@evergis/react 4.0.143 → 4.0.145
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/dist/components/Dashboard/components/ResizeHandle/constants.d.ts +15 -0
- package/dist/components/Dashboard/components/ResizeHandle/index.d.ts +3 -0
- package/dist/components/Dashboard/components/ResizeHandle/styled.d.ts +17 -0
- package/dist/components/Dashboard/components/ResizeHandle/types.d.ts +2 -0
- package/dist/components/Dashboard/components/index.d.ts +1 -0
- package/dist/components/Dashboard/containers/StructuredDataContainer/types.d.ts +12 -1
- package/dist/components/Dashboard/elements/ElementTable/components/AttachmentsCell.d.ts +9 -0
- package/dist/components/Dashboard/elements/ElementTable/components/TableColumnResizer.d.ts +9 -0
- package/dist/components/Dashboard/elements/ElementTable/components/TableHeadRow.d.ts +9 -0
- package/dist/components/Dashboard/elements/ElementTable/constants.d.ts +2 -0
- package/dist/components/Dashboard/elements/ElementTable/hooks/useAttachmentsCell.d.ts +26 -0
- package/dist/components/Dashboard/elements/ElementTable/hooks/useColumnResize.d.ts +19 -0
- package/dist/components/Dashboard/elements/ElementTable/hooks/useTableView.d.ts +5 -0
- package/dist/components/Dashboard/elements/ElementTable/styled.d.ts +31 -3
- package/dist/components/Dashboard/elements/ElementTable/types.d.ts +16 -0
- package/dist/components/Dashboard/elements/ElementTable/utils/columnStyle.d.ts +19 -0
- package/dist/components/Dashboard/grid/constants.d.ts +0 -14
- package/dist/components/Dashboard/grid/hooks/useGridHeightResize.d.ts +2 -2
- package/dist/components/Dashboard/grid/hooks/useGridResize.d.ts +6 -10
- package/dist/components/Dashboard/hooks/index.d.ts +1 -0
- package/dist/components/Dashboard/hooks/useResizeDrag.d.ts +29 -0
- package/dist/components/Dashboard/types.d.ts +19 -0
- package/dist/index.js +409 -145
- package/dist/index.js.map +1 -1
- package/dist/react.esm.js +408 -145
- package/dist/react.esm.js.map +1 -1
- package/package.json +2 -2
package/dist/react.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import styled, { createGlobalStyle, css, useTheme } from 'styled-components';
|
|
2
|
-
import { Icon, IconButtonInnerChild, IconButton, Flex, transition, Chip, shadows, Description, Divider, Popup, Menu, IconToggleButton, LinearProgress, Tooltip as Tooltip$1, IconToggle, Preview, LegendToggler, DropdownField, MultiSelectContainer, IconButtonButton,
|
|
2
|
+
import { Icon, IconButtonInnerChild, IconButton, Flex, transition, Chip, shadows, Description, Divider, useDragAndDropEffect, Popup, Menu, IconToggleButton, LinearProgress, Tooltip as Tooltip$1, IconToggle, Preview, LegendToggler, DropdownField, MultiSelectContainer, IconButtonButton, FlatButton, DraggableTreeContainer, DraggableTree, FlexSpan, Dialog, DialogTitle, ActionsGroup, DialogContent, DialogActions, RaisedButton, UploaderItemArea, UploaderTitleWrapper, RadioGroup, Dropdown, Input, Switch, Checkbox, Radio, ThemeProvider, darkTheme, CircularProgress, AutoComplete, Slider, DatePicker, getLocale, H2, Blank, Popover, NumberInput, Uploader, NumberRangeSlider, useAsyncAutocomplete, RangeNumberInput, TreeDropdown, defaultTheme, dateFormat } from '@evergis/uilib-gl';
|
|
3
3
|
import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
|
|
4
4
|
import { isValidElement, Fragment, createContext, memo, useRef, useState, useCallback, useEffect, useContext, useMemo, createElement, useLayoutEffect, forwardRef } from 'react';
|
|
5
5
|
import { barChartClassNames, lineChartClassNames, BarChart as BarChart$1, LineChart, PieChart } from '@evergis/charts';
|
|
@@ -8168,6 +8168,47 @@ const useProjectDashboardInit = () => {
|
|
|
8168
8168
|
}, [projectInfo, updateProject]);
|
|
8169
8169
|
};
|
|
8170
8170
|
|
|
8171
|
+
/**
|
|
8172
|
+
* Перетаскивание границы: подписка на ручку, снимок на старте, предпросмотр на движении,
|
|
8173
|
+
* запись результата на отпускании.
|
|
8174
|
+
*
|
|
8175
|
+
* Общий для сетки дашборда и колонок таблицы. Различаются они только тем, что именно меряют и
|
|
8176
|
+
* куда пишут; сам жест обязан ощущаться одинаково — включая то, что мышь ведут по документу, а
|
|
8177
|
+
* не по самой ручке, и отпускание за пределами окна тоже завершает жест.
|
|
8178
|
+
*/
|
|
8179
|
+
const useResizeDrag = ({ onStart, onMove, onEnd }) => {
|
|
8180
|
+
const [handle, setHandle] = useState(null);
|
|
8181
|
+
const [dragging, setDragging] = useState(false);
|
|
8182
|
+
const stateRef = useRef(null);
|
|
8183
|
+
const mouseDown = useCallback((event) => {
|
|
8184
|
+
const state = onStart(event);
|
|
8185
|
+
if (state === null) {
|
|
8186
|
+
return;
|
|
8187
|
+
}
|
|
8188
|
+
// Гасим выделение текста: жест ведут мышью по документу, и без этого он выделял бы всё,
|
|
8189
|
+
// над чем проходит курсор.
|
|
8190
|
+
event.preventDefault();
|
|
8191
|
+
stateRef.current = state;
|
|
8192
|
+
setDragging(true);
|
|
8193
|
+
}, [onStart]);
|
|
8194
|
+
const mouseMove = useCallback((event) => {
|
|
8195
|
+
if (stateRef.current !== null) {
|
|
8196
|
+
onMove(stateRef.current, event);
|
|
8197
|
+
}
|
|
8198
|
+
}, [onMove]);
|
|
8199
|
+
const mouseUp = useCallback((event) => {
|
|
8200
|
+
const state = stateRef.current;
|
|
8201
|
+
if (state === null) {
|
|
8202
|
+
return;
|
|
8203
|
+
}
|
|
8204
|
+
stateRef.current = null;
|
|
8205
|
+
setDragging(false);
|
|
8206
|
+
onEnd(state, event);
|
|
8207
|
+
}, [onEnd]);
|
|
8208
|
+
useDragAndDropEffect(handle, { mouseDown, mouseMove, mouseUp });
|
|
8209
|
+
return { setHandle, dragging };
|
|
8210
|
+
};
|
|
8211
|
+
|
|
8171
8212
|
const useRelatedDataSourceAttributes = ({ type = WidgetType.Dashboard, elementConfig, dataSources, feature, }) => {
|
|
8172
8213
|
const { layerInfos } = useWidgetContext(type);
|
|
8173
8214
|
const { currentPage } = useWidgetPage(type);
|
|
@@ -9602,6 +9643,92 @@ const FiltersContainer = memo(({ elementConfig, config, type, renderElement }) =
|
|
|
9602
9643
|
return (jsxs(ContainerRoot, { ...root, children: [jsx(ContainerBackground, { elementConfig: elementConfig, renderElement: renderElement }), jsx(Flex, { mb: !isVisible && selectedItems.length ? "2rem" : 0, children: jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }) }), isLoading && jsx(ContainerLoading, {}), !isLoading && isVisible && (jsx(FiltersContainerWrapper, { ...body, "$padding": padding, "$bgColor": bgColor, "$fontSize": fontSize, "$fontColor": fontColor, children: filterItems?.map(renderFilter) })), jsx(HiddenTitleItems, { elementConfig: elementConfig, config: config, type: type, filter: filterItems[0]?.options?.filterName })] }));
|
|
9603
9644
|
});
|
|
9604
9645
|
|
|
9646
|
+
/**
|
|
9647
|
+
* Заход зоны захвата на содержимое с каждой стороны границы, px.
|
|
9648
|
+
*
|
|
9649
|
+
* Без него попасть курсором ровно в границу невозможно: у таблицы её толщина — один пиксель,
|
|
9650
|
+
* а у сетки зазора может не быть вовсе. Ручка абсолютная и в раскладке не участвует, поэтому
|
|
9651
|
+
* расширение ничего не сдвигает.
|
|
9652
|
+
*/
|
|
9653
|
+
const HANDLE_BLEED_PX = 3;
|
|
9654
|
+
/**
|
|
9655
|
+
* Маркер ручки: нажатие на ней тянет границу, а не ячейку сетки.
|
|
9656
|
+
*
|
|
9657
|
+
* Ставит его сам компонент. Ручка колонки таблицы, оказавшейся внутри ячейки сетки, обязана
|
|
9658
|
+
* помечаться так же — иначе нажатие на ней начинало бы перетаскивание всей ячейки.
|
|
9659
|
+
*/
|
|
9660
|
+
const RESIZE_HANDLE_ATTR = "data-grid-handle";
|
|
9661
|
+
|
|
9662
|
+
/**
|
|
9663
|
+
* Зона захвата = зазор плюс небольшой заход на содержимое с обеих сторон.
|
|
9664
|
+
*
|
|
9665
|
+
* Смещение уводит дальний край ручки за зазор ровно на `HANDLE_BLEED_PX`, поэтому вместе с
|
|
9666
|
+
* шириной она оказывается симметрично «надета» на границу: от `-bleed` до `gap + bleed`.
|
|
9667
|
+
*/
|
|
9668
|
+
const handleSize = `calc(var(--grid-gap, 0px) + ${HANDLE_BLEED_PX * 2}px)`;
|
|
9669
|
+
const handleOffset = `calc(-1 * (var(--grid-gap, 0px) + ${HANDLE_BLEED_PX}px))`;
|
|
9670
|
+
/**
|
|
9671
|
+
* Ручка перетаскивания границы. Общая для сетки дашборда и колонок таблицы: жест один и тот же,
|
|
9672
|
+
* и выглядеть он обязан одинаково.
|
|
9673
|
+
*
|
|
9674
|
+
* Абсолютная и целиком лежит в зазоре, поэтому включение режима редактирования не сдвигает
|
|
9675
|
+
* раскладку ни на пиксель. Сам ползунок (`::after`) появляется только при наведении и во время
|
|
9676
|
+
* перетаскивания — в покое раскладка выглядит как обычно.
|
|
9677
|
+
*
|
|
9678
|
+
* Ширину зазора берёт из переменной: у сетки её объявляет тело сетки, у таблицы зазора нет вовсе,
|
|
9679
|
+
* и зона захвата сжимается до одного захода на содержимое с каждой стороны.
|
|
9680
|
+
*/
|
|
9681
|
+
const ResizeHandle = styled.div.attrs({ [RESIZE_HANDLE_ATTR]: true }).withConfig({ displayName: "ResizeHandle", componentId: "sc-1n6ja5b" }) `
|
|
9682
|
+
position: absolute;
|
|
9683
|
+
z-index: 3;
|
|
9684
|
+
touch-action: none;
|
|
9685
|
+
|
|
9686
|
+
::after {
|
|
9687
|
+
content: "";
|
|
9688
|
+
position: absolute;
|
|
9689
|
+
border-radius: 0.0625rem;
|
|
9690
|
+
background: transparent;
|
|
9691
|
+
transition: background-color 120ms ease;
|
|
9692
|
+
}
|
|
9693
|
+
|
|
9694
|
+
:hover::after,
|
|
9695
|
+
&[data-dragging="true"]::after {
|
|
9696
|
+
background: ${({ theme: { palette } }) => palette.primary};
|
|
9697
|
+
}
|
|
9698
|
+
|
|
9699
|
+
${({ $axis }) => $axis === "column"
|
|
9700
|
+
? css `
|
|
9701
|
+
top: 0;
|
|
9702
|
+
bottom: 0;
|
|
9703
|
+
right: ${handleOffset};
|
|
9704
|
+
width: ${handleSize};
|
|
9705
|
+
cursor: col-resize;
|
|
9706
|
+
|
|
9707
|
+
::after {
|
|
9708
|
+
top: 20%;
|
|
9709
|
+
bottom: 20%;
|
|
9710
|
+
left: 50%;
|
|
9711
|
+
width: 0.125rem;
|
|
9712
|
+
transform: translateX(-50%);
|
|
9713
|
+
}
|
|
9714
|
+
`
|
|
9715
|
+
: css `
|
|
9716
|
+
left: 0;
|
|
9717
|
+
right: 0;
|
|
9718
|
+
bottom: ${handleOffset};
|
|
9719
|
+
height: ${handleSize};
|
|
9720
|
+
cursor: row-resize;
|
|
9721
|
+
|
|
9722
|
+
::after {
|
|
9723
|
+
left: 20%;
|
|
9724
|
+
right: 20%;
|
|
9725
|
+
top: 50%;
|
|
9726
|
+
height: 0.125rem;
|
|
9727
|
+
transform: translateY(-50%);
|
|
9728
|
+
}
|
|
9729
|
+
`};
|
|
9730
|
+
`;
|
|
9731
|
+
|
|
9605
9732
|
/** Размер, при котором контейнер занимает всю ячейку родителя. */
|
|
9606
9733
|
const FILL_SIZE = "100%";
|
|
9607
9734
|
/** Собственные горизонтальные дефолты обёртки, мешающие контейнеру занять всю ширину ячейки. */
|
|
@@ -9681,6 +9808,7 @@ const getWrapperSizeStyle = ({ style, width: widthOption, height: heightOption,
|
|
|
9681
9808
|
};
|
|
9682
9809
|
};
|
|
9683
9810
|
|
|
9811
|
+
// Прямой импорт листового модуля, а не барреля components: тот тянет за собой контейнеры.
|
|
9684
9812
|
/**
|
|
9685
9813
|
* Минимальный размер трека, px. Ниже него ресайз не пускает — иначе ячейку не за что схватить.
|
|
9686
9814
|
*
|
|
@@ -9716,14 +9844,6 @@ const GRID_AUTO_FILL_DEFAULTS = { ...CONTAINERS_GROUP_DEFAULTS, minHeight: FILL_
|
|
|
9716
9844
|
* раскладки, поэтому задаётся явно через `options.gap`, а не навязывается всем сеткам.
|
|
9717
9845
|
*/
|
|
9718
9846
|
const DEFAULT_GRID_GAP = 0;
|
|
9719
|
-
/**
|
|
9720
|
-
* Насколько ручка ресайза заходит на содержимое с каждой стороны, px.
|
|
9721
|
-
*
|
|
9722
|
-
* По умолчанию зазора нет вовсе, так что попасть курсором ровно в границу невозможно — зона
|
|
9723
|
-
* захвата всегда шире зазора на эту величину с каждой стороны. Ручка абсолютная и в раскладке
|
|
9724
|
-
* не участвует, поэтому расширение ничего не сдвигает.
|
|
9725
|
-
*/
|
|
9726
|
-
const HANDLE_BLEED_PX = 3;
|
|
9727
9847
|
/**
|
|
9728
9848
|
* Сдвиг курсора, после которого нажатие на ячейке считается перетаскиванием, px.
|
|
9729
9849
|
*
|
|
@@ -9733,17 +9853,13 @@ const HANDLE_BLEED_PX = 3;
|
|
|
9733
9853
|
const DRAG_THRESHOLD_PX = 4;
|
|
9734
9854
|
/** Маркер ячейки в DOM: по нему ищется цель перетаскивания под курсором. */
|
|
9735
9855
|
const GRID_CELL_ATTR = "data-grid-cell";
|
|
9736
|
-
/** Маркер ручки ресайза: нажатие на ней тянет границу, а не ячейку. */
|
|
9737
|
-
const GRID_HANDLE_ATTR = "data-grid-handle";
|
|
9738
|
-
/** Тот же маркер пропсами: имя атрибута вычисляемое, а в JSX такое подставляется только спредом. */
|
|
9739
|
-
const GRID_HANDLE_PROPS = { [GRID_HANDLE_ATTR]: true };
|
|
9740
9856
|
/**
|
|
9741
9857
|
* Нажатия, которые перетаскиванием ячейки не считаются.
|
|
9742
9858
|
*
|
|
9743
9859
|
* Ручка тянет границу трека, а поля ввода живут своей жизнью: там нажатие ставит каретку и
|
|
9744
9860
|
* выделяет текст, и подменять это перестановкой ячеек нельзя.
|
|
9745
9861
|
*/
|
|
9746
|
-
const NO_CELL_DRAG_SELECTOR = `[${
|
|
9862
|
+
const NO_CELL_DRAG_SELECTOR = `[${RESIZE_HANDLE_ATTR}], input, textarea, select, [contenteditable="true"]`;
|
|
9747
9863
|
/**
|
|
9748
9864
|
* Разметка идущего жеста: ячейка-источник, цель под курсором и сам факт перетаскивания.
|
|
9749
9865
|
*
|
|
@@ -9764,72 +9880,6 @@ const FR_PRECISION = 1000;
|
|
|
9764
9880
|
const GRID_ROW_ID_PREFIX = "gridRow_";
|
|
9765
9881
|
const GRID_CELL_ID_PREFIX = "gridCell_";
|
|
9766
9882
|
|
|
9767
|
-
/**
|
|
9768
|
-
* Зона захвата = зазор плюс небольшой заход на содержимое с обеих сторон.
|
|
9769
|
-
*
|
|
9770
|
-
* Смещение уводит дальний край ручки за зазор ровно на `HANDLE_BLEED_PX`, поэтому вместе с
|
|
9771
|
-
* шириной она оказывается симметрично «надета» на границу: от `-bleed` до `gap + bleed`.
|
|
9772
|
-
*/
|
|
9773
|
-
const handleSize = `calc(var(--grid-gap, 0px) + ${HANDLE_BLEED_PX * 2}px)`;
|
|
9774
|
-
const handleOffset = `calc(-1 * (var(--grid-gap, 0px) + ${HANDLE_BLEED_PX}px))`;
|
|
9775
|
-
/**
|
|
9776
|
-
* Ручка перетаскивания границы треков.
|
|
9777
|
-
*
|
|
9778
|
-
* Абсолютная и целиком лежит в зазоре, поэтому включение режима редактирования не сдвигает
|
|
9779
|
-
* раскладку ни на пиксель. Сам ползунок (`::after`) появляется только при наведении и во время
|
|
9780
|
-
* перетаскивания — в покое сетка выглядит как обычно.
|
|
9781
|
-
*/
|
|
9782
|
-
const ResizeHandle = styled.div.withConfig({ displayName: "ResizeHandle", componentId: "sc-1dtcak4" }) `
|
|
9783
|
-
position: absolute;
|
|
9784
|
-
z-index: 3;
|
|
9785
|
-
touch-action: none;
|
|
9786
|
-
|
|
9787
|
-
::after {
|
|
9788
|
-
content: "";
|
|
9789
|
-
position: absolute;
|
|
9790
|
-
border-radius: 0.0625rem;
|
|
9791
|
-
background: transparent;
|
|
9792
|
-
transition: background-color 120ms ease;
|
|
9793
|
-
}
|
|
9794
|
-
|
|
9795
|
-
:hover::after,
|
|
9796
|
-
&[data-dragging="true"]::after {
|
|
9797
|
-
background: ${({ theme: { palette } }) => palette.primary};
|
|
9798
|
-
}
|
|
9799
|
-
|
|
9800
|
-
${({ $axis }) => $axis === "column"
|
|
9801
|
-
? css `
|
|
9802
|
-
top: 0;
|
|
9803
|
-
bottom: 0;
|
|
9804
|
-
right: ${handleOffset};
|
|
9805
|
-
width: ${handleSize};
|
|
9806
|
-
cursor: col-resize;
|
|
9807
|
-
|
|
9808
|
-
::after {
|
|
9809
|
-
top: 20%;
|
|
9810
|
-
bottom: 20%;
|
|
9811
|
-
left: 50%;
|
|
9812
|
-
width: 0.125rem;
|
|
9813
|
-
transform: translateX(-50%);
|
|
9814
|
-
}
|
|
9815
|
-
`
|
|
9816
|
-
: css `
|
|
9817
|
-
left: 0;
|
|
9818
|
-
right: 0;
|
|
9819
|
-
bottom: ${handleOffset};
|
|
9820
|
-
height: ${handleSize};
|
|
9821
|
-
cursor: row-resize;
|
|
9822
|
-
|
|
9823
|
-
::after {
|
|
9824
|
-
left: 20%;
|
|
9825
|
-
right: 20%;
|
|
9826
|
-
top: 50%;
|
|
9827
|
-
height: 0.125rem;
|
|
9828
|
-
transform: translateY(-50%);
|
|
9829
|
-
}
|
|
9830
|
-
`};
|
|
9831
|
-
`;
|
|
9832
|
-
|
|
9833
9883
|
const getTemplateProperty = (axis) => axis === "row" ? "gridTemplateRows" : "gridTemplateColumns";
|
|
9834
9884
|
/**
|
|
9835
9885
|
* Пиксельные размеры треков отрисованной сетки.
|
|
@@ -9917,29 +9967,24 @@ const toShares = (pixels, total) => {
|
|
|
9917
9967
|
* снова раздувалась содержимым.
|
|
9918
9968
|
*/
|
|
9919
9969
|
const useGridHeightResize = ({ sizes, autoHeight, getGrid, onCommit, }) => {
|
|
9920
|
-
const [handle, setHandle] = useState(null);
|
|
9921
|
-
const [dragging, setDragging] = useState(false);
|
|
9922
|
-
const dragRef = useRef(null);
|
|
9923
9970
|
const sizesRef = useRef(sizes);
|
|
9924
9971
|
sizesRef.current = sizes;
|
|
9925
9972
|
/** Свойство корня, которым жест двигает нижнюю границу: жёсткая высота либо её минимум. */
|
|
9926
9973
|
const heightProperty = autoHeight ? "minHeight" : "height";
|
|
9927
|
-
const
|
|
9974
|
+
const onStart = useCallback((event) => {
|
|
9928
9975
|
const grid = getGrid();
|
|
9929
9976
|
const root = grid?.parentElement;
|
|
9930
9977
|
if (!grid || !root)
|
|
9931
|
-
return;
|
|
9978
|
+
return null;
|
|
9932
9979
|
const pixels = readTrackPixels(grid, "row");
|
|
9933
9980
|
if (!pixels?.length || pixels.length !== sizesRef.current.length)
|
|
9934
|
-
return;
|
|
9935
|
-
|
|
9936
|
-
dragRef.current = {
|
|
9981
|
+
return null;
|
|
9982
|
+
return {
|
|
9937
9983
|
start: event.clientY,
|
|
9938
9984
|
pixels,
|
|
9939
9985
|
root,
|
|
9940
9986
|
rootHeight: root.getBoundingClientRect().height,
|
|
9941
9987
|
};
|
|
9942
|
-
setDragging(true);
|
|
9943
9988
|
}, [getGrid]);
|
|
9944
9989
|
/** Пиксели треков после сдвига: меняется только последний, минимум — текущий, если он уже мал. */
|
|
9945
9990
|
const getNextPixels = useCallback((state, event) => {
|
|
@@ -9947,22 +9992,16 @@ const useGridHeightResize = ({ sizes, autoHeight, getGrid, onCommit, }) => {
|
|
|
9947
9992
|
const min = Math.min(MIN_TRACK_PX, last);
|
|
9948
9993
|
return [...state.pixels.slice(0, -1), Math.max(last + event.clientY - state.start, min)];
|
|
9949
9994
|
}, []);
|
|
9950
|
-
const
|
|
9951
|
-
const state = dragRef.current;
|
|
9995
|
+
const onMove = useCallback((state, event) => {
|
|
9952
9996
|
const grid = getGrid();
|
|
9953
|
-
if (!
|
|
9997
|
+
if (!grid)
|
|
9954
9998
|
return;
|
|
9955
9999
|
const pixels = getNextPixels(state, event);
|
|
9956
10000
|
const delta = pixels[pixels.length - 1] - state.pixels[state.pixels.length - 1];
|
|
9957
10001
|
state.root.style[heightProperty] = `${state.rootHeight + delta}px`;
|
|
9958
10002
|
grid.style[getTemplateProperty("row")] = buildTrackTemplate(pixels.map(size => `${size}px`), autoHeight);
|
|
9959
10003
|
}, [autoHeight, getGrid, getNextPixels, heightProperty]);
|
|
9960
|
-
const
|
|
9961
|
-
const state = dragRef.current;
|
|
9962
|
-
if (!state)
|
|
9963
|
-
return;
|
|
9964
|
-
dragRef.current = null;
|
|
9965
|
-
setDragging(false);
|
|
10004
|
+
const onEnd = useCallback((state, event) => {
|
|
9966
10005
|
const grid = getGrid();
|
|
9967
10006
|
if (grid)
|
|
9968
10007
|
grid.style[getTemplateProperty("row")] = "";
|
|
@@ -9974,8 +10013,7 @@ const useGridHeightResize = ({ sizes, autoHeight, getGrid, onCommit, }) => {
|
|
|
9974
10013
|
const total = sizesRef.current.reduce((value, size) => value + size, 0);
|
|
9975
10014
|
onCommit(`${Math.round(state.rootHeight + delta)}px`, toShares(pixels, total));
|
|
9976
10015
|
}, [getGrid, getNextPixels, heightProperty, onCommit]);
|
|
9977
|
-
|
|
9978
|
-
return { setHandle, dragging };
|
|
10016
|
+
return useResizeDrag({ onStart, onMove, onEnd });
|
|
9979
10017
|
};
|
|
9980
10018
|
|
|
9981
10019
|
/**
|
|
@@ -9988,7 +10026,7 @@ const GridHeightResizer = memo(({ sizes, autoHeight, getGrid, onCommit }) => {
|
|
|
9988
10026
|
// Ручка лежит внутри трека: без остановки всплытия перетаскивание границы заканчивалось бы
|
|
9989
10027
|
// кликом по ячейке, то есть меняло бы выделение.
|
|
9990
10028
|
const stopPropagation = useCallback((event) => event.stopPropagation(), []);
|
|
9991
|
-
return (jsx(ResizeHandle, {
|
|
10029
|
+
return (jsx(ResizeHandle, { ref: setHandle, "$axis": "row", "data-dragging": dragging, onClick: stopPropagation }));
|
|
9992
10030
|
});
|
|
9993
10031
|
|
|
9994
10032
|
const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
@@ -10009,31 +10047,26 @@ const buildPreviewTemplate = (pixels, index, first, second) => buildTrackTemplat
|
|
|
10009
10047
|
/**
|
|
10010
10048
|
* Перетаскивание границы между двумя соседними треками.
|
|
10011
10049
|
*
|
|
10012
|
-
*
|
|
10013
|
-
*
|
|
10014
|
-
* на отпускание мыши.
|
|
10050
|
+
* Сам жест — общий {@link useResizeDrag}: он же двигает и границы колонок таблицы, поэтому
|
|
10051
|
+
* ощущаются они одинаково. Здесь остаётся только грид-специфичное: во время жеста раскладка
|
|
10052
|
+
* меняется ИНЛАЙН-стилем на самом гриде, а в конфиг доли уходят один раз, на отпускание мыши.
|
|
10015
10053
|
*
|
|
10016
|
-
* Пиксельный снимок треков берётся однократно на
|
|
10054
|
+
* Пиксельный снимок треков берётся однократно на нажатии — если пересчитывать его на каждом
|
|
10017
10055
|
* шаге уже после применения новых долей, округление `fr → px → fr` даёт дрейф границы.
|
|
10018
10056
|
*/
|
|
10019
10057
|
const useGridResize = ({ axis, index, sizes, getGrid, onCommit }) => {
|
|
10020
|
-
const [handle, setHandle] = useState(null);
|
|
10021
|
-
const [dragging, setDragging] = useState(false);
|
|
10022
|
-
const dragRef = useRef(null);
|
|
10023
10058
|
const sizesRef = useRef(sizes);
|
|
10024
10059
|
sizesRef.current = sizes;
|
|
10025
10060
|
const isRow = axis === "row";
|
|
10026
10061
|
const getPosition = useCallback((event) => (isRow ? event.clientY : event.clientX), [isRow]);
|
|
10027
|
-
const
|
|
10062
|
+
const onStart = useCallback((event) => {
|
|
10028
10063
|
const grid = getGrid();
|
|
10029
10064
|
if (!grid)
|
|
10030
|
-
return;
|
|
10065
|
+
return null;
|
|
10031
10066
|
const pixels = readTrackPixels(grid, axis);
|
|
10032
10067
|
if (!pixels || index + 1 >= pixels.length)
|
|
10033
|
-
return;
|
|
10034
|
-
event
|
|
10035
|
-
dragRef.current = { start: getPosition(event), pixels };
|
|
10036
|
-
setDragging(true);
|
|
10068
|
+
return null;
|
|
10069
|
+
return { start: getPosition(event), pixels };
|
|
10037
10070
|
}, [axis, getGrid, getPosition, index]);
|
|
10038
10071
|
/** Новый пиксельный размер первого трека пары с учётом минимального размера обоих. */
|
|
10039
10072
|
const getNextFirstSize = useCallback((state, event) => {
|
|
@@ -10044,10 +10077,9 @@ const useGridResize = ({ axis, index, sizes, getGrid, onCommit }) => {
|
|
|
10044
10077
|
const min = getMinTrackSize(total);
|
|
10045
10078
|
return clamp(first + getPosition(event) - state.start, min, total - min);
|
|
10046
10079
|
}, [getPosition, index]);
|
|
10047
|
-
const
|
|
10048
|
-
const state = dragRef.current;
|
|
10080
|
+
const onMove = useCallback((state, event) => {
|
|
10049
10081
|
const grid = getGrid();
|
|
10050
|
-
if (!
|
|
10082
|
+
if (!grid)
|
|
10051
10083
|
return;
|
|
10052
10084
|
const first = getNextFirstSize(state, event);
|
|
10053
10085
|
if (first === null)
|
|
@@ -10055,12 +10087,7 @@ const useGridResize = ({ axis, index, sizes, getGrid, onCommit }) => {
|
|
|
10055
10087
|
const total = state.pixels[index] + state.pixels[index + 1];
|
|
10056
10088
|
grid.style[getTemplateProperty(axis)] = buildPreviewTemplate(state.pixels, index, first, total - first);
|
|
10057
10089
|
}, [axis, getGrid, getNextFirstSize, index]);
|
|
10058
|
-
const
|
|
10059
|
-
const state = dragRef.current;
|
|
10060
|
-
if (!state)
|
|
10061
|
-
return;
|
|
10062
|
-
dragRef.current = null;
|
|
10063
|
-
setDragging(false);
|
|
10090
|
+
const onEnd = useCallback((state, event) => {
|
|
10064
10091
|
const grid = getGrid();
|
|
10065
10092
|
if (grid)
|
|
10066
10093
|
grid.style[getTemplateProperty(axis)] = "";
|
|
@@ -10075,8 +10102,7 @@ const useGridResize = ({ axis, index, sizes, getGrid, onCommit }) => {
|
|
|
10075
10102
|
return;
|
|
10076
10103
|
onCommit(index, [nextFirst, roundFr(share - nextFirst)]);
|
|
10077
10104
|
}, [axis, getGrid, getNextFirstSize, index, onCommit]);
|
|
10078
|
-
|
|
10079
|
-
return { setHandle, dragging };
|
|
10105
|
+
return useResizeDrag({ onStart, onMove, onEnd });
|
|
10080
10106
|
};
|
|
10081
10107
|
|
|
10082
10108
|
const GridResizer = memo(({ axis, index, sizes, getGrid, onCommit }) => {
|
|
@@ -10084,7 +10110,7 @@ const GridResizer = memo(({ axis, index, sizes, getGrid, onCommit }) => {
|
|
|
10084
10110
|
// Ручка лежит внутри трека, и без этого перетаскивание границы заканчивалось бы кликом
|
|
10085
10111
|
// по ячейке — то есть меняло бы выделение.
|
|
10086
10112
|
const stopPropagation = useCallback((event) => event.stopPropagation(), []);
|
|
10087
|
-
return (jsx(ResizeHandle, {
|
|
10113
|
+
return (jsx(ResizeHandle, { ref: setHandle, "$axis": axis, "data-dragging": dragging, onClick: stopPropagation }));
|
|
10088
10114
|
});
|
|
10089
10115
|
|
|
10090
10116
|
/**
|
|
@@ -11405,10 +11431,17 @@ const toSchemaAttribute = (params) => {
|
|
|
11405
11431
|
attributeName,
|
|
11406
11432
|
// Тип принадлежит источнику: конфиг задаёт его только там, где источника нет.
|
|
11407
11433
|
type: source?.type ?? description?.type ?? DEFAULT_ATTRIBUTE_TYPE,
|
|
11434
|
+
// Уточнение типа — целиком за конфигом: у атрибута источника поля `subType` нет.
|
|
11435
|
+
subType: description?.subType,
|
|
11408
11436
|
alias: description?.alias ?? source?.alias ?? attributeName,
|
|
11409
11437
|
description: description?.description ?? source?.description,
|
|
11410
11438
|
isEditable: resolveIsEditable(params),
|
|
11411
11439
|
stringFormat: resolveStringFormat(description, source),
|
|
11440
|
+
// Раскладка колонки живёт только в конфиге контейнера: источник о ширине таблицы не знает.
|
|
11441
|
+
width: description?.width,
|
|
11442
|
+
resizable: description?.resizable,
|
|
11443
|
+
multiline: description?.multiline,
|
|
11444
|
+
style: description?.style,
|
|
11412
11445
|
};
|
|
11413
11446
|
};
|
|
11414
11447
|
/**
|
|
@@ -15439,6 +15472,8 @@ const TIME_FORMAT = /hh:mm/;
|
|
|
15439
15472
|
* закрытие редактора по клику снаружи обязано этот контейнер пропускать.
|
|
15440
15473
|
*/
|
|
15441
15474
|
const PORTAL_ROOT_SELECTOR = "#portal-root";
|
|
15475
|
+
/** Ниже этой ширины колонку не ужать мышью: уже неё в ячейке не остаётся места под значение. */
|
|
15476
|
+
const MIN_COLUMN_WIDTH = 48;
|
|
15442
15477
|
|
|
15443
15478
|
/**
|
|
15444
15479
|
* Собственный бокс таблицы. Без размеров в `options` представления узел ничего не меняет:
|
|
@@ -15495,10 +15530,13 @@ const TableHead = styled.thead.withConfig({ displayName: "TableHead", componentI
|
|
|
15495
15530
|
z-index: 1;
|
|
15496
15531
|
`;
|
|
15497
15532
|
const TableHeadCell = styled.th.withConfig({ displayName: "TableHeadCell", componentId: "sc-1m6xil2" }) `
|
|
15533
|
+
/* Относительное позиционирование держит захват границы колонки. */
|
|
15534
|
+
position: relative;
|
|
15498
15535
|
padding: 0.375rem 0.5rem;
|
|
15499
15536
|
text-align: left;
|
|
15500
15537
|
font-weight: 600;
|
|
15501
15538
|
white-space: nowrap;
|
|
15539
|
+
overflow: hidden;
|
|
15502
15540
|
color: ${({ theme }) => theme.palette.textSecondary};
|
|
15503
15541
|
/* Рамка принадлежит ячейке (рамки раздельные), поэтому едет вместе с липкой шапкой. */
|
|
15504
15542
|
border-bottom: 1px solid ${({ theme }) => theme.palette.elementDeep};
|
|
@@ -15509,10 +15547,17 @@ const TableHeadCell = styled.th.withConfig({ displayName: "TableHeadCell", compo
|
|
|
15509
15547
|
user-select: none;
|
|
15510
15548
|
`}
|
|
15511
15549
|
`;
|
|
15550
|
+
/**
|
|
15551
|
+
* Содержимое заголовка. Псевдоним обрезается многоточием, значок сортировки не сжимается:
|
|
15552
|
+
* у колонки с заданной шириной длинный псевдоним иначе выдавил бы значок за край ячейки.
|
|
15553
|
+
*/
|
|
15512
15554
|
const TableHeadContent = styled.span.withConfig({ displayName: "TableHeadContent", componentId: "sc-8hzcop" }) `
|
|
15513
|
-
display:
|
|
15555
|
+
display: flex;
|
|
15514
15556
|
align-items: center;
|
|
15515
15557
|
gap: 0.25rem;
|
|
15558
|
+
min-width: 0;
|
|
15559
|
+
overflow: hidden;
|
|
15560
|
+
text-overflow: ellipsis;
|
|
15516
15561
|
`;
|
|
15517
15562
|
/**
|
|
15518
15563
|
* Место под значок сортировки. Занято всегда, пока сортировка включена, а сам значок только
|
|
@@ -15552,13 +15597,31 @@ const TableActionsCell = styled(TableCellWrapper).withConfig({ displayName: "Tab
|
|
|
15552
15597
|
width: 2rem;
|
|
15553
15598
|
text-align: right;
|
|
15554
15599
|
`;
|
|
15600
|
+
/**
|
|
15601
|
+
* Как значение ведёт себя, когда не помещается в колонку: режется многоточием в одну строку
|
|
15602
|
+
* или переносится по словам, растягивая строку таблицы вниз (`multiline` атрибута).
|
|
15603
|
+
*
|
|
15604
|
+
* Перенос разрешаем и посреди слова: колонка бывает уже одного длинного слова (ссылка, артикул),
|
|
15605
|
+
* и без этого оно вылезло бы за заданную ширину, сделав её бессмысленной.
|
|
15606
|
+
*/
|
|
15607
|
+
const cellWrapMixin = css `
|
|
15608
|
+
${({ $multiline }) => $multiline
|
|
15609
|
+
? css `
|
|
15610
|
+
white-space: normal;
|
|
15611
|
+
overflow-wrap: anywhere;
|
|
15612
|
+
`
|
|
15613
|
+
: css `
|
|
15614
|
+
overflow: hidden;
|
|
15615
|
+
text-overflow: ellipsis;
|
|
15616
|
+
white-space: nowrap;
|
|
15617
|
+
`}
|
|
15618
|
+
`;
|
|
15555
15619
|
const CellText = styled.div.withConfig({ displayName: "CellText", componentId: "sc-ok630s" }) `
|
|
15556
15620
|
padding: 0.375rem 0.25rem;
|
|
15557
15621
|
/* Та же высота строки, что у редактора — иначе строка подпрыгивала бы по вертикали. */
|
|
15558
15622
|
line-height: 1.25rem;
|
|
15559
|
-
|
|
15560
|
-
|
|
15561
|
-
white-space: nowrap;
|
|
15623
|
+
|
|
15624
|
+
${cellWrapMixin};
|
|
15562
15625
|
`;
|
|
15563
15626
|
/**
|
|
15564
15627
|
* Редактируемая ячейка вне фокуса. Показывает значение по `stringFormat`, а редактор
|
|
@@ -15578,9 +15641,8 @@ const CellButton = styled.button.withConfig({ displayName: "CellButton", compone
|
|
|
15578
15641
|
color: inherit;
|
|
15579
15642
|
text-align: left;
|
|
15580
15643
|
cursor: text;
|
|
15581
|
-
|
|
15582
|
-
|
|
15583
|
-
white-space: nowrap;
|
|
15644
|
+
|
|
15645
|
+
${cellWrapMixin};
|
|
15584
15646
|
|
|
15585
15647
|
:hover {
|
|
15586
15648
|
border-color: ${({ theme }) => theme.palette.elementDeep};
|
|
@@ -15605,8 +15667,9 @@ const CellGhost = styled.span.withConfig({ displayName: "CellGhost", componentId
|
|
|
15605
15667
|
/* Рамка повторяет CellButton — с ней высота ячейки в правке совпадает с высотой на чтении. */
|
|
15606
15668
|
border: 1px solid transparent;
|
|
15607
15669
|
line-height: 1.25rem;
|
|
15608
|
-
white-space: nowrap;
|
|
15609
15670
|
visibility: hidden;
|
|
15671
|
+
|
|
15672
|
+
${cellWrapMixin};
|
|
15610
15673
|
`;
|
|
15611
15674
|
const CellField = styled.div.withConfig({ displayName: "CellField", componentId: "sc-1ww3875" }) `
|
|
15612
15675
|
position: absolute;
|
|
@@ -15623,11 +15686,97 @@ const CellField = styled.div.withConfig({ displayName: "CellField", componentId:
|
|
|
15623
15686
|
min-width: 0;
|
|
15624
15687
|
}
|
|
15625
15688
|
`;
|
|
15626
|
-
|
|
15689
|
+
/**
|
|
15690
|
+
* Ячейка со вложениями. Список идёт колонкой, кнопка добавления — под ним, поэтому строка растёт
|
|
15691
|
+
* ровно на столько, сколько файлов в ней лежит.
|
|
15692
|
+
*
|
|
15693
|
+
* Отступы те же, что у текстовой ячейки (`CellText`): в одном ряду с обычными колонками значения
|
|
15694
|
+
* обязаны стоять на одной линии.
|
|
15695
|
+
*/
|
|
15696
|
+
const AttachmentsCellBox = styled.div.withConfig({ displayName: "AttachmentsCellBox", componentId: "sc-1ayq7sq" }) `
|
|
15697
|
+
display: flex;
|
|
15698
|
+
flex-direction: column;
|
|
15699
|
+
align-items: flex-start;
|
|
15700
|
+
gap: 0.25rem;
|
|
15701
|
+
padding: 0.375rem 0.25rem;
|
|
15702
|
+
`;
|
|
15703
|
+
const TableEmpty = styled.div.withConfig({ displayName: "TableEmpty", componentId: "sc-dmdhrv" }) `
|
|
15627
15704
|
padding: 0.75rem 0.25rem;
|
|
15628
15705
|
color: ${({ theme }) => theme.palette.textSecondary};
|
|
15629
15706
|
`;
|
|
15630
15707
|
|
|
15708
|
+
/**
|
|
15709
|
+
* Ячейка с вложениями: разбор значения, просмотр, скачивание и правка списка.
|
|
15710
|
+
*
|
|
15711
|
+
* Значение атрибута — строка: файлы приезжают в ней списком JSON, поэтому и обратно в черновик
|
|
15712
|
+
* кладём строку, а не массив — иначе тип ячейки менялся бы от самой правки.
|
|
15713
|
+
*
|
|
15714
|
+
* Добавление здесь только по ссылке. Загрузка с диска требует ресурса-родителя и файлового
|
|
15715
|
+
* api контейнера вложений, а у колонки таблицы ни того, ни другого нет.
|
|
15716
|
+
*/
|
|
15717
|
+
const useAttachmentsCell = ({ attribute, row, canEdit, onChange }) => {
|
|
15718
|
+
const [previewIndex, setPreviewIndex] = useState(null);
|
|
15719
|
+
const [isLinkDialogOpen, setLinkDialogOpen] = useState(false);
|
|
15720
|
+
const { attributeName, isEditable } = attribute;
|
|
15721
|
+
const value = row.properties[attributeName];
|
|
15722
|
+
const items = useMemo(() => parseAttachments(value), [value]);
|
|
15723
|
+
const previewImages = useAttachmentPreviewImages({ items, active: previewIndex !== null });
|
|
15724
|
+
const downloadByIndex = useAttachmentDownload(items);
|
|
15725
|
+
// Те же два условия, что и у обычной ячейки: режим таблицы и разрешение самого атрибута.
|
|
15726
|
+
const editable = canEdit && isEditable;
|
|
15727
|
+
const persist = useCallback((next) => onChange(row.key, attributeName, JSON.stringify(next)), [attributeName, onChange, row.key]);
|
|
15728
|
+
const onPreview = useCallback((link) => {
|
|
15729
|
+
const index = items.findIndex(item => item.link === link);
|
|
15730
|
+
if (index >= 0) {
|
|
15731
|
+
setPreviewIndex(index);
|
|
15732
|
+
}
|
|
15733
|
+
}, [items]);
|
|
15734
|
+
const onClosePreview = useCallback(() => setPreviewIndex(null), []);
|
|
15735
|
+
const onDownload = useCallback((_image, index) => downloadByIndex(index), [downloadByIndex]);
|
|
15736
|
+
const onDelete = useCallback((link) => persist(items.filter(item => item.link !== link)), [items, persist]);
|
|
15737
|
+
const onOpenLinkDialog = useCallback(() => setLinkDialogOpen(true), []);
|
|
15738
|
+
const onCloseLinkDialog = useCallback(() => setLinkDialogOpen(false), []);
|
|
15739
|
+
const onAddByLink = useCallback((url) => persist([
|
|
15740
|
+
...items,
|
|
15741
|
+
{
|
|
15742
|
+
link: url,
|
|
15743
|
+
name: getFileNameFromUrl(url),
|
|
15744
|
+
mimeType: getMimeTypeFromUrl(url),
|
|
15745
|
+
date: new Date().toISOString(),
|
|
15746
|
+
isExternal: true,
|
|
15747
|
+
},
|
|
15748
|
+
]), [items, persist]);
|
|
15749
|
+
return {
|
|
15750
|
+
items,
|
|
15751
|
+
editable,
|
|
15752
|
+
previewIndex,
|
|
15753
|
+
previewImages,
|
|
15754
|
+
isLinkDialogOpen,
|
|
15755
|
+
onPreview,
|
|
15756
|
+
onClosePreview,
|
|
15757
|
+
onDownload,
|
|
15758
|
+
onDelete,
|
|
15759
|
+
onOpenLinkDialog,
|
|
15760
|
+
onCloseLinkDialog,
|
|
15761
|
+
onAddByLink,
|
|
15762
|
+
};
|
|
15763
|
+
};
|
|
15764
|
+
|
|
15765
|
+
/**
|
|
15766
|
+
* Колонка со вложениями: список файлов прямо в ячейке.
|
|
15767
|
+
*
|
|
15768
|
+
* Тип у атрибута строковый, вложениями его делает `subType: "Attachments"` в схеме контейнера —
|
|
15769
|
+
* поэтому ветка стоит раньше разбора типа и обычных редакторов ячейки.
|
|
15770
|
+
*/
|
|
15771
|
+
const AttachmentsCell = memo(({ attribute, row, canEdit, onChange }) => {
|
|
15772
|
+
const { t } = useGlobalContext();
|
|
15773
|
+
const { items, editable, previewIndex, previewImages, isLinkDialogOpen, onPreview, onClosePreview, onDownload, onDelete, onOpenLinkDialog, onCloseLinkDialog, onAddByLink, } = useAttachmentsCell({ attribute, row, canEdit, onChange });
|
|
15774
|
+
return (jsxs(AttachmentsCellBox, { children: [!items.length && !editable && jsx(CellPlaceholder, { children: "\u2014" }), jsx(AttachmentsList, { items: items, isEdit: editable, onPreview: onPreview, onDelete: onDelete }), editable && (jsx(IconButton, { kind: "link", tabIndex: 0, title: t("attachments.fromLink", { ns: "common", defaultValue: "По ссылке" }), onClick: onOpenLinkDialog })), jsx(AttachmentLinkDialog, { isOpen: isLinkDialogOpen, onClose: onCloseLinkDialog, onSubmit: onAddByLink }), previewIndex !== null && (jsx(Preview, { images: previewImages, initialIndex: previewIndex, isOpen: true, onClose: onClosePreview, onDownload: onDownload, errorTitleText: t("attachments.resourceUnavailable", {
|
|
15775
|
+
ns: "common",
|
|
15776
|
+
defaultValue: "Ресурс недоступен",
|
|
15777
|
+
}) }, previewIndex))] }));
|
|
15778
|
+
});
|
|
15779
|
+
|
|
15631
15780
|
/**
|
|
15632
15781
|
* Значение ячейки не изменилось.
|
|
15633
15782
|
*
|
|
@@ -15726,7 +15875,7 @@ const useCellEditing = () => {
|
|
|
15726
15875
|
const TableCell = memo(({ attribute, row, canEdit, onChange }) => {
|
|
15727
15876
|
const { t, language } = useGlobalContext();
|
|
15728
15877
|
const { editing, buttonProps, editorProps } = useCellEditing();
|
|
15729
|
-
const { attributeName, type, isEditable, stringFormat } = attribute;
|
|
15878
|
+
const { attributeName, type, subType, isEditable, stringFormat, multiline } = attribute;
|
|
15730
15879
|
const value = row.properties[attributeName];
|
|
15731
15880
|
const handleChange = useCallback((next) => {
|
|
15732
15881
|
// Пустые правки отбрасываем: иначе строка становилась бы «изменённой» от простого
|
|
@@ -15745,16 +15894,21 @@ const TableCell = memo(({ attribute, row, canEdit, onChange }) => {
|
|
|
15745
15894
|
const withTime = useMemo(() => TIME_FORMAT.test(stringFormat?.format ?? ""), [stringFormat?.format]);
|
|
15746
15895
|
// `canEdit` — режим таблицы, `isEditable` — разрешение конкретного атрибута: правка требует обоих.
|
|
15747
15896
|
const editable = canEdit && isEditable && EDITABLE_ATTRIBUTE_TYPES.includes(type);
|
|
15897
|
+
// Вложения — это строка с JSON, а не текст: разбирать и рисовать её нужно раньше любых
|
|
15898
|
+
// редакторов по типу, иначе в ячейке оказался бы сырой список файлов.
|
|
15899
|
+
if (subType === StringSubType.Attachments) {
|
|
15900
|
+
return jsx(AttachmentsCell, { attribute: attribute, row: row, canEdit: canEdit, onChange: onChange });
|
|
15901
|
+
}
|
|
15748
15902
|
// Логическое значение и на чтение показываем галкой, а не словами «true»/«false» —
|
|
15749
15903
|
// так же, как остальной дашборд рисует булевы атрибуты.
|
|
15750
15904
|
if (type === AttributeType.Boolean) {
|
|
15751
15905
|
return jsx(Checkbox, { checked: !!value, disabled: !editable, onChange: () => handleChange(!value) });
|
|
15752
15906
|
}
|
|
15753
15907
|
if (!editable) {
|
|
15754
|
-
return jsx(CellText, { title: formatted, children: formatted || jsx(CellPlaceholder, { children: "\u2014" }) });
|
|
15908
|
+
return (jsx(CellText, { "$multiline": multiline, title: formatted, children: formatted || jsx(CellPlaceholder, { children: "\u2014" }) }));
|
|
15755
15909
|
}
|
|
15756
15910
|
if (!editing) {
|
|
15757
|
-
return (jsx(CellButton, { type: "button", ...buttonProps, children: formatted || jsx(CellPlaceholder, { children: "\u2014" }) }));
|
|
15911
|
+
return (jsx(CellButton, { type: "button", "$multiline": multiline, ...buttonProps, children: formatted || jsx(CellPlaceholder, { children: "\u2014" }) }));
|
|
15758
15912
|
}
|
|
15759
15913
|
const renderEditor = () => {
|
|
15760
15914
|
if (type === AttributeType.DateTime) {
|
|
@@ -15765,9 +15919,105 @@ const TableCell = memo(({ attribute, row, canEdit, onChange }) => {
|
|
|
15765
15919
|
}
|
|
15766
15920
|
return (jsx(Input, { autoFocus: true, value: value === null || value === undefined ? "" : String(value), width: "100%", onChange: ({ target }) => handleChange(target.value) }));
|
|
15767
15921
|
};
|
|
15768
|
-
return (jsxs(CellEditor, { ...editorProps, children: [jsx(CellGhost, { children: formatted || "—" }), jsx(CellField, { children: renderEditor() })] }));
|
|
15922
|
+
return (jsxs(CellEditor, { ...editorProps, children: [jsx(CellGhost, { "$multiline": multiline, children: formatted || "—" }), jsx(CellField, { children: renderEditor() })] }));
|
|
15923
|
+
});
|
|
15924
|
+
|
|
15925
|
+
/**
|
|
15926
|
+
* Имя переменной ширины колонки.
|
|
15927
|
+
*
|
|
15928
|
+
* Через неё идёт и предпросмотр перетаскивания, и итоговая ширина: пока переменная не задана,
|
|
15929
|
+
* работает запасное значение из стиля ячейки, а жест на время перетаскивания объявляет её на
|
|
15930
|
+
* самой таблице — одним свойством на один узел, как сетка меняет свой шаблон треков.
|
|
15931
|
+
*/
|
|
15932
|
+
const getColumnWidthVariable = (index) => `--table-col-${index}`;
|
|
15933
|
+
/**
|
|
15934
|
+
* Инлайн-размер ячейки колонки с заданной или изменяемой шириной.
|
|
15935
|
+
*
|
|
15936
|
+
* Раскладка таблицы автоматическая (ширину колонок выбирает содержимое), и одной `width` ей мало —
|
|
15937
|
+
* она для неё лишь пожелание. Жёстко колонку держат все три предела сразу, поэтому и ставим их
|
|
15938
|
+
* втроём, на каждую ячейку колонки.
|
|
15939
|
+
*
|
|
15940
|
+
* Ни ширины, ни разрешения тянуть — стиля нет: колонка остаётся на попечении раскладки, как и была.
|
|
15941
|
+
*/
|
|
15942
|
+
const getColumnStyle = (index, width, resizable) => {
|
|
15943
|
+
if (width == null && !resizable) {
|
|
15944
|
+
return undefined;
|
|
15945
|
+
}
|
|
15946
|
+
const variable = getColumnWidthVariable(index);
|
|
15947
|
+
const fixed = width == null ? null : `${width}px`;
|
|
15948
|
+
return {
|
|
15949
|
+
width: `var(${variable}, ${fixed ?? "auto"})`,
|
|
15950
|
+
minWidth: `var(${variable}, ${fixed ?? "0"})`,
|
|
15951
|
+
// Без заданной ширины предел остаётся общим для всех ячеек — тем, что задан стилем таблицы.
|
|
15952
|
+
maxWidth: `var(${variable}, ${fixed ?? "var(--table-cell-max-width, 20rem)"})`,
|
|
15953
|
+
};
|
|
15954
|
+
};
|
|
15955
|
+
|
|
15956
|
+
/**
|
|
15957
|
+
* Перетаскивание правой границы колонки.
|
|
15958
|
+
*
|
|
15959
|
+
* Жест — общий {@link useResizeDrag}, тот же, что двигает границы ячеек сетки дашборда. Здесь
|
|
15960
|
+
* остаётся только табличное: во время жеста ширина рисуется переменной на самой таблице, а в
|
|
15961
|
+
* состояние уходит один раз, на отпускание мыши. Так шаг жеста меняет одно свойство одного узла,
|
|
15962
|
+
* а не перерисовывает таблицу целиком.
|
|
15963
|
+
*
|
|
15964
|
+
* Стартовая ширина берётся с самой ячейки заголовка: у колонки без `width` её выбрала раскладка
|
|
15965
|
+
* таблицы, и тянуть надо от того, что видно.
|
|
15966
|
+
*/
|
|
15967
|
+
const useColumnResize = ({ index, onCommit }) => {
|
|
15968
|
+
const variable = getColumnWidthVariable(index);
|
|
15969
|
+
const onStart = useCallback((event) => {
|
|
15970
|
+
// Обработчик нажатия висит на самой ручке, поэтому её ячейка и таблица достаются отсюда —
|
|
15971
|
+
// отдельный ref на них не нужен.
|
|
15972
|
+
const cell = event.currentTarget?.closest("th");
|
|
15973
|
+
if (!cell) {
|
|
15974
|
+
return null;
|
|
15975
|
+
}
|
|
15976
|
+
return {
|
|
15977
|
+
start: event.clientX,
|
|
15978
|
+
width: cell.getBoundingClientRect().width,
|
|
15979
|
+
table: cell.closest("table"),
|
|
15980
|
+
};
|
|
15981
|
+
}, []);
|
|
15982
|
+
const getNextWidth = useCallback((state, event) => Math.max(MIN_COLUMN_WIDTH, Math.round(state.width + event.clientX - state.start)), []);
|
|
15983
|
+
const onMove = useCallback((state, event) => state.table?.style.setProperty(variable, `${getNextWidth(state, event)}px`), [getNextWidth, variable]);
|
|
15984
|
+
const onEnd = useCallback((state, event) => {
|
|
15985
|
+
state.table?.style.removeProperty(variable);
|
|
15986
|
+
const next = getNextWidth(state, event);
|
|
15987
|
+
// Клик по границе без перетаскивания ширину менять не должен.
|
|
15988
|
+
if (next === Math.round(state.width)) {
|
|
15989
|
+
return;
|
|
15990
|
+
}
|
|
15991
|
+
onCommit(next);
|
|
15992
|
+
}, [getNextWidth, onCommit, variable]);
|
|
15993
|
+
return useResizeDrag({ onStart, onMove, onEnd });
|
|
15994
|
+
};
|
|
15995
|
+
|
|
15996
|
+
/**
|
|
15997
|
+
* Ручка ширины колонки на правой границе заголовка.
|
|
15998
|
+
*
|
|
15999
|
+
* Тот же компонент и тот же жест, что двигают границы ячеек сетки дашборда: пользователю это одно
|
|
16000
|
+
* и то же действие, и выглядеть оно обязано одинаково.
|
|
16001
|
+
*/
|
|
16002
|
+
const TableColumnResizer = memo(({ index, onCommit }) => {
|
|
16003
|
+
const { setHandle, dragging } = useColumnResize({ index, onCommit });
|
|
16004
|
+
// Ручка лежит внутри заголовка, и без остановки всплытия перетаскивание границы заканчивалось бы
|
|
16005
|
+
// кликом по нему — то есть переключало бы сортировку.
|
|
16006
|
+
const stopPropagation = useCallback((event) => event.stopPropagation(), []);
|
|
16007
|
+
return jsx(ResizeHandle, { ref: setHandle, "$axis": "column", "data-dragging": dragging, onClick: stopPropagation });
|
|
15769
16008
|
});
|
|
15770
16009
|
|
|
16010
|
+
/**
|
|
16011
|
+
* Шапка таблицы: заголовки колонок, сортировка кликом и захват границы для ручной ширины.
|
|
16012
|
+
*
|
|
16013
|
+
* Захват рисуется по разрешению атрибута (`resizable`) и не смотрит на режим правки контейнера:
|
|
16014
|
+
* ширина колонки — это вид, а не данные.
|
|
16015
|
+
*/
|
|
16016
|
+
const TableHeadRow = ({ columns, sort, sortEnabled, columnWidths, withActionsColumn, onSortToggle, onColumnResize, }) => (jsxs("tr", { children: [columns.map(({ attributeName, alias, description, resizable }, index) => {
|
|
16017
|
+
const sorted = sort?.attributeName === attributeName;
|
|
16018
|
+
return (jsxs(TableHeadCell, { title: description || alias, style: getColumnStyle(index, columnWidths[attributeName], resizable), "$sortable": sortEnabled, onClick: sortEnabled ? () => onSortToggle(attributeName) : undefined, children: [jsxs(TableHeadContent, { children: [alias, sortEnabled && (jsx(TableSortSlot, { "$active": sorted, children: jsx(Icon, { kind: sorted && sort?.direction === "desc" ? "sorting_des" : "sorting_asc" }) }))] }), resizable && (jsx(TableColumnResizer, { index: index, onCommit: nextWidth => onColumnResize(attributeName, nextWidth) }))] }, attributeName));
|
|
16019
|
+
}), withActionsColumn && jsx(TableHeadCell, {})] }));
|
|
16020
|
+
|
|
15771
16021
|
const ContainerLoading = () => (jsx(Flex, { alignContent: "center", justifyContent: "center", width: "100%", children: jsx(CircularProgress, { diameter: 1.5, mono: true }) }));
|
|
15772
16022
|
|
|
15773
16023
|
/**
|
|
@@ -15883,16 +16133,24 @@ const getTableBoxStyle = (width, height) => {
|
|
|
15883
16133
|
*
|
|
15884
16134
|
* `width`/`height` — размер собственного бокса таблицы: он ограничивает её саму и прокручивает
|
|
15885
16135
|
* то, что не влезло. Место, отведённое контейнеру, задаётся его же опциями и живёт отдельно.
|
|
16136
|
+
*
|
|
16137
|
+
* Ширины колонок — тоже вид: конфиг задаёт стартовую, растянутая мышью живёт здесь и в конфиг
|
|
16138
|
+
* не возвращается.
|
|
15886
16139
|
*/
|
|
15887
16140
|
const useTableView = (elementConfig) => {
|
|
15888
16141
|
const context = useContext(StructuredDataContext);
|
|
15889
16142
|
const { sort: sortEnabled, width, height } = elementConfig?.options || {};
|
|
15890
16143
|
const [sort, setSort] = useState(null);
|
|
16144
|
+
const [widths, setWidths] = useState({});
|
|
15891
16145
|
const schema = context?.schema;
|
|
15892
16146
|
const rows = context?.rows;
|
|
15893
16147
|
const columns = useMemo(() => schema ?? [], [schema]);
|
|
15894
16148
|
const sortedRows = useMemo(() => sortRows(rows ?? [], sort, schema ?? []), [rows, schema, sort]);
|
|
15895
16149
|
const sizeCss = useMemo(() => getTableBoxStyle(width, height), [height, width]);
|
|
16150
|
+
// Растянутая мышью ширина живёт только в рантайме и перебивает конфигурационную: последнее
|
|
16151
|
+
// слово за тем, кто тянул. Обратно в конфиг она не пишется.
|
|
16152
|
+
const columnWidths = useMemo(() => columns.reduce((acc, attribute) => ({ ...acc, [attribute.attributeName]: widths[attribute.attributeName] ?? attribute.width }), {}), [columns, widths]);
|
|
16153
|
+
const onColumnResize = useCallback((attributeName, nextWidth) => setWidths(current => ({ ...current, [attributeName]: nextWidth })), []);
|
|
15896
16154
|
const onSortToggle = useCallback((attributeName) => setSort(current => getNextSort(current, attributeName)), []);
|
|
15897
16155
|
return {
|
|
15898
16156
|
context,
|
|
@@ -15903,7 +16161,9 @@ const useTableView = (elementConfig) => {
|
|
|
15903
16161
|
sizeCss,
|
|
15904
16162
|
// Ширина задана — колонки по содержимому: лишнее уходит в прокрутку бокса, а не в многоточие.
|
|
15905
16163
|
contentWidth: width != null,
|
|
16164
|
+
columnWidths,
|
|
15906
16165
|
onSortToggle,
|
|
16166
|
+
onColumnResize,
|
|
15907
16167
|
};
|
|
15908
16168
|
};
|
|
15909
16169
|
|
|
@@ -15915,7 +16175,7 @@ const useTableView = (elementConfig) => {
|
|
|
15915
16175
|
*/
|
|
15916
16176
|
const ElementTable = memo(({ elementConfig }) => {
|
|
15917
16177
|
const { t } = useGlobalContext();
|
|
15918
|
-
const { context, columns, rows, sort, sortEnabled, sizeCss, contentWidth, onSortToggle } = useTableView(elementConfig);
|
|
16178
|
+
const { context, columns, rows, sort, sortEnabled, sizeCss, contentWidth, columnWidths, onSortToggle, onColumnResize, } = useTableView(elementConfig);
|
|
15919
16179
|
// Узел таблицы держим состоянием, а не ref: отсечка должна встать сразу, как он появится.
|
|
15920
16180
|
const [table, setTable] = useState(null);
|
|
15921
16181
|
useHeadOverlap(table);
|
|
@@ -15931,10 +16191,13 @@ const ElementTable = memo(({ elementConfig }) => {
|
|
|
15931
16191
|
defaultValue: "Схема данных не задана",
|
|
15932
16192
|
}) }));
|
|
15933
16193
|
}
|
|
15934
|
-
return (jsx(TableBox, { "$sizeCss": sizeCss, children: jsxs(TableWrapper, { ref: setTable, "$contentWidth": contentWidth, children: [jsx(TableHead, { children: jsxs(
|
|
15935
|
-
|
|
15936
|
-
|
|
15937
|
-
|
|
16194
|
+
return (jsx(TableBox, { "$sizeCss": sizeCss, children: jsxs(TableWrapper, { ref: setTable, "$contentWidth": contentWidth, children: [jsx(TableHead, { children: jsx(TableHeadRow, { columns: columns, sort: sort, sortEnabled: sortEnabled, columnWidths: columnWidths, withActionsColumn: context.canDelete, onSortToggle: onSortToggle, onColumnResize: onColumnResize }) }), jsx(TableBody, { children: rows.map(row => (jsxs(TableRow, { children: [columns.map((attribute, columnIndex) => (jsx(TableCellWrapper, {
|
|
16195
|
+
// Стиль колонки из конфига идёт последним: шрифт задан для значений, и ширину
|
|
16196
|
+
// он не трогает — своих размеров у него нет.
|
|
16197
|
+
style: {
|
|
16198
|
+
...getColumnStyle(columnIndex, columnWidths[attribute.attributeName], attribute.resizable),
|
|
16199
|
+
...attribute.style,
|
|
16200
|
+
}, children: jsx(TableCell, { attribute: attribute, row: row, canEdit: context.canEdit, onChange: context.onCellChange }) }, attribute.attributeName))), context.canDelete && (jsx(TableActionsCell, { children: jsx(IconButton, { kind: "delete", title: t("actions.delete", { ns: "common", defaultValue: "Удалить" }), onClick: () => context.onRowDelete(row.key) }) }))] }, row.key))) })] }) }));
|
|
15938
16201
|
});
|
|
15939
16202
|
|
|
15940
16203
|
const TooltipIcon = styled(Icon).withConfig({ displayName: "TooltipIcon", componentId: "sc-1lkxudm" }) `
|
|
@@ -19252,5 +19515,5 @@ const DEFAULT_HEATMAP_STYLE = {
|
|
|
19252
19515
|
],
|
|
19253
19516
|
};
|
|
19254
19517
|
|
|
19255
|
-
export { ALIGNMENTS, ALIGN_ITEMS, ATTRIBUTE_ICON_ELEMENT_TYPES, AddButtonRow, AddFeatureButton, AddFeatureContainer, AlertIconContainer, AttachmentContainer, AttributeGalleryContainer, AttributeLabel, BASE_CONTAINER_STYLE, BG_IMAGE_SLOT_ID, BaseMapTheme, CHART_TYPES, COMPACT_FRACTION_DIGITS, CONFIG_PAGES_ID, CONFIG_PAGE_ID, CONTAINERS_GROUP_DEFAULTS, CONTAINER_BODY_ATTRIBUTE, CONTAINER_BODY_FILL_STYLE, CameraContainer, Chart, ChartContainer, ChartLegend, ChartLoading, Container, ContainerBackground, ContainerChildren, ContainerLoading, ContainerRoot, ContainerTemplate, ContainerWrapper, ContainersGroupContainer, DASHBOARD_OVERLAY_Z_INDEX, DEFAULT_ATTRIBUTE_NAME, DEFAULT_BARCHART_RADIUS, DEFAULT_BASE_MAP, DEFAULT_BLUR, DEFAULT_CHART_ANGLE, DEFAULT_CHART_HEIGHT, DEFAULT_CHART_WIDTH, DEFAULT_CIRCLE_RADIUS, DEFAULT_CIRCLE_STROKE_WIDTH, DEFAULT_CIRCLE_STYLE, DEFAULT_COLOR, DEFAULT_DASHBOARD_CONFIG, DEFAULT_DATA_SOURCE_LIMIT, DEFAULT_DROPDOWN_WIDTH, DEFAULT_FILL_EXTRUSION_BASE, DEFAULT_FILL_EXTRUSION_HEIGHT, DEFAULT_FILL_EXTRUSION_STYLE, DEFAULT_FILL_EXTRUSION_VERTICAL_GRADIENT, DEFAULT_FILL_STYLE, DEFAULT_FILTER_PADDING, DEFAULT_GRID_GAP, DEFAULT_HEATMAP_COLOR, DEFAULT_HEATMAP_INTENSITY, DEFAULT_HEATMAP_RADIUS, DEFAULT_HEATMAP_STYLE, DEFAULT_HEATMAP_WEIGHT, DEFAULT_ICON_ANCHOR, DEFAULT_ICON_OVERLAP, DEFAULT_ICON_PADDING, DEFAULT_ICON_ROTATE, DEFAULT_ICON_SIZE, DEFAULT_ID_ATTRIBUTE_NAME, DEFAULT_LAT, DEFAULT_LINE_CAP, DEFAULT_LINE_JOIN, DEFAULT_LINE_STYLE, DEFAULT_LINE_WIDTH, DEFAULT_LNG, DEFAULT_OPACITY, DEFAULT_PAGES_CONFIG, DEFAULT_PIECHART_RADIUS, DEFAULT_SYMBOL_COLOR, DEFAULT_SYMBOL_HALO_COLOR, DEFAULT_SYMBOL_PLACEMENT, DEFAULT_SYMBOL_SPACING, DEFAULT_SYMBOL_STYLE, DEFAULT_TEXT_ANCHOR, DEFAULT_TEXT_JUSTIFY, DEFAULT_TEXT_SIZE, DEFAULT_TEXT_TRANSFORM, DEFAULT_TRACK_FR, DEFAULT_TRANSLATE, DEFAULT_ZOOM, DRAG_THRESHOLD_PX, Dashboard, DashboardCheckbox, DashboardChip, DashboardContent, DashboardContext, DashboardDefaultHeader, DashboardHeader, DashboardLoading, DashboardPlaceholder, DashboardPlaceholderWrap, DashboardProvider, DashboardWrapper, DataSourceContainer, DataSourceError, DataSourceErrorContainer, DataSourceInnerContainer, DataSourceProgressContainer, DateFormat, DefaultAttributesContainer, DefaultHeaderContainer, DefaultHeaderWrapper, DividerContainer, EMPTY_DATA_SOURCE_LAYER_INFO, EXTENT_FILTER_NAME, EditGeometryType, ElementButton, ElementCamera, ElementChart, ElementChips, ElementControl, ElementIcon, ElementImage, ElementLegend, ElementLink, ElementMarkdown, ElementSlideshow, ElementSvg, ElementTable, ElementTooltip, ElementValueWrapper, ExpandableTitle, FEATURE_CARD_DEFAULT_COLORS, FEATURE_CARD_OTHER_COLOR, FILL_SIZE, FILTERED_VALUE_OPACITY, FILTER_PREFIX, FR_PRECISION, FeatureCardBackgroundHeader, FeatureCardButtons, FeatureCardContext, FeatureCardDefaultHeader, FeatureCardHeader, FeatureCardProvider, FeatureCardSlideshowHeader, FeatureCardTitle, FeatureControls, FeatureTitleContainer, FiltersContainer, GEOMETRY_ATTRIBUTE, GEOMETRY_FILTER_NAME, GRID_AUTO_FILL_DEFAULTS, GRID_CELL_ATTR, GRID_CELL_ID_PREFIX, GRID_DRAGGING_ATTR, GRID_DRAG_SOURCE_ATTR, GRID_DROP_TARGET_ATTR, GRID_FILL_DEFAULTS,
|
|
19518
|
+
export { ALIGNMENTS, ALIGN_ITEMS, ATTRIBUTE_ICON_ELEMENT_TYPES, AddButtonRow, AddFeatureButton, AddFeatureContainer, AlertIconContainer, AttachmentContainer, AttributeGalleryContainer, AttributeLabel, BASE_CONTAINER_STYLE, BG_IMAGE_SLOT_ID, BaseMapTheme, CHART_TYPES, COMPACT_FRACTION_DIGITS, CONFIG_PAGES_ID, CONFIG_PAGE_ID, CONTAINERS_GROUP_DEFAULTS, CONTAINER_BODY_ATTRIBUTE, CONTAINER_BODY_FILL_STYLE, CameraContainer, Chart, ChartContainer, ChartLegend, ChartLoading, Container, ContainerBackground, ContainerChildren, ContainerLoading, ContainerRoot, ContainerTemplate, ContainerWrapper, ContainersGroupContainer, DASHBOARD_OVERLAY_Z_INDEX, DEFAULT_ATTRIBUTE_NAME, DEFAULT_BARCHART_RADIUS, DEFAULT_BASE_MAP, DEFAULT_BLUR, DEFAULT_CHART_ANGLE, DEFAULT_CHART_HEIGHT, DEFAULT_CHART_WIDTH, DEFAULT_CIRCLE_RADIUS, DEFAULT_CIRCLE_STROKE_WIDTH, DEFAULT_CIRCLE_STYLE, DEFAULT_COLOR, DEFAULT_DASHBOARD_CONFIG, DEFAULT_DATA_SOURCE_LIMIT, DEFAULT_DROPDOWN_WIDTH, DEFAULT_FILL_EXTRUSION_BASE, DEFAULT_FILL_EXTRUSION_HEIGHT, DEFAULT_FILL_EXTRUSION_STYLE, DEFAULT_FILL_EXTRUSION_VERTICAL_GRADIENT, DEFAULT_FILL_STYLE, DEFAULT_FILTER_PADDING, DEFAULT_GRID_GAP, DEFAULT_HEATMAP_COLOR, DEFAULT_HEATMAP_INTENSITY, DEFAULT_HEATMAP_RADIUS, DEFAULT_HEATMAP_STYLE, DEFAULT_HEATMAP_WEIGHT, DEFAULT_ICON_ANCHOR, DEFAULT_ICON_OVERLAP, DEFAULT_ICON_PADDING, DEFAULT_ICON_ROTATE, DEFAULT_ICON_SIZE, DEFAULT_ID_ATTRIBUTE_NAME, DEFAULT_LAT, DEFAULT_LINE_CAP, DEFAULT_LINE_JOIN, DEFAULT_LINE_STYLE, DEFAULT_LINE_WIDTH, DEFAULT_LNG, DEFAULT_OPACITY, DEFAULT_PAGES_CONFIG, DEFAULT_PIECHART_RADIUS, DEFAULT_SYMBOL_COLOR, DEFAULT_SYMBOL_HALO_COLOR, DEFAULT_SYMBOL_PLACEMENT, DEFAULT_SYMBOL_SPACING, DEFAULT_SYMBOL_STYLE, DEFAULT_TEXT_ANCHOR, DEFAULT_TEXT_JUSTIFY, DEFAULT_TEXT_SIZE, DEFAULT_TEXT_TRANSFORM, DEFAULT_TRACK_FR, DEFAULT_TRANSLATE, DEFAULT_ZOOM, DRAG_THRESHOLD_PX, Dashboard, DashboardCheckbox, DashboardChip, DashboardContent, DashboardContext, DashboardDefaultHeader, DashboardHeader, DashboardLoading, DashboardPlaceholder, DashboardPlaceholderWrap, DashboardProvider, DashboardWrapper, DataSourceContainer, DataSourceError, DataSourceErrorContainer, DataSourceInnerContainer, DataSourceProgressContainer, DateFormat, DefaultAttributesContainer, DefaultHeaderContainer, DefaultHeaderWrapper, DividerContainer, EMPTY_DATA_SOURCE_LAYER_INFO, EXTENT_FILTER_NAME, EditGeometryType, ElementButton, ElementCamera, ElementChart, ElementChips, ElementControl, ElementIcon, ElementImage, ElementLegend, ElementLink, ElementMarkdown, ElementSlideshow, ElementSvg, ElementTable, ElementTooltip, ElementValueWrapper, ExpandableTitle, FEATURE_CARD_DEFAULT_COLORS, FEATURE_CARD_OTHER_COLOR, FILL_SIZE, FILTERED_VALUE_OPACITY, FILTER_PREFIX, FR_PRECISION, FeatureCardBackgroundHeader, FeatureCardButtons, FeatureCardContext, FeatureCardDefaultHeader, FeatureCardHeader, FeatureCardProvider, FeatureCardSlideshowHeader, FeatureCardTitle, FeatureControls, FeatureTitleContainer, FiltersContainer, GEOMETRY_ATTRIBUTE, GEOMETRY_FILTER_NAME, GRID_AUTO_FILL_DEFAULTS, GRID_CELL_ATTR, GRID_CELL_ID_PREFIX, GRID_DRAGGING_ATTR, GRID_DRAG_SOURCE_ATTR, GRID_DROP_TARGET_ATTR, GRID_FILL_DEFAULTS, GRID_ROW_ID_PREFIX, GlobalContext, GlobalProvider, GridRowContainer, HANDLE_BLEED_PX, Header, HeaderContainer, HeaderFontColorMixin, HeaderFrontView, HeaderTemplate, HeaderTitleContainer, HiddenTitleItems, IconContainer, ImageContainer, LEFT_PANEL_HEADER_HEIGHT, Layer, LayerDescription, LayerGroupList, LayerIcon, LayerIconContainer, LayerListContainer, LayerTree, LayersContainer, LayersListWrapper, LinearProgressContainer, LogTerminal, LogoContainer, MAP_VIEW_FILTER_NAMES, MAX_CHART_WIDTH, MAX_TRACKS, MIN_TRACK_PX, MIN_TRACK_RATIO, Map$1 as Map, MapContext, MapProvider, NON_TRACK_SLOT_IDS, NO_CELL_DRAG_SELECTOR, NO_CONTENT_VALUE, NUMERIC_ATTRIBUTE_TYPES, NoLiveSnapshotContainer, OBJECT_FITS, OVERFLOWS, OneColumnContainer, PIE_CHART_TOOLTIP_STYLE, POLL_SUBTASK_INTERVAL_MS, POLL_SUBTASK_TIMEOUT_MS, PROJECT_ALIAS_PROP, PROJECT_FILTER_NAME, PROJECT_NAME_PROP, PROJECT_PROPS, PROVIDER_PREFIX, PageNavigator, PageTitle, PageTitleContainer, PagesContainer, Pagination, PresentationHeader, PresentationHeaderButtons, PresentationHeaderTools, PresentationPanelContainer, PresentationPanelWrapper, PresentationWrapper, ProgressContainer, ProviderPrefix, QUERY_DESCRIPTION_CACHE_TTL, RESIZE_HANDLE_ATTR, ResizeHandle, RoundedBackgroundContainer, SAVE_HOOK_RESULT_DURATION, SERVER_NOTIFICATION_EVENT, STACK_BAR_TOTAL_HEIGHT, ScalingFactor, ServerNotificationsContext, ServerNotificationsProvider, SlideshowContainer, SmallPreviewContainer$1 as SmallPreviewContainer, SmallPreviewControl, SmallPreviewCounter, SmallPreviewImages, SmallPreviewLeft, SmallPreviewRight, StackBar, StructuredDataContainer, SvgImage, TILE_ALIGNMENTS, TIME_ZONE_FORMAT, TITLE_SLOT_IDS, TabsContainer, TextTrim, ThemeName, TitleContainer, TopContainer, TopContainerButtons, TwoColumnContainer, UploadContainer, VIEW_MODES, VoteContainer, WidgetType, ZOOM_FILTER_NAME, addDataSource, addDataSources, adjustColor, applyFiltersToCondition, applyQueryFilters, applyTreeFilterToCondition, applyVarsToCondition, asAttributeName, asChartId, asContainerId, asDataSourceName, asFilterName, asLayerName, asModalId, asResourceId, asTabId, buildGridTemplate, buildTrackTemplate, checkEqualOrIncludes, checkIsLoading, collectConfigIds, containsNodeId, createConfigLayer, createConfigPage, createGridCell, createGridIdFactory, createGridRow, createNewPageId, createSaveNotificationId, dateOptions, debounce, decimalOpacityToHex, enrichStyleItemsWithIds, enrichStyleModelsWithIds, eqlParametersToPayload, fetchQueryDescription, findAttributeInExpression, findCellContext, formatArea, formatAttributeValue, formatChartRelatedValue, formatConditionValue, formatDataSourceCondition, formatDate$1 as formatDate, formatElementValue, formatLength, formatNumber, formatPolygonMeasure, geometryToEwkt, getActualExtrusionHeight, getAttributeByName, getAttributeConfigurationByName, getAttributeIconElement, getAttributeIconUrl, getAttributeValue, getAttributesConfiguration, getAverageTrackSize, getChartAxes, getChartFilterName, getChartMarkers, getConfigFilter, getContainerComponent, getDashboardHeader, getDataFromAttributes, getDataFromRelatedFeatures, getDataSource, getDataSourceFilterValue, getDataSourceLayerInfo, getDate, getDefaultConfig, getDisplayTemplateNameFromAttribute, getElementValue, getFeatureAttributes, getFeatureCardHeader, getFilterComponent, getFilterSelectedItems, getFilterValue, getFormattedAttributes, getGradientColors, getImageUrl, getLayerClientStyle, getLayerInfo, getLayerInfoAttribute, getLayerInfoFromDataSources, getLayoutChildren, getMapViewDataSources, getPagesFromConfig, getPagesFromProjectInfo, getProjectValue, getProxyService, getRelatedAttribute, getRenderElement, getResourceUrl, getRootElementId, getSelectedFilterValue, getSlideshowImages, getStyleAttributes, getSvgUrl, getTemplateNameFromAttribute, getThemeByName, getTotalFromAttributes, getTotalFromRelatedFeatures, getTrackSize, getTrackSizeKey, getTrackSizes, getWrapperSizeStyle, hasContainerBgImage, hexToRgba, isCrossOriginUrl, isEmptyElementValue, isEmptyValue, isFeaturesFilterValue, isFillSize, isFrSize, isGridNode, isHiddenEmptyValue, isHookActive, isLayerService, isNotValidSelectedTab, isNumeric, isObject, isProxyService, isRootOwningContainer, isTreeFilterValue, isVisibleContainer, mapNodeById, mergeAttributeConfigurations, metersPerPixel, noMarginMixin, numberOptions, parseFrValue, parseIconNames, parseIconNamesFromClientStyle, pieChartTooltipFromAttributes, pieChartTooltipFromRelatedFeatures, pointOptions, removeDataSource, removeTracks, replaceNodesByIds, rgbToHex, roundFr, roundTotalSum, setLayoutChildren, sizeCssMixin, sliceShownOtherItems, stretchPalette, timeOptions, toConditionsArray, toCssSize, toFrSize, toPxNumber, toRenderableValue, tooltipNameFromAttributes, tooltipValueFromAttributes, tooltipValueFromRelatedFeatures, transparentizeColor, updateDataSource, useAfterSave, useAppHeight, useAttachmentDownload, useAttachmentItems, useAttachmentPreviewImages, useAutoCompleteControl, useBeforeSave, useBgImageHost, useChartChange, useChartData, useContainerAttributes, useContainerRoot, useCurrentPageLayers, useCustomFeatureSelect, useDashboardHeader, useDataSourceLoading, useDataSources, useDebouncedCallback, useDiffPage, useEditGroupAttributes, useEqualTileWidth, useExpandableContainers, useExportPdf, useFeatureSaveHooks, useFetchImageWithAuth, useFetchWithAuth, useGetConfigLayer, useGlobalContext, useHeaderRender, useHideIfEmptyDataSource, useLayerHiddenAttributes, useLayerParams, useMapContext, useMapDraw, useMapImages, useMaxZoomTo, useProjectDashboardInit, usePythonSandbox, usePythonTask, useRedrawLayer, useRelatedDataSourceAttributes, useRemoteTask, useRenderElement, useResizeBox, useResizeDrag, useSavePrototypeBuilder, useServerNotificationsContext, useShownOtherItems, useToggle, useUpdateDataSource, useVisibleProjectItems, useWidgetConfig, useWidgetContext, useWidgetFilters, useWidgetPage, useWindowResize, useWrapperSize, useZoomToFeatures, useZoomToPoint, withTrackSize };
|
|
19256
19519
|
//# sourceMappingURL=react.esm.js.map
|