|
| 1 | +<script lang="ts"> |
| 2 | + import { createEventDispatcher } from 'svelte'; |
| 3 | + const dispatch = createEventDispatcher<{ update: { json: string } }>(); |
| 4 | +
|
| 5 | + import { type RequiredField, parseFieldsFromJSON } from '$lib/models/Connection'; |
| 6 | + import RequiredFieldRow from './RequiredFieldRow.svelte'; |
| 7 | +
|
| 8 | + export let fields: string = '[]'; |
| 9 | +
|
| 10 | + $: fieldList = parseFieldsFromJSON(fields); |
| 11 | + $: enableNewField = fieldList.length === 0; |
| 12 | + $: duplicates = fieldList.filter((checkField) => { |
| 13 | + return ( |
| 14 | + fieldList |
| 15 | + .filter((field) => field !== checkField) |
| 16 | + .filter((field) => field.id === checkField.id).length > 0 |
| 17 | + ); |
| 18 | + }); |
| 19 | +
|
| 20 | + type SaveRequiredField = { detail: { previous: RequiredField; current: RequiredField } }; |
| 21 | + type RequiredFieldEvent = { detail: RequiredField }; |
| 22 | +
|
| 23 | + function hasDuplicate(checkField: RequiredField) { |
| 24 | + return !!duplicates.find((field) => field === checkField); |
| 25 | + } |
| 26 | +
|
| 27 | + function updateFields(fields: RequiredField[]) { |
| 28 | + dispatch('update', { json: JSON.stringify(fields) }); |
| 29 | + } |
| 30 | +
|
| 31 | + function saveField(event: SaveRequiredField) { |
| 32 | + const newFields = [...fieldList]; |
| 33 | + if (event.detail.previous.label === '' || event.detail.previous.id === '') { |
| 34 | + newFields.push(event.detail.current); |
| 35 | + enableNewField = false; |
| 36 | + } else { |
| 37 | + const fieldIndex: number = newFields.findIndex( |
| 38 | + (f) => f.label === event.detail.previous.label && f.id === event.detail.previous.id, |
| 39 | + ); |
| 40 | + if (fieldIndex > -1) { |
| 41 | + newFields[fieldIndex] = event.detail.current; |
| 42 | + } |
| 43 | + } |
| 44 | +
|
| 45 | + updateFields(newFields); |
| 46 | + } |
| 47 | +
|
| 48 | + function deleteField(event: RequiredFieldEvent) { |
| 49 | + const newFields = fieldList.filter( |
| 50 | + (f) => f.label !== event.detail.label || f.id !== event.detail.id, |
| 51 | + ); |
| 52 | + updateFields(newFields); |
| 53 | + } |
| 54 | +</script> |
| 55 | + |
| 56 | +<fieldset class="border border-surface-300-600-token"> |
| 57 | + <legend class="px-2 ml-2"> |
| 58 | + Required Fields: |
| 59 | + <button |
| 60 | + type="button" |
| 61 | + class="text-primary-600-300-token hover:text-secondary-600-300-token" |
| 62 | + title="Add New Field" |
| 63 | + data-testid="required-field-new-btn" |
| 64 | + disabled={enableNewField} |
| 65 | + on:click={() => (enableNewField = !enableNewField)} |
| 66 | + > |
| 67 | + <i class="fa-solid fa-square-plus fa-xl"></i> |
| 68 | + </button> |
| 69 | + </legend> |
| 70 | + |
| 71 | + {#if enableNewField} |
| 72 | + <RequiredFieldRow on:save={saveField} on:delete={() => (enableNewField = false)} /> |
| 73 | + {/if} |
| 74 | + |
| 75 | + {#each fieldList as field, index (`${index}-${field.label}-${field.id}`)} |
| 76 | + <RequiredFieldRow |
| 77 | + duplicate={hasDuplicate(field)} |
| 78 | + {field} |
| 79 | + on:save={saveField} |
| 80 | + on:delete={deleteField} |
| 81 | + /> |
| 82 | + {/each} |
| 83 | + |
| 84 | + {#if duplicates.length > 0} |
| 85 | + <aside data-testid="validation-warn" class="alert variant-ghost-warning m-2"> |
| 86 | + <i class="fa-solid fa-triangle-exclamation"></i> |
| 87 | + <div class="alert-message"> |
| 88 | + <p>Fields with the same ID may not function properly.</p> |
| 89 | + </div> |
| 90 | + </aside> |
| 91 | + {/if} |
| 92 | +</fieldset> |
0 commit comments