diff --git a/frontend/src/metadata/metadata-view/components/table/container.js b/frontend/src/metadata/metadata-view/components/table/container.js
deleted file mode 100644
index e45dd285bb..0000000000
--- a/frontend/src/metadata/metadata-view/components/table/container.js
+++ /dev/null
@@ -1,219 +0,0 @@
-import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
-import toaster from '../../../../components/toast';
-import { EVENT_BUS_TYPE, PER_LOAD_NUMBER, MAX_LOAD_NUMBER } from '../../constants';
-import { CommonlyUsedHotkey, getValidGroupbys } from '../../_basic';
-import { gettext } from '../../utils';
-import { useMetadata } from '../../hooks';
-import TableMain from './table-main';
-import Gallery from './gallery';
-import { Utils } from '../../../../utils/utils';
-
-import './index.css';
-
-const Container = () => {
- const [isLoadingMore, setLoadingMore] = useState(false);
- const { metadata, errorMsg, store } = useMetadata();
- const containerRef = useRef(null);
-
- const onKeyDown = useCallback((event) => {
- if (event.target.className.includes('editor-main')) return;
- if (CommonlyUsedHotkey.isModF(event)) {
- event.preventDefault();
- window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.SEARCH_CELLS);
- return;
- }
- }, []);
-
- const isGroupView = useMemo(() => {
- const validGroupbys = getValidGroupbys(metadata.view.groupbys, metadata.columns);
- return validGroupbys.length > 0;
- }, [metadata]);
-
- const loadMore = useCallback(async () => {
- if (!metadata.hasMore) return;
- setLoadingMore(true);
-
- try {
- await store.loadMore(PER_LOAD_NUMBER);
- setLoadingMore(false);
- } catch (error) {
- const errorMsg = Utils.getErrorMsg(error);
- toaster.danger(errorMsg);
- setLoadingMore(false);
- return;
- }
-
- }, [metadata, store]);
-
- const loadAll = useCallback(async (maxLoadNumber, callback) => {
- if (!metadata.hasMore) return;
- setLoadingMore(true);
- const rowsCount = metadata.row_ids.length;
- const loadNumber = rowsCount % MAX_LOAD_NUMBER !== 0 ? MAX_LOAD_NUMBER - rowsCount % MAX_LOAD_NUMBER : MAX_LOAD_NUMBER;
- try {
- await store.loadMore(loadNumber);
- setLoadingMore(false);
- } catch (error) {
- const errorMsg = Utils.getErrorMsg(error);
- toaster.danger(errorMsg);
- setLoadingMore(false);
- return;
- }
- if (store.data.hasMore && store.data.row_ids.length < maxLoadNumber) {
- loadAll(maxLoadNumber, callback);
- } else {
- typeof callback === 'function' && callback(store.data.hasMore);
- setLoadingMore(false);
- }
- }, [metadata, store]);
-
- const modifyRecords = useCallback((rowIds, idRowUpdates, idOriginalRowUpdates, idOldRowData, idOriginalOldRowData, isCopyPaste = false) => {
- store.modifyRecords(rowIds, idRowUpdates, idOriginalRowUpdates, idOldRowData, idOriginalOldRowData, isCopyPaste);
- }, [store]);
-
- const modifyRecord = useCallback((rowId, updates, oldRowData, originalUpdates, originalOldRowData) => {
- const rowIds = [rowId];
- const idRowUpdates = { [rowId]: updates };
- const idOriginalRowUpdates = { [rowId]: originalUpdates };
- const idOldRowData = { [rowId]: oldRowData };
- const idOriginalOldRowData = { [rowId]: originalOldRowData };
- modifyRecords(rowIds, idRowUpdates, idOriginalRowUpdates, idOldRowData, idOriginalOldRowData);
- }, [modifyRecords]);
-
- const getAdjacentRowsIds = useCallback((rowIds) => {
- const rowIdsLen = metadata.row_ids.length;
- let rowIdsInOrder = [];
- let upperRowIds = [];
- let belowRowIds = [];
- let rowIdMap = {};
- rowIds.forEach(rowId => rowIdMap[rowId] = rowId);
- metadata.row_ids.forEach((rowId, index) => {
- if (!rowIdMap[rowId]) {
- return;
- }
- const upperRowId = index === 0 ? null : metadata.row_ids[index - 1];
- const belowRowId = index === rowIdsLen - 1 ? null : metadata.row_ids[index + 1];
- rowIdsInOrder.push(rowId);
- upperRowIds.push(upperRowId);
- belowRowIds.push(belowRowId);
- });
- return { rowIdsInOrder, upperRowIds, belowRowIds };
- }, [metadata]);
-
- const modifyFilters = useCallback((filters, filterConjunction, basicFilters) => {
- store.modifyFilters(filterConjunction, filters, basicFilters);
- }, [store]);
-
- const modifySorts = useCallback((sorts) => {
- store.modifySorts(sorts);
- }, [store]);
-
- const modifyGroupbys = useCallback((groupbys) => {
- store.modifyGroupbys(groupbys);
- }, [store]);
-
- const modifyHiddenColumns = useCallback((hiddenColumns) => {
- store.modifyHiddenColumns(hiddenColumns);
- }, [store]);
-
- const renameColumn = useCallback((columnKey, newName, oldName) => {
- store.renameColumn(columnKey, newName, oldName);
- }, [store]);
-
- const deleteColumn = useCallback((columnKey, oldColumn) => {
- store.deleteColumn(columnKey, oldColumn);
- }, [store]);
-
- const modifyColumnData = useCallback((columnKey, newData, oldData) => {
- store.modifyColumnData(columnKey, newData, oldData);
- }, [store]);
-
- const modifyColumnWidth = useCallback((columnKey, newWidth) => {
- store.modifyColumnWidth(columnKey, newWidth);
- }, [store]);
-
- const modifyColumnOrder = useCallback((sourceColumnKey, targetColumnKey) => {
- store.modifyColumnOrder(sourceColumnKey, targetColumnKey);
- }, [store]);
-
- const recordGetterById = useCallback((recordId) => {
- return metadata.id_row_map[recordId];
- }, [metadata]);
-
- const recordGetter = useCallback((recordIndex) => {
- const recordId = metadata.view.rows[recordIndex];
- return recordId && recordGetterById(recordId);
- }, [metadata, recordGetterById]);
-
- const groupRecordGetter = useCallback((groupRecordIndex) => {
- if (!window.sfMetadataBody || !window.sfMetadataBody.getGroupRecordByIndex) return null;
- const groupRecord = window.sfMetadataBody.getGroupRecordByIndex(groupRecordIndex);
- const recordId = groupRecord.rowId;
- return recordId && recordGetterById(recordId);
- }, [recordGetterById]);
-
- const recordGetterByIndex = useCallback(({ isGroupView, groupRecordIndex, recordIndex }) => {
- if (isGroupView) return groupRecordGetter(groupRecordIndex);
- return recordGetter(recordIndex);
- }, [groupRecordGetter, recordGetter]);
-
- const getTableContentRect = useCallback(() => {
- return containerRef?.current?.getBoundingClientRect() || { x: 0, right: window.innerWidth };
- }, [containerRef]);
-
- useEffect(() => {
- document.addEventListener('keydown', onKeyDown);
- const eventBus = window.sfMetadataContext.eventBus;
- const unsubscribeModifyFilters = eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_FILTERS, modifyFilters);
- const unsubscribeModifySorts = eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_SORTS, modifySorts);
- const unsubscribeModifyGroupbys = eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_GROUPBYS, modifyGroupbys);
- const unsubscribeModifyHiddenColumns = eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_HIDDEN_COLUMNS, modifyHiddenColumns);
- const unsubscribeModifyColumnOrder = eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_COLUMN_ORDER, modifyColumnOrder);
- return () => {
- document.removeEventListener('keydown', onKeyDown);
- unsubscribeModifyFilters();
- unsubscribeModifySorts();
- unsubscribeModifyGroupbys();
- unsubscribeModifyHiddenColumns();
- unsubscribeModifyColumnOrder();
- };
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
-
- return (
- <>
-
-
- {errorMsg && (
{gettext(errorMsg)}
)}
- {!errorMsg && (
-
- {metadata.view.type === 'table' && (
-
- )}
- {metadata.view.type === 'image' && (
)}
-
- )}
-
-
- >
- );
-};
-
-export default Container;
diff --git a/frontend/src/metadata/metadata-view/components/table/index.js b/frontend/src/metadata/metadata-view/components/table/index.js
index 1ae29e0768..f888f29332 100644
--- a/frontend/src/metadata/metadata-view/components/table/index.js
+++ b/frontend/src/metadata/metadata-view/components/table/index.js
@@ -1,15 +1,196 @@
-import React from 'react';
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { CenteredLoading } from '@seafile/sf-metadata-ui-component';
+import toaster from '../../../../components/toast';
+import { EVENT_BUS_TYPE, PER_LOAD_NUMBER, MAX_LOAD_NUMBER } from '../../constants';
+import { CommonlyUsedHotkey, getValidGroupbys } from '../../_basic';
+import { gettext } from '../../utils';
import { useMetadata } from '../../hooks';
-import Container from './container';
+import TableMain from './table-main';
+import Gallery from './gallery';
+import { Utils } from '../../../../utils/utils';
import './index.css';
const Table = () => {
- const { isLoading } = useMetadata();
+ const [isLoadingMore, setLoadingMore] = useState(false);
+ const { isLoading, metadata, errorMsg, store } = useMetadata();
+ const containerRef = useRef(null);
+
+ const onKeyDown = useCallback((event) => {
+ if (event.target.className.includes('editor-main')) return;
+ if (CommonlyUsedHotkey.isModF(event)) {
+ event.preventDefault();
+ window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.SEARCH_CELLS);
+ return;
+ }
+ }, []);
+
+ const isGroupView = useMemo(() => {
+ if (isLoading || !metadata) return false;
+ const validGroupbys = getValidGroupbys(metadata.view.groupbys, metadata.columns);
+ return validGroupbys.length > 0;
+ }, [isLoading, metadata]);
+
+ const loadMore = useCallback(async () => {
+ if (!metadata.hasMore) return;
+ setLoadingMore(true);
+
+ try {
+ await store.loadMore(PER_LOAD_NUMBER);
+ setLoadingMore(false);
+ } catch (error) {
+ const errorMsg = Utils.getErrorMsg(error);
+ toaster.danger(errorMsg);
+ setLoadingMore(false);
+ return;
+ }
+
+ }, [metadata, store]);
+
+ const loadAll = useCallback(async (maxLoadNumber, callback) => {
+ if (!metadata.hasMore) return;
+ setLoadingMore(true);
+ const rowsCount = metadata.row_ids.length;
+ const loadNumber = rowsCount % MAX_LOAD_NUMBER !== 0 ? MAX_LOAD_NUMBER - rowsCount % MAX_LOAD_NUMBER : MAX_LOAD_NUMBER;
+ try {
+ await store.loadMore(loadNumber);
+ setLoadingMore(false);
+ } catch (error) {
+ const errorMsg = Utils.getErrorMsg(error);
+ toaster.danger(errorMsg);
+ setLoadingMore(false);
+ return;
+ }
+ if (store.data.hasMore && store.data.row_ids.length < maxLoadNumber) {
+ loadAll(maxLoadNumber, callback);
+ } else {
+ typeof callback === 'function' && callback(store.data.hasMore);
+ setLoadingMore(false);
+ }
+ }, [metadata, store]);
+
+ const modifyRecords = useCallback((rowIds, idRowUpdates, idOriginalRowUpdates, idOldRowData, idOriginalOldRowData, isCopyPaste = false) => {
+ store.modifyRecords(rowIds, idRowUpdates, idOriginalRowUpdates, idOldRowData, idOriginalOldRowData, isCopyPaste);
+ }, [store]);
+
+ const modifyRecord = useCallback((rowId, updates, oldRowData, originalUpdates, originalOldRowData) => {
+ const rowIds = [rowId];
+ const idRowUpdates = { [rowId]: updates };
+ const idOriginalRowUpdates = { [rowId]: originalUpdates };
+ const idOldRowData = { [rowId]: oldRowData };
+ const idOriginalOldRowData = { [rowId]: originalOldRowData };
+ modifyRecords(rowIds, idRowUpdates, idOriginalRowUpdates, idOldRowData, idOriginalOldRowData);
+ }, [modifyRecords]);
+
+ const getAdjacentRowsIds = useCallback((rowIds) => {
+ const rowIdsLen = metadata.row_ids.length;
+ let rowIdsInOrder = [];
+ let upperRowIds = [];
+ let belowRowIds = [];
+ let rowIdMap = {};
+ rowIds.forEach(rowId => rowIdMap[rowId] = rowId);
+ metadata.row_ids.forEach((rowId, index) => {
+ if (!rowIdMap[rowId]) {
+ return;
+ }
+ const upperRowId = index === 0 ? null : metadata.row_ids[index - 1];
+ const belowRowId = index === rowIdsLen - 1 ? null : metadata.row_ids[index + 1];
+ rowIdsInOrder.push(rowId);
+ upperRowIds.push(upperRowId);
+ belowRowIds.push(belowRowId);
+ });
+ return { rowIdsInOrder, upperRowIds, belowRowIds };
+ }, [metadata]);
+
+ const renameColumn = useCallback((columnKey, newName, oldName) => {
+ store.renameColumn(columnKey, newName, oldName);
+ }, [store]);
+
+ const deleteColumn = useCallback((columnKey, oldColumn) => {
+ store.deleteColumn(columnKey, oldColumn);
+ }, [store]);
+
+ const modifyColumnData = useCallback((columnKey, newData, oldData) => {
+ store.modifyColumnData(columnKey, newData, oldData);
+ }, [store]);
+
+ const modifyColumnWidth = useCallback((columnKey, newWidth) => {
+ store.modifyColumnWidth(columnKey, newWidth);
+ }, [store]);
+
+ const modifyColumnOrder = useCallback((sourceColumnKey, targetColumnKey) => {
+ store.modifyColumnOrder(sourceColumnKey, targetColumnKey);
+ }, [store]);
+
+ const recordGetterById = useCallback((recordId) => {
+ return metadata.id_row_map[recordId];
+ }, [metadata]);
+
+ const recordGetter = useCallback((recordIndex) => {
+ const recordId = metadata.view.rows[recordIndex];
+ return recordId && recordGetterById(recordId);
+ }, [metadata, recordGetterById]);
+
+ const groupRecordGetter = useCallback((groupRecordIndex) => {
+ if (!window.sfMetadataBody || !window.sfMetadataBody.getGroupRecordByIndex) return null;
+ const groupRecord = window.sfMetadataBody.getGroupRecordByIndex(groupRecordIndex);
+ const recordId = groupRecord.rowId;
+ return recordId && recordGetterById(recordId);
+ }, [recordGetterById]);
+
+ const recordGetterByIndex = useCallback(({ isGroupView, groupRecordIndex, recordIndex }) => {
+ if (isGroupView) return groupRecordGetter(groupRecordIndex);
+ return recordGetter(recordIndex);
+ }, [groupRecordGetter, recordGetter]);
+
+ const getTableContentRect = useCallback(() => {
+ return containerRef?.current?.getBoundingClientRect() || { x: 0, right: window.innerWidth };
+ }, [containerRef]);
+
+ useEffect(() => {
+ document.addEventListener('keydown', onKeyDown);
+ return () => {
+ document.removeEventListener('keydown', onKeyDown);
+ };
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
if (isLoading) return ();
- return ();
+
+ return (
+ <>
+
+
+ {errorMsg && (
{gettext(errorMsg)}
)}
+ {!errorMsg && (
+
+ {metadata.view.type === 'table' && (
+
+ )}
+ {metadata.view.type === 'image' && (
)}
+
+ )}
+
+
+ >
+ );
};
export default Table;
diff --git a/frontend/src/metadata/metadata-view/hooks/metadata.js b/frontend/src/metadata/metadata-view/hooks/metadata.js
index 08906497ae..528e88bff6 100644
--- a/frontend/src/metadata/metadata-view/hooks/metadata.js
+++ b/frontend/src/metadata/metadata-view/hooks/metadata.js
@@ -45,6 +45,26 @@ export const MetadataProvider = ({
});
}, []);
+ const modifyFilters = useCallback((filters, filterConjunction, basicFilters) => {
+ window.sfMetadataStore.modifyFilters(filterConjunction, filters, basicFilters);
+ }, []);
+
+ const modifySorts = useCallback((sorts) => {
+ window.sfMetadataStore.modifySorts(sorts);
+ }, []);
+
+ const modifyGroupbys = useCallback((groupbys) => {
+ window.sfMetadataStore.modifyGroupbys(groupbys);
+ }, []);
+
+ const modifyHiddenColumns = useCallback((hiddenColumns) => {
+ window.sfMetadataStore.modifyHiddenColumns(hiddenColumns);
+ }, []);
+
+ const modifyColumnOrder = useCallback((sourceColumnKey, targetColumnKey) => {
+ window.sfMetadataStore.modifyColumnOrder(sourceColumnKey, targetColumnKey);
+ }, []);
+
// init
useEffect(() => {
setLoading(true);
@@ -72,6 +92,11 @@ export const MetadataProvider = ({
const unsubscribeHandleTableError = eventBus.subscribe(EVENT_BUS_TYPE.TABLE_ERROR, handleTableError);
const unsubscribeUpdateRows = eventBus.subscribe(EVENT_BUS_TYPE.UPDATE_TABLE_ROWS, updateMetadata);
const unsubscribeReloadData = eventBus.subscribe(EVENT_BUS_TYPE.RELOAD_DATA, reloadMetadata);
+ const unsubscribeModifyFilters = eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_FILTERS, modifyFilters);
+ const unsubscribeModifySorts = eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_SORTS, modifySorts);
+ const unsubscribeModifyGroupbys = eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_GROUPBYS, modifyGroupbys);
+ const unsubscribeModifyHiddenColumns = eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_HIDDEN_COLUMNS, modifyHiddenColumns);
+ const unsubscribeModifyColumnOrder = eventBus.subscribe(EVENT_BUS_TYPE.MODIFY_COLUMN_ORDER, modifyColumnOrder);
return () => {
window.sfMetadataContext.destroy();
@@ -81,6 +106,11 @@ export const MetadataProvider = ({
unsubscribeHandleTableError();
unsubscribeUpdateRows();
unsubscribeReloadData();
+ unsubscribeModifyFilters();
+ unsubscribeModifySorts();
+ unsubscribeModifyGroupbys();
+ unsubscribeModifyHiddenColumns();
+ unsubscribeModifyColumnOrder();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [repoID, viewID]);