diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 8f4a242b1..957356bfb 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -174,7 +174,7 @@ diff --git a/resources/scss/_material.scss b/resources/scss/_material.scss index 94c485b12..002fb123e 100644 --- a/resources/scss/_material.scss +++ b/resources/scss/_material.scss @@ -8,10 +8,9 @@ md-icon svg { line-height: 0; } -:is(md-list-item, md-list-item-link) md-icon { - --md-icon-color: var(--_list-item-leading-icon-color); - - padding-left: 16px; +md-list-item md-icon { + margin-left: 16px; + color: var(--_list-item-leading-icon-color); svg { width: var(--_list-item-leading-icon-size, var(--_icon-size, var(--_size))); @@ -42,7 +41,7 @@ md-navigation-drawer, md-navigation-drawer-modal { justify-content: center; min-width: 300px; - md-list-item-link { + md-list-item { --md-list-item-list-item-container-shape: 100px; --md-ripple-shape: 100px; diff --git a/resources/ts/Components/DataTable/DataTable.tsx b/resources/ts/Components/DataTable/DataTable.tsx index 88ae44d56..c87dbbe05 100644 --- a/resources/ts/Components/DataTable/DataTable.tsx +++ b/resources/ts/Components/DataTable/DataTable.tsx @@ -1,6 +1,6 @@ import '@maicol07/material-web-additions/data-table/data-table.js'; -import {DataTable as MdDataTable} from '@maicol07/material-web-additions/data-table/lib/data-table'; +import {DataTable as MdDataTable} from '@maicol07/material-web-additions/data-table/internal/data-table'; import { mdiChevronLeft, mdiChevronRight, diff --git a/resources/ts/Components/DataTable/DataTableColumn.tsx b/resources/ts/Components/DataTable/DataTableColumn.tsx index 3f4c78084..9357986fb 100644 --- a/resources/ts/Components/DataTable/DataTableColumn.tsx +++ b/resources/ts/Components/DataTable/DataTableColumn.tsx @@ -1,6 +1,6 @@ import '@maicol07/material-web-additions/data-table/data-table-column.js'; -import {DataTableColumn as MdDataTableColumn} from '@maicol07/material-web-additions/data-table/lib/data-table-column.js'; +import {DataTableColumn as MdDataTableColumn} from '@maicol07/material-web-additions/data-table/internal/data-table-column.js'; import { mdiArrowDown, mdiArrowUp diff --git a/resources/ts/Components/DataTable/RecordsTable.tsx b/resources/ts/Components/DataTable/RecordsTable.tsx index 9c04b32eb..bdc4a1bdf 100644 --- a/resources/ts/Components/DataTable/RecordsTable.tsx +++ b/resources/ts/Components/DataTable/RecordsTable.tsx @@ -7,8 +7,8 @@ import { DataTable as MdDataTable, PaginateDetail, RowSelectionChangedDetail -} from '@maicol07/material-web-additions/data-table/lib/data-table'; -import {DataTableCell} from '@maicol07/material-web-additions/data-table/lib/data-table-cell'; +} from '@maicol07/material-web-additions/data-table/internal/data-table'; +import {DataTableCell} from '@maicol07/material-web-additions/data-table/internal/data-table-cell'; import {mdiDeleteOutline} from '@mdi/js'; import DataTable, {DataTableAttributes} from '@osm/Components/DataTable/DataTable'; import DataTableColumn, {DataTableColumnAttributes} from '@osm/Components/DataTable/DataTableColumn'; @@ -171,9 +171,9 @@ export default class RecordsTable, A extends RecordsTa protected tableRowActions(vnode: Vnode, record: M) { return collect({ delete: ( - + - + ) }); } diff --git a/resources/ts/Components/Dialogs/AddEditRecordDialog.tsx b/resources/ts/Components/Dialogs/AddEditRecordDialog.tsx index a8bedea58..1052e87ec 100644 --- a/resources/ts/Components/Dialogs/AddEditRecordDialog.tsx +++ b/resources/ts/Components/Dialogs/AddEditRecordDialog.tsx @@ -31,6 +31,7 @@ export default abstract class AddEditRecordDialog> ext // Recommended: <= 3 protected numberOfColumns: number = 3; protected record!: M; + protected formId?: string; oninit(vnode: Vnode, this>) { super.oninit(vnode); @@ -57,16 +58,19 @@ export default abstract class AddEditRecordDialog> ext contents(): Children { return ( <> -

{this.record.isNew() ? __('Nuovo record') : __('Modifica record')}

{this.form()} - {this.afterForm().toArray()} ); } + headline() { + return {this.record.isNew() ? __('Nuovo record') : __('Modifica record')}; + } + form(): Children { + this.formId ??= `form-${Date.now()}`; return ( -
+ {this.formContents()}
); @@ -95,24 +99,24 @@ export default abstract class AddEditRecordDialog> ext abstract fields(): Collection; onCancelButtonClicked(): void { - this.close('cancel'); + void this.close('cancel'); } async onFormSubmit() { if (isFormValid(this.formElement!) && await this.save()) { - this.close(); + void this.close(); } } - afterForm(): VnodeCollection { + actions(): VnodeCollection { return collect({ cancelButton: ( - + {__('Annulla')} ), saveButton: ( - + {__('Salva')} @@ -120,10 +124,6 @@ export default abstract class AddEditRecordDialog> ext }); } - onSaveButtonClicked(): void { - this.formElement?.requestSubmit(); - } - async save(): Promise { this.record.setAttributes(this.modelAttributesFromFormState); try { @@ -136,9 +136,7 @@ export default abstract class AddEditRecordDialog> ext } } - // @ts-expect-error - Temporary afterSave(response: SaveResponse): void { - // @ts-expect-error - Temporary const responseModel = response.getModel() as M; if (responseModel !== undefined) { this.record = responseModel; diff --git a/resources/ts/Components/Dialogs/Dialog.tsx b/resources/ts/Components/Dialogs/Dialog.tsx index 9aabbd8fb..23a72a0a3 100644 --- a/resources/ts/Components/Dialogs/Dialog.tsx +++ b/resources/ts/Components/Dialogs/Dialog.tsx @@ -4,9 +4,13 @@ import '@material/web/dialog/dialog.js'; import {Dialog as MDDialog} from '@material/web/dialog/internal/dialog'; import { + VnodeCollection, + VnodeCollectionItem +} from '@osm/typings/jsx'; +import collect from 'collect.js'; +import Mithril, { Children, - Vnode, - VnodeDOM + Vnode } from 'mithril'; import Stream from 'mithril/stream'; import { @@ -36,40 +40,63 @@ export default abstract class Dialog
) { - super.oncreate(vnode); - - this.element.addEventListener('closed', () => { - vnode.attrs.onClose?.(); - this.open(false); - m.redraw(); - }); - - this.element.addEventListener('opened', () => { - vnode.attrs.onOpen?.(); - }); - } - public view(vnode: Vnode): Children { + let open = this.open(); + // If dialog is open but element isn't created yet, don't open it (wait for oncreate, see below) + if (open && this.element === undefined) { + open = false; + } + const contents = this.contents(vnode) ?? vnode.children; + const actions = this.actions(vnode); return ( - {this.contents(vnode) ?? vnode.children} + maxWidth: 'calc(100% - 48px)', + maxHeight: 'calc(100% - 48px)' + }} {...vnode.attrs} open={open} onopened={vnode.attrs.onOpen} onclosed={this.onDialogClosed.bind(this, vnode)}> + {this.icon() &&
{this.icon()}
} + {this.headline() &&
{this.headline()}
} + {contents &&
{contents}
} + {actions.isNotEmpty() &&
{actions.toArray()}
}
); } + oncreate(vnode: Mithril.VnodeDOM) { + super.oncreate(vnode); + // TODO: [BUG] Dialog not opening by default on creation. Wait for https://github.com/material-components/material-web/issues/4728 + setTimeout(() => { + if (this.open()) { + void this.show(); + } + }, 0); + } + + onDialogClosed(vnode:Vnode) { + vnode.attrs.onClose?.(); + this.open(false); + } + + icon(): Children { + return undefined; + } + + headline(): Children { + return undefined; + } + contents(vnode: Vnode): Children { return undefined; } - public show(): void { - this.element.show(); + actions(vnode: Vnode): VnodeCollection { + return collect(); } - public close(action?: string): void { - this.element.close(action); + public async show() { + return this.element.show(); + } + + public async close(action?: string) { + return this.element.close(action); } } diff --git a/resources/ts/Components/FilledDateTextField.tsx b/resources/ts/Components/FilledDateTextField.tsx index d0f266fec..9e5b5413a 100644 --- a/resources/ts/Components/FilledDateTextField.tsx +++ b/resources/ts/Components/FilledDateTextField.tsx @@ -1,5 +1,5 @@ import '@material/web/textfield/filled-text-field.js'; -import '@material/web/iconbutton/standard-icon-button.js'; +import '@material/web/iconbutton/icon-button.js'; import {FilledTextField} from '@material/web/textfield/internal/filled-text-field'; import {mdiCalendarMonthOutline} from '@mdi/js'; @@ -21,9 +21,9 @@ export default class FilledDateTextField
{/* @ts-ignore */} {vnode.children} - + - + ); } diff --git a/resources/ts/Components/Pages/RecordsPage.tsx b/resources/ts/Components/Pages/RecordsPage.tsx index 8ecffb76c..be8eee336 100644 --- a/resources/ts/Components/Pages/RecordsPage.tsx +++ b/resources/ts/Components/Pages/RecordsPage.tsx @@ -3,14 +3,14 @@ import '@maicol07/material-web-additions/layout-grid/layout-grid.js'; import '@material/web/dialog/dialog.js'; import '@material/web/fab/branded-fab.js'; import '@material/web/fab/fab.js'; -import '@material/web/iconbutton/standard-icon-button.js'; +import '@material/web/iconbutton/icon-button.js'; import {router} from '@maicol07/inertia-mithril'; -import {PaginateDetail} from '@maicol07/material-web-additions/data-table/lib/data-table'; +import {PaginateDetail} from '@maicol07/material-web-additions/data-table/internal/data-table'; import { FilterTextFieldInputEventDetail, SortButtonClickedEventDetail -} from '@maicol07/material-web-additions/data-table/lib/data-table-column.js'; +} from '@maicol07/material-web-additions/data-table/internal/data-table-column.js'; import { mdiPlus, mdiRefresh diff --git a/resources/ts/Components/layout/Drawer.tsx b/resources/ts/Components/layout/Drawer.tsx index d08e1c92a..3cc275bc2 100644 --- a/resources/ts/Components/layout/Drawer.tsx +++ b/resources/ts/Components/layout/Drawer.tsx @@ -40,7 +40,7 @@ export default class Drawer exten const DrawerTag = isMobile() ? 'md-navigation-drawer-modal' : 'md-navigation-drawer'; return ( - {DrawerTag === 'md-navigation-drawer-modal' && } + {DrawerTag === 'md-navigation-drawer-modal' && } {this.entries().values().all()} ); diff --git a/resources/ts/Components/layout/DrawerEntry.tsx b/resources/ts/Components/layout/DrawerEntry.tsx index 8a2db1e3a..6b3bb797d 100644 --- a/resources/ts/Components/layout/DrawerEntry.tsx +++ b/resources/ts/Components/layout/DrawerEntry.tsx @@ -1,8 +1,8 @@ import '@material/web/icon/icon.js'; -import '@material/web/list/list-item-link.js'; +import '@material/web/list/list-item.js'; import {router} from '@maicol07/inertia-mithril'; -import {ListItemLink} from '@material/web/list/internal/listitemlink/list-item-link'; +import {ListItemEl} from '@material/web/list/internal/listitem/list-item'; import type * as MaterialIcons from '@mdi/js'; import MdIcon from '@osm/Components/MdIcon'; import {Vnode} from 'mithril'; @@ -14,17 +14,17 @@ import {ValueOf} from 'type-fest'; type Icons = ValueOf; -export interface DrawerEntryAttributes extends Attributes, Partial { - href: ListItemLink['href']; +export interface DrawerEntryAttributes extends Attributes, Partial { + href: ListItemEl['href']; icon: Icons; } export class DrawerEntry extends Component { view(vnode: Vnode) { return ( - + - + ); } @@ -34,6 +34,6 @@ export class DrawerEntry + - + ); } diff --git a/resources/ts/Components/layout/topappbar_actions/TopAppBarAction.tsx b/resources/ts/Components/layout/topappbar_actions/TopAppBarAction.tsx index 1347370e9..1596d53cd 100644 --- a/resources/ts/Components/layout/topappbar_actions/TopAppBarAction.tsx +++ b/resources/ts/Components/layout/topappbar_actions/TopAppBarAction.tsx @@ -12,9 +12,9 @@ export default abstract class TopAppBarAction extends Component { view(vnode: Vnode): Children { return ( - + - + ); } diff --git a/resources/ts/Views/LoginPage.tsx b/resources/ts/Views/LoginPage.tsx index 7c6376ae2..60746e321 100644 --- a/resources/ts/Views/LoginPage.tsx +++ b/resources/ts/Views/LoginPage.tsx @@ -5,7 +5,6 @@ import '@material/web/checkbox/checkbox.js'; import '@material/web/dialog/dialog.js'; import '@material/web/textfield/filled-text-field.js'; -import {Dialog} from '@material/web/dialog/internal/dialog'; import { mdiAccountOutline, mdiEmailOutline, @@ -19,8 +18,7 @@ import {VnodeCollectionItem} from '@osm/typings/jsx'; import {showSnackbar} from '@osm/utils/misc'; import collect from 'collect.js'; import type { - Vnode, - VnodeDOM + Vnode } from 'mithril'; import Stream from 'mithril/stream'; import { @@ -41,7 +39,7 @@ export default class LoginPage extends Page { email: Stream('') }; - forgotPasswordDialog!: Dialog; + forgotPasswordDialogOpen = false; contents(vnode: Vnode) { return <> @@ -52,18 +50,25 @@ export default class LoginPage extends Page { {this.buttons().toArray()} - -

{__('Recupero password')}

-

{__('Inserisci il tuo indirizzo email per ricevere le istruzioni per il recupero della password.')}

-
-
- {this.forgotPasswordFields().toArray()} -
-
- - - {__('Invia')} - + +
+ +
+
+ {__('Recupero password')} +
+
+

{__('Inserisci il tuo indirizzo email per ricevere le istruzioni per il recupero della password.')}

+
+
+ {this.forgotPasswordFields().toArray()} +
+
+
+
+ {__('Annulla')} + {__('Invia')} +
; } @@ -82,7 +87,7 @@ export default class LoginPage extends Page { ), remember: ( ) @@ -102,7 +107,7 @@ export default class LoginPage extends Page { buttons() { return collect({ forgotPassword: ( - + {__('Password dimenticata')} @@ -116,12 +121,6 @@ export default class LoginPage extends Page { }); } - oncreate(vnode: VnodeDOM) { - super.oncreate(vnode); - - this.forgotPasswordDialog = this.element.querySelector('md-dialog#forgot-password-dialog')!; - } - async onLoginFormSubmit(event: FormSubmitEvent) { try { await Request.get(route('sanctum.csrf-cookie')); @@ -136,11 +135,19 @@ export default class LoginPage extends Page { } onForgotPasswordButtonClicked() { - this.forgotPasswordDialog.show(); + this.openForgotPasswordDialog(); } - onForgotPasswordDialogSubmitButtonClicked() { - this.forgotPasswordDialog.querySelector('form')?.requestSubmit(); + onForgotPasswordDialogCancelButtonClicked() { + this.closeForgotPasswordDialog(); + } + + openForgotPasswordDialog() { + this.forgotPasswordDialogOpen = true; + } + + closeForgotPasswordDialog() { + this.forgotPasswordDialogOpen = false; } async onForgotPasswordFormSubmit(event: FormSubmitEvent) { @@ -152,6 +159,6 @@ export default class LoginPage extends Page { } void showSnackbar(__('La password รจ stata inviata alla tua email')); - this.forgotPasswordDialog.close(); + this.closeForgotPasswordDialog(); } } diff --git a/resources/ts/WebComponents/TopAppBar.ts b/resources/ts/WebComponents/TopAppBar.ts index e0dcf95a3..c8a227207 100644 --- a/resources/ts/WebComponents/TopAppBar.ts +++ b/resources/ts/WebComponents/TopAppBar.ts @@ -12,7 +12,7 @@ declare global { export default class TopAppBar extends MWCTopAppBar { static styles = [...MWCTopAppBar.styles, css` header.mdc-top-app-bar { - z-index: 7; + z-index: 0; } `]; } diff --git a/resources/ts/typings/jsx.d.ts b/resources/ts/typings/jsx.d.ts index 7b6cc0a58..f42d1c5ec 100644 --- a/resources/ts/typings/jsx.d.ts +++ b/resources/ts/typings/jsx.d.ts @@ -19,8 +19,6 @@ declare module 'csstype' { declare module 'mithril' { interface Attributes extends LayoutGridAttributes { - // Needed for md-dialog - 'dialog-action'?: string | 'ok' | 'discard' | 'close' | 'cancel' | 'accept' | 'decline', 'auto-animate'?: boolean } }