Merge pull request #1094 from proddy/dev

edit name from dialog
This commit is contained in:
Proddy
2023-03-02 17:15:54 +01:00
committed by GitHub
4 changed files with 69 additions and 77 deletions

View File

@@ -25,9 +25,9 @@
"@mui/icons-material": "^5.11.11", "@mui/icons-material": "^5.11.11",
"@mui/material": "^5.11.11", "@mui/material": "^5.11.11",
"@remix-run/router": "^1.3.3", "@remix-run/router": "^1.3.3",
"@table-library/react-table-library": "4.0.28", "@table-library/react-table-library": "4.0.29",
"@types/lodash-es": "^4.17.6", "@types/lodash-es": "^4.17.6",
"@types/node": "^18.14.2", "@types/node": "^18.14.4",
"@types/react": "^18.0.28", "@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11", "@types/react-dom": "^18.0.11",
"@types/react-router-dom": "^5.3.3", "@types/react-router-dom": "^5.3.3",

View File

@@ -51,7 +51,6 @@ import { ScheduleItem, ScheduleFlag } from './types';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import * as EMSESP from './api'; import * as EMSESP from './api';
export const APIURL = window.location.origin + '/api/';
const SettingsScheduler: FC = () => { const SettingsScheduler: FC = () => {
const { LL, locale } = useI18nContext(); const { LL, locale } = useI18nContext();
@@ -69,7 +68,8 @@ const SettingsScheduler: FC = () => {
time: '12:00', time: '12:00',
cmd: '', cmd: '',
value: '', value: '',
description: '' description: '',
o_id: ''
}; };
const [schedule, setSchedule] = useState<ScheduleItem[]>([emptySchedule]); const [schedule, setSchedule] = useState<ScheduleItem[]>([emptySchedule]);
const [scheduleItem, setScheduleItem] = useState<ScheduleItem>(); const [scheduleItem, setScheduleItem] = useState<ScheduleItem>();
@@ -97,7 +97,7 @@ const SettingsScheduler: FC = () => {
const schedule_theme = useTheme({ const schedule_theme = useTheme({
Table: ` Table: `
--data-table-library_grid-template-columns: 140px 48px 324px 72px 240px repeat(1, minmax(100px, 1fr)); --data-table-library_grid-template-columns: 152px 36px 324px 72px 240px repeat(1, minmax(100px, 1fr));
`, `,
BaseRow: ` BaseRow: `
font-size: 14px; font-size: 14px;
@@ -106,22 +106,18 @@ const SettingsScheduler: FC = () => {
} }
`, `,
BaseCell: ` BaseCell: `
&:nth-of-type(1) {
padding: 8px;
}
&:nth-of-type(2) { &:nth-of-type(2) {
text-align: center; text-align: center;
}, }
&:nth-of-type(3) {
text-align: center;
},
&:nth-of-type(4) {
text-align: center;
},
`, `,
HeaderRow: ` HeaderRow: `
text-transform: uppercase; text-transform: uppercase;
background-color: black; background-color: black;
color: #90CAF9; color: #90CAF9;
.th { .th {
padding: 8px;
border-bottom: 1px solid #565656; border-bottom: 1px solid #565656;
font-weight: 500; font-weight: 500;
height: 36px; height: 36px;
@@ -132,7 +128,6 @@ const SettingsScheduler: FC = () => {
position: relative; position: relative;
cursor: pointer; cursor: pointer;
.td { .td {
padding: 8px;
border-top: 1px solid #565656; border-top: 1px solid #565656;
border-bottom: 1px solid #565656; border-bottom: 1px solid #565656;
} }
@@ -325,13 +320,8 @@ const SettingsScheduler: FC = () => {
}; };
const updateScheduleItem = () => { const updateScheduleItem = () => {
if (scheduleItem) { setSchedule([...schedule.filter((si) => creating || si.o_id !== scheduleItem.o_id), scheduleItem]);
const new_schedule = [...schedule.filter((si) => si.id !== scheduleItem.id), scheduleItem].sort((a, b) => setScheduleItem(undefined);
a.time.localeCompare(b.time)
);
setSchedule(new_schedule);
setScheduleItem(undefined);
}
}; };
const renderSchedule = () => { const renderSchedule = () => {
@@ -340,7 +330,11 @@ const SettingsScheduler: FC = () => {
} }
return ( return (
<Table data={{ nodes: schedule.filter((si) => !si.deleted) }} theme={schedule_theme} layout={{ custom: true }}> <Table
data={{ nodes: schedule.filter((si) => !si.deleted).sort((a, b) => a.time.localeCompare(b.time)) }}
theme={schedule_theme}
layout={{ custom: true }}
>
{(tableList: any) => ( {(tableList: any) => (
<> <>
<Header> <Header>
@@ -414,7 +408,7 @@ const SettingsScheduler: FC = () => {
if (scheduleItem) { if (scheduleItem) {
try { try {
setFieldErrors(undefined); setFieldErrors(undefined);
await validate(schedulerItemValidation(schedule, creating), scheduleItem); await validate(schedulerItemValidation(schedule, scheduleItem.o_id), scheduleItem);
updateScheduleItem(); updateScheduleItem();
} catch (errors: any) { } catch (errors: any) {
setFieldErrors(errors); setFieldErrors(errors);
@@ -422,44 +416,47 @@ const SettingsScheduler: FC = () => {
} }
}; };
const closeDialog = () => {
setScheduleItem(undefined);
setFieldErrors();
};
const renderEditSchedule = () => { const renderEditSchedule = () => {
if (scheduleItem) { if (scheduleItem) {
return ( return (
<Dialog open={!!scheduleItem} onClose={() => setScheduleItem(undefined)}> <Dialog open={!!scheduleItem} onClose={() => closeDialog()}>
<DialogTitle> <DialogTitle>
{creating ? LL.ADD(0) + ' ' + LL.NEW() + ' ' + LL.SCHEDULE() : LL.EDIT() + " '" + scheduleItem.id + "'"} {creating ? LL.ADD(0) + ' ' + LL.NEW() + ' ' + LL.SCHEDULE() : LL.EDIT() + " '" + scheduleItem.id + "'"}
</DialogTitle> </DialogTitle>
<DialogContent dividers> <DialogContent dividers>
<ValidatedTextField
fieldErrors={fieldErrors}
name="id"
label={LL.NAME()}
value={scheduleItem.id}
fullWidth
margin="normal"
sx={{ width: '60ch' }}
onChange={updateValue(setScheduleItem)}
/>
{creating ? ( {creating ? (
<> <RadioGroup
<ValidatedTextField row
fieldErrors={fieldErrors} name="schedule-type"
name="id" onChange={(event) => {
label={LL.NAME()} if ((event.target as HTMLInputElement).value === 't') {
value={scheduleItem.id} scheduleItem.flags = ScheduleFlag.SCHEDULE_TIMER;
fullWidth scheduleItem.time = '01:00';
margin="normal" } else {
sx={{ width: '60ch' }} scheduleItem.flags = 0;
onChange={updateValue(setScheduleItem)} }
/> updateValue(setScheduleItem);
<RadioGroup setFlags(['']); // refresh screen
row }}
name="schedule-type" >
onChange={(event) => { <FormControlLabel value="w" control={<Radio />} label={LL.WEEKLY()} />
if ((event.target as HTMLInputElement).value === 't') { <FormControlLabel value="t" control={<Radio />} label={LL.TIMER()} />
scheduleItem.flags = ScheduleFlag.SCHEDULE_TIMER; </RadioGroup>
scheduleItem.time = '01:00';
} else {
scheduleItem.flags = 0;
}
updateValue(setScheduleItem);
setFlags(['']); // refresh screen
}}
>
<FormControlLabel value="w" control={<Radio />} label={LL.WEEKLY()} />
<FormControlLabel value="t" control={<Radio />} label={LL.TIMER()} />
</RadioGroup>
</>
) : ( ) : (
<Typography variant="h6" color="primary" sx={{ pb: 1 }}> <Typography variant="h6" color="primary" sx={{ pb: 1 }}>
{LL.TYPE()}:&nbsp;{scheduleItem.flags & ScheduleFlag.SCHEDULE_TIMER ? LL.TIMER() : LL.WEEKLY()} {LL.TYPE()}:&nbsp;{scheduleItem.flags & ScheduleFlag.SCHEDULE_TIMER ? LL.TIMER() : LL.WEEKLY()}
@@ -536,16 +533,11 @@ const SettingsScheduler: FC = () => {
</Button> </Button>
</Box> </Box>
)} )}
<Button <Button startIcon={<CancelIcon />} variant="outlined" onClick={() => closeDialog()} color="secondary">
startIcon={<CancelIcon />}
variant="outlined"
onClick={() => setScheduleItem(undefined)}
color="secondary"
>
{LL.CANCEL()} {LL.CANCEL()}
</Button> </Button>
<Button <Button
startIcon={<DoneIcon />} startIcon={creating ? <AddIcon /> : <DoneIcon />}
variant="outlined" variant="outlined"
type="submit" type="submit"
onClick={() => validateScheduleItem()} onClick={() => validateScheduleItem()}

View File

@@ -85,26 +85,26 @@ export const createSettingsValidator = (settings: Settings) =>
}) })
}); });
export const schedulerItemValidation = (schedule: ScheduleItem[], creating: boolean) => export const schedulerItemValidation = (schedule: ScheduleItem[], o_id: string) =>
new Schema({ new Schema({
id: [ id: [
{ required: true, message: 'Name is required' }, { required: true, message: 'Name is required' },
{ {
type: 'string', type: 'string',
pattern: /^[a-zA-Z0-9_\\.]{1,24}$/, pattern: /^[a-zA-Z0-9_\\.]{1,15}$/,
message: "Must be 1-24 characters: alpha numeric, '_' or '.'" message: "Must be 1-15 characters: alpha numeric, '_' or '.'"
}, },
...(creating ? [uniqueIDValidator(schedule)] : []) ...[uniqueIDValidator(schedule, o_id)]
], ],
cmd: [ cmd: [
{ required: true, message: 'Command is required' }, { required: true, message: 'Command is required' },
{ type: 'string', min: 1, max: 32, message: 'Command must be 1-32 characters' } { type: 'string', min: 1, max: 64, message: 'Command must be 1-64 characters' }
] ]
}); });
export const uniqueIDValidator = (schedule: ScheduleItem[]) => ({ export const uniqueIDValidator = (schedule: ScheduleItem[], o_id: string) => ({
validator(rule: InternalRuleItem, id: string, callback: (error?: string) => void) { validator(rule: InternalRuleItem, id: string, callback: (error?: string) => void) {
if (id && schedule.find((si) => si.id === id)) { if (id && o_id !== id && schedule.find((si) => si.id === id)) {
callback('Name already in use'); callback('Name already in use');
} else { } else {
callback(); callback();

View File

@@ -1165,9 +1165,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@table-library/react-table-library@npm:4.0.28": "@table-library/react-table-library@npm:4.0.29":
version: 4.0.28 version: 4.0.29
resolution: "@table-library/react-table-library@npm:4.0.28" resolution: "@table-library/react-table-library@npm:4.0.29"
dependencies: dependencies:
clsx: 1.1.1 clsx: 1.1.1
react-virtualized-auto-sizer: 1.0.7 react-virtualized-auto-sizer: 1.0.7
@@ -1176,7 +1176,7 @@ __metadata:
"@emotion/react": ">= 11" "@emotion/react": ">= 11"
react: ">=16.8.0" react: ">=16.8.0"
react-dom: ">=16.8.0" react-dom: ">=16.8.0"
checksum: de4e429d5659e22b101cfef8aafb430fcad20a20af803982e50ed0ba070968c0bd5a3ef02e64c34eb1b40fb7415f417cf3c30b483b0b1bbad9099f15d6489a8d checksum: f0daace88cc8fe20d23a7f0430c293cd737ae9d0f5deb8ef17eec238917ae0fd1d196453e2a8549cdd6e92533c4e2469dc0aeb6333555502b8b1e5df4ab2bdf4
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1238,10 +1238,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/node@npm:^18.14.2": "@types/node@npm:^18.14.4":
version: 18.14.2 version: 18.14.4
resolution: "@types/node@npm:18.14.2" resolution: "@types/node@npm:18.14.4"
checksum: 53c07e721f6ae33de71306f6a0b75dae6066a4f55bd5484c93bd59ff25f0c5f004ceafeef509a4d0cb9e24a247efc34d50489bcc1b05a53ecc68e2fc088e65cb checksum: 3f2f625777747b9f87e793eea5a8bbf1ac2c828846bda5811d07a457d55cfe6762239779759de61e7b7e917632b9ceee3f7ffd2a024117e7ec364dc1b4eb8d55
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1485,10 +1485,10 @@ __metadata:
"@mui/icons-material": ^5.11.11 "@mui/icons-material": ^5.11.11
"@mui/material": ^5.11.11 "@mui/material": ^5.11.11
"@remix-run/router": ^1.3.3 "@remix-run/router": ^1.3.3
"@table-library/react-table-library": 4.0.28 "@table-library/react-table-library": 4.0.29
"@types/lodash-es": ^4.17.6 "@types/lodash-es": ^4.17.6
"@types/mime-types": ^2 "@types/mime-types": ^2
"@types/node": ^18.14.2 "@types/node": ^18.14.4
"@types/react": ^18.0.28 "@types/react": ^18.0.28
"@types/react-dom": ^18.0.11 "@types/react-dom": ^18.0.11
"@types/react-router-dom": ^5.3.3 "@types/react-router-dom": ^5.3.3