mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-14 20:03:52 +00:00
Remove serverport from project file (#1957)
* feat: get server port from app satate or env optional startup port from env will always override function for parsing port from env populate default port in app state add test for migration * bump version
This commit is contained in:
committed by
GitHub
parent
1fe58e21be
commit
c1fcdf7065
@@ -1,5 +1,5 @@
|
||||
import axios, { AxiosResponse } from 'axios';
|
||||
import { Settings } from 'ontime-types';
|
||||
import { PortInfo, Settings } from 'ontime-types';
|
||||
|
||||
import { apiEntryUrl } from './constants';
|
||||
import type { RequestOptions } from './requestOptions';
|
||||
@@ -27,3 +27,18 @@ export async function postSettings(data: Settings): Promise<AxiosResponse<Settin
|
||||
export async function postShowWelcomeDialog(show: boolean) {
|
||||
axios.post(`${settingsPath}/welcomedialog`, { show });
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP request to retrieve server port
|
||||
*/
|
||||
export async function getServerPort(): Promise<PortInfo> {
|
||||
const res = await axios.get(`${settingsPath}/serverport`);
|
||||
return res.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP request to set server port
|
||||
*/
|
||||
export async function postServerPort(serverPort: number): Promise<AxiosResponse<PortInfo>> {
|
||||
return axios.post(`${settingsPath}/serverport`, { serverPort });
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Settings } from 'ontime-types';
|
||||
|
||||
export const ontimePlaceholderSettings: Settings = {
|
||||
version: '4.0.0',
|
||||
serverPort: 4001,
|
||||
editorKey: null,
|
||||
operatorKey: null,
|
||||
timeFormat: '24',
|
||||
|
||||
@@ -7,12 +7,9 @@ import { postSettings } from '../../../../common/api/settings';
|
||||
import { maybeAxiosError } from '../../../../common/api/utils';
|
||||
import Button from '../../../../common/components/buttons/Button';
|
||||
import Info from '../../../../common/components/info/Info';
|
||||
import Input from '../../../../common/components/input/input/Input';
|
||||
import Select from '../../../../common/components/select/Select';
|
||||
import useSettings from '../../../../common/hooks-query/useSettings';
|
||||
import { preventEscape } from '../../../../common/utils/keyEvent';
|
||||
import { isOnlyNumbers } from '../../../../common/utils/regex';
|
||||
import { isOntimeCloud } from '../../../../externals';
|
||||
import * as Panel from '../../panel-utils/PanelUtils';
|
||||
|
||||
import GeneralPinInput from './composite/GeneralPinInput';
|
||||
@@ -101,33 +98,6 @@ export default function GeneralSettings() {
|
||||
<Info>Changes to the time format and views language do not affect the editor view</Info>
|
||||
<Panel.Loader isLoading={isLoading} />
|
||||
<Panel.ListGroup>
|
||||
<Panel.ListItem>
|
||||
<Panel.Field
|
||||
title='Ontime server port'
|
||||
description={
|
||||
isOntimeCloud
|
||||
? 'Server port disabled for Ontime Cloud'
|
||||
: 'Port ontime server listens in. Defaults to 4001 (needs app restart)'
|
||||
}
|
||||
error={errors.serverPort?.message}
|
||||
/>
|
||||
<Input
|
||||
id='serverPort'
|
||||
type='number'
|
||||
maxLength={5}
|
||||
style={{ width: '75px' }}
|
||||
disabled={isOntimeCloud}
|
||||
{...register('serverPort', {
|
||||
required: { value: true, message: 'Required field' },
|
||||
max: { value: 65535, message: 'Port must be within range 1024 - 65535' },
|
||||
min: { value: 1024, message: 'Port must be within range 1024 - 65535' },
|
||||
pattern: {
|
||||
value: isOnlyNumbers,
|
||||
message: 'Value should be numeric',
|
||||
},
|
||||
})}
|
||||
/>
|
||||
</Panel.ListItem>
|
||||
<Panel.ListItem>
|
||||
<Panel.Field
|
||||
title='Editor pin code'
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { PortInfo } from 'ontime-types';
|
||||
|
||||
import { getServerPort, postServerPort } from '../../../../common/api/settings';
|
||||
import { maybeAxiosError } from '../../../../common/api/utils';
|
||||
import Button from '../../../../common/components/buttons/Button';
|
||||
import Input from '../../../../common/components/input/input/Input';
|
||||
import Tag from '../../../../common/components/tag/Tag';
|
||||
import { preventEscape } from '../../../../common/utils/keyEvent';
|
||||
import { isOnlyNumbers } from '../../../../common/utils/regex';
|
||||
import * as Panel from '../../panel-utils/PanelUtils';
|
||||
|
||||
interface ServerPortForm {
|
||||
serverPort: number;
|
||||
}
|
||||
|
||||
export default function ServerPortSettings() {
|
||||
const {
|
||||
handleSubmit,
|
||||
register,
|
||||
reset,
|
||||
setError,
|
||||
formState: { isSubmitting, isDirty, isValid, errors },
|
||||
} = useForm<ServerPortForm>({
|
||||
mode: 'onChange',
|
||||
defaultValues: { serverPort: 4001 },
|
||||
});
|
||||
|
||||
const [pendingRestart, setPendingRestart] = useState<boolean>(false);
|
||||
|
||||
const setPort = useCallback((info: PortInfo) => {
|
||||
reset({ serverPort: info.port });
|
||||
setPendingRestart(info.pendingRestart);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
getServerPort()
|
||||
.then(setPort)
|
||||
.catch(() => setError('root', { message: 'Failed to load server port' }));
|
||||
}, [reset, setError, setPort]);
|
||||
|
||||
const onSubmit = async (formData: ServerPortForm) => {
|
||||
if (formData.serverPort < 1024 || formData.serverPort > 65535) {
|
||||
setError('serverPort', { message: 'Port must be within range 1024 - 65535' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await postServerPort(formData.serverPort);
|
||||
setPort(await getServerPort());
|
||||
} catch (error) {
|
||||
setError('root', { message: maybeAxiosError(error) });
|
||||
}
|
||||
};
|
||||
|
||||
const onReset = async () => {
|
||||
try {
|
||||
setPort(await getServerPort());
|
||||
} catch (error) {
|
||||
setError('root', { message: 'Failed to load server port' });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Panel.Section
|
||||
as='form'
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
onKeyDown={(event) => preventEscape(event, onReset)}
|
||||
id='server-port-settings'
|
||||
>
|
||||
<Panel.Card>
|
||||
<Panel.SubHeader>
|
||||
Server port
|
||||
<Panel.InlineElements>
|
||||
{pendingRestart && <Tag>A port change is pending and will happen on the next restart</Tag>}
|
||||
<Button disabled={!isDirty || isSubmitting} variant='ghosted' onClick={onReset}>
|
||||
Revert to saved
|
||||
</Button>
|
||||
<Button
|
||||
type='submit'
|
||||
form='server-port-settings'
|
||||
name='server-port-settings-submit'
|
||||
loading={isSubmitting}
|
||||
disabled={!isDirty || !isValid || isSubmitting}
|
||||
variant='primary'
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Panel.InlineElements>
|
||||
</Panel.SubHeader>
|
||||
{errors.root && <Panel.Error>{errors.root.message}</Panel.Error>}
|
||||
<Panel.Divider />
|
||||
<Panel.Section>
|
||||
<Panel.ListGroup>
|
||||
<Panel.ListItem>
|
||||
<Panel.Field
|
||||
title='Ontime server port'
|
||||
description='Port ontime server listens in. Defaults to 4001 (needs app restart)'
|
||||
error={errors.serverPort?.message}
|
||||
/>
|
||||
<Input
|
||||
id='serverPort'
|
||||
type='number'
|
||||
maxLength={5}
|
||||
style={{ width: '75px' }}
|
||||
{...register('serverPort', {
|
||||
required: { value: true, message: 'Required field' },
|
||||
max: { value: 65535, message: 'Port must be within range 1024 - 65535' },
|
||||
min: { value: 1024, message: 'Port must be within range 1024 - 65535' },
|
||||
pattern: {
|
||||
value: isOnlyNumbers,
|
||||
message: 'Value should be numeric',
|
||||
},
|
||||
})}
|
||||
/>
|
||||
</Panel.ListItem>
|
||||
</Panel.ListGroup>
|
||||
</Panel.Section>
|
||||
</Panel.Card>
|
||||
</Panel.Section>
|
||||
);
|
||||
}
|
||||
@@ -1,14 +1,17 @@
|
||||
import useScrollIntoView from '../../../../common/hooks/useScrollIntoView';
|
||||
import { isDocker } from '../../../../externals';
|
||||
import type { PanelBaseProps } from '../../panel-list/PanelList';
|
||||
import * as Panel from '../../panel-utils/PanelUtils';
|
||||
|
||||
import GeneralSettings from './GeneralSettings';
|
||||
import ProjectData from './ProjectData';
|
||||
import ServerPortSettings from './ServerPortSettings';
|
||||
import ViewSettings from './ViewSettings';
|
||||
|
||||
export default function SettingsPanel({ location }: PanelBaseProps) {
|
||||
const dataRef = useScrollIntoView<HTMLDivElement>('data', location);
|
||||
const generalRef = useScrollIntoView<HTMLDivElement>('general', location);
|
||||
const portRef = useScrollIntoView<HTMLDivElement>('port', location);
|
||||
const viewRef = useScrollIntoView<HTMLDivElement>('view', location);
|
||||
|
||||
return (
|
||||
@@ -23,6 +26,11 @@ export default function SettingsPanel({ location }: PanelBaseProps) {
|
||||
<div ref={viewRef}>
|
||||
<ViewSettings />
|
||||
</div>
|
||||
{!isDocker && (
|
||||
<div ref={portRef}>
|
||||
<ServerPortSettings />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import useAppVersion from '../../common/hooks-query/useAppVersion';
|
||||
import { isDocker } from '../../externals';
|
||||
|
||||
export type SettingsOption = {
|
||||
id: string;
|
||||
@@ -18,6 +19,7 @@ const staticOptions = [
|
||||
{ id: 'settings__data', label: 'Project data' },
|
||||
{ id: 'settings__general', label: 'General settings' },
|
||||
{ id: 'settings__view', label: 'View settings' },
|
||||
{ id: 'settings__port', label: 'Server Port' },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -102,6 +104,14 @@ export function useAppSettingsMenu() {
|
||||
() =>
|
||||
staticOptions.map((option) => ({
|
||||
...option,
|
||||
// if we are in docker don't show the port option
|
||||
secondary:
|
||||
'secondary' in option
|
||||
? isDocker && option.id === 'settings'
|
||||
? [...option.secondary.filter(({ id }) => id !== 'settings__port')]
|
||||
: [...option.secondary]
|
||||
: undefined,
|
||||
// if there is an update then highlight the about setting
|
||||
highlight: option.id === 'about' && data.hasUpdates ? 'New version available' : undefined,
|
||||
})),
|
||||
[data],
|
||||
|
||||
Reference in New Issue
Block a user