support settings array (#40103)

This commit is contained in:
An 2021-10-06 15:55:54 -04:00 committed by GitHub
parent 3db98f417d
commit 6567462de9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 89 additions and 27 deletions

View File

@ -12,7 +12,7 @@ export function AddNewRule({ onClose }: Props) {
.post(`api/live/channel-rules`, {
pattern: formData.pattern,
settings: {
output: formData.settings.output,
output: formData.settings.frameOutputs,
converter: formData.settings.converter,
},
})
@ -31,9 +31,11 @@ export function AddNewRule({ onClose }: Props) {
converter: {
type: 'jsonAuto',
},
output: {
type: 'managedStream',
},
frameOutputs: [
{
type: 'managedStream',
},
],
},
}}
onSubmit={onSubmit}

View File

@ -13,9 +13,6 @@ function renderOutputTags(key: string, output?: Output): React.ReactNode {
if (!output?.type) {
return null;
}
if (output.multiple?.outputs?.length) {
return output.multiple?.outputs.map((v, i) => renderOutputTags(`${key}-${i}`, v));
}
return <Tag key={key} name={output.type} />;
}
@ -47,7 +44,9 @@ export default function PipelineAdminPage() {
const onRowClick = (event: any) => {
const pattern = event.target.getAttribute('data-pattern');
const column = event.target.getAttribute('data-column');
if (column) {
if (column === 'pattern') {
setClickColumn('converter');
} else {
setClickColumn(column);
}
setSelectedRule(rules.filter((rule) => rule.pattern === pattern)[0]);
@ -99,10 +98,14 @@ export default function PipelineAdminPage() {
{rule.settings?.converter?.type}
</td>
<td data-pattern={rule.pattern} data-column="processor">
{rule.settings?.processor?.type}
{rule.settings?.frameProcessors?.map((processor) => (
<span key={rule.pattern + processor.type}>{processor.type}</span>
))}
</td>
<td data-pattern={rule.pattern} data-column="output">
{renderOutputTags('out', rule.settings?.output)}
{rule.settings?.frameOutputs?.map((output) => (
<span key={rule.pattern + output.type}>{renderOutputTags('out', output)}</span>
))}
</td>
<td>
<IconButton name="trash-alt" onClick={() => onRemoveRule(rule.pattern)}></IconButton>

View File

@ -6,6 +6,7 @@ import { css } from '@emotion/css';
import { GrafanaTheme } from '@grafana/data';
import { RuleSettingsEditor } from './RuleSettingsEditor';
import { getPipeLineEntities } from './utils';
import { RuleSettingsArray } from './RuleSettingsArray';
interface Props {
rule: Rule;
@ -19,8 +20,8 @@ interface TabType {
}
const tabs: TabType[] = [
{ label: 'Converter', value: 'converter' },
{ label: 'Processor', value: 'processor' },
{ label: 'Output', value: 'output' },
{ label: 'Processors', value: 'frameProcessors' },
{ label: 'Outputs', value: 'frameOutputs' },
];
export const RuleModal: React.FC<Props> = (props) => {
@ -33,7 +34,7 @@ export const RuleModal: React.FC<Props> = (props) => {
const [entitiesInfo, setEntitiesInfo] = useState<PipeLineEntitiesInfo>();
const styles = useStyles(getStyles);
const onRuleSettingChange = (value: RuleSetting) => {
const onRuleSettingChange = (value: RuleSetting | RuleSetting[]) => {
setChange(true);
setRule({
...rule,
@ -57,6 +58,7 @@ export const RuleModal: React.FC<Props> = (props) => {
.put(`api/live/channel-rules`, rule)
.then(() => {
setChange(false);
onClose();
})
.catch((e) => console.error(e));
};
@ -80,7 +82,7 @@ export const RuleModal: React.FC<Props> = (props) => {
})}
</TabsBar>
<TabContent>
{entitiesInfo && rule && (
{entitiesInfo && rule && activeTab === 'converter' && (
<RuleSettingsEditor
onChange={onRuleSettingChange}
value={ruleSetting}
@ -88,6 +90,14 @@ export const RuleModal: React.FC<Props> = (props) => {
entitiesInfo={entitiesInfo}
/>
)}
{entitiesInfo && rule && activeTab !== 'converter' && (
<RuleSettingsArray
onChange={onRuleSettingChange}
value={ruleSetting}
ruleType={activeTab}
entitiesInfo={entitiesInfo}
/>
)}
<Button onClick={onSave} className={styles.save} variant={hasChange ? 'primary' : 'secondary'}>
Save
</Button>

View File

@ -0,0 +1,50 @@
import React, { useState } from 'react';
import { RuleSettingsEditor } from './RuleSettingsEditor';
import { RuleType, RuleSetting, PipeLineEntitiesInfo } from './types';
import { Select } from '@grafana/ui';
import { SelectableValue } from '../../../../../packages/grafana-data/src';
interface Props {
ruleType: RuleType;
onChange: (value: RuleSetting[]) => void;
value: RuleSetting[];
entitiesInfo: PipeLineEntitiesInfo;
}
export const RuleSettingsArray: React.FC<Props> = ({ onChange, value, ruleType, entitiesInfo }) => {
const [index, setIndex] = useState<number>(0);
const arr = value ?? [];
const onRuleChange = (v: RuleSetting) => {
if (!value) {
onChange([v]);
} else {
const copy = [...value];
copy[index] = v;
onChange(copy);
}
};
// create array of value.length + 1
let indexArr: Array<SelectableValue<number>> = [];
for (let i = 0; i <= arr.length; i++) {
indexArr.push({
label: `${ruleType}: ${i}`,
value: i,
});
}
return (
<>
<Select
placeholder="Select an index"
menuShouldPortal={true}
options={indexArr}
value={index}
onChange={(index) => {
// set index to find the correct setting
setIndex(index.value!);
}}
></Select>
<RuleSettingsEditor onChange={onRuleChange} value={arr[index]} ruleType={ruleType} entitiesInfo={entitiesInfo} />
</>
);
};

View File

@ -9,9 +9,6 @@ export interface Processor extends RuleSetting {
export interface Output extends RuleSetting {
[t: string]: any;
multiple?: {
outputs: Output[];
};
}
export interface RuleSetting<T = any> {
@ -20,8 +17,8 @@ export interface RuleSetting<T = any> {
}
export interface RuleSettings {
converter?: Converter;
processor?: Processor;
output?: Output;
frameProcessors?: Processor[];
frameOutputs?: Output[];
}
export interface Rule {
@ -38,22 +35,22 @@ export interface GrafanaCloudBackend {
settings: any;
}
export type RuleType = 'converter' | 'processor' | 'output';
export type RuleType = 'converter' | 'frameProcessors' | 'frameOutputs';
export interface PipelineListOption {
type: string;
description: string;
example: object;
example?: object;
}
export interface EntitiesTypes {
converters: PipelineListOption[];
processors: PipelineListOption[];
outputs: PipelineListOption[];
frameProcessors: PipelineListOption[];
frameOutputs: PipelineListOption[];
}
export interface PipeLineEntitiesInfo {
converter: SelectableValue[];
processor: SelectableValue[];
output: SelectableValue[];
frameProcessors: SelectableValue[];
frameOutputs: SelectableValue[];
getExample: (rule: RuleType, type: string) => object;
}

View File

@ -7,8 +7,8 @@ export async function getPipeLineEntities(): Promise<PipeLineEntitiesInfo> {
.then((data) => {
return {
converter: transformLabel(data, 'converters'),
processor: transformLabel(data, 'processors'),
output: transformLabel(data, 'outputs'),
frameProcessors: transformLabel(data, 'frameProcessors'),
frameOutputs: transformLabel(data, 'frameOutputs'),
getExample: (ruleType, type) => {
return data[`${ruleType}s`]?.filter((option: PipelineListOption) => option.type === type)?.[0]?.['example'];
},