cloud-ide-shared 1.0.74 → 1.0.76
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.
- package/fesm2022/cloud-ide-shared.mjs +38 -5
- package/fesm2022/cloud-ide-shared.mjs.map +1 -1
- package/package.json +1 -1
- package/README.md +0 -63
|
@@ -997,7 +997,7 @@ class CideSharedOrgStructureComponent {
|
|
|
997
997
|
});
|
|
998
998
|
}
|
|
999
999
|
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"] }] });
|
|
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=\"xs\" (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=\"xs\" (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", "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
1001
|
}
|
|
1002
1002
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CideSharedOrgStructureComponent, decorators: [{
|
|
1003
1003
|
type: Component,
|
|
@@ -1007,7 +1007,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
1007
1007
|
CideIconComponent,
|
|
1008
1008
|
CideSpinnerComponent,
|
|
1009
1009
|
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=\"
|
|
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=\"xs\" (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=\"xs\" (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"] }]
|
|
1011
1011
|
}], 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
1012
|
|
|
1013
1013
|
class CideSharedProgramSectionSelectorComponent {
|
|
@@ -1500,13 +1500,39 @@ class CideSharedProgramSectionSelectorComponent {
|
|
|
1500
1500
|
setTimeout(() => clearInterval(branchCheckInterval), 5000);
|
|
1501
1501
|
}
|
|
1502
1502
|
else {
|
|
1503
|
-
//
|
|
1504
|
-
|
|
1503
|
+
// Extract config to check for one-to-one term relationship
|
|
1504
|
+
const selectedProgram = this.selectedClassProgram();
|
|
1505
|
+
const generalMaster = selectedProgram?.acacpm_class_program_id_sygms || selectedProgram?.acacpm_class_program_id_sygmt;
|
|
1506
|
+
let config;
|
|
1507
|
+
if (generalMaster && typeof generalMaster === 'object' && 'sygms_configuration' in generalMaster) {
|
|
1508
|
+
const configValue = generalMaster.sygms_configuration;
|
|
1509
|
+
if (typeof configValue === 'string') {
|
|
1510
|
+
try {
|
|
1511
|
+
config = JSON.parse(configValue);
|
|
1512
|
+
}
|
|
1513
|
+
catch { }
|
|
1514
|
+
}
|
|
1515
|
+
else if (typeof configValue === 'object' && configValue !== null) {
|
|
1516
|
+
config = configValue;
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
// Check if one-to-one term (dropdown hidden but term exists)
|
|
1520
|
+
const isOneToOneTerm = config?.termType === true && config?.termLevelUpTo === 1 && config?.termProgramLevelOneConnected === true;
|
|
1521
|
+
// Load terms if dropdown shown OR one-to-one relationship
|
|
1522
|
+
if (this.showTermDropdown() || isOneToOneTerm) {
|
|
1523
|
+
console.log('📚 Loading terms - dropdown:', this.showTermDropdown(), 'oneToOne:', isOneToOneTerm);
|
|
1505
1524
|
this.loadClassProgramTerms(classProgramId, undefined);
|
|
1506
|
-
// After terms load,
|
|
1525
|
+
// After terms load, auto-select if one-to-one OR validate if dropdown shown
|
|
1507
1526
|
const termCheckInterval = setInterval(() => {
|
|
1508
1527
|
if (!this.classProgramTermsLoading()) {
|
|
1509
1528
|
clearInterval(termCheckInterval);
|
|
1529
|
+
if (isOneToOneTerm && this.classProgramTerms().length > 0) {
|
|
1530
|
+
// One-to-one: Auto-select the first term
|
|
1531
|
+
const firstTerm = this.classProgramTerms()[0];
|
|
1532
|
+
console.log('🎯 Auto-selecting one-to-one term:', firstTerm);
|
|
1533
|
+
form.patchValue({ [this.termControlName()]: firstTerm.value }, { emitEvent: true });
|
|
1534
|
+
return; // Exit early, onTermChange will load sections
|
|
1535
|
+
}
|
|
1510
1536
|
// Check if current term value exists in loaded terms
|
|
1511
1537
|
const termExists = currentTermId &&
|
|
1512
1538
|
this.classProgramTerms().some(t => t.value === currentTermId);
|
|
@@ -1676,6 +1702,7 @@ class CideSharedProgramSectionSelectorComponent {
|
|
|
1676
1702
|
}
|
|
1677
1703
|
}
|
|
1678
1704
|
loadProgramTermSections(termId) {
|
|
1705
|
+
console.log('🔍 loadProgramTermSections called with termId:', termId);
|
|
1679
1706
|
this.programTermSectionsLoading.set(true);
|
|
1680
1707
|
const payload = new MPrgTrmSection({
|
|
1681
1708
|
acapts_parent_class_prog_term_acapt: termId,
|
|
@@ -1695,12 +1722,16 @@ class CideSharedProgramSectionSelectorComponent {
|
|
|
1695
1722
|
academicsRoutesUrl.programTermSection,
|
|
1696
1723
|
query
|
|
1697
1724
|
]);
|
|
1725
|
+
console.log('📡 Fetching sections from URL:', url);
|
|
1726
|
+
console.log('📦 Payload:', payload);
|
|
1698
1727
|
this.http.get(url)
|
|
1699
1728
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
1700
1729
|
.subscribe({
|
|
1701
1730
|
next: (response) => {
|
|
1731
|
+
console.log('✅ Section API response:', response);
|
|
1702
1732
|
if (response?.success && response?.data) {
|
|
1703
1733
|
const sections = Array.isArray(response.data) ? response.data : [];
|
|
1734
|
+
console.log(`📊 Found ${sections.length} sections:`, sections);
|
|
1704
1735
|
const hasSections = sections.length > 0;
|
|
1705
1736
|
this.hasSections.set(hasSections);
|
|
1706
1737
|
if (hasSections) {
|
|
@@ -1708,6 +1739,7 @@ class CideSharedProgramSectionSelectorComponent {
|
|
|
1708
1739
|
value: section._id || '',
|
|
1709
1740
|
label: section.acapts_name || section.acapts_code || ''
|
|
1710
1741
|
})));
|
|
1742
|
+
console.log('✅ Section dropdown will be shown. hasSections =', hasSections);
|
|
1711
1743
|
const form = this.formGroup();
|
|
1712
1744
|
const sectionControl = form?.get(this.sectionControlName());
|
|
1713
1745
|
if (sectionControl) {
|
|
@@ -1716,6 +1748,7 @@ class CideSharedProgramSectionSelectorComponent {
|
|
|
1716
1748
|
}
|
|
1717
1749
|
}
|
|
1718
1750
|
else {
|
|
1751
|
+
console.warn('⚠️ No sections found! Section dropdown will be hidden.');
|
|
1719
1752
|
this.programTermSections.set([]);
|
|
1720
1753
|
const form = this.formGroup();
|
|
1721
1754
|
const sectionControl = form?.get(this.sectionControlName());
|