|
| 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 | +`; |
0 commit comments