Fix: sheet export (#1606)

* add util to get keys from labels

* look for existing keys first then create new

* save ontime key to rundown metadata

* update test
This commit is contained in:
Alex Christoffer Rasmussen
2025-05-12 13:56:25 +02:00
committed by GitHub
parent 1f0cde6d0d
commit 1e1aa4bca5
4 changed files with 31 additions and 11 deletions
+13 -5
View File
@@ -838,6 +838,7 @@ describe('getCustomFieldData()', () => {
lighting: 'lx', lighting: 'lx',
sound: 'sound', sound: 'sound',
video: 'av', video: 'av',
ontime_label: 'excel label',
}, },
entryId: 'id', entryId: 'id',
} as ImportMap; } as ImportMap;
@@ -845,6 +846,7 @@ describe('getCustomFieldData()', () => {
const customFields: CustomFields = { const customFields: CustomFields = {
lighting: { label: 'lx', type: 'string', colour: 'red' }, lighting: { label: 'lx', type: 'string', colour: 'red' },
sound: { label: 'sound', type: 'string', colour: 'green' }, sound: { label: 'sound', type: 'string', colour: 'green' },
ontime_key: { label: 'ontime_label', type: 'string', colour: 'blue' },
}; };
const result = getCustomFieldData(importMap, customFields); const result = getCustomFieldData(importMap, customFields);
@@ -864,6 +866,11 @@ describe('getCustomFieldData()', () => {
colour: '', colour: '',
label: 'video', label: 'video',
}, },
ontime_key: {
type: 'string',
colour: 'blue',
label: 'ontime_label',
},
}); });
// it is an inverted record of <importKey, ontimeKey> // it is an inverted record of <importKey, ontimeKey>
@@ -871,6 +878,7 @@ describe('getCustomFieldData()', () => {
lx: 'lighting', lx: 'lighting',
sound: 'sound', sound: 'sound',
av: 'video', av: 'video',
'excel label': 'ontime_key',
}); });
}); });
}); });
@@ -1022,8 +1030,8 @@ describe('parseExcel()', () => {
user2: { type: 'string', colour: 'blue', label: 'user2' }, user2: { type: 'string', colour: 'blue', label: 'user2' },
}; };
const parsedData = parseExcel(testdata, existingCustomFields, importMap); const { customFields, rundown } = parseExcel(testdata, existingCustomFields, importMap);
expect(parsedData.customFields).toStrictEqual({ expect(customFields).toStrictEqual({
user0: { user0: {
type: 'string', type: 'string',
colour: 'red', colour: 'red',
@@ -1075,9 +1083,9 @@ describe('parseExcel()', () => {
label: 'user9', label: 'user9',
}, },
}); });
expect(parsedData.rundown.length).toBe(2); expect(rundown.length).toBe(2);
expect(parsedData.rundown[0]).toMatchObject(expectedParsedRundown[0]); expect(rundown[0]).toMatchObject(expectedParsedRundown[0]);
expect(parsedData.rundown[1]).toMatchObject(expectedParsedRundown[1]); expect(rundown[1]).toMatchObject(expectedParsedRundown[1]);
}); });
it('parses a file without custom fields', () => { it('parses a file without custom fields', () => {
+7 -5
View File
@@ -1,5 +1,6 @@
import { import {
customFieldLabelToKey, customFieldLabelToKey,
customKeyFromLabel,
defaultImportMap, defaultImportMap,
generateId, generateId,
type ImportMap, type ImportMap,
@@ -60,7 +61,7 @@ export function getCustomFieldData(
const customFields = {}; const customFields = {};
const customFieldImportKeys = {}; const customFieldImportKeys = {};
for (const ontimeLabel in importMap.custom) { for (const ontimeLabel in importMap.custom) {
const ontimeKey = customFieldLabelToKey(ontimeLabel); const ontimeKey = customKeyFromLabel(ontimeLabel, existingCustomFields) ?? customFieldLabelToKey(ontimeLabel);
const importLabel = importMap.custom[ontimeLabel].toLowerCase(); const importLabel = importMap.custom[ontimeLabel].toLowerCase();
const colour = ontimeKey in existingCustomFields ? existingCustomFields[ontimeKey].colour : ''; const colour = ontimeKey in existingCustomFields ? existingCustomFields[ontimeKey].colour : '';
customFields[ontimeKey] = { customFields[ontimeKey] = {
@@ -198,9 +199,9 @@ export const parseExcel = (
entryIdIndex = col; entryIdIndex = col;
rundownMetadata['id'] = { row, col }; rundownMetadata['id'] = { row, col };
}, },
custom: (row: number, col: number, columnText: string) => { custom: (row: number, col: number, columnText: string, ontimeKey: string) => {
customFieldIndexes[col] = columnText; customFieldIndexes[col] = columnText;
rundownMetadata[`custom:${columnText}`] = { row, col }; rundownMetadata[`custom:${ontimeKey}`] = { row, col };
}, },
} as const; } as const;
@@ -266,12 +267,13 @@ export const parseExcel = (
// check if it is an ontime column // check if it is an ontime column
if (handlers[columnText]) { if (handlers[columnText]) {
handlers[columnText](rowIndex, j, undefined); handlers[columnText](rowIndex, j, undefined, undefined);
} }
// check if it is a custom field // check if it is a custom field
if (columnText in customFieldImportKeys) { if (columnText in customFieldImportKeys) {
handlers.custom(rowIndex, j, columnText); const ontimeKey = customFieldImportKeys[columnText];
handlers.custom(rowIndex, j, columnText, ontimeKey);
} }
// else. we don't know how to handle this column // else. we don't know how to handle this column
+1 -1
View File
@@ -58,7 +58,7 @@ export { isAlphanumeric, isAlphanumericWithSpace } from './src/regex-utils/isAlp
export { isColourHex } from './src/regex-utils/isColourHex.js'; export { isColourHex } from './src/regex-utils/isColourHex.js';
export { splitWhitespace } from './src/regex-utils/splitWhitespace.js'; export { splitWhitespace } from './src/regex-utils/splitWhitespace.js';
export { customFieldLabelToKey } from './src/customField-utils/customFieldLabelToKey.js'; export { customFieldLabelToKey, customKeyFromLabel } from './src/customField-utils/customFieldLabelToKey.js';
// helpers from externals // helpers from externals
export { deepmerge } from './src/externals/deepmerge.js'; export { deepmerge } from './src/externals/deepmerge.js';
@@ -1,3 +1,5 @@
import type { CustomFields } from 'ontime-types';
import { isAlphanumericWithSpace } from '../regex-utils/isAlphanumeric.js'; import { isAlphanumericWithSpace } from '../regex-utils/isAlphanumeric.js';
/** /**
@@ -9,3 +11,11 @@ export const customFieldLabelToKey = (label: string): string | null => {
} }
return null; return null;
}; };
export const customKeyFromLabel = (label: string, fields: CustomFields): string | null => {
const maybeMatchingKey = Object.keys(fields).find((key) => fields[key].label === label);
if (maybeMatchingKey) {
return maybeMatchingKey;
}
return null;
};