diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ca6bfcbc144..3d5703e72ce 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -19,7 +19,7 @@ "@seafile/sdoc-editor": "1.0.41", "@seafile/seafile-calendar": "0.0.12", "@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/react-codemirror": "^4.19.4", "chart.js": "2.9.4", @@ -5092,9 +5092,9 @@ } }, "node_modules/@seafile/sf-metadata-ui-component": { - "version": "0.0.16", - "resolved": "https://registry.npmjs.org/@seafile/sf-metadata-ui-component/-/sf-metadata-ui-component-0.0.16.tgz", - "integrity": "sha512-f5yOmP2LPWdlJfhlM5RKu7hmmGlNxlV7V0qjP2XNne4/s0Z7elqeZ4ZxRKtSTZwAHtgyazHSJ93EqEwU67wQfg==", + "version": "0.0.17", + "resolved": "https://registry.npmjs.org/@seafile/sf-metadata-ui-component/-/sf-metadata-ui-component-0.0.17.tgz", + "integrity": "sha512-2m8bIAXxzw0ZOMFsGesh4lXQdoOL1/0ONP0pwFxEVWtyG6zRThiFL80OgqGKjluVlehxpfgOaTgIQYr6Wy6IEw==", "dependencies": { "@seafile/seafile-calendar": "0.0.24", "@seafile/seafile-editor": "~1.0.102", diff --git a/frontend/package.json b/frontend/package.json index 0c332e78439..ad6b246ab34 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,7 +14,7 @@ "@seafile/sdoc-editor": "1.0.41", "@seafile/seafile-calendar": "0.0.12", "@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/react-codemirror": "^4.19.4", "chart.js": "2.9.4", diff --git a/frontend/src/metadata/metadata-view/components/data-process-setter/filter-setter.jsx b/frontend/src/metadata/metadata-view/components/data-process-setter/filter-setter.jsx index e0cb36c4713..c1c825141f7 100644 --- a/frontend/src/metadata/metadata-view/components/data-process-setter/filter-setter.jsx +++ b/frontend/src/metadata/metadata-view/components/data-process-setter/filter-setter.jsx @@ -7,7 +7,9 @@ import { getValidFilters, CommonlyUsedHotkey } from '../../_basic'; import { gettext } from '../../../../utils/constants'; import { FilterPopover } from '../popover'; -const FilterSetter = ({ columns, +const FilterSetter = ({ + readOnly, + columns, wrapperClass, filters: propsFilters, isNeedSubmit, @@ -67,6 +69,7 @@ const FilterSetter = ({ columns, placement="bottom-end" filtersClassName={filtersClassName} target={target} + readOnly={readOnly} isNeedSubmit={isNeedSubmit} columns={columns} collaborators={collaborators} @@ -83,6 +86,7 @@ const FilterSetter = ({ columns, }; FilterSetter.propTypes = { + readOnly: PropTypes.bool, wrapperClass: PropTypes.string, filtersClassName: PropTypes.string, target: PropTypes.string, diff --git a/frontend/src/metadata/metadata-view/components/data-process-setter/groupby-setter.jsx b/frontend/src/metadata/metadata-view/components/data-process-setter/groupby-setter.jsx index 2f1fd7da29a..ef60ed86d49 100644 --- a/frontend/src/metadata/metadata-view/components/data-process-setter/groupby-setter.jsx +++ b/frontend/src/metadata/metadata-view/components/data-process-setter/groupby-setter.jsx @@ -6,7 +6,7 @@ import { CommonlyUsedHotkey, getValidGroupbys, SUPPORT_GROUP_COLUMN_TYPES } from import { gettext } from '../../utils'; 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 columns = useMemo(() => { @@ -56,6 +56,7 @@ const GroupbySetter = ({ columns: allColumns, groupbys: propsGroupbys, wrapperCl /> {isShowSetter && ( { +const HideColumnSetter = ({ readOnly, columns, wrapperClass, target, hiddenColumns, modifyHiddenColumns }) => { const [isShowSetter, setShowSetter] = useState(false); const validHiddenColumns = useMemo(() => { @@ -50,6 +50,7 @@ const HideColumnSetter = ({ columns, wrapperClass, target, hiddenColumns, modify /> {isShowSetter && ( { +const SortSetter = ({ target, sorts: propsSorts, readOnly, columns, isNeedSubmit, wrapperClass, modifySorts }) => { const [isShowSetter, setShowSetter] = useState(false); const sorts = useMemo(() => { @@ -53,6 +53,7 @@ const SortSetter = ({ target, sorts: propsSorts, columns, isNeedSubmit, wrapperC {isShowSetter && ( 0; return ( @@ -169,17 +169,19 @@ class FilterPopover extends Component { deleteFilter={this.deleteFilter} updateFilterConjunction={this.updateFilterConjunction} collaborators={this.props.collaborators} - readOnly={false} + readOnly={readOnly} scheduleUpdate={scheduleUpdate} isPre={this.props.isPre} /> - this.addFilter(scheduleUpdate) : () => {}} - footerName={gettext('Add filter')} - addIconClassName="popover-add-icon" - /> - {this.isNeedSubmit() && ( + {!readOnly && ( + this.addFilter(scheduleUpdate) : () => {}} + footerName={gettext('Add filter')} + addIconClassName="popover-add-icon" + /> + )} + {!readOnly && this.isNeedSubmit() && (
@@ -197,7 +199,7 @@ FilterPopover.propTypes = { filtersClassName: PropTypes.string, target: PropTypes.string.isRequired, isNeedSubmit: PropTypes.bool, - isLocked: PropTypes.bool, + readOnly: PropTypes.bool, columns: PropTypes.array.isRequired, filterConjunction: PropTypes.string, filters: PropTypes.array, diff --git a/frontend/src/metadata/metadata-view/components/popover/filter-popover/widgets/filter-calendar.js b/frontend/src/metadata/metadata-view/components/popover/filter-popover/widgets/filter-calendar.js index b3e8c4349d5..4ad5fc8e143 100644 --- a/frontend/src/metadata/metadata-view/components/popover/filter-popover/widgets/filter-calendar.js +++ b/frontend/src/metadata/metadata-view/components/popover/filter-popover/widgets/filter-calendar.js @@ -3,12 +3,12 @@ import PropTypes from 'prop-types'; import { SfFilterCalendar } from '@seafile/sf-metadata-ui-component'; import { getDateColumnFormat } from '../../../../utils/column-utils'; -const FilterCalendar = ({ value, filterColumn, isReadOnly, onChange }) => { +const FilterCalendar = ({ value, filterColumn, readOnly, onChange }) => { const format = getDateColumnFormat(filterColumn).trim(); const lang = window.sfMetadataContext.getSetting('lang'); return ( { +const CollaboratorFilter = ({ readOnly, filterIndex, filterTerm, collaborators, placeholder, filter_predicate, onSelectCollaborator }) => { const supportMultipleSelectOptions = useMemo(() => { return [ FILTER_PREDICATE_TYPE.HAS_ANY_OF, @@ -80,7 +80,7 @@ const CollaboratorFilter = ({ isLocked, filterIndex, filterTerm, collaborators, onSelectOption={onSelectCollaborator} options={options} placeholder={placeholder} - isLocked={isLocked} + readOnly={readOnly} supportMultipleSelect={isSupportMultipleSelect} searchable={true} searchPlaceholder={gettext('Search collaborator')} @@ -96,7 +96,7 @@ CollaboratorFilter.propTypes = { filter_predicate: PropTypes.string, collaborators: PropTypes.array, onSelectCollaborator: PropTypes.func, - isLocked: PropTypes.bool, + readOnly: PropTypes.bool, placeholder: PropTypes.string, }; diff --git a/frontend/src/metadata/metadata-view/components/popover/filter-popover/widgets/filter-item/index.js b/frontend/src/metadata/metadata-view/components/popover/filter-popover/widgets/filter-item/index.js index 9e81e37037e..05636932eb7 100644 --- a/frontend/src/metadata/metadata-view/components/popover/filter-popover/widgets/filter-item/index.js +++ b/frontend/src/metadata/metadata-view/components/popover/filter-popover/widgets/filter-item/index.js @@ -25,6 +25,7 @@ import { DELETED_OPTION_BACKGROUND_COLOR, DELETED_OPTION_TIPS } from '../../../. import './index.css'; const propTypes = { + readOnly: PropTypes.bool, index: PropTypes.number.isRequired, filter: PropTypes.object.isRequired, filterColumn: PropTypes.object.isRequired, @@ -245,6 +246,7 @@ class FilterItem extends React.Component { }; getInputComponent = (type) => { + const { readOnly } = this.props; const { filterTerm } = this.state; if (type === 'text') { return ( @@ -252,13 +254,16 @@ class FilterItem extends React.Component { value={filterTerm} onChange={this.onFilterTermTextChanged} autoFocus={false} + disabled={readOnly} className='text-truncate' /> ); } else if (type === 'checkbox') { + const { readOnly } = this.props; return ( @@ -267,7 +272,7 @@ class FilterItem extends React.Component { }; renderConjunction = () => { - const { index, filterConjunction, conjunctionOptions } = this.props; + const { index, readOnly, filterConjunction, conjunctionOptions } = this.props; switch (index) { case 0: { return null; @@ -276,6 +281,7 @@ class FilterItem extends React.Component { const activeConjunction = FilterItemUtils.getActiveConjunctionOption(filterConjunction); return ( { - const { index, filter, collaborators } = this.props; + const { index, filter, collaborators, readOnly } = this.props; const { type } = filterColumn; const { filter_term, filter_predicate, filter_term_modifier } = filter; // predicate is empty or not empty @@ -381,6 +387,7 @@ class FilterItem extends React.Component { if (filter_term_modifier === 'exact_date') { return ( -
- -
+ {!readOnly && ( +
+ +
+ )}
{this.renderConjunction()} @@ -531,6 +543,7 @@ class FilterItem extends React.Component {
{ - const { filterConjunction, value } = this.props; + const { readOnly, filterConjunction, value } = this.props; const conjunctionOptions = this.getConjunctionOptions(); const columnOptions = this.getColumnOptions(); return ( ({ */ const GroupbyItem = memo(({ isOver, isDragging, canDrop, connectDragSource, connectDragPreview, connectDropTarget, - showDragBtn, index, groupby, columns, onDelete, onUpdate + showDragBtn, index, readOnly, groupby, columns, onDelete, onUpdate }) => { const column = useMemo(() => { return getColumnByKey(columns, groupby.column_key); @@ -162,12 +162,15 @@ const GroupbyItem = memo(({ { 'group-can-drop': isOver && canDrop && !isDragging } )} > -
- -
+ {!readOnly && ( +
+ +
+ )}
{(!column.key || SORT_COLUMN_OPTIONS.includes(column.type)) && (
- {showDragBtn && connectDragSource( + {!readOnly && showDragBtn && connectDragSource(
@@ -217,6 +222,7 @@ const GroupbyItem = memo(({ GroupbyItem.propTypes = { index: PropTypes.number, + readOnly: PropTypes.bool, groupby: PropTypes.object, columns: PropTypes.array, onDelete: PropTypes.func, diff --git a/frontend/src/metadata/metadata-view/components/popover/groupbys-popover/groupbys/index.js b/frontend/src/metadata/metadata-view/components/popover/groupbys-popover/groupbys/index.js index dbebd237c86..43b68c482bd 100644 --- a/frontend/src/metadata/metadata-view/components/popover/groupbys-popover/groupbys/index.js +++ b/frontend/src/metadata/metadata-view/components/popover/groupbys-popover/groupbys/index.js @@ -6,15 +6,16 @@ import html5DragDropContext from '../../../../../../pages/wiki2/wiki-nav/html5Dr import { gettext } from '../../../../utils'; import GroupbyItem from './groupby-item'; -const Groupbys = ({ groupbys, columns, onDelete, onUpdate, onMove }) => { +const Groupbys = ({ readOnly, groupbys, columns, onDelete, onUpdate, onMove }) => { const isEmpty = useMemo(() => { if (!Array.isArray(groupbys) || groupbys.length === 0) return true; return false; }, [groupbys]); const showDragBtn = useMemo(() => { + if (readOnly) return false; if (!Array.isArray(groupbys) || groupbys.length === 0) return false; return groupbys.length > 1; - }, [groupbys]); + }, [readOnly, groupbys]); return (
@@ -24,6 +25,7 @@ const Groupbys = ({ groupbys, columns, onDelete, onUpdate, onMove }) => { { +const GroupbysPopover = ({ groupbys: propsGroupBys, readOnly, hidePopover, onChange, target, placement, columns }) => { const [groupbys, setGroupbys] = useState(propsGroupBys); const isSelectOpenRef = useState(false); const popoverRef = useRef(null); @@ -107,8 +107,8 @@ const GroupbysPopover = ({ groupbys: propsGroupBys, hidePopover, onChange, targe boundariesElement={document.body} >
- - {(groupbys.length < MAX_GROUP_LEVEL) && ( + + {!readOnly && (groupbys.length < MAX_GROUP_LEVEL) && ( { +const HideColumnItem = ({ readOnly, column, isHidden, onChange }) => { const update = useCallback(() => { + if (readOnly) return; onChange(column.key); - }, [column, onChange]); + }, [readOnly, column, onChange]); return ( -
+
@@ -27,6 +30,7 @@ const HideColumnItem = ({ column, isHidden, onChange }) => { }; HideColumnItem.propTypes = { + readOnly: PropTypes.bool, isHidden: PropTypes.bool, column: PropTypes.object.isRequired, onChange: PropTypes.func.isRequired, diff --git a/frontend/src/metadata/metadata-view/components/popover/hidden-column-popover/hidden-columns/index.js b/frontend/src/metadata/metadata-view/components/popover/hidden-column-popover/hidden-columns/index.js index 0e533bb0b93..360f91e67d7 100644 --- a/frontend/src/metadata/metadata-view/components/popover/hidden-column-popover/hidden-columns/index.js +++ b/frontend/src/metadata/metadata-view/components/popover/hidden-column-popover/hidden-columns/index.js @@ -4,7 +4,7 @@ import classnames from 'classnames'; import { gettext } from '../../../../utils'; import HideColumn from './hide-column'; -const HiddenColumns = ({ columns, hiddenColumns, onChange }) => { +const HiddenColumns = ({ readOnly, columns, hiddenColumns, onChange }) => { const isEmpty = useMemo(() => { if (!Array.isArray(columns) || columns.length === 0) return true; return false; @@ -17,6 +17,7 @@ const HiddenColumns = ({ columns, hiddenColumns, onChange }) => { return ( { }; HiddenColumns.propTypes = { + readOnly: PropTypes.bool, hiddenColumns: PropTypes.array, columns: PropTypes.array, onChange: PropTypes.func, diff --git a/frontend/src/metadata/metadata-view/components/popover/hidden-column-popover/index.css b/frontend/src/metadata/metadata-view/components/popover/hidden-column-popover/index.css index 12bb8c8dd33..5810069fd77 100644 --- a/frontend/src/metadata/metadata-view/components/popover/hidden-column-popover/index.css +++ b/frontend/src/metadata/metadata-view/components/popover/hidden-column-popover/index.css @@ -57,10 +57,10 @@ .sf-metadata-hide-columns-popover .hide-columns-list .hide-column-item:hover { 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; } diff --git a/frontend/src/metadata/metadata-view/components/popover/hidden-column-popover/index.js b/frontend/src/metadata/metadata-view/components/popover/hidden-column-popover/index.js index b6784d2c385..28f6b1b8d3c 100644 --- a/frontend/src/metadata/metadata-view/components/popover/hidden-column-popover/index.js +++ b/frontend/src/metadata/metadata-view/components/popover/hidden-column-popover/index.js @@ -9,7 +9,7 @@ import { getEventClassName, gettext } from '../../../utils'; 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 [hiddenColumns, setHiddenColumns] = useState(oldHiddenColumns); const displayColumns = useMemo(() => { @@ -104,8 +104,8 @@ const HideColumnPopover = ({ hidePopover, onChange, target, placement, columns,
- - {!searchValue && ( + + {!readOnly && !searchValue && (
{gettext('Hide all')}
{gettext('Show all')}
@@ -118,6 +118,7 @@ const HideColumnPopover = ({ hidePopover, onChange, target, placement, columns, }; HideColumnPopover.propTypes = { + readOnly: PropTypes.bool, placement: PropTypes.string.isRequired, target: PropTypes.string.isRequired, hiddenColumns: PropTypes.array.isRequired, diff --git a/frontend/src/metadata/metadata-view/components/popover/sort-popover/index.jsx b/frontend/src/metadata/metadata-view/components/popover/sort-popover/index.jsx index 7eb0994c3d2..907dc93f828 100644 --- a/frontend/src/metadata/metadata-view/components/popover/sort-popover/index.jsx +++ b/frontend/src/metadata/metadata-view/components/popover/sort-popover/index.jsx @@ -18,19 +18,19 @@ import './index.css'; const SORT_TYPES = [SORT_TYPE.UP, SORT_TYPE.DOWN]; const propTypes = { + readOnly: PropTypes.bool, target: PropTypes.string.isRequired, isNeedSubmit: PropTypes.bool, sorts: PropTypes.array, columns: PropTypes.array.isRequired, onSortComponentToggle: PropTypes.func, update: PropTypes.func, - readonly: PropTypes.bool, }; class SortPopover extends Component { static defaultProps = { - readonly: false, + readOnly: false, }; constructor(props) { @@ -183,7 +183,7 @@ class SortPopover extends Component { renderSortItem = (column, sort, index) => { let { name, type } = column; - const { readonly } = this.props; + const { readOnly } = this.props; let selectedColumn = { label: ( @@ -200,7 +200,7 @@ class SortPopover extends Component { return (
- {!readonly && + {!readOnly &&
this.deleteSort(event, index)}>
@@ -208,7 +208,7 @@ class SortPopover extends Component {
this.onSelectColumn(value, index)} options={this.columnsOptions} @@ -219,7 +219,7 @@ class SortPopover extends Component {
this.onSelectSortType(value, index)} options={this.sortTypeOptions} @@ -235,7 +235,7 @@ class SortPopover extends Component { }; render() { - const { target, readonly } = this.props; + const { target, readOnly } = this.props; const { sorts } = this.state; const isEmpty = isSortsEmpty(sorts); return ( @@ -255,7 +255,7 @@ class SortPopover extends Component { this.renderSortsList() }
- {!readonly && + {!readOnly && } - {(this.isNeedSubmit() && !readonly) && ( + {(this.isNeedSubmit() && !readOnly) && (
diff --git a/frontend/src/metadata/metadata-view/components/view-toolbar/index.js b/frontend/src/metadata/metadata-view/components/view-toolbar/index.js index cd5c12d3523..31305568287 100644 --- a/frontend/src/metadata/metadata-view/components/view-toolbar/index.js +++ b/frontend/src/metadata/metadata-view/components/view-toolbar/index.js @@ -63,6 +63,8 @@ const ViewToolBar = ({ metadataViewId }) => { if (!view) return null; + const readOnly = !window.sfMetadataContext.canModifyView(view); + return (
{ wrapperClass="sf-metadata-view-tool-operation-btn sf-metadata-view-tool-filter" filtersClassName="sf-metadata-filters" target="sf-metadata-filter-popover" + readOnly={readOnly} filterConjunction={view.filter_conjunction} filters={view.filters} columns={availableColumns} @@ -82,6 +85,7 @@ const ViewToolBar = ({ metadataViewId }) => { { { { + if (this.permission === 'r') return false; + return true; + }; + getCollaboratorFromCache(email) { return this.collaboratorsCache[email]; }