Skip to content
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
3 changes: 3 additions & 0 deletions packages/blueprints-integration/src/documents/part.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ export interface IBlueprintMutatablePart<TPrivateData = unknown, TPublicData = u
/** User-facing identifier that can be used by the User to identify the contents of a segment in the Rundown source system */
identifier?: string

/** User-facing notes shown in the segment header */
segmentHeaderNotes?: ITranslatableMessage[]

/** MediaObjects that when created/updated, should cause the blueprint to be rerun for the Segment of this Part */
hackListenToMediaObjectUpdates?: HackPartMediaObjectSubscription[]

Expand Down
11 changes: 10 additions & 1 deletion packages/job-worker/src/blueprints/context/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import {
IBlueprintShowStyleVariant,
IOutputLayer,
ISourceLayer,
ITranslatableMessage,
PieceAbSessionInfo,
RundownPlaylistTiming,
} from '@sofie-automation/blueprints-integration'
Expand Down Expand Up @@ -138,6 +139,7 @@ export const PlayoutMutatablePartSampleKeys = allKeysOfObject<PlayoutMutatablePa
displayDurationGroup: true,
displayDuration: true,
identifier: true,
segmentHeaderNotes: true,
hackListenToMediaObjectUpdates: true,
userEditOperations: true,
userEditProperties: true,
Expand Down Expand Up @@ -326,6 +328,7 @@ export function convertPartToBlueprints(part: ReadonlyDeep<DBPart>): IBlueprintP
displayDurationGroup: part.displayDurationGroup,
displayDuration: part.displayDuration,
identifier: part.identifier,
segmentHeaderNotes: clone<ITranslatableMessage[] | undefined>(part.segmentHeaderNotes),
hackListenToMediaObjectUpdates: clone<HackPartMediaObjectSubscription[] | undefined>(
part.hackListenToMediaObjectUpdates
),
Expand Down Expand Up @@ -705,7 +708,13 @@ export function convertPartialBlueprintMutablePartToCore(
blueprintId,
])
} else {
delete playoutUpdatePart.userEditOperations
delete playoutUpdatePart.userEditProperties
}

if ('segmentHeaderNotes' in updatePart) {
playoutUpdatePart.segmentHeaderNotes = updatePart.segmentHeaderNotes?.map((note) =>
wrapTranslatableMessageFromBlueprints(note, [blueprintId])
)
}

return playoutUpdatePart
Expand Down
3 changes: 3 additions & 0 deletions packages/job-worker/src/ingest/generationSegment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,9 @@ function updateModelWithGeneratedPart(
]),
}
: undefined,
segmentHeaderNotes: blueprintPart.part.segmentHeaderNotes?.map((note) =>
wrapTranslatableMessageFromBlueprints(note, [blueprintId])
),
userEditOperations: translateUserEditsFromBlueprint(blueprintPart.part.userEditOperations, [blueprintId]),
userEditProperties: translateUserEditPropertiesFromBlueprint(blueprintPart.part.userEditProperties, [
blueprintId,
Expand Down
3 changes: 3 additions & 0 deletions packages/webui/src/client/styles/_colorScheme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ $general-timecode-color: var(--general-timecode-color);
$part-identifier: var(--part-identifier);
$part-identifier-text: var(--part-identifier-text);

$segment-event-identifier: var(--segment-event-identifier);
$segment-event-identifier-text: var(--segment-event-identifier-text);

$ui-button-primary: var(--ui-button-primary);
$ui-button-primary--hover: var(--ui-button-primary--hover);
$ui-button-primary--translucent: var(--ui-button-primary--translucent);
Expand Down
4 changes: 4 additions & 0 deletions packages/webui/src/client/styles/defaultColors.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@

--part-identifier: #363636;
--part-identifier-text: #eee;

--segment-event-identifier: #363636;
--segment-event-identifier-text: #fff;

--general-timecode-color: #ffff00;

--ui-button-primary: #1769ff;
Expand Down
115 changes: 97 additions & 18 deletions packages/webui/src/client/styles/rundownView.scss
Original file line number Diff line number Diff line change
Expand Up @@ -539,9 +539,8 @@ svg.icon {
}

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

margin: 0;
padding: 0;
Expand All @@ -562,6 +561,12 @@ svg.icon {
grid-row: title / timeline-header;
}

.segment-timeline__title__content {
display: flex;
flex-direction: column;
flex-grow: 1;
}

h2 {
margin: 0;
padding: 0.2em;
Expand All @@ -571,7 +576,6 @@ svg.icon {
hyphens: auto;
-webkit-hyphens: auto;
-ms-hyphens: auto;
grid-row: title-title / title-notifications;
}

.segment-timeline__title__notes {
Expand All @@ -580,27 +584,79 @@ svg.icon {
line-height: 1.4em;
font-size: 0.75em;
font-weight: 400;
grid-row: title-notifications / title-identifiers;
}

.segment-timeline__part-identifiers {
grid-row: title-identifiers / end;
margin-top: auto;

.segment-timeline__part-identifiers__identifier {
font-weight: 300;
text-shadow: none;
margin: 2.5px;
padding: 1px 4px;
// The pill-shaped labels that appear in the segment header, showing and linking to the part name or number
margin: 0.1rem;
padding: 0.1rem 0.35rem 0.1rem 0.35rem;
background-color: $part-identifier;
color: $part-identifier-text;
border-radius: 10px;
font-size: 0.85rem;
border-radius: 99px;
font-family: "Roboto Flex", "Roboto", sans-serif;
font-style: normal;
font-size: 0.9rem;
letter-spacing: 0.03em;
line-height: 100%;
text-shadow: none;
font-variant-numeric: proportional-nums;
font-variation-settings:
'wdth' 90,
'wght' 500,
'opsz' 120,
'slnt' 0,
'GRAD' 0,
'XOPQ' 96,
'XTRA' 468,
'YOPQ' 79,
'YTAS' 750,
'YTDE' -203,
'YTFI' 738,
'YTLC' 514,
'YTUC' 712;

&:hover {
background-color: #8c8c8c;
background-color: #6f6f6f;
color: #fff;
}
}
font-weight: 700;
box-shadow: 0px 0px 4px 0px #fff;
}
}
}
.segment-timeline__segment-event-identifier{
// The pill-shaped labels that appear in the segment header, showing extra information about the segment.
align-self: flex-start;
display: inline-block;
margin-top: auto;
margin: 0.25rem;
padding: 0.1rem 0.35rem 0.1rem 0.35rem;
background-color: $segment-event-identifier;
color: $segment-event-identifier-text;
border-radius: 99px;
font-family: "Roboto Flex", "Roboto", sans-serif;
font-style: normal;
font-size: 0.9rem;
letter-spacing: 0.03em;
line-height: 100%;
text-shadow: none;
font-variant-numeric: proportional-nums;
font-variation-settings:
'wdth' 70,
'wght' 500,
'opsz' 120,
'slnt' 0,
'GRAD' 0,
'XOPQ' 96,
'XTRA' 468,
'YOPQ' 79,
'YTAS' 750,
'YTDE' -203,
'YTFI' 738,
'YTLC' 514,
'YTUC' 712;
}
}

Expand Down Expand Up @@ -2491,13 +2547,36 @@ svg.icon {
}

.segment-timeline__identifier {
// The Parts identifier label on the right side of the part, showing the Part name or number
z-index: -1;
padding: 0 4px 0 10px;
padding: 0.1rem 0.35rem 0.1rem 0.6rem;
box-sizing: border-box;
border-radius: 0 99px 99px 0;
margin: 0rem;

background-color: $part-identifier;
border-radius: 0 8px 8px 0;
color: $part-identifier-text;
font-size: 0.85rem;
font-family: "Roboto Flex", "Roboto", sans-serif;
font-style: normal;
font-size: 0.9rem;
letter-spacing: 0.03em;
line-height: 100%;
text-shadow: none;
font-variant-numeric: proportional-nums;
font-variation-settings:
'wdth' 90,
'wght' 500,
'opsz' 120,
'slnt' 0,
'GRAD' 0,
'XOPQ' 96,
'XTRA' 468,
'YOPQ' 79,
'YTAS' 750,
'YTDE' -203,
'YTFI' 738,
'YTLC' 514,
'YTUC' 712;
}

&.gap {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
import { NoteSeverity } from '@sofie-automation/blueprints-integration'
import { IContextMenuContext } from '../RundownView.js'
import {
IOutputLayerUi,
PartUi,
PieceUi,
SegmentNoteCounts,
SegmentUi,
} from '../SegmentContainer/withResolvedSegment.js'
import { IOutputLayerUi, PartUi, PieceUi, SegmentUi } from '../SegmentContainer/withResolvedSegment.js'
import { ContextMenuTrigger } from '@jstarpl/react-contextmenu'
import { CriticalIconSmall, WarningIconSmall } from '../../lib/ui/icons/notifications.js'
import { contextMenuHoldToDisplayTime, useCombinedRefs, useRundownViewEventBusListener } from '../../lib/lib.js'
import { useTranslation } from 'react-i18next'
import { literal } from '@sofie-automation/corelib/dist/lib'
Expand All @@ -33,6 +26,7 @@ import { SegmentId } from '@sofie-automation/corelib/dist/dataModel/Ids'
import { DBRundownPlaylist, RundownHoldState } from '@sofie-automation/corelib/dist/dataModel/RundownPlaylist'
import { isPartPlayable } from '@sofie-automation/corelib/dist/dataModel/Part'
import { isLoopRunning } from '../../lib/RundownResolver.js'
import { SegmentHeaderNotes } from '../SegmentHeader/SegmentHeaderNotes.js'

interface IProps {
id: string
Expand All @@ -41,7 +35,6 @@ interface IProps {
playlist: DBRundownPlaylist
studio: UIStudio
parts: Array<PartUi>
segmentNoteCounts: SegmentNoteCounts
hasAlreadyPlayed: boolean
hasGuestItems: boolean
hasRemoteItems: boolean
Expand Down Expand Up @@ -84,9 +77,6 @@ export const SegmentAdlibTesting = React.memo(
const [squishedHover, setSquishedHover] = useState<null | number>(null)
const squishedHoverTimeout = useRef<number | null>(null)

const criticalNotes = props.segmentNoteCounts.criticial
const warningNotes = props.segmentNoteCounts.warning

const getSegmentContext = () => {
const ctx = literal<IContextMenuContext>({
segment: props.segment,
Expand Down Expand Up @@ -465,30 +455,7 @@ export const SegmentAdlibTesting = React.memo(
>
{t('Adlib Testing')}
</h2>
{(criticalNotes > 0 || warningNotes > 0) && (
<div className="segment-timeline__title__notes">
{criticalNotes > 0 && (
<div
className="segment-timeline__title__notes__note segment-timeline__title__notes__note--critical"
onClick={() => props.onHeaderNoteClick?.(props.segment._id, NoteSeverity.ERROR)}
aria-label={t('Critical problems')}
>
<CriticalIconSmall />
<div className="segment-timeline__title__notes__count">{criticalNotes}</div>
</div>
)}
{warningNotes > 0 && (
<div
className="segment-timeline__title__notes__note segment-timeline__title__notes__note--warning"
onClick={() => props.onHeaderNoteClick?.(props.segment._id, NoteSeverity.WARNING)}
aria-label={t('Warnings')}
>
<WarningIconSmall />
<div className="segment-timeline__title__notes__count">{warningNotes}</div>
</div>
)}
</div>
)}
<SegmentHeaderNotes segmentId={props.segment._id} onHeaderNoteClick={props.onHeaderNoteClick} />
</ContextMenuTrigger>
<div className="segment-timeline__source-layers" role="tree" aria-label={t('Sources')}>
{Object.values<IOutputLayerUi>(props.segment.outputLayers)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ export const SegmentAdlibTestingContainer = withResolvedSegment<IProps>(function
segment={props.segmentui}
studio={props.studio}
parts={props.parts}
segmentNoteCounts={props.segmentNoteCounts}
onItemClick={props.onPieceClick}
onItemDoubleClick={props.onPieceDoubleClick}
playlist={props.playlist}
Expand Down
Loading
Loading