diff --git a/shanoir-ng-front/src/app/studies/study/tree.service.ts b/shanoir-ng-front/src/app/studies/study/tree.service.ts index 516513b7c1..2b65187cb6 100644 --- a/shanoir-ng-front/src/app/studies/study/tree.service.ts +++ b/shanoir-ng-front/src/app/studies/study/tree.service.ts @@ -231,31 +231,36 @@ export class TreeService { } private selectNode(selection: Selection): Promise { + let node: Promise; if (selection?.type == 'dataset') { - return this.selectDataset(selection.entity as Dataset); + node = this.selectDataset(selection.entity as Dataset); } else if (selection?.type == 'dicomMetadata') { - return this.selectDicomMetadata(selection.entity as Dataset); + node = this.selectDicomMetadata(selection.entity as Dataset); } else if (selection?.type == 'subject') { - return this.selectSubject(selection.id); + node = this.selectSubject(selection.id); } else if (selection?.type == 'acquisition') { - return this.selectAcquisition(selection.entity as DatasetAcquisition); + node = this.selectAcquisition(selection.entity as DatasetAcquisition); } else if (selection?.type == 'processing') { - return this.selectProcessing(selection.entity as DatasetProcessing); + node = this.selectProcessing(selection.entity as DatasetProcessing); } else if (selection?.type == 'examination') { - return this.selectExamination(selection.entity as Examination); + node = this.selectExamination(selection.entity as Examination); } else if (selection?.type == 'center') { - return this.selectCenter(selection.id); + node = this.selectCenter(selection.id); } else if (selection?.type == 'equipment') { - return this.selectEquipment(selection.entity as AcquisitionEquipment); + node = this.selectEquipment(selection.entity as AcquisitionEquipment); } else if (selection?.type == 'qualitycard') { - return this.selectQualitycard(selection.id); + node = this.selectQualitycard(selection.id); } else if (selection?.type == 'studycard') { - return this.selectStudycard(selection.id); + node = this.selectStudycard(selection.id); } else if (selection?.type == 'user') { - return this.selectUser(selection.id); + node = this.selectUser(selection.id); } else if (selection?.type == 'coil') { - return this.selectCoil(selection.entity as Coil); - } else return Promise.resolve(null); + node = this.selectCoil(selection.entity as Coil); + } else node = Promise.resolve(null); + node.then(n => { + if(!!n) n.hidden = false; + }); + return node; } private selectDataset(dataset: number | Dataset): Promise { @@ -584,13 +589,23 @@ export class TreeService { members.sort((a: MemberNode, b: MemberNode) => { return a.label.toLowerCase().localeCompare(b.label.toLowerCase()) }) - studyNode.subjectsNode = new SubjectsNode(studyNode, null, 'Subjects', subjects); + studyNode.subjectsNode = new SubjectsNode(studyNode, null, 'Subjects', subjects.concat(this.generateSubs(100, studyNode.subjectsNode))); studyNode.centersNode = new CentersNode(studyNode, null, 'Centers', centers); studyNode.membersNode = new MembersNode(studyNode, null, 'Members', members); studyNode.membersNode.open(); return studyNode; } + generateSubs(times: number, parent: ShanoirNode): SubjectNode[] { + let res = []; + for (let i = 0; i < times; i++) { + let n: SubjectNode = new ClinicalSubjectNode(parent, 100000 + i, 'test ' + i, [], [], null, true, false); + (n.examinations as ExaminationNode[]).push(new ExaminationNode(n, 100000 + i, 'test', UNLOADED, UNLOADED, true, true, false)); + res.push(n); + } + return res; + } + unSelectAll() { this.unSelectNode(this.studyNode); } diff --git a/shanoir-ng-front/src/app/studies/tree/study-node.component.css b/shanoir-ng-front/src/app/studies/tree/study-node.component.css index bfb10adbc3..568bb1719c 100644 --- a/shanoir-ng-front/src/app/studies/tree/study-node.component.css +++ b/shanoir-ng-front/src/app/studies/tree/study-node.component.css @@ -1,3 +1,13 @@ .overmenu input { height: 16px; } .overmenu .filter { margin-left: 10px; } -.overmenu:has(input:focus) { visibility: visible; } \ No newline at end of file +.overmenu:has(input:focus) { visibility: visible; } + +.fake-node { margin-left: 22px; height: 24.5px; } +.fake-node a { all: unset; } +.fake-node i { margin-right: 6px; } +.fake-node .chevron { vertical-align: -5px; cursor: pointer; } +.fake-node .picto { color: var(--color-b); margin-right: 0px; } +.fake-node .inner { display: inline-block; vertical-align: -4px; cursor: pointer; margin-right: 16px; } +.fake-node .tag { border: 1px solid var(--grey); border-radius: 10px; padding: 0 5px; margin: 0 2px; font-size: 10px; display: inline-block; line-height: 18px; vertical-align: top; } +.fake-node .tag i { margin-right: 3px; } +.fake-node .dark { color:white } \ No newline at end of file diff --git a/shanoir-ng-front/src/app/studies/tree/study-node.component.html b/shanoir-ng-front/src/app/studies/tree/study-node.component.html index 8d9cf70f18..9356369e42 100644 --- a/shanoir-ng-front/src/app/studies/tree/study-node.component.html +++ b/shanoir-ng-front/src/app/studies/tree/study-node.component.html @@ -35,7 +35,6 @@ label="Subjects" awesome="fas fa-user-injured" [(opened)]="node.subjectsNode.opened" - (openedChange)="onOpenedChange($event)" (labelClick)="subjectsMenuOpened = !subjectsMenuOpened" [hasChildren]="hasDependency(node.subjectsNode.subjects)"> @@ -60,17 +59,30 @@ - - + + @if (!subject.hidden) { + + + } @else { +
+ + + + {{subject.label}} + + + {{tag.name}} + +
+ } +
diff --git a/shanoir-ng-front/src/app/studies/tree/study-node.component.ts b/shanoir-ng-front/src/app/studies/tree/study-node.component.ts index 2b6c871d3c..35032f6866 100644 --- a/shanoir-ng-front/src/app/studies/tree/study-node.component.ts +++ b/shanoir-ng-front/src/app/studies/tree/study-node.component.ts @@ -28,8 +28,10 @@ import { import { StudyRightsService } from "../shared/study-rights.service"; import { StudyUserRight } from '../shared/study-user-right.enum'; import { Study } from '../shared/study.model'; -import { TreeService } from '../study/tree.service'; +import { Selection, TreeService } from '../study/tree.service'; import { TreeNodeAbstractComponent } from 'src/app/shared/components/tree/tree-node.abstract.component'; +import { Entity } from 'src/app/shared/components/entity/entity.abstract'; +import { isDarkColor } from 'src/app/utils/app.utils'; export type Sort = {field: 'name' | 'id', way : 'asc' | 'desc'} @@ -53,8 +55,6 @@ export class StudyNodeComponent extends TreeNodeAbstractComponent imp filter: string; filteredNodes: SubjectNode[]; subjectsOrder: Sort; - protected nbSubjectsInit: number = 0; - private subjectsInited: SuperPromise; constructor( private router: Router, @@ -85,18 +85,16 @@ export class StudyNodeComponent extends TreeNodeAbstractComponent imp let id: number = this.input instanceof StudyNode ? this.input.id : this.input.study.id; this.idPromise.resolve(id); if (this.input instanceof StudyNode) { - this.subjectsInited = new SuperPromise(); - this.nbSubjectsInit = 0; this.node = this.input; } else if (this.input.study && this.input.rights) { - this.subjectsInited = new SuperPromise(); - this.nbSubjectsInit = 0; this.node = this.treeService.buildStudyNode(this.input.study, this.input.rights); } else { throw new Error('Illegal argument type'); } this.sortSubjects({field: 'name', way: 'asc'}); - this.node.subjectsNode.registerOpenPromise(this.subjectsInited); + if (!!this.node.subjectsNode.subjects && this.node.subjectsNode.subjects != UNLOADED) { + this.node.subjectsNode.subjects.forEach(s => s.hidden = !this.treeService.isSelected(s.id, 'subject')); + } this.nodeInit.emit(this.node); this.showDetails = this.router.url != this.detailsPath + this.node.id; } @@ -172,16 +170,20 @@ export class StudyNodeComponent extends TreeNodeAbstractComponent imp } } - onSubjectNodeInit() { - this.nbSubjectsInit++; - if (this.nbSubjectsInit == this.node.subjectsNode?.subjects?.length) { - this.subjectsInited.resolve(); - } + trackByFn(index, item: Entity) { + return item.id; } - onOpenedChange(state) { - if (!state) { - this.nbSubjectsInit = 0; - } + protected clickNode(node: SubjectNode) { + node.hidden = false; + } + + protected clickOpen(node: SubjectNode) { + node.opened = true; + node.hidden = false; + } + + getFontColor(colorInp: string): boolean { + return isDarkColor(colorInp); } } diff --git a/shanoir-ng-front/src/app/tree/tree.model.ts b/shanoir-ng-front/src/app/tree/tree.model.ts index 96611e69da..919cfaffe3 100644 --- a/shanoir-ng-front/src/app/tree/tree.model.ts +++ b/shanoir-ng-front/src/app/tree/tree.model.ts @@ -35,6 +35,7 @@ export abstract class ShanoirNode { private openPromise: Promise; protected readonly routeBase: string; getTop: () => number; // to scroll to the node + hidden: boolean = false; constructor( public parent: ShanoirNode, @@ -46,6 +47,7 @@ export abstract class ShanoirNode { open(): Promise { if (!this._opened) { + this.hidden = false; if (this.parent) { this.parent.open(); } @@ -53,7 +55,7 @@ export abstract class ShanoirNode { // removing timeout may cause random bugs in the tree this._opened = true; }); - return (this.openPromise || Promise.resolve()).then(() => SuperPromise.timeoutPromise()); + return SuperPromise.timeoutPromise().then(() => (this.openPromise || Promise.resolve())); } else { return Promise.resolve(); } @@ -191,7 +193,6 @@ export class MembersNode extends ShanoirNode { export abstract class SubjectNode extends ShanoirNode { - constructor( public parent: ShanoirNode, public id: number,