mirror of https://gitee.com/topiam/eiam
⚡ 应用分组
parent
43af7e668f
commit
1f66d372a0
|
@ -134,26 +134,44 @@ export default [
|
|||
},
|
||||
],
|
||||
},
|
||||
//应用列表
|
||||
//应用管理
|
||||
{
|
||||
name: 'app',
|
||||
icon: 'AppstoreOutlined',
|
||||
path: '/app',
|
||||
component: './app/AppList',
|
||||
},
|
||||
//创建应用
|
||||
{
|
||||
name: 'app.create',
|
||||
path: '/app/create',
|
||||
hideInMenu: true,
|
||||
component: './app/AppCreate',
|
||||
},
|
||||
//应用配置
|
||||
{
|
||||
name: 'app.config',
|
||||
path: '/app/config',
|
||||
hideInMenu: true,
|
||||
component: './app/AppConfig',
|
||||
routes: [
|
||||
// 应用列表
|
||||
{
|
||||
path: '/app',
|
||||
redirect: '/app/list',
|
||||
},
|
||||
// 应用列表
|
||||
{
|
||||
name: 'list',
|
||||
path: '/app/list',
|
||||
component: './app/AppList',
|
||||
},
|
||||
//创建应用
|
||||
{
|
||||
name: 'create',
|
||||
path: '/app/list/create',
|
||||
hideInMenu: true,
|
||||
component: './app/AppCreate',
|
||||
},
|
||||
//应用配置
|
||||
{
|
||||
name: 'config',
|
||||
path: '/app/list/config',
|
||||
hideInMenu: true,
|
||||
component: './app/AppConfig',
|
||||
},
|
||||
// 应用分组
|
||||
{
|
||||
name: 'group',
|
||||
path: '/app/group',
|
||||
component: './app/AppGroup',
|
||||
},
|
||||
],
|
||||
},
|
||||
//行为审计
|
||||
{
|
||||
|
|
|
@ -57,7 +57,7 @@ const GlobalHeaderRight: React.FC = () => {
|
|||
return (
|
||||
<div className={styles.main}>
|
||||
<Helmet>
|
||||
<link rel="icon" href={initialState?.globalConfig?.appearance?.favicon} />
|
||||
<link rel="icon" href={'/favicon.ico'} />
|
||||
</Helmet>
|
||||
<About />
|
||||
<SelectLang className={styles.action} />
|
||||
|
|
|
@ -39,6 +39,8 @@ export default {
|
|||
'menu.account.logout': '退出登录',
|
||||
'menu.social-bind': '用户绑定',
|
||||
'menu.app': '应用管理',
|
||||
'menu.app.list': '应用列表',
|
||||
'menu.app.group': '应用分组',
|
||||
'menu.app.create': '创建应用',
|
||||
'menu.app.config': '应用配置',
|
||||
'menu.account': '账户管理',
|
||||
|
|
|
@ -81,7 +81,7 @@ export default () => {
|
|||
history.push(`/account/identity-source`);
|
||||
return;
|
||||
}
|
||||
if (!type) {
|
||||
if (!type || !IdentitySourceDetailTabs[type]) {
|
||||
setTabActiveKey(IdentitySourceDetailTabs.config);
|
||||
history.push({
|
||||
pathname: location.pathname,
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { getApp, updateApp } from '@/services/app';
|
||||
import { updateApp } from '@/services/app';
|
||||
|
||||
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
|
||||
import { useAsyncEffect } from 'ahooks';
|
||||
|
@ -30,6 +30,7 @@ import classNames from 'classnames';
|
|||
import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import { uploadFile } from '@/services/upload';
|
||||
import { GetApp } from '@/pages/app/AppConfig/data';
|
||||
import { getApp } from '../../service';
|
||||
|
||||
const prefixCls = 'app-basic-info';
|
||||
const AppBasic = (props: { appId: string }) => {
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* eiam-console - Employee Identity and Access Management
|
||||
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { getPermissionResource, permissionResourceParamCheck } from '../../service';
|
||||
import { ModalForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components';
|
||||
import { Form, Spin } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import { useAsyncEffect } from 'ahooks';
|
||||
import Paragraph from 'antd/es/typography/Paragraph';
|
||||
|
||||
type UpdateFormProps = {
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
id?: string;
|
||||
/**
|
||||
* SYSTEM
|
||||
*/
|
||||
appId: string;
|
||||
/**
|
||||
* 是否显示
|
||||
*/
|
||||
open: boolean;
|
||||
/**
|
||||
* 取消方法
|
||||
*/
|
||||
onCancel: (e?: React.MouseEvent | React.KeyboardEvent) => void;
|
||||
/**
|
||||
* 提交
|
||||
*/
|
||||
onFinish?: (formData: Record<string, string>) => Promise<boolean | void>;
|
||||
};
|
||||
const UpdateResource: React.FC<UpdateFormProps> = (props) => {
|
||||
const { open, onCancel, onFinish, id, appId } = props;
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [form] = Form.useForm();
|
||||
|
||||
useAsyncEffect(async () => {
|
||||
if (open && id) {
|
||||
setLoading(true);
|
||||
const { success, result } = await getPermissionResource(id);
|
||||
if (success && result) {
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, [id, onCancel, open]);
|
||||
|
||||
return (
|
||||
<ModalForm
|
||||
title="修改资源"
|
||||
width={'500px'}
|
||||
open={open}
|
||||
labelCol={{ span: 4 }}
|
||||
wrapperCol={{ span: 20 }}
|
||||
layout={'horizontal'}
|
||||
labelAlign={'right'}
|
||||
modalProps={{
|
||||
maskClosable: true,
|
||||
destroyOnClose: true,
|
||||
onCancel: onCancel,
|
||||
}}
|
||||
form={form}
|
||||
onFinish={async (values) => {
|
||||
setLoading(true);
|
||||
const result = await onFinish?.(values);
|
||||
setLoading(false);
|
||||
return result;
|
||||
}}
|
||||
>
|
||||
<Spin spinning={loading}>
|
||||
<ProFormText name={'id'} hidden />
|
||||
<ProFormText
|
||||
name="name"
|
||||
label="资源名称"
|
||||
placeholder="请输入资源名称"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: '请输入资源名称',
|
||||
},
|
||||
{
|
||||
validator: async (rule, value) => {
|
||||
if (!value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
setLoading(true);
|
||||
const { success, result } = await permissionResourceParamCheck(
|
||||
appId,
|
||||
'NAME',
|
||||
value,
|
||||
id,
|
||||
);
|
||||
setLoading(false);
|
||||
if (!success) {
|
||||
return Promise.reject<any>();
|
||||
}
|
||||
if (!result) {
|
||||
return Promise.reject<any>(new Error('资源名称已存在'));
|
||||
}
|
||||
},
|
||||
validateTrigger: ['onBlur'],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormText
|
||||
name="code"
|
||||
label="资源编码"
|
||||
placeholder="请输入资源编码"
|
||||
proFieldProps={{
|
||||
render: (value: string) => {
|
||||
return (
|
||||
value && (
|
||||
<Paragraph copyable={{ text: value }} style={{ marginBottom: '0' }}>
|
||||
<span
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `<span>${value}</span>`,
|
||||
}}
|
||||
/>
|
||||
</Paragraph>
|
||||
)
|
||||
);
|
||||
},
|
||||
}}
|
||||
readonly
|
||||
extra="资源编码在当前应用中的唯一标识,不能重复,仅支持英文、数字、下划线,创建后不可修改。"
|
||||
/>
|
||||
<ProFormTextArea
|
||||
name="desc"
|
||||
fieldProps={{ rows: 2, maxLength: 20, showCount: false }}
|
||||
label="资源描述"
|
||||
placeholder="请输入资源描述"
|
||||
/>
|
||||
</Spin>
|
||||
</ModalForm>
|
||||
);
|
||||
};
|
||||
export default UpdateResource;
|
|
@ -21,6 +21,7 @@ import {
|
|||
ModalForm,
|
||||
PageContainer,
|
||||
ProCard,
|
||||
ProFormSelect,
|
||||
ProFormText,
|
||||
ProFormTextArea,
|
||||
ProList,
|
||||
|
@ -38,6 +39,7 @@ import classnames from 'classnames';
|
|||
import { ListTemplate } from './data.d';
|
||||
import { AppType } from '@/constant';
|
||||
import { createApp, getAppTemplateList } from './service';
|
||||
import { getAllAppGroupList } from '@/services/app';
|
||||
|
||||
const { Paragraph } = Typography;
|
||||
const prefixCls = 'topiam-create-app';
|
||||
|
@ -106,7 +108,7 @@ const CreateApp = (props: {
|
|||
onOk: () => {
|
||||
successModal.destroy();
|
||||
history.push(
|
||||
`/app/config?id=${result.id}&name=${values.name}&protocol=${protocol}`,
|
||||
`/app/list/config?id=${result.id}&name=${values.name}&protocol=${protocol}`,
|
||||
);
|
||||
},
|
||||
});
|
||||
|
@ -128,6 +130,23 @@ const CreateApp = (props: {
|
|||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormSelect
|
||||
name="groups"
|
||||
mode="multiple"
|
||||
label={'归属分组'}
|
||||
request={async () => {
|
||||
setLoading(true);
|
||||
const { success, data } = await getAllAppGroupList({}, {}, {}).finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
if (success && data) {
|
||||
return data.map((i) => {
|
||||
return { label: i.name, value: i.id };
|
||||
});
|
||||
}
|
||||
return [];
|
||||
}}
|
||||
/>
|
||||
<ProFormTextArea
|
||||
name="remark"
|
||||
preserve={false}
|
||||
|
@ -232,22 +251,20 @@ const AppCreate = () => {
|
|||
);
|
||||
}}
|
||||
/>
|
||||
{createAppTemplate && (
|
||||
<CreateApp
|
||||
code={createAppTemplate?.code}
|
||||
name={createAppTemplate?.name}
|
||||
protocol={createAppTemplate.protocol}
|
||||
open={createAppOpen}
|
||||
onCancel={() => {
|
||||
setCreateAppOpen(false);
|
||||
setCreateAppTemplate(undefined);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</PageContainer>
|
||||
{createAppTemplate && (
|
||||
<CreateApp
|
||||
code={createAppTemplate?.code}
|
||||
name={createAppTemplate?.name}
|
||||
protocol={createAppTemplate.protocol}
|
||||
open={createAppOpen}
|
||||
onCancel={() => {
|
||||
setCreateAppOpen(false);
|
||||
setCreateAppTemplate(undefined);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default () => {
|
||||
return <AppCreate />;
|
||||
};
|
||||
export default AppCreate;
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* eiam-console - Employee Identity and Access Management
|
||||
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
||||
import type { ActionType, ProColumns } from '@ant-design/pro-components';
|
||||
import { PageContainer, ProTable } from '@ant-design/pro-components';
|
||||
import { App, Button, Popconfirm, Tag } from 'antd';
|
||||
import { useRef, useState } from 'react';
|
||||
import CreateModal from './components/CreateModal';
|
||||
import UpdateModal from './components/UpdateModal';
|
||||
import { createAppGroup, removeAppGroup, updateAppGroup } from './service';
|
||||
import { useIntl } from '@@/exports';
|
||||
import { getAppGroupList } from '@/services/app';
|
||||
|
||||
export default () => {
|
||||
const intl = useIntl();
|
||||
const actionRef = useRef<ActionType>();
|
||||
const [createModalOpen, setCreateModalOpen] = useState<boolean>(false);
|
||||
const [updateModalOpen, setUpdateModalOpen] = useState<boolean>(false);
|
||||
const [id, setId] = useState<string>();
|
||||
const { message } = App.useApp();
|
||||
const columns: ProColumns<AppAPI.AppGroupList>[] = [
|
||||
{
|
||||
title: intl.formatMessage({ id: 'pages.app_group.list.column.name' }),
|
||||
dataIndex: 'name',
|
||||
fixed: 'left',
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: 'pages.app_group.list.column.code' }),
|
||||
dataIndex: 'code',
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: 'pages.app_group.list.column.app_count' }),
|
||||
dataIndex: 'appCount',
|
||||
search: false,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: 'pages.app_group.list.column.type' }),
|
||||
dataIndex: 'type',
|
||||
valueEnum: {
|
||||
default: {
|
||||
text: intl.formatMessage({
|
||||
id: 'pages.app_group.list.column.type.default',
|
||||
}),
|
||||
},
|
||||
custom: {
|
||||
text: intl.formatMessage({
|
||||
id: 'pages.app_group.list.column.type.custom',
|
||||
}),
|
||||
},
|
||||
},
|
||||
render: (_, record) => (
|
||||
<>
|
||||
{record.type === 'custom' && (
|
||||
<Tag color={'#108ee9'} key={'custom'}>
|
||||
{intl.formatMessage({
|
||||
id: 'pages.app_group.list.column.type.custom',
|
||||
})}
|
||||
</Tag>
|
||||
)}
|
||||
{record.type === 'default' && (
|
||||
<Tag color={'#2db7f5'} key={'default'}>
|
||||
{intl.formatMessage({
|
||||
id: 'pages.app_group.list.column.type.default',
|
||||
})}
|
||||
</Tag>
|
||||
)}
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: 'pages.app_group.list.column.create_time' }),
|
||||
dataIndex: 'createTime',
|
||||
search: false,
|
||||
align: 'center',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: 'pages.app_group.list.column.remark' }),
|
||||
dataIndex: 'remark',
|
||||
search: false,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: 'pages.app_group.list.column.option' }),
|
||||
valueType: 'option',
|
||||
key: 'option',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
render: (text, record) => [
|
||||
<a
|
||||
key="editable"
|
||||
onClick={() => {
|
||||
setId(record.id);
|
||||
setUpdateModalOpen(true);
|
||||
}}
|
||||
>
|
||||
{intl.formatMessage({ id: 'app.update' })}
|
||||
</a>,
|
||||
<Popconfirm
|
||||
title={intl.formatMessage({
|
||||
id: 'pages.app_group.list.actions.popconfirm.delete',
|
||||
})}
|
||||
placement="bottomRight"
|
||||
icon={
|
||||
<QuestionCircleOutlined
|
||||
style={{
|
||||
color: 'red',
|
||||
}}
|
||||
/>
|
||||
}
|
||||
onConfirm={async () => {
|
||||
const { success } = await removeAppGroup(record.id);
|
||||
if (success) {
|
||||
message.success(intl.formatMessage({ id: 'app.operation_success' }));
|
||||
actionRef.current?.reload();
|
||||
return;
|
||||
}
|
||||
}}
|
||||
okText={intl.formatMessage({ id: 'app.yes' })}
|
||||
cancelText={intl.formatMessage({ id: 'app.no' })}
|
||||
key="delete"
|
||||
>
|
||||
<a target="_blank" key="remove" style={{ color: 'red' }}>
|
||||
{intl.formatMessage({ id: 'app.delete' })}
|
||||
</a>
|
||||
</Popconfirm>,
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<PageContainer>
|
||||
<ProTable<AppAPI.AppGroupList>
|
||||
columns={columns}
|
||||
actionRef={actionRef}
|
||||
request={getAppGroupList}
|
||||
rowKey="id"
|
||||
search={{
|
||||
labelWidth: 'auto',
|
||||
}}
|
||||
scroll={{ x: 900 }}
|
||||
form={{
|
||||
syncToUrl: (values, type) => {
|
||||
if (type === 'get') {
|
||||
return {
|
||||
...values,
|
||||
};
|
||||
}
|
||||
return values;
|
||||
},
|
||||
}}
|
||||
pagination={{
|
||||
pageSize: 5,
|
||||
}}
|
||||
dateFormatter="string"
|
||||
toolBarRender={() => [
|
||||
<Button
|
||||
key="button"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => {
|
||||
setCreateModalOpen(true);
|
||||
}}
|
||||
type="primary"
|
||||
>
|
||||
{intl.formatMessage({ id: 'pages.app_group.list.create' })}
|
||||
</Button>,
|
||||
]}
|
||||
/>
|
||||
<CreateModal
|
||||
open={createModalOpen}
|
||||
onCancel={() => {
|
||||
setCreateModalOpen(false);
|
||||
}}
|
||||
onFinish={async (values) => {
|
||||
const { result, success } = await createAppGroup(values);
|
||||
if (success && result) {
|
||||
message.success(intl.formatMessage({ id: 'app.create_success' }));
|
||||
actionRef.current?.reload();
|
||||
}
|
||||
actionRef.current?.reload();
|
||||
setCreateModalOpen(false);
|
||||
return true;
|
||||
}}
|
||||
/>
|
||||
{id && (
|
||||
<UpdateModal
|
||||
open={updateModalOpen}
|
||||
id={id}
|
||||
onCancel={() => {
|
||||
setUpdateModalOpen(false);
|
||||
}}
|
||||
onFinish={async (values) => {
|
||||
const { result, success } = await updateAppGroup(values);
|
||||
if (success && result) {
|
||||
message.success(intl.formatMessage({ id: 'app.create_success' }));
|
||||
actionRef.current?.reload();
|
||||
}
|
||||
actionRef.current?.reload();
|
||||
setUpdateModalOpen(false);
|
||||
return true;
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* eiam-console - Employee Identity and Access Management
|
||||
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ModalForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components';
|
||||
import { Form, Spin } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import { useIntl } from '@@/exports';
|
||||
import { getAppGroup } from '@/pages/app/AppGroup/service';
|
||||
|
||||
export default (props: {
|
||||
id: string;
|
||||
open: boolean;
|
||||
onFinish: (formData: Record<string, string>) => Promise<boolean | void>;
|
||||
onCancel: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
}) => {
|
||||
const { id, open, onCancel, onFinish } = props;
|
||||
const [form] = Form.useForm();
|
||||
const intl = useIntl();
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
|
||||
return (
|
||||
<ModalForm
|
||||
title={intl.formatMessage({ id: 'pages.app_group.update.modal_form.title' })}
|
||||
form={form}
|
||||
open={open}
|
||||
labelCol={{ span: 4 }}
|
||||
wrapperCol={{ span: 20 }}
|
||||
width={'500px'}
|
||||
labelAlign={'right'}
|
||||
preserve={false}
|
||||
layout={'horizontal'}
|
||||
autoFocusFirstInput
|
||||
modalProps={{
|
||||
maskClosable: true,
|
||||
destroyOnClose: true,
|
||||
onCancel: onCancel,
|
||||
}}
|
||||
onOpenChange={async (visible) => {
|
||||
if (visible) {
|
||||
setLoading(true);
|
||||
const { result, success } = await getAppGroup(id).finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
if (success) {
|
||||
form.setFieldsValue(result);
|
||||
}
|
||||
}
|
||||
}}
|
||||
onFinish={async (values) => {
|
||||
setLoading(true);
|
||||
await onFinish(values).finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Spin spinning={loading}>
|
||||
<ProFormText hidden name="id" />
|
||||
<ProFormText
|
||||
label={intl.formatMessage({ id: 'pages.app_group.modal_form.name' })}
|
||||
name="name"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({
|
||||
id: 'pages.app_group.modal_form.name.rule.0.message',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormText
|
||||
label={intl.formatMessage({ id: 'pages.app_group.modal_form.name' })}
|
||||
name="code"
|
||||
readonly
|
||||
/>
|
||||
<ProFormTextArea
|
||||
label={intl.formatMessage({ id: 'pages.app_group.modal_form.remark' })}
|
||||
name="remark"
|
||||
fieldProps={{
|
||||
placeholder: intl.formatMessage({
|
||||
id: 'pages.app_group.modal_form.remark.placeholder',
|
||||
}),
|
||||
rows: 2,
|
||||
maxLength: 20,
|
||||
autoComplete: 'off',
|
||||
showCount: true,
|
||||
}}
|
||||
/>
|
||||
</Spin>
|
||||
</ModalForm>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* eiam-console - Employee Identity and Access Management
|
||||
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* eiam-console - Employee Identity and Access Management
|
||||
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { request } from '@umijs/max';
|
||||
|
||||
/**
|
||||
* 创建应用分组
|
||||
*/
|
||||
export async function createAppGroup(
|
||||
params: Record<string, string>,
|
||||
): Promise<API.ApiResult<Record<string, string>>> {
|
||||
return request<API.ApiResult<Record<string, string>>>(`/api/v1/app/group/create`, {
|
||||
method: 'POST',
|
||||
data: params,
|
||||
requestType: 'json',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用分组
|
||||
*/
|
||||
export async function getAppGroup(id: string): Promise<API.ApiResult<Record<string, string>>> {
|
||||
return request<API.ApiResult<Record<string, string>>>(`/api/v1/app/group/get/${id}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改应用分组
|
||||
*/
|
||||
export async function updateAppGroup(
|
||||
params: Record<string, string>,
|
||||
): Promise<API.ApiResult<Record<string, string>>> {
|
||||
return request<API.ApiResult<Record<string, string>>>(`/api/v1/app/group/update`, {
|
||||
method: 'PUT',
|
||||
data: params,
|
||||
requestType: 'json',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove App Group
|
||||
*/
|
||||
export async function removeAppGroup(id: string): Promise<API.ApiResult<boolean>> {
|
||||
return request<API.ApiResult<boolean>>(`/api/v1/app/group/delete/${id}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { getAppList } from '@/services/app';
|
||||
import { getAllAppGroupList, getAppList } from '@/services/app';
|
||||
import { PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
||||
import type { ActionType } from '@ant-design/pro-components';
|
||||
import { PageContainer, ProList } from '@ant-design/pro-components';
|
||||
|
@ -86,7 +86,7 @@ export default () => {
|
|||
key={'create'}
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
history.push('/app/create');
|
||||
history.push('/app/list/create');
|
||||
}}
|
||||
>
|
||||
<PlusOutlined />
|
||||
|
@ -102,7 +102,7 @@ export default () => {
|
|||
<span
|
||||
onClick={() => {
|
||||
history.push(
|
||||
`/app/config?id=${row.id}&protocol=${row.protocol}&name=${row.name}`,
|
||||
`/app/list/config?id=${row.id}&protocol=${row.protocol}&name=${row.name}`,
|
||||
);
|
||||
}}
|
||||
>
|
||||
|
@ -177,7 +177,7 @@ export default () => {
|
|||
key="config"
|
||||
onClick={() => {
|
||||
history.push(
|
||||
`/app/config?id=${row.id}&protocol=${row.protocol}&name=${row.name}`,
|
||||
`/app/list/config?id=${row.id}&protocol=${row.protocol}&name=${row.name}`,
|
||||
);
|
||||
}}
|
||||
>
|
||||
|
@ -213,6 +213,25 @@ export default () => {
|
|||
</Popconfirm>,
|
||||
],
|
||||
},
|
||||
status: {
|
||||
// 自己扩展的字段,主要用于筛选,不在列表中显示
|
||||
title: intl.formatMessage({
|
||||
id: 'pages.app.list.metas.group',
|
||||
}),
|
||||
valueType: 'select',
|
||||
fieldProps: {
|
||||
mode: 'multiple',
|
||||
},
|
||||
request: async () => {
|
||||
const { success, data } = await getAllAppGroupList({}, {}, {});
|
||||
if (success && data) {
|
||||
return data.map((i) => {
|
||||
return { label: i.name, value: i.id };
|
||||
});
|
||||
}
|
||||
return [];
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</PageContainer>
|
||||
|
|
Loading…
Reference in New Issue