refactor: simplify update functions

This commit is contained in:
Carlos Valente
2024-12-20 09:36:03 +01:00
committed by Carlos Valente
parent ab6765b332
commit 4cbe25a845
4 changed files with 47 additions and 83 deletions
+16
View File
@@ -6,6 +6,9 @@ declare module '*.scss' {
type ListenerType = (event: 'string', args: unknown[]) => void;
declare global {
/**
* Register the electron properties
*/
interface Window {
ipcRenderer: {
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' {
interface CSSProperties {
[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 { IoApps } from '@react-icons/all-files/io5/IoApps';
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 EmptyPage from '../../common/components/state/EmptyPage';
import ViewParamsEditor from '../../common/components/view-params-editor/ViewParamsEditor';
import { useEventAction } from '../../common/hooks/useEventAction';
import { useWindowTitle } from '../../common/hooks/useWindowTitle';
import useCustomFields from '../../common/hooks-query/useCustomFields';
import { useFlatRundown } from '../../common/hooks-query/useRundown';
@@ -32,7 +30,6 @@ export default function CuesheetPage() {
const { isOpen: isEventEditorOpen, onOpen: onEventEditorOpen, onClose: onEventEditorClose } = useDisclosure();
const [eventId, setEventId] = useState<string | null>(null);
const { updateCustomField, updateEvent } = useEventAction();
const columns = useMemo(() => makeCuesheetColumns(customFields), [customFields]);
useWindowTitle('Cuesheet');
@@ -43,65 +40,6 @@ export default function CuesheetPage() {
setSearchParams(searchParams);
}, [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
*/
@@ -151,13 +89,7 @@ export default function CuesheetPage() {
</CuesheetOverview>
<CuesheetProgress />
<CuesheetDnd columns={columns}>
<CuesheetTable
data={flatRundown}
columns={columns}
handleUpdate={handleUpdate}
handleUpdateCustom={handleUpdateCustom}
showModal={setShowModal}
/>
<CuesheetTable data={flatRundown} columns={columns} showModal={setShowModal} />
</CuesheetDnd>
</div>
</>
@@ -4,15 +4,16 @@ import { IoEllipsisHorizontal } from '@react-icons/all-files/io5/IoEllipsisHoriz
import { ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table';
import Color from 'color';
import {
CustomFieldLabel,
isOntimeBlock,
isOntimeDelay,
isOntimeEvent,
MaybeString,
OntimeEvent,
OntimeRundown,
OntimeRundownEntry,
} from 'ontime-types';
import { useEventAction } from '../../../common/hooks/useEventAction';
import useFollowComponent from '../../../common/hooks/useFollowComponent';
import { useSelectedEventId } from '../../../common/hooks/useSocket';
import { getAccessibleColour } from '../../../common/utils/styleUtils';
@@ -31,14 +32,13 @@ import style from './CuesheetTable.module.scss';
interface CuesheetTableProps {
data: OntimeRundown;
columns: ColumnDef<OntimeRundownEntry>[];
handleUpdate: (rowIndex: number, accessor: keyof OntimeRundownEntry, payload: string) => void;
handleUpdateCustom: (rowIndex: number, accessor: CustomFieldLabel, payload: string) => void;
showModal: (eventId: MaybeString) => void;
}
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 { followSelected, hideDelays, hidePast, hideIndexColumn } = useCuesheetOptions();
const { columnVisibility, columnOrder, columnSizing, resetColumnOrder, setColumnVisibility, setColumnSizing } =
@@ -57,13 +57,32 @@ export default function CuesheetTable(props: CuesheetTableProps) {
columnVisibility,
columnSizing,
},
meta: {
handleUpdate,
handleUpdateCustom,
},
onColumnVisibilityChange: setColumnVisibility,
onColumnSizingChange: setColumnSizing,
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 = () => {
@@ -37,8 +37,7 @@ function MakeDuration({ getValue }: CellContext<OntimeRundownEntry, unknown>) {
function MakeMultiLineField({ row, column, table }: CellContext<OntimeRundownEntry, unknown>) {
const update = useCallback(
(newValue: string) => {
// @ts-expect-error -- we inject this into react-table
table.options.meta?.handleUpdate(row.index, column.id, newValue);
table.options.meta?.handleUpdate(row.index, column.id, newValue, false);
},
// eslint-disable-next-line react-hooks/exhaustive-deps -- we skip table.options.meta since the reference seems unstable
[column.id, row.index],
@@ -57,8 +56,7 @@ function MakeMultiLineField({ row, column, table }: CellContext<OntimeRundownEnt
function MakeSingleLineField({ row, column, table }: CellContext<OntimeRundownEntry, unknown>) {
const update = useCallback(
(newValue: string) => {
// @ts-expect-error -- we inject this into react-table
table.options.meta?.handleUpdate(row.index, column.id, newValue);
table.options.meta?.handleUpdate(row.index, column.id, newValue, false);
},
// eslint-disable-next-line react-hooks/exhaustive-deps -- we skip table.options.meta since the reference seems unstable
[column.id, row.index],
@@ -77,8 +75,7 @@ function MakeSingleLineField({ row, column, table }: CellContext<OntimeRundownEn
function MakeCustomField({ row, column, table }: CellContext<OntimeRundownEntry, unknown>) {
const update = useCallback(
(newValue: string) => {
// @ts-expect-error -- we inject this into react-table
table.options.meta?.handleUpdateCustom(row.index, column.id, newValue);
table.options.meta?.handleUpdate(row.index, column.id, newValue, true);
},
// eslint-disable-next-line react-hooks/exhaustive-deps -- we skip table.options.meta since the reference seems unstable
[column.id, row.index],