Ensure provided injector in display fields is hierarchical

pull/7042/head
Oliver Günther 6 years ago
parent 52c7eb5063
commit 0654ee71fe
No known key found for this signature in database
GPG Key ID: A3A8BDAD7C0C552C
  1. 2
      frontend/src/app/components/work-packages/work-package-comment/wp-comment-field.component.ts
  2. 5
      frontend/src/app/components/work-packages/wp-single-view/wp-single-view.component.ts
  3. 2
      frontend/src/app/components/wp-edit-form/display-field-renderer.ts
  4. 4
      frontend/src/app/components/wp-query-select/wp-query-select-dropdown.component.ts
  5. 7
      frontend/src/app/components/wp-table/wp-table-sums-row/wp-table-sums-row.directive.ts
  6. 2
      frontend/src/app/components/wp-table/wp-table.directive.ts
  7. 13
      frontend/src/app/modules/fields/display/display-field.module.ts
  8. 3
      frontend/src/app/modules/fields/display/display-field.service.ts
  9. 2
      frontend/src/app/modules/fields/edit/field-types/duration-edit-field.component.ts
  10. 2
      frontend/src/app/modules/fields/edit/field-types/formattable-edit-field.component.ts
  11. 5
      frontend/src/app/modules/fields/field.base.ts
  12. 17
      frontend/src/app/modules/work_packages/openproject-work-packages.module.ts
  13. 25
      frontend/src/app/modules/work_packages/query-space/wp-isolated-query-space.directive.ts
  14. 2
      frontend/src/app/modules/work_packages/routing/work-packages-routes.ts
  15. 2
      frontend/src/app/modules/work_packages/routing/wp-base/wp--base.component.ts

@ -39,7 +39,7 @@ import {
export class WorkPackageCommentFieldComponent extends FormattableEditFieldComponent implements OnInit {
public isBusy:boolean = false;
public ConfigurationService:ConfigurationService = this.$injector.get(ConfigurationService);
public ConfigurationService:ConfigurationService = this.injector.get(ConfigurationService);
public get name() {
return 'comment';

@ -26,7 +26,7 @@
// See doc/COPYRIGHT.rdoc for more details.
// ++
import {Component, ElementRef, Inject, Input, OnDestroy, OnInit} from '@angular/core';
import {Component, ElementRef, Inject, Injector, Input, OnDestroy, OnInit} from '@angular/core';
import {I18nService} from 'core-app/modules/common/i18n/i18n.service';
import {PathHelperService} from 'core-app/modules/common/path-helper/path-helper.service';
import {componentDestroyed} from 'ng2-rx-componentdestroyed';
@ -126,6 +126,7 @@ export class WorkPackageSingleViewComponent implements OnInit, OnDestroy {
protected displayFieldService:DisplayFieldService,
protected wpCacheService:WorkPackageCacheService,
protected hook:HookService,
protected injector:Injector,
readonly elementRef:ElementRef) {
}
@ -356,7 +357,7 @@ export class WorkPackageSingleViewComponent implements OnInit, OnDestroy {
resource,
name,
resource.schema[name],
{ container: 'single-view', options: {} }
{ container: 'single-view', injector: this.injector, options: {} }
) as DisplayField;
}

@ -79,7 +79,7 @@ export class DisplayFieldRenderer {
}
private getFieldForCurrentContext(workPackage:WorkPackageResource, fieldSchema:IFieldSchema, name:string):DisplayField {
const context:DisplayFieldContext = { container: this.container, options: this.options };
const context:DisplayFieldContext = { container: this.container, injector: this.injector, options: this.options };
// We handle multi value fields differently in the single view context
const isMultiLinesField = ['[]CustomOption', '[]User'].indexOf(fieldSchema.type) >= 0;

@ -118,8 +118,7 @@ export class WorkPackageQuerySelectDropdownComponent implements OnInit, OnDestro
readonly loadingIndicator:LoadingIndicatorService,
readonly pathHelper:PathHelperService,
readonly wpStaticQueries:WorkPackageStaticQueriesService,
readonly toggleService:MainMenuToggleService,
readonly wpStatesInitialization:WorkPackageStatesInitializationService) {
readonly toggleService:MainMenuToggleService) {
}
public ngOnInit() {
@ -440,7 +439,6 @@ export class WorkPackageQuerySelectDropdownComponent implements OnInit, OnDestro
// Ensure we're reloading the query
if (isSameItem) {
this.wpStatesInitialization.clearStates();
this.wpListChecksumService.clear();
opts.reload = true;
}

@ -121,7 +121,12 @@ export class WorkPackageTableSumsRowController implements AfterViewInit {
return div;
}
const field = this.displayFieldService.getField(sums, name, fieldSchema, { container: 'table', options: {} });
const field = this.displayFieldService.getField(
sums,
name,
fieldSchema,
{ injector: this.injector, container: 'table', options: {} }
);
if (!field.isEmpty()) {
field.render(div, field.valueString);

@ -107,7 +107,7 @@ export class WorkPackagesTableController implements OnInit, OnDestroy {
public readonly uniqueTableIdentifier = `wp-table--container-${randomString(16)}`;
constructor(readonly elementRef:ElementRef,
readonly injector:Injector,
readonly injector:Injector,
readonly states:States,
readonly querySpace:IsolatedQuerySpace,
readonly opModalService:OpModalService,

@ -36,19 +36,28 @@ export class DisplayField extends Field {
public mode:string | null = null;
public changeset:WorkPackageChangeset|null = null;
protected I18n:I18nService
protected I18n:I18nService = this.$injector.get(I18nService);
constructor(public resource:any,
public name:string,
public schema:IFieldSchema,
public context:DisplayFieldContext) {
super();
this.I18n = this.$injector.get(I18nService);
}
public get isFormattable():boolean {
return false;
}
/**
* Return the provided local injector,
* which is relevant to provide the display field
* the current space context.
*/
protected get $injector() {
return this.context.injector;
}
public get value() {
if (!this.schema) {
return null;

@ -37,6 +37,9 @@ export interface IDisplayFieldType extends IFieldType<DisplayField> {
}
export interface DisplayFieldContext {
/** The injector to use for the context of this field. Relevant for embedded service injection */
injector:Injector;
/** Where will the field be rendered? This may result in different styles (Multi select field, e.g.,) */
container: 'table'|'single-view'|'timeline';

@ -46,7 +46,7 @@ import {EditFieldComponent} from "core-app/modules/fields/edit/edit-field.compon
`
})
export class DurationEditFieldComponent extends EditFieldComponent {
readonly TimezoneService:TimezoneService = this.$injector.get(TimezoneService);
readonly TimezoneService:TimezoneService = this.injector.get(TimezoneService);
public parser(value:any) {
if (!isNaN(value)) {

@ -57,7 +57,7 @@ export const formattableFieldTemplate = `
template: formattableFieldTemplate
})
export class FormattableEditFieldComponent extends EditFieldComponent implements OnInit {
readonly pathHelper:PathHelperService = this.$injector.get(PathHelperService);
readonly pathHelper:PathHelperService = this.injector.get(PathHelperService);
public readonly field = this;

@ -40,7 +40,6 @@ export interface IFieldSchema {
export class Field {
public static type:string;
public static $injector:Injector;
public resource:any;
public name:string;
public schema:IFieldSchema;
@ -77,8 +76,4 @@ export class Field {
public get unknownAttribute():boolean {
return this.isEmpty && !this.schema;
}
protected get $injector():Injector {
return (this.constructor as typeof Field).$injector;
}
}

@ -56,7 +56,6 @@ import {WorkPackageTimelineHeaderController} from 'core-components/wp-table/time
import {WorkPackageTableTimelineRelations} from 'core-components/wp-table/timeline/global-elements/wp-timeline-relations.directive';
import {WorkPackageTableTimelineStaticElements} from 'core-components/wp-table/timeline/global-elements/wp-timeline-static-elements.directive';
import {WorkPackageTableTimelineGrid} from 'core-components/wp-table/timeline/grid/wp-timeline-grid.directive';
import {WorkPackageTableTimelineService} from 'core-components/wp-fast-table/state/wp-table-timeline.service';
import {WorkPackageTimelineButtonComponent} from 'core-components/wp-buttons/wp-timeline-toggle-button/wp-timeline-toggle-button.component';
import {WorkPackageOverviewTabComponent} from 'core-components/wp-single-view-tabs/overview-tab/overview-tab.component';
import {WorkPackageStatusButtonComponent} from 'core-components/wp-buttons/wp-status-button/wp-status-button.component';
@ -135,7 +134,6 @@ import {ExternalRelationQueryConfigurationService} from "core-components/wp-tabl
import {WorkPackageStaticQueriesService} from 'core-components/wp-query-select/wp-static-queries.service';
import {WorkPackagesListInvalidQueryService} from 'core-components/wp-list/wp-list-invalid-query.service';
import {WorkPackageInlineCreateService} from 'core-components/wp-inline-create/wp-inline-create.service';
import {WorkPackageRelationsService} from 'core-components/wp-relations/wp-relations.service';
import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service';
import {SchemaCacheService} from 'core-components/schemas/schema-cache.service';
import {WorkPackageContextMenuHelperService} from 'core-components/wp-table/context-menu-helper/wp-context-menu-helper.service';
@ -191,25 +189,14 @@ import {WorkPackageIsolatedQuerySpaceDirective} from "core-app/modules/work_pack
multi: true
},
// Timeline
WorkPackageTableTimelineService,
// External query configuration
ExternalQueryConfigurationService,
ExternalRelationQueryConfigurationService,
// Global work package states / services
WorkPackageService,
WorkPackageCacheService,
SchemaCacheService,
// Provide a separate service for creation events of WP Inline create
// This can be hierarchically injected to provide isolated events on an embedded table
WorkPackageInlineCreateService,
WpChildrenInlineCreateService,
WpRelationInlineCreateService,
WorkPackageRelationsService,
// Global query/table state services
// For any service that depends on the isolated query space,
// they should be provided in wp-isolated-query-space.directive instead
@ -220,15 +207,11 @@ import {WorkPackageIsolatedQuerySpaceDirective} from "core-app/modules/work_pack
KeepTabService,
WorkPackageNotificationService,
WorkPackagesListChecksumService,
WorkPackageRelationsHierarchyService,
WorkPackageFiltersService,
ApiWorkPackagesService,
WorkPackagesActivityService,
WorkPackageWatchersService,
WorkPackageContextMenuHelperService,
QueryFormDmService,
],
declarations: [

@ -26,7 +26,7 @@
// See doc/COPYRIGHT.rdoc for more details.
// ++
import {Directive} from '@angular/core';
import {Directive, Injector} from '@angular/core';
import {IsolatedQuerySpace} from "core-app/modules/work_packages/query-space/isolated-query-space";
import {OpTableActionsService} from "core-components/wp-table/table-actions/table-actions.service";
import {WorkPackageTableRelationColumnsService} from "core-components/wp-fast-table/state/wp-table-relation-columns.service";
@ -51,6 +51,14 @@ import {ReorderQueryService} from "core-app/modules/boards/drag-and-drop/reorder
import {IWorkPackageEditingServiceToken} from "core-components/wp-edit-form/work-package-editing.service.interface";
import {WorkPackageEditingService} from "core-components/wp-edit-form/work-package-editing-service";
import {WorkPackagesListService} from "core-components/wp-list/wp-list.service";
import {WorkPackageService} from "core-components/work-packages/work-package.service";
import {WorkPackageRelationsService} from "core-components/wp-relations/wp-relations.service";
import {WorkPackageRelationsHierarchyService} from "core-components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.service";
import {WorkPackageFiltersService} from "core-components/filters/wp-filters/wp-filters.service";
import {WorkPackageContextMenuHelperService} from "core-components/wp-table/context-menu-helper/wp-context-menu-helper.service";
import {WorkPackageInlineCreateService} from "core-components/wp-inline-create/wp-inline-create.service";
import {WpChildrenInlineCreateService} from "core-components/wp-relations/embedded/children/wp-children-inline-create.service";
import {WpRelationInlineCreateService} from "core-components/wp-relations/embedded/relations/wp-relation-inline-create.service";
/**
* Directive to open a work package query 'space', an isolated injector hierarchy
@ -82,6 +90,17 @@ import {WorkPackagesListService} from "core-components/wp-list/wp-list.service";
WorkPackageTableRefreshService,
WorkPackageTableFocusService,
WorkPackageTableHighlightingService,
WorkPackageService,
WorkPackageRelationsService,
WorkPackageRelationsHierarchyService,
WorkPackageFiltersService,
WorkPackageContextMenuHelperService,
// Provide a separate service for creation events of WP Inline create
// This can be hierarchically injected to provide isolated events on an embedded table
WorkPackageInlineCreateService,
WpChildrenInlineCreateService,
WpRelationInlineCreateService,
// Provide both serves with tokens to avoid tight dependency cycles
{ provide: IWorkPackageCreateServiceToken, useClass: WorkPackageCreateService },
@ -93,4 +112,8 @@ import {WorkPackagesListService} from "core-components/wp-list/wp-list.service";
]
})
export class WorkPackageIsolatedQuerySpaceDirective {
constructor(private injector:Injector) {
console.log(injector.get(IsolatedQuerySpace));
}
}

@ -50,7 +50,7 @@ export const WORK_PACKAGES_ROUTES:Ng2StateDeclaration[] = [
parent: 'root',
component: WorkPackagesBaseComponent,
url: '/work_packages?query_id&query_props',
abstract: true,
redirectTo: 'work-packages.list',
params: {
query_id: { type: 'query', dynamic: true },
// Use custom encoder/decoder that ensures validity of URL string

@ -26,7 +26,7 @@
// See doc/COPYRIGHT.rdoc for more details.
// ++
import {Component} from "@angular/core";
import {Component, Injector} from "@angular/core";
import {DynamicBootstrapper} from "core-app/globals/dynamic-bootstrapper";
export const wpBaseSelector = 'work-packages-base';

Loading…
Cancel
Save