cloud-ide-layout 1.0.297 → 1.0.302

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 (18) hide show
  1. package/fesm2022/cloud-ide-layout-api-endpoint-manager.component-h6VzYckg.mjs +288 -0
  2. package/fesm2022/cloud-ide-layout-api-endpoint-manager.component-h6VzYckg.mjs.map +1 -0
  3. package/fesm2022/{cloud-ide-layout-cloud-ide-layout-DgwU-sCr.mjs → cloud-ide-layout-cloud-ide-layout-B3aNlPnd.mjs} +36 -21
  4. package/fesm2022/{cloud-ide-layout-cloud-ide-layout-DgwU-sCr.mjs.map → cloud-ide-layout-cloud-ide-layout-B3aNlPnd.mjs.map} +1 -1
  5. package/fesm2022/cloud-ide-layout-dashboard-manager.component-DdEEGw7d.mjs +706 -0
  6. package/fesm2022/cloud-ide-layout-dashboard-manager.component-DdEEGw7d.mjs.map +1 -0
  7. package/fesm2022/{cloud-ide-layout-drawer-theme.component-BWSMDvLy.mjs → cloud-ide-layout-drawer-theme.component-DZxUoK7a.mjs} +4 -4
  8. package/fesm2022/{cloud-ide-layout-drawer-theme.component-BWSMDvLy.mjs.map → cloud-ide-layout-drawer-theme.component-DZxUoK7a.mjs.map} +1 -1
  9. package/fesm2022/{cloud-ide-layout-home-wrapper.component-CH7LlO1x.mjs → cloud-ide-layout-home-wrapper.component-1SSET2sB.mjs} +2 -2
  10. package/fesm2022/{cloud-ide-layout-home-wrapper.component-CH7LlO1x.mjs.map → cloud-ide-layout-home-wrapper.component-1SSET2sB.mjs.map} +1 -1
  11. package/fesm2022/{cloud-ide-layout-sidedrawer-notes.component-DVj6eU3V.mjs → cloud-ide-layout-sidedrawer-notes.component-D4UliYnP.mjs} +4 -4
  12. package/fesm2022/{cloud-ide-layout-sidedrawer-notes.component-DVj6eU3V.mjs.map → cloud-ide-layout-sidedrawer-notes.component-D4UliYnP.mjs.map} +1 -1
  13. package/fesm2022/cloud-ide-layout.mjs +1 -1
  14. package/index.d.ts +1 -1
  15. package/package.json +1 -1
  16. package/README.md +0 -63
  17. package/fesm2022/cloud-ide-layout-dashboard-manager.component-CHthRoQj.mjs +0 -653
  18. package/fesm2022/cloud-ide-layout-dashboard-manager.component-CHthRoQj.mjs.map +0 -1
@@ -0,0 +1,288 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, Injectable, input, output, signal, effect, Component } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import * as i2 from '@angular/forms';
6
+ import { FormBuilder, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
7
+ import { generateStringFromObject, cidePath, hostManagerRoutesUrl, coreRoutesUrl, MApiEndpointMasterGetByIdPayload, MApiEndpointMasterDeletePayload, ApiEndpointMasterSaveUpdatePayload, MApiEndpointMaster } from 'cloud-ide-lms-model';
8
+ import { HttpClient } from '@angular/common/http';
9
+ import { CideEleFloatingContainerService } from 'cloud-ide-element';
10
+ import { C as CideLytSharedWrapperComponent } from './cloud-ide-layout-cloud-ide-layout-B3aNlPnd.mjs';
11
+
12
+ class ApiEndpointMasterService {
13
+ http = inject(HttpClient);
14
+ /**
15
+ * Get API endpoint master list
16
+ * @param payload - MApiEndpointMaster payload for filtering
17
+ * @returns Observable of API endpoints list response
18
+ */
19
+ getApiEndpointMasterList(payload) {
20
+ const query = generateStringFromObject(payload);
21
+ const url = cidePath.join([
22
+ hostManagerRoutesUrl.cideSuiteHost,
23
+ coreRoutesUrl.module,
24
+ coreRoutesUrl.apiEndpointMaster,
25
+ query
26
+ ]);
27
+ return this.http.get(url);
28
+ }
29
+ /**
30
+ * Get API endpoint by ID
31
+ * @param api_id - API ID
32
+ * @returns Observable of API endpoint response
33
+ */
34
+ getApiEndpointById(api_id) {
35
+ const payload = new MApiEndpointMasterGetByIdPayload({ api_id });
36
+ const query = generateStringFromObject(payload);
37
+ const url = cidePath.join([
38
+ hostManagerRoutesUrl.cideSuiteHost,
39
+ coreRoutesUrl.module,
40
+ coreRoutesUrl.apiEndpointMaster,
41
+ 'byId',
42
+ query
43
+ ]);
44
+ return this.http.get(url);
45
+ }
46
+ /**
47
+ * Create or update API endpoint
48
+ * @param payload - ApiEndpointMasterSaveUpdatePayload
49
+ * @returns Observable of insert/update response
50
+ */
51
+ saveUpdateApiEndpoint(payload) {
52
+ const url = cidePath.join([
53
+ hostManagerRoutesUrl.cideSuiteHost,
54
+ coreRoutesUrl.module,
55
+ coreRoutesUrl.apiEndpointMaster
56
+ ]);
57
+ return this.http.post(url, payload);
58
+ }
59
+ /**
60
+ * Delete API endpoint
61
+ * @param api_id - API ID
62
+ * @returns Observable of delete response
63
+ */
64
+ deleteApiEndpoint(api_id) {
65
+ const payload = new MApiEndpointMasterDeletePayload({ api_id });
66
+ const query = generateStringFromObject(payload);
67
+ const url = cidePath.join([
68
+ hostManagerRoutesUrl.cideSuiteHost,
69
+ coreRoutesUrl.module,
70
+ coreRoutesUrl.apiEndpointMaster,
71
+ query
72
+ ]);
73
+ return this.http.delete(url);
74
+ }
75
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ApiEndpointMasterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
76
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ApiEndpointMasterService, providedIn: 'root' });
77
+ }
78
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ApiEndpointMasterService, decorators: [{
79
+ type: Injectable,
80
+ args: [{
81
+ providedIn: 'root'
82
+ }]
83
+ }] });
84
+
85
+ class ApiEndpointFormComponent {
86
+ fb = inject(FormBuilder);
87
+ apiService = inject(ApiEndpointMasterService);
88
+ floatingContainerService = inject(CideEleFloatingContainerService);
89
+ // Inputs
90
+ containerId = input('', ...(ngDevMode ? [{ debugName: "containerId" }] : []));
91
+ editApiData = input(null, ...(ngDevMode ? [{ debugName: "editApiData" }] : []));
92
+ // Outputs
93
+ saved = output();
94
+ cancelled = output();
95
+ // State
96
+ apiForm;
97
+ isSubmitting = signal(false, ...(ngDevMode ? [{ debugName: "isSubmitting" }] : []));
98
+ errorMessage = signal('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
99
+ constructor() {
100
+ this.initForm();
101
+ // React to input changes
102
+ effect(() => {
103
+ const data = this.editApiData();
104
+ if (data) {
105
+ this.apiForm.patchValue({
106
+ api_endpoint: data.api_endpoint,
107
+ api_method: data.api_method,
108
+ api_description: data.api_description,
109
+ api_category: data.api_category,
110
+ api_requires_auth: data.api_requires_auth
111
+ });
112
+ }
113
+ });
114
+ }
115
+ ngOnInit() {
116
+ // Form already initialized in constructor
117
+ }
118
+ initForm() {
119
+ this.apiForm = this.fb.group({
120
+ api_endpoint: ['', [Validators.required]],
121
+ api_method: ['GET', [Validators.required]],
122
+ api_description: ['', [Validators.required]],
123
+ api_category: ['', [Validators.required]],
124
+ api_requires_auth: [true]
125
+ });
126
+ }
127
+ onSubmit() {
128
+ if (this.apiForm.invalid) {
129
+ this.apiForm.markAllAsTouched();
130
+ return;
131
+ }
132
+ this.isSubmitting.set(true);
133
+ this.errorMessage.set('');
134
+ const formValue = this.apiForm.value;
135
+ const apiData = {
136
+ ...formValue
137
+ };
138
+ if (this.editApiData()) {
139
+ apiData._id = this.editApiData()._id;
140
+ }
141
+ const payload = new ApiEndpointMasterSaveUpdatePayload({
142
+ core_api_endpoint_master: apiData
143
+ });
144
+ this.apiService.saveUpdateApiEndpoint(payload).subscribe({
145
+ next: (response) => {
146
+ if (response.success) {
147
+ this.saved.emit();
148
+ this.closeContainer();
149
+ }
150
+ else {
151
+ this.errorMessage.set(response.message || 'Failed to save API endpoint');
152
+ }
153
+ this.isSubmitting.set(false);
154
+ },
155
+ error: (err) => {
156
+ console.error('Error saving API endpoint:', err);
157
+ this.errorMessage.set('An error occurred while saving');
158
+ this.isSubmitting.set(false);
159
+ }
160
+ });
161
+ }
162
+ onCancel() {
163
+ this.cancelled.emit();
164
+ this.closeContainer();
165
+ }
166
+ closeContainer() {
167
+ if (this.containerId()) {
168
+ this.floatingContainerService.hide(this.containerId());
169
+ }
170
+ }
171
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ApiEndpointFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
172
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: ApiEndpointFormComponent, isStandalone: true, selector: "app-api-endpoint-form", inputs: { containerId: { classPropertyName: "containerId", publicName: "containerId", isSignal: true, isRequired: false, transformFunction: null }, editApiData: { classPropertyName: "editApiData", publicName: "editApiData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saved: "saved", cancelled: "cancelled" }, ngImport: i0, template: "<div class=\"h-full flex flex-col bg-white dark:bg-gray-800\">\r\n <form [formGroup]=\"apiForm\" (ngSubmit)=\"onSubmit()\" class=\"flex-1 flex flex-col h-full\">\r\n <!-- Form Body -->\r\n <div class=\"flex-1 overflow-y-auto p-6 space-y-6\">\r\n\r\n <!-- Error Message -->\r\n <div *ngIf=\"errorMessage()\"\r\n class=\"bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 text-red-600 dark:text-red-400 p-3 rounded-lg text-sm\">\r\n {{ errorMessage() }}\r\n </div>\r\n\r\n <!-- Endpoint -->\r\n <div>\r\n <label for=\"api_endpoint\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\r\n Endpoint Path <span class=\"text-red-500\">*</span>\r\n </label>\r\n <input type=\"text\" id=\"api_endpoint\" formControlName=\"api_endpoint\" placeholder=\"/core/example/:id\"\r\n class=\"w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 hover:border-blue-400 outline-none transition-all font-mono text-sm\"\r\n [class.border-red-500]=\"apiForm.get('api_endpoint')?.invalid && apiForm.get('api_endpoint')?.touched\">\r\n <p *ngIf=\"apiForm.get('api_endpoint')?.invalid && apiForm.get('api_endpoint')?.touched\"\r\n class=\"mt-1 text-xs text-red-500\">\r\n Endpoint path is required\r\n </p>\r\n </div>\r\n\r\n <!-- Method -->\r\n <div>\r\n <label for=\"api_method\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\r\n HTTP Method\r\n </label>\r\n <select id=\"api_method\" formControlName=\"api_method\"\r\n class=\"w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 outline-none transition-all\">\r\n <option value=\"GET\">GET</option>\r\n <option value=\"POST\">POST</option>\r\n <option value=\"PUT\">PUT</option>\r\n <option value=\"DELETE\">DELETE</option>\r\n <option value=\"PATCH\">PATCH</option>\r\n </select>\r\n </div>\r\n\r\n <!-- Category -->\r\n <div>\r\n <label for=\"api_category\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\r\n Category <span class=\"text-red-500\">*</span>\r\n </label>\r\n <input type=\"text\" id=\"api_category\" formControlName=\"api_category\"\r\n placeholder=\"e.g. Dashboard, User Management\"\r\n class=\"w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 hover:border-blue-400 outline-none transition-all\"\r\n [class.border-red-500]=\"apiForm.get('api_category')?.invalid && apiForm.get('api_category')?.touched\">\r\n <p *ngIf=\"apiForm.get('api_category')?.invalid && apiForm.get('api_category')?.touched\"\r\n class=\"mt-1 text-xs text-red-500\">\r\n Category is required\r\n </p>\r\n </div>\r\n\r\n <!-- Description -->\r\n <div>\r\n <label for=\"api_description\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\r\n Description <span class=\"text-red-500\">*</span>\r\n </label>\r\n <textarea id=\"api_description\" formControlName=\"api_description\" rows=\"3\"\r\n placeholder=\"What does this endpoint do?\"\r\n class=\"w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 hover:border-blue-400 outline-none transition-all resize-none\"\r\n [class.border-red-500]=\"apiForm.get('api_description')?.invalid && apiForm.get('api_description')?.touched\"></textarea>\r\n <p *ngIf=\"apiForm.get('api_description')?.invalid && apiForm.get('api_description')?.touched\"\r\n class=\"mt-1 text-xs text-red-500\">\r\n Description is required\r\n </p>\r\n </div>\r\n\r\n <!-- Auth Required -->\r\n <div class=\"flex items-center\">\r\n <input type=\"checkbox\" id=\"api_requires_auth\" formControlName=\"api_requires_auth\"\r\n class=\"w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700\">\r\n <label for=\"api_requires_auth\" class=\"ml-2 block text-sm text-gray-700 dark:text-gray-300\">\r\n Requires Authentication\r\n </label>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- Footer Actions -->\r\n <div\r\n class=\"p-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/50 flex justify-end gap-3\">\r\n <button type=\"button\" (click)=\"onCancel()\"\r\n class=\"px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 transition-colors\">\r\n Cancel\r\n </button>\r\n <button type=\"submit\" [disabled]=\"isSubmitting() || apiForm.invalid || apiForm.pristine\"\r\n class=\"px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center gap-2\">\r\n <span *ngIf=\"isSubmitting()\"\r\n class=\"w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin\"></span>\r\n {{ editApiData() ? 'Update' : 'Create' }}\r\n </button>\r\n </div>\r\n </form>\r\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
173
+ }
174
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ApiEndpointFormComponent, decorators: [{
175
+ type: Component,
176
+ args: [{ selector: 'app-api-endpoint-form', standalone: true, imports: [CommonModule, ReactiveFormsModule], template: "<div class=\"h-full flex flex-col bg-white dark:bg-gray-800\">\r\n <form [formGroup]=\"apiForm\" (ngSubmit)=\"onSubmit()\" class=\"flex-1 flex flex-col h-full\">\r\n <!-- Form Body -->\r\n <div class=\"flex-1 overflow-y-auto p-6 space-y-6\">\r\n\r\n <!-- Error Message -->\r\n <div *ngIf=\"errorMessage()\"\r\n class=\"bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 text-red-600 dark:text-red-400 p-3 rounded-lg text-sm\">\r\n {{ errorMessage() }}\r\n </div>\r\n\r\n <!-- Endpoint -->\r\n <div>\r\n <label for=\"api_endpoint\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\r\n Endpoint Path <span class=\"text-red-500\">*</span>\r\n </label>\r\n <input type=\"text\" id=\"api_endpoint\" formControlName=\"api_endpoint\" placeholder=\"/core/example/:id\"\r\n class=\"w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 hover:border-blue-400 outline-none transition-all font-mono text-sm\"\r\n [class.border-red-500]=\"apiForm.get('api_endpoint')?.invalid && apiForm.get('api_endpoint')?.touched\">\r\n <p *ngIf=\"apiForm.get('api_endpoint')?.invalid && apiForm.get('api_endpoint')?.touched\"\r\n class=\"mt-1 text-xs text-red-500\">\r\n Endpoint path is required\r\n </p>\r\n </div>\r\n\r\n <!-- Method -->\r\n <div>\r\n <label for=\"api_method\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\r\n HTTP Method\r\n </label>\r\n <select id=\"api_method\" formControlName=\"api_method\"\r\n class=\"w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 outline-none transition-all\">\r\n <option value=\"GET\">GET</option>\r\n <option value=\"POST\">POST</option>\r\n <option value=\"PUT\">PUT</option>\r\n <option value=\"DELETE\">DELETE</option>\r\n <option value=\"PATCH\">PATCH</option>\r\n </select>\r\n </div>\r\n\r\n <!-- Category -->\r\n <div>\r\n <label for=\"api_category\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\r\n Category <span class=\"text-red-500\">*</span>\r\n </label>\r\n <input type=\"text\" id=\"api_category\" formControlName=\"api_category\"\r\n placeholder=\"e.g. Dashboard, User Management\"\r\n class=\"w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 hover:border-blue-400 outline-none transition-all\"\r\n [class.border-red-500]=\"apiForm.get('api_category')?.invalid && apiForm.get('api_category')?.touched\">\r\n <p *ngIf=\"apiForm.get('api_category')?.invalid && apiForm.get('api_category')?.touched\"\r\n class=\"mt-1 text-xs text-red-500\">\r\n Category is required\r\n </p>\r\n </div>\r\n\r\n <!-- Description -->\r\n <div>\r\n <label for=\"api_description\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\r\n Description <span class=\"text-red-500\">*</span>\r\n </label>\r\n <textarea id=\"api_description\" formControlName=\"api_description\" rows=\"3\"\r\n placeholder=\"What does this endpoint do?\"\r\n class=\"w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 hover:border-blue-400 outline-none transition-all resize-none\"\r\n [class.border-red-500]=\"apiForm.get('api_description')?.invalid && apiForm.get('api_description')?.touched\"></textarea>\r\n <p *ngIf=\"apiForm.get('api_description')?.invalid && apiForm.get('api_description')?.touched\"\r\n class=\"mt-1 text-xs text-red-500\">\r\n Description is required\r\n </p>\r\n </div>\r\n\r\n <!-- Auth Required -->\r\n <div class=\"flex items-center\">\r\n <input type=\"checkbox\" id=\"api_requires_auth\" formControlName=\"api_requires_auth\"\r\n class=\"w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700\">\r\n <label for=\"api_requires_auth\" class=\"ml-2 block text-sm text-gray-700 dark:text-gray-300\">\r\n Requires Authentication\r\n </label>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- Footer Actions -->\r\n <div\r\n class=\"p-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/50 flex justify-end gap-3\">\r\n <button type=\"button\" (click)=\"onCancel()\"\r\n class=\"px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 transition-colors\">\r\n Cancel\r\n </button>\r\n <button type=\"submit\" [disabled]=\"isSubmitting() || apiForm.invalid || apiForm.pristine\"\r\n class=\"px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center gap-2\">\r\n <span *ngIf=\"isSubmitting()\"\r\n class=\"w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin\"></span>\r\n {{ editApiData() ? 'Update' : 'Create' }}\r\n </button>\r\n </div>\r\n </form>\r\n</div>" }]
177
+ }], ctorParameters: () => [], propDecorators: { containerId: [{ type: i0.Input, args: [{ isSignal: true, alias: "containerId", required: false }] }], editApiData: [{ type: i0.Input, args: [{ isSignal: true, alias: "editApiData", required: false }] }], saved: [{ type: i0.Output, args: ["saved"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
178
+
179
+ class ApiEndpointManagerComponent {
180
+ apiService = inject(ApiEndpointMasterService);
181
+ floatingContainerService = inject(CideEleFloatingContainerService);
182
+ shared_wrapper_setup_param = {
183
+ sypg_page_code: "cide_lyt_api_endpoint_manager"
184
+ };
185
+ // Signals
186
+ apiList = signal([], ...(ngDevMode ? [{ debugName: "apiList" }] : []));
187
+ totalRecords = signal(0, ...(ngDevMode ? [{ debugName: "totalRecords" }] : []));
188
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
189
+ searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : []));
190
+ // Pagination
191
+ pageSize = signal(20, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
192
+ pageIndex = signal(1, ...(ngDevMode ? [{ debugName: "pageIndex" }] : []));
193
+ constructor() {
194
+ // Register the form component with the floating container service
195
+ this.floatingContainerService.registerComponent('api-endpoint-form', ApiEndpointFormComponent);
196
+ }
197
+ ngOnInit() {
198
+ this.loadApiList();
199
+ }
200
+ loadApiList() {
201
+ this.loading.set(true);
202
+ const payload = new MApiEndpointMaster({
203
+ query: this.searchQuery(),
204
+ pageSize: this.pageSize(),
205
+ pageIndex: this.pageIndex()
206
+ });
207
+ this.apiService.getApiEndpointMasterList(payload).subscribe({
208
+ next: (response) => {
209
+ if (response.success && response.data) {
210
+ this.apiList.set(response.data);
211
+ this.totalRecords.set(response.total || 0);
212
+ }
213
+ else {
214
+ this.apiList.set([]);
215
+ this.totalRecords.set(0);
216
+ }
217
+ this.loading.set(false);
218
+ },
219
+ error: (err) => {
220
+ console.error('Error fetching API list:', err);
221
+ this.loading.set(false);
222
+ }
223
+ });
224
+ }
225
+ onSearch(query) {
226
+ this.searchQuery.set(query);
227
+ this.pageIndex.set(1);
228
+ this.loadApiList();
229
+ }
230
+ onPageChange(page) {
231
+ this.pageIndex.set(page);
232
+ this.loadApiList();
233
+ }
234
+ openApiForm(apiData) {
235
+ const config = {
236
+ id: apiData ? `edit-api-${apiData._id}` : 'new-api-endpoint',
237
+ title: apiData ? 'Edit API Endpoint' : 'Add New API Endpoint',
238
+ width: '500px',
239
+ height: 'auto',
240
+ minWidth: '400px',
241
+ minHeight: '300px',
242
+ backdrop: true,
243
+ componentId: 'api-endpoint-form',
244
+ componentConfig: {
245
+ inputs: {
246
+ containerId: signal(apiData ? `edit-api-${apiData._id}` : 'new-api-endpoint'),
247
+ editApiData: signal(apiData || null)
248
+ },
249
+ outputs: {
250
+ saved: () => {
251
+ this.loadApiList();
252
+ },
253
+ cancelled: () => {
254
+ // Container handles closing
255
+ }
256
+ }
257
+ }
258
+ };
259
+ this.floatingContainerService.show(config);
260
+ }
261
+ deleteApi(apiId) {
262
+ if (!apiId) {
263
+ console.error('API endpoint id is missing');
264
+ return;
265
+ }
266
+ if (confirm('Are you sure you want to delete this API endpoint?')) {
267
+ this.apiService.deleteApiEndpoint(apiId).subscribe({
268
+ next: (response) => {
269
+ if (response.success) {
270
+ this.loadApiList();
271
+ }
272
+ },
273
+ error: (err) => {
274
+ console.error('Error deleting API endpoint:', err);
275
+ }
276
+ });
277
+ }
278
+ }
279
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ApiEndpointManagerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
280
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: ApiEndpointManagerComponent, isStandalone: true, selector: "app-api-endpoint-manager", ngImport: i0, template: "<cide-lyt-shared-wrapper [shared_wrapper_setup_param]=\"shared_wrapper_setup_param\">\r\n <!-- Breadcrumb Actions -->\r\n <div breadcrumb-actions>\r\n <button (click)=\"openApiForm()\"\r\n class=\"bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg flex items-center gap-2 transition-colors\">\r\n <i class=\"cide-icon-plus\"></i>\r\n <span>Add New Endpoint</span>\r\n </button>\r\n </div>\r\n\r\n <!-- Main Content -->\r\n <div class=\"h-full flex flex-col bg-gray-50 dark:bg-gray-900 p-4\">\r\n\r\n <!-- Search & Filter -->\r\n <div class=\"mb-6\">\r\n <div class=\"relative max-w-md\">\r\n <input type=\"text\" [ngModel]=\"searchQuery()\" (ngModelChange)=\"onSearch($event)\"\r\n placeholder=\"Search endpoints, descriptions...\"\r\n class=\"w-full pl-10 pr-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all\">\r\n <i class=\"cide-icon-search absolute left-3 top-1/2 -translate-y-1/2 text-gray-400\"></i>\r\n </div>\r\n </div>\r\n\r\n <!-- Data Table -->\r\n <div\r\n class=\"flex-1 overflow-hidden bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 flex flex-col\">\r\n <div class=\"overflow-x-auto flex-1\">\r\n <table class=\"w-full text-left border-collapse\">\r\n <thead class=\"bg-gray-50 dark:bg-gray-900/50 sticky top-0 z-10\">\r\n <tr>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700\">\r\n Method</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700\">\r\n Endpoint</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700\">\r\n Description</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700\">\r\n Category</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 text-center\">\r\n Auth</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 text-right\">\r\n Actions</th>\r\n </tr>\r\n </thead>\r\n <tbody class=\"divide-y divide-gray-200 dark:divide-gray-700\">\r\n <tr *ngFor=\"let api of apiList()\"\r\n class=\"hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors\">\r\n <td class=\"p-4 whitespace-nowrap\">\r\n <span class=\"px-2 py-1 text-xs font-bold rounded\" [ngClass]=\"{\r\n 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400': api.api_method === 'GET',\r\n 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400': api.api_method === 'POST',\r\n 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400': api.api_method === 'PUT',\r\n 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400': api.api_method === 'DELETE',\r\n 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400': api.api_method === 'PATCH'\r\n }\">\r\n {{ api.api_method }}\r\n </span>\r\n </td>\r\n <td class=\"p-4 text-sm font-medium text-gray-900 dark:text-gray-100 font-mono\">{{\r\n api.api_endpoint }}</td>\r\n <td class=\"p-4 text-sm text-gray-500 dark:text-gray-400 max-w-xs truncate\"\r\n title=\"{{ api.api_description }}\">{{ api.api_description }}</td>\r\n <td class=\"p-4 text-sm text-gray-500 dark:text-gray-400\">\r\n <span\r\n class=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300\">\r\n {{ api.api_category }}\r\n </span>\r\n </td>\r\n <td class=\"p-4 text-center\">\r\n <i class=\"text-sm\"\r\n [ngClass]=\"api.api_requires_auth ? 'cide-icon-lock text-green-500' : 'cide-icon-unlock text-gray-400'\"></i>\r\n </td>\r\n <td class=\"p-4 text-right whitespace-nowrap\">\r\n <button (click)=\"openApiForm(api)\"\r\n class=\"text-blue-600 hover:text-blue-800 p-1 mr-2 transition-colors\" title=\"Edit\">\r\n <i class=\"cide-icon-edit\"></i>\r\n </button>\r\n <button (click)=\"deleteApi(api._id)\"\r\n class=\"text-red-600 hover:text-red-800 p-1 transition-colors\" title=\"Delete\">\r\n <i class=\"cide-icon-trash\"></i>\r\n </button>\r\n </td>\r\n </tr>\r\n <tr *ngIf=\"apiList().length === 0 && !loading()\">\r\n <td colspan=\"6\" class=\"p-8 text-center text-gray-500 dark:text-gray-400\">\r\n <div class=\"flex flex-col items-center\">\r\n <i class=\"cide-icon-database text-4xl mb-3 opacity-50\"></i>\r\n <p>No API endpoints found</p>\r\n </div>\r\n </td>\r\n </tr>\r\n <tr *ngIf=\"loading()\">\r\n <td colspan=\"6\" class=\"p-8 text-center\">\r\n <div class=\"flex justify-center\">\r\n <div class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600\"></div>\r\n </div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- Footer / Pagination -->\r\n <div\r\n class=\"p-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/50 flex justify-between items-center text-sm text-gray-600 dark:text-gray-400\">\r\n <span>Showing {{ apiList().length }} of {{ totalRecords() }} endpoints</span>\r\n <div class=\"flex gap-2\">\r\n <button [disabled]=\"pageIndex() <= 1\" (click)=\"onPageChange(pageIndex() - 1)\"\r\n class=\"px-3 py-1 rounded border border-gray-300 dark:border-gray-600 disabled:opacity-50 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors\">\r\n Previous\r\n </button>\r\n <button [disabled]=\"apiList().length < pageSize()\" (click)=\"onPageChange(pageIndex() + 1)\"\r\n class=\"px-3 py-1 rounded border border-gray-300 dark:border-gray-600 disabled:opacity-50 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors\">\r\n Next\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</cide-lyt-shared-wrapper>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: CideLytSharedWrapperComponent, selector: "cide-lyt-shared-wrapper", inputs: ["shared_wrapper_setup_param", "breadcrumb_data"] }] });
281
+ }
282
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ApiEndpointManagerComponent, decorators: [{
283
+ type: Component,
284
+ args: [{ selector: 'app-api-endpoint-manager', standalone: true, imports: [CommonModule, FormsModule, ReactiveFormsModule, CideLytSharedWrapperComponent], template: "<cide-lyt-shared-wrapper [shared_wrapper_setup_param]=\"shared_wrapper_setup_param\">\r\n <!-- Breadcrumb Actions -->\r\n <div breadcrumb-actions>\r\n <button (click)=\"openApiForm()\"\r\n class=\"bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg flex items-center gap-2 transition-colors\">\r\n <i class=\"cide-icon-plus\"></i>\r\n <span>Add New Endpoint</span>\r\n </button>\r\n </div>\r\n\r\n <!-- Main Content -->\r\n <div class=\"h-full flex flex-col bg-gray-50 dark:bg-gray-900 p-4\">\r\n\r\n <!-- Search & Filter -->\r\n <div class=\"mb-6\">\r\n <div class=\"relative max-w-md\">\r\n <input type=\"text\" [ngModel]=\"searchQuery()\" (ngModelChange)=\"onSearch($event)\"\r\n placeholder=\"Search endpoints, descriptions...\"\r\n class=\"w-full pl-10 pr-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all\">\r\n <i class=\"cide-icon-search absolute left-3 top-1/2 -translate-y-1/2 text-gray-400\"></i>\r\n </div>\r\n </div>\r\n\r\n <!-- Data Table -->\r\n <div\r\n class=\"flex-1 overflow-hidden bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 flex flex-col\">\r\n <div class=\"overflow-x-auto flex-1\">\r\n <table class=\"w-full text-left border-collapse\">\r\n <thead class=\"bg-gray-50 dark:bg-gray-900/50 sticky top-0 z-10\">\r\n <tr>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700\">\r\n Method</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700\">\r\n Endpoint</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700\">\r\n Description</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700\">\r\n Category</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 text-center\">\r\n Auth</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 text-right\">\r\n Actions</th>\r\n </tr>\r\n </thead>\r\n <tbody class=\"divide-y divide-gray-200 dark:divide-gray-700\">\r\n <tr *ngFor=\"let api of apiList()\"\r\n class=\"hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors\">\r\n <td class=\"p-4 whitespace-nowrap\">\r\n <span class=\"px-2 py-1 text-xs font-bold rounded\" [ngClass]=\"{\r\n 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400': api.api_method === 'GET',\r\n 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400': api.api_method === 'POST',\r\n 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400': api.api_method === 'PUT',\r\n 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400': api.api_method === 'DELETE',\r\n 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400': api.api_method === 'PATCH'\r\n }\">\r\n {{ api.api_method }}\r\n </span>\r\n </td>\r\n <td class=\"p-4 text-sm font-medium text-gray-900 dark:text-gray-100 font-mono\">{{\r\n api.api_endpoint }}</td>\r\n <td class=\"p-4 text-sm text-gray-500 dark:text-gray-400 max-w-xs truncate\"\r\n title=\"{{ api.api_description }}\">{{ api.api_description }}</td>\r\n <td class=\"p-4 text-sm text-gray-500 dark:text-gray-400\">\r\n <span\r\n class=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300\">\r\n {{ api.api_category }}\r\n </span>\r\n </td>\r\n <td class=\"p-4 text-center\">\r\n <i class=\"text-sm\"\r\n [ngClass]=\"api.api_requires_auth ? 'cide-icon-lock text-green-500' : 'cide-icon-unlock text-gray-400'\"></i>\r\n </td>\r\n <td class=\"p-4 text-right whitespace-nowrap\">\r\n <button (click)=\"openApiForm(api)\"\r\n class=\"text-blue-600 hover:text-blue-800 p-1 mr-2 transition-colors\" title=\"Edit\">\r\n <i class=\"cide-icon-edit\"></i>\r\n </button>\r\n <button (click)=\"deleteApi(api._id)\"\r\n class=\"text-red-600 hover:text-red-800 p-1 transition-colors\" title=\"Delete\">\r\n <i class=\"cide-icon-trash\"></i>\r\n </button>\r\n </td>\r\n </tr>\r\n <tr *ngIf=\"apiList().length === 0 && !loading()\">\r\n <td colspan=\"6\" class=\"p-8 text-center text-gray-500 dark:text-gray-400\">\r\n <div class=\"flex flex-col items-center\">\r\n <i class=\"cide-icon-database text-4xl mb-3 opacity-50\"></i>\r\n <p>No API endpoints found</p>\r\n </div>\r\n </td>\r\n </tr>\r\n <tr *ngIf=\"loading()\">\r\n <td colspan=\"6\" class=\"p-8 text-center\">\r\n <div class=\"flex justify-center\">\r\n <div class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600\"></div>\r\n </div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- Footer / Pagination -->\r\n <div\r\n class=\"p-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/50 flex justify-between items-center text-sm text-gray-600 dark:text-gray-400\">\r\n <span>Showing {{ apiList().length }} of {{ totalRecords() }} endpoints</span>\r\n <div class=\"flex gap-2\">\r\n <button [disabled]=\"pageIndex() <= 1\" (click)=\"onPageChange(pageIndex() - 1)\"\r\n class=\"px-3 py-1 rounded border border-gray-300 dark:border-gray-600 disabled:opacity-50 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors\">\r\n Previous\r\n </button>\r\n <button [disabled]=\"apiList().length < pageSize()\" (click)=\"onPageChange(pageIndex() + 1)\"\r\n class=\"px-3 py-1 rounded border border-gray-300 dark:border-gray-600 disabled:opacity-50 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors\">\r\n Next\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</cide-lyt-shared-wrapper>" }]
285
+ }], ctorParameters: () => [] });
286
+
287
+ export { ApiEndpointManagerComponent };
288
+ //# sourceMappingURL=cloud-ide-layout-api-endpoint-manager.component-h6VzYckg.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-ide-layout-api-endpoint-manager.component-h6VzYckg.mjs","sources":["../../../projects/cloud-ide-layout/src/lib/services/api-endpoint-master.service.ts","../../../projects/cloud-ide-layout/src/lib/components/api-endpoint-manager/api-endpoint-form.component.ts","../../../projects/cloud-ide-layout/src/lib/components/api-endpoint-manager/api-endpoint-form.component.html","../../../projects/cloud-ide-layout/src/lib/components/api-endpoint-manager/api-endpoint-manager.component.ts","../../../projects/cloud-ide-layout/src/lib/components/api-endpoint-manager/api-endpoint-manager.component.html"],"sourcesContent":["import { Injectable, inject } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { Observable } from 'rxjs';\r\nimport {\r\n cidePath,\r\n coreRoutesUrl,\r\n hostManagerRoutesUrl,\r\n apiEndpointMasterControllerResponse,\r\n apiEndpointMasterByIdControllerResponse,\r\n apiEndpointMasterInsertUpdateControllerResponse,\r\n controllerResponse,\r\n MApiEndpointMaster,\r\n ApiEndpointMasterSaveUpdatePayload,\r\n generateStringFromObject,\r\n MApiEndpointMasterGetByIdPayload,\r\n MApiEndpointMasterDeletePayload\r\n} from 'cloud-ide-lms-model';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class ApiEndpointMasterService {\r\n private http = inject(HttpClient);\r\n\r\n /**\r\n * Get API endpoint master list\r\n * @param payload - MApiEndpointMaster payload for filtering\r\n * @returns Observable of API endpoints list response\r\n */\r\n getApiEndpointMasterList(payload: Partial<MApiEndpointMaster>): Observable<apiEndpointMasterControllerResponse> {\r\n const query = generateStringFromObject(payload);\r\n const url = cidePath.join([\r\n hostManagerRoutesUrl.cideSuiteHost,\r\n coreRoutesUrl.module,\r\n coreRoutesUrl.apiEndpointMaster,\r\n query\r\n ]);\r\n\r\n return this.http.get(url) as Observable<apiEndpointMasterControllerResponse>;\r\n }\r\n\r\n /**\r\n * Get API endpoint by ID\r\n * @param api_id - API ID\r\n * @returns Observable of API endpoint response\r\n */\r\n getApiEndpointById(api_id: string): Observable<apiEndpointMasterByIdControllerResponse> {\r\n const payload = new MApiEndpointMasterGetByIdPayload({ api_id });\r\n const query = generateStringFromObject(payload);\r\n const url = cidePath.join([\r\n hostManagerRoutesUrl.cideSuiteHost,\r\n coreRoutesUrl.module,\r\n coreRoutesUrl.apiEndpointMaster,\r\n 'byId',\r\n query\r\n ]);\r\n\r\n return this.http.get(url) as Observable<apiEndpointMasterByIdControllerResponse>;\r\n }\r\n\r\n /**\r\n * Create or update API endpoint\r\n * @param payload - ApiEndpointMasterSaveUpdatePayload\r\n * @returns Observable of insert/update response\r\n */\r\n saveUpdateApiEndpoint(payload: ApiEndpointMasterSaveUpdatePayload): Observable<apiEndpointMasterInsertUpdateControllerResponse> {\r\n const url = cidePath.join([\r\n hostManagerRoutesUrl.cideSuiteHost,\r\n coreRoutesUrl.module,\r\n coreRoutesUrl.apiEndpointMaster\r\n ]);\r\n\r\n return this.http.post(url, payload) as Observable<apiEndpointMasterInsertUpdateControllerResponse>;\r\n }\r\n\r\n /**\r\n * Delete API endpoint\r\n * @param api_id - API ID\r\n * @returns Observable of delete response\r\n */\r\n deleteApiEndpoint(api_id: string): Observable<controllerResponse> {\r\n const payload = new MApiEndpointMasterDeletePayload({ api_id });\r\n const query = generateStringFromObject(payload);\r\n const url = cidePath.join([\r\n hostManagerRoutesUrl.cideSuiteHost,\r\n coreRoutesUrl.module,\r\n coreRoutesUrl.apiEndpointMaster,\r\n query\r\n ]);\r\n\r\n return this.http.delete(url) as Observable<controllerResponse>;\r\n }\r\n}\r\n","import { Component, inject, signal, input, output, OnInit, effect } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';\r\nimport { CoreApiEndpointMaster, ApiEndpointMasterSaveUpdatePayload } from 'cloud-ide-lms-model';\r\nimport { ApiEndpointMasterService } from '../../services/api-endpoint-master.service';\r\nimport { CideEleFloatingContainerService } from 'cloud-ide-element';\r\n\r\n@Component({\r\n selector: 'app-api-endpoint-form',\r\n standalone: true,\r\n imports: [CommonModule, ReactiveFormsModule],\r\n templateUrl: './api-endpoint-form.component.html',\r\n styleUrls: ['./api-endpoint-form.component.css']\r\n})\r\nexport class ApiEndpointFormComponent implements OnInit {\r\n private fb = inject(FormBuilder);\r\n private apiService = inject(ApiEndpointMasterService);\r\n private floatingContainerService = inject(CideEleFloatingContainerService);\r\n\r\n // Inputs\r\n containerId = input<string>('');\r\n editApiData = input<CoreApiEndpointMaster | null>(null);\r\n\r\n // Outputs\r\n saved = output<void>();\r\n cancelled = output<void>();\r\n\r\n // State\r\n apiForm!: FormGroup;\r\n isSubmitting = signal<boolean>(false);\r\n errorMessage = signal<string>('');\r\n\r\n constructor() {\r\n this.initForm();\r\n\r\n // React to input changes\r\n effect(() => {\r\n const data = this.editApiData();\r\n if (data) {\r\n this.apiForm.patchValue({\r\n api_endpoint: data.api_endpoint,\r\n api_method: data.api_method,\r\n api_description: data.api_description,\r\n api_category: data.api_category,\r\n api_requires_auth: data.api_requires_auth\r\n });\r\n }\r\n });\r\n }\r\n\r\n ngOnInit(): void {\r\n // Form already initialized in constructor\r\n }\r\n\r\n private initForm() {\r\n this.apiForm = this.fb.group({\r\n api_endpoint: ['', [Validators.required]],\r\n api_method: ['GET', [Validators.required]],\r\n api_description: ['', [Validators.required]],\r\n api_category: ['', [Validators.required]],\r\n api_requires_auth: [true]\r\n });\r\n }\r\n\r\n onSubmit() {\r\n if (this.apiForm.invalid) {\r\n this.apiForm.markAllAsTouched();\r\n return;\r\n }\r\n\r\n this.isSubmitting.set(true);\r\n this.errorMessage.set('');\r\n\r\n const formValue = this.apiForm.value;\r\n const apiData: CoreApiEndpointMaster = {\r\n ...formValue\r\n };\r\n\r\n if (this.editApiData()) {\r\n apiData._id = this.editApiData()!._id;\r\n }\r\n\r\n const payload = new ApiEndpointMasterSaveUpdatePayload({\r\n core_api_endpoint_master: apiData\r\n });\r\n\r\n this.apiService.saveUpdateApiEndpoint(payload).subscribe({\r\n next: (response) => {\r\n if (response.success) {\r\n this.saved.emit();\r\n this.closeContainer();\r\n } else {\r\n this.errorMessage.set(response.message || 'Failed to save API endpoint');\r\n }\r\n this.isSubmitting.set(false);\r\n },\r\n error: (err) => {\r\n console.error('Error saving API endpoint:', err);\r\n this.errorMessage.set('An error occurred while saving');\r\n this.isSubmitting.set(false);\r\n }\r\n });\r\n }\r\n\r\n onCancel() {\r\n this.cancelled.emit();\r\n this.closeContainer();\r\n }\r\n\r\n private closeContainer() {\r\n if (this.containerId()) {\r\n this.floatingContainerService.hide(this.containerId());\r\n }\r\n }\r\n}\r\n","<div class=\"h-full flex flex-col bg-white dark:bg-gray-800\">\r\n <form [formGroup]=\"apiForm\" (ngSubmit)=\"onSubmit()\" class=\"flex-1 flex flex-col h-full\">\r\n <!-- Form Body -->\r\n <div class=\"flex-1 overflow-y-auto p-6 space-y-6\">\r\n\r\n <!-- Error Message -->\r\n <div *ngIf=\"errorMessage()\"\r\n class=\"bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 text-red-600 dark:text-red-400 p-3 rounded-lg text-sm\">\r\n {{ errorMessage() }}\r\n </div>\r\n\r\n <!-- Endpoint -->\r\n <div>\r\n <label for=\"api_endpoint\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\r\n Endpoint Path <span class=\"text-red-500\">*</span>\r\n </label>\r\n <input type=\"text\" id=\"api_endpoint\" formControlName=\"api_endpoint\" placeholder=\"/core/example/:id\"\r\n class=\"w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 hover:border-blue-400 outline-none transition-all font-mono text-sm\"\r\n [class.border-red-500]=\"apiForm.get('api_endpoint')?.invalid && apiForm.get('api_endpoint')?.touched\">\r\n <p *ngIf=\"apiForm.get('api_endpoint')?.invalid && apiForm.get('api_endpoint')?.touched\"\r\n class=\"mt-1 text-xs text-red-500\">\r\n Endpoint path is required\r\n </p>\r\n </div>\r\n\r\n <!-- Method -->\r\n <div>\r\n <label for=\"api_method\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\r\n HTTP Method\r\n </label>\r\n <select id=\"api_method\" formControlName=\"api_method\"\r\n class=\"w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 outline-none transition-all\">\r\n <option value=\"GET\">GET</option>\r\n <option value=\"POST\">POST</option>\r\n <option value=\"PUT\">PUT</option>\r\n <option value=\"DELETE\">DELETE</option>\r\n <option value=\"PATCH\">PATCH</option>\r\n </select>\r\n </div>\r\n\r\n <!-- Category -->\r\n <div>\r\n <label for=\"api_category\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\r\n Category <span class=\"text-red-500\">*</span>\r\n </label>\r\n <input type=\"text\" id=\"api_category\" formControlName=\"api_category\"\r\n placeholder=\"e.g. Dashboard, User Management\"\r\n class=\"w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 hover:border-blue-400 outline-none transition-all\"\r\n [class.border-red-500]=\"apiForm.get('api_category')?.invalid && apiForm.get('api_category')?.touched\">\r\n <p *ngIf=\"apiForm.get('api_category')?.invalid && apiForm.get('api_category')?.touched\"\r\n class=\"mt-1 text-xs text-red-500\">\r\n Category is required\r\n </p>\r\n </div>\r\n\r\n <!-- Description -->\r\n <div>\r\n <label for=\"api_description\" class=\"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1\">\r\n Description <span class=\"text-red-500\">*</span>\r\n </label>\r\n <textarea id=\"api_description\" formControlName=\"api_description\" rows=\"3\"\r\n placeholder=\"What does this endpoint do?\"\r\n class=\"w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 hover:border-blue-400 outline-none transition-all resize-none\"\r\n [class.border-red-500]=\"apiForm.get('api_description')?.invalid && apiForm.get('api_description')?.touched\"></textarea>\r\n <p *ngIf=\"apiForm.get('api_description')?.invalid && apiForm.get('api_description')?.touched\"\r\n class=\"mt-1 text-xs text-red-500\">\r\n Description is required\r\n </p>\r\n </div>\r\n\r\n <!-- Auth Required -->\r\n <div class=\"flex items-center\">\r\n <input type=\"checkbox\" id=\"api_requires_auth\" formControlName=\"api_requires_auth\"\r\n class=\"w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700\">\r\n <label for=\"api_requires_auth\" class=\"ml-2 block text-sm text-gray-700 dark:text-gray-300\">\r\n Requires Authentication\r\n </label>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- Footer Actions -->\r\n <div\r\n class=\"p-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/50 flex justify-end gap-3\">\r\n <button type=\"button\" (click)=\"onCancel()\"\r\n class=\"px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 transition-colors\">\r\n Cancel\r\n </button>\r\n <button type=\"submit\" [disabled]=\"isSubmitting() || apiForm.invalid || apiForm.pristine\"\r\n class=\"px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center gap-2\">\r\n <span *ngIf=\"isSubmitting()\"\r\n class=\"w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin\"></span>\r\n {{ editApiData() ? 'Update' : 'Create' }}\r\n </button>\r\n </div>\r\n </form>\r\n</div>","import { Component, inject, signal, OnInit } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\r\nimport {\r\n CoreApiEndpointMaster,\r\n MApiEndpointMaster,\r\n ApiEndpointMasterListResponse\r\n} from 'cloud-ide-lms-model';\r\nimport { ApiEndpointMasterService } from '../../services/api-endpoint-master.service';\r\nimport { CideEleFloatingContainerService, FloatingContainerConfig } from 'cloud-ide-element';\r\nimport { ApiEndpointFormComponent } from './api-endpoint-form.component';\r\nimport { CideLytSharedWrapperComponent } from '../../layout/shared/shared-wrapper/shared-wrapper.component';\r\n\r\n@Component({\r\n selector: 'app-api-endpoint-manager',\r\n standalone: true,\r\n imports: [CommonModule, FormsModule, ReactiveFormsModule, CideLytSharedWrapperComponent],\r\n templateUrl: './api-endpoint-manager.component.html',\r\n styleUrls: ['./api-endpoint-manager.component.css']\r\n})\r\nexport class ApiEndpointManagerComponent implements OnInit {\r\n private apiService = inject(ApiEndpointMasterService);\r\n private floatingContainerService = inject(CideEleFloatingContainerService);\r\n\r\n shared_wrapper_setup_param = {\r\n sypg_page_code: \"cide_lyt_api_endpoint_manager\"\r\n };\r\n\r\n // Signals\r\n apiList = signal<ApiEndpointMasterListResponse[]>([]);\r\n totalRecords = signal<number>(0);\r\n loading = signal<boolean>(false);\r\n searchQuery = signal<string>('');\r\n\r\n // Pagination\r\n pageSize = signal<number>(20);\r\n pageIndex = signal<number>(1);\r\n\r\n constructor() {\r\n // Register the form component with the floating container service\r\n this.floatingContainerService.registerComponent('api-endpoint-form', ApiEndpointFormComponent);\r\n }\r\n\r\n ngOnInit(): void {\r\n this.loadApiList();\r\n }\r\n\r\n loadApiList() {\r\n this.loading.set(true);\r\n const payload = new MApiEndpointMaster({\r\n query: this.searchQuery(),\r\n pageSize: this.pageSize(),\r\n pageIndex: this.pageIndex()\r\n });\r\n\r\n this.apiService.getApiEndpointMasterList(payload).subscribe({\r\n next: (response) => {\r\n if (response.success && response.data) {\r\n this.apiList.set(response.data);\r\n this.totalRecords.set(response.total || 0);\r\n } else {\r\n this.apiList.set([]);\r\n this.totalRecords.set(0);\r\n }\r\n this.loading.set(false);\r\n },\r\n error: (err) => {\r\n console.error('Error fetching API list:', err);\r\n this.loading.set(false);\r\n }\r\n });\r\n }\r\n\r\n onSearch(query: string) {\r\n this.searchQuery.set(query);\r\n this.pageIndex.set(1);\r\n this.loadApiList();\r\n }\r\n\r\n onPageChange(page: number) {\r\n this.pageIndex.set(page);\r\n this.loadApiList();\r\n }\r\n\r\n openApiForm(apiData?: CoreApiEndpointMaster | ApiEndpointMasterListResponse) {\r\n const config: FloatingContainerConfig = {\r\n id: apiData ? `edit-api-${apiData._id}` : 'new-api-endpoint',\r\n title: apiData ? 'Edit API Endpoint' : 'Add New API Endpoint',\r\n width: '500px',\r\n height: 'auto',\r\n minWidth: '400px',\r\n minHeight: '300px',\r\n backdrop: true,\r\n componentId: 'api-endpoint-form',\r\n componentConfig: {\r\n inputs: {\r\n containerId: signal(apiData ? `edit-api-${apiData._id}` : 'new-api-endpoint'),\r\n editApiData: signal(apiData || null)\r\n },\r\n outputs: {\r\n saved: () => {\r\n this.loadApiList();\r\n },\r\n cancelled: () => {\r\n // Container handles closing\r\n }\r\n }\r\n }\r\n };\r\n\r\n this.floatingContainerService.show(config);\r\n }\r\n\r\n deleteApi(apiId?: string) {\r\n if (!apiId) {\r\n console.error('API endpoint id is missing');\r\n return;\r\n }\r\n\r\n if (confirm('Are you sure you want to delete this API endpoint?')) {\r\n this.apiService.deleteApiEndpoint(apiId).subscribe({\r\n next: (response) => {\r\n if (response.success) {\r\n this.loadApiList();\r\n }\r\n },\r\n error: (err) => {\r\n console.error('Error deleting API endpoint:', err);\r\n }\r\n });\r\n }\r\n }\r\n}\r\n","<cide-lyt-shared-wrapper [shared_wrapper_setup_param]=\"shared_wrapper_setup_param\">\r\n <!-- Breadcrumb Actions -->\r\n <div breadcrumb-actions>\r\n <button (click)=\"openApiForm()\"\r\n class=\"bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg flex items-center gap-2 transition-colors\">\r\n <i class=\"cide-icon-plus\"></i>\r\n <span>Add New Endpoint</span>\r\n </button>\r\n </div>\r\n\r\n <!-- Main Content -->\r\n <div class=\"h-full flex flex-col bg-gray-50 dark:bg-gray-900 p-4\">\r\n\r\n <!-- Search & Filter -->\r\n <div class=\"mb-6\">\r\n <div class=\"relative max-w-md\">\r\n <input type=\"text\" [ngModel]=\"searchQuery()\" (ngModelChange)=\"onSearch($event)\"\r\n placeholder=\"Search endpoints, descriptions...\"\r\n class=\"w-full pl-10 pr-4 py-2 rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all\">\r\n <i class=\"cide-icon-search absolute left-3 top-1/2 -translate-y-1/2 text-gray-400\"></i>\r\n </div>\r\n </div>\r\n\r\n <!-- Data Table -->\r\n <div\r\n class=\"flex-1 overflow-hidden bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 flex flex-col\">\r\n <div class=\"overflow-x-auto flex-1\">\r\n <table class=\"w-full text-left border-collapse\">\r\n <thead class=\"bg-gray-50 dark:bg-gray-900/50 sticky top-0 z-10\">\r\n <tr>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700\">\r\n Method</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700\">\r\n Endpoint</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700\">\r\n Description</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700\">\r\n Category</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 text-center\">\r\n Auth</th>\r\n <th\r\n class=\"p-4 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 text-right\">\r\n Actions</th>\r\n </tr>\r\n </thead>\r\n <tbody class=\"divide-y divide-gray-200 dark:divide-gray-700\">\r\n <tr *ngFor=\"let api of apiList()\"\r\n class=\"hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors\">\r\n <td class=\"p-4 whitespace-nowrap\">\r\n <span class=\"px-2 py-1 text-xs font-bold rounded\" [ngClass]=\"{\r\n 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400': api.api_method === 'GET',\r\n 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400': api.api_method === 'POST',\r\n 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400': api.api_method === 'PUT',\r\n 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400': api.api_method === 'DELETE',\r\n 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400': api.api_method === 'PATCH'\r\n }\">\r\n {{ api.api_method }}\r\n </span>\r\n </td>\r\n <td class=\"p-4 text-sm font-medium text-gray-900 dark:text-gray-100 font-mono\">{{\r\n api.api_endpoint }}</td>\r\n <td class=\"p-4 text-sm text-gray-500 dark:text-gray-400 max-w-xs truncate\"\r\n title=\"{{ api.api_description }}\">{{ api.api_description }}</td>\r\n <td class=\"p-4 text-sm text-gray-500 dark:text-gray-400\">\r\n <span\r\n class=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300\">\r\n {{ api.api_category }}\r\n </span>\r\n </td>\r\n <td class=\"p-4 text-center\">\r\n <i class=\"text-sm\"\r\n [ngClass]=\"api.api_requires_auth ? 'cide-icon-lock text-green-500' : 'cide-icon-unlock text-gray-400'\"></i>\r\n </td>\r\n <td class=\"p-4 text-right whitespace-nowrap\">\r\n <button (click)=\"openApiForm(api)\"\r\n class=\"text-blue-600 hover:text-blue-800 p-1 mr-2 transition-colors\" title=\"Edit\">\r\n <i class=\"cide-icon-edit\"></i>\r\n </button>\r\n <button (click)=\"deleteApi(api._id)\"\r\n class=\"text-red-600 hover:text-red-800 p-1 transition-colors\" title=\"Delete\">\r\n <i class=\"cide-icon-trash\"></i>\r\n </button>\r\n </td>\r\n </tr>\r\n <tr *ngIf=\"apiList().length === 0 && !loading()\">\r\n <td colspan=\"6\" class=\"p-8 text-center text-gray-500 dark:text-gray-400\">\r\n <div class=\"flex flex-col items-center\">\r\n <i class=\"cide-icon-database text-4xl mb-3 opacity-50\"></i>\r\n <p>No API endpoints found</p>\r\n </div>\r\n </td>\r\n </tr>\r\n <tr *ngIf=\"loading()\">\r\n <td colspan=\"6\" class=\"p-8 text-center\">\r\n <div class=\"flex justify-center\">\r\n <div class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600\"></div>\r\n </div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- Footer / Pagination -->\r\n <div\r\n class=\"p-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/50 flex justify-between items-center text-sm text-gray-600 dark:text-gray-400\">\r\n <span>Showing {{ apiList().length }} of {{ totalRecords() }} endpoints</span>\r\n <div class=\"flex gap-2\">\r\n <button [disabled]=\"pageIndex() <= 1\" (click)=\"onPageChange(pageIndex() - 1)\"\r\n class=\"px-3 py-1 rounded border border-gray-300 dark:border-gray-600 disabled:opacity-50 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors\">\r\n Previous\r\n </button>\r\n <button [disabled]=\"apiList().length < pageSize()\" (click)=\"onPageChange(pageIndex() + 1)\"\r\n class=\"px-3 py-1 rounded border border-gray-300 dark:border-gray-600 disabled:opacity-50 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors\">\r\n Next\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</cide-lyt-shared-wrapper>"],"names":[],"mappings":"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"}