@evergis/react 3.1.50 → 3.1.52

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/react.esm.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
2
- import { IconButton, Flex, transition, Chip, Icon, Description, FlexSpan, IconToggle, Popup, Menu, DraggableTree, shadows, Divider, LegendToggler, Tooltip as Tooltip$1, DropdownField, MultiSelectContainer, IconButtonButton, FlatButton, DraggableTreeContainer, LinearProgress, H2, ThemeProvider, defaultTheme, Preview, Blank, Popover, Expander, darkTheme, NumberRangeSlider, useAsyncAutocomplete, AutoComplete, Dropdown, Checkbox, CircularProgress, RangeNumberInput, dateFormat } from '@evergis/uilib-gl';
2
+ import { IconButton, Flex, transition, Chip, Divider, Icon, Description, FlexSpan, IconToggle, Popup, Menu, DraggableTree, shadows, LegendToggler, Tooltip as Tooltip$1, DropdownField, MultiSelectContainer, IconButtonButton, FlatButton, DraggableTreeContainer, UploaderItemArea, UploaderTitleWrapper, Uploader, WaitingButton, LinearProgress, H2, ThemeProvider, defaultTheme, Preview, Blank, Popover, Expander, darkTheme, NumberRangeSlider, useAsyncAutocomplete, AutoComplete, Dropdown, Checkbox, CircularProgress, RangeNumberInput, dateFormat } from '@evergis/uilib-gl';
3
3
  import { createContext, memo, useRef, useState, useEffect, useCallback, useContext, useMemo, Fragment } from 'react';
4
4
  import styled, { createGlobalStyle, css, useTheme } from 'styled-components';
5
5
  import { lineChartClassNames, BarChart as BarChart$1, barChartClassNames, LineChart, PieChart } from '@evergis/charts';
6
- import { AttributeType, GeometryType } from '@evergis/api';
6
+ import { AttributeType, GeometryType, RemoteTaskStatus } from '@evergis/api';
7
7
  import Gradient from 'javascript-color-gradient';
8
8
  import { Color as Color$1 } from '@evergis/color';
9
9
  import { isValid, format, parseJSON, parseISO, toDate, sub } from 'date-fns';
@@ -3380,6 +3380,8 @@ var ContainerTemplate;
3380
3380
  ContainerTemplate["AddFeature"] = "AddFeature";
3381
3381
  ContainerTemplate["Slideshow"] = "Slideshow";
3382
3382
  ContainerTemplate["ExportPdf"] = "ExportPdf";
3383
+ ContainerTemplate["Upload"] = "Upload";
3384
+ ContainerTemplate["Task"] = "Task";
3383
3385
  ContainerTemplate["Divider"] = "Divider";
3384
3386
  })(ContainerTemplate || (ContainerTemplate = {}));
3385
3387
  var HeaderTemplate;
@@ -4503,6 +4505,75 @@ const DashboardChip$1 = styled(Chip) `
4503
4505
  ${({ $fontColor, $isDefault }) => !!$fontColor && !$isDefault && CustomChipColorMixin}
4504
4506
  `;
4505
4507
 
4508
+ const getAttributeByName = (attributeName, attributes) => {
4509
+ return Array.isArray(attributeName)
4510
+ ? null
4511
+ : attributeName
4512
+ ? attributes?.find(({ name }) => name === attributeName)
4513
+ : null;
4514
+ };
4515
+
4516
+ const formatElementValue = ({ t, value, elementConfig, attributes, wrap, }) => {
4517
+ const { id, type, defaultValue, options, style, attributeName, templateName } = elementConfig || {};
4518
+ const attribute = attributeName ? getAttributeByName(attributeName, attributes) : null;
4519
+ const { fontColor, fontSize, noUnits, tagView, bgColor, withDivider, radius } = options || {};
4520
+ const valueOrDefault = value || defaultValue;
4521
+ const resultValue = type === "attributeValue" && attribute?.type && attribute?.stringFormat
4522
+ ? formatAttributeValue({
4523
+ t,
4524
+ type: attribute.type,
4525
+ value: valueOrDefault,
4526
+ stringFormat: attribute.stringFormat,
4527
+ noUnits,
4528
+ })
4529
+ : valueOrDefault;
4530
+ if (!wrap)
4531
+ return resultValue;
4532
+ return (jsxs(Fragment, { children: [tagView ? (jsx(DashboardChip$1, { text: resultValue, "$bgColor": bgColor, "$fontColor": fontColor, "$fontSize": fontSize, "$radius": radius, style: style })) : resultValue, withDivider && jsx(Divider, {})] }, id));
4533
+ };
4534
+
4535
+ const getAttributeValue = (element, attributes) => {
4536
+ const attribute = getAttributeByName(element?.attributeName, attributes);
4537
+ const { maxLength, separator, expandable, lineBreak } = element.options || {};
4538
+ let value = "";
4539
+ if (attribute?.type === AttributeType.Boolean && typeof attribute.value === "boolean") {
4540
+ return jsx(DashboardCheckbox, { title: attribute.alias || attribute.name, checked: attribute.value });
4541
+ }
4542
+ if (Array.isArray(element?.attributeName)) {
4543
+ const concatAttributes = element.attributeName.map((attributeName) => attributes?.find(({ name }) => name === attributeName)?.value || "");
4544
+ value = concatAttributes.join(separator || ", ");
4545
+ }
4546
+ else {
4547
+ value = attribute?.value?.toString() || "";
4548
+ }
4549
+ return maxLength && maxLength < value.length ? (jsx(TextTrim, { maxLength: maxLength, expandable: expandable, lineBreak: lineBreak, children: value })) : (value);
4550
+ };
4551
+
4552
+ const getChartAxes = (chartElement) => chartElement?.options?.relatedDataSources?.filter(({ chartAxis }) => chartAxis === "y");
4553
+
4554
+ const getChartFilterName = (relatedDataSources) => {
4555
+ const relatedAttributes = relatedDataSources || [];
4556
+ const axes = relatedAttributes.filter(({ chartAxis }) => chartAxis === "y");
4557
+ return axes?.[0]?.filterName;
4558
+ };
4559
+
4560
+ function getValueIndex(items, attributes) {
4561
+ return items?.findIndex(({ name }) => name.toString() === attributes.value?.toString());
4562
+ }
4563
+ const getChartMarkers = (items, markers, dataSources) => {
4564
+ if (typeof markers === "string") {
4565
+ const dataSource = getDataSource(markers, dataSources);
4566
+ return dataSource?.features?.map(({ attributes }) => ({
4567
+ ...attributes,
4568
+ value: getValueIndex(items, attributes),
4569
+ })) || [];
4570
+ }
4571
+ return (markers?.map(marker => ({
4572
+ ...marker,
4573
+ value: getValueIndex(items, marker),
4574
+ })) || []);
4575
+ };
4576
+
4506
4577
  const ChartLegendContainer = styled(Flex) `
4507
4578
  flex-direction: column;
4508
4579
  flex-wrap: wrap;
@@ -4531,156 +4602,6 @@ const ChartLegendName = styled.div `
4531
4602
  color: ${({ theme: { palette }, $fontColor }) => $fontColor || palette.textPrimary};
4532
4603
  `;
4533
4604
 
4534
- const Container = styled(Flex) `
4535
- flex-direction: column;
4536
- width: 100%;
4537
-
4538
- ${({ isColumn }) => isColumn
4539
- ? css `
4540
- > * {
4541
- width: 100%;
4542
- }
4543
- `
4544
- : css `
4545
- flex-direction: row;
4546
- justify-content: space-between;
4547
- align-items: center;
4548
- `}
4549
-
4550
- ${({ isMain, isColumn }) => (isMain || isColumn) &&
4551
- css `
4552
- > :not(:last-child) {
4553
- margin-bottom: 1.5rem;
4554
- }
4555
- `}
4556
-
4557
- ${({ isTitle }) => isTitle &&
4558
- css `
4559
- &&&& {
4560
- margin-bottom: 0.75rem;
4561
- }
4562
- `}
4563
-
4564
- ${({ noBorders }) => noBorders && css `
4565
- ${ContainerWrapper} {
4566
- box-shadow: none;
4567
- padding: 0;
4568
- }
4569
- `}
4570
- `;
4571
- const ContainerAlias = styled(Flex) `
4572
- align-items: center;
4573
- flex-wrap: nowrap;
4574
- margin-bottom: ${({ hasBottomMargin }) => (hasBottomMargin ? 0.25 : 0)}rem;
4575
- font-size: 0.75rem;
4576
- color: ${({ theme: { palette } }) => palette.textSecondary};
4577
-
4578
- span[kind] {
4579
- margin-right: 0.5rem;
4580
-
4581
- :after {
4582
- color: ${({ theme: { palette } }) => palette.primary};
4583
- }
4584
- }
4585
- `;
4586
- const ContainerAliasIcon = styled.div `
4587
- margin-right: 0.5rem;
4588
- `;
4589
- const ContainerChart = styled(Flex) `
4590
- justify-content: flex-start;
4591
-
4592
- > * {
4593
- display: flex;
4594
- justify-content: center;
4595
- width: 100%;
4596
- }
4597
- `;
4598
- const ContainerLegend = styled(Flex) ``;
4599
- const ContainerUnits = styled.div `
4600
- margin-left: 0.5rem;
4601
- white-space: nowrap;
4602
- font-size: 0.75rem;
4603
- `;
4604
- const ContainerValue = styled(Flex) `
4605
- justify-content: flex-end;
4606
- align-items: center;
4607
- flex-wrap: nowrap;
4608
- width: 100%;
4609
- font-size: ${({ big }) => (big ? 1.5 : 1)}rem;
4610
- color: ${({ fontColor, theme: { palette } }) => fontColor || palette.textPrimary};
4611
-
4612
- > * {
4613
- width: ${({ column }) => (column ? "100%" : "auto")};
4614
- }
4615
-
4616
- ${ContainerChart}, ${ContainerLegend} {
4617
- width: ${({ column }) => (column ? "100%" : "50%")};
4618
- }
4619
-
4620
- ${ContainerLegend} {
4621
- margin-left: ${({ column }) => (column ? 0 : "1rem")};
4622
- }
4623
-
4624
- ${ChartLegendContainer} {
4625
- flex-direction: ${({ column }) => (column ? "row" : "column")};
4626
- margin-top: ${({ column }) => (column ? "1rem" : 0)};
4627
- }
4628
- `;
4629
- const ColorIconMixin = css `
4630
- :after {
4631
- color: ${({ $fontColor }) => $fontColor} !important;
4632
- }
4633
- `;
4634
- const SizeIconMixin = css `
4635
- :after {
4636
- font-size: ${({ $fontSize }) => $fontSize}px !important;
4637
- }
4638
- `;
4639
- const ContainerIcon = styled(Icon) `
4640
- width: auto;
4641
- height: auto;
4642
- margin-bottom: 0.5rem;
4643
- ${({ $fontColor }) => !!$fontColor && ColorIconMixin};
4644
- ${({ $fontSize }) => !!$fontSize && SizeIconMixin};
4645
- `;
4646
- const SvgContainerColorMixin$1 = css `
4647
- path,
4648
- line,
4649
- circle {
4650
- fill: ${({ $fontColor }) => $fontColor};
4651
- }
4652
- `;
4653
- const SvgContainer$1 = styled.div `
4654
- &&& {
4655
- min-width: ${({ $width }) => ($width ? `${$width}px` : "1rem")};
4656
- max-width: ${({ $width }) => ($width ? `${$width}px` : "1rem")};
4657
-
4658
- ${({ $fontColor }) => !!$fontColor && SvgContainerColorMixin$1};
4659
-
4660
- > * {
4661
- min-width: inherit;
4662
- }
4663
- }
4664
- `;
4665
- const TwoColumnContainerWrapper = styled(Flex) `
4666
- width: 100%;
4667
- flex-direction: row;
4668
- flex-wrap: nowrap;
4669
- align-items: center;
4670
-
4671
- > * {
4672
- flex: 1;
4673
- }
4674
-
4675
- > ${ContainerValue} {
4676
- justify-content: flex-end;
4677
-
4678
- > * {
4679
- text-align: right;
4680
- }
4681
- }
4682
- `;
4683
-
4684
4605
  const LayerGroupContainer = styled(Flex) `
4685
4606
  display: flex;
4686
4607
  justify-content: center;
@@ -4992,6 +4913,88 @@ const useServerNotificationsContext = () => {
4992
4913
  return useContext(ServerNotificationsContext);
4993
4914
  };
4994
4915
 
4916
+ const SERVER_NOTIFICATION_EVENT = {
4917
+ ReceiveFeaturesUpdate: "ReceiveFeaturesUpdateNotification",
4918
+ PythonProgressNotification: "ReceivePythonProgressNotification",
4919
+ };
4920
+
4921
+ const usePythonTask = () => {
4922
+ const { api, t } = useGlobalContext();
4923
+ const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
4924
+ const [result, setResult] = useState(null);
4925
+ const [error, setError] = useState(null);
4926
+ const [loading, setLoading] = useState(false);
4927
+ const [executionTime, setExecutionTime] = useState(null);
4928
+ const [taskId, setTaskId] = useState(null);
4929
+ const [subscriptionId, setSubscriptionId] = useState(null);
4930
+ const reset = useCallback(() => {
4931
+ setResult(null);
4932
+ setError(null);
4933
+ setLoading(true);
4934
+ setExecutionTime(null);
4935
+ setTaskId(null);
4936
+ setSubscriptionId(null);
4937
+ }, []);
4938
+ const runTask = useCallback(async ({ resourceId, parameters, script, }) => {
4939
+ reset();
4940
+ const start = Date.now();
4941
+ let prototypeId = await api.remoteTaskManager.createTaskPrototype({
4942
+ enabled: true,
4943
+ startIfPreviousError: true,
4944
+ startIfPreviousNotFinished: true,
4945
+ subTaskSettings: [
4946
+ {
4947
+ type: "pythonService",
4948
+ startParameters: {
4949
+ resourceId,
4950
+ parameters,
4951
+ script,
4952
+ method: "pythonrunner/run",
4953
+ },
4954
+ },
4955
+ ],
4956
+ });
4957
+ prototypeId = prototypeId.replace(/["']+/g, "");
4958
+ const { id: newTaskId, success } = await api.remoteTaskManager.startTask1(prototypeId);
4959
+ if (!success) {
4960
+ setResult(t("taskRunFail", { ns: "devMode", defaultValue: "Не удалось запустить задачу" }));
4961
+ setExecutionTime(Date.now() - start);
4962
+ setLoading(false);
4963
+ }
4964
+ const newSubscriptionId = await addSubscription({
4965
+ tag: "python_task_progress_event",
4966
+ taskId: newTaskId,
4967
+ });
4968
+ setTaskId(newTaskId);
4969
+ setSubscriptionId(newSubscriptionId);
4970
+ const onNotification = ({ data }) => {
4971
+ if (data?.taskId === newTaskId) {
4972
+ setResult(`${data ? `${data}\n` : ""}${data.log || ""}`);
4973
+ setError(null);
4974
+ setExecutionTime(Date.now() - start);
4975
+ setLoading(false);
4976
+ setTaskId([RemoteTaskStatus.Completed, RemoteTaskStatus.Error].includes(data.status)
4977
+ ? undefined
4978
+ : newTaskId);
4979
+ setSubscriptionId([RemoteTaskStatus.Completed, RemoteTaskStatus.Error].includes(data.status)
4980
+ ? undefined
4981
+ : newSubscriptionId);
4982
+ if ([RemoteTaskStatus.Completed, RemoteTaskStatus.Error].includes(data.status)) {
4983
+ unsubscribeById(newSubscriptionId);
4984
+ connection.off(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
4985
+ }
4986
+ }
4987
+ };
4988
+ connection.on(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
4989
+ }, [api, connection, addSubscription, unsubscribeById, reset]);
4990
+ const stopTask = useCallback(async () => {
4991
+ await api.remoteTaskManager.stop(taskId);
4992
+ reset();
4993
+ unsubscribeById(subscriptionId);
4994
+ }, [api, reset, unsubscribeById, taskId, subscriptionId]);
4995
+ return { runTask, stopTask, result, error, loading, executionTime };
4996
+ };
4997
+
4995
4998
  const useAppHeight = () => {
4996
4999
  useEffect(() => {
4997
5000
  const setAppHeight = () => {
@@ -5127,12 +5130,8 @@ const LayerListContainer = styled(Flex) `
5127
5130
  box-sizing: border-box;
5128
5131
  `;
5129
5132
 
5130
- const ElementValueWrapper = styled.div `
5131
- transition: background-color ${transition.toggle};
5132
- `;
5133
5133
  const ContainerWrapper = styled(Flex) `
5134
5134
  position: relative;
5135
- min-height: 1rem;
5136
5135
  box-sizing: border-box;
5137
5136
  width: 100%;
5138
5137
  background: ${({ theme: { palette } }) => palette.backgroundAlpha};
@@ -5144,7 +5143,7 @@ const ContainerWrapper = styled(Flex) `
5144
5143
  z-index: ${({ $zIndex }) => $zIndex ?? 1};
5145
5144
  transition: background-color ${transition.toggle};
5146
5145
 
5147
- ${Container} > ${ElementValueWrapper}:not(:last-child) {
5146
+ ${Container} > :not(:last-child) {
5148
5147
  margin-bottom: 1.5rem;
5149
5148
  }
5150
5149
  `;
@@ -5397,74 +5396,155 @@ const FeatureControls = styled(Flex) `
5397
5396
  }
5398
5397
  `;
5399
5398
 
5400
- const getAttributeByName = (attributeName, attributes) => {
5401
- return Array.isArray(attributeName)
5402
- ? null
5403
- : attributeName
5404
- ? attributes?.find(({ name }) => name === attributeName)
5405
- : null;
5406
- };
5407
-
5408
- const formatElementValue = ({ t, value, elementConfig, attributes, wrap, }) => {
5409
- const { id, type, defaultValue, options, style, attributeName, templateName } = elementConfig || {};
5410
- const attribute = attributeName ? getAttributeByName(attributeName, attributes) : null;
5411
- const { fontColor, fontSize, noUnits, tagView, bgColor, withDivider, radius } = options || {};
5412
- const valueOrDefault = value || defaultValue;
5413
- const resultValue = type === "attributeValue" && attribute?.type && attribute?.stringFormat
5414
- ? formatAttributeValue({
5415
- t,
5416
- type: attribute.type,
5417
- value: valueOrDefault,
5418
- stringFormat: attribute.stringFormat,
5419
- noUnits,
5420
- })
5421
- : valueOrDefault;
5422
- if (!wrap)
5423
- return resultValue;
5424
- return (jsxs(Fragment, { children: [tagView ? (jsx(DashboardChip$1, { text: resultValue, "$bgColor": bgColor, "$fontColor": fontColor, "$fontSize": fontSize, "$radius": radius, style: style })) : (jsx(ElementValueWrapper, { "data-id": id, "data-templatename": templateName, style: style, children: resultValue })), withDivider && jsx(Divider, {})] }, id));
5425
- };
5426
-
5427
- const getAttributeValue = (element, attributes) => {
5428
- const attribute = getAttributeByName(element?.attributeName, attributes);
5429
- const { maxLength, separator, expandable, lineBreak } = element.options || {};
5430
- let value = "";
5431
- if (attribute?.type === AttributeType.Boolean && typeof attribute.value === "boolean") {
5432
- return jsx(DashboardCheckbox, { title: attribute.alias || attribute.name, checked: attribute.value });
5433
- }
5434
- if (Array.isArray(element?.attributeName)) {
5435
- const concatAttributes = element.attributeName.map((attributeName) => attributes?.find(({ name }) => name === attributeName)?.value || "");
5436
- value = concatAttributes.join(separator || ", ");
5437
- }
5438
- else {
5439
- value = attribute?.value?.toString() || "";
5440
- }
5441
- return maxLength && maxLength < value.length ? (jsx(TextTrim, { maxLength: maxLength, expandable: expandable, lineBreak: lineBreak, children: value })) : (value);
5442
- };
5443
-
5444
- const getChartAxes = (chartElement) => chartElement?.options?.relatedDataSources?.filter(({ chartAxis }) => chartAxis === "y");
5445
-
5446
- const getChartFilterName = (relatedDataSources) => {
5447
- const relatedAttributes = relatedDataSources || [];
5448
- const axes = relatedAttributes.filter(({ chartAxis }) => chartAxis === "y");
5449
- return axes?.[0]?.filterName;
5450
- };
5451
-
5452
- function getValueIndex(items, attributes) {
5453
- return items?.findIndex(({ name }) => name.toString() === attributes.value?.toString());
5454
- }
5455
- const getChartMarkers = (items, markers, dataSources) => {
5456
- if (typeof markers === "string") {
5457
- const dataSource = getDataSource(markers, dataSources);
5458
- return dataSource?.features?.map(({ attributes }) => ({
5459
- ...attributes,
5460
- value: getValueIndex(items, attributes),
5461
- })) || [];
5462
- }
5463
- return (markers?.map(marker => ({
5464
- ...marker,
5465
- value: getValueIndex(items, marker),
5466
- })) || []);
5467
- };
5399
+ const Container = styled(Flex) `
5400
+ flex-direction: column;
5401
+ width: 100%;
5402
+
5403
+ ${({ isColumn }) => isColumn
5404
+ ? css `
5405
+ > * {
5406
+ width: 100%;
5407
+ }
5408
+ `
5409
+ : css `
5410
+ flex-direction: row;
5411
+ justify-content: space-between;
5412
+ align-items: center;
5413
+ `}
5414
+
5415
+ ${({ isMain, isColumn }) => (isMain || isColumn) &&
5416
+ css `
5417
+ > :not(:last-child) {
5418
+ margin-bottom: 1.5rem;
5419
+ }
5420
+ `}
5421
+
5422
+ ${({ isTitle }) => isTitle &&
5423
+ css `
5424
+ &&&& {
5425
+ margin-bottom: 0.75rem;
5426
+ }
5427
+ `}
5428
+
5429
+ ${({ noBorders }) => noBorders && css `
5430
+ ${ContainerWrapper} {
5431
+ box-shadow: none;
5432
+ padding: 0;
5433
+ }
5434
+ `}
5435
+ `;
5436
+ const ContainerAlias = styled(Flex) `
5437
+ align-items: center;
5438
+ flex-wrap: nowrap;
5439
+ margin-bottom: ${({ hasBottomMargin }) => (hasBottomMargin ? 0.25 : 0)}rem;
5440
+ font-size: 0.75rem;
5441
+ color: ${({ theme: { palette } }) => palette.textSecondary};
5442
+
5443
+ span[kind] {
5444
+ margin-right: 0.5rem;
5445
+
5446
+ :after {
5447
+ color: ${({ theme: { palette } }) => palette.primary};
5448
+ }
5449
+ }
5450
+ `;
5451
+ const ContainerAliasIcon = styled.div `
5452
+ margin-right: 0.5rem;
5453
+ `;
5454
+ const ContainerChart = styled(Flex) `
5455
+ justify-content: flex-start;
5456
+
5457
+ > * {
5458
+ display: flex;
5459
+ justify-content: center;
5460
+ width: 100%;
5461
+ }
5462
+ `;
5463
+ const ContainerLegend = styled(Flex) ``;
5464
+ const ContainerUnits = styled.div `
5465
+ margin-left: 0.5rem;
5466
+ white-space: nowrap;
5467
+ font-size: 0.75rem;
5468
+ `;
5469
+ const ContainerValue = styled(Flex) `
5470
+ justify-content: flex-end;
5471
+ align-items: center;
5472
+ flex-wrap: nowrap;
5473
+ width: 100%;
5474
+ font-size: ${({ big }) => (big ? 1.5 : 1)}rem;
5475
+ color: ${({ fontColor, theme: { palette } }) => fontColor || palette.textPrimary};
5476
+
5477
+ > * {
5478
+ width: ${({ column }) => (column ? "100%" : "auto")};
5479
+ }
5480
+
5481
+ ${ContainerChart}, ${ContainerLegend} {
5482
+ width: ${({ column }) => (column ? "100%" : "50%")};
5483
+ }
5484
+
5485
+ ${ContainerLegend} {
5486
+ margin-left: ${({ column }) => (column ? 0 : "1rem")};
5487
+ }
5488
+
5489
+ ${ChartLegendContainer} {
5490
+ flex-direction: ${({ column }) => (column ? "row" : "column")};
5491
+ margin-top: ${({ column }) => (column ? "1rem" : 0)};
5492
+ }
5493
+ `;
5494
+ const ColorIconMixin = css `
5495
+ :after {
5496
+ color: ${({ $fontColor }) => $fontColor} !important;
5497
+ }
5498
+ `;
5499
+ const SizeIconMixin = css `
5500
+ :after {
5501
+ font-size: ${({ $fontSize }) => $fontSize}px !important;
5502
+ }
5503
+ `;
5504
+ const ContainerIcon = styled(Icon) `
5505
+ width: auto;
5506
+ height: auto;
5507
+ margin-bottom: 0.5rem;
5508
+ ${({ $fontColor }) => !!$fontColor && ColorIconMixin};
5509
+ ${({ $fontSize }) => !!$fontSize && SizeIconMixin};
5510
+ `;
5511
+ const SvgContainerColorMixin$1 = css `
5512
+ path,
5513
+ line,
5514
+ circle {
5515
+ fill: ${({ $fontColor }) => $fontColor};
5516
+ }
5517
+ `;
5518
+ const SvgContainer$1 = styled.div `
5519
+ &&& {
5520
+ min-width: ${({ $width }) => ($width ? `${$width}px` : "1rem")};
5521
+ max-width: ${({ $width }) => ($width ? `${$width}px` : "1rem")};
5522
+
5523
+ ${({ $fontColor }) => !!$fontColor && SvgContainerColorMixin$1};
5524
+
5525
+ > * {
5526
+ min-width: inherit;
5527
+ }
5528
+ }
5529
+ `;
5530
+ const TwoColumnContainerWrapper = styled(Flex) `
5531
+ width: 100%;
5532
+ flex-direction: row;
5533
+ flex-wrap: nowrap;
5534
+ align-items: center;
5535
+
5536
+ > * {
5537
+ flex: 1;
5538
+ }
5539
+
5540
+ > ${ContainerValue} {
5541
+ justify-content: flex-end;
5542
+
5543
+ > * {
5544
+ text-align: right;
5545
+ }
5546
+ }
5547
+ `;
5468
5548
 
5469
5549
  const ContainersGroupContainer = memo(({ elementConfig, type, renderElement }) => {
5470
5550
  const { expandedContainers } = useWidgetContext(type);
@@ -6635,6 +6715,98 @@ const ExportPdfContainer = memo(({ type, elementConfig }) => {
6635
6715
  return (jsx(Container, { id: id, style: style, children: jsx(IconButton, { kind: icon || "download", primary: true, disabled: loading, onClick: onExport, children: title ?? t("downloadPdf", { ns: "dashboard", defaultValue: "Скачать PDF" }) }) }));
6636
6716
  });
6637
6717
 
6718
+ const UploaderContainer = styled(Container) `
6719
+ ${UploaderItemArea} {
6720
+ overflow: visible;
6721
+ padding-top: 1rem;
6722
+ padding-bottom: 1rem;
6723
+ }
6724
+
6725
+ ${UploaderTitleWrapper} {
6726
+ top: 0;
6727
+ padding-top: 0;
6728
+ border: 0;
6729
+ }
6730
+ `;
6731
+ const UploaderTitle = styled(Flex) `
6732
+ flex-direction: column;
6733
+ align-items: center;
6734
+ width: 11rem;
6735
+ margin: 0 auto;
6736
+ text-align: center;
6737
+ font-size: 0.625rem;
6738
+ color: ${({ theme: { palette } }) => palette.textSecondary};
6739
+
6740
+ span[kind] {
6741
+ width: 1.5rem;
6742
+ height: 1.5rem;
6743
+ margin-bottom: 0.75rem;
6744
+
6745
+ :after {
6746
+ font-size: 1.5rem;
6747
+ color: ${({ theme: { palette } }) => palette.textSecondary};
6748
+ opacity: 0.12;
6749
+ }
6750
+ }
6751
+ `;
6752
+
6753
+ const DEFAULT_FILE_EXTENSIONS = ".txt,.csv,.py";
6754
+ const UploadContainer = memo(({ type, elementConfig, renderElement }) => {
6755
+ const { t, api } = useGlobalContext();
6756
+ const { changeFilters } = useWidgetContext(type);
6757
+ const [files, setFiles] = useState([]);
6758
+ const refInput = useRef();
6759
+ const { id, style, options } = elementConfig || {};
6760
+ const { icon, title, filterName, fileExtensions = DEFAULT_FILE_EXTENSIONS, parentResourceId, multiSelect } = options || {};
6761
+ const onUpload = useCallback(async (input) => {
6762
+ const files = Array.isArray(input) ? input : [input];
6763
+ const response = await Promise.all(files.map(file => {
6764
+ return api.file.upload(file, true, parentResourceId, file.name);
6765
+ }));
6766
+ const uploadedFiles = response.map(item => ({
6767
+ name: item.name,
6768
+ id: item.resourceId,
6769
+ done: true,
6770
+ }));
6771
+ setFiles(currentFiles => ([...uploadedFiles, ...currentFiles]));
6772
+ }, [parentResourceId]);
6773
+ const onDelete = useCallback(async (id) => {
6774
+ const index = files.findIndex(file => file.id === id);
6775
+ if (index === -1)
6776
+ return;
6777
+ const resourceId = files[index].id;
6778
+ await api.file.deleteResource(resourceId);
6779
+ setFiles(currentFiles => currentFiles.filter(({ id }) => id !== resourceId));
6780
+ }, [files]);
6781
+ const renderTitle = useMemo(() => {
6782
+ if (files.length)
6783
+ return null;
6784
+ return (jsxs(UploaderTitle, { children: [jsx(Icon, { kind: icon || "upload" }), jsx("div", { children: title ?? t("uploadTitle", {
6785
+ ns: "dashboard",
6786
+ defaultValue: "Перетащите файл сюда или нажмите, чтобы выбрать",
6787
+ }) })] }));
6788
+ }, [icon, t, title, files.length]);
6789
+ useEffect(() => {
6790
+ if (!filterName)
6791
+ return;
6792
+ changeFilters({ [filterName]: { value: files.map(({ id }) => id) } });
6793
+ }, [files]);
6794
+ return (jsxs(Fragment$1, { children: [jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsx(UploaderContainer, { id: id, style: style, children: jsx(Uploader, { title: renderTitle, accept: fileExtensions, fileItems: files, currentRef: refInput, isMultiple: multiSelect, onUpload: onUpload, onDelete: onDelete }) })] }));
6795
+ });
6796
+
6797
+ const TaskContainer = memo(({ elementConfig }) => {
6798
+ const { t } = useGlobalContext();
6799
+ const { runTask, error, result, executionTime, loading } = usePythonTask();
6800
+ const { options } = elementConfig || {};
6801
+ const { title, relatedResources } = options || {};
6802
+ const onClick = useCallback(async () => {
6803
+ await Promise.all(relatedResources.map(({ resourceId, parameters, script }) => {
6804
+ return runTask({ resourceId, parameters, script });
6805
+ }));
6806
+ }, [relatedResources, runTask]);
6807
+ return (jsx(WaitingButton, { primary: true, isWaiting: loading, disabled: !relatedResources?.length, onClick: onClick, children: title || t("run", { ns: "dashboard", defaultValue: "Запуск" }) }));
6808
+ });
6809
+
6638
6810
  const containerComponents = {
6639
6811
  [ContainerTemplate.DefaultAttributes]: DefaultAttributesContainer,
6640
6812
  [ContainerTemplate.Pages]: PagesContainer,
@@ -6656,6 +6828,8 @@ const containerComponents = {
6656
6828
  [ContainerTemplate.AddFeature]: AddFeatureContainer,
6657
6829
  [ContainerTemplate.Divider]: DividerContainer,
6658
6830
  [ContainerTemplate.ExportPdf]: ExportPdfContainer,
6831
+ [ContainerTemplate.Upload]: UploadContainer,
6832
+ [ContainerTemplate.Task]: TaskContainer,
6659
6833
  default: ContainersGroupContainer,
6660
6834
  };
6661
6835
 
@@ -10571,5 +10745,5 @@ const Map$1 = ({ zIndex, lowerSiblings, upperSiblings, onError, children, ...res
10571
10745
  }, children: children }), upperSiblings] }));
10572
10746
  };
10573
10747
 
10574
- export { AddFeatureButton, AddFeatureContainer, AttributeGalleryContainer, AttributeLabel, BaseMapTheme, CONFIG_PAGES_ID, CONFIG_PAGE_ID, CameraContainer, Chart, ChartContainer, ChartLegend, ChartLoading, ContainerChildren, ContainerLoading, ContainerTemplate, ContainerWrapper, ContainersGroupContainer, DEFAULT_ATTRIBUTE_NAME, DEFAULT_BARCHART_RADIUS, DEFAULT_BASE_MAP, DEFAULT_CHART_ANGLE, DEFAULT_CHART_HEIGHT, DEFAULT_CHART_WIDTH, DEFAULT_CIRCLE_PAINT, DEFAULT_DASHBOARD_CONFIG, DEFAULT_DATA_SOURCE_LIMIT, DEFAULT_FILL_EXTRUSION_PAINT, DEFAULT_FILL_PAINT, DEFAULT_ID_ATTRIBUTE_NAME, DEFAULT_LAT, DEFAULT_LINE_PAINT, DEFAULT_LNG, DEFAULT_PAGES_CONFIG, DEFAULT_PIECHART_RADIUS, DEFAULT_ZOOM, Dashboard, DashboardCheckbox, DashboardChip, DashboardContent, DashboardContext, DashboardDefaultHeader, DashboardHeader, DashboardLoading, DashboardPlaceholder, DashboardPlaceholderWrap, DashboardProvider, DashboardWrapper, DataSourceContainer, DataSourceError, DataSourceErrorContainer, DataSourceInnerContainer, DataSourceProgressContainer, DateFormat, DefaultAttributesContainer, DefaultHeaderContainer, DefaultHeaderWrapper, DividerContainer, EditGeometryType, ElementButton, ElementCamera, ElementChart, ElementChips, ElementIcon, ElementImage, ElementLegend, ElementLink, ElementMarkdown, ElementSlideshow, ElementSvg, ElementTooltip, ElementValueWrapper, ExpandableTitle, FEATURE_CARD_DEFAULT_COLORS, FEATURE_CARD_OTHER_COLOR, FILTERED_VALUE_OPACITY, FILTER_PREFIX, FeatureCardButtons, FeatureCardContext, FeatureCardDefaultHeader, FeatureCardGradientHeader, FeatureCardHeader, FeatureCardIconHeader, FeatureCardProvider, FeatureCardSlideshowHeader, FeatureCardTitle, FeatureControls, FeatureTitleContainer, FiltersContainer, GEOMETRY_ATTRIBUTE, GlobalContext, GlobalProvider, Header, HeaderContainer, HeaderFrontView, HeaderTemplate, HeaderTitleContainer, HiddenTitleItems, IconContainer, ImageContainer, LEFT_PANEL_HEADER_HEIGHT, Layer, LayerDescription, LayerGroup, LayerGroupList, LayerIcon, LayerListContainer, LayerTree, LayersContainer, LayersListWrapper, LinearProgressContainer, LogoContainer, MAX_CHART_WIDTH, Map$1 as Map, MapContext, MapProvider, NO_CONTENT_VALUE, NUMERIC_ATTRIBUTE_TYPES, NoLiveSnapshotContainer, OneColumnContainer, PageNavigator, PageTitle, PagesContainer, Pagination, PresentationHeader, PresentationHeaderButtons, PresentationHeaderTools, PresentationPanelContainer, PresentationPanelWrapper, PresentationWrapper, ProgressContainer, RoundedBackgroundContainer, ScalingFactor, ServerNotificationsContext, ServerNotificationsProvider, SlideshowContainer, SmallPreviewContainer$1 as SmallPreviewContainer, SmallPreviewControl, SmallPreviewCounter, SmallPreviewImages, SmallPreviewLeft, SmallPreviewRight, StackBar, SvgImage, TIME_ZONE_FORMAT, TabsContainer, TextTrim, ThemeName, TitleContainer, TmsType, TopContainer, TopContainerButtons, TwoColumnContainer, WidgetType, addDataSource, addDataSources, applyFiltersToCondition, applyQueryFilters, applyVarsToCondition, checkEqualOrIncludes, checkIsLoading, convertSpToTurfFeature, createConfigLayer, createConfigPage, createNewPageId, createTreeNode, dateOptions, debounce, decimalOpacityToHex, eqlParametersToPayload, findAttributeInExpression, formatArea, formatAttributeValue, formatChartRelatedValue, formatConditionValue, formatDataSourceCondition, formatDate$1 as formatDate, formatElementValue, formatLength, formatNumber, formatPolygonMeasure, getActualExtrusionHeight, getAttributeByName, getAttributeValue, getAttributesConfiguration, getChartAxes, getChartFilterName, getChartMarkers, getConfigFilter, getContainerComponent, getDashboardHeader, getDataFromAttributes, getDataFromRelatedFeatures, getDataSource, getDataSourceFilterValue, getDate, getDefaultConfig, getElementValue, getFeatureAttributes, getFeatureCardHeader, getFilterComponent, getFilterSelectedItems, getFilterValue, getFormattedAttributes, getGradientColors, getLayerDefinition, getLayerInfo, getLayerInfoFromDataSources, getPagesFromConfig, getPagesFromProjectInfo, getProxyService, getRelatedAttribute, getRenderElement, getResourceUrl, getRootElementId, getSelectedFilterValue, getSlideshowImages, getSvgUrl, getTotalFromAttributes, getTotalFromRelatedFeatures, hexToRgba, isCompositeLayerConfiguration, isEmptyElementValue, isEmptyValue, isHiddenEmptyValue, isLayerService, isNotValidSelectedTab, isNumeric, isObject, isProxyService, isVisibleContainer, numberOptions, parseClientStyle, pieChartTooltipFromAttributes, pieChartTooltipFromRelatedFeatures, pointOptions, removeDataSource, rgbToHex, roundTotalSum, sliceShownOtherItems, timeOptions, tooltipNameFromAttributes, tooltipValueFromAttributes, tooltipValueFromRelatedFeatures, transparentizeColor, treeNodesToProjectItems, useAppHeight, useChartChange, useChartData, useDashboardHeader, useDataSources, useDebouncedCallback, useDiffPage, useExpandableContainers, useExportPdf, useGetConfigLayer, useGlobalContext, useHeaderRender, useLayerParams, useMapContext, useMapDraw, useProjectDashboardInit, useRedrawLayer, useRelatedDataSourceAttributes, useRenderElement, useServerNotificationsContext, useShownOtherItems, useToggle, useUpdateDataSource, useWidgetConfig, useWidgetContext, useWidgetFilters, useWidgetPage, useWindowResize, useZoomToFeatures, useZoomToPoint };
10748
+ export { AddFeatureButton, AddFeatureContainer, AttributeGalleryContainer, AttributeLabel, BaseMapTheme, CONFIG_PAGES_ID, CONFIG_PAGE_ID, CameraContainer, Chart, ChartContainer, ChartLegend, ChartLoading, ContainerChildren, ContainerLoading, ContainerTemplate, ContainerWrapper, ContainersGroupContainer, DEFAULT_ATTRIBUTE_NAME, DEFAULT_BARCHART_RADIUS, DEFAULT_BASE_MAP, DEFAULT_CHART_ANGLE, DEFAULT_CHART_HEIGHT, DEFAULT_CHART_WIDTH, DEFAULT_CIRCLE_PAINT, DEFAULT_DASHBOARD_CONFIG, DEFAULT_DATA_SOURCE_LIMIT, DEFAULT_FILL_EXTRUSION_PAINT, DEFAULT_FILL_PAINT, DEFAULT_ID_ATTRIBUTE_NAME, DEFAULT_LAT, DEFAULT_LINE_PAINT, DEFAULT_LNG, DEFAULT_PAGES_CONFIG, DEFAULT_PIECHART_RADIUS, DEFAULT_ZOOM, Dashboard, DashboardCheckbox, DashboardChip, DashboardContent, DashboardContext, DashboardDefaultHeader, DashboardHeader, DashboardLoading, DashboardPlaceholder, DashboardPlaceholderWrap, DashboardProvider, DashboardWrapper, DataSourceContainer, DataSourceError, DataSourceErrorContainer, DataSourceInnerContainer, DataSourceProgressContainer, DateFormat, DefaultAttributesContainer, DefaultHeaderContainer, DefaultHeaderWrapper, DividerContainer, EditGeometryType, ElementButton, ElementCamera, ElementChart, ElementChips, ElementIcon, ElementImage, ElementLegend, ElementLink, ElementMarkdown, ElementSlideshow, ElementSvg, ElementTooltip, ExpandableTitle, FEATURE_CARD_DEFAULT_COLORS, FEATURE_CARD_OTHER_COLOR, FILTERED_VALUE_OPACITY, FILTER_PREFIX, FeatureCardButtons, FeatureCardContext, FeatureCardDefaultHeader, FeatureCardGradientHeader, FeatureCardHeader, FeatureCardIconHeader, FeatureCardProvider, FeatureCardSlideshowHeader, FeatureCardTitle, FeatureControls, FeatureTitleContainer, FiltersContainer, GEOMETRY_ATTRIBUTE, GlobalContext, GlobalProvider, Header, HeaderContainer, HeaderFrontView, HeaderTemplate, HeaderTitleContainer, HiddenTitleItems, IconContainer, ImageContainer, LEFT_PANEL_HEADER_HEIGHT, Layer, LayerDescription, LayerGroup, LayerGroupList, LayerIcon, LayerListContainer, LayerTree, LayersContainer, LayersListWrapper, LinearProgressContainer, LogoContainer, MAX_CHART_WIDTH, Map$1 as Map, MapContext, MapProvider, NO_CONTENT_VALUE, NUMERIC_ATTRIBUTE_TYPES, NoLiveSnapshotContainer, OneColumnContainer, PageNavigator, PageTitle, PagesContainer, Pagination, PresentationHeader, PresentationHeaderButtons, PresentationHeaderTools, PresentationPanelContainer, PresentationPanelWrapper, PresentationWrapper, ProgressContainer, RoundedBackgroundContainer, SERVER_NOTIFICATION_EVENT, ScalingFactor, ServerNotificationsContext, ServerNotificationsProvider, SlideshowContainer, SmallPreviewContainer$1 as SmallPreviewContainer, SmallPreviewControl, SmallPreviewCounter, SmallPreviewImages, SmallPreviewLeft, SmallPreviewRight, StackBar, SvgImage, TIME_ZONE_FORMAT, TabsContainer, TextTrim, ThemeName, TitleContainer, TmsType, TopContainer, TopContainerButtons, TwoColumnContainer, UploadContainer, WidgetType, addDataSource, addDataSources, applyFiltersToCondition, applyQueryFilters, applyVarsToCondition, checkEqualOrIncludes, checkIsLoading, convertSpToTurfFeature, createConfigLayer, createConfigPage, createNewPageId, createTreeNode, dateOptions, debounce, decimalOpacityToHex, eqlParametersToPayload, findAttributeInExpression, formatArea, formatAttributeValue, formatChartRelatedValue, formatConditionValue, formatDataSourceCondition, formatDate$1 as formatDate, formatElementValue, formatLength, formatNumber, formatPolygonMeasure, getActualExtrusionHeight, getAttributeByName, getAttributeValue, getAttributesConfiguration, getChartAxes, getChartFilterName, getChartMarkers, getConfigFilter, getContainerComponent, getDashboardHeader, getDataFromAttributes, getDataFromRelatedFeatures, getDataSource, getDataSourceFilterValue, getDate, getDefaultConfig, getElementValue, getFeatureAttributes, getFeatureCardHeader, getFilterComponent, getFilterSelectedItems, getFilterValue, getFormattedAttributes, getGradientColors, getLayerDefinition, getLayerInfo, getLayerInfoFromDataSources, getPagesFromConfig, getPagesFromProjectInfo, getProxyService, getRelatedAttribute, getRenderElement, getResourceUrl, getRootElementId, getSelectedFilterValue, getSlideshowImages, getSvgUrl, getTotalFromAttributes, getTotalFromRelatedFeatures, hexToRgba, isCompositeLayerConfiguration, isEmptyElementValue, isEmptyValue, isHiddenEmptyValue, isLayerService, isNotValidSelectedTab, isNumeric, isObject, isProxyService, isVisibleContainer, numberOptions, parseClientStyle, pieChartTooltipFromAttributes, pieChartTooltipFromRelatedFeatures, pointOptions, removeDataSource, rgbToHex, roundTotalSum, sliceShownOtherItems, timeOptions, tooltipNameFromAttributes, tooltipValueFromAttributes, tooltipValueFromRelatedFeatures, transparentizeColor, treeNodesToProjectItems, useAppHeight, useChartChange, useChartData, useDashboardHeader, useDataSources, useDebouncedCallback, useDiffPage, useExpandableContainers, useExportPdf, useGetConfigLayer, useGlobalContext, useHeaderRender, useLayerParams, useMapContext, useMapDraw, useProjectDashboardInit, usePythonTask, useRedrawLayer, useRelatedDataSourceAttributes, useRenderElement, useServerNotificationsContext, useShownOtherItems, useToggle, useUpdateDataSource, useWidgetConfig, useWidgetContext, useWidgetFilters, useWidgetPage, useWindowResize, useZoomToFeatures, useZoomToPoint };
10575
10749
  //# sourceMappingURL=react.esm.js.map