Link start times from excel import (#903)

* add test for linking start time in excel import

* link ids

* add link to UI

* ensure times with cachedRundown

---------

Co-authored-by: Carlos Valente <carlosvalente@pm.me>
This commit is contained in:
Alex Christoffer Rasmussen
2024-04-26 17:09:59 +01:00
committed by GitHub
parent d8a8f0ad92
commit 74418ce17e
9 changed files with 157 additions and 22 deletions
@@ -1,12 +1,13 @@
import { ImportCustom } from 'ontime-utils';
import { convertToImportMap } from '../importMapUtils';
import { convertToImportMap, NamedImportMap } from '../importMapUtils';
describe('convertToImportMap', () => {
it('converts a namedImportMap to a importMap', () => {
const defaultNamedImporMap = {
Worksheet: 'event schedule',
Start: 'time start',
'Link start': 'link start',
End: 'time end',
Duration: 'duration',
Cue: 'cue',
@@ -26,7 +27,7 @@ describe('convertToImportMap', () => {
{ ontimeName: 'EmptyImportName', importName: '' },
{ ontimeName: '', importName: 'EmptyOntimeName' },
] as ImportCustom[],
};
} as NamedImportMap;
const importMap = convertToImportMap(defaultNamedImporMap);
expect(importMap.custom).toStrictEqual({
@@ -6,6 +6,7 @@ export type NamedImportMap = typeof namedImportMap;
export const namedImportMap = {
Worksheet: 'event schedule',
Start: 'time start',
'Link start': 'link start',
End: 'time end',
Duration: 'duration',
Cue: 'cue',
@@ -21,6 +22,15 @@ export const namedImportMap = {
custom: [] as ImportCustom[],
};
function isNamedImportMap(obj: unknown): obj is NamedImportMap {
if (typeof obj !== 'object' || obj === null) {
return false;
}
const keys = Object.keys(namedImportMap);
return keys.every((key) => Object.hasOwn(obj, key));
}
export function convertToImportMap(namedImportMap: NamedImportMap): ImportMap {
const custom = namedImportMap.custom.reduce((accumulator, { ontimeName, importName }) => {
if (ontimeName && importName) {
@@ -32,6 +42,7 @@ export function convertToImportMap(namedImportMap: NamedImportMap): ImportMap {
return {
worksheet: namedImportMap.Worksheet,
timeStart: namedImportMap.Start,
linkStart: namedImportMap['Link start'],
timeEnd: namedImportMap.End,
duration: namedImportMap.Duration,
cue: namedImportMap.Cue,
@@ -52,10 +63,22 @@ export function persistImportMap(options: NamedImportMap) {
localStorage.setItem('ontime-import-options', JSON.stringify(options));
}
export function getPersistedOptions(): NamedImportMap {
function getPersistImportMap(): unknown {
const options = localStorage.getItem('ontime-import-options');
if (!options) {
return namedImportMap;
throw new Error('no import options found');
}
return JSON.parse(options);
}
export function getPersistedOptions(): NamedImportMap {
try {
const options = getPersistImportMap();
if (!isNamedImportMap(options)) {
return namedImportMap;
}
return options;
} catch {
return namedImportMap;
}
}
@@ -1,12 +1,27 @@
.center {
text-align: center;
}
.center {
text-align: center;
}
.nowrap {
white-space: nowrap;
}
.nowrap {
white-space: nowrap;
}
tr .secondaryRow {
background-color: $white-7;
padding-left: 2em;
}
tr .secondaryRow {
background-color: $white-7;
padding-left: 2em;
}
.linkStartActive {
color: $active-indicator;
transform: rotate(-45deg);
}
.flex {
display: flex;
align-items: center;
gap: 0.5rem;
}
.subdued {
opacity: $opacity-disabled;
}
@@ -1,4 +1,5 @@
import { Fragment } from 'react';
import { IoLink } from '@react-icons/all-files/io5/IoLink';
import { CustomFields, isOntimeBlock, isOntimeEvent, OntimeRundown } from 'ontime-types';
import { millisToString } from 'ontime-utils';
@@ -83,7 +84,10 @@ export default function PreviewRundown(props: PreviewRundownProps) {
</td>
<td className={style.nowrap}>{event.cue}</td>
<td>{event.title}</td>
<td>{millisToString(event.timeStart)}</td>
<td className={style.flex}>
<span className={event.linkStart ? style.subdued : undefined}>{millisToString(event.timeStart)}</span>
{event.linkStart && <IoLink className={style.linkStartActive} />}
</td>
<td>{millisToString(event.timeEnd)}</td>
<td>{millisToString(event.duration)}</td>
<td>{millisToString(event.timeWarning)}</td>