@genexus/genexus-ide-ui 3.2.21 → 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 (52) hide show
  1. package/dist/cjs/genexus-ide-ui.cjs.js +1 -1
  2. package/dist/cjs/gx-ide-plugin-details.cjs.entry.js +31 -13
  3. package/dist/cjs/gx-ide-plugin-details.cjs.entry.js.map +1 -1
  4. package/dist/cjs/gx-ide-plugin-explorer.cjs.entry.js +97 -48
  5. package/dist/cjs/gx-ide-plugin-explorer.cjs.entry.js.map +1 -1
  6. package/dist/cjs/gx-ide-progress-bar.cjs.entry.js +1 -1
  7. package/dist/cjs/gx-ide-progress-bar.cjs.entry.js.map +1 -1
  8. package/dist/cjs/loader.cjs.js +1 -1
  9. package/dist/collection/components/_helpers/progress-bar/progress-bar.css +10 -0
  10. package/dist/collection/components/plugin-details/gx-ide-assets/plugin-details/langs/plugin-details.lang.en.json +3 -1
  11. package/dist/collection/components/plugin-details/gx-ide-assets/plugin-details/langs/plugin-details.lang.ja.json +3 -1
  12. package/dist/collection/components/plugin-details/gx-ide-assets/plugin-details/langs/plugin-details.lang.zh.json +3 -1
  13. package/dist/collection/components/plugin-details/plugin-details.css +7 -1
  14. package/dist/collection/components/plugin-details/plugin-details.js +75 -16
  15. package/dist/collection/components/plugin-details/plugin-details.js.map +1 -1
  16. package/dist/collection/components/plugin-explorer/plugin-explorer.css +83 -26
  17. package/dist/collection/components/plugin-explorer/plugin-explorer.js +105 -56
  18. package/dist/collection/components/plugin-explorer/plugin-explorer.js.map +1 -1
  19. package/dist/components/gx-ide-plugin-details.js +40 -14
  20. package/dist/components/gx-ide-plugin-details.js.map +1 -1
  21. package/dist/components/gx-ide-plugin-explorer.js +107 -52
  22. package/dist/components/gx-ide-plugin-explorer.js.map +1 -1
  23. package/dist/components/progress-bar.js +1 -1
  24. package/dist/components/progress-bar.js.map +1 -1
  25. package/dist/esm/genexus-ide-ui.js +1 -1
  26. package/dist/esm/gx-ide-plugin-details.entry.js +31 -13
  27. package/dist/esm/gx-ide-plugin-details.entry.js.map +1 -1
  28. package/dist/esm/gx-ide-plugin-explorer.entry.js +97 -48
  29. package/dist/esm/gx-ide-plugin-explorer.entry.js.map +1 -1
  30. package/dist/esm/gx-ide-progress-bar.entry.js +1 -1
  31. package/dist/esm/gx-ide-progress-bar.entry.js.map +1 -1
  32. package/dist/esm/loader.js +1 -1
  33. package/dist/genexus-ide-ui/genexus-ide-ui.esm.js +1 -1
  34. package/dist/genexus-ide-ui/genexus-ide-ui.esm.js.map +1 -1
  35. package/dist/genexus-ide-ui/gx-ide-assets/plugin-details/langs/plugin-details.lang.en.json +3 -1
  36. package/dist/genexus-ide-ui/gx-ide-assets/plugin-details/langs/plugin-details.lang.ja.json +3 -1
  37. package/dist/genexus-ide-ui/gx-ide-assets/plugin-details/langs/plugin-details.lang.zh.json +3 -1
  38. package/dist/genexus-ide-ui/{p-b3c5c315.entry.js → p-63e41ecd.entry.js} +2 -2
  39. package/dist/genexus-ide-ui/p-63e41ecd.entry.js.map +1 -0
  40. package/dist/genexus-ide-ui/p-e82d9621.entry.js +317 -0
  41. package/dist/genexus-ide-ui/p-e82d9621.entry.js.map +1 -0
  42. package/dist/genexus-ide-ui/p-ef8663dd.entry.js +284 -0
  43. package/dist/genexus-ide-ui/p-ef8663dd.entry.js.map +1 -0
  44. package/dist/types/components/plugin-details/plugin-details.d.ts +21 -3
  45. package/dist/types/components/plugin-explorer/plugin-explorer.d.ts +31 -4
  46. package/dist/types/components.d.ts +34 -14
  47. package/package.json +1 -1
  48. package/dist/genexus-ide-ui/p-514445ac.entry.js +0 -291
  49. package/dist/genexus-ide-ui/p-514445ac.entry.js.map +0 -1
  50. package/dist/genexus-ide-ui/p-b3c5c315.entry.js.map +0 -1
  51. package/dist/genexus-ide-ui/p-fc0bc991.entry.js +0 -204
  52. package/dist/genexus-ide-ui/p-fc0bc991.entry.js.map +0 -1
@@ -11,7 +11,7 @@ require('lit/directives/if-defined.js');
11
11
  const locale = require('./locale-ff30a5f3.js');
12
12
  const config = require('./config-3bb95f39.js');
13
13
 
14
- const pluginExplorerCss = ":host{display:grid;block-size:100%;position:relative}.outer-container{grid-template-rows:max-content 1fr}.inner-container{position:relative}.list-box::part(item){width:100%;min-width:100%}.list-box::part(item__action){gap:var(--spacing-gap-xs)}.list-box::part(item__caption){font-weight:var(--font-style-semi-bold)}.list-box::part(custom-container){display:flex;flex-direction:column;gap:var(--spacing-gap-xs);width:100%}.list-box::part(custom-image){block-size:32px;inline-size:32px;margin-inline-end:12px}.list-box::part(custom-description){font-size:var(--font-size-body-s);margin:0;opacity:0.8;line-height:var(--line-height-relaxed);margin-inline-end:8px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.list-box::part(item__block-end start){width:100%;min-width:100%}.list-box::part(custom-brand){font-weight:var(--font-style-semi-bold);display:flex;gap:var(--spacing-gap-xs);align-items:center}.list-box::part(custom-brand-icon){--icon-path:var(--icon__system_user_neutral--enabled);display:inline-block;background-image:var(--icon-path);background-size:contain;background-repeat:no-repeat;background-position:center center;block-size:16px;inline-size:16px}.list-box::part(custom-button){--button-color:var(--color-text-primary-default);--button-color--enabled:var(--color-text-neutral-on-text);--button-color--active:var(--color-text-neutral-on-pressed);display:inline-grid;grid-auto-flow:column;grid-auto-columns:max-content;justify-content:center;padding-block:var(--control-padding-block);padding-inline:var(--control-padding-inline);box-sizing:border-box;color:var(--button-color);font-weight:var(--font-style-semi-bold);margin-block-end:auto;margin-block-start:auto;text-transform:capitalize}.list-box::part(custom-button):hover{--button-color:var(--color-text-primary-hover)}.list-box::part(custom-button):active{--button-color:var(--color-text-primary-pressed)}";
14
+ const pluginExplorerCss = ":host{display:grid;block-size:100%;position:relative}.outer-container{grid-template-rows:max-content 1fr}.inner-container{position:relative}.list-box::part(item){width:100%;min-width:100%}.list-box::part(item__action){gap:var(--spacing-gap-xs)}.list-box::part(item__caption){font-weight:var(--font-style-semi-bold);color:var(--color-text-neutral-default);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.list-box::part(item__inline-caption){grid-template-columns:minmax(0, 1fr) max-content;align-items:center;gap:var(--spacing-gap-m);width:100%;min-width:100%}:host .list-box::part(group__action),:host .list-box::part(group__caption){font-size:var(--font-size-body-s);--ch-action-list-group__expandable-button-size:var(--icon-xs);--ch-action-list-group__expandable-button-image-size:var(--icon-xs)}.list-box::part(custom-image){block-size:40px;inline-size:40px;border-radius:var(--border-radius-m);object-fit:cover;margin-inline-end:12px}.list-box::part(custom-meta){display:flex;align-items:center;gap:var(--spacing-gap-m)}.list-box::part(custom-meta-item){display:inline-flex;align-items:center;gap:var(--spacing-gap-xs);font-size:var(--font-size-body-s);color:var(--color-text-neutral-default);white-space:nowrap}.list-box::part(custom-meta-icon){--ch-image-size:14px}.list-box::part(custom-container){display:flex;flex-direction:column;gap:var(--spacing-gap-xs);width:100%}.list-box::part(item__block-end start){width:100%;min-width:100%}.list-box::part(custom-description){font-size:var(--font-size-body-s);margin:0;color:var(--color-text-neutral-neutral);line-height:var(--line-height-relaxed);margin-inline-end:8px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.list-box::part(custom-footer){display:flex;align-items:center;gap:var(--spacing-gap-m);width:100%;margin-block-start:2px;min-block-size:var(--control-block-size)}.list-box::part(custom-brand){font-weight:var(--font-style-regular);font-size:var(--font-size-body-s);color:var(--color-text-neutral-disabled);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.list-box::part(custom-button){--button-color:var(--color-text-primary-default);margin-inline-start:auto;display:inline-grid;grid-auto-flow:column;grid-auto-columns:max-content;justify-content:center;padding-block:var(--control-padding-block);padding-inline:var(--control-padding-inline);box-sizing:border-box;color:var(--button-color);font-size:var(--font-size-body-s);font-weight:var(--font-style-semi-bold);text-transform:capitalize}.list-box::part(custom-button):hover{--button-color:var(--color-text-primary-hover)}.list-box::part(custom-button):active{--button-color:var(--color-text-primary-pressed)}.list-box::part(custom-progress){display:flex;align-items:center;gap:var(--spacing-gap-xs);margin-inline-start:auto;inline-size:140px}.list-box::part(custom-progress-label){font-size:var(--font-size-caption-s);line-height:1;color:var(--color-text-neutral-neutral);white-space:nowrap}.list-box::part(custom-progress-bar){flex:1}";
15
15
 
16
16
  var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) {
17
17
  if (kind === "a" && !f)
@@ -29,14 +29,14 @@ var __classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) ||
29
29
  throw new TypeError("Cannot write private member to an object whose class did not declare it");
30
30
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
31
31
  };
32
- var _GxIdePluginManager_componentLocale, _GxIdePluginManager_animateEmptyState, _GxIdePluginManager_actionListButtonClickHandler, _GxIdePluginManager_mapPluginDataToActionListModel, _GxIdePluginManager_pluginsFilterInputHandler, _GxIdePluginManager_evaluateContentToDisplay, _GxIdePluginManager_renderLoader, _GxIdePluginManager_pluginSelectedHandler;
32
+ var _GxIdePluginManager_componentLocale, _GxIdePluginManager_animateEmptyState, _GxIdePluginManager_actionListButtonClickHandler, _GxIdePluginManager_downloadsFormatter, _GxIdePluginManager_formatDownloads, _GxIdePluginManager_mapPluginToItem, _GxIdePluginManager_mapPluginGroupsToActionListModel, _GxIdePluginManager_pluginsFilterInputHandler, _GxIdePluginManager_evaluateContentToDisplay, _GxIdePluginManager_renderLoader, _GxIdePluginManager_pluginSelectedHandler;
33
33
  const FILTER_ICON = assetsManager.getIconPath({
34
34
  category: "system",
35
35
  name: "filters",
36
36
  colorType: "on-surface"
37
37
  });
38
38
  // plugin icon if no iconUrl was provided
39
- const EXTENSION_ICON_IMG = index.getAssetPath(`./gx-ide-assets/plugin-manager/images/plugin-icon.svg`);
39
+ const EXTENSION_ICON_IMG = index.getAssetPath(`./gx-ide-assets/plugin-explorer/images/plugin-icon.svg`);
40
40
  const CSS_BUNDLES = [
41
41
  "resets/box-sizing",
42
42
  "components/list-box",
@@ -48,6 +48,21 @@ const CSS_BUNDLES = [
48
48
  "utils/spacing",
49
49
  "chameleon/scrollbar"
50
50
  ];
51
+ const SEARCH_ICON = assetsManager.getIconPath({
52
+ category: "system",
53
+ name: "search",
54
+ colorType: "on-surface"
55
+ });
56
+ const STAR_ICON = assetsManager.getIconPath({
57
+ category: "system",
58
+ name: "star-fill",
59
+ colorType: "warning"
60
+ });
61
+ const DOWNLOAD_ICON = assetsManager.getIconPath({
62
+ category: "system",
63
+ name: "download",
64
+ colorType: "on-surface"
65
+ });
51
66
  const GxIdePluginManager = class {
52
67
  constructor(hostRef) {
53
68
  index.registerInstance(this, hostRef);
@@ -61,51 +76,85 @@ const GxIdePluginManager = class {
61
76
  event.stopPropagation();
62
77
  this.executeActionCallback(pluginId, action);
63
78
  });
64
- _GxIdePluginManager_mapPluginDataToActionListModel.set(this, (pluginsData) => {
65
- const pluginsActionListModel = [];
66
- const separatorItem = { type: "separator" };
67
- pluginsData === null || pluginsData === void 0 ? void 0 : pluginsData.forEach((pluginData, index$1) => {
68
- const hasActionButton = !!pluginData.action;
69
- const pluginItem = {
70
- id: pluginData.id,
71
- caption: pluginData.name,
72
- imgSrc: pluginData.iconUrl,
73
- type: "actionable",
74
- additionalInformation: {
75
- "stretch-start": {
76
- center: [
77
- {
78
- part: "custom-image",
79
- jsx: () => (index.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" }))
80
- }
81
- ]
82
- },
83
- "block-end": {
84
- start: [
85
- {
86
- part: "custom-description custom-button custom-container custom-brand custom-brand-icon custom-image item__block-end start",
87
- jsx: () => (index.h("div", { part: "custom-container", title: pluginData.description }, index.h("p", { part: "custom-description" }, pluginData.description), index.h("small", { part: "custom-brand" }, pluginData.publisher)))
88
- }
89
- // {
90
- // slot: "abcd"
91
- // } as ActionListItemAdditionalSlot // slot not working
92
- ]
93
- },
94
- "stretch-end": hasActionButton && {
95
- center: [
96
- {
97
- jsx: () => (index.h("button", { part: "custom-button", onClick: __classPrivateFieldGet(this, _GxIdePluginManager_actionListButtonClickHandler, "f").call(this, pluginData.id, pluginData.action) }, pluginData.action))
98
- }
99
- ]
100
- }
79
+ // Formats a raw downloads count into a compact string (e.g. 4000 -> "4K").
80
+ _GxIdePluginManager_downloadsFormatter.set(this, new Intl.NumberFormat(undefined, {
81
+ notation: "compact",
82
+ maximumFractionDigits: 1
83
+ }));
84
+ _GxIdePluginManager_formatDownloads.set(this, (value) => {
85
+ const numericValue = typeof value === "number" ? value : Number(value);
86
+ return Number.isFinite(numericValue)
87
+ ? __classPrivateFieldGet(this, _GxIdePluginManager_downloadsFormatter, "f").format(numericValue)
88
+ : `${value}`;
89
+ });
90
+ _GxIdePluginManager_mapPluginToItem.set(this, (pluginData) => {
91
+ const hasActionButton = !!pluginData.action;
92
+ const hasDownloads = pluginData.downloads !== undefined && pluginData.downloads !== null;
93
+ const hasRating = pluginData.rating !== undefined && pluginData.rating !== null;
94
+ const hasMeta = hasDownloads || hasRating;
95
+ const pluginItem = {
96
+ id: pluginData.id,
97
+ caption: pluginData.name,
98
+ imgSrc: pluginData.iconUrl,
99
+ type: "actionable",
100
+ additionalInformation: {
101
+ "stretch-start": {
102
+ center: [
103
+ {
104
+ part: "custom-image",
105
+ jsx: () => (index.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" }))
106
+ }
107
+ ]
108
+ },
109
+ "inline-caption": hasMeta && {
110
+ end: [
111
+ {
112
+ part: "custom-meta",
113
+ jsx: () => (index.h("div", { part: "custom-meta" }, hasDownloads && (index.h("span", { part: "custom-meta-item custom-downloads", title: `${pluginData.downloads}` }, index.h("ch-image", { part: "custom-meta-icon custom-downloads-icon", src: DOWNLOAD_ICON }), __classPrivateFieldGet(this, _GxIdePluginManager_formatDownloads, "f").call(this, pluginData.downloads))), hasRating && (index.h("span", { part: "custom-meta-item custom-rating", title: `${pluginData.rating}` }, index.h("ch-image", { part: "custom-meta-icon custom-rating-icon", src: STAR_ICON }), pluginData.rating))))
114
+ }
115
+ ]
116
+ },
117
+ "block-end": {
118
+ start: [
119
+ {
120
+ 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",
121
+ jsx: () => (index.h("div", { part: "custom-container" }, index.h("p", { part: "custom-description", title: pluginData.description }, pluginData.description), index.h("div", { part: "custom-footer" }, index.h("small", { part: "custom-brand" }, pluginData.publisher), pluginData.installProgress ? (index.h("div", { part: "custom-progress" }, index.h("span", { part: "custom-progress-label" }, pluginData.installProgress.percent, "%"), index.h("gx-ide-progress-bar", { part: "custom-progress-bar", class: "plain", minimal: true, active: true, stateType: "in-progress", progress: pluginData.installProgress.percent }))) : hasActionButton ? (index.h("button", { class: "button", part: "custom-button", onClick: __classPrivateFieldGet(this, _GxIdePluginManager_actionListButtonClickHandler, "f").call(this, pluginData.id, pluginData.action) }, pluginData.action)) : null)))
122
+ }
123
+ // {
124
+ // slot: "abcd"
125
+ // } as ActionListItemAdditionalSlot // slot not working
126
+ ]
101
127
  }
102
- };
103
- if (index$1 !== 0) {
104
- pluginsActionListModel.push(separatorItem);
105
128
  }
106
- pluginsActionListModel.push(pluginItem);
129
+ };
130
+ return pluginItem;
131
+ });
132
+ // Builds the ch-action-list model from groups: one native action-list group
133
+ // per PluginGroupData, plus a separator between groups. The group header only
134
+ // renders a plain-text caption (no custom pill element is supported), so the
135
+ // per-group total is shown as a number appended to the caption.
136
+ _GxIdePluginManager_mapPluginGroupsToActionListModel.set(this, (groups) => {
137
+ const model = [];
138
+ const separatorItem = { type: "separator" };
139
+ groups === null || groups === void 0 ? void 0 : groups.forEach(group => {
140
+ var _a, _b, _c;
141
+ // Skip empty groups so we don't render a header with "(0)".
142
+ if (!((_a = group.plugins) === null || _a === void 0 ? void 0 : _a.length)) {
143
+ return;
144
+ }
145
+ if (model.length > 0) {
146
+ model.push(separatorItem);
147
+ }
148
+ model.push({
149
+ id: group.id,
150
+ type: "group",
151
+ caption: `${group.caption} (${group.plugins.length})`,
152
+ expandable: (_b = group.expandable) !== null && _b !== void 0 ? _b : true,
153
+ expanded: (_c = group.expanded) !== null && _c !== void 0 ? _c : true,
154
+ items: group.plugins.map(plugin => __classPrivateFieldGet(this, _GxIdePluginManager_mapPluginToItem, "f").call(this, plugin))
155
+ });
107
156
  });
108
- return pluginsActionListModel;
157
+ return model;
109
158
  });
110
159
  _GxIdePluginManager_pluginsFilterInputHandler.set(this, async (event) => {
111
160
  this.loading = true;
@@ -137,7 +186,7 @@ const GxIdePluginManager = class {
137
186
  }
138
187
  pluginsChangedHandler(newPlugins) {
139
188
  this.pluginsActionListModel =
140
- __classPrivateFieldGet(this, _GxIdePluginManager_mapPluginDataToActionListModel, "f").call(this, newPlugins);
189
+ __classPrivateFieldGet(this, _GxIdePluginManager_mapPluginGroupsToActionListModel, "f").call(this, newPlugins);
141
190
  this.loading = false;
142
191
  }
143
192
  async componentWillLoad() {
@@ -145,7 +194,7 @@ const GxIdePluginManager = class {
145
194
  this.pluginsChangedHandler(this.plugins);
146
195
  }
147
196
  render() {
148
- return (index.h(index.Host, { class: "widget" }, index.h("ch-theme", { model: CSS_BUNDLES }), index.h("div", { class: "outer-container field-group" }, index.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.config.inputDebounce, onInput: __classPrivateFieldGet(this, _GxIdePluginManager_pluginsFilterInputHandler, "f"), type: "search" }), index.h("div", { class: "inner-container" }, this.loading
197
+ return (index.h(index.Host, { class: "widget" }, index.h("ch-theme", { model: CSS_BUNDLES }), index.h("div", { class: "outer-container field-group" }, index.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.config.inputDebounce, onInput: __classPrivateFieldGet(this, _GxIdePluginManager_pluginsFilterInputHandler, "f"), type: "search", startImgSrc: SEARCH_ICON }), index.h("div", { class: "inner-container" }, this.loading
149
198
  ? __classPrivateFieldGet(this, _GxIdePluginManager_renderLoader, "f").call(this)
150
199
  : __classPrivateFieldGet(this, _GxIdePluginManager_evaluateContentToDisplay, "f").call(this)))));
151
200
  }
@@ -155,7 +204,7 @@ const GxIdePluginManager = class {
155
204
  "plugins": ["pluginsChangedHandler"]
156
205
  }; }
157
206
  };
158
- _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();
207
+ _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();
159
208
  GxIdePluginManager.style = pluginExplorerCss;
160
209
 
161
210
  exports.gx_ide_plugin_explorer = GxIdePluginManager;
@@ -1 +1 @@
1
- {"file":"gx-ide-plugin-explorer.entry.cjs.js","mappings":"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","names":["getIconPath","getAssetPath","index","h","Locale","Host","config"],"sources":["src/components/plugin-explorer/plugin-explorer.scss?tag=gx-ide-plugin-explorer&encapsulation=shadow","src/components/plugin-explorer/plugin-explorer.tsx"],"sourcesContent":["@import \"../../global/gx-ide-mixins.scss\";\n\n:host {\n display: grid;\n block-size: 100%;\n position: relative;\n}\n\n.outer-container {\n grid-template-rows: max-content 1fr;\n}\n.inner-container {\n position: relative;\n}\n\n.list-box::part(item) {\n width: 100%;\n min-width: 100%;\n}\n.list-box::part(item__action) {\n gap: var(--spacing-gap-xs);\n}\n.list-box::part(item__caption) {\n font-weight: var(--font-style-semi-bold);\n}\n.list-box::part(custom-container) {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-xs);\n width: 100%;\n}\n.list-box::part(custom-image) {\n block-size: 32px;\n inline-size: 32px;\n margin-inline-end: 12px;\n}\n.list-box::part(custom-description) {\n font-size: var(--font-size-body-s);\n margin: 0;\n opacity: 0.8;\n line-height: var(--line-height-relaxed);\n margin-inline-end: 8px;\n @include ellipsis();\n}\n.list-box::part(item__block-end start) {\n width: 100%;\n min-width: 100%;\n}\n.list-box::part(custom-brand) {\n font-weight: var(--font-style-semi-bold);\n display: flex;\n gap: var(--spacing-gap-xs);\n align-items: center;\n}\n.list-box::part(custom-brand-icon) {\n // --icon-path: var(--icon__system_publish_on-elevation--enabled);\n --icon-path: var(--icon__system_user_neutral--enabled);\n display: inline-block;\n background-image: var(--icon-path);\n background-size: contain;\n background-repeat: no-repeat;\n background-position: center center;\n block-size: 16px;\n inline-size: 16px;\n}\n.list-box::part(custom-button) {\n // WA: Style the button like a Mercury primary button\n // \"Slot\" not working apparently.\n --button-color: var(--color-text-primary-default);\n --button-color--enabled: var(--color-text-neutral-on-text);\n --button-color--active: var(--color-text-neutral-on-pressed);\n display: inline-grid;\n grid-auto-flow: column;\n grid-auto-columns: max-content;\n justify-content: center;\n padding-block: var(--control-padding-block);\n padding-inline: var(--control-padding-inline);\n box-sizing: border-box;\n color: var(--button-color);\n font-weight: var(--font-style-semi-bold);\n margin-block-end: auto;\n margin-block-start: auto;\n text-transform: capitalize;\n}\n.list-box::part(custom-button):hover {\n --button-color: var(--color-text-primary-hover);\n}\n.list-box::part(custom-button):active {\n --button-color: var(--color-text-primary-pressed);\n}\n","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"],"version":3}
1
+ {"file":"gx-ide-plugin-explorer.entry.cjs.js","mappings":"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","names":["getIconPath","getAssetPath","h","Locale","Host","config"],"sources":["src/components/plugin-explorer/plugin-explorer.scss?tag=gx-ide-plugin-explorer&encapsulation=shadow","src/components/plugin-explorer/plugin-explorer.tsx"],"sourcesContent":["@import \"../../global/gx-ide-mixins.scss\";\n\n:host {\n display: grid;\n block-size: 100%;\n position: relative;\n}\n\n.outer-container {\n grid-template-rows: max-content 1fr;\n}\n.inner-container {\n position: relative;\n}\n\n.list-box::part(item) {\n width: 100%;\n min-width: 100%;\n}\n.list-box::part(item__action) {\n gap: var(--spacing-gap-xs);\n}\n.list-box::part(item__caption) {\n font-weight: var(--font-style-semi-bold);\n color: var(--color-text-neutral-default);\n @include ellipsis();\n}\n\n// Caption row: name (flexible) + metadata pinned to the end\n.list-box::part(item__inline-caption) {\n grid-template-columns: minmax(0, 1fr) max-content;\n align-items: center;\n gap: var(--spacing-gap-m);\n width: 100%;\n min-width: 100%;\n}\n\n// Group header: Mercury defaults it to body-m (14px), which reads too large\n// next to the 12px item text. Keep it compact so it looks like a section label.\n// The `:host` prefix raises specificity over Mercury's themed ::part rule\n// (same-specificity ::part rules from the adopted theme would otherwise win).\n:host .list-box::part(group__action),\n:host .list-box::part(group__caption) {\n font-size: var(--font-size-body-s);\n // The expand/collapse chevron is sized by these chameleon vars (Mercury sets\n // them to --icon-s = 14px). Match the 12px header so it doesn't look oversized.\n --ch-action-list-group__expandable-button-size: var(--icon-xs);\n --ch-action-list-group__expandable-button-image-size: var(--icon-xs);\n}\n\n// Plugin logo\n.list-box::part(custom-image) {\n block-size: 40px;\n inline-size: 40px;\n border-radius: var(--border-radius-m);\n object-fit: cover;\n margin-inline-end: 12px;\n}\n\n// Metadata (downloads + rating), aligned with the name\n.list-box::part(custom-meta) {\n display: flex;\n align-items: center;\n gap: var(--spacing-gap-m);\n}\n.list-box::part(custom-meta-item) {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-gap-xs);\n font-size: var(--font-size-body-s);\n // Same emphasis as the title. Applied via `color` (not opacity) so the meta\n // icons keep their own color (e.g. the rating star).\n color: var(--color-text-neutral-default);\n white-space: nowrap;\n}\n.list-box::part(custom-meta-icon) {\n --ch-image-size: 14px;\n}\n\n// Content block (description + footer)\n.list-box::part(custom-container) {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-xs);\n width: 100%;\n}\n.list-box::part(item__block-end start) {\n width: 100%;\n min-width: 100%;\n}\n// Description — second level: lighter than the title.\n.list-box::part(custom-description) {\n font-size: var(--font-size-body-s);\n margin: 0;\n color: var(--color-text-neutral-neutral);\n line-height: var(--line-height-relaxed);\n margin-inline-end: 8px;\n @include ellipsis();\n}\n\n// Footer row: publisher + action button.\n// Pin the row height to the standard control height so swapping the action\n// button for the install progress bar doesn't shift the layout.\n.list-box::part(custom-footer) {\n display: flex;\n align-items: center;\n gap: var(--spacing-gap-m);\n width: 100%;\n margin-block-start: 2px;\n min-block-size: var(--control-block-size);\n}\n// Publisher — the least prominent line in the hierarchy: regular weight and\n// the most muted of the three text levels (below title and description).\n.list-box::part(custom-brand) {\n font-weight: var(--font-style-regular);\n font-size: var(--font-size-body-s);\n color: var(--color-text-neutral-disabled);\n @include ellipsis();\n}\n.list-box::part(custom-button) {\n // WA: Style the button like a Mercury primary button\n // \"Slot\" not working apparently.\n --button-color: var(--color-text-primary-default);\n margin-inline-start: auto;\n display: inline-grid;\n grid-auto-flow: column;\n grid-auto-columns: max-content;\n justify-content: center;\n padding-block: var(--control-padding-block);\n padding-inline: var(--control-padding-inline);\n box-sizing: border-box;\n color: var(--button-color);\n // Match the surrounding text size so the action doesn't look oversized.\n font-size: var(--font-size-body-s);\n font-weight: var(--font-style-semi-bold);\n text-transform: capitalize;\n}\n.list-box::part(custom-button):hover {\n --button-color: var(--color-text-primary-hover);\n}\n.list-box::part(custom-button):active {\n --button-color: var(--color-text-primary-pressed);\n}\n\n// The install progress is the shared gx-ide-progress-bar, rendered inside the\n// ch-action-list shadow tree via the item's jsx callback, so it must be sized\n// through ::part (like the other custom-* elements), not with plain selectors.\n// A percent label sits inline with the bar so the progress reads as part of\n// the row instead of a detached bar.\n.list-box::part(custom-progress) {\n display: flex;\n align-items: center;\n gap: var(--spacing-gap-xs);\n margin-inline-start: auto;\n inline-size: 140px;\n}\n.list-box::part(custom-progress-label) {\n font-size: var(--font-size-caption-s);\n line-height: 1;\n color: var(--color-text-neutral-neutral);\n white-space: nowrap;\n}\n.list-box::part(custom-progress-bar) {\n flex: 1;\n}\n","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"],"version":3}
@@ -9,7 +9,7 @@ require('lit');
9
9
  require('lit/directives/when.js');
10
10
  require('lit/directives/if-defined.js');
11
11
 
12
- const progressBarCss = ":host{--top-bar-progress:0%;display:grid;grid-template-rows:0fr;transition:var(--timing-fast) grid-template-rows;overflow:hidden;--ds-icon-size-box--small:var(--font-size-body-s);--ds-icon-size--small:100%}:host>*{overflow:hidden}:host(.disable-transition){--progress-bar-transition-speed:0 !important}:host(.visible){grid-template-rows:1fr}.top-state-bar{position:relative;display:flex;flex-direction:column;gap:var(--spacing-gap-l);border-radius:4px;list-style:var(--font-size-body-s);display:flex;}.top-state-bar>*{position:relative;z-index:1}.top-state-bar__outer-wrapper{position:relative;flex:1;display:flex;flex-direction:column;gap:var(--spacing-gap-l);padding:var(--spacing-padding-l) var(--spacing-padding-l)}.top-state-bar__outer-wrapper::after,.top-state-bar__outer-wrapper::before{border-radius:4px}.top-state-bar__outer-wrapper::before{content:\"\";inline-size:100%;block-size:100%;inset-inline-start:0;inset-block-start:0;position:absolute;background-color:var(--color-accent-surface-elevation-3);z-index:0}.top-state-bar__outer-wrapper::after{content:\"\";inset-inline-start:1px;inset-block-start:1px;inline-size:calc(100% - 1px * 2);block-size:calc(100% - 1px * 2);position:absolute;background-color:var(--color-accent-surface-surface);z-index:1}.top-state-bar__inner-wrapper{flex:1;display:flex;flex-direction:row;justify-content:space-between;gap:var(--spacing-gap-m);position:relative;z-index:2}.top-state-bar__caption{color:var(--color-text-neutral-strawberry);font-size:var(--font-size-body-s);line-height:var(--font-size-body-s);font-weight:var(--font-style-regular);display:flex;align-items:center;font-style:italic}.top-state-bar__progress-wrapper{block-size:4px;background-color:var(--color-accent-surface-elevation-1);position:relative;z-index:2}.top-state-bar__close{cursor:pointer;transition:var(--timing-fast) background-color}.top-state-bar__inner-wrapper,.top-state-bar__progress-wrapper,.top-state-bar__close{opacity:0;transition:150ms opacity}.top-state-bar--accent .progress-bar{background-color:var(--color-accent-primary-default)}.top-state-bar--success .progress-bar{background-color:var(--color-border-success-default)}.top-state-bar--warning .progress-bar{background-color:var(--color-border-warning-default)}.top-state-bar--error .progress-bar{background-color:var(--color-border-error-default)}.top-state-bar--in-progress .top-state-bar__outer-wrapper:before{block-size:0;inline-size:120%;padding-block-start:60%;padding-block-end:60%;background:linear-gradient(90deg, rgba(91, 167, 255, 0.4) 0%, rgba(63, 168, 155, 0.4) 100%);inset-block-start:50%;inset-inline-start:50%;transform:translate(-50%, -50%);-webkit-animation:inProgressBackgroundColor 1s linear infinite;animation:inProgressBackgroundColor 1s linear infinite}.top-state-bar--in-progress .progress-bar{position:relative;overflow:hidden;z-index:1}.top-state-bar--in-progress .progress-bar:after{content:\"\";position:absolute;z-index:0;inline-size:300%;block-size:100%;inset-inline-start:0;background:linear-gradient(90deg, #93f5eb 0%, #1aa3ff 33%, #93f5eb 66%, #1aa3ff 100%);animation-name:inProgressBar;animation-duration:2s;animation-iteration-count:infinite}.top-state-bar--visible .top-state-bar__inner-wrapper,.top-state-bar--visible .top-state-bar__progress-wrapper,.top-state-bar--visible .top-state-bar__close{opacity:1}.top-state-bar--visible .top-state-bar__close:hover{opacity:0.75}.top-state-bar--visible .top-state-bar__close:active{opacity:0.5}:host(.with-close-button) .top-state-bar__outer-wrapper{padding-block-start:4px;gap:var(--spacing-gap-xs)}@-webkit-keyframes inProgressBackgroundColor{0%{transform:translate(-50%, -50%) rotate(0)}100%{transform:translate(-50%, -50%) rotate(1turn)}}@-webkit-keyframes inProgressBar{0%{inset-inline-start:0%}100%{inset-inline-start:-200%}}@-moz-keyframes inProgressBar{0%{inset-inline-start:0%}100%{inset-inline-start:200%}}@keyframes inProgressBar{0%{inset-inline-start:0%}100%{inset-inline-start:-200%}}.progress-bar{display:block;transition:all var(--progress-bar-transition-speed);inline-size:var(--top-bar-progress);border-radius:calc(4px / 2);block-size:100%}:host(.no-border) .top-state-bar__outer-wrapper:before,:host(.border-block-start) .top-state-bar__outer-wrapper:before,:host(.border-block-end) .top-state-bar__outer-wrapper:before{display:none}:host(.border-block-start) .top-state-bar__outer-wrapper{border-block-start:1px solid var(--color-border-surface-on-elevation-1)}:host(.border-block-end) .top-state-bar__outer-wrapper{border-block-end:1px solid var(--color-border-surface-on-elevation-1)}";
12
+ const progressBarCss = ":host{--top-bar-progress:0%;display:grid;grid-template-rows:0fr;transition:var(--timing-fast) grid-template-rows;overflow:hidden;--ds-icon-size-box--small:var(--font-size-body-s);--ds-icon-size--small:100%}:host>*{overflow:hidden}:host(.disable-transition){--progress-bar-transition-speed:0 !important}:host(.visible){grid-template-rows:1fr}.top-state-bar{position:relative;display:flex;flex-direction:column;gap:var(--spacing-gap-l);border-radius:4px;list-style:var(--font-size-body-s);display:flex;}.top-state-bar>*{position:relative;z-index:1}.top-state-bar__outer-wrapper{position:relative;flex:1;display:flex;flex-direction:column;gap:var(--spacing-gap-l);padding:var(--spacing-padding-l) var(--spacing-padding-l)}.top-state-bar__outer-wrapper::after,.top-state-bar__outer-wrapper::before{border-radius:4px}.top-state-bar__outer-wrapper::before{content:\"\";inline-size:100%;block-size:100%;inset-inline-start:0;inset-block-start:0;position:absolute;background-color:var(--color-accent-surface-elevation-3);z-index:0}.top-state-bar__outer-wrapper::after{content:\"\";inset-inline-start:1px;inset-block-start:1px;inline-size:calc(100% - 1px * 2);block-size:calc(100% - 1px * 2);position:absolute;background-color:var(--color-accent-surface-surface);z-index:1}.top-state-bar__inner-wrapper{flex:1;display:flex;flex-direction:row;justify-content:space-between;gap:var(--spacing-gap-m);position:relative;z-index:2}.top-state-bar__caption{color:var(--color-text-neutral-strawberry);font-size:var(--font-size-body-s);line-height:var(--font-size-body-s);font-weight:var(--font-style-regular);display:flex;align-items:center;font-style:italic}.top-state-bar__progress-wrapper{block-size:4px;background-color:var(--color-accent-surface-elevation-1);position:relative;z-index:2}.top-state-bar__close{cursor:pointer;transition:var(--timing-fast) background-color}.top-state-bar__inner-wrapper,.top-state-bar__progress-wrapper,.top-state-bar__close{opacity:0;transition:150ms opacity}.top-state-bar--accent .progress-bar{background-color:var(--color-accent-primary-default)}.top-state-bar--success .progress-bar{background-color:var(--color-border-success-default)}.top-state-bar--warning .progress-bar{background-color:var(--color-border-warning-default)}.top-state-bar--error .progress-bar{background-color:var(--color-border-error-default)}.top-state-bar--in-progress .top-state-bar__outer-wrapper:before{block-size:0;inline-size:120%;padding-block-start:60%;padding-block-end:60%;background:linear-gradient(90deg, rgba(91, 167, 255, 0.4) 0%, rgba(63, 168, 155, 0.4) 100%);inset-block-start:50%;inset-inline-start:50%;transform:translate(-50%, -50%);-webkit-animation:inProgressBackgroundColor 1s linear infinite;animation:inProgressBackgroundColor 1s linear infinite}.top-state-bar--in-progress .progress-bar{position:relative;overflow:hidden;z-index:1}.top-state-bar--in-progress .progress-bar:after{content:\"\";position:absolute;z-index:0;inline-size:300%;block-size:100%;inset-inline-start:0;background:linear-gradient(90deg, #93f5eb 0%, #1aa3ff 33%, #93f5eb 66%, #1aa3ff 100%);animation-name:inProgressBar;animation-duration:2s;animation-iteration-count:infinite}.top-state-bar--visible .top-state-bar__inner-wrapper,.top-state-bar--visible .top-state-bar__progress-wrapper,.top-state-bar--visible .top-state-bar__close{opacity:1}.top-state-bar--visible .top-state-bar__close:hover{opacity:0.75}.top-state-bar--visible .top-state-bar__close:active{opacity:0.5}:host(.with-close-button) .top-state-bar__outer-wrapper{padding-block-start:4px;gap:var(--spacing-gap-xs)}:host(.plain) .top-state-bar__outer-wrapper{padding:0}:host(.plain) .top-state-bar__outer-wrapper::before,:host(.plain) .top-state-bar__outer-wrapper::after{display:none}:host(.plain) .top-state-bar__progress-wrapper{background-color:color-mix(in srgb, var(--color-text-neutral-default) 25%, transparent)}@-webkit-keyframes inProgressBackgroundColor{0%{transform:translate(-50%, -50%) rotate(0)}100%{transform:translate(-50%, -50%) rotate(1turn)}}@-webkit-keyframes inProgressBar{0%{inset-inline-start:0%}100%{inset-inline-start:-200%}}@-moz-keyframes inProgressBar{0%{inset-inline-start:0%}100%{inset-inline-start:200%}}@keyframes inProgressBar{0%{inset-inline-start:0%}100%{inset-inline-start:-200%}}.progress-bar{display:block;transition:all var(--progress-bar-transition-speed);inline-size:var(--top-bar-progress);border-radius:calc(4px / 2);block-size:100%}:host(.no-border) .top-state-bar__outer-wrapper:before,:host(.border-block-start) .top-state-bar__outer-wrapper:before,:host(.border-block-end) .top-state-bar__outer-wrapper:before{display:none}:host(.border-block-start) .top-state-bar__outer-wrapper{border-block-start:1px solid var(--color-border-surface-on-elevation-1)}:host(.border-block-end) .top-state-bar__outer-wrapper{border-block-end:1px solid var(--color-border-surface-on-elevation-1)}";
13
13
 
14
14
  const CSS_BUNDLES = [
15
15
  "resets/box-sizing",
@@ -1 +1 @@
1
- {"file":"gx-ide-progress-bar.entry.cjs.js","mappings":"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","names":["getIconPath","h","Host"],"sources":["src/components/_helpers/progress-bar/progress-bar.scss?tag=gx-ide-progress-bar&encapsulation=shadow","src/components/_helpers/progress-bar/progress-bar.tsx"],"sourcesContent":["// --progress-bar-transition-speed is defined on the Host in the .tsx\n$border: 1px solid var(--color-border-surface-on-elevation-1);\n\n:host {\n --top-bar-progress: 0%;\n display: grid;\n grid-template-rows: 0fr;\n transition: var(--timing-fast) grid-template-rows;\n overflow: hidden;\n\n //icon\n --ds-icon-size-box--small: var(--font-size-body-s);\n --ds-icon-size--small: 100%;\n\n > * {\n overflow: hidden;\n }\n}\n:host(.disable-transition) {\n --progress-bar-transition-speed: 0 !important;\n}\n:host(.visible) {\n grid-template-rows: 1fr;\n}\n.top-state-bar {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-l);\n\n > * {\n position: relative;\n z-index: 1;\n }\n border-radius: 4px;\n list-style: var(--font-size-body-s);\n display: flex;\n\n &__outer-wrapper {\n &::after,\n &::before {\n border-radius: 4px;\n }\n &::before {\n content: \"\";\n inline-size: 100%;\n block-size: 100%;\n inset-inline-start: 0;\n inset-block-start: 0;\n position: absolute;\n background-color: var(--color-accent-surface-elevation-3);\n z-index: 0;\n }\n &::after {\n content: \"\";\n inset-inline-start: 1px;\n inset-block-start: 1px;\n inline-size: calc(100% - 1px * 2);\n block-size: calc(100% - 1px * 2);\n position: absolute;\n background-color: var(--color-accent-surface-surface);\n z-index: 1;\n }\n\n position: relative;\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-l);\n padding: var(--spacing-padding-l) var(--spacing-padding-l);\n }\n &__inner-wrapper {\n flex: 1;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n gap: var(--spacing-gap-m);\n position: relative;\n z-index: 2;\n }\n &__caption {\n color: var(--color-text-neutral-strawberry);\n font-size: var(--font-size-body-s);\n line-height: var(--font-size-body-s);\n font-weight: var(--font-style-regular);\n display: flex;\n align-items: center;\n font-style: italic;\n }\n &__progress-wrapper {\n block-size: 4px;\n background-color: var(--color-accent-surface-elevation-1);\n position: relative;\n z-index: 2;\n }\n &__close {\n cursor: pointer;\n transition: var(--timing-fast) background-color;\n }\n &__inner-wrapper,\n &__progress-wrapper,\n &__close {\n opacity: 0;\n transition: 150ms opacity;\n }\n\n /*states*/\n &--accent {\n .progress-bar {\n background-color: var(--color-accent-primary-default);\n }\n }\n &--success {\n .progress-bar {\n background-color: var(--color-border-success-default);\n }\n }\n &--warning {\n .progress-bar {\n background-color: var(--color-border-warning-default);\n }\n }\n &--error {\n .progress-bar {\n background-color: var(--color-border-error-default);\n }\n }\n &--in-progress {\n .top-state-bar__outer-wrapper:before {\n block-size: 0;\n inline-size: 120%;\n padding-block-start: 60%;\n padding-block-end: 60%;\n background: linear-gradient(\n 90deg,\n rgba(91, 167, 255, 0.4) 0%,\n rgba(63, 168, 155, 0.4) 100%\n );\n inset-block-start: 50%;\n inset-inline-start: 50%;\n transform: translate(-50%, -50%);\n -webkit-animation: inProgressBackgroundColor 1s linear infinite;\n animation: inProgressBackgroundColor 1s linear infinite;\n }\n .progress-bar {\n position: relative;\n overflow: hidden;\n z-index: 1;\n &:after {\n content: \"\";\n position: absolute;\n z-index: 0;\n inline-size: 300%;\n block-size: 100%;\n inset-inline-start: 0;\n background: linear-gradient(\n 90deg,\n rgba(147, 245, 235, 1) 0%,\n rgba(26, 163, 255, 1) 33%,\n rgba(147, 245, 235, 1) 66%,\n rgba(26, 163, 255, 1) 100%\n );\n animation-name: inProgressBar;\n animation-duration: 2s;\n animation-iteration-count: infinite;\n }\n }\n }\n &--visible {\n .top-state-bar__inner-wrapper,\n .top-state-bar__progress-wrapper,\n .top-state-bar__close {\n opacity: 1;\n }\n .top-state-bar__close {\n &:hover {\n opacity: 0.75;\n }\n &:active {\n opacity: 0.5;\n }\n }\n }\n}\n\n// With Close Button (some spacing needs to be adjusted)\n:host(.with-close-button) {\n .top-state-bar {\n &__outer-wrapper {\n padding-block-start: 4px;\n gap: var(--spacing-gap-xs);\n }\n }\n}\n\n/*in progress animation*/\n@-webkit-keyframes inProgressBackgroundColor {\n 0% {\n transform: translate(-50%, -50%) rotate(0);\n }\n 100% {\n transform: translate(-50%, -50%) rotate(1turn);\n }\n}\n@-webkit-keyframes inProgressBar {\n 0% {\n inset-inline-start: 0%;\n }\n 100% {\n inset-inline-start: -200%;\n }\n}\n@-moz-keyframes inProgressBar {\n 0% {\n inset-inline-start: 0%;\n }\n 100% {\n inset-inline-start: 200%;\n }\n}\n@keyframes inProgressBar {\n 0% {\n inset-inline-start: 0%;\n }\n 100% {\n inset-inline-start: -200%;\n }\n}\n\n.progress-bar {\n display: block;\n transition: all var(--progress-bar-transition-speed);\n inline-size: var(--top-bar-progress);\n border-radius: calc(4px / 2);\n block-size: 100%;\n}\n\n:host(.no-border),\n:host(.border-block-start),\n:host(.border-block-end) {\n .top-state-bar__outer-wrapper {\n &:before {\n display: none;\n }\n }\n}\n:host(.border-block-start) {\n .top-state-bar__outer-wrapper {\n border-block-start: $border;\n }\n}\n:host(.border-block-end) {\n .top-state-bar__outer-wrapper {\n border-block-end: $border;\n }\n}\n","import {\n Component,\n Host,\n h,\n Prop,\n State,\n Watch,\n Element,\n Event,\n EventEmitter,\n Method\n} from \"@stencil/core\";\nimport { MercuryBundles, getIconPath } from \"@genexus/mercury\";\n\nconst CSS_BUNDLES: MercuryBundles = [\n \"resets/box-sizing\",\n \"utils/form\",\n \"utils/layout\",\n \"utils/typography\",\n \"components/button\",\n \"components/icon\",\n \"components/combo-box\",\n \"components/edit\",\n \"components/tabular-grid\"\n];\n\nconst CLOSE_ICON = getIconPath({\n category: \"system\",\n name: \"close\",\n colorType: \"primary\"\n});\nconst PROGRESS_TRANSITION_SPEED = 200;\n\n@Component({\n tag: \"gx-ide-progress-bar\",\n styleUrl: \"progress-bar.scss\",\n shadow: true,\n assetsDirs: [\"gx-ide-assets/progress-bar\"]\n})\nexport class GxIdeProgressBar {\n @Element() el: HTMLGxIdeProgressBarElement;\n\n /**\n * If true it will display the caption\n */\n @State() topStateBarVisible: boolean = false;\n\n /**\n * If true the progress will be updated instantly, without transition. This is required when the host user is calling the \"reset\" method.\n */\n @State() disableTransition: boolean = false;\n\n /**\n * If true it will display bar\n */\n @State() visible: boolean = false;\n\n /**\n * The top-bar title\n */\n @Prop() readonly caption: string;\n\n /**\n * It will only display the bar (no title, no close button)\n */\n @Prop({ reflect: true }) readonly minimal: boolean = false;\n\n /**\n * The top-bar active state. If false it will be hidden\n */\n @Prop({ mutable: true }) active: boolean = false;\n @Watch(\"active\")\n watchActiveHandler(active: boolean) {\n if (active) {\n this.visible = true;\n setTimeout(() => {\n this.topStateBarVisible = true;\n }, 300);\n } else {\n this.topStateBarVisible = false;\n setTimeout(() => {\n this.visible = false;\n this.el.style.setProperty(\"--top-bar-progress\", `0%`);\n this.progressBarClosed.emit();\n }, 300);\n }\n }\n\n /**\n * The top-bar state\n */\n @Prop({ mutable: true }) stateType: TopStateBarType = \"in-progress\";\n\n /**\n * The progress bar progress\n */\n @Prop({ mutable: true }) progress: number = undefined;\n @Watch(\"progress\")\n watchProgressHandler(progress: number) {\n if (progress >= 0 && progress <= 100) {\n this.el.style.setProperty(\"--top-bar-progress\", `${progress}%`);\n }\n if (progress === 100 && this.closeType === \"auto-close\") {\n setTimeout(() => {\n this.active = false;\n }, 200);\n }\n }\n\n /**\n * How to display the close button\n */\n @Prop() readonly closeType: \"auto-close\" | \"button\" = \"button\";\n\n /**\n * A callback that gets called when the top-state-bar is closed\n */\n @Prop() readonly closedCallback: () => void = () => {};\n\n /**\n * Emitted every time the progress bar is closed.\n */\n @Event() progressBarClosed: EventEmitter;\n\n componentWillLoad() {\n this.evaluateInitialProgress();\n if (this.active) {\n this.visible = true;\n this.topStateBarVisible = true;\n }\n }\n\n /**\n * Sets the progress bar to zero instantly (no transition) and changes the type\n * to 'accent'. Useful when reusing the progress bar for a new process.\n */\n @Method()\n async reset() {\n // Resetting involves setting the progress to zero. In this case it is preferable\n // to disable the transition.\n this.disableTransition = true;\n this.progress = 0;\n this.stateType = \"accent\";\n setTimeout(() => {\n this.disableTransition = false; // enable transition for the nex process.\n }, PROGRESS_TRANSITION_SPEED);\n }\n\n private evaluateInitialProgress = () => {\n if (\n this.progress === undefined &&\n (this.stateType === \"error\" ||\n this.stateType === \"warning\" ||\n this.stateType === \"success\")\n ) {\n this.progress = 100;\n } else if (\n this.progress === undefined &&\n this.stateType === \"in-progress\"\n ) {\n this.progress = 0;\n }\n this.el.style.setProperty(\"--top-bar-progress\", `${this.progress}%`);\n };\n\n private closeClickHandler = () => {\n this.active = false;\n this.closedCallback();\n };\n\n private renderClose = () => {\n return (\n this.closeType === \"button\" && (\n <button\n class=\"button-tertiary button-icon-only\"\n aria-label=\"close\"\n onClick={this.closeClickHandler}\n role=\"button\"\n tabIndex={this.visible ? 0 : -1}\n >\n <ch-image src={CLOSE_ICON} class=\"icon-m\"></ch-image>\n </button>\n )\n );\n };\n\n render() {\n return (\n <Host\n class={{\n \"visible\": this.visible,\n \"with-close-button\": this.closeType === \"button\",\n \"disable-transition\": this.disableTransition\n }}\n aria-hidden={!this.active}\n style={{\n \"--progress-bar-transition-speed\": `${PROGRESS_TRANSITION_SPEED}ms`\n }}\n >\n <ch-theme model={CSS_BUNDLES}></ch-theme>\n <div\n role=\"status\"\n aria-labelledby=\"label\"\n aria-hidden={!this.active}\n class={{\n \"top-state-bar\": true,\n [`top-state-bar--${this.stateType}`]: true,\n \"top-state-bar--visible\": this.topStateBarVisible\n }}\n >\n <div class=\"top-state-bar__outer-wrapper\">\n {!this.minimal ? (\n <div class=\"top-state-bar__inner-wrapper\">\n <label\n id=\"label\"\n class={{\n \"top-state-bar__caption\": true\n }}\n part=\"label\"\n >\n {this.caption}\n </label>\n\n {this.renderClose()}\n </div>\n ) : null}\n <div\n class={{\n \"top-state-bar__progress-wrapper\": true\n }}\n part=\"progress-wrapper\"\n >\n <span class=\"progress-bar\"></span>\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n\nexport type TopStateBarType =\n | \"accent\"\n | \"success\"\n | \"warning\"\n | \"error\"\n | \"in-progress\";\n"],"version":3}
1
+ {"file":"gx-ide-progress-bar.entry.cjs.js","mappings":"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","names":["getIconPath","h","Host"],"sources":["src/components/_helpers/progress-bar/progress-bar.scss?tag=gx-ide-progress-bar&encapsulation=shadow","src/components/_helpers/progress-bar/progress-bar.tsx"],"sourcesContent":["// --progress-bar-transition-speed is defined on the Host in the .tsx\n$border: 1px solid var(--color-border-surface-on-elevation-1);\n\n:host {\n --top-bar-progress: 0%;\n display: grid;\n grid-template-rows: 0fr;\n transition: var(--timing-fast) grid-template-rows;\n overflow: hidden;\n\n //icon\n --ds-icon-size-box--small: var(--font-size-body-s);\n --ds-icon-size--small: 100%;\n\n > * {\n overflow: hidden;\n }\n}\n:host(.disable-transition) {\n --progress-bar-transition-speed: 0 !important;\n}\n:host(.visible) {\n grid-template-rows: 1fr;\n}\n.top-state-bar {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-l);\n\n > * {\n position: relative;\n z-index: 1;\n }\n border-radius: 4px;\n list-style: var(--font-size-body-s);\n display: flex;\n\n &__outer-wrapper {\n &::after,\n &::before {\n border-radius: 4px;\n }\n &::before {\n content: \"\";\n inline-size: 100%;\n block-size: 100%;\n inset-inline-start: 0;\n inset-block-start: 0;\n position: absolute;\n background-color: var(--color-accent-surface-elevation-3);\n z-index: 0;\n }\n &::after {\n content: \"\";\n inset-inline-start: 1px;\n inset-block-start: 1px;\n inline-size: calc(100% - 1px * 2);\n block-size: calc(100% - 1px * 2);\n position: absolute;\n background-color: var(--color-accent-surface-surface);\n z-index: 1;\n }\n\n position: relative;\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-l);\n padding: var(--spacing-padding-l) var(--spacing-padding-l);\n }\n &__inner-wrapper {\n flex: 1;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n gap: var(--spacing-gap-m);\n position: relative;\n z-index: 2;\n }\n &__caption {\n color: var(--color-text-neutral-strawberry);\n font-size: var(--font-size-body-s);\n line-height: var(--font-size-body-s);\n font-weight: var(--font-style-regular);\n display: flex;\n align-items: center;\n font-style: italic;\n }\n &__progress-wrapper {\n block-size: 4px;\n background-color: var(--color-accent-surface-elevation-1);\n position: relative;\n z-index: 2;\n }\n &__close {\n cursor: pointer;\n transition: var(--timing-fast) background-color;\n }\n &__inner-wrapper,\n &__progress-wrapper,\n &__close {\n opacity: 0;\n transition: 150ms opacity;\n }\n\n /*states*/\n &--accent {\n .progress-bar {\n background-color: var(--color-accent-primary-default);\n }\n }\n &--success {\n .progress-bar {\n background-color: var(--color-border-success-default);\n }\n }\n &--warning {\n .progress-bar {\n background-color: var(--color-border-warning-default);\n }\n }\n &--error {\n .progress-bar {\n background-color: var(--color-border-error-default);\n }\n }\n &--in-progress {\n .top-state-bar__outer-wrapper:before {\n block-size: 0;\n inline-size: 120%;\n padding-block-start: 60%;\n padding-block-end: 60%;\n background: linear-gradient(\n 90deg,\n rgba(91, 167, 255, 0.4) 0%,\n rgba(63, 168, 155, 0.4) 100%\n );\n inset-block-start: 50%;\n inset-inline-start: 50%;\n transform: translate(-50%, -50%);\n -webkit-animation: inProgressBackgroundColor 1s linear infinite;\n animation: inProgressBackgroundColor 1s linear infinite;\n }\n .progress-bar {\n position: relative;\n overflow: hidden;\n z-index: 1;\n &:after {\n content: \"\";\n position: absolute;\n z-index: 0;\n inline-size: 300%;\n block-size: 100%;\n inset-inline-start: 0;\n background: linear-gradient(\n 90deg,\n rgba(147, 245, 235, 1) 0%,\n rgba(26, 163, 255, 1) 33%,\n rgba(147, 245, 235, 1) 66%,\n rgba(26, 163, 255, 1) 100%\n );\n animation-name: inProgressBar;\n animation-duration: 2s;\n animation-iteration-count: infinite;\n }\n }\n }\n &--visible {\n .top-state-bar__inner-wrapper,\n .top-state-bar__progress-wrapper,\n .top-state-bar__close {\n opacity: 1;\n }\n .top-state-bar__close {\n &:hover {\n opacity: 0.75;\n }\n &:active {\n opacity: 0.5;\n }\n }\n }\n}\n\n// With Close Button (some spacing needs to be adjusted)\n:host(.with-close-button) {\n .top-state-bar {\n &__outer-wrapper {\n padding-block-start: 4px;\n gap: var(--spacing-gap-xs);\n }\n }\n}\n\n// Plain: renders the bar inline, without the elevated surface \"card\"\n// (no background, no border, no padding). Opt-in for embedded usages.\n:host(.plain) {\n .top-state-bar__outer-wrapper {\n padding: 0;\n\n &::before,\n &::after {\n display: none;\n }\n }\n\n // Without the surface \"card\" behind it, the unfilled track would blend into\n // the host's background (they can share the same elevation). A translucent\n // neutral tint keeps the track visible on any surface elevation and theme,\n // since it contrasts relative to whatever is painted behind it.\n .top-state-bar__progress-wrapper {\n background-color: color-mix(\n in srgb,\n var(--color-text-neutral-default) 25%,\n transparent\n );\n }\n}\n\n/*in progress animation*/\n@-webkit-keyframes inProgressBackgroundColor {\n 0% {\n transform: translate(-50%, -50%) rotate(0);\n }\n 100% {\n transform: translate(-50%, -50%) rotate(1turn);\n }\n}\n@-webkit-keyframes inProgressBar {\n 0% {\n inset-inline-start: 0%;\n }\n 100% {\n inset-inline-start: -200%;\n }\n}\n@-moz-keyframes inProgressBar {\n 0% {\n inset-inline-start: 0%;\n }\n 100% {\n inset-inline-start: 200%;\n }\n}\n@keyframes inProgressBar {\n 0% {\n inset-inline-start: 0%;\n }\n 100% {\n inset-inline-start: -200%;\n }\n}\n\n.progress-bar {\n display: block;\n transition: all var(--progress-bar-transition-speed);\n inline-size: var(--top-bar-progress);\n border-radius: calc(4px / 2);\n block-size: 100%;\n}\n\n:host(.no-border),\n:host(.border-block-start),\n:host(.border-block-end) {\n .top-state-bar__outer-wrapper {\n &:before {\n display: none;\n }\n }\n}\n:host(.border-block-start) {\n .top-state-bar__outer-wrapper {\n border-block-start: $border;\n }\n}\n:host(.border-block-end) {\n .top-state-bar__outer-wrapper {\n border-block-end: $border;\n }\n}\n","import {\n Component,\n Host,\n h,\n Prop,\n State,\n Watch,\n Element,\n Event,\n EventEmitter,\n Method\n} from \"@stencil/core\";\nimport { MercuryBundles, getIconPath } from \"@genexus/mercury\";\n\nconst CSS_BUNDLES: MercuryBundles = [\n \"resets/box-sizing\",\n \"utils/form\",\n \"utils/layout\",\n \"utils/typography\",\n \"components/button\",\n \"components/icon\",\n \"components/combo-box\",\n \"components/edit\",\n \"components/tabular-grid\"\n];\n\nconst CLOSE_ICON = getIconPath({\n category: \"system\",\n name: \"close\",\n colorType: \"primary\"\n});\nconst PROGRESS_TRANSITION_SPEED = 200;\n\n@Component({\n tag: \"gx-ide-progress-bar\",\n styleUrl: \"progress-bar.scss\",\n shadow: true,\n assetsDirs: [\"gx-ide-assets/progress-bar\"]\n})\nexport class GxIdeProgressBar {\n @Element() el: HTMLGxIdeProgressBarElement;\n\n /**\n * If true it will display the caption\n */\n @State() topStateBarVisible: boolean = false;\n\n /**\n * If true the progress will be updated instantly, without transition. This is required when the host user is calling the \"reset\" method.\n */\n @State() disableTransition: boolean = false;\n\n /**\n * If true it will display bar\n */\n @State() visible: boolean = false;\n\n /**\n * The top-bar title\n */\n @Prop() readonly caption: string;\n\n /**\n * It will only display the bar (no title, no close button)\n */\n @Prop({ reflect: true }) readonly minimal: boolean = false;\n\n /**\n * The top-bar active state. If false it will be hidden\n */\n @Prop({ mutable: true }) active: boolean = false;\n @Watch(\"active\")\n watchActiveHandler(active: boolean) {\n if (active) {\n this.visible = true;\n setTimeout(() => {\n this.topStateBarVisible = true;\n }, 300);\n } else {\n this.topStateBarVisible = false;\n setTimeout(() => {\n this.visible = false;\n this.el.style.setProperty(\"--top-bar-progress\", `0%`);\n this.progressBarClosed.emit();\n }, 300);\n }\n }\n\n /**\n * The top-bar state\n */\n @Prop({ mutable: true }) stateType: TopStateBarType = \"in-progress\";\n\n /**\n * The progress bar progress\n */\n @Prop({ mutable: true }) progress: number = undefined;\n @Watch(\"progress\")\n watchProgressHandler(progress: number) {\n if (progress >= 0 && progress <= 100) {\n this.el.style.setProperty(\"--top-bar-progress\", `${progress}%`);\n }\n if (progress === 100 && this.closeType === \"auto-close\") {\n setTimeout(() => {\n this.active = false;\n }, 200);\n }\n }\n\n /**\n * How to display the close button\n */\n @Prop() readonly closeType: \"auto-close\" | \"button\" = \"button\";\n\n /**\n * A callback that gets called when the top-state-bar is closed\n */\n @Prop() readonly closedCallback: () => void = () => {};\n\n /**\n * Emitted every time the progress bar is closed.\n */\n @Event() progressBarClosed: EventEmitter;\n\n componentWillLoad() {\n this.evaluateInitialProgress();\n if (this.active) {\n this.visible = true;\n this.topStateBarVisible = true;\n }\n }\n\n /**\n * Sets the progress bar to zero instantly (no transition) and changes the type\n * to 'accent'. Useful when reusing the progress bar for a new process.\n */\n @Method()\n async reset() {\n // Resetting involves setting the progress to zero. In this case it is preferable\n // to disable the transition.\n this.disableTransition = true;\n this.progress = 0;\n this.stateType = \"accent\";\n setTimeout(() => {\n this.disableTransition = false; // enable transition for the nex process.\n }, PROGRESS_TRANSITION_SPEED);\n }\n\n private evaluateInitialProgress = () => {\n if (\n this.progress === undefined &&\n (this.stateType === \"error\" ||\n this.stateType === \"warning\" ||\n this.stateType === \"success\")\n ) {\n this.progress = 100;\n } else if (\n this.progress === undefined &&\n this.stateType === \"in-progress\"\n ) {\n this.progress = 0;\n }\n this.el.style.setProperty(\"--top-bar-progress\", `${this.progress}%`);\n };\n\n private closeClickHandler = () => {\n this.active = false;\n this.closedCallback();\n };\n\n private renderClose = () => {\n return (\n this.closeType === \"button\" && (\n <button\n class=\"button-tertiary button-icon-only\"\n aria-label=\"close\"\n onClick={this.closeClickHandler}\n role=\"button\"\n tabIndex={this.visible ? 0 : -1}\n >\n <ch-image src={CLOSE_ICON} class=\"icon-m\"></ch-image>\n </button>\n )\n );\n };\n\n render() {\n return (\n <Host\n class={{\n \"visible\": this.visible,\n \"with-close-button\": this.closeType === \"button\",\n \"disable-transition\": this.disableTransition\n }}\n aria-hidden={!this.active}\n style={{\n \"--progress-bar-transition-speed\": `${PROGRESS_TRANSITION_SPEED}ms`\n }}\n >\n <ch-theme model={CSS_BUNDLES}></ch-theme>\n <div\n role=\"status\"\n aria-labelledby=\"label\"\n aria-hidden={!this.active}\n class={{\n \"top-state-bar\": true,\n [`top-state-bar--${this.stateType}`]: true,\n \"top-state-bar--visible\": this.topStateBarVisible\n }}\n >\n <div class=\"top-state-bar__outer-wrapper\">\n {!this.minimal ? (\n <div class=\"top-state-bar__inner-wrapper\">\n <label\n id=\"label\"\n class={{\n \"top-state-bar__caption\": true\n }}\n part=\"label\"\n >\n {this.caption}\n </label>\n\n {this.renderClose()}\n </div>\n ) : null}\n <div\n class={{\n \"top-state-bar__progress-wrapper\": true\n }}\n part=\"progress-wrapper\"\n >\n <span class=\"progress-bar\"></span>\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n\nexport type TopStateBarType =\n | \"accent\"\n | \"success\"\n | \"warning\"\n | \"error\"\n | \"in-progress\";\n"],"version":3}