mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-11 02:13:48 +00:00
feat: small improvements to instance info (#591)
* refactor: add typings to backend info * refactor: write current version to project file * feat: show location of css override
This commit is contained in:
@@ -2,6 +2,7 @@ import axios, { AxiosResponse } from 'axios';
|
||||
import {
|
||||
Alias,
|
||||
DatabaseModel,
|
||||
GetInfo,
|
||||
OntimeRundown,
|
||||
OSCSettings,
|
||||
OscSubscription,
|
||||
@@ -13,7 +14,6 @@ import {
|
||||
import { ExcelImportMap } from 'ontime-utils';
|
||||
|
||||
import { apiRepoLatest } from '../../externals';
|
||||
import { InfoType } from '../models/Info';
|
||||
import fileDownload from '../utils/fileDownload';
|
||||
|
||||
import { ontimeURL } from './apiConstants';
|
||||
@@ -39,7 +39,7 @@ export async function postSettings(data: Settings) {
|
||||
* @description HTTP request to retrieve application info
|
||||
* @return {Promise}
|
||||
*/
|
||||
export async function getInfo(): Promise<InfoType> {
|
||||
export async function getInfo(): Promise<GetInfo> {
|
||||
const res = await axios.get(`${ontimeURL}/info`);
|
||||
return res.data;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { GetInfo } from 'ontime-types';
|
||||
|
||||
import { queryRefetchIntervalSlow } from '../../ontimeConfig';
|
||||
import { APP_INFO } from '../api/apiConstants';
|
||||
@@ -6,7 +7,7 @@ import { getInfo } from '../api/ontimeApi';
|
||||
import { ontimePlaceholderInfo } from '../models/Info';
|
||||
|
||||
export default function useInfo() {
|
||||
const { data, status, isError, refetch } = useQuery({
|
||||
const { data, status, isError, refetch, isFetching } = useQuery<GetInfo>({
|
||||
queryKey: APP_INFO,
|
||||
queryFn: getInfo,
|
||||
placeholderData: ontimePlaceholderInfo,
|
||||
@@ -16,5 +17,5 @@ export default function useInfo() {
|
||||
networkMode: 'always',
|
||||
});
|
||||
|
||||
return { data, status, isError, refetch };
|
||||
return { data, status, isError, refetch, isFetching };
|
||||
}
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
import { Settings } from 'ontime-types';
|
||||
import { GetInfo, OSCSettings } from 'ontime-types';
|
||||
|
||||
type NetworkInterfaceType = {
|
||||
name: string;
|
||||
address: string;
|
||||
};
|
||||
|
||||
export type InfoType = {
|
||||
networkInterfaces: NetworkInterfaceType[];
|
||||
settings: Pick<Settings, 'version' | 'serverPort'>;
|
||||
};
|
||||
|
||||
export const ontimePlaceholderInfo: InfoType = {
|
||||
networkInterfaces: [],
|
||||
settings: {
|
||||
version: 2,
|
||||
serverPort: 4001,
|
||||
export const oscPlaceholderSettings: OSCSettings = {
|
||||
portIn: 0,
|
||||
portOut: 0,
|
||||
targetIP: '',
|
||||
enabledIn: false,
|
||||
enabledOut: false,
|
||||
subscriptions: {
|
||||
onLoad: [],
|
||||
onStart: [],
|
||||
onPause: [],
|
||||
onStop: [],
|
||||
onUpdate: [],
|
||||
onFinish: [],
|
||||
},
|
||||
};
|
||||
|
||||
export const ontimePlaceholderInfo: GetInfo = {
|
||||
networkInterfaces: [],
|
||||
version: '2.0.0',
|
||||
serverPort: 4001,
|
||||
osc: oscPlaceholderSettings,
|
||||
cssOverride: '',
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Settings } from 'ontime-types';
|
||||
|
||||
export const ontimePlaceholderSettings: Settings = {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
serverPort: 4001,
|
||||
editorKey: null,
|
||||
operatorKey: null,
|
||||
|
||||
@@ -3,19 +3,24 @@
|
||||
.aliases {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
gap: 0.5rem;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
padding: 8px 0;
|
||||
padding: 0.5rem 0;
|
||||
|
||||
.aliasRow {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.grow {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.url {
|
||||
font-size: calc(1rem - 2px);
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { Input, Switch } from '@chakra-ui/react';
|
||||
import { Alert, AlertDescription, AlertIcon, AlertTitle, Input, Switch } from '@chakra-ui/react';
|
||||
import { ViewSettings } from 'ontime-types';
|
||||
|
||||
import { logAxiosError } from '../../../common/api/apiUtils';
|
||||
import { postViewSettings } from '../../../common/api/ontimeApi';
|
||||
import { PopoverPickerRHF } from '../../../common/components/input/popover-picker/PopoverPicker';
|
||||
import useInfo from '../../../common/hooks-query/useInfo';
|
||||
import useViewSettings from '../../../common/hooks-query/useViewSettings';
|
||||
import { mtm } from '../../../common/utils/timeConstants';
|
||||
import ModalLoader from '../modal-loader/ModalLoader';
|
||||
import { inputProps } from '../modalHelper';
|
||||
import ModalInput from '../ModalInput';
|
||||
import ModalLink from '../ModalLink';
|
||||
import ModalSplitInput from '../ModalSplitInput';
|
||||
import OntimeModalFooter from '../OntimeModalFooter';
|
||||
|
||||
@@ -18,8 +20,12 @@ import InputMillisWithString from './InputMillisWithString';
|
||||
|
||||
import style from './SettingsModal.module.scss';
|
||||
|
||||
const cssOverrideDocsUrl = 'https://ontime.gitbook.io/v2/features/custom-styling';
|
||||
|
||||
export default function ViewSettingsForm() {
|
||||
const { data, status, refetch, isFetching } = useViewSettings();
|
||||
const { data: info, isFetching: isFetchingInfo } = useInfo();
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
@@ -75,13 +81,24 @@ export default function ViewSettingsForm() {
|
||||
|
||||
const disableInputs = status === 'loading';
|
||||
|
||||
if (isFetching) {
|
||||
if (isFetching || isFetchingInfo) {
|
||||
return <ModalLoader />;
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} id='view-settings' className={style.sectionContainer}>
|
||||
<span className={style.title}>General view settings</span>
|
||||
<Alert status='info' variant='ontime-on-light-info'>
|
||||
<AlertIcon />
|
||||
<div className={style.column}>
|
||||
<AlertTitle>CSS Override</AlertTitle>
|
||||
<AlertDescription>
|
||||
Ontime will use the CSS file at its install location. <br />
|
||||
<span className={style.url}>{info.cssOverride}</span>
|
||||
<ModalLink href={cssOverrideDocsUrl}>For more information, see the docs</ModalLink>
|
||||
</AlertDescription>
|
||||
</div>
|
||||
</Alert>
|
||||
<ModalSplitInput
|
||||
field='overrideStyles'
|
||||
title='Override CSS Styles'
|
||||
|
||||
@@ -11,7 +11,7 @@ describe('safeMerge', () => {
|
||||
},
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
serverPort: 4001,
|
||||
editorKey: null,
|
||||
operatorKey: null,
|
||||
@@ -84,7 +84,7 @@ describe('safeMerge', () => {
|
||||
const mergedData = safeMerge(existing, newData);
|
||||
expect(mergedData.settings).toEqual({
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
serverPort: 3000,
|
||||
operatorKey: null,
|
||||
editorKey: null,
|
||||
@@ -144,7 +144,7 @@ describe('safeMerge', () => {
|
||||
},
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
serverPort: 4001,
|
||||
operatorKey: null,
|
||||
editorKey: null,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Alias, DatabaseModel, LogOrigin, ProjectData } from 'ontime-types';
|
||||
import { Alias, DatabaseModel, GetInfo, LogOrigin, ProjectData } from 'ontime-types';
|
||||
|
||||
import { RequestHandler } from 'express';
|
||||
import { RequestHandler, Request, Response } from 'express';
|
||||
import fs from 'fs';
|
||||
import { networkInterfaces } from 'os';
|
||||
|
||||
@@ -9,7 +9,7 @@ import { DataProvider } from '../classes/data-provider/DataProvider.js';
|
||||
import { failEmptyObjects, failIsNotArray } from '../utils/routerUtils.js';
|
||||
import { PlaybackService } from '../services/PlaybackService.js';
|
||||
import { eventStore } from '../stores/EventStore.js';
|
||||
import { isDocker, resolveDbPath } from '../setup.js';
|
||||
import { isDocker, pathToStartStyles, resolveDbPath } from '../setup.js';
|
||||
import { oscIntegration } from '../services/integration-service/OscIntegration.js';
|
||||
import { logger } from '../classes/Logger.js';
|
||||
import { deleteAllEvents, notifyChanges } from '../services/rundown-service/RundownService.js';
|
||||
@@ -105,15 +105,16 @@ const getNetworkInterfaces = () => {
|
||||
return results;
|
||||
};
|
||||
|
||||
// Create controller for POST request to '/ontime/info'
|
||||
// Create controller for GET request to '/ontime/info'
|
||||
// Returns -
|
||||
export const getInfo = async (req, res) => {
|
||||
export const getInfo = async (req: Request, res: Response<GetInfo>) => {
|
||||
const { version, serverPort } = DataProvider.getSettings();
|
||||
const osc = DataProvider.getOsc();
|
||||
|
||||
// get nif and inject localhost
|
||||
const ni = getNetworkInterfaces();
|
||||
ni.unshift({ name: 'localhost', address: '127.0.0.1' });
|
||||
const cssOverride = pathToStartStyles;
|
||||
|
||||
// send object with network information
|
||||
res.status(200).send({
|
||||
@@ -121,6 +122,7 @@ export const getInfo = async (req, res) => {
|
||||
version,
|
||||
serverPort,
|
||||
osc,
|
||||
cssOverride,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { DatabaseModel } from 'ontime-types';
|
||||
import { ONTIME_VERSION } from '../ONTIME_VERSION.js';
|
||||
|
||||
export const dbModel: DatabaseModel = {
|
||||
rundown: [],
|
||||
@@ -12,7 +13,7 @@ export const dbModel: DatabaseModel = {
|
||||
},
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: ONTIME_VERSION,
|
||||
serverPort: 4001,
|
||||
editorKey: null,
|
||||
operatorKey: null,
|
||||
|
||||
@@ -201,7 +201,7 @@ describe('test json parser with valid def', () => {
|
||||
},
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
timeFormat: '24',
|
||||
},
|
||||
viewSettings: {},
|
||||
@@ -260,7 +260,7 @@ describe('test json parser with valid def', () => {
|
||||
it('settings are for right app and version', () => {
|
||||
const settings = parseResponse?.settings;
|
||||
expect(settings.app).toBe('ontime');
|
||||
expect(settings.version).toBe(2);
|
||||
expect(settings.version).toEqual(expect.any(String));
|
||||
});
|
||||
|
||||
it('missing settings', () => {
|
||||
@@ -387,7 +387,7 @@ describe('test corrupt data', () => {
|
||||
},
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
serverPort: 4001,
|
||||
lock: null,
|
||||
timeFormat: '24',
|
||||
@@ -410,7 +410,7 @@ describe('test corrupt data', () => {
|
||||
},
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
serverPort: 4001,
|
||||
lock: null,
|
||||
timeFormat: '24',
|
||||
@@ -427,7 +427,7 @@ describe('test corrupt data', () => {
|
||||
project: {},
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
serverPort: 4001,
|
||||
lock: null,
|
||||
timeFormat: '24',
|
||||
@@ -444,7 +444,7 @@ describe('test corrupt data', () => {
|
||||
event: {},
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -734,7 +734,7 @@ describe('test aliases import', () => {
|
||||
rundown: [],
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
},
|
||||
aliases: [
|
||||
{
|
||||
@@ -773,7 +773,7 @@ describe('test userFields import', () => {
|
||||
rundown: [],
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
},
|
||||
userFields: testUserFields,
|
||||
};
|
||||
@@ -800,7 +800,7 @@ describe('test userFields import', () => {
|
||||
rundown: [],
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
},
|
||||
userFields: testUserFields,
|
||||
};
|
||||
@@ -814,7 +814,7 @@ describe('test userFields import', () => {
|
||||
rundown: [],
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -828,7 +828,7 @@ describe('test userFields import', () => {
|
||||
rundown: [],
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
},
|
||||
userFields: {
|
||||
notThis: 'this shouldng be accepted',
|
||||
@@ -847,7 +847,7 @@ describe('test views import', () => {
|
||||
rundown: [],
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
},
|
||||
viewSettings: {
|
||||
normalColor: '#ffffffcc',
|
||||
@@ -881,7 +881,7 @@ describe('test views import', () => {
|
||||
rundown: [],
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
},
|
||||
};
|
||||
const parsed = parseViewSettings(testData);
|
||||
|
||||
@@ -241,7 +241,7 @@ export const parseExcel = (excelData: unknown[][], options?: Partial<ExcelImport
|
||||
project: projectData,
|
||||
settings: {
|
||||
app: 'ontime',
|
||||
version: 2,
|
||||
version: '2.0.0',
|
||||
},
|
||||
userFields: customUserFields,
|
||||
};
|
||||
@@ -382,9 +382,6 @@ export const fileHandler = async (file: string, options: ExcelImportOptions): Pr
|
||||
let uploadedJson = null;
|
||||
|
||||
uploadedJson = JSON.parse(rawdata);
|
||||
if (uploadedJson.settings.version !== 2) {
|
||||
throw new Error(`Project version unknown ${uploadedJson.settings.version}`);
|
||||
}
|
||||
res.data = await parseJson(uploadedJson);
|
||||
|
||||
// delete file
|
||||
|
||||
@@ -114,6 +114,7 @@ export const parseSettings = (data): Settings => {
|
||||
console.log('ERROR: unknown app version, skipping');
|
||||
} else {
|
||||
const settings = {
|
||||
version: dbModel.settings.version,
|
||||
serverPort: s.serverPort || dbModel.settings.serverPort,
|
||||
editorKey: s.editorKey || null,
|
||||
operatorKey: s.operatorKey || null,
|
||||
|
||||
@@ -237,7 +237,7 @@
|
||||
},
|
||||
"settings": {
|
||||
"app": "ontime",
|
||||
"version": 2,
|
||||
"version": "2.0.0",
|
||||
"serverPort": 4001,
|
||||
"editorKey": null,
|
||||
"operatorKey": null,
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
},
|
||||
"settings": {
|
||||
"app": "ontime",
|
||||
"version": 2,
|
||||
"version": "2.0.0",
|
||||
"serverPort": 4001,
|
||||
"editorKey": null,
|
||||
"operatorKey": null,
|
||||
|
||||
+1
-1
@@ -413,7 +413,7 @@
|
||||
},
|
||||
"settings": {
|
||||
"app": "ontime",
|
||||
"version": 2,
|
||||
"version": "2.0.0",
|
||||
"serverPort": 4001,
|
||||
"editorKey": null,
|
||||
"operatorKey": null,
|
||||
|
||||
Vendored
+1
-1
@@ -103,7 +103,7 @@
|
||||
},
|
||||
"settings": {
|
||||
"app": "ontime",
|
||||
"version": 2,
|
||||
"version": "2.0.0",
|
||||
"serverPort": 4001,
|
||||
"editorKey": null,
|
||||
"operatorKey": null,
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { OSCSettings } from '../../definitions/core/OscSettings.type.js';
|
||||
|
||||
export type NetworkInterface = {
|
||||
name: string;
|
||||
address: string;
|
||||
};
|
||||
|
||||
export interface GetInfo {
|
||||
networkInterfaces: NetworkInterface[];
|
||||
version: string;
|
||||
serverPort: number;
|
||||
osc: OSCSettings;
|
||||
cssOverride: string;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { TimeFormat } from './TimeFormat.type';
|
||||
import { TimeFormat } from './TimeFormat.type.js';
|
||||
|
||||
export type Settings = {
|
||||
app: 'ontime';
|
||||
version: 2;
|
||||
version: string;
|
||||
serverPort: number;
|
||||
editorKey: null | string;
|
||||
operatorKey: null | string;
|
||||
|
||||
@@ -33,6 +33,9 @@ export type { OSCSettings, OscSubscription, OscSubscriptionOptions } from './def
|
||||
|
||||
// ---> HTTP
|
||||
|
||||
// SERVER RESPONSES
|
||||
export type { NetworkInterface, GetInfo } from './api/ontime-controller/BackendResponse.type.js';
|
||||
|
||||
// SERVER RUNTIME
|
||||
export { type Log, LogLevel, type LogMessage, LogOrigin } from './definitions/runtime/Logger.type.js';
|
||||
export { Playback } from './definitions/runtime/Playback.type.js';
|
||||
|
||||
Reference in New Issue
Block a user