mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-21 15:09:10 +00:00
feat: allow finding milestones
This commit is contained in:
committed by
Carlos Valente
parent
ded8bddb2d
commit
e4b0df42cf
@@ -66,4 +66,5 @@
|
|||||||
.scrollContainer {
|
.scrollContainer {
|
||||||
max-height: 70vh;
|
max-height: 70vh;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
padding-top: 1rem;
|
||||||
}
|
}
|
||||||
@@ -71,8 +71,7 @@ export default function Finder({ isOpen, onClose }: FinderProps) {
|
|||||||
results.map((entry, index) => {
|
results.map((entry, index) => {
|
||||||
const isSelected = selected === index;
|
const isSelected = selected === index;
|
||||||
const displayIndex = entry.type === SupportedEntry.Event ? entry.eventIndex : '-';
|
const displayIndex = entry.type === SupportedEntry.Event ? entry.eventIndex : '-';
|
||||||
const displayCue = entry.type === SupportedEntry.Event ? entry.cue : '';
|
const displayCue = 'cue' in entry ? entry.cue : '';
|
||||||
const colour = entry.type === SupportedEntry.Event ? entry.colour : '';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
@@ -83,7 +82,7 @@ export default function Finder({ isOpen, onClose }: FinderProps) {
|
|||||||
onClick={submit}
|
onClick={submit}
|
||||||
>
|
>
|
||||||
<div className={style.data}>
|
<div className={style.data}>
|
||||||
<div className={style.index} style={{ '--color': colour }}>
|
<div className={style.index} style={{ '--color': entry.colour }}>
|
||||||
{displayIndex}
|
{displayIndex}
|
||||||
</div>
|
</div>
|
||||||
<div className={style.cue}>{displayCue}</div>
|
<div className={style.cue}>{displayCue}</div>
|
||||||
@@ -99,7 +98,7 @@ export default function Finder({ isOpen, onClose }: FinderProps) {
|
|||||||
footerElements={
|
footerElements={
|
||||||
<div className={style.footer}>
|
<div className={style.footer}>
|
||||||
Use the keywords <span className={style.em}>cue</span>, <span className={style.em}>index</span> or
|
Use the keywords <span className={style.em}>cue</span>, <span className={style.em}>index</span> or
|
||||||
<span className={style.em}>title</span> to filter search
|
<span className={style.em}>title</span> to filter search.
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ChangeEvent, useCallback, useEffect, useRef, useState } from 'react';
|
import { ChangeEvent, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { useSessionStorage } from '@mantine/hooks';
|
import { useSessionStorage } from '@mantine/hooks';
|
||||||
import { EntryId, isOntimeEvent, isOntimeGroup, MaybeString, SupportedEntry } from 'ontime-types';
|
import { EntryId, isOntimeEvent, isOntimeGroup, isOntimeMilestone, MaybeString, SupportedEntry } from 'ontime-types';
|
||||||
|
|
||||||
import { useFlatRundown } from '../../../common/hooks-query/useRundown';
|
import { useFlatRundown } from '../../../common/hooks-query/useRundown';
|
||||||
import { useEventSelection } from '../../../features/rundown/useEventSelection';
|
import { useEventSelection } from '../../../features/rundown/useEventSelection';
|
||||||
@@ -9,14 +9,15 @@ const maxResults = 12;
|
|||||||
|
|
||||||
type FilterableGroup = {
|
type FilterableGroup = {
|
||||||
type: SupportedEntry.Group;
|
type: SupportedEntry.Group;
|
||||||
id: string;
|
id: EntryId;
|
||||||
index: number;
|
index: number;
|
||||||
title: string;
|
title: string;
|
||||||
|
colour: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type FilterableEvent = {
|
type FilterableEvent = {
|
||||||
type: SupportedEntry.Event;
|
type: SupportedEntry.Event;
|
||||||
id: string;
|
id: EntryId;
|
||||||
index: number;
|
index: number;
|
||||||
eventIndex: number;
|
eventIndex: number;
|
||||||
title: string;
|
title: string;
|
||||||
@@ -25,7 +26,17 @@ type FilterableEvent = {
|
|||||||
parent: MaybeString;
|
parent: MaybeString;
|
||||||
};
|
};
|
||||||
|
|
||||||
type FilterableEntry = FilterableGroup | FilterableEvent;
|
type FilterableMilestone = {
|
||||||
|
type: SupportedEntry.Milestone;
|
||||||
|
id: EntryId;
|
||||||
|
index: number;
|
||||||
|
title: string;
|
||||||
|
cue: string;
|
||||||
|
colour: string;
|
||||||
|
parent: MaybeString;
|
||||||
|
};
|
||||||
|
|
||||||
|
type FilterableEntry = FilterableGroup | FilterableEvent | FilterableMilestone;
|
||||||
|
|
||||||
export default function useFinder() {
|
export default function useFinder() {
|
||||||
const { data, rundownId } = useFlatRundown();
|
const { data, rundownId } = useFlatRundown();
|
||||||
@@ -59,7 +70,7 @@ export default function useFinder() {
|
|||||||
lastSearchString.current = searchValue;
|
lastSearchString.current = searchValue;
|
||||||
|
|
||||||
if (searchValue.startsWith('index ')) {
|
if (searchValue.startsWith('index ')) {
|
||||||
const searchString = searchValue.replace('index ', '').trim();
|
const searchString = searchValue.slice('index '.length).trim();
|
||||||
const { results, error } = searchByIndex(searchString);
|
const { results, error } = searchByIndex(searchString);
|
||||||
setResults(results);
|
setResults(results);
|
||||||
setError(error);
|
setError(error);
|
||||||
@@ -67,14 +78,14 @@ export default function useFinder() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (searchValue.startsWith('cue ')) {
|
if (searchValue.startsWith('cue ')) {
|
||||||
const searchString = searchValue.replace('cue ', '').trim();
|
const searchString = searchValue.slice('cue '.length).trim();
|
||||||
const { results, error } = searchByCue(searchString);
|
const { results, error } = searchByCue(searchString);
|
||||||
setResults(results);
|
setResults(results);
|
||||||
setError(error);
|
setError(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchString = searchValue.replace('title ', '').trim();
|
const searchString = searchValue.startsWith('title ') ? searchValue.slice('title '.length).trim() : searchValue;
|
||||||
const { results, error } = searchByTitle(searchString);
|
const { results, error } = searchByTitle(searchString);
|
||||||
setResults(results);
|
setResults(results);
|
||||||
setError(error);
|
setError(error);
|
||||||
@@ -162,33 +173,46 @@ export default function useFinder() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const event = data[i];
|
const entry = data[i];
|
||||||
if (isOntimeEvent(event)) {
|
if (isOntimeEvent(entry)) {
|
||||||
if (event.title.toLowerCase().includes(searchString)) {
|
if (entry.title.toLowerCase().includes(searchString)) {
|
||||||
remaining--;
|
remaining--;
|
||||||
results.push({
|
results.push({
|
||||||
type: SupportedEntry.Event,
|
type: SupportedEntry.Event,
|
||||||
id: event.id,
|
id: entry.id,
|
||||||
index: i,
|
index: i,
|
||||||
eventIndex,
|
eventIndex,
|
||||||
title: event.title,
|
title: entry.title,
|
||||||
cue: event.cue,
|
cue: entry.cue,
|
||||||
colour: event.colour,
|
colour: entry.colour,
|
||||||
parent: event.parent,
|
parent: entry.parent,
|
||||||
} satisfies FilterableEvent);
|
} satisfies FilterableEvent);
|
||||||
}
|
}
|
||||||
eventIndex++;
|
eventIndex++;
|
||||||
}
|
} else if (isOntimeGroup(entry)) {
|
||||||
if (isOntimeGroup(event)) {
|
if (entry.title.toLowerCase().includes(searchString)) {
|
||||||
if (event.title.toLowerCase().includes(searchString)) {
|
|
||||||
remaining--;
|
remaining--;
|
||||||
results.push({
|
results.push({
|
||||||
type: SupportedEntry.Group,
|
type: SupportedEntry.Group,
|
||||||
id: event.id,
|
id: entry.id,
|
||||||
index: i,
|
index: i,
|
||||||
title: event.title,
|
title: entry.title,
|
||||||
|
colour: entry.colour,
|
||||||
} satisfies FilterableGroup);
|
} satisfies FilterableGroup);
|
||||||
}
|
}
|
||||||
|
} else if (isOntimeMilestone(entry)) {
|
||||||
|
if (entry.title.toLowerCase().includes(searchString)) {
|
||||||
|
remaining--;
|
||||||
|
results.push({
|
||||||
|
type: SupportedEntry.Milestone,
|
||||||
|
id: entry.id,
|
||||||
|
index: i,
|
||||||
|
title: entry.title,
|
||||||
|
cue: entry.cue,
|
||||||
|
colour: entry.colour,
|
||||||
|
parent: entry.parent,
|
||||||
|
} satisfies FilterableMilestone);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { results, error: null };
|
return { results, error: null };
|
||||||
@@ -200,7 +224,7 @@ export default function useFinder() {
|
|||||||
const select = useCallback(
|
const select = useCallback(
|
||||||
(selectedEvent: FilterableEntry) => {
|
(selectedEvent: FilterableEntry) => {
|
||||||
// First expand the parent group if this is an event inside a group
|
// First expand the parent group if this is an event inside a group
|
||||||
if (selectedEvent.type === SupportedEntry.Event && selectedEvent.parent !== null) {
|
if ('parent' in selectedEvent && selectedEvent.parent !== null) {
|
||||||
// Try direct state update instead of using callback
|
// Try direct state update instead of using callback
|
||||||
const currentGroups = [...new Set(collapsedGroups)];
|
const currentGroups = [...new Set(collapsedGroups)];
|
||||||
const newGroups = currentGroups.filter((id) => id !== selectedEvent.parent);
|
const newGroups = currentGroups.filter((id) => id !== selectedEvent.parent);
|
||||||
|
|||||||
Reference in New Issue
Block a user