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

Drag and drop from MOS plugin to a Part #21

Open
wants to merge 2 commits into
base: bbc-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
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { CustomPublishCollection } from '../../../lib/customPublication'
import { logger } from '../../../logging'
import { ExpectedPackagesContentCache } from './contentCache'
import type { StudioFields } from './publication'
import { applyAndValidateOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'

/**
* Regenerate the output for the provided ExpectedPackage `regenerateIds`, updating the data in `collection` as needed
Expand All @@ -39,7 +38,6 @@ export async function updateCollectionForExpectedPackageIds(
): Promise<void> {
const updatedDocIds = new Set<PackageManagerExpectedPackageId>()
const missingExpectedPackageIds = new Set<ExpectedPackageId>()
const packageContainers = applyAndValidateOverrides(studio.packageContainersWithOverrides).obj

for (const packageId of regenerateIds) {
const packageDoc = contentCache.ExpectedPackages.findOne(packageId)
Expand Down Expand Up @@ -110,7 +108,6 @@ export async function updateCollectionForPieceInstanceIds(
): Promise<void> {
const updatedDocIds = new Set<PackageManagerExpectedPackageId>()
const missingPieceInstanceIds = new Set<PieceInstanceId>()
const packageContainers = applyAndValidateOverrides(studio.packageContainersWithOverrides).obj

for (const pieceInstanceId of regenerateIds) {
const pieceInstanceDoc = contentCache.PieceInstances.findOne(pieceInstanceId)
Expand Down
7 changes: 2 additions & 5 deletions packages/blueprints-integration/src/ingest.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IngestPart, IngestSegment } from '@sofie-automation/shared-lib/dist/peripheralDevice/ingest'
import { DefaultUserOperations } from '@sofie-automation/shared-lib/dist/core/model/ingest'
import { IBlueprintRundownDBData } from './documents'
import { ReadonlyDeep } from 'type-fest'
import { SofieIngestRundown } from './ingest-types'
Expand All @@ -10,6 +11,7 @@ export {
IngestSegment,
IngestAdlib,
} from '@sofie-automation/shared-lib/dist/peripheralDevice/ingest'
export * from '@sofie-automation/shared-lib/dist/core/model/ingest'

/** The IngestRundown is extended with data from Core */
export interface ExtendedIngestRundown<TRundownPayload = unknown, TSegmentPayload = unknown, TPartPayload = unknown>
Expand Down Expand Up @@ -124,11 +126,6 @@ export interface UserOperationTarget {
pieceExternalId: string | undefined
}

export type DefaultUserOperations = {
id: '__sofie-move-segment' // Future: define properly
payload: Record<string, never>
}

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

/**
* Description of a user performed editing operation allowed on an document
*/
export type UserEditingDefinition = UserEditingDefinitionAction | UserEditingDefinitionForm
export type UserEditingDefinition =
| UserEditingDefinitionAction
| UserEditingDefinitionForm
| UserEditingDefinitionSofieDefault

/**
* A simple 'action' that can be performed
Expand Down Expand Up @@ -37,9 +41,20 @@ export interface UserEditingDefinitionForm {
currentValues: Record<string, any>
}

/**
* A simple form based operation
*/
export interface UserEditingDefinitionSofieDefault {
type: UserEditingType.SOFIE
/** Id of this operation */
id: DefaultUserOperationsIDs
}

export enum UserEditingType {
/** Action */
ACTION = 'action',
/** Form of selections */
FORM = 'form',
/** Operation for the Built-in Sofie Rich Editing UI */
SOFIE = 'sofie',
}
18 changes: 16 additions & 2 deletions packages/corelib/src/dataModel/UserEditingDefinitions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import type { UserEditingType, JSONBlob, JSONSchema } from '@sofie-automation/blueprints-integration'
import type {
UserEditingType,
JSONBlob,
JSONSchema,
DefaultUserOperationsIDs,
} from '@sofie-automation/blueprints-integration'
import type { ITranslatableMessage } from '../TranslatableMessage'

export type CoreUserEditingDefinition = CoreUserEditingDefinitionAction | CoreUserEditingDefinitionForm
export type CoreUserEditingDefinition =
| CoreUserEditingDefinitionAction
| CoreUserEditingDefinitionForm
| CoreUserEditingDefinitionSofie

export interface CoreUserEditingDefinitionAction {
type: UserEditingType.ACTION
Expand All @@ -28,3 +36,9 @@ export interface CoreUserEditingDefinitionForm {
/** Translation namespaces to use when rendering this form */
translationNamespaces: string[]
}

export interface CoreUserEditingDefinitionSofie {
type: UserEditingType.SOFIE
/** Id of this operation */
id: DefaultUserOperationsIDs
}
12 changes: 12 additions & 0 deletions packages/job-worker/src/blueprints/context/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
CoreUserEditingDefinition,
CoreUserEditingDefinitionAction,
CoreUserEditingDefinitionForm,
CoreUserEditingDefinitionSofie,
} from '@sofie-automation/corelib/dist/dataModel/UserEditingDefinitions'
import { DBSegment } from '@sofie-automation/corelib/dist/dataModel/Segment'
import { assertNever, clone, Complete, literal, omit } from '@sofie-automation/corelib/dist/lib'
Expand Down Expand Up @@ -56,6 +57,7 @@ import {
UserEditingDefinition,
UserEditingDefinitionAction,
UserEditingDefinitionForm,
UserEditingDefinitionSofieDefault,
UserEditingType,
} from '@sofie-automation/blueprints-integration/dist/userEditing'
import type { PlayoutMutatablePart } from '../../playout/model/PlayoutPartInstanceModel'
Expand Down Expand Up @@ -520,6 +522,11 @@ function translateUserEditsToBlueprint(
schema: clone(userEdit.schema),
currentValues: clone(userEdit.currentValues),
} satisfies Complete<UserEditingDefinitionForm>
case UserEditingType.SOFIE:
return {
type: UserEditingType.SOFIE,
id: userEdit.id,
} satisfies Complete<UserEditingDefinitionSofieDefault>
default:
assertNever(userEdit)
return undefined
Expand Down Expand Up @@ -554,6 +561,11 @@ export function translateUserEditsFromBlueprint(
currentValues: clone(userEdit.currentValues),
translationNamespaces: unprotectStringArray(blueprintIds),
} satisfies Complete<CoreUserEditingDefinitionForm>
case UserEditingType.SOFIE:
return {
type: UserEditingType.SOFIE,
id: userEdit.id,
} satisfies Complete<CoreUserEditingDefinitionSofie>
default:
assertNever(userEdit)
return undefined
Expand Down
18 changes: 18 additions & 0 deletions packages/shared-lib/src/core/model/ingest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export enum DefaultUserOperationsIDs {
MoveSegment = '__sofie-move-segment',
ImportMOSItem = '__sofie-import-mos',
}

export type DefaultUserOperations = MoveSegmentUserOperations | ImportMOSItemUserOperation

export type MoveSegmentUserOperations = {
id: DefaultUserOperationsIDs.MoveSegment
payload: Record<string, never> // Future: define properly
}

export type ImportMOSItemUserOperation = {
id: DefaultUserOperationsIDs.ImportMOSItem

payloadType: string
payload: any
}
24 changes: 19 additions & 5 deletions packages/webui/src/client/styles/rundownView.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1399,12 +1399,13 @@ svg.icon {
&.quickloop-start {
left: -2px;

&::before, &::after {
&::before,
&::after {
z-index: 1;
margin-left: 5px;
border-left-color: white;
}

.segment-timeline__part__nextline__label {
z-index: 5;
left: 5px;
Expand Down Expand Up @@ -1571,6 +1572,19 @@ svg.icon {
z-index: 1;
}

&.drop-active {
&::after {
content: ' ';
display: block;
background-color: rgba(0, 183, 255, 0.5);
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
}

&.outside-quickloop {
&::before {
content: ' ';
Expand All @@ -1586,7 +1600,6 @@ svg.icon {
}
}


&:not(.live) {
.segment-timeline__part__nextline.auto-next:not(.segment-timeline__part__nextline--endline),
.segment-timeline__part__nextline.invalid:not(.segment-timeline__part__nextline--endline) {
Expand Down Expand Up @@ -1832,7 +1845,8 @@ svg.icon {
right: 0;
}

.segment-timeline__part__quickloop-start, .segment-timeline__part__quickloop-end {
.segment-timeline__part__quickloop-start,
.segment-timeline__part__quickloop-end {
background: $segment-background-color;
padding: 0 0.3em;
margin-bottom: -2px;
Expand All @@ -1849,7 +1863,7 @@ svg.icon {

.segment-timeline__part__quickloop-end {
padding-right: 0.6em;
margin-left: auto
margin-left: auto;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@
import { getPartInstanceTimingId, getPartInstanceTimingValue, RundownTimingContext } from '../../../lib/rundownTiming'
import { OutputGroup } from './OutputGroup'
import { InvalidPartCover } from './InvalidPartCover'
import { ISourceLayer } from '@sofie-automation/blueprints-integration'
import { DefaultUserOperationsIDs, ISourceLayer, UserEditingType } from '@sofie-automation/blueprints-integration'
import { UIStudio } from '@sofie-automation/meteor-lib/dist/api/studios'
import { LIVE_LINE_TIME_PADDING } from '../Constants'
import * as RundownResolver from '../../../lib/RundownResolver'
import { Events as MOSEvents } from '../../../lib/data/mos/plugin-support'

export const SegmentTimelineLineElementId = 'rundown__segment__line__'
export const SegmentTimelinePartElementId = 'rundown__segment__part__'
Expand Down Expand Up @@ -99,6 +100,8 @@
isTooSmallForText: boolean
isTooSmallForDisplay: boolean
highlight: boolean

dropActive: boolean
}
export class SegmentTimelinePartClass extends React.Component<Translated<WithTiming<IProps>>, IState> {
constructor(props: Readonly<Translated<WithTiming<IProps>>>) {
Expand Down Expand Up @@ -137,6 +140,7 @@
: 0
)
: 0,
dropActive: false,
}
}

Expand Down Expand Up @@ -263,6 +267,10 @@

componentDidMount(): void {
super.componentDidMount && super.componentDidMount()

window.addEventListener(MOSEvents.dragenter, this.onDragEnter)
window.addEventListener(MOSEvents.dragleave, this.onDragLeave)

RundownViewEventBus.on(RundownViewEvents.HIGHLIGHT, this.onHighlight)
const tooSmallState = this.state.isTooSmallForDisplay || this.state.isTooSmallForText
if (tooSmallState) {
Expand All @@ -282,6 +290,10 @@

componentWillUnmount(): void {
super.componentWillUnmount && super.componentWillUnmount()

window.removeEventListener(MOSEvents.dragenter, this.onDragEnter)
window.removeEventListener(MOSEvents.dragleave, this.onDragLeave)

RundownViewEventBus.off(RundownViewEvents.HIGHLIGHT, this.onHighlight)
this.highlightTimeout && clearTimeout(this.highlightTimeout)
}
Expand Down Expand Up @@ -622,6 +634,23 @@
return { red, green, blue }
}

onDragEnter = () => {

Check failure on line 637 in packages/webui/src/client/ui/SegmentTimeline/Parts/SegmentTimelinePart.tsx

View workflow job for this annotation

GitHub Actions / Lint Package (webui)

Missing return type on function

Check failure on line 637 in packages/webui/src/client/ui/SegmentTimeline/Parts/SegmentTimelinePart.tsx

View workflow job for this annotation

GitHub Actions / Lint Package (webui)

Missing return type on function
const supportsDrop = this.props.part.instance.part.userEditOperations?.find(
(op) => op.type === UserEditingType.SOFIE && op.id === DefaultUserOperationsIDs.ImportMOSItem
)
if (!supportsDrop) return

this.setState({
dropActive: true,
})
}

onDragLeave = () => {

Check failure on line 648 in packages/webui/src/client/ui/SegmentTimeline/Parts/SegmentTimelinePart.tsx

View workflow job for this annotation

GitHub Actions / Lint Package (webui)

Missing return type on function

Check failure on line 648 in packages/webui/src/client/ui/SegmentTimeline/Parts/SegmentTimelinePart.tsx

View workflow job for this annotation

GitHub Actions / Lint Package (webui)

Missing return type on function
this.setState({
dropActive: false,
})
}

render(): JSX.Element | null {
// optimize early, if not inside viewport
if (!this.state.isInsideViewport) {
Expand Down Expand Up @@ -681,6 +710,8 @@
'outside-quickloop': isOutsideActiveQuickLoop,
'quickloop-start': isQuickLoopStart,
'quickloop-end': isQuickLoopEnd,

'drop-active': this.state.dropActive,
},
this.props.className
)}
Expand All @@ -690,6 +721,7 @@
role="region"
aria-roledescription={t('part')}
aria-label={this.props.part.instance.part.title}
data-part-id={this.props.part.partId}
>
{DEBUG_MODE && (
<div className="segment-timeline__debug-info">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1248,7 +1248,7 @@ function HeaderEditStates({ userEditOperations }: HeaderEditStatesProps) {
<div className="segment-timeline__title__user-edit-states">
{userEditOperations &&
userEditOperations.map((operation) => {
if (operation.type === UserEditingType.FORM || !operation.svgIcon || !operation.isActive) return null
if (operation.type !== UserEditingType.ACTION || !operation.svgIcon || !operation.isActive) return null

return (
<div
Expand Down
Loading
Loading