Compare commits
14 Commits
main
...
feat/logs-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a959328411 | ||
|
|
8452b69d1c | ||
|
|
85beee876c | ||
|
|
19c42bf5ee | ||
|
|
a40fae85b8 | ||
|
|
3d83872196 | ||
|
|
6e41f900dc | ||
|
|
c5dbac793b | ||
|
|
8b2f8c5b1e | ||
|
|
b7dc7d519b | ||
|
|
58d63695d8 | ||
|
|
b1133bf812 | ||
|
|
065d064ac1 | ||
|
|
4ec7dc550b |
@@ -42,5 +42,7 @@
|
||||
"processor_span_id_placeholder": "Parse Span ID from",
|
||||
"processor_trace_flags_placeholder": "Parse Trace flags from",
|
||||
"processor_from_placeholder": "From",
|
||||
"processor_to_placeholder": "To"
|
||||
"processor_to_placeholder": "To",
|
||||
"share_pipelines": "Share Pipelines",
|
||||
"import_pipelines": "Import Pipelines"
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ function Editor({
|
||||
readOnly,
|
||||
height,
|
||||
options,
|
||||
beforeMount,
|
||||
onValidate,
|
||||
}: MEditorProps): JSX.Element {
|
||||
const isDarkMode = useIsDarkMode();
|
||||
|
||||
@@ -31,6 +33,8 @@ function Editor({
|
||||
options={editorOptions}
|
||||
height={height}
|
||||
onChange={onChangeHandler}
|
||||
beforeMount={beforeMount}
|
||||
onValidate={onValidate}
|
||||
data-testid="monaco-editor"
|
||||
/>
|
||||
);
|
||||
@@ -43,6 +47,8 @@ interface MEditorProps {
|
||||
readOnly?: boolean;
|
||||
height?: string;
|
||||
options?: EditorProps['options'];
|
||||
beforeMount?: EditorProps['beforeMount'];
|
||||
onValidate?: EditorProps['onValidate'];
|
||||
}
|
||||
|
||||
Editor.defaultProps = {
|
||||
@@ -51,6 +57,8 @@ Editor.defaultProps = {
|
||||
height: '40vh',
|
||||
options: {},
|
||||
onChange: (): void => {},
|
||||
beforeMount: (): void => {},
|
||||
onValidate: (): void => {},
|
||||
};
|
||||
|
||||
export default Editor;
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
import { EditFilled, PlusOutlined } from '@ant-design/icons';
|
||||
import TextToolTip from 'components/TextToolTip';
|
||||
import useAnalytics from 'hooks/analytics/useAnalytics';
|
||||
import { useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ActionMode, ActionType, Pipeline } from 'types/api/pipeline/def';
|
||||
|
||||
import { ButtonContainer, CustomButton } from '../../styles';
|
||||
import { checkDataLength } from '../utils';
|
||||
|
||||
function CreatePipelineButton({
|
||||
setActionType,
|
||||
isActionMode,
|
||||
setActionMode,
|
||||
pipelineData,
|
||||
}: CreatePipelineButtonProps): JSX.Element {
|
||||
const { t } = useTranslation(['pipeline']);
|
||||
const { trackEvent } = useAnalytics();
|
||||
|
||||
const isAddNewPipelineVisible = useMemo(
|
||||
() => checkDataLength(pipelineData?.pipelines),
|
||||
[pipelineData?.pipelines],
|
||||
);
|
||||
const isDisabled = isActionMode === ActionMode.Editing;
|
||||
|
||||
const onEnterEditMode = (): void => {
|
||||
setActionMode(ActionMode.Editing);
|
||||
|
||||
trackEvent('Logs: Pipelines: Entered Edit Mode', {
|
||||
source: 'signoz-ui',
|
||||
});
|
||||
};
|
||||
const onAddNewPipeline = (): void => {
|
||||
setActionMode(ActionMode.Editing);
|
||||
setActionType(ActionType.AddPipeline);
|
||||
|
||||
trackEvent('Logs: Pipelines: Clicked Add New Pipeline', {
|
||||
source: 'signoz-ui',
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<ButtonContainer>
|
||||
<TextToolTip
|
||||
text={t('learn_more')}
|
||||
url="https://signoz.io/docs/logs-pipelines/introduction/"
|
||||
/>
|
||||
{isAddNewPipelineVisible && (
|
||||
<CustomButton
|
||||
icon={<EditFilled />}
|
||||
onClick={onEnterEditMode}
|
||||
disabled={isDisabled}
|
||||
>
|
||||
{t('enter_edit_mode')}
|
||||
</CustomButton>
|
||||
)}
|
||||
{!isAddNewPipelineVisible && (
|
||||
<CustomButton
|
||||
icon={<PlusOutlined />}
|
||||
onClick={onAddNewPipeline}
|
||||
type="primary"
|
||||
>
|
||||
{t('new_pipeline')}
|
||||
</CustomButton>
|
||||
)}
|
||||
</ButtonContainer>
|
||||
);
|
||||
}
|
||||
|
||||
interface CreatePipelineButtonProps {
|
||||
setActionType: (actionType: string) => void;
|
||||
isActionMode: string;
|
||||
setActionMode: (actionMode: string) => void;
|
||||
pipelineData: Pipeline;
|
||||
}
|
||||
|
||||
export default CreatePipelineButton;
|
||||
@@ -0,0 +1,125 @@
|
||||
import {
|
||||
EditFilled,
|
||||
ImportOutlined,
|
||||
PlusOutlined,
|
||||
ShareAltOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import TextToolTip from 'components/TextToolTip';
|
||||
import useAnalytics from 'hooks/analytics/useAnalytics';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
ActionMode,
|
||||
ActionType,
|
||||
Pipeline,
|
||||
PipelineData,
|
||||
} from 'types/api/pipeline/def';
|
||||
|
||||
import { ButtonContainer, CustomButton } from '../../styles';
|
||||
import PipelinesExportModal from './PipelinesExportModal';
|
||||
import PipelinesImportModal from './PipelinesImportModal/PipelinesImportModal';
|
||||
|
||||
function PipelinesActions({
|
||||
setActionType,
|
||||
isActionMode,
|
||||
setActionMode,
|
||||
pipelineData,
|
||||
setCurrentPipelines,
|
||||
}: PipelinesActionsProps): JSX.Element {
|
||||
const { t } = useTranslation(['pipeline']);
|
||||
const { trackEvent } = useAnalytics();
|
||||
|
||||
const [isExportModalVisible, setIsExportModalVisible] = useState(false);
|
||||
const [isImportModalVisible, setIsImportModalVisible] = useState(false);
|
||||
|
||||
const pipelinesExist = useMemo(() => pipelineData?.pipelines?.length > 0, [
|
||||
pipelineData?.pipelines,
|
||||
]);
|
||||
const inEditMode = isActionMode === ActionMode.Editing;
|
||||
|
||||
const onEnterEditMode = (): void => {
|
||||
setActionMode(ActionMode.Editing);
|
||||
|
||||
trackEvent('Logs: Pipelines: Entered Edit Mode', {
|
||||
source: 'signoz-ui',
|
||||
});
|
||||
};
|
||||
const onAddNewPipeline = (): void => {
|
||||
setActionMode(ActionMode.Editing);
|
||||
setActionType(ActionType.AddPipeline);
|
||||
|
||||
trackEvent('Logs: Pipelines: Clicked Add New Pipeline', {
|
||||
source: 'signoz-ui',
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ButtonContainer>
|
||||
<TextToolTip
|
||||
text={t('learn_more')}
|
||||
url="https://signoz.io/docs/logs-pipelines/introduction/"
|
||||
/>
|
||||
{pipelinesExist && !inEditMode && (
|
||||
<CustomButton
|
||||
onClick={(): void => setIsExportModalVisible(true)}
|
||||
icon={<ShareAltOutlined />}
|
||||
>
|
||||
{t('share_pipelines')}
|
||||
</CustomButton>
|
||||
)}
|
||||
{(inEditMode || !pipelinesExist) && (
|
||||
<CustomButton
|
||||
onClick={(): void => {
|
||||
onEnterEditMode();
|
||||
setIsImportModalVisible(true);
|
||||
}}
|
||||
icon={<ImportOutlined />}
|
||||
>
|
||||
{t('import_pipelines')}
|
||||
</CustomButton>
|
||||
)}
|
||||
{pipelinesExist && (
|
||||
<CustomButton
|
||||
icon={<EditFilled />}
|
||||
onClick={onEnterEditMode}
|
||||
disabled={inEditMode}
|
||||
>
|
||||
{t('enter_edit_mode')}
|
||||
</CustomButton>
|
||||
)}
|
||||
{!pipelinesExist && (
|
||||
<CustomButton
|
||||
icon={<PlusOutlined />}
|
||||
onClick={onAddNewPipeline}
|
||||
type="primary"
|
||||
>
|
||||
{t('new_pipeline')}
|
||||
</CustomButton>
|
||||
)}
|
||||
</ButtonContainer>
|
||||
<PipelinesExportModal
|
||||
open={isExportModalVisible}
|
||||
onClose={(): void => setIsExportModalVisible(false)}
|
||||
pipelines={pipelineData.pipelines}
|
||||
/>
|
||||
<PipelinesImportModal
|
||||
open={isImportModalVisible}
|
||||
onClose={(): void => setIsImportModalVisible(false)}
|
||||
setCurrentPipelines={setCurrentPipelines}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
interface PipelinesActionsProps {
|
||||
setActionType: (actionType: string) => void;
|
||||
isActionMode: string;
|
||||
setActionMode: (actionMode: string) => void;
|
||||
pipelineData: Pipeline;
|
||||
setCurrentPipelines: (
|
||||
value: React.SetStateAction<Array<PipelineData>>,
|
||||
) => void;
|
||||
}
|
||||
|
||||
export default PipelinesActions;
|
||||
@@ -0,0 +1,99 @@
|
||||
import { CopyFilled, DownloadOutlined } from '@ant-design/icons';
|
||||
import { Button, Modal } from 'antd';
|
||||
import Editor from 'components/Editor';
|
||||
import { downloadObjectAsJson } from 'container/NewDashboard/DashboardDescription/utils';
|
||||
import { useNotifications } from 'hooks/useNotifications';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useCopyToClipboard } from 'react-use';
|
||||
import { PipelineData } from 'types/api/pipeline/def';
|
||||
|
||||
export default function PipelinesExportModal({
|
||||
open,
|
||||
onClose,
|
||||
pipelines,
|
||||
}: PipelinesExportModalProps): JSX.Element {
|
||||
const { t } = useTranslation(['pipeline']);
|
||||
const postablePipelines = pipelines.map((p) =>
|
||||
Object.fromEntries(
|
||||
Object.entries(p).filter((e) => !['createdBy', 'createdAt'].includes(e[0])),
|
||||
),
|
||||
);
|
||||
const pipelinesPropJson = JSON.stringify(postablePipelines, null, 2);
|
||||
const [pipelinesJson, setPipelinesJson] = useState(pipelinesPropJson);
|
||||
useEffect(() => {
|
||||
setPipelinesJson(pipelinesPropJson);
|
||||
}, [open, pipelinesPropJson]);
|
||||
|
||||
const { notifications } = useNotifications();
|
||||
const [clipboardContent, setClipboardContent] = useCopyToClipboard();
|
||||
useEffect(() => {
|
||||
if (clipboardContent.error) {
|
||||
notifications.error({
|
||||
message: t('something_went_wrong', {
|
||||
ns: 'common',
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
if (clipboardContent.value) {
|
||||
notifications.success({
|
||||
message: t('success', {
|
||||
ns: 'common',
|
||||
}),
|
||||
});
|
||||
}
|
||||
}, [clipboardContent.error, clipboardContent.value, t, notifications]);
|
||||
|
||||
const footer = useMemo(
|
||||
() => (
|
||||
<>
|
||||
<Button
|
||||
style={{
|
||||
marginTop: '16px',
|
||||
}}
|
||||
onClick={(): void => setClipboardContent(pipelinesJson)}
|
||||
type="primary"
|
||||
size="small"
|
||||
>
|
||||
<CopyFilled /> {t('copy_to_clipboard')}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
onClick={(): void => {
|
||||
downloadObjectAsJson(JSON.parse(pipelinesJson), 'pipelines');
|
||||
}}
|
||||
>
|
||||
<DownloadOutlined /> {t('download_json')}
|
||||
</Button>
|
||||
</>
|
||||
),
|
||||
[pipelinesJson, t, setClipboardContent],
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
onCancel={onClose}
|
||||
width="80vw"
|
||||
centered
|
||||
title={t('share')}
|
||||
destroyOnClose
|
||||
footer={footer}
|
||||
>
|
||||
<Editor
|
||||
height="70vh"
|
||||
onChange={(value): void => setPipelinesJson(value)}
|
||||
value={pipelinesJson}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
interface PipelinesExportModalProps {
|
||||
open: boolean;
|
||||
onClose: VoidFunction;
|
||||
pipelines: Array<PipelineData>;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import './styles.scss';
|
||||
|
||||
import { ImportOutlined } from '@ant-design/icons';
|
||||
import { Monaco } from '@monaco-editor/react';
|
||||
import { Button, Modal } from 'antd';
|
||||
import Editor from 'components/Editor';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PipelineData } from 'types/api/pipeline/def';
|
||||
|
||||
import { PipelinesJSONSchema } from '../schema';
|
||||
|
||||
export default function PipelinesImportModal({
|
||||
open,
|
||||
onClose,
|
||||
setCurrentPipelines,
|
||||
}: PipelinesImportModalProps): JSX.Element {
|
||||
const { t } = useTranslation(['pipeline']);
|
||||
const [pipelinesJson, setPipelinesJson] = useState('');
|
||||
const [editorErrors, setEditorErrors] = useState<string[]>([]);
|
||||
const isEmpty = pipelinesJson.trim().length < 1;
|
||||
const isInvalid = (editorErrors || []).length > 0;
|
||||
|
||||
const firstError = editorErrors?.[0];
|
||||
const onImport = useCallback((): void => {
|
||||
try {
|
||||
const pipelines = JSON.parse(pipelinesJson);
|
||||
setCurrentPipelines(pipelines);
|
||||
onClose();
|
||||
} catch (error) {
|
||||
setEditorErrors([String(error)]);
|
||||
}
|
||||
}, [pipelinesJson, setCurrentPipelines, onClose]);
|
||||
const footer = useMemo(
|
||||
() => (
|
||||
<div className="pipelines-import-modal-footer">
|
||||
<div className="pipelines-import-modal-error">{firstError || ''}</div>
|
||||
<Button
|
||||
disabled={isEmpty || isInvalid}
|
||||
type="primary"
|
||||
size="small"
|
||||
onClick={onImport}
|
||||
>
|
||||
<ImportOutlined /> {t('import')}
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
[t, isEmpty, isInvalid, firstError, onImport],
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
onCancel={onClose}
|
||||
width="80vw"
|
||||
centered
|
||||
title={t('import')}
|
||||
destroyOnClose
|
||||
footer={footer}
|
||||
>
|
||||
<Editor
|
||||
height="70vh"
|
||||
onChange={(value): void => setPipelinesJson(value)}
|
||||
value={pipelinesJson}
|
||||
language="json"
|
||||
beforeMount={(monaco: Monaco): void => {
|
||||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
||||
validate: true,
|
||||
schemas: [
|
||||
{
|
||||
fileMatch: ['*'],
|
||||
schema: PipelinesJSONSchema,
|
||||
},
|
||||
],
|
||||
});
|
||||
}}
|
||||
onValidate={(markers): void =>
|
||||
setEditorErrors(
|
||||
markers.map(
|
||||
(m) => `Ln ${m.startLineNumber}, Col ${m.startColumn}: ${m.message}`,
|
||||
),
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
interface PipelinesImportModalProps {
|
||||
open: boolean;
|
||||
onClose: VoidFunction;
|
||||
setCurrentPipelines: (
|
||||
value: React.SetStateAction<Array<PipelineData>>,
|
||||
) => void;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import PipelinesImportModal from './PipelinesImportModal';
|
||||
|
||||
export default PipelinesImportModal;
|
||||
@@ -0,0 +1,10 @@
|
||||
.pipelines-import-modal-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.pipelines-import-modal-error {
|
||||
flex-grow: 1;
|
||||
text-align: left;
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
import cloneDeep from 'lodash-es/cloneDeep';
|
||||
import { useState } from 'react';
|
||||
import { Pipeline } from 'types/api/pipeline/def';
|
||||
import { Pipeline, PipelineData } from 'types/api/pipeline/def';
|
||||
|
||||
import PipelineListsView from '../../PipelineListsView';
|
||||
import CreatePipelineButton from './CreatePipelineButton';
|
||||
import PipelinesActions from './PipelinesActions';
|
||||
|
||||
function PipelinePageLayout({
|
||||
refetchPipelineLists,
|
||||
@@ -10,21 +11,32 @@ function PipelinePageLayout({
|
||||
}: PipelinePageLayoutProps): JSX.Element {
|
||||
const [isActionType, setActionType] = useState<string>();
|
||||
const [isActionMode, setActionMode] = useState<string>('viewing-mode');
|
||||
const [savedPipelines, setSavedPipelines] = useState<Array<PipelineData>>(
|
||||
cloneDeep(pipelineData?.pipelines || []),
|
||||
);
|
||||
const [currentPipelines, setCurrentPipelines] = useState<Array<PipelineData>>(
|
||||
cloneDeep(pipelineData?.pipelines || []),
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<CreatePipelineButton
|
||||
<PipelinesActions
|
||||
setActionType={setActionType}
|
||||
setActionMode={setActionMode}
|
||||
isActionMode={isActionMode}
|
||||
pipelineData={pipelineData}
|
||||
setCurrentPipelines={setCurrentPipelines}
|
||||
/>
|
||||
<PipelineListsView
|
||||
isActionType={String(isActionType)}
|
||||
setActionType={setActionType}
|
||||
setActionMode={setActionMode}
|
||||
isActionMode={isActionMode}
|
||||
pipelineData={pipelineData}
|
||||
savedPipelinesVersion={pipelineData?.version}
|
||||
savedPipelines={savedPipelines}
|
||||
setSavedPipelines={setSavedPipelines}
|
||||
currentPipelines={currentPipelines}
|
||||
setCurrentPipelines={setCurrentPipelines}
|
||||
refetchPipelineLists={refetchPipelineLists}
|
||||
/>
|
||||
</>
|
||||
|
||||
247
frontend/src/container/PipelinePage/Layouts/Pipeline/schema.ts
Normal file
247
frontend/src/container/PipelinePage/Layouts/Pipeline/schema.ts
Normal file
@@ -0,0 +1,247 @@
|
||||
// JSON schema for pipelines payload.
|
||||
|
||||
export const PipelinesJSONSchema = JSON.parse(`
|
||||
{
|
||||
"items": {
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"orderId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"alias": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"filter": {
|
||||
"properties": {
|
||||
"op": {
|
||||
"type": "string"
|
||||
},
|
||||
"items": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"dataType": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"isColumn": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isJSON": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"key",
|
||||
"dataType",
|
||||
"type",
|
||||
"isColumn",
|
||||
"isJSON"
|
||||
]
|
||||
},
|
||||
"value": true,
|
||||
"op": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"key",
|
||||
"value",
|
||||
"op"
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"op",
|
||||
"items"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"output": {
|
||||
"type": "string"
|
||||
},
|
||||
"on_error": {
|
||||
"type": "string"
|
||||
},
|
||||
"if": {
|
||||
"type": "string"
|
||||
},
|
||||
"orderId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"parse_to": {
|
||||
"type": "string"
|
||||
},
|
||||
"pattern": {
|
||||
"type": "string"
|
||||
},
|
||||
"regex": {
|
||||
"type": "string"
|
||||
},
|
||||
"parse_from": {
|
||||
"type": "string"
|
||||
},
|
||||
"trace_id": {
|
||||
"properties": {
|
||||
"parse_from": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parse_from"
|
||||
]
|
||||
},
|
||||
"span_id": {
|
||||
"properties": {
|
||||
"parse_from": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parse_from"
|
||||
]
|
||||
},
|
||||
"trace_flags": {
|
||||
"properties": {
|
||||
"parse_from": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"parse_from"
|
||||
]
|
||||
},
|
||||
"field": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"from": {
|
||||
"type": "string"
|
||||
},
|
||||
"to": {
|
||||
"type": "string"
|
||||
},
|
||||
"expr": {
|
||||
"type": "string"
|
||||
},
|
||||
"routes": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"output": {
|
||||
"type": "string"
|
||||
},
|
||||
"expr": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"output",
|
||||
"expr"
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"fields": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"default": {
|
||||
"type": "string"
|
||||
},
|
||||
"layout": {
|
||||
"type": "string"
|
||||
},
|
||||
"layout_type": {
|
||||
"type": "string"
|
||||
},
|
||||
"mapping": {
|
||||
"additionalProperties": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"overwrite_text": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"orderId",
|
||||
"enabled"
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"orderId",
|
||||
"name",
|
||||
"alias",
|
||||
"description",
|
||||
"enabled",
|
||||
"filter",
|
||||
"config"
|
||||
]
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
`);
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Button, Divider, Form, Modal } from 'antd';
|
||||
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { ActionMode, ActionType, PipelineData } from 'types/api/pipeline/def';
|
||||
import { ActionType, PipelineData } from 'types/api/pipeline/def';
|
||||
import AppReducer from 'types/reducer/app';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
@@ -15,7 +15,6 @@ function AddNewPipeline({
|
||||
isActionType,
|
||||
setActionType,
|
||||
selectedPipelineData,
|
||||
setShowSaveButton,
|
||||
setCurrPipelineData,
|
||||
currPipelineData,
|
||||
}: AddNewPipelineProps): JSX.Element {
|
||||
@@ -90,11 +89,6 @@ function AddNewPipeline({
|
||||
[isEdit, selectedPipelineData?.name, t],
|
||||
);
|
||||
|
||||
const onOkModalHandler = useCallback(
|
||||
() => setShowSaveButton(ActionMode.Editing),
|
||||
[setShowSaveButton],
|
||||
);
|
||||
|
||||
const isOpen = useMemo(() => isEdit || isAdd, [isAdd, isEdit]);
|
||||
|
||||
return (
|
||||
@@ -122,7 +116,7 @@ function AddNewPipeline({
|
||||
key="submit"
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
onClick={onOkModalHandler}
|
||||
onClick={(): void => {}}
|
||||
>
|
||||
{isEdit ? t('update') : t('create')}
|
||||
</Button>
|
||||
@@ -140,7 +134,6 @@ interface AddNewPipelineProps {
|
||||
isActionType: string;
|
||||
setActionType: (actionType?: ActionType) => void;
|
||||
selectedPipelineData: PipelineData | undefined;
|
||||
setShowSaveButton: (actionMode: ActionMode) => void;
|
||||
setCurrPipelineData: (
|
||||
value: React.SetStateAction<Array<PipelineData>>,
|
||||
) => void;
|
||||
|
||||
@@ -2,7 +2,6 @@ import { Button, Divider, Form, Modal } from 'antd';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
ActionMode,
|
||||
ActionType,
|
||||
PipelineData,
|
||||
ProcessorData,
|
||||
@@ -19,7 +18,6 @@ function AddNewProcessor({
|
||||
isActionType,
|
||||
setActionType,
|
||||
selectedProcessorData,
|
||||
setShowSaveButton,
|
||||
expandedPipelineData,
|
||||
setExpandedPipelineData,
|
||||
}: AddNewProcessorProps): JSX.Element {
|
||||
@@ -134,11 +132,6 @@ function AddNewProcessor({
|
||||
[isEdit, selectedProcessorData?.name, t],
|
||||
);
|
||||
|
||||
const onOkModalHandler = useCallback(
|
||||
() => setShowSaveButton(ActionMode.Editing),
|
||||
[setShowSaveButton],
|
||||
);
|
||||
|
||||
const isOpen = useMemo(() => isEdit || isAdd, [isAdd, isEdit]);
|
||||
|
||||
const onFormValuesChanged = useCallback(
|
||||
@@ -179,7 +172,7 @@ function AddNewProcessor({
|
||||
key="submit"
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
onClick={onOkModalHandler}
|
||||
onClick={(): void => {}}
|
||||
>
|
||||
{isEdit ? t('update') : t('create')}
|
||||
</Button>
|
||||
@@ -202,7 +195,6 @@ interface AddNewProcessorProps {
|
||||
isActionType: string;
|
||||
setActionType: (actionType?: ActionType) => void;
|
||||
selectedProcessorData?: ProcessorData;
|
||||
setShowSaveButton: (actionMode: ActionMode) => void;
|
||||
expandedPipelineData?: PipelineData;
|
||||
setExpandedPipelineData: (data: PipelineData) => void;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ function PipelineExpandView({
|
||||
setActionType,
|
||||
processorEditAction,
|
||||
isActionMode,
|
||||
setShowSaveButton,
|
||||
expandedPipelineData,
|
||||
setExpandedPipelineData,
|
||||
prevPipelineData,
|
||||
@@ -44,7 +43,6 @@ function PipelineExpandView({
|
||||
|
||||
const deleteProcessorHandler = useCallback(
|
||||
(record: ProcessorData) => (): void => {
|
||||
setShowSaveButton(ActionMode.Editing);
|
||||
if (expandedPipelineData && expandedPipelineData?.config) {
|
||||
const filteredData = expandedPipelineData?.config.filter(
|
||||
(item: ProcessorData) => item.id !== record.id,
|
||||
@@ -62,7 +60,7 @@ function PipelineExpandView({
|
||||
setExpandedPipelineData(pipelineData);
|
||||
}
|
||||
},
|
||||
[expandedPipelineData, setShowSaveButton, setExpandedPipelineData],
|
||||
[expandedPipelineData, setExpandedPipelineData],
|
||||
);
|
||||
|
||||
const processorDeleteAction = useCallback(
|
||||
@@ -80,7 +78,6 @@ function PipelineExpandView({
|
||||
const onSwitchProcessorChange = useCallback(
|
||||
(checked: boolean, record: ProcessorData): void => {
|
||||
if (expandedPipelineData && expandedPipelineData?.config) {
|
||||
setShowSaveButton(ActionMode.Editing);
|
||||
const findRecordIndex = getRecordIndex(
|
||||
expandedPipelineData?.config,
|
||||
record,
|
||||
@@ -102,7 +99,7 @@ function PipelineExpandView({
|
||||
setExpandedPipelineData(modifiedProcessorData);
|
||||
}
|
||||
},
|
||||
[expandedPipelineData, setExpandedPipelineData, setShowSaveButton],
|
||||
[expandedPipelineData, setExpandedPipelineData],
|
||||
);
|
||||
|
||||
const columns = useMemo(() => {
|
||||
@@ -145,14 +142,13 @@ function PipelineExpandView({
|
||||
|
||||
const reorderProcessorRow = useCallback(
|
||||
(updatedRow: ProcessorData[]) => (): void => {
|
||||
setShowSaveButton(ActionMode.Editing);
|
||||
if (expandedPipelineData) {
|
||||
const modifiedProcessorData = { ...expandedPipelineData };
|
||||
modifiedProcessorData.config = updatedRow;
|
||||
setExpandedPipelineData(modifiedProcessorData);
|
||||
}
|
||||
},
|
||||
[expandedPipelineData, setShowSaveButton, setExpandedPipelineData],
|
||||
[expandedPipelineData, setExpandedPipelineData],
|
||||
);
|
||||
|
||||
const onCancelReorderProcessorRow = useCallback(
|
||||
@@ -267,7 +263,6 @@ interface PipelineExpandViewProps {
|
||||
setActionType: (actionType?: ActionType) => void;
|
||||
processorEditAction: (record: ProcessorData) => () => void;
|
||||
isActionMode: string;
|
||||
setShowSaveButton: (actionMode: ActionMode) => void;
|
||||
expandedPipelineData?: PipelineData;
|
||||
setExpandedPipelineData: (data: PipelineData) => void;
|
||||
prevPipelineData: Array<PipelineData>;
|
||||
|
||||
@@ -7,6 +7,7 @@ import savePipeline from 'api/pipeline/post';
|
||||
import useAnalytics from 'hooks/analytics/useAnalytics';
|
||||
import { useNotifications } from 'hooks/useNotifications';
|
||||
import cloneDeep from 'lodash-es/cloneDeep';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { DndProvider } from 'react-dnd';
|
||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||
@@ -14,7 +15,6 @@ import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
ActionMode,
|
||||
ActionType,
|
||||
Pipeline,
|
||||
PipelineData,
|
||||
ProcessorData,
|
||||
} from 'types/api/pipeline/def';
|
||||
@@ -85,7 +85,11 @@ function PipelineListsView({
|
||||
setActionType,
|
||||
isActionMode,
|
||||
setActionMode,
|
||||
pipelineData,
|
||||
savedPipelinesVersion,
|
||||
savedPipelines,
|
||||
setSavedPipelines,
|
||||
currentPipelines,
|
||||
setCurrentPipelines,
|
||||
refetchPipelineLists,
|
||||
}: PipelineListsViewProps): JSX.Element {
|
||||
const { t } = useTranslation(['pipeline', 'common']);
|
||||
@@ -93,34 +97,28 @@ function PipelineListsView({
|
||||
const { notifications } = useNotifications();
|
||||
const [pipelineSearchValue, setPipelineSearchValue] = useState<string>('');
|
||||
const { trackEvent } = useAnalytics();
|
||||
const [prevPipelineData, setPrevPipelineData] = useState<Array<PipelineData>>(
|
||||
cloneDeep(pipelineData?.pipelines || []),
|
||||
);
|
||||
const [currPipelineData, setCurrPipelineData] = useState<Array<PipelineData>>(
|
||||
cloneDeep(pipelineData?.pipelines || []),
|
||||
);
|
||||
|
||||
const [expandedPipelineId, setExpandedPipelineId] = useState<
|
||||
string | undefined
|
||||
>(undefined);
|
||||
const expandedPipelineData = useCallback(
|
||||
() => currPipelineData?.find((p) => p.id === expandedPipelineId),
|
||||
[currPipelineData, expandedPipelineId],
|
||||
() => currentPipelines?.find((p) => p.id === expandedPipelineId),
|
||||
[currentPipelines, expandedPipelineId],
|
||||
);
|
||||
|
||||
const setExpandedPipelineData = useCallback(
|
||||
(newData: PipelineData): void => {
|
||||
if (expandedPipelineId) {
|
||||
const pipelineIdx = currPipelineData?.findIndex(
|
||||
const pipelineIdx = currentPipelines?.findIndex(
|
||||
(p) => p.id === expandedPipelineId,
|
||||
);
|
||||
if (pipelineIdx >= 0) {
|
||||
const newPipelineData = [...currPipelineData];
|
||||
const newPipelineData = cloneDeep(currentPipelines);
|
||||
newPipelineData[pipelineIdx] = newData;
|
||||
setCurrPipelineData(newPipelineData);
|
||||
setCurrentPipelines(newPipelineData);
|
||||
}
|
||||
}
|
||||
},
|
||||
[expandedPipelineId, currPipelineData],
|
||||
[expandedPipelineId, currentPipelines, setCurrentPipelines],
|
||||
);
|
||||
|
||||
const [
|
||||
@@ -134,17 +132,16 @@ function PipelineListsView({
|
||||
] = useState<PipelineData>();
|
||||
|
||||
const [expandedRowKeys, setExpandedRowKeys] = useState<Array<string>>();
|
||||
const [showSaveButton, setShowSaveButton] = useState<string>();
|
||||
const isEditingActionMode = isActionMode === ActionMode.Editing;
|
||||
|
||||
const visibleCurrPipelines = useMemo((): Array<PipelineData> => {
|
||||
if (pipelineSearchValue === '') {
|
||||
return currPipelineData;
|
||||
return currentPipelines;
|
||||
}
|
||||
return currPipelineData.filter((data) =>
|
||||
return currentPipelines.filter((data) =>
|
||||
getDataOnSearch(data as never, pipelineSearchValue),
|
||||
);
|
||||
}, [currPipelineData, pipelineSearchValue]);
|
||||
}, [currentPipelines, pipelineSearchValue]);
|
||||
|
||||
const handleAlert = useCallback(
|
||||
({ title, descrition, buttontext, onCancel, onOk }: AlertMessage) => {
|
||||
@@ -171,15 +168,18 @@ function PipelineListsView({
|
||||
|
||||
const pipelineDeleteHandler = useCallback(
|
||||
(record: PipelineData) => (): void => {
|
||||
setShowSaveButton(ActionMode.Editing);
|
||||
const filteredData = getElementFromArray(currPipelineData, record, 'id');
|
||||
const filteredData = getElementFromArray(
|
||||
cloneDeep(currentPipelines),
|
||||
record,
|
||||
'id',
|
||||
);
|
||||
filteredData.forEach((item, index) => {
|
||||
const obj = item;
|
||||
obj.orderId = index + 1;
|
||||
});
|
||||
setCurrPipelineData(filteredData);
|
||||
setCurrentPipelines(filteredData);
|
||||
},
|
||||
[currPipelineData],
|
||||
[currentPipelines, setCurrentPipelines],
|
||||
);
|
||||
|
||||
const pipelineDeleteAction = useCallback(
|
||||
@@ -204,21 +204,20 @@ function PipelineListsView({
|
||||
|
||||
const onSwitchPipelineChange = useCallback(
|
||||
(checked: boolean, record: PipelineData): void => {
|
||||
setShowSaveButton(ActionMode.Editing);
|
||||
const findRecordIndex = getRecordIndex(currPipelineData, record, 'id');
|
||||
const findRecordIndex = getRecordIndex(currentPipelines, record, 'id');
|
||||
const updateSwitch = {
|
||||
...currPipelineData[findRecordIndex],
|
||||
...currentPipelines[findRecordIndex],
|
||||
enabled: checked,
|
||||
};
|
||||
const editedPipelineData = getEditedDataSource(
|
||||
currPipelineData,
|
||||
cloneDeep(currentPipelines),
|
||||
record,
|
||||
'id',
|
||||
updateSwitch,
|
||||
);
|
||||
setCurrPipelineData(editedPipelineData);
|
||||
setCurrentPipelines(editedPipelineData);
|
||||
},
|
||||
[currPipelineData],
|
||||
[currentPipelines, setCurrentPipelines],
|
||||
);
|
||||
|
||||
const columns = useMemo(() => {
|
||||
@@ -271,28 +270,13 @@ function PipelineListsView({
|
||||
onSwitchPipelineChange,
|
||||
]);
|
||||
|
||||
const updatePipelineSequence = useCallback(
|
||||
(updatedRow: PipelineData[]) => (): void => {
|
||||
setShowSaveButton(ActionMode.Editing);
|
||||
setCurrPipelineData(updatedRow);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const onCancelPipelineSequence = useCallback(
|
||||
(rawData: PipelineData[]) => (): void => {
|
||||
setCurrPipelineData(rawData);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const movePipelineRow = useCallback(
|
||||
(dragIndex: number, hoverIndex: number) => {
|
||||
if (currPipelineData && isEditingActionMode) {
|
||||
const rawData = currPipelineData;
|
||||
if (currentPipelines && isEditingActionMode) {
|
||||
const rawData = currentPipelines;
|
||||
|
||||
const updatedRows = getUpdatedRow(
|
||||
currPipelineData,
|
||||
cloneDeep(currentPipelines),
|
||||
visibleCurrPipelines[dragIndex].orderId - 1,
|
||||
visibleCurrPipelines[hoverIndex].orderId - 1,
|
||||
);
|
||||
@@ -305,19 +289,18 @@ function PipelineListsView({
|
||||
title: t('reorder_pipeline'),
|
||||
descrition: t('reorder_pipeline_description'),
|
||||
buttontext: t('reorder'),
|
||||
onOk: updatePipelineSequence(updatedRows),
|
||||
onCancel: onCancelPipelineSequence(rawData),
|
||||
onOk: (): void => setCurrentPipelines(updatedRows),
|
||||
onCancel: (): void => setCurrentPipelines(rawData),
|
||||
});
|
||||
}
|
||||
},
|
||||
[
|
||||
currPipelineData,
|
||||
currentPipelines,
|
||||
isEditingActionMode,
|
||||
visibleCurrPipelines,
|
||||
handleAlert,
|
||||
t,
|
||||
updatePipelineSequence,
|
||||
onCancelPipelineSequence,
|
||||
setCurrentPipelines,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -328,10 +311,9 @@ function PipelineListsView({
|
||||
isActionMode={isActionMode}
|
||||
setActionType={setActionType}
|
||||
processorEditAction={processorEditAction}
|
||||
setShowSaveButton={setShowSaveButton}
|
||||
expandedPipelineData={expandedPipelineData()}
|
||||
setExpandedPipelineData={setExpandedPipelineData}
|
||||
prevPipelineData={prevPipelineData}
|
||||
prevPipelineData={savedPipelines}
|
||||
/>
|
||||
),
|
||||
[
|
||||
@@ -340,7 +322,7 @@ function PipelineListsView({
|
||||
isActionMode,
|
||||
expandedPipelineData,
|
||||
setActionType,
|
||||
prevPipelineData,
|
||||
savedPipelines,
|
||||
setExpandedPipelineData,
|
||||
],
|
||||
);
|
||||
@@ -390,7 +372,7 @@ function PipelineListsView({
|
||||
}, [isEditingActionMode, addNewPipelineHandler, t]);
|
||||
|
||||
const onSaveConfigurationHandler = useCallback(async () => {
|
||||
const modifiedPipelineData = currPipelineData.map((item: PipelineData) => {
|
||||
const modifiedPipelineData = currentPipelines.map((item: PipelineData) => {
|
||||
const pipelineData = { ...item };
|
||||
delete pipelineData?.id;
|
||||
return pipelineData;
|
||||
@@ -401,11 +383,10 @@ function PipelineListsView({
|
||||
if (response.statusCode === 200) {
|
||||
refetchPipelineLists();
|
||||
setActionMode(ActionMode.Viewing);
|
||||
setShowSaveButton(undefined);
|
||||
|
||||
const pipelinesInDB = response.payload?.pipelines || [];
|
||||
setCurrPipelineData(pipelinesInDB);
|
||||
setPrevPipelineData(pipelinesInDB);
|
||||
setCurrentPipelines(cloneDeep(pipelinesInDB));
|
||||
setSavedPipelines(cloneDeep(pipelinesInDB));
|
||||
|
||||
trackEvent('Logs: Pipelines: Saved Pipelines', {
|
||||
count: pipelinesInDB.length,
|
||||
@@ -419,21 +400,19 @@ function PipelineListsView({
|
||||
return pipelineData;
|
||||
});
|
||||
setActionMode(ActionMode.Editing);
|
||||
setShowSaveButton(ActionMode.Editing);
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: response.error || t('something_went_wrong'),
|
||||
});
|
||||
setCurrPipelineData(modifiedPipelineData);
|
||||
setPrevPipelineData(modifiedPipelineData);
|
||||
setCurrentPipelines(cloneDeep(modifiedPipelineData));
|
||||
setSavedPipelines(cloneDeep(modifiedPipelineData));
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [currPipelineData, notifications, refetchPipelineLists, setActionMode, t]);
|
||||
}, [currentPipelines, notifications, refetchPipelineLists, setActionMode, t]);
|
||||
|
||||
const onCancelConfigurationHandler = useCallback((): void => {
|
||||
setActionMode(ActionMode.Viewing);
|
||||
setShowSaveButton(undefined);
|
||||
prevPipelineData.forEach((item, index) => {
|
||||
savedPipelines.forEach((item, index) => {
|
||||
const obj = item;
|
||||
obj.orderId = index + 1;
|
||||
if (obj.config) {
|
||||
@@ -446,9 +425,9 @@ function PipelineListsView({
|
||||
}
|
||||
}
|
||||
});
|
||||
setCurrPipelineData(prevPipelineData);
|
||||
setCurrentPipelines(cloneDeep(savedPipelines));
|
||||
setExpandedRowKeys([]);
|
||||
}, [prevPipelineData, setActionMode]);
|
||||
}, [savedPipelines, setCurrentPipelines, setActionMode]);
|
||||
|
||||
const onRowHandler = (
|
||||
_data: PipelineData,
|
||||
@@ -473,25 +452,23 @@ function PipelineListsView({
|
||||
isActionType={isActionType}
|
||||
setActionType={setActionType}
|
||||
selectedPipelineData={selectedPipelineData}
|
||||
setShowSaveButton={setShowSaveButton}
|
||||
setCurrPipelineData={setCurrPipelineData}
|
||||
currPipelineData={currPipelineData}
|
||||
setCurrPipelineData={setCurrentPipelines}
|
||||
currPipelineData={currentPipelines}
|
||||
/>
|
||||
<AddNewProcessor
|
||||
isActionType={isActionType}
|
||||
setActionType={setActionType}
|
||||
selectedProcessorData={selectedProcessorData}
|
||||
setShowSaveButton={setShowSaveButton}
|
||||
expandedPipelineData={expandedPipelineData()}
|
||||
setExpandedPipelineData={setExpandedPipelineData}
|
||||
/>
|
||||
{prevPipelineData?.length > 0 || currPipelineData?.length > 0 ? (
|
||||
{savedPipelines?.length > 0 || currentPipelines?.length > 0 ? (
|
||||
<>
|
||||
<PipelinesSearchSection setPipelineSearchValue={setPipelineSearchValue} />
|
||||
<Container>
|
||||
<ModeAndConfiguration
|
||||
isActionMode={isActionMode}
|
||||
version={pipelineData?.version}
|
||||
version={savedPipelinesVersion}
|
||||
/>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Table
|
||||
@@ -508,7 +485,7 @@ function PipelineListsView({
|
||||
</DndProvider>
|
||||
{isEditingActionMode && (
|
||||
<SaveConfigButton
|
||||
showSaveButton={Boolean(showSaveButton)}
|
||||
showSaveButton={!isEqual(currentPipelines, savedPipelines)}
|
||||
onSaveConfigurationHandler={onSaveConfigurationHandler}
|
||||
onCancelConfigurationHandler={onCancelConfigurationHandler}
|
||||
/>
|
||||
@@ -529,7 +506,13 @@ interface PipelineListsViewProps {
|
||||
setActionType: (actionType?: ActionType) => void;
|
||||
isActionMode: string;
|
||||
setActionMode: (actionMode: ActionMode) => void;
|
||||
pipelineData: Pipeline;
|
||||
savedPipelinesVersion: number | string;
|
||||
savedPipelines: Array<PipelineData>;
|
||||
setSavedPipelines: (value: React.SetStateAction<Array<PipelineData>>) => void;
|
||||
currentPipelines: Array<PipelineData>;
|
||||
setCurrentPipelines: (
|
||||
value: React.SetStateAction<Array<PipelineData>>,
|
||||
) => void;
|
||||
refetchPipelineLists: VoidFunction;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ export const ButtonContainer = styled.div`
|
||||
|
||||
export const CustomButton = styled(Button)`
|
||||
&&& {
|
||||
margin-left: 1rem;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { MemoryRouter } from 'react-router-dom';
|
||||
import i18n from 'ReactI18';
|
||||
import store from 'store';
|
||||
|
||||
import CreatePipelineButton from '../Layouts/Pipeline/CreatePipelineButton';
|
||||
import PipelinesActions from '../Layouts/Pipeline/PipelinesActions';
|
||||
import { pipelineApiResponseMockData } from '../mocks/pipeline';
|
||||
|
||||
describe('PipelinePage container test', () => {
|
||||
@@ -14,7 +14,7 @@ describe('PipelinePage container test', () => {
|
||||
<MemoryRouter>
|
||||
<Provider store={store}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<CreatePipelineButton
|
||||
<PipelinesActions
|
||||
setActionType={jest.fn()}
|
||||
isActionMode="viewing-mode"
|
||||
setActionMode={jest.fn()}
|
||||
|
||||
Reference in New Issue
Block a user