@memberjunction/ng-dashboards 2.47.0 → 2.49.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 (92) hide show
  1. package/README.md +105 -2
  2. package/dist/AI/ai-dashboard.component.d.ts +2 -0
  3. package/dist/AI/ai-dashboard.component.d.ts.map +1 -1
  4. package/dist/AI/ai-dashboard.component.js +66 -43
  5. package/dist/AI/ai-dashboard.component.js.map +1 -1
  6. package/dist/AI/components/agents/agent-configuration.component.js +45 -58
  7. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  8. package/dist/AI/components/agents/agent-editor.component.d.ts +6 -1
  9. package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
  10. package/dist/AI/components/agents/agent-editor.component.js +368 -366
  11. package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
  12. package/dist/AI/components/agents/agent-filter-panel.component.js +83 -85
  13. package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
  14. package/dist/AI/components/charts/performance-heatmap.component.d.ts +66 -0
  15. package/dist/AI/components/charts/performance-heatmap.component.d.ts.map +1 -0
  16. package/dist/AI/components/charts/performance-heatmap.component.js +428 -0
  17. package/dist/AI/components/charts/performance-heatmap.component.js.map +1 -0
  18. package/dist/AI/components/charts/time-series-chart.component.d.ts +66 -0
  19. package/dist/AI/components/charts/time-series-chart.component.d.ts.map +1 -0
  20. package/dist/AI/components/charts/time-series-chart.component.js +547 -0
  21. package/dist/AI/components/charts/time-series-chart.component.js.map +1 -0
  22. package/dist/AI/components/execution-monitoring.component.d.ts +157 -5
  23. package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
  24. package/dist/AI/components/execution-monitoring.component.js +2032 -20
  25. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  26. package/dist/AI/components/models/model-management.component.js +211 -237
  27. package/dist/AI/components/models/model-management.component.js.map +1 -1
  28. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +208 -226
  29. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
  30. package/dist/AI/components/prompts/prompt-filter-panel.component.js +97 -99
  31. package/dist/AI/components/prompts/prompt-filter-panel.component.js.map +1 -1
  32. package/dist/AI/components/prompts/prompt-management.component.js +381 -424
  33. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  34. package/dist/AI/components/prompts/prompt-version-control.component.js +173 -191
  35. package/dist/AI/components/prompts/prompt-version-control.component.js.map +1 -1
  36. package/dist/AI/components/system/system-config-filter-panel.component.js +85 -87
  37. package/dist/AI/components/system/system-config-filter-panel.component.js.map +1 -1
  38. package/dist/AI/components/system/system-configuration.component.js +86 -99
  39. package/dist/AI/components/system/system-configuration.component.js.map +1 -1
  40. package/dist/AI/components/widgets/kpi-card.component.d.ts +25 -0
  41. package/dist/AI/components/widgets/kpi-card.component.d.ts.map +1 -0
  42. package/dist/AI/components/widgets/kpi-card.component.js +163 -0
  43. package/dist/AI/components/widgets/kpi-card.component.js.map +1 -0
  44. package/dist/AI/components/widgets/live-execution-widget.component.d.ts +25 -0
  45. package/dist/AI/components/widgets/live-execution-widget.component.d.ts.map +1 -0
  46. package/dist/AI/components/widgets/live-execution-widget.component.js +298 -0
  47. package/dist/AI/components/widgets/live-execution-widget.component.js.map +1 -0
  48. package/dist/AI/index.d.ts +7 -0
  49. package/dist/AI/index.d.ts.map +1 -0
  50. package/dist/AI/index.js +9 -0
  51. package/dist/AI/index.js.map +1 -0
  52. package/dist/AI/services/ai-instrumentation.service.d.ts +109 -0
  53. package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -0
  54. package/dist/AI/services/ai-instrumentation.service.js +490 -0
  55. package/dist/AI/services/ai-instrumentation.service.js.map +1 -0
  56. package/dist/Actions/actions-management-dashboard.component.js +40 -41
  57. package/dist/Actions/actions-management-dashboard.component.js.map +1 -1
  58. package/dist/Actions/components/actions-list-view.component.js +117 -134
  59. package/dist/Actions/components/actions-list-view.component.js.map +1 -1
  60. package/dist/Actions/components/actions-overview.component.js +274 -296
  61. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  62. package/dist/Actions/components/categories-list-view.component.js +12 -14
  63. package/dist/Actions/components/categories-list-view.component.js.map +1 -1
  64. package/dist/Actions/components/code-management.component.js +12 -14
  65. package/dist/Actions/components/code-management.component.js.map +1 -1
  66. package/dist/Actions/components/entity-integration.component.js +12 -14
  67. package/dist/Actions/components/entity-integration.component.js.map +1 -1
  68. package/dist/Actions/components/execution-monitoring.component.js +238 -256
  69. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  70. package/dist/Actions/components/executions-list-view.component.js +12 -14
  71. package/dist/Actions/components/executions-list-view.component.js.map +1 -1
  72. package/dist/Actions/components/scheduled-actions.component.js +12 -14
  73. package/dist/Actions/components/scheduled-actions.component.js.map +1 -1
  74. package/dist/Actions/components/security-permissions.component.js +12 -14
  75. package/dist/Actions/components/security-permissions.component.js.map +1 -1
  76. package/dist/EntityAdmin/components/entity-details.component.js +105 -107
  77. package/dist/EntityAdmin/components/entity-details.component.js.map +1 -1
  78. package/dist/EntityAdmin/components/entity-filter-panel.component.js +100 -102
  79. package/dist/EntityAdmin/components/entity-filter-panel.component.js.map +1 -1
  80. package/dist/EntityAdmin/components/erd-composite.component.js +84 -100
  81. package/dist/EntityAdmin/components/erd-composite.component.js.map +1 -1
  82. package/dist/EntityAdmin/components/erd-diagram.component.js +50 -50
  83. package/dist/EntityAdmin/components/erd-diagram.component.js.map +1 -1
  84. package/dist/EntityAdmin/entity-admin-dashboard.component.js +45 -49
  85. package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
  86. package/dist/generic/base-dashboard.js +28 -40
  87. package/dist/generic/base-dashboard.js.map +1 -1
  88. package/dist/module.d.ts +16 -12
  89. package/dist/module.d.ts.map +1 -1
  90. package/dist/module.js +36 -15
  91. package/dist/module.js.map +1 -1
  92. package/package.json +6 -6
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import { Component, Output, EventEmitter } from '@angular/core';
11
2
  import { RunView, Metadata, LogError, LogStatus } from '@memberjunction/core';
12
3
  import { Subject, BehaviorSubject, combineLatest } from 'rxjs';
@@ -686,61 +677,62 @@ function PromptManagementComponent_Conditional_2_Template(rf, ctx) { if (rf & 1)
686
677
  i0.ɵɵconditional(ctx_r1.isEditing ? 57 : -1);
687
678
  } }
688
679
  export class PromptManagementComponent {
680
+ mjNotificationsService;
681
+ openEntityRecord = new EventEmitter();
682
+ stateChange = new EventEmitter();
683
+ // Data properties
684
+ prompts = [];
685
+ categories = [];
686
+ types = [];
687
+ templates = [];
688
+ templateContents = [];
689
+ promptsWithTemplates = [];
690
+ filteredPrompts = [];
691
+ // UI state
692
+ isLoading = false;
693
+ loadingMessage = 'Loading prompts...';
694
+ error = null;
695
+ currentView = 'list';
696
+ currentSubView = 'list';
697
+ selectedPrompt = null;
698
+ isEditing = false;
699
+ isDirty = false;
700
+ // Editor state
701
+ editorContent = '';
702
+ editorMode = 'nunjucks';
703
+ showPreview = false;
704
+ supportedLanguages = languages;
705
+ editorLanguage = 'jinja2';
706
+ // Category creation
707
+ newCategoryName = '';
708
+ showNewCategoryInput = false;
709
+ // Splitter panel width
710
+ promptDetailsPanelWidth = 300;
711
+ // Filter panel visibility
712
+ filterPanelVisible = true;
713
+ // Current filters object for the filter panel
714
+ currentFilters = {
715
+ searchTerm: '',
716
+ categoryId: 'all',
717
+ typeId: 'all',
718
+ status: 'all'
719
+ };
720
+ // Filter state
721
+ searchTerm$ = new BehaviorSubject('');
722
+ selectedCategory$ = new BehaviorSubject('all');
723
+ selectedType$ = new BehaviorSubject('all');
724
+ selectedStatus$ = new BehaviorSubject('all');
725
+ categoryOptions = [];
726
+ typeOptions = [];
727
+ statusOptions = [
728
+ { text: 'All Statuses', value: 'all' },
729
+ { text: 'Active', value: 'Active' },
730
+ { text: 'Pending', value: 'Pending' },
731
+ { text: 'Disabled', value: 'Disabled' }
732
+ ];
733
+ destroy$ = new Subject();
689
734
  constructor(mjNotificationsService) {
690
735
  this.mjNotificationsService = mjNotificationsService;
691
- this.openEntityRecord = new EventEmitter();
692
- this.stateChange = new EventEmitter();
693
- // Data properties
694
- this.prompts = [];
695
- this.categories = [];
696
- this.types = [];
697
- this.templates = [];
698
- this.templateContents = [];
699
- this.promptsWithTemplates = [];
700
- this.filteredPrompts = [];
701
- // UI state
702
- this.isLoading = false;
703
- this.loadingMessage = 'Loading prompts...';
704
- this.error = null;
705
- this.currentView = 'list';
706
- this.currentSubView = 'list';
707
- this.selectedPrompt = null;
708
- this.isEditing = false;
709
- this.isDirty = false;
710
- // Editor state
711
- this.editorContent = '';
712
- this.editorMode = 'nunjucks';
713
- this.showPreview = false;
714
- this.supportedLanguages = languages;
715
- this.editorLanguage = 'jinja2';
716
- // Category creation
717
- this.newCategoryName = '';
718
- this.showNewCategoryInput = false;
719
- // Splitter panel width
720
- this.promptDetailsPanelWidth = 300;
721
- // Filter panel visibility
722
- this.filterPanelVisible = true;
723
- // Current filters object for the filter panel
724
- this.currentFilters = {
725
- searchTerm: '',
726
- categoryId: 'all',
727
- typeId: 'all',
728
- status: 'all'
729
- };
730
- // Filter state
731
- this.searchTerm$ = new BehaviorSubject('');
732
- this.selectedCategory$ = new BehaviorSubject('all');
733
- this.selectedType$ = new BehaviorSubject('all');
734
- this.selectedStatus$ = new BehaviorSubject('all');
735
- this.categoryOptions = [];
736
- this.typeOptions = [];
737
- this.statusOptions = [
738
- { text: 'All Statuses', value: 'all' },
739
- { text: 'Active', value: 'Active' },
740
- { text: 'Pending', value: 'Pending' },
741
- { text: 'Disabled', value: 'Disabled' }
742
- ];
743
- this.destroy$ = new Subject();
744
736
  }
745
737
  toggleFilterPanel() {
746
738
  this.filterPanelVisible = !this.filterPanelVisible;
@@ -751,7 +743,7 @@ export class PromptManagementComponent {
751
743
  this.emitStateChange();
752
744
  }
753
745
  onFiltersChange(filters) {
754
- this.currentFilters = Object.assign({}, filters);
746
+ this.currentFilters = { ...filters };
755
747
  // Update the BehaviorSubjects to match the filter panel
756
748
  this.searchTerm$.next(filters.searchTerm);
757
749
  this.selectedCategory$.next(filters.categoryId);
@@ -791,132 +783,120 @@ export class PromptManagementComponent {
791
783
  this.applyFilters();
792
784
  });
793
785
  }
794
- loadData() {
795
- return __awaiter(this, void 0, void 0, function* () {
796
- try {
797
- this.isLoading = true;
798
- this.error = null;
799
- this.loadingMessage = 'Loading prompts and templates...';
800
- const [prompts, categories, types, templates, templateContents] = yield Promise.all([
801
- this.loadPrompts(),
802
- this.loadCategories(),
803
- this.loadTypes(),
804
- this.loadTemplates(),
805
- this.loadTemplateContents()
806
- ]);
807
- this.prompts = prompts;
808
- this.categories = categories;
809
- this.types = types;
810
- this.templates = templates;
811
- this.templateContents = templateContents;
812
- this.buildPromptTemplateRelationships();
813
- this.buildFilterOptions();
814
- this.applyFilters();
815
- LogStatus('Prompt management data loaded successfully');
816
- }
817
- catch (error) {
818
- this.error = 'Failed to load prompt data. Please try again.';
819
- LogError('Error loading prompt management data', undefined, error);
820
- }
821
- finally {
822
- this.isLoading = false;
823
- }
824
- });
786
+ async loadData() {
787
+ try {
788
+ this.isLoading = true;
789
+ this.error = null;
790
+ this.loadingMessage = 'Loading prompts and templates...';
791
+ const [prompts, categories, types, templates, templateContents] = await Promise.all([
792
+ this.loadPrompts(),
793
+ this.loadCategories(),
794
+ this.loadTypes(),
795
+ this.loadTemplates(),
796
+ this.loadTemplateContents()
797
+ ]);
798
+ this.prompts = prompts;
799
+ this.categories = categories;
800
+ this.types = types;
801
+ this.templates = templates;
802
+ this.templateContents = templateContents;
803
+ this.buildPromptTemplateRelationships();
804
+ this.buildFilterOptions();
805
+ this.applyFilters();
806
+ LogStatus('Prompt management data loaded successfully');
807
+ }
808
+ catch (error) {
809
+ this.error = 'Failed to load prompt data. Please try again.';
810
+ LogError('Error loading prompt management data', undefined, error);
811
+ }
812
+ finally {
813
+ this.isLoading = false;
814
+ }
825
815
  }
826
- loadPrompts() {
827
- return __awaiter(this, void 0, void 0, function* () {
828
- const rv = new RunView();
829
- const result = yield rv.RunView({
830
- EntityName: 'AI Prompts',
831
- ExtraFilter: '',
832
- OrderBy: 'Name',
833
- UserSearchString: '',
834
- IgnoreMaxRows: false,
835
- MaxRows: 1000
836
- });
837
- if (result && result.Success && result.Results) {
838
- return result.Results;
839
- }
840
- else {
841
- throw new Error('Failed to load AI prompts');
842
- }
816
+ async loadPrompts() {
817
+ const rv = new RunView();
818
+ const result = await rv.RunView({
819
+ EntityName: 'AI Prompts',
820
+ ExtraFilter: '',
821
+ OrderBy: 'Name',
822
+ UserSearchString: '',
823
+ IgnoreMaxRows: false,
824
+ MaxRows: 1000
843
825
  });
826
+ if (result && result.Success && result.Results) {
827
+ return result.Results;
828
+ }
829
+ else {
830
+ throw new Error('Failed to load AI prompts');
831
+ }
844
832
  }
845
- loadCategories() {
846
- return __awaiter(this, void 0, void 0, function* () {
847
- const rv = new RunView();
848
- const result = yield rv.RunView({
849
- EntityName: 'AI Prompt Categories',
850
- ExtraFilter: '',
851
- OrderBy: 'Name',
852
- UserSearchString: '',
853
- IgnoreMaxRows: false,
854
- MaxRows: 1000
855
- });
856
- if (result && result.Success && result.Results) {
857
- return result.Results;
858
- }
859
- else {
860
- throw new Error('Failed to load AI prompt categories');
861
- }
833
+ async loadCategories() {
834
+ const rv = new RunView();
835
+ const result = await rv.RunView({
836
+ EntityName: 'AI Prompt Categories',
837
+ ExtraFilter: '',
838
+ OrderBy: 'Name',
839
+ UserSearchString: '',
840
+ IgnoreMaxRows: false,
841
+ MaxRows: 1000
862
842
  });
843
+ if (result && result.Success && result.Results) {
844
+ return result.Results;
845
+ }
846
+ else {
847
+ throw new Error('Failed to load AI prompt categories');
848
+ }
863
849
  }
864
- loadTypes() {
865
- return __awaiter(this, void 0, void 0, function* () {
866
- const rv = new RunView();
867
- const result = yield rv.RunView({
868
- EntityName: 'AI Prompt Types',
869
- ExtraFilter: '',
870
- OrderBy: 'Name',
871
- UserSearchString: '',
872
- IgnoreMaxRows: false,
873
- MaxRows: 1000
874
- });
875
- if (result && result.Success && result.Results) {
876
- return result.Results;
877
- }
878
- else {
879
- throw new Error('Failed to load AI prompt types');
880
- }
850
+ async loadTypes() {
851
+ const rv = new RunView();
852
+ const result = await rv.RunView({
853
+ EntityName: 'AI Prompt Types',
854
+ ExtraFilter: '',
855
+ OrderBy: 'Name',
856
+ UserSearchString: '',
857
+ IgnoreMaxRows: false,
858
+ MaxRows: 1000
881
859
  });
860
+ if (result && result.Success && result.Results) {
861
+ return result.Results;
862
+ }
863
+ else {
864
+ throw new Error('Failed to load AI prompt types');
865
+ }
882
866
  }
883
- loadTemplates() {
884
- return __awaiter(this, void 0, void 0, function* () {
885
- const rv = new RunView();
886
- const result = yield rv.RunView({
887
- EntityName: 'Templates',
888
- ExtraFilter: '',
889
- OrderBy: 'Name',
890
- UserSearchString: '',
891
- IgnoreMaxRows: false,
892
- MaxRows: 1000
893
- });
894
- if (result && result.Success && result.Results) {
895
- return result.Results;
896
- }
897
- else {
898
- throw new Error('Failed to load templates');
899
- }
867
+ async loadTemplates() {
868
+ const rv = new RunView();
869
+ const result = await rv.RunView({
870
+ EntityName: 'Templates',
871
+ ExtraFilter: '',
872
+ OrderBy: 'Name',
873
+ UserSearchString: '',
874
+ IgnoreMaxRows: false,
875
+ MaxRows: 1000
900
876
  });
877
+ if (result && result.Success && result.Results) {
878
+ return result.Results;
879
+ }
880
+ else {
881
+ throw new Error('Failed to load templates');
882
+ }
901
883
  }
902
- loadTemplateContents() {
903
- return __awaiter(this, void 0, void 0, function* () {
904
- const rv = new RunView();
905
- const result = yield rv.RunView({
906
- EntityName: 'Template Contents',
907
- ExtraFilter: '',
908
- OrderBy: 'TemplateID',
909
- UserSearchString: '',
910
- IgnoreMaxRows: false,
911
- MaxRows: 1000
912
- });
913
- if (result && result.Success && result.Results) {
914
- return result.Results;
915
- }
916
- else {
917
- throw new Error('Failed to load template contents');
918
- }
884
+ async loadTemplateContents() {
885
+ const rv = new RunView();
886
+ const result = await rv.RunView({
887
+ EntityName: 'Template Contents',
888
+ ExtraFilter: '',
889
+ OrderBy: 'TemplateID',
890
+ UserSearchString: '',
891
+ IgnoreMaxRows: false,
892
+ MaxRows: 1000
919
893
  });
894
+ if (result && result.Success && result.Results) {
895
+ return result.Results;
896
+ }
897
+ else {
898
+ throw new Error('Failed to load template contents');
899
+ }
920
900
  }
921
901
  buildPromptTemplateRelationships() {
922
902
  this.promptsWithTemplates = this.prompts.map(prompt => {
@@ -949,13 +929,10 @@ export class PromptManagementComponent {
949
929
  // Apply search filter
950
930
  const searchTerm = this.searchTerm$.value.toLowerCase();
951
931
  if (searchTerm) {
952
- filtered = filtered.filter(item => {
953
- var _a, _b;
954
- return item.prompt.Name.toLowerCase().includes(searchTerm) ||
955
- (item.prompt.Description || '').toLowerCase().includes(searchTerm) ||
956
- (((_a = item.category) === null || _a === void 0 ? void 0 : _a.Name) || '').toLowerCase().includes(searchTerm) ||
957
- (((_b = item.template) === null || _b === void 0 ? void 0 : _b.Name) || '').toLowerCase().includes(searchTerm);
958
- });
932
+ filtered = filtered.filter(item => item.prompt.Name.toLowerCase().includes(searchTerm) ||
933
+ (item.prompt.Description || '').toLowerCase().includes(searchTerm) ||
934
+ (item.category?.Name || '').toLowerCase().includes(searchTerm) ||
935
+ (item.template?.Name || '').toLowerCase().includes(searchTerm));
959
936
  }
960
937
  // Apply category filter
961
938
  const categoryId = this.selectedCategory$.value;
@@ -989,64 +966,59 @@ export class PromptManagementComponent {
989
966
  }
990
967
  // Navigation methods
991
968
  viewPrompt(promptWithTemplate) {
992
- var _a;
993
969
  this.selectedPrompt = promptWithTemplate;
994
970
  this.currentView = 'editor';
995
971
  this.isEditing = false;
996
972
  this.isDirty = false;
997
- this.editorContent = ((_a = promptWithTemplate.templateContent) === null || _a === void 0 ? void 0 : _a.TemplateText) || '';
973
+ this.editorContent = promptWithTemplate.templateContent?.TemplateText || '';
998
974
  this.emitStateChange();
999
975
  }
1000
976
  editPrompt(promptWithTemplate) {
1001
- var _a;
1002
977
  this.selectedPrompt = promptWithTemplate;
1003
978
  this.currentView = 'editor';
1004
979
  this.isEditing = true;
1005
980
  this.isDirty = false;
1006
- this.editorContent = ((_a = promptWithTemplate.templateContent) === null || _a === void 0 ? void 0 : _a.TemplateText) || '';
981
+ this.editorContent = promptWithTemplate.templateContent?.TemplateText || '';
1007
982
  this.emitStateChange();
1008
983
  }
1009
- createNewCategory() {
1010
- return __awaiter(this, void 0, void 0, function* () {
1011
- var _a;
1012
- if (!this.newCategoryName.trim())
1013
- return null;
1014
- try {
1015
- const md = new Metadata();
1016
- if (!md)
1017
- throw new Error('Metadata provider not available');
1018
- const category = yield md.GetEntityObject('AI Prompt Categories', md.CurrentUser);
1019
- category.Name = this.newCategoryName.trim();
1020
- category.Description = 'Category created during prompt editing';
1021
- const result = yield category.Save();
1022
- if (result) {
1023
- LogStatus('Category created successfully');
1024
- this.mjNotificationsService.CreateSimpleNotification('Category created successfully', 'success', 2000);
1025
- yield this.loadCategories();
1026
- this.buildFilterOptions();
1027
- // Update filter panel categories
1028
- this.updateFilterPanelCategories();
1029
- this.newCategoryName = '';
1030
- this.showNewCategoryInput = false;
1031
- return category.ID;
1032
- }
1033
- else {
1034
- // Handle save failure
1035
- const errorMessage = ((_a = category.LatestResult) === null || _a === void 0 ? void 0 : _a.Message) || 'Unknown error occurred while saving category';
1036
- console.error('Category save failed:', category.LatestResult);
1037
- LogError('Category save failed', undefined, category.LatestResult);
1038
- this.mjNotificationsService.CreateSimpleNotification(errorMessage, 'error', 3500);
1039
- this.error = `Failed to create category: ${errorMessage}`;
1040
- return null;
1041
- }
984
+ async createNewCategory() {
985
+ if (!this.newCategoryName.trim())
986
+ return null;
987
+ try {
988
+ const md = new Metadata();
989
+ if (!md)
990
+ throw new Error('Metadata provider not available');
991
+ const category = await md.GetEntityObject('AI Prompt Categories', md.CurrentUser);
992
+ category.Name = this.newCategoryName.trim();
993
+ category.Description = 'Category created during prompt editing';
994
+ const result = await category.Save();
995
+ if (result) {
996
+ LogStatus('Category created successfully');
997
+ this.mjNotificationsService.CreateSimpleNotification('Category created successfully', 'success', 2000);
998
+ await this.loadCategories();
999
+ this.buildFilterOptions();
1000
+ // Update filter panel categories
1001
+ this.updateFilterPanelCategories();
1002
+ this.newCategoryName = '';
1003
+ this.showNewCategoryInput = false;
1004
+ return category.ID;
1042
1005
  }
1043
- catch (error) {
1044
- LogError('Error creating category', undefined, error);
1045
- this.mjNotificationsService.CreateSimpleNotification('Failed to create category. Please try again.', 'error', 3500);
1046
- this.error = 'Failed to create category. Please try again.';
1006
+ else {
1007
+ // Handle save failure
1008
+ const errorMessage = category.LatestResult?.Message || 'Unknown error occurred while saving category';
1009
+ console.error('Category save failed:', category.LatestResult);
1010
+ LogError('Category save failed', undefined, category.LatestResult);
1011
+ this.mjNotificationsService.CreateSimpleNotification(errorMessage, 'error', 3500);
1012
+ this.error = `Failed to create category: ${errorMessage}`;
1047
1013
  return null;
1048
1014
  }
1049
- });
1015
+ }
1016
+ catch (error) {
1017
+ LogError('Error creating category', undefined, error);
1018
+ this.mjNotificationsService.CreateSimpleNotification('Failed to create category. Please try again.', 'error', 3500);
1019
+ this.error = 'Failed to create category. Please try again.';
1020
+ return null;
1021
+ }
1050
1022
  }
1051
1023
  updateFilterPanelCategories() {
1052
1024
  // Trigger update of filter panel categories when new ones are created
@@ -1062,56 +1034,50 @@ export class PromptManagementComponent {
1062
1034
  this.isDirty = true;
1063
1035
  }
1064
1036
  }
1065
- onCreateNewCategoryKeyup(event) {
1066
- return __awaiter(this, void 0, void 0, function* () {
1067
- if (event.key === 'Enter') {
1068
- yield this.createAndSelectNewCategory();
1069
- }
1070
- else if (event.key === 'Escape') {
1071
- this.newCategoryName = '';
1072
- this.showNewCategoryInput = false;
1073
- }
1074
- });
1037
+ async onCreateNewCategoryKeyup(event) {
1038
+ if (event.key === 'Enter') {
1039
+ await this.createAndSelectNewCategory();
1040
+ }
1041
+ else if (event.key === 'Escape') {
1042
+ this.newCategoryName = '';
1043
+ this.showNewCategoryInput = false;
1044
+ }
1075
1045
  }
1076
1046
  cancelNewCategory() {
1077
1047
  this.newCategoryName = '';
1078
1048
  this.showNewCategoryInput = false;
1079
1049
  }
1080
- createAndSelectNewCategory() {
1081
- return __awaiter(this, void 0, void 0, function* () {
1082
- const newCategoryId = yield this.createNewCategory();
1083
- if (newCategoryId && this.selectedPrompt) {
1084
- this.selectedPrompt.prompt.CategoryID = newCategoryId;
1085
- this.isDirty = true;
1086
- }
1087
- });
1050
+ async createAndSelectNewCategory() {
1051
+ const newCategoryId = await this.createNewCategory();
1052
+ if (newCategoryId && this.selectedPrompt) {
1053
+ this.selectedPrompt.prompt.CategoryID = newCategoryId;
1054
+ this.isDirty = true;
1055
+ }
1088
1056
  }
1089
- createNewPrompt() {
1090
- return __awaiter(this, void 0, void 0, function* () {
1091
- // Create a new prompt structure
1092
- const md = new Metadata();
1093
- if (!md)
1094
- return;
1095
- const promptEntity = yield md.GetEntityObject('AI Prompts', md.CurrentUser);
1096
- promptEntity.Name = 'New Prompt';
1097
- promptEntity.Description = '';
1098
- promptEntity.CategoryID = '';
1099
- promptEntity.TypeID = '';
1100
- promptEntity.Status = 'Pending';
1101
- promptEntity.TemplateID = '';
1102
- const newPrompt = {
1103
- prompt: promptEntity,
1104
- template: null,
1105
- templateContent: null,
1106
- category: null,
1107
- type: null
1108
- };
1109
- this.selectedPrompt = newPrompt;
1110
- this.currentView = 'editor';
1111
- this.isEditing = true;
1112
- this.isDirty = false;
1113
- this.editorContent = '';
1114
- });
1057
+ async createNewPrompt() {
1058
+ // Create a new prompt structure
1059
+ const md = new Metadata();
1060
+ if (!md)
1061
+ return;
1062
+ const promptEntity = await md.GetEntityObject('AI Prompts', md.CurrentUser);
1063
+ promptEntity.Name = 'New Prompt';
1064
+ promptEntity.Description = '';
1065
+ promptEntity.CategoryID = '';
1066
+ promptEntity.TypeID = '';
1067
+ promptEntity.Status = 'Pending';
1068
+ promptEntity.TemplateID = '';
1069
+ const newPrompt = {
1070
+ prompt: promptEntity,
1071
+ template: null,
1072
+ templateContent: null,
1073
+ category: null,
1074
+ type: null
1075
+ };
1076
+ this.selectedPrompt = newPrompt;
1077
+ this.currentView = 'editor';
1078
+ this.isEditing = true;
1079
+ this.isDirty = false;
1080
+ this.editorContent = '';
1115
1081
  }
1116
1082
  backToList() {
1117
1083
  if (this.isDirty) {
@@ -1154,11 +1120,10 @@ export class PromptManagementComponent {
1154
1120
  }
1155
1121
  }
1156
1122
  emitStateChange() {
1157
- var _a;
1158
1123
  const state = {
1159
1124
  currentView: this.currentView,
1160
1125
  currentSubView: this.currentSubView,
1161
- selectedPromptId: ((_a = this.selectedPrompt) === null || _a === void 0 ? void 0 : _a.prompt.ID) || null,
1126
+ selectedPromptId: this.selectedPrompt?.prompt.ID || null,
1162
1127
  isEditing: this.isEditing,
1163
1128
  promptDetailsPanelWidth: this.promptDetailsPanelWidth,
1164
1129
  filterPanelVisible: this.filterPanelVisible,
@@ -1169,160 +1134,154 @@ export class PromptManagementComponent {
1169
1134
  };
1170
1135
  this.stateChange.emit(state);
1171
1136
  }
1172
- savePrompt() {
1173
- return __awaiter(this, void 0, void 0, function* () {
1174
- var _a, _b, _c, _d, _e, _f;
1175
- if (!this.selectedPrompt || !this.isEditing)
1176
- return;
1177
- try {
1178
- this.isLoading = true;
1179
- const md = new Metadata();
1180
- if (!md)
1181
- throw new Error('Metadata provider not available');
1182
- // Save or create template content first
1183
- let templateContentId = (_a = this.selectedPrompt.templateContent) === null || _a === void 0 ? void 0 : _a.ID;
1184
- if (!templateContentId) {
1185
- // Create new template content
1186
- const templateContent = yield md.GetEntityObject('Template Contents', md.CurrentUser);
1187
- templateContent.TemplateText = this.editorContent;
1188
- // make sure the template engine metadata is set correctly
1189
- yield TemplateEngineBase.Instance.Config(false);
1190
- const tcType = TemplateEngineBase.Instance.TemplateContentTypes.find(tct => tct.Name.trim().toLowerCase() === 'text');
1191
- if (!tcType) {
1192
- throw new Error('Template content type "text" not found');
1193
- }
1194
- templateContent.TypeID = tcType.ID;
1195
- templateContent.Priority = 0; // Default priority
1196
- // We need to link to a template, create one if needed
1197
- if (!this.selectedPrompt.template) {
1198
- const template = yield md.GetEntityObject('Templates', md.CurrentUser);
1199
- template.Name = this.selectedPrompt.prompt.Name + ' Template';
1200
- template.Description = 'Template for ' + this.selectedPrompt.prompt.Name;
1201
- template.UserID = md.CurrentUser.ID;
1202
- if (yield template.Save()) {
1203
- templateContent.TemplateID = template.ID;
1204
- this.selectedPrompt.template = template;
1205
- }
1206
- else {
1207
- // we have an error saving the template
1208
- const errorMessage = ((_b = template.LatestResult) === null || _b === void 0 ? void 0 : _b.Message) || 'Unknown error occurred while saving template';
1209
- console.error('Template save failed:', errorMessage);
1210
- LogError('Template save failed', undefined, errorMessage);
1211
- this.mjNotificationsService.CreateSimpleNotification(errorMessage, 'error', 3500);
1212
- this.error = `Failed to save template: ${errorMessage}`;
1213
- return;
1214
- }
1215
- }
1216
- else {
1217
- templateContent.TemplateID = this.selectedPrompt.template.ID;
1218
- }
1219
- if (yield templateContent.Save()) {
1220
- templateContentId = templateContent.ID;
1221
- this.selectedPrompt.templateContent = templateContent;
1137
+ async savePrompt() {
1138
+ if (!this.selectedPrompt || !this.isEditing)
1139
+ return;
1140
+ try {
1141
+ this.isLoading = true;
1142
+ const md = new Metadata();
1143
+ if (!md)
1144
+ throw new Error('Metadata provider not available');
1145
+ // Save or create template content first
1146
+ let templateContentId = this.selectedPrompt.templateContent?.ID;
1147
+ if (!templateContentId) {
1148
+ // Create new template content
1149
+ const templateContent = await md.GetEntityObject('Template Contents', md.CurrentUser);
1150
+ templateContent.TemplateText = this.editorContent;
1151
+ // make sure the template engine metadata is set correctly
1152
+ await TemplateEngineBase.Instance.Config(false);
1153
+ const tcType = TemplateEngineBase.Instance.TemplateContentTypes.find(tct => tct.Name.trim().toLowerCase() === 'text');
1154
+ if (!tcType) {
1155
+ throw new Error('Template content type "text" not found');
1156
+ }
1157
+ templateContent.TypeID = tcType.ID;
1158
+ templateContent.Priority = 0; // Default priority
1159
+ // We need to link to a template, create one if needed
1160
+ if (!this.selectedPrompt.template) {
1161
+ const template = await md.GetEntityObject('Templates', md.CurrentUser);
1162
+ template.Name = this.selectedPrompt.prompt.Name + ' Template';
1163
+ template.Description = 'Template for ' + this.selectedPrompt.prompt.Name;
1164
+ template.UserID = md.CurrentUser.ID;
1165
+ if (await template.Save()) {
1166
+ templateContent.TemplateID = template.ID;
1167
+ this.selectedPrompt.template = template;
1222
1168
  }
1223
1169
  else {
1224
- // Handle save failure
1225
- const errorMessage = ((_c = templateContent.LatestResult) === null || _c === void 0 ? void 0 : _c.Message) || 'Unknown error occurred while saving template content';
1226
- console.error('Template content save failed:', errorMessage);
1227
- LogError('Template content save failed', undefined, errorMessage);
1170
+ // we have an error saving the template
1171
+ const errorMessage = template.LatestResult?.Message || 'Unknown error occurred while saving template';
1172
+ console.error('Template save failed:', errorMessage);
1173
+ LogError('Template save failed', undefined, errorMessage);
1228
1174
  this.mjNotificationsService.CreateSimpleNotification(errorMessage, 'error', 3500);
1229
- this.error = `Failed to save template content: ${errorMessage}`;
1175
+ this.error = `Failed to save template: ${errorMessage}`;
1230
1176
  return;
1231
1177
  }
1232
1178
  }
1233
1179
  else {
1234
- // Update existing template content
1235
- const templateContent = yield md.GetEntityObject('Template Contents');
1236
- yield templateContent.Load(templateContentId);
1237
- templateContent.TemplateText = this.editorContent;
1238
- if (!(yield templateContent.Save())) {
1239
- // Handle save failure
1240
- const errorMessage = ((_d = templateContent.LatestResult) === null || _d === void 0 ? void 0 : _d.Message) || 'Unknown error occurred while saving template content';
1241
- console.error('Template content update failed:', errorMessage);
1242
- LogError('Template content update failed', undefined, errorMessage);
1243
- this.mjNotificationsService.CreateSimpleNotification(errorMessage, 'error', 3500);
1244
- this.error = `Failed to update template content: ${errorMessage}`;
1245
- return;
1246
- }
1180
+ templateContent.TemplateID = this.selectedPrompt.template.ID;
1247
1181
  }
1248
- // Save the prompt
1249
- let prompt;
1250
- if (this.selectedPrompt.prompt.ID) {
1251
- // Update existing prompt
1252
- prompt = yield md.GetEntityObject('AI Prompts', md.CurrentUser);
1253
- yield prompt.Load(this.selectedPrompt.prompt.ID);
1182
+ if (await templateContent.Save()) {
1183
+ templateContentId = templateContent.ID;
1184
+ this.selectedPrompt.templateContent = templateContent;
1254
1185
  }
1255
1186
  else {
1256
- // Create new prompt
1257
- prompt = yield md.GetEntityObject('AI Prompts', md.CurrentUser);
1258
- }
1259
- // Update prompt properties
1260
- prompt.Name = this.selectedPrompt.prompt.Name;
1261
- prompt.Description = this.selectedPrompt.prompt.Description;
1262
- prompt.CategoryID = this.selectedPrompt.prompt.CategoryID;
1263
- prompt.TypeID = this.selectedPrompt.prompt.TypeID;
1264
- prompt.Status = this.selectedPrompt.prompt.Status;
1265
- prompt.TemplateID = ((_e = this.selectedPrompt.template) === null || _e === void 0 ? void 0 : _e.ID) || '';
1266
- const promptResult = yield prompt.Save();
1267
- if (promptResult) {
1268
- this.isDirty = false;
1269
- this.isEditing = false;
1270
- LogStatus('Prompt saved successfully');
1271
- // Reload data to get the updated state
1272
- yield this.loadData();
1273
- // Find and select the updated prompt
1274
- this.selectedPrompt = this.promptsWithTemplates.find(p => p.prompt.ID === prompt.ID) || null;
1187
+ // Handle save failure
1188
+ const errorMessage = templateContent.LatestResult?.Message || 'Unknown error occurred while saving template content';
1189
+ console.error('Template content save failed:', errorMessage);
1190
+ LogError('Template content save failed', undefined, errorMessage);
1191
+ this.mjNotificationsService.CreateSimpleNotification(errorMessage, 'error', 3500);
1192
+ this.error = `Failed to save template content: ${errorMessage}`;
1193
+ return;
1275
1194
  }
1276
- else {
1195
+ }
1196
+ else {
1197
+ // Update existing template content
1198
+ const templateContent = await md.GetEntityObject('Template Contents');
1199
+ await templateContent.Load(templateContentId);
1200
+ templateContent.TemplateText = this.editorContent;
1201
+ if (!await templateContent.Save()) {
1277
1202
  // Handle save failure
1278
- const errorMessage = ((_f = prompt.LatestResult) === null || _f === void 0 ? void 0 : _f.Message) || 'Unknown error occurred while saving prompt';
1279
- console.error('Prompt save failed:', errorMessage);
1280
- LogError('Prompt save failed', undefined, errorMessage);
1203
+ const errorMessage = templateContent.LatestResult?.Message || 'Unknown error occurred while saving template content';
1204
+ console.error('Template content update failed:', errorMessage);
1205
+ LogError('Template content update failed', undefined, errorMessage);
1281
1206
  this.mjNotificationsService.CreateSimpleNotification(errorMessage, 'error', 3500);
1282
- this.error = `Failed to save prompt: ${errorMessage}`;
1207
+ this.error = `Failed to update template content: ${errorMessage}`;
1208
+ return;
1283
1209
  }
1284
1210
  }
1285
- catch (error) {
1286
- LogError('Error saving prompt', undefined, error);
1287
- this.error = 'Failed to save prompt. Please try again.';
1211
+ // Save the prompt
1212
+ let prompt;
1213
+ if (this.selectedPrompt.prompt.ID) {
1214
+ // Update existing prompt
1215
+ prompt = await md.GetEntityObject('AI Prompts', md.CurrentUser);
1216
+ await prompt.Load(this.selectedPrompt.prompt.ID);
1288
1217
  }
1289
- finally {
1290
- this.isLoading = false;
1218
+ else {
1219
+ // Create new prompt
1220
+ prompt = await md.GetEntityObject('AI Prompts', md.CurrentUser);
1291
1221
  }
1292
- });
1293
- }
1294
- deletePrompt(promptWithTemplate) {
1295
- return __awaiter(this, void 0, void 0, function* () {
1296
- var _a;
1297
- if (!promptWithTemplate.prompt.ID)
1298
- return;
1299
- const confirm = window.confirm(`Are you sure you want to delete "${promptWithTemplate.prompt.Name}"?`);
1300
- if (!confirm)
1301
- return;
1302
- try {
1303
- this.isLoading = true;
1304
- const md = Metadata.Provider;
1305
- if (!md)
1306
- throw new Error('Metadata provider not available');
1307
- const prompt = yield md.GetEntityObject('AI Prompts', md.CurrentUser);
1308
- yield prompt.Load(promptWithTemplate.prompt.ID);
1309
- const result = yield prompt.Delete();
1310
- if (result) {
1311
- LogStatus('Prompt deleted successfully');
1312
- yield this.loadData();
1313
- if (((_a = this.selectedPrompt) === null || _a === void 0 ? void 0 : _a.prompt.ID) === promptWithTemplate.prompt.ID) {
1314
- this.backToList();
1315
- }
1316
- }
1222
+ // Update prompt properties
1223
+ prompt.Name = this.selectedPrompt.prompt.Name;
1224
+ prompt.Description = this.selectedPrompt.prompt.Description;
1225
+ prompt.CategoryID = this.selectedPrompt.prompt.CategoryID;
1226
+ prompt.TypeID = this.selectedPrompt.prompt.TypeID;
1227
+ prompt.Status = this.selectedPrompt.prompt.Status;
1228
+ prompt.TemplateID = this.selectedPrompt.template?.ID || '';
1229
+ const promptResult = await prompt.Save();
1230
+ if (promptResult) {
1231
+ this.isDirty = false;
1232
+ this.isEditing = false;
1233
+ LogStatus('Prompt saved successfully');
1234
+ // Reload data to get the updated state
1235
+ await this.loadData();
1236
+ // Find and select the updated prompt
1237
+ this.selectedPrompt = this.promptsWithTemplates.find(p => p.prompt.ID === prompt.ID) || null;
1317
1238
  }
1318
- catch (error) {
1319
- LogError('Error deleting prompt', undefined, error);
1320
- this.error = 'Failed to delete prompt. Please try again.';
1239
+ else {
1240
+ // Handle save failure
1241
+ const errorMessage = prompt.LatestResult?.Message || 'Unknown error occurred while saving prompt';
1242
+ console.error('Prompt save failed:', errorMessage);
1243
+ LogError('Prompt save failed', undefined, errorMessage);
1244
+ this.mjNotificationsService.CreateSimpleNotification(errorMessage, 'error', 3500);
1245
+ this.error = `Failed to save prompt: ${errorMessage}`;
1321
1246
  }
1322
- finally {
1323
- this.isLoading = false;
1247
+ }
1248
+ catch (error) {
1249
+ LogError('Error saving prompt', undefined, error);
1250
+ this.error = 'Failed to save prompt. Please try again.';
1251
+ }
1252
+ finally {
1253
+ this.isLoading = false;
1254
+ }
1255
+ }
1256
+ async deletePrompt(promptWithTemplate) {
1257
+ if (!promptWithTemplate.prompt.ID)
1258
+ return;
1259
+ const confirm = window.confirm(`Are you sure you want to delete "${promptWithTemplate.prompt.Name}"?`);
1260
+ if (!confirm)
1261
+ return;
1262
+ try {
1263
+ this.isLoading = true;
1264
+ const md = Metadata.Provider;
1265
+ if (!md)
1266
+ throw new Error('Metadata provider not available');
1267
+ const prompt = await md.GetEntityObject('AI Prompts', md.CurrentUser);
1268
+ await prompt.Load(promptWithTemplate.prompt.ID);
1269
+ const result = await prompt.Delete();
1270
+ if (result) {
1271
+ LogStatus('Prompt deleted successfully');
1272
+ await this.loadData();
1273
+ if (this.selectedPrompt?.prompt.ID === promptWithTemplate.prompt.ID) {
1274
+ this.backToList();
1275
+ }
1324
1276
  }
1325
- });
1277
+ }
1278
+ catch (error) {
1279
+ LogError('Error deleting prompt', undefined, error);
1280
+ this.error = 'Failed to delete prompt. Please try again.';
1281
+ }
1282
+ finally {
1283
+ this.isLoading = false;
1284
+ }
1326
1285
  }
1327
1286
  // Utility methods
1328
1287
  getStatusColor(status) {
@@ -1337,16 +1296,14 @@ export class PromptManagementComponent {
1337
1296
  return 'fa-solid fa-comment-dots';
1338
1297
  }
1339
1298
  getCategoryName(categoryId) {
1340
- var _a;
1341
1299
  if (!categoryId || categoryId === '')
1342
1300
  return 'No Category';
1343
- return ((_a = this.categories.find(c => c.ID === categoryId)) === null || _a === void 0 ? void 0 : _a.Name) || 'Unknown Category';
1301
+ return this.categories.find(c => c.ID === categoryId)?.Name || 'Unknown Category';
1344
1302
  }
1345
1303
  getTypeName(typeId) {
1346
- var _a;
1347
1304
  if (!typeId || typeId === '')
1348
1305
  return 'No Type';
1349
- return ((_a = this.types.find(t => t.ID === typeId)) === null || _a === void 0 ? void 0 : _a.Name) || 'Unknown Type';
1306
+ return this.types.find(t => t.ID === typeId)?.Name || 'Unknown Type';
1350
1307
  }
1351
1308
  setSubView(subView) {
1352
1309
  this.currentSubView = subView;
@@ -1369,19 +1326,19 @@ export class PromptManagementComponent {
1369
1326
  get promptsForMatrix() {
1370
1327
  return this.filteredPrompts.map(p => p.prompt);
1371
1328
  }
1329
+ static ɵfac = function PromptManagementComponent_Factory(t) { return new (t || PromptManagementComponent)(i0.ɵɵdirectiveInject(i1.MJNotificationService)); };
1330
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PromptManagementComponent, selectors: [["app-prompt-management"]], outputs: { openEntityRecord: "openEntityRecord", stateChange: "stateChange" }, decls: 3, vars: 4, consts: [["newCategoryInput", ""], ["mjFillContainer", "", 1, "prompt-management-container", 3, "rightMargin", "bottomMargin"], [1, "list-view"], [1, "editor-view"], [1, "dashboard-header"], [1, "header-info"], ["type", "button", "title", "Toggle Filters", 1, "filter-toggle-btn", 3, "click"], [1, "fa-solid", "fa-filter"], [1, "prompt-count"], [1, "header-controls"], ["type", "button", 1, "control-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "sub-navigation"], ["type", "button", "title", "List View", 1, "sub-nav-btn", 3, "click"], [1, "fa-solid", "fa-list"], ["type", "button", "title", "Priority Matrix", 1, "sub-nav-btn", 3, "click"], [1, "fa-solid", "fa-th"], ["type", "button", "title", "Version Control", 1, "sub-nav-btn", 3, "click"], [1, "fa-solid", "fa-code-branch"], [1, "main-content"], ["orientation", "horizontal", "mjFillContainer", "", 1, "main-splitter"], ["mjFillContainer", "", 3, "selectedPrompts"], ["mjFillContainer", "", 3, "prompt"], ["orientation", "horizontal", "mjFillContainer", "", 1, "main-splitter", 3, "layoutChange"], [3, "size", "collapsible", "resizable", "scrollable", "hidden"], [3, "filtersChange", "filterChange", "resetFilters", "closePanel", "prompts", "filteredPrompts", "categories", "types", "filters"], [3, "resizable", "scrollable"], [1, "prompts-content"], [1, "loading-container"], [1, "error-container"], [1, "prompts-list"], [1, "loading-content"], [1, "loading-spinner"], [1, "spinner-ring"], [1, "loading-text"], [1, "error-message"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "empty-state"], [1, "prompts-grid"], [1, "fa-solid", "fa-comment-dots"], [1, "prompt-card"], [1, "prompt-card", 3, "click"], [1, "card-header"], [1, "prompt-info"], [1, "prompt-icon"], [1, "prompt-details"], [1, "prompt-name"], [1, "prompt-meta"], [1, "prompt-category"], [1, "prompt-type"], [1, "card-body"], [1, "prompt-description"], [1, "prompt-description", "text-muted"], [1, "template-info"], [1, "template-item", "text-muted"], [1, "card-actions", 3, "click"], ["type", "button", 1, "action-btn", 3, "click"], [1, "fa-solid", "fa-eye"], ["type", "button", 1, "action-btn", "action-btn-primary", 3, "click"], [1, "fa-solid", "fa-edit"], ["type", "button", 1, "action-btn", "action-btn-danger", 3, "click"], [1, "fa-solid", "fa-trash"], [1, "template-item"], [1, "fa-solid", "fa-file-code"], [1, "template-content-info"], ["mjFillContainer", "", 3, "promptSelected", "selectedPrompts"], ["mjFillContainer", "", 3, "versionSelected", "prompt"], [1, "editor-header"], [1, "breadcrumb-section"], ["type", "button", 1, "back-btn", 3, "click"], [1, "fa-solid", "fa-arrow-left"], [1, "editor-title"], [3, "class"], [1, "editor-actions"], ["type", "button", 1, "control-btn"], [1, "editor-content"], ["orientation", "horizontal", "mjFillContainer", "", 1, "editor-splitter", 3, "layoutChange"], [3, "collapsible", "resizable", "scrollable"], [1, "prompt-details-panel"], [1, "form-field"], [1, "field-label"], ["type", "text", "placeholder", "Enter prompt name", 1, "field-input", 3, "ngModel"], [1, "field-value"], ["placeholder", "Enter prompt description", 1, "field-textarea", 3, "ngModel"], [1, "field-select", 3, "ngModel"], [1, "template-info-section"], [1, "template-editor-panel"], [1, "editor-info"], [1, "editor-badge", "editor-badge-secondary"], [1, "editor-container"], [3, "change", "value", "languages", "language", "placeholder", "lineWrapping", "highlightWhitespace", "indentWithTab", "indentUnit", "readonly"], [1, "editor-help"], [1, "fa-solid", "fa-times"], ["type", "button", 1, "control-btn", "control-btn-primary", 3, "click", "disabled"], [1, "loading-spinner-sm"], [1, "fa-solid", "fa-save"], ["type", "text", "placeholder", "Enter prompt name", 1, "field-input", 3, "ngModelChange", "input", "ngModel"], ["placeholder", "Enter prompt description", 1, "field-textarea", 3, "ngModelChange", "input", "ngModel"], [1, "new-category-container"], [1, "field-select", 3, "ngModelChange", "ngModel"], ["value", ""], [3, "value"], ["value", "new", 1, "new-category-option"], ["type", "text", "placeholder", "Enter new category name", 1, "field-input", 3, "ngModelChange", "keyup", "ngModel"], [1, "new-category-actions"], [1, "fa-solid", "fa-check"], [1, "field-select", 3, "ngModelChange", "change", "ngModel"], ["value", "Active"], ["value", "Pending"], ["value", "Disabled"], [1, "template-details"], [1, "editor-badge", "editor-badge-info"], [1, "editor-badge", "editor-badge-warning"], [1, "help-section"], [1, "syntax-examples"], [1, "syntax-item"]], template: function PromptManagementComponent_Template(rf, ctx) { if (rf & 1) {
1331
+ i0.ɵɵelementStart(0, "div", 1);
1332
+ i0.ɵɵtemplate(1, PromptManagementComponent_Conditional_1_Template, 27, 11, "div", 2)(2, PromptManagementComponent_Conditional_2_Template, 58, 25, "div", 3);
1333
+ i0.ɵɵelementEnd();
1334
+ } if (rf & 2) {
1335
+ i0.ɵɵproperty("rightMargin", 8)("bottomMargin", 8);
1336
+ i0.ɵɵadvance();
1337
+ i0.ɵɵconditional(ctx.currentView === "list" ? 1 : -1);
1338
+ i0.ɵɵadvance();
1339
+ i0.ɵɵconditional(ctx.currentView === "editor" && ctx.selectedPrompt ? 2 : -1);
1340
+ } }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.SplitterComponent, i3.SplitterPaneComponent, i4.FillContainer, i5.CodeEditorComponent, i6.PromptFilterPanelComponent, i7.ModelPromptPriorityMatrixComponent, i8.PromptVersionControlComponent], styles: [".prompt-management-container[_ngcontent-%COMP%] {\n overflow: hidden;\n padding: 4px;\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.dashboard-header[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-shrink: 0;\n \n .header-info {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n \n .filter-toggle-btn {\n padding: 6px 10px;\n border: 1px solid #ddd;\n border-radius: 4px;\n background: white;\n cursor: pointer;\n font-size: 11px;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.2s;\n color: #555;\n \n &:hover {\n background-color: #f0f0f0;\n border-color: #2196f3;\n color: #2196f3;\n }\n \n .fa-solid {\n font-size: 10px;\n }\n }\n \n .prompt-count {\n font-size: 12px;\n color: #2196f3;\n font-weight: 600;\n background: rgba(33, 150, 243, 0.1);\n padding: 4px 8px;\n border-radius: 4px;\n border: 1px solid rgba(33, 150, 243, 0.2);\n }\n \n .header-controls {\n display: flex;\n gap: 8px;\n \n .control-btn {\n padding: 8px 12px;\n border: 1px solid #ccc;\n border-radius: 4px;\n background: white;\n cursor: pointer;\n font-size: 12px;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.2s;\n \n &:hover {\n background-color: #f0f0f0;\n border-color: #2196f3;\n }\n \n &.active {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n }\n \n &.control-btn-primary {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n \n &:hover {\n background-color: #1976d2;\n }\n }\n \n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n \n &:hover {\n background-color: white;\n border-color: #ccc;\n }\n }\n \n .fa-solid {\n font-size: 14px;\n }\n }\n }\n}\n\n//[_ngcontent-%COMP%] Filters[_ngcontent-%COMP%] now[_ngcontent-%COMP%] handled[_ngcontent-%COMP%] by[_ngcontent-%COMP%] filter[_ngcontent-%COMP%] panel[_ngcontent-%COMP%] component\n\n.loading-container[_ngcontent-%COMP%], .error-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n background: #fafafa;\n flex: 1;\n \n p {\n color: #666;\n font-size: 14px;\n }\n}\n\n.error-message[_ngcontent-%COMP%] {\n color: #d32f2f;\n font-weight: 500;\n \n .fa-solid {\n margin-right: 8px;\n }\n}\n\n.loading-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 16px;\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n display: inline-block;\n position: relative;\n width: 40px;\n height: 40px;\n \n .spinner-ring {\n box-sizing: border-box;\n display: block;\n position: absolute;\n width: 32px;\n height: 32px;\n margin: 4px;\n border: 3px solid #2196f3;\n border-radius: 50%;\n animation: _ngcontent-%COMP%_loading-spin 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n border-color: #2196f3 transparent transparent transparent;\n \n &:nth-child(1) { animation-delay: -0.45s; }\n &:nth-child(2) { animation-delay: -0.3s; }\n &:nth-child(3) { animation-delay: -0.15s; }\n }\n}\n\n@keyframes _ngcontent-%COMP%_loading-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 60px 20px;\n color: #666;\n \n .fa-solid {\n font-size: 48px;\n margin-bottom: 16px;\n color: #ccc;\n }\n \n h3 {\n margin: 0 0 8px 0;\n color: #333;\n font-size: 18px;\n font-weight: 500;\n }\n \n p {\n margin: 0;\n font-size: 14px;\n }\n}\n\n.prompts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));\n gap: 16px;\n flex: 1;\n overflow-y: auto;\n}\n\n.prompt-card[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n padding: 16px;\n transition: all 0.2s ease;\n height: fit-content;\n cursor: pointer;\n \n &:hover {\n border-color: #2196f3;\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.1);\n transform: translateY(-1px);\n }\n \n .card-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 12px;\n \n .prompt-info {\n display: flex;\n gap: 12px;\n flex: 1;\n \n .prompt-icon {\n color: #2196f3;\n font-size: 20px;\n margin-top: 2px;\n }\n \n .prompt-details {\n flex: 1;\n \n .prompt-name {\n margin: 0 0 4px 0;\n font-size: 16px;\n font-weight: 500;\n color: #333;\n }\n \n .prompt-meta {\n font-size: 12px;\n color: #666;\n \n .prompt-type {\n margin-left: 8px;\n }\n }\n }\n }\n }\n \n .card-body {\n margin-bottom: 12px;\n \n .prompt-description {\n margin-bottom: 12px;\n color: #555;\n font-size: 13px;\n line-height: 1.4;\n }\n \n .template-info {\n .template-item {\n display: flex;\n align-items: center;\n margin-bottom: 4px;\n font-size: 12px;\n color: #666;\n \n .fa-solid {\n margin-right: 6px;\n color: #999;\n }\n }\n \n .template-content-info {\n font-size: 11px;\n color: #999;\n }\n }\n }\n \n .card-actions {\n display: flex;\n gap: 8px;\n border-top: 1px solid #f0f0f0;\n padding-top: 12px;\n \n .action-btn {\n padding: 6px 12px;\n border: 1px solid #ddd;\n border-radius: 3px;\n background: white;\n cursor: pointer;\n font-size: 11px;\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all 0.2s;\n \n &:hover {\n background-color: #f5f5f5;\n border-color: #bbb;\n }\n \n &.action-btn-primary {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n \n &:hover {\n background-color: #1976d2;\n }\n }\n \n &.action-btn-danger {\n background-color: #f44336;\n border-color: #f44336;\n color: white;\n \n &:hover {\n background-color: #d32f2f;\n }\n }\n \n .fa-solid {\n font-size: 10px;\n }\n }\n }\n}\n\n//[_ngcontent-%COMP%] Editor[_ngcontent-%COMP%] View\n.editor-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n}\n\n.editor-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding-bottom: 16px;\n border-bottom: 1px solid #e0e0e0;\n \n .breadcrumb-section {\n .back-btn {\n background: none;\n border: none;\n color: #2196f3;\n cursor: pointer;\n font-size: 12px;\n display: flex;\n align-items: center;\n gap: 6px;\n \n &:hover {\n text-decoration: underline;\n }\n }\n }\n \n .editor-title {\n flex: 1;\n margin: 0 20px;\n \n h2 {\n margin: 0;\n font-size: 18px;\n font-weight: 500;\n color: #333;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n }\n \n .editor-actions {\n display: flex;\n gap: 8px;\n }\n}\n\n.editor-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n}\n\n.editor-splitter[_ngcontent-%COMP%] {\n height: 100%;\n \n .k-pane {\n overflow: hidden;\n }\n}\n\n.prompt-details-panel[_ngcontent-%COMP%], .template-editor-panel[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n padding: 16px;\n height: 100%;\n overflow-y: auto;\n \n h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 500;\n color: #333;\n border-bottom: 1px solid #f0f0f0;\n padding-bottom: 8px;\n }\n}\n\n.form-field[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n \n .field-label {\n display: block;\n margin-bottom: 4px;\n font-size: 12px;\n font-weight: 500;\n color: #555;\n }\n \n .field-input, .field-select {\n width: 100%;\n padding: 6px 8px;\n border: 1px solid #ddd;\n border-radius: 3px;\n font-size: 12px;\n \n &:focus {\n outline: none;\n border-color: #2196f3;\n }\n }\n \n .field-textarea {\n width: 100%;\n padding: 6px 8px;\n border: 1px solid #ddd;\n border-radius: 3px;\n font-size: 12px;\n resize: vertical;\n min-height: 60px;\n \n &:focus {\n outline: none;\n border-color: #2196f3;\n }\n }\n \n .field-value {\n padding: 6px 8px;\n background: #f8f9fa;\n border: 1px solid #e0e0e0;\n border-radius: 3px;\n font-size: 12px;\n color: #555;\n }\n}\n\n.template-editor-panel[_ngcontent-%COMP%] {\n .editor-container {\n margin-bottom: 16px;\n \n .code-editor {\n width: 100%;\n min-height: 300px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 12px;\n border: 1px solid #ddd;\n border-radius: 3px;\n padding: 8px;\n background: #f8f9fa;\n \n &:focus {\n outline: none;\n border-color: #2196f3;\n }\n }\n \n .code-display {\n border: 1px solid #e0e0e0;\n border-radius: 3px;\n background: #f8f9fa;\n max-height: 400px;\n overflow-y: auto;\n \n pre {\n margin: 0;\n padding: 12px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 12px;\n line-height: 1.4;\n color: #333;\n \n code {\n background: none;\n padding: 0;\n font-size: inherit;\n color: inherit;\n }\n }\n }\n }\n \n .editor-help {\n .help-section {\n h5 {\n font-size: 13px;\n font-weight: 500;\n margin-bottom: 8px;\n color: #333;\n }\n \n .syntax-examples {\n .syntax-item {\n margin-bottom: 6px;\n padding: 6px 8px;\n background: #f0f0f0;\n border-radius: 3px;\n font-size: 11px;\n \n code {\n background: #e0e0e0;\n padding: 2px 4px;\n border-radius: 2px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n margin-right: 8px;\n }\n }\n }\n }\n }\n}\n\n//[_ngcontent-%COMP%] CodeMirror[_ngcontent-%COMP%] overrides\n.CodeMirror[_ngcontent-%COMP%] {\n border: 1px solid #ddd !important;\n border-radius: 3px !important;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace !important;\n font-size: 12px !important;\n min-height: 300px !important;\n}\n\n.CodeMirror-focused[_ngcontent-%COMP%] {\n border-color: #2196f3 !important;\n}\n\n//[_ngcontent-%COMP%] Status[_ngcontent-%COMP%] badges\n.status-badge[_ngcontent-%COMP%] {\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 500;\n text-transform: uppercase;\n \n &.status-active {\n background: #e8f5e8;\n color: #2e7d32;\n }\n \n &.status-pending {\n background: #fff3e0;\n color: #f57c00;\n }\n \n &.status-disabled {\n background: #ffebee;\n color: #c62828;\n }\n}\n\n//[_ngcontent-%COMP%] Editor[_ngcontent-%COMP%] badges\n.editor-badge[_ngcontent-%COMP%] {\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 500;\n margin-left: 8px;\n \n &.editor-badge-info {\n background: #e3f2fd;\n color: #1976d2;\n }\n \n &.editor-badge-warning {\n background: #fff3e0;\n color: #f57c00;\n }\n \n &.editor-badge-secondary {\n background: #f5f5f5;\n color: #666;\n }\n}\n\n//[_ngcontent-%COMP%] New[_ngcontent-%COMP%] category[_ngcontent-%COMP%] creation\n.new-category-container[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n align-items: center;\n \n .field-input {\n flex: 1;\n }\n \n .new-category-actions {\n display: flex;\n gap: 2px;\n \n .action-btn {\n padding: 4px 6px;\n border: 1px solid #ddd;\n border-radius: 3px;\n background: white;\n cursor: pointer;\n font-size: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n \n &:hover {\n background-color: #f5f5f5;\n }\n \n &.action-btn-primary {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n \n &:hover {\n background-color: #1976d2;\n }\n }\n \n .fa-solid {\n font-size: 10px;\n }\n }\n }\n}\n\n.new-category-option[_ngcontent-%COMP%] {\n color: #2196f3;\n font-style: italic;\n}\n\n//[_ngcontent-%COMP%] CodeMirror[_ngcontent-%COMP%] 6[_ngcontent-%COMP%] styling\nmj-code-editor[_ngcontent-%COMP%] {\n display: block;\n border: 1px solid #ddd;\n border-radius: 3px;\n overflow: hidden;\n min-height: 300px;\n \n .cm-editor {\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace !important;\n font-size: 12px !important;\n min-height: 300px;\n }\n \n .cm-focused {\n outline: none !important;\n }\n \n .cm-editor.cm-focused {\n border-color: #2196f3;\n }\n}\n\n//[_ngcontent-%COMP%] List[_ngcontent-%COMP%] View[_ngcontent-%COMP%] Layout\n.list-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n}\n\n.sub-navigation[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-bottom: 16px;\n padding: 8px 0;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n\n .sub-nav-btn {\n padding: 8px 12px;\n border: 1px solid #ddd;\n border-radius: 4px;\n background: white;\n cursor: pointer;\n font-size: 12px;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.2s;\n color: #555;\n font-weight: 500;\n\n &:hover {\n background-color: #f0f0f0;\n border-color: #2196f3;\n color: #2196f3;\n }\n\n &.active {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n box-shadow: 0 2px 4px rgba(33, 150, 243, 0.2);\n }\n\n .fa-solid {\n font-size: 11px;\n }\n }\n}\n\n.main-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n}\n\n.main-splitter[_ngcontent-%COMP%] {\n height: 100%;\n \n .k-pane {\n overflow: hidden;\n }\n}\n\n.prompts-content[_ngcontent-%COMP%] {\n height: 100%;\n overflow-y: auto;\n padding: 0 16px;\n}"] });
1372
1341
  }
1373
- PromptManagementComponent.ɵfac = function PromptManagementComponent_Factory(t) { return new (t || PromptManagementComponent)(i0.ɵɵdirectiveInject(i1.MJNotificationService)); };
1374
- PromptManagementComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PromptManagementComponent, selectors: [["app-prompt-management"]], outputs: { openEntityRecord: "openEntityRecord", stateChange: "stateChange" }, decls: 3, vars: 4, consts: [["newCategoryInput", ""], ["mjFillContainer", "", 1, "prompt-management-container", 3, "rightMargin", "bottomMargin"], [1, "list-view"], [1, "editor-view"], [1, "dashboard-header"], [1, "header-info"], ["type", "button", "title", "Toggle Filters", 1, "filter-toggle-btn", 3, "click"], [1, "fa-solid", "fa-filter"], [1, "prompt-count"], [1, "header-controls"], ["type", "button", 1, "control-btn", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "sub-navigation"], ["type", "button", "title", "List View", 1, "sub-nav-btn", 3, "click"], [1, "fa-solid", "fa-list"], ["type", "button", "title", "Priority Matrix", 1, "sub-nav-btn", 3, "click"], [1, "fa-solid", "fa-th"], ["type", "button", "title", "Version Control", 1, "sub-nav-btn", 3, "click"], [1, "fa-solid", "fa-code-branch"], [1, "main-content"], ["orientation", "horizontal", "mjFillContainer", "", 1, "main-splitter"], ["mjFillContainer", "", 3, "selectedPrompts"], ["mjFillContainer", "", 3, "prompt"], ["orientation", "horizontal", "mjFillContainer", "", 1, "main-splitter", 3, "layoutChange"], [3, "size", "collapsible", "resizable", "scrollable", "hidden"], [3, "filtersChange", "filterChange", "resetFilters", "closePanel", "prompts", "filteredPrompts", "categories", "types", "filters"], [3, "resizable", "scrollable"], [1, "prompts-content"], [1, "loading-container"], [1, "error-container"], [1, "prompts-list"], [1, "loading-content"], [1, "loading-spinner"], [1, "spinner-ring"], [1, "loading-text"], [1, "error-message"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "empty-state"], [1, "prompts-grid"], [1, "fa-solid", "fa-comment-dots"], [1, "prompt-card"], [1, "prompt-card", 3, "click"], [1, "card-header"], [1, "prompt-info"], [1, "prompt-icon"], [1, "prompt-details"], [1, "prompt-name"], [1, "prompt-meta"], [1, "prompt-category"], [1, "prompt-type"], [1, "card-body"], [1, "prompt-description"], [1, "prompt-description", "text-muted"], [1, "template-info"], [1, "template-item", "text-muted"], [1, "card-actions", 3, "click"], ["type", "button", 1, "action-btn", 3, "click"], [1, "fa-solid", "fa-eye"], ["type", "button", 1, "action-btn", "action-btn-primary", 3, "click"], [1, "fa-solid", "fa-edit"], ["type", "button", 1, "action-btn", "action-btn-danger", 3, "click"], [1, "fa-solid", "fa-trash"], [1, "template-item"], [1, "fa-solid", "fa-file-code"], [1, "template-content-info"], ["mjFillContainer", "", 3, "promptSelected", "selectedPrompts"], ["mjFillContainer", "", 3, "versionSelected", "prompt"], [1, "editor-header"], [1, "breadcrumb-section"], ["type", "button", 1, "back-btn", 3, "click"], [1, "fa-solid", "fa-arrow-left"], [1, "editor-title"], [3, "class"], [1, "editor-actions"], ["type", "button", 1, "control-btn"], [1, "editor-content"], ["orientation", "horizontal", "mjFillContainer", "", 1, "editor-splitter", 3, "layoutChange"], [3, "collapsible", "resizable", "scrollable"], [1, "prompt-details-panel"], [1, "form-field"], [1, "field-label"], ["type", "text", "placeholder", "Enter prompt name", 1, "field-input", 3, "ngModel"], [1, "field-value"], ["placeholder", "Enter prompt description", 1, "field-textarea", 3, "ngModel"], [1, "field-select", 3, "ngModel"], [1, "template-info-section"], [1, "template-editor-panel"], [1, "editor-info"], [1, "editor-badge", "editor-badge-secondary"], [1, "editor-container"], [3, "change", "value", "languages", "language", "placeholder", "lineWrapping", "highlightWhitespace", "indentWithTab", "indentUnit", "readonly"], [1, "editor-help"], [1, "fa-solid", "fa-times"], ["type", "button", 1, "control-btn", "control-btn-primary", 3, "click", "disabled"], [1, "loading-spinner-sm"], [1, "fa-solid", "fa-save"], ["type", "text", "placeholder", "Enter prompt name", 1, "field-input", 3, "ngModelChange", "input", "ngModel"], ["placeholder", "Enter prompt description", 1, "field-textarea", 3, "ngModelChange", "input", "ngModel"], [1, "new-category-container"], [1, "field-select", 3, "ngModelChange", "ngModel"], ["value", ""], [3, "value"], ["value", "new", 1, "new-category-option"], ["type", "text", "placeholder", "Enter new category name", 1, "field-input", 3, "ngModelChange", "keyup", "ngModel"], [1, "new-category-actions"], [1, "fa-solid", "fa-check"], [1, "field-select", 3, "ngModelChange", "change", "ngModel"], ["value", "Active"], ["value", "Pending"], ["value", "Disabled"], [1, "template-details"], [1, "editor-badge", "editor-badge-info"], [1, "editor-badge", "editor-badge-warning"], [1, "help-section"], [1, "syntax-examples"], [1, "syntax-item"]], template: function PromptManagementComponent_Template(rf, ctx) { if (rf & 1) {
1375
- i0.ɵɵelementStart(0, "div", 1);
1376
- i0.ɵɵtemplate(1, PromptManagementComponent_Conditional_1_Template, 27, 11, "div", 2)(2, PromptManagementComponent_Conditional_2_Template, 58, 25, "div", 3);
1377
- i0.ɵɵelementEnd();
1378
- } if (rf & 2) {
1379
- i0.ɵɵproperty("rightMargin", 8)("bottomMargin", 8);
1380
- i0.ɵɵadvance();
1381
- i0.ɵɵconditional(ctx.currentView === "list" ? 1 : -1);
1382
- i0.ɵɵadvance();
1383
- i0.ɵɵconditional(ctx.currentView === "editor" && ctx.selectedPrompt ? 2 : -1);
1384
- } }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.SplitterComponent, i3.SplitterPaneComponent, i4.FillContainer, i5.CodeEditorComponent, i6.PromptFilterPanelComponent, i7.ModelPromptPriorityMatrixComponent, i8.PromptVersionControlComponent], styles: [".prompt-management-container[_ngcontent-%COMP%] {\n overflow: hidden;\n padding: 4px;\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.dashboard-header[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-shrink: 0;\n \n .header-info {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n \n .filter-toggle-btn {\n padding: 6px 10px;\n border: 1px solid #ddd;\n border-radius: 4px;\n background: white;\n cursor: pointer;\n font-size: 11px;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.2s;\n color: #555;\n \n &:hover {\n background-color: #f0f0f0;\n border-color: #2196f3;\n color: #2196f3;\n }\n \n .fa-solid {\n font-size: 10px;\n }\n }\n \n .prompt-count {\n font-size: 12px;\n color: #2196f3;\n font-weight: 600;\n background: rgba(33, 150, 243, 0.1);\n padding: 4px 8px;\n border-radius: 4px;\n border: 1px solid rgba(33, 150, 243, 0.2);\n }\n \n .header-controls {\n display: flex;\n gap: 8px;\n \n .control-btn {\n padding: 8px 12px;\n border: 1px solid #ccc;\n border-radius: 4px;\n background: white;\n cursor: pointer;\n font-size: 12px;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.2s;\n \n &:hover {\n background-color: #f0f0f0;\n border-color: #2196f3;\n }\n \n &.active {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n }\n \n &.control-btn-primary {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n \n &:hover {\n background-color: #1976d2;\n }\n }\n \n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n \n &:hover {\n background-color: white;\n border-color: #ccc;\n }\n }\n \n .fa-solid {\n font-size: 14px;\n }\n }\n }\n}\n\n//[_ngcontent-%COMP%] Filters[_ngcontent-%COMP%] now[_ngcontent-%COMP%] handled[_ngcontent-%COMP%] by[_ngcontent-%COMP%] filter[_ngcontent-%COMP%] panel[_ngcontent-%COMP%] component\n\n.loading-container[_ngcontent-%COMP%], .error-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n background: #fafafa;\n flex: 1;\n \n p {\n color: #666;\n font-size: 14px;\n }\n}\n\n.error-message[_ngcontent-%COMP%] {\n color: #d32f2f;\n font-weight: 500;\n \n .fa-solid {\n margin-right: 8px;\n }\n}\n\n.loading-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 16px;\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n display: inline-block;\n position: relative;\n width: 40px;\n height: 40px;\n \n .spinner-ring {\n box-sizing: border-box;\n display: block;\n position: absolute;\n width: 32px;\n height: 32px;\n margin: 4px;\n border: 3px solid #2196f3;\n border-radius: 50%;\n animation: _ngcontent-%COMP%_loading-spin 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n border-color: #2196f3 transparent transparent transparent;\n \n &:nth-child(1) { animation-delay: -0.45s; }\n &:nth-child(2) { animation-delay: -0.3s; }\n &:nth-child(3) { animation-delay: -0.15s; }\n }\n}\n\n@keyframes _ngcontent-%COMP%_loading-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 60px 20px;\n color: #666;\n \n .fa-solid {\n font-size: 48px;\n margin-bottom: 16px;\n color: #ccc;\n }\n \n h3 {\n margin: 0 0 8px 0;\n color: #333;\n font-size: 18px;\n font-weight: 500;\n }\n \n p {\n margin: 0;\n font-size: 14px;\n }\n}\n\n.prompts-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));\n gap: 16px;\n flex: 1;\n overflow-y: auto;\n}\n\n.prompt-card[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n padding: 16px;\n transition: all 0.2s ease;\n height: fit-content;\n cursor: pointer;\n \n &:hover {\n border-color: #2196f3;\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.1);\n transform: translateY(-1px);\n }\n \n .card-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 12px;\n \n .prompt-info {\n display: flex;\n gap: 12px;\n flex: 1;\n \n .prompt-icon {\n color: #2196f3;\n font-size: 20px;\n margin-top: 2px;\n }\n \n .prompt-details {\n flex: 1;\n \n .prompt-name {\n margin: 0 0 4px 0;\n font-size: 16px;\n font-weight: 500;\n color: #333;\n }\n \n .prompt-meta {\n font-size: 12px;\n color: #666;\n \n .prompt-type {\n margin-left: 8px;\n }\n }\n }\n }\n }\n \n .card-body {\n margin-bottom: 12px;\n \n .prompt-description {\n margin-bottom: 12px;\n color: #555;\n font-size: 13px;\n line-height: 1.4;\n }\n \n .template-info {\n .template-item {\n display: flex;\n align-items: center;\n margin-bottom: 4px;\n font-size: 12px;\n color: #666;\n \n .fa-solid {\n margin-right: 6px;\n color: #999;\n }\n }\n \n .template-content-info {\n font-size: 11px;\n color: #999;\n }\n }\n }\n \n .card-actions {\n display: flex;\n gap: 8px;\n border-top: 1px solid #f0f0f0;\n padding-top: 12px;\n \n .action-btn {\n padding: 6px 12px;\n border: 1px solid #ddd;\n border-radius: 3px;\n background: white;\n cursor: pointer;\n font-size: 11px;\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all 0.2s;\n \n &:hover {\n background-color: #f5f5f5;\n border-color: #bbb;\n }\n \n &.action-btn-primary {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n \n &:hover {\n background-color: #1976d2;\n }\n }\n \n &.action-btn-danger {\n background-color: #f44336;\n border-color: #f44336;\n color: white;\n \n &:hover {\n background-color: #d32f2f;\n }\n }\n \n .fa-solid {\n font-size: 10px;\n }\n }\n }\n}\n\n//[_ngcontent-%COMP%] Editor[_ngcontent-%COMP%] View\n.editor-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n}\n\n.editor-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding-bottom: 16px;\n border-bottom: 1px solid #e0e0e0;\n \n .breadcrumb-section {\n .back-btn {\n background: none;\n border: none;\n color: #2196f3;\n cursor: pointer;\n font-size: 12px;\n display: flex;\n align-items: center;\n gap: 6px;\n \n &:hover {\n text-decoration: underline;\n }\n }\n }\n \n .editor-title {\n flex: 1;\n margin: 0 20px;\n \n h2 {\n margin: 0;\n font-size: 18px;\n font-weight: 500;\n color: #333;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n }\n \n .editor-actions {\n display: flex;\n gap: 8px;\n }\n}\n\n.editor-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n}\n\n.editor-splitter[_ngcontent-%COMP%] {\n height: 100%;\n \n .k-pane {\n overflow: hidden;\n }\n}\n\n.prompt-details-panel[_ngcontent-%COMP%], .template-editor-panel[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n padding: 16px;\n height: 100%;\n overflow-y: auto;\n \n h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 500;\n color: #333;\n border-bottom: 1px solid #f0f0f0;\n padding-bottom: 8px;\n }\n}\n\n.form-field[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n \n .field-label {\n display: block;\n margin-bottom: 4px;\n font-size: 12px;\n font-weight: 500;\n color: #555;\n }\n \n .field-input, .field-select {\n width: 100%;\n padding: 6px 8px;\n border: 1px solid #ddd;\n border-radius: 3px;\n font-size: 12px;\n \n &:focus {\n outline: none;\n border-color: #2196f3;\n }\n }\n \n .field-textarea {\n width: 100%;\n padding: 6px 8px;\n border: 1px solid #ddd;\n border-radius: 3px;\n font-size: 12px;\n resize: vertical;\n min-height: 60px;\n \n &:focus {\n outline: none;\n border-color: #2196f3;\n }\n }\n \n .field-value {\n padding: 6px 8px;\n background: #f8f9fa;\n border: 1px solid #e0e0e0;\n border-radius: 3px;\n font-size: 12px;\n color: #555;\n }\n}\n\n.template-editor-panel[_ngcontent-%COMP%] {\n .editor-container {\n margin-bottom: 16px;\n \n .code-editor {\n width: 100%;\n min-height: 300px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 12px;\n border: 1px solid #ddd;\n border-radius: 3px;\n padding: 8px;\n background: #f8f9fa;\n \n &:focus {\n outline: none;\n border-color: #2196f3;\n }\n }\n \n .code-display {\n border: 1px solid #e0e0e0;\n border-radius: 3px;\n background: #f8f9fa;\n max-height: 400px;\n overflow-y: auto;\n \n pre {\n margin: 0;\n padding: 12px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 12px;\n line-height: 1.4;\n color: #333;\n \n code {\n background: none;\n padding: 0;\n font-size: inherit;\n color: inherit;\n }\n }\n }\n }\n \n .editor-help {\n .help-section {\n h5 {\n font-size: 13px;\n font-weight: 500;\n margin-bottom: 8px;\n color: #333;\n }\n \n .syntax-examples {\n .syntax-item {\n margin-bottom: 6px;\n padding: 6px 8px;\n background: #f0f0f0;\n border-radius: 3px;\n font-size: 11px;\n \n code {\n background: #e0e0e0;\n padding: 2px 4px;\n border-radius: 2px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n margin-right: 8px;\n }\n }\n }\n }\n }\n}\n\n//[_ngcontent-%COMP%] CodeMirror[_ngcontent-%COMP%] overrides\n.CodeMirror[_ngcontent-%COMP%] {\n border: 1px solid #ddd !important;\n border-radius: 3px !important;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace !important;\n font-size: 12px !important;\n min-height: 300px !important;\n}\n\n.CodeMirror-focused[_ngcontent-%COMP%] {\n border-color: #2196f3 !important;\n}\n\n//[_ngcontent-%COMP%] Status[_ngcontent-%COMP%] badges\n.status-badge[_ngcontent-%COMP%] {\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 500;\n text-transform: uppercase;\n \n &.status-active {\n background: #e8f5e8;\n color: #2e7d32;\n }\n \n &.status-pending {\n background: #fff3e0;\n color: #f57c00;\n }\n \n &.status-disabled {\n background: #ffebee;\n color: #c62828;\n }\n}\n\n//[_ngcontent-%COMP%] Editor[_ngcontent-%COMP%] badges\n.editor-badge[_ngcontent-%COMP%] {\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 500;\n margin-left: 8px;\n \n &.editor-badge-info {\n background: #e3f2fd;\n color: #1976d2;\n }\n \n &.editor-badge-warning {\n background: #fff3e0;\n color: #f57c00;\n }\n \n &.editor-badge-secondary {\n background: #f5f5f5;\n color: #666;\n }\n}\n\n//[_ngcontent-%COMP%] New[_ngcontent-%COMP%] category[_ngcontent-%COMP%] creation\n.new-category-container[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n align-items: center;\n \n .field-input {\n flex: 1;\n }\n \n .new-category-actions {\n display: flex;\n gap: 2px;\n \n .action-btn {\n padding: 4px 6px;\n border: 1px solid #ddd;\n border-radius: 3px;\n background: white;\n cursor: pointer;\n font-size: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n \n &:hover {\n background-color: #f5f5f5;\n }\n \n &.action-btn-primary {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n \n &:hover {\n background-color: #1976d2;\n }\n }\n \n .fa-solid {\n font-size: 10px;\n }\n }\n }\n}\n\n.new-category-option[_ngcontent-%COMP%] {\n color: #2196f3;\n font-style: italic;\n}\n\n//[_ngcontent-%COMP%] CodeMirror[_ngcontent-%COMP%] 6[_ngcontent-%COMP%] styling\nmj-code-editor[_ngcontent-%COMP%] {\n display: block;\n border: 1px solid #ddd;\n border-radius: 3px;\n overflow: hidden;\n min-height: 300px;\n \n .cm-editor {\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace !important;\n font-size: 12px !important;\n min-height: 300px;\n }\n \n .cm-focused {\n outline: none !important;\n }\n \n .cm-editor.cm-focused {\n border-color: #2196f3;\n }\n}\n\n//[_ngcontent-%COMP%] List[_ngcontent-%COMP%] View[_ngcontent-%COMP%] Layout\n.list-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n}\n\n.sub-navigation[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-bottom: 16px;\n padding: 8px 0;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n\n .sub-nav-btn {\n padding: 8px 12px;\n border: 1px solid #ddd;\n border-radius: 4px;\n background: white;\n cursor: pointer;\n font-size: 12px;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.2s;\n color: #555;\n font-weight: 500;\n\n &:hover {\n background-color: #f0f0f0;\n border-color: #2196f3;\n color: #2196f3;\n }\n\n &.active {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n box-shadow: 0 2px 4px rgba(33, 150, 243, 0.2);\n }\n\n .fa-solid {\n font-size: 11px;\n }\n }\n}\n\n.main-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n}\n\n.main-splitter[_ngcontent-%COMP%] {\n height: 100%;\n \n .k-pane {\n overflow: hidden;\n }\n}\n\n.prompts-content[_ngcontent-%COMP%] {\n height: 100%;\n overflow-y: auto;\n padding: 0 16px;\n}"] });
1385
1342
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PromptManagementComponent, [{
1386
1343
  type: Component,
1387
1344
  args: [{ selector: 'app-prompt-management', template: "<div class=\"prompt-management-container\" mjFillContainer [rightMargin]=\"8\" [bottomMargin]=\"8\">\n <!-- List View -->\n @if (currentView === 'list') {\n <div class=\"list-view\">\n <!-- Header -->\n <div class=\"dashboard-header\">\n <div class=\"header-info\">\n <button \n type=\"button\" \n class=\"filter-toggle-btn\"\n (click)=\"toggleFilterPanel()\"\n title=\"Toggle Filters\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (filterPanelVisible) {\n Hide Filters\n } @else {\n Show Filters\n }\n </button>\n <span class=\"prompt-count\">{{ filteredPrompts.length }} prompts</span>\n </div>\n \n <div class=\"header-controls\">\n <button \n type=\"button\" \n class=\"control-btn\"\n (click)=\"createNewPrompt()\">\n <i class=\"fa-solid fa-plus\"></i>\n New Prompt\n </button>\n </div>\n </div>\n\n <!-- Sub Navigation -->\n <div class=\"sub-navigation\">\n <button \n type=\"button\" \n class=\"sub-nav-btn\"\n [class.active]=\"currentSubView === 'list'\"\n (click)=\"setSubView('list')\"\n title=\"List View\">\n <i class=\"fa-solid fa-list\"></i>\n List View\n </button>\n <button \n type=\"button\" \n class=\"sub-nav-btn\"\n [class.active]=\"currentSubView === 'priority-matrix'\"\n (click)=\"setSubView('priority-matrix')\"\n title=\"Priority Matrix\">\n <i class=\"fa-solid fa-th\"></i>\n Priority Matrix\n </button>\n <button \n type=\"button\" \n class=\"sub-nav-btn\"\n [class.active]=\"currentSubView === 'version-control'\"\n (click)=\"setSubView('version-control')\"\n title=\"Version Control\">\n <i class=\"fa-solid fa-code-branch\"></i>\n Version Control\n </button>\n </div>\n\n <!-- Main Content with Splitter -->\n <div class=\"main-content\">\n <!-- List View Content -->\n @if (currentSubView === 'list') {\n <kendo-splitter \n class=\"main-splitter\"\n orientation=\"horizontal\"\n (layoutChange)=\"onMainSplitterChange($event)\"\n mjFillContainer>\n \n <!-- Filter Panel (Left) -->\n <kendo-splitter-pane \n [size]=\"filterPanelVisible ? '320px' : '0px'\"\n [collapsible]=\"false\"\n [resizable]=\"filterPanelVisible\"\n [scrollable]=\"false\"\n [hidden]=\"!filterPanelVisible\">\n <mj-prompt-filter-panel\n [prompts]=\"promptsWithTemplates\"\n [filteredPrompts]=\"filteredPrompts\"\n [categories]=\"categories\"\n [types]=\"types\"\n [filters]=\"currentFilters\"\n (filtersChange)=\"onFiltersChange($event)\"\n (filterChange)=\"onFilterChange()\"\n (resetFilters)=\"onResetFilters()\"\n (closePanel)=\"toggleFilterPanel()\">\n </mj-prompt-filter-panel>\n </kendo-splitter-pane>\n \n <!-- Prompts List Panel -->\n <kendo-splitter-pane \n [resizable]=\"true\"\n [scrollable]=\"false\">\n <div class=\"prompts-content\">\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <div class=\"loading-content\">\n <div class=\"loading-spinner\">\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n </div>\n <div class=\"loading-text\">{{ loadingMessage }}</div>\n </div>\n </div>\n }\n\n <!-- Error State -->\n @if (error) {\n <div class=\"error-container\">\n <p class=\"error-message\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n {{ error }}\n </p>\n </div>\n }\n\n <!-- Prompts List -->\n @if (!isLoading && !error) {\n <div class=\"prompts-list\">\n @if (filteredPrompts.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-comment-dots\"></i>\n <h3>No prompts found</h3>\n <p>No prompts match your current filters. Try adjusting your search criteria or create a new prompt.</p>\n </div>\n } @else {\n <div class=\"prompts-grid\">\n @for (promptWithTemplate of filteredPrompts; track promptWithTemplate.prompt.ID || $index) {\n <div class=\"prompt-card\" (click)=\"viewPrompt(promptWithTemplate)\">\n <!-- Card Header -->\n <div class=\"card-header\">\n <div class=\"prompt-info\">\n <div class=\"prompt-icon\">\n <i [class]=\"getPromptIcon()\"></i>\n </div>\n <div class=\"prompt-details\">\n <h4 class=\"prompt-name\">{{ promptWithTemplate.prompt.Name }}</h4>\n <div class=\"prompt-meta\">\n <span class=\"prompt-category\">{{ getCategoryName(promptWithTemplate.prompt.CategoryID) }}</span>\n @if (promptWithTemplate.type) {\n <span class=\"prompt-type\">\u2022 {{ promptWithTemplate.type.Name }}</span>\n }\n </div>\n </div>\n </div>\n \n <div class=\"status-badge status-{{ promptWithTemplate.prompt.Status.toLowerCase() }}\">\n {{ promptWithTemplate.prompt.Status }}\n </div>\n </div>\n\n <!-- Card Body -->\n <div class=\"card-body\">\n @if (promptWithTemplate.prompt.Description) {\n <p class=\"prompt-description\">{{ promptWithTemplate.prompt.Description }}</p>\n } @else {\n <p class=\"prompt-description text-muted\">No description provided</p>\n }\n \n <!-- Template Info -->\n <div class=\"template-info\">\n @if (promptWithTemplate.template) {\n <div class=\"template-item\">\n <i class=\"fa-solid fa-file-code\"></i>\n <span>{{ promptWithTemplate.template.Name }}</span>\n </div>\n @if (promptWithTemplate.templateContent) {\n <div class=\"template-content-info\">\n <small>\n Template content: {{ (promptWithTemplate.templateContent.TemplateText || '').length }} characters\n </small>\n </div>\n }\n } @else {\n <div class=\"template-item text-muted\">\n <i class=\"fa-solid fa-file-code\"></i>\n <span>No template assigned</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Card Actions -->\n <div class=\"card-actions\" (click)=\"$event.stopPropagation()\">\n <button \n type=\"button\" \n class=\"action-btn\"\n (click)=\"viewPrompt(promptWithTemplate)\">\n <i class=\"fa-solid fa-eye\"></i>\n View\n </button>\n \n <button \n type=\"button\" \n class=\"action-btn action-btn-primary\"\n (click)=\"editPrompt(promptWithTemplate)\">\n <i class=\"fa-solid fa-edit\"></i>\n Edit\n </button>\n \n <button \n type=\"button\" \n class=\"action-btn action-btn-danger\"\n (click)=\"deletePrompt(promptWithTemplate)\">\n <i class=\"fa-solid fa-trash\"></i>\n Delete\n </button>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </kendo-splitter-pane>\n </kendo-splitter>\n }\n\n\n <!-- Priority Matrix View -->\n @if (currentSubView === 'priority-matrix') {\n <app-model-prompt-priority-matrix\n [selectedPrompts]=\"promptsForMatrix\"\n (promptSelected)=\"onPromptSelectedFromMatrix($event)\"\n mjFillContainer>\n </app-model-prompt-priority-matrix>\n }\n\n <!-- Version Control View -->\n @if (currentSubView === 'version-control') {\n <app-prompt-version-control\n [prompt]=\"selectedPrompt?.prompt || null\"\n (versionSelected)=\"onVersionSelected($event)\"\n mjFillContainer>\n </app-prompt-version-control>\n }\n </div>\n </div>\n }\n\n <!-- Editor View -->\n @if (currentView === 'editor' && selectedPrompt) {\n <div class=\"editor-view\">\n <!-- Editor Header -->\n <div class=\"editor-header\">\n <div class=\"breadcrumb-section\">\n <button \n type=\"button\" \n class=\"back-btn\"\n (click)=\"backToList()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Back to Prompts\n </button>\n </div>\n \n <div class=\"editor-title\">\n <h2>\n @if (isEditing && !selectedPrompt.prompt.ID) {\n <i class=\"fa-solid fa-plus\"></i>\n Create New Prompt\n } @else if (isEditing) {\n <i class=\"fa-solid fa-edit\"></i>\n Edit Prompt\n } @else {\n <i class=\"fa-solid fa-eye\"></i>\n View Prompt\n }\n </h2>\n \n @if (selectedPrompt.prompt.ID) {\n <div class=\"status-badge status-{{ selectedPrompt.prompt.Status.toLowerCase() }}\">\n {{ selectedPrompt.prompt.Status }}\n </div>\n }\n </div>\n \n <div class=\"editor-actions\">\n @if (!isEditing) {\n <button \n type=\"button\" \n class=\"control-btn\"\n (click)=\"toggleEdit()\">\n <i class=\"fa-solid fa-edit\"></i>\n Edit\n </button>\n } @else {\n <button \n type=\"button\" \n class=\"control-btn\"\n (click)=\"toggleEdit()\">\n <i class=\"fa-solid fa-times\"></i>\n Cancel\n </button>\n \n <button \n type=\"button\" \n class=\"control-btn control-btn-primary\"\n (click)=\"savePrompt()\"\n [disabled]=\"isLoading\">\n @if (isLoading) {\n <span class=\"loading-spinner-sm\"></span>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n }\n Save\n </button>\n }\n </div>\n </div>\n\n <!-- Editor Content -->\n <div class=\"editor-content\">\n <kendo-splitter \n class=\"editor-splitter\"\n orientation=\"horizontal\"\n (layoutChange)=\"onEditorSplitterChange($event)\"\n mjFillContainer>\n \n <!-- Prompt Details Panel -->\n <kendo-splitter-pane \n [collapsible]=\"false\"\n [resizable]=\"true\"\n [scrollable]=\"true\">\n <div class=\"prompt-details-panel\">\n <h3>Prompt Details</h3>\n \n <!-- Name -->\n <div class=\"form-field\">\n <label class=\"field-label\">Name *</label>\n @if (isEditing) {\n <input \n type=\"text\" \n class=\"field-input\"\n [(ngModel)]=\"selectedPrompt.prompt.Name\"\n placeholder=\"Enter prompt name\"\n (input)=\"isDirty = true\">\n } @else {\n <div class=\"field-value\">{{ selectedPrompt.prompt.Name }}</div>\n }\n </div>\n \n <!-- Description -->\n <div class=\"form-field\">\n <label class=\"field-label\">Description</label>\n @if (isEditing) {\n <textarea \n class=\"field-textarea\"\n [(ngModel)]=\"selectedPrompt.prompt.Description\"\n placeholder=\"Enter prompt description\"\n (input)=\"isDirty = true\"></textarea>\n } @else {\n <div class=\"field-value\">\n {{ selectedPrompt.prompt.Description || 'No description provided' }}\n </div>\n }\n </div>\n \n <!-- Category -->\n <div class=\"form-field\">\n <label class=\"field-label\">Category</label>\n @if (isEditing) {\n @if (!showNewCategoryInput) {\n <select \n class=\"field-select\"\n [(ngModel)]=\"selectedPrompt.prompt.CategoryID\"\n (ngModelChange)=\"onCategoryChange($event)\">\n <option value=\"\">Select category...</option>\n @for (category of categories; track category.ID) {\n <option [value]=\"category.ID\">{{ category.Name }}</option>\n }\n <option value=\"new\" class=\"new-category-option\">+ Create New Category</option>\n </select>\n } @else {\n <div class=\"new-category-container\">\n <input \n type=\"text\" \n class=\"field-input\"\n [(ngModel)]=\"newCategoryName\"\n placeholder=\"Enter new category name\"\n (keyup)=\"onCreateNewCategoryKeyup($event)\"\n #newCategoryInput>\n <div class=\"new-category-actions\">\n <button \n type=\"button\" \n class=\"action-btn action-btn-primary\"\n (click)=\"createAndSelectNewCategory()\">\n <i class=\"fa-solid fa-check\"></i>\n </button>\n <button \n type=\"button\" \n class=\"action-btn\"\n (click)=\"cancelNewCategory()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n }\n } @else {\n <div class=\"field-value\">\n {{ getCategoryName(selectedPrompt.prompt.CategoryID) }}\n </div>\n }\n </div>\n \n <!-- Type -->\n <div class=\"form-field\">\n <label class=\"field-label\">Type</label>\n @if (isEditing) {\n <select \n class=\"field-select\"\n [(ngModel)]=\"selectedPrompt.prompt.TypeID\"\n (change)=\"isDirty = true\">\n <option value=\"\">Select type...</option>\n @for (type of types; track type.ID) {\n <option [value]=\"type.ID\">{{ type.Name }}</option>\n }\n </select>\n } @else {\n <div class=\"field-value\">\n {{ getTypeName(selectedPrompt.prompt.TypeID) }}\n </div>\n }\n </div>\n \n <!-- Status -->\n <div class=\"form-field\">\n <label class=\"field-label\">Status</label>\n @if (isEditing) {\n <select \n class=\"field-select\"\n [(ngModel)]=\"selectedPrompt.prompt.Status\"\n (change)=\"isDirty = true\">\n <option value=\"Active\">Active</option>\n <option value=\"Pending\">Pending</option>\n <option value=\"Disabled\">Disabled</option>\n </select>\n } @else {\n <div class=\"field-value\">\n <span class=\"status-badge status-{{ selectedPrompt.prompt.Status.toLowerCase() }}\">\n {{ selectedPrompt.prompt.Status }}\n </span>\n </div>\n }\n </div>\n \n <!-- Template Info -->\n @if (selectedPrompt.template) {\n <div class=\"template-info-section\">\n <h4>Template Information</h4>\n <div class=\"template-details\">\n <div><strong>Template:</strong> {{ selectedPrompt.template.Name }}</div>\n @if (selectedPrompt.template.Description) {\n <div><strong>Description:</strong> {{ selectedPrompt.template.Description }}</div>\n }\n @if (selectedPrompt.templateContent) {\n <div><strong>Content Length:</strong> {{ (selectedPrompt.templateContent.TemplateText || '').length }} characters</div>\n }\n </div>\n </div>\n }\n </div>\n </kendo-splitter-pane>\n \n <!-- Template Editor Panel -->\n <kendo-splitter-pane \n [resizable]=\"true\"\n [scrollable]=\"true\">\n <div class=\"template-editor-panel\">\n <div class=\"editor-header\">\n <h3>Template Content</h3>\n <div class=\"editor-info\">\n @if (isEditing) {\n <span class=\"editor-badge editor-badge-info\">Nunjucks Template</span>\n @if (isDirty) {\n <span class=\"editor-badge editor-badge-warning\">Unsaved Changes</span>\n }\n } @else {\n <span class=\"editor-badge editor-badge-secondary\">Read Only</span>\n }\n </div>\n </div>\n \n <div class=\"editor-container\">\n <mj-code-editor\n [value]=\"editorContent\"\n [languages]=\"supportedLanguages\"\n [language]=\"editorLanguage\"\n [placeholder]=\"'Enter your Nunjucks template here...'\"\n [lineWrapping]=\"true\"\n [highlightWhitespace]=\"false\"\n [indentWithTab]=\"true\"\n [indentUnit]=\"' '\"\n [readonly]=\"!isEditing\"\n (change)=\"onEditorContentChange($event)\">\n </mj-code-editor>\n </div>\n \n <!-- Editor Help -->\n @if (isEditing) {\n <div class=\"editor-help\">\n <div class=\"help-section\">\n <h5>Nunjucks Template Syntax</h5>\n <div class=\"syntax-examples\">\n <div class=\"syntax-item\">\n <code>{{ \"{{ variable }}\" }}</code> - Variable output\n </div>\n <div class=\"syntax-item\">\n <code>{{ \"{% if condition %} ... {% endif %}\" }}</code> - Conditionals\n </div>\n <div class=\"syntax-item\">\n <code>{{ \"{% for item in items %} ... {% endfor %}\" }}</code> - Loops\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n </kendo-splitter-pane>\n </kendo-splitter>\n </div>\n </div>\n }\n</div>", styles: [".prompt-management-container {\n overflow: hidden;\n padding: 4px;\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.dashboard-header {\n margin-bottom: 16px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-shrink: 0;\n \n .header-info {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n \n .filter-toggle-btn {\n padding: 6px 10px;\n border: 1px solid #ddd;\n border-radius: 4px;\n background: white;\n cursor: pointer;\n font-size: 11px;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.2s;\n color: #555;\n \n &:hover {\n background-color: #f0f0f0;\n border-color: #2196f3;\n color: #2196f3;\n }\n \n .fa-solid {\n font-size: 10px;\n }\n }\n \n .prompt-count {\n font-size: 12px;\n color: #2196f3;\n font-weight: 600;\n background: rgba(33, 150, 243, 0.1);\n padding: 4px 8px;\n border-radius: 4px;\n border: 1px solid rgba(33, 150, 243, 0.2);\n }\n \n .header-controls {\n display: flex;\n gap: 8px;\n \n .control-btn {\n padding: 8px 12px;\n border: 1px solid #ccc;\n border-radius: 4px;\n background: white;\n cursor: pointer;\n font-size: 12px;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.2s;\n \n &:hover {\n background-color: #f0f0f0;\n border-color: #2196f3;\n }\n \n &.active {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n }\n \n &.control-btn-primary {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n \n &:hover {\n background-color: #1976d2;\n }\n }\n \n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n \n &:hover {\n background-color: white;\n border-color: #ccc;\n }\n }\n \n .fa-solid {\n font-size: 14px;\n }\n }\n }\n}\n\n// Filters now handled by filter panel component\n\n.loading-container, .error-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n background: #fafafa;\n flex: 1;\n \n p {\n color: #666;\n font-size: 14px;\n }\n}\n\n.error-message {\n color: #d32f2f;\n font-weight: 500;\n \n .fa-solid {\n margin-right: 8px;\n }\n}\n\n.loading-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 16px;\n}\n\n.loading-spinner {\n display: inline-block;\n position: relative;\n width: 40px;\n height: 40px;\n \n .spinner-ring {\n box-sizing: border-box;\n display: block;\n position: absolute;\n width: 32px;\n height: 32px;\n margin: 4px;\n border: 3px solid #2196f3;\n border-radius: 50%;\n animation: loading-spin 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n border-color: #2196f3 transparent transparent transparent;\n \n &:nth-child(1) { animation-delay: -0.45s; }\n &:nth-child(2) { animation-delay: -0.3s; }\n &:nth-child(3) { animation-delay: -0.15s; }\n }\n}\n\n@keyframes loading-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n.empty-state {\n text-align: center;\n padding: 60px 20px;\n color: #666;\n \n .fa-solid {\n font-size: 48px;\n margin-bottom: 16px;\n color: #ccc;\n }\n \n h3 {\n margin: 0 0 8px 0;\n color: #333;\n font-size: 18px;\n font-weight: 500;\n }\n \n p {\n margin: 0;\n font-size: 14px;\n }\n}\n\n.prompts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));\n gap: 16px;\n flex: 1;\n overflow-y: auto;\n}\n\n.prompt-card {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n padding: 16px;\n transition: all 0.2s ease;\n height: fit-content;\n cursor: pointer;\n \n &:hover {\n border-color: #2196f3;\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.1);\n transform: translateY(-1px);\n }\n \n .card-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 12px;\n \n .prompt-info {\n display: flex;\n gap: 12px;\n flex: 1;\n \n .prompt-icon {\n color: #2196f3;\n font-size: 20px;\n margin-top: 2px;\n }\n \n .prompt-details {\n flex: 1;\n \n .prompt-name {\n margin: 0 0 4px 0;\n font-size: 16px;\n font-weight: 500;\n color: #333;\n }\n \n .prompt-meta {\n font-size: 12px;\n color: #666;\n \n .prompt-type {\n margin-left: 8px;\n }\n }\n }\n }\n }\n \n .card-body {\n margin-bottom: 12px;\n \n .prompt-description {\n margin-bottom: 12px;\n color: #555;\n font-size: 13px;\n line-height: 1.4;\n }\n \n .template-info {\n .template-item {\n display: flex;\n align-items: center;\n margin-bottom: 4px;\n font-size: 12px;\n color: #666;\n \n .fa-solid {\n margin-right: 6px;\n color: #999;\n }\n }\n \n .template-content-info {\n font-size: 11px;\n color: #999;\n }\n }\n }\n \n .card-actions {\n display: flex;\n gap: 8px;\n border-top: 1px solid #f0f0f0;\n padding-top: 12px;\n \n .action-btn {\n padding: 6px 12px;\n border: 1px solid #ddd;\n border-radius: 3px;\n background: white;\n cursor: pointer;\n font-size: 11px;\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all 0.2s;\n \n &:hover {\n background-color: #f5f5f5;\n border-color: #bbb;\n }\n \n &.action-btn-primary {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n \n &:hover {\n background-color: #1976d2;\n }\n }\n \n &.action-btn-danger {\n background-color: #f44336;\n border-color: #f44336;\n color: white;\n \n &:hover {\n background-color: #d32f2f;\n }\n }\n \n .fa-solid {\n font-size: 10px;\n }\n }\n }\n}\n\n// Editor View\n.editor-view {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n}\n\n.editor-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding-bottom: 16px;\n border-bottom: 1px solid #e0e0e0;\n \n .breadcrumb-section {\n .back-btn {\n background: none;\n border: none;\n color: #2196f3;\n cursor: pointer;\n font-size: 12px;\n display: flex;\n align-items: center;\n gap: 6px;\n \n &:hover {\n text-decoration: underline;\n }\n }\n }\n \n .editor-title {\n flex: 1;\n margin: 0 20px;\n \n h2 {\n margin: 0;\n font-size: 18px;\n font-weight: 500;\n color: #333;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n }\n \n .editor-actions {\n display: flex;\n gap: 8px;\n }\n}\n\n.editor-content {\n flex: 1;\n overflow: hidden;\n}\n\n.editor-splitter {\n height: 100%;\n \n .k-pane {\n overflow: hidden;\n }\n}\n\n.prompt-details-panel, .template-editor-panel {\n background: white;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n padding: 16px;\n height: 100%;\n overflow-y: auto;\n \n h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 500;\n color: #333;\n border-bottom: 1px solid #f0f0f0;\n padding-bottom: 8px;\n }\n}\n\n.form-field {\n margin-bottom: 16px;\n \n .field-label {\n display: block;\n margin-bottom: 4px;\n font-size: 12px;\n font-weight: 500;\n color: #555;\n }\n \n .field-input, .field-select {\n width: 100%;\n padding: 6px 8px;\n border: 1px solid #ddd;\n border-radius: 3px;\n font-size: 12px;\n \n &:focus {\n outline: none;\n border-color: #2196f3;\n }\n }\n \n .field-textarea {\n width: 100%;\n padding: 6px 8px;\n border: 1px solid #ddd;\n border-radius: 3px;\n font-size: 12px;\n resize: vertical;\n min-height: 60px;\n \n &:focus {\n outline: none;\n border-color: #2196f3;\n }\n }\n \n .field-value {\n padding: 6px 8px;\n background: #f8f9fa;\n border: 1px solid #e0e0e0;\n border-radius: 3px;\n font-size: 12px;\n color: #555;\n }\n}\n\n.template-editor-panel {\n .editor-container {\n margin-bottom: 16px;\n \n .code-editor {\n width: 100%;\n min-height: 300px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 12px;\n border: 1px solid #ddd;\n border-radius: 3px;\n padding: 8px;\n background: #f8f9fa;\n \n &:focus {\n outline: none;\n border-color: #2196f3;\n }\n }\n \n .code-display {\n border: 1px solid #e0e0e0;\n border-radius: 3px;\n background: #f8f9fa;\n max-height: 400px;\n overflow-y: auto;\n \n pre {\n margin: 0;\n padding: 12px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n font-size: 12px;\n line-height: 1.4;\n color: #333;\n \n code {\n background: none;\n padding: 0;\n font-size: inherit;\n color: inherit;\n }\n }\n }\n }\n \n .editor-help {\n .help-section {\n h5 {\n font-size: 13px;\n font-weight: 500;\n margin-bottom: 8px;\n color: #333;\n }\n \n .syntax-examples {\n .syntax-item {\n margin-bottom: 6px;\n padding: 6px 8px;\n background: #f0f0f0;\n border-radius: 3px;\n font-size: 11px;\n \n code {\n background: #e0e0e0;\n padding: 2px 4px;\n border-radius: 2px;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n margin-right: 8px;\n }\n }\n }\n }\n }\n}\n\n// CodeMirror overrides\n.CodeMirror {\n border: 1px solid #ddd !important;\n border-radius: 3px !important;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace !important;\n font-size: 12px !important;\n min-height: 300px !important;\n}\n\n.CodeMirror-focused {\n border-color: #2196f3 !important;\n}\n\n// Status badges\n.status-badge {\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 500;\n text-transform: uppercase;\n \n &.status-active {\n background: #e8f5e8;\n color: #2e7d32;\n }\n \n &.status-pending {\n background: #fff3e0;\n color: #f57c00;\n }\n \n &.status-disabled {\n background: #ffebee;\n color: #c62828;\n }\n}\n\n// Editor badges\n.editor-badge {\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 500;\n margin-left: 8px;\n \n &.editor-badge-info {\n background: #e3f2fd;\n color: #1976d2;\n }\n \n &.editor-badge-warning {\n background: #fff3e0;\n color: #f57c00;\n }\n \n &.editor-badge-secondary {\n background: #f5f5f5;\n color: #666;\n }\n}\n\n// New category creation\n.new-category-container {\n display: flex;\n gap: 4px;\n align-items: center;\n \n .field-input {\n flex: 1;\n }\n \n .new-category-actions {\n display: flex;\n gap: 2px;\n \n .action-btn {\n padding: 4px 6px;\n border: 1px solid #ddd;\n border-radius: 3px;\n background: white;\n cursor: pointer;\n font-size: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 24px;\n height: 24px;\n \n &:hover {\n background-color: #f5f5f5;\n }\n \n &.action-btn-primary {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n \n &:hover {\n background-color: #1976d2;\n }\n }\n \n .fa-solid {\n font-size: 10px;\n }\n }\n }\n}\n\n.new-category-option {\n color: #2196f3;\n font-style: italic;\n}\n\n// CodeMirror 6 styling\nmj-code-editor {\n display: block;\n border: 1px solid #ddd;\n border-radius: 3px;\n overflow: hidden;\n min-height: 300px;\n \n .cm-editor {\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace !important;\n font-size: 12px !important;\n min-height: 300px;\n }\n \n .cm-focused {\n outline: none !important;\n }\n \n .cm-editor.cm-focused {\n border-color: #2196f3;\n }\n}\n\n// List View Layout\n.list-view {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n}\n\n.sub-navigation {\n display: flex;\n gap: 8px;\n margin-bottom: 16px;\n padding: 8px 0;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n\n .sub-nav-btn {\n padding: 8px 12px;\n border: 1px solid #ddd;\n border-radius: 4px;\n background: white;\n cursor: pointer;\n font-size: 12px;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all 0.2s;\n color: #555;\n font-weight: 500;\n\n &:hover {\n background-color: #f0f0f0;\n border-color: #2196f3;\n color: #2196f3;\n }\n\n &.active {\n background-color: #2196f3;\n border-color: #2196f3;\n color: white;\n box-shadow: 0 2px 4px rgba(33, 150, 243, 0.2);\n }\n\n .fa-solid {\n font-size: 11px;\n }\n }\n}\n\n.main-content {\n flex: 1;\n overflow: hidden;\n}\n\n.main-splitter {\n height: 100%;\n \n .k-pane {\n overflow: hidden;\n }\n}\n\n.prompts-content {\n height: 100%;\n overflow-y: auto;\n padding: 0 16px;\n}"] }]