Skip to content

Commit

Permalink
feat: add some tips when updating scope config (#7422)
Browse files Browse the repository at this point in the history
  • Loading branch information
mintsweet authored May 6, 2024
1 parent 8a6bbe2 commit 2164b9d
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 22 deletions.
5 changes: 5 additions & 0 deletions config-ui/src/api/scope-config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import { request } from '@/utils';

import { ICheck } from './types';

export const list = (plugin: string, connectionId: ID) =>
request(`/plugins/${plugin}/connections/${connectionId}/scope-configs`);

Expand All @@ -35,3 +37,6 @@ export const update = (plugin: string, connectionId: ID, id: ID, data: any) =>
method: 'patch',
data,
});

export const check = (plugin: string, id: ID): Promise<ICheck> =>
request(`/plugins/${plugin}/scope-config/${id}/projects`);
24 changes: 24 additions & 0 deletions config-ui/src/api/scope-config/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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 ICheck = {
count: number;
projects: Array<{
name: string;
}>;
};
75 changes: 58 additions & 17 deletions config-ui/src/plugins/components/scope-config/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@

import { useState } from 'react';
import { LinkOutlined, EditOutlined } from '@ant-design/icons';
import { Button, Modal } from 'antd';
import { theme, Button, Modal, Flex, Space } from 'antd';
import styled from 'styled-components';

import API from '@/api';
import { Message } from '@/components';
import { operator } from '@/utils';

import { PluginName } from '../plugin-name';
Expand All @@ -34,16 +35,39 @@ interface Props {
plugin: string;
connectionId: ID;
scopeId: ID;
scopeName: string;
id?: ID;
name?: string;
onSuccess?: () => void;
onSuccess?: (id?: ID) => void;
}

export const ScopeConfig = ({ plugin, connectionId, scopeId, id, name, onSuccess }: Props) => {
const [type, setType] = useState<'associate' | 'update'>();
export const ScopeConfig = ({ plugin, connectionId, scopeId, scopeName, id, name, onSuccess }: Props) => {
const [type, setType] = useState<'associate' | 'update' | 'relatedProjects'>();
const [relatedProjects, setRelatedProjects] = useState<Array<{ name: string; scopes: string[] }>>([]);

const {
token: { colorPrimary },
} = theme.useToken();

const handleHideDialog = () => setType(undefined);

const handleCheckScopeConfig = async () => {
if (!id) return;

const [success, res] = await operator(() => API.scopeConfig.check(plugin, id), { hideToast: true });

if (success) {
const projects = res.projects.map((it: any) => ({ name: it.name, scopes: [] }));

if (projects.length !== 1) {
setRelatedProjects(projects);
setType('relatedProjects');
} else {
setType('update');
}
}
};

const handleAssociate = async (trId: ID) => {
const [success] = await operator(
() => API.scope.update(plugin, connectionId, scopeId, { scopeConfigId: trId !== 'None' ? +trId : null }),
Expand All @@ -54,13 +78,13 @@ export const ScopeConfig = ({ plugin, connectionId, scopeId, id, name, onSuccess

if (success) {
handleHideDialog();
onSuccess?.();
onSuccess?.(id);
}
};

const handleUpdate = (trId: ID) => {
handleHideDialog();
onSuccess?.();
onSuccess?.(id);
};

return (
Expand All @@ -74,17 +98,7 @@ export const ScopeConfig = ({ plugin, connectionId, scopeId, id, name, onSuccess
setType('associate');
}}
/>
{id && (
<Button
size="small"
type="link"
icon={<EditOutlined />}
onClick={() => {
// TO-DO: check if the scope config is associated with any scope
setType('update');
}}
/>
)}
{id && <Button size="small" type="link" icon={<EditOutlined />} onClick={handleCheckScopeConfig} />}
{type === 'associate' && (
<Modal
open
Expand Down Expand Up @@ -127,6 +141,33 @@ export const ScopeConfig = ({ plugin, connectionId, scopeId, id, name, onSuccess
/>
</Modal>
)}
{type === 'relatedProjects' && (
<Modal
open
width={830}
centered
footer={null}
title={`Edit '${name}' for '${scopeName}'`}
onCancel={handleHideDialog}
>
<Message content="The change will apply to all following projects:" />
<ul style={{ marginTop: 15, marginLeft: 30 }}>
{relatedProjects.map((it) => (
<li style={{ color: colorPrimary }}>
{it.name}:{it.scopes.join(',')}
</li>
))}
</ul>
<Flex justify="end">
<Space>
<Button onClick={handleHideDialog}>Cancel</Button>
<Button type="primary" onClick={() => setType('update')}>
Continue
</Button>
</Space>
</Flex>
</Modal>
)}
</Wrapper>
);
};
3 changes: 2 additions & 1 deletion config-ui/src/routes/blueprint/connection-detail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -263,11 +263,12 @@ export const BlueprintConnectionDetailPage = () => {
{
title: 'Scope Config',
key: 'scopeConfig',
render: (_, { id, scopeConfigId, scopeConfigName }) => (
render: (_, { id, name, scopeConfigId, scopeConfigName }) => (
<ScopeConfig
plugin={plugin}
connectionId={connectionId}
scopeId={id}
scopeName={name}
id={scopeConfigId}
name={scopeConfigName}
onSuccess={handleChangeScopeConfig}
Expand Down
50 changes: 46 additions & 4 deletions config-ui/src/routes/connection/connection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,13 @@ export const Connection = () => {
token: { colorPrimary },
} = theme.useToken();

const [modal, contextHolder] = Modal.useModal();

const dispatch = useAppDispatch();
const connection = useAppSelector((state) => selectConnection(state, `${plugin}-${connectionId}`)) as IConnection;

const navigate = useNavigate();

const { ready, data } = useRefreshData(
() => API.scope.list(plugin, connectionId, { page, pageSize, blueprints: true }),
[version, page, pageSize],
Expand Down Expand Up @@ -227,9 +230,46 @@ export const Connection = () => {
}
};

const handleScopeConfigChange = () => {
// TO-DO: check scope config change will effect the scope config
setVersion(version + 1);
const handleScopeConfigChange = async (scopeConfigId?: ID) => {
if (!scopeConfigId) {
return;
}

const [success, res] = await operator(() => API.scopeConfig.check(plugin, scopeConfigId), { hideToast: true });

if (success) {
modal.success({
closable: true,
centered: true,
width: 830,
title: 'Scope Config Saved',
content: (
<>
<div style={{ marginBottom: 16 }}>
The listed projects are impacted. Please re-transform the data to apply the updated scope config.
</div>
<ul>
{res.projects.map((it: any) => (
<li style={{ marginBottom: 10 }}>
<Space>
<span>{it.name}</span>
<Button
size="small"
type="link"
onClick={() => navigate(PATHS.PROJECT(it.name, { tab: 'status' }))}
>
Re-transform Data
</Button>
</Space>
</li>
))}
</ul>
</>
),
footer: null,
onCancel: () => setVersion(version + 1),
});
}
};

return (
Expand Down Expand Up @@ -305,11 +345,12 @@ export const Connection = () => {
title: 'Scope Config',
key: 'scopeConfig',
width: 400,
render: (_, { id, configId, configName }) => (
render: (_, { id, name, configId, configName }) => (
<ScopeConfig
plugin={plugin}
connectionId={connectionId}
scopeId={id}
scopeName={name}
id={configId}
name={configName}
onSuccess={handleScopeConfigChange}
Expand Down Expand Up @@ -515,6 +556,7 @@ export const Connection = () => {
)}
</Modal>
)}
{contextHolder}
</PageHeader>
);
};

0 comments on commit 2164b9d

Please sign in to comment.