duoyun-ui
Version:
A lightweight desktop UI component library, implemented using Gem
751 lines • 42.9 kB
JavaScript
/** biome-ignore-all lint/complexity/useOptionalChain: type maybe is false */
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
var _, done = false;
for (var i = decorators.length - 1; i >= 0; i--) {
var context = {};
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
if (kind === "accessor") {
if (result === void 0) continue;
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
if (_ = accept(result.get)) descriptor.get = _;
if (_ = accept(result.set)) descriptor.set = _;
if (_ = accept(result.init)) initializers.unshift(_);
}
else if (_ = accept(result)) {
if (kind === "field") initializers.unshift(_);
else descriptor[key] = _;
}
}
if (target) Object.defineProperty(target, contextIn.name, descriptor);
done = true;
};
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
var useValue = arguments.length > 2;
for (var i = 0; i < initializers.length; i++) {
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
}
return useValue ? value : void 0;
};
import { adoptedStyle, boolattribute, connectStore, customElement, effect, emitter, memo, numattribute, property, shadow, } from '@mantou/gem/lib/decorators';
import { createRef, createState, css, GemElement, html } from '@mantou/gem/lib/element';
import { history } from '@mantou/gem/lib/history';
import { connect } from '@mantou/gem/lib/store';
import { addListener, QueryString, styleMap } from '@mantou/gem/lib/utils';
import { ContextMenu } from '../elements/contextmenu';
import { closestElement, findRanges, findScrollContainer } from '../lib/element';
import { hotkeys } from '../lib/hotkeys';
import { icons } from '../lib/icons';
import { locale } from '../lib/locale';
import { blockContainer } from '../lib/styles';
import { theme } from '../lib/theme';
import { formatDuration, Time } from '../lib/time';
import { sleep, throttle } from '../lib/timer';
import { isNotBoolean } from '../lib/types';
import { ComparerType, comparer, convertToMap, getStringFromTemplate, isIncludesString, readProp, splitString, } from '../lib/utils';
import { locationStore } from './console';
import '../elements/button';
import '../elements/input';
import '../elements/loading';
import '../elements/pagination';
import '../elements/scroll-box';
import '../elements/table';
import '../elements/tag';
import './filter-form';
// 不能和外部冲突
const queryKeys = {
PAGINATION_PAGE: '_dy_page',
PAGINATION_SIZE: '_dy_size',
SEARCH: '_dy_search',
FILTERS: '_dy_filters',
SORT: '_dy_sort',
};
function getNextSort(current) {
switch (current) {
case 'asc':
return 'des';
case 'des':
return;
default:
return 'asc';
}
}
const style = css `
.searchbar {
display: flex;
align-items: center;
gap: 1em;
margin-block-end: calc(1 * ${theme.gridGutter});
}
.search {
border-width: 2px;
}
.filters {
position: relative;
display: flex;
flex-grow: 1;
gap: 1em;
width: 0;
white-space: nowrap;
}
.comparer {
color: ${theme.highlightColor};
}
.pagination {
margin-block-start: ${theme.gridGutter};
}
.updating {
position: fixed;
right: 1rem;
bottom: 1rem;
}
`;
/**
* !WARNING
*
* field not contain `,`, `filters` field and `sort` key use `,` split
*/
let DyPatTableElement = (() => {
let _classDecorators = [customElement('dy-pat-table'), adoptedStyle(style), adoptedStyle(blockContainer), connectStore(locationStore), shadow()];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
let _classSuper = GemElement;
let _filterable_decorators;
let _filterable_initializers = [];
let _filterable_extraInitializers = [];
let _selectable_decorators;
let _selectable_initializers = [];
let _selectable_extraInitializers = [];
let _pagesize_decorators;
let _pagesize_initializers = [];
let _pagesize_extraInitializers = [];
let _sizes_decorators;
let _sizes_initializers = [];
let _sizes_extraInitializers = [];
let _data_decorators;
let _data_initializers = [];
let _data_extraInitializers = [];
let _paginationStore_decorators;
let _paginationStore_initializers = [];
let _paginationStore_extraInitializers = [];
let _locationStore_decorators;
let _locationStore_initializers = [];
let _locationStore_extraInitializers = [];
let _rowKey_decorators;
let _rowKey_initializers = [];
let _rowKey_extraInitializers = [];
let _getRowStyle_decorators;
let _getRowStyle_initializers = [];
let _getRowStyle_extraInitializers = [];
let _expandedRowRender_decorators;
let _expandedRowRender_initializers = [];
let _expandedRowRender_extraInitializers = [];
let _getActions_decorators;
let _getActions_initializers = [];
let _getActions_extraInitializers = [];
let _getSelectedActions_decorators;
let _getSelectedActions_initializers = [];
let _getSelectedActions_extraInitializers = [];
let _expand_decorators;
let _expand_initializers = [];
let _expand_extraInitializers = [];
let _fetch_decorators;
let _fetch_initializers = [];
let _fetch_extraInitializers = [];
let _columns_decorators;
let _columns_initializers = [];
let _columns_extraInitializers = [];
let _getText_decorators;
let _getText_initializers = [];
let _getText_extraInitializers = [];
let _private_setSelectionContainer_decorators;
let _private_setSelectionContainer_initializers = [];
let _private_setSelectionContainer_extraInitializers = [];
let _private_setColumns_decorators;
let _private_setColumns_initializers = [];
let _private_setColumns_extraInitializers = [];
let _private_setFilterFieldEnumMap_decorators;
let _private_setFilterFieldEnumMap_initializers = [];
let _private_setFilterFieldEnumMap_extraInitializers = [];
let _private_setData_decorators;
let _private_setData_initializers = [];
let _private_setData_extraInitializers = [];
let _private_addListener_decorators;
let _private_addListener_initializers = [];
let _private_addListener_extraInitializers = [];
let _private_connectPaginationStore_decorators;
let _private_connectPaginationStore_initializers = [];
let _private_connectPaginationStore_extraInitializers = [];
let _private_connectLocationStore_decorators;
let _private_connectLocationStore_initializers = [];
let _private_connectLocationStore_extraInitializers = [];
let _private_emitterEvent_decorators;
let _private_emitterEvent_initializers = [];
let _private_emitterEvent_extraInitializers = [];
let _private_setHighlights_decorators;
let _private_setHighlights_initializers = [];
let _private_setHighlights_extraInitializers = [];
var DyPatTableElement = class extends _classSuper {
static { _classThis = this; }
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
_filterable_decorators = [boolattribute];
_selectable_decorators = [boolattribute];
_pagesize_decorators = [numattribute];
_sizes_decorators = [property];
_data_decorators = [property];
_paginationStore_decorators = [property];
_locationStore_decorators = [property];
_rowKey_decorators = [property];
_getRowStyle_decorators = [property];
_expandedRowRender_decorators = [property];
_getActions_decorators = [property];
_getSelectedActions_decorators = [property];
_expand_decorators = [emitter];
_fetch_decorators = [emitter];
_columns_decorators = [property];
_getText_decorators = [property];
_private_setSelectionContainer_decorators = [memo((i) => [i.selectable])];
_private_setColumns_decorators = [memo((i) => [i.columns, i.#state.sort])];
_private_setFilterFieldEnumMap_decorators = [memo((i) => [i.columns])];
_private_setData_decorators = [memo((i) => [(i.locationStore || locationStore).query, i.columns, i.data])];
_private_addListener_decorators = [effect((i) => [i.selectable])];
_private_connectPaginationStore_decorators = [effect((i) => [i.paginationStore])];
_private_connectLocationStore_decorators = [effect((i) => [i.locationStore])];
_private_emitterEvent_decorators = [effect((i) => i.#getEmitterEventDeps())];
_private_setHighlights_decorators = [effect((i) => [i.paginationStore ? i.paginationStore.pagination[i.#page]?.ids : i.#search])];
__esDecorate(null, null, _filterable_decorators, { kind: "field", name: "filterable", static: false, private: false, access: { has: obj => "filterable" in obj, get: obj => obj.filterable, set: (obj, value) => { obj.filterable = value; } }, metadata: _metadata }, _filterable_initializers, _filterable_extraInitializers);
__esDecorate(null, null, _selectable_decorators, { kind: "field", name: "selectable", static: false, private: false, access: { has: obj => "selectable" in obj, get: obj => obj.selectable, set: (obj, value) => { obj.selectable = value; } }, metadata: _metadata }, _selectable_initializers, _selectable_extraInitializers);
__esDecorate(null, null, _pagesize_decorators, { kind: "field", name: "pagesize", static: false, private: false, access: { has: obj => "pagesize" in obj, get: obj => obj.pagesize, set: (obj, value) => { obj.pagesize = value; } }, metadata: _metadata }, _pagesize_initializers, _pagesize_extraInitializers);
__esDecorate(null, null, _sizes_decorators, { kind: "field", name: "sizes", static: false, private: false, access: { has: obj => "sizes" in obj, get: obj => obj.sizes, set: (obj, value) => { obj.sizes = value; } }, metadata: _metadata }, _sizes_initializers, _sizes_extraInitializers);
__esDecorate(null, null, _data_decorators, { kind: "field", name: "data", static: false, private: false, access: { has: obj => "data" in obj, get: obj => obj.data, set: (obj, value) => { obj.data = value; } }, metadata: _metadata }, _data_initializers, _data_extraInitializers);
__esDecorate(null, null, _paginationStore_decorators, { kind: "field", name: "paginationStore", static: false, private: false, access: { has: obj => "paginationStore" in obj, get: obj => obj.paginationStore, set: (obj, value) => { obj.paginationStore = value; } }, metadata: _metadata }, _paginationStore_initializers, _paginationStore_extraInitializers);
__esDecorate(null, null, _locationStore_decorators, { kind: "field", name: "locationStore", static: false, private: false, access: { has: obj => "locationStore" in obj, get: obj => obj.locationStore, set: (obj, value) => { obj.locationStore = value; } }, metadata: _metadata }, _locationStore_initializers, _locationStore_extraInitializers);
__esDecorate(null, null, _rowKey_decorators, { kind: "field", name: "rowKey", static: false, private: false, access: { has: obj => "rowKey" in obj, get: obj => obj.rowKey, set: (obj, value) => { obj.rowKey = value; } }, metadata: _metadata }, _rowKey_initializers, _rowKey_extraInitializers);
__esDecorate(null, null, _getRowStyle_decorators, { kind: "field", name: "getRowStyle", static: false, private: false, access: { has: obj => "getRowStyle" in obj, get: obj => obj.getRowStyle, set: (obj, value) => { obj.getRowStyle = value; } }, metadata: _metadata }, _getRowStyle_initializers, _getRowStyle_extraInitializers);
__esDecorate(null, null, _expandedRowRender_decorators, { kind: "field", name: "expandedRowRender", static: false, private: false, access: { has: obj => "expandedRowRender" in obj, get: obj => obj.expandedRowRender, set: (obj, value) => { obj.expandedRowRender = value; } }, metadata: _metadata }, _expandedRowRender_initializers, _expandedRowRender_extraInitializers);
__esDecorate(null, null, _getActions_decorators, { kind: "field", name: "getActions", static: false, private: false, access: { has: obj => "getActions" in obj, get: obj => obj.getActions, set: (obj, value) => { obj.getActions = value; } }, metadata: _metadata }, _getActions_initializers, _getActions_extraInitializers);
__esDecorate(null, null, _getSelectedActions_decorators, { kind: "field", name: "getSelectedActions", static: false, private: false, access: { has: obj => "getSelectedActions" in obj, get: obj => obj.getSelectedActions, set: (obj, value) => { obj.getSelectedActions = value; } }, metadata: _metadata }, _getSelectedActions_initializers, _getSelectedActions_extraInitializers);
__esDecorate(null, null, _expand_decorators, { kind: "field", name: "expand", static: false, private: false, access: { has: obj => "expand" in obj, get: obj => obj.expand, set: (obj, value) => { obj.expand = value; } }, metadata: _metadata }, _expand_initializers, _expand_extraInitializers);
__esDecorate(null, null, _fetch_decorators, { kind: "field", name: "fetch", static: false, private: false, access: { has: obj => "fetch" in obj, get: obj => obj.fetch, set: (obj, value) => { obj.fetch = value; } }, metadata: _metadata }, _fetch_initializers, _fetch_extraInitializers);
__esDecorate(null, null, _columns_decorators, { kind: "field", name: "columns", static: false, private: false, access: { has: obj => "columns" in obj, get: obj => obj.columns, set: (obj, value) => { obj.columns = value; } }, metadata: _metadata }, _columns_initializers, _columns_extraInitializers);
__esDecorate(null, null, _getText_decorators, { kind: "field", name: "getText", static: false, private: false, access: { has: obj => "getText" in obj, get: obj => obj.getText, set: (obj, value) => { obj.getText = value; } }, metadata: _metadata }, _getText_initializers, _getText_extraInitializers);
__esDecorate(null, null, _private_setSelectionContainer_decorators, { kind: "field", name: "#setSelectionContainer", static: false, private: true, access: { has: obj => #setSelectionContainer in obj, get: obj => obj.#setSelectionContainer, set: (obj, value) => { obj.#setSelectionContainer = value; } }, metadata: _metadata }, _private_setSelectionContainer_initializers, _private_setSelectionContainer_extraInitializers);
__esDecorate(null, null, _private_setColumns_decorators, { kind: "field", name: "#setColumns", static: false, private: true, access: { has: obj => #setColumns in obj, get: obj => obj.#setColumns, set: (obj, value) => { obj.#setColumns = value; } }, metadata: _metadata }, _private_setColumns_initializers, _private_setColumns_extraInitializers);
__esDecorate(null, null, _private_setFilterFieldEnumMap_decorators, { kind: "field", name: "#setFilterFieldEnumMap", static: false, private: true, access: { has: obj => #setFilterFieldEnumMap in obj, get: obj => obj.#setFilterFieldEnumMap, set: (obj, value) => { obj.#setFilterFieldEnumMap = value; } }, metadata: _metadata }, _private_setFilterFieldEnumMap_initializers, _private_setFilterFieldEnumMap_extraInitializers);
__esDecorate(null, null, _private_setData_decorators, { kind: "field", name: "#setData", static: false, private: true, access: { has: obj => #setData in obj, get: obj => obj.#setData, set: (obj, value) => { obj.#setData = value; } }, metadata: _metadata }, _private_setData_initializers, _private_setData_extraInitializers);
__esDecorate(null, null, _private_addListener_decorators, { kind: "field", name: "#addListener", static: false, private: true, access: { has: obj => #addListener in obj, get: obj => obj.#addListener, set: (obj, value) => { obj.#addListener = value; } }, metadata: _metadata }, _private_addListener_initializers, _private_addListener_extraInitializers);
__esDecorate(null, null, _private_connectPaginationStore_decorators, { kind: "field", name: "#connectPaginationStore", static: false, private: true, access: { has: obj => #connectPaginationStore in obj, get: obj => obj.#connectPaginationStore, set: (obj, value) => { obj.#connectPaginationStore = value; } }, metadata: _metadata }, _private_connectPaginationStore_initializers, _private_connectPaginationStore_extraInitializers);
__esDecorate(null, null, _private_connectLocationStore_decorators, { kind: "field", name: "#connectLocationStore", static: false, private: true, access: { has: obj => #connectLocationStore in obj, get: obj => obj.#connectLocationStore, set: (obj, value) => { obj.#connectLocationStore = value; } }, metadata: _metadata }, _private_connectLocationStore_initializers, _private_connectLocationStore_extraInitializers);
__esDecorate(null, null, _private_emitterEvent_decorators, { kind: "field", name: "#emitterEvent", static: false, private: true, access: { has: obj => #emitterEvent in obj, get: obj => obj.#emitterEvent, set: (obj, value) => { obj.#emitterEvent = value; } }, metadata: _metadata }, _private_emitterEvent_initializers, _private_emitterEvent_extraInitializers);
__esDecorate(null, null, _private_setHighlights_decorators, { kind: "field", name: "#setHighlights", static: false, private: true, access: { has: obj => #setHighlights in obj, get: obj => obj.#setHighlights, set: (obj, value) => { obj.#setHighlights = value; } }, metadata: _metadata }, _private_setHighlights_initializers, _private_setHighlights_extraInitializers);
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
DyPatTableElement = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
}
filterable = __runInitializers(this, _filterable_initializers, void 0);
selectable = (__runInitializers(this, _filterable_extraInitializers), __runInitializers(this, _selectable_initializers, void 0));
// 默认 pagesize
pagesize = (__runInitializers(this, _selectable_extraInitializers), __runInitializers(this, _pagesize_initializers, void 0));
sizes = (__runInitializers(this, _pagesize_extraInitializers), __runInitializers(this, _sizes_initializers, void 0));
data = (__runInitializers(this, _sizes_extraInitializers), __runInitializers(this, _data_initializers, void 0));
paginationStore = (__runInitializers(this, _data_extraInitializers), __runInitializers(this, _paginationStore_initializers, void 0));
// 如果不在 dy-pat-console 中,则需要提供 `locationStore`
locationStore = (__runInitializers(this, _paginationStore_extraInitializers), __runInitializers(this, _locationStore_initializers, void 0));
rowKey = (__runInitializers(this, _locationStore_extraInitializers), __runInitializers(this, _rowKey_initializers, void 0));
getRowStyle = (__runInitializers(this, _rowKey_extraInitializers), __runInitializers(this, _getRowStyle_initializers, void 0));
expandedRowRender = (__runInitializers(this, _getRowStyle_extraInitializers), __runInitializers(this, _expandedRowRender_initializers, void 0));
getActions = (__runInitializers(this, _expandedRowRender_extraInitializers), __runInitializers(this, _getActions_initializers, void 0));
getSelectedActions = (__runInitializers(this, _getActions_extraInitializers), __runInitializers(this, _getSelectedActions_initializers, void 0));
expand = (__runInitializers(this, _getSelectedActions_extraInitializers), __runInitializers(this, _expand_initializers, void 0));
fetch = (__runInitializers(this, _expand_extraInitializers), __runInitializers(this, _fetch_initializers, void 0));
columns = (__runInitializers(this, _fetch_extraInitializers), __runInitializers(this, _columns_initializers, []));
getText = (__runInitializers(this, _columns_extraInitializers), __runInitializers(this, _getText_initializers, (e) => e.replace(/([A-Z])/g, ' $1').replace(/^\w/, ($1) => $1.toUpperCase())));
#tableRef = (__runInitializers(this, _getText_extraInitializers), createRef());
get #defaultPagesize() {
return this.pagesize || this.sizes?.[0] || 20;
}
get #defaultPage() {
return 1;
}
get #page() {
return Number(history.getParams().query.get(queryKeys.PAGINATION_PAGE)) || this.#defaultPage;
}
get #size() {
return Number(history.getParams().query.get(queryKeys.PAGINATION_SIZE)) || this.#defaultPagesize;
}
get #search() {
return history.getParams().query.get(queryKeys.SEARCH) || '';
}
get #filters() {
return history.getParams().query.getAnyAll(queryKeys.FILTERS);
}
get #sort() {
return history.getParams().query.getAny(queryKeys.SORT) || {};
}
#state = createState({
selection: [],
search: this.#search,
filters: this.#filters,
sort: this.#sort,
});
#data = [];
#onSelect = (evt) => this.#state({ selection: evt.detail });
#onContextMenu = (originEvent, currentRowData, selected) => {
if (originEvent.altKey)
return;
if (!this.selectable)
return;
const table = this.#tableRef.value;
const { selection } = this.#state;
originEvent.stopPropagation();
originEvent.preventDefault();
const currentRowMenu = !currentRowData
? []
: [
selected
? {
text: this.getText('removeItemFromSelection'),
handle: () => table.removeSelection([currentRowData]),
}
: {
text: this.getText('addToSelection'),
handle: () => table.appendSelection([currentRowData]),
},
];
const unSelectionMenu = [
...currentRowMenu,
{
text: this.getText('addPageAllToSelection'),
handle: () => table.appendSelection(this.#getPageData().data || []),
},
!this.paginationStore && {
text: this.getText('addAllToSelection'),
handle: () => table.appendSelection(this.#data || []),
},
].filter(isNotBoolean);
const userCustomMenu = this.getSelectedActions?.(selection);
ContextMenu.open(selection.length
? [
{
text: this.getText('removeAllSelection'),
handle: () => this.#state({ selection: [] }),
},
...currentRowMenu,
...(userCustomMenu ? [{ text: '---' }, ...userCustomMenu] : []).map((item) => ({
...item,
handle: async () => {
await item.handle?.(currentRowData);
this.#state({ selection: [] });
},
})),
]
: unSelectionMenu, {
activeElement: originEvent.target,
x: originEvent.x,
y: originEvent.y,
});
};
#onItemContextMenu = (evt) => {
const { data, originEvent, selected } = evt.detail;
this.#onContextMenu(originEvent, data, selected);
};
#getPageData = () => {
const page = this.#page;
const size = this.#size;
const total = this.paginationStore
? this.paginationStore.total
: this.#data
? Math.ceil(this.#data.length / size)
: 0;
const data = this.paginationStore
? this.paginationStore.getData(page)
: this.#data?.slice((page - 1) * size, page * size);
const updating = data &&
(this.paginationStore
? this.paginationStore.isLoading(page)
: // 只有一个全局数据请求,简单起见,不显示更新标识
false);
return { total, data, size, page, updating };
};
#createChangeFunction = (key, getDefaultValue) => {
return ({ detail }) => {
const p = history.getParams();
const query = new QueryString(p.query);
if (detail === getDefaultValue()) {
query.delete(key);
}
else {
query.set(key, String(detail));
}
history.push({ ...p, query });
findScrollContainer(this)?.scrollTo(0, 0);
};
};
#onPageChange = this.#createChangeFunction(queryKeys.PAGINATION_PAGE, () => this.#defaultPage);
#onSizeChange = this.#createChangeFunction(queryKeys.PAGINATION_SIZE, () => this.#defaultPagesize);
#changeQuery = () => {
const p = history.getParams();
const query = new QueryString(p.query);
query.setAny(queryKeys.SEARCH, this.#state.search);
query.setAny(queryKeys.FILTERS, this.#state.filters);
query.delete(queryKeys.PAGINATION_PAGE);
query.delete(queryKeys.PAGINATION_SIZE);
history.replace({ ...p, query, hash: '' });
};
#changeQueryThrottle = throttle(this.#changeQuery, 120);
#onSearch = (evt) => {
this.#state({ search: evt.detail });
this.#changeQueryThrottle();
evt.stopPropagation();
};
#onKeydown = (evt) => {
hotkeys({
esc: () => {
this.#state({ search: '' });
this.#changeQueryThrottle();
},
})(evt);
};
#onSwitchSort = (field) => {
const { sort } = this.#state;
const newSort = { ...sort };
delete newSort[field];
this.#state({ sort: { ...newSort, [field]: getNextSort(sort[field]) } });
const p = history.getParams();
const query = new QueryString(p.query);
if (JSON.stringify(this.#state.sort) === '{}') {
query.delete(queryKeys.SORT);
}
else {
query.setAny(queryKeys.SORT, this.#state.sort);
}
history.replace({ ...p, query });
};
#onAddFilter = (data) => {
ContextMenu.close();
this.#state({ filters: [...this.#state.filters, data] });
this.#changeQuery();
};
#onRemoveFilter = (index) => {
this.#state.filters.splice(index, 1);
this.#changeQuery();
};
#onModifyFilter = (index, data) => {
ContextMenu.close();
this.#state.filters.splice(index, 1, data);
this.#changeQuery();
};
#getMenuWidth = ({ filterOptions }) => {
if (filterOptions === false)
return;
if (filterOptions?.width)
return filterOptions?.width;
switch (filterOptions?.type) {
case 'date-time':
return '26em';
default:
return '15em';
}
};
#getFilterField = ({ filterOptions, dataIndex }) => {
return filterOptions === false ? '' : String(filterOptions?.field || dataIndex);
};
#onClickFilter = (evt, index) => {
const { field, cType, value } = this.#state.filters[index];
const column = this.columns.find((col) => this.#getFilterField(col) === field);
const tagEle = evt.currentTarget;
const offsetEle = tagEle.offsetParent;
ContextMenu.open(html `
<dy-pat-filter-form
.getText=${this.getText}
.options=${column.filterOptions || undefined}
.initValue=${{ comparerType: cType, value }}
=${({ detail }) => this.#onModifyFilter(index, { cType: detail.comparerType, value: detail.value, field })}
></dy-pat-filter-form>
`, {
activeElement: tagEle.offsetLeft > offsetEle.scrollLeft ? tagEle : offsetEle,
width: this.#getMenuWidth(column),
});
};
#onOpenFilter = (e) => {
ContextMenu.open(this.columns
.filter((column) => column.title && !!this.#getFilterField(column))
.map((column) => ({
text: getStringFromTemplate(column.title),
menu: {
width: this.#getMenuWidth(column),
menu: html `
<dy-pat-filter-form
.getText=${this.getText}
.options=${column.filterOptions || undefined}
=${({ detail }) => this.#onAddFilter({
cType: detail.comparerType,
value: detail.value,
field: this.#getFilterField(column),
})}
></dy-pat-filter-form>
`,
},
})), { activeElement: e.currentTarget });
};
#getValueFromField = (field, value) => {
return [].concat(value).map((e) => {
const filterOptions = this.#filterFieldOptionsMap[field];
switch (filterOptions && filterOptions?.type) {
case 'date':
return new Time(Number(e)).format('YYYY-MM-DD');
case 'date-time':
return new Time(Number(e)).format();
case 'time':
return formatDuration(e, { numeric: true });
case 'duration':
return formatDuration(e);
default:
return this.#filterFieldEnumMap[field]?.[e] || e;
}
});
};
#selectionContainer;
#setSelectionContainer = __runInitializers(this, _private_setSelectionContainer_initializers, () => {
this.#selectionContainer = (this.selectable && closestElement(this, 'main')) || undefined;
});
#columns = (__runInitializers(this, _private_setSelectionContainer_extraInitializers), []);
#setColumns = __runInitializers(this, _private_setColumns_initializers, () => {
const { sort } = this.#state;
this.#columns = this.columns.map((column, _index, _arr, field = String(column.dataIndex), status = sort[field]) => ({
...column,
title: column.sortable && column.title && column.dataIndex
? html `
<div
style=${styleMap({ cursor: 'pointer', display: 'flex', gap: '.3em' })}
=${() => this.#onSwitchSort(field)}
>
${column.title}
<dy-use style="width: 1em" .element=${icons.sort}>
<style>
{
:scope::part(up),
:scope::part(down) {
opacity: 0.2;
}
:scope::part(${!status ? '' : status === 'asc' ? 'up' : 'down'}) {
opacity: 1;
}
}
</style>
</dy-use>
</div>
`
: column.title,
}));
});
#filterFieldOptionsMap = (__runInitializers(this, _private_setColumns_extraInitializers), {});
#filterFieldLabelMap = {};
#filterFieldEnumMap = {};
// 显示正确的过滤器文本
#setFilterFieldEnumMap = __runInitializers(this, _private_setFilterFieldEnumMap_initializers, () => {
this.columns.forEach((column) => {
const { title, filterOptions } = column;
const field = this.#getFilterField(column);
this.#filterFieldOptionsMap[field] = filterOptions;
this.#filterFieldLabelMap[field] = typeof title === 'string' ? title : getStringFromTemplate(title);
const enums = filterOptions && filterOptions.getOptions?.('');
if (enums) {
this.#filterFieldEnumMap[field] = convertToMap(enums, 'value', 'label');
}
});
});
// 搜索和过滤数据,如果服务端分页,则跳过
#setData = (__runInitializers(this, _private_setFilterFieldEnumMap_extraInitializers), __runInitializers(this, _private_setData_initializers, () => {
this.#data = this.data;
if (this.paginationStore)
return;
if (!this.#data)
return;
const { search, filters, sort } = this.#state;
if (search) {
this.#data = this.#data.filter((e) => {
if (!e)
return true;
const str = this.columns
.filter(({ title }) => !!title)
.map(({ dataIndex, render, filterOptions }) => {
if (filterOptions && filterOptions.getSearchText)
return filterOptions.getSearchText(e);
if (dataIndex)
return readProp(e, dataIndex);
if (render) {
const result = render(e);
return typeof result === 'string' ? result : '';
}
return '';
})
.join();
return isIncludesString(str, search);
});
}
this.#data = this.#data?.filter((filter) => {
return filters.every(({ field, cType, value }) => {
if (!filter)
return true;
const filterOptions = this.#filterFieldOptionsMap[field];
const fieldValue = filterOptions && filterOptions.getCompareValue
? filterOptions.getCompareValue(filter)
: readProp(filter, field.split(','));
if (Array.isArray(value)) {
if (Array.isArray(fieldValue))
return fieldValue.some((e) => comparer(value, cType, e));
return comparer(value, cType, fieldValue);
}
return comparer(String(fieldValue || '').toLowerCase(), cType, String(value || '').toLowerCase());
});
});
Object.entries(sort).forEach(([field, sortType]) => {
if (!sortType)
return;
this.#data?.sort((a, b) => {
if (!a || !b)
return 0;
const [aa, bb] = sortType === 'asc' ? [a, b] : [b, a];
const dataIndex = field.split(',');
return comparer(readProp(aa, dataIndex), ComparerType.Gte, readProp(bb, dataIndex)) ? 1 : -1;
});
});
}));
#addListener = (__runInitializers(this, _private_setData_extraInitializers), __runInitializers(this, _private_addListener_initializers, () => {
if (this.#selectionContainer) {
return addListener(this.#selectionContainer, 'contextmenu', this.#onContextMenu);
}
}));
#connectPaginationStore = (__runInitializers(this, _private_addListener_extraInitializers), __runInitializers(this, _private_connectPaginationStore_initializers, () => this.paginationStore && connect(this.paginationStore, this.update)));
#connectLocationStore = (__runInitializers(this, _private_connectPaginationStore_extraInitializers), __runInitializers(this, _private_connectLocationStore_initializers, () => this.locationStore && connect(this.locationStore, this.update)));
#getEmitterEventDeps = (__runInitializers(this, _private_connectLocationStore_extraInitializers), () => {
const { path, query } = this.locationStore || locationStore;
return [
this.paginationStore?.updatedItem,
query.get(queryKeys.PAGINATION_PAGE),
query.get(queryKeys.PAGINATION_SIZE),
query.get(queryKeys.FILTERS),
query.get(queryKeys.SORT),
query.get(queryKeys.SEARCH),
path,
];
});
#emitterEvent = __runInitializers(this, _private_emitterEvent_initializers, () => {
const { search, filters, sort } = this.#state;
const sorts = Object.entries(sort).filter(([_, v]) => v);
this.fetch({
sort,
search,
filters,
page: this.#page,
size: this.#size,
...locationStore,
...this.locationStore,
pageKey: search || filters.length || sorts.length
? `${search}-${filters
.sort((a, b) => (a.field > b.field ? 1 : 0))
.map(({ field, cType, value }) => `${field}-${cType}-${value}`)
.join()}-${sorts
.sort(([k], [kk]) => (k > kk ? 1 : 0))
.map((e) => e.join('-'))
.join()}`
: '',
});
});
// search 进行了节流,所以是依赖 query
#setHighlights = (__runInitializers(this, _private_emitterEvent_extraInitializers), __runInitializers(this, _private_setHighlights_initializers, async () => {
await sleep(1);
const { search } = this.#state;
const Highlight = window.Highlight;
const highlights = CSS.highlights;
if (!Highlight || !highlights)
return;
if (!search)
return highlights.clear();
const tbody = this.#tableRef.value?.shadowRoot?.querySelector('tbody');
if (!tbody)
return;
const highlight = new Highlight();
splitString(search).forEach((s) => {
findRanges(tbody, s).forEach((range) => highlight.add(range));
});
highlights.set('search', highlight);
}));
render = (__runInitializers(this, _private_setHighlights_extraInitializers), () => {
const { data, page, size, total, updating } = this.#getPageData();
return html `
<div class="searchbar" part="searchbar">
<dy-input
class="search"
type="search"
placeholder=${locale.search}
clearable
=${this.#onSearch}
=${this.#onSearch}
=${this.#onKeydown}
.value=${this.#state.search}
></dy-input>
<dy-button v-if=${this.filterable} color="cancel" =${this.#onOpenFilter} .icon=${icons.filter}>
${this.getText('filter')}
</dy-button>
<dy-scroll-box class="filters" part="filters">
${this.#state.filters.map(({ field, value, cType }, index) => html `
<dy-tag
=${(evt) => evt.preventDefault()}
=${(evt) => this.#onClickFilter(evt, index)}
=${() => this.#onRemoveFilter(index)}
closable
>
<span>${this.#filterFieldLabelMap[field]}</span>
<span class="comparer">${this.getText(cType)}</span>
<span>"${this.#getValueFromField(field, value).join(', ')}"</span>
</dy-tag>
`)}
</dy-scroll-box>
<slot></slot>
</div>
<dy-table
${this.#tableRef}
part="table-wrap"
exportparts="table,tr,td,th"
.getRowStyle=${this.getRowStyle}
.getActions=${this.getActions}
.expandedRowRender=${this.expandedRowRender}
.data=${data}
.columns=${this.#columns}
.selectable=${this.selectable}
.rowKey=${this.rowKey}
.selection=${this.#state.selection}
.selectionContainer=${this.#selectionContainer}
=${this.#onSelect}
=${(evt) => this.expand(evt.detail)}
=${this.#onItemContextMenu}
></dy-table>
<dy-loading class="updating" ?hidden=${!updating}></dy-loading>
<dy-pagination
class="pagination"
part="pagination"
=${this.#onPageChange}
=${this.#onSizeChange}
.page=${page}
.size=${size}
.sizes=${this.sizes && this.sizes.length > 1 ? this.sizes : undefined}
.total=${total}
></dy-pagination>
`;
});
};
return DyPatTableElement = _classThis;
})();
export { DyPatTableElement };
//# sourceMappingURL=table.js.map