RuleModal.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import { css } from '@emotion/css';
  2. import React, { useState, useMemo } from 'react';
  3. import { GrafanaTheme } from '@grafana/data';
  4. import { getBackendSrv } from '@grafana/runtime';
  5. import { Modal, TabContent, TabsBar, Tab, Button, useStyles } from '@grafana/ui';
  6. import { RuleSettingsArray } from './RuleSettingsArray';
  7. import { RuleSettingsEditor } from './RuleSettingsEditor';
  8. import { RuleTest } from './RuleTest';
  9. import { Rule, RuleType, PipeLineEntitiesInfo, RuleSetting } from './types';
  10. import { getPipeLineEntities } from './utils';
  11. interface Props {
  12. rule: Rule;
  13. isOpen: boolean;
  14. onClose: () => void;
  15. clickColumn: RuleType;
  16. }
  17. interface TabInfo {
  18. label: string;
  19. type?: RuleType;
  20. isTest?: boolean;
  21. isConverter?: boolean;
  22. icon?: string;
  23. }
  24. const tabs: TabInfo[] = [
  25. { label: 'Converter', type: 'converter', isConverter: true },
  26. { label: 'Processors', type: 'frameProcessors' },
  27. { label: 'Outputs', type: 'frameOutputs' },
  28. { label: 'Test', isTest: true, icon: 'flask' },
  29. ];
  30. export const RuleModal: React.FC<Props> = (props) => {
  31. const { isOpen, onClose, clickColumn } = props;
  32. const [rule, setRule] = useState<Rule>(props.rule);
  33. const [activeTab, setActiveTab] = useState<TabInfo | undefined>(tabs.find((t) => t.type === clickColumn));
  34. // to show color of Save button
  35. const [hasChange, setChange] = useState<boolean>(false);
  36. const [ruleSetting, setRuleSetting] = useState<any>(activeTab?.type ? rule?.settings?.[activeTab.type] : undefined);
  37. const [entitiesInfo, setEntitiesInfo] = useState<PipeLineEntitiesInfo>();
  38. const styles = useStyles(getStyles);
  39. const onRuleSettingChange = (value: RuleSetting | RuleSetting[]) => {
  40. setChange(true);
  41. if (activeTab?.type) {
  42. setRule({
  43. ...rule,
  44. settings: {
  45. ...rule.settings,
  46. [activeTab?.type]: value,
  47. },
  48. });
  49. }
  50. setRuleSetting(value);
  51. };
  52. // load pipeline entities info
  53. useMemo(() => {
  54. getPipeLineEntities().then((data) => {
  55. setEntitiesInfo(data);
  56. });
  57. }, []);
  58. const onSave = () => {
  59. getBackendSrv()
  60. .put(`api/live/channel-rules`, rule)
  61. .then(() => {
  62. setChange(false);
  63. onClose();
  64. })
  65. .catch((e) => console.error(e));
  66. };
  67. return (
  68. <Modal isOpen={isOpen} title={rule.pattern} onDismiss={onClose} closeOnEscape>
  69. <TabsBar>
  70. {tabs.map((tab, index) => {
  71. return (
  72. <Tab
  73. key={index}
  74. label={tab.label}
  75. active={tab === activeTab}
  76. icon={tab.icon as any}
  77. onChangeTab={() => {
  78. setActiveTab(tab);
  79. if (tab.type) {
  80. // to notify children of the new rule
  81. setRuleSetting(rule?.settings?.[tab.type]);
  82. }
  83. }}
  84. />
  85. );
  86. })}
  87. </TabsBar>
  88. <TabContent>
  89. {entitiesInfo && rule && activeTab && (
  90. <>
  91. {activeTab?.isTest && <RuleTest rule={rule} />}
  92. {activeTab.isConverter && (
  93. <RuleSettingsEditor
  94. onChange={onRuleSettingChange}
  95. value={ruleSetting}
  96. ruleType={'converter'}
  97. entitiesInfo={entitiesInfo}
  98. />
  99. )}
  100. {!activeTab.isConverter && activeTab.type && (
  101. <RuleSettingsArray
  102. onChange={onRuleSettingChange}
  103. value={ruleSetting}
  104. ruleType={activeTab.type}
  105. entitiesInfo={entitiesInfo}
  106. />
  107. )}
  108. </>
  109. )}
  110. <Button onClick={onSave} className={styles.save} variant={hasChange ? 'primary' : 'secondary'}>
  111. Save
  112. </Button>
  113. </TabContent>
  114. </Modal>
  115. );
  116. };
  117. const getStyles = (theme: GrafanaTheme) => {
  118. return {
  119. save: css`
  120. margin-top: 5px;
  121. `,
  122. };
  123. };