Skip to content

Commit

Permalink
Merge branch 'develop' into feature/anchor-getCurrentAnchor
Browse files Browse the repository at this point in the history
  • Loading branch information
ontheroad1992 committed Aug 21, 2023
2 parents 873de0d + 416d007 commit 02cc527
Show file tree
Hide file tree
Showing 22 changed files with 196 additions and 39 deletions.
2 changes: 1 addition & 1 deletion docs/web/api/select-input.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ spline: data

### 可调整下拉框宽度的筛选器输入框

下拉框宽度规则:下拉框宽度默认和触发元素宽度保持同宽,如果下拉框宽度超出输入框组件会自动撑开下拉框宽度,但最大宽度不超过 `1000px`。也可以通过 `popupProps.overlayStyle.width` 自由设置下拉框宽度。`popupProps.overlayStyle` 类型为函数时,可以更灵活地动态控制下拉框宽度。
下拉框宽度规则:下拉框宽度默认和触发元素宽度保持同宽,如果下拉框宽度超出输入框组件会自动撑开下拉框宽度,但最大宽度不超过 `1000px`。也可以通过 `popupProps.overlayInnerStyle.width` 自由设置下拉框宽度。`popupProps.overlayInnerStyle` 类型为函数时,可以更灵活地动态控制下拉框宽度。

{{ width }}

Expand Down
6 changes: 3 additions & 3 deletions js/input-number/number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ export function canInputNumber(number: string, largeNumber: boolean) {
if (number.slice(0, 2) === '00') return false;
// 只能出现一个点(.)
if (number.match(/\./g)?.length > 1) return false;
// 只能出现一个负号(-),并且在第一个位置
const minusSignCount = number.match(/-/g)?.length || 0;
if (minusSignCount > 1 || (minusSignCount === 1 && number[0] !== '-')) return false;
// 只能出现一个负号(-)或 一个正号(+),并且在第一个位置;但允许 3e+10 这种形式
const tmpNumber = number.slice(1);
if (/(\+|-)/.test(tmpNumber) && !/e+/i.test(tmpNumber)) return false;
// 允许输入数字字符
const isNumber = (largeNumber && isInputNumber(number)) || !Number.isNaN(Number(number));
if (!isNumber && !specialCode.includes(number.slice(-1))) return false;
Expand Down
152 changes: 132 additions & 20 deletions js/table/tree-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import isUndefined from 'lodash/isUndefined';
/* eslint-disable no-param-reassign */
/* eslint-disable no-use-before-define */
import get from 'lodash/get';
import set from 'lodash/set';
import { isRowSelectedDisabled } from './utils';
import { PrimaryTableCol, TableRowState, TableRowValue, TableRowData } from './types';
import log from '../log';
Expand Down Expand Up @@ -30,6 +31,18 @@ export const TABLE_TREE_ERROR_CODE_NOT_SAME_LEVEL = {
reason: 'The same level of rows can not be swapped.',
};

/**
* 获取行唯一标识
* @param row 行数据
* @param colKey 列字段
* @param rowIndex 行下标
* @param level 层级
*/
export function getUniqueRowValue(row: TableRowData, colKey: string, rowIndex: number = 0, level: number = 0) {
const rowValue = get(row, colKey);
return rowIndex || level ? `${rowValue}_${rowIndex || 0}_${level || 0}}` : rowValue;
}

/**
* 表格树形结构处理器
* Vue 和 React 可以通用
Expand Down Expand Up @@ -67,7 +80,7 @@ class TableTreeStore<T extends TableRowData = TableRowData> {
getAllUniqueKeys(data: T[], keys: KeysType, arr: T[] = []) {
for (let i = 0, len = data.length; i < len; i++) {
const item = data[i];
arr.push(get(item, keys.rowKey));
arr.push(getUniqueRowValue(item, keys.rowKey));
const children = get(item, keys.childrenKey);
if (children?.length) {
this.getAllUniqueKeys(children, keys, arr);
Expand All @@ -76,9 +89,45 @@ class TableTreeStore<T extends TableRowData = TableRowData> {
return arr;
}

toggleExpandData(p: { rowIndex: number; row: T }, dataSource: T[], keys: KeysType) {
getExpandedChildrenKeys(data: T[], keys: KeysType, arr: (string | number)[] = []) {
for (let i = 0, len = data.length; i < len; i++) {
const item = data[i];
const rowValue = getUniqueRowValue(item, keys.rowKey);
const rowState = this.treeDataMap.get(rowValue);
if (rowState.expanded) {
arr.push(rowValue);
}
const children = get(item, keys.childrenKey);
if (children?.length) {
this.getExpandedChildrenKeys(children, keys, arr);
}
}
return arr;
}

expandTreeNode(rowList: (string | number)[], dataSource: T[], keys: KeysType) {
if (!rowList.length) return dataSource;
rowList.forEach((rowValue) => {
const rowState = this.treeDataMap.get(rowValue);
if (!rowState) return;
this.toggleExpandData({ row: rowState.row as T, rowIndex: rowState.rowIndex }, dataSource, keys, 'expand');
});
return dataSource;
}

foldTreeNode(rowList: (string | number)[], dataSource: T[], keys: KeysType) {
if (!rowList.length) return dataSource;
rowList.forEach((rowValue) => {
const rowState = this.treeDataMap.get(rowValue);
if (!rowState) return;
this.toggleExpandData({ row: rowState.row as T, rowIndex: rowState.rowIndex }, dataSource, keys, 'fold');
});
return dataSource;
}

toggleExpandData(p: { rowIndex: number; row: T }, dataSource: T[], keys: KeysType, type?: 'expand' | 'fold') {
if (!p) {
log.error('EnhancedTable', 'the node you want to toggleExpand doest not exist in `data`');
log.error('EnhancedTable', 'the node toggleExpanded doest not exist in `data`');
return dataSource;
}
const rowValue = get(p.row, keys.rowKey);
Expand All @@ -90,7 +139,9 @@ class TableTreeStore<T extends TableRowData = TableRowData> {
// childrenNodes = true,表示懒加载,直接返回,暂时不做展开处理
if (childrenNodes === true) return dataSource;
const r = this.treeDataMap.get(rowValue);
r.rowIndex = p.rowIndex;
if (type === 'expand' && r.expanded) return dataSource;
if (type === 'fold' && !r.expanded) return dataSource;
r.rowIndex = r.rowIndex ?? p.rowIndex;
r.expanded = !r.expanded;
this.treeDataMap.set(rowValue, r);
return this.updateExpandRow(r, dataSource, keys);
Expand Down Expand Up @@ -136,7 +187,7 @@ class TableTreeStore<T extends TableRowData = TableRowData> {
* @returns {number} rowIndex 设置的行下标
*/
updateData(rowValue: TableRowValue, newRowData: T, dataSource: T[], keys: KeysType): number {
const newRowValue = get(newRowData, keys.rowKey);
const newRowValue = getUniqueRowValue(newRowData, keys.rowKey);
const rowState = this.treeDataMap.get(rowValue);
// Map 没有查询到,或者查询到的 rowIndex 值为 -1,均表示当前数据不在 dataSource 列表中,未显示在页面中
if (!rowState || rowState.rowIndex === -1) {
Expand All @@ -152,7 +203,7 @@ class TableTreeStore<T extends TableRowData = TableRowData> {
const oldChildren = get(rowState.row, keys.childrenKey);
if (oldChildren?.length) {
for (let i = 0, len = oldChildren.length; i < len; i++) {
const rowValue = get(oldChildren[i], keys.rowKey);
const rowValue = getUniqueRowValue(oldChildren[i], keys.rowKey);
const state = this.treeDataMap.get(rowValue);
if (state) {
this.treeDataMap.delete(rowValue);
Expand All @@ -169,7 +220,7 @@ class TableTreeStore<T extends TableRowData = TableRowData> {
if (rowState.parent) {
// 更新直接子元素数组
const siblings = get(rowState.parent.row, keys.childrenKey);
const index = siblings.findIndex((item: T) => get(item, keys.rowKey) === rowValue);
const index = siblings.findIndex((item: T) => getUniqueRowValue(item, keys.rowKey) === rowValue);
siblings[index] = newRowData;
}

Expand Down Expand Up @@ -208,7 +259,41 @@ class TableTreeStore<T extends TableRowData = TableRowData> {
type: 'remove',
});
} else {
log.warn('EnhancedTable', 'Do not remove this node, which is not appeared.');
log.warn('EnhancedTable', 'Can not remove this node, which is not appeared.');
}
return dataSource;
}

/**
* 清除子节点
* @param key
* @param dataSource
* @param keys
*/
removeChildren(key: TableRowValue, dataSource: T[], keys: KeysType): T[] {
const r = this.treeDataMap.get(key);
if (r && r.rowIndex >= 0) {
const removeNumber = r.expandChildrenLength || 0;
if (removeNumber) {
dataSource.splice(r.rowIndex + 1, removeNumber);
}
if (r.parent) {
updateRowExpandLength(this.treeDataMap, r.parent.row, -1 * removeNumber, 'delete', keys);
}
r.expandChildrenLength = 0;
r.expanded = false;
set(r.row, keys.childrenKey, undefined);
this.treeDataMap.set(key, r);
// 更新 rowIndex 之后的下标
if (removeNumber) {
updateRowIndex(this.treeDataMap, dataSource, {
minRowIndex: r.rowIndex + 1,
rowKey: keys.rowKey,
type: 'remove',
});
}
} else {
log.warn('EnhancedTable', 'Can not remove this node\'s children, which is not appeared.');
}
return dataSource;
}
Expand All @@ -231,7 +316,7 @@ class TableTreeStore<T extends TableRowData = TableRowData> {
let firstNewChildrenIndex = -1;
for (let i = 0, len = tmpData.length; i < len; i++) {
const oneData = tmpData[i];
const newRowValue = get(oneData, keys.rowKey);
const newRowValue = getUniqueRowValue(oneData, keys.rowKey);
const mapState = this.treeDataMap.get(newRowValue);
if (!this.validateDataDoubleExist(mapState, newRowValue)) {
log.warn('Table', `Duplicated Data \`${newRowValue}\` has been removed.`);
Expand Down Expand Up @@ -450,30 +535,27 @@ class TableTreeStore<T extends TableRowData = TableRowData> {
*/
expandAll(dataSource: T[], keys: KeysType) {
this.expandAllRowIndex = 0;
const newData: T[] = [];
const expandLoop = (
dataSource: T[],
keys: KeysType,
newData: T[] = [],
parentExpanded = false,
parent: TableRowState = null,
) => {
for (let i = 0, len = dataSource.length; i < len; i++) {
const item = dataSource[i];
const rowValue = get(item, keys.rowKey);
const state = this.treeDataMap.get(rowValue);
const children = get(item, keys.childrenKey);
const originalExpanded = state.expanded;
state.rowIndex = this.expandAllRowIndex;
// children = true is async load
if (children !== true && children?.length) {
state.expanded = true;
}
state.expandChildrenLength = children?.length || 0;
this.expandAllRowIndex += 1;
if (!parentExpanded) {
newData.push(item);
}
newData.push(item);
this.treeDataMap.set(rowValue, state);
if (children?.length && !originalExpanded) {
if (children?.length) {
// 同步更新父元素的展开数量
let tmpParent = parent;
while (tmpParent?.row) {
Expand All @@ -482,12 +564,12 @@ class TableTreeStore<T extends TableRowData = TableRowData> {
tmpParent = tmpParent.parent;
}
// 继续子元素
expandLoop(children, keys, newData, originalExpanded, state);
expandLoop(children, keys, state);
}
}
return newData;
};
return expandLoop(dataSource, keys);
expandLoop(dataSource, keys);
return newData;
}

/**
Expand Down Expand Up @@ -573,7 +655,7 @@ class TableTreeStore<T extends TableRowData = TableRowData> {
) {
for (let i = 0, len = dataSource.length; i < len; i++) {
const item = dataSource[i];
const rowValue = get(item, keys.rowKey);
const rowValue = getUniqueRowValue(item, keys.rowKey);
if (isUndefined(rowValue)) {
log.error('EnhancedTable', '`rowKey` could be wrong, can not get rowValue from `data` by `rowKey`.');
return;
Expand Down Expand Up @@ -767,4 +849,34 @@ export function updateRowIndex<T>(
}
}

export function diffExpandedTreeNode(
newExpandedNode: (number | string)[] = [],
oldExpandedNode: (number | string)[] = [],
) {
const removedList: (number | string)[] = [];
const addedList: (number | string)[] = [];
const newExpandedNodeMap: Map<any, boolean> = new Map();
const oldExpandedNodeMap: Map<any, boolean> = new Map();
for (let i = 0, len = newExpandedNode.length; i < len; i++) {
newExpandedNodeMap.set(newExpandedNode[i], true);
}
for (let i = 0, len = oldExpandedNode.length; i < len; i++) {
oldExpandedNodeMap.set(oldExpandedNode[i], true);
}
for (let i = 0, len = newExpandedNode.length; i < len; i++) {
if (!oldExpandedNodeMap.get(newExpandedNode[i])) {
addedList.push(newExpandedNode[i]);
}
}
for (let i = 0, len = oldExpandedNode.length; i < len; i++) {
if (!newExpandedNodeMap.get(oldExpandedNode[i])) {
removedList.push(oldExpandedNode[i]);
}
}
return {
removedList,
addedList,
};
}

export type TreeDataMapType = InstanceType<typeof TableTreeStore>['treeDataMap'];
9 changes: 6 additions & 3 deletions js/tree/tree-node-model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import isUndefined from 'lodash/isUndefined';
import isBoolean from 'lodash/isBoolean';
import omit from 'lodash/omit';
import get from 'lodash/get';
import { TreeNode } from './tree-node';
import { OptionData } from '../common';
import {
Expand Down Expand Up @@ -253,12 +254,14 @@ export class TreeNodeModel {
public setData(data: OptionData) {
const node = this[nodeKey];
// 详细细节可见 https://github.com/Tencent/tdesign-common/issues/655
const _data = omit(data, ['children', 'value', 'label']);
const _data = omit(data, ['children', 'value', 'label', 'disabled']);
const { keys } = node.tree.config;
const dataValue = data[keys?.value || 'value'];
const dataLabel = data[keys?.label || 'label'];
const dataValue = get(data, keys?.value || 'value');
const dataLabel = get(data, keys?.label || 'label');
const dataDisabled = get(data, keys?.disabled || 'disabled');
if (!isUndefined(dataValue)) _data.value = dataValue;
if (!isUndefined(dataLabel)) _data.label = dataLabel;
if (!isUndefined(dataDisabled)) _data.disable = dataDisabled;

Object.assign(node.data, _data);
Object.assign(node, _data);
Expand Down
11 changes: 6 additions & 5 deletions js/tree/tree-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export const setableStatus: Record<string, boolean | null> = {
expandMutex: null,
activable: null,
checkable: null,
disabled: null,
draggable: null,
loading: false,
};
Expand Down Expand Up @@ -140,6 +139,7 @@ export class TreeNode {
const propChildren = keys.children || 'children';
const propLabel = keys.label || 'label';
const propValue = keys.value || 'value';
const propsDisabled = keys.disabled || 'disabled';

// 节点自身初始化数据
this.model = null;
Expand Down Expand Up @@ -168,7 +168,6 @@ export class TreeNode {
// 这种处理方式主要是解决 treeStore.setConfig 方法配置全局属性导致的状态切换与保留的问题
this.activable = null;
this.checkable = null;
this.disabled = null;
this.expandMutex = null;
this.draggable = null;

Expand All @@ -179,7 +178,7 @@ export class TreeNode {

// 设置 value
// 没有 value 的时候,value 默认使用自动生成的 唯一 id
this.value = isNil(data[propValue]) ? this[privateKey] : data[propValue];
this.value = isNil(get(data, propValue)) ? this[privateKey] : get(data, propValue);
const { nodeMap, privateMap } = tree;
if (nodeMap.get(this.value)) {
log.warn('Tree', `Dulplicate value: ${this.value}`);
Expand All @@ -188,7 +187,9 @@ export class TreeNode {
privateMap.set(this[privateKey], this);

// 设置标签
this.label = data[propLabel] || '';
this.label = get(data, propLabel) || '';
// 设置是否禁用
this.disabled = get(data, propsDisabled);

// 设置子节点
const children = data[propChildren];
Expand Down Expand Up @@ -557,7 +558,7 @@ export class TreeNode {
const { tree } = this;
const keys = Object.keys(item);
keys.forEach((key) => {
if (hasOwnProperty.call(setableStatus, key) || key === 'label') {
if (hasOwnProperty.call(setableStatus, key) || key === 'label' || key === 'disabled') {
this[key] = item[key];
}
});
Expand Down
1 change: 1 addition & 0 deletions js/tree/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface KeysType {
value?: string;
label?: string;
children?: string;
disabled?: string;
}

export interface TreeNodeState {
Expand Down
4 changes: 3 additions & 1 deletion js/upload/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import isFunction from 'lodash/isFunction';
import isNumber from 'lodash/isNumber';
/* eslint-disable no-param-reassign */
import { isOverSizeLimit } from './utils';
import { getCurrentDate, isOverSizeLimit } from './utils';
import xhr from './xhr';
import log from '../log/log';
import {
Expand Down Expand Up @@ -171,6 +171,8 @@ export function uploadOneRequest(params: HandleUploadParams): Promise<UploadRequ
file.response = response;
file.url = response.url;
file.percent = res.status === 'success' ? 100 : 0;
// 如果上传请求返回结果没有上传日期,则使用电脑当前日期显示
file.uploadTime = response?.uploadTime || getCurrentDate();
});
resultFiles = toUploadFiles;
}
Expand Down
Loading

0 comments on commit 02cc527

Please sign in to comment.