Skip to content

Commit 3d2493b

Browse files
committed
Allow AB display settings to be set by blueprints
And add a reset button in the UI to return them to the blueprints default state,
1 parent 87f8d04 commit 3d2493b

File tree

5 files changed

+97
-18
lines changed

5 files changed

+97
-18
lines changed

meteor/server/migration/upgrades/showStyleBase.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,28 @@ export async function runUpgradeForShowStyleBase(showStyleBaseId: ShowStyleBaseI
129129

130130
const result = blueprintManifest.applyConfig(blueprintContext, rawBlueprintConfig)
131131

132-
await ShowStyleBases.updateAsync(showStyleBaseId, {
133-
$set: {
134-
'sourceLayersWithOverrides.defaults': normalizeArray(result.sourceLayers, '_id'),
135-
'outputLayersWithOverrides.defaults': normalizeArray(result.outputLayers, '_id'),
136-
lastBlueprintConfig: {
137-
blueprintHash: blueprint.blueprintHash,
138-
blueprintId: blueprint._id,
139-
blueprintConfigPresetId: showStyleBase.blueprintConfigPresetId ?? '',
140-
config: rawBlueprintConfig,
141-
},
132+
const updateSet: Record<string, any> = {
133+
'sourceLayersWithOverrides.defaults': normalizeArray(result.sourceLayers, '_id'),
134+
'outputLayersWithOverrides.defaults': normalizeArray(result.outputLayers, '_id'),
135+
lastBlueprintConfig: {
136+
blueprintHash: blueprint.blueprintHash,
137+
blueprintId: blueprint._id,
138+
blueprintConfigPresetId: showStyleBase.blueprintConfigPresetId ?? '',
139+
config: rawBlueprintConfig,
142140
},
141+
}
142+
143+
// Store the blueprint-defined abChannelDisplay config if provided
144+
if (result.abChannelDisplay !== undefined) {
145+
updateSet.blueprintAbChannelDisplay = result.abChannelDisplay
146+
// Initialize abChannelDisplay from blueprint if not already set by user
147+
if (!showStyleBase.abChannelDisplay) {
148+
updateSet.abChannelDisplay = result.abChannelDisplay
149+
}
150+
}
151+
152+
await ShowStyleBases.updateAsync(showStyleBaseId, {
153+
$set: updateSet,
143154
})
144155

145156
await updateTriggeredActionsForShowStyleBaseId(showStyleBaseId, result.triggeredActions)
@@ -153,6 +164,7 @@ async function loadShowStyleAndBlueprint(showStyleBaseId: ShowStyleBaseId) {
153164
blueprintConfigPresetId: 1,
154165
blueprintConfigWithOverrides: 1,
155166
lastBlueprintFixUpHash: 1,
167+
abChannelDisplay: 1,
156168
},
157169
})) as
158170
| Pick<
@@ -161,6 +173,7 @@ async function loadShowStyleAndBlueprint(showStyleBaseId: ShowStyleBaseId) {
161173
| 'blueprintId'
162174
| 'blueprintConfigPresetId'
163175
| 'blueprintConfigWithOverrides'
176+
| 'abChannelDisplay'
164177
| 'lastBlueprintFixUpHash'
165178
>
166179
| undefined

packages/blueprints-integration/src/api/showStyle.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import type {
3636
IBlueprintPiece,
3737
IBlueprintPart,
3838
} from '../documents/index.js'
39-
import type { IBlueprintShowStyleVariant, IOutputLayer, ISourceLayer } from '../showStyle.js'
39+
import type { IBlueprintShowStyleVariant, IOutputLayer, ISourceLayer, SourceLayerType } from '../showStyle.js'
4040
import type { TSR, OnGenerateTimelineObj, TimelineObjectCoreExt } from '../timeline.js'
4141
import type { IBlueprintConfig } from '../common.js'
4242
import type { ReadonlyDeep } from 'type-fest'
@@ -322,6 +322,19 @@ export interface BlueprintResultApplyShowStyleConfig {
322322
outputLayers: IOutputLayer[]
323323

324324
triggeredActions: IBlueprintTriggeredActions[]
325+
326+
/** Configuration for displaying AB resolver channel assignments */
327+
abChannelDisplay?: {
328+
/** Source layer IDs that should show AB channel info */
329+
sourceLayerIds: string[]
330+
/** Configure by source layer type */
331+
sourceLayerTypes: SourceLayerType[]
332+
/** Only show for specific output layers (e.g., only PGM) */
333+
outputLayerIds: string[]
334+
/** Enable display on Director screen */
335+
showOnDirectorScreen: boolean
336+
// Future: showOnPresenterScreen, showOnCameraScreen when those views are implemented
337+
}
325338
}
326339

327340
export interface IShowStyleConfigPreset<TConfig = IBlueprintConfig> {

packages/corelib/src/dataModel/ShowStyleBase.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ export interface DBShowStyleBase {
6161
// Future: showOnPresenterScreen, showOnCameraScreen when those views are implemented
6262
}
6363

64+
/** Blueprint default for abChannelDisplay (saved during blueprint upgrade) */
65+
blueprintAbChannelDisplay?: {
66+
sourceLayerIds: string[]
67+
sourceLayerTypes: SourceLayerType[]
68+
outputLayerIds: string[]
69+
showOnDirectorScreen: boolean
70+
}
71+
6472
_rundownVersionHash: string
6573

6674
/** Details on the last blueprint used to generate the defaults values for this */

packages/webui/src/client/ui/Settings/ShowStyle/AbChannelDisplay.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
.ab-channel-display {
2+
&__header {
3+
display: flex;
4+
justify-content: space-between;
5+
align-items: center;
6+
}
7+
28
&__section {
39
margin-top: 1rem;
410

packages/webui/src/client/ui/Settings/ShowStyle/AbChannelDisplay.tsx

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { useCallback, useMemo } from 'react'
66
import { SourceLayers, OutputLayers } from '@sofie-automation/corelib/dist/dataModel/ShowStyleBase'
77
import { applyAndValidateOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'
88
import { ColumnPackedGrid, ColumnPackedGridGroup, ColumnPackedGridItem } from '../components/ColumnPackedGrid'
9+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
10+
import { faSync } from '@fortawesome/free-solid-svg-icons'
911
import '../components/ColumnPackedGrid.scss'
1012
import './AbChannelDisplay.scss'
1113

@@ -45,12 +47,27 @@ export function AbChannelDisplaySettings({ showStyleBase }: Readonly<AbChannelDi
4547
[]
4648
)
4749

48-
const config = showStyleBase.abChannelDisplay ?? {
49-
sourceLayerIds: [],
50-
sourceLayerTypes: [SourceLayerType.VT, SourceLayerType.LIVE_SPEAK],
51-
outputLayerIds: [],
52-
showOnDirectorScreen: false,
53-
}
50+
const blueprintDefault = showStyleBase.blueprintAbChannelDisplay
51+
const config = showStyleBase.abChannelDisplay ??
52+
blueprintDefault ?? {
53+
sourceLayerIds: [],
54+
sourceLayerTypes: [SourceLayerType.VT, SourceLayerType.LIVE_SPEAK],
55+
outputLayerIds: [],
56+
showOnDirectorScreen: false,
57+
}
58+
59+
// Check if current config differs from blueprint default
60+
const hasOverrides = useMemo(() => {
61+
if (!blueprintDefault || !showStyleBase.abChannelDisplay) return false
62+
63+
const current = showStyleBase.abChannelDisplay
64+
return (
65+
JSON.stringify(current.sourceLayerIds.sort()) !== JSON.stringify(blueprintDefault.sourceLayerIds.sort()) ||
66+
JSON.stringify(current.sourceLayerTypes.sort()) !== JSON.stringify(blueprintDefault.sourceLayerTypes.sort()) ||
67+
JSON.stringify(current.outputLayerIds.sort()) !== JSON.stringify(blueprintDefault.outputLayerIds.sort()) ||
68+
current.showOnDirectorScreen !== blueprintDefault.showOnDirectorScreen
69+
)
70+
}, [showStyleBase.abChannelDisplay, blueprintDefault])
5471

5572
const updateConfig = useCallback(
5673
(updates: Partial<NonNullable<DBShowStyleBase['abChannelDisplay']>>) => {
@@ -71,6 +88,14 @@ export function AbChannelDisplaySettings({ showStyleBase }: Readonly<AbChannelDi
7188
[showStyleBase._id, config]
7289
)
7390

91+
const resetToBlueprint = useCallback(() => {
92+
ShowStyleBases.update(showStyleBase._id, {
93+
$unset: {
94+
abChannelDisplay: 1,
95+
},
96+
})
97+
}, [showStyleBase._id])
98+
7499
const toggleDirectorScreen = useCallback(() => {
75100
updateConfig({ showOnDirectorScreen: !config.showOnDirectorScreen })
76101
}, [updateConfig, config.showOnDirectorScreen])
@@ -161,7 +186,21 @@ export function AbChannelDisplaySettings({ showStyleBase }: Readonly<AbChannelDi
161186

162187
return (
163188
<div className="studio-edit ab-channel-display">
164-
<h2>{t('AB Resolver Channel Display')}</h2>
189+
<div className="ab-channel-display__header">
190+
<h2>{t('AB Resolver Channel Display')}</h2>
191+
{blueprintDefault && (
192+
<button
193+
type="button"
194+
className="btn btn-primary"
195+
onClick={resetToBlueprint}
196+
title={t('Reset to default')}
197+
disabled={!hasOverrides}
198+
>
199+
<span>{t('Reset')}</span>
200+
<FontAwesomeIcon icon={faSync} />
201+
</button>
202+
)}
203+
</div>
165204
<p>
166205
{t(
167206
'Configure which pieces should display their assigned AB resolver channel (e.g., "Server A") on various screens. This helps operators identify which video server is playing each clip.'

0 commit comments

Comments
 (0)