mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-25 14:50:29 +00:00
feat: metadata property sort (#6755)
Co-authored-by: 杨国璇 <ygx@Hello-word.local>
This commit is contained in:
1
frontend/src/assets/icons/sort-ascending.svg
Normal file
1
frontend/src/assets/icons/sort-ascending.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1726034713002" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15456" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M643.2 777.6c28.8 0 57.6 35.2 57.6 73.6S672 928 643.2 928h-108.8c-28.8 0-57.6-35.2-57.6-73.6s25.6-73.6 57.6-73.6h108.8v-3.2zM195.2 131.2c19.2-25.6 48-32 67.2-19.2 6.4 3.2 12.8 12.8 16 19.2l153.6 224c12.8 22.4 9.6 57.6-12.8 73.6-6.4 6.4-19.2 12.8-28.8 12.8H304v403.2c0 38.4-32 67.2-67.2 67.2s-67.2-32-67.2-67.2V441.6H86.4c-25.6 0-51.2-22.4-54.4-51.2v-3.2c0-12.8 3.2-22.4 9.6-28.8l153.6-227.2z m569.6 422.4c32 0 60.8 35.2 60.8 73.6s-28.8 76.8-60.8 76.8h-233.6c-32 0-60.8-35.2-60.8-73.6s28.8-73.6 60.8-73.6h233.6v-3.2z m99.2-224c28.8 0 57.6 35.2 57.6 73.6 0 38.4-25.6 73.6-57.6 73.6H528c-28.8 0-57.6-35.2-57.6-73.6 0-38.4 25.6-73.6 57.6-73.6H864z m67.2-224v6.4c28.8 0 51.2 35.2 51.2 73.6 0 38.4-25.6 70.4-51.2 70.4H524.8c-28.8 0-51.2-35.2-51.2-73.6s25.6-73.6 51.2-73.6h406.4z" p-id="15457"></path></svg>
|
After Width: | Height: | Size: 1.1 KiB |
1
frontend/src/assets/icons/sort-descending.svg
Normal file
1
frontend/src/assets/icons/sort-descending.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1726034718075" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15598" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M643.2 777.6c28.8 0 57.6 35.2 57.6 73.6 0 38.4-25.6 73.6-57.6 73.6h-108.8c-28.8 0-57.6-35.2-57.6-73.6 0-38.4 25.6-73.6 57.6-73.6h108.8zM236.8 92.8c38.4 0 67.2 32 67.2 67.2v425.6h86.4c9.6 0 22.4 3.2 28.8 12.8 25.6 19.2 28.8 51.2 12.8 73.6l-153.6 224c-3.2 6.4-9.6 12.8-16 19.2-22.4 16-51.2 6.4-67.2-19.2l-153.6-224c-6.4-6.4-9.6-19.2-9.6-28.8 0-28.8 25.6-57.6 54.4-57.6h83.2V160c0-38.4 28.8-67.2 67.2-67.2z m528 460.8c32 0 60.8 35.2 60.8 73.6s-28.8 76.8-60.8 76.8h-233.6c-32 0-60.8-35.2-60.8-73.6s28.8-73.6 60.8-73.6h233.6v-3.2z m99.2-224c28.8 0 57.6 35.2 57.6 73.6S892.8 480 864 480H528c-28.8 0-57.6-35.2-57.6-73.6s25.6-73.6 57.6-73.6H864v-3.2z m67.2-224v6.4c28.8 0 51.2 35.2 51.2 73.6S960 256 931.2 256H524.8c-28.8 0-51.2-35.2-51.2-73.6s25.6-73.6 51.2-73.6h406.4z" p-id="15599"></path></svg>
|
After Width: | Height: | Size: 1.1 KiB |
@@ -19,6 +19,13 @@ const SORT_COLUMN_OPTIONS = [
|
|||||||
CellType.RATE,
|
CellType.RATE,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const SHOW_DISABLED_SORT_COLUMNS = [
|
||||||
|
CellType.LONG_TEXT,
|
||||||
|
CellType.GEOLOCATION,
|
||||||
|
CellType.CREATOR,
|
||||||
|
CellType.LAST_MODIFIER,
|
||||||
|
];
|
||||||
|
|
||||||
const GALLERY_SORT_COLUMN_OPTIONS = [
|
const GALLERY_SORT_COLUMN_OPTIONS = [
|
||||||
CellType.CTIME,
|
CellType.CTIME,
|
||||||
CellType.MTIME,
|
CellType.MTIME,
|
||||||
@@ -38,6 +45,7 @@ const NUMBER_SORTER_COLUMN_TYPES = [CellType.NUMBER, CellType.RATE];
|
|||||||
export {
|
export {
|
||||||
SORT_TYPE,
|
SORT_TYPE,
|
||||||
SORT_COLUMN_OPTIONS,
|
SORT_COLUMN_OPTIONS,
|
||||||
|
SHOW_DISABLED_SORT_COLUMNS,
|
||||||
GALLERY_SORT_COLUMN_OPTIONS,
|
GALLERY_SORT_COLUMN_OPTIONS,
|
||||||
GALLERY_FIRST_SORT_COLUMN_OPTIONS,
|
GALLERY_FIRST_SORT_COLUMN_OPTIONS,
|
||||||
TEXT_SORTER_COLUMN_TYPES,
|
TEXT_SORTER_COLUMN_TYPES,
|
||||||
|
@@ -53,7 +53,7 @@ const RateItem = ({
|
|||||||
<Icon iconName={type || 'rate'} />
|
<Icon iconName={type || 'rate'} />
|
||||||
</div>
|
</div>
|
||||||
{enterIndex !== -1 && (
|
{enterIndex !== -1 && (
|
||||||
<UncontrolledTooltip placement='bottom' target={ref} modifiers={{ preventOverflow: { boundariesElement: document.body } }}>
|
<UncontrolledTooltip placement='bottom' target={ref} modifiers={{ preventOverflow: { boundariesElement: document.body } }} className="sf-metadata-tooltip">
|
||||||
{enterIndex}
|
{enterIndex}
|
||||||
</UncontrolledTooltip>
|
</UncontrolledTooltip>
|
||||||
)}
|
)}
|
||||||
|
@@ -1,10 +1,11 @@
|
|||||||
import React, { useCallback, useState, useMemo } from 'react';
|
import React, { useCallback, useState, useMemo, useEffect } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { IconBtn } from '@seafile/sf-metadata-ui-component';
|
import { IconBtn } from '@seafile/sf-metadata-ui-component';
|
||||||
import { getValidSorts, CommonlyUsedHotkey } from '../../_basic';
|
import { getValidSorts, CommonlyUsedHotkey } from '../../_basic';
|
||||||
import { gettext } from '../../utils';
|
import { gettext } from '../../utils';
|
||||||
import { SortPopover } from '../popover';
|
import { SortPopover } from '../popover';
|
||||||
|
import { EVENT_BUS_TYPE } from '../../constants';
|
||||||
|
|
||||||
const SortSetter = ({ target, type, sorts: propsSorts, readOnly, columns, isNeedSubmit, wrapperClass, modifySorts }) => {
|
const SortSetter = ({ target, type, sorts: propsSorts, readOnly, columns, isNeedSubmit, wrapperClass, modifySorts }) => {
|
||||||
const [isShowSetter, setShowSetter] = useState(false);
|
const [isShowSetter, setShowSetter] = useState(false);
|
||||||
@@ -20,6 +21,19 @@ const SortSetter = ({ target, type, sorts: propsSorts, readOnly, columns, isNeed
|
|||||||
return isNeedSubmit ? gettext('Preset sort') : gettext('Sort');
|
return isNeedSubmit ? gettext('Preset sort') : gettext('Sort');
|
||||||
}, [isNeedSubmit, sorts]);
|
}, [isNeedSubmit, sorts]);
|
||||||
|
|
||||||
|
const displaySetter = useCallback(() => {
|
||||||
|
setShowSetter(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const eventBus = window.sfMetadataContext.eventBus;
|
||||||
|
const unsubscribeDisplaySorts = eventBus.subscribe(EVENT_BUS_TYPE.DISPLAY_SORTS, displaySetter);
|
||||||
|
return () => {
|
||||||
|
unsubscribeDisplaySorts();
|
||||||
|
};
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
const onSetterToggle = useCallback(() => {
|
const onSetterToggle = useCallback(() => {
|
||||||
setShowSetter(!isShowSetter);
|
setShowSetter(!isShowSetter);
|
||||||
}, [isShowSetter]);
|
}, [isShowSetter]);
|
||||||
|
@@ -534,6 +534,7 @@ class FilterItem extends React.Component {
|
|||||||
target={this.invalidFilterTip}
|
target={this.invalidFilterTip}
|
||||||
placement='bottom'
|
placement='bottom'
|
||||||
fade={false}
|
fade={false}
|
||||||
|
className="sf-metadata-tooltip"
|
||||||
>
|
>
|
||||||
{gettext('Invalid filter')}
|
{gettext('Invalid filter')}
|
||||||
</UncontrolledTooltip>
|
</UncontrolledTooltip>
|
||||||
@@ -608,7 +609,7 @@ class FilterItem extends React.Component {
|
|||||||
{/* {showToolTip && (
|
{/* {showToolTip && (
|
||||||
<div className="ml-2" >
|
<div className="ml-2" >
|
||||||
<IconBtn id={`filter-tool-tip-${filterColumn.key}`} iconName="exclamation-triangle" />
|
<IconBtn id={`filter-tool-tip-${filterColumn.key}`} iconName="exclamation-triangle" />
|
||||||
<UncontrolledTooltip placement="bottom" target={`filter-tool-tip-${filterColumn.key}`} >
|
<UncontrolledTooltip placement="bottom" target={`filter-tool-tip-${filterColumn.key}`} className="sf-metadata-tooltip">
|
||||||
{gettext('If there are multiple items in the cell, a random one will be chosen and be compared with the filter value.')}
|
{gettext('If there are multiple items in the cell, a random one will be chosen and be compared with the filter value.')}
|
||||||
</UncontrolledTooltip>
|
</UncontrolledTooltip>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -84,7 +84,7 @@ export default class OptionFooter extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<div className='option-editor-footer'>
|
<div className='option-editor-footer'>
|
||||||
<span aria-hidden="true" className="sf3-font-help sf3-font option-editor-tips" id="edit-option-tip"></span>
|
<span aria-hidden="true" className="sf3-font-help sf3-font option-editor-tips" id="edit-option-tip"></span>
|
||||||
<UncontrolledTooltip delay={{ show: 0, hide: 0 }} target={'edit-option-tip'} placement='bottom'>
|
<UncontrolledTooltip delay={{ show: 0, hide: 0 }} target="edit-option-tip" placement="bottom" className="sf-metadata-tooltip">
|
||||||
{gettext('Use the import/export function to transfer options quickly. (The export is in JSON format.) By pasting cells, copied from a text column, an Excel or a TXT file, you can also add options quickly.')}
|
{gettext('Use the import/export function to transfer options quickly. (The export is in JSON format.) By pasting cells, copied from a text column, an Excel or a TXT file, you can also add options quickly.')}
|
||||||
</UncontrolledTooltip>
|
</UncontrolledTooltip>
|
||||||
<input
|
<input
|
||||||
|
@@ -204,13 +204,33 @@
|
|||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-inner {
|
.sf-metadata-tooltip .tooltip-inner {
|
||||||
max-width: 242px;
|
max-width: 242px;
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
text-align: start;
|
text-align: start;
|
||||||
background-color: #303133;
|
background-color: #303133;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sf-metadata-tooltip .bs-tooltip-right .arrow::before,
|
||||||
|
.sf-metadata-tooltip .bs-tooltip-auto[x-placement^="right"] .arrow::before {
|
||||||
|
border-right-color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sf-metadata-tooltip .bs-tooltip-top .arrow::before,
|
||||||
|
.sf-metadata-tooltip .bs-tooltip-auto[x-placement^="top"] .arrow::before {
|
||||||
|
border-top-color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sf-metadata-tooltip .bs-tooltip-bottom .arrow::before,
|
||||||
|
.sf-metadata-tooltip .bs-tooltip-auto[x-placement^="bottom"] .arrow::before {
|
||||||
|
border-bottom-color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sf-metadata-tooltip .bs-tooltip-left .arrow::before,
|
||||||
|
.sf-metadata-tooltip .bs-tooltip-auto[x-placement^="left"] .arrow::before {
|
||||||
|
border-left-color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
/* records count */
|
/* records count */
|
||||||
.sf-metadata-result.success .sf-metadata-result-footer {
|
.sf-metadata-result.success .sf-metadata-result-footer {
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
@@ -28,6 +28,7 @@ const CellOperationBtn = ({ isDir, column, value }) => {
|
|||||||
fade={false}
|
fade={false}
|
||||||
delay={{ show: 0, hide: 0 }}
|
delay={{ show: 0, hide: 0 }}
|
||||||
modifiers={{ preventOverflow: { boundariesElement: document.body } }}
|
modifiers={{ preventOverflow: { boundariesElement: document.body } }}
|
||||||
|
className="sf-metadata-tooltip"
|
||||||
>
|
>
|
||||||
{isDir ? gettext('Open folder') : gettext('Open file')}
|
{isDir ? gettext('Open folder') : gettext('Open file')}
|
||||||
</UncontrolledTooltip>
|
</UncontrolledTooltip>
|
||||||
|
@@ -41,7 +41,7 @@ const ColumnDropdownItem = ({ disabled, iconName, target, title, tip, className,
|
|||||||
<Icon iconName={iconName} />
|
<Icon iconName={iconName} />
|
||||||
<span className="item-text">{title}</span>
|
<span className="item-text">{title}</span>
|
||||||
{isShowToolTip && (
|
{isShowToolTip && (
|
||||||
<UncontrolledTooltip placement="right" target={target} fade={false} delay={{ show: 0, hide: 0 }}>
|
<UncontrolledTooltip placement="right" target={target} fade={false} delay={{ show: 0, hide: 0 }} className="sf-metadata-tooltip">
|
||||||
{tip}
|
{tip}
|
||||||
</UncontrolledTooltip>
|
</UncontrolledTooltip>
|
||||||
)}
|
)}
|
||||||
|
@@ -5,12 +5,15 @@ import classnames from 'classnames';
|
|||||||
import { ModalPortal, Icon } from '@seafile/sf-metadata-ui-component';
|
import { ModalPortal, Icon } from '@seafile/sf-metadata-ui-component';
|
||||||
import { isMobile, gettext } from '../../../../../../../../utils';
|
import { isMobile, gettext } from '../../../../../../../../utils';
|
||||||
import DropdownItem from './dropdown-item';
|
import DropdownItem from './dropdown-item';
|
||||||
import { CellType, DEFAULT_DATE_FORMAT, getDateDisplayString } from '../../../../../../../../_basic';
|
import { CellType, DEFAULT_DATE_FORMAT, SORT_COLUMN_OPTIONS, SHOW_DISABLED_SORT_COLUMNS, SORT_TYPE,
|
||||||
|
getDateDisplayString
|
||||||
|
} from '../../../../../../../../_basic';
|
||||||
import { RenamePopover, OptionsPopover } from '../../../../../../../popover';
|
import { RenamePopover, OptionsPopover } from '../../../../../../../popover';
|
||||||
|
import { EVENT_BUS_TYPE } from '../../../../../../../../constants';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
const HeaderDropdownMenu = ({ column, renameColumn, modifyColumnData, deleteColumn }) => {
|
const HeaderDropdownMenu = ({ column, view, renameColumn, modifyColumnData, deleteColumn }) => {
|
||||||
const menuRef = createRef();
|
const menuRef = createRef();
|
||||||
const dropdownDomRef = createRef();
|
const dropdownDomRef = createRef();
|
||||||
const [isMenuShow, setMenuShow] = useState(false);
|
const [isMenuShow, setMenuShow] = useState(false);
|
||||||
@@ -153,11 +156,38 @@ const HeaderDropdownMenu = ({ column, renameColumn, modifyColumnData, deleteColu
|
|||||||
);
|
);
|
||||||
}, [today, column, isMenuShow, isSubMenuShow, onChangeDateFormat, openSubMenu]);
|
}, [today, column, isMenuShow, isSubMenuShow, onChangeDateFormat, openSubMenu]);
|
||||||
|
|
||||||
|
const modifySort = useCallback((type, event) => {
|
||||||
|
const canModifyView = window.sfMetadataContext.canModifyView();
|
||||||
|
if (!canModifyView) {
|
||||||
|
event.stopPropagation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const sorts = view.sorts.slice(0);
|
||||||
|
const { key } = column;
|
||||||
|
const sortIndex = sorts.findIndex(sort => sort.column_key === key);
|
||||||
|
const sort = sorts[sortIndex];
|
||||||
|
const newSort = { column_key: column.key, sort_type: type };
|
||||||
|
const eventBus = window.sfMetadataContext.eventBus;
|
||||||
|
if (!sort) {
|
||||||
|
sorts.push(newSort);
|
||||||
|
eventBus.dispatch(EVENT_BUS_TYPE.MODIFY_SORTS, sorts, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sort && sort.sort_type !== type) {
|
||||||
|
sorts.splice(sortIndex, 1, newSort);
|
||||||
|
eventBus.dispatch(EVENT_BUS_TYPE.MODIFY_SORTS, sorts, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eventBus.dispatch(EVENT_BUS_TYPE.DISPLAY_SORTS);
|
||||||
|
}, [view, column]);
|
||||||
|
|
||||||
const renderDropdownMenu = useCallback(() => {
|
const renderDropdownMenu = useCallback(() => {
|
||||||
const { type } = column;
|
const { type } = column;
|
||||||
const canModifyColumnData = window.sfMetadataContext.canModifyColumnData(column);
|
const canModifyColumnData = window.sfMetadataContext.canModifyColumnData(column);
|
||||||
const canDeleteColumn = window.sfMetadataContext.canDeleteColumn(column);
|
const canDeleteColumn = window.sfMetadataContext.canDeleteColumn(column);
|
||||||
const canRenameColumn = window.sfMetadataContext.canRenameColumn(column);
|
const canRenameColumn = window.sfMetadataContext.canRenameColumn(column);
|
||||||
|
const canModifyView = window.sfMetadataContext.canModifyView();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu ref={menuRef} className="sf-metadata-column-dropdown-menu">
|
<DropdownMenu ref={menuRef} className="sf-metadata-column-dropdown-menu">
|
||||||
<div ref={dropdownDomRef}>
|
<div ref={dropdownDomRef}>
|
||||||
@@ -216,6 +246,28 @@ const HeaderDropdownMenu = ({ column, renameColumn, modifyColumnData, deleteColu
|
|||||||
onChange={openRenamePopover}
|
onChange={openRenamePopover}
|
||||||
onMouseEnter={hideSubMenu}
|
onMouseEnter={hideSubMenu}
|
||||||
/>
|
/>
|
||||||
|
{(SORT_COLUMN_OPTIONS.includes(column.type) || SHOW_DISABLED_SORT_COLUMNS.includes(column.type)) && (
|
||||||
|
<>
|
||||||
|
<DropdownItem
|
||||||
|
disabled={!canModifyView || SHOW_DISABLED_SORT_COLUMNS.includes(column.type)}
|
||||||
|
target="sf-metadata-sort-ascending-column"
|
||||||
|
iconName="sort-ascending"
|
||||||
|
title={gettext('Sort ascending')}
|
||||||
|
tip={!canModifyView ? gettext('You do not have permission') : gettext('This property does not support sorting')}
|
||||||
|
onChange={() => modifySort(SORT_TYPE.UP)}
|
||||||
|
onMouseEnter={hideSubMenu}
|
||||||
|
/>
|
||||||
|
<DropdownItem
|
||||||
|
disabled={!canModifyView || SHOW_DISABLED_SORT_COLUMNS.includes(column.type)}
|
||||||
|
target="sf-metadata-sort-descending-column"
|
||||||
|
iconName="sort-descending"
|
||||||
|
title={gettext('Sort descending')}
|
||||||
|
tip={!canModifyView ? gettext('You do not have permission') : gettext('This property does not support sorting')}
|
||||||
|
onChange={() => modifySort(SORT_TYPE.DOWN)}
|
||||||
|
onMouseEnter={hideSubMenu}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
disabled={!canDeleteColumn}
|
disabled={!canDeleteColumn}
|
||||||
target="sf-metadata-delete-column"
|
target="sf-metadata-delete-column"
|
||||||
@@ -228,7 +280,7 @@ const HeaderDropdownMenu = ({ column, renameColumn, modifyColumnData, deleteColu
|
|||||||
</div>
|
</div>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
);
|
);
|
||||||
}, [column, openRenamePopover, hideSubMenu, renderDateFormat, openOptionPopover, menuRef, dropdownDomRef, onDelete]);
|
}, [column, openRenamePopover, hideSubMenu, renderDateFormat, openOptionPopover, menuRef, dropdownDomRef, modifySort, onDelete]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@@ -89,6 +89,7 @@ const Cell = ({
|
|||||||
isHideTriangle,
|
isHideTriangle,
|
||||||
column,
|
column,
|
||||||
style: propsStyle,
|
style: propsStyle,
|
||||||
|
view,
|
||||||
renameColumn,
|
renameColumn,
|
||||||
deleteColumn,
|
deleteColumn,
|
||||||
modifyColumnData,
|
modifyColumnData,
|
||||||
@@ -99,8 +100,8 @@ const Cell = ({
|
|||||||
|
|
||||||
const canEditColumnInfo = useMemo(() => {
|
const canEditColumnInfo = useMemo(() => {
|
||||||
if (isHideTriangle) return false;
|
if (isHideTriangle) return false;
|
||||||
return window.sfMetadataContext.canModifyColumn(column);
|
return window.sfMetadataContext.canModify();
|
||||||
}, [isHideTriangle, column]);
|
}, [isHideTriangle]);
|
||||||
|
|
||||||
const style = useMemo(() => {
|
const style = useMemo(() => {
|
||||||
const { left, width } = column;
|
const { left, width } = column;
|
||||||
@@ -159,7 +160,7 @@ const Cell = ({
|
|||||||
<span className="mr-2" id={`header-icon-${key}`}>
|
<span className="mr-2" id={`header-icon-${key}`}>
|
||||||
<Icon iconName={COLUMNS_ICON_CONFIG[type]} className="sf-metadata-column-icon" />
|
<Icon iconName={COLUMNS_ICON_CONFIG[type]} className="sf-metadata-column-icon" />
|
||||||
</span>
|
</span>
|
||||||
<UncontrolledTooltip placement="bottom" target={`header-icon-${key}`} fade={false} trigger="hover">
|
<UncontrolledTooltip placement="bottom" target={`header-icon-${key}`} fade={false} trigger="hover" className="sf-metadata-tooltip">
|
||||||
{gettext(headerIconTooltip)}
|
{gettext(headerIconTooltip)}
|
||||||
</UncontrolledTooltip>
|
</UncontrolledTooltip>
|
||||||
<div className="header-name d-flex">
|
<div className="header-name d-flex">
|
||||||
@@ -169,6 +170,7 @@ const Cell = ({
|
|||||||
{canEditColumnInfo && (
|
{canEditColumnInfo && (
|
||||||
<DropdownMenu
|
<DropdownMenu
|
||||||
column={column}
|
column={column}
|
||||||
|
view={view}
|
||||||
renameColumn={renameColumn}
|
renameColumn={renameColumn}
|
||||||
deleteColumn={deleteColumn}
|
deleteColumn={deleteColumn}
|
||||||
modifyColumnData={modifyColumnData}
|
modifyColumnData={modifyColumnData}
|
||||||
@@ -213,6 +215,7 @@ Cell.propTypes = {
|
|||||||
frozen: PropTypes.bool,
|
frozen: PropTypes.bool,
|
||||||
isLastFrozenCell: PropTypes.bool,
|
isLastFrozenCell: PropTypes.bool,
|
||||||
isHideTriangle: PropTypes.bool,
|
isHideTriangle: PropTypes.bool,
|
||||||
|
view: PropTypes.object,
|
||||||
renameColumn: PropTypes.func,
|
renameColumn: PropTypes.func,
|
||||||
deleteColumn: PropTypes.func,
|
deleteColumn: PropTypes.func,
|
||||||
modifyColumnData: PropTypes.func,
|
modifyColumnData: PropTypes.func,
|
||||||
|
@@ -114,6 +114,7 @@ const RecordsHeader = ({
|
|||||||
isLastFrozenCell={isLastFrozenCell}
|
isLastFrozenCell={isLastFrozenCell}
|
||||||
frozenColumnsWidth={frozenColumnsWidth}
|
frozenColumnsWidth={frozenColumnsWidth}
|
||||||
isHideTriangle={isHideTriangle}
|
isHideTriangle={isHideTriangle}
|
||||||
|
view={table.view}
|
||||||
modifyLocalColumnWidth={modifyLocalColumnWidth}
|
modifyLocalColumnWidth={modifyLocalColumnWidth}
|
||||||
modifyColumnWidth={modifyColumnWidth}
|
modifyColumnWidth={modifyColumnWidth}
|
||||||
onMove={modifyColumnOrder}
|
onMove={modifyColumnOrder}
|
||||||
@@ -131,6 +132,7 @@ const RecordsHeader = ({
|
|||||||
groupOffsetLeft={groupOffsetLeft}
|
groupOffsetLeft={groupOffsetLeft}
|
||||||
height={height}
|
height={height}
|
||||||
column={column}
|
column={column}
|
||||||
|
view={table.view}
|
||||||
frozenColumnsWidth={frozenColumnsWidth}
|
frozenColumnsWidth={frozenColumnsWidth}
|
||||||
modifyLocalColumnWidth={modifyLocalColumnWidth}
|
modifyLocalColumnWidth={modifyLocalColumnWidth}
|
||||||
modifyColumnWidth={modifyColumnWidth}
|
modifyColumnWidth={modifyColumnWidth}
|
||||||
|
@@ -38,6 +38,7 @@ export const EVENT_BUS_TYPE = {
|
|||||||
MODIFY_SORTS: 'modify_sorts',
|
MODIFY_SORTS: 'modify_sorts',
|
||||||
MODIFY_GROUPBYS: 'modify_groupbys',
|
MODIFY_GROUPBYS: 'modify_groupbys',
|
||||||
MODIFY_HIDDEN_COLUMNS: 'modify_hidden_columns',
|
MODIFY_HIDDEN_COLUMNS: 'modify_hidden_columns',
|
||||||
|
DISPLAY_SORTS: 'display_sorts',
|
||||||
|
|
||||||
// change
|
// change
|
||||||
VIEW_CHANGED: 'view_changed',
|
VIEW_CHANGED: 'view_changed',
|
||||||
|
@@ -92,6 +92,11 @@ class Context {
|
|||||||
return this.permission;
|
return this.permission;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
canModify = () => {
|
||||||
|
if (this.permission === 'r') return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
canModifyRow = (row) => {
|
canModifyRow = (row) => {
|
||||||
if (this.permission === 'r') return false;
|
if (this.permission === 'r') return false;
|
||||||
return true;
|
return true;
|
||||||
|
@@ -49,8 +49,8 @@ export const MetadataProvider = ({
|
|||||||
window.sfMetadataStore.modifyFilters(filterConjunction, filters, basicFilters);
|
window.sfMetadataStore.modifyFilters(filterConjunction, filters, basicFilters);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const modifySorts = useCallback((sorts) => {
|
const modifySorts = useCallback((sorts, displaySorts = false) => {
|
||||||
window.sfMetadataStore.modifySorts(sorts);
|
window.sfMetadataStore.modifySorts(sorts, displaySorts);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const modifyGroupbys = useCallback((groupbys) => {
|
const modifyGroupbys = useCallback((groupbys) => {
|
||||||
|
@@ -360,7 +360,7 @@ class Store {
|
|||||||
this.applyOperation(operation);
|
this.applyOperation(operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
modifySorts(sorts) {
|
modifySorts(sorts, displaySorts = false) {
|
||||||
const type = OPERATION_TYPE.MODIFY_SORTS;
|
const type = OPERATION_TYPE.MODIFY_SORTS;
|
||||||
const operation = this.createOperation({
|
const operation = this.createOperation({
|
||||||
type,
|
type,
|
||||||
@@ -369,6 +369,7 @@ class Store {
|
|||||||
view_id: this.viewId,
|
view_id: this.viewId,
|
||||||
success_callback: () => {
|
success_callback: () => {
|
||||||
this.context.eventBus.dispatch(EVENT_BUS_TYPE.RELOAD_DATA);
|
this.context.eventBus.dispatch(EVENT_BUS_TYPE.RELOAD_DATA);
|
||||||
|
displaySorts && this.context.eventBus.dispatch(EVENT_BUS_TYPE.DISPLAY_SORTS);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.applyOperation(operation);
|
this.applyOperation(operation);
|
||||||
|
Reference in New Issue
Block a user