@evergis/react 4.0.148 → 4.0.149
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/containers/StructuredDataContainer/types.d.ts +2 -0
- package/dist/components/Dashboard/elements/ElementTable/components/ColorCell.d.ts +12 -0
- package/dist/components/Dashboard/elements/ElementTable/constants.d.ts +5 -0
- package/dist/components/Dashboard/elements/ElementTable/styled.d.ts +14 -0
- package/dist/components/Dashboard/types.d.ts +5 -0
- package/dist/index.js +89 -8
- package/dist/index.js.map +1 -1
- package/dist/react.esm.js +90 -10
- package/dist/react.esm.js.map +1 -1
- package/dist/utils/color.d.ts +8 -0
- package/package.json +2 -2
|
@@ -35,6 +35,8 @@ export interface StructuredDataAttribute {
|
|
|
35
35
|
resizable?: boolean;
|
|
36
36
|
/** Значение переносится по словам, а не режется многоточием. */
|
|
37
37
|
multiline?: boolean;
|
|
38
|
+
/** Значение — цвет: колонка показывает плашку, а правится палитрой. */
|
|
39
|
+
colorPicker?: boolean;
|
|
38
40
|
/** Стиль значений колонки из конфига. */
|
|
39
41
|
style?: CSSProperties;
|
|
40
42
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { TableCellProps } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Колонка цвета (`colorPicker` у атрибута).
|
|
5
|
+
*
|
|
6
|
+
* Значение хранится строкой в любом из привычных видов — `hex`, `rgb`, `rgba`, — поэтому рядом со
|
|
7
|
+
* значением показывается плашка этого цвета, а на правку встаёт палитра.
|
|
8
|
+
*
|
|
9
|
+
* Неразбираемая строка остаётся просто текстом, без плашки: так видно, что в данных мусор, а не
|
|
10
|
+
* пустое значение.
|
|
11
|
+
*/
|
|
12
|
+
export declare const ColorCell: FC<TableCellProps>;
|
|
@@ -18,3 +18,8 @@ export declare const TIME_FORMAT: RegExp;
|
|
|
18
18
|
export declare const PORTAL_ROOT_SELECTOR = "#portal-root";
|
|
19
19
|
/** Ниже этой ширины колонку не ужать мышью: уже неё в ячейке не остаётся места под значение. */
|
|
20
20
|
export declare const MIN_COLUMN_WIDTH = 48;
|
|
21
|
+
/**
|
|
22
|
+
* Цвет, с которого палитра открывается у пустой ячейки. Своего значения там ещё нет, а `Color`
|
|
23
|
+
* без валидной строки не собрать.
|
|
24
|
+
*/
|
|
25
|
+
export declare const DEFAULT_CELL_COLOR = "#000000";
|
|
@@ -105,4 +105,18 @@ export declare const CellField: import('styled-components').StyledComponent<"div
|
|
|
105
105
|
* обязаны стоять на одной линии.
|
|
106
106
|
*/
|
|
107
107
|
export declare const AttachmentsCellBox: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
108
|
+
/**
|
|
109
|
+
* Ячейка цвета: плашка или палитра слева, значение справа.
|
|
110
|
+
*
|
|
111
|
+
* Отступы те же, что у текстовой ячейки: в одном ряду с обычными колонками значения обязаны
|
|
112
|
+
* стоять на одной линии.
|
|
113
|
+
*/
|
|
114
|
+
export declare const ColorCellBox: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
115
|
+
/**
|
|
116
|
+
* Плашка цвета. Повторяет маркер легенды графика: цвет всюду обозначается одинаково, где бы он
|
|
117
|
+
* ни показывался.
|
|
118
|
+
*/
|
|
119
|
+
export declare const ColorSwatch: import('styled-components').StyledComponent<"div", any, {
|
|
120
|
+
$color: string;
|
|
121
|
+
}, never>;
|
|
108
122
|
export declare const TableEmpty: import('styled-components').StyledComponent<"div", any, {}, never>;
|
|
@@ -518,6 +518,11 @@ export interface ConfigAttributeDescription {
|
|
|
518
518
|
resizable?: boolean;
|
|
519
519
|
/** Значение переносится на следующую строку вместо обрезки многоточием, высота строки растёт. */
|
|
520
520
|
multiline?: boolean;
|
|
521
|
+
/**
|
|
522
|
+
* Строковое значение атрибута — цвет (`hex`, `rgb` или `rgba`). Показывается плашкой этого
|
|
523
|
+
* цвета рядом со значением, а правится палитрой вместо текстового поля.
|
|
524
|
+
*/
|
|
525
|
+
colorPicker?: boolean;
|
|
521
526
|
/**
|
|
522
527
|
* Стиль значений колонки: семейство, размер, цвет и начертание шрифта. Своего узла-элемента
|
|
523
528
|
* у колонки нет, поэтому стиль живёт прямо у описания атрибута.
|
package/dist/index.js
CHANGED
|
@@ -3849,7 +3849,7 @@ const hue2rgb = (p, q, t) => {
|
|
|
3849
3849
|
*/
|
|
3850
3850
|
const toHex = (value) => {
|
|
3851
3851
|
const hex = Math.round(value * 255).toString(16);
|
|
3852
|
-
return hex.padStart(2,
|
|
3852
|
+
return hex.padStart(2, "0");
|
|
3853
3853
|
};
|
|
3854
3854
|
/**
|
|
3855
3855
|
* Adjusts color brightness
|
|
@@ -3859,7 +3859,7 @@ const toHex = (value) => {
|
|
|
3859
3859
|
*/
|
|
3860
3860
|
const adjustColor = (color, lightnessAdjustment = 5) => {
|
|
3861
3861
|
// Convert hex to RGB
|
|
3862
|
-
const hex = color.replace(
|
|
3862
|
+
const hex = color.replace("#", "");
|
|
3863
3863
|
const r = parseInt(hex.substring(0, 2), 16) / 255;
|
|
3864
3864
|
const g = parseInt(hex.substring(2, 4), 16) / 255;
|
|
3865
3865
|
const b = parseInt(hex.substring(4, 6), 16) / 255;
|
|
@@ -3901,6 +3901,17 @@ const adjustColor = (color, lightnessAdjustment = 5) => {
|
|
|
3901
3901
|
}
|
|
3902
3902
|
return `#${toHex(rNew)}${toHex(gNew)}${toHex(bNew)}`;
|
|
3903
3903
|
};
|
|
3904
|
+
const OPAQUE_ALPHA = "ff";
|
|
3905
|
+
/**
|
|
3906
|
+
* Цвет в hex: `#rrggbb`, а при неполной непрозрачности — `#rrggbbaa`.
|
|
3907
|
+
*
|
|
3908
|
+
* Полностью непрозрачная альфа отбрасывается: в значении она ничего не уточняет, а строку
|
|
3909
|
+
* удлиняет — и в конфиге, и в данных удобнее короткая запись.
|
|
3910
|
+
*/
|
|
3911
|
+
const colorToHex = (color) => {
|
|
3912
|
+
const hex = color.toString("hex");
|
|
3913
|
+
return hex.slice(HEX_RRGGBB_LENGTH).toLowerCase() === OPAQUE_ALPHA ? hex.slice(0, HEX_RRGGBB_LENGTH) : hex;
|
|
3914
|
+
};
|
|
3904
3915
|
|
|
3905
3916
|
const NO_CONTENT_VALUE = "—";
|
|
3906
3917
|
exports.DateFormat = void 0;
|
|
@@ -8751,22 +8762,31 @@ const LinkDialogContent = styled.div.withConfig({ displayName: "LinkDialogConten
|
|
|
8751
8762
|
padding: 1rem 0;
|
|
8752
8763
|
`;
|
|
8753
8764
|
|
|
8765
|
+
/**
|
|
8766
|
+
* Заглушка недоступного изображения.
|
|
8767
|
+
*
|
|
8768
|
+
* Масштаб значка считается от размера самого превью: `font-size` контейнера приравнен к нему, а
|
|
8769
|
+
* бокс значка и его глиф заданы одной долей от этого размера. Раньше бокс был долей превью, а
|
|
8770
|
+
* глиф — фиксированным: в списке, где превью всего `1.5rem`, глиф выходил втрое крупнее своего
|
|
8771
|
+
* бокса и съезжал относительно квадрата.
|
|
8772
|
+
*/
|
|
8754
8773
|
const ImagePreviewError = styled.div.withConfig({ displayName: "ImagePreviewError", componentId: "sc-7cwrhm" }) `
|
|
8755
8774
|
display: flex;
|
|
8756
8775
|
align-items: center;
|
|
8757
8776
|
justify-content: center;
|
|
8758
8777
|
width: 100%;
|
|
8759
8778
|
height: 100%;
|
|
8779
|
+
font-size: ${({ $size = GRID_TILE_SIZE }) => $size};
|
|
8760
8780
|
background-color: ${({ theme }) => theme.palette.elementDark};
|
|
8761
8781
|
border-radius: ${({ theme: { borderRadius: themeBorder }, borderRadius }) => borderRadius || themeBorder.smallest};
|
|
8762
8782
|
|
|
8763
8783
|
${uilibGl.Icon} {
|
|
8764
|
-
width:
|
|
8765
|
-
height:
|
|
8784
|
+
width: 0.375em;
|
|
8785
|
+
height: 0.375em;
|
|
8766
8786
|
}
|
|
8767
8787
|
|
|
8768
8788
|
${uilibGl.Icon}:after {
|
|
8769
|
-
font-size:
|
|
8789
|
+
font-size: 0.375em;
|
|
8770
8790
|
color: ${({ theme }) => theme.palette.textSecondary};
|
|
8771
8791
|
}
|
|
8772
8792
|
`;
|
|
@@ -8804,7 +8824,7 @@ const FileImagePreview = ({ link, isExternal, size, borderRadius, }) => {
|
|
|
8804
8824
|
URL.revokeObjectURL(objectUrl);
|
|
8805
8825
|
};
|
|
8806
8826
|
}, [api, link, isExternal]);
|
|
8807
|
-
return (jsxRuntime.jsxs(ImagePreviewContainer, { size: size, children: [hasError && (jsxRuntime.jsx(ImagePreviewError, { borderRadius: borderRadius, children: jsxRuntime.jsx(uilibGl.Icon, { kind: "alert" }) })), !hasError && !imageSrc && (jsxRuntime.jsx(ImagePreviewLoaderContainer, { children: jsxRuntime.jsx(uilibGl.LinearProgress, {}) })), !hasError && imageSrc && (jsxRuntime.jsx(GridImagePreview, { borderRadius: borderRadius, size: size, src: imageSrc, alt: "", onError: () => setHasError(true) }))] }));
|
|
8827
|
+
return (jsxRuntime.jsxs(ImagePreviewContainer, { size: size, children: [hasError && (jsxRuntime.jsx(ImagePreviewError, { borderRadius: borderRadius, "$size": size, children: jsxRuntime.jsx(uilibGl.Icon, { kind: "alert" }) })), !hasError && !imageSrc && (jsxRuntime.jsx(ImagePreviewLoaderContainer, { children: jsxRuntime.jsx(uilibGl.LinearProgress, {}) })), !hasError && imageSrc && (jsxRuntime.jsx(GridImagePreview, { borderRadius: borderRadius, size: size, src: imageSrc, alt: "", onError: () => setHasError(true) }))] }));
|
|
8808
8828
|
};
|
|
8809
8829
|
|
|
8810
8830
|
const AttachmentItem = ({ item, viewMode, isEdit, onPreview, onDelete, }) => {
|
|
@@ -11466,6 +11486,7 @@ const toSchemaAttribute = (params) => {
|
|
|
11466
11486
|
width: description?.width,
|
|
11467
11487
|
resizable: description?.resizable,
|
|
11468
11488
|
multiline: description?.multiline,
|
|
11489
|
+
colorPicker: description?.colorPicker,
|
|
11469
11490
|
style: description?.style,
|
|
11470
11491
|
};
|
|
11471
11492
|
};
|
|
@@ -15499,6 +15520,11 @@ const TIME_FORMAT = /hh:mm/;
|
|
|
15499
15520
|
const PORTAL_ROOT_SELECTOR = "#portal-root";
|
|
15500
15521
|
/** Ниже этой ширины колонку не ужать мышью: уже неё в ячейке не остаётся места под значение. */
|
|
15501
15522
|
const MIN_COLUMN_WIDTH = 48;
|
|
15523
|
+
/**
|
|
15524
|
+
* Цвет, с которого палитра открывается у пустой ячейки. Своего значения там ещё нет, а `Color`
|
|
15525
|
+
* без валидной строки не собрать.
|
|
15526
|
+
*/
|
|
15527
|
+
const DEFAULT_CELL_COLOR = "#000000";
|
|
15502
15528
|
|
|
15503
15529
|
/**
|
|
15504
15530
|
* Собственный бокс таблицы. Без размеров в `options` представления узел ничего не меняет:
|
|
@@ -15730,7 +15756,35 @@ const AttachmentsCellBox = styled.div.withConfig({ displayName: "AttachmentsCell
|
|
|
15730
15756
|
gap: 0.25rem;
|
|
15731
15757
|
padding: 0.375rem 0.25rem;
|
|
15732
15758
|
`;
|
|
15733
|
-
|
|
15759
|
+
/**
|
|
15760
|
+
* Ячейка цвета: плашка или палитра слева, значение справа.
|
|
15761
|
+
*
|
|
15762
|
+
* Отступы те же, что у текстовой ячейки: в одном ряду с обычными колонками значения обязаны
|
|
15763
|
+
* стоять на одной линии.
|
|
15764
|
+
*/
|
|
15765
|
+
const ColorCellBox = styled.div.withConfig({ displayName: "ColorCellBox", componentId: "sc-n2zhg2" }) `
|
|
15766
|
+
display: flex;
|
|
15767
|
+
align-items: center;
|
|
15768
|
+
gap: 0.375rem;
|
|
15769
|
+
padding: 0 0.25rem;
|
|
15770
|
+
|
|
15771
|
+
${CellText} {
|
|
15772
|
+
padding-left: 0;
|
|
15773
|
+
padding-right: 0;
|
|
15774
|
+
}
|
|
15775
|
+
`;
|
|
15776
|
+
/**
|
|
15777
|
+
* Плашка цвета. Повторяет маркер легенды графика: цвет всюду обозначается одинаково, где бы он
|
|
15778
|
+
* ни показывался.
|
|
15779
|
+
*/
|
|
15780
|
+
const ColorSwatch = styled.div.withConfig({ displayName: "ColorSwatch", componentId: "sc-103e3cx" }) `
|
|
15781
|
+
flex-shrink: 0;
|
|
15782
|
+
width: 0.75rem;
|
|
15783
|
+
height: 0.75rem;
|
|
15784
|
+
background-color: ${({ $color }) => $color};
|
|
15785
|
+
border-radius: ${({ theme: { borderRadius } }) => borderRadius.tiny};
|
|
15786
|
+
`;
|
|
15787
|
+
const TableEmpty = styled.div.withConfig({ displayName: "TableEmpty", componentId: "sc-zo5yrp" }) `
|
|
15734
15788
|
padding: 0.75rem 0.25rem;
|
|
15735
15789
|
color: ${({ theme }) => theme.palette.textSecondary};
|
|
15736
15790
|
`;
|
|
@@ -15807,6 +15861,27 @@ const AttachmentsCell = React.memo(({ attribute, row, canEdit, onChange }) => {
|
|
|
15807
15861
|
}) }, previewIndex))] }));
|
|
15808
15862
|
});
|
|
15809
15863
|
|
|
15864
|
+
/**
|
|
15865
|
+
* Колонка цвета (`colorPicker` у атрибута).
|
|
15866
|
+
*
|
|
15867
|
+
* Значение хранится строкой в любом из привычных видов — `hex`, `rgb`, `rgba`, — поэтому рядом со
|
|
15868
|
+
* значением показывается плашка этого цвета, а на правку встаёт палитра.
|
|
15869
|
+
*
|
|
15870
|
+
* Неразбираемая строка остаётся просто текстом, без плашки: так видно, что в данных мусор, а не
|
|
15871
|
+
* пустое значение.
|
|
15872
|
+
*/
|
|
15873
|
+
const ColorCell = React.memo(({ attribute, row, canEdit, onChange }) => {
|
|
15874
|
+
const { attributeName, isEditable } = attribute;
|
|
15875
|
+
const value = row.properties[attributeName];
|
|
15876
|
+
const text = React.useMemo(() => (lodash.isNil(value) ? "" : String(value)), [value]);
|
|
15877
|
+
const color = React.useMemo(() => (text ? new color$1.Color(text) : null), [text]);
|
|
15878
|
+
const isValidColor = !!color?.isValid;
|
|
15879
|
+
// Те же два условия, что и у обычной ячейки: режим таблицы и разрешение самого атрибута.
|
|
15880
|
+
const editable = canEdit && isEditable;
|
|
15881
|
+
const handleChange = React.useCallback((next) => onChange(row.key, attributeName, colorToHex(next)), [attributeName, onChange, row.key]);
|
|
15882
|
+
return (jsxRuntime.jsxs(ColorCellBox, { children: [editable ? (jsxRuntime.jsx(uilibGl.ColorPicker, { zIndex: DASHBOARD_OVERLAY_Z_INDEX, withOpacity: true, value: isValidColor ? color : new color$1.Color(DEFAULT_CELL_COLOR), onChange: handleChange })) : (isValidColor && jsxRuntime.jsx(ColorSwatch, { "$color": text })), jsxRuntime.jsx(CellText, { title: text, children: text || jsxRuntime.jsx(CellPlaceholder, { children: "\u2014" }) })] }));
|
|
15883
|
+
});
|
|
15884
|
+
|
|
15810
15885
|
/**
|
|
15811
15886
|
* Значение ячейки не изменилось.
|
|
15812
15887
|
*
|
|
@@ -15905,7 +15980,7 @@ const useCellEditing = () => {
|
|
|
15905
15980
|
const TableCell = React.memo(({ attribute, row, canEdit, onChange }) => {
|
|
15906
15981
|
const { t, language } = useGlobalContext();
|
|
15907
15982
|
const { editing, buttonProps, editorProps } = useCellEditing();
|
|
15908
|
-
const { attributeName, type, subType, isEditable, stringFormat, multiline } = attribute;
|
|
15983
|
+
const { attributeName, type, subType, isEditable, stringFormat, multiline, colorPicker } = attribute;
|
|
15909
15984
|
const value = row.properties[attributeName];
|
|
15910
15985
|
const handleChange = React.useCallback((next) => {
|
|
15911
15986
|
// Пустые правки отбрасываем: иначе строка становилась бы «изменённой» от простого
|
|
@@ -15929,6 +16004,11 @@ const TableCell = React.memo(({ attribute, row, canEdit, onChange }) => {
|
|
|
15929
16004
|
if (subType === api.StringSubType.Attachments) {
|
|
15930
16005
|
return jsxRuntime.jsx(AttachmentsCell, { attribute: attribute, row: row, canEdit: canEdit, onChange: onChange });
|
|
15931
16006
|
}
|
|
16007
|
+
// Цвет — тоже строка, и по типу от обычной не отличается: что она значит, говорит только
|
|
16008
|
+
// `colorPicker` в схеме.
|
|
16009
|
+
if (colorPicker) {
|
|
16010
|
+
return jsxRuntime.jsx(ColorCell, { attribute: attribute, row: row, canEdit: canEdit, onChange: onChange });
|
|
16011
|
+
}
|
|
15932
16012
|
// Логическое значение и на чтение показываем галкой, а не словами «true»/«false» —
|
|
15933
16013
|
// так же, как остальной дашборд рисует булевы атрибуты.
|
|
15934
16014
|
if (type === api.AttributeType.Boolean) {
|
|
@@ -19816,6 +19896,7 @@ exports.buildTrackTemplate = buildTrackTemplate;
|
|
|
19816
19896
|
exports.checkEqualOrIncludes = checkEqualOrIncludes;
|
|
19817
19897
|
exports.checkIsLoading = checkIsLoading;
|
|
19818
19898
|
exports.collectConfigIds = collectConfigIds;
|
|
19899
|
+
exports.colorToHex = colorToHex;
|
|
19819
19900
|
exports.containsNodeId = containsNodeId;
|
|
19820
19901
|
exports.createConfigLayer = createConfigLayer;
|
|
19821
19902
|
exports.createConfigPage = createConfigPage;
|