mirror of
https://github.com/devcode-it/openstamanager.git
synced 2025-06-05 22:09:38 +02:00
feat: ✨ Ristrutturazione completa del progetto
This commit is contained in:
129
resources/ts/Components/Dialogs/AddEditRecordDialog.tsx
Normal file
129
resources/ts/Components/Dialogs/AddEditRecordDialog.tsx
Normal file
@@ -0,0 +1,129 @@
|
||||
import {mdiFloppy} from '@mdi/js';
|
||||
import collect, {Collection} from 'collect.js';
|
||||
import {
|
||||
Children,
|
||||
Vnode,
|
||||
VnodeDOM
|
||||
} from 'mithril';
|
||||
import Stream from 'mithril/stream';
|
||||
import {Class} from 'type-fest';
|
||||
|
||||
import Form from '~/Components/Form';
|
||||
import MdIcon from '~/Components/MdIcon';
|
||||
import RecordDialog, {RecordDialogAttributes} from '~/Components/Dialogs/RecordDialog';
|
||||
import Model from '~/Models/Model';
|
||||
import {
|
||||
VnodeCollection,
|
||||
VnodeCollectionItem
|
||||
} from '~/typings/jsx';
|
||||
import {isFormValid} from '~/utils/misc';
|
||||
|
||||
export default abstract class AddEditRecordDialog<M extends Model<any, any>> extends RecordDialog<M> {
|
||||
// eslint-disable-next-line unicorn/no-null
|
||||
protected formElement: HTMLFormElement | null = null;
|
||||
protected abstract formState: Map<string, Stream<unknown>>;
|
||||
protected abstract modelType: Class<M>;
|
||||
// Recommended: <= 3
|
||||
protected numberOfColumns: number = 3;
|
||||
protected record!: M;
|
||||
|
||||
oninit(vnode: Vnode<RecordDialogAttributes<M>, this>) {
|
||||
super.oninit(vnode);
|
||||
|
||||
if (!this.record) {
|
||||
this.record = new this.modelType();
|
||||
}
|
||||
|
||||
this.fillForm();
|
||||
}
|
||||
|
||||
oncreate(vnode: VnodeDOM<RecordDialogAttributes<M>, this>) {
|
||||
super.oncreate(vnode);
|
||||
|
||||
this.formElement = this.element.querySelector('form');
|
||||
}
|
||||
|
||||
fillForm() {
|
||||
for (const [key, value] of this.formState) {
|
||||
value(this.record.getAttribute(key) ?? value());
|
||||
}
|
||||
}
|
||||
|
||||
contents(): Children {
|
||||
return (
|
||||
<>
|
||||
<h2 slot="headline">{this.record.isNew() ? __('Nuovo record') : __('Modifica record')}</h2>
|
||||
{this.form()}
|
||||
{this.afterForm().toArray()}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
form(): Children {
|
||||
return (
|
||||
<Form state={this.formState} onsubmit={this.onFormSubmit.bind(this)}>
|
||||
{this.formContents()}
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
||||
formContents(): Children {
|
||||
return (
|
||||
<md-layout-grid>
|
||||
{...this.fields().map((item, key: string) => {
|
||||
// TODO: Remove this cast when new collection library is done
|
||||
const field = item as Vnode<{name?: string, 'grid-span'?: number}>;
|
||||
field.attrs.name ??= key;
|
||||
field.attrs['grid-span'] ??= Math.floor(12 / this.numberOfColumns);
|
||||
return item;
|
||||
}).values().all()}
|
||||
</md-layout-grid>
|
||||
);
|
||||
}
|
||||
|
||||
abstract fields(): Collection<Children>;
|
||||
|
||||
onCancelButtonClicked(): void {
|
||||
this.close('cancel');
|
||||
}
|
||||
|
||||
async onFormSubmit() {
|
||||
if (isFormValid(this.formElement!) && await this.save()) {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
abstract save(): boolean | Promise<boolean>;
|
||||
|
||||
afterForm(): VnodeCollection {
|
||||
return collect<VnodeCollectionItem>({
|
||||
cancelButton: (
|
||||
<md-text-button slot="footer" onclick={this.onCancelButtonClicked.bind(this)}>
|
||||
{__('Annulla')}
|
||||
</md-text-button>
|
||||
),
|
||||
saveButton: (
|
||||
<md-text-button type="submit" slot="footer" onclick={this.onSaveButtonClicked.bind(this)}>
|
||||
{__('Salva')}
|
||||
<MdIcon icon={mdiFloppy} slot="icon"/>
|
||||
</md-text-button>
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
onSaveButtonClicked(): void {
|
||||
this.formElement?.requestSubmit();
|
||||
}
|
||||
|
||||
protected static createFormState(entries: Record<string, Stream<any>>): Map<string, Stream<unknown>> {
|
||||
return new Map(Object.entries(entries));
|
||||
}
|
||||
|
||||
get formStateRecord(): Record<string, unknown> {
|
||||
const state: Record<string, unknown> = {};
|
||||
for (const [key, value] of this.formState) {
|
||||
state[key] = value();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user