diff --git a/.idea/blade.xml b/.idea/blade.xml index d6400260c..1eb77b476 100644 --- a/.idea/blade.xml +++ b/.idea/blade.xml @@ -10,6 +10,8 @@ + + @@ -80,6 +82,7 @@ + @@ -90,8 +93,9 @@ + - + \ No newline at end of file diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml index 6e0106267..8d7608578 100644 --- a/.idea/jsLibraryMappings.xml +++ b/.idea/jsLibraryMappings.xml @@ -4,4 +4,4 @@ - \ No newline at end of file + diff --git a/.idea/misc.xml b/.idea/misc.xml index 3668dc8ca..e7f63a8ab 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,4 +3,7 @@ + + + \ No newline at end of file diff --git a/.idea/osm_rewrite.iml b/.idea/osm_rewrite.iml index 03e8bf2c8..3c922e2a3 100644 --- a/.idea/osm_rewrite.iml +++ b/.idea/osm_rewrite.iml @@ -91,10 +91,11 @@ + - \ No newline at end of file + diff --git a/.idea/php.xml b/.idea/php.xml index 87d3ed251..6f2fae034 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -109,10 +109,12 @@ - + + + diff --git a/composer.json b/composer.json index 53caac3db..0ec00e2df 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,9 @@ "laravel/tinker": "^2", "nette/utils": "^3", "riverskies/laravel-mobile-detect": "^1", - "tightenco/ziggy": "^1" + "tightenco/ziggy": "^1", + "innocenzi/laravel-vite": "^0.1.4", + "openstamanager/tipi-attivita": "@dev" }, "require-dev": { "barryvdh/laravel-ide-helper": "^2", diff --git a/config/vite.php b/config/vite.php new file mode 100644 index 000000000..2ccbccaa2 --- /dev/null +++ b/config/vite.php @@ -0,0 +1,126 @@ + 0) { + foreach ($glob as $_dir) { + $dirs[] = $_dir; + } + } else { + break; + } + + $dir = $dirs[$next++]; + } + + return $relative ? array_unique(array_map(static fn ($dir) => ltrim(str_replace(base_path(), '', $dir), DIRECTORY_SEPARATOR), $dirs)) : $dirs; +} + +return [ + /* + |-------------------------------------------------------------------------- + | Entrypoints + |-------------------------------------------------------------------------- + | The files in the configured directories will be considered + | entry points and will not be required in the configuration file. + | To disable the feature, set to false. + */ + 'entrypoints' => array_merge( + listdirs(resource_path('js'), true), + [resource_path('scss/app.scss')] // listdirs(resource_path('scss'), true) + ), + 'ignore_patterns' => ['/\\.d\\.ts$/'], + + /* + |-------------------------------------------------------------------------- + | Aliases + |-------------------------------------------------------------------------- + | These aliases will be added to the Vite configuration and used + | to generate a proper tsconfig.json file. + */ + 'aliases' => [ + '@' => 'resources', + ], + + /* + |-------------------------------------------------------------------------- + | Static assets path + |-------------------------------------------------------------------------- + | This option defines the directory that Vite considers as the + | public directory. Its content will be copied to the build directory + | at build-time. + | https://vitejs.dev/config/#publicdir + */ + 'public_directory' => resource_path('static'), + + /* + |-------------------------------------------------------------------------- + | Ping timeout + |-------------------------------------------------------------------------- + | The maximum duration, in seconds, that the ping to the development + | server should take while trying to determine whether to use the + | manifest or the server in a local environment. Using false will disable + | the feature. + | https://laravel-vite.innocenzi.dev/guide/configuration.html#ping-timeout + */ + 'ping_timeout' => .5, + + /* + |-------------------------------------------------------------------------- + | Build path + |-------------------------------------------------------------------------- + | The directory, relative to /public, in which Vite will build + | the production files. This should match "build.outDir" in the Vite + | configuration file. + */ + 'build_path' => 'build', + + /* + |-------------------------------------------------------------------------- + | Development URL + |-------------------------------------------------------------------------- + | The URL at which the Vite development server runs. + | This is used to generate the script tags when developing. + */ + 'dev_url' => 'http://localhost:3000', + + /* + |-------------------------------------------------------------------------- + | Inject asset-fixing plugin + |-------------------------------------------------------------------------- + | Currently, Vite does not support loading assets from an URL other than + | the development server's URL. If this option is enabled, a plugin fixing + | this issue will be injected. + | See: https://github.com/innocenzi/laravel-vite/issues/31 + */ + 'asset_plugin' => [ + 'find_regex' => '/\/resources\/(.*)\.(svg|jp?g|png|webp)/', + 'replace_with' => '/resources/$1.$2', + ], + + /* + |-------------------------------------------------------------------------- + | Commands + |-------------------------------------------------------------------------- + | Defines the list of artisan commands that will be executed when + | the development server starts. + */ + 'commands' => [ + 'vite:aliases', + // 'typescript:generate' + ], +]; diff --git a/package.json b/package.json index 0b4cbd13d..bbbcd6d16 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,16 @@ { "name": "openstamanager", - "packageManager": "yarn@3.0.0", + "version": "3.0.0", + "packageManager": "pnpm", "private": true, + "main": "resources/js/index.js", "scripts": { - "dev": "npm run development", - "development": "mix", - "watch": "mix watch", - "watch-poll": "mix watch -- --watch-options-poll=1000", - "hot": "mix watch --hot", - "prod": "npm run production", - "production": "mix --production" + "build": "vite build", + "serve": "php artisan serve", + "watch": "vite build --watch", + "serve-watch": "concurrently --raw npm:serve npm:watch ", + "prepublishOnly": "pnpm run build", + "preinstall": "npx only-allow pnpm" }, "dependencies": { "@inertiajs/inertia": "^0.10.0", @@ -34,13 +35,15 @@ "@material/theme": "^12.0.0", "@mdi/font": "^5.9.55", "classnames": "^2.3.1", + "collect.js": "^4.28.6", "jquery": "^3.6.0", "lit-element": "^2.5.1", "locale-code": "^2.0.2", "lodash": "^4.17.21", "mithril": "^2.0.4", "mithril-node-render": "^3.0.1", - "modern-normalize": "^1.1.0" + "modern-normalize": "^1.1.0", + "openstamanager": "link:." }, "devDependencies": { "@babel/cli": "^7.14.8", @@ -50,8 +53,8 @@ "@babel/plugin-transform-react-jsx": "^7.14.9", "@babel/preset-env": "^7.14.9", "@babel/preset-flow": "^7.14.5", - "browser-sync": "^2.27.5", - "browser-sync-webpack-plugin": "2.3.0", + "@bunchtogether/vite-plugin-flow": "github:maicol07/vite-plugin-flow", + "concurrently": "^6.2.1", "eslint": "^7.32.0", "eslint-config-airbnb-base": "^14.2.1", "eslint-plugin-flowtype": "^5.8.2", @@ -70,6 +73,8 @@ "stylelint-config-recommended-scss": "^4.3.0", "stylelint-config-standard": "^22.0.0", "stylelint-scss": "^3.20.1", - "webpack": "^5.47.1" + "typescript": "^4.4.2", + "vite": "^2.5.3", + "vite-plugin-fonts": "^0.2.2" } } diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index e69de29bb..000000000 diff --git a/resources/js/Components/Card/Actions.js b/resources/js/Components/Card/Actions.jsx similarity index 50% rename from resources/js/Components/Card/Actions.js rename to resources/js/Components/Card/Actions.jsx index b86cb11bb..b40ed0f06 100644 --- a/resources/js/Components/Card/Actions.js +++ b/resources/js/Components/Card/Actions.jsx @@ -2,8 +2,11 @@ import Component from '../Component'; export default class Actions extends Component { view(vnode) { + this.attrs.addClassNames('mdc-card__actions', { + 'mdc-card__actions--full-bleed': this.attrs.has('full-bleed') + }); return ( -
+
{vnode.children}
); diff --git a/resources/js/Components/Card/Card.js b/resources/js/Components/Card/Card.js deleted file mode 100644 index 0f50a1c8e..000000000 --- a/resources/js/Components/Card/Card.js +++ /dev/null @@ -1,20 +0,0 @@ -import Component from '../Component'; - -export default class Card extends Component { - view(vnode) { - return
- {vnode.children} -
; - } -} diff --git a/resources/js/Components/Card/Card.jsx b/resources/js/Components/Card/Card.jsx new file mode 100644 index 000000000..bcb9ec008 --- /dev/null +++ b/resources/js/Components/Card/Card.jsx @@ -0,0 +1,15 @@ +import Component from '../Component'; + +export default class Card extends Component { + view(vnode) { + this.attrs.addClassNames('mdc-card', { + 'mdc-card--outlined': this.attrs.has('outlined') + }); + + return ( +
+ {vnode.children} +
+ ); + } +} diff --git a/resources/js/Components/Card/Content.js b/resources/js/Components/Card/Content.jsx similarity index 66% rename from resources/js/Components/Card/Content.js rename to resources/js/Components/Card/Content.jsx index b53997333..76dc4f0dc 100644 --- a/resources/js/Components/Card/Content.js +++ b/resources/js/Components/Card/Content.jsx @@ -2,8 +2,9 @@ import Component from '../Component'; export default class Content extends Component { view(vnode) { + this.attrs.addClassNames('mdc-card__content'); return ( -
+
{vnode.children}
); diff --git a/resources/js/Components/Card/Media.js b/resources/js/Components/Card/Media.js deleted file mode 100644 index d030d01b4..000000000 --- a/resources/js/Components/Card/Media.js +++ /dev/null @@ -1,14 +0,0 @@ -import Component from '../Component'; - -export default class Media extends Component { - view(vnode) { - return ( -
-
{vnode.attrs.title ?? ''}
-
- ); - } -} diff --git a/resources/js/Components/Card/Media.jsx b/resources/js/Components/Card/Media.jsx new file mode 100644 index 000000000..72e1e8dd4 --- /dev/null +++ b/resources/js/Components/Card/Media.jsx @@ -0,0 +1,19 @@ +import Component from '../Component'; + +export default class Media extends Component { + view(vnode) { + this.attrs.addClassNames('mdc-card__media', { + 'mdc-card__media--16-9': !this.attrs.has('no-scaling'), + 'mdc-card__media--square': this.attrs.has('square') + }); + if (this.attrs.has('background')) { + this.attrs.addStyles(`background-image: url("${this.attrs.get('background')}");`); + } + + return ( +
+
{this.attrs.get('title')}
+
+ ); + } +} diff --git a/resources/js/Components/Card/PrimaryAction.js b/resources/js/Components/Card/PrimaryAction.jsx similarity index 68% rename from resources/js/Components/Card/PrimaryAction.js rename to resources/js/Components/Card/PrimaryAction.jsx index 9bfd50e96..90c55408a 100644 --- a/resources/js/Components/Card/PrimaryAction.js +++ b/resources/js/Components/Card/PrimaryAction.jsx @@ -1,10 +1,12 @@ -import Component from '../Component'; import '@material/mwc-ripple'; +import Component from '../Component'; + export default class PrimaryAction extends Component { view(vnode) { + this.attrs.addClassNames('mdc-card__primary-action'); return ( -
+
{vnode.children}
diff --git a/resources/js/Components/Card/index.js b/resources/js/Components/Card/index.js new file mode 100644 index 000000000..464a00765 --- /dev/null +++ b/resources/js/Components/Card/index.js @@ -0,0 +1,6 @@ +export { default as Actions } from './Actions.jsx'; +export { default as Card } from './Card.jsx'; +export { default as Content } from './Content.jsx'; +export { default as Media } from './Media.jsx'; +export { default as PrimaryAction } from './PrimaryAction.jsx'; + diff --git a/resources/js/Components/Component.js b/resources/js/Components/Component.jsx similarity index 60% rename from resources/js/Components/Component.js rename to resources/js/Components/Component.jsx index 3f4557a47..0e11a4a9f 100644 --- a/resources/js/Components/Component.js +++ b/resources/js/Components/Component.jsx @@ -1,8 +1,16 @@ -/* eslint-disable no-unused-vars */ -import * as Mithril from 'mithril'; +import classnames, {Argument as ClassNames} from 'classnames'; +import collect, {Collection} from 'collect.js'; +import m, { + Children, ClassComponent, + Vnode, VnodeDOM +} from 'mithril'; -export interface ComponentAttrs extends Mithril.Attributes {} +interface Attributes extends Collection { + addClassNames(...classNames: ClassNames[]): void, + addStyles(...styles: string[]): void +} +// noinspection SpellCheckingInspection /** * @abstract * @@ -31,9 +39,9 @@ export interface ComponentAttrs extends Mithril.Attributes {} * @example * return m('div', MyComponent.component({foo: 'bar'), m('p', 'Hello World!')); * - * @see https://mithril.js.org/components.html + * @see https://js.org/components.html */ -export default class Component implements ComponentAttrs { +export default class Component implements ClassComponent { /** * The root DOM element for the component. * @@ -42,54 +50,58 @@ export default class Component implements ComponentAttrs { element: Element; /** - * The attributes passed into the component. + * The attributes passed into the component. They are transformed into a collection by initAttrs. + * + * @method addClassNames() + * + * @see https://js.org/components.html#passing-data-to-components + * @see initAttrs * - * @see https://mithril.js.org/components.html#passing-data-to-components * @protected */ - attrs; + attrs: Attributes; /** * @inheritdoc * @abstract */ - view(vnode: Mithril.Vnode): Mithril.Children {} + view(vnode: Vnode): Children {} /** * @inheritdoc */ - oninit(vnode: Mithril.Vnode) { + oninit(vnode: Vnode) { this.setAttrs(vnode.attrs); } /** * @inheritdoc */ - oncreate(vnode: Mithril.VnodeDOM) { + oncreate(vnode: VnodeDOM) { this.element = vnode.dom; } /** * @inheritdoc */ - onbeforeupdate(vnode: Mithril.VnodeDOM) { + onbeforeupdate(vnode: VnodeDOM) { this.setAttrs(vnode.attrs); } /** * @inheritdoc */ - onupdate(vnode: Mithril.VnodeDOM) {} + onupdate(vnode: VnodeDOM) {} /** * @inheritdoc */ - onbeforeremove(vnode: Mithril.VnodeDOM) {} + onbeforeremove(vnode: VnodeDOM) {} /** * @inheritdoc */ - onremove(vnode: Mithril.VnodeDOM) {} + onremove(vnode: VnodeDOM) {} /** * Returns a jQuery object for this component's element. If you pass in a @@ -105,22 +117,22 @@ export default class Component implements ComponentAttrs { * @final * @protected */ - /* $(selector?: string): JQuery { + $(selector?: string): JQuery { const $element: JQuery = $(this.element); - return selector ? $element.find(selector) : $element; - }; */ + return selector ? $element.find((element) => selector(element)) : $element; + } /** * Convenience method to attach a component without JSX. * Has the same effect as calling `m(THIS_CLASS, attrs, children)`. * - * @see https://mithril.js.org/hyperscript.html#mselector,-attributes,-children + * @see https://js.org/hyperscript.html#mselector,-attributes,-children */ - static component(attrs = {}, children = null): Mithril.Vnode { - const componentAttrs: Record = { ...attrs}; + static component(attributes = {}, children): Vnode { + const componentAttributes: Record = { ...attributes}; - return Mithril.m(this, componentAttrs, children); + return m(this, componentAttributes, children); } /** @@ -129,17 +141,32 @@ export default class Component implements ComponentAttrs { * * @private */ - setAttrs(attrs = {}): void { - this.initAttrs(attrs); - if (attrs) { - if ('children' in attrs) { + setAttrs(attributes: Object = {}): void { + this.initAttrs(attributes); + if (attributes) { + if ('children' in attributes) { + // noinspection JSUnresolvedVariable throw new Error(`[${this.constructor.name}] The "children" attribute of attrs should never be used. Either pass children in as the vnode children or rename the attribute`); } - if ('tag' in attrs) { + if ('tag' in attributes) { + // noinspection JSUnresolvedVariable throw new Error(`[${this.constructor.name}] You cannot use the "tag" attribute name with Mithril 2.`); } } - this.attrs = attrs; + this.attrs = collect(attributes); + this.attrs.macro('addClassNames', (...classNames: ClassNames[]) => { + this.attrs.put('className', classnames(this.attrs.get('className'), ...classNames)); + }); + this.attrs.macro('addStyles', (...styles: string[]) => { + let s: string = this.attrs.get('style', ''); + + if (!s.trimEnd().endsWith(';')) { + s += '; '; + } + + s += styles.join('; '); + this.attrs.put('style', s); + }); } /** @@ -149,5 +176,5 @@ export default class Component implements ComponentAttrs { * * @protected */ - initAttrs(attrs): void {} + initAttrs(attributes: Object): void {} } diff --git a/resources/js/Components/DataTable/DataTable.js b/resources/js/Components/DataTable/DataTable.jsx similarity index 87% rename from resources/js/Components/DataTable/DataTable.js rename to resources/js/Components/DataTable/DataTable.jsx index 3d2225ebf..577adbe73 100644 --- a/resources/js/Components/DataTable/DataTable.js +++ b/resources/js/Components/DataTable/DataTable.jsx @@ -1,18 +1,19 @@ import '@material/mwc-linear-progress'; import '@material/mwc-list/mwc-list-item'; import '@material/mwc-select'; + import Component from '../Component'; import Mdi from '../Mdi'; export default class DataTable extends Component { view(vnode) { - return
+ return
{vnode.children}
- {vnode.attrs.paginated ?
+ {this.attrs.has('paginated') ?
@@ -20,6 +21,8 @@ export default class DataTable extends Component {
+ {/* TODO: Rendere dinamico (permetti a chi chiama il componente di + scegliere i valori da visualizzare */} 10 25 50 @@ -30,6 +33,7 @@ export default class DataTable extends Component {
+ {/* TODO: Aggiungere i18n */} 1‑10 di 100
@@ -54,6 +58,5 @@ export default class DataTable extends Component {
; - // TODO: Inserire traduzioni } } diff --git a/resources/js/Components/DataTable/TableBody.js b/resources/js/Components/DataTable/TableBody.jsx similarity index 62% rename from resources/js/Components/DataTable/TableBody.js rename to resources/js/Components/DataTable/TableBody.jsx index ee9bd7898..98fc9742a 100644 --- a/resources/js/Components/DataTable/TableBody.js +++ b/resources/js/Components/DataTable/TableBody.jsx @@ -2,6 +2,6 @@ import Component from '../Component'; export default class TableBody extends Component { view(vnode) { - return {vnode.children}; + return {vnode.children}; } } diff --git a/resources/js/Components/DataTable/TableCell.js b/resources/js/Components/DataTable/TableCell.js deleted file mode 100644 index 1c43cabe4..000000000 --- a/resources/js/Components/DataTable/TableCell.js +++ /dev/null @@ -1,13 +0,0 @@ -import classnames from 'classnames'; -import Component from '../Component'; - -/** - * Attributes: - * - type: numeric, checkbox - */ -export default class TableCell extends Component { - view(vnode) { - this.attrs.className = classnames('mdc-data-table__cell', vnode.attrs.className, `mdc-data-table__cell--${vnode.attrs.type}`); - return {vnode.children}; - } -} diff --git a/resources/js/Components/DataTable/TableCell.jsx b/resources/js/Components/DataTable/TableCell.jsx new file mode 100644 index 000000000..512ebc80a --- /dev/null +++ b/resources/js/Components/DataTable/TableCell.jsx @@ -0,0 +1,12 @@ +import Component from '../Component'; + +/** + * Attributes: + * - type: numeric, checkbox + */ +export default class TableCell extends Component { + view(vnode) { + this.attrs.addClassNames('mdc-data-table__cell', `mdc-data-table__cell--${this.attrs.get('type')}`); + return {vnode.children}; + } +} diff --git a/resources/js/Components/DataTable/TableFooter.js b/resources/js/Components/DataTable/TableFooter.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/resources/js/Components/DataTable/TableFooter.jsx b/resources/js/Components/DataTable/TableFooter.jsx new file mode 100644 index 000000000..6b947d52d --- /dev/null +++ b/resources/js/Components/DataTable/TableFooter.jsx @@ -0,0 +1,7 @@ +import Component from '../Component'; + +export default class TableFooter extends Component { + view(vnode) { + return {vnode.children}; + } +} diff --git a/resources/js/Components/DataTable/TableHead.js b/resources/js/Components/DataTable/TableHead.jsx similarity index 62% rename from resources/js/Components/DataTable/TableHead.js rename to resources/js/Components/DataTable/TableHead.jsx index 0ca8568a8..094e7e47f 100644 --- a/resources/js/Components/DataTable/TableHead.js +++ b/resources/js/Components/DataTable/TableHead.jsx @@ -2,6 +2,6 @@ import Component from '../Component'; export default class TableHead extends Component { view(vnode) { - return {vnode.children}; + return {vnode.children}; } } diff --git a/resources/js/Components/DataTable/TableHeadCell.js b/resources/js/Components/DataTable/TableHeadCell.js deleted file mode 100644 index 44ca952e2..000000000 --- a/resources/js/Components/DataTable/TableHeadCell.js +++ /dev/null @@ -1,15 +0,0 @@ -import classnames from 'classnames'; -import Component from '../Component'; - -/** - * Attributes: - * - type: numeric, checkbox - */ -export default class TableHeadCell extends Component { - view(vnode) { - this.attrs.className = classnames('mdc-data-table__header-cell', vnode.attrs.className, { - [`mdc-data-table__header-cell--${vnode.attrs.type}`]: vnode.attrs.type - }); - return {vnode.children}; - } -} diff --git a/resources/js/Components/DataTable/TableHeadCell.jsx b/resources/js/Components/DataTable/TableHeadCell.jsx new file mode 100644 index 000000000..a736ce833 --- /dev/null +++ b/resources/js/Components/DataTable/TableHeadCell.jsx @@ -0,0 +1,14 @@ +import Component from '../Component'; + +/** + * Attributes: + * - type: numeric, checkbox + */ +export default class TableHeadCell extends Component { + view(vnode) { + this.attrs.addClassNames('mdc-data-table__header-cell', { + [`mdc-data-table__header-cell--${this.attrs.get('type')}`]: this.attrs.has('type') + }); + return {vnode.children}; + } +} diff --git a/resources/js/Components/DataTable/TableHeadRow.js b/resources/js/Components/DataTable/TableHeadRow.js deleted file mode 100644 index d8ac478ca..000000000 --- a/resources/js/Components/DataTable/TableHeadRow.js +++ /dev/null @@ -1,9 +0,0 @@ -import classnames from 'classnames'; -import Component from '../Component'; - -export default class TableHeadRow extends Component { - view(vnode) { - this.attrs.className = classnames('mdc-data-table__header-row', vnode.attrs.className); - return {vnode.children}; - } -} diff --git a/resources/js/Components/DataTable/TableHeadRow.jsx b/resources/js/Components/DataTable/TableHeadRow.jsx new file mode 100644 index 000000000..318bf0aa6 --- /dev/null +++ b/resources/js/Components/DataTable/TableHeadRow.jsx @@ -0,0 +1,8 @@ +import Component from '../Component'; + +export default class TableHeadRow extends Component { + view(vnode) { + this.attrs.addClassNames('mdc-data-table__header-row'); + return {vnode.children}; + } +} diff --git a/resources/js/Components/DataTable/TableRow.js b/resources/js/Components/DataTable/TableRow.js deleted file mode 100644 index 58f9a700a..000000000 --- a/resources/js/Components/DataTable/TableRow.js +++ /dev/null @@ -1,9 +0,0 @@ -import classnames from 'classnames'; -import Component from '../Component'; - -export default class TableRow extends Component { - view(vnode) { - this.attrs.className = classnames('mdc-data-table__row', vnode.attrs.className); - return {vnode.children}; - } -} diff --git a/resources/js/Components/DataTable/TableRow.jsx b/resources/js/Components/DataTable/TableRow.jsx new file mode 100644 index 000000000..650b6ebc3 --- /dev/null +++ b/resources/js/Components/DataTable/TableRow.jsx @@ -0,0 +1,8 @@ +import Component from '../Component'; + +export default class TableRow extends Component { + view(vnode) { + this.attrs.addClassNames('mdc-data-table__row'); + return {vnode.children}; + } +} diff --git a/resources/js/Components/DataTable/index.js b/resources/js/Components/DataTable/index.js new file mode 100644 index 000000000..4b2be1de9 --- /dev/null +++ b/resources/js/Components/DataTable/index.js @@ -0,0 +1,9 @@ +export { default as DataTable } from './DataTable.jsx'; +export { default as TableBody } from './TableBody.jsx'; +export { default as TableCell } from './TableCell.jsx'; +export { default as TableFooter } from './TableFooter.jsx'; +export { default as TableHead } from './TableHead.jsx'; +export { default as TableHeadCell } from './TableHeadCell.jsx'; +export { default as TableHeadRow } from './TableHeadRow.jsx'; +export { default as TableRow } from './TableRow.jsx'; + diff --git a/resources/js/Components/Grid/Cell.js b/resources/js/Components/Grid/Cell.js deleted file mode 100644 index 46ed62eeb..000000000 --- a/resources/js/Components/Grid/Cell.js +++ /dev/null @@ -1,20 +0,0 @@ -import Component from '../Component'; - -export default class Cell extends Component { - view(vnode) { - return
- {vnode.children} -
; - } -} diff --git a/resources/js/Components/Grid/Cell.jsx b/resources/js/Components/Grid/Cell.jsx new file mode 100644 index 000000000..6855e471b --- /dev/null +++ b/resources/js/Components/Grid/Cell.jsx @@ -0,0 +1,23 @@ +import Component from '../Component'; + +export default class Cell extends Component { + view(vnode) { + const spans = []; + for (const device of ['desktop', 'tablet', 'phone']) { + const key = `columnspan-${device}`; + if (this.attrs.has(key)) { + spans.push(`mdc-layout-grid__cell--span-${this.attrs.get(key)}-${device}`); + } + } + + this.attrs.addClassNames('mdc-layout-grid__cell', { + [`mdc-layout-grid__cell--span-${this.attrs.columnspan}`]: this.attrs.has('columnspan'), + [`mdc-layout-grid__cell--order-${this.attrs.get('order')}`]: this.attrs.has('order'), + [`mdc-layout-grid__cell--align-${this.attrs.get('align')}`]: this.attrs.has('align') + }, spans); + + return
+ {vnode.children} +
; + } +} diff --git a/resources/js/Components/Grid/LayoutGrid.js b/resources/js/Components/Grid/LayoutGrid.js deleted file mode 100644 index 748edce6b..000000000 --- a/resources/js/Components/Grid/LayoutGrid.js +++ /dev/null @@ -1,15 +0,0 @@ -import Component from '../Component'; - -export default class LayoutGrid extends Component { - view(vnode) { - return
- {vnode.children} -
; - } -} diff --git a/resources/js/Components/Grid/LayoutGrid.jsx b/resources/js/Components/Grid/LayoutGrid.jsx new file mode 100644 index 000000000..ded0e8df1 --- /dev/null +++ b/resources/js/Components/Grid/LayoutGrid.jsx @@ -0,0 +1,14 @@ +import Component from '../Component'; + +export default class LayoutGrid extends Component { + view(vnode) { + this.attrs.addClassNames('mdc-layout-grid', { + 'mdc-layout-grid--fixed-column-width': this.attrs.has('fixed'), + [`mdc-layout-grid--align-${this.attrs.get('align')}`]: this.attrs.has('align') + }); + + return
+ {vnode.children} +
; + } +} diff --git a/resources/js/Components/Grid/Row.js b/resources/js/Components/Grid/Row.js deleted file mode 100644 index 793a0f840..000000000 --- a/resources/js/Components/Grid/Row.js +++ /dev/null @@ -1,7 +0,0 @@ -import Component from '../Component'; - -export default class Row extends Component { - view(vnode) { - return
{vnode.children}
; - } -} diff --git a/resources/js/Components/Grid/Row.jsx b/resources/js/Components/Grid/Row.jsx new file mode 100644 index 000000000..e2428071e --- /dev/null +++ b/resources/js/Components/Grid/Row.jsx @@ -0,0 +1,8 @@ +import Component from '../Component'; + +export default class Row extends Component { + view(vnode) { + this.attrs.addClassNames('mdc-layout-grid__inner'); + return
{vnode.children}
; + } +} diff --git a/resources/js/Components/Grid/index.js b/resources/js/Components/Grid/index.js new file mode 100644 index 000000000..0ddb7d727 --- /dev/null +++ b/resources/js/Components/Grid/index.js @@ -0,0 +1,4 @@ +export { default as Cell } from './Cell.jsx'; +export { default as LayoutGrid } from './LayoutGrid.jsx'; +export { default as Row } from './Row.jsx'; + diff --git a/resources/js/Components/Mdi.js b/resources/js/Components/Mdi.js deleted file mode 100644 index 2fde80ca2..000000000 --- a/resources/js/Components/Mdi.js +++ /dev/null @@ -1,14 +0,0 @@ -import Component from './Component'; - -export default class Mdi extends Component { - view(vnode) { - return ; - /* - Quando MWC supporterà pienamente le icone SVG potremo - import * as mdi from '@mdi/js'; - import {camelCase} from 'lodash/string'; - return - - ; */ - } -} diff --git a/resources/js/Components/Mdi.jsx b/resources/js/Components/Mdi.jsx new file mode 100644 index 000000000..85b77effd --- /dev/null +++ b/resources/js/Components/Mdi.jsx @@ -0,0 +1,19 @@ +import Component from './Component'; + +export default class Mdi extends Component { + view(vnode) { + this.attrs.addClassNames('mdi', `mdi-${vnode.attrs.icon}`); + return ; + } +} + +/* + Quando MWC supporterà pienamente le icone SVG potremo fare così: + import * as mdi from '@mdi/js'; + import {camelCase} from 'lodash/string'; + + return + + ; +*/ diff --git a/resources/js/Components/Page.js b/resources/js/Components/Page.jsx similarity index 68% rename from resources/js/Components/Page.js rename to resources/js/Components/Page.jsx index 33948ee27..3c0b003a8 100644 --- a/resources/js/Components/Page.js +++ b/resources/js/Components/Page.jsx @@ -1,5 +1,6 @@ -import * as Mithril from 'mithril'; -import * as render from 'mithril-node-render'; +import {Vnode} from 'mithril'; +import {sync as render} from 'mithril-node-render'; + import Component from './Component'; /** @@ -21,21 +22,22 @@ export default class Page extends Component { /** * Ritorna una traduzione * - * @param {string|Mithril.Vnode} key Stringa di cui prelevare la traduzione + * @param {string|Vnode} key Stringa di cui prelevare la traduzione * @param {Object|boolean} replace Eventuali parametri da rimpiazzare. * Se il parametro è "true" (valore booleano), verrà ritornato il valore come stringa * (stesso funzionamento del parametro dedicato (sotto ↓)) * @param {boolean} returnAsString Se impostato a "true" vien ritornata una stringa invece di * un Vnode di Mithril - * @returns {Mithril.Vnode} + * + * @returns {Vnode} * * @protected */ __( - key: string | Mithril.Vnode, + key: string | Vnode, replace: Object | boolean = {}, returnAsString: boolean = false - ): Mithril.Vnode { + ): Vnode { let translation = (this.page.translations && this.page.translations[key]) ? this.page.translations[key] : key; @@ -44,11 +46,11 @@ export default class Page extends Component { return translation; } - Object.keys(replace).forEach(async (k: string) => { - // "'attrs' in replace[k]" controlla se replace[k] è un vnode di Mithril - translation = translation.replace(`:${k}`, ((typeof replace[k] === 'object' && 'attrs' in replace[k]) ? render.sync(replace[k]) : replace[k])); - }); + for (const k of Object.keys(replace)) { + // `'attrs' in replace[k]` controlla se replace[k] è un vnode di Mithril + translation = translation.replace(`:${k}`, ((typeof replace[k] === 'object' && 'attrs' in replace[k]) ? render(replace[k]) : replace[k])); + } - return returnAsString ? translation : Mithril.m.trust(translation); + return returnAsString ? translation : window.m.trust(translation); } } diff --git a/resources/js/Components/ListPage.js b/resources/js/Components/Pages/ListPage.jsx similarity index 54% rename from resources/js/Components/ListPage.js rename to resources/js/Components/Pages/ListPage.jsx index 1fca6bf9b..01e064400 100644 --- a/resources/js/Components/ListPage.js +++ b/resources/js/Components/Pages/ListPage.jsx @@ -1,11 +1,11 @@ -import Page from './Page'; -import DataTable from './DataTable/DataTable'; -import TableHeadCell from './DataTable/TableHeadCell'; -import TableHead from './DataTable/TableHead'; -import TableHeadRow from './DataTable/TableHeadRow'; -import TableBody from './DataTable/TableBody'; -import TableRow from './DataTable/TableRow'; -import TableCell from './DataTable/TableCell'; +import DataTable from '../DataTable/DataTable'; +import TableBody from '../DataTable/TableBody'; +import TableCell from '../DataTable/TableCell'; +import TableHead from '../DataTable/TableHead'; +import TableHeadCell from '../DataTable/TableHeadCell'; +import TableHeadRow from '../DataTable/TableHeadRow'; +import TableRow from '../DataTable/TableRow'; +import Page from '../Page'; /** * @abstract @@ -21,16 +21,16 @@ export default class ListPage extends Page { view(vnode) { const columns = this.columns.map( - (column, i) => ( - + (column, index) => ( + {column} ) ); - const rows = this.rows.length ? this.rows.map((row, i) => ( - - {row.map((cell, index) => {cell})} + const rows = this.rows.length > 0 ? this.rows.map((row, index) => ( + + {row.map((cell, index_) => {cell})} )) : {this.__('Non sono presenti dati')}; diff --git a/resources/js/Components/index.js b/resources/js/Components/index.js new file mode 100644 index 000000000..4f29370b0 --- /dev/null +++ b/resources/js/Components/index.js @@ -0,0 +1,8 @@ +export * from './Card'; +export { default as Component } from './Component.jsx'; +export * from './DataTable'; +export { extend, override } from './extend'; +export * from './Grid'; +export { default as ListPage } from './Pages/ListPage.jsx'; +export { default as Mdi } from './Mdi.jsx'; +export { default as Page } from './Page.jsx'; diff --git a/resources/js/Views/SetupPage.js b/resources/js/Views/SetupPage.jsx similarity index 78% rename from resources/js/Views/SetupPage.js rename to resources/js/Views/SetupPage.jsx index 42e7470b8..ec9d84e6f 100644 --- a/resources/js/Views/SetupPage.js +++ b/resources/js/Views/SetupPage.jsx @@ -6,30 +6,32 @@ import '@material/mwc-list/mwc-list-item'; import '@material/mwc-select'; import '@material/mwc-textarea'; import '@material/mwc-textfield'; + +import collect from 'collect.js'; import LocaleCode from 'locale-code'; import Mithril from 'mithril'; -import Page from '../Components/Page'; -import LayoutGrid from '../Components/Grid/LayoutGrid'; -import Row from '../Components/Grid/Row'; -import Cell from '../Components/Grid/Cell'; -import Mdi from '../Components/Mdi'; +import logoUrl from '@/static/images/logo_completo.png'; + import Card from '../Components/Card/Card'; import Content from '../Components/Card/Content'; +import Cell from '../Components/Grid/Cell'; +import LayoutGrid from '../Components/Grid/LayoutGrid'; +import Row from '../Components/Grid/Row'; +import Mdi from '../Components/Mdi'; +import Page from '../Components/Page'; export default class SetupPage extends Page { - // eslint-disable-next-line no-unused-vars view(vnode) { - const listItems: array[Mithril.Vnode] = []; + const listItems: Array[Mithril.Vnode] = []; - // noinspection JSUnresolvedVariable - this.page.props.languages.forEach((lang) => { - const prop = { + for (const lang of this.page.props.languages) { + const attributes = { selected: this.page.props.locale === lang }; const langCode = lang.replace('_', '-'); listItems.push( - + {LocaleCode.getLanguageNativeName(langCode)} ); - }); + } + + const examplesTexts = collect(); + for (const example of ['localhost', 'root', 'mysql', 'openstamanager']) { + examplesTexts.put(example, this.__('Esempio: :example', {example}, true)); + } return ( <> - + - {this.__('OpenSTAManager')} + {this.__('OpenSTAManager')}

{this.__('Benvenuto in :name!', {name: {this.__('OpenSTAManager')}})}

{this.__('Puoi procedere alla configurazione tecnica del software attraverso i ' + 'parametri seguenti, che potranno essere corretti secondo necessità tramite il file .env.')}
- {this.__("Se necessiti supporto puoi contattarci tramite l':contact_link o tramite il nostro :forum_link.", { - contact_link: {this.__('assistenza ufficiale')}, - forum_link: {this.__('forum')} + {this.__("Se necessiti supporto puoi contattarci tramite l':contactLink o tramite il nostro :forumLink.", { + // eslint-disable-next-line no-secrets/no-secrets + contactLink: {this.__('assistenza ufficiale')}, + forumLink: {this.__('forum')} })}

{this.__('Formato date')}

@@ -77,16 +85,16 @@ export default class SetupPage extends Page {

{this.__('Database')}

- + - + - + - +
@@ -134,8 +142,8 @@ export default class SetupPage extends Page {
- - + + ); diff --git a/resources/js/Views/index.js b/resources/js/Views/index.js new file mode 100644 index 000000000..10b46a519 --- /dev/null +++ b/resources/js/Views/index.js @@ -0,0 +1,2 @@ +export { default as SetupPage } from './SetupPage.jsx'; + diff --git a/resources/js/WebComponents/index.js b/resources/js/WebComponents/index.js new file mode 100644 index 000000000..62adea54a --- /dev/null +++ b/resources/js/WebComponents/index.js @@ -0,0 +1,3 @@ +export { default as Drawer } from './MaterialDrawer'; +export { default as TopAppBar } from './TopAppBar'; + diff --git a/resources/js/app.js b/resources/js/app.js index 563edc9ac..da5ea1cd4 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -1,12 +1,36 @@ -import m from 'mithril'; -import {createInertiaApp} from '@maicol07/inertia-mithril'; +import '../scss/app.scss'; import './_material'; +import {createInertiaApp} from '@maicol07/inertia-mithril'; +import {waitUntil} from 'async-wait-until'; +import jQuery from 'jquery'; +import m from 'mithril'; + +// Fix Mithril JSX durante la compilazione +m.Fragment = '['; + +// Variabili globali +window.$ = jQuery; +window.jQuery = jQuery; +window.m = m; + // noinspection JSIgnoredPromiseFromCall createInertiaApp({ - title: (title) => `${title} - OpenStaManager`, - resolve: async (name) => import(`./Views/${name}`), + title: title => `${title} - OpenSTAManager`, + resolve: async (name) => { + const split = name.split('::'); + + if (split.length === 1) { + return (await import(`./Views/${name}.jsx`)).default; + } + + const [, page] = split; + // noinspection JSUnresolvedVariable + await waitUntil(() => typeof window.extmodule !== 'undefined'); + // noinspection JSUnresolvedVariable + return window.extmodule[page]; + }, setup({ el, app }) { m.mount(el, app); - }, + } }); diff --git a/resources/js/index.js b/resources/js/index.js new file mode 100644 index 000000000..8001acccc --- /dev/null +++ b/resources/js/index.js @@ -0,0 +1,4 @@ +export * from './Components'; +export { default as utils } from './utils'; +export * from './Views'; +export * from './WebComponents'; diff --git a/resources/scss/_material.scss b/resources/scss/_material.scss index a7d037daf..873dbff45 100644 --- a/resources/scss/_material.scss +++ b/resources/scss/_material.scss @@ -1,12 +1,13 @@ @use "variables"; -@use '~@material/theme' with ( +@use '@material/theme' with ( $primary: variables.$primary, $secondary: variables.$secondary ); -@use "~@material/card"; -@use "~@material/layout-grid/mdc-layout-grid"; -@use "~@material/data-table/data-table"; -@use "~@mdi/font"; +@use "@material/card"; +@use "@material/layout-grid/mdc-layout-grid"; +@use "@material/data-table/data-table"; + +@import "https://cdn.jsdelivr.net/npm/@mdi/font@5.9.55/css/materialdesignicons.min.css"; @include card.core-styles; @include data-table.core-styles; diff --git a/resources/scss/app.scss b/resources/scss/app.scss index e6992e74c..a43b8ee51 100644 --- a/resources/scss/app.scss +++ b/resources/scss/app.scss @@ -1,6 +1,6 @@ @use 'variables'; -@import '~modern-normalize/modern-normalize.css'; +@import 'modern-normalize/modern-normalize.css'; @import 'material'; h1, diff --git a/public/images/favicon/android-chrome-192x192.png b/resources/static/images/favicon/android-chrome-192x192.png similarity index 100% rename from public/images/favicon/android-chrome-192x192.png rename to resources/static/images/favicon/android-chrome-192x192.png diff --git a/public/images/favicon/android-chrome-512x512.png b/resources/static/images/favicon/android-chrome-512x512.png similarity index 100% rename from public/images/favicon/android-chrome-512x512.png rename to resources/static/images/favicon/android-chrome-512x512.png diff --git a/public/images/favicon/apple-touch-icon.png b/resources/static/images/favicon/apple-touch-icon.png similarity index 100% rename from public/images/favicon/apple-touch-icon.png rename to resources/static/images/favicon/apple-touch-icon.png diff --git a/public/images/favicon/browserconfig.xml b/resources/static/images/favicon/browserconfig.xml similarity index 100% rename from public/images/favicon/browserconfig.xml rename to resources/static/images/favicon/browserconfig.xml diff --git a/public/images/favicon/favicon-16x16.png b/resources/static/images/favicon/favicon-16x16.png similarity index 100% rename from public/images/favicon/favicon-16x16.png rename to resources/static/images/favicon/favicon-16x16.png diff --git a/public/images/favicon/favicon-32x32.png b/resources/static/images/favicon/favicon-32x32.png similarity index 100% rename from public/images/favicon/favicon-32x32.png rename to resources/static/images/favicon/favicon-32x32.png diff --git a/public/images/favicon/favicon.ico b/resources/static/images/favicon/favicon.ico similarity index 100% rename from public/images/favicon/favicon.ico rename to resources/static/images/favicon/favicon.ico diff --git a/public/images/favicon/mstile-150x150.png b/resources/static/images/favicon/mstile-150x150.png similarity index 100% rename from public/images/favicon/mstile-150x150.png rename to resources/static/images/favicon/mstile-150x150.png diff --git a/public/images/favicon/safari-pinned-tab.svg b/resources/static/images/favicon/safari-pinned-tab.svg similarity index 100% rename from public/images/favicon/safari-pinned-tab.svg rename to resources/static/images/favicon/safari-pinned-tab.svg diff --git a/public/images/favicon/site.webmanifest b/resources/static/images/favicon/site.webmanifest similarity index 100% rename from public/images/favicon/site.webmanifest rename to resources/static/images/favicon/site.webmanifest diff --git a/public/images/logo.png b/resources/static/images/logo.png similarity index 100% rename from public/images/logo.png rename to resources/static/images/logo.png diff --git a/public/images/logo_completo.png b/resources/static/images/logo_completo.png similarity index 100% rename from public/images/logo_completo.png rename to resources/static/images/logo_completo.png diff --git a/routes/web.php b/routes/web.php index c09aab25b..356f893ee 100644 --- a/routes/web.php +++ b/routes/web.php @@ -22,6 +22,7 @@ Route::inertia('setup', 'SetupPage', [ glob(resource_path('lang').'/*.json') ), 'license' => file_get_contents(base_path('LICENSE')), + 'title' => __('Configurazione'), ]); Route::get('lang/{language}', function ($language) { diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 000000000..54ca36ece --- /dev/null +++ b/vite.config.js @@ -0,0 +1,57 @@ +import { esbuildFlowPlugin, flowPlugin } from '@bunchtogether/vite-plugin-flow'; +import { defineConfig } from 'laravel-vite'; +// import ViteFonts from 'vite-plugin-fonts'; + +export default defineConfig({ + assetsInclude: ['js', 'png'], + /* NOT WORKING: waiting a fix + css: { + preprocessorOptions: { + scss: { + additionalData: '$mdi-font-path: "./build";', + }, + }, + }, */ + build: { + minify: false, + rollupOptions: { + manualChunks: {}, + output: { + entryFileNames: '[name].js', + chunkFileNames: '[name].js', + assetFileNames: '[name].[ext]' + }, + preserveEntrySignatures: 'allow-extension' + } + }, + esbuild: { + jsxFactory: 'm', + jsxFragment: 'm.Fragment' + }, + optimizeDeps: { + esbuildOptions: { + plugins: [esbuildFlowPlugin(/\.(flow|jsx?)$/, (path) => (/\.jsx$/.test(path) ? 'jsx' : 'js'), { + all: true, + pretty: true, + ignoreUninitializedFields: false, + })] + }, + }, + plugins: [ + flowPlugin({ + include: /\.(flow|jsx?)$/, + exclude: /node_modules/, + flow: { + all: true, + pretty: true, + ignoreUninitializedFields: false, + } + }) + /* NOT WORKING. Waiting a fix + ViteFonts({ + google: { + families: ['Montserrat', 'Nunito'] + } + }) */ + ] +}); diff --git a/webpack.mix.js b/webpack.mix.js deleted file mode 100644 index 8f98640dd..000000000 --- a/webpack.mix.js +++ /dev/null @@ -1,42 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -// noinspection JSUnresolvedFunction - -const mix = require('laravel-mix'); -require('laravel-mix-versionhash'); -require('laravel-mix-serve'); - -/* - |-------------------------------------------------------------------------- - | Mix Asset Management - |-------------------------------------------------------------------------- - | - | Mix provides a clean, fluent API for defining some Webpack build steps - | for your Laravel applications. By default, we are compiling the CSS - | file for the application as well as bundling up all the JS files. - | - */ -mix.disableSuccessNotifications(); - -mix.js('resources/js/app.js', 'public/js') - .sass('resources/scss/app.scss', 'public/css', { - sassOptions: { - includePaths: ['./node_modules'], - }, - }).extract(); - -mix.autoload({ - jquery: ['$', 'global.$', 'window.$', 'jQuery', 'window.jQuery', 'global.jQuery'], - mithril: ['m'] -}); - -if (mix.inProduction()) { - mix.versionHash(); -} else { - // noinspection ChainedFunctionCallJS - mix.webpackConfig({ - devtool: 'source-map', - resolve: { - modules: ['./node_modules'], - }, - }).sourceMaps().serve().browserSync('localhost:8000'); -}