You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by li...@apache.org on 2023/05/30 01:59:59 UTC
[incubator-devlake] branch main updated: feat(config-ui): add clear and delete data scope (#5304)
This is an automated email from the ASF dual-hosted git repository.
likyh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new b67dacafc feat(config-ui): add clear and delete data scope (#5304)
b67dacafc is described below
commit b67dacafc2a656662fdd10dfff79ad747a620080
Author: 青湛 <0x...@gmail.com>
AuthorDate: Tue May 30 09:59:53 2023 +0800
feat(config-ui): add clear and delete data scope (#5304)
* refactor(config-ui): rename data-scope-form-2 to data-scope-select-remote
* feat(config-ui): add clear and delete data scope
---
config-ui/src/pages/connection/detail/api.ts | 8 ++
config-ui/src/pages/connection/detail/index.tsx | 116 ++++++++++++++++-----
config-ui/src/pages/connection/detail/styled.ts | 15 +--
.../api.ts | 0
.../index.tsx | 28 +----
.../styled.ts | 0
config-ui/src/plugins/components/index.ts | 2 +-
7 files changed, 109 insertions(+), 60 deletions(-)
diff --git a/config-ui/src/pages/connection/detail/api.ts b/config-ui/src/pages/connection/detail/api.ts
index c86588cc4..055719883 100644
--- a/config-ui/src/pages/connection/detail/api.ts
+++ b/config-ui/src/pages/connection/detail/api.ts
@@ -22,3 +22,11 @@ export const deleteConnection = (plugin: string, id: ID) =>
request(`/plugins/${plugin}/connections/${id}`, { method: 'delete' });
export const getDataScope = (plugin: string, id: ID) => request(`/plugins/${plugin}/connections/${id}/scopes`);
+
+export const deleteDataScope = (plugin: string, id: ID, scopeId: ID, onlyData: boolean) =>
+ request(`/plugins/${plugin}/connections/${id}/scopes/${scopeId}`, {
+ method: 'delete',
+ data: {
+ delete_data_only: onlyData,
+ },
+ });
diff --git a/config-ui/src/pages/connection/detail/index.tsx b/config-ui/src/pages/connection/detail/index.tsx
index 7e3d3e9fe..a82eba8c4 100644
--- a/config-ui/src/pages/connection/detail/index.tsx
+++ b/config-ui/src/pages/connection/detail/index.tsx
@@ -21,9 +21,8 @@ import { useParams, useHistory } from 'react-router-dom';
import { Button, Icon, Intent } from '@blueprintjs/core';
import { PageHeader, Dialog, IconButton, Table } from '@/components';
-import { transformEntities } from '@/config';
import { useTips, useConnections, useRefreshData } from '@/hooks';
-import { ConnectionForm, ConnectionStatus, DataScopeForm2 } from '@/plugins';
+import { ConnectionForm, ConnectionStatus, DataScopeSelectRemote, getPluginId } from '@/plugins';
import { operator } from '@/utils';
import * as API from './api';
@@ -35,16 +34,19 @@ interface Props {
}
const ConnectionDetail = ({ plugin, id }: Props) => {
- const [type, setType] = useState<'deleteConnection' | 'updateConnection' | 'createDataScope'>();
+ const [type, setType] = useState<
+ 'deleteConnection' | 'updateConnection' | 'createDataScope' | 'clearDataScope' | 'deleteDataScope'
+ >();
const [operating, setOperating] = useState(false);
const [version, setVersion] = useState(1);
+ const [scopeId, setScopeId] = useState<ID>();
const history = useHistory();
const { onGet, onTest, onRefresh } = useConnections();
const { setTips } = useTips();
const { ready, data } = useRefreshData(() => API.getDataScope(plugin, id), [version]);
- const { unique, status, name, icon, entities } = onGet(`${plugin}-${id}`);
+ const { unique, status, name, icon } = onGet(`${plugin}-${id}`);
const handleHideDialog = () => {
setType(undefined);
@@ -96,6 +98,31 @@ const ConnectionDetail = ({ plugin, id }: Props) => {
handleHideDialog();
};
+ const handleShowClearDataScopeDialog = (scopeId: ID) => {
+ setType('clearDataScope');
+ setScopeId(scopeId);
+ };
+
+ const handleShowDeleteDataScopeDialog = (scopeId: ID) => {
+ setType('deleteDataScope');
+ setScopeId(scopeId);
+ };
+
+ const handleDeleteDataScope = async (onlyData: boolean) => {
+ if (!scopeId) return;
+
+ const [success] = await operator(() => API.deleteDataScope(plugin, id, scopeId, onlyData), {
+ setOperating,
+ formatMessage: () => (onlyData ? 'Clear historical data successful.' : 'Delete Data Scope successful.'),
+ });
+
+ if (success) {
+ setVersion((v) => v + 1);
+ handleShowTips();
+ handleHideDialog();
+ }
+ };
+
return (
<PageHeader
breadcrumbs={[
@@ -105,25 +132,10 @@ const ConnectionDetail = ({ plugin, id }: Props) => {
extra={<Button intent={Intent.DANGER} icon="trash" text="Delete Connection" onClick={handleShowDeleteDialog} />}
>
<S.Wrapper>
- <div className="top">
- <div className="entities">
- <h3>Data Entities</h3>
- <span>
- {transformEntities(entities)
- .map((it) => it.label)
- .join(',')}
- </span>
- </div>
- <div className="authentication">
- <h3>
- <span>Authentication</span>
- <IconButton icon="annotation" tooltip="Edit Connection" onClick={handleShowUpdateDialog} />
- </h3>
- <span>Status: </span>
- <span>
- Status: <ConnectionStatus status={status} unique={unique} onTest={onTest} />
- </span>
- </div>
+ <div className="authentication">
+ <span style={{ marginRight: 4 }}>Authentication Status:</span>
+ <ConnectionStatus status={status} unique={unique} onTest={onTest} />
+ <IconButton icon="annotation" tooltip="Edit Connection" onClick={handleShowUpdateDialog} />
</div>
<div className="action">
<Button intent={Intent.PRIMARY} icon="add" text="Add Data Scope" onClick={handleShowCreateDataScopeDialog} />
@@ -136,6 +148,26 @@ const ConnectionDetail = ({ plugin, id }: Props) => {
dataIndex: 'name',
key: 'name',
},
+ {
+ title: '',
+ dataIndex: getPluginId(plugin),
+ key: 'id',
+ width: 100,
+ render: (id) => (
+ <>
+ <IconButton
+ icon="unarchive"
+ tooltip="Clear historical data"
+ onClick={() => handleShowClearDataScopeDialog(id)}
+ />
+ <IconButton
+ icon="trash"
+ tooltip="Delete Data Scope"
+ onClick={() => handleShowDeleteDataScopeDialog(id)}
+ />
+ </>
+ ),
+ },
]}
dataSource={data}
noData={{
@@ -148,6 +180,7 @@ const ConnectionDetail = ({ plugin, id }: Props) => {
{type === 'deleteConnection' && (
<Dialog
isOpen
+ style={{ width: 820 }}
title="Would you like to delete this Data Connection?"
okText="Confirm"
okLoading={operating}
@@ -192,7 +225,7 @@ const ConnectionDetail = ({ plugin, id }: Props) => {
}
onCancel={handleHideDialog}
>
- <DataScopeForm2
+ <DataScopeSelectRemote
plugin={plugin}
connectionId={id}
disabledScope={data}
@@ -201,6 +234,41 @@ const ConnectionDetail = ({ plugin, id }: Props) => {
/>
</Dialog>
)}
+ {type === 'clearDataScope' && (
+ <Dialog
+ isOpen
+ style={{ width: 820 }}
+ title="Would you like to clear the historical data of the selected Data Scope?"
+ okText="Confirm"
+ okLoading={operating}
+ onCancel={handleHideDialog}
+ onOk={() => handleDeleteDataScope(true)}
+ >
+ <S.DialogBody>
+ <Icon icon="warning-sign" />
+ <span>This operation cannot be undone.</span>
+ </S.DialogBody>
+ </Dialog>
+ )}
+ {type === 'deleteDataScope' && (
+ <Dialog
+ isOpen
+ style={{ width: 820 }}
+ title="Would you like to delete the selected Data Scope?"
+ okText="Confirm"
+ okLoading={operating}
+ onCancel={handleHideDialog}
+ onOk={() => handleDeleteDataScope(false)}
+ >
+ <S.DialogBody>
+ <Icon icon="warning-sign" />
+ <span>
+ This operation cannot be undone. Deleting Data Scope will delete all data that have been collected in the
+ past.
+ </span>
+ </S.DialogBody>
+ </Dialog>
+ )}
</PageHeader>
);
};
diff --git a/config-ui/src/pages/connection/detail/styled.ts b/config-ui/src/pages/connection/detail/styled.ts
index 4a9225132..ce2815f10 100644
--- a/config-ui/src/pages/connection/detail/styled.ts
+++ b/config-ui/src/pages/connection/detail/styled.ts
@@ -19,18 +19,13 @@
import styled from 'styled-components';
export const Wrapper = styled.div`
- .top {
+ .authentication {
display: flex;
- justify-content: space-between;
+ align-items: center;
+ justify-content: flex-end;
- h3 {
- margin-bottom: 16px;
- }
- }
-
- .authentication {
- h3 {
- span
+ & > .bp4-popover2-target {
+ margin-left: 8px;
}
}
diff --git a/config-ui/src/plugins/components/data-scope-form-2/api.ts b/config-ui/src/plugins/components/data-scope-select-remote/api.ts
similarity index 100%
rename from config-ui/src/plugins/components/data-scope-form-2/api.ts
rename to config-ui/src/plugins/components/data-scope-select-remote/api.ts
diff --git a/config-ui/src/plugins/components/data-scope-form-2/index.tsx b/config-ui/src/plugins/components/data-scope-select-remote/index.tsx
similarity index 92%
rename from config-ui/src/plugins/components/data-scope-form-2/index.tsx
rename to config-ui/src/plugins/components/data-scope-select-remote/index.tsx
index 4d64dc8df..b9954f010 100644
--- a/config-ui/src/plugins/components/data-scope-form-2/index.tsx
+++ b/config-ui/src/plugins/components/data-scope-select-remote/index.tsx
@@ -29,35 +29,21 @@ import { BitbucketDataScope } from '@/plugins/register/bitbucket';
import { AzureDataScope } from '@/plugins/register/azure';
import { SonarQubeDataScope } from '@/plugins/register/sonarqube';
import { PagerDutyDataScope } from '@/plugins/register/pagerduty';
+import { TapdDataScope } from '@/plugins/register/tapd';
import { ZentaoDataScope } from '@/plugins/register/zentao';
import * as API from './api';
import * as S from './styled';
-import { TapdDataScope } from '@/plugins/register/tapd';
interface Props {
plugin: string;
connectionId: ID;
disabledScope?: any[];
- cancelBtnProps?: {
- text?: string;
- };
- submitBtnProps?: {
- text?: string;
- };
onCancel?: () => void;
onSubmit?: (origin: any) => void;
}
-export const DataScopeForm2 = ({
- plugin,
- connectionId,
- disabledScope,
- onSubmit,
- onCancel,
- cancelBtnProps,
- submitBtnProps,
-}: Props) => {
+export const DataScopeSelectRemote = ({ plugin, connectionId, disabledScope, onSubmit, onCancel }: Props) => {
const [operating, setOperating] = useState(false);
const [scope, setScope] = useState<any>([]);
@@ -192,19 +178,11 @@ export const DataScopeForm2 = ({
)}
<div className="action">
- <Button
- outlined
- intent={Intent.PRIMARY}
- text="Cancel"
- {...cancelBtnProps}
- disabled={operating}
- onClick={onCancel}
- />
+ <Button outlined intent={Intent.PRIMARY} text="Cancel" disabled={operating} onClick={onCancel} />
<Button
outlined
intent={Intent.PRIMARY}
text="Save"
- {...submitBtnProps}
loading={operating}
disabled={!!error}
onClick={handleSubmit}
diff --git a/config-ui/src/plugins/components/data-scope-form-2/styled.ts b/config-ui/src/plugins/components/data-scope-select-remote/styled.ts
similarity index 100%
rename from config-ui/src/plugins/components/data-scope-form-2/styled.ts
rename to config-ui/src/plugins/components/data-scope-select-remote/styled.ts
diff --git a/config-ui/src/plugins/components/index.ts b/config-ui/src/plugins/components/index.ts
index 6a81da1a4..b7fc05447 100644
--- a/config-ui/src/plugins/components/index.ts
+++ b/config-ui/src/plugins/components/index.ts
@@ -19,10 +19,10 @@
export * from './connection-form';
export * from './connection-list';
export * from './connection-status';
-export * from './data-scope-form-2';
export * from './data-scope-miller-columns';
export * from './data-scope-search';
export * from './data-scope-select';
+export * from './data-scope-select-remote';
export * from './transformation';
export * from './transformation-form';
export * from './transformation-select';