rename status file for clarity; temp style fix for streamkey actions

This commit is contained in:
gingervitis 2021-02-01 00:36:27 -08:00
parent a69cfd7abf
commit 3488a259bd
9 changed files with 77 additions and 45 deletions

View File

@ -64,23 +64,27 @@ export default function EditInstanceDetails() {
return ( return (
<div className="edit-public-details-container"> <div className="edit-public-details-container">
<TextFieldWithSubmit <div className="field-container field-streamkey-container">
fieldName="streamKey" <div className="left-side">
{...TEXTFIELD_PROPS_STREAM_KEY} <TextFieldWithSubmit
value={formDataValues.streamKey} fieldName="streamKey"
initialValue={streamKey} {...TEXTFIELD_PROPS_STREAM_KEY}
type={TEXTFIELD_TYPE_PASSWORD} value={formDataValues.streamKey}
onChange={handleFieldChange} initialValue={streamKey}
/> type={TEXTFIELD_TYPE_PASSWORD}
<div> onChange={handleFieldChange}
<span style={{ fontSize: '0.75em', color: '#ff7777', marginRight: '0.5em' }}> />
<div className="streamkey-actions">
<Tooltip className="copy-tooltip" title="Copied!" trigger="" visible={copyIsVisible}>
<Button icon={<CopyOutlined />} size="small" onClick={copyStreamKey} />
</Tooltip>
<Button icon={<RedoOutlined />} size="small" onClick={generateStreamKey} />
</div>
</div>
<div className="streamkey-notice">
Save this key somewhere safe, you will need it to stream or login to the admin Save this key somewhere safe, you will need it to stream or login to the admin
dashboard! dashboard!
</span> </div>
<Tooltip className="copy-tooltip" title="Copied!" trigger="" visible={copyIsVisible}>
<Button type="primary" icon={<CopyOutlined />} size="small" onClick={copyStreamKey} />
</Tooltip>
<Button type="primary" icon={<RedoOutlined />} size="small" onClick={generateStreamKey} />
</div> </div>
<TextFieldWithSubmit <TextFieldWithSubmit
fieldName="ffmpegPath" fieldName="ffmpegPath"

View File

@ -16,7 +16,7 @@ import { SocialHandle, UpdateArgs } from '../../../types/config-section';
import { isValidUrl } from '../../../utils/urls'; import { isValidUrl } from '../../../utils/urls';
import TextField from './form-textfield'; import TextField from './form-textfield';
import { createInputStatus, STATUS_ERROR, STATUS_SUCCESS } from '../../../utils/input-statuses'; import { createInputStatus, STATUS_ERROR, STATUS_SUCCESS } from '../../../utils/input-statuses';
import InputStatusInfo from './input-status-info'; import FormStatusIndicator from './form-status-indicator';
const { Title } = Typography; const { Title } = Typography;
@ -229,7 +229,7 @@ export default function EditSocialLinks() {
<Title level={2}>Social Links</Title> <Title level={2}>Social Links</Title>
<p>Add all your social media handles and links to your other profiles here.</p> <p>Add all your social media handles and links to your other profiles here.</p>
<InputStatusInfo status={submitStatus} /> <FormStatusIndicator status={submitStatus} />
<Table <Table
className="dataTable" className="dataTable"
@ -271,7 +271,7 @@ export default function EditSocialLinks() {
value={modalDataState.url} value={modalDataState.url}
onChange={handleUrlChange} onChange={handleUrlChange}
/> />
<InputStatusInfo status={submitStatus} /> <FormStatusIndicator status={submitStatus} />
</Modal> </Modal>
<br /> <br />
<Button <Button

View File

@ -17,7 +17,7 @@ import {
STATUS_SUCCESS, STATUS_SUCCESS,
} from '../../../utils/input-statuses'; } from '../../../utils/input-statuses';
import TextField from './form-textfield'; import TextField from './form-textfield';
import InputStatusInfo from './input-status-info'; import FormStatusIndicator from './form-status-indicator';
const { Panel } = Collapse; const { Panel } = Collapse;
@ -211,7 +211,7 @@ export default function EditStorage() {
<Button type="primary" onClick={handleSave} disabled={!isSaveable}> <Button type="primary" onClick={handleSave} disabled={!isSaveable}>
Save Save
</Button> </Button>
<InputStatusInfo status={submitStatus} /> <FormStatusIndicator status={submitStatus} />
</div> </div>
</div> </div>
); );

View File

@ -3,10 +3,10 @@ import classNames from 'classnames';
import { StatusState } from '../../../utils/input-statuses'; import { StatusState } from '../../../utils/input-statuses';
interface InputStatusInfoProps { interface FormStatusIndicatorProps {
status: StatusState; status: StatusState;
} }
export default function InputStatusInfo({ status }: InputStatusInfoProps) { export default function FormStatusIndicator({ status }: FormStatusIndicatorProps) {
const { type, icon, message } = status || {}; const { type, icon, message } = status || {};
const classes = classNames({ const classes = classNames({
'status-container': true, 'status-container': true,

View File

@ -13,7 +13,7 @@ import {
STATUS_SUCCESS, STATUS_SUCCESS,
} from '../../../utils/input-statuses'; } from '../../../utils/input-statuses';
import { UpdateArgs } from '../../../types/config-section'; import { UpdateArgs } from '../../../types/config-section';
import InputStatusInfo from './input-status-info'; import FormStatusIndicator from './form-status-indicator';
export const TEXTFIELD_TYPE_TEXT = 'default'; export const TEXTFIELD_TYPE_TEXT = 'default';
export const TEXTFIELD_TYPE_PASSWORD = 'password'; // Input.Password export const TEXTFIELD_TYPE_PASSWORD = 'password'; // Input.Password
@ -124,7 +124,7 @@ export default function TextFieldWithSubmit(props: TextFieldWithSubmitProps) {
<p className="label-spacer" /> <p className="label-spacer" />
<div className="lower-content"> <div className="lower-content">
<div className="field-tip">{tip}</div> <div className="field-tip">{tip}</div>
<InputStatusInfo status={status || submitStatus} /> <FormStatusIndicator status={status || submitStatus} />
<div className="update-button-container"> <div className="update-button-container">
<Button <Button
type="primary" type="primary"

View File

@ -4,7 +4,7 @@ import { Input, InputNumber } from 'antd';
import { FieldUpdaterFunc } from '../../../types/config-section'; import { FieldUpdaterFunc } from '../../../types/config-section';
// import InfoTip from '../info-tip'; // import InfoTip from '../info-tip';
import { StatusState } from '../../../utils/input-statuses'; import { StatusState } from '../../../utils/input-statuses';
import InputStatusInfo from './input-status-info'; import FormStatusIndicator from './form-status-indicator';
export const TEXTFIELD_TYPE_TEXT = 'default'; export const TEXTFIELD_TYPE_TEXT = 'default';
export const TEXTFIELD_TYPE_PASSWORD = 'password'; // Input.Password export const TEXTFIELD_TYPE_PASSWORD = 'password'; // Input.Password
@ -143,7 +143,7 @@ export default function TextField(props: TextFieldProps) {
value={value} value={value}
/> />
</div> </div>
<InputStatusInfo status={status} /> <FormStatusIndicator status={status} />
<p className="field-tip"> <p className="field-tip">
{tip} {tip}
{/* <InfoTip tip={tip} /> */} {/* <InfoTip tip={tip} /> */}

View File

@ -7,7 +7,7 @@ import {
STATUS_PROCESSING, STATUS_PROCESSING,
STATUS_SUCCESS, STATUS_SUCCESS,
} from '../../../utils/input-statuses'; } from '../../../utils/input-statuses';
import InputStatusInfo from './input-status-info'; import FormStatusIndicator from './form-status-indicator';
import { RESET_TIMEOUT, postConfigUpdateToAPI } from './constants'; import { RESET_TIMEOUT, postConfigUpdateToAPI } from './constants';
@ -76,7 +76,7 @@ export default function ToggleSwitch(props: ToggleSwitchProps) {
{label} <InfoTip tip={tip} /> {label} <InfoTip tip={tip} />
</span> </span>
</div> </div>
<InputStatusInfo status={submitStatus} /> <FormStatusIndicator status={submitStatus} />
</div> </div>
); );
} }

View File

@ -1,6 +1,5 @@
import React, { useState, useEffect, useContext } from 'react'; import React, { useState, useEffect, useContext } from 'react';
import { Typography, Button } from 'antd'; import { Typography, Button } from 'antd';
import { FormItemProps } from 'antd/lib/form';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import MarkdownIt from 'markdown-it'; import MarkdownIt from 'markdown-it';
@ -8,11 +7,17 @@ import { ServerStatusContext } from '../utils/server-status-context';
import { import {
postConfigUpdateToAPI, postConfigUpdateToAPI,
RESET_TIMEOUT, RESET_TIMEOUT,
SUCCESS_STATES,
API_CUSTOM_CONTENT, API_CUSTOM_CONTENT,
} from './components/config/constants'; } from './components/config/constants';
import {
createInputStatus,
StatusState,
STATUS_ERROR,
STATUS_PROCESSING,
STATUS_SUCCESS,
} from '../utils/input-statuses';
import 'react-markdown-editor-lite/lib/index.css'; import 'react-markdown-editor-lite/lib/index.css';
import FormStatusIndicator from './components/config/form-status-indicator';
const { Title } = Typography; const { Title } = Typography;
@ -24,8 +29,7 @@ const MdEditor = dynamic(() => import('react-markdown-editor-lite'), {
export default function PageContentEditor() { export default function PageContentEditor() {
const [content, setContent] = useState(''); const [content, setContent] = useState('');
const [submitStatus, setSubmitStatus] = useState<FormItemProps['validateStatus']>(''); const [submitStatus, setSubmitStatus] = useState<StatusState>(null);
const [submitStatusMessage, setSubmitStatusMessage] = useState('');
const [hasChanged, setHasChanged] = useState(false); const [hasChanged, setHasChanged] = useState(false);
const serverStatusData = useContext(ServerStatusContext); const serverStatusData = useContext(ServerStatusContext);
@ -47,7 +51,7 @@ export default function PageContentEditor() {
// Clear out any validation states and messaging // Clear out any validation states and messaging
const resetStates = () => { const resetStates = () => {
setSubmitStatus(''); setSubmitStatus(null);
setHasChanged(false); setHasChanged(false);
clearTimeout(resetTimer); clearTimeout(resetTimer);
resetTimer = null; resetTimer = null;
@ -55,21 +59,20 @@ export default function PageContentEditor() {
// posts all the tags at once as an array obj // posts all the tags at once as an array obj
async function handleSave() { async function handleSave() {
setSubmitStatus('validating'); setSubmitStatus(createInputStatus(STATUS_PROCESSING));
await postConfigUpdateToAPI({ await postConfigUpdateToAPI({
apiPath: API_CUSTOM_CONTENT, apiPath: API_CUSTOM_CONTENT,
data: { value: content }, data: { value: content },
onSuccess: () => { onSuccess: (message: string) => {
setFieldInConfigState({ setFieldInConfigState({
fieldName: 'extraPageContent', fieldName: 'extraPageContent',
value: content, value: content,
path: 'instanceDetails', path: 'instanceDetails',
}); });
setSubmitStatus('success'); setSubmitStatus(createInputStatus(STATUS_SUCCESS, message));
}, },
onError: (message: string) => { onError: (message: string) => {
setSubmitStatus('error'); setSubmitStatus(createInputStatus(STATUS_ERROR, message));
setSubmitStatusMessage(`There was an error: ${message}`);
}, },
}); });
resetTimer = setTimeout(resetStates, RESET_TIMEOUT); resetTimer = setTimeout(resetStates, RESET_TIMEOUT);
@ -79,9 +82,6 @@ export default function PageContentEditor() {
setContent(initialContent); setContent(initialContent);
}, [instanceDetails]); }, [instanceDetails]);
const { icon: newStatusIcon = null, message: newStatusMessage = '' } =
SUCCESS_STATES[submitStatus] || {};
return ( return (
<div className="config-page-content-form"> <div className="config-page-content-form">
<Title level={2}>Edit custom content</Title> <Title level={2}>Edit custom content</Title>
@ -107,9 +107,8 @@ export default function PageContentEditor() {
Save Save
</Button> </Button>
) : null} ) : null}
<div className={`status-message ${submitStatus || ''}`}> <FormStatusIndicator status={submitStatus} />
{newStatusIcon} {newStatusMessage} {submitStatusMessage}
</div>
</div> </div>
</div> </div>
); );

View File

@ -351,3 +351,32 @@
background-color: rgba(0,0,0,.25); background-color: rgba(0,0,0,.25);
} }
} }
.field-streamkey-container {
.left-side {
display: flex;
flex-direction: row;
align-items: flex-start;
}
.textfield-with-submit-container {
margin-bottom: 0;
.textfield-container {
max-width: 400px;
}
}
.streamkey-actions {
max-width: 90px;
button {
margin: .25em;
}
}
.streamkey-notice {
font-size: 0.75em;
color: var(--ant-error);
margin-left: 12em;
margin-bottom: 1em;
}
}