Skip to content

Commit 662681e

Browse files
committed
feat: properties panel with refactored data structure.
1 parent 8bdc2cd commit 662681e

File tree

3 files changed

+108
-71
lines changed

3 files changed

+108
-71
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1273,7 +1273,7 @@ function HeaderEditStates({ userEditOperations }: HeaderEditStatesProps) {
12731273
<div className="segment-timeline__title__user-edit-states">
12741274
{userEditOperations &&
12751275
userEditOperations.map((operation) => {
1276-
if (operation.type === UserEditingType.FORM || !operation.svgIcon || !operation.isActive) return null
1276+
if (operation.type !== UserEditingType.ACTION || !operation.svgIcon || !operation.isActive) return null
12771277

12781278
return (
12791279
<div

packages/webui/src/client/ui/SegmentTimeline/SegmentTimelineContainer.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import {
3939
TIMELINE_RIGHT_PADDING,
4040
} from './Constants'
4141
import { UIPartInstances, UIParts } from '../Collections'
42-
import { useSelection } from '../RundownView/SelectedElementsContext'
4342

4443
// Kept for backwards compatibility
4544
export type {

packages/webui/src/client/ui/UserEditOperations/PropertiesPanel.tsx

Lines changed: 107 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@ import { MeteorCall } from '../../lib/meteorApi'
66
import {
77
DefaultUserOperationsTypes,
88
JSONBlobParse,
9+
SourceLayerType,
910
UserEditingButtonType,
10-
UserEditingGroupingType,
11+
UserEditingSourceLayer,
1112
UserEditingType,
1213
} from '@sofie-automation/blueprints-integration'
1314
import { assertNever, clone } from '@sofie-automation/corelib/dist/lib'
1415
import classNames from 'classnames'
1516
import {
17+
CoreUserEditingDefinition,
1618
CoreUserEditingDefinitionAction,
1719
CoreUserEditingDefinitionForm,
20+
CoreUserEditingDefinitionSourceLayerForm,
1821
} from '@sofie-automation/corelib/dist/dataModel/UserEditingDefinitions'
1922
import { useTranslation } from 'react-i18next'
2023
import { useTracker } from '../../lib/ReactMeteorData/ReactMeteorData'
@@ -24,6 +27,7 @@ import { useSelection } from '../RundownView/SelectedElementsContext'
2427
import { DBSegment } from '@sofie-automation/corelib/dist/dataModel/Segment'
2528
import { DBPart } from '@sofie-automation/corelib/dist/dataModel/Part'
2629
import { RundownId } from '@sofie-automation/corelib/dist/dataModel/Ids'
30+
import { SchemaFormInPlace } from '../../lib/forms/SchemaFormInPlace'
2731

2832
interface PendingChange {
2933
operationId: string
@@ -116,7 +120,8 @@ export function PropertiesPanel(): JSX.Element {
116120
<div className="propertiespanel-pop-up__header">
117121
{part?.userEditOperations &&
118122
part.userEditOperations.map((operation) => {
119-
if (operation.type === UserEditingType.FORM || !operation.svgIcon || !operation.isActive) return null
123+
if (operation.type !== UserEditingType.ACTION || !operation.svgIcon || !operation.isActive)
124+
return null
120125
return (
121126
<div
122127
key={operation.id}
@@ -148,7 +153,19 @@ export function PropertiesPanel(): JSX.Element {
148153
)
149154
case UserEditingType.FORM:
150155
return (
151-
<EditingTypeChangeSource
156+
<EditingTypeChangeForm
157+
key={i}
158+
userEditOperation={userEditOperation}
159+
segment={segment}
160+
part={part}
161+
rundownId={rundownId}
162+
pendingChanges={pendingChanges}
163+
setPendingChanges={setPendingChanges}
164+
/>
165+
)
166+
case UserEditingType.SOURCE_LAYER_FORM:
167+
return (
168+
<EditingTypeChangeSourceLayerSource
152169
key={i}
153170
userEditOperation={userEditOperation}
154171
segment={segment}
@@ -172,7 +189,8 @@ export function PropertiesPanel(): JSX.Element {
172189
<div className="propertiespanel-pop-up__header">
173190
{segment?.userEditOperations &&
174191
segment.userEditOperations.map((operation) => {
175-
if (operation.type === UserEditingType.FORM || !operation.svgIcon || !operation.isActive) return null
192+
if (operation.type !== UserEditingType.ACTION || !operation.svgIcon || !operation.isActive)
193+
return null
176194

177195
return (
178196
<div
@@ -205,7 +223,19 @@ export function PropertiesPanel(): JSX.Element {
205223
)
206224
case UserEditingType.FORM:
207225
return (
208-
<EditingTypeChangeSource
226+
<EditingTypeChangeForm
227+
key={i}
228+
userEditOperation={userEditOperation}
229+
segment={segment}
230+
part={part}
231+
rundownId={rundownId}
232+
pendingChanges={pendingChanges}
233+
setPendingChanges={setPendingChanges}
234+
/>
235+
)
236+
case UserEditingType.SOURCE_LAYER_FORM:
237+
return (
238+
<EditingTypeChangeSourceLayerSource
209239
key={i}
210240
userEditOperation={userEditOperation}
211241
segment={segment}
@@ -328,7 +358,7 @@ function EditingTypeAction(props: {
328358
}
329359
}
330360

331-
function EditingTypeChangeSource(props: {
361+
function EditingTypeChangeForm(props: {
332362
userEditOperation: CoreUserEditingDefinitionForm
333363
segment: DBSegment | undefined
334364
part: DBPart | undefined
@@ -337,27 +367,58 @@ function EditingTypeChangeSource(props: {
337367
setPendingChanges: React.Dispatch<React.SetStateAction<PendingChange[]>>
338368
}) {
339369
const { t } = useTranslation()
370+
371+
const jsonSchema = props.userEditOperation.schema
372+
const schema = jsonSchema ? JSONBlobParse(jsonSchema) : undefined
373+
const values = clone(props.userEditOperation.currentValues)
374+
375+
return (
376+
<>
377+
{schema && (
378+
<>
379+
<a className="propertiespanel-pop-up__label">{t('Source')}:</a>
380+
<SchemaFormInPlace
381+
schema={schema}
382+
object={values}
383+
translationNamespaces={props.userEditOperation.translationNamespaces}
384+
/>
385+
<br />
386+
<hr />
387+
</>
388+
)}
389+
</>
390+
)
391+
}
392+
393+
function EditingTypeChangeSourceLayerSource(props: {
394+
userEditOperation: CoreUserEditingDefinitionSourceLayerForm
395+
segment: DBSegment | undefined
396+
part: DBPart | undefined
397+
rundownId: RundownId
398+
pendingChanges: PendingChange[]
399+
setPendingChanges: React.Dispatch<React.SetStateAction<PendingChange[]>>
400+
}) {
401+
const { t } = useTranslation()
340402
const [selectedSource, setSelectedSource] = React.useState<Record<string, string>>(
341-
clone(props.userEditOperation.currentValues)
403+
clone(props.userEditOperation.currentValues.value)
404+
)
405+
const [selectedSourceGroup, setSelectedSourceGroup] = React.useState<SourceLayerType>(
406+
props.userEditOperation.currentValues.type
342407
)
343-
const [selectedGroup, setSelectedGroup] = React.useState<string | undefined>(Object.keys(selectedSource)[0])
344408

345-
const jsonSchema = props.userEditOperation.schemas[selectedGroup || '']
409+
const sourceLayer = Object.values<UserEditingSourceLayer>(props.userEditOperation.schemas).find(
410+
(layer) => layer.sourceLayerType === selectedSourceGroup
411+
)
412+
const jsonSchema = sourceLayer?.schema
346413
const schema = jsonSchema ? JSONBlobParse(jsonSchema) : undefined
347-
const sourceList = (schema?.properties ? schema?.properties[selectedGroup ?? ''] : []) as {
348-
enum: string[]
349-
tsEnumNames: string[]
350-
}
351-
const groups: UserEditingGroupingType[] = clone(props.userEditOperation.grouping) || []
352-
const numberOfEmptySlots = 14 - groups.length
353-
for (let i = 0; i < numberOfEmptySlots; i++) {
354-
groups.push({})
355-
}
414+
const values = clone(props.userEditOperation.currentValues)
415+
416+
const groups = clone(props.userEditOperation.schemas) || {}
356417

357418
const handleSourceChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
358419
const newValue = e.target.value
359-
if (selectedGroup) {
360-
const newSelectedSource = { [selectedGroup]: newValue }
420+
if (selectedSourceGroup) {
421+
const newSelectedSource = { [selectedSourceGroup]: newValue }
361422
setSelectedSource(newSelectedSource)
362423

363424
// Add to pending changes instead of executing immediately
@@ -380,58 +441,35 @@ function EditingTypeChangeSource(props: {
380441
return (
381442
<>
382443
<div className="propertiespanel-pop-up__groupselector">
383-
{props.userEditOperation.grouping &&
384-
groups.map((group, index) => {
385-
return !group.svgIcon ? (
386-
<button
387-
className={
388-
selectedGroup !== group.filter
389-
? `propertiespanel-pop-up__groupselector__button`
390-
: `propertiespanel-pop-up__groupselector__button-active`
391-
}
392-
style={{ backgroundColor: group.color }}
393-
key={index}
394-
onClick={() => {
395-
setSelectedGroup(group.filter)
396-
}}
397-
disabled={!group.filter}
398-
>
399-
<div
400-
className="svg"
401-
dangerouslySetInnerHTML={{
402-
__html: group.svgIcon || '',
403-
}}
404-
></div>
405-
{!group.svgIcon && group.label}
406-
</button>
407-
) : (
408-
<button
409-
className={
410-
selectedGroup !== group.filter
411-
? `propertiespanel-pop-up__groupselector__button-svg`
412-
: `propertiespanel-pop-up__groupselector__button-svg-active`
413-
}
414-
key={index}
415-
onClick={() => {
416-
setSelectedGroup(group.filter)
417-
}}
418-
disabled={!group.filter}
419-
>
420-
<div
421-
className="svg-icon"
422-
dangerouslySetInnerHTML={{
423-
__html: group.svgIcon,
424-
}}
425-
></div>
426-
</button>
427-
)
428-
})}
444+
{Object.values<UserEditingSourceLayer>(groups).map((group, index) => {
445+
return (
446+
<button
447+
className={
448+
selectedSourceGroup !== group.sourceLayerType
449+
? `propertiespanel-pop-up__groupselector__button`
450+
: `propertiespanel-pop-up__groupselector__button-active`
451+
}
452+
style={{ backgroundColor: 'blue' }}
453+
key={index}
454+
onClick={() => {
455+
setSelectedSourceGroup(group.sourceLayerType)
456+
}}
457+
>
458+
{group.sourceLayerLabel}
459+
</button>
460+
)
461+
})}
429462
</div>
430-
{selectedGroup && schema && (
463+
{schema && (
431464
<>
432465
<a className="propertiespanel-pop-up__label">{t('Source')}:</a>
466+
<SchemaFormInPlace
467+
schema={schema}
468+
object={values}
469+
translationNamespaces={props.userEditOperation.translationNamespaces}
470+
/>
433471
<br />
434-
<select
472+
{/* <select
435473
title="Sources in the selected group"
436474
className="propertiespanel-pop-up__select"
437475
value={selectedSource[selectedGroup] || ''}
@@ -442,7 +480,7 @@ function EditingTypeChangeSource(props: {
442480
{sourceList.tsEnumNames[index]}
443481
</option>
444482
))}
445-
</select>
483+
</select> */}
446484
<hr />
447485
</>
448486
)}

0 commit comments

Comments
 (0)