This is an automated email from the ASF dual-hosted git repository.
mintsweet pushed a commit to branch feat-dora-config
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/feat-dora-config by this push:
new 76e89eece feat: adjust the part of github scope config cicd
76e89eece is described below
commit 76e89eece36c68ff7c0e13deea17ebc7d7ac9440
Author: mintsweet <[email protected]>
AuthorDate: Wed Sep 11 16:41:02 2024 +1200
feat: adjust the part of github scope config cicd
---
config-ui/src/api/scope-config/index.ts | 18 +++-
config-ui/src/api/scope-config/types.ts | 5 +
.../components/check-matched-items/index.tsx | 93 +++++++++++++++++++
.../src/plugins/components/deployments/index.tsx | 102 +++++++++++++++++++++
config-ui/src/plugins/components/index.ts | 2 +
.../plugins/components/scope-config-form/index.tsx | 2 +
.../src/plugins/register/github/transformation.tsx | 34 ++++---
7 files changed, 244 insertions(+), 12 deletions(-)
diff --git a/config-ui/src/api/scope-config/index.ts
b/config-ui/src/api/scope-config/index.ts
index 41547d9c0..f29786b56 100644
--- a/config-ui/src/api/scope-config/index.ts
+++ b/config-ui/src/api/scope-config/index.ts
@@ -18,7 +18,7 @@
import { request } from '@/utils';
-import { ICheck } from './types';
+import { ICheck, ITransform2deployments } from './types';
export const list = (plugin: string, connectionId: ID) =>
request(`/plugins/${plugin}/connections/${connectionId}/scope-configs`);
@@ -40,3 +40,19 @@ export const update = (plugin: string, connectionId: ID, id:
ID, data: any) =>
export const check = (plugin: string, id: ID): Promise<ICheck> =>
request(`/plugins/${plugin}/scope-config/${id}/projects`);
+
+export const deployments = (plugin: string, connectionId: ID):
Promise<string[]> =>
+ request(`/plugins/${plugin}/connections/${connectionId}/deployments`);
+
+export const transform2deployments = (
+ plugin: string,
+ connectionId: ID,
+ data: {
+ deploymentPattern: string;
+ productionPattern: string;
+ } & Pagination,
+): Promise<{ total: number; data: ITransform2deployments[] }> =>
+
request(`/plugins/${plugin}/connections/${connectionId}/transform-to-deployments`,
{
+ method: 'post',
+ data,
+ });
diff --git a/config-ui/src/api/scope-config/types.ts
b/config-ui/src/api/scope-config/types.ts
index 4c779c658..e61992aca 100644
--- a/config-ui/src/api/scope-config/types.ts
+++ b/config-ui/src/api/scope-config/types.ts
@@ -22,3 +22,8 @@ export type ICheck = {
name: string;
}>;
};
+
+export type ITransform2deployments = {
+ name: string;
+ url: string;
+};
diff --git a/config-ui/src/plugins/components/check-matched-items/index.tsx
b/config-ui/src/plugins/components/check-matched-items/index.tsx
new file mode 100644
index 000000000..ce9c2b12b
--- /dev/null
+++ b/config-ui/src/plugins/components/check-matched-items/index.tsx
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ *
+ */
+
+import { useState, useReducer } from 'react';
+import { SearchOutlined, PlusOutlined } from '@ant-design/icons';
+import { Flex, Button, Tag } from 'antd';
+
+import API from '@/api';
+import type { ITransform2deployments } from '@/api/scope-config/types';
+import { ExternalLink } from '@/components';
+
+const reducer = (state: ITransform2deployments[], action: { type: string;
payload: ITransform2deployments[] }) => {
+ switch (action.type) {
+ case 'APPEND':
+ return [...state, ...action.payload];
+ default:
+ return state;
+ }
+};
+
+interface Props {
+ plugin: string;
+ connectionId: ID;
+ transformation: any;
+}
+
+export const CheckMatchedItems = ({ plugin, connectionId, transformation }:
Props) => {
+ const [page, setPage] = useState(1);
+ const [total, setTotal] = useState(0);
+ const [loading, setLoading] = useState(false);
+
+ const [state, dispatch] = useReducer(reducer, []);
+
+ const handleLoadItems = async () => {
+ setLoading(true);
+ const res = await API.scopeConfig.transform2deployments(plugin,
connectionId, {
+ deploymentPattern: transformation.deploymentPattern,
+ productionPattern: transformation.productionPattern,
+ page,
+ pageSize: 10,
+ });
+
+ dispatch({ type: 'APPEND', payload: res.data });
+
+ setPage(page + 1);
+ setTotal(res.total);
+ setLoading(false);
+ };
+
+ return (
+ <Flex vertical gap="small">
+ <div>
+ <Button ghost type="primary" loading={loading} icon={<SearchOutlined
/>} onClick={handleLoadItems}>
+ Check Matched Items
+ </Button>
+ </div>
+ {!!state.length && (
+ <Flex vertical gap="small">
+ <h3>Matched Items</h3>
+ <Flex wrap="wrap" gap="small">
+ {state.map((it) => (
+ <Tag key={it.url} color="blue">
+ <ExternalLink link={it.url}>{it.name}</ExternalLink>
+ </Tag>
+ ))}
+ </Flex>
+ {total > state.length && (
+ <div>
+ <Button type="link" size="small" loading={loading}
icon={<PlusOutlined />} onClick={handleLoadItems}>
+ See More
+ </Button>
+ </div>
+ )}
+ </Flex>
+ )}
+ </Flex>
+ );
+};
diff --git a/config-ui/src/plugins/components/deployments/index.tsx
b/config-ui/src/plugins/components/deployments/index.tsx
new file mode 100644
index 000000000..b3b0d6a58
--- /dev/null
+++ b/config-ui/src/plugins/components/deployments/index.tsx
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ *
+ */
+
+import { useState, useEffect } from 'react';
+import { Space, Select, Input } from 'antd';
+import { useRequest } from '@mints/hooks';
+
+import API from '@/api';
+import { PageLoading } from '@/components';
+
+interface Props {
+ plugin: string;
+ connectionId: ID;
+ transformation: any;
+ setTransformation: React.Dispatch<React.SetStateAction<any>>;
+}
+
+export const Deployments = ({ plugin, connectionId, transformation,
setTransformation }: Props) => {
+ const [type, setType] = useState('regex');
+
+ const { loading, data } = useRequest(() =>
API.scopeConfig.deployments(plugin, connectionId), [plugin, connectionId]);
+
+ useEffect(() => {
+ if (transformation.envNamePattern) {
+ setType('regex');
+ }
+ }, [transformation]);
+
+ const handleChangeType = (t: string) => {
+ if (t === 'regex') {
+ setTransformation({
+ ...transformation,
+ envNameList: [],
+ });
+ }
+
+ if (t === 'select') {
+ setTransformation({
+ ...transformation,
+ envNamePattern: '',
+ });
+ }
+
+ setType(t);
+ };
+
+ const handleChangeRegex = (e: React.ChangeEvent<HTMLInputElement>) => {
+ const envNamePattern = e.target.value;
+ setTransformation({
+ ...transformation,
+ envNamePattern,
+ envNameList: [],
+ });
+ };
+
+ const handleChangeSelect = (value: string[]) => {
+ setTransformation({
+ ...transformation,
+ envNamePattern: '',
+ envNameList: value,
+ });
+ };
+
+ if (loading || !data) {
+ return <PageLoading />;
+ }
+
+ return (
+ <Space>
+ <Select value={type} onChange={handleChangeType}>
+ <Select.Option value="select">is one of</Select.Option>
+ <Select.Option value="regex">matches</Select.Option>
+ </Select>
+ {type === 'regex' ? (
+ <Input placeholder="(?i)prod(.*)" onChange={handleChangeRegex} />
+ ) : (
+ <Select mode="tags" style={{ width: 180 }} maxTagCount={2}
onChange={handleChangeSelect}>
+ {data.map((d) => (
+ <Select.Option key={d} value={d}>
+ {d}
+ </Select.Option>
+ ))}
+ </Select>
+ )}
+ </Space>
+ );
+};
diff --git a/config-ui/src/plugins/components/index.ts
b/config-ui/src/plugins/components/index.ts
index 337e446fe..4cbfa01e5 100644
--- a/config-ui/src/plugins/components/index.ts
+++ b/config-ui/src/plugins/components/index.ts
@@ -16,12 +16,14 @@
*
*/
+export * from './check-matched-items';
export * from './connection-form';
export * from './connection-list';
export * from './connection-select';
export * from './connection-status';
export * from './data-scope-remote';
export * from './data-scope-select';
+export * from './deployments';
export * from './plugin-name';
export * from './scope-config';
export * from './scope-config-form';
diff --git a/config-ui/src/plugins/components/scope-config-form/index.tsx
b/config-ui/src/plugins/components/scope-config-form/index.tsx
index 5c27d84d4..06b4e27c6 100644
--- a/config-ui/src/plugins/components/scope-config-form/index.tsx
+++ b/config-ui/src/plugins/components/scope-config-form/index.tsx
@@ -243,6 +243,8 @@ export const ScopeConfigForm = ({
{plugin === 'github' && (
<GitHubTransformation
+ plugin={plugin}
+ connectionId={connectionId}
entities={entities}
transformation={transformation}
setTransformation={setTransformation}
diff --git a/config-ui/src/plugins/register/github/transformation.tsx
b/config-ui/src/plugins/register/github/transformation.tsx
index 0d6473c4d..9114e72eb 100644
--- a/config-ui/src/plugins/register/github/transformation.tsx
+++ b/config-ui/src/plugins/register/github/transformation.tsx
@@ -23,15 +23,25 @@ import { theme, Form, Collapse, Input, Tag, Checkbox } from
'antd';
import { HelpTooltip, ExternalLink } from '@/components';
import { DOC_URL } from '@/release';
+import { CheckMatchedItems, Deployments } from '@/plugins';
interface Props {
+ plugin: string;
+ connectionId: ID;
entities: string[];
transformation: any;
setTransformation: React.Dispatch<React.SetStateAction<any>>;
setHasError: React.Dispatch<React.SetStateAction<boolean>>;
}
-export const GitHubTransformation = ({ entities, transformation,
setTransformation, setHasError }: Props) => {
+export const GitHubTransformation = ({
+ plugin,
+ connectionId,
+ entities,
+ transformation,
+ setTransformation,
+ setHasError,
+}: Props) => {
const [useCustom, setUseCustom] = useState(false);
useEffect(() => {
@@ -77,6 +87,8 @@ export const GitHubTransformation = ({ entities,
transformation, setTransformati
style={{ background: token.colorBgContainer }}
size="large"
items={renderCollapseItems({
+ plugin,
+ connectionId,
entities,
panelStyle,
transformation,
@@ -89,6 +101,8 @@ export const GitHubTransformation = ({ entities,
transformation, setTransformati
};
const renderCollapseItems = ({
+ plugin,
+ connectionId,
entities,
panelStyle,
transformation,
@@ -96,6 +110,8 @@ const renderCollapseItems = ({
useCustom,
onChangeUseCustom,
}: {
+ plugin: string;
+ connectionId: ID;
entities: string[];
panelStyle: React.CSSProperties;
transformation: any;
@@ -245,16 +261,11 @@ const renderCollapseItems = ({
</Checkbox>
<div style={{ margin: '8px 0', paddingLeft: 28 }}>
<span>If its environment name matches</span>
- <Input
- style={{ width: 180, margin: '0 8px' }}
- placeholder="(?i)prod(.*)"
- value={transformation.envNamePattern}
- onChange={(e) =>
- onChangeTransformation({
- ...transformation,
- envNamePattern: e.target.value,
- })
- }
+ <Deployments
+ plugin={plugin}
+ connectionId={connectionId}
+ transformation={transformation}
+ setTransformation={onChangeTransformation}
/>
<span>, this deployment is a ‘Production Deployment’</span>
</div>
@@ -296,6 +307,7 @@ const renderCollapseItems = ({
<span>, this deployment is a ‘Production Deployment’</span>
<HelpTooltip content="If you leave this field empty, all
Deployments will be tagged as in the Production environment. " />
</div>
+ <CheckMatchedItems plugin={plugin} connectionId={connectionId}
transformation={transformation} />
</>
),
},