Skip to content

Commit 90c1509

Browse files
committed
增加生成EIS菜单功能
1 parent 4da097b commit 90c1509

File tree

6 files changed

+312
-8
lines changed

6 files changed

+312
-8
lines changed
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
/**
2+
* Datart
3+
*
4+
* Copyright 2021
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import { DatePicker, Form, Modal, Radio, Select, Space } from 'antd';
20+
import { FormItemEx } from 'app/components';
21+
import useI18NPrefix from 'app/hooks/useI18NPrefix';
22+
import { useMemberSlice } from 'app/pages/MainPage/pages/MemberPage/slice';
23+
import {
24+
selectMembers,
25+
selectRoles as rdxSelectRoles,
26+
} from 'app/pages/MainPage/pages/MemberPage/slice/selectors';
27+
import {
28+
getMembers,
29+
getRoles,
30+
} from 'app/pages/MainPage/pages/MemberPage/slice/thunks';
31+
import { selectIsOrgOwner } from 'app/pages/MainPage/slice/selectors';
32+
import { TIME_FORMATTER } from 'globalConstants';
33+
import moment from 'moment';
34+
import { FC, memo, useCallback, useEffect, useState } from 'react';
35+
import { useDispatch, useSelector } from 'react-redux';
36+
import styled from 'styled-components/macro';
37+
import { SPACE } from 'styles/StyleConstants';
38+
import { AuthenticationModeType, RowPermissionByType } from './slice/constants';
39+
import { ShareDetail } from './slice/type';
40+
41+
const GenEisMenuModal: FC<{
42+
orgId: string;
43+
vizType: string;
44+
visibility: boolean;
45+
shareData?: ShareDetail | null;
46+
onOk?;
47+
onCancel?;
48+
}> = memo(({ visibility, onOk, onCancel, shareData, orgId }) => {
49+
useMemberSlice();
50+
51+
const t = useI18NPrefix(`viz.action`);
52+
const dispatch = useDispatch();
53+
const [expiryDate, setExpiryDate] = useState<string | Date>('');
54+
const [authenticationMode, setAuthenticationMode] = useState(
55+
AuthenticationModeType.none,
56+
);
57+
const [rowPermissionBy, setRowPermissionBy] = useState('');
58+
const [selectUsers, setSelectUsers] = useState<string[] | null>([]);
59+
const [selectRoles, setSelectRoles] = useState<string[] | null>([]);
60+
const [btnLoading, setBtnLoading] = useState<boolean>(false);
61+
const usersList = useSelector(selectMembers);
62+
const rolesList = useSelector(rdxSelectRoles);
63+
const isOwner = useSelector(selectIsOrgOwner);
64+
65+
const handleOkFn = useCallback(
66+
async ({
67+
expiryDate,
68+
authenticationMode,
69+
roles,
70+
users,
71+
rowPermissionBy,
72+
}) => {
73+
setBtnLoading(true);
74+
75+
try {
76+
let paramsData = {
77+
expiryDate,
78+
authenticationMode,
79+
roles,
80+
users,
81+
rowPermissionBy,
82+
};
83+
if (shareData) {
84+
paramsData = Object.assign({}, shareData, paramsData);
85+
}
86+
87+
await onOk(paramsData);
88+
setBtnLoading(false);
89+
} catch (err) {
90+
setBtnLoading(false);
91+
throw err;
92+
}
93+
},
94+
[onOk, shareData],
95+
);
96+
97+
const handleAuthenticationMode = useCallback(async e => {
98+
const value = e.target.value;
99+
100+
setSelectRoles([]);
101+
setSelectUsers([]);
102+
setRowPermissionBy('');
103+
104+
if (value === AuthenticationModeType.login) {
105+
setRowPermissionBy(RowPermissionByType.visitor);
106+
}
107+
108+
setAuthenticationMode(e.target.value);
109+
}, []);
110+
111+
const handleRowPermissionBy = useCallback(e => {
112+
setRowPermissionBy(e.target.value);
113+
}, []);
114+
115+
const handleChangeMembers = useCallback(users => {
116+
setSelectUsers(users);
117+
}, []);
118+
119+
const handleChangeRoles = useCallback(roles => {
120+
setSelectRoles(roles);
121+
}, []);
122+
123+
const handleDefauleValue = useCallback((shareData: ShareDetail) => {
124+
setExpiryDate(shareData.expiryDate);
125+
setAuthenticationMode(shareData.authenticationMode);
126+
setRowPermissionBy(shareData.rowPermissionBy);
127+
setSelectUsers(shareData.users);
128+
setSelectRoles(shareData.roles);
129+
}, []);
130+
131+
useEffect(() => {
132+
if (isOwner) {
133+
dispatch(getRoles(orgId));
134+
dispatch(getMembers(orgId));
135+
}
136+
}, [orgId, dispatch, isOwner]);
137+
138+
useEffect(() => {
139+
shareData && handleDefauleValue(shareData);
140+
}, [handleDefauleValue, shareData]);
141+
142+
return (
143+
<StyledGenEisMenuModal
144+
title={t('share.shareLink')}
145+
visible={visibility}
146+
okText={shareData ? t('share.save') : t('share.generateLink')}
147+
onOk={() =>
148+
handleOkFn?.({
149+
expiryDate,
150+
authenticationMode,
151+
roles: selectRoles,
152+
users: selectUsers,
153+
rowPermissionBy,
154+
})
155+
}
156+
okButtonProps={{ loading: btnLoading }}
157+
onCancel={onCancel}
158+
destroyOnClose
159+
forceRender
160+
>
161+
<Form
162+
preserve={false}
163+
labelCol={{ span: 8 }}
164+
wrapperCol={{ span: 16 }}
165+
autoComplete="off"
166+
>
167+
<FormItemEx label={t('share.expireDate')}>
168+
<DatePicker
169+
value={expiryDate ? moment(expiryDate, TIME_FORMATTER) : null}
170+
showTime
171+
disabledDate={current => {
172+
return current && current < moment().endOf('day');
173+
}}
174+
onChange={(_, dateString) => {
175+
setExpiryDate(dateString);
176+
}}
177+
/>
178+
</FormItemEx>
179+
<FormItemEx label={t('share.verificationMethod')}>
180+
<Radio.Group
181+
onChange={handleAuthenticationMode}
182+
value={authenticationMode}
183+
>
184+
<Radio value={AuthenticationModeType.none}>{t('share.NONE')}</Radio>
185+
<Radio value={AuthenticationModeType.code}>{t('share.CODE')}</Radio>
186+
<Radio value={AuthenticationModeType.login}>
187+
{t('share.LOGIN')}
188+
</Radio>
189+
</Radio.Group>
190+
</FormItemEx>
191+
{authenticationMode === AuthenticationModeType.login && (
192+
<>
193+
<FormItemEx label={t('share.dataPermission')}>
194+
<Radio.Group
195+
onChange={handleRowPermissionBy}
196+
value={rowPermissionBy}
197+
>
198+
<Radio value={RowPermissionByType.visitor}>
199+
{t('share.loginUser')}
200+
</Radio>
201+
<Radio value={RowPermissionByType.creator}>
202+
{t('share.shareUser')}
203+
</Radio>
204+
</Radio.Group>
205+
</FormItemEx>
206+
{isOwner && (
207+
<FormItemEx label={t('share.userOrRole')}>
208+
<Space>
209+
<StyledSelection
210+
onChange={handleChangeRoles}
211+
placeholder={t('share.selectRole')}
212+
mode="multiple"
213+
maxTagCount="responsive"
214+
optionFilterProp="label"
215+
value={selectRoles || []}
216+
>
217+
{rolesList?.map((v, i) => {
218+
return (
219+
<Select.Option key={i} value={v.id} label={v.name}>
220+
{v.name}
221+
</Select.Option>
222+
);
223+
})}
224+
</StyledSelection>
225+
<StyledSelection
226+
onChange={handleChangeMembers}
227+
placeholder={t('share.selectUser')}
228+
mode="multiple"
229+
maxTagCount="responsive"
230+
optionFilterProp="label"
231+
value={selectUsers || []}
232+
>
233+
{usersList?.map((v, i) => {
234+
return (
235+
<Select.Option key={i} value={v.id} label={v.username}>
236+
{v.username}
237+
</Select.Option>
238+
);
239+
})}
240+
</StyledSelection>
241+
</Space>
242+
</FormItemEx>
243+
)}
244+
</>
245+
)}
246+
</Form>
247+
</StyledGenEisMenuModal>
248+
);
249+
});
250+
251+
export default GenEisMenuModal;
252+
253+
const StyledGenEisMenuModal = styled(Modal)`
254+
& .ant-modal-body .ant-row {
255+
margin-top: ${SPACE};
256+
margin-bottom: ${SPACE};
257+
}
258+
`;
259+
260+
const StyledSelection = styled(Select)`
261+
min-width: 100px;
262+
`;

frontend/src/app/components/VizOperationMenu/components/ShareManageModal.tsx

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { FC, memo, useCallback, useEffect, useMemo, useState } from 'react';
2323
import styled from 'styled-components/macro';
2424
import { SPACE_TIMES } from 'styles/StyleConstants';
2525
import { getServerDomain, request2 } from 'utils/request';
26+
import GenEisMenuModal from './GenEisMenuModal';
2627
import ShareLinkModal from './ShareLinkModal';
2728
import { ShareDetail } from './slice/type';
2829

@@ -57,6 +58,7 @@ const ShareManageModal: FC<{
5758
orgId,
5859
}) => {
5960
const [showShareLinkModal, setShowShareLinkModal] = useState(false);
61+
const [showGenEisMenuModal, setShowGenEisMenuModal] = useState(false);
6062
const [listData, setListData] = useState<ShareDetail[]>([]);
6163
const [manipulatedData, setManipulatedData] = useState<ShareDetail | null>(
6264
null,
@@ -169,13 +171,23 @@ const ShareManageModal: FC<{
169171
const handleCancelModalFn = useCallback(() => {
170172
setManipulatedData(null);
171173
setShowShareLinkModal(false);
174+
setShowGenEisMenuModal(false);
172175
}, []);
173176

174177
const handleOperateFn = useCallback((share: ShareDetail) => {
175178
setManipulatedData(share);
176179
setShowShareLinkModal(true);
177180
}, []);
178181

182+
const handleGenEisMenuFn = useCallback(
183+
(share: ShareDetail) => {
184+
let linkPath = getFullShareLinkPath(share);
185+
186+
setShowGenEisMenuModal(true);
187+
},
188+
[getFullShareLinkPath],
189+
);
190+
179191
const handleOkFn = useCallback(
180192
async paramsData => {
181193
const { id } = paramsData;
@@ -236,6 +248,15 @@ const ShareManageModal: FC<{
236248
>
237249
{t('shareList.operate')}
238250
</Button>
251+
<Button
252+
type="primary"
253+
ghost
254+
onClick={() => {
255+
handleGenEisMenuFn(share);
256+
}}
257+
>
258+
{t('shareList.genEisMenu')}
259+
</Button>
239260
<Popconfirm
240261
title={t('shareList.sureDelete')}
241262
onConfirm={() => {
@@ -252,6 +273,7 @@ const ShareManageModal: FC<{
252273
}, [
253274
t,
254275
handleOperateFn,
276+
handleGenEisMenuFn,
255277
handleCopyToClipboard,
256278
deleteShareLinkFn,
257279
getFullShareLinkPath,
@@ -265,7 +287,7 @@ const ShareManageModal: FC<{
265287

266288
return (
267289
<StyledShareLinkModal
268-
width={1300}
290+
width={1500}
269291
title={
270292
<ModalHeader>
271293
<span>{t('shareList.shareList')}</span>
@@ -302,6 +324,14 @@ const ShareManageModal: FC<{
302324
onOk={handleOkFn}
303325
onCancel={handleCancelModalFn}
304326
></ShareLinkModal>
327+
<GenEisMenuModal
328+
shareData={manipulatedData}
329+
orgId={orgId}
330+
vizType={vizType}
331+
visibility={showGenEisMenuModal}
332+
onOk={handleOkFn}
333+
onCancel={handleCancelModalFn}
334+
></GenEisMenuModal>
305335
</StyledShareLinkModal>
306336
);
307337
},
@@ -314,6 +344,7 @@ const StyledShareLinkModal = styled(Modal)`
314344
padding-right: ${SPACE_TIMES(4)};
315345
padding-left: ${SPACE_TIMES(4)};
316346
}
347+
317348
.ant-modal-body {
318349
padding: 0px;
319350
}

frontend/src/app/components/VizOperationMenu/components/slice/constants.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,14 @@ export enum RowPermissionByType {
2626
creator = 'CREATOR',
2727
visitor = 'VISITOR',
2828
}
29+
30+
export enum SuperModuleType {
31+
PM_M009 = '运营报表',
32+
FIN_M005 = '财务报表',
33+
BM_M004 = '预算报表',
34+
CRM_M008 = '商务报表',
35+
COMMON_M003 = '系统报表',
36+
FILEMANAGE_M003 = '质量报表',
37+
PROD_M003 = '产品报表',
38+
HR_M010 = '人力报表',
39+
}

frontend/src/locales/en/translation.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,8 @@
936936
"deleteError": "Failed to delete",
937937
"sureDelete": "Confirm to delete?",
938938
"noDataTip": "No link yet, click on the top right corner to add",
939-
"Permanent": "Permanent"
939+
"Permanent": "Permanent",
940+
"genEisMenu": "generate EIS menu"
940941
}
941942
},
942943
"board": {

0 commit comments

Comments
 (0)