Skip to content

Commit 27e9cb2

Browse files
committed
wip: ux
1 parent a4439e9 commit 27e9cb2

File tree

4 files changed

+101
-207
lines changed

4 files changed

+101
-207
lines changed

packages/corelib/src/overrideOpHelper.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,25 @@ export function getAllCurrentAndDeletedItemsFromOverrides<T extends object>(
4444
// Sort and wrap in the return type
4545
const sortedItems = getAllCurrentItemsFromOverrides(rawObject, comparitor)
4646

47-
const removedOutputLayers: WrappedOverridableItemDeleted<T>[] = []
47+
const computedItemIds = new Set(sortedItems.map((l) => l.id))
48+
const removedItems = getAllRemovedItemsFromOverrides(rawObject, comparitor, computedItemIds)
49+
50+
return [...sortedItems, ...removedItems]
51+
}
52+
53+
export function getAllRemovedItemsFromOverrides<T extends object>(
54+
rawObject: ReadonlyDeep<ObjectWithOverrides<Record<string, T | undefined>>>,
55+
comparitor:
56+
| ((a: [id: string, obj: T | ReadonlyDeep<T>], b: [id: string, obj: T | ReadonlyDeep<T>]) => number)
57+
| null,
58+
validItemIds: Set<string> // TODO - should this be optional?
59+
): WrappedOverridableItemDeleted<T>[] {
60+
const removedItems: WrappedOverridableItemDeleted<T>[] = []
4861

4962
// Find the items which have been deleted with an override
50-
const computedOutputLayerIds = new Set(sortedItems.map((l) => l.id))
5163
for (const [id, output] of Object.entries<ReadonlyDeep<T | undefined>>(rawObject.defaults)) {
52-
if (!computedOutputLayerIds.has(id) && output) {
53-
removedOutputLayers.push(
64+
if (!validItemIds.has(id) && output) {
65+
removedItems.push(
5466
literal<WrappedOverridableItemDeleted<T>>({
5567
type: 'deleted',
5668
id: id,
@@ -62,9 +74,9 @@ export function getAllCurrentAndDeletedItemsFromOverrides<T extends object>(
6274
}
6375
}
6476

65-
if (comparitor) removedOutputLayers.sort((a, b) => comparitor([a.id, a.defaults], [b.id, b.defaults]))
77+
if (comparitor) removedItems.sort((a, b) => comparitor([a.id, a.defaults], [b.id, b.defaults]))
6678

67-
return [...sortedItems, ...removedOutputLayers]
79+
return removedItems
6880
}
6981

7082
/**

packages/webui/src/client/ui/Settings/Studio/Devices/ParentDevices.tsx

Lines changed: 83 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import { useTracker } from '../../../../lib/ReactMeteorData/ReactMeteorData'
3333
import { TextInputControl } from '../../../../lib/Components/TextInput'
3434
import { MomentFromNow } from '../../../../lib/Moment'
3535
import { MeteorCall } from '../../../../lib/meteorApi'
36+
import { ReadonlyDeep } from 'type-fest'
37+
import { PeripheralDevice } from '@sofie-automation/corelib/dist/dataModel/PeripheralDevice'
3638

3739
interface StudioParentDevicesProps {
3840
studioId: StudioId
@@ -63,8 +65,6 @@ export function StudioParentDevices({ studioId }: Readonly<StudioParentDevicesPr
6365

6466
const overrideHelper = useOverrideOpHelper(saveOverrides, deviceSettings)
6567

66-
console.log('deviceSettings', deviceSettings)
67-
6868
const wrappedDeviceSettings = useMemo(
6969
() =>
7070
getAllCurrentAndDeletedItemsFromOverrides<StudioDeviceSettings>(deviceSettings, (a, b) =>
@@ -73,43 +73,50 @@ export function StudioParentDevices({ studioId }: Readonly<StudioParentDevicesPr
7373
[deviceSettings]
7474
)
7575

76-
const addNewItem = useCallback(() => {
77-
const newId = getRandomString()
78-
const newDevice = literal<StudioDeviceSettings>({
79-
// peripheralDeviceId: undefined,
80-
name: 'New Device',
81-
options: {},
82-
})
83-
84-
const addOp = literal<ObjectOverrideSetOp>({
85-
op: 'set',
86-
path: newId,
87-
value: newDevice,
88-
})
89-
90-
Studios.update(studioId, {
91-
$push: {
92-
'peripheralDeviceSettings.deviceSettings.overrides': addOp,
93-
},
94-
})
95-
}, [studioId])
76+
const addNewItem = useCallback(
77+
(id?: string) => {
78+
const newId = id ?? getRandomString()
79+
const newDevice = literal<StudioDeviceSettings>({
80+
// peripheralDeviceId: undefined,
81+
name: 'New Device',
82+
options: {},
83+
})
84+
85+
const addOp = literal<ObjectOverrideSetOp>({
86+
op: 'set',
87+
path: newId,
88+
value: newDevice,
89+
})
90+
91+
Studios.update(studioId, {
92+
$push: {
93+
'peripheralDeviceSettings.deviceSettings.overrides': addOp,
94+
},
95+
})
96+
},
97+
[studioId]
98+
)
99+
const addNewItemClick = useCallback(() => addNewItem(), [studioId])
100+
101+
const hasCurrentDevice = wrappedDeviceSettings.find((d) => d.type === 'normal')
96102

97103
return (
98104
<div>
99105
<h2 className="mhn">
100-
<Tooltip
101-
overlay={t('Parent devices are ????')}
102-
visible={getHelpMode() && !wrappedDeviceSettings.length}
103-
placement="right"
104-
>
106+
<Tooltip overlay={t('Parent devices are ????')} visible={getHelpMode() && !hasCurrentDevice} placement="right">
105107
<span>{t('Parent Devices')}</span>
106108
</Tooltip>
107109
</h2>
108110

109-
<GenericParentDevicesTable studioId={studioId} devices={wrappedDeviceSettings} overrideHelper={overrideHelper} />
111+
<GenericParentDevicesTable
112+
studioId={studioId}
113+
devices={wrappedDeviceSettings}
114+
overrideHelper={overrideHelper}
115+
createItemWithId={addNewItem}
116+
/>
110117

111118
<div className="mod mhs">
112-
<button className="btn btn-primary" onClick={addNewItem}>
119+
<button className="btn btn-primary" onClick={addNewItemClick}>
113120
<FontAwesomeIcon icon={faPlus} />
114121
</button>
115122
</div>
@@ -128,17 +135,26 @@ interface ParentDevicesTableProps {
128135
studioId: StudioId
129136
devices: WrappedOverridableItem<StudioDeviceSettings>[]
130137
overrideHelper: OverrideOpHelper
138+
createItemWithId: (id: string) => void
131139
}
132140
function GenericParentDevicesTable({
133141
studioId,
134142
devices,
135143
overrideHelper,
144+
createItemWithId,
136145
}: Readonly<ParentDevicesTableProps>): JSX.Element {
137146
const { t } = useTranslation()
138147
const { toggleExpanded, isExpanded } = useToggleExpandHelper()
139148

140149
const allParentDevices = useTracker(() => PeripheralDevices.find({ parentDeviceId: undefined }).fetch(), [], [])
141150

151+
const studioParentDevices = useTracker(
152+
() => PeripheralDevices.find({ parentDeviceId: undefined, 'studioAndConfigId.studioId': studioId }).fetch(),
153+
[studioId],
154+
[]
155+
)
156+
const allKnownConfigIds = new Set(devices.map((d) => d.id))
157+
142158
const peripheralDevicesByConfigIdMap = useMemo(() => {
143159
const devicesMap = new Map<string, PeripheralDeviceTranslated>()
144160

@@ -250,6 +266,19 @@ function GenericParentDevicesTable({
250266
)
251267
}
252268
})}
269+
{studioParentDevices.map((device) => {
270+
if (!device.studioAndConfigId) return null
271+
if (allKnownConfigIds.has(device.studioAndConfigId.configId)) return null
272+
273+
return (
274+
<OrphanedSummaryRow
275+
key={`device_${device._id}`}
276+
configId={device.studioAndConfigId.configId}
277+
device={device}
278+
createItemWithId={createItemWithId}
279+
/>
280+
)
281+
})}
253282
</tbody>
254283
</table>
255284
)
@@ -322,6 +351,31 @@ function DeletedSummaryRow({ item, undeleteItemWithId }: Readonly<DeletedSummary
322351
)
323352
}
324353

354+
interface OrphanedSummaryRowProps {
355+
configId: string
356+
device: ReadonlyDeep<PeripheralDevice>
357+
createItemWithId: (itemId: string) => void
358+
}
359+
function OrphanedSummaryRow({ configId, device, createItemWithId }: Readonly<OrphanedSummaryRowProps>): JSX.Element {
360+
const createItem = useCallback(() => createItemWithId(configId), [createItemWithId, configId])
361+
362+
return (
363+
<tr>
364+
<th className="settings-studio-device__name c2 deleted">-</th>
365+
366+
<th className="settings-studio-device__gateway c2 deleted">{device.name || unprotectString(device._id)}</th>
367+
368+
<th className="settings-studio-device__last_seen c2 deleted">{<MomentFromNow date={device.lastSeen} />}</th>
369+
370+
<td className="settings-studio-device__actions table-item-actions c1" key="action">
371+
<button className="action-btn" onClick={createItem} title="Setup device">
372+
<FontAwesomeIcon icon={faPlus} />
373+
</button>
374+
</td>
375+
</tr>
376+
)
377+
}
378+
325379
interface ParentDeviceEditRowProps {
326380
studioId: StudioId
327381
peripheralDevice: PeripheralDeviceTranslated | undefined

packages/webui/src/client/ui/Settings/Studio/Devices/SelectDevices.tsx

Lines changed: 0 additions & 169 deletions
This file was deleted.

0 commit comments

Comments
 (0)