mirror of
https://github.com/haiwen/seahub.git
synced 2025-10-22 03:16:34 +00:00
A11y keyboard library list (#8288)
* [aria] make the 'view mode' tool accessible by keyboard for all the pages with it * [aria] make the 'sort menu' tool accessible by keyboard for all the pages with it * [aria] make the 'single dropdown menu' accessible by keyboard for all the pages with it * [a11y] make the 'star/unstar' icon accessible by keyboard for repo list pages('my libs', 'shared with me', 'shared with all', group/department) * [a11y] make the 'share, delete' icons accessible by keyboard for 'my libs' * [a11y] improvements for 'my libs' * [a11y] make the 'leave share' icon accessible by keyboard for 'shared with ocm' * [a11y] improvements for 'shared with me' * [a11y] improvements for 'shared with all', 'group', 'department'
This commit is contained in:
@@ -13,7 +13,7 @@ class OpIcon extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
const { className, op, title } = this.props;
|
const { className, op, title } = this.props;
|
||||||
return (
|
return (
|
||||||
<span
|
<i
|
||||||
tabIndex="0"
|
tabIndex="0"
|
||||||
role="button"
|
role="button"
|
||||||
className={className}
|
className={className}
|
||||||
@@ -22,7 +22,7 @@ class OpIcon extends React.Component {
|
|||||||
onClick={op}
|
onClick={op}
|
||||||
onKeyDown={Utils.onKeyDown}
|
onKeyDown={Utils.onKeyDown}
|
||||||
>
|
>
|
||||||
</span>
|
</i>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@ import RepoAPITokenDialog from '../dialog/repo-api-token-dialog';
|
|||||||
import RepoShareAdminDialog from '../dialog/repo-share-admin-dialog';
|
import RepoShareAdminDialog from '../dialog/repo-share-admin-dialog';
|
||||||
import { LIST_MODE } from '../dir-view-mode/constants';
|
import { LIST_MODE } from '../dir-view-mode/constants';
|
||||||
import TransferDialog from '../dialog/transfer-dialog';
|
import TransferDialog from '../dialog/transfer-dialog';
|
||||||
|
import OpIcon from '../../components/op-icon';
|
||||||
|
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
|
|
||||||
@@ -441,9 +442,28 @@ class SharedRepoListItem extends React.Component {
|
|||||||
} else {
|
} else {
|
||||||
operations = this.generatorOperations();
|
operations = this.generatorOperations();
|
||||||
}
|
}
|
||||||
const shareOperation = <i className="op-icon sf3-font-share sf3-font" title={gettext('Share')} role="button" aria-label={gettext('Share')} onClick={this.onItemShare}></i>;
|
const shareOperation = (
|
||||||
const unshareOperation = <i className="op-icon sf2-icon-x3" title={gettext('Unshare')} role="button" aria-label={gettext('Unshare')} onClick={this.onItemUnshare}></i>;
|
<OpIcon
|
||||||
const deleteOperation = <i className="op-icon sf3-font-delete1 sf3-font" title={gettext('Delete')} role="button" aria-label={gettext('Delete')} onClick={this.onItemDeleteToggle}></i>;
|
className="op-icon sf3-font-share sf3-font"
|
||||||
|
title={gettext('Share')}
|
||||||
|
op={this.onItemShare}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
const unshareOperation = (
|
||||||
|
<OpIcon
|
||||||
|
className="op-icon sf2-icon-x3"
|
||||||
|
title={gettext('Unshare')}
|
||||||
|
op={this.onItemUnshare}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
const deleteOperation = (
|
||||||
|
<OpIcon
|
||||||
|
className="op-icon sf3-font-delete1 sf3-font"
|
||||||
|
title={gettext('Delete')}
|
||||||
|
role="button" aria-label={gettext('Delete')}
|
||||||
|
op={this.onItemDeleteToggle}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
if (this.isDepartmentOwnerGroupMember) {
|
if (this.isDepartmentOwnerGroupMember) {
|
||||||
const advancedOperations = this.getAdvancedOperations();
|
const advancedOperations = this.getAdvancedOperations();
|
||||||
@@ -482,8 +502,11 @@ class SharedRepoListItem extends React.Component {
|
|||||||
>
|
>
|
||||||
<DropdownToggle
|
<DropdownToggle
|
||||||
tag="span"
|
tag="span"
|
||||||
|
role="button"
|
||||||
|
tabIndex="0"
|
||||||
className="dropdown-item font-weight-normal rounded-0 d-flex justify-content-between align-items-center pr-2"
|
className="dropdown-item font-weight-normal rounded-0 d-flex justify-content-between align-items-center pr-2"
|
||||||
onMouseEnter={this.toggleAdvancedMenuShown}
|
onMouseEnter={this.toggleAdvancedMenuShown}
|
||||||
|
onKeyDown={this.toggleAdvancedMenuShown}
|
||||||
>
|
>
|
||||||
{this.translateMenuItem(item)}
|
{this.translateMenuItem(item)}
|
||||||
<i className="sf3-font-down sf3-font rotate-270"></i>
|
<i className="sf3-font-down sf3-font rotate-270"></i>
|
||||||
@@ -521,8 +544,7 @@ class SharedRepoListItem extends React.Component {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onToggleStarRepo = (e) => {
|
onToggleStarRepo = () => {
|
||||||
e.preventDefault();
|
|
||||||
const { repo_name: repoName } = this.props.repo;
|
const { repo_name: repoName } = this.props.repo;
|
||||||
if (this.state.isStarred) {
|
if (this.state.isStarred) {
|
||||||
seafileAPI.unstarItem(this.props.repo.repo_id, '/').then(() => {
|
seafileAPI.unstarItem(this.props.repo.repo_id, '/').then(() => {
|
||||||
@@ -565,22 +587,17 @@ class SharedRepoListItem extends React.Component {
|
|||||||
onContextMenu={this.handleContextMenu}
|
onContextMenu={this.handleContextMenu}
|
||||||
>
|
>
|
||||||
<td className="text-center">
|
<td className="text-center">
|
||||||
<i
|
<OpIcon
|
||||||
role="button"
|
|
||||||
title={this.state.isStarred ? gettext('Unstar') : gettext('Star')}
|
|
||||||
aria-label={this.state.isStarred ? gettext('Unstar') : gettext('Star')}
|
|
||||||
onClick={this.onToggleStarRepo}
|
|
||||||
className={`${this.state.isStarred ? 'sf3-font-star' : 'sf3-font-star-empty'} sf3-font`}
|
className={`${this.state.isStarred ? 'sf3-font-star' : 'sf3-font-star-empty'} sf3-font`}
|
||||||
>
|
title={this.state.isStarred ? gettext('Unstar') : gettext('Star')}
|
||||||
</i>
|
op={this.onToggleStarRepo}
|
||||||
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
|
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
|
||||||
<td>
|
<td>
|
||||||
{this.state.isRenaming ?
|
{this.state.isRenaming ?
|
||||||
<Rename name={repo.repo_name} onRenameConfirm={this.onRenameConfirm} onRenameCancel={this.onRenameCancel}/> :
|
<Rename name={repo.repo_name} onRenameConfirm={this.onRenameConfirm} onRenameCancel={this.onRenameCancel}/> :
|
||||||
<Fragment>
|
<Link to={libPath}>{repo.repo_name}</Link>
|
||||||
<Link to={libPath}>{repo.repo_name}</Link>
|
|
||||||
</Fragment>
|
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>{this.state.isOperationShow && this.generatorPCMenu()}</td>
|
<td>{this.state.isOperationShow && this.generatorPCMenu()}</td>
|
||||||
@@ -603,14 +620,11 @@ class SharedRepoListItem extends React.Component {
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
<Link to={libPath} className="library-name text-truncate" title={repo.repo_name}>{repo.repo_name}</Link>
|
<Link to={libPath} className="library-name text-truncate" title={repo.repo_name}>{repo.repo_name}</Link>
|
||||||
{isStarred &&
|
{isStarred &&
|
||||||
<i
|
<OpIcon
|
||||||
role="button"
|
className='op-icon library-grid-item-icon sf3-font-star sf3-font'
|
||||||
title={gettext('Unstar')}
|
title={gettext('Unstar')}
|
||||||
aria-label={gettext('Unstar')}
|
op={this.onToggleStarRepo}
|
||||||
onClick={this.onToggleStarRepo}
|
/>
|
||||||
className='op-icon library-grid-item-icon sf3-font-star sf3-font'
|
|
||||||
>
|
|
||||||
</i>
|
|
||||||
}
|
}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
}
|
}
|
||||||
|
@@ -51,16 +51,13 @@ class SortMenu extends React.Component {
|
|||||||
toggle={this.toggleDropdownMenu}
|
toggle={this.toggleDropdownMenu}
|
||||||
>
|
>
|
||||||
<DropdownToggle
|
<DropdownToggle
|
||||||
tag="span"
|
className="border-0 font-weight-normal cur-view-path-btn px-1"
|
||||||
role="button"
|
|
||||||
data-toggle="dropdown"
|
|
||||||
title={gettext('Switch sort mode')}
|
title={gettext('Switch sort mode')}
|
||||||
|
data-toggle="dropdown"
|
||||||
aria-label={gettext('Switch sort mode')}
|
aria-label={gettext('Switch sort mode')}
|
||||||
aria-expanded={isDropdownMenuOpen}
|
aria-expanded={isDropdownMenuOpen}
|
||||||
>
|
>
|
||||||
<span className="cur-view-path-btn px-1">
|
<i className="sf3-font-sort2 sf3-font"></i>
|
||||||
<i className="sf3-font-sort2 sf3-font" aria-label={gettext('Switch sort mode')}></i>
|
|
||||||
</span>
|
|
||||||
</DropdownToggle>
|
</DropdownToggle>
|
||||||
<DropdownMenu className="mt-1">
|
<DropdownMenu className="mt-1">
|
||||||
{sortOptions.map((item, index) => {
|
{sortOptions.map((item, index) => {
|
||||||
|
@@ -41,13 +41,11 @@ class SingleDropdownToolbar extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<Dropdown isOpen={this.state.isDropdownMenuOpen} toggle={this.toggleDropdownMenu} direction="down">
|
<Dropdown isOpen={this.state.isDropdownMenuOpen} toggle={this.toggleDropdownMenu} direction="down">
|
||||||
<DropdownToggle
|
<DropdownToggle
|
||||||
tag="span"
|
className={`border-0 font-weight-normal ${withPlusIcon ? 'ml-2 sf-dropdown-combined-toggle' : 'ml-1 sf-dropdown-toggle'}`}
|
||||||
role="button"
|
|
||||||
className={withPlusIcon ? 'ml-2 sf-dropdown-combined-toggle' : 'ml-1 sf-dropdown-toggle'}
|
|
||||||
onClick={this.toggleDropdownMenu}
|
onClick={this.toggleDropdownMenu}
|
||||||
onKeyDown={this.onDropdownToggleKeyDown}
|
onKeyDown={this.onDropdownToggleKeyDown}
|
||||||
data-toggle="dropdown"
|
data-toggle="dropdown"
|
||||||
aria-label={gettext('More options')}
|
aria-label={gettext('Operations')}
|
||||||
aria-expanded={this.state.isDropdownMenuOpen}
|
aria-expanded={this.state.isDropdownMenuOpen}
|
||||||
>
|
>
|
||||||
{withPlusIcon && <i className="sf3-font-new sf3-font main-icon"></i>}
|
{withPlusIcon && <i className="sf3-font-new sf3-font main-icon"></i>}
|
||||||
|
@@ -60,16 +60,13 @@ class ViewModes extends React.Component {
|
|||||||
id="cur-view-change-mode-dropdown"
|
id="cur-view-change-mode-dropdown"
|
||||||
>
|
>
|
||||||
<DropdownToggle
|
<DropdownToggle
|
||||||
tag="span"
|
className="border-0 font-weight-normal cur-view-path-btn px-1"
|
||||||
role="button"
|
|
||||||
data-toggle="dropdown"
|
|
||||||
title={gettext('Switch view mode')}
|
title={gettext('Switch view mode')}
|
||||||
|
data-toggle="dropdown"
|
||||||
aria-label={gettext('Switch view mode')}
|
aria-label={gettext('Switch view mode')}
|
||||||
aria-expanded={isDropdownMenuOpen}
|
aria-expanded={isDropdownMenuOpen}
|
||||||
>
|
>
|
||||||
<span className='cur-view-path-btn px-1'>
|
<i className={`sf3-font sf3-font-${currentViewMode}-view`}></i>
|
||||||
<span className={`sf3-font sf3-font-${currentViewMode}-view`} aria-label={gettext('Switch view mode')}></span>
|
|
||||||
</span>
|
|
||||||
</DropdownToggle>
|
</DropdownToggle>
|
||||||
<DropdownMenu className="mt-1">
|
<DropdownMenu className="mt-1">
|
||||||
{options.map((item, index) => {
|
{options.map((item, index) => {
|
||||||
@@ -77,13 +74,13 @@ class ViewModes extends React.Component {
|
|||||||
<DropdownItem className='p-0' key={index} onClick={this.props.switchViewMode.bind(this, item.value)}>
|
<DropdownItem className='p-0' key={index} onClick={this.props.switchViewMode.bind(this, item.value)}>
|
||||||
<div className="view-modes-dropdown-wrapper">
|
<div className="view-modes-dropdown-wrapper">
|
||||||
<span className='view-modes-dropdown-tick'>
|
<span className='view-modes-dropdown-tick'>
|
||||||
{currentViewMode === item.value && <i className="sf2-icon-tick" aria-hidden="true"></i>}
|
{currentViewMode === item.value && <i className="sf2-icon-tick"></i>}
|
||||||
</span>
|
</span>
|
||||||
<span className="view-modes-dropdown-content d-flex align-items-center">
|
<span className="view-modes-dropdown-content d-flex align-items-center">
|
||||||
<span className={`sf3-font-${item.icon} sf3-font mr-2`} aria-hidden="true"></span>
|
<span className={`sf3-font-${item.icon} sf3-font mr-2`} aria-hidden="true"></span>
|
||||||
<span>{item.text}</span>
|
<span>{item.text}</span>
|
||||||
</span>
|
</span>
|
||||||
<span className="view-modes-dropdown-shortcut ml-4 d-flex align-items-center" aria-hidden="true">{item.shortcut}</span>
|
<span className="view-modes-dropdown-shortcut ml-4 d-flex align-items-center">{item.shortcut}</span>
|
||||||
</div>
|
</div>
|
||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
);
|
);
|
||||||
|
@@ -2,13 +2,17 @@
|
|||||||
color: var(--bs-icon-color);
|
color: var(--bs-icon-color);
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sf-dropdown-combined-toggle:active,
|
||||||
.sf-dropdown-combined-toggle:hover {
|
.sf-dropdown-combined-toggle:hover {
|
||||||
background: var(--bs-hover-bg);
|
color: var(--bs-icon-color)!important;
|
||||||
|
background: var(--bs-hover-bg)!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-dropdown-combined-toggle .main-icon {
|
.sf-dropdown-combined-toggle .main-icon {
|
||||||
|
font-size: 1rem;
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,6 +23,7 @@ import RepoShareAdminDialog from '../../components/dialog/repo-share-admin-dialo
|
|||||||
import OfficeSuiteDialog from '../../components/dialog/repo-office-suite-dialog';
|
import OfficeSuiteDialog from '../../components/dialog/repo-office-suite-dialog';
|
||||||
import { LIST_MODE } from '../../components/dir-view-mode/constants';
|
import { LIST_MODE } from '../../components/dir-view-mode/constants';
|
||||||
import { userAPI } from '../../utils/user-api';
|
import { userAPI } from '../../utils/user-api';
|
||||||
|
import OpIcon from '../../components/op-icon';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
currentViewMode: PropTypes.string,
|
currentViewMode: PropTypes.string,
|
||||||
@@ -61,13 +62,6 @@ class MylibRepoListItem extends React.Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
onFocus = () => {
|
|
||||||
if (!this.props.isItemFreezed) {
|
|
||||||
this.setState({
|
|
||||||
isOpIconShow: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onMouseEnter = () => {
|
onMouseEnter = () => {
|
||||||
if (!this.props.isItemFreezed) {
|
if (!this.props.isItemFreezed) {
|
||||||
@@ -282,16 +276,19 @@ class MylibRepoListItem extends React.Component {
|
|||||||
let iconTitle = Utils.getLibIconTitle(repo);
|
let iconTitle = Utils.getLibIconTitle(repo);
|
||||||
let repoURL = `${siteRoot}library/${repo.repo_id}/${Utils.encodePath(repo.repo_name)}/`;
|
let repoURL = `${siteRoot}library/${repo.repo_id}/${Utils.encodePath(repo.repo_name)}/`;
|
||||||
return currentViewMode == LIST_MODE ? (
|
return currentViewMode == LIST_MODE ? (
|
||||||
<tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} onFocus={this.onFocus} onContextMenu={this.handleContextMenu}>
|
<tr
|
||||||
|
className={this.state.highlight ? 'tr-highlight' : ''}
|
||||||
|
onMouseEnter={this.onMouseEnter}
|
||||||
|
onMouseLeave={this.onMouseLeave}
|
||||||
|
onFocus={this.onMouseEnter}
|
||||||
|
onContextMenu={this.handleContextMenu}
|
||||||
|
>
|
||||||
<td className="text-center">
|
<td className="text-center">
|
||||||
<i
|
<OpIcon
|
||||||
role="button"
|
|
||||||
title={this.state.isStarred ? gettext('Unstar') : gettext('Star')}
|
|
||||||
aria-label={this.state.isStarred ? gettext('Unstar') : gettext('Star')}
|
|
||||||
onClick={this.onToggleStarRepo}
|
|
||||||
className={`${this.state.isStarred ? 'sf3-font-star' : 'sf3-font-star-empty'} sf3-font`}
|
className={`${this.state.isStarred ? 'sf3-font-star' : 'sf3-font-star-empty'} sf3-font`}
|
||||||
>
|
title={this.state.isStarred ? gettext('Unstar') : gettext('Star')}
|
||||||
</i>
|
op={this.onToggleStarRepo}
|
||||||
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
|
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
|
||||||
<td>
|
<td>
|
||||||
@@ -303,9 +300,7 @@ class MylibRepoListItem extends React.Component {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!this.state.isRenaming && repo.repo_name && (
|
{!this.state.isRenaming && repo.repo_name && (
|
||||||
<Fragment>
|
<Link to={repoURL}>{repo.repo_name}</Link>
|
||||||
<Link to={repoURL}>{repo.repo_name}</Link>
|
|
||||||
</Fragment>
|
|
||||||
)}
|
)}
|
||||||
{!this.state.isRenaming && !repo.repo_name &&
|
{!this.state.isRenaming && !repo.repo_name &&
|
||||||
(gettext('Broken (please contact your administrator to fix this library)'))
|
(gettext('Broken (please contact your administrator to fix this library)'))
|
||||||
@@ -314,8 +309,16 @@ class MylibRepoListItem extends React.Component {
|
|||||||
<td>
|
<td>
|
||||||
{(repo.repo_name && this.state.isOpIconShow) && (
|
{(repo.repo_name && this.state.isOpIconShow) && (
|
||||||
<div className="d-flex align-items-center">
|
<div className="d-flex align-items-center">
|
||||||
<i className="op-icon sf3-font-share sf3-font" title={gettext('Share')} role="button" aria-label={gettext('Share')} onClick={this.onShareToggle}></i>
|
<OpIcon
|
||||||
<i className="op-icon sf3-font-delete1 sf3-font" title={gettext('Delete')} role="button" aria-label={gettext('Delete')} onClick={this.onDeleteToggle}></i>
|
className="op-icon sf3-font-share sf3-font"
|
||||||
|
title={gettext('Share')}
|
||||||
|
op={this.onShareToggle}
|
||||||
|
/>
|
||||||
|
<OpIcon
|
||||||
|
className="op-icon sf3-font-delete1 sf3-font"
|
||||||
|
title={gettext('Delete')}
|
||||||
|
op={this.onDeleteToggle}
|
||||||
|
/>
|
||||||
<LibraryOpMenu
|
<LibraryOpMenu
|
||||||
isPC={true}
|
isPC={true}
|
||||||
repo={this.props.repo}
|
repo={this.props.repo}
|
||||||
@@ -335,7 +338,7 @@ class MylibRepoListItem extends React.Component {
|
|||||||
className="library-grid-item px-3 d-flex justify-content-between align-items-center"
|
className="library-grid-item px-3 d-flex justify-content-between align-items-center"
|
||||||
onMouseEnter={this.onMouseEnter}
|
onMouseEnter={this.onMouseEnter}
|
||||||
onMouseLeave={this.onMouseLeave}
|
onMouseLeave={this.onMouseLeave}
|
||||||
onFocus={this.onFocus}
|
onFocus={this.onMouseEnter}
|
||||||
onContextMenu={this.handleContextMenu}
|
onContextMenu={this.handleContextMenu}
|
||||||
>
|
>
|
||||||
<div className="d-flex align-items-center text-truncate">
|
<div className="d-flex align-items-center text-truncate">
|
||||||
@@ -351,14 +354,11 @@ class MylibRepoListItem extends React.Component {
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
<Link to={repoURL} className="library-name text-truncate" title={repo.repo_name}>{repo.repo_name}</Link>
|
<Link to={repoURL} className="library-name text-truncate" title={repo.repo_name}>{repo.repo_name}</Link>
|
||||||
{isStarred &&
|
{isStarred &&
|
||||||
<i
|
<OpIcon
|
||||||
role="button"
|
className='op-icon library-grid-item-icon sf3-font-star sf3-font'
|
||||||
title={gettext('Unstar')}
|
title={gettext('Unstar')}
|
||||||
aria-label={gettext('Unstar')}
|
op={this.onToggleStarRepo}
|
||||||
className='op-icon library-grid-item-icon sf3-font-star sf3-font'
|
/>
|
||||||
onClick={this.onToggleStarRepo}
|
|
||||||
>
|
|
||||||
</i>
|
|
||||||
}
|
}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
@@ -368,8 +368,16 @@ class MylibRepoListItem extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
{(repo.repo_name && this.state.isOpIconShow) && (
|
{(repo.repo_name && this.state.isOpIconShow) && (
|
||||||
<div className="flex-shrink-0 d-flex align-items-center">
|
<div className="flex-shrink-0 d-flex align-items-center">
|
||||||
<i className="op-icon sf3-font-share sf3-font" title={gettext('Share')} role="button" aria-label={gettext('Share')} onClick={this.onShareToggle}></i>
|
<OpIcon
|
||||||
<i className="op-icon sf3-font-delete1 sf3-font" title={gettext('Delete')} role="button" aria-label={gettext('Delete')} onClick={this.onDeleteToggle}></i>
|
className="op-icon sf3-font-share sf3-font"
|
||||||
|
title={gettext('Share')}
|
||||||
|
op={this.onShareToggle}
|
||||||
|
/>
|
||||||
|
<OpIcon
|
||||||
|
className="op-icon sf3-font-delete1 sf3-font"
|
||||||
|
title={gettext('Delete')}
|
||||||
|
op={this.onDeleteToggle}
|
||||||
|
/>
|
||||||
<LibraryOpMenu
|
<LibraryOpMenu
|
||||||
isPC={true}
|
isPC={true}
|
||||||
repo={this.props.repo}
|
repo={this.props.repo}
|
||||||
|
@@ -18,6 +18,7 @@ import SortOptionsDialog from '../../components/dialog/sort-options';
|
|||||||
import LibsMobileThead from '../../components/libs-mobile-thead';
|
import LibsMobileThead from '../../components/libs-mobile-thead';
|
||||||
import { LIST_MODE } from '../../components/dir-view-mode/constants';
|
import { LIST_MODE } from '../../components/dir-view-mode/constants';
|
||||||
import MobileItemMenu from '../../components/mobile-item-menu';
|
import MobileItemMenu from '../../components/mobile-item-menu';
|
||||||
|
import OpIcon from '../../components/op-icon';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
currentViewMode: PropTypes.string,
|
currentViewMode: PropTypes.string,
|
||||||
@@ -202,7 +203,11 @@ class Item extends Component {
|
|||||||
<td><img src={item.icon_url} title={item.icon_title} alt={item.icon_title} width="24" /></td>
|
<td><img src={item.icon_url} title={item.icon_title} alt={item.icon_title} width="24" /></td>
|
||||||
<td><Link to={shareRepoUrl}>{item.repo_name}</Link></td>
|
<td><Link to={shareRepoUrl}>{item.repo_name}</Link></td>
|
||||||
<td>
|
<td>
|
||||||
<i role="button" className={`op-icon sf2-icon-x3 ${isOpIconShown ? '' : 'invisible'}`} title={gettext('Leave Share')} aria-label={gettext('Leave Share')} onClick={this.leaveShare}></i>
|
<OpIcon
|
||||||
|
className={`op-icon sf2-icon-x3 ${isOpIconShown ? '' : 'invisible'}`}
|
||||||
|
title={gettext('Leave Share')}
|
||||||
|
op={this.leaveShare}
|
||||||
|
/>
|
||||||
</td>
|
</td>
|
||||||
{inAllLibs
|
{inAllLibs
|
||||||
? (
|
? (
|
||||||
@@ -231,7 +236,11 @@ class Item extends Component {
|
|||||||
<Link to={shareRepoUrl} className="library-name text-truncate" title={item.repo_name}>{item.repo_name}</Link>
|
<Link to={shareRepoUrl} className="library-name text-truncate" title={item.repo_name}>{item.repo_name}</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-shrink-0">
|
<div className="flex-shrink-0">
|
||||||
<i role="button" className={`op-icon sf2-icon-x3 ${isOpIconShown ? '' : 'invisible'}`} title={gettext('Leave Share')} aria-label={gettext('Leave Share')} onClick={this.leaveShare}></i>
|
<OpIcon
|
||||||
|
className={`op-icon sf2-icon-x3 ${isOpIconShown ? '' : 'invisible'}`}
|
||||||
|
title={gettext('Leave Share')}
|
||||||
|
op={this.leaveShare}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -12,6 +12,7 @@ import ModalPortal from '../../components/modal-portal';
|
|||||||
import ShareDialog from '../../components/dialog/share-dialog';
|
import ShareDialog from '../../components/dialog/share-dialog';
|
||||||
import MobileItemMenu from '../../components/mobile-item-menu';
|
import MobileItemMenu from '../../components/mobile-item-menu';
|
||||||
import { LIST_MODE } from '../../components/dir-view-mode/constants';
|
import { LIST_MODE } from '../../components/dir-view-mode/constants';
|
||||||
|
import OpIcon from '../../components/op-icon';
|
||||||
|
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
|
|
||||||
@@ -55,14 +56,11 @@ class Item extends Component {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
share = (e) => {
|
share = () => {
|
||||||
e.preventDefault();
|
|
||||||
this.setState({ isShowSharedDialog: true });
|
this.setState({ isShowSharedDialog: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
leaveShare = (e) => {
|
leaveShare = () => {
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const data = this.props.data;
|
const data = this.props.data;
|
||||||
|
|
||||||
let request;
|
let request;
|
||||||
@@ -129,10 +127,10 @@ class Item extends Component {
|
|||||||
onMenuItemClick = (operation, event) => {
|
onMenuItemClick = (operation, event) => {
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case 'Share':
|
case 'Share':
|
||||||
this.share(event);
|
this.share();
|
||||||
break;
|
break;
|
||||||
case 'Unshare':
|
case 'Unshare':
|
||||||
this.leaveShare(event);
|
this.leaveShare();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -158,29 +156,38 @@ class Item extends Component {
|
|||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{currentViewMode == LIST_MODE ? (
|
{currentViewMode == LIST_MODE ? (
|
||||||
<tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut} onFocus={this.handleMouseOver} onContextMenu={this.handleContextMenu}>
|
<tr
|
||||||
|
className={this.state.highlight ? 'tr-highlight' : ''}
|
||||||
|
onMouseOver={this.handleMouseOver}
|
||||||
|
onMouseOut={this.handleMouseOut}
|
||||||
|
onFocus={this.handleMouseOver}
|
||||||
|
onContextMenu={this.handleContextMenu}
|
||||||
|
>
|
||||||
<td className="text-center">
|
<td className="text-center">
|
||||||
<i
|
<OpIcon
|
||||||
role="button"
|
|
||||||
title={this.state.isStarred ? gettext('Unstar') : gettext('Star')}
|
|
||||||
aria-label={this.state.isStarred ? gettext('Unstar') : gettext('Star')}
|
|
||||||
onClick={this.onToggleStarRepo}
|
|
||||||
className={`${this.state.isStarred ? 'sf3-font-star' : 'sf3-font-star-empty'} sf3-font`}
|
className={`${this.state.isStarred ? 'sf3-font-star' : 'sf3-font-star-empty'} sf3-font`}
|
||||||
>
|
title={this.state.isStarred ? gettext('Unstar') : gettext('Star')}
|
||||||
</i>
|
op={this.onToggleStarRepo}
|
||||||
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td><img src={data.icon_url} title={data.icon_title} alt={data.icon_title} width="24" /></td>
|
<td><img src={data.icon_url} title={data.icon_title} alt={data.icon_title} width="24" /></td>
|
||||||
<td>
|
<td>
|
||||||
<Fragment>
|
<Link to={shareRepoUrl}>{data.repo_name}</Link>
|
||||||
<Link to={shareRepoUrl}>{data.repo_name}</Link>
|
|
||||||
</Fragment>
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div className="d-flex align-items-center">
|
<div className="d-flex align-items-center">
|
||||||
{(isPro && data.is_admin) &&
|
{(isPro && data.is_admin) &&
|
||||||
<a href="#" className={shareIconClassName} title={gettext('Share')} role="button" aria-label={gettext('Share')} onClick={this.share}></a>
|
<OpIcon
|
||||||
|
className={shareIconClassName}
|
||||||
|
title={gettext('Share')}
|
||||||
|
op={this.share}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
<a href="#" className={leaveShareIconClassName} title={gettext('Leave Share')} role="button" aria-label={gettext('Leave Share')} onClick={this.leaveShare}></a>
|
<OpIcon
|
||||||
|
className={leaveShareIconClassName}
|
||||||
|
title={gettext('Leave Share')}
|
||||||
|
op={this.leaveShare}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>{data.size}</td>
|
<td>{data.size}</td>
|
||||||
@@ -199,22 +206,26 @@ class Item extends Component {
|
|||||||
<img src={data.icon_url} title={data.icon_title} alt={data.icon_title} width="36" className="mr-2" />
|
<img src={data.icon_url} title={data.icon_title} alt={data.icon_title} width="36" className="mr-2" />
|
||||||
<Link to={shareRepoUrl} className="text-truncate library-name" title={data.repo_name}>{data.repo_name}</Link>
|
<Link to={shareRepoUrl} className="text-truncate library-name" title={data.repo_name}>{data.repo_name}</Link>
|
||||||
{isStarred &&
|
{isStarred &&
|
||||||
<i
|
<OpIcon
|
||||||
role="button"
|
className='op-icon library-grid-item-icon sf3-font-star sf3-font'
|
||||||
title={gettext('Unstar')}
|
title={gettext('Unstar')}
|
||||||
aria-label={gettext('Unstar')}
|
op={this.onToggleStarRepo}
|
||||||
onClick={this.onToggleStarRepo}
|
/>
|
||||||
className='op-icon library-grid-item-icon sf3-font-star sf3-font'
|
|
||||||
>
|
|
||||||
</i>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex-shrink-0 d-flex align-items-center">
|
<div className="flex-shrink-0 d-flex align-items-center">
|
||||||
{(isPro && data.is_admin) &&
|
{(isPro && data.is_admin) &&
|
||||||
<a href="#" className={shareIconClassName} title={gettext('Share')} role="button" aria-label={gettext('Share')} onClick={this.share}></a>
|
<OpIcon
|
||||||
|
className={shareIconClassName}
|
||||||
|
title={gettext('Share')}
|
||||||
|
op={this.share}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
<a href="#" className={leaveShareIconClassName} title={gettext('Leave Share')} role="button" aria-label={gettext('Leave Share')} onClick={this.leaveShare}></a>
|
<OpIcon
|
||||||
|
className={leaveShareIconClassName}
|
||||||
|
title={gettext('Leave Share')}
|
||||||
|
op={this.leaveShare}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
Reference in New Issue
Block a user