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();
}
}