fixes for various admin issues (#181)
* up max char count for variant name to fix https://github.com/owncast/owncast/issues/1037 * max widthing the line chart canvas size so it scales with the page. fixes - https://github.com/owncast/owncast/issues/842 - https://github.com/owncast/owncast/issues/1024 * A fix to make Storage Endpoint URL validation have better feedback. - give the field a type of "url" - give the field a pattern to check - have native browser handle the validation - if the field is invalid, use :invalid selector to turn the text red on blur. fixes: https://github.com/owncast/owncast/issues/1000 * a fix for https://github.com/owncast/owncast/issues/874 * - fixes for https://github.com/owncast/owncast/issues/972 Add optional prop to text field to trim() whitespaces from field. Apply logic to mostly url fields. - move textfield blur if invalid turn red to globaal * - a fix for bug: https://github.com/owncast/owncast/issues/998 don't return null if platform name not found because its custom. - clean up react key problem on socialhandles table * fix react key issue on Actions table * fix for https://github.com/owncast/owncast/issues/1008 to display 'other' field when editing an item not in predefined social list * clean up other potential react key warnings * Prettified Code! Co-authored-by: gingervitis <gingervitis@users.noreply.github.com>
This commit is contained in:
@@ -4,7 +4,7 @@ import React, { useState, useEffect, useContext } from 'react';
|
||||
import { Table, Space, Button, Modal, Checkbox, Input, Typography } from 'antd';
|
||||
import { ServerStatusContext } from '../utils/server-status-context';
|
||||
import { DeleteOutlined } from '@ant-design/icons';
|
||||
import isValidUrl from '../utils/urls';
|
||||
import isValidUrl, { DEFAULT_TEXTFIELD_URL_PATTERN } from '../utils/urls';
|
||||
import FormStatusIndicator from '../components/config/form-status-indicator';
|
||||
import {
|
||||
createInputStatus,
|
||||
@@ -41,12 +41,12 @@ function NewActionModal(props: Props) {
|
||||
|
||||
function save() {
|
||||
onOk(actionUrl, actionTitle, actionDescription, actionIcon, actionColor, openExternally);
|
||||
setActionUrl('')
|
||||
setActionTitle('')
|
||||
setActionDescription('')
|
||||
setActionIcon('')
|
||||
setActionColor('')
|
||||
setOpenExternally(false)
|
||||
setActionUrl('');
|
||||
setActionTitle('');
|
||||
setActionDescription('');
|
||||
setActionIcon('');
|
||||
setActionColor('');
|
||||
setOpenExternally(false);
|
||||
}
|
||||
|
||||
function canSave(): Boolean {
|
||||
@@ -91,7 +91,9 @@ function NewActionModal(props: Props) {
|
||||
value={actionUrl}
|
||||
required
|
||||
placeholder="https://myserver.com/action (required)"
|
||||
onChange={input => setActionUrl(input.currentTarget.value)}
|
||||
onChange={input => setActionUrl(input.currentTarget.value.trim())}
|
||||
type="url"
|
||||
pattern={DEFAULT_TEXTFIELD_URL_PATTERN}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
@@ -184,7 +186,7 @@ export default function Actions() {
|
||||
dataIndex: 'icon',
|
||||
key: 'icon',
|
||||
render: (url: string) => {
|
||||
return url ? <img style={{width: '2vw'}} src={url} /> : null;
|
||||
return url ? <img style={{ width: '2vw' }} src={url} /> : null;
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -289,11 +291,22 @@ export default function Actions() {
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
Read more about how to use actions, with examples, at{' '}
|
||||
<a href="https://owncast.online/thirdparty/?source=admin" target="_blank"
|
||||
rel="noopener noreferrer">our documentation</a>.
|
||||
<a
|
||||
href="https://owncast.online/thirdparty/?source=admin"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
our documentation
|
||||
</a>
|
||||
.
|
||||
</Paragraph>
|
||||
|
||||
<Table rowKey="id" columns={columns} dataSource={actions} pagination={false} />
|
||||
<Table
|
||||
rowKey={record => `${record.title}-${record.url}`}
|
||||
columns={columns}
|
||||
dataSource={actions}
|
||||
pagination={false}
|
||||
/>
|
||||
<br />
|
||||
<Button type="primary" onClick={showCreateModal}>
|
||||
Create New Action
|
||||
|
||||
@@ -37,7 +37,7 @@ export default function ConfigVideoSettings() {
|
||||
<VideoLatency />
|
||||
</div>
|
||||
|
||||
<Collapse className="advanced-settings">
|
||||
<Collapse className="advanced-settings codec-module">
|
||||
<Panel header="Advanced Settings" key="1">
|
||||
<div className="form-module variants-table-module">
|
||||
<VideoCodecSelector />
|
||||
|
||||
@@ -75,7 +75,7 @@ export default function HardwareInfo() {
|
||||
<Col>
|
||||
<StatisticItem
|
||||
title={series[0].name}
|
||||
value={`${currentCPUUsage}`}
|
||||
value={`${currentCPUUsage || 0}`}
|
||||
prefix={<LaptopOutlined style={{ color: series[0].color }} />}
|
||||
color={series[0].color}
|
||||
progress
|
||||
@@ -85,7 +85,7 @@ export default function HardwareInfo() {
|
||||
<Col>
|
||||
<StatisticItem
|
||||
title={series[1].name}
|
||||
value={`${currentRamUsage}`}
|
||||
value={`${currentRamUsage || 0}`}
|
||||
prefix={<BulbOutlined style={{ color: series[1].color }} />}
|
||||
color={series[1].color}
|
||||
progress
|
||||
@@ -95,7 +95,7 @@ export default function HardwareInfo() {
|
||||
<Col>
|
||||
<StatisticItem
|
||||
title={series[2].name}
|
||||
value={`${currentDiskUsage}`}
|
||||
value={`${currentDiskUsage || 0}`}
|
||||
prefix={<SaveOutlined style={{ color: series[2].color }} />}
|
||||
color={series[2].color}
|
||||
progress
|
||||
|
||||
@@ -205,8 +205,8 @@ export default function Help() {
|
||||
<Title level={2}>Common tasks</Title>
|
||||
<Row gutter={[16, 16]}>
|
||||
{questions.map(question => (
|
||||
<Col xs={24} lg={12}>
|
||||
<Card key={question.title}>
|
||||
<Col xs={24} lg={12} key={question.title}>
|
||||
<Card>
|
||||
<Meta avatar={question.icon} title={question.title} description={question.content} />
|
||||
</Card>
|
||||
</Col>
|
||||
@@ -216,8 +216,8 @@ export default function Help() {
|
||||
<Title level={2}>Other</Title>
|
||||
<Row gutter={[16, 16]}>
|
||||
{otherResources.map(question => (
|
||||
<Col xs={24} lg={12}>
|
||||
<Card key={question.title}>
|
||||
<Col xs={24} lg={12} key={question.title}>
|
||||
<Card>
|
||||
<Meta avatar={question.icon} title={question.title} description={question.content} />
|
||||
</Card>
|
||||
</Col>
|
||||
|
||||
@@ -23,7 +23,15 @@ function AssetTable(assets) {
|
||||
},
|
||||
];
|
||||
|
||||
return <Table dataSource={data} columns={columns} rowKey="id" size="large" pagination={false} />;
|
||||
return (
|
||||
<Table
|
||||
dataSource={data}
|
||||
columns={columns}
|
||||
rowKey={record => record.id}
|
||||
size="large"
|
||||
pagination={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Logs() {
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
Col,
|
||||
} from 'antd';
|
||||
import { DeleteOutlined } from '@ant-design/icons';
|
||||
import isValidUrl from '../utils/urls';
|
||||
import isValidUrl, { DEFAULT_TEXTFIELD_URL_PATTERN } from '../utils/urls';
|
||||
|
||||
import { fetchData, DELETE_WEBHOOK, CREATE_WEBHOOK, WEBHOOKS } from '../utils/apis';
|
||||
|
||||
@@ -86,7 +86,11 @@ function NewWebhookModal(props: Props) {
|
||||
};
|
||||
|
||||
const checkboxes = events.map(function (singleEvent) {
|
||||
return (<Col span={8} key={singleEvent.value}><Checkbox value={singleEvent.value}>{singleEvent.label}</Checkbox></Col>)
|
||||
return (
|
||||
<Col span={8} key={singleEvent.value}>
|
||||
<Checkbox value={singleEvent.value}>{singleEvent.label}</Checkbox>
|
||||
</Col>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
@@ -101,15 +105,15 @@ function NewWebhookModal(props: Props) {
|
||||
<Input
|
||||
value={webhookUrl}
|
||||
placeholder="https://myserver.com/webhook"
|
||||
onChange={input => setWebhookUrl(input.currentTarget.value)}
|
||||
onChange={input => setWebhookUrl(input.currentTarget.value.trim())}
|
||||
type="url"
|
||||
pattern={DEFAULT_TEXTFIELD_URL_PATTERN}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<p>Select the events that will be sent to this webhook.</p>
|
||||
<Checkbox.Group style={{ width: '100%' }} value={selectedEvents} onChange={onChange}>
|
||||
<Row>
|
||||
{checkboxes}
|
||||
</Row>
|
||||
<Row>{checkboxes}</Row>
|
||||
</Checkbox.Group>
|
||||
<p>
|
||||
<Button type="primary" onClick={selectAll}>
|
||||
@@ -225,7 +229,12 @@ export default function Webhooks() {
|
||||
.
|
||||
</Paragraph>
|
||||
|
||||
<Table rowKey="id" columns={columns} dataSource={webhooks} pagination={false} />
|
||||
<Table
|
||||
rowKey={record => record.id}
|
||||
columns={columns}
|
||||
dataSource={webhooks}
|
||||
pagination={false}
|
||||
/>
|
||||
<br />
|
||||
<Button type="primary" onClick={showCreateModal}>
|
||||
Create Webhook
|
||||
|
||||
Reference in New Issue
Block a user