Skip to content

Commit 3222f65

Browse files
committed
wip: useSelection on Parts
1 parent 382179c commit 3222f65

File tree

5 files changed

+63
-59
lines changed

5 files changed

+63
-59
lines changed

packages/webui/src/client/lib/notifications/NotificationCenterPanel.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { RundownId, SegmentId } from '@sofie-automation/corelib/dist/dataModel/I
1414
import { useTranslation } from 'react-i18next'
1515
import { PropertiesPanel } from '../../ui/UserEditOperations/PropertiesPanel'
1616
import { UserEditsIcon } from '../ui/icons/useredits'
17-
import { IContextMenuContext } from '../../ui/RundownView'
1817

1918
interface IPopUpProps {
2019
id?: string
@@ -155,7 +154,6 @@ interface IProps {
155154
limitCount?: number
156155

157156
filter?: NoticeLevel
158-
contextMenuContext: IContextMenuContext | null
159157
}
160158

161159
interface IState {
@@ -398,7 +396,7 @@ export const NotificationCenterPopUps = translateWithTracker<IProps, IState, ITr
398396

399397
// For PropertiesPanel ignore the filter:
400398
if (Number(filter) >= NoticeLevel.PROPERTIES_PANEL) {
401-
return <PropertiesPanel contextMenuContext={this.props.contextMenuContext} />
399+
return <PropertiesPanel />
402400
}
403401

404402
const notifications = this.getNotificationsToDisplay()
@@ -467,18 +465,13 @@ export const NotificationCenterPopUps = translateWithTracker<IProps, IState, ITr
467465
* @class NotificationCenterPanel
468466
* @extends React.Component
469467
*/
470-
export const NotificationCenterPanel = (props: {
471-
limitCount?: number
472-
filter?: NoticeLevel
473-
contextMenuContext: IContextMenuContext | null
474-
}): JSX.Element => (
468+
export const NotificationCenterPanel = (props: { limitCount?: number; filter?: NoticeLevel }): JSX.Element => (
475469
<div className="notification-center-panel">
476470
<NotificationCenterPopUps
477471
showEmptyListLabel={true}
478472
showSnoozed={true}
479473
limitCount={props.limitCount}
480474
filter={props.filter}
481-
contextMenuContext={props.contextMenuContext}
482475
/>
483476
</div>
484477
)

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3043,10 +3043,7 @@ const RundownViewContent = translateWithTracker<IPropsWithReady, IState, ITracke
30433043
}}
30443044
>
30453045
{this.state.isNotificationsCenterOpen && (
3046-
<NotificationCenterPanel
3047-
filter={this.state.isNotificationsCenterOpen}
3048-
contextMenuContext={this.state.contextMenuContext}
3049-
/>
3046+
<NotificationCenterPanel filter={this.state.isNotificationsCenterOpen} />
30503047
)}
30513048
</VelocityReact.VelocityTransitionGroup>
30523049
<VelocityReact.VelocityTransitionGroup

packages/webui/src/client/ui/RundownView/SelectedElementsContext.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ interface AdlibActionElement {
3737
type SelectedElement = RundownElement | SegmentElement | PartInstanceElement | PieceElement | AdlibActionElement
3838
type ElementId = SelectedElement['elementId']
3939

40-
interface SelectionContextType {
40+
export interface SelectionContextType {
4141
isSelected: (elementId: ElementId) => boolean
4242
listSelectedElements: () => SelectedElement[]
4343
clearAndSetSelection: (element: SelectedElement) => void

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import { ISourceLayer } from '@sofie-automation/blueprints-integration'
3636
import { UIStudio } from '@sofie-automation/meteor-lib/dist/api/studios'
3737
import { LIVE_LINE_TIME_PADDING } from '../Constants'
3838
import * as RundownResolver from '../../../lib/RundownResolver'
39+
import { SelectedElementsContext } from '../../RundownView/SelectedElementsContext'
3940

4041
export const SegmentTimelineLineElementId = 'rundown__segment__line__'
4142
export const SegmentTimelinePartElementId = 'rundown__segment__part__'
@@ -51,6 +52,7 @@ interface IProps {
5152
playlist: DBRundownPlaylist
5253
studio: UIStudio
5354
part: PartUi
55+
onPartClick?: (part: PartUi, e: React.MouseEvent<HTMLDivElement>) => void
5456
timeToPixelRatio: number
5557
onCollapseOutputToggle?: (layer: IOutputLayerUi, event: any) => void
5658
collapsedOutputs: {
@@ -101,6 +103,9 @@ interface IState {
101103
highlight: boolean
102104
}
103105
export class SegmentTimelinePartClass extends React.Component<Translated<WithTiming<IProps>>, IState> {
106+
static contextType = SelectedElementsContext
107+
declare context: React.ContextType<typeof SelectedElementsContext>
108+
104109
constructor(props: Readonly<Translated<WithTiming<IProps>>>) {
105110
super(props)
106111

@@ -245,6 +250,19 @@ export class SegmentTimelinePartClass extends React.Component<Translated<WithTim
245250
}
246251
}
247252

253+
private handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
254+
this.props.onPartClick?.(this.props.part, e)
255+
256+
// Only toggle selection if Alt/Option is pressed
257+
if (e.altKey && this.context) {
258+
e.preventDefault()
259+
this.context.clearAndSetSelection({
260+
type: 'partInstance',
261+
elementId: this.props.part.instance._id,
262+
})
263+
}
264+
}
265+
248266
private highlightTimeout: NodeJS.Timer | undefined
249267

250268
private onHighlight = (e: HighlightEvent) => {
@@ -690,6 +708,7 @@ export class SegmentTimelinePartClass extends React.Component<Translated<WithTim
690708
role="region"
691709
aria-roledescription={t('part')}
692710
aria-label={this.props.part.instance.part.title}
711+
onClick={(e) => this.handleClick(e)}
693712
>
694713
{DEBUG_MODE && (
695714
<div className="segment-timeline__debug-info">
@@ -762,6 +781,7 @@ export class SegmentTimelinePartClass extends React.Component<Translated<WithTim
762781
'segment-timeline__part__nextline__label--thin':
763782
(this.props.autoNextPart || this.props.part.willProbablyAutoNext) && !this.state.isNext,
764783
})}
784+
onClick={(e) => this.handleClick(e)}
765785
>
766786
{innerPart.invalid && !innerPart.gap ? null : (
767787
<React.Fragment>

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

Lines changed: 39 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as React from 'react'
22
// @ts-expect-error No types available
33
import * as VelocityReact from 'velocity-react'
44
import { i18nTranslator } from '../i18n'
5-
import { IContextMenuContext } from '../RundownView'
65
import { translateMessage } from '@sofie-automation/corelib/dist/TranslatableMessage'
76
import { doUserAction, UserAction } from '../../lib/clientUserAction'
87
import { MeteorCall } from '../../lib/meteorApi'
@@ -24,20 +23,13 @@ import { useTranslation } from 'react-i18next'
2423
import { useTracker } from '../../lib/ReactMeteorData/ReactMeteorData'
2524
import _ from 'underscore'
2625
import { Segments } from '../../collections'
27-
import { UIParts } from '../Collections'
26+
import { UIPartInstances, UIParts } from '../Collections'
2827
import { useSelection } from '../RundownView/SelectedElementsContext'
28+
import { DBSegment } from '@sofie-automation/corelib/dist/dataModel/Segment'
29+
import { DBPart } from '@sofie-automation/corelib/dist/dataModel/Part'
30+
import { RundownId } from '@sofie-automation/corelib/dist/dataModel/Ids'
2931

30-
/**
31-
* Propertiespanel PopUp props.
32-
*/
33-
interface Props {
34-
// Currently selected context menu context
35-
// Plan is to replace this with a more specific selection of what is selected in the UI
36-
// When selected element for propertiesPanel has been implemented
37-
contextMenuContext: IContextMenuContext | null
38-
}
39-
40-
export function PropertiesPanel(props: Props): JSX.Element {
32+
export function PropertiesPanel(): JSX.Element {
4133
const { listSelectedElements } = useSelection()
4234
console.log('listSelectedElements', listSelectedElements())
4335
const selectedElement = listSelectedElements()?.[0]
@@ -54,14 +46,19 @@ export function PropertiesPanel(props: Props): JSX.Element {
5446
}
5547
}, [])
5648

57-
const rundownId = props.contextMenuContext?.segment?.rundownId
58-
const part = useTracker(() => UIParts.findOne({ _id: selectedElement.elementId }), [selectedElement.elementId])
49+
const partInstance = useTracker(
50+
() => UIPartInstances.findOne({ _id: selectedElement.elementId }),
51+
[selectedElement.elementId]
52+
)
53+
const part = useTracker(() => UIParts.findOne({ _id: partInstance?.part._id }), [partInstance?.part._id])
5954

60-
console.log('Context Segment id', props.contextMenuContext?.segment?._id)
61-
const segment = useTracker(
62-
() => Segments.findOne({ rundownId: rundownId, _id: selectedElement.elementId }),
55+
const segment: DBSegment | undefined = useTracker(
56+
() => Segments.findOne({ _id: part ? part.segmentId : selectedElement.elementId }),
6357
[selectedElement.elementId]
6458
)
59+
const rundownId = part ? part.rundownId : segment?.rundownId
60+
61+
if (!rundownId) return <></>
6562

6663
return (
6764
<div className="propertiespanel-pop-up">
@@ -94,15 +91,19 @@ export function PropertiesPanel(props: Props): JSX.Element {
9491
<EditingTypeAction
9592
key={i}
9693
userEditOperation={userEditOperation}
97-
contextMenuContext={props.contextMenuContext}
94+
segment={segment}
95+
part={part}
96+
rundownId={rundownId}
9897
/>
9998
)
10099
case UserEditingType.FORM:
101100
return (
102101
<EditingTypeChangeSource
103102
key={i}
104103
userEditOperation={userEditOperation}
105-
contextMenuContext={props.contextMenuContext}
104+
segment={segment}
105+
part={part}
106+
rundownId={rundownId}
106107
/>
107108
)
108109
default:
@@ -143,15 +144,19 @@ export function PropertiesPanel(props: Props): JSX.Element {
143144
<EditingTypeAction
144145
key={i}
145146
userEditOperation={userEditOperation}
146-
contextMenuContext={props.contextMenuContext}
147+
segment={segment}
148+
part={part}
149+
rundownId={rundownId}
147150
/>
148151
)
149152
case UserEditingType.FORM:
150153
return (
151154
<EditingTypeChangeSource
152155
key={i}
153156
userEditOperation={userEditOperation}
154-
contextMenuContext={props.contextMenuContext}
157+
segment={segment}
158+
part={part}
159+
rundownId={rundownId}
155160
/>
156161
)
157162
default:
@@ -196,7 +201,9 @@ export function PropertiesPanel(props: Props): JSX.Element {
196201

197202
function EditingTypeAction(props: {
198203
userEditOperation: CoreUserEditingDefinitionAction
199-
contextMenuContext: IContextMenuContext | null
204+
segment: DBSegment | undefined
205+
part: DBPart | undefined
206+
rundownId: RundownId
200207
}) {
201208
if (!props.userEditOperation.buttonType) return null
202209
switch (props.userEditOperation.buttonType) {
@@ -213,8 +220,8 @@ function EditingTypeAction(props: {
213220
//@ts-expect-error TODO: Fix this
214221
props.contextMenuContext?.segment?.rundownId,
215222
{
216-
segmentExternalId: props.contextMenuContext?.segment?.externalId,
217-
partExternalId: props.contextMenuContext?.part?.instance.part.externalId,
223+
segmentExternalId: props.segment?.externalId,
224+
partExternalId: props.part?.externalId,
218225
pieceExternalId: undefined,
219226
},
220227
{
@@ -246,8 +253,8 @@ function EditingTypeAction(props: {
246253
//@ts-expect-error TODO: Fix this
247254
props.contextMenuContext?.segment?.rundownId,
248255
{
249-
segmentExternalId: props.contextMenuContext?.segment?.externalId,
250-
partExternalId: props.contextMenuContext?.part?.instance.part.externalId,
256+
segmentExternalId: props.segment?.externalId,
257+
partExternalId: props.part?.externalId,
251258
pieceExternalId: undefined,
252259
},
253260
{
@@ -282,7 +289,9 @@ function EditingTypeAction(props: {
282289

283290
function EditingTypeChangeSource(props: {
284291
userEditOperation: CoreUserEditingDefinitionForm
285-
contextMenuContext: IContextMenuContext | null
292+
segment: DBSegment | undefined
293+
part: DBPart | undefined
294+
rundownId: RundownId
286295
}) {
287296
const { t } = useTranslation()
288297
const [selectedSource, setSelectedSource] = React.useState<Record<string, string>>(
@@ -371,8 +380,8 @@ function EditingTypeChangeSource(props: {
371380
//@ts-expect-error TODO: Fix this
372381
props.contextMenuContext?.segment?.rundownId,
373382
{
374-
segmentExternalId: props.contextMenuContext?.segment?.externalId,
375-
partExternalId: props.contextMenuContext?.part?.instance.part.externalId,
383+
segmentExternalId: props.segment?.externalId,
384+
partExternalId: props.part?.externalId,
376385
pieceExternalId: undefined,
377386
},
378387
{
@@ -395,18 +404,3 @@ function EditingTypeChangeSource(props: {
395404
</>
396405
)
397406
}
398-
399-
// This is simmilar implementation as the function in SegmentContextMenu.tsx
400-
// and is used to check if a segment or a part is used.
401-
// A better implementation of what is selected in the UI should be implemented.
402-
function getTimePosition(contextMenuContext: IContextMenuContext): number | null {
403-
let offset = 0
404-
if (contextMenuContext && contextMenuContext.partDocumentOffset) {
405-
const left = contextMenuContext.partDocumentOffset.left || 0
406-
const timeScale = contextMenuContext.timeScale || 1
407-
const menuPosition = contextMenuContext.mousePosition || { left }
408-
offset = (menuPosition.left - left) / timeScale
409-
return offset
410-
}
411-
return null
412-
}

0 commit comments

Comments
 (0)