@gingkoo/pandora-metabase 1.0.0-alpha.2 → 1.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/es/components/modules/{group.d.ts → union.d.ts} +1 -1
- package/lib/es/components/popup.d.ts +2 -0
- package/lib/es/index.js +137 -47
- package/lib/es/index.js.map +1 -1
- package/lib/es/store/enum.d.ts +1 -1
- package/lib/es/store/types.d.ts +1 -1
- package/lib/es/types.d.ts +3 -2
- package/lib/es/utils/helper-dom.d.ts +4 -3
- package/lib/es/utils.d.ts +2 -0
- package/package.json +1 -1
|
@@ -11,6 +11,7 @@ export declare function generateTrigger(PortalComponent: any): {
|
|
|
11
11
|
getCurrentNodePos: () => {
|
|
12
12
|
x: number;
|
|
13
13
|
y: number;
|
|
14
|
+
t: number;
|
|
14
15
|
h: any;
|
|
15
16
|
};
|
|
16
17
|
getContainer: () => HTMLSpanElement;
|
|
@@ -54,6 +55,7 @@ declare const _default: {
|
|
|
54
55
|
getCurrentNodePos: () => {
|
|
55
56
|
x: number;
|
|
56
57
|
y: number;
|
|
58
|
+
t: number;
|
|
57
59
|
h: any;
|
|
58
60
|
};
|
|
59
61
|
getContainer: () => HTMLSpanElement;
|
package/lib/es/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @gingkoo/pandora-metabase v1.0.0-alpha.
|
|
2
|
+
* @gingkoo/pandora-metabase v1.0.0-alpha.4
|
|
3
3
|
*/
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
import * as React from 'react';
|
|
@@ -89,7 +89,7 @@ var TypeEnum;
|
|
|
89
89
|
TypeEnum["summarize"] = "summarize";
|
|
90
90
|
TypeEnum["sort"] = "sort";
|
|
91
91
|
TypeEnum["rowLimit"] = "rowLimit";
|
|
92
|
-
TypeEnum["
|
|
92
|
+
TypeEnum["union"] = "union";
|
|
93
93
|
})(TypeEnum || (TypeEnum = {}));
|
|
94
94
|
var JoinEnum;
|
|
95
95
|
(function (JoinEnum) {
|
|
@@ -869,6 +869,86 @@ const changeFieldAlias = (list, curObj) => {
|
|
|
869
869
|
});
|
|
870
870
|
return newList;
|
|
871
871
|
};
|
|
872
|
+
function splitByUnion(data) {
|
|
873
|
+
const original = cloneDeep(data);
|
|
874
|
+
const result = [];
|
|
875
|
+
let i = 0;
|
|
876
|
+
while (i < original.length) {
|
|
877
|
+
const item = original[i];
|
|
878
|
+
if (item.type === 'group') {
|
|
879
|
+
// group.list 中每一项原样推入结果
|
|
880
|
+
for (const subItem of item.list) {
|
|
881
|
+
result.push(subItem);
|
|
882
|
+
}
|
|
883
|
+
i++;
|
|
884
|
+
} else if (item.type === 'union') {
|
|
885
|
+
const {
|
|
886
|
+
list,
|
|
887
|
+
...otehr
|
|
888
|
+
} = item;
|
|
889
|
+
// 查找下一个 group,并将其 list 转成 subquery
|
|
890
|
+
const nextItem = original[i + 1];
|
|
891
|
+
if (nextItem && nextItem.type === 'group') {
|
|
892
|
+
result.push({
|
|
893
|
+
...otehr,
|
|
894
|
+
subquery: nextItem.list.map(subItem => subItem)
|
|
895
|
+
});
|
|
896
|
+
i += 2;
|
|
897
|
+
} else {
|
|
898
|
+
result.push({
|
|
899
|
+
...otehr,
|
|
900
|
+
subquery: []
|
|
901
|
+
});
|
|
902
|
+
i++;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
return result;
|
|
907
|
+
}
|
|
908
|
+
function reassembleByUnion(target) {
|
|
909
|
+
const result = [];
|
|
910
|
+
let i = 0;
|
|
911
|
+
const len = target.length;
|
|
912
|
+
// 如果没有任何 union,直接放入一个 group.list
|
|
913
|
+
const hasUnion = target.some(item => item.type === 'union');
|
|
914
|
+
if (!hasUnion) {
|
|
915
|
+
return [{
|
|
916
|
+
type: 'group',
|
|
917
|
+
name: 'default',
|
|
918
|
+
list: [...target]
|
|
919
|
+
}];
|
|
920
|
+
}
|
|
921
|
+
// 否则正常处理
|
|
922
|
+
while (i < len) {
|
|
923
|
+
const item = target[i];
|
|
924
|
+
if (item.type !== 'union') {
|
|
925
|
+
// 收集连续非 union 的 item,统一放入一个 group.list
|
|
926
|
+
const groupList = [];
|
|
927
|
+
while (i < len && target[i].type !== 'union') {
|
|
928
|
+
groupList.push(target[i]);
|
|
929
|
+
i++;
|
|
930
|
+
}
|
|
931
|
+
result.push({
|
|
932
|
+
type: 'group',
|
|
933
|
+
name: 'default',
|
|
934
|
+
list: groupList
|
|
935
|
+
});
|
|
936
|
+
} else {
|
|
937
|
+
// 处理 union
|
|
938
|
+
result.push({
|
|
939
|
+
type: 'union',
|
|
940
|
+
name: 'union',
|
|
941
|
+
union: item.union ?? 'UNION',
|
|
942
|
+
list: []
|
|
943
|
+
});
|
|
944
|
+
const subquery = item.subquery || [];
|
|
945
|
+
const convertedSubquery = reassembleByUnion(subquery);
|
|
946
|
+
result.push(...convertedSubquery);
|
|
947
|
+
i++; // 跳过当前 union
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
return result;
|
|
951
|
+
}
|
|
872
952
|
|
|
873
953
|
let metaKey = 1;
|
|
874
954
|
const SummarizeAlias = 'source';
|
|
@@ -893,9 +973,9 @@ const useStore = () => {
|
|
|
893
973
|
list: defaultMetaList
|
|
894
974
|
}];
|
|
895
975
|
const defaultOperator = {
|
|
896
|
-
type: '
|
|
897
|
-
name: '
|
|
898
|
-
|
|
976
|
+
type: 'union',
|
|
977
|
+
name: 'union',
|
|
978
|
+
union: UnionEnum.union,
|
|
899
979
|
list: []
|
|
900
980
|
};
|
|
901
981
|
const [showFields, setShowFields] = useState(true); //显示字段
|
|
@@ -1053,7 +1133,8 @@ const useStore = () => {
|
|
|
1053
1133
|
return {
|
|
1054
1134
|
name: item.name || 'default',
|
|
1055
1135
|
list: newList.length < 1 ? defaultMetaList : newList,
|
|
1056
|
-
type: item.type || 'group'
|
|
1136
|
+
type: item.type || 'group',
|
|
1137
|
+
union: item.union
|
|
1057
1138
|
};
|
|
1058
1139
|
});
|
|
1059
1140
|
const validMetaKeys = _metaList.flatMap(group => group.list).map(v => Number(v.metaKey)).filter(num => !isNaN(num));
|
|
@@ -1161,7 +1242,7 @@ const useStore = () => {
|
|
|
1161
1242
|
}
|
|
1162
1243
|
};
|
|
1163
1244
|
}
|
|
1164
|
-
if (type === TypeEnum.
|
|
1245
|
+
if (type === TypeEnum.union) {
|
|
1165
1246
|
// 添加分组
|
|
1166
1247
|
let newMetaList = metaList.slice();
|
|
1167
1248
|
newMetaList.splice(groupIndex + 1, 0, defaultOperator, ...defaultMeta);
|
|
@@ -1732,6 +1813,7 @@ const getComputedTranslate = obj => {
|
|
|
1732
1813
|
};
|
|
1733
1814
|
// 获取元素距离浏览器顶部的距离
|
|
1734
1815
|
const getElementTop = elem => {
|
|
1816
|
+
if (!elem) return 0;
|
|
1735
1817
|
let elemTop = elem.offsetTop;
|
|
1736
1818
|
let pElem = elem.offsetParent;
|
|
1737
1819
|
while (pElem != null) {
|
|
@@ -1745,6 +1827,7 @@ const getElementTop = elem => {
|
|
|
1745
1827
|
};
|
|
1746
1828
|
// 获取元素距离浏览器顶部的距离
|
|
1747
1829
|
const getElementLeft = elem => {
|
|
1830
|
+
if (!elem) return 0;
|
|
1748
1831
|
let elemLeft = elem.offsetLeft;
|
|
1749
1832
|
let pElem = elem.offsetParent;
|
|
1750
1833
|
while (pElem != null) {
|
|
@@ -1756,8 +1839,23 @@ const getElementLeft = elem => {
|
|
|
1756
1839
|
}
|
|
1757
1840
|
return elemLeft;
|
|
1758
1841
|
};
|
|
1759
|
-
|
|
1760
|
-
|
|
1842
|
+
// 获取元素可见范围内高度
|
|
1843
|
+
const getContainerVisibleHeight = container => {
|
|
1844
|
+
if (!container) return 0;
|
|
1845
|
+
const rect = container.getBoundingClientRect();
|
|
1846
|
+
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
1847
|
+
// 元素顶部在视口上方 -> 不可见
|
|
1848
|
+
if (rect.bottom < 0) return 0;
|
|
1849
|
+
// 元素底部在视口下方 -> 不可见
|
|
1850
|
+
if (rect.top > windowHeight) return 0;
|
|
1851
|
+
// 可见区域的 top 和 bottom
|
|
1852
|
+
const visibleTop = Math.max(rect.top, 0);
|
|
1853
|
+
const visibleBottom = Math.min(rect.bottom, windowHeight);
|
|
1854
|
+
// 可见高度
|
|
1855
|
+
return visibleBottom - visibleTop;
|
|
1856
|
+
};
|
|
1857
|
+
const getScrollTop = elem => {
|
|
1858
|
+
return elem?.scrollTop || document.documentElement.scrollTop;
|
|
1761
1859
|
};
|
|
1762
1860
|
// 浏览器可视宽高
|
|
1763
1861
|
const getWindowSize = () => {
|
|
@@ -2236,7 +2334,7 @@ const List = [{
|
|
|
2236
2334
|
const RowLimit$1 = props => {
|
|
2237
2335
|
const {
|
|
2238
2336
|
meta,
|
|
2239
|
-
|
|
2337
|
+
union,
|
|
2240
2338
|
groupIndex
|
|
2241
2339
|
} = props;
|
|
2242
2340
|
const store = useStore$1();
|
|
@@ -2246,10 +2344,10 @@ const RowLimit$1 = props => {
|
|
|
2246
2344
|
node: e.currentTarget,
|
|
2247
2345
|
content: jsx(SelectList, {
|
|
2248
2346
|
list: List,
|
|
2249
|
-
value:
|
|
2347
|
+
value: union,
|
|
2250
2348
|
onChange: type => {
|
|
2251
2349
|
let newMeta = store.metaList.slice();
|
|
2252
|
-
newMeta[groupIndex].
|
|
2350
|
+
newMeta[groupIndex].union = type;
|
|
2253
2351
|
store._setMeta(newMeta);
|
|
2254
2352
|
store.setPopup({
|
|
2255
2353
|
visible: false
|
|
@@ -2272,7 +2370,7 @@ const RowLimit$1 = props => {
|
|
|
2272
2370
|
children: jsx("div", {
|
|
2273
2371
|
className: `Sqb-TableName`,
|
|
2274
2372
|
onClick: e => selectOperator(e),
|
|
2275
|
-
children:
|
|
2373
|
+
children: union
|
|
2276
2374
|
})
|
|
2277
2375
|
})
|
|
2278
2376
|
})]
|
|
@@ -3364,7 +3462,7 @@ function generateTrigger(PortalComponent) {
|
|
|
3364
3462
|
this.props.visible && this.props.closable && this.props.hideVisible();
|
|
3365
3463
|
};
|
|
3366
3464
|
attachParent = popupContainer => {
|
|
3367
|
-
let mountNode = returnDocument().body;
|
|
3465
|
+
let mountNode = this.props.container || returnDocument().body;
|
|
3368
3466
|
mountNode.appendChild(popupContainer);
|
|
3369
3467
|
};
|
|
3370
3468
|
getCurrentNodePos = () => {
|
|
@@ -3373,8 +3471,9 @@ function generateTrigger(PortalComponent) {
|
|
|
3373
3471
|
container
|
|
3374
3472
|
} = this.props;
|
|
3375
3473
|
return {
|
|
3376
|
-
x: getElementLeft(node),
|
|
3377
|
-
y: getElementTop(node) - (container
|
|
3474
|
+
x: getElementLeft(node) - getElementLeft(container),
|
|
3475
|
+
y: getElementTop(node) - getElementTop(container),
|
|
3476
|
+
t: getElementTop(container),
|
|
3378
3477
|
h: node.offsetHeight
|
|
3379
3478
|
};
|
|
3380
3479
|
};
|
|
@@ -3417,19 +3516,21 @@ function generateTrigger(PortalComponent) {
|
|
|
3417
3516
|
didUpdate = () => {
|
|
3418
3517
|
if (!this.props.node) return false;
|
|
3419
3518
|
let {
|
|
3420
|
-
innerSpacing = 10
|
|
3519
|
+
innerSpacing = 10,
|
|
3520
|
+
container
|
|
3421
3521
|
} = this.props;
|
|
3422
3522
|
let pos = this.getCurrentNodePos();
|
|
3423
|
-
let posY = pos.y - getScrollTop();
|
|
3523
|
+
let posY = pos.y - getScrollTop(container);
|
|
3424
3524
|
if (!this.ref) return false;
|
|
3425
3525
|
let realHeight = this.ref?.current?.childNodes?.[0]?.offsetHeight || 0;
|
|
3426
3526
|
if (!realHeight) return false;
|
|
3427
3527
|
let {
|
|
3428
3528
|
height: winH
|
|
3429
3529
|
} = getWindowSize();
|
|
3430
|
-
let
|
|
3530
|
+
let containerH = getContainerVisibleHeight(container);
|
|
3531
|
+
let downH = (containerH || winH) - posY - pos.h; // 元素下面可用高度
|
|
3431
3532
|
let maxHeight = 0;
|
|
3432
|
-
let topHeight = getScrollTop();
|
|
3533
|
+
let topHeight = getScrollTop(container);
|
|
3433
3534
|
if (downH >= posY || realHeight <= downH - innerSpacing - outSpacing) {
|
|
3434
3535
|
// 下面比上面宽敞 或 下面足够放下所有 放下面
|
|
3435
3536
|
maxHeight = Math.min(realHeight, downH - innerSpacing - outSpacing);
|
|
@@ -5015,17 +5116,17 @@ const IconTypeMap = new Map([[TypeEnum.filter, {
|
|
|
5015
5116
|
name: __('SqlQueryBuilder.rowLimit'),
|
|
5016
5117
|
icon: jsx(RowLimitIcon, {}),
|
|
5017
5118
|
className: 'rowLimit'
|
|
5018
|
-
}], [TypeEnum.
|
|
5119
|
+
}], [TypeEnum.union, {
|
|
5019
5120
|
name: __('SqlQueryBuilder.union'),
|
|
5020
5121
|
icon: jsx(GroupIcon, {}),
|
|
5021
5122
|
className: 'union'
|
|
5022
5123
|
}]]);
|
|
5023
5124
|
// 前端展示的icon顺序 随便改不影响逻辑
|
|
5024
|
-
const DisplayOrder = [TypeEnum.filter, TypeEnum.summarize, TypeEnum.joinData, TypeEnum.permissionTable, TypeEnum.customColumn, TypeEnum.sort, TypeEnum.rowLimit, TypeEnum.
|
|
5125
|
+
const DisplayOrder = [TypeEnum.filter, TypeEnum.summarize, TypeEnum.joinData, TypeEnum.permissionTable, TypeEnum.customColumn, TypeEnum.sort, TypeEnum.rowLimit, TypeEnum.union];
|
|
5025
5126
|
// js逻辑顺序 正常顺序
|
|
5026
|
-
const OrderType = [TypeEnum.data, TypeEnum.joinData, TypeEnum.permissionTable, TypeEnum.customColumn, TypeEnum.filter, TypeEnum.summarize, TypeEnum.sort, TypeEnum.rowLimit, TypeEnum.
|
|
5127
|
+
const OrderType = [TypeEnum.data, TypeEnum.joinData, TypeEnum.permissionTable, TypeEnum.customColumn, TypeEnum.filter, TypeEnum.summarize, TypeEnum.sort, TypeEnum.rowLimit, TypeEnum.union];
|
|
5027
5128
|
// js逻辑顺序 聚合下面的顺序是这个样子
|
|
5028
|
-
const OrderNewType = [TypeEnum.sort, TypeEnum.rowLimit, TypeEnum.joinData, TypeEnum.permissionTable, TypeEnum.customColumn, TypeEnum.filter, TypeEnum.summarize, TypeEnum.
|
|
5129
|
+
const OrderNewType = [TypeEnum.sort, TypeEnum.rowLimit, TypeEnum.joinData, TypeEnum.permissionTable, TypeEnum.customColumn, TypeEnum.filter, TypeEnum.summarize, TypeEnum.union];
|
|
5029
5130
|
const metaIcon = (size, handleClick) => {
|
|
5030
5131
|
return ({
|
|
5031
5132
|
type
|
|
@@ -5130,7 +5231,7 @@ const findNextIcon = (store, props) => {
|
|
|
5130
5231
|
if (meta.table2.name) {
|
|
5131
5232
|
available = OrderType.slice(curLocation + 1);
|
|
5132
5233
|
} else {
|
|
5133
|
-
available = [TypeEnum.customColumn, TypeEnum.filter, TypeEnum.summarize, TypeEnum.
|
|
5234
|
+
available = [TypeEnum.customColumn, TypeEnum.filter, TypeEnum.summarize, TypeEnum.union];
|
|
5134
5235
|
}
|
|
5135
5236
|
} else {
|
|
5136
5237
|
if (isLast) {
|
|
@@ -5152,7 +5253,7 @@ const findNextIcon = (store, props) => {
|
|
|
5152
5253
|
if (meta.customColumn.length || ~joinIndex && prevList[joinIndex].table2.name) {
|
|
5153
5254
|
available = OrderType.slice(curLocation + 1);
|
|
5154
5255
|
} else {
|
|
5155
|
-
available = [TypeEnum.filter, TypeEnum.summarize, TypeEnum.
|
|
5256
|
+
available = [TypeEnum.filter, TypeEnum.summarize, TypeEnum.union];
|
|
5156
5257
|
}
|
|
5157
5258
|
} else {
|
|
5158
5259
|
if (isLast) {
|
|
@@ -5185,7 +5286,7 @@ const findNextIcon = (store, props) => {
|
|
|
5185
5286
|
if (isLast) {
|
|
5186
5287
|
if (!ExistAboveGroupBy) {
|
|
5187
5288
|
if (meta.group.length && !meta.by.length) ; else if (!meta.group.length && !meta.by.length) {
|
|
5188
|
-
available = [TypeEnum.sort, TypeEnum.rowLimit, TypeEnum.
|
|
5289
|
+
available = [TypeEnum.sort, TypeEnum.rowLimit, TypeEnum.union];
|
|
5189
5290
|
} else {
|
|
5190
5291
|
available = OrderNewType;
|
|
5191
5292
|
}
|
|
@@ -8545,21 +8646,16 @@ const Metabase = props => {
|
|
|
8545
8646
|
}, [store.popupData2]);
|
|
8546
8647
|
const onSave = async () => {
|
|
8547
8648
|
let intercept = false; // 是否返回
|
|
8649
|
+
const _metaList = splitByUnion(store.metaList);
|
|
8548
8650
|
store.metaList.map(v => {
|
|
8549
|
-
if (v.type !== '
|
|
8651
|
+
if (v.type !== 'union' && !(v.list?.[0]).table.name) {
|
|
8550
8652
|
intercept = true;
|
|
8551
8653
|
return Toast.warning(__('data.pleaseSelectDataTable'));
|
|
8552
8654
|
}
|
|
8553
8655
|
});
|
|
8554
8656
|
if (saveLoading || intercept) return null;
|
|
8555
8657
|
setSaveLoading(true);
|
|
8556
|
-
|
|
8557
|
-
// 分组
|
|
8558
|
-
await onOk?.(store.metaList);
|
|
8559
|
-
} else {
|
|
8560
|
-
// 非分组
|
|
8561
|
-
await onOk?.(store.metaList[0].list);
|
|
8562
|
-
}
|
|
8658
|
+
await onOk?.(_metaList);
|
|
8563
8659
|
setSaveLoading(false);
|
|
8564
8660
|
};
|
|
8565
8661
|
let zIndex = popupContainer.current ? getMaxZIndexInParents(popupContainer.current) : null;
|
|
@@ -8570,15 +8666,15 @@ const Metabase = props => {
|
|
|
8570
8666
|
children: jsxs("div", {
|
|
8571
8667
|
className: 'Sqb',
|
|
8572
8668
|
children: [store.metaList.map((v, index) => {
|
|
8573
|
-
if (v.type === '
|
|
8669
|
+
if (v.type === 'union' && v.union) {
|
|
8574
8670
|
return jsx("div", {
|
|
8575
8671
|
className: cx(`Sqb-list`),
|
|
8576
8672
|
children: jsx(RowLimit$1, {
|
|
8577
|
-
|
|
8673
|
+
union: v.union,
|
|
8578
8674
|
meta: v,
|
|
8579
8675
|
groupIndex: index
|
|
8580
8676
|
})
|
|
8581
|
-
}, '
|
|
8677
|
+
}, 'union' + index);
|
|
8582
8678
|
}
|
|
8583
8679
|
return jsx("div", {
|
|
8584
8680
|
className: cx(`Sqb-list`),
|
|
@@ -8665,15 +8761,9 @@ const SqlVisionBuilder = /*#__PURE__*/React__default.forwardRef((props, ref) =>
|
|
|
8665
8761
|
store.setProps(props);
|
|
8666
8762
|
}, [props]);
|
|
8667
8763
|
useEffect(() => {
|
|
8668
|
-
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
store.setPreData([{
|
|
8672
|
-
name: 'default',
|
|
8673
|
-
list: value
|
|
8674
|
-
}]);
|
|
8675
|
-
}
|
|
8676
|
-
}, [value, toolbar]);
|
|
8764
|
+
const _value = reassembleByUnion(value);
|
|
8765
|
+
store.setPreData(_value);
|
|
8766
|
+
}, [value]);
|
|
8677
8767
|
useEffect(() => {
|
|
8678
8768
|
store.setSourceList(sourceList);
|
|
8679
8769
|
}, [sourceList]);
|