mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-25 00:49:10 +00:00
more comprihensive disable logic and better description + icons
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { MaybeNumber } from 'ontime-types';
|
import { MaybeNumber } from 'ontime-types';
|
||||||
import { IoLockClosed, IoLockOpenOutline } from 'react-icons/io5';
|
import { TbTargetArrow, TbTarget } from 'react-icons/tb';
|
||||||
|
|
||||||
import IconButton from '../../../../common/components/buttons/IconButton';
|
import IconButton from '../../../../common/components/buttons/IconButton';
|
||||||
import * as Editor from '../../../../common/components/editor-utils/EditorUtils';
|
import * as Editor from '../../../../common/components/editor-utils/EditorUtils';
|
||||||
@@ -37,7 +37,7 @@ export default function TargetDurationInput({ duration, targetDuration, submitHa
|
|||||||
data-testid='lock__duration'
|
data-testid='lock__duration'
|
||||||
render={<IconButton variant='subtle-white' className={isLocked ? style.active : style.inactive} />}
|
render={<IconButton variant='subtle-white' className={isLocked ? style.active : style.inactive} />}
|
||||||
>
|
>
|
||||||
{isLocked ? <IoLockClosed /> : <IoLockOpenOutline />}
|
{isLocked ? <TbTargetArrow /> : <TbTarget />}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TimeInputGroup>
|
</TimeInputGroup>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useSortable } from '@dnd-kit/sortable';
|
import { useSortable } from '@dnd-kit/sortable';
|
||||||
import { CSS } from '@dnd-kit/utilities';
|
import { CSS } from '@dnd-kit/utilities';
|
||||||
import { Day, EndAction, EntryId, Playback, TimeStrategy, TimerType } from 'ontime-types';
|
import { Day, EndAction, EntryId, Maybe, OntimeGroup, Playback, TimeStrategy, TimerType } from 'ontime-types';
|
||||||
import { isPlaybackActive } from 'ontime-utils';
|
import { isPlaybackActive } from 'ontime-utils';
|
||||||
import { MouseEvent, useEffect, useRef } from 'react';
|
import { MouseEvent, useEffect, useRef } from 'react';
|
||||||
import {
|
import {
|
||||||
@@ -16,6 +16,7 @@ import {
|
|||||||
import { TbClockPin, TbFlagFilled, TbListNumbers } from 'react-icons/tb';
|
import { TbClockPin, TbFlagFilled, TbListNumbers } from 'react-icons/tb';
|
||||||
|
|
||||||
import { useEntryActionsContext } from '../../../common/context/EntryActionsContext';
|
import { useEntryActionsContext } from '../../../common/context/EntryActionsContext';
|
||||||
|
import { useEntry } from '../../../common/hooks-query/useRundown';
|
||||||
import { useContextMenu } from '../../../common/hooks/useContextMenu';
|
import { useContextMenu } from '../../../common/hooks/useContextMenu';
|
||||||
import { useEntryCopy } from '../../../common/stores/entryCopyStore';
|
import { useEntryCopy } from '../../../common/stores/entryCopyStore';
|
||||||
import { deviceAlt, deviceMod } from '../../../common/utils/deviceUtils';
|
import { deviceAlt, deviceMod } from '../../../common/utils/deviceUtils';
|
||||||
@@ -102,6 +103,8 @@ export default function RundownEvent({
|
|||||||
const clearSelectedEventId = useEventIdSwapping((state) => state.clearSelectedEventId);
|
const clearSelectedEventId = useEventIdSwapping((state) => state.clearSelectedEventId);
|
||||||
const openRenumberDialog = useRenumberCuesDialogStore((state) => state.onOpen);
|
const openRenumberDialog = useRenumberCuesDialogStore((state) => state.onOpen);
|
||||||
|
|
||||||
|
const parentGroup = useEntry(parent) as Maybe<OntimeGroup>;
|
||||||
|
|
||||||
const { updateEntry, batchUpdateEvents, clone, deleteEntry, groupEntries, swapEvents, matchGroupDuration } =
|
const { updateEntry, batchUpdateEvents, clone, deleteEntry, groupEntries, swapEvents, matchGroupDuration } =
|
||||||
useEntryActionsContext();
|
useEntryActionsContext();
|
||||||
|
|
||||||
@@ -176,12 +179,16 @@ export default function RundownEvent({
|
|||||||
{
|
{
|
||||||
type: 'item',
|
type: 'item',
|
||||||
label: 'Match Group Target Duration',
|
label: 'Match Group Target Duration',
|
||||||
|
description: 'Change event duration to fill the group target',
|
||||||
icon: TbClockPin,
|
icon: TbClockPin,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
if (!parent) return;
|
if (!parent) return;
|
||||||
matchGroupDuration(eventId, parent);
|
matchGroupDuration(eventId, parent);
|
||||||
},
|
},
|
||||||
disabled: !parent,
|
disabled:
|
||||||
|
!parentGroup ||
|
||||||
|
parentGroup.targetDuration === null ||
|
||||||
|
parentGroup.duration === parentGroup.targetDuration,
|
||||||
},
|
},
|
||||||
{ type: 'divider' },
|
{ type: 'divider' },
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -90,7 +90,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.lockIcon {
|
.lockIcon {
|
||||||
opacity: 0.6;
|
&.inactive {
|
||||||
|
color: $muted-gray;
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
color: $active-indicator;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.over {
|
.over {
|
||||||
|
|||||||
@@ -8,11 +8,10 @@ import {
|
|||||||
IoChevronUp,
|
IoChevronUp,
|
||||||
IoDuplicateOutline,
|
IoDuplicateOutline,
|
||||||
IoFolderOpenOutline,
|
IoFolderOpenOutline,
|
||||||
IoLockClosed,
|
|
||||||
IoReorderTwo,
|
IoReorderTwo,
|
||||||
IoTrash,
|
IoTrash,
|
||||||
} from 'react-icons/io5';
|
} from 'react-icons/io5';
|
||||||
import { TbClockPin } from 'react-icons/tb';
|
import { TbTargetArrow, TbClockPin } from 'react-icons/tb';
|
||||||
|
|
||||||
import IconButton from '../../../common/components/buttons/IconButton';
|
import IconButton from '../../../common/components/buttons/IconButton';
|
||||||
import Tag from '../../../common/components/tag/Tag';
|
import Tag from '../../../common/components/tag/Tag';
|
||||||
@@ -47,6 +46,8 @@ export default function RundownGroup({ data, hasCursor, collapsed, onCollapse }:
|
|||||||
const selectedEvents = useEventSelection((state) => state.selectedEvents);
|
const selectedEvents = useEventSelection((state) => state.selectedEvents);
|
||||||
const entryCopyId = useEntryCopy((state) => state.entryCopyId);
|
const entryCopyId = useEntryCopy((state) => state.entryCopyId);
|
||||||
|
|
||||||
|
const isDurationMatching = data.targetDuration !== null && data.targetDuration === data.duration;
|
||||||
|
|
||||||
const matchDuration = useCallback(() => {
|
const matchDuration = useCallback(() => {
|
||||||
updateEntry({ id: data.id, targetDuration: data.duration });
|
updateEntry({ id: data.id, targetDuration: data.duration });
|
||||||
}, [data.duration, data.id, updateEntry]);
|
}, [data.duration, data.id, updateEntry]);
|
||||||
@@ -72,6 +73,8 @@ export default function RundownGroup({ data, hasCursor, collapsed, onCollapse }:
|
|||||||
label: 'Match Content Duration',
|
label: 'Match Content Duration',
|
||||||
icon: TbClockPin,
|
icon: TbClockPin,
|
||||||
onClick: matchDuration,
|
onClick: matchDuration,
|
||||||
|
disabled: isDurationMatching,
|
||||||
|
description: "Change group target duration to match it's contents",
|
||||||
},
|
},
|
||||||
{ type: 'divider' },
|
{ type: 'divider' },
|
||||||
{
|
{
|
||||||
@@ -198,7 +201,9 @@ export default function RundownGroup({ data, hasCursor, collapsed, onCollapse }:
|
|||||||
<Tag className={style.offsetLabel}>{planOffset}</Tag>
|
<Tag className={style.offsetLabel}>{planOffset}</Tag>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{data.targetDuration !== null && <IoLockClosed className={style.lockIcon} />}
|
{data.targetDuration !== null && (
|
||||||
|
<TbTargetArrow className={cx([style.lockIcon, isDurationMatching ? style.active : style.inactive])} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user