mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-22 07:29:08 +00:00
refactor: simplify update functions
This commit is contained in:
committed by
Carlos Valente
parent
ab6765b332
commit
4cbe25a845
+16
@@ -6,6 +6,9 @@ declare module '*.scss' {
|
|||||||
type ListenerType = (event: 'string', args: unknown[]) => void;
|
type ListenerType = (event: 'string', args: unknown[]) => void;
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
/**
|
||||||
|
* Register the electron properties
|
||||||
|
*/
|
||||||
interface Window {
|
interface Window {
|
||||||
ipcRenderer: {
|
ipcRenderer: {
|
||||||
send: (channel: string, args?: string | object) => void;
|
send: (channel: string, args?: string | object) => void;
|
||||||
@@ -17,6 +20,19 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We pass a custom property to the table meta to allow field update
|
||||||
|
*/
|
||||||
|
declare module '@tanstack/react-table' {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
interface TableMeta<TData extends RowData> {
|
||||||
|
handleUpdate: (rowIndex: number, accessor: string, payload: string, isCustom: boolean) => void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow passing CSS Properties
|
||||||
|
*/
|
||||||
declare module 'react' {
|
declare module 'react' {
|
||||||
interface CSSProperties {
|
interface CSSProperties {
|
||||||
[key: `--${string}`]: string | number;
|
[key: `--${string}`]: string | number;
|
||||||
|
|||||||
@@ -3,12 +3,10 @@ import { useSearchParams } from 'react-router-dom';
|
|||||||
import { IconButton, Modal, ModalContent, ModalOverlay, useDisclosure } from '@chakra-ui/react';
|
import { IconButton, Modal, ModalContent, ModalOverlay, useDisclosure } from '@chakra-ui/react';
|
||||||
import { IoApps } from '@react-icons/all-files/io5/IoApps';
|
import { IoApps } from '@react-icons/all-files/io5/IoApps';
|
||||||
import { IoSettingsOutline } from '@react-icons/all-files/io5/IoSettingsOutline';
|
import { IoSettingsOutline } from '@react-icons/all-files/io5/IoSettingsOutline';
|
||||||
import { CustomFieldLabel, isOntimeEvent, OntimeEvent } from 'ontime-types';
|
|
||||||
|
|
||||||
import ProductionNavigationMenu from '../../common/components/navigation-menu/ProductionNavigationMenu';
|
import ProductionNavigationMenu from '../../common/components/navigation-menu/ProductionNavigationMenu';
|
||||||
import EmptyPage from '../../common/components/state/EmptyPage';
|
import EmptyPage from '../../common/components/state/EmptyPage';
|
||||||
import ViewParamsEditor from '../../common/components/view-params-editor/ViewParamsEditor';
|
import ViewParamsEditor from '../../common/components/view-params-editor/ViewParamsEditor';
|
||||||
import { useEventAction } from '../../common/hooks/useEventAction';
|
|
||||||
import { useWindowTitle } from '../../common/hooks/useWindowTitle';
|
import { useWindowTitle } from '../../common/hooks/useWindowTitle';
|
||||||
import useCustomFields from '../../common/hooks-query/useCustomFields';
|
import useCustomFields from '../../common/hooks-query/useCustomFields';
|
||||||
import { useFlatRundown } from '../../common/hooks-query/useRundown';
|
import { useFlatRundown } from '../../common/hooks-query/useRundown';
|
||||||
@@ -32,7 +30,6 @@ export default function CuesheetPage() {
|
|||||||
const { isOpen: isEventEditorOpen, onOpen: onEventEditorOpen, onClose: onEventEditorClose } = useDisclosure();
|
const { isOpen: isEventEditorOpen, onOpen: onEventEditorOpen, onClose: onEventEditorClose } = useDisclosure();
|
||||||
const [eventId, setEventId] = useState<string | null>(null);
|
const [eventId, setEventId] = useState<string | null>(null);
|
||||||
|
|
||||||
const { updateCustomField, updateEvent } = useEventAction();
|
|
||||||
const columns = useMemo(() => makeCuesheetColumns(customFields), [customFields]);
|
const columns = useMemo(() => makeCuesheetColumns(customFields), [customFields]);
|
||||||
|
|
||||||
useWindowTitle('Cuesheet');
|
useWindowTitle('Cuesheet');
|
||||||
@@ -43,65 +40,6 @@ export default function CuesheetPage() {
|
|||||||
setSearchParams(searchParams);
|
setSearchParams(searchParams);
|
||||||
}, [searchParams, setSearchParams]);
|
}, [searchParams, setSearchParams]);
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles updating a custom field
|
|
||||||
*/
|
|
||||||
const handleUpdateCustom = useCallback(
|
|
||||||
async (rowIndex: number, accessor: CustomFieldLabel, payload: string) => {
|
|
||||||
if (!flatRundown || rundownStatus !== 'success') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rowIndex == null || accessor == null || payload == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if value is the same
|
|
||||||
const event = flatRundown[rowIndex];
|
|
||||||
if (!event || !isOntimeEvent(event)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// skip if there is no value change
|
|
||||||
const previousValue = event.custom[accessor];
|
|
||||||
if (previousValue === payload) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
updateCustomField(event.id, accessor, payload);
|
|
||||||
},
|
|
||||||
[flatRundown, rundownStatus, updateCustomField],
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles updating all other string fields
|
|
||||||
*/
|
|
||||||
const handleUpdate = useCallback(
|
|
||||||
async (rowIndex: number, accessor: keyof OntimeEvent, payload: string) => {
|
|
||||||
if (!flatRundown || rundownStatus !== 'success') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rowIndex == null || accessor == null || payload == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if value is the same
|
|
||||||
const event = flatRundown[rowIndex];
|
|
||||||
if (!event || !isOntimeEvent(event)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// skip if there is no value change
|
|
||||||
const previousValue = event[accessor];
|
|
||||||
if (previousValue === payload) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateEvent({ id: event.id, [accessor]: payload });
|
|
||||||
},
|
|
||||||
[flatRundown, rundownStatus, updateEvent],
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles setting the edit modal target and visibility
|
* Handles setting the edit modal target and visibility
|
||||||
*/
|
*/
|
||||||
@@ -151,13 +89,7 @@ export default function CuesheetPage() {
|
|||||||
</CuesheetOverview>
|
</CuesheetOverview>
|
||||||
<CuesheetProgress />
|
<CuesheetProgress />
|
||||||
<CuesheetDnd columns={columns}>
|
<CuesheetDnd columns={columns}>
|
||||||
<CuesheetTable
|
<CuesheetTable data={flatRundown} columns={columns} showModal={setShowModal} />
|
||||||
data={flatRundown}
|
|
||||||
columns={columns}
|
|
||||||
handleUpdate={handleUpdate}
|
|
||||||
handleUpdateCustom={handleUpdateCustom}
|
|
||||||
showModal={setShowModal}
|
|
||||||
/>
|
|
||||||
</CuesheetDnd>
|
</CuesheetDnd>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -4,15 +4,16 @@ import { IoEllipsisHorizontal } from '@react-icons/all-files/io5/IoEllipsisHoriz
|
|||||||
import { ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table';
|
import { ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table';
|
||||||
import Color from 'color';
|
import Color from 'color';
|
||||||
import {
|
import {
|
||||||
CustomFieldLabel,
|
|
||||||
isOntimeBlock,
|
isOntimeBlock,
|
||||||
isOntimeDelay,
|
isOntimeDelay,
|
||||||
isOntimeEvent,
|
isOntimeEvent,
|
||||||
MaybeString,
|
MaybeString,
|
||||||
|
OntimeEvent,
|
||||||
OntimeRundown,
|
OntimeRundown,
|
||||||
OntimeRundownEntry,
|
OntimeRundownEntry,
|
||||||
} from 'ontime-types';
|
} from 'ontime-types';
|
||||||
|
|
||||||
|
import { useEventAction } from '../../../common/hooks/useEventAction';
|
||||||
import useFollowComponent from '../../../common/hooks/useFollowComponent';
|
import useFollowComponent from '../../../common/hooks/useFollowComponent';
|
||||||
import { useSelectedEventId } from '../../../common/hooks/useSocket';
|
import { useSelectedEventId } from '../../../common/hooks/useSocket';
|
||||||
import { getAccessibleColour } from '../../../common/utils/styleUtils';
|
import { getAccessibleColour } from '../../../common/utils/styleUtils';
|
||||||
@@ -31,14 +32,13 @@ import style from './CuesheetTable.module.scss';
|
|||||||
interface CuesheetTableProps {
|
interface CuesheetTableProps {
|
||||||
data: OntimeRundown;
|
data: OntimeRundown;
|
||||||
columns: ColumnDef<OntimeRundownEntry>[];
|
columns: ColumnDef<OntimeRundownEntry>[];
|
||||||
handleUpdate: (rowIndex: number, accessor: keyof OntimeRundownEntry, payload: string) => void;
|
|
||||||
handleUpdateCustom: (rowIndex: number, accessor: CustomFieldLabel, payload: string) => void;
|
|
||||||
showModal: (eventId: MaybeString) => void;
|
showModal: (eventId: MaybeString) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function CuesheetTable(props: CuesheetTableProps) {
|
export default function CuesheetTable(props: CuesheetTableProps) {
|
||||||
const { data, columns, handleUpdate, handleUpdateCustom, showModal } = props;
|
const { data, columns, showModal } = props;
|
||||||
|
|
||||||
|
const { updateEvent } = useEventAction();
|
||||||
const { selectedEventId } = useSelectedEventId();
|
const { selectedEventId } = useSelectedEventId();
|
||||||
const { followSelected, hideDelays, hidePast, hideIndexColumn } = useCuesheetOptions();
|
const { followSelected, hideDelays, hidePast, hideIndexColumn } = useCuesheetOptions();
|
||||||
const { columnVisibility, columnOrder, columnSizing, resetColumnOrder, setColumnVisibility, setColumnSizing } =
|
const { columnVisibility, columnOrder, columnSizing, resetColumnOrder, setColumnVisibility, setColumnSizing } =
|
||||||
@@ -57,13 +57,32 @@ export default function CuesheetTable(props: CuesheetTableProps) {
|
|||||||
columnVisibility,
|
columnVisibility,
|
||||||
columnSizing,
|
columnSizing,
|
||||||
},
|
},
|
||||||
meta: {
|
|
||||||
handleUpdate,
|
|
||||||
handleUpdateCustom,
|
|
||||||
},
|
|
||||||
onColumnVisibilityChange: setColumnVisibility,
|
onColumnVisibilityChange: setColumnVisibility,
|
||||||
onColumnSizingChange: setColumnSizing,
|
onColumnSizingChange: setColumnSizing,
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
meta: {
|
||||||
|
handleUpdate: async (rowIndex: number, accessor: string, payload: string, isCustom = false) => {
|
||||||
|
// check if value is the same
|
||||||
|
const event = data[rowIndex];
|
||||||
|
if (!event || !isOntimeEvent(event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip if there is no value change
|
||||||
|
const key = accessor as keyof OntimeEvent;
|
||||||
|
const previousValue = event[key];
|
||||||
|
if (previousValue === payload) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCustom) {
|
||||||
|
updateEvent({ id: event.id, custom: { [accessor]: payload } });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateEvent({ id: event.id, [accessor]: payload });
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const setAllVisible = () => {
|
const setAllVisible = () => {
|
||||||
|
|||||||
+3
-6
@@ -37,8 +37,7 @@ function MakeDuration({ getValue }: CellContext<OntimeRundownEntry, unknown>) {
|
|||||||
function MakeMultiLineField({ row, column, table }: CellContext<OntimeRundownEntry, unknown>) {
|
function MakeMultiLineField({ row, column, table }: CellContext<OntimeRundownEntry, unknown>) {
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
(newValue: string) => {
|
(newValue: string) => {
|
||||||
// @ts-expect-error -- we inject this into react-table
|
table.options.meta?.handleUpdate(row.index, column.id, newValue, false);
|
||||||
table.options.meta?.handleUpdate(row.index, column.id, newValue);
|
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps -- we skip table.options.meta since the reference seems unstable
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- we skip table.options.meta since the reference seems unstable
|
||||||
[column.id, row.index],
|
[column.id, row.index],
|
||||||
@@ -57,8 +56,7 @@ function MakeMultiLineField({ row, column, table }: CellContext<OntimeRundownEnt
|
|||||||
function MakeSingleLineField({ row, column, table }: CellContext<OntimeRundownEntry, unknown>) {
|
function MakeSingleLineField({ row, column, table }: CellContext<OntimeRundownEntry, unknown>) {
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
(newValue: string) => {
|
(newValue: string) => {
|
||||||
// @ts-expect-error -- we inject this into react-table
|
table.options.meta?.handleUpdate(row.index, column.id, newValue, false);
|
||||||
table.options.meta?.handleUpdate(row.index, column.id, newValue);
|
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps -- we skip table.options.meta since the reference seems unstable
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- we skip table.options.meta since the reference seems unstable
|
||||||
[column.id, row.index],
|
[column.id, row.index],
|
||||||
@@ -77,8 +75,7 @@ function MakeSingleLineField({ row, column, table }: CellContext<OntimeRundownEn
|
|||||||
function MakeCustomField({ row, column, table }: CellContext<OntimeRundownEntry, unknown>) {
|
function MakeCustomField({ row, column, table }: CellContext<OntimeRundownEntry, unknown>) {
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
(newValue: string) => {
|
(newValue: string) => {
|
||||||
// @ts-expect-error -- we inject this into react-table
|
table.options.meta?.handleUpdate(row.index, column.id, newValue, true);
|
||||||
table.options.meta?.handleUpdateCustom(row.index, column.id, newValue);
|
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps -- we skip table.options.meta since the reference seems unstable
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- we skip table.options.meta since the reference seems unstable
|
||||||
[column.id, row.index],
|
[column.id, row.index],
|
||||||
|
|||||||
Reference in New Issue
Block a user