@gingkoo/pandora-metabase 1.0.0-alpha.3 → 1.0.0-alpha.5

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.
@@ -1,16 +1,20 @@
1
1
  import * as React from 'react';
2
2
  export declare function generateTrigger(PortalComponent: any): {
3
3
  new (props: PropsType): {
4
+ resizeObserver: ResizeObserver | null;
4
5
  resetId: number;
5
6
  ref: any;
6
7
  componentDidMount(): void;
8
+ componentDidUpdate(prevProps: PropsType): void;
7
9
  componentWillUnmount(): void;
10
+ initResizeObserver: () => void;
8
11
  bindEvent: () => void;
9
12
  closePopup: () => void;
10
13
  attachParent: (popupContainer: HTMLSpanElement) => void;
11
14
  getCurrentNodePos: () => {
12
15
  x: number;
13
16
  y: number;
17
+ t: number;
14
18
  h: any;
15
19
  };
16
20
  getContainer: () => HTMLSpanElement;
@@ -28,7 +32,6 @@ export declare function generateTrigger(PortalComponent: any): {
28
32
  shouldComponentUpdate?(nextProps: Readonly<PropsType>, nextState: Readonly<{}>, nextContext: any): boolean;
29
33
  componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
30
34
  getSnapshotBeforeUpdate?(prevProps: Readonly<PropsType>, prevState: Readonly<{}>): any;
31
- componentDidUpdate?(prevProps: Readonly<PropsType>, prevState: Readonly<{}>, snapshot?: any): void;
32
35
  componentWillMount?(): void;
33
36
  UNSAFE_componentWillMount?(): void;
34
37
  componentWillReceiveProps?(nextProps: Readonly<PropsType>, nextContext: any): void;
@@ -44,16 +47,20 @@ export declare function generateTrigger(PortalComponent: any): {
44
47
  };
45
48
  declare const _default: {
46
49
  new (props: PropsType): {
50
+ resizeObserver: ResizeObserver | null;
47
51
  resetId: number;
48
52
  ref: any;
49
53
  componentDidMount(): void;
54
+ componentDidUpdate(prevProps: PropsType): void;
50
55
  componentWillUnmount(): void;
56
+ initResizeObserver: () => void;
51
57
  bindEvent: () => void;
52
58
  closePopup: () => void;
53
59
  attachParent: (popupContainer: HTMLSpanElement) => void;
54
60
  getCurrentNodePos: () => {
55
61
  x: number;
56
62
  y: number;
63
+ t: number;
57
64
  h: any;
58
65
  };
59
66
  getContainer: () => HTMLSpanElement;
@@ -71,7 +78,6 @@ declare const _default: {
71
78
  shouldComponentUpdate?(nextProps: Readonly<PropsType>, nextState: Readonly<{}>, nextContext: any): boolean;
72
79
  componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
73
80
  getSnapshotBeforeUpdate?(prevProps: Readonly<PropsType>, prevState: Readonly<{}>): any;
74
- componentDidUpdate?(prevProps: Readonly<PropsType>, prevState: Readonly<{}>, snapshot?: any): void;
75
81
  componentWillMount?(): void;
76
82
  UNSAFE_componentWillMount?(): void;
77
83
  componentWillReceiveProps?(nextProps: Readonly<PropsType>, nextContext: any): void;
package/lib/es/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @gingkoo/pandora-metabase v1.0.0-alpha.3
2
+ * @gingkoo/pandora-metabase v1.0.0-alpha.5
3
3
  */
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import * as React from 'react';
@@ -278,7 +278,6 @@ const summarizeToSql = (arr, record) => {
278
278
  condition,
279
279
  alias,
280
280
  name,
281
- fieldAlias,
282
281
  realName = ''
283
282
  } = record;
284
283
  let index = arr.indexOf(record);
@@ -339,7 +338,7 @@ const summarizeToSql = (arr, record) => {
339
338
  count++;
340
339
  }
341
340
  });
342
- as = fieldAlias || as + (count ? '_' + (count + 1) : '');
341
+ as = as + (count ? '_' + (count + 1) : '');
343
342
  return {
344
343
  sql: sql + ' AS ' + as,
345
344
  fieldAlias: as
@@ -1001,6 +1000,8 @@ const useStore = () => {
1001
1000
  }); //弹窗
1002
1001
  const [popupClosable, setClosable] = useState(true); //是否可关闭 如果弹框里面再弹框 则不可关闭
1003
1002
  const [popupClosable2, setClosable2] = useState(true); //是否可关闭 如果弹框里面再弹框 则不可关闭
1003
+ // 外层ref
1004
+ const popupContainer = useRef();
1004
1005
  // const [fetchDatasetFn, setFetchDatasetFn] = useState<(id: string) => Promise<any>>(
1005
1006
  // async () => {},
1006
1007
  // ); //fn
@@ -1411,7 +1412,8 @@ const useStore = () => {
1411
1412
  _setShowSubquery,
1412
1413
  constantList,
1413
1414
  setConstantList,
1414
- changeAlias
1415
+ changeAlias,
1416
+ popupContainer
1415
1417
  };
1416
1418
  };
1417
1419
 
@@ -1813,6 +1815,7 @@ const getComputedTranslate = obj => {
1813
1815
  };
1814
1816
  // 获取元素距离浏览器顶部的距离
1815
1817
  const getElementTop = elem => {
1818
+ if (!elem) return 0;
1816
1819
  let elemTop = elem.offsetTop;
1817
1820
  let pElem = elem.offsetParent;
1818
1821
  while (pElem != null) {
@@ -1826,6 +1829,7 @@ const getElementTop = elem => {
1826
1829
  };
1827
1830
  // 获取元素距离浏览器顶部的距离
1828
1831
  const getElementLeft = elem => {
1832
+ if (!elem) return 0;
1829
1833
  let elemLeft = elem.offsetLeft;
1830
1834
  let pElem = elem.offsetParent;
1831
1835
  while (pElem != null) {
@@ -1837,8 +1841,23 @@ const getElementLeft = elem => {
1837
1841
  }
1838
1842
  return elemLeft;
1839
1843
  };
1840
- const getScrollTop = () => {
1841
- return document.documentElement.scrollTop;
1844
+ // 获取元素可见范围内高度
1845
+ const getContainerVisibleHeight = container => {
1846
+ if (!container) return 0;
1847
+ const rect = container.getBoundingClientRect();
1848
+ const windowHeight = window.innerHeight || document.documentElement.clientHeight;
1849
+ // 元素顶部在视口上方 -> 不可见
1850
+ if (rect.bottom < 0) return 0;
1851
+ // 元素底部在视口下方 -> 不可见
1852
+ if (rect.top > windowHeight) return 0;
1853
+ // 可见区域的 top 和 bottom
1854
+ const visibleTop = Math.max(rect.top, 0);
1855
+ const visibleBottom = Math.min(rect.bottom, windowHeight);
1856
+ // 可见高度
1857
+ return visibleBottom - visibleTop;
1858
+ };
1859
+ const getScrollTop = elem => {
1860
+ return elem?.scrollTop || document.documentElement.scrollTop;
1842
1861
  };
1843
1862
  // 浏览器可视宽高
1844
1863
  const getWindowSize = () => {
@@ -3409,6 +3428,7 @@ function returnDocument(element) {
3409
3428
  const outSpacing = 10;
3410
3429
  function generateTrigger(PortalComponent) {
3411
3430
  class Trigger extends React.Component {
3431
+ resizeObserver = null; // 显式声明 resizeObserver 属性
3412
3432
  resetId = -1; // 监听窗口改变事件id 用于组件销毁的时候清除事件
3413
3433
  static defaultProps = {
3414
3434
  visible: false,
@@ -3423,11 +3443,39 @@ function generateTrigger(PortalComponent) {
3423
3443
  this.resetId = winResetEvent.addEvent(this.didUpdate, this, 300);
3424
3444
  this.props.container && this.props.container.addEventListener('scroll', this.didUpdate);
3425
3445
  this.bindEvent();
3446
+ // 延迟绑定 ResizeObserver 到 ensure the element is ready
3447
+ this.initResizeObserver();
3448
+ }
3449
+ componentDidUpdate(prevProps) {
3450
+ // 如果 children 发生变化,重新初始化观察器
3451
+ if (prevProps.children !== this.props.children) {
3452
+ this.initResizeObserver();
3453
+ }
3426
3454
  }
3427
3455
  componentWillUnmount() {
3428
3456
  winResetEvent.removeEvent(this.resetId);
3429
3457
  this.props.container && this.props.container.removeEventListener('scroll', this.didUpdate);
3458
+ if (this.resizeObserver) {
3459
+ this.resizeObserver.disconnect();
3460
+ this.resizeObserver = null;
3461
+ }
3430
3462
  }
3463
+ // children高度变化后,从新计算高度
3464
+ initResizeObserver = () => {
3465
+ const targetNode = this.ref.current;
3466
+ if (!targetNode) return;
3467
+ // 如果已经存在 ResizeObserver,先断开连接
3468
+ if (this.resizeObserver) {
3469
+ this.resizeObserver.disconnect();
3470
+ }
3471
+ // 初始化 ResizeObserver 并开始观察目标节点
3472
+ this.resizeObserver = new ResizeObserver(entries => {
3473
+ entries.forEach(entry => {
3474
+ this.didUpdate();
3475
+ });
3476
+ });
3477
+ this.resizeObserver.observe(targetNode);
3478
+ };
3431
3479
  bindEvent = () => {
3432
3480
  let that = this;
3433
3481
  returnDocument().body.addEventListener('click', function (e) {
@@ -3445,7 +3493,7 @@ function generateTrigger(PortalComponent) {
3445
3493
  this.props.visible && this.props.closable && this.props.hideVisible();
3446
3494
  };
3447
3495
  attachParent = popupContainer => {
3448
- let mountNode = returnDocument().body;
3496
+ let mountNode = this.props.container || returnDocument().body;
3449
3497
  mountNode.appendChild(popupContainer);
3450
3498
  };
3451
3499
  getCurrentNodePos = () => {
@@ -3454,8 +3502,9 @@ function generateTrigger(PortalComponent) {
3454
3502
  container
3455
3503
  } = this.props;
3456
3504
  return {
3457
- x: getElementLeft(node),
3458
- y: getElementTop(node) - (container?.scrollTop || 0),
3505
+ x: getElementLeft(node) - getElementLeft(container),
3506
+ y: getElementTop(node) - getElementTop(container),
3507
+ t: getElementTop(container),
3459
3508
  h: node.offsetHeight
3460
3509
  };
3461
3510
  };
@@ -3498,19 +3547,21 @@ function generateTrigger(PortalComponent) {
3498
3547
  didUpdate = () => {
3499
3548
  if (!this.props.node) return false;
3500
3549
  let {
3501
- innerSpacing = 10
3550
+ innerSpacing = 10,
3551
+ container
3502
3552
  } = this.props;
3503
3553
  let pos = this.getCurrentNodePos();
3504
- let posY = pos.y - getScrollTop();
3554
+ let posY = pos.y - getScrollTop(container);
3505
3555
  if (!this.ref) return false;
3506
3556
  let realHeight = this.ref?.current?.childNodes?.[0]?.offsetHeight || 0;
3507
3557
  if (!realHeight) return false;
3508
3558
  let {
3509
3559
  height: winH
3510
3560
  } = getWindowSize();
3511
- let downH = winH - posY - pos.h; // 元素下面可用高度
3561
+ let containerH = getContainerVisibleHeight(container);
3562
+ let downH = (containerH || winH) - posY - pos.h; // 元素下面可用高度
3512
3563
  let maxHeight = 0;
3513
- let topHeight = getScrollTop();
3564
+ let topHeight = getScrollTop(container);
3514
3565
  if (downH >= posY || realHeight <= downH - innerSpacing - outSpacing) {
3515
3566
  // 下面比上面宽敞 或 下面足够放下所有 放下面
3516
3567
  maxHeight = Math.min(realHeight, downH - innerSpacing - outSpacing);
@@ -5983,10 +6034,11 @@ const JoinData = props => {
5983
6034
  let oldList = cloneDeep(newMeta[index].subquery);
5984
6035
  let _toolbar = subToolbar || toolbar;
5985
6036
  _toolbar = _toolbar.filter(v => v !== 'group'); // 子查询不需要分组
6037
+ let zIndex = store.popupContainer.current ? getMaxZIndexInParents(store.popupContainer.current) : 0;
5986
6038
  let o = Modal2.openModal({
5987
6039
  title: __('SqlQueryBuilder.subquery'),
5988
6040
  transparentMask: true,
5989
- zIndex: 200,
6041
+ zIndex: Number(zIndex),
5990
6042
  content: jsx(Fragment, {
5991
6043
  children: jsx(SqlVisionBuilder, {
5992
6044
  ...other,
@@ -7026,10 +7078,11 @@ const CustomColumn = props => {
7026
7078
  const showSubQuery = (e, i) => {
7027
7079
  let newMeta = store.metaList[groupIndex].list.slice();
7028
7080
  const _value = newMeta[index].customColumn[i] || [];
7081
+ let zIndex = store.popupContainer.current ? getMaxZIndexInParents(store.popupContainer.current) : 0;
7029
7082
  let o = Modal2.openModal({
7030
7083
  title: __('SqlQueryBuilder.customExpression'),
7031
7084
  transparentMask: true,
7032
- zIndex: 200,
7085
+ zIndex: Number(zIndex),
7033
7086
  content: jsx(Fragment, {
7034
7087
  children: jsx(Provider, {
7035
7088
  value: store,
@@ -7401,10 +7454,11 @@ const Filter = props => {
7401
7454
  let oldList = position ? [] : cloneDeep(newMeta[index].filter[i]?.subquery || []);
7402
7455
  let _toolbar = subToolbar || toolbar;
7403
7456
  _toolbar = _toolbar.filter(v => v !== 'group'); // 子查询不需要分组
7457
+ let zIndex = store.popupContainer.current ? getMaxZIndexInParents(store.popupContainer.current) : null;
7404
7458
  let o = Modal2.openModal({
7405
7459
  title: 'NOT EXISTS',
7406
7460
  transparentMask: true,
7407
- zIndex: 200,
7461
+ zIndex: Number(zIndex),
7408
7462
  content: jsx(Fragment, {
7409
7463
  children: jsx(SqlVisionBuilder, {
7410
7464
  ...other,
@@ -7740,7 +7794,7 @@ const GroupBy = props => {
7740
7794
  newMeta[index].by.splice(i, 1, data);
7741
7795
  // @ts-ignore
7742
7796
  newMeta[index].by = newMeta[index].by.map(v => {
7743
- const fieldAlias = v.fieldAlias || `${v.alias}__${v.name}`;
7797
+ const fieldAlias = `${v.alias}__${v.name}`;
7744
7798
  return {
7745
7799
  ...v,
7746
7800
  sql: `${v.alias}.${v.realName || v.name} AS ${fieldAlias}`,
@@ -7792,7 +7846,7 @@ const GroupBy = props => {
7792
7846
  newMeta[index].by.push(data);
7793
7847
  // @ts-ignore
7794
7848
  newMeta[index].by = newMeta[index].by.map(v => {
7795
- const fieldAlias = v.fieldAlias || `${v.alias}__${v.name}`;
7849
+ const fieldAlias = `${v.alias}__${v.name}`;
7796
7850
  return {
7797
7851
  ...v,
7798
7852
  sql: `${v.alias}.${v.realName || v.name} AS ${fieldAlias}`,
@@ -8607,7 +8661,8 @@ const Metabase = props => {
8607
8661
  } = props;
8608
8662
  const store = useStore$1();
8609
8663
  const [saveLoading, setSaveLoading] = useState(false);
8610
- const popupContainer = useRef();
8664
+ // const popupContainer = useRef();
8665
+ // store.setPopupContainer(popupContainer);
8611
8666
  const popupContent = useMemo(() => {
8612
8667
  let {
8613
8668
  visible,
@@ -8638,11 +8693,11 @@ const Metabase = props => {
8638
8693
  await onOk?.(_metaList);
8639
8694
  setSaveLoading(false);
8640
8695
  };
8641
- let zIndex = popupContainer.current ? getMaxZIndexInParents(popupContainer.current) : null;
8696
+ let zIndex = store.popupContainer.current ? getMaxZIndexInParents(store.popupContainer.current) : null;
8642
8697
  return (
8643
8698
  // @ts-ignore
8644
8699
  jsx(VisualBox, {
8645
- ref: popupContainer,
8700
+ ref: store.popupContainer,
8646
8701
  children: jsxs("div", {
8647
8702
  className: 'Sqb',
8648
8703
  children: [store.metaList.map((v, index) => {
@@ -8679,8 +8734,8 @@ const Metabase = props => {
8679
8734
  disabled: saveLoading,
8680
8735
  onClick: onSave,
8681
8736
  children: btnText || __('SqlQueryBuilder.visualize')
8682
- }) : null, popupContainer.current && jsx(Popup, {
8683
- container: popupContainer.current,
8737
+ }) : null, store.popupContainer.current && jsx(Popup, {
8738
+ container: store.popupContainer.current,
8684
8739
  visible: store.popupData.visible,
8685
8740
  node: store.popupData.node,
8686
8741
  closable: store.popupClosable,
@@ -8691,8 +8746,8 @@ const Metabase = props => {
8691
8746
  });
8692
8747
  },
8693
8748
  children: popupContent
8694
- }), popupContainer.current && jsx(Popup, {
8695
- container: popupContainer.current,
8749
+ }), store.popupContainer.current && jsx(Popup, {
8750
+ container: store.popupContainer.current,
8696
8751
  visible: store.popupData2.visible,
8697
8752
  node: store.popupData2.node,
8698
8753
  closable: store.popupClosable2,