@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/index.js CHANGED
@@ -3382,6 +3382,8 @@ exports.ContainerTemplate = void 0;
3382
3382
  ContainerTemplate["AddFeature"] = "AddFeature";
3383
3383
  ContainerTemplate["Slideshow"] = "Slideshow";
3384
3384
  ContainerTemplate["ExportPdf"] = "ExportPdf";
3385
+ ContainerTemplate["Upload"] = "Upload";
3386
+ ContainerTemplate["Task"] = "Task";
3385
3387
  ContainerTemplate["Divider"] = "Divider";
3386
3388
  })(exports.ContainerTemplate || (exports.ContainerTemplate = {}));
3387
3389
  exports.HeaderTemplate = void 0;
@@ -4505,6 +4507,75 @@ const DashboardChip$1 = styled(uilibGl.Chip) `
4505
4507
  ${({ $fontColor, $isDefault }) => !!$fontColor && !$isDefault && CustomChipColorMixin}
4506
4508
  `;
4507
4509
 
4510
+ const getAttributeByName = (attributeName, attributes) => {
4511
+ return Array.isArray(attributeName)
4512
+ ? null
4513
+ : attributeName
4514
+ ? attributes?.find(({ name }) => name === attributeName)
4515
+ : null;
4516
+ };
4517
+
4518
+ const formatElementValue = ({ t, value, elementConfig, attributes, wrap, }) => {
4519
+ const { id, type, defaultValue, options, style, attributeName, templateName } = elementConfig || {};
4520
+ const attribute = attributeName ? getAttributeByName(attributeName, attributes) : null;
4521
+ const { fontColor, fontSize, noUnits, tagView, bgColor, withDivider, radius } = options || {};
4522
+ const valueOrDefault = value || defaultValue;
4523
+ const resultValue = type === "attributeValue" && attribute?.type && attribute?.stringFormat
4524
+ ? formatAttributeValue({
4525
+ t,
4526
+ type: attribute.type,
4527
+ value: valueOrDefault,
4528
+ stringFormat: attribute.stringFormat,
4529
+ noUnits,
4530
+ })
4531
+ : valueOrDefault;
4532
+ if (!wrap)
4533
+ return resultValue;
4534
+ return (jsxRuntime.jsxs(React.Fragment, { children: [tagView ? (jsxRuntime.jsx(DashboardChip$1, { text: resultValue, "$bgColor": bgColor, "$fontColor": fontColor, "$fontSize": fontSize, "$radius": radius, style: style })) : resultValue, withDivider && jsxRuntime.jsx(uilibGl.Divider, {})] }, id));
4535
+ };
4536
+
4537
+ const getAttributeValue = (element, attributes) => {
4538
+ const attribute = getAttributeByName(element?.attributeName, attributes);
4539
+ const { maxLength, separator, expandable, lineBreak } = element.options || {};
4540
+ let value = "";
4541
+ if (attribute?.type === api.AttributeType.Boolean && typeof attribute.value === "boolean") {
4542
+ return jsxRuntime.jsx(DashboardCheckbox, { title: attribute.alias || attribute.name, checked: attribute.value });
4543
+ }
4544
+ if (Array.isArray(element?.attributeName)) {
4545
+ const concatAttributes = element.attributeName.map((attributeName) => attributes?.find(({ name }) => name === attributeName)?.value || "");
4546
+ value = concatAttributes.join(separator || ", ");
4547
+ }
4548
+ else {
4549
+ value = attribute?.value?.toString() || "";
4550
+ }
4551
+ return maxLength && maxLength < value.length ? (jsxRuntime.jsx(TextTrim, { maxLength: maxLength, expandable: expandable, lineBreak: lineBreak, children: value })) : (value);
4552
+ };
4553
+
4554
+ const getChartAxes = (chartElement) => chartElement?.options?.relatedDataSources?.filter(({ chartAxis }) => chartAxis === "y");
4555
+
4556
+ const getChartFilterName = (relatedDataSources) => {
4557
+ const relatedAttributes = relatedDataSources || [];
4558
+ const axes = relatedAttributes.filter(({ chartAxis }) => chartAxis === "y");
4559
+ return axes?.[0]?.filterName;
4560
+ };
4561
+
4562
+ function getValueIndex(items, attributes) {
4563
+ return items?.findIndex(({ name }) => name.toString() === attributes.value?.toString());
4564
+ }
4565
+ const getChartMarkers = (items, markers, dataSources) => {
4566
+ if (typeof markers === "string") {
4567
+ const dataSource = getDataSource(markers, dataSources);
4568
+ return dataSource?.features?.map(({ attributes }) => ({
4569
+ ...attributes,
4570
+ value: getValueIndex(items, attributes),
4571
+ })) || [];
4572
+ }
4573
+ return (markers?.map(marker => ({
4574
+ ...marker,
4575
+ value: getValueIndex(items, marker),
4576
+ })) || []);
4577
+ };
4578
+
4508
4579
  const ChartLegendContainer = styled(uilibGl.Flex) `
4509
4580
  flex-direction: column;
4510
4581
  flex-wrap: wrap;
@@ -4533,156 +4604,6 @@ const ChartLegendName = styled.div `
4533
4604
  color: ${({ theme: { palette }, $fontColor }) => $fontColor || palette.textPrimary};
4534
4605
  `;
4535
4606
 
4536
- const Container = styled(uilibGl.Flex) `
4537
- flex-direction: column;
4538
- width: 100%;
4539
-
4540
- ${({ isColumn }) => isColumn
4541
- ? styled.css `
4542
- > * {
4543
- width: 100%;
4544
- }
4545
- `
4546
- : styled.css `
4547
- flex-direction: row;
4548
- justify-content: space-between;
4549
- align-items: center;
4550
- `}
4551
-
4552
- ${({ isMain, isColumn }) => (isMain || isColumn) &&
4553
- styled.css `
4554
- > :not(:last-child) {
4555
- margin-bottom: 1.5rem;
4556
- }
4557
- `}
4558
-
4559
- ${({ isTitle }) => isTitle &&
4560
- styled.css `
4561
- &&&& {
4562
- margin-bottom: 0.75rem;
4563
- }
4564
- `}
4565
-
4566
- ${({ noBorders }) => noBorders && styled.css `
4567
- ${ContainerWrapper} {
4568
- box-shadow: none;
4569
- padding: 0;
4570
- }
4571
- `}
4572
- `;
4573
- const ContainerAlias = styled(uilibGl.Flex) `
4574
- align-items: center;
4575
- flex-wrap: nowrap;
4576
- margin-bottom: ${({ hasBottomMargin }) => (hasBottomMargin ? 0.25 : 0)}rem;
4577
- font-size: 0.75rem;
4578
- color: ${({ theme: { palette } }) => palette.textSecondary};
4579
-
4580
- span[kind] {
4581
- margin-right: 0.5rem;
4582
-
4583
- :after {
4584
- color: ${({ theme: { palette } }) => palette.primary};
4585
- }
4586
- }
4587
- `;
4588
- const ContainerAliasIcon = styled.div `
4589
- margin-right: 0.5rem;
4590
- `;
4591
- const ContainerChart = styled(uilibGl.Flex) `
4592
- justify-content: flex-start;
4593
-
4594
- > * {
4595
- display: flex;
4596
- justify-content: center;
4597
- width: 100%;
4598
- }
4599
- `;
4600
- const ContainerLegend = styled(uilibGl.Flex) ``;
4601
- const ContainerUnits = styled.div `
4602
- margin-left: 0.5rem;
4603
- white-space: nowrap;
4604
- font-size: 0.75rem;
4605
- `;
4606
- const ContainerValue = styled(uilibGl.Flex) `
4607
- justify-content: flex-end;
4608
- align-items: center;
4609
- flex-wrap: nowrap;
4610
- width: 100%;
4611
- font-size: ${({ big }) => (big ? 1.5 : 1)}rem;
4612
- color: ${({ fontColor, theme: { palette } }) => fontColor || palette.textPrimary};
4613
-
4614
- > * {
4615
- width: ${({ column }) => (column ? "100%" : "auto")};
4616
- }
4617
-
4618
- ${ContainerChart}, ${ContainerLegend} {
4619
- width: ${({ column }) => (column ? "100%" : "50%")};
4620
- }
4621
-
4622
- ${ContainerLegend} {
4623
- margin-left: ${({ column }) => (column ? 0 : "1rem")};
4624
- }
4625
-
4626
- ${ChartLegendContainer} {
4627
- flex-direction: ${({ column }) => (column ? "row" : "column")};
4628
- margin-top: ${({ column }) => (column ? "1rem" : 0)};
4629
- }
4630
- `;
4631
- const ColorIconMixin = styled.css `
4632
- :after {
4633
- color: ${({ $fontColor }) => $fontColor} !important;
4634
- }
4635
- `;
4636
- const SizeIconMixin = styled.css `
4637
- :after {
4638
- font-size: ${({ $fontSize }) => $fontSize}px !important;
4639
- }
4640
- `;
4641
- const ContainerIcon = styled(uilibGl.Icon) `
4642
- width: auto;
4643
- height: auto;
4644
- margin-bottom: 0.5rem;
4645
- ${({ $fontColor }) => !!$fontColor && ColorIconMixin};
4646
- ${({ $fontSize }) => !!$fontSize && SizeIconMixin};
4647
- `;
4648
- const SvgContainerColorMixin$1 = styled.css `
4649
- path,
4650
- line,
4651
- circle {
4652
- fill: ${({ $fontColor }) => $fontColor};
4653
- }
4654
- `;
4655
- const SvgContainer$1 = styled.div `
4656
- &&& {
4657
- min-width: ${({ $width }) => ($width ? `${$width}px` : "1rem")};
4658
- max-width: ${({ $width }) => ($width ? `${$width}px` : "1rem")};
4659
-
4660
- ${({ $fontColor }) => !!$fontColor && SvgContainerColorMixin$1};
4661
-
4662
- > * {
4663
- min-width: inherit;
4664
- }
4665
- }
4666
- `;
4667
- const TwoColumnContainerWrapper = styled(uilibGl.Flex) `
4668
- width: 100%;
4669
- flex-direction: row;
4670
- flex-wrap: nowrap;
4671
- align-items: center;
4672
-
4673
- > * {
4674
- flex: 1;
4675
- }
4676
-
4677
- > ${ContainerValue} {
4678
- justify-content: flex-end;
4679
-
4680
- > * {
4681
- text-align: right;
4682
- }
4683
- }
4684
- `;
4685
-
4686
4607
  const LayerGroupContainer = styled(uilibGl.Flex) `
4687
4608
  display: flex;
4688
4609
  justify-content: center;
@@ -4994,6 +4915,88 @@ const useServerNotificationsContext = () => {
4994
4915
  return React.useContext(ServerNotificationsContext);
4995
4916
  };
4996
4917
 
4918
+ const SERVER_NOTIFICATION_EVENT = {
4919
+ ReceiveFeaturesUpdate: "ReceiveFeaturesUpdateNotification",
4920
+ PythonProgressNotification: "ReceivePythonProgressNotification",
4921
+ };
4922
+
4923
+ const usePythonTask = () => {
4924
+ const { api: api$1, t } = useGlobalContext();
4925
+ const { addSubscription, connection, unsubscribeById } = useServerNotificationsContext();
4926
+ const [result, setResult] = React.useState(null);
4927
+ const [error, setError] = React.useState(null);
4928
+ const [loading, setLoading] = React.useState(false);
4929
+ const [executionTime, setExecutionTime] = React.useState(null);
4930
+ const [taskId, setTaskId] = React.useState(null);
4931
+ const [subscriptionId, setSubscriptionId] = React.useState(null);
4932
+ const reset = React.useCallback(() => {
4933
+ setResult(null);
4934
+ setError(null);
4935
+ setLoading(true);
4936
+ setExecutionTime(null);
4937
+ setTaskId(null);
4938
+ setSubscriptionId(null);
4939
+ }, []);
4940
+ const runTask = React.useCallback(async ({ resourceId, parameters, script, }) => {
4941
+ reset();
4942
+ const start = Date.now();
4943
+ let prototypeId = await api$1.remoteTaskManager.createTaskPrototype({
4944
+ enabled: true,
4945
+ startIfPreviousError: true,
4946
+ startIfPreviousNotFinished: true,
4947
+ subTaskSettings: [
4948
+ {
4949
+ type: "pythonService",
4950
+ startParameters: {
4951
+ resourceId,
4952
+ parameters,
4953
+ script,
4954
+ method: "pythonrunner/run",
4955
+ },
4956
+ },
4957
+ ],
4958
+ });
4959
+ prototypeId = prototypeId.replace(/["']+/g, "");
4960
+ const { id: newTaskId, success } = await api$1.remoteTaskManager.startTask1(prototypeId);
4961
+ if (!success) {
4962
+ setResult(t("taskRunFail", { ns: "devMode", defaultValue: "Не удалось запустить задачу" }));
4963
+ setExecutionTime(Date.now() - start);
4964
+ setLoading(false);
4965
+ }
4966
+ const newSubscriptionId = await addSubscription({
4967
+ tag: "python_task_progress_event",
4968
+ taskId: newTaskId,
4969
+ });
4970
+ setTaskId(newTaskId);
4971
+ setSubscriptionId(newSubscriptionId);
4972
+ const onNotification = ({ data }) => {
4973
+ if (data?.taskId === newTaskId) {
4974
+ setResult(`${data ? `${data}\n` : ""}${data.log || ""}`);
4975
+ setError(null);
4976
+ setExecutionTime(Date.now() - start);
4977
+ setLoading(false);
4978
+ setTaskId([api.RemoteTaskStatus.Completed, api.RemoteTaskStatus.Error].includes(data.status)
4979
+ ? undefined
4980
+ : newTaskId);
4981
+ setSubscriptionId([api.RemoteTaskStatus.Completed, api.RemoteTaskStatus.Error].includes(data.status)
4982
+ ? undefined
4983
+ : newSubscriptionId);
4984
+ if ([api.RemoteTaskStatus.Completed, api.RemoteTaskStatus.Error].includes(data.status)) {
4985
+ unsubscribeById(newSubscriptionId);
4986
+ connection.off(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
4987
+ }
4988
+ }
4989
+ };
4990
+ connection.on(SERVER_NOTIFICATION_EVENT.PythonProgressNotification, onNotification);
4991
+ }, [api$1, connection, addSubscription, unsubscribeById, reset]);
4992
+ const stopTask = React.useCallback(async () => {
4993
+ await api$1.remoteTaskManager.stop(taskId);
4994
+ reset();
4995
+ unsubscribeById(subscriptionId);
4996
+ }, [api$1, reset, unsubscribeById, taskId, subscriptionId]);
4997
+ return { runTask, stopTask, result, error, loading, executionTime };
4998
+ };
4999
+
4997
5000
  const useAppHeight = () => {
4998
5001
  React.useEffect(() => {
4999
5002
  const setAppHeight = () => {
@@ -5129,12 +5132,8 @@ const LayerListContainer = styled(uilibGl.Flex) `
5129
5132
  box-sizing: border-box;
5130
5133
  `;
5131
5134
 
5132
- const ElementValueWrapper = styled.div `
5133
- transition: background-color ${uilibGl.transition.toggle};
5134
- `;
5135
5135
  const ContainerWrapper = styled(uilibGl.Flex) `
5136
5136
  position: relative;
5137
- min-height: 1rem;
5138
5137
  box-sizing: border-box;
5139
5138
  width: 100%;
5140
5139
  background: ${({ theme: { palette } }) => palette.backgroundAlpha};
@@ -5146,7 +5145,7 @@ const ContainerWrapper = styled(uilibGl.Flex) `
5146
5145
  z-index: ${({ $zIndex }) => $zIndex ?? 1};
5147
5146
  transition: background-color ${uilibGl.transition.toggle};
5148
5147
 
5149
- ${Container} > ${ElementValueWrapper}:not(:last-child) {
5148
+ ${Container} > :not(:last-child) {
5150
5149
  margin-bottom: 1.5rem;
5151
5150
  }
5152
5151
  `;
@@ -5399,74 +5398,155 @@ const FeatureControls = styled(uilibGl.Flex) `
5399
5398
  }
5400
5399
  `;
5401
5400
 
5402
- const getAttributeByName = (attributeName, attributes) => {
5403
- return Array.isArray(attributeName)
5404
- ? null
5405
- : attributeName
5406
- ? attributes?.find(({ name }) => name === attributeName)
5407
- : null;
5408
- };
5409
-
5410
- const formatElementValue = ({ t, value, elementConfig, attributes, wrap, }) => {
5411
- const { id, type, defaultValue, options, style, attributeName, templateName } = elementConfig || {};
5412
- const attribute = attributeName ? getAttributeByName(attributeName, attributes) : null;
5413
- const { fontColor, fontSize, noUnits, tagView, bgColor, withDivider, radius } = options || {};
5414
- const valueOrDefault = value || defaultValue;
5415
- const resultValue = type === "attributeValue" && attribute?.type && attribute?.stringFormat
5416
- ? formatAttributeValue({
5417
- t,
5418
- type: attribute.type,
5419
- value: valueOrDefault,
5420
- stringFormat: attribute.stringFormat,
5421
- noUnits,
5422
- })
5423
- : valueOrDefault;
5424
- if (!wrap)
5425
- return resultValue;
5426
- return (jsxRuntime.jsxs(React.Fragment, { children: [tagView ? (jsxRuntime.jsx(DashboardChip$1, { text: resultValue, "$bgColor": bgColor, "$fontColor": fontColor, "$fontSize": fontSize, "$radius": radius, style: style })) : (jsxRuntime.jsx(ElementValueWrapper, { "data-id": id, "data-templatename": templateName, style: style, children: resultValue })), withDivider && jsxRuntime.jsx(uilibGl.Divider, {})] }, id));
5427
- };
5428
-
5429
- const getAttributeValue = (element, attributes) => {
5430
- const attribute = getAttributeByName(element?.attributeName, attributes);
5431
- const { maxLength, separator, expandable, lineBreak } = element.options || {};
5432
- let value = "";
5433
- if (attribute?.type === api.AttributeType.Boolean && typeof attribute.value === "boolean") {
5434
- return jsxRuntime.jsx(DashboardCheckbox, { title: attribute.alias || attribute.name, checked: attribute.value });
5435
- }
5436
- if (Array.isArray(element?.attributeName)) {
5437
- const concatAttributes = element.attributeName.map((attributeName) => attributes?.find(({ name }) => name === attributeName)?.value || "");
5438
- value = concatAttributes.join(separator || ", ");
5439
- }
5440
- else {
5441
- value = attribute?.value?.toString() || "";
5442
- }
5443
- return maxLength && maxLength < value.length ? (jsxRuntime.jsx(TextTrim, { maxLength: maxLength, expandable: expandable, lineBreak: lineBreak, children: value })) : (value);
5444
- };
5445
-
5446
- const getChartAxes = (chartElement) => chartElement?.options?.relatedDataSources?.filter(({ chartAxis }) => chartAxis === "y");
5447
-
5448
- const getChartFilterName = (relatedDataSources) => {
5449
- const relatedAttributes = relatedDataSources || [];
5450
- const axes = relatedAttributes.filter(({ chartAxis }) => chartAxis === "y");
5451
- return axes?.[0]?.filterName;
5452
- };
5453
-
5454
- function getValueIndex(items, attributes) {
5455
- return items?.findIndex(({ name }) => name.toString() === attributes.value?.toString());
5456
- }
5457
- const getChartMarkers = (items, markers, dataSources) => {
5458
- if (typeof markers === "string") {
5459
- const dataSource = getDataSource(markers, dataSources);
5460
- return dataSource?.features?.map(({ attributes }) => ({
5461
- ...attributes,
5462
- value: getValueIndex(items, attributes),
5463
- })) || [];
5464
- }
5465
- return (markers?.map(marker => ({
5466
- ...marker,
5467
- value: getValueIndex(items, marker),
5468
- })) || []);
5469
- };
5401
+ const Container = styled(uilibGl.Flex) `
5402
+ flex-direction: column;
5403
+ width: 100%;
5404
+
5405
+ ${({ isColumn }) => isColumn
5406
+ ? styled.css `
5407
+ > * {
5408
+ width: 100%;
5409
+ }
5410
+ `
5411
+ : styled.css `
5412
+ flex-direction: row;
5413
+ justify-content: space-between;
5414
+ align-items: center;
5415
+ `}
5416
+
5417
+ ${({ isMain, isColumn }) => (isMain || isColumn) &&
5418
+ styled.css `
5419
+ > :not(:last-child) {
5420
+ margin-bottom: 1.5rem;
5421
+ }
5422
+ `}
5423
+
5424
+ ${({ isTitle }) => isTitle &&
5425
+ styled.css `
5426
+ &&&& {
5427
+ margin-bottom: 0.75rem;
5428
+ }
5429
+ `}
5430
+
5431
+ ${({ noBorders }) => noBorders && styled.css `
5432
+ ${ContainerWrapper} {
5433
+ box-shadow: none;
5434
+ padding: 0;
5435
+ }
5436
+ `}
5437
+ `;
5438
+ const ContainerAlias = styled(uilibGl.Flex) `
5439
+ align-items: center;
5440
+ flex-wrap: nowrap;
5441
+ margin-bottom: ${({ hasBottomMargin }) => (hasBottomMargin ? 0.25 : 0)}rem;
5442
+ font-size: 0.75rem;
5443
+ color: ${({ theme: { palette } }) => palette.textSecondary};
5444
+
5445
+ span[kind] {
5446
+ margin-right: 0.5rem;
5447
+
5448
+ :after {
5449
+ color: ${({ theme: { palette } }) => palette.primary};
5450
+ }
5451
+ }
5452
+ `;
5453
+ const ContainerAliasIcon = styled.div `
5454
+ margin-right: 0.5rem;
5455
+ `;
5456
+ const ContainerChart = styled(uilibGl.Flex) `
5457
+ justify-content: flex-start;
5458
+
5459
+ > * {
5460
+ display: flex;
5461
+ justify-content: center;
5462
+ width: 100%;
5463
+ }
5464
+ `;
5465
+ const ContainerLegend = styled(uilibGl.Flex) ``;
5466
+ const ContainerUnits = styled.div `
5467
+ margin-left: 0.5rem;
5468
+ white-space: nowrap;
5469
+ font-size: 0.75rem;
5470
+ `;
5471
+ const ContainerValue = styled(uilibGl.Flex) `
5472
+ justify-content: flex-end;
5473
+ align-items: center;
5474
+ flex-wrap: nowrap;
5475
+ width: 100%;
5476
+ font-size: ${({ big }) => (big ? 1.5 : 1)}rem;
5477
+ color: ${({ fontColor, theme: { palette } }) => fontColor || palette.textPrimary};
5478
+
5479
+ > * {
5480
+ width: ${({ column }) => (column ? "100%" : "auto")};
5481
+ }
5482
+
5483
+ ${ContainerChart}, ${ContainerLegend} {
5484
+ width: ${({ column }) => (column ? "100%" : "50%")};
5485
+ }
5486
+
5487
+ ${ContainerLegend} {
5488
+ margin-left: ${({ column }) => (column ? 0 : "1rem")};
5489
+ }
5490
+
5491
+ ${ChartLegendContainer} {
5492
+ flex-direction: ${({ column }) => (column ? "row" : "column")};
5493
+ margin-top: ${({ column }) => (column ? "1rem" : 0)};
5494
+ }
5495
+ `;
5496
+ const ColorIconMixin = styled.css `
5497
+ :after {
5498
+ color: ${({ $fontColor }) => $fontColor} !important;
5499
+ }
5500
+ `;
5501
+ const SizeIconMixin = styled.css `
5502
+ :after {
5503
+ font-size: ${({ $fontSize }) => $fontSize}px !important;
5504
+ }
5505
+ `;
5506
+ const ContainerIcon = styled(uilibGl.Icon) `
5507
+ width: auto;
5508
+ height: auto;
5509
+ margin-bottom: 0.5rem;
5510
+ ${({ $fontColor }) => !!$fontColor && ColorIconMixin};
5511
+ ${({ $fontSize }) => !!$fontSize && SizeIconMixin};
5512
+ `;
5513
+ const SvgContainerColorMixin$1 = styled.css `
5514
+ path,
5515
+ line,
5516
+ circle {
5517
+ fill: ${({ $fontColor }) => $fontColor};
5518
+ }
5519
+ `;
5520
+ const SvgContainer$1 = styled.div `
5521
+ &&& {
5522
+ min-width: ${({ $width }) => ($width ? `${$width}px` : "1rem")};
5523
+ max-width: ${({ $width }) => ($width ? `${$width}px` : "1rem")};
5524
+
5525
+ ${({ $fontColor }) => !!$fontColor && SvgContainerColorMixin$1};
5526
+
5527
+ > * {
5528
+ min-width: inherit;
5529
+ }
5530
+ }
5531
+ `;
5532
+ const TwoColumnContainerWrapper = styled(uilibGl.Flex) `
5533
+ width: 100%;
5534
+ flex-direction: row;
5535
+ flex-wrap: nowrap;
5536
+ align-items: center;
5537
+
5538
+ > * {
5539
+ flex: 1;
5540
+ }
5541
+
5542
+ > ${ContainerValue} {
5543
+ justify-content: flex-end;
5544
+
5545
+ > * {
5546
+ text-align: right;
5547
+ }
5548
+ }
5549
+ `;
5470
5550
 
5471
5551
  const ContainersGroupContainer = React.memo(({ elementConfig, type, renderElement }) => {
5472
5552
  const { expandedContainers } = useWidgetContext(type);
@@ -6637,6 +6717,98 @@ const ExportPdfContainer = React.memo(({ type, elementConfig }) => {
6637
6717
  return (jsxRuntime.jsx(Container, { id: id, style: style, children: jsxRuntime.jsx(uilibGl.IconButton, { kind: icon || "download", primary: true, disabled: loading, onClick: onExport, children: title ?? t("downloadPdf", { ns: "dashboard", defaultValue: "Скачать PDF" }) }) }));
6638
6718
  });
6639
6719
 
6720
+ const UploaderContainer = styled(Container) `
6721
+ ${uilibGl.UploaderItemArea} {
6722
+ overflow: visible;
6723
+ padding-top: 1rem;
6724
+ padding-bottom: 1rem;
6725
+ }
6726
+
6727
+ ${uilibGl.UploaderTitleWrapper} {
6728
+ top: 0;
6729
+ padding-top: 0;
6730
+ border: 0;
6731
+ }
6732
+ `;
6733
+ const UploaderTitle = styled(uilibGl.Flex) `
6734
+ flex-direction: column;
6735
+ align-items: center;
6736
+ width: 11rem;
6737
+ margin: 0 auto;
6738
+ text-align: center;
6739
+ font-size: 0.625rem;
6740
+ color: ${({ theme: { palette } }) => palette.textSecondary};
6741
+
6742
+ span[kind] {
6743
+ width: 1.5rem;
6744
+ height: 1.5rem;
6745
+ margin-bottom: 0.75rem;
6746
+
6747
+ :after {
6748
+ font-size: 1.5rem;
6749
+ color: ${({ theme: { palette } }) => palette.textSecondary};
6750
+ opacity: 0.12;
6751
+ }
6752
+ }
6753
+ `;
6754
+
6755
+ const DEFAULT_FILE_EXTENSIONS = ".txt,.csv,.py";
6756
+ const UploadContainer = React.memo(({ type, elementConfig, renderElement }) => {
6757
+ const { t, api } = useGlobalContext();
6758
+ const { changeFilters } = useWidgetContext(type);
6759
+ const [files, setFiles] = React.useState([]);
6760
+ const refInput = React.useRef();
6761
+ const { id, style, options } = elementConfig || {};
6762
+ const { icon, title, filterName, fileExtensions = DEFAULT_FILE_EXTENSIONS, parentResourceId, multiSelect } = options || {};
6763
+ const onUpload = React.useCallback(async (input) => {
6764
+ const files = Array.isArray(input) ? input : [input];
6765
+ const response = await Promise.all(files.map(file => {
6766
+ return api.file.upload(file, true, parentResourceId, file.name);
6767
+ }));
6768
+ const uploadedFiles = response.map(item => ({
6769
+ name: item.name,
6770
+ id: item.resourceId,
6771
+ done: true,
6772
+ }));
6773
+ setFiles(currentFiles => ([...uploadedFiles, ...currentFiles]));
6774
+ }, [parentResourceId]);
6775
+ const onDelete = React.useCallback(async (id) => {
6776
+ const index = files.findIndex(file => file.id === id);
6777
+ if (index === -1)
6778
+ return;
6779
+ const resourceId = files[index].id;
6780
+ await api.file.deleteResource(resourceId);
6781
+ setFiles(currentFiles => currentFiles.filter(({ id }) => id !== resourceId));
6782
+ }, [files]);
6783
+ const renderTitle = React.useMemo(() => {
6784
+ if (files.length)
6785
+ return null;
6786
+ return (jsxRuntime.jsxs(UploaderTitle, { children: [jsxRuntime.jsx(uilibGl.Icon, { kind: icon || "upload" }), jsxRuntime.jsx("div", { children: title ?? t("uploadTitle", {
6787
+ ns: "dashboard",
6788
+ defaultValue: "Перетащите файл сюда или нажмите, чтобы выбрать",
6789
+ }) })] }));
6790
+ }, [icon, t, title, files.length]);
6791
+ React.useEffect(() => {
6792
+ if (!filterName)
6793
+ return;
6794
+ changeFilters({ [filterName]: { value: files.map(({ id }) => id) } });
6795
+ }, [files]);
6796
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), jsxRuntime.jsx(UploaderContainer, { id: id, style: style, children: jsxRuntime.jsx(uilibGl.Uploader, { title: renderTitle, accept: fileExtensions, fileItems: files, currentRef: refInput, isMultiple: multiSelect, onUpload: onUpload, onDelete: onDelete }) })] }));
6797
+ });
6798
+
6799
+ const TaskContainer = React.memo(({ elementConfig }) => {
6800
+ const { t } = useGlobalContext();
6801
+ const { runTask, error, result, executionTime, loading } = usePythonTask();
6802
+ const { options } = elementConfig || {};
6803
+ const { title, relatedResources } = options || {};
6804
+ const onClick = React.useCallback(async () => {
6805
+ await Promise.all(relatedResources.map(({ resourceId, parameters, script }) => {
6806
+ return runTask({ resourceId, parameters, script });
6807
+ }));
6808
+ }, [relatedResources, runTask]);
6809
+ return (jsxRuntime.jsx(uilibGl.WaitingButton, { primary: true, isWaiting: loading, disabled: !relatedResources?.length, onClick: onClick, children: title || t("run", { ns: "dashboard", defaultValue: "Запуск" }) }));
6810
+ });
6811
+
6640
6812
  const containerComponents = {
6641
6813
  [exports.ContainerTemplate.DefaultAttributes]: DefaultAttributesContainer,
6642
6814
  [exports.ContainerTemplate.Pages]: PagesContainer,
@@ -6658,6 +6830,8 @@ const containerComponents = {
6658
6830
  [exports.ContainerTemplate.AddFeature]: AddFeatureContainer,
6659
6831
  [exports.ContainerTemplate.Divider]: DividerContainer,
6660
6832
  [exports.ContainerTemplate.ExportPdf]: ExportPdfContainer,
6833
+ [exports.ContainerTemplate.Upload]: UploadContainer,
6834
+ [exports.ContainerTemplate.Task]: TaskContainer,
6661
6835
  default: ContainersGroupContainer,
6662
6836
  };
6663
6837
 
@@ -10639,7 +10813,6 @@ exports.ElementMarkdown = ElementMarkdown;
10639
10813
  exports.ElementSlideshow = ElementSlideshow;
10640
10814
  exports.ElementSvg = ElementSvg;
10641
10815
  exports.ElementTooltip = ElementTooltip;
10642
- exports.ElementValueWrapper = ElementValueWrapper;
10643
10816
  exports.ExpandableTitle = ExpandableTitle;
10644
10817
  exports.FEATURE_CARD_DEFAULT_COLORS = FEATURE_CARD_DEFAULT_COLORS;
10645
10818
  exports.FEATURE_CARD_OTHER_COLOR = FEATURE_CARD_OTHER_COLOR;
@@ -10699,6 +10872,7 @@ exports.PresentationPanelWrapper = PresentationPanelWrapper;
10699
10872
  exports.PresentationWrapper = PresentationWrapper;
10700
10873
  exports.ProgressContainer = ProgressContainer;
10701
10874
  exports.RoundedBackgroundContainer = RoundedBackgroundContainer;
10875
+ exports.SERVER_NOTIFICATION_EVENT = SERVER_NOTIFICATION_EVENT;
10702
10876
  exports.ServerNotificationsContext = ServerNotificationsContext;
10703
10877
  exports.ServerNotificationsProvider = ServerNotificationsProvider;
10704
10878
  exports.SlideshowContainer = SlideshowContainer;
@@ -10717,6 +10891,7 @@ exports.TitleContainer = TitleContainer;
10717
10891
  exports.TopContainer = TopContainer;
10718
10892
  exports.TopContainerButtons = TopContainerButtons;
10719
10893
  exports.TwoColumnContainer = TwoColumnContainer;
10894
+ exports.UploadContainer = UploadContainer;
10720
10895
  exports.addDataSource = addDataSource;
10721
10896
  exports.addDataSources = addDataSources;
10722
10897
  exports.applyFiltersToCondition = applyFiltersToCondition;
@@ -10825,6 +11000,7 @@ exports.useLayerParams = useLayerParams;
10825
11000
  exports.useMapContext = useMapContext;
10826
11001
  exports.useMapDraw = useMapDraw;
10827
11002
  exports.useProjectDashboardInit = useProjectDashboardInit;
11003
+ exports.usePythonTask = usePythonTask;
10828
11004
  exports.useRedrawLayer = useRedrawLayer;
10829
11005
  exports.useRelatedDataSourceAttributes = useRelatedDataSourceAttributes;
10830
11006
  exports.useRenderElement = useRenderElement;