Introduction
This project is a dashboard UI, for LC3 operators to be able to see all the ad-breaks that happened(is happening)
on each MediaSource, on a timeline, indicating when each of the ad-breaks started/stopped.
The operator is able to filter the MediaSources using a text box, and also select the time range.
Currently, it's just a visualization application, so operators will only able to identify ad-breaks,
but will have no control over the MediaSources.
Technical Details
The project has been bootstrapped with create-react-app, using Typescript as the main programming language, and
React as the frontend framework.
As this application is a dashboard, it's consuming data
from lc3-backend,
connecting via websockets endpoint, thus, whenever there is an ad-break, a message will be broadcast to this
project, and the graphs will be updated.
This project is using Redux for the global state management of the application, and Thunk, which is a Redux middleware
that lets you call action creators and return a function.
Apart from the global state, some components uses their own internal state using hooks.
For connecting to websockets, a custom Redux middleware has been
created middleware.ts,
and everytime the application initializes, the middleware will get which environment the app is running, through
an environment variable, and will try to connect to the websockets endpoint of the respective LC3 environment.
If the connection is successful, a Redux store will be updated with the state of the connection, otherwise it will
be updated with the error status.
After the application is connected to the endpoint, whenever a message is received, a Thunk action creator will be
called:
thunk.ts, and the message will be processed, and formatted, then finally, the Redux store
will be updated with the new data.
Basically, whenever a new ad-break happens in a single MediaSource, the correspondent
Redux store is updated. The reference data structure for that, is a JSON, where each of the keys,
are represented by a MediaSource ID, and inside these keys, there is an array of all the latest ad-breaks
for this MediaSource. So, everytime a new ad-break comes in, the application includes that on the
respective MediaSource. Following, we can check the type for this data structure:
export interface AdBreaksMessageMapping {
[key: string]: AdBreaks
}
export interface AdBreaks {
mediaSourceID: string
timeline: TimelineRecord[] | null
}
export interface TimelineRecord {
adStartTime: string
adEndTime: string | null
encoderName: string
materialID: string
expiration: string
}
Following and example of how the data looks like:
{
"BTN": {
"mediaSourceID": "BTN",
"timeline": [
{
"adStartTime": "2022-04-22T09:49:25.366Z",
"adEndTime": "2022-04-22T09:51:55.539Z",
"encoderName": "bigten_fxa_p",
"materialID": "SH025536650000",
"expiration": "2022-04-22T15:51:56.766950528Z"
},
{
"adStartTime": "2022-04-22T09:54:49.422Z",
"adEndTime": "2022-04-22T09:57:16.257Z",
"encoderName": "bigten_fxa_p",
"materialID": "SH025536650000",
"expiration": "2022-04-22T15:57:17.021420489Z"
}
]
},
"FBN": {
"mediaSourceID": "FBN",
"timeline": [
{
"adStartTime": "2022-04-22T09:37:14.805Z",
"adEndTime": "2022-04-22T09:41:14.871Z",
"encoderName": "fbn_fxa_p",
"materialID": "EP037730330308",
"expiration": "2022-04-22T15:41:15.22718158Z"
},
{
"adStartTime": "2022-04-22T09:47:42.779Z",
"adEndTime": "2022-04-22T09:51:22.869Z",
"encoderName": "fbn_fxa_p",
"materialID": "EP037730330308",
"expiration": "2022-04-22T15:51:23.939767619Z"
}
]
}
}
Available Scripts
In the project directory, you can run:
yarn start
Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.
The page will reload if you make edits.
You will also see any lint errors in the console.
yarn test
Launches the test runner in the interactive watch mode.
See the section about running tests for more
information.
yarn build
Builds the app for production to the build
folder.
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.
Your app is ready to be deployed!
See the section about deployment for more information.
yarn eject
Note: this is a one-way operation. Once you eject
, you can’t go back!
If you aren’t satisfied with the build tool and configuration choices, you can eject
at any time. This command will
remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right
into your project so you have full control over them. All of the commands except eject
will still work, but they will
point to the copied scripts so you can tweak them. At this point you’re on your own.
You don’t have to ever use eject
. The curated feature set is suitable for small and middle deployments, and you
shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t
customize it when you are ready for it.
Prettier and ESLint
Currently, ESLint isn't considering rules on .prettierrc.json, so if you change some rule on this
file, make sure to change also on .eslintrc.json.