Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properties Panel (RFC #1289) #1342

Open
wants to merge 1 commit into
base: release52
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions meteor/server/api/rest/v1/typeConversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@
enableQuickLoop: apiStudioSettings.enableQuickLoop,
forceQuickLoopAutoNext: forceQuickLoopAutoNextFrom(apiStudioSettings.forceQuickLoopAutoNext),
fallbackPartDuration: apiStudioSettings.fallbackPartDuration ?? DEFAULT_FALLBACK_PART_DURATION,
enableUserEdits: apiStudioSettings.enableUserEdits,

Check warning on line 370 in meteor/server/api/rest/v1/typeConversion.ts

View check run for this annotation

Codecov / codecov/patch

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

Added line #L370 was not covered by tests
allowAdlibTestingSegment: apiStudioSettings.allowAdlibTestingSegment,
allowHold: apiStudioSettings.allowHold ?? true, // Backwards compatible
allowPieceDirectPlay: apiStudioSettings.allowPieceDirectPlay ?? true, // Backwards compatible
Expand All @@ -390,6 +391,7 @@
enableQuickLoop: settings.enableQuickLoop,
forceQuickLoopAutoNext: APIForceQuickLoopAutoNextFrom(settings.forceQuickLoopAutoNext),
fallbackPartDuration: settings.fallbackPartDuration,
enableUserEdits: settings.enableUserEdits,

Check warning on line 394 in meteor/server/api/rest/v1/typeConversion.ts

View check run for this annotation

Codecov / codecov/patch

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

Added line #L394 was not covered by tests
allowAdlibTestingSegment: settings.allowAdlibTestingSegment,
allowHold: settings.allowHold,
allowPieceDirectPlay: settings.allowPieceDirectPlay,
Expand Down
1 change: 1 addition & 0 deletions meteor/server/lib/rest/v1/studios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@
forceQuickLoopAutoNext?: 'disabled' | 'enabled_when_valid_duration' | 'enabled_forcing_min_duration'
minimumTakeSpan?: number
fallbackPartDuration?: number
enableUserEdits?: boolean

Check warning on line 219 in meteor/server/lib/rest/v1/studios.ts

View check run for this annotation

Codecov / codecov/patch

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

Added line #L219 was not covered by tests
allowAdlibTestingSegment?: boolean
allowHold?: boolean
allowPieceDirectPlay?: boolean
Expand Down
8 changes: 7 additions & 1 deletion packages/blueprints-integration/src/documents/part.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { UserEditingDefinition } from '../userEditing'
import { UserEditingDefinition, UserEditingProperties } from '../userEditing'
import type { NoteSeverity } from '../lib'
import type { ITranslatableMessage } from '../translations'

Expand Down Expand Up @@ -88,6 +88,12 @@ export interface IBlueprintMutatablePart<TPrivateData = unknown, TPublicData = u
* User editing definitions for this part
*/
userEditOperations?: UserEditingDefinition[]

/**
* Properties that are user editable from the properties panel in the Sofie UI, if the user saves changes to these
* it will trigger a user edit operation of type DefaultUserOperationEditProperties
*/
userEditProperties?: UserEditingProperties
}

export interface HackPartMediaObjectSubscription {
Expand Down
8 changes: 7 additions & 1 deletion packages/blueprints-integration/src/documents/piece.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { UserEditingDefinition } from '../userEditing'
import { UserEditingDefinition, UserEditingProperties } from '../userEditing'
import type { IBlueprintPieceGeneric } from './pieceGeneric'

/** Special types of pieces. Some are not always used in all circumstances */
Expand Down Expand Up @@ -35,6 +35,12 @@ export interface IBlueprintPiece<TPrivateData = unknown, TPublicData = unknown>
* User editing definitions for this piece
*/
userEditOperations?: UserEditingDefinition[]

/**
* Properties that are user editable from the properties panel in the Sofie UI, if the user saves changes to these
* it will trigger a user edit operation of type DefaultUserOperationEditProperties
*/
userEditProperties?: UserEditingProperties
}
export interface IBlueprintPieceDB<TPrivateData = unknown, TPublicData = unknown>
extends IBlueprintPiece<TPrivateData, TPublicData> {
Expand Down
8 changes: 7 additions & 1 deletion packages/blueprints-integration/src/documents/segment.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { UserEditingDefinition } from '../userEditing'
import { UserEditingDefinition, UserEditingProperties } from '../userEditing'

export enum SegmentDisplayMode {
Timeline = 'timeline',
Expand Down Expand Up @@ -52,6 +52,12 @@ export interface IBlueprintSegment<TPrivateData = unknown, TPublicData = unknown
* User editing definitions for this segment
*/
userEditOperations?: UserEditingDefinition[]

/**
* Properties that are user editable from the properties panel in the Sofie UI, if the user saves changes to these
* it will trigger a user edit operation of type DefaultUserOperationEditProperties
*/
userEditProperties?: UserEditingProperties
}
/** The Segment sent from Core */
export interface IBlueprintSegmentDB<TPrivateData = unknown, TPublicData = unknown>
Expand Down
34 changes: 32 additions & 2 deletions packages/blueprints-integration/src/ingest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,41 @@ export interface UserOperationTarget {
pieceExternalId: string | undefined
}

export type DefaultUserOperations = {
id: '__sofie-move-segment' // Future: define properly
export enum DefaultUserOperationsTypes {
REVERT_SEGMENT = '__sofie-revert-segment',
REVERT_PART = '__sofie-revert-part',
REVERT_RUNDOWN = '__sofie-revert-rundown',
UPDATE_PROPS = '__sofie-update-props',
}

export interface DefaultUserOperationRevertRundown {
id: DefaultUserOperationsTypes.REVERT_RUNDOWN
payload: Record<string, never>
}

export interface DefaultUserOperationRevertSegment {
id: DefaultUserOperationsTypes.REVERT_SEGMENT
payload: Record<string, never>
}

export interface DefaultUserOperationRevertPart {
id: DefaultUserOperationsTypes.REVERT_PART
}

export interface DefaultUserOperationEditProperties {
id: DefaultUserOperationsTypes.UPDATE_PROPS
payload: {
pieceTypeProperties: { type: string; value: Record<string, any> }
globalProperties: Record<string, any>
}
}

export type DefaultUserOperations =
| DefaultUserOperationRevertRundown
| DefaultUserOperationRevertSegment
| DefaultUserOperationRevertPart
| DefaultUserOperationEditProperties

export interface UserOperationChange<TCustomBlueprintOperations extends { id: string } = never> {
/** Indicate that this change is from user operations */
source: IngestChangeType.User
Expand Down
56 changes: 53 additions & 3 deletions packages/blueprints-integration/src/userEditing.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { JSONBlob } from '@sofie-automation/shared-lib/dist/lib/JSONBlob'
import type { ITranslatableMessage } from './translations'
import type { JSONSchema } from '@sofie-automation/shared-lib/dist/lib/JSONSchemaTypes'
import { JSONSchema } from '@sofie-automation/shared-lib/dist/lib/JSONSchemaTypes'
import { SourceLayerType } from './content'

/**
* Description of a user performed editing operation allowed on an document
Expand All @@ -16,8 +17,10 @@ export interface UserEditingDefinitionAction {
id: string
/** Label to show to the user for this operation */
label: ITranslatableMessage
/** Icon to show to when this action is 'active' */
/** Icon to show when this action is 'active' */
svgIcon?: string
/** Icon to show when this action is 'disabled' */
svgIconInactive?: string
/** Whether this action should be indicated as being active */
isActive?: boolean
}
Expand All @@ -40,6 +43,53 @@ export interface UserEditingDefinitionForm {
export enum UserEditingType {
/** Action */
ACTION = 'action',
/** Form of selections */
/** Form */
FORM = 'form',
}

export interface UserEditingSourceLayer {
sourceLayerLabel: string
sourceLayerType: SourceLayerType
schema: JSONBlob<JSONSchema>
defaultValue?: Record<string, any>
}

export interface UserEditingProperties {
/**
* These properties are dependent on the (primary) piece type, the user will get the option
* to select the type of piece (from the SourceLayerTypes i.e. Camera or Split etc.) and then
* be presented the corresponding form
*
* example:
* {
* schema: {
* camera: '{ "type": "object", "properties": { "input": { "type": "number" } } }',
* split: '{ "type": "object", ... }',
* },
* currentValue: {
* type: 'camera',
* value: {
* input: 3
* },
* }
* }
*/
pieceTypeProperties?: {
schema: Record<string, UserEditingSourceLayer>
currentValue: { type: string; value: Record<string, any> }
}

/**
* These are properties that are available to edit regardless of the piece type, examples
* could be whether it an element is locked from NRCS updates
*
* if you do not want the piece type to be changed, then use only this field.
*/
globalProperties?: { schema: JSONBlob<JSONSchema>; currentValue: Record<string, any> }

/**
* A list of id's of operations to be exposed on the properties panel as buttons. These operations
* must be available on the element
*/
operations?: UserEditingDefinitionAction[]
}
8 changes: 7 additions & 1 deletion packages/corelib/src/dataModel/Part.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ITranslatableMessage } from '../TranslatableMessage'
import { PartId, RundownId, SegmentId } from './Ids'
import { PartNote } from './Notes'
import { ReadonlyDeep } from 'type-fest'
import { CoreUserEditingDefinition } from './UserEditingDefinitions'
import { CoreUserEditingDefinition, CoreUserEditingProperties } from './UserEditingDefinitions'

export interface PartInvalidReason {
message: ITranslatableMessage
Expand Down Expand Up @@ -41,6 +41,12 @@ export interface DBPart extends Omit<IBlueprintPart, 'userEditOperations'> {
* User editing definitions for this part
*/
userEditOperations?: CoreUserEditingDefinition[]

/**
* Properties that are user editable from the properties panel in the Sofie UI, if the user saves changes to these
* it will trigger a user edit operation of type DefaultUserOperationEditProperties
*/
userEditProperties?: CoreUserEditingProperties
}

export function isPartPlayable(part: Pick<ReadonlyDeep<DBPart>, 'invalid' | 'floated'>): boolean {
Expand Down
12 changes: 10 additions & 2 deletions packages/corelib/src/dataModel/Piece.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from '@sofie-automation/blueprints-integration'
import { ProtectedString, protectString, unprotectString } from '../protectedString'
import { PieceId, RundownId, SegmentId, PartId } from './Ids'
import { CoreUserEditingDefinition } from './UserEditingDefinitions'
import { CoreUserEditingDefinition, CoreUserEditingProperties } from './UserEditingDefinitions'

/** A generic list of playback availability statuses for a Piece */
export enum PieceStatusCode {
Expand Down Expand Up @@ -50,7 +50,9 @@ export interface PieceGeneric extends Omit<IBlueprintPieceGeneric, 'content'> {
/** Stringified timelineObjects */
timelineObjectsString: PieceTimelineObjectsBlob
}
export interface Piece extends PieceGeneric, Omit<IBlueprintPieceDB, '_id' | 'content' | 'userEditOperations'> {
export interface Piece
extends PieceGeneric,
Omit<IBlueprintPieceDB, '_id' | 'content' | 'userEditOperations' | 'userEditProperties'> {
/**
* This is the id of the rundown this piece starts playing in.
* Currently this is the only rundown the piece could be playing in
Expand All @@ -77,6 +79,12 @@ export interface Piece extends PieceGeneric, Omit<IBlueprintPieceDB, '_id' | 'co
* User editing definitions for this piece
*/
userEditOperations?: CoreUserEditingDefinition[]

/**
* Properties that are user editable from the properties panel in the Sofie UI, if the user saves changes to these
* it will trigger a user edit operation of type DefaultUserOperationEditProperties
*/
userEditProperties?: CoreUserEditingProperties
}

export type PieceTimelineObjectsBlob = ProtectedString<'PieceTimelineObjectsBlob'>
Expand Down
8 changes: 7 additions & 1 deletion packages/corelib/src/dataModel/Segment.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SegmentDisplayMode, SegmentTimingInfo } from '@sofie-automation/blueprints-integration'
import { SegmentId, RundownId } from './Ids'
import { SegmentNote } from './Notes'
import { CoreUserEditingDefinition } from './UserEditingDefinitions'
import { CoreUserEditingDefinition, CoreUserEditingProperties } from './UserEditingDefinitions'

export enum SegmentOrphanedReason {
/** Segment is deleted from the NRCS but we still need it */
Expand Down Expand Up @@ -51,4 +51,10 @@ export interface DBSegment {
* User editing definitions for this segment
*/
userEditOperations?: CoreUserEditingDefinition[]

/**
* Properties that are user editable from the properties panel in the Sofie UI, if the user saves changes to these
* it will trigger a user edit operation of type DefaultUserOperationEditProperties
*/
userEditProperties?: CoreUserEditingProperties
}
59 changes: 57 additions & 2 deletions packages/corelib/src/dataModel/UserEditingDefinitions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import type { UserEditingType, JSONBlob, JSONSchema } from '@sofie-automation/blueprints-integration'
import type {
UserEditingType,
JSONBlob,
JSONSchema,
UserEditingSourceLayer,
} from '@sofie-automation/blueprints-integration'
import type { ITranslatableMessage } from '../TranslatableMessage'

export type CoreUserEditingDefinition = CoreUserEditingDefinitionAction | CoreUserEditingDefinitionForm
Expand All @@ -9,12 +14,17 @@ export interface CoreUserEditingDefinitionAction {
id: string
/** Label to show to the user for this operation */
label: ITranslatableMessage
/** Icon to show to when this action is 'active' */
/** Icon to show when this action is 'active' */
svgIcon?: string
/** Icon to show when this action is 'disabled' */
svgIconInactive?: string
/** Whether this action should be indicated as being active */
isActive?: boolean
}

/**
* A simple form based operation
*/
export interface CoreUserEditingDefinitionForm {
type: UserEditingType.FORM
/** Id of this operation */
Expand All @@ -28,3 +38,48 @@ export interface CoreUserEditingDefinitionForm {
/** Translation namespaces to use when rendering this form */
translationNamespaces: string[]
}

export interface CoreUserEditingProperties {
/**
* These properties are dependent on the (primary) piece type, the user will get the option
* to select the type of piece (from the SourceLayerTypes i.e. Camera or Split etc.) and then
* be presented the corresponding form
*
* example:
* {
* schema: {
* camera: '{ "type": "object", "properties": { "input": { "type": "number" } } }',
* split: '{ "type": "object", ... }',
* },
* currentValue: {
* type: 'camera',
* value: {
* input: 3
* },
* }
* }
*/
pieceTypeProperties?: {
schema: Record<string, UserEditingSourceLayer>
currentValue: { type: string; value: Record<string, any> }
}

/**
* These are properties that are available to edit regardless of the piece type, examples
* could be whether it an element is locked from NRCS updates
*
* if you do not want the piece type to be changed, then use only this field.
*/
globalProperties?: { schema: JSONBlob<JSONSchema>; currentValue: Record<string, any> }

/**
* A list of id's of operations to be exposed on the properties panel as buttons. These operations
* must be available on the element
*
* note - perhaps these should have their own full definitions?
*/
operations?: CoreUserEditingDefinitionAction[]

/** Translation namespaces to use when rendering this form */
translationNamespaces: string[]
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ If an integer property, whether to treat it as zero-based
### `ui:displayType`

Override the presentation with a special mode.
Currently only valid for string properties. Valid values are 'json'.

Currently only valid for:

- object properties. Valid values are 'json'.
- string properties. Valid values are 'base64-image'.
- boolean properties. Valid values are 'switch'.

### `tsEnumNames`

Expand Down
Loading
Loading