mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-08 02:10:24 +00:00
feat: metadata view permission (#6500)
Co-authored-by: 杨国璇 <ygx@Hello-word.local>
This commit is contained in:
8
frontend/package-lock.json
generated
8
frontend/package-lock.json
generated
@@ -19,7 +19,7 @@
|
|||||||
"@seafile/sdoc-editor": "1.0.41",
|
"@seafile/sdoc-editor": "1.0.41",
|
||||||
"@seafile/seafile-calendar": "0.0.12",
|
"@seafile/seafile-calendar": "0.0.12",
|
||||||
"@seafile/seafile-editor": "1.0.107",
|
"@seafile/seafile-editor": "1.0.107",
|
||||||
"@seafile/sf-metadata-ui-component": "0.0.16",
|
"@seafile/sf-metadata-ui-component": "0.0.17",
|
||||||
"@uiw/codemirror-extensions-langs": "^4.19.4",
|
"@uiw/codemirror-extensions-langs": "^4.19.4",
|
||||||
"@uiw/react-codemirror": "^4.19.4",
|
"@uiw/react-codemirror": "^4.19.4",
|
||||||
"chart.js": "2.9.4",
|
"chart.js": "2.9.4",
|
||||||
@@ -5092,9 +5092,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@seafile/sf-metadata-ui-component": {
|
"node_modules/@seafile/sf-metadata-ui-component": {
|
||||||
"version": "0.0.16",
|
"version": "0.0.17",
|
||||||
"resolved": "https://registry.npmjs.org/@seafile/sf-metadata-ui-component/-/sf-metadata-ui-component-0.0.16.tgz",
|
"resolved": "https://registry.npmjs.org/@seafile/sf-metadata-ui-component/-/sf-metadata-ui-component-0.0.17.tgz",
|
||||||
"integrity": "sha512-f5yOmP2LPWdlJfhlM5RKu7hmmGlNxlV7V0qjP2XNne4/s0Z7elqeZ4ZxRKtSTZwAHtgyazHSJ93EqEwU67wQfg==",
|
"integrity": "sha512-2m8bIAXxzw0ZOMFsGesh4lXQdoOL1/0ONP0pwFxEVWtyG6zRThiFL80OgqGKjluVlehxpfgOaTgIQYr6Wy6IEw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@seafile/seafile-calendar": "0.0.24",
|
"@seafile/seafile-calendar": "0.0.24",
|
||||||
"@seafile/seafile-editor": "~1.0.102",
|
"@seafile/seafile-editor": "~1.0.102",
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
"@seafile/sdoc-editor": "1.0.41",
|
"@seafile/sdoc-editor": "1.0.41",
|
||||||
"@seafile/seafile-calendar": "0.0.12",
|
"@seafile/seafile-calendar": "0.0.12",
|
||||||
"@seafile/seafile-editor": "1.0.107",
|
"@seafile/seafile-editor": "1.0.107",
|
||||||
"@seafile/sf-metadata-ui-component": "0.0.16",
|
"@seafile/sf-metadata-ui-component": "0.0.17",
|
||||||
"@uiw/codemirror-extensions-langs": "^4.19.4",
|
"@uiw/codemirror-extensions-langs": "^4.19.4",
|
||||||
"@uiw/react-codemirror": "^4.19.4",
|
"@uiw/react-codemirror": "^4.19.4",
|
||||||
"chart.js": "2.9.4",
|
"chart.js": "2.9.4",
|
||||||
|
@@ -7,7 +7,9 @@ import { getValidFilters, CommonlyUsedHotkey } from '../../_basic';
|
|||||||
import { gettext } from '../../../../utils/constants';
|
import { gettext } from '../../../../utils/constants';
|
||||||
import { FilterPopover } from '../popover';
|
import { FilterPopover } from '../popover';
|
||||||
|
|
||||||
const FilterSetter = ({ columns,
|
const FilterSetter = ({
|
||||||
|
readOnly,
|
||||||
|
columns,
|
||||||
wrapperClass,
|
wrapperClass,
|
||||||
filters: propsFilters,
|
filters: propsFilters,
|
||||||
isNeedSubmit,
|
isNeedSubmit,
|
||||||
@@ -67,6 +69,7 @@ const FilterSetter = ({ columns,
|
|||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
filtersClassName={filtersClassName}
|
filtersClassName={filtersClassName}
|
||||||
target={target}
|
target={target}
|
||||||
|
readOnly={readOnly}
|
||||||
isNeedSubmit={isNeedSubmit}
|
isNeedSubmit={isNeedSubmit}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
collaborators={collaborators}
|
collaborators={collaborators}
|
||||||
@@ -83,6 +86,7 @@ const FilterSetter = ({ columns,
|
|||||||
};
|
};
|
||||||
|
|
||||||
FilterSetter.propTypes = {
|
FilterSetter.propTypes = {
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
wrapperClass: PropTypes.string,
|
wrapperClass: PropTypes.string,
|
||||||
filtersClassName: PropTypes.string,
|
filtersClassName: PropTypes.string,
|
||||||
target: PropTypes.string,
|
target: PropTypes.string,
|
||||||
|
@@ -6,7 +6,7 @@ import { CommonlyUsedHotkey, getValidGroupbys, SUPPORT_GROUP_COLUMN_TYPES } from
|
|||||||
import { gettext } from '../../utils';
|
import { gettext } from '../../utils';
|
||||||
import { GroupbysPopover } from '../popover';
|
import { GroupbysPopover } from '../popover';
|
||||||
|
|
||||||
const GroupbySetter = ({ columns: allColumns, groupbys: propsGroupbys, wrapperClass, target, modifyGroupbys }) => {
|
const GroupbySetter = ({ columns: allColumns, readOnly, groupbys: propsGroupbys, wrapperClass, target, modifyGroupbys }) => {
|
||||||
const [isShowSetter, setShowSetter] = useState(false);
|
const [isShowSetter, setShowSetter] = useState(false);
|
||||||
|
|
||||||
const columns = useMemo(() => {
|
const columns = useMemo(() => {
|
||||||
@@ -56,6 +56,7 @@ const GroupbySetter = ({ columns: allColumns, groupbys: propsGroupbys, wrapperCl
|
|||||||
/>
|
/>
|
||||||
{isShowSetter && (
|
{isShowSetter && (
|
||||||
<GroupbysPopover
|
<GroupbysPopover
|
||||||
|
readOnly={readOnly}
|
||||||
groupbys={groupbys}
|
groupbys={groupbys}
|
||||||
target={target}
|
target={target}
|
||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
@@ -75,6 +76,7 @@ GroupbySetter.defaultProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
GroupbySetter.propTypes = {
|
GroupbySetter.propTypes = {
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
wrapperClass: PropTypes.string,
|
wrapperClass: PropTypes.string,
|
||||||
columns: PropTypes.array,
|
columns: PropTypes.array,
|
||||||
groupbys: PropTypes.array, // valid groupbys
|
groupbys: PropTypes.array, // valid groupbys
|
||||||
|
@@ -6,7 +6,7 @@ import { CommonlyUsedHotkey } from '../../_basic';
|
|||||||
import { gettext } from '../../utils';
|
import { gettext } from '../../utils';
|
||||||
import { HideColumnPopover } from '../popover';
|
import { HideColumnPopover } from '../popover';
|
||||||
|
|
||||||
const HideColumnSetter = ({ columns, wrapperClass, target, hiddenColumns, modifyHiddenColumns }) => {
|
const HideColumnSetter = ({ readOnly, columns, wrapperClass, target, hiddenColumns, modifyHiddenColumns }) => {
|
||||||
const [isShowSetter, setShowSetter] = useState(false);
|
const [isShowSetter, setShowSetter] = useState(false);
|
||||||
|
|
||||||
const validHiddenColumns = useMemo(() => {
|
const validHiddenColumns = useMemo(() => {
|
||||||
@@ -50,6 +50,7 @@ const HideColumnSetter = ({ columns, wrapperClass, target, hiddenColumns, modify
|
|||||||
/>
|
/>
|
||||||
{isShowSetter && (
|
{isShowSetter && (
|
||||||
<HideColumnPopover
|
<HideColumnPopover
|
||||||
|
readOnly={readOnly}
|
||||||
hiddenColumns={validHiddenColumns}
|
hiddenColumns={validHiddenColumns}
|
||||||
target={target}
|
target={target}
|
||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
@@ -63,6 +64,7 @@ const HideColumnSetter = ({ columns, wrapperClass, target, hiddenColumns, modify
|
|||||||
};
|
};
|
||||||
|
|
||||||
HideColumnSetter.propTypes = {
|
HideColumnSetter.propTypes = {
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
wrapperClass: PropTypes.string,
|
wrapperClass: PropTypes.string,
|
||||||
target: PropTypes.string,
|
target: PropTypes.string,
|
||||||
hiddenColumns: PropTypes.array,
|
hiddenColumns: PropTypes.array,
|
||||||
|
@@ -6,7 +6,7 @@ import { getValidSorts, CommonlyUsedHotkey } from '../../_basic';
|
|||||||
import { gettext } from '../../utils';
|
import { gettext } from '../../utils';
|
||||||
import { SortPopover } from '../popover';
|
import { SortPopover } from '../popover';
|
||||||
|
|
||||||
const SortSetter = ({ target, sorts: propsSorts, columns, isNeedSubmit, wrapperClass, modifySorts }) => {
|
const SortSetter = ({ target, sorts: propsSorts, readOnly, columns, isNeedSubmit, wrapperClass, modifySorts }) => {
|
||||||
const [isShowSetter, setShowSetter] = useState(false);
|
const [isShowSetter, setShowSetter] = useState(false);
|
||||||
|
|
||||||
const sorts = useMemo(() => {
|
const sorts = useMemo(() => {
|
||||||
@@ -53,6 +53,7 @@ const SortSetter = ({ target, sorts: propsSorts, columns, isNeedSubmit, wrapperC
|
|||||||
{isShowSetter && (
|
{isShowSetter && (
|
||||||
<SortPopover
|
<SortPopover
|
||||||
isNeedSubmit={isNeedSubmit}
|
isNeedSubmit={isNeedSubmit}
|
||||||
|
readOnly={readOnly}
|
||||||
target={target}
|
target={target}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
sorts={sorts}
|
sorts={sorts}
|
||||||
@@ -67,6 +68,7 @@ const SortSetter = ({ target, sorts: propsSorts, columns, isNeedSubmit, wrapperC
|
|||||||
|
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
wrapperClass: PropTypes.string,
|
wrapperClass: PropTypes.string,
|
||||||
target: PropTypes.string,
|
target: PropTypes.string,
|
||||||
isNeedSubmit: PropTypes.bool,
|
isNeedSubmit: PropTypes.bool,
|
||||||
|
@@ -145,7 +145,7 @@ class FilterPopover extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { target, columns, placement } = this.props;
|
const { readOnly, target, columns, placement } = this.props;
|
||||||
const { filters, filterConjunction } = this.state;
|
const { filters, filterConjunction } = this.state;
|
||||||
const canAddFilter = columns.length > 0;
|
const canAddFilter = columns.length > 0;
|
||||||
return (
|
return (
|
||||||
@@ -169,17 +169,19 @@ class FilterPopover extends Component {
|
|||||||
deleteFilter={this.deleteFilter}
|
deleteFilter={this.deleteFilter}
|
||||||
updateFilterConjunction={this.updateFilterConjunction}
|
updateFilterConjunction={this.updateFilterConjunction}
|
||||||
collaborators={this.props.collaborators}
|
collaborators={this.props.collaborators}
|
||||||
readOnly={false}
|
readOnly={readOnly}
|
||||||
scheduleUpdate={scheduleUpdate}
|
scheduleUpdate={scheduleUpdate}
|
||||||
isPre={this.props.isPre}
|
isPre={this.props.isPre}
|
||||||
/>
|
/>
|
||||||
|
{!readOnly && (
|
||||||
<CustomizeAddTool
|
<CustomizeAddTool
|
||||||
className={`popover-add-tool ${canAddFilter ? '' : 'disabled'}`}
|
className={`popover-add-tool ${canAddFilter ? '' : 'disabled'}`}
|
||||||
callBack={canAddFilter ? () => this.addFilter(scheduleUpdate) : () => {}}
|
callBack={canAddFilter ? () => this.addFilter(scheduleUpdate) : () => {}}
|
||||||
footerName={gettext('Add filter')}
|
footerName={gettext('Add filter')}
|
||||||
addIconClassName="popover-add-icon"
|
addIconClassName="popover-add-icon"
|
||||||
/>
|
/>
|
||||||
{this.isNeedSubmit() && (
|
)}
|
||||||
|
{!readOnly && this.isNeedSubmit() && (
|
||||||
<div className='sf-metadata-filter-popover-footer'>
|
<div className='sf-metadata-filter-popover-footer'>
|
||||||
<Button className='mr-2' onClick={this.onClosePopover}>{gettext('Cancel')}</Button>
|
<Button className='mr-2' onClick={this.onClosePopover}>{gettext('Cancel')}</Button>
|
||||||
<Button color="primary" disabled={this.state.isSubmitDisabled} onClick={this.onSubmitFilters}>{gettext('Submit')}</Button>
|
<Button color="primary" disabled={this.state.isSubmitDisabled} onClick={this.onSubmitFilters}>{gettext('Submit')}</Button>
|
||||||
@@ -197,7 +199,7 @@ FilterPopover.propTypes = {
|
|||||||
filtersClassName: PropTypes.string,
|
filtersClassName: PropTypes.string,
|
||||||
target: PropTypes.string.isRequired,
|
target: PropTypes.string.isRequired,
|
||||||
isNeedSubmit: PropTypes.bool,
|
isNeedSubmit: PropTypes.bool,
|
||||||
isLocked: PropTypes.bool,
|
readOnly: PropTypes.bool,
|
||||||
columns: PropTypes.array.isRequired,
|
columns: PropTypes.array.isRequired,
|
||||||
filterConjunction: PropTypes.string,
|
filterConjunction: PropTypes.string,
|
||||||
filters: PropTypes.array,
|
filters: PropTypes.array,
|
||||||
|
@@ -3,12 +3,12 @@ import PropTypes from 'prop-types';
|
|||||||
import { SfFilterCalendar } from '@seafile/sf-metadata-ui-component';
|
import { SfFilterCalendar } from '@seafile/sf-metadata-ui-component';
|
||||||
import { getDateColumnFormat } from '../../../../utils/column-utils';
|
import { getDateColumnFormat } from '../../../../utils/column-utils';
|
||||||
|
|
||||||
const FilterCalendar = ({ value, filterColumn, isReadOnly, onChange }) => {
|
const FilterCalendar = ({ value, filterColumn, readOnly, onChange }) => {
|
||||||
const format = getDateColumnFormat(filterColumn).trim();
|
const format = getDateColumnFormat(filterColumn).trim();
|
||||||
const lang = window.sfMetadataContext.getSetting('lang');
|
const lang = window.sfMetadataContext.getSetting('lang');
|
||||||
return (
|
return (
|
||||||
<SfFilterCalendar
|
<SfFilterCalendar
|
||||||
isReadOnly={isReadOnly}
|
isReadOnly={readOnly}
|
||||||
format={format}
|
format={format}
|
||||||
lang={lang}
|
lang={lang}
|
||||||
value={value}
|
value={value}
|
||||||
@@ -22,7 +22,7 @@ FilterCalendar.propTypes = {
|
|||||||
value: PropTypes.string.isRequired,
|
value: PropTypes.string.isRequired,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
filterColumn: PropTypes.object.isRequired,
|
filterColumn: PropTypes.object.isRequired,
|
||||||
isReadOnly: PropTypes.bool,
|
readOnly: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FilterCalendar;
|
export default FilterCalendar;
|
||||||
|
@@ -6,7 +6,7 @@ import { gettext } from '../../../../../../utils';
|
|||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
const CollaboratorFilter = ({ isLocked, filterIndex, filterTerm, collaborators, placeholder, filter_predicate, onSelectCollaborator }) => {
|
const CollaboratorFilter = ({ readOnly, filterIndex, filterTerm, collaborators, placeholder, filter_predicate, onSelectCollaborator }) => {
|
||||||
const supportMultipleSelectOptions = useMemo(() => {
|
const supportMultipleSelectOptions = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
FILTER_PREDICATE_TYPE.HAS_ANY_OF,
|
FILTER_PREDICATE_TYPE.HAS_ANY_OF,
|
||||||
@@ -80,7 +80,7 @@ const CollaboratorFilter = ({ isLocked, filterIndex, filterTerm, collaborators,
|
|||||||
onSelectOption={onSelectCollaborator}
|
onSelectOption={onSelectCollaborator}
|
||||||
options={options}
|
options={options}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
isLocked={isLocked}
|
readOnly={readOnly}
|
||||||
supportMultipleSelect={isSupportMultipleSelect}
|
supportMultipleSelect={isSupportMultipleSelect}
|
||||||
searchable={true}
|
searchable={true}
|
||||||
searchPlaceholder={gettext('Search collaborator')}
|
searchPlaceholder={gettext('Search collaborator')}
|
||||||
@@ -96,7 +96,7 @@ CollaboratorFilter.propTypes = {
|
|||||||
filter_predicate: PropTypes.string,
|
filter_predicate: PropTypes.string,
|
||||||
collaborators: PropTypes.array,
|
collaborators: PropTypes.array,
|
||||||
onSelectCollaborator: PropTypes.func,
|
onSelectCollaborator: PropTypes.func,
|
||||||
isLocked: PropTypes.bool,
|
readOnly: PropTypes.bool,
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@ import { DELETED_OPTION_BACKGROUND_COLOR, DELETED_OPTION_TIPS } from '../../../.
|
|||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
index: PropTypes.number.isRequired,
|
index: PropTypes.number.isRequired,
|
||||||
filter: PropTypes.object.isRequired,
|
filter: PropTypes.object.isRequired,
|
||||||
filterColumn: PropTypes.object.isRequired,
|
filterColumn: PropTypes.object.isRequired,
|
||||||
@@ -245,6 +246,7 @@ class FilterItem extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
getInputComponent = (type) => {
|
getInputComponent = (type) => {
|
||||||
|
const { readOnly } = this.props;
|
||||||
const { filterTerm } = this.state;
|
const { filterTerm } = this.state;
|
||||||
if (type === 'text') {
|
if (type === 'text') {
|
||||||
return (
|
return (
|
||||||
@@ -252,13 +254,16 @@ class FilterItem extends React.Component {
|
|||||||
value={filterTerm}
|
value={filterTerm}
|
||||||
onChange={this.onFilterTermTextChanged}
|
onChange={this.onFilterTermTextChanged}
|
||||||
autoFocus={false}
|
autoFocus={false}
|
||||||
|
disabled={readOnly}
|
||||||
className='text-truncate'
|
className='text-truncate'
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else if (type === 'checkbox') {
|
} else if (type === 'checkbox') {
|
||||||
|
const { readOnly } = this.props;
|
||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
disabled={readOnly}
|
||||||
checked={filterTerm}
|
checked={filterTerm}
|
||||||
onChange={this.onFilterTermCheckboxChanged}
|
onChange={this.onFilterTermCheckboxChanged}
|
||||||
/>
|
/>
|
||||||
@@ -267,7 +272,7 @@ class FilterItem extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
renderConjunction = () => {
|
renderConjunction = () => {
|
||||||
const { index, filterConjunction, conjunctionOptions } = this.props;
|
const { index, readOnly, filterConjunction, conjunctionOptions } = this.props;
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0: {
|
case 0: {
|
||||||
return null;
|
return null;
|
||||||
@@ -276,6 +281,7 @@ class FilterItem extends React.Component {
|
|||||||
const activeConjunction = FilterItemUtils.getActiveConjunctionOption(filterConjunction);
|
const activeConjunction = FilterItemUtils.getActiveConjunctionOption(filterConjunction);
|
||||||
return (
|
return (
|
||||||
<CustomizeSelect
|
<CustomizeSelect
|
||||||
|
readOnly={readOnly}
|
||||||
value={activeConjunction}
|
value={activeConjunction}
|
||||||
options={conjunctionOptions}
|
options={conjunctionOptions}
|
||||||
onSelectOption={this.onSelectConjunction}
|
onSelectOption={this.onSelectConjunction}
|
||||||
@@ -356,7 +362,7 @@ class FilterItem extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
renderFilterTerm = (filterColumn) => {
|
renderFilterTerm = (filterColumn) => {
|
||||||
const { index, filter, collaborators } = this.props;
|
const { index, filter, collaborators, readOnly } = this.props;
|
||||||
const { type } = filterColumn;
|
const { type } = filterColumn;
|
||||||
const { filter_term, filter_predicate, filter_term_modifier } = filter;
|
const { filter_term, filter_predicate, filter_term_modifier } = filter;
|
||||||
// predicate is empty or not empty
|
// predicate is empty or not empty
|
||||||
@@ -381,6 +387,7 @@ class FilterItem extends React.Component {
|
|||||||
if (filter_term_modifier === 'exact_date') {
|
if (filter_term_modifier === 'exact_date') {
|
||||||
return (
|
return (
|
||||||
<FilterCalendar
|
<FilterCalendar
|
||||||
|
readOnly={readOnly}
|
||||||
onChange={this.onFilterExactDateChanged}
|
onChange={this.onFilterExactDateChanged}
|
||||||
value={this.state.filterTerm}
|
value={this.state.filterTerm}
|
||||||
filterColumn={filterColumn}
|
filterColumn={filterColumn}
|
||||||
@@ -409,6 +416,7 @@ class FilterItem extends React.Component {
|
|||||||
const creators = collaborators;
|
const creators = collaborators;
|
||||||
return (
|
return (
|
||||||
<CollaboratorFilter
|
<CollaboratorFilter
|
||||||
|
readOnly={readOnly}
|
||||||
filterIndex={index}
|
filterIndex={index}
|
||||||
filterTerm={filter_term || []}
|
filterTerm={filter_term || []}
|
||||||
collaborators={creators}
|
collaborators={creators}
|
||||||
@@ -444,6 +452,7 @@ class FilterItem extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<CustomizeSelect
|
<CustomizeSelect
|
||||||
|
readOnly={readOnly}
|
||||||
className="sf-metadata-selector-single-select"
|
className="sf-metadata-selector-single-select"
|
||||||
value={selectedOptionDom}
|
value={selectedOptionDom}
|
||||||
options={dataOptions || []}
|
options={dataOptions || []}
|
||||||
@@ -461,6 +470,7 @@ class FilterItem extends React.Component {
|
|||||||
const allCollaborators = this.getAllCollaborators();
|
const allCollaborators = this.getAllCollaborators();
|
||||||
return (
|
return (
|
||||||
<CollaboratorFilter
|
<CollaboratorFilter
|
||||||
|
readOnly={readOnly}
|
||||||
filterIndex={index}
|
filterIndex={index}
|
||||||
filterTerm={filter_term || []}
|
filterTerm={filter_term || []}
|
||||||
filter_predicate={filter_predicate}
|
filter_predicate={filter_predicate}
|
||||||
@@ -501,7 +511,7 @@ class FilterItem extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { filterPredicateOptions, filterTermModifierOptions } = this;
|
const { filterPredicateOptions, filterTermModifierOptions } = this;
|
||||||
const { filter, filterColumn, filterColumnOptions } = this.props;
|
const { filter, filterColumn, filterColumnOptions, readOnly } = this.props;
|
||||||
const { filter_predicate, filter_term_modifier } = filter;
|
const { filter_predicate, filter_term_modifier } = filter;
|
||||||
const activeColumn = FilterItemUtils.generatorColumnOption(filterColumn);
|
const activeColumn = FilterItemUtils.generatorColumnOption(filterColumn);
|
||||||
const activePredicate = FilterItemUtils.generatorPredicateOption(filter_predicate);
|
const activePredicate = FilterItemUtils.generatorPredicateOption(filter_predicate);
|
||||||
@@ -521,9 +531,11 @@ class FilterItem extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="filter-item">
|
<div className="filter-item">
|
||||||
|
{!readOnly && (
|
||||||
<div className="delete-filter" onClick={this.onDeleteFilter}>
|
<div className="delete-filter" onClick={this.onDeleteFilter}>
|
||||||
<Icon iconName="fork-number"/>
|
<Icon iconName="fork-number"/>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
<div className="condition">
|
<div className="condition">
|
||||||
<div className="filter-conjunction">
|
<div className="filter-conjunction">
|
||||||
{this.renderConjunction()}
|
{this.renderConjunction()}
|
||||||
@@ -531,6 +543,7 @@ class FilterItem extends React.Component {
|
|||||||
<div className="filter-container">
|
<div className="filter-container">
|
||||||
<div className="filter-column">
|
<div className="filter-column">
|
||||||
<CustomizeSelect
|
<CustomizeSelect
|
||||||
|
readOnly={readOnly}
|
||||||
value={activeColumn}
|
value={activeColumn}
|
||||||
options={filterColumnOptions}
|
options={filterColumnOptions}
|
||||||
onSelectOption={this.onSelectColumn}
|
onSelectOption={this.onSelectColumn}
|
||||||
@@ -541,6 +554,7 @@ class FilterItem extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div className={`filter-predicate ml-2 ${_isCheckboxColumn ? 'filter-checkbox-predicate' : ''}`}>
|
<div className={`filter-predicate ml-2 ${_isCheckboxColumn ? 'filter-checkbox-predicate' : ''}`}>
|
||||||
<CustomizeSelect
|
<CustomizeSelect
|
||||||
|
readOnly={readOnly}
|
||||||
value={activePredicate}
|
value={activePredicate}
|
||||||
options={filterPredicateOptions}
|
options={filterPredicateOptions}
|
||||||
onSelectOption={this.onSelectPredicate}
|
onSelectOption={this.onSelectPredicate}
|
||||||
@@ -549,6 +563,7 @@ class FilterItem extends React.Component {
|
|||||||
{isDateColumn(filterColumn) && isNeedShowTermModifier && (
|
{isDateColumn(filterColumn) && isNeedShowTermModifier && (
|
||||||
<div className="filter-term-modifier ml-2">
|
<div className="filter-term-modifier ml-2">
|
||||||
<CustomizeSelect
|
<CustomizeSelect
|
||||||
|
readOnly={readOnly}
|
||||||
value={activeTermModifier}
|
value={activeTermModifier}
|
||||||
options={filterTermModifierOptions}
|
options={filterTermModifierOptions}
|
||||||
onSelectOption={this.onSelectTermModifier}
|
onSelectOption={this.onSelectTermModifier}
|
||||||
|
@@ -67,6 +67,10 @@
|
|||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filters-list .sf-metadata-select.disabled .selected-option-show {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.filters-list .sf-metadata-select .selected-option {
|
.filters-list .sf-metadata-select .selected-option {
|
||||||
width: auto;
|
width: auto;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
@@ -147,7 +151,7 @@
|
|||||||
border-color: rgb(179, 179, 179);
|
border-color: rgb(179, 179, 179);
|
||||||
}
|
}
|
||||||
|
|
||||||
.filters-list .filter-term input.disabled:hover {
|
.filters-list .filter-term input:disabled:hover {
|
||||||
border-color: rgba(0, 40, 100, 0.12);
|
border-color: rgba(0, 40, 100, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@ import FilterItem from './filter-item';
|
|||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
isLocked: PropTypes.bool,
|
readOnly: PropTypes.bool,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
filters: PropTypes.array,
|
filters: PropTypes.array,
|
||||||
columns: PropTypes.array.isRequired,
|
columns: PropTypes.array.isRequired,
|
||||||
@@ -81,13 +81,13 @@ class FiltersList extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
renderFilterItem = (filter, index, errMsg, filterColumn) => {
|
renderFilterItem = (filter, index, errMsg, filterColumn) => {
|
||||||
const { filterConjunction, value } = this.props;
|
const { readOnly, filterConjunction, value } = this.props;
|
||||||
const conjunctionOptions = this.getConjunctionOptions();
|
const conjunctionOptions = this.getConjunctionOptions();
|
||||||
const columnOptions = this.getColumnOptions();
|
const columnOptions = this.getColumnOptions();
|
||||||
return (
|
return (
|
||||||
<FilterItem
|
<FilterItem
|
||||||
key={index}
|
key={index}
|
||||||
isLocked={this.props.isLocked}
|
readOnly={readOnly}
|
||||||
index={index}
|
index={index}
|
||||||
filter={filter}
|
filter={filter}
|
||||||
errMsg={errMsg}
|
errMsg={errMsg}
|
||||||
|
@@ -60,7 +60,7 @@ const dropCollect = (connect, monitor) => ({
|
|||||||
*/
|
*/
|
||||||
const GroupbyItem = memo(({
|
const GroupbyItem = memo(({
|
||||||
isOver, isDragging, canDrop, connectDragSource, connectDragPreview, connectDropTarget,
|
isOver, isDragging, canDrop, connectDragSource, connectDragPreview, connectDropTarget,
|
||||||
showDragBtn, index, groupby, columns, onDelete, onUpdate
|
showDragBtn, index, readOnly, groupby, columns, onDelete, onUpdate
|
||||||
}) => {
|
}) => {
|
||||||
const column = useMemo(() => {
|
const column = useMemo(() => {
|
||||||
return getColumnByKey(columns, groupby.column_key);
|
return getColumnByKey(columns, groupby.column_key);
|
||||||
@@ -162,12 +162,15 @@ const GroupbyItem = memo(({
|
|||||||
{ 'group-can-drop': isOver && canDrop && !isDragging }
|
{ 'group-can-drop': isOver && canDrop && !isDragging }
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
{!readOnly && (
|
||||||
<div className="delete-groupby" onClick={deleteGroupby} aria-label={gettext('Delete')}>
|
<div className="delete-groupby" onClick={deleteGroupby} aria-label={gettext('Delete')}>
|
||||||
<Icon iconName="fork-number"/>
|
<Icon iconName="fork-number"/>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
<div className="condition">
|
<div className="condition">
|
||||||
<div className="groupby-column">
|
<div className="groupby-column">
|
||||||
<CustomizeSelect
|
<CustomizeSelect
|
||||||
|
readOnly={readOnly}
|
||||||
value={selectedColumn}
|
value={selectedColumn}
|
||||||
options={columnsOptions}
|
options={columnsOptions}
|
||||||
onSelectOption={selectColumn}
|
onSelectOption={selectColumn}
|
||||||
@@ -179,6 +182,7 @@ const GroupbyItem = memo(({
|
|||||||
{isShowGroupCountType(column) && (
|
{isShowGroupCountType(column) && (
|
||||||
<div className="groupby-count-type">
|
<div className="groupby-count-type">
|
||||||
<CustomizeSelect
|
<CustomizeSelect
|
||||||
|
readOnly={readOnly}
|
||||||
value={selectedCountType}
|
value={selectedCountType}
|
||||||
onSelectOption={selectCountType}
|
onSelectOption={selectCountType}
|
||||||
options={countTypeOptions}
|
options={countTypeOptions}
|
||||||
@@ -188,6 +192,7 @@ const GroupbyItem = memo(({
|
|||||||
<div className="groupby-predicate">
|
<div className="groupby-predicate">
|
||||||
{(!column.key || SORT_COLUMN_OPTIONS.includes(column.type)) && (
|
{(!column.key || SORT_COLUMN_OPTIONS.includes(column.type)) && (
|
||||||
<CustomizeSelect
|
<CustomizeSelect
|
||||||
|
readOnly={readOnly}
|
||||||
value={selectedSortType}
|
value={selectedSortType}
|
||||||
options={sortOptions}
|
options={sortOptions}
|
||||||
onSelectOption={selectSortType}
|
onSelectOption={selectSortType}
|
||||||
@@ -195,7 +200,7 @@ const GroupbyItem = memo(({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{showDragBtn && connectDragSource(
|
{!readOnly && showDragBtn && connectDragSource(
|
||||||
<div className="groupby-drag">
|
<div className="groupby-drag">
|
||||||
<Icon iconName="drag" />
|
<Icon iconName="drag" />
|
||||||
</div>
|
</div>
|
||||||
@@ -217,6 +222,7 @@ const GroupbyItem = memo(({
|
|||||||
|
|
||||||
GroupbyItem.propTypes = {
|
GroupbyItem.propTypes = {
|
||||||
index: PropTypes.number,
|
index: PropTypes.number,
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
groupby: PropTypes.object,
|
groupby: PropTypes.object,
|
||||||
columns: PropTypes.array,
|
columns: PropTypes.array,
|
||||||
onDelete: PropTypes.func,
|
onDelete: PropTypes.func,
|
||||||
|
@@ -6,15 +6,16 @@ import html5DragDropContext from '../../../../../../pages/wiki2/wiki-nav/html5Dr
|
|||||||
import { gettext } from '../../../../utils';
|
import { gettext } from '../../../../utils';
|
||||||
import GroupbyItem from './groupby-item';
|
import GroupbyItem from './groupby-item';
|
||||||
|
|
||||||
const Groupbys = ({ groupbys, columns, onDelete, onUpdate, onMove }) => {
|
const Groupbys = ({ readOnly, groupbys, columns, onDelete, onUpdate, onMove }) => {
|
||||||
const isEmpty = useMemo(() => {
|
const isEmpty = useMemo(() => {
|
||||||
if (!Array.isArray(groupbys) || groupbys.length === 0) return true;
|
if (!Array.isArray(groupbys) || groupbys.length === 0) return true;
|
||||||
return false;
|
return false;
|
||||||
}, [groupbys]);
|
}, [groupbys]);
|
||||||
const showDragBtn = useMemo(() => {
|
const showDragBtn = useMemo(() => {
|
||||||
|
if (readOnly) return false;
|
||||||
if (!Array.isArray(groupbys) || groupbys.length === 0) return false;
|
if (!Array.isArray(groupbys) || groupbys.length === 0) return false;
|
||||||
return groupbys.length > 1;
|
return groupbys.length > 1;
|
||||||
}, [groupbys]);
|
}, [readOnly, groupbys]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classnames('groupbys-list', { 'empty-groupbys-container': isEmpty })}>
|
<div className={classnames('groupbys-list', { 'empty-groupbys-container': isEmpty })}>
|
||||||
@@ -24,6 +25,7 @@ const Groupbys = ({ groupbys, columns, onDelete, onUpdate, onMove }) => {
|
|||||||
<GroupbyItem
|
<GroupbyItem
|
||||||
key={index}
|
key={index}
|
||||||
index={index}
|
index={index}
|
||||||
|
readOnly={readOnly}
|
||||||
showDragBtn={showDragBtn}
|
showDragBtn={showDragBtn}
|
||||||
groupby={groupby}
|
groupby={groupby}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
@@ -13,7 +13,7 @@ import Groupbys from './groupbys';
|
|||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
const GroupbysPopover = ({ groupbys: propsGroupBys, hidePopover, onChange, target, placement, columns }) => {
|
const GroupbysPopover = ({ groupbys: propsGroupBys, readOnly, hidePopover, onChange, target, placement, columns }) => {
|
||||||
const [groupbys, setGroupbys] = useState(propsGroupBys);
|
const [groupbys, setGroupbys] = useState(propsGroupBys);
|
||||||
const isSelectOpenRef = useState(false);
|
const isSelectOpenRef = useState(false);
|
||||||
const popoverRef = useRef(null);
|
const popoverRef = useRef(null);
|
||||||
@@ -107,8 +107,8 @@ const GroupbysPopover = ({ groupbys: propsGroupBys, hidePopover, onChange, targe
|
|||||||
boundariesElement={document.body}
|
boundariesElement={document.body}
|
||||||
>
|
>
|
||||||
<div ref={popoverRef} onClick={onPopoverInsideClick} className="sf-metadata-groupbys">
|
<div ref={popoverRef} onClick={onPopoverInsideClick} className="sf-metadata-groupbys">
|
||||||
<Groupbys groupbys={groupbys} columns={columns} onDelete={deleteGroup} onUpdate={updateGroup} onMove={moveGroupbys} />
|
<Groupbys readOnly={readOnly} groupbys={groupbys} columns={columns} onDelete={deleteGroup} onUpdate={updateGroup} onMove={moveGroupbys} />
|
||||||
{(groupbys.length < MAX_GROUP_LEVEL) && (
|
{!readOnly && (groupbys.length < MAX_GROUP_LEVEL) && (
|
||||||
<CustomizeAddTool
|
<CustomizeAddTool
|
||||||
className="popover-add-tool"
|
className="popover-add-tool"
|
||||||
callBack={addGroupby}
|
callBack={addGroupby}
|
||||||
@@ -128,6 +128,7 @@ const GroupbysPopover = ({ groupbys: propsGroupBys, hidePopover, onChange, targe
|
|||||||
};
|
};
|
||||||
|
|
||||||
GroupbysPopover.propTypes = {
|
GroupbysPopover.propTypes = {
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
target: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.node]),
|
target: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.node]),
|
||||||
groupbys: PropTypes.array,
|
groupbys: PropTypes.array,
|
||||||
columns: PropTypes.array,
|
columns: PropTypes.array,
|
||||||
|
@@ -2,16 +2,19 @@ import React, { useCallback } from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Icon, Switch } from '@seafile/sf-metadata-ui-component';
|
import { Icon, Switch } from '@seafile/sf-metadata-ui-component';
|
||||||
import { COLUMNS_ICON_CONFIG } from '../../../../_basic';
|
import { COLUMNS_ICON_CONFIG } from '../../../../_basic';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
const HideColumnItem = ({ column, isHidden, onChange }) => {
|
const HideColumnItem = ({ readOnly, column, isHidden, onChange }) => {
|
||||||
|
|
||||||
const update = useCallback(() => {
|
const update = useCallback(() => {
|
||||||
|
if (readOnly) return;
|
||||||
onChange(column.key);
|
onChange(column.key);
|
||||||
}, [column, onChange]);
|
}, [readOnly, column, onChange]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="hide-column-item">
|
<div className={classNames('hide-column-item', { 'disabled': readOnly })}>
|
||||||
<Switch
|
<Switch
|
||||||
|
disabled={readOnly}
|
||||||
checked={isHidden}
|
checked={isHidden}
|
||||||
placeholder={(
|
placeholder={(
|
||||||
<>
|
<>
|
||||||
@@ -27,6 +30,7 @@ const HideColumnItem = ({ column, isHidden, onChange }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
HideColumnItem.propTypes = {
|
HideColumnItem.propTypes = {
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
isHidden: PropTypes.bool,
|
isHidden: PropTypes.bool,
|
||||||
column: PropTypes.object.isRequired,
|
column: PropTypes.object.isRequired,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
|
@@ -4,7 +4,7 @@ import classnames from 'classnames';
|
|||||||
import { gettext } from '../../../../utils';
|
import { gettext } from '../../../../utils';
|
||||||
import HideColumn from './hide-column';
|
import HideColumn from './hide-column';
|
||||||
|
|
||||||
const HiddenColumns = ({ columns, hiddenColumns, onChange }) => {
|
const HiddenColumns = ({ readOnly, columns, hiddenColumns, onChange }) => {
|
||||||
const isEmpty = useMemo(() => {
|
const isEmpty = useMemo(() => {
|
||||||
if (!Array.isArray(columns) || columns.length === 0) return true;
|
if (!Array.isArray(columns) || columns.length === 0) return true;
|
||||||
return false;
|
return false;
|
||||||
@@ -17,6 +17,7 @@ const HiddenColumns = ({ columns, hiddenColumns, onChange }) => {
|
|||||||
return (
|
return (
|
||||||
<HideColumn
|
<HideColumn
|
||||||
key={column.key}
|
key={column.key}
|
||||||
|
readOnly={readOnly}
|
||||||
isHidden={hiddenColumns.includes(column.key)}
|
isHidden={hiddenColumns.includes(column.key)}
|
||||||
column={column}
|
column={column}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
@@ -28,6 +29,7 @@ const HiddenColumns = ({ columns, hiddenColumns, onChange }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
HiddenColumns.propTypes = {
|
HiddenColumns.propTypes = {
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
hiddenColumns: PropTypes.array,
|
hiddenColumns: PropTypes.array,
|
||||||
columns: PropTypes.array,
|
columns: PropTypes.array,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
|
@@ -57,10 +57,10 @@
|
|||||||
|
|
||||||
.sf-metadata-hide-columns-popover .hide-columns-list .hide-column-item:hover {
|
.sf-metadata-hide-columns-popover .hide-columns-list .hide-column-item:hover {
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-hide-columns-popover .hide-columns-list .hide-column-item:hover * {
|
.sf-metadata-hide-columns-popover .hide-columns-list .hide-column-item:not(.disabled):hover
|
||||||
|
.sf-metadata-hide-columns-popover .hide-columns-list .hide-column-item:not(.disabled):hover * {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@ import { getEventClassName, gettext } from '../../../utils';
|
|||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
const HideColumnPopover = ({ hidePopover, onChange, target, placement, columns, hiddenColumns: oldHiddenColumns }) => {
|
const HideColumnPopover = ({ hidePopover, onChange, readOnly, target, placement, columns, hiddenColumns: oldHiddenColumns }) => {
|
||||||
const [searchValue, setSearchValue] = useState('');
|
const [searchValue, setSearchValue] = useState('');
|
||||||
const [hiddenColumns, setHiddenColumns] = useState(oldHiddenColumns);
|
const [hiddenColumns, setHiddenColumns] = useState(oldHiddenColumns);
|
||||||
const displayColumns = useMemo(() => {
|
const displayColumns = useMemo(() => {
|
||||||
@@ -104,8 +104,8 @@ const HideColumnPopover = ({ hidePopover, onChange, target, placement, columns,
|
|||||||
<div className="sf-metadata-hide-columns-search-container">
|
<div className="sf-metadata-hide-columns-search-container">
|
||||||
<SearchInput placeholder={gettext('Search column')} onKeyDown={onKeyDown} onChange={onChangeSearch} autoFocus={true}/>
|
<SearchInput placeholder={gettext('Search column')} onKeyDown={onKeyDown} onChange={onChangeSearch} autoFocus={true}/>
|
||||||
</div>
|
</div>
|
||||||
<HiddenColumns columns={displayColumns} hiddenColumns={hiddenColumns} onChange={hideColumn} />
|
<HiddenColumns readOnly={readOnly} columns={displayColumns} hiddenColumns={hiddenColumns} onChange={hideColumn} />
|
||||||
{!searchValue && (
|
{!readOnly && !searchValue && (
|
||||||
<div className="sf-metadata-hide-columns-operations">
|
<div className="sf-metadata-hide-columns-operations">
|
||||||
<div className="sf-metadata-hide-columns-operation px-2" onClick={hideAll} aria-label={gettext('Hide all')}>{gettext('Hide all')}</div>
|
<div className="sf-metadata-hide-columns-operation px-2" onClick={hideAll} aria-label={gettext('Hide all')}>{gettext('Hide all')}</div>
|
||||||
<div className="sf-metadata-hide-columns-operation px-2" onClick={showAll} aria-label={gettext('Show all')}>{gettext('Show all')}</div>
|
<div className="sf-metadata-hide-columns-operation px-2" onClick={showAll} aria-label={gettext('Show all')}>{gettext('Show all')}</div>
|
||||||
@@ -118,6 +118,7 @@ const HideColumnPopover = ({ hidePopover, onChange, target, placement, columns,
|
|||||||
};
|
};
|
||||||
|
|
||||||
HideColumnPopover.propTypes = {
|
HideColumnPopover.propTypes = {
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
placement: PropTypes.string.isRequired,
|
placement: PropTypes.string.isRequired,
|
||||||
target: PropTypes.string.isRequired,
|
target: PropTypes.string.isRequired,
|
||||||
hiddenColumns: PropTypes.array.isRequired,
|
hiddenColumns: PropTypes.array.isRequired,
|
||||||
|
@@ -18,19 +18,19 @@ import './index.css';
|
|||||||
const SORT_TYPES = [SORT_TYPE.UP, SORT_TYPE.DOWN];
|
const SORT_TYPES = [SORT_TYPE.UP, SORT_TYPE.DOWN];
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
target: PropTypes.string.isRequired,
|
target: PropTypes.string.isRequired,
|
||||||
isNeedSubmit: PropTypes.bool,
|
isNeedSubmit: PropTypes.bool,
|
||||||
sorts: PropTypes.array,
|
sorts: PropTypes.array,
|
||||||
columns: PropTypes.array.isRequired,
|
columns: PropTypes.array.isRequired,
|
||||||
onSortComponentToggle: PropTypes.func,
|
onSortComponentToggle: PropTypes.func,
|
||||||
update: PropTypes.func,
|
update: PropTypes.func,
|
||||||
readonly: PropTypes.bool,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SortPopover extends Component {
|
class SortPopover extends Component {
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
readonly: false,
|
readOnly: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -183,7 +183,7 @@ class SortPopover extends Component {
|
|||||||
|
|
||||||
renderSortItem = (column, sort, index) => {
|
renderSortItem = (column, sort, index) => {
|
||||||
let { name, type } = column;
|
let { name, type } = column;
|
||||||
const { readonly } = this.props;
|
const { readOnly } = this.props;
|
||||||
let selectedColumn = {
|
let selectedColumn = {
|
||||||
label: (
|
label: (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
@@ -200,7 +200,7 @@ class SortPopover extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={'sort-item-' + index} className="sort-item">
|
<div key={'sort-item-' + index} className="sort-item">
|
||||||
{!readonly &&
|
{!readOnly &&
|
||||||
<div className="delete-sort" onClick={(event) => this.deleteSort(event, index)}>
|
<div className="delete-sort" onClick={(event) => this.deleteSort(event, index)}>
|
||||||
<Icon iconName="fork-number"/>
|
<Icon iconName="fork-number"/>
|
||||||
</div>
|
</div>
|
||||||
@@ -208,7 +208,7 @@ class SortPopover extends Component {
|
|||||||
<div className="condition">
|
<div className="condition">
|
||||||
<div className="sort-column">
|
<div className="sort-column">
|
||||||
<CustomizeSelect
|
<CustomizeSelect
|
||||||
isLocked={readonly}
|
readOnly={readOnly}
|
||||||
value={selectedColumn}
|
value={selectedColumn}
|
||||||
onSelectOption={(value) => this.onSelectColumn(value, index)}
|
onSelectOption={(value) => this.onSelectColumn(value, index)}
|
||||||
options={this.columnsOptions}
|
options={this.columnsOptions}
|
||||||
@@ -219,7 +219,7 @@ class SortPopover extends Component {
|
|||||||
</div>
|
</div>
|
||||||
<div className="sort-predicate ml-2">
|
<div className="sort-predicate ml-2">
|
||||||
<CustomizeSelect
|
<CustomizeSelect
|
||||||
isLocked={readonly}
|
readOnly={readOnly}
|
||||||
value={selectedSortType}
|
value={selectedSortType}
|
||||||
onSelectOption={(value) => this.onSelectSortType(value, index)}
|
onSelectOption={(value) => this.onSelectSortType(value, index)}
|
||||||
options={this.sortTypeOptions}
|
options={this.sortTypeOptions}
|
||||||
@@ -235,7 +235,7 @@ class SortPopover extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { target, readonly } = this.props;
|
const { target, readOnly } = this.props;
|
||||||
const { sorts } = this.state;
|
const { sorts } = this.state;
|
||||||
const isEmpty = isSortsEmpty(sorts);
|
const isEmpty = isSortsEmpty(sorts);
|
||||||
return (
|
return (
|
||||||
@@ -255,7 +255,7 @@ class SortPopover extends Component {
|
|||||||
this.renderSortsList()
|
this.renderSortsList()
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
{!readonly &&
|
{!readOnly &&
|
||||||
<CustomizeAddTool
|
<CustomizeAddTool
|
||||||
callBack={this.addSort}
|
callBack={this.addSort}
|
||||||
footerName={gettext('Add sort')}
|
footerName={gettext('Add sort')}
|
||||||
@@ -263,7 +263,7 @@ class SortPopover extends Component {
|
|||||||
addIconClassName="popover-add-icon"
|
addIconClassName="popover-add-icon"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
{(this.isNeedSubmit() && !readonly) && (
|
{(this.isNeedSubmit() && !readOnly) && (
|
||||||
<div className='sf-metadata-sort-popover-footer'>
|
<div className='sf-metadata-sort-popover-footer'>
|
||||||
<Button className='mr-2' onClick={this.onClosePopover}>{gettext('Cancel')}</Button>
|
<Button className='mr-2' onClick={this.onClosePopover}>{gettext('Cancel')}</Button>
|
||||||
<Button color="primary" disabled={this.state.isSubmitDisabled} onClick={this.onSubmitSorts}>{gettext('Submit')}</Button>
|
<Button color="primary" disabled={this.state.isSubmitDisabled} onClick={this.onSubmitSorts}>{gettext('Submit')}</Button>
|
||||||
|
@@ -63,6 +63,8 @@ const ViewToolBar = ({ metadataViewId }) => {
|
|||||||
|
|
||||||
if (!view) return null;
|
if (!view) return null;
|
||||||
|
|
||||||
|
const readOnly = !window.sfMetadataContext.canModifyView(view);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="sf-metadata-tool"
|
className="sf-metadata-tool"
|
||||||
@@ -73,6 +75,7 @@ const ViewToolBar = ({ metadataViewId }) => {
|
|||||||
wrapperClass="sf-metadata-view-tool-operation-btn sf-metadata-view-tool-filter"
|
wrapperClass="sf-metadata-view-tool-operation-btn sf-metadata-view-tool-filter"
|
||||||
filtersClassName="sf-metadata-filters"
|
filtersClassName="sf-metadata-filters"
|
||||||
target="sf-metadata-filter-popover"
|
target="sf-metadata-filter-popover"
|
||||||
|
readOnly={readOnly}
|
||||||
filterConjunction={view.filter_conjunction}
|
filterConjunction={view.filter_conjunction}
|
||||||
filters={view.filters}
|
filters={view.filters}
|
||||||
columns={availableColumns}
|
columns={availableColumns}
|
||||||
@@ -82,6 +85,7 @@ const ViewToolBar = ({ metadataViewId }) => {
|
|||||||
<SortSetter
|
<SortSetter
|
||||||
wrapperClass="sf-metadata-view-tool-operation-btn sf-metadata-view-tool-sort"
|
wrapperClass="sf-metadata-view-tool-operation-btn sf-metadata-view-tool-sort"
|
||||||
target="sf-metadata-sort-popover"
|
target="sf-metadata-sort-popover"
|
||||||
|
readOnly={readOnly}
|
||||||
sorts={view.sorts}
|
sorts={view.sorts}
|
||||||
columns={viewColumns}
|
columns={viewColumns}
|
||||||
modifySorts={modifySorts}
|
modifySorts={modifySorts}
|
||||||
@@ -89,6 +93,7 @@ const ViewToolBar = ({ metadataViewId }) => {
|
|||||||
<GroupbySetter
|
<GroupbySetter
|
||||||
wrapperClass="sf-metadata-view-tool-operation-btn sf-metadata-view-tool-groupby"
|
wrapperClass="sf-metadata-view-tool-operation-btn sf-metadata-view-tool-groupby"
|
||||||
target="sf-metadata-groupby-popover"
|
target="sf-metadata-groupby-popover"
|
||||||
|
readOnly={readOnly}
|
||||||
columns={viewColumns}
|
columns={viewColumns}
|
||||||
groupbys={view.groupbys}
|
groupbys={view.groupbys}
|
||||||
modifyGroupbys={modifyGroupbys}
|
modifyGroupbys={modifyGroupbys}
|
||||||
@@ -96,6 +101,7 @@ const ViewToolBar = ({ metadataViewId }) => {
|
|||||||
<HideColumnSetter
|
<HideColumnSetter
|
||||||
wrapperClass="sf-metadata-view-tool-operation-btn sf-metadata-view-tool-hide-column"
|
wrapperClass="sf-metadata-view-tool-operation-btn sf-metadata-view-tool-hide-column"
|
||||||
target="sf-metadata-hide-column-popover"
|
target="sf-metadata-hide-column-popover"
|
||||||
|
readOnly={readOnly}
|
||||||
columns={viewColumns.slice(1)}
|
columns={viewColumns.slice(1)}
|
||||||
hiddenColumns={view.hidden_columns || []}
|
hiddenColumns={view.hidden_columns || []}
|
||||||
modifyHiddenColumns={modifyHiddenColumns}
|
modifyHiddenColumns={modifyHiddenColumns}
|
||||||
|
@@ -130,6 +130,11 @@ class Context {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
canModifyView = (view) => {
|
||||||
|
if (this.permission === 'r') return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
getCollaboratorFromCache(email) {
|
getCollaboratorFromCache(email) {
|
||||||
return this.collaboratorsCache[email];
|
return this.collaboratorsCache[email];
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user