1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-07 01:41:39 +00:00

refactor: metadata view (#6322)

* refactor: metadata view

* feat: update code

* feat: update code

* feat: update code

---------

Co-authored-by: 杨国璇 <ygx@Hello-word.local>
This commit is contained in:
杨国璇
2024-07-10 18:18:57 +08:00
committed by GitHub
parent 98b818b26e
commit 4d3f8a6df5
21 changed files with 224 additions and 156 deletions

View 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="1720504436505" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6548" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M80.91936 102.4l156.8 124.8C311.31936 169.6 400.91936 128 512.91936 128c134.4 0 243.2 64 320 137.6 76.8 73.6 131.2 163.2 153.6 224 6.4 12.8 6.4 28.8 0 41.6-22.4 51.2-64 124.8-124.8 192l140.8 112c19.2 16 22.4 44.8 6.4 67.2-16 19.2-48 22.4-67.2 6.4l-928-736C-2.28064 160-5.48064 128 10.51936 108.8s48-22.4 70.4-6.4z m32 256L186.51936 416C160.91936 454.4 141.71936 486.4 128.91936 515.2c22.4 51.2 64 121.6 128 179.2 67.2 64 153.6 112 256 112 44.8 0 86.4-9.6 124.8-22.4l76.8 64c-57.6 32-124.8 51.2-201.6 51.2-134.4 0-243.2-64-320-137.6-76.8-73.6-131.2-163.2-153.6-224-6.4-12.8-6.4-28.8 0-41.6 12.8-41.6 38.4-89.6 73.6-137.6z m185.6 150.4l112 89.6c12.8 16 25.6 25.6 44.8 35.2l112 89.6c-16 3.2-35.2 6.4-51.2 6.4-121.6 3.2-217.6-96-217.6-220.8zM512.91936 224c-76.8 0-144 25.6-198.4 64l67.2 51.2c35.2-28.8 80-48 131.2-48 118.4 0 214.4 99.2 214.4 220.8 0 32-6.4 60.8-19.2 89.6l86.4 70.4c48-54.4 83.2-112 102.4-153.6-22.4-51.2-64-121.6-128-179.2C704.91936 272 618.51936 224 512.91936 224z m0 150.4h-3.2c3.2 9.6 3.2 19.2 3.2 28.8 0 12.8-3.2 25.6-6.4 38.4l134.4 108.8c3.2-12.8 3.2-22.4 3.2-35.2 3.2-80-57.6-140.8-131.2-140.8z" p-id="6549"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1 +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="1718866549156" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16805" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M985.6 704h-236.8c-22.4 0-38.4-32-38.4-70.4 0-38.4 19.2-70.4 38.4-70.4h236.8c22.4 0 38.4 32 38.4 70.4 0 38.4-19.2 70.4-38.4 70.4z m0-230.4h-236.8c-22.4 0-38.4-32-38.4-70.4s19.2-70.4 38.4-70.4h236.8c22.4 0 38.4 32 38.4 70.4s-19.2 70.4-38.4 70.4z m-211.2-243.2L556.8 480v348.8L384 944c-38.4 22.4-86.4 9.6-108.8-28.8-6.4-9.6-9.6-25.6-9.6-38.4V476.8L22.4 230.4c-28.8-32-28.8-83.2 3.2-115.2 12.8-12.8 35.2-19.2 51.2-19.2h636.8c41.6 0 76.8 35.2 76.8 80 6.4 19.2 0 38.4-16 54.4z m-409.6 192c9.6 9.6 12.8 22.4 12.8 32V800l57.6-38.4v-304c0-9.6 3.2-22.4 12.8-28.8l195.2-227.2H166.4l198.4 220.8z m320 374.4h288c25.6 0 48 32 48 70.4 0 38.4-22.4 70.4-48 70.4h-288c-25.6 0-48-32-48-70.4 0-38.4 22.4-70.4 48-70.4z" p-id="16806"></path></svg>
<?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="1720504407707" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6260" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M617.6 736c28.8 0 54.4 22.4 54.4 48s-22.4 48-54.4 48h-214.4c-28.8 0-54.4-22.4-54.4-48s22.4-48 54.4-48h214.4z m169.6-272c25.6 0 44.8 22.4 44.8 48s-19.2 48-44.8 48H236.8c-25.6 0-44.8-22.4-44.8-48s19.2-48 44.8-48h550.4z m236.8-224c0 25.6-22.4 48-48 48h-928C22.4 288 0 265.6 0 240S22.4 192 48 192h931.2c22.4 0 44.8 22.4 44.8 48z" p-id="6261"></path></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 684 B

View File

@@ -1 +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="1718866570524" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16947" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M98.272 34.272h832c35.2 0 64 28.8 64 64v832c0 35.2-28.8 64-64 64h-832c-35.2 0-64-28.8-64-64v-832c0-35.2 28.8-64 64-64z m128 128c-35.2 0-64 28.8-64 64v576c0 35.2 28.8 64 64 64h576c35.2 0 64-28.8 64-64v-576c0-35.2-28.8-64-64-64h-576z" p-id="16948"></path><path d="M312.672 293.472c44.8 0 80 35.2 80 80s-35.2 80-80 80-80-35.2-80-80 35.2-80 80-80zM312.672 562.272c44.8 0 80 35.2 80 80s-35.2 80-80 80-80-35.2-80-80 35.2-80 80-80zM549.472 293.472h160c44.8 0 80 35.2 80 80s-35.2 80-80 80h-160c-44.8 0-80-35.2-80-80s38.4-80 80-80zM549.472 562.272h160c44.8 0 80 35.2 80 80s-35.2 80-80 80h-160c-44.8 0-80-35.2-80-80s38.4-80 80-80z" fill="#949494" p-id="16949"></path></svg>
<?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="1720504411375" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6402" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M928 64c35.2 0 64 28.8 64 64v768c0 35.2-28.8 64-64 64H96c-35.2 0-64-28.8-64-64V128c0-35.2 28.8-64 64-64h832z m-32 96H128v704h768V160z" p-id="6403"></path><path d="M304 368m-80 0a80 80 0 1 0 160 0 80 80 0 1 0-160 0Z" p-id="6404"></path><path d="M496 320h256c25.6 0 48 22.4 48 48S777.6 416 752 416h-256C470.4 416 448 393.6 448 368S470.4 320 496 320z" p-id="6405"></path><path d="M304 656m-80 0a80 80 0 1 0 160 0 80 80 0 1 0-160 0Z" p-id="6406"></path><path d="M496 608h256c25.6 0 48 22.4 48 48S777.6 704 752 704h-256C470.4 704 448 681.6 448 656S470.4 608 496 608z" p-id="6407"></path></svg>

Before

Width:  |  Height:  |  Size: 997 B

After

Width:  |  Height:  |  Size: 921 B

View File

@@ -1 +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="1718865263224" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16094" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M812.8 483.2v428.8c0 25.6-22.4 48-48 48h-83.2c-25.6 0-48-22.4-48-48V483.2h-118.4C608 243.2 678.4 124.8 723.2 124.8s115.2 118.4 208 358.4h-118.4z m-419.2 57.6H512c-89.6 240-160 358.4-208 358.4S185.6 780.8 96 540.8h118.4V112c0-25.6 22.4-48 48-48h83.2c25.6 0 48 22.4 48 48v428.8z" p-id="16095"></path></svg>
<?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="1720576644983" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6118" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M294.4 105.6l201.6 204.8c19.2 19.2 19.2 51.2 0 73.6-19.2 19.2-51.2 19.2-70.4 0L320 275.2v604.8c0 25.6-22.4 48-48 48S224 905.6 224 880V275.2L118.4 384c-19.2 19.2-48 19.2-67.2 3.2l-3.2-3.2c-19.2-19.2-19.2-51.2 0-73.6l201.6-204.8c12.8-12.8 32-12.8 44.8 0zM752 96c25.6 0 48 22.4 48 48v604.8l105.6-108.8c19.2-19.2 51.2-19.2 70.4 0 19.2 19.2 19.2 51.2 0 73.6l-201.6 204.8c-12.8 12.8-32 12.8-44.8 0l-201.6-204.8c-19.2-19.2-19.2-51.2 0-73.6l3.2-3.2c19.2-16 48-16 67.2 3.2l105.6 108.8V144c0-25.6 22.4-48 48-48z" p-id="6119"></path></svg>

Before

Width:  |  Height:  |  Size: 639 B

After

Width:  |  Height:  |  Size: 861 B

View File

@@ -8,6 +8,7 @@ import SeahubPopover from '../common/seahub-popover';
import ListTagPopover from '../popover/list-tag-popover';
import ViewModes from '../../components/view-modes';
import { PRIVATE_FILE_TYPE } from '../../constants';
import MetadataViewToolBar from '../../metadata/metadata-view/components/view-toolbar';
const propTypes = {
repoID: PropTypes.string.isRequired,
@@ -83,11 +84,20 @@ class DirTool extends React.Component {
const { repoID, currentMode, currentPath } = this.props;
const propertiesText = TextTranslation.PROPERTIES.value;
const isFileExtended = currentPath === '/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES;
if (isFileExtended) {
return (
<div className="d-flex">
<MetadataViewToolBar />
</div>
);
}
return (
<React.Fragment>
<div className="d-flex">
<ViewModes currentViewMode={currentMode} switchViewMode={this.props.switchViewMode} />
{(!this.props.isCustomPermission && !isFileExtended) &&
{(!this.props.isCustomPermission) &&
<span className="cur-view-path-btn ml-2" onClick={() => this.props.switchViewMode('detail')}>
<span className="sf3-font sf3-font-info" aria-label={propertiesText} title={propertiesText}></span>
</span>

View File

@@ -1,15 +0,0 @@
.dir-column-file {
padding-right: 10px;
padding-left: 10px;
flex-direction: column;
align-items: center;
}
.dir-column-file .dir-column-file-top {
width: 100%;
height: 10px;
z-index: 7;
transform: translateZ(1000px);
position: relative;
background: #ffffff;
}

View File

@@ -5,8 +5,6 @@ import { Utils } from '../../utils/utils';
import { gettext, siteRoot, lang, mediaUrl } from '../../utils/constants';
import SeafileMarkdownViewer from '../seafile-markdown-viewer';
import './dir-column-file.css';
const propTypes = {
path: PropTypes.string.isRequired,
repoID: PropTypes.string.isRequired,
@@ -60,12 +58,7 @@ class DirColumnFile extends React.Component {
mediaUrl,
};
return (
<div className="dir-column-file w-100 h-100 o-hidden d-flex">
<div className="dir-column-file-top"></div>
<SeafileMetadata repoID={this.props.repoID} currentRepoInfo={this.props.currentRepoInfo} />
</div>
);
return (<SeafileMetadata repoID={this.props.repoID} currentRepoInfo={this.props.currentRepoInfo} />);
}
return (

View File

@@ -43,7 +43,7 @@ const MetadataTreeView = ({ repoID, currentPath, onNodeClick }) => {
return (
<div className="tree-view tree metadata-tree-view">
<div className="tree-node">
<div className="children" style={{ paddingLeft: 20 }}>
<div className="children">
<div
className={classnames('tree-node-inner text-nowrap', { 'tree-node-inner-hover': highlight, 'tree-node-hight-light': currentPath === node.path })}
title={gettext('File extended properties')}

View File

@@ -1,5 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { Icon } from '@seafile/sf-metadata-ui-component';
import { CommonlyUsedHotkey } from '../../_basic';
import { gettext } from '../../utils';
@@ -37,9 +38,9 @@ class HideColumnSetter extends Component {
return (
<>
<div className={`setting-item ${labelClass ? '' : 'mb-1'}`}>
<div className={classnames('setting-item', { 'mb-1': !labelClass })}>
<div
className={`mr-2 setting-item-btn filters-setting-btn ${labelClass}`}
className={classnames('setting-item-btn filters-setting-btn', labelClass) }
onClick={this.onHideColumnToggle}
role="button"
onKeyDown={this.onKeyDown}

View File

@@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
import { Z_INDEX } from '../../_basic';
const propTypes = {
table: PropTypes.object.isRequired,
onScrollbarScroll: PropTypes.func.isRequired,
onScrollbarMouseUp: PropTypes.func.isRequired,
};
@@ -53,10 +52,10 @@ class RightScrollbar extends React.Component {
style.zIndex = Z_INDEX.SCROLL_BAR;
}
/* sf-metadata-footer have 30px height */
style.bottom = 30;
/* sf-metadata-wrapper have 10px margin */
style.right = '10px';
/* sf-metadata-header have 33px height */
style.top = 33;
/* sf-metadata-wrapper have 0px margin */
style.right = 0;
return style;
};

View File

@@ -4,7 +4,6 @@ import { EVENT_BUS_TYPE } from '../../constants';
import { CommonlyUsedHotkey } from '../../_basic';
import { gettext } from '../../utils';
import { useMetadata } from '../../hooks';
import TableTool from './table-tool';
import TableMain from './table-main';
import RecordDetailsDialog from '../record-details-dialog';
import { PER_LOAD_NUMBER, MAX_LOAD_NUMBER } from '../../constants';
@@ -108,12 +107,10 @@ const Container = () => {
const modifyFilters = useCallback((filters, filterConjunction) => {
store.modifyFilters(filterConjunction, filters);
store.saveView();
}, [store]);
const modifySorts = useCallback((sorts) => {
store.modifySorts(sorts);
store.saveView();
}, [store]);
const modifyGroupbys = useCallback(() => {
@@ -154,9 +151,17 @@ const Container = () => {
useEffect(() => {
document.addEventListener('keydown', onKeyDown);
const unsubscribeSelectCell = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.SELECT_CELL, onSelectCell);
const unsubscribeModifyFilters = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_FILTERS, modifyFilters);
const unsubscribeModifySorts = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_SORTS, modifySorts);
const unsubscribeModifyGroupbys = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_GROUPBYS, modifyGroupbys);
const unsubscribeModifyHiddenColumns = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_HIDDEN_COLUMNS, modifyHiddenColumns);
return () => {
document.removeEventListener('keydown', onKeyDown);
unsubscribeSelectCell();
unsubscribeModifyFilters();
unsubscribeModifySorts();
unsubscribeModifyGroupbys();
unsubscribeModifyHiddenColumns();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
@@ -164,7 +169,6 @@ const Container = () => {
return (
<>
<div className="sf-metadata-wrapper">
<TableTool view={metadata.view} modifyFilters={modifyFilters} modifySorts={modifySorts} modifyGroupbys={modifyGroupbys} modifyHiddenColumns={modifyHiddenColumns} />
<div className="sf-metadata-main">
{errorMsg && (<div className="d-center-middle error">{gettext(errorMsg)}</div>)}
{!errorMsg && (
@@ -188,9 +192,7 @@ const Container = () => {
</div>
<RecordDetailsDialog />
</>
);
};
export default Container;

View File

@@ -16,15 +16,6 @@
align-items: center;
}
.sf-metadata-wrapper .seatable-app-header.searcher-active .table-right-operations {
width: 100%;
margin-right: 10px;
}
.sf-metadata-wrapper .seatable-app-header .table-left-operations .setting-item {
margin-right: 0 !important;
}
.sf-metadata-wrapper .table-left-operations .custom-filter-label {
padding: 0 0.5rem;
}
@@ -186,7 +177,6 @@
}
.sf-metadata-result-container {
flex: 1;
overflow-x: scroll;
overflow-y: hidden;
}
@@ -299,6 +289,11 @@
background-color: #fff;
}
.sf-metadata-result-table-content .sf-metadata-result-table-row.sf-metadata-last-table-row {
height: 32px !important;
border-bottom: none;
}
.sf-metadata-result-table-cell.index {
width: 90px;
height: 100%;
@@ -361,7 +356,7 @@
.sf-metadata-result-column-content .header-name-text.double {
white-space: normal;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
@@ -394,7 +389,6 @@
flex: 1 1;
position: relative;
overflow-y: scroll;
padding-bottom: 150px;
}
.sf-metadata-result-table-content .sf-metadata-result-loading {
@@ -409,18 +403,6 @@
align-items: flex-start;
}
.sf-metadata-result-footer {
position: relative;
height: 30px;
width: 100%;
overflow: hidden;
line-height: 30px;
background-color: #f9f9f9;
border-top: 1px solid #ddd;
display: flex;
flex-shrink: 0;
}
.sf-metadata-result-table-cell .cell-file-add {
height: 31px;
line-height: 31px;
@@ -975,12 +957,6 @@
max-width: 250px;
}
.sf-metadata-wrapper .sf-metadata-main,
.sf-metadata-wrapper .seatable-app-header {
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
}
.sf-metadata-wrapper .sf-metadata-main {
flex: 1;
overflow: hidden;

View File

@@ -1,3 +1,20 @@
.sf-metadata-result-footer {
position: relative;
height: 32px;
width: 100%;
overflow: hidden;
line-height: 32px;
background-color: #f9f9f9;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
display: flex;
flex-shrink: 0;
}
.sf-metadata-result-footer.at-border {
border-bottom: none;
}
.sf-metadata-result-footer .rows-record {
width: 80px;
padding-left: 8px;

View File

@@ -8,11 +8,42 @@ import RecordMetrics from '../../../../../utils/record-metrics';
import { SEQUENCE_COLUMN_WIDTH, CANVAS_RIGHT_INTERVAL } from '../../../../../constants';
import { getRecordsFromSelectedRange } from '../../../../../utils/selected-cell-utils';
import { gettext } from '../../../../../../../utils/constants';
import { addClassName, removeClassName } from '../../../../../utils';
import './index.css';
class RecordsFooter extends React.Component {
ref = null;
componentDidMount() {
window.addEventListener('resize', this.calculateAtBorder);
}
componentWillUnmount() {
window.removeEventListener('resize', this.calculateAtBorder);
}
componentDidUpdate() {
this.calculateAtBorder();
}
calculateAtBorder = () => {
const { bottom } = this.ref.getBoundingClientRect();
// update classnames after records count change
const originClassName = this.ref ? this.ref.className : '';
let newClassName;
if (bottom >= window.innerHeight) {
newClassName = addClassName(originClassName, 'at-border');
} else {
newClassName = removeClassName(originClassName, 'at-border');
}
if (newClassName !== originClassName && this.ref) {
this.ref.className = newClassName;
}
};
onClick = () => {
if (this.props.isLoadingMore) {
return;
@@ -105,7 +136,7 @@ class RecordsFooter extends React.Component {
const recordWidth = (isLoadingMore || hasMore ? SEQUENCE_COLUMN_WIDTH + columns[0].width : SEQUENCE_COLUMN_WIDTH) + groupOffsetLeft;
return (
<div className="sf-metadata-result-footer" style={{ zIndex: Z_INDEX.GRID_FOOTER, transform: 'translateZ(1000px)' }}>
<div className="sf-metadata-result-footer" style={{ zIndex: Z_INDEX.GRID_FOOTER, transform: 'translateZ(1000px)' }} ref={ref => this.ref = ref}>
<div className="rows-record d-flex text-nowrap" style={{ width: recordWidth }}>
<span>{this.getRecord()}</span>
{!isLoadingMore && hasMore &&

View File

@@ -100,7 +100,8 @@ class RecordsBody extends Component {
const { startRenderIndex, endRenderIndex } = this.state;
const contentScrollTop = this.resultContentRef.scrollTop;
const start = Math.max(0, Math.floor(contentScrollTop / ROW_HEIGHT) - RENDER_MORE_NUMBER);
const end = Math.min(Math.ceil((contentScrollTop + this.resultContentRef.offsetHeight) / ROW_HEIGHT) + RENDER_MORE_NUMBER, recordIds.length);
const { height } = this.props.getTableContentRect();
const end = Math.min(Math.ceil((contentScrollTop + height) / ROW_HEIGHT) + RENDER_MORE_NUMBER, recordIds.length);
if (start !== startRenderIndex) {
this.setState({ startRenderIndex: start });
}

View File

@@ -1,75 +0,0 @@
import React, { useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { FilterSetter, GroupbySetter, SortSetter, HideColumnSetter } from '../../data-process-setter';
import { Z_INDEX } from '../../../_basic';
import { EVENT_BUS_TYPE } from '../../../constants';
import { useCollaborators } from '../../../hooks';
import './index.css';
const TableTool = ({ searcherActive, view, modifyFilters, modifySorts, modifyGroupbys, modifyHiddenColumns }) => {
const columns = useMemo(() => {
return view.available_columns;
}, [view]);
const { collaborators } = useCollaborators();
const onHeaderClick = useCallback(() => {
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.SELECT_NONE);
}, []);
return (
<div
className={classnames('sf-metadata-tool', { 'searcher-active': searcherActive })}
style={{ zIndex: Z_INDEX.TABLE_HEADER, transform: 'translateZ(1000px)' }}
onClick={onHeaderClick}
>
<div className="sf-metadata-tool-left-operations">
<FilterSetter
wrapperClass="custom-tool-label custom-filter-label"
filtersClassName="sf-metadata-filters"
target="sf-metadata-filter-popover"
filterConjunction={view.filter_conjunction}
filters={view.filters}
columns={columns}
modifyFilters={modifyFilters}
collaborators={collaborators}
/>
<SortSetter
wrapperClass="custom-tool-label custom-sort-label"
target="sf-metadata-sort-popover"
sorts={view.sorts}
columns={columns}
modifySorts={modifySorts}
/>
<GroupbySetter
wrapperClass={'custom-tool-label custom-groupby-label'}
target={'sf-metadata-groupby-popover'}
columns={[]}
groupbys={[]}
modifyGroupbys={modifyGroupbys}
/>
<HideColumnSetter
wrapperClass={'custom-tool-label custom-hide-column-label'}
target={'sf-metadata-hide-column-popover'}
columns={[]}
modifyHiddenColumns={modifyHiddenColumns}
/>
</div>
<div className="sf-metadata-tool-right-operations"></div>
</div>
);
};
TableTool.propTypes = {
searcherActive: PropTypes.bool,
view: PropTypes.object,
modifyFilters: PropTypes.func,
modifySorts: PropTypes.func,
modifyGroupbys: PropTypes.func,
modifyHiddenColumns: PropTypes.func,
};
export default TableTool;

View File

@@ -1,18 +1,10 @@
.sf-metadata-tool {
background-color: #fff;
border-bottom: 1px solid #e4e4e4;
border-top: 1px solid #ddd;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
display: flex;
flex-shrink: 0;
flex-wrap: nowrap;
height: 48px;
justify-content: space-between;
padding: 0 20px;
position: relative;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
}
.sf-metadata-tool .sf-metadata-tool-left-operations,

View File

@@ -0,0 +1,120 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { FilterSetter, GroupbySetter, SortSetter, HideColumnSetter } from '../data-process-setter';
import { EVENT_BUS_TYPE } from '../../constants';
import './index.css';
const ViewToolBar = () => {
const [isLoading, setLoading] = useState(true);
const [view, setView] = useState(null);
const [collaborators, setCollaborators] = useState([]);
const columns = useMemo(() => {
if (!view) return [];
return view.available_columns;
}, [view]);
const onHeaderClick = useCallback(() => {
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.SELECT_NONE);
}, []);
const modifyFilters = useCallback((filters, filterConjunction) => {
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.MODIFY_FILTERS, filters, filterConjunction);
}, []);
const modifySorts = useCallback((sorts) => {
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.MODIFY_SORTS, sorts);
}, []);
const modifyGroupbys = useCallback(() => {
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.MODIFY_GROUPBYS);
}, []);
const modifyHiddenColumns = useCallback(() => {
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.MODIFY_GROUPBYS);
}, []);
const viewChange = useCallback((view) => {
setView(view);
}, []);
useEffect(() => {
let timer = setInterval(() => {
if (window.sfMetadataContext) {
timer && clearInterval(timer);
timer = null;
setLoading(false);
setView(window.sfMetadataStore.data.view);
setCollaborators(window.sfMetadataStore?.collaborators || []);
}
}, 300);
return () => {
timer && clearInterval(timer);
};
}, []);
useEffect(() => {
if (isLoading) return;
const unsubscribeViewChange = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.VIEW_CHANGED, viewChange);
return () => {
unsubscribeViewChange();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoading]);
if (!view) return null;
return (
<div
className={classnames('sf-metadata-tool')}
// style={{ zIndex: Z_INDEX.TABLE_HEADER, transform: 'translateZ(1000px)' }}
onClick={onHeaderClick}
>
<div className="sf-metadata-tool-left-operations">
<FilterSetter
wrapperClass="custom-tool-label custom-filter-label"
filtersClassName="sf-metadata-filters"
target="sf-metadata-filter-popover"
filterConjunction={view.filter_conjunction}
filters={view.filters}
columns={columns}
modifyFilters={modifyFilters}
collaborators={collaborators}
/>
<SortSetter
wrapperClass="custom-tool-label custom-sort-label"
target="sf-metadata-sort-popover"
sorts={view.sorts}
columns={columns}
modifySorts={modifySorts}
/>
<GroupbySetter
wrapperClass={'custom-tool-label custom-groupby-label'}
target={'sf-metadata-groupby-popover'}
columns={[]}
groupbys={[]}
modifyGroupbys={modifyGroupbys}
/>
<HideColumnSetter
wrapperClass={'custom-tool-label custom-hide-column-label'}
target={'sf-metadata-hide-column-popover'}
columns={[]}
modifyHiddenColumns={modifyHiddenColumns}
/>
</div>
<div className="sf-metadata-tool-right-operations"></div>
</div>
);
};
ViewToolBar.propTypes = {
view: PropTypes.object,
modifyFilters: PropTypes.func,
modifySorts: PropTypes.func,
modifyGroupbys: PropTypes.func,
modifyHiddenColumns: PropTypes.func,
};
export default ViewToolBar;

View File

@@ -25,4 +25,13 @@ export const EVENT_BUS_TYPE = {
DRAG_ENTER: 'drag_enter',
COLLAPSE_ALL_GROUPS: 'collapse_all_groups',
EXPAND_ALL_GROUPS: 'expand_all_groups',
// modify view
MODIFY_FILTERS: 'modify_filters',
MODIFY_SORTS:'modify_sorts',
MODIFY_GROUPBYS:'modify_groupbys',
MODIFY_HIDDEN_COLUMNS:'modify_hidden_columns',
// change
VIEW_CHANGED: 'view_changed',
};

View File

@@ -37,6 +37,7 @@ export const MetadataProvider = ({
window.sfMetadataContext.init({ otherSettings: params });
const repoId = window.sfMetadataContext.getSetting('repoID');
storeRef.current = new Store({ context: window.sfMetadataContext, repoId });
window.sfMetadataStore = storeRef.current;
storeRef.current.initStartIndex();
storeRef.current.loadData(PER_LOAD_NUMBER).then(() => {
setMetadata(storeRef.current.data);

View File

@@ -34,6 +34,7 @@ class Store {
saveView = () => {
const { filters, sorts, gropbys, filter_conjunction } = this.data.view;
const view = { filters, sorts, gropbys, filter_conjunction };
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.VIEW_CHANGED, this.data.view);
this.context.localStorage.setItem('view', view);
};
@@ -330,6 +331,7 @@ class Store {
type, filter_conjunction: filterConjunction, filters,
});
this.applyOperation(operation);
this.saveView();
}
modifySorts(sorts) {
@@ -338,6 +340,7 @@ class Store {
type, sorts,
});
this.applyOperation(operation);
this.saveView();
}
modifyGroupbys(groupbys) {
@@ -346,6 +349,7 @@ class Store {
type, groupbys,
});
this.applyOperation(operation);
this.saveView();
}
modifyHiddenColumns(shown_column_keys) {
@@ -354,6 +358,7 @@ class Store {
type, shown_column_keys
});
this.applyOperation(operation);
this.saveView();
}
}