@genexus/genexus-ide-ui 3.2.20 → 3.2.22

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 (68) hide show
  1. package/dist/cjs/genexus-ide-ui.cjs.js +1 -1
  2. package/dist/cjs/gx-ide-db-properties-configurator.cjs.entry.js +15 -5
  3. package/dist/cjs/gx-ide-db-properties-configurator.cjs.entry.js.map +1 -1
  4. package/dist/cjs/gx-ide-plugin-details.cjs.entry.js +31 -13
  5. package/dist/cjs/gx-ide-plugin-details.cjs.entry.js.map +1 -1
  6. package/dist/cjs/gx-ide-plugin-explorer.cjs.entry.js +97 -48
  7. package/dist/cjs/gx-ide-plugin-explorer.cjs.entry.js.map +1 -1
  8. package/dist/cjs/gx-ide-progress-bar.cjs.entry.js +1 -1
  9. package/dist/cjs/gx-ide-progress-bar.cjs.entry.js.map +1 -1
  10. package/dist/cjs/loader.cjs.js +1 -1
  11. package/dist/collection/components/_helpers/progress-bar/progress-bar.css +10 -0
  12. package/dist/collection/components/db-properties-configurator/db-properties-configurator.css +2 -7
  13. package/dist/collection/components/db-properties-configurator/db-properties-configurator.js +40 -5
  14. package/dist/collection/components/db-properties-configurator/db-properties-configurator.js.map +1 -1
  15. package/dist/collection/components/db-properties-configurator/gx-ide-assets/db-properties-configurator/shortcuts.json +15 -0
  16. package/dist/collection/components/plugin-details/gx-ide-assets/plugin-details/langs/plugin-details.lang.en.json +3 -1
  17. package/dist/collection/components/plugin-details/gx-ide-assets/plugin-details/langs/plugin-details.lang.ja.json +3 -1
  18. package/dist/collection/components/plugin-details/gx-ide-assets/plugin-details/langs/plugin-details.lang.zh.json +3 -1
  19. package/dist/collection/components/plugin-details/plugin-details.css +7 -1
  20. package/dist/collection/components/plugin-details/plugin-details.js +75 -16
  21. package/dist/collection/components/plugin-details/plugin-details.js.map +1 -1
  22. package/dist/collection/components/plugin-explorer/plugin-explorer.css +83 -26
  23. package/dist/collection/components/plugin-explorer/plugin-explorer.js +105 -56
  24. package/dist/collection/components/plugin-explorer/plugin-explorer.js.map +1 -1
  25. package/dist/components/gx-ide-db-properties-configurator.js +18 -7
  26. package/dist/components/gx-ide-db-properties-configurator.js.map +1 -1
  27. package/dist/components/gx-ide-plugin-details.js +40 -14
  28. package/dist/components/gx-ide-plugin-details.js.map +1 -1
  29. package/dist/components/gx-ide-plugin-explorer.js +107 -52
  30. package/dist/components/gx-ide-plugin-explorer.js.map +1 -1
  31. package/dist/components/progress-bar.js +1 -1
  32. package/dist/components/progress-bar.js.map +1 -1
  33. package/dist/esm/genexus-ide-ui.js +1 -1
  34. package/dist/esm/gx-ide-db-properties-configurator.entry.js +16 -6
  35. package/dist/esm/gx-ide-db-properties-configurator.entry.js.map +1 -1
  36. package/dist/esm/gx-ide-plugin-details.entry.js +31 -13
  37. package/dist/esm/gx-ide-plugin-details.entry.js.map +1 -1
  38. package/dist/esm/gx-ide-plugin-explorer.entry.js +97 -48
  39. package/dist/esm/gx-ide-plugin-explorer.entry.js.map +1 -1
  40. package/dist/esm/gx-ide-progress-bar.entry.js +1 -1
  41. package/dist/esm/gx-ide-progress-bar.entry.js.map +1 -1
  42. package/dist/esm/loader.js +1 -1
  43. package/dist/genexus-ide-ui/genexus-ide-ui.esm.js +1 -1
  44. package/dist/genexus-ide-ui/genexus-ide-ui.esm.js.map +1 -1
  45. package/dist/genexus-ide-ui/gx-ide-assets/db-properties-configurator/shortcuts.json +15 -0
  46. package/dist/genexus-ide-ui/gx-ide-assets/plugin-details/langs/plugin-details.lang.en.json +3 -1
  47. package/dist/genexus-ide-ui/gx-ide-assets/plugin-details/langs/plugin-details.lang.ja.json +3 -1
  48. package/dist/genexus-ide-ui/gx-ide-assets/plugin-details/langs/plugin-details.lang.zh.json +3 -1
  49. package/dist/genexus-ide-ui/{p-b3c5c315.entry.js → p-63e41ecd.entry.js} +2 -2
  50. package/dist/genexus-ide-ui/p-63e41ecd.entry.js.map +1 -0
  51. package/dist/genexus-ide-ui/p-9cf62f0a.entry.js +292 -0
  52. package/dist/genexus-ide-ui/p-9cf62f0a.entry.js.map +1 -0
  53. package/dist/genexus-ide-ui/p-e82d9621.entry.js +317 -0
  54. package/dist/genexus-ide-ui/p-e82d9621.entry.js.map +1 -0
  55. package/dist/genexus-ide-ui/p-ef8663dd.entry.js +284 -0
  56. package/dist/genexus-ide-ui/p-ef8663dd.entry.js.map +1 -0
  57. package/dist/types/components/db-properties-configurator/db-properties-configurator.d.ts +4 -0
  58. package/dist/types/components/plugin-details/plugin-details.d.ts +21 -3
  59. package/dist/types/components/plugin-explorer/plugin-explorer.d.ts +31 -4
  60. package/dist/types/components.d.ts +38 -14
  61. package/package.json +1 -1
  62. package/dist/genexus-ide-ui/p-514445ac.entry.js +0 -291
  63. package/dist/genexus-ide-ui/p-514445ac.entry.js.map +0 -1
  64. package/dist/genexus-ide-ui/p-b3c5c315.entry.js.map +0 -1
  65. package/dist/genexus-ide-ui/p-e759cfdb.entry.js +0 -281
  66. package/dist/genexus-ide-ui/p-e759cfdb.entry.js.map +0 -1
  67. package/dist/genexus-ide-ui/p-fc0bc991.entry.js +0 -204
  68. package/dist/genexus-ide-ui/p-fc0bc991.entry.js.map +0 -1
@@ -14,7 +14,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
14
14
  throw new TypeError("Cannot write private member to an object whose class did not declare it");
15
15
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16
16
  };
17
- var _GxIdePluginManager_componentLocale, _GxIdePluginManager_animateEmptyState, _GxIdePluginManager_actionListButtonClickHandler, _GxIdePluginManager_mapPluginDataToActionListModel, _GxIdePluginManager_pluginsFilterInputHandler, _GxIdePluginManager_evaluateContentToDisplay, _GxIdePluginManager_renderLoader, _GxIdePluginManager_pluginSelectedHandler;
17
+ var _GxIdePluginManager_componentLocale, _GxIdePluginManager_animateEmptyState, _GxIdePluginManager_actionListButtonClickHandler, _GxIdePluginManager_downloadsFormatter, _GxIdePluginManager_formatDownloads, _GxIdePluginManager_mapPluginToItem, _GxIdePluginManager_mapPluginGroupsToActionListModel, _GxIdePluginManager_pluginsFilterInputHandler, _GxIdePluginManager_evaluateContentToDisplay, _GxIdePluginManager_renderLoader, _GxIdePluginManager_pluginSelectedHandler;
18
18
  import { Host, h, getAssetPath } from "@stencil/core";
19
19
  import { getIconPath } from "@genexus/mercury";
20
20
  import { Locale } from "../../common/locale";
@@ -25,7 +25,7 @@ const FILTER_ICON = getIconPath({
25
25
  colorType: "on-surface"
26
26
  });
27
27
  // plugin icon if no iconUrl was provided
28
- const EXTENSION_ICON_IMG = getAssetPath(`./gx-ide-assets/plugin-manager/images/plugin-icon.svg`);
28
+ const EXTENSION_ICON_IMG = getAssetPath(`./gx-ide-assets/plugin-explorer/images/plugin-icon.svg`);
29
29
  const CSS_BUNDLES = [
30
30
  "resets/box-sizing",
31
31
  "components/list-box",
@@ -37,6 +37,21 @@ const CSS_BUNDLES = [
37
37
  "utils/spacing",
38
38
  "chameleon/scrollbar"
39
39
  ];
40
+ const SEARCH_ICON = getIconPath({
41
+ category: "system",
42
+ name: "search",
43
+ colorType: "on-surface"
44
+ });
45
+ const STAR_ICON = getIconPath({
46
+ category: "system",
47
+ name: "star-fill",
48
+ colorType: "warning"
49
+ });
50
+ const DOWNLOAD_ICON = getIconPath({
51
+ category: "system",
52
+ name: "download",
53
+ colorType: "on-surface"
54
+ });
40
55
  export class GxIdePluginManager {
41
56
  constructor() {
42
57
  /**
@@ -49,51 +64,85 @@ export class GxIdePluginManager {
49
64
  event.stopPropagation();
50
65
  this.executeActionCallback(pluginId, action);
51
66
  });
52
- _GxIdePluginManager_mapPluginDataToActionListModel.set(this, (pluginsData) => {
53
- const pluginsActionListModel = [];
54
- const separatorItem = { type: "separator" };
55
- pluginsData === null || pluginsData === void 0 ? void 0 : pluginsData.forEach((pluginData, index) => {
56
- const hasActionButton = !!pluginData.action;
57
- const pluginItem = {
58
- id: pluginData.id,
59
- caption: pluginData.name,
60
- imgSrc: pluginData.iconUrl,
61
- type: "actionable",
62
- additionalInformation: {
63
- "stretch-start": {
64
- center: [
65
- {
66
- part: "custom-image",
67
- jsx: () => (h("img", { part: "custom-image", src: pluginData.iconUrl || EXTENSION_ICON_IMG, alt: `${__classPrivateFieldGet(this, _GxIdePluginManager_componentLocale, "f").logotype.replace("PLUGIN_NAME_PLACEHOLDER", pluginData.name)}`, loading: "lazy" }))
68
- }
69
- ]
70
- },
71
- "block-end": {
72
- start: [
73
- {
74
- part: "custom-description custom-button custom-container custom-brand custom-brand-icon custom-image item__block-end start",
75
- jsx: () => (h("div", { part: "custom-container", title: pluginData.description }, h("p", { part: "custom-description" }, pluginData.description), h("small", { part: "custom-brand" }, pluginData.publisher)))
76
- }
77
- // {
78
- // slot: "abcd"
79
- // } as ActionListItemAdditionalSlot // slot not working
80
- ]
81
- },
82
- "stretch-end": hasActionButton && {
83
- center: [
84
- {
85
- jsx: () => (h("button", { part: "custom-button", onClick: __classPrivateFieldGet(this, _GxIdePluginManager_actionListButtonClickHandler, "f").call(this, pluginData.id, pluginData.action) }, pluginData.action))
86
- }
87
- ]
88
- }
67
+ // Formats a raw downloads count into a compact string (e.g. 4000 -> "4K").
68
+ _GxIdePluginManager_downloadsFormatter.set(this, new Intl.NumberFormat(undefined, {
69
+ notation: "compact",
70
+ maximumFractionDigits: 1
71
+ }));
72
+ _GxIdePluginManager_formatDownloads.set(this, (value) => {
73
+ const numericValue = typeof value === "number" ? value : Number(value);
74
+ return Number.isFinite(numericValue)
75
+ ? __classPrivateFieldGet(this, _GxIdePluginManager_downloadsFormatter, "f").format(numericValue)
76
+ : `${value}`;
77
+ });
78
+ _GxIdePluginManager_mapPluginToItem.set(this, (pluginData) => {
79
+ const hasActionButton = !!pluginData.action;
80
+ const hasDownloads = pluginData.downloads !== undefined && pluginData.downloads !== null;
81
+ const hasRating = pluginData.rating !== undefined && pluginData.rating !== null;
82
+ const hasMeta = hasDownloads || hasRating;
83
+ const pluginItem = {
84
+ id: pluginData.id,
85
+ caption: pluginData.name,
86
+ imgSrc: pluginData.iconUrl,
87
+ type: "actionable",
88
+ additionalInformation: {
89
+ "stretch-start": {
90
+ center: [
91
+ {
92
+ part: "custom-image",
93
+ jsx: () => (h("img", { part: "custom-image", src: pluginData.iconUrl || EXTENSION_ICON_IMG, alt: `${__classPrivateFieldGet(this, _GxIdePluginManager_componentLocale, "f").logotype.replace("PLUGIN_NAME_PLACEHOLDER", pluginData.name)}`, loading: "lazy" }))
94
+ }
95
+ ]
96
+ },
97
+ "inline-caption": hasMeta && {
98
+ end: [
99
+ {
100
+ part: "custom-meta",
101
+ jsx: () => (h("div", { part: "custom-meta" }, hasDownloads && (h("span", { part: "custom-meta-item custom-downloads", title: `${pluginData.downloads}` }, h("ch-image", { part: "custom-meta-icon custom-downloads-icon", src: DOWNLOAD_ICON }), __classPrivateFieldGet(this, _GxIdePluginManager_formatDownloads, "f").call(this, pluginData.downloads))), hasRating && (h("span", { part: "custom-meta-item custom-rating", title: `${pluginData.rating}` }, h("ch-image", { part: "custom-meta-icon custom-rating-icon", src: STAR_ICON }), pluginData.rating))))
102
+ }
103
+ ]
104
+ },
105
+ "block-end": {
106
+ start: [
107
+ {
108
+ part: "custom-description custom-button custom-container custom-brand custom-footer custom-meta custom-meta-item custom-meta-icon custom-progress custom-progress-label custom-progress-bar item__block-end start",
109
+ jsx: () => (h("div", { part: "custom-container" }, h("p", { part: "custom-description", title: pluginData.description }, pluginData.description), h("div", { part: "custom-footer" }, h("small", { part: "custom-brand" }, pluginData.publisher), pluginData.installProgress ? (h("div", { part: "custom-progress" }, h("span", { part: "custom-progress-label" }, pluginData.installProgress.percent, "%"), h("gx-ide-progress-bar", { part: "custom-progress-bar", class: "plain", minimal: true, active: true, stateType: "in-progress", progress: pluginData.installProgress.percent }))) : hasActionButton ? (h("button", { class: "button", part: "custom-button", onClick: __classPrivateFieldGet(this, _GxIdePluginManager_actionListButtonClickHandler, "f").call(this, pluginData.id, pluginData.action) }, pluginData.action)) : null)))
110
+ }
111
+ // {
112
+ // slot: "abcd"
113
+ // } as ActionListItemAdditionalSlot // slot not working
114
+ ]
89
115
  }
90
- };
91
- if (index !== 0) {
92
- pluginsActionListModel.push(separatorItem);
93
116
  }
94
- pluginsActionListModel.push(pluginItem);
117
+ };
118
+ return pluginItem;
119
+ });
120
+ // Builds the ch-action-list model from groups: one native action-list group
121
+ // per PluginGroupData, plus a separator between groups. The group header only
122
+ // renders a plain-text caption (no custom pill element is supported), so the
123
+ // per-group total is shown as a number appended to the caption.
124
+ _GxIdePluginManager_mapPluginGroupsToActionListModel.set(this, (groups) => {
125
+ const model = [];
126
+ const separatorItem = { type: "separator" };
127
+ groups === null || groups === void 0 ? void 0 : groups.forEach(group => {
128
+ var _a, _b, _c;
129
+ // Skip empty groups so we don't render a header with "(0)".
130
+ if (!((_a = group.plugins) === null || _a === void 0 ? void 0 : _a.length)) {
131
+ return;
132
+ }
133
+ if (model.length > 0) {
134
+ model.push(separatorItem);
135
+ }
136
+ model.push({
137
+ id: group.id,
138
+ type: "group",
139
+ caption: `${group.caption} (${group.plugins.length})`,
140
+ expandable: (_b = group.expandable) !== null && _b !== void 0 ? _b : true,
141
+ expanded: (_c = group.expanded) !== null && _c !== void 0 ? _c : true,
142
+ items: group.plugins.map(plugin => __classPrivateFieldGet(this, _GxIdePluginManager_mapPluginToItem, "f").call(this, plugin))
143
+ });
95
144
  });
96
- return pluginsActionListModel;
145
+ return model;
97
146
  });
98
147
  _GxIdePluginManager_pluginsFilterInputHandler.set(this, async (event) => {
99
148
  this.loading = true;
@@ -125,7 +174,7 @@ export class GxIdePluginManager {
125
174
  }
126
175
  pluginsChangedHandler(newPlugins) {
127
176
  this.pluginsActionListModel =
128
- __classPrivateFieldGet(this, _GxIdePluginManager_mapPluginDataToActionListModel, "f").call(this, newPlugins);
177
+ __classPrivateFieldGet(this, _GxIdePluginManager_mapPluginGroupsToActionListModel, "f").call(this, newPlugins);
129
178
  this.loading = false;
130
179
  }
131
180
  async componentWillLoad() {
@@ -133,7 +182,7 @@ export class GxIdePluginManager {
133
182
  this.pluginsChangedHandler(this.plugins);
134
183
  }
135
184
  render() {
136
- return (h(Host, { class: "widget" }, h("ch-theme", { model: CSS_BUNDLES }), h("div", { class: "outer-container field-group" }, h("ch-edit", { id: "search-plugins-input", class: "input", accessibleName: __classPrivateFieldGet(this, _GxIdePluginManager_componentLocale, "f").accessibleName, placeholder: __classPrivateFieldGet(this, _GxIdePluginManager_componentLocale, "f").searchInputPlaceholder, debounce: config.inputDebounce, onInput: __classPrivateFieldGet(this, _GxIdePluginManager_pluginsFilterInputHandler, "f"), type: "search" }), h("div", { class: "inner-container" }, this.loading
185
+ return (h(Host, { class: "widget" }, h("ch-theme", { model: CSS_BUNDLES }), h("div", { class: "outer-container field-group" }, h("ch-edit", { id: "search-plugins-input", class: "input", accessibleName: __classPrivateFieldGet(this, _GxIdePluginManager_componentLocale, "f").accessibleName, placeholder: __classPrivateFieldGet(this, _GxIdePluginManager_componentLocale, "f").searchInputPlaceholder, debounce: config.inputDebounce, onInput: __classPrivateFieldGet(this, _GxIdePluginManager_pluginsFilterInputHandler, "f"), type: "search", startImgSrc: SEARCH_ICON }), h("div", { class: "inner-container" }, this.loading
137
186
  ? __classPrivateFieldGet(this, _GxIdePluginManager_renderLoader, "f").call(this)
138
187
  : __classPrivateFieldGet(this, _GxIdePluginManager_evaluateContentToDisplay, "f").call(this)))));
139
188
  }
@@ -156,13 +205,13 @@ export class GxIdePluginManager {
156
205
  "type": "unknown",
157
206
  "mutable": true,
158
207
  "complexType": {
159
- "original": "PluginData[]",
160
- "resolved": "PluginData[]",
208
+ "original": "PluginGroupData[]",
209
+ "resolved": "PluginGroupData[]",
161
210
  "references": {
162
- "PluginData": {
211
+ "PluginGroupData": {
163
212
  "location": "local",
164
213
  "path": "/home/runner/work/genexus-ide-ui/genexus-ide-ui/src/components/plugin-explorer/plugin-explorer.tsx",
165
- "id": "src/components/plugin-explorer/plugin-explorer.tsx::PluginData"
214
+ "id": "src/components/plugin-explorer/plugin-explorer.tsx::PluginGroupData"
166
215
  }
167
216
  }
168
217
  },
@@ -170,24 +219,24 @@ export class GxIdePluginManager {
170
219
  "optional": false,
171
220
  "docs": {
172
221
  "tags": [],
173
- "text": "List of plugins to display. Usually used to initialize the component."
222
+ "text": "List of plugin groups to display. Each group is rendered as a native\naction-list group (with a separator between groups) and its header caption\nincludes the total number of plugins in the group.\nUsually used to initialize the component."
174
223
  }
175
224
  },
176
225
  "filterCallback": {
177
226
  "type": "unknown",
178
227
  "mutable": false,
179
228
  "complexType": {
180
- "original": "(text: string) => Promise<PluginData[]>",
181
- "resolved": "(text: string) => Promise<PluginData[]>",
229
+ "original": "(\n text: string\n ) => Promise<PluginGroupData[]>",
230
+ "resolved": "(text: string) => Promise<PluginGroupData[]>",
182
231
  "references": {
183
232
  "Promise": {
184
233
  "location": "global",
185
234
  "id": "global::Promise"
186
235
  },
187
- "PluginData": {
236
+ "PluginGroupData": {
188
237
  "location": "local",
189
238
  "path": "/home/runner/work/genexus-ide-ui/genexus-ide-ui/src/components/plugin-explorer/plugin-explorer.tsx",
190
- "id": "src/components/plugin-explorer/plugin-explorer.tsx::PluginData"
239
+ "id": "src/components/plugin-explorer/plugin-explorer.tsx::PluginGroupData"
191
240
  }
192
241
  }
193
242
  },
@@ -259,5 +308,5 @@ export class GxIdePluginManager {
259
308
  }];
260
309
  }
261
310
  }
262
- _GxIdePluginManager_componentLocale = new WeakMap(), _GxIdePluginManager_animateEmptyState = new WeakMap(), _GxIdePluginManager_actionListButtonClickHandler = new WeakMap(), _GxIdePluginManager_mapPluginDataToActionListModel = new WeakMap(), _GxIdePluginManager_pluginsFilterInputHandler = new WeakMap(), _GxIdePluginManager_evaluateContentToDisplay = new WeakMap(), _GxIdePluginManager_renderLoader = new WeakMap(), _GxIdePluginManager_pluginSelectedHandler = new WeakMap();
311
+ _GxIdePluginManager_componentLocale = new WeakMap(), _GxIdePluginManager_animateEmptyState = new WeakMap(), _GxIdePluginManager_actionListButtonClickHandler = new WeakMap(), _GxIdePluginManager_downloadsFormatter = new WeakMap(), _GxIdePluginManager_formatDownloads = new WeakMap(), _GxIdePluginManager_mapPluginToItem = new WeakMap(), _GxIdePluginManager_mapPluginGroupsToActionListModel = new WeakMap(), _GxIdePluginManager_pluginsFilterInputHandler = new WeakMap(), _GxIdePluginManager_evaluateContentToDisplay = new WeakMap(), _GxIdePluginManager_renderLoader = new WeakMap(), _GxIdePluginManager_pluginSelectedHandler = new WeakMap();
263
312
  //# sourceMappingURL=plugin-explorer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-explorer.js","sourceRoot":"","sources":["../../../src/components/plugin-explorer/plugin-explorer.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Host,\n Prop,\n State,\n Element,\n h,\n Watch,\n getAssetPath\n} from \"@stencil/core\";\n\nimport { getIconPath, MercuryBundles } from \"@genexus/mercury\";\nimport { Locale } from \"../../common/locale\";\nimport { config } from \"../../common/config\";\n\nimport { ActionListModel } from \"@genexus/chameleon-controls-library\";\nimport {\n ActionListItemModel,\n ActionListItemModelExtended,\n ActionListItemSeparator\n} from \"@genexus/chameleon-controls-library/dist/types/components/action-list/types\";\n\nconst FILTER_ICON = getIconPath({\n category: \"system\",\n name: \"filters\",\n colorType: \"on-surface\"\n});\n\n// plugin icon if no iconUrl was provided\nconst EXTENSION_ICON_IMG = getAssetPath(\n `./gx-ide-assets/plugin-manager/images/plugin-icon.svg`\n);\n\nconst CSS_BUNDLES: MercuryBundles = [\n \"resets/box-sizing\",\n \"components/list-box\",\n \"components/button\",\n \"components/edit\",\n \"utils/form\",\n \"utils/layout\",\n \"utils/typography\",\n \"utils/spacing\",\n \"chameleon/scrollbar\"\n];\n\n@Component({\n tag: \"gx-ide-plugin-explorer\",\n styleUrl: \"plugin-explorer.scss\",\n shadow: true,\n assetsDirs: [\"gx-ide-assets/plugin-explorer\"]\n})\nexport class GxIdePluginManager {\n /**\n * The component hard-coded strings translations.\n */\n // eslint-disable-next-line @stencil-community/own-props-must-be-private\n #componentLocale: any;\n #animateEmptyState: boolean = false;\n\n @Element() el: HTMLGxIdePluginExplorerElement;\n\n /**\n * If true it will hide the content, and display a loader\n */\n @State() loading: boolean = true;\n\n /**\n * The plugins model as ActionListModel, which is the model the ch-action-list expects\n */\n @State() pluginsActionListModel: ActionListModel = [];\n\n /**\n * List of plugins to display. Usually used to initialize the component.\n */\n @Prop({ mutable: true }) plugins: PluginData[];\n @Watch(\"plugins\")\n pluginsChangedHandler(newPlugins: PluginData[]) {\n this.pluginsActionListModel =\n this.#mapPluginDataToActionListModel(newPlugins);\n this.loading = false;\n }\n\n /**\n * Callback that should be invoked when the user updates the filter.\n * A debounce should be applied before invoking this function.\n */\n @Prop() readonly filterCallback!: (text: string) => Promise<PluginData[]>;\n\n /**\n * Callback that should be invoked when the user clicks or presses Enter\n * on a selected plugin item.\n */\n @Prop() readonly showDetailsCallback!: (pluginId: string) => Promise<void>;\n\n /**\n * Callback that should be invoked when the user clicks on a plugin's action button.\n */\n @Prop() readonly executeActionCallback!: (\n pluginId: string,\n action: PluginAction\n ) => Promise<void>;\n\n async componentWillLoad() {\n this.#componentLocale = await Locale.getComponentStrings(this.el);\n this.pluginsChangedHandler(this.plugins);\n }\n\n #actionListButtonClickHandler =\n (pluginId: string, action: PluginAction) => (event: MouseEvent) => {\n event.stopPropagation();\n this.executeActionCallback(pluginId, action);\n };\n\n #mapPluginDataToActionListModel = (\n pluginsData: PluginData[]\n ): ActionListModel => {\n const pluginsActionListModel: ActionListModel = [];\n const separatorItem: ActionListItemSeparator = { type: \"separator\" };\n\n pluginsData?.forEach((pluginData, index) => {\n const hasActionButton = !!pluginData.action;\n const pluginItem = {\n id: pluginData.id,\n caption: pluginData.name,\n imgSrc: pluginData.iconUrl,\n type: \"actionable\",\n\n additionalInformation: {\n \"stretch-start\": {\n center: [\n {\n part: \"custom-image\",\n jsx: () => (\n <img\n part=\"custom-image\"\n src={pluginData.iconUrl || EXTENSION_ICON_IMG}\n alt={`${this.#componentLocale.logotype.replace(\n \"PLUGIN_NAME_PLACEHOLDER\",\n pluginData.name\n )}`}\n loading=\"lazy\"\n />\n )\n }\n ]\n },\n \"block-end\": {\n start: [\n {\n part: \"custom-description custom-button custom-container custom-brand custom-brand-icon custom-image item__block-end start\",\n jsx: () => (\n <div part=\"custom-container\" title={pluginData.description}>\n <p part=\"custom-description\">{pluginData.description}</p>\n <small part=\"custom-brand\">{pluginData.publisher}</small>\n </div>\n )\n }\n // {\n // slot: \"abcd\"\n // } as ActionListItemAdditionalSlot // slot not working\n ]\n },\n \"stretch-end\": hasActionButton && {\n center: [\n {\n jsx: () => (\n <button\n part=\"custom-button\"\n onClick={this.#actionListButtonClickHandler(\n pluginData.id,\n pluginData.action\n )}\n >\n {pluginData.action}\n </button>\n )\n }\n ]\n }\n }\n } as ActionListItemModel;\n if (index !== 0) {\n pluginsActionListModel.push(separatorItem);\n }\n pluginsActionListModel.push(pluginItem);\n });\n\n return pluginsActionListModel;\n };\n\n #pluginsFilterInputHandler = async (\n event: CustomEvent<string> | InputEvent\n ) => {\n this.loading = true;\n const filterValue = event.detail as string;\n this.plugins = await this.filterCallback(filterValue);\n };\n\n #evaluateContentToDisplay = () => {\n const pluginsToDisplay = this.pluginsActionListModel.length;\n return pluginsToDisplay ? (\n <ch-action-list-render\n model={this.pluginsActionListModel}\n class=\"list-box\"\n selection=\"single\"\n onSelectedItemsChange={this.#pluginSelectedHandler}\n >\n {/* <p slot=\"abcd\">Slot for \"abcd\" id</p> */}\n </ch-action-list-render>\n ) : (\n <gx-ide-empty-state\n isAnimated={this.#animateEmptyState}\n class=\"recent-objects__empty-state\"\n stateIconSrc={FILTER_ICON}\n stateTitle={this.#componentLocale.emptyStateTitle}\n stateDescription={this.#componentLocale.emptyStateDescription}\n ></gx-ide-empty-state>\n );\n };\n\n #renderLoader = () => {\n this.#animateEmptyState = true;\n return (\n <gx-ide-loader\n loaderTitle={this.#componentLocale.loaderTitle}\n description={this.#componentLocale.loaderDescription}\n show\n ></gx-ide-loader>\n );\n };\n\n #pluginSelectedHandler = (\n event: CustomEvent<ActionListItemModelExtended[]>\n ) => {\n const eventType = event.detail[0]?.item.type;\n if (eventType === \"actionable\") {\n const pluginId = event.detail[0].item.id;\n this.showDetailsCallback(pluginId);\n }\n };\n\n render() {\n return (\n <Host class=\"widget\">\n <ch-theme model={CSS_BUNDLES}></ch-theme>\n\n <div class=\"outer-container field-group\">\n <ch-edit\n id=\"search-plugins-input\"\n class=\"input\"\n accessibleName={this.#componentLocale.accessibleName}\n placeholder={this.#componentLocale.searchInputPlaceholder}\n debounce={config.inputDebounce}\n onInput={this.#pluginsFilterInputHandler}\n type=\"search\"\n ></ch-edit>\n <div class=\"inner-container\">\n {this.loading\n ? this.#renderLoader()\n : this.#evaluateContentToDisplay()}\n </div>\n </div>\n </Host>\n );\n }\n}\n\nexport type PluginData = {\n id: string;\n iconUrl: string;\n name: string;\n description: string;\n publisher: string;\n action?: PluginAction;\n};\n\nexport type PluginAction = \"install\" | \"update\";\n"]}
1
+ {"version":3,"file":"plugin-explorer.js","sourceRoot":"","sources":["../../../src/components/plugin-explorer/plugin-explorer.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Host,\n Prop,\n State,\n Element,\n h,\n Watch,\n getAssetPath\n} from \"@stencil/core\";\n\nimport { getIconPath, MercuryBundles } from \"@genexus/mercury\";\nimport { Locale } from \"../../common/locale\";\nimport { config } from \"../../common/config\";\n\nimport { ActionListModel } from \"@genexus/chameleon-controls-library\";\nimport {\n ActionListItemActionable,\n ActionListItemGroup,\n ActionListItemModelExtended,\n ActionListItemSeparator\n} from \"@genexus/chameleon-controls-library/dist/types/components/action-list/types\";\n\nconst FILTER_ICON = getIconPath({\n category: \"system\",\n name: \"filters\",\n colorType: \"on-surface\"\n});\n\n// plugin icon if no iconUrl was provided\nconst EXTENSION_ICON_IMG = getAssetPath(\n `./gx-ide-assets/plugin-explorer/images/plugin-icon.svg`\n);\n\nconst CSS_BUNDLES: MercuryBundles = [\n \"resets/box-sizing\",\n \"components/list-box\",\n \"components/button\",\n \"components/edit\",\n \"utils/form\",\n \"utils/layout\",\n \"utils/typography\",\n \"utils/spacing\",\n \"chameleon/scrollbar\"\n];\n\nconst SEARCH_ICON = getIconPath({\n category: \"system\",\n name: \"search\",\n colorType: \"on-surface\"\n});\n\nconst STAR_ICON = getIconPath({\n category: \"system\",\n name: \"star-fill\",\n colorType: \"warning\"\n});\n\nconst DOWNLOAD_ICON = getIconPath({\n category: \"system\",\n name: \"download\",\n colorType: \"on-surface\"\n});\n\n@Component({\n tag: \"gx-ide-plugin-explorer\",\n styleUrl: \"plugin-explorer.scss\",\n shadow: true,\n assetsDirs: [\"gx-ide-assets/plugin-explorer\"]\n})\nexport class GxIdePluginManager {\n /**\n * The component hard-coded strings translations.\n */\n // eslint-disable-next-line @stencil-community/own-props-must-be-private\n #componentLocale: any;\n #animateEmptyState: boolean = false;\n\n @Element() el: HTMLGxIdePluginExplorerElement;\n\n /**\n * If true it will hide the content, and display a loader\n */\n @State() loading: boolean = true;\n\n /**\n * The plugins model as ActionListModel, which is the model the ch-action-list expects\n */\n @State() pluginsActionListModel: ActionListModel = [];\n\n /**\n * List of plugin groups to display. Each group is rendered as a native\n * action-list group (with a separator between groups) and its header caption\n * includes the total number of plugins in the group.\n * Usually used to initialize the component.\n */\n @Prop({ mutable: true }) plugins: PluginGroupData[];\n @Watch(\"plugins\")\n pluginsChangedHandler(newPlugins: PluginGroupData[]) {\n this.pluginsActionListModel =\n this.#mapPluginGroupsToActionListModel(newPlugins);\n this.loading = false;\n }\n\n /**\n * Callback that should be invoked when the user updates the filter.\n * A debounce should be applied before invoking this function.\n */\n @Prop() readonly filterCallback!: (\n text: string\n ) => Promise<PluginGroupData[]>;\n\n /**\n * Callback that should be invoked when the user clicks or presses Enter\n * on a selected plugin item.\n */\n @Prop() readonly showDetailsCallback!: (pluginId: string) => Promise<void>;\n\n /**\n * Callback that should be invoked when the user clicks on a plugin's action button.\n */\n @Prop() readonly executeActionCallback!: (\n pluginId: string,\n action: PluginAction\n ) => Promise<void>;\n\n async componentWillLoad() {\n this.#componentLocale = await Locale.getComponentStrings(this.el);\n this.pluginsChangedHandler(this.plugins);\n }\n\n #actionListButtonClickHandler =\n (pluginId: string, action: PluginAction) => (event: MouseEvent) => {\n event.stopPropagation();\n this.executeActionCallback(pluginId, action);\n };\n\n // Formats a raw downloads count into a compact string (e.g. 4000 -> \"4K\").\n #downloadsFormatter = new Intl.NumberFormat(undefined, {\n notation: \"compact\",\n maximumFractionDigits: 1\n });\n\n #formatDownloads = (value: number): string => {\n const numericValue = typeof value === \"number\" ? value : Number(value);\n return Number.isFinite(numericValue)\n ? this.#downloadsFormatter.format(numericValue)\n : `${value}`;\n };\n\n #mapPluginToItem = (pluginData: PluginData): ActionListItemActionable => {\n const hasActionButton = !!pluginData.action;\n const hasDownloads =\n pluginData.downloads !== undefined && pluginData.downloads !== null;\n const hasRating =\n pluginData.rating !== undefined && pluginData.rating !== null;\n const hasMeta = hasDownloads || hasRating;\n\n const pluginItem = {\n id: pluginData.id,\n caption: pluginData.name,\n imgSrc: pluginData.iconUrl,\n type: \"actionable\",\n\n additionalInformation: {\n \"stretch-start\": {\n center: [\n {\n part: \"custom-image\",\n jsx: () => (\n <img\n part=\"custom-image\"\n src={pluginData.iconUrl || EXTENSION_ICON_IMG}\n alt={`${this.#componentLocale.logotype.replace(\n \"PLUGIN_NAME_PLACEHOLDER\",\n pluginData.name\n )}`}\n loading=\"lazy\"\n />\n )\n }\n ]\n },\n \"inline-caption\": hasMeta && {\n end: [\n {\n part: \"custom-meta\",\n jsx: () => (\n <div part=\"custom-meta\">\n {hasDownloads && (\n <span\n part=\"custom-meta-item custom-downloads\"\n title={`${pluginData.downloads}`}\n >\n <ch-image\n part=\"custom-meta-icon custom-downloads-icon\"\n src={DOWNLOAD_ICON}\n ></ch-image>\n {this.#formatDownloads(pluginData.downloads)}\n </span>\n )}\n {hasRating && (\n <span\n part=\"custom-meta-item custom-rating\"\n title={`${pluginData.rating}`}\n >\n <ch-image\n part=\"custom-meta-icon custom-rating-icon\"\n src={STAR_ICON}\n ></ch-image>\n {pluginData.rating}\n </span>\n )}\n </div>\n )\n }\n ]\n },\n \"block-end\": {\n start: [\n {\n part: \"custom-description custom-button custom-container custom-brand custom-footer custom-meta custom-meta-item custom-meta-icon custom-progress custom-progress-label custom-progress-bar item__block-end start\",\n jsx: () => (\n <div part=\"custom-container\">\n <p part=\"custom-description\" title={pluginData.description}>\n {pluginData.description}\n </p>\n <div part=\"custom-footer\">\n <small part=\"custom-brand\">{pluginData.publisher}</small>\n {pluginData.installProgress ? (\n <div part=\"custom-progress\">\n <span part=\"custom-progress-label\">\n {pluginData.installProgress.percent}%\n </span>\n <gx-ide-progress-bar\n part=\"custom-progress-bar\"\n class=\"plain\"\n minimal\n active\n stateType=\"in-progress\"\n progress={pluginData.installProgress.percent}\n ></gx-ide-progress-bar>\n </div>\n ) : hasActionButton ? (\n <button\n class=\"button\"\n part=\"custom-button\"\n onClick={this.#actionListButtonClickHandler(\n pluginData.id,\n pluginData.action\n )}\n >\n {pluginData.action}\n </button>\n ) : null}\n </div>\n </div>\n )\n }\n // {\n // slot: \"abcd\"\n // } as ActionListItemAdditionalSlot // slot not working\n ]\n }\n }\n } as ActionListItemActionable;\n\n return pluginItem;\n };\n\n // Builds the ch-action-list model from groups: one native action-list group\n // per PluginGroupData, plus a separator between groups. The group header only\n // renders a plain-text caption (no custom pill element is supported), so the\n // per-group total is shown as a number appended to the caption.\n #mapPluginGroupsToActionListModel = (\n groups: PluginGroupData[]\n ): ActionListModel => {\n const model: ActionListModel = [];\n const separatorItem: ActionListItemSeparator = { type: \"separator\" };\n\n groups?.forEach(group => {\n // Skip empty groups so we don't render a header with \"(0)\".\n if (!group.plugins?.length) {\n return;\n }\n if (model.length > 0) {\n model.push(separatorItem);\n }\n model.push({\n id: group.id,\n type: \"group\",\n caption: `${group.caption} (${group.plugins.length})`,\n expandable: group.expandable ?? true,\n expanded: group.expanded ?? true,\n items: group.plugins.map(plugin => this.#mapPluginToItem(plugin))\n } as ActionListItemGroup);\n });\n\n return model;\n };\n\n #pluginsFilterInputHandler = async (\n event: CustomEvent<string> | InputEvent\n ) => {\n this.loading = true;\n const filterValue = event.detail as string;\n this.plugins = await this.filterCallback(filterValue);\n };\n\n #evaluateContentToDisplay = () => {\n const pluginsToDisplay = this.pluginsActionListModel.length;\n return pluginsToDisplay ? (\n <ch-action-list-render\n model={this.pluginsActionListModel}\n class=\"list-box\"\n selection=\"single\"\n onSelectedItemsChange={this.#pluginSelectedHandler}\n >\n {/* <p slot=\"abcd\">Slot for \"abcd\" id</p> */}\n </ch-action-list-render>\n ) : (\n <gx-ide-empty-state\n isAnimated={this.#animateEmptyState}\n class=\"recent-objects__empty-state\"\n stateIconSrc={FILTER_ICON}\n stateTitle={this.#componentLocale.emptyStateTitle}\n stateDescription={this.#componentLocale.emptyStateDescription}\n ></gx-ide-empty-state>\n );\n };\n\n #renderLoader = () => {\n this.#animateEmptyState = true;\n return (\n <gx-ide-loader\n loaderTitle={this.#componentLocale.loaderTitle}\n description={this.#componentLocale.loaderDescription}\n show\n ></gx-ide-loader>\n );\n };\n\n #pluginSelectedHandler = (\n event: CustomEvent<ActionListItemModelExtended[]>\n ) => {\n const eventType = event.detail[0]?.item.type;\n if (eventType === \"actionable\") {\n const pluginId = event.detail[0].item.id;\n this.showDetailsCallback(pluginId);\n }\n };\n\n render() {\n return (\n <Host class=\"widget\">\n <ch-theme model={CSS_BUNDLES}></ch-theme>\n\n <div class=\"outer-container field-group\">\n <ch-edit\n id=\"search-plugins-input\"\n class=\"input\"\n accessibleName={this.#componentLocale.accessibleName}\n placeholder={this.#componentLocale.searchInputPlaceholder}\n debounce={config.inputDebounce}\n onInput={this.#pluginsFilterInputHandler}\n type=\"search\"\n startImgSrc={SEARCH_ICON}\n ></ch-edit>\n <div class=\"inner-container\">\n {this.loading\n ? this.#renderLoader()\n : this.#evaluateContentToDisplay()}\n </div>\n </div>\n </Host>\n );\n }\n}\n\nexport type PluginGroupData = {\n id: string;\n /**\n * Group header text. The total number of plugins in the group is appended\n * automatically, e.g. \"Installed (12)\".\n */\n caption: string;\n /**\n * Whether the group can be collapsed/expanded. Defaults to `true`.\n */\n expandable?: boolean;\n /**\n * Whether the group starts expanded. Defaults to `true`.\n */\n expanded?: boolean;\n plugins: PluginData[];\n};\n\nexport type PluginData = {\n id: string;\n iconUrl: string;\n name: string;\n description: string;\n publisher: string;\n action?: PluginAction;\n downloads?: number;\n rating?: string | number;\n // When set, the card shows a determinate progress bar instead of the action button.\n installProgress?: PluginInstallProgress;\n};\n\nexport type PluginInstallProgress = {\n phase: \"download\" | \"install\";\n percent: number;\n};\n\nexport type PluginAction = \"install\" | \"update\";\n"]}
@@ -1,4 +1,4 @@
1
- import { proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal/client';
1
+ import { proxyCustomElement, HTMLElement, getAssetPath, h, Host } from '@stencil/core/internal/client';
2
2
  import { g as getIconPath } from './mer-animated-dots.js';
3
3
  import 'lit';
4
4
  import 'lit/directives/when.js';
@@ -6,7 +6,7 @@ import 'lit/directives/if-defined.js';
6
6
  import { L as Locale } from './locale.js';
7
7
  import { c as config } from './config.js';
8
8
 
9
- const dbPropertiesConfiguratorCss = "button.button-secondary{border-color:var(--color-border-neutral-default)}:host{display:grid;block-size:100%;overflow:hidden;grid-template-rows:max-content 1fr max-content;background-color:var(--color-accent-surface-elevation-1);color:var(--color-text-neutral-default)}.section{display:contents}.hero{display:flex;align-items:flex-start;gap:var(--spacing-gap-xl);padding-block:var(--spacing-padding-l);padding-inline:var(--spacing-padding-l);border-block-end:var(--size-1) solid var(--color-border-surface-on-elevation-1)}.hero__text{flex:1;min-inline-size:0}.hero__title{margin:0;color:var(--color-text-neutral-default)}.hero__description{margin-block:var(--spacing-gap-xs) 0;margin-inline:0;color:var(--color-text-neutral-disabled);text-wrap:pretty}.hero__badge{flex:none;display:grid;place-items:center;inline-size:44px;block-size:44px;border-radius:var(--border-radius-m);background-color:var(--color-accent-item-hover);color:var(--color-icon-primary-default)}.main{overflow:auto;display:flex;flex-direction:column;gap:var(--spacing-gap-xxl);padding-block:var(--spacing-padding-l);padding-inline:var(--spacing-padding-l)}.field-section{display:flex;flex-direction:column;gap:var(--spacing-gap-l)}.field-section+.field-section{padding-block-start:var(--spacing-padding-xl);border-block-start:var(--size-1) solid var(--color-border-surface-on-elevation-1)}.field-section__head{display:flex;align-items:baseline;gap:var(--spacing-gap-m)}.field-section__title{font-family:var(--font-family-body);font-weight:var(--font-style-semi-bold);font-size:var(--font-size-caption-m);letter-spacing:0.06em;text-transform:uppercase;color:var(--color-text-neutral-neutral)}.fields{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:var(--spacing-gap-l)}.field--full{grid-column:1/-1}.field--checkbox{display:flex;flex-direction:column;gap:var(--spacing-gap-xs)}.field--checkbox .field__row{display:flex;align-items:center;gap:var(--spacing-gap-xs)}.field--checkbox .label{margin:0;cursor:pointer}.field--checkbox .field__hint{margin:0;margin-inline-start:calc(var(--spacing-gap-m) + var(--spacing-gap-m));color:var(--color-text-neutral-disabled);text-wrap:pretty}.footer{padding-block:var(--spacing-padding-m);padding-inline:var(--spacing-padding-l)}";
9
+ const dbPropertiesConfiguratorCss = "button.button-secondary{border-color:var(--color-border-neutral-default)}:host{display:grid;block-size:100%;overflow:hidden;grid-template-rows:max-content 1fr max-content;background-color:var(--color-accent-surface-elevation-1);color:var(--color-text-neutral-default)}.section{display:contents}.hero{display:flex;align-items:flex-start;gap:var(--spacing-gap-xl);padding-block:var(--spacing-padding-l);padding-inline:var(--spacing-padding-l);border-block-end:var(--size-1) solid var(--color-border-surface-on-elevation-1)}.hero__text{flex:1;min-inline-size:0}.hero__description{margin-block:var(--spacing-gap-xs) 0;margin-inline:0;color:var(--color-text-neutral-neutral)}.hero__badge{flex:none;display:grid;place-items:center;pointer-events:none;inline-size:44px;block-size:44px;border-radius:var(--border-radius-m);background-color:var(--color-accent-item-hover);color:var(--color-icon-primary-default)}.main{overflow:auto;display:flex;flex-direction:column;gap:var(--spacing-gap-xxl);padding-block:var(--spacing-padding-l);padding-inline:var(--spacing-padding-l)}.field-section{display:flex;flex-direction:column;gap:var(--spacing-gap-l)}.field-section+.field-section{padding-block-start:var(--spacing-padding-xl);border-block-start:var(--size-1) solid var(--color-border-surface-on-elevation-1)}.field-section__head{display:flex;align-items:baseline;gap:var(--spacing-gap-m)}.field-section__title{font-family:var(--font-family-body);font-weight:var(--font-style-semi-bold);font-size:var(--font-size-caption-m);letter-spacing:0.06em;text-transform:uppercase;color:var(--color-text-neutral-neutral)}.fields{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:var(--spacing-gap-l)}.field--full{grid-column:1/-1}.field--checkbox{display:flex;flex-direction:column;gap:var(--spacing-gap-xs)}.field--checkbox .field__row{display:flex;align-items:center;gap:var(--spacing-gap-xs)}.field--checkbox .label{margin:0;cursor:pointer}.field--checkbox .field__hint{margin:0;margin-inline-start:calc(var(--spacing-gap-m) + var(--spacing-gap-m));color:var(--color-text-neutral-disabled);text-wrap:pretty}.footer{padding-block:var(--spacing-padding-m);padding-inline:var(--spacing-padding-l)}";
10
10
 
11
11
  var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) {
12
12
  if (kind === "a" && !f)
@@ -24,7 +24,7 @@ var __classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) ||
24
24
  throw new TypeError("Cannot write private member to an object whose class did not declare it");
25
25
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
26
26
  };
27
- var _GxIdeDbPropertiesConfigurator_componentLocale, _GxIdeDbPropertiesConfigurator_getValue, _GxIdeDbPropertiesConfigurator_hasPendingRequired, _GxIdeDbPropertiesConfigurator_buildComboModel, _GxIdeDbPropertiesConfigurator_isAuthField, _GxIdeDbPropertiesConfigurator_hasTrustedConnection, _GxIdeDbPropertiesConfigurator_valueChangeHandler, _GxIdeDbPropertiesConfigurator_cancelButtonClickedHandler, _GxIdeDbPropertiesConfigurator_confirmButtonClickedHandler, _GxIdeDbPropertiesConfigurator_renderControl, _GxIdeDbPropertiesConfigurator_renderField, _GxIdeDbPropertiesConfigurator_renderSection;
27
+ var _GxIdeDbPropertiesConfigurator_componentLocale, _GxIdeDbPropertiesConfigurator_chShortcutsEl, _GxIdeDbPropertiesConfigurator_shortcutsSrc, _GxIdeDbPropertiesConfigurator_getValue, _GxIdeDbPropertiesConfigurator_hasPendingRequired, _GxIdeDbPropertiesConfigurator_buildComboModel, _GxIdeDbPropertiesConfigurator_isAuthField, _GxIdeDbPropertiesConfigurator_hasTrustedConnection, _GxIdeDbPropertiesConfigurator_valueChangeHandler, _GxIdeDbPropertiesConfigurator_cancelButtonClickedHandler, _GxIdeDbPropertiesConfigurator_confirmButtonClickedHandler, _GxIdeDbPropertiesConfigurator_renderControl, _GxIdeDbPropertiesConfigurator_renderField, _GxIdeDbPropertiesConfigurator_renderSection;
28
28
  const CSS_BUNDLES = [
29
29
  "resets/box-sizing",
30
30
  "components/button",
@@ -58,6 +58,8 @@ const GxIdeDbPropertiesConfigurator$1 = /*@__PURE__*/ proxyCustomElement(class G
58
58
  this.__attachShadow();
59
59
  // eslint-disable-next-line @stencil-community/own-props-must-be-private
60
60
  _GxIdeDbPropertiesConfigurator_componentLocale.set(this, void 0);
61
+ _GxIdeDbPropertiesConfigurator_chShortcutsEl.set(this, void 0);
62
+ _GxIdeDbPropertiesConfigurator_shortcutsSrc.set(this, getAssetPath(`./gx-ide-assets/db-properties-configurator/shortcuts.json`));
61
63
  _GxIdeDbPropertiesConfigurator_getValue.set(this, (field) => { var _a; return (_a = field.value) !== null && _a !== void 0 ? _a : ""; });
62
64
  _GxIdeDbPropertiesConfigurator_hasPendingRequired.set(this, () => {
63
65
  var _a;
@@ -88,6 +90,9 @@ const GxIdeDbPropertiesConfigurator$1 = /*@__PURE__*/ proxyCustomElement(class G
88
90
  });
89
91
  _GxIdeDbPropertiesConfigurator_confirmButtonClickedHandler.set(this, () => {
90
92
  var _a;
93
+ if (__classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_hasPendingRequired, "f").call(this)) {
94
+ return;
95
+ }
91
96
  (_a = this.confirmCallback) === null || _a === void 0 ? void 0 : _a.call(this);
92
97
  });
93
98
  // #region Renders
@@ -129,10 +134,15 @@ const GxIdeDbPropertiesConfigurator$1 = /*@__PURE__*/ proxyCustomElement(class G
129
134
  async componentWillLoad() {
130
135
  __classPrivateFieldSet(this, _GxIdeDbPropertiesConfigurator_componentLocale, await Locale.getComponentStrings(this.el), "f");
131
136
  }
137
+ /**
138
+ * Suspends or reactivates the shortcuts.
139
+ */
140
+ async suspendShortcuts(suspendShortcuts) {
141
+ __classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_chShortcutsEl, "f").suspend = suspendShortcuts;
142
+ }
132
143
  // #endregion Renders
133
144
  render() {
134
145
  var _a;
135
- const title = __classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_componentLocale, "f").header.title;
136
146
  const description = __classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_componentLocale, "f").header.description;
137
147
  const sections = __classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_componentLocale, "f").sections;
138
148
  const allFields = (_a = this.properties) !== null && _a !== void 0 ? _a : [];
@@ -146,7 +156,7 @@ const GxIdeDbPropertiesConfigurator$1 = /*@__PURE__*/ proxyCustomElement(class G
146
156
  const connectionFields = hasAuthSection
147
157
  ? allFields.filter(field => !__classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_isAuthField, "f").call(this, field))
148
158
  : allFields;
149
- return (h(Host, { class: "widget" }, h("ch-theme", { model: CSS_BUNDLES }), h("section", { class: "section" }, h("div", { class: "hero" }, h("div", { class: "hero__text" }, h("h1", { class: "hero__title subtitle-semi-bold-l" }, title), description && (h("p", { class: "hero__description body-regular-s" }, description))), h("div", { class: "hero__badge", "aria-hidden": "true" }, h("ch-image", { class: "icon-xl", src: DATABASE_ICON }))), h("div", { class: "main scrollable" }, connectionFields.length > 0 &&
159
+ return (h(Host, { class: "widget" }, h("ch-theme", { model: CSS_BUNDLES }), h("ch-shortcuts", { src: __classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_shortcutsSrc, "f"), ref: (el) => (__classPrivateFieldSet(this, _GxIdeDbPropertiesConfigurator_chShortcutsEl, el, "f")) }), h("section", { class: "section" }, h("div", { class: "hero" }, h("div", { class: "hero__badge", "aria-hidden": "true" }, h("ch-image", { class: "icon-xl", src: DATABASE_ICON, type: "mask" })), h("div", { class: "hero__text" }, description && (h("p", { class: "hero__description body-regular-s" }, description)))), h("div", { class: "main scrollable" }, connectionFields.length > 0 &&
150
160
  __classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_renderSection, "f").call(this, sections.connection, connectionFields), hasAuthSection &&
151
161
  authFields.length > 0 &&
152
162
  __classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_renderSection, "f").call(this, sections.authentication, authFields)), h("footer", { class: "dialog-footer-with-border footer" }, h("div", { class: "buttons-spacer" }, h("button", { class: "button-secondary", id: "button-cancel", type: "button", onClick: __classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_cancelButtonClickedHandler, "f"), part: "button-cancel" }, __classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_componentLocale, "f").footer.btnCancel), h("button", { class: "button-primary", id: "button-confirm", type: "button", disabled: __classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_hasPendingRequired, "f").call(this), onClick: __classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_confirmButtonClickedHandler, "f"), part: "button-confirm" }, __classPrivateFieldGet(this, _GxIdeDbPropertiesConfigurator_componentLocale, "f").footer.btnConfirm))))));
@@ -158,9 +168,10 @@ const GxIdeDbPropertiesConfigurator$1 = /*@__PURE__*/ proxyCustomElement(class G
158
168
  "properties": [16],
159
169
  "cancelCallback": [16],
160
170
  "confirmCallback": [16],
161
- "propertyChangeCallback": [16]
171
+ "propertyChangeCallback": [16],
172
+ "suspendShortcuts": [64]
162
173
  }]);
163
- _GxIdeDbPropertiesConfigurator_componentLocale = new WeakMap(), _GxIdeDbPropertiesConfigurator_getValue = new WeakMap(), _GxIdeDbPropertiesConfigurator_hasPendingRequired = new WeakMap(), _GxIdeDbPropertiesConfigurator_buildComboModel = new WeakMap(), _GxIdeDbPropertiesConfigurator_isAuthField = new WeakMap(), _GxIdeDbPropertiesConfigurator_hasTrustedConnection = new WeakMap(), _GxIdeDbPropertiesConfigurator_valueChangeHandler = new WeakMap(), _GxIdeDbPropertiesConfigurator_cancelButtonClickedHandler = new WeakMap(), _GxIdeDbPropertiesConfigurator_confirmButtonClickedHandler = new WeakMap(), _GxIdeDbPropertiesConfigurator_renderControl = new WeakMap(), _GxIdeDbPropertiesConfigurator_renderField = new WeakMap(), _GxIdeDbPropertiesConfigurator_renderSection = new WeakMap();
174
+ _GxIdeDbPropertiesConfigurator_componentLocale = new WeakMap(), _GxIdeDbPropertiesConfigurator_chShortcutsEl = new WeakMap(), _GxIdeDbPropertiesConfigurator_shortcutsSrc = new WeakMap(), _GxIdeDbPropertiesConfigurator_getValue = new WeakMap(), _GxIdeDbPropertiesConfigurator_hasPendingRequired = new WeakMap(), _GxIdeDbPropertiesConfigurator_buildComboModel = new WeakMap(), _GxIdeDbPropertiesConfigurator_isAuthField = new WeakMap(), _GxIdeDbPropertiesConfigurator_hasTrustedConnection = new WeakMap(), _GxIdeDbPropertiesConfigurator_valueChangeHandler = new WeakMap(), _GxIdeDbPropertiesConfigurator_cancelButtonClickedHandler = new WeakMap(), _GxIdeDbPropertiesConfigurator_confirmButtonClickedHandler = new WeakMap(), _GxIdeDbPropertiesConfigurator_renderControl = new WeakMap(), _GxIdeDbPropertiesConfigurator_renderField = new WeakMap(), _GxIdeDbPropertiesConfigurator_renderSection = new WeakMap();
164
175
  function defineCustomElement$1() {
165
176
  if (typeof customElements === "undefined") {
166
177
  return;
@@ -1 +1 @@
1
- {"file":"gx-ide-db-properties-configurator.js","mappings":"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","names":["GxIdeDbPropertiesConfigurator"],"sources":["src/components/db-properties-configurator/db-properties-configurator.scss?tag=gx-ide-db-properties-configurator&encapsulation=shadow","src/components/db-properties-configurator/db-properties-configurator.tsx"],"sourcesContent":["@import \"../../global/temporary-mercury-overrides/_button.scss\";\n\n// The component reproduces the Mercury \"Set required properties\" connection\n// dialog. Real Mercury classes (.dialog-header-with-border, .field-group-\n// justified-end, .label, .input, .combo-box, .button-*, typography) come from\n// the loaded bundles; the rules below only add the scaffolding Mercury does\n// not define (hero banner, badge, close button, field help) using DS tokens.\n\n:host {\n display: grid;\n block-size: 100%;\n overflow: hidden;\n grid-template-rows: max-content 1fr max-content;\n background-color: var(--color-accent-surface-elevation-1);\n color: var(--color-text-neutral-default);\n}\n\n.section {\n // section is just for semantics; the host owns the grid.\n display: contents;\n}\n\n// #region Hero\n.hero {\n display: flex;\n align-items: flex-start;\n gap: var(--spacing-gap-xl);\n padding-block: var(--spacing-padding-l);\n padding-inline: var(--spacing-padding-l);\n border-block-end: var(--size-1) solid\n var(--color-border-surface-on-elevation-1);\n}\n\n.hero__text {\n flex: 1;\n min-inline-size: 0;\n}\n\n.hero__title {\n margin: 0;\n color: var(--color-text-neutral-default);\n}\n\n.hero__description {\n margin-block: var(--spacing-gap-xs) 0;\n margin-inline: 0;\n color: var(--color-text-neutral-disabled);\n text-wrap: pretty;\n}\n\n.hero__badge {\n flex: none;\n display: grid;\n place-items: center;\n inline-size: 44px;\n block-size: 44px;\n border-radius: var(--border-radius-m);\n background-color: var(--color-accent-item-hover);\n color: var(--color-icon-primary-default);\n}\n// #endregion Hero\n\n// #region Body\n.main {\n overflow: auto;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-xxl);\n padding-block: var(--spacing-padding-l);\n padding-inline: var(--spacing-padding-l);\n}\n\n// Field section: a quiet uppercase header + its field grid. Sections after\n// the first get a divider so the body reads as structured groups.\n.field-section {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-l);\n}\n\n.field-section + .field-section {\n padding-block-start: var(--spacing-padding-xl);\n border-block-start: var(--size-1) solid\n var(--color-border-surface-on-elevation-1);\n}\n\n.field-section__head {\n display: flex;\n align-items: baseline;\n gap: var(--spacing-gap-m);\n}\n\n.field-section__title {\n font-family: var(--font-family-body);\n font-weight: var(--font-style-semi-bold);\n font-size: var(--font-size-caption-m);\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--color-text-neutral-neutral);\n}\n\n// Two-column field grid. Each field occupies one column; checkbox fields\n// (and any other field marked as full-width) span the entire row, forcing\n// the following fields to wrap onto the next row.\n.fields {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: var(--spacing-gap-l);\n}\n\n.field--full {\n grid-column: 1 / -1;\n}\n\n// Inline checkbox field: control + label on the same row, optional help text\n// flows below aligned with the label.\n.field--checkbox {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-xs);\n}\n\n.field--checkbox .field__row {\n display: flex;\n align-items: center;\n gap: var(--spacing-gap-xs);\n}\n\n.field--checkbox .label {\n margin: 0;\n cursor: pointer;\n}\n\n// Help text below a checkbox, indented to align with the label past the box.\n.field--checkbox .field__hint {\n margin: 0;\n margin-inline-start: calc(var(--spacing-gap-m) + var(--spacing-gap-m));\n color: var(--color-text-neutral-disabled);\n text-wrap: pretty;\n}\n// #endregion Body\n\n// #region Footer\n.footer {\n padding-block: var(--spacing-padding-m);\n padding-inline: var(--spacing-padding-l);\n}\n// #endregion Footer\n","import { Component, Host, Prop, Element, h } from \"@stencil/core\";\n\nimport { MercuryBundles, getIconPath } from \"@genexus/mercury\";\nimport { ComboBoxModel } from \"@genexus/chameleon-controls-library\";\n\nimport { Locale } from \"../../common/locale\";\nimport { config } from \"../../common/config\";\n\nconst CSS_BUNDLES: MercuryBundles = [\n \"resets/box-sizing\",\n \"components/button\",\n \"components/combo-box\",\n \"components/edit\",\n \"components/icon\",\n \"utils/form\",\n \"utils/layout\",\n \"utils/typography\",\n \"utils/spacing\",\n \"chameleon/scrollbar\"\n];\n\nconst DATABASE_ICON = getIconPath({\n category: \"system\",\n name: \"database\",\n colorType: \"primary\"\n});\n\n/**\n * Name of the property that toggles integrated security. Its presence in\n * `properties` is what drives the rendering of the Authentication section.\n */\nconst TRUSTED_CONNECTION = \"TRUSTED_CONNECTION\";\nconst USER_ID = \"USER_ID\";\nconst USER_PASSWORD = \"USER_PASSWORD\";\n\n/** Category that groups the authentication-related fields. */\nconst AUTH_CATEGORY = \"authentication\";\n\n@Component({\n tag: \"gx-ide-db-properties-configurator\",\n styleUrl: \"db-properties-configurator.scss\",\n shadow: true,\n assetsDirs: [\"gx-ide-assets/db-properties-configurator\"]\n})\nexport class GxIdeDbPropertiesConfigurator {\n // eslint-disable-next-line @stencil-community/own-props-must-be-private\n #componentLocale: any;\n\n @Element() el: HTMLGxIdeDbPropertiesConfiguratorElement;\n\n /**\n * The list of properties to configure. Acts as the single source of truth:\n * the dialog reads each value from `DSPropertyField.value` and notifies the\n * host of every edit through `propertyChangeCallback`.\n */\n @Prop() readonly properties: DSPropertyField[] = [];\n\n /**\n * Callback invoked when the user cancels the configuration.\n */\n @Prop() readonly cancelCallback!: CancelCallback;\n\n /**\n * Callback invoked when the user confirms the configuration.\n */\n @Prop() readonly confirmCallback!: ConfirmCallback;\n\n /**\n * Callback invoked on every input change. Receives the name of the\n * property that changed and its new value. The host is expected to apply\n * the change and push an updated `properties` array back to the component.\n */\n @Prop() readonly propertyChangeCallback!: PropertyChangeCallback;\n\n async componentWillLoad() {\n this.#componentLocale = await Locale.getComponentStrings(this.el);\n }\n\n #getValue = (field: DSPropertyField): string => field.value ?? \"\";\n\n #hasPendingRequired = (): boolean =>\n (this.properties ?? []).some(\n field => field.missing && this.#getValue(field).trim() === \"\"\n );\n\n #buildComboModel = (field: DSPropertyField): ComboBoxModel =>\n (field.standardValues ?? []).map(value => ({ value, caption: value }));\n\n #isAuthField = (field: DSPropertyField): boolean =>\n field.name === TRUSTED_CONNECTION ||\n field.name === USER_ID ||\n field.name === USER_PASSWORD ||\n field.category?.toLowerCase() === AUTH_CATEGORY;\n\n /** Whether the host sent the TRUSTED_CONNECTION property. Only then is the\n * Authentication section rendered. */\n #hasTrustedConnection = (): boolean =>\n (this.properties ?? []).some(field => field.name === TRUSTED_CONNECTION);\n\n #valueChangeHandler =\n (name: string) => (event: CustomEvent<string> | InputEvent) => {\n const detail = (event as CustomEvent<string>).detail;\n const value =\n typeof detail === \"string\"\n ? detail\n : ((event.target as HTMLChEditElement)?.value ?? \"\");\n this.propertyChangeCallback(name, value);\n };\n\n #cancelButtonClickedHandler = () => {\n this.cancelCallback?.();\n };\n\n #confirmButtonClickedHandler = () => {\n this.confirmCallback?.();\n };\n\n // #region Renders\n\n #renderControl = (field: DSPropertyField) => {\n const fieldId = `field-${field.name}`;\n const value = this.#getValue(field);\n\n switch (field.control) {\n case \"password\":\n return (\n <ch-edit\n id={fieldId}\n class=\"input\"\n type=\"password\"\n showPasswordButton\n debounce={config.inputDebounce}\n value={value}\n onInput={this.#valueChangeHandler(field.name)}\n ></ch-edit>\n );\n\n case \"combo\":\n return (\n <ch-combo-box-render\n id={fieldId}\n class=\"combo-box\"\n value={value}\n model={this.#buildComboModel(field)}\n onInput={this.#valueChangeHandler(field.name)}\n onChange={this.#valueChangeHandler(field.name)}\n ></ch-combo-box-render>\n );\n\n case \"checkbox\":\n return (\n <ch-checkbox\n id={fieldId}\n class=\"checkbox\"\n value={value}\n checkedValue=\"Yes\"\n unCheckedValue=\"No\"\n onInput={this.#valueChangeHandler(field.name)}\n ></ch-checkbox>\n );\n\n case \"combo-editable\":\n return (\n <ch-combo-box-render\n id={fieldId}\n class=\"combo-box\"\n suggest\n suggestDebounce={config.inputDebounce}\n value={value}\n model={this.#buildComboModel(field)}\n onInput={this.#valueChangeHandler(field.name)}\n onChange={this.#valueChangeHandler(field.name)}\n part={`combo-box combo-box--editable combo-box--${field.name}`}\n ></ch-combo-box-render>\n );\n\n case \"custom\":\n case \"readonly\":\n return (\n <ch-edit\n id={fieldId}\n class=\"input\"\n readonly\n value={value}\n part={`input input--${field.control} input--${field.name}`}\n ></ch-edit>\n );\n\n // \"text\"\n default:\n return (\n <ch-edit\n id={fieldId}\n class=\"input\"\n debounce={config.inputDebounce}\n value={value}\n onInput={this.#valueChangeHandler(field.name)}\n part={`input input--text input--${field.name}`}\n ></ch-edit>\n );\n }\n };\n\n #renderField = (field: DSPropertyField) => {\n const fieldId = `field-${field.name}`;\n const isReadonly =\n field.control === \"readonly\" || field.control === \"custom\";\n const isCheckbox = field.control === \"checkbox\";\n\n if (isCheckbox) {\n return (\n <div class=\"field field--checkbox field--full\" key={field.name}>\n <div class=\"field__row\">\n {this.#renderControl(field)}\n <label class=\"label\" htmlFor={fieldId}>\n {field.label}\n </label>\n </div>\n {field.description && (\n <p class=\"field__hint body-regular-s\">{field.description}</p>\n )}\n </div>\n );\n }\n\n return (\n <div class=\"field field-block\" key={field.name}>\n <label\n class={{ \"label\": true, \"label--disabled\": isReadonly }}\n htmlFor={fieldId}\n >\n {field.label}\n </label>\n\n {this.#renderControl(field)}\n </div>\n );\n };\n\n #renderSection = (title: string, fields: DSPropertyField[]) => (\n <section class=\"field-section\">\n <div class=\"field-section__head\">\n <span class=\"field-section__title\">{title}</span>\n </div>\n <div class=\"fields\">{fields.map(this.#renderField)}</div>\n </section>\n );\n\n // #endregion Renders\n\n render() {\n const title = this.#componentLocale.header.title;\n const description = this.#componentLocale.header.description;\n const sections = this.#componentLocale.sections;\n\n const allFields = this.properties ?? [];\n const hasAuthSection = this.#hasTrustedConnection();\n\n // The Authentication section is only rendered when TRUSTED_CONNECTION is\n // present; otherwise every field stays in the always-present Connection\n // section so nothing is dropped.\n const authFields = hasAuthSection\n ? allFields.filter(this.#isAuthField)\n : [];\n const connectionFields = hasAuthSection\n ? allFields.filter(field => !this.#isAuthField(field))\n : allFields;\n\n return (\n <Host class=\"widget\">\n <ch-theme model={CSS_BUNDLES}></ch-theme>\n <section class=\"section\">\n <div class=\"hero\">\n <div class=\"hero__text\">\n <h1 class=\"hero__title subtitle-semi-bold-l\">{title}</h1>\n {description && (\n <p class=\"hero__description body-regular-s\">{description}</p>\n )}\n </div>\n <div class=\"hero__badge\" aria-hidden=\"true\">\n <ch-image class=\"icon-xl\" src={DATABASE_ICON}></ch-image>\n </div>\n </div>\n\n <div class=\"main scrollable\">\n {connectionFields.length > 0 &&\n this.#renderSection(sections.connection, connectionFields)}\n\n {hasAuthSection &&\n authFields.length > 0 &&\n this.#renderSection(sections.authentication, authFields)}\n </div>\n\n <footer class=\"dialog-footer-with-border footer\">\n <div class=\"buttons-spacer\">\n <button\n class=\"button-secondary\"\n id=\"button-cancel\"\n type=\"button\"\n onClick={this.#cancelButtonClickedHandler}\n part=\"button-cancel\"\n >\n {this.#componentLocale.footer.btnCancel}\n </button>\n <button\n class=\"button-primary\"\n id=\"button-confirm\"\n type=\"button\"\n disabled={this.#hasPendingRequired()}\n onClick={this.#confirmButtonClickedHandler}\n part=\"button-confirm\"\n >\n {this.#componentLocale.footer.btnConfirm}\n </button>\n </div>\n </footer>\n </section>\n </Host>\n );\n }\n}\n\nexport type DSControlKind =\n | \"checkbox\"\n | \"text\"\n | \"password\"\n | \"combo\"\n | \"combo-editable\"\n | \"custom\"\n | \"readonly\";\n\nexport interface DSPropertyField {\n /** `PropertyData.name` — key used to set the property value. */\n name: string;\n /** `definition.displayName`. */\n label: string;\n /** `definition.description` (rendered below the control). */\n description?: string;\n /** `definition.category` (optional grouping). */\n category?: string;\n\n /** Control resolved by the host. */\n control: DSControlKind;\n\n /** `PropertyData.value` (masked when password). */\n value: string;\n /** `required && isDefault` (host detection). */\n missing: boolean;\n\n // combos:\n /** `PropertyData.standardValues`. */\n standardValues?: string[];\n /** `PropertyData.isStandardValuesExclusive`. */\n exclusive?: boolean;\n}\n\nexport type CancelCallback = () => void | Promise<void>;\n\nexport type ConfirmCallback = () => void | Promise<void>;\n\nexport type PropertyChangeCallback = (\n name: string,\n value: string\n) => void | Promise<void>;\n"],"version":3}
1
+ {"file":"gx-ide-db-properties-configurator.js","mappings":";;;;;;;;AAAA,MAAM,2BAA2B,GAAG,gpEAAgpE;;;;;;;;;;;;;;;;;;;ACgBprE,MAAM,WAAW,GAAmB;IAClC,mBAAmB;IACnB,mBAAmB;IACnB,sBAAsB;IACtB,iBAAiB;IACjB,iBAAiB;IACjB,YAAY;IACZ,cAAc;IACd,kBAAkB;IAClB,eAAe;IACf,qBAAqB;CACtB,CAAC;AAEF,MAAM,aAAa,GAAG,WAAW,CAAC;IAChC,QAAQ,EAAE,QAAQ;IAClB,IAAI,EAAE,UAAU;IAChB,SAAS,EAAE,SAAS;CACrB,CAAC,CAAC;AAEH;;;;AAIA,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAChD,MAAM,OAAO,GAAG,SAAS,CAAC;AAC1B,MAAM,aAAa,GAAG,eAAe,CAAC;AAEtC;AACA,MAAM,aAAa,GAAG,gBAAgB,CAAC;MAQ1BA,+BAA6B;;;;;;QAExC,iEAAsB;QAEtB,+DAAuC;QACvC,sDAAgB,YAAY,CAC1B,2DAA2D,CAC5D,EAAC;QAwCF,kDAAY,CAAC,KAAsB,eAAa,OAAA,MAAA,KAAK,CAAC,KAAK,mCAAI,EAAE,CAAA,EAAA,EAAC;QAElE,4DAAsB;;YACpB,OAAA,CAAC,MAAA,IAAI,CAAC,UAAU,mCAAI,EAAE,EAAE,IAAI,CAC1B,KAAK,IAAI,KAAK,CAAC,OAAO,IAAI,uBAAA,IAAI,+CAAU,MAAd,IAAI,EAAW,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAC9D,CAAA;SAAA,EAAC;QAEJ,yDAAmB,CAAC,KAAsB,eACxC,OAAA,CAAC,MAAA,KAAK,CAAC,cAAc,mCAAI,EAAE,EAAE,GAAG,CAAC,KAAK,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA,EAAA,EAAC;QAEzE,qDAAe,CAAC,KAAsB;;YACpC,OAAA,KAAK,CAAC,IAAI,KAAK,kBAAkB;gBACjC,KAAK,CAAC,IAAI,KAAK,OAAO;gBACtB,KAAK,CAAC,IAAI,KAAK,aAAa;gBAC5B,CAAA,MAAA,KAAK,CAAC,QAAQ,0CAAE,WAAW,EAAE,MAAK,aAAa,CAAA;SAAA,EAAC;;;QAIlD,8DAAwB,gBACtB,OAAA,CAAC,MAAA,IAAI,CAAC,UAAU,mCAAI,EAAE,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAA,EAAA,EAAC;QAE3E,4DACE,CAAC,IAAY,KAAK,CAAC,KAAuC;;YACxD,MAAM,MAAM,GAAI,KAA6B,CAAC,MAAM,CAAC;YACrD,MAAM,KAAK,GACT,OAAO,MAAM,KAAK,QAAQ;kBACtB,MAAM;mBACL,MAAA,MAAC,KAAK,CAAC,MAA4B,0CAAE,KAAK,mCAAI,EAAE,CAAC,CAAC;YACzD,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;SAC1C,EAAC;QAEJ,oEAA8B;;YAC5B,MAAA,IAAI,CAAC,cAAc,oDAAI,CAAC;SACzB,EAAC;QAEF,qEAA+B;;YAC7B,IAAI,uBAAA,IAAI,yDAAoB,MAAxB,IAAI,CAAsB,EAAE;gBAC9B,OAAO;aACR;YACD,MAAA,IAAI,CAAC,eAAe,oDAAI,CAAC;SAC1B,EAAC;;QAIF,uDAAiB,CAAC,KAAsB;YACtC,MAAM,OAAO,GAAG,SAAS,KAAK,CAAC,IAAI,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,uBAAA,IAAI,+CAAU,MAAd,IAAI,EAAW,KAAK,CAAC,CAAC;YAEpC,QAAQ,KAAK,CAAC,OAAO;gBACnB,KAAK,UAAU;oBACb,QACE,eACE,EAAE,EAAE,OAAO,EACX,KAAK,EAAC,OAAO,EACb,IAAI,EAAC,UAAU,EACf,kBAAkB,QAClB,QAAQ,EAAE,MAAM,CAAC,aAAa,EAC9B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,uBAAA,IAAI,yDAAoB,MAAxB,IAAI,EAAqB,KAAK,CAAC,IAAI,CAAC,GACpC,EACX;gBAEJ,KAAK,OAAO;oBACV,QACE,2BACE,EAAE,EAAE,OAAO,EACX,KAAK,EAAC,WAAW,EACjB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,uBAAA,IAAI,sDAAiB,MAArB,IAAI,EAAkB,KAAK,CAAC,EACnC,OAAO,EAAE,uBAAA,IAAI,yDAAoB,MAAxB,IAAI,EAAqB,KAAK,CAAC,IAAI,CAAC,EAC7C,QAAQ,EAAE,uBAAA,IAAI,yDAAoB,MAAxB,IAAI,EAAqB,KAAK,CAAC,IAAI,CAAC,GACzB,EACvB;gBAEJ,KAAK,UAAU;oBACb,QACE,mBACE,EAAE,EAAE,OAAO,EACX,KAAK,EAAC,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,YAAY,EAAC,KAAK,EAClB,cAAc,EAAC,IAAI,EACnB,OAAO,EAAE,uBAAA,IAAI,yDAAoB,MAAxB,IAAI,EAAqB,KAAK,CAAC,IAAI,CAAC,GAChC,EACf;gBAEJ,KAAK,gBAAgB;oBACnB,QACE,2BACE,EAAE,EAAE,OAAO,EACX,KAAK,EAAC,WAAW,EACjB,OAAO,QACP,eAAe,EAAE,MAAM,CAAC,aAAa,EACrC,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,uBAAA,IAAI,sDAAiB,MAArB,IAAI,EAAkB,KAAK,CAAC,EACnC,OAAO,EAAE,uBAAA,IAAI,yDAAoB,MAAxB,IAAI,EAAqB,KAAK,CAAC,IAAI,CAAC,EAC7C,QAAQ,EAAE,uBAAA,IAAI,yDAAoB,MAAxB,IAAI,EAAqB,KAAK,CAAC,IAAI,CAAC,EAC9C,IAAI,EAAE,4CAA4C,KAAK,CAAC,IAAI,EAAE,GACzC,EACvB;gBAEJ,KAAK,QAAQ,CAAC;gBACd,KAAK,UAAU;oBACb,QACE,eACE,EAAE,EAAE,OAAO,EACX,KAAK,EAAC,OAAO,EACb,QAAQ,QACR,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,gBAAgB,KAAK,CAAC,OAAO,WAAW,KAAK,CAAC,IAAI,EAAE,GACjD,EACX;;gBAGJ;oBACE,QACE,eACE,EAAE,EAAE,OAAO,EACX,KAAK,EAAC,OAAO,EACb,QAAQ,EAAE,MAAM,CAAC,aAAa,EAC9B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,uBAAA,IAAI,yDAAoB,MAAxB,IAAI,EAAqB,KAAK,CAAC,IAAI,CAAC,EAC7C,IAAI,EAAE,4BAA4B,KAAK,CAAC,IAAI,EAAE,GACrC,EACX;aACL;SACF,EAAC;QAEF,qDAAe,CAAC,KAAsB;YACpC,MAAM,OAAO,GAAG,SAAS,KAAK,CAAC,IAAI,EAAE,CAAC;YACtC,MAAM,UAAU,GACd,KAAK,CAAC,OAAO,KAAK,UAAU,IAAI,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC;YAC7D,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,KAAK,UAAU,CAAC;YAEhD,IAAI,UAAU,EAAE;gBACd,QACE,WAAK,KAAK,EAAC,mCAAmC,EAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAC5D,WAAK,KAAK,EAAC,YAAY,IACpB,uBAAA,IAAI,oDAAe,MAAnB,IAAI,EAAgB,KAAK,CAAC,EAC3B,aAAO,KAAK,EAAC,OAAO,EAAC,OAAO,EAAE,OAAO,IAClC,KAAK,CAAC,KAAK,CACN,CACJ,EACL,KAAK,CAAC,WAAW,KAChB,SAAG,KAAK,EAAC,4BAA4B,IAAE,KAAK,CAAC,WAAW,CAAK,CAC9D,CACG,EACN;aACH;YAED,QACE,WAAK,KAAK,EAAC,mBAAmB,EAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAC5C,aACE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,UAAU,EAAE,EACvD,OAAO,EAAE,OAAO,IAEf,KAAK,CAAC,KAAK,CACN,EAEP,uBAAA,IAAI,oDAAe,MAAnB,IAAI,EAAgB,KAAK,CAAC,CACvB,EACN;SACH,EAAC;QAEF,uDAAiB,CAAC,KAAa,EAAE,MAAyB,MACxD,eAAS,KAAK,EAAC,eAAe,IAC5B,WAAK,KAAK,EAAC,qBAAqB,IAC9B,YAAM,KAAK,EAAC,sBAAsB,IAAE,KAAK,CAAQ,CAC7C,EACN,WAAK,KAAK,EAAC,QAAQ,IAAE,MAAM,CAAC,GAAG,CAAC,uBAAA,IAAI,kDAAa,CAAC,CAAO,CACjD,CACX,EAAC;0BA1M+C,EAAE;;;;;IAmBnD,MAAM,iBAAiB;QACrB,uBAAA,IAAI,kDAAoB,MAAM,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC,MAAA,CAAC;KACnE;;;;IAMD,MAAM,gBAAgB,CAAC,gBAAyB;QAC9C,uBAAA,IAAI,oDAAe,CAAC,OAAO,GAAG,gBAAgB,CAAC;KAChD;;IAiLD,MAAM;;QACJ,MAAM,WAAW,GAAG,uBAAA,IAAI,sDAAiB,CAAC,MAAM,CAAC,WAAW,CAAC;QAC7D,MAAM,QAAQ,GAAG,uBAAA,IAAI,sDAAiB,CAAC,QAAQ,CAAC;QAEhD,MAAM,SAAS,GAAG,MAAA,IAAI,CAAC,UAAU,mCAAI,EAAE,CAAC;QACxC,MAAM,cAAc,GAAG,uBAAA,IAAI,2DAAsB,MAA1B,IAAI,CAAwB,CAAC;;;;QAKpD,MAAM,UAAU,GAAG,cAAc;cAC7B,SAAS,CAAC,MAAM,CAAC,uBAAA,IAAI,kDAAa,CAAC;cACnC,EAAE,CAAC;QACP,MAAM,gBAAgB,GAAG,cAAc;cACnC,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,uBAAA,IAAI,kDAAa,MAAjB,IAAI,EAAc,KAAK,CAAC,CAAC;cACpD,SAAS,CAAC;QAEd,QACE,EAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,IAClB,gBAAU,KAAK,EAAE,WAAW,GAAa,EACzC,oBACE,GAAG,EAAE,uBAAA,IAAI,mDAAc,EACvB,GAAG,EAAE,CAAC,EAA0B,MAC7B,uBAAA,IAAI,gDAAkB,EAA4B,MAAA,CAAC,GAExC,EAChB,eAAS,KAAK,EAAC,SAAS,IACtB,WAAK,KAAK,EAAC,MAAM,IACf,WAAK,KAAK,EAAC,aAAa,iBAAa,MAAM,IACzC,gBACE,KAAK,EAAC,SAAS,EACf,GAAG,EAAE,aAAa,EAClB,IAAI,EAAC,MAAM,GACD,CACR,EACN,WAAK,KAAK,EAAC,YAAY,IACpB,WAAW,KACV,SAAG,KAAK,EAAC,kCAAkC,IAAE,WAAW,CAAK,CAC9D,CACG,CACF,EAEN,WAAK,KAAK,EAAC,iBAAiB,IACzB,gBAAgB,CAAC,MAAM,GAAG,CAAC;YAC1B,uBAAA,IAAI,oDAAe,MAAnB,IAAI,EAAgB,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC,EAE3D,cAAc;YACb,UAAU,CAAC,MAAM,GAAG,CAAC;YACrB,uBAAA,IAAI,oDAAe,MAAnB,IAAI,EAAgB,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC,CACtD,EAEN,cAAQ,KAAK,EAAC,kCAAkC,IAC9C,WAAK,KAAK,EAAC,gBAAgB,IACzB,cACE,KAAK,EAAC,kBAAkB,EACxB,EAAE,EAAC,eAAe,EAClB,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,uBAAA,IAAI,iEAA4B,EACzC,IAAI,EAAC,eAAe,IAEnB,uBAAA,IAAI,sDAAiB,CAAC,MAAM,CAAC,SAAS,CAChC,EACT,cACE,KAAK,EAAC,gBAAgB,EACtB,EAAE,EAAC,gBAAgB,EACnB,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,uBAAA,IAAI,yDAAoB,MAAxB,IAAI,CAAsB,EACpC,OAAO,EAAE,uBAAA,IAAI,kEAA6B,EAC1C,IAAI,EAAC,gBAAgB,IAEpB,uBAAA,IAAI,sDAAiB,CAAC,MAAM,CAAC,UAAU,CACjC,CACL,CACC,CACD,CACL,EACP;KACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","names":["GxIdeDbPropertiesConfigurator"],"sources":["src/components/db-properties-configurator/db-properties-configurator.scss?tag=gx-ide-db-properties-configurator&encapsulation=shadow","src/components/db-properties-configurator/db-properties-configurator.tsx"],"sourcesContent":["@import \"../../global/temporary-mercury-overrides/_button.scss\";\n\n// The component reproduces the Mercury \"Set required properties\" connection\n// dialog. Real Mercury classes (.dialog-header-with-border, .field-group-\n// justified-end, .label, .input, .combo-box, .button-*, typography) come from\n// the loaded bundles; the rules below only add the scaffolding Mercury does\n// not define (hero banner, badge, close button, field help) using DS tokens.\n\n:host {\n display: grid;\n block-size: 100%;\n overflow: hidden;\n grid-template-rows: max-content 1fr max-content;\n background-color: var(--color-accent-surface-elevation-1);\n color: var(--color-text-neutral-default);\n}\n\n.section {\n // section is just for semantics; the host owns the grid.\n display: contents;\n}\n\n// #region Hero\n.hero {\n display: flex;\n align-items: flex-start;\n gap: var(--spacing-gap-xl);\n padding-block: var(--spacing-padding-l);\n padding-inline: var(--spacing-padding-l);\n border-block-end: var(--size-1) solid\n var(--color-border-surface-on-elevation-1);\n}\n\n.hero__text {\n flex: 1;\n min-inline-size: 0;\n}\n\n.hero__description {\n margin-block: var(--spacing-gap-xs) 0;\n margin-inline: 0;\n color: var(--color-text-neutral-neutral);\n}\n\n.hero__badge {\n flex: none;\n display: grid;\n place-items: center;\n // Decorative badge: neutralize ch-image's hover/active/focus state swap\n // (driven by the [data-ch-image] attribute it adds to this parent), which\n // otherwise makes the icon flicker and read as clickable.\n pointer-events: none;\n inline-size: 44px;\n block-size: 44px;\n border-radius: var(--border-radius-m);\n background-color: var(--color-accent-item-hover);\n color: var(--color-icon-primary-default);\n}\n// #endregion Hero\n\n// #region Body\n.main {\n overflow: auto;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-xxl);\n padding-block: var(--spacing-padding-l);\n padding-inline: var(--spacing-padding-l);\n}\n\n// Field section: a quiet uppercase header + its field grid. Sections after\n// the first get a divider so the body reads as structured groups.\n.field-section {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-l);\n}\n\n.field-section + .field-section {\n padding-block-start: var(--spacing-padding-xl);\n border-block-start: var(--size-1) solid\n var(--color-border-surface-on-elevation-1);\n}\n\n.field-section__head {\n display: flex;\n align-items: baseline;\n gap: var(--spacing-gap-m);\n}\n\n.field-section__title {\n font-family: var(--font-family-body);\n font-weight: var(--font-style-semi-bold);\n font-size: var(--font-size-caption-m);\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--color-text-neutral-neutral);\n}\n\n// Two-column field grid. Each field occupies one column; checkbox fields\n// (and any other field marked as full-width) span the entire row, forcing\n// the following fields to wrap onto the next row.\n.fields {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: var(--spacing-gap-l);\n}\n\n.field--full {\n grid-column: 1 / -1;\n}\n\n// Inline checkbox field: control + label on the same row, optional help text\n// flows below aligned with the label.\n.field--checkbox {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-xs);\n}\n\n.field--checkbox .field__row {\n display: flex;\n align-items: center;\n gap: var(--spacing-gap-xs);\n}\n\n.field--checkbox .label {\n margin: 0;\n cursor: pointer;\n}\n\n// Help text below a checkbox, indented to align with the label past the box.\n.field--checkbox .field__hint {\n margin: 0;\n margin-inline-start: calc(var(--spacing-gap-m) + var(--spacing-gap-m));\n color: var(--color-text-neutral-disabled);\n text-wrap: pretty;\n}\n// #endregion Body\n\n// #region Footer\n.footer {\n padding-block: var(--spacing-padding-m);\n padding-inline: var(--spacing-padding-l);\n}\n// #endregion Footer\n","import {\n Component,\n Host,\n Prop,\n Element,\n Method,\n getAssetPath,\n h\n} from \"@stencil/core\";\n\nimport { MercuryBundles, getIconPath } from \"@genexus/mercury\";\nimport { ComboBoxModel } from \"@genexus/chameleon-controls-library\";\n\nimport { Locale } from \"../../common/locale\";\nimport { config } from \"../../common/config\";\n\nconst CSS_BUNDLES: MercuryBundles = [\n \"resets/box-sizing\",\n \"components/button\",\n \"components/combo-box\",\n \"components/edit\",\n \"components/icon\",\n \"utils/form\",\n \"utils/layout\",\n \"utils/typography\",\n \"utils/spacing\",\n \"chameleon/scrollbar\"\n];\n\nconst DATABASE_ICON = getIconPath({\n category: \"system\",\n name: \"database\",\n colorType: \"primary\"\n});\n\n/**\n * Name of the property that toggles integrated security. Its presence in\n * `properties` is what drives the rendering of the Authentication section.\n */\nconst TRUSTED_CONNECTION = \"TRUSTED_CONNECTION\";\nconst USER_ID = \"USER_ID\";\nconst USER_PASSWORD = \"USER_PASSWORD\";\n\n/** Category that groups the authentication-related fields. */\nconst AUTH_CATEGORY = \"authentication\";\n\n@Component({\n tag: \"gx-ide-db-properties-configurator\",\n styleUrl: \"db-properties-configurator.scss\",\n shadow: true,\n assetsDirs: [\"gx-ide-assets/db-properties-configurator\"]\n})\nexport class GxIdeDbPropertiesConfigurator {\n // eslint-disable-next-line @stencil-community/own-props-must-be-private\n #componentLocale: any;\n\n #chShortcutsEl: HTMLChShortcutsElement;\n #shortcutsSrc = getAssetPath(\n `./gx-ide-assets/db-properties-configurator/shortcuts.json`\n );\n\n @Element() el: HTMLGxIdeDbPropertiesConfiguratorElement;\n\n /**\n * The list of properties to configure. Acts as the single source of truth:\n * the dialog reads each value from `DSPropertyField.value` and notifies the\n * host of every edit through `propertyChangeCallback`.\n */\n @Prop() readonly properties: DSPropertyField[] = [];\n\n /**\n * Callback invoked when the user cancels the configuration.\n */\n @Prop() readonly cancelCallback!: CancelCallback;\n\n /**\n * Callback invoked when the user confirms the configuration.\n */\n @Prop() readonly confirmCallback!: ConfirmCallback;\n\n /**\n * Callback invoked on every input change. Receives the name of the\n * property that changed and its new value. The host is expected to apply\n * the change and push an updated `properties` array back to the component.\n */\n @Prop() readonly propertyChangeCallback!: PropertyChangeCallback;\n\n async componentWillLoad() {\n this.#componentLocale = await Locale.getComponentStrings(this.el);\n }\n\n /**\n * Suspends or reactivates the shortcuts.\n */\n @Method()\n async suspendShortcuts(suspendShortcuts: boolean) {\n this.#chShortcutsEl.suspend = suspendShortcuts;\n }\n\n #getValue = (field: DSPropertyField): string => field.value ?? \"\";\n\n #hasPendingRequired = (): boolean =>\n (this.properties ?? []).some(\n field => field.missing && this.#getValue(field).trim() === \"\"\n );\n\n #buildComboModel = (field: DSPropertyField): ComboBoxModel =>\n (field.standardValues ?? []).map(value => ({ value, caption: value }));\n\n #isAuthField = (field: DSPropertyField): boolean =>\n field.name === TRUSTED_CONNECTION ||\n field.name === USER_ID ||\n field.name === USER_PASSWORD ||\n field.category?.toLowerCase() === AUTH_CATEGORY;\n\n /** Whether the host sent the TRUSTED_CONNECTION property. Only then is the\n * Authentication section rendered. */\n #hasTrustedConnection = (): boolean =>\n (this.properties ?? []).some(field => field.name === TRUSTED_CONNECTION);\n\n #valueChangeHandler =\n (name: string) => (event: CustomEvent<string> | InputEvent) => {\n const detail = (event as CustomEvent<string>).detail;\n const value =\n typeof detail === \"string\"\n ? detail\n : ((event.target as HTMLChEditElement)?.value ?? \"\");\n this.propertyChangeCallback(name, value);\n };\n\n #cancelButtonClickedHandler = () => {\n this.cancelCallback?.();\n };\n\n #confirmButtonClickedHandler = () => {\n if (this.#hasPendingRequired()) {\n return;\n }\n this.confirmCallback?.();\n };\n\n // #region Renders\n\n #renderControl = (field: DSPropertyField) => {\n const fieldId = `field-${field.name}`;\n const value = this.#getValue(field);\n\n switch (field.control) {\n case \"password\":\n return (\n <ch-edit\n id={fieldId}\n class=\"input\"\n type=\"password\"\n showPasswordButton\n debounce={config.inputDebounce}\n value={value}\n onInput={this.#valueChangeHandler(field.name)}\n ></ch-edit>\n );\n\n case \"combo\":\n return (\n <ch-combo-box-render\n id={fieldId}\n class=\"combo-box\"\n value={value}\n model={this.#buildComboModel(field)}\n onInput={this.#valueChangeHandler(field.name)}\n onChange={this.#valueChangeHandler(field.name)}\n ></ch-combo-box-render>\n );\n\n case \"checkbox\":\n return (\n <ch-checkbox\n id={fieldId}\n class=\"checkbox\"\n value={value}\n checkedValue=\"Yes\"\n unCheckedValue=\"No\"\n onInput={this.#valueChangeHandler(field.name)}\n ></ch-checkbox>\n );\n\n case \"combo-editable\":\n return (\n <ch-combo-box-render\n id={fieldId}\n class=\"combo-box\"\n suggest\n suggestDebounce={config.inputDebounce}\n value={value}\n model={this.#buildComboModel(field)}\n onInput={this.#valueChangeHandler(field.name)}\n onChange={this.#valueChangeHandler(field.name)}\n part={`combo-box combo-box--editable combo-box--${field.name}`}\n ></ch-combo-box-render>\n );\n\n case \"custom\":\n case \"readonly\":\n return (\n <ch-edit\n id={fieldId}\n class=\"input\"\n readonly\n value={value}\n part={`input input--${field.control} input--${field.name}`}\n ></ch-edit>\n );\n\n // \"text\"\n default:\n return (\n <ch-edit\n id={fieldId}\n class=\"input\"\n debounce={config.inputDebounce}\n value={value}\n onInput={this.#valueChangeHandler(field.name)}\n part={`input input--text input--${field.name}`}\n ></ch-edit>\n );\n }\n };\n\n #renderField = (field: DSPropertyField) => {\n const fieldId = `field-${field.name}`;\n const isReadonly =\n field.control === \"readonly\" || field.control === \"custom\";\n const isCheckbox = field.control === \"checkbox\";\n\n if (isCheckbox) {\n return (\n <div class=\"field field--checkbox field--full\" key={field.name}>\n <div class=\"field__row\">\n {this.#renderControl(field)}\n <label class=\"label\" htmlFor={fieldId}>\n {field.label}\n </label>\n </div>\n {field.description && (\n <p class=\"field__hint body-regular-s\">{field.description}</p>\n )}\n </div>\n );\n }\n\n return (\n <div class=\"field field-block\" key={field.name}>\n <label\n class={{ \"label\": true, \"label--disabled\": isReadonly }}\n htmlFor={fieldId}\n >\n {field.label}\n </label>\n\n {this.#renderControl(field)}\n </div>\n );\n };\n\n #renderSection = (title: string, fields: DSPropertyField[]) => (\n <section class=\"field-section\">\n <div class=\"field-section__head\">\n <span class=\"field-section__title\">{title}</span>\n </div>\n <div class=\"fields\">{fields.map(this.#renderField)}</div>\n </section>\n );\n\n // #endregion Renders\n\n render() {\n const description = this.#componentLocale.header.description;\n const sections = this.#componentLocale.sections;\n\n const allFields = this.properties ?? [];\n const hasAuthSection = this.#hasTrustedConnection();\n\n // The Authentication section is only rendered when TRUSTED_CONNECTION is\n // present; otherwise every field stays in the always-present Connection\n // section so nothing is dropped.\n const authFields = hasAuthSection\n ? allFields.filter(this.#isAuthField)\n : [];\n const connectionFields = hasAuthSection\n ? allFields.filter(field => !this.#isAuthField(field))\n : allFields;\n\n return (\n <Host class=\"widget\">\n <ch-theme model={CSS_BUNDLES}></ch-theme>\n <ch-shortcuts\n src={this.#shortcutsSrc}\n ref={(el: HTMLChShortcutsElement) =>\n (this.#chShortcutsEl = el as HTMLChShortcutsElement)\n }\n ></ch-shortcuts>\n <section class=\"section\">\n <div class=\"hero\">\n <div class=\"hero__badge\" aria-hidden=\"true\">\n <ch-image\n class=\"icon-xl\"\n src={DATABASE_ICON}\n type=\"mask\"\n ></ch-image>\n </div>\n <div class=\"hero__text\">\n {description && (\n <p class=\"hero__description body-regular-s\">{description}</p>\n )}\n </div>\n </div>\n\n <div class=\"main scrollable\">\n {connectionFields.length > 0 &&\n this.#renderSection(sections.connection, connectionFields)}\n\n {hasAuthSection &&\n authFields.length > 0 &&\n this.#renderSection(sections.authentication, authFields)}\n </div>\n\n <footer class=\"dialog-footer-with-border footer\">\n <div class=\"buttons-spacer\">\n <button\n class=\"button-secondary\"\n id=\"button-cancel\"\n type=\"button\"\n onClick={this.#cancelButtonClickedHandler}\n part=\"button-cancel\"\n >\n {this.#componentLocale.footer.btnCancel}\n </button>\n <button\n class=\"button-primary\"\n id=\"button-confirm\"\n type=\"button\"\n disabled={this.#hasPendingRequired()}\n onClick={this.#confirmButtonClickedHandler}\n part=\"button-confirm\"\n >\n {this.#componentLocale.footer.btnConfirm}\n </button>\n </div>\n </footer>\n </section>\n </Host>\n );\n }\n}\n\nexport type DSControlKind =\n | \"checkbox\"\n | \"text\"\n | \"password\"\n | \"combo\"\n | \"combo-editable\"\n | \"custom\"\n | \"readonly\";\n\nexport interface DSPropertyField {\n /** `PropertyData.name` — key used to set the property value. */\n name: string;\n /** `definition.displayName`. */\n label: string;\n /** `definition.description` (rendered below the control). */\n description?: string;\n /** `definition.category` (optional grouping). */\n category?: string;\n\n /** Control resolved by the host. */\n control: DSControlKind;\n\n /** `PropertyData.value` (masked when password). */\n value: string;\n /** `required && isDefault` (host detection). */\n missing: boolean;\n\n // combos:\n /** `PropertyData.standardValues`. */\n standardValues?: string[];\n /** `PropertyData.isStandardValuesExclusive`. */\n exclusive?: boolean;\n}\n\nexport type CancelCallback = () => void | Promise<void>;\n\nexport type ConfirmCallback = () => void | Promise<void>;\n\nexport type PropertyChangeCallback = (\n name: string,\n value: string\n) => void | Promise<void>;\n"],"version":3}