mirror of
https://github.com/cpvalente/ontime.git
synced 2026-07-26 10:38:55 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 03c9f51b47 | |||
| 8d00fd3966 | |||
| 80fd21354e | |||
| a87b15825a | |||
| 6a8f98c469 | |||
| 8685298430 | |||
| d43af2db57 | |||
| ef718c48e4 | |||
| 45e7373279 | |||
| 6af2d6e021 | |||
| 9b36f36f73 | |||
| 3a0dbf057e | |||
| dae84ab48a |
Binary file not shown.
|
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 259 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 336 KiB After Width: | Height: | Size: 149 KiB |
@@ -45,10 +45,9 @@ jobs:
|
||||
- name: Copy external
|
||||
run: cp -R apps/server/src/external apps/cli/external
|
||||
|
||||
- name: Setup pnpm auth config
|
||||
run: pnpm config set '//registry.npmjs.org/:_authToken' "${NODE_AUTH_TOKEN}"
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||
# This will be included in v24 of NodeJS so when the project upgrades to that this can be removed
|
||||
- name: Install newer version of npm
|
||||
run: npm install -g npm@11
|
||||
|
||||
- name: Publish to NPM
|
||||
run: pnpm publish --access public --no-git-checks
|
||||
|
||||
@@ -34,10 +34,9 @@ jobs:
|
||||
- name: Build project packages
|
||||
run: pnpm build:resolver
|
||||
|
||||
- name: Setup pnpm auth config
|
||||
run: pnpm config set '//registry.npmjs.org/:_authToken' "${NODE_AUTH_TOKEN}"
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||
# This will be included in v24 of NodeJS so when the project upgrades to that this can be removed
|
||||
- name: Install newer version of npm
|
||||
run: npm install -g npm@11
|
||||
|
||||
- name: Publish to NPM
|
||||
run: pnpm publish --access public --no-git-checks
|
||||
|
||||
@@ -26,8 +26,6 @@ We do our best to have most topics covered by the documentation. However, if you
|
||||
Let us know!
|
||||
Ontime improves from the collaboration with its users. We would like to understand how you use Ontime and appreciate your feedback.
|
||||
|
||||
We would also like to include a testimonials section in our ✨new website✨. It would be great to showcase the diversity of users running Ontime.
|
||||
|
||||
# Ontime
|
||||
|
||||
Ontime is a browser-based application that manages event rundowns, scheduling, and cueing.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@getontime/cli",
|
||||
"version": "4.0.0",
|
||||
"version": "4.0.1",
|
||||
"author": "Carlos Valente",
|
||||
"description": "Time keeping for live events",
|
||||
"repository": "https://github.com/cpvalente/ontime",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ontime-ui",
|
||||
"version": "4.0.0",
|
||||
"version": "4.0.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
||||
@@ -92,10 +92,10 @@
|
||||
.end-message {
|
||||
text-align: center;
|
||||
font-size: 11.5vw;
|
||||
line-height: 0.9em;
|
||||
font-weight: 600;
|
||||
color: var(--timer-overtime-color-override, $timer-finished-color);
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.timer {
|
||||
@@ -117,7 +117,7 @@
|
||||
|
||||
// use a class instead of a phase, to allow suppressing overtime style
|
||||
&--finished {
|
||||
color: var(--timer-colour, var(--timer-overtime-color-override, $timer-finished-color));
|
||||
color: var(--timer-overtime-color-override, $timer-finished-color);
|
||||
}
|
||||
|
||||
&[data-phase="warning"] {
|
||||
|
||||
@@ -105,7 +105,7 @@ export function getShowModifiers(
|
||||
}
|
||||
|
||||
return {
|
||||
showEndMessage: freezeOvertime && freezeMessage !== '',
|
||||
showEndMessage: phase === TimerPhase.Overtime && freezeOvertime && freezeMessage !== '',
|
||||
showFinished: phase === TimerPhase.Overtime,
|
||||
showWarning: phase === TimerPhase.Warning,
|
||||
showDanger: phase === TimerPhase.Danger,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ontime-electron",
|
||||
"version": "4.0.0",
|
||||
"version": "4.0.1",
|
||||
"author": "Carlos Valente",
|
||||
"description": "Time keeping for live events",
|
||||
"repository": "https://github.com/cpvalente/ontime",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "ontime-server",
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
"version": "4.0.0",
|
||||
"version": "4.0.1",
|
||||
"exports": "./src/index.js",
|
||||
"dependencies": {
|
||||
"@googleapis/sheets": "^5.0.5",
|
||||
|
||||
@@ -109,7 +109,7 @@ export async function projectDownload(req: Request, res: Response) {
|
||||
return;
|
||||
}
|
||||
|
||||
res.download(pathToFile, filename, (error) => {
|
||||
res.download(pathToFile, filename, { dotfiles: 'allow' }, (error) => {
|
||||
if (error) {
|
||||
const message = getErrorMessage(error);
|
||||
res.status(500).send({ message });
|
||||
|
||||
@@ -355,7 +355,7 @@ export function migrateRundown(
|
||||
const newCustom: EntryCustomFields = {};
|
||||
|
||||
if (translationTable) {
|
||||
Object.entries(custom).map(([key, value]) => {
|
||||
Object.entries(custom).forEach(([key, value]) => {
|
||||
const newKey = translationTable.get(key);
|
||||
if (newKey) {
|
||||
newCustom[newKey] = value;
|
||||
|
||||
@@ -19,8 +19,10 @@ exports[`rundownToTabular() > returns an array of arrays describing a rundown 1`
|
||||
"Warning Time",
|
||||
"Danger Time",
|
||||
"Skip",
|
||||
"Custom Field",
|
||||
"Images",
|
||||
"Video Notes",
|
||||
"Audio Notes",
|
||||
"PowerPoint Name",
|
||||
"PowerPoint Slide",
|
||||
],
|
||||
[
|
||||
"e2163f",
|
||||
@@ -33,16 +35,21 @@ exports[`rundownToTabular() > returns an array of arrays describing a rundown 1`
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Go to Settings cog wheel top left of Editor, Project > Create",
|
||||
"Moderator - Emma Thompson
|
||||
|
||||
Speakers
|
||||
- Liam Carter + Sophia Patel
|
||||
- Ethan Brooks
|
||||
- Lucas Bennett",
|
||||
"milestone",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Create Custom Fields to store specific text information or images.
|
||||
|
||||
Go to Settings > Project data > Custom fields",
|
||||
"https://www.getontime.no/images/icons/ontime-logo.png",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
],
|
||||
[
|
||||
"7eaf99",
|
||||
@@ -63,6 +70,8 @@ Go to Settings > Project data > Custom fields",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
],
|
||||
[
|
||||
"9bf60f",
|
||||
@@ -81,8 +90,11 @@ Go to Settings > Project data > Custom fields",
|
||||
"00:10:00",
|
||||
"00:05:00",
|
||||
"",
|
||||
"Put additional info here",
|
||||
"",
|
||||
"Camera + PowerPoint on stream
|
||||
PowerPoint on screens",
|
||||
"2x Wireless Hand Helds",
|
||||
"HoldingSlide.pptx",
|
||||
"https://www.getontime.no/images/aux/demo-slide1.webp",
|
||||
],
|
||||
[
|
||||
"bf71a2",
|
||||
@@ -103,6 +115,8 @@ Go to Settings > Project data > Custom fields",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
],
|
||||
[
|
||||
"c2697f",
|
||||
@@ -121,8 +135,11 @@ Go to Settings > Project data > Custom fields",
|
||||
"00:02:00",
|
||||
"00:01:00",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Cameras on stream
|
||||
PowerPoint on screens",
|
||||
"1x Wireless Hand Held",
|
||||
"HoldingSlide.pptx",
|
||||
"https://www.getontime.no/images/aux/demo-slide1.webp",
|
||||
],
|
||||
[
|
||||
"fa593e",
|
||||
@@ -141,8 +158,11 @@ Go to Settings > Project data > Custom fields",
|
||||
"00:02:00",
|
||||
"00:01:00",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Camera + PowerPoint on stream
|
||||
PowerPoint on screens",
|
||||
"2x Wireless Hand Helds",
|
||||
"Session1.pptx",
|
||||
"https://www.getontime.no/images/aux/demo-slide2.webp",
|
||||
],
|
||||
[
|
||||
"a8b0b3",
|
||||
@@ -163,6 +183,8 @@ Go to Settings > Project data > Custom fields",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
],
|
||||
[
|
||||
"",
|
||||
@@ -201,6 +223,8 @@ Go to Settings > Project data > Custom fields",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
],
|
||||
[
|
||||
"0aaa7d",
|
||||
@@ -213,15 +237,16 @@ Go to Settings > Project data > Custom fields",
|
||||
"01:00:00",
|
||||
"TRUE",
|
||||
"",
|
||||
"Buffet in lobby
|
||||
Music plays, holding slide on screens",
|
||||
"Buffet in lobby",
|
||||
"count-down",
|
||||
"",
|
||||
"00:02:00",
|
||||
"00:01:00",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Holding slide on screens",
|
||||
"House music",
|
||||
"HoldingSlide.pptx",
|
||||
"https://www.getontime.no/images/aux/demo-slide1.webp",
|
||||
],
|
||||
[
|
||||
"",
|
||||
@@ -260,6 +285,8 @@ Music plays, holding slide on screens",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
],
|
||||
[
|
||||
"02afca",
|
||||
@@ -280,6 +307,8 @@ Music plays, holding slide on screens",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
],
|
||||
[
|
||||
"75ce86",
|
||||
@@ -298,8 +327,14 @@ Music plays, holding slide on screens",
|
||||
"00:02:00",
|
||||
"00:01:00",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Camera + PPT + Video on stream
|
||||
PowerPoint + Video on screens
|
||||
|
||||
Video file: Session2.mp4",
|
||||
"1x Wireless Hand Held
|
||||
1x Video with audio",
|
||||
"Session2.pptx",
|
||||
"https://www.getontime.no/images/aux/demo-slide3.webp",
|
||||
],
|
||||
[
|
||||
"e10ed9",
|
||||
@@ -318,8 +353,10 @@ Music plays, holding slide on screens",
|
||||
"00:02:00",
|
||||
"00:01:00",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Holding slide on screens",
|
||||
"1x Wireless Hand Held",
|
||||
"HoldingSlide.pptx",
|
||||
"https://www.getontime.no/images/aux/demo-slide1.webp",
|
||||
],
|
||||
[
|
||||
"07df89",
|
||||
@@ -340,6 +377,8 @@ Music plays, holding slide on screens",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
],
|
||||
[
|
||||
"",
|
||||
|
||||
@@ -52,7 +52,7 @@ router.get('/:rundownId/export', validateRundownExport, (req: Request, res: Resp
|
||||
const customFields = getProjectCustomFields();
|
||||
const buffer = generateExcelFile(rundown, customFields);
|
||||
|
||||
res.setHeader('Content-Disposition', `attachment;`);
|
||||
res.setHeader('Content-Disposition', 'attachment;');
|
||||
res.setHeader('Content-Type', EXCEL_MIME);
|
||||
res.setHeader('Content-Length', buffer.length.toString());
|
||||
res.status(200).send(buffer);
|
||||
|
||||
Vendored
+2
-2
@@ -123,8 +123,8 @@ function formatTimer(number) {
|
||||
* @param {number} number - The number to pad
|
||||
* @returns {string} The padded number string
|
||||
*/
|
||||
function leftPad(number) {
|
||||
return Math.floor(number).toString().padStart(2, '0');
|
||||
function leftPad(val) {
|
||||
return Math.floor(val).toString().padStart(2, '0');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,13 +28,9 @@ export const demoDb: DatabaseModel = {
|
||||
type: SupportedEntry.Milestone,
|
||||
cue: 'Demo',
|
||||
title: 'Clear all, or Create New Project to start fresh',
|
||||
note: 'Go to Settings cog wheel top left of Editor, Project > Create',
|
||||
note: 'Moderator - Emma Thompson\n\nSpeakers\n- Liam Carter + Sophia Patel\n- Ethan Brooks\n- Lucas Bennett',
|
||||
colour: '#9d9d9d',
|
||||
custom: {
|
||||
Custom_Field:
|
||||
'Create Custom Fields to store specific text information or images.\n\nGo to Settings > Project data > Custom fields',
|
||||
Images: 'https://www.getontime.no/images/icons/ontime-logo.png',
|
||||
},
|
||||
custom: {},
|
||||
parent: null,
|
||||
revision: 0,
|
||||
},
|
||||
@@ -78,7 +74,10 @@ export const demoDb: DatabaseModel = {
|
||||
timeWarning: 600000,
|
||||
timeDanger: 300000,
|
||||
custom: {
|
||||
Custom_Field: 'Put additional info here',
|
||||
PowerPoint_Slide: 'https://www.getontime.no/images/aux/demo-slide1.webp',
|
||||
Video_Notes: 'Camera + PowerPoint on stream\nPowerPoint on screens',
|
||||
Audio_Notes: '2x Wireless Hand Helds',
|
||||
PowerPoint_Name: 'HoldingSlide.pptx',
|
||||
},
|
||||
triggers: [],
|
||||
},
|
||||
@@ -117,7 +116,12 @@ export const demoDb: DatabaseModel = {
|
||||
revision: 0,
|
||||
timeWarning: 120000,
|
||||
timeDanger: 60000,
|
||||
custom: {},
|
||||
custom: {
|
||||
PowerPoint_Slide: 'https://www.getontime.no/images/aux/demo-slide1.webp',
|
||||
Video_Notes: 'Cameras on stream\nPowerPoint on screens',
|
||||
Audio_Notes: '1x Wireless Hand Held',
|
||||
PowerPoint_Name: 'HoldingSlide.pptx',
|
||||
},
|
||||
triggers: [],
|
||||
},
|
||||
fa593e: {
|
||||
@@ -144,7 +148,12 @@ export const demoDb: DatabaseModel = {
|
||||
revision: 0,
|
||||
timeWarning: 120000,
|
||||
timeDanger: 60000,
|
||||
custom: {},
|
||||
custom: {
|
||||
PowerPoint_Slide: 'https://www.getontime.no/images/aux/demo-slide2.webp',
|
||||
Video_Notes: 'Camera + PowerPoint on stream\nPowerPoint on screens',
|
||||
Audio_Notes: '2x Wireless Hand Helds',
|
||||
PowerPoint_Name: 'Session1.pptx',
|
||||
},
|
||||
triggers: [],
|
||||
},
|
||||
a8b0b3: {
|
||||
@@ -187,7 +196,7 @@ export const demoDb: DatabaseModel = {
|
||||
timerType: TimerType.CountDown,
|
||||
countToEnd: false,
|
||||
skip: false,
|
||||
note: 'Buffet in lobby\nMusic plays, holding slide on screens',
|
||||
note: 'Buffet in lobby',
|
||||
colour: '#779BE7',
|
||||
delay: 0,
|
||||
dayOffset: 0,
|
||||
@@ -197,7 +206,12 @@ export const demoDb: DatabaseModel = {
|
||||
revision: 0,
|
||||
timeWarning: 120000,
|
||||
timeDanger: 60000,
|
||||
custom: {},
|
||||
custom: {
|
||||
PowerPoint_Slide: 'https://www.getontime.no/images/aux/demo-slide1.webp',
|
||||
Video_Notes: 'Holding slide on screens',
|
||||
Audio_Notes: 'House music',
|
||||
PowerPoint_Name: 'HoldingSlide.pptx',
|
||||
},
|
||||
triggers: [],
|
||||
},
|
||||
'6b0edb': {
|
||||
@@ -250,7 +264,12 @@ export const demoDb: DatabaseModel = {
|
||||
revision: 0,
|
||||
timeWarning: 120000,
|
||||
timeDanger: 60000,
|
||||
custom: {},
|
||||
custom: {
|
||||
PowerPoint_Slide: 'https://www.getontime.no/images/aux/demo-slide3.webp',
|
||||
Video_Notes: 'Camera + PPT + Video on stream\nPowerPoint + Video on screens\n\nVideo file: Session2.mp4',
|
||||
Audio_Notes: '1x Wireless Hand Held\n1x Video with audio',
|
||||
PowerPoint_Name: 'Session2.pptx',
|
||||
},
|
||||
triggers: [],
|
||||
},
|
||||
e10ed9: {
|
||||
@@ -277,7 +296,12 @@ export const demoDb: DatabaseModel = {
|
||||
revision: 0,
|
||||
timeWarning: 120000,
|
||||
timeDanger: 60000,
|
||||
custom: {},
|
||||
custom: {
|
||||
PowerPoint_Slide: 'https://www.getontime.no/images/aux/demo-slide1.webp',
|
||||
Video_Notes: 'Holding slide on screens',
|
||||
Audio_Notes: '1x Wireless Hand Held',
|
||||
PowerPoint_Name: 'HoldingSlide.pptx',
|
||||
},
|
||||
triggers: [],
|
||||
},
|
||||
'07df89': {
|
||||
@@ -341,15 +365,25 @@ export const demoDb: DatabaseModel = {
|
||||
},
|
||||
],
|
||||
customFields: {
|
||||
Custom_Field: {
|
||||
Video_Notes: {
|
||||
type: 'text',
|
||||
colour: '#FFAB33',
|
||||
label: 'Video Notes',
|
||||
},
|
||||
Audio_Notes: {
|
||||
type: 'text',
|
||||
colour: '#339E4E',
|
||||
label: 'Audio Notes',
|
||||
},
|
||||
PowerPoint_Name: {
|
||||
type: 'text',
|
||||
colour: '#3E75E8',
|
||||
label: 'Custom Field',
|
||||
label: 'PowerPoint Name',
|
||||
},
|
||||
Images: {
|
||||
PowerPoint_Slide: {
|
||||
type: 'image',
|
||||
colour: '#ED3333',
|
||||
label: 'Images',
|
||||
label: 'PowerPoint Slide',
|
||||
},
|
||||
},
|
||||
automation: {
|
||||
|
||||
@@ -50,7 +50,7 @@ export function isRestorePoint(restorePoint: unknown): restorePoint is RestorePo
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is.number(restorePoint.startEpoch) && restorePoint.startEpoch !== null) {
|
||||
if (!is.number(restorePoint.startEpoch) && restorePoint.startEpoch !== null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -273,13 +273,14 @@ class RuntimeService {
|
||||
public startByCue(cue: string): boolean {
|
||||
const state = runtimeState.getState();
|
||||
const rundown = getCurrentRundown();
|
||||
const { playableEventOrder } = getRundownMetadata();
|
||||
const { timedEventOrder } = getRundownMetadata();
|
||||
|
||||
const event = findNextPlayableWithCue(
|
||||
rundown,
|
||||
playableEventOrder,
|
||||
timedEventOrder,
|
||||
cue,
|
||||
state.rundown.selectedEventIndex ?? undefined,
|
||||
state.timer.playback === Playback.Armed, // If we are armed allow the armed event to be considered for playback
|
||||
);
|
||||
|
||||
if (!event) {
|
||||
@@ -341,6 +342,7 @@ class RuntimeService {
|
||||
playableEventOrder,
|
||||
cue,
|
||||
state.rundown.selectedEventIndex ?? undefined,
|
||||
false,
|
||||
);
|
||||
|
||||
if (!event) {
|
||||
|
||||
@@ -118,24 +118,25 @@ export function findNextPlayableId(playableEventsOrder: EntryId[], currentEventI
|
||||
*/
|
||||
export function findNextPlayableWithCue(
|
||||
rundown: Rundown,
|
||||
playableEventsOrder: EntryId[],
|
||||
timedEventsOrder: EntryId[],
|
||||
targetCue: string,
|
||||
currentEventIndex = 0,
|
||||
allowCurrent = false,
|
||||
): OntimeEvent | undefined {
|
||||
const lowerCaseCue = targetCue.toLowerCase();
|
||||
const startFromIndex = allowCurrent ? currentEventIndex : currentEventIndex + 1;
|
||||
|
||||
for (let i = currentEventIndex; i < playableEventsOrder.length; i++) {
|
||||
const eventId = playableEventsOrder[i];
|
||||
for (let i = startFromIndex; i < timedEventsOrder.length; i++) {
|
||||
const eventId = timedEventsOrder[i];
|
||||
const event = rundown.entries[eventId];
|
||||
if (isOntimeEvent(event) && isPlayableEvent(event) && event.cue.toLowerCase() === lowerCaseCue) {
|
||||
if (isOntimeEvent(event) && isPlayableEvent(event) && event.cue === targetCue) {
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < currentEventIndex; i++) {
|
||||
const eventId = playableEventsOrder[i];
|
||||
for (let i = 0; i < startFromIndex; i++) {
|
||||
const eventId = timedEventsOrder[i];
|
||||
const event = rundown.entries[eventId];
|
||||
if (isOntimeEvent(event) && isPlayableEvent(event) && event.cue.toLowerCase() === lowerCaseCue) {
|
||||
if (isOntimeEvent(event) && isPlayableEvent(event) && event.cue === targetCue) {
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,7 +377,7 @@ export async function upload(sheetId: string, options: ImportMap) {
|
||||
|
||||
const titleMetadata = Object.values(sheetMetadata)[0];
|
||||
if (titleMetadata === undefined) {
|
||||
throw new Error(`Sheet read failed: failed to find title row`);
|
||||
throw new Error('Sheet read failed: failed to find title row');
|
||||
}
|
||||
const titleRow = titleMetadata['row'];
|
||||
const updateRundown = Array<sheets_v4.Schema$Request>();
|
||||
|
||||
@@ -11,14 +11,14 @@ describe('parseExcelDate', () => {
|
||||
['1899-12-30T07:00:00.000Z', 28800000],
|
||||
['1899-12-30T08:00:10.000Z', 32410000],
|
||||
['1899-12-30T08:30:00.000Z', 34200000],
|
||||
])(`handles %s`, (fromExcel, expected) => {
|
||||
])('handles %s', (fromExcel, expected) => {
|
||||
expect(parseExcelDate(fromExcel)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parses a time string that passes validation', () => {
|
||||
test.each([['10:00:00'], ['10:00'], ['10:00AM'], ['10:00am'], ['10:00PM'], ['10:00pm']])(
|
||||
`handles %s`,
|
||||
'handles %s',
|
||||
(fromExcel) => {
|
||||
expect(parseExcelDate(fromExcel)).not.toBe(0);
|
||||
},
|
||||
@@ -26,13 +26,13 @@ describe('parseExcelDate', () => {
|
||||
});
|
||||
|
||||
describe('uses numeric fields as minutes', () => {
|
||||
test.each([[1], [10], [100]])(`handles numeric fields %s`, (fromExcel) => {
|
||||
test.each([[1], [10], [100]])('handles numeric fields %s', (fromExcel) => {
|
||||
expect(parseExcelDate(fromExcel)).toBe(fromExcel * MILLIS_PER_MINUTE);
|
||||
});
|
||||
});
|
||||
|
||||
describe('returns 0 on other strings', () => {
|
||||
test.each([['test'], [''], ['x']])(`handles invalid fields %s`, (fromExcel) => {
|
||||
test.each([['test'], [''], ['x']])('handles invalid fields %s', (fromExcel) => {
|
||||
expect(parseExcelDate(fromExcel)).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ontime",
|
||||
"version": "4.0.0",
|
||||
"version": "4.0.1",
|
||||
"description": "Time keeping for live events",
|
||||
"keywords": [
|
||||
"ontime",
|
||||
|
||||
Reference in New Issue
Block a user