diff --git a/dcm4chee-arc-ui2/src/app/app.module.ts b/dcm4chee-arc-ui2/src/app/app.module.ts index c703f3331..0d14e686c 100644 --- a/dcm4chee-arc-ui2/src/app/app.module.ts +++ b/dcm4chee-arc-ui2/src/app/app.module.ts @@ -96,6 +96,9 @@ import { StorageVerificationComponent } from './monitoring/storage-verification/ import {StorageVerificationService} from "./monitoring/storage-verification/storage-verification.service"; import { ConfigTabComponent } from './configuration/config-tab.component'; import {DevicesService} from './configuration/devices/devices.service'; +import {StudyTabComponent} from "./study/study-tab.component"; +import { StudyComponent } from './study/study/study.component'; +import {StudyService} from "./study/study/study.service"; @NgModule({ declarations: [ @@ -149,6 +152,8 @@ import {DevicesService} from './configuration/devices/devices.service'; TableGeneratorComponent, StorageVerificationComponent, ConfigTabComponent, + StudyTabComponent, + StudyComponent, ], imports: [ BrowserModule, @@ -184,6 +189,7 @@ import {DevicesService} from './configuration/devices/devices.service'; canActivate: [AuthGuard] }, { path: 'studies', component: StudiesComponent , canActivate: [AuthGuard]}, + { path: 'study/:tab', component: StudyComponent , canActivate: [AuthGuard]}, { path: 'permission-denied', component: PermissionDeniedComponent}, { path: 'monitoring/control', component: ControlComponent, canActivate: [AuthGuard] }, { path: 'monitoring/export', component: ExportComponent, canActivate: [AuthGuard] }, @@ -237,6 +243,7 @@ import {DevicesService} from './configuration/devices/devices.service'; DiffMonitorService, RangePickerService, StorageVerificationService, + StudyService, {provide: LOCALE_ID, useValue: 'en-US' } ], bootstrap: [AppComponent] diff --git a/dcm4chee-arc-ui2/src/app/configuration/ae-list/ae-list.service.ts b/dcm4chee-arc-ui2/src/app/configuration/ae-list/ae-list.service.ts index 6ea49d492..791c1de7e 100644 --- a/dcm4chee-arc-ui2/src/app/configuration/ae-list/ae-list.service.ts +++ b/dcm4chee-arc-ui2/src/app/configuration/ae-list/ae-list.service.ts @@ -16,12 +16,12 @@ export class AeListService { getAes(){ return this.$http.get( '../aes' - ).map(res => {let resjson; try{ let pattern = new RegExp("[^:]*:\/\/[^\/]*\/auth\/"); if(pattern.exec(res.url)){ WindowRefService.nativeWindow.location = "/dcm4chee-arc/ui2/";} resjson = res.json(); }catch (e){ resjson = [];} return resjson;}) + ).map(res => j4care.redirectOnAuthResponse(res)); } getAets(){ return this.$http.get( '../aets' - ).map(res => {let resjson; try{ let pattern = new RegExp("[^:]*:\/\/[^\/]*\/auth\/"); if(pattern.exec(res.url)){ WindowRefService.nativeWindow.location = "/dcm4chee-arc/ui2/";} resjson = res.json(); }catch (e){ resjson = [];} return resjson;}) + ).map(res => j4care.redirectOnAuthResponse(res)); } getDevices(){ diff --git a/dcm4chee-arc-ui2/src/app/constants/globalvar.ts b/dcm4chee-arc-ui2/src/app/constants/globalvar.ts index 2f0534cc0..ff4bd05ea 100644 --- a/dcm4chee-arc-ui2/src/app/constants/globalvar.ts +++ b/dcm4chee-arc-ui2/src/app/constants/globalvar.ts @@ -1,3 +1,5 @@ +import {FilterSchema} from "../interfaces"; + export class Globalvar { public static get MODALITIES(): any { return { @@ -648,7 +650,7 @@ export class Globalvar { return actionObject; } } - static STUDY_FILTER_SCHEMA(aets,hidden?){ + static STUDY_FILTER_SCHEMA(aets,hidden?):FilterSchema{ if(hidden){ return [ { diff --git a/dcm4chee-arc-ui2/src/app/interfaces.ts b/dcm4chee-arc-ui2/src/app/interfaces.ts new file mode 100644 index 000000000..064be79bb --- /dev/null +++ b/dcm4chee-arc-ui2/src/app/interfaces.ts @@ -0,0 +1,85 @@ +export interface J4careDateTime { + FullYear:string; + Month:string; + Date:string; + Hours:string; + Minutes:string; + Seconds:string; + dateObject?:Date; +} +export type J4careDateTimeMode = "range" | "leftOpen" | "rightOpen" | "single"; + +export interface RangeObject { + firstDateTime:J4careDateTime; + secondDateTime:J4careDateTime; + mode:J4careDateTimeMode; +} + +export type StatisticsPage = "simple"|"detailed" + +export type FilterTag = "input"|"checkbox"|"select"|"modality"|"range-picker-limit"|"range-picker-time"|"range-picker"|"multi-select"; + +export type RangeUnit = "hour" | "day" | "week" | "month" | "year"; + +export class SelectDropdown { + private _value:string; + private _text:string; + private _label:string; + private _title?:string; + constructor(value:any,text:string, title?:string){ + this._value = value; + this._text = text; + this._label = text; + this._title = title; + } + + get value(): string { + return this._value; + } + + set value(value: string) { + this._value = value; + } + + get text(): string { + return this._text; + } + + set text(value: string) { + this._text = value; + } + + get label(): string { + return this._label; + } + + set label(value:string) { + this._label = value; + } + + get title(): string { + return this._title; + } + + set title(value: string) { + this._title = value; + } +} +export type Quantity = "count"|"size"|string; +export type StudyDateMode = "StudyReceiveDateTime"|"StudyDate"|string; +export type FilterSchema = FilterSchemaElement[]; + +export interface FilterSchemaElement { + tag:FilterTag; + filterKey:string; + type?:"text"|"number"; + text?:string; + description?:string; + placeholder?:string; + showStar?:boolean; + maxSelectedLabels?:number; + options?:SelectDropdown[] +} + +export type StudyTab = "study" | "patient" | "mwl" | "diff"; +export type AccessLocation = "internal" | "external"; diff --git a/dcm4chee-arc-ui2/src/app/models/aet.ts b/dcm4chee-arc-ui2/src/app/models/aet.ts new file mode 100644 index 000000000..80fc27dae --- /dev/null +++ b/dcm4chee-arc-ui2/src/app/models/aet.ts @@ -0,0 +1,102 @@ +import * as _ from "lodash"; + +export class Aet { + private _dicomAETitle:string; + private _dicomDescription:string; + private _dcmAcceptedUserRole:string[]; + private _dcmAllowDeletePatient:string; + private _dcmAllowDeleteStudyPermanently:string; + private _dicomApplicationCluster:string[]; + private _dicomAssociationAcceptor:boolean; + private _dicomAssociationInitiator:boolean; + private _dicomNetworkConnection:any + + constructor(aetObject){ + [ + "dicomAETitle", + "dicomDescription", + "dcmAcceptedUserRole", + "dcmAllowDeletePatient", + "dcmAllowDeleteStudyPermanently", + "dicomApplicationCluster", + "dicomAssociationAcceptor", + "dicomAssociationInitiator", + "dicomNetworkConnection" + ].forEach(attr=>{ + if(_.hasIn(aetObject,attr)) + this[attr] = aetObject[attr]; + }); + } + + get dcmAcceptedUserRole(): string[] { + return this._dcmAcceptedUserRole; + } + + set dcmAcceptedUserRole(value: string[]) { + this._dcmAcceptedUserRole = value; + } + + get dcmAllowDeletePatient(): string { + return this._dcmAllowDeletePatient; + } + + set dcmAllowDeletePatient(value: string) { + this._dcmAllowDeletePatient = value; + } + + get dcmAllowDeleteStudyPermanently(): string { + return this._dcmAllowDeleteStudyPermanently; + } + + set dcmAllowDeleteStudyPermanently(value: string) { + this._dcmAllowDeleteStudyPermanently = value; + } + + get dicomAETitle(): string { + return this._dicomAETitle; + } + + set dicomAETitle(value: string) { + this._dicomAETitle = value; + } + + get dicomDescription(): string { + return this._dicomDescription; + } + + set dicomDescription(value: string) { + this._dicomDescription = value; + } + + get dicomApplicationCluster(): string[] { + return this._dicomApplicationCluster; + } + + set dicomApplicationCluster(value: string[]) { + this._dicomApplicationCluster = value; + } + + get dicomAssociationAcceptor(): boolean { + return this._dicomAssociationAcceptor; + } + + set dicomAssociationAcceptor(value: boolean) { + this._dicomAssociationAcceptor = value; + } + + get dicomAssociationInitiator(): boolean { + return this._dicomAssociationInitiator; + } + + set dicomAssociationInitiator(value: boolean) { + this._dicomAssociationInitiator = value; + } + + get dicomNetworkConnection(): any { + return this._dicomNetworkConnection; + } + + set dicomNetworkConnection(value: any) { + this._dicomNetworkConnection = value; + } +} diff --git a/dcm4chee-arc-ui2/src/app/models/instance-dicom.ts b/dcm4chee-arc-ui2/src/app/models/instance-dicom.ts new file mode 100644 index 000000000..937a5e1de --- /dev/null +++ b/dcm4chee-arc-ui2/src/app/models/instance-dicom.ts @@ -0,0 +1,2 @@ +export class InstanceDicom { +} diff --git a/dcm4chee-arc-ui2/src/app/models/patient-dicom.ts b/dcm4chee-arc-ui2/src/app/models/patient-dicom.ts new file mode 100644 index 000000000..592b80598 --- /dev/null +++ b/dcm4chee-arc-ui2/src/app/models/patient-dicom.ts @@ -0,0 +1,3 @@ +export class PatientDicom { + +} diff --git a/dcm4chee-arc-ui2/src/app/models/series-dicom.ts b/dcm4chee-arc-ui2/src/app/models/series-dicom.ts new file mode 100644 index 000000000..68b792a17 --- /dev/null +++ b/dcm4chee-arc-ui2/src/app/models/series-dicom.ts @@ -0,0 +1,2 @@ +export class SeriesDicom { +} diff --git a/dcm4chee-arc-ui2/src/app/models/study-dicom.ts b/dcm4chee-arc-ui2/src/app/models/study-dicom.ts new file mode 100644 index 000000000..2bd4af03a --- /dev/null +++ b/dcm4chee-arc-ui2/src/app/models/study-dicom.ts @@ -0,0 +1,2 @@ +export class StudyDicom { +} diff --git a/dcm4chee-arc-ui2/src/app/study/study-tab.component.ts b/dcm4chee-arc-ui2/src/app/study/study-tab.component.ts new file mode 100644 index 000000000..acda38c97 --- /dev/null +++ b/dcm4chee-arc-ui2/src/app/study/study-tab.component.ts @@ -0,0 +1,17 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'study-tab', + template:` + + ` +}) +export class StudyTabComponent{ + + constructor() { } +} diff --git a/dcm4chee-arc-ui2/src/app/study/study/study.component.html b/dcm4chee-arc-ui2/src/app/study/study/study.component.html new file mode 100644 index 000000000..040ffab31 --- /dev/null +++ b/dcm4chee-arc-ui2/src/app/study/study/study.component.html @@ -0,0 +1,6 @@ +
+ +
+

Studies {{tab}}

+
+
\ No newline at end of file diff --git a/dcm4chee-arc-ui2/src/app/study/study/study.component.scss b/dcm4chee-arc-ui2/src/app/study/study/study.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/dcm4chee-arc-ui2/src/app/study/study/study.component.spec.ts b/dcm4chee-arc-ui2/src/app/study/study/study.component.spec.ts new file mode 100644 index 000000000..ba943862d --- /dev/null +++ b/dcm4chee-arc-ui2/src/app/study/study/study.component.spec.ts @@ -0,0 +1,41 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { StudyComponent } from './study.component'; +import {StudyTabComponent} from "../study-tab.component"; +import {PermissionDirective} from "../../helpers/permissions/permission.directive"; +import {ActivatedRoute} from "@angular/router"; +import {AeListService} from "../../configuration/ae-list/ae-list.service"; +import {StudyService} from "./study.service"; +import {PermissionService} from "../../helpers/permissions/permission.service"; +import {AppService} from "../../app.service"; +import {HttpModule} from "@angular/http"; +import {RouterTestingModule} from "@angular/router/testing"; + +describe('StudyComponent', () => { + let component: StudyComponent; + let fixture: ComponentFixture; + +/* beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ StudyComponent, StudyTabComponent, PermissionDirective], + providers:[ + {provide:ActivatedRoute, useClass:StudyComponentDependenc}, + {provide:StudyService, useClass:StudyComponentDependenc}, + {provide:AppService, useClass:StudyComponentDependenc}, + {provide:PermissionService, useClass:StudyComponentDependenc} + ], + imports:[RouterTestingModule] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(StudyComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + });*/ +}); diff --git a/dcm4chee-arc-ui2/src/app/study/study/study.component.ts b/dcm4chee-arc-ui2/src/app/study/study/study.component.ts new file mode 100644 index 000000000..d34960c11 --- /dev/null +++ b/dcm4chee-arc-ui2/src/app/study/study/study.component.ts @@ -0,0 +1,71 @@ +import { Component, OnInit } from '@angular/core'; +import {ActivatedRoute} from "@angular/router"; +import {AccessLocation, FilterSchema, StudyTab} from "../../interfaces"; +import {StudyService} from "./study.service"; +import {Observable} from "rxjs/Observable"; +import {j4care} from "../../helpers/j4care.service"; +import {Aet} from "../../models/aet"; +import {PermissionService} from "../../helpers/permissions/permission.service"; +import {AppService} from "../../app.service"; + +@Component({ + selector: 'app-study', + templateUrl: './study.component.html', + styleUrls: ['./study.component.scss'] +}) +export class StudyComponent implements OnInit { + + tab:StudyTab; + + applicationEntities = { + aes:{ + external:[], + internal:[] + }, + aets:{ + external:[], + internal:[] + } + }; + filterSchema:FilterSchema; + accessLocation:AccessLocation = "internal"; + constructor( + private route:ActivatedRoute, + private service:StudyService, + private permissionService:PermissionService, + private appService:AppService + ) { } + + ngOnInit() { + console.log("aet",this.applicationEntities); + this.route.queryParams.subscribe(params => { + this.tab = params.tab; + this.getApplicationEntities(); + }); + } + + + initSchema(){ + this.filterSchema = this.service.getFilterSchema(this.tab, this.applicationEntities.aes[this.accessLocation],false); + } + getApplicationEntities(){ + Observable.forkJoin( + this.service.getAes().map(aes=> aes.map(aet=> new Aet(aet))), + this.service.getAets().map(aets=> aets.map(aet => new Aet(aet))), + ) + .retry(2) + .subscribe((res)=>{ + [0,1].forEach(i=>{ + res[i] = j4care.extendAetObjectWithAlias(res[i]); + ["external","internal"].forEach(location=>{ + this.applicationEntities.aes[location] = this.permissionService.filterAetDependingOnUiConfig(res[i],location); + this.applicationEntities.aets[location] = this.permissionService.filterAetDependingOnUiConfig(res[i],location); + }) + }); + this.initSchema(); + },(err)=>{ + this.appService.showError("Error getting AETs!"); + j4care.log("error getting aets in Study page",err); + }); + } +} diff --git a/dcm4chee-arc-ui2/src/app/study/study/study.service.spec.ts b/dcm4chee-arc-ui2/src/app/study/study/study.service.spec.ts new file mode 100644 index 000000000..eded0885b --- /dev/null +++ b/dcm4chee-arc-ui2/src/app/study/study/study.service.spec.ts @@ -0,0 +1,22 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { StudyService } from './study.service'; +import {AeListService} from "../../configuration/ae-list/ae-list.service"; + +class StudyServiceDependenc{ +} + +describe('StudyService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + StudyService, + {provide:AeListService, useClass:StudyServiceDependenc} + ] + }); + }); + + it('should be created', inject([StudyService], (service: StudyService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/dcm4chee-arc-ui2/src/app/study/study/study.service.ts b/dcm4chee-arc-ui2/src/app/study/study/study.service.ts new file mode 100644 index 000000000..46e708ca0 --- /dev/null +++ b/dcm4chee-arc-ui2/src/app/study/study/study.service.ts @@ -0,0 +1,30 @@ +import { Injectable } from '@angular/core'; +import {StudyTab} from "../../interfaces"; +import {Globalvar} from "../../constants/globalvar"; +import {Aet} from "../../models/aet"; +import {AeListService} from "../../configuration/ae-list/ae-list.service"; + +@Injectable() +export class StudyService { + + constructor( + private aeListService:AeListService + ) { } + + getFilterSchema(tab:StudyTab, aets:Aet[], hidden:boolean){ + switch(tab){ + case "patient": + break; + case "mwl": + break; + case "diff": + break; + default: + return Globalvar.STUDY_FILTER_SCHEMA(aets,hidden); + } + } + + getAets = ()=> this.aeListService.getAets(); + + getAes = ()=> this.aeListService.getAes(); +}