From df4ba2a8c21ea77fbd36dda33db029404bc1beef Mon Sep 17 00:00:00 2001 From: Michael An <2331806369@qq.com> Date: Fri, 9 May 2025 17:28:05 +0800 Subject: [PATCH] Change transfer repo dialog UI (#7801) * 01 change transfer repo to user * 01 change transfer repo to department --- .../src/components/customize-select/index.css | 14 ++ .../src/components/customize-select/index.js | 17 ++- .../select-option-group/index.css | 5 + .../select-option-group/index.js | 4 +- .../src/components/dialog/transfer-dialog.js | 143 ++++++++++-------- frontend/src/components/user-item/index.css | 2 - frontend/src/components/user-select.js | 14 +- frontend/src/css/share-link-dialog.css | 1 + frontend/src/css/transfer-dialog.css | 7 +- frontend/src/css/user-select.css | 2 +- 10 files changed, 130 insertions(+), 79 deletions(-) diff --git a/frontend/src/components/customize-select/index.css b/frontend/src/components/customize-select/index.css index 98af234ed9..51ad300bb3 100644 --- a/frontend/src/components/customize-select/index.css +++ b/frontend/src/components/customize-select/index.css @@ -47,6 +47,19 @@ background: #fff; } +.seafile-customize-select .selected-option .selected-option-show-container { + background: #F2F2F2; + border-radius: 10px; + padding-right: 6px; + padding-left: 12px; + margin-right: 6px; +} + +.seafile-customize-select .selected-option .selected-option-show-container .sf3-font-x-01 { + font-size: 12px; + color: #999; +} + .seafile-customize-select .selected-option .custom-select-dropdown-icon { height: 12px; width: 12px; @@ -97,4 +110,5 @@ line-height: 1; font-size: 14px; white-space: nowrap; + color: #999; } diff --git a/frontend/src/components/customize-select/index.js b/frontend/src/components/customize-select/index.js index 907a6e3023..ea2321343f 100644 --- a/frontend/src/components/customize-select/index.js +++ b/frontend/src/components/customize-select/index.js @@ -88,7 +88,7 @@ class CustomizeSelect extends Component { render() { const { className, value, options, placeholder, searchable, searchPlaceholder, noOptionsPlaceholder, - readOnly, isInModal, addOptionAble, component } = this.props; + readOnly, isInModal, addOptionAble, component, enableDeleteSelected } = this.props; return (
{value && value.label ? - {value.label} - : - {placeholder} + (enableDeleteSelected ? + + {value.label} + + + + + : {value.label} + ) + : {placeholder} } {this.renderDropDownIcon()}
@@ -168,6 +175,8 @@ CustomizeSelect.propTypes = { supportMultipleSelect: PropTypes.bool, isShowSelected: PropTypes.bool, isInModal: PropTypes.bool, // if select component in a modal (option group need ModalPortal to show) + enableDeleteSelected: PropTypes.bool, + deleteSelected: PropTypes.func, }; export default CustomizeSelect; diff --git a/frontend/src/components/customize-select/select-option-group/index.css b/frontend/src/components/customize-select/select-option-group/index.css index 830702647a..fa08a36c4b 100644 --- a/frontend/src/components/customize-select/select-option-group/index.css +++ b/frontend/src/components/customize-select/select-option-group/index.css @@ -56,6 +56,11 @@ cursor: pointer; } +.seafile-select-option .sf2-icon-tick { + right: 10px; + position: absolute; +} + .seafile-select-option.seafile-select-option-active .select-option-name { color: #fff; } diff --git a/frontend/src/components/customize-select/select-option-group/index.js b/frontend/src/components/customize-select/select-option-group/index.js index 62ec481145..606486ce09 100644 --- a/frontend/src/components/customize-select/select-option-group/index.js +++ b/frontend/src/components/customize-select/select-option-group/index.js @@ -128,7 +128,7 @@ class SelectOptionGroup extends Component { }; renderOptGroup = (searchVal) => { - let { noOptionsPlaceholder, onSelectOption } = this.props; + let { noOptionsPlaceholder, onSelectOption, value } = this.props; this.filterOptions = this.props.getFilterOptions(searchVal); if (this.filterOptions.length === 0) { return ( @@ -138,6 +138,7 @@ class SelectOptionGroup extends Component { return this.filterOptions.map((opt, i) => { let key = opt.value.column ? opt.value.column.key : i; let isActive = this.state.activeIndex === i; + const isSelected = value && opt.value === value.value; return ( ); }); diff --git a/frontend/src/components/dialog/transfer-dialog.js b/frontend/src/components/dialog/transfer-dialog.js index 67eefaf280..d8009fdd17 100644 --- a/frontend/src/components/dialog/transfer-dialog.js +++ b/frontend/src/components/dialog/transfer-dialog.js @@ -1,9 +1,8 @@ -import React, { Fragment } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { Button, Modal, ModalBody, ModalFooter, Nav, NavItem, NavLink, TabContent, TabPane, Label } from 'reactstrap'; import SeahubModalHeader from '@/components/common/seahub-modal-header'; -import makeAnimated from 'react-select/animated'; import { seafileAPI } from '../../utils/seafile-api'; import { systemAdminAPI } from '../../utils/system-admin-api'; import { orgAdminAPI } from '../../utils/org-admin-api'; @@ -11,8 +10,9 @@ import { gettext, isPro, orgID } from '../../utils/constants'; import { Utils } from '../../utils/utils'; import toaster from '../toast'; import UserSelect from '../user-select'; -import { SeahubSelect } from '../common/select'; import Switch from '../switch'; +import CustomizeSelect from '../customize-select'; + import '../../css/transfer-dialog.css'; const propTypes = { @@ -43,8 +43,19 @@ class TransferDialog extends React.Component { }; } - handleSelectChange = (option) => { - this.setState({ selectedOption: option }); + handleSelectDepartment = (value) => { + if (this.state.selectedOption && this.state.selectedOption.value === value) { + this.setState({ selectedOption: null }); + } else { + const option = this.state.options.find(item => item.value === value); + this.setState({ selectedOption: option }); + } + }; + + deleteSelectedDepartment = (e) => { + e.stopPropagation(); + e.preventDefault(); + this.setState({ selectedOption: null }); }; onUsersChange = (selectedUsers) => { @@ -53,7 +64,7 @@ class TransferDialog extends React.Component { submit = () => { const { activeTab, reshare, selectedOption, selectedUsers } = this.state; - const email = activeTab === TRANS_DEPART ? selectedOption.email : selectedUsers[0].email; + const email = activeTab === TRANS_DEPART ? selectedOption.value : selectedUsers[0].email; this.props.onTransferRepo(email, reshare); }; @@ -89,9 +100,9 @@ class TransferDialog extends React.Component { updateOptions = (departmentsRes) => { const options = departmentsRes.data.map(item => { let option = { - value: item.name, - email: item.email, + value: item.email, label: item.name, + name: item.name, }; return option; }); @@ -128,8 +139,20 @@ class TransferDialog extends React.Component { if (this.props.canTransferToDept != undefined) { canTransferToDept = this.props.canTransferToDept; } + + const { selectedOption } = this.state; + let buttonDisabled = false; + if (activeTab === TRANS_DEPART) { + if (selectedOption === null || (Array.isArray(selectedOption) && selectedOption.length === 0)) { + buttonDisabled = true; + } + } else { + if (this.state.selectedUsers.length === 0) { + buttonDisabled = true; + } + } return ( - + <>
- + <>
{gettext('If the library is shared to another user, the sharing will be kept.')}
{isPro && canTransferToDept && - - - - -
{gettext('If the library is shared to another department, the sharing will be kept.')}
-
} -
+ + + + +
{gettext('If the library is shared to another department, the sharing will be kept.')}
+
+ } +
+ + + +
-
+ ); }; render() { - const { selectedOption, activeTab } = this.state; - const { itemName: repoName } = this.props; + let { itemName } = this.props; let title = gettext('Transfer Library {library_name}'); - title = title.replace('{library_name}', '' + Utils.HTMLescape(repoName) + ''); - let buttonDisabled = false; - if (activeTab === TRANS_DEPART) { - if (selectedOption === null || (Array.isArray(selectedOption) && selectedOption.length === 0)) { - buttonDisabled = true; - } - } else { - if (this.state.selectedUsers.length === 0) { - buttonDisabled = true; - } - } + title = title.replace('{library_name}', '' + Utils.HTMLescape(itemName) + ''); return ( @@ -234,10 +253,6 @@ class TransferDialog extends React.Component { {this.renderTransContent()} - - - - ); } diff --git a/frontend/src/components/user-item/index.css b/frontend/src/components/user-item/index.css index 622c986c64..896242e2a3 100644 --- a/frontend/src/components/user-item/index.css +++ b/frontend/src/components/user-item/index.css @@ -4,7 +4,6 @@ margin: 2px 10px 2px 0; padding: 0 8px 0 2px; height: 20px; - font-size: 13px; border-radius: 10px; background: #eaeaea; } @@ -44,7 +43,6 @@ display: inline-block; font-size: 12px; color: #909090; - transform: scale(.8); cursor: pointer; } diff --git a/frontend/src/components/user-select.js b/frontend/src/components/user-select.js index 0edfd8ccc6..4b5f9f87e2 100644 --- a/frontend/src/components/user-select.js +++ b/frontend/src/components/user-select.js @@ -14,7 +14,8 @@ import ClickOutside from './click-outside'; import '../css/user-select.css'; const propTypes = { - placeholder: PropTypes.string.isRequired, + placeholder: PropTypes.string, + searchPlaceholder: PropTypes.string, onSelectChange: PropTypes.func.isRequired, isMulti: PropTypes.bool, className: PropTypes.string, @@ -162,15 +163,19 @@ class UserSelect extends React.Component { onUserClick = (user) => { const { isMulti = true } = this.props; let selectedUsers = this.props.selectedUsers.slice(0); + const index = selectedUsers.findIndex(item => item.email === user.email); if (isMulti) { - const index = selectedUsers.findIndex(item => item.email === user.email); if (index > -1) { selectedUsers.splice(index, 1); } else { selectedUsers.push(user); } } else { - selectedUsers = [user]; + if (index > -1) { + selectedUsers = []; + } else { + selectedUsers = [user]; + } } this.props.onSelectChange(selectedUsers); }; @@ -229,7 +234,7 @@ class UserSelect extends React.Component {
+ {selectedUsers.find(u => u.email === user.email) && }
); }) diff --git a/frontend/src/css/share-link-dialog.css b/frontend/src/css/share-link-dialog.css index a8b8c92231..e079b0ea6f 100644 --- a/frontend/src/css/share-link-dialog.css +++ b/frontend/src/css/share-link-dialog.css @@ -118,6 +118,7 @@ .tip { color: #666; + font-size: 13px; margin-bottom: 1rem; } diff --git a/frontend/src/css/transfer-dialog.css b/frontend/src/css/transfer-dialog.css index c834e07a96..4226c48747 100644 --- a/frontend/src/css/transfer-dialog.css +++ b/frontend/src/css/transfer-dialog.css @@ -41,12 +41,14 @@ .transfer-dialog-content .transfer-dialog-main { display: flex; + flex-direction: column; flex-basis: 78%; - padding: 1rem; } .transfer-dialog-content .transfer-dialog-main .tab-content { flex: 1; + padding: 1rem; + min-height: 400px; } .transfer-dialog-content .transfer-dialog-main .tab-pane { @@ -57,8 +59,7 @@ color: #666; } -.transfer-dialog-content .transfer-dialog-main .user-select, -.transfer-dialog-content .transfer-dialog-main .transfer-repo-select-department { +.transfer-dialog-content .transfer-dialog-main .user-select { padding: 8px 0; border-top: 1px solid #eee; border-bottom: 1px solid #eee; diff --git a/frontend/src/css/user-select.css b/frontend/src/css/user-select.css index 0e46b5b12a..4485cb919a 100644 --- a/frontend/src/css/user-select.css +++ b/frontend/src/css/user-select.css @@ -4,7 +4,7 @@ } .selected-user-item-container .user-select-placeholder { - color: #808080; + color: #999; } .user-select-container {