This is an automated email from the ASF dual-hosted git repository.
mintsweet 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 f254f25c1 feat(config-ui): missed content about move data scope (#5331)
f254f25c1 is described below
commit f254f25c168f9fb74ab4e5c6b28711d048a49f03
Author: 青湛 <[email protected]>
AuthorDate: Thu Jun 1 11:34:49 2023 +0800
feat(config-ui): missed content about move data scope (#5331)
---
.../src/pages/blueprint/connection-detail/api.ts | 4 +-
.../pages/blueprint/connection-detail/index.tsx | 132 ++++++++++++---------
.../pages/blueprint/connection-detail/styled.ts | 8 +-
config-ui/src/pages/blueprint/detail/api.ts | 3 +-
.../pages/blueprint/detail/blueprint-detail.tsx | 19 ++-
.../components/add-connection-dialog/index.tsx | 24 +++-
.../configuration.tsx => configuration-panel.tsx} | 72 ++++++-----
.../detail/{panel/status.tsx => status-panel.tsx} | 12 +-
config-ui/src/pages/blueprint/detail/types.ts | 28 -----
config-ui/src/pages/blueprint/types.ts | 1 -
config-ui/src/pages/connection/detail/index.tsx | 1 -
.../components/data-scope-select-remote/index.tsx | 7 +-
.../plugins/components/data-scope-select/index.tsx | 94 +++++++++------
.../plugins/components/data-scope-select/styled.ts | 13 +-
14 files changed, 222 insertions(+), 196 deletions(-)
diff --git a/config-ui/src/pages/blueprint/connection-detail/api.ts
b/config-ui/src/pages/blueprint/connection-detail/api.ts
index 7686757f3..dac107063 100644
--- a/config-ui/src/pages/blueprint/connection-detail/api.ts
+++ b/config-ui/src/pages/blueprint/connection-detail/api.ts
@@ -26,5 +26,5 @@ export const updateBlueprint = (id: ID, payload: any) =>
export const getConnection = (plugin: string, connectionId: ID) =>
request(`/plugins/${plugin}/connections/${connectionId}`);
-export const getDataScope = (plugin: string, connectionId: ID, scopeId: ID) =>
- request(`/plugins/${plugin}/connections/${connectionId}/scopes/${scopeId}`);
+export const getDataScopes = (plugin: string, connectionId: ID) =>
+ request(`/plugins/${plugin}/connections/${connectionId}/scopes`);
diff --git a/config-ui/src/pages/blueprint/connection-detail/index.tsx
b/config-ui/src/pages/blueprint/connection-detail/index.tsx
index 657fd570c..39dc7cf44 100644
--- a/config-ui/src/pages/blueprint/connection-detail/index.tsx
+++ b/config-ui/src/pages/blueprint/connection-detail/index.tsx
@@ -21,10 +21,10 @@ import { useHistory, useParams } from 'react-router-dom';
import { Button, Intent, Position } from '@blueprintjs/core';
import { Popover2 } from '@blueprintjs/popover2';
-import { Dialog, PageHeader, PageLoading } from '@/components';
-import { EntitiesLabel } from '@/config';
+import { PageLoading, PageHeader, ExternalLink, Buttons, Table, Dialog } from
'@/components';
import { useRefreshData } from '@/hooks';
-import { DataScopeSelect, getPluginConfig } from '@/plugins';
+import { DataScopeSelect, getPluginId } from '@/plugins';
+import { operator } from '@/utils';
import * as API from './api';
import * as S from './styled';
@@ -33,33 +33,30 @@ export const BlueprintConnectionDetailPage = () => {
const [version, setVersion] = useState(1);
const [isOpen, setIsOpen] = useState(false);
- const { pname, bid, unique } = useParams<{ pname?: string; bid: string;
unique: string }>();
+ const { bid, unique } = useParams<{ bid: string; unique: string }>();
const history = useHistory();
const { ready, data } = useRefreshData(async () => {
const [plugin, connectionId] = unique.split('-');
- const blueprint = await API.getBlueprint(bid);
- const connection = await API.getConnection(plugin, connectionId);
- const scope = blueprint.settings.connections.find(
- (cs: any) => cs.plugin === plugin && cs.connectionId === +connectionId,
- ).scopes;
- const config = getPluginConfig(plugin);
- const origin = await Promise.all(scope.map((sc: any) =>
API.getDataScope(plugin, connectionId, sc.id)));
+ const [blueprint, connection, scopes] = await Promise.all([
+ API.getBlueprint(bid),
+ API.getConnection(plugin, connectionId),
+ API.getDataScopes(plugin, connectionId),
+ ]);
+
+ const scopeIds = blueprint.settings.connections
+ .find((cs: any) => cs.plugin === plugin && cs.connectionId ===
+connectionId)
+ .scopes.map((sc: any) => +sc.id);
return {
blueprint,
- bpName: blueprint.name,
- csName: connection.name,
- entities: scope[0].entities,
connection: {
unique,
plugin,
- connectionId: +connectionId,
+ id: +connectionId,
name: connection.name,
- icon: config.icon,
- scope,
- origin,
},
+ scopes: scopes.filter((sc: any) =>
scopeIds.includes(sc[getPluginId(plugin)])),
};
}, [version]);
@@ -67,52 +64,72 @@ export const BlueprintConnectionDetailPage = () => {
return <PageLoading />;
}
- const { blueprint, bpName, csName, entities, connection } = data;
+ const { blueprint, connection, scopes } = data;
const handleShowDataScope = () => setIsOpen(true);
const handleHideDataScope = () => setIsOpen(false);
const handleRemoveConnection = async () => {
- await API.updateBlueprint(blueprint.id, {
- ...blueprint,
- settings: {
- ...blueprint.settings,
- connections: blueprint.settings.connections.filter(
- (cs: any) => !(cs.plugin === connection.plugin && cs.connectionId
=== connection.connectionId),
- ),
- },
- });
- history.push(pname ? `/projects/:${pname}` :
`/blueprints/${blueprint.id}`);
+ const [success] = await operator(() =>
+ API.updateBlueprint(blueprint.id, {
+ ...blueprint,
+ settings: {
+ ...blueprint.settings,
+ connections: blueprint.settings.connections.filter(
+ (cs: any) => !(cs.plugin === connection.plugin && cs.connectionId
=== connection.id),
+ ),
+ },
+ }),
+ );
+
+ if (success) {
+ history.push(`/blueprints/${blueprint.id}`);
+ }
};
- const handleChangeDataScope = (scope: any) => {
- console.log(scope);
- setVersion((v) => v + 1);
+ const handleChangeDataScope = async (scope: any) => {
+ const [success] = await operator(
+ () =>
+ API.updateBlueprint(blueprint.id, {
+ ...blueprint,
+ settings: {
+ ...blueprint.settings,
+ connections: blueprint.settings.connections.map((cs: any) => {
+ if (cs.plugin === connection.plugin && cs.connectionId ===
connection.id) {
+ return {
+ ...cs,
+ scopes: scope.map((sc: any) => ({ id:
`${sc[getPluginId(connection.plugin)]}` })),
+ };
+ }
+ return cs;
+ }),
+ },
+ }),
+ {
+ formatMessage: () => 'Update data scope successful.',
+ },
+ );
+
+ if (success) {
+ handleHideDataScope();
+ setVersion((v) => v + 1);
+ }
};
return (
<PageHeader
breadcrumbs={[
- ...(pname
- ? [
- {
- name: 'Projects',
- path: '/projects',
- },
- {
- name: pname,
- path: `/projects/${pname}`,
- },
- ]
- : [{ name: bpName, path: `/blueprints/${bid}` }]),
- { name: `Connection - ${csName}`, path: '' },
+ { name: blueprint.name, path: `/blueprints/${bid}` },
+ { name: `Connection - ${connection.name}`, path: '' },
]}
>
- <S.Action>
+ <S.Top>
<span>
- <Button intent={Intent.PRIMARY} icon="annotation"
onClick={handleShowDataScope}>
- Edit Data Scope
- </Button>
+ If you would like to manage Data Entities and Data Scope of this
Connection, please{' '}
+ <ExternalLink
link={`/connections/${connection.plugin}/${connection.id}`}>
+ go to the Connection detail page
+ </ExternalLink>
+ .
</span>
<Popover2
position={Position.BOTTOM}
@@ -129,15 +146,11 @@ export const BlueprintConnectionDetailPage = () => {
Remove this Connection
</Button>
</Popover2>
- </S.Action>
- <S.Entities>
- <h4>Data Entities</h4>
- <ul>
- {entities.map((it: string) => (
- <li key={it}>{EntitiesLabel[it]}</li>
- ))}
- </ul>
- </S.Entities>
+ </S.Top>
+ <Buttons position="top" align="left">
+ <Button intent={Intent.PRIMARY} icon="annotation" text="Manage Data
Scope" onClick={handleShowDataScope} />
+ </Buttons>
+ <Table columns={[{ title: 'Data Scope', dataIndex: 'name', key: 'name'
}]} dataSource={scopes} />
<Dialog
isOpen={isOpen}
title="Change Data Scope"
@@ -147,7 +160,8 @@ export const BlueprintConnectionDetailPage = () => {
>
<DataScopeSelect
plugin={connection.plugin}
- connectionId={connection.connectionId}
+ connectionId={connection.id}
+ initialScope={scopes}
onCancel={handleHideDataScope}
onSubmit={handleChangeDataScope}
/>
diff --git a/config-ui/src/pages/blueprint/connection-detail/styled.ts
b/config-ui/src/pages/blueprint/connection-detail/styled.ts
index 92de69ebe..716316b8c 100644
--- a/config-ui/src/pages/blueprint/connection-detail/styled.ts
+++ b/config-ui/src/pages/blueprint/connection-detail/styled.ts
@@ -18,15 +18,11 @@
import styled from 'styled-components';
-export const Action = styled.div`
+export const Top = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
- margin-bottom: 24px;
-
- .bp4-button + .bp4-button {
- margin-left: 8px;
- }
+ margin-bottom: 36px;
`;
export const ActionDelete = styled.div`
diff --git a/config-ui/src/pages/blueprint/detail/api.ts
b/config-ui/src/pages/blueprint/detail/api.ts
index 2fc8424eb..2f260fe5f 100644
--- a/config-ui/src/pages/blueprint/detail/api.ts
+++ b/config-ui/src/pages/blueprint/detail/api.ts
@@ -24,7 +24,8 @@ export const getBlueprint = (id: ID): Promise<BlueprintType>
=> request(`/bluepr
export const getBlueprintPipelines = (id: ID) =>
request(`/blueprints/${id}/pipelines`);
-export const runBlueprint = (id: ID) => request(`/blueprints/${id}/trigger`, {
method: 'post' });
+export const runBlueprint = (id: ID, skipCollectors: boolean) =>
+ request(`/blueprints/${id}/trigger`, { method: 'post', data: {
skipCollectors } });
export const updateBlueprint = (id: ID, payload: any) =>
request(`/blueprints/${id}`, { method: 'patch', data: payload });
diff --git a/config-ui/src/pages/blueprint/detail/blueprint-detail.tsx
b/config-ui/src/pages/blueprint/detail/blueprint-detail.tsx
index 36cf81e99..f3daee155 100644
--- a/config-ui/src/pages/blueprint/detail/blueprint-detail.tsx
+++ b/config-ui/src/pages/blueprint/detail/blueprint-detail.tsx
@@ -25,8 +25,8 @@ import { PageLoading, Dialog } from '@/components';
import { useRefreshData } from '@/hooks';
import { operator } from '@/utils';
-import { Configuration } from './panel/configuration';
-import { Status } from './panel/status';
+import { ConfigurationPanel } from './configuration-panel';
+import { StatusPanel } from './status-panel';
import * as API from './api';
import * as S from './styled';
@@ -62,6 +62,7 @@ export const BlueprintDetail = ({ id }: Props) => {
}),
{
setOperating,
+ formatMessage: () => 'Update blueprint successful.',
},
);
@@ -71,9 +72,10 @@ export const BlueprintDetail = ({ id }: Props) => {
}
};
- const handleRun = async () => {
- const [success] = await operator(() => API.runBlueprint(id), {
+ const handleRun = async (skipCollectors: boolean) => {
+ const [success] = await operator(() => API.runBlueprint(id,
skipCollectors), {
setOperating,
+ formatMessage: () => 'Trigger blueprint successful.',
});
if (success) {
@@ -107,13 +109,18 @@ export const BlueprintDetail = ({ id }: Props) => {
id="status"
title="Status"
panel={
- <Status blueprint={blueprint} pipelineId={pipelines?.[0]?.id}
operating={operating} onRun={handleRun} />
+ <StatusPanel
+ blueprint={blueprint}
+ pipelineId={pipelines?.[0]?.id}
+ operating={operating}
+ onRun={handleRun}
+ />
}
/>
<Tab
id="configuration"
title="Configuration"
- panel={<Configuration blueprint={blueprint} operating={operating}
onUpdate={handleUpdate} />}
+ panel={<ConfigurationPanel blueprint={blueprint}
operating={operating} onUpdate={handleUpdate} />}
/>
<Tabs.Expander />
<Switch
diff --git
a/config-ui/src/pages/blueprint/detail/components/add-connection-dialog/index.tsx
b/config-ui/src/pages/blueprint/detail/components/add-connection-dialog/index.tsx
index 95982ba94..cf06480c3 100644
---
a/config-ui/src/pages/blueprint/detail/components/add-connection-dialog/index.tsx
+++
b/config-ui/src/pages/blueprint/detail/components/add-connection-dialog/index.tsx
@@ -16,29 +16,42 @@
*
*/
-import { useState } from 'react';
+import { useState, useMemo } from 'react';
import { Button, Intent } from '@blueprintjs/core';
import { Dialog, FormItem, Selector, Buttons } from '@/components';
import { useConnections } from '@/hooks';
-import { DataScopeSelect } from '@/plugins';
+import { DataScopeSelect, getPluginId } from '@/plugins';
import type { ConnectionItemType } from '@/store';
interface Props {
+ disabled: string[];
onCancel: () => void;
onSubmit: (value: any) => void;
}
-export const AddConnectionDialog = ({ onCancel, onSubmit }: Props) => {
+export const AddConnectionDialog = ({ disabled = [], onCancel, onSubmit }:
Props) => {
const [step, setStep] = useState(1);
const [selectedConnection, setSelectedConnection] =
useState<ConnectionItemType>();
const { connections } = useConnections();
- const handleSubmit = (scope: any) => console.log(scope);
+ const disabledItems = useMemo(
+ () => connections.filter((cs) => (disabled.length ?
disabled.includes(cs.unique) : false)),
+ [disabled],
+ );
+
+ const handleSubmit = (scope: any) => {
+ if (!selectedConnection) return;
+ onSubmit({
+ plugin: selectedConnection.plugin,
+ connectionId: selectedConnection.id,
+ scopes: scope.map((sc: any) => ({ id:
`${sc[getPluginId(selectedConnection.plugin)]}` })),
+ });
+ };
return (
- <Dialog style={{ width: 820 }} isOpen title={`Add a Connection - Step
${step}`} footer={null}>
+ <Dialog style={{ width: 820 }} isOpen title={`Add a Connection - Step
${step}`} footer={null} onCancel={onCancel}>
{step === 1 && (
<FormItem
label="Data Connections"
@@ -47,6 +60,7 @@ export const AddConnectionDialog = ({ onCancel, onSubmit }:
Props) => {
>
<Selector
items={connections}
+ disabledItems={disabledItems}
getKey={(it) => it.unique}
getName={(it) => it.name}
selectedItem={selectedConnection}
diff --git a/config-ui/src/pages/blueprint/detail/panel/configuration.tsx
b/config-ui/src/pages/blueprint/detail/configuration-panel.tsx
similarity index 75%
rename from config-ui/src/pages/blueprint/detail/panel/configuration.tsx
rename to config-ui/src/pages/blueprint/detail/configuration-panel.tsx
index 8d7b88220..a76f95655 100644
--- a/config-ui/src/pages/blueprint/detail/panel/configuration.tsx
+++ b/config-ui/src/pages/blueprint/detail/configuration-panel.tsx
@@ -20,16 +20,16 @@ import { useState, useEffect, useMemo } from 'react';
import { Link } from 'react-router-dom';
import { Button, Intent } from '@blueprintjs/core';
-import { IconButton, Table, NoData } from '@/components';
+import { IconButton, Table, NoData, Buttons } from '@/components';
import { useConnections } from '@/hooks';
import { getPluginConfig } from '@/plugins';
-import type { BlueprintType } from '../../types';
-import { ModeEnum } from '../../types';
-import { validRawPlan } from '../../utils';
+import type { BlueprintType } from '../types';
+import { ModeEnum } from '../types';
+import { validRawPlan } from '../utils';
-import { AdvancedEditor, UpdateNameDialog, UpdatePolicyDialog,
AddConnectionDialog } from '../components';
-import * as S from '../styled';
+import { AdvancedEditor, UpdateNameDialog, UpdatePolicyDialog,
AddConnectionDialog } from './components';
+import * as S from './styled';
interface Props {
blueprint: BlueprintType;
@@ -37,7 +37,7 @@ interface Props {
onUpdate: (payload: any, callback?: () => void) => void;
}
-export const Configuration = ({ blueprint, operating, onUpdate }: Props) => {
+export const ConfigurationPanel = ({ blueprint, operating, onUpdate }: Props)
=> {
const [type, setType] = useState<'name' | 'policy' | 'add-connection'>();
const [rawPlan, setRawPlan] = useState('');
@@ -83,10 +83,6 @@ export const Configuration = ({ blueprint, operating,
onUpdate }: Props) => {
setType('add-connection');
};
- const handleAddConnection = (value: any) => {
- console.log(value);
- };
-
return (
<S.ConfigurationPanel>
<div className="block">
@@ -149,22 +145,32 @@ export const Configuration = ({ blueprint, operating,
onUpdate }: Props) => {
}
/>
) : (
- <S.ConnectionList>
- {connections.map((cs) => (
- <S.ConnectionItem key={cs.unique}>
- <div className="title">
- <img src={cs.icon} alt="" />
- <span>{cs.name}</span>
- </div>
- <div className="count">
- <span>{cs.scope.length} data scope</span>
- </div>
- <div className="link">
- <Link to={`${cs.unique}`}>View Detail</Link>
- </div>
- </S.ConnectionItem>
- ))}
- </S.ConnectionList>
+ <>
+ <Buttons position="top" align="left">
+ <Button
+ intent={Intent.PRIMARY}
+ icon="add"
+ text="Add a Connection"
+ onClick={handleShowAddConnectionDialog}
+ />
+ </Buttons>
+ <S.ConnectionList>
+ {connections.map((cs) => (
+ <S.ConnectionItem key={cs.unique}>
+ <div className="title">
+ <img src={cs.icon} alt="" />
+ <span>{cs.name}</span>
+ </div>
+ <div className="count">
+ <span>{cs.scope.length} data scope</span>
+ </div>
+ <div className="link">
+ <Link
to={`/blueprints/${blueprint.id}/${cs.unique}`}>Edit Data Scope and Scope
Config</Link>
+ </div>
+ </S.ConnectionItem>
+ ))}
+ </S.ConnectionList>
+ </>
)}
</div>
)}
@@ -205,7 +211,17 @@ export const Configuration = ({ blueprint, operating,
onUpdate }: Props) => {
onSubmit={(payload) => onUpdate(payload, handleCancel)}
/>
)}
- {type === 'add-connection' && <AddConnectionDialog
onCancel={handleCancel} onSubmit={handleAddConnection} />}
+ {type === 'add-connection' && (
+ <AddConnectionDialog
+ disabled={connections.map((cs) => cs.unique)}
+ onCancel={handleCancel}
+ onSubmit={(connection) =>
+ onUpdate({
+ settings: { ...blueprint.settings, connections:
[...blueprint.settings.connections, connection] },
+ })
+ }
+ />
+ )}
</S.ConfigurationPanel>
);
};
diff --git a/config-ui/src/pages/blueprint/detail/panel/status.tsx
b/config-ui/src/pages/blueprint/detail/status-panel.tsx
similarity index 90%
rename from config-ui/src/pages/blueprint/detail/panel/status.tsx
rename to config-ui/src/pages/blueprint/detail/status-panel.tsx
index 264fa28b3..756e4b3f1 100644
--- a/config-ui/src/pages/blueprint/detail/panel/status.tsx
+++ b/config-ui/src/pages/blueprint/detail/status-panel.tsx
@@ -25,18 +25,18 @@ import { getCron } from '@/config';
import { PipelineContextProvider, PipelineInfo, PipelineTasks,
PipelineHistorical } from '@/pages';
import { formatTime } from '@/utils';
-import type { BlueprintType } from '../../types';
+import type { BlueprintType } from '../types';
-import * as S from '../styled';
+import * as S from './styled';
interface Props {
blueprint: BlueprintType;
pipelineId?: ID;
operating: boolean;
- onRun: () => void;
+ onRun: (skipCollectors: boolean) => void;
}
-export const Status = ({ blueprint, pipelineId, operating, onRun }: Props) => {
+export const StatusPanel = ({ blueprint, pipelineId, operating, onRun }:
Props) => {
const cron = useMemo(() => getCron(blueprint.isManual,
blueprint.cronConfig), [blueprint]);
return (
@@ -52,7 +52,7 @@ export const Status = ({ blueprint, pipelineId, operating,
onRun }: Props) => {
loading={operating}
intent={Intent.PRIMARY}
text="Re-transform Data"
- onClick={onRun}
+ onClick={() => onRun(true)}
/>
</Tooltip2>
<Button
@@ -60,7 +60,7 @@ export const Status = ({ blueprint, pipelineId, operating,
onRun }: Props) => {
loading={operating}
intent={Intent.PRIMARY}
text="Collect All Data"
- onClick={onRun}
+ onClick={() => onRun(false)}
/>
</div>
<PipelineContextProvider>
diff --git a/config-ui/src/pages/blueprint/detail/types.ts
b/config-ui/src/pages/blueprint/detail/types.ts
deleted file mode 100644
index 19e2a2ab8..000000000
--- a/config-ui/src/pages/blueprint/detail/types.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-export type ConfigConnectionItemType = {
- icon: string;
- name: string;
- connectionId: ID;
- plugin: string;
- entities: string[];
- selectedEntites: string[];
- scope: Array<{ id: string; entities: string[] }>;
- scopeIds: string[];
-};
diff --git a/config-ui/src/pages/blueprint/types.ts
b/config-ui/src/pages/blueprint/types.ts
index eec9164d6..ca87e5d6a 100644
--- a/config-ui/src/pages/blueprint/types.ts
+++ b/config-ui/src/pages/blueprint/types.ts
@@ -38,7 +38,6 @@ export type BlueprintType = {
connectionId: ID;
scopes?: Array<{
id: string;
- entities: string[];
}>;
}>;
};
diff --git a/config-ui/src/pages/connection/detail/index.tsx
b/config-ui/src/pages/connection/detail/index.tsx
index 0d7945497..12be3e8c3 100644
--- a/config-ui/src/pages/connection/detail/index.tsx
+++ b/config-ui/src/pages/connection/detail/index.tsx
@@ -109,7 +109,6 @@ const ConnectionDetail = ({ plugin, id }: Props) => {
const handleCreateDataScope = () => {
setVersion((v) => v + 1);
handleShowTips();
- handleHideDialog();
};
const handleShowClearDataScopeDialog = (scopeId: ID) => {
diff --git
a/config-ui/src/plugins/components/data-scope-select-remote/index.tsx
b/config-ui/src/plugins/components/data-scope-select-remote/index.tsx
index b9954f010..582be6462 100644
--- a/config-ui/src/plugins/components/data-scope-select-remote/index.tsx
+++ b/config-ui/src/plugins/components/data-scope-select-remote/index.tsx
@@ -39,8 +39,8 @@ interface Props {
plugin: string;
connectionId: ID;
disabledScope?: any[];
- onCancel?: () => void;
- onSubmit?: (origin: any) => void;
+ onCancel: () => void;
+ onSubmit: (origin: any) => void;
}
export const DataScopeSelectRemote = ({ plugin, connectionId, disabledScope,
onSubmit, onCancel }: Props) => {
@@ -79,9 +79,10 @@ export const DataScopeSelectRemote = ({ plugin,
connectionId, disabledScope, onS
data,
});
- onSubmit?.(res);
+ onSubmit(res);
} finally {
setOperating(false);
+ onCancel();
}
};
diff --git a/config-ui/src/plugins/components/data-scope-select/index.tsx
b/config-ui/src/plugins/components/data-scope-select/index.tsx
index 93cf8b353..4a3730972 100644
--- a/config-ui/src/plugins/components/data-scope-select/index.tsx
+++ b/config-ui/src/plugins/components/data-scope-select/index.tsx
@@ -17,9 +17,9 @@
*/
import { useState, useEffect } from 'react';
-import { Button, InputGroup, Intent } from '@blueprintjs/core';
+import { Button, Intent } from '@blueprintjs/core';
-import { FormItem, ExternalLink, Table, Buttons } from '@/components';
+import { PageLoading, FormItem, ExternalLink, Buttons, Table } from
'@/components';
import { useRefreshData } from '@/hooks';
import { getPluginId } from '@/plugins';
@@ -48,49 +48,67 @@ export const DataScopeSelect = ({ plugin, connectionId,
initialScope, onSubmit,
onSubmit?.(scope);
};
+ if (!ready || !data) {
+ return <PageLoading />;
+ }
+
return (
<FormItem
label="Select Data Scope"
subLabel={
- <>
- {' '}
- Select the data scope in this Connection that you wish to associate
with this Project. If you wish to add more
- Data Scope to this Connection, please{' '}
- <ExternalLink link={`/connections/${plugin}/${connectionId}`}>go to
the Connection page</ExternalLink>.
- </>
+ data.length ? (
+ <>
+ Select the data scope in this Connection that you wish to
associate with this Project. If you wish to add
+ more Data Scope to this Connection, please{' '}
+ <ExternalLink link={`/connections/${plugin}/${connectionId}`}>go
to the Connection page</ExternalLink>.
+ </>
+ ) : (
+ <>
+ There is no Data Scope in this connection yet, please{' '}
+ <ExternalLink link={`/connections/${plugin}/${connectionId}`}>
+ add Data Scope and manage their Scope Configs
+ </ExternalLink>{' '}
+ first.
+ </>
+ )
}
required
>
- <S.Wrapper>
- <div className="action">
- <Button intent={Intent.PRIMARY} icon="refresh" text="Refresh Data
Scope" />
- </div>
- <div className="search">
- <InputGroup placeholder="Search for Data Scopes" />
- </div>
- <Table
- noShadow
- loading={!ready}
- columns={[
- {
- title: 'Data Scope',
- dataIndex: 'name',
- key: 'name',
- },
- ]}
- dataSource={data}
- rowSelection={{
- rowKey: getPluginId(plugin),
- type: 'checkbox',
- selectedRowKeys: scopeIds as string[],
- onChange: (selectedRowKeys) => setScopeIds(selectedRowKeys),
- }}
- />
- <Buttons>
- <Button outlined intent={Intent.PRIMARY} text="Cancel"
onClick={onCancel} />
- <Button intent={Intent.PRIMARY} text="Save" onClick={handleSubmit} />
- </Buttons>
- </S.Wrapper>
+ {data.length ? (
+ <S.Wrapper>
+ <Buttons position="top" align="left">
+ <Button intent={Intent.PRIMARY} icon="refresh" text="Refresh Data
Scope" />
+ </Buttons>
+ <Table
+ noShadow
+ loading={!ready}
+ columns={[
+ {
+ title: 'Data Scope',
+ dataIndex: 'name',
+ key: 'name',
+ },
+ ]}
+ dataSource={data}
+ rowSelection={{
+ rowKey: getPluginId(plugin),
+ type: 'checkbox',
+ selectedRowKeys: scopeIds as string[],
+ onChange: (selectedRowKeys) => setScopeIds(selectedRowKeys),
+ }}
+ />
+ <Buttons>
+ <Button outlined intent={Intent.PRIMARY} text="Cancel"
onClick={onCancel} />
+ <Button disabled={!scopeIds.length} intent={Intent.PRIMARY}
text="Save" onClick={handleSubmit} />
+ </Buttons>
+ </S.Wrapper>
+ ) : (
+ <S.Wrapper>
+ <ExternalLink link={`/connections/${plugin}/${connectionId}`}>
+ <Button intent={Intent.PRIMARY} icon="add" text="Add Data Scope" />
+ </ExternalLink>
+ </S.Wrapper>
+ )}
</FormItem>
);
};
diff --git a/config-ui/src/plugins/components/data-scope-select/styled.ts
b/config-ui/src/plugins/components/data-scope-select/styled.ts
index 719705ec3..d61c686ae 100644
--- a/config-ui/src/plugins/components/data-scope-select/styled.ts
+++ b/config-ui/src/plugins/components/data-scope-select/styled.ts
@@ -19,16 +19,5 @@
import styled from 'styled-components';
export const Wrapper = styled.div`
- .action {
- margin-top: 24px;
- }
-
- .search {
- margin-top: 24px;
- margin-bottom: 24px;
- }
-
- .btns {
- display: flex;
- }
+ margin-top: 24px;
`;