File size: 5,928 Bytes
c6db453 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | class CustomUpload extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
@import url('https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css');
</style>
<form class="space-y-4">
<div>
<label for="batchType" class="block text-sm font-medium text-gray-700 mb-1">Batch Type</label>
<select id="batchType" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
<option value="Anonymisation">Anonymisation</option>
</select>
</div>
<div>
<label for="fileInput" class="block text-sm font-medium text-gray-700 mb-1">Input File</label>
<div class="file-input-label" id="dropZone">
<div class="flex flex-col items-center justify-center pt-5 pb-6">
<i data-feather="upload-cloud" class="w-10 h-10 text-gray-400 mb-2"></i>
<p class="mb-2 text-sm text-gray-500"><span class="font-semibold">Click to upload</span> or drag and drop</p>
<p class="text-xs text-gray-500">CSV files only</p>
</div>
<input id="fileInput" type="file" class="hidden" accept=".csv" />
</div>
</div>
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Process File
</button>
<div id="statusMessage" class="hidden p-3 rounded-md text-sm"></div>
</form>
`;
}
connectedCallback() {
this.shadowRoot.querySelector('form').addEventListener('submit', this.handleSubmit.bind(this));
const fileInput = this.shadowRoot.getElementById('fileInput');
const dropZone = this.shadowRoot.getElementById('dropZone');
fileInput.addEventListener('change', () => this.updateFileDisplay());
// Drag and drop handlers
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('drag-over');
});
['dragleave', 'dragend'].forEach(type => {
dropZone.addEventListener(type, () => {
dropZone.classList.remove('drag-over');
});
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('drag-over');
if (e.dataTransfer.files.length) {
fileInput.files = e.dataTransfer.files;
this.updateFileDisplay();
}
});
dropZone.addEventListener('click', () => fileInput.click());
// Initialize Feather icons
feather.replace({ width: 20, height: 20 });
}
updateFileDisplay() {
const fileInput = this.shadowRoot.getElementById('fileInput');
const dropZone = this.shadowRoot.getElementById('dropZone');
if (fileInput.files.length > 0) {
const file = fileInput.files[0];
dropZone.innerHTML = `
<div class="flex items-center p-4">
<i data-feather="file-text" class="w-6 h-6 text-indigo-500 mr-3"></i>
<div>
<p class="text-sm font-medium text-gray-900">${file.name}</p>
<p class="text-xs text-gray-500">${(file.size / 1024).toFixed(2)} KB</p>
</div>
</div>
`;
feather.replace({ width: 20, height: 20 });
}
}
async handleSubmit(e) {
e.preventDefault();
const batchType = this.shadowRoot.getElementById('batchType').value;
const fileInput = this.shadowRoot.getElementById('fileInput');
const statusMessage = this.shadowRoot.getElementById('statusMessage');
if (!fileInput.files.length) {
statusMessage.textContent = 'Please select a file first';
statusMessage.className = 'bg-red-50 text-red-700';
statusMessage.classList.remove('hidden');
return;
}
const file = fileInput.files[0];
if (!file.name.endsWith('.csv')) {
statusMessage.textContent = 'Only CSV files are allowed';
statusMessage.className = 'bg-red-50 text-red-700';
statusMessage.classList.remove('hidden');
return;
}
statusMessage.textContent = 'Processing your file...';
statusMessage.className = 'bg-blue-50 text-blue-700';
statusMessage.classList.remove('hidden');
try {
const batch = await window.batchService.createBatch(batchType, file);
statusMessage.textContent = `Batch #${batch.id} created successfully!`;
statusMessage.className = 'bg-green-50 text-green-700';
// Dispatch event to notify list component
document.dispatchEvent(new CustomEvent('batch-created'));
// Reset form
fileInput.value = '';
this.updateFileDisplay();
} catch (error) {
statusMessage.textContent = 'Error creating batch: ' + error.message;
statusMessage.className = 'bg-red-50 text-red-700';
}
}
}
customElements.define('custom-upload', CustomUpload); |