Skip to content

Commit 95c1529

Browse files
committed
improved-design
Signed-off-by: Maximilian Inckmann <[email protected]>
1 parent 9968d71 commit 95c1529

File tree

3 files changed

+278
-152
lines changed

3 files changed

+278
-152
lines changed

src/main.ts

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,15 @@ class MappingInputProvider extends HTMLElement {
264264
options.labelIdle = `Drag & Drop your files or Browse (File size limit: ${options.maxFileSize})`;
265265
this.fileChooser = FilePondLib.create(filepondElement, options);
266266
queueMicrotask(() => this.decorateFilePondLabel(options.maxFileSize as string));
267+
this.fileChooser.on('addfile', () => {
268+
if (this.selectedMappingId) {
269+
this.setSubmitEnabled(true);
270+
}
271+
this.removeMessage();
272+
});
273+
this.fileChooser.on('removefile', () => {
274+
this.setSubmitEnabled(false);
275+
});
267276
}
268277

269278
private decorateFilePondLabel(limit: string): void {
@@ -281,20 +290,23 @@ class MappingInputProvider extends HTMLElement {
281290
// Using text nodes avoids surprises from HTML whitespace collapsing rules or CSS resets.
282291
'';
283292
dropLabel.replaceChildren();
293+
294+
const div = document.createElement('div');
284295
// Use non‑breaking spaces (\u00A0) so spacing is preserved regardless of CSS white-space rules.
285-
dropLabel.append('Drag & Drop your files or\u00A0');
296+
div.append(document.createTextNode('Drag & Drop your files or\u00A0'));
286297
const browseEl = document.createElement('span');
287298
browseEl.className = 'filepond--label-action';
288299
browseEl.setAttribute('role', 'button');
289300
browseEl.setAttribute('tabindex', '0');
290301
browseEl.textContent = 'Browse';
291-
dropLabel.append(browseEl);
292-
dropLabel.append('\u00A0');
293-
dropLabel.append(document.createElement('br'));
302+
div.append(browseEl);
303+
div.append('\u00A0');
304+
div.append(document.createElement('br'));
294305
const info = document.createElement('span');
295306
info.className = 'info-small';
296307
info.textContent = `(File size is limited to ${limit})`;
297-
dropLabel.append(info);
308+
div.append(info);
309+
dropLabel.appendChild(div);
298310
const trigger = () => this.fileChooser?.browse();
299311
browseEl.addEventListener('click', trigger);
300312
browseEl.addEventListener('keydown', (e: Event) => {
@@ -374,7 +386,7 @@ class MappingInputProvider extends HTMLElement {
374386
descWrapper.classList.add('description');
375387
descWrapper.appendChild(document.createElement('br'));
376388
const scrollSpan = document.createElement('span');
377-
scrollSpan.setAttribute('style', 'display:inline-block; overflow: auto; height: 124px;');
389+
scrollSpan.setAttribute('style', 'display:inline-block; overflow: auto; height: 10rem;');
378390
scrollSpan.textContent = mapping.description ?? '';
379391
descWrapper.appendChild(scrollSpan);
380392
const buttonEl = document.createElement('button');
@@ -440,17 +452,20 @@ class MappingInputProvider extends HTMLElement {
440452
b.classList.remove('selected-id');
441453
b.setAttribute('aria-selected', 'false');
442454
});
443-
if (id && id !== this.selectedMappingId) {
455+
if (id && id !== this.selectedMappingId && id !== '') {
444456
buttonEl.classList.add('selected-id');
445457
buttonEl.setAttribute('aria-selected', 'true');
458+
buttonEl.innerText = '✓ Selected';
446459
this.selectedMappingId = id;
447-
this.showMessage(
448-
'Mapping selected. Please choose a file and then activate <b><i>Execute Mapping</i></b> to start the process.',
449-
);
450-
this.setSubmitEnabled(true);
460+
if (this.fileChooser && this.fileChooser.getFiles().length > 0) {
461+
this.setSubmitEnabled(true);
462+
this.removeMessage();
463+
} else this.setSubmitEnabled(false);
451464
} else {
465+
buttonEl.innerText = 'Select';
452466
this.selectedMappingId = null;
453467
this.showMessage('Please select a mapping from the list above.');
468+
this.removeMessage();
454469
this.setSubmitEnabled(false);
455470
}
456471
}
@@ -498,8 +513,15 @@ class MappingInputProvider extends HTMLElement {
498513
submit.setAttribute('disabled', 'true');
499514
submit.innerText = 'Please wait...';
500515
const ok = await this.executeMapping();
501-
if (ok) console.log('Mapping successfully finished.');
502-
else console.error('Mapping failed.');
516+
if (ok) {
517+
console.log('Mapping successfully finished.');
518+
this.showMessage(
519+
'Mapping successfully finished. You can now select another mapping or upload a new file.',
520+
);
521+
setTimeout(() => this.removeMessage(), 10000);
522+
} else {
523+
console.error('Mapping failed.');
524+
}
503525
if (this.selectedMappingId) submit.removeAttribute('disabled');
504526
else submit.setAttribute('disabled', 'true');
505527
submit.innerText = 'Execute Mapping';
@@ -519,6 +541,18 @@ class MappingInputProvider extends HTMLElement {
519541
return false;
520542
}
521543

544+
private removeMessage(): void {
545+
/**
546+
* Clear any existing status or error message from the message area.
547+
*/
548+
const el = this.shadowRoot.querySelector('#message');
549+
if (!el) return;
550+
el.replaceChildren();
551+
el.setAttribute('hidden', 'true');
552+
el.classList.add('hidden');
553+
el.classList.remove('info', 'error');
554+
}
555+
522556
/**
523557
* Render a status or error message in the message area.
524558
* Accepts a limited HTML subset (currently: <span class="heroicons-outline--exclamation"></span> and <br> tags).
@@ -533,6 +567,7 @@ class MappingInputProvider extends HTMLElement {
533567
const isError = type === 'ERROR';
534568
el.setAttribute('role', isError ? 'alert' : 'status');
535569
el.setAttribute('aria-live', isError ? 'assertive' : 'polite');
570+
el.removeAttribute('hidden');
536571
// Sanitize supplied HTML and append
537572
const fragment = this.sanitizeMessageHtml(text);
538573
el.appendChild(fragment);

0 commit comments

Comments
 (0)