1
0
mirror of https://github.com/devcode-it/openstamanager.git synced 2025-06-05 22:09:38 +02:00

refactor: ♻️ Refactor generale

- Fix problemi rilevati da ESLint (per togliere alcune regole commentate)
- Spostati i tipi nella cartella typings
- Aggiunti alcuni alias per la cartella resources
This commit is contained in:
Maicol Battistini
2022-01-26 16:24:20 +01:00
parent 81e4b3214f
commit bda53b272a
27 changed files with 174 additions and 161 deletions

View File

@ -49,7 +49,10 @@ return [
| These aliases will be added to the Vite configuration and used
| to generate a proper tsconfig.json file.
*/
'aliases' => [],
'aliases' => [
'@openstamanager/assets' => 'resources/static',
'@openstamanager/scss' => 'resources/scss',
],
/*
|--------------------------------------------------------------------------
@ -115,7 +118,7 @@ return [
| the development server starts.
*/
'commands' => [
//'vite:aliases',
'vite:aliases',
// 'typescript:generate'
],
];

View File

@ -1,4 +1,3 @@
/* eslint-disable no-console */
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
@ -17,4 +16,5 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import gulp from 'gulp';

View File

@ -60,7 +60,7 @@
"redaxios": "^0.4.1"
},
"devDependencies": {
"@maicol07/eslint-config": "^2.1.2",
"@maicol07/eslint-config": "^2.1.4",
"@openstamanager/vite-config": "github:devcode-it/openstamanager-vite-config",
"@types/gulp": "^4.0.0",
"@types/lodash": "^4.14.178",

16
pnpm-lock.yaml generated
View File

@ -3,7 +3,7 @@ lockfileVersion: 5.3
specifiers:
'@inertiajs/inertia': ^0.10.1
'@inertiajs/progress': ^0.2.7
'@maicol07/eslint-config': ^2.1.2
'@maicol07/eslint-config': ^2.1.4
'@maicol07/inertia-mithril': ^0.4.2
'@maicol07/mwc-card': ^0.25.3
'@maicol07/mwc-layout-grid': ^0.25.3-1
@ -113,7 +113,7 @@ dependencies:
redaxios: 0.4.1
devDependencies:
'@maicol07/eslint-config': 2.1.2
'@maicol07/eslint-config': 2.1.4
'@openstamanager/vite-config': github.com/devcode-it/openstamanager-vite-config/9399c4a34b39c0a80408db47575794f089465be5_sass@1.49.0
'@types/gulp': 4.0.9
'@types/lodash': 4.14.178
@ -1346,8 +1346,8 @@ packages:
resolution: {integrity: sha512-B2JdRMwCGv+VpIRj3CYVQBx3muPDeE8y+HPgWqzrAHsO5/40BpwDFZeplIV790BaTqDVUDvZOKMSbuFM9zWC0w==}
dev: false
/@maicol07/eslint-config/2.1.2:
resolution: {integrity: sha512-9h75NkOwRvAUh52O1NsvYeFaVkOGxd8QNwQtpPLxXYjoM2IrJO59Al6wG+rVaI2np25ssMVuag+s3RO0rzuzeg==}
/@maicol07/eslint-config/2.1.4:
resolution: {integrity: sha512-g6PHY17wIU9zKnQEEo8hd/6q7Zyz4iUC13JaMUITUMSwls19mNUqGnK4eYuo8+wzu8vPgvks/RA/AZE0T6wsgg==}
dependencies:
'@typescript-eslint/eslint-plugin': 5.9.1_46ff1e3eeda39b5395c18b563a83af7a
'@typescript-eslint/parser': 5.9.1_eslint@8.6.0+typescript@4.5.5
@ -2956,7 +2956,7 @@ packages:
postcss: ^8.1.0
dependencies:
browserslist: 4.19.1
caniuse-lite: 1.0.30001301
caniuse-lite: 1.0.30001302
fraction.js: 4.1.2
normalize-range: 0.1.2
picocolors: 1.0.0
@ -3107,7 +3107,7 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
caniuse-lite: 1.0.30001301
caniuse-lite: 1.0.30001302
electron-to-chromium: 1.4.53
escalade: 3.1.1
node-releases: 2.0.1
@ -3173,8 +3173,8 @@ packages:
engines: {node: '>=6'}
dev: true
/caniuse-lite/1.0.30001301:
resolution: {integrity: sha512-csfD/GpHMqgEL3V3uIgosvh+SVIQvCh43SNu9HRbP1lnxkKm1kjDG4f32PP571JplkLjfS+mg2p1gxR7MYrrIA==}
/caniuse-lite/1.0.30001302:
resolution: {integrity: sha512-YYTMO+tfwvgUN+1ZnRViE53Ma1S/oETg+J2lISsqi/ZTNThj3ZYBOKP2rHwJc37oCsPqAzJ3w2puZHn0xlLPPw==}
dev: true
/cash-dom/8.1.0:

View File

@ -1,7 +1,8 @@
import {MaterialIcons} from '../typings';
import Component from './Component';
type Attributes = {
icon?: string
icon?: MaterialIcons
};
declare global {

View File

@ -28,7 +28,7 @@ import type {
SelectT,
TextAreaT,
TextFieldT
} from '../../types';
} from '../../typings';
import {
getFormData,
isFormValid,
@ -57,6 +57,8 @@ export type ColumnsT = Record<string, string | ColumnT>;
export type RowsT = Collection<IModel>;
export type SectionsT = Record<string, SectionT>;
const FIELDS: string = 'text-field, text-area, material-select';
/**
* @abstract
*/
@ -160,8 +162,8 @@ export class RecordsPage extends Page {
const dialog = $('mwc-dialog#add-record-dialog');
dialog
// eslint-disable-next-line sonarjs/no-duplicate-string
.find('text-field, text-area, material-select')
// eslint-disable-next-line unicorn/no-array-callback-reference
.find(FIELDS)
.each(async (index, field) => {
field.innerHTML = await this.getFieldBody(field as HTMLFormElement);
(field as HTMLInputElement).value = this.getModelValue(instance, field.id) as string;
@ -318,7 +320,8 @@ export class RecordsPage extends Page {
openNewRecordDialog(form: Cash, dialog: Cash) {
form
.find('text-field, text-area, material-select')
// eslint-disable-next-line unicorn/no-array-callback-reference
.find(FIELDS)
.each(async (index, field) => {
field.innerHTML = await this.getFieldBody(field as HTMLFormElement);
(field as HTMLInputElement).value = $(field)
@ -340,7 +343,6 @@ export class RecordsPage extends Page {
if (isFormValid(form)) {
const data = collect(getFormData(form));
// @ts-ignore
// eslint-disable-next-line new-cap
const instance = this.rows.get(data.get('id'), new this.model() as IModel) as IModel;
const modelId = await this.setter(instance, data);
@ -424,7 +426,6 @@ export class RecordsPage extends Page {
}
if (typeof column === 'object' && column.valueModifier) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
value = column.valueModifier(model, field);
}
@ -450,14 +451,13 @@ export class RecordsPage extends Page {
}
}
async getFieldBody(field: HTMLFormElement) {
async getFieldBody(field: HTMLFormElement & FieldT) {
const list = [];
switch (field.type ?? field.getAttribute('type')) {
case 'select':
// eslint-disable-next-line no-case-declarations
const section = collect(this.sections).first((s) => field.id in s.fields);
// eslint-disable-next-line no-case-declarations
case 'select': {
const section = collect(this.sections)
.first((s) => field.id in s.fields);
let {options} = section.fields[field.id] as SelectT;
if (options instanceof Promise) {
options = await options;
@ -474,18 +474,18 @@ export class RecordsPage extends Page {
}
break;
}
case 'checkbox':
return '';
case 'radio':
return '';
default:
}
if (field.icon) {
list.push(render(<Mdi icon={(field as FieldT).icon} slot="icon"/>));
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const {icon} = field;
if (typeof icon === 'string') {
list.push(render(<Mdi icon={icon} slot="icon"/>));
}
return list.join('');

View File

@ -21,7 +21,7 @@ export abstract class Model extends BaseModel {
super();
// Return a proxy of this object to allow dynamic attributes getters and setters
// eslint-disable-next-line no-constructor-return, @typescript-eslint/no-unsafe-return
// eslint-disable-next-line no-constructor-return
return new Proxy(this, {
get(target, property: string, receiver): any {
const snakeCasedProperty = snakeCase(property);

View File

@ -12,7 +12,7 @@ import logoUrl from '/images/logo_completo.png';
import LoadingButton from '../Components/LoadingButton';
import Mdi from '../Components/Mdi';
import Page from '../Components/Page';
import type {ErrorResponse} from '../types';
import type {ErrorResponse} from '../typings';
import {
getFormData,
isFormValid,

View File

@ -4,6 +4,7 @@ import '@material/mwc-checkbox';
import '@material/mwc-formfield';
import '../WebComponents/TextField';
import logoUrl from '@openstamanager/assets/images/logo_completo.png';
import type {Cash} from 'cash-dom';
import type {
Vnode,
@ -11,13 +12,10 @@ import type {
} from 'mithril';
import redaxios from 'redaxios';
// eslint-disable-next-line import/no-absolute-path
import logoUrl from '/images/logo_completo.png';
import LoadingButton from '../Components/LoadingButton';
import Mdi from '../Components/Mdi';
import Page from '../Components/Page';
import {ErrorResponse} from '../types';
import {ErrorResponse} from '../typings';
import {getFormData, isFormValid, showSnackbar} from '../utils';
export default class LoginPage extends Page {

View File

@ -11,13 +11,12 @@ import type {
} from 'mithril';
import redaxios from 'redaxios';
// eslint-disable-next-line import/no-absolute-path
import logoUrl from '/images/logo_completo.png';
import logoUrl from '@openstamanager/assets/images/logo_completo.png';
import LoadingButton from '../Components/LoadingButton';
import Mdi from '../Components/Mdi';
import Page from '../Components/Page';
import {ErrorResponse} from '../types';
import {ErrorResponse} from '../typings';
import {
getFormData,
isFormValid,

View File

@ -16,9 +16,7 @@ import LocaleCode from 'locale-code';
import type {Vnode, VnodeDOM} from 'mithril';
import redaxios, {Response} from 'redaxios';
// @ts-ignore
// eslint-disable-next-line import/no-absolute-path
import logoUrl from '/images/logo_completo.png';
import logoUrl from '@openstamanager/assets/images/logo_completo.png';
import {Alert} from '../Components';
import Mdi from '../Components/Mdi';

View File

@ -1,9 +1,8 @@
import {Drawer as MWCDrawer} from '@material/mwc-drawer';
import {css} from 'lit';
// eslint-disable-next-line import/extensions
import {customElement} from 'lit/decorators.js';
import type {JSXElement} from '../types';
import type {JSXElement} from '../typings';
declare global {
namespace JSX {

View File

@ -2,10 +2,9 @@ import {Select as MWCSelect} from '@material/mwc-select';
import {waitUntil} from 'async-wait-until';
import type {TemplateResult} from 'lit';
import {css, html} from 'lit';
// eslint-disable-next-line import/extensions
import {customElement} from 'lit/decorators.js';
import type {JSXElement} from '../types';
import type {JSXElement} from '../typings';
declare global {
namespace JSX {

View File

@ -1,8 +1,7 @@
import {TextArea as MWCTextArea} from '@material/mwc-textarea';
// eslint-disable-next-line import/extensions
import {customElement} from 'lit/decorators.js';
import {type JSXElement} from '../types';
import {type JSXElement} from '../typings';
declare global {
namespace JSX {

View File

@ -1,14 +1,13 @@
import {TextField as MWCTextField} from '@material/mwc-textfield';
import styles from '@openstamanager/scss/material/text-field.scss';
import {waitUntil} from 'async-wait-until';
import classnames from 'classnames';
import {
type TemplateResult, css, html, unsafeCSS
} from 'lit';
// eslint-disable-next-line import/extensions
import {customElement, property} from 'lit/decorators.js';
import styles from '../../scss/material/text-field.scss';
import type {JSXElement} from '../types';
import type {JSXElement} from '../typings';
declare global {
namespace JSX {

View File

@ -1,6 +1,5 @@
import {TopAppBar as MWCTopAppBar} from '@material/mwc-top-app-bar';
import {css} from 'lit';
// eslint-disable-next-line import/extensions
import {customElement} from 'lit/decorators.js';
declare global {

View File

@ -26,7 +26,7 @@ import $, {
type Element
} from 'cash-dom';
import type {JSXElement} from './types';
import type {JSXElement} from './typings';
// Declare Material JSX components
declare global {

View File

@ -7,7 +7,7 @@ import redaxios from 'redaxios';
import {registerSW} from 'virtual:pwa-register';
import {type Page} from './Components';
import {OpenSTAManager} from './types/modules';
import {OpenSTAManager} from './typings/modules';
import {
__ as translator,
showSnackbar
@ -72,7 +72,6 @@ $('#logout-button')
window.location.href = route('auth.login');
});
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
const updateSW = registerSW({
async onNeedRefresh() {
const action = await showSnackbar(__('Aggiornamento del frontend disponibile!'), false, __('Ricarica'), __('Annulla'));

View File

@ -5,7 +5,7 @@ import type cash from 'cash-dom';
import type Mithril from 'mithril';
import type router from 'ziggy-js';
import {OpenSTAManager} from './types/modules';
import {OpenSTAManager} from './typings/modules';
import type {__ as translator} from './utils';
declare global {

View File

@ -1,6 +1,6 @@
export * from './Components';
export * from './Models';
export * from './types';
export * from './typings';
export * from './utils';
export * from './Views';
export * from './WebComponents';

View File

@ -0,0 +1,89 @@
import {ListItemBase} from '@material/mwc-list/mwc-list-item-base.js';
import {
TextAreaCharCounter,
TextFieldInputMode,
TextFieldType
} from '@material/mwc-textfield';
import {MaterialIcons} from './icons';
export interface FieldT {
id?: string
name?: string
value?: string
label?: string
outlined?: boolean
helper?: string
icon?: string | MaterialIcons
placeholder?: string
disabled?: boolean
required?: boolean
validity?: ValidityState
validityTransform?: (
value: string,
nativeValidity: ValidityState,
) => Partial<ValidityState> | null
validateOnInitialRender?: boolean
validationMessage?: string
// Custom
type?: string
}
export type TextFieldT = FieldT & {
type?: TextFieldType
prefix?: string
suffix?: string
iconTrailing?: string
charCounter?: boolean
helperPersistent?: boolean | string
minLength?: number
maxLength?: number
pattern?: string
min?: number | string
max?: number | string
size?: number | null
step?: number | null
autoValidate?: boolean
willValidate?: boolean
name?: string
inputMode?: TextFieldInputMode
readOnly?: boolean
autocapitalize?:
| 'on'
| 'off'
| 'sentences'
| 'none'
| 'words'
| 'characters'
endAligned?: boolean
elementType?: 'text-field'
};
export type TextAreaT = FieldT & {
rows?: number
cols?: number
type?: TextFieldType
iconTrailing?: string
charCounter?: boolean | TextAreaCharCounter
willValidate?: boolean
helperPersistent?: boolean | string
maxLength?: number
elementType?: 'text-area'
};
export type SelectOptionsT = {
label: string
value: string
}[];
export type SelectT = FieldT & {
multiple?: boolean
naturalMenuWidth?: boolean
fixedMenuPosition?: boolean
willValidate?: boolean
elementType?: 'material-select'
selected?: ListItemBase | null
items?: ListItemBase[]
index?: number
options?: SelectOptionsT | Promise<SelectOptionsT>
};

View File

@ -1,103 +1,3 @@
import type {ListItemBase} from '@material/mwc-list/mwc-list-item-base';
import type {
TextAreaCharCounter,
TextFieldInputMode,
TextFieldType
} from '@material/mwc-textfield';
import type {
Attributes,
CommonAttributes
} from 'mithril';
import type {Response} from 'redaxios';
export type ErrorResponse = Response<{errors: Record<string, string>}>;
export type JSXElement<T> = Omit<Partial<T>, 'children' | 'style'>
& CommonAttributes<any, any>
& {
children?: JSX.Element | JSX.Element[] | Attributes | Attributes[],
style?: string | CSSStyleDeclaration
};
export type FieldT = {
id?: string
name?: string
value?: string
label?: string
outlined?: boolean
helper?: string
icon?: string | MaterialIcons
placeholder?: string
disabled?: boolean
required?: boolean
validity?: ValidityState
validityTransform?: (
value: string,
nativeValidity: ValidityState,
) => Partial<ValidityState> | null
validateOnInitialRender?: boolean
validationMessage?: string
// Custom
type?: string
};
export type TextFieldT = FieldT & {
type?: TextFieldType
prefix?: string
suffix?: string
iconTrailing?: string
charCounter?: boolean
helperPersistent?: boolean | string
minLength?: number
maxLength?: number
pattern?: string
min?: number | string
max?: number | string
size?: number | null
step?: number | null
autoValidate?: boolean
willValidate?: boolean
name?: string
inputMode?: TextFieldInputMode
readOnly?: boolean
autocapitalize?:
| 'on'
| 'off'
| 'sentences'
| 'none'
| 'words'
| 'characters'
endAligned?: boolean
elementType?: 'text-field'
};
export type TextAreaT = FieldT & {
rows?: number
cols?: number
type?: TextFieldType
iconTrailing?: string
charCounter?: boolean | TextAreaCharCounter
willValidate?: boolean
helperPersistent?: boolean | string
maxLength?: number
elementType?: 'text-area'
};
export type SelectOptionsT = {
label: string
value: string
}[];
export type SelectT = FieldT & {
multiple?: boolean
naturalMenuWidth?: boolean
fixedMenuPosition?: boolean
willValidate?: boolean
elementType?: 'material-select'
selected?: ListItemBase | null
items?: ListItemBase[]
index?: number
options?: SelectOptionsT | Promise<SelectOptionsT>
};
export type MaterialIcons =
| '10k'
| '10mp'

View File

@ -0,0 +1,7 @@
/**
* This file exports only from files that has exportable types definition or interfaces.
*/
export * from './forms';
export * from './icons';
export * from './misc';

View File

@ -0,0 +1,15 @@
import type {
Attributes,
CommonAttributes
} from 'mithril';
import type {Response} from 'redaxios';
export type ErrorResponse = Response<{errors: Record<string, string>}>;
export type JSXElement<T> = Omit<Partial<T>, 'children' | 'style'>
& CommonAttributes<any, any>
& {
children?: JSX.Element | JSX.Element[] | Attributes | Attributes[],
style?: string | CSSStyleDeclaration
};

View File

@ -1,4 +1,4 @@
import {MaterialIcons} from '../types';
import {MaterialIcons} from './icons';
declare module OpenSTAManager {
export type Modules = Record<string, Module>;

View File

@ -16,14 +16,23 @@
"dom.iterable"
],
"types": [
"vite/client",
"vite-plugin-pwa/client"
],
"baseUrl": ".",
"paths": {
"/images/logo_completo.png": ["resources/static/images/logo_completo.png"]
"@openstamanager/assets/*": [
"resources/static/*"
],
"@openstamanager/scss/*": [
"resources/scss/*"
]
}
},
"exclude": ["**/node_modules", "**/.*/"],
"exclude": [
"**/node_modules",
"**/.*/"
],
"include": [
"resources/js/**/*",
"gulpfile.ts",