import { html, LitElement } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { Signal, SignalWatcher } from '@lit-labs/signals'; import { getSignal, doFetch, State } from './utils'; import { map } from 'lit/directives/map.js'; type Field = { id?: string; name: string; label?: string; type?: string; placeholder?: string; }; type FormConfig = { action: string; fields: Field[]; submit?: string; type?: 'table' | 'line'; }; /** * Fetch data from a URL and store it in a signal. */ @customElement('admin-form') export default class Link extends SignalWatcher(LitElement) { @property() data: string = ''; @property() emit: string = ''; @property() state: string = ''; @property({ type: Boolean }) emitOnError: boolean = false; @property({ type: Boolean }) dataOnError: boolean = false; dataSignal?: Signal.State; emitSignal?: Signal.State; stateSignal?: Signal.State; config?: FormConfig; connectedCallback() { super.connectedCallback(); this.dataSignal = getSignal(this.data); this.emitSignal = getSignal(this.emit); this.stateSignal = getSignal(this.state); } override createRenderRoot() { return this; } // eslint-disable-next-line @typescript-eslint/no-explicit-any getJsonData(form: HTMLFormElement): { [id: string]: any } { const data = new FormData(form); // eslint-disable-next-line @typescript-eslint/no-explicit-any const jsonData: { [id: string]: any } = {}; data.forEach((value, key) => { jsonData[key] = value; }); return jsonData; } handleSubmit(event: Event) { event.preventDefault(); if (this.stateSignal) { this.stateSignal.set(State.Loading); } const form = this.getElementsByTagName('form')[0]; const jsonData = this.getJsonData(form); if (this.dataSignal && this.emitSignal) { doFetch( form.getAttribute('action') || '', this.dataSignal, this.emitSignal, this.stateSignal, (form.getAttribute('method') || 'POST').toUpperCase(), jsonData, { emitOnError: this.emitOnError, dataOnError: this.dataOnError, }, ); } } render() { if (this.innerHTML) { this.config = JSON.parse(this.innerText); this.innerHTML = ''; } if (!this.config) { console.error('Missing config'); return html``; } const formType = this.config?.type ?? 'table'; if (formType === 'table') { return html`
${map(this.config.fields, (field: Field) => { const fieldId = field?.id ?? field.name; return html`
`; })}
`; } if (formType === 'line') { return html`
${map(this.config.fields, (field: Field) => { const fieldId = field?.id ?? field.name; return html`
${field?.label ? html`` : html``}
`; })}
`; } } }