cloud-ide-shared 1.0.3 → 1.0.5

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.
@@ -1,9 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, InjectionToken, inject, input, output, signal } from '@angular/core';
2
+ import { Component, InjectionToken, inject, Injectable, input, output, signal } from '@angular/core';
3
3
  import { Router } from '@angular/router';
4
+ import { Observable } from 'rxjs';
5
+ import { CideEleFileManagerService, CideEleButtonComponent, CideIconComponent, CideSpinnerComponent } from 'cloud-ide-element';
4
6
  import * as i1 from '@angular/common';
5
7
  import { CommonModule } from '@angular/common';
6
- import { CideEleButtonComponent, CideIconComponent, CideSpinnerComponent } from 'cloud-ide-element';
7
8
 
8
9
  class CloudIdeShared {
9
10
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CloudIdeShared, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -45,6 +46,216 @@ const authGuard = (route, state) => {
45
46
  return false;
46
47
  };
47
48
 
49
+ /**
50
+ * Shared Object ID Generation Service
51
+ *
52
+ * This service provides a consistent interface for generating Object IDs
53
+ * across all libraries. It internally uses the FileManagerService but
54
+ * provides a standardized API that can be used throughout the application.
55
+ *
56
+ * Benefits:
57
+ * - Consistent interface across all libraries
58
+ * - Centralized Object ID generation logic
59
+ * - Easy to maintain and update
60
+ * - Prevents confusion with different Object ID generation methods
61
+ */
62
+ class SharedObjectIdService {
63
+ fileManagerService = inject(CideEleFileManagerService);
64
+ /**
65
+ * Generate a new Object ID
66
+ *
67
+ * This method internally uses the FileManagerService to generate
68
+ * a unique Object ID that can be used for any entity in the system.
69
+ *
70
+ * @returns Observable<mongooseObjectIdCreateControllerResponse> - The generated Object ID response
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * // Generate Object ID for a new user
75
+ * this.sharedObjectIdService.generateObjectId().subscribe({
76
+ * next: (response) => {
77
+ * if (response.success && response.data?.objectId) {
78
+ * const newUserId = response.data.objectId;
79
+ * // Use the Object ID for creating a new user
80
+ * }
81
+ * },
82
+ * error: (error) => {
83
+ * console.error('Failed to generate Object ID:', error);
84
+ * }
85
+ * });
86
+ * ```
87
+ */
88
+ generateObjectId() {
89
+ console.log('🆔 [SharedObjectIdService] Generating Object ID via FileManagerService');
90
+ return this.fileManagerService.generateObjectId();
91
+ }
92
+ /**
93
+ * Generate Object ID as Promise
94
+ *
95
+ * Convenience method that converts the Observable to a Promise
96
+ * for easier use with async/await syntax.
97
+ *
98
+ * @returns Promise<string> - The generated Object ID string
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * // Generate Object ID using async/await
103
+ * try {
104
+ * const objectId = await this.sharedObjectIdService.generateObjectIdAsync();
105
+ * console.log('Generated Object ID:', objectId);
106
+ * } catch (error) {
107
+ * console.error('Failed to generate Object ID:', error);
108
+ * }
109
+ * ```
110
+ */
111
+ async generateObjectIdAsync() {
112
+ try {
113
+ const response = await this.generateObjectId().toPromise();
114
+ if (response?.success && response?.data?.objectId) {
115
+ console.log('🆔 [SharedObjectIdService] Generated Object ID:', response.data.objectId);
116
+ return response.data.objectId;
117
+ }
118
+ else {
119
+ throw new Error('Failed to generate Object ID: Invalid response');
120
+ }
121
+ }
122
+ catch (error) {
123
+ console.error('❌ [SharedObjectIdService] Error generating Object ID:', error);
124
+ throw error;
125
+ }
126
+ }
127
+ /**
128
+ * Generate multiple Object IDs at once
129
+ *
130
+ * Useful when you need multiple Object IDs for batch operations.
131
+ *
132
+ * @param count - Number of Object IDs to generate
133
+ * @returns Observable<string[]> - Array of generated Object IDs
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * // Generate 5 Object IDs for batch creation
138
+ * this.sharedObjectIdService.generateMultipleObjectIds(5).subscribe({
139
+ * next: (objectIds) => {
140
+ * console.log('Generated Object IDs:', objectIds);
141
+ * // Use the Object IDs for batch operations
142
+ * }
143
+ * });
144
+ * ```
145
+ */
146
+ generateMultipleObjectIds(count) {
147
+ console.log(`🆔 [SharedObjectIdService] Generating ${count} Object IDs`);
148
+ const requests = Array.from({ length: count }, () => this.generateObjectId());
149
+ return new Observable(observer => {
150
+ let completed = 0;
151
+ const objectIds = [];
152
+ requests.forEach((request, index) => {
153
+ request.subscribe({
154
+ next: (response) => {
155
+ if (response?.success && response?.data?.objectId) {
156
+ objectIds[index] = response.data.objectId;
157
+ }
158
+ else {
159
+ observer.error(new Error(`Failed to generate Object ID at index ${index}`));
160
+ return;
161
+ }
162
+ completed++;
163
+ if (completed === count) {
164
+ observer.next(objectIds);
165
+ observer.complete();
166
+ }
167
+ },
168
+ error: (error) => {
169
+ observer.error(error);
170
+ }
171
+ });
172
+ });
173
+ });
174
+ }
175
+ /**
176
+ * Generate Object ID with validation
177
+ *
178
+ * Generates an Object ID and validates it before returning.
179
+ *
180
+ * @param validator - Optional validation function
181
+ * @returns Observable<string> - Validated Object ID
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * // Generate Object ID with custom validation
186
+ * const validator = (id: string) => id.length === 24; // MongoDB ObjectId length
187
+ * this.sharedObjectIdService.generateObjectIdWithValidation(validator).subscribe({
188
+ * next: (validatedId) => {
189
+ * console.log('Validated Object ID:', validatedId);
190
+ * }
191
+ * });
192
+ * ```
193
+ */
194
+ generateObjectIdWithValidation(validator) {
195
+ return new Observable(observer => {
196
+ this.generateObjectId().subscribe({
197
+ next: (response) => {
198
+ if (response?.success && response?.data?.objectId) {
199
+ const objectId = response.data.objectId;
200
+ // Apply validation if provided
201
+ if (validator && !validator(objectId)) {
202
+ observer.error(new Error('Generated Object ID failed validation'));
203
+ return;
204
+ }
205
+ observer.next(objectId);
206
+ observer.complete();
207
+ }
208
+ else {
209
+ observer.error(new Error('Failed to generate Object ID: Invalid response'));
210
+ }
211
+ },
212
+ error: (error) => {
213
+ observer.error(error);
214
+ }
215
+ });
216
+ });
217
+ }
218
+ /**
219
+ * Check if a string is a valid Object ID format
220
+ *
221
+ * @param id - String to validate
222
+ * @returns boolean - True if valid Object ID format
223
+ *
224
+ * @example
225
+ * ```typescript
226
+ * const isValid = this.sharedObjectIdService.isValidObjectId('507f1f77bcf86cd799439011');
227
+ * console.log('Is valid Object ID:', isValid); // true
228
+ * ```
229
+ */
230
+ isValidObjectId(id) {
231
+ // MongoDB ObjectId is 24 characters long and contains only hexadecimal characters
232
+ const objectIdRegex = /^[0-9a-fA-F]{24}$/;
233
+ return objectIdRegex.test(id);
234
+ }
235
+ /**
236
+ * Get Object ID generation statistics
237
+ *
238
+ * Returns information about Object ID generation for monitoring purposes.
239
+ *
240
+ * @returns Object with statistics
241
+ */
242
+ getGenerationStats() {
243
+ return {
244
+ serviceName: 'SharedObjectIdService',
245
+ description: 'Centralized Object ID generation service',
246
+ internalService: 'CideEleFileManagerService'
247
+ };
248
+ }
249
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: SharedObjectIdService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
250
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: SharedObjectIdService, providedIn: 'root' });
251
+ }
252
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: SharedObjectIdService, decorators: [{
253
+ type: Injectable,
254
+ args: [{
255
+ providedIn: 'root'
256
+ }]
257
+ }] });
258
+
48
259
  // Injection token for entity service
49
260
  const ENTITY_SERVICE_TOKEN = new InjectionToken('EntityService');
50
261
  class CideSharedOrgStructureComponent {
@@ -100,16 +311,10 @@ class CideSharedOrgStructureComponent {
100
311
  // First pass: create all nodes
101
312
  entities.forEach(entity => {
102
313
  const node = {
103
- _id: entity._id || '',
104
- syen_name: entity.syen_name || 'Unnamed Entity',
105
- syen_entity_code: entity.syen_entity_code || '',
106
- syen_entity_type_sygms: entity.syen_entity_type_sygms || '',
107
- syen_isactive: entity.syen_isactive || false,
108
- children: [],
109
- level: 0,
110
- parentId: entity.syen_id_syen || undefined
314
+ ...entity,
315
+ children: []
111
316
  };
112
- nodeMap.set(node._id, node);
317
+ nodeMap.set(entity._id || '', node);
113
318
  });
114
319
  // Second pass: build hierarchy
115
320
  entities.forEach(entity => {
@@ -120,10 +325,8 @@ class CideSharedOrgStructureComponent {
120
325
  const parent = nodeMap.get(parentId);
121
326
  parent.children = parent.children || [];
122
327
  parent.children.push(node);
123
- node.level = this.calculateLevel(parent, nodeMap);
124
328
  }
125
329
  else {
126
- node.level = 0;
127
330
  rootNodes.push(node);
128
331
  }
129
332
  }
@@ -138,9 +341,9 @@ class CideSharedOrgStructureComponent {
138
341
  calculateLevel(node, nodeMap) {
139
342
  let level = 0;
140
343
  let current = node;
141
- while (current.parentId && nodeMap.has(current.parentId)) {
344
+ while (current.syen_id_syen && nodeMap.has(current.syen_id_syen)) {
142
345
  level++;
143
- current = nodeMap.get(current.parentId);
346
+ current = nodeMap.get(current.syen_id_syen);
144
347
  }
145
348
  return level;
146
349
  }
@@ -148,7 +351,7 @@ class CideSharedOrgStructureComponent {
148
351
  * Sort children recursively by name
149
352
  */
150
353
  sortChildrenRecursively(nodes) {
151
- nodes.sort((a, b) => a.syen_name.localeCompare(b.syen_name));
354
+ nodes.sort((a, b) => (a.syen_name || '').localeCompare(b.syen_name || ''));
152
355
  nodes.forEach(node => {
153
356
  if (node.children && node.children.length > 0) {
154
357
  this.sortChildrenRecursively(node.children);
@@ -206,7 +409,7 @@ class CideSharedOrgStructureComponent {
206
409
  });
207
410
  }
208
411
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideSharedOrgStructureComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
209
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideSharedOrgStructureComponent, isStandalone: true, selector: "cide-shared-org-structure", inputs: { allowSwitching: { classPropertyName: "allowSwitching", publicName: "allowSwitching", isSignal: true, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entityClick: "entityClick", entitySelect: "entitySelect", entityView: "entityView" }, ngImport: i0, template: "<!-- Organization Structure Component -->\r\n<div class=\"tw-flex-1 tw-overflow-hidden\">\r\n @if (loading()) {\r\n <div class=\"tw-flex tw-items-center tw-justify-center tw-py-12\">\r\n <cide-ele-spinner size=\"md\"></cide-ele-spinner>\r\n <span class=\"tw-ml-3 tw-text-gray-600 tw-text-sm\">Loading organization structure...</span>\r\n </div>\r\n } @else if (error()) {\r\n <div class=\"tw-text-center tw-py-12\">\r\n <div class=\"tw-w-16 tw-h-16 tw-bg-red-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\r\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-red-500\">error</cide-ele-icon>\r\n </div>\r\n <h3 class=\"tw-text-lg tw-font-medium tw-text-gray-900 tw-mb-2\">Error Loading Structure</h3>\r\n <p class=\"tw-text-gray-600 tw-mb-4\">{{ error() }}</p>\r\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"loadOrgStructure()\">\r\n <cide-ele-icon>refresh</cide-ele-icon>\r\n Try Again\r\n </button>\r\n </div>\r\n } @else if (orgStructure().length === 0) {\r\n <div class=\"tw-text-center tw-py-12\">\r\n <div class=\"tw-w-16 tw-h-16 tw-bg-gray-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\r\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-gray-400\">account_tree</cide-ele-icon>\r\n </div>\r\n <h3 class=\"tw-text-lg tw-font-medium tw-text-gray-900 tw-mb-2\">No Entities Found</h3>\r\n <p class=\"tw-text-gray-600 tw-mb-4\">No entities are available to display in the organization structure.</p>\r\n @if (mode() === 'view') {\r\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"router.navigate(['/control-panel/entity-list'])\">\r\n <cide-ele-icon>add</cide-ele-icon>\r\n Create First Entity\r\n </button>\r\n }\r\n </div>\r\n } @else {\r\n <!-- Organization Chart Container -->\r\n <div class=\"tw-relative tw-min-h-screen tw-bg-gray-50 tw-py-8\">\r\n <!-- Background Grid Pattern -->\r\n <div class=\"tw-absolute tw-inset-0 tw-opacity-30\" style=\"background-image: radial-gradient(circle, #e5e7eb 1px, transparent 1px); background-size: 20px 20px;\"></div>\r\n \r\n <!-- Chart Content -->\r\n <div class=\"tw-relative tw-z-10\">\r\n @for (rootNode of orgStructure(); track rootNode._id) {\r\n <div class=\"tw-flex tw-flex-col tw-items-center tw-mb-12\">\r\n <!-- Render node recursively with unlimited depth -->\r\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\" [ngTemplateOutletContext]=\"{ $implicit: rootNode, level: 0 }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n\r\n<!-- Entity Node Template (Recursive) -->\r\n<ng-template #entityNodeTemplate let-node let-level=\"level\">\r\n <div class=\"tw-flex tw-flex-col tw-items-center\">\r\n \r\n <!-- Entity Card -->\r\n <div class=\"tw-bg-white tw-shadow-lg tw-rounded-lg tw-p-4 tw-min-w-64 tw-max-w-72 tw-border-t-4 tw-transition-shadow tw-cursor-pointer hover:tw-shadow-xl\"\r\n [class.level-0]=\"level === 0\"\r\n [class.level-1]=\"level === 1\"\r\n [class.level-2]=\"level === 2\"\r\n [class.level-3]=\"level === 3\"\r\n [class.level-4]=\"level === 4\"\r\n [class.level-5]=\"level === 5\"\r\n (click)=\"viewEntity(node._id)\">\r\n \r\n <!-- Card Content -->\r\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\r\n <!-- Avatar -->\r\n <div class=\"tw-w-12 tw-h-12 tw-bg-purple-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-flex-shrink-0\">\r\n <cide-ele-icon class=\"tw-w-6 tw-h-6 tw-text-purple-600\">person</cide-ele-icon>\r\n </div>\r\n \r\n <!-- Entity Info -->\r\n <div class=\"tw-flex-1 tw-min-w-0\">\r\n <h3 class=\"tw-text-sm tw-font-semibold tw-text-gray-900 tw-whitespace-nowrap tw-overflow-hidden tw-text-ellipsis\">{{ node.syen_name }}</h3>\r\n <p class=\"tw-text-xs tw-text-gray-600 tw-mt-1\">{{ node.syen_entity_code }}</p>\r\n <p class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">{{ node.syen_entity_type_sygms }}</p>\r\n </div>\r\n </div>\r\n \r\n <!-- Action Icons -->\r\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mt-3\">\r\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\r\n <!-- Phone Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">phone</cide-ele-icon>\r\n </button>\r\n \r\n <!-- Email Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">email</cide-ele-icon>\r\n </button>\r\n \r\n <!-- LinkedIn Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-blue-100 tw-flex tw-items-center tw-justify-center tw-text-blue-600 hover:tw-bg-blue-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">attach_money</cide-ele-icon>\r\n </button>\r\n \r\n <!-- Document Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">description</cide-ele-icon>\r\n </button>\r\n \r\n <!-- More Options Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">more_horiz</cide-ele-icon>\r\n </button>\r\n </div>\r\n \r\n <!-- Status Badge -->\r\n <div class=\"tw-flex-shrink-0\">\r\n @if (node.syen_isactive) {\r\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-bg-green-100 tw-text-green-800\">\r\n <div class=\"tw-w-1.5 tw-h-1.5 tw-bg-green-500 tw-rounded-full tw-mr-1\"></div>\r\n Active\r\n </div>\r\n } @else {\r\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-bg-red-100 tw-text-red-800\">\r\n <div class=\"tw-w-1.5 tw-h-1.5 tw-bg-red-500 tw-rounded-full tw-mr-1\"></div>\r\n Inactive\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Children Entities (Recursive) -->\r\n @if (node.children && node.children.length > 0) {\r\n <!-- Ultra-Compact Connection Lines -->\r\n <div class=\"tw-relative tw-flex tw-flex-col tw-items-center tw-mt-2\">\r\n <!-- Minimal connection dot -->\r\n <div class=\"tw-absolute tw-left-1/2 tw-transform tw--translate-x-1/2\" style=\"top: -8px;\">\r\n <div class=\"tw-w-2 tw-h-2 tw-bg-purple-600 tw-rounded-full tw-border tw-border-white\"></div>\r\n </div>\r\n \r\n <!-- Ultra-Compact SVG Lines -->\r\n <div class=\"tw-relative tw-w-full\" style=\"height: 30px;\">\r\n @if (node.children && node.children.length === 1) {\r\n <!-- Single child - minimal line -->\r\n <svg class=\"tw-absolute tw-left-1/2 connection-line-compact\" style=\"transform: translateX(-50%); width: 2px; height: 30px; top: 0;\">\r\n <line x1=\"1\" y1=\"0\" x2=\"1\" y2=\"30\" stroke=\"#9333ea\" stroke-width=\"2\" stroke-linecap=\"round\"/>\r\n </svg>\r\n }\r\n @else if (node.children && node.children.length > 1) {\r\n <!-- Multiple children - minimal design -->\r\n <svg class=\"tw-absolute tw-left-1/2 connection-line-compact\" [attr.style]=\"'transform: translateX(-50%); width: ' + ((node.children.length - 1) * 336 + 256) + 'px; height: 30px; top: 0;'\">\r\n <!-- Vertical line -->\r\n <line [attr.x1]=\"((node.children.length - 1) * 336 + 256) / 2\" \r\n y1=\"0\" \r\n [attr.x2]=\"((node.children.length - 1) * 336 + 256) / 2\" \r\n y2=\"12\" \r\n stroke=\"#9333ea\" \r\n stroke-width=\"2\" \r\n stroke-linecap=\"round\"/>\r\n \r\n <!-- Horizontal line -->\r\n <path [attr.d]=\"'M 128 15 L ' + ((node.children.length - 1) * 336 + 128) + ' 15'\" \r\n stroke=\"#9333ea\" \r\n stroke-width=\"2\" \r\n stroke-linecap=\"round\"/>\r\n \r\n <!-- Vertical lines to children -->\r\n @for (child of node.children; track child._id; let i = $index) {\r\n <line [attr.x1]=\"(i * 336) + 128\" \r\n y1=\"15\" \r\n [attr.x2]=\"(i * 336) + 128\" \r\n y2=\"28\" \r\n stroke=\"#9333ea\" \r\n stroke-width=\"2\" \r\n stroke-linecap=\"round\"/>\r\n <!-- Tiny dot -->\r\n <circle [attr.cx]=\"(i * 336) + 128\" cy=\"28\" r=\"2.5\" fill=\"#9333ea\" stroke=\"#fff\" stroke-width=\"1\"/>\r\n }\r\n </svg>\r\n }\r\n </div>\r\n \r\n <!-- Children -->\r\n <div class=\"tw-flex tw-justify-center tw-gap-20\">\r\n @for (child of node.children; track child._id) {\r\n <div class=\"tw-flex tw-flex-col tw-items-center\">\r\n <!-- Child node -->\r\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\" [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: [":host{height:100%;display:flex;flex-direction:column}.tw-overflow-y-auto::-webkit-scrollbar{width:6px}.tw-overflow-y-auto::-webkit-scrollbar-track{background:#f1f5f9;border-radius:3px}.tw-overflow-y-auto::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px}.tw-overflow-y-auto::-webkit-scrollbar-thumb:hover{background:#94a3b8}.tw-transition-shadow{transition:box-shadow .2s ease-in-out}.tw-shadow-lg:hover{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a;transform:translateY(-2px);transition:all .2s ease-in-out}.tw-bg-purple-300,.tw-bg-purple-400{transition:all .3s ease-in-out}.connection-line-compact{display:block;overflow:visible}.connection-line-compact path,.connection-line-compact line{stroke-linecap:round;stroke-linejoin:round;transition:stroke-width .2s ease}.connection-line-compact:hover path,.connection-line-compact:hover line{stroke-width:3}.connection-line-compact circle{transition:all .2s ease}.connection-line-compact circle:hover{filter:drop-shadow(0 2px 4px rgba(147,51,234,.4))}.level-0{border-color:#fb923c!important}.level-1{border-color:#60a5fa!important}.level-2{border-color:#a78bfa!important}.level-3{border-color:#4ade80!important}.level-4{border-color:#818cf8!important}.level-5{border-color:#f472b6!important}@media (max-width: 1200px){.tw-max-w-7xl{max-width:100%}.tw-gap-6{gap:1rem}.tw-min-w-64{min-width:14rem}.tw-max-w-72{max-width:16rem}}@media (max-width: 768px){.tw-min-w-64{min-width:12rem}.tw-max-w-72{max-width:14rem}.tw-max-w-7xl{max-width:100%}.tw-gap-6{gap:.75rem}.tw-p-4{padding:.75rem}.tw-mb-4{margin-bottom:.75rem}.tw-space-x-3{gap:.5rem}.tw-space-x-2{gap:.375rem}.tw-w-12{width:2.5rem}.tw-h-12{height:2.5rem}}@media (max-width: 480px){.tw-min-w-72{min-width:12rem}.tw-max-w-80{max-width:14rem}.tw-p-4{padding:.5rem}.tw-space-x-3{gap:.375rem}.tw-space-x-2{gap:.25rem}.tw-mb-3{margin-bottom:.5rem}.tw-w-12{width:2rem}.tw-h-12{height:2rem}.tw-w-8{width:1.5rem}.tw-h-8{height:1.5rem}}@media print{.tw-bg-gray-50{background:#fff!important}.tw-shadow-lg{box-shadow:none!important;border:1px solid #e5e7eb!important}.tw-bg-purple-300{background:#6b7280!important}.tw-border-purple-300{border-color:#6b7280!important}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton]", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }, { kind: "component", type: CideSpinnerComponent, selector: "cide-ele-spinner", inputs: ["size", "type"] }] });
412
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideSharedOrgStructureComponent, isStandalone: true, selector: "cide-shared-org-structure", inputs: { allowSwitching: { classPropertyName: "allowSwitching", publicName: "allowSwitching", isSignal: true, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entityClick: "entityClick", entitySelect: "entitySelect", entityView: "entityView" }, ngImport: i0, template: "<!-- Organization Structure Component -->\n<div class=\"tw-flex-1 tw-overflow-hidden\">\n @if (loading()) {\n <div class=\"tw-flex tw-items-center tw-justify-center tw-py-12\">\n <cide-ele-spinner size=\"md\"></cide-ele-spinner>\n <span class=\"tw-ml-3 tw-text-gray-600 tw-text-sm\">Loading organization structure...</span>\n </div>\n } @else if (error()) {\n <div class=\"tw-text-center tw-py-12\">\n <div class=\"tw-w-16 tw-h-16 tw-bg-red-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-red-500\">error</cide-ele-icon>\n </div>\n <h3 class=\"tw-text-lg tw-font-medium tw-text-gray-900 tw-mb-2\">Error Loading Structure</h3>\n <p class=\"tw-text-gray-600 tw-mb-4\">{{ error() }}</p>\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"loadOrgStructure()\">\n <cide-ele-icon>refresh</cide-ele-icon>\n Try Again\n </button>\n </div>\n } @else if (orgStructure().length === 0) {\n <div class=\"tw-text-center tw-py-12\">\n <div class=\"tw-w-16 tw-h-16 tw-bg-gray-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-gray-400\">account_tree</cide-ele-icon>\n </div>\n <h3 class=\"tw-text-lg tw-font-medium tw-text-gray-900 tw-mb-2\">No Entities Found</h3>\n <p class=\"tw-text-gray-600 tw-mb-4\">No entities are available to display in the organization structure.</p>\n @if (mode() === 'view') {\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"router.navigate(['/control-panel/entity-list'])\">\n <cide-ele-icon>add</cide-ele-icon>\n Create First Entity\n </button>\n }\n </div>\n } @else {\n <!-- Organization Chart Container -->\n <div class=\"tw-relative tw-min-h-screen tw-bg-gray-50 tw-py-8 tw-overflow-x-auto org-chart-container\">\n <!-- Background Grid Pattern -->\n <div class=\"tw-absolute tw-inset-0 tw-opacity-30\" style=\"background-image: radial-gradient(circle, #e5e7eb 1px, transparent 1px); background-size: 20px 20px;\"></div>\n \n <!-- Chart Content -->\n <div class=\"tw-relative tw-z-10 tw-min-w-max tw-px-4 org-chart-content\">\n @for (rootNode of orgStructure(); track rootNode._id) {\n <div class=\"tw-flex tw-flex-col tw-items-center tw-mb-12\">\n <!-- Render node recursively with unlimited depth -->\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\" [ngTemplateOutletContext]=\"{ $implicit: rootNode, level: 0 }\"></ng-container>\n </div>\n }\n </div>\n </div>\n }\n</div>\n\n<!-- Entity Node Template (Recursive) -->\n<ng-template #entityNodeTemplate let-node let-level=\"level\">\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n \n <!-- Entity Card -->\n <div class=\"tw-bg-white tw-shadow-lg tw-rounded-lg tw-p-4 tw-w-64 tw-max-w-72 tw-border-t-4 tw-transition-all tw-cursor-pointer hover:tw-shadow-xl hover:tw-scale-105 entity-card\"\n [class.level-0]=\"level === 0\"\n [class.level-1]=\"level === 1\"\n [class.level-2]=\"level === 2\"\n [class.level-3]=\"level === 3\"\n [class.level-4]=\"level === 4\"\n [class.level-5]=\"level === 5\"\n (click)=\"viewEntity(node._id)\">\n \n <!-- Card Content -->\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\n <!-- Avatar -->\n <div class=\"tw-w-12 tw-h-12 tw-bg-purple-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-flex-shrink-0\">\n <cide-ele-icon class=\"tw-w-6 tw-h-6 tw-text-purple-600\">person</cide-ele-icon>\n </div>\n \n <!-- Entity Info -->\n <div class=\"tw-flex-1 tw-min-w-0\">\n <h3 class=\"tw-text-sm tw-font-semibold tw-text-gray-900 tw-whitespace-nowrap tw-overflow-hidden tw-text-ellipsis\">{{ node.syen_name }}</h3>\n <p class=\"tw-text-xs tw-text-gray-600 tw-mt-1\">{{ node.syen_entity_code }}</p>\n <p class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">{{ node.syen_entity_type_sygms }}</p>\n </div>\n </div>\n \n <!-- Action Icons -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mt-3\">\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <!-- Phone Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">phone</cide-ele-icon>\n </button>\n \n <!-- Email Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">email</cide-ele-icon>\n </button>\n \n <!-- LinkedIn Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-blue-100 tw-flex tw-items-center tw-justify-center tw-text-blue-600 hover:tw-bg-blue-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">attach_money</cide-ele-icon>\n </button>\n \n <!-- Document Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">description</cide-ele-icon>\n </button>\n \n <!-- More Options Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">more_horiz</cide-ele-icon>\n </button>\n </div>\n \n <!-- Status Badge -->\n <div class=\"tw-flex-shrink-0\">\n @if (node.syen_isactive) {\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-bg-green-100 tw-text-green-800\">\n <div class=\"tw-w-1.5 tw-h-1.5 tw-bg-green-500 tw-rounded-full tw-mr-1\"></div>\n Active\n </div>\n } @else {\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-bg-red-100 tw-text-red-800\">\n <div class=\"tw-w-1.5 tw-h-1.5 tw-bg-red-500 tw-rounded-full tw-mr-1\"></div>\n Inactive\n </div>\n }\n </div>\n </div>\n </div>\n \n <!-- Children Entities (Recursive) -->\n @if (node.children && node.children.length > 0) {\n <!-- Flexible Connection Lines -->\n <div class=\"tw-relative tw-flex tw-flex-col tw-items-center tw-mt-4\">\n <!-- Connection dot -->\n <div class=\"tw-absolute tw-left-1/2 tw-transform tw--translate-x-1/2\" style=\"top: -8px;\">\n <div class=\"tw-w-2 tw-h-2 tw-bg-purple-600 tw-rounded-full tw-border tw-border-white\"></div>\n </div>\n \n <!-- Flexible SVG Lines -->\n <div class=\"tw-relative tw-w-full tw-flex tw-justify-center flexible-connection-lines\">\n @if (node.children && node.children.length === 1) {\n <!-- Single child - simple vertical line -->\n <svg class=\"tw-absolute tw-left-1/2\" style=\"transform: translateX(-50%); width: 2px; height: 40px; top: 0;\">\n <line x1=\"1\" y1=\"0\" x2=\"1\" y2=\"40\" stroke=\"#9333ea\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n }\n @else if (node.children && node.children.length > 1) {\n <!-- Multiple children - flexible design -->\n <svg class=\"tw-absolute tw-left-1/2\" style=\"transform: translateX(-50%); width: 100%; height: 40px; top: 0;\">\n <!-- Vertical line from parent -->\n <line x1=\"50%\" y1=\"0\" x2=\"50%\" y2=\"15\" stroke=\"#9333ea\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n \n <!-- Horizontal line spanning children -->\n <line x1=\"20%\" y1=\"15\" x2=\"80%\" y2=\"15\" stroke=\"#9333ea\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n \n <!-- Vertical lines to children -->\n @for (child of node.children; track child._id; let i = $index) {\n <line [attr.x1]=\"(20 + (60 * i) / (node.children.length - 1)) + '%'\" \n y1=\"15\" \n [attr.x2]=\"(20 + (60 * i) / (node.children.length - 1)) + '%'\" \n y2=\"35\" \n stroke=\"#9333ea\" \n stroke-width=\"2\" \n stroke-linecap=\"round\"/>\n <!-- Connection dot -->\n <circle [attr.cx]=\"(20 + (60 * i) / (node.children.length - 1)) + '%'\" cy=\"35\" r=\"2.5\" fill=\"#9333ea\" stroke=\"#fff\" stroke-width=\"1\"/>\n }\n </svg>\n }\n </div>\n \n <!-- Children Container - Flexible Layout -->\n <div class=\"tw-flex tw-flex-wrap tw-justify-center tw-gap-4 tw-w-full tw-max-w-6xl tw-px-4 children-container\">\n @for (child of node.children; track child._id) {\n <div class=\"tw-flex tw-flex-col tw-items-center tw-flex-shrink-0\">\n <!-- Child node -->\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\" [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"></ng-container>\n </div>\n }\n </div>\n </div>\n }\n </div>\n</ng-template>\n", styles: [".org-chart-container{overflow-x:auto;overflow-y:visible;min-height:100vh}.org-chart-content{min-width:max-content;padding:2rem 1rem}.flexible-connection-lines{position:relative;width:100%;height:40px}.flexible-connection-lines svg{position:absolute;left:50%;transform:translate(-50%);width:100%;height:100%;top:0}.children-container{display:flex;flex-wrap:wrap;justify-content:center;gap:1rem;width:100%;max-width:80rem;padding:0 1rem}.children-container>div{flex-shrink:0;display:flex;flex-direction:column;align-items:center}.entity-card{width:16rem;max-width:18rem;transition:all .2s ease-in-out}.entity-card:hover{transform:translateY(-2px) scale(1.02);box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a}@media (max-width: 1400px){.children-container{max-width:70rem;gap:.875rem}.entity-card{width:15rem;max-width:17rem}}@media (max-width: 1200px){.children-container{max-width:60rem;gap:.75rem}.entity-card{width:14rem;max-width:16rem}}@media (max-width: 992px){.children-container{max-width:50rem;gap:.625rem}.entity-card{width:13rem;max-width:15rem}}@media (max-width: 768px){.children-container{max-width:40rem;gap:.5rem}.entity-card{width:12rem;max-width:14rem}.org-chart-content{padding:1.5rem .75rem}}@media (max-width: 576px){.children-container{max-width:30rem;gap:.375rem}.entity-card{width:11rem;max-width:13rem}.org-chart-content{padding:1rem .5rem}}.tw-overflow-y-auto::-webkit-scrollbar{width:6px}.tw-overflow-y-auto::-webkit-scrollbar-track{background:#f1f5f9;border-radius:3px}.tw-overflow-y-auto::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px}.tw-overflow-y-auto::-webkit-scrollbar-thumb:hover{background:#94a3b8}.tw-transition-shadow{transition:box-shadow .2s ease-in-out}.tw-shadow-lg:hover{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a;transform:translateY(-2px);transition:all .2s ease-in-out}.tw-bg-purple-300,.tw-bg-purple-400{transition:all .3s ease-in-out}.connection-line-compact{display:block;overflow:visible}.connection-line-compact path,.connection-line-compact line{stroke-linecap:round;stroke-linejoin:round;transition:stroke-width .2s ease}.connection-line-compact:hover path,.connection-line-compact:hover line{stroke-width:3}.connection-line-compact circle{transition:all .2s ease}.connection-line-compact circle:hover{filter:drop-shadow(0 2px 4px rgba(147,51,234,.4))}.level-0{border-color:#fb923c!important}.level-1{border-color:#60a5fa!important}.level-2{border-color:#a78bfa!important}.level-3{border-color:#4ade80!important}.level-4{border-color:#818cf8!important}.level-5{border-color:#f472b6!important}@media (max-width: 1200px){.tw-max-w-7xl{max-width:100%}.tw-gap-6{gap:1rem}.tw-min-w-64{min-width:14rem}.tw-max-w-72{max-width:16rem}}@media (max-width: 768px){.tw-min-w-64{min-width:12rem}.tw-max-w-72{max-width:14rem}.tw-max-w-7xl{max-width:100%}.tw-gap-6{gap:.75rem}.tw-p-4{padding:.75rem}.tw-mb-4{margin-bottom:.75rem}.tw-space-x-3{gap:.5rem}.tw-space-x-2{gap:.375rem}.tw-w-12{width:2.5rem}.tw-h-12{height:2.5rem}}@media (max-width: 480px){.tw-min-w-72{min-width:12rem}.tw-max-w-80{max-width:14rem}.tw-p-4{padding:.5rem}.tw-space-x-3{gap:.375rem}.tw-space-x-2{gap:.25rem}.tw-mb-3{margin-bottom:.5rem}.tw-w-12{width:2rem}.tw-h-12{height:2rem}.tw-w-8{width:1.5rem}.tw-h-8{height:1.5rem}}@media print{.tw-bg-gray-50{background:#fff!important}.tw-shadow-lg{box-shadow:none!important;border:1px solid #e5e7eb!important}.tw-bg-purple-300{background:#6b7280!important}.tw-border-purple-300{border-color:#6b7280!important}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton]", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }, { kind: "component", type: CideSpinnerComponent, selector: "cide-ele-spinner", inputs: ["size", "type"] }] });
210
413
  }
211
414
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideSharedOrgStructureComponent, decorators: [{
212
415
  type: Component,
@@ -215,7 +418,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
215
418
  CideEleButtonComponent,
216
419
  CideIconComponent,
217
420
  CideSpinnerComponent
218
- ], template: "<!-- Organization Structure Component -->\r\n<div class=\"tw-flex-1 tw-overflow-hidden\">\r\n @if (loading()) {\r\n <div class=\"tw-flex tw-items-center tw-justify-center tw-py-12\">\r\n <cide-ele-spinner size=\"md\"></cide-ele-spinner>\r\n <span class=\"tw-ml-3 tw-text-gray-600 tw-text-sm\">Loading organization structure...</span>\r\n </div>\r\n } @else if (error()) {\r\n <div class=\"tw-text-center tw-py-12\">\r\n <div class=\"tw-w-16 tw-h-16 tw-bg-red-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\r\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-red-500\">error</cide-ele-icon>\r\n </div>\r\n <h3 class=\"tw-text-lg tw-font-medium tw-text-gray-900 tw-mb-2\">Error Loading Structure</h3>\r\n <p class=\"tw-text-gray-600 tw-mb-4\">{{ error() }}</p>\r\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"loadOrgStructure()\">\r\n <cide-ele-icon>refresh</cide-ele-icon>\r\n Try Again\r\n </button>\r\n </div>\r\n } @else if (orgStructure().length === 0) {\r\n <div class=\"tw-text-center tw-py-12\">\r\n <div class=\"tw-w-16 tw-h-16 tw-bg-gray-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\r\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-gray-400\">account_tree</cide-ele-icon>\r\n </div>\r\n <h3 class=\"tw-text-lg tw-font-medium tw-text-gray-900 tw-mb-2\">No Entities Found</h3>\r\n <p class=\"tw-text-gray-600 tw-mb-4\">No entities are available to display in the organization structure.</p>\r\n @if (mode() === 'view') {\r\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"router.navigate(['/control-panel/entity-list'])\">\r\n <cide-ele-icon>add</cide-ele-icon>\r\n Create First Entity\r\n </button>\r\n }\r\n </div>\r\n } @else {\r\n <!-- Organization Chart Container -->\r\n <div class=\"tw-relative tw-min-h-screen tw-bg-gray-50 tw-py-8\">\r\n <!-- Background Grid Pattern -->\r\n <div class=\"tw-absolute tw-inset-0 tw-opacity-30\" style=\"background-image: radial-gradient(circle, #e5e7eb 1px, transparent 1px); background-size: 20px 20px;\"></div>\r\n \r\n <!-- Chart Content -->\r\n <div class=\"tw-relative tw-z-10\">\r\n @for (rootNode of orgStructure(); track rootNode._id) {\r\n <div class=\"tw-flex tw-flex-col tw-items-center tw-mb-12\">\r\n <!-- Render node recursively with unlimited depth -->\r\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\" [ngTemplateOutletContext]=\"{ $implicit: rootNode, level: 0 }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n\r\n<!-- Entity Node Template (Recursive) -->\r\n<ng-template #entityNodeTemplate let-node let-level=\"level\">\r\n <div class=\"tw-flex tw-flex-col tw-items-center\">\r\n \r\n <!-- Entity Card -->\r\n <div class=\"tw-bg-white tw-shadow-lg tw-rounded-lg tw-p-4 tw-min-w-64 tw-max-w-72 tw-border-t-4 tw-transition-shadow tw-cursor-pointer hover:tw-shadow-xl\"\r\n [class.level-0]=\"level === 0\"\r\n [class.level-1]=\"level === 1\"\r\n [class.level-2]=\"level === 2\"\r\n [class.level-3]=\"level === 3\"\r\n [class.level-4]=\"level === 4\"\r\n [class.level-5]=\"level === 5\"\r\n (click)=\"viewEntity(node._id)\">\r\n \r\n <!-- Card Content -->\r\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\r\n <!-- Avatar -->\r\n <div class=\"tw-w-12 tw-h-12 tw-bg-purple-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-flex-shrink-0\">\r\n <cide-ele-icon class=\"tw-w-6 tw-h-6 tw-text-purple-600\">person</cide-ele-icon>\r\n </div>\r\n \r\n <!-- Entity Info -->\r\n <div class=\"tw-flex-1 tw-min-w-0\">\r\n <h3 class=\"tw-text-sm tw-font-semibold tw-text-gray-900 tw-whitespace-nowrap tw-overflow-hidden tw-text-ellipsis\">{{ node.syen_name }}</h3>\r\n <p class=\"tw-text-xs tw-text-gray-600 tw-mt-1\">{{ node.syen_entity_code }}</p>\r\n <p class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">{{ node.syen_entity_type_sygms }}</p>\r\n </div>\r\n </div>\r\n \r\n <!-- Action Icons -->\r\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mt-3\">\r\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\r\n <!-- Phone Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">phone</cide-ele-icon>\r\n </button>\r\n \r\n <!-- Email Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">email</cide-ele-icon>\r\n </button>\r\n \r\n <!-- LinkedIn Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-blue-100 tw-flex tw-items-center tw-justify-center tw-text-blue-600 hover:tw-bg-blue-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">attach_money</cide-ele-icon>\r\n </button>\r\n \r\n <!-- Document Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">description</cide-ele-icon>\r\n </button>\r\n \r\n <!-- More Options Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">more_horiz</cide-ele-icon>\r\n </button>\r\n </div>\r\n \r\n <!-- Status Badge -->\r\n <div class=\"tw-flex-shrink-0\">\r\n @if (node.syen_isactive) {\r\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-bg-green-100 tw-text-green-800\">\r\n <div class=\"tw-w-1.5 tw-h-1.5 tw-bg-green-500 tw-rounded-full tw-mr-1\"></div>\r\n Active\r\n </div>\r\n } @else {\r\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-bg-red-100 tw-text-red-800\">\r\n <div class=\"tw-w-1.5 tw-h-1.5 tw-bg-red-500 tw-rounded-full tw-mr-1\"></div>\r\n Inactive\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Children Entities (Recursive) -->\r\n @if (node.children && node.children.length > 0) {\r\n <!-- Ultra-Compact Connection Lines -->\r\n <div class=\"tw-relative tw-flex tw-flex-col tw-items-center tw-mt-2\">\r\n <!-- Minimal connection dot -->\r\n <div class=\"tw-absolute tw-left-1/2 tw-transform tw--translate-x-1/2\" style=\"top: -8px;\">\r\n <div class=\"tw-w-2 tw-h-2 tw-bg-purple-600 tw-rounded-full tw-border tw-border-white\"></div>\r\n </div>\r\n \r\n <!-- Ultra-Compact SVG Lines -->\r\n <div class=\"tw-relative tw-w-full\" style=\"height: 30px;\">\r\n @if (node.children && node.children.length === 1) {\r\n <!-- Single child - minimal line -->\r\n <svg class=\"tw-absolute tw-left-1/2 connection-line-compact\" style=\"transform: translateX(-50%); width: 2px; height: 30px; top: 0;\">\r\n <line x1=\"1\" y1=\"0\" x2=\"1\" y2=\"30\" stroke=\"#9333ea\" stroke-width=\"2\" stroke-linecap=\"round\"/>\r\n </svg>\r\n }\r\n @else if (node.children && node.children.length > 1) {\r\n <!-- Multiple children - minimal design -->\r\n <svg class=\"tw-absolute tw-left-1/2 connection-line-compact\" [attr.style]=\"'transform: translateX(-50%); width: ' + ((node.children.length - 1) * 336 + 256) + 'px; height: 30px; top: 0;'\">\r\n <!-- Vertical line -->\r\n <line [attr.x1]=\"((node.children.length - 1) * 336 + 256) / 2\" \r\n y1=\"0\" \r\n [attr.x2]=\"((node.children.length - 1) * 336 + 256) / 2\" \r\n y2=\"12\" \r\n stroke=\"#9333ea\" \r\n stroke-width=\"2\" \r\n stroke-linecap=\"round\"/>\r\n \r\n <!-- Horizontal line -->\r\n <path [attr.d]=\"'M 128 15 L ' + ((node.children.length - 1) * 336 + 128) + ' 15'\" \r\n stroke=\"#9333ea\" \r\n stroke-width=\"2\" \r\n stroke-linecap=\"round\"/>\r\n \r\n <!-- Vertical lines to children -->\r\n @for (child of node.children; track child._id; let i = $index) {\r\n <line [attr.x1]=\"(i * 336) + 128\" \r\n y1=\"15\" \r\n [attr.x2]=\"(i * 336) + 128\" \r\n y2=\"28\" \r\n stroke=\"#9333ea\" \r\n stroke-width=\"2\" \r\n stroke-linecap=\"round\"/>\r\n <!-- Tiny dot -->\r\n <circle [attr.cx]=\"(i * 336) + 128\" cy=\"28\" r=\"2.5\" fill=\"#9333ea\" stroke=\"#fff\" stroke-width=\"1\"/>\r\n }\r\n </svg>\r\n }\r\n </div>\r\n \r\n <!-- Children -->\r\n <div class=\"tw-flex tw-justify-center tw-gap-20\">\r\n @for (child of node.children; track child._id) {\r\n <div class=\"tw-flex tw-flex-col tw-items-center\">\r\n <!-- Child node -->\r\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\" [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: [":host{height:100%;display:flex;flex-direction:column}.tw-overflow-y-auto::-webkit-scrollbar{width:6px}.tw-overflow-y-auto::-webkit-scrollbar-track{background:#f1f5f9;border-radius:3px}.tw-overflow-y-auto::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px}.tw-overflow-y-auto::-webkit-scrollbar-thumb:hover{background:#94a3b8}.tw-transition-shadow{transition:box-shadow .2s ease-in-out}.tw-shadow-lg:hover{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a;transform:translateY(-2px);transition:all .2s ease-in-out}.tw-bg-purple-300,.tw-bg-purple-400{transition:all .3s ease-in-out}.connection-line-compact{display:block;overflow:visible}.connection-line-compact path,.connection-line-compact line{stroke-linecap:round;stroke-linejoin:round;transition:stroke-width .2s ease}.connection-line-compact:hover path,.connection-line-compact:hover line{stroke-width:3}.connection-line-compact circle{transition:all .2s ease}.connection-line-compact circle:hover{filter:drop-shadow(0 2px 4px rgba(147,51,234,.4))}.level-0{border-color:#fb923c!important}.level-1{border-color:#60a5fa!important}.level-2{border-color:#a78bfa!important}.level-3{border-color:#4ade80!important}.level-4{border-color:#818cf8!important}.level-5{border-color:#f472b6!important}@media (max-width: 1200px){.tw-max-w-7xl{max-width:100%}.tw-gap-6{gap:1rem}.tw-min-w-64{min-width:14rem}.tw-max-w-72{max-width:16rem}}@media (max-width: 768px){.tw-min-w-64{min-width:12rem}.tw-max-w-72{max-width:14rem}.tw-max-w-7xl{max-width:100%}.tw-gap-6{gap:.75rem}.tw-p-4{padding:.75rem}.tw-mb-4{margin-bottom:.75rem}.tw-space-x-3{gap:.5rem}.tw-space-x-2{gap:.375rem}.tw-w-12{width:2.5rem}.tw-h-12{height:2.5rem}}@media (max-width: 480px){.tw-min-w-72{min-width:12rem}.tw-max-w-80{max-width:14rem}.tw-p-4{padding:.5rem}.tw-space-x-3{gap:.375rem}.tw-space-x-2{gap:.25rem}.tw-mb-3{margin-bottom:.5rem}.tw-w-12{width:2rem}.tw-h-12{height:2rem}.tw-w-8{width:1.5rem}.tw-h-8{height:1.5rem}}@media print{.tw-bg-gray-50{background:#fff!important}.tw-shadow-lg{box-shadow:none!important;border:1px solid #e5e7eb!important}.tw-bg-purple-300{background:#6b7280!important}.tw-border-purple-300{border-color:#6b7280!important}}\n"] }]
421
+ ], template: "<!-- Organization Structure Component -->\n<div class=\"tw-flex-1 tw-overflow-hidden\">\n @if (loading()) {\n <div class=\"tw-flex tw-items-center tw-justify-center tw-py-12\">\n <cide-ele-spinner size=\"md\"></cide-ele-spinner>\n <span class=\"tw-ml-3 tw-text-gray-600 tw-text-sm\">Loading organization structure...</span>\n </div>\n } @else if (error()) {\n <div class=\"tw-text-center tw-py-12\">\n <div class=\"tw-w-16 tw-h-16 tw-bg-red-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-red-500\">error</cide-ele-icon>\n </div>\n <h3 class=\"tw-text-lg tw-font-medium tw-text-gray-900 tw-mb-2\">Error Loading Structure</h3>\n <p class=\"tw-text-gray-600 tw-mb-4\">{{ error() }}</p>\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"loadOrgStructure()\">\n <cide-ele-icon>refresh</cide-ele-icon>\n Try Again\n </button>\n </div>\n } @else if (orgStructure().length === 0) {\n <div class=\"tw-text-center tw-py-12\">\n <div class=\"tw-w-16 tw-h-16 tw-bg-gray-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-gray-400\">account_tree</cide-ele-icon>\n </div>\n <h3 class=\"tw-text-lg tw-font-medium tw-text-gray-900 tw-mb-2\">No Entities Found</h3>\n <p class=\"tw-text-gray-600 tw-mb-4\">No entities are available to display in the organization structure.</p>\n @if (mode() === 'view') {\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"router.navigate(['/control-panel/entity-list'])\">\n <cide-ele-icon>add</cide-ele-icon>\n Create First Entity\n </button>\n }\n </div>\n } @else {\n <!-- Organization Chart Container -->\n <div class=\"tw-relative tw-min-h-screen tw-bg-gray-50 tw-py-8 tw-overflow-x-auto org-chart-container\">\n <!-- Background Grid Pattern -->\n <div class=\"tw-absolute tw-inset-0 tw-opacity-30\" style=\"background-image: radial-gradient(circle, #e5e7eb 1px, transparent 1px); background-size: 20px 20px;\"></div>\n \n <!-- Chart Content -->\n <div class=\"tw-relative tw-z-10 tw-min-w-max tw-px-4 org-chart-content\">\n @for (rootNode of orgStructure(); track rootNode._id) {\n <div class=\"tw-flex tw-flex-col tw-items-center tw-mb-12\">\n <!-- Render node recursively with unlimited depth -->\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\" [ngTemplateOutletContext]=\"{ $implicit: rootNode, level: 0 }\"></ng-container>\n </div>\n }\n </div>\n </div>\n }\n</div>\n\n<!-- Entity Node Template (Recursive) -->\n<ng-template #entityNodeTemplate let-node let-level=\"level\">\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n \n <!-- Entity Card -->\n <div class=\"tw-bg-white tw-shadow-lg tw-rounded-lg tw-p-4 tw-w-64 tw-max-w-72 tw-border-t-4 tw-transition-all tw-cursor-pointer hover:tw-shadow-xl hover:tw-scale-105 entity-card\"\n [class.level-0]=\"level === 0\"\n [class.level-1]=\"level === 1\"\n [class.level-2]=\"level === 2\"\n [class.level-3]=\"level === 3\"\n [class.level-4]=\"level === 4\"\n [class.level-5]=\"level === 5\"\n (click)=\"viewEntity(node._id)\">\n \n <!-- Card Content -->\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\n <!-- Avatar -->\n <div class=\"tw-w-12 tw-h-12 tw-bg-purple-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-flex-shrink-0\">\n <cide-ele-icon class=\"tw-w-6 tw-h-6 tw-text-purple-600\">person</cide-ele-icon>\n </div>\n \n <!-- Entity Info -->\n <div class=\"tw-flex-1 tw-min-w-0\">\n <h3 class=\"tw-text-sm tw-font-semibold tw-text-gray-900 tw-whitespace-nowrap tw-overflow-hidden tw-text-ellipsis\">{{ node.syen_name }}</h3>\n <p class=\"tw-text-xs tw-text-gray-600 tw-mt-1\">{{ node.syen_entity_code }}</p>\n <p class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">{{ node.syen_entity_type_sygms }}</p>\n </div>\n </div>\n \n <!-- Action Icons -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mt-3\">\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <!-- Phone Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">phone</cide-ele-icon>\n </button>\n \n <!-- Email Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">email</cide-ele-icon>\n </button>\n \n <!-- LinkedIn Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-blue-100 tw-flex tw-items-center tw-justify-center tw-text-blue-600 hover:tw-bg-blue-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">attach_money</cide-ele-icon>\n </button>\n \n <!-- Document Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">description</cide-ele-icon>\n </button>\n \n <!-- More Options Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">more_horiz</cide-ele-icon>\n </button>\n </div>\n \n <!-- Status Badge -->\n <div class=\"tw-flex-shrink-0\">\n @if (node.syen_isactive) {\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-bg-green-100 tw-text-green-800\">\n <div class=\"tw-w-1.5 tw-h-1.5 tw-bg-green-500 tw-rounded-full tw-mr-1\"></div>\n Active\n </div>\n } @else {\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-bg-red-100 tw-text-red-800\">\n <div class=\"tw-w-1.5 tw-h-1.5 tw-bg-red-500 tw-rounded-full tw-mr-1\"></div>\n Inactive\n </div>\n }\n </div>\n </div>\n </div>\n \n <!-- Children Entities (Recursive) -->\n @if (node.children && node.children.length > 0) {\n <!-- Flexible Connection Lines -->\n <div class=\"tw-relative tw-flex tw-flex-col tw-items-center tw-mt-4\">\n <!-- Connection dot -->\n <div class=\"tw-absolute tw-left-1/2 tw-transform tw--translate-x-1/2\" style=\"top: -8px;\">\n <div class=\"tw-w-2 tw-h-2 tw-bg-purple-600 tw-rounded-full tw-border tw-border-white\"></div>\n </div>\n \n <!-- Flexible SVG Lines -->\n <div class=\"tw-relative tw-w-full tw-flex tw-justify-center flexible-connection-lines\">\n @if (node.children && node.children.length === 1) {\n <!-- Single child - simple vertical line -->\n <svg class=\"tw-absolute tw-left-1/2\" style=\"transform: translateX(-50%); width: 2px; height: 40px; top: 0;\">\n <line x1=\"1\" y1=\"0\" x2=\"1\" y2=\"40\" stroke=\"#9333ea\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n }\n @else if (node.children && node.children.length > 1) {\n <!-- Multiple children - flexible design -->\n <svg class=\"tw-absolute tw-left-1/2\" style=\"transform: translateX(-50%); width: 100%; height: 40px; top: 0;\">\n <!-- Vertical line from parent -->\n <line x1=\"50%\" y1=\"0\" x2=\"50%\" y2=\"15\" stroke=\"#9333ea\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n \n <!-- Horizontal line spanning children -->\n <line x1=\"20%\" y1=\"15\" x2=\"80%\" y2=\"15\" stroke=\"#9333ea\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n \n <!-- Vertical lines to children -->\n @for (child of node.children; track child._id; let i = $index) {\n <line [attr.x1]=\"(20 + (60 * i) / (node.children.length - 1)) + '%'\" \n y1=\"15\" \n [attr.x2]=\"(20 + (60 * i) / (node.children.length - 1)) + '%'\" \n y2=\"35\" \n stroke=\"#9333ea\" \n stroke-width=\"2\" \n stroke-linecap=\"round\"/>\n <!-- Connection dot -->\n <circle [attr.cx]=\"(20 + (60 * i) / (node.children.length - 1)) + '%'\" cy=\"35\" r=\"2.5\" fill=\"#9333ea\" stroke=\"#fff\" stroke-width=\"1\"/>\n }\n </svg>\n }\n </div>\n \n <!-- Children Container - Flexible Layout -->\n <div class=\"tw-flex tw-flex-wrap tw-justify-center tw-gap-4 tw-w-full tw-max-w-6xl tw-px-4 children-container\">\n @for (child of node.children; track child._id) {\n <div class=\"tw-flex tw-flex-col tw-items-center tw-flex-shrink-0\">\n <!-- Child node -->\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\" [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"></ng-container>\n </div>\n }\n </div>\n </div>\n }\n </div>\n</ng-template>\n", styles: [".org-chart-container{overflow-x:auto;overflow-y:visible;min-height:100vh}.org-chart-content{min-width:max-content;padding:2rem 1rem}.flexible-connection-lines{position:relative;width:100%;height:40px}.flexible-connection-lines svg{position:absolute;left:50%;transform:translate(-50%);width:100%;height:100%;top:0}.children-container{display:flex;flex-wrap:wrap;justify-content:center;gap:1rem;width:100%;max-width:80rem;padding:0 1rem}.children-container>div{flex-shrink:0;display:flex;flex-direction:column;align-items:center}.entity-card{width:16rem;max-width:18rem;transition:all .2s ease-in-out}.entity-card:hover{transform:translateY(-2px) scale(1.02);box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a}@media (max-width: 1400px){.children-container{max-width:70rem;gap:.875rem}.entity-card{width:15rem;max-width:17rem}}@media (max-width: 1200px){.children-container{max-width:60rem;gap:.75rem}.entity-card{width:14rem;max-width:16rem}}@media (max-width: 992px){.children-container{max-width:50rem;gap:.625rem}.entity-card{width:13rem;max-width:15rem}}@media (max-width: 768px){.children-container{max-width:40rem;gap:.5rem}.entity-card{width:12rem;max-width:14rem}.org-chart-content{padding:1.5rem .75rem}}@media (max-width: 576px){.children-container{max-width:30rem;gap:.375rem}.entity-card{width:11rem;max-width:13rem}.org-chart-content{padding:1rem .5rem}}.tw-overflow-y-auto::-webkit-scrollbar{width:6px}.tw-overflow-y-auto::-webkit-scrollbar-track{background:#f1f5f9;border-radius:3px}.tw-overflow-y-auto::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px}.tw-overflow-y-auto::-webkit-scrollbar-thumb:hover{background:#94a3b8}.tw-transition-shadow{transition:box-shadow .2s ease-in-out}.tw-shadow-lg:hover{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a;transform:translateY(-2px);transition:all .2s ease-in-out}.tw-bg-purple-300,.tw-bg-purple-400{transition:all .3s ease-in-out}.connection-line-compact{display:block;overflow:visible}.connection-line-compact path,.connection-line-compact line{stroke-linecap:round;stroke-linejoin:round;transition:stroke-width .2s ease}.connection-line-compact:hover path,.connection-line-compact:hover line{stroke-width:3}.connection-line-compact circle{transition:all .2s ease}.connection-line-compact circle:hover{filter:drop-shadow(0 2px 4px rgba(147,51,234,.4))}.level-0{border-color:#fb923c!important}.level-1{border-color:#60a5fa!important}.level-2{border-color:#a78bfa!important}.level-3{border-color:#4ade80!important}.level-4{border-color:#818cf8!important}.level-5{border-color:#f472b6!important}@media (max-width: 1200px){.tw-max-w-7xl{max-width:100%}.tw-gap-6{gap:1rem}.tw-min-w-64{min-width:14rem}.tw-max-w-72{max-width:16rem}}@media (max-width: 768px){.tw-min-w-64{min-width:12rem}.tw-max-w-72{max-width:14rem}.tw-max-w-7xl{max-width:100%}.tw-gap-6{gap:.75rem}.tw-p-4{padding:.75rem}.tw-mb-4{margin-bottom:.75rem}.tw-space-x-3{gap:.5rem}.tw-space-x-2{gap:.375rem}.tw-w-12{width:2.5rem}.tw-h-12{height:2.5rem}}@media (max-width: 480px){.tw-min-w-72{min-width:12rem}.tw-max-w-80{max-width:14rem}.tw-p-4{padding:.5rem}.tw-space-x-3{gap:.375rem}.tw-space-x-2{gap:.25rem}.tw-mb-3{margin-bottom:.5rem}.tw-w-12{width:2rem}.tw-h-12{height:2rem}.tw-w-8{width:1.5rem}.tw-h-8{height:1.5rem}}@media print{.tw-bg-gray-50{background:#fff!important}.tw-shadow-lg{box-shadow:none!important;border:1px solid #e5e7eb!important}.tw-bg-purple-300{background:#6b7280!important}.tw-border-purple-300{border-color:#6b7280!important}}\n"] }]
219
422
  }] });
220
423
 
221
424
  /*
@@ -226,5 +429,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
226
429
  * Generated bundle index. Do not edit.
227
430
  */
228
431
 
229
- export { APP_STATE_SERVICE_TOKEN, AUTH_SERVICE_TOKEN, CideSharedOrgStructureComponent, CloudIdeShared, ENTITY_SERVICE_TOKEN, authGuard };
432
+ export { APP_STATE_SERVICE_TOKEN, AUTH_SERVICE_TOKEN, CideSharedOrgStructureComponent, CloudIdeShared, ENTITY_SERVICE_TOKEN, SharedObjectIdService, authGuard };
230
433
  //# sourceMappingURL=cloud-ide-shared.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-ide-shared.mjs","sources":["../../../projects/cloud-ide-shared/src/lib/cloud-ide-shared.ts","../../../projects/cloud-ide-shared/src/lib/services/auth.service.interface.ts","../../../projects/cloud-ide-shared/src/lib/guards/auth.guard.ts","../../../projects/cloud-ide-shared/src/lib/components/org-structure/org-structure.component.ts","../../../projects/cloud-ide-shared/src/lib/components/org-structure/org-structure.component.html","../../../projects/cloud-ide-shared/src/public-api.ts","../../../projects/cloud-ide-shared/src/cloud-ide-shared.ts"],"sourcesContent":["import { Component } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'lib-cloud-ide-shared',\r\n imports: [],\r\n template: `\r\n <p>\r\n cloud-ide-shared works!\r\n </p>\r\n `,\r\n styles: ``\r\n})\r\nexport class CloudIdeShared {\r\n\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\n// Interface for auth service to avoid circular dependency\r\nexport interface IAuthService {\r\n isAuthenticated(): boolean;\r\n isTokenExpired(): boolean;\r\n signOut(): void;\r\n refreshAuthState(): void;\r\n}\r\n\r\n// Interface for app state service to avoid circular dependency\r\nexport interface IAppStateService {\r\n isUserAuthenticated(): boolean;\r\n refreshFromLocalStorage(): void;\r\n}\r\n\r\n// Tokens for dependency injection\r\nexport const AUTH_SERVICE_TOKEN = new InjectionToken<IAuthService>('AuthService');\r\nexport const APP_STATE_SERVICE_TOKEN = new InjectionToken<IAppStateService>('AppStateService');\r\n","import { inject } from '@angular/core';\r\nimport { CanActivateFn, Router } from '@angular/router';\r\nimport { IAuthService, AUTH_SERVICE_TOKEN, IAppStateService, APP_STATE_SERVICE_TOKEN } from '../services/auth.service.interface';\r\n\r\nexport const authGuard: CanActivateFn = (route, state) => {\r\n const authService = inject(AUTH_SERVICE_TOKEN) as IAuthService;\r\n const appState = inject(APP_STATE_SERVICE_TOKEN) as IAppStateService;\r\n const router = inject(Router);\r\n \r\n // Refresh auth state to make sure it's current\r\n authService.refreshAuthState();\r\n \r\n // Refresh app state from localStorage to ensure synchronization\r\n appState.refreshFromLocalStorage();\r\n \r\n // Check if user is authenticated using app state (modern approach)\r\n if (appState.isUserAuthenticated() && !authService.isTokenExpired()) {\r\n return true;\r\n }\r\n \r\n // Redirect to login page with the intended destination\r\n router.navigate(['/auth/sign-in'], { \r\n queryParams: { returnUrl: state.url }\r\n });\r\n \r\n return false;\r\n};\r\n","import { Component, signal, OnInit, inject, input, output, InjectionToken } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { Router } from '@angular/router';\r\nimport { CideEleButtonComponent, CideIconComponent, CideSpinnerComponent } from 'cloud-ide-element';\r\n\r\nexport interface OrgStructureNode {\r\n _id: string; // Primary key\r\n syen_name: string;\r\n syen_entity_code: string;\r\n syen_entity_type_sygms: string;\r\n syen_isactive: boolean;\r\n children?: OrgStructureNode[];\r\n level: number;\r\n parentId?: string; // Foreign key referencing syen_id_syen (empty string \"\" means root level)\r\n}\r\n\r\n// Interface for entity service to avoid circular dependency\r\nexport interface IEntityService {\r\n getEntityList(params: any): any;\r\n}\r\n\r\n// Injection token for entity service\r\nexport const ENTITY_SERVICE_TOKEN = new InjectionToken<IEntityService>('EntityService');\r\n\r\n@Component({\r\n selector: 'cide-shared-org-structure',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n CideEleButtonComponent,\r\n CideIconComponent,\r\n CideSpinnerComponent\r\n ],\r\n templateUrl: './org-structure.component.html',\r\n styleUrl: './org-structure.component.scss'\r\n})\r\nexport class CideSharedOrgStructureComponent implements OnInit {\r\n // Input parameters for configuration\r\n allowSwitching = input<boolean>(true); // Allow entity switching (default: true)\r\n showActions = input<boolean>(true); // Show action buttons (default: true)\r\n mode = input<'selection' | 'view'>('view'); // Mode: selection or view-only\r\n\r\n // Output events\r\n entityClick = output<OrgStructureNode>(); // Emit when entity is clicked\r\n entitySelect = output<OrgStructureNode>(); // Emit when entity is selected for switching\r\n entityView = output<OrgStructureNode>(); // Emit when entity is viewed\r\n\r\n private entityService = inject(ENTITY_SERVICE_TOKEN) as IEntityService;\r\n public router = inject(Router);\r\n\r\n // Signals\r\n loading = signal(false);\r\n error = signal<string | null>(null);\r\n orgStructure = signal<OrgStructureNode[]>([]);\r\n\r\n ngOnInit(): void {\r\n this.loadOrgStructure();\r\n }\r\n\r\n /**\r\n * Load organization structure\r\n */\r\n loadOrgStructure(): void {\r\n this.loading.set(true);\r\n this.error.set(null);\r\n\r\n this.entityService.getEntityList({}).subscribe({\r\n next: (response: any) => {\r\n if (response?.success && response?.data) {\r\n const structure = this.buildOrgStructure(response.data);\r\n this.orgStructure.set(structure);\r\n console.log('🏢 [OrgStructure] Loaded organization structure:', structure.length, 'root entities');\r\n } else {\r\n this.error.set('Failed to load organization structure');\r\n console.error('❌ [OrgStructure] Failed to load entities:', response);\r\n }\r\n this.loading.set(false);\r\n },\r\n error: (error: any) => {\r\n this.error.set('Error loading organization structure');\r\n console.error('❌ [OrgStructure] Error loading entities:', error);\r\n this.loading.set(false);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Build organization structure from flat entity list\r\n */\r\n private buildOrgStructure(entities: any[]): OrgStructureNode[] {\r\n const nodeMap = new Map<string, OrgStructureNode>();\r\n const rootNodes: OrgStructureNode[] = [];\r\n\r\n // First pass: create all nodes\r\n entities.forEach(entity => {\r\n const node: OrgStructureNode = {\r\n _id: entity._id || '',\r\n syen_name: entity.syen_name || 'Unnamed Entity',\r\n syen_entity_code: entity.syen_entity_code || '',\r\n syen_entity_type_sygms: entity.syen_entity_type_sygms || '',\r\n syen_isactive: entity.syen_isactive || false,\r\n children: [],\r\n level: 0,\r\n parentId: entity.syen_id_syen || undefined\r\n };\r\n nodeMap.set(node._id, node);\r\n });\r\n\r\n // Second pass: build hierarchy\r\n entities.forEach(entity => {\r\n const node = nodeMap.get(entity._id || '');\r\n if (node) {\r\n const parentId = entity.syen_id_syen;\r\n if (parentId && parentId !== \"\" && nodeMap.has(parentId)) {\r\n const parent = nodeMap.get(parentId)!;\r\n parent.children = parent.children || [];\r\n parent.children.push(node);\r\n node.level = this.calculateLevel(parent, nodeMap);\r\n } else {\r\n node.level = 0;\r\n rootNodes.push(node);\r\n }\r\n }\r\n });\r\n\r\n // Sort children recursively\r\n this.sortChildrenRecursively(rootNodes);\r\n return rootNodes;\r\n }\r\n\r\n /**\r\n * Calculate level of a node based on its parent\r\n */\r\n private calculateLevel(node: OrgStructureNode, nodeMap: Map<string, OrgStructureNode>): number {\r\n let level = 0;\r\n let current = node;\r\n \r\n while (current.parentId && nodeMap.has(current.parentId)) {\r\n level++;\r\n current = nodeMap.get(current.parentId)!;\r\n }\r\n \r\n return level;\r\n }\r\n\r\n /**\r\n * Sort children recursively by name\r\n */\r\n private sortChildrenRecursively(nodes: OrgStructureNode[]): void {\r\n nodes.sort((a, b) => a.syen_name.localeCompare(b.syen_name));\r\n \r\n nodes.forEach(node => {\r\n if (node.children && node.children.length > 0) {\r\n this.sortChildrenRecursively(node.children);\r\n }\r\n });\r\n }\r\n\r\n\r\n /**\r\n * View entity details\r\n */\r\n viewEntity(entityId: string): void {\r\n // Find the entity in the structure\r\n const entity = this.findEntityById(entityId);\r\n if (entity) {\r\n // Emit the appropriate event based on mode\r\n this.entityClick.emit(entity);\r\n \r\n if (this.mode() === 'selection' && this.allowSwitching()) {\r\n this.entitySelect.emit(entity);\r\n } else {\r\n this.entityView.emit(entity);\r\n }\r\n }\r\n\r\n // Only navigate if not in selection mode\r\n if (this.mode() !== 'selection') {\r\n this.router.navigate(['/control-panel/entity-list'], { \r\n queryParams: { view: entityId } \r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Find entity by ID in the structure\r\n */\r\n private findEntityById(entityId: string): OrgStructureNode | null {\r\n const findInNodes = (nodes: OrgStructureNode[]): OrgStructureNode | null => {\r\n for (const node of nodes) {\r\n if (node._id === entityId) {\r\n return node;\r\n }\r\n if (node.children && node.children.length > 0) {\r\n const found = findInNodes(node.children);\r\n if (found) return found;\r\n }\r\n }\r\n return null;\r\n };\r\n \r\n return findInNodes(this.orgStructure());\r\n }\r\n\r\n /**\r\n * Edit entity\r\n */\r\n editEntity(entityId: string): void {\r\n this.router.navigate(['/control-panel/entity-list/entity-create'], { \r\n queryParams: { edit: entityId } \r\n });\r\n }\r\n}\r\n","<!-- Organization Structure Component -->\r\n<div class=\"tw-flex-1 tw-overflow-hidden\">\r\n @if (loading()) {\r\n <div class=\"tw-flex tw-items-center tw-justify-center tw-py-12\">\r\n <cide-ele-spinner size=\"md\"></cide-ele-spinner>\r\n <span class=\"tw-ml-3 tw-text-gray-600 tw-text-sm\">Loading organization structure...</span>\r\n </div>\r\n } @else if (error()) {\r\n <div class=\"tw-text-center tw-py-12\">\r\n <div class=\"tw-w-16 tw-h-16 tw-bg-red-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\r\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-red-500\">error</cide-ele-icon>\r\n </div>\r\n <h3 class=\"tw-text-lg tw-font-medium tw-text-gray-900 tw-mb-2\">Error Loading Structure</h3>\r\n <p class=\"tw-text-gray-600 tw-mb-4\">{{ error() }}</p>\r\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"loadOrgStructure()\">\r\n <cide-ele-icon>refresh</cide-ele-icon>\r\n Try Again\r\n </button>\r\n </div>\r\n } @else if (orgStructure().length === 0) {\r\n <div class=\"tw-text-center tw-py-12\">\r\n <div class=\"tw-w-16 tw-h-16 tw-bg-gray-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\r\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-gray-400\">account_tree</cide-ele-icon>\r\n </div>\r\n <h3 class=\"tw-text-lg tw-font-medium tw-text-gray-900 tw-mb-2\">No Entities Found</h3>\r\n <p class=\"tw-text-gray-600 tw-mb-4\">No entities are available to display in the organization structure.</p>\r\n @if (mode() === 'view') {\r\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"router.navigate(['/control-panel/entity-list'])\">\r\n <cide-ele-icon>add</cide-ele-icon>\r\n Create First Entity\r\n </button>\r\n }\r\n </div>\r\n } @else {\r\n <!-- Organization Chart Container -->\r\n <div class=\"tw-relative tw-min-h-screen tw-bg-gray-50 tw-py-8\">\r\n <!-- Background Grid Pattern -->\r\n <div class=\"tw-absolute tw-inset-0 tw-opacity-30\" style=\"background-image: radial-gradient(circle, #e5e7eb 1px, transparent 1px); background-size: 20px 20px;\"></div>\r\n \r\n <!-- Chart Content -->\r\n <div class=\"tw-relative tw-z-10\">\r\n @for (rootNode of orgStructure(); track rootNode._id) {\r\n <div class=\"tw-flex tw-flex-col tw-items-center tw-mb-12\">\r\n <!-- Render node recursively with unlimited depth -->\r\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\" [ngTemplateOutletContext]=\"{ $implicit: rootNode, level: 0 }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n\r\n<!-- Entity Node Template (Recursive) -->\r\n<ng-template #entityNodeTemplate let-node let-level=\"level\">\r\n <div class=\"tw-flex tw-flex-col tw-items-center\">\r\n \r\n <!-- Entity Card -->\r\n <div class=\"tw-bg-white tw-shadow-lg tw-rounded-lg tw-p-4 tw-min-w-64 tw-max-w-72 tw-border-t-4 tw-transition-shadow tw-cursor-pointer hover:tw-shadow-xl\"\r\n [class.level-0]=\"level === 0\"\r\n [class.level-1]=\"level === 1\"\r\n [class.level-2]=\"level === 2\"\r\n [class.level-3]=\"level === 3\"\r\n [class.level-4]=\"level === 4\"\r\n [class.level-5]=\"level === 5\"\r\n (click)=\"viewEntity(node._id)\">\r\n \r\n <!-- Card Content -->\r\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\r\n <!-- Avatar -->\r\n <div class=\"tw-w-12 tw-h-12 tw-bg-purple-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-flex-shrink-0\">\r\n <cide-ele-icon class=\"tw-w-6 tw-h-6 tw-text-purple-600\">person</cide-ele-icon>\r\n </div>\r\n \r\n <!-- Entity Info -->\r\n <div class=\"tw-flex-1 tw-min-w-0\">\r\n <h3 class=\"tw-text-sm tw-font-semibold tw-text-gray-900 tw-whitespace-nowrap tw-overflow-hidden tw-text-ellipsis\">{{ node.syen_name }}</h3>\r\n <p class=\"tw-text-xs tw-text-gray-600 tw-mt-1\">{{ node.syen_entity_code }}</p>\r\n <p class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">{{ node.syen_entity_type_sygms }}</p>\r\n </div>\r\n </div>\r\n \r\n <!-- Action Icons -->\r\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mt-3\">\r\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\r\n <!-- Phone Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">phone</cide-ele-icon>\r\n </button>\r\n \r\n <!-- Email Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">email</cide-ele-icon>\r\n </button>\r\n \r\n <!-- LinkedIn Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-blue-100 tw-flex tw-items-center tw-justify-center tw-text-blue-600 hover:tw-bg-blue-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">attach_money</cide-ele-icon>\r\n </button>\r\n \r\n <!-- Document Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">description</cide-ele-icon>\r\n </button>\r\n \r\n <!-- More Options Icon -->\r\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\r\n <cide-ele-icon class=\"tw-text-xs\">more_horiz</cide-ele-icon>\r\n </button>\r\n </div>\r\n \r\n <!-- Status Badge -->\r\n <div class=\"tw-flex-shrink-0\">\r\n @if (node.syen_isactive) {\r\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-bg-green-100 tw-text-green-800\">\r\n <div class=\"tw-w-1.5 tw-h-1.5 tw-bg-green-500 tw-rounded-full tw-mr-1\"></div>\r\n Active\r\n </div>\r\n } @else {\r\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-bg-red-100 tw-text-red-800\">\r\n <div class=\"tw-w-1.5 tw-h-1.5 tw-bg-red-500 tw-rounded-full tw-mr-1\"></div>\r\n Inactive\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Children Entities (Recursive) -->\r\n @if (node.children && node.children.length > 0) {\r\n <!-- Ultra-Compact Connection Lines -->\r\n <div class=\"tw-relative tw-flex tw-flex-col tw-items-center tw-mt-2\">\r\n <!-- Minimal connection dot -->\r\n <div class=\"tw-absolute tw-left-1/2 tw-transform tw--translate-x-1/2\" style=\"top: -8px;\">\r\n <div class=\"tw-w-2 tw-h-2 tw-bg-purple-600 tw-rounded-full tw-border tw-border-white\"></div>\r\n </div>\r\n \r\n <!-- Ultra-Compact SVG Lines -->\r\n <div class=\"tw-relative tw-w-full\" style=\"height: 30px;\">\r\n @if (node.children && node.children.length === 1) {\r\n <!-- Single child - minimal line -->\r\n <svg class=\"tw-absolute tw-left-1/2 connection-line-compact\" style=\"transform: translateX(-50%); width: 2px; height: 30px; top: 0;\">\r\n <line x1=\"1\" y1=\"0\" x2=\"1\" y2=\"30\" stroke=\"#9333ea\" stroke-width=\"2\" stroke-linecap=\"round\"/>\r\n </svg>\r\n }\r\n @else if (node.children && node.children.length > 1) {\r\n <!-- Multiple children - minimal design -->\r\n <svg class=\"tw-absolute tw-left-1/2 connection-line-compact\" [attr.style]=\"'transform: translateX(-50%); width: ' + ((node.children.length - 1) * 336 + 256) + 'px; height: 30px; top: 0;'\">\r\n <!-- Vertical line -->\r\n <line [attr.x1]=\"((node.children.length - 1) * 336 + 256) / 2\" \r\n y1=\"0\" \r\n [attr.x2]=\"((node.children.length - 1) * 336 + 256) / 2\" \r\n y2=\"12\" \r\n stroke=\"#9333ea\" \r\n stroke-width=\"2\" \r\n stroke-linecap=\"round\"/>\r\n \r\n <!-- Horizontal line -->\r\n <path [attr.d]=\"'M 128 15 L ' + ((node.children.length - 1) * 336 + 128) + ' 15'\" \r\n stroke=\"#9333ea\" \r\n stroke-width=\"2\" \r\n stroke-linecap=\"round\"/>\r\n \r\n <!-- Vertical lines to children -->\r\n @for (child of node.children; track child._id; let i = $index) {\r\n <line [attr.x1]=\"(i * 336) + 128\" \r\n y1=\"15\" \r\n [attr.x2]=\"(i * 336) + 128\" \r\n y2=\"28\" \r\n stroke=\"#9333ea\" \r\n stroke-width=\"2\" \r\n stroke-linecap=\"round\"/>\r\n <!-- Tiny dot -->\r\n <circle [attr.cx]=\"(i * 336) + 128\" cy=\"28\" r=\"2.5\" fill=\"#9333ea\" stroke=\"#fff\" stroke-width=\"1\"/>\r\n }\r\n </svg>\r\n }\r\n </div>\r\n \r\n <!-- Children -->\r\n <div class=\"tw-flex tw-justify-center tw-gap-20\">\r\n @for (child of node.children; track child._id) {\r\n <div class=\"tw-flex tw-flex-col tw-items-center\">\r\n <!-- Child node -->\r\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\" [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"></ng-container>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n</ng-template>\r\n","/*\r\n * Public API Surface of cloud-ide-shared\r\n */\r\n\r\nexport * from './lib/cloud-ide-shared';\r\n\r\n// Guards\r\nexport * from './lib/guards/auth.guard';\r\n\r\n// Services\r\nexport * from './lib/services/auth.service.interface';\r\n\r\n// Components\r\nexport * from './lib/components/org-structure/org-structure.component';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cloud-ide-shared.mjs","sources":["../../../projects/cloud-ide-shared/src/lib/cloud-ide-shared.ts","../../../projects/cloud-ide-shared/src/lib/services/auth.service.interface.ts","../../../projects/cloud-ide-shared/src/lib/guards/auth.guard.ts","../../../projects/cloud-ide-shared/src/lib/services/shared-object-id.service.ts","../../../projects/cloud-ide-shared/src/lib/components/org-structure/org-structure.component.ts","../../../projects/cloud-ide-shared/src/lib/components/org-structure/org-structure.component.html","../../../projects/cloud-ide-shared/src/public-api.ts","../../../projects/cloud-ide-shared/src/cloud-ide-shared.ts"],"sourcesContent":["import { Component } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'lib-cloud-ide-shared',\r\n imports: [],\r\n template: `\r\n <p>\r\n cloud-ide-shared works!\r\n </p>\r\n `,\r\n styles: ``\r\n})\r\nexport class CloudIdeShared {\r\n\r\n}\r\n","import { InjectionToken } from '@angular/core';\n\n// Interface for auth service to avoid circular dependency\nexport interface IAuthService {\n isAuthenticated(): boolean;\n isTokenExpired(): boolean;\n signOut(): void;\n refreshAuthState(): void;\n}\n\n// Interface for app state service to avoid circular dependency\nexport interface IAppStateService {\n isUserAuthenticated(): boolean;\n refreshFromLocalStorage(): void;\n}\n\n// Tokens for dependency injection\nexport const AUTH_SERVICE_TOKEN = new InjectionToken<IAuthService>('AuthService');\nexport const APP_STATE_SERVICE_TOKEN = new InjectionToken<IAppStateService>('AppStateService');\n","import { inject } from '@angular/core';\r\nimport { CanActivateFn, Router } from '@angular/router';\r\nimport { IAuthService, AUTH_SERVICE_TOKEN, IAppStateService, APP_STATE_SERVICE_TOKEN } from '../services/auth.service.interface';\r\n\r\nexport const authGuard: CanActivateFn = (route, state) => {\r\n const authService = inject(AUTH_SERVICE_TOKEN) as IAuthService;\r\n const appState = inject(APP_STATE_SERVICE_TOKEN) as IAppStateService;\r\n const router = inject(Router);\r\n \r\n // Refresh auth state to make sure it's current\r\n authService.refreshAuthState();\r\n \r\n // Refresh app state from localStorage to ensure synchronization\r\n appState.refreshFromLocalStorage();\r\n \r\n // Check if user is authenticated using app state (modern approach)\r\n if (appState.isUserAuthenticated() && !authService.isTokenExpired()) {\r\n return true;\r\n }\r\n \r\n // Redirect to login page with the intended destination\r\n router.navigate(['/auth/sign-in'], { \r\n queryParams: { returnUrl: state.url }\r\n });\r\n \r\n return false;\r\n};\r\n","import { Injectable, inject } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\nimport { CideEleFileManagerService } from 'cloud-ide-element';\r\nimport { mongooseObjectIdCreateControllerResponse } from 'cloud-ide-element';\r\n\r\n/**\r\n * Shared Object ID Generation Service\r\n * \r\n * This service provides a consistent interface for generating Object IDs\r\n * across all libraries. It internally uses the FileManagerService but\r\n * provides a standardized API that can be used throughout the application.\r\n * \r\n * Benefits:\r\n * - Consistent interface across all libraries\r\n * - Centralized Object ID generation logic\r\n * - Easy to maintain and update\r\n * - Prevents confusion with different Object ID generation methods\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class SharedObjectIdService {\r\n private fileManagerService = inject(CideEleFileManagerService);\r\n\r\n /**\r\n * Generate a new Object ID\r\n * \r\n * This method internally uses the FileManagerService to generate\r\n * a unique Object ID that can be used for any entity in the system.\r\n * \r\n * @returns Observable<mongooseObjectIdCreateControllerResponse> - The generated Object ID response\r\n * \r\n * @example\r\n * ```typescript\r\n * // Generate Object ID for a new user\r\n * this.sharedObjectIdService.generateObjectId().subscribe({\r\n * next: (response) => {\r\n * if (response.success && response.data?.objectId) {\r\n * const newUserId = response.data.objectId;\r\n * // Use the Object ID for creating a new user\r\n * }\r\n * },\r\n * error: (error) => {\r\n * console.error('Failed to generate Object ID:', error);\r\n * }\r\n * });\r\n * ```\r\n */\r\n generateObjectId(): Observable<mongooseObjectIdCreateControllerResponse> {\r\n console.log('🆔 [SharedObjectIdService] Generating Object ID via FileManagerService');\r\n \r\n return this.fileManagerService.generateObjectId();\r\n }\r\n\r\n /**\r\n * Generate Object ID as Promise\r\n * \r\n * Convenience method that converts the Observable to a Promise\r\n * for easier use with async/await syntax.\r\n * \r\n * @returns Promise<string> - The generated Object ID string\r\n * \r\n * @example\r\n * ```typescript\r\n * // Generate Object ID using async/await\r\n * try {\r\n * const objectId = await this.sharedObjectIdService.generateObjectIdAsync();\r\n * console.log('Generated Object ID:', objectId);\r\n * } catch (error) {\r\n * console.error('Failed to generate Object ID:', error);\r\n * }\r\n * ```\r\n */\r\n async generateObjectIdAsync(): Promise<string> {\r\n try {\r\n const response = await this.generateObjectId().toPromise();\r\n if (response?.success && response?.data?.objectId) {\r\n console.log('🆔 [SharedObjectIdService] Generated Object ID:', response.data.objectId);\r\n return response.data.objectId;\r\n } else {\r\n throw new Error('Failed to generate Object ID: Invalid response');\r\n }\r\n } catch (error) {\r\n console.error('❌ [SharedObjectIdService] Error generating Object ID:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Generate multiple Object IDs at once\r\n * \r\n * Useful when you need multiple Object IDs for batch operations.\r\n * \r\n * @param count - Number of Object IDs to generate\r\n * @returns Observable<string[]> - Array of generated Object IDs\r\n * \r\n * @example\r\n * ```typescript\r\n * // Generate 5 Object IDs for batch creation\r\n * this.sharedObjectIdService.generateMultipleObjectIds(5).subscribe({\r\n * next: (objectIds) => {\r\n * console.log('Generated Object IDs:', objectIds);\r\n * // Use the Object IDs for batch operations\r\n * }\r\n * });\r\n * ```\r\n */\r\n generateMultipleObjectIds(count: number): Observable<string[]> {\r\n console.log(`🆔 [SharedObjectIdService] Generating ${count} Object IDs`);\r\n \r\n const requests = Array.from({ length: count }, () => this.generateObjectId());\r\n \r\n return new Observable(observer => {\r\n let completed = 0;\r\n const objectIds: string[] = [];\r\n \r\n requests.forEach((request, index) => {\r\n request.subscribe({\r\n next: (response) => {\r\n if (response?.success && response?.data?.objectId) {\r\n objectIds[index] = response.data.objectId;\r\n } else {\r\n observer.error(new Error(`Failed to generate Object ID at index ${index}`));\r\n return;\r\n }\r\n \r\n completed++;\r\n if (completed === count) {\r\n observer.next(objectIds);\r\n observer.complete();\r\n }\r\n },\r\n error: (error) => {\r\n observer.error(error);\r\n }\r\n });\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Generate Object ID with validation\r\n * \r\n * Generates an Object ID and validates it before returning.\r\n * \r\n * @param validator - Optional validation function\r\n * @returns Observable<string> - Validated Object ID\r\n * \r\n * @example\r\n * ```typescript\r\n * // Generate Object ID with custom validation\r\n * const validator = (id: string) => id.length === 24; // MongoDB ObjectId length\r\n * this.sharedObjectIdService.generateObjectIdWithValidation(validator).subscribe({\r\n * next: (validatedId) => {\r\n * console.log('Validated Object ID:', validatedId);\r\n * }\r\n * });\r\n * ```\r\n */\r\n generateObjectIdWithValidation(validator?: (id: string) => boolean): Observable<string> {\r\n return new Observable(observer => {\r\n this.generateObjectId().subscribe({\r\n next: (response) => {\r\n if (response?.success && response?.data?.objectId) {\r\n const objectId = response.data.objectId;\r\n \r\n // Apply validation if provided\r\n if (validator && !validator(objectId)) {\r\n observer.error(new Error('Generated Object ID failed validation'));\r\n return;\r\n }\r\n \r\n observer.next(objectId);\r\n observer.complete();\r\n } else {\r\n observer.error(new Error('Failed to generate Object ID: Invalid response'));\r\n }\r\n },\r\n error: (error) => {\r\n observer.error(error);\r\n }\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Check if a string is a valid Object ID format\r\n * \r\n * @param id - String to validate\r\n * @returns boolean - True if valid Object ID format\r\n * \r\n * @example\r\n * ```typescript\r\n * const isValid = this.sharedObjectIdService.isValidObjectId('507f1f77bcf86cd799439011');\r\n * console.log('Is valid Object ID:', isValid); // true\r\n * ```\r\n */\r\n isValidObjectId(id: string): boolean {\r\n // MongoDB ObjectId is 24 characters long and contains only hexadecimal characters\r\n const objectIdRegex = /^[0-9a-fA-F]{24}$/;\r\n return objectIdRegex.test(id);\r\n }\r\n\r\n /**\r\n * Get Object ID generation statistics\r\n * \r\n * Returns information about Object ID generation for monitoring purposes.\r\n * \r\n * @returns Object with statistics\r\n */\r\n getGenerationStats(): { serviceName: string; description: string; internalService: string } {\r\n return {\r\n serviceName: 'SharedObjectIdService',\r\n description: 'Centralized Object ID generation service',\r\n internalService: 'CideEleFileManagerService'\r\n };\r\n }\r\n}\r\n","import { Component, signal, OnInit, inject, input, output, InjectionToken } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Router } from '@angular/router';\nimport { CideEleButtonComponent, CideIconComponent, CideSpinnerComponent } from 'cloud-ide-element';\nimport { entityControllerResponse, MEntity, CoreSystemEntityListResponse } from 'cloud-ide-lms-model';\nimport { Observable } from 'rxjs';\n\n// Interface for entity service to avoid circular dependency\nexport interface IEntityService {\n getEntityList(params: MEntity): Observable<entityControllerResponse>;\n}\n\n// Injection token for entity service\nexport const ENTITY_SERVICE_TOKEN = new InjectionToken<IEntityService>('EntityService');\n\n@Component({\n selector: 'cide-shared-org-structure',\n standalone: true,\n imports: [\n CommonModule,\n CideEleButtonComponent,\n CideIconComponent,\n CideSpinnerComponent\n ],\n templateUrl: './org-structure.component.html',\n styleUrl: './org-structure.component.scss'\n})\nexport class CideSharedOrgStructureComponent implements OnInit {\n // Input parameters for configuration\n allowSwitching = input<boolean>(true); // Allow entity switching (default: true)\n showActions = input<boolean>(true); // Show action buttons (default: true)\n mode = input<'selection' | 'view'>('view'); // Mode: selection or view-only\n\n // Output events\n entityClick = output<CoreSystemEntityListResponse>(); // Emit when entity is clicked\n entitySelect = output<CoreSystemEntityListResponse>(); // Emit when entity is selected for switching\n entityView = output<CoreSystemEntityListResponse>(); // Emit when entity is viewed\n\n private entityService = inject(ENTITY_SERVICE_TOKEN) as IEntityService;\n public router = inject(Router);\n\n // Signals\n loading = signal(false);\n error = signal<string | null>(null);\n orgStructure = signal<CoreSystemEntityListResponse[]>([]);\n\n ngOnInit(): void {\n this.loadOrgStructure();\n }\n\n /**\n * Load organization structure\n */\n loadOrgStructure(): void {\n this.loading.set(true);\n this.error.set(null);\n\n this.entityService.getEntityList({}).subscribe({\n next: (response: entityControllerResponse) => {\n if (response?.success && response?.data) {\n const structure = this.buildOrgStructure(response.data);\n this.orgStructure.set(structure);\n console.log('🏢 [OrgStructure] Loaded organization structure:', structure.length, 'root entities');\n } else {\n this.error.set('Failed to load organization structure');\n console.error('❌ [OrgStructure] Failed to load entities:', response);\n }\n this.loading.set(false);\n },\n error: (error: any) => {\n this.error.set('Error loading organization structure');\n console.error('❌ [OrgStructure] Error loading entities:', error);\n this.loading.set(false);\n }\n });\n }\n\n /**\n * Build organization structure from flat entity list\n */\n private buildOrgStructure(entities: CoreSystemEntityListResponse[]): CoreSystemEntityListResponse[] {\n const nodeMap = new Map<string, CoreSystemEntityListResponse>();\n const rootNodes: CoreSystemEntityListResponse[] = [];\n\n // First pass: create all nodes\n entities.forEach(entity => {\n const node: CoreSystemEntityListResponse = {\n ...entity,\n children: []\n };\n nodeMap.set(entity._id || '', node);\n });\n\n // Second pass: build hierarchy\n entities.forEach(entity => {\n const node = nodeMap.get(entity._id || '');\n if (node) {\n const parentId = entity.syen_id_syen;\n if (parentId && parentId !== \"\" && nodeMap.has(parentId)) {\n const parent = nodeMap.get(parentId)!;\n parent.children = parent.children || [];\n parent.children.push(node);\n } else {\n rootNodes.push(node);\n }\n }\n });\n\n // Sort children recursively\n this.sortChildrenRecursively(rootNodes);\n return rootNodes;\n }\n\n /**\n * Calculate level of a node based on its parent\n */\n private calculateLevel(node: CoreSystemEntityListResponse, nodeMap: Map<string, CoreSystemEntityListResponse>): number {\n let level = 0;\n let current = node;\n \n while (current.syen_id_syen && nodeMap.has(current.syen_id_syen)) {\n level++;\n current = nodeMap.get(current.syen_id_syen)!;\n }\n \n return level;\n }\n\n /**\n * Sort children recursively by name\n */\n private sortChildrenRecursively(nodes: CoreSystemEntityListResponse[]): void {\n nodes.sort((a, b) => (a.syen_name || '').localeCompare(b.syen_name || ''));\n \n nodes.forEach(node => {\n if (node.children && node.children.length > 0) {\n this.sortChildrenRecursively(node.children);\n }\n });\n }\n\n\n /**\n * View entity details\n */\n viewEntity(entityId: string): void {\n // Find the entity in the structure\n const entity = this.findEntityById(entityId);\n if (entity) {\n // Emit the appropriate event based on mode\n this.entityClick.emit(entity);\n \n if (this.mode() === 'selection' && this.allowSwitching()) {\n this.entitySelect.emit(entity);\n } else {\n this.entityView.emit(entity);\n }\n }\n\n // Only navigate if not in selection mode\n if (this.mode() !== 'selection') {\n this.router.navigate(['/control-panel/entity-list'], { \n queryParams: { view: entityId } \n });\n }\n }\n\n /**\n * Find entity by ID in the structure\n */\n private findEntityById(entityId: string): CoreSystemEntityListResponse | null {\n const findInNodes = (nodes: CoreSystemEntityListResponse[]): CoreSystemEntityListResponse | null => {\n for (const node of nodes) {\n if (node._id === entityId) {\n return node;\n }\n if (node.children && node.children.length > 0) {\n const found = findInNodes(node.children);\n if (found) return found;\n }\n }\n return null;\n };\n \n return findInNodes(this.orgStructure());\n }\n\n /**\n * Edit entity\n */\n editEntity(entityId: string): void {\n this.router.navigate(['/control-panel/entity-list/entity-create'], { \n queryParams: { edit: entityId } \n });\n }\n}\n","<!-- Organization Structure Component -->\n<div class=\"tw-flex-1 tw-overflow-hidden\">\n @if (loading()) {\n <div class=\"tw-flex tw-items-center tw-justify-center tw-py-12\">\n <cide-ele-spinner size=\"md\"></cide-ele-spinner>\n <span class=\"tw-ml-3 tw-text-gray-600 tw-text-sm\">Loading organization structure...</span>\n </div>\n } @else if (error()) {\n <div class=\"tw-text-center tw-py-12\">\n <div class=\"tw-w-16 tw-h-16 tw-bg-red-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-red-500\">error</cide-ele-icon>\n </div>\n <h3 class=\"tw-text-lg tw-font-medium tw-text-gray-900 tw-mb-2\">Error Loading Structure</h3>\n <p class=\"tw-text-gray-600 tw-mb-4\">{{ error() }}</p>\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"loadOrgStructure()\">\n <cide-ele-icon>refresh</cide-ele-icon>\n Try Again\n </button>\n </div>\n } @else if (orgStructure().length === 0) {\n <div class=\"tw-text-center tw-py-12\">\n <div class=\"tw-w-16 tw-h-16 tw-bg-gray-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-gray-400\">account_tree</cide-ele-icon>\n </div>\n <h3 class=\"tw-text-lg tw-font-medium tw-text-gray-900 tw-mb-2\">No Entities Found</h3>\n <p class=\"tw-text-gray-600 tw-mb-4\">No entities are available to display in the organization structure.</p>\n @if (mode() === 'view') {\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"router.navigate(['/control-panel/entity-list'])\">\n <cide-ele-icon>add</cide-ele-icon>\n Create First Entity\n </button>\n }\n </div>\n } @else {\n <!-- Organization Chart Container -->\n <div class=\"tw-relative tw-min-h-screen tw-bg-gray-50 tw-py-8 tw-overflow-x-auto org-chart-container\">\n <!-- Background Grid Pattern -->\n <div class=\"tw-absolute tw-inset-0 tw-opacity-30\" style=\"background-image: radial-gradient(circle, #e5e7eb 1px, transparent 1px); background-size: 20px 20px;\"></div>\n \n <!-- Chart Content -->\n <div class=\"tw-relative tw-z-10 tw-min-w-max tw-px-4 org-chart-content\">\n @for (rootNode of orgStructure(); track rootNode._id) {\n <div class=\"tw-flex tw-flex-col tw-items-center tw-mb-12\">\n <!-- Render node recursively with unlimited depth -->\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\" [ngTemplateOutletContext]=\"{ $implicit: rootNode, level: 0 }\"></ng-container>\n </div>\n }\n </div>\n </div>\n }\n</div>\n\n<!-- Entity Node Template (Recursive) -->\n<ng-template #entityNodeTemplate let-node let-level=\"level\">\n <div class=\"tw-flex tw-flex-col tw-items-center\">\n \n <!-- Entity Card -->\n <div class=\"tw-bg-white tw-shadow-lg tw-rounded-lg tw-p-4 tw-w-64 tw-max-w-72 tw-border-t-4 tw-transition-all tw-cursor-pointer hover:tw-shadow-xl hover:tw-scale-105 entity-card\"\n [class.level-0]=\"level === 0\"\n [class.level-1]=\"level === 1\"\n [class.level-2]=\"level === 2\"\n [class.level-3]=\"level === 3\"\n [class.level-4]=\"level === 4\"\n [class.level-5]=\"level === 5\"\n (click)=\"viewEntity(node._id)\">\n \n <!-- Card Content -->\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\n <!-- Avatar -->\n <div class=\"tw-w-12 tw-h-12 tw-bg-purple-100 tw-rounded-full tw-flex tw-items-center tw-justify-center tw-flex-shrink-0\">\n <cide-ele-icon class=\"tw-w-6 tw-h-6 tw-text-purple-600\">person</cide-ele-icon>\n </div>\n \n <!-- Entity Info -->\n <div class=\"tw-flex-1 tw-min-w-0\">\n <h3 class=\"tw-text-sm tw-font-semibold tw-text-gray-900 tw-whitespace-nowrap tw-overflow-hidden tw-text-ellipsis\">{{ node.syen_name }}</h3>\n <p class=\"tw-text-xs tw-text-gray-600 tw-mt-1\">{{ node.syen_entity_code }}</p>\n <p class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">{{ node.syen_entity_type_sygms }}</p>\n </div>\n </div>\n \n <!-- Action Icons -->\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mt-3\">\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <!-- Phone Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">phone</cide-ele-icon>\n </button>\n \n <!-- Email Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">email</cide-ele-icon>\n </button>\n \n <!-- LinkedIn Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-blue-100 tw-flex tw-items-center tw-justify-center tw-text-blue-600 hover:tw-bg-blue-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">attach_money</cide-ele-icon>\n </button>\n \n <!-- Document Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">description</cide-ele-icon>\n </button>\n \n <!-- More Options Icon -->\n <button class=\"tw-w-6 tw-h-6 tw-rounded-full tw-bg-gray-100 tw-flex tw-items-center tw-justify-center tw-text-gray-600 hover:tw-bg-gray-200 tw-transition-colors\">\n <cide-ele-icon class=\"tw-text-xs\">more_horiz</cide-ele-icon>\n </button>\n </div>\n \n <!-- Status Badge -->\n <div class=\"tw-flex-shrink-0\">\n @if (node.syen_isactive) {\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-bg-green-100 tw-text-green-800\">\n <div class=\"tw-w-1.5 tw-h-1.5 tw-bg-green-500 tw-rounded-full tw-mr-1\"></div>\n Active\n </div>\n } @else {\n <div class=\"tw-inline-flex tw-items-center tw-px-1.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-bg-red-100 tw-text-red-800\">\n <div class=\"tw-w-1.5 tw-h-1.5 tw-bg-red-500 tw-rounded-full tw-mr-1\"></div>\n Inactive\n </div>\n }\n </div>\n </div>\n </div>\n \n <!-- Children Entities (Recursive) -->\n @if (node.children && node.children.length > 0) {\n <!-- Flexible Connection Lines -->\n <div class=\"tw-relative tw-flex tw-flex-col tw-items-center tw-mt-4\">\n <!-- Connection dot -->\n <div class=\"tw-absolute tw-left-1/2 tw-transform tw--translate-x-1/2\" style=\"top: -8px;\">\n <div class=\"tw-w-2 tw-h-2 tw-bg-purple-600 tw-rounded-full tw-border tw-border-white\"></div>\n </div>\n \n <!-- Flexible SVG Lines -->\n <div class=\"tw-relative tw-w-full tw-flex tw-justify-center flexible-connection-lines\">\n @if (node.children && node.children.length === 1) {\n <!-- Single child - simple vertical line -->\n <svg class=\"tw-absolute tw-left-1/2\" style=\"transform: translateX(-50%); width: 2px; height: 40px; top: 0;\">\n <line x1=\"1\" y1=\"0\" x2=\"1\" y2=\"40\" stroke=\"#9333ea\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n }\n @else if (node.children && node.children.length > 1) {\n <!-- Multiple children - flexible design -->\n <svg class=\"tw-absolute tw-left-1/2\" style=\"transform: translateX(-50%); width: 100%; height: 40px; top: 0;\">\n <!-- Vertical line from parent -->\n <line x1=\"50%\" y1=\"0\" x2=\"50%\" y2=\"15\" stroke=\"#9333ea\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n \n <!-- Horizontal line spanning children -->\n <line x1=\"20%\" y1=\"15\" x2=\"80%\" y2=\"15\" stroke=\"#9333ea\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n \n <!-- Vertical lines to children -->\n @for (child of node.children; track child._id; let i = $index) {\n <line [attr.x1]=\"(20 + (60 * i) / (node.children.length - 1)) + '%'\" \n y1=\"15\" \n [attr.x2]=\"(20 + (60 * i) / (node.children.length - 1)) + '%'\" \n y2=\"35\" \n stroke=\"#9333ea\" \n stroke-width=\"2\" \n stroke-linecap=\"round\"/>\n <!-- Connection dot -->\n <circle [attr.cx]=\"(20 + (60 * i) / (node.children.length - 1)) + '%'\" cy=\"35\" r=\"2.5\" fill=\"#9333ea\" stroke=\"#fff\" stroke-width=\"1\"/>\n }\n </svg>\n }\n </div>\n \n <!-- Children Container - Flexible Layout -->\n <div class=\"tw-flex tw-flex-wrap tw-justify-center tw-gap-4 tw-w-full tw-max-w-6xl tw-px-4 children-container\">\n @for (child of node.children; track child._id) {\n <div class=\"tw-flex tw-flex-col tw-items-center tw-flex-shrink-0\">\n <!-- Child node -->\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\" [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"></ng-container>\n </div>\n }\n </div>\n </div>\n }\n </div>\n</ng-template>\n","/*\n * Public API Surface of cloud-ide-shared\n */\n\nexport * from './lib/cloud-ide-shared';\n\n// Guards\nexport * from './lib/guards/auth.guard';\n\n// Services\nexport * from './lib/services/auth.service.interface';\nexport * from './lib/services/shared-object-id.service';\n\n// Components\nexport * from './lib/components/org-structure/org-structure.component';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { InjectionToken, OnInit } from '@angular/core';
3
3
  import { CanActivateFn, Router } from '@angular/router';
4
+ import { Observable } from 'rxjs';
5
+ import { mongooseObjectIdCreateControllerResponse } from 'cloud-ide-element';
6
+ import { MEntity, entityControllerResponse, CoreSystemEntityListResponse } from 'cloud-ide-lms-model';
4
7
 
5
8
  declare class CloudIdeShared {
6
9
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<CloudIdeShared, never>;
@@ -22,32 +25,151 @@ interface IAppStateService {
22
25
  declare const AUTH_SERVICE_TOKEN: InjectionToken<IAuthService>;
23
26
  declare const APP_STATE_SERVICE_TOKEN: InjectionToken<IAppStateService>;
24
27
 
25
- interface OrgStructureNode {
26
- _id: string;
27
- syen_name: string;
28
- syen_entity_code: string;
29
- syen_entity_type_sygms: string;
30
- syen_isactive: boolean;
31
- children?: OrgStructureNode[];
32
- level: number;
33
- parentId?: string;
28
+ /**
29
+ * Shared Object ID Generation Service
30
+ *
31
+ * This service provides a consistent interface for generating Object IDs
32
+ * across all libraries. It internally uses the FileManagerService but
33
+ * provides a standardized API that can be used throughout the application.
34
+ *
35
+ * Benefits:
36
+ * - Consistent interface across all libraries
37
+ * - Centralized Object ID generation logic
38
+ * - Easy to maintain and update
39
+ * - Prevents confusion with different Object ID generation methods
40
+ */
41
+ declare class SharedObjectIdService {
42
+ private fileManagerService;
43
+ /**
44
+ * Generate a new Object ID
45
+ *
46
+ * This method internally uses the FileManagerService to generate
47
+ * a unique Object ID that can be used for any entity in the system.
48
+ *
49
+ * @returns Observable<mongooseObjectIdCreateControllerResponse> - The generated Object ID response
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * // Generate Object ID for a new user
54
+ * this.sharedObjectIdService.generateObjectId().subscribe({
55
+ * next: (response) => {
56
+ * if (response.success && response.data?.objectId) {
57
+ * const newUserId = response.data.objectId;
58
+ * // Use the Object ID for creating a new user
59
+ * }
60
+ * },
61
+ * error: (error) => {
62
+ * console.error('Failed to generate Object ID:', error);
63
+ * }
64
+ * });
65
+ * ```
66
+ */
67
+ generateObjectId(): Observable<mongooseObjectIdCreateControllerResponse>;
68
+ /**
69
+ * Generate Object ID as Promise
70
+ *
71
+ * Convenience method that converts the Observable to a Promise
72
+ * for easier use with async/await syntax.
73
+ *
74
+ * @returns Promise<string> - The generated Object ID string
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * // Generate Object ID using async/await
79
+ * try {
80
+ * const objectId = await this.sharedObjectIdService.generateObjectIdAsync();
81
+ * console.log('Generated Object ID:', objectId);
82
+ * } catch (error) {
83
+ * console.error('Failed to generate Object ID:', error);
84
+ * }
85
+ * ```
86
+ */
87
+ generateObjectIdAsync(): Promise<string>;
88
+ /**
89
+ * Generate multiple Object IDs at once
90
+ *
91
+ * Useful when you need multiple Object IDs for batch operations.
92
+ *
93
+ * @param count - Number of Object IDs to generate
94
+ * @returns Observable<string[]> - Array of generated Object IDs
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * // Generate 5 Object IDs for batch creation
99
+ * this.sharedObjectIdService.generateMultipleObjectIds(5).subscribe({
100
+ * next: (objectIds) => {
101
+ * console.log('Generated Object IDs:', objectIds);
102
+ * // Use the Object IDs for batch operations
103
+ * }
104
+ * });
105
+ * ```
106
+ */
107
+ generateMultipleObjectIds(count: number): Observable<string[]>;
108
+ /**
109
+ * Generate Object ID with validation
110
+ *
111
+ * Generates an Object ID and validates it before returning.
112
+ *
113
+ * @param validator - Optional validation function
114
+ * @returns Observable<string> - Validated Object ID
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * // Generate Object ID with custom validation
119
+ * const validator = (id: string) => id.length === 24; // MongoDB ObjectId length
120
+ * this.sharedObjectIdService.generateObjectIdWithValidation(validator).subscribe({
121
+ * next: (validatedId) => {
122
+ * console.log('Validated Object ID:', validatedId);
123
+ * }
124
+ * });
125
+ * ```
126
+ */
127
+ generateObjectIdWithValidation(validator?: (id: string) => boolean): Observable<string>;
128
+ /**
129
+ * Check if a string is a valid Object ID format
130
+ *
131
+ * @param id - String to validate
132
+ * @returns boolean - True if valid Object ID format
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * const isValid = this.sharedObjectIdService.isValidObjectId('507f1f77bcf86cd799439011');
137
+ * console.log('Is valid Object ID:', isValid); // true
138
+ * ```
139
+ */
140
+ isValidObjectId(id: string): boolean;
141
+ /**
142
+ * Get Object ID generation statistics
143
+ *
144
+ * Returns information about Object ID generation for monitoring purposes.
145
+ *
146
+ * @returns Object with statistics
147
+ */
148
+ getGenerationStats(): {
149
+ serviceName: string;
150
+ description: string;
151
+ internalService: string;
152
+ };
153
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SharedObjectIdService, never>;
154
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<SharedObjectIdService>;
34
155
  }
156
+
35
157
  interface IEntityService {
36
- getEntityList(params: any): any;
158
+ getEntityList(params: MEntity): Observable<entityControllerResponse>;
37
159
  }
38
160
  declare const ENTITY_SERVICE_TOKEN: InjectionToken<IEntityService>;
39
161
  declare class CideSharedOrgStructureComponent implements OnInit {
40
162
  allowSwitching: _angular_core.InputSignal<boolean>;
41
163
  showActions: _angular_core.InputSignal<boolean>;
42
164
  mode: _angular_core.InputSignal<"selection" | "view">;
43
- entityClick: _angular_core.OutputEmitterRef<OrgStructureNode>;
44
- entitySelect: _angular_core.OutputEmitterRef<OrgStructureNode>;
45
- entityView: _angular_core.OutputEmitterRef<OrgStructureNode>;
165
+ entityClick: _angular_core.OutputEmitterRef<CoreSystemEntityListResponse>;
166
+ entitySelect: _angular_core.OutputEmitterRef<CoreSystemEntityListResponse>;
167
+ entityView: _angular_core.OutputEmitterRef<CoreSystemEntityListResponse>;
46
168
  private entityService;
47
169
  router: Router;
48
170
  loading: _angular_core.WritableSignal<boolean>;
49
171
  error: _angular_core.WritableSignal<string | null>;
50
- orgStructure: _angular_core.WritableSignal<OrgStructureNode[]>;
172
+ orgStructure: _angular_core.WritableSignal<CoreSystemEntityListResponse[]>;
51
173
  ngOnInit(): void;
52
174
  /**
53
175
  * Load organization structure
@@ -81,5 +203,5 @@ declare class CideSharedOrgStructureComponent implements OnInit {
81
203
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<CideSharedOrgStructureComponent, "cide-shared-org-structure", never, { "allowSwitching": { "alias": "allowSwitching"; "required": false; "isSignal": true; }; "showActions": { "alias": "showActions"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; }, { "entityClick": "entityClick"; "entitySelect": "entitySelect"; "entityView": "entityView"; }, never, never, true, never>;
82
204
  }
83
205
 
84
- export { APP_STATE_SERVICE_TOKEN, AUTH_SERVICE_TOKEN, CideSharedOrgStructureComponent, CloudIdeShared, ENTITY_SERVICE_TOKEN, authGuard };
85
- export type { IAppStateService, IAuthService, IEntityService, OrgStructureNode };
206
+ export { APP_STATE_SERVICE_TOKEN, AUTH_SERVICE_TOKEN, CideSharedOrgStructureComponent, CloudIdeShared, ENTITY_SERVICE_TOKEN, SharedObjectIdService, authGuard };
207
+ export type { IAppStateService, IAuthService, IEntityService };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloud-ide-shared",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^20.1.0",
6
6
  "@angular/core": "^20.1.0",