Платформа 3V/Формы/Компоненты/Основные/Кнопка/Кнопка 'Сохранить': различия между версиями

Материал из 3v-wiki
Перейти к навигации Перейти к поиску
 
(не показано 38 промежуточных версий 2 участников)
Строка 1: Строка 1:
=!!!СТРАНИЦА НАХОДИТСЯ В СТАДИИ РАЗРАБОТКИ!!!=
+
Кнопку "Сохранить" можно реализовать двумя способами: <br><br>
 +
1. Кнопка Сохранить (ButtonSubmitSourceEntryDto), <br>
 +
2. Пользовательская кнопка (CustomButtonEntry).  <br>
 +
<br>
 +
 
 +
Кнопка Сохранить (ButtonSubmitSourceEntryDto) сохраняет данные автоматически в источники, у которых свойство readOnly = false. <br>
 +
Пользовательской кнопке (CustomButtonEntry) необходимо прописать действие, которое сохраняет добавленный элемент в источнике данных. <br>
 +
Обе кнопки могут содержать дополнительные действия помимо сохранения.  <br>
 +
Основным отличием является порядок выполнения действий -  в кнопке ButtonSubmitSourceEntryDto нельзя управлять порядком сохранения. <br>
 +
 
 +
== Сравнение кнопок  ==
 +
{| class="wikitable"
 +
|-
 +
! Свойство / Тип кнопки !! ButtonSubmitSourceEntryDto !! CustomButtonEntry
 +
|-
 +
| Actions || Может быть пустым || Обязательно должно содержать [[Платформа_3V/Формы/Действия/Сохранение источников|'''действие, <br> которое сохраняет добавленный элемент в источнике данных''']]
 +
|-
 +
| Управлять порядком выполнения действий ||  Нельзя  ||  Можно
 +
 
 +
|}
  
Кнопку "Сохранить" можно реализовать двумя способами: <br>
 
1. кнопка ButtonSubmitSourceEntryDto, <br>
 
2. кнопка CustomButtonEntry.  <br>
 
<br>
 
Обе кнопки могут содержать дополнительные действия помимо сохранения. Основным отличием является порядок сохранения данных -  в кнопке ButtonSubmitSourceEntryDto нельзя управлять порядком сохранения. <br>
 
  
 
==ButtonSubmitSourceEntryDto==
 
==ButtonSubmitSourceEntryDto==
 +
Примерный алгоритм: <br>
 +
1. В раздел uiSources добавляем элемент управления (строка в данном примере), значения которого будет записывать кнопка.
 +
<syntaxhighlight lang="JSON" line>
 +
  "uiSources": [
 +
    {...},
 +
    {
 +
      ...
  
===Пример===
+
      "id": 1,
Имеется справочник контрагентов, ниже представлена серверная карточка для добавления наименования нового контрагента.<br>
+
      "uiDataSource": {
1. Добавлен контрол кнопка Сохранить id=100. <br>
+
        "attribute": {
Этот вид кнопки сохраняет все введенные данные автоматически, при условии, что источник (источники), куда записываются данные имеет свойство "isReadOnly": false.
+
          "id": 2,
 +
          "discriminator": "OwnAttributeDefinitionDto"
 +
        },
 +
        "attributeId": null,
 +
        "sourceId": 1,
 +
        "discriminator": "UiDataSourceDictionary"
 +
      },
 +
      ...
 +
 
 +
      "discriminator": "StringSourceEntry"
 +
    }
 +
]
 +
 
 +
</syntaxhighlight>
 +
</div></div>
 +
 
 +
2. В раздел uiSources добавляем элементы управления кнопка ButtonSubmitSourceEntry. Свойство Actions в данном примере пустое, дополнительных действий нет.
  
 
<syntaxhighlight lang="JSON" line>
 
<syntaxhighlight lang="JSON" line>
{
+
 
      "actionConfirmation": {
+
"uiSources": [
        "message": null,
+
    {
        "conditionId": null
+
      "actionConfirmation": { ... },
      },
+
       "Actions": [],
       "controlsValueCalculateRulesIds": [],
 
      "conditionalActions": [],
 
 
       "onBeforeClickConditionalActions": [],
 
       "onBeforeClickConditionalActions": [],
 
       "submitRuleIds": [],
 
       "submitRuleIds": [],
 
       "id": 100,
 
       "id": 100,
 
       "caption": "Сохранить",
 
       "caption": "Сохранить",
      "enable": true,
+
 
      "visible": true,
+
       ...
      "hint": null,
+
 
      "uiDataSource": null,
 
      "doActionOnChangeValue": true,
 
      "onAfterChangeValueConditionalActions": null,
 
      "onAfterChangeValueByClientConditionalActions": null,
 
      "rebuildDependentsObjectOnChange": false,
 
       "enableRuleIds": [],
 
      "visibleRuleIds": [],
 
      "access": null,
 
      "isValueChanged": false,
 
      "expressionId": null,
 
 
       "discriminator": "ButtonSubmitSourceEntry"
 
       "discriminator": "ButtonSubmitSourceEntry"
     }
+
     },
 +
    {...}
 +
]
  
 
</syntaxhighlight>
 
</syntaxhighlight>
 
</div></div>
 
</div></div>
2. Кнопка Сохранить будет сохранять введенное в строку значение в источник - справочник  id=3.
 
  
<syntaxhighlight lang="JSON" line>
+
3. В раздел entryDataSources добавляем источник (справочник в данном примере), в который записываются данные.  <br>
{
+
Важно, чтобы свойство "isReadOnly" [[Платформа_3V/Формы/Источники_данных|'''источника (источников)''']], куда записываются данные, принимало значение false.
 +
 
 +
<syntaxhighlight lang="JSON" line>
 +
 
 +
"entryDataSources": [
 +
    {
 
       "dictionaryId": 47,
 
       "dictionaryId": 47,
      "hierarchyId": null,
+
 
      "filter": null,
+
       ...
      "sortingOptions": null,
+
 
      "groupingOptions": null,
+
       "id": 1,
      "dictionaryAttributes": null,
 
      "defaultValue": [],
 
       "defaultValueExpressionId": null,
 
      "parameterId": null,
 
      "dictionarySourceSelectionMode": "None",
 
      "dataSourceAttributesAdditionsSettings": [],
 
      "externalFileStorageUrl": null,
 
      "filePrefix": null,
 
      "defaultNewElementSettings": null,
 
       "id": 3,
 
 
       "name": "Список контрагентов",
 
       "name": "Список контрагентов",
 
       "isReadOnly": false,
 
       "isReadOnly": false,
      "dataEditRuleIds": [],
+
 
       "beforeSaveDataActions": [],
+
       ...
      "afterSaveDataActions": [],
+
 
 
       "discriminator": "DictionaryDataSource"
 
       "discriminator": "DictionaryDataSource"
      
+
     }
}
+
  ],
 +
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 
</div></div>
 
</div></div>
  
Здесь два контрола - кнопка Сохранить и строка для ввода нового наименования. <br>
+
Кнопка сохранит все введенные данные автоматически. <br>  
Источник один - справочник в который записываются новые данные, важно, что его свойство isReadOnly имеет значение false, поэтому кнопка типа ButtonSubmitSourceEntry автоматически записывает все введенные данные.<br>
+
 
 +
===Пример===
 +
 
 +
Кейс: Добавление нового элемента справочника.<br>
  
 
[[Файл:Screenshot 2021-06-18 at 11.37.46.png|мини|слева]]
 
[[Файл:Screenshot 2021-06-18 at 11.37.46.png|мини|слева]]
Строка 82: Строка 107:
 
[[Файл:Screenshot 2021-06-18 at 11.41.09.png|мини|слева]]
 
[[Файл:Screenshot 2021-06-18 at 11.41.09.png|мини|слева]]
 
<br><br><br><br><br><br><br><br><br>
 
<br><br><br><br><br><br><br><br><br>
 +
 +
Кнопка Сохранить (контрол id=100) сохрает введенное в строку значение в справочник (источник id=3).
  
 
<div class="toccolours mw-collapsible mw-collapsed" style="width:800px; overflow:auto;">
 
<div class="toccolours mw-collapsible mw-collapsed" style="width:800px; overflow:auto;">
Строка 192: Строка 219:
  
 
==CustomButtonEntry==
 
==CustomButtonEntry==
Кнопка CustomButtonEntry требует [[Платформа_3V/Формы/Действия/Сохранение источников|'''добавить действие, которое сохраняет добавленный элемент в источнике данных''']]. <br>
+
Пользовательская кнопка CustomButtonEntry требует [[Платформа_3V/Формы/Действия/Сохранение источников|'''добавить действие, которое сохраняет добавленный элемент в источнике данных''']]. Действия, "повешанные" на кнопку, будут выполняться последовательно.<br>
 +
Примерный алгоритм:<br>
 +
1. В раздел uiSources добавляем элементы управления. В приведенном примере - дата начала периода, дата окончания периода и строка, которая заполнится рассчитанной длительностью периода.
 +
 
 
<syntaxhighlight lang="JSON" line>
 
<syntaxhighlight lang="JSON" line>
{
+
  "id": 1,
+
"uiSources": [
  "caption": "Сохранить",
+
    {...},
  "nullable": true,
+
    {
  "enable": true,
+
      "id": 222,
  "visible": true,
+
      "caption": "Длительность периода",
  "hint": null,
+
      "uiDataSource": {
  "nullable": true
+
        "attribute": {
  "uiDataSource": null,
+
          "id": 20,
  "doActionOnChangeValue": true,
+
          "discriminator": "OwnAttributeDefinitionDto"
  "onAfterChangeValueConditionalActions": null,
+
        },
  "onAfterChangeValueActions": null,
+
        "attributeId": null,
  "onAfterChangeValueByClientConditionalActions": null,
+
        "sourceId": 1,
  "onAfterChangeValueByClientActions": null,
+
        "discriminator": "UiDataSourceDictionary"
  "rebuildDependentsObjectOnChange": true,
+
      },
  "enableExpressionIds": [],
+
      "discriminator": "StringSourceEntry",
  "visibleExpressionIds": [],
+
      ...
  "isValueChanged" boolean
+
    },
  "expressionId": [],
+
    {
  "controlsValueCalculateRulesIds"[],
+
      "id": 21,
  "actions[ 51, 50]
+
      "caption": "Дата начала периода",
  "onBeforeClickConditionalActions": [],
+
      ...,
  "onBeforeClickActions": [],
+
      "discriminator": "DateTimeSourceEntry"
  "submitRuleIds": [],
+
    },
  "discriminator": CustomButtonEntry,
+
    {
}
+
   
 +
      "id": 22,
 +
      "caption": "Дата конца периода",
 +
      ...,
 +
      "discriminator": "DateTimeSourceEntry"
 +
    },
 +
 
 +
    {...}
 +
]
 +
</syntaxhighlight>
 +
</div></div>
 +
 
 +
2. В раздел uiSources добавляем элементы управления пользовательская кнопка CustomButtonEntry. В Actions в данном примере два действия, сначала рассчитается длинна периода, отобразится в строке и только потом сохранится это значение.
 +
 
 +
<syntaxhighlight lang="JSON" line>
 +
 
 +
"uiSources": [  
 +
    {
 +
      ...,
 +
 
 +
      "Actions": [
 +
        222,
 +
        111
 +
      ],
 +
      "id": 200,
 +
      "caption": "Сохранить",
 +
 
 +
      ...
 +
 
 +
      "discriminator": "CustomButtonEntry"
 +
    },
 +
 
 +
    {...}
 +
]
 +
 
 +
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
</div></div>
 +
 +
3. В раздел entryDataSources добавляем источник (справочник в данном примере), в который записываются данные.  <br>
 +
 +
<syntaxhighlight lang="JSON" line>
 +
 +
"entryDataSources": [
 +
    {
 +
      "dictionaryId": 316,
 +
      ...,
 +
      "name": "Длительность отпусков",
 +
      "isReadOnly": false,
 +
      "dataEditRuleIds": [],
 +
      "beforeSaveDataActions": [],
 +
      "afterSaveDataActions": [],
 +
      "discriminator": "DictionaryDataSource"
 +
    },
 +
    {...}
 +
]
  
 +
</syntaxhighlight>
 +
</div></div>
 
===Пример===
 
===Пример===
Кейс: Внести данные об отпуске сотрудника - ФИО и период, при нажатии кнопки "Сохранить" произойдет вычисление количества дней отпуска, после этого данные сохранятся.
+
Кейс: Внести данные об отпуске сотрудника - ФИО и период.  При нажатии кнопки "Сохранить" выполняться три действия: сначала произойдет вычисление количества дней отпуска, затем данные сохранятся и, наконец, обновится пивот.
 +
 
 +
[[Файл:SubmitButton_1.gif|мини|слева|Внесение данных]]
 +
<br><br><br><br><br><br><br><br><br><br><br>
  
[[Файл:SubmitButton_1.gif|мини|слева]]
+
[[Файл:SubmitButton 4.gif|обрамить|слева|Вычисление и запись результата]]
<br><br><br><br><br><br><br><br><br>
+
<br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  
[[Файл:SubmitButton 4.gif|мини|центр|Вычисление и запись результата]]
 
  
 
<div class="toccolours mw-collapsible mw-collapsed" style="width:800px; overflow:auto;">
 
<div class="toccolours mw-collapsible mw-collapsed" style="width:800px; overflow:auto;">
Строка 247: Строка 335:
 
       },
 
       },
 
       "controlsValueCalculateRulesIds": [],
 
       "controlsValueCalculateRulesIds": [],
       "conditionalActions": [
+
       "Actions": [
 
         222,
 
         222,
 
         111,
 
         111,
Строка 254: Строка 342:
 
       "onBeforeClickConditionalActions": [],
 
       "onBeforeClickConditionalActions": [],
 
       "id": 200,
 
       "id": 200,
       "caption": "Кнопка для вычисления длительности периода",
+
       "caption": "Сохранить",
 
       "enable": true,
 
       "enable": true,
 
       "visible": true,
 
       "visible": true,
Строка 455: Строка 543:
 
       "instanceId": 2,
 
       "instanceId": 2,
 
       "id": 333,
 
       "id": 333,
       "comment": null,
+
       "comment": "Обновление пивота",
 
       "discriminator": "RebuildSourceInstanceAction"
 
       "discriminator": "RebuildSourceInstanceAction"
    }
 
  ],
 
  "conditionalActions": [
 
    {
 
      "id": 111,
 
      "binaryConditionRuleId": null,
 
      "actions": [
 
        111
 
      ],
 
      "parallelRunning": true
 
    },
 
    {
 
      "id": 222,
 
      "binaryConditionRuleId": null,
 
      "actions": [
 
        222
 
      ]
 
    },
 
    {
 
      "id": 333,
 
      "binaryConditionRuleId": null,
 
      "actions": [
 
        333
 
      ]
 
 
     }
 
     }
 
   ],
 
   ],

Текущая версия на 08:43, 17 сентября 2021

Кнопку "Сохранить" можно реализовать двумя способами:

1. Кнопка Сохранить (ButtonSubmitSourceEntryDto),
2. Пользовательская кнопка (CustomButtonEntry).

Кнопка Сохранить (ButtonSubmitSourceEntryDto) сохраняет данные автоматически в источники, у которых свойство readOnly = false.
Пользовательской кнопке (CustomButtonEntry) необходимо прописать действие, которое сохраняет добавленный элемент в источнике данных.
Обе кнопки могут содержать дополнительные действия помимо сохранения.
Основным отличием является порядок выполнения действий - в кнопке ButtonSubmitSourceEntryDto нельзя управлять порядком сохранения.

Сравнение кнопок

Свойство / Тип кнопки ButtonSubmitSourceEntryDto CustomButtonEntry
Actions Может быть пустым Обязательно должно содержать действие,
которое сохраняет добавленный элемент в источнике данных
Управлять порядком выполнения действий Нельзя Можно


ButtonSubmitSourceEntryDto

Примерный алгоритм:
1. В раздел uiSources добавляем элемент управления (строка в данном примере), значения которого будет записывать кнопка.

 1   "uiSources": [
 2     {...},
 3     {
 4       ...
 5 
 6       "id": 1,
 7       "uiDataSource": {
 8         "attribute": {
 9           "id": 2,
10           "discriminator": "OwnAttributeDefinitionDto"
11         },
12         "attributeId": null,
13         "sourceId": 1,
14         "discriminator": "UiDataSourceDictionary"
15       },
16        ... 
17 
18       "discriminator": "StringSourceEntry"
19     }
20 ]

2. В раздел uiSources добавляем элементы управления кнопка ButtonSubmitSourceEntry. Свойство Actions в данном примере пустое, дополнительных действий нет.

 1 "uiSources": [
 2      {
 3       "actionConfirmation": { ... },
 4       "Actions": [],
 5       "onBeforeClickConditionalActions": [],
 6       "submitRuleIds": [],
 7       "id": 100,
 8       "caption": "Сохранить",
 9 
10       ... 
11 
12       "discriminator": "ButtonSubmitSourceEntry"
13     },
14     {...}
15 ]

3. В раздел entryDataSources добавляем источник (справочник в данном примере), в который записываются данные.
Важно, чтобы свойство "isReadOnly" источника (источников), куда записываются данные, принимало значение false.

 1 "entryDataSources": [
 2     {
 3       "dictionaryId": 47,
 4 
 5       ... 
 6 
 7       "id": 1,
 8       "name": "Список контрагентов",
 9       "isReadOnly": false,
10 
11       ...
12 
13       "discriminator": "DictionaryDataSource"
14     }
15   ],

Кнопка сохранит все введенные данные автоматически.

Пример

Кейс: Добавление нового элемента справочника.

Screenshot 2021-06-18 at 11.37.46.png








Screenshot 2021-06-18 at 11.41.09.png










Кнопка Сохранить (контрол id=100) сохрает введенное в строку значение в справочник (источник id=3).

JSON серверной карточки
 1 {
 2   "id": 315,
 3   "name": "Кнопка сохранить (ButtonSubmitSourceEntry)",
 4   "description": null,
 5   "title": "Пример кнопки Сохранить ButtonSubmitSourceEntry",
 6   "entrySettings": null,
 7   "uiSources": [
 8     {
 9       "actionConfirmation": {
10         "message": null,
11         "conditionId": null
12       },
13       "controlsValueCalculateRulesIds": [],
14       "conditionalActions": [],
15       "onBeforeClickConditionalActions": [],
16       "submitRuleIds": [],
17       "id": 100,
18       "caption": "Сохранить",
19       "enable": true,
20       "visible": true,
21       "hint": null,
22       "uiDataSource": null,
23       "doActionOnChangeValue": true,
24       "onAfterChangeValueConditionalActions": null,
25       "onAfterChangeValueByClientConditionalActions": null,
26       "rebuildDependentsObjectOnChange": false,
27       "enableRuleIds": [],
28       "visibleRuleIds": [],
29       "access": null,
30       "isValueChanged": false,
31       "expressionId": null,
32       "discriminator": "ButtonSubmitSourceEntry"
33     },
34     {
35       "trimSpaces": false,
36       "defaultValue": null,
37       "value": null,
38       "id": 1,
39       "caption": "Новый контрагент",
40       "enable": true,
41       "visible": true,
42       "hint": null,
43       "uiDataSource": {
44         "attribute": {
45           "id": 2,
46           "discriminator": "OwnAttributeDefinitionDto"
47         },
48         "attributeId": null,
49         "sourceId": 3,
50         "discriminator": "UiDataSourceDictionary"
51       },
52       "doActionOnChangeValue": false,
53       "onAfterChangeValueConditionalActions": null,
54       "onAfterChangeValueByClientConditionalActions": null,
55       "enableRuleIds": [],
56       "visibleRuleIds": [],
57       "access": null,
58       "isValueChanged": false,
59       "expressionId": null,
60       "discriminator": "StringSourceEntry"
61     }
62   ],
63   "entryDataSources": [
64     {
65       "dictionaryId": 47,
66       "hierarchyId": null,
67       "filter": null,
68       "sortingOptions": null,
69       "groupingOptions": null,
70       "dictionaryAttributes": null,
71       "defaultValue": [],
72       "defaultValueExpressionId": null,
73       "parameterId": null,
74       "dictionarySourceSelectionMode": "None",
75       "dataSourceAttributesAdditionsSettings": [],
76       "externalFileStorageUrl": null,
77       "filePrefix": null,
78       "defaultNewElementSettings": null,
79       "id": 3,
80       "name": "Список контрагентов",
81       "isReadOnly": false,
82       "dataEditRuleIds": [],
83       "beforeSaveDataActions": [],
84       "afterSaveDataActions": [],
85       "discriminator": "DictionaryDataSource"
86     }
87   ],
88   "parameters": [],
89   "binaryConditionsRules": [],
90   "submitValidateRules": [],
91   "expressions": [],
92   "controlsValueCalculateRules": [],
93   "actions": [],
94   "conditionActionIdsOnOpen": [],
95   "conditionalActions": [],
96   "selectionSets": [],
97   "reportTemplates": [],
98   "useNewDependenciesBuilder": null
99 }

CustomButtonEntry

Пользовательская кнопка CustomButtonEntry требует добавить действие, которое сохраняет добавленный элемент в источнике данных. Действия, "повешанные" на кнопку, будут выполняться последовательно.
Примерный алгоритм:
1. В раздел uiSources добавляем элементы управления. В приведенном примере - дата начала периода, дата окончания периода и строка, которая заполнится рассчитанной длительностью периода.

 1  
 2 "uiSources": [
 3     {...},
 4     {
 5       "id": 222,
 6       "caption": "Длительность периода",
 7       "uiDataSource": {
 8         "attribute": {
 9           "id": 20,
10           "discriminator": "OwnAttributeDefinitionDto"
11         },
12         "attributeId": null,
13         "sourceId": 1,
14         "discriminator": "UiDataSourceDictionary"
15       },
16       "discriminator": "StringSourceEntry",
17       ...
18     },
19     {
20       "id": 21,
21       "caption": "Дата начала периода",
22        ...,
23       "discriminator": "DateTimeSourceEntry"
24     },
25     {
26      
27       "id": 22,
28       "caption": "Дата конца периода",
29       ...,
30       "discriminator": "DateTimeSourceEntry"
31     },
32 
33     {...}
34 ]

2. В раздел uiSources добавляем элементы управления пользовательская кнопка CustomButtonEntry. В Actions в данном примере два действия, сначала рассчитается длинна периода, отобразится в строке и только потом сохранится это значение.

 1 "uiSources": [  
 2     {
 3       ...,
 4 
 5       "Actions": [
 6         222,
 7         111
 8       ],
 9       "id": 200,
10       "caption": "Сохранить",
11 
12       ...
13 
14       "discriminator": "CustomButtonEntry"
15     },
16 
17     {...}
18 ]

3. В раздел entryDataSources добавляем источник (справочник в данном примере), в который записываются данные.

 1 "entryDataSources": [
 2     {
 3       "dictionaryId": 316,
 4       ...,
 5       "name": "Длительность отпусков",
 6       "isReadOnly": false,
 7       "dataEditRuleIds": [],
 8       "beforeSaveDataActions": [],
 9       "afterSaveDataActions": [],
10        "discriminator": "DictionaryDataSource"
11     },
12     {...}
13 ]

Пример

Кейс: Внести данные об отпуске сотрудника - ФИО и период. При нажатии кнопки "Сохранить" выполняться три действия: сначала произойдет вычисление количества дней отпуска, затем данные сохранятся и, наконец, обновится пивот.

Внесение данных












Вычисление и запись результата
















JSON серверной карточки
  1 {
  2   "id": 356,
  3   "title": "",
  4   "description": "",
  5   "uiSources": [
  6     {
  7       "submitRuleIds": [],
  8       "actionConfirmation": {
  9         "message": null,
 10         "conditionId": null
 11       },
 12       "controlsValueCalculateRulesIds": [],
 13       "Actions": [
 14         222,
 15         111,
 16         333
 17       ],
 18       "onBeforeClickConditionalActions": [],
 19       "id": 200,
 20       "caption": "Сохранить",
 21       "enable": true,
 22       "visible": true,
 23       "hint": null,
 24       "uiDataSource": null,
 25       "doActionOnChangeValue": false,
 26       "onAfterChangeValueConditionalActions": null,
 27       "onAfterChangeValueByClientConditionalActions": null,
 28       "enableRuleIds": [],
 29       "visibleRuleIds": [],
 30       "access": {
 31         "read": {
 32           "roles": [],
 33           "inversion": false,
 34           "default": true
 35         },
 36         "edit": {
 37           "roles": [],
 38           "inversion": false,
 39           "default": true
 40         }
 41       },
 42       "isValueChanged": false,
 43       "expressionId": null,
 44       "discriminator": "CustomButtonEntry"
 45     },
 46     {
 47       "id": 222,
 48       "caption": "Длительность периода",
 49       "enable": true,
 50       "visible": true,
 51       "uiDataSource": {
 52         "attribute": {
 53           "id": 20,
 54           "discriminator": "OwnAttributeDefinitionDto"
 55         },
 56         "attributeId": null,
 57         "sourceId": 1,
 58         "discriminator": "UiDataSourceDictionary"
 59       },
 60       "discriminator": "StringSourceEntry",
 61       "doActionOnChangeValue": false
 62     },
 63     {
 64       "defaultValue": null,
 65       "value": null,
 66       "id": 21,
 67       "caption": "Дата начала периода",
 68       "enable": true,
 69       "visible": true,
 70       "hint": null,
 71       "doActionOnChangeValue": false,
 72       "onAfterChangeValueConditionalActions": null,
 73       "onAfterChangeValueByClientConditionalActions": null,
 74       "visibleRuleIds": [],
 75       "isValueChanged": false,
 76       "expressionId": null,
 77       "discriminator": "DateTimeSourceEntry"
 78     },
 79     {
 80       "defaultValue": null,
 81       "value": null,
 82       "id": 22,
 83       "caption": "Дата конца периода",
 84       "enable": true,
 85       "visible": true,
 86       "hint": null,
 87       "doActionOnChangeValue": false,
 88       "onAfterChangeValueConditionalActions": null,
 89       "onAfterChangeValueByClientConditionalActions": null,
 90       "visibleRuleIds": [],
 91       "isValueChanged": false,
 92       "expressionId": null,
 93       "discriminator": "DateTimeSourceEntry"
 94     },
 95     {
 96       "trimSpaces": false,
 97       "defaultValue": null,
 98       "value": null,
 99       "id": 1,
100       "caption": "Список сотрудников",
101       "enable": true,
102       "visible": true,
103       "hint": null,
104       "uiDataSource": {
105         "attribute": {
106           "id": 2,
107           "discriminator": "OwnAttributeDefinitionDto"
108         },
109         "attributeId": null,
110         "sourceId": 1,
111         "discriminator": "UiDataSourceDictionary"
112       },
113       "doActionOnChangeValue": false,
114       "onAfterChangeValueConditionalActions": null,
115       "onAfterChangeValueByClientConditionalActions": null,
116       "enableRuleIds": [],
117       "visibleRuleIds": [],
118       "access": null,
119       "isValueChanged": false,
120       "expressionId": null,
121       "discriminator": "StringSourceEntry"
122     },
123     {
124       "id": 2,
125       "pivotSourceId": 2,
126       "doActionOnChangeFocusedCell": false,
127       "doActionOnChangeCellValue": true,
128       "caption": "Пивот Режимы",
129       "enable": true,
130       "visible": true,
131       "hint": null,
132       "uiDataSource": null,
133       "doActionOnChangeValue": false,
134       "onAfterChangeValueConditionalActions": null,
135       "onAfterChangeValueByClientConditionalActions": null,
136       "enableRuleIds": [],
137       "visibleRuleIds": [],
138       "access": {},
139       "isValueChanged": false,
140       "expressionId": null,
141       "discriminator": "PivotSourceEntry"
142     }
143   ],
144   "entryDataSources": [
145     {
146       "dictionaryId": 316,
147       "hierarchyId": null,
148       "filter": null,
149       "sortingOptions": null,
150       "groupingOptions": null,
151       "dictionaryAttributes": null,
152       "defaultValue": [],
153       "defaultValueExpressionId": null,
154       "parameterId": null,
155       "dictionarySourceSelectionMode": "None",
156       "dataSourceAttributesAdditionsSettings": [],
157       "externalFileStorageUrl": null,
158       "filePrefix": null,
159       "defaultNewElementSettings": null,
160       "id": 1,
161       "name": "Отпуска",
162       "isReadOnly": false,
163       "dataEditRuleIds": [],
164       "beforeSaveDataActions": [],
165       "afterSaveDataActions": [],
166       "discriminator": "DictionaryDataSource"
167     },
168     {
169       "pivotId": 358,
170       "parameters": [],
171       "id": 2,
172       "name": "Пивот Сотрудник и количество дней отпуска",
173       "isReadOnly": false,
174       "dataEditRuleIds": [],
175       "beforeSaveDataActions": [],
176       "afterSaveDataActions": [],
177       "discriminator": "PivotDataSource"
178     }
179   ],
180   "parameters": null,
181   "binaryConditionsRules": [],
182   "expressions": [
183     {
184       "id": 222,
185       "expression": "if(IsNullOrEmpty([21]) or IsNullOrEmpty([22]), Null(), (TrimTime([22])-TrimTime([21]))+1)",
186       "returnFirstParameterValue": false,
187       "parameters": [
188         {
189           "uiSourceId": 22,
190           "id": 22,
191           "discriminator": "EntryExpressionUiSourceParameterDto"
192         },
193         {
194           "uiSourceId": 21,
195           "id": 21,
196           "discriminator": "EntryExpressionUiSourceParameterDto"
197         }
198       ],
199       "comment": null
200     }
201   ],
202   "actions": [
203     {
204       "dataSourcesIds": [
205         1
206       ],
207       "id": 111,
208       "comment": "Сохранение значения",
209       "discriminator": "SaveDataSourceAction"
210     },
211     {
212       "id": 222,
213       "controlId": 222,
214       "expressionId": 222,
215       "comment": "Вычисление количества дней отпуска",
216       "discriminator": "CalculateControlValueAction"
217     },
218     {
219       "instanceId": 2,
220       "id": 333,
221       "comment": "Обновление пивота",
222       "discriminator": "RebuildSourceInstanceAction"
223     }
224   ],
225   "conditionActionIdsOnOpen": null
226 }