Skip to content

Commit 7a45d83

Browse files
committed
Merge remote-tracking branch 'origin/feat/segment-event-identifier' into bbc-main-autonext
2 parents 737a6eb + 3aa0091 commit 7a45d83

19 files changed

Lines changed: 366 additions & 272 deletions

File tree

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ export interface IBlueprintMutatablePart<TPrivateData = unknown, TPublicData = u
9898
/** User-facing identifier that can be used by the User to identify the contents of a segment in the Rundown source system */
9999
identifier?: string
100100

101+
/** User-facing notes shown in the segment header */
102+
segmentHeaderNotes?: ITranslatableMessage[]
103+
101104
/** MediaObjects that when created/updated, should cause the blueprint to be rerun for the Segment of this Part */
102105
hackListenToMediaObjectUpdates?: HackPartMediaObjectSubscription[]
103106

packages/job-worker/src/blueprints/context/lib.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import {
5454
IOutputLayer,
5555
ISourceLayer,
5656
NoteSeverity,
57+
ITranslatableMessage,
5758
PieceAbSessionInfo,
5859
RundownPlaylistTiming,
5960
} from '@sofie-automation/blueprints-integration'
@@ -146,6 +147,7 @@ export const PlayoutMutatablePartSampleKeys = allKeysOfObject<PlayoutMutatablePa
146147
displayDurationGroup: true,
147148
displayDuration: true,
148149
identifier: true,
150+
segmentHeaderNotes: true,
149151
hackListenToMediaObjectUpdates: true,
150152
userEditOperations: true,
151153
userEditProperties: true,
@@ -336,6 +338,7 @@ export function convertPartToBlueprints(part: ReadonlyDeep<DBPart>): IBlueprintP
336338
displayDurationGroup: part.displayDurationGroup,
337339
displayDuration: part.displayDuration,
338340
identifier: part.identifier,
341+
segmentHeaderNotes: clone<ITranslatableMessage[] | undefined>(part.segmentHeaderNotes),
339342
hackListenToMediaObjectUpdates: clone<HackPartMediaObjectSubscription[] | undefined>(
340343
part.hackListenToMediaObjectUpdates
341344
),
@@ -736,7 +739,13 @@ export function convertPartialBlueprintMutablePartToCore(
736739
blueprintId,
737740
])
738741
} else {
739-
delete playoutUpdatePart.userEditOperations
742+
delete playoutUpdatePart.userEditProperties
743+
}
744+
745+
if ('segmentHeaderNotes' in updatePart) {
746+
playoutUpdatePart.segmentHeaderNotes = updatePart.segmentHeaderNotes?.map((note) =>
747+
wrapTranslatableMessageFromBlueprints(note, [blueprintId])
748+
)
740749
}
741750

742751
return playoutUpdatePart

packages/job-worker/src/ingest/generationSegment.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,9 @@ function updateModelWithGeneratedPart(
405405
]),
406406
}
407407
: undefined,
408+
segmentHeaderNotes: blueprintPart.part.segmentHeaderNotes?.map((note) =>
409+
wrapTranslatableMessageFromBlueprints(note, [blueprintId])
410+
),
408411
userEditOperations: translateUserEditsFromBlueprint(blueprintPart.part.userEditOperations, [blueprintId]),
409412
userEditProperties: translateUserEditPropertiesFromBlueprint(blueprintPart.part.userEditProperties, [
410413
blueprintId,

packages/webui/src/client/styles/_colorScheme.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ $general-timecode-color: var(--general-timecode-color);
3232
$part-identifier: var(--part-identifier);
3333
$part-identifier-text: var(--part-identifier-text);
3434

35+
$segment-header-note-identifier: var(--segment-header-note-identifier);
36+
$segment-header-note-identifier-text: var(--segment-header-note-identifier-text);
37+
3538
$ui-button-primary: var(--ui-button-primary);
3639
$ui-button-primary--hover: var(--ui-button-primary--hover);
3740
$ui-button-primary--translucent: var(--ui-button-primary--translucent);

packages/webui/src/client/styles/defaultColors.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232

3333
--part-identifier: #363636;
3434
--part-identifier-text: #eee;
35+
36+
--segment-header-note-identifier: #363636;
37+
--segment-header-note-identifier-text: #fff;
38+
3539
--general-timecode-color: #ffff00;
3640

3741
--ui-button-primary: #1769ff;

packages/webui/src/client/styles/rundownView.scss

Lines changed: 97 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -284,9 +284,8 @@ svg.icon {
284284
}
285285

286286
.segment-timeline__title {
287-
display: grid;
288-
grid-template-columns: auto;
289-
grid-template-rows: [title-title] min-content [title-notifications] 1fr [title-identifiers] min-content [end];
287+
display: flex;
288+
flex-direction: column;
290289

291290
margin: 0;
292291
padding: 0;
@@ -307,6 +306,12 @@ svg.icon {
307306
grid-row: title / timeline-header;
308307
}
309308

309+
.segment-timeline__title__content {
310+
display: flex;
311+
flex-direction: column;
312+
flex-grow: 1;
313+
}
314+
310315
h2 {
311316
margin: 0;
312317
padding: 0.2em;
@@ -316,7 +321,6 @@ svg.icon {
316321
hyphens: auto;
317322
-webkit-hyphens: auto;
318323
-ms-hyphens: auto;
319-
grid-row: title-title / title-notifications;
320324
}
321325

322326
.segment-timeline__title__notes {
@@ -325,27 +329,79 @@ svg.icon {
325329
line-height: 1.4em;
326330
font-size: 0.75em;
327331
font-weight: 400;
328-
grid-row: title-notifications / title-identifiers;
329332
}
330333

331334
.segment-timeline__part-identifiers {
332-
grid-row: title-identifiers / end;
335+
margin-top: auto;
333336

334337
.segment-timeline__part-identifiers__identifier {
335-
font-weight: 300;
336-
text-shadow: none;
337-
margin: 2.5px;
338-
padding: 1px 4px;
338+
// The pill-shaped labels that appear in the segment header, showing and linking to the part name or number
339+
margin: 0.1rem;
340+
padding: 0.1rem 0.35rem 0.1rem 0.35rem;
339341
background-color: $part-identifier;
340342
color: $part-identifier-text;
341-
border-radius: 10px;
342-
font-size: 0.85rem;
343+
border-radius: 99px;
344+
font-family: 'Roboto Flex', 'Roboto', sans-serif;
345+
font-style: normal;
346+
font-size: 0.9rem;
347+
letter-spacing: 0.03em;
348+
line-height: 100%;
349+
text-shadow: none;
350+
font-variant-numeric: proportional-nums;
351+
font-variation-settings:
352+
'wdth' 90,
353+
'wght' 500,
354+
'opsz' 120,
355+
'slnt' 0,
356+
'GRAD' 0,
357+
'XOPQ' 96,
358+
'XTRA' 468,
359+
'YOPQ' 79,
360+
'YTAS' 750,
361+
'YTDE' -203,
362+
'YTFI' 738,
363+
'YTLC' 514,
364+
'YTUC' 712;
343365

344366
&:hover {
345-
background-color: #8c8c8c;
367+
background-color: #6f6f6f;
346368
color: #fff;
347-
}
348-
}
369+
font-weight: 700;
370+
box-shadow: 0px 0px 4px 0px #fff;
371+
}
372+
}
373+
}
374+
.segment-timeline__segment-header-note-identifier {
375+
// The pill-shaped labels that appear in the segment header, showing extra information about the segment.
376+
align-self: flex-start;
377+
display: inline-block;
378+
margin-top: auto;
379+
margin: 0.25rem;
380+
padding: 0.1rem 0.35rem 0.1rem 0.35rem;
381+
background-color: $segment-header-note-identifier;
382+
color: $segment-header-note-identifier-text;
383+
border-radius: 99px;
384+
font-family: 'Roboto Flex', 'Roboto', sans-serif;
385+
font-style: normal;
386+
font-size: 0.9rem;
387+
letter-spacing: 0.03em;
388+
line-height: 100%;
389+
text-shadow: none;
390+
font-variant-numeric: proportional-nums;
391+
font-variation-settings:
392+
'wdth' 70,
393+
'wght' 500,
394+
'opsz' 120,
395+
'slnt' 0,
396+
'GRAD' 0,
397+
'XOPQ' 96,
398+
'XTRA' 468,
399+
'YOPQ' 79,
400+
'YTAS' 750,
401+
'YTDE' -203,
402+
'YTFI' 738,
403+
'YTLC' 514,
404+
'YTUC' 712;
349405
}
350406
}
351407

@@ -2300,13 +2356,36 @@ svg.icon {
23002356
}
23012357

23022358
.segment-timeline__identifier {
2359+
// The Parts identifier label on the right side of the part, showing the Part name or number
23032360
z-index: -1;
2304-
padding: 0 4px 0 10px;
2361+
padding: 0.1rem 0.35rem 0.1rem 0.6rem;
23052362
box-sizing: border-box;
2363+
border-radius: 0 99px 99px 0;
2364+
margin: 0rem;
2365+
23062366
background-color: $part-identifier;
2307-
border-radius: 0 8px 8px 0;
23082367
color: $part-identifier-text;
2309-
font-size: 0.85rem;
2368+
font-family: 'Roboto Flex', 'Roboto', sans-serif;
2369+
font-style: normal;
2370+
font-size: 0.9rem;
2371+
letter-spacing: 0.03em;
2372+
line-height: 100%;
2373+
text-shadow: none;
2374+
font-variant-numeric: proportional-nums;
2375+
font-variation-settings:
2376+
'wdth' 90,
2377+
'wght' 500,
2378+
'opsz' 120,
2379+
'slnt' 0,
2380+
'GRAD' 0,
2381+
'XOPQ' 96,
2382+
'XTRA' 468,
2383+
'YOPQ' 79,
2384+
'YTAS' 750,
2385+
'YTDE' -203,
2386+
'YTFI' 738,
2387+
'YTLC' 514,
2388+
'YTUC' 712;
23102389
}
23112390

23122391
&.gap {

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

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
22
import { NoteSeverity } from '@sofie-automation/blueprints-integration'
33
import type { IContextMenuContext } from '../RundownView.js'
4-
import type { IOutputLayerUi, PartUi, SegmentNoteCounts, SegmentUi } from '../SegmentContainer/withResolvedSegment.js'
4+
import type { IOutputLayerUi, PartUi, SegmentUi } from '../SegmentContainer/withResolvedSegment.js'
55
import { ContextMenuTrigger } from '@jstarpl/react-contextmenu'
6-
import { CriticalIconSmall, WarningIconSmall } from '../../lib/ui/icons/notifications.js'
76
import { contextMenuHoldToDisplayTime, useCombinedRefs, useRundownViewEventBusListener } from '../../lib/lib.js'
87
import { useTranslation } from 'react-i18next'
98
import { literal } from '@sofie-automation/corelib/dist/lib'
@@ -31,6 +30,7 @@ import type { UIStudio } from '@sofie-automation/corelib/src/dataModel/Studio.js
3130
import type { PieceUi } from '@sofie-automation/corelib/src/dataModel/Piece.js'
3231
import { isLoopRunning } from '@sofie-automation/corelib/src/playout/stateCacheResolver.js'
3332
import { HOVER_TIMEOUT } from '../Shelf/DashboardPieceButton/types.js'
33+
import { SegmentHeaderNotes } from '../SegmentHeader/SegmentHeaderNotes.js'
3434

3535
interface IProps {
3636
id: string
@@ -39,7 +39,6 @@ interface IProps {
3939
playlist: DBRundownPlaylist
4040
studio: UIStudio
4141
parts: Array<PartUi>
42-
segmentNoteCounts: SegmentNoteCounts
4342
hasAlreadyPlayed: boolean
4443
hasGuestItems: boolean
4544
hasRemoteItems: boolean
@@ -82,9 +81,6 @@ export const SegmentAdlibTesting = React.memo(
8281
const [squishedHover, setSquishedHover] = useState<null | number>(null)
8382
const squishedHoverTimeout = useRef<number | null>(null)
8483

85-
const criticalNotes = props.segmentNoteCounts.criticial
86-
const warningNotes = props.segmentNoteCounts.warning
87-
8884
const getSegmentContext = () => {
8985
const ctx = literal<IContextMenuContext>({
9086
segment: props.segment,
@@ -466,30 +462,7 @@ export const SegmentAdlibTesting = React.memo(
466462
>
467463
{t('Adlib Testing')}
468464
</h2>
469-
{(criticalNotes > 0 || warningNotes > 0) && (
470-
<div className="segment-timeline__title__notes">
471-
{criticalNotes > 0 && (
472-
<div
473-
className="segment-timeline__title__notes__note segment-timeline__title__notes__note--critical"
474-
onClick={() => props.onHeaderNoteClick?.(props.segment._id, NoteSeverity.ERROR)}
475-
aria-label={t('Critical problems')}
476-
>
477-
<CriticalIconSmall />
478-
<div className="segment-timeline__title__notes__count">{criticalNotes}</div>
479-
</div>
480-
)}
481-
{warningNotes > 0 && (
482-
<div
483-
className="segment-timeline__title__notes__note segment-timeline__title__notes__note--warning"
484-
onClick={() => props.onHeaderNoteClick?.(props.segment._id, NoteSeverity.WARNING)}
485-
aria-label={t('Warnings')}
486-
>
487-
<WarningIconSmall />
488-
<div className="segment-timeline__title__notes__count">{warningNotes}</div>
489-
</div>
490-
)}
491-
</div>
492-
)}
465+
<SegmentHeaderNotes segmentId={props.segment._id} onHeaderNoteClick={props.onHeaderNoteClick} />
493466
</ContextMenuTrigger>
494467
<div className="segment-timeline__source-layers" role="tree" aria-label={t('Sources')}>
495468
{Object.values<IOutputLayerUi>(props.segment.outputLayers)

packages/webui/src/client/ui/SegmentAdlibTesting/SegmentAdlibTestingContainer.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ export const SegmentAdlibTestingContainer = withResolvedSegment<IProps>(function
209209
segment={props.segmentui}
210210
studio={props.studio}
211211
parts={props.parts}
212-
segmentNoteCounts={props.segmentNoteCounts}
213212
onItemClick={props.onPieceClick}
214213
onItemDoubleClick={props.onPieceDoubleClick}
215214
playlist={props.playlist}

0 commit comments

Comments
 (0)