@memberjunction/ng-dashboard-viewer 6.2.0-edge.2 → 6.2.0-edge.4
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.
- package/README.md +165 -17
- package/dist/lib/config-dialogs/confirm-dialog.component.d.ts +3 -4
- package/dist/lib/config-dialogs/confirm-dialog.component.d.ts.map +1 -1
- package/dist/lib/config-dialogs/confirm-dialog.component.js +3 -2
- package/dist/lib/config-dialogs/confirm-dialog.component.js.map +1 -1
- package/dist/lib/config-panels/artifact-config-panel.component.d.ts.map +1 -1
- package/dist/lib/config-panels/artifact-config-panel.component.js +59 -50
- package/dist/lib/config-panels/artifact-config-panel.component.js.map +1 -1
- package/dist/lib/config-panels/base-config-panel.d.ts +8 -3
- package/dist/lib/config-panels/base-config-panel.d.ts.map +1 -1
- package/dist/lib/config-panels/base-config-panel.js +10 -3
- package/dist/lib/config-panels/base-config-panel.js.map +1 -1
- package/dist/lib/config-panels/query-config-panel.component.js +124 -99
- package/dist/lib/config-panels/query-config-panel.component.js.map +1 -1
- package/dist/lib/config-panels/view-config-panel.component.js +111 -103
- package/dist/lib/config-panels/view-config-panel.component.js.map +1 -1
- package/dist/lib/config-panels/weburl-config-panel.component.js +89 -80
- package/dist/lib/config-panels/weburl-config-panel.component.js.map +1 -1
- package/dist/lib/dashboard-browser/dashboard-browser.component.d.ts +79 -28
- package/dist/lib/dashboard-browser/dashboard-browser.component.d.ts.map +1 -1
- package/dist/lib/dashboard-browser/dashboard-browser.component.js +446 -447
- package/dist/lib/dashboard-browser/dashboard-browser.component.js.map +1 -1
- package/dist/lib/dashboard-card/dashboard-card.component.d.ts +69 -0
- package/dist/lib/dashboard-card/dashboard-card.component.d.ts.map +1 -0
- package/dist/lib/dashboard-card/dashboard-card.component.js +281 -0
- package/dist/lib/dashboard-card/dashboard-card.component.js.map +1 -0
- package/dist/lib/dashboard-card/dashboard-card.helpers.d.ts +18 -0
- package/dist/lib/dashboard-card/dashboard-card.helpers.d.ts.map +1 -0
- package/dist/lib/dashboard-card/dashboard-card.helpers.js +43 -0
- package/dist/lib/dashboard-card/dashboard-card.helpers.js.map +1 -0
- package/dist/lib/dashboard-card/layout-preview-cache.d.ts +15 -0
- package/dist/lib/dashboard-card/layout-preview-cache.d.ts.map +1 -0
- package/dist/lib/dashboard-card/layout-preview-cache.js +22 -0
- package/dist/lib/dashboard-card/layout-preview-cache.js.map +1 -0
- package/dist/lib/dashboard-viewer/dashboard-viewer.component.d.ts +69 -12
- package/dist/lib/dashboard-viewer/dashboard-viewer.component.d.ts.map +1 -1
- package/dist/lib/dashboard-viewer/dashboard-viewer.component.js +173 -145
- package/dist/lib/dashboard-viewer/dashboard-viewer.component.js.map +1 -1
- package/dist/lib/dashboard-viewer.module.d.ts +24 -20
- package/dist/lib/dashboard-viewer.module.d.ts.map +1 -1
- package/dist/lib/dashboard-viewer.module.js +42 -5
- package/dist/lib/dashboard-viewer.module.js.map +1 -1
- package/dist/lib/dialogs/add-panel-dialog/add-panel-dialog.component.d.ts +7 -12
- package/dist/lib/dialogs/add-panel-dialog/add-panel-dialog.component.d.ts.map +1 -1
- package/dist/lib/dialogs/add-panel-dialog/add-panel-dialog.component.js +3 -1
- package/dist/lib/dialogs/add-panel-dialog/add-panel-dialog.component.js.map +1 -1
- package/dist/lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component.d.ts +54 -0
- package/dist/lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component.d.ts.map +1 -0
- package/dist/lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component.js +156 -0
- package/dist/lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component.js.map +1 -0
- package/dist/lib/dialogs/edit-part-dialog/edit-part-dialog.component.d.ts +5 -11
- package/dist/lib/dialogs/edit-part-dialog/edit-part-dialog.component.d.ts.map +1 -1
- package/dist/lib/dialogs/edit-part-dialog/edit-part-dialog.component.js +3 -1
- package/dist/lib/dialogs/edit-part-dialog/edit-part-dialog.component.js.map +1 -1
- package/dist/lib/dialogs/part-dialog/dashboard-part-dialog.component.d.ts +147 -0
- package/dist/lib/dialogs/part-dialog/dashboard-part-dialog.component.d.ts.map +1 -0
- package/dist/lib/dialogs/part-dialog/dashboard-part-dialog.component.js +536 -0
- package/dist/lib/dialogs/part-dialog/dashboard-part-dialog.component.js.map +1 -0
- package/dist/lib/layout-preview/dashboard-layout-preview-node.component.d.ts +20 -0
- package/dist/lib/layout-preview/dashboard-layout-preview-node.component.d.ts.map +1 -0
- package/dist/lib/layout-preview/dashboard-layout-preview-node.component.js +80 -0
- package/dist/lib/layout-preview/dashboard-layout-preview-node.component.js.map +1 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.component.d.ts +28 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.component.d.ts.map +1 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.component.js +62 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.component.js.map +1 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.d.ts +33 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.d.ts.map +1 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.js +138 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.js.map +1 -0
- package/dist/lib/models/dashboard-layout-editor.d.ts +78 -0
- package/dist/lib/models/dashboard-layout-editor.d.ts.map +1 -0
- package/dist/lib/models/dashboard-layout-editor.js +374 -0
- package/dist/lib/models/dashboard-layout-editor.js.map +1 -0
- package/dist/lib/models/remove-part-confirm.d.ts +8 -0
- package/dist/lib/models/remove-part-confirm.d.ts.map +1 -0
- package/dist/lib/models/remove-part-confirm.js +23 -0
- package/dist/lib/models/remove-part-confirm.js.map +1 -0
- package/dist/lib/parts/artifact-part.component.js +2 -2
- package/dist/lib/parts/artifact-part.component.js.map +1 -1
- package/dist/lib/parts/query-part.component.js +2 -2
- package/dist/lib/parts/query-part.component.js.map +1 -1
- package/dist/lib/parts/view-part.component.js +2 -2
- package/dist/lib/parts/view-part.component.js.map +1 -1
- package/dist/lib/parts/weburl-part.component.js +2 -2
- package/dist/lib/parts/weburl-part.component.js.map +1 -1
- package/dist/lib/services/golden-layout-wrapper.service.d.ts +40 -0
- package/dist/lib/services/golden-layout-wrapper.service.d.ts.map +1 -1
- package/dist/lib/services/golden-layout-wrapper.service.js +117 -9
- package/dist/lib/services/golden-layout-wrapper.service.js.map +1 -1
- package/dist/lib/services/stack-part-actions.d.ts +11 -0
- package/dist/lib/services/stack-part-actions.d.ts.map +1 -0
- package/dist/lib/services/stack-part-actions.js +41 -0
- package/dist/lib/services/stack-part-actions.js.map +1 -0
- package/dist/public-api.d.ts +9 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +13 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +13 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-part.component.js","sourceRoot":"","sources":["../../../src/lib/parts/artifact-part.component.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAA+C,KAAK,EAAE,MAAM,eAAe,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAI1D,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;;;;;;IAcnB,8BAA2B;IACzB,gCAAoD;IACtD,iBAAM;;;IAKN,oCAMmB;;;IADjB,6CAAwB;;;IAM1B,oCAKmB;;;;IAKnB,mDAkBkD;IAAhD,AADA,AADA,AADA,mOAAkB,+BAAwB,KAAC,0NACvB,iCAA0B,KAAC,4NAC1B,kCAA2B,KAAC,0NAC7B,iCAA0B,KAAC;IACjD,iBAA2B;;;IALzB,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,AADA,8CAAyB,mCACE,uCACI,uCACA,+BACD,iCACL,6BACJ,2CACc,iDACM,qBACrB,mBACF,kBACD,sBACI,yCACY;;AAtD/C;;;GAGG;AAgGI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,iBAAiB;IAoGZ;IAnG5C;;;OAGG;IACM,WAAW,GAAoB,IAAI,CAAC;IAE7C;;;OAGG;IACM,aAAa,GAAW,EAAE,CAAC;IAE7B,WAAW,GAAG,KAAK,CAAC;IAE3B,2CAA2C;IAC3C,IAAW,WAAW;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IACD,2CAA2C;IAC3C,IAAW,WAAW,CAAC,KAAK;QAC1B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IACM,UAAU,GAAkB,IAAI,CAAC;IACjC,aAAa,CAAqB;IAEzC,6CAA6C;IAC7C,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IACD,6CAA6C;IAC7C,IAAW,aAAa,CAAC,KAAyB;QAChD,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;IAC7B,CAAC;IACM,UAAU,GAAY,KAAK,CAAC;IAEnC,0CAA0C;IAC1C,IAAW,UAAU;QACnB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IACD,0CAA0C;IAC1C,IAAW,UAAU,CAAC,KAAc;QAClC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAC1B,CAAC,CAAC,2CAA2C;IACtC,QAAQ,GAAY,IAAI,CAAC;IAEhC,wCAAwC;IACxC,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IACD,wCAAwC;IACxC,IAAW,QAAQ,CAAC,KAAc;QAChC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IACxB,CAAC;IACM,eAAe,GAAY,KAAK,CAAC;IAExC,+CAA+C;IAC/C,IAAW,eAAe;QACxB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IACD,+CAA+C;IAC/C,IAAW,eAAe,CAAC,KAAc;QACvC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;IAC/B,CAAC,CAAC,iEAAiE;IAC5D,kBAAkB,GAAY,KAAK,CAAC;IAE3C,kDAAkD;IAClD,IAAW,kBAAkB;QAC3B,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IACD,kDAAkD;IAClD,IAAW,kBAAkB,CAAC,KAAc;QAC1C,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;IAClC,CAAC,CAAC,oEAAoE;IAC/D,cAAc,GAAG,IAAI,OAAO,EAAiD,CAAC;IAErF,8CAA8C;IAC9C,IAAW,cAAc;QACvB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IACD,8CAA8C;IAC9C,IAAW,cAAc,CAAC,KAAK;QAC7B,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;IAC9B,CAAC;IAED,sBAAsB;IACtB,IAAW,WAAW;QAClB,iEAAiE;QACjE,kFAAkF;QAClF,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC;QAChE,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;QAC5F,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,IAAW,aAAa;QACpB,OAAO,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC;IACpC,CAAC;IAED,YAAY,GAAsB,EAAU,cAAsC;QAC9E,sEAAsE;QACtE,oEAAoE;QACpE,wEAAwE;QACxE,uEAAuE;QACvE,uEAAuE;QACvE,iEAAiE;QACjE,KAAK,CAAC,GAAG,CAAC,CAAC;QAP6B,mBAAc,GAAd,cAAc,CAAwB;IAQlF,CAAC;IAED,eAAe;QACX,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,WAAW,EAAE,CAAC;QACvB,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,WAAW;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAe,CAAC;QAC7C,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,YAAY,CAAuB,CAAC;QAEhE,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YACzB,OAAO;QACX,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAEtB,IAAI,CAAC;YACD,0CAA0C;YAC1C,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;YAC7B,IAAI,CAAC,aAAa,GAAG,MAAM,EAAE,CAAC,eAAe,CAAuB,CAAC;YACrE,+EAA+E;YAC/E,IAAI,CAAC,UAAU,GAAI,MAAM,EAAE,CAAC,YAAY,CAAa,IAAI,KAAK,CAAC;YAC/D,IAAI,CAAC,QAAQ,GAAI,MAAM,EAAE,CAAC,UAAU,CAAa,IAAI,IAAI,CAAC;YAC1D,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YAExB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,QAAQ,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC;QACtF,CAAC;IACL,CAAC;IAED;;OAEG;IACI,OAAO;QACV,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACxC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;gBACrB,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,aAAa,EAAE,IAAI,CAAC,aAAa;aACpC,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,uCAAuC;IAChC,OAAO;QACZ,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;IAED;;OAEG;IACI,gBAAgB,CAAC,KAA2H;QAC/I,6DAA6D;QAC7D,IAAI,CAAC,eAAe,CAAC;YACjB,IAAI,EAAE,kBAAkB;YACxB,QAAQ,EAAE,KAAK,CAAC,IAAI;YACpB,MAAM,EAAE,KAAK,CAAC,EAAE;YAChB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,SAAS,EAAE,KAAK,CAAC,SAAS;SAC7B,CAAC,CAAC;QAEH,+EAA+E;QAC/E,mFAAmF;IACvF,CAAC;IAED,gDAAgD;IACzC,gBAAgB,CAAC,KAA2H;QACjJ,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACI,kBAAkB,CAAC,KAAyD;QAC/E,uCAAuC;QACvC,IAAI,CAAC,eAAe,CAAC;YACjB,IAAI,EAAE,oBAAoB;YAC1B,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,YAAY,EAAE,KAAK,CAAC,YAAY;SACnC,CAAC,CAAC;QAEH,+DAA+D;QAC/D,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACzC,IAAI,CAAC,uBAAuB,CACxB,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,EACjC,MAAM,EACN,KAAK,CACR,CAAC;QACN,CAAC;IACL,CAAC;IAED,kDAAkD;IAC3C,kBAAkB,CAAC,KAAyD;QACjF,OAAO,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAED;;OAEG;IACI,mBAAmB,CAAC,KAAwB;QAC/C,IAAI,CAAC,kBAAkB,CACnB,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,WAAW,EACjB,KAAK,CACR,CAAC;IACN,CAAC;IAED,mDAAmD;IAC5C,mBAAmB,CAAC,KAAwB;QACjD,OAAO,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,kBAAkB,CAAC,KAAqD;QACjF,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,yBAAyB,CAAC;gBAC/D,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,aAAa,EAAE,IAAI,CAAC,aAAa;aACpC,CAAC,CAAC;YAEH,IAAI,CAAC,kBAAkB,CACnB,eAAe,EACf,SAAS,EACT,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,EACzC,KAAK,CACR,CAAC;QACN,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,QAAQ,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC;QACpG,CAAC;IACL,CAAC;IAED,kDAAkD;IAC3C,KAAK,CAAC,kBAAkB,CAAC,KAAqD;QACnF,OAAO,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAEkB,OAAO;QACtB,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;IACnC,CAAC;+GArQQ,qBAAqB;6DAArB,qBAAqB;YA1F1B,8BAAoF;YAElF,uFAAiB;YAOjB,kGAAkC;YAWlC,kGAAmD;YAUnD,6GAAgE;YAsBlE,iBAAM;;YApDiD,AAA5B,wCAA2B,2BAA6B;YAEjF,cAIC;YAJD,wCAIC;YAGD,cAQC;YARD,6DAQC;YAGD,cAOC;YAPD,kFAOC;YAGD,cAqBC;YArBD,mGAqBC;;;AAuCE,qBAAqB;IA/FjC,aAAa,CAAC,iBAAiB,EAAE,uBAAuB,CAAC;GA+F7C,qBAAqB,CAsQjC;;iFAtQY,qBAAqB;cA9FjC,SAAS;6BACI,KAAK,YACL,kBAAkB,YAClB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAsDL;;kBA0CJ,KAAK;;kBAML,KAAK;;kFAXG,qBAAqB","sourcesContent":["import { Component, ChangeDetectorRef, AfterViewInit, OnDestroy, Input } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseDashboardPart } from './base-dashboard-part';\nimport { PanelConfig } from '../models/dashboard-types';\nimport { AnalyzeArtifactService, NavigationRequest } from '@memberjunction/ng-artifacts';\nimport { DataSnapshot, UserInfo, CompositeKey } from '@memberjunction/core';\nimport { Subject } from 'rxjs';\n\n/**\n * Runtime renderer for Artifact dashboard parts.\n * Displays artifacts using mj-artifact-viewer-panel including reports, charts, and AI-generated content.\n */\n@RegisterClass(BaseDashboardPart, 'ArtifactPanelRenderer')\n@Component({\n standalone: false,\n selector: 'mj-artifact-part',\n template: `\n <div class=\"artifact-part\" [class.loading]=\"IsLoading\" [class.error]=\"ErrorMessage\">\n <!-- Loading state -->\n @if (IsLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading artifact...\"></mj-loading>\n </div>\n }\n \n <!-- Error state -->\n @if (ErrorMessage && !IsLoading) {\n <mj-empty-state\n class=\"part-placeholder\"\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load artifact\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\" />\n }\n\n <!-- No artifact configured -->\n @if (!IsLoading && !ErrorMessage && !hasArtifact) {\n <mj-empty-state\n class=\"part-placeholder\"\n Icon=\"fa-solid fa-palette\"\n Title=\"No Artifact Selected\"\n Message=\"Click the configure button to select an artifact for this part.\"\n Size=\"compact\" />\n }\n \n <!-- Artifact Viewer Panel -->\n @if (!IsLoading && !ErrorMessage && hasArtifact && artifactId) {\n <mj-artifact-viewer-panel\n [artifactId]=\"artifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"versionNumber\"\n [showSaveToCollection]=\"false\"\n [showHeader]=\"showHeader\"\n [showTabs]=\"showTabs\"\n [showCloseButton]=\"showCloseButton\"\n [showMaximizeButton]=\"showMaximizeButton\"\n [viewContext]=\"null\"\n [canShare]=\"false\"\n [canEdit]=\"false\"\n [isMaximized]=\"false\"\n [refreshTrigger]=\"refreshTrigger\"\n (navigateToLink)=\"onNavigateToLink($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (navigationRequest)=\"onNavigationRequest($event)\"\n (analyzeRequested)=\"onAnalyzeRequested($event)\">\n </mj-artifact-viewer-panel>\n }\n </div>\n `,\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .artifact-part {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n }\n\n .loading-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--mj-text-secondary);\n text-align: center;\n padding: 24px;\n }\n\n .part-placeholder {\n height: 100%;\n }\n\n mj-artifact-viewer-panel {\n flex: 1;\n min-height: 0;\n }\n `]\n})\nexport class ArtifactPartComponent extends BaseDashboardPart implements AfterViewInit, OnDestroy {\n /**\n * Current user - required by the artifact viewer panel.\n * Should be provided by the dashboard host or retrieved from a service.\n */\n @Input() CurrentUser: UserInfo | null = null;\n\n /**\n * Environment ID - required by the artifact viewer panel.\n * Should be provided by the dashboard host.\n */\n @Input() EnvironmentId: string = '';\n\n public HasArtifact = false;\n\n /** @deprecated Use {@link HasArtifact}. */\n public get hasArtifact() {\n return this.HasArtifact;\n }\n /** @deprecated Use {@link HasArtifact}. */\n public set hasArtifact(value) {\n this.HasArtifact = value;\n }\n public artifactId: string | null = null;\n public VersionNumber: number | undefined;\n\n /** @deprecated Use {@link VersionNumber}. */\n public get versionNumber(): number | undefined {\n return this.VersionNumber;\n }\n /** @deprecated Use {@link VersionNumber}. */\n public set versionNumber(value: number | undefined) {\n this.VersionNumber = value;\n }\n public ShowHeader: boolean = false;\n\n /** @deprecated Use {@link ShowHeader}. */\n public get showHeader(): boolean {\n return this.ShowHeader;\n }\n /** @deprecated Use {@link ShowHeader}. */\n public set showHeader(value: boolean) {\n this.ShowHeader = value;\n } // Default to false for dashboard embedding\n public ShowTabs: boolean = true;\n\n /** @deprecated Use {@link ShowTabs}. */\n public get showTabs(): boolean {\n return this.ShowTabs;\n }\n /** @deprecated Use {@link ShowTabs}. */\n public set showTabs(value: boolean) {\n this.ShowTabs = value;\n }\n public ShowCloseButton: boolean = false;\n\n /** @deprecated Use {@link ShowCloseButton}. */\n public get showCloseButton(): boolean {\n return this.ShowCloseButton;\n }\n /** @deprecated Use {@link ShowCloseButton}. */\n public set showCloseButton(value: boolean) {\n this.ShowCloseButton = value;\n } // Always false in dashboard context - close handled by dashboard\n public ShowMaximizeButton: boolean = false;\n\n /** @deprecated Use {@link ShowMaximizeButton}. */\n public get showMaximizeButton(): boolean {\n return this.ShowMaximizeButton;\n }\n /** @deprecated Use {@link ShowMaximizeButton}. */\n public set showMaximizeButton(value: boolean) {\n this.ShowMaximizeButton = value;\n } // Always false in dashboard context - maximize handled by dashboard\n public RefreshTrigger = new Subject<{ artifactId: string; versionNumber: number }>();\n\n /** @deprecated Use {@link RefreshTrigger}. */\n public get refreshTrigger() {\n return this.RefreshTrigger;\n }\n /** @deprecated Use {@link RefreshTrigger}. */\n public set refreshTrigger(value) {\n this.RefreshTrigger = value;\n }\n\n // Expose for template\n public get currentUser(): UserInfo { // case-violation-ok-legacy-back-compat: the PascalCase name is already taken in this scope\n // Use provided CurrentUser, or fall back to Metadata.CurrentUser\n // In client-side Angular context, Metadata.CurrentUser should always be available\n const user = this.CurrentUser || this.ProviderToUse.CurrentUser;\n if (!user) {\n throw new Error('No current user available - user must be logged in to view artifacts');\n }\n return user;\n }\n\n public get environmentId(): string { // case-violation-ok-legacy-back-compat: the PascalCase name is already taken in this scope\n return this.EnvironmentId || '';\n }\n\n constructor(cdr: ChangeDetectorRef, private analyzeService: AnalyzeArtifactService) {\n // Note: this component is instantiated twice — once via bare `new` by\n // ClassFactory.CreateInstanceAsync (just to extract the constructor\n // reference), then properly via createComponent() with a full injector.\n // Constructor parameters are undefined on the bare path but Angular DI\n // populates them on the real path. Field initializers calling inject()\n // would throw on the bare path, so we use constructor injection.\n super(cdr);\n }\n\n ngAfterViewInit(): void {\n if (this.Panel) {\n this.loadContent();\n }\n }\n\n public async loadContent(): Promise<void> {\n const config = this.getConfig<PanelConfig>();\n const artifactId = config?.['artifactId'] as string | undefined;\n\n if (!artifactId) {\n this.HasArtifact = false;\n this.cdr.detectChanges();\n return;\n }\n\n this.setLoading(true);\n\n try {\n // Set artifact ID and version from config\n this.artifactId = artifactId;\n this.VersionNumber = config?.['versionNumber'] as number | undefined;\n // Display options - showHeader defaults to false for clean dashboard embedding\n this.ShowHeader = (config?.['showHeader'] as boolean) ?? false;\n this.ShowTabs = (config?.['showTabs'] as boolean) ?? true;\n this.HasArtifact = true;\n\n this.setLoading(false);\n } catch (error) {\n this.setError(error instanceof Error ? error.message : 'Failed to load artifact');\n }\n }\n\n /**\n * Refresh the artifact display\n */\n public Refresh(): void {\n if (this.artifactId && this.VersionNumber) {\n this.RefreshTrigger.next({\n artifactId: this.artifactId,\n versionNumber: this.VersionNumber\n });\n }\n }\n\n /** @deprecated Use {@link Refresh}. */\n public refresh(): void {\n return this.Refresh();\n }\n\n /**\n * Handle navigation link events from artifact viewer (conversation/collection links)\n */\n public OnNavigateToLink(event: { type: 'conversation' | 'collection'; id: string; artifactId?: string; versionNumber?: number; versionId?: string }): void {\n // Emit data change event for navigation link (for listeners)\n this.emitDataChanged({\n type: 'navigate-to-link',\n linkType: event.type,\n linkId: event.id,\n artifactId: event.artifactId,\n versionNumber: event.versionNumber,\n versionId: event.versionId\n });\n\n // TODO: Add navigation request methods for conversation/collection when needed\n // For now, these are emitted as data change events for parent components to handle\n }\n\n /** @deprecated Use {@link OnNavigateToLink}. */\n public onNavigateToLink(event: { type: 'conversation' | 'collection'; id: string; artifactId?: string; versionNumber?: number; versionId?: string }): void {\n return this.OnNavigateToLink(event);\n }\n\n /**\n * Handle entity record navigation events from artifact viewer\n */\n public OnOpenEntityRecord(event: { entityName: string; compositeKey: CompositeKey }): void {\n // Emit data change event for listeners\n this.emitDataChanged({\n type: 'open-entity-record',\n entityName: event.entityName,\n compositeKey: event.compositeKey\n });\n\n // Use proper navigation request to bubble up through the stack\n if (event.entityName && event.compositeKey) {\n this.RequestOpenEntityRecord(\n event.entityName,\n event.compositeKey.ToURLSegment(),\n 'view',\n false\n );\n }\n }\n\n /** @deprecated Use {@link OnOpenEntityRecord}. */\n public onOpenEntityRecord(event: { entityName: string; compositeKey: CompositeKey }): void {\n return this.OnOpenEntityRecord(event);\n }\n\n /**\n * Handle general navigation request events from artifact viewer plugins\n */\n public OnNavigationRequest(event: NavigationRequest): void {\n this.RequestOpenNavItem(\n event.navItemName,\n event.appName,\n event.queryParams,\n false\n );\n }\n\n /** @deprecated Use {@link OnNavigationRequest}. */\n public onNavigationRequest(event: NavigationRequest): void {\n return this.OnNavigationRequest(event);\n }\n\n /**\n * Handler for the Analyze button on the embedded artifact viewer.\n * Captures the live DataSnapshot, creates an analysis conversation with\n * the snapshot attached as input, and emits a navigation request to open\n * the new conversation in the host application.\n */\n public async OnAnalyzeRequested(event: { artifactId: string; snapshot: DataSnapshot }): Promise<void> {\n try {\n const result = await this.analyzeService.StartAnalysisConversation({\n snapshot: event.snapshot,\n currentUser: this.currentUser,\n environmentId: this.environmentId,\n });\n\n this.RequestOpenNavItem(\n 'Conversations',\n undefined,\n { conversationId: result.conversationId },\n false,\n );\n } catch (error) {\n this.setError(error instanceof Error ? error.message : 'Failed to start analysis conversation');\n }\n }\n\n /** @deprecated Use {@link OnAnalyzeRequested}. */\n public async onAnalyzeRequested(event: { artifactId: string; snapshot: DataSnapshot }): Promise<void> {\n return this.OnAnalyzeRequested(event);\n }\n\n protected override cleanup(): void {\n this.RefreshTrigger.complete();\n this.artifactId = null;\n this.VersionNumber = undefined;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"artifact-part.component.js","sourceRoot":"","sources":["../../../src/lib/parts/artifact-part.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectorRef, AfterViewInit, OnDestroy, Input } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseDashboardPart } from './base-dashboard-part';\nimport { PanelConfig } from '../models/dashboard-types';\nimport { AnalyzeArtifactService, NavigationRequest } from '@memberjunction/ng-artifacts';\nimport { DataSnapshot, UserInfo, CompositeKey } from '@memberjunction/core';\nimport { Subject } from 'rxjs';\n\n/**\n * Runtime renderer for Artifact dashboard parts.\n * Displays artifacts using mj-artifact-viewer-panel including reports, charts, and AI-generated content.\n */\n@RegisterClass(BaseDashboardPart, 'ArtifactPanelRenderer')\n@Component({\n standalone: false,\n selector: 'mj-artifact-part',\n template: `\n <div class=\"artifact-part\" [class.loading]=\"IsLoading\" [class.error]=\"ErrorMessage\">\n <!-- Loading state -->\n @if (IsLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading artifact...\"></mj-loading>\n </div>\n }\n \n <!-- Error state -->\n @if (ErrorMessage && !IsLoading) {\n <mj-empty-state\n class=\"part-placeholder\"\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load artifact\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\" />\n }\n\n <!-- No artifact configured -->\n @if (!IsLoading && !ErrorMessage && !hasArtifact) {\n <mj-empty-state\n class=\"part-placeholder\"\n Icon=\"fa-solid fa-palette\"\n Title=\"No Artifact Selected\"\n Message=\"Use Edit part to choose an artifact.\"\n Size=\"compact\" />\n }\n \n <!-- Artifact Viewer Panel -->\n @if (!IsLoading && !ErrorMessage && hasArtifact && artifactId) {\n <mj-artifact-viewer-panel\n [artifactId]=\"artifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"versionNumber\"\n [showSaveToCollection]=\"false\"\n [showHeader]=\"showHeader\"\n [showTabs]=\"showTabs\"\n [showCloseButton]=\"showCloseButton\"\n [showMaximizeButton]=\"showMaximizeButton\"\n [viewContext]=\"null\"\n [canShare]=\"false\"\n [canEdit]=\"false\"\n [isMaximized]=\"false\"\n [refreshTrigger]=\"refreshTrigger\"\n (navigateToLink)=\"onNavigateToLink($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (navigationRequest)=\"onNavigationRequest($event)\"\n (analyzeRequested)=\"onAnalyzeRequested($event)\">\n </mj-artifact-viewer-panel>\n }\n </div>\n `,\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .artifact-part {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n }\n\n .loading-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--mj-text-secondary);\n text-align: center;\n padding: 24px;\n }\n\n .part-placeholder {\n height: 100%;\n }\n\n mj-artifact-viewer-panel {\n flex: 1;\n min-height: 0;\n }\n `]\n})\nexport class ArtifactPartComponent extends BaseDashboardPart implements AfterViewInit, OnDestroy {\n /**\n * Current user - required by the artifact viewer panel.\n * Should be provided by the dashboard host or retrieved from a service.\n */\n @Input() CurrentUser: UserInfo | null = null;\n\n /**\n * Environment ID - required by the artifact viewer panel.\n * Should be provided by the dashboard host.\n */\n @Input() EnvironmentId: string = '';\n\n public HasArtifact = false;\n\n /** @deprecated Use {@link HasArtifact}. */\n public get hasArtifact() {\n return this.HasArtifact;\n }\n /** @deprecated Use {@link HasArtifact}. */\n public set hasArtifact(value) {\n this.HasArtifact = value;\n }\n public artifactId: string | null = null;\n public VersionNumber: number | undefined;\n\n /** @deprecated Use {@link VersionNumber}. */\n public get versionNumber(): number | undefined {\n return this.VersionNumber;\n }\n /** @deprecated Use {@link VersionNumber}. */\n public set versionNumber(value: number | undefined) {\n this.VersionNumber = value;\n }\n public ShowHeader: boolean = false;\n\n /** @deprecated Use {@link ShowHeader}. */\n public get showHeader(): boolean {\n return this.ShowHeader;\n }\n /** @deprecated Use {@link ShowHeader}. */\n public set showHeader(value: boolean) {\n this.ShowHeader = value;\n } // Default to false for dashboard embedding\n public ShowTabs: boolean = true;\n\n /** @deprecated Use {@link ShowTabs}. */\n public get showTabs(): boolean {\n return this.ShowTabs;\n }\n /** @deprecated Use {@link ShowTabs}. */\n public set showTabs(value: boolean) {\n this.ShowTabs = value;\n }\n public ShowCloseButton: boolean = false;\n\n /** @deprecated Use {@link ShowCloseButton}. */\n public get showCloseButton(): boolean {\n return this.ShowCloseButton;\n }\n /** @deprecated Use {@link ShowCloseButton}. */\n public set showCloseButton(value: boolean) {\n this.ShowCloseButton = value;\n } // Always false in dashboard context - close handled by dashboard\n public ShowMaximizeButton: boolean = false;\n\n /** @deprecated Use {@link ShowMaximizeButton}. */\n public get showMaximizeButton(): boolean {\n return this.ShowMaximizeButton;\n }\n /** @deprecated Use {@link ShowMaximizeButton}. */\n public set showMaximizeButton(value: boolean) {\n this.ShowMaximizeButton = value;\n } // Always false in dashboard context - maximize handled by dashboard\n public RefreshTrigger = new Subject<{ artifactId: string; versionNumber: number }>();\n\n /** @deprecated Use {@link RefreshTrigger}. */\n public get refreshTrigger() {\n return this.RefreshTrigger;\n }\n /** @deprecated Use {@link RefreshTrigger}. */\n public set refreshTrigger(value) {\n this.RefreshTrigger = value;\n }\n\n // Expose for template\n public get currentUser(): UserInfo { // case-violation-ok-legacy-back-compat: the PascalCase name is already taken in this scope\n // Use provided CurrentUser, or fall back to Metadata.CurrentUser\n // In client-side Angular context, Metadata.CurrentUser should always be available\n const user = this.CurrentUser || this.ProviderToUse.CurrentUser;\n if (!user) {\n throw new Error('No current user available - user must be logged in to view artifacts');\n }\n return user;\n }\n\n public get environmentId(): string { // case-violation-ok-legacy-back-compat: the PascalCase name is already taken in this scope\n return this.EnvironmentId || '';\n }\n\n constructor(cdr: ChangeDetectorRef, private analyzeService: AnalyzeArtifactService) {\n // Note: this component is instantiated twice — once via bare `new` by\n // ClassFactory.CreateInstanceAsync (just to extract the constructor\n // reference), then properly via createComponent() with a full injector.\n // Constructor parameters are undefined on the bare path but Angular DI\n // populates them on the real path. Field initializers calling inject()\n // would throw on the bare path, so we use constructor injection.\n super(cdr);\n }\n\n ngAfterViewInit(): void {\n if (this.Panel) {\n this.loadContent();\n }\n }\n\n public async loadContent(): Promise<void> {\n const config = this.getConfig<PanelConfig>();\n const artifactId = config?.['artifactId'] as string | undefined;\n\n if (!artifactId) {\n this.HasArtifact = false;\n this.cdr.detectChanges();\n return;\n }\n\n this.setLoading(true);\n\n try {\n // Set artifact ID and version from config\n this.artifactId = artifactId;\n this.VersionNumber = config?.['versionNumber'] as number | undefined;\n // Display options - showHeader defaults to false for clean dashboard embedding\n this.ShowHeader = (config?.['showHeader'] as boolean) ?? false;\n this.ShowTabs = (config?.['showTabs'] as boolean) ?? true;\n this.HasArtifact = true;\n\n this.setLoading(false);\n } catch (error) {\n this.setError(error instanceof Error ? error.message : 'Failed to load artifact');\n }\n }\n\n /**\n * Refresh the artifact display\n */\n public Refresh(): void {\n if (this.artifactId && this.VersionNumber) {\n this.RefreshTrigger.next({\n artifactId: this.artifactId,\n versionNumber: this.VersionNumber\n });\n }\n }\n\n /** @deprecated Use {@link Refresh}. */\n public refresh(): void {\n return this.Refresh();\n }\n\n /**\n * Handle navigation link events from artifact viewer (conversation/collection links)\n */\n public OnNavigateToLink(event: { type: 'conversation' | 'collection'; id: string; artifactId?: string; versionNumber?: number; versionId?: string }): void {\n // Emit data change event for navigation link (for listeners)\n this.emitDataChanged({\n type: 'navigate-to-link',\n linkType: event.type,\n linkId: event.id,\n artifactId: event.artifactId,\n versionNumber: event.versionNumber,\n versionId: event.versionId\n });\n\n // TODO: Add navigation request methods for conversation/collection when needed\n // For now, these are emitted as data change events for parent components to handle\n }\n\n /** @deprecated Use {@link OnNavigateToLink}. */\n public onNavigateToLink(event: { type: 'conversation' | 'collection'; id: string; artifactId?: string; versionNumber?: number; versionId?: string }): void {\n return this.OnNavigateToLink(event);\n }\n\n /**\n * Handle entity record navigation events from artifact viewer\n */\n public OnOpenEntityRecord(event: { entityName: string; compositeKey: CompositeKey }): void {\n // Emit data change event for listeners\n this.emitDataChanged({\n type: 'open-entity-record',\n entityName: event.entityName,\n compositeKey: event.compositeKey\n });\n\n // Use proper navigation request to bubble up through the stack\n if (event.entityName && event.compositeKey) {\n this.RequestOpenEntityRecord(\n event.entityName,\n event.compositeKey.ToURLSegment(),\n 'view',\n false\n );\n }\n }\n\n /** @deprecated Use {@link OnOpenEntityRecord}. */\n public onOpenEntityRecord(event: { entityName: string; compositeKey: CompositeKey }): void {\n return this.OnOpenEntityRecord(event);\n }\n\n /**\n * Handle general navigation request events from artifact viewer plugins\n */\n public OnNavigationRequest(event: NavigationRequest): void {\n this.RequestOpenNavItem(\n event.navItemName,\n event.appName,\n event.queryParams,\n false\n );\n }\n\n /** @deprecated Use {@link OnNavigationRequest}. */\n public onNavigationRequest(event: NavigationRequest): void {\n return this.OnNavigationRequest(event);\n }\n\n /**\n * Handler for the Analyze button on the embedded artifact viewer.\n * Captures the live DataSnapshot, creates an analysis conversation with\n * the snapshot attached as input, and emits a navigation request to open\n * the new conversation in the host application.\n */\n public async OnAnalyzeRequested(event: { artifactId: string; snapshot: DataSnapshot }): Promise<void> {\n try {\n const result = await this.analyzeService.StartAnalysisConversation({\n snapshot: event.snapshot,\n currentUser: this.currentUser,\n environmentId: this.environmentId,\n });\n\n this.RequestOpenNavItem(\n 'Conversations',\n undefined,\n { conversationId: result.conversationId },\n false,\n );\n } catch (error) {\n this.setError(error instanceof Error ? error.message : 'Failed to start analysis conversation');\n }\n }\n\n /** @deprecated Use {@link OnAnalyzeRequested}. */\n public async onAnalyzeRequested(event: { artifactId: string; snapshot: DataSnapshot }): Promise<void> {\n return this.OnAnalyzeRequested(event);\n }\n\n protected override cleanup(): void {\n this.RefreshTrigger.complete();\n this.artifactId = null;\n this.VersionNumber = undefined;\n }\n}\n"]}
|
|
@@ -189,7 +189,7 @@ let QueryPartComponent = class QueryPartComponent extends BaseDashboardPart {
|
|
|
189
189
|
} if (rf & 2) {
|
|
190
190
|
let _t;
|
|
191
191
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.QueryViewer = _t.first);
|
|
192
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 8, consts: [["queryViewer", ""], [1, "query-part"], [1, "loading-state"], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Couldn't load query", "Size", "compact", 1, "part-placeholder", 3, "Message"], ["Icon", "fa-solid fa-flask", "Title", "No Query Selected", "Message", "
|
|
192
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 8, consts: [["queryViewer", ""], [1, "query-part"], [1, "loading-state"], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Couldn't load query", "Size", "compact", 1, "part-placeholder", 3, "Message"], ["Icon", "fa-solid fa-flask", "Title", "No Query Selected", "Message", "Use Edit part to choose a query.", "Size", "compact", 1, "part-placeholder"], [1, "query-content"], ["text", "Loading query..."], [3, "EntityLinkClick", "QueryError", "QueryId", "AutoRun", "ShowToolbar", "PersistState", "PersistParameters"]], template: function QueryPartComponent_Template(rf, ctx) { if (rf & 1) {
|
|
193
193
|
i0.ɵɵelementStart(0, "div", 1);
|
|
194
194
|
i0.ɵɵconditionalCreate(1, QueryPartComponent_Conditional_1_Template, 2, 0, "div", 2);
|
|
195
195
|
i0.ɵɵconditionalCreate(2, QueryPartComponent_Conditional_2_Template, 1, 1, "mj-empty-state", 3);
|
|
@@ -240,7 +240,7 @@ export { QueryPartComponent };
|
|
|
240
240
|
class="part-placeholder"
|
|
241
241
|
Icon="fa-solid fa-flask"
|
|
242
242
|
Title="No Query Selected"
|
|
243
|
-
Message="
|
|
243
|
+
Message="Use Edit part to choose a query."
|
|
244
244
|
Size="compact" />
|
|
245
245
|
}
|
|
246
246
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-part.component.js","sourceRoot":"","sources":["../../../src/lib/parts/query-part.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectorRef, ViewChild, AfterViewInit, OnDestroy } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseDashboardPart } from './base-dashboard-part';\nimport { PanelConfig } from '../models/dashboard-types';\nimport { MJQueryEntity } from '@memberjunction/core-entities';\nimport { QueryViewerComponent, QueryEntityLinkClickEvent } from '@memberjunction/ng-query-viewer';\n\n/**\n * Runtime renderer for Query dashboard parts.\n * Displays query results using mj-query-viewer with parameter controls and auto-refresh support.\n */\n@RegisterClass(BaseDashboardPart, 'QueryPanelRenderer')\n@Component({\n standalone: false,\n selector: 'mj-query-part',\n template: `\n <div class=\"query-part\" [class.loading]=\"IsLoading\" [class.error]=\"ErrorMessage\">\n <!-- Loading state -->\n @if (IsLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading query...\"></mj-loading>\n </div>\n }\n \n <!-- Error state -->\n @if (ErrorMessage && !IsLoading) {\n <mj-empty-state\n class=\"part-placeholder\"\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load query\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\" />\n }\n\n <!-- No query configured -->\n @if (!IsLoading && !ErrorMessage && !hasQuery) {\n <mj-empty-state\n class=\"part-placeholder\"\n Icon=\"fa-solid fa-flask\"\n Title=\"No Query Selected\"\n Message=\"Click the configure button to select a query for this part.\"\n Size=\"compact\" />\n }\n \n <!-- Query Viewer -->\n @if (!IsLoading && !ErrorMessage && hasQuery && queryId) {\n <div class=\"query-content\">\n <mj-query-viewer\n #queryViewer\n [QueryId]=\"queryId\"\n [AutoRun]=\"true\"\n [ShowToolbar]=\"showToolbar\"\n [PersistState]=\"true\"\n [PersistParameters]=\"true\"\n (EntityLinkClick)=\"onEntityLinkClick($event)\"\n (QueryError)=\"onQueryError($event)\">\n </mj-query-viewer>\n </div>\n }\n </div>\n `,\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .query-part {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n }\n\n .loading-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--mj-text-secondary);\n text-align: center;\n padding: 24px;\n }\n\n .part-placeholder {\n height: 100%;\n }\n\n .query-content {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n }\n\n mj-query-viewer {\n display: block;\n width: 100%;\n height: 100%;\n }\n `]\n})\nexport class QueryPartComponent extends BaseDashboardPart implements AfterViewInit, OnDestroy {\n @ViewChild('queryViewer') QueryViewer!: QueryViewerComponent;\n\n /** @deprecated Use {@link QueryViewer}. */\n get queryViewer(): QueryViewerComponent {\n return this.QueryViewer;\n }\n /** @deprecated Use {@link QueryViewer}. */\n set queryViewer(value: QueryViewerComponent) {\n this.QueryViewer = value;\n }\n\n public HasQuery = false;\n\n /** @deprecated Use {@link HasQuery}. */\n public get hasQuery() {\n return this.HasQuery;\n }\n /** @deprecated Use {@link HasQuery}. */\n public set hasQuery(value) {\n this.HasQuery = value;\n }\n public QueryId: string | null = null;\n\n /** @deprecated Use {@link QueryId}. */\n public get queryId(): string | null {\n return this.QueryId;\n }\n /** @deprecated Use {@link QueryId}. */\n public set queryId(value: string | null) {\n this.QueryId = value;\n }\n public ShowToolbar = true;\n\n /** @deprecated Use {@link ShowToolbar}. */\n public get showToolbar() {\n return this.ShowToolbar;\n }\n /** @deprecated Use {@link ShowToolbar}. */\n public set showToolbar(value) {\n this.ShowToolbar = value;\n }\n\n private queryEntity: MJQueryEntity | null = null;\n private autoRefreshTimer: ReturnType<typeof setInterval> | null = null;\n\n constructor(cdr: ChangeDetectorRef) {\n super(cdr);\n }\n\n ngAfterViewInit(): void {\n if (this.Panel) {\n this.loadContent();\n }\n }\n\n public async loadContent(): Promise<void> {\n const config = this.getConfig<PanelConfig>();\n const queryId = config?.['queryId'] as string | undefined;\n const queryName = config?.['queryName'] as string | undefined;\n\n if (!queryId && !queryName) {\n this.HasQuery = false;\n this.cdr.detectChanges();\n return;\n }\n\n this.setLoading(true);\n this.stopAutoRefresh();\n\n try {\n const p = this.ProviderToUse;\n\n if (queryId) {\n // Load query by ID to verify it exists\n this.queryEntity = await p.GetEntityObject<MJQueryEntity>('MJ: Queries', p.CurrentUser);\n const loaded = await this.queryEntity.Load(queryId);\n\n if (!loaded) {\n throw new Error('Query not found');\n }\n\n this.QueryId = queryId;\n } else if (queryName) {\n // Query by name - find the query ID from metadata\n const queryInfo = p.Queries.find(q => q.Name === queryName);\n if (queryInfo) {\n this.QueryId = queryInfo.ID;\n } else {\n throw new Error(`Query \"${queryName}\" not found`);\n }\n }\n\n this.HasQuery = true;\n this.ShowToolbar = (config?.['showParameterControls'] as boolean) !== false;\n\n // Set auto-refresh if configured\n const autoRefreshSeconds = (config?.['autoRefreshSeconds'] as number) || 0;\n if (autoRefreshSeconds > 0) {\n this.startAutoRefresh(autoRefreshSeconds);\n }\n\n this.setLoading(false);\n } catch (error) {\n this.setError(error instanceof Error ? error.message : 'Failed to load query');\n }\n }\n\n public OnEntityLinkClick(event: QueryEntityLinkClickEvent): void {\n // Emit data change event with clicked entity info (for any listeners that need it)\n this.emitDataChanged({\n type: 'entity-link-click',\n entityName: event.entityName,\n recordId: event.recordId\n });\n\n // Request navigation to open the record\n if (event.entityName && event.recordId) {\n this.RequestOpenEntityRecord(\n event.entityName,\n event.recordId,\n 'view',\n false\n );\n }\n }\n\n /** @deprecated Use {@link OnEntityLinkClick}. */\n public onEntityLinkClick(event: QueryEntityLinkClickEvent): void {\n return this.OnEntityLinkClick(event);\n }\n\n public OnQueryError(error: Error): void {\n console.error('[QueryPart] Query error:', error.message);\n }\n\n /** @deprecated Use {@link OnQueryError}. */\n public onQueryError(error: Error): void {\n return this.OnQueryError(error);\n }\n\n public RefreshQuery(): void {\n if (this.QueryViewer) {\n this.QueryViewer.Refresh();\n }\n }\n\n /** @deprecated Use {@link RefreshQuery}. */\n public refreshQuery(): void {\n return this.RefreshQuery();\n }\n\n private startAutoRefresh(seconds: number): void {\n this.stopAutoRefresh();\n if (seconds > 0) {\n this.autoRefreshTimer = setInterval(() => {\n this.RefreshQuery();\n }, seconds * 1000);\n }\n }\n\n private stopAutoRefresh(): void {\n if (this.autoRefreshTimer) {\n clearInterval(this.autoRefreshTimer);\n this.autoRefreshTimer = null;\n }\n }\n\n protected override cleanup(): void {\n this.stopAutoRefresh();\n this.queryEntity = null;\n this.QueryId = null;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"query-part.component.js","sourceRoot":"","sources":["../../../src/lib/parts/query-part.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectorRef, ViewChild, AfterViewInit, OnDestroy } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseDashboardPart } from './base-dashboard-part';\nimport { PanelConfig } from '../models/dashboard-types';\nimport { MJQueryEntity } from '@memberjunction/core-entities';\nimport { QueryViewerComponent, QueryEntityLinkClickEvent } from '@memberjunction/ng-query-viewer';\n\n/**\n * Runtime renderer for Query dashboard parts.\n * Displays query results using mj-query-viewer with parameter controls and auto-refresh support.\n */\n@RegisterClass(BaseDashboardPart, 'QueryPanelRenderer')\n@Component({\n standalone: false,\n selector: 'mj-query-part',\n template: `\n <div class=\"query-part\" [class.loading]=\"IsLoading\" [class.error]=\"ErrorMessage\">\n <!-- Loading state -->\n @if (IsLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading query...\"></mj-loading>\n </div>\n }\n \n <!-- Error state -->\n @if (ErrorMessage && !IsLoading) {\n <mj-empty-state\n class=\"part-placeholder\"\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load query\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\" />\n }\n\n <!-- No query configured -->\n @if (!IsLoading && !ErrorMessage && !hasQuery) {\n <mj-empty-state\n class=\"part-placeholder\"\n Icon=\"fa-solid fa-flask\"\n Title=\"No Query Selected\"\n Message=\"Use Edit part to choose a query.\"\n Size=\"compact\" />\n }\n \n <!-- Query Viewer -->\n @if (!IsLoading && !ErrorMessage && hasQuery && queryId) {\n <div class=\"query-content\">\n <mj-query-viewer\n #queryViewer\n [QueryId]=\"queryId\"\n [AutoRun]=\"true\"\n [ShowToolbar]=\"showToolbar\"\n [PersistState]=\"true\"\n [PersistParameters]=\"true\"\n (EntityLinkClick)=\"onEntityLinkClick($event)\"\n (QueryError)=\"onQueryError($event)\">\n </mj-query-viewer>\n </div>\n }\n </div>\n `,\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .query-part {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n }\n\n .loading-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--mj-text-secondary);\n text-align: center;\n padding: 24px;\n }\n\n .part-placeholder {\n height: 100%;\n }\n\n .query-content {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n }\n\n mj-query-viewer {\n display: block;\n width: 100%;\n height: 100%;\n }\n `]\n})\nexport class QueryPartComponent extends BaseDashboardPart implements AfterViewInit, OnDestroy {\n @ViewChild('queryViewer') QueryViewer!: QueryViewerComponent;\n\n /** @deprecated Use {@link QueryViewer}. */\n get queryViewer(): QueryViewerComponent {\n return this.QueryViewer;\n }\n /** @deprecated Use {@link QueryViewer}. */\n set queryViewer(value: QueryViewerComponent) {\n this.QueryViewer = value;\n }\n\n public HasQuery = false;\n\n /** @deprecated Use {@link HasQuery}. */\n public get hasQuery() {\n return this.HasQuery;\n }\n /** @deprecated Use {@link HasQuery}. */\n public set hasQuery(value) {\n this.HasQuery = value;\n }\n public QueryId: string | null = null;\n\n /** @deprecated Use {@link QueryId}. */\n public get queryId(): string | null {\n return this.QueryId;\n }\n /** @deprecated Use {@link QueryId}. */\n public set queryId(value: string | null) {\n this.QueryId = value;\n }\n public ShowToolbar = true;\n\n /** @deprecated Use {@link ShowToolbar}. */\n public get showToolbar() {\n return this.ShowToolbar;\n }\n /** @deprecated Use {@link ShowToolbar}. */\n public set showToolbar(value) {\n this.ShowToolbar = value;\n }\n\n private queryEntity: MJQueryEntity | null = null;\n private autoRefreshTimer: ReturnType<typeof setInterval> | null = null;\n\n constructor(cdr: ChangeDetectorRef) {\n super(cdr);\n }\n\n ngAfterViewInit(): void {\n if (this.Panel) {\n this.loadContent();\n }\n }\n\n public async loadContent(): Promise<void> {\n const config = this.getConfig<PanelConfig>();\n const queryId = config?.['queryId'] as string | undefined;\n const queryName = config?.['queryName'] as string | undefined;\n\n if (!queryId && !queryName) {\n this.HasQuery = false;\n this.cdr.detectChanges();\n return;\n }\n\n this.setLoading(true);\n this.stopAutoRefresh();\n\n try {\n const p = this.ProviderToUse;\n\n if (queryId) {\n // Load query by ID to verify it exists\n this.queryEntity = await p.GetEntityObject<MJQueryEntity>('MJ: Queries', p.CurrentUser);\n const loaded = await this.queryEntity.Load(queryId);\n\n if (!loaded) {\n throw new Error('Query not found');\n }\n\n this.QueryId = queryId;\n } else if (queryName) {\n // Query by name - find the query ID from metadata\n const queryInfo = p.Queries.find(q => q.Name === queryName);\n if (queryInfo) {\n this.QueryId = queryInfo.ID;\n } else {\n throw new Error(`Query \"${queryName}\" not found`);\n }\n }\n\n this.HasQuery = true;\n this.ShowToolbar = (config?.['showParameterControls'] as boolean) !== false;\n\n // Set auto-refresh if configured\n const autoRefreshSeconds = (config?.['autoRefreshSeconds'] as number) || 0;\n if (autoRefreshSeconds > 0) {\n this.startAutoRefresh(autoRefreshSeconds);\n }\n\n this.setLoading(false);\n } catch (error) {\n this.setError(error instanceof Error ? error.message : 'Failed to load query');\n }\n }\n\n public OnEntityLinkClick(event: QueryEntityLinkClickEvent): void {\n // Emit data change event with clicked entity info (for any listeners that need it)\n this.emitDataChanged({\n type: 'entity-link-click',\n entityName: event.entityName,\n recordId: event.recordId\n });\n\n // Request navigation to open the record\n if (event.entityName && event.recordId) {\n this.RequestOpenEntityRecord(\n event.entityName,\n event.recordId,\n 'view',\n false\n );\n }\n }\n\n /** @deprecated Use {@link OnEntityLinkClick}. */\n public onEntityLinkClick(event: QueryEntityLinkClickEvent): void {\n return this.OnEntityLinkClick(event);\n }\n\n public OnQueryError(error: Error): void {\n console.error('[QueryPart] Query error:', error.message);\n }\n\n /** @deprecated Use {@link OnQueryError}. */\n public onQueryError(error: Error): void {\n return this.OnQueryError(error);\n }\n\n public RefreshQuery(): void {\n if (this.QueryViewer) {\n this.QueryViewer.Refresh();\n }\n }\n\n /** @deprecated Use {@link RefreshQuery}. */\n public refreshQuery(): void {\n return this.RefreshQuery();\n }\n\n private startAutoRefresh(seconds: number): void {\n this.stopAutoRefresh();\n if (seconds > 0) {\n this.autoRefreshTimer = setInterval(() => {\n this.RefreshQuery();\n }, seconds * 1000);\n }\n }\n\n private stopAutoRefresh(): void {\n if (this.autoRefreshTimer) {\n clearInterval(this.autoRefreshTimer);\n this.autoRefreshTimer = null;\n }\n }\n\n protected override cleanup(): void {\n this.stopAutoRefresh();\n this.queryEntity = null;\n this.QueryId = null;\n }\n}\n"]}
|
|
@@ -176,7 +176,7 @@ let ViewPartComponent = class ViewPartComponent extends BaseDashboardPart {
|
|
|
176
176
|
this.EntityInfo = null;
|
|
177
177
|
}
|
|
178
178
|
static ɵfac = function ViewPartComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ViewPartComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
179
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ViewPartComponent, selectors: [["mj-view-part"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 8, consts: [[1, "view-part"], [1, "loading-state"], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Couldn't load view", "Size", "compact", 1, "part-placeholder", 3, "Message"], ["Icon", "fa-solid fa-table", "Title", "No View Selected", "Message", "
|
|
179
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ViewPartComponent, selectors: [["mj-view-part"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 8, consts: [[1, "view-part"], [1, "loading-state"], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Couldn't load view", "Size", "compact", 1, "part-placeholder", 3, "Message"], ["Icon", "fa-solid fa-table", "Title", "No View Selected", "Message", "Use Edit part to choose a view.", "Size", "compact", 1, "part-placeholder"], [3, "Entity", "ViewEntity"], ["text", "Loading view..."], [3, "RecordSelected", "RecordOpened", "OpenRelatedRecordRequested", "Entity", "ViewEntity"]], template: function ViewPartComponent_Template(rf, ctx) { if (rf & 1) {
|
|
180
180
|
i0.ɵɵelementStart(0, "div", 0);
|
|
181
181
|
i0.ɵɵconditionalCreate(1, ViewPartComponent_Conditional_1_Template, 2, 0, "div", 1);
|
|
182
182
|
i0.ɵɵconditionalCreate(2, ViewPartComponent_Conditional_2_Template, 1, 1, "mj-empty-state", 2);
|
|
@@ -227,7 +227,7 @@ export { ViewPartComponent };
|
|
|
227
227
|
class="part-placeholder"
|
|
228
228
|
Icon="fa-solid fa-table"
|
|
229
229
|
Title="No View Selected"
|
|
230
|
-
Message="
|
|
230
|
+
Message="Use Edit part to choose a view."
|
|
231
231
|
Size="compact" />
|
|
232
232
|
}
|
|
233
233
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-part.component.js","sourceRoot":"","sources":["../../../src/lib/parts/view-part.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectorRef, AfterViewInit, OnDestroy } from '@angular/core';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { BaseDashboardPart } from './base-dashboard-part';\nimport { PanelConfig } from '../models/dashboard-types';\nimport { EntityInfo } from '@memberjunction/core';\nimport { MJUserViewEntityExtended } from '@memberjunction/core-entities';\nimport { RecordSelectedEvent, RecordOpenedEvent, ViewRelatedRecordNavigation } from '@memberjunction/ng-entity-viewer';\n\n/**\n * Runtime renderer for View dashboard parts.\n * Displays entity data using mj-entity-viewer with grid, cards, or timeline layout.\n */\n@RegisterClass(BaseDashboardPart, 'ViewPanelRenderer')\n@Component({\n standalone: false,\n selector: 'mj-view-part',\n template: `\n <div class=\"view-part\" [class.loading]=\"IsLoading\" [class.error]=\"ErrorMessage\">\n <!-- Loading state -->\n @if (IsLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading view...\"></mj-loading>\n </div>\n }\n \n <!-- Error state -->\n @if (ErrorMessage && !IsLoading) {\n <mj-empty-state\n class=\"part-placeholder\"\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load view\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\" />\n }\n\n <!-- No view configured -->\n @if (!IsLoading && !ErrorMessage && !hasView) {\n <mj-empty-state\n class=\"part-placeholder\"\n Icon=\"fa-solid fa-table\"\n Title=\"No View Selected\"\n Message=\"Click the configure button to select a view for this part.\"\n Size=\"compact\" />\n }\n \n <!-- Entity Viewer -->\n @if (!IsLoading && !ErrorMessage && hasView && entityInfo) {\n <mj-entity-viewer\n [Entity]=\"entityInfo\"\n [ViewEntity]=\"viewEntity\"\n (RecordSelected)=\"onRecordSelected($event)\"\n (RecordOpened)=\"onRecordOpened($event)\"\n (OpenRelatedRecordRequested)=\"onOpenRelatedRecordRequested($event)\">\n </mj-entity-viewer>\n }\n </div>\n `,\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .view-part {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n }\n\n .loading-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--mj-text-secondary);\n text-align: center;\n padding: 24px;\n }\n\n .part-placeholder {\n height: 100%;\n }\n\n mj-entity-viewer {\n flex: 1;\n min-height: 0;\n }\n `]\n})\nexport class ViewPartComponent extends BaseDashboardPart implements AfterViewInit, OnDestroy {\n public HasView = false;\n\n /** @deprecated Use {@link HasView}. */\n public get hasView() {\n return this.HasView;\n }\n /** @deprecated Use {@link HasView}. */\n public set hasView(value) {\n this.HasView = value;\n }\n public ViewEntity: MJUserViewEntityExtended | null = null;\n\n /** @deprecated Use {@link ViewEntity}. */\n public get viewEntity(): MJUserViewEntityExtended | null {\n return this.ViewEntity;\n }\n /** @deprecated Use {@link ViewEntity}. */\n public set viewEntity(value: MJUserViewEntityExtended | null) {\n this.ViewEntity = value;\n }\n public EntityInfo: EntityInfo | null = null;\n\n /** @deprecated Use {@link EntityInfo}. */\n public get entityInfo(): EntityInfo | null {\n return this.EntityInfo;\n }\n /** @deprecated Use {@link EntityInfo}. */\n public set entityInfo(value: EntityInfo | null) {\n this.EntityInfo = value;\n }\n\n constructor(cdr: ChangeDetectorRef) {\n super(cdr);\n }\n\n ngAfterViewInit(): void {\n if (this.Panel) {\n this.loadContent();\n }\n }\n\n public async loadContent(): Promise<void> {\n const config = this.getConfig<PanelConfig>();\n const viewId = config?.['viewId'] as string | undefined;\n const entityName = config?.['entityName'] as string | undefined;\n\n if (!viewId && !entityName) {\n this.HasView = false;\n this.cdr.detectChanges();\n return;\n }\n\n this.setLoading(true);\n\n try {\n const p = this.ProviderToUse;\n\n if (viewId) {\n // Load saved view by ID\n const viewEntity = await p.GetEntityObject<MJUserViewEntityExtended>('MJ: User Views', p.CurrentUser);\n const loaded = await viewEntity.Load(viewId);\n this.ViewEntity = viewEntity; // IMPORTANT - only set this.viewEntity AFTER we have it loaded in the above\n\n if (!loaded) {\n throw new Error('View not found');\n }\n\n // Get entity info from the view - prefer ViewEntityInfo if available (set by MJUserViewEntityExtended.Load)\n // Fall back to looking up by Entity name (virtual field) or EntityID\n if (viewEntity.ViewEntityInfo) {\n this.EntityInfo = viewEntity.ViewEntityInfo;\n } else if (viewEntity.Entity) {\n this.EntityInfo = p.EntityByName(viewEntity!.Entity) || null;\n } else if (viewEntity.EntityID) {\n // Last resort: look up by EntityID\n this.EntityInfo = p.Entities.find(e => UUIDsEqual(e.ID, viewEntity!.EntityID)) || null;\n }\n\n if (!this.EntityInfo) {\n throw new Error(`Could not determine entity for view \"${this.ViewEntity.Name}\" (ID: ${viewId})`);\n }\n } else if (entityName) {\n // Create dynamic view for entity (no saved view)\n this.EntityInfo = p.EntityByName(entityName) || null;\n\n if (!this.EntityInfo) {\n throw new Error(`Entity \"${entityName}\" not found`);\n }\n\n // No viewEntity means the entity-viewer will show all records\n this.ViewEntity = null;\n }\n\n this.HasView = true;\n this.setLoading(false);\n } catch (error) {\n this.setError(error instanceof Error ? error.message : 'Failed to load view');\n }\n }\n\n public OnRecordSelected(event: RecordSelectedEvent): void {\n // Emit data change event with selected record\n this.emitDataChanged({\n type: 'record-selected',\n record: event.record,\n primaryKey: event.record?.PrimaryKey\n });\n }\n\n /** @deprecated Use {@link OnRecordSelected}. */\n public onRecordSelected(event: RecordSelectedEvent): void {\n return this.OnRecordSelected(event);\n }\n\n public OnRecordOpened(event: RecordOpenedEvent): void {\n // Emit data change event for record open (for any listeners that need it)\n this.emitDataChanged({\n type: 'record-opened',\n record: event.record,\n primaryKey: event.record?.PrimaryKey\n });\n\n // Request navigation to open the record\n if (event.entity && event.compositeKey) {\n this.RequestOpenEntityRecord(\n event.entity.Name,\n event.compositeKey.ToURLSegment(),\n 'view',\n false\n );\n }\n }\n\n /** @deprecated Use {@link OnRecordOpened}. */\n public onRecordOpened(event: RecordOpenedEvent): void {\n return this.OnRecordOpened(event);\n }\n\n /**\n * Handle a plug-in renderer's request (bubbled up via the inner entity-viewer) to open a\n * *related* record on a (possibly different) entity — e.g. a grid foreign-key drill-through.\n * Requests navigation through the dashboard-part routing contract.\n *\n * @param nav the related-record navigation payload: the target entity name and the record's key.\n */\n public OnOpenRelatedRecordRequested(nav: ViewRelatedRecordNavigation): void {\n if (nav?.entityName && nav.recordKey != null) {\n this.RequestOpenEntityRecord(\n nav.entityName,\n String(nav.recordKey),\n 'view',\n false\n );\n }\n }\n\n /** @deprecated Use {@link OnOpenRelatedRecordRequested}. */\n public onOpenRelatedRecordRequested(nav: ViewRelatedRecordNavigation): void {\n return this.OnOpenRelatedRecordRequested(nav);\n }\n\n protected override cleanup(): void {\n // EntityViewer handles its own cleanup\n this.ViewEntity = null;\n this.EntityInfo = null;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"view-part.component.js","sourceRoot":"","sources":["../../../src/lib/parts/view-part.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectorRef, AfterViewInit, OnDestroy } from '@angular/core';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { BaseDashboardPart } from './base-dashboard-part';\nimport { PanelConfig } from '../models/dashboard-types';\nimport { EntityInfo } from '@memberjunction/core';\nimport { MJUserViewEntityExtended } from '@memberjunction/core-entities';\nimport { RecordSelectedEvent, RecordOpenedEvent, ViewRelatedRecordNavigation } from '@memberjunction/ng-entity-viewer';\n\n/**\n * Runtime renderer for View dashboard parts.\n * Displays entity data using mj-entity-viewer with grid, cards, or timeline layout.\n */\n@RegisterClass(BaseDashboardPart, 'ViewPanelRenderer')\n@Component({\n standalone: false,\n selector: 'mj-view-part',\n template: `\n <div class=\"view-part\" [class.loading]=\"IsLoading\" [class.error]=\"ErrorMessage\">\n <!-- Loading state -->\n @if (IsLoading) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading view...\"></mj-loading>\n </div>\n }\n \n <!-- Error state -->\n @if (ErrorMessage && !IsLoading) {\n <mj-empty-state\n class=\"part-placeholder\"\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load view\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\" />\n }\n\n <!-- No view configured -->\n @if (!IsLoading && !ErrorMessage && !hasView) {\n <mj-empty-state\n class=\"part-placeholder\"\n Icon=\"fa-solid fa-table\"\n Title=\"No View Selected\"\n Message=\"Use Edit part to choose a view.\"\n Size=\"compact\" />\n }\n \n <!-- Entity Viewer -->\n @if (!IsLoading && !ErrorMessage && hasView && entityInfo) {\n <mj-entity-viewer\n [Entity]=\"entityInfo\"\n [ViewEntity]=\"viewEntity\"\n (RecordSelected)=\"onRecordSelected($event)\"\n (RecordOpened)=\"onRecordOpened($event)\"\n (OpenRelatedRecordRequested)=\"onOpenRelatedRecordRequested($event)\">\n </mj-entity-viewer>\n }\n </div>\n `,\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .view-part {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n }\n\n .loading-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--mj-text-secondary);\n text-align: center;\n padding: 24px;\n }\n\n .part-placeholder {\n height: 100%;\n }\n\n mj-entity-viewer {\n flex: 1;\n min-height: 0;\n }\n `]\n})\nexport class ViewPartComponent extends BaseDashboardPart implements AfterViewInit, OnDestroy {\n public HasView = false;\n\n /** @deprecated Use {@link HasView}. */\n public get hasView() {\n return this.HasView;\n }\n /** @deprecated Use {@link HasView}. */\n public set hasView(value) {\n this.HasView = value;\n }\n public ViewEntity: MJUserViewEntityExtended | null = null;\n\n /** @deprecated Use {@link ViewEntity}. */\n public get viewEntity(): MJUserViewEntityExtended | null {\n return this.ViewEntity;\n }\n /** @deprecated Use {@link ViewEntity}. */\n public set viewEntity(value: MJUserViewEntityExtended | null) {\n this.ViewEntity = value;\n }\n public EntityInfo: EntityInfo | null = null;\n\n /** @deprecated Use {@link EntityInfo}. */\n public get entityInfo(): EntityInfo | null {\n return this.EntityInfo;\n }\n /** @deprecated Use {@link EntityInfo}. */\n public set entityInfo(value: EntityInfo | null) {\n this.EntityInfo = value;\n }\n\n constructor(cdr: ChangeDetectorRef) {\n super(cdr);\n }\n\n ngAfterViewInit(): void {\n if (this.Panel) {\n this.loadContent();\n }\n }\n\n public async loadContent(): Promise<void> {\n const config = this.getConfig<PanelConfig>();\n const viewId = config?.['viewId'] as string | undefined;\n const entityName = config?.['entityName'] as string | undefined;\n\n if (!viewId && !entityName) {\n this.HasView = false;\n this.cdr.detectChanges();\n return;\n }\n\n this.setLoading(true);\n\n try {\n const p = this.ProviderToUse;\n\n if (viewId) {\n // Load saved view by ID\n const viewEntity = await p.GetEntityObject<MJUserViewEntityExtended>('MJ: User Views', p.CurrentUser);\n const loaded = await viewEntity.Load(viewId);\n this.ViewEntity = viewEntity; // IMPORTANT - only set this.viewEntity AFTER we have it loaded in the above\n\n if (!loaded) {\n throw new Error('View not found');\n }\n\n // Get entity info from the view - prefer ViewEntityInfo if available (set by MJUserViewEntityExtended.Load)\n // Fall back to looking up by Entity name (virtual field) or EntityID\n if (viewEntity.ViewEntityInfo) {\n this.EntityInfo = viewEntity.ViewEntityInfo;\n } else if (viewEntity.Entity) {\n this.EntityInfo = p.EntityByName(viewEntity!.Entity) || null;\n } else if (viewEntity.EntityID) {\n // Last resort: look up by EntityID\n this.EntityInfo = p.Entities.find(e => UUIDsEqual(e.ID, viewEntity!.EntityID)) || null;\n }\n\n if (!this.EntityInfo) {\n throw new Error(`Could not determine entity for view \"${this.ViewEntity.Name}\" (ID: ${viewId})`);\n }\n } else if (entityName) {\n // Create dynamic view for entity (no saved view)\n this.EntityInfo = p.EntityByName(entityName) || null;\n\n if (!this.EntityInfo) {\n throw new Error(`Entity \"${entityName}\" not found`);\n }\n\n // No viewEntity means the entity-viewer will show all records\n this.ViewEntity = null;\n }\n\n this.HasView = true;\n this.setLoading(false);\n } catch (error) {\n this.setError(error instanceof Error ? error.message : 'Failed to load view');\n }\n }\n\n public OnRecordSelected(event: RecordSelectedEvent): void {\n // Emit data change event with selected record\n this.emitDataChanged({\n type: 'record-selected',\n record: event.record,\n primaryKey: event.record?.PrimaryKey\n });\n }\n\n /** @deprecated Use {@link OnRecordSelected}. */\n public onRecordSelected(event: RecordSelectedEvent): void {\n return this.OnRecordSelected(event);\n }\n\n public OnRecordOpened(event: RecordOpenedEvent): void {\n // Emit data change event for record open (for any listeners that need it)\n this.emitDataChanged({\n type: 'record-opened',\n record: event.record,\n primaryKey: event.record?.PrimaryKey\n });\n\n // Request navigation to open the record\n if (event.entity && event.compositeKey) {\n this.RequestOpenEntityRecord(\n event.entity.Name,\n event.compositeKey.ToURLSegment(),\n 'view',\n false\n );\n }\n }\n\n /** @deprecated Use {@link OnRecordOpened}. */\n public onRecordOpened(event: RecordOpenedEvent): void {\n return this.OnRecordOpened(event);\n }\n\n /**\n * Handle a plug-in renderer's request (bubbled up via the inner entity-viewer) to open a\n * *related* record on a (possibly different) entity — e.g. a grid foreign-key drill-through.\n * Requests navigation through the dashboard-part routing contract.\n *\n * @param nav the related-record navigation payload: the target entity name and the record's key.\n */\n public OnOpenRelatedRecordRequested(nav: ViewRelatedRecordNavigation): void {\n if (nav?.entityName && nav.recordKey != null) {\n this.RequestOpenEntityRecord(\n nav.entityName,\n String(nav.recordKey),\n 'view',\n false\n );\n }\n }\n\n /** @deprecated Use {@link OnOpenRelatedRecordRequested}. */\n public onOpenRelatedRecordRequested(nav: ViewRelatedRecordNavigation): void {\n return this.OnOpenRelatedRecordRequested(nav);\n }\n\n protected override cleanup(): void {\n // EntityViewer handles its own cleanup\n this.ViewEntity = null;\n this.EntityInfo = null;\n }\n}\n"]}
|
|
@@ -280,7 +280,7 @@ let WebURLPartComponent = class WebURLPartComponent extends BaseDashboardPart {
|
|
|
280
280
|
} if (rf & 2) {
|
|
281
281
|
let _t;
|
|
282
282
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.IframeRef = _t.first);
|
|
283
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 6, vars: 9, consts: [["iframe", ""], [1, "weburl-part"], [1, "loading-state"], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Couldn't load content", "Size", "compact", 1, "part-placeholder", 3, "Message"], ["Icon", "fa-solid fa-globe", "Title", "No URL Configured", "Message", "
|
|
283
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 6, vars: 9, consts: [["iframe", ""], [1, "weburl-part"], [1, "loading-state"], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Couldn't load content", "Size", "compact", 1, "part-placeholder", 3, "Message"], ["Icon", "fa-solid fa-globe", "Title", "No URL Configured", "Message", "Use Edit part to set a URL.", "Size", "compact", 1, "part-placeholder"], [1, "iframe-fallback"], [1, "fa-solid", "fa-spinner", "fa-spin"], ["actions", "", "target", "_blank", 1, "open-link", 3, "href"], [1, "fa-solid", "fa-up-right-from-square"], ["sandbox", "allow-scripts allow-same-origin allow-forms allow-popups", "allowfullscreen", "", 1, "content-iframe", 3, "src", "title"], ["sandbox", "allow-scripts allow-same-origin allow-forms allow-popups", 1, "content-iframe", 3, "src", "title"], ["sandbox", "allow-scripts", "allowfullscreen", "", 1, "content-iframe", 3, "src", "title"], ["sandbox", "allow-scripts", 1, "content-iframe", 3, "src", "title"], ["sandbox", "allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-top-navigation", "allowfullscreen", "", 1, "content-iframe", 3, "src", "title"], ["sandbox", "allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-top-navigation", 1, "content-iframe", 3, "src", "title"], ["sandbox", "allow-scripts allow-same-origin allow-forms allow-popups", "allowfullscreen", "", 1, "content-iframe", 3, "load", "error", "src", "title"], ["sandbox", "allow-scripts allow-same-origin allow-forms allow-popups", 1, "content-iframe", 3, "load", "error", "src", "title"], ["sandbox", "allow-scripts", "allowfullscreen", "", 1, "content-iframe", 3, "load", "error", "src", "title"], ["sandbox", "allow-scripts", 1, "content-iframe", 3, "load", "error", "src", "title"], ["sandbox", "allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-top-navigation", "allowfullscreen", "", 1, "content-iframe", 3, "load", "error", "src", "title"], ["sandbox", "allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-top-navigation", 1, "content-iframe", 3, "load", "error", "src", "title"], ["target", "_blank", 3, "href"], [1, "fa-solid", "fa-external-link-alt"]], template: function WebURLPartComponent_Template(rf, ctx) { if (rf & 1) {
|
|
284
284
|
i0.ɵɵelementStart(0, "div", 1);
|
|
285
285
|
i0.ɵɵconditionalCreate(1, WebURLPartComponent_Conditional_1_Template, 4, 0, "div", 2);
|
|
286
286
|
i0.ɵɵconditionalCreate(2, WebURLPartComponent_Conditional_2_Template, 2, 2, "mj-empty-state", 3);
|
|
@@ -342,7 +342,7 @@ export { WebURLPartComponent };
|
|
|
342
342
|
class="part-placeholder"
|
|
343
343
|
Icon="fa-solid fa-globe"
|
|
344
344
|
Title="No URL Configured"
|
|
345
|
-
Message="
|
|
345
|
+
Message="Use Edit part to set a URL."
|
|
346
346
|
Size="compact" />
|
|
347
347
|
}
|
|
348
348
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"weburl-part.component.js","sourceRoot":"","sources":["../../../src/lib/parts/weburl-part.component.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAiC,SAAS,EAAiB,MAAM,eAAe,CAAC;AAEnG,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;;;;;;IAe9C,8BAA2B;IACzB,uBAA2C;IAC3C,4BAAM;IAAA,0BAAU;IAClB,AADkB,iBAAO,EACnB;;;IAaF,4BAA6D;IAC3D,uBAAgD;IAChD,oCACF;IAAA,iBAAI;;;IAHO,sDAAe;;;IAR9B,yCAMiB;IACf,iGAAc;IAMhB,iBAAiB;;;IARf,6CAAwB;IAExB,cAKC;IALD,wCAKC;;;IAMH,oCAKmB;;;;IAOjB,qCAQyB;IADvB,AADA,oMAAQ,qBAAc,KAAC,+LACd,4BAAqB,KAAC;IAEjC,iBAAS;;;IAJP,AAHA,8DAAe,mFAG6B;;;;IAQ9C,qCAOyB;IADvB,AADA,oMAAQ,qBAAc,KAAC,+LACd,4BAAqB,KAAC;IAEjC,iBAAS;;;IAJP,AAFA,8DAAe,mFAE6B;;;;IAQ9C,qCAQyB;IADvB,AADA,oMAAQ,qBAAc,KAAC,+LACd,4BAAqB,KAAC;IAEjC,iBAAS;;;IAJP,AAHA,8DAAe,mFAG6B;;;;IAQ9C,qCAOyB;IADvB,AADA,oMAAQ,qBAAc,KAAC,+LACd,4BAAqB,KAAC;IAEjC,iBAAS;;;IAJP,AAFA,8DAAe,mFAE6B;;;;IAQ9C,qCAQyB;IADvB,AADA,oMAAQ,qBAAc,KAAC,+LACd,4BAAqB,KAAC;IAEjC,iBAAS;;;IAJP,AAHA,8DAAe,mFAG6B;;;;IAQ9C,qCAOyB;IADvB,AADA,oMAAQ,qBAAc,KAAC,+LACd,4BAAqB,KAAC;IAEjC,iBAAS;;;IAJP,AAFA,8DAAe,mFAE6B;;;IApEhD,sGAAqD;IAarD,uGAAsD;IAYtD,uGAAmD;IAanD,uGAAoD;IAYpD,uGAAuD;IAavD,uGAAwD;;;IA/DxD,sFAWC;IAED,cAUC;IAVD,uFAUC;IAED,cAWC;IAXD,oFAWC;IAED,cAUC;IAVD,qFAUC;IAED,cAWC;IAXD,wFAWC;IAED,cAUC;IAVD,yFAUC;;;IAMC,AADF,8BAA6B,WACrB;IAAA,4CAA4B;IAAA,iBAAO;IACzC,6BAAmC;IACjC,wBAA6C;IAC7C,oCACF;IACF,AADE,iBAAI,EACA;;;IAJD,eAAe;IAAf,sDAAe;;AAjIhC;;;GAGG;AA4NI,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,iBAAiB;IACjC,SAAS,CAAiC;IAE/D,yCAAyC;IACzC,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IACD,yCAAyC;IACzC,IAAI,SAAS,CAAC,KAAoC;QAChD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAEM,OAAO,GAA2B,IAAI,CAAC;IACvC,MAAM,GAAW,EAAE,CAAC;IAE3B,sCAAsC;IACtC,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IACD,sCAAsC;IACtC,IAAW,MAAM,CAAC,KAAa;QAC7B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IACM,WAAW,GAAyC,UAAU,CAAC;IAEtE,2CAA2C;IAC3C,IAAW,WAAW;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IACD,2CAA2C;IAC3C,IAAW,WAAW,CAAC,KAA2C;QAChE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IACM,eAAe,GAAY,IAAI,CAAC;IAEvC,+CAA+C;IAC/C,IAAW,eAAe;QACxB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IACD,+CAA+C;IAC/C,IAAW,eAAe,CAAC,KAAc;QACvC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;IAC/B,CAAC;IACM,gBAAgB,GAAY,KAAK,CAAC;IAEzC,gDAAgD;IAChD,IAAW,gBAAgB;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IACD,gDAAgD;IAChD,IAAW,gBAAgB,CAAC,KAAc;QACxC,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAChC,CAAC,CAAC,uDAAuD;IAEjD,SAAS,CAAe;IACxB,gBAAgB,GAAyC,IAAI,CAAC;IAC9D,YAAY,GAAY,KAAK,CAAC;IAEtC,YAAY,GAAsB,EAAE,SAAuB;QACvD,KAAK,CAAC,GAAG,CAAC,CAAC;QACX,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC/B,CAAC;IAED,eAAe;QACX,uCAAuC;QACvC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,WAAW,EAAE,CAAC;QACvB,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,WAAW;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAe,CAAC;QAC7C,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,KAAK,CAAuB,CAAC;QAElD,6BAA6B;QAC7B,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACpC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QACjC,CAAC;QAED,cAAc;QACd,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAE9B,IAAI,CAAC,GAAG,EAAE,CAAC;YACP,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;YACjB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YACzB,OAAO;QACX,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAEtB,IAAI,CAAC;YACD,kCAAkC;YAClC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;YAElB,8CAA8C;YAC9C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,8BAA8B,CAAC,GAAG,CAAC,CAAC;YAElE,+DAA+D;YAC/D,IAAI,CAAC,WAAW,GAAI,MAAM,EAAE,CAAC,aAAa,CAA0C,IAAI,UAAU,CAAC;YAEnG,4BAA4B;YAC5B,IAAI,CAAC,eAAe,GAAI,MAAM,EAAE,CAAC,iBAAiB,CAAa,IAAI,IAAI,CAAC;YAExE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAEvB,iEAAiE;YACjE,kFAAkF;YAClF,gGAAgG;YAChG,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC,GAAG,EAAE;gBACpC,IAAI,CAAC,cAAc,EAAE,CAAC;YAC1B,CAAC,EAAE,IAAI,CAAC,CAAC;QAEb,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,QAAQ,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;QACjF,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,cAAc;QAClB,6EAA6E;QAC7E,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACrB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC7B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;QACD,8EAA8E;IAClF,CAAC;IAED;;OAEG;IACI,YAAY;QACf,iCAAiC;QACjC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAEzB,4CAA4C;QAC5C,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACpC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QACjC,CAAC;QAED,+DAA+D;QAC/D,4DAA4D;QAC5D,iFAAiF;QACjF,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,4CAA4C;IACrC,YAAY;QACjB,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACI,aAAa,CAAC,MAAa;QAC9B,oEAAoE;QACpE,IAAI,CAAC,QAAQ,CAAC,mFAAmF,CAAC,CAAC;IACvG,CAAC;IAED,6CAA6C;IACtC,aAAa,CAAC,MAAa;QAChC,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;6GAxKQ,mBAAmB;6DAAnB,mBAAmB;;;;;;YAtNxB,8BAAkF;YAEhF,qFAAiB;YAQjB,gGAAoB;YAkBpB,gGAA+C;YAU/C,2EAA8C;YA+E9C,qFAAkE;YASpE,iBAAM;;YA9H+C,AAA5B,wCAA2B,2BAA6B;YAE/E,cAKC;YALD,wCAKC;YAGD,cAeC;YAfD,2CAeC;YAGD,cAOC;YAPD,8EAOC;YAGD,cA4EC;YA5ED,6EA4EC;YAGD,cAQC;YARD,qGAQC;;;AAyFE,mBAAmB;IA3N/B,aAAa,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;GA2N3C,mBAAmB,CAyK/B;;iFAzKY,mBAAmB;cA1N/B,SAAS;6BACI,KAAK,YACL,gBAAgB,YAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAgIL;;kBAwFJ,SAAS;mBAAC,QAAQ;;kFADV,mBAAmB","sourcesContent":["import { Component, ChangeDetectorRef, ElementRef, ViewChild, AfterViewInit } from '@angular/core';\nimport { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseDashboardPart } from './base-dashboard-part';\nimport { PanelConfig } from '../models/dashboard-types';\n\n/**\n * Runtime renderer for WebURL dashboard parts.\n * Displays web content in an iframe with configurable sandbox permissions.\n */\n@RegisterClass(BaseDashboardPart, 'WebURLPanelRenderer')\n@Component({\n standalone: false,\n selector: 'mj-weburl-part',\n template: `\n <div class=\"weburl-part\" [class.loading]=\"IsLoading\" [class.error]=\"ErrorMessage\">\n <!-- Loading state -->\n @if (IsLoading) {\n <div class=\"loading-state\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n \n <!-- Error state -->\n @if (ErrorMessage) {\n <mj-empty-state\n class=\"part-placeholder\"\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load content\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\">\n @if (rawUrl) {\n <a actions [href]=\"rawUrl\" target=\"_blank\" class=\"open-link\">\n <i class=\"fa-solid fa-up-right-from-square\"></i>\n Open in new window\n </a>\n }\n </mj-empty-state>\n }\n\n <!-- No URL configured -->\n @if (!IsLoading && !ErrorMessage && !SafeUrl) {\n <mj-empty-state\n class=\"part-placeholder\"\n Icon=\"fa-solid fa-globe\"\n Title=\"No URL Configured\"\n Message=\"Click the configure button to set a URL for this part.\"\n Size=\"compact\" />\n }\n \n <!-- Iframe container - sandbox and allowfullscreen must be static, so we use ng-container to switch -->\n @if (!IsLoading && !ErrorMessage && SafeUrl) {\n <!-- Standard sandbox + fullscreen enabled -->\n @if (sandboxMode === 'standard' && allowFullscreen) {\n <iframe\n #iframe\n [src]=\"SafeUrl\"\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups\"\n allowfullscreen\n [title]=\"Panel?.title || 'Embedded content'\"\n (load)=\"onIframeLoad()\"\n (error)=\"onIframeError($event)\"\n class=\"content-iframe\">\n </iframe>\n }\n <!-- Standard sandbox + fullscreen disabled -->\n @if (sandboxMode === 'standard' && !allowFullscreen) {\n <iframe\n #iframe\n [src]=\"SafeUrl\"\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups\"\n [title]=\"Panel?.title || 'Embedded content'\"\n (load)=\"onIframeLoad()\"\n (error)=\"onIframeError($event)\"\n class=\"content-iframe\">\n </iframe>\n }\n <!-- Strict sandbox + fullscreen enabled -->\n @if (sandboxMode === 'strict' && allowFullscreen) {\n <iframe\n #iframe\n [src]=\"SafeUrl\"\n sandbox=\"allow-scripts\"\n allowfullscreen\n [title]=\"Panel?.title || 'Embedded content'\"\n (load)=\"onIframeLoad()\"\n (error)=\"onIframeError($event)\"\n class=\"content-iframe\">\n </iframe>\n }\n <!-- Strict sandbox + fullscreen disabled -->\n @if (sandboxMode === 'strict' && !allowFullscreen) {\n <iframe\n #iframe\n [src]=\"SafeUrl\"\n sandbox=\"allow-scripts\"\n [title]=\"Panel?.title || 'Embedded content'\"\n (load)=\"onIframeLoad()\"\n (error)=\"onIframeError($event)\"\n class=\"content-iframe\">\n </iframe>\n }\n <!-- Permissive sandbox + fullscreen enabled -->\n @if (sandboxMode === 'permissive' && allowFullscreen) {\n <iframe\n #iframe\n [src]=\"SafeUrl\"\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-top-navigation\"\n allowfullscreen\n [title]=\"Panel?.title || 'Embedded content'\"\n (load)=\"onIframeLoad()\"\n (error)=\"onIframeError($event)\"\n class=\"content-iframe\">\n </iframe>\n }\n <!-- Permissive sandbox + fullscreen disabled -->\n @if (sandboxMode === 'permissive' && !allowFullscreen) {\n <iframe\n #iframe\n [src]=\"SafeUrl\"\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-top-navigation\"\n [title]=\"Panel?.title || 'Embedded content'\"\n (load)=\"onIframeLoad()\"\n (error)=\"onIframeError($event)\"\n class=\"content-iframe\">\n </iframe>\n }\n }\n \n <!-- Fallback link shown below iframe if content might be blocked -->\n @if (!IsLoading && !ErrorMessage && SafeUrl && showFallbackLink) {\n <div class=\"iframe-fallback\">\n <span>If the content doesn't load:</span>\n <a [href]=\"rawUrl\" target=\"_blank\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n Open in new window\n </a>\n </div>\n }\n </div>\n `,\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .weburl-part {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n position: relative; /* Required for overlay positioning */\n }\n\n .loading-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--mj-text-secondary);\n text-align: center;\n padding: 24px;\n }\n\n .loading-state i {\n font-size: 48px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n }\n\n .part-placeholder {\n height: 100%;\n }\n\n /* Projected \"open in new window\" link inside the error empty-state */\n .open-link {\n padding: 8px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n text-decoration: none;\n border-radius: 4px;\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n }\n\n .open-link:hover {\n background: var(--mj-brand-primary-hover);\n }\n\n .content-iframe {\n width: 100%;\n height: 100%;\n border: none;\n flex: 1;\n }\n\n .iframe-fallback {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 8px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n font-size: 12px;\n color: var(--mj-text-secondary);\n }\n\n .iframe-fallback a {\n color: var(--mj-brand-primary);\n text-decoration: none;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .iframe-fallback a:hover {\n text-decoration: underline;\n }\n `]\n})\nexport class WebURLPartComponent extends BaseDashboardPart implements AfterViewInit {\n @ViewChild('iframe') IframeRef!: ElementRef<HTMLIFrameElement>;\n\n /** @deprecated Use {@link IframeRef}. */\n get iframeRef(): ElementRef<HTMLIFrameElement> {\n return this.IframeRef;\n }\n /** @deprecated Use {@link IframeRef}. */\n set iframeRef(value: ElementRef<HTMLIFrameElement>) {\n this.IframeRef = value;\n }\n\n public SafeUrl: SafeResourceUrl | null = null;\n public RawUrl: string = '';\n\n /** @deprecated Use {@link RawUrl}. */\n public get rawUrl(): string {\n return this.RawUrl;\n }\n /** @deprecated Use {@link RawUrl}. */\n public set rawUrl(value: string) {\n this.RawUrl = value;\n }\n public SandboxMode: 'standard' | 'strict' | 'permissive' = 'standard';\n\n /** @deprecated Use {@link SandboxMode}. */\n public get sandboxMode(): 'standard' | 'strict' | 'permissive' {\n return this.SandboxMode;\n }\n /** @deprecated Use {@link SandboxMode}. */\n public set sandboxMode(value: 'standard' | 'strict' | 'permissive') {\n this.SandboxMode = value;\n }\n public AllowFullscreen: boolean = true;\n\n /** @deprecated Use {@link AllowFullscreen}. */\n public get allowFullscreen(): boolean {\n return this.AllowFullscreen;\n }\n /** @deprecated Use {@link AllowFullscreen}. */\n public set allowFullscreen(value: boolean) {\n this.AllowFullscreen = value;\n }\n public ShowFallbackLink: boolean = false;\n\n /** @deprecated Use {@link ShowFallbackLink}. */\n public get showFallbackLink(): boolean {\n return this.ShowFallbackLink;\n }\n /** @deprecated Use {@link ShowFallbackLink}. */\n public set showFallbackLink(value: boolean) {\n this.ShowFallbackLink = value;\n } // Hidden by default, shown if content might be blocked\n\n private sanitizer: DomSanitizer;\n private loadCheckTimeout: ReturnType<typeof setTimeout> | null = null;\n private iframeLoaded: boolean = false;\n\n constructor(cdr: ChangeDetectorRef, sanitizer: DomSanitizer) {\n super(cdr);\n this.sanitizer = sanitizer;\n }\n\n ngAfterViewInit(): void {\n // Initial load if panel is already set\n if (this.Panel) {\n this.loadContent();\n }\n }\n\n public async loadContent(): Promise<void> {\n const config = this.getConfig<PanelConfig>();\n const url = config?.['url'] as string | undefined;\n\n // Clear any existing timeout\n if (this.loadCheckTimeout) {\n clearTimeout(this.loadCheckTimeout);\n this.loadCheckTimeout = null;\n }\n\n // Reset state\n this.iframeLoaded = false;\n this.ShowFallbackLink = false;\n\n if (!url) {\n this.SafeUrl = null;\n this.RawUrl = '';\n this.cdr.detectChanges();\n return;\n }\n\n this.setLoading(true);\n\n try {\n // Store raw URL for fallback link\n this.RawUrl = url;\n\n // Sanitize and set URL for iframe src binding\n this.SafeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);\n\n // Set sandbox mode (used by template to select correct iframe)\n this.SandboxMode = (config?.['sandboxMode'] as 'standard' | 'strict' | 'permissive') || 'standard';\n\n // Set fullscreen permission\n this.AllowFullscreen = (config?.['allowFullscreen'] as boolean) ?? true;\n\n this.setLoading(false);\n\n // Set up a delayed check to detect if embedding might be blocked\n // If after 3 seconds the iframe hasn't successfully loaded content we can access,\n // show the blocked overlay. This is a heuristic since we can't detect X-Frame-Options directly.\n this.loadCheckTimeout = setTimeout(() => {\n this.checkIfBlocked();\n }, 3000);\n\n } catch (error) {\n this.setError(error instanceof Error ? error.message : 'Failed to load URL');\n }\n }\n\n /**\n * Check if the iframe content might be blocked.\n * Called after a timeout - if the iframe load event hasn't fired, show the fallback link.\n */\n private checkIfBlocked(): void {\n // If the load event hasn't fired after the timeout, content might be blocked\n if (!this.iframeLoaded) {\n this.ShowFallbackLink = true;\n this.cdr.detectChanges();\n }\n // If iframeLoaded is true, content loaded successfully - keep fallback hidden\n }\n\n /**\n * Handle iframe load event\n */\n public OnIframeLoad(): void {\n // Mark that the load event fired\n this.iframeLoaded = true;\n\n // Clear the timeout since the iframe loaded\n if (this.loadCheckTimeout) {\n clearTimeout(this.loadCheckTimeout);\n this.loadCheckTimeout = null;\n }\n\n // The iframe loaded something - could still be blocked content\n // We can't reliably detect X-Frame-Options blocking from JS\n // The fallback link provides a way for users to open the site if it doesn't load\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link OnIframeLoad}. */\n public onIframeLoad(): void {\n return this.OnIframeLoad();\n }\n\n /**\n * Handle iframe error event\n */\n public OnIframeError(_event: Event): void {\n // This may fire for some load failures, but not for X-Frame-Options\n this.setError('This site cannot be embedded. It may block iframe embedding for security reasons.');\n }\n\n /** @deprecated Use {@link OnIframeError}. */\n public onIframeError(_event: Event): void {\n return this.OnIframeError(_event);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"weburl-part.component.js","sourceRoot":"","sources":["../../../src/lib/parts/weburl-part.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectorRef, ElementRef, ViewChild, AfterViewInit } from '@angular/core';\nimport { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseDashboardPart } from './base-dashboard-part';\nimport { PanelConfig } from '../models/dashboard-types';\n\n/**\n * Runtime renderer for WebURL dashboard parts.\n * Displays web content in an iframe with configurable sandbox permissions.\n */\n@RegisterClass(BaseDashboardPart, 'WebURLPanelRenderer')\n@Component({\n standalone: false,\n selector: 'mj-weburl-part',\n template: `\n <div class=\"weburl-part\" [class.loading]=\"IsLoading\" [class.error]=\"ErrorMessage\">\n <!-- Loading state -->\n @if (IsLoading) {\n <div class=\"loading-state\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n \n <!-- Error state -->\n @if (ErrorMessage) {\n <mj-empty-state\n class=\"part-placeholder\"\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load content\"\n [Message]=\"ErrorMessage\"\n Size=\"compact\">\n @if (rawUrl) {\n <a actions [href]=\"rawUrl\" target=\"_blank\" class=\"open-link\">\n <i class=\"fa-solid fa-up-right-from-square\"></i>\n Open in new window\n </a>\n }\n </mj-empty-state>\n }\n\n <!-- No URL configured -->\n @if (!IsLoading && !ErrorMessage && !SafeUrl) {\n <mj-empty-state\n class=\"part-placeholder\"\n Icon=\"fa-solid fa-globe\"\n Title=\"No URL Configured\"\n Message=\"Use Edit part to set a URL.\"\n Size=\"compact\" />\n }\n \n <!-- Iframe container - sandbox and allowfullscreen must be static, so we use ng-container to switch -->\n @if (!IsLoading && !ErrorMessage && SafeUrl) {\n <!-- Standard sandbox + fullscreen enabled -->\n @if (sandboxMode === 'standard' && allowFullscreen) {\n <iframe\n #iframe\n [src]=\"SafeUrl\"\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups\"\n allowfullscreen\n [title]=\"Panel?.title || 'Embedded content'\"\n (load)=\"onIframeLoad()\"\n (error)=\"onIframeError($event)\"\n class=\"content-iframe\">\n </iframe>\n }\n <!-- Standard sandbox + fullscreen disabled -->\n @if (sandboxMode === 'standard' && !allowFullscreen) {\n <iframe\n #iframe\n [src]=\"SafeUrl\"\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups\"\n [title]=\"Panel?.title || 'Embedded content'\"\n (load)=\"onIframeLoad()\"\n (error)=\"onIframeError($event)\"\n class=\"content-iframe\">\n </iframe>\n }\n <!-- Strict sandbox + fullscreen enabled -->\n @if (sandboxMode === 'strict' && allowFullscreen) {\n <iframe\n #iframe\n [src]=\"SafeUrl\"\n sandbox=\"allow-scripts\"\n allowfullscreen\n [title]=\"Panel?.title || 'Embedded content'\"\n (load)=\"onIframeLoad()\"\n (error)=\"onIframeError($event)\"\n class=\"content-iframe\">\n </iframe>\n }\n <!-- Strict sandbox + fullscreen disabled -->\n @if (sandboxMode === 'strict' && !allowFullscreen) {\n <iframe\n #iframe\n [src]=\"SafeUrl\"\n sandbox=\"allow-scripts\"\n [title]=\"Panel?.title || 'Embedded content'\"\n (load)=\"onIframeLoad()\"\n (error)=\"onIframeError($event)\"\n class=\"content-iframe\">\n </iframe>\n }\n <!-- Permissive sandbox + fullscreen enabled -->\n @if (sandboxMode === 'permissive' && allowFullscreen) {\n <iframe\n #iframe\n [src]=\"SafeUrl\"\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-top-navigation\"\n allowfullscreen\n [title]=\"Panel?.title || 'Embedded content'\"\n (load)=\"onIframeLoad()\"\n (error)=\"onIframeError($event)\"\n class=\"content-iframe\">\n </iframe>\n }\n <!-- Permissive sandbox + fullscreen disabled -->\n @if (sandboxMode === 'permissive' && !allowFullscreen) {\n <iframe\n #iframe\n [src]=\"SafeUrl\"\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-top-navigation\"\n [title]=\"Panel?.title || 'Embedded content'\"\n (load)=\"onIframeLoad()\"\n (error)=\"onIframeError($event)\"\n class=\"content-iframe\">\n </iframe>\n }\n }\n \n <!-- Fallback link shown below iframe if content might be blocked -->\n @if (!IsLoading && !ErrorMessage && SafeUrl && showFallbackLink) {\n <div class=\"iframe-fallback\">\n <span>If the content doesn't load:</span>\n <a [href]=\"rawUrl\" target=\"_blank\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n Open in new window\n </a>\n </div>\n }\n </div>\n `,\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .weburl-part {\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface);\n position: relative; /* Required for overlay positioning */\n }\n\n .loading-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--mj-text-secondary);\n text-align: center;\n padding: 24px;\n }\n\n .loading-state i {\n font-size: 48px;\n color: var(--mj-text-muted);\n margin-bottom: 16px;\n }\n\n .part-placeholder {\n height: 100%;\n }\n\n /* Projected \"open in new window\" link inside the error empty-state */\n .open-link {\n padding: 8px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n text-decoration: none;\n border-radius: 4px;\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n }\n\n .open-link:hover {\n background: var(--mj-brand-primary-hover);\n }\n\n .content-iframe {\n width: 100%;\n height: 100%;\n border: none;\n flex: 1;\n }\n\n .iframe-fallback {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 8px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n font-size: 12px;\n color: var(--mj-text-secondary);\n }\n\n .iframe-fallback a {\n color: var(--mj-brand-primary);\n text-decoration: none;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .iframe-fallback a:hover {\n text-decoration: underline;\n }\n `]\n})\nexport class WebURLPartComponent extends BaseDashboardPart implements AfterViewInit {\n @ViewChild('iframe') IframeRef!: ElementRef<HTMLIFrameElement>;\n\n /** @deprecated Use {@link IframeRef}. */\n get iframeRef(): ElementRef<HTMLIFrameElement> {\n return this.IframeRef;\n }\n /** @deprecated Use {@link IframeRef}. */\n set iframeRef(value: ElementRef<HTMLIFrameElement>) {\n this.IframeRef = value;\n }\n\n public SafeUrl: SafeResourceUrl | null = null;\n public RawUrl: string = '';\n\n /** @deprecated Use {@link RawUrl}. */\n public get rawUrl(): string {\n return this.RawUrl;\n }\n /** @deprecated Use {@link RawUrl}. */\n public set rawUrl(value: string) {\n this.RawUrl = value;\n }\n public SandboxMode: 'standard' | 'strict' | 'permissive' = 'standard';\n\n /** @deprecated Use {@link SandboxMode}. */\n public get sandboxMode(): 'standard' | 'strict' | 'permissive' {\n return this.SandboxMode;\n }\n /** @deprecated Use {@link SandboxMode}. */\n public set sandboxMode(value: 'standard' | 'strict' | 'permissive') {\n this.SandboxMode = value;\n }\n public AllowFullscreen: boolean = true;\n\n /** @deprecated Use {@link AllowFullscreen}. */\n public get allowFullscreen(): boolean {\n return this.AllowFullscreen;\n }\n /** @deprecated Use {@link AllowFullscreen}. */\n public set allowFullscreen(value: boolean) {\n this.AllowFullscreen = value;\n }\n public ShowFallbackLink: boolean = false;\n\n /** @deprecated Use {@link ShowFallbackLink}. */\n public get showFallbackLink(): boolean {\n return this.ShowFallbackLink;\n }\n /** @deprecated Use {@link ShowFallbackLink}. */\n public set showFallbackLink(value: boolean) {\n this.ShowFallbackLink = value;\n } // Hidden by default, shown if content might be blocked\n\n private sanitizer: DomSanitizer;\n private loadCheckTimeout: ReturnType<typeof setTimeout> | null = null;\n private iframeLoaded: boolean = false;\n\n constructor(cdr: ChangeDetectorRef, sanitizer: DomSanitizer) {\n super(cdr);\n this.sanitizer = sanitizer;\n }\n\n ngAfterViewInit(): void {\n // Initial load if panel is already set\n if (this.Panel) {\n this.loadContent();\n }\n }\n\n public async loadContent(): Promise<void> {\n const config = this.getConfig<PanelConfig>();\n const url = config?.['url'] as string | undefined;\n\n // Clear any existing timeout\n if (this.loadCheckTimeout) {\n clearTimeout(this.loadCheckTimeout);\n this.loadCheckTimeout = null;\n }\n\n // Reset state\n this.iframeLoaded = false;\n this.ShowFallbackLink = false;\n\n if (!url) {\n this.SafeUrl = null;\n this.RawUrl = '';\n this.cdr.detectChanges();\n return;\n }\n\n this.setLoading(true);\n\n try {\n // Store raw URL for fallback link\n this.RawUrl = url;\n\n // Sanitize and set URL for iframe src binding\n this.SafeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);\n\n // Set sandbox mode (used by template to select correct iframe)\n this.SandboxMode = (config?.['sandboxMode'] as 'standard' | 'strict' | 'permissive') || 'standard';\n\n // Set fullscreen permission\n this.AllowFullscreen = (config?.['allowFullscreen'] as boolean) ?? true;\n\n this.setLoading(false);\n\n // Set up a delayed check to detect if embedding might be blocked\n // If after 3 seconds the iframe hasn't successfully loaded content we can access,\n // show the blocked overlay. This is a heuristic since we can't detect X-Frame-Options directly.\n this.loadCheckTimeout = setTimeout(() => {\n this.checkIfBlocked();\n }, 3000);\n\n } catch (error) {\n this.setError(error instanceof Error ? error.message : 'Failed to load URL');\n }\n }\n\n /**\n * Check if the iframe content might be blocked.\n * Called after a timeout - if the iframe load event hasn't fired, show the fallback link.\n */\n private checkIfBlocked(): void {\n // If the load event hasn't fired after the timeout, content might be blocked\n if (!this.iframeLoaded) {\n this.ShowFallbackLink = true;\n this.cdr.detectChanges();\n }\n // If iframeLoaded is true, content loaded successfully - keep fallback hidden\n }\n\n /**\n * Handle iframe load event\n */\n public OnIframeLoad(): void {\n // Mark that the load event fired\n this.iframeLoaded = true;\n\n // Clear the timeout since the iframe loaded\n if (this.loadCheckTimeout) {\n clearTimeout(this.loadCheckTimeout);\n this.loadCheckTimeout = null;\n }\n\n // The iframe loaded something - could still be blocked content\n // We can't reliably detect X-Frame-Options blocking from JS\n // The fallback link provides a way for users to open the site if it doesn't load\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link OnIframeLoad}. */\n public onIframeLoad(): void {\n return this.OnIframeLoad();\n }\n\n /**\n * Handle iframe error event\n */\n public OnIframeError(_event: Event): void {\n // This may fire for some load failures, but not for X-Frame-Options\n this.setError('This site cannot be embedded. It may block iframe embedding for security reasons.');\n }\n\n /** @deprecated Use {@link OnIframeError}. */\n public onIframeError(_event: Event): void {\n return this.OnIframeError(_event);\n }\n}\n"]}
|
|
@@ -16,6 +16,17 @@ export interface LayoutLocation {
|
|
|
16
16
|
* Receives the full DashboardPanel from GL's componentState (single source of truth).
|
|
17
17
|
*/
|
|
18
18
|
export type PanelComponentFactory = (panel: DashboardPanel, container: HTMLElement) => void;
|
|
19
|
+
/** What a part button in a stack header asks for. */
|
|
20
|
+
export type StackAction = 'edit' | 'remove';
|
|
21
|
+
/** A click on a stack header's part button: the action, and the panel in the stack's active tab. */
|
|
22
|
+
export interface StackActionEvent {
|
|
23
|
+
Action: StackAction;
|
|
24
|
+
PanelId: string;
|
|
25
|
+
}
|
|
26
|
+
/** The height of a stack header (part tabs and part buttons), in pixels. The viewer CSS uses the same value. */
|
|
27
|
+
export declare const DASHBOARD_STACK_HEADER_HEIGHT = 44;
|
|
28
|
+
/** Room Golden Layout keeps beside a stack's tabs, in pixels: the tab track's inset, borders and padding, the tab dropdown button with its gaps, and the controls' inset. The viewer CSS uses the same values. */
|
|
29
|
+
export declare const DASHBOARD_TAB_CONTROL_OFFSET = 78;
|
|
19
30
|
/**
|
|
20
31
|
* Service that wraps Golden Layout for Angular integration.
|
|
21
32
|
* Uses Golden Layout 2.6.0 VirtualLayout API.
|
|
@@ -65,6 +76,8 @@ export declare class GoldenLayoutWrapperService {
|
|
|
65
76
|
get onPanelSelected(): Subject<string>;
|
|
66
77
|
/** @deprecated Use {@link OnPanelSelected}. */
|
|
67
78
|
set onPanelSelected(value: Subject<string>);
|
|
79
|
+
/** Emitted when the user clicks Edit part or Remove in a stack header. Edit mode only. */
|
|
80
|
+
OnStackAction: Subject<StackActionEvent>;
|
|
68
81
|
/** Current panels in layout */
|
|
69
82
|
Panels$: BehaviorSubject<string[]>;
|
|
70
83
|
/** @deprecated Use {@link Panels$}. */
|
|
@@ -104,6 +117,12 @@ export declare class GoldenLayoutWrapperService {
|
|
|
104
117
|
* Update layout size to match container.
|
|
105
118
|
*/
|
|
106
119
|
UpdateSize(): void;
|
|
120
|
+
/**
|
|
121
|
+
* The container's layout size (offsetWidth / offsetHeight). Golden Layout lays out in this size
|
|
122
|
+
* and reads it itself when it resizes with the container. It differs from the on-screen size
|
|
123
|
+
* (getBoundingClientRect) when a host scales the viewer, for example with a CSS transform.
|
|
124
|
+
*/
|
|
125
|
+
private containerLayoutSize;
|
|
107
126
|
/** @deprecated Use {@link UpdateSize}. */
|
|
108
127
|
updateSize(): void;
|
|
109
128
|
/**
|
|
@@ -115,6 +134,27 @@ export declare class GoldenLayoutWrapperService {
|
|
|
115
134
|
* Unbind component event listener (called by Golden Layout VirtualLayout)
|
|
116
135
|
*/
|
|
117
136
|
private unbindComponentEventListener;
|
|
137
|
+
/**
|
|
138
|
+
* Wires each stack Golden Layout creates: on load, on add, and when a dragged tab makes a new stack.
|
|
139
|
+
* Every stack gets tab list ARIA; in edit mode it also gets the part buttons.
|
|
140
|
+
*/
|
|
141
|
+
private onItemCreated;
|
|
142
|
+
/**
|
|
143
|
+
* Marks the stack header's tab list as a tablist, and the tab dropdown list too (Golden Layout moves the
|
|
144
|
+
* tabs that do not fit there). Keeps aria-selected on each tab in step with the stack's active tab.
|
|
145
|
+
*/
|
|
146
|
+
private addTabListAria;
|
|
147
|
+
/** Adds Edit part and Remove to the stack header. They act on the stack's active tab at click time. */
|
|
148
|
+
private addStackActions;
|
|
149
|
+
/** Emits the action for the panel in the stack's active tab. Does nothing when the active tab has no panel. */
|
|
150
|
+
private emitStackAction;
|
|
151
|
+
/** The ID of the panel bound to a component container, or null. */
|
|
152
|
+
private panelIdOf;
|
|
153
|
+
/**
|
|
154
|
+
* Allows tab dragging only in edit mode (a saved part's own reorderEnabled would allow it in view mode),
|
|
155
|
+
* and makes the tab reachable from the keyboard.
|
|
156
|
+
*/
|
|
157
|
+
private onTabCreated;
|
|
118
158
|
/**
|
|
119
159
|
* Check if Golden Layout is initialized
|
|
120
160
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"golden-layout-wrapper.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/golden-layout-wrapper.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAChD,OAAO,EAEH,oBAAoB,
|
|
1
|
+
{"version":3,"file":"golden-layout-wrapper.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/golden-layout-wrapper.service.ts"],"names":[],"mappings":"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"}
|