Skip to content

Commit f6089c7

Browse files
authored
Merge pull request #1501 from nrkno/feat/sofie-3979/adLibTriggerIcons
2 parents 518977c + 9214e73 commit f6089c7

File tree

17 files changed

+282
-115
lines changed

17 files changed

+282
-115
lines changed

packages/blueprints-integration/src/action.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ export interface IBlueprintActionTriggerMode {
6464
label: ITranslatableMessage
6565
/** An optional, longer description that will not be immediately visible to the user */
6666
description?: ITranslatableMessage
67+
/** An icon to be displayed to the user next to the label
68+
*
69+
* This can either be a relative URL to an image in the Blueprints assets or a `data:` URL
70+
*/
71+
icon?: string
6772
}
6873
}
6974

packages/blueprints-integration/src/userEditing.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,16 @@ export interface UserEditingDefinitionAction {
2121
id: string
2222
/** Label to show to the user for this operation */
2323
label: ITranslatableMessage
24-
/** Icon to show when this action is 'active' */
25-
svgIcon?: string
26-
/** Icon to show when this action is 'disabled' */
27-
svgIconInactive?: string
24+
/** Icon to show when this action is 'active'
25+
*
26+
* This can either be a relative URL to an image in the Blueprints assets or a `data:` URL
27+
*/
28+
icon?: string
29+
/** Icon to show when this action is 'disabled'
30+
*
31+
* This can either be a relative URL to an image in the Blueprints assets or a `data:` URL
32+
*/
33+
iconInactive?: string
2834
/** Whether this action should be indicated as being active */
2935
isActive?: boolean
3036
}

packages/corelib/src/dataModel/UserEditingDefinitions.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ export interface CoreUserEditingDefinitionAction {
1818
id: string
1919
/** Label to show to the user for this operation */
2020
label: ITranslatableMessage
21-
/** Icon to show when this action is 'active' */
22-
svgIcon?: string
23-
/** Icon to show when this action is 'disabled' */
24-
svgIconInactive?: string
21+
/** Icon to show when this action is 'active'.
22+
*
23+
* This can either be a relative URL to an image in the Blueprints assets or a `data:` URL */
24+
icon?: string
25+
/** Icon to show when this action is 'disabled'.
26+
*
27+
* This can either be a relative URL to an image in the Blueprints assets or a `data:` URL */
28+
iconInactive?: string
2529
/** Whether this action should be indicated as being active */
2630
isActive?: boolean
2731
}

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -522,8 +522,8 @@ function translateUserEditsToBlueprint(
522522
type: UserEditingType.ACTION,
523523
id: userEdit.id,
524524
label: omit(userEdit.label, 'namespaces'),
525-
svgIcon: userEdit.svgIcon,
526-
svgIconInactive: userEdit.svgIconInactive,
525+
icon: userEdit.icon,
526+
iconInactive: userEdit.iconInactive,
527527
isActive: userEdit.isActive,
528528
} satisfies Complete<UserEditingDefinitionAction>
529529
case UserEditingType.FORM:
@@ -562,8 +562,8 @@ function translateUserEditPropertiesToBlueprint(
562562
type: UserEditingType.ACTION,
563563
id: userEdit.id,
564564
label: omit(userEdit.label, 'namespaces'),
565-
svgIcon: userEdit.svgIcon,
566-
svgIconInactive: userEdit.svgIconInactive,
565+
icon: userEdit.icon,
566+
iconInactive: userEdit.iconInactive,
567567
isActive: userEdit.isActive,
568568
}) satisfies Complete<UserEditingDefinitionAction>
569569
),
@@ -584,8 +584,8 @@ export function translateUserEditsFromBlueprint(
584584
type: UserEditingType.ACTION,
585585
id: userEdit.id,
586586
label: wrapTranslatableMessageFromBlueprints(userEdit.label, blueprintIds),
587-
svgIcon: userEdit.svgIcon,
588-
svgIconInactive: userEdit.svgIconInactive,
587+
icon: userEdit.icon,
588+
iconInactive: userEdit.iconInactive,
589589
isActive: userEdit.isActive,
590590
} satisfies Complete<CoreUserEditingDefinitionAction>
591591
case UserEditingType.FORM:
@@ -626,8 +626,8 @@ export function translateUserEditPropertiesFromBlueprint(
626626
type: UserEditingType.ACTION,
627627
id: userEdit.id,
628628
label: wrapTranslatableMessageFromBlueprints(userEdit.label, blueprintIds),
629-
svgIcon: userEdit.svgIcon,
630-
svgIconInactive: userEdit.svgIconInactive,
629+
icon: userEdit.icon,
630+
iconInactive: userEdit.iconInactive,
631631
isActive: userEdit.isActive,
632632
}) satisfies Complete<UserEditingDefinitionAction>
633633
),
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { useEffect, useMemo, useState } from 'react'
2+
import { createPrivateApiPath } from '../../url.js'
3+
4+
const GLOBAL_BLUEPRINT_ASSET_CACHE: Record<string, string> = {}
5+
6+
export function BlueprintAssetIcon({ src, className }: { src: string; className?: string }): JSX.Element | null {
7+
const url = useMemo(() => {
8+
if (src.startsWith('data:')) return new URL(src)
9+
return new URL(createPrivateApiPath('/blueprints/assets/' + src), location.href)
10+
}, [src])
11+
const [svgAsset, setSvgAsset] = useState<string | null>(GLOBAL_BLUEPRINT_ASSET_CACHE[url.href] ?? null)
12+
13+
useEffect(() => {
14+
if (svgAsset) return
15+
if (url.origin !== window.origin && url.origin !== null) {
16+
console.error(`Invalid origin for BlueprintAssetIcon: ${url}`)
17+
return
18+
}
19+
20+
const abort = new AbortController()
21+
22+
fetch(url, {
23+
redirect: 'follow',
24+
referrerPolicy: 'origin',
25+
signal: abort.signal,
26+
})
27+
.then((res) => {
28+
if (res.status !== 200) throw new Error(`Invalid response code: ${url} ${res.status} ${res.statusText}`)
29+
if (!res.headers.get('content-type')?.startsWith('image/svg'))
30+
throw new Error(`Asset is not an SVG image: ${url}`)
31+
32+
return res.text()
33+
})
34+
.then((body) => {
35+
GLOBAL_BLUEPRINT_ASSET_CACHE[url.href] = body
36+
if (abort.signal.aborted) return
37+
setSvgAsset(body)
38+
})
39+
.catch((err) => {
40+
console.error(err)
41+
setSvgAsset(null)
42+
})
43+
44+
return () => {
45+
abort.abort()
46+
}
47+
}, [url, svgAsset])
48+
49+
const dangerouslySetInnerHTML = useMemo(() => {
50+
if (!svgAsset) return undefined
51+
52+
return {
53+
__html: svgAsset,
54+
}
55+
}, [svgAsset])
56+
57+
if (svgAsset === null) {
58+
return null
59+
}
60+
61+
return <div className={className} dangerouslySetInnerHTML={dangerouslySetInnerHTML}></div>
62+
}

packages/webui/src/client/lib/shelf.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ export type { AdLibPieceUi } from '@sofie-automation/meteor-lib/dist/uiTypes/Adl
1616
export interface ShelfDisplayOptions {
1717
enableBuckets: boolean
1818
enableLayout: boolean
19-
enableInspector: boolean
2019
}
2120

2221
export interface AdlibSegmentUi extends DBSegment {
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { faPencil, faTrashCan } from '@fortawesome/free-solid-svg-icons'
2+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3+
4+
export function EmptyBucket({ className }: { className?: string }): JSX.Element {
5+
return (
6+
<svg
7+
width="20"
8+
height="20"
9+
viewBox="0 0 20 20"
10+
fill="none"
11+
xmlns="http://www.w3.org/2000/svg"
12+
className={className}
13+
>
14+
<path
15+
d="M5.69409 2.5316L5.48082 2.28098C5.4214 2.21116 5.33451 2.17069 5.24282 2.17015C5.15114 2.16961 5.06377 2.20905 5.00353 2.27817L1.1751 6.67103C0.867817 7.02362 0.864726 7.54796 1.16783 7.90415L4.13873 11.3953C4.44184 11.7515 4.95992 11.8324 5.35713 11.5855L10.3059 8.50918C10.3838 8.46077 10.4367 8.38084 10.4508 8.29025C10.465 8.19966 10.4389 8.10741 10.3795 8.03758L10.1662 7.78697C11.4079 6.52143 11.5 4.49448 10.3288 3.11816C9.15755 1.74184 7.14198 1.50842 5.69409 2.5316ZM6.26283 3.22334C7.44371 2.42416 8.8104 2.58925 9.75596 3.7004C10.7015 4.81156 10.4475 5.96219 9.46967 7L6.26283 3.22334ZM9.32316 8.03758L5.49982 10.5C4.99982 11 4.49982 10.5 4.49982 10.5L1.96967 7.5C1.86863 7.38127 1.86724 7.11753 1.96967 7L5.24282 3.22334L9.32316 8.03758Z"
16+
fill="currentColor"
17+
/>
18+
<path
19+
d="M8.67236 6.25806H8.67432C8.675 6.25828 8.67621 6.25896 8.67725 6.25903C8.68067 6.25927 8.68655 6.25955 8.69287 6.26001C8.70603 6.26096 8.72594 6.26209 8.75049 6.26392C8.80025 6.26761 8.87225 6.27366 8.96045 6.28052C9.13785 6.29432 9.38288 6.31351 9.65088 6.33716C10.1855 6.38434 10.8202 6.44808 11.2036 6.51196L11.6313 6.56958C11.7407 6.58109 11.8367 6.58938 11.9429 6.60571C12.1584 6.63893 12.419 6.70552 12.9868 6.89478L13.2124 6.98462C13.7393 7.22941 14.2694 7.70419 14.7192 8.21021C15.2362 8.79172 15.6646 9.43407 15.8813 9.86743L15.9771 10.0803C16.23 10.6835 16.6815 12.0092 17.1157 13.4309C17.6127 15.0582 18.0946 16.8347 18.2368 17.8303L18.2563 17.9651L18.1206 17.9739L12.4517 18.3518L12.3364 18.3596L12.3188 18.2454C12.1774 17.3259 12.0333 15.5895 11.8853 13.9719C11.8111 13.1614 11.7353 12.3794 11.6587 11.7405C11.6007 11.2572 11.5429 10.8635 11.4858 10.6018L11.4292 10.386C11.0177 9.15161 10.1317 8.28184 9.7085 7.85864L9.69971 7.84985L8.56592 6.46411L8.38135 6.23755L8.67236 6.25806ZM15.7183 15.0637C15.2145 14.3081 14.8363 13.3009 14.4585 13.552C14.0806 13.8039 14.3322 14.4336 13.9546 14.4338C13.5768 14.4338 13.4504 13.8045 13.0728 13.9299C12.6951 14.0558 12.6948 14.9493 12.6948 15.0764C12.6948 15.2016 12.9436 18.0629 12.9468 18.0999L17.356 17.7219L16.7261 14.9377C16.7261 14.9377 16.2222 15.8196 15.7183 15.0637ZM14.5845 8.89087C14.3326 9.01682 14.3322 9.6465 13.9546 9.77271C13.5766 9.89869 13.0728 9.77271 12.9468 9.52075C12.8208 9.26889 12.317 8.89117 12.0649 8.89087C11.8131 8.89087 11.6872 9.01691 11.687 9.14282C11.687 9.2058 11.7809 9.70982 11.8911 10.2766L12.1909 11.7883C12.3169 12.4182 12.5688 13.0481 12.9468 13.0481C13.3246 13.0479 13.7026 12.6701 13.7026 12.2922C13.7028 11.9145 14.0806 11.7883 14.3325 11.7883C14.5844 11.7885 14.9624 12.0404 15.0884 12.2922C15.2144 12.5442 15.4663 12.9221 15.8442 12.7961C16.2218 12.6698 15.9702 11.6623 15.8442 11.2844C15.7181 10.9061 14.8367 8.76654 14.5845 8.89087ZM11.3091 7.76978C11.3273 7.78505 12.951 9.14141 13.7026 8.89087C14.4535 8.64016 12.7148 7.53052 12.6948 7.51782L11.3091 7.76978Z"
20+
fill="currentColor"
21+
/>
22+
<path
23+
d="M10.0488 18.8434C9.79688 18.9694 9.79688 19.2339 9.79688 19.2339H12.0645H19.8753C19.8753 19.2339 19.8753 18.5914 19.6233 18.3395C19.3714 18.0875 19.1963 18.2519 19.1194 18.2135C19.0425 18.175 18.8675 17.0797 17.6076 16.7017C16.3478 16.3238 15.8439 17.7096 15.7179 17.7096C15.592 17.7096 15.466 17.5836 15.214 17.5836C14.9621 17.5836 14.7101 17.8355 14.5841 17.9615C14.4581 18.0875 14.2062 17.0797 12.6944 17.2056C11.1827 17.3316 11.0567 18.7174 11.0567 18.7174C11.0567 18.7174 10.3008 18.7174 10.0488 18.8434Z"
24+
fill="currentColor"
25+
stroke="currentColor"
26+
strokeWidth="0.25196"
27+
/>
28+
</svg>
29+
)
30+
}
31+
32+
export function Rename({ className }: { className?: string }): JSX.Element {
33+
return <FontAwesomeIcon icon={faPencil} className={className} />
34+
}
35+
36+
export function Delete({ className }: { className?: string }): JSX.Element {
37+
return <FontAwesomeIcon icon={faTrashCan} className={className} />
38+
}
39+
40+
export function CreateNewBucket({ className }: { className?: string }): JSX.Element {
41+
return (
42+
<svg
43+
width="20"
44+
height="20"
45+
viewBox="0 0 20 20"
46+
fill="none"
47+
xmlns="http://www.w3.org/2000/svg"
48+
className={className}
49+
>
50+
<path
51+
d="M3.15303 6.25H2.5C2.31806 6.25 2.14515 6.32928 2.02642 6.46715C1.90769 6.60502 1.85493 6.78778 1.88192 6.96771L3.59723 18.4031C3.73491 19.321 4.52337 20 5.45149 20H14.5485C15.4766 20 16.2651 19.321 16.4028 18.4031L18.1181 6.96771C18.1451 6.78778 18.0923 6.60502 17.9736 6.46715C17.8549 6.32928 17.682 6.25 17.5 6.25H16.847C16.5312 2.74594 13.5863 0 10 0C6.41373 0 3.4688 2.74594 3.15303 6.25ZM4.40933 6.25C4.72024 3.43753 7.10466 1.25 10 1.25C12.8954 1.25 15.2798 3.43753 15.5907 6.25H4.40933ZM16.7743 7.5L15.1666 18.2177C15.1207 18.5237 14.8579 18.75 14.5485 18.75H5.45149C5.14212 18.75 4.8793 18.5237 4.8334 18.2177L3.22575 7.5H16.7743Z"
52+
fill="currentColor"
53+
/>
54+
<path d="M9.2 9V12.2H6V13.8H9.2V17H10.8008V13.8H14V12.2H10.8008V9H9.2Z" fill="currentColor" />
55+
</svg>
56+
)
57+
}
58+
59+
export function BucketHandle({ className }: { className?: string }): JSX.Element {
60+
return (
61+
<svg
62+
width="20"
63+
height="20"
64+
viewBox="0 0 20 20"
65+
fill="none"
66+
xmlns="http://www.w3.org/2000/svg"
67+
className={className}
68+
>
69+
<path d="M3 13H17" stroke="white" strokeWidth="2.5" strokeLinecap="square" />
70+
<path d="M3 7H17" stroke="white" strokeWidth="2.5" strokeLinecap="square" />
71+
</svg>
72+
)
73+
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ nav.react-contextmenu {
1616

1717
hr {
1818
margin: 0;
19+
border-color: var(--bs-border-color);
1920
}
2021

2122
.react-contextmenu-item,
@@ -46,6 +47,10 @@ nav.react-contextmenu {
4647
padding-right: 25px;
4748
cursor: pointer;
4849

50+
display: flex;
51+
flex-direction: row;
52+
align-items: center;
53+
4954
&.react-contextmenu-item--selected:not(.react-contextmenu-item--disabled) {
5055
background: #313334;
5156
color: #ffffff;
@@ -55,5 +60,22 @@ nav.react-contextmenu {
5560
&.react-contextmenu-item--disabled {
5661
opacity: 0.5;
5762
}
63+
64+
> svg,
65+
> .svg {
66+
width: 17px;
67+
height: 17px;
68+
display: inline-block;
69+
object-fit: contain;
70+
margin-left: -10px;
71+
margin-right: 10px;
72+
margin-bottom: 3px;
73+
}
74+
75+
> .svg > svg {
76+
width: inherit;
77+
height: inherit;
78+
object-fit: contain;
79+
}
5880
}
5981
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142

143143
.rundown-list-item__actions {
144144
display: inline-grid;
145+
margin-left: 1em;
145146
grid-column: -1;
146147
grid-template-columns: 1fr 1fr;
147148
align-items: center;
@@ -349,6 +350,7 @@
349350
);
350351

351352
.rundown-list-item__actions {
353+
margin-left: 1em;
352354
padding: 0 0 3px; // cater for icons being larger than the font
353355
}
354356

packages/webui/src/client/styles/shelf/dashboard.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ $dashboard-button-height: 3.625em;
116116

117117
.dashboard-panel__handle {
118118
cursor: move;
119+
120+
> svg {
121+
height: 1em;
122+
vertical-align: top;
123+
margin-top: 0.05em;
124+
}
119125
}
120126
}
121127

0 commit comments

Comments
 (0)