Skip to content

Commit b51ee26

Browse files
authored
Merge pull request #1342 from bbc/upstream/feat/properties-panel
Properties Panel (RFC #1289)
2 parents a5d3101 + 054dcb1 commit b51ee26

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2639
-357
lines changed

meteor/server/api/rest/v1/typeConversion.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ export function studioSettingsFrom(apiStudioSettings: APIStudioSettings): Comple
367367
enableQuickLoop: apiStudioSettings.enableQuickLoop,
368368
forceQuickLoopAutoNext: forceQuickLoopAutoNextFrom(apiStudioSettings.forceQuickLoopAutoNext),
369369
fallbackPartDuration: apiStudioSettings.fallbackPartDuration ?? DEFAULT_FALLBACK_PART_DURATION,
370+
enableUserEdits: apiStudioSettings.enableUserEdits,
370371
allowAdlibTestingSegment: apiStudioSettings.allowAdlibTestingSegment,
371372
allowHold: apiStudioSettings.allowHold ?? true, // Backwards compatible
372373
allowPieceDirectPlay: apiStudioSettings.allowPieceDirectPlay ?? true, // Backwards compatible
@@ -391,6 +392,7 @@ export function APIStudioSettingsFrom(settings: IStudioSettings): Complete<APISt
391392
enableQuickLoop: settings.enableQuickLoop,
392393
forceQuickLoopAutoNext: APIForceQuickLoopAutoNextFrom(settings.forceQuickLoopAutoNext),
393394
fallbackPartDuration: settings.fallbackPartDuration,
395+
enableUserEdits: settings.enableUserEdits,
394396
allowAdlibTestingSegment: settings.allowAdlibTestingSegment,
395397
allowHold: settings.allowHold,
396398
allowPieceDirectPlay: settings.allowPieceDirectPlay,

meteor/server/lib/rest/v1/studios.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ export interface APIStudioSettings {
216216
forceQuickLoopAutoNext?: 'disabled' | 'enabled_when_valid_duration' | 'enabled_forcing_min_duration'
217217
minimumTakeSpan?: number
218218
fallbackPartDuration?: number
219+
enableUserEdits?: boolean
219220
allowAdlibTestingSegment?: boolean
220221
allowHold?: boolean
221222
allowPieceDirectPlay?: boolean

packages/blueprints-integration/src/documents/part.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { UserEditingDefinition } from '../userEditing'
1+
import { UserEditingDefinition, UserEditingProperties } from '../userEditing'
22
import type { NoteSeverity } from '../lib'
33
import type { ITranslatableMessage } from '../translations'
44

@@ -88,6 +88,12 @@ export interface IBlueprintMutatablePart<TPrivateData = unknown, TPublicData = u
8888
* User editing definitions for this part
8989
*/
9090
userEditOperations?: UserEditingDefinition[]
91+
92+
/**
93+
* Properties that are user editable from the properties panel in the Sofie UI, if the user saves changes to these
94+
* it will trigger a user edit operation of type DefaultUserOperationEditProperties
95+
*/
96+
userEditProperties?: UserEditingProperties
9197
}
9298

9399
export interface HackPartMediaObjectSubscription {

packages/blueprints-integration/src/documents/piece.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { UserEditingDefinition } from '../userEditing'
1+
import { UserEditingDefinition, UserEditingProperties } from '../userEditing'
22
import type { IBlueprintPieceGeneric } from './pieceGeneric'
33

44
/** Special types of pieces. Some are not always used in all circumstances */
@@ -35,6 +35,12 @@ export interface IBlueprintPiece<TPrivateData = unknown, TPublicData = unknown>
3535
* User editing definitions for this piece
3636
*/
3737
userEditOperations?: UserEditingDefinition[]
38+
39+
/**
40+
* Properties that are user editable from the properties panel in the Sofie UI, if the user saves changes to these
41+
* it will trigger a user edit operation of type DefaultUserOperationEditProperties
42+
*/
43+
userEditProperties?: UserEditingProperties
3844
}
3945
export interface IBlueprintPieceDB<TPrivateData = unknown, TPublicData = unknown>
4046
extends IBlueprintPiece<TPrivateData, TPublicData> {

packages/blueprints-integration/src/documents/segment.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { UserEditingDefinition } from '../userEditing'
1+
import { UserEditingDefinition, UserEditingProperties } from '../userEditing'
22

33
export enum SegmentDisplayMode {
44
Timeline = 'timeline',
@@ -52,6 +52,12 @@ export interface IBlueprintSegment<TPrivateData = unknown, TPublicData = unknown
5252
* User editing definitions for this segment
5353
*/
5454
userEditOperations?: UserEditingDefinition[]
55+
56+
/**
57+
* Properties that are user editable from the properties panel in the Sofie UI, if the user saves changes to these
58+
* it will trigger a user edit operation of type DefaultUserOperationEditProperties
59+
*/
60+
userEditProperties?: UserEditingProperties
5561
}
5662
/** The Segment sent from Core */
5763
export interface IBlueprintSegmentDB<TPrivateData = unknown, TPublicData = unknown>

packages/blueprints-integration/src/ingest.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,41 @@ export interface UserOperationTarget {
124124
pieceExternalId: string | undefined
125125
}
126126

127-
export type DefaultUserOperations = {
128-
id: '__sofie-move-segment' // Future: define properly
127+
export enum DefaultUserOperationsTypes {
128+
REVERT_SEGMENT = '__sofie-revert-segment',
129+
REVERT_PART = '__sofie-revert-part',
130+
REVERT_RUNDOWN = '__sofie-revert-rundown',
131+
UPDATE_PROPS = '__sofie-update-props',
132+
}
133+
134+
export interface DefaultUserOperationRevertRundown {
135+
id: DefaultUserOperationsTypes.REVERT_RUNDOWN
136+
payload: Record<string, never>
137+
}
138+
139+
export interface DefaultUserOperationRevertSegment {
140+
id: DefaultUserOperationsTypes.REVERT_SEGMENT
129141
payload: Record<string, never>
130142
}
131143

144+
export interface DefaultUserOperationRevertPart {
145+
id: DefaultUserOperationsTypes.REVERT_PART
146+
}
147+
148+
export interface DefaultUserOperationEditProperties {
149+
id: DefaultUserOperationsTypes.UPDATE_PROPS
150+
payload: {
151+
pieceTypeProperties: { type: string; value: Record<string, any> }
152+
globalProperties: Record<string, any>
153+
}
154+
}
155+
156+
export type DefaultUserOperations =
157+
| DefaultUserOperationRevertRundown
158+
| DefaultUserOperationRevertSegment
159+
| DefaultUserOperationRevertPart
160+
| DefaultUserOperationEditProperties
161+
132162
export interface UserOperationChange<TCustomBlueprintOperations extends { id: string } = never> {
133163
/** Indicate that this change is from user operations */
134164
source: IngestChangeType.User

packages/blueprints-integration/src/userEditing.ts

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { JSONBlob } from '@sofie-automation/shared-lib/dist/lib/JSONBlob'
22
import type { ITranslatableMessage } from './translations'
3-
import type { JSONSchema } from '@sofie-automation/shared-lib/dist/lib/JSONSchemaTypes'
3+
import { JSONSchema } from '@sofie-automation/shared-lib/dist/lib/JSONSchemaTypes'
4+
import { SourceLayerType } from './content'
45

56
/**
67
* Description of a user performed editing operation allowed on an document
@@ -16,8 +17,10 @@ export interface UserEditingDefinitionAction {
1617
id: string
1718
/** Label to show to the user for this operation */
1819
label: ITranslatableMessage
19-
/** Icon to show to when this action is 'active' */
20+
/** Icon to show when this action is 'active' */
2021
svgIcon?: string
22+
/** Icon to show when this action is 'disabled' */
23+
svgIconInactive?: string
2124
/** Whether this action should be indicated as being active */
2225
isActive?: boolean
2326
}
@@ -40,6 +43,53 @@ export interface UserEditingDefinitionForm {
4043
export enum UserEditingType {
4144
/** Action */
4245
ACTION = 'action',
43-
/** Form of selections */
46+
/** Form */
4447
FORM = 'form',
4548
}
49+
50+
export interface UserEditingSourceLayer {
51+
sourceLayerLabel: string
52+
sourceLayerType: SourceLayerType
53+
schema: JSONBlob<JSONSchema>
54+
defaultValue?: Record<string, any>
55+
}
56+
57+
export interface UserEditingProperties {
58+
/**
59+
* These properties are dependent on the (primary) piece type, the user will get the option
60+
* to select the type of piece (from the SourceLayerTypes i.e. Camera or Split etc.) and then
61+
* be presented the corresponding form
62+
*
63+
* example:
64+
* {
65+
* schema: {
66+
* camera: '{ "type": "object", "properties": { "input": { "type": "number" } } }',
67+
* split: '{ "type": "object", ... }',
68+
* },
69+
* currentValue: {
70+
* type: 'camera',
71+
* value: {
72+
* input: 3
73+
* },
74+
* }
75+
* }
76+
*/
77+
pieceTypeProperties?: {
78+
schema: Record<string, UserEditingSourceLayer>
79+
currentValue: { type: string; value: Record<string, any> }
80+
}
81+
82+
/**
83+
* These are properties that are available to edit regardless of the piece type, examples
84+
* could be whether it an element is locked from NRCS updates
85+
*
86+
* if you do not want the piece type to be changed, then use only this field.
87+
*/
88+
globalProperties?: { schema: JSONBlob<JSONSchema>; currentValue: Record<string, any> }
89+
90+
/**
91+
* A list of id's of operations to be exposed on the properties panel as buttons. These operations
92+
* must be available on the element
93+
*/
94+
operations?: UserEditingDefinitionAction[]
95+
}

packages/corelib/src/dataModel/Part.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { ITranslatableMessage } from '../TranslatableMessage'
33
import { PartId, RundownId, SegmentId } from './Ids'
44
import { PartNote } from './Notes'
55
import { ReadonlyDeep } from 'type-fest'
6-
import { CoreUserEditingDefinition } from './UserEditingDefinitions'
6+
import { CoreUserEditingDefinition, CoreUserEditingProperties } from './UserEditingDefinitions'
77

88
export interface PartInvalidReason {
99
message: ITranslatableMessage
@@ -41,6 +41,12 @@ export interface DBPart extends Omit<IBlueprintPart, 'userEditOperations'> {
4141
* User editing definitions for this part
4242
*/
4343
userEditOperations?: CoreUserEditingDefinition[]
44+
45+
/**
46+
* Properties that are user editable from the properties panel in the Sofie UI, if the user saves changes to these
47+
* it will trigger a user edit operation of type DefaultUserOperationEditProperties
48+
*/
49+
userEditProperties?: CoreUserEditingProperties
4450
}
4551

4652
export function isPartPlayable(part: Pick<ReadonlyDeep<DBPart>, 'invalid' | 'floated'>): boolean {

packages/corelib/src/dataModel/Piece.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from '@sofie-automation/blueprints-integration'
88
import { ProtectedString, protectString, unprotectString } from '../protectedString'
99
import { PieceId, RundownId, SegmentId, PartId } from './Ids'
10-
import { CoreUserEditingDefinition } from './UserEditingDefinitions'
10+
import { CoreUserEditingDefinition, CoreUserEditingProperties } from './UserEditingDefinitions'
1111

1212
/** A generic list of playback availability statuses for a Piece */
1313
export enum PieceStatusCode {
@@ -50,7 +50,9 @@ export interface PieceGeneric extends Omit<IBlueprintPieceGeneric, 'content'> {
5050
/** Stringified timelineObjects */
5151
timelineObjectsString: PieceTimelineObjectsBlob
5252
}
53-
export interface Piece extends PieceGeneric, Omit<IBlueprintPieceDB, '_id' | 'content' | 'userEditOperations'> {
53+
export interface Piece
54+
extends PieceGeneric,
55+
Omit<IBlueprintPieceDB, '_id' | 'content' | 'userEditOperations' | 'userEditProperties'> {
5456
/**
5557
* This is the id of the rundown this piece starts playing in.
5658
* Currently this is the only rundown the piece could be playing in
@@ -77,6 +79,12 @@ export interface Piece extends PieceGeneric, Omit<IBlueprintPieceDB, '_id' | 'co
7779
* User editing definitions for this piece
7880
*/
7981
userEditOperations?: CoreUserEditingDefinition[]
82+
83+
/**
84+
* Properties that are user editable from the properties panel in the Sofie UI, if the user saves changes to these
85+
* it will trigger a user edit operation of type DefaultUserOperationEditProperties
86+
*/
87+
userEditProperties?: CoreUserEditingProperties
8088
}
8189

8290
export type PieceTimelineObjectsBlob = ProtectedString<'PieceTimelineObjectsBlob'>

packages/corelib/src/dataModel/Segment.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { SegmentDisplayMode, SegmentTimingInfo } from '@sofie-automation/blueprints-integration'
22
import { SegmentId, RundownId } from './Ids'
33
import { SegmentNote } from './Notes'
4-
import { CoreUserEditingDefinition } from './UserEditingDefinitions'
4+
import { CoreUserEditingDefinition, CoreUserEditingProperties } from './UserEditingDefinitions'
55

66
export enum SegmentOrphanedReason {
77
/** Segment is deleted from the NRCS but we still need it */
@@ -51,4 +51,10 @@ export interface DBSegment {
5151
* User editing definitions for this segment
5252
*/
5353
userEditOperations?: CoreUserEditingDefinition[]
54+
55+
/**
56+
* Properties that are user editable from the properties panel in the Sofie UI, if the user saves changes to these
57+
* it will trigger a user edit operation of type DefaultUserOperationEditProperties
58+
*/
59+
userEditProperties?: CoreUserEditingProperties
5460
}

0 commit comments

Comments
 (0)