mirror of
https://github.com/haiwen/seahub.git
synced 2025-10-22 11:43:33 +00:00
[metadata] 'card' view: added a 'settings' panel (#8267)
This commit is contained in:
@@ -63,7 +63,7 @@ const CardViewToolbar = ({
|
|||||||
{!readOnly && (
|
{!readOnly && (
|
||||||
<IconBtn
|
<IconBtn
|
||||||
symbol="set-up"
|
symbol="set-up"
|
||||||
className="sf-metadata-view-tool-operation-btn sf-metadata-view-tool-setting d-none"
|
className="sf-metadata-view-tool-operation-btn sf-metadata-view-tool-setting"
|
||||||
size={24}
|
size={24}
|
||||||
role="button"
|
role="button"
|
||||||
aria-label={gettext('Settings')}
|
aria-label={gettext('Settings')}
|
||||||
|
@@ -168,6 +168,13 @@ export const KANBAN_SETTINGS_KEYS = {
|
|||||||
COLUMNS: 'columns', // display and order
|
COLUMNS: 'columns', // display and order
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const CARD_SETTINGS_KEYS = {
|
||||||
|
HIDE_EMPTY_VALUE: 'hide_empty_value',
|
||||||
|
SHOW_COLUMN_NAME: 'show_column_name',
|
||||||
|
TEXT_WRAP: 'text_wrap',
|
||||||
|
COLUMNS: 'columns', // display and order
|
||||||
|
};
|
||||||
|
|
||||||
export const VIEW_DEFAULT_SETTINGS = {
|
export const VIEW_DEFAULT_SETTINGS = {
|
||||||
[VIEW_TYPE.TABLE]: {},
|
[VIEW_TYPE.TABLE]: {},
|
||||||
[VIEW_TYPE.GALLERY]: {},
|
[VIEW_TYPE.GALLERY]: {},
|
||||||
@@ -180,7 +187,12 @@ export const VIEW_DEFAULT_SETTINGS = {
|
|||||||
[KANBAN_SETTINGS_KEYS.TEXT_WRAP]: false,
|
[KANBAN_SETTINGS_KEYS.TEXT_WRAP]: false,
|
||||||
[KANBAN_SETTINGS_KEYS.COLUMNS]: [],
|
[KANBAN_SETTINGS_KEYS.COLUMNS]: [],
|
||||||
},
|
},
|
||||||
[VIEW_TYPE.CARD]: {}
|
[VIEW_TYPE.CARD]: {
|
||||||
|
[CARD_SETTINGS_KEYS.HIDE_EMPTY_VALUE]: false,
|
||||||
|
[CARD_SETTINGS_KEYS.SHOW_COLUMN_NAME]: false,
|
||||||
|
[CARD_SETTINGS_KEYS.TEXT_WRAP]: false,
|
||||||
|
[CARD_SETTINGS_KEYS.COLUMNS]: [],
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const VIEW_PROPERTY_KEYS = {
|
export const VIEW_PROPERTY_KEYS = {
|
||||||
|
@@ -30,6 +30,25 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sf-metadata-card-item .sf-metadata-card-item-field {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sf-metadata-card-item .sf-metadata-card-item-field-name {
|
||||||
|
display: block;
|
||||||
|
color: #666;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sf-metadata-card-item .sf-metadata-card-item-field .sf-metadata-record-cell-empty {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 8px;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.sf-metadata-card-item .sf-metadata-ui {
|
.sf-metadata-card-item .sf-metadata-ui {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
@@ -65,37 +84,37 @@
|
|||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-card-item .sf-metadata-card-item-record .collaborators-formatter {
|
.sf-metadata-card-item .sf-metadata-card-item-field .collaborators-formatter {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-card-item .sf-metadata-card-item-record .collaborators-formatter .collaborator-item {
|
.sf-metadata-card-item .sf-metadata-card-item-field .collaborators-formatter .collaborator-item {
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-card-item .sf-metadata-card-item-record .sf-metadata-checkbox-formatter {
|
.sf-metadata-card-item .sf-metadata-card-item-field .sf-metadata-checkbox-formatter {
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
padding-left: 2px;
|
padding-left: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-card-item .sf-metadata-card-item-record .sf-metadata-multiple-select-formatter {
|
.sf-metadata-card-item .sf-metadata-card-item-field .sf-metadata-multiple-select-formatter {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-card-item .sf-metadata-card-item-record .sf-metadata-multiple-select-formatter .sf-metadata-ui-select-option {
|
.sf-metadata-card-item .sf-metadata-card-item-field .sf-metadata-multiple-select-formatter .sf-metadata-ui-select-option {
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-view-kanban-boards-text-wrap .sf-metadata-card-item-record .text-formatter {
|
.sf-metadata-view-card-items-container-text-wrap .sf-metadata-card-item-field .text-formatter {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
max-height: 68px;
|
max-height: 68px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-card-item .long-text-formatter,
|
.sf-metadata-card-item .long-text-formatter,
|
||||||
.sf-metadata-view-kanban-boards-text-wrap .sf-metadata-card-item-record .long-text-formatter {
|
.sf-metadata-view-card-items-container-text-wrap .sf-metadata-card-item-field .long-text-formatter {
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 2;
|
||||||
|
@@ -4,6 +4,7 @@ import classnames from 'classnames';
|
|||||||
import Formatter from './formatter';
|
import Formatter from './formatter';
|
||||||
import {
|
import {
|
||||||
getCellValueByColumn,
|
getCellValueByColumn,
|
||||||
|
isValidCellValue,
|
||||||
getParentDirFromRecord, getFileMTimeFromRecord
|
getParentDirFromRecord, getFileMTimeFromRecord
|
||||||
} from '../../../../utils/cell';
|
} from '../../../../utils/cell';
|
||||||
import { Utils } from '../../../../../utils/utils';
|
import { Utils } from '../../../../../utils/utils';
|
||||||
@@ -18,6 +19,9 @@ const CardItem = ({
|
|||||||
tagsData,
|
tagsData,
|
||||||
fileNameColumn,
|
fileNameColumn,
|
||||||
mtimeColumn,
|
mtimeColumn,
|
||||||
|
displayColumns,
|
||||||
|
displayEmptyValue,
|
||||||
|
displayColumnName,
|
||||||
onOpenFile,
|
onOpenFile,
|
||||||
onSelectCard,
|
onSelectCard,
|
||||||
onContextMenu,
|
onContextMenu,
|
||||||
@@ -80,6 +84,28 @@ const CardItem = ({
|
|||||||
<div className="sf-metadata-card-item-text-container">
|
<div className="sf-metadata-card-item-text-container">
|
||||||
<Formatter value={fileNameValue} column={fileNameColumn} record={record} onFileNameClick={handleFilenameClick} tagsData={tagsData} />
|
<Formatter value={fileNameValue} column={fileNameColumn} record={record} onFileNameClick={handleFilenameClick} tagsData={tagsData} />
|
||||||
<Formatter value={mtimeValue} format="relativeTime" column={mtimeColumn} record={record} tagsData={tagsData} />
|
<Formatter value={mtimeValue} format="relativeTime" column={mtimeColumn} record={record} tagsData={tagsData} />
|
||||||
|
{displayColumns.map((column) => {
|
||||||
|
const value = getCellValueByColumn(record, column);
|
||||||
|
if (!displayEmptyValue && !isValidCellValue(value)) {
|
||||||
|
if (displayColumnName) {
|
||||||
|
return (
|
||||||
|
<div className="sf-metadata-card-item-field" key={column.key}>
|
||||||
|
<span className="sf-metadata-card-item-field-name">{column.name}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="sf-metadata-card-item-field" key={column.key}>
|
||||||
|
{displayColumnName && (
|
||||||
|
<span className="sf-metadata-card-item-field-name">{column.name}</span>
|
||||||
|
)}
|
||||||
|
<Formatter value={value} column={column} record={record} tagsData={tagsData} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
);
|
);
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
.sf-metadata-view-card-items-container {
|
.sf-metadata-view-card-items-container {
|
||||||
|
padding: 20px;
|
||||||
grid-gap: 20px;
|
grid-gap: 20px;
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ import React, { useMemo, useCallback, useState, useRef, useEffect } from 'react'
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { useMetadataView } from '../../../hooks/metadata-view';
|
import { useMetadataView } from '../../../hooks/metadata-view';
|
||||||
|
import { CARD_SETTINGS_KEYS } from '../../../constants';
|
||||||
import { gettext } from '../../../../utils/constants';
|
import { gettext } from '../../../../utils/constants';
|
||||||
import { getRecordIdFromRecord, getFileNameFromRecord, getParentDirFromRecord } from '../../../utils/cell';
|
import { getRecordIdFromRecord, getFileNameFromRecord, getParentDirFromRecord } from '../../../utils/cell';
|
||||||
import { openFile } from '../../../utils/file';
|
import { openFile } from '../../../utils/file';
|
||||||
@@ -36,6 +37,18 @@ const CardItems = ({ modifyRecord, deleteRecords, modifyColumnData, onCloseSetti
|
|||||||
return metadata.key_column_map['_file_mtime'];
|
return metadata.key_column_map['_file_mtime'];
|
||||||
}, [metadata.key_column_map]);
|
}, [metadata.key_column_map]);
|
||||||
|
|
||||||
|
const displayColumns = useMemo(() => {
|
||||||
|
const displayColumnsConfig = metadata.view.settings[CARD_SETTINGS_KEYS.COLUMNS];
|
||||||
|
if (!displayColumnsConfig) return [];
|
||||||
|
return displayColumnsConfig
|
||||||
|
.filter(config => config.shown)
|
||||||
|
.map(config => metadata.key_column_map[config.key]);
|
||||||
|
}, [metadata.key_column_map, metadata.view.settings]);
|
||||||
|
|
||||||
|
const displayEmptyValue = useMemo(() => !metadata.view.settings[CARD_SETTINGS_KEYS.HIDE_EMPTY_VALUE], [metadata.view.settings]);
|
||||||
|
const displayColumnName = useMemo(() => metadata.view.settings[CARD_SETTINGS_KEYS.SHOW_COLUMN_NAME], [metadata.view.settings]);
|
||||||
|
const textWrap = useMemo(() => metadata.view.settings[CARD_SETTINGS_KEYS.TEXT_WRAP], [metadata.view.settings]);
|
||||||
|
|
||||||
const records = useMemo(() => {
|
const records = useMemo(() => {
|
||||||
const { rows } = metadata;
|
const { rows } = metadata;
|
||||||
return rows || [];
|
return rows || [];
|
||||||
@@ -126,7 +139,8 @@ const CardItems = ({ modifyRecord, deleteRecords, modifyColumnData, onCloseSetti
|
|||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
className={classnames('sf-metadata-view-card-items-container d-flex flex-wrap', {
|
className={classnames('sf-metadata-view-card-items-container d-flex flex-wrap h-100 o-auto', {
|
||||||
|
'sf-metadata-view-card-items-container-text-wrap': textWrap
|
||||||
})}
|
})}
|
||||||
onClick={handleClickOutside}
|
onClick={handleClickOutside}
|
||||||
>
|
>
|
||||||
@@ -140,6 +154,9 @@ const CardItems = ({ modifyRecord, deleteRecords, modifyColumnData, onCloseSetti
|
|||||||
tagsData={tagsData}
|
tagsData={tagsData}
|
||||||
fileNameColumn={fileNameColumn}
|
fileNameColumn={fileNameColumn}
|
||||||
mtimeColumn={mtimeColumn}
|
mtimeColumn={mtimeColumn}
|
||||||
|
displayColumns={displayColumns}
|
||||||
|
displayEmptyValue={displayEmptyValue}
|
||||||
|
displayColumnName={displayColumnName}
|
||||||
onOpenFile={onOpenFile}
|
onOpenFile={onOpenFile}
|
||||||
onSelectCard={onSelectCard}
|
onSelectCard={onSelectCard}
|
||||||
onContextMenu={(e) => onContextMenu(e, record._id)}
|
onContextMenu={(e) => onContextMenu(e, record._id)}
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
.sf-metadata-view-card {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
@@ -4,12 +4,7 @@ import { EVENT_BUS_TYPE } from '../../constants';
|
|||||||
import CardItems from './card-items';
|
import CardItems from './card-items';
|
||||||
import Settings from './settings';
|
import Settings from './settings';
|
||||||
|
|
||||||
import './index.css';
|
|
||||||
|
|
||||||
const Card = () => {
|
const Card = () => {
|
||||||
|
|
||||||
// Thu Sep 11 18:29:51 CST 2025
|
|
||||||
// 'Settings' will be implemented later
|
|
||||||
const [isShowSettings, setShowSettings] = useState(false);
|
const [isShowSettings, setShowSettings] = useState(false);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -46,7 +41,7 @@ const Card = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="sf-metadata-container">
|
<div className="sf-metadata-container">
|
||||||
<div className="sf-metadata-view-card flex-fill o-auto">
|
<div className="sf-metadata-view-card flex-fill o-hidden position-relative">
|
||||||
<CardItems
|
<CardItems
|
||||||
modifyRecord={modifyRecord}
|
modifyRecord={modifyRecord}
|
||||||
deleteRecords={deleteRecords}
|
deleteRecords={deleteRecords}
|
||||||
@@ -54,7 +49,7 @@ const Card = () => {
|
|||||||
onCloseSettings={closeSettings}
|
onCloseSettings={closeSettings}
|
||||||
/>
|
/>
|
||||||
{isShowSettings && (
|
{isShowSettings && (
|
||||||
<div className="sf-metadata-view-setting-panel sf-metadata-view-card-setting h-100">
|
<div className="sf-metadata-view-setting-panel sf-metadata-view-card-setting h-100 position-absolute end-0 top-0">
|
||||||
<Settings
|
<Settings
|
||||||
columns={columns}
|
columns={columns}
|
||||||
columnsMap={metadata.key_column_map}
|
columnsMap={metadata.key_column_map}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
.sf-metadata-view-kanban-setting-panel {
|
.sf-metadata-view-card-setting-panel {
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
background: var(--bs-body-bg);
|
background: var(--bs-body-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-view-kanban-setting-panel .setting-panel-header {
|
.sf-metadata-view-card-setting-panel .setting-panel-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
border-bottom: 1px solid var(--bs-border-secondary-color);
|
border-bottom: 1px solid var(--bs-border-secondary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-view-kanban-setting-panel .setting-panel-body {
|
.sf-metadata-view-card-setting-panel .setting-panel-body {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 16px 16px 50px;
|
padding: 16px 16px 50px;
|
||||||
@@ -23,26 +23,26 @@
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-view-kanban-setting-panel .setting-panel-body .setting-item {
|
.sf-metadata-view-card-setting-panel .setting-panel-body .setting-item {
|
||||||
margin-bottom: 14px;
|
margin-bottom: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-view-kanban-setting-panel .setting-item .setting-item-label {
|
.sf-metadata-view-card-setting-panel .setting-item .setting-item-label {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-view-kanban-setting-panel .setting-item .custom-switch-description {
|
.sf-metadata-view-card-setting-panel .setting-item .custom-switch-description {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-view-kanban-setting-panel .setting-item .switch-setting-item {
|
.sf-metadata-view-card-setting-panel .setting-item .switch-setting-item {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-view-kanban-setting-panel .custom-switch {
|
.sf-metadata-view-card-setting-panel .custom-switch {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -51,18 +51,18 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-view-kanban-setting-panel .custom-switch-indicator{
|
.sf-metadata-view-card-setting-panel .custom-switch-indicator {
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
width: 22px;
|
width: 22px;
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-view-kanban-setting-panel .custom-switch .custom-switch-indicator:before {
|
.sf-metadata-view-card-setting-panel .custom-switch .custom-switch-indicator:before {
|
||||||
height: 8px;
|
height: 8px;
|
||||||
width: 8px;
|
width: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-metadata-view-kanban-setting-panel .custom-switch .custom-switch-input:checked~.custom-switch-indicator:before {
|
.sf-metadata-view-card-setting-panel .custom-switch .custom-switch-input:checked~.custom-switch-indicator:before {
|
||||||
left: 12px;
|
left: 12px;
|
||||||
}
|
}
|
||||||
|
@@ -1,12 +1,10 @@
|
|||||||
import React, { useCallback, useMemo } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Icon from '../../../../components/icon';
|
|
||||||
import OpIcon from '../../../../components/op-icon';
|
import OpIcon from '../../../../components/op-icon';
|
||||||
import Switch from '../../../../components/switch';
|
import Switch from '../../../../components/switch';
|
||||||
import Selector from '../../../components/selector';
|
|
||||||
import FieldDisplaySettings from '../../../components/data-process-setter/field-display-settings';
|
import FieldDisplaySettings from '../../../components/data-process-setter/field-display-settings';
|
||||||
import { gettext } from '../../../../utils/constants';
|
import { gettext } from '../../../../utils/constants';
|
||||||
import { CellType, COLUMNS_ICON_CONFIG, KANBAN_SETTINGS_KEYS } from '../../../constants';
|
import { COLUMNS_ICON_CONFIG, CARD_SETTINGS_KEYS } from '../../../constants';
|
||||||
import { getColumnByKey } from '../../../utils/column';
|
import { getColumnByKey } from '../../../utils/column';
|
||||||
import { useMetadataStatus } from '../../../../hooks';
|
import { useMetadataStatus } from '../../../../hooks';
|
||||||
|
|
||||||
@@ -21,45 +19,26 @@ const Settings = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { globalHiddenColumns } = useMetadataStatus();
|
const { globalHiddenColumns } = useMetadataStatus();
|
||||||
const validColumns = useMemo(() => columns.filter(column => !globalHiddenColumns.includes(column.key)), [columns, globalHiddenColumns]);
|
const validColumns = useMemo(() => columns.filter(column => !globalHiddenColumns.includes(column.key)), [columns, globalHiddenColumns]);
|
||||||
const groupByColumnOptions = useMemo(() => {
|
|
||||||
return validColumns
|
|
||||||
.filter(col => col.type === CellType.SINGLE_SELECT || col.type === CellType.COLLABORATOR)
|
|
||||||
.map(col => ({
|
|
||||||
value: col.key,
|
|
||||||
label: (
|
|
||||||
<>
|
|
||||||
<span className="sf-metadata-select-icon"><Icon className="sf-metadata-icon" symbol={COLUMNS_ICON_CONFIG[col.type]} /></span>
|
|
||||||
<span>{col.name}</span>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}));
|
|
||||||
}, [validColumns]);
|
|
||||||
const titleColumnOptions = useMemo(() => {
|
|
||||||
return validColumns
|
|
||||||
.map(col => ({
|
|
||||||
value: col.key,
|
|
||||||
label: (
|
|
||||||
<>
|
|
||||||
<span className="sf-metadata-select-icon"><Icon className="sf-metadata-icon" symbol={COLUMNS_ICON_CONFIG[col.type]} /></span>
|
|
||||||
<span>{col.name}</span>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}));
|
|
||||||
}, [validColumns]);
|
|
||||||
|
|
||||||
const displayColumns = useMemo(() => {
|
const displayColumns = useMemo(() => {
|
||||||
const displayColumnsConfig = settings[KANBAN_SETTINGS_KEYS.COLUMNS].filter(column => !globalHiddenColumns.includes(column.key));
|
const displayColumnsConfig = settings[CARD_SETTINGS_KEYS.COLUMNS].filter(column => !globalHiddenColumns.includes(column.key));
|
||||||
const titleColumnKey = settings[KANBAN_SETTINGS_KEYS.TITLE_COLUMN_KEY];
|
const nameColumnKey = '_name';
|
||||||
const filteredColumns = validColumns.filter(item => item.key !== titleColumnKey);
|
const mtimeColumnKey = '_file_mtime';
|
||||||
if (!displayColumnsConfig) return filteredColumns.map(column => ({ ...column, shown: false }));
|
const filteredColumns = validColumns.filter(item => item.key !== nameColumnKey && item.key !== mtimeColumnKey);
|
||||||
|
|
||||||
|
if (!displayColumnsConfig) {
|
||||||
|
return filteredColumns.map(column => ({ ...column, shown: false }));
|
||||||
|
}
|
||||||
|
|
||||||
const validDisplayColumnsConfig = displayColumnsConfig.map(columnConfig => {
|
const validDisplayColumnsConfig = displayColumnsConfig.map(columnConfig => {
|
||||||
const column = columnsMap[columnConfig.key];
|
const column = columnsMap[columnConfig.key];
|
||||||
if (column) return { ...column, shown: columnConfig.shown };
|
if (column) return { ...column, shown: columnConfig.shown };
|
||||||
return null;
|
return null;
|
||||||
}).filter(column => column && column.key !== titleColumnKey);
|
}).filter(column => column && column.key !== nameColumnKey && column.key !== mtimeColumnKey);
|
||||||
const addedColumns = filteredColumns
|
const addedColumns = filteredColumns
|
||||||
.filter(column => !getColumnByKey(validDisplayColumnsConfig, column.key))
|
.filter(column => !getColumnByKey(validDisplayColumnsConfig, column.key))
|
||||||
.map(column => ({ ...column, shown: false }));
|
.map(column => ({ ...column, shown: false }));
|
||||||
|
|
||||||
return [...validDisplayColumnsConfig, ...addedColumns];
|
return [...validDisplayColumnsConfig, ...addedColumns];
|
||||||
}, [validColumns, columnsMap, settings, globalHiddenColumns]);
|
}, [validColumns, columnsMap, settings, globalHiddenColumns]);
|
||||||
|
|
||||||
@@ -74,7 +53,7 @@ const Settings = ({
|
|||||||
if (columnConfig.key === key) return { ...columnConfig, shown };
|
if (columnConfig.key === key) return { ...columnConfig, shown };
|
||||||
return columnConfig;
|
return columnConfig;
|
||||||
});
|
});
|
||||||
handleUpdateSettings(KANBAN_SETTINGS_KEYS.COLUMNS, newDisplayColumnsConfig);
|
handleUpdateSettings(CARD_SETTINGS_KEYS.COLUMNS, newDisplayColumnsConfig);
|
||||||
}, [displayColumnsConfig, handleUpdateSettings]);
|
}, [displayColumnsConfig, handleUpdateSettings]);
|
||||||
|
|
||||||
const onMoveField = useCallback((sourceKey, targetKey) => {
|
const onMoveField = useCallback((sourceKey, targetKey) => {
|
||||||
@@ -84,63 +63,42 @@ const Settings = ({
|
|||||||
if (sourceIndex === -1 || targetIndex === -1) return;
|
if (sourceIndex === -1 || targetIndex === -1) return;
|
||||||
newDisplayColumnsConfig.splice(sourceIndex, 1, displayColumnsConfig[targetIndex]);
|
newDisplayColumnsConfig.splice(sourceIndex, 1, displayColumnsConfig[targetIndex]);
|
||||||
newDisplayColumnsConfig.splice(targetIndex, 1, displayColumnsConfig[sourceIndex]);
|
newDisplayColumnsConfig.splice(targetIndex, 1, displayColumnsConfig[sourceIndex]);
|
||||||
handleUpdateSettings(KANBAN_SETTINGS_KEYS.COLUMNS, newDisplayColumnsConfig);
|
handleUpdateSettings(CARD_SETTINGS_KEYS.COLUMNS, newDisplayColumnsConfig);
|
||||||
}, [displayColumnsConfig, handleUpdateSettings]);
|
}, [displayColumnsConfig, handleUpdateSettings]);
|
||||||
|
|
||||||
const onToggleFieldsVisibility = useCallback((visibility) => {
|
const onToggleFieldsVisibility = useCallback((visibility) => {
|
||||||
const newDisplayColumnsConfig = displayColumnsConfig.map(columnConfig => ({ ...columnConfig, shown: visibility }));
|
const newDisplayColumnsConfig = displayColumnsConfig.map(columnConfig => ({ ...columnConfig, shown: visibility }));
|
||||||
handleUpdateSettings(KANBAN_SETTINGS_KEYS.COLUMNS, newDisplayColumnsConfig);
|
handleUpdateSettings(CARD_SETTINGS_KEYS.COLUMNS, newDisplayColumnsConfig);
|
||||||
}, [displayColumnsConfig, handleUpdateSettings]);
|
}, [displayColumnsConfig, handleUpdateSettings]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="sf-metadata-view-kanban-setting-panel">
|
<div className="sf-metadata-view-card-setting-panel">
|
||||||
<div className="setting-panel-header">
|
<div className="setting-panel-header">
|
||||||
<h5 className="m-0">{gettext('Settings')}</h5>
|
<h5 className="m-0">{gettext('Settings')}</h5>
|
||||||
<OpIcon className='sf3-font sf3-font-x-01 op-icon' op={onClose} title={gettext('Close')} />
|
<OpIcon className='sf3-font sf3-font-x-01 op-icon' op={onClose} title={gettext('Close')} />
|
||||||
</div>
|
</div>
|
||||||
<div className="setting-panel-body">
|
<div className="setting-panel-body">
|
||||||
<div className="setting-item">
|
|
||||||
<span className="setting-item-label">{gettext('Group by')}</span>
|
|
||||||
<Selector
|
|
||||||
settingKey={KANBAN_SETTINGS_KEYS.GROUP_BY_COLUMN_KEY}
|
|
||||||
value={settings[KANBAN_SETTINGS_KEYS.GROUP_BY_COLUMN_KEY]}
|
|
||||||
defaultValue={groupByColumnOptions[0]?.value}
|
|
||||||
options={groupByColumnOptions}
|
|
||||||
onChange={handleUpdateSettings}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="sf-metadata-setting-divide-line"></div>
|
|
||||||
<div className="setting-item">
|
|
||||||
<span className="setting-item-label">{gettext('Title property')}</span>
|
|
||||||
<Selector
|
|
||||||
settingKey={KANBAN_SETTINGS_KEYS.TITLE_COLUMN_KEY}
|
|
||||||
value={settings[KANBAN_SETTINGS_KEYS.TITLE_COLUMN_KEY]}
|
|
||||||
options={titleColumnOptions}
|
|
||||||
onChange={handleUpdateSettings}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="sf-metadata-setting-divide-line"></div>
|
|
||||||
<div className="setting-item">
|
<div className="setting-item">
|
||||||
<Switch
|
<Switch
|
||||||
placeholder={gettext('Don\'t show empty values')}
|
placeholder={gettext('Don\'t show empty values')}
|
||||||
checked={settings[KANBAN_SETTINGS_KEYS.HIDE_EMPTY_VALUE] || false}
|
checked={settings[CARD_SETTINGS_KEYS.HIDE_EMPTY_VALUE] || false}
|
||||||
onChange={() => handleUpdateSettings(KANBAN_SETTINGS_KEYS.HIDE_EMPTY_VALUE, !settings[KANBAN_SETTINGS_KEYS.HIDE_EMPTY_VALUE])}
|
onChange={() => handleUpdateSettings(CARD_SETTINGS_KEYS.HIDE_EMPTY_VALUE, !settings[CARD_SETTINGS_KEYS.HIDE_EMPTY_VALUE])}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="sf-metadata-setting-divide-line"></div>
|
<div className="sf-metadata-setting-divide-line"></div>
|
||||||
<div className="setting-item">
|
<div className="setting-item">
|
||||||
<Switch
|
<Switch
|
||||||
placeholder={gettext('Show property names')}
|
placeholder={gettext('Show property names')}
|
||||||
checked={settings[KANBAN_SETTINGS_KEYS.SHOW_COLUMN_NAME] || false}
|
checked={settings[CARD_SETTINGS_KEYS.SHOW_COLUMN_NAME] || false}
|
||||||
onChange={() => handleUpdateSettings(KANBAN_SETTINGS_KEYS.SHOW_COLUMN_NAME, !settings[KANBAN_SETTINGS_KEYS.SHOW_COLUMN_NAME])}
|
onChange={() => handleUpdateSettings(CARD_SETTINGS_KEYS.SHOW_COLUMN_NAME, !settings[CARD_SETTINGS_KEYS.SHOW_COLUMN_NAME])}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="sf-metadata-setting-divide-line"></div>
|
<div className="sf-metadata-setting-divide-line"></div>
|
||||||
<div className="setting-item">
|
<div className="setting-item">
|
||||||
<Switch
|
<Switch
|
||||||
placeholder={gettext('Text wraps')}
|
placeholder={gettext('Text wraps')}
|
||||||
checked={settings[KANBAN_SETTINGS_KEYS.TEXT_WRAP] || false}
|
checked={settings[CARD_SETTINGS_KEYS.TEXT_WRAP] || false}
|
||||||
onChange={() => handleUpdateSettings(KANBAN_SETTINGS_KEYS.TEXT_WRAP, !settings[KANBAN_SETTINGS_KEYS.TEXT_WRAP])}
|
onChange={() => handleUpdateSettings(CARD_SETTINGS_KEYS.TEXT_WRAP, !settings[CARD_SETTINGS_KEYS.TEXT_WRAP])}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="sf-metadata-setting-divide-line"></div>
|
<div className="sf-metadata-setting-divide-line"></div>
|
||||||
|
Reference in New Issue
Block a user