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` `;
}
if (formType === 'line') {
return html``;
}
}
}