@memberjunction/ng-dashboards 5.28.0 → 5.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
  2. package/dist/AI/components/agents/agent-configuration.component.js +11 -9
  3. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  4. package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
  5. package/dist/AI/components/agents/agent-editor.component.js +21 -19
  6. package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
  7. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +154 -154
  8. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  9. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  10. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +8 -0
  11. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  12. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +1 -1
  13. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  14. package/dist/AI/components/vectors/vector-management-resource.component.js +2 -2
  15. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  16. package/dist/APIKeys/api-applications-panel.component.d.ts +1 -1
  17. package/dist/APIKeys/api-applications-panel.component.d.ts.map +1 -1
  18. package/dist/APIKeys/api-applications-panel.component.js +15 -2
  19. package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
  20. package/dist/APIKeys/api-key-edit-panel.component.d.ts.map +1 -1
  21. package/dist/APIKeys/api-key-edit-panel.component.js +17 -5
  22. package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
  23. package/dist/Archiving/components/archive-config-resource.component.d.ts +20 -0
  24. package/dist/Archiving/components/archive-config-resource.component.d.ts.map +1 -0
  25. package/dist/Archiving/components/archive-config-resource.component.js +46 -0
  26. package/dist/Archiving/components/archive-config-resource.component.js.map +1 -0
  27. package/dist/Archiving/components/archive-runs-resource.component.d.ts +20 -0
  28. package/dist/Archiving/components/archive-runs-resource.component.d.ts.map +1 -0
  29. package/dist/Archiving/components/archive-runs-resource.component.js +46 -0
  30. package/dist/Archiving/components/archive-runs-resource.component.js.map +1 -0
  31. package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
  32. package/dist/Credentials/components/credentials-list-resource.component.js +56 -71
  33. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  34. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +0 -8
  35. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
  36. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +73 -74
  37. package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
  38. package/dist/DashboardBrowser/dashboard-share-adapter.d.ts +25 -0
  39. package/dist/DashboardBrowser/dashboard-share-adapter.d.ts.map +1 -0
  40. package/dist/DashboardBrowser/dashboard-share-adapter.js +99 -0
  41. package/dist/DashboardBrowser/dashboard-share-adapter.js.map +1 -0
  42. package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts +21 -104
  43. package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts.map +1 -1
  44. package/dist/DashboardBrowser/dashboard-share-dialog.component.js +48 -530
  45. package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
  46. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +5 -0
  47. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  48. package/dist/DataExplorer/data-explorer-dashboard.component.js +17 -0
  49. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  50. package/dist/Integration/components/connections/connections.component.d.ts +18 -1
  51. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
  52. package/dist/Integration/components/connections/connections.component.js +251 -199
  53. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  54. package/dist/Integration/services/integration-data.service.d.ts +7 -2
  55. package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
  56. package/dist/Integration/services/integration-data.service.js +10 -2
  57. package/dist/Integration/services/integration-data.service.js.map +1 -1
  58. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +144 -144
  59. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
  60. package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
  61. package/dist/Lists/components/lists-operations-resource.component.js +12 -14
  62. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  63. package/dist/MCP/components/mcp-connection-dialog.component.js +1 -1
  64. package/dist/MCP/components/mcp-connection-dialog.component.js.map +1 -1
  65. package/dist/MCP/mcp-dashboard.component.d.ts +170 -0
  66. package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
  67. package/dist/MCP/mcp-dashboard.component.js +2521 -758
  68. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  69. package/dist/MCP/mcp-filter-panel.component.d.ts +16 -1
  70. package/dist/MCP/mcp-filter-panel.component.d.ts.map +1 -1
  71. package/dist/MCP/mcp-filter-panel.component.js +187 -60
  72. package/dist/MCP/mcp-filter-panel.component.js.map +1 -1
  73. package/dist/MCP/mcp-resource.component.d.ts +0 -9
  74. package/dist/MCP/mcp-resource.component.d.ts.map +1 -1
  75. package/dist/MCP/mcp-resource.component.js +1 -10
  76. package/dist/MCP/mcp-resource.component.js.map +1 -1
  77. package/dist/MCP/mcp.module.d.ts +7 -6
  78. package/dist/MCP/mcp.module.d.ts.map +1 -1
  79. package/dist/MCP/mcp.module.js +4 -8
  80. package/dist/MCP/mcp.module.js.map +1 -1
  81. package/dist/Permissions/audit-log-resource.component.d.ts +38 -0
  82. package/dist/Permissions/audit-log-resource.component.d.ts.map +1 -0
  83. package/dist/Permissions/audit-log-resource.component.js +380 -0
  84. package/dist/Permissions/audit-log-resource.component.js.map +1 -0
  85. package/dist/Permissions/permissions-shared.d.ts +51 -0
  86. package/dist/Permissions/permissions-shared.d.ts.map +1 -0
  87. package/dist/Permissions/permissions-shared.js +91 -0
  88. package/dist/Permissions/permissions-shared.js.map +1 -0
  89. package/dist/Permissions/resource-access-resource.component.d.ts +45 -0
  90. package/dist/Permissions/resource-access-resource.component.d.ts.map +1 -0
  91. package/dist/Permissions/resource-access-resource.component.js +342 -0
  92. package/dist/Permissions/resource-access-resource.component.js.map +1 -0
  93. package/dist/Permissions/user-access-resource.component.d.ts +39 -0
  94. package/dist/Permissions/user-access-resource.component.d.ts.map +1 -0
  95. package/dist/Permissions/user-access-resource.component.js +346 -0
  96. package/dist/Permissions/user-access-resource.component.js.map +1 -0
  97. package/dist/QueryBrowser/query-browser-resource.component.d.ts +13 -3
  98. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  99. package/dist/QueryBrowser/query-browser-resource.component.js +186 -139
  100. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  101. package/dist/archiving-dashboards.module.d.ts +19 -0
  102. package/dist/archiving-dashboards.module.d.ts.map +1 -0
  103. package/dist/archiving-dashboards.module.js +52 -0
  104. package/dist/archiving-dashboards.module.js.map +1 -0
  105. package/dist/component-studio-dashboards.module.d.ts +1 -0
  106. package/dist/component-studio-dashboards.module.d.ts.map +1 -1
  107. package/dist/component-studio-dashboards.module.js +7 -0
  108. package/dist/component-studio-dashboards.module.js.map +1 -1
  109. package/dist/core-dashboards.module.d.ts +24 -19
  110. package/dist/core-dashboards.module.d.ts.map +1 -1
  111. package/dist/core-dashboards.module.js +30 -1
  112. package/dist/core-dashboards.module.js.map +1 -1
  113. package/dist/module.d.ts +13 -12
  114. package/dist/module.d.ts.map +1 -1
  115. package/dist/module.js +7 -0
  116. package/dist/module.js.map +1 -1
  117. package/dist/public-api.d.ts +7 -1
  118. package/dist/public-api.d.ts.map +1 -1
  119. package/dist/public-api.js +8 -0
  120. package/dist/public-api.js.map +1 -1
  121. package/dist/shared/pipes/highlight-search.pipe.d.ts +1 -1
  122. package/dist/shared/pipes/highlight-search.pipe.d.ts.map +1 -1
  123. package/dist/shared/pipes/highlight-search.pipe.js +14 -4
  124. package/dist/shared/pipes/highlight-search.pipe.js.map +1 -1
  125. package/package.json +52 -48
@@ -8,14 +8,15 @@ import * as i6 from "./components/mcp-test-tool-dialog.component";
8
8
  import * as i7 from "./components/mcp-log-detail-panel.component";
9
9
  import * as i8 from "@angular/common";
10
10
  import * as i9 from "@angular/forms";
11
- import * as i10 from "@memberjunction/ng-ui-components";
12
- import * as i11 from "@memberjunction/ng-shared-generic";
13
- import * as i12 from "@memberjunction/ng-credentials";
14
- import * as i13 from "@memberjunction/ng-code-editor";
15
- import * as i14 from "../shared/shared-pipes.module";
11
+ import * as i10 from "@angular/cdk/scrolling";
12
+ import * as i11 from "@memberjunction/ng-ui-components";
13
+ import * as i12 from "@memberjunction/ng-shared-generic";
14
+ import * as i13 from "@memberjunction/ng-credentials";
15
+ import * as i14 from "@memberjunction/ng-code-editor";
16
+ import * as i15 from "../shared/shared-pipes.module";
16
17
  export declare class MCPModule {
17
18
  static ɵfac: i0.ɵɵFactoryDeclaration<MCPModule, never>;
18
- static ɵmod: i0.ɵɵNgModuleDeclaration<MCPModule, [typeof i1.MCPDashboardComponent, typeof i2.MCPResourceComponent, typeof i3.MCPFilterPanelComponent, typeof i4.MCPServerDialogComponent, typeof i5.MCPConnectionDialogComponent, typeof i6.MCPTestToolDialogComponent, typeof i7.MCPLogDetailPanelComponent], [typeof i8.CommonModule, typeof i9.FormsModule, typeof i9.ReactiveFormsModule, typeof i10.MJButtonDirective, typeof i10.MJDialogComponent, typeof i10.MJDialogActionsComponent, typeof i10.MJDropdownComponent, typeof i10.MJNumericInputComponent, typeof i11.SharedGenericModule, typeof i12.CredentialsModule, typeof i13.CodeEditorModule, typeof i14.SharedPipesModule], [typeof i1.MCPDashboardComponent, typeof i2.MCPResourceComponent, typeof i3.MCPFilterPanelComponent, typeof i4.MCPServerDialogComponent, typeof i5.MCPConnectionDialogComponent, typeof i6.MCPTestToolDialogComponent, typeof i7.MCPLogDetailPanelComponent]>;
19
+ static ɵmod: i0.ɵɵNgModuleDeclaration<MCPModule, [typeof i1.MCPDashboardComponent, typeof i2.MCPResourceComponent, typeof i3.MCPFilterPanelComponent, typeof i4.MCPServerDialogComponent, typeof i5.MCPConnectionDialogComponent, typeof i6.MCPTestToolDialogComponent, typeof i7.MCPLogDetailPanelComponent], [typeof i8.CommonModule, typeof i9.FormsModule, typeof i9.ReactiveFormsModule, typeof i10.ScrollingModule, typeof i11.MJButtonDirective, typeof i11.MJDialogComponent, typeof i11.MJDialogActionsComponent, typeof i11.MJDropdownComponent, typeof i11.MJNumericInputComponent, typeof i12.SharedGenericModule, typeof i13.CredentialsModule, typeof i14.CodeEditorModule, typeof i15.SharedPipesModule], [typeof i1.MCPDashboardComponent, typeof i2.MCPResourceComponent, typeof i3.MCPFilterPanelComponent, typeof i4.MCPServerDialogComponent, typeof i5.MCPConnectionDialogComponent, typeof i6.MCPTestToolDialogComponent, typeof i7.MCPLogDetailPanelComponent]>;
19
20
  static ɵinj: i0.ɵɵInjectorDeclaration<MCPModule>;
20
21
  }
21
22
  //# sourceMappingURL=mcp.module.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.module.d.ts","sourceRoot":"","sources":["../../src/MCP/mcp.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAqCA,qBAkCa,SAAS;yCAAT,SAAS;0CAAT,SAAS;0CAAT,SAAS;CAAI"}
1
+ {"version":3,"file":"mcp.module.d.ts","sourceRoot":"","sources":["../../src/MCP/mcp.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAsCA,qBAmCa,SAAS;yCAAT,SAAS;0CAAT,SAAS;0CAAT,SAAS;CAAI"}
@@ -7,6 +7,7 @@
7
7
  import { NgModule } from '@angular/core';
8
8
  import { CommonModule } from '@angular/common';
9
9
  import { FormsModule, ReactiveFormsModule } from '@angular/forms';
10
+ import { ScrollingModule } from '@angular/cdk/scrolling';
10
11
  // MJ UI Components
11
12
  import { MJButtonDirective, MJDialogComponent, MJDialogActionsComponent, MJDropdownComponent, MJNumericInputComponent } from '@memberjunction/ng-ui-components';
12
13
  // MemberJunction Modules
@@ -24,15 +25,13 @@ import { MCPConnectionDialogComponent } from './components/mcp-connection-dialog
24
25
  import { MCPTestToolDialogComponent } from './components/mcp-test-tool-dialog.component';
25
26
  import { MCPLogDetailPanelComponent } from './components/mcp-log-detail-panel.component';
26
27
  import * as i0 from "@angular/core";
27
- import * as i1 from "@angular/common";
28
- import * as i2 from "@memberjunction/ng-shared-generic";
29
- import * as i3 from "../shared/pipes/highlight-search.pipe";
30
28
  export class MCPModule {
31
29
  static ɵfac = function MCPModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MCPModule)(); };
32
30
  static ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: MCPModule });
33
31
  static ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [CommonModule,
34
32
  FormsModule,
35
33
  ReactiveFormsModule,
34
+ ScrollingModule,
36
35
  MJDialogComponent,
37
36
  MJDialogActionsComponent,
38
37
  MJDropdownComponent,
@@ -58,6 +57,7 @@ export class MCPModule {
58
57
  CommonModule,
59
58
  FormsModule,
60
59
  ReactiveFormsModule,
60
+ ScrollingModule,
61
61
  MJButtonDirective,
62
62
  MJDialogComponent,
63
63
  MJDialogActionsComponent,
@@ -88,6 +88,7 @@ export class MCPModule {
88
88
  MCPLogDetailPanelComponent], imports: [CommonModule,
89
89
  FormsModule,
90
90
  ReactiveFormsModule,
91
+ ScrollingModule,
91
92
  MJButtonDirective,
92
93
  MJDialogComponent,
93
94
  MJDialogActionsComponent,
@@ -103,9 +104,4 @@ export class MCPModule {
103
104
  MCPConnectionDialogComponent,
104
105
  MCPTestToolDialogComponent,
105
106
  MCPLogDetailPanelComponent] }); })();
106
- i0.ɵɵsetComponentScope(MCPDashboardComponent, [i1.NgClass, MJButtonDirective, i2.LoadingComponent, MCPFilterPanelComponent,
107
- MCPServerDialogComponent,
108
- MCPConnectionDialogComponent,
109
- MCPTestToolDialogComponent,
110
- MCPLogDetailPanelComponent], [i1.AsyncPipe, i3.HighlightSearchPipe]);
111
107
  //# sourceMappingURL=mcp.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.module.js","sourceRoot":"","sources":["../../src/MCP/mcp.module.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAElE,mBAAmB;AACnB,OAAO,EACH,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,EACnB,uBAAuB,EAC1B,MAAM,kCAAkC,CAAC;AAE1C,yBAAyB;AACzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAElE,sBAAsB;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,iBAAiB;AACjB,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,EAAE,4BAA4B,EAAE,MAAM,8CAA8C,CAAC;AAC5F,OAAO,EAAE,0BAA0B,EAAE,MAAM,6CAA6C,CAAC;AACzF,OAAO,EAAE,0BAA0B,EAAE,MAAM,6CAA6C,CAAC;;;;;AAoCzF,MAAM,OAAO,SAAS;mGAAT,SAAS;4DAAT,SAAS;gEAvBd,YAAY;YACZ,WAAW;YACX,mBAAmB;YAEnB,iBAAiB;YACjB,wBAAwB;YACxB,mBAAmB;YACnB,uBAAuB;YACvB,mBAAmB;YACnB,iBAAiB;YACjB,gBAAgB;YAChB,iBAAiB;;iFAYZ,SAAS;cAlCrB,QAAQ;eAAC;gBACN,YAAY,EAAE;oBACV,qBAAqB;oBACrB,oBAAoB;oBACpB,uBAAuB;oBACvB,wBAAwB;oBACxB,4BAA4B;oBAC5B,0BAA0B;oBAC1B,0BAA0B;iBAC7B;gBACD,OAAO,EAAE;oBACL,YAAY;oBACZ,WAAW;oBACX,mBAAmB;oBACnB,iBAAiB;oBACjB,iBAAiB;oBACjB,wBAAwB;oBACxB,mBAAmB;oBACnB,uBAAuB;oBACvB,mBAAmB;oBACnB,iBAAiB;oBACjB,gBAAgB;oBAChB,iBAAiB;iBACpB;gBACD,OAAO,EAAE;oBACL,qBAAqB;oBACrB,oBAAoB;oBACpB,uBAAuB;oBACvB,wBAAwB;oBACxB,4BAA4B;oBAC5B,0BAA0B;oBAC1B,0BAA0B;iBAC7B;aACJ;;wFACY,SAAS,mBAhCd,qBAAqB;QACrB,oBAAoB;QACpB,uBAAuB;QACvB,wBAAwB;QACxB,4BAA4B;QAC5B,0BAA0B;QAC1B,0BAA0B,aAG1B,YAAY;QACZ,WAAW;QACX,mBAAmB;QACnB,iBAAiB;QACjB,iBAAiB;QACjB,wBAAwB;QACxB,mBAAmB;QACnB,uBAAuB;QACvB,mBAAmB;QACnB,iBAAiB;QACjB,gBAAgB;QAChB,iBAAiB,aAGjB,qBAAqB;QACrB,oBAAoB;QACpB,uBAAuB;QACvB,wBAAwB;QACxB,4BAA4B;QAC5B,0BAA0B;QAC1B,0BAA0B;uBA7B1B,qBAAqB,eAYrB,iBAAiB,uBAVjB,uBAAuB;IACvB,wBAAwB;IACxB,4BAA4B;IAC5B,0BAA0B;IAC1B,0BAA0B","sourcesContent":["/**\n * @fileoverview MCP Management Module\n *\n * Angular module for MCP (Model Context Protocol) server management.\n * Provides components for managing servers, connections, tools, and viewing logs.\n */\n\nimport { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\n\n// MJ UI Components\nimport {\n MJButtonDirective,\n MJDialogComponent,\n MJDialogActionsComponent,\n MJDropdownComponent,\n MJNumericInputComponent\n} from '@memberjunction/ng-ui-components';\n\n// MemberJunction Modules\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { CredentialsModule } from '@memberjunction/ng-credentials';\nimport { CodeEditorModule } from '@memberjunction/ng-code-editor';\n\n// Shared Pipes Module\nimport { SharedPipesModule } from '../shared/shared-pipes.module';\n\n// MCP Components\nimport { MCPDashboardComponent } from './mcp-dashboard.component';\nimport { MCPResourceComponent } from './mcp-resource.component';\nimport { MCPFilterPanelComponent } from './mcp-filter-panel.component';\nimport { MCPServerDialogComponent } from './components/mcp-server-dialog.component';\nimport { MCPConnectionDialogComponent } from './components/mcp-connection-dialog.component';\nimport { MCPTestToolDialogComponent } from './components/mcp-test-tool-dialog.component';\nimport { MCPLogDetailPanelComponent } from './components/mcp-log-detail-panel.component';\n\n@NgModule({\n declarations: [\n MCPDashboardComponent,\n MCPResourceComponent,\n MCPFilterPanelComponent,\n MCPServerDialogComponent,\n MCPConnectionDialogComponent,\n MCPTestToolDialogComponent,\n MCPLogDetailPanelComponent\n ],\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n MJButtonDirective,\n MJDialogComponent,\n MJDialogActionsComponent,\n MJDropdownComponent,\n MJNumericInputComponent,\n SharedGenericModule,\n CredentialsModule,\n CodeEditorModule,\n SharedPipesModule\n ],\n exports: [\n MCPDashboardComponent,\n MCPResourceComponent,\n MCPFilterPanelComponent,\n MCPServerDialogComponent,\n MCPConnectionDialogComponent,\n MCPTestToolDialogComponent,\n MCPLogDetailPanelComponent\n ]\n})\nexport class MCPModule { }\n"]}
1
+ {"version":3,"file":"mcp.module.js","sourceRoot":"","sources":["../../src/MCP/mcp.module.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,mBAAmB;AACnB,OAAO,EACH,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,EACnB,uBAAuB,EAC1B,MAAM,kCAAkC,CAAC;AAE1C,yBAAyB;AACzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAElE,sBAAsB;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,iBAAiB;AACjB,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,EAAE,4BAA4B,EAAE,MAAM,8CAA8C,CAAC;AAC5F,OAAO,EAAE,0BAA0B,EAAE,MAAM,6CAA6C,CAAC;AACzF,OAAO,EAAE,0BAA0B,EAAE,MAAM,6CAA6C,CAAC;;AAqCzF,MAAM,OAAO,SAAS;mGAAT,SAAS;4DAAT,SAAS;gEAxBd,YAAY;YACZ,WAAW;YACX,mBAAmB;YACnB,eAAe;YAEf,iBAAiB;YACjB,wBAAwB;YACxB,mBAAmB;YACnB,uBAAuB;YACvB,mBAAmB;YACnB,iBAAiB;YACjB,gBAAgB;YAChB,iBAAiB;;iFAYZ,SAAS;cAnCrB,QAAQ;eAAC;gBACN,YAAY,EAAE;oBACV,qBAAqB;oBACrB,oBAAoB;oBACpB,uBAAuB;oBACvB,wBAAwB;oBACxB,4BAA4B;oBAC5B,0BAA0B;oBAC1B,0BAA0B;iBAC7B;gBACD,OAAO,EAAE;oBACL,YAAY;oBACZ,WAAW;oBACX,mBAAmB;oBACnB,eAAe;oBACf,iBAAiB;oBACjB,iBAAiB;oBACjB,wBAAwB;oBACxB,mBAAmB;oBACnB,uBAAuB;oBACvB,mBAAmB;oBACnB,iBAAiB;oBACjB,gBAAgB;oBAChB,iBAAiB;iBACpB;gBACD,OAAO,EAAE;oBACL,qBAAqB;oBACrB,oBAAoB;oBACpB,uBAAuB;oBACvB,wBAAwB;oBACxB,4BAA4B;oBAC5B,0BAA0B;oBAC1B,0BAA0B;iBAC7B;aACJ;;wFACY,SAAS,mBAjCd,qBAAqB;QACrB,oBAAoB;QACpB,uBAAuB;QACvB,wBAAwB;QACxB,4BAA4B;QAC5B,0BAA0B;QAC1B,0BAA0B,aAG1B,YAAY;QACZ,WAAW;QACX,mBAAmB;QACnB,eAAe;QACf,iBAAiB;QACjB,iBAAiB;QACjB,wBAAwB;QACxB,mBAAmB;QACnB,uBAAuB;QACvB,mBAAmB;QACnB,iBAAiB;QACjB,gBAAgB;QAChB,iBAAiB,aAGjB,qBAAqB;QACrB,oBAAoB;QACpB,uBAAuB;QACvB,wBAAwB;QACxB,4BAA4B;QAC5B,0BAA0B;QAC1B,0BAA0B","sourcesContent":["/**\n * @fileoverview MCP Management Module\n *\n * Angular module for MCP (Model Context Protocol) server management.\n * Provides components for managing servers, connections, tools, and viewing logs.\n */\n\nimport { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { ScrollingModule } from '@angular/cdk/scrolling';\n\n// MJ UI Components\nimport {\n MJButtonDirective,\n MJDialogComponent,\n MJDialogActionsComponent,\n MJDropdownComponent,\n MJNumericInputComponent\n} from '@memberjunction/ng-ui-components';\n\n// MemberJunction Modules\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\nimport { CredentialsModule } from '@memberjunction/ng-credentials';\nimport { CodeEditorModule } from '@memberjunction/ng-code-editor';\n\n// Shared Pipes Module\nimport { SharedPipesModule } from '../shared/shared-pipes.module';\n\n// MCP Components\nimport { MCPDashboardComponent } from './mcp-dashboard.component';\nimport { MCPResourceComponent } from './mcp-resource.component';\nimport { MCPFilterPanelComponent } from './mcp-filter-panel.component';\nimport { MCPServerDialogComponent } from './components/mcp-server-dialog.component';\nimport { MCPConnectionDialogComponent } from './components/mcp-connection-dialog.component';\nimport { MCPTestToolDialogComponent } from './components/mcp-test-tool-dialog.component';\nimport { MCPLogDetailPanelComponent } from './components/mcp-log-detail-panel.component';\n\n@NgModule({\n declarations: [\n MCPDashboardComponent,\n MCPResourceComponent,\n MCPFilterPanelComponent,\n MCPServerDialogComponent,\n MCPConnectionDialogComponent,\n MCPTestToolDialogComponent,\n MCPLogDetailPanelComponent\n ],\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n ScrollingModule,\n MJButtonDirective,\n MJDialogComponent,\n MJDialogActionsComponent,\n MJDropdownComponent,\n MJNumericInputComponent,\n SharedGenericModule,\n CredentialsModule,\n CodeEditorModule,\n SharedPipesModule\n ],\n exports: [\n MCPDashboardComponent,\n MCPResourceComponent,\n MCPFilterPanelComponent,\n MCPServerDialogComponent,\n MCPConnectionDialogComponent,\n MCPTestToolDialogComponent,\n MCPLogDetailPanelComponent\n ]\n})\nexport class MCPModule { }\n"]}
@@ -0,0 +1,38 @@
1
+ import { ChangeDetectorRef, OnDestroy, OnInit } from '@angular/core';
2
+ import { PermissionAuditEntry } from '@memberjunction/core';
3
+ import { MJPermissionDomainEntity, ResourceData } from '@memberjunction/core-entities';
4
+ import { BaseResourceComponent } from '@memberjunction/ng-shared';
5
+ import { PermissionsUserOption } from './permissions-shared';
6
+ import * as i0 from "@angular/core";
7
+ /**
8
+ * Audit Log resource — one of three tabs in the Permissions admin application.
9
+ * Chronological log of Create / Update / Delete events against any permission
10
+ * record across every registered domain. Powered by `PermissionEngine.GetAuditTimeline`.
11
+ */
12
+ export declare class PermissionsAuditLogResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {
13
+ private cdr;
14
+ Domains: MJPermissionDomainEntity[];
15
+ Users: PermissionsUserOption[];
16
+ DomainFilter: string | '';
17
+ UserFilter: string | '';
18
+ StartDate: string;
19
+ EndDate: string;
20
+ Entries: PermissionAuditEntry[];
21
+ IsLoading: boolean;
22
+ HasRunQuery: boolean;
23
+ ErrorMessage: string | null;
24
+ constructor(cdr: ChangeDetectorRef);
25
+ GetResourceDisplayName(_data: ResourceData): Promise<string>;
26
+ GetResourceIconClass(_data: ResourceData): Promise<string>;
27
+ ngOnInit(): Promise<void>;
28
+ ngOnDestroy(): void;
29
+ OnRunQuery(): Promise<void>;
30
+ OnResetFilters(): void;
31
+ TrackByAuditEntry(_index: number, entry: PermissionAuditEntry): string;
32
+ ChangeIcon(type: PermissionAuditEntry['ChangeType']): string;
33
+ static ɵfac: i0.ɵɵFactoryDeclaration<PermissionsAuditLogResourceComponent, never>;
34
+ static ɵcmp: i0.ɵɵComponentDeclaration<PermissionsAuditLogResourceComponent, "mj-permissions-audit-log-resource", never, {}, {}, never, never, false, never>;
35
+ }
36
+ /** Tree-shaking prevention — referenced from `public-api.ts`. */
37
+ export declare function LoadPermissionsAuditLogResource(): void;
38
+ //# sourceMappingURL=audit-log-resource.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-log-resource.component.d.ts","sourceRoot":"","sources":["../../src/Permissions/audit-log-resource.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAa,SAAS,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAoB,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAEzG,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,EAAE,qBAAqB,EAAwB,MAAM,sBAAsB,CAAC;;AAEnF;;;;GAIG;AACH,qBAOa,oCAAqC,SAAQ,qBAAsB,YAAW,MAAM,EAAE,SAAS;IAa5F,OAAO,CAAC,GAAG;IAZvB,OAAO,EAAE,wBAAwB,EAAE,CAAM;IACzC,KAAK,EAAE,qBAAqB,EAAE,CAAM;IAEpC,YAAY,EAAE,MAAM,GAAG,EAAE,CAAM;IAC/B,UAAU,EAAE,MAAM,GAAG,EAAE,CAAM;IAC7B,SAAS,EAAE,MAAM,CAAM;IACvB,OAAO,EAAE,MAAM,CAAM;IACrB,OAAO,EAAE,oBAAoB,EAAE,CAAM;IACrC,SAAS,UAAS;IAClB,WAAW,UAAS;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;gBAEf,GAAG,EAAE,iBAAiB;IAI3B,sBAAsB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI5D,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI1D,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAW/B,WAAW,IAAI,IAAI;IAItB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BjC,cAAc,IAAI,IAAI;IAUtB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,GAAG,MAAM;IAItE,UAAU,CAAC,IAAI,EAAE,oBAAoB,CAAC,YAAY,CAAC,GAAG,MAAM;yCApFnD,oCAAoC;2CAApC,oCAAoC;CAkGhD;AAED,iEAAiE;AACjE,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD"}
@@ -0,0 +1,380 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Component } from '@angular/core';
8
+ import { PermissionEngine } from '@memberjunction/core-entities';
9
+ import { RegisterClass } from '@memberjunction/global';
10
+ import { BaseResourceComponent } from '@memberjunction/ng-shared';
11
+ import { loadPermissionsUsers } from './permissions-shared';
12
+ import * as i0 from "@angular/core";
13
+ import * as i1 from "@angular/forms";
14
+ import * as i2 from "@memberjunction/ng-ui-components";
15
+ import * as i3 from "@memberjunction/ng-shared-generic";
16
+ import * as i4 from "@angular/common";
17
+ const _forTrack0 = ($index, $item) => $item.ID;
18
+ function PermissionsAuditLogResourceComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
19
+ i0.ɵɵelementStart(0, "div", 6);
20
+ i0.ɵɵelement(1, "i", 22);
21
+ i0.ɵɵelementStart(2, "span");
22
+ i0.ɵɵtext(3);
23
+ i0.ɵɵelementEnd()();
24
+ } if (rf & 2) {
25
+ const ctx_r0 = i0.ɵɵnextContext();
26
+ i0.ɵɵadvance(3);
27
+ i0.ɵɵtextInterpolate(ctx_r0.ErrorMessage);
28
+ } }
29
+ function PermissionsAuditLogResourceComponent_For_19_Template(rf, ctx) { if (rf & 1) {
30
+ i0.ɵɵelementStart(0, "option", 10);
31
+ i0.ɵɵtext(1);
32
+ i0.ɵɵelementEnd();
33
+ } if (rf & 2) {
34
+ const d_r2 = ctx.$implicit;
35
+ i0.ɵɵproperty("ngValue", d_r2.Name);
36
+ i0.ɵɵadvance();
37
+ i0.ɵɵtextInterpolate(d_r2.Name);
38
+ } }
39
+ function PermissionsAuditLogResourceComponent_For_26_Template(rf, ctx) { if (rf & 1) {
40
+ i0.ɵɵelementStart(0, "option", 10);
41
+ i0.ɵɵtext(1);
42
+ i0.ɵɵelementEnd();
43
+ } if (rf & 2) {
44
+ const user_r3 = ctx.$implicit;
45
+ i0.ɵɵproperty("ngValue", user_r3.ID);
46
+ i0.ɵɵadvance();
47
+ i0.ɵɵtextInterpolate(user_r3.Name);
48
+ } }
49
+ function PermissionsAuditLogResourceComponent_Conditional_34_Template(rf, ctx) { if (rf & 1) {
50
+ i0.ɵɵelement(0, "i", 23);
51
+ i0.ɵɵtext(1, " Querying... ");
52
+ } }
53
+ function PermissionsAuditLogResourceComponent_Conditional_35_Template(rf, ctx) { if (rf & 1) {
54
+ i0.ɵɵelement(0, "i", 24);
55
+ i0.ɵɵtext(1, " Query ");
56
+ } }
57
+ function PermissionsAuditLogResourceComponent_Conditional_39_Template(rf, ctx) { if (rf & 1) {
58
+ i0.ɵɵelement(0, "mj-loading", 20);
59
+ } }
60
+ function PermissionsAuditLogResourceComponent_Conditional_40_Template(rf, ctx) { if (rf & 1) {
61
+ i0.ɵɵelementStart(0, "div", 21);
62
+ i0.ɵɵelement(1, "i", 25);
63
+ i0.ɵɵelementStart(2, "p");
64
+ i0.ɵɵtext(3, "Set your filters and press Query to see audit entries.");
65
+ i0.ɵɵelementEnd()();
66
+ } }
67
+ function PermissionsAuditLogResourceComponent_Conditional_41_Template(rf, ctx) { if (rf & 1) {
68
+ i0.ɵɵelementStart(0, "div", 21);
69
+ i0.ɵɵelement(1, "i", 26);
70
+ i0.ɵɵelementStart(2, "p");
71
+ i0.ɵɵtext(3, "No audit entries match your filters.");
72
+ i0.ɵɵelementEnd()();
73
+ } }
74
+ function PermissionsAuditLogResourceComponent_Conditional_42_Conditional_4_Template(rf, ctx) { if (rf & 1) {
75
+ i0.ɵɵelementStart(0, "span", 28);
76
+ i0.ɵɵtext(1, "(capped at 500 \u2014 narrow the filters to see more)");
77
+ i0.ɵɵelementEnd();
78
+ } }
79
+ function PermissionsAuditLogResourceComponent_Conditional_42_For_25_Conditional_19_Template(rf, ctx) { if (rf & 1) {
80
+ i0.ɵɵelementStart(0, "span");
81
+ i0.ɵɵtext(1);
82
+ i0.ɵɵelementEnd();
83
+ } if (rf & 2) {
84
+ const entry_r4 = i0.ɵɵnextContext().$implicit;
85
+ i0.ɵɵadvance();
86
+ i0.ɵɵtextInterpolate(entry_r4.Summary);
87
+ } }
88
+ function PermissionsAuditLogResourceComponent_Conditional_42_For_25_Conditional_20_Template(rf, ctx) { if (rf & 1) {
89
+ i0.ɵɵelementStart(0, "span", 28);
90
+ i0.ɵɵtext(1, "\u2014");
91
+ i0.ɵɵelementEnd();
92
+ } }
93
+ function PermissionsAuditLogResourceComponent_Conditional_42_For_25_Template(rf, ctx) { if (rf & 1) {
94
+ i0.ɵɵelementStart(0, "tr")(1, "td");
95
+ i0.ɵɵtext(2);
96
+ i0.ɵɵpipe(3, "date");
97
+ i0.ɵɵelementEnd();
98
+ i0.ɵɵelementStart(4, "td");
99
+ i0.ɵɵtext(5);
100
+ i0.ɵɵelementEnd();
101
+ i0.ɵɵelementStart(6, "td")(7, "span", 31);
102
+ i0.ɵɵelement(8, "i");
103
+ i0.ɵɵtext(9);
104
+ i0.ɵɵelementEnd()();
105
+ i0.ɵɵelementStart(10, "td");
106
+ i0.ɵɵtext(11);
107
+ i0.ɵɵelementEnd();
108
+ i0.ɵɵelementStart(12, "td")(13, "span", 28);
109
+ i0.ɵɵtext(14);
110
+ i0.ɵɵelementEnd()();
111
+ i0.ɵɵelementStart(15, "td", 32)(16, "span", 33);
112
+ i0.ɵɵtext(17);
113
+ i0.ɵɵelementEnd()();
114
+ i0.ɵɵelementStart(18, "td");
115
+ i0.ɵɵconditionalCreate(19, PermissionsAuditLogResourceComponent_Conditional_42_For_25_Conditional_19_Template, 2, 1, "span")(20, PermissionsAuditLogResourceComponent_Conditional_42_For_25_Conditional_20_Template, 2, 0, "span", 28);
116
+ i0.ɵɵelementEnd()();
117
+ } if (rf & 2) {
118
+ const entry_r4 = ctx.$implicit;
119
+ const ctx_r0 = i0.ɵɵnextContext(2);
120
+ i0.ɵɵadvance(2);
121
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(3, 9, entry_r4.ChangedAt, "medium"));
122
+ i0.ɵɵadvance(3);
123
+ i0.ɵɵtextInterpolate(entry_r4.ChangedByUserName || entry_r4.ChangedByUserID || "System");
124
+ i0.ɵɵadvance(3);
125
+ i0.ɵɵclassMap(ctx_r0.ChangeIcon(entry_r4.ChangeType));
126
+ i0.ɵɵadvance();
127
+ i0.ɵɵtextInterpolate1(" ", entry_r4.ChangeType, " ");
128
+ i0.ɵɵadvance(2);
129
+ i0.ɵɵtextInterpolate(entry_r4.DomainName);
130
+ i0.ɵɵadvance(3);
131
+ i0.ɵɵtextInterpolate(entry_r4.EntityName);
132
+ i0.ɵɵadvance(3);
133
+ i0.ɵɵtextInterpolate(entry_r4.RecordID);
134
+ i0.ɵɵadvance(2);
135
+ i0.ɵɵconditional(entry_r4.Summary ? 19 : 20);
136
+ } }
137
+ function PermissionsAuditLogResourceComponent_Conditional_42_Template(rf, ctx) { if (rf & 1) {
138
+ i0.ɵɵelementStart(0, "div", 27)(1, "strong");
139
+ i0.ɵɵtext(2);
140
+ i0.ɵɵelementEnd();
141
+ i0.ɵɵtext(3);
142
+ i0.ɵɵconditionalCreate(4, PermissionsAuditLogResourceComponent_Conditional_42_Conditional_4_Template, 2, 0, "span", 28);
143
+ i0.ɵɵelementEnd();
144
+ i0.ɵɵelementStart(5, "div", 29)(6, "table", 30)(7, "thead")(8, "tr")(9, "th");
145
+ i0.ɵɵtext(10, "When");
146
+ i0.ɵɵelementEnd();
147
+ i0.ɵɵelementStart(11, "th");
148
+ i0.ɵɵtext(12, "Who");
149
+ i0.ɵɵelementEnd();
150
+ i0.ɵɵelementStart(13, "th");
151
+ i0.ɵɵtext(14, "Change");
152
+ i0.ɵɵelementEnd();
153
+ i0.ɵɵelementStart(15, "th");
154
+ i0.ɵɵtext(16, "Domain");
155
+ i0.ɵɵelementEnd();
156
+ i0.ɵɵelementStart(17, "th");
157
+ i0.ɵɵtext(18, "Entity");
158
+ i0.ɵɵelementEnd();
159
+ i0.ɵɵelementStart(19, "th");
160
+ i0.ɵɵtext(20, "Record");
161
+ i0.ɵɵelementEnd();
162
+ i0.ɵɵelementStart(21, "th");
163
+ i0.ɵɵtext(22, "Summary");
164
+ i0.ɵɵelementEnd()()();
165
+ i0.ɵɵelementStart(23, "tbody");
166
+ i0.ɵɵrepeaterCreate(24, PermissionsAuditLogResourceComponent_Conditional_42_For_25_Template, 21, 12, "tr", null, i0.ɵɵcomponentInstance().TrackByAuditEntry, true);
167
+ i0.ɵɵelementEnd()()();
168
+ } if (rf & 2) {
169
+ const ctx_r0 = i0.ɵɵnextContext();
170
+ i0.ɵɵadvance(2);
171
+ i0.ɵɵtextInterpolate(ctx_r0.Entries.length);
172
+ i0.ɵɵadvance();
173
+ i0.ɵɵtextInterpolate1(" entr", ctx_r0.Entries.length === 1 ? "y" : "ies", " ");
174
+ i0.ɵɵadvance();
175
+ i0.ɵɵconditional(ctx_r0.Entries.length === 500 ? 4 : -1);
176
+ i0.ɵɵadvance(20);
177
+ i0.ɵɵrepeater(ctx_r0.Entries);
178
+ } }
179
+ /**
180
+ * Audit Log resource — one of three tabs in the Permissions admin application.
181
+ * Chronological log of Create / Update / Delete events against any permission
182
+ * record across every registered domain. Powered by `PermissionEngine.GetAuditTimeline`.
183
+ */
184
+ let PermissionsAuditLogResourceComponent = class PermissionsAuditLogResourceComponent extends BaseResourceComponent {
185
+ cdr;
186
+ Domains = [];
187
+ Users = [];
188
+ DomainFilter = '';
189
+ UserFilter = '';
190
+ StartDate = '';
191
+ EndDate = '';
192
+ Entries = [];
193
+ IsLoading = false;
194
+ HasRunQuery = false;
195
+ ErrorMessage = null;
196
+ constructor(cdr) {
197
+ super();
198
+ this.cdr = cdr;
199
+ }
200
+ async GetResourceDisplayName(_data) {
201
+ return 'Audit Log';
202
+ }
203
+ async GetResourceIconClass(_data) {
204
+ return 'fa-solid fa-clock-rotate-left';
205
+ }
206
+ async ngOnInit() {
207
+ super.ngOnInit();
208
+ this.Domains = PermissionEngine.Instance.Domains;
209
+ try {
210
+ this.Users = await loadPermissionsUsers();
211
+ }
212
+ catch (e) {
213
+ this.ErrorMessage = `Error loading users: ${e instanceof Error ? e.message : String(e)}`;
214
+ }
215
+ this.NotifyLoadComplete();
216
+ }
217
+ ngOnDestroy() {
218
+ super.ngOnDestroy();
219
+ }
220
+ async OnRunQuery() {
221
+ this.ErrorMessage = null;
222
+ this.IsLoading = true;
223
+ this.Entries = [];
224
+ this.cdr.detectChanges();
225
+ try {
226
+ const filter = {
227
+ MaxRows: 500,
228
+ };
229
+ if (this.DomainFilter)
230
+ filter.DomainName = this.DomainFilter;
231
+ if (this.UserFilter)
232
+ filter.ChangedByUserID = this.UserFilter;
233
+ if (this.StartDate)
234
+ filter.StartDate = new Date(this.StartDate);
235
+ if (this.EndDate) {
236
+ // End-of-day semantics — include everything on the selected day
237
+ const d = new Date(this.EndDate);
238
+ d.setHours(23, 59, 59, 999);
239
+ filter.EndDate = d;
240
+ }
241
+ this.Entries = await PermissionEngine.Instance.GetAuditTimeline(filter);
242
+ this.HasRunQuery = true;
243
+ }
244
+ catch (e) {
245
+ this.ErrorMessage = `Error loading audit timeline: ${e instanceof Error ? e.message : String(e)}`;
246
+ }
247
+ this.IsLoading = false;
248
+ this.cdr.detectChanges();
249
+ }
250
+ OnResetFilters() {
251
+ this.DomainFilter = '';
252
+ this.UserFilter = '';
253
+ this.StartDate = '';
254
+ this.EndDate = '';
255
+ this.Entries = [];
256
+ this.HasRunQuery = false;
257
+ this.cdr.detectChanges();
258
+ }
259
+ TrackByAuditEntry(_index, entry) {
260
+ return entry.SourceRecordChangeID;
261
+ }
262
+ ChangeIcon(type) {
263
+ switch (type) {
264
+ case 'Create':
265
+ return 'fa-solid fa-plus';
266
+ case 'Update':
267
+ return 'fa-solid fa-pen';
268
+ case 'Delete':
269
+ return 'fa-solid fa-trash';
270
+ case 'Snapshot':
271
+ return 'fa-solid fa-camera';
272
+ default:
273
+ return 'fa-solid fa-circle';
274
+ }
275
+ }
276
+ static ɵfac = function PermissionsAuditLogResourceComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PermissionsAuditLogResourceComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
277
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PermissionsAuditLogResourceComponent, selectors: [["mj-permissions-audit-log-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 43, vars: 15, consts: [[1, "permissions-container"], [1, "header"], [1, "header-left"], [1, "fa-solid", "fa-clock-rotate-left", "header-icon"], [1, "header-title"], [1, "description"], [1, "message", "error-message"], [1, "selector-row", "wrap"], ["for", "audit-domain-select", 1, "selector-label"], ["id", "audit-domain-select", 1, "mj-input", 3, "ngModelChange", "ngModel", "disabled"], [3, "ngValue"], ["for", "audit-user-select", 1, "selector-label"], ["id", "audit-user-select", 1, "mj-input", 3, "ngModelChange", "ngModel", "disabled"], ["for", "audit-start-date", 1, "selector-label"], ["id", "audit-start-date", "type", "date", 1, "mj-input", 3, "ngModelChange", "ngModel", "disabled"], ["for", "audit-end-date", 1, "selector-label"], ["id", "audit-end-date", "type", "date", 1, "mj-input", 3, "ngModelChange", "ngModel", "disabled"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], ["mjButton", "", "variant", "secondary", 3, "click", "disabled"], [1, "fa-solid", "fa-rotate-left"], ["text", "Loading audit entries...", "size", "medium"], [1, "empty-state"], [1, "fa-solid", "fa-circle-exclamation"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-magnifying-glass"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "fa-solid", "fa-folder-open"], [1, "total-summary"], [1, "muted"], [1, "domain-body"], [1, "perms-table"], [1, "action-chip"], [1, "resource-cell"], [1, "resource-id"]], template: function PermissionsAuditLogResourceComponent_Template(rf, ctx) { if (rf & 1) {
278
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2);
279
+ i0.ɵɵelement(3, "i", 3);
280
+ i0.ɵɵelementStart(4, "h2", 4);
281
+ i0.ɵɵtext(5, "Audit Log");
282
+ i0.ɵɵelementEnd()()();
283
+ i0.ɵɵelementStart(6, "p", 5);
284
+ i0.ɵɵtext(7, " Chronological log of Create, Update, and Delete events against any permission record across every registered domain. Filter by domain, user, or date range. Data comes from ");
285
+ i0.ɵɵelementStart(8, "code");
286
+ i0.ɵɵtext(9, "MJ: Record Changes");
287
+ i0.ɵɵelementEnd();
288
+ i0.ɵɵtext(10, "; domains whose entities don't track changes won't appear here. ");
289
+ i0.ɵɵelementEnd();
290
+ i0.ɵɵconditionalCreate(11, PermissionsAuditLogResourceComponent_Conditional_11_Template, 4, 1, "div", 6);
291
+ i0.ɵɵelementStart(12, "div", 7)(13, "label", 8);
292
+ i0.ɵɵtext(14, "Domain:");
293
+ i0.ɵɵelementEnd();
294
+ i0.ɵɵelementStart(15, "select", 9);
295
+ i0.ɵɵtwoWayListener("ngModelChange", function PermissionsAuditLogResourceComponent_Template_select_ngModelChange_15_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.DomainFilter, $event) || (ctx.DomainFilter = $event); return $event; });
296
+ i0.ɵɵelementStart(16, "option", 10);
297
+ i0.ɵɵtext(17, "All domains");
298
+ i0.ɵɵelementEnd();
299
+ i0.ɵɵrepeaterCreate(18, PermissionsAuditLogResourceComponent_For_19_Template, 2, 2, "option", 10, _forTrack0);
300
+ i0.ɵɵelementEnd();
301
+ i0.ɵɵelementStart(20, "label", 11);
302
+ i0.ɵɵtext(21, "Changed by:");
303
+ i0.ɵɵelementEnd();
304
+ i0.ɵɵelementStart(22, "select", 12);
305
+ i0.ɵɵtwoWayListener("ngModelChange", function PermissionsAuditLogResourceComponent_Template_select_ngModelChange_22_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.UserFilter, $event) || (ctx.UserFilter = $event); return $event; });
306
+ i0.ɵɵelementStart(23, "option", 10);
307
+ i0.ɵɵtext(24, "Any user");
308
+ i0.ɵɵelementEnd();
309
+ i0.ɵɵrepeaterCreate(25, PermissionsAuditLogResourceComponent_For_26_Template, 2, 2, "option", 10, _forTrack0);
310
+ i0.ɵɵelementEnd();
311
+ i0.ɵɵelementStart(27, "label", 13);
312
+ i0.ɵɵtext(28, "From:");
313
+ i0.ɵɵelementEnd();
314
+ i0.ɵɵelementStart(29, "input", 14);
315
+ i0.ɵɵtwoWayListener("ngModelChange", function PermissionsAuditLogResourceComponent_Template_input_ngModelChange_29_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.StartDate, $event) || (ctx.StartDate = $event); return $event; });
316
+ i0.ɵɵelementEnd();
317
+ i0.ɵɵelementStart(30, "label", 15);
318
+ i0.ɵɵtext(31, "To:");
319
+ i0.ɵɵelementEnd();
320
+ i0.ɵɵelementStart(32, "input", 16);
321
+ i0.ɵɵtwoWayListener("ngModelChange", function PermissionsAuditLogResourceComponent_Template_input_ngModelChange_32_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.EndDate, $event) || (ctx.EndDate = $event); return $event; });
322
+ i0.ɵɵelementEnd();
323
+ i0.ɵɵelementStart(33, "button", 17);
324
+ i0.ɵɵlistener("click", function PermissionsAuditLogResourceComponent_Template_button_click_33_listener() { return ctx.OnRunQuery(); });
325
+ i0.ɵɵconditionalCreate(34, PermissionsAuditLogResourceComponent_Conditional_34_Template, 2, 0)(35, PermissionsAuditLogResourceComponent_Conditional_35_Template, 2, 0);
326
+ i0.ɵɵelementEnd();
327
+ i0.ɵɵelementStart(36, "button", 18);
328
+ i0.ɵɵlistener("click", function PermissionsAuditLogResourceComponent_Template_button_click_36_listener() { return ctx.OnResetFilters(); });
329
+ i0.ɵɵelement(37, "i", 19);
330
+ i0.ɵɵtext(38, " Reset ");
331
+ i0.ɵɵelementEnd()();
332
+ i0.ɵɵconditionalCreate(39, PermissionsAuditLogResourceComponent_Conditional_39_Template, 1, 0, "mj-loading", 20)(40, PermissionsAuditLogResourceComponent_Conditional_40_Template, 4, 0, "div", 21)(41, PermissionsAuditLogResourceComponent_Conditional_41_Template, 4, 0, "div", 21)(42, PermissionsAuditLogResourceComponent_Conditional_42_Template, 26, 3);
333
+ i0.ɵɵelementEnd();
334
+ } if (rf & 2) {
335
+ i0.ɵɵadvance(11);
336
+ i0.ɵɵconditional(ctx.ErrorMessage ? 11 : -1);
337
+ i0.ɵɵadvance(4);
338
+ i0.ɵɵtwoWayProperty("ngModel", ctx.DomainFilter);
339
+ i0.ɵɵproperty("disabled", ctx.IsLoading);
340
+ i0.ɵɵadvance();
341
+ i0.ɵɵproperty("ngValue", "");
342
+ i0.ɵɵadvance(2);
343
+ i0.ɵɵrepeater(ctx.Domains);
344
+ i0.ɵɵadvance(4);
345
+ i0.ɵɵtwoWayProperty("ngModel", ctx.UserFilter);
346
+ i0.ɵɵproperty("disabled", ctx.IsLoading);
347
+ i0.ɵɵadvance();
348
+ i0.ɵɵproperty("ngValue", "");
349
+ i0.ɵɵadvance(2);
350
+ i0.ɵɵrepeater(ctx.Users);
351
+ i0.ɵɵadvance(4);
352
+ i0.ɵɵtwoWayProperty("ngModel", ctx.StartDate);
353
+ i0.ɵɵproperty("disabled", ctx.IsLoading);
354
+ i0.ɵɵadvance(3);
355
+ i0.ɵɵtwoWayProperty("ngModel", ctx.EndDate);
356
+ i0.ɵɵproperty("disabled", ctx.IsLoading);
357
+ i0.ɵɵadvance();
358
+ i0.ɵɵproperty("disabled", ctx.IsLoading);
359
+ i0.ɵɵadvance();
360
+ i0.ɵɵconditional(ctx.IsLoading ? 34 : 35);
361
+ i0.ɵɵadvance(2);
362
+ i0.ɵɵproperty("disabled", ctx.IsLoading);
363
+ i0.ɵɵadvance(3);
364
+ i0.ɵɵconditional(ctx.IsLoading ? 39 : !ctx.HasRunQuery ? 40 : ctx.Entries.length === 0 ? 41 : 42);
365
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJButtonDirective, i3.LoadingComponent, i4.DatePipe], styles: [".permissions-container[_ngcontent-%COMP%] {\n padding: 24px;\n max-width: 1080px;\n margin: 0 auto;\n height: 100%;\n overflow-y: auto;\n box-sizing: border-box;\n}\n\n\n\n.header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 12px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.header-icon[_ngcontent-%COMP%] {\n font-size: 24px;\n color: var(--mj-brand-primary);\n}\n\n.header-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 22px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.description[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 14px;\n margin-bottom: 20px;\n line-height: 1.5;\n}\n\n\n\n.tab-bar[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 16px;\n}\n\n.tab[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n padding: 10px 16px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font: inherit;\n font-weight: 500;\n border-bottom: 2px solid transparent;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.tab-active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.selector-row.wrap[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n}\n\n.mj-input.mono[_ngcontent-%COMP%] {\n font-family: var(--mj-font-mono, monospace);\n min-width: 300px;\n}\n\n.muted[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.message[_ngcontent-%COMP%] {\n padding: 10px 14px;\n border-radius: 6px;\n margin-bottom: 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n}\n\n.error-message[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n\n\n.user-selector-row[_ngcontent-%COMP%], \n.selector-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n}\n\n.user-selector-label[_ngcontent-%COMP%], \n.selector-label[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n#user-select[_ngcontent-%COMP%], \n#domain-select[_ngcontent-%COMP%] {\n min-width: 320px;\n flex: 0 1 auto;\n}\n\n.roles-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-radius: 12px;\n font-size: 12px;\n font-weight: 500;\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 48px 16px;\n color: var(--mj-text-muted);\n border: 1px dashed var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n display: block;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n}\n\n.total-summary[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 13px;\n margin-bottom: 12px;\n}\n\n.total-summary[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n}\n\n\n\n.domain-groups[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.domain-group[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.domain-header[_ngcontent-%COMP%] {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border: none;\n cursor: pointer;\n text-align: left;\n color: var(--mj-text-primary);\n font: inherit;\n}\n\n.domain-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.domain-header-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.domain-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.domain-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 15px;\n}\n\n.domain-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 20px;\n padding: 0 8px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 10px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.toggle-icon[_ngcontent-%COMP%] {\n transition: transform 0.15s ease;\n color: var(--mj-text-muted);\n}\n\n.toggle-icon.rotated[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n.domain-body[_ngcontent-%COMP%] {\n padding: 0;\n background: var(--mj-bg-surface);\n overflow-x: auto;\n}\n\n\n\n.perms-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.perms-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n.perms-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 8px 16px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-subtle);\n vertical-align: top;\n}\n\n.perms-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-weight: 600;\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n}\n\n.perms-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child td[_ngcontent-%COMP%] {\n border-bottom: none;\n}\n\n.perms-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.resource-cell[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.resource-name[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n.resource-id[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 11px;\n font-family: var(--mj-font-mono, monospace);\n}\n\n\n\n.action-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.action-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n\n\n.effect-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.effect-allow[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.effect-deny[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}"] });
366
+ };
367
+ PermissionsAuditLogResourceComponent = __decorate([
368
+ RegisterClass(BaseResourceComponent, 'PermissionsAuditLogResource')
369
+ ], PermissionsAuditLogResourceComponent);
370
+ export { PermissionsAuditLogResourceComponent };
371
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PermissionsAuditLogResourceComponent, [{
372
+ type: Component,
373
+ args: [{ standalone: false, selector: 'mj-permissions-audit-log-resource', template: "<div class=\"permissions-container\">\n <div class=\"header\">\n <div class=\"header-left\">\n <i class=\"fa-solid fa-clock-rotate-left header-icon\"></i>\n <h2 class=\"header-title\">Audit Log</h2>\n </div>\n </div>\n\n <p class=\"description\">\n Chronological log of Create, Update, and Delete events against any permission\n record across every registered domain. Filter by domain, user, or date range.\n Data comes from <code>MJ: Record Changes</code>; domains whose entities don't\n track changes won't appear here.\n </p>\n\n @if (ErrorMessage) {\n <div class=\"message error-message\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n <span>{{ ErrorMessage }}</span>\n </div>\n }\n\n <div class=\"selector-row wrap\">\n <label class=\"selector-label\" for=\"audit-domain-select\">Domain:</label>\n <select\n id=\"audit-domain-select\"\n class=\"mj-input\"\n [(ngModel)]=\"DomainFilter\"\n [disabled]=\"IsLoading\"\n >\n <option [ngValue]=\"''\">All domains</option>\n @for (d of Domains; track d.ID) {\n <option [ngValue]=\"d.Name\">{{ d.Name }}</option>\n }\n </select>\n\n <label class=\"selector-label\" for=\"audit-user-select\">Changed by:</label>\n <select\n id=\"audit-user-select\"\n class=\"mj-input\"\n [(ngModel)]=\"UserFilter\"\n [disabled]=\"IsLoading\"\n >\n <option [ngValue]=\"''\">Any user</option>\n @for (user of Users; track user.ID) {\n <option [ngValue]=\"user.ID\">{{ user.Name }}</option>\n }\n </select>\n\n <label class=\"selector-label\" for=\"audit-start-date\">From:</label>\n <input\n id=\"audit-start-date\"\n type=\"date\"\n class=\"mj-input\"\n [(ngModel)]=\"StartDate\"\n [disabled]=\"IsLoading\"\n />\n\n <label class=\"selector-label\" for=\"audit-end-date\">To:</label>\n <input\n id=\"audit-end-date\"\n type=\"date\"\n class=\"mj-input\"\n [(ngModel)]=\"EndDate\"\n [disabled]=\"IsLoading\"\n />\n\n <button mjButton variant=\"primary\" (click)=\"OnRunQuery()\" [disabled]=\"IsLoading\">\n @if (IsLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Querying...\n } @else {\n <i class=\"fa-solid fa-magnifying-glass\"></i> Query\n }\n </button>\n\n <button mjButton variant=\"secondary\" (click)=\"OnResetFilters()\" [disabled]=\"IsLoading\">\n <i class=\"fa-solid fa-rotate-left\"></i> Reset\n </button>\n </div>\n\n @if (IsLoading) {\n <mj-loading text=\"Loading audit entries...\" size=\"medium\"></mj-loading>\n } @else if (!HasRunQuery) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n <p>Set your filters and press Query to see audit entries.</p>\n </div>\n } @else if (Entries.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-folder-open\"></i>\n <p>No audit entries match your filters.</p>\n </div>\n } @else {\n <div class=\"total-summary\">\n <strong>{{ Entries.length }}</strong> entr{{ Entries.length === 1 ? 'y' : 'ies' }}\n @if (Entries.length === 500) {\n <span class=\"muted\">(capped at 500 \u2014 narrow the filters to see more)</span>\n }\n </div>\n\n <div class=\"domain-body\">\n <table class=\"perms-table\">\n <thead>\n <tr>\n <th>When</th>\n <th>Who</th>\n <th>Change</th>\n <th>Domain</th>\n <th>Entity</th>\n <th>Record</th>\n <th>Summary</th>\n </tr>\n </thead>\n <tbody>\n @for (entry of Entries; track TrackByAuditEntry($index, entry)) {\n <tr>\n <td>{{ entry.ChangedAt | date:'medium' }}</td>\n <td>{{ entry.ChangedByUserName || entry.ChangedByUserID || 'System' }}</td>\n <td>\n <span class=\"action-chip\">\n <i [class]=\"ChangeIcon(entry.ChangeType)\"></i>\n {{ entry.ChangeType }}\n </span>\n </td>\n <td>{{ entry.DomainName }}</td>\n <td><span class=\"muted\">{{ entry.EntityName }}</span></td>\n <td class=\"resource-cell\">\n <span class=\"resource-id\">{{ entry.RecordID }}</span>\n </td>\n <td>\n @if (entry.Summary) {\n <span>{{ entry.Summary }}</span>\n } @else {\n <span class=\"muted\">\u2014</span>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n</div>\n", styles: [".permissions-container {\n padding: 24px;\n max-width: 1080px;\n margin: 0 auto;\n height: 100%;\n overflow-y: auto;\n box-sizing: border-box;\n}\n\n/* Header */\n.header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 12px;\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.header-icon {\n font-size: 24px;\n color: var(--mj-brand-primary);\n}\n\n.header-title {\n margin: 0;\n font-size: 22px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.description {\n color: var(--mj-text-secondary);\n font-size: 14px;\n margin-bottom: 20px;\n line-height: 1.5;\n}\n\n/* Tab bar */\n.tab-bar {\n display: flex;\n gap: 4px;\n border-bottom: 1px solid var(--mj-border-default);\n margin-bottom: 16px;\n}\n\n.tab {\n background: transparent;\n border: none;\n padding: 10px 16px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font: inherit;\n font-weight: 500;\n border-bottom: 2px solid transparent;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.tab:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.tab-active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.selector-row.wrap {\n flex-wrap: wrap;\n}\n\n.mj-input.mono {\n font-family: var(--mj-font-mono, monospace);\n min-width: 300px;\n}\n\n.muted {\n color: var(--mj-text-muted);\n}\n\n/* Messages */\n.message {\n padding: 10px 14px;\n border-radius: 6px;\n margin-bottom: 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n}\n\n.error-message {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n/* User selector (legacy name kept for User Access tab, plus generic selector-row for Resource tab) */\n.user-selector-row,\n.selector-row {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n}\n\n.user-selector-label,\n.selector-label {\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n#user-select,\n#domain-select {\n min-width: 320px;\n flex: 0 1 auto;\n}\n\n.roles-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-radius: 12px;\n font-size: 12px;\n font-weight: 500;\n}\n\n/* Empty state */\n.empty-state {\n text-align: center;\n padding: 48px 16px;\n color: var(--mj-text-muted);\n border: 1px dashed var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface-card);\n}\n\n.empty-state i {\n font-size: 32px;\n margin-bottom: 12px;\n display: block;\n}\n\n.empty-state p {\n margin: 0;\n font-size: 14px;\n}\n\n.total-summary {\n color: var(--mj-text-secondary);\n font-size: 13px;\n margin-bottom: 12px;\n}\n\n.total-summary strong {\n color: var(--mj-text-primary);\n}\n\n/* Domain groups */\n.domain-groups {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.domain-group {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.domain-header {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border: none;\n cursor: pointer;\n text-align: left;\n color: var(--mj-text-primary);\n font: inherit;\n}\n\n.domain-header:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.domain-header-left {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.domain-icon {\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.domain-name {\n font-weight: 600;\n font-size: 15px;\n}\n\n.domain-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 20px;\n padding: 0 8px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 10px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.toggle-icon {\n transition: transform 0.15s ease;\n color: var(--mj-text-muted);\n}\n\n.toggle-icon.rotated {\n transform: rotate(180deg);\n}\n\n.domain-body {\n padding: 0;\n background: var(--mj-bg-surface);\n overflow-x: auto;\n}\n\n/* Permissions table */\n.perms-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.perms-table th,\n.perms-table td {\n padding: 8px 16px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-subtle);\n vertical-align: top;\n}\n\n.perms-table th {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-weight: 600;\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n}\n\n.perms-table tbody tr:last-child td {\n border-bottom: none;\n}\n\n.perms-table tbody tr:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.resource-cell {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.resource-name {\n color: var(--mj-text-primary);\n font-weight: 500;\n}\n\n.resource-id {\n color: var(--mj-text-muted);\n font-size: 11px;\n font-family: var(--mj-font-mono, monospace);\n}\n\n/* Action chips */\n.action-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.action-chip {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n/* Effect badge */\n.effect-badge {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.effect-allow {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.effect-deny {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n"] }]
374
+ }], () => [{ type: i0.ChangeDetectorRef }], null); })();
375
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PermissionsAuditLogResourceComponent, { className: "PermissionsAuditLogResourceComponent", filePath: "src/Permissions/audit-log-resource.component.ts", lineNumber: 21 }); })();
376
+ /** Tree-shaking prevention — referenced from `public-api.ts`. */
377
+ export function LoadPermissionsAuditLogResource() {
378
+ // intentionally empty
379
+ }
380
+ //# sourceMappingURL=audit-log-resource.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-log-resource.component.js","sourceRoot":"","sources":["../../src/Permissions/audit-log-resource.component.ts","../../src/Permissions/audit-log-resource.component.html"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAqB,SAAS,EAAqB,MAAM,eAAe,CAAC;AAEhF,OAAO,EAA4B,gBAAgB,EAAgB,MAAM,+BAA+B,CAAC;AACzG,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,EAAyB,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;;;;;;;;ICU/E,8BAAmC;IACjC,wBAA8C;IAC9C,4BAAM;IAAA,YAAkB;IAC1B,AAD0B,iBAAO,EAC3B;;;IADE,eAAkB;IAAlB,yCAAkB;;;IActB,kCAA2B;IAAA,YAAY;IAAA,iBAAS;;;IAAxC,mCAAkB;IAAC,cAAY;IAAZ,+BAAY;;;IAavC,kCAA4B;IAAA,YAAe;IAAA,iBAAS;;;IAA5C,oCAAmB;IAAC,cAAe;IAAf,kCAAe;;;IAwB3C,wBAA2C;IAAC,6BAC9C;;;IACE,wBAA4C;IAAC,uBAC/C;;;IASF,iCAAuE;;;IAEvE,+BAAyB;IACvB,wBAA6C;IAC7C,yBAAG;IAAA,sEAAsD;IAC3D,AAD2D,iBAAI,EACzD;;;IAEN,+BAAyB;IACvB,wBAAuC;IACvC,yBAAG;IAAA,oDAAoC;IACzC,AADyC,iBAAI,EACvC;;;IAKF,gCAAoB;IAAA,qEAAgD;IAAA,iBAAO;;;IAmCjE,4BAAM;IAAA,YAAmB;IAAA,iBAAO;;;IAA1B,cAAmB;IAAnB,sCAAmB;;;IAEzB,gCAAoB;IAAA,sBAAC;IAAA,iBAAO;;;IAjBhC,AADF,0BAAI,SACE;IAAA,YAAqC;;IAAA,iBAAK;IAC9C,0BAAI;IAAA,YAAkE;IAAA,iBAAK;IAEzE,AADF,0BAAI,eACwB;IACxB,oBAA8C;IAC9C,YACF;IACF,AADE,iBAAO,EACJ;IACL,2BAAI;IAAA,aAAsB;IAAA,iBAAK;IAC3B,AAAJ,2BAAI,gBAAoB;IAAA,aAAsB;IAAO,AAAP,iBAAO,EAAK;IAExD,AADF,+BAA0B,gBACE;IAAA,aAAoB;IAChD,AADgD,iBAAO,EAClD;IACL,2BAAI;IAGA,AAFF,4HAAqB,0GAEZ;IAIb,AADE,iBAAK,EACF;;;;IApBC,eAAqC;IAArC,wEAAqC;IACrC,eAAkE;IAAlE,wFAAkE;IAG/D,eAAsC;IAAtC,qDAAsC;IACzC,cACF;IADE,oDACF;IAEE,eAAsB;IAAtB,yCAAsB;IACF,eAAsB;IAAtB,yCAAsB;IAElB,eAAoB;IAApB,uCAAoB;IAG9C,eAIC;IAJD,4CAIC;;;IAxCX,AADF,+BAA2B,aACjB;IAAA,YAAoB;IAAA,iBAAS;IAAC,YACtC;IAAA,uHAA8B;IAGhC,iBAAM;IAME,AADF,AADF,AADF,AADF,+BAAyB,gBACI,YAClB,SACD,SACE;IAAA,qBAAI;IAAA,iBAAK;IACb,2BAAI;IAAA,oBAAG;IAAA,iBAAK;IACZ,2BAAI;IAAA,uBAAM;IAAA,iBAAK;IACf,2BAAI;IAAA,uBAAM;IAAA,iBAAK;IACf,2BAAI;IAAA,uBAAM;IAAA,iBAAK;IACf,2BAAI;IAAA,uBAAM;IAAA,iBAAK;IACf,2BAAI;IAAA,wBAAO;IAEf,AADE,AADa,iBAAK,EACb,EACC;IACR,8BAAO;IACL,kKAuBC;IAGP,AADE,AADE,iBAAQ,EACF,EACJ;;;IA9CI,eAAoB;IAApB,2CAAoB;IAAU,cACtC;IADsC,8EACtC;IAAA,cAEC;IAFD,wDAEC;IAiBG,gBAuBC;IAvBD,6BAuBC;;ADjIX;;;;GAIG;AAQI,IAAM,oCAAoC,GAA1C,MAAM,oCAAqC,SAAQ,qBAAqB;IAavD;IAZpB,OAAO,GAA+B,EAAE,CAAC;IACzC,KAAK,GAA4B,EAAE,CAAC;IAEpC,YAAY,GAAgB,EAAE,CAAC;IAC/B,UAAU,GAAgB,EAAE,CAAC;IAC7B,SAAS,GAAW,EAAE,CAAC;IACvB,OAAO,GAAW,EAAE,CAAC;IACrB,OAAO,GAA2B,EAAE,CAAC;IACrC,SAAS,GAAG,KAAK,CAAC;IAClB,WAAW,GAAG,KAAK,CAAC;IACpB,YAAY,GAAkB,IAAI,CAAC;IAEnC,YAAoB,GAAsB;QACtC,KAAK,EAAE,CAAC;QADQ,QAAG,GAAH,GAAG,CAAmB;IAE1C,CAAC;IAEQ,KAAK,CAAC,sBAAsB,CAAC,KAAmB;QACrD,OAAO,WAAW,CAAC;IACvB,CAAC;IAEQ,KAAK,CAAC,oBAAoB,CAAC,KAAmB;QACnD,OAAO,+BAA+B,CAAC;IAC3C,CAAC;IAEQ,KAAK,CAAC,QAAQ;QACnB,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC;QACjD,IAAI,CAAC;YACD,IAAI,CAAC,KAAK,GAAG,MAAM,oBAAoB,EAAE,CAAC;QAC9C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,IAAI,CAAC,YAAY,GAAG,wBAAwB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7F,CAAC;QACD,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC9B,CAAC;IAEQ,WAAW;QAChB,KAAK,CAAC,WAAW,EAAE,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,UAAU;QACZ,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC;YACD,MAAM,MAAM,GAAqE;gBAC7E,OAAO,EAAE,GAAG;aACf,CAAC;YACF,IAAI,IAAI,CAAC,YAAY;gBAAE,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC;YAC7D,IAAI,IAAI,CAAC,UAAU;gBAAE,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU,CAAC;YAC9D,IAAI,IAAI,CAAC,SAAS;gBAAE,MAAM,CAAC,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAChE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,gEAAgE;gBAChE,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACjC,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;gBAC5B,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;YACvB,CAAC;YAED,IAAI,CAAC,OAAO,GAAG,MAAM,gBAAgB,CAAC,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YACxE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,IAAI,CAAC,YAAY,GAAG,iCAAiC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACtG,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,cAAc;QACV,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,iBAAiB,CAAC,MAAc,EAAE,KAA2B;QACzD,OAAO,KAAK,CAAC,oBAAoB,CAAC;IACtC,CAAC;IAED,UAAU,CAAC,IAAwC;QAC/C,QAAQ,IAAI,EAAE,CAAC;YACX,KAAK,QAAQ;gBACT,OAAO,kBAAkB,CAAC;YAC9B,KAAK,QAAQ;gBACT,OAAO,iBAAiB,CAAC;YAC7B,KAAK,QAAQ;gBACT,OAAO,mBAAmB,CAAC;YAC/B,KAAK,UAAU;gBACX,OAAO,oBAAoB,CAAC;YAChC;gBACI,OAAO,oBAAoB,CAAC;QACpC,CAAC;IACL,CAAC;8HAjGQ,oCAAoC;6DAApC,oCAAoC;YClB7C,AADF,AADF,8BAAmC,aACb,aACO;YACvB,uBAAyD;YACzD,6BAAyB;YAAA,yBAAS;YAEtC,AADE,AADoC,iBAAK,EACnC,EACF;YAEN,4BAAuB;YACrB,6LAEgB;YAAA,4BAAM;YAAA,kCAAkB;YAAA,iBAAO;YAAA,iFAEjD;YAAA,iBAAI;YAEJ,wGAAoB;YAQlB,AADF,+BAA+B,gBAC2B;YAAA,wBAAO;YAAA,iBAAQ;YACvE,kCAKC;YAFC,wOAA0B;YAG1B,mCAAuB;YAAA,4BAAW;YAAA,iBAAS;YAC3C,6GAEC;YACH,iBAAS;YAET,kCAAsD;YAAA,4BAAW;YAAA,iBAAQ;YACzE,mCAKC;YAFC,oOAAwB;YAGxB,mCAAuB;YAAA,yBAAQ;YAAA,iBAAS;YACxC,6GAEC;YACH,iBAAS;YAET,kCAAqD;YAAA,sBAAK;YAAA,iBAAQ;YAClE,kCAME;YAFA,iOAAuB;YAJzB,iBAME;YAEF,kCAAmD;YAAA,oBAAG;YAAA,iBAAQ;YAC9D,kCAME;YAFA,6NAAqB;YAJvB,iBAME;YAEF,mCAAiF;YAA9C,kHAAS,gBAAY,IAAC;YAGrD,AAFF,8FAAiB,wEAER;YAGX,iBAAS;YAET,mCAAuF;YAAlD,kHAAS,oBAAgB,IAAC;YAC7D,yBAAuC;YAAC,wBAC1C;YACF,AADE,iBAAS,EACL;YAcJ,AALA,AALA,AAFF,gHAAiB,mFAEU,mFAKQ,yEAK1B;YAkDX,iBAAM;;YA/HJ,gBAKC;YALD,4CAKC;YAOG,eAA0B;YAA1B,gDAA0B;YAC1B,wCAAsB;YAEd,cAAc;YAAd,4BAAc;YACtB,eAEC;YAFD,0BAEC;YAOD,eAAwB;YAAxB,8CAAwB;YACxB,wCAAsB;YAEd,cAAc;YAAd,4BAAc;YACtB,eAEC;YAFD,wBAEC;YAQD,eAAuB;YAAvB,6CAAuB;YACvB,wCAAsB;YAQtB,eAAqB;YAArB,2CAAqB;YACrB,wCAAsB;YAGkC,cAAsB;YAAtB,wCAAsB;YAC9E,cAIC;YAJD,yCAIC;YAG6D,eAAsB;YAAtB,wCAAsB;YAKxF,eA6DC;YA7DD,iGA6DC;;;ADzHU,oCAAoC;IAPhD,aAAa,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;GAOvD,oCAAoC,CAkGhD;;iFAlGY,oCAAoC;cANhD,SAAS;6BACM,KAAK,YACP,mCAAmC;;kFAIpC,oCAAoC;AAoGjD,iEAAiE;AACjE,MAAM,UAAU,+BAA+B;IAC3C,sBAAsB;AAC1B,CAAC","sourcesContent":["import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';\nimport { PermissionAuditEntry } from '@memberjunction/core';\nimport { MJPermissionDomainEntity, PermissionEngine, ResourceData } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\n\nimport { PermissionsUserOption, loadPermissionsUsers } from './permissions-shared';\n\n/**\n * Audit Log resource — one of three tabs in the Permissions admin application.\n * Chronological log of Create / Update / Delete events against any permission\n * record across every registered domain. Powered by `PermissionEngine.GetAuditTimeline`.\n */\n@RegisterClass(BaseResourceComponent, 'PermissionsAuditLogResource')\n@Component({\n standalone: false,\n selector: 'mj-permissions-audit-log-resource',\n templateUrl: './audit-log-resource.component.html',\n styleUrls: ['./permissions-resource.component.css'],\n})\nexport class PermissionsAuditLogResourceComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n Domains: MJPermissionDomainEntity[] = [];\n Users: PermissionsUserOption[] = [];\n\n DomainFilter: string | '' = '';\n UserFilter: string | '' = '';\n StartDate: string = '';\n EndDate: string = '';\n Entries: PermissionAuditEntry[] = [];\n IsLoading = false;\n HasRunQuery = false;\n ErrorMessage: string | null = null;\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n override async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return 'Audit Log';\n }\n\n override async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-clock-rotate-left';\n }\n\n override async ngOnInit(): Promise<void> {\n super.ngOnInit();\n this.Domains = PermissionEngine.Instance.Domains;\n try {\n this.Users = await loadPermissionsUsers();\n } catch (e) {\n this.ErrorMessage = `Error loading users: ${e instanceof Error ? e.message : String(e)}`;\n }\n this.NotifyLoadComplete();\n }\n\n override ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n async OnRunQuery(): Promise<void> {\n this.ErrorMessage = null;\n this.IsLoading = true;\n this.Entries = [];\n this.cdr.detectChanges();\n\n try {\n const filter: Parameters<typeof PermissionEngine.Instance.GetAuditTimeline>[0] = {\n MaxRows: 500,\n };\n if (this.DomainFilter) filter.DomainName = this.DomainFilter;\n if (this.UserFilter) filter.ChangedByUserID = this.UserFilter;\n if (this.StartDate) filter.StartDate = new Date(this.StartDate);\n if (this.EndDate) {\n // End-of-day semantics — include everything on the selected day\n const d = new Date(this.EndDate);\n d.setHours(23, 59, 59, 999);\n filter.EndDate = d;\n }\n\n this.Entries = await PermissionEngine.Instance.GetAuditTimeline(filter);\n this.HasRunQuery = true;\n } catch (e) {\n this.ErrorMessage = `Error loading audit timeline: ${e instanceof Error ? e.message : String(e)}`;\n }\n\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n\n OnResetFilters(): void {\n this.DomainFilter = '';\n this.UserFilter = '';\n this.StartDate = '';\n this.EndDate = '';\n this.Entries = [];\n this.HasRunQuery = false;\n this.cdr.detectChanges();\n }\n\n TrackByAuditEntry(_index: number, entry: PermissionAuditEntry): string {\n return entry.SourceRecordChangeID;\n }\n\n ChangeIcon(type: PermissionAuditEntry['ChangeType']): string {\n switch (type) {\n case 'Create':\n return 'fa-solid fa-plus';\n case 'Update':\n return 'fa-solid fa-pen';\n case 'Delete':\n return 'fa-solid fa-trash';\n case 'Snapshot':\n return 'fa-solid fa-camera';\n default:\n return 'fa-solid fa-circle';\n }\n }\n}\n\n/** Tree-shaking prevention — referenced from `public-api.ts`. */\nexport function LoadPermissionsAuditLogResource(): void {\n // intentionally empty\n}\n","<div class=\"permissions-container\">\n <div class=\"header\">\n <div class=\"header-left\">\n <i class=\"fa-solid fa-clock-rotate-left header-icon\"></i>\n <h2 class=\"header-title\">Audit Log</h2>\n </div>\n </div>\n\n <p class=\"description\">\n Chronological log of Create, Update, and Delete events against any permission\n record across every registered domain. Filter by domain, user, or date range.\n Data comes from <code>MJ: Record Changes</code>; domains whose entities don't\n track changes won't appear here.\n </p>\n\n @if (ErrorMessage) {\n <div class=\"message error-message\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n <span>{{ ErrorMessage }}</span>\n </div>\n }\n\n <div class=\"selector-row wrap\">\n <label class=\"selector-label\" for=\"audit-domain-select\">Domain:</label>\n <select\n id=\"audit-domain-select\"\n class=\"mj-input\"\n [(ngModel)]=\"DomainFilter\"\n [disabled]=\"IsLoading\"\n >\n <option [ngValue]=\"''\">All domains</option>\n @for (d of Domains; track d.ID) {\n <option [ngValue]=\"d.Name\">{{ d.Name }}</option>\n }\n </select>\n\n <label class=\"selector-label\" for=\"audit-user-select\">Changed by:</label>\n <select\n id=\"audit-user-select\"\n class=\"mj-input\"\n [(ngModel)]=\"UserFilter\"\n [disabled]=\"IsLoading\"\n >\n <option [ngValue]=\"''\">Any user</option>\n @for (user of Users; track user.ID) {\n <option [ngValue]=\"user.ID\">{{ user.Name }}</option>\n }\n </select>\n\n <label class=\"selector-label\" for=\"audit-start-date\">From:</label>\n <input\n id=\"audit-start-date\"\n type=\"date\"\n class=\"mj-input\"\n [(ngModel)]=\"StartDate\"\n [disabled]=\"IsLoading\"\n />\n\n <label class=\"selector-label\" for=\"audit-end-date\">To:</label>\n <input\n id=\"audit-end-date\"\n type=\"date\"\n class=\"mj-input\"\n [(ngModel)]=\"EndDate\"\n [disabled]=\"IsLoading\"\n />\n\n <button mjButton variant=\"primary\" (click)=\"OnRunQuery()\" [disabled]=\"IsLoading\">\n @if (IsLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Querying...\n } @else {\n <i class=\"fa-solid fa-magnifying-glass\"></i> Query\n }\n </button>\n\n <button mjButton variant=\"secondary\" (click)=\"OnResetFilters()\" [disabled]=\"IsLoading\">\n <i class=\"fa-solid fa-rotate-left\"></i> Reset\n </button>\n </div>\n\n @if (IsLoading) {\n <mj-loading text=\"Loading audit entries...\" size=\"medium\"></mj-loading>\n } @else if (!HasRunQuery) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n <p>Set your filters and press Query to see audit entries.</p>\n </div>\n } @else if (Entries.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-folder-open\"></i>\n <p>No audit entries match your filters.</p>\n </div>\n } @else {\n <div class=\"total-summary\">\n <strong>{{ Entries.length }}</strong> entr{{ Entries.length === 1 ? 'y' : 'ies' }}\n @if (Entries.length === 500) {\n <span class=\"muted\">(capped at 500 — narrow the filters to see more)</span>\n }\n </div>\n\n <div class=\"domain-body\">\n <table class=\"perms-table\">\n <thead>\n <tr>\n <th>When</th>\n <th>Who</th>\n <th>Change</th>\n <th>Domain</th>\n <th>Entity</th>\n <th>Record</th>\n <th>Summary</th>\n </tr>\n </thead>\n <tbody>\n @for (entry of Entries; track TrackByAuditEntry($index, entry)) {\n <tr>\n <td>{{ entry.ChangedAt | date:'medium' }}</td>\n <td>{{ entry.ChangedByUserName || entry.ChangedByUserID || 'System' }}</td>\n <td>\n <span class=\"action-chip\">\n <i [class]=\"ChangeIcon(entry.ChangeType)\"></i>\n {{ entry.ChangeType }}\n </span>\n </td>\n <td>{{ entry.DomainName }}</td>\n <td><span class=\"muted\">{{ entry.EntityName }}</span></td>\n <td class=\"resource-cell\">\n <span class=\"resource-id\">{{ entry.RecordID }}</span>\n </td>\n <td>\n @if (entry.Summary) {\n <span>{{ entry.Summary }}</span>\n } @else {\n <span class=\"muted\">—</span>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n</div>\n"]}