Bump Angular to 11.0 (#8913)

* Bump Angular to 11

* Bump fullcalendar

* Bump uirouter

* bump typescript and rxjs

fixup! bump typescript and rxjs

* Run angular update migrations

* Fix deprecated options in serve, they are kept in builder

* Replace node-sass with sass and fix errors

* Include all ts files again to fix warnings

We have scripts that should be contained but are only loaded dynamically. It seems this trips up TS

to print warnings that these files are unused, which they really aren't.

* Address typescript compilation errors and warnings due to 4.0 upgrade

* Link to styles.css not js with updated sass

* Only reposition dropdown if appendTo is set

* Initialize resource property in edit field component

Correctly update field component and handler properties

Always use the changeset schema

Fix removed property in custom text
pull/8918/head
Oliver Günther 4 years ago committed by GitHub
parent 49abb1bc33
commit 1ef61291f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      app/helpers/frontend_asset_helper.rb
  2. 2
      frontend/angular.json
  3. 3748
      frontend/npm-shrinkwrap.json
  4. 47
      frontend/package.json
  5. 2
      frontend/src/app/components/datepicker/datepicker.modal.ts
  6. 6
      frontend/src/app/components/op-context-menu/wp-context-menu/wp-view-context-menu.directive.ts
  7. 8
      frontend/src/app/components/user/user-avatar/user-avatar.component.spec.ts
  8. 8
      frontend/src/app/components/user/user-link/user-link.component.spec.ts
  9. 5
      frontend/src/app/components/work-packages/work-package-comment/work-package-comment-field-handler.ts
  10. 6
      frontend/src/app/components/work-packages/work-package-comment/work-package-comment.component.ts
  11. 5
      frontend/src/app/components/work-packages/work-package-comment/wp-comment-field.component.ts
  12. 6
      frontend/src/app/components/wp-activity/user/user-activity.component.ts
  13. 2
      frontend/src/app/components/wp-edit-form/table-edit-form.ts
  14. 2
      frontend/src/app/components/wp-fast-table/builders/primary-render-pass.ts
  15. 2
      frontend/src/app/components/wp-fast-table/builders/rows/single-row-builder.ts
  16. 2
      frontend/src/app/components/wp-fast-table/wp-fast-table.ts
  17. 2
      frontend/src/app/components/wp-inline-create/wp-inline-create.service.ts
  18. 1
      frontend/src/app/components/wp-new/wp-create.component.ts
  19. 2
      frontend/src/app/components/wp-table/embedded/wp-embedded-base.component.ts
  20. 2
      frontend/src/app/components/wp-table/table-actions/table-action.ts
  21. 4
      frontend/src/app/components/wp-table/table-pagination/wp-table-pagination.component.spec.ts
  22. 2
      frontend/src/app/components/wp-table/timeline/cells/timeline-cell-renderer.ts
  23. 4
      frontend/src/app/modules/apiv3/api-v3.service.spec.ts
  24. 4
      frontend/src/app/modules/bim/bcf/api/bcf-api.service.spec.ts
  25. 4
      frontend/src/app/modules/boards/board/board-actions/assignee/assignee-action.service.ts
  26. 4
      frontend/src/app/modules/boards/board/board-actions/status/status-action.service.ts
  27. 4
      frontend/src/app/modules/boards/board/board-actions/subproject/subproject-action.service.ts
  28. 4
      frontend/src/app/modules/boards/board/board-actions/subtasks/board-subtasks-action.service.ts
  29. 4
      frontend/src/app/modules/boards/board/board-actions/version/version-action.service.ts
  30. 2
      frontend/src/app/modules/boards/tile-view/tile-view.component.spec.ts
  31. 2
      frontend/src/app/modules/common/autocomplete/create-autocompleter.component.ts
  32. 1
      frontend/src/app/modules/common/autocomplete/version-autocompleter.component.ts
  33. 2
      frontend/src/app/modules/common/editable-toolbar-title/editable-toolbar-title.component.ts
  34. 2
      frontend/src/app/modules/common/editable-toolbar-title/editable-toolbar-title.sass
  35. 4
      frontend/src/app/modules/common/icon/op-icon.spec.ts
  36. 4
      frontend/src/app/modules/common/notifications/notifications.service.spec.ts
  37. 2
      frontend/src/app/modules/fields/display/display-field-renderer.ts
  38. 2
      frontend/src/app/modules/fields/display/display-field.module.ts
  39. 4
      frontend/src/app/modules/fields/display/field-types/linked-work-package-display-field.module.ts
  40. 4
      frontend/src/app/modules/fields/display/field-types/wp-id-display-field.module.ts
  41. 29
      frontend/src/app/modules/fields/edit/edit-field.component.ts
  42. 11
      frontend/src/app/modules/fields/edit/editing-portal/edit-field-handler.ts
  43. 2
      frontend/src/app/modules/fields/edit/field-controls/edit-field-controls.component.html
  44. 25
      frontend/src/app/modules/fields/edit/field-handler/hal-resource-edit-field-handler.ts
  45. 2
      frontend/src/app/modules/fields/edit/field-types/multi-select-edit-field.component.ts
  46. 2
      frontend/src/app/modules/fields/edit/field-types/project-status-edit-field.component.ts
  47. 2
      frontend/src/app/modules/fields/help-texts/attribute-help-text.service.ts
  48. 4
      frontend/src/app/modules/global_search/services/global-search.service.spec.ts
  49. 44
      frontend/src/app/modules/grids/widgets/custom-text/custom-text-edit-field.service.ts
  50. 12
      frontend/src/app/modules/grids/widgets/news/news.component.spec.ts
  51. 1
      frontend/src/app/modules/hal/resources/custom-action-resource.ts
  52. 1
      frontend/src/app/modules/hal/resources/grid-resource.ts
  53. 1
      frontend/src/app/modules/hal/resources/group-resource.ts
  54. 4
      frontend/src/app/modules/hal/resources/hal-resource.spec.ts
  55. 2
      frontend/src/app/modules/hal/resources/hal-resource.ts
  56. 2
      frontend/src/app/modules/hal/resources/help-text-resource.ts
  57. 5
      frontend/src/app/modules/hal/resources/query-filter-instance-schema-resource.ts
  58. 1
      frontend/src/app/modules/hal/resources/query-group-by-resource.ts
  59. 1
      frontend/src/app/modules/hal/resources/relation-resource.ts
  60. 1
      frontend/src/app/modules/hal/resources/user-resource.ts
  61. 4
      frontend/src/app/modules/hal/resources/work-package-resource.spec.ts
  62. 2
      frontend/src/app/modules/hal/resources/work-package-resource.ts
  63. 2
      frontend/src/app/modules/time_entries/edit/trigger-actions-entry.component.ts
  64. 2
      frontend/src/app/modules/work_packages/routing/partitioned-query-space-page/partitioned-query-space-page.component.ts
  65. 3
      frontend/src/app/modules/work_packages/routing/wp-view-base/view-services/wp-view-group-by.service.ts
  66. 4
      frontend/src/app/modules/work_packages/routing/wp-view-base/view-services/wp-view-hierarchy-indentation.service.spec.ts
  67. 2
      frontend/src/app/modules/work_packages/routing/wp-view-base/work-package-single-view.base.ts
  68. 2
      frontend/src/app/modules/work_packages/routing/wp-view-base/work-packages-view.base.ts
  69. 4
      frontend/src/global_styles/content/user-content/_image.sass
  70. 4
      frontend/src/global_styles/content/user-content/_index.sass
  71. 2
      frontend/src/global_styles/content/user-content/_table.sass
  72. 2
      frontend/src/global_styles/content/user-content/_toc.sass
  73. 2
      frontend/src/global_styles/content/work_packages/_table_content.sass
  74. 2
      frontend/src/global_styles/layout/work_packages/_details_view.sass
  75. 3
      frontend/src/tsconfig.app.json

@ -51,11 +51,7 @@ module FrontendAssetHelper
concat javascript_include_tag variable_asset_path(file)
end
if FrontendAssetHelper.assets_proxied?
concat javascript_include_tag variable_asset_path("styles.js")
else
concat stylesheet_link_tag variable_asset_path("styles.css"), media: :all
end
concat stylesheet_link_tag variable_asset_path("styles.css"), media: :all
end
end

@ -89,8 +89,6 @@
"options": {
"browserTarget": "OpenProject:build",
"proxyConfig": "cli_to_rails_proxy.js",
"deployUrl": "/assets/frontend/",
"aot": true
},
"configurations": {
"production": {

File diff suppressed because it is too large Load Diff

@ -5,7 +5,7 @@
"version": "0.1.0",
"private": true,
"devDependencies": {
"@angular/language-service": "10.0.6",
"@angular/language-service": "11.0.6",
"@types/jasmine": "~3.5.7",
"@types/jasminewd2": "~2.0.8",
"@types/node": "^13.7.7",
@ -30,28 +30,27 @@
"tslint": "~6.1.0"
},
"dependencies": {
"@angular-devkit/build-angular": "^0.1002.0",
"@angular/animations": "10.0.6",
"@angular/cdk": "^10.1.1",
"@angular/cli": "^10.0.4",
"@angular/common": "10.0.6",
"@angular/compiler": "10.0.6",
"@angular/compiler-cli": "^10.0.6",
"@angular/core": "10.0.6",
"@angular/forms": "10.0.6",
"@angular/platform-browser": "10.0.6",
"@angular/platform-browser-dynamic": "10.0.6",
"@angular/router": "10.0.6",
"@fullcalendar/angular": "5.3.1",
"@fullcalendar/core": "5.3.1",
"@fullcalendar/daygrid": "5.3.1",
"@fullcalendar/interaction": "5.3.1",
"@fullcalendar/timegrid": "5.3.1",
"@angular-devkit/build-angular": "^0.1100.6",
"@angular/animations": "11.0.6",
"@angular/cdk": "^11.0.3",
"@angular/cli": "^11.0.6",
"@angular/common": "11.0.6",
"@angular/compiler": "11.0.6",
"@angular/compiler-cli": "^11.0.6",
"@angular/core": "11.0.6",
"@angular/forms": "11.0.6",
"@angular/platform-browser": "11.0.6",
"@angular/platform-browser-dynamic": "11.0.6",
"@angular/router": "11.0.6",
"@fullcalendar/angular": "5.5.0",
"@fullcalendar/core": "5.5.0",
"@fullcalendar/daygrid": "5.5.0",
"@fullcalendar/interaction": "5.5.0",
"@fullcalendar/timegrid": "5.5.0",
"@kolkov/ngx-gallery": "^1.0.11",
"@ng-select/ng-option-highlight": "0.0.5",
"@ng-select/ng-select": "^4.0.4",
"@sentry/browser": "^5.13.0",
"@types/resize-observer-browser": "^0.1.4",
"@types/assertion-error": "^1.1.0",
"@types/chart.js": "^2.9.20",
"@types/codemirror": "0.0.87",
@ -65,11 +64,12 @@
"@types/mousetrap": "^1.6.3",
"@types/pako": "^1.0.1",
"@types/promises-a-plus": "0.0.27",
"@types/resize-observer-browser": "^0.1.4",
"@types/rosie": "0.0.37",
"@types/urijs": "^1.19.6",
"@types/webpack-env": "^1.15.1",
"@uirouter/angular": "^7.0.0",
"@uirouter/core": "^6.0.6",
"@uirouter/angular": "^8.0.0",
"@uirouter/core": "^6.0.7",
"@uirouter/rx": "^0.6.5",
"@w11k/ngx-componentdestroyed": "^5.0.2",
"@xeokit/xeokit-bim-viewer": "^1.8.6",
@ -114,18 +114,17 @@
"ng2-charts": "^2.3.1",
"ng2-dragula": "^2.1.1",
"ngtemplate-loader": "^2.0.1",
"node-sass": "^4.14.1",
"observable-array": "0.0.4",
"reactivestates": "2.0.1",
"reflect-metadata": "^0.1.13",
"rxjs": "^6.6.0",
"rxjs": "^6.6.3",
"screenfull": "^4.2.1",
"shelljs": "^0.8.3",
"tablesorter": "^2.31.3",
"ticky": "^1.0.1",
"tslib": "^2.0.0",
"typedjson": "^1.5.1",
"typescript": "3.9.7",
"typescript": "^4.0.5",
"uglifyjs-webpack-plugin": "^2.2.0",
"ui-select": "~0.19.6",
"urijs": "^1.19.2",

@ -59,7 +59,7 @@ export type DateKeys = 'date'|'start'|'end';
encapsulation: ViewEncapsulation.None
})
export class DatePickerModal extends OpModalComponent implements AfterViewInit {
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
@InjectField() timezoneService:TimezoneService;
@InjectField() halEditing:HalResourceEditingService;
@InjectField() datepickerHelper:DatePickerModalHelper;

@ -20,12 +20,12 @@ import {splitViewRoute} from "core-app/modules/work_packages/routing/split-view-
export class WorkPackageViewContextMenu extends OpContextMenuHandler {
@InjectField() protected states:States;
@InjectField() protected states!:States;
@InjectField() protected wpRelationsHierarchyService:WorkPackageRelationsHierarchyService;
@InjectField() protected opModalService:OpModalService;
@InjectField() protected $state:StateService;
@InjectField() protected $state!:StateService;
@InjectField() protected wpTableSelection:WorkPackageViewSelectionService;
@InjectField() protected WorkPackageContextMenuHelper:WorkPackageContextMenuHelperService;
@InjectField() protected WorkPackageContextMenuHelper!:WorkPackageContextMenuHelperService;
@InjectField() protected timeEntryCreateService:TimeEntryCreateService;
protected workPackage = this.states.workPackages.get(this.workPackageId).value!;

@ -26,7 +26,7 @@
// See docs/COPYRIGHT.rdoc for more details.
// ++
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import {PathHelperService} from 'core-app/modules/common/path-helper/path-helper.service';
import {UserAvatarComponent} from "core-components/user/user-avatar/user-avatar.component";
import {APIV3Service} from "core-app/modules/apiv3/api-v3.service";
@ -38,7 +38,7 @@ describe('UserAvatar component test', () => {
let element:HTMLElement;
let user:any;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// noinspection JSIgnoredPromiseFromCall
TestBed.configureTestingModule({
@ -58,7 +58,7 @@ describe('UserAvatar component test', () => {
}));
describe('Regular initials', () => {
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
user = {
id: 1,
name: 'First Last',
@ -77,7 +77,7 @@ describe('UserAvatar component test', () => {
});
describe('Emoji initials', () => {
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
user = {
id: 1,
name: "\uFE0F Foo Bar",

@ -28,7 +28,7 @@
import {UserLinkComponent} from './user-link.component';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import {I18nService} from 'core-app/modules/common/i18n/i18n.service';
import {UserResource} from '../../../modules/hal/resources/user-resource';
import {PathHelperService} from 'core-app/modules/common/path-helper/path-helper.service';
@ -47,7 +47,7 @@ describe('UserLinkComponent component test', () => {
let element:HTMLElement;
let user:UserResource;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// noinspection JSIgnoredPromiseFromCall
TestBed.configureTestingModule({
@ -67,7 +67,7 @@ describe('UserLinkComponent component test', () => {
describe('inner element', function() {
describe('with the uer having the showUserPath attribute', function() {
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
user = {
name: 'First Last',
showUserPath: '/users/1'
@ -87,7 +87,7 @@ describe('UserLinkComponent component test', () => {
});
describe('with the user not having the showUserPath attribute', function() {
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
user = {
name: 'First Last',
showUserPath: null

@ -32,11 +32,6 @@ export abstract class WorkPackageCommentFieldHandler extends EditFieldHandler im
*/
public abstract handleUserSubmit():Promise<any>;
/**
* Required HTML id for the edit field
*/
public abstract get htmlId():string;
public abstract get workPackage():WorkPackageResource;
public reset(withText:string = '') {

@ -75,6 +75,8 @@ export class WorkPackageCommentComponent extends WorkPackageCommentFieldHandler
public canAddComment:boolean;
public showAbove:boolean;
public htmlId = 'wp-comment-field';
constructor(protected elementRef:ElementRef,
protected injector:Injector,
protected commentService:CommentService,
@ -117,10 +119,6 @@ export class WorkPackageCommentComponent extends WorkPackageCommentFieldHandler
return false;
}
public get htmlId() {
return 'wp-comment-field';
}
public activate(withText?:string) {
super.activate(withText);

@ -39,13 +39,10 @@ import {InjectField} from "core-app/helpers/angular/inject-field.decorator";
})
export class WorkPackageCommentFieldComponent extends FormattableEditFieldComponent implements OnInit {
public isBusy:boolean = false;
public name = 'comment';
@InjectField() public ConfigurationService:ConfigurationService;
public get name() {
return 'comment';
}
public get required() {
return true;
}

@ -98,6 +98,8 @@ export class UserActivityComponent extends WorkPackageCommentFieldHandler implem
public ngOnInit() {
super.ngOnInit();
this.htmlId = `user_activity_edit_field_${this.activityNo}`;
this.updateCommentText();
this.isComment = this.activity._type === 'Activity::Comment';
this.isBcfComment = this.activity._type === 'Activity::BcfComment';
@ -216,10 +218,6 @@ export class UserActivityComponent extends WorkPackageCommentFieldHandler implem
return this.userName + ' wrote:\n' + quoted;
}
public get htmlId() {
return `user_activity_edit_field_${this.activityNo}`;
}
deactivate(focus:boolean):void {
super.deactivate(focus);

@ -48,7 +48,7 @@ export const activeFieldClassName = 'inline-edit--field';
export class TableEditForm extends EditForm<WorkPackageResource> {
@InjectField() public wpTableColumns:WorkPackageViewColumnsService;
@InjectField() public apiV3Service:APIV3Service;
@InjectField() public apiV3Service!:APIV3Service;
@InjectField() public states:States;
@InjectField() public FocusHelper:FocusHelperService;
@InjectField() public editingPortalService:EditingPortalService;

@ -40,7 +40,7 @@ export abstract class PrimaryRenderPass {
@InjectField() halEditing:HalResourceEditingService;
@InjectField() states:States;
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
/** The rendered order of rows of work package IDs or <null>, if not a work package row */
public renderedOrder:RowRenderInfo[];

@ -27,7 +27,7 @@ export class SingleRowBuilder {
// Injections
@InjectField() wpTableSelection:WorkPackageViewSelectionService;
@InjectField() wpTableColumns:WorkPackageViewColumnsService;
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
// Cell builder instance
protected cellBuilder = new CellBuilder(this.injector);

@ -23,7 +23,7 @@ export class WorkPackageTable {
@InjectField() querySpace:IsolatedQuerySpace;
@InjectField() apiV3Service:APIV3Service;
@InjectField() states:States;
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
@InjectField() workPackageViewCollapsedGroupsService:WorkPackageViewCollapsedGroupsService;
public originalRows:string[] = [];

@ -37,7 +37,7 @@ import {InjectField} from "core-app/helpers/angular/inject-field.decorator";
@Injectable()
export class WorkPackageInlineCreateService implements OnDestroy {
@InjectField() protected readonly I18n:I18nService;
@InjectField() I18n!:I18nService;
@InjectField() protected readonly authorisationService:AuthorisationService;
constructor(readonly injector:Injector) {

@ -46,7 +46,6 @@ import {UntilDestroyedMixin} from "core-app/helpers/angular/until-destroyed.mixi
import {splitViewRoute} from "core-app/modules/work_packages/routing/split-view-routes.helper";
import {APIV3Service} from "core-app/modules/apiv3/api-v3.service";
import {HalSource, HalSourceLinks} from "core-app/modules/hal/resources/hal-resource";
import {HalLinkSource} from "core-app/modules/hal/hal-link/hal-link";
@Directive()
export class WorkPackageCreateComponent extends UntilDestroyedMixin implements OnInit {

@ -29,7 +29,7 @@ export abstract class WorkPackageEmbeddedBaseComponent extends WorkPackagesViewB
@InjectField() apiV3Service:APIV3Service;
@InjectField() querySpace:IsolatedQuerySpace;
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
@InjectField() urlParamsHelper:UrlParamsHelperService;
@InjectField() loadingIndicatorService:LoadingIndicatorService;
@InjectField() wpStatesInitialization:WorkPackageStatesInitializationService;

@ -11,7 +11,7 @@ export const contextColumnIcon = 'wp-table-context-menu-icon';
export abstract class OpTableAction {
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
constructor(readonly injector:Injector,
readonly workPackage:WorkPackageResource) {

@ -29,7 +29,7 @@
import {HttpClientModule} from '@angular/common/http';
import {IsolatedQuerySpace} from "core-app/modules/work_packages/query-space/isolated-query-space";
import {async, inject, TestBed} from '@angular/core/testing';
import { inject, TestBed, waitForAsync } from '@angular/core/testing';
import {States} from 'core-components/states.service';
import {PaginationInstance} from 'core-components/table-pagination/pagination-instance';
import {IPaginationOptions, PaginationService} from 'core-components/table-pagination/pagination-service';
@ -70,7 +70,7 @@ function pageString(element:JQuery) {
describe('wpTablePagination Directive', () => {
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
window.OpenProject = new OpenProject();
// noinspection JSIgnoredPromiseFromCall

@ -48,7 +48,7 @@ export class TimelineCellRenderer {
@InjectField() wpTableTimeline:WorkPackageViewTimelineService;
@InjectField() TimezoneService:TimezoneService;
@InjectField() schemaCache:SchemaCacheService;
@InjectField() readonly I18n:I18nService;
@InjectField() I18n!:I18nService;
public text = {
label_children_derived_duration: this.I18n.t('js.label_children_derived_duration')

@ -26,7 +26,7 @@
// See docs/COPYRIGHT.rdoc for more details.
// ++
import {async, TestBed} from "@angular/core/testing";
import { TestBed, waitForAsync } from "@angular/core/testing";
import {APIV3Service} from "core-app/modules/apiv3/api-v3.service";
import {PathHelperService} from "core-app/modules/common/path-helper/path-helper.service";
import {States} from "core-components/states.service";
@ -34,7 +34,7 @@ import {States} from "core-components/states.service";
describe('APIv3Service', function() {
let service:APIV3Service;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// noinspection JSIgnoredPromiseFromCall
TestBed.configureTestingModule({
providers: [

@ -26,7 +26,7 @@
// See docs/COPYRIGHT.rdoc for more details.
//++
import {async, TestBed} from "@angular/core/testing";
import { TestBed, waitForAsync } from "@angular/core/testing";
import {BcfApiService} from "core-app/modules/bim/bcf/api/bcf-api.service";
import {BcfResourceCollectionPath, BcfResourcePath} from "core-app/modules/bim/bcf/api/bcf-path-resources";
import {BcfTopicPaths} from "core-app/modules/bim/bcf/api/topics/bcf-topic.paths";
@ -34,7 +34,7 @@ import {BcfTopicPaths} from "core-app/modules/bim/bcf/api/topics/bcf-topic.paths
describe('BcfApiService', function () {
let service:BcfApiService;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// noinspection JSIgnoredPromiseFromCall
TestBed.configureTestingModule({
providers: [

@ -76,9 +76,7 @@ export class BoardAssigneeActionService extends CachedBoardActionService {
return super.getLoadedActionValue(query);
}
public get localizedName() {
return this.I18n.t('js.work_packages.properties.assignee');
}
localizedName = this.I18n.t('js.work_packages.properties.assignee');
public headerComponent() {
return AssigneeBoardHeaderComponent;

@ -20,9 +20,7 @@ export class BoardStatusActionService extends CachedBoardActionService {
image = ImageHelpers.imagePath('board_creation_modal/status.svg');
public get localizedName() {
return this.I18n.t('js.work_packages.properties.status');
}
localizedName = this.I18n.t('js.work_packages.properties.status');
headerComponent() {
return StatusBoardHeaderComponent;

@ -24,9 +24,7 @@ export class BoardSubprojectActionService extends CachedBoardActionService {
image = ImageHelpers.imagePath('board_creation_modal/subproject.svg');
get localizedName() {
return this.I18n.t('js.work_packages.properties.subproject');
}
localizedName = this.I18n.t('js.work_packages.properties.subproject');
headerComponent() {
return SubprojectBoardHeaderComponent;

@ -24,9 +24,7 @@ export class BoardSubtasksActionService extends BoardActionService {
image = ImageHelpers.imagePath('board_creation_modal/parent-child.svg');
public get localizedName() {
return this.I18n.t('js.boards.board_type.action_type.subtasks');
}
localizedName = this.I18n.t('js.boards.board_type.action_type.subtasks');
public headerComponent() {
return SubtasksBoardHeaderComponent;

@ -34,9 +34,7 @@ export class BoardVersionActionService extends CachedBoardActionService {
private writable$:Promise<boolean>;
public get localizedName() {
return this.I18n.t('js.work_packages.properties.version');
}
localizedName = this.I18n.t('js.work_packages.properties.version');
public canAddToQuery(query:QueryResource):Promise<boolean> {
const formLink = _.get(query, 'results.createWorkPackage.href', null);

@ -1,4 +1,4 @@
import {ComponentFixture, TestBed, async} from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import {DebugElement} from '@angular/core';
import {By} from '@angular/platform-browser';
import {TileViewComponent} from './tile-view.component';

@ -108,7 +108,7 @@ export class CreateAutocompleterComponent implements AfterViewInit {
// https://github.com/ng-select/ng-select/issues/1259
setTimeout(() => {
const component = this.ngSelectComponent as any;
if (component && component.dropdownPanel) {
if (this.appendTo && component && component.dropdownPanel) {
component.dropdownPanel._updatePosition();
}
}, 25);

@ -40,7 +40,6 @@ import {APIV3Service} from "core-app/modules/apiv3/api-v3.service";
selector: 'version-autocompleter'
})
export class VersionAutocompleterComponent extends CreateAutocompleterComponent implements AfterViewInit {
@Input() public openDirectly:boolean = false;
@Output() public onCreate = new EventEmitter<VersionResource>();
constructor(readonly I18n:I18nService,

@ -67,7 +67,7 @@ export class EditableToolbarTitleComponent implements OnInit, OnChanges {
public selectableTitleIdentifier = selectableTitleIdentifier;
@InjectField() protected readonly elementRef:ElementRef;
@InjectField() protected readonly I18n:I18nService;
@InjectField() I18n!:I18nService;
public text = {
click_to_edit: this.I18n.t('js.work_packages.query.click_to_edit_query_name'),

@ -3,7 +3,7 @@
align-items: center
grid-template-columns: auto auto 1fr
&::before
&::before,
&::after
display: block
content: ''

@ -26,7 +26,7 @@
// See docs/COPYRIGHT.rdoc for more details.
//++
import {async, ComponentFixture, TestBed} from "@angular/core/testing";
import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing";
import {OpIcon} from "core-app/modules/common/icon/op-icon";
import {By} from "@angular/platform-browser";
import {DebugElement} from "@angular/core";
@ -36,7 +36,7 @@ describe('opIcon Directive', function() {
let fixture:ComponentFixture<OpIcon>;
let element:DebugElement;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// noinspection JSIgnoredPromiseFromCall
TestBed.configureTestingModule({
declarations: [

@ -27,7 +27,7 @@
// ++
import {OpenprojectHalModule} from 'core-app/modules/hal/openproject-hal.module';
import {async, TestBed} from '@angular/core/testing';
import { TestBed, waitForAsync } from '@angular/core/testing';
import {NotificationsService} from 'core-app/modules/common/notifications/notifications.service';
import {ConfigurationService} from 'core-app/modules/common/config/configuration.service';
import {I18nService} from 'core-app/modules/common/i18n/i18n.service';
@ -35,7 +35,7 @@ import {I18nService} from 'core-app/modules/common/i18n/i18n.service';
describe('NotificationsService', function () {
var notificationsService:NotificationsService;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// noinspection JSIgnoredPromiseFromCall
TestBed.configureTestingModule({
imports: [

@ -28,7 +28,7 @@ export class DisplayFieldRenderer<T extends HalResource = HalResource> {
@InjectField() displayFieldService:DisplayFieldService;
@InjectField() schemaCache:SchemaCacheService;
@InjectField() halEditing:HalResourceEditingService;
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
/** We cache the previously used fields to avoid reinitialization */
private fieldCache:{ [key:string]:DisplayField } = {};

@ -40,7 +40,7 @@ export class DisplayField<T extends HalResource = HalResource> extends Field {
public mode:string | null = null;
public activeChange:ResourceChangeset<T>|null = null;
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
constructor(public name:string, public context:DisplayFieldContext) {
super();

@ -39,8 +39,8 @@ export class LinkedWorkPackageDisplayField extends WorkPackageDisplayField {
none: this.I18n.t('js.filter.noneElement')
};
@InjectField() $state:StateService;
@InjectField() keepTab:KeepTabService;
@InjectField() $state!:StateService;
@InjectField() keepTab!:KeepTabService;
private uiStateBuilder:UiStateLinkBuilder = new UiStateLinkBuilder(this.$state, this.keepTab);

@ -33,8 +33,8 @@ import {IdDisplayField} from "core-app/modules/fields/display/field-types/id-dis
import {InjectField} from "core-app/helpers/angular/inject-field.decorator";
export class WorkPackageIdDisplayField extends IdDisplayField {
@InjectField() $state:StateService;
@InjectField() keepTab:KeepTabService;
@InjectField() $state!:StateService;
@InjectField() keepTab!:KeepTabService;
private uiStateBuilder:UiStateLinkBuilder = new UiStateLinkBuilder(this.$state, this.keepTab);

@ -67,7 +67,8 @@ export abstract class EditFieldComponent extends Field implements OnInit, OnDest
readonly cdRef:ChangeDetectorRef,
readonly injector:Injector) {
super();
this.schema = this.schema || this.change.schema.ofProperty(this.name);
this.updateFromChangeset(change);
if (this.change.state) {
this.change.state
@ -82,8 +83,7 @@ export abstract class EditFieldComponent extends Field implements OnInit, OnDest
return handler.deactivate(false);
}
this.change = change;
this.schema = change.schema.ofProperty(this.name);
this.updateFromChangeset(change);
this.initialize();
this.cdRef.markForCheck();
});
@ -113,12 +113,6 @@ export abstract class EditFieldComponent extends Field implements OnInit, OnDest
return this.resource[this.name];
}
public get name() {
// Get the mapped schema name, as this is not always the attribute
// e.g., startDate in table for milestone => date attribute
return this.change.schema.mappedName(this.handler.fieldName);
}
public set value(value:any) {
this.resource[this.name] = this.parseValue(value);
}
@ -131,16 +125,25 @@ export abstract class EditFieldComponent extends Field implements OnInit, OnDest
return '';
}
public get resource() {
return this.change.projectedResource;
}
/**
* Initialize the field after constructor was called.
*/
protected initialize() {
}
/**
* Update resource and properties from changeset
*/
private updateFromChangeset(change:ResourceChangeset) {
this.change = change;
this.resource = this.change.projectedResource;
this.schema = this.change.schema.ofProperty(this.handler.fieldName) || this.schema;
// Get the mapped schema name, as this is not always the attribute
// e.g., startDate in table for milestone => date attribute
this.name = this.change.schema.mappedName(this.handler.fieldName);
}
/**
* Parse the value from the model for setting
*/

@ -35,13 +35,10 @@ export abstract class EditFieldHandler extends UntilDestroyedMixin {
* Whether the handler belongs to a larger edit mode form
* e.g., WP-create
*/
inEditMode:boolean;
/** Whether the field is currently active */
active:boolean;
abstract get inEditMode():boolean;
/** Whether the field is being saved */
inFlight:boolean;
abstract get inFlight():boolean;
/**
* Return a unique ID for this edit field
@ -66,7 +63,9 @@ export abstract class EditFieldHandler extends UntilDestroyedMixin {
/**
* Error messages on the field, if any.
*/
errorMessageOnLabel?:string;
public errorMessageOnLabel():string|undefined {
return undefined;
}
/**
* On destroy observable

@ -1,5 +1,5 @@
<div class="inplace-edit--dashboard">
<div class="inplace-edit--controls" *ngIf="field.handler.active">
<div class="inplace-edit--controls">
<accessible-by-keyboard (execute)="save()"
[attr.disabled]="(field.required && field.isEmpty()) || undefined"
[linkTitle]="saveTitle"

@ -45,7 +45,7 @@ export class HalResourceEditFieldHandler extends EditFieldHandler {
// Injections
@InjectField() FocusHelper:FocusHelperService;
@InjectField() ConfigurationService:ConfigurationService;
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
// Subject to fire when user demanded activation
public $onUserActivate = new Subject<void>();
@ -66,6 +66,9 @@ export class HalResourceEditFieldHandler extends EditFieldHandler {
if (withErrors !== undefined) {
this.setErrors(withErrors);
}
this.htmlId = `wp-${this.resource.id}-inline-edit--field-${this.fieldName}`;
this.fieldLabel = this.schema.name || this.fieldName;
}
/**
@ -84,10 +87,6 @@ export class HalResourceEditFieldHandler extends EditFieldHandler {
return this.form.change.inFlight;
}
public get active() {
return true;
}
public focus(setClickOffset?:number) {
const target = this.element.querySelector('.inline-edit--field') as HTMLElement;
@ -211,21 +210,7 @@ export class HalResourceEditFieldHandler extends EditFieldHandler {
return this.form.change.projectedResource.project;
}
/**
* Return a unique ID for this edit field
*/
public get htmlId() {
return `wp-${this.resource.id}-inline-edit--field-${this.fieldName}`;
}
/**
* Return the field label
*/
public get fieldLabel() {
return this.schema.name || this.fieldName;
}
public get errorMessageOnLabel() {
public errorMessageOnLabel() {
if (!this.isErrorenous) {
return '';
} else {

@ -40,7 +40,7 @@ import {InjectField} from "core-app/helpers/angular/inject-field.decorator";
})
export class MultiSelectEditFieldComponent extends EditFieldComponent implements OnInit {
@ViewChild(NgSelectComponent, { static: true }) public ngSelectComponent:NgSelectComponent;
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
public availableOptions:any[] = [];
public valueOptions:ValueOption[];

@ -39,7 +39,7 @@ import {InjectField} from "core-app/helpers/angular/inject-field.decorator";
})
export class ProjectStatusEditFieldComponent extends EditFieldComponent implements OnInit {
@ViewChild(NgSelectComponent, {static: true}) public ngSelectComponent:NgSelectComponent;
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
private _availableStatusCodes:string[] = ['not set', 'off track', 'at risk', 'on track'];
public currentStatusCode:string = 'not set';

@ -77,7 +77,7 @@ export class AttributeHelpTextsService {
.toPromise()
.then(() => {
const value = this.helpTexts.getValueOr([]);
return _.find(value, element => element.id.toString() === id);
return _.find(value, element => element.id?.toString() === id);
});
}

@ -31,7 +31,7 @@
import {CurrentProjectService} from "core-components/projects/current-project.service";
import {GlobalSearchService} from "core-app/modules/global_search/services/global-search.service";
import {I18nService} from "core-app/modules/common/i18n/i18n.service";
import {async, TestBed} from "@angular/core/testing";
import { TestBed, waitForAsync } from "@angular/core/testing";
import {PathHelperService} from "core-app/modules/common/path-helper/path-helper.service";
import {States} from "core-components/states.service";
import {APIV3Service} from "core-app/modules/apiv3/api-v3.service";
@ -41,7 +41,7 @@ describe('Global search service', function() {
let CurrentProject:CurrentProjectService;
let CurrentProjectSpy;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// noinspection JSIgnoredPromiseFromCall
TestBed.configureTestingModule({
providers: [

@ -12,13 +12,11 @@ import {SchemaResource} from "core-app/modules/hal/resources/schema-resource";
@Injectable()
export class CustomTextEditFieldService extends EditFieldHandler {
public fieldName = 'text';
public inEdit = false;
public inEditMode = false;
public inFlight = false;
public valueChanged$:BehaviorSubject<string>;
public changeset:ResourceChangeset;
public active:boolean;
constructor(protected elementRef:ElementRef,
protected injector:Injector,
@ -27,8 +25,6 @@ export class CustomTextEditFieldService extends EditFieldHandler {
super();
}
errorMessageOnLabel:string;
onFocusOut():void {
// interface
}
@ -92,17 +88,21 @@ export class CustomTextEditFieldService extends EditFieldHandler {
this.deactivate();
}
public get active() {
return this.inEdit;
deactivate():void {
this.changeset.clear();
this.active = false;
}
public activate(withText?:string) {
this.inEdit = true;
activate() {
this.active = true;
}
deactivate():void {
this.changeset.clear();
this.inEdit = false;
get inEditMode():boolean {
return false;
}
get inFlight():boolean {
return this.changeset.inFlight;
}
focus():void {
@ -133,16 +133,16 @@ export class CustomTextEditFieldService extends EditFieldHandler {
private initializeChangeset(value:GridWidgetResource) {
let schemaHref = 'customtext-schema';
let resourceSource = {
text: value.options.text,
getEditorTypeFor: () => 'full',
canAddAttachments: value.grid.canAddAttachments,
uploadAttachments: (files:UploadFile[]) => value.grid.uploadAttachments(files),
_links: {
schema: {
href: schemaHref
}
}
};
text: value.options.text,
getEditorTypeFor: () => 'full',
canAddAttachments: value.grid.canAddAttachments,
uploadAttachments: (files:UploadFile[]) => value.grid.uploadAttachments(files),
_links: {
schema: {
href: schemaHref
}
}
};
let resource = this.halResource.createHalResource(resourceSource, true);

@ -1,4 +1,4 @@
import { ComponentFixture, fakeAsync, TestBed, tick, async } from '@angular/core/testing';
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { WidgetNewsComponent } from './news.component';
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { TimezoneService } from 'core-app/components/datetime/timezone.service';
@ -72,7 +72,7 @@ describe('shows news', () => {
}));
it('should render the componenet successfully to show the news', async(() => {
it('should render the componenet successfully to show the news', waitForAsync(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
let newsItem = document.querySelector('li');
@ -80,7 +80,7 @@ describe('shows news', () => {
});
}));
it('should Not add the no-results component into DOM', async(() => {
it('should Not add the no-results component into DOM', waitForAsync(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
let newsItem = document.querySelector('no-results');
@ -88,7 +88,7 @@ describe('shows news', () => {
});
}));
it('should add the widget-header component into DOM', async(() => {
it('should add the widget-header component into DOM', waitForAsync(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
let newsItem = document.querySelector('widget-header');
@ -96,7 +96,7 @@ describe('shows news', () => {
});
}));
it('should show summary of news', async(() => {
it('should show summary of news', waitForAsync(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
@ -106,7 +106,7 @@ describe('shows news', () => {
});
}));
it('should Not add the user-avatar component into DOM', async(() => {
it('should Not add the user-avatar component into DOM', waitForAsync(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {

@ -35,7 +35,6 @@ export interface CustomActionResourceLinks {
}
export class CustomActionResource extends HalResource {
public name:string;
public description:string;
}

@ -38,7 +38,6 @@ export interface GridResourceLinks {
export class GridBaseResource extends HalResource {
public widgets:GridWidgetResource[];
public name:string;
public options:{[key:string]:unknown};
public rowCount:number;
public columnCount:number;

@ -29,5 +29,4 @@
import {HalResource} from 'core-app/modules/hal/resources/hal-resource';
export class GroupResource extends HalResource {
public name:string;
}

@ -27,7 +27,7 @@
//++
import {Injector} from '@angular/core';
import {async, TestBed} from '@angular/core/testing';
import { TestBed, waitForAsync } from '@angular/core/testing';
import {I18nService} from 'core-app/modules/common/i18n/i18n.service';
import {HalLink, HalLinkInterface} from 'core-app/modules/hal/hal-link/hal-link';
import {OpenprojectHalModule} from 'core-app/modules/hal/openproject-hal.module';
@ -47,7 +47,7 @@ describe('HalResource', () => {
class OtherResource extends HalResource {
}
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// noinspection JSIgnoredPromiseFromCall
TestBed.configureTestingModule({
imports: [

@ -74,7 +74,7 @@ export class HalResource {
public $halType:string;
@InjectField() states:States;
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
/**
* Constructs and initializes the HalResource. For this, the halResoureFactory is required.

@ -31,8 +31,6 @@ import {CallableHalLink} from 'core-app/modules/hal/hal-link/hal-link';
import {Attachable} from "core-app/modules/hal/resources/mixins/attachable-mixin";
export class HelpTextBaseResource extends HalResource {
public id:string;
public attribute:string;
public attributeCaption:string;
public scope:string;

@ -51,10 +51,7 @@ export class QueryFilterInstanceSchemaResource extends SchemaResource {
public filter:SchemaAttributeObject<QueryFilterResource>;
public dependency:SchemaDependencyResource;
public values:SchemaAttributeObject|null;
public get _type() {
return 'QueryFilterInstanceSchema';
}
public type = 'QueryFilterInstanceSchema';
public get availableOperators():HalResource[] | CollectionResource {
return this.operator.allowedValues;

@ -29,5 +29,4 @@
import {HalResource} from 'core-app/modules/hal/resources/hal-resource';
export class QueryGroupByResource extends HalResource {
public id:string;
}

@ -73,7 +73,6 @@ export class RelationResource extends HalResource {
// Properties
public description:string|null;
public name:string;
public type:any;
public reverseType:string;

@ -35,7 +35,6 @@ export class UserResource extends HalResource {
public login:string;
public firstName:string;
public lastName:string;
public name:string;
public email:string;
public avatar:string;
public status:string;

@ -26,7 +26,7 @@
// See docs/COPYRIGHT.rdoc for more details.
//++
import {async, TestBed} from '@angular/core/testing';
import { TestBed, waitForAsync } from '@angular/core/testing';
import {OpenprojectHalModule} from 'core-app/modules/hal/openproject-hal.module';
import {HalResourceService} from 'core-app/modules/hal/services/hal-resource.service';
import {Injector} from '@angular/core';
@ -63,7 +63,7 @@ describe('WorkPackage', () => {
workPackage = halResourceService.createHalResourceOfType('WorkPackage', { ...source });
};
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
// noinspection JSIgnoredPromiseFromCall
TestBed.configureTestingModule({
imports: [

@ -122,7 +122,7 @@ export class WorkPackageBaseResource extends HalResource {
public activities:CollectionResource;
public attachments:AttachmentCollectionResource;
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
@InjectField() states:States;
@InjectField() wpActivity:WorkPackagesActivityService;
@InjectField() apiV3Service:APIV3Service;

@ -34,7 +34,7 @@ export class TriggerActionsEntryComponent {
@InjectField() readonly apiv3Service:APIV3Service;
@InjectField() readonly notificationsService:NotificationsService;
@InjectField() readonly elementRef:ElementRef;
@InjectField() readonly i18n:I18nService;
@InjectField() i18n!:I18nService;
@InjectField() readonly cdRef:ChangeDetectorRef;
public text = {

@ -65,7 +65,7 @@ export type ViewPartitionState = '-split'|'-left-only'|'-right-only';
]
})
export class PartitionedQuerySpacePageComponent extends WorkPackagesViewBase implements OnInit, OnDestroy {
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
@InjectField() titleService:OpTitleService;
@InjectField() queryParamListener:QueryParamListenerService;

@ -33,6 +33,7 @@ import {States} from 'core-components/states.service';
import {IsolatedQuerySpace} from "core-app/modules/work_packages/query-space/isolated-query-space";
import {Injectable} from '@angular/core';
import {QueryColumn} from "core-components/wp-query/query-column";
import {HalResource} from "core-app/modules/hal/resources/hal-resource";
@Injectable()
export class WorkPackageViewGroupByService extends WorkPackageQueryStateService<QueryGroupByResource|null> {
@ -46,7 +47,7 @@ export class WorkPackageViewGroupByService extends WorkPackageQueryStateService<
}
public hasChanged(query:QueryResource) {
const comparer = (groupBy:QueryColumn|null|undefined) => groupBy ? groupBy.href : null;
const comparer = (groupBy:QueryColumn|HalResource|null|undefined) => groupBy ? groupBy.href : null;
return !_.isEqual(
comparer(query.groupBy),

@ -28,7 +28,7 @@
/*jshint expr: true*/
import {async, TestBed} from "@angular/core/testing";
import { TestBed, waitForAsync } from "@angular/core/testing";
import {States} from "core-components/states.service";
import {IsolatedQuerySpace} from "core-app/modules/work_packages/query-space/isolated-query-space";
import {WorkPackageViewHierarchiesService} from "core-app/modules/work_packages/routing/wp-view-base/view-services/wp-view-hierarchy.service";
@ -62,7 +62,7 @@ describe('WorkPackageViewIndentation service', function () {
};
}
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
parentServiceSpy = jasmine.createSpyObj(
'WorkPackageRelationHierarchyService',
['changeParent']

@ -46,7 +46,7 @@ import {catchError, subscribeOn} from "rxjs/operators";
export class WorkPackageSingleViewBase extends UntilDestroyedMixin {
@InjectField() states:States;
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
@InjectField() keepTab:KeepTabService;
@InjectField() PathHelper:PathHelperService;
@InjectField() halEditing:HalResourceEditingService;

@ -77,7 +77,7 @@ export abstract class WorkPackagesViewBase extends UntilDestroyedMixin implement
@InjectField() wpListChecksumService:WorkPackagesListChecksumService;
@InjectField() loadingIndicatorService:LoadingIndicatorService;
@InjectField() $transitions:TransitionService;
@InjectField() I18n:I18nService;
@InjectField() I18n!:I18nService;
@InjectField() wpStaticQueries:WorkPackageStaticQueriesService;
@InjectField() wpStatesInitialization:WorkPackageStatesInitializationService;
@InjectField() cdRef:ChangeDetectorRef;

@ -1,6 +1,6 @@
.op-uc-image
max-width: 100%;
max-height: 100%;
max-width: 100%
max-height: 100%
// Needed to override built-in ckeditor styles
@at-root .op-uc-container .image &

@ -15,8 +15,8 @@
display: block
overflow: hidden
font-size: var(--wiki-default-font-size)
z-index: 0;
padding-bottom: 1rem;
z-index: 0
padding-bottom: 1rem
// TODO: This becomes obsolete once border-box is the default
box-sizing: border-box

@ -14,7 +14,7 @@
&--cell
text-align: left
min-width: 3em;
min-width: 3em
padding: 0.75rem
&:not(:last-child):not([colspan])

@ -9,7 +9,7 @@
&--list
padding-left: 1rem
margin: 0;
margin: 0
list-style: none
&--list-item

@ -107,7 +107,7 @@ html:not(.-browser-mobile)
width: 60px
// Override the default td line-height
line-height: initial !important
white-space: nowrap;
white-space: nowrap
// Show context menu button when hovering
.wp-table--context-menu-td a

@ -70,7 +70,7 @@ body.router--work-packages-partitioned-split-view-new
padding: 0 1rem 10px
@media print
display: none;
display: none
.button
margin: .5rem .5rem 0 0

@ -9,9 +9,10 @@
"main.ts",
"polyfills.ts",
"app/init-globals.ts",
"app/init-vendors"
"app/init-vendors.ts"
],
"include": [
"src/**/*.ts",
"**/*.d.ts",
"app/modules/augmenting/dynamic-scripts/*.ts"
]

Loading…
Cancel
Save