mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-22 15:39:11 +00:00
feat:toggle index column (#1037)
* feat:add `showIndexColumn` boolean property to `CuesheetSettings` * feat:use `showIndexColumn` to hide column index th/tr * feat:pass `showIndexColumn` to components * fix:update column headers naming
This commit is contained in:
@@ -25,7 +25,7 @@ interface CuesheetProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Cuesheet({ data, columns, handleUpdate, selectedId }: CuesheetProps) {
|
export default function Cuesheet({ data, columns, handleUpdate, selectedId }: CuesheetProps) {
|
||||||
const { followSelected, showSettings, showDelayBlock, showPrevious } = useCuesheetSettings();
|
const { followSelected, showSettings, showDelayBlock, showPrevious, showIndexColumn } = useCuesheetSettings();
|
||||||
|
|
||||||
const [columnVisibility, setColumnVisibility] = useLocalStorage({ key: 'table-hidden', defaultValue: {} });
|
const [columnVisibility, setColumnVisibility] = useLocalStorage({ key: 'table-hidden', defaultValue: {} });
|
||||||
const [columnOrder, saveColumnOrder] = useLocalStorage<string[]>({
|
const [columnOrder, saveColumnOrder] = useLocalStorage<string[]>({
|
||||||
@@ -112,7 +112,7 @@ export default function Cuesheet({ data, columns, handleUpdate, selectedId }: Cu
|
|||||||
)}
|
)}
|
||||||
<div ref={tableContainerRef} className={style.cuesheetContainer}>
|
<div ref={tableContainerRef} className={style.cuesheetContainer}>
|
||||||
<table className={style.cuesheet}>
|
<table className={style.cuesheet}>
|
||||||
<CuesheetHeader headerGroups={headerGroups} saveColumnOrder={reorder} />
|
<CuesheetHeader headerGroups={headerGroups} saveColumnOrder={reorder} showIndexColumn={showIndexColumn} />
|
||||||
<tbody>
|
<tbody>
|
||||||
{rowModel.rows.map((row) => {
|
{rowModel.rows.map((row) => {
|
||||||
const key = row.original.id;
|
const key = row.original.id;
|
||||||
@@ -165,6 +165,7 @@ export default function Cuesheet({ data, columns, handleUpdate, selectedId }: Cu
|
|||||||
selectedRef={isSelected ? selectedRef : undefined}
|
selectedRef={isSelected ? selectedRef : undefined}
|
||||||
skip={row.original.skip}
|
skip={row.original.skip}
|
||||||
colour={row.original.colour}
|
colour={row.original.colour}
|
||||||
|
showIndexColumn={showIndexColumn}
|
||||||
>
|
>
|
||||||
{row.getVisibleCells().map((cell) => {
|
{row.getVisibleCells().map((cell) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { Tooltip } from '@chakra-ui/react';
|
|
||||||
import {
|
import {
|
||||||
closestCorners,
|
closestCorners,
|
||||||
DndContext,
|
DndContext,
|
||||||
@@ -13,7 +12,6 @@ import { flexRender, HeaderGroup } from '@tanstack/react-table';
|
|||||||
import { OntimeRundownEntry } from 'ontime-types';
|
import { OntimeRundownEntry } from 'ontime-types';
|
||||||
|
|
||||||
import { getAccessibleColour } from '../../../common/utils/styleUtils';
|
import { getAccessibleColour } from '../../../common/utils/styleUtils';
|
||||||
import { tooltipDelayFast } from '../../../ontimeConfig';
|
|
||||||
|
|
||||||
import { SortableCell } from './SortableCell';
|
import { SortableCell } from './SortableCell';
|
||||||
|
|
||||||
@@ -22,10 +20,11 @@ import style from '../Cuesheet.module.scss';
|
|||||||
interface CuesheetHeaderProps {
|
interface CuesheetHeaderProps {
|
||||||
headerGroups: HeaderGroup<OntimeRundownEntry>[];
|
headerGroups: HeaderGroup<OntimeRundownEntry>[];
|
||||||
saveColumnOrder: (fromId: string, toId: string) => void;
|
saveColumnOrder: (fromId: string, toId: string) => void;
|
||||||
|
showIndexColumn: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function CuesheetHeader(props: CuesheetHeaderProps) {
|
export default function CuesheetHeader(props: CuesheetHeaderProps) {
|
||||||
const { headerGroups, saveColumnOrder } = props;
|
const { headerGroups, saveColumnOrder, showIndexColumn } = props;
|
||||||
|
|
||||||
const handleOnDragEnd = (event: DragEndEvent) => {
|
const handleOnDragEnd = (event: DragEndEvent) => {
|
||||||
const { delta, active, over } = event;
|
const { delta, active, over } = event;
|
||||||
@@ -61,11 +60,7 @@ export default function CuesheetHeader(props: CuesheetHeaderProps) {
|
|||||||
return (
|
return (
|
||||||
<DndContext key={key} sensors={sensors} collisionDetection={closestCorners} onDragEnd={handleOnDragEnd}>
|
<DndContext key={key} sensors={sensors} collisionDetection={closestCorners} onDragEnd={handleOnDragEnd}>
|
||||||
<tr key={headerGroup.id}>
|
<tr key={headerGroup.id}>
|
||||||
<th className={style.indexColumn}>
|
{showIndexColumn && <th className={style.indexColumn}>#</th>}
|
||||||
<Tooltip label='Event Order' openDelay={tooltipDelayFast}>
|
|
||||||
#
|
|
||||||
</Tooltip>
|
|
||||||
</th>
|
|
||||||
<SortableContext key={key} items={headerGroup.headers} strategy={horizontalListSortingStrategy}>
|
<SortableContext key={key} items={headerGroup.headers} strategy={horizontalListSortingStrategy}>
|
||||||
{headerGroup.headers.map((header) => {
|
{headerGroup.headers.map((header) => {
|
||||||
const width = header.getSize();
|
const width = header.getSize();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const pastOpacity = '0.2';
|
|||||||
|
|
||||||
interface EventRowProps {
|
interface EventRowProps {
|
||||||
eventIndex: number;
|
eventIndex: number;
|
||||||
|
showIndexColumn: boolean;
|
||||||
isPast?: boolean;
|
isPast?: boolean;
|
||||||
selectedRef?: MutableRefObject<HTMLTableRowElement | null>;
|
selectedRef?: MutableRefObject<HTMLTableRowElement | null>;
|
||||||
skip?: boolean;
|
skip?: boolean;
|
||||||
@@ -15,7 +16,7 @@ interface EventRowProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function EventRow(props: PropsWithChildren<EventRowProps>) {
|
function EventRow(props: PropsWithChildren<EventRowProps>) {
|
||||||
const { children, eventIndex, isPast, selectedRef, skip, colour } = props;
|
const { children, eventIndex, isPast, selectedRef, skip, colour, showIndexColumn } = props;
|
||||||
const ownRef = useRef<HTMLTableRowElement>(null);
|
const ownRef = useRef<HTMLTableRowElement>(null);
|
||||||
const [isVisible, setIsVisible] = useState(false);
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
|
|
||||||
@@ -55,9 +56,11 @@ function EventRow(props: PropsWithChildren<EventRowProps>) {
|
|||||||
style={{ opacity: `${isPast ? pastOpacity : '1'}` }}
|
style={{ opacity: `${isPast ? pastOpacity : '1'}` }}
|
||||||
ref={selectedRef ?? ownRef}
|
ref={selectedRef ?? ownRef}
|
||||||
>
|
>
|
||||||
<td className={style.indexColumn} style={{ backgroundColor: bgColour, color: textColour.color }}>
|
{showIndexColumn && (
|
||||||
{eventIndex}
|
<td className={style.indexColumn} style={{ backgroundColor: bgColour, color: textColour.color }}>
|
||||||
</td>
|
{eventIndex}
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
{isVisible ? children : null}
|
{isVisible ? children : null}
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,11 +24,13 @@ function CuesheetTableSettings(props: CuesheetTableSettingsProps) {
|
|||||||
const { columns, handleResetResizing, handleResetReordering, handleClearToggles } = props;
|
const { columns, handleResetResizing, handleResetReordering, handleClearToggles } = props;
|
||||||
const {
|
const {
|
||||||
followSelected,
|
followSelected,
|
||||||
|
showIndexColumn,
|
||||||
toggleFollow,
|
toggleFollow,
|
||||||
showPrevious,
|
showPrevious,
|
||||||
togglePreviousVisibility,
|
togglePreviousVisibility,
|
||||||
showDelayBlock,
|
showDelayBlock,
|
||||||
showDelayedTimes,
|
showDelayedTimes,
|
||||||
|
toggleIndexColumn,
|
||||||
toggleDelayedTimes,
|
toggleDelayedTimes,
|
||||||
toggleDelayVisibility,
|
toggleDelayVisibility,
|
||||||
} = useCuesheetSettings();
|
} = useCuesheetSettings();
|
||||||
@@ -38,6 +40,10 @@ function CuesheetTableSettings(props: CuesheetTableSettingsProps) {
|
|||||||
<div className={style.leftPanel}>
|
<div className={style.leftPanel}>
|
||||||
<div className={style.sectionTitle}>Toggle column visibility</div>
|
<div className={style.sectionTitle}>Toggle column visibility</div>
|
||||||
<div className={style.options}>
|
<div className={style.options}>
|
||||||
|
<label className={style.option}>
|
||||||
|
<Checkbox variant='ontime-ondark' defaultChecked={showIndexColumn} onChange={() => toggleIndexColumn()} />
|
||||||
|
Event Order
|
||||||
|
</label>
|
||||||
{columns.map((column) => {
|
{columns.map((column) => {
|
||||||
const columnHeader = column.columnDef.header;
|
const columnHeader = column.columnDef.header;
|
||||||
const visible = column.getIsVisible();
|
const visible = column.getIsVisible();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { booleanFromLocalStorage } from '../../../common/utils/localStorage';
|
|||||||
|
|
||||||
interface CuesheetSettings {
|
interface CuesheetSettings {
|
||||||
showSettings: boolean;
|
showSettings: boolean;
|
||||||
|
showIndexColumn: boolean;
|
||||||
followSelected: boolean;
|
followSelected: boolean;
|
||||||
showPrevious: boolean;
|
showPrevious: boolean;
|
||||||
showDelayBlock: boolean;
|
showDelayBlock: boolean;
|
||||||
@@ -12,6 +13,7 @@ interface CuesheetSettings {
|
|||||||
toggleSettings: (newValue?: boolean) => void;
|
toggleSettings: (newValue?: boolean) => void;
|
||||||
toggleFollow: (newValue?: boolean) => void;
|
toggleFollow: (newValue?: boolean) => void;
|
||||||
togglePreviousVisibility: (newValue?: boolean) => void;
|
togglePreviousVisibility: (newValue?: boolean) => void;
|
||||||
|
toggleIndexColumn: (newValue?: boolean) => void;
|
||||||
toggleDelayVisibility: (newValue?: boolean) => void;
|
toggleDelayVisibility: (newValue?: boolean) => void;
|
||||||
toggleDelayedTimes: (newValue?: boolean) => void;
|
toggleDelayedTimes: (newValue?: boolean) => void;
|
||||||
}
|
}
|
||||||
@@ -27,11 +29,13 @@ enum CuesheetKeys {
|
|||||||
Follow = 'ontime-cuesheet-follow-selected',
|
Follow = 'ontime-cuesheet-follow-selected',
|
||||||
DelayVisibility = 'ontime-cuesheet-show-delay',
|
DelayVisibility = 'ontime-cuesheet-show-delay',
|
||||||
PreviousVisibility = 'ontime-cuesheet-show-previous',
|
PreviousVisibility = 'ontime-cuesheet-show-previous',
|
||||||
|
ColumnIndex = 'ontime-cuesheet-show-index-column',
|
||||||
DelayedTimes = 'ontime-cuesheet-show-delayed',
|
DelayedTimes = 'ontime-cuesheet-show-delayed',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useCuesheetSettings = create<CuesheetSettings>()((set) => ({
|
export const useCuesheetSettings = create<CuesheetSettings>()((set) => ({
|
||||||
showSettings: false,
|
showSettings: false,
|
||||||
|
showIndexColumn: booleanFromLocalStorage(CuesheetKeys.ColumnIndex, true),
|
||||||
followSelected: booleanFromLocalStorage(CuesheetKeys.Follow, false),
|
followSelected: booleanFromLocalStorage(CuesheetKeys.Follow, false),
|
||||||
showPrevious: booleanFromLocalStorage(CuesheetKeys.PreviousVisibility, true),
|
showPrevious: booleanFromLocalStorage(CuesheetKeys.PreviousVisibility, true),
|
||||||
showDelayBlock: booleanFromLocalStorage(CuesheetKeys.DelayVisibility, true),
|
showDelayBlock: booleanFromLocalStorage(CuesheetKeys.DelayVisibility, true),
|
||||||
@@ -44,6 +48,12 @@ export const useCuesheetSettings = create<CuesheetSettings>()((set) => ({
|
|||||||
localStorage.setItem(CuesheetKeys.Follow, String(followSelected));
|
localStorage.setItem(CuesheetKeys.Follow, String(followSelected));
|
||||||
return { followSelected };
|
return { followSelected };
|
||||||
}),
|
}),
|
||||||
|
toggleIndexColumn: (newValue?: boolean) =>
|
||||||
|
set((state) => {
|
||||||
|
const showIndexColumn = toggle(state.showIndexColumn, newValue);
|
||||||
|
localStorage.setItem(CuesheetKeys.ColumnIndex, String(showIndexColumn));
|
||||||
|
return { showIndexColumn };
|
||||||
|
}),
|
||||||
togglePreviousVisibility: (newValue?: boolean) =>
|
togglePreviousVisibility: (newValue?: boolean) =>
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const showPrevious = toggle(state.showPrevious, newValue);
|
const showPrevious = toggle(state.showPrevious, newValue);
|
||||||
|
|||||||
Reference in New Issue
Block a user