From 230be1edb00fe107f39a4069d1fb9265e35f1d35 Mon Sep 17 00:00:00 2001 From: "kham.vilaythong" Date: Sun, 17 Aug 2025 10:20:04 +1000 Subject: [PATCH] before ugrade --- API/FamilyTreeAPI/Entities/TreeNode.cs | 4 +- .../Properties/launchSettings.json | 3 +- .../Repository/PersonRepository.cs | 39 +++++- .../Repository/PersonRepository.tree.cs | 1 + UI/angular.json | 3 + UI/package-lock.json | 121 +++++++++++++++++- UI/package.json | 5 +- UI/src/app/app.config.ts | 3 + UI/src/app/mythem.ts | 12 ++ UI/src/app/person/family.orga.html | 3 +- UI/src/app/person/family.orga.ts | 46 +++++-- UI/src/app/person/family.tree.html | 19 ++- UI/src/app/person/family.tree.ts | 65 ++-------- UI/src/app/person/familylist.html | 7 +- UI/src/app/person/familylist.ts | 18 +++ UI/src/app/shares/utils.ts | 1 + document_Install.docx | Bin 0 -> 6097 bytes document_table.docx | Bin 5586 -> 6518 bytes 18 files changed, 263 insertions(+), 87 deletions(-) create mode 100644 document_Install.docx diff --git a/API/FamilyTreeAPI/Entities/TreeNode.cs b/API/FamilyTreeAPI/Entities/TreeNode.cs index d7cb19a..531ba35 100644 --- a/API/FamilyTreeAPI/Entities/TreeNode.cs +++ b/API/FamilyTreeAPI/Entities/TreeNode.cs @@ -6,10 +6,12 @@ public class TreeNode public T? Data { get; set; } public List>? Children { get; set; } public string? Icon { get; set; } - public bool? Checked { get; set; } + public bool? Checked { get; set; } public bool? Leaf { get; set; } public bool? Expanded { get; set; } public string? Type { get; set; } + + public string StyleClass { get; set; } public string? Key { get; set; } public bool? Loading { get; set; } } \ No newline at end of file diff --git a/API/FamilyTreeAPI/Properties/launchSettings.json b/API/FamilyTreeAPI/Properties/launchSettings.json index 0e0cdd6..6118837 100644 --- a/API/FamilyTreeAPI/Properties/launchSettings.json +++ b/API/FamilyTreeAPI/Properties/launchSettings.json @@ -8,7 +8,8 @@ "ASPNETCORE_ENVIRONMENT": "Development" }, "dotnetRunMessages": true, - "applicationUrl": "http://localhost:5015" + "applicationUrl": "http://localhost:5015", + "applicationUrl1": "http://192.168.8.188:5015" }, "IIS Express": { "commandName": "IISExpress", diff --git a/API/FamilyTreeAPI/Repository/PersonRepository.cs b/API/FamilyTreeAPI/Repository/PersonRepository.cs index 42f46ba..336946d 100644 --- a/API/FamilyTreeAPI/Repository/PersonRepository.cs +++ b/API/FamilyTreeAPI/Repository/PersonRepository.cs @@ -214,6 +214,27 @@ public partial class PersonRepository : IPerson Person rval = await _context.Persons.FindAsync(id); return rval; } + + private string getStyleClass(string va) + { + string result = ""; + //result = "bg-indigo-500 text-black"; + + if (va == "T") + { + result = "bg-indigo-500 text-white"; + } + else if (va == "P") + { + //result = "bg-purple-500 text-black"; + result = "bg-purple-500 text-black"; + } + else if (va == "C") + { + result = "bg-teal-500 text-white"; + } + return result; + } public async Task>> GetByFamilyAsync(int id) { int statuscode = 0; @@ -241,6 +262,8 @@ public partial class PersonRepository : IPerson node.Label = item.FirstName; node.Key = item.Id.ToString(); node.Type = type; + node.Icon = "T"; + node.StyleClass = getStyleClass(node.Icon); node.Expanded = true; node.Data = item.Sex; statuscode = 1; @@ -300,13 +323,13 @@ public partial class PersonRepository : IPerson { if (data == "M") { - fatherId = relate.PersonId; - motherId = relate.RelatePersonId; + fatherId = relate.RelatePersonId; + motherId = relate.PersonId; } else { - fatherId = relate.RelatePersonId; - motherId = relate.PersonId; + fatherId = relate.PersonId; + motherId = relate.RelatePersonId; } } //get children @@ -321,7 +344,7 @@ public partial class PersonRepository : IPerson pe = await GetPerson(motherId); pName = pe.FirstName; key = motherId.ToString(); - data = "F"; + data = pe.Sex; } } else @@ -331,12 +354,14 @@ public partial class PersonRepository : IPerson pe = await GetPerson(fatherId); pName = pe.FirstName; key = fatherId.ToString(); - data = "M"; + data = pe.Sex; } } citem = new TreeNode(); citem.Label = pName; + citem.Icon = "P"; + citem.StyleClass = getStyleClass(citem.Icon); citem.Expanded = true; citem.Data = data; citem.Type = type; @@ -349,6 +374,8 @@ public partial class PersonRepository : IPerson child = new TreeNode(); child.Expanded = true; child.Type = type; + child.Icon = "C"; + child.StyleClass = getStyleClass(child.Icon); child.Label = dto.FirstName; child.Key = dto.Id.ToString(); child.Data = dto.Sex; diff --git a/API/FamilyTreeAPI/Repository/PersonRepository.tree.cs b/API/FamilyTreeAPI/Repository/PersonRepository.tree.cs index ef4e879..64afaff 100644 --- a/API/FamilyTreeAPI/Repository/PersonRepository.tree.cs +++ b/API/FamilyTreeAPI/Repository/PersonRepository.tree.cs @@ -12,6 +12,7 @@ public partial class PersonRepository treeNode.Label = model.FirstName; treeNode.Data = model.Id.ToString(); treeNode.Key = model.Id.ToString(); + treeNode.Expanded = false; treeNode.Children = new(); return treeNode; } diff --git a/UI/angular.json b/UI/angular.json index 969baf6..88a0fad 100644 --- a/UI/angular.json +++ b/UI/angular.json @@ -13,6 +13,9 @@ "build": { "builder": "@angular/build:application", "options": { + "allowedCommonJsDependencies": [ + "moment", "file-saver", "xlsx" + ], "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ diff --git a/UI/package-lock.json b/UI/package-lock.json index 37cbeba..538fb26 100644 --- a/UI/package-lock.json +++ b/UI/package-lock.json @@ -16,6 +16,7 @@ "@angular/router": "^20.1.0", "@primeuix/themes": "^1.2.1", "@tailwindcss/postcss": "^4.1.11", + "file-saver": "^2.0.5", "moment": "^2.30.1", "postcss": "^8.5.6", "primeicons": "^7.0.0", @@ -23,12 +24,14 @@ "rxjs": "~7.8.0", "tailwindcss": "^4.1.11", "tailwindcss-primeui": "^0.6.1", - "tslib": "^2.3.0" + "tslib": "^2.3.0", + "xlsx": "^0.18.5" }, "devDependencies": { "@angular/build": "^20.1.1", "@angular/cli": "^20.1.1", "@angular/compiler-cli": "^20.1.0", + "@types/file-saver": "^2.0.7", "@types/jasmine": "~5.1.0", "jasmine-core": "~5.8.0", "karma": "~6.4.0", @@ -3864,6 +3867,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/file-saver": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz", + "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/jasmine": { "version": "5.1.8", "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.8.tgz", @@ -3925,6 +3935,15 @@ "node": ">= 0.6" } }, + "node_modules/adler-32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", + "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -4400,6 +4419,19 @@ ], "license": "CC-BY-4.0" }, + "node_modules/cfb": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", + "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", + "license": "Apache-2.0", + "dependencies": { + "adler-32": "~1.3.0", + "crc-32": "~1.2.0" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/chalk": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", @@ -4535,6 +4567,15 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/codepage": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", + "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4718,6 +4759,18 @@ "node": ">= 0.10" } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -5417,6 +5470,12 @@ } } }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==", + "license": "MIT" + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -5503,6 +5562,15 @@ "node": ">= 0.6" } }, + "node_modules/frac": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", + "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, "node_modules/fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", @@ -9232,6 +9300,18 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/ssf": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", + "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", + "license": "Apache-2.0", + "dependencies": { + "frac": "~1.1.2" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/ssri": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", @@ -9959,6 +10039,24 @@ "node": ">= 8" } }, + "node_modules/wmf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", + "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/word": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", + "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8" + } + }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -10164,6 +10262,27 @@ } } }, + "node_modules/xlsx": { + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", + "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", + "license": "Apache-2.0", + "dependencies": { + "adler-32": "~1.3.0", + "cfb": "~1.2.1", + "codepage": "~1.15.0", + "crc-32": "~1.2.1", + "ssf": "~0.11.2", + "wmf": "~1.0.1", + "word": "~0.3.0" + }, + "bin": { + "xlsx": "bin/xlsx.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/UI/package.json b/UI/package.json index 7d027e1..24e9881 100644 --- a/UI/package.json +++ b/UI/package.json @@ -28,6 +28,7 @@ "@angular/router": "^20.1.0", "@primeuix/themes": "^1.2.1", "@tailwindcss/postcss": "^4.1.11", + "file-saver": "^2.0.5", "moment": "^2.30.1", "postcss": "^8.5.6", "primeicons": "^7.0.0", @@ -35,12 +36,14 @@ "rxjs": "~7.8.0", "tailwindcss": "^4.1.11", "tailwindcss-primeui": "^0.6.1", - "tslib": "^2.3.0" + "tslib": "^2.3.0", + "xlsx": "^0.18.5" }, "devDependencies": { "@angular/build": "^20.1.1", "@angular/cli": "^20.1.1", "@angular/compiler-cli": "^20.1.0", + "@types/file-saver": "^2.0.7", "@types/jasmine": "~5.1.0", "jasmine-core": "~5.8.0", "karma": "~6.4.0", diff --git a/UI/src/app/app.config.ts b/UI/src/app/app.config.ts index 091094c..7a8fbcc 100644 --- a/UI/src/app/app.config.ts +++ b/UI/src/app/app.config.ts @@ -30,3 +30,6 @@ export const appConfig: ApplicationConfig = { provideRouter(routes) ] }; +/* +ng build --base-href "/FamilyTreeUI/" -c production +*/ \ No newline at end of file diff --git a/UI/src/app/mythem.ts b/UI/src/app/mythem.ts index 3728d2a..884d922 100644 --- a/UI/src/app/mythem.ts +++ b/UI/src/app/mythem.ts @@ -3,10 +3,22 @@ //mypreset.ts import { definePreset } from '@primeuix/themes'; import Aura from '@primeuix/themes/aura'; +import { primitive } from '@primeuix/themes/aura/base'; const MyPreset = definePreset(Aura, { semantic: { colorScheme: { + primitive: { + cyan: { + 50: '{cyan.50}', + 100: '{cyan.100}', + 200: '{cyan.200}', + 300: '{cyan.300}', + 400: '{cyan.400}', + 500: '{cyan.500}', + } + + }, primary: { 50: '{zinc.50}', 100: '{zinc.100}', diff --git a/UI/src/app/person/family.orga.html b/UI/src/app/person/family.orga.html index 7b1c112..5bd8736 100644 --- a/UI/src/app/person/family.orga.html +++ b/UI/src/app/person/family.orga.html @@ -3,7 +3,8 @@
- + +
diff --git a/UI/src/app/person/family.orga.ts b/UI/src/app/person/family.orga.ts index 6389976..9cdd606 100644 --- a/UI/src/app/person/family.orga.ts +++ b/UI/src/app/person/family.orga.ts @@ -59,43 +59,67 @@ export class FamilyOrga implements OnInit, OnDestroy{ if (item != undefined) this.person = item; this.loadPersonFamilyTree(id); - // this. populateTree(); + //this.populateTree(); } populateTree() : void { - const tree = [ - { - label: 'F.C Barcelona', + const data: TreeNode[] = [ + { expanded: true, + type: 'person', + styleClass: 'bg-indigo-500 text-white', + data: { + image: 'https://primefaces.org/cdn/primeng/images/demo/avatar/amyelsner.png', + name: 'Amy Elsner', + title: 'CEO' + }, children: [ { - label: 'Argentina', expanded: true, + type: 'person', + styleClass: 'bg-purple-500 text-white', + data: { + image: 'https://primefaces.org/cdn/primeng/images/demo/avatar/annafali.png', + name: 'Anna Fali', + title: 'CMO' + }, children: [ { - label: 'Argentina' + label: 'Sales', + styleClass: 'bg-purple-500 text-white', + style: ' border-radius: 12px' }, { - label: 'France' + label: 'Marketing', + styleClass: 'bg-purple-500 text-white', + style: ' border-radius: 12px' } ] }, { - label: 'France', expanded: true, + type: 'person', + styleClass: 'bg-teal-500 text-white', + data: { + image: 'https://primefaces.org/cdn/primeng/images/demo/avatar/stephenshaw.png', + name: 'Stephen Shaw', + title: 'CTO' + }, children: [ { - label: 'France' + label: 'Development', + styleClass: 'bg-teal-500 text-white' }, { - label: 'Morocco' + label: 'UI/UX Design', + styleClass: 'bg-teal-500 text-white' } ] } ] } ]; - this.familyTree.set(tree); + this.familyTree.set(data); } loadPersonFamilyTree(id: number): void { const relationShip$ = this.personService.loadPersonFamily(id); diff --git a/UI/src/app/person/family.tree.html b/UI/src/app/person/family.tree.html index 15449ee..905b0be 100644 --- a/UI/src/app/person/family.tree.html +++ b/UI/src/app/person/family.tree.html @@ -2,18 +2,15 @@

Family Tree by Person has Father

-
-
- - -
+
+
+ + +
- - -
+ +
diff --git a/UI/src/app/person/family.tree.ts b/UI/src/app/person/family.tree.ts index bc27239..1d5bdcf 100644 --- a/UI/src/app/person/family.tree.ts +++ b/UI/src/app/person/family.tree.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, OnDestroy, inject, ChangeDetectorRef} from '@angular/core'; +import { Component, OnInit, OnDestroy, inject, ChangeDetectorRef, signal} from '@angular/core'; import { StaffView ,StaffSearch, Person } from '../models'; import { OrganizationChartModule } from 'primeng/organizationchart'; @@ -17,18 +17,22 @@ import { InputTextModule } from 'primeng/inputtext'; import { DialogService } from 'primeng/dynamicdialog'; import { PersonEdit } from './person.edit'; import { MessageService } from 'primeng/api'; +import { CheckboxModule } from 'primeng/checkbox'; import { TreeModule, TreeNodeDoubleClickEvent, TreeNodeSelectEvent } from 'primeng/tree'; import { Utils } from '../shares'; @Component({ selector: 'family-tree', templateUrl: './family.tree.html', - imports:[TableModule,FormsModule,TreeModule, OrganizationChartModule,CommonModule,ButtonModule,InputTextModule], + imports:[TableModule,FormsModule,TreeModule,CheckboxModule, + OrganizationChartModule,CommonModule, + FormsModule, + ButtonModule,InputTextModule], styleUrls: ['./family.tree.css'], providers: [DialogService] }) export class FamilyTree implements OnInit, OnDestroy{ - + isFather = signal(true); private subscription:Subscription = new Subscription(); firstname = ''; selectedNode!: TreeNode; @@ -73,25 +77,8 @@ export class FamilyTree implements OnInit, OnDestroy{ this.authenticationService.isReport = false; const prev = this.personService.searchCriteria; let goload = true; - if (prev.lastName !== '') - { - this.lastname = prev.lastName; - goload = true; - } - if (prev.firstName !== '') - { - this.firstname = prev.firstName; - goload = true; - } - if (prev.email !== '') - { - this.email = prev.email; - goload = true; - } - if (goload) - { - this.search(); - } + this.load(); + } getActive(active:boolean):string { let result = 'false-icon pi-times-circle'; @@ -99,15 +86,13 @@ export class FamilyTree implements OnInit, OnDestroy{ result = 'true-icon pi-check-circle'; return result; } - search():void { - const canSearch = true; // this.canSearch(); - if (canSearch) - { + load():void { + let father = this.isFather(); this.loading = true; //const criteria = this.getSearchCiteria(); // this.personService.searchCriteria = criteria; this.subscription.add( - this.personService.loadPersonFamilyTree(true, false).subscribe( + this.personService.loadPersonFamilyTree(father, !father).subscribe( { next: x => { if (x.statusCode == 1) @@ -126,31 +111,7 @@ export class FamilyTree implements OnInit, OnDestroy{ console.log("error ", e); } }) - ); - - /* - this.personService.searchPersons(criteria).subscribe( { - next: result => { - // console.log(this.msg + "search load Data", result); - this.familyList = result.data; - this.familyTree = Utils.populateNode( "fatherId", this.familyList); - this.loading = false; - this.cd.detectChanges(); - } - }, - - error: e => { - const message = e || e.message; - // this.toastr.error(message); - this.loading = false; - console.log("error ", e); - } - }) - ); - */ - - - } + ); } nodeSelect(event: TreeNodeSelectEvent) { diff --git a/UI/src/app/person/familylist.html b/UI/src/app/person/familylist.html index e81839a..024e19a 100644 --- a/UI/src/app/person/familylist.html +++ b/UI/src/app/person/familylist.html @@ -21,20 +21,23 @@
- +
-
+ diff --git a/UI/src/app/person/familylist.ts b/UI/src/app/person/familylist.ts index edc2923..007309d 100644 --- a/UI/src/app/person/familylist.ts +++ b/UI/src/app/person/familylist.ts @@ -20,6 +20,10 @@ import { IconFieldModule } from 'primeng/iconfield'; import { InputIconModule } from 'primeng/inputicon'; import { Menu, MenuModule } from 'primeng/menu'; import { FamilyOrga } from './family.orga'; + +import { saveAs } from 'file-saver'; +import * as XLSX from 'xlsx'; + @Component({ selector: 'family-list', templateUrl: './familylist.html', @@ -88,6 +92,20 @@ export class FamilyList implements OnInit, OnDestroy{ ]; } + exportExport() : void { + this.ExcelExport(this.familyList(), 'family_export'); + } + + ExcelExport(data: any, fileName:string) :void + { + const worksheet = XLSX.utils.json_to_sheet(data); + const workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); + const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); + const blob = new Blob([excelBuffer], { type: 'application/octet-stream' }); + saveAs(blob, `${fileName}.xlsx`); + } + actionClick(id: number, event:Event): void { // console.log("action edit "+ id); this.selectId = id; diff --git a/UI/src/app/shares/utils.ts b/UI/src/app/shares/utils.ts index 0ebe03f..047e628 100644 --- a/UI/src/app/shares/utils.ts +++ b/UI/src/app/shares/utils.ts @@ -166,6 +166,7 @@ static formatNode(item:Person): TreeNode let tree_node_child: TreeNode[]; let node:TreeNode; let item: Person; + const children = childressNodes.filter(x => x[proName] == pid); for (let c = 0; c < children.length; c++) { diff --git a/document_Install.docx b/document_Install.docx new file mode 100644 index 0000000000000000000000000000000000000000..3c1fc81409e4e816ea318711361f64522fa804c6 GIT binary patch literal 6097 zcma)A1yoe+)}}#nXa%HGx@$5QR6x2*8M>tr>5%U3E=dI>Kk&|YLq6|+ zUH_gnXU$o2_Iu8Gp1q!T??*)e5s3f}4Gj%W+6bTrcP}uYzm1&CZJpWKV8^n!1$jhH zK}zJZ9f#e;J#MtG*~}L4KzGWQ^u}{xEVKjZ(z8*q z&}@wdEXF@%JnC`ER1PmDcqKYgd&fR=i%I-AB#?$bI+$q)*T5jIm%QrPkAXKzX@a@? z3e<{(D?o5;=H2`?!%+5EJkGoyoQeV}T4EmYhdn3&GYD|d^Zx}AF7yfz*i6LFBQluaaeJ1zTlH%AiF9YY zJ%J^2o5!#$Nxw#T-Sm_2$~C>h)CU=oLQWIAX*#H`VT2n-rATBUYh*LVI_)f-nUD|k zGA>mtm!KlIPkUJCQIJ5AT;3EUr1!N%E_UUjyQvuFtOu&?8ee3U_JVNZE9@4sBE5_D z->=qx-*6TyW(UzEN7Jgsh7b$N+l6F9uDnk#GzVvEg|DT>9o=2X zwVcdkzB64!$MyoF(K6{0x`=5aQGCs@yvJ^v-wxgs;~&lQHAXA1x}{hlu+?>Fa^&`W z9eF+20uQ5U`IL*u5*`k2@sBhC?$c!A-~eMOQ?*?QkqXd!Lzo^p!&Y%il8?iIFr)2;eknQLeTOGLlNPDZM@h|98l&^&UJ1yy^?bpZ0S$Gh$A^Rtq zopnh0u6YddU#vdUPJOr6UqcbfG4JaeJ?!yveHUu1A>o*b=XZQrz4(-1_DFEmhL~sF z@pGTxrh6Ht8XXIOH{FS=4bk3C?PfhsGV)6>b~Os-C*%g4@p{z+h7pWs4v$hUQD8*a zsExKLK#7q4BN6!bi7<0@b^+V{!qVtAqfdkU zrVl=Xh0;c_fWSI$c6b#lS!bQNPS9mE(HII+DGu}+aB+& z0yb#n_;MLc;ZVqJ_7d_@K;dBN=o=FVT z1w5IC5Cv)&LH9eJqbkG+L%zd%ING@dFU*${MFm6lO&Dd*8ro3>c1g zak<5JP?Urb|AZqP!_bGoHt?Zh!CYnf>JDZoi>I3AwoL9mv$i6aB z{@NG37chBp(4#E^Xt@z>qG8a#yR(C1z!&cfSIlc4FY9o4Mo*g}1K`v%Q@0N|?wmLi z)2j2=ziGzHWp-09t5TK_O5E}V_ibsnzR`F;ryXDd_ARY}XA}dX8sBIyjBfbTjuGDG zs|!4RWDP2H=s0>-w`^N3x4VT;m4*~X*>i$rqN&2(tE9W4CiSr<(6hoj5F-5?iySQ> zH#bt?ql0c2Q4hloTpP9)IZ~4#TsiEo#3q+dfTTWRRfl{YJ&c z(6E$Ct89!Xs@OF{6{?R$HJJS@_F-So#b<>uOs{J?MmCOR2~*S8RAOB>hc9j0`SWQT zX|lrb(J$WQx=k`D27ly9c~&cfKW zZj9LWB8qZ>u*pSB((c9VODXxqcuG!mj~aLE0kXwpj2z?lahA&dBL3(}&G>Oay_ICS z-8}gTgiM`R%+VnkBpbmOyUnK~*e)yVoZK^OpR#Mi2m4T6X!bL64v_)($B|3TcYE7*CyFW~o2$8ZPw2O89_1fVD1XezEN1^yzbx=u8Kye?o7SW3ge50i%SzKU{tA0s}3p+L5D^sC0YuxyPo`vC8NW(7@ zRUm|2AgriG{nkcZtV|;e2lyi``;Xyrd(DqRA!bandu%oEA+-&4abEiKQXj|pI5oK) zuoo0?&$D;A5)zozYQLP5M$%en3X5D2KOayT*~yR?L$7zwS(ghh4geJZVkgaozF!ES4A7l_+#n@!9KmAkE1UNdV-o7(bwzrL^g$@5~&2>n@>&OjJ0W4 zFWxHIeFVT)XMKXHZgE!Qziu=CNZHx48$UPsWEhkN#vEAd=!_j&D;5yo?#`~y8QgEI zm6NdZ^hlSO8%@C4XYB~>koxFQZ$w(tuA)Gkl*Y58ok0I!FG2VTx<5gpN~T7~=S4Al zjG0c70Yc?7>$jRZtR47P;NYUs!pS+6ZVVlZS8IVyF^ysu#`XT!!^H-dcsfQit41iV ztsr)vgV(cuh$x3dC>H31YjUeQj9Aqmm#$jRad>Mzun9kkBwe#mnUA$w65m0}=q?iR zbr(NXsOl^1;;)2Y$Bh)TrlA}9g!qs4UE|KkJZ(hcn3xYW;7DgW_`WZAaGuToI_il# zt+ToL&RM~p6L!m(@G9$A39|JlUSa!tkBX_o(cmV)0l{qu*3?pMB5o&=QT1OZ?91_Z z68XpMeX;J%3*d>%MaWTu4Yv9#yXpg(0=I@b&t{9EhQGQeH%%;6Ky-J)pY_%a4B9UW z&v@cf_}yt2Ju_ASM?ownLl?7|K2w>@lLA-SGwt^L_Gini2ciIOF#uk2gbm zH8}J?RX*OoEB__f-bLNS)b{6qGZfoy-@$NHJ&M}LaGMN{P zR}jw4wd@B$wwf2PeS=uv)p~nVEu!Zm#O(HP)}we6q%Rwg>uYDJ*LU%KU{@7AN}N|) zS-Vf9N`LV9WsxmVil`yuz}W#zm*gZ4*_VpGA(rNlz`uHNCtln-aMfwI=( zS0Od?jgj>ha^=hWOa&QW*Y?p2%+nCc4=;ltVhP$N9Eu}Id~DTTCs&@#u82L?!&qHA z6|Wx~VVoN&h>CjLA;W|wq|3LJ9oilb{r}n@XLA=9D|?HdQj-@q1VtMVeC!+Edl460 z?2ijShPVe2kf=XaE8u>@LSN@UkX^~gC9>v1S4ns4&QMt&-l_%K$f&!DK@M2yY?Df2|$r+Yz@ z#5&pVNtxXHk#7Eu!3zjt5;;SrZ$vXhD1t(510}8OFcYU8-=a6nB=M_$LR5NK46*C_u68D0tS7m68Q}f3VrDx zClkVdSGtR(xt%%t&m$*H>6a1}!3(frzab1fDp~*dV4PBklLf<#vEpgn(xcS6DcLHj zqQjHpf?lQd50Fj{<6WOHSrH$p@VCvMen4nFrOl*@@JW`QGfE5%sP6(HD=qdb?2MJz zF6dR0DWf#H(5AIMFppV<>f72p8x z9ZW@lSmA^H7+MCo+8tkqku`(kpPwp=q!>Lk((2e;Fb zur@b_ur9Y)!CGh-wFwwG&Kjsc+knS$d@FK$*}sB)8B*YVU9aWGw|ceoxOGtuqd55# z*N;SMb`4Qo7J`$*A7ybJ2+I2l7(Vh6m*pJGFHhUXXV2qMsBd#4!J<3l9sfE+?r^@Ub!ob-snX@9@1;mEpSl zF2C+)UdL&Bb<1>XQpx^IVR@elh^(G`tbH^0L-@wGQW}?ZSmDW;^Lt3Q&d7W$3VY>J zhIm5J76m0i{jF9$;9E5fE6K89Civ8w5qNicOlR}bg;%V51RZj&uM-?B(=Ouu()&yO z1yjs>m)L9wrSx-r_QB$|wRjM=| z$K7C&*Xt+5Z`KV(6b5qG*!1bNaYU-lmpH53h;-BvtrROX_H(K83HmXWwO*zgyMD)_ z)Hq;ycfq{Oa;A_5XZ_A$Q3+jkdoV;MpCh29OUcr0+wWSo<7)%=^oA}O=mxd*HStuD z6pe#Khsm=VQF6d}FGHGriVXhvI+tM0Z8PC#)CQyUhPvEsjP-HTgUE;8$s_DUv%t zZOOKMlKGv@O)ipjY{7o3Q~wk{1Q=O{X}8n1P&H6OfsqA|Kmhm4{Jih^!OYLU$2}|b z_r&`y6l{e36*SOW{g*-bd-{Fv1ZGwJihgKW{U`lj#?|lH_ZJ%uMYh8Cg1vcb4CmxL=xo eCsGM|`hRGLiUKkeRya5e=%)=@DK`YLvwr|!o-RrN literal 0 HcmV?d00001 diff --git a/document_table.docx b/document_table.docx index f20660516e222000417e2ed76cfb6cca50a691fb..59feaf86af79ed8174ac6ccc2521d274fd2b268a 100644 GIT binary patch delta 5047 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 TuQO7RVv%CCU1rImxk~XrBSP4F delta 4134 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