Skip to content

Commit 8bba9ef

Browse files
committed
Merge branch 'feat/rundown-view-refactor' into release53
2 parents 5c20bea + 8955b3e commit 8bba9ef

25 files changed

+2766
-2416
lines changed

packages/corelib/src/playout/infinites.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export function getPlayheadTrackingInfinitesForPart(
9494
partsToReceiveOnSegmentEndFromSet: Set<PartId>,
9595
segmentsToReceiveOnRundownEndFromSet: Set<SegmentId>,
9696
rundownsToReceiveOnShowStyleEndFrom: RundownId[],
97-
rundownsToShowstyles: Map<RundownId, ShowStyleBaseId>,
97+
rundownsToShowstyles: ReadonlyMap<RundownId, ShowStyleBaseId>,
9898
currentPartInstance: ReadonlyDeep<DBPartInstance>,
9999
playingSegment: ReadonlyDeep<Pick<DBSegment, '_id' | 'orphaned'>>,
100100
currentPartPieceInstances: ReadonlyDeep<PieceInstance[]>,
@@ -278,7 +278,7 @@ export function isPiecePotentiallyActiveInPart(
278278
partsToReceiveOnSegmentEndFrom: Set<PartId>,
279279
segmentsToReceiveOnRundownEndFrom: Set<SegmentId>,
280280
rundownsToReceiveOnShowStyleEndFrom: RundownId[],
281-
rundownsToShowstyles: Map<RundownId, ShowStyleBaseId>,
281+
rundownsToShowstyles: ReadonlyMap<RundownId, ShowStyleBaseId>,
282282
rundown: ReadonlyDeep<Pick<DBRundown, '_id' | 'showStyleBaseId'>>,
283283
part: ReadonlyDeep<DBPart>,
284284
pieceToCheck: ReadonlyDeep<Piece>
@@ -375,7 +375,7 @@ export function getPieceInstancesForPart(
375375
partsToReceiveOnSegmentEndFromSet: Set<PartId>,
376376
segmentsToReceiveOnRundownEndFromSet: Set<SegmentId>,
377377
rundownsToReceiveOnShowStyleEndFrom: RundownId[],
378-
rundownsToShowstyles: Map<RundownId, ShowStyleBaseId>,
378+
rundownsToShowstyles: ReadonlyMap<RundownId, ShowStyleBaseId>,
379379
possiblePieces: ReadonlyDeep<Piece>[],
380380
orderedPartIds: PartId[],
381381
newInstanceId: PartInstanceId,
@@ -576,7 +576,7 @@ export function isCandidateBetterToBeContinued(
576576

577577
function continueShowStyleEndInfinites(
578578
rundownsToReceiveOnShowStyleEndFrom: RundownId[],
579-
rundownsToShowstyles: Map<RundownId, ShowStyleBaseId>,
579+
rundownsToShowstyles: ReadonlyMap<RundownId, ShowStyleBaseId>,
580580
previousRundownId: RundownId,
581581
targetRundown: ReadonlyDeep<Pick<DBRundown, '_id' | 'showStyleBaseId'>>
582582
): boolean {

packages/live-status-gateway-api/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Sofie: The Modern TV News Studio Automation System (Shared Lib)
1+
# Sofie: The Modern TV News Studio Automation System (Live Status Gateway API)
22

33
[![npm](https://img.shields.io/npm/v/@sofie-automation/live-status-gateway-api)](https://www.npmjs.com/package/@sofie-automation/live-status-gateway-api)
44

packages/webui/src/client/lib/RundownResolver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ export function getPieceInstancesForPartInstance(
122122
partsToReceiveOnSegmentEndFromSet: Set<PartId>,
123123
segmentsToReceiveOnRundownEndFromSet: Set<SegmentId>,
124124
rundownsToReceiveOnShowStyleEndFrom: RundownId[],
125-
rundownsToShowstyles: Map<RundownId, ShowStyleBaseId>,
125+
rundownsToShowstyles: ReadonlyMap<RundownId, ShowStyleBaseId>,
126126
orderedAllParts: PartId[],
127127
nextPartIsAfterCurrentPart: boolean,
128128
currentPartInstance: PartInstance | undefined,

packages/webui/src/client/lib/rundown.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ export namespace RundownUtils {
289289
segment: DBSegment,
290290
segmentsToReceiveOnRundownEndFromSet: Set<SegmentId>,
291291
rundownsToReceiveOnShowStyleEndFrom: RundownId[],
292-
rundownsToShowstyles: Map<RundownId, ShowStyleBaseId>,
292+
rundownsToShowstyles: ReadonlyMap<RundownId, ShowStyleBaseId>,
293293
orderedAllPartIds: PartId[],
294294
currentPartInstance: PartInstance | undefined,
295295
nextPartInstance: PartInstance | undefined,

packages/webui/src/client/ui/RundownList/util.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { doModalDialog } from '../../lib/ModalDialog.js'
44
import { doUserAction, UserAction } from '../../lib/clientUserAction.js'
55
import { MeteorCall } from '../../lib/meteorApi.js'
66
import { TFunction } from 'i18next'
7-
import { handleRundownReloadResponse } from '../RundownView.js'
7+
import { handleRundownReloadResponse } from '../RundownView/RundownHeader/RundownReloadResponse.js'
88
import {
99
RundownId,
1010
RundownLayoutId,

packages/webui/src/client/ui/RundownView.tsx

Lines changed: 545 additions & 2363 deletions
Large diffs are not rendered by default.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { TSR } from '@sofie-automation/blueprints-integration'
2+
import { StudioId } from '@sofie-automation/corelib/dist/dataModel/Ids'
3+
import { PeripheralDevice } from '@sofie-automation/corelib/dist/dataModel/PeripheralDevice'
4+
import { unprotectString } from '@sofie-automation/corelib/dist/protectedString'
5+
import { isTranslatableMessage, translateMessage } from '@sofie-automation/corelib/dist/TranslatableMessage'
6+
import { DEFAULT_TSR_ACTION_TIMEOUT_TIME } from '@sofie-automation/shared-lib/dist/core/constants'
7+
import { PeripheralDeviceType } from '@sofie-automation/shared-lib/dist/peripheralDevice/peripheralDeviceAPI'
8+
import React, { memo, useCallback } from 'react'
9+
import { useTranslation } from 'react-i18next'
10+
import { PeripheralDevices } from '../../collections'
11+
import { callPeripheralDeviceAction } from '../../lib/clientAPI'
12+
import { doModalDialog } from '../../lib/ModalDialog'
13+
import { NotificationCenter, NoticeLevel, Notification } from '../../lib/notifications/notifications'
14+
import { useTracker } from '../../lib/ReactMeteorData/ReactMeteorData'
15+
import { i18nTranslator } from '../i18n'
16+
17+
export const CasparCGRestartButtons = memo(function CasparCGRestartButtons({ studioId }: { studioId: StudioId }) {
18+
const { t } = useTranslation()
19+
20+
const casparCGPlayoutDevices = useTracker(
21+
() =>
22+
PeripheralDevices.find({
23+
parentDeviceId: {
24+
$in: PeripheralDevices.find({
25+
'studioAndConfigId.studioId': studioId,
26+
})
27+
.fetch()
28+
.map((i) => i._id),
29+
},
30+
type: PeripheralDeviceType.PLAYOUT,
31+
subType: TSR.DeviceType.CASPARCG,
32+
}).fetch(),
33+
[studioId],
34+
[]
35+
)
36+
37+
const onRestartCasparCG = useCallback(
38+
(e: React.MouseEvent<HTMLButtonElement>, device: PeripheralDevice) => {
39+
e.persist()
40+
41+
doModalDialog({
42+
title: t('Restart CasparCG Server'),
43+
message: t('Do you want to restart CasparCG Server "{{device}}"?', { device: device.name }),
44+
onAccept: () => {
45+
callPeripheralDeviceAction(e, device._id, DEFAULT_TSR_ACTION_TIMEOUT_TIME, TSR.CasparCGActions.RestartServer)
46+
.then((r) => {
47+
if (r?.result === TSR.ActionExecutionResultCode.Error) {
48+
throw new Error(
49+
r.response && isTranslatableMessage(r.response)
50+
? translateMessage(r.response, i18nTranslator)
51+
: t('Unknown error')
52+
)
53+
}
54+
55+
NotificationCenter.push(
56+
new Notification(
57+
undefined,
58+
NoticeLevel.NOTIFICATION,
59+
t('CasparCG on device "{{deviceName}}" restarting...', { deviceName: device.name }),
60+
'SystemStatus'
61+
)
62+
)
63+
})
64+
.catch((err) => {
65+
NotificationCenter.push(
66+
new Notification(
67+
undefined,
68+
NoticeLevel.WARNING,
69+
t('Failed to restart CasparCG on device: "{{deviceName}}": {{errorMessage}}', {
70+
deviceName: device.name,
71+
errorMessage: err + '',
72+
}),
73+
'SystemStatus'
74+
)
75+
)
76+
})
77+
},
78+
})
79+
},
80+
[t]
81+
)
82+
83+
return (
84+
<>
85+
{casparCGPlayoutDevices.map((i) => (
86+
<React.Fragment key={unprotectString(i._id)}>
87+
<button className="btn btn-secondary" onClick={(e) => onRestartCasparCG(e, i)}>
88+
{t('Restart {{device}}', { device: i.name })}
89+
</button>
90+
<hr />
91+
</React.Fragment>
92+
))}
93+
</>
94+
)
95+
})
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { useTranslation } from 'react-i18next'
2+
import { Route } from 'react-router-dom'
3+
import type { DBRundownPlaylist } from '@sofie-automation/corelib/dist/dataModel/RundownPlaylist'
4+
import type { DBRundown } from '@sofie-automation/corelib/dist/dataModel/Rundown'
5+
import type { DBShowStyleVariant } from '@sofie-automation/corelib/dist/dataModel/ShowStyleVariant'
6+
import type { UIStudio } from '@sofie-automation/meteor-lib/dist/api/studios'
7+
import type { UIShowStyleBase } from '@sofie-automation/meteor-lib/dist/api/showStyles'
8+
9+
interface RundownDataMissingProps {
10+
playlist: DBRundownPlaylist | undefined
11+
studio: UIStudio | undefined
12+
rundowns: DBRundown[]
13+
showStyleBase: UIShowStyleBase | undefined
14+
showStyleVariant: DBShowStyleVariant | undefined
15+
}
16+
17+
export function RundownDataMissing(props: RundownDataMissingProps): JSX.Element {
18+
const { t } = useTranslation()
19+
20+
return (
21+
<div className="rundown-view rundown-view--unpublished">
22+
<div className="rundown-view__label">
23+
<p className="summary">
24+
{!props.playlist
25+
? t('This rundown has been unpublished from Sofie.')
26+
: !props.studio
27+
? t('Error: The studio of this Rundown was not found.')
28+
: !props.rundowns.length
29+
? t('This playlist is empty')
30+
: !props.showStyleBase || !props.showStyleVariant
31+
? t('Error: The ShowStyle of this Rundown was not found.')
32+
: t('Unknown error')}
33+
</p>
34+
<p>
35+
<Route
36+
render={({ history }) => (
37+
<button
38+
className="btn btn-primary"
39+
onClick={() => {
40+
history.push('/rundowns')
41+
}}
42+
>
43+
{t('Return to list')}
44+
</button>
45+
)}
46+
/>
47+
</p>
48+
</div>
49+
</div>
50+
)
51+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { Rundown } from '@sofie-automation/corelib/dist/dataModel/Rundown'
2+
import { DBRundownPlaylist } from '@sofie-automation/corelib/dist/dataModel/RundownPlaylist'
3+
import { DBShowStyleVariant } from '@sofie-automation/corelib/dist/dataModel/ShowStyleVariant'
4+
import { UIShowStyleBase } from '@sofie-automation/meteor-lib/dist/api/showStyles'
5+
import { UIStudio } from '@sofie-automation/meteor-lib/dist/api/studios'
6+
import { useContext } from 'react'
7+
import { ErrorBoundary } from '../../lib/ErrorBoundary'
8+
import { PreviewPopUpContextProvider } from '../PreviewPopUp/PreviewPopUpContext'
9+
import { Shelf } from '../Shelf/Shelf'
10+
import { UserPermissionsContext } from '../UserPermissions'
11+
import { RundownSorensenContext } from './RundownSorensenContext'
12+
import { RundownTimingProvider } from './RundownTiming/RundownTimingProvider'
13+
import { Settings } from '../../lib/Settings'
14+
import { RundownLayoutShelfBase } from '@sofie-automation/meteor-lib/dist/collections/RundownLayouts'
15+
16+
interface RundownDetachedShelfProps {
17+
playlist: DBRundownPlaylist
18+
currentRundown: Rundown | undefined
19+
studio: UIStudio
20+
showStyleBase: UIShowStyleBase
21+
showStyleVariant: DBShowStyleVariant
22+
shelfLayout: RundownLayoutShelfBase | undefined
23+
}
24+
25+
export function RundownDetachedShelf({
26+
playlist,
27+
currentRundown,
28+
studio,
29+
showStyleBase,
30+
showStyleVariant,
31+
shelfLayout,
32+
}: RundownDetachedShelfProps): JSX.Element {
33+
const userPermissions = useContext(UserPermissionsContext)
34+
35+
return (
36+
<RundownTimingProvider playlist={playlist} defaultDuration={Settings.defaultDisplayDuration}>
37+
<PreviewPopUpContextProvider>
38+
<ErrorBoundary>
39+
<Shelf
40+
isExpanded={true}
41+
playlist={playlist}
42+
showStyleBase={showStyleBase}
43+
showStyleVariant={showStyleVariant}
44+
rundownLayout={shelfLayout}
45+
studio={studio}
46+
fullViewport={true}
47+
/>
48+
</ErrorBoundary>
49+
</PreviewPopUpContextProvider>
50+
<ErrorBoundary>
51+
{userPermissions.studio && currentRundown && (
52+
<RundownSorensenContext
53+
studio={studio}
54+
playlist={playlist}
55+
currentRundown={currentRundown}
56+
showStyleBase={showStyleBase}
57+
/>
58+
)}
59+
</ErrorBoundary>
60+
</RundownTimingProvider>
61+
)
62+
}

0 commit comments

Comments
 (0)