@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
@@ -1 +1 @@
1
- {"file":"gx-ide-db-properties-configurator.entry.js","mappings":";;;;;;;;;AAAA,MAAM,2BAA2B,GAAG,4sEAA4sE;;;;;;;;;;;;;;;;;;;ACQhvE,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;MAQ1B,6BAA6B;;;;QAExC,iEAAsB;QAgCtB,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,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;0BA/L+C,EAAE;;;;;IAmBnD,MAAM,iBAAiB;QACrB,uBAAA,IAAI,kDAAoB,MAAM,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC,MAAA,CAAC;KACnE;;IA8KD,MAAM;;QACJ,MAAM,KAAK,GAAG,uBAAA,IAAI,sDAAiB,CAAC,MAAM,CAAC,KAAK,CAAC;QACjD,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,eAAS,KAAK,EAAC,SAAS,IACtB,WAAK,KAAK,EAAC,MAAM,IACf,WAAK,KAAK,EAAC,YAAY,IACrB,UAAI,KAAK,EAAC,kCAAkC,IAAE,KAAK,CAAM,EACxD,WAAW,KACV,SAAG,KAAK,EAAC,kCAAkC,IAAE,WAAW,CAAK,CAC9D,CACG,EACN,WAAK,KAAK,EAAC,aAAa,iBAAa,MAAM,IACzC,gBAAU,KAAK,EAAC,SAAS,EAAC,GAAG,EAAE,aAAa,GAAa,CACrD,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":[],"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.entry.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;MAQ1B,6BAA6B;;;;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":[],"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}
@@ -6,7 +6,7 @@ import 'lit/directives/when.js';
6
6
  import 'lit/directives/if-defined.js';
7
7
  import { L as Locale } from './locale-e5107fad.js';
8
8
 
9
- const pluginDetailsCss = "ch-tab-render.tab{background-color:transparent;border-color:transparent}ch-tab-render.tab::part(tab-list block-start){border-block-end:none}ch-tab-render.tab::part(tab block closable),ch-tab-render.tab::part(tab block not-closable){background-color:transparent}:host{display:grid;block-size:100%;grid-template-areas:\"header header\" \"main aside\";grid-template-rows:max-content 1fr;grid-template-columns:1fr 280px;row-gap:var(--spacing-gap-l)}.section{display:contents}.header{display:grid;grid-area:header;grid-template-areas:\"plugin-icon plugin-details\";grid-template-columns:64px 1fr;column-gap:var(--spacing-gap-xl);padding-block-start:var(--spacing-padding-xxl);padding-block-end:var(--spacing-padding-xl);padding-inline:var(--spacing-padding-xxl)}.plugin__icon{grid-area:plugin-icon;inline-size:100%;block-size:auto;display:block}.plugin__details{grid-area:plugin-details;display:flex;flex-direction:column;gap:var(--spacing-gap-m)}.plugin__publisher{display:flex;align-items:center;gap:var(--spacing-gap-xs)}.plugin__description{line-height:var(--line-height-spacious)}.plugin__actions-container{margin-block-start:var(--spacing-padding-m);align-items:center}.action-button{min-inline-size:100px}.action-button.more-versions-available{border-start-end-radius:0 !important;border-end-end-radius:0 !important}.installed-container{display:flex;align-items:center;gap:var(--spacing-gap-m)}.installed-container ch-image{--ch-image-size:20px}.main{grid-area:main}.docsTab{block-size:100%}.aside{grid-area:aside;overflow:auto;border-block-start:1px solid var(--items-container__border-color)}.fields__list{list-style:none;padding:0;margin:0;font-size:var(--font-size-body-s)}.plugin__info-category{display:flex;flex-direction:column;gap:var(--spacing-gap-m)}.plugin__info-category:not(:first-child){padding-block-start:var(--spacing-padding-xl);margin-block-start:var(--spacing-padding-xl);border-block-start:1px solid var(--color-border-surface-on-elevation-1)}.fields__list:not(.fields__list--as-tags){display:flex;flex-direction:column;gap:var(--spacing-gap-m)}.fields__list:not(.fields__list--as-tags) .field__li{display:flex;gap:var(--spacing-gap-xl)}.fields__list--as-tags{display:flex;flex-wrap:wrap;gap:var(--spacing-gap-m)}.fields__list--as-tags .field__li{border:1px solid var(--color-border-surface-on-elevation-1);padding-block:var(--spacing-padding-xxs);padding-inline:var(--spacing-padding-m);border-radius:4px;text-transform:lowercase}.fields__list--as-tags .field__link{color:var(--color-text-neutral-strawberry)}.fields__list--as-tags .field__link:hover{color:var(--color-accent-primary-default)}.fields__list--as-tags .field__link:active{color:var(--color-accent-primary-hover)}.field__name,.field__value{flex:1}.field__link{color:var(--color-accent-primary-default)}.field__link:hover{color:var(--color-accent-primary-hover)}.field__link:active{color:var(--color-accent-primary-pressed)}.docsTab{background-color:transparent !important}.dropdown.button-icon-only::part(expandable-button){padding:calc( (var(--control-block-size) - 2 * var(--control-border-width) - 16px) / 2 ) !important;border-start-start-radius:0 !important;border-end-start-radius:0 !important}.version-buttons-container{display:flex;align-items:center;gap:1px}ch-markdown-viewer{block-size:100%;overflow:auto}.text-underline{text-decoration:underline}";
9
+ const pluginDetailsCss = "ch-tab-render.tab{background-color:transparent;border-color:transparent}ch-tab-render.tab::part(tab-list block-start){border-block-end:none}ch-tab-render.tab::part(tab block closable),ch-tab-render.tab::part(tab block not-closable){background-color:transparent}:host{display:grid;block-size:100%;grid-template-areas:\"header header\" \"main aside\";grid-template-rows:max-content 1fr;grid-template-columns:1fr 280px;row-gap:var(--spacing-gap-l)}.section{display:contents}.header{display:grid;grid-area:header;grid-template-areas:\"plugin-icon plugin-details\";grid-template-columns:64px 1fr;column-gap:var(--spacing-gap-xl);padding-block-start:var(--spacing-padding-xxl);padding-block-end:var(--spacing-padding-xl);padding-inline:var(--spacing-padding-xxl)}.plugin__icon{grid-area:plugin-icon;inline-size:100%;block-size:auto;display:block}.plugin__details{grid-area:plugin-details;display:flex;flex-direction:column;gap:var(--spacing-gap-m)}.plugin__publisher{display:flex;align-items:center;gap:var(--spacing-gap-xs)}.plugin__description{line-height:var(--line-height-spacious)}.plugin__actions-container{margin-block-start:var(--spacing-padding-m);align-items:center;min-block-size:calc(var(--control-block-size) + var(--spacing-gap-xs) + 4px)}.action-button{min-inline-size:100px}.action-button.more-versions-available{border-start-end-radius:0 !important;border-end-end-radius:0 !important}.installed-container{display:flex;align-items:center;gap:var(--spacing-gap-m)}.installed-container ch-image{--ch-image-size:20px}.main{grid-area:main}.docsTab{block-size:100%}.aside{grid-area:aside;overflow:auto;border-block-start:1px solid var(--items-container__border-color)}.fields__list{list-style:none;padding:0;margin:0;font-size:var(--font-size-body-s)}.plugin__info-category{display:flex;flex-direction:column;gap:var(--spacing-gap-m)}.plugin__info-category:not(:first-child){padding-block-start:var(--spacing-padding-xl);margin-block-start:var(--spacing-padding-xl);border-block-start:1px solid var(--color-border-surface-on-elevation-1)}.fields__list:not(.fields__list--as-tags){display:flex;flex-direction:column;gap:var(--spacing-gap-m)}.fields__list:not(.fields__list--as-tags) .field__li{display:flex;gap:var(--spacing-gap-xl)}.fields__list--as-tags{display:flex;flex-wrap:wrap;gap:var(--spacing-gap-m)}.fields__list--as-tags .field__li{border:1px solid var(--color-border-surface-on-elevation-1);padding-block:var(--spacing-padding-xxs);padding-inline:var(--spacing-padding-m);border-radius:4px;text-transform:lowercase}.fields__list--as-tags .field__link{color:var(--color-text-neutral-strawberry)}.fields__list--as-tags .field__link:hover{color:var(--color-accent-primary-default)}.fields__list--as-tags .field__link:active{color:var(--color-accent-primary-hover)}.field__name,.field__value{flex:1}.field__link{color:var(--color-accent-primary-default)}.field__link:hover{color:var(--color-accent-primary-hover)}.field__link:active{color:var(--color-accent-primary-pressed)}.docsTab{background-color:transparent !important}.dropdown.button-icon-only::part(expandable-button){padding:calc( (var(--control-block-size) - 2 * var(--control-border-width) - 16px) / 2 ) !important;border-start-start-radius:0 !important;border-end-start-radius:0 !important}.version-buttons-container{display:flex;align-items:stretch;gap:1px}.install-progress{flex:1;min-inline-size:220px}ch-markdown-viewer{block-size:100%;overflow:auto}.text-underline{text-decoration:underline}";
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 _GxIdePluginDetails_componentLocale, _GxIdePluginDetails_chMarkdownViewer, _GxIdePluginDetails_docSectionIdDescriptionMap, _GxIdePluginDetails_versionsMenuOptionsModel, _GxIdePluginDetails_menuVersionSelectedHandler, _GxIdePluginDetails_renderUninstallButton, _GxIdePluginDetails_installClickedHandler, _GxIdePluginDetails_updateVersionHandler, _GxIdePluginDetails_openLinkHandler, _GxIdePluginDetails_uninstallClickedHandler, _GxIdePluginDetails_renderActionButtons, _GxIdePluginDetails_tabSelectionChangedHandler, _GxIdePluginDetails_renderDocSectionsSlots, _GxIdePluginDetails_returnFormatedId, _GxIdePluginDetails_renderLinkTag, _GxIdePluginDetails_renderAsideContent;
27
+ var _GxIdePluginDetails_componentLocale, _GxIdePluginDetails_chMarkdownViewer, _GxIdePluginDetails_docSectionIdDescriptionMap, _GxIdePluginDetails_versionsMenuOptionsModel, _GxIdePluginDetails_menuVersionSelectedHandler, _GxIdePluginDetails_renderUninstallButton, _GxIdePluginDetails_latestVersionId, _GxIdePluginDetails_installClickedHandler, _GxIdePluginDetails_openLinkHandler, _GxIdePluginDetails_uninstallClickedHandler, _GxIdePluginDetails_cancelClickedHandler, _GxIdePluginDetails_renderInstallProgress, _GxIdePluginDetails_renderActionButtons, _GxIdePluginDetails_tabSelectionChangedHandler, _GxIdePluginDetails_renderDocSectionsSlots, _GxIdePluginDetails_returnFormatedId, _GxIdePluginDetails_renderLinkTag, _GxIdePluginDetails_renderAsideContent;
28
28
  const USER_ICON = getIconPath({
29
29
  category: "system",
30
30
  name: "user",
@@ -71,22 +71,22 @@ const GxIdePluginDetails = class {
71
71
  _GxIdePluginDetails_versionsMenuOptionsModel.set(this, () => {
72
72
  var _a;
73
73
  const versionsToUpdateMenusModel = (_a = this.data.versions) === null || _a === void 0 ? void 0 : _a.map(version => {
74
- return { id: version, caption: version };
74
+ // The menu id carries the ordinal versionId; the caption shows the human-readable version.
75
+ return { id: String(version.versionId), caption: version.version };
75
76
  });
76
77
  return versionsToUpdateMenusModel;
77
78
  });
78
79
  _GxIdePluginDetails_menuVersionSelectedHandler.set(this, (event) => {
79
- const selectedVersion = event.detail.id;
80
- this.installCallback(selectedVersion);
80
+ const selectedVersionId = event.detail.id;
81
+ this.installCallback(selectedVersionId != null ? Number(selectedVersionId) : undefined);
81
82
  });
82
83
  _GxIdePluginDetails_renderUninstallButton.set(this, () => {
83
84
  return (h("button", { class: "button-tertiary", onClick: __classPrivateFieldGet(this, _GxIdePluginDetails_uninstallClickedHandler, "f") }, __classPrivateFieldGet(this, _GxIdePluginDetails_componentLocale, "f").actions.uninstall));
84
85
  });
86
+ // The latest version is listed first; its ordinal drives install/update from the primary button.
87
+ _GxIdePluginDetails_latestVersionId.set(this, () => { var _a, _b; return (_b = (_a = this.data.versions) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.versionId; });
85
88
  _GxIdePluginDetails_installClickedHandler.set(this, () => {
86
- this.installCallback();
87
- });
88
- _GxIdePluginDetails_updateVersionHandler.set(this, (id) => () => {
89
- this.installCallback(id);
89
+ this.installCallback(__classPrivateFieldGet(this, _GxIdePluginDetails_latestVersionId, "f").call(this));
90
90
  });
91
91
  _GxIdePluginDetails_openLinkHandler.set(this, (link) => (event) => {
92
92
  if (this.openLinkCallback) {
@@ -97,19 +97,33 @@ const GxIdePluginDetails = class {
97
97
  _GxIdePluginDetails_uninstallClickedHandler.set(this, () => {
98
98
  this.uninstallCallback();
99
99
  });
100
+ _GxIdePluginDetails_cancelClickedHandler.set(this, () => {
101
+ this.cancelCallback();
102
+ });
103
+ _GxIdePluginDetails_renderInstallProgress.set(this, () => {
104
+ const { phase, percent } = this.installProgress;
105
+ const caption = phase === "download"
106
+ ? __classPrivateFieldGet(this, _GxIdePluginDetails_componentLocale, "f").actions.downloading
107
+ : __classPrivateFieldGet(this, _GxIdePluginDetails_componentLocale, "f").actions.installing;
108
+ return (h("gx-ide-progress-bar", { class: "install-progress plain", active: true, caption: `${caption} ${percent}%`, progress: percent, stateType: "in-progress", closeType: "button", closedCallback: __classPrivateFieldGet(this, _GxIdePluginDetails_cancelClickedHandler, "f") }));
109
+ });
100
110
  _GxIdePluginDetails_renderActionButtons.set(this, () => {
101
111
  var _a;
112
+ // While an install/update is running, replace the buttons with a determinate progress bar.
113
+ if (this.installProgress) {
114
+ return __classPrivateFieldGet(this, _GxIdePluginDetails_renderInstallProgress, "f").call(this);
115
+ }
102
116
  let actionButtonCaption;
103
117
  let actionButtonClasses = "button-primary action-button";
104
118
  let actionButtonCallback;
105
- const moreVersionsToUpdate = (_a = this.data.versions) === null || _a === void 0 ? void 0 : _a.length;
119
+ const moreVersionsToUpdate = ((_a = this.data.versions) === null || _a === void 0 ? void 0 : _a.length) > 1;
106
120
  if (!this.data.installed) {
107
121
  actionButtonCaption = __classPrivateFieldGet(this, _GxIdePluginDetails_componentLocale, "f").actions.install;
108
122
  actionButtonCallback = __classPrivateFieldGet(this, _GxIdePluginDetails_installClickedHandler, "f");
109
123
  }
110
124
  else if (this.data.updateVersion) {
111
125
  actionButtonCaption = `${__classPrivateFieldGet(this, _GxIdePluginDetails_componentLocale, "f").actions.updateTo} ${this.data.updateVersion}`;
112
- actionButtonCallback = __classPrivateFieldGet(this, _GxIdePluginDetails_updateVersionHandler, "f").call(this, this.data.updateVersion);
126
+ actionButtonCallback = () => this.installCallback(__classPrivateFieldGet(this, _GxIdePluginDetails_latestVersionId, "f").call(this));
113
127
  }
114
128
  else {
115
129
  actionButtonCaption = __classPrivateFieldGet(this, _GxIdePluginDetails_componentLocale, "f").actions.installed;
@@ -163,6 +177,8 @@ const GxIdePluginDetails = class {
163
177
  this.selectedTabId = undefined;
164
178
  this.data = undefined;
165
179
  this.installCallback = undefined;
180
+ this.installProgress = undefined;
181
+ this.cancelCallback = undefined;
166
182
  this.openLinkCallback = undefined;
167
183
  this.uninstallCallback = undefined;
168
184
  }
@@ -184,7 +200,9 @@ const GxIdePluginDetails = class {
184
200
  }
185
201
  }
186
202
  componentDidLoad() {
187
- __classPrivateFieldGet(this, _GxIdePluginDetails_chMarkdownViewer, "f").addEventListener("click", event => {
203
+ var _a;
204
+ // Guard: #chMarkdownViewer is unset when there are no docSections.
205
+ (_a = __classPrivateFieldGet(this, _GxIdePluginDetails_chMarkdownViewer, "f")) === null || _a === void 0 ? void 0 : _a.addEventListener("click", event => {
188
206
  // Listens for clicks on links inside <ch-markdown-viewer>.
189
207
  // If a link (<a>) is clicked and openLinkCallback is defined,
190
208
  // it prevents the default navigation and delegates the event
@@ -214,7 +232,7 @@ const GxIdePluginDetails = class {
214
232
  static get assetsDirs() { return ["gx-ide-assets/plugin-details"]; }
215
233
  get el() { return getElement(this); }
216
234
  };
217
- _GxIdePluginDetails_componentLocale = new WeakMap(), _GxIdePluginDetails_chMarkdownViewer = new WeakMap(), _GxIdePluginDetails_docSectionIdDescriptionMap = new WeakMap(), _GxIdePluginDetails_versionsMenuOptionsModel = new WeakMap(), _GxIdePluginDetails_menuVersionSelectedHandler = new WeakMap(), _GxIdePluginDetails_renderUninstallButton = new WeakMap(), _GxIdePluginDetails_installClickedHandler = new WeakMap(), _GxIdePluginDetails_updateVersionHandler = new WeakMap(), _GxIdePluginDetails_openLinkHandler = new WeakMap(), _GxIdePluginDetails_uninstallClickedHandler = new WeakMap(), _GxIdePluginDetails_renderActionButtons = new WeakMap(), _GxIdePluginDetails_tabSelectionChangedHandler = new WeakMap(), _GxIdePluginDetails_renderDocSectionsSlots = new WeakMap(), _GxIdePluginDetails_returnFormatedId = new WeakMap(), _GxIdePluginDetails_renderLinkTag = new WeakMap(), _GxIdePluginDetails_renderAsideContent = new WeakMap();
235
+ _GxIdePluginDetails_componentLocale = new WeakMap(), _GxIdePluginDetails_chMarkdownViewer = new WeakMap(), _GxIdePluginDetails_docSectionIdDescriptionMap = new WeakMap(), _GxIdePluginDetails_versionsMenuOptionsModel = new WeakMap(), _GxIdePluginDetails_menuVersionSelectedHandler = new WeakMap(), _GxIdePluginDetails_renderUninstallButton = new WeakMap(), _GxIdePluginDetails_latestVersionId = new WeakMap(), _GxIdePluginDetails_installClickedHandler = new WeakMap(), _GxIdePluginDetails_openLinkHandler = new WeakMap(), _GxIdePluginDetails_uninstallClickedHandler = new WeakMap(), _GxIdePluginDetails_cancelClickedHandler = new WeakMap(), _GxIdePluginDetails_renderInstallProgress = new WeakMap(), _GxIdePluginDetails_renderActionButtons = new WeakMap(), _GxIdePluginDetails_tabSelectionChangedHandler = new WeakMap(), _GxIdePluginDetails_renderDocSectionsSlots = new WeakMap(), _GxIdePluginDetails_returnFormatedId = new WeakMap(), _GxIdePluginDetails_renderLinkTag = new WeakMap(), _GxIdePluginDetails_renderAsideContent = new WeakMap();
218
236
  GxIdePluginDetails.style = pluginDetailsCss;
219
237
 
220
238
  export { GxIdePluginDetails as gx_ide_plugin_details };
@@ -1 +1 @@
1
- {"file":"gx-ide-plugin-details.entry.js","mappings":"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","names":[],"sources":["src/components/plugin-details/plugin-details.scss?tag=gx-ide-plugin-details&encapsulation=shadow","src/components/plugin-details/plugin-details.tsx"],"sourcesContent":["@import \"../../global/temporary-mercury-overrides/_tab.scss\";\n\n:host {\n display: grid;\n block-size: 100%;\n grid-template-areas:\n \"header header\"\n \"main aside\";\n grid-template-rows: max-content 1fr;\n grid-template-columns: 1fr 280px;\n row-gap: var(--spacing-gap-l);\n}\n\n.section {\n display: contents;\n}\n\n// header\n.header {\n display: grid;\n grid-area: header;\n grid-template-areas: \"plugin-icon plugin-details\";\n grid-template-columns: 64px 1fr;\n column-gap: var(--spacing-gap-xl);\n padding-block-start: var(--spacing-padding-xxl);\n padding-block-end: var(--spacing-padding-xl);\n padding-inline: var(--spacing-padding-xxl);\n}\n.plugin__icon {\n grid-area: plugin-icon;\n inline-size: 100%;\n block-size: auto;\n display: block;\n}\n.plugin__details {\n grid-area: plugin-details;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-m);\n}\n.plugin__publisher {\n display: flex;\n align-items: center;\n gap: var(--spacing-gap-xs);\n}\n.plugin__description {\n line-height: var(--line-height-spacious); // WA: Text appears too tight.\n}\n.plugin__actions-container {\n margin-block-start: var(--spacing-padding-m);\n align-items: center;\n}\n.action-button {\n min-inline-size: 100px;\n\n &.more-versions-available {\n border-start-end-radius: 0 !important;\n border-end-end-radius: 0 !important;\n }\n}\n.installed-container {\n display: flex;\n align-items: center;\n gap: var(--spacing-gap-m);\n\n // WA Biggest Mercury icon (icon-s) looks small in this case.\n // Mercury should expose more icon sizes.\n ch-image {\n --ch-image-size: 20px;\n }\n}\n\n// main\n.main {\n grid-area: main;\n}\n.docsTab {\n block-size: 100%;\n}\n\n// aside\n.aside {\n grid-area: aside;\n overflow: auto;\n border-block-start: 1px solid var(--items-container__border-color);\n}\n.fields__list {\n list-style: none;\n padding: 0;\n margin: 0;\n font-size: var(--font-size-body-s);\n}\n.plugin__info-category {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-m);\n\n &:not(:first-child) {\n padding-block-start: var(--spacing-padding-xl);\n margin-block-start: var(--spacing-padding-xl);\n border-block-start: 1px solid var(--color-border-surface-on-elevation-1);\n }\n}\n.fields__list:not(.fields__list--as-tags) {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-m);\n .field__li {\n display: flex;\n gap: var(--spacing-gap-xl);\n }\n}\n.fields__list--as-tags {\n display: flex;\n flex-wrap: wrap;\n gap: var(--spacing-gap-m);\n\n .field__li {\n border: 1px solid var(--color-border-surface-on-elevation-1);\n padding-block: var(--spacing-padding-xxs);\n padding-inline: var(--spacing-padding-m);\n border-radius: 4px;\n\n text-transform: lowercase;\n }\n .field__link {\n color: var(--color-text-neutral-strawberry);\n\n &:hover {\n color: var(--color-accent-primary-default);\n }\n &:active {\n color: var(--color-accent-primary-hover);\n }\n }\n}\n\n.field__name,\n.field__value {\n flex: 1;\n}\n// WA: Link styles should be defined Mercury\n.field__link {\n color: var(--color-accent-primary-default);\n &:hover {\n color: var(--color-accent-primary-hover);\n }\n &:active {\n color: var(--color-accent-primary-pressed);\n }\n}\n// WA: Remove tab elevation background color\n.docsTab {\n background-color: transparent !important;\n}\n\n// WA: Styles for \"button-icon-only\" should be defined on mercury\n.dropdown.button-icon-only::part(expandable-button) {\n padding: calc(\n (var(--control-block-size) - 2 * var(--control-border-width) - 16px) / 2\n ) !important;\n border-start-start-radius: 0 !important;\n border-end-start-radius: 0 !important;\n}\n\n.version-buttons-container {\n display: flex;\n align-items: center;\n gap: 1px;\n}\n\nch-markdown-viewer {\n block-size: 100%;\n overflow: auto;\n}\n\n// WA: Need text with underline. This should be defined on Mercury\n.text-underline {\n text-decoration: underline;\n}\n","import {\n Component,\n Host,\n State,\n Prop,\n Element,\n h,\n getAssetPath,\n JSX\n} from \"@stencil/core\";\n\nimport { getIconPath, MercuryBundles } from \"@genexus/mercury\";\nimport { Locale } from \"../../common/locale\";\nimport { ActionMenuModel, TabModel } from \"@genexus/chameleon-controls-library\";\nimport { TabItemModel } from \"@genexus/chameleon-controls-library/dist/types/components/tab/types\";\n\nconst USER_ICON = getIconPath({\n category: \"system\",\n name: \"user\",\n colorType: \"on-surface\"\n});\nconst CHEVRON_DOWN_ICON = getIconPath({\n category: \"system\",\n name: \"chevron-down\",\n colorType: \"on-primary\"\n});\nconst CHECK_CIRCLE_ICON = getIconPath({\n category: \"system\",\n name: \"check-circle\",\n colorType: \"success\"\n});\n\n// plugin icon if no iconUri 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 \"chameleon/scrollbar\",\n \"components/button\",\n \"components/dropdown\",\n \"components/edit\",\n \"components/icon\",\n \"components/list-box\",\n \"components/tab\",\n \"utils/form\",\n \"utils/layout\",\n \"utils/spacing\",\n \"utils/typography\"\n];\n\n@Component({\n tag: \"gx-ide-plugin-details\",\n styleUrl: \"plugin-details.scss\",\n shadow: true,\n assetsDirs: [\"gx-ide-assets/plugin-details\"]\n})\nexport class GxIdePluginDetails {\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\n #chMarkdownViewer: HTMLChMarkdownViewerElement;\n\n // A map between docSection \"id\", and docSection \"description\".\n // \"id\" is generated inside this component.\n #docSectionIdDescriptionMap: Map<string, string> = new Map();\n\n @Element() el: HTMLGxIdePluginDetailsElement;\n\n @State() docsTabModel: TabModel = [];\n @State() selectedTabId: string;\n\n /**\n * Specifies all the information related to a plugin.\n */\n @Prop() readonly data!: PluginDetailsData;\n\n /**\n * Callback that should be invoked when the user performs the install or update action.\n * Receives an optional version string when a specific version is selected.\n */\n @Prop() readonly installCallback!: (version?: string) => Promise<void>;\n\n /**\n * Callback that should be invoked when the user attempts to open any link displayed in this component.\n */\n @Prop() readonly openLinkCallback!: (url: string) => Promise<void>;\n\n /**\n * Callback that should be invoked when the user performs the uninstall action.\n */\n @Prop() readonly uninstallCallback!: () => Promise<void>;\n\n async componentWillLoad() {\n this.#componentLocale = await Locale.getComponentStrings(this.el);\n\n if (this.data.docSections?.length) {\n this.docsTabModel = this.data.docSections.map((docSection, i) => {\n const formatedId = this.#returnFormatedId(docSection.name);\n\n this.#docSectionIdDescriptionMap.set(formatedId, docSection.content);\n\n if (i === 0) {\n this.selectedTabId = formatedId;\n }\n return {\n id: formatedId,\n name: docSection.name\n } as TabItemModel;\n });\n }\n }\n\n componentDidLoad() {\n this.#chMarkdownViewer.addEventListener(\"click\", event => {\n // Listens for clicks on links inside <ch-markdown-viewer>.\n // If a link (<a>) is clicked and openLinkCallback is defined,\n // it prevents the default navigation and delegates the event\n // to this.#openLinkHandler, passing the link's href.\n const path = event.composedPath() as EventTarget[];\n\n const link = path.find(el => el instanceof HTMLAnchorElement) as\n | HTMLAnchorElement\n | undefined;\n\n if (link?.href) {\n this.#openLinkHandler(link.href)(event);\n }\n });\n }\n\n #versionsMenuOptionsModel = (): ActionMenuModel => {\n const versionsToUpdateMenusModel: ActionMenuModel = this.data.versions?.map(\n version => {\n return { id: version, caption: version };\n }\n );\n return versionsToUpdateMenusModel;\n };\n\n #menuVersionSelectedHandler = (\n event: CustomEvent<{\n id?: string;\n }>\n ) => {\n const selectedVersion = event.detail.id;\n this.installCallback(selectedVersion);\n };\n\n #renderUninstallButton = (): JSX.Element => {\n return (\n <button class=\"button-tertiary\" onClick={this.#uninstallClickedHandler}>\n {this.#componentLocale.actions.uninstall}\n </button>\n );\n };\n\n #installClickedHandler = () => {\n this.installCallback();\n };\n\n #updateVersionHandler = (id: string) => () => {\n this.installCallback(id);\n };\n\n #openLinkHandler = (link: string) => (event: MouseEvent) => {\n if (this.openLinkCallback) {\n event.preventDefault();\n this.openLinkCallback(link);\n }\n };\n\n #uninstallClickedHandler = () => {\n this.uninstallCallback();\n };\n\n #renderActionButtons = (): JSX.Element => {\n let actionButtonCaption;\n let actionButtonClasses = \"button-primary action-button\";\n let actionButtonCallback;\n const moreVersionsToUpdate = this.data.versions?.length;\n\n if (!this.data.installed) {\n actionButtonCaption = this.#componentLocale.actions.install;\n actionButtonCallback = this.#installClickedHandler;\n } else if (this.data.updateVersion) {\n actionButtonCaption = `${this.#componentLocale.actions.updateTo} ${\n this.data.updateVersion\n }`;\n actionButtonCallback = this.#updateVersionHandler(\n this.data.updateVersion\n );\n } else {\n actionButtonCaption = this.#componentLocale.actions.installed;\n }\n\n if (moreVersionsToUpdate) {\n actionButtonClasses = `${actionButtonClasses} more-versions-available`;\n }\n\n return [\n <div class=\"version-buttons-container\">\n <button class={actionButtonClasses} onClick={actionButtonCallback}>\n {actionButtonCaption}\n </button>\n {moreVersionsToUpdate ? (\n <ch-action-menu-render\n class=\"dropdown button-primary button-icon-only\"\n blockAlign=\"outside-end\"\n inlineAlign=\"inside-start\"\n model={this.#versionsMenuOptionsModel()}\n onButtonClick={this.#menuVersionSelectedHandler}\n >\n <ch-image src={CHEVRON_DOWN_ICON} class=\"icon-m\"></ch-image>\n </ch-action-menu-render>\n ) : null}\n </div>\n ];\n };\n\n #tabSelectionChangedHandler = (\n event: CustomEvent<{\n lastSelectedIndex: number;\n newSelectedId: string;\n newSelectedIndex: number;\n }>\n ): void => {\n this.selectedTabId = event.detail.newSelectedId;\n };\n\n #renderDocSectionsSlots = (): JSX.Element => {\n return this.docsTabModel.map(docSectionTab => {\n if (docSectionTab.id === this.selectedTabId) {\n const markdownValue = this.#docSectionIdDescriptionMap.get(\n docSectionTab.id\n );\n\n return (\n <ch-markdown-viewer\n ref={(el: HTMLChMarkdownViewerElement) =>\n (this.#chMarkdownViewer = el as HTMLChMarkdownViewerElement)\n }\n slot={docSectionTab.id}\n key={docSectionTab.id}\n class=\"markdown spacing-body scrollable\"\n theme=\"components/markdown-viewer\"\n value={markdownValue}\n ></ch-markdown-viewer>\n );\n }\n });\n };\n\n #returnFormatedId = (rawId: string): string => {\n return rawId.toLowerCase().replace(/\\s+/g, \"-\");\n };\n\n #renderLinkTag = (\n href: string,\n label: string,\n cssClass?: string,\n chImageSrc?: string\n ): HTMLAnchorElement => {\n return (\n <a\n href={href}\n target=\"_blank\"\n onClick={this.#openLinkHandler(href)}\n class={cssClass}\n >\n {chImageSrc && <ch-image src={chImageSrc} class=\"icon-m\"></ch-image>}\n {label}\n </a>\n );\n };\n\n #renderAsideContent = (): JSX.Element => {\n return this.data.infoCategories.map(infoCategory => {\n return (\n <div class=\"plugin__info-category\">\n <h3 class=\"subtitle-semi-bold-s\">{infoCategory.name}</h3>\n <ul\n class={{\n \"fields__list\": true,\n \"fields__list--as-tags\": infoCategory.displayAsTags\n }}\n >\n {infoCategory.fields.map(field => {\n // If the field name isn’t specified, only the value is shown — usually a link.\n const fieldValue: string | HTMLAnchorElement =\n typeof field.value === \"string\"\n ? (field.value as string)\n : this.#renderLinkTag(\n (field.value as LinkData).url,\n (field.value as LinkData).text,\n \"field__link\"\n );\n return (\n <li class=\"field__li\">\n {field.name && !infoCategory.displayAsTags\n ? // displaysAsTags forces the items to be displayed as tags\n // no span.field__name and span.field__value\n [\n <span class=\"field__name body-semi-bold-s\">\n {field.name}\n </span>,\n <span class=\"field__value body-regular-s\">\n {fieldValue}\n </span>\n ]\n : fieldValue}\n </li>\n );\n })}\n </ul>\n </div>\n );\n });\n };\n\n render() {\n const renderActionButtons =\n !this.data.installed ||\n (this.data.installed && !!this.data.updateVersion);\n\n const titleLinkDataText = (this.data.name as LinkData).text;\n const titleLinkDataUrl = (this.data.name as LinkData).url;\n const titleHasLink = titleLinkDataText && titleLinkDataUrl;\n const titleText = titleLinkDataText || this.data.name;\n\n const publisherDataText = (this.data.publisher as LinkData).text;\n const publisherDataUrl = (this.data.publisher as LinkData).url;\n const publisherHasLink = publisherDataText && publisherDataUrl;\n const publisherText = publisherDataText || this.data.publisher;\n\n return (\n <Host class=\"widget\">\n <ch-theme model={CSS_BUNDLES}></ch-theme>\n <section class=\"section\">\n <header class=\"header\">\n <img\n class=\"plugin__icon\"\n src={this.data.iconUrl || EXTENSION_ICON_IMG}\n alt=\"plugin extension icon\"\n />\n <div class=\"plugin__details\">\n {titleHasLink ? (\n <h2 class=\"heading-5 has-link\">\n {this.#renderLinkTag(\n titleLinkDataUrl,\n titleText as string,\n \"text-underline\"\n )}\n </h2>\n ) : (\n <h2 class=\"heading-5\">{titleText}</h2>\n )}\n {publisherHasLink ? (\n this.#renderLinkTag(\n publisherDataUrl,\n titleText as string,\n \"text-underline plugin__publisher caption-semi-bold-l\",\n USER_ICON\n )\n ) : (\n <p class=\"plugin__publisher caption-semi-bold-l\">\n <ch-image src={USER_ICON} class=\"icon-s\"></ch-image>\n {publisherText}\n </p>\n )}\n\n <p class=\"plugin__description\">{this.data.description}</p>\n <div class=\"buttons-spacer plugin__actions-container\">\n {renderActionButtons ? (\n this.#renderActionButtons()\n ) : (\n // installed and no updates\n <p class=\"installed-container subtitle-semi-bold-s\">\n <ch-image src={CHECK_CIRCLE_ICON} class=\"icon-s\"></ch-image>\n {this.#componentLocale.actions.installed}\n </p>\n )}\n {this.data.installed && this.#renderUninstallButton()}\n </div>\n </div>\n </header>\n <div class=\"main\">\n {this.docsTabModel.length > 0 && (\n <ch-tab-render\n class=\"tab docsTab scrollable\"\n tabListPosition=\"block-start\"\n overflow=\"auto\"\n contain=\"size\"\n model={this.docsTabModel}\n onSelectedItemChange={this.#tabSelectionChangedHandler}\n selectedId={this.selectedTabId}\n >\n {this.#renderDocSectionsSlots()}\n </ch-tab-render>\n )}\n </div>\n <div class=\"aside spacing-body scrollable\">\n {this.#renderAsideContent()}\n </div>\n </section>\n {/* <slot></slot> */}\n </Host>\n );\n }\n}\n\n// plugin-details.types.ts\n\nexport type LinkData = {\n text: string;\n url: string;\n};\n\nexport type PluginFieldData = {\n name?: string;\n value: string | LinkData;\n};\n\nexport type PluginInfoCategoryData = {\n name: string;\n fields: PluginFieldData[];\n displayAsTags: boolean;\n};\n\nexport type DocSectionData = {\n name: string;\n content: string;\n};\n\nexport type PluginDetailsData = {\n id: string;\n name: string | LinkData;\n publisher: string | LinkData;\n installed: boolean;\n updateVersion?: string;\n versions: string[];\n iconUrl: string;\n description: string;\n docSections: DocSectionData[];\n infoCategories: PluginInfoCategoryData[];\n};\n"],"version":3}
1
+ {"file":"gx-ide-plugin-details.entry.js","mappings":"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","names":[],"sources":["src/components/plugin-details/plugin-details.scss?tag=gx-ide-plugin-details&encapsulation=shadow","src/components/plugin-details/plugin-details.tsx"],"sourcesContent":["@import \"../../global/temporary-mercury-overrides/_tab.scss\";\n\n:host {\n display: grid;\n block-size: 100%;\n grid-template-areas:\n \"header header\"\n \"main aside\";\n grid-template-rows: max-content 1fr;\n grid-template-columns: 1fr 280px;\n row-gap: var(--spacing-gap-l);\n}\n\n.section {\n display: contents;\n}\n\n// header\n.header {\n display: grid;\n grid-area: header;\n grid-template-areas: \"plugin-icon plugin-details\";\n grid-template-columns: 64px 1fr;\n column-gap: var(--spacing-gap-xl);\n padding-block-start: var(--spacing-padding-xxl);\n padding-block-end: var(--spacing-padding-xl);\n padding-inline: var(--spacing-padding-xxl);\n}\n.plugin__icon {\n grid-area: plugin-icon;\n inline-size: 100%;\n block-size: auto;\n display: block;\n}\n.plugin__details {\n grid-area: plugin-details;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-m);\n}\n.plugin__publisher {\n display: flex;\n align-items: center;\n gap: var(--spacing-gap-xs);\n}\n.plugin__description {\n line-height: var(--line-height-spacious); // WA: Text appears too tight.\n}\n.plugin__actions-container {\n margin-block-start: var(--spacing-padding-m);\n align-items: center;\n // Reserve the taller progress-bar height (control + gap + bar) so swapping\n // the install button for the progress bar doesn't shift the layout.\n min-block-size: calc(var(--control-block-size) + var(--spacing-gap-xs) + 4px);\n}\n.action-button {\n min-inline-size: 100px;\n\n &.more-versions-available {\n border-start-end-radius: 0 !important;\n border-end-end-radius: 0 !important;\n }\n}\n.installed-container {\n display: flex;\n align-items: center;\n gap: var(--spacing-gap-m);\n\n // WA Biggest Mercury icon (icon-s) looks small in this case.\n // Mercury should expose more icon sizes.\n ch-image {\n --ch-image-size: 20px;\n }\n}\n\n// main\n.main {\n grid-area: main;\n}\n.docsTab {\n block-size: 100%;\n}\n\n// aside\n.aside {\n grid-area: aside;\n overflow: auto;\n border-block-start: 1px solid var(--items-container__border-color);\n}\n.fields__list {\n list-style: none;\n padding: 0;\n margin: 0;\n font-size: var(--font-size-body-s);\n}\n.plugin__info-category {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-m);\n\n &:not(:first-child) {\n padding-block-start: var(--spacing-padding-xl);\n margin-block-start: var(--spacing-padding-xl);\n border-block-start: 1px solid var(--color-border-surface-on-elevation-1);\n }\n}\n.fields__list:not(.fields__list--as-tags) {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-gap-m);\n .field__li {\n display: flex;\n gap: var(--spacing-gap-xl);\n }\n}\n.fields__list--as-tags {\n display: flex;\n flex-wrap: wrap;\n gap: var(--spacing-gap-m);\n\n .field__li {\n border: 1px solid var(--color-border-surface-on-elevation-1);\n padding-block: var(--spacing-padding-xxs);\n padding-inline: var(--spacing-padding-m);\n border-radius: 4px;\n\n text-transform: lowercase;\n }\n .field__link {\n color: var(--color-text-neutral-strawberry);\n\n &:hover {\n color: var(--color-accent-primary-default);\n }\n &:active {\n color: var(--color-accent-primary-hover);\n }\n }\n}\n\n.field__name,\n.field__value {\n flex: 1;\n}\n// WA: Link styles should be defined Mercury\n.field__link {\n color: var(--color-accent-primary-default);\n &:hover {\n color: var(--color-accent-primary-hover);\n }\n &:active {\n color: var(--color-accent-primary-pressed);\n }\n}\n// WA: Remove tab elevation background color\n.docsTab {\n background-color: transparent !important;\n}\n\n// WA: Styles for \"button-icon-only\" should be defined on mercury\n.dropdown.button-icon-only::part(expandable-button) {\n padding: calc(\n (var(--control-block-size) - 2 * var(--control-border-width) - 16px) / 2\n ) !important;\n border-start-start-radius: 0 !important;\n border-end-start-radius: 0 !important;\n}\n\n.version-buttons-container {\n display: flex;\n align-items: stretch;\n gap: 1px;\n}\n\n.install-progress {\n flex: 1;\n min-inline-size: 220px;\n}\n\nch-markdown-viewer {\n block-size: 100%;\n overflow: auto;\n}\n\n// WA: Need text with underline. This should be defined on Mercury\n.text-underline {\n text-decoration: underline;\n}\n","import {\n Component,\n Host,\n State,\n Prop,\n Element,\n h,\n getAssetPath,\n JSX\n} from \"@stencil/core\";\n\nimport { getIconPath, MercuryBundles } from \"@genexus/mercury\";\nimport { Locale } from \"../../common/locale\";\nimport { ActionMenuModel, TabModel } from \"@genexus/chameleon-controls-library\";\nimport { TabItemModel } from \"@genexus/chameleon-controls-library/dist/types/components/tab/types\";\n\nconst USER_ICON = getIconPath({\n category: \"system\",\n name: \"user\",\n colorType: \"on-surface\"\n});\nconst CHEVRON_DOWN_ICON = getIconPath({\n category: \"system\",\n name: \"chevron-down\",\n colorType: \"on-primary\"\n});\nconst CHECK_CIRCLE_ICON = getIconPath({\n category: \"system\",\n name: \"check-circle\",\n colorType: \"success\"\n});\n\n// plugin icon if no iconUri 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 \"chameleon/scrollbar\",\n \"components/button\",\n \"components/dropdown\",\n \"components/edit\",\n \"components/icon\",\n \"components/list-box\",\n \"components/tab\",\n \"utils/form\",\n \"utils/layout\",\n \"utils/spacing\",\n \"utils/typography\"\n];\n\n@Component({\n tag: \"gx-ide-plugin-details\",\n styleUrl: \"plugin-details.scss\",\n shadow: true,\n assetsDirs: [\"gx-ide-assets/plugin-details\"]\n})\nexport class GxIdePluginDetails {\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\n #chMarkdownViewer: HTMLChMarkdownViewerElement;\n\n // A map between docSection \"id\", and docSection \"description\".\n // \"id\" is generated inside this component.\n #docSectionIdDescriptionMap: Map<string, string> = new Map();\n\n @Element() el: HTMLGxIdePluginDetailsElement;\n\n @State() docsTabModel: TabModel = [];\n @State() selectedTabId: string;\n\n /**\n * Specifies all the information related to a plugin.\n */\n @Prop() readonly data!: PluginDetailsData;\n\n /**\n * Callback that should be invoked when the user performs the install or update action.\n * Receives the ordinal versionId of the selected version (undefined installs the latest).\n */\n @Prop() readonly installCallback!: (versionId?: number) => Promise<void>;\n\n /**\n * When set, the component is installing this plugin and shows a determinate progress bar\n * instead of the action button.\n */\n @Prop() readonly installProgress?: PluginInstallProgress;\n\n /**\n * Callback that should be invoked when the user cancels an in-progress\n * install/update from the progress bar.\n */\n @Prop() readonly cancelCallback!: () => Promise<void>;\n\n /**\n * Callback that should be invoked when the user attempts to open any link displayed in this component.\n */\n @Prop() readonly openLinkCallback!: (url: string) => Promise<void>;\n\n /**\n * Callback that should be invoked when the user performs the uninstall action.\n */\n @Prop() readonly uninstallCallback!: () => Promise<void>;\n\n async componentWillLoad() {\n this.#componentLocale = await Locale.getComponentStrings(this.el);\n\n if (this.data.docSections?.length) {\n this.docsTabModel = this.data.docSections.map((docSection, i) => {\n const formatedId = this.#returnFormatedId(docSection.name);\n\n this.#docSectionIdDescriptionMap.set(formatedId, docSection.content);\n\n if (i === 0) {\n this.selectedTabId = formatedId;\n }\n return {\n id: formatedId,\n name: docSection.name\n } as TabItemModel;\n });\n }\n }\n\n componentDidLoad() {\n // Guard: #chMarkdownViewer is unset when there are no docSections.\n this.#chMarkdownViewer?.addEventListener(\"click\", event => {\n // Listens for clicks on links inside <ch-markdown-viewer>.\n // If a link (<a>) is clicked and openLinkCallback is defined,\n // it prevents the default navigation and delegates the event\n // to this.#openLinkHandler, passing the link's href.\n const path = event.composedPath() as EventTarget[];\n\n const link = path.find(el => el instanceof HTMLAnchorElement) as\n | HTMLAnchorElement\n | undefined;\n\n if (link?.href) {\n this.#openLinkHandler(link.href)(event);\n }\n });\n }\n\n #versionsMenuOptionsModel = (): ActionMenuModel => {\n const versionsToUpdateMenusModel: ActionMenuModel = this.data.versions?.map(\n version => {\n // The menu id carries the ordinal versionId; the caption shows the human-readable version.\n return { id: String(version.versionId), caption: version.version };\n }\n );\n return versionsToUpdateMenusModel;\n };\n\n #menuVersionSelectedHandler = (\n event: CustomEvent<{\n id?: string;\n }>\n ) => {\n const selectedVersionId = event.detail.id;\n this.installCallback(\n selectedVersionId != null ? Number(selectedVersionId) : undefined\n );\n };\n\n #renderUninstallButton = (): JSX.Element => {\n return (\n <button class=\"button-tertiary\" onClick={this.#uninstallClickedHandler}>\n {this.#componentLocale.actions.uninstall}\n </button>\n );\n };\n\n // The latest version is listed first; its ordinal drives install/update from the primary button.\n #latestVersionId = (): number | undefined =>\n this.data.versions?.[0]?.versionId;\n\n #installClickedHandler = () => {\n this.installCallback(this.#latestVersionId());\n };\n\n #openLinkHandler = (link: string) => (event: MouseEvent) => {\n if (this.openLinkCallback) {\n event.preventDefault();\n this.openLinkCallback(link);\n }\n };\n\n #uninstallClickedHandler = () => {\n this.uninstallCallback();\n };\n\n #cancelClickedHandler = () => {\n this.cancelCallback();\n };\n\n #renderInstallProgress = (): JSX.Element => {\n const { phase, percent } = this.installProgress;\n const caption =\n phase === \"download\"\n ? this.#componentLocale.actions.downloading\n : this.#componentLocale.actions.installing;\n\n return (\n <gx-ide-progress-bar\n class=\"install-progress plain\"\n active\n caption={`${caption} ${percent}%`}\n progress={percent}\n stateType=\"in-progress\"\n closeType=\"button\"\n closedCallback={this.#cancelClickedHandler}\n ></gx-ide-progress-bar>\n );\n };\n\n #renderActionButtons = (): JSX.Element => {\n // While an install/update is running, replace the buttons with a determinate progress bar.\n if (this.installProgress) {\n return this.#renderInstallProgress();\n }\n\n let actionButtonCaption;\n let actionButtonClasses = \"button-primary action-button\";\n let actionButtonCallback;\n const moreVersionsToUpdate = this.data.versions?.length > 1;\n\n if (!this.data.installed) {\n actionButtonCaption = this.#componentLocale.actions.install;\n actionButtonCallback = this.#installClickedHandler;\n } else if (this.data.updateVersion) {\n actionButtonCaption = `${this.#componentLocale.actions.updateTo} ${\n this.data.updateVersion\n }`;\n actionButtonCallback = () =>\n this.installCallback(this.#latestVersionId());\n } else {\n actionButtonCaption = this.#componentLocale.actions.installed;\n }\n\n if (moreVersionsToUpdate) {\n actionButtonClasses = `${actionButtonClasses} more-versions-available`;\n }\n\n return [\n <div class=\"version-buttons-container\">\n <button class={actionButtonClasses} onClick={actionButtonCallback}>\n {actionButtonCaption}\n </button>\n {moreVersionsToUpdate ? (\n <ch-action-menu-render\n class=\"dropdown button-primary button-icon-only\"\n blockAlign=\"outside-end\"\n inlineAlign=\"inside-start\"\n model={this.#versionsMenuOptionsModel()}\n onButtonClick={this.#menuVersionSelectedHandler}\n >\n <ch-image src={CHEVRON_DOWN_ICON} class=\"icon-m\"></ch-image>\n </ch-action-menu-render>\n ) : null}\n </div>\n ];\n };\n\n #tabSelectionChangedHandler = (\n event: CustomEvent<{\n lastSelectedIndex: number;\n newSelectedId: string;\n newSelectedIndex: number;\n }>\n ): void => {\n this.selectedTabId = event.detail.newSelectedId;\n };\n\n #renderDocSectionsSlots = (): JSX.Element => {\n return this.docsTabModel.map(docSectionTab => {\n if (docSectionTab.id === this.selectedTabId) {\n const markdownValue = this.#docSectionIdDescriptionMap.get(\n docSectionTab.id\n );\n\n return (\n <ch-markdown-viewer\n ref={(el: HTMLChMarkdownViewerElement) =>\n (this.#chMarkdownViewer = el as HTMLChMarkdownViewerElement)\n }\n slot={docSectionTab.id}\n key={docSectionTab.id}\n class=\"markdown spacing-body scrollable\"\n theme=\"components/markdown-viewer\"\n value={markdownValue}\n ></ch-markdown-viewer>\n );\n }\n });\n };\n\n #returnFormatedId = (rawId: string): string => {\n return rawId.toLowerCase().replace(/\\s+/g, \"-\");\n };\n\n #renderLinkTag = (\n href: string,\n label: string,\n cssClass?: string,\n chImageSrc?: string\n ): HTMLAnchorElement => {\n return (\n <a\n href={href}\n target=\"_blank\"\n onClick={this.#openLinkHandler(href)}\n class={cssClass}\n >\n {chImageSrc && <ch-image src={chImageSrc} class=\"icon-m\"></ch-image>}\n {label}\n </a>\n );\n };\n\n #renderAsideContent = (): JSX.Element => {\n return this.data.infoCategories.map(infoCategory => {\n return (\n <div class=\"plugin__info-category\">\n <h3 class=\"subtitle-semi-bold-s\">{infoCategory.name}</h3>\n <ul\n class={{\n \"fields__list\": true,\n \"fields__list--as-tags\": infoCategory.displayAsTags\n }}\n >\n {infoCategory.fields.map(field => {\n // If the field name isn’t specified, only the value is shown — usually a link.\n const fieldValue: string | HTMLAnchorElement =\n typeof field.value === \"string\"\n ? (field.value as string)\n : this.#renderLinkTag(\n (field.value as LinkData).url,\n (field.value as LinkData).text,\n \"field__link\"\n );\n return (\n <li class=\"field__li\">\n {field.name && !infoCategory.displayAsTags\n ? // displaysAsTags forces the items to be displayed as tags\n // no span.field__name and span.field__value\n [\n <span class=\"field__name body-semi-bold-s\">\n {field.name}\n </span>,\n <span class=\"field__value body-regular-s\">\n {fieldValue}\n </span>\n ]\n : fieldValue}\n </li>\n );\n })}\n </ul>\n </div>\n );\n });\n };\n\n render() {\n const renderActionButtons =\n !this.data.installed ||\n (this.data.installed && !!this.data.updateVersion);\n\n const titleLinkDataText = (this.data.name as LinkData).text;\n const titleLinkDataUrl = (this.data.name as LinkData).url;\n const titleHasLink = titleLinkDataText && titleLinkDataUrl;\n const titleText = titleLinkDataText || this.data.name;\n\n const publisherDataText = (this.data.publisher as LinkData).text;\n const publisherDataUrl = (this.data.publisher as LinkData).url;\n const publisherHasLink = publisherDataText && publisherDataUrl;\n const publisherText = publisherDataText || this.data.publisher;\n\n return (\n <Host class=\"widget\">\n <ch-theme model={CSS_BUNDLES}></ch-theme>\n <section class=\"section\">\n <header class=\"header\">\n <img\n class=\"plugin__icon\"\n src={this.data.iconUrl || EXTENSION_ICON_IMG}\n alt=\"plugin extension icon\"\n />\n <div class=\"plugin__details\">\n {titleHasLink ? (\n <h2 class=\"heading-5 has-link\">\n {this.#renderLinkTag(\n titleLinkDataUrl,\n titleText as string,\n \"text-underline\"\n )}\n </h2>\n ) : (\n <h2 class=\"heading-5\">{titleText}</h2>\n )}\n {publisherHasLink ? (\n this.#renderLinkTag(\n publisherDataUrl,\n titleText as string,\n \"text-underline plugin__publisher caption-semi-bold-l\",\n USER_ICON\n )\n ) : (\n <p class=\"plugin__publisher caption-semi-bold-l\">\n <ch-image src={USER_ICON} class=\"icon-s\"></ch-image>\n {publisherText}\n </p>\n )}\n\n <p class=\"plugin__description\">{this.data.description}</p>\n <div class=\"buttons-spacer plugin__actions-container\">\n {renderActionButtons ? (\n this.#renderActionButtons()\n ) : (\n // installed and no updates\n <p class=\"installed-container subtitle-semi-bold-s\">\n <ch-image src={CHECK_CIRCLE_ICON} class=\"icon-s\"></ch-image>\n {this.#componentLocale.actions.installed}\n </p>\n )}\n {this.data.installed && this.#renderUninstallButton()}\n </div>\n </div>\n </header>\n <div class=\"main\">\n {this.docsTabModel.length > 0 && (\n <ch-tab-render\n class=\"tab docsTab scrollable\"\n tabListPosition=\"block-start\"\n overflow=\"auto\"\n contain=\"size\"\n model={this.docsTabModel}\n onSelectedItemChange={this.#tabSelectionChangedHandler}\n selectedId={this.selectedTabId}\n >\n {this.#renderDocSectionsSlots()}\n </ch-tab-render>\n )}\n </div>\n <div class=\"aside spacing-body scrollable\">\n {this.#renderAsideContent()}\n </div>\n </section>\n {/* <slot></slot> */}\n </Host>\n );\n }\n}\n\n// plugin-details.types.ts\n\nexport type LinkData = {\n text: string;\n url: string;\n};\n\nexport type PluginFieldData = {\n name?: string;\n value: string | LinkData;\n};\n\nexport type PluginInfoCategoryData = {\n name: string;\n fields: PluginFieldData[];\n displayAsTags: boolean;\n};\n\nexport type DocSectionData = {\n name: string;\n content: string;\n};\n\nexport type PluginVersionOption = {\n version: string;\n versionId: number;\n};\n\nexport type PluginInstallProgress = {\n phase: \"download\" | \"install\";\n percent: number;\n};\n\nexport type PluginDetailsData = {\n id: string;\n name: string | LinkData;\n publisher: string | LinkData;\n installed: boolean;\n updateVersion?: string;\n versions: PluginVersionOption[];\n iconUrl: string;\n description: string;\n docSections: DocSectionData[];\n infoCategories: PluginInfoCategoryData[];\n};\n"],"version":3}
@@ -7,7 +7,7 @@ import 'lit/directives/if-defined.js';
7
7
  import { L as Locale } from './locale-e5107fad.js';
8
8
  import { c as config } from './config-5a775b7a.js';
9
9
 
10
- 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)}";
10
+ 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}";
11
11
 
12
12
  var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) {
13
13
  if (kind === "a" && !f)
@@ -25,14 +25,14 @@ var __classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) ||
25
25
  throw new TypeError("Cannot write private member to an object whose class did not declare it");
26
26
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
27
27
  };
28
- var _GxIdePluginManager_componentLocale, _GxIdePluginManager_animateEmptyState, _GxIdePluginManager_actionListButtonClickHandler, _GxIdePluginManager_mapPluginDataToActionListModel, _GxIdePluginManager_pluginsFilterInputHandler, _GxIdePluginManager_evaluateContentToDisplay, _GxIdePluginManager_renderLoader, _GxIdePluginManager_pluginSelectedHandler;
28
+ var _GxIdePluginManager_componentLocale, _GxIdePluginManager_animateEmptyState, _GxIdePluginManager_actionListButtonClickHandler, _GxIdePluginManager_downloadsFormatter, _GxIdePluginManager_formatDownloads, _GxIdePluginManager_mapPluginToItem, _GxIdePluginManager_mapPluginGroupsToActionListModel, _GxIdePluginManager_pluginsFilterInputHandler, _GxIdePluginManager_evaluateContentToDisplay, _GxIdePluginManager_renderLoader, _GxIdePluginManager_pluginSelectedHandler;
29
29
  const FILTER_ICON = getIconPath({
30
30
  category: "system",
31
31
  name: "filters",
32
32
  colorType: "on-surface"
33
33
  });
34
34
  // plugin icon if no iconUrl was provided
35
- const EXTENSION_ICON_IMG = getAssetPath(`./gx-ide-assets/plugin-manager/images/plugin-icon.svg`);
35
+ const EXTENSION_ICON_IMG = getAssetPath(`./gx-ide-assets/plugin-explorer/images/plugin-icon.svg`);
36
36
  const CSS_BUNDLES = [
37
37
  "resets/box-sizing",
38
38
  "components/list-box",
@@ -44,6 +44,21 @@ const CSS_BUNDLES = [
44
44
  "utils/spacing",
45
45
  "chameleon/scrollbar"
46
46
  ];
47
+ const SEARCH_ICON = getIconPath({
48
+ category: "system",
49
+ name: "search",
50
+ colorType: "on-surface"
51
+ });
52
+ const STAR_ICON = getIconPath({
53
+ category: "system",
54
+ name: "star-fill",
55
+ colorType: "warning"
56
+ });
57
+ const DOWNLOAD_ICON = getIconPath({
58
+ category: "system",
59
+ name: "download",
60
+ colorType: "on-surface"
61
+ });
47
62
  const GxIdePluginManager = class {
48
63
  constructor(hostRef) {
49
64
  registerInstance(this, hostRef);
@@ -57,51 +72,85 @@ const GxIdePluginManager = class {
57
72
  event.stopPropagation();
58
73
  this.executeActionCallback(pluginId, action);
59
74
  });
60
- _GxIdePluginManager_mapPluginDataToActionListModel.set(this, (pluginsData) => {
61
- const pluginsActionListModel = [];
62
- const separatorItem = { type: "separator" };
63
- pluginsData === null || pluginsData === void 0 ? void 0 : pluginsData.forEach((pluginData, index) => {
64
- const hasActionButton = !!pluginData.action;
65
- const pluginItem = {
66
- id: pluginData.id,
67
- caption: pluginData.name,
68
- imgSrc: pluginData.iconUrl,
69
- type: "actionable",
70
- additionalInformation: {
71
- "stretch-start": {
72
- center: [
73
- {
74
- part: "custom-image",
75
- 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" }))
76
- }
77
- ]
78
- },
79
- "block-end": {
80
- start: [
81
- {
82
- part: "custom-description custom-button custom-container custom-brand custom-brand-icon custom-image item__block-end start",
83
- jsx: () => (h("div", { part: "custom-container", title: pluginData.description }, h("p", { part: "custom-description" }, pluginData.description), h("small", { part: "custom-brand" }, pluginData.publisher)))
84
- }
85
- // {
86
- // slot: "abcd"
87
- // } as ActionListItemAdditionalSlot // slot not working
88
- ]
89
- },
90
- "stretch-end": hasActionButton && {
91
- center: [
92
- {
93
- jsx: () => (h("button", { part: "custom-button", onClick: __classPrivateFieldGet(this, _GxIdePluginManager_actionListButtonClickHandler, "f").call(this, pluginData.id, pluginData.action) }, pluginData.action))
94
- }
95
- ]
96
- }
75
+ // Formats a raw downloads count into a compact string (e.g. 4000 -> "4K").
76
+ _GxIdePluginManager_downloadsFormatter.set(this, new Intl.NumberFormat(undefined, {
77
+ notation: "compact",
78
+ maximumFractionDigits: 1
79
+ }));
80
+ _GxIdePluginManager_formatDownloads.set(this, (value) => {
81
+ const numericValue = typeof value === "number" ? value : Number(value);
82
+ return Number.isFinite(numericValue)
83
+ ? __classPrivateFieldGet(this, _GxIdePluginManager_downloadsFormatter, "f").format(numericValue)
84
+ : `${value}`;
85
+ });
86
+ _GxIdePluginManager_mapPluginToItem.set(this, (pluginData) => {
87
+ const hasActionButton = !!pluginData.action;
88
+ const hasDownloads = pluginData.downloads !== undefined && pluginData.downloads !== null;
89
+ const hasRating = pluginData.rating !== undefined && pluginData.rating !== null;
90
+ const hasMeta = hasDownloads || hasRating;
91
+ const pluginItem = {
92
+ id: pluginData.id,
93
+ caption: pluginData.name,
94
+ imgSrc: pluginData.iconUrl,
95
+ type: "actionable",
96
+ additionalInformation: {
97
+ "stretch-start": {
98
+ center: [
99
+ {
100
+ part: "custom-image",
101
+ 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" }))
102
+ }
103
+ ]
104
+ },
105
+ "inline-caption": hasMeta && {
106
+ end: [
107
+ {
108
+ part: "custom-meta",
109
+ 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))))
110
+ }
111
+ ]
112
+ },
113
+ "block-end": {
114
+ start: [
115
+ {
116
+ 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",
117
+ 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)))
118
+ }
119
+ // {
120
+ // slot: "abcd"
121
+ // } as ActionListItemAdditionalSlot // slot not working
122
+ ]
97
123
  }
98
- };
99
- if (index !== 0) {
100
- pluginsActionListModel.push(separatorItem);
101
124
  }
102
- pluginsActionListModel.push(pluginItem);
125
+ };
126
+ return pluginItem;
127
+ });
128
+ // Builds the ch-action-list model from groups: one native action-list group
129
+ // per PluginGroupData, plus a separator between groups. The group header only
130
+ // renders a plain-text caption (no custom pill element is supported), so the
131
+ // per-group total is shown as a number appended to the caption.
132
+ _GxIdePluginManager_mapPluginGroupsToActionListModel.set(this, (groups) => {
133
+ const model = [];
134
+ const separatorItem = { type: "separator" };
135
+ groups === null || groups === void 0 ? void 0 : groups.forEach(group => {
136
+ var _a, _b, _c;
137
+ // Skip empty groups so we don't render a header with "(0)".
138
+ if (!((_a = group.plugins) === null || _a === void 0 ? void 0 : _a.length)) {
139
+ return;
140
+ }
141
+ if (model.length > 0) {
142
+ model.push(separatorItem);
143
+ }
144
+ model.push({
145
+ id: group.id,
146
+ type: "group",
147
+ caption: `${group.caption} (${group.plugins.length})`,
148
+ expandable: (_b = group.expandable) !== null && _b !== void 0 ? _b : true,
149
+ expanded: (_c = group.expanded) !== null && _c !== void 0 ? _c : true,
150
+ items: group.plugins.map(plugin => __classPrivateFieldGet(this, _GxIdePluginManager_mapPluginToItem, "f").call(this, plugin))
151
+ });
103
152
  });
104
- return pluginsActionListModel;
153
+ return model;
105
154
  });
106
155
  _GxIdePluginManager_pluginsFilterInputHandler.set(this, async (event) => {
107
156
  this.loading = true;
@@ -133,7 +182,7 @@ const GxIdePluginManager = class {
133
182
  }
134
183
  pluginsChangedHandler(newPlugins) {
135
184
  this.pluginsActionListModel =
136
- __classPrivateFieldGet(this, _GxIdePluginManager_mapPluginDataToActionListModel, "f").call(this, newPlugins);
185
+ __classPrivateFieldGet(this, _GxIdePluginManager_mapPluginGroupsToActionListModel, "f").call(this, newPlugins);
137
186
  this.loading = false;
138
187
  }
139
188
  async componentWillLoad() {
@@ -141,7 +190,7 @@ const GxIdePluginManager = class {
141
190
  this.pluginsChangedHandler(this.plugins);
142
191
  }
143
192
  render() {
144
- 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
193
+ 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
145
194
  ? __classPrivateFieldGet(this, _GxIdePluginManager_renderLoader, "f").call(this)
146
195
  : __classPrivateFieldGet(this, _GxIdePluginManager_evaluateContentToDisplay, "f").call(this)))));
147
196
  }
@@ -151,7 +200,7 @@ const GxIdePluginManager = class {
151
200
  "plugins": ["pluginsChangedHandler"]
152
201
  }; }
153
202
  };
154
- _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();
203
+ _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();
155
204
  GxIdePluginManager.style = pluginExplorerCss;
156
205
 
157
206
  export { GxIdePluginManager as gx_ide_plugin_explorer };