@gravitee/ui-components 3.25.3-typescript-ad6021f → 3.25.3-typescript-bfd8f67

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.
Files changed (188) hide show
  1. package/package.json +5 -8
  2. package/src/atoms/gv-autocomplete.js +1 -461
  3. package/src/atoms/gv-button.js +1 -410
  4. package/src/atoms/gv-checkbox.js +1 -187
  5. package/src/atoms/gv-date-picker-calendar.js +1 -894
  6. package/src/atoms/gv-date-picker-cell.js +1 -190
  7. package/src/atoms/gv-date-picker.js +1 -671
  8. package/src/atoms/gv-file-upload.js +1 -367
  9. package/src/atoms/gv-icon.js +1 -103
  10. package/src/atoms/gv-image.js +1 -144
  11. package/src/atoms/gv-input-message.js +1 -84
  12. package/src/atoms/gv-input.js +1 -561
  13. package/src/atoms/gv-link.js +1 -210
  14. package/src/atoms/gv-message.js +1 -128
  15. package/src/atoms/gv-metric.js +1 -117
  16. package/src/atoms/gv-relative-time.js +1 -156
  17. package/src/atoms/gv-select-native.js +1 -388
  18. package/src/atoms/gv-select.js +1 -437
  19. package/src/atoms/gv-spinner.js +1 -57
  20. package/src/atoms/gv-state.js +1 -130
  21. package/src/atoms/gv-switch.js +1 -243
  22. package/src/atoms/gv-tag.js +1 -168
  23. package/src/atoms/gv-text.js +1 -168
  24. package/src/charts/gv-chart-bar.js +1 -103
  25. package/src/charts/gv-chart-gauge.js +1 -100
  26. package/src/charts/gv-chart-histogram.js +1 -83
  27. package/src/charts/gv-chart-line.js +1 -224
  28. package/src/charts/gv-chart-map.js +1 -112
  29. package/src/charts/gv-chart-pie.js +1 -91
  30. package/src/index.js +1 -77
  31. package/src/lib/cron-expression.js +1 -205
  32. package/src/lib/date.js +1 -44
  33. package/src/lib/events.js +1 -26
  34. package/src/lib/http-client-schema-form.js +1 -67
  35. package/src/lib/http.js +1 -237
  36. package/src/lib/i18n.js +1 -103
  37. package/src/lib/item.js +1 -118
  38. package/src/lib/properties.js +1 -189
  39. package/src/lib/schema-form.js +1 -44
  40. package/src/lib/studio.js +1 -141
  41. package/src/lib/style.js +1 -41
  42. package/src/lib/text-format.js +1 -69
  43. package/src/lib/theme.js +1 -63
  44. package/src/lib/utils.js +1 -111
  45. package/src/mixins/chart-element.js +1 -165
  46. package/src/mixins/input-element.js +1 -144
  47. package/src/mixins/item-resource.js +1 -120
  48. package/src/mixins/keyboard-element.js +1 -69
  49. package/src/mixins/update-after-browser.js +1 -30
  50. package/src/mixins/with-resize-observer.js +1 -68
  51. package/src/mixins/with-skeleton-attribute.js +1 -112
  52. package/src/molecules/gv-card-full.js +1 -218
  53. package/src/molecules/gv-card-list.js +1 -113
  54. package/src/molecules/gv-card.js +1 -133
  55. package/src/molecules/gv-category-list.js +1 -60
  56. package/src/molecules/gv-category.js +1 -170
  57. package/src/molecules/gv-code.js +1 -359
  58. package/src/molecules/gv-confirm.js +1 -188
  59. package/src/molecules/gv-cron-editor.js +1 -710
  60. package/src/molecules/gv-dropdown-menu.js +1 -116
  61. package/src/molecules/gv-expandable.js +1 -122
  62. package/src/molecules/gv-expression-language.js +1 -270
  63. package/src/molecules/gv-identity-picture.js +1 -148
  64. package/src/molecules/gv-list.js +1 -227
  65. package/src/molecules/gv-metrics.js +1 -162
  66. package/src/molecules/gv-modal.js +1 -213
  67. package/src/molecules/gv-nav.js +1 -196
  68. package/src/molecules/gv-option.js +1 -242
  69. package/src/molecules/gv-plans.js +1 -429
  70. package/src/molecules/gv-popover.js +1 -351
  71. package/src/molecules/gv-promote.js +1 -209
  72. package/src/molecules/gv-rating-list.js +1 -365
  73. package/src/molecules/gv-rating.js +1 -253
  74. package/src/molecules/gv-row-expandable.js +1 -45
  75. package/src/molecules/gv-row.js +1 -210
  76. package/src/molecules/gv-stats.js +1 -121
  77. package/src/molecules/gv-stepper.js +1 -288
  78. package/src/molecules/gv-table.js +1 -685
  79. package/src/molecules/gv-tree.js +1 -250
  80. package/src/organisms/gv-documentation.js +1 -215
  81. package/src/organisms/gv-header.js +1 -288
  82. package/src/organisms/gv-http-client.js +1 -275
  83. package/src/organisms/gv-menu.js +1 -263
  84. package/src/organisms/gv-newsletter-subscription.js +1 -271
  85. package/src/organisms/gv-pagination.js +1 -198
  86. package/src/organisms/gv-properties.js +1 -920
  87. package/src/organisms/gv-resizable-views.js +1 -396
  88. package/src/organisms/gv-resources.js +1 -535
  89. package/src/organisms/gv-schema-form-array.js +1 -250
  90. package/src/organisms/gv-schema-form-control-object.js +1 -154
  91. package/src/organisms/gv-schema-form-control.js +1 -443
  92. package/src/organisms/gv-schema-form.js +1 -751
  93. package/src/organisms/gv-tabs.js +1 -210
  94. package/src/organisms/gv-user-menu.js +1 -314
  95. package/src/organisms/gv-vertical-menu.js +1 -123
  96. package/src/policy-studio/gv-flow-step.js +1 -464
  97. package/src/policy-studio/gv-flow.js +1 -621
  98. package/src/policy-studio/gv-policy-studio-menu.js +1 -750
  99. package/src/policy-studio/gv-policy-studio.js +1 -1842
  100. package/src/styles/empty.js +1 -36
  101. package/src/styles/input.js +1 -263
  102. package/src/styles/link.js +1 -32
  103. package/src/styles/shapes.js +1 -17
  104. package/src/styles/skeleton.js +1 -53
  105. package/src/styles/zoom.js +1 -40
  106. package/src/theme/gv-theme.js +1 -203
  107. package/wc/gv-autocomplete.js +1 -1
  108. package/wc/gv-button.js +1 -1
  109. package/wc/gv-card-full.js +1 -1
  110. package/wc/gv-card-list.js +1 -1
  111. package/wc/gv-card.js +1 -1
  112. package/wc/gv-category-list.js +1 -1
  113. package/wc/gv-category.js +1 -1
  114. package/wc/gv-chart-bar.js +1 -1
  115. package/wc/gv-chart-gauge.js +1 -1
  116. package/wc/gv-chart-histogram.js +1 -1
  117. package/wc/gv-chart-line.js +1 -1
  118. package/wc/gv-chart-map.js +1 -1
  119. package/wc/gv-chart-pie.js +1 -1
  120. package/wc/gv-checkbox.js +1 -1
  121. package/wc/gv-code.js +1 -1
  122. package/wc/gv-confirm.js +1 -1
  123. package/wc/gv-cron-editor.js +1 -1
  124. package/wc/gv-date-picker-calendar.js +1 -1
  125. package/wc/gv-date-picker-cell.js +1 -1
  126. package/wc/gv-date-picker.js +1 -1
  127. package/wc/gv-documentation.js +1 -1
  128. package/wc/gv-dropdown-menu.js +1 -1
  129. package/wc/gv-expandable.js +1 -1
  130. package/wc/gv-expression-language.js +1 -1
  131. package/wc/gv-file-upload.js +1 -1
  132. package/wc/gv-flow-step.js +1 -1
  133. package/wc/gv-flow.js +1 -1
  134. package/wc/gv-header.js +1 -1
  135. package/wc/gv-http-client.js +1 -1
  136. package/wc/gv-icon.js +1 -1
  137. package/wc/gv-identity-picture.js +1 -1
  138. package/wc/gv-image.js +1 -1
  139. package/wc/gv-input-message.js +1 -1
  140. package/wc/gv-input.js +1 -1
  141. package/wc/gv-link.js +1 -1
  142. package/wc/gv-list.js +1 -1
  143. package/wc/gv-menu.js +1 -1
  144. package/wc/gv-message.js +1 -1
  145. package/wc/gv-metric.js +1 -1
  146. package/wc/gv-metrics.js +1 -1
  147. package/wc/gv-modal.js +1 -1
  148. package/wc/gv-nav.js +1 -1
  149. package/wc/gv-newsletter-subscription.js +1 -1
  150. package/wc/gv-option.js +1 -1
  151. package/wc/gv-pagination.js +1 -1
  152. package/wc/gv-plans.js +1 -1
  153. package/wc/gv-policy-studio-menu.js +1 -1
  154. package/wc/gv-policy-studio.js +1 -1
  155. package/wc/gv-popover.js +1 -1
  156. package/wc/gv-promote.js +1 -1
  157. package/wc/gv-properties.js +1 -1
  158. package/wc/gv-rating-list.js +1 -1
  159. package/wc/gv-rating.js +1 -1
  160. package/wc/gv-relative-time.js +1 -1
  161. package/wc/gv-resizable-views.js +1 -1
  162. package/wc/gv-resources.js +1 -1
  163. package/wc/gv-row-expandable.js +1 -1
  164. package/wc/gv-row.js +1 -1
  165. package/wc/gv-schema-form-array.js +1 -1
  166. package/wc/gv-schema-form-control-object.js +1 -1
  167. package/wc/gv-schema-form-control.js +1 -1
  168. package/wc/gv-schema-form.js +1 -1
  169. package/wc/gv-select-native.js +1 -1
  170. package/wc/gv-select.js +1 -1
  171. package/wc/gv-spinner.js +1 -1
  172. package/wc/gv-state.js +1 -1
  173. package/wc/gv-stats.js +1 -1
  174. package/wc/gv-stepper.js +1 -1
  175. package/wc/gv-switch.js +1 -1
  176. package/wc/gv-table.js +1 -1
  177. package/wc/gv-tabs.js +1 -1
  178. package/wc/gv-tag.js +1 -1
  179. package/wc/gv-text.js +1 -1
  180. package/wc/gv-theme.js +1 -1
  181. package/wc/gv-tree.js +1 -1
  182. package/wc/gv-user-menu.js +1 -1
  183. package/wc/gv-vertical-menu.js +1 -1
  184. package/CHANGELOG.md +0 -1292
  185. package/LICENSE.txt +0 -202
  186. package/README.md +0 -195
  187. package/src/.eslintrc.js +0 -19
  188. package/src/theme/definition.json +0 -1762
@@ -1,1842 +1 @@
1
- /*
2
- * Copyright (C) 2015 The Gravitee team (http://gravitee.io)
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import { css, html, LitElement } from 'lit';
17
- import { methods } from '../lib/studio';
18
- import { dispatchCustomEvent } from '../lib/events';
19
- import { i18n } from '../lib/i18n';
20
- import '../atoms/gv-button';
21
- import '../atoms/gv-icon';
22
- import '../molecules/gv-option';
23
- import '../organisms/gv-documentation';
24
- import '../organisms/gv-resizable-views';
25
- import '../organisms/gv-schema-form';
26
- import '../organisms/gv-http-client';
27
- import '../organisms/gv-tabs';
28
- import '../molecules/gv-row';
29
- import './gv-flow';
30
- import './gv-flow-step';
31
- import './gv-policy-studio-menu';
32
- import { empty } from '../styles/empty';
33
- import { cache } from 'lit/directives/cache';
34
- import { deepClone, deepEqual } from '../lib/utils';
35
- import { KeyboardElement, KEYS } from '../mixins/keyboard-element';
36
-
37
- const FLOW_STEP_FORM_ID = 'flow-step-form';
38
-
39
- /**
40
- * Studio Policy component
41
- *
42
- * ⚠️ This component is based on `asciidoctor`, `highlight.js` and `asciidoctor-highlight.js`.
43
- * To use this component in your project be sure the dependencies are installed or
44
- * install them with: `npm install asciidoctor highlight.js asciidoctor-highlight.js --save`
45
- *
46
- * @fires gv-policy-studio:select-policy - Select policy event
47
- * @fires gv-policy-studio:save - Event sent when "Save" button is clicked, it contains the whole definition of the API
48
- * @fires gv-policy-studio:debug - Event sent when validation button of the 'Try it' tab is clicked, it contains the whole definition of the API and the information about the try it request.
49
- *
50
- * @attr {Array} policies - Policies available
51
- * @attr {Array} services - Services available
52
- * @attr {Array} resourceTypes - Resources types available
53
- * @attr {Array} propertyProviders - Providers of properties
54
- * @attr {Array} dynamicPropertySchema - Schema for the dynamic property form
55
- * @attr {String} tabId - Current tabId to display (design, settings, properties or resources)
56
- * @attr {Object} definition - The definition of flows
57
- * @attr {Object} documentation - The documentation to display
58
- * @attr {Object} flowSchema - The flow form configuration to display in gv-schema-form component
59
- * @attr {Object} configurationSchema - The form configuration to display in gv-schema-form component
60
- * @attr {Object} configurationInformation - The information related to api configuration tab
61
- * @attr {Boolean} isDirty - true if component is dirty
62
- * @attr {Array} selectedFlowsId - The selected flows id
63
- * @attr {Boolean} sortable - true if flows are sortable
64
- * @attr {Boolean} readonly - true if readonly
65
- * @attr {Boolean} readonly-plans - true if plans' flows can't be modified
66
- * @attr {Boolean} can-add - true if user can add flow
67
- * @attr {String} flowsTitle - flows menu title
68
- * @attr {Boolean} has-policy-filter - true if policies have onRequest/onResponse properties
69
- * @attr {Boolean} can-debug - true if debug tab should be displayed
70
- * @attr {Object} debugResponse - true if debug tab should be displayed
71
- * @attr {Boolean} has-conditional-steps - true if steps can be conditioned
72
- */
73
- export class GvPolicyStudio extends KeyboardElement(LitElement) {
74
- static get properties() {
75
- return {
76
- policies: { type: Array },
77
- services: { type: Object },
78
- resourceTypes: { type: Array, attribute: 'resource-types' },
79
- propertyProviders: { type: Array, attribute: 'property-providers' },
80
- dynamicPropertySchema: { type: Object, attribute: 'dynamic-property-schema' },
81
- tabId: { type: String, attribute: 'tab-id' },
82
- _tabId: { type: String, attribute: false },
83
- definition: { type: Object },
84
- _definition: { type: Object, attribute: false },
85
- documentation: { type: Object },
86
- flowSchema: { type: Object, attribute: 'flow-schema' },
87
- configurationSchema: { type: Object, attribute: 'configuration-schema' },
88
- _configurationSchema: { type: Object, attribute: false },
89
- configurationInformation: { type: String, attribute: 'configuration-information' },
90
- isDirty: { type: Boolean, attribute: 'dirty', reflect: true },
91
- _dragPolicy: { type: Object, attribute: false },
92
- _dropPolicy: { type: Object, attribute: false },
93
- selectedFlowsId: { type: Array, attribute: 'selected-flows-id' },
94
- _selectedFlowsId: { type: Array, attribute: false },
95
- _currentPolicyId: { type: String, attribute: false },
96
- _searchPolicyQuery: { type: String, attribute: false },
97
- _searchFlowQuery: { type: String, attribute: false },
98
- _flowStepSchema: { type: Object, attribute: false },
99
- _currentFlowStep: { type: Object, attribute: false },
100
- _policyFilter: { type: Array, attribute: false },
101
- _flowFilter: { type: Array, attribute: false },
102
- _currentAskConfirmation: { type: Boolean, attribute: false },
103
- hasProperties: { type: Boolean, attribute: 'has-properties' },
104
- _hasProperties: { type: Boolean, attribute: false },
105
- hasResources: { type: Boolean, attribute: 'has-resources' },
106
- hasPolicyFilter: { type: Boolean, attribute: 'has-policy-filter' },
107
- flowsTitle: { type: String, attribute: 'flows-title' },
108
- sortable: { type: Boolean },
109
- canAdd: { type: Boolean, attribute: 'can-add' },
110
- readonly: { type: Boolean },
111
- readonlyPlans: { type: Boolean, attribute: 'readonly-plans' },
112
- canDebug: { type: Boolean, attribute: 'can-debug' },
113
- _canDebug: { type: Boolean, attribute: false },
114
- debugResponse: { type: Object, attribute: 'debug-response' },
115
- hasConditionalSteps: { type: Boolean, attribute: 'has-conditional-steps' },
116
- };
117
- }
118
-
119
- static get styles() {
120
- return [
121
- empty,
122
- methods,
123
- // language=CSS
124
- css`
125
- :host {
126
- box-sizing: border-box;
127
- --height: var(--gv-policy-studio--h, calc(100vh - 32px));
128
- height: var(--height);
129
- --height-in-tabs: calc(var(--height) - 25px);
130
- }
131
-
132
- .box {
133
- height: var(--height);
134
- display: flex;
135
- }
136
-
137
- .design,
138
- .properties {
139
- display: flex;
140
- }
141
-
142
- gv-resizable-views {
143
- width: 100%;
144
- }
145
-
146
- .editable-name {
147
- padding: 0.5rem 1rem;
148
- font-size: 16px;
149
- }
150
-
151
- .editable-name span {
152
- color: #bfbfbf;
153
- font-size: 12px;
154
- }
155
-
156
- .form__control {
157
- margin: 0.5rem;
158
- }
159
-
160
- gv-input {
161
- width: 100%;
162
- }
163
-
164
- .flow-name {
165
- display: flex;
166
- align-items: center;
167
- }
168
-
169
- .flow-name.dirty {
170
- font-style: italic;
171
- opacity: 0.8;
172
- }
173
-
174
- .flow-name gv-icon {
175
- --gv-icon--s: 24px;
176
- margin-right: 0.2rem;
177
- }
178
-
179
- .flow-path {
180
- margin-left: 0.2rem;
181
- }
182
-
183
- .title_methods {
184
- margin-left: 0.5rem;
185
- }
186
-
187
- .two-cols {
188
- display: flex;
189
- width: 100%;
190
- height: 100%;
191
- }
192
-
193
- .two-cols > * {
194
- flex: 1;
195
- }
196
-
197
- .left-menu {
198
- border-left: 1px solid #d9d9d9;
199
- height: var(--height-in-tabs);
200
- }
201
-
202
- .right-menu {
203
- border-right: 1px solid #d9d9d9;
204
- height: var(--height-in-tabs);
205
- }
206
-
207
- .two-cols > *:first-child {
208
- border-right: 1px solid #d9d9d9;
209
- }
210
-
211
- .flow-step__container {
212
- overflow: hidden;
213
- position: relative;
214
- overflow: hidden;
215
- height: 99%;
216
- }
217
-
218
- .flow-step__form {
219
- padding: 0 0.5rem;
220
- overflow: auto;
221
- }
222
-
223
- .flow-step__form-title {
224
- text-transform: uppercase;
225
- letter-spacing: 0.2rem;
226
- }
227
-
228
- gv-tabs {
229
- width: 100%;
230
- height: 100%;
231
- display: inline-block;
232
- }
233
-
234
- gv-resizable-views,
235
- gv-properties,
236
- gv-resources {
237
- height: var(--height-in-tabs);
238
- }
239
-
240
- gv-properties,
241
- gv-resources {
242
- width: 100%;
243
- }
244
-
245
- gv-properties.properties {
246
- --gv-properties-table--colmg: 10px;
247
- }
248
-
249
- .api-settings {
250
- display: flex;
251
- flex-direction: column;
252
- border-left: 1px solid #bfbfbf;
253
- height: var(--height-in-tabs);
254
- }
255
-
256
- .debug {
257
- display: flex;
258
- flex-direction: column;
259
- border-left: 1px solid #bfbfbf;
260
- height: var(--height-in-tabs);
261
- }
262
-
263
- .api-settings-information {
264
- display: flex;
265
- align-items: center;
266
- }
267
-
268
- .api-settings-information__icon {
269
- --gv-icon--c: var(--gv-theme-color, #5a7684);
270
- --gv-icon-opacity--c: var(--gv-theme-color-info-light, #64b5f6);
271
- }
272
-
273
- .api-settings-information__blockquote,
274
- .debug-information__blockquote {
275
- border-left: 1px solid var(--gv-theme-color, #5a7684);
276
- margin: 15px;
277
- padding-left: 15px;
278
- font-size: 14px;
279
- }
280
-
281
- .flow-settings gv-schema-form {
282
- flex: 1;
283
- padding: 0.5rem;
284
- }
285
-
286
- .search {
287
- display: flex;
288
- justify-content: stretch;
289
- }
290
-
291
- gv-input {
292
- margin: 0.2rem 0;
293
- width: 100%;
294
- }
295
-
296
- .header-actions,
297
- .search-policies {
298
- display: flex;
299
- flex-direction: column;
300
- align-items: center;
301
- margin: 0.5rem;
302
- }
303
-
304
- .search-policies {
305
- margin: 1.5rem 0.5rem 0.5rem;
306
- }
307
-
308
- .footer-actions > gv-button.btn-large,
309
- .footer-actions > gv-option {
310
- width: 100%;
311
- }
312
-
313
- .footer-actions {
314
- display: flex;
315
- flex-direction: column;
316
- align-items: center;
317
- padding: 0.5rem 0;
318
- margin: 0.5rem 15px;
319
- border-top: 1px solid #bfbfbf;
320
- }
321
-
322
- .header-actions .title {
323
- text-transform: uppercase;
324
- text-align: center;
325
- letter-spacing: 0.3rem;
326
- color: #bfbfbf;
327
- font-size: 18px;
328
- white-space: nowrap;
329
- overflow: hidden;
330
- text-overflow: ellipsis;
331
- width: 240px;
332
- min-height: 25px;
333
- }
334
-
335
- .header-actions > *,
336
- .search-policies > * {
337
- margin-bottom: 1rem;
338
- }
339
- `,
340
- ];
341
- }
342
-
343
- constructor() {
344
- super();
345
- this.isDirty = false;
346
- this.policies = [];
347
- this.resourceTypes = [];
348
- this.tabId = 'design';
349
- this.selectedFlowsId = [];
350
- this.flowsTitle = 'Flows';
351
- this.sortable = false;
352
- this.services = {};
353
- this._definition = {
354
- flows: [],
355
- };
356
- this._tabs = [{ id: 'design', title: 'Design', icon: 'navigation:exchange' }];
357
- this._policyFilter = [];
358
- this._flowFilter = [];
359
- }
360
-
361
- set hasProperties(value) {
362
- if (value) {
363
- import('../organisms/gv-properties').then(() => {
364
- this._tabs = [...this._tabs, { id: 'properties', title: 'Properties', icon: 'general:settings#1' }];
365
- this.requestUpdate();
366
- });
367
- }
368
- this._hasProperties = value;
369
- }
370
-
371
- get hasProperties() {
372
- return this._hasProperties;
373
- }
374
-
375
- set hasResources(value) {
376
- if (value) {
377
- import('../organisms/gv-resources').then(() => {
378
- this._tabs = [...this._tabs, { id: 'resources', title: 'Resources', icon: 'general:settings#5' }];
379
- this.requestUpdate();
380
- });
381
- }
382
- }
383
-
384
- set canDebug(value) {
385
- if (value) {
386
- this._tabs = [...this._tabs, { id: 'debug', title: 'Try it', icon: 'content:send' }];
387
- }
388
- }
389
-
390
- get _flowFilterOptions() {
391
- if (this.definedPlans.length > 0) {
392
- return [
393
- { id: 'api', title: 'Api', icon: 'shopping:box#3' },
394
- { id: 'plan', title: 'Plans', icon: 'shopping:sale#2' },
395
- ];
396
- }
397
- }
398
-
399
- set hasPolicyFilter(value) {
400
- if (value) {
401
- this._policyFilterOptions = [
402
- { id: 'onRequest', title: 'Request', icon: 'navigation:arrow-from-left' },
403
- { id: 'onResponse', title: 'Response', icon: 'navigation:arrow-from-right' },
404
- ];
405
- }
406
- }
407
-
408
- set configurationSchema(value) {
409
- if (value) {
410
- this._tabs.splice(1, 0, { id: 'settings', title: 'Configuration', icon: 'general:settings#2' });
411
- }
412
-
413
- this._configurationSchema = value;
414
- }
415
-
416
- get configurationSchema() {
417
- return this._configurationSchema;
418
- }
419
-
420
- onKeyboard() {
421
- if (this._currentAskConfirmation == null) {
422
- if (this.isPressed(KEYS.Shift, KEYS.Ctrl, KEYS.Space)) {
423
- const search = this.shadowRoot.querySelector('#search-policy');
424
- if (search) {
425
- search.focus();
426
- }
427
- } else if (this.isPressed(KEYS.Ctrl, KEYS.Space)) {
428
- const search = this.shadowRoot.querySelector('#search-flow');
429
- if (search) {
430
- search.focus();
431
- }
432
- }
433
- }
434
- }
435
-
436
- set tabId(tabId) {
437
- if (tabId != null && ['design', 'settings', 'properties', 'resources', 'debug'].includes(tabId)) {
438
- this._tabId = tabId;
439
- } else {
440
- this._tabId = 'design';
441
- }
442
- }
443
-
444
- get tabId() {
445
- return this._tabId;
446
- }
447
-
448
- set definition(definition) {
449
- if (definition) {
450
- const flows = this._generateFlowsId(definition.flows);
451
- const resources = this._generateId('resource-', definition.resources);
452
- const plans =
453
- definition.plans == null
454
- ? []
455
- : definition.plans.map((plan) => {
456
- return { ...plan, flows: this._generatePlanFlowsId(plan) };
457
- });
458
- this._initialDefinition = { ...definition, flows, resources, plans };
459
- this._definition = deepClone(this._initialDefinition);
460
- this.isDirty = false;
461
- this._selectFirstFlow();
462
- }
463
- }
464
-
465
- get definition() {
466
- return this._definition;
467
- }
468
-
469
- set selectedFlowsId(selectedFlowsId) {
470
- if (selectedFlowsId != null && Array.isArray(selectedFlowsId)) {
471
- this._selectedFlowsId = selectedFlowsId.filter((id) => this._findFlowById(id) != null);
472
- if (selectedFlowsId.length !== this._selectedFlowsId.length) {
473
- this._selectFirstFlow(true);
474
- }
475
- }
476
- }
477
-
478
- get selectedFlowsId() {
479
- return this._selectedFlowsId.filter((id) => this._findFlowById(id) != null);
480
- }
481
-
482
- _updateSelectedFlows(selectedFlowsId) {
483
- this.selectedFlowsId = selectedFlowsId;
484
- dispatchCustomEvent(this, 'select-flows', { flows: this.selectedFlowsId });
485
- }
486
-
487
- _selectFirstFlow(dispatch = false) {
488
- if (this.selectedFlowsId.length === 0) {
489
- let candidate = null;
490
- if (this.definedFlows.length > 0 && this.definedFlows[0]._id != null) {
491
- candidate = this.definedFlows[0];
492
- } else if (this.definedPlans.length > 0) {
493
- const plan = this.definedPlans.find((plan) => plan.flows != null && plan.flows.length > 0 && plan.flows[0]._id != null);
494
- if (plan) {
495
- candidate = plan.flows[0];
496
- }
497
- }
498
- if (candidate != null) {
499
- if (dispatch) {
500
- this._updateSelectedFlows([candidate._id]);
501
- } else {
502
- this.selectedFlowsId = [candidate._id];
503
- }
504
- }
505
- }
506
- }
507
-
508
- _getFlowElement(flowId) {
509
- return this.shadowRoot.querySelector(`[id="${flowId}"]`);
510
- }
511
-
512
- _onDragEndPolicy() {
513
- this.shadowRoot.querySelectorAll('gv-flow').forEach((e) => e.onDragEnd());
514
- }
515
-
516
- async _onDropPolicy({ detail }) {
517
- try {
518
- await this._askToValidateForms();
519
-
520
- const policy = detail.policy;
521
- const targetFlow = this._findFlowById(detail.flowId);
522
-
523
- let name = policy.name;
524
- let description = '';
525
- let condition = '';
526
- let configuration = {};
527
- let _id;
528
- let _new = false;
529
- if (detail.flowStep) {
530
- _id = detail.flowStep._id;
531
- name = detail.flowStep.name;
532
- description = detail.flowStep.description || '';
533
- condition = detail.flowStep.condition || '';
534
- configuration = detail.flowStep.configuration;
535
- } else {
536
- _id = this._generateFlowStepId(targetFlow._id, detail.flowKey, detail.position);
537
- _new = true;
538
- }
539
-
540
- const flowStep = { _id, _new, name, policy: policy.id, description, condition, enabled: true, configuration };
541
- const sourceFlow = detail.sourceFlowId != null ? this._findFlowById(detail.sourceFlowId) : targetFlow;
542
-
543
- if (detail.sourcePosition != null) {
544
- if (detail.sourceFlowKey && detail.sourceFlowKey !== detail.flowKey) {
545
- sourceFlow[detail.sourceFlowKey].splice(detail.sourcePosition, 1);
546
- targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
547
- if (this._currentFlowStep != null && this._currentFlowStep.step._id === _id) {
548
- this._currentFlowStep.group = detail.flowKey;
549
- // Special case for update schema after change request to response or inverse
550
- const schema = this.buildSchema(this._currentFlowStep.policy);
551
- await this._setCurrentFlowStep(this._currentFlowStep, schema, true);
552
- this._getFlowElement(targetFlow._id).requestUpdate();
553
- }
554
- } else {
555
- if (detail.position > detail.sourcePosition) {
556
- targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
557
- sourceFlow[detail.flowKey].splice(detail.sourcePosition, 1);
558
- } else {
559
- sourceFlow[detail.flowKey].splice(detail.sourcePosition, 1);
560
- targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
561
- }
562
- }
563
- // Force Refresh source flow element when move to other flow
564
- if (targetFlow._id !== sourceFlow._id) {
565
- this._getFlowElement(targetFlow._id).requestUpdate();
566
- }
567
- } else {
568
- targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
569
- const currentFlowForm = this._getFlowStepForm();
570
- if (currentFlowForm == null || currentFlowForm.dirty !== true) {
571
- let step = targetFlow[detail.flowKey][detail.position];
572
- if (step == null) {
573
- // When confirm lose change after drop policy
574
- step = targetFlow[detail.flowKey][detail.position - 1];
575
- }
576
-
577
- if (detail.cancelEdit !== true) {
578
- setTimeout(async () => {
579
- await this._editFlowStep({ step, policy, flow: targetFlow, group: detail.flowKey });
580
- this.updateComplete.then(() => {
581
- const flowElement = this._getFlowElement(targetFlow._id);
582
- flowElement.selectedStepId = step._id;
583
- flowElement.requestUpdate();
584
- });
585
- });
586
- }
587
- }
588
- }
589
- targetFlow._dirty = true;
590
- sourceFlow._dirty = true;
591
- this.isDirty = true;
592
- this.shadowRoot.querySelectorAll('gv-flow').forEach((gvFlow) => gvFlow.removeCandidate());
593
- setTimeout(() => {
594
- this._dragPolicy = null;
595
- this._dropPolicy = null;
596
- }, 0);
597
- } catch (e) {
598
- this._currentAskConfirmation = null;
599
- }
600
- }
601
-
602
- _onDeletePolicy({ detail }) {
603
- const targetFlow = this._findFlowById(detail.flowId);
604
- targetFlow[detail.flowKey].splice(detail.position, 1);
605
- targetFlow._dirty = true;
606
- this.isDirty = true;
607
- if (detail.target.editing) {
608
- this._closeFlowStepForm(true);
609
- }
610
- this._getFlowElement(detail.flowId).requestUpdate();
611
- }
612
-
613
- _onDesign() {
614
- this._changeTab('design');
615
- this._splitMainViews();
616
- }
617
-
618
- buildSchema({ schema }) {
619
- const commonDescription = {
620
- title: 'Description',
621
- description: 'Description of flow step',
622
- type: 'string',
623
- };
624
- const commonCondition = {
625
- title: 'Condition',
626
- description: 'Condition the execution of the flow step (support EL)',
627
- type: 'string',
628
- 'x-schema-form': {
629
- 'expression-language': true,
630
- },
631
- };
632
- if (schema) {
633
- const jsonSchema = typeof schema === 'string' ? JSON.parse(schema) : schema;
634
- const properties = { commonDescription, ...(this.hasConditionalSteps ? { commonCondition } : {}), ...jsonSchema.properties };
635
- return { ...jsonSchema, properties };
636
- }
637
- return { properties: { commonDescription, ...(this.hasConditionalSteps ? { commonCondition } : {}) } };
638
- }
639
-
640
- async _editFlowStep({ step, flow, policy, group }) {
641
- if (step) {
642
- this._currentPolicyId = policy.id;
643
- const currentFlowStep = { flow, step, policy, group };
644
- const schema = this.buildSchema(policy);
645
- try {
646
- await this._setCurrentFlowStep(currentFlowStep, schema);
647
- this._updateSelectedFlows([flow._id]);
648
- this._splitMainViews();
649
- if (localStorage.getItem('gv-policy-studio:keep-documentation-close') == null) {
650
- this._onOpenDocumentation();
651
- }
652
- } catch (e) {
653
- this._currentAskConfirmation = null;
654
- }
655
- } else {
656
- await this._closeFlowStepForm();
657
- this._maximizeTopView();
658
- }
659
- }
660
-
661
- async _onEditFlowStep({ detail: { step, flow, policy, group } }) {
662
- return this._editFlowStep({ step, flow, policy, group });
663
- }
664
-
665
- _getResizableViews() {
666
- return this.shadowRoot.querySelector('gv-resizable-views');
667
- }
668
-
669
- _maximizeTopView() {
670
- if (this.selectedFlowsId.length <= 1) {
671
- this._getResizableViews().maximizeTop();
672
- }
673
- }
674
-
675
- _maximizeBottomView() {
676
- this._getResizableViews().maximizeBottom();
677
- }
678
-
679
- _splitMainViews() {
680
- this._getResizableViews().split();
681
- }
682
-
683
- _onChangeFlowStepState({ detail }) {
684
- const targetFlow = this._findFlowById(detail.flowId);
685
- const step = targetFlow[detail.flowKey][detail.position];
686
- step.enabled = detail.enabled;
687
- targetFlow._dirty = true;
688
- this.isDirty = true;
689
- }
690
-
691
- async _onCloseFlowStepForm() {
692
- try {
693
- await this._closeFlowStepForm();
694
- } catch (err) {
695
- this._currentAskConfirmation = null;
696
- }
697
- }
698
-
699
- async _closeFlowStepForm(force = false) {
700
- await this._setCurrentFlowStep(null, null, force);
701
- }
702
-
703
- async _askToValidateForms() {
704
- if (this._currentAskConfirmation == null) {
705
- this._currentAskConfirmation = true;
706
- return Promise.all(this._submitOrConfirmForms()).then((forms) => {
707
- if (forms.filter((r) => r != null).length > 0) {
708
- this._definition = this._buildDefinitionToSave();
709
- this.getChildren().forEach((e) => e.requestUpdate());
710
- // Refresh if lose changes lost current step selection
711
- return this._checkCurrentFlowStep().then(() => {
712
- this.getChildren().forEach((e) => e.requestUpdate());
713
- return this.updateComplete.then(() => {
714
- this._currentAskConfirmation = null;
715
- return forms;
716
- });
717
- });
718
- } else {
719
- this._currentAskConfirmation = null;
720
- return forms;
721
- }
722
- });
723
- }
724
- throw new Error('ask already waiting');
725
- }
726
-
727
- async _setCurrentFlowStep(currentFlowStep, flowStepSchema, force = false) {
728
- if (!force) {
729
- await this._askToValidateForms();
730
- }
731
-
732
- const schema = deepClone(flowStepSchema);
733
- if (currentFlowStep != null) {
734
- const configuration =
735
- typeof currentFlowStep.step.configuration === 'string'
736
- ? JSON.parse(currentFlowStep.step.configuration)
737
- : currentFlowStep.step.configuration;
738
- const step = { ...currentFlowStep.step, configuration };
739
-
740
- const _initialValues = { ...step.configuration, commonDescription: step.description, commonCondition: step.condition };
741
- this._currentFlowStep = { ...currentFlowStep, step, _initialValues };
742
-
743
- if (flowStepSchema && flowStepSchema.properties.scope) {
744
- const _enum = schema.properties.scope.enum;
745
- if (_enum.find((scope) => ['REQUEST', 'REQUEST_CONTENT', 'RESPONSE', 'RESPONSE_CONTENT'].includes(scope)) != null) {
746
- const filtered = this._currentFlowStep.group === 'pre' ? ['REQUEST', 'REQUEST_CONTENT'] : ['RESPONSE', 'RESPONSE_CONTENT'];
747
- schema.properties.scope.enum = _enum.filter((scope) => filtered.includes(scope));
748
- const scope = this._currentFlowStep.step.configuration.scope;
749
- if (scope == null || !schema.properties.scope.enum.includes(scope)) {
750
- schema.properties.scope.default = schema.properties.scope.enum[0];
751
- this._currentFlowStep.step.configuration.scope = schema.properties.scope.enum[0];
752
- this._currentFlowStep._initialValues.scope = schema.properties.scope.enum[0];
753
- if (this._currentFlowStep._values) {
754
- this._currentFlowStep._values.scope = schema.properties.scope.enum[0];
755
- }
756
- }
757
- }
758
- }
759
- } else {
760
- this._currentFlowStep = null;
761
- }
762
-
763
- this._flowStepSchema = schema;
764
- }
765
-
766
- _refresh(closeStepForm = true) {
767
- if (closeStepForm) {
768
- this._closeFlowStepForm(true);
769
- }
770
- this._definition = deepClone(this._definition);
771
- }
772
-
773
- async _onSelectFlows({ detail }) {
774
- try {
775
- await this._closeFlowStepForm();
776
- this._onCloseDocumentation();
777
- this._updateSelectedFlows(detail.flows);
778
- this._onDesign();
779
- } catch (e) {
780
- this._currentAskConfirmation = null;
781
- }
782
- }
783
-
784
- async _onOpenDocumentationFromMenu({ detail: { policy } }) {
785
- try {
786
- if (this.documentation == null || this.documentation.id !== policy.id) {
787
- await this._closeFlowStepForm();
788
- this._currentPolicyId = policy.id;
789
- if (this.getSelectedFlow()) {
790
- this._splitMainViews();
791
- } else {
792
- this._maximizeBottomView();
793
- }
794
- dispatchCustomEvent(this, 'fetch-documentation', { policy });
795
- }
796
- } catch (e) {}
797
- }
798
-
799
- _fetchDocumentation(policy) {
800
- if (this.documentation == null || this.documentation.id !== policy.id) {
801
- dispatchCustomEvent(this, 'fetch-documentation', { policy });
802
- }
803
- }
804
-
805
- _onOpenDocumentation() {
806
- if (this._currentFlowStep && this._currentFlowStep.policy) {
807
- this._fetchDocumentation(this._currentFlowStep.policy);
808
- }
809
- }
810
-
811
- _onOpenDocumentationFromForm() {
812
- localStorage.removeItem('gv-policy-studio:keep-documentation-close');
813
- this._onOpenDocumentation();
814
- }
815
-
816
- _findFlowCollection(flowId) {
817
- const plan = this.definedPlans.find((plan) => plan.flows.find((flow) => flow._id === flowId) != null);
818
- return { plan, flows: plan != null ? plan.flows : this.definedFlows };
819
- }
820
-
821
- _findFlowById(flowId) {
822
- let flow = this.definedFlows.find((flow) => flow._id === flowId);
823
- if (flow == null) {
824
- const plansFlows = this.definedPlans.map((plan) => plan.flows).reduce((acc, val) => acc.concat(val), []);
825
- flow = plansFlows.find((flow) => flow._id === flowId);
826
- }
827
- return flow;
828
- }
829
-
830
- getSelectedFlow(index = 0) {
831
- const selectedFlowId = this.selectedFlowsId[index];
832
- return this._findFlowById(selectedFlowId);
833
- }
834
-
835
- _onTargetPolicy({ detail }) {
836
- if (this._currentAskConfirmation == null) {
837
- this._dragPolicy = detail;
838
- }
839
- }
840
-
841
- _onChangeFlowStep({ detail }) {
842
- this._currentFlowStep._values = detail.values;
843
- }
844
-
845
- _writeFlowStep(values) {
846
- const { commonDescription, commonCondition, ...configuration } = values;
847
- if (
848
- this._currentFlowStep.step._new ||
849
- this._currentFlowStep.step.description !== commonDescription ||
850
- this._currentFlowStep.step.condition !== commonCondition ||
851
- !deepEqual(this._currentFlowStep.step.configuration, configuration)
852
- ) {
853
- const flow = this._findFlowById(this._currentFlowStep.flow._id);
854
- const position = flow[this._currentFlowStep.group].findIndex((step) => step._id === this._currentFlowStep.step._id);
855
-
856
- flow[this._currentFlowStep.group][position].description = commonDescription;
857
- flow[this._currentFlowStep.group][position].condition = commonCondition;
858
- flow[this._currentFlowStep.group][position].configuration = deepClone(configuration);
859
- delete flow[this._currentFlowStep.group][position]._new;
860
- flow[this._currentFlowStep.group][position]._dirty = true;
861
- flow._dirty = true;
862
- this.isDirty = true;
863
- this._currentFlowStep.flow = flow;
864
- this._currentFlowStep.step = flow[this._currentFlowStep.group][position];
865
- }
866
- }
867
-
868
- async _onSubmitFlowStep({ detail }) {
869
- this._writeFlowStep(detail.values);
870
- await this.requestUpdate('_definition');
871
- this.getChildren().forEach((c) => c.requestUpdate());
872
- }
873
-
874
- _onCancelFlow() {
875
- this._onDesign();
876
- }
877
-
878
- _onSubmitFlow({ detail: { values } }) {
879
- const selectedFlow = this.getSelectedFlow();
880
- const _values = Object.assign({}, this._createFlowFromSchema(), values);
881
- const selectedFlowUpdated = Object.assign({}, selectedFlow, _values);
882
- if (!deepEqual(selectedFlow, selectedFlowUpdated)) {
883
- Object.assign(selectedFlow, selectedFlowUpdated, { _dirty: true });
884
- this.isDirty = true;
885
- this._refresh();
886
- }
887
- }
888
-
889
- _onCancelFlowMode() {
890
- this._onDesign();
891
- }
892
-
893
- _onSubmitFlowMode({ detail: { values } }) {
894
- this._definition['flow-mode'] = values['flow-mode'] || 'DEFAULT';
895
- this.isDirty = true;
896
- this._refresh();
897
- }
898
-
899
- _onChangeTab({ detail }) {
900
- this._changeTab(detail.value);
901
- }
902
-
903
- async _changeTabValidator({ from, to }) {
904
- if (from === 'properties') {
905
- const component = this.shadowRoot.querySelector('gv-properties');
906
- if (component.dirty) {
907
- return component.confirm();
908
- }
909
- } else if (from === 'resources') {
910
- const component = this.shadowRoot.querySelector('gv-resources');
911
- if (component.dirty) {
912
- return component.confirm();
913
- }
914
- } else {
915
- try {
916
- return await this._askToValidateForms();
917
- } catch (e) {
918
- this._currentAskConfirmation = null;
919
- throw e;
920
- }
921
- }
922
- return Promise.resolve();
923
- }
924
-
925
- _changeTab(tabId) {
926
- if (this._currentAskConfirmation == null) {
927
- this.tabId = tabId;
928
- dispatchCustomEvent(this, 'change-tab', this.tabId);
929
- }
930
- }
931
-
932
- _onDragStartFlowStep(flow, { detail }) {
933
- if (this._currentAskConfirmation == null) {
934
- this._dropPolicy = detail;
935
- this._dragPolicy = detail;
936
- }
937
- }
938
-
939
- _renderFlowEmptyState(readonlyMode) {
940
- return html`<div slot="content" class="empty">
941
- <div>
942
- Select a flow
943
- ${readonlyMode !== true
944
- ? html`or <gv-button @gv-button:click="${this._onAddFlow}" outlined icon="code:plus" large>design new one</gv-button>`
945
- : ''}
946
- </div>
947
- </div>`;
948
- }
949
-
950
- _renderFlow(index = 0, hasEmptyState = true, readonlyMode) {
951
- const flow = this.getSelectedFlow(index);
952
- if (flow) {
953
- const { plan } = this._findFlowCollection(flow._id);
954
- const selectedStepId = this._currentFlowStep ? this._currentFlowStep.step._id : null;
955
- return html` <gv-flow
956
- style="height: 100%"
957
- .id="${flow._id}"
958
- .flow="${flow}"
959
- .plan="${plan}"
960
- .policies="${this.policies}"
961
- slot="content"
962
- ?disabled="${this._currentAskConfirmation}"
963
- .dragPolicy="${this._dragPolicy}"
964
- .dropPolicy="${this._dropPolicy}"
965
- .selectedStepId="${selectedStepId}"
966
- ?readonly="${readonlyMode}"
967
- ?has-policy-filter="${this._policyFilterOptions != null}"
968
- flows-title="${this.flowsTitle}"
969
- @gv-flow:drag-start="${this._onDragStartFlowStep.bind(this, flow)}"
970
- @gv-flow:edit="${this._onEditFlowStep}"
971
- @gv-flow:change-state="${this._onChangeFlowStepState}"
972
- @gv-flow:drop="${this._onDropPolicy}"
973
- @gv-flow:delete="${this._onDeletePolicy}"
974
- ></gv-flow>`;
975
- } else if (hasEmptyState) {
976
- return this._renderFlowEmptyState(readonlyMode);
977
- }
978
- return html``;
979
- }
980
-
981
- _onFetchResources(event) {
982
- const { currentTarget, regexTypes } = event.detail;
983
- const options = this.definedResources
984
- .filter((resource) => regexTypes == null || new RegExp(regexTypes).test(resource.type))
985
- .map((resource, index) => {
986
- const resourceType = this.resourceTypes.find((type) => type.id === resource.type);
987
- const row = document.createElement('gv-row');
988
- const picture = resourceType.icon ? resourceType.icon : null;
989
- row.item = { picture, name: resource.name };
990
- return {
991
- element: row,
992
- value: resource.name,
993
- id: resource.type,
994
- };
995
- });
996
- currentTarget.options = options;
997
- }
998
-
999
- _renderPolicy(readonlyMode) {
1000
- if (this._flowStepSchema && this.documentation) {
1001
- return html`<gv-resizable-views direction="horizontal" no-overflow>
1002
- <div slot="top">${this._renderFlowStepForm(readonlyMode)}</div>
1003
- <div slot="bottom">
1004
- <gv-documentation
1005
- .text="${this.documentation.content}"
1006
- .image="${this.documentation.image}"
1007
- ?disabled="${this._currentAskConfirmation}"
1008
- @gv-documentation:close="${this._onCloseDocumentation}"
1009
- ></gv-documentation>
1010
- </div>
1011
- </gv-resizable-views>`;
1012
- } else if (this.documentation) {
1013
- return html`<gv-documentation
1014
- .text="${this.documentation.content}"
1015
- .image="${this.documentation.image}"
1016
- ?disabled="${this._currentAskConfirmation}"
1017
- @gv-documentation:close="${this._onCloseDocumentation}"
1018
- ></gv-documentation>`;
1019
- } else if (this._flowStepSchema) {
1020
- return this._renderFlowStepForm(readonlyMode);
1021
- }
1022
- return html``;
1023
- }
1024
-
1025
- _getFlowStepForm() {
1026
- return this.shadowRoot.querySelector(`#${FLOW_STEP_FORM_ID}`);
1027
- }
1028
-
1029
- _onResetFlowStep() {
1030
- if (this._currentFlowStep) {
1031
- delete this._currentFlowStep._values;
1032
- this._getFlowStepForm().reset();
1033
- }
1034
- }
1035
-
1036
- _generateFlowsId(list, force = false) {
1037
- return this._generateId('f', list, force, true);
1038
- }
1039
-
1040
- _generatePlanFlowsId(plan, force = false) {
1041
- return this._generateId(plan.id, plan.flows, force, true);
1042
- }
1043
-
1044
- _generateFlowStepId(flowId, flowKey, position) {
1045
- return `${flowId}_${flowKey}_${position}`;
1046
- }
1047
-
1048
- _generateId(prefix, list, force = false, isFlow = false) {
1049
- if (list) {
1050
- return list.map((e, index) => {
1051
- const _id = `${prefix}_${index}`;
1052
- if (isFlow) {
1053
- if (e.pre) {
1054
- e.pre.forEach((step, stepIndex) => (step._id = this._generateFlowStepId(_id, 'pre', stepIndex)));
1055
- }
1056
- if (e.post) {
1057
- e.post.forEach((step, stepIndex) => (step._id = this._generateFlowStepId(_id, 'post', stepIndex)));
1058
- }
1059
- }
1060
- if (force || e._id == null) {
1061
- return { ...e, _id };
1062
- }
1063
- return e;
1064
- });
1065
- }
1066
- return list;
1067
- }
1068
-
1069
- getChildren() {
1070
- return [
1071
- ...Array.from(this.shadowRoot.querySelectorAll('gv-flow')),
1072
- ...Array.from(this.shadowRoot.querySelectorAll('gv-resizable-views')),
1073
- ];
1074
- }
1075
-
1076
- async getUpdateComplete() {
1077
- await super.getUpdateComplete();
1078
- await Promise.all(this.getChildren().map((e) => e.updateComplete));
1079
- }
1080
-
1081
- shouldUpdate(changedProperties) {
1082
- // Just refresh gv-flow components
1083
- if (changedProperties.has('_dragPolicy')) {
1084
- this.shadowRoot.querySelectorAll('gv-flow').forEach((flow) => (flow.dragPolicy = this._dragPolicy));
1085
- return false;
1086
- }
1087
- if (changedProperties.has('_dropPolicy')) {
1088
- this.shadowRoot.querySelectorAll('gv-flow').forEach((flow) => (flow.dropPolicy = this._dropPolicy));
1089
- return false;
1090
- }
1091
- return super.shouldUpdate(changedProperties);
1092
- }
1093
-
1094
- updated(props) {
1095
- if (props.has('documentation') && this.documentation != null && this.selectedFlowsId.length > 1) {
1096
- this._updateSelectedFlows([this.selectedFlowsId[0]]);
1097
- }
1098
- }
1099
-
1100
- _renderFlowStepForm(readonlyMode) {
1101
- const values = this._currentFlowStep._values || this._currentFlowStep._initialValues;
1102
-
1103
- const groups = [{ items: ['commonDescription', 'commonCondition'] }, { name: i18n('gv-policy-studio.policy-settings'), default: true }];
1104
- return html`${cache(
1105
- this._flowStepSchema && this._currentFlowStep
1106
- ? html`<div class="flow-step__container">
1107
- <div class="flow-step__form">
1108
- <gv-schema-form
1109
- .id="${FLOW_STEP_FORM_ID}"
1110
- .schema="${this._flowStepSchema}"
1111
- .icon="design:edit"
1112
- has-header
1113
- validate-on-render
1114
- .values="${values}"
1115
- .dirty="${this._currentFlowStep._values != null}"
1116
- ?readonly="${readonlyMode}"
1117
- scrollable
1118
- .groups="${groups}"
1119
- @gv-schema-form:change="${this._onChangeFlowStep}"
1120
- @gv-schema-form:reset="${this._onResetFlowStep}"
1121
- @gv-schema-form:fetch-resources="${this._onFetchResources}"
1122
- @gv-schema-form:submit="${this._onSubmitFlowStep}"
1123
- >
1124
- <div slot="title" class="flow-step__form-title">${this._currentFlowStep.step.name}</div>
1125
- <gv-button
1126
- slot="header-left"
1127
- icon="general:close"
1128
- outlined
1129
- small
1130
- @gv-button:click="${this._onCloseFlowStepForm}"
1131
- title="Close"
1132
- ></gv-button>
1133
- <gv-button
1134
- slot="header-left"
1135
- icon="home:book"
1136
- ?disabled="${this.documentation != null}"
1137
- outlined
1138
- small
1139
- @gv-button:click="${this._onOpenDocumentationFromForm}"
1140
- title="Open documentation"
1141
- ></gv-button>
1142
- </gv-schema-form>
1143
- </div>
1144
- </div>`
1145
- : '',
1146
- )}`;
1147
- }
1148
-
1149
- _onCloseDocumentation() {
1150
- this.documentation = null;
1151
- if (this._currentFlowStep == null) {
1152
- this._maximizeTopView();
1153
- } else {
1154
- localStorage.setItem('gv-policy-studio:keep-documentation-close', true);
1155
- }
1156
- }
1157
-
1158
- _onDeleteFlow({ detail }) {
1159
- const flowId = detail.content._id;
1160
- const { flows } = this._findFlowCollection(flowId);
1161
- const flow = flows.find((flow) => flow._id === flowId);
1162
- this._deleteFlow(flows, flow);
1163
- }
1164
-
1165
- get definedFlows() {
1166
- return this._definition && this._definition.flows ? this._definition.flows : [];
1167
- }
1168
-
1169
- get definedPlans() {
1170
- return this._definition && this._definition.plans ? this._definition.plans : [];
1171
- }
1172
-
1173
- get definedResources() {
1174
- return this._definition && this._definition.resources ? this._definition.resources : [];
1175
- }
1176
-
1177
- get definedProperties() {
1178
- return this._definition && this._definition.properties ? this._definition.properties : [];
1179
- }
1180
-
1181
- async _onDuplicateFlow({ detail }) {
1182
- try {
1183
- await this._askToValidateForms();
1184
-
1185
- const flowId = detail.content._id;
1186
- const { plan, flows } = this._findFlowCollection(flowId);
1187
- this._addFlow(flows, this._findFlowById(flowId));
1188
- if (plan != null) {
1189
- let planIndex = null;
1190
- this.definedPlans.find((p, i) => {
1191
- if (p.id === plan.id) {
1192
- planIndex = i;
1193
- return true;
1194
- }
1195
- return false;
1196
- });
1197
- plan.flows = flows;
1198
- this.definedPlans[planIndex].flows = this._generatePlanFlowsId(plan, true);
1199
- this._updateSelectedFlows([this.definedPlans[planIndex].flows[flows.length - 1]._id]);
1200
- } else {
1201
- this._definition.flows = this._generateFlowsId(this._definition.flows);
1202
- this._updateSelectedFlows([this._definition.flows[this._definition.flows.length - 1]._id]);
1203
- }
1204
- } catch (err) {
1205
- this._currentAskConfirmation = null;
1206
- }
1207
- }
1208
-
1209
- _onChangeFlowState({ detail }) {
1210
- const flow = this._findFlowById(detail.content._id);
1211
- flow.enabled = detail.enabled;
1212
- flow._dirty = true;
1213
- this.isDirty = true;
1214
- }
1215
-
1216
- async _onAddFlowPlan({ detail }) {
1217
- try {
1218
- await this._askToValidateForms();
1219
- this._addFlow(this.definedPlans[detail.planIndex].flows);
1220
- this.definedPlans[detail.planIndex].flows = this._generatePlanFlowsId(this.definedPlans[detail.planIndex]);
1221
- this._updateSelectedFlows([this.definedPlans[detail.planIndex].flows[this.definedPlans[detail.planIndex].flows.length - 1]._id]);
1222
- } catch (err) {
1223
- this._currentAskConfirmation = null;
1224
- }
1225
- }
1226
-
1227
- async _onAddFlow() {
1228
- try {
1229
- await this._askToValidateForms();
1230
-
1231
- this._addFlow(this._definition.flows);
1232
- this._definition.flows = this._generateFlowsId(this._definition.flows);
1233
- this._updateSelectedFlows([this._definition.flows[this._definition.flows.length - 1]._id]);
1234
- } catch (err) {
1235
- this._currentAskConfirmation = null;
1236
- }
1237
- }
1238
-
1239
- _addFlow(collection, duplicate = null) {
1240
- const flow =
1241
- duplicate == null
1242
- ? this._createFlowFromSchema()
1243
- : {
1244
- ...duplicate,
1245
- _id: null,
1246
- // reset the id to avoid issue with AM that persists the ID
1247
- id: null,
1248
- _dirty: true,
1249
- };
1250
-
1251
- collection.push(flow);
1252
- this.isDirty = true;
1253
- return collection;
1254
- }
1255
-
1256
- _createFlowFromSchema() {
1257
- const newFlow = {
1258
- name: '',
1259
- pre: [],
1260
- post: [],
1261
- _dirty: true,
1262
- };
1263
-
1264
- return this._instantiate(this.flowSchema.properties, newFlow);
1265
- }
1266
-
1267
- _instantiate(propertiesDefinition, initiator = {}) {
1268
- const property = { ...initiator };
1269
-
1270
- if (propertiesDefinition) {
1271
- for (const key of Object.keys(propertiesDefinition)) {
1272
- const entry = propertiesDefinition[key];
1273
-
1274
- if (entry.type === 'object') {
1275
- property[key] = this._instantiate(entry.properties, (initiator = {}));
1276
- }
1277
- if (entry.default !== undefined) {
1278
- property[key] = entry.default;
1279
- } else if (entry.type === 'string') {
1280
- property[key] = '';
1281
- }
1282
- }
1283
- }
1284
-
1285
- return property;
1286
- }
1287
-
1288
- _deleteFlow(collection, flow) {
1289
- const index = collection.indexOf(flow);
1290
- collection.splice(index, 1);
1291
- const selectedFlows = this.selectedFlowsId.filter((flowId) => flowId !== flow._id);
1292
- if (selectedFlows.length === 1) {
1293
- this._updateSelectedFlows(selectedFlows);
1294
- } else {
1295
- this._selectFirstFlow(true);
1296
- }
1297
- this._changeTab('design');
1298
- this._refresh();
1299
- this.isDirty = true;
1300
- }
1301
-
1302
- _findFlowIndex(list, id) {
1303
- let index = null;
1304
- list.find((f, i) => {
1305
- if (f._id === id) {
1306
- index = i;
1307
- return true;
1308
- }
1309
- return false;
1310
- });
1311
- return index;
1312
- }
1313
-
1314
- async _onReorderFlows({ detail: { plan } }) {
1315
- try {
1316
- await this._askToValidateForms();
1317
- this.isDirty = true;
1318
- if (plan != null) {
1319
- const newOrder = this._generatePlanFlowsId(plan, true);
1320
- if (this.selectedFlowsId) {
1321
- this._updateSelectedFlows(
1322
- this.selectedFlowsId.map((flowId) => {
1323
- const index = this._findFlowIndex(plan.flows, flowId);
1324
- return index != null ? newOrder[index]._id : flowId;
1325
- }),
1326
- );
1327
- }
1328
- plan.flows = newOrder;
1329
- } else {
1330
- const newOrder = this._generateFlowsId(this._definition.flows, true);
1331
- if (this.selectedFlowsId) {
1332
- this._updateSelectedFlows(
1333
- this.selectedFlowsId.map((flowId) => {
1334
- const index = this._findFlowIndex(this._definition.flows, flowId);
1335
- return index != null ? newOrder[index]._id : flowId;
1336
- }),
1337
- );
1338
- }
1339
- this._definition.flows = newOrder;
1340
- }
1341
- } catch (err) {
1342
- this._currentAskConfirmation = false;
1343
- }
1344
- }
1345
-
1346
- _onSearchPolicy({ detail }) {
1347
- this._searchPolicyQuery = detail;
1348
- }
1349
-
1350
- _onClearPolicy() {
1351
- this._searchPolicyQuery = null;
1352
- }
1353
-
1354
- _onSearchFlows({ detail }) {
1355
- this._searchFlowQuery = detail;
1356
- }
1357
-
1358
- _onClearFlows() {
1359
- this._searchFlowQuery = null;
1360
- }
1361
-
1362
- async _onResetAll() {
1363
- try {
1364
- await this._closeFlowStepForm();
1365
- this.definition = deepClone(this._initialDefinition);
1366
- } catch (e) {
1367
- this._currentAskConfirmation = null;
1368
- }
1369
- }
1370
-
1371
- _filterNotValidStep(step) {
1372
- return step._new !== true;
1373
- }
1374
-
1375
- _removePrivateProperties(o) {
1376
- const copy = { ...o };
1377
- Object.keys(o)
1378
- .filter((key) => key.startsWith('_'))
1379
- .forEach((key) => {
1380
- delete copy[key];
1381
- });
1382
- return copy;
1383
- }
1384
-
1385
- _submitOrConfirmForms() {
1386
- return [...this.shadowRoot.querySelectorAll('gv-schema-form')]
1387
- .filter((form) => {
1388
- const isValid = form.isValid();
1389
- if (isValid) {
1390
- form.submit();
1391
- } else {
1392
- form.dirty = true;
1393
- }
1394
- return !isValid;
1395
- })
1396
- .map((form) => form.confirm());
1397
- }
1398
-
1399
- getPropertiesElement() {
1400
- return this.shadowRoot.querySelector('gv-properties');
1401
- }
1402
-
1403
- async _checkCurrentFlowStep() {
1404
- if (this._currentFlowStep && this.selectedFlowsId) {
1405
- const closePromises = this.selectedFlowsId
1406
- .map((flowId) => {
1407
- const flow = this._findFlowById(flowId);
1408
- const currentStep = [...flow.pre, ...flow.post].find((step) => step._id === this._currentFlowStep.step._id);
1409
- if (currentStep == null) {
1410
- return this._closeFlowStepForm(true);
1411
- }
1412
- return null;
1413
- })
1414
- .filter((p) => p !== null);
1415
- return Promise.all(closePromises);
1416
- }
1417
- return Promise.resolve();
1418
- }
1419
-
1420
- saved() {
1421
- if (this.isDirty) {
1422
- this._initialDefinition = deepClone(this._definitionSaved);
1423
- this._definition = deepClone(this._definitionSaved);
1424
- this._definitionSaved = null;
1425
- this.isDirty = false;
1426
- this._checkCurrentFlowStep();
1427
- this.definedPlans.forEach((plan) => {
1428
- plan.flows.forEach((flow) => (flow._dirty = false));
1429
- });
1430
- this.definedFlows.forEach((flow) => (flow._dirty = false));
1431
- this.getChildren().forEach((e) => e.requestUpdate());
1432
- }
1433
- }
1434
-
1435
- _buildDefinitionToSave() {
1436
- // Copy definition and remove invalid step
1437
- // Keep private properties like _id and others stuff useful for render
1438
- const flows = this._definition.flows.map((flow) => {
1439
- flow.pre = flow.pre.filter(this._filterNotValidStep);
1440
- flow.post = flow.post.filter(this._filterNotValidStep);
1441
- return flow;
1442
- });
1443
-
1444
- let definition = { ...this._definition, flows };
1445
-
1446
- if (this._definition.plans != null) {
1447
- const plans = this._definition.plans.map((plan) => {
1448
- const flows = plan.flows.map((flow) => {
1449
- flow.pre = flow.pre.filter(this._filterNotValidStep);
1450
- flow.post = flow.post.filter(this._filterNotValidStep);
1451
- return flow;
1452
- });
1453
- return { ...plan, flows };
1454
- });
1455
- definition = { ...definition, plans };
1456
- }
1457
- return definition;
1458
- }
1459
-
1460
- _buildDefinitionToSend(definitionToSave) {
1461
- // Copy definition and remove all private properties
1462
- const flows = definitionToSave.flows.map((f) => {
1463
- const flow = this._removePrivateProperties(f);
1464
- flow.pre = flow.pre.map(this._removePrivateProperties);
1465
- flow.post = flow.post.map(this._removePrivateProperties);
1466
- return flow;
1467
- });
1468
-
1469
- let definition = { ...this._definition, flows };
1470
- if (this._definition.plans != null) {
1471
- const plans = definitionToSave.plans.map((plan) => {
1472
- const flows = plan.flows.map((f) => {
1473
- const flow = this._removePrivateProperties(f);
1474
- flow.pre = flow.pre.map(this._removePrivateProperties);
1475
- flow.post = flow.post.map(this._removePrivateProperties);
1476
- return flow;
1477
- });
1478
- return { ...plan, flows };
1479
- });
1480
- definition = { ...definition, plans };
1481
- }
1482
-
1483
- if (this._definition.properties != null) {
1484
- const properties = this._definition.properties.map(this._removePrivateProperties);
1485
- definition = { ...definition, properties };
1486
- }
1487
-
1488
- if (this._definition.resources != null) {
1489
- const resources = this._definition.resources.map(this._removePrivateProperties);
1490
- definition = { ...definition, resources };
1491
- }
1492
-
1493
- return definition;
1494
- }
1495
-
1496
- _onSaveAll() {
1497
- if (this.hasProperties) {
1498
- this.getPropertiesElement().submit();
1499
- }
1500
-
1501
- Promise.all(this._submitOrConfirmForms())
1502
- .then(() => {
1503
- this._definitionSaved = this._buildDefinitionToSave();
1504
- const definition = this._buildDefinitionToSend(this._definitionSaved);
1505
- dispatchCustomEvent(this, 'save', { definition, services: this.services });
1506
- })
1507
- .catch((err) => {
1508
- console.error(`[policy-studio] Error on save`, err);
1509
- });
1510
- }
1511
-
1512
- _onDebug(requestEvent) {
1513
- if (this.hasProperties) {
1514
- this.getPropertiesElement().submit();
1515
- }
1516
-
1517
- Promise.all(this._submitOrConfirmForms())
1518
- .then(() => {
1519
- const definition = this._buildDefinitionToSend(this._buildDefinitionToSave());
1520
- dispatchCustomEvent(this, 'debug', { definition, services: this.services, request: requestEvent.detail.request });
1521
- })
1522
- .catch((err) => {
1523
- console.error(`[policy-studio] Error on debug`, err);
1524
- });
1525
- }
1526
-
1527
- get filteredFlows() {
1528
- if (this._flowFilter.length === 0 || this._flowFilter.includes('api')) {
1529
- return this.definedFlows;
1530
- }
1531
- return null;
1532
- }
1533
-
1534
- get filteredPlans() {
1535
- if (this._flowFilter.length === 0 || this._flowFilter.includes('plan')) {
1536
- return this.definedPlans;
1537
- }
1538
- return null;
1539
- }
1540
-
1541
- _onFilterFlows({ detail }) {
1542
- if (this._flowFilter.includes(detail.id)) {
1543
- this._flowFilter = [];
1544
- } else {
1545
- this._flowFilter = [detail.id];
1546
- }
1547
- }
1548
-
1549
- _getFilteredPolicies() {
1550
- if (this._policyFilter.length > 0) {
1551
- return this.policies.filter((policy) => {
1552
- return (
1553
- (policy.onRequest && this._policyFilter.includes('onRequest')) || (policy.onResponse && this._policyFilter.includes('onResponse'))
1554
- );
1555
- });
1556
- }
1557
- return this.policies;
1558
- }
1559
-
1560
- _onFilterPolicies({ detail }) {
1561
- if (this._policyFilter.includes(detail.id)) {
1562
- this._policyFilter = [];
1563
- } else {
1564
- this._policyFilter = [detail.id];
1565
- }
1566
- }
1567
-
1568
- _renderDesign(readonlyMode) {
1569
- return html` <div id="design" slot="content" class="design">
1570
- <gv-resizable-views no-overflow>
1571
- <div slot="top">${this._renderFlow(0, true, readonlyMode)}</div>
1572
-
1573
- <div slot="bottom">
1574
- ${this._renderFlow(1, false, readonlyMode)} ${this._renderPolicy(readonlyMode)} ${this._renderFlowForm(readonlyMode)}
1575
- </div>
1576
- </gv-resizable-views>
1577
- ${readonlyMode !== true
1578
- ? html`<gv-policy-studio-menu
1579
- class="right-menu"
1580
- ?disabled="${this._currentAskConfirmation}"
1581
- .policies="${this._getFilteredPolicies()}"
1582
- .selectedIds="${[this._currentPolicyId]}"
1583
- .query="${this._searchPolicyQuery}"
1584
- ?has-policy-filter="${this._policyFilterOptions != null}"
1585
- ?readonly="${readonlyMode}"
1586
- @gv-policy-studio-menu:target-policy="${this._onTargetPolicy}"
1587
- @gv-policy-studio-menu:fetch-documentation="${this._onOpenDocumentationFromMenu}"
1588
- @gv-policy-studio-menu:dragend-policy="${this._onDragEndPolicy}"
1589
- >
1590
- <div slot="header" class="search-policies">
1591
- ${this._policyFilterOptions != null
1592
- ? html`<gv-option
1593
- ?disabled="${this._currentAskConfirmation}"
1594
- .options="${this._policyFilterOptions}"
1595
- multiple
1596
- outlined
1597
- .value="${this._policyFilter}"
1598
- small
1599
- @gv-option:select="${this._onFilterPolicies}"
1600
- ></gv-option>`
1601
- : ''}
1602
- <gv-input
1603
- id="search-policy"
1604
- ?disabled="${this._currentAskConfirmation}"
1605
- placeholder="Filter policies (Shift + Ctrl + Space)"
1606
- type="search"
1607
- small
1608
- @gv-input:input="${this._onSearchPolicy}"
1609
- @gv-input:clear="${this._onClearPolicy}"
1610
- ></gv-input>
1611
- </div>
1612
- </gv-policy-studio-menu>`
1613
- : ''}
1614
- </div>`;
1615
- }
1616
-
1617
- _renderDebug() {
1618
- const response = this.debugResponse ? this.debugResponse.response : undefined;
1619
- const isLoading = this.debugResponse ? this.debugResponse.isLoading : undefined;
1620
- const path = this.debugResponse && this.debugResponse.request ? this.debugResponse.request.path : undefined;
1621
- const method = this.debugResponse && this.debugResponse.request ? this.debugResponse.request.method : undefined;
1622
- return html`<gv-http-client
1623
- id="debug"
1624
- slot="content"
1625
- class="debug"
1626
- @gv-http-client:send="${this._onDebug}"
1627
- .response="${response}"
1628
- .path="${path}"
1629
- .method="${method}"
1630
- ?loading="${isLoading}"
1631
- >
1632
- </gv-http-client>`;
1633
- }
1634
-
1635
- _renderConfigurationForm(readonlyMode) {
1636
- if (this.configurationSchema) {
1637
- const values = deepClone(this._definition);
1638
- return html` <div id="settings" slot="content" class="api-settings" @dragover="${this._onDesign}">
1639
- <gv-schema-form
1640
- .schema="${this.configurationSchema}"
1641
- id="api-settings-form"
1642
- .values="${values}"
1643
- has-header
1644
- has-footer
1645
- scrollable
1646
- ?readonly="${readonlyMode}"
1647
- @gv-schema-form:cancel="${this._onCancelFlowMode}"
1648
- @gv-schema-form:submit="${this._onSubmitFlowMode}"
1649
- >
1650
- ${!this.configurationInformation
1651
- ? ''
1652
- : html`
1653
- <div class="api-settings-information" slot="title">
1654
- <gv-icon class="api-settings-information__icon" title="Info" shape="code:info"></gv-icon>
1655
- <blockquote class="api-settings-information__blockquote">${this.configurationInformation}</blockquote>
1656
- </div>
1657
- `}
1658
- </gv-schema-form>
1659
- </div>`;
1660
- }
1661
- return html``;
1662
- }
1663
-
1664
- _renderFlowForm(readonlyMode) {
1665
- if (this.flowSchema && this._flowStepSchema == null && this.documentation == null && this.selectedFlowsId.length === 1) {
1666
- const flow = this.getSelectedFlow();
1667
- if (flow) {
1668
- const values = deepClone(flow);
1669
- return html`<div slot="content" class="flow-settings">
1670
- <gv-schema-form
1671
- .schema="${this.flowSchema}"
1672
- id="settings-form"
1673
- .values="${values}"
1674
- has-header
1675
- scrollable
1676
- ?readonly="${readonlyMode}"
1677
- @gv-schema-form:cancel="${this._onCancelFlow}"
1678
- @gv-schema-form:submit="${this._onSubmitFlow}"
1679
- >
1680
- <div slot="title" class="flow-step__form-title">Flow configuration</div>
1681
- </gv-schema-form>
1682
- </div>`;
1683
- }
1684
- }
1685
- }
1686
-
1687
- _onResourcesChange({ detail }) {
1688
- this.definition.resources = detail.resources;
1689
- this.isDirty = true;
1690
- }
1691
-
1692
- _onPropertiesChange({ detail }) {
1693
- this.definition.properties = detail.properties;
1694
- this.isDirty = true;
1695
- }
1696
-
1697
- _onSaveProvider({ detail }) {
1698
- this.services['dynamic-property'] = detail.provider;
1699
- this.isDirty = true;
1700
- }
1701
-
1702
- _onSwitchEncryptedProperty({ detail }) {
1703
- this.isDirty = true;
1704
- }
1705
-
1706
- render() {
1707
- const readonlyMode = this._getReadonlyModeForDesign();
1708
-
1709
- return html`<div class="box">
1710
- <gv-policy-studio-menu
1711
- class="left-menu"
1712
- .api-name="${this._definition.name}"
1713
- .flows="${this.filteredFlows}"
1714
- .plans="${this.filteredPlans}"
1715
- .selectedIds="${this.selectedFlowsId}"
1716
- ?disabled="${this._currentAskConfirmation}"
1717
- ?sortable="${this.sortable && this.readonly !== true}"
1718
- ?readonly="${this.readonly}"
1719
- ?readonlyPlans="${this.readonlyPlans}"
1720
- flows-title="${this.flowsTitle}"
1721
- .query="${this._searchFlowQuery}"
1722
- ?can-add="${this.canAdd && !this.readonly}"
1723
- @gv-policy-studio-menu:reorder-flows="${this._onReorderFlows}"
1724
- @gv-policy-studio-menu:change-flow-state="${this._onChangeFlowState}"
1725
- @gv-policy-studio-menu:add-flow="${this._onAddFlow}"
1726
- @gv-policy-studio-menu:add-flow-plan="${this._onAddFlowPlan}"
1727
- @gv-policy-studio-menu:delete-flow="${this._onDeleteFlow}"
1728
- @gv-policy-studio-menu:duplicate-flow="${this._onDuplicateFlow}"
1729
- @gv-policy-studio-menu:select-flows="${this._onSelectFlows}"
1730
- >
1731
- <div slot="header" class="header-actions">
1732
- <div class="title">${this._definition.name}</div>
1733
- ${this._flowFilterOptions != null
1734
- ? html`<gv-option
1735
- ?disabled="${this._currentAskConfirmation}"
1736
- .options="${this._flowFilterOptions}"
1737
- multiple
1738
- outlined
1739
- .value="${this._flowFilter}"
1740
- small
1741
- @gv-option:select="${this._onFilterFlows}"
1742
- ></gv-option>`
1743
- : ''}
1744
- <gv-input
1745
- ?disabled="${this._currentAskConfirmation}"
1746
- id="search-flow"
1747
- placeholder="Filter flows (Ctrl + Space)"
1748
- type="search"
1749
- small
1750
- @gv-input:input="${this._onSearchFlows}"
1751
- @gv-input:clear="${this._onClearFlows}"
1752
- ></gv-input>
1753
- </div>
1754
-
1755
- ${this.readonly !== true
1756
- ? html` <div slot="footer" class="footer-actions">
1757
- <gv-button
1758
- class="btn-large"
1759
- .disabled="${!this.isDirty || this._currentAskConfirmation}"
1760
- @gv-button:click="${this._onSaveAll}"
1761
- >Save</gv-button
1762
- >
1763
- <gv-button link .disabled="${!this.isDirty || this._currentAskConfirmation}" @gv-button:click="${this._onResetAll}"
1764
- >Reset</gv-button
1765
- >
1766
- </div>`
1767
- : ''}
1768
- </gv-policy-studio-menu>
1769
-
1770
- <gv-tabs
1771
- .value="${this.tabId}"
1772
- .options="${this._tabs}"
1773
- .disabled="${this._currentAskConfirmation}"
1774
- @gv-tabs:change="${this._onChangeTab}"
1775
- .validator="${this._changeTabValidator.bind(this)}"
1776
- >
1777
- ${this._renderDesign(readonlyMode)} ${this._renderConfigurationForm(readonlyMode)} ${this._renderDebug()}
1778
- <gv-properties
1779
- id="properties"
1780
- slot="content"
1781
- class="properties"
1782
- .provider="${this.services['dynamic-property']}"
1783
- @gv-properties:change="${this._onPropertiesChange}"
1784
- @gv-properties:save-provider="${this._onSaveProvider}"
1785
- @gv-properties:switch-encrypted="${this._onSwitchEncryptedProperty}"
1786
- ?readonly="${readonlyMode}"
1787
- encryptable="true"
1788
- .properties="${this.definedProperties}"
1789
- .providers="${this.propertyProviders}"
1790
- .dynamicPropertySchema="${this.dynamicPropertySchema}"
1791
- ></gv-properties>
1792
- <gv-resources
1793
- id="resources"
1794
- slot="content"
1795
- class="resources"
1796
- @gv-resources:change="${this._onResourcesChange}"
1797
- ?readonly="${readonlyMode}"
1798
- .resources="${this.definedResources}"
1799
- .types="${this.resourceTypes}"
1800
- ></gv-resources>
1801
- </gv-tabs>
1802
- </div>`;
1803
- }
1804
-
1805
- /**
1806
- * Determine if the design view should be in readonly mode or not
1807
- * It is in readonly mode if:
1808
- * the readonly attribute is set to true
1809
- * OR
1810
- * the main selected flow belongs to a plan and the readonly-plans attribute is set to true
1811
- * OR
1812
- * the second flow for comparison belongs to a plan and the readonly-plans attribute is set to true
1813
- * @returns {boolean|*|{type: BooleanConstructor}|{attribute: string, type: BooleanConstructor}|{type: *}|{attribute: string, type: *}}
1814
- * @private
1815
- */
1816
- _getReadonlyModeForDesign() {
1817
- if (this.readonly) {
1818
- return true;
1819
- }
1820
-
1821
- const flow = this.getSelectedFlow(0);
1822
- if (!flow) {
1823
- return false;
1824
- }
1825
-
1826
- const { plan: flowPlan } = this._findFlowCollection(flow._id);
1827
- const readonlyMode = flowPlan && this.readonlyPlans;
1828
- if (readonlyMode) {
1829
- return true;
1830
- }
1831
-
1832
- const comparedFlow = this.getSelectedFlow(1);
1833
- if (!comparedFlow) {
1834
- return false;
1835
- }
1836
-
1837
- const { plan: comparedFlowPlan } = this._findFlowCollection(comparedFlow._id);
1838
- return comparedFlowPlan && this.readonlyPlans;
1839
- }
1840
- }
1841
-
1842
- window.customElements.define('gv-policy-studio', GvPolicyStudio);
1
+ var e=Object.create?function(e,t,i,o){void 0===o&&(o=i),Object.defineProperty(e,o,{enumerable:!0,get:function(){return t[i]}})}:function(e,t,i,o){void 0===o&&(o=i),e[o]=t[i]},t=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t},i=function(i){if(i&&i.__esModule)return i;var o={};if(null!=i)for(var s in i)"default"!==s&&Object.prototype.hasOwnProperty.call(i,s)&&e(o,i,s);return t(o,i),o};Object.defineProperty(exports,"__esModule",{value:!0}),exports.GvPolicyStudio=void 0;const o=require("lit"),s=require("../lib/studio"),n=require("../lib/events"),r=require("../lib/i18n");require("../atoms/gv-button"),require("../atoms/gv-icon"),require("../molecules/gv-option"),require("../organisms/gv-documentation"),require("../organisms/gv-resizable-views"),require("../organisms/gv-schema-form"),require("../organisms/gv-http-client"),require("../organisms/gv-tabs"),require("../molecules/gv-row"),require("./gv-flow"),require("./gv-flow-step"),require("./gv-policy-studio-menu");const l=require("../styles/empty"),a=require("lit/directives/cache"),d=require("../lib/utils"),c=require("../mixins/keyboard-element");class h extends((0,c.KeyboardElement)(o.LitElement)){static get properties(){return{policies:{type:Array},services:{type:Object},resourceTypes:{type:Array,attribute:"resource-types"},propertyProviders:{type:Array,attribute:"property-providers"},dynamicPropertySchema:{type:Object,attribute:"dynamic-property-schema"},tabId:{type:String,attribute:"tab-id"},_tabId:{type:String,attribute:!1},definition:{type:Object},_definition:{type:Object,attribute:!1},documentation:{type:Object},flowSchema:{type:Object,attribute:"flow-schema"},configurationSchema:{type:Object,attribute:"configuration-schema"},_configurationSchema:{type:Object,attribute:!1},configurationInformation:{type:String,attribute:"configuration-information"},isDirty:{type:Boolean,attribute:"dirty",reflect:!0},_dragPolicy:{type:Object,attribute:!1},_dropPolicy:{type:Object,attribute:!1},selectedFlowsId:{type:Array,attribute:"selected-flows-id"},_selectedFlowsId:{type:Array,attribute:!1},_currentPolicyId:{type:String,attribute:!1},_searchPolicyQuery:{type:String,attribute:!1},_searchFlowQuery:{type:String,attribute:!1},_flowStepSchema:{type:Object,attribute:!1},_currentFlowStep:{type:Object,attribute:!1},_policyFilter:{type:Array,attribute:!1},_flowFilter:{type:Array,attribute:!1},_currentAskConfirmation:{type:Boolean,attribute:!1},hasProperties:{type:Boolean,attribute:"has-properties"},_hasProperties:{type:Boolean,attribute:!1},hasResources:{type:Boolean,attribute:"has-resources"},hasPolicyFilter:{type:Boolean,attribute:"has-policy-filter"},flowsTitle:{type:String,attribute:"flows-title"},sortable:{type:Boolean},canAdd:{type:Boolean,attribute:"can-add"},readonly:{type:Boolean},readonlyPlans:{type:Boolean,attribute:"readonly-plans"},canDebug:{type:Boolean,attribute:"can-debug"},_canDebug:{type:Boolean,attribute:!1},debugResponse:{type:Object,attribute:"debug-response"},hasConditionalSteps:{type:Boolean,attribute:"has-conditional-steps"}}}static get styles(){return[l.empty,s.methods,o.css`:host{box-sizing:border-box;--height:var(--gv-policy-studio--h, calc(100vh - 32px));height:var(--height);--height-in-tabs:calc(var(--height) - 25px)}.box{height:var(--height);display:flex}.design,.properties{display:flex}gv-resizable-views{width:100%}.editable-name{padding:.5rem 1rem;font-size:16px}.editable-name span{color:#bfbfbf;font-size:12px}.form__control{margin:.5rem}gv-input{width:100%}.flow-name{display:flex;align-items:center}.flow-name.dirty{font-style:italic;opacity:.8}.flow-name gv-icon{--gv-icon--s:24px;margin-right:.2rem}.flow-path{margin-left:.2rem}.title_methods{margin-left:.5rem}.two-cols{display:flex;width:100%;height:100%}.two-cols>*{flex:1}.left-menu{border-left:1px solid #d9d9d9;height:var(--height-in-tabs)}.right-menu{border-right:1px solid #d9d9d9;height:var(--height-in-tabs)}.two-cols>:first-child{border-right:1px solid #d9d9d9}.flow-step__container{overflow:hidden;position:relative;overflow:hidden;height:99%}.flow-step__form{padding:0 .5rem;overflow:auto}.flow-step__form-title{text-transform:uppercase;letter-spacing:.2rem}gv-tabs{width:100%;height:100%;display:inline-block}gv-properties,gv-resizable-views,gv-resources{height:var(--height-in-tabs)}gv-properties,gv-resources{width:100%}gv-properties.properties{--gv-properties-table--colmg:10px}.api-settings{display:flex;flex-direction:column;border-left:1px solid #bfbfbf;height:var(--height-in-tabs)}.debug{display:flex;flex-direction:column;border-left:1px solid #bfbfbf;height:var(--height-in-tabs)}.api-settings-information{display:flex;align-items:center}.api-settings-information__icon{--gv-icon--c:var(--gv-theme-color, #5a7684);--gv-icon-opacity--c:var(--gv-theme-color-info-light, #64b5f6)}.api-settings-information__blockquote,.debug-information__blockquote{border-left:1px solid var(--gv-theme-color,#5a7684);margin:15px;padding-left:15px;font-size:14px}.flow-settings gv-schema-form{flex:1;padding:.5rem}.search{display:flex;justify-content:stretch}gv-input{margin:.2rem 0;width:100%}.header-actions,.search-policies{display:flex;flex-direction:column;align-items:center;margin:.5rem}.search-policies{margin:1.5rem .5rem .5rem}.footer-actions>gv-button.btn-large,.footer-actions>gv-option{width:100%}.footer-actions{display:flex;flex-direction:column;align-items:center;padding:.5rem 0;margin:.5rem 15px;border-top:1px solid #bfbfbf}.header-actions .title{text-transform:uppercase;text-align:center;letter-spacing:.3rem;color:#bfbfbf;font-size:18px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:240px;min-height:25px}.header-actions>*,.search-policies>*{margin-bottom:1rem}`]}constructor(){super(),this.isDirty=!1,this.policies=[],this.resourceTypes=[],this.tabId="design",this.selectedFlowsId=[],this.flowsTitle="Flows",this.sortable=!1,this.services={},this._definition={flows:[]},this._tabs=[{id:"design",title:"Design",icon:"navigation:exchange"}],this._policyFilter=[],this._flowFilter=[]}set hasProperties(e){e&&Promise.resolve().then((()=>i(require("../organisms/gv-properties")))).then((()=>{this._tabs=[...this._tabs,{id:"properties",title:"Properties",icon:"general:settings#1"}],this.requestUpdate()})),this._hasProperties=e}get hasProperties(){return this._hasProperties}set hasResources(e){e&&Promise.resolve().then((()=>i(require("../organisms/gv-resources")))).then((()=>{this._tabs=[...this._tabs,{id:"resources",title:"Resources",icon:"general:settings#5"}],this.requestUpdate()}))}set canDebug(e){e&&(this._tabs=[...this._tabs,{id:"debug",title:"Try it",icon:"content:send"}])}get _flowFilterOptions(){if(this.definedPlans.length>0)return[{id:"api",title:"Api",icon:"shopping:box#3"},{id:"plan",title:"Plans",icon:"shopping:sale#2"}]}set hasPolicyFilter(e){e&&(this._policyFilterOptions=[{id:"onRequest",title:"Request",icon:"navigation:arrow-from-left"},{id:"onResponse",title:"Response",icon:"navigation:arrow-from-right"}])}set configurationSchema(e){e&&this._tabs.splice(1,0,{id:"settings",title:"Configuration",icon:"general:settings#2"}),this._configurationSchema=e}get configurationSchema(){return this._configurationSchema}onKeyboard(){if(null==this._currentAskConfirmation)if(this.isPressed(c.KEYS.Shift,c.KEYS.Ctrl,c.KEYS.Space)){const e=this.shadowRoot.querySelector("#search-policy");e&&e.focus()}else if(this.isPressed(c.KEYS.Ctrl,c.KEYS.Space)){const e=this.shadowRoot.querySelector("#search-flow");e&&e.focus()}}set tabId(e){null!=e&&["design","settings","properties","resources","debug"].includes(e)?this._tabId=e:this._tabId="design"}get tabId(){return this._tabId}set definition(e){if(e){const t=this._generateFlowsId(e.flows),i=this._generateId("resource-",e.resources),o=null==e.plans?[]:e.plans.map((e=>({...e,flows:this._generatePlanFlowsId(e)})));this._initialDefinition={...e,flows:t,resources:i,plans:o},this._definition=(0,d.deepClone)(this._initialDefinition),this.isDirty=!1,this._selectFirstFlow()}}get definition(){return this._definition}set selectedFlowsId(e){null!=e&&Array.isArray(e)&&(this._selectedFlowsId=e.filter((e=>null!=this._findFlowById(e))),e.length!==this._selectedFlowsId.length&&this._selectFirstFlow(!0))}get selectedFlowsId(){return this._selectedFlowsId.filter((e=>null!=this._findFlowById(e)))}_updateSelectedFlows(e){this.selectedFlowsId=e,(0,n.dispatchCustomEvent)(this,"select-flows",{flows:this.selectedFlowsId})}_selectFirstFlow(e=!1){if(0===this.selectedFlowsId.length){let t=null;if(this.definedFlows.length>0&&null!=this.definedFlows[0]._id)t=this.definedFlows[0];else if(this.definedPlans.length>0){const e=this.definedPlans.find((e=>null!=e.flows&&e.flows.length>0&&null!=e.flows[0]._id));e&&(t=e.flows[0])}null!=t&&(e?this._updateSelectedFlows([t._id]):this.selectedFlowsId=[t._id])}}_getFlowElement(e){return this.shadowRoot.querySelector(`[id="${e}"]`)}_onDragEndPolicy(){this.shadowRoot.querySelectorAll("gv-flow").forEach((e=>e.onDragEnd()))}async _onDropPolicy({detail:e}){try{await this._askToValidateForms();const t=e.policy,i=this._findFlowById(e.flowId);let o,s=t.name,n="",r="",l={},a=!1;e.flowStep?(o=e.flowStep._id,s=e.flowStep.name,n=e.flowStep.description||"",r=e.flowStep.condition||"",l=e.flowStep.configuration):(o=this._generateFlowStepId(i._id,e.flowKey,e.position),a=!0);const d={_id:o,_new:a,name:s,policy:t.id,description:n,condition:r,enabled:!0,configuration:l},c=null!=e.sourceFlowId?this._findFlowById(e.sourceFlowId):i;if(null!=e.sourcePosition){if(e.sourceFlowKey&&e.sourceFlowKey!==e.flowKey){if(c[e.sourceFlowKey].splice(e.sourcePosition,1),i[e.flowKey].splice(e.position,0,d),null!=this._currentFlowStep&&this._currentFlowStep.step._id===o){this._currentFlowStep.group=e.flowKey;const t=this.buildSchema(this._currentFlowStep.policy);await this._setCurrentFlowStep(this._currentFlowStep,t,!0),this._getFlowElement(i._id).requestUpdate()}}else e.position>e.sourcePosition?(i[e.flowKey].splice(e.position,0,d),c[e.flowKey].splice(e.sourcePosition,1)):(c[e.flowKey].splice(e.sourcePosition,1),i[e.flowKey].splice(e.position,0,d));i._id!==c._id&&this._getFlowElement(i._id).requestUpdate()}else{i[e.flowKey].splice(e.position,0,d);const o=this._getFlowStepForm();if(null==o||!0!==o.dirty){let o=i[e.flowKey][e.position];null==o&&(o=i[e.flowKey][e.position-1]),!0!==e.cancelEdit&&setTimeout((async()=>{await this._editFlowStep({step:o,policy:t,flow:i,group:e.flowKey}),this.updateComplete.then((()=>{const e=this._getFlowElement(i._id);e.selectedStepId=o._id,e.requestUpdate()}))}))}}i._dirty=!0,c._dirty=!0,this.isDirty=!0,this.shadowRoot.querySelectorAll("gv-flow").forEach((e=>e.removeCandidate())),setTimeout((()=>{this._dragPolicy=null,this._dropPolicy=null}),0)}catch(e){this._currentAskConfirmation=null}}_onDeletePolicy({detail:e}){const t=this._findFlowById(e.flowId);t[e.flowKey].splice(e.position,1),t._dirty=!0,this.isDirty=!0,e.target.editing&&this._closeFlowStepForm(!0),this._getFlowElement(e.flowId).requestUpdate()}_onDesign(){this._changeTab("design"),this._splitMainViews()}buildSchema({schema:e}){const t={title:"Description",description:"Description of flow step",type:"string"},i={title:"Condition",description:"Condition the execution of the flow step (support EL)",type:"string","x-schema-form":{"expression-language":!0}};if(e){const o="string"==typeof e?JSON.parse(e):e,s={commonDescription:t,...this.hasConditionalSteps?{commonCondition:i}:{},...o.properties};return{...o,properties:s}}return{properties:{commonDescription:t,...this.hasConditionalSteps?{commonCondition:i}:{}}}}async _editFlowStep({step:e,flow:t,policy:i,group:o}){if(e){this._currentPolicyId=i.id;const s={flow:t,step:e,policy:i,group:o},n=this.buildSchema(i);try{await this._setCurrentFlowStep(s,n),this._updateSelectedFlows([t._id]),this._splitMainViews(),null==localStorage.getItem("gv-policy-studio:keep-documentation-close")&&this._onOpenDocumentation()}catch(e){this._currentAskConfirmation=null}}else await this._closeFlowStepForm(),this._maximizeTopView()}async _onEditFlowStep({detail:{step:e,flow:t,policy:i,group:o}}){return this._editFlowStep({step:e,flow:t,policy:i,group:o})}_getResizableViews(){return this.shadowRoot.querySelector("gv-resizable-views")}_maximizeTopView(){this.selectedFlowsId.length<=1&&this._getResizableViews().maximizeTop()}_maximizeBottomView(){this._getResizableViews().maximizeBottom()}_splitMainViews(){this._getResizableViews().split()}_onChangeFlowStepState({detail:e}){const t=this._findFlowById(e.flowId);t[e.flowKey][e.position].enabled=e.enabled,t._dirty=!0,this.isDirty=!0}async _onCloseFlowStepForm(){try{await this._closeFlowStepForm()}catch(e){this._currentAskConfirmation=null}}async _closeFlowStepForm(e=!1){await this._setCurrentFlowStep(null,null,e)}async _askToValidateForms(){if(null==this._currentAskConfirmation)return this._currentAskConfirmation=!0,Promise.all(this._submitOrConfirmForms()).then((e=>e.filter((e=>null!=e)).length>0?(this._definition=this._buildDefinitionToSave(),this.getChildren().forEach((e=>e.requestUpdate())),this._checkCurrentFlowStep().then((()=>(this.getChildren().forEach((e=>e.requestUpdate())),this.updateComplete.then((()=>(this._currentAskConfirmation=null,e))))))):(this._currentAskConfirmation=null,e)));throw new Error("ask already waiting")}async _setCurrentFlowStep(e,t,i=!1){i||await this._askToValidateForms();const o=(0,d.deepClone)(t);if(null!=e){const i="string"==typeof e.step.configuration?JSON.parse(e.step.configuration):e.step.configuration,s={...e.step,configuration:i},n={...s.configuration,commonDescription:s.description,commonCondition:s.condition};if(this._currentFlowStep={...e,step:s,_initialValues:n},t&&t.properties.scope){const e=o.properties.scope.enum;if(null!=e.find((e=>["REQUEST","REQUEST_CONTENT","RESPONSE","RESPONSE_CONTENT"].includes(e)))){const t="pre"===this._currentFlowStep.group?["REQUEST","REQUEST_CONTENT"]:["RESPONSE","RESPONSE_CONTENT"];o.properties.scope.enum=e.filter((e=>t.includes(e)));const i=this._currentFlowStep.step.configuration.scope;null!=i&&o.properties.scope.enum.includes(i)||(o.properties.scope.default=o.properties.scope.enum[0],this._currentFlowStep.step.configuration.scope=o.properties.scope.enum[0],this._currentFlowStep._initialValues.scope=o.properties.scope.enum[0],this._currentFlowStep._values&&(this._currentFlowStep._values.scope=o.properties.scope.enum[0]))}}}else this._currentFlowStep=null;this._flowStepSchema=o}_refresh(e=!0){e&&this._closeFlowStepForm(!0),this._definition=(0,d.deepClone)(this._definition)}async _onSelectFlows({detail:e}){try{await this._closeFlowStepForm(),this._onCloseDocumentation(),this._updateSelectedFlows(e.flows),this._onDesign()}catch(e){this._currentAskConfirmation=null}}async _onOpenDocumentationFromMenu({detail:{policy:e}}){try{null!=this.documentation&&this.documentation.id===e.id||(await this._closeFlowStepForm(),this._currentPolicyId=e.id,this.getSelectedFlow()?this._splitMainViews():this._maximizeBottomView(),(0,n.dispatchCustomEvent)(this,"fetch-documentation",{policy:e}))}catch(e){}}_fetchDocumentation(e){null!=this.documentation&&this.documentation.id===e.id||(0,n.dispatchCustomEvent)(this,"fetch-documentation",{policy:e})}_onOpenDocumentation(){this._currentFlowStep&&this._currentFlowStep.policy&&this._fetchDocumentation(this._currentFlowStep.policy)}_onOpenDocumentationFromForm(){localStorage.removeItem("gv-policy-studio:keep-documentation-close"),this._onOpenDocumentation()}_findFlowCollection(e){const t=this.definedPlans.find((t=>null!=t.flows.find((t=>t._id===e))));return{plan:t,flows:null!=t?t.flows:this.definedFlows}}_findFlowById(e){let t=this.definedFlows.find((t=>t._id===e));if(null==t){t=this.definedPlans.map((e=>e.flows)).reduce(((e,t)=>e.concat(t)),[]).find((t=>t._id===e))}return t}getSelectedFlow(e=0){const t=this.selectedFlowsId[e];return this._findFlowById(t)}_onTargetPolicy({detail:e}){null==this._currentAskConfirmation&&(this._dragPolicy=e)}_onChangeFlowStep({detail:e}){this._currentFlowStep._values=e.values}_writeFlowStep(e){const{commonDescription:t,commonCondition:i,...o}=e;if(this._currentFlowStep.step._new||this._currentFlowStep.step.description!==t||this._currentFlowStep.step.condition!==i||!(0,d.deepEqual)(this._currentFlowStep.step.configuration,o)){const e=this._findFlowById(this._currentFlowStep.flow._id),s=e[this._currentFlowStep.group].findIndex((e=>e._id===this._currentFlowStep.step._id));e[this._currentFlowStep.group][s].description=t,e[this._currentFlowStep.group][s].condition=i,e[this._currentFlowStep.group][s].configuration=(0,d.deepClone)(o),delete e[this._currentFlowStep.group][s]._new,e[this._currentFlowStep.group][s]._dirty=!0,e._dirty=!0,this.isDirty=!0,this._currentFlowStep.flow=e,this._currentFlowStep.step=e[this._currentFlowStep.group][s]}}async _onSubmitFlowStep({detail:e}){this._writeFlowStep(e.values),await this.requestUpdate("_definition"),this.getChildren().forEach((e=>e.requestUpdate()))}_onCancelFlow(){this._onDesign()}_onSubmitFlow({detail:{values:e}}){const t=this.getSelectedFlow(),i=Object.assign({},this._createFlowFromSchema(),e),o=Object.assign({},t,i);(0,d.deepEqual)(t,o)||(Object.assign(t,o,{_dirty:!0}),this.isDirty=!0,this._refresh())}_onCancelFlowMode(){this._onDesign()}_onSubmitFlowMode({detail:{values:e}}){this._definition["flow-mode"]=e["flow-mode"]||"DEFAULT",this.isDirty=!0,this._refresh()}_onChangeTab({detail:e}){this._changeTab(e.value)}async _changeTabValidator({from:e,to:t}){if("properties"===e){const e=this.shadowRoot.querySelector("gv-properties");if(e.dirty)return e.confirm()}else if("resources"===e){const e=this.shadowRoot.querySelector("gv-resources");if(e.dirty)return e.confirm()}else try{return await this._askToValidateForms()}catch(e){throw this._currentAskConfirmation=null,e}return Promise.resolve()}_changeTab(e){null==this._currentAskConfirmation&&(this.tabId=e,(0,n.dispatchCustomEvent)(this,"change-tab",this.tabId))}_onDragStartFlowStep(e,{detail:t}){null==this._currentAskConfirmation&&(this._dropPolicy=t,this._dragPolicy=t)}_renderFlowEmptyState(e){return o.html`<div slot="content" class="empty"><div>Select a flow ${!0!==e?o.html`or<gv-button @gv-button:click="${this._onAddFlow}" outlined icon="code:plus" large>design new one</gv-button>`:""}</div></div>`}_renderFlow(e=0,t=!0,i){const s=this.getSelectedFlow(e);if(s){const{plan:e}=this._findFlowCollection(s._id),t=this._currentFlowStep?this._currentFlowStep.step._id:null;return o.html`<gv-flow style="height:100%" .id="${s._id}" .flow="${s}" .plan="${e}" .policies="${this.policies}" slot="content" ?disabled="${this._currentAskConfirmation}" .dragPolicy="${this._dragPolicy}" .dropPolicy="${this._dropPolicy}" .selectedStepId="${t}" ?readonly="${i}" ?has-policy-filter="${null!=this._policyFilterOptions}" flows-title="${this.flowsTitle}" @gv-flow:drag-start="${this._onDragStartFlowStep.bind(this,s)}" @gv-flow:edit="${this._onEditFlowStep}" @gv-flow:change-state="${this._onChangeFlowStepState}" @gv-flow:drop="${this._onDropPolicy}" @gv-flow:delete="${this._onDeletePolicy}"></gv-flow>`}return t?this._renderFlowEmptyState(i):o.html``}_onFetchResources(e){const{currentTarget:t,regexTypes:i}=e.detail,o=this.definedResources.filter((e=>null==i||new RegExp(i).test(e.type))).map(((e,t)=>{const i=this.resourceTypes.find((t=>t.id===e.type)),o=document.createElement("gv-row"),s=i.icon?i.icon:null;return o.item={picture:s,name:e.name},{element:o,value:e.name,id:e.type}}));t.options=o}_renderPolicy(e){return this._flowStepSchema&&this.documentation?o.html`<gv-resizable-views direction="horizontal" no-overflow><div slot="top">${this._renderFlowStepForm(e)}</div><div slot="bottom"><gv-documentation .text="${this.documentation.content}" .image="${this.documentation.image}" ?disabled="${this._currentAskConfirmation}" @gv-documentation:close="${this._onCloseDocumentation}"></gv-documentation></div></gv-resizable-views>`:this.documentation?o.html`<gv-documentation .text="${this.documentation.content}" .image="${this.documentation.image}" ?disabled="${this._currentAskConfirmation}" @gv-documentation:close="${this._onCloseDocumentation}"></gv-documentation>`:this._flowStepSchema?this._renderFlowStepForm(e):o.html``}_getFlowStepForm(){return this.shadowRoot.querySelector("#flow-step-form")}_onResetFlowStep(){this._currentFlowStep&&(delete this._currentFlowStep._values,this._getFlowStepForm().reset())}_generateFlowsId(e,t=!1){return this._generateId("f",e,t,!0)}_generatePlanFlowsId(e,t=!1){return this._generateId(e.id,e.flows,t,!0)}_generateFlowStepId(e,t,i){return`${e}_${t}_${i}`}_generateId(e,t,i=!1,o=!1){return t?t.map(((t,s)=>{const n=`${e}_${s}`;return o&&(t.pre&&t.pre.forEach(((e,t)=>e._id=this._generateFlowStepId(n,"pre",t))),t.post&&t.post.forEach(((e,t)=>e._id=this._generateFlowStepId(n,"post",t)))),i||null==t._id?{...t,_id:n}:t})):t}getChildren(){return[...Array.from(this.shadowRoot.querySelectorAll("gv-flow")),...Array.from(this.shadowRoot.querySelectorAll("gv-resizable-views"))]}async getUpdateComplete(){await super.getUpdateComplete(),await Promise.all(this.getChildren().map((e=>e.updateComplete)))}shouldUpdate(e){return e.has("_dragPolicy")?(this.shadowRoot.querySelectorAll("gv-flow").forEach((e=>e.dragPolicy=this._dragPolicy)),!1):e.has("_dropPolicy")?(this.shadowRoot.querySelectorAll("gv-flow").forEach((e=>e.dropPolicy=this._dropPolicy)),!1):super.shouldUpdate(e)}updated(e){e.has("documentation")&&null!=this.documentation&&this.selectedFlowsId.length>1&&this._updateSelectedFlows([this.selectedFlowsId[0]])}_renderFlowStepForm(e){const t=this._currentFlowStep._values||this._currentFlowStep._initialValues,i=[{items:["commonDescription","commonCondition"]},{name:(0,r.i18n)("gv-policy-studio.policy-settings"),default:!0}];return o.html`${(0,a.cache)(this._flowStepSchema&&this._currentFlowStep?o.html`<div class="flow-step__container"><div class="flow-step__form"><gv-schema-form .id="${"flow-step-form"}" .schema="${this._flowStepSchema}" .icon="design:edit" has-header validate-on-render .values="${t}" .dirty="${null!=this._currentFlowStep._values}" ?readonly="${e}" scrollable .groups="${i}" @gv-schema-form:change="${this._onChangeFlowStep}" @gv-schema-form:reset="${this._onResetFlowStep}" @gv-schema-form:fetch-resources="${this._onFetchResources}" @gv-schema-form:submit="${this._onSubmitFlowStep}"><div slot="title" class="flow-step__form-title">${this._currentFlowStep.step.name}</div><gv-button slot="header-left" icon="general:close" outlined small @gv-button:click="${this._onCloseFlowStepForm}" title="Close"></gv-button><gv-button slot="header-left" icon="home:book" ?disabled="${null!=this.documentation}" outlined small @gv-button:click="${this._onOpenDocumentationFromForm}" title="Open documentation"></gv-button></gv-schema-form></div></div>`:"")}`}_onCloseDocumentation(){this.documentation=null,null==this._currentFlowStep?this._maximizeTopView():localStorage.setItem("gv-policy-studio:keep-documentation-close",!0)}_onDeleteFlow({detail:e}){const t=e.content._id,{flows:i}=this._findFlowCollection(t),o=i.find((e=>e._id===t));this._deleteFlow(i,o)}get definedFlows(){return this._definition&&this._definition.flows?this._definition.flows:[]}get definedPlans(){return this._definition&&this._definition.plans?this._definition.plans:[]}get definedResources(){return this._definition&&this._definition.resources?this._definition.resources:[]}get definedProperties(){return this._definition&&this._definition.properties?this._definition.properties:[]}async _onDuplicateFlow({detail:e}){try{await this._askToValidateForms();const t=e.content._id,{plan:i,flows:o}=this._findFlowCollection(t);if(this._addFlow(o,this._findFlowById(t)),null!=i){let e=null;this.definedPlans.find(((t,o)=>t.id===i.id&&(e=o,!0))),i.flows=o,this.definedPlans[e].flows=this._generatePlanFlowsId(i,!0),this._updateSelectedFlows([this.definedPlans[e].flows[o.length-1]._id])}else this._definition.flows=this._generateFlowsId(this._definition.flows),this._updateSelectedFlows([this._definition.flows[this._definition.flows.length-1]._id])}catch(e){this._currentAskConfirmation=null}}_onChangeFlowState({detail:e}){const t=this._findFlowById(e.content._id);t.enabled=e.enabled,t._dirty=!0,this.isDirty=!0}async _onAddFlowPlan({detail:e}){try{await this._askToValidateForms(),this._addFlow(this.definedPlans[e.planIndex].flows),this.definedPlans[e.planIndex].flows=this._generatePlanFlowsId(this.definedPlans[e.planIndex]),this._updateSelectedFlows([this.definedPlans[e.planIndex].flows[this.definedPlans[e.planIndex].flows.length-1]._id])}catch(e){this._currentAskConfirmation=null}}async _onAddFlow(){try{await this._askToValidateForms(),this._addFlow(this._definition.flows),this._definition.flows=this._generateFlowsId(this._definition.flows),this._updateSelectedFlows([this._definition.flows[this._definition.flows.length-1]._id])}catch(e){this._currentAskConfirmation=null}}_addFlow(e,t=null){const i=null==t?this._createFlowFromSchema():{...t,_id:null,id:null,_dirty:!0};return e.push(i),this.isDirty=!0,e}_createFlowFromSchema(){return this._instantiate(this.flowSchema.properties,{name:"",pre:[],post:[],_dirty:!0})}_instantiate(e,t={}){const i={...t};if(e)for(const o of Object.keys(e)){const s=e[o];"object"===s.type&&(i[o]=this._instantiate(s.properties,t={})),void 0!==s.default?i[o]=s.default:"string"===s.type&&(i[o]="")}return i}_deleteFlow(e,t){const i=e.indexOf(t);e.splice(i,1);const o=this.selectedFlowsId.filter((e=>e!==t._id));1===o.length?this._updateSelectedFlows(o):this._selectFirstFlow(!0),this._changeTab("design"),this._refresh(),this.isDirty=!0}_findFlowIndex(e,t){let i=null;return e.find(((e,o)=>e._id===t&&(i=o,!0))),i}async _onReorderFlows({detail:{plan:e}}){try{if(await this._askToValidateForms(),this.isDirty=!0,null!=e){const t=this._generatePlanFlowsId(e,!0);this.selectedFlowsId&&this._updateSelectedFlows(this.selectedFlowsId.map((i=>{const o=this._findFlowIndex(e.flows,i);return null!=o?t[o]._id:i}))),e.flows=t}else{const e=this._generateFlowsId(this._definition.flows,!0);this.selectedFlowsId&&this._updateSelectedFlows(this.selectedFlowsId.map((t=>{const i=this._findFlowIndex(this._definition.flows,t);return null!=i?e[i]._id:t}))),this._definition.flows=e}}catch(e){this._currentAskConfirmation=!1}}_onSearchPolicy({detail:e}){this._searchPolicyQuery=e}_onClearPolicy(){this._searchPolicyQuery=null}_onSearchFlows({detail:e}){this._searchFlowQuery=e}_onClearFlows(){this._searchFlowQuery=null}async _onResetAll(){try{await this._closeFlowStepForm(),this.definition=(0,d.deepClone)(this._initialDefinition)}catch(e){this._currentAskConfirmation=null}}_filterNotValidStep(e){return!0!==e._new}_removePrivateProperties(e){const t={...e};return Object.keys(e).filter((e=>e.startsWith("_"))).forEach((e=>{delete t[e]})),t}_submitOrConfirmForms(){return[...this.shadowRoot.querySelectorAll("gv-schema-form")].filter((e=>{const t=e.isValid();return t?e.submit():e.dirty=!0,!t})).map((e=>e.confirm()))}getPropertiesElement(){return this.shadowRoot.querySelector("gv-properties")}async _checkCurrentFlowStep(){if(this._currentFlowStep&&this.selectedFlowsId){const e=this.selectedFlowsId.map((e=>{const t=this._findFlowById(e);return null==[...t.pre,...t.post].find((e=>e._id===this._currentFlowStep.step._id))?this._closeFlowStepForm(!0):null})).filter((e=>null!==e));return Promise.all(e)}return Promise.resolve()}saved(){this.isDirty&&(this._initialDefinition=(0,d.deepClone)(this._definitionSaved),this._definition=(0,d.deepClone)(this._definitionSaved),this._definitionSaved=null,this.isDirty=!1,this._checkCurrentFlowStep(),this.definedPlans.forEach((e=>{e.flows.forEach((e=>e._dirty=!1))})),this.definedFlows.forEach((e=>e._dirty=!1)),this.getChildren().forEach((e=>e.requestUpdate())))}_buildDefinitionToSave(){const e=this._definition.flows.map((e=>(e.pre=e.pre.filter(this._filterNotValidStep),e.post=e.post.filter(this._filterNotValidStep),e)));let t={...this._definition,flows:e};if(null!=this._definition.plans){const e=this._definition.plans.map((e=>{const t=e.flows.map((e=>(e.pre=e.pre.filter(this._filterNotValidStep),e.post=e.post.filter(this._filterNotValidStep),e)));return{...e,flows:t}}));t={...t,plans:e}}return t}_buildDefinitionToSend(e){const t=e.flows.map((e=>{const t=this._removePrivateProperties(e);return t.pre=t.pre.map(this._removePrivateProperties),t.post=t.post.map(this._removePrivateProperties),t}));let i={...this._definition,flows:t};if(null!=this._definition.plans){const t=e.plans.map((e=>{const t=e.flows.map((e=>{const t=this._removePrivateProperties(e);return t.pre=t.pre.map(this._removePrivateProperties),t.post=t.post.map(this._removePrivateProperties),t}));return{...e,flows:t}}));i={...i,plans:t}}if(null!=this._definition.properties){const e=this._definition.properties.map(this._removePrivateProperties);i={...i,properties:e}}if(null!=this._definition.resources){const e=this._definition.resources.map(this._removePrivateProperties);i={...i,resources:e}}return i}_onSaveAll(){this.hasProperties&&this.getPropertiesElement().submit(),Promise.all(this._submitOrConfirmForms()).then((()=>{this._definitionSaved=this._buildDefinitionToSave();const e=this._buildDefinitionToSend(this._definitionSaved);(0,n.dispatchCustomEvent)(this,"save",{definition:e,services:this.services})})).catch((e=>{console.error("[policy-studio] Error on save",e)}))}_onDebug(e){this.hasProperties&&this.getPropertiesElement().submit(),Promise.all(this._submitOrConfirmForms()).then((()=>{const t=this._buildDefinitionToSend(this._buildDefinitionToSave());(0,n.dispatchCustomEvent)(this,"debug",{definition:t,services:this.services,request:e.detail.request})})).catch((e=>{console.error("[policy-studio] Error on debug",e)}))}get filteredFlows(){return 0===this._flowFilter.length||this._flowFilter.includes("api")?this.definedFlows:null}get filteredPlans(){return 0===this._flowFilter.length||this._flowFilter.includes("plan")?this.definedPlans:null}_onFilterFlows({detail:e}){this._flowFilter.includes(e.id)?this._flowFilter=[]:this._flowFilter=[e.id]}_getFilteredPolicies(){return this._policyFilter.length>0?this.policies.filter((e=>e.onRequest&&this._policyFilter.includes("onRequest")||e.onResponse&&this._policyFilter.includes("onResponse"))):this.policies}_onFilterPolicies({detail:e}){this._policyFilter.includes(e.id)?this._policyFilter=[]:this._policyFilter=[e.id]}_renderDesign(e){return o.html`<div id="design" slot="content" class="design"><gv-resizable-views no-overflow><div slot="top">${this._renderFlow(0,!0,e)}</div><div slot="bottom">${this._renderFlow(1,!1,e)} ${this._renderPolicy(e)} ${this._renderFlowForm(e)}</div></gv-resizable-views>${!0!==e?o.html`<gv-policy-studio-menu class="right-menu" ?disabled="${this._currentAskConfirmation}" .policies="${this._getFilteredPolicies()}" .selectedIds="${[this._currentPolicyId]}" .query="${this._searchPolicyQuery}" ?has-policy-filter="${null!=this._policyFilterOptions}" ?readonly="${e}" @gv-policy-studio-menu:target-policy="${this._onTargetPolicy}" @gv-policy-studio-menu:fetch-documentation="${this._onOpenDocumentationFromMenu}" @gv-policy-studio-menu:dragend-policy="${this._onDragEndPolicy}"><div slot="header" class="search-policies">${null!=this._policyFilterOptions?o.html`<gv-option ?disabled="${this._currentAskConfirmation}" .options="${this._policyFilterOptions}" multiple="multiple" outlined .value="${this._policyFilter}" small @gv-option:select="${this._onFilterPolicies}"></gv-option>`:""}<gv-input id="search-policy" ?disabled="${this._currentAskConfirmation}" placeholder="Filter policies (Shift + Ctrl + Space)" type="search" small @gv-input:input="${this._onSearchPolicy}" @gv-input:clear="${this._onClearPolicy}"></gv-input></div></gv-policy-studio-menu>`:""}</div>`}_renderDebug(){const e=this.debugResponse?this.debugResponse.response:void 0,t=this.debugResponse?this.debugResponse.isLoading:void 0,i=this.debugResponse&&this.debugResponse.request?this.debugResponse.request.path:void 0,s=this.debugResponse&&this.debugResponse.request?this.debugResponse.request.method:void 0;return o.html`<gv-http-client id="debug" slot="content" class="debug" @gv-http-client:send="${this._onDebug}" .response="${e}" .path="${i}" .method="${s}" ?loading="${t}"></gv-http-client>`}_renderConfigurationForm(e){if(this.configurationSchema){const t=(0,d.deepClone)(this._definition);return o.html`<div id="settings" slot="content" class="api-settings" @dragover="${this._onDesign}"><gv-schema-form .schema="${this.configurationSchema}" id="api-settings-form" .values="${t}" has-header has-footer scrollable ?readonly="${e}" @gv-schema-form:cancel="${this._onCancelFlowMode}" @gv-schema-form:submit="${this._onSubmitFlowMode}">${this.configurationInformation?o.html`<div class="api-settings-information" slot="title"><gv-icon class="api-settings-information__icon" title="Info" shape="code:info"></gv-icon><blockquote class="api-settings-information__blockquote">${this.configurationInformation}</blockquote></div>`:""}</gv-schema-form></div>`}return o.html``}_renderFlowForm(e){if(this.flowSchema&&null==this._flowStepSchema&&null==this.documentation&&1===this.selectedFlowsId.length){const t=this.getSelectedFlow();if(t){const i=(0,d.deepClone)(t);return o.html`<div slot="content" class="flow-settings"><gv-schema-form .schema="${this.flowSchema}" id="settings-form" .values="${i}" has-header scrollable ?readonly="${e}" @gv-schema-form:cancel="${this._onCancelFlow}" @gv-schema-form:submit="${this._onSubmitFlow}"><div slot="title" class="flow-step__form-title">Flow configuration</div></gv-schema-form></div>`}}}_onResourcesChange({detail:e}){this.definition.resources=e.resources,this.isDirty=!0}_onPropertiesChange({detail:e}){this.definition.properties=e.properties,this.isDirty=!0}_onSaveProvider({detail:e}){this.services["dynamic-property"]=e.provider,this.isDirty=!0}_onSwitchEncryptedProperty({detail:e}){this.isDirty=!0}render(){const e=this._getReadonlyModeForDesign();return o.html`<div class="box"><gv-policy-studio-menu class="left-menu" .api-name="${this._definition.name}" .flows="${this.filteredFlows}" .plans="${this.filteredPlans}" .selectedIds="${this.selectedFlowsId}" ?disabled="${this._currentAskConfirmation}" ?sortable="${this.sortable&&!0!==this.readonly}" ?readonly="${this.readonly}" ?readonlyPlans="${this.readonlyPlans}" flows-title="${this.flowsTitle}" .query="${this._searchFlowQuery}" ?can-add="${this.canAdd&&!this.readonly}" @gv-policy-studio-menu:reorder-flows="${this._onReorderFlows}" @gv-policy-studio-menu:change-flow-state="${this._onChangeFlowState}" @gv-policy-studio-menu:add-flow="${this._onAddFlow}" @gv-policy-studio-menu:add-flow-plan="${this._onAddFlowPlan}" @gv-policy-studio-menu:delete-flow="${this._onDeleteFlow}" @gv-policy-studio-menu:duplicate-flow="${this._onDuplicateFlow}" @gv-policy-studio-menu:select-flows="${this._onSelectFlows}"><div slot="header" class="header-actions"><div class="title">${this._definition.name}</div>${null!=this._flowFilterOptions?o.html`<gv-option ?disabled="${this._currentAskConfirmation}" .options="${this._flowFilterOptions}" multiple="multiple" outlined .value="${this._flowFilter}" small @gv-option:select="${this._onFilterFlows}"></gv-option>`:""}<gv-input ?disabled="${this._currentAskConfirmation}" id="search-flow" placeholder="Filter flows (Ctrl + Space)" type="search" small @gv-input:input="${this._onSearchFlows}" @gv-input:clear="${this._onClearFlows}"></gv-input></div>${!0!==this.readonly?o.html`<div slot="footer" class="footer-actions"><gv-button class="btn-large" .disabled="${!this.isDirty||this._currentAskConfirmation}" @gv-button:click="${this._onSaveAll}">Save</gv-button><gv-button link .disabled="${!this.isDirty||this._currentAskConfirmation}" @gv-button:click="${this._onResetAll}">Reset</gv-button></div>`:""}</gv-policy-studio-menu><gv-tabs .value="${this.tabId}" .options="${this._tabs}" .disabled="${this._currentAskConfirmation}" @gv-tabs:change="${this._onChangeTab}" .validator="${this._changeTabValidator.bind(this)}">${this._renderDesign(e)} ${this._renderConfigurationForm(e)} ${this._renderDebug()}<gv-properties id="properties" slot="content" class="properties" .provider="${this.services["dynamic-property"]}" @gv-properties:change="${this._onPropertiesChange}" @gv-properties:save-provider="${this._onSaveProvider}" @gv-properties:switch-encrypted="${this._onSwitchEncryptedProperty}" ?readonly="${e}" encryptable="true" .properties="${this.definedProperties}" .providers="${this.propertyProviders}" .dynamicPropertySchema="${this.dynamicPropertySchema}"></gv-properties><gv-resources id="resources" slot="content" class="resources" @gv-resources:change="${this._onResourcesChange}" ?readonly="${e}" .resources="${this.definedResources}" .types="${this.resourceTypes}"></gv-resources></gv-tabs></div>`}_getReadonlyModeForDesign(){if(this.readonly)return!0;const e=this.getSelectedFlow(0);if(!e)return!1;const{plan:t}=this._findFlowCollection(e._id);if(t&&this.readonlyPlans)return!0;const i=this.getSelectedFlow(1);if(!i)return!1;const{plan:o}=this._findFlowCollection(i._id);return o&&this.readonlyPlans}}exports.GvPolicyStudio=h,window.customElements.define("gv-policy-studio",h);