Skip to content

Commit 47efb95

Browse files
committed
feat: add ingest statuses debug page
1 parent a2a6556 commit 47efb95

File tree

8 files changed

+178
-31
lines changed

8 files changed

+178
-31
lines changed

meteor/server/publications/ingestStatus/publication.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { IngestRundownStatus } from '@sofie-automation/shared-lib/dist/ingest/ru
2121
import { protectString } from '@sofie-automation/corelib/dist/protectedString'
2222
import { DBRundown } from '@sofie-automation/corelib/dist/dataModel/Rundown'
2323
import { createIngestRundownStatus } from './createIngestRundownStatus'
24+
import { Settings } from '../../Settings'
2425

2526
interface IngestRundownStatusArgs {
2627
readonly deviceId: PeripheralDeviceId
@@ -176,7 +177,10 @@ meteorCustomPublish(
176177
async function (pub, deviceId: PeripheralDeviceId, token: string | undefined) {
177178
check(deviceId, String)
178179

179-
await checkAccessAndGetPeripheralDevice(deviceId, token, this)
180+
if (Settings.enableHeaderAuth) {
181+
// This is used in a testTool, so only check when auth is enabled
182+
await checkAccessAndGetPeripheralDevice(deviceId, token, this)
183+
}
180184

181185
await setUpCollectionOptimizedObserver<
182186
IngestRundownStatus,

packages/webui/src/client/ui/TestTools/DeviceTriggers.tsx

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,18 @@
11
import React, { Fragment, useState } from 'react'
22
import { useSubscription, useTracker } from '../../lib/ReactMeteorData/react-meteor-data'
3-
import { Mongo } from 'meteor/mongo'
4-
import {} from '@sofie-automation/meteor-lib/dist/api/pubsub'
53
import { protectString, unprotectString } from '@sofie-automation/corelib/dist/protectedString'
64
import { useTranslation } from 'react-i18next'
75
import { Link, useParams } from 'react-router-dom'
86
import { PeripheralDeviceId } from '@sofie-automation/corelib/dist/dataModel/Ids'
97
import { DeviceTriggerMountedAction, PreviewWrappedAdLib } from '@sofie-automation/meteor-lib/dist/api/MountedTriggers'
108
import { PeripheralDevices } from '../../collections'
119
import { CorelibPubSub } from '@sofie-automation/corelib/dist/pubsub'
12-
import {
13-
PeripheralDevicePubSub,
14-
PeripheralDevicePubSubCollectionsNames,
15-
} from '@sofie-automation/shared-lib/dist/pubsub/peripheralDevice'
10+
import { PeripheralDevicePubSub } from '@sofie-automation/shared-lib/dist/pubsub/peripheralDevice'
11+
import { MountedTriggers, MountedTriggersPreviews } from './collections'
1612
import Row from 'react-bootstrap/Row'
1713
import Col from 'react-bootstrap/Col'
1814
import Form from 'react-bootstrap/Form'
1915

20-
const MountedTriggers = new Mongo.Collection<DeviceTriggerMountedAction>(
21-
PeripheralDevicePubSubCollectionsNames.mountedTriggers
22-
)
23-
const MountedTriggersPreviews = new Mongo.Collection<PreviewWrappedAdLib>(
24-
PeripheralDevicePubSubCollectionsNames.mountedTriggersPreviews
25-
)
26-
2716
interface DeviceTriggersViewRouteParams {
2817
peripheralDeviceId: string
2918
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { useSubscription, useTracker } from '../../lib/ReactMeteorData/react-meteor-data'
2+
import { unprotectString } from '../../lib/tempLib'
3+
import { makeTableOfObject } from '../../lib/utilComponents'
4+
import { PeripheralDeviceId } from '@sofie-automation/corelib/dist/dataModel/Ids'
5+
import { PeripheralDevicePubSub } from '@sofie-automation/shared-lib/dist/pubsub/peripheralDevice'
6+
import { useTranslation } from 'react-i18next'
7+
import { CorelibPubSub } from '@sofie-automation/corelib/dist/pubsub'
8+
import { PeripheralDevices } from '../../collections'
9+
import { Link } from 'react-router-dom'
10+
import { PeripheralDeviceCategory } from '@sofie-automation/shared-lib/dist/peripheralDevice/peripheralDeviceAPI'
11+
import { IngestRundownStatuses } from './collections'
12+
import { IngestPartStatus, IngestRundownStatus } from '@sofie-automation/shared-lib/dist/ingest/rundownStatus'
13+
14+
interface IMappingsViewProps {
15+
match?: {
16+
params?: {
17+
peripheralDeviceId: PeripheralDeviceId
18+
}
19+
}
20+
}
21+
function IngestRundownStatusView(props: Readonly<IMappingsViewProps>): JSX.Element {
22+
const { t } = useTranslation()
23+
24+
return (
25+
<div className="mtl gutter">
26+
<header className="mvs">
27+
<h1>{t('Ingest Rundown Status')}</h1>
28+
</header>
29+
<div className="mod mvl">
30+
{props.match && props.match.params && (
31+
<ComponentMappingsTable peripheralDeviceId={props.match.params.peripheralDeviceId} />
32+
)}
33+
</div>
34+
</div>
35+
)
36+
}
37+
38+
interface ComponentMappingsTableProps {
39+
peripheralDeviceId: PeripheralDeviceId
40+
}
41+
function ComponentMappingsTable({ peripheralDeviceId }: Readonly<ComponentMappingsTableProps>): JSX.Element {
42+
useSubscription(PeripheralDevicePubSub.ingestDeviceRundownStatus, peripheralDeviceId)
43+
44+
const rundowns = useTracker(() => IngestRundownStatuses.find({}).fetch(), [], [])
45+
46+
return (
47+
<>
48+
{rundowns.map((rundown) => (
49+
<StatusesForRundown key={rundown.externalId} rundown={rundown} />
50+
))}
51+
</>
52+
)
53+
}
54+
55+
function StatusesForRundown({ rundown }: { rundown: IngestRundownStatus }): JSX.Element {
56+
return (
57+
<div className="mbl">
58+
<h3>
59+
{rundown.externalId} ({unprotectString(rundown._id)})
60+
</h3>
61+
62+
<p>Status: {rundown.active}</p>
63+
64+
<table className="testtools-timelinetable mll">
65+
<tbody>
66+
<tr>
67+
<th>Segment Id</th>
68+
<th>Part Id</th>
69+
<th>Ready</th>
70+
<th>Status</th>
71+
<th>Items</th>
72+
</tr>
73+
{rundown.segments.flatMap((segment) =>
74+
segment.parts.map((part) => (
75+
<StatusesForSegmentRow key={segment.externalId} part={part} segmentId={segment.externalId} />
76+
))
77+
)}
78+
</tbody>
79+
</table>
80+
81+
<p></p>
82+
</div>
83+
)
84+
}
85+
86+
interface StatusesForSegmentRowProps {
87+
segmentId: string
88+
part: IngestPartStatus
89+
}
90+
function StatusesForSegmentRow({ segmentId, part }: Readonly<StatusesForSegmentRowProps>) {
91+
return (
92+
<tr>
93+
<td>{segmentId}</td>
94+
<td>{part.externalId}</td>
95+
<td>{JSON.stringify(part.isReady)}</td>
96+
<td>{part.playbackStatus}</td>
97+
<td>{makeTableOfObject(part.itemsReady)}</td>
98+
</tr>
99+
)
100+
}
101+
102+
function IngestRundownStatusSelect(): JSX.Element | null {
103+
const { t } = useTranslation()
104+
105+
useSubscription(CorelibPubSub.peripheralDevices, null)
106+
const devices = useTracker(() => PeripheralDevices.find({ category: PeripheralDeviceCategory.INGEST }).fetch(), [])
107+
108+
return (
109+
<div className="mhl gutter recordings-studio-select">
110+
<header className="mbs">
111+
<h1>{t('Ingest Rundown Statuses')}</h1>
112+
</header>
113+
<div className="mod mvl">
114+
<strong>Peripheral Device</strong>
115+
<ul>
116+
{devices?.map((device) => (
117+
<li key={unprotectString(device._id)}>
118+
<Link to={`ingestRundownStatus/${device._id}`}>{device.name}</Link>
119+
</li>
120+
))}
121+
</ul>
122+
</div>
123+
</div>
124+
)
125+
}
126+
127+
export { IngestRundownStatusView, IngestRundownStatusSelect }

packages/webui/src/client/ui/TestTools/Mappings.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,11 @@ import { makeTableOfObject } from '../../lib/utilComponents'
66
import { StudioSelect } from './StudioSelect'
77
import { MappingExt } from '@sofie-automation/corelib/dist/dataModel/Studio'
88
import { LookaheadMode, TSR } from '@sofie-automation/blueprints-integration'
9-
import { createSyncPeripheralDeviceCustomPublicationMongoCollection } from '../../collections/lib'
109
import { StudioId } from '@sofie-automation/corelib/dist/dataModel/Ids'
11-
import { PeripheralDevicePubSubCollectionsNames } from '@sofie-automation/shared-lib/dist/pubsub/peripheralDevice'
1210
import { useTranslation } from 'react-i18next'
1311
import Row from 'react-bootstrap/Row'
1412
import Col from 'react-bootstrap/Col'
15-
16-
const StudioMappings = createSyncPeripheralDeviceCustomPublicationMongoCollection(
17-
PeripheralDevicePubSubCollectionsNames.studioMappings
18-
)
13+
import { StudioMappings } from './collections'
1914

2015
interface IMappingsViewProps {
2116
match?: {

packages/webui/src/client/ui/TestTools/Timeline.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,12 @@ import { useTranslation } from 'react-i18next'
2020
import { useParams } from 'react-router-dom'
2121
import { useCallback, useEffect, useMemo, useState } from 'react'
2222
import Classnames from 'classnames'
23-
import { createSyncPeripheralDeviceCustomPublicationMongoCollection } from '../../collections/lib'
2423
import { StudioId } from '@sofie-automation/corelib/dist/dataModel/Ids'
25-
import { PeripheralDevicePubSubCollectionsNames } from '@sofie-automation/shared-lib/dist/pubsub/peripheralDevice'
2624
import Row from 'react-bootstrap/Row'
2725
import Col from 'react-bootstrap/Col'
2826
import Button from 'react-bootstrap/Button'
2927
import Form from 'react-bootstrap/Form'
30-
31-
export const StudioTimeline = createSyncPeripheralDeviceCustomPublicationMongoCollection(
32-
PeripheralDevicePubSubCollectionsNames.studioTimeline
33-
)
28+
import { StudioTimeline } from './collections'
3429

3530
interface TimelineViewRouteParams {
3631
studioId: string | undefined

packages/webui/src/client/ui/TestTools/TimelineDatastore.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
import { useSubscription, useTracker } from '../../lib/ReactMeteorData/react-meteor-data'
22
import { StudioSelect } from './StudioSelect'
3-
import { Mongo } from 'meteor/mongo'
4-
import { DBTimelineDatastoreEntry } from '@sofie-automation/corelib/dist/dataModel/TimelineDatastore'
53
import { protectString, unprotectString } from '@sofie-automation/corelib/dist/protectedString'
64
import { useTranslation } from 'react-i18next'
75
import { useParams } from 'react-router-dom'
86
import { StudioId } from '@sofie-automation/corelib/dist/dataModel/Ids'
97
import { CorelibPubSub } from '@sofie-automation/corelib/dist/pubsub'
108
import Row from 'react-bootstrap/Row'
119
import Col from 'react-bootstrap/Col'
12-
13-
const TimelineDatastore = new Mongo.Collection<DBTimelineDatastoreEntry>('timelineDatastore')
10+
import { TimelineDatastore } from './collections'
1411

1512
interface TimelineDatastoreViewRouteParams {
1613
studioId: string
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { PeripheralDevicePubSubCollectionsNames } from '@sofie-automation/shared-lib/dist/pubsub/peripheralDevice'
2+
import { createSyncPeripheralDeviceCustomPublicationMongoCollection } from '../../collections/lib'
3+
4+
/**
5+
* These collections are not public and are for the use of the TestTools only.
6+
* They are defined in this file, as hot reloading them is not supported
7+
*/
8+
9+
export const IngestRundownStatuses = createSyncPeripheralDeviceCustomPublicationMongoCollection(
10+
PeripheralDevicePubSubCollectionsNames.ingestRundownStatus
11+
)
12+
13+
export const MountedTriggers = createSyncPeripheralDeviceCustomPublicationMongoCollection(
14+
PeripheralDevicePubSubCollectionsNames.mountedTriggers
15+
)
16+
export const MountedTriggersPreviews = createSyncPeripheralDeviceCustomPublicationMongoCollection(
17+
PeripheralDevicePubSubCollectionsNames.mountedTriggersPreviews
18+
)
19+
20+
export const StudioMappings = createSyncPeripheralDeviceCustomPublicationMongoCollection(
21+
PeripheralDevicePubSubCollectionsNames.studioMappings
22+
)
23+
24+
export const StudioTimeline = createSyncPeripheralDeviceCustomPublicationMongoCollection(
25+
PeripheralDevicePubSubCollectionsNames.studioTimeline
26+
)
27+
28+
export const TimelineDatastore = createSyncPeripheralDeviceCustomPublicationMongoCollection(
29+
PeripheralDevicePubSubCollectionsNames.timelineDatastore
30+
)

packages/webui/src/client/ui/TestTools/index.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { DeviceTriggersDeviceSelect, DeviceTriggersView } from './DeviceTriggers
99
import { CorelibPubSub } from '@sofie-automation/corelib/dist/pubsub'
1010
import Row from 'react-bootstrap/Row'
1111
import Col from 'react-bootstrap/Col'
12+
import { IngestRundownStatusSelect, IngestRundownStatusView } from './IngestRundownStatus'
1213

1314
function StatusMenu() {
1415
const { t } = useTranslation()
@@ -43,6 +44,13 @@ function StatusMenu() {
4344
>
4445
<h3>{t('Device Triggers')}</h3>
4546
</NavLink>
47+
<NavLink
48+
activeClassName="selectable-selected"
49+
className="testTools-menu__testTools-menu-item selectable clickable"
50+
to={'/testTools/ingestRundownStatus'}
51+
>
52+
<h3>{t('Ingest Rundown Statuses')}</h3>
53+
</NavLink>
4654
</div>
4755
)
4856
}
@@ -68,7 +76,9 @@ export default function Status(): JSX.Element {
6876
<Route path="/testTools/timelinedatastore/:studioId" component={TimelineDatastoreView} />
6977
<Route path="/testTools/timelinedatastore" component={TimelineDatastoreStudioSelect} />
7078
<Route path="/testTools/devicetriggers/:peripheralDeviceId" component={DeviceTriggersView} />
71-
<Route path="/testTools/devicetriggers" component={DeviceTriggersDeviceSelect} />{' '}
79+
<Route path="/testTools/devicetriggers" component={DeviceTriggersDeviceSelect} />
80+
<Route path="/testTools/ingestRundownStatus/:peripheralDeviceId" component={IngestRundownStatusView} />
81+
<Route path="/testTools/ingestRundownStatus" component={IngestRundownStatusSelect} />
7282
<Redirect to="/testTools/timeline" />
7383
</Switch>
7484
</Col>

0 commit comments

Comments
 (0)