diff --git a/frontend/src/app/modules/grids/widgets/project-details/project-details.component.html b/frontend/src/app/modules/grids/widgets/project-details/project-details.component.html index 6ba8a201c2..4f36fa126e 100644 --- a/frontend/src/app/modules/grids/widgets/project-details/project-details.component.html +++ b/frontend/src/app/modules/grids/widgets/project-details/project-details.component.html @@ -9,10 +9,19 @@
-
-
- - + +
+ +
+ {{ cf.label }} +
+
+ + +
+
+
+
diff --git a/frontend/src/app/modules/grids/widgets/project-details/project-details.component.ts b/frontend/src/app/modules/grids/widgets/project-details/project-details.component.ts index bc481cd4a9..a1650bb3d3 100644 --- a/frontend/src/app/modules/grids/widgets/project-details/project-details.component.ts +++ b/frontend/src/app/modules/grids/widgets/project-details/project-details.component.ts @@ -26,53 +26,50 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef, Injector, ViewChild, ElementRef} from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + ElementRef, + Injector, + OnInit, + ViewChild +} from '@angular/core'; import {AbstractWidgetComponent} from "app/modules/grids/widgets/abstract-widget.component"; import {I18nService} from "core-app/modules/common/i18n/i18n.service"; import {ProjectDmService} from "core-app/modules/hal/dm-services/project-dm.service"; import {CurrentProjectService} from "core-components/projects/current-project.service"; import {SchemaResource} from "core-app/modules/hal/resources/schema-resource"; -import {DisplayFieldContext, DisplayFieldService} from "core-app/modules/fields/display/display-field.service"; -import {ProjectResource} from "core-app/modules/hal/resources/project-resource"; -import {PortalCleanupService} from 'core-app/modules/fields/display/display-portal/portal-cleanup.service'; -import {DisplayField} from "core-app/modules/fields/display/display-field.module"; -import {WorkPackageViewHighlightingService} from "core-app/modules/work_packages/routing/wp-view-base/view-services/wp-view-highlighting.service"; -import {IsolatedQuerySpace} from "core-app/modules/work_packages/query-space/isolated-query-space"; import {ProjectCacheService} from "core-components/projects/project-cache.service"; - -export const emptyPlaceholder = '-'; +import {Observable} from "rxjs"; +import {ProjectResource} from "core-app/modules/hal/resources/project-resource"; +import {HalResourceEditingService} from "core-app/modules/fields/edit/services/hal-resource-editing.service"; @Component({ templateUrl: './project-details.component.html', changeDetection: ChangeDetectionStrategy.OnPush, providers: [ - // required by the displayField service to render the fields - PortalCleanupService, - WorkPackageViewHighlightingService, - IsolatedQuerySpace + HalResourceEditingService ] }) export class WidgetProjectDetailsComponent extends AbstractWidgetComponent implements OnInit { @ViewChild('contentContainer', { static: true }) readonly contentContainer:ElementRef; - public noFields = false; - - public text = { - noResults: this.i18n.t('js.grid.widgets.project_details.no_results'), - }; + public customFields:{key:string, label:string}[] = []; + public project$:Observable; constructor(protected readonly i18n:I18nService, protected readonly injector:Injector, protected readonly projectDm:ProjectDmService, protected readonly projectCache:ProjectCacheService, protected readonly currentProject:CurrentProjectService, - protected readonly displayField:DisplayFieldService, - protected readonly cdr:ChangeDetectorRef) { + protected readonly cdRef:ChangeDetectorRef) { super(i18n, injector); } ngOnInit() { this.loadAndRender(); + this.project$ = this.projectCache.requireAndStream(this.currentProject.id!); } public get isEditable() { @@ -80,96 +77,25 @@ export class WidgetProjectDetailsComponent extends AbstractWidgetComponent imple } private loadAndRender() { - Promise.all( - [this.loadCurrentProject(), - this.loadProjectSchema()] - ) - .then(([project, schema]) => { - this.renderCFs(project, schema as SchemaResource); - - this.redraw(); + Promise.all([ + this.loadProjectSchema() + ]) + .then(([schema]) => { + this.setCustomFields(schema); }); } - private loadCurrentProject() { - return this.projectCache.require(this.currentProject.id as string); - } - - public get isLoaded() { - return this.projectCache.state(this.currentProject.id as string).value; - } - private loadProjectSchema() { return this.projectDm.schema(); } - private renderCFs(project:ProjectResource, schema:SchemaResource) { - const cfFields = this.collectFieldsForCfs(project, schema); - - this.noFields = cfFields.length === 0; - - this.sortFieldsLexicographically(cfFields); - this.renderFields(cfFields); - } - - private collectFieldsForCfs(project:ProjectResource, schema:SchemaResource) { - let displayFields:Array = []; - // passing an arbitrary context to displayField.getField only to satisfy the interface - let context:DisplayFieldContext = {injector: this.injector, container: 'table', options: []}; - + private setCustomFields(schema:SchemaResource) { Object.entries(schema).forEach(([key, keySchema]) => { if (key.match(/customField\d+/)) { - let field = this.displayField.getField(project, key, keySchema, context); - - displayFields.push(field); + this.customFields.push({key: key, label: keySchema.name }); } }); - return displayFields; - } - - private sortFieldsLexicographically(fields:Array) { - fields.sort((a, b) => { return a.label.localeCompare(b.label); }); - } - - private renderFields(fields:Array) { - this.contentContainer.nativeElement.innerHTML = ''; - - fields.forEach(field => { - this.renderKeyValue(field); - }); - } - - private renderKeyValue(field:DisplayField) { - this.contentContainer.nativeElement.appendChild(this.labelElement(field)); - this.contentContainer.nativeElement.appendChild(this.valueElement(field)); - } - - private labelElement(field:DisplayField) { - const label = document.createElement('div'); - label.classList.add('attributes-map--key'); - label.innerText = field.label; - - return label; - } - - private valueElement(field:DisplayField) { - const value = document.createElement('div'); - value.classList.add('attributes-map--value'); - field.render(value, this.getText(field)); - - return value; - } - - private getText(field:DisplayField):string { - if (field.isEmpty()) { - return emptyPlaceholder; - } else { - return field.valueString; - } - } - - private redraw() { - this.cdr.detectChanges(); + this.cdRef.detectChanges(); } }