mirror of
https://github.com/haiwen/seahub.git
synced 2025-08-19 07:27:56 +00:00
feat: metadata basic filter (#6633)
* feat: metadata basic filter * feat: update code * feat: update code --------- Co-authored-by: 杨国璇 <ygx@192.168.124.9> Co-authored-by: 杨国璇 <ygx@Hello-word.local>
This commit is contained in:
parent
50035219bb
commit
2ec3fc7a51
@ -10,6 +10,7 @@ export const NOT_DISPLAY_COLUMN_KEYS = [
|
|||||||
PRIVATE_COLUMN_KEY.SUFFIX,
|
PRIVATE_COLUMN_KEY.SUFFIX,
|
||||||
PRIVATE_COLUMN_KEY.FILE_DETAILS,
|
PRIVATE_COLUMN_KEY.FILE_DETAILS,
|
||||||
PRIVATE_COLUMN_KEY.LOCATION,
|
PRIVATE_COLUMN_KEY.LOCATION,
|
||||||
|
PRIVATE_COLUMN_KEY.IS_DIR,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const VIEW_NOT_DISPLAY_COLUMN_KEYS = [
|
export const VIEW_NOT_DISPLAY_COLUMN_KEYS = [
|
||||||
|
@ -18,6 +18,7 @@ const FilterSetter = ({
|
|||||||
filtersClassName,
|
filtersClassName,
|
||||||
target,
|
target,
|
||||||
filterConjunction,
|
filterConjunction,
|
||||||
|
basicFilters,
|
||||||
modifyFilters
|
modifyFilters
|
||||||
}) => {
|
}) => {
|
||||||
const [isShowSetter, setShowSetter] = useState(false);
|
const [isShowSetter, setShowSetter] = useState(false);
|
||||||
@ -26,12 +27,15 @@ const FilterSetter = ({
|
|||||||
return deepCopy(getValidFilters(propsFilters || [], columns));
|
return deepCopy(getValidFilters(propsFilters || [], columns));
|
||||||
}, [propsFilters, columns]);
|
}, [propsFilters, columns]);
|
||||||
|
|
||||||
|
const filtersCount = useMemo(() => {
|
||||||
|
return filters.length + basicFilters.length;
|
||||||
|
}, [filters, basicFilters]);
|
||||||
|
|
||||||
const message = useMemo(() => {
|
const message = useMemo(() => {
|
||||||
const filtersLength = filters.length;
|
if (filtersCount === 1) return isNeedSubmit ? gettext('1 preset filter') : gettext('1 filter');
|
||||||
if (filtersLength === 1) return isNeedSubmit ? gettext('1 preset filter') : gettext('1 filter');
|
if (filtersCount > 1) return filtersCount + ' ' + (isNeedSubmit ? gettext('Preset filters') : gettext('Filters'));
|
||||||
if (filtersLength > 1) return filtersLength + ' ' + (isNeedSubmit ? gettext('Preset filters') : gettext('Filters'));
|
|
||||||
return isNeedSubmit ? gettext('Preset filter') : gettext('Filter');
|
return isNeedSubmit ? gettext('Preset filter') : gettext('Filter');
|
||||||
}, [isNeedSubmit, filters]);
|
}, [isNeedSubmit, filtersCount]);
|
||||||
|
|
||||||
const onSetterToggle = useCallback(() => {
|
const onSetterToggle = useCallback(() => {
|
||||||
setShowSetter(!isShowSetter);
|
setShowSetter(!isShowSetter);
|
||||||
@ -43,13 +47,13 @@ const FilterSetter = ({
|
|||||||
}, [onSetterToggle]);
|
}, [onSetterToggle]);
|
||||||
|
|
||||||
const onChange = useCallback((update) => {
|
const onChange = useCallback((update) => {
|
||||||
const { filters, filter_conjunction } = update || {};
|
const { filters, filter_conjunction, basic_filters } = update || {};
|
||||||
const validFilters = getValidFilters(filters, columns);
|
const validFilters = getValidFilters(filters, columns);
|
||||||
modifyFilters(validFilters, filter_conjunction);
|
modifyFilters(validFilters, filter_conjunction, basic_filters);
|
||||||
}, [columns, modifyFilters]);
|
}, [columns, modifyFilters]);
|
||||||
|
|
||||||
if (!columns) return null;
|
if (!columns) return null;
|
||||||
const className = classnames(wrapperClass, { 'active': filters.length > 0 });
|
const className = classnames(wrapperClass, { 'active': filtersCount > 0 });
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<IconBtn
|
<IconBtn
|
||||||
@ -75,6 +79,7 @@ const FilterSetter = ({
|
|||||||
collaborators={collaborators}
|
collaborators={collaborators}
|
||||||
filterConjunction={filterConjunction}
|
filterConjunction={filterConjunction}
|
||||||
filters={filters}
|
filters={filters}
|
||||||
|
basicFilters={basicFilters}
|
||||||
hidePopover={onSetterToggle}
|
hidePopover={onSetterToggle}
|
||||||
update={onChange}
|
update={onChange}
|
||||||
isPre={isPre}
|
isPre={isPre}
|
||||||
@ -97,11 +102,13 @@ FilterSetter.propTypes = {
|
|||||||
modifyFilters: PropTypes.func,
|
modifyFilters: PropTypes.func,
|
||||||
collaborators: PropTypes.array,
|
collaborators: PropTypes.array,
|
||||||
isPre: PropTypes.bool,
|
isPre: PropTypes.bool,
|
||||||
|
basicFilters: PropTypes.array,
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterSetter.defaultProps = {
|
FilterSetter.defaultProps = {
|
||||||
target: 'sf-metadata-filter-popover',
|
target: 'sf-metadata-filter-popover',
|
||||||
isNeedSubmit: false,
|
isNeedSubmit: false,
|
||||||
|
basicFilters: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FilterSetter;
|
export default FilterSetter;
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
import React, { useCallback, useMemo } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { gettext } from '../../../../utils';
|
||||||
|
import { CustomizeSelect, Icon } from '@seafile/sf-metadata-ui-component';
|
||||||
|
|
||||||
|
const OPTIONS = [
|
||||||
|
{ value: 'file', name: gettext('Only files') },
|
||||||
|
{ value: 'folder', name: gettext('Only folders') },
|
||||||
|
{ value: 'all', name: gettext('Files and folders') },
|
||||||
|
];
|
||||||
|
|
||||||
|
const FileOrFolderFilter = ({ readOnly, value = 'all', onChange: onChangeAPI }) => {
|
||||||
|
|
||||||
|
const options = useMemo(() => {
|
||||||
|
return OPTIONS.map(o => {
|
||||||
|
const { name } = o;
|
||||||
|
return {
|
||||||
|
value: o.value,
|
||||||
|
label: (
|
||||||
|
<div className="select-basic-filter-option">
|
||||||
|
<div className="select-basic-filter-option-name" title={name} aria-label={name}>{name}</div>
|
||||||
|
<div className="select-basic-filter-option-check-icon">
|
||||||
|
{value === o.value && (<Icon iconName="check-mark" />)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
|
const displayValue = useMemo(() => {
|
||||||
|
const selectedOption = OPTIONS.find(o => o.value === value) || OPTIONS[2];
|
||||||
|
return {
|
||||||
|
label: (
|
||||||
|
<div>
|
||||||
|
{selectedOption.name}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
|
const onChange = useCallback((newValue) => {
|
||||||
|
if (newValue === value) return;
|
||||||
|
onChangeAPI(newValue);
|
||||||
|
}, [value, onChangeAPI]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CustomizeSelect
|
||||||
|
readOnly={readOnly}
|
||||||
|
className="sf-metadata-basic-filters-select"
|
||||||
|
value={displayValue}
|
||||||
|
options={options}
|
||||||
|
onSelectOption={onChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
FileOrFolderFilter.propTypes = {
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
|
value: PropTypes.string,
|
||||||
|
onChange: PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FileOrFolderFilter;
|
@ -0,0 +1,30 @@
|
|||||||
|
.sf-metadata-basic-filters-select {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-basic-filter-option {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-basic-filter-option .select-basic-filter-option-name {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-basic-filter-option .select-basic-filter-option-check-icon {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
text-align: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sf-metadata-option.sf-metadata-option-active .sf-metadata-icon-check-mark {
|
||||||
|
fill: #fff;
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
import React, { useCallback } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { FormGroup, Label } from 'reactstrap';
|
||||||
|
import { gettext } from '../../../../utils';
|
||||||
|
import { PRIVATE_COLUMN_KEY } from '../../../../_basic';
|
||||||
|
import FileOrFolderFilter from './file-folder-filter';
|
||||||
|
|
||||||
|
import './index.css';
|
||||||
|
|
||||||
|
const BasicFilters = ({ readOnly, filters = [], onChange }) => {
|
||||||
|
|
||||||
|
const onChangeFileOrFolderFilter = useCallback((newValue) => {
|
||||||
|
const filterIndex = filters.findIndex(filter => filter.column_key === PRIVATE_COLUMN_KEY.IS_DIR);
|
||||||
|
const filter = filters[filterIndex];
|
||||||
|
const newFilters = filters.slice(0);
|
||||||
|
newFilters[filterIndex] = { ...filter, filter_term: newValue };
|
||||||
|
onChange(newFilters);
|
||||||
|
}, [filters, onChange]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormGroup className="filter-group p-4">
|
||||||
|
<Label className="filter-group-name">{gettext('Basic')}</Label>
|
||||||
|
<div className="filter-group-container">
|
||||||
|
{filters.map(filter => {
|
||||||
|
const { column_key, filter_term } = filter;
|
||||||
|
if (column_key === PRIVATE_COLUMN_KEY.IS_DIR) {
|
||||||
|
return (
|
||||||
|
<FileOrFolderFilter key={column_key} readOnly={readOnly} value={filter_term} onChange={onChangeFileOrFolderFilter} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</FormGroup>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
BasicFilters.propTypes = {
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
|
value: PropTypes.string,
|
||||||
|
onChange: PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BasicFilters;
|
@ -2,3 +2,39 @@
|
|||||||
max-width: none;
|
max-width: none;
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sf-metadata-filter-popover .sf-metadata-filters {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sf-metadata-filter-popover .filter-group-name {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sf-metadata-filter-popover .filter-group-advanced {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sf-metadata-filter-popover .filter-group-advanced .filter-group-name {
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sf-metadata-filter-popover .filter-group-advanced .filter-group-container {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sf-metadata-filter-popover .add-item-btn.popover-add-tool {
|
||||||
|
height: 28px;
|
||||||
|
padding: 0 6px;
|
||||||
|
width: fit-content;
|
||||||
|
max-width: 100%;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-left: -6px;
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import isHotkey from 'is-hotkey';
|
import isHotkey from 'is-hotkey';
|
||||||
import { Button, UncontrolledPopover } from 'reactstrap';
|
import { Button, FormGroup, Label, UncontrolledPopover } from 'reactstrap';
|
||||||
import { CustomizeAddTool } from '@seafile/sf-metadata-ui-component';
|
import { CustomizeAddTool } from '@seafile/sf-metadata-ui-component';
|
||||||
import {
|
import {
|
||||||
FILTER_COLUMN_OPTIONS,
|
FILTER_COLUMN_OPTIONS,
|
||||||
@ -11,6 +11,7 @@ import { getEventClassName, gettext } from '../../../utils';
|
|||||||
import { getFilterByColumn } from '../../../utils/filters-utils';
|
import { getFilterByColumn } from '../../../utils/filters-utils';
|
||||||
import FiltersList from './widgets';
|
import FiltersList from './widgets';
|
||||||
import { EVENT_BUS_TYPE } from '../../../constants';
|
import { EVENT_BUS_TYPE } from '../../../constants';
|
||||||
|
import BasicFilters from './basic-filters';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ class FilterPopover extends Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
basicFilters: props.basicFilters,
|
||||||
filters: getValidFilters(props.filters, props.columns),
|
filters: getValidFilters(props.filters, props.columns),
|
||||||
filterConjunction: props.filterConjunction || 'And',
|
filterConjunction: props.filterConjunction || 'And',
|
||||||
};
|
};
|
||||||
@ -97,7 +99,7 @@ class FilterPopover extends Component {
|
|||||||
this.update(filters);
|
this.update(filters);
|
||||||
};
|
};
|
||||||
|
|
||||||
updateFilterConjunction = (conjunction) => {
|
modifyFilterConjunction = (conjunction) => {
|
||||||
if (this.props.isNeedSubmit) {
|
if (this.props.isNeedSubmit) {
|
||||||
const isSubmitDisabled = false;
|
const isSubmitDisabled = false;
|
||||||
this.setState({ filterConjunction: conjunction, isSubmitDisabled });
|
this.setState({ filterConjunction: conjunction, isSubmitDisabled });
|
||||||
@ -130,8 +132,8 @@ class FilterPopover extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onSubmitFilters = () => {
|
onSubmitFilters = () => {
|
||||||
const { filters, filterConjunction } = this.state;
|
const { filters, filterConjunction, basicFilters } = this.state;
|
||||||
const update = { filters, filter_conjunction: filterConjunction };
|
const update = { filters, filter_conjunction: filterConjunction, basic_filters: basicFilters };
|
||||||
this.props.update(update);
|
this.props.update(update);
|
||||||
this.props.hidePopover();
|
this.props.hidePopover();
|
||||||
};
|
};
|
||||||
@ -140,9 +142,21 @@ class FilterPopover extends Component {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onBasicFilterChange = (value) => {
|
||||||
|
if (this.props.isNeedSubmit) {
|
||||||
|
const isSubmitDisabled = false;
|
||||||
|
this.setState({ basicFilters: value, isSubmitDisabled });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.setState({ basicFilters: value }, () => {
|
||||||
|
const update = { filters: this.state.filters, filter_conjunction: this.state.filterConjunction, basic_filters: value };
|
||||||
|
this.props.update(update);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { readOnly, target, columns, placement } = this.props;
|
const { readOnly, target, columns, placement } = this.props;
|
||||||
const { filters, filterConjunction } = this.state;
|
const { filters, filterConjunction, basicFilters } = this.state;
|
||||||
const canAddFilter = columns.length > 0;
|
const canAddFilter = columns.length > 0;
|
||||||
return (
|
return (
|
||||||
<UncontrolledPopover
|
<UncontrolledPopover
|
||||||
@ -151,11 +165,15 @@ class FilterPopover extends Component {
|
|||||||
target={target}
|
target={target}
|
||||||
fade={false}
|
fade={false}
|
||||||
hideArrow={true}
|
hideArrow={true}
|
||||||
className=" sf-metadata-filter-popover"
|
className="sf-metadata-filter-popover"
|
||||||
boundariesElement={document.body}
|
boundariesElement={document.body}
|
||||||
>
|
>
|
||||||
{({ scheduleUpdate }) => (
|
{({ scheduleUpdate }) => (
|
||||||
<div ref={ref => this.dtablePopoverRef = ref} onClick={this.onPopoverInsideClick} className={this.props.filtersClassName}>
|
<div ref={ref => this.dtablePopoverRef = ref} onClick={this.onPopoverInsideClick} className={this.props.filtersClassName}>
|
||||||
|
<BasicFilters filters={basicFilters} onChange={this.onBasicFilterChange} />
|
||||||
|
<FormGroup className="filter-group-advanced filter-group mb-0">
|
||||||
|
<Label className="filter-group-name">{gettext('Advanced')}</Label>
|
||||||
|
<div className="filter-group-container">
|
||||||
<FiltersList
|
<FiltersList
|
||||||
filterConjunction={filterConjunction}
|
filterConjunction={filterConjunction}
|
||||||
filters={filters}
|
filters={filters}
|
||||||
@ -163,7 +181,7 @@ class FilterPopover extends Component {
|
|||||||
emptyPlaceholder={gettext('No filters')}
|
emptyPlaceholder={gettext('No filters')}
|
||||||
updateFilter={this.updateFilter}
|
updateFilter={this.updateFilter}
|
||||||
deleteFilter={this.deleteFilter}
|
deleteFilter={this.deleteFilter}
|
||||||
updateFilterConjunction={this.updateFilterConjunction}
|
modifyFilterConjunction={this.modifyFilterConjunction}
|
||||||
collaborators={this.props.collaborators}
|
collaborators={this.props.collaborators}
|
||||||
readOnly={readOnly}
|
readOnly={readOnly}
|
||||||
scheduleUpdate={scheduleUpdate}
|
scheduleUpdate={scheduleUpdate}
|
||||||
@ -177,6 +195,8 @@ class FilterPopover extends Component {
|
|||||||
addIconClassName="popover-add-icon"
|
addIconClassName="popover-add-icon"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
</FormGroup>
|
||||||
{!readOnly && this.props.isNeedSubmit && (
|
{!readOnly && this.props.isNeedSubmit && (
|
||||||
<div className="sf-metadata-popover-footer">
|
<div className="sf-metadata-popover-footer">
|
||||||
<Button className='mr-2' onClick={this.onClosePopover}>{gettext('Cancel')}</Button>
|
<Button className='mr-2' onClick={this.onClosePopover}>{gettext('Cancel')}</Button>
|
||||||
@ -201,6 +221,7 @@ FilterPopover.propTypes = {
|
|||||||
filters: PropTypes.array,
|
filters: PropTypes.array,
|
||||||
collaborators: PropTypes.array,
|
collaborators: PropTypes.array,
|
||||||
isPre: PropTypes.bool,
|
isPre: PropTypes.bool,
|
||||||
|
basicFilters: PropTypes.array,
|
||||||
hidePopover: PropTypes.func,
|
hidePopover: PropTypes.func,
|
||||||
update: PropTypes.func,
|
update: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
.sf-metadata-filters-list {
|
.sf-metadata-filters-list {
|
||||||
min-height: 120px;
|
min-height: 120px;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
padding: 15px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-filters-list.empty-filters-container {
|
.sf-metadata-filters-list.empty-filters-container {
|
||||||
min-height: 80px;
|
min-height: 80px;
|
||||||
padding: 16px;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-filters-list.empty-filters-container .empty-filters-list {
|
.sf-metadata-filters-list.empty-filters-container .empty-filters-list {
|
||||||
@ -230,7 +229,7 @@
|
|||||||
|
|
||||||
.sf-metadata-filters-list .multiple-check-icon .sf-metadata-icon-check-mark,
|
.sf-metadata-filters-list .multiple-check-icon .sf-metadata-icon-check-mark,
|
||||||
.sf-metadata-filters-list .collaborator-check-icon .sf-metadata-icon-check-mark {
|
.sf-metadata-filters-list .collaborator-check-icon .sf-metadata-icon-check-mark {
|
||||||
fill: #798d99;
|
fill: #798d99 !important;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ import React, { Component } from 'react';
|
|||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {
|
import {
|
||||||
VIEW_NOT_DISPLAY_COLUMN_KEYS,
|
|
||||||
FILTER_COLUMN_OPTIONS,
|
FILTER_COLUMN_OPTIONS,
|
||||||
ValidateFilter,
|
ValidateFilter,
|
||||||
getColumnByKey,
|
getColumnByKey,
|
||||||
@ -20,7 +19,7 @@ const propTypes = {
|
|||||||
filterConjunction: PropTypes.string.isRequired,
|
filterConjunction: PropTypes.string.isRequired,
|
||||||
updateFilter: PropTypes.func.isRequired,
|
updateFilter: PropTypes.func.isRequired,
|
||||||
deleteFilter: PropTypes.func.isRequired,
|
deleteFilter: PropTypes.func.isRequired,
|
||||||
updateFilterConjunction: PropTypes.func,
|
modifyFilterConjunction: PropTypes.func,
|
||||||
emptyPlaceholder: PropTypes.string,
|
emptyPlaceholder: PropTypes.string,
|
||||||
value: PropTypes.object,
|
value: PropTypes.object,
|
||||||
collaborators: PropTypes.array,
|
collaborators: PropTypes.array,
|
||||||
@ -53,7 +52,7 @@ class FiltersList extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
updateConjunction = (filterConjunction) => {
|
updateConjunction = (filterConjunction) => {
|
||||||
this.props.updateFilterConjunction(filterConjunction);
|
this.props.modifyFilterConjunction(filterConjunction);
|
||||||
};
|
};
|
||||||
|
|
||||||
getConjunctionOptions = () => {
|
getConjunctionOptions = () => {
|
||||||
@ -66,8 +65,7 @@ class FiltersList extends Component {
|
|||||||
getFilterColumns = () => {
|
getFilterColumns = () => {
|
||||||
const { columns } = this.props;
|
const { columns } = this.props;
|
||||||
return columns.filter(column => {
|
return columns.filter(column => {
|
||||||
let { type, key } = column;
|
let { type } = column;
|
||||||
if (VIEW_NOT_DISPLAY_COLUMN_KEYS.includes(key)) return false;
|
|
||||||
return Object.prototype.hasOwnProperty.call(FILTER_COLUMN_OPTIONS, type);
|
return Object.prototype.hasOwnProperty.call(FILTER_COLUMN_OPTIONS, type);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -100,8 +100,8 @@ const Container = () => {
|
|||||||
return { rowIdsInOrder, upperRowIds, belowRowIds };
|
return { rowIdsInOrder, upperRowIds, belowRowIds };
|
||||||
}, [metadata]);
|
}, [metadata]);
|
||||||
|
|
||||||
const modifyFilters = useCallback((filters, filterConjunction) => {
|
const modifyFilters = useCallback((filters, filterConjunction, basicFilters) => {
|
||||||
store.modifyFilters(filterConjunction, filters);
|
store.modifyFilters(filterConjunction, filters, basicFilters);
|
||||||
}, [store]);
|
}, [store]);
|
||||||
|
|
||||||
const modifySorts = useCallback((sorts) => {
|
const modifySorts = useCallback((sorts) => {
|
||||||
|
@ -9,11 +9,6 @@ const ViewToolBar = ({ viewId }) => {
|
|||||||
const [view, setView] = useState(null);
|
const [view, setView] = useState(null);
|
||||||
const [collaborators, setCollaborators] = useState([]);
|
const [collaborators, setCollaborators] = useState([]);
|
||||||
|
|
||||||
const availableColumns = useMemo(() => {
|
|
||||||
if (!view) return [];
|
|
||||||
return view.available_columns;
|
|
||||||
}, [view]);
|
|
||||||
|
|
||||||
const viewColumns = useMemo(() => {
|
const viewColumns = useMemo(() => {
|
||||||
if (!view) return [];
|
if (!view) return [];
|
||||||
return view.columns;
|
return view.columns;
|
||||||
@ -23,8 +18,8 @@ const ViewToolBar = ({ viewId }) => {
|
|||||||
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.SELECT_NONE);
|
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.SELECT_NONE);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const modifyFilters = useCallback((filters, filterConjunction) => {
|
const modifyFilters = useCallback((filters, filterConjunction, basicFilters) => {
|
||||||
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.MODIFY_FILTERS, filters, filterConjunction);
|
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.MODIFY_FILTERS, filters, filterConjunction, basicFilters);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const modifySorts = useCallback((sorts) => {
|
const modifySorts = useCallback((sorts) => {
|
||||||
@ -83,8 +78,9 @@ const ViewToolBar = ({ viewId }) => {
|
|||||||
target="sf-metadata-filter-popover"
|
target="sf-metadata-filter-popover"
|
||||||
readOnly={readOnly}
|
readOnly={readOnly}
|
||||||
filterConjunction={view.filter_conjunction}
|
filterConjunction={view.filter_conjunction}
|
||||||
|
basicFilters={view.basic_filters}
|
||||||
filters={view.filters}
|
filters={view.filters}
|
||||||
columns={availableColumns}
|
columns={viewColumns}
|
||||||
modifyFilters={modifyFilters}
|
modifyFilters={modifyFilters}
|
||||||
collaborators={collaborators}
|
collaborators={collaborators}
|
||||||
/>
|
/>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { getColumnByKey, VIEW_NOT_DISPLAY_COLUMN_KEYS } from '../../_basic';
|
import { getColumnByKey, VIEW_NOT_DISPLAY_COLUMN_KEYS, PRIVATE_COLUMN_KEY, FILTER_PREDICATE_TYPE } from '../../_basic';
|
||||||
|
|
||||||
class View {
|
class View {
|
||||||
constructor(object, columns) {
|
constructor(object, columns) {
|
||||||
@ -10,6 +10,8 @@ class View {
|
|||||||
this.filters = object.filters || [];
|
this.filters = object.filters || [];
|
||||||
this.filter_conjunction = object.filter_conjunction || 'Or';
|
this.filter_conjunction = object.filter_conjunction || 'Or';
|
||||||
|
|
||||||
|
this.basic_filters = object.basic_filters && object.basic_filters.length > 0 ? object.basic_filters : [{ column_key: PRIVATE_COLUMN_KEY.IS_DIR, filter_predicate: FILTER_PREDICATE_TYPE.IS, filter_term: 'all' }];
|
||||||
|
|
||||||
// sort
|
// sort
|
||||||
this.sorts = object.sorts || [];
|
this.sorts = object.sorts || [];
|
||||||
|
|
||||||
|
@ -344,12 +344,13 @@ class Store {
|
|||||||
this.applyOperation(operation);
|
this.applyOperation(operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
modifyFilters(filterConjunction, filters) {
|
modifyFilters(filterConjunction, filters, basicFilters = []) {
|
||||||
const type = OPERATION_TYPE.MODIFY_FILTERS;
|
const type = OPERATION_TYPE.MODIFY_FILTERS;
|
||||||
const operation = this.createOperation({
|
const operation = this.createOperation({
|
||||||
type,
|
type,
|
||||||
filter_conjunction: filterConjunction,
|
filter_conjunction: filterConjunction,
|
||||||
filters,
|
filters,
|
||||||
|
basic_filters: basicFilters,
|
||||||
repo_id: this.repoId,
|
repo_id: this.repoId,
|
||||||
view_id: this.viewId,
|
view_id: this.viewId,
|
||||||
success_callback: () => {
|
success_callback: () => {
|
||||||
|
@ -101,9 +101,10 @@ export default function apply(data, operation) {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
case OPERATION_TYPE.MODIFY_FILTERS: {
|
case OPERATION_TYPE.MODIFY_FILTERS: {
|
||||||
const { filter_conjunction, filters } = operation;
|
const { filter_conjunction, filters, basic_filters } = operation;
|
||||||
data.view.filter_conjunction = filter_conjunction;
|
data.view.filter_conjunction = filter_conjunction;
|
||||||
data.view.filters = filters;
|
data.view.filters = filters;
|
||||||
|
data.view.basic_filters = basic_filters;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
case OPERATION_TYPE.MODIFY_SORTS: {
|
case OPERATION_TYPE.MODIFY_SORTS: {
|
||||||
|
@ -24,7 +24,7 @@ export const OPERATION_ATTRIBUTES = {
|
|||||||
[OPERATION_TYPE.MODIFY_RECORDS]: ['repo_id', 'row_ids', 'id_row_updates', 'id_original_row_updates', 'id_old_row_data', 'id_original_old_row_data', 'is_copy_paste', 'id_obj_id'],
|
[OPERATION_TYPE.MODIFY_RECORDS]: ['repo_id', 'row_ids', 'id_row_updates', 'id_original_row_updates', 'id_old_row_data', 'id_original_old_row_data', 'is_copy_paste', 'id_obj_id'],
|
||||||
[OPERATION_TYPE.RESTORE_RECORDS]: ['repo_id', 'rows_data', 'original_rows', 'link_infos', 'upper_row_ids'],
|
[OPERATION_TYPE.RESTORE_RECORDS]: ['repo_id', 'rows_data', 'original_rows', 'link_infos', 'upper_row_ids'],
|
||||||
[OPERATION_TYPE.RELOAD_RECORDS]: ['repo_id', 'row_ids'],
|
[OPERATION_TYPE.RELOAD_RECORDS]: ['repo_id', 'row_ids'],
|
||||||
[OPERATION_TYPE.MODIFY_FILTERS]: ['repo_id', 'view_id', 'filter_conjunction', 'filters'],
|
[OPERATION_TYPE.MODIFY_FILTERS]: ['repo_id', 'view_id', 'filter_conjunction', 'filters', 'basic_filters'],
|
||||||
[OPERATION_TYPE.MODIFY_SORTS]: ['repo_id', 'view_id', 'sorts'],
|
[OPERATION_TYPE.MODIFY_SORTS]: ['repo_id', 'view_id', 'sorts'],
|
||||||
[OPERATION_TYPE.MODIFY_GROUPBYS]: ['repo_id', 'view_id', 'groupbys'],
|
[OPERATION_TYPE.MODIFY_GROUPBYS]: ['repo_id', 'view_id', 'groupbys'],
|
||||||
[OPERATION_TYPE.MODIFY_HIDDEN_COLUMNS]: ['repo_id', 'view_id', 'hidden_columns'],
|
[OPERATION_TYPE.MODIFY_HIDDEN_COLUMNS]: ['repo_id', 'view_id', 'hidden_columns'],
|
||||||
|
@ -107,8 +107,8 @@ class ServerOperator {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPERATION_TYPE.MODIFY_FILTERS: {
|
case OPERATION_TYPE.MODIFY_FILTERS: {
|
||||||
const { repo_id, view_id, filter_conjunction, filters } = operation;
|
const { repo_id, view_id, filter_conjunction, filters, basic_filters } = operation;
|
||||||
window.sfMetadataContext.modifyView(repo_id, view_id, { filters, filter_conjunction }).then(res => {
|
window.sfMetadataContext.modifyView(repo_id, view_id, { filters, filter_conjunction, basic_filters }).then(res => {
|
||||||
callback({ operation });
|
callback({ operation });
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
callback({ error: gettext('Failed to modify filter') });
|
callback({ error: gettext('Failed to modify filter') });
|
||||||
|
Loading…
Reference in New Issue
Block a user