cloud-ide-shared 1.0.74 → 1.0.78

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.
@@ -725,9 +725,49 @@ class CideSharedOrgStructureComponent {
725
725
  loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
726
726
  error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
727
727
  orgStructure = signal([], ...(ngDevMode ? [{ debugName: "orgStructure" }] : []));
728
+ /** Set of node IDs that are expanded (children visible). Default: all expanded. */
729
+ expandedIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedIds" }] : []));
728
730
  ngOnInit() {
729
731
  this.loadOrgStructure();
730
732
  }
733
+ /** Collect all node IDs from tree (for expand all / collapse all). */
734
+ getAllNodeIds(nodes) {
735
+ const ids = new Set();
736
+ const visit = (list) => {
737
+ list.forEach(n => {
738
+ if (n._id)
739
+ ids.add(n._id);
740
+ if (n.children?.length)
741
+ visit(n.children);
742
+ });
743
+ };
744
+ visit(nodes);
745
+ return ids;
746
+ }
747
+ isExpanded(nodeId) {
748
+ if (!nodeId)
749
+ return false;
750
+ return this.expandedIds().has(nodeId);
751
+ }
752
+ toggleExpand(nodeId) {
753
+ if (!nodeId)
754
+ return;
755
+ const next = new Set(this.expandedIds());
756
+ if (next.has(nodeId))
757
+ next.delete(nodeId);
758
+ else
759
+ next.add(nodeId);
760
+ this.expandedIds.set(next);
761
+ }
762
+ expandAll() {
763
+ this.expandedIds.set(this.getAllNodeIds(this.orgStructure()));
764
+ }
765
+ collapseAll() {
766
+ this.expandedIds.set(new Set());
767
+ }
768
+ hasChildren(node) {
769
+ return !!(node.children && node.children.length > 0);
770
+ }
731
771
  /**
732
772
  * Load organization structure
733
773
  */
@@ -742,6 +782,7 @@ class CideSharedOrgStructureComponent {
742
782
  console.log('Built organization structure:', structure);
743
783
  console.log('Root nodes count:', structure.length);
744
784
  this.orgStructure.set(structure);
785
+ this.expandedIds.set(this.getAllNodeIds(structure));
745
786
  }
746
787
  else {
747
788
  this.error.set('Failed to load organization structure');
@@ -997,7 +1038,7 @@ class CideSharedOrgStructureComponent {
997
1038
  });
998
1039
  }
999
1040
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CideSharedOrgStructureComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1000
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", 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-auto !tw-h-full\">\n @if (loading()) {\n <div class=\"tw-flex tw-items-center !tw-h-full 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\n 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\n 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-h-full tw-bg-gray-50 tw-py-8 org-chart-container\">\n <!-- Chart Content with Background Pattern -->\n <div class=\"tw-relative tw-z-10 tw-min-w-max tw-px-4 org-chart-content org-chart-content-with-bg\">\n <div class=\"tree\">\n @for (rootNode of orgStructure(); track rootNode._id) {\n <!-- Root nodes don't need top lines, but using wrapper is fine as they are not inside .tree-children -->\n <div class=\"tree-node-wrapper tw-mb-12\">\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: rootNode, level: 0 }\"></ng-container>\n </div>\n }\n </div>\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=\"tree-node-content\">\n\n <!-- Entity Card -->\n <div class=\"tw-bg-white tw-shadow-lg tw-rounded-lg tw-p-4 entity-card tw-border-t-4 tw-cursor-pointer\"\n [class.level-0]=\"level === 0\" [class.level-1]=\"level === 1\" [class.level-2]=\"level === 2\"\n [class.level-3]=\"level === 3\" [class.level-4]=\"level === 4\" [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\n 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\n class=\"tw-text-sm tw-font-semibold tw-text-gray-900 tw-whitespace-nowrap tw-overflow-hidden tw-text-ellipsis\"\n [cideEleTooltip]=\"node.syen_name || ''\" [tooltipPlacement]=\"'top'\" [tooltipType]=\"'default'\">{{\n 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 <!-- Icons (unchanged) -->\n <button\n 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 <button\n 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 <button\n 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 <button\n 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 <button\n 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\n 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\n 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 <!-- Connector line extending downwards from parent -->\n @if (node.children && node.children.length > 0) {\n <div class=\"min-h-connector\"></div>\n }\n </div>\n\n <!-- Recursive Children Container -->\n @if (node.children && node.children.length > 0) {\n <div class=\"tree-children\">\n @for (child of node.children; track child._id) {\n <div class=\"tree-node-wrapper\">\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"></ng-container>\n </div>\n }\n </div>\n }\n</ng-template>", styles: [".org-chart-container{overflow:auto;height:100%;position:relative;padding-top:2rem}.org-chart-content{min-width:max-content;min-height:max-content;padding:0 1rem 4rem;margin:0 auto;display:block}.org-chart-content-with-bg{position:relative}.org-chart-content-with-bg:before{content:\"\";position:absolute;inset:0;opacity:.3;pointer-events:none;background-image:radial-gradient(circle,#e5e7eb 1px,transparent 1px);background-size:20px 20px;background-repeat:repeat;z-index:-1}.tree{display:flex;flex-direction:column;align-items:center}.tree-children{display:flex;flex-direction:row;justify-content:center;position:relative}.tree-node-wrapper{display:flex;flex-direction:column;align-items:center;position:relative;padding:20px 1rem 0}.tree-node-wrapper:before{content:\"\";position:absolute;top:0;left:50%;border-left:2px solid #9333ea;width:0;height:20px;z-index:1}.tree-node-wrapper:after{content:\"\";position:absolute;top:0;right:50%;border-top:2px solid #9333ea;width:50%;height:20px;z-index:0}.tree-children>.tree-node-wrapper:before{height:20px}.tree-children>.tree-node-wrapper:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:20px;border-top:2px solid #9333ea;border-left:0;right:auto}.tree-children>.tree-node-wrapper:first-child:after{left:50%;width:50%;border-top:2px solid #9333ea}.tree-children>.tree-node-wrapper:last-child:after{left:0;width:50%;border-top:2px solid #9333ea}.tree-children>.tree-node-wrapper:only-child:after{display:none}.tree-children>.tree-node-wrapper:only-child:before{height:20px}.tree-node-content{position:relative;z-index:2;margin-bottom:0}.min-h-connector{height:20px;width:2px;background-color:#9333ea;margin:0 auto}.entity-card{width:18rem;transition:all .2s ease-in-out;flex-shrink:0}.entity-card:hover{transform:translateY(-2px) scale(1.02);box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a}.connection-dot{width:6px;height:6px;background-color:#9333ea;border-radius:50%;position:absolute;top:-3px;left:50%;transform:translate(-50%);z-index:5}@media (max-width: 1400px){.entity-card{width:16rem}}@media (max-width: 1200px){.entity-card{width:14rem}}@media (max-width: 992px){.entity-card{width:13rem}}.level-0{border-top-color:#3b82f6!important}.level-1{border-top-color:#f59e0b!important}.level-2{border-top-color:#10b981!important}.level-3{border-top-color:#8b5cf6!important}.level-4{border-top-color:#ef4444!important}.level-5{border-top-color:#06b6d4!important}.org-chart-container::-webkit-scrollbar{height:8px;width:8px}.org-chart-container::-webkit-scrollbar-track{background:#f1f5f9}.org-chart-container::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:4px}.org-chart-container::-webkit-scrollbar-thumb:hover{background:#94a3b8}\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], cide-ele-button", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated", "adaptive"], 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"] }, { kind: "directive", type: TooltipDirective, selector: "[cideEleTooltip]", inputs: ["cideEleTooltip", "tooltipColor", "tooltipBg", "tooltipPlacement", "tooltipType", "tooltipDelay", "tooltipDir", "tooltipShowArrow", "tooltipMultiline", "tooltipMaxWidth", "tooltipInteractive", "tooltipClass"] }] });
1041
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", 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=\"org-structure tw-flex tw-flex-col tw-h-full tw-overflow-hidden\">\n @if (loading()) {\n <div class=\"org-structure__loading tw-flex tw-items-center tw-justify-center tw-flex-1 tw-py-16\">\n <div class=\"tw-flex tw-flex-col tw-items-center tw-gap-4\">\n <cide-ele-spinner size=\"lg\"></cide-ele-spinner>\n <span class=\"tw-text-sm tw-text-slate-500 tw-font-medium\">Loading organization structure\u2026</span>\n </div>\n </div>\n } @else if (error()) {\n <div class=\"org-structure__error tw-flex tw-items-center tw-justify-center tw-flex-1 tw-py-16\">\n <div class=\"org-structure__error-card tw-text-center tw-max-w-md tw-px-6\">\n <div class=\"org-structure__error-icon tw-w-14 tw-h-14 tw-rounded-2xl tw-bg-red-100 tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\n <cide-ele-icon class=\"tw-w-7 tw-h-7 tw-text-red-600\">error</cide-ele-icon>\n </div>\n <h3 class=\"tw-text-lg tw-font-semibold tw-text-slate-900 tw-mb-2\">Error loading structure</h3>\n <p class=\"tw-text-slate-600 tw-mb-6\">{{ error() }}</p>\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"loadOrgStructure()\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-2\">refresh</cide-ele-icon>\n Try again\n </button>\n </div>\n </div>\n } @else if (orgStructure().length === 0) {\n <div class=\"org-structure__empty tw-flex tw-items-center tw-justify-center tw-flex-1 tw-py-16\">\n <div class=\"tw-text-center tw-max-w-md tw-px-6\">\n <div class=\"tw-w-16 tw-h-16 tw-rounded-2xl tw-bg-slate-100 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-slate-400\">account_tree</cide-ele-icon>\n </div>\n <h3 class=\"tw-text-lg tw-font-semibold tw-text-slate-900 tw-mb-2\">No entities found</h3>\n <p class=\"tw-text-slate-600 tw-mb-6\">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 class=\"tw-w-4 tw-h-4 tw-mr-2\">add</cide-ele-icon>\n Create first entity\n </button>\n }\n </div>\n </div>\n } @else {\n <!-- Toolbar: title + Expand all / Collapse all -->\n <div class=\"org-structure__toolbar\">\n <div class=\"org-structure__toolbar-inner\">\n <h2 class=\"org-structure__title\">\n <cide-ele-icon class=\"tw-w-5 tw-h-5 tw-mr-2 tw-text-indigo-500\">account_tree</cide-ele-icon>\n Organization structure\n </h2>\n <div class=\"org-structure__actions\">\n <button type=\"button\" class=\"org-structure__btn\" (click)=\"expandAll()\"\n cideEleTooltip=\"Expand all\" tooltipPlacement=\"bottom\" tooltipType=\"default\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4\">unfold_more</cide-ele-icon>\n <span class=\"tw-ml-1.5 tw-hidden sm:tw-inline\">Expand all</span>\n </button>\n <button type=\"button\" class=\"org-structure__btn\" (click)=\"collapseAll()\"\n cideEleTooltip=\"Collapse all\" tooltipPlacement=\"bottom\" tooltipType=\"default\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4\">unfold_less</cide-ele-icon>\n <span class=\"tw-ml-1.5 tw-hidden sm:tw-inline\">Collapse all</span>\n </button>\n </div>\n </div>\n </div>\n\n <!-- Chart area -->\n <div class=\"org-structure__chart\">\n <div class=\"org-structure__chart-inner\">\n <div class=\"org-tree\">\n @for (rootNode of orgStructure(); track rootNode._id) {\n <div class=\"org-tree__branch\">\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: rootNode, level: 0 }\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n }\n</div>\n\n<!-- Entity node (recursive) -->\n<ng-template #entityNodeTemplate let-node let-level=\"level\">\n <div class=\"org-node\">\n <div class=\"org-node__card\"\n [class.org-node__card--root]=\"level === 0\"\n [class.org-node__card--level-1]=\"level === 1\"\n [class.org-node__card--level-2]=\"level === 2\"\n [class.org-node__card--level-3]=\"level >= 3\"\n (click)=\"viewEntity(node._id)\">\n <div class=\"org-node__main\">\n @if (hasChildren(node)) {\n <button type=\"button\" class=\"org-node__expand\"\n (click)=\"toggleExpand(node._id); $event.stopPropagation()\"\n [attr.aria-expanded]=\"isExpanded(node._id)\"\n cideEleTooltip=\"{{ isExpanded(node._id) ? 'Collapse' : 'Expand' }}\" tooltipPlacement=\"top\" tooltipType=\"default\">\n <cide-ele-icon class=\"org-node__expand-icon\" [class.org-node__expand-icon--open]=\"isExpanded(node._id)\">expand_more</cide-ele-icon>\n </button>\n } @else {\n <span class=\"org-node__expand-placeholder\"></span>\n }\n <div class=\"org-node__avatar\">\n <span class=\"org-node__avatar-text\">{{ (node.syen_name || '?').substring(0, 2).toUpperCase() }}</span>\n </div>\n <div class=\"org-node__info\">\n <h3 class=\"org-node__name\" [cideEleTooltip]=\"node.syen_name || ''\" tooltipPlacement=\"top\" tooltipType=\"default\">\n {{ node.syen_name }}\n </h3>\n <p class=\"org-node__meta\">{{ node.syen_entity_code }}</p>\n @if (node.entity_type_details?.sygms_title) {\n <p class=\"org-node__type\">{{ node.entity_type_details.sygms_title }}</p>\n } @else if (node.syen_entity_type_sygms) {\n <p class=\"org-node__type\">{{ node.syen_entity_type_sygms }}</p>\n }\n </div>\n <div class=\"org-node__badge\">\n @if (node.syen_isactive) {\n <span class=\"org-node__status org-node__status--active\">Active</span>\n } @else {\n <span class=\"org-node__status org-node__status--inactive\">Inactive</span>\n }\n </div>\n </div>\n @if (showActions()) {\n <div class=\"org-node__actions\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"org-node__action\" cideEleTooltip=\"Phone\" tooltipPlacement=\"top\" tooltipType=\"default\">\n <cide-ele-icon class=\"tw-w-3.5 tw-h-3.5\">phone</cide-ele-icon>\n </button>\n <button type=\"button\" class=\"org-node__action\" cideEleTooltip=\"Email\" tooltipPlacement=\"top\" tooltipType=\"default\">\n <cide-ele-icon class=\"tw-w-3.5 tw-h-3.5\">email</cide-ele-icon>\n </button>\n <button type=\"button\" class=\"org-node__action\" cideEleTooltip=\"More\" tooltipPlacement=\"top\" tooltipType=\"default\">\n <cide-ele-icon class=\"tw-w-3.5 tw-h-3.5\">more_horiz</cide-ele-icon>\n </button>\n </div>\n }\n </div>\n\n @if (node.children && node.children.length > 0 && isExpanded(node._id)) {\n <div class=\"org-node__connector\"></div>\n }\n </div>\n\n @if (node.children && node.children.length > 0 && isExpanded(node._id)) {\n <div class=\"org-tree__children\">\n @for (child of node.children; track child._id) {\n <div class=\"org-tree__branch\">\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"></ng-container>\n </div>\n }\n </div>\n }\n</ng-template>\n", styles: ["@charset \"UTF-8\";.org-structure{background:#f8fafc}.org-structure__toolbar{flex-shrink:0;background:#fff;border-bottom:1px solid #e2e8f0;padding:.75rem 1.25rem;position:sticky;top:0;z-index:10}.org-structure__toolbar-inner{display:flex;align-items:center;justify-content:space-between;gap:1rem;max-width:100%}.org-structure__title{display:flex;align-items:center;margin:0;font-size:1.125rem;font-weight:600;color:#0f172a;letter-spacing:-.01em}.org-structure__actions{display:flex;align-items:center;gap:.5rem}.org-structure__btn{display:inline-flex;align-items:center;padding:.5rem .75rem;font-size:.8125rem;font-weight:500;color:#475569;background:#f1f5f9;border:none;border-radius:8px;cursor:pointer;transition:color .15s,background .15s,box-shadow .15s}.org-structure__btn:hover{color:#6366f1;background:#eef2ff}.org-structure__btn:active{background:#e0e7ff}.org-structure__chart{flex:1;overflow:auto;padding:1.5rem 1rem 3rem}.org-structure__chart-inner{min-width:max-content;min-height:max-content;position:relative}.org-tree{display:flex;flex-direction:column;align-items:center}.org-tree__branch{display:flex;flex-direction:column;align-items:center;position:relative;padding-top:0}.org-tree__children{display:flex;flex-direction:row;justify-content:center;align-items:flex-start;position:relative;padding-top:0;gap:0 1.5rem}.org-node__connector{width:2px;height:20px;background:#6366f1;margin:0 auto;flex-shrink:0}.org-tree__children>.org-tree__branch{position:relative;padding-top:20px}.org-tree__children>.org-tree__branch:before{content:\"\";position:absolute;top:0;left:50%;width:0;height:20px;border-left:2px solid #6366f1;z-index:0}.org-tree__children>.org-tree__branch:after{content:\"\";position:absolute;top:0;left:0;right:0;height:20px;border-top:2px solid #6366f1;z-index:0}.org-tree__children>.org-tree__branch:first-child:after{left:50%;width:50%}.org-tree__children>.org-tree__branch:last-child:after{left:0;width:50%}.org-tree__children>.org-tree__branch:only-child:after{display:none}.org-tree__children>.org-tree__branch:only-child:before{height:20px}.org-node{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;margin-bottom:0}.org-node__card{width:100%;min-width:280px;max-width:320px;background:#fff;border-radius:12px;box-shadow:0 1px 3px #0000000f;border:1px solid #e2e8f0;padding:.875rem 1rem;cursor:pointer;transition:box-shadow .2s ease,transform .2s ease,border-color .2s ease}.org-node__card:hover{box-shadow:0 10px 40px -10px #6366f133,0 4px 12px -4px #00000014;border-color:#6366f140}.org-node__card:active{transform:scale(.995)}.org-node__card--root{border-left:3px solid #6366f1}.org-node__card--level-1{border-left:3px solid #8b5cf6}.org-node__card--level-2{border-left:3px solid #06b6d4}.org-node__card--level-3{border-left:3px solid #10b981}.org-node__main{display:flex;align-items:center;gap:.75rem}.org-node__expand{flex-shrink:0;width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;margin:-4px 0;background:#f1f5f9;border:none;border-radius:6px;cursor:pointer;color:#64748b;transition:background .15s,color .15s,transform .2s ease}.org-node__expand:hover{background:#e0e7ff;color:#6366f1}.org-node__expand-icon{transition:transform .25s ease;font-size:1.25rem}.org-node__expand-icon--open{transform:rotate(0)}.org-node__expand:not([aria-expanded=true]) .org-node__expand-icon{transform:rotate(-90deg)}.org-node__expand-placeholder{width:28px;flex-shrink:0;display:inline-block}.org-node__avatar{width:40px;height:40px;flex-shrink:0;border-radius:10px;background:linear-gradient(135deg,#6366f1,#8b5cf6);display:flex;align-items:center;justify-content:center}.org-node__avatar-text{font-size:.75rem;font-weight:700;color:#fff;letter-spacing:.02em}.org-node__info{flex:1;min-width:0}.org-node__name{margin:0;font-size:.9375rem;font-weight:600;color:#0f172a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.3}.org-node__meta{margin:.125rem 0 0;font-size:.75rem;color:#64748b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.org-node__type{margin:.125rem 0 0;font-size:.6875rem;color:#94a3b8;text-transform:uppercase;letter-spacing:.04em}.org-node__badge{flex-shrink:0}.org-node__status{display:inline-flex;align-items:center;padding:.25rem .5rem;font-size:.6875rem;font-weight:600;border-radius:6px;text-transform:uppercase;letter-spacing:.03em}.org-node__status--active{background:#dcfce7;color:#166534}.org-node__status--inactive{background:#fee2e2;color:#991b1b}.org-node__actions{display:flex;align-items:center;gap:.25rem;margin-top:.75rem;padding-top:.75rem;border-top:1px solid #f1f5f9}.org-node__action{width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;border-radius:6px;color:#94a3b8;cursor:pointer;transition:background .15s,color .15s}.org-node__action:hover{background:#f1f5f9;color:#6366f1}.org-structure__loading,.org-structure__error,.org-structure__empty{background:#f8fafc}.org-structure__error-icon{box-shadow:0 4px 12px #ef444426}.org-structure__chart::-webkit-scrollbar{width:8px;height:8px}.org-structure__chart::-webkit-scrollbar-track{background:#f1f5f9;border-radius:4px}.org-structure__chart::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:4px}.org-structure__chart::-webkit-scrollbar-thumb:hover{background:#94a3b8}@media (max-width: 640px){.org-node__card{min-width:260px;max-width:100%}}\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], cide-ele-button", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated", "adaptive"], outputs: ["btnClick", "doubleClick"] }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip", "active", "name"] }, { kind: "component", type: CideSpinnerComponent, selector: "cide-ele-spinner", inputs: ["size", "type"] }, { kind: "directive", type: TooltipDirective, selector: "[cideEleTooltip]", inputs: ["cideEleTooltip", "tooltipColor", "tooltipBg", "tooltipPlacement", "tooltipType", "tooltipDelay", "tooltipDir", "tooltipShowArrow", "tooltipMultiline", "tooltipMaxWidth", "tooltipInteractive", "tooltipClass"] }] });
1001
1042
  }
1002
1043
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CideSharedOrgStructureComponent, decorators: [{
1003
1044
  type: Component,
@@ -1007,7 +1048,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
1007
1048
  CideIconComponent,
1008
1049
  CideSpinnerComponent,
1009
1050
  TooltipDirective
1010
- ], template: "<!-- Organization Structure Component -->\n<div class=\"tw-flex-1 tw-overflow-auto !tw-h-full\">\n @if (loading()) {\n <div class=\"tw-flex tw-items-center !tw-h-full 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\n 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\n 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-h-full tw-bg-gray-50 tw-py-8 org-chart-container\">\n <!-- Chart Content with Background Pattern -->\n <div class=\"tw-relative tw-z-10 tw-min-w-max tw-px-4 org-chart-content org-chart-content-with-bg\">\n <div class=\"tree\">\n @for (rootNode of orgStructure(); track rootNode._id) {\n <!-- Root nodes don't need top lines, but using wrapper is fine as they are not inside .tree-children -->\n <div class=\"tree-node-wrapper tw-mb-12\">\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: rootNode, level: 0 }\"></ng-container>\n </div>\n }\n </div>\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=\"tree-node-content\">\n\n <!-- Entity Card -->\n <div class=\"tw-bg-white tw-shadow-lg tw-rounded-lg tw-p-4 entity-card tw-border-t-4 tw-cursor-pointer\"\n [class.level-0]=\"level === 0\" [class.level-1]=\"level === 1\" [class.level-2]=\"level === 2\"\n [class.level-3]=\"level === 3\" [class.level-4]=\"level === 4\" [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\n 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\n class=\"tw-text-sm tw-font-semibold tw-text-gray-900 tw-whitespace-nowrap tw-overflow-hidden tw-text-ellipsis\"\n [cideEleTooltip]=\"node.syen_name || ''\" [tooltipPlacement]=\"'top'\" [tooltipType]=\"'default'\">{{\n 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 <!-- Icons (unchanged) -->\n <button\n 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 <button\n 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 <button\n 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 <button\n 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 <button\n 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\n 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\n 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 <!-- Connector line extending downwards from parent -->\n @if (node.children && node.children.length > 0) {\n <div class=\"min-h-connector\"></div>\n }\n </div>\n\n <!-- Recursive Children Container -->\n @if (node.children && node.children.length > 0) {\n <div class=\"tree-children\">\n @for (child of node.children; track child._id) {\n <div class=\"tree-node-wrapper\">\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"></ng-container>\n </div>\n }\n </div>\n }\n</ng-template>", styles: [".org-chart-container{overflow:auto;height:100%;position:relative;padding-top:2rem}.org-chart-content{min-width:max-content;min-height:max-content;padding:0 1rem 4rem;margin:0 auto;display:block}.org-chart-content-with-bg{position:relative}.org-chart-content-with-bg:before{content:\"\";position:absolute;inset:0;opacity:.3;pointer-events:none;background-image:radial-gradient(circle,#e5e7eb 1px,transparent 1px);background-size:20px 20px;background-repeat:repeat;z-index:-1}.tree{display:flex;flex-direction:column;align-items:center}.tree-children{display:flex;flex-direction:row;justify-content:center;position:relative}.tree-node-wrapper{display:flex;flex-direction:column;align-items:center;position:relative;padding:20px 1rem 0}.tree-node-wrapper:before{content:\"\";position:absolute;top:0;left:50%;border-left:2px solid #9333ea;width:0;height:20px;z-index:1}.tree-node-wrapper:after{content:\"\";position:absolute;top:0;right:50%;border-top:2px solid #9333ea;width:50%;height:20px;z-index:0}.tree-children>.tree-node-wrapper:before{height:20px}.tree-children>.tree-node-wrapper:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:20px;border-top:2px solid #9333ea;border-left:0;right:auto}.tree-children>.tree-node-wrapper:first-child:after{left:50%;width:50%;border-top:2px solid #9333ea}.tree-children>.tree-node-wrapper:last-child:after{left:0;width:50%;border-top:2px solid #9333ea}.tree-children>.tree-node-wrapper:only-child:after{display:none}.tree-children>.tree-node-wrapper:only-child:before{height:20px}.tree-node-content{position:relative;z-index:2;margin-bottom:0}.min-h-connector{height:20px;width:2px;background-color:#9333ea;margin:0 auto}.entity-card{width:18rem;transition:all .2s ease-in-out;flex-shrink:0}.entity-card:hover{transform:translateY(-2px) scale(1.02);box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a}.connection-dot{width:6px;height:6px;background-color:#9333ea;border-radius:50%;position:absolute;top:-3px;left:50%;transform:translate(-50%);z-index:5}@media (max-width: 1400px){.entity-card{width:16rem}}@media (max-width: 1200px){.entity-card{width:14rem}}@media (max-width: 992px){.entity-card{width:13rem}}.level-0{border-top-color:#3b82f6!important}.level-1{border-top-color:#f59e0b!important}.level-2{border-top-color:#10b981!important}.level-3{border-top-color:#8b5cf6!important}.level-4{border-top-color:#ef4444!important}.level-5{border-top-color:#06b6d4!important}.org-chart-container::-webkit-scrollbar{height:8px;width:8px}.org-chart-container::-webkit-scrollbar-track{background:#f1f5f9}.org-chart-container::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:4px}.org-chart-container::-webkit-scrollbar-thumb:hover{background:#94a3b8}\n"] }]
1051
+ ], template: "<!-- Organization Structure Component -->\n<div class=\"org-structure tw-flex tw-flex-col tw-h-full tw-overflow-hidden\">\n @if (loading()) {\n <div class=\"org-structure__loading tw-flex tw-items-center tw-justify-center tw-flex-1 tw-py-16\">\n <div class=\"tw-flex tw-flex-col tw-items-center tw-gap-4\">\n <cide-ele-spinner size=\"lg\"></cide-ele-spinner>\n <span class=\"tw-text-sm tw-text-slate-500 tw-font-medium\">Loading organization structure\u2026</span>\n </div>\n </div>\n } @else if (error()) {\n <div class=\"org-structure__error tw-flex tw-items-center tw-justify-center tw-flex-1 tw-py-16\">\n <div class=\"org-structure__error-card tw-text-center tw-max-w-md tw-px-6\">\n <div class=\"org-structure__error-icon tw-w-14 tw-h-14 tw-rounded-2xl tw-bg-red-100 tw-flex tw-items-center tw-justify-center tw-mx-auto tw-mb-4\">\n <cide-ele-icon class=\"tw-w-7 tw-h-7 tw-text-red-600\">error</cide-ele-icon>\n </div>\n <h3 class=\"tw-text-lg tw-font-semibold tw-text-slate-900 tw-mb-2\">Error loading structure</h3>\n <p class=\"tw-text-slate-600 tw-mb-6\">{{ error() }}</p>\n <button cideEleButton variant=\"primary\" size=\"sm\" (click)=\"loadOrgStructure()\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4 tw-mr-2\">refresh</cide-ele-icon>\n Try again\n </button>\n </div>\n </div>\n } @else if (orgStructure().length === 0) {\n <div class=\"org-structure__empty tw-flex tw-items-center tw-justify-center tw-flex-1 tw-py-16\">\n <div class=\"tw-text-center tw-max-w-md tw-px-6\">\n <div class=\"tw-w-16 tw-h-16 tw-rounded-2xl tw-bg-slate-100 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-slate-400\">account_tree</cide-ele-icon>\n </div>\n <h3 class=\"tw-text-lg tw-font-semibold tw-text-slate-900 tw-mb-2\">No entities found</h3>\n <p class=\"tw-text-slate-600 tw-mb-6\">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 class=\"tw-w-4 tw-h-4 tw-mr-2\">add</cide-ele-icon>\n Create first entity\n </button>\n }\n </div>\n </div>\n } @else {\n <!-- Toolbar: title + Expand all / Collapse all -->\n <div class=\"org-structure__toolbar\">\n <div class=\"org-structure__toolbar-inner\">\n <h2 class=\"org-structure__title\">\n <cide-ele-icon class=\"tw-w-5 tw-h-5 tw-mr-2 tw-text-indigo-500\">account_tree</cide-ele-icon>\n Organization structure\n </h2>\n <div class=\"org-structure__actions\">\n <button type=\"button\" class=\"org-structure__btn\" (click)=\"expandAll()\"\n cideEleTooltip=\"Expand all\" tooltipPlacement=\"bottom\" tooltipType=\"default\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4\">unfold_more</cide-ele-icon>\n <span class=\"tw-ml-1.5 tw-hidden sm:tw-inline\">Expand all</span>\n </button>\n <button type=\"button\" class=\"org-structure__btn\" (click)=\"collapseAll()\"\n cideEleTooltip=\"Collapse all\" tooltipPlacement=\"bottom\" tooltipType=\"default\">\n <cide-ele-icon class=\"tw-w-4 tw-h-4\">unfold_less</cide-ele-icon>\n <span class=\"tw-ml-1.5 tw-hidden sm:tw-inline\">Collapse all</span>\n </button>\n </div>\n </div>\n </div>\n\n <!-- Chart area -->\n <div class=\"org-structure__chart\">\n <div class=\"org-structure__chart-inner\">\n <div class=\"org-tree\">\n @for (rootNode of orgStructure(); track rootNode._id) {\n <div class=\"org-tree__branch\">\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: rootNode, level: 0 }\"></ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n }\n</div>\n\n<!-- Entity node (recursive) -->\n<ng-template #entityNodeTemplate let-node let-level=\"level\">\n <div class=\"org-node\">\n <div class=\"org-node__card\"\n [class.org-node__card--root]=\"level === 0\"\n [class.org-node__card--level-1]=\"level === 1\"\n [class.org-node__card--level-2]=\"level === 2\"\n [class.org-node__card--level-3]=\"level >= 3\"\n (click)=\"viewEntity(node._id)\">\n <div class=\"org-node__main\">\n @if (hasChildren(node)) {\n <button type=\"button\" class=\"org-node__expand\"\n (click)=\"toggleExpand(node._id); $event.stopPropagation()\"\n [attr.aria-expanded]=\"isExpanded(node._id)\"\n cideEleTooltip=\"{{ isExpanded(node._id) ? 'Collapse' : 'Expand' }}\" tooltipPlacement=\"top\" tooltipType=\"default\">\n <cide-ele-icon class=\"org-node__expand-icon\" [class.org-node__expand-icon--open]=\"isExpanded(node._id)\">expand_more</cide-ele-icon>\n </button>\n } @else {\n <span class=\"org-node__expand-placeholder\"></span>\n }\n <div class=\"org-node__avatar\">\n <span class=\"org-node__avatar-text\">{{ (node.syen_name || '?').substring(0, 2).toUpperCase() }}</span>\n </div>\n <div class=\"org-node__info\">\n <h3 class=\"org-node__name\" [cideEleTooltip]=\"node.syen_name || ''\" tooltipPlacement=\"top\" tooltipType=\"default\">\n {{ node.syen_name }}\n </h3>\n <p class=\"org-node__meta\">{{ node.syen_entity_code }}</p>\n @if (node.entity_type_details?.sygms_title) {\n <p class=\"org-node__type\">{{ node.entity_type_details.sygms_title }}</p>\n } @else if (node.syen_entity_type_sygms) {\n <p class=\"org-node__type\">{{ node.syen_entity_type_sygms }}</p>\n }\n </div>\n <div class=\"org-node__badge\">\n @if (node.syen_isactive) {\n <span class=\"org-node__status org-node__status--active\">Active</span>\n } @else {\n <span class=\"org-node__status org-node__status--inactive\">Inactive</span>\n }\n </div>\n </div>\n @if (showActions()) {\n <div class=\"org-node__actions\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"org-node__action\" cideEleTooltip=\"Phone\" tooltipPlacement=\"top\" tooltipType=\"default\">\n <cide-ele-icon class=\"tw-w-3.5 tw-h-3.5\">phone</cide-ele-icon>\n </button>\n <button type=\"button\" class=\"org-node__action\" cideEleTooltip=\"Email\" tooltipPlacement=\"top\" tooltipType=\"default\">\n <cide-ele-icon class=\"tw-w-3.5 tw-h-3.5\">email</cide-ele-icon>\n </button>\n <button type=\"button\" class=\"org-node__action\" cideEleTooltip=\"More\" tooltipPlacement=\"top\" tooltipType=\"default\">\n <cide-ele-icon class=\"tw-w-3.5 tw-h-3.5\">more_horiz</cide-ele-icon>\n </button>\n </div>\n }\n </div>\n\n @if (node.children && node.children.length > 0 && isExpanded(node._id)) {\n <div class=\"org-node__connector\"></div>\n }\n </div>\n\n @if (node.children && node.children.length > 0 && isExpanded(node._id)) {\n <div class=\"org-tree__children\">\n @for (child of node.children; track child._id) {\n <div class=\"org-tree__branch\">\n <ng-container [ngTemplateOutlet]=\"entityNodeTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: child, level: level + 1 }\"></ng-container>\n </div>\n }\n </div>\n }\n</ng-template>\n", styles: ["@charset \"UTF-8\";.org-structure{background:#f8fafc}.org-structure__toolbar{flex-shrink:0;background:#fff;border-bottom:1px solid #e2e8f0;padding:.75rem 1.25rem;position:sticky;top:0;z-index:10}.org-structure__toolbar-inner{display:flex;align-items:center;justify-content:space-between;gap:1rem;max-width:100%}.org-structure__title{display:flex;align-items:center;margin:0;font-size:1.125rem;font-weight:600;color:#0f172a;letter-spacing:-.01em}.org-structure__actions{display:flex;align-items:center;gap:.5rem}.org-structure__btn{display:inline-flex;align-items:center;padding:.5rem .75rem;font-size:.8125rem;font-weight:500;color:#475569;background:#f1f5f9;border:none;border-radius:8px;cursor:pointer;transition:color .15s,background .15s,box-shadow .15s}.org-structure__btn:hover{color:#6366f1;background:#eef2ff}.org-structure__btn:active{background:#e0e7ff}.org-structure__chart{flex:1;overflow:auto;padding:1.5rem 1rem 3rem}.org-structure__chart-inner{min-width:max-content;min-height:max-content;position:relative}.org-tree{display:flex;flex-direction:column;align-items:center}.org-tree__branch{display:flex;flex-direction:column;align-items:center;position:relative;padding-top:0}.org-tree__children{display:flex;flex-direction:row;justify-content:center;align-items:flex-start;position:relative;padding-top:0;gap:0 1.5rem}.org-node__connector{width:2px;height:20px;background:#6366f1;margin:0 auto;flex-shrink:0}.org-tree__children>.org-tree__branch{position:relative;padding-top:20px}.org-tree__children>.org-tree__branch:before{content:\"\";position:absolute;top:0;left:50%;width:0;height:20px;border-left:2px solid #6366f1;z-index:0}.org-tree__children>.org-tree__branch:after{content:\"\";position:absolute;top:0;left:0;right:0;height:20px;border-top:2px solid #6366f1;z-index:0}.org-tree__children>.org-tree__branch:first-child:after{left:50%;width:50%}.org-tree__children>.org-tree__branch:last-child:after{left:0;width:50%}.org-tree__children>.org-tree__branch:only-child:after{display:none}.org-tree__children>.org-tree__branch:only-child:before{height:20px}.org-node{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;margin-bottom:0}.org-node__card{width:100%;min-width:280px;max-width:320px;background:#fff;border-radius:12px;box-shadow:0 1px 3px #0000000f;border:1px solid #e2e8f0;padding:.875rem 1rem;cursor:pointer;transition:box-shadow .2s ease,transform .2s ease,border-color .2s ease}.org-node__card:hover{box-shadow:0 10px 40px -10px #6366f133,0 4px 12px -4px #00000014;border-color:#6366f140}.org-node__card:active{transform:scale(.995)}.org-node__card--root{border-left:3px solid #6366f1}.org-node__card--level-1{border-left:3px solid #8b5cf6}.org-node__card--level-2{border-left:3px solid #06b6d4}.org-node__card--level-3{border-left:3px solid #10b981}.org-node__main{display:flex;align-items:center;gap:.75rem}.org-node__expand{flex-shrink:0;width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;margin:-4px 0;background:#f1f5f9;border:none;border-radius:6px;cursor:pointer;color:#64748b;transition:background .15s,color .15s,transform .2s ease}.org-node__expand:hover{background:#e0e7ff;color:#6366f1}.org-node__expand-icon{transition:transform .25s ease;font-size:1.25rem}.org-node__expand-icon--open{transform:rotate(0)}.org-node__expand:not([aria-expanded=true]) .org-node__expand-icon{transform:rotate(-90deg)}.org-node__expand-placeholder{width:28px;flex-shrink:0;display:inline-block}.org-node__avatar{width:40px;height:40px;flex-shrink:0;border-radius:10px;background:linear-gradient(135deg,#6366f1,#8b5cf6);display:flex;align-items:center;justify-content:center}.org-node__avatar-text{font-size:.75rem;font-weight:700;color:#fff;letter-spacing:.02em}.org-node__info{flex:1;min-width:0}.org-node__name{margin:0;font-size:.9375rem;font-weight:600;color:#0f172a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.3}.org-node__meta{margin:.125rem 0 0;font-size:.75rem;color:#64748b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.org-node__type{margin:.125rem 0 0;font-size:.6875rem;color:#94a3b8;text-transform:uppercase;letter-spacing:.04em}.org-node__badge{flex-shrink:0}.org-node__status{display:inline-flex;align-items:center;padding:.25rem .5rem;font-size:.6875rem;font-weight:600;border-radius:6px;text-transform:uppercase;letter-spacing:.03em}.org-node__status--active{background:#dcfce7;color:#166534}.org-node__status--inactive{background:#fee2e2;color:#991b1b}.org-node__actions{display:flex;align-items:center;gap:.25rem;margin-top:.75rem;padding-top:.75rem;border-top:1px solid #f1f5f9}.org-node__action{width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;background:transparent;border:none;border-radius:6px;color:#94a3b8;cursor:pointer;transition:background .15s,color .15s}.org-node__action:hover{background:#f1f5f9;color:#6366f1}.org-structure__loading,.org-structure__error,.org-structure__empty{background:#f8fafc}.org-structure__error-icon{box-shadow:0 4px 12px #ef444426}.org-structure__chart::-webkit-scrollbar{width:8px;height:8px}.org-structure__chart::-webkit-scrollbar-track{background:#f1f5f9;border-radius:4px}.org-structure__chart::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:4px}.org-structure__chart::-webkit-scrollbar-thumb:hover{background:#94a3b8}@media (max-width: 640px){.org-node__card{min-width:260px;max-width:100%}}\n"] }]
1011
1052
  }], propDecorators: { allowSwitching: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowSwitching", required: false }] }], showActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "showActions", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], entityClick: [{ type: i0.Output, args: ["entityClick"] }], entitySelect: [{ type: i0.Output, args: ["entitySelect"] }], entityView: [{ type: i0.Output, args: ["entityView"] }] } });
1012
1053
 
1013
1054
  class CideSharedProgramSectionSelectorComponent {
@@ -1500,13 +1541,39 @@ class CideSharedProgramSectionSelectorComponent {
1500
1541
  setTimeout(() => clearInterval(branchCheckInterval), 5000);
1501
1542
  }
1502
1543
  else {
1503
- // If no branch dropdown but term dropdown should be shown, load terms directly
1504
- if (this.showTermDropdown()) {
1544
+ // Extract config to check for one-to-one term relationship
1545
+ const selectedProgram = this.selectedClassProgram();
1546
+ const generalMaster = selectedProgram?.acacpm_class_program_id_sygms || selectedProgram?.acacpm_class_program_id_sygmt;
1547
+ let config;
1548
+ if (generalMaster && typeof generalMaster === 'object' && 'sygms_configuration' in generalMaster) {
1549
+ const configValue = generalMaster.sygms_configuration;
1550
+ if (typeof configValue === 'string') {
1551
+ try {
1552
+ config = JSON.parse(configValue);
1553
+ }
1554
+ catch { }
1555
+ }
1556
+ else if (typeof configValue === 'object' && configValue !== null) {
1557
+ config = configValue;
1558
+ }
1559
+ }
1560
+ // Check if one-to-one term (dropdown hidden but term exists)
1561
+ const isOneToOneTerm = config?.termType === true && config?.termLevelUpTo === 1 && config?.termProgramLevelOneConnected === true;
1562
+ // Load terms if dropdown shown OR one-to-one relationship
1563
+ if (this.showTermDropdown() || isOneToOneTerm) {
1564
+ console.log('📚 Loading terms - dropdown:', this.showTermDropdown(), 'oneToOne:', isOneToOneTerm);
1505
1565
  this.loadClassProgramTerms(classProgramId, undefined);
1506
- // After terms load, check if current term value is valid
1566
+ // After terms load, auto-select if one-to-one OR validate if dropdown shown
1507
1567
  const termCheckInterval = setInterval(() => {
1508
1568
  if (!this.classProgramTermsLoading()) {
1509
1569
  clearInterval(termCheckInterval);
1570
+ if (isOneToOneTerm && this.classProgramTerms().length > 0) {
1571
+ // One-to-one: Auto-select the first term
1572
+ const firstTerm = this.classProgramTerms()[0];
1573
+ console.log('🎯 Auto-selecting one-to-one term:', firstTerm);
1574
+ form.patchValue({ [this.termControlName()]: firstTerm.value }, { emitEvent: true });
1575
+ return; // Exit early, onTermChange will load sections
1576
+ }
1510
1577
  // Check if current term value exists in loaded terms
1511
1578
  const termExists = currentTermId &&
1512
1579
  this.classProgramTerms().some(t => t.value === currentTermId);
@@ -1676,6 +1743,7 @@ class CideSharedProgramSectionSelectorComponent {
1676
1743
  }
1677
1744
  }
1678
1745
  loadProgramTermSections(termId) {
1746
+ console.log('🔍 loadProgramTermSections called with termId:', termId);
1679
1747
  this.programTermSectionsLoading.set(true);
1680
1748
  const payload = new MPrgTrmSection({
1681
1749
  acapts_parent_class_prog_term_acapt: termId,
@@ -1695,12 +1763,16 @@ class CideSharedProgramSectionSelectorComponent {
1695
1763
  academicsRoutesUrl.programTermSection,
1696
1764
  query
1697
1765
  ]);
1766
+ console.log('📡 Fetching sections from URL:', url);
1767
+ console.log('📦 Payload:', payload);
1698
1768
  this.http.get(url)
1699
1769
  .pipe(takeUntilDestroyed(this.destroyRef))
1700
1770
  .subscribe({
1701
1771
  next: (response) => {
1772
+ console.log('✅ Section API response:', response);
1702
1773
  if (response?.success && response?.data) {
1703
1774
  const sections = Array.isArray(response.data) ? response.data : [];
1775
+ console.log(`📊 Found ${sections.length} sections:`, sections);
1704
1776
  const hasSections = sections.length > 0;
1705
1777
  this.hasSections.set(hasSections);
1706
1778
  if (hasSections) {
@@ -1708,6 +1780,7 @@ class CideSharedProgramSectionSelectorComponent {
1708
1780
  value: section._id || '',
1709
1781
  label: section.acapts_name || section.acapts_code || ''
1710
1782
  })));
1783
+ console.log('✅ Section dropdown will be shown. hasSections =', hasSections);
1711
1784
  const form = this.formGroup();
1712
1785
  const sectionControl = form?.get(this.sectionControlName());
1713
1786
  if (sectionControl) {
@@ -1716,6 +1789,7 @@ class CideSharedProgramSectionSelectorComponent {
1716
1789
  }
1717
1790
  }
1718
1791
  else {
1792
+ console.warn('⚠️ No sections found! Section dropdown will be hidden.');
1719
1793
  this.programTermSections.set([]);
1720
1794
  const form = this.formGroup();
1721
1795
  const sectionControl = form?.get(this.sectionControlName());