From 25ecdfb0b23ad05c30859b43940244e1c7453d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Fri, 23 Mar 2018 11:13:45 +0100 Subject: [PATCH] WIP --- frontend/app/angular4-modules.ts | 34 +- .../angular/simple-template-renderer.ts | 2 +- .../api-v3/hal-link/hal-link.service.test.ts | 291 ------- .../hal-request/hal-request.service.test.ts | 241 ------ .../relations-dm.service.test.ts | 114 --- .../hal-changeset-proxy.ts | 23 - .../hal-resource-factory.service.test.ts | 109 --- .../hal-resource-types.config.ts | 92 --- .../hal-resource-types.service.test.ts | 133 ---- .../hal-resource-types.service.ts | 85 -- ...chment-collection-resource.service.test.ts | 74 -- .../attachment-collection-resource.service.ts | 60 -- .../collection-resource.service.test.ts | 76 -- .../custom-action-resource.service.ts | 55 -- .../hal-resource.service.test.ts | 726 ------------------ .../hal-resources/hal-resource.service.ts | 394 ---------- .../query-schema-resource.service.ts | 41 - .../work-package-resource.service.test.ts | 455 ----------- .../api-work-packages.service.ts | 60 +- .../caching/cache-service.service.ts | 141 ---- .../common/authoring/authoring.component.ts | 2 +- .../date/op-date-time.upgraded.directive.ts | 2 +- .../attribute-help-text.directive.ts | 6 +- .../help-texts/attribute-help-text.service.ts | 21 +- .../common/textile/textile-service.ts | 6 +- ...tract-filter-date-time-value.controller.ts | 2 +- .../filter-boolean-value.directive.ts | 2 +- .../filter-date-time-value.directive.ts | 2 +- .../filter-date-times-value.directive.ts | 2 +- .../filter-date-value.directive.ts | 2 +- .../filter-dates-value.directive.ts | 2 +- .../filter-integer-value.directive.ts | 6 +- .../filter-string-value.directive.ts | 2 +- ...oggled-multiselect-value.directive.test.ts | 2 +- ...ter-toggled-multiselect-value.directive.ts | 19 +- .../query-filter/query-filter.directive.ts | 8 +- .../query-filters/query-filters.directive.ts | 10 +- .../confirm-dialog/confirm-dialog.service.ts | 2 +- .../export-modal/export-modal.controller.ts | 16 +- .../save-modal/save-modal.controller.ts | 5 +- .../share-modal/share-modal.controller.ts | 2 +- .../sorting-modal/sorting-modal.controller.ts | 2 +- .../wp-destroy-modal.controller.ts | 12 +- .../op-settings-dropdown-menu.directive.ts | 4 +- .../op-types-context-menu.directive.ts | 4 +- .../wp-create-settings-menu.directive.ts | 6 +- .../wp-status-dropdown-menu.directive.ts | 8 +- .../wp-context-menu/wp-single-context-menu.ts | 4 +- .../wp-full-view/wp-full-view.component.ts | 8 +- .../routing/wp-list/wp-list.component.ts | 2 +- .../wp-view-base/wp-view-base.controller.ts | 6 +- .../schemas/schema-cache.service.ts | 17 +- frontend/app/components/states.service.ts | 16 +- .../table-pagination/pagination-service.ts | 6 +- .../user/user-link/user-link.directive.ts | 2 +- .../user-link/user-link.upgraded.component.ts | 2 +- .../work-package-authorization.service.ts | 4 +- .../work-package-cache.service.test.ts | 35 +- .../work-package-cache.service.ts | 28 +- .../work-package-comment.directive.ts | 6 +- ...work-package-comment.directive.upgraded.ts | 6 +- .../wp-comment-field.module.ts | 4 +- .../models/drop-model.ts | 4 +- .../models/work-package-field-model.ts | 7 +- .../wp-attachments-formattable.directive.ts | 8 +- .../wp-breadcrumb/wp-breadcrumb.component.ts | 4 +- .../wp-editor-field.component.ts | 4 +- .../wp-single-view.component.ts | 12 +- .../wp-subject/wp-subject.component.ts | 14 +- .../wp-type-status.component.ts | 4 +- .../wp-watcher-button.component.ts | 16 +- .../activity-entry.directive.upgraded.ts | 8 +- .../wp-activity/activity-service.ts | 8 +- .../revision-activity-directive.test.ts | 131 ---- .../user/user-activity-directive.ts | 9 +- .../wp-attachment-list-item.component.ts | 6 +- .../wp-attachment-list.component.ts | 6 +- .../wp-attachments-upload-ng1-wrapper.ts | 4 +- .../wp-attachments-upload.directive.ts | 4 +- .../wp-status-button.component.ts | 4 +- .../wp-timeline-toggle-button.component.ts | 2 +- .../components/wp-copy/wp-copy.controller.ts | 10 +- .../wp-custom-actions.component.ts | 2 +- .../wp-custom-action.component.ts | 20 +- .../wp-details-toolbar.component.ts | 4 +- .../wp-display-duration-field.module.ts | 3 +- .../wp-display-float-field.module.ts | 2 +- .../wp-display-formattable-field.module.ts | 2 +- .../field-types/wp-display-id-field.module.ts | 4 +- .../wp-display-resources-field.module.ts | 4 +- .../wp-display-spent-time-field.module.ts | 3 +- .../wp-display-work-package-field.module.ts | 3 +- .../wp-display-field.module.ts | 6 +- .../wp-edit-form/display-field-renderer.ts | 14 +- .../wp-edit-form/single-view-edit-context.ts | 6 +- .../wp-edit-form/table-row-edit-context.ts | 14 +- .../wp-edit-form/work-package-changeset.ts | 50 +- .../wp-edit-form/work-package-edit-context.ts | 9 +- .../work-package-edit-field-handler.ts | 4 - .../wp-edit-form/work-package-edit-form.ts | 20 +- .../work-package-editing-service.ts | 12 +- .../work-package-filter-values.ts | 14 +- .../wp-edit-multi-select-field.module.ts | 4 +- .../wp-edit-select-field.module.ts | 5 +- .../wp-edit-wiki-textarea-field.module.ts | 3 +- .../wp-edit-field-group.directive.ts | 20 +- .../wp-edit-field/wp-edit-field.component.ts | 6 +- .../wp-edit/wp-notification.service.ts | 16 +- .../wp-fast-table/builders/cell-builder.ts | 6 +- .../modes/grouped/group-header-builder.ts | 2 +- .../modes/grouped/grouped-render-pass.ts | 8 +- .../modes/grouped/grouped-rows-builder.ts | 2 +- .../modes/grouped/grouped-rows-helpers.ts | 2 +- .../modes/hierarchy/hierarchy-render-pass.ts | 30 +- .../hierarchy/single-hierarchy-row-builder.ts | 14 +- .../builders/primary-render-pass.ts | 10 +- .../builders/relation-cell-builder.ts | 8 +- .../relations/relation-row-builder.ts | 19 +- .../relations/relations-render-pass.ts | 6 +- .../builders/rows/single-row-builder.ts | 17 +- .../builders/table-action-renderer.ts | 4 +- .../handlers/row/wp-state-links-handler.ts | 2 +- .../handlers/state/rows-transformer.ts | 6 +- .../helpers/wp-table-hierarchy-helpers.ts | 4 +- .../wp-table-additional-elements.service.ts | 12 +- .../state/wp-table-base.service.ts | 13 +- .../state/wp-table-columns.service.ts | 2 +- .../state/wp-table-filters.service.ts | 21 +- .../state/wp-table-group-by.service.ts | 6 +- .../state/wp-table-hierarchy.service.ts | 7 +- .../state/wp-table-pagination.service.ts | 6 +- .../wp-table-relation-columns.service.ts | 19 +- .../state/wp-table-selection.service.ts | 14 +- .../state/wp-table-sort-by.service.ts | 16 +- .../state/wp-table-sum.service.ts | 2 +- .../state/wp-table-timeline.service.ts | 19 +- .../components/wp-fast-table/wp-fast-table.ts | 10 +- .../wp-fast-table/wp-table-columns.ts | 6 +- .../wp-fast-table/wp-table-editing.ts | 4 +- .../wp-fast-table/wp-table-filters.ts | 10 +- .../wp-fast-table/wp-table-group-by.ts | 6 +- .../wp-fast-table/wp-table-pagination.ts | 2 +- .../wp-fast-table/wp-table-sort-by.ts | 10 +- .../wp-fast-table/wp-table-timeline.ts | 6 +- .../wp-fast-table/wp-table.interfaces.ts | 12 +- .../components/wp-field/wp-field.module.ts | 2 +- .../inline-create-row-builder.ts | 8 +- .../wp-inline-create.component.ts | 10 +- .../wp-list/wp-list-checksum.service.ts | 2 +- .../wp-list/wp-list-invalid-query.service.ts | 16 +- .../app/components/wp-list/wp-list.service.ts | 57 +- .../wp-states-initialization.service.ts | 17 +- .../components/wp-new/wp-create.controller.ts | 16 +- .../components/wp-new/wp-create.service.ts | 22 +- .../wp-query-select-dropdown.component.ts | 4 +- .../app/components/wp-query/query-column.ts | 2 +- .../components/wp-query/url-params-helper.ts | 4 +- .../ng1-wp-relations-wrapper.directive.ts | 4 +- .../wp-relation-add-child.ts | 4 +- .../wp-relation-row.directive.ts | 25 +- .../ng1-wp-relations-create.directive.ts | 4 +- .../wp-relations-autocomplete.directive.ts | 10 +- ...lations-autocomplete.upgraded.component.ts | 12 +- .../wp-relations-create.directive.ts | 29 +- .../wp-relations-group.directive.ts | 6 +- .../wp-relations-hierarchy-row.directive.ts | 6 +- .../wp-relations-hierarchy.directive.ts | 16 +- .../wp-relations-hierarchy.service.ts | 18 +- .../wp-relations-parent.component.ts | 6 +- .../wp-relations/wp-relations.directive.ts | 26 +- .../wp-relations/wp-relations.interfaces.ts | 4 +- .../wp-relations/wp-relations.service.ts | 33 +- .../wp-single-relation.directive.ts | 4 +- .../activity-base.controller.ts | 8 +- .../activity-on-overview.component.ts | 6 +- .../activity-panel/activity-tab.component.ts | 6 +- .../activity-panel/wp-activity.service.ts | 10 +- .../overview-tab/overview-tab.component.ts | 4 +- .../relations-tab/relations-tab.component.ts | 4 +- .../watchers-tab/watchers-tab.component.ts | 10 +- .../wp-watcher-entry.component.ts | 2 +- .../wp-context-menu-helper.service.ts | 10 +- .../embedded/wp-embedded-table.component.ts | 13 +- .../sort-header/sort-header.directive.ts | 31 +- .../actions/unlink-table-action.ts | 10 +- .../wp-table/table-actions/table-action.ts | 6 +- .../table-actions/table-actions.service.ts | 4 +- .../wp-table-pagination.component.ng2.test.ts | 9 +- .../wp-table-pagination.component.ts | 2 - .../wp-table/table-state/table-state.ts | 19 +- .../timeline/cells/timeline-cell-renderer.ts | 8 +- .../cells/timeline-milestone-cell-renderer.ts | 6 +- .../cells/wp-timeline-cell-mouse-handler.ts | 27 +- .../timeline/cells/wp-timeline-cell.ts | 4 +- .../wp-timeline-container.directive.ts | 20 +- .../timeline-relation-element.ts | 8 +- .../grid/wp-timeline-grid.directive.ts | 2 +- .../header/wp-timeline-header.directive.ts | 2 +- .../wp-table/timeline/wp-timeline.ts | 19 +- .../wp-table-sums-row.directive.ts | 8 +- .../components/wp-table/wp-table.directive.ts | 4 +- .../dm-services}/configuration-dm.service.ts | 13 +- .../dm-services}/help-text-dm.service.ts | 24 +- .../dm-services}/payload-dm.service.ts | 10 +- .../dm-services}/query-dm.service.ts | 82 +- .../dm-services}/query-form-dm.service.ts | 19 +- .../dm-services}/relations-dm.service.ts | 44 +- .../dm-services}/root-dm.service.ts | 18 +- .../dm-services/type-dm.service.ts} | 67 +- .../modules/hal/hal-link/hal-link.service.ts | 64 ++ .../hal/hal-link/hal-link.ts} | 68 +- .../hal/helpers/hal-resource-builder.ts | 162 ++++ .../app/modules/hal/helpers/lazy-accessor.ts | 64 ++ .../app/modules/hal/openproject-hal.module.ts | 46 ++ .../attachment-collection-resource.ts} | 29 +- .../hal/resources/collection-resource.ts} | 23 +- .../hal/resources/configuration-resource.ts} | 18 +- .../hal/resources/custom-action-resource.ts | 44 ++ .../hal/resources/error-resource.ts} | 31 +- .../modules/hal/resources/form-resource.ts | 60 ++ .../app/modules/hal/resources/hal-resource.ts | 209 +++++ .../hal/resources/help-text-resource.ts} | 14 +- .../hal/resources/project-resource.ts} | 17 +- .../query-filter-instance-resource.ts} | 30 +- .../query-filter-instance-schema-resource.ts} | 34 +- .../hal/resources/query-filter-resource.ts} | 18 +- .../hal/resources/query-form-resource.ts} | 23 +- .../hal/resources/query-group-by-resource.ts} | 18 +- .../hal/resources/query-operator-resource.ts} | 20 +- .../hal/resources/query-resource.ts} | 31 +- .../hal/resources/query-schema-resource.ts | 41 + .../hal/resources/query-sort-by-resource.ts} | 14 +- .../hal/resources/relation-resource.ts} | 38 +- .../app/modules/hal/resources/resources.ts | 53 ++ .../hal/resources/root-resource.ts} | 18 +- .../resources/schema-dependency-resource.ts} | 12 +- .../hal/resources/schema-resource.ts} | 30 +- .../modules/hal/resources/type-resource.ts | 38 + .../hal/resources/user-resource.ts} | 10 +- .../hal/resources/work-package-resource.ts} | 182 ++--- .../hal/resources/wp-collection-resource.ts} | 43 +- .../hal/services}/hal-request.service.ts | 92 +-- .../services/hal-resource-factory.config.ts | 143 ++++ .../services}/hal-resource-factory.service.ts | 128 ++- frontend/npm-shrinkwrap.json | 6 + frontend/package.json | 1 + frontend/webpack-main-config.js | 14 +- 247 files changed, 2178 insertions(+), 4981 deletions(-) delete mode 100644 frontend/app/components/api/api-v3/hal-link/hal-link.service.test.ts delete mode 100644 frontend/app/components/api/api-v3/hal-request/hal-request.service.test.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resource-dms/relations-dm.service.test.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resource-factory/hal-changeset-proxy.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resource-factory/hal-resource-factory.service.test.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resource-types/hal-resource-types.config.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resource-types/hal-resource-types.service.test.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resource-types/hal-resource-types.service.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resources/attachment-collection-resource.service.test.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resources/attachment-collection-resource.service.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resources/collection-resource.service.test.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resources/custom-action-resource.service.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resources/hal-resource.service.test.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resources/hal-resource.service.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resources/query-schema-resource.service.ts delete mode 100644 frontend/app/components/api/api-v3/hal-resources/work-package-resource.service.test.ts delete mode 100644 frontend/app/components/caching/cache-service.service.ts delete mode 100644 frontend/app/components/wp-activity/revision/revision-activity-directive.test.ts rename frontend/app/{components/api/api-v3/hal-resource-dms => modules/dm-services}/configuration-dm.service.ts (79%) rename frontend/app/{components/api/api-v3/hal-resource-dms => modules/dm-services}/help-text-dm.service.ts (66%) rename frontend/app/{components/api/api-v3/hal-resource-dms => modules/dm-services}/payload-dm.service.ts (88%) rename frontend/app/{components/api/api-v3/hal-resource-dms => modules/dm-services}/query-dm.service.ts (64%) rename frontend/app/{components/api/api-v3/hal-resource-dms => modules/dm-services}/query-form-dm.service.ts (80%) rename frontend/app/{components/api/api-v3/hal-resource-dms => modules/dm-services}/relations-dm.service.ts (57%) rename frontend/app/{components/api/api-v3/hal-resource-dms => modules/dm-services}/root-dm.service.ts (73%) rename frontend/app/{components/api/api-v3/hal-resources/type-resource.service.ts => modules/dm-services/type-dm.service.ts} (51%) create mode 100644 frontend/app/modules/hal/hal-link/hal-link.service.ts rename frontend/app/{components/api/api-v3/hal-link/hal-link.service.ts => modules/hal/hal-link/hal-link.ts} (65%) create mode 100644 frontend/app/modules/hal/helpers/hal-resource-builder.ts create mode 100644 frontend/app/modules/hal/helpers/lazy-accessor.ts create mode 100644 frontend/app/modules/hal/openproject-hal.module.ts rename frontend/app/{components/api/api-v3/hal-resources/form-resource.service.ts => modules/hal/resources/attachment-collection-resource.ts} (64%) rename frontend/app/{components/api/api-v3/hal-resources/collection-resource.service.ts => modules/hal/resources/collection-resource.ts} (73%) rename frontend/app/{components/api/api-v3/hal-resources/configuration-resource.service.ts => modules/hal/resources/configuration-resource.ts} (72%) create mode 100644 frontend/app/modules/hal/resources/custom-action-resource.ts rename frontend/app/{components/api/api-v3/hal-resources/error-resource.service.ts => modules/hal/resources/error-resource.ts} (80%) create mode 100644 frontend/app/modules/hal/resources/form-resource.ts create mode 100644 frontend/app/modules/hal/resources/hal-resource.ts rename frontend/app/{components/api/api-v3/hal-resources/help-text-resource.service.ts => modules/hal/resources/help-text-resource.ts} (77%) rename frontend/app/{components/api/api-v3/hal-resources/project-resource.service.ts => modules/hal/resources/project-resource.ts} (77%) rename frontend/app/{components/api/api-v3/hal-resources/query-filter-instance-resource.service.ts => modules/hal/resources/query-filter-instance-resource.ts} (77%) rename frontend/app/{components/api/api-v3/hal-resources/query-filter-instance-schema-resource.service.ts => modules/hal/resources/query-filter-instance-schema-resource.ts} (68%) rename frontend/app/{components/api/api-v3/hal-resources/query-filter-resource.service.ts => modules/hal/resources/query-filter-resource.ts} (75%) rename frontend/app/{components/api/api-v3/hal-resources/query-form-resource.service.ts => modules/hal/resources/query-form-resource.ts} (73%) rename frontend/app/{components/api/api-v3/hal-resources/query-group-by-resource.service.ts => modules/hal/resources/query-group-by-resource.ts} (73%) rename frontend/app/{components/api/api-v3/hal-resources/query-operator-resource.service.ts => modules/hal/resources/query-operator-resource.ts} (75%) rename frontend/app/{components/api/api-v3/hal-resources/query-resource.service.ts => modules/hal/resources/query-resource.ts} (72%) create mode 100644 frontend/app/modules/hal/resources/query-schema-resource.ts rename frontend/app/{components/api/api-v3/hal-resources/query-sort-by-resource.service.ts => modules/hal/resources/query-sort-by-resource.ts} (81%) rename frontend/app/{components/api/api-v3/hal-resources/relation-resource.service.ts => modules/hal/resources/relation-resource.ts} (74%) create mode 100644 frontend/app/modules/hal/resources/resources.ts rename frontend/app/{components/api/api-v3/hal-resources/root-resource.service.ts => modules/hal/resources/root-resource.ts} (73%) rename frontend/app/{components/api/api-v3/hal-resources/schema-dependency-resource.service.ts => modules/hal/resources/schema-dependency-resource.ts} (80%) rename frontend/app/{components/api/api-v3/hal-resources/schema-resource.service.ts => modules/hal/resources/schema-resource.ts} (77%) create mode 100644 frontend/app/modules/hal/resources/type-resource.ts rename frontend/app/{components/api/api-v3/hal-resources/user-resource.service.ts => modules/hal/resources/user-resource.ts} (89%) rename frontend/app/{components/api/api-v3/hal-resources/work-package-resource.service.ts => modules/hal/resources/work-package-resource.ts} (65%) rename frontend/app/{components/api/api-v3/hal-resources/wp-collection-resource.service.ts => modules/hal/resources/wp-collection-resource.ts} (60%) rename frontend/app/{components/api/api-v3/hal-request => modules/hal/services}/hal-request.service.ts (64%) create mode 100644 frontend/app/modules/hal/services/hal-resource-factory.config.ts rename frontend/app/{components/api/api-v3/hal-resource-factory => modules/hal/services}/hal-resource-factory.service.ts (54%) diff --git a/frontend/app/angular4-modules.ts b/frontend/app/angular4-modules.ts index d63789b20a..1692a76c95 100644 --- a/frontend/app/angular4-modules.ts +++ b/frontend/app/angular4-modules.ts @@ -26,7 +26,7 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {InjectionToken, NgModule} from '@angular/core'; +import {NgModule} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {UpgradeModule} from '@angular/upgrade/static'; import {FormsModule} from '@angular/forms'; @@ -49,9 +49,7 @@ import {WorkPackageTableRelationColumnsService} from 'core-components/wp-fast-ta import {WorkPackageTableSelection} from 'core-components/wp-fast-table/state/wp-table-selection.service'; import {WorkPackageTableSortByService} from 'core-components/wp-fast-table/state/wp-table-sort-by.service'; import {WorkPackageTableTimelineService} from 'core-components/wp-fast-table/state/wp-table-timeline.service'; -import { - WorkPackageInlineCreateComponent, -} from 'core-components/wp-inline-create/wp-inline-create.component'; +import {WorkPackageInlineCreateComponent,} from 'core-components/wp-inline-create/wp-inline-create.component'; import {KeepTabService} from 'core-components/wp-single-view-tabs/keep-tab/keep-tab.service'; import {WorkPackageRelationsService} from 'core-components/wp-relations/wp-relations.service'; import {WpResizerDirectiveUpgraded} from 'core-components/wp-resizer/wp-resizer.directive'; @@ -71,14 +69,21 @@ import { $rootScopeToken, $stateToken, $timeoutToken, - columnsModalToken, exportModalToken, - FocusHelperToken, groupingModalToken, - halRequestToken, HalResourceToken, + columnsModalToken, + exportModalToken, + FocusHelperToken, + groupingModalToken, + halRequestToken, + HalResourceToken, HookServiceToken, I18nToken, NotificationsServiceToken, - PathHelperToken, QueryFilterInstanceResourceToken, QueryResourceToken, saveModalToken, - settingsModalToken, shareModalToken, + PathHelperToken, + QueryFilterInstanceResourceToken, + QueryResourceToken, + saveModalToken, + settingsModalToken, + shareModalToken, sortingModalToken, timelinesModalToken, TimezoneServiceToken, @@ -149,7 +154,6 @@ import {WorkPackageWatcherEntryComponent} from 'core-components/wp-single-view-t import {WorkPackageNewFullViewComponent} from 'core-components/wp-new/wp-new-full-view.component'; import {WorkPackageTypeStatusComponent} from 'core-components/work-packages/wp-type-status/wp-type-status.component'; import {WorkPackageEditActionsBarComponent} from 'core-components/common/edit-actions-bar/wp-edit-actions-bar.component'; -import {RootDmService} from 'core-components/api/api-v3/hal-resource-dms/root-dm.service'; import {WorkPackageCopyFullViewComponent} from 'core-components/wp-copy/wp-copy-full-view.component'; import {WorkPackageNewSplitViewComponent} from 'core-components/wp-new/wp-new-split-view.component'; import {WorkPackageCopySplitViewComponent} from 'core-components/wp-copy/wp-copy-split-view.component'; @@ -169,10 +173,8 @@ import {WorkPackageCreateSettingsMenuDirective} from 'core-components/op-context import {WorkPackageSingleContextMenuDirective} from 'core-components/op-context-menu/wp-context-menu/wp-single-context-menu'; import {WorkPackageQuerySelectableTitleComponent} from 'core-components/wp-query-select/wp-query-selectable-title.component'; import {WorkPackageQuerySelectDropdownComponent} from 'core-components/wp-query-select/wp-query-select-dropdown.component'; -import {QueryDmService} from 'core-components/api/api-v3/hal-resource-dms/query-dm.service'; import {TableState} from 'core-components/wp-table/table-state/table-state'; import {QueryMenuService} from 'core-components/wp-query-menu/wp-query-menu.service'; -import {QueryFormDmService} from 'core-components/api/api-v3/hal-resource-dms/query-form-dm.service'; import {WorkPackageStatesInitializationService} from 'core-components/wp-list/wp-states-initialization.service'; import {WorkPackageTableAdditionalElementsService} from 'core-components/wp-fast-table/state/wp-table-additional-elements.service'; import {WorkPackagesListInvalidQueryService} from 'core-components/wp-list/wp-list-invalid-query.service'; @@ -188,6 +190,8 @@ import {Ng1RelationsCreateWrapper} from 'core-components/wp-relations/wp-relatio import {WpRelationsAutocompleteComponent} from 'core-components/wp-relations/wp-relations-create/wp-relations-autocomplete/wp-relations-autocomplete.upgraded.component'; import {WpRelationAddChildComponent} from 'core-components/wp-relations/wp-relation-add-child/wp-relation-add-child'; import {WpRelationParentComponent} from 'core-components/wp-relations/wp-relations-parent/wp-relations-parent.component'; +import {OpenprojectHalModule} from 'core-app/modules/hal/openproject-hal.module'; +import {QueryFormDmService} from 'core-app/modules/dm-services/query-form-dm.service'; @NgModule({ imports: [ @@ -196,7 +200,9 @@ import {WpRelationParentComponent} from 'core-components/wp-relations/wp-relatio FormsModule, UIRouterUpgradeModule, // Angular CDK - PortalModule + PortalModule, + // Hal Module + OpenprojectHalModule ], providers: [ GonRef, @@ -267,8 +273,6 @@ import {WpRelationParentComponent} from 'core-components/wp-relations/wp-relatio upgradeService('authorisationService', AuthorisationService), upgradeService('ConfigurationService', ConfigurationService), upgradeService('currentProject', CurrentProjectService), - upgradeService('RootDm', RootDmService), - upgradeService('QueryDm', QueryDmService), upgradeService('queryMenu', QueryMenuService), // Split view upgradeService('firstRoute', FirstRouteService), diff --git a/frontend/app/components/angular/simple-template-renderer.ts b/frontend/app/components/angular/simple-template-renderer.ts index 248ce906c8..10386b7f91 100644 --- a/frontend/app/components/angular/simple-template-renderer.ts +++ b/frontend/app/components/angular/simple-template-renderer.ts @@ -55,7 +55,7 @@ export class SimpleTemplateRenderer { public renderIsolated(element:JQuery, scope:ng.IScope, template:string, - scopeValues:Object):ng.IPromise { + scopeValues:Object):Promise { const deferred = this.$q.defer(); _.assign(scope, scopeValues); diff --git a/frontend/app/components/api/api-v3/hal-link/hal-link.service.test.ts b/frontend/app/components/api/api-v3/hal-link/hal-link.service.test.ts deleted file mode 100644 index ab3728bd0f..0000000000 --- a/frontend/app/components/api/api-v3/hal-link/hal-link.service.test.ts +++ /dev/null @@ -1,291 +0,0 @@ -//-- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -//++ - -import {opApiModule, opServicesModule} from '../../../../angular-modules'; -import {HalLink} from './hal-link.service'; -import {HalRequestService} from '../hal-request/hal-request.service'; - -describe('HalLink service', () => { - var $httpBackend:ng.IHttpBackendService; - var $rootScope:any; - var HalLink:any; - var link:HalLink; - - beforeEach(angular.mock.module(opApiModule.name, opServicesModule.name)); - beforeEach(angular.mock.inject(function (_$httpBackend_:any, - _$rootScope_:any, - _HalLink_:any, - halRequest:HalRequestService) { - [$httpBackend, $rootScope, HalLink] = _.toArray(arguments); - halRequest.defaultHeaders.caching.enabled = false; - })); - - it('should exist', () => { - expect(HalLink).to.exist; - }); - - describe('when creating a HalLink from an empty object', () => { - beforeEach(() => { - link = HalLink.fromObject({}); - }); - - it('should have the "get" method as default', () => { - expect(link.method).to.eq('get'); - }); - - it('should have a null href', () => { - expect(link.href).to.be.null; - }); - - it('should not be templated', () => { - expect(link.templated).to.be.false; - }); - - it('should have an empty string as title', () => { - expect(link.title).to.equal(''); - }); - }); - - describe('when fetching a link that has a null href', () => { - beforeEach(() => { - link = new HalLink(); - link.href = null; - }); - - it('should return a promise that has null as its return value', () => { - expect(link.$fetch()).to.eventually.be.null; - $rootScope.$apply(); - }); - }); - - describe('when the method of the link is "delete"', () => { - beforeEach(() => { - link = HalLink.fromObject({ - href: 'home', - method: 'delete' - }); - }); - - it('should throw no error', () => { - expect(() => link.$fetch()).not.to.throw(Error); - }); - }); - - describe('when passing headers to $fetch', () => { - beforeEach(() => { - link = HalLink.fromObject({href: 'foobar'}); - link.$fetch({param: 'foo'}, {foo: 'bar'}); - }); - - it('should send the headers', () => { - $httpBackend.expectGET('foobar?param=foo', (headers:any) => headers.foo === 'bar').respond(200, {}); - $httpBackend.flush(); - }); - }); - - describe('when using the link', () => { - var response:any; - var result:any; - - beforeEach(() => { - link = HalLink.fromObject({ - href: '/api/link' - }); - response = { - _links: {}, - hello: 'world' - }; - - link.$fetch().then(val => result = val); - $httpBackend.expectGET('/api/link').respond(200, response); - $httpBackend.flush(); - }); - - it('should return a promise that returns the given value', () => { - expect(result.hello).to.eq(response.hello); - }); - - it('should return a HalResource', () => { - expect(result.$isHal).to.be.true; - }); - - it('should perform a GET request by default', () => { - link.$fetch(); - $httpBackend.expectGET('/api/link').respond(200, {}); - $httpBackend.flush(); - }); - - it('should send the provided data', () => { - const data = {hello: 'world'}; - link.method = 'post'; - - link.$fetch(data); - $httpBackend.expect('POST', '/api/link', data).respond(200, {}); - $httpBackend.flush(); - }); - - it('should perform a POST request', () => { - link.method = 'post'; - - link.$fetch(); - $httpBackend.expectPOST('/api/link').respond(200, {}); - $httpBackend.flush(); - }); - - it('should perform a PUT request', () => { - link.method = 'put'; - - link.$fetch(); - $httpBackend.expectPUT('/api/link').respond(200, {}); - $httpBackend.flush(); - }); - - it('should perform a PATCH request', () => { - link.method = 'patch'; - - link.$fetch(); - $httpBackend.expectPATCH('/api/link').respond(200, {}); - $httpBackend.flush(); - }); - - describe('when making the link callable', () => { - var func:any; - const runChecks = () => { - it('should return a function that fetches the data', () => { - func(); - - $httpBackend.expectPOST('foo').respond(200, {}); - $httpBackend.flush(); - }); - - it('should pass the params to $fetch', () => { - var $fetch = sinon.spy(link, '$fetch'); - func('hello'); - - expect($fetch.calledWith('hello')).to.be.true; - }); - - it('should have the href property of the link', () => { - expect(func.href).to.equal(link.href); - }); - - it('should have the title property of the link', () => { - expect(func.title).to.equal(link.title); - }); - - it('should have the method property of the link', () => { - expect(func.method).to.equal(link.method); - }); - - it('should have the templated property of the link', () => { - expect(func.templated).to.equal(link.templated); - }); - }; - - beforeEach(() => { - link.href = 'foo'; - link.title = 'title'; - link.method = 'post'; - link.templated = true; - }); - - describe('when using the instance method', () => { - beforeEach(() => { - func = link.$callable(); - }); - runChecks(); - }); - - describe('when using the static factory method', () => { - beforeEach(() => { - func = HalLink.callable(link); - link = func.$link; - }); - runChecks(); - }); - }); - - describe('when $preparing the link', () => { - var func:any; - - beforeEach(() => { - link.href = '/foo/bar/{user_id}'; - link.title = 'title'; - link.method = 'post'; - link.templated = true; - }); - - describe('when the link is NOT templated', () => { - beforeEach(() => { - link.templated = false; - }); - it('should raise an exception', () => { - expect(function() { - link.$prepare({}); - }).to.throw; - }); - }); - - describe('when the link is templated', () => { - beforeEach(() => { - func = link.$prepare({ user_id: '1234' }); - }); - - it('should return a function that fetches the data', () => { - func(); - - $httpBackend.expectPOST('/foo/bar/1234').respond(200, {}); - $httpBackend.flush(); - }); - - it('should pass the params to $fetch', () => { - var $fetch = sinon.spy(func.$link, '$fetch'); - func('hello'); - - expect($fetch.calledWith('hello')).to.be.true; - }); - - it('should have the untemplated href property', () => { - expect(func.href).to.equal('/foo/bar/1234'); - }); - - it('should have the title property of the link', () => { - expect(func.title).to.equal(link.title); - }); - - it('should have the method property of the link', () => { - expect(func.method).to.equal(link.method); - }); - - it('should not be templated', () => { - expect(func.templated).to.equal(false); - }); - }); - }); - }); -}); diff --git a/frontend/app/components/api/api-v3/hal-request/hal-request.service.test.ts b/frontend/app/components/api/api-v3/hal-request/hal-request.service.test.ts deleted file mode 100644 index afd78f28b3..0000000000 --- a/frontend/app/components/api/api-v3/hal-request/hal-request.service.test.ts +++ /dev/null @@ -1,241 +0,0 @@ -//-- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -//++ - -import {opApiModule} from '../../../../angular-modules'; -import {HalRequestService} from './hal-request.service'; -import {HalResource} from '../hal-resources/hal-resource.service'; -import IPromise = angular.IPromise; -import IRootScopeService = angular.IRootScopeService; -import IHttpBackendService = angular.IHttpBackendService; - -describe('halRequest service', () => { - var $httpBackend:IHttpBackendService; - var $rootScope:IRootScopeService; - var halRequest:HalRequestService; - - beforeEach(angular.mock.module(opApiModule.name)); - beforeEach(angular.mock.inject(function (_$httpBackend_:any, _$rootScope_:any, _halRequest_:any) { - [$httpBackend, $rootScope, halRequest] = _.toArray(arguments); - })); - - it('should exist', () => { - expect(halRequest).to.exist; - }); - - afterEach(() => { - $rootScope.$apply(); - }); - - describe('when requesting a null href', () => { - var promise:any; - - beforeEach(() => { - promise = halRequest.request('get', ''); - }); - - it('should return a rejected promise', () => { - expect(promise).to.eventually.be.rejected; - }); - }); - - describe('when requesting the same GET resource multiple times', () => { - var headers:any; - - const testRequest = (prepare:any) => { - beforeEach(prepare); - - it('should perform requests according to the cache options', () => { - $httpBackend.expectGET('something').respond(200, '', (headers:any) => { - return headers.caching.enabled === true; - }); - - if (headers.caching && headers.caching.enabled === false) { - $httpBackend.expectGET('something').respond(200, ''); - } - }); - }; - const testMethods = () => { - describe('when using request()', () => { - testRequest(() => { - halRequest.request('get', 'something', {}, headers); - halRequest.request('get', 'something', {}, headers); - }); - }); - - describe('when using get()', () => { - testRequest(() => { - halRequest.get('something', {}, headers); - halRequest.get('something', {}, headers); - }); - }); - }; - - beforeEach(() => { - halRequest.defaultHeaders.caching = {enabled: true}; - headers = {}; - }); - - testMethods(); - - describe('when sending a no cache header', () => { - beforeEach(() => { - headers = {caching: {enabled: false}}; - }); - - testMethods(); - }); - }); - - describe('when requesting data', () => { - var promise:IPromise; - var method:string; - var data:any; - var expectedData:any; - var headers = {Accept: 'foo', caching: {enabled: false}}; - - const methods = ['get', 'put', 'post', 'patch', 'delete']; - const respond = (status:any, response:any) => { - $httpBackend - .expect(method.toUpperCase(), 'href', expectedData, (headers:any) => { - return headers.Accept === 'foo'; - }) - .respond(status, response); - - $httpBackend.flush(); - }; - const runTests = () => { - describe('when no error occurs', () => { - beforeEach(() => respond(200, {})); - it('should return a HalResource', () => { - expect(promise).to.eventually.be.an.instanceOf(HalResource); - }); - }); - - describe('when an error occurs', () => { - beforeEach(() => respond(400, {})); - - it('should be rejected with an instance of HalResource', () => { - expect(promise).to.eventually.be.rejectedWith(HalResource); - }); - }); - - describe('when the server does not respond with a result', () => { - beforeEach(() => respond(200, null)); - - it('should return nothing as well', () => { - expect(promise).to.eventually.be.null; - }); - }); - }; - const runRequests = (cb:any) => { - const callback = () => { - if (method === 'get') { - data = null; - expectedData = null; - } - cb(); - }; - methods.forEach(requestMethod => { - describe(`when performing a ${requestMethod} request`, () => { - beforeEach(() => { - method = requestMethod; - }); - - describe('when sending no data with the request', () => { - beforeEach(() => { - data = void 0; - expectedData = void 0; - - if (method === 'post') { - expectedData = {}; - } - - callback(); - }); - - runTests(); - }); - - describe('when sending data with the request', () => { - beforeEach(() => { - data = {foo: 'bar'}; - expectedData = data; - callback(); - }); - - runTests(); - }); - }); - }); - }; - - describe('when calling the http methods of the service', () => { - runRequests(() => { - promise = (halRequest as any)[method]('href', data, headers); - }); - }); - - describe('when calling request()', () => { - runRequests(() => { - promise = halRequest.request(method, 'href', data, headers); - }); - }); - - describe('when requesting a GET resource with parameters', () => { - const params = {foo: 'bar'}; - - beforeEach(() => { - promise = halRequest.get('href', params); - }); - - it('should append the parameters at the end of the requested url', () => { - $httpBackend.expectGET('href?foo=bar').respond(200, {}); - $httpBackend.flush(); - }); - }); - - describe('#getAllPaginated', () => { - const params = {}; - let promise:any; - - beforeEach(() => { - promise = halRequest.getAllPaginated('href', 25, params); - - $httpBackend.expectGET('href?offset=1').respond(200, { count: 12, total: 25 }); - $httpBackend.expectGET('href?offset=2').respond(200, { count: 12, total: 25 }); - $httpBackend.expectGET('href?offset=3').respond(200, { count: 1, total: 25 }); - }); - - it('should resolve with three results', () => { - expect(promise).to.eventually.be.fulfilled.then(allResults => { - expect(allResults.length).to.eq(3); - }); - }); - }); - }); -}); diff --git a/frontend/app/components/api/api-v3/hal-resource-dms/relations-dm.service.test.ts b/frontend/app/components/api/api-v3/hal-resource-dms/relations-dm.service.test.ts deleted file mode 100644 index f8341cb425..0000000000 --- a/frontend/app/components/api/api-v3/hal-resource-dms/relations-dm.service.test.ts +++ /dev/null @@ -1,114 +0,0 @@ -//-- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -//++ - -import {opApiModule} from '../../../../angular-modules'; -import IPromise = angular.IPromise; -import IRootScopeService = angular.IRootScopeService; -import IHttpBackendService = angular.IHttpBackendService; -import {RelationsDmService} from './relations-dm.service'; -import {buildApiV3Filter} from '../api-v3-filter-builder'; - -describe('relationsDm service', () => { - var $httpBackend:IHttpBackendService; - var relationsDm:RelationsDmService; - var $rootScope:ng.IRootScopeService; - - beforeEach(angular.mock.module(opApiModule.name)); - beforeEach(angular.mock.inject(function (_relationsDm_:RelationsDmService, _$rootScope_:ng.IRootScopeService, _$httpBackend_:ng.IHttpBackendService) { - $httpBackend = _$httpBackend_; - relationsDm = _relationsDm_; - $rootScope = _$rootScope_; - })); - - it('should exist', () => { - expect(relationsDm).to.exist; - }); - - afterEach(() => { - $rootScope.$apply(); - }); - - function filterString(ids:string[]) { - let filterString = encodeURI(buildApiV3Filter('involved', '=', ids).toJson()); - // Angular extends on encodeURI to unescape some values.. - // https://github.com/angular/angular.js/blob/v1.5.x/src/Angular.js - filterString = filterString.replace(/=/gi, '%3D'); - return '?filters=' + filterString; - } - - describe('#loadInvolved', () => { - let promise:ng.IPromise; - let ids:string[]; - - describe('when requesting some IDs', () => { - beforeEach(() => { - ids = ['1', '2', '3']; - promise = relationsDm.loadInvolved(ids); - }); - - it('should append the parameters at the end of the requested url', () => { - $httpBackend.expectGET('/api/v3/relations' + filterString(ids)).respond(200, { elements: ['foo'] }); - $httpBackend.flush(); - - expect(promise).to.eventually.be.fulfilled.then((relations) => { - expect(relations).to.deep.equal(['foo']); - }); - }); - }); - - describe('when requesting with an invalid IDs', () => { - beforeEach(() => { - ids = ['1', 'foo']; - promise = relationsDm.loadInvolved(ids); - }); - - it('should append the parameters at the end of the requested url', () => { - $httpBackend.expectGET('/api/v3/relations' + filterString(['1'])).respond(200, { elements: ['foo'] }); - $httpBackend.flush(); - - expect(promise).to.eventually.be.fulfilled.then((relations) => { - expect(relations).to.deep.equal(['foo']); - }); - }); - }); - - describe('when requesting with no valid IDs', () => { - beforeEach(() => { - ids = ['foo']; - promise = relationsDm.loadInvolved(ids); - }); - - it('should append the parameters at the end of the requested url', () => { - expect($httpBackend.flush.bind($httpBackend)).to.throw('No pending request to flush !'); - expect(promise).to.eventually.be.fulfilled.then((relations) => { - expect(relations).to.be.empty; - }); - }); - }); - }); -}); diff --git a/frontend/app/components/api/api-v3/hal-resource-factory/hal-changeset-proxy.ts b/frontend/app/components/api/api-v3/hal-resource-factory/hal-changeset-proxy.ts deleted file mode 100644 index 2d6ac5fe7e..0000000000 --- a/frontend/app/components/api/api-v3/hal-resource-factory/hal-changeset-proxy.ts +++ /dev/null @@ -1,23 +0,0 @@ -export interface ChangesetProxy { - changesetReset():void; - - changesetPersist():void; -} - -export function createChangeSetProxy(target:T):T & ChangesetProxy { - const proxy = {} as any; - Object.setPrototypeOf(proxy, target); - - proxy.changesetReset = () => { - _.forOwn(proxy, (value, key) => delete proxy[key]); - }; - - proxy.changesetPersist = () => { - _.forOwn(proxy, (value, key) => { - (target as any)[key] = value; - delete proxy[key]; - }); - }; - - return proxy; -} diff --git a/frontend/app/components/api/api-v3/hal-resource-factory/hal-resource-factory.service.test.ts b/frontend/app/components/api/api-v3/hal-resource-factory/hal-resource-factory.service.test.ts deleted file mode 100644 index a473034a96..0000000000 --- a/frontend/app/components/api/api-v3/hal-resource-factory/hal-resource-factory.service.test.ts +++ /dev/null @@ -1,109 +0,0 @@ -// -- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -// ++ - -import {opApiModule} from '../../../../angular-modules'; -import {HalResourceFactoryService} from './hal-resource-factory.service'; -import {HalResource} from '../hal-resources/hal-resource.service'; - -describe('halResourceFactory', () => { - var halResourceFactory:HalResourceFactoryService; - var resource:HalResource; - - class OtherResource extends HalResource { - } - - beforeEach(angular.mock.module(opApiModule.name)); - beforeEach(angular.mock.module(opApiModule.name, ($provide:any) => { - $provide.value('OtherResource', OtherResource); - })); - beforeEach(angular.mock.inject(function (_halResourceFactory_:any) { - [halResourceFactory] = _.toArray(arguments); - })); - - it('should exist', () => { - expect(halResourceFactory).to.exist; - }); - - it('should have HalResource as its default class', () => { - expect(halResourceFactory.defaultClass).to.equal(HalResource); - }); - - describe('when no resource type is configured', () => { - describe('when creating a resource', () => { - beforeEach(() => { - resource = halResourceFactory.createHalResource({}); - }); - - it('should create an instance of the default type', () => { - expect(resource).to.be.an.instanceOf(halResourceFactory.defaultClass); - }); - }); - }); - - describe('when a resource type is configured', () => { - beforeEach(() => { - halResourceFactory.setResourceType('Other', OtherResource); - }); - - describe('when creating a resource of that type', () => { - beforeEach(() => { - resource = halResourceFactory.createHalResource({_type: 'Other'}); - }); - - it('should be an instance of the configured type', () => { - expect(resource).to.be.an.instanceOf(OtherResource); - }); - }); - - describe('when adding attribute configuration for that type', () => { - beforeEach(() => { - halResourceFactory.setResourceTypeAttributes('Other', { - attr: 'Other' - }); - resource = halResourceFactory.createLinkedHalResource({}, 'Other', 'attr'); - }); - - it('should be an instance of the configured attr type', () => { - expect(resource).to.be.an.instanceOf(OtherResource); - }); - }); - }); - - describe('when adding attr type configuration to for a non configured type', () => { - beforeEach(() => { - halResourceFactory.setResourceTypeAttributes('NonExistent', { - attr: 'NonExistent' - }); - resource = halResourceFactory.createLinkedHalResource({}, 'NonExistent', 'attr'); - }); - - it('should create a resource from the default tpye', () => { - expect(resource).to.be.an.instanceOf(halResourceFactory.defaultClass); - }); - }); -}); diff --git a/frontend/app/components/api/api-v3/hal-resource-types/hal-resource-types.config.ts b/frontend/app/components/api/api-v3/hal-resource-types/hal-resource-types.config.ts deleted file mode 100644 index 88aea083e6..0000000000 --- a/frontend/app/components/api/api-v3/hal-resource-types/hal-resource-types.config.ts +++ /dev/null @@ -1,92 +0,0 @@ -// -- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -// ++ - -import {opApiModule} from '../../../../angular-modules'; -import {HalResourceTypesService} from './hal-resource-types.service'; - -function halResourceTypesConfig(halResourceTypes:HalResourceTypesService) { - halResourceTypes.setResourceTypeConfig({ - WorkPackage: { - className: 'WorkPackageResource', - attrTypes: { - parent: 'WorkPackage', - ancestors: 'WorkPackage', - children: 'WorkPackage', - relations: 'Relation', - schema: 'Schema', - type: 'Type' - } - }, - Activity: { - user: 'User' - }, - 'Activity::Comment': { - user: 'User' - }, - 'Activity::Revision': { - user: 'User' - }, - Relation: { - className: 'RelationResource', - attrTypes: { - from: 'WorkPackage', - to: 'WorkPackage' - } - }, - Schema: 'SchemaResource', - Type: 'TypeResource', - SchemaDependency: 'SchemaDependencyResource', - Error: 'ErrorResource', - User: 'UserResource', - Collection: 'CollectionResource', - WorkPackageCollection: 'WorkPackageCollectionResource', - Query: { - className: 'QueryResource', - attrTypes: { - filters: 'QueryFilterInstance' - } - }, - Form: 'FormResource', - QueryFilterInstance: { - className: 'QueryFilterInstanceResource' , - attrTypes: { - schema: 'QueryFilterInstanceSchema', - filter: 'QueryFilter', - operator: 'QueryOperator' - } - }, - QueryFilterInstanceSchema: 'QueryFilterInstanceSchemaResource', - QueryFilter: 'QueryFilterResource', - Root: 'RootResource', - QueryOperator: 'QueryOperatorResource', - HelpText: 'HelpTextResource', - CustomAction: 'CustomActionResource' - }); -} - -opApiModule.run(halResourceTypesConfig); diff --git a/frontend/app/components/api/api-v3/hal-resource-types/hal-resource-types.service.test.ts b/frontend/app/components/api/api-v3/hal-resource-types/hal-resource-types.service.test.ts deleted file mode 100644 index 425c06e98d..0000000000 --- a/frontend/app/components/api/api-v3/hal-resource-types/hal-resource-types.service.test.ts +++ /dev/null @@ -1,133 +0,0 @@ -// -- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -// ++ - -import {opApiModule} from '../../../../angular-modules'; -import {HalResourceTypesService} from './hal-resource-types.service'; -import {HalResourceFactoryService} from '../hal-resource-factory/hal-resource-factory.service'; - -describe('halResourceTypes service', () => { - var halResourceTypes:HalResourceTypesService; - var halResourceFactory:HalResourceFactoryService; - var config:any; - var compareCls:typeof HalResource; - - class HalResource { - } - class OtherResource { - } - class FooResource { - } - - beforeEach(angular.mock.module(opApiModule.name, ($provide:any) => { - $provide.value('HalResource', HalResource); - $provide.value('OtherResource', OtherResource); - $provide.value('FooResource', FooResource); - })); - - beforeEach(angular.mock.inject(function (_halResourceTypes_:any, _halResourceFactory_:any) { - [halResourceTypes, halResourceFactory] = _.toArray(arguments); - })); - - const expectResourceClassAdded = () => { - it('should add the respective class object to the storage', () => { - const resource = halResourceFactory.createHalResource({_type: 'Other'}); - expect(resource).to.be.an.instanceOf(compareCls); - }); - }; - - const expectAttributeClassAdded = () => { - it('should add the attribute type config to the storage', () => { - const resource = halResourceFactory.createLinkedHalResource({}, 'Other', 'attr'); - expect(resource).to.be.an.instanceOf(compareCls); - }); - }; - - it('should exist', () => { - expect(halResourceTypes).to.exist; - }); - - describe('when configuring the type with class and attributes', () => { - beforeEach(() => { - compareCls = OtherResource; - config = { - Other: { - className: 'OtherResource', - attrTypes: { - attr: 'Other' - } - } - }; - halResourceTypes.setResourceTypeConfig(config); - }); - - expectResourceClassAdded(); - expectAttributeClassAdded(); - }); - - describe('when configuring the type with the class name as value', () => { - beforeEach(() => { - compareCls = OtherResource; - config = { - Other: 'OtherResource' - }; - halResourceTypes.setResourceTypeConfig(config); - }); - - expectResourceClassAdded(); - }); - - describe('when configuring the type with only the attribute types', () => { - beforeEach(() => { - compareCls = halResourceFactory.defaultClass; - config = { - Other: { - attr: 'Other' - } - }; - halResourceTypes.setResourceTypeConfig(config); - }); - - expectResourceClassAdded(); - expectAttributeClassAdded(); - }); - - describe('when an attribute has a type, that defined later in the config', () => { - beforeEach(() => { - compareCls = FooResource; - config = { - Other: { - attr: 'Foo' - }, - Foo: 'FooResource', - }; - halResourceTypes.setResourceTypeConfig(config); - }); - - expectAttributeClassAdded(); - }); -}); diff --git a/frontend/app/components/api/api-v3/hal-resource-types/hal-resource-types.service.ts b/frontend/app/components/api/api-v3/hal-resource-types/hal-resource-types.service.ts deleted file mode 100644 index 88bb270415..0000000000 --- a/frontend/app/components/api/api-v3/hal-resource-types/hal-resource-types.service.ts +++ /dev/null @@ -1,85 +0,0 @@ -// -- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -// ++ - -import {opApiModule} from '../../../../angular-modules'; -import {HalResourceFactoryService} from '../hal-resource-factory/hal-resource-factory.service'; - -export class HalResourceTypesService { - constructor(protected $injector:ng.auto.IInjectorService, - protected halResourceFactory:HalResourceFactoryService, - HalResource:any) { - halResourceFactory.defaultClass = HalResource; - } - - public setResourceTypeConfig(config:any) { - const types = Object.keys(config).map(typeName => { - const value = config[typeName]; - const result = { - typeName: typeName, - className: value.className || this.getClassName(this.halResourceFactory.defaultClass), - attrTypes: value.attrTypes || {} - }; - - if (angular.isString(value)) { - result.className = value; - } - - if (!value.className && angular.isObject(value)) { - result.attrTypes = value; - } - - return result; - }); - - types.forEach(typeConfig => { - this.halResourceFactory - .setResourceType(typeConfig.typeName, this.$injector.get(typeConfig.className) as any); - }); - - types - .forEach(typeConfig => { - this.halResourceFactory.setResourceTypeAttributes(typeConfig.typeName, typeConfig.attrTypes); - }); - } - - /** - * IE11 has no support for .name, thus polyfill the actual class name - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name - * @param cls - */ - protected getClassName(cls:Function) { - if (cls.hasOwnProperty('name')) { - return cls.name; - } - - const matches = cls.toString().match(/^function\s*([^\s(]+)/) as any[]; - return matches[1]; - } -} - -opApiModule.service('halResourceTypes', HalResourceTypesService); diff --git a/frontend/app/components/api/api-v3/hal-resources/attachment-collection-resource.service.test.ts b/frontend/app/components/api/api-v3/hal-resources/attachment-collection-resource.service.test.ts deleted file mode 100644 index ae93849783..0000000000 --- a/frontend/app/components/api/api-v3/hal-resources/attachment-collection-resource.service.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -// -- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -// ++ - -import {opApiModule, opServicesModule} from '../../../../angular-modules'; -import {AttachmentCollectionResource} from './attachment-collection-resource.service'; -import {OpenProjectFileUploadService} from '../../op-file-upload/op-file-upload.service'; - -describe('AttachmentCollectionResource service', () => { - var AttachmentCollectionResource:any; - var opFileUpload: OpenProjectFileUploadService; - - beforeEach(angular.mock.module( - opApiModule.name, - opServicesModule.name - )); - beforeEach(angular.mock.inject(function (_AttachmentCollectionResource_:any, - _opFileUpload_:any) { - [AttachmentCollectionResource, opFileUpload] = _.toArray(arguments); - })); - - it('should exist', () => { - expect(AttachmentCollectionResource).to.exist; - }); - - describe('when creating an attachment collection', () => { - var collection: AttachmentCollectionResource; - - beforeEach(() => { - collection = new AttachmentCollectionResource({ - _links: {self: {href: 'attachments'}} - }, true); - }); - - describe('when using upload()', () => { - var uploadStub: sinon.SinonStub; - var params:any; - - beforeEach(() => { - params = [{}, {}]; - uploadStub = sinon.stub(opFileUpload, 'upload'); - collection.upload((params)); - }); - - it('should upload the files as expected', () => { - expect(uploadStub.calledWith(collection.$href, params)).to.be.true; - }); - }); - }); -}); diff --git a/frontend/app/components/api/api-v3/hal-resources/attachment-collection-resource.service.ts b/frontend/app/components/api/api-v3/hal-resources/attachment-collection-resource.service.ts deleted file mode 100644 index d9cde09518..0000000000 --- a/frontend/app/components/api/api-v3/hal-resources/attachment-collection-resource.service.ts +++ /dev/null @@ -1,60 +0,0 @@ -//-- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -//++ - -import {opApiModule} from '../../../../angular-modules'; -import {CollectionResource} from './collection-resource.service'; -import {HalResource} from './hal-resource.service'; -import { - OpenProjectFileUploadService, - UploadFile, UploadResult -} from '../../op-file-upload/op-file-upload.service'; -import IPromise = angular.IPromise; - -var opFileUpload: OpenProjectFileUploadService; - -export class AttachmentCollectionResource extends CollectionResource { - /** - * Upload the given files to the $href property of this resource. - */ - public upload(files: UploadFile[]): UploadResult { - return opFileUpload.upload(this.$href as string, files); - } -} - -export interface AttachmentCollectionResourceInterface extends AttachmentCollectionResource { - elements: HalResource[]; -} - -function attachmentCollectionResourceService(...args:any[]) { - [opFileUpload] = args; - return AttachmentCollectionResource; -} - -attachmentCollectionResourceService.$inject = ['opFileUpload']; - -opApiModule.factory('AttachmentCollectionResource', attachmentCollectionResourceService); diff --git a/frontend/app/components/api/api-v3/hal-resources/collection-resource.service.test.ts b/frontend/app/components/api/api-v3/hal-resources/collection-resource.service.test.ts deleted file mode 100644 index f91537ce22..0000000000 --- a/frontend/app/components/api/api-v3/hal-resources/collection-resource.service.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -// -- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -// ++ - -import {opApiModule, opServicesModule} from '../../../../angular-modules'; -import IQService = angular.IQService; -import IRootScopeService = angular.IRootScopeService; - -describe('CollectionResource service', () => { - var $q:any; - var $rootScope:any; - var CollectionResource:any; - - var source:any; - var collection:any; - - beforeEach(angular.mock.module(opApiModule.name, opServicesModule.name)); - beforeEach(angular.mock.inject(function (_$q_:any, _$rootScope_:any, _CollectionResource_:any) { - [$q, $rootScope, CollectionResource] = _.toArray(arguments); - })); - - function createCollection() { - source = source || {}; - collection = new CollectionResource(source); - } - - it('should exist', () => { - expect(CollectionResource).to.exist; - }); - - describe('when using updateElements', () => { - var elements:any; - var result:any; - - beforeEach(() => { - createCollection(); - elements = [{}, {}]; - sinon.stub(collection, '$load').returns($q.when({elements})); - - result = collection.updateElements(); - $rootScope.$apply(); - }); - - it('should set the elements of the resource so the new value', () => { - expect(collection.elements).to.equal(elements); - }); - - it('should return a promise with the elements as the result', () => { - expect(result).to.eventually.equal(elements); - }); - }); -}); diff --git a/frontend/app/components/api/api-v3/hal-resources/custom-action-resource.service.ts b/frontend/app/components/api/api-v3/hal-resources/custom-action-resource.service.ts deleted file mode 100644 index 7678053ffe..0000000000 --- a/frontend/app/components/api/api-v3/hal-resources/custom-action-resource.service.ts +++ /dev/null @@ -1,55 +0,0 @@ -//-- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -//++ - -import {opApiModule} from '../../../../angular-modules'; -import {HalResource} from './hal-resource.service'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; - -interface CustomActionResourceEmbedded { -} - -export interface CustomActionResourceLinks extends CustomActionResourceEmbedded { - self():ng.IPromise; - executeImmediately(payload:any):ng.IPromise; -} - -export class CustomActionResource extends HalResource { - public $embedded:CustomActionResourceEmbedded; - public id:number; - public name:string; - public description:string; -} - -function customActionResource() { - return CustomActionResource; -} - -export interface CustomActionResourceInterface extends CustomActionResourceLinks, CustomActionResourceEmbedded, CustomActionResource { -} - -opApiModule.factory('CustomActionResource', customActionResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/hal-resource.service.test.ts b/frontend/app/components/api/api-v3/hal-resources/hal-resource.service.test.ts deleted file mode 100644 index f520b33fee..0000000000 --- a/frontend/app/components/api/api-v3/hal-resources/hal-resource.service.test.ts +++ /dev/null @@ -1,726 +0,0 @@ -//-- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -//++ - -import {opApiModule, opServicesModule} from '../../../../angular-modules'; -import {HalResource} from './hal-resource.service'; -import {HalResourceFactoryService} from '../hal-resource-factory/hal-resource-factory.service'; -import {HalRequestService} from '../hal-request/hal-request.service'; -import {HalLinkInterface} from './../hal-link/hal-link.service'; - -describe('HalResource service', () => { - var $httpBackend:ng.IHttpBackendService; - var halResourceFactory:HalResourceFactoryService; - var resource:any; - var source:any; - - class OtherResource extends HalResource { - } - - beforeEach(angular.mock.module(opApiModule.name, opServicesModule.name, ($provide:ng.auto.IProvideService) => { - $provide.value('OtherResource', OtherResource); - })); - beforeEach(angular.mock.inject(function (_$httpBackend_:any, - _halResourceFactory_:any, - halRequest:HalRequestService) { - [$httpBackend, halResourceFactory] = _.toArray(arguments); - halRequest.defaultHeaders.caching.enabled = false; - })); - - it('should exist', () => { - expect(HalResource).to.exist; - }); - - it('should be instantiable using a default object', () => { - expect(new HalResource().$href).to.equal(null); - }); - - describe('when updating a loaded resource using `$update()`', () => { - beforeEach(() => { - source = { - _links: { - self: { - href: 'hello' - } - } - }; - resource = new HalResource(source); - resource.$update(); - }); - - it('should perform a no-cache request', () => { - const expectHeaders = (headers:any) => headers.caching.enabled === false; - $httpBackend.expectGET('hello', expectHeaders).respond(200, {}); - $httpBackend.flush(); - }); - }); - - describe('when creating a resource using the create factory method', () => { - describe('when there is no type configuration', () => { - beforeEach(() => { - source = {_embedded: {}}; - resource = HalResource.create(source); - }); - - it('should be an instance of HalResource', () => { - expect(resource).to.be.an.instanceOf(HalResource); - }); - }); - - describe('when the type is configured', () => { - beforeEach(() => { - source = { - _type: 'Other', - _links: { - someResource: { - href: 'foo' - } - } - }; - - halResourceFactory.setResourceType('Other', OtherResource); - halResourceFactory.setResourceTypeAttributes('Other', { - someResource: 'Other' - }); - - resource = HalResource.create(source); - }); - - it('should be an instance of that type', () => { - expect(resource).to.be.an.instanceOf(OtherResource); - }); - - it('should have an attribute that is of the configured instance', () => { - expect(resource.someResource).to.be.an.instanceOf(OtherResource); - }); - - it('should not be loaded', () => { - expect(resource.someResource.$loaded).to.be.false; - }); - }); - }); - - describe('when after generating the lazy object', () => { - var linkFn = sinon.spy(); - var embeddedFn = sinon.spy(); - - beforeEach(() => { - resource = new HalResource({ - _links: { - get link() { - linkFn(); - return {}; - } - }, - _embedded: { - get resource() { - embeddedFn(); - return {}; - } - } - }); - }); - - it('should not have touched the source links initially', () => { - expect(linkFn.called).to.be.false; - }); - - it('should not have touched the embedded elements of the source initially', () => { - expect(embeddedFn.called).to.be.false; - }); - - it('should use the source link only once when called', () => { - resource.link; - resource.link; - expect(linkFn.calledOnce).to.be.true; - }); - - it('should use the source embedded only once when called', () => { - resource.resource; - resource.resource; - expect(embeddedFn.calledOnce).to.be.true; - }); - }); - - describe('when the source has properties, the resource', () => { - beforeEach(() => { - source = { - _links: {}, - _embedded: {}, - property: 'foo', - obj: { - foo: 'bar' - } - }; - resource = new HalResource(source); - }); - - it('should have the same properties', () => { - expect(resource.property).to.exist; - expect(resource.obj).to.exist; - }); - - it('should have properties with equal values', () => { - expect(resource.property).to.eq(source.property); - expect(resource.obj).to.eql(source.obj); - }); - - it('should not have the _links property', () => { - expect(resource._links).to.not.exist; - }); - - it('should not have the _embedded property', () => { - expect(resource._embedded).to.not.exist; - }); - - it('should have enumerable properties', () => { - expect(resource.propertyIsEnumerable('property')).to.be.true; - }); - - describe('when a property is changed', () => { - beforeEach(() => { - resource.property = 'carrot'; - }); - - it('should change the property of the source', () => { - expect(resource.$source.property).to.eq('carrot'); - }); - }); - }); - - describe('when creating a resource from a source with a self link', () => { - beforeEach(() => { - source = { - _links: { - self: { - href: '/api/hello', - title: 'some title' - } - } - }; - resource = new HalResource(source); - }); - - it('should have a name attribute that is equal to the title of the self link', () => { - expect(resource.name).to.eq('some title'); - }); - - it('should have a writable name attribute', () => { - resource.name = 'some name'; - expect(resource.name).to.eq('some name'); - }); - - it('should have a href property that is the same as the self href', () => { - expect(resource.href).to.eq(resource.$links.self.$link.href); - }); - - it('should have a href property that is equal to the source href', () => { - expect(resource.href).to.eq(source._links.self.href); - }); - - it('should not have a self property', () => { - expect(resource.self).not.to.exist; - }); - }); - - describe('when setting a property that is a resource to null', () => { - beforeEach(() => { - source = { - _links: { - resource: { - method: 'get', - href: 'resource/1' - } - } - }; - resource = new HalResource(source); - resource.resource = null; - }); - - it('should be null', () => { - expect(resource.resource).to.be.null; - }); - - it('should set the respective link href to null', () => { - expect(resource.$source._links.resource.href).to.be.null; - }); - }); - - describe('when a property that is a resource has a null href', () => { - beforeEach(() => { - source = { - _links: { - property: { - href: null - } - } - }; - resource = new HalResource(source); - }); - - it('should be null', () => { - expect(resource.property).to.be.null; - }); - }); - - describe('when using $plain', () => { - var plain:any; - - beforeEach(() => { - source = { - _links: {self: {href: 'bunny'}}, - rabbit: 'fluffy' - }; - plain = new HalResource(source).$plain(); - }); - - it('should return an object that is equal to the source', () => { - expect(plain).to.eql(source); - }); - - it('should not be the exact same object', () => { - expect(plain).not.to.equal(source); - }); - }); - - describe('when creating a resource with a source that has no links', () => { - beforeEach(() => { - resource = new HalResource({}); - }); - - it('should return null for the href if it has no self link', () => { - expect(resource.href).to.equal(null); - }); - - it('should have a $link object with null href', () => { - expect(resource.$link.href).to.equal(null); - }); - }); - - describe('when creating a resource form a source with linked resources', () => { - beforeEach(() => { - source = { - _links: { - self: { - href: 'unicorn/69' - }, - beaver: { - href: 'justin/420' - } - } - }; - resource = new HalResource(source); - }); - - it('should have no "self" property', () => { - expect(resource.self).to.not.exist; - }); - - it('should have a beaver', () => { - expect(resource.beaver).to.exist; - }); - - it('should have no "_links" property', () => { - expect(resource._links).to.not.exist; - }); - - it('should leave the source accessible', () => { - expect(resource.$source).to.eql(source); - }); - - it('should have a callable self link', () => { - expect(() => resource.$links.self()).to.not.throw(Error); - }); - - it('should have a callable beaver', () => { - expect(() => resource.$links.beaver()).to.not.throw(Error); - }); - - it('should have a $links property with the keys of its source _links', () => { - const transformedLinks = Object.keys(resource.$links); - const plainLinks = Object.keys(source._links); - - expect(transformedLinks).to.have.members(plainLinks); - }); - }); - - describe('when creating a resource from a source with embedded resources', () => { - beforeEach(() => { - source = { - _embedded: { - resource: {_links: {}}, - } - }; - - resource = new HalResource(source); - }); - - it('should not have the original _embedded property', () => { - expect(resource._embedded).to.not.be.ok; - }); - - it('should have a property, that is a loaded resource', () => { - expect(resource.resource.$loaded).to.be.true; - }); - - it('should have an embedded resource, that is loaded', () => { - expect(resource.$embedded.resource.$loaded).to.be.true; - }); - - it('should have a property that is the resource', () => { - expect(resource.resource).to.equal(resource.$embedded.resource); - }); - - it.skip('should have a callable link to that resource', () => { - expect(() => resource.$links.resource()).to.not.throw(Error); - }); - - describe('when overriding the property with a resource', () => { - var link:HalLinkInterface; - - beforeEach(() => { - link = { - href: 'pony', - method: 'GET' - }; - resource.resource = HalResource.fromLink(link); - }); - - it('should set the property to that resource', () => { - expect(resource.resource.href).to.equal(link.href); - }); - - it.skip('should set the corresponding link', () => { - expect(resource.$links.resource.$link.href).to.equal(link.href); - }); - }); - - describe('when the embedded resources are nested', () => { - var first:any; - var deep:any; - - beforeEach(() => { - source._embedded.resource._embedded = { - first: { - _embedded: { - second: { - _links: {}, - property: 'yet another value' - } - }, - property: 'another value' - } - }; - - first = resource.$embedded.resource.$embedded.first; - deep = resource.$embedded.resource.$embedded.first.$embedded.second; - }); - - it('should crate all nested resources recursively', () => { - expect(deep.$isHal).to.be.true; - }); - - it('should transfer the properties of the nested resources correctly', () => { - expect(first.property).to.eq('another value'); - expect(deep.property).to.eq('yet another value'); - }); - }); - }); - - describe('when creating a resource from a source with a linked array property', () => { - var expectLengthsToBe = (length:any, update = 'update') => { - it(`should ${update} the values of the resource`, () => { - expect(resource.values).to.have.lengthOf(length); - }); - - it(`should ${update} the source`, () => { - expect(source._links.values).to.have.lengthOf(length); - }); - - it(`should ${update} the $source property`, () => { - expect(resource.$source._links.values).to.have.lengthOf(length); - }); - }; - - beforeEach(() => { - source = { - _links: { - values: [ - { - href: '/api/value/1', - title: 'val1' - }, - { - href: '/api/value/2', - title: 'val2' - } - ] - } - }; - resource = new HalResource(source); - }); - - it('should be an array that is a property of the resource', () => { - expect(resource).to.have.property('values').that.is.an('array'); - }); - - expectLengthsToBe(2); - - describe('when adding resources to the array', () => { - beforeEach(() => { - resource.values.push(resource); - }); - expectLengthsToBe(3); - }); - - describe('when adding arbitrary values to the array', () => { - beforeEach(() => { - resource.values.push('something'); - }); - expectLengthsToBe(2, 'not update'); - }); - - describe('when removing resources from the array', () => { - beforeEach(() => { - resource.values.pop(); - }); - expectLengthsToBe(1); - }); - - describe('when each value is transformed', () => { - beforeEach(() => { - resource = resource.values[0]; - source = source._links.values[0]; - }); - - it('should have made each link a resource', () => { - expect(resource.$isHal).to.be.true; - }); - - it('should be resources generated from the links', () => { - expect(resource.href).to.eq(source.href); - }); - - it('should have a name attribute equal to the title of its link', () => { - expect(resource.name).to.eq(source.title); - }); - - it('should not be loaded', () => { - expect(resource.$loaded).to.be.false; - }); - }); - }); - - describe('when transforming an object with an _embedded list with the list element having _links', () => { - beforeEach(() => { - source = { - _embedded: { - elements: [{_links: {}}, {_links: {}}] - } - }; - - resource = new HalResource(source); - }); - - it('should not have the original _embedded property', () => { - expect(resource._embedded).to.not.be.ok; - }); - - it('should transform the list elements', () => { - expect(resource.$embedded.elements[0].$isHal).to.be.true; - expect(resource.$embedded.elements[1].$isHal).to.be.true; - }); - }); - - describe('when transforming an object with _links and _embedded', () => { - beforeEach(() => { - source = { - _links: { - property: { - href: '/api/property', - title: 'Property' - }, - embedded: { - href: '/api/embedded', - }, - action: { - href: '/api/action', - method: 'post' - }, - self: { - href: '/api/self' - } - }, - _embedded: { - embedded: { - _links: { - self: { - href: '/api/embedded' - } - }, - name: 'name' - }, - notLinked: { - _links: { - self: { - href: '/api/not-linked' - } - } - } - } - }; - - resource = new HalResource(source); - }); - - it('should be loaded', () => { - expect(resource.$loaded).to.be.true; - }); - - it('should not be possible to override a link', () => { - try { - resource.$links.action = 'foo'; - } catch (ignore) { - /**/ - } - - expect(resource.$links.action).to.not.eq('foo'); - }); - - it('should not be possible to override an embedded resource', () => { - try { - resource.$embedded.embedded = 'foo'; - } catch (ignore) { - /**/ - } - - expect(resource.$embedded.embedded).to.not.eq('foo'); - }); - - it('should have linked resources as properties', () => { - expect(resource.property).to.exist; - }); - - it('should have linked actions as properties', () => { - expect(resource.action).to.exist; - }); - - it('should have embedded resources as properties', () => { - expect(resource.embedded).to.exist; - }); - - it('should have embedded, but not linked resources as properties', () => { - expect(resource.notLinked).to.exist; - }); - - describe('when a resource that is linked and embedded is updated', () => { - var embeddedResource; - beforeEach(() => { - embeddedResource = { - $link: { - method: 'get', - href: 'newHref' - } - }; - - resource.embedded = embeddedResource; - }); - - it('should update the source', () => { - expect(resource.$source._links.embedded.href).to.eq('newHref'); - }); - }); - - describe('when after generating the properties from the links, each property', () => { - it('should be a function, if the link method is not "get"', () => { - expect(resource).to.respondTo('action'); - }); - - it('should be a resource, if the link method is "get"', () => { - expect(resource.property.$isHal).to.be.true; - }); - - describe('when a property is a resource', () => { - it('should not be callable', () => { - expect(resource).to.not.to.respondTo('property'); - }); - - it('should not be loaded initially', () => { - expect(resource.property.$loaded).to.be.false; - expect(resource.notLinked.$loaded).to.be.true; - }); - - it('should be loaded, if the resource is embedded', () => { - expect(resource.embedded.$loaded).to.be.true; - }); - - it('should update the source when set', () => { - resource.property = resource; - expect(resource.$source._links.property.href).to.eql('/api/self'); - }); - - describe('when loading it', () => { - beforeEach(() => { - resource = resource.property; - resource.$load(); - - $httpBackend.expectGET('/api/property').respond(200, { - _links: {}, - name: 'name', - foo: 'bar' - }); - $httpBackend.flush(); - }); - - it('should be loaded', () => { - expect(resource.$loaded).to.be.true; - }); - - it('should be updated', () => { - expect(resource.name).to.eq('name'); - }); - - it('should have properties that have a getter', () => { - expect((Object as any).getOwnPropertyDescriptor(resource, 'foo').get).to.exist; - }); - - it('should have properties that have a setter', () => { - expect((Object as any).getOwnPropertyDescriptor(resource, 'foo').set).to.exist; - }); - - it('should return itself in a promise if already loaded', () => { - resource.$loaded = 1; - - expect(resource.$load()).to.eventually.be.fulfilled.then(result => { - expect(result).to.equal(result); - }); - }); - }); - }); - }); - }); -}); diff --git a/frontend/app/components/api/api-v3/hal-resources/hal-resource.service.ts b/frontend/app/components/api/api-v3/hal-resources/hal-resource.service.ts deleted file mode 100644 index e43270f838..0000000000 --- a/frontend/app/components/api/api-v3/hal-resources/hal-resource.service.ts +++ /dev/null @@ -1,394 +0,0 @@ -//-- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -//++ - -import {InputState} from "reactivestates"; -import {opApiModule} from "../../../../angular-modules"; -import {HalLink, HalLinkInterface} from "../hal-link/hal-link.service"; -import {HalResourceFactoryService} from "../hal-resource-factory/hal-resource-factory.service"; - -const ObservableArray:any = require('observable-array'); - -var $q:ng.IQService; -var lazy:Function; -var halLink:typeof HalLink; -var halResourceFactory:HalResourceFactoryService; -var CacheService:any; - -export class HalResource { - [attribute:string]:any; - public _type:string; - - public static create(element:any, force:boolean = false) { - if (_.isNil(element)) { - return element; - } - - - if (!force && !(element._embedded || element._links)) { - return element; - } - - return halResourceFactory.createHalResource(element); - } - - public static fromLink(link:HalLinkInterface) { - const resource = HalResource.getEmptyResource(halLink.fromObject(link)); - return new HalResource(resource, false); - } - - public static getEmptyResource(self:{href:string|null} = {href: null}):any { - return {_links: {self: self}}; - } - - public $links:any = {}; - public $embedded:any = {}; - public $self:ng.IPromise; - - public _name:string; - - public static idFromLink(href:string):string { - return href.split('/').pop()!; - } - - public get idFromLink():string { - if (this.$href) { - return HalResource.idFromLink(this.$href); - } - - return ''; - } - - public get $isHal():boolean { - return true; - } - - public get $link():HalLinkInterface { - return this.$links.self.$link; - } - - public get name():string { - return this._name || this.$link.title || ''; - } - - public set name(name:string) { - this._name = name; - } - - /** - * Alias for $href. - * Please use $href instead. - * - * @deprecated - */ - public get href():string|null { - return this.$link.href; - } - - public get $href():string|null { - return this.$link.href; - } - - constructor(public $source:any = HalResource.getEmptyResource(), - public $loaded:boolean = true) { - this.$initialize($source); - } - - /** - * Return the associated state to this HAL resource, if any. - */ - public get state(): InputState | null { - return null; - } - - public $load(force = false):ng.IPromise { - if (!this.state) { - return this.$loadResource(force); - } - - const state = this.state; - - if (force) { - state.clear(); - } - - // If nobody has asked yet for the resource to be $loaded, do it ourselves. - // Otherwise, we risk returning a promise, that will never be resolved. - state.putFromPromiseIfPristine(() => this.$loadResource(force)); - - return > state.valuesPromise().then(source => { - this.$initialize(source); - this.$loaded = true; - return this; - }); - } - - protected $loadResource(force = false):ng.IPromise { - if (!force) { - if (this.$loaded) { - return $q.when(this); - } - - if (!this.$loaded && this.$self) { - return this.$self; - } - } - - // HACK: Remove cleared promise key from cache. - // We should not be so clever as to do that, instead, rewrite this with states. - if (force) { - CacheService.clearPromisedKey(this.$links.self.href); - } - // Reset and load this resource - this.$loaded = false; - this.$self = this.$links.self({}, this.$loadHeaders(force)).then((source:any) => { - this.$loaded = true; - this.$initialize(source); - return this; - }); - - return this.$self; - } - - /** - * Update the resource ignoring the cache. - */ - public $update() { - return this.$load(true); - } - - public $plain() { - return angular.copy(this.$source); - } - - public $copy() { - let clone:any = this.constructor - return new clone(_.cloneDeep(this.$source), this.$loaded);; - } - - public $initialize(source:any) { - this.$source = source.$source || source; - initializeResource(this); - } - - /** - * $load by default uses the $http cache. This will likely be replaced by - the HAL cache, but while it lasts, it should be ignored when using - force. - */ - protected $loadHeaders(force:boolean) { - var headers:any = {}; - - if (force) { - headers.caching = {enabled: false}; - } - - return headers; - } - - /** - * Specify this resource's embedded keys that should be transformed with resources. - * Use this to restrict, e.g., links that should not be made properties if you have a custom get/setter. - */ - public $embeddableKeys():string[] { - const properties = Object.keys(this.$source); - return _.without(properties, '_links', '_embedded'); - } - - /** - * Specify this resource's keys that should not be transformed with resources. - * Use this to restrict, e.g., links that should not be made properties if you have a custom get/setter. - */ - public $linkableKeys():string[] { - const properties = Object.keys(this.$links); - return _.without(properties, 'self'); - } - - /** - * Get a linked resource from its HalLink with the correct ype - */ - public createLinkedResource(linkName:string, link:HalLinkInterface) { - const resource = HalResource.getEmptyResource(); - const type = this.constructor._type; - resource._links.self = link; - - return halResourceFactory.createLinkedHalResource(resource, type, linkName); - } -} - -function initializeResource(halResource:HalResource) { - setSource(); - setupLinks(); - setupEmbedded(); - proxyProperties(); - setLinksAsProperties(); - setEmbeddedAsProperties(); - - function setSource() { - if (!halResource.$source._links) { - halResource.$source._links = {}; - } - - if (!halResource.$source._links.self) { - halResource.$source._links.self = new HalLink(); - } - } - - function proxyProperties() { - halResource.$embeddableKeys().forEach((property:any) => { - Object.defineProperty(halResource, property, { - get() { - return halResource.$source[property]; - }, - - set(value) { - halResource.$source[property] = value; - }, - - enumerable: true, - configurable: true - }); - }); - } - - function setLinksAsProperties() { - halResource.$linkableKeys().forEach((linkName:string) => { - lazy(halResource, linkName, - () => { - const link:any = halResource.$links[linkName].$link || halResource.$links[linkName]; - - if (Array.isArray(link)) { - var items = link.map(item => halResource.createLinkedResource(linkName, item.$link)); - var property:HalResource[] = new ObservableArray(...items).on('change', () => { - property.forEach(item => { - if (!item.$link) { - property.splice(property.indexOf(item), 1); - } - }); - - halResource.$source._links[linkName] = property.map(item => item.$link); - }); - - return property; - } - - if (link.href) { - if (link.method !== 'get') { - return HalLink.callable(link); - } - - return halResource.createLinkedResource(linkName, link); - } - - return null; - }, - (val:any) => setter(val, linkName) - ); - }); - } - - function setEmbeddedAsProperties() { - if (!halResource.$source._embedded) { - return; - } - - Object.keys(halResource.$source._embedded).forEach(name => { - lazy(halResource, name, () => halResource.$embedded[name], (val:any) => setter(val, name)); - }); - } - - function setupProperty(name:string, callback:(element:any) => any) { - const instanceName = '$' + name; - const sourceName = '_' + name; - const sourceObj = halResource.$source[sourceName]; - - if (angular.isObject(sourceObj)) { - Object.keys(sourceObj).forEach(propName => { - lazy((halResource as any)[instanceName], propName, () => callback(sourceObj[propName])); - }); - } - } - - function setupLinks() { - setupProperty('links', - link => Array.isArray(link) ? link.map(HalLink.callable) : HalLink.callable(link)); - } - - function setupEmbedded() { - setupProperty('embedded', element => { - angular.forEach(element, (child:any, name:string) => { - if (child && (child._embedded || child._links)) { - lazy(element, name, () => HalResource.create(child)); - } - }); - - if (Array.isArray(element)) { - return element.map((source) => HalResource.create(source, true)); - } - - return HalResource.create(element); - }); - } - - function setter(val:HalResource|{ href?: string }, linkName:string) { - if (!val) { - halResource.$source._links[linkName] = {href: null}; - } else if (_.isArray(val)) { - halResource.$source._links[linkName] = val.map((el:any) => { return {href: el.href} }); - } else if (val.hasOwnProperty('$link')) { - const link = (val as HalResource).$link; - - if (link.href) { - halResource.$source._links[linkName] = link; - } - } else if ('href' in val) { - halResource.$source._links[linkName] = {href: val.href}; - } - - if (halResource.$embedded && halResource.$embedded[linkName]) { - halResource.$embedded[linkName] = val; - halResource.$source._embedded[linkName] = _.get(val, '$source', val); - } - - return val; - } -} - -function halResourceService(...args:any[]) { - [$q, lazy, halLink, halResourceFactory, CacheService] = args; - return HalResource; -} - -halResourceService.$inject = [ - '$q', - 'lazy', - 'HalLink', - 'halResourceFactory', - 'CacheService' -]; - -opApiModule.factory('HalResource', halResourceService); diff --git a/frontend/app/components/api/api-v3/hal-resources/query-schema-resource.service.ts b/frontend/app/components/api/api-v3/hal-resources/query-schema-resource.service.ts deleted file mode 100644 index d7eb5ff396..0000000000 --- a/frontend/app/components/api/api-v3/hal-resources/query-schema-resource.service.ts +++ /dev/null @@ -1,41 +0,0 @@ -//-- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -//++ - -import {SchemaResource, SchemaAttributeObject} from './schema-resource.service'; -import {CollectionResource} from './collection-resource.service'; -import {QueryColumn} from '../../../wp-query/query-column'; -import {QuerySortByResource} from './query-sort-by-resource.service'; -import {QueryGroupByResource} from './query-group-by-resource.service'; -import {QueryFilterInstanceSchemaResource} from "core-components/api/api-v3/hal-resources/query-filter-instance-schema-resource.service"; - -export interface QuerySchemaResourceInterface extends SchemaResource { - columns:{ allowedValues: QueryColumn[] }; - filtersSchemas: CollectionResource; - sortBy:{ allowedValues: QuerySortByResource[] }; - groupBy:{ allowedValues: QueryGroupByResource[] }; -} diff --git a/frontend/app/components/api/api-v3/hal-resources/work-package-resource.service.test.ts b/frontend/app/components/api/api-v3/hal-resources/work-package-resource.service.test.ts deleted file mode 100644 index 28550445ef..0000000000 --- a/frontend/app/components/api/api-v3/hal-resources/work-package-resource.service.test.ts +++ /dev/null @@ -1,455 +0,0 @@ -//-- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -//++ - -import {opApiModule} from '../../../../angular-modules'; -import {WorkPackageCacheService} from '../../../work-packages/work-package-cache.service'; -import IHttpBackendService = angular.IHttpBackendService; -import IQService = angular.IQService; -import IRootScopeService = angular.IRootScopeService; -import IPromise = angular.IPromise; - -describe('WorkPackageResource service', () => { - var $httpBackend: IHttpBackendService; - var $rootScope: IRootScopeService; - var $q: IQService; - var WorkPackageResource:any; - var AttachmentCollectionResource:any; - var wpCacheService: WorkPackageCacheService; - var NotificationsService: any; - var wpNotificationsService: any; - - var source: any; - var workPackage: any; - - const createWorkPackage = () => { - source = source || { id: 'new' }; - workPackage = new WorkPackageResource(source); - }; - - const expectUncachedRequest = (href:string) => { - $httpBackend - .expectGET(href, (headers:any) => headers.caching.enabled === false) - .respond(200, {_links: {self: {href}}}); - }; - - const expectUncachedRequests = (...urls:string[]) => { - urls.forEach(expectUncachedRequest); - $httpBackend.flush(); - }; - - beforeEach(angular.mock.module(opApiModule.name)); - beforeEach(angular.mock.inject(function (_$httpBackend_:any, - _$rootScope_:any, - _$q_:any, - _WorkPackageResource_:any, - _AttachmentCollectionResource_:any, - _wpCacheService_:any, - _NotificationsService_:any, - _wpNotificationsService_:any) { - [ - $httpBackend, - $rootScope, - $q, - WorkPackageResource, - AttachmentCollectionResource, - wpCacheService, - NotificationsService, - wpNotificationsService - ] = _.toArray(arguments); - })); - - it('should exist', () => { - expect(WorkPackageResource).to.exist; - }); - - describe('when creating an empty work package', () => { - beforeEach(createWorkPackage); - - it('should have an attachments property of type `AttachmentCollectionResource`', () => { - expect(workPackage.attachments).to.be.instanceOf(AttachmentCollectionResource); - }); - - it('should return true for `isNew`', () => { - expect(workPackage.isNew).to.be.true; - }); - }); - - describe('when retrieving `canAddAttachment`', () => { - beforeEach(createWorkPackage); - - const expectValue = (value:any, prepare = () => angular.noop()) => { - value = value.toString(); - - beforeEach(prepare); - it('should be ' + value, () => { - (expect(workPackage.canAddAttachments).to.be as any)[value]; - }); - }; - - describe('when the work package is new', () => { - expectValue(true); - }); - - describe('when the work package is not new', () => { - expectValue(false, () => { - workPackage.id = 420; - }); - }); - - describe('when the work work package has no `addAttachment` link and is not new', () => { - expectValue(false, () => { - workPackage.id = 69; - workPackage.$links.addAttachment = null; - }); - }); - - describe('when the work work package has an `addAttachment` link', () => { - expectValue(true, () => { - workPackage.$links.addAttachment = angular.noop; - }); - }); - }); - - describe('when updating multiple linked resources', () => { - var updateWorkPackageStub: sinon.SinonStub; - var result:Promise; - - const expectCacheUpdate = () => { - it('should update the work package cache', () => { - result.then(() => { - expect(updateWorkPackageStub.calledWith(workPackage.id)).to.be.true; - }); - }); - }; - - beforeEach(() => { - updateWorkPackageStub = sinon.stub(wpCacheService, 'touch'); - }); - - afterEach(() => { - $rootScope.$apply(); - updateWorkPackageStub.restore(); - }); - - describe('when the resources are properties of the work package', () => { - const testResultIsResource = (href:string, prepare:any) => { - beforeEach(prepare); - expectCacheUpdate(); - - it('should be a promise with a resource where the $href is ' + href, () => { - expect(result).to.eventually.have.property('$href', href); - }); - }; - - beforeEach(() => { - source = { - _links: { - schema: { _type: 'Schema', href: 'schema' }, - attachments: { href: 'attachmentsHref' }, - activities: { href: 'activitiesHref' } - } - }; - createWorkPackage(); - }); - - describe('when updating the properties using updateLinkedResources()', () => { - var results:any; - - beforeEach(() => { - results = workPackage.updateLinkedResources('attachments', 'activities'); - expectUncachedRequests('attachmentsHref', 'activitiesHref'); - }); - - it('should return a result, that has the same properties as the updated ones', () => { - expect(results).to.eventually.be.fulfilled.then(results => { - expect(Object.keys(results)).to.have.members(['attachments', 'activities']); - }); - }); - - testResultIsResource('attachmentsHref', () => { - results.then((results:any) => result = $q.when(results.attachments)); - }); - - testResultIsResource('activitiesHref', () => { - results.then((results:any) => result = $q.when(results.activities)); - }); - }); - - describe('when updating the activities', () => { - testResultIsResource('activitiesHref', () => { - result = workPackage.updateActivities(); - expectUncachedRequests('activitiesHref'); - }); - }); - - describe('when updating the attachments', () => { - testResultIsResource('attachmentsHref', () => { - result = workPackage.updateAttachments(); - expectUncachedRequests('activitiesHref', 'attachmentsHref'); - }); - }); - }); - - describe('when the linked resource are not properties of the work package', () => { - const expectRejectedWithCacheUpdate = (prepare:any) => { - beforeEach(prepare); - - it('should return a rejected promise', () => { - expect(result).to.eventually.be.rejected; - }); - - expectCacheUpdate(); - }; - - beforeEach(() => { - source = {}; - createWorkPackage(); - }); - - describe('when using updateLinkedResources', () => { - expectRejectedWithCacheUpdate(() => { - result = workPackage.updateLinkedResources('attachments', 'activities'); - }); - }); - - describe('when using updateActivities', () => { - expectRejectedWithCacheUpdate(() => { - result = workPackage.updateActivities(); - }); - }); - - describe('when using updateAttachments', () => { - expectRejectedWithCacheUpdate(() => { - result = workPackage.updateAttachments(); - }); - }); - }); - }); - - describe('when a work package is created with attachments and activities', () => { - beforeEach(() => { - source = { - _links: { - schema: { _type: 'Schema', href: 'schema' }, - attachments: { href: 'attachments' }, - activities: { href: 'activities' } - }, - isNew: true - }; - createWorkPackage(); - }); - - describe('when adding multiple attachments to the work package', () => { - var file: any = {}; - var files: any[] = [file, file]; - var uploadFilesDeferred:any; - var uploadAttachmentsPromise:any; - var attachmentsUploadStub:any; - var uploadNotificationStub:any; - - beforeEach(() => { - uploadFilesDeferred = $q.defer(); - const uploadResult = { - uploads: [uploadFilesDeferred.promise], - finished: uploadFilesDeferred.promise - }; - attachmentsUploadStub = sinon.stub(workPackage.attachments, 'upload').returns(uploadResult); - uploadNotificationStub = sinon.stub(NotificationsService, 'addWorkPackageUpload'); - - uploadAttachmentsPromise = workPackage.uploadAttachments(files); - }); - - it('should call the upload method of the attachment collection resource', () => { - expect(attachmentsUploadStub.calledWith(files)).to.be.true; - }); - - it('should add an upload notification', () => { - expect(uploadNotificationStub.calledOnce).to.be.true; - }); - - describe('when the upload fails', () => { - var notificationStub:any; - var error = 'err'; - - beforeEach(() => { - uploadFilesDeferred.reject(error); - notificationStub = sinon.stub(wpNotificationsService, 'handleRawError'); - $rootScope.$apply(); - }); - - it('should call the error response notification', () => { - expect(notificationStub.calledWith(error, workPackage)).to.be.true; - }); - }); - - describe('when the upload succeeds', () => { - var removeStub:any; - var updateWorkPackageStub:any; - var updateWorkPackageTouchStub: sinon.SinonStub; - - beforeEach(() => { - updateWorkPackageStub = sinon.stub(wpCacheService, 'updateWorkPackage'); - uploadFilesDeferred.resolve(); - updateWorkPackageTouchStub = sinon.stub(wpCacheService, 'touch'); - removeStub = sinon.stub(NotificationsService, 'remove'); - - expectUncachedRequest('activities'); - expectUncachedRequest('attachments'); - $httpBackend - .when('GET', 'schema') - .respond(200, {_links: {self: 'schema'}}); - $httpBackend.flush(); - $rootScope.$apply(); - }); - - it('should remove the upload notification', angular.mock.inject(($timeout:ng.ITimeoutService) => { - $timeout.flush(); - expect(removeStub.calledOnce).to.be.true; - })); - - it('should return an attachment collection resource promise', () => { - expect(uploadAttachmentsPromise).to.eventually.have.property('$href', 'attachments'); - $rootScope.$apply(); - }); - - afterEach(() => { - updateWorkPackageStub.restore(); - updateWorkPackageTouchStub.restore(); - removeStub.restore(); - }); - }); - }); - - describe('when using uploadPendingAttachments', () => { - var uploadAttachmentsStub: sinon.SinonStub; - - beforeEach(() => { - workPackage.pendingAttachments.push({}, {}); - uploadAttachmentsStub = sinon - .stub(workPackage, 'uploadAttachments') - .returns($q.when()); - }); - - beforeEach(() => { - workPackage.isNew = false; - workPackage.uploadPendingAttachments(); - }); - - it('should call the uploadAttachments method with the pendingAttachments', () => { - expect(uploadAttachmentsStub.calledWith([{},{}])).to.be.true; - }); - - describe('when the upload succeeds', () => { - beforeEach(() => { - $rootScope.$apply(); - }); - - it('should reset the pending attachments', () => { - expect(workPackage.pendingAttachments).to.have.length(0); - }); - }); - }); - }); - - describe('when using removeAttachment', () => { - var file:any; - var attachment:any; - - beforeEach(() => { - file = {}; - attachment = { - $isHal: true, - 'delete': sinon.stub() - }; - - createWorkPackage(); - workPackage.attachments = {elements: [attachment]}; - workPackage.pendingAttachments.push(file); - }); - - describe('when the attachment is a regular file', () => { - beforeEach(() => { - workPackage.removeAttachment(file); - }); - - it('should be removed from the pending attachments', () => { - expect(workPackage.pendingAttachments).to.have.length(0); - }); - }); - - describe('when the attachment is an attachment resource', () => { - var deletion:any; - - beforeEach(() => { - deletion = $q.defer(); - attachment.delete.returns(deletion.promise); - sinon.stub(workPackage, 'updateAttachments'); - - workPackage.removeAttachment(attachment); - }); - - it('should call its delete method', () => { - expect(attachment.delete.calledOnce).to.be.true; - }); - - describe('when the deletion gets resolved', () => { - beforeEach(() => { - deletion.resolve(); - $rootScope.$apply(); - }); - - it('should call updateAttachments()', () => { - expect(workPackage.updateAttachments.calledOnce).to.be.true; - }); - }); - - describe('when an error occurs', () => { - var error:any; - - beforeEach(() => { - error = {foo: 'bar'}; - sinon.stub(wpNotificationsService, 'handleErrorResponse'); - deletion.reject(error); - $rootScope.$apply(); - }); - - it('should call the handleErrorResponse notification', () => { - const calledWithErrorAndWorkPackage = wpNotificationsService - .handleErrorResponse - .calledWith(error, workPackage); - - expect(calledWithErrorAndWorkPackage).to.be.true; - }); - - it('should not remove the attachment from the elements array', () => { - expect(workPackage.attachments.elements).to.have.length(1); - }); - }); - }); - }); -}); diff --git a/frontend/app/components/api/api-work-packages/api-work-packages.service.ts b/frontend/app/components/api/api-work-packages/api-work-packages.service.ts index 54179ff2d8..526df40d7d 100644 --- a/frontend/app/components/api/api-work-packages/api-work-packages.service.ts +++ b/frontend/app/components/api/api-work-packages/api-work-packages.service.ts @@ -26,21 +26,13 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from '../api-v3/hal-resources/hal-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; import {opApiModule} from '../../../angular-modules'; -import {HalRequestService} from '../api-v3/hal-request/hal-request.service'; -import { - WorkPackageResource, - WorkPackageResourceInterface, -} from '../api-v3/hal-resources/work-package-resource.service'; -import { - WorkPackageCollectionResource, - WorkPackageCollectionResourceInterface, -} from '../api-v3/hal-resources/wp-collection-resource.service'; import {States} from '../../states.service'; -import IPromise = angular.IPromise; -import {SchemaResource} from '../api-v3/hal-resources/schema-resource.service'; -import {ApiV3FilterBuilder, buildApiV3Filter} from '../api-v3/api-v3-filter-builder'; +import {buildApiV3Filter} from '../api-v3/api-v3-filter-builder'; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource'; export class ApiWorkPackagesService { constructor(protected $q:ng.IQService, @@ -59,11 +51,7 @@ export class ApiWorkPackagesService { public async loadWorkPackageById(id:string, force = false) { const url = this.v3Path.wp({wp: id}); - return this.halRequest.get(url, null, { - caching: { - enabled: !force - } - }) as Promise; + return this.halRequest.get(url).toPromise(); } /** @@ -71,18 +59,16 @@ export class ApiWorkPackagesService { * Returns a WP Collection with schemas and results embedded. * * @param ids - * @return {WorkPackageCollectionResourceInterface[]} + * @return {WorkPackageCollectionResource[]} */ - public loadWorkPackagesCollectionsFor(ids:string[]) { + public loadWorkPackagesCollectionsFor(ids:string[]):Promise { return this.halRequest.getAllPaginated( this.v3Path.wps(), ids.length, { filters: buildApiV3Filter('id', '=', ids).toJson(), - }, - { - caching: { enabled: false } - }) as any; + } + ) as any; // WorkPackageCollectionResource does not satisfy constraint HalResource[] } /** @@ -90,8 +76,10 @@ export class ApiWorkPackagesService { * * @returns An empty work package form resource. */ - public emptyCreateForm(request:any, projectIdentifier?:string):ng.IPromise { - return this.halRequest.post(this.v3Path.wp.form({ project: projectIdentifier }), request); + public emptyCreateForm(request:any, projectIdentifier?:string):Promise { + return this.halRequest + .post(this.v3Path.wp.form({ project: projectIdentifier }), request) + .toPromise(); } /** @@ -102,29 +90,35 @@ export class ApiWorkPackagesService { * @param projectIdentifier: The project to which the work package is initialized * @returns An empty work package form resource. */ - public typedCreateForm(typeId:number, projectIdentifier?:string):ng.IPromise { + public typedCreateForm(typeId:number, projectIdentifier?:string):Promise { const typeUrl = this.v3Path.types({type: typeId}); const request = { _links: { type: { href: typeUrl } } }; - return this.halRequest.post(this.v3Path.wp.form({ project: projectIdentifier }), request); + return this.halRequest + .post(this.v3Path.wp.form({ project: projectIdentifier }), request) + .toPromise(); } /** * Returns a promise to GET `/api/v3/work_packages/available_projects`. */ - public availableProjects(projectIdentifier?:string):ng.IPromise { - return this.halRequest.get(this.v3Path.wp.availableProjects({project: projectIdentifier})); + public availableProjects(projectIdentifier?:string):Promise { + return this.halRequest + .get(this.v3Path.wp.availableProjects({project: projectIdentifier})) + .toPromise(); } /** * Create a work package from a form payload * * @param payload - * @return {ng.IPromise} + * @return {Promise} */ - public createWorkPackage(payload:any):ng.IPromise { - return this.halRequest.post(this.v3Path.wps(), payload); + public createWorkPackage(payload:any):Promise { + return this.halRequest + .post(this.v3Path.wps(), payload) + .toPromise(); } } diff --git a/frontend/app/components/caching/cache-service.service.ts b/frontend/app/components/caching/cache-service.service.ts deleted file mode 100644 index 12aa4f8d08..0000000000 --- a/frontend/app/components/caching/cache-service.service.ts +++ /dev/null @@ -1,141 +0,0 @@ -//-- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -//++ - -function CacheService($q:ng.IQService, CacheFactory:any) { - - // Temporary storage for currently resolving promises - var _promises:{[key:string]: ng.IPromise} = {}; - - // Global switch to disable all caches - var disabled = false; - - var CacheService = { - - temporaryCache: function() { - return CacheService.customCache('openproject-session_cache', { - maxAge: 10 * 60 * 1000, // 10 mins - storageMode: 'sessionStorage' - }); - }, - - localStorage: function() { - return CacheService.customCache('openproject-local_storage_cache', { - storageMode: 'localStorage' - }); - }, - - memoryStorage: function() { - return CacheService.customCache('openproject-memory_storage_cache', { - storageMode: 'memory' - }); - }, - - customCache: function(identifier:string, params:any) { - var _cache = CacheFactory.get(identifier); - - if (!_cache) { - _cache = CacheFactory(identifier, params); - } - - if (disabled) { - _cache.disable(); - } - - return _cache; - }, - - isCacheDisabled: function() { - return disabled; - }, - - enableCaching: function() { - disabled = false; - }, - - disableCaching: function() { - disabled = true; - }, - - clearPromisedKey: function(key:string, options:any) { - options = options || {}; - var cache = options.cache || CacheService.memoryStorage(); - cache.remove(key); - }, - - cachedPromise: function(promiseFn:() => ng.IPromise, key:string, options:any) { - options = options || {}; - var cache = options.cache || CacheService.memoryStorage(); - var force = options.force || false; - var deferred = $q.defer(); - var cachedValue, promise; - - // Return early when frontend caching is not desired - if (cache.disabled) { - return promiseFn(); - } - - // Got the result directly? Great. - cachedValue = cache.get(key); - if (cachedValue && !force) { - deferred.resolve(cachedValue); - return deferred.promise; - } - - // Return an existing promise if it exists - // Avoids intermittent requests while a first - // is already underway. - if (_promises[key]) { - return _promises[key]; - } - - // Call now to retrieve promise - promise = promiseFn(); - promise - .then(data => { - cache.put(key, data); - deferred.resolve(data); - }) - .catch(error => { - deferred.reject(error); - cache.remove(key); - }) - .finally(() => delete _promises[key]); - - _promises[key] = deferred.promise; - return deferred.promise; - }, - }; - - return CacheService; -} - - -angular - .module('openproject.services') - .factory('CacheService', CacheService); - diff --git a/frontend/app/components/common/authoring/authoring.component.ts b/frontend/app/components/common/authoring/authoring.component.ts index 1ba79deebc..d9e7add415 100644 --- a/frontend/app/components/common/authoring/authoring.component.ts +++ b/frontend/app/components/common/authoring/authoring.component.ts @@ -29,7 +29,7 @@ import {Component, Inject, Input, OnInit} from '@angular/core'; import {I18nToken, TimezoneServiceToken} from '../../../angular4-transition-utils'; import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; -import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; import {opUiComponentsModule} from 'core-app/angular-modules'; import {downgradeComponent} from '@angular/upgrade/static'; diff --git a/frontend/app/components/common/date/op-date-time.upgraded.directive.ts b/frontend/app/components/common/date/op-date-time.upgraded.directive.ts index 1c3b38da13..c3b638ade9 100644 --- a/frontend/app/components/common/date/op-date-time.upgraded.directive.ts +++ b/frontend/app/components/common/date/op-date-time.upgraded.directive.ts @@ -28,7 +28,7 @@ import {Component, Directive, ElementRef, Injector, Input, Output} from '@angular/core'; import {UpgradeComponent} from '@angular/upgrade/static'; -import {UserResource} from 'core-components/api/api-v3/hal-resources/user-resource.service'; +import {UserResource} from 'core-app/modules/hal/resources/user-resource'; @Directive({ selector: 'op-date-time' diff --git a/frontend/app/components/common/help-texts/attribute-help-text.directive.ts b/frontend/app/components/common/help-texts/attribute-help-text.directive.ts index adb04f8a4c..df2aa6ff23 100644 --- a/frontend/app/components/common/help-texts/attribute-help-text.directive.ts +++ b/frontend/app/components/common/help-texts/attribute-help-text.directive.ts @@ -30,9 +30,9 @@ import IAugmentedJQuery = angular.IAugmentedJQuery; import {IDialogService} from 'ng-dialog'; import {IDialogScope} from 'ng-dialog'; import {opUiComponentsModule} from '../../../angular-modules'; -import {HelpTextResourceInterface} from '../../api/api-v3/hal-resources/help-text-resource.service'; -import {HelpTextDmService} from '../../api/api-v3/hal-resource-dms/help-text-dm.service'; import {AttributeHelpTextsService} from './attribute-help-text.service'; +import {HelpTextDmService} from 'core-app/modules/dm-services/help-text-dm.service'; +import {HelpTextResource} from 'core-app/modules/hal/resources/help-text-resource'; export class AttributeHelpTextController { // Attribute to show help text for @@ -100,7 +100,7 @@ export class AttributeHelpTextController { } } - private renderModal(resource:HelpTextResourceInterface) { + private renderModal(resource:HelpTextResource) { this.$scope.resource = resource; this.ngDialog.open({ closeByEscape: true, diff --git a/frontend/app/components/common/help-texts/attribute-help-text.service.ts b/frontend/app/components/common/help-texts/attribute-help-text.service.ts index 4c4710eae3..7bdb7e0c73 100644 --- a/frontend/app/components/common/help-texts/attribute-help-text.service.ts +++ b/frontend/app/components/common/help-texts/attribute-help-text.service.ts @@ -26,14 +26,15 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {opUiComponentsModule} from '../../../angular-modules'; -import {HelpTextResourceInterface} from '../../api/api-v3/hal-resources/help-text-resource.service'; -import {HelpTextDmService} from '../../api/api-v3/hal-resource-dms/help-text-dm.service'; import {input} from 'reactivestates'; -import {CollectionResource} from "core-components/api/api-v3/hal-resources/collection-resource.service"; +import {HelpTextResource} from 'core-app/modules/hal/resources/help-text-resource'; +import {HelpTextDmService} from 'core-app/modules/dm-services/help-text-dm.service'; +import {Injectable} from '@angular/core'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +@Injectable() export class AttributeHelpTextsService { - private helpTexts = input(); + private helpTexts = input(); constructor(private helpTextDm:HelpTextDmService, private $q:ng.IQService) { @@ -45,12 +46,12 @@ export class AttributeHelpTextsService { * @param attribute * @param scope */ - public require(attribute:string, scope:string):ng.IPromise { - const deferred = this.$q.defer(); + public require(attribute:string, scope:string):Promise { + const deferred = this.$q.defer(); if (this.helpTexts.isPristine()) { this.helpTextDm.loadAll() - .then((resources:CollectionResource) => { + .then((resources:CollectionResource) => { this.helpTexts.putValue(resources.elements as any); deferred.resolve(this.find(attribute, scope)); }); @@ -61,10 +62,8 @@ export class AttributeHelpTextsService { return deferred.promise; } - private find(attribute:string, scope:string):HelpTextResourceInterface|undefined { + private find(attribute:string, scope:string):HelpTextResource|undefined { const value = this.helpTexts.getValueOr([]); return _.find(value, (element) => element.scope === scope && element.attribute === attribute); } } - -opUiComponentsModule.service('attributeHelpTexts', AttributeHelpTextsService); diff --git a/frontend/app/components/common/textile/textile-service.ts b/frontend/app/components/common/textile/textile-service.ts index 525b39cb6b..af4fea9aa7 100644 --- a/frontend/app/components/common/textile/textile-service.ts +++ b/frontend/app/components/common/textile/textile-service.ts @@ -27,16 +27,16 @@ //++ import {PathHelperService} from './../path-helper/path-helper.service'; -import {HalLink} from './../../api/api-v3/hal-link/hal-link.service'; -import {WorkPackageResourceInterface} from 'app/components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageNotificationService} from './../../wp-edit/wp-notification.service'; +import {HalLink} from 'core-app/modules/hal/hal-link/hal-link'; export class TextileService { constructor(public $http:ng.IHttpService, public wpNotificationsService:WorkPackageNotificationService, public PathHelper:PathHelperService) {} - public renderWithWorkPackageContext(workPackage:WorkPackageResourceInterface, text:string) { + public renderWithWorkPackageContext(workPackage:WorkPackageResource, text:string) { return this.render(workPackage.previewMarkup, text); } diff --git a/frontend/app/components/filters/abstract-filter-date-time-value/abstract-filter-date-time-value.controller.ts b/frontend/app/components/filters/abstract-filter-date-time-value/abstract-filter-date-time-value.controller.ts index 83c360acac..408488c0ee 100644 --- a/frontend/app/components/filters/abstract-filter-date-time-value/abstract-filter-date-time-value.controller.ts +++ b/frontend/app/components/filters/abstract-filter-date-time-value/abstract-filter-date-time-value.controller.ts @@ -29,7 +29,7 @@ import {filtersModule} from '../../../angular-modules'; import {Moment} from 'moment'; -import {QueryFilterInstanceResource} from '../../api/api-v3/hal-resources/query-filter-instance-resource.service'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; export abstract class AbstractDateTimeValueController { public filter:QueryFilterInstanceResource; diff --git a/frontend/app/components/filters/filter-boolean-value/filter-boolean-value.directive.ts b/frontend/app/components/filters/filter-boolean-value/filter-boolean-value.directive.ts index 299bc6bfda..35fe85a875 100644 --- a/frontend/app/components/filters/filter-boolean-value/filter-boolean-value.directive.ts +++ b/frontend/app/components/filters/filter-boolean-value/filter-boolean-value.directive.ts @@ -27,7 +27,7 @@ //++ import {filtersModule} from '../../../angular-modules'; -import {QueryFilterInstanceResource} from '../../api/api-v3/hal-resources/query-filter-instance-resource.service'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; export class BooleanValueController { public filter:QueryFilterInstanceResource; diff --git a/frontend/app/components/filters/filter-date-time-value/filter-date-time-value.directive.ts b/frontend/app/components/filters/filter-date-time-value/filter-date-time-value.directive.ts index f9d6b84c94..96468d3281 100644 --- a/frontend/app/components/filters/filter-date-time-value/filter-date-time-value.directive.ts +++ b/frontend/app/components/filters/filter-date-time-value/filter-date-time-value.directive.ts @@ -28,7 +28,7 @@ import {filtersModule} from '../../../angular-modules'; -import {QueryFilterInstanceResource} from '../../api/api-v3/hal-resources/query-filter-instance-resource.service'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; import {AbstractDateTimeValueController} from '../abstract-filter-date-time-value/abstract-filter-date-time-value.controller' export class DateTimeValueController extends AbstractDateTimeValueController { diff --git a/frontend/app/components/filters/filter-date-times-value/filter-date-times-value.directive.ts b/frontend/app/components/filters/filter-date-times-value/filter-date-times-value.directive.ts index 475656728d..b8ba047f4d 100644 --- a/frontend/app/components/filters/filter-date-times-value/filter-date-times-value.directive.ts +++ b/frontend/app/components/filters/filter-date-times-value/filter-date-times-value.directive.ts @@ -28,7 +28,7 @@ import {filtersModule} from '../../../angular-modules'; -import {QueryFilterInstanceResource} from '../../api/api-v3/hal-resources/query-filter-instance-resource.service'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; import {AbstractDateTimeValueController} from '../abstract-filter-date-time-value/abstract-filter-date-time-value.controller' export class DateTimesValueController extends AbstractDateTimeValueController { diff --git a/frontend/app/components/filters/filter-date-value/filter-date-value.directive.ts b/frontend/app/components/filters/filter-date-value/filter-date-value.directive.ts index 4b44473584..a265d4b1e4 100644 --- a/frontend/app/components/filters/filter-date-value/filter-date-value.directive.ts +++ b/frontend/app/components/filters/filter-date-value/filter-date-value.directive.ts @@ -28,7 +28,7 @@ import {filtersModule} from '../../../angular-modules'; -import {QueryFilterInstanceResource} from '../../api/api-v3/hal-resources/query-filter-instance-resource.service'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; export class DateValueController { public filter:QueryFilterInstanceResource; diff --git a/frontend/app/components/filters/filter-dates-value/filter-dates-value.directive.ts b/frontend/app/components/filters/filter-dates-value/filter-dates-value.directive.ts index b0c7d55238..253dc34912 100644 --- a/frontend/app/components/filters/filter-dates-value/filter-dates-value.directive.ts +++ b/frontend/app/components/filters/filter-dates-value/filter-dates-value.directive.ts @@ -28,7 +28,7 @@ import {filtersModule} from '../../../angular-modules'; -import {QueryFilterInstanceResource} from '../../api/api-v3/hal-resources/query-filter-instance-resource.service'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; export class DatesValueController { public filter:QueryFilterInstanceResource; diff --git a/frontend/app/components/filters/filter-integer-value/filter-integer-value.directive.ts b/frontend/app/components/filters/filter-integer-value/filter-integer-value.directive.ts index 081063b963..fdab45c978 100644 --- a/frontend/app/components/filters/filter-integer-value/filter-integer-value.directive.ts +++ b/frontend/app/components/filters/filter-integer-value/filter-integer-value.directive.ts @@ -28,9 +28,9 @@ import {filtersModule} from '../../../angular-modules'; -import {HalResource} from '../../api/api-v3/hal-resources/hal-resource.service'; -import {QueryFilterResource} from '../../api/api-v3/hal-resources/query-filter-resource.service'; -import {QueryFilterInstanceResource} from '../../api/api-v3/hal-resources/query-filter-instance-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {QueryFilterResource} from 'core-app/modules/hal/resources/query-filter-resource'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; export class IntegerValueController { public filter:QueryFilterInstanceResource; diff --git a/frontend/app/components/filters/filter-string-value/filter-string-value.directive.ts b/frontend/app/components/filters/filter-string-value/filter-string-value.directive.ts index 4813f00065..fd2c2b71f2 100644 --- a/frontend/app/components/filters/filter-string-value/filter-string-value.directive.ts +++ b/frontend/app/components/filters/filter-string-value/filter-string-value.directive.ts @@ -27,7 +27,7 @@ //++ import {filtersModule} from '../../../angular-modules'; -import {QueryFilterInstanceResource} from '../../api/api-v3/hal-resources/query-filter-instance-resource.service'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; export class StringValueController { public filter:QueryFilterInstanceResource; diff --git a/frontend/app/components/filters/filter-toggled-multiselect-value/filter-toggled-multiselect-value.directive.test.ts b/frontend/app/components/filters/filter-toggled-multiselect-value/filter-toggled-multiselect-value.directive.test.ts index bca7999827..82336abca9 100644 --- a/frontend/app/components/filters/filter-toggled-multiselect-value/filter-toggled-multiselect-value.directive.test.ts +++ b/frontend/app/components/filters/filter-toggled-multiselect-value/filter-toggled-multiselect-value.directive.test.ts @@ -29,7 +29,7 @@ /*jshint expr: true*/ import {ToggledMultiselectController} from './filter-toggled-multiselect-value.directive' -import {HalResource} from '../../api/api-v3/hal-resources/hal-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; describe('toggledMultiselect Directive', function() { var compile:any, element:any, rootScope:any, scope:any, I18n:any; diff --git a/frontend/app/components/filters/filter-toggled-multiselect-value/filter-toggled-multiselect-value.directive.ts b/frontend/app/components/filters/filter-toggled-multiselect-value/filter-toggled-multiselect-value.directive.ts index 4608ae7fdc..10d12b31e9 100644 --- a/frontend/app/components/filters/filter-toggled-multiselect-value/filter-toggled-multiselect-value.directive.ts +++ b/frontend/app/components/filters/filter-toggled-multiselect-value/filter-toggled-multiselect-value.directive.ts @@ -26,18 +26,16 @@ // See doc/COPYRIGHT.rdoc for more details. //++ - import {filtersModule} from '../../../angular-modules'; -import {HalResource} from '../../api/api-v3/hal-resources/hal-resource.service'; -import {UserResource} from '../../api/api-v3/hal-resources/user-resource.service'; -import {CollectionResource} from '../../api/api-v3/hal-resources/collection-resource.service'; -import { - QueryFilterInstanceResource -} from '../../api/api-v3/hal-resources/query-filter-instance-resource.service'; -import {RootDmService} from '../../api/api-v3/hal-resource-dms/root-dm.service'; -import {RootResource} from '../../api/api-v3/hal-resources/root-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {UserResource} from 'core-app/modules/hal/resources/user-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {RootResource} from 'core-app/modules/hal/resources/root-resource'; import {PathHelperService} from '../../common/path-helper/path-helper.service'; import {$injectFields} from '../../angular/angular-injector-bridge.functions'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; +import {RootDmService} from 'core-app/modules/dm-services/root-dm.service'; +import {Injector} from '@angular/core'; export class ToggledMultiselectController { // Injected @@ -51,6 +49,7 @@ export class ToggledMultiselectController { public text:{ [key: string]: string; }; constructor(public $scope:ng.IScope, + public injector:Injector, private I18n:op.I18n, private $q:ng.IQService, private RootDm:RootDmService) { @@ -135,7 +134,7 @@ export class ToggledMultiselectController { return; } - let me:HalResource = new HalResource({ + let me:HalResource = new HalResource(this.injector, { _links: { self: { href: this.PathHelper.apiV3UserMePath(), diff --git a/frontend/app/components/filters/query-filter/query-filter.directive.ts b/frontend/app/components/filters/query-filter/query-filter.directive.ts index 6de23e81dd..91f6b6a660 100644 --- a/frontend/app/components/filters/query-filter/query-filter.directive.ts +++ b/frontend/app/components/filters/query-filter/query-filter.directive.ts @@ -27,10 +27,10 @@ // ++ import {filtersModule} from '../../../angular-modules'; -import {QueryFilterInstanceResource} from '../../api/api-v3/hal-resources/query-filter-instance-resource.service'; -import {QueryFilterInstanceSchemaResource} from '../../api/api-v3/hal-resources/query-filter-instance-schema-resource.service'; -import {HalResource} from '../../api/api-v3/hal-resources/hal-resource.service'; -import {QueryOperatorResource} from '../../api/api-v3/hal-resources/query-operator-resource.service'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; +import {QueryFilterInstanceSchemaResource} from 'core-app/modules/hal/resources/query-filter-instance-schema-resource'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {QueryOperatorResource} from 'core-app/modules/hal/resources/query-operator-resource'; import {WorkPackageTableFiltersService} from '../../wp-fast-table/state/wp-table-filters.service'; function queryFilterDirective($animate:any, diff --git a/frontend/app/components/filters/query-filters/query-filters.directive.ts b/frontend/app/components/filters/query-filters/query-filters.directive.ts index be831d333f..63a24e8816 100644 --- a/frontend/app/components/filters/query-filters/query-filters.directive.ts +++ b/frontend/app/components/filters/query-filters/query-filters.directive.ts @@ -27,11 +27,11 @@ //++ import {filtersModule} from '../../../angular-modules'; -import {QueryFilterInstanceSchemaResource} from '../../api/api-v3/hal-resources/query-filter-instance-schema-resource.service' -import {QueryFilterInstanceResource} from '../../api/api-v3/hal-resources/query-filter-instance-resource.service' -import {QueryFilterResource} from '../../api/api-v3/hal-resources/query-filter-resource.service' -import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service' -import {FormResource} from '../../api/api-v3/hal-resources/form-resource.service' +import {QueryFilterInstanceSchemaResource} from 'core-app/modules/hal/resources/query-filter-instance-schema-resource' +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource' +import {QueryFilterResource} from 'core-app/modules/hal/resources/query-filter-resource' +import {QueryResource} from 'core-app/modules/hal/resources/query-resource' +import {FormResource} from 'core-app/modules/hal/resources/form-resource' import {WorkPackageTableFiltersService} from '../../wp-fast-table/state/wp-table-filters.service'; import WorkPackageFiltersService from "../../filters/wp-filters/wp-filters.service"; diff --git a/frontend/app/components/modals/confirm-dialog/confirm-dialog.service.ts b/frontend/app/components/modals/confirm-dialog/confirm-dialog.service.ts index 344ff8732a..9ef43d7181 100644 --- a/frontend/app/components/modals/confirm-dialog/confirm-dialog.service.ts +++ b/frontend/app/components/modals/confirm-dialog/confirm-dialog.service.ts @@ -62,7 +62,7 @@ export class ConfirmDialogService { /** * Confirm an action with an ng dialog with the given options */ - public confirm(options:ConfirmDialogOptions):ng.IPromise { + public confirm(options:ConfirmDialogOptions):Promise { const deferred = this.$q.defer(); const scope:any = this.$rootScope.$new(); let dialog:IDialogOpenResult; diff --git a/frontend/app/components/modals/export-modal/export-modal.controller.ts b/frontend/app/components/modals/export-modal/export-modal.controller.ts index c63fb2fc1e..a571a67b79 100644 --- a/frontend/app/components/modals/export-modal/export-modal.controller.ts +++ b/frontend/app/components/modals/export-modal/export-modal.controller.ts @@ -27,19 +27,19 @@ //++ import {wpControllersModule} from '../../../angular-modules'; -import {WorkPackageCollectionResource} from '../../api/api-v3/hal-resources/wp-collection-resource.service'; -import {HalLink} from '../../api/api-v3/hal-link/hal-link.service'; import {WorkPackageTableColumnsService} from '../../wp-fast-table/state/wp-table-columns.service'; import {TableState} from 'core-components/wp-table/table-state/table-state'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource'; +import {HalLink} from 'core-app/modules/hal/hal-link/hal-link'; interface ExportLink extends HalLink { identifier:string; } class ExportModalController { - public name: string; - public closeMe: Function; - public exportOptions: any; + public name:string; + public closeMe:Function; + public exportOptions:any; constructor(exportModal:any, private UrlParamsHelper:any, @@ -71,9 +71,11 @@ class ExportModalController { private addColumnsToHref(href:string) { let columns = this.wpTableColumns.getColumns(); - let columnIds = columns.map(function(column) { return column.id; }); + let columnIds = columns.map(function (column) { + return column.id; + }); - return href + "&" + this.UrlParamsHelper.buildQueryString({'columns[]': columnIds}); + return href + "&" + this.UrlParamsHelper.buildQueryString({ 'columns[]': columnIds }); } } diff --git a/frontend/app/components/modals/save-modal/save-modal.controller.ts b/frontend/app/components/modals/save-modal/save-modal.controller.ts index 91f34ce4cb..e4fd8143bd 100644 --- a/frontend/app/components/modals/save-modal/save-modal.controller.ts +++ b/frontend/app/components/modals/save-modal/save-modal.controller.ts @@ -30,8 +30,7 @@ import {wpControllersModule} from '../../../angular-modules'; import {WorkPackagesListService} from '../../wp-list/wp-list.service'; import {States} from '../../states.service'; import {WorkPackageNotificationService} from '../../wp-edit/wp-notification.service'; -import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service'; -import {QueryDmService} from '../../api/api-v3/hal-resource-dms/query-dm.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; function SaveModalController(this:any, $scope:any, @@ -73,7 +72,7 @@ function SaveModalController(this:any, return $q.when(true); }) .catch((error:any) => wpNotificationsService.handleErrorResponse(error)) - .finally(() => this.isBusy = false); + .then(() => this.isBusy = false); // Same as .finally() }; } diff --git a/frontend/app/components/modals/share-modal/share-modal.controller.ts b/frontend/app/components/modals/share-modal/share-modal.controller.ts index 6585c5dcd9..9ca0efca9c 100644 --- a/frontend/app/components/modals/share-modal/share-modal.controller.ts +++ b/frontend/app/components/modals/share-modal/share-modal.controller.ts @@ -29,7 +29,7 @@ import {wpControllersModule} from '../../../angular-modules'; import {States} from '../../states.service'; import {WorkPackagesListService} from '../../wp-list/wp-list.service'; -import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; export class ShareModalController { public query:QueryResource; diff --git a/frontend/app/components/modals/sorting-modal/sorting-modal.controller.ts b/frontend/app/components/modals/sorting-modal/sorting-modal.controller.ts index bc7113a364..3485a4ee1a 100644 --- a/frontend/app/components/modals/sorting-modal/sorting-modal.controller.ts +++ b/frontend/app/components/modals/sorting-modal/sorting-modal.controller.ts @@ -32,7 +32,7 @@ import { QUERY_SORT_BY_ASC, QUERY_SORT_BY_DESC, QuerySortByResource -} from '../../api/api-v3/hal-resources/query-sort-by-resource.service'; +} from 'core-app/modules/hal/resources/query-sort-by-resource'; import {QueryColumn} from '../../wp-query/query-column'; class SortModalObject { diff --git a/frontend/app/components/modals/wp-destroy-modal/wp-destroy-modal.controller.ts b/frontend/app/components/modals/wp-destroy-modal/wp-destroy-modal.controller.ts index c4d13eb013..4aa3367aec 100644 --- a/frontend/app/components/modals/wp-destroy-modal/wp-destroy-modal.controller.ts +++ b/frontend/app/components/modals/wp-destroy-modal/wp-destroy-modal.controller.ts @@ -28,13 +28,13 @@ import {wpControllersModule} from '../../../angular-modules'; import {States} from '../../states.service'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageTableFocusService} from 'core-components/wp-fast-table/state/wp-table-focus.service'; import {StateService} from '@uirouter/core'; export class WorkPackageDestroyModalController { public text:any; - public workPackages:WorkPackageResourceInterface[]; + public workPackages:WorkPackageResource[]; public workPackageLabel:string; constructor(private $scope:any, @@ -57,11 +57,11 @@ export class WorkPackageDestroyModalController { title: I18n.t('js.modals.destroy_work_package.title', { label: this.workPackageLabel }), text: I18n.t('js.modals.destroy_work_package.text', { label: this.workPackageLabel, count: this.workPackages.length }), - childCount: (wp:WorkPackageResourceInterface) => { + childCount: (wp:WorkPackageResource) => { const count = this.children(wp).length; return this.I18n.t('js.units.child_work_packages', {count: count}); }, - hasChildren: (wp:WorkPackageResourceInterface) => + hasChildren: (wp:WorkPackageResource) => I18n.t('js.modals.destroy_work_package.has_children', {childUnits: this.text.childCount(wp) }), deletesChildren: I18n.t('js.modals.destroy_work_package.deletes_children') }; @@ -89,10 +89,10 @@ export class WorkPackageDestroyModalController { }); } - public childLabel (workPackage:WorkPackageResourceInterface) { + public childLabel (workPackage:WorkPackageResource) { } - public children(workPackage:WorkPackageResourceInterface) { + public children(workPackage:WorkPackageResource) { if (workPackage.hasOwnProperty('children')) { return workPackage.children; } else { diff --git a/frontend/app/components/op-context-menu/handlers/op-settings-dropdown-menu.directive.ts b/frontend/app/components/op-context-menu/handlers/op-settings-dropdown-menu.directive.ts index bd25285d5d..411b05e114 100644 --- a/frontend/app/components/op-context-menu/handlers/op-settings-dropdown-menu.directive.ts +++ b/frontend/app/components/op-context-menu/handlers/op-settings-dropdown-menu.directive.ts @@ -38,8 +38,6 @@ import { sortingModalToken, timelinesModalToken } from 'core-app/angular4-transition-utils'; -import {QueryFormResource} from 'core-components/api/api-v3/hal-resources/query-form-resource.service'; -import {QueryResource} from 'core-components/api/api-v3/hal-resources/query-resource.service'; import {AuthorisationService} from 'core-components/common/model-auth/model-auth.service'; import {OpContextMenuTrigger} from 'core-components/op-context-menu/handlers/op-context-menu-trigger.directive'; import {OPContextMenuService} from 'core-components/op-context-menu/op-context-menu.service'; @@ -53,6 +51,8 @@ import {WorkPackageTableTimelineService} from 'core-components/wp-fast-table/sta import {WorkPackagesListService} from 'core-components/wp-list/wp-list.service'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {takeUntil} from 'rxjs/operators'; +import {QueryFormResource} from 'core-app/modules/hal/resources/query-form-resource'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; @Directive({ selector: '[opSettingsContextMenu]' diff --git a/frontend/app/components/op-context-menu/handlers/op-types-context-menu.directive.ts b/frontend/app/components/op-context-menu/handlers/op-types-context-menu.directive.ts index da07a61297..879ebe573a 100644 --- a/frontend/app/components/op-context-menu/handlers/op-types-context-menu.directive.ts +++ b/frontend/app/components/op-context-menu/handlers/op-types-context-menu.directive.ts @@ -31,10 +31,10 @@ import {StateService} from '@uirouter/core'; import {OPContextMenuService} from "core-components/op-context-menu/op-context-menu.service"; import {Directive, ElementRef, Inject, Input} from "@angular/core"; import {$stateToken} from "core-app/angular4-transition-utils"; -import {TypeResource} from "core-components/api/api-v3/hal-resources/type-resource.service"; -import {CollectionResource} from "core-components/api/api-v3/hal-resources/collection-resource.service"; import {LinkHandling} from "core-components/common/link-handling/link-handling"; import {OpContextMenuTrigger} from "core-components/op-context-menu/handlers/op-context-menu-trigger.directive"; +import {TypeResource} from 'core-app/modules/hal/resources/type-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; @Directive({ selector: '[opTypesCreateDropdown]' diff --git a/frontend/app/components/op-context-menu/handlers/wp-create-settings-menu.directive.ts b/frontend/app/components/op-context-menu/handlers/wp-create-settings-menu.directive.ts index e2c5a29bc1..06ed7875e1 100644 --- a/frontend/app/components/op-context-menu/handlers/wp-create-settings-menu.directive.ts +++ b/frontend/app/components/op-context-menu/handlers/wp-create-settings-menu.directive.ts @@ -31,7 +31,7 @@ import {Directive, ElementRef} from "@angular/core"; import {OpContextMenuTrigger} from "core-components/op-context-menu/handlers/op-context-menu-trigger.directive"; import {WorkPackageEditingService} from "core-components/wp-edit-form/work-package-editing-service"; import {States} from "core-components/states.service"; -import {FormResourceInterface} from "core-components/api/api-v3/hal-resources/form-resource.service"; +import {FormResource} from 'core-app/modules/hal/resources/form-resource'; @Directive({ selector: '[wpCreateSettingsMenu]' @@ -52,7 +52,7 @@ export class WorkPackageCreateSettingsMenuDirective extends OpContextMenuTrigger if (wp) { const changeset = this.wpEditing.changesetFor(wp); changeset.getForm().then( - (loadedForm:FormResourceInterface) => { + (loadedForm:FormResource) => { this.buildItems(loadedForm); this.opContextMenu.show(this, evt); } @@ -73,7 +73,7 @@ export class WorkPackageCreateSettingsMenuDirective extends OpContextMenuTrigger }; } - private buildItems(form:FormResourceInterface) { + private buildItems(form:FormResource) { this.items = []; const configureFormLink = form.configureForm; const queryCustomFields = form.customFields; diff --git a/frontend/app/components/op-context-menu/handlers/wp-status-dropdown-menu.directive.ts b/frontend/app/components/op-context-menu/handlers/wp-status-dropdown-menu.directive.ts index 4988359bb7..56569358a8 100644 --- a/frontend/app/components/op-context-menu/handlers/wp-status-dropdown-menu.directive.ts +++ b/frontend/app/components/op-context-menu/handlers/wp-status-dropdown-menu.directive.ts @@ -30,19 +30,19 @@ import {StateService} from '@uirouter/core'; import {OPContextMenuService} from "core-components/op-context-menu/op-context-menu.service"; import {Directive, ElementRef, Inject, Input} from "@angular/core"; import {$stateToken} from "core-app/angular4-transition-utils"; -import {CollectionResource} from "core-components/api/api-v3/hal-resources/collection-resource.service"; import {OpContextMenuTrigger} from "core-components/op-context-menu/handlers/op-context-menu-trigger.directive"; import {WorkPackageEditingService} from "core-components/wp-edit-form/work-package-editing-service"; import {WorkPackageTableRefreshService} from "core-components/wp-table/wp-table-refresh-request.service"; import {WorkPackageNotificationService} from "core-components/wp-edit/wp-notification.service"; -import {WorkPackageResourceInterface} from "core-components/api/api-v3/hal-resources/work-package-resource.service"; -import {HalResource} from "core-components/api/api-v3/hal-resources/hal-resource.service"; +import {WorkPackageResource} from "core-app/modules/hal/resources/work-package-resource"; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; @Directive({ selector: '[wpStatusDropdown]' }) export class WorkPackageStatusDropdownDirective extends OpContextMenuTrigger { - @Input('wpStatusDropdown-workPackage') public workPackage:WorkPackageResourceInterface; + @Input('wpStatusDropdown-workPackage') public workPackage:WorkPackageResource; constructor(readonly elementRef:ElementRef, readonly opContextMenu:OPContextMenuService, diff --git a/frontend/app/components/op-context-menu/wp-context-menu/wp-single-context-menu.ts b/frontend/app/components/op-context-menu/wp-context-menu/wp-single-context-menu.ts index 081c887b42..e8d63ba9d1 100644 --- a/frontend/app/components/op-context-menu/wp-context-menu/wp-single-context-menu.ts +++ b/frontend/app/components/op-context-menu/wp-context-menu/wp-single-context-menu.ts @@ -7,7 +7,7 @@ import { } from "core-app/angular4-transition-utils"; import {LinkHandling} from "core-components/common/link-handling/link-handling"; import {OPContextMenuService} from "core-components/op-context-menu/op-context-menu.service"; -import {WorkPackageResourceInterface} from "core-components/api/api-v3/hal-resources/work-package-resource.service"; +import {WorkPackageResource} from "core-app/modules/hal/resources/work-package-resource"; import {PERMITTED_CONTEXT_MENU_ACTIONS} from "core-components/op-context-menu/wp-context-menu/wp-static-context-menu-actions"; import {OpContextMenuTrigger} from "core-components/op-context-menu/handlers/op-context-menu-trigger.directive"; import {WorkPackageAuthorization} from "core-components/work-packages/work-package-authorization.service"; @@ -18,7 +18,7 @@ import {StateService} from "@uirouter/core"; selector: '[wpSingleContextMenu]' }) export class WorkPackageSingleContextMenuDirective extends OpContextMenuTrigger { - @Input('wpSingleContextMenu-workPackage') public workPackage:WorkPackageResourceInterface; + @Input('wpSingleContextMenu-workPackage') public workPackage:WorkPackageResource; constructor(@Inject(HookServiceToken) readonly HookService:any, @Inject(wpDestroyModalToken) readonly wpDestroyModal:any, diff --git a/frontend/app/components/routing/wp-full-view/wp-full-view.component.ts b/frontend/app/components/routing/wp-full-view/wp-full-view.component.ts index a3232cbb29..15d4b80a39 100644 --- a/frontend/app/components/routing/wp-full-view/wp-full-view.component.ts +++ b/frontend/app/components/routing/wp-full-view/wp-full-view.component.ts @@ -26,12 +26,12 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {UserResource} from '../../api/api-v3/hal-resources/user-resource.service'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {UserResource} from 'core-app/modules/hal/resources/user-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageViewController} from '../wp-view-base/wp-view-base.controller'; import {WorkPackageTableFocusService} from 'core-components/wp-fast-table/state/wp-table-focus.service'; import {StateService} from '@uirouter/core'; -import {TypeResource} from 'core-components/api/api-v3/hal-resources/type-resource.service'; +import {TypeResource} from 'core-app/modules/hal/resources/type-resource'; import {Component, Inject, Injector} from '@angular/core'; import {$stateToken} from 'core-app/angular4-transition-utils'; import {WorkPackageTableSelection} from 'core-components/wp-fast-table/state/wp-table-selection.service'; @@ -97,7 +97,7 @@ export class WorkPackagesFullViewComponent extends WorkPackageViewController { this.$state.go('work-packages.list', this.$state.params); } - private setWorkPackageScopeProperties(wp:WorkPackageResourceInterface) { + private setWorkPackageScopeProperties(wp:WorkPackageResource) { this.isWatched = wp.hasOwnProperty('unwatch'); this.displayWatchButton = wp.hasOwnProperty('unwatch') || wp.hasOwnProperty('watch'); diff --git a/frontend/app/components/routing/wp-list/wp-list.component.ts b/frontend/app/components/routing/wp-list/wp-list.component.ts index 67ff1744ad..bec4009880 100644 --- a/frontend/app/components/routing/wp-list/wp-list.component.ts +++ b/frontend/app/components/routing/wp-list/wp-list.component.ts @@ -35,7 +35,7 @@ import {TableState} from 'core-components/wp-table/table-state/table-state'; import {untilComponentDestroyed} from 'ng2-rx-componentdestroyed'; import {auditTime, distinctUntilChanged, filter, take, withLatestFrom} from 'rxjs/operators'; import {debugLog} from '../../../helpers/debug_output'; -import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; import {LoadingIndicatorService} from '../../common/loading-indicator/loading-indicator.service'; import {States} from '../../states.service'; import {WorkPackageQueryStateService} from '../../wp-fast-table/state/wp-table-base.service'; diff --git a/frontend/app/components/routing/wp-view-base/wp-view-base.controller.ts b/frontend/app/components/routing/wp-view-base/wp-view-base.controller.ts index e748b944af..2a609ce770 100644 --- a/frontend/app/components/routing/wp-view-base/wp-view-base.controller.ts +++ b/frontend/app/components/routing/wp-view-base/wp-view-base.controller.ts @@ -32,12 +32,12 @@ import {PathHelperService} from 'core-components/common/path-helper/path-helper. import {WorkPackageTableFocusService} from 'core-components/wp-fast-table/state/wp-table-focus.service'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {takeUntil} from 'rxjs/operators'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; import {States} from '../../states.service'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; import {WorkPackageEditingService} from '../../wp-edit-form/work-package-editing-service'; import {KeepTabService} from '../../wp-single-view-tabs/keep-tab/keep-tab.service'; import {WorkPackageTableRefreshService} from '../../wp-table/wp-table-refresh-request.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; export class WorkPackageViewController implements OnDestroy { @@ -54,7 +54,7 @@ export class WorkPackageViewController implements OnDestroy { public text:any = {}; // Work package resource to be loaded from the cache - public workPackage:WorkPackageResourceInterface; + public workPackage:WorkPackageResource; public projectIdentifier:string; protected focusAnchorLabel:string; @@ -77,7 +77,7 @@ export class WorkPackageViewController implements OnDestroy { .pipe( takeUntil(componentDestroyed(this)) ) - .subscribe((wp:WorkPackageResourceInterface) => { + .subscribe((wp:WorkPackageResource) => { this.workPackage = wp; this.init(); }); diff --git a/frontend/app/components/schemas/schema-cache.service.ts b/frontend/app/components/schemas/schema-cache.service.ts index 9ebe9525fa..1c9cb7739f 100644 --- a/frontend/app/components/schemas/schema-cache.service.ts +++ b/frontend/app/components/schemas/schema-cache.service.ts @@ -27,12 +27,9 @@ // ++ import {State} from "reactivestates"; import {States} from "../states.service"; -import {SchemaResource} from "../api/api-v3/hal-resources/schema-resource.service"; -import {WorkPackageResourceInterface} from "core-components/api/api-v3/hal-resources/work-package-resource.service"; import {Injectable} from '@angular/core'; -import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; -import {opWorkPackagesModule} from 'core-app/angular-modules'; -import {downgradeInjectable} from '@angular/upgrade/static'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; @Injectable() export class SchemaCacheService { @@ -46,7 +43,7 @@ export class SchemaCacheService { * @param href The schema's href. * @return A promise with the loaded schema. */ - ensureLoaded(workPackage:WorkPackageResourceInterface):PromiseLike { + ensureLoaded(workPackage:WorkPackageResource):PromiseLike { const state = this.state(workPackage); if (state.hasValue()) { @@ -59,8 +56,8 @@ export class SchemaCacheService { /** * Get the associated schema state of the work package * without initializing a new resource. - */ - state(workPackage:WorkPackageResourceInterface) { + */ + state(workPackage:WorkPackageResource) { const schema = workPackage.$links.schema; return this.states.schemas.get(schema.href!); } @@ -68,7 +65,7 @@ export class SchemaCacheService { /** * Load the associated schema for the given work package, if needed. */ - load(workPackage:WorkPackageResourceInterface, forceUpdate = false):State { + load(workPackage:WorkPackageResource, forceUpdate = false):State { const state = this.state(workPackage); if (forceUpdate) { @@ -83,5 +80,3 @@ export class SchemaCacheService { return state; } } - -opWorkPackagesModule.service('schemaCacheService', downgradeInjectable(SchemaCacheService)); diff --git a/frontend/app/components/states.service.ts b/frontend/app/components/states.service.ts index b7cf31e9f8..4bad578ce0 100644 --- a/frontend/app/components/states.service.ts +++ b/frontend/app/components/states.service.ts @@ -3,22 +3,22 @@ import {TableState} from 'core-components/wp-table/table-state/table-state'; import {combine, derive, input, multiInput, StatesGroup} from 'reactivestates'; import {mapTo} from 'rxjs/operators'; import {opServicesModule} from '../angular-modules'; -import {QueryFormResource} from './api/api-v3/hal-resources/query-form-resource.service'; -import {QueryGroupByResource} from './api/api-v3/hal-resources/query-group-by-resource.service'; -import {QueryResource} from './api/api-v3/hal-resources/query-resource.service'; -import {QuerySortByResource} from './api/api-v3/hal-resources/query-sort-by-resource.service'; -import {SchemaResource} from './api/api-v3/hal-resources/schema-resource.service'; -import {TypeResource} from './api/api-v3/hal-resources/type-resource.service'; -import {WorkPackageResourceInterface} from './api/api-v3/hal-resources/work-package-resource.service'; +import {QueryFormResource} from 'core-app/modules/hal/resources/query-form-resource'; +import {QueryGroupByResource} from 'core-app/modules/hal/resources/query-group-by-resource'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {QuerySortByResource} from 'core-app/modules/hal/resources/query-sort-by-resource'; +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {SwitchState} from './states/switch-state'; import {QueryColumn} from './wp-query/query-column'; +import {TypeResource} from 'core-app/modules/hal/resources/type-resource'; export class States extends StatesGroup { name = 'MainStore'; /* /api/v3/work_packages */ - workPackages = multiInput(); + workPackages = multiInput(); /* /api/v3/schemas */ schemas = multiInput(); diff --git a/frontend/app/components/table-pagination/pagination-service.ts b/frontend/app/components/table-pagination/pagination-service.ts index 0458f39fdd..7fa8a263ca 100644 --- a/frontend/app/components/table-pagination/pagination-service.ts +++ b/frontend/app/components/table-pagination/pagination-service.ts @@ -27,8 +27,8 @@ //++ import {Injectable} from '@angular/core'; -import {ConfigurationDmService} from "core-components/api/api-v3/hal-resource-dms/configuration-dm.service"; import {opServicesModule} from "../../angular-modules"; +import {ConfigurationDmService} from 'core-app/modules/dm-services/configuration-dm.service'; export const DEFAULT_PAGINATION_OPTIONS = { maxVisiblePageOptions: 6, @@ -44,7 +44,7 @@ export interface IPaginationOptions { @Injectable() export class PaginationService { - private paginationOptions: IPaginationOptions; + private paginationOptions:IPaginationOptions; constructor(private ConfigurationDm:ConfigurationDmService) { const gonPaginationOptions = this.getInitialPageOptions(); @@ -60,7 +60,7 @@ export class PaginationService { public getInitialPageOptions():number[] { try { return (window as any).gon.settings.pagination.per_page_options; - } catch(e) { + } catch (e) { console.log("Can't load initial page options from gon: " + e); return []; } diff --git a/frontend/app/components/user/user-link/user-link.directive.ts b/frontend/app/components/user/user-link/user-link.directive.ts index 51735fd67b..05c6aa190e 100644 --- a/frontend/app/components/user/user-link/user-link.directive.ts +++ b/frontend/app/components/user/user-link/user-link.directive.ts @@ -27,7 +27,7 @@ //++ import {openprojectModule} from '../../../angular-modules'; -import {UserResource} from '../../api/api-v3/hal-resources/user-resource.service'; +import {UserResource} from 'core-app/modules/hal/resources/user-resource'; interface UserLinkScope { user:UserResource; diff --git a/frontend/app/components/user/user-link/user-link.upgraded.component.ts b/frontend/app/components/user/user-link/user-link.upgraded.component.ts index 6fe2d1a670..571989c5e8 100644 --- a/frontend/app/components/user/user-link/user-link.upgraded.component.ts +++ b/frontend/app/components/user/user-link/user-link.upgraded.component.ts @@ -28,7 +28,7 @@ import {Component, Directive, ElementRef, Injector, Input, Output} from '@angular/core'; import {UpgradeComponent} from '@angular/upgrade/static'; -import {UserResource} from 'core-components/api/api-v3/hal-resources/user-resource.service'; +import {UserResource} from 'core-app/modules/hal/resources/user-resource'; @Directive({ selector: 'user-link' diff --git a/frontend/app/components/work-packages/work-package-authorization.service.ts b/frontend/app/components/work-packages/work-package-authorization.service.ts index 22bf409f28..1a70893721 100644 --- a/frontend/app/components/work-packages/work-package-authorization.service.ts +++ b/frontend/app/components/work-packages/work-package-authorization.service.ts @@ -28,7 +28,7 @@ import {opWorkPackagesModule} from '../../angular-modules'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {StateService} from '@uirouter/core'; var $state:StateService; @@ -38,7 +38,7 @@ export class WorkPackageAuthorization { public project:any; - constructor(public workPackage:WorkPackageResourceInterface) { + constructor(public workPackage:WorkPackageResource) { this.project = workPackage.project; } diff --git a/frontend/app/components/work-packages/work-package-cache.service.test.ts b/frontend/app/components/work-packages/work-package-cache.service.test.ts index e2dabfa02e..b15823101d 100644 --- a/frontend/app/components/work-packages/work-package-cache.service.test.ts +++ b/frontend/app/components/work-packages/work-package-cache.service.test.ts @@ -26,23 +26,21 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {SchemaCacheService} from 'core-components/schemas/schema-cache.service'; +import {TestBed} from '@angular/core/testing'; require('../../angular4-test-setup'); -import { - WorkPackageResource, - WorkPackageResourceInterface -} from '../api/api-v3/hal-resources/work-package-resource.service'; -import {WorkPackageCacheService} from "./work-package-cache.service"; -import {TestBed} from '@angular/core/testing'; -import {take, takeUntil, takeWhile} from 'rxjs/operators'; +import {SchemaCacheService} from 'core-components/schemas/schema-cache.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; import {ApiWorkPackagesService} from 'core-components/api/api-work-packages/api-work-packages.service'; -import {States} from 'core-components/states.service'; import {WorkPackageNotificationService} from 'core-components/wp-edit/wp-notification.service'; -import {$q} from '@uirouter/core'; +import {States} from 'core-components/states.service'; +import {take, takeWhile} from 'rxjs/operators'; +import {Injector} from '@angular/core'; describe('WorkPackageCacheService', () => { + let injector:Injector; let wpCacheService:WorkPackageCacheService; let schemaCacheService:SchemaCacheService; let dummyWorkPackages:WorkPackageResource[] = []; @@ -59,12 +57,15 @@ describe('WorkPackageCacheService', () => { ] }); + injector = TestBed.get(Injector); wpCacheService = TestBed.get(WorkPackageCacheService); schemaCacheService = TestBed.get(SchemaCacheService); sinon.stub(schemaCacheService, 'ensureLoaded').returns(Promise.resolve(true)); - const workPackage1 = new WorkPackageResource({ + const workPackage1 = new WorkPackageResource( + injector, + { id: '1', _links: { self: "" @@ -79,12 +80,12 @@ describe('WorkPackageCacheService', () => { .pipe( take(1) ) - .subscribe((wp:WorkPackageResourceInterface) => { + .subscribe((wp:WorkPackageResource) => { expect(wp.id).to.eq('1'); done(); }); - wpCacheService.updateWorkPackageList(dummyWorkPackages as WorkPackageResourceInterface[]); + wpCacheService.updateWorkPackageList(dummyWorkPackages as WorkPackageResource[]); }); it('should return/stream a work package every time it gets updated', (done:any) => { @@ -94,7 +95,7 @@ describe('WorkPackageCacheService', () => { .pipe( takeWhile((wp) => count < 2) ) - .subscribe((wp:WorkPackageResourceInterface) => { + .subscribe((wp:WorkPackageResource) => { expect(wp.id).to.eq('1'); count += 1; @@ -103,8 +104,8 @@ describe('WorkPackageCacheService', () => { } }); - wpCacheService.updateWorkPackageList([dummyWorkPackages[0]] as WorkPackageResourceInterface[]); - wpCacheService.updateWorkPackageList([dummyWorkPackages[0]] as WorkPackageResourceInterface[]); - wpCacheService.updateWorkPackageList([dummyWorkPackages[0]] as WorkPackageResourceInterface[]); + wpCacheService.updateWorkPackageList([dummyWorkPackages[0]] as WorkPackageResource[]); + wpCacheService.updateWorkPackageList([dummyWorkPackages[0]] as WorkPackageResource[]); + wpCacheService.updateWorkPackageList([dummyWorkPackages[0]] as WorkPackageResource[]); }); }); diff --git a/frontend/app/components/work-packages/work-package-cache.service.ts b/frontend/app/components/work-packages/work-package-cache.service.ts index 19214e5fd6..362d1ec005 100644 --- a/frontend/app/components/work-packages/work-package-cache.service.ts +++ b/frontend/app/components/work-packages/work-package-cache.service.ts @@ -28,23 +28,23 @@ import {State} from 'reactivestates'; import {opWorkPackagesModule} from '../../angular-modules'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; import {ApiWorkPackagesService} from '../api/api-work-packages/api-work-packages.service'; import {States} from '../states.service'; import {WorkPackageNotificationService} from './../wp-edit/wp-notification.service'; -import {WorkPackageCollectionResourceInterface} from '../api/api-v3/hal-resources/wp-collection-resource.service'; -import {SchemaResource} from '../api/api-v3/hal-resources/schema-resource.service'; import {StateCacheService} from '../states/state-cache.service'; import {downgradeInjectable} from '@angular/upgrade/static'; -import {Injectable} from '@angular/core'; import {SchemaCacheService} from './../schemas/schema-cache.service'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource'; +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {Injectable} from '@angular/core'; function getWorkPackageId(id:number | string):string { return (id || '__new_work_package__').toString(); } @Injectable() -export class WorkPackageCacheService extends StateCacheService { +export class WorkPackageCacheService extends StateCacheService { /*@ngInject*/ constructor(private states:States, @@ -54,15 +54,15 @@ export class WorkPackageCacheService extends StateCacheService { + async saveWorkPackage(workPackage:WorkPackageResource):Promise { if (!(workPackage.dirty || workPackage.isNew)) { return Promise.reject(null); } - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { return workPackage.save() .then(() => { this.wpNotificationsService.showSave(workPackage); @@ -104,7 +104,7 @@ export class WorkPackageCacheService extends StateCacheService { + loadWorkPackage(workPackageId:string, forceUpdate = false):State { const state = this.state(workPackageId); // Several services involved in the creation of work packages @@ -122,7 +122,7 @@ export class WorkPackageCacheService extends StateCacheService((resolve, reject) => { this.apiWorkPackages .loadWorkPackagesCollectionsFor(_.uniq(ids)) - .then((pagedResults:WorkPackageCollectionResourceInterface[]) => { + .then((pagedResults:WorkPackageCollectionResource[]) => { _.each(pagedResults, (results) => { if (results.schemas) { _.each(results.schemas.elements, (schema:SchemaResource) => { @@ -141,9 +141,9 @@ export class WorkPackageCacheService extends StateCacheService((resolve, reject) => { + return new Promise((resolve, reject) => { this.apiWorkPackages.loadWorkPackageById(id, true) - .then((workPackage:WorkPackageResourceInterface) => { + .then((workPackage:WorkPackageResource) => { this.schemaCacheService.ensureLoaded(workPackage).then(() => { this.multiState.get(id).putValue(workPackage); resolve(workPackage); diff --git a/frontend/app/components/work-packages/work-package-comment/work-package-comment.directive.ts b/frontend/app/components/work-packages/work-package-comment/work-package-comment.directive.ts index 0e3521f570..ce1a154d38 100644 --- a/frontend/app/components/work-packages/work-package-comment/work-package-comment.directive.ts +++ b/frontend/app/components/work-packages/work-package-comment/work-package-comment.directive.ts @@ -26,16 +26,16 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageCommentField} from './wp-comment-field.module'; -import {ErrorResource} from '../../api/api-v3/hal-resources/error-resource.service'; +import {ErrorResource} from 'core-app/modules/hal/resources/error-resource'; import {WorkPackageNotificationService} from '../../wp-edit/wp-notification.service'; import {WorkPackageCacheService} from '../work-package-cache.service'; import {LoadingIndicatorService} from '../../common/loading-indicator/loading-indicator.service'; import {scopedObservable} from 'core-app/helpers/angular-rx-utils'; export class CommentFieldDirectiveController { - public workPackage:WorkPackageResourceInterface; + public workPackage:WorkPackageResource; public field:WorkPackageCommentField; protected text:Object; diff --git a/frontend/app/components/work-packages/work-package-comment/work-package-comment.directive.upgraded.ts b/frontend/app/components/work-packages/work-package-comment/work-package-comment.directive.upgraded.ts index e4c9831dd9..47146d737f 100644 --- a/frontend/app/components/work-packages/work-package-comment/work-package-comment.directive.upgraded.ts +++ b/frontend/app/components/work-packages/work-package-comment/work-package-comment.directive.upgraded.ts @@ -29,14 +29,14 @@ import {UpgradeComponent} from '@angular/upgrade/static'; import {Directive, ElementRef, Injector, Input} from '@angular/core'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; -import {CollectionResource} from 'core-components/api/api-v3/hal-resources/collection-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; @Directive({ selector: 'work-package-comment-upgraded' }) export class WorkPackageCommentDirectiveUpgraded extends UpgradeComponent { - @Input('workPackage') public workPackage:WorkPackageResourceInterface; + @Input('workPackage') public workPackage:WorkPackageResource; @Input('activities') public activities:CollectionResource; constructor(elementRef:ElementRef, injector:Injector) { diff --git a/frontend/app/components/work-packages/work-package-comment/wp-comment-field.module.ts b/frontend/app/components/work-packages/work-package-comment/wp-comment-field.module.ts index 525bc58885..054fa9f76d 100644 --- a/frontend/app/components/work-packages/work-package-comment/wp-comment-field.module.ts +++ b/frontend/app/components/work-packages/work-package-comment/wp-comment-field.module.ts @@ -26,7 +26,7 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WikiTextareaEditField} from '../../wp-edit/field-types/wp-edit-wiki-textarea-field.module'; import {WorkPackageChangeset} from '../../wp-edit-form/work-package-changeset'; import {ConfigurationService} from 'core-components/common/config/configuration.service'; @@ -38,7 +38,7 @@ export class WorkPackageCommentField extends WikiTextareaEditField { public ConfigurationService:ConfigurationService = this.$injector.get(ConfigurationService); - constructor(public workPackage:WorkPackageResourceInterface, protected I18n:op.I18n) { + constructor(public workPackage:WorkPackageResource, protected I18n:op.I18n) { super( new WorkPackageChangeset(WorkPackageCommentField.$injector, workPackage), 'comment', diff --git a/frontend/app/components/work-packages/wp-attachments-formattable-field/models/drop-model.ts b/frontend/app/components/work-packages/wp-attachments-formattable-field/models/drop-model.ts index 73f4fac305..f5215f689c 100644 --- a/frontend/app/components/work-packages/wp-attachments-formattable-field/models/drop-model.ts +++ b/frontend/app/components/work-packages/wp-attachments-formattable-field/models/drop-model.ts @@ -1,5 +1,5 @@ import IAugmentedJQuery = angular.IAugmentedJQuery; -import {WorkPackageResourceInterface} from '../../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; export class DropModel { public files:File[]; @@ -16,7 +16,7 @@ export class DropModel { constructor(protected $location:ng.ILocationService, protected dataTransfer:any, - protected workPackage:WorkPackageResourceInterface) { + protected workPackage:WorkPackageResource) { this.files = dataTransfer.files; this.filesCount = this.files.length; this.isUpload = this._isUpload(dataTransfer); diff --git a/frontend/app/components/work-packages/wp-attachments-formattable-field/models/work-package-field-model.ts b/frontend/app/components/work-packages/wp-attachments-formattable-field/models/work-package-field-model.ts index c79ed3b335..b4db4dd58c 100644 --- a/frontend/app/components/work-packages/wp-attachments-formattable-field/models/work-package-field-model.ts +++ b/frontend/app/components/work-packages/wp-attachments-formattable-field/models/work-package-field-model.ts @@ -1,20 +1,17 @@ import {InsertMode} from '../wp-attachments-formattable.enums'; import {IApplyAttachmentMarkup} from '../wp-attachments-formattable.interfaces'; -import {WorkPackageResourceInterface} from '../../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {MarkupModel} from './markup-model'; import {WorkPackageCacheService} from '../../work-package-cache.service'; -import {$injectFields} from '../../../angular/angular-injector-bridge.functions'; import {WorkPackageChangeset} from '../../../wp-edit-form/work-package-changeset'; -import {Injector} from '@angular/core'; export class WorkPackageFieldModel implements IApplyAttachmentMarkup { public contentToInsert:string; - constructor(protected workPackage:WorkPackageResourceInterface, + constructor(protected workPackage:WorkPackageResource, protected attribute:string, protected markupModel:MarkupModel) { - const formattable = workPackage[attribute]; this.contentToInsert = _.get(formattable, 'raw') as string || ''; } diff --git a/frontend/app/components/work-packages/wp-attachments-formattable-field/wp-attachments-formattable.directive.ts b/frontend/app/components/work-packages/wp-attachments-formattable-field/wp-attachments-formattable.directive.ts index 6b9009d185..18fb5f2bd1 100644 --- a/frontend/app/components/work-packages/wp-attachments-formattable-field/wp-attachments-formattable.directive.ts +++ b/frontend/app/components/work-packages/wp-attachments-formattable-field/wp-attachments-formattable.directive.ts @@ -1,5 +1,5 @@ import {InsertMode, ViewMode} from './wp-attachments-formattable.enums'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {KeepTabService} from '../../wp-single-view-tabs/keep-tab/keep-tab.service'; import {openprojectModule} from '../../../angular-modules'; import {WorkPackageCacheService} from '../work-package-cache.service'; @@ -47,7 +47,7 @@ export class WpAttachmentsFormattableController { const [, editor] = this.getEditor(); const originalEvent = (evt.originalEvent as DragEvent); - const workPackage:WorkPackageResourceInterface = this.$scope.workPackage; + const workPackage:WorkPackageResource = this.$scope.workPackage; const dropData:DropModel = new DropModel(this.$location, originalEvent.dataTransfer, workPackage); @@ -109,7 +109,7 @@ export class WpAttachmentsFormattableController { } protected uploadAndInsert(files:UploadFile[], model:EditorModel | WorkPackageFieldModel) { - const wp = this.$scope.workPackage as WorkPackageResourceInterface; + const wp = this.$scope.workPackage as WorkPackageResource; if (wp.isNew) { return this.insertDelayedAttachments(files, model, wp); } @@ -160,7 +160,7 @@ export class WpAttachmentsFormattableController { } } - protected insertDelayedAttachments(files:UploadFile[], description:any, workPackage:WorkPackageResourceInterface):void { + protected insertDelayedAttachments(files:UploadFile[], description:any, workPackage:WorkPackageResource):void { for (var i = 0; i < files.length; i++) { var currentFile = new SingleAttachmentModel(files[i]); var insertMode = currentFile.isAnImage ? InsertMode.INLINE : InsertMode.ATTACHMENT; diff --git a/frontend/app/components/work-packages/wp-breadcrumb/wp-breadcrumb.component.ts b/frontend/app/components/work-packages/wp-breadcrumb/wp-breadcrumb.component.ts index 6931a11978..4878764963 100644 --- a/frontend/app/components/work-packages/wp-breadcrumb/wp-breadcrumb.component.ts +++ b/frontend/app/components/work-packages/wp-breadcrumb/wp-breadcrumb.component.ts @@ -29,14 +29,14 @@ import {wpControllersModule} from '../../../angular-modules'; import {Component, Input} from '@angular/core'; import {downgradeComponent} from '@angular/upgrade/static'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; @Component({ template: require('!!raw-loader!./wp-breadcrumb.html'), selector: 'wp-breadcrumb', }) export class WorkPackageBreadcrumbComponent { - @Input('workPackage') workPackage:WorkPackageResourceInterface; + @Input('workPackage') workPackage:WorkPackageResource; } wpControllersModule.directive( diff --git a/frontend/app/components/work-packages/wp-editor-field/wp-editor-field.component.ts b/frontend/app/components/work-packages/wp-editor-field/wp-editor-field.component.ts index f5ca632144..c63330b609 100644 --- a/frontend/app/components/work-packages/wp-editor-field/wp-editor-field.component.ts +++ b/frontend/app/components/work-packages/wp-editor-field/wp-editor-field.component.ts @@ -28,12 +28,12 @@ import {opWorkPackagesModule} from './../../../angular-modules'; import {WorkPackageChangeset} from './../../wp-edit-form/work-package-changeset'; -import {WorkPackageResourceInterface} from './../../api/api-v3/hal-resources/work-package-resource.service'; import {WorkPackageEditFieldGroupComponent} from 'core-components/wp-edit/wp-edit-field/wp-edit-field-group.directive'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; export class WorkPackageEditorFieldController { public wpEditFieldGroup:WorkPackageEditFieldGroupComponent; - public workPackage:WorkPackageResourceInterface; + public workPackage:WorkPackageResource; public attribute:string; public wrapperClasses:string; diff --git a/frontend/app/components/work-packages/wp-single-view/wp-single-view.component.ts b/frontend/app/components/work-packages/wp-single-view/wp-single-view.component.ts index 041229d996..84a05ba358 100644 --- a/frontend/app/components/work-packages/wp-single-view/wp-single-view.component.ts +++ b/frontend/app/components/work-packages/wp-single-view/wp-single-view.component.ts @@ -33,9 +33,9 @@ import {WorkPackageEditFieldGroupComponent} from 'core-components/wp-edit/wp-edi import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {takeUntil} from 'rxjs/operators'; import {debugLog} from '../../../helpers/debug_output'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; import {CurrentProjectService} from '../../projects/current-project.service'; import {States} from '../../states.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {DisplayField} from '../../wp-display/wp-display-field/wp-display-field.module'; import {WorkPackageDisplayFieldService} from '../../wp-display/wp-display-field/wp-display-field.service'; import {WorkPackageEditingService} from '../../wp-edit-form/work-package-editing-service'; @@ -60,7 +60,7 @@ interface GroupDescriptor { selector: 'wp-single-view', }) export class WorkPackageSingleViewComponent implements OnInit, OnDestroy { - @Input('workPackage') public workPackage:WorkPackageResourceInterface; + @Input('workPackage') public workPackage:WorkPackageResource; // Grouped fields returned from API public groupedFields:GroupDescriptor[] = []; @@ -117,7 +117,7 @@ export class WorkPackageSingleViewComponent implements OnInit, OnDestroy { .pipe( takeUntil(componentDestroyed(this)) ) - .subscribe((resource:WorkPackageResourceInterface) => { + .subscribe((resource:WorkPackageResource) => { // Prepare the fields that are required always const isNew = this.workPackage.isNew; @@ -201,7 +201,7 @@ export class WorkPackageSingleViewComponent implements OnInit, OnDestroy { * Maps the grouped fields into their display fields. * May return multiple fields (for the date virtual field). */ - private getFields(resource:WorkPackageResourceInterface, fieldNames:string[]):FieldDescriptor[] { + private getFields(resource:WorkPackageResource, fieldNames:string[]):FieldDescriptor[] { const descriptors:FieldDescriptor[] = []; fieldNames.forEach((fieldName:string) => { @@ -233,7 +233,7 @@ export class WorkPackageSingleViewComponent implements OnInit, OnDestroy { * 'date' field vs. all other types which should display a * combined 'start' and 'due' date field. */ - private getDateField(resource:WorkPackageResourceInterface):FieldDescriptor { + private getDateField(resource:WorkPackageResource):FieldDescriptor { let object:any = { name: 'date', label: this.I18n.t('js.work_packages.properties.date'), @@ -250,7 +250,7 @@ export class WorkPackageSingleViewComponent implements OnInit, OnDestroy { return object; } - private displayField(resource:WorkPackageResourceInterface, name:string):DisplayField { + private displayField(resource:WorkPackageResource, name:string):DisplayField { return this.wpDisplayField.getField( resource, name, diff --git a/frontend/app/components/work-packages/wp-subject/wp-subject.component.ts b/frontend/app/components/work-packages/wp-subject/wp-subject.component.ts index 9c474b9eca..036fb1f394 100644 --- a/frontend/app/components/work-packages/wp-subject/wp-subject.component.ts +++ b/frontend/app/components/work-packages/wp-subject/wp-subject.component.ts @@ -27,12 +27,10 @@ // ++ import {Component, Input, OnDestroy, OnInit} from '@angular/core'; -import {downgradeComponent} from '@angular/upgrade/static'; import {UIRouterGlobals} from '@uirouter/core'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {takeUntil} from 'rxjs/operators'; -import {opWorkPackagesModule} from '../../../angular-modules'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageCacheService} from '../work-package-cache.service'; @Component({ @@ -40,7 +38,7 @@ import {WorkPackageCacheService} from '../work-package-cache.service'; selector: 'wp-subject', }) export class WorkPackageSubjectComponent implements OnInit, OnDestroy { - @Input('workPackage') workPackage:WorkPackageResourceInterface; + @Input('workPackage') workPackage:WorkPackageResource; constructor(protected uiRouterGlobals:UIRouterGlobals, protected wpCacheService:WorkPackageCacheService) { @@ -57,15 +55,9 @@ export class WorkPackageSubjectComponent implements OnInit, OnDestroy { .pipe( takeUntil(componentDestroyed(this)) ) - .subscribe((wp:WorkPackageResourceInterface) => { + .subscribe((wp:WorkPackageResource) => { this.workPackage = wp; }); } } } - -opWorkPackagesModule.directive( - 'wpSubject', - downgradeComponent({component: WorkPackageSubjectComponent}) -); - diff --git a/frontend/app/components/work-packages/wp-type-status/wp-type-status.component.ts b/frontend/app/components/work-packages/wp-type-status/wp-type-status.component.ts index e434176c8a..5456590ade 100644 --- a/frontend/app/components/work-packages/wp-type-status/wp-type-status.component.ts +++ b/frontend/app/components/work-packages/wp-type-status/wp-type-status.component.ts @@ -26,7 +26,7 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {Component, Input} from '@angular/core'; @Component({ @@ -34,5 +34,5 @@ import {Component, Input} from '@angular/core'; selector: 'wp-type-status', }) export class WorkPackageTypeStatusComponent { - @Input('workPackage') workPackage:WorkPackageResourceInterface; + @Input('workPackage') workPackage:WorkPackageResource; } diff --git a/frontend/app/components/work-packages/wp-watcher-button/wp-watcher-button.component.ts b/frontend/app/components/work-packages/wp-watcher-button/wp-watcher-button.component.ts index c197a80563..ca7ffc5e5c 100644 --- a/frontend/app/components/work-packages/wp-watcher-button/wp-watcher-button.component.ts +++ b/frontend/app/components/work-packages/wp-watcher-button/wp-watcher-button.component.ts @@ -26,21 +26,19 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {WorkPackageCacheService} from '../work-package-cache.service'; import {Component, Inject, Input, OnDestroy, OnInit} from '@angular/core'; -import {downgradeComponent} from '@angular/upgrade/static'; import {I18nToken} from 'core-app/angular4-transition-utils'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {takeUntil} from 'rxjs/operators'; -import {wpDirectivesModule} from '../../../angular-modules'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; -import {WorkPackageCacheService} from '../work-package-cache.service'; @Component({ template: require('!!raw-loader!./wp-watcher-button.html'), selector: 'wp-watcher-button', }) -export class WorkPackageWatcherButtonComponent implements OnInit, OnDestroy { - @Input('workPackage') public workPackage:WorkPackageResourceInterface; +export class WorkPackageWatcherButtonComponent implements OnInit, OnDestroy { + @Input('workPackage') public workPackage:WorkPackageResource; @Input('showText') public showText:boolean = false; @Input('disabled') public disabled:boolean = false; @@ -60,7 +58,7 @@ export class WorkPackageWatcherButtonComponent implements OnInit, OnDestroy { .pipe( takeUntil(componentDestroyed(this)) ) - .subscribe((wp:WorkPackageResourceInterface) => { + .subscribe((wp:WorkPackageResource) => { this.workPackage = wp; this.setWatchStatus(); }); @@ -108,7 +106,3 @@ export class WorkPackageWatcherButtonComponent implements OnInit, OnDestroy { } } } - -wpDirectivesModule.directive('wpWatcherButton', - downgradeComponent({component: WorkPackageWatcherButtonComponent}) -); diff --git a/frontend/app/components/wp-activity/activity-entry.directive.upgraded.ts b/frontend/app/components/wp-activity/activity-entry.directive.upgraded.ts index 6f88a1c91e..51da712592 100644 --- a/frontend/app/components/wp-activity/activity-entry.directive.upgraded.ts +++ b/frontend/app/components/wp-activity/activity-entry.directive.upgraded.ts @@ -31,15 +31,15 @@ import { SimpleChanges } from '@angular/core'; import {UpgradeComponent} from '@angular/upgrade/static'; -import {UserResource} from 'core-components/api/api-v3/hal-resources/user-resource.service'; -import {HalResource} from '../api/api-v3/hal-resources/hal-resource.service'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {UserResource} from 'core-app/modules/hal/resources/user-resource'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; @Directive({ selector: 'activity-entry-upgraded' }) export class ActivityEntryDirectiveUpgraded extends UpgradeComponent { - @Input('workPackage') public workPackage:WorkPackageResourceInterface; + @Input('workPackage') public workPackage:WorkPackageResource; @Input('activity') public activity:HalResource; @Input('activityNo') public activityNo:number; @Input('isInitial') public isInitial:boolean; diff --git a/frontend/app/components/wp-activity/activity-service.ts b/frontend/app/components/wp-activity/activity-service.ts index 7f491fb450..10b6ccde71 100644 --- a/frontend/app/components/wp-activity/activity-service.ts +++ b/frontend/app/components/wp-activity/activity-service.ts @@ -28,9 +28,9 @@ /* globals URI */ import {opServicesModule} from './../../angular-modules'; -import {WorkPackageResourceInterface} from 'app/components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageNotificationService} from './../wp-edit/wp-notification.service'; -import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; import {input} from 'reactivestates'; export class ActivityService { @@ -47,7 +47,7 @@ export class ActivityService { private $q:ng.IQService) { } - public createComment(workPackage:WorkPackageResourceInterface, comment:string) { + public createComment(workPackage:WorkPackageResource, comment:string) { return workPackage.addComment( { comment: comment}, { 'Content-Type': 'application/json; charset=UTF-8' } @@ -76,7 +76,7 @@ export class ActivityService { }).catch((error:any) => this.errorAndReject(error)); } - private errorAndReject(error:HalResource, workPackage?:WorkPackageResourceInterface) { + private errorAndReject(error:HalResource, workPackage?:WorkPackageResource) { this.wpNotificationsService.handleErrorResponse(error, workPackage); // returning a reject will enable to correctly work with subsequent then/catch handlers. diff --git a/frontend/app/components/wp-activity/revision/revision-activity-directive.test.ts b/frontend/app/components/wp-activity/revision/revision-activity-directive.test.ts deleted file mode 100644 index a88203445f..0000000000 --- a/frontend/app/components/wp-activity/revision/revision-activity-directive.test.ts +++ /dev/null @@ -1,131 +0,0 @@ -//-- copyright -// OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See doc/COPYRIGHT.rdoc for more details. -//++ - - -import {UserResource} from '../../api/api-v3/hal-resources/user-resource.service'; -describe('revisionActivity Directive', function () { - var compile:any, element:any, rootScope:any, scope:any, I18n:any, $q:any; - - beforeEach(angular.mock.module('openproject.workPackages.activities')); - beforeEach(function () { - angular.mock.module( - 'openproject.api', - 'openproject.workPackages', - 'openproject.models', - 'openproject.services', - 'openproject.config', - 'openproject.templates' - ); - }); - - beforeEach(inject(function ($rootScope:any, $compile:any, _I18n_:any, _$q_:any) { - var html:string; - html = ''; - - rootScope = $rootScope; - $q = _$q_; - scope = $rootScope.$new(); - - I18n = _I18n_; - sinon.stub(I18n, 't').returns(''); - - - compile = function () { - element = angular.element(html); - $compile(element)(scope); - scope.$digest(); - }; - })); - - afterEach(function () { - I18n.t.restore(); - }); - - describe('with a valid revision', function () { - beforeEach(function () { - scope.workPackage = { - revisions: true - }; - scope.activity = { - showRevision: { - $link: { href: '/project/foo/repository/revision/1234' }, - }, - - id: 1, - identifier: '11f4b07dff4f4ce9548a52b7d002daca7cd63ec6', - formattedIdentifier: '11f4b07', - authorName: 'some developer', - message: { - format: 'plain', - raw: 'This revision provides new features\n\nAn elaborate description', - html: '

This revision provides new features

An elaborate description

' - }, - createdAt: '2015-07-21T13:36:59Z' - }; - compile(); - }); - - it('should not render an image', function () { - expect(element.find('.avatar')).to.have.length(0); - }); - - it('should have the author name, but no link', function () { - expect(element.find('.user').html()).to.equal('some developer'); - expect(element.find('.user > a')).to.have.length(0); - }); - - describe('with linked author', function () { - beforeEach(function () { - scope.activity.author = { - $load: function () { - return $q.when(new UserResource({ - id: 1, - name: 'Some Dude', - avatar: 'avatar.png', - status: 'active' - }, true)); - } - }; - compile(); - }); - - it('should render a user profile', function () { - expect(element.find('.avatar').attr('alt')).to.equal('Avatar'); - expect(element.find('span.user > a').text()).to.equal('Some Dude'); - }); - }); - - describe('message', function () { - it('should render commit message', function () { - var message = element.find('.user-comment > span.message').html(); - - expect(message).to.eq(scope.activity.message.html); - }); - }); - }); -}); diff --git a/frontend/app/components/wp-activity/user/user-activity-directive.ts b/frontend/app/components/wp-activity/user/user-activity-directive.ts index 567ad8dcf7..d69ceb4613 100644 --- a/frontend/app/components/wp-activity/user/user-activity-directive.ts +++ b/frontend/app/components/wp-activity/user/user-activity-directive.ts @@ -26,19 +26,18 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {UserResource} from '../../api/api-v3/hal-resources/user-resource.service'; +import {UserResource} from 'core-app/modules/hal/resources/user-resource'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; import {TextileService} from './../../common/textile/textile-service'; import {ActivityService} from './../activity-service'; import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; import {ConfigurationService} from 'core-components/common/config/configuration.service'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; -import {ActivityEntryInfo} from 'core-components/wp-single-view-tabs/activity-panel/activity-entry-info'; -import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; import {WorkPackageCommentField} from 'core-components/work-packages/work-package-comment/wp-comment-field.module'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; export class UserActivityController { - public workPackage:WorkPackageResourceInterface; + public workPackage:WorkPackageResource; public activity:HalResource; public activityNo:string; public activityLabel:string; diff --git a/frontend/app/components/wp-attachments/wp-attachment-list/wp-attachment-list-item.component.ts b/frontend/app/components/wp-attachments/wp-attachment-list/wp-attachment-list-item.component.ts index 22dcc1f20f..b09419510d 100644 --- a/frontend/app/components/wp-attachments/wp-attachment-list/wp-attachment-list-item.component.ts +++ b/frontend/app/components/wp-attachments/wp-attachment-list/wp-attachment-list-item.component.ts @@ -26,18 +26,18 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageNotificationService} from '../../wp-edit/wp-notification.service'; import {Component, Inject, Input} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; -import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; @Component({ template: require('!!raw-loader!./wp-attachment-list-item.html'), selector: 'wp-attachment-list-item', }) export class WorkPackageAttachmentListItemComponent { - @Input('workPackage') public workPackage:WorkPackageResourceInterface; + @Input('workPackage') public workPackage:WorkPackageResource; @Input('attachment') public attachment:HalResource; public text = { diff --git a/frontend/app/components/wp-attachments/wp-attachment-list/wp-attachment-list.component.ts b/frontend/app/components/wp-attachments/wp-attachment-list/wp-attachment-list.component.ts index 1ecd1cf43d..65ffc09ab4 100644 --- a/frontend/app/components/wp-attachments/wp-attachment-list/wp-attachment-list.component.ts +++ b/frontend/app/components/wp-attachments/wp-attachment-list/wp-attachment-list.component.ts @@ -26,16 +26,16 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {Component, Input, OnInit} from '@angular/core'; -import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; @Component({ template: require('!!raw-loader!./wp-attachment-list.html'), selector: 'wp-attachment-list', }) export class WorkPackageAttachmentListComponent implements OnInit { - @Input('workPackage') public workPackage:WorkPackageResourceInterface; + @Input('workPackage') public workPackage:WorkPackageResource; ngOnInit() { if (this.workPackage.attachments) { diff --git a/frontend/app/components/wp-attachments/wp-attachments-upload/wp-attachments-upload-ng1-wrapper.ts b/frontend/app/components/wp-attachments/wp-attachments-upload/wp-attachments-upload-ng1-wrapper.ts index 93d539c373..205d83f14f 100644 --- a/frontend/app/components/wp-attachments/wp-attachments-upload/wp-attachments-upload-ng1-wrapper.ts +++ b/frontend/app/components/wp-attachments/wp-attachments-upload/wp-attachments-upload-ng1-wrapper.ts @@ -32,11 +32,11 @@ import { OnInit, SimpleChanges } from '@angular/core'; import {UpgradeComponent} from '@angular/upgrade/static'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; @Directive({selector: 'ng1-wp-attachments-upload-wrapper'}) export class Ng1WorkPackageAttachmentsUploadWrapper extends UpgradeComponent implements OnInit, OnChanges, DoCheck, OnDestroy { - @Input('workPackage') workPackage:WorkPackageResourceInterface; + @Input('workPackage') workPackage:WorkPackageResource; constructor(@Inject(ElementRef) elementRef:ElementRef, @Inject(Injector) injector:Injector) { // We must pass the name of the directive as used by AngularJS to the super diff --git a/frontend/app/components/wp-attachments/wp-attachments-upload/wp-attachments-upload.directive.ts b/frontend/app/components/wp-attachments/wp-attachments-upload/wp-attachments-upload.directive.ts index 0a708bd333..09561afb7d 100644 --- a/frontend/app/components/wp-attachments/wp-attachments-upload/wp-attachments-upload.directive.ts +++ b/frontend/app/components/wp-attachments/wp-attachments-upload/wp-attachments-upload.directive.ts @@ -27,12 +27,12 @@ //++ import {wpDirectivesModule} from '../../../angular-modules'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {UploadFile} from '../../api/op-file-upload/op-file-upload.service'; import IDirective = angular.IDirective; export class WorkPackageUploadDirectiveController { - public workPackage: WorkPackageResourceInterface; + public workPackage: WorkPackageResource; public text: any; public maxFileSize: number; diff --git a/frontend/app/components/wp-buttons/wp-status-button/wp-status-button.component.ts b/frontend/app/components/wp-buttons/wp-status-button/wp-status-button.component.ts index 6ec1212370..4ed44e236d 100644 --- a/frontend/app/components/wp-buttons/wp-status-button/wp-status-button.component.ts +++ b/frontend/app/components/wp-buttons/wp-status-button/wp-status-button.component.ts @@ -26,7 +26,7 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageEditingService} from 'core-components/wp-edit-form/work-package-editing-service'; import {Component, Inject, Input} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; @@ -36,7 +36,7 @@ import {I18nToken} from 'core-app/angular4-transition-utils'; selector: 'wp-status-button', }) export class WorkPackageStatusButtonComponent { - @Input('workPackage') public workPackage:WorkPackageResourceInterface; + @Input('workPackage') public workPackage:WorkPackageResource; @Input('allowed') public allowed:boolean; public text = { diff --git a/frontend/app/components/wp-buttons/wp-timeline-toggle-button/wp-timeline-toggle-button.component.ts b/frontend/app/components/wp-buttons/wp-timeline-toggle-button/wp-timeline-toggle-button.component.ts index b4527e9a7a..dff9403084 100644 --- a/frontend/app/components/wp-buttons/wp-timeline-toggle-button/wp-timeline-toggle-button.component.ts +++ b/frontend/app/components/wp-buttons/wp-timeline-toggle-button/wp-timeline-toggle-button.component.ts @@ -27,12 +27,12 @@ // ++ import {wpButtonsModule} from '../../../angular-modules'; -import {TimelineZoomLevel} from '../../api/api-v3/hal-resources/query-resource.service'; import {WorkPackageTableTimelineService} from '../../wp-fast-table/state/wp-table-timeline.service'; import {AbstractWorkPackageButtonComponent, ButtonControllerText} from '../wp-buttons.module'; import {Component, Inject} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; import {downgradeComponent} from '@angular/upgrade/static'; +import {TimelineZoomLevel} from 'core-app/modules/hal/resources/query-resource'; interface TimelineButtonText extends ButtonControllerText { zoomOut:string; diff --git a/frontend/app/components/wp-copy/wp-copy.controller.ts b/frontend/app/components/wp-copy/wp-copy.controller.ts index b83cb6eef2..2448b69bc4 100644 --- a/frontend/app/components/wp-copy/wp-copy.controller.ts +++ b/frontend/app/components/wp-copy/wp-copy.controller.ts @@ -27,9 +27,9 @@ // ++ import {take} from 'rxjs/operators'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; -import {WorkPackageChangeset} from '../wp-edit-form/work-package-changeset'; -import {WorkPackageCreateController} from '../wp-new/wp-create.controller'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {WorkPackageChangeset} from 'core-components/wp-edit-form/work-package-changeset'; +import {WorkPackageCreateController} from 'core-components/wp-new/wp-create.controller'; export class WorkPackageCopyController extends WorkPackageCreateController { protected async newWorkPackageFromParams(stateParams:any) { @@ -40,12 +40,12 @@ export class WorkPackageCopyController extends WorkPackageCreateController { take(1) ) .subscribe( - async (wp:WorkPackageResourceInterface) => this.createCopyFrom(wp).then(resolve), + async (wp:WorkPackageResource) => this.createCopyFrom(wp).then(resolve), reject); }); } - private async createCopyFrom(wp:WorkPackageResourceInterface) { + private async createCopyFrom(wp:WorkPackageResource) { const changeset = this.wpEditing.changesetFor(wp); return changeset.getForm().then((form:any) => { return this.wpCreate.copyWorkPackage(form, wp.project.identifier); diff --git a/frontend/app/components/wp-custom-actions/wp-custom-actions.component.ts b/frontend/app/components/wp-custom-actions/wp-custom-actions.component.ts index 77f8defd8c..c1d902ae80 100644 --- a/frontend/app/components/wp-custom-actions/wp-custom-actions.component.ts +++ b/frontend/app/components/wp-custom-actions/wp-custom-actions.component.ts @@ -30,7 +30,7 @@ import {opUiComponentsModule} from '../../angular-modules'; import {Component} from '@angular/core'; import {OnInit, Input} from '@angular/core'; import {downgradeComponent} from '@angular/upgrade/static'; -import {WorkPackageResource} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; @Component({ selector: 'wp-custom-actions', diff --git a/frontend/app/components/wp-custom-actions/wp-custom-actions/wp-custom-action.component.ts b/frontend/app/components/wp-custom-actions/wp-custom-actions/wp-custom-action.component.ts index af8312290c..5f3c640717 100644 --- a/frontend/app/components/wp-custom-actions/wp-custom-actions/wp-custom-action.component.ts +++ b/frontend/app/components/wp-custom-actions/wp-custom-actions/wp-custom-action.component.ts @@ -29,13 +29,13 @@ import {opUiComponentsModule} from '../../../angular-modules'; import {Component, HostListener, Inject, Input} from '@angular/core'; -import {CustomActionResourceInterface} from 'core-components/api/api-v3/hal-resources/custom-action-resource.service'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; -import {HalRequestService} from 'core-components/api/api-v3/hal-request/hal-request.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; import {WorkPackageNotificationService} from 'core-components/wp-edit/wp-notification.service'; import {downgradeComponent} from '@angular/upgrade/static'; import {halRequestToken} from 'core-app/angular4-transition-utils'; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; +import {CustomActionResource} from 'core-app/modules/hal/resources/custom-action-resource'; @Component({ selector: 'wp-custom-action', @@ -43,17 +43,18 @@ import {halRequestToken} from 'core-app/angular4-transition-utils'; }) export class WpCustomActionComponent { - @Input() workPackage:WorkPackageResourceInterface; - @Input() action:CustomActionResourceInterface; + @Input() workPackage:WorkPackageResource; + @Input() action:CustomActionResource; constructor(@Inject(halRequestToken) private halRequest:HalRequestService, private wpCacheService:WorkPackageCacheService, private wpNotificationsService:WorkPackageNotificationService) { } private fetchAction() { - this.halRequest.get(this.action.href!) + this.halRequest.get(this.action.href!) + .toPromise() .then((action) => { - this.action = action; + this.action = action; }); } @@ -67,8 +68,9 @@ export class WpCustomActionComponent { } }; - this.halRequest.post(this.action.href + '/execute', payload) - .then((savedWp:WorkPackageResourceInterface) => { + this.halRequest.post(this.action.href + '/execute', payload) + .toPromise() + .then((savedWp:WorkPackageResource) => { this.wpNotificationsService.showSave(savedWp, false); this.workPackage = savedWp; this.wpCacheService.updateWorkPackage(savedWp); diff --git a/frontend/app/components/wp-details/wp-details-toolbar.component.ts b/frontend/app/components/wp-details/wp-details-toolbar.component.ts index f10421e5e5..c8d23302e8 100644 --- a/frontend/app/components/wp-details/wp-details-toolbar.component.ts +++ b/frontend/app/components/wp-details/wp-details-toolbar.component.ts @@ -29,7 +29,7 @@ import {openprojectModule} from '../../angular-modules'; import {WorkPackageEditingService} from '../wp-edit-form/work-package-editing-service'; import {I18nToken} from 'core-app/angular4-transition-utils'; import {Component, Inject, Input} from '@angular/core'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {downgradeComponent} from '@angular/upgrade/static'; @Component({ @@ -37,7 +37,7 @@ import {downgradeComponent} from '@angular/upgrade/static'; selector: 'wp-details-toolbar', }) export class WorkPackageSplitViewToolbarComponent { - @Input('workPackage') workPackage:WorkPackageResourceInterface; + @Input('workPackage') workPackage:WorkPackageResource; public text = { button_more: this.I18n.t('js.button_more') diff --git a/frontend/app/components/wp-display/field-types/wp-display-duration-field.module.ts b/frontend/app/components/wp-display/field-types/wp-display-duration-field.module.ts index 86debeccfa..114fb7129f 100644 --- a/frontend/app/components/wp-display/field-types/wp-display-duration-field.module.ts +++ b/frontend/app/components/wp-display/field-types/wp-display-duration-field.module.ts @@ -27,9 +27,8 @@ // ++ import {DisplayField} from "../wp-display-field/wp-display-field.module"; -import {WorkPackageResource} from "../../api/api-v3/hal-resources/work-package-resource.service"; -import {HalResource} from "core-components/api/api-v3/hal-resources/hal-resource.service"; import {TimezoneServiceToken} from 'core-app/angular4-transition-utils'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export class DurationDisplayField extends DisplayField { diff --git a/frontend/app/components/wp-display/field-types/wp-display-float-field.module.ts b/frontend/app/components/wp-display/field-types/wp-display-float-field.module.ts index 52e0a3f0bd..72a9992026 100644 --- a/frontend/app/components/wp-display/field-types/wp-display-float-field.module.ts +++ b/frontend/app/components/wp-display/field-types/wp-display-float-field.module.ts @@ -27,7 +27,7 @@ // ++ import {DisplayField} from '../wp-display-field/wp-display-field.module'; -import {HalResource} from '../../api/api-v3/hal-resources/hal-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; import {$injectFields} from '../../angular/angular-injector-bridge.functions'; import * as angular from 'angular'; diff --git a/frontend/app/components/wp-display/field-types/wp-display-formattable-field.module.ts b/frontend/app/components/wp-display/field-types/wp-display-formattable-field.module.ts index 77bd07900f..dd762675bf 100644 --- a/frontend/app/components/wp-display/field-types/wp-display-formattable-field.module.ts +++ b/frontend/app/components/wp-display/field-types/wp-display-formattable-field.module.ts @@ -28,7 +28,7 @@ import {DisplayField} from "../wp-display-field/wp-display-field.module"; import ExpressionService from "../../common/xss/expression.service"; -import {HalResource} from "../../api/api-v3/hal-resources/hal-resource.service"; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export class FormattableDisplayField extends DisplayField { protected ExpressionService:ExpressionService; diff --git a/frontend/app/components/wp-display/field-types/wp-display-id-field.module.ts b/frontend/app/components/wp-display/field-types/wp-display-id-field.module.ts index 482a3f3a7b..f5e8797e72 100644 --- a/frontend/app/components/wp-display/field-types/wp-display-id-field.module.ts +++ b/frontend/app/components/wp-display/field-types/wp-display-id-field.module.ts @@ -27,7 +27,7 @@ // ++ import {DisplayField} from "../wp-display-field/wp-display-field.module"; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {UiStateLinkBuilder} from '../../wp-fast-table/builders/ui-state-link-builder'; import {$stateToken} from 'core-app/angular4-transition-utils'; import {KeepTabService} from 'core-components/wp-single-view-tabs/keep-tab/keep-tab.service'; @@ -41,7 +41,7 @@ export class IdDisplayField extends DisplayField { private $state:StateService = this.$injector.get($stateToken); private keepTab:KeepTabService = this.$injector.get(KeepTabService); - constructor(public workPackage:WorkPackageResourceInterface, + constructor(public workPackage:WorkPackageResource, public name:string, public schema:op.FieldSchema) { super(workPackage as any, name, schema); diff --git a/frontend/app/components/wp-display/field-types/wp-display-resources-field.module.ts b/frontend/app/components/wp-display/field-types/wp-display-resources-field.module.ts index 970970cc47..2d4a1f5656 100644 --- a/frontend/app/components/wp-display/field-types/wp-display-resources-field.module.ts +++ b/frontend/app/components/wp-display/field-types/wp-display-resources-field.module.ts @@ -27,8 +27,8 @@ // ++ import {DisplayField} from "../wp-display-field/wp-display-field.module"; -import {HalResource} from '../../api/api-v3/hal-resources/hal-resource.service'; -import {WorkPackageResourceInterface} from "core-components/api/api-v3/hal-resources/work-package-resource.service"; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {WorkPackageResource} from "core-app/modules/hal/resources/work-package-resource"; export const cssClassCustomOption = 'custom-option'; diff --git a/frontend/app/components/wp-display/field-types/wp-display-spent-time-field.module.ts b/frontend/app/components/wp-display/field-types/wp-display-spent-time-field.module.ts index ac413e519f..785ed29099 100644 --- a/frontend/app/components/wp-display/field-types/wp-display-spent-time-field.module.ts +++ b/frontend/app/components/wp-display/field-types/wp-display-spent-time-field.module.ts @@ -26,10 +26,9 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; import {DurationDisplayField} from './wp-display-duration-field.module'; -import {HalResource} from "core-components/api/api-v3/hal-resources/hal-resource.service"; import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export class SpentTimeDisplayField extends DurationDisplayField { public template: string = '/components/wp-display/field-types/wp-display-spent-time-field.directive.html'; diff --git a/frontend/app/components/wp-display/field-types/wp-display-work-package-field.module.ts b/frontend/app/components/wp-display/field-types/wp-display-work-package-field.module.ts index 6fbd094474..529c20de9b 100644 --- a/frontend/app/components/wp-display/field-types/wp-display-work-package-field.module.ts +++ b/frontend/app/components/wp-display/field-types/wp-display-work-package-field.module.ts @@ -26,13 +26,12 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageResource} from '../../api/api-v3/hal-resources/work-package-resource.service'; import {UiStateLinkBuilder} from '../../wp-fast-table/builders/ui-state-link-builder'; import {DisplayField} from '../wp-display-field/wp-display-field.module'; -import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; import {StateService} from '@uirouter/core'; import {$stateToken} from 'core-app/angular4-transition-utils'; import {KeepTabService} from 'core-components/wp-single-view-tabs/keep-tab/keep-tab.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export class WorkPackageDisplayField extends DisplayField { diff --git a/frontend/app/components/wp-display/wp-display-field/wp-display-field.module.ts b/frontend/app/components/wp-display/wp-display-field/wp-display-field.module.ts index ee9eaf5a4c..9706561646 100644 --- a/frontend/app/components/wp-display/wp-display-field/wp-display-field.module.ts +++ b/frontend/app/components/wp-display/wp-display-field/wp-display-field.module.ts @@ -26,9 +26,9 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {HalResource} from '../../api/api-v3/hal-resources/hal-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; import {Field, FieldFactory} from '../../wp-field/wp-field.module'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageChangeset} from '../../wp-edit-form/work-package-changeset'; import {Injector} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; @@ -102,7 +102,7 @@ export class DisplayFieldFactory extends FieldFactory { protected static fields:{ [field:string]:string } = {}; protected static classes:{ [type:string]:typeof DisplayField } = {}; - public static create(workPackage:WorkPackageResourceInterface, + public static create(workPackage:WorkPackageResource, fieldName:string, schema:op.FieldSchema):DisplayField { let type = DisplayFieldFactory.getSpecificType(fieldName) || diff --git a/frontend/app/components/wp-edit-form/display-field-renderer.ts b/frontend/app/components/wp-edit-form/display-field-renderer.ts index 8a56bfc40b..94de02d208 100644 --- a/frontend/app/components/wp-edit-form/display-field-renderer.ts +++ b/frontend/app/components/wp-edit-form/display-field-renderer.ts @@ -1,7 +1,7 @@ import {ProgressTextDisplayField} from './../wp-display/field-types/wp-display-progress-text-field.module'; import {$injectFields} from '../angular/angular-injector-bridge.functions'; import {WorkPackageDisplayFieldService} from '../wp-display/wp-display-field/wp-display-field.service'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {DisplayField} from '../wp-display/wp-display-field/wp-display-field.module'; import {MultipleLinesStringObjectsDisplayField} from '../wp-display/field-types/wp-display-multiple-lines-string-objects-field.module'; import {WorkPackageChangeset} from './work-package-changeset'; @@ -24,7 +24,7 @@ export class DisplayFieldRenderer { $injectFields(this, 'wpDisplayField', 'I18n'); } - public render(workPackage:WorkPackageResourceInterface, + public render(workPackage:WorkPackageResource, name:string, changeset:WorkPackageChangeset|null, placeholder = cellEmptyPlaceholder):HTMLSpanElement { @@ -39,7 +39,7 @@ export class DisplayFieldRenderer { return span; } - public renderFieldValue(workPackage:WorkPackageResourceInterface, + public renderFieldValue(workPackage:WorkPackageResource, name:string, changeset:WorkPackageChangeset|null, placeholder = cellEmptyPlaceholder):[DisplayField|null, HTMLSpanElement] { @@ -65,7 +65,7 @@ export class DisplayFieldRenderer { return [field, span]; } - public getField(workPackage:WorkPackageResourceInterface, + public getField(workPackage:WorkPackageResource, fieldSchema:op.FieldSchema, name:string, changeset:WorkPackageChangeset|null):DisplayField { @@ -75,7 +75,7 @@ export class DisplayFieldRenderer { return field; } - private getFieldForCurrentContext(workPackage:WorkPackageResourceInterface, fieldSchema:op.FieldSchema, name:string) { + private getFieldForCurrentContext(workPackage:WorkPackageResource, fieldSchema:op.FieldSchema, name:string) { // We handle multi value fields differently in the single view context const isMultiLinesField = ['[]CustomOption', '[]User'].indexOf(fieldSchema.type) >= 0; @@ -99,7 +99,7 @@ export class DisplayFieldRenderer { } } - private setSpanAttributes(span:HTMLElement, field:DisplayField, name:string, workPackage:WorkPackageResourceInterface):void { + private setSpanAttributes(span:HTMLElement, field:DisplayField, name:string, workPackage:WorkPackageResource):void { span.classList.add(cellClassName, displayClassName, 'inplace-edit', 'wp-edit-field', name); span.dataset['fieldName'] = name; @@ -122,7 +122,7 @@ export class DisplayFieldRenderer { } } - private getAriaLabel(field:DisplayField, workPackage:WorkPackageResourceInterface):string { + private getAriaLabel(field:DisplayField, workPackage:WorkPackageResource):string { let titleContent; let labelContent = this.getLabelContent(field); diff --git a/frontend/app/components/wp-edit-form/single-view-edit-context.ts b/frontend/app/components/wp-edit-form/single-view-edit-context.ts index 5d21a6cfed..cff5f26596 100644 --- a/frontend/app/components/wp-edit-form/single-view-edit-context.ts +++ b/frontend/app/components/wp-edit-form/single-view-edit-context.ts @@ -30,7 +30,7 @@ import {StateService} from '@uirouter/core'; import {WorkPackageEditFieldGroupComponent} from 'core-components/wp-edit/wp-edit-field/wp-edit-field-group.directive'; import {WorkPackageEditFieldComponent} from 'core-components/wp-edit/wp-edit-field/wp-edit-field.component'; import {SimpleTemplateRenderer} from '../angular/simple-template-renderer'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {States} from '../states.service'; import {EditField} from '../wp-edit/wp-edit-field/wp-edit-field.module'; import {WorkPackageNotificationService} from '../wp-edit/wp-notification.service'; @@ -106,13 +106,13 @@ export class SingleViewEditContext implements WorkPackageEditContext { handler.$scope.$evalAsync(() => handler.field = field); } - public async reset(workPackage:WorkPackageResourceInterface, fieldName:string, focus:boolean = false) { + public async reset(workPackage:WorkPackageResource, fieldName:string, focus:boolean = false) { const ctrl = await this.fieldCtrl(fieldName); ctrl.reset(workPackage); ctrl.deactivate(focus); } - public onSaved(isInitial:boolean, savedWorkPackage:WorkPackageResourceInterface) { + public onSaved(isInitial:boolean, savedWorkPackage:WorkPackageResource) { this.fieldGroup.onSaved(isInitial, savedWorkPackage); } diff --git a/frontend/app/components/wp-edit-form/table-row-edit-context.ts b/frontend/app/components/wp-edit-form/table-row-edit-context.ts index 2741990e8c..59dcda973a 100644 --- a/frontend/app/components/wp-edit-form/table-row-edit-context.ts +++ b/frontend/app/components/wp-edit-form/table-row-edit-context.ts @@ -29,7 +29,8 @@ import {Injector} from '@angular/core'; import {$qToken, $timeoutToken, FocusHelperToken} from 'core-app/angular4-transition-utils'; import {SimpleTemplateRenderer} from '../angular/simple-template-renderer'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {injectorBridge} from '../angular/angular-injector-bridge.functions'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {States} from '../states.service'; import {EditField} from '../wp-edit/wp-edit-field/wp-edit-field.module'; import {CellBuilder, editCellContainer, tdClassName} from '../wp-fast-table/builders/cell-builder'; @@ -70,7 +71,7 @@ export class TableRowEditContext implements WorkPackageEditContext { return this.rowContainer.find(`.${tdClassName}.${fieldName}`).first(); } - public activateField(form:WorkPackageEditForm, field:EditField, fieldName:string, errors:string[]):ng.IPromise { + public activateField(form:WorkPackageEditForm, field:EditField, fieldName:string, errors:string[]):Promise { const deferred = this.$q.defer(); this.waitForContainer(fieldName) @@ -119,7 +120,7 @@ export class TableRowEditContext implements WorkPackageEditContext { handler.$scope.$evalAsync(() => handler.field = field); } - public reset(workPackage:WorkPackageResourceInterface, fieldName:string, focus?:boolean) { + public reset(workPackage:WorkPackageResource, fieldName:string, focus?:boolean) { const cell = this.findContainer(fieldName); if (cell.length) { @@ -142,7 +143,7 @@ export class TableRowEditContext implements WorkPackageEditContext { return 'subject'; } - public onSaved(isInitial:boolean, savedWorkPackage:WorkPackageResourceInterface) { + public onSaved(isInitial:boolean, savedWorkPackage:WorkPackageResource) { // Nothing to do here. } @@ -167,8 +168,3 @@ export class TableRowEditContext implements WorkPackageEditContext { return jQuery(`.${this.classIdentifier}-table`); } } - -// TableRowEditContext.$inject = [ -// 'wpCacheService', 'states', 'wpTableColumns', 'wpTableRefresh', -// 'FocusHelper', '$q', '$timeout', 'templateRenderer' -// ]; diff --git a/frontend/app/components/wp-edit-form/work-package-changeset.ts b/frontend/app/components/wp-edit-form/work-package-changeset.ts index e366153f0f..964b3201e3 100644 --- a/frontend/app/components/wp-edit-form/work-package-changeset.ts +++ b/frontend/app/components/wp-edit-form/work-package-changeset.ts @@ -28,18 +28,14 @@ import {input} from 'reactivestates'; import {debugLog} from '../../helpers/debug_output'; -import {ErrorResource} from '../api/api-v3/hal-resources/error-resource.service'; -import {FormResourceInterface} from '../api/api-v3/hal-resources/form-resource.service'; -import { - WorkPackageResource, - WorkPackageResourceInterface -} from '../api/api-v3/hal-resources/work-package-resource.service'; import {SchemaCacheService} from '../schemas/schema-cache.service'; import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; import {WorkPackageNotificationService} from '../wp-edit/wp-notification.service'; import {WorkPackageCreateService} from '../wp-new/wp-create.service'; import {WorkPackageEditingService} from './work-package-editing-service'; import {Injector} from '@angular/core'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {FormResource} from 'core-app/modules/hal/resources/form-resource'; export class WorkPackageChangeset { // Injections @@ -54,14 +50,14 @@ export class WorkPackageChangeset { public inFlight:boolean = false; // The current work package form - public wpForm = input(); + public wpForm = input(); // The current editing resource - public resource:WorkPackageResourceInterface | null; + public resource:WorkPackageResource|null; constructor(readonly injector:Injector, - public workPackage:WorkPackageResourceInterface, - form?:FormResourceInterface) { + public workPackage:WorkPackageResource, + form?:FormResource) { // New work packages have no schema set yet, so update the form immediately to get one if (form !== undefined) { this.wpForm.putValue(form); @@ -124,8 +120,8 @@ export class WorkPackageChangeset { return this.changes.hasOwnProperty(key); } - public async getForm():Promise { - this.wpForm.putFromPromiseIfPristine(async() => { + public async getForm():Promise { + this.wpForm.putFromPromiseIfPristine(() => { return this.updateForm(); }); @@ -133,7 +129,7 @@ export class WorkPackageChangeset { if (this.wpForm.hasValue()) { return Promise.resolve(this.wpForm.value!); } else { - return new Promise((resolve) => this.wpForm.valuesPromise().then(resolve)); + return new Promise((resolve) => this.wpForm.valuesPromise().then(resolve)); } } @@ -141,12 +137,12 @@ export class WorkPackageChangeset { * Update the form resource from the API. * @return {angular.IPromise} */ - public async updateForm():Promise { + public async updateForm():Promise { let payload = this.buildPayloadFromChanges(); - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.workPackage.$links.update(payload) - .then((form:FormResourceInterface) => { + .then((form:FormResource) => { this.wpForm.putValue(form); this.buildResource(); @@ -160,25 +156,23 @@ export class WorkPackageChangeset { }); } - - public async save():Promise { - + public async save():Promise { this.inFlight = true; const wasNew = this.workPackage.isNew; - let promise = new Promise((resolve, reject) => { + let promise = new Promise((resolve, reject) => { this.updateForm() .then((form) => { const payload = this.buildPayloadFromChanges(); // Reject errors when occurring in form validation - const errors = ErrorResource.fromFormResponse(form); + const errors = form.getErrors(); if (errors !== null) { return reject(errors); } this.workPackage.$links.updateImmediately(payload) - .then(async(savedWp:WorkPackageResourceInterface) => { + .then((savedWp:WorkPackageResource) => { // Initialize any potentially new HAL values this.workPackage.$initialize(savedWp); @@ -205,9 +199,9 @@ export class WorkPackageChangeset { errorsOnForm: false, error: error }); - }); - }) - .catch(reject); + }) + .catch(reject); + }); }); promise @@ -220,7 +214,7 @@ export class WorkPackageChangeset { /** * Merge the current changes into the payload resource. * - * @param {FormResourceInterface} form + * @param {FormResource} form * @return {any} */ private mergeWithPayload(plainPayload:any) { @@ -328,14 +322,14 @@ export class WorkPackageChangeset { let payload:any = this.workPackage.$plain(); if (hasForm) { - _.defaultsDeep(payload, this.wpForm.value!.payload.$source); + } const resource = new WorkPackageResource(this.mergeWithPayload(payload), true); // Override the schema with the current form, if any. resource.overriddenSchema = this.schema; - this.resource = (resource as WorkPackageResourceInterface); + this.resource = (resource as WorkPackageResource); this.wpEditing.updateValue(this.workPackage.id, this); } } diff --git a/frontend/app/components/wp-edit-form/work-package-edit-context.ts b/frontend/app/components/wp-edit-form/work-package-edit-context.ts index 277a04dc9b..c58de1b63d 100644 --- a/frontend/app/components/wp-edit-form/work-package-edit-context.ts +++ b/frontend/app/components/wp-edit-form/work-package-edit-context.ts @@ -26,10 +26,7 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import { - WorkPackageResource, - WorkPackageResourceInterface -} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageEditForm} from './work-package-edit-form'; import {EditField} from '../wp-edit/wp-edit-field/wp-edit-field.module'; import {WorkPackageEditFieldHandler} from './work-package-edit-field-handler'; @@ -52,7 +49,7 @@ export interface WorkPackageEditContext { /** * Reset the field and re-render the current WPs value. */ - reset(workPackage:WorkPackageResourceInterface, fieldName:string, focus?:boolean):void; + reset(workPackage:WorkPackageResource, fieldName:string, focus?:boolean):void; /** * Return the first relevant field from the given list of attributes. @@ -62,5 +59,5 @@ export interface WorkPackageEditContext { /** * Optional callback when the form is being saved */ - onSaved(isInitial:boolean, savedWorkPackage:WorkPackageResourceInterface):void; + onSaved(isInitial:boolean, savedWorkPackage:WorkPackageResource):void; } diff --git a/frontend/app/components/wp-edit-form/work-package-edit-field-handler.ts b/frontend/app/components/wp-edit-form/work-package-edit-field-handler.ts index 4c8155ca50..cb71c9e0b6 100644 --- a/frontend/app/components/wp-edit-form/work-package-edit-field-handler.ts +++ b/frontend/app/components/wp-edit-form/work-package-edit-field-handler.ts @@ -30,10 +30,6 @@ import {WorkPackageEditForm} from './work-package-edit-form'; import {EditField} from '../wp-edit/wp-edit-field/wp-edit-field.module'; import {WorkPackageEditContext} from './work-package-edit-context'; import {$injectFields} from '../angular/angular-injector-bridge.functions'; -import { - WorkPackageResource, - WorkPackageResourceInterface -} from '../api/api-v3/hal-resources/work-package-resource.service'; import {keyCodes} from '../common/keyCodes.enum'; export class WorkPackageEditFieldHandler { diff --git a/frontend/app/components/wp-edit-form/work-package-edit-form.ts b/frontend/app/components/wp-edit-form/work-package-edit-form.ts index 61cb440ea1..bec74ad7be 100644 --- a/frontend/app/components/wp-edit-form/work-package-edit-form.ts +++ b/frontend/app/components/wp-edit-form/work-package-edit-form.ts @@ -27,8 +27,8 @@ // ++ import {Subscription} from 'rxjs/Subscription'; -import {$injectFields, injectorBridge} from '../angular/angular-injector-bridge.functions'; -import {ErrorResource} from '../api/api-v3/hal-resources/error-resource.service'; +import {$injectFields} from '../angular/angular-injector-bridge.functions'; +import {ErrorResource} from 'core-app/modules/hal/resources/error-resource'; import {States} from '../states.service'; import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; import {EditField} from '../wp-edit/wp-edit-field/wp-edit-field.module'; @@ -38,9 +38,9 @@ import {WorkPackageEditContext} from './work-package-edit-context'; import {WorkPackageEditFieldHandler} from './work-package-edit-field-handler'; import {debugLog} from '../../helpers/debug_output'; import {WorkPackageChangeset} from './work-package-changeset'; -import {FormResourceInterface} from '../api/api-v3/hal-resources/form-resource.service'; +import {FormResource} from 'core-app/modules/hal/resources/form-resource'; import {WorkPackageEditingService} from './work-package-editing-service'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageTableRefreshService} from '../wp-table/wp-table-refresh-request.service'; import {Injector} from '@angular/core'; @@ -71,7 +71,7 @@ export class WorkPackageEditForm { public static createInContext(injector:Injector, editContext:WorkPackageEditContext, - wp:WorkPackageResourceInterface, + wp:WorkPackageResource, editMode:boolean = false) { const form = new WorkPackageEditForm(injector, wp, editMode); @@ -81,12 +81,12 @@ export class WorkPackageEditForm { } constructor(readonly injector:Injector, - public workPackage:WorkPackageResourceInterface, + public workPackage:WorkPackageResource, public editMode:boolean = false) { this.wpSubscription = this.wpCacheService.state(workPackage.id) .values$() - .subscribe((wp:WorkPackageResourceInterface) => { + .subscribe((wp:WorkPackageResource) => { this.workPackage = wp; }); @@ -179,7 +179,7 @@ export class WorkPackageEditForm { * Save the active changeset. * @return {any} */ - public async submit():Promise { + public async submit():Promise { if (this.changeset.empty && !this.workPackage.isNew) { this.closeEditFields(); return Promise.resolve(this.workPackage); @@ -194,7 +194,7 @@ export class WorkPackageEditForm { const openFields = _.keys(this.activeFields); _.each(this.activeFields, (handler:WorkPackageEditFieldHandler) => handler.field.onSubmit()); - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.changeset.save() .then(savedWorkPackage => { // Close all current fields @@ -297,7 +297,7 @@ export class WorkPackageEditForm { private async buildField(fieldName:string):Promise { return new Promise((resolve, reject) => { this.changeset.getForm() - .then((form:FormResourceInterface) => { + .then((form:FormResource) => { const schemaName = this.changeset.getSchemaName(fieldName); const fieldSchema = form.schema[schemaName]; diff --git a/frontend/app/components/wp-edit-form/work-package-editing-service.ts b/frontend/app/components/wp-edit-form/work-package-editing-service.ts index f8604dbf81..149f0f5802 100644 --- a/frontend/app/components/wp-edit-form/work-package-editing-service.ts +++ b/frontend/app/components/wp-edit-form/work-package-editing-service.ts @@ -27,7 +27,7 @@ // ++ import {WorkPackageEditForm} from './work-package-edit-form'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageEditContext} from './work-package-edit-context'; import {WorkPackageChangeset} from './work-package-changeset'; import {combine, deriveRaw, multiInput, State, StatesGroup} from 'reactivestates'; @@ -65,7 +65,7 @@ export class WorkPackageEditingService extends StateCacheService} + * @return {State} */ - public temporaryEditResource(id:string):State { + public temporaryEditResource(id:string):State { const combined = combine(this.wpCacheService.state(id), this.state(id)); return deriveRaw(combined, @@ -116,7 +116,7 @@ export class WorkPackageEditingService extends StateCacheService { + public async saveChanges(workPackageId:string):Promise { const state = this.state(workPackageId); if (state.hasValue()) { @@ -129,7 +129,7 @@ export class WorkPackageEditingService extends StateCacheService { + .then((wp:WorkPackageResource) => { return new WorkPackageChangeset(this.injector, wp); }); } diff --git a/frontend/app/components/wp-edit-form/work-package-filter-values.ts b/frontend/app/components/wp-edit-form/work-package-filter-values.ts index c9bf46ad88..56d37f2167 100644 --- a/frontend/app/components/wp-edit-form/work-package-filter-values.ts +++ b/frontend/app/components/wp-edit-form/work-package-filter-values.ts @@ -1,10 +1,8 @@ -import {HalResource} from '../api/api-v3/hal-resources/hal-resource.service'; -import {CollectionResource} from '../api/api-v3/hal-resources/collection-resource.service'; -import {FormResourceInterface} from '../api/api-v3/hal-resources/form-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {FormResource} from 'core-app/modules/hal/resources/form-resource'; import {WorkPackageChangeset} from './work-package-changeset'; -import { - QueryFilterInstanceResource, -} from '../api/api-v3/hal-resources/query-filter-instance-resource.service'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; export class WorkPackageFilterValues { @@ -43,7 +41,7 @@ export class WorkPackageFilterValues { }); } - private async setAllowedValueFor(form:FormResourceInterface, field:string, value:string|HalResource) { + private async setAllowedValueFor(form:FormResource, field:string, value:string|HalResource) { return this.allowedValuesFor(form, field).then((allowedValues) => { let newValue; @@ -63,7 +61,7 @@ export class WorkPackageFilterValues { }); } - private async allowedValuesFor(form:FormResourceInterface, field:string):Promise { + private async allowedValuesFor(form:FormResource, field:string):Promise { const fieldSchema = form.schema[field]; return new Promise(resolve => { diff --git a/frontend/app/components/wp-edit/field-types/wp-edit-multi-select-field.module.ts b/frontend/app/components/wp-edit/field-types/wp-edit-multi-select-field.module.ts index 4d3dae4d41..e6b9b966d7 100644 --- a/frontend/app/components/wp-edit/field-types/wp-edit-multi-select-field.module.ts +++ b/frontend/app/components/wp-edit/field-types/wp-edit-multi-select-field.module.ts @@ -27,8 +27,8 @@ // ++ import {EditField} from '../wp-edit-field/wp-edit-field.module'; -import {CollectionResource} from '../../api/api-v3/hal-resources/collection-resource.service'; -import {HalResource} from '../../api/api-v3/hal-resources/hal-resource.service'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; import {$injectFields} from '../../angular/angular-injector-bridge.functions'; export class MultiSelectEditField extends EditField { diff --git a/frontend/app/components/wp-edit/field-types/wp-edit-select-field.module.ts b/frontend/app/components/wp-edit/field-types/wp-edit-select-field.module.ts index 72392028b3..900deb6f34 100644 --- a/frontend/app/components/wp-edit/field-types/wp-edit-select-field.module.ts +++ b/frontend/app/components/wp-edit/field-types/wp-edit-select-field.module.ts @@ -27,10 +27,9 @@ // ++ import {EditField} from '../wp-edit-field/wp-edit-field.module'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; -import {CollectionResource} from '../../api/api-v3/hal-resources/collection-resource.service'; -import {HalResource} from '../../api/api-v3/hal-resources/hal-resource.service'; import {I18nToken} from 'core-app/angular4-transition-utils'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export class SelectEditField extends EditField { public options:any[]; diff --git a/frontend/app/components/wp-edit/field-types/wp-edit-wiki-textarea-field.module.ts b/frontend/app/components/wp-edit/field-types/wp-edit-wiki-textarea-field.module.ts index a2ec6a41b3..b94a101396 100644 --- a/frontend/app/components/wp-edit/field-types/wp-edit-wiki-textarea-field.module.ts +++ b/frontend/app/components/wp-edit/field-types/wp-edit-wiki-textarea-field.module.ts @@ -27,7 +27,8 @@ // ++ import {EditField} from '../wp-edit-field/wp-edit-field.module'; -import {$injectFields} from '../../angular/angular-injector-bridge.functions'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {$injectFields, $injectNow} from '../../angular/angular-injector-bridge.functions'; import {TextileService} from './../../common/textile/textile-service'; import {WorkPackageEditFieldHandler} from 'core-components/wp-edit-form/work-package-edit-field-handler'; import {AutoCompleteHelperService} from 'core-components/common/autocomplete/auto-complete-helper.service'; diff --git a/frontend/app/components/wp-edit/wp-edit-field/wp-edit-field-group.directive.ts b/frontend/app/components/wp-edit/wp-edit-field/wp-edit-field-group.directive.ts index 714efd6e9a..0c839ec474 100644 --- a/frontend/app/components/wp-edit/wp-edit-field/wp-edit-field-group.directive.ts +++ b/frontend/app/components/wp-edit/wp-edit-field/wp-edit-field-group.directive.ts @@ -27,7 +27,6 @@ // ++ import {Component, Inject, Injector, Input, OnDestroy, OnInit} from '@angular/core'; -import {downgradeComponent} from '@angular/upgrade/static'; import {StateService, Transition, TransitionService} from '@uirouter/core'; import {$stateToken, I18nToken} from 'core-app/angular4-transition-utils'; import {ConfigurationService} from 'core-components/common/config/configuration.service'; @@ -37,11 +36,11 @@ import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {input} from 'reactivestates'; import {filter, map, take, takeUntil} from 'rxjs/operators'; import {opWorkPackagesModule} from '../../../angular-modules'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; import {States} from '../../states.service'; import {SingleViewEditContext} from '../../wp-edit-form/single-view-edit-context'; import {WorkPackageEditForm} from '../../wp-edit-form/work-package-edit-form'; import {WorkPackageEditingService} from '../../wp-edit-form/work-package-editing-service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageTableSelection} from '../../wp-fast-table/state/wp-table-selection.service'; import {WorkPackageNotificationService} from '../wp-notification.service'; import {WorkPackageCreateService} from './../../wp-new/wp-create.service'; @@ -51,7 +50,7 @@ import {WorkPackageCreateService} from './../../wp-new/wp-create.service'; template: '' }) export class WorkPackageEditFieldGroupComponent implements OnInit, OnDestroy { - @Input('workPackage') workPackage:WorkPackageResourceInterface; + @Input('workPackage') workPackage:WorkPackageResource; @Input('successState') successState?:string; @Input('inEditMode') inEditMode:boolean = false; @@ -113,7 +112,7 @@ export class WorkPackageEditFieldGroupComponent implements OnInit, OnDestroy { .pipe( takeUntil(componentDestroyed(this)) ) - .subscribe((wp:WorkPackageResourceInterface) => { + .subscribe((wp:WorkPackageResource) => { this.form.editMode = false; this.stopEditingAndLeave(wp, true); }); @@ -184,13 +183,13 @@ export class WorkPackageEditFieldGroupComponent implements OnInit, OnDestroy { * for new work packages, ignore them and only stop editing on non-new WPs. * */ - public onSaved(isInitial:boolean, savedWorkPackage:WorkPackageResourceInterface) { + public onSaved(isInitial:boolean, savedWorkPackage:WorkPackageResource) { if (!isInitial) { this.stopEditingAndLeave(savedWorkPackage, false); } } - private stopEditingAndLeave(savedWorkPackage:WorkPackageResourceInterface, isInitial:boolean) { + private stopEditingAndLeave(savedWorkPackage:WorkPackageResource, isInitial:boolean) { this.wpEditing.stopEditing(this.workPackage.id); if (this.successState) { @@ -202,7 +201,7 @@ export class WorkPackageEditFieldGroupComponent implements OnInit, OnDestroy { } } - private updateDisplayField(field:WorkPackageEditFieldComponent, wp:WorkPackageResourceInterface) { + private updateDisplayField(field:WorkPackageEditFieldComponent, wp:WorkPackageResource) { field.workPackage = wp; field.render(); } @@ -225,10 +224,3 @@ export class WorkPackageEditFieldGroupComponent implements OnInit, OnDestroy { return toParams.workPackageId !== undefined && toParams.workPackageId === fromParams.workPackageId; } } - - -opWorkPackagesModule.directive('wpEditFieldGroupNg1', - downgradeComponent({component: WorkPackageEditFieldGroupComponent}) -); - - diff --git a/frontend/app/components/wp-edit/wp-edit-field/wp-edit-field.component.ts b/frontend/app/components/wp-edit/wp-edit-field/wp-edit-field.component.ts index 3d9cce7bcf..b5d5abbcd4 100644 --- a/frontend/app/components/wp-edit/wp-edit-field/wp-edit-field.component.ts +++ b/frontend/app/components/wp-edit/wp-edit-field/wp-edit-field.component.ts @@ -26,7 +26,7 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; import {WorkPackageNotificationService} from '../wp-notification.service'; import {opWorkPackagesModule} from '../../../angular-modules'; @@ -59,7 +59,7 @@ export class WorkPackageEditFieldComponent implements OnInit { @Input('wrapperClasses') public wrapperClasses?:string; @Input('displayPlaceholder') public displayPlaceholder?:string; - public workPackage:WorkPackageResourceInterface; + public workPackage:WorkPackageResource; public fieldRenderer = new DisplayFieldRenderer('single-view'); public editFieldContainerClass = editFieldContainerClass; private active = false; @@ -175,7 +175,7 @@ export class WorkPackageEditFieldComponent implements OnInit { return this.$element.find('.__d_edit_container'); } - public reset(workPackage:WorkPackageResourceInterface) { + public reset(workPackage:WorkPackageResource) { this.workPackage = workPackage; this.render(); diff --git a/frontend/app/components/wp-edit/wp-notification.service.ts b/frontend/app/components/wp-edit/wp-notification.service.ts index a3f645189b..bb779701c5 100644 --- a/frontend/app/components/wp-edit/wp-notification.service.ts +++ b/frontend/app/components/wp-edit/wp-notification.service.ts @@ -26,8 +26,8 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; -import {ErrorResource} from '../api/api-v3/hal-resources/error-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {ErrorResource} from 'core-app/modules/hal/resources/error-resource'; import {wpServicesModule} from '../../angular-modules'; import {StateService} from '@uirouter/core'; @@ -38,7 +38,7 @@ export class WorkPackageNotificationService { protected loadingIndicator:any) { } - public showSave(workPackage: WorkPackageResourceInterface, isCreate:boolean = false) { + public showSave(workPackage: WorkPackageResource, isCreate:boolean = false) { var message:any = { message: this.I18n.t('js.notice_successful_' + (isCreate ? 'create' : 'update')), }; @@ -51,7 +51,7 @@ export class WorkPackageNotificationService { this.NotificationsService.addSuccess(message); } - public handleRawError(response:any, workPackage?:WorkPackageResourceInterface) { + public handleRawError(response:any, workPackage?:WorkPackageResource) { if (response && response.data && response.data._type === 'Error') { const resource = new ErrorResource(response.data); return this.handleErrorResponse(resource, workPackage); @@ -60,7 +60,7 @@ export class WorkPackageNotificationService { this.showGeneralError(response); } - public handleErrorResponse(errorResource:any, workPackage?:WorkPackageResourceInterface) { + public handleErrorResponse(errorResource:any, workPackage?:WorkPackageResource) { if (!(errorResource instanceof ErrorResource)) { return this.showGeneralError(errorResource); } @@ -72,7 +72,7 @@ export class WorkPackageNotificationService { this.showApiErrorMessages(errorResource); } - public showError(errorResource:any, workPackage:WorkPackageResourceInterface) { + public showError(errorResource:any, workPackage:WorkPackageResource) { this.showCustomError(errorResource, workPackage) || this.showApiErrorMessages(errorResource); } @@ -93,7 +93,7 @@ export class WorkPackageNotificationService { )); } - private showCustomError(errorResource:any, workPackage:WorkPackageResourceInterface) { + private showCustomError(errorResource:any, workPackage:WorkPackageResource) { if (errorResource.errorIdentifier === 'urn:openproject-org:api:v3:errors:PropertyFormatError') { let attributeName = workPackage.schema[errorResource.details.attribute].name; @@ -125,7 +125,7 @@ export class WorkPackageNotificationService { return true; } - private showInFullScreenLink(workPackage:WorkPackageResourceInterface) { + private showInFullScreenLink(workPackage:WorkPackageResource) { return { target: () => { this.loadingIndicator.mainPage = diff --git a/frontend/app/components/wp-fast-table/builders/cell-builder.ts b/frontend/app/components/wp-fast-table/builders/cell-builder.ts index 2406ae072a..ab8f403b42 100644 --- a/frontend/app/components/wp-fast-table/builders/cell-builder.ts +++ b/frontend/app/components/wp-fast-table/builders/cell-builder.ts @@ -1,4 +1,4 @@ -import {WorkPackageResourceInterface} from './../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import { DisplayFieldRenderer, editFieldContainerClass @@ -11,7 +11,7 @@ export class CellBuilder { private fieldRenderer = new DisplayFieldRenderer('table'); - public build(workPackage:WorkPackageResourceInterface, attribute:string) { + public build(workPackage:WorkPackageResource, attribute:string) { const td = document.createElement('td'); td.classList.add(tdClassName, wpCellTdClassName, attribute); @@ -25,7 +25,7 @@ export class CellBuilder { return td; } - public refresh(container:HTMLElement, workPackage:WorkPackageResourceInterface, attribute:string) { + public refresh(container:HTMLElement, workPackage:WorkPackageResource, attribute:string) { const displayElement = this.fieldRenderer.render(workPackage, attribute, null); container.innerHTML = ''; diff --git a/frontend/app/components/wp-fast-table/builders/modes/grouped/group-header-builder.ts b/frontend/app/components/wp-fast-table/builders/modes/grouped/group-header-builder.ts index 7c8265e8c8..1c31dcd494 100644 --- a/frontend/app/components/wp-fast-table/builders/modes/grouped/group-header-builder.ts +++ b/frontend/app/components/wp-fast-table/builders/modes/grouped/group-header-builder.ts @@ -1,7 +1,7 @@ import {Injector} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; -import {GroupObject} from '../../../../api/api-v3/hal-resources/wp-collection-resource.service'; import {groupName} from './grouped-rows-helpers'; +import {GroupObject} from 'core-app/modules/hal/resources/wp-collection-resource'; export const rowGroupClassName = 'wp-table--group-header'; diff --git a/frontend/app/components/wp-fast-table/builders/modes/grouped/grouped-render-pass.ts b/frontend/app/components/wp-fast-table/builders/modes/grouped/grouped-render-pass.ts index 42f31caf9d..810044ecea 100644 --- a/frontend/app/components/wp-fast-table/builders/modes/grouped/grouped-render-pass.ts +++ b/frontend/app/components/wp-fast-table/builders/modes/grouped/grouped-render-pass.ts @@ -1,7 +1,6 @@ import {Injector} from '@angular/core'; -import {HalResource} from '../../../../api/api-v3/hal-resources/hal-resource.service'; -import {WorkPackageResourceInterface} from '../../../../api/api-v3/hal-resources/work-package-resource.service'; -import {GroupObject} from '../../../../api/api-v3/hal-resources/wp-collection-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageTable} from '../../../wp-fast-table'; import {WorkPackageTableRow} from '../../../wp-table.interfaces'; import {SingleRowBuilder} from '../../rows/single-row-builder'; @@ -9,6 +8,7 @@ import {PlainRenderPass} from '../plain/plain-render-pass'; import {groupClassNameFor, GroupHeaderBuilder} from './group-header-builder'; import {collapsedRowClass} from './grouped-rows-builder'; import {groupByProperty, groupedRowClassName} from './grouped-rows-helpers'; +import {GroupObject} from 'core-app/modules/hal/resources/wp-collection-resource'; export class GroupedRenderPass extends PlainRenderPass { @@ -46,7 +46,7 @@ export class GroupedRenderPass extends PlainRenderPass { * Find a matching group for the given work package. * The API sadly doesn't provide us with the information which group a WP belongs to. */ - private matchingGroup(workPackage:WorkPackageResourceInterface) { + private matchingGroup(workPackage:WorkPackageResource) { return _.find(this.groups, (group:GroupObject) => { let property = workPackage[groupByProperty(group)]; // explicitly check for undefined as `false` (bool) is a valid value. diff --git a/frontend/app/components/wp-fast-table/builders/modes/grouped/grouped-rows-builder.ts b/frontend/app/components/wp-fast-table/builders/modes/grouped/grouped-rows-builder.ts index e2277a0a69..b6e25ead3d 100644 --- a/frontend/app/components/wp-fast-table/builders/modes/grouped/grouped-rows-builder.ts +++ b/frontend/app/components/wp-fast-table/builders/modes/grouped/grouped-rows-builder.ts @@ -1,6 +1,5 @@ import {Injector} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; -import {GroupObject} from '../../../../api/api-v3/hal-resources/wp-collection-resource.service'; import {States} from '../../../../states.service'; import {WorkPackageTableColumnsService} from '../../../state/wp-table-columns.service'; import {WorkPackageTable} from '../../../wp-fast-table'; @@ -9,6 +8,7 @@ import {RowsBuilder} from '../rows-builder'; import {GroupHeaderBuilder} from './group-header-builder'; import {GroupedRenderPass} from './grouped-render-pass'; import {groupedRowClassName, groupIdentifier} from './grouped-rows-helpers'; +import {GroupObject} from 'core-app/modules/hal/resources/wp-collection-resource'; import {TableState} from 'core-components/wp-table/table-state/table-state'; export const rowGroupClassName = 'wp-table--group-header'; diff --git a/frontend/app/components/wp-fast-table/builders/modes/grouped/grouped-rows-helpers.ts b/frontend/app/components/wp-fast-table/builders/modes/grouped/grouped-rows-helpers.ts index dc2e391d3e..dd9316472b 100644 --- a/frontend/app/components/wp-fast-table/builders/modes/grouped/grouped-rows-helpers.ts +++ b/frontend/app/components/wp-fast-table/builders/modes/grouped/grouped-rows-helpers.ts @@ -1,4 +1,4 @@ -import {GroupObject} from '../../../../api/api-v3/hal-resources/wp-collection-resource.service'; +import {GroupObject} from 'core-app/modules/hal/resources/wp-collection-resource'; export function groupIdentifier(group:GroupObject) { let value = group.value || 'nullValue'; diff --git a/frontend/app/components/wp-fast-table/builders/modes/hierarchy/hierarchy-render-pass.ts b/frontend/app/components/wp-fast-table/builders/modes/hierarchy/hierarchy-render-pass.ts index e68e6f5cf1..f2122a2cfc 100644 --- a/frontend/app/components/wp-fast-table/builders/modes/hierarchy/hierarchy-render-pass.ts +++ b/frontend/app/components/wp-fast-table/builders/modes/hierarchy/hierarchy-render-pass.ts @@ -1,7 +1,6 @@ import {Injector} from '@angular/core'; import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; import {TableState} from 'core-components/wp-table/table-state/table-state'; -import {WorkPackageResourceInterface} from '../../../../api/api-v3/hal-resources/work-package-resource.service'; import {States} from '../../../../states.service'; import { ancestorClassIdentifier, @@ -14,6 +13,7 @@ import {WorkPackageTableHierarchies} from '../../../wp-table-hierarchies'; import {WorkPackageTableRow} from '../../../wp-table.interfaces'; import {PrimaryRenderPass, RowRenderInfo} from '../../primary-render-pass'; import {additionalHierarchyRowClassName, SingleHierarchyRowBuilder} from './single-hierarchy-row-builder'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; export class HierarchyRenderPass extends PrimaryRenderPass { @@ -26,10 +26,10 @@ export class HierarchyRenderPass extends PrimaryRenderPass { public rendered:{ [workPackageId:string]:boolean }; // Remember additional parents inserted that are not part of the results table - public additionalParents:{ [workPackageId:string]:WorkPackageResourceInterface }; + public additionalParents:{ [workPackageId:string]:WorkPackageResource }; // Defer children to be rendered when their parent occurs later in the table - public deferred:{ [parentId:string]:WorkPackageResourceInterface[] }; + public deferred:{ [parentId:string]:WorkPackageResource[] }; // Collapsed state private hierarchies:WorkPackageTableHierarchies; @@ -55,7 +55,7 @@ export class HierarchyRenderPass extends PrimaryRenderPass { protected doRender() { this.workPackageTable.originalRows.forEach((wpId:string) => { const row:WorkPackageTableRow = this.workPackageTable.originalRowIndex[wpId]; - const workPackage:WorkPackageResourceInterface = row.object; + const workPackage:WorkPackageResource = row.object; // If we need to defer this row, skip it for now if (this.deferInsertion(workPackage)) { @@ -84,7 +84,7 @@ export class HierarchyRenderPass extends PrimaryRenderPass { * @param workPackage * @returns {boolean} */ - public deferInsertion(workPackage:WorkPackageResourceInterface):boolean { + public deferInsertion(workPackage:WorkPackageResource):boolean { const ancestors = workPackage.ancestors; // Will only defer if at least one ancestor exists @@ -134,13 +134,13 @@ export class HierarchyRenderPass extends PrimaryRenderPass { * deferred, each of them will be passed through renderCallback. * @param workPackage */ - private renderAllDeferredChildren(workPackage:WorkPackageResourceInterface) { + private renderAllDeferredChildren(workPackage:WorkPackageResource) { const wpId = workPackage.id.toString(); const deferredChildren = this.deferred[wpId] || []; // If the work package has deferred children to render, // run them through the callback - deferredChildren.forEach((child:WorkPackageResourceInterface) => { + deferredChildren.forEach((child:WorkPackageResource) => { this.insertUnderParent(this.getOrBuildRow(child), child.parent); // Descend into any children the child WP might have and callback @@ -148,7 +148,7 @@ export class HierarchyRenderPass extends PrimaryRenderPass { }); } - private getOrBuildRow(workPackage:WorkPackageResourceInterface) { + private getOrBuildRow(workPackage:WorkPackageResource) { let row:WorkPackageTableRow = this.workPackageTable.originalRowIndex[workPackage.id]; if (!row) { @@ -164,7 +164,7 @@ export class HierarchyRenderPass extends PrimaryRenderPass { const ancestorGroups:string[] = []; // Iterate ancestors - ancestors.forEach((el:WorkPackageResourceInterface, index:number) => { + ancestors.forEach((el:WorkPackageResource, index:number) => { const ancestor = this.states.workPackages.get(el.id).value!; @@ -206,7 +206,7 @@ export class HierarchyRenderPass extends PrimaryRenderPass { * @param row * @param parentId */ - private insertUnderParent(row:WorkPackageTableRow, parent:WorkPackageResourceInterface) { + private insertUnderParent(row:WorkPackageTableRow, parent:WorkPackageResource) { const [tr, hidden] = this.rowBuilder.buildEmpty(row.object); row.element = tr; this.insertAtExistingHierarchy(row.object, tr, parent, hidden, false); @@ -217,12 +217,12 @@ export class HierarchyRenderPass extends PrimaryRenderPass { * @param workPackage * @param hidden */ - private markRendered(workPackage:WorkPackageResourceInterface, hidden:boolean = false, isAncestor:boolean = false) { + private markRendered(workPackage:WorkPackageResource, hidden:boolean = false, isAncestor:boolean = false) { this.rendered[workPackage.id] = true; this.renderedOrder.push(this.buildRenderInfo(workPackage, hidden, isAncestor)); } - public ancestorClasses(workPackage:WorkPackageResourceInterface) { + public ancestorClasses(workPackage:WorkPackageResource) { const rowClasses = [hierarchyRootClass(workPackage.id)]; if (_.isArray(workPackage.ancestors)) { @@ -242,9 +242,9 @@ export class HierarchyRenderPass extends PrimaryRenderPass { /** * Append a row to the given parent hierarchy group. */ - private insertAtExistingHierarchy(workPackage:WorkPackageResourceInterface, + private insertAtExistingHierarchy(workPackage:WorkPackageResource, el:HTMLElement, - parent:WorkPackageResourceInterface, + parent:WorkPackageResource, hidden:boolean, isAncestor:boolean) { // Either append to the hierarchy group root (= the parentID row itself) @@ -262,7 +262,7 @@ export class HierarchyRenderPass extends PrimaryRenderPass { this.rendered[workPackage.id] = true; } - private buildRenderInfo(workPackage:WorkPackageResourceInterface, hidden:boolean, isAncestor:boolean):RowRenderInfo { + private buildRenderInfo(workPackage:WorkPackageResource, hidden:boolean, isAncestor:boolean):RowRenderInfo { let info:any = { workPackage: workPackage, renderType: 'primary', diff --git a/frontend/app/components/wp-fast-table/builders/modes/hierarchy/single-hierarchy-row-builder.ts b/frontend/app/components/wp-fast-table/builders/modes/hierarchy/single-hierarchy-row-builder.ts index b56da73a7b..68c1e73071 100644 --- a/frontend/app/components/wp-fast-table/builders/modes/hierarchy/single-hierarchy-row-builder.ts +++ b/frontend/app/components/wp-fast-table/builders/modes/hierarchy/single-hierarchy-row-builder.ts @@ -1,5 +1,5 @@ import {Injector} from '@angular/core'; -import {WorkPackageResourceInterface} from '../../../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {States} from '../../../../states.service'; import {WorkPackageChangeset} from '../../../../wp-edit-form/work-package-changeset'; import {collapsedGroupClass, hasChildrenInTable} from '../../../helpers/wp-table-hierarchy-helpers'; @@ -40,7 +40,7 @@ export class SingleHierarchyRowBuilder extends SingleRowBuilder { * Refresh a single row after structural changes. * Remembers and re-adds the hierarchy indicator if neccessary. */ - public refreshRow(workPackage:WorkPackageResourceInterface, changeset:WorkPackageChangeset, jRow:JQuery):JQuery { + public refreshRow(workPackage:WorkPackageResource, changeset:WorkPackageChangeset, jRow:JQuery):JQuery { // Remove any old hierarchy const newRow = super.refreshRow(workPackage, changeset, jRow); newRow.find(`.wp-table--hierarchy-span`).remove(); @@ -52,11 +52,11 @@ export class SingleHierarchyRowBuilder extends SingleRowBuilder { /** * Build the columns on the given empty row */ - public buildEmpty(workPackage:WorkPackageResourceInterface):[HTMLElement, boolean] { + public buildEmpty(workPackage:WorkPackageResource):[HTMLElement, boolean] { let [element, hidden] = super.buildEmpty(workPackage); const state = this.wpTableHierarchies.currentState; - workPackage.ancestors.forEach((ancestor:WorkPackageResourceInterface) => { + workPackage.ancestors.forEach((ancestor:WorkPackageResource) => { element.classList.add(`__hierarchy-group-${ancestor.id}`); if (state.collapsed[ancestor.id]) { @@ -73,7 +73,7 @@ export class SingleHierarchyRowBuilder extends SingleRowBuilder { /** * Append an additional ancestor row that is not yet loaded */ - public buildAncestorRow(ancestor:WorkPackageResourceInterface, + public buildAncestorRow(ancestor:WorkPackageResource, ancestorGroups:string[], index:number):[HTMLElement, boolean] { @@ -89,7 +89,7 @@ export class SingleHierarchyRowBuilder extends SingleRowBuilder { * @param row * @param level */ - private appendHierarchyIndicator(workPackage:WorkPackageResourceInterface, jRow:JQuery, level?:number):void { + private appendHierarchyIndicator(workPackage:WorkPackageResource, jRow:JQuery, level?:number):void { const hierarchyLevel = level === undefined || null ? workPackage.ancestors.length : level; const hierarchyElement = this.buildHierarchyIndicator(workPackage, jRow, hierarchyLevel); @@ -104,7 +104,7 @@ export class SingleHierarchyRowBuilder extends SingleRowBuilder { /** * Build the hierarchy indicator at the given indentation level. */ - private buildHierarchyIndicator(workPackage:WorkPackageResourceInterface, jRow:JQuery | null, level:number):HTMLElement { + private buildHierarchyIndicator(workPackage:WorkPackageResource, jRow:JQuery | null, level:number):HTMLElement { const hierarchyIndicator = document.createElement('span'); const collapsed = this.wpTableHierarchies.collapsed(workPackage.id); const indicatorWidth = 25 + (20 * level) + 'px'; diff --git a/frontend/app/components/wp-fast-table/builders/primary-render-pass.ts b/frontend/app/components/wp-fast-table/builders/primary-render-pass.ts index 452cedf1da..832c8b55ff 100644 --- a/frontend/app/components/wp-fast-table/builders/primary-render-pass.ts +++ b/frontend/app/components/wp-fast-table/builders/primary-render-pass.ts @@ -1,7 +1,7 @@ import {Injector} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; import {timeOutput} from '../../../helpers/debug_output'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {States} from '../../states.service'; import {WorkPackageEditingService} from '../../wp-edit-form/work-package-editing-service'; import {WorkPackageTable} from '../wp-fast-table'; @@ -17,10 +17,10 @@ export interface RowRenderInfo { // Additional classes to be added by any secondary render passes additionalClasses:string[]; // If this row is a work package, contains a reference to the rendered WP - workPackage:WorkPackageResourceInterface | null; + workPackage:WorkPackageResource | null; // If this is an additional row not present, this contains a reference to the WP // it originated from - belongsTo?:WorkPackageResourceInterface; + belongsTo?:WorkPackageResource; // The type of row this was rendered from renderType:RenderedRowType; // Marks if the row is currently hidden to the user @@ -88,7 +88,7 @@ export abstract class PrimaryRenderPass { * Refresh a single row using the render pass it was originally created from. * @param row */ - public refresh(row:RowRenderInfo, workPackage:WorkPackageResourceInterface, body:HTMLElement) { + public refresh(row:RowRenderInfo, workPackage:WorkPackageResource, body:HTMLElement) { let oldRow = jQuery(body).find(`.${row.classIdentifier}`); let replacement:JQuery | null = null; let editing = this.wpEditing.changesetFor(workPackage); @@ -156,7 +156,7 @@ export abstract class PrimaryRenderPass { * @param rowClasses Additional classes to apply to the timeline row for mirroring purposes * @param hidden whether the row was rendered hidden */ - protected appendRow(workPackage:WorkPackageResourceInterface, + protected appendRow(workPackage:WorkPackageResource, row:HTMLElement, additionalClasses:string[] = [], hidden:boolean = false) { diff --git a/frontend/app/components/wp-fast-table/builders/relation-cell-builder.ts b/frontend/app/components/wp-fast-table/builders/relation-cell-builder.ts index 890a04c812..90bc582bd0 100644 --- a/frontend/app/components/wp-fast-table/builders/relation-cell-builder.ts +++ b/frontend/app/components/wp-fast-table/builders/relation-cell-builder.ts @@ -1,10 +1,10 @@ import {Injector} from '@angular/core'; import {States} from '../../states.service'; -import {WorkPackageResourceInterface} from './../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageDisplayFieldService} from './../../wp-display/wp-display-field/wp-display-field.service'; import {tdClassName} from './cell-builder'; import {WorkPackageTableRelationColumnsService} from '../state/wp-table-relation-columns.service'; -import {RelationResourceInterface} from '../../api/api-v3/hal-resources/relation-resource.service'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; import {QueryColumn} from '../../wp-query/query-column'; import {WorkPackageRelationsService} from '../../wp-relations/wp-relations.service'; @@ -22,7 +22,7 @@ export class RelationCellbuilder { constructor(public readonly injector:Injector) { } - public build(workPackage:WorkPackageResourceInterface, column:QueryColumn) { + public build(workPackage:WorkPackageResource, column:QueryColumn) { const td = document.createElement('td'); td.classList.add(tdClassName, relationCellTdClassName, column.id); td.dataset['columnId'] = column.id; @@ -58,7 +58,7 @@ export class RelationCellbuilder { return indicator; } - private renderBadge(relations:RelationResourceInterface[]) { + private renderBadge(relations:RelationResource[]) { const badge = document.createElement('span'); badge.classList.add('wp-table--relation-count'); diff --git a/frontend/app/components/wp-fast-table/builders/relations/relation-row-builder.ts b/frontend/app/components/wp-fast-table/builders/relations/relation-row-builder.ts index 892fefbea8..9114a367cc 100644 --- a/frontend/app/components/wp-fast-table/builders/relations/relation-row-builder.ts +++ b/frontend/app/components/wp-fast-table/builders/relations/relation-row-builder.ts @@ -1,16 +1,13 @@ import {Injector} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; -import {RelationResource} from '../../../api/api-v3/hal-resources/relation-resource.service'; -import { - WorkPackageResource, - WorkPackageResourceInterface -} from '../../../api/api-v3/hal-resources/work-package-resource.service'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; import {States} from '../../../states.service'; import {isRelationColumn, QueryColumn} from '../../../wp-query/query-column'; import {RelationColumnType} from '../../state/wp-table-relation-columns.service'; import {WorkPackageTable} from '../../wp-fast-table'; import {wpCellTdClassName} from '../cell-builder'; import {commonRowClassName, SingleRowBuilder, tableRowClassName} from '../rows/single-row-builder'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; export function relationGroupClass(workPackageId:string) { return `__relations-expanded-from-${workPackageId}`; @@ -40,7 +37,7 @@ export class RelationRowBuilder extends SingleRowBuilder { * @param column * @return {any} */ - public buildCell(workPackage:WorkPackageResourceInterface, column:QueryColumn):HTMLElement|null { + public buildCell(workPackage:WorkPackageResource, column:QueryColumn):HTMLElement|null { // handle relation types if (isRelationColumn(column)) { @@ -53,10 +50,10 @@ export class RelationRowBuilder extends SingleRowBuilder { /** * Build the columns on the given empty row */ - public buildEmptyRelationRow(from:WorkPackageResourceInterface, relation:RelationResource, type:RelationColumnType):[HTMLElement, WorkPackageResourceInterface] { + public buildEmptyRelationRow(from:WorkPackageResource, relation:RelationResource, type:RelationColumnType):[HTMLElement, WorkPackageResource] { const denormalized = relation.denormalized(from); - const to = this.states.workPackages.get(denormalized.targetId).value!; + const to = this.states.workPackages.get(denormalized.targetId).value! as WorkPackageResource; // Let the primary row builder build the row const row = this.createEmptyRelationRow(from, to); @@ -70,7 +67,7 @@ export class RelationRowBuilder extends SingleRowBuilder { * @param workPackage * @returns {any} */ - public createEmptyRelationRow(from:WorkPackageResourceInterface, to:WorkPackageResourceInterface) { + public createEmptyRelationRow(from:WorkPackageResource, to:WorkPackageResource) { const identifier = this.relationClassIdentifier(from, to); let tr = document.createElement('tr'); tr.dataset['workPackageId'] = to.id; @@ -87,7 +84,7 @@ export class RelationRowBuilder extends SingleRowBuilder { return tr; } - public relationClassIdentifier(from:WorkPackageResourceInterface, to:WorkPackageResourceInterface) { + public relationClassIdentifier(from:WorkPackageResource, to:WorkPackageResource) { return relationIdentifier(to.id, from.id); } @@ -97,7 +94,7 @@ export class RelationRowBuilder extends SingleRowBuilder { * @param denormalized * @param type */ - public appendRelationLabel(jRow:JQuery, from:WorkPackageResourceInterface, relation:RelationResource, columnId:string, type:RelationColumnType) { + public appendRelationLabel(jRow:JQuery, from:WorkPackageResource, relation:RelationResource, columnId:string, type:RelationColumnType) { const denormalized = relation.denormalized(from); let typeLabel = ''; diff --git a/frontend/app/components/wp-fast-table/builders/relations/relations-render-pass.ts b/frontend/app/components/wp-fast-table/builders/relations/relations-render-pass.ts index 60f90ff02b..374821e3b9 100644 --- a/frontend/app/components/wp-fast-table/builders/relations/relations-render-pass.ts +++ b/frontend/app/components/wp-fast-table/builders/relations/relations-render-pass.ts @@ -1,6 +1,6 @@ import {Injector} from '@angular/core'; -import {RelationResource} from '../../../api/api-v3/hal-resources/relation-resource.service'; -import {WorkPackageResourceInterface} from '../../../api/api-v3/hal-resources/work-package-resource.service'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageChangeset} from '../../../wp-edit-form/work-package-changeset'; import {WorkPackageRelationsService} from '../../../wp-relations/wp-relations.service'; import {WorkPackageTableColumnsService} from '../../state/wp-table-columns.service'; @@ -104,7 +104,7 @@ export class RelationsRenderPass { } public refreshRelationRow(renderedRow:RelationRenderInfo, - workPackage:WorkPackageResourceInterface, + workPackage:WorkPackageResource, changeset:WorkPackageChangeset, oldRow:JQuery) { const newRow = this.relationRowBuilder.refreshRow(workPackage, changeset, oldRow); diff --git a/frontend/app/components/wp-fast-table/builders/rows/single-row-builder.ts b/frontend/app/components/wp-fast-table/builders/rows/single-row-builder.ts index ccfe390997..93c1fe299b 100644 --- a/frontend/app/components/wp-fast-table/builders/rows/single-row-builder.ts +++ b/frontend/app/components/wp-fast-table/builders/rows/single-row-builder.ts @@ -2,7 +2,7 @@ import {Injector} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; import {locateTableRowByIdentifier} from 'core-components/wp-fast-table/helpers/wp-table-row-helpers'; import {debugLog} from '../../../../helpers/debug_output'; -import {WorkPackageResourceInterface} from '../../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageChangeset} from '../../../wp-edit-form/work-package-changeset'; import {isRelationColumn, QueryColumn} from '../../../wp-query/query-column'; import {WorkPackageTableColumnsService} from '../../state/wp-table-columns.service'; @@ -56,8 +56,7 @@ export class SingleRowBuilder { return this.columns.concat([internalContextMenuColumn]); } - public buildCell(workPackage:WorkPackageResourceInterface, column:QueryColumn):HTMLElement|null { - + public buildCell(workPackage:WorkPackageResource, column:QueryColumn):HTMLElement|null { // handle relation types if (isRelationColumn(column)) { return this.relationCellBuilder.build(workPackage, column); @@ -79,7 +78,7 @@ export class SingleRowBuilder { /** * Build the columns on the given empty row */ - public buildEmpty(workPackage:WorkPackageResourceInterface):[HTMLElement, boolean] { + public buildEmpty(workPackage:WorkPackageResource):[HTMLElement, boolean] { let row = this.createEmptyRow(workPackage); return this.buildEmptyRow(workPackage, row); } @@ -89,7 +88,7 @@ export class SingleRowBuilder { * @param workPackage * @returns {any} */ - public createEmptyRow(workPackage:WorkPackageResourceInterface) { + public createEmptyRow(workPackage:WorkPackageResource) { const identifier = this.classIdentifier(workPackage); let tr = document.createElement('tr'); tr.setAttribute('tabindex', '0'); @@ -106,14 +105,14 @@ export class SingleRowBuilder { return tr; } - public classIdentifier(workPackage:WorkPackageResourceInterface) { + public classIdentifier(workPackage:WorkPackageResource) { return `wp-row-${workPackage.id}`; } /** * Refresh a row that is currently being edited, that is, some edit fields may be open */ - public refreshRow(workPackage:WorkPackageResourceInterface, changeset:WorkPackageChangeset, jRow:JQuery):JQuery { + public refreshRow(workPackage:WorkPackageResource, changeset:WorkPackageChangeset, jRow:JQuery):JQuery { // Detach all current edit cells const cells = jRow.find(`.${wpCellTdClassName}`).detach(); @@ -145,7 +144,7 @@ export class SingleRowBuilder { return changeset && changeset.isOverridden(column.id); } - protected buildEmptyRow(workPackage:WorkPackageResourceInterface, row:HTMLElement):[HTMLElement, boolean] { + protected buildEmptyRow(workPackage:WorkPackageResource, row:HTMLElement):[HTMLElement, boolean] { const changeset = this.workPackageTable.editing.changeset(workPackage.id); let cells:{ [attribute:string]:JQuery } = {}; @@ -160,7 +159,7 @@ export class SingleRowBuilder { this.augmentedColumns.forEach((column:QueryColumn) => { let cell:Element|null; - let oldCell:JQuery | undefined = cells[column.id]; + let oldCell:JQuery|undefined = cells[column.id]; if (oldCell && oldCell.length) { debugLog(`Rendering previous open column ${column.id} on ${workPackage.id}`); diff --git a/frontend/app/components/wp-fast-table/builders/table-action-renderer.ts b/frontend/app/components/wp-fast-table/builders/table-action-renderer.ts index 0ab1df6c24..5d98b482d8 100644 --- a/frontend/app/components/wp-fast-table/builders/table-action-renderer.ts +++ b/frontend/app/components/wp-fast-table/builders/table-action-renderer.ts @@ -1,7 +1,7 @@ import {Injector} from '@angular/core'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; import {wpCellTdClassName} from './cell-builder'; import {OpTableActionsService} from 'core-components/wp-table/table-actions/table-actions.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; export const contextMenuTdClassName = 'wp-table--context-menu-td'; export const contextMenuSpanClassName = 'wp-table--context-menu-span'; @@ -17,7 +17,7 @@ export class TableActionRenderer { constructor(public readonly injector:Injector) { } - public build(workPackage:WorkPackageResourceInterface):HTMLElement { + public build(workPackage:WorkPackageResource):HTMLElement { // Append details button let td = document.createElement('td'); td.classList.add(wpCellTdClassName, contextMenuTdClassName, 'hide-when-print'); diff --git a/frontend/app/components/wp-fast-table/handlers/row/wp-state-links-handler.ts b/frontend/app/components/wp-fast-table/handlers/row/wp-state-links-handler.ts index e466cc066b..aa82b06f68 100644 --- a/frontend/app/components/wp-fast-table/handlers/row/wp-state-links-handler.ts +++ b/frontend/app/components/wp-fast-table/handlers/row/wp-state-links-handler.ts @@ -1,7 +1,7 @@ import {Injector} from '@angular/core'; import {$stateToken} from 'core-app/angular4-transition-utils'; import {WorkPackageTableFocusService} from 'core-components/wp-fast-table/state/wp-table-focus.service'; -import {WorkPackageResource} from '../../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {States} from '../../../states.service'; import {KeepTabService} from '../../../wp-single-view-tabs/keep-tab/keep-tab.service'; import {tableRowClassName} from '../../builders/rows/single-row-builder'; diff --git a/frontend/app/components/wp-fast-table/handlers/state/rows-transformer.ts b/frontend/app/components/wp-fast-table/handlers/state/rows-transformer.ts index be0d0112b4..58e17b5777 100644 --- a/frontend/app/components/wp-fast-table/handlers/state/rows-transformer.ts +++ b/frontend/app/components/wp-fast-table/handlers/state/rows-transformer.ts @@ -1,7 +1,7 @@ import {Injector} from '@angular/core'; import {filter, takeUntil} from 'rxjs/operators'; import {debugLog} from '../../../../helpers/debug_output'; -import {WorkPackageResourceInterface} from '../../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageTable} from '../../wp-fast-table'; import {TableState} from 'core-components/wp-table/table-state/table-state'; import {States} from 'core-components/states.service'; @@ -20,7 +20,7 @@ export class RowsTransformer { .pipe( takeUntil(this.tableState.stopAllSubscriptions) ) - .subscribe((rows:WorkPackageResourceInterface[]) => { + .subscribe((rows:WorkPackageResource[]) => { var t0 = performance.now(); table.initialSetup(rows); @@ -40,7 +40,7 @@ export class RowsTransformer { return; } - this.table.refreshRows(wp); + this.table.refreshRows(wp as WorkPackageResource); }); } } diff --git a/frontend/app/components/wp-fast-table/helpers/wp-table-hierarchy-helpers.ts b/frontend/app/components/wp-fast-table/helpers/wp-table-hierarchy-helpers.ts index 5d89984a05..3a4fd760d4 100644 --- a/frontend/app/components/wp-fast-table/helpers/wp-table-hierarchy-helpers.ts +++ b/frontend/app/components/wp-fast-table/helpers/wp-table-hierarchy-helpers.ts @@ -1,4 +1,4 @@ -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageTable} from '../wp-fast-table'; /** * Returns the collapsed group class for the given ancestor id @@ -23,7 +23,7 @@ export function ancestorClassIdentifier(ancestorId:string) { * Returns whether any of the children of this work package * are visible in the table results. */ -export function hasChildrenInTable(workPackage:WorkPackageResourceInterface, table:WorkPackageTable) { +export function hasChildrenInTable(workPackage:WorkPackageResource, table:WorkPackageTable) { if (workPackage.isLeaf) { return false; // Work Package has no children at all } diff --git a/frontend/app/components/wp-fast-table/state/wp-table-additional-elements.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-additional-elements.service.ts index c03b4cc907..032cde3036 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-additional-elements.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-additional-elements.service.ts @@ -28,11 +28,10 @@ import {opServicesModule} from '../../../angular-modules'; import {States} from '../../states.service'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageTableColumnsService} from './wp-table-columns.service'; -import {RelationResourceInterface} from '../../api/api-v3/hal-resources/relation-resource.service'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; import {IQService} from 'angular'; -import {HalRequestService} from '../../api/api-v3/hal-request/hal-request.service'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; import { RelationsStateValue, @@ -43,6 +42,7 @@ import {WorkPackageNotificationService} from 'core-components/wp-edit/wp-notific import {TableState} from 'core-components/wp-table/table-state/table-state'; import {Inject, Injectable} from '@angular/core'; import {halRequestToken} from 'core-app/angular4-transition-utils'; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; @Injectable() export class WorkPackageTableAdditionalElementsService { @@ -56,7 +56,7 @@ export class WorkPackageTableAdditionalElementsService { readonly wpRelations:WorkPackageRelationsService) { } - public initialize(rows:WorkPackageResourceInterface[]) { + public initialize(rows:WorkPackageResource[]) { // Add relations to the stack Promise.all([ this.requireInvolvedRelations(rows.map(el => el.id)), @@ -101,7 +101,7 @@ export class WorkPackageTableAdditionalElementsService { * @param rows * @return {string[]} */ - private async requireHierarchyElements(rows:WorkPackageResourceInterface[]):Promise { + private async requireHierarchyElements(rows:WorkPackageResource[]):Promise { if (!this.wpTableHierarchies.isEnabled) { return Promise.resolve([]); } @@ -118,7 +118,7 @@ export class WorkPackageTableAdditionalElementsService { private getInvolvedWorkPackages(states:RelationsStateValue[]) { const ids:string[] = []; _.each(states, (relations:RelationsStateValue) => { - _.each(relations, (resource:RelationResourceInterface) => { + _.each(relations, (resource:RelationResource) => { ids.push(resource.ids.from, resource.ids.to); }); }); diff --git a/frontend/app/components/wp-fast-table/state/wp-table-base.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-base.service.ts index ad65853a4e..04df9e8f30 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-base.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-base.service.ts @@ -26,15 +26,14 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {QuerySchemaResourceInterface} from 'core-components/api/api-v3/hal-resources/query-schema-resource.service'; -import {WorkPackageCollectionResource} from 'core-components/api/api-v3/hal-resources/wp-collection-resource.service'; -import {States} from 'core-components/states.service'; import {TableState} from 'core-components/wp-table/table-state/table-state'; import {InputState, State} from 'reactivestates'; -import {Observable} from 'rxjs/Observable'; import {mapTo, take, takeUntil} from 'rxjs/operators'; import {scopedObservable} from '../../../helpers/angular-rx-utils'; -import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service'; +import {Observable} from 'rxjs'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {QuerySchemaResource} from 'core-app/modules/hal/resources/query-schema-resource'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource'; export abstract class WorkPackageTableBaseService { @@ -60,9 +59,9 @@ export abstract class WorkPackageTableBaseService { * and possibly the associated schema. * * @param {QueryResource} query - * @param {QuerySchemaResourceInterface} schema + * @param {QuerySchemaResource} schema */ - public initialize(query:QueryResource, results:WorkPackageCollectionResource, schema?:QuerySchemaResourceInterface) { + public initialize(query:QueryResource, results:WorkPackageCollectionResource, schema?:QuerySchemaResource) { this.state.putValue(this.valueFromQuery(query, results)!); } diff --git a/frontend/app/components/wp-fast-table/state/wp-table-columns.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-columns.service.ts index f6221369bc..ee41214f48 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-columns.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-columns.service.ts @@ -28,7 +28,7 @@ import {WorkPackageQueryStateService, WorkPackageTableBaseService} from './wp-table-base.service'; import {opServicesModule} from '../../../angular-modules'; -import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; import {WorkPackageTableColumns} from '../wp-table-columns'; import {QueryColumn, queryColumnTypes} from '../../wp-query/query-column'; import {InputState} from 'reactivestates'; diff --git a/frontend/app/components/wp-fast-table/state/wp-table-filters.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-filters.service.ts index 00b6a2b4a6..7e3da1859f 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-filters.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-filters.service.ts @@ -26,20 +26,17 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import { - WorkPackageQueryStateService, - WorkPackageTableBaseService -} from './wp-table-base.service'; -import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service'; -import {QuerySchemaResourceInterface} from '../../api/api-v3/hal-resources/query-schema-resource.service'; -import {QueryFilterInstanceResource} from '../../api/api-v3/hal-resources/query-filter-instance-resource.service'; -import {CollectionResource} from '../../api/api-v3/hal-resources/collection-resource.service'; -import {WorkPackageTableFilters} from '../wp-table-filters'; -import {TableState} from 'core-components/wp-table/table-state/table-state'; -import {InputState} from 'reactivestates'; +import {WorkPackageQueryStateService, WorkPackageTableBaseService} from './wp-table-base.service'; import {Injectable} from '@angular/core'; import {opServicesModule} from 'core-app/angular-modules'; import {downgradeInjectable} from '@angular/upgrade/static'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {QuerySchemaResource} from 'core-app/modules/hal/resources/query-schema-resource'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {WorkPackageTableFilters} from '../wp-table-filters'; +import {TableState} from 'core-components/wp-table/table-state/table-state'; +import {InputState} from 'reactivestates'; @Injectable() export class WorkPackageTableFiltersService extends WorkPackageTableBaseService implements WorkPackageQueryStateService { @@ -56,7 +53,7 @@ export class WorkPackageTableFiltersService extends WorkPackageTableBaseService< return undefined; } - public initializeFilters(query:QueryResource, schema:QuerySchemaResourceInterface) { + public initializeFilters(query:QueryResource, schema:QuerySchemaResource) { let filters = _.map(query.filters, filter => filter.$copy()); this.loadCurrentFiltersSchemas(filters).then(() => { diff --git a/frontend/app/components/wp-fast-table/state/wp-table-group-by.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-group-by.service.ts index 8e3cbcce5a..1e22865eb0 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-group-by.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-group-by.service.ts @@ -26,14 +26,14 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service'; -import {QueryGroupByResource} from '../../api/api-v3/hal-resources/query-group-by-resource.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {QueryGroupByResource} from 'core-app/modules/hal/resources/query-group-by-resource'; import {opServicesModule} from '../../../angular-modules'; import {WorkPackageTableGroupBy} from '../wp-table-group-by'; import {WorkPackageQueryStateService, WorkPackageTableBaseService} from './wp-table-base.service'; import {QueryColumn} from '../../wp-query/query-column'; import {InputState} from 'reactivestates'; -import {WorkPackageCollectionResource} from 'core-components/api/api-v3/hal-resources/wp-collection-resource.service'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource'; import {States} from 'core-components/states.service'; import {TableState} from 'core-components/wp-table/table-state/table-state'; import {Injectable} from '@angular/core'; diff --git a/frontend/app/components/wp-fast-table/state/wp-table-hierarchy.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-hierarchy.service.ts index 0800451b16..bda38dc414 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-hierarchy.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-hierarchy.service.ts @@ -1,11 +1,8 @@ -import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; import {WorkPackageQueryStateService, WorkPackageTableBaseService} from './wp-table-base.service'; import {WorkPackageTableHierarchies} from '../wp-table-hierarchies'; import {TableState} from 'core-components/wp-table/table-state/table-state'; import {Injectable} from '@angular/core'; -import {opServicesModule} from 'core-app/angular-modules'; -import {WorkPackageTableColumnsService} from 'core-components/wp-fast-table/state/wp-table-columns.service'; -import {downgradeInjectable} from '@angular/upgrade/static'; @Injectable() export class WorkPackageTableHierarchiesService extends WorkPackageTableBaseService implements WorkPackageQueryStateService { @@ -116,5 +113,3 @@ export class WorkPackageTableHierarchiesService extends WorkPackageTableBaseServ return new WorkPackageTableHierarchies(false); } } - -opServicesModule.service('wpTableHierarchies', downgradeInjectable(WorkPackageTableHierarchiesService)); diff --git a/frontend/app/components/wp-fast-table/state/wp-table-pagination.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-pagination.service.ts index d453ddf309..f7508f3971 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-pagination.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-pagination.service.ts @@ -29,12 +29,12 @@ import {Injectable} from '@angular/core'; import {WorkPackageTableBaseService,} from './wp-table-base.service'; import {opServicesModule} from '../../../angular-modules'; -import {WorkPackageCollectionResource} from '../../api/api-v3/hal-resources/wp-collection-resource.service' -import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource' +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; import {WorkPackageTablePagination} from '../wp-table-pagination'; import {TableState} from 'core-components/wp-table/table-state/table-state'; import {downgradeInjectable} from '@angular/upgrade/static'; -import {PaginationObject} from 'core-components/api/api-v3/hal-resource-dms/query-dm.service'; +import {PaginationObject} from 'core-app/modules/dm-services/query-dm.service'; interface PaginationUpdateObject { page?:number; diff --git a/frontend/app/components/wp-fast-table/state/wp-table-relation-columns.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-relation-columns.service.ts index f17ace5585..e89e2fa825 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-relation-columns.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-relation-columns.service.ts @@ -27,31 +27,28 @@ // ++ import {WorkPackageTableRelationColumns} from '../wp-table-relation-columns'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageTableColumnsService} from './wp-table-columns.service'; import {WorkPackageTableBaseService} from './wp-table-base.service'; -import { - RelationResource, - RelationResourceInterface -} from '../../api/api-v3/hal-resources/relation-resource.service'; import { QueryColumn, queryColumnTypes, RelationQueryColumn, TypeRelationQueryColumn } from '../../wp-query/query-column'; -import {HalRequestService} from '../../api/api-v3/hal-request/hal-request.service'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; import { RelationsStateValue, WorkPackageRelationsService } from '../../wp-relations/wp-relations.service'; import {TableState} from 'core-components/wp-table/table-state/table-state'; -import {QueryResource} from 'core-components/api/api-v3/hal-resources/query-resource.service'; import {Inject, Injectable} from '@angular/core'; import {halRequestToken} from 'core-app/angular4-transition-utils'; import {opServicesModule} from 'core-app/angular-modules'; import {downgradeInjectable} from '@angular/upgrade/static'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; export type RelationColumnType = 'toType' | 'ofType'; @@ -83,7 +80,7 @@ export class WorkPackageTableRelationColumnsService extends WorkPackageTableBase * @param workPackage * @param relation */ - public relationsToExtendFor(workPackage:WorkPackageResourceInterface, + public relationsToExtendFor(workPackage:WorkPackageResource, relations:RelationsStateValue|undefined, eachCallback:(relation:RelationResource, column:QueryColumn, type:RelationColumnType) => void) { // Only if any relation columns or stored expansion state exist @@ -119,7 +116,7 @@ export class WorkPackageTableRelationColumnsService extends WorkPackageTableBase * @param column The relation column to filter for * @return The filtered relations */ - public relationsForColumn(workPackage:WorkPackageResourceInterface, relations:RelationsStateValue|undefined, column:QueryColumn) { + public relationsForColumn(workPackage:WorkPackageResource, relations:RelationsStateValue|undefined, column:QueryColumn) { if (_.isNil(relations)) { return []; } @@ -129,7 +126,7 @@ export class WorkPackageTableRelationColumnsService extends WorkPackageTableBase if (type === 'toType') { const typeHref = (column as TypeRelationQueryColumn).type.href; - return _.filter(relations, (relation:RelationResourceInterface) => { + return _.filter(relations, (relation:RelationResource) => { const denormalized = relation.denormalized(workPackage); const target = this.wpCacheService.state(denormalized.targetId).value; @@ -141,7 +138,7 @@ export class WorkPackageTableRelationColumnsService extends WorkPackageTableBase if (type === 'ofType') { const relationType = (column as RelationQueryColumn).relationType; - return _.filter(relations, (relation:RelationResourceInterface) => { + return _.filter(relations, (relation:RelationResource) => { return relation.denormalized(workPackage).relationType === relationType; }); } diff --git a/frontend/app/components/wp-fast-table/state/wp-table-selection.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-selection.service.ts index ef57e73b8c..c34e76e749 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-selection.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-selection.service.ts @@ -1,13 +1,11 @@ import {WPTableRowSelectionState} from '../wp-table.interfaces'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; import {RenderedRow} from '../builders/primary-render-pass'; import {InputState} from 'reactivestates'; import {TableState} from 'core-components/wp-table/table-state/table-state'; import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; import {Injectable} from '@angular/core'; -import {opServicesModule} from 'core-app/angular-modules'; -import {WorkPackageTableColumnsService} from 'core-components/wp-fast-table/state/wp-table-columns.service'; -import {downgradeInjectable} from '@angular/upgrade/static'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {States} from 'core-components/states.service'; @Injectable() export class WorkPackageTableSelection { @@ -15,6 +13,7 @@ export class WorkPackageTableSelection { public selectionState:InputState; public constructor(readonly tableState:TableState, + readonly states:States, readonly wpCacheService:WorkPackageCacheService) { this.selectionState = tableState.selection; @@ -45,8 +44,9 @@ export class WorkPackageTableSelection { /** * Get the current work package resource form the selection state. */ - public getSelectedWorkPackages():WorkPackageResourceInterface[] { - return this.getSelectedWorkPackageIds().map(id => this.wpCacheService.state(id).value!); + public getSelectedWorkPackages():WorkPackageResource[] { + let wpState = this.states.workPackages; + return this.getSelectedWorkPackageIds().map(id => wpState.get(id).value!); } public getSelectedWorkPackageIds():string[] { @@ -157,5 +157,3 @@ export class WorkPackageTableSelection { }; } } - -opServicesModule.service('wpTableSelection', downgradeInjectable(WorkPackageTableSelection)); diff --git a/frontend/app/components/wp-fast-table/state/wp-table-sort-by.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-sort-by.service.ts index 182af01d1a..56cd368517 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-sort-by.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-sort-by.service.ts @@ -29,20 +29,18 @@ import {States} from 'core-components/states.service'; import {combine} from 'reactivestates'; import {mapTo} from 'rxjs/operators'; -import {opServicesModule} from '../../../angular-modules'; -import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service'; -import { - QUERY_SORT_BY_ASC, - QUERY_SORT_BY_DESC, - QuerySortByResource -} from '../../api/api-v3/hal-resources/query-sort-by-resource.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {WorkPackageTableSortBy} from '../wp-table-sort-by'; import {QueryColumn} from '../../wp-query/query-column'; import {TableState} from 'core-components/wp-table/table-state/table-state'; import {Injectable} from '@angular/core'; import {downgradeInjectable} from '@angular/upgrade/static'; -import {WorkPackageTableSortBy} from '../wp-table-sort-by'; import {WorkPackageQueryStateService, WorkPackageTableBaseService} from './wp-table-base.service'; import {Observable} from 'rxjs'; +import { + QUERY_SORT_BY_ASC, QUERY_SORT_BY_DESC, + QuerySortByResource +} from 'core-app/modules/hal/resources/query-sort-by-resource'; @Injectable() export class WorkPackageTableSortByService extends WorkPackageTableBaseService implements WorkPackageQueryStateService { @@ -146,5 +144,3 @@ export class WorkPackageTableSortByService extends WorkPackageTableBaseService implements WorkPackageQueryStateService { @@ -102,7 +99,7 @@ export class WorkPackageTableTimelineService extends WorkPackageTableBaseService this.state.putValue(currentState); } - public getNormalizedLabels(workPackage:WorkPackageResourceInterface) { + public getNormalizedLabels(workPackage:WorkPackageResource) { let labels:TimelineLabels = _.clone(this.current.defaultLabels); _.each(this.current.labels, (attribute:string | null, positionAsString:string) => { @@ -152,5 +149,3 @@ export class WorkPackageTableTimelineService extends WorkPackageTableBaseService return this.state.value as WorkPackageTableTimelineState; } } - -opServicesModule.service('wpTableTimeline', downgradeInjectable(WorkPackageTableTimelineService)); diff --git a/frontend/app/components/wp-fast-table/wp-fast-table.ts b/frontend/app/components/wp-fast-table/wp-fast-table.ts index e5d0987a07..ae8183d260 100644 --- a/frontend/app/components/wp-fast-table/wp-fast-table.ts +++ b/frontend/app/components/wp-fast-table/wp-fast-table.ts @@ -2,7 +2,7 @@ import {Injector} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; import {TableState} from 'core-components/wp-table/table-state/table-state'; import {debugLog} from '../../helpers/debug_output'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {States} from '../states.service'; import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; @@ -69,9 +69,9 @@ export class WorkPackageTable { * Build the row index and positions from the given set of ordered work packages. * @param rows */ - private buildIndex(rows:WorkPackageResourceInterface[]) { + private buildIndex(rows:WorkPackageResource[]) { this.originalRowIndex = {}; - this.originalRows = rows.map((wp:WorkPackageResourceInterface, i:number) => { + this.originalRows = rows.map((wp:WorkPackageResource, i:number) => { let wpId = wp.id; this.originalRowIndex[wpId] = {object: wp, workPackageId: wpId, position: i}; return wpId; @@ -82,7 +82,7 @@ export class WorkPackageTable { * * @param rows */ - public initialSetup(rows:WorkPackageResourceInterface[]) { + public initialSetup(rows:WorkPackageResource[]) { // Build the row representation this.buildIndex(rows); @@ -124,7 +124,7 @@ export class WorkPackageTable { /** * Redraw single rows for a given work package being updated. */ - public refreshRows(workPackage:WorkPackageResourceInterface) { + public refreshRows(workPackage:WorkPackageResource) { const pass = this.lastRenderPass; if (!pass) { debugLog('Trying to refresh a singular row without a previus render pass.'); diff --git a/frontend/app/components/wp-fast-table/wp-table-columns.ts b/frontend/app/components/wp-fast-table/wp-table-columns.ts index c3cdeec732..174d0550b0 100644 --- a/frontend/app/components/wp-fast-table/wp-table-columns.ts +++ b/frontend/app/components/wp-fast-table/wp-table-columns.ts @@ -26,8 +26,8 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {QueryResource} from '../api/api-v3/hal-resources/query-resource.service'; -import {QuerySchemaResourceInterface} from '../api/api-v3/hal-resources/query-schema-resource.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {QuerySchemaResource} from 'core-app/modules/hal/resources/query-schema-resource'; import {WorkPackageTableBaseState} from './wp-table-base'; import {QueryColumn} from '../wp-query/query-column'; @@ -41,7 +41,7 @@ export class WorkPackageTableColumns extends WorkPackageTableBaseState { @@ -37,7 +37,7 @@ export class WorkPackageTableFilters extends WorkPackageTableBaseState { public current:QuerySortByResource[] = []; diff --git a/frontend/app/components/wp-fast-table/wp-table-timeline.ts b/frontend/app/components/wp-fast-table/wp-table-timeline.ts index acc43acf62..c7ec652d03 100644 --- a/frontend/app/components/wp-fast-table/wp-table-timeline.ts +++ b/frontend/app/components/wp-fast-table/wp-table-timeline.ts @@ -28,16 +28,16 @@ import {WorkPackageTableBaseState} from './wp-table-base'; import { - QueryResourceInterface, TimelineLabels, + QueryResource, TimelineLabels, TimelineZoomLevel -} from '../api/api-v3/hal-resources/query-resource.service'; +} from 'core-app/modules/hal/resources/query-resource'; export class WorkPackageTableTimelineState extends WorkPackageTableBaseState { public visible:boolean; public zoomLevel:TimelineZoomLevel; public labels:TimelineLabels; - constructor(query:QueryResourceInterface) { + constructor(query:QueryResource) { super(); this.visible = query.timelineVisible; this.zoomLevel = query.timelineZoomLevel; diff --git a/frontend/app/components/wp-fast-table/wp-table.interfaces.ts b/frontend/app/components/wp-fast-table/wp-table.interfaces.ts index 06fc4a2936..8097a7bd44 100644 --- a/frontend/app/components/wp-fast-table/wp-table.interfaces.ts +++ b/frontend/app/components/wp-fast-table/wp-table.interfaces.ts @@ -1,17 +1,13 @@ -import { - WorkPackageResource, - WorkPackageResourceInterface -} from '../api/api-v3/hal-resources/work-package-resource.service'; -import {GroupObject} from '../api/api-v3/hal-resources/wp-collection-resource.service'; -import {WorkPackageTable} from './wp-fast-table'; - /** * Interface of a single row instance handled by the table. * May contain references to the current inserted row (if present) * or the group it belonged to when initially rendered. */ +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {GroupObject} from 'core-app/modules/hal/resources/wp-collection-resource'; + export interface WorkPackageTableRow { - object:WorkPackageResourceInterface; + object:WorkPackageResource; workPackageId:string; position:number; element?:HTMLElement; diff --git a/frontend/app/components/wp-field/wp-field.module.ts b/frontend/app/components/wp-field/wp-field.module.ts index 3d92a8b05c..cbc9d8fa45 100644 --- a/frontend/app/components/wp-field/wp-field.module.ts +++ b/frontend/app/components/wp-field/wp-field.module.ts @@ -26,8 +26,8 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {HalResource} from '../api/api-v3/hal-resources/hal-resource.service'; import {Injector} from '@angular/core'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export class Field { public static type:string; diff --git a/frontend/app/components/wp-inline-create/inline-create-row-builder.ts b/frontend/app/components/wp-inline-create/inline-create-row-builder.ts index 1c385b92e6..cd085902f8 100644 --- a/frontend/app/components/wp-inline-create/inline-create-row-builder.ts +++ b/frontend/app/components/wp-inline-create/inline-create-row-builder.ts @@ -1,6 +1,6 @@ import {Injector} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {States} from '../states.service'; import {WorkPackageEditForm} from '../wp-edit-form/work-package-edit-form'; import { @@ -39,7 +39,7 @@ export class InlineCreateRowBuilder extends SingleRowBuilder { }; } - public buildCell(workPackage:WorkPackageResourceInterface, column:QueryColumn):HTMLElement|null { + public buildCell(workPackage:WorkPackageResource, column:QueryColumn):HTMLElement|null { switch (column.id) { case internalContextMenuColumn.id: return this.buildCancelButton(); @@ -48,7 +48,7 @@ export class InlineCreateRowBuilder extends SingleRowBuilder { } } - public buildNew(workPackage:WorkPackageResourceInterface, form:WorkPackageEditForm):[HTMLElement, boolean] { + public buildNew(workPackage:WorkPackageResource, form:WorkPackageEditForm):[HTMLElement, boolean] { // Get any existing edit state for this work package const [row, hidden] = this.buildEmpty(workPackage); @@ -61,7 +61,7 @@ export class InlineCreateRowBuilder extends SingleRowBuilder { * @param workPackage * @returns {any} */ - public createEmptyRow(workPackage:WorkPackageResourceInterface) { + public createEmptyRow(workPackage:WorkPackageResource) { const identifier = this.classIdentifier(workPackage); const tr = document.createElement('tr'); tr.id = rowId(workPackage.id); diff --git a/frontend/app/components/wp-inline-create/wp-inline-create.component.ts b/frontend/app/components/wp-inline-create/wp-inline-create.component.ts index a9aab0a7df..793e9131e2 100644 --- a/frontend/app/components/wp-inline-create/wp-inline-create.component.ts +++ b/frontend/app/components/wp-inline-create/wp-inline-create.component.ts @@ -39,7 +39,7 @@ import { import {AuthorisationService} from 'core-components/common/model-auth/model-auth.service'; import {WorkPackageTableFocusService} from 'core-components/wp-fast-table/state/wp-table-focus.service'; import {filter, takeUntil} from 'rxjs/operators'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; import {TableRowEditContext} from '../wp-edit-form/table-row-edit-context'; import {WorkPackageChangeset} from '../wp-edit-form/work-package-changeset'; @@ -80,7 +80,7 @@ export class WorkPackageInlineCreateComponent implements OnInit, OnChanges, OnDe create: this.I18n.t('js.label_create_work_package') }; - private currentWorkPackage:WorkPackageResourceInterface | null; + private currentWorkPackage:WorkPackageResource | null; private workPackageEditForm:WorkPackageEditForm | undefined; @@ -126,8 +126,10 @@ export class WorkPackageInlineCreateComponent implements OnInit, OnChanges, OnDe // Remove temporary rows on creation of new work package this.wpCreate.onNewWorkPackage() - .takeUntil(componentDestroyed(this)) - .subscribe((wp:WorkPackageResourceInterface) => { + .pipe( + takeUntil(componentDestroyed(this)) + ) + .subscribe((wp:WorkPackageResource) => { if (this.currentWorkPackage && this.currentWorkPackage === wp) { // Add next row this.removeWorkPackageRow(); diff --git a/frontend/app/components/wp-list/wp-list-checksum.service.ts b/frontend/app/components/wp-list/wp-list-checksum.service.ts index e31ab72886..4c77501217 100644 --- a/frontend/app/components/wp-list/wp-list-checksum.service.ts +++ b/frontend/app/components/wp-list/wp-list-checksum.service.ts @@ -26,7 +26,7 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {QueryResource} from '../api/api-v3/hal-resources/query-resource.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; import {WorkPackageTablePagination} from '../wp-fast-table/wp-table-pagination'; import {StateService} from '@uirouter/core'; diff --git a/frontend/app/components/wp-list/wp-list-invalid-query.service.ts b/frontend/app/components/wp-list/wp-list-invalid-query.service.ts index f471d46774..a4570128a5 100644 --- a/frontend/app/components/wp-list/wp-list-invalid-query.service.ts +++ b/frontend/app/components/wp-list/wp-list-invalid-query.service.ts @@ -26,14 +26,14 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {QueryResource} from '../api/api-v3/hal-resources/query-resource.service'; -import {QueryFormResource} from '../api/api-v3/hal-resources/query-form-resource.service'; -import {QuerySortByResource} from '../api/api-v3/hal-resources/query-sort-by-resource.service'; -import {QueryGroupByResource} from '../api/api-v3/hal-resources/query-group-by-resource.service'; -import {SchemaResource} from '../api/api-v3/hal-resources/schema-resource.service'; -import {QueryFilterResource} from '../api/api-v3/hal-resources/query-filter-resource.service'; -import {QueryFilterInstanceResource} from '../api/api-v3/hal-resources/query-filter-instance-resource.service'; -import {QueryFilterInstanceSchemaResource} from '../api/api-v3/hal-resources/query-filter-instance-schema-resource.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {QueryFormResource} from 'core-app/modules/hal/resources/query-form-resource'; +import {QuerySortByResource} from 'core-app/modules/hal/resources/query-sort-by-resource'; +import {QueryGroupByResource} from 'core-app/modules/hal/resources/query-group-by-resource'; +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; +import {QueryFilterResource} from 'core-app/modules/hal/resources/query-filter-resource'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; +import {QueryFilterInstanceSchemaResource} from 'core-app/modules/hal/resources/query-filter-instance-schema-resource'; import {QueryColumn} from '../wp-query/query-column'; import {Inject, Injectable} from '@angular/core'; import { diff --git a/frontend/app/components/wp-list/wp-list.service.ts b/frontend/app/components/wp-list/wp-list.service.ts index 35c1b344e7..3b105d6db3 100644 --- a/frontend/app/components/wp-list/wp-list.service.ts +++ b/frontend/app/components/wp-list/wp-list.service.ts @@ -26,13 +26,11 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {QueryResource} from '../api/api-v3/hal-resources/query-resource.service'; -import {QueryFormResource} from '../api/api-v3/hal-resources/query-form-resource.service'; -import {PaginationObject, QueryDmService} from '../api/api-v3/hal-resource-dms/query-dm.service'; -import {QueryFormDmService} from '../api/api-v3/hal-resource-dms/query-form-dm.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {QueryFormResource} from 'core-app/modules/hal/resources/query-form-resource'; import {States} from '../states.service'; -import {ErrorResource} from '../api/api-v3/hal-resources/error-resource.service'; -import {WorkPackageCollectionResource} from '../api/api-v3/hal-resources/wp-collection-resource.service'; +import {ErrorResource} from 'core-app/modules/hal/resources/error-resource'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource'; import {WorkPackageTablePaginationService} from '../wp-fast-table/state/wp-table-pagination.service'; import {WorkPackagesListInvalidQueryService} from './wp-list-invalid-query.service'; import {WorkPackageStatesInitializationService} from './wp-states-initialization.service'; @@ -44,11 +42,14 @@ import {LoadingIndicatorService} from 'core-components/common/loading-indicator/ import {TableState} from 'core-components/wp-table/table-state/table-state'; import {Inject, Injectable} from '@angular/core'; import { - I18nToken, NotificationsServiceToken, + I18nToken, + NotificationsServiceToken, UrlParamsHelperToken } from 'core-app/angular4-transition-utils'; import {downgradeInjectable} from '@angular/upgrade/static'; import {opServicesModule} from 'core-app/angular-modules'; +import {QueryFormDmService} from 'core-app/modules/dm-services/query-form-dm.service'; +import {PaginationObject, QueryDmService} from 'core-app/modules/dm-services/query-dm.service'; @Injectable() export class WorkPackagesListService { @@ -73,7 +74,7 @@ export class WorkPackagesListService { * Load a query. * The query is either a persisted query, identified by the query_id parameter, or the default query. Both will be modified by the parameters in the query_props parameter. */ - public fromQueryParams(queryParams:any, projectIdentifier ?:string):ng.IPromise { + public fromQueryParams(queryParams:any, projectIdentifier ?:string):Promise { const queryData = this.UrlParamsHelper.buildV3GetQueryFromJsonParams(queryParams.query_props); const wpListPromise = this.QueryDm.find(queryData, queryParams.query_id, projectIdentifier); const promise = this.updateStatesFromQueryOnPromise(wpListPromise); @@ -91,16 +92,15 @@ export class WorkPackagesListService { /** * Load the default query. */ - public loadDefaultQuery(projectIdentifier ?:string):ng.IPromise { + public loadDefaultQuery(projectIdentifier ?:string):Promise { return this.fromQueryParams({}, projectIdentifier); } /** * Reloads the current query and set the pagination to the first page. */ - public reloadQuery(query:QueryResource):ng.IPromise { - let pagination = this.wpTablePagination.paginationObject; - + public reloadQuery(query:QueryResource):Promise { + let pagination = this.getPaginationInfo(); pagination.offset = 1; let wpListPromise = this.QueryDm.reload(query, pagination); @@ -120,7 +120,7 @@ export class WorkPackagesListService { /** * Update the list from an existing query object. */ - public loadResultsList(query:QueryResource, additionalParams:PaginationObject):ng.IPromise { + public loadResultsList(query:QueryResource, additionalParams:PaginationObject):Promise { let wpListPromise = this.QueryDm.loadResults(query, additionalParams); return this.updateStatesFromWPListOnPromise(query, wpListPromise); @@ -130,8 +130,8 @@ export class WorkPackagesListService { * Reload the list of work packages for the current query keeping the * pagination options. */ - public reloadCurrentResultsList():ng.IPromise { - let pagination = this.wpTablePagination.paginationObject; + public reloadCurrentResultsList():Promise { + let pagination = this.getPaginationInfo(); let query = this.currentQuery; return this.loadResultsList(query, pagination); @@ -140,8 +140,8 @@ export class WorkPackagesListService { /** * Reload the first page of work packages for the current query */ - public loadCurrentResultsListFirstPage():ng.IPromise { - let pagination = this.wpTablePagination.paginationObject; + public loadCurrentResultsListFirstPage():Promise { + let pagination = this.getPaginationInfo(); pagination.offset = 1; let query = this.currentQuery; @@ -160,7 +160,7 @@ export class WorkPackagesListService { }); } - public loadForm(query:QueryResource):ng.IPromise { + public loadForm(query:QueryResource):Promise { return this.QueryFormDm.load(query).then((form:QueryFormResource) => { this.wpStatesInitialization.updateStatesFromForm(query, form); @@ -172,7 +172,7 @@ export class WorkPackagesListService { * Persist the current query in the backend. * After the update, the new query is reloaded (e.g. for the work packages) */ - public create(query:QueryResource, name:string):ng.IPromise { + public create(query:QueryResource, name:string):Promise { let form = this.states.query.form.value!; query.name = name; @@ -241,7 +241,7 @@ export class WorkPackagesListService { return promise; } - public toggleStarred(query:QueryResource):ng.IPromise { + public toggleStarred(query:QueryResource):Promise { let promise = this.QueryDm.toggleStarred(query); promise.then((query:QueryResource) => { @@ -255,7 +255,16 @@ export class WorkPackagesListService { return promise; } - private conditionallyLoadForm(promise:ng.IPromise):ng.IPromise { + private getPaginationInfo() { + let pagination = this.wpTablePagination.current; + + return { + pageSize: pagination.perPage, + offset: pagination.page + }; + } + + private conditionallyLoadForm(promise:Promise):Promise { promise.then(query => { let currentForm = this.states.query.form.value; @@ -270,7 +279,7 @@ export class WorkPackagesListService { return promise; } - private updateStatesFromQueryOnPromise(promise:ng.IPromise):ng.IPromise { + private updateStatesFromQueryOnPromise(promise:Promise):Promise { promise .then(query => { this.tableState.ready.doAndTransition('Query loaded', () => { @@ -284,7 +293,7 @@ export class WorkPackagesListService { return promise; } - private updateStatesFromWPListOnPromise(query:QueryResource, promise:ng.IPromise):ng.IPromise { + private updateStatesFromWPListOnPromise(query:QueryResource, promise:Promise):Promise { return promise.then((results) => { this.tableState.ready.doAndTransition('Query loaded', () => { this.wpStatesInitialization.updateTableState(query, results); @@ -338,7 +347,7 @@ export class WorkPackagesListService { }) .catch(reject); }) - .catch(reject); + .catch(reject); }); } diff --git a/frontend/app/components/wp-list/wp-states-initialization.service.ts b/frontend/app/components/wp-list/wp-states-initialization.service.ts index 41152a1457..69a4d1601a 100644 --- a/frontend/app/components/wp-list/wp-states-initialization.service.ts +++ b/frontend/app/components/wp-list/wp-states-initialization.service.ts @@ -6,12 +6,10 @@ import {WorkPackageTableSumService} from '../wp-fast-table/state/wp-table-sum.se import {WorkPackageTableFiltersService} from '../wp-fast-table/state/wp-table-filters.service'; import {WorkPackageTableGroupByService} from '../wp-fast-table/state/wp-table-group-by.service'; import {WorkPackageTableColumnsService} from '../wp-fast-table/state/wp-table-columns.service'; -import {QueryResource} from '../api/api-v3/hal-resources/query-resource.service'; -import {WorkPackageCollectionResource} from '../api/api-v3/hal-resources/wp-collection-resource.service'; -import {SchemaResource} from '../api/api-v3/hal-resources/schema-resource.service'; -import {QueryFormResource} from '../api/api-v3/hal-resources/query-form-resource.service'; -import {QuerySchemaResourceInterface} from '../api/api-v3/hal-resources/query-schema-resource.service'; -import {QueryFilterInstanceSchemaResource} from '../api/api-v3/hal-resources/query-filter-instance-schema-resource.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource'; +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; +import {QueryFormResource} from 'core-app/modules/hal/resources/query-form-resource'; import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; import {WorkPackageTableRelationColumnsService} from '../wp-fast-table/state/wp-table-relation-columns.service'; import {WorkPackagesListChecksumService} from './wp-list-checksum.service'; @@ -21,6 +19,7 @@ import {AuthorisationService} from 'core-components/common/model-auth/model-auth import {TableState} from 'core-components/wp-table/table-state/table-state'; import {Injectable} from '@angular/core'; import {downgradeInjectable} from '@angular/upgrade/static'; +import {QuerySchemaResource} from 'core-app/modules/hal/resources/query-schema-resource'; @Injectable() export class WorkPackageStatesInitializationService { @@ -69,10 +68,10 @@ export class WorkPackageStatesInitializationService { * @param form */ public updateStatesFromForm(query:QueryResource, form:QueryFormResource) { - let schema = form.schema as QuerySchemaResourceInterface; + let schema:QuerySchemaResource = form.schema as any; - _.each(schema.filtersSchemas.elements, (schema:QueryFilterInstanceSchemaResource) => { - this.states.schemas.get(schema.href as string).putValue(schema); + _.each(schema.filtersSchemas.elements, (schema) => { + this.states.schemas.get(schema.$href as string).putValue(schema as any); }); this.wpTableFilters.initializeFilters(query, schema); diff --git a/frontend/app/components/wp-new/wp-create.controller.ts b/frontend/app/components/wp-new/wp-create.controller.ts index 87a801ae73..1c32a6e431 100644 --- a/frontend/app/components/wp-new/wp-create.controller.ts +++ b/frontend/app/components/wp-new/wp-create.controller.ts @@ -31,11 +31,9 @@ import {StateService, Transition} from '@uirouter/core'; import {$stateToken, I18nToken, v3PathToken} from 'core-app/angular4-transition-utils'; import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; -import {takeUntil} from 'rxjs/operators'; -import {RootDmService} from '../api/api-v3/hal-resource-dms/root-dm.service'; -import {RootResource} from '../api/api-v3/hal-resources/root-resource.service'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; import {States} from '../states.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {RootResource} from 'core-app/modules/hal/resources/root-resource'; import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; import {WorkPackageChangeset} from '../wp-edit-form/work-package-changeset'; import {WorkPackageEditingService} from '../wp-edit-form/work-package-editing-service'; @@ -43,11 +41,13 @@ import {WorkPackageFilterValues} from '../wp-edit-form/work-package-filter-value import {WorkPackageNotificationService} from '../wp-edit/wp-notification.service'; import {WorkPackageTableFiltersService} from '../wp-fast-table/state/wp-table-filters.service'; import {WorkPackageCreateService} from './wp-create.service'; +import {takeUntil} from 'rxjs/operators'; +import {RootDmService} from 'core-app/modules/dm-services/root-dm.service'; export class WorkPackageCreateController implements OnInit, OnDestroy { public successState:string; - public newWorkPackage:WorkPackageResourceInterface; - public parentWorkPackage:WorkPackageResourceInterface; + public newWorkPackage:WorkPackageResource; + public parentWorkPackage:WorkPackageResource; public changeset:WorkPackageChangeset; public stateParams = this.$transition.params('to'); @@ -115,7 +115,7 @@ export class WorkPackageCreateController implements OnInit, OnDestroy { } public ngOnDestroy() { - + // Nothing to do } public switchToFullscreen() { @@ -141,7 +141,7 @@ export class WorkPackageCreateController implements OnInit, OnDestroy { return this.wpCreate.createNewTypedWorkPackage(stateParams.projectPath, type).then(changeset => { const filter = new WorkPackageFilterValues(changeset, this.wpTableFilters.current, ['type']); - return filter.applyDefaultsFromFilters().then(() => changeset) as ng.IPromise; + return filter.applyDefaultsFromFilters().then(() => changeset) as Promise; }); } diff --git a/frontend/app/components/wp-new/wp-create.service.ts b/frontend/app/components/wp-new/wp-create.service.ts index 79f12618c5..7529c79147 100644 --- a/frontend/app/components/wp-new/wp-create.service.ts +++ b/frontend/app/components/wp-new/wp-create.service.ts @@ -26,35 +26,31 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {Observable} from 'rxjs/Observable'; -import {Subject} from 'rxjs/Subject'; -import {HalResource} from '../api/api-v3/hal-resources/hal-resource.service'; -import { - WorkPackageResource, - WorkPackageResourceInterface -} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {Injectable, Injector} from '@angular/core'; import {ApiWorkPackagesService} from '../api/api-work-packages/api-work-packages.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; +import {Observable, Subject} from 'rxjs'; import {WorkPackageChangeset} from '../wp-edit-form/work-package-changeset'; -import {Injectable, Injector} from '@angular/core'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; @Injectable() export class WorkPackageCreateService { - protected form:ng.IPromise; + protected form:Promise; // Allow callbacks to happen on newly created work packages - protected newWorkPackageCreatedSubject = new Subject(); + protected newWorkPackageCreatedSubject = new Subject(); constructor(protected injector:Injector, protected wpCacheService:WorkPackageCacheService, protected apiWorkPackages:ApiWorkPackagesService) { } - public newWorkPackageCreated(wp:WorkPackageResourceInterface) { + public newWorkPackageCreated(wp:WorkPackageResource) { this.newWorkPackageCreatedSubject.next(wp); } - public onNewWorkPackage():Observable { + public onNewWorkPackage():Observable { return this.newWorkPackageCreatedSubject.asObservable(); } @@ -101,7 +97,7 @@ export class WorkPackageCreateService { }); } - public getEmptyForm(projectIdentifier:string):ng.IPromise { + public getEmptyForm(projectIdentifier:string):Promise { if (!this.form) { this.form = this.apiWorkPackages.emptyCreateForm({}, projectIdentifier); } diff --git a/frontend/app/components/wp-query-select/wp-query-select-dropdown.component.ts b/frontend/app/components/wp-query-select/wp-query-select-dropdown.component.ts index 0bb866a20f..6eb94a5cef 100644 --- a/frontend/app/components/wp-query-select/wp-query-select-dropdown.component.ts +++ b/frontend/app/components/wp-query-select/wp-query-select-dropdown.component.ts @@ -26,8 +26,7 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {QueryDmService} from '../api/api-v3/hal-resource-dms/query-dm.service'; -import {QueryResource} from '../api/api-v3/hal-resources/query-resource.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; import {States} from '../states.service'; import {WorkPackagesListService} from '../wp-list/wp-list.service'; import {LoadingIndicatorService} from '../common/loading-indicator/loading-indicator.service'; @@ -39,6 +38,7 @@ import { OpContextMenuLocalsToken } from "core-app/angular4-transition-utils"; import {OpContextMenuLocalsMap} from "core-components/op-context-menu/op-context-menu.types"; +import {QueryDmService} from 'core-app/modules/dm-services/query-dm.service'; interface IAutocompleteItem { label:string; diff --git a/frontend/app/components/wp-query/query-column.ts b/frontend/app/components/wp-query/query-column.ts index a21437bd4c..51dbb9313a 100644 --- a/frontend/app/components/wp-query/query-column.ts +++ b/frontend/app/components/wp-query/query-column.ts @@ -1,5 +1,5 @@ -import {HalResource} from '../api/api-v3/hal-resources/hal-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export const queryColumnTypes = { PROPERTY: 'QueryColumn::Property', RELATION_OF_TYPE: 'QueryColumn::RelationOfType', diff --git a/frontend/app/components/wp-query/url-params-helper.ts b/frontend/app/components/wp-query/url-params-helper.ts index 2375060bca..e43cec467e 100644 --- a/frontend/app/components/wp-query/url-params-helper.ts +++ b/frontend/app/components/wp-query/url-params-helper.ts @@ -26,9 +26,9 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {QuerySortByResource} from "../api/api-v3/hal-resources/query-sort-by-resource.service"; -import {QueryResource} from "../api/api-v3/hal-resources/query-resource.service"; import {PathHelperService} from '../common/path-helper/path-helper.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {QuerySortByResource} from 'core-app/modules/hal/resources/query-sort-by-resource'; export class UrlParamsHelperService { diff --git a/frontend/app/components/wp-relations/ng1-wp-relations-wrapper.directive.ts b/frontend/app/components/wp-relations/ng1-wp-relations-wrapper.directive.ts index 75b8e8fdd0..d2ac181504 100644 --- a/frontend/app/components/wp-relations/ng1-wp-relations-wrapper.directive.ts +++ b/frontend/app/components/wp-relations/ng1-wp-relations-wrapper.directive.ts @@ -12,11 +12,11 @@ import { OnInit } from '@angular/core'; import {UpgradeComponent} from '@angular/upgrade/static'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; @Directive({selector: 'ng1-wp-relations-wrapper'}) export class Ng1RelationsDirectiveWrapper extends UpgradeComponent implements OnInit, OnChanges, DoCheck, OnDestroy { - @Input('workPackage') workPackage:WorkPackageResourceInterface; + @Input('workPackage') workPackage:WorkPackageResource; constructor(@Inject(ElementRef) elementRef:ElementRef, @Inject(Injector) injector:Injector) { // We must pass the name of the directive as used by AngularJS to the super diff --git a/frontend/app/components/wp-relations/wp-relation-add-child/wp-relation-add-child.ts b/frontend/app/components/wp-relations/wp-relation-add-child/wp-relation-add-child.ts index 8de74d3815..f33fac0fdb 100644 --- a/frontend/app/components/wp-relations/wp-relation-add-child/wp-relation-add-child.ts +++ b/frontend/app/components/wp-relations/wp-relation-add-child/wp-relation-add-child.ts @@ -1,17 +1,17 @@ -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; import {WorkPackageNotificationService} from '../../wp-edit/wp-notification.service'; import {WorkPackageRelationsHierarchyService} from '../wp-relations-hierarchy/wp-relations-hierarchy.service'; import {WorkPackageRelationsService} from '../wp-relations.service'; import {Component, ElementRef, EventEmitter, Inject, Input, OnInit, Output} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; @Component({ selector: 'wp-relation-add-child', template: require('!!raw-loader!./wp-relation-add-child.html') }) export class WpRelationAddChildComponent implements OnInit { - @Input() public workPackage:WorkPackageResourceInterface; + @Input() public workPackage:WorkPackageResource; @Output() public onAdded = new EventEmitter(); public showRelationsCreateForm: boolean = false; diff --git a/frontend/app/components/wp-relations/wp-relation-row/wp-relation-row.directive.ts b/frontend/app/components/wp-relations/wp-relation-row/wp-relation-row.directive.ts index 48c92ac6db..d2788b0469 100644 --- a/frontend/app/components/wp-relations/wp-relation-row/wp-relation-row.directive.ts +++ b/frontend/app/components/wp-relations/wp-relation-row/wp-relation-row.directive.ts @@ -1,24 +1,21 @@ import {wpDirectivesModule} from '../../../angular-modules'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; import {WorkPackageNotificationService} from '../../wp-edit/wp-notification.service'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; -import { - RelationResource, - RelationResourceInterface -} from '../../api/api-v3/hal-resources/relation-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageRelationsService} from '../wp-relations.service'; import {keyCodes} from 'core-components/common/keyCodes.enum'; import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; class WpRelationRowDirectiveController { - public workPackage:WorkPackageResourceInterface; - public relatedWorkPackage:WorkPackageResourceInterface; + public workPackage:WorkPackageResource; + public relatedWorkPackage:WorkPackageResource; public relationType:string; public groupByWorkPackageType:boolean; public showRelationInfo:boolean = false; public showEditForm:boolean = false; public availableRelationTypes:{ name:string }[]; - public selectedRelationType:RelationResourceInterface; + public selectedRelationType:RelationResource; public userInputs = { newRelationText: '', @@ -35,7 +32,7 @@ class WpRelationRowDirectiveController { } }; - public relation:RelationResourceInterface; + public relation:RelationResource; public text:Object; constructor(protected $scope:ng.IScope, @@ -48,7 +45,7 @@ class WpRelationRowDirectiveController { protected I18n:op.I18n, protected PathHelper:PathHelperService) { - this.relation = this.relatedWorkPackage.relatedBy as RelationResourceInterface; + this.relation = this.relatedWorkPackage.relatedBy as RelationResource; this.text = { cancel: I18n.t('js.button_cancel'), save: I18n.t('js.button_save'), @@ -64,7 +61,7 @@ class WpRelationRowDirectiveController { this.userInputs.newRelationText = this.relation.description || ''; this.availableRelationTypes = RelationResource.LOCALIZED_RELATION_TYPES(false); this.selectedRelationType = _.find(this.availableRelationTypes, - {'name': this.relation.normalizedType(this.workPackage)}) as RelationResourceInterface; + {'name': this.relation.normalizedType(this.workPackage)}) as RelationResource; }; /** @@ -108,7 +105,7 @@ class WpRelationRowDirectiveController { this.wpRelations.updateRelation( this.relation, {description: this.userInputs.newRelationText}) - .then((savedRelation:RelationResourceInterface) => { + .then((savedRelation:RelationResource) => { this.relation = savedRelation; this.relatedWorkPackage.relatedBy = savedRelation; this.userInputs.showDescriptionEditForm = false; @@ -138,14 +135,14 @@ class WpRelationRowDirectiveController { this.relatedWorkPackage, this.relation, this.selectedRelationType.name) - .then((savedRelation:RelationResourceInterface) => { + .then((savedRelation:RelationResource) => { this.wpNotificationsService.showSave(this.relatedWorkPackage); this.relatedWorkPackage.relatedBy = savedRelation; this.relation = savedRelation; this.userInputs.showRelationTypesForm = false; }) - .catch((error) => this.wpNotificationsService.handleErrorResponse(error, this.workPackage)); + .catch((error:any) => this.wpNotificationsService.handleErrorResponse(error, this.workPackage)); } public toggleUserDescriptionForm() { diff --git a/frontend/app/components/wp-relations/wp-relations-create/ng1-wp-relations-create.directive.ts b/frontend/app/components/wp-relations/wp-relations-create/ng1-wp-relations-create.directive.ts index 029efa125e..277536bdaa 100644 --- a/frontend/app/components/wp-relations/wp-relations-create/ng1-wp-relations-create.directive.ts +++ b/frontend/app/components/wp-relations/wp-relations-create/ng1-wp-relations-create.directive.ts @@ -12,11 +12,11 @@ import { OnInit } from '@angular/core'; import {UpgradeComponent} from '@angular/upgrade/static'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; @Directive({selector: 'ng1-wp-relations-create'}) export class Ng1RelationsCreateWrapper extends UpgradeComponent implements OnInit, OnChanges, DoCheck, OnDestroy { - @Input('workPackage') workPackage:WorkPackageResourceInterface; + @Input('workPackage') workPackage:WorkPackageResource; @Input('fixedRelationType') fixedRelationType:string; @Input('externalFormToggle') externalFormToggle:boolean; diff --git a/frontend/app/components/wp-relations/wp-relations-create/wp-relations-autocomplete/wp-relations-autocomplete.directive.ts b/frontend/app/components/wp-relations/wp-relations-create/wp-relations-autocomplete/wp-relations-autocomplete.directive.ts index 8b23e1a0b5..fa843f34c3 100644 --- a/frontend/app/components/wp-relations/wp-relations-create/wp-relations-autocomplete/wp-relations-autocomplete.directive.ts +++ b/frontend/app/components/wp-relations/wp-relations-create/wp-relations-autocomplete/wp-relations-autocomplete.directive.ts @@ -27,9 +27,9 @@ //++ import {wpDirectivesModule} from '../../../../angular-modules'; -import {CollectionResource} from '../../../api/api-v3/hal-resources/collection-resource.service'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; import {LoadingIndicatorService} from '../../../common/loading-indicator/loading-indicator.service'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; function wpRelationsAutocompleteDirective( $q:ng.IQService, @@ -54,7 +54,7 @@ function wpRelationsAutocompleteDirective( scope.options = []; scope.relatedWps = []; - let input = jQuery('.wp-relations--autocomplete') + let input = jQuery('.wp-relations--autocomplete'); let selected = false; input.autocomplete({ @@ -78,7 +78,7 @@ function wpRelationsAutocompleteDirective( minLength: 0 }).focus(() => !selected && input.autocomplete('search', input.val())); - function getIdentifier(workPackage:WorkPackageResourceInterface):string { + function getIdentifier(workPackage:WorkPackageResource):string { if (workPackage) { return `#${workPackage.id} - ${workPackage.subject}`; } else { @@ -86,7 +86,7 @@ function wpRelationsAutocompleteDirective( } } - async function autocompleteWorkPackages(query:string):Promise { + async function autocompleteWorkPackages(query:string):Promise { element.find('.ui-autocomplete--loading').show(); return scope.workPackage.available_relation_candidates.$link.$fetch({ query: query, diff --git a/frontend/app/components/wp-relations/wp-relations-create/wp-relations-autocomplete/wp-relations-autocomplete.upgraded.component.ts b/frontend/app/components/wp-relations/wp-relations-create/wp-relations-autocomplete/wp-relations-autocomplete.upgraded.component.ts index 2b9bd5871b..01fb36dfcd 100644 --- a/frontend/app/components/wp-relations/wp-relations-create/wp-relations-autocomplete/wp-relations-autocomplete.upgraded.component.ts +++ b/frontend/app/components/wp-relations/wp-relations-create/wp-relations-autocomplete/wp-relations-autocomplete.upgraded.component.ts @@ -26,19 +26,19 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {CollectionResource} from '../../../api/api-v3/hal-resources/collection-resource.service'; -import {LoadingIndicatorService} from '../../../common/loading-indicator/loading-indicator.service'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; import {Component, ElementRef, EventEmitter, Inject, Input, OnInit, Output} from '@angular/core'; import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; import {I18nToken} from 'core-app/angular4-transition-utils'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {LoadingIndicatorService} from 'core-components/common/loading-indicator/loading-indicator.service'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; @Component({ selector: 'wp-relations-autocomplete-upgraded', template: require('!!raw-loader!./wp-relations-autocomplete.upgraded.html') }) export class WpRelationsAutocompleteComponent implements OnInit { - @Input() workPackage:WorkPackageResourceInterface; + @Input() workPackage:WorkPackageResource; @Input() loadingPromiseName:string; @Input() selectedRelationType:string; @Input() filterCandidatesFor:string; @@ -89,7 +89,7 @@ export class WpRelationsAutocompleteComponent implements OnInit { setTimeout(() => input.focus(), 20); } - private getIdentifier(workPackage:WorkPackageResourceInterface):string { + private getIdentifier(workPackage:WorkPackageResource):string { if (workPackage) { return `#${workPackage.id} - ${workPackage.subject}`; } else { @@ -97,7 +97,7 @@ export class WpRelationsAutocompleteComponent implements OnInit { } } - private async autocompleteWorkPackages(query:string):Promise { + private async autocompleteWorkPackages(query:string):Promise { this.$element.find('.ui-autocomplete--loading').show(); return this.workPackage.available_relation_candidates.$link.$fetch({ diff --git a/frontend/app/components/wp-relations/wp-relations-create/wp-relations-create.directive.ts b/frontend/app/components/wp-relations/wp-relations-create/wp-relations-create.directive.ts index 943b6df6a7..b58747d9bc 100644 --- a/frontend/app/components/wp-relations/wp-relations-create/wp-relations-create.directive.ts +++ b/frontend/app/components/wp-relations/wp-relations-create/wp-relations-create.directive.ts @@ -1,6 +1,6 @@ import {wpDirectivesModule} from '../../../angular-modules'; -import {RelationResource} from '../../api/api-v3/hal-resources/relation-resource.service'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; import {WorkPackageNotificationService} from '../../wp-edit/wp-notification.service'; import {WorkPackageRelationsHierarchyService} from '../wp-relations-hierarchy/wp-relations-hierarchy.service'; @@ -8,11 +8,11 @@ import {WorkPackageRelationsService} from '../wp-relations.service'; export class WorkPackageRelationsCreateController { - public showRelationsCreateForm: boolean = false; - public workPackage:WorkPackageResourceInterface; + public showRelationsCreateForm:boolean = false; + public workPackage:WorkPackageResource; public selectedRelationType:string = RelationResource.DEFAULT(); public selectedWpId:string; - public externalFormToggle: boolean; + public externalFormToggle:boolean; public fixedRelationType:string; public relationTypes = RelationResource.LOCALIZED_RELATION_TYPES(false); @@ -47,23 +47,28 @@ export class WorkPackageRelationsCreateController { public createRelation() { - if (!this.selectedRelationType || ! this.selectedWpId) { + if (!this.selectedRelationType || !this.selectedWpId) { return; } this.isDisabled = true; - this.createCommonRelation().finally(() => { - this.isDisabled = false; - }); + this.createCommonRelation() + .catch(() => this.isDisabled = false) + .then(() => this.isDisabled = false); } protected createCommonRelation() { - return this.wpRelations.addCommonRelation(this.workPackage, this.selectedRelationType, this.selectedWpId) + return this.wpRelations.addCommonRelation(this.workPackage, + this.selectedRelationType, + this.selectedWpId) .then(relation => { this.wpNotificationsService.showSave(this.workPackage); + this.toggleRelationsCreateForm(); }) - .catch(err => this.wpNotificationsService.handleErrorResponse(err, this.workPackage)) - .finally(() => this.toggleRelationsCreateForm()); + .catch(err => { + this.wpNotificationsService.handleErrorResponse(err, this.workPackage); + this.toggleRelationsCreateForm(); + }); } public toggleRelationsCreateForm() { diff --git a/frontend/app/components/wp-relations/wp-relations-group/wp-relations-group.directive.ts b/frontend/app/components/wp-relations/wp-relations-group/wp-relations-group.directive.ts index fe8e0d78b2..67aff47f41 100644 --- a/frontend/app/components/wp-relations/wp-relations-group/wp-relations-group.directive.ts +++ b/frontend/app/components/wp-relations/wp-relations-group/wp-relations-group.directive.ts @@ -27,13 +27,13 @@ //++ import {wpDirectivesModule} from '../../../angular-modules'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageRelationsController} from '../wp-relations.directive'; export class WorkPackageRelationsGroupController { - public relatedWorkPackages:Array; - public workPackage:WorkPackageResourceInterface; + public relatedWorkPackages:Array; + public workPackage:WorkPackageResource; public header:string; public firstGroup:boolean; public groupByWorkPackageType:boolean; diff --git a/frontend/app/components/wp-relations/wp-relations-hierarchy-row/wp-relations-hierarchy-row.directive.ts b/frontend/app/components/wp-relations/wp-relations-hierarchy-row/wp-relations-hierarchy-row.directive.ts index bea5600f8c..6c1a7ddaf9 100644 --- a/frontend/app/components/wp-relations/wp-relations-hierarchy-row/wp-relations-hierarchy-row.directive.ts +++ b/frontend/app/components/wp-relations/wp-relations-hierarchy-row/wp-relations-hierarchy-row.directive.ts @@ -1,4 +1,4 @@ -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {wpDirectivesModule} from '../../../angular-modules'; import {WorkPackageRelationsHierarchyService} from '../wp-relations-hierarchy/wp-relations-hierarchy.service'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; @@ -7,8 +7,8 @@ import {scopedObservable} from '../../../helpers/angular-rx-utils'; import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; class WpRelationsHierarchyRowDirectiveController { - public workPackage:WorkPackageResourceInterface; - public relatedWorkPackage:WorkPackageResourceInterface; + public workPackage:WorkPackageResource; + public relatedWorkPackage:WorkPackageResource; public relationType:any; public showEditForm:boolean = false; public workPackagePath = this.PathHelper.workPackagePath.bind(this.PathHelper); diff --git a/frontend/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.directive.ts b/frontend/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.directive.ts index e1723676a2..ff7722f701 100644 --- a/frontend/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.directive.ts +++ b/frontend/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.directive.ts @@ -26,25 +26,23 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {wpDirectivesModule} from "../../../angular-modules"; -import {WorkPackageResourceInterface} from "../../api/api-v3/hal-resources/work-package-resource.service"; import {WorkPackageCacheService} from "../../work-packages/work-package-cache.service"; import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; import {OpUnlinkTableAction} from 'core-components/wp-table/table-actions/actions/unlink-table-action'; import {WorkPackageRelationsHierarchyService} from 'core-components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.service'; import {Component, Inject, Input, OnDestroy, OnInit, ViewChild} from '@angular/core'; import {WorkPackageEmbeddedTableComponent} from 'core-components/wp-table/embedded/wp-embedded-table.component'; -import {downgradeComponent} from '@angular/upgrade/static'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {I18nToken} from 'core-app/angular4-transition-utils'; import {take} from 'rxjs/operators'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; @Component({ selector: 'wp-relations-hierarchy', template: require('!!raw-loader!./wp-relations-hierarchy.template.html') }) export class WorkPackageRelationsHierarchyComponent implements OnInit, OnDestroy { - @Input() public workPackage:WorkPackageResourceInterface; + @Input() public workPackage:WorkPackageResource; @Input() public relationType:string; @ViewChild('childrenEmbeddedTable') private childrenEmbeddedTable:WorkPackageEmbeddedTableComponent; @@ -60,7 +58,7 @@ export class WorkPackageRelationsHierarchyComponent implements OnInit, OnDestroy OpUnlinkTableAction.factoryFor( 'remove-child-action', this.I18n.t('js.relation_buttons.remove_child'), - (child:WorkPackageResourceInterface) => { + (child:WorkPackageResource) => { this.childrenEmbeddedTable.loadingIndicator = this.wpRelationsHierarchyService .removeChild(child) .then(() => this.refreshTable()); @@ -92,7 +90,7 @@ export class WorkPackageRelationsHierarchyComponent implements OnInit, OnDestroy this.wpCacheService.loadWorkPackage(this.workPackage.id).values$() .takeUntil(componentDestroyed(this)) - .subscribe((wp:WorkPackageResourceInterface) => { + .subscribe((wp:WorkPackageResource) => { this.workPackage = wp; let toLoad:string[] = []; @@ -104,7 +102,7 @@ export class WorkPackageRelationsHierarchyComponent implements OnInit, OnDestroy .pipe( take(1) ) - .subscribe((parent:WorkPackageResourceInterface) => { + .subscribe((parent:WorkPackageResource) => { this.workPackage.parent = parent; }); } @@ -125,7 +123,3 @@ export class WorkPackageRelationsHierarchyComponent implements OnInit, OnDestroy this.childrenEmbeddedTable.refresh(); } } - -wpDirectivesModule - .directive('wpRelationsHierarchy', - downgradeComponent({component: WorkPackageRelationsHierarchyComponent})); diff --git a/frontend/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.service.ts b/frontend/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.service.ts index b8cf206d2b..93d8c7c563 100644 --- a/frontend/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.service.ts +++ b/frontend/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.service.ts @@ -28,7 +28,7 @@ import {wpDirectivesModule} from '../../../angular-modules'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageNotificationService} from 'core-components/wp-edit/wp-notification.service'; import {States} from '../../states.service'; import {WorkPackageTableRefreshService} from '../../wp-table/wp-table-refresh-request.service'; @@ -46,7 +46,7 @@ export class WorkPackageRelationsHierarchyService { } - public changeParent(workPackage:WorkPackageResourceInterface, parentId:string | null) { + public changeParent(workPackage:WorkPackageResource, parentId:string | null) { let payload:any = { lockVersion: workPackage.lockVersion }; @@ -67,7 +67,7 @@ export class WorkPackageRelationsHierarchyService { return workPackage .changeParent(payload) - .then((wp:WorkPackageResourceInterface) => { + .then((wp:WorkPackageResource) => { this.wpCacheService.updateWorkPackage(wp); this.wpNotificationsService.showSave(wp); this.wpTableRefresh.request(`Changed parent of ${workPackage.id} to ${parentId}`, true); @@ -79,15 +79,15 @@ export class WorkPackageRelationsHierarchyService { }); } - public removeParent(workPackage:WorkPackageResourceInterface) { + public removeParent(workPackage:WorkPackageResource) { return this.changeParent(workPackage, null); } - public addExistingChildWp(workPackage:WorkPackageResourceInterface, childWpId:string):ng.IPromise { - const deferred = this.$q.defer(); + public addExistingChildWp(workPackage:WorkPackageResource, childWpId:string):Promise { + const deferred = this.$q.defer(); const state = this.wpCacheService.loadWorkPackage(childWpId); - state.valuesPromise().then((wpToBecomeChild:WorkPackageResourceInterface|undefined) => { + state.valuesPromise().then((wpToBecomeChild:WorkPackageResource|undefined) => { this.wpTableRefresh.request(`Added new child to ${workPackage.id}`, true); this.changeParent(wpToBecomeChild!, workPackage.id).then(wp => deferred.resolve(wp)); }); @@ -95,7 +95,7 @@ export class WorkPackageRelationsHierarchyService { return deferred.promise; } - public addNewChildWp(workPackage:WorkPackageResourceInterface) { + public addNewChildWp(workPackage:WorkPackageResource) { workPackage.project.$load() .then(() => { const args = [ @@ -113,7 +113,7 @@ export class WorkPackageRelationsHierarchyService { }); } - public removeChild(childWorkPackage:WorkPackageResourceInterface) { + public removeChild(childWorkPackage:WorkPackageResource) { return childWorkPackage.$load().then(() => { return childWorkPackage.changeParent({ _links: { diff --git a/frontend/app/components/wp-relations/wp-relations-parent/wp-relations-parent.component.ts b/frontend/app/components/wp-relations/wp-relations-parent/wp-relations-parent.component.ts index b7e15a4995..c1d6141192 100644 --- a/frontend/app/components/wp-relations/wp-relations-parent/wp-relations-parent.component.ts +++ b/frontend/app/components/wp-relations/wp-relations-parent/wp-relations-parent.component.ts @@ -1,4 +1,3 @@ -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; import {WorkPackageRelationsHierarchyService} from '../wp-relations-hierarchy/wp-relations-hierarchy.service'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; import {WorkPackageNotificationService} from '../../wp-edit/wp-notification.service'; @@ -6,13 +5,14 @@ import {PathHelperService} from 'core-components/common/path-helper/path-helper. import {Component, ElementRef, Inject, Input, OnDestroy, OnInit} from '@angular/core'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {I18nToken} from 'core-app/angular4-transition-utils'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; @Component({ selector: 'wp-relation-parent', template: require('!!raw-loader!./wp-relations-parent.html') }) export class WpRelationParentComponent implements OnInit, OnDestroy { - @Input() public workPackage:WorkPackageResourceInterface; + @Input() public workPackage:WorkPackageResource; public showEditForm:boolean = false; public canModifyHierarchy:boolean = false; public selectedWpId:string|null = null; @@ -62,7 +62,7 @@ export class WpRelationParentComponent implements OnInit, OnDestroy { this.isSaving = true; this.wpRelationsHierarchyService.changeParent(this.workPackage, newParentId) - .then((updatedWp:WorkPackageResourceInterface) => { + .then((updatedWp:WorkPackageResource) => { setTimeout(() => angular.element('#hierarchy--parent').focus()); }) .catch((err:any) => { diff --git a/frontend/app/components/wp-relations/wp-relations.directive.ts b/frontend/app/components/wp-relations/wp-relations.directive.ts index 10e2d14b26..60c2c9ce78 100644 --- a/frontend/app/components/wp-relations/wp-relations.directive.ts +++ b/frontend/app/components/wp-relations/wp-relations.directive.ts @@ -32,8 +32,8 @@ import {zip} from 'rxjs/observable/zip'; import {take} from 'rxjs/operators'; import {wpDirectivesModule} from '../../angular-modules'; import {scopedObservable} from '../../helpers/angular-rx-utils'; -import {RelationResourceInterface} from '../api/api-v3/hal-resources/relation-resource.service'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; import {RelatedWorkPackagesGroup} from './wp-relations.interfaces'; import {RelationsStateValue, WorkPackageRelationsService} from './wp-relations.service'; @@ -42,16 +42,16 @@ import {RelationsStateValue, WorkPackageRelationsService} from './wp-relations.s export class WorkPackageRelationsController { public relationGroups:RelatedWorkPackagesGroup; public relationsPresent:boolean = false; - public workPackage:WorkPackageResourceInterface; + public workPackage:WorkPackageResource; public canAddRelation:boolean; // By default, group by relation type public groupByWorkPackageType = false; - public currentRelations:WorkPackageResourceInterface[] = []; public text = { relations_header: this.I18n.t('js.work_packages.tabs.relations') }; + public currentRelations:WorkPackageResource[] = []; constructor(protected $scope:ng.IScope, protected $q:ng.IQService, @@ -75,20 +75,20 @@ export class WorkPackageRelationsController { // Listen for changes to this WP. scopedObservable(this.$scope, this.wpCacheService.loadWorkPackage(this.workPackage.id).values$()) - .subscribe((wp:WorkPackageResourceInterface) => { + .subscribe((wp:WorkPackageResource) => { this.workPackage = wp; }); } - private getRelatedWorkPackages(workPackageIds:string[]):Observable { - let observablesToGetZipped:Observable[] = workPackageIds.map(wpId => { + private getRelatedWorkPackages(workPackageIds:string[]):Observable { + let observablesToGetZipped:Observable[] = workPackageIds.map(wpId => { return scopedObservable(this.$scope, this.wpCacheService.loadWorkPackage(wpId).values$()); }); return zip(...observablesToGetZipped); } - protected getRelatedWorkPackageId(relation:RelationResourceInterface):string { + protected getRelatedWorkPackageId(relation:RelationResource):string { const involved = relation.ids; return (relation.to.href === this.workPackage.href) ? involved.from : involved.to; } @@ -104,11 +104,11 @@ export class WorkPackageRelationsController { } this.relationGroups = _.groupBy(this.currentRelations, - (wp:WorkPackageResourceInterface) => { + (wp:WorkPackageResource) => { if (this.groupByWorkPackageType) { return wp.type.name; } else { - var normalizedType = (wp.relatedBy as RelationResourceInterface).normalizedType(this.workPackage); + var normalizedType = (wp.relatedBy as RelationResource).normalizedType(this.workPackage); return this.I18n.t('js.relation_labels.' + normalizedType); } }); @@ -124,7 +124,7 @@ export class WorkPackageRelationsController { return this.buildRelationGroups(); } - _.each(stateValues, (relation:RelationResourceInterface) => { + _.each(stateValues, (relation:RelationResource) => { const relatedWpId = this.getRelatedWorkPackageId(relation); relatedWpIds.push(relatedWpId); relations[relatedWpId] = relation; @@ -134,8 +134,8 @@ export class WorkPackageRelationsController { .pipe( take(1) ) - .subscribe((relatedWorkPackages:WorkPackageResourceInterface[]) => { - this.currentRelations = relatedWorkPackages.map((wp:WorkPackageResourceInterface) => { + .subscribe((relatedWorkPackages:WorkPackageResource[]) => { + this.currentRelations = relatedWorkPackages.map((wp:WorkPackageResource) => { wp.relatedBy = relations[wp.id]; return wp; }); diff --git a/frontend/app/components/wp-relations/wp-relations.interfaces.ts b/frontend/app/components/wp-relations/wp-relations.interfaces.ts index 04a7e749f8..0f8a66e9a8 100644 --- a/frontend/app/components/wp-relations/wp-relations.interfaces.ts +++ b/frontend/app/components/wp-relations/wp-relations.interfaces.ts @@ -1,5 +1,5 @@ -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; -import {RelationResourceInterface} from '../api/api-v3/hal-resources/relation-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; export interface RelatedWorkPackagesGroup { [key: string] : any; diff --git a/frontend/app/components/wp-relations/wp-relations.service.ts b/frontend/app/components/wp-relations/wp-relations.service.ts index 1eafb88420..edd2c96a3f 100644 --- a/frontend/app/components/wp-relations/wp-relations.service.ts +++ b/frontend/app/components/wp-relations/wp-relations.service.ts @@ -1,15 +1,12 @@ import {multiInput, StatesGroup} from 'reactivestates'; -import { - RelationResource, - RelationResourceInterface -} from '../api/api-v3/hal-resources/relation-resource.service'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; -import {RelationsDmService} from '../api/api-v3/hal-resource-dms/relations-dm.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageTableRefreshService} from '../wp-table/wp-table-refresh-request.service'; import {opServicesModule} from '../../angular-modules'; import {StateCacheService} from '../states/state-cache.service'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; +import {RelationsDmService} from 'core-app/modules/dm-services/relations-dm.service'; -export type RelationsStateValue = { [relationId:number]:RelationResourceInterface }; +export type RelationsStateValue = { [relationId:number]:RelationResource }; class RelationStateGroup extends StatesGroup { name = 'WP-Relations'; @@ -60,7 +57,7 @@ export class WorkPackageRelationsService extends StateCacheService { + .then((elements:RelationResource[]) => { this.clearSome(...ids); this.accumulateRelationsFromInvolved(ids, elements); deferred.resolve(); @@ -72,7 +69,7 @@ export class WorkPackageRelationsService extends StateCacheService { this.removeFromStates(relation); this.wpTableRefresh.request( @@ -85,7 +82,7 @@ export class WorkPackageRelationsService extends StateCacheService { + .then((savedRelation:RelationResource) => { this.insertIntoStates(savedRelation); this.wpTableRefresh.request( `Updating relation (${relation.ids.from} to ${relation.ids.to})`, @@ -109,7 +106,7 @@ export class WorkPackageRelationsService extends StateCacheService { + return workPackage.addRelation(params).then((relation:RelationResource) => { this.insertIntoStates(relation); this.wpTableRefresh.request( `Adding relation (${relation.ids.from} to ${relation.ids.to})`, @@ -134,7 +131,7 @@ export class WorkPackageRelationsService extends StateCacheService { this.multiState.get(wpId).doModify((value:RelationsStateValue) => { value[relation.id] = relation; @@ -151,7 +148,7 @@ export class WorkPackageRelationsService extends StateCacheService { this.multiState.get(wpId).doModify((value:RelationsStateValue) => { delete value[relation.id]; @@ -167,7 +164,7 @@ export class WorkPackageRelationsService extends StateCacheService r.id); @@ -181,7 +178,7 @@ export class WorkPackageRelationsService extends StateCacheService { const relevant = relations.filter(r => r.isInvolved(id)); this.updateRelationsStateTo(id, relevant); diff --git a/frontend/app/components/wp-relations/wp-single-relation.directive.ts b/frontend/app/components/wp-relations/wp-single-relation.directive.ts index 24408175ae..94989be9b3 100644 --- a/frontend/app/components/wp-relations/wp-single-relation.directive.ts +++ b/frontend/app/components/wp-relations/wp-single-relation.directive.ts @@ -27,8 +27,8 @@ //++ import {wpDirectivesModule} from '../../angular-modules'; -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; /** * Contains methods and attributes shared * between common relations and parent-child relations @@ -39,7 +39,7 @@ export class WorkPackageSingleRelationController { constructor(protected PathHelper:PathHelperService) { } - public getFullIdentifier(workPackage:WorkPackageResourceInterface, hideType?:boolean) { + public getFullIdentifier(workPackage:WorkPackageResource, hideType?:boolean) { if (hideType) { return workPackage.subject; } diff --git a/frontend/app/components/wp-single-view-tabs/activity-panel/activity-base.controller.ts b/frontend/app/components/wp-single-view-tabs/activity-panel/activity-base.controller.ts index d71ebe1096..5ca1db15ef 100644 --- a/frontend/app/components/wp-single-view-tabs/activity-panel/activity-base.controller.ts +++ b/frontend/app/components/wp-single-view-tabs/activity-panel/activity-base.controller.ts @@ -27,16 +27,16 @@ // ++ import {OnDestroy, OnInit} from '@angular/core'; -import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; import {ActivityEntryInfo} from 'core-components/wp-single-view-tabs/activity-panel/activity-entry-info'; import {WorkPackagesActivityService} from 'core-components/wp-single-view-tabs/activity-panel/wp-activity.service'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {takeUntil} from 'rxjs/operators'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; export class ActivityPanelBaseController implements OnInit, OnDestroy { - public workPackage:WorkPackageResourceInterface; + public workPackage:WorkPackageResource; public workPackageId:string; // All activities retrieved for the work package @@ -69,7 +69,7 @@ export class ActivityPanelBaseController implements OnInit, OnDestroy { .pipe( takeUntil(componentDestroyed(this)) ) - .subscribe((wp:WorkPackageResourceInterface) => { + .subscribe((wp:WorkPackageResource) => { this.workPackage = wp; this.wpActivity.aggregateActivities(this.workPackage).then((activities:any) => { this.updateActivities(activities); diff --git a/frontend/app/components/wp-single-view-tabs/activity-panel/activity-on-overview.component.ts b/frontend/app/components/wp-single-view-tabs/activity-panel/activity-on-overview.component.ts index dba193f1e9..6d7e2edd6b 100644 --- a/frontend/app/components/wp-single-view-tabs/activity-panel/activity-on-overview.component.ts +++ b/frontend/app/components/wp-single-view-tabs/activity-panel/activity-on-overview.component.ts @@ -26,13 +26,13 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; import {ActivityPanelBaseController} from 'core-components/wp-single-view-tabs/activity-panel/activity-base.controller'; import {Component, Inject, Input} from '@angular/core'; import {WorkPackagesActivityService} from 'core-components/wp-single-view-tabs/activity-panel/wp-activity.service'; import {I18nToken} from 'core-app/angular4-transition-utils'; -import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; import {ActivityEntryInfo} from 'core-components/wp-single-view-tabs/activity-panel/activity-entry-info'; @Component({ @@ -40,7 +40,7 @@ import {ActivityEntryInfo} from 'core-components/wp-single-view-tabs/activity-pa selector: 'newest-activity-on-overview', }) export class NewestActivityOnOverviewComponent extends ActivityPanelBaseController { - @Input('workPackage') public workPackage:WorkPackageResourceInterface; + @Input('workPackage') public workPackage:WorkPackageResource; public latestActivityInfo:ActivityEntryInfo[] = []; diff --git a/frontend/app/components/wp-single-view-tabs/activity-panel/activity-tab.component.ts b/frontend/app/components/wp-single-view-tabs/activity-panel/activity-tab.component.ts index 1aef93ef18..34145ce1d4 100644 --- a/frontend/app/components/wp-single-view-tabs/activity-panel/activity-tab.component.ts +++ b/frontend/app/components/wp-single-view-tabs/activity-panel/activity-tab.component.ts @@ -30,17 +30,17 @@ import {Component, Inject, Input, OnDestroy} from '@angular/core'; import {Transition} from '@uirouter/core'; import {I18nToken} from '../../../angular4-transition-utils'; import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {ActivityPanelBaseController} from 'core-components/wp-single-view-tabs/activity-panel/activity-base.controller'; import {WorkPackagesActivityService} from 'core-components/wp-single-view-tabs/activity-panel/wp-activity.service'; -import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; @Component({ template: require('!!raw-loader!./activity-tab.html'), selector: 'wp-activity-tab', }) export class WorkPackageActivityTabComponent extends ActivityPanelBaseController implements OnDestroy { - public workPackage:WorkPackageResourceInterface; + public workPackage:WorkPackageResource; public tabName = this.I18n.t('js.work_packages.tabs.activity'); constructor(readonly wpCacheService:WorkPackageCacheService, diff --git a/frontend/app/components/wp-single-view-tabs/activity-panel/wp-activity.service.ts b/frontend/app/components/wp-single-view-tabs/activity-panel/wp-activity.service.ts index 261f085dac..93a7444778 100644 --- a/frontend/app/components/wp-single-view-tabs/activity-panel/wp-activity.service.ts +++ b/frontend/app/components/wp-single-view-tabs/activity-panel/wp-activity.service.ts @@ -28,8 +28,8 @@ import {opWorkPackagesModule} from '../../../angular-modules'; import {ActivityEntryInfo} from './activity-entry-info'; -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; -import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export class WorkPackagesActivityService { @@ -52,8 +52,8 @@ export class WorkPackagesActivityService { * Resolves both promises and returns a sorted list of activities * whose order depends on the 'commentsSortedInDescendingOrder' property. */ - public aggregateActivities(workPackage:WorkPackageResourceInterface):ng.IPromise { - var aggregated:any[] = [], promises:ng.IPromise[] = []; + public aggregateActivities(workPackage:WorkPackageResource):Promise { + var aggregated:any[] = [], promises:Promise[] = []; var add = function (data:any) { aggregated.push(data.elements); @@ -85,7 +85,7 @@ export class WorkPackagesActivityService { // FIXME: ugly hack to enable circumventing cached responses which would return stale activities after a user updated a resource. // The correct solution is to rely on states. - private hackNonCachedActivities(workPackage:WorkPackageResourceInterface) { + private hackNonCachedActivities(workPackage:WorkPackageResource) { let newLoadHeaders = () => { return { caching: { enabled: false } } }; diff --git a/frontend/app/components/wp-single-view-tabs/overview-tab/overview-tab.component.ts b/frontend/app/components/wp-single-view-tabs/overview-tab/overview-tab.component.ts index def4d03661..471dc063b0 100644 --- a/frontend/app/components/wp-single-view-tabs/overview-tab/overview-tab.component.ts +++ b/frontend/app/components/wp-single-view-tabs/overview-tab/overview-tab.component.ts @@ -28,8 +28,8 @@ import {Component, Inject, OnDestroy} from '@angular/core'; import {Transition} from '@uirouter/core'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {takeUntil} from 'rxjs/operators'; import {I18nToken} from '../../../angular4-transition-utils'; @@ -40,7 +40,7 @@ import {I18nToken} from '../../../angular4-transition-utils'; }) export class WorkPackageOverviewTabComponent implements OnDestroy { public workPackageId:string; - public workPackage:WorkPackageResourceInterface; + public workPackage:WorkPackageResource; public tabName = this.I18n.t('js.label_latest_activity'); public constructor(@Inject(I18nToken) readonly I18n:op.I18n, diff --git a/frontend/app/components/wp-single-view-tabs/relations-tab/relations-tab.component.ts b/frontend/app/components/wp-single-view-tabs/relations-tab/relations-tab.component.ts index e8c856f4af..68bb105f89 100644 --- a/frontend/app/components/wp-single-view-tabs/relations-tab/relations-tab.component.ts +++ b/frontend/app/components/wp-single-view-tabs/relations-tab/relations-tab.component.ts @@ -30,7 +30,7 @@ import {Transition} from '@uirouter/core'; import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; import {Component, Inject, Input, OnDestroy, OnInit} from '@angular/core'; import {I18nToken} from '../../../angular4-transition-utils'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {takeUntil} from 'rxjs/operators'; @@ -40,7 +40,7 @@ import {takeUntil} from 'rxjs/operators'; }) export class WorkPackageRelationsTabComponent implements OnInit, OnDestroy { @Input() public workPackageId?:string; - public workPackage:WorkPackageResourceInterface; + public workPackage:WorkPackageResource; public constructor(@Inject(I18nToken) readonly I18n:op.I18n, readonly $transition:Transition, diff --git a/frontend/app/components/wp-single-view-tabs/watchers-tab/watchers-tab.component.ts b/frontend/app/components/wp-single-view-tabs/watchers-tab/watchers-tab.component.ts index 53278473fd..6e56b68cfd 100644 --- a/frontend/app/components/wp-single-view-tabs/watchers-tab/watchers-tab.component.ts +++ b/frontend/app/components/wp-single-view-tabs/watchers-tab/watchers-tab.component.ts @@ -28,10 +28,10 @@ import {Component, ElementRef, Inject, OnDestroy, OnInit} from '@angular/core'; import {Transition} from '@uirouter/core'; -import {CollectionResource} from 'core-components/api/api-v3/hal-resources/collection-resource.service'; -import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; -import {UserResource} from 'core-components/api/api-v3/hal-resources/user-resource.service'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {UserResource} from 'core-app/modules/hal/resources/user-resource'; import {LoadingIndicatorService} from 'core-components/common/loading-indicator/loading-indicator.service'; import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; import {WorkPackageNotificationService} from 'core-components/wp-edit/wp-notification.service'; @@ -45,7 +45,7 @@ import {I18nToken} from '../../../angular4-transition-utils'; }) export class WorkPackageWatchersTabComponent implements OnInit, OnDestroy { public workPackageId:string; - public workPackage:WorkPackageResourceInterface; + public workPackage:WorkPackageResource; public autocompleteInput = ''; public error = false; diff --git a/frontend/app/components/wp-single-view-tabs/watchers-tab/wp-watcher-entry.component.ts b/frontend/app/components/wp-single-view-tabs/watchers-tab/wp-watcher-entry.component.ts index f76bc594fb..ac15836d9d 100644 --- a/frontend/app/components/wp-single-view-tabs/watchers-tab/wp-watcher-entry.component.ts +++ b/frontend/app/components/wp-single-view-tabs/watchers-tab/wp-watcher-entry.component.ts @@ -29,7 +29,7 @@ import {Component, Inject, Input, OnInit} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; import {WorkPackageWatchersTabComponent} from './watchers-tab.component'; -import {UserResource} from '../../api/api-v3/hal-resources/user-resource.service'; +import {UserResource} from 'core-app/modules/hal/resources/user-resource'; @Component({ template: require('!!raw-loader!./wp-watcher-entry.html'), diff --git a/frontend/app/components/wp-table/context-menu-helper/wp-context-menu-helper.service.ts b/frontend/app/components/wp-table/context-menu-helper/wp-context-menu-helper.service.ts index 840dcff7ac..40a4beb716 100644 --- a/frontend/app/components/wp-table/context-menu-helper/wp-context-menu-helper.service.ts +++ b/frontend/app/components/wp-table/context-menu-helper/wp-context-menu-helper.service.ts @@ -25,7 +25,7 @@ // // See doc/COPYRIGHT.rdoc for more details. //++ -import {WorkPackageResourceInterface} from './../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {WorkPackageTableTimelineService} from "../../wp-fast-table/state/wp-table-timeline.service"; import {Inject, Injectable} from "@angular/core"; import {PathHelperService} from "core-components/common/path-helper/path-helper.service"; @@ -74,7 +74,7 @@ export class WorkPackageContextMenuHelperService { private PathHelper:PathHelperService) { } - public getPermittedActionLinks(workPackage:WorkPackageResourceInterface, permittedActionConstants:any):WorkPackageAction[] { + public getPermittedActionLinks(workPackage:WorkPackageResource, permittedActionConstants:any):WorkPackageAction[] { var singularPermittedActions:any[] = []; var allowedActions = this.getAllowedActions(workPackage, permittedActionConstants); @@ -94,7 +94,7 @@ export class WorkPackageContextMenuHelperService { var bulkPermittedActions:any = []; var permittedActions = _.filter(this.BULK_ACTIONS, (action:any) => { - return _.every(workPackages, (workPackage:WorkPackageResourceInterface) => { + return _.every(workPackages, (workPackage:WorkPackageResource) => { return this.getAllowedActions(workPackage, [action]).length >= 1; }); }); @@ -125,7 +125,7 @@ export class WorkPackageContextMenuHelperService { return link + '?' + queryParts.join('&'); } - public getAllowedActions(workPackage:WorkPackageResourceInterface, actions:any):WorkPackageAction[] { + public getAllowedActions(workPackage:WorkPackageResource, actions:any):WorkPackageAction[] { var allowedActions:any[] = []; angular.forEach(actions, (action) => { @@ -166,7 +166,7 @@ export class WorkPackageContextMenuHelperService { return allowedActions; } - public getPermittedActions(workPackages:WorkPackageResourceInterface[], permittedActionConstants:any):WorkPackageAction[] { + public getPermittedActions(workPackages:WorkPackageResource[], permittedActionConstants:any):WorkPackageAction[] { if (workPackages.length === 1) { return this.getPermittedActionLinks(workPackages[0], permittedActionConstants); } else { diff --git a/frontend/app/components/wp-table/embedded/wp-embedded-table.component.ts b/frontend/app/components/wp-table/embedded/wp-embedded-table.component.ts index c22cef7b17..3221e49440 100644 --- a/frontend/app/components/wp-table/embedded/wp-embedded-table.component.ts +++ b/frontend/app/components/wp-table/embedded/wp-embedded-table.component.ts @@ -1,10 +1,5 @@ import {Component, Input, OnDestroy, OnInit} from '@angular/core'; -import {QueryDmService} from '../../api/api-v3/hal-resource-dms/query-dm.service'; import {CurrentProjectService} from '../../projects/current-project.service'; -import { - QueryResource, - QueryResourceInterface -} from '../../api/api-v3/hal-resources/query-resource.service'; import {TableState} from '../table-state/table-state'; import {WorkPackageStatesInitializationService} from '../../wp-list/wp-states-initialization.service'; import {WorkPackageTableRelationColumnsService} from 'core-components/wp-fast-table/state/wp-table-relation-columns.service'; @@ -19,7 +14,6 @@ import {WorkPackageTableSumService} from 'core-components/wp-fast-table/state/wp import {WorkPackageTableAdditionalElementsService} from 'core-components/wp-fast-table/state/wp-table-additional-elements.service'; import {withLatestFrom} from 'rxjs/operators'; import {untilComponentDestroyed} from 'ng2-rx-componentdestroyed'; -import {WorkPackageCollectionResource} from 'core-components/api/api-v3/hal-resources/wp-collection-resource.service'; import {WorkPackageTableConfigurationObject} from 'core-components/wp-table/wp-table-configuration'; import {OpTableActionFactory} from 'core-components/wp-table/table-actions/table-action'; import {WorkPackageTableRefreshService} from 'core-components/wp-table/wp-table-refresh-request.service'; @@ -28,6 +22,9 @@ import {opUiComponentsModule} from 'core-app/angular-modules'; import {downgradeComponent} from '@angular/upgrade/static'; import {LoadingIndicatorService} from 'core-components/common/loading-indicator/loading-indicator.service'; import {WorkPackageTableSelection} from 'core-components/wp-fast-table/state/wp-table-selection.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {QueryDmService} from 'core-app/modules/dm-services/query-dm.service'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource'; @Component({ selector: 'wp-embedded-table', @@ -58,7 +55,7 @@ export class WorkPackageEmbeddedTableComponent implements OnInit, OnDestroy { @Input() public tableActions?:OpTableActionFactory[]; @Input() public compactTableStyle:boolean = false; - private query:QueryResourceInterface; + private query:QueryResource; public tableInformationLoaded = false; public showTablePagination = false; @@ -139,7 +136,7 @@ export class WorkPackageEmbeddedTableComponent implements OnInit, OnDestroy { this.queryId, this.projectIdentifier ) - .then((query:QueryResourceInterface) => this.initializeStates(query, query.results)); + .then((query:QueryResource) => this.initializeStates(query, query.results)); } } diff --git a/frontend/app/components/wp-table/sort-header/sort-header.directive.ts b/frontend/app/components/wp-table/sort-header/sort-header.directive.ts index c78a27a7ad..91bf2f5f23 100644 --- a/frontend/app/components/wp-table/sort-header/sort-header.directive.ts +++ b/frontend/app/components/wp-table/sort-header/sort-header.directive.ts @@ -28,10 +28,6 @@ import {AfterViewInit, Component, ElementRef, Inject, Input, OnDestroy} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; -import { - QUERY_SORT_BY_ASC, - QUERY_SORT_BY_DESC -} from 'core-components/api/api-v3/hal-resources/query-sort-by-resource.service'; import {RelationQueryColumn, TypeRelationQueryColumn} from 'core-components/wp-query/query-column'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {takeUntil} from 'rxjs/operators'; @@ -40,6 +36,10 @@ import {WorkPackageTableRelationColumnsService} from '../../wp-fast-table/state/ import {WorkPackageTableSortByService} from '../../wp-fast-table/state/wp-table-sort-by.service'; import {WorkPackageTableGroupByService} from './../../wp-fast-table/state/wp-table-group-by.service'; import {WorkPackageTable} from 'core-components/wp-fast-table/wp-fast-table'; +import { + QUERY_SORT_BY_ASC, + QUERY_SORT_BY_DESC +} from 'core-app/modules/hal/resources/query-sort-by-resource'; @Component({ @@ -224,28 +224,5 @@ export class SortHeaderDirective implements OnDestroy, AfterViewInit { } -// angular -// .module('openproject.workPackages.directives') -// .directive('sortHeader', sortHeader); -// -// function sortHeader(wpTableHierarchies:WorkPackageTableHierarchiesService, -// wpTableSortBy:WorkPackageTableSortByService, -// wpTableGroupBy:WorkPackageTableGroupByService, -// wpTableRelationColumns:WorkPackageTableRelationColumnsService, -// I18n:op.I18n) { -// return { -// restrict: 'A', -// templateUrl: '/components/wp-table/sort-header/sort-header.directive.html', -// -// scope: { -// column: '=headerColumn', -// locale: '=' -// }, -// -// link: function(scope:any, element:ng.IAugmentedJQuery) { -// } -// }; -// } -// diff --git a/frontend/app/components/wp-table/table-actions/actions/unlink-table-action.ts b/frontend/app/components/wp-table/table-actions/actions/unlink-table-action.ts index 138810e5f9..df92503e3c 100644 --- a/frontend/app/components/wp-table/table-actions/actions/unlink-table-action.ts +++ b/frontend/app/components/wp-table/table-actions/actions/unlink-table-action.ts @@ -4,16 +4,16 @@ import { } from 'core-components/wp-table/table-actions/table-action'; import {opIconElement} from 'core-app/helpers/op-icon-builder'; import {contextColumnIcon} from 'core-components/wp-fast-table/builders/table-action-renderer'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; import {Injector} from '@angular/core'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; export class OpUnlinkTableAction extends OpTableAction { constructor(public injector:Injector, - public workPackage:WorkPackageResourceInterface, + public workPackage:WorkPackageResource, public readonly identifier:string, private title:string, - readonly onClick:(workPackage:WorkPackageResourceInterface) => void) { + readonly onClick:(workPackage:WorkPackageResource) => void) { super(injector, workPackage); } @@ -27,8 +27,8 @@ export class OpUnlinkTableAction extends OpTableAction { */ public static factoryFor(identifier:string, title:string, - onClick:(workPackage:WorkPackageResourceInterface) => void):OpTableActionFactory { - return (injector:Injector, workPackage:WorkPackageResourceInterface) => { + onClick:(workPackage:WorkPackageResource) => void):OpTableActionFactory { + return (injector:Injector, workPackage:WorkPackageResource) => { return new OpUnlinkTableAction(injector, workPackage, identifier, diff --git a/frontend/app/components/wp-table/table-actions/table-action.ts b/frontend/app/components/wp-table/table-actions/table-action.ts index e44239f432..4345b1365c 100644 --- a/frontend/app/components/wp-table/table-actions/table-action.ts +++ b/frontend/app/components/wp-table/table-actions/table-action.ts @@ -1,15 +1,15 @@ -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; import {Injector} from '@angular/core'; import {I18nToken} from 'core-app/angular4-transition-utils'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; -export type OpTableActionFactory = (i:Injector, wp:WorkPackageResourceInterface) => OpTableAction; +export type OpTableActionFactory = (i:Injector, wp:WorkPackageResource) => OpTableAction; export abstract class OpTableAction { public I18n:op.I18n = this.injector.get(I18nToken); constructor(readonly injector:Injector, - readonly workPackage:WorkPackageResourceInterface) { + readonly workPackage:WorkPackageResource) { } /** Identifier to uniquely identify the action */ diff --git a/frontend/app/components/wp-table/table-actions/table-actions.service.ts b/frontend/app/components/wp-table/table-actions/table-actions.service.ts index 20a4cdc293..a6b371dbb6 100644 --- a/frontend/app/components/wp-table/table-actions/table-actions.service.ts +++ b/frontend/app/components/wp-table/table-actions/table-actions.service.ts @@ -4,7 +4,7 @@ import { } from 'core-components/wp-table/table-actions/table-action'; import {OpDetailsTableAction} from 'core-components/wp-table/table-actions/actions/details-table-action'; import {OpContextMenuTableAction} from 'core-components/wp-table/table-actions/actions/context-menu-table-action'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; @Injectable() export class OpTableActionsService { @@ -31,7 +31,7 @@ export class OpTableActionsService { * Render actions for the given work package. * @param {WorkPackageResource} workPackage */ - public render(workPackage:WorkPackageResourceInterface):HTMLElement[] { + public render(workPackage:WorkPackageResource):HTMLElement[] { return this.actions.map((factory) => factory(this.injector, workPackage).buildElement()); } } diff --git a/frontend/app/components/wp-table/table-pagination/wp-table-pagination.component.ng2.test.ts b/frontend/app/components/wp-table/table-pagination/wp-table-pagination.component.ng2.test.ts index e638c1e7fa..9bc622bbc8 100644 --- a/frontend/app/components/wp-table/table-pagination/wp-table-pagination.component.ng2.test.ts +++ b/frontend/app/components/wp-table/table-pagination/wp-table-pagination.component.ng2.test.ts @@ -26,19 +26,18 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {TableState} from 'core-components/wp-table/table-state/table-state'; - -require('../../../angular4-test-setup'); +require('core-app/angular4-test-setup'); +import {TableState} from 'core-components/wp-table/table-state/table-state'; +import {ConfigurationDmService} from 'core-app/modules/dm-services/configuration-dm.service'; import {async, inject, TestBed} from '@angular/core/testing'; import {$httpToken, $qToken, halResourceFactoryToken, I18nToken, v3PathToken} from 'core-app/angular4-transition-utils'; -import {HalRequestService} from 'core-components/api/api-v3/hal-request/hal-request.service'; -import {ConfigurationDmService} from 'core-components/api/api-v3/hal-resource-dms/configuration-dm.service'; 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'; import {WorkPackageTablePaginationService} from 'core-components/wp-fast-table/state/wp-table-pagination.service'; import {WorkPackageTablePaginationComponent} from 'core-components/wp-table/table-pagination/wp-table-pagination.component'; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; async function setupMocks(paginationService:PaginationService) { sinon.stub(paginationService, 'loadPaginationOptions', async () => { diff --git a/frontend/app/components/wp-table/table-pagination/wp-table-pagination.component.ts b/frontend/app/components/wp-table/table-pagination/wp-table-pagination.component.ts index af7fb23310..cc6a22d8a1 100644 --- a/frontend/app/components/wp-table/table-pagination/wp-table-pagination.component.ts +++ b/frontend/app/components/wp-table/table-pagination/wp-table-pagination.component.ts @@ -26,8 +26,6 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {ConfigurationResource} from '../../api/api-v3/hal-resources/configuration-resource.service'; -import {ConfigurationDmService} from '../../api/api-v3/hal-resource-dms/configuration-dm.service'; import {WorkPackageTablePaginationService} from '../../wp-fast-table/state/wp-table-pagination.service'; import {WorkPackageTablePagination} from '../../wp-fast-table/wp-table-pagination'; import {wpDirectivesModule} from '../../../angular-modules'; diff --git a/frontend/app/components/wp-table/table-state/table-state.ts b/frontend/app/components/wp-table/table-state/table-state.ts index ea7d938b3b..5c2a105eb1 100644 --- a/frontend/app/components/wp-table/table-state/table-state.ts +++ b/frontend/app/components/wp-table/table-state/table-state.ts @@ -1,8 +1,3 @@ -import {WorkPackageResourceInterface} from 'app/components/api/api-v3/hal-resources/work-package-resource.service'; -import { - GroupObject, - WorkPackageCollectionResource -} from 'app/components/api/api-v3/hal-resources/wp-collection-resource.service'; import {RenderedRow} from 'app/components/wp-fast-table/builders/primary-render-pass'; import {WorkPackageTableColumns} from 'app/components/wp-fast-table/wp-table-columns'; import {WorkPackageTableFilters} from 'app/components/wp-fast-table/wp-table-filters'; @@ -16,13 +11,15 @@ import {WorkPackageTableTimelineState} from 'app/components/wp-fast-table/wp-tab import {WPTableRowSelectionState} from 'app/components/wp-fast-table/wp-table.interfaces'; import {combine, derive, input, State, StatesGroup} from 'reactivestates'; import {Subject} from 'rxjs/Rx'; -import {States} from 'core-components/states.service'; import {Injectable} from '@angular/core'; -import {QueryResource} from 'core-components/api/api-v3/hal-resources/query-resource.service'; -import {opServicesModule} from 'core-app/angular-modules'; -import {downgradeInjectable} from '@angular/upgrade/static'; import {SwitchState} from 'core-components/states/switch-state'; import {mapTo, map} from 'rxjs/operators'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import { + GroupObject, + WorkPackageCollectionResource +} from 'core-app/modules/hal/resources/wp-collection-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; @Injectable() export class TableState extends StatesGroup { @@ -39,7 +36,7 @@ export class TableState extends StatesGroup { // the results associated with the table results = input(); // Set of work package IDs in strict order of appearance - rows = input(); + rows = input(); // all groups returned as results groups = input(); // Set of columns in strict order of appearance @@ -94,8 +91,6 @@ export class TableState extends StatesGroup { updates = new UserUpdaterStates(this); } -opServicesModule.service('globalTableState', downgradeInjectable(TableState)); - export class TableRenderingStates { constructor(private tableState:TableState) { } diff --git a/frontend/app/components/wp-table/timeline/cells/timeline-cell-renderer.ts b/frontend/app/components/wp-table/timeline/cells/timeline-cell-renderer.ts index 2a4cb83c92..0d47cae873 100644 --- a/frontend/app/components/wp-table/timeline/cells/timeline-cell-renderer.ts +++ b/frontend/app/components/wp-table/timeline/cells/timeline-cell-renderer.ts @@ -1,6 +1,6 @@ import * as moment from 'moment'; import {$injectFields} from '../../../angular/angular-injector-bridge.functions'; -import {WorkPackageResourceInterface} from '../../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import { calculatePositionValueForDayCount, calculatePositionValueForDayCountingPx, @@ -65,11 +65,11 @@ export class TimelineCellRenderer { return 'rgba(50, 50, 50, 0.1)'; } - public canMoveDates(wp:WorkPackageResourceInterface) { + public canMoveDates(wp:WorkPackageResource) { return wp.schema.startDate.writable && wp.schema.dueDate.writable; } - public isEmpty(wp:WorkPackageResourceInterface) { + public isEmpty(wp:WorkPackageResource) { const start = moment(wp.startDate as any); const due = moment(wp.dueDate as any); const noStartAndDueValues = _.isNaN(start.valueOf()) && _.isNaN(due.valueOf()); @@ -371,7 +371,7 @@ export class TimelineCellRenderer { return labels; } - protected typeColor(wp:WorkPackageResourceInterface):string { + protected typeColor(wp:WorkPackageResource):string { let type = wp.type && wp.type.state.value; if (type && type.color) { return type.color; diff --git a/frontend/app/components/wp-table/timeline/cells/timeline-milestone-cell-renderer.ts b/frontend/app/components/wp-table/timeline/cells/timeline-milestone-cell-renderer.ts index 01f6860d09..1585181226 100644 --- a/frontend/app/components/wp-table/timeline/cells/timeline-milestone-cell-renderer.ts +++ b/frontend/app/components/wp-table/timeline/cells/timeline-milestone-cell-renderer.ts @@ -1,5 +1,5 @@ import * as moment from 'moment'; -import {WorkPackageResourceInterface} from '../../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import { calculatePositionValueForDayCountingPx, RenderInfo, @@ -25,13 +25,13 @@ export class TimelineMilestoneCellRenderer extends TimelineCellRenderer { return 'milestone'; } - public isEmpty(wp:WorkPackageResourceInterface) { + public isEmpty(wp:WorkPackageResource) { const date = moment(wp.date as any); const noDateValue = _.isNaN(date.valueOf()); return noDateValue; } - public canMoveDates(wp:WorkPackageResourceInterface) { + public canMoveDates(wp:WorkPackageResource) { return wp.schema.date.writable; } diff --git a/frontend/app/components/wp-table/timeline/cells/wp-timeline-cell-mouse-handler.ts b/frontend/app/components/wp-table/timeline/cells/wp-timeline-cell-mouse-handler.ts index 178dd74ed5..684e25d0d6 100644 --- a/frontend/app/components/wp-table/timeline/cells/wp-timeline-cell-mouse-handler.ts +++ b/frontend/app/components/wp-table/timeline/cells/wp-timeline-cell-mouse-handler.ts @@ -28,8 +28,6 @@ import {Injector} from '@angular/core'; import * as moment from 'moment'; -import {$injectNow} from '../../../angular/angular-injector-bridge.functions'; -import {QueryDmService} from '../../../api/api-v3/hal-resource-dms/query-dm.service'; import {keyCodes} from '../../../common/keyCodes.enum'; import {LoadingIndicatorService} from '../../../common/loading-indicator/loading-indicator.service'; import {States} from '../../../states.service'; @@ -41,8 +39,9 @@ import {WorkPackageTimelineTableController} from '../container/wp-timeline-conta import {RenderInfo} from '../wp-timeline'; import {TimelineCellRenderer} from './timeline-cell-renderer'; import {WorkPackageCellLabels} from './wp-timeline-cell'; -import Moment = moment.Moment; import {TableState} from 'core-components/wp-table/table-state/table-state'; +import {QueryDmService} from 'core-app/modules/dm-services/query-dm.service'; +import Moment = moment.Moment; export const classNameBar = 'bar'; export const classNameLeftHandle = 'leftHandle'; @@ -226,25 +225,23 @@ export function registerWorkPackageMouseHandler(this:void, renderer.onMouseDownEnd(labels, renderInfo.changeset); workPackageTimeline.refreshView(); } else { + const stopAndRefresh = () => { + renderInfo.changeset.clear(); + renderer.onMouseDownEnd(labels, renderInfo.changeset); + workPackageTimeline.refreshView(); + }; + // Persist the changes saveWorkPackage(renderInfo.changeset) - .then(() => { - renderInfo.changeset.clear(); - renderer.onMouseDownEnd(labels, renderInfo.changeset); - workPackageTimeline.refreshView(); - }) - .catch(() => { - renderInfo.changeset.clear(); - renderer.onMouseDownEnd(labels, renderInfo.changeset); - workPackageTimeline.refreshView(); - }); + .then(stopAndRefresh) + .catch(stopAndRefresh); } } async function saveWorkPackage(changeset:WorkPackageChangeset) { - const queryDm:QueryDmService = $injectNow('QueryDm'); - const states:States = $injectNow('states'); + const queryDm:QueryDmService = injector.get(QueryDmService); + const states:States = injector.get(States); // Remmeber the time before saving the work package to know which work packages to update const updatedAt = moment().toISOString(); diff --git a/frontend/app/components/wp-table/timeline/cells/wp-timeline-cell.ts b/frontend/app/components/wp-table/timeline/cells/wp-timeline-cell.ts index 1139b502ec..040935be7f 100644 --- a/frontend/app/components/wp-table/timeline/cells/wp-timeline-cell.ts +++ b/frontend/app/components/wp-table/timeline/cells/wp-timeline-cell.ts @@ -27,7 +27,7 @@ import {$injectFields} from '../../../angular/angular-injector-bridge.functions' // // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageResourceInterface} from '../../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {LoadingIndicatorService} from '../../../common/loading-indicator/loading-indicator.service'; import {States} from '../../../states.service'; import {WorkPackageCacheService} from '../../../work-packages/work-package-cache.service'; @@ -171,7 +171,7 @@ export class WorkPackageTimelineCell { return cell; } - private cellRenderer(workPackage:WorkPackageResourceInterface):TimelineCellRenderer { + private cellRenderer(workPackage:WorkPackageResource):TimelineCellRenderer { if (workPackage.isMilestone) { return this.renderers.milestone; } diff --git a/frontend/app/components/wp-table/timeline/container/wp-timeline-container.directive.ts b/frontend/app/components/wp-table/timeline/container/wp-timeline-container.directive.ts index 7c203bd18c..a4b9ee4a73 100644 --- a/frontend/app/components/wp-table/timeline/container/wp-timeline-container.directive.ts +++ b/frontend/app/components/wp-table/timeline/container/wp-timeline-container.directive.ts @@ -33,8 +33,8 @@ import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {filter, map, take, takeUntil, withLatestFrom} from 'rxjs/operators'; import {I18nToken, NotificationsServiceToken} from '../../../../angular4-transition-utils'; import {debugLog, timeOutput} from '../../../../helpers/debug_output'; -import {TypeResource} from '../../../api/api-v3/hal-resources/type-resource.service'; -import {WorkPackageResourceInterface} from '../../../api/api-v3/hal-resources/work-package-resource.service'; +import {TypeResource} from 'core-app/modules/hal/resources/type-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; import {States} from '../../../states.service'; import {WorkPackageNotificationService} from '../../../wp-edit/wp-notification.service'; import {RenderedRow} from '../../../wp-fast-table/builders/primary-render-pass'; @@ -57,6 +57,7 @@ import { zoomLevelOrder } from '../wp-timeline'; import moment = require('moment'); +import {TypeDmService} from 'core-app/modules/dm-services/type-dm.service'; @Component({ selector: 'wp-timeline-container', @@ -96,6 +97,7 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest private elementRef:ElementRef, private states:States, public wpTableDirective:WorkPackagesTableController, + public typeDmService:TypeDmService, @Inject(NotificationsServiceToken) private NotificationsService:any, private wpTableTimeline:WorkPackageTableTimelineService, private wpNotificationsService:WorkPackageNotificationService, @@ -176,9 +178,9 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest take(1) ) .subscribe(() => { - TypeResource.loadAll().then(() => { - this.debouncedRefresh(); - }); + this.typeDmService + .loadAll() + .then(() => this.debouncedRefresh()); }); } @@ -276,7 +278,7 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest }); } - startAddRelationPredecessor(start:WorkPackageResourceInterface) { + startAddRelationPredecessor(start:WorkPackageResource) { this.activateSelectionMode(start.id, end => { this.wpRelations .addCommonRelation(start as any, 'follows', end.id) @@ -284,7 +286,7 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest }); } - startAddRelationFollower(start:WorkPackageResourceInterface) { + startAddRelationFollower(start:WorkPackageResource) { this.activateSelectionMode(start.id, end => { this.wpRelations .addCommonRelation(start as any, 'precedes', end.id) @@ -337,10 +339,10 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest this.refreshView(); } - private activateSelectionMode(start:string, callback:(wp:WorkPackageResourceInterface) => any) { + private activateSelectionMode(start:string, callback:(wp:WorkPackageResource) => any) { start = start.toString(); // old system bug: ID can be a 'number' - this._viewParameters.activeSelectionMode = (wp:WorkPackageResourceInterface) => { + this._viewParameters.activeSelectionMode = (wp:WorkPackageResource) => { callback(wp); this.resetSelectionMode(); }; diff --git a/frontend/app/components/wp-table/timeline/global-elements/timeline-relation-element.ts b/frontend/app/components/wp-table/timeline/global-elements/timeline-relation-element.ts index d316a890c8..3c90826cf5 100644 --- a/frontend/app/components/wp-table/timeline/global-elements/timeline-relation-element.ts +++ b/frontend/app/components/wp-table/timeline/global-elements/timeline-relation-element.ts @@ -1,15 +1,15 @@ -import {RelationResourceInterface} from "core-components/api/api-v3/hal-resources/relation-resource.service"; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; -export function workPackagePrefix(workPackageId: string) { +export function workPackagePrefix(workPackageId:string) { return `__tl-relation-${workPackageId}`; } export class TimelineRelationElement { - constructor(public belongsToId: string, public relation: RelationResourceInterface) { + constructor(public belongsToId:string, public relation:RelationResource) { } - public get classNames(): string[] { + public get classNames():string[] { return [ workPackagePrefix(this.relation.ids.from), workPackagePrefix(this.relation.ids.to) diff --git a/frontend/app/components/wp-table/timeline/grid/wp-timeline-grid.directive.ts b/frontend/app/components/wp-table/timeline/grid/wp-timeline-grid.directive.ts index 835236fbed..5b640aa520 100644 --- a/frontend/app/components/wp-table/timeline/grid/wp-timeline-grid.directive.ts +++ b/frontend/app/components/wp-table/timeline/grid/wp-timeline-grid.directive.ts @@ -27,7 +27,6 @@ // ++ import {AfterViewInit, Component, ElementRef} from '@angular/core'; import * as moment from 'moment'; -import {TimelineZoomLevel} from '../../../api/api-v3/hal-resources/query-resource.service'; import {WorkPackageTimelineTableController} from '../container/wp-timeline-container.directive'; import { calculatePositionValueForDayCount, @@ -37,6 +36,7 @@ import { TimelineViewParameters } from '../wp-timeline'; import Moment = moment.Moment; +import {TimelineZoomLevel} from 'core-app/modules/hal/resources/query-resource'; function checkForWeekendHighlight(date:Moment, cell:HTMLElement) { const day = date.day(); diff --git a/frontend/app/components/wp-table/timeline/header/wp-timeline-header.directive.ts b/frontend/app/components/wp-table/timeline/header/wp-timeline-header.directive.ts index 6b8ce6a5d0..a748b25b93 100644 --- a/frontend/app/components/wp-table/timeline/header/wp-timeline-header.directive.ts +++ b/frontend/app/components/wp-table/timeline/header/wp-timeline-header.directive.ts @@ -29,9 +29,9 @@ import {Component, ElementRef, OnInit} from '@angular/core'; import {WorkPackageTimelineTableController} from 'core-components/wp-table/timeline/container/wp-timeline-container.directive'; import * as moment from 'moment'; -import {TimelineZoomLevel} from '../../../api/api-v3/hal-resources/query-resource.service'; import {calculatePositionValueForDayCount, getTimeSlicesForHeader, TimelineViewParameters} from '../wp-timeline'; import Moment = moment.Moment; +import {TimelineZoomLevel} from 'core-app/modules/hal/resources/query-resource'; export const timelineHeaderCSSClass = 'wp-timeline--header-element'; diff --git a/frontend/app/components/wp-table/timeline/wp-timeline.ts b/frontend/app/components/wp-table/timeline/wp-timeline.ts index 143af58568..f8c6f17876 100644 --- a/frontend/app/components/wp-table/timeline/wp-timeline.ts +++ b/frontend/app/components/wp-table/timeline/wp-timeline.ts @@ -27,14 +27,11 @@ // ++ import * as moment from 'moment'; import {InputState, MultiInputState} from 'reactivestates'; -import {TimelineZoomLevel} from '../../api/api-v3/hal-resources/query-resource.service'; -import { - WorkPackageResource, - WorkPackageResourceInterface -} from '../../api/api-v3/hal-resources/work-package-resource.service'; -import {WorkPackageChangeset} from '../../wp-edit-form/work-package-changeset'; import {RenderedRow} from '../../wp-fast-table/builders/primary-render-pass'; import Moment = moment.Moment; +import {TimelineZoomLevel} from 'core-app/modules/hal/resources/query-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {WorkPackageChangeset} from 'core-components/wp-edit-form/work-package-changeset'; export const timelineElementCssClass = 'timeline-element'; export const timelineGridElementCssClass = 'wp-timeline--grid-element'; @@ -87,7 +84,7 @@ export class TimelineViewParameters { settings:TimelineViewParametersSettings = new TimelineViewParametersSettings(); - activeSelectionMode:null | ((wp:WorkPackageResourceInterface) => any) = null; + activeSelectionMode:null | ((wp:WorkPackageResource) => any) = null; selectionModeStart:null | string = null; @@ -115,7 +112,7 @@ export class TimelineViewParameters { */ export interface RenderInfo { viewParams:TimelineViewParameters; - workPackage:WorkPackageResourceInterface; + workPackage:WorkPackageResource; changeset:WorkPackageChangeset; } @@ -177,7 +174,7 @@ export function getTimeSlicesForHeader(vp:TimelineViewParameters, } export function calculateDaySpan(visibleWorkPackages:RenderedRow[], - loadedWorkPackages:MultiInputState):number { + loadedWorkPackages:MultiInputState):number { let earliest:Moment = moment(); let latest:Moment = moment(); @@ -187,8 +184,8 @@ export function calculateDaySpan(visibleWorkPackages:RenderedRow[], if (!wpId) { return; } - const workPackageState:InputState = loadedWorkPackages.get(wpId); - const workPackage:WorkPackageResourceInterface = workPackageState.value!; + const workPackageState:InputState = loadedWorkPackages.get(wpId); + const workPackage:WorkPackageResource = workPackageState.value!; const start = workPackage.startDate ? workPackage.startDate : workPackage.date; if (start && moment(start).isBefore(earliest)) { diff --git a/frontend/app/components/wp-table/wp-table-sums-row/wp-table-sums-row.directive.ts b/frontend/app/components/wp-table/wp-table-sums-row/wp-table-sums-row.directive.ts index fc91b50710..3c0d31ae84 100644 --- a/frontend/app/components/wp-table/wp-table-sums-row/wp-table-sums-row.directive.ts +++ b/frontend/app/components/wp-table/wp-table-sums-row/wp-table-sums-row.directive.ts @@ -30,8 +30,8 @@ import {AfterViewInit, Directive, ElementRef, Inject, Injector} from '@angular/c import {combine} from 'reactivestates'; import {takeUntil} from 'rxjs/operators'; import {I18nToken} from '../../../angular4-transition-utils'; -import {SchemaResource} from '../../api/api-v3/hal-resources/schema-resource.service'; -import {WorkPackageCollectionResourceInterface} from '../../api/api-v3/hal-resources/wp-collection-resource.service'; +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource'; import {States} from '../../states.service'; import {DisplayField} from '../../wp-display/wp-display-field/wp-display-field.module'; import {WorkPackageDisplayFieldService} from '../../wp-display/wp-display-field/wp-display-field.service'; @@ -87,12 +87,12 @@ export class WorkPackageTableSumsRowController implements AfterViewInit { this.$element.empty(); } - private refresh(columns:WorkPackageTableColumns, resource:WorkPackageCollectionResourceInterface, schema:SchemaResource) { + private refresh(columns:WorkPackageTableColumns, resource:WorkPackageCollectionResource, schema:SchemaResource) { this.clear(); this.render(columns, resource, schema); } - private render(columns:WorkPackageTableColumns, resource:WorkPackageCollectionResourceInterface, schema:SchemaResource) { + private render(columns:WorkPackageTableColumns, resource:WorkPackageCollectionResource, schema:SchemaResource) { this.$element[0].classList.add('sum', 'group', 'all', 'issue', 'work_package'); // build diff --git a/frontend/app/components/wp-table/wp-table.directive.ts b/frontend/app/components/wp-table/wp-table.directive.ts index 69bb8c9f5b..a62eab4c18 100644 --- a/frontend/app/components/wp-table/wp-table.directive.ts +++ b/frontend/app/components/wp-table/wp-table.directive.ts @@ -28,8 +28,8 @@ import {Component, ElementRef, Inject, Injector, Input, OnDestroy, OnInit} from '@angular/core'; import {columnsModalToken, I18nToken} from 'core-app/angular4-transition-utils'; -import {QueryGroupByResource} from 'core-components/api/api-v3/hal-resources/query-group-by-resource.service'; -import {QueryResource} from 'core-components/api/api-v3/hal-resources/query-resource.service'; +import {QueryGroupByResource} from 'core-app/modules/hal/resources/query-group-by-resource'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; import {TableHandlerRegistry} from 'core-components/wp-fast-table/handlers/table-handler-registry'; import {TableState} from 'core-components/wp-table/table-state/table-state'; import {untilComponentDestroyed} from 'ng2-rx-componentdestroyed'; diff --git a/frontend/app/components/api/api-v3/hal-resource-dms/configuration-dm.service.ts b/frontend/app/modules/dm-services/configuration-dm.service.ts similarity index 79% rename from frontend/app/components/api/api-v3/hal-resource-dms/configuration-dm.service.ts rename to frontend/app/modules/dm-services/configuration-dm.service.ts index 3525ba84de..4c75850031 100644 --- a/frontend/app/components/api/api-v3/hal-resource-dms/configuration-dm.service.ts +++ b/frontend/app/modules/dm-services/configuration-dm.service.ts @@ -26,11 +26,12 @@ // See doc/COPYRIGHT.rdoc for more details. //++ + + import {Inject, Injectable} from '@angular/core'; -import {opApiModule} from 'core-app/angular-modules'; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; import {v3PathToken} from 'core-app/angular4-transition-utils'; -import {HalRequestService} from '../hal-request/hal-request.service'; -import {ConfigurationResource} from '../hal-resources/configuration-resource.service'; +import {ConfigurationResource} from 'core-app/modules/hal/resources/configuration-resource'; @Injectable() export class ConfigurationDmService { @@ -38,9 +39,7 @@ export class ConfigurationDmService { @Inject(v3PathToken) protected v3Path:any) { } - public load():ng.IPromise { - return this.halRequest.get(this.v3Path.configuration()); + public load():Promise { + return this.halRequest.get(this.v3Path.configuration()).toPromise(); } } - -opApiModule.service('ConfigurationDm', ConfigurationDmService); diff --git a/frontend/app/components/api/api-v3/hal-resource-dms/help-text-dm.service.ts b/frontend/app/modules/dm-services/help-text-dm.service.ts similarity index 66% rename from frontend/app/components/api/api-v3/hal-resource-dms/help-text-dm.service.ts rename to frontend/app/modules/dm-services/help-text-dm.service.ts index 60fc40596b..f9287ea467 100644 --- a/frontend/app/components/api/api-v3/hal-resource-dms/help-text-dm.service.ts +++ b/frontend/app/modules/dm-services/help-text-dm.service.ts @@ -26,26 +26,24 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {opApiModule} from '../../../../angular-modules'; -import {HalRequestService} from '../hal-request/hal-request.service'; -import { - HelpTextResource, - HelpTextResourceInterface -} from '../hal-resources/help-text-resource.service'; -import {CollectionResource} from "core-components/api/api-v3/hal-resources/collection-resource.service"; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {HelpTextResource} from 'core-app/modules/hal/resources/help-text-resource'; export class HelpTextDmService { constructor(protected halRequest:HalRequestService, protected v3Path:any) { } - public loadAll():ng.IPromise> { - return this.halRequest.get(this.v3Path.help_texts()); + public loadAll():Promise> { + return this.halRequest + .get>(this.v3Path.help_texts()) + .toPromise(); } - public load(helpTextId:string):ng.IPromise { - return this.halRequest.get(this.v3Path.help_texts({ id: helpTextId})); + public load(helpTextId:string):Promise { + return this.halRequest + .get(this.v3Path.help_texts({ id: helpTextId})) + .toPromise(); } } - -opApiModule.service('helpTextDm', HelpTextDmService); diff --git a/frontend/app/components/api/api-v3/hal-resource-dms/payload-dm.service.ts b/frontend/app/modules/dm-services/payload-dm.service.ts similarity index 88% rename from frontend/app/components/api/api-v3/hal-resource-dms/payload-dm.service.ts rename to frontend/app/modules/dm-services/payload-dm.service.ts index 00ec4a9aea..45adfe39ef 100644 --- a/frontend/app/components/api/api-v3/hal-resource-dms/payload-dm.service.ts +++ b/frontend/app/modules/dm-services/payload-dm.service.ts @@ -26,11 +26,11 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {FormResource} from '../hal-resources/form-resource.service'; -import {SchemaResource} from '../hal-resources/schema-resource.service'; -import {HalResource} from '../hal-resources/hal-resource.service'; -import {opApiModule} from '../../../../angular-modules'; +import {Injectable} from '@angular/core'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; +@Injectable() export class PayloadDmService { public extract(resource:T, schema:SchemaResource) { let payload:any = { @@ -76,5 +76,3 @@ export class PayloadDmService { return payload; } } - -opApiModule.service('PayloadDm', PayloadDmService); diff --git a/frontend/app/components/api/api-v3/hal-resource-dms/query-dm.service.ts b/frontend/app/modules/dm-services/query-dm.service.ts similarity index 64% rename from frontend/app/components/api/api-v3/hal-resource-dms/query-dm.service.ts rename to frontend/app/modules/dm-services/query-dm.service.ts index 87a68ec6ed..9ee41a15bf 100644 --- a/frontend/app/components/api/api-v3/hal-resource-dms/query-dm.service.ts +++ b/frontend/app/modules/dm-services/query-dm.service.ts @@ -26,15 +26,15 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {QueryResource} from '../hal-resources/query-resource.service'; -import {CollectionResource} from '../hal-resources/collection-resource.service'; -import {WorkPackageCollectionResource} from '../hal-resources/wp-collection-resource.service'; -import {FormResource} from '../hal-resources/form-resource.service'; -import {opApiModule} from '../../../../angular-modules'; -import {HalRequestService} from '../hal-request/hal-request.service'; -import {PayloadDmService} from './payload-dm.service'; -import {ApiV3FilterBuilder} from '../api-v3-filter-builder'; -import {QueryFormResource} from "core-components/api/api-v3/hal-resources/query-form-resource.service"; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; +import {PayloadDmService} from 'core-app/modules/dm-services/payload-dm.service'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource'; +import {QueryFormResource} from 'core-app/modules/hal/resources/query-form-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {ApiV3FilterBuilder} from 'core-components/api/api-v3/api-v3-filter-builder'; +import {v3PathToken} from 'core-app/angular4-transition-utils'; +import {Inject} from '@angular/core'; export interface PaginationObject { pageSize:number; @@ -43,13 +43,12 @@ export interface PaginationObject { export class QueryDmService { constructor(protected halRequest:HalRequestService, - protected v3Path:any, + @Inject(v3PathToken) protected v3Path:any, protected UrlParamsHelper:any, - protected PayloadDm:PayloadDmService, - protected $q:ng.IQService) { + protected PayloadDm:PayloadDmService) { } - public find(queryData:Object, queryId?:string, projectIdentifier?:string):ng.IPromise { + public find(queryData:Object, queryId?:string, projectIdentifier?:string):Promise { let path:string; if (queryId) { @@ -58,24 +57,24 @@ export class QueryDmService { path = this.v3Path.queries.default({project: projectIdentifier}); } - return this.halRequest.get(path, - queryData, - {caching: {enabled: false} }); + return this.halRequest + .get(path, queryData) + .toPromise(); } - public findDefault(queryData:Object, projectIdentifier?:string):ng.IPromise { + public findDefault(queryData:Object, projectIdentifier?:string):Promise { return this.find(queryData, undefined, projectIdentifier); } - public reload(query:QueryResource, pagination:PaginationObject):ng.IPromise { + public reload(query:QueryResource, pagination:PaginationObject):Promise { let path = this.v3Path.queries({query: query.id}); - return this.halRequest.get(path, - pagination, - {caching: {enabled: false} }); + return this.halRequest + .get(path, pagination) + .toPromise(); } - public loadResults(query:QueryResource, pagination:PaginationObject):ng.IPromise { + public loadResults(query:QueryResource, pagination:PaginationObject):Promise { if (!query.results) { throw 'No results embedded when expected'; } @@ -84,10 +83,12 @@ export class QueryDmService { var url = URI(query.results.href!).path(); - return this.halRequest.get(url, queryData, {caching: {enabled: false} }); + return this.halRequest + .get(url, queryData, {caching: {enabled: false} }) + .toPromise(); } - public loadIdsUpdatedSince(ids:any, timestamp:any):ng.IPromise { + public loadIdsUpdatedSince(ids:any, timestamp:any):Promise { const filters = [ { id: { @@ -103,9 +104,9 @@ export class QueryDmService { } ]; - return this.halRequest.get(this.v3Path.wps(), - {filters: JSON.stringify(filters)}, - {caching: {enabled: false} }); + return this.halRequest + .get(this.v3Path.wps(), {filters: JSON.stringify(filters)}) + .toPromise(); } public async update(query:QueryResource, form:QueryFormResource) { @@ -114,6 +115,7 @@ export class QueryDmService { .then(payload => { let path = this.v3Path.queries({ query: query.id }); this.halRequest.patch(path, payload) + .toPromise() .then(resolve) .catch(reject) }) @@ -121,11 +123,13 @@ export class QueryDmService { }); } - public create(query:QueryResource, form:QueryFormResource):ng.IPromise { + public create(query:QueryResource, form:QueryFormResource):Promise { return this.extractPayload(query, form).then(payload => { let path = this.v3Path.queries(); - return this.halRequest.post(path, payload); + return this.halRequest + .post(path, payload) + .toPromise(); }); } @@ -141,7 +145,7 @@ export class QueryDmService { } } - public all(projectIdentifier?:string):ng.IPromise { + public all(projectIdentifier?:string):Promise { let filters = new ApiV3FilterBuilder(); if (projectIdentifier) { @@ -155,18 +159,18 @@ export class QueryDmService { let urlQuery = { filters: filters.toJson() }; let caching = { caching: {enabled: false} }; - return this.halRequest.get(this.v3Path.queries(), - urlQuery, - caching); + return this.halRequest + .get(this.v3Path.queries(), urlQuery) + .toPromise(); } - private extractPayload(query:QueryResource, form:QueryFormResource) { + private extractPayload(query:QueryResource, form:QueryFormResource):Promise { // Extracting requires having the filter schemas loaded as the dependencies // need to be present. This should be handled within the cached information however, so it is fast. - return this.$q.all(_.map(query.filters, filter => filter.schema.$load())).then(() => { - return this.PayloadDm.extract(query, form.schema); - }); + const promises = _.map(query.filters, filter => filter.schema.$load()); + + return Promise + .all(promises) + .then(() => this.PayloadDm.extract(query, form.schema)); } } - -opApiModule.service('QueryDm', QueryDmService); diff --git a/frontend/app/components/api/api-v3/hal-resource-dms/query-form-dm.service.ts b/frontend/app/modules/dm-services/query-form-dm.service.ts similarity index 80% rename from frontend/app/components/api/api-v3/hal-resource-dms/query-form-dm.service.ts rename to frontend/app/modules/dm-services/query-form-dm.service.ts index 4d4397ae7b..366ec89d95 100644 --- a/frontend/app/components/api/api-v3/hal-resource-dms/query-form-dm.service.ts +++ b/frontend/app/modules/dm-services/query-form-dm.service.ts @@ -26,20 +26,19 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {QueryFormResource} from '../hal-resources/query-form-resource.service'; -import {QueryResource} from '../hal-resources/query-resource.service'; -import {opApiModule} from '../../../../angular-modules'; -import {HalRequestService} from '../hal-request/hal-request.service'; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; import {Inject, Injectable} from '@angular/core'; -import {halRequestToken, v3PathToken} from 'core-app/angular4-transition-utils'; +import {v3PathToken} from 'core-app/angular4-transition-utils'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {QueryFormResource} from 'core-app/modules/hal/resources/query-form-resource'; @Injectable() export class QueryFormDmService { - constructor(@Inject(halRequestToken) protected halRequest:HalRequestService, + constructor(readonly halRequest:HalRequestService, @Inject(v3PathToken) protected v3Path:any) { } - public load(query:QueryResource):ng.IPromise { + public load(query:QueryResource):Promise { // We need a valid payload so that we // can check whether form saving is possible. // The query needs a name to be valid. @@ -58,7 +57,7 @@ export class QueryFormDmService { return query.$links.update(payload); } - public loadWithParams(params:{}, queryId?:number, projectIdentifier?:string):ng.IPromise { + public loadWithParams(params:{}, queryId?:number, projectIdentifier?:string):Promise { // We need a valid payload so that we // can check whether form saving is possible. // The query needs a name to be valid. @@ -86,6 +85,8 @@ export class QueryFormDmService { href = URI(href).search(params).toString(); - return this.halRequest.post(href, payload); + return this.halRequest + .post(href, payload) + .toPromise(); } } diff --git a/frontend/app/components/api/api-v3/hal-resource-dms/relations-dm.service.ts b/frontend/app/modules/dm-services/relations-dm.service.ts similarity index 57% rename from frontend/app/components/api/api-v3/hal-resource-dms/relations-dm.service.ts rename to frontend/app/modules/dm-services/relations-dm.service.ts index a712cd9af3..e013daf217 100644 --- a/frontend/app/components/api/api-v3/hal-resource-dms/relations-dm.service.ts +++ b/frontend/app/modules/dm-services/relations-dm.service.ts @@ -26,50 +26,42 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {wpDirectivesModule} from '../../../../angular-modules'; -import {HalRequestService} from '../hal-request/hal-request.service'; -import {CollectionResource} from '../hal-resources/collection-resource.service'; -import {RelationResource} from '../hal-resources/relation-resource.service'; -import {buildApiV3Filter} from '../api-v3-filter-builder'; -import {RelationResourceInterface} from "core-components/api/api-v3/hal-resources/relation-resource.service"; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; +import {Inject, Injectable} from '@angular/core'; +import {v3PathToken} from 'core-app/angular4-transition-utils'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; +import {buildApiV3Filter} from 'core-components/api/api-v3/api-v3-filter-builder'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +@Injectable() export class RelationsDmService { constructor(private halRequest:HalRequestService, - private v3Path:any, + @Inject(v3PathToken) private v3Path:any, private $q:ng.IQService) { } - public load(workPackageId:string):ng.IPromise { - return this.halRequest.get( - this.v3Path.wp.relations({wp: workPackageId}), - {}, - { - caching: {enabled: false} - }).then((collection:any) => { - return collection.elements; - }) as ng.IPromise; + public load(workPackageId:string):Promise { + return this.halRequest.get>( + this.v3Path.wp.relations({wp: workPackageId}), {}) + .toPromise() + .then((collection:CollectionResource) => collection.elements); } - public loadInvolved(workPackageIds:string[]):ng.IPromise { + public loadInvolved(workPackageIds:string[]):Promise { let validIds = _.filter(workPackageIds, id => /\d+/.test(id)); if (validIds.length === 0) { return this.$q.resolve([]); } - return this.halRequest.get( + return this.halRequest.get>( '/api/v3/relations', { filters: buildApiV3Filter('involved', '=', validIds).toJson() - }, - { - caching: {enabled: false} - }).then((collection:any) => { - return collection.elements; - }) as ng.IPromise; + }) + .toPromise() + .then((collection:CollectionResource) => collection.elements); } } - -wpDirectivesModule.service('relationsDm', RelationsDmService); diff --git a/frontend/app/components/api/api-v3/hal-resource-dms/root-dm.service.ts b/frontend/app/modules/dm-services/root-dm.service.ts similarity index 73% rename from frontend/app/components/api/api-v3/hal-resource-dms/root-dm.service.ts rename to frontend/app/modules/dm-services/root-dm.service.ts index 41c148f0cc..0759a09aff 100644 --- a/frontend/app/components/api/api-v3/hal-resource-dms/root-dm.service.ts +++ b/frontend/app/modules/dm-services/root-dm.service.ts @@ -26,18 +26,20 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {opApiModule} from '../../../../angular-modules'; -import {RootResource} from '../hal-resources/root-resource.service'; -import {HalRequestService} from '../hal-request/hal-request.service'; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; +import {Inject, Injectable} from '@angular/core'; +import {v3PathToken} from 'core-app/angular4-transition-utils'; +import {RootResource} from 'core-app/modules/hal/resources/root-resource'; +@Injectable() export class RootDmService { constructor(protected halRequest:HalRequestService, - protected v3Path:any) { + @Inject(v3PathToken) protected v3Path:any) { } - public load():ng.IPromise { - return this.halRequest.get(this.v3Path.root()); + public load():Promise { + return this.halRequest + .get(this.v3Path.root()) + .toPromise(); } } - -opApiModule.service('RootDm', RootDmService); diff --git a/frontend/app/components/api/api-v3/hal-resources/type-resource.service.ts b/frontend/app/modules/dm-services/type-dm.service.ts similarity index 51% rename from frontend/app/components/api/api-v3/hal-resources/type-resource.service.ts rename to frontend/app/modules/dm-services/type-dm.service.ts index 8bee34fe3b..6c49240489 100644 --- a/frontend/app/components/api/api-v3/hal-resources/type-resource.service.ts +++ b/frontend/app/modules/dm-services/type-dm.service.ts @@ -26,52 +26,37 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {opApiModule} from "../../../../angular-modules"; -import {States} from "../../../states.service"; -import {HalRequestService} from "../hal-request/hal-request.service"; -import {CollectionResource} from "./collection-resource.service"; -import {HalResource} from "./hal-resource.service"; -import {InputState, State} from "reactivestates"; - -var states: States; -var halRequest: HalRequestService; -var v3Path:any; - -export class TypeResource extends HalResource { - public color:string; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; +import {Inject, Injectable} from '@angular/core'; +import {v3PathToken} from 'core-app/angular4-transition-utils'; +import {RootResource} from 'core-app/modules/hal/resources/root-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {TypeResource} from 'core-app/modules/hal/resources/type-resource'; +import {States} from 'core-components/states.service'; + +@Injectable() +export class TypeDmService { + constructor(protected halRequest:HalRequestService, + protected states:States, + @Inject(v3PathToken) protected v3Path:any) { + } - public static loadAll():ng.IPromise { - const types = states.types; - const typeUrl = v3Path.types(); + public loadAll():Promise { + const typeUrl = this.v3Path.types(); - return halRequest.get>(typeUrl) + return this.halRequest + .get>(typeUrl) + .toPromise() .then((result:CollectionResource) => { - result.elements.forEach((value:TypeResource) => { - types.get(value.href as string).putValue(value); + // TODO move into a TypeCacheService + _.each(result.elements, (type) => this.states.types.get(type.href!).putValue(type)); + return result.elements; }); - }); } - // @ts-ignore - // TS2416: Property 'state' in type 'TypeResource' is not assignable to the same property in base type 'HalResource'. - public get state() { - return states.types.get(this.href as string); + public load():Promise { + return this.halRequest + .get(this.v3Path.root()) + .toPromise(); } } - -function typeResource(...args:any[]) { - [ - states, - halRequest, - v3Path - ] = args; - return TypeResource; -} - -typeResource.$inject = [ - 'states', - 'halRequest', - 'v3Path' -]; - -opApiModule.factory('TypeResource', typeResource); diff --git a/frontend/app/modules/hal/hal-link/hal-link.service.ts b/frontend/app/modules/hal/hal-link/hal-link.service.ts new file mode 100644 index 0000000000..7a596b5a59 --- /dev/null +++ b/frontend/app/modules/hal/hal-link/hal-link.service.ts @@ -0,0 +1,64 @@ +//-- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See doc/COPYRIGHT.rdoc for more details. +//++ + +import {Injectable} from '@angular/core'; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; +import {CallableHalLink, HalLink, HalLinkInterface} from 'core-app/modules/hal/hal-link/hal-link'; + +@Injectable() +export class HalLinkService { + + constructor(readonly halRequestService:HalRequestService) { + } + + /** + * Create the HalLink from an object with the HalLinkInterface. + */ + public fromObject(link:HalLinkInterface):HalLink { + return new HalLink( + this, + link.href, + link.title, + link.method, + link.templated, + link.payload, + link.type, + link.identifier + ); + } + + /** + * Return a function that fetches the resource. + */ + public callable(link:HalLinkInterface):CallableHalLink { + return this.fromObject(link).$callable(); + } + + +} + diff --git a/frontend/app/components/api/api-v3/hal-link/hal-link.service.ts b/frontend/app/modules/hal/hal-link/hal-link.ts similarity index 65% rename from frontend/app/components/api/api-v3/hal-link/hal-link.service.ts rename to frontend/app/modules/hal/hal-link/hal-link.ts index 9f8a576d17..695958954f 100644 --- a/frontend/app/components/api/api-v3/hal-link/hal-link.service.ts +++ b/frontend/app/modules/hal/hal-link/hal-link.ts @@ -1,6 +1,6 @@ //-- copyright // OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +// Copyright (C) 2012-2018 the OpenProject Foundation (OPF) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License version 3. @@ -26,17 +26,16 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {opApiModule} from '../../../../angular-modules'; -import {HalRequestService} from '../hal-request/hal-request.service'; -import {HalResource} from '../hal-resources/hal-resource.service'; -import FunctionBind = _.FunctionBind; - -var $q:ng.IQService; -var halRequest:HalRequestService; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import { + HalRequestService, + HTTPSupportedMethods +} from 'core-app/modules/hal/services/hal-request.service'; +import {HalLinkService} from 'core-app/modules/hal/hal-link/hal-link.service'; export interface HalLinkInterface { href:string|null; - method:string; + method:HTTPSupportedMethods; title?:string; templated?:boolean; payload?:any; @@ -44,36 +43,15 @@ export interface HalLinkInterface { identifier?:string; } -interface CallableHalLink extends HalLinkInterface { - data?:ng.IPromise; +export interface CallableHalLink extends HalLinkInterface { + data?:Promise; } export class HalLink implements HalLinkInterface { - /** - * Create the HalLink from an object with the HalLinkInterface. - */ - public static fromObject(link:HalLinkInterface):HalLink { - return new HalLink( - link.href, - link.title, - link.method, - link.templated, - link.payload, - link.type, - link.identifier - ); - } - - /** - * Return a function that fetches the resource. - */ - public static callable(link:HalLinkInterface):CallableHalLink { - return HalLink.fromObject(link).$callable(); - } - - constructor(public href:string|null = null, + constructor(public halLinkService:HalLinkService, + public href:string|null = null, public title:string = '', - public method:string = 'get', + public method:HTTPSupportedMethods = 'get', public templated:boolean = false, public payload?:any, public type:string = 'application/json', @@ -83,9 +61,11 @@ export class HalLink implements HalLinkInterface { /** * Fetch the resource. */ - public $fetch(...params:any[]):ng.IPromise { + public $fetch(...params:any[]):Promise { const [data, headers] = params; - return halRequest.request(this.method, this.href as string, data, headers); + return this.halLinkService.halRequestService + .request(this.method, this.href as string, data, headers) + .toPromise(); } /** @@ -93,7 +73,7 @@ export class HalLink implements HalLinkInterface { * * @returns {CallableHalLink} */ - public $prepare(templateValues:{[templateKey:string]: string}) { + public $prepare(templateValues:{ [templateKey:string]:string }) { if (!this.templated) { throw 'The link ' + this.href + ' is not templated.'; } @@ -104,7 +84,7 @@ export class HalLink implements HalLinkInterface { href = href.replace(regexp, value); }); - return HalLink.callable({ + return this.halLinkService.callable({ href: href, title: this.title, method: this.method, @@ -136,14 +116,4 @@ export class HalLink implements HalLinkInterface { return linkFunc; } - } - -function halLinkService(...args:any[]) { - [$q, halRequest] = args; - return HalLink; -} - -halLinkService.$inject = ['$q', 'halRequest']; - -opApiModule.factory('HalLink', halLinkService); diff --git a/frontend/app/modules/hal/helpers/hal-resource-builder.ts b/frontend/app/modules/hal/helpers/hal-resource-builder.ts new file mode 100644 index 0000000000..4c639bea1f --- /dev/null +++ b/frontend/app/modules/hal/helpers/hal-resource-builder.ts @@ -0,0 +1,162 @@ +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {OpenprojectHalModuleHelpers} from 'core-app/modules/hal/helpers/lazy-accessor'; +import {HalLinkService} from 'core-app/modules/hal/hal-link/hal-link.service'; +import {HalResourceFactoryService} from 'core-app/modules/hal/services/hal-resource-factory.service'; + +const ObservableArray:any = require('observable-array'); + +export function initializeHalResource(halResource:HalResource, + halResourceFactory:HalResourceFactoryService, + halLinkService:HalLinkService) { + setSource(); + setupLinks(); + setupEmbedded(); + proxyProperties(); + setLinksAsProperties(); + setEmbeddedAsProperties(); + + function setSource() { + if (!halResource.$source._links) { + halResource.$source._links = {}; + } + + if (!halResource.$source._links.self) { + halResource.$source._links.self = {href: null}; + } + } + + function proxyProperties() { + halResource.$embeddableKeys().forEach((property:any) => { + Object.defineProperty(halResource, property, { + get() { + return halResource.$source[property]; + }, + + set(value) { + halResource.$source[property] = value; + }, + + enumerable: true, + configurable: true + }); + }); + } + + function setLinksAsProperties() { + halResource.$linkableKeys().forEach((linkName:string) => { + OpenprojectHalModuleHelpers.lazy(halResource, linkName, + () => { + const link:any = halResource.$links[linkName].$link || halResource.$links[linkName]; + + if (Array.isArray(link)) { + var items = link.map(item => halResource.createLinkedResource(linkName, item.$link)); + var property:HalResource[] = new ObservableArray(...items).on('change', () => { + property.forEach(item => { + if (!item.$link) { + property.splice(property.indexOf(item), 1); + } + }); + + halResource.$source._links[linkName] = property.map(item => item.$link); + }); + + return property; + } + + if (link.href) { + if (link.method !== 'get') { + return halLinkService.callable(link); + } + + return halResource.createLinkedResource(linkName, link); + } + + return null; + }, + (val:any) => setter(val, linkName) + ); + }); + } + + function setEmbeddedAsProperties() { + if (!halResource.$source._embedded) { + return; + } + + Object.keys(halResource.$source._embedded).forEach(name => { + OpenprojectHalModuleHelpers.lazy(halResource, + name, + () => halResource.$embedded[name], + (val:any) => setter(val, name)); + }); + } + + function setupProperty(name:string, callback:(element:any) => any) { + const instanceName = '$' + name; + const sourceName = '_' + name; + const sourceObj = halResource.$source[sourceName]; + + if (angular.isObject(sourceObj)) { + Object.keys(sourceObj).forEach(propName => { + OpenprojectHalModuleHelpers.lazy((halResource as any)[instanceName], + propName, + () => callback(sourceObj[propName])); + }); + } + } + + function setupLinks() { + setupProperty('links', + (link) => { + if (Array.isArray(link)) { + return link.map(l => halLinkService.callable(l)); + } else { + return halLinkService.callable(link); + } + }); + } + + function setupEmbedded() { + setupProperty('embedded', element => { + angular.forEach(element, (child:any, name:string) => { + if (child && (child._embedded || child._links)) { + OpenprojectHalModuleHelpers.lazy(element, + name, + () => halResourceFactory.createHalResource(child)); + } + }); + + if (Array.isArray(element)) { + return element.map((source) => halResourceFactory.createHalResource(source, + true)); + } + + return halResourceFactory.createHalResource(element); + }); + } + + function setter(val:HalResource|{ href?:string }, linkName:string) { + if (!val) { + halResource.$source._links[linkName] = {href: null}; + } else if (_.isArray(val)) { + halResource.$source._links[linkName] = val.map((el:any) => { + return {href: el.href} + }); + } else if (val.hasOwnProperty('$link')) { + const link = (val as HalResource).$link; + + if (link.href) { + halResource.$source._links[linkName] = link; + } + } else if ('href' in val) { + halResource.$source._links[linkName] = {href: val.href}; + } + + if (halResource.$embedded && halResource.$embedded[linkName]) { + halResource.$embedded[linkName] = val; + halResource.$source._embedded[linkName] = _.get(val, '$source', val); + } + + return val; + } +} diff --git a/frontend/app/modules/hal/helpers/lazy-accessor.ts b/frontend/app/modules/hal/helpers/lazy-accessor.ts new file mode 100644 index 0000000000..d5e45d82e1 --- /dev/null +++ b/frontend/app/modules/hal/helpers/lazy-accessor.ts @@ -0,0 +1,64 @@ +// -- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See doc/COPYRIGHT.rdoc for more details. +// ++ + +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; + +export namespace OpenprojectHalModuleHelpers { + export function lazy(obj:HalResource, + property:string, + getter:{ ():any }, + setter?:{ (value:any):void }):void { + + if (_.isObject(obj)) { + let done = false; + let value:any; + let config:any = { + get() { + if (!done) { + value = getter(); + done = true; + } + return value; + }, + set: ():void => undefined, + + configurable: true, + enumerable: true + }; + + if (setter) { + config.set = (val:any) => { + value = setter(val); + done = true; + }; + } + + Object.defineProperty(obj, property, config); + } + } +} diff --git a/frontend/app/modules/hal/openproject-hal.module.ts b/frontend/app/modules/hal/openproject-hal.module.ts new file mode 100644 index 0000000000..755d617441 --- /dev/null +++ b/frontend/app/modules/hal/openproject-hal.module.ts @@ -0,0 +1,46 @@ +// -- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2018 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See doc/COPYRIGHT.rdoc for more details. +// ++ + +import {NgModule} from '@angular/core'; +import {HalLinkService} from 'core-app/modules/hal/hal-link/hal-link.service'; +import {HttpClientModule} from '@angular/common/http'; +import {BrowserModule} from '@angular/platform-browser'; +import {HalRequestService} from 'core-app/modules/hal/services/hal-request.service'; +import {HalResourceFactoryService} from 'core-app/modules/hal/services/hal-resource-factory.service'; + +@NgModule({ + providers: [ + BrowserModule, + HttpClientModule, + HalLinkService, + HalRequestService, + HalResourceFactoryService, + ] +}) +export class OpenprojectHalModule { } + diff --git a/frontend/app/components/api/api-v3/hal-resources/form-resource.service.ts b/frontend/app/modules/hal/resources/attachment-collection-resource.ts similarity index 64% rename from frontend/app/components/api/api-v3/hal-resources/form-resource.service.ts rename to frontend/app/modules/hal/resources/attachment-collection-resource.ts index a421292002..a6e36849d8 100644 --- a/frontend/app/components/api/api-v3/hal-resources/form-resource.service.ts +++ b/frontend/app/modules/hal/resources/attachment-collection-resource.ts @@ -26,26 +26,23 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from './hal-resource.service'; -import {SchemaResource} from './schema-resource.service'; -import {opApiModule} from '../../../../angular-modules'; -import {ErrorResource} from './error-resource.service'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {UploadFile, UploadResult} from 'core-components/api/op-file-upload/op-file-upload.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; -interface FormResourceEmbedded { -} - -export class FormResource extends HalResource { +export class AttachmentCollectionResource extends CollectionResource { - public $embedded:FormResourceEmbedded; - public schema:SchemaResource; - public validationErrors:{ [attribute:string]:ErrorResource }; -} + readonly opFileUplaod = this.injector.get('opFileUploadToken'); // TODO -function formResource() { - return FormResource; + /** + * Upload the given files to the $href property of this resource. + */ + public upload(files:UploadFile[]):UploadResult { + return this.opFileUpload.upload(this.$href as string, files); + } } -export interface FormResourceInterface extends FormResource { +export interface AttachmentCollectionResource { + elements:HalResource[]; } -opApiModule.factory('FormResource', formResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/collection-resource.service.ts b/frontend/app/modules/hal/resources/collection-resource.ts similarity index 73% rename from frontend/app/components/api/api-v3/hal-resources/collection-resource.service.ts rename to frontend/app/modules/hal/resources/collection-resource.ts index 5efb92169e..82e4f49d30 100644 --- a/frontend/app/components/api/api-v3/hal-resources/collection-resource.service.ts +++ b/frontend/app/modules/hal/resources/collection-resource.ts @@ -26,27 +26,20 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from './hal-resource.service'; -import {opApiModule} from '../../../../angular-modules'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; -export class CollectionResource extends HalResource { - public elements: T[]; - public count: number; - public total: number; - public pageSize: number; - public offset: number; +export class CollectionResource extends HalResource { + public elements:T[]; + public count:number; + public total:number; + public pageSize:number; + public offset:number; /** * Update the collection's elements and return them in a promise. * This is useful, as angular does not recognize update made by $load. */ public updateElements() { - return this.$load().then((collection:this) => this.elements = collection.elements); + return this.$load().then((collection:this) => this.elements = collection.elements); } } - -function collectionResource() { - return CollectionResource; -} - -opApiModule.factory('CollectionResource', collectionResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/configuration-resource.service.ts b/frontend/app/modules/hal/resources/configuration-resource.ts similarity index 72% rename from frontend/app/components/api/api-v3/hal-resources/configuration-resource.service.ts rename to frontend/app/modules/hal/resources/configuration-resource.ts index 1fba8fbc2f..d800efb620 100644 --- a/frontend/app/components/api/api-v3/hal-resources/configuration-resource.service.ts +++ b/frontend/app/modules/hal/resources/configuration-resource.ts @@ -26,23 +26,9 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from './hal-resource.service'; -import {opApiModule} from '../../../../angular-modules'; - -interface ConfigurationResourceEmbedded { -} +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export class ConfigurationResource extends HalResource { - public $embedded: ConfigurationResourceEmbedded; - public perPageOptions: Array -} - -function configurationResource() { - return ConfigurationResource; + public perPageOptions:Array; } - -export interface ConfigurationResourceInterface extends ConfigurationResourceEmbedded, ConfigurationResource { -} - -opApiModule.factory('ConfigurationResource', configurationResource); diff --git a/frontend/app/modules/hal/resources/custom-action-resource.ts b/frontend/app/modules/hal/resources/custom-action-resource.ts new file mode 100644 index 0000000000..75e4dd555b --- /dev/null +++ b/frontend/app/modules/hal/resources/custom-action-resource.ts @@ -0,0 +1,44 @@ +//-- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See doc/COPYRIGHT.rdoc for more details. +//++ + +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; + +interface CustomActionResourceLinks { + self():Promise; + executeImmediately(payload:any):Promise; +} + +export class CustomActionResource extends HalResource { + public id:number; + public name:string; + public description:string; +} + +export interface CustomActionResource extends CustomActionResourceLinks { +} diff --git a/frontend/app/components/api/api-v3/hal-resources/error-resource.service.ts b/frontend/app/modules/hal/resources/error-resource.ts similarity index 80% rename from frontend/app/components/api/api-v3/hal-resources/error-resource.service.ts rename to frontend/app/modules/hal/resources/error-resource.ts index fc43099bed..f7580ca1cc 100644 --- a/frontend/app/components/api/api-v3/hal-resources/error-resource.service.ts +++ b/frontend/app/modules/hal/resources/error-resource.ts @@ -26,9 +26,8 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from './hal-resource.service'; -import {opApiModule} from '../../../../angular-modules'; -import {FormResourceInterface} from './form-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {FormResource} from 'core-app/modules/hal/resources/form-resource'; export const v3ErrorIdentifierQueryInvalid = 'urn:openproject-org:api:v3:errors:InvalidQuery'; export const v3ErrorIdentifierMultipleErrors = 'urn:openproject-org:api:v3:errors:MultipleErrors'; @@ -41,26 +40,6 @@ export class ErrorResource extends HalResource { public isValidationError:boolean = false; - public static fromFormResponse(form:FormResourceInterface):ErrorResource|null { - const errors = _.values(form.validationErrors); - const count = errors.length; - - if (count === 0) { - return null; - } - - let resource ; - if (count === 1) { - resource = new ErrorResource(errors[0], true); - } else { - resource = new ErrorResource({}); - resource.errorIdentifier = v3ErrorIdentifierMultipleErrors; - resource.errors = errors; - } - resource.isValidationError = true; - return resource; - } - public get errorMessages():string[] { if (this.isMultiErrorMessage()) { return this.errors.map(error => error.message); @@ -123,9 +102,3 @@ export class ErrorResource extends HalResource { return [attribute, messages]; } } - -function errorResourceService() { - return ErrorResource; -} - -opApiModule.factory('ErrorResource', errorResourceService); diff --git a/frontend/app/modules/hal/resources/form-resource.ts b/frontend/app/modules/hal/resources/form-resource.ts new file mode 100644 index 0000000000..f2f81b2269 --- /dev/null +++ b/frontend/app/modules/hal/resources/form-resource.ts @@ -0,0 +1,60 @@ +//-- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See doc/COPYRIGHT.rdoc for more details. +//++ + +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; +import { + ErrorResource, + v3ErrorIdentifierMultipleErrors +} from 'core-app/modules/hal/resources/error-resource'; + +export class FormResource extends HalResource { + + public schema:SchemaResource; + public validationErrors:{ [attribute:string]:ErrorResource }; + + public getErrors():ErrorResource|null { + const errors = _.values(this.validationErrors); + const count = errors.length; + + if (count === 0) { + return null; + } + + let resource; + if (count === 1) { + resource = new ErrorResource(this.injector, errors[0], true); + } else { + resource = new ErrorResource(this.injector, {}); + resource.errorIdentifier = v3ErrorIdentifierMultipleErrors; + resource.errors = errors; + } + resource.isValidationError = true; + return resource; + } +} diff --git a/frontend/app/modules/hal/resources/hal-resource.ts b/frontend/app/modules/hal/resources/hal-resource.ts new file mode 100644 index 0000000000..3c3f25c474 --- /dev/null +++ b/frontend/app/modules/hal/resources/hal-resource.ts @@ -0,0 +1,209 @@ +//-- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See doc/COPYRIGHT.rdoc for more details. +//++ + +import {InputState} from "reactivestates"; +import {HalResourceFactoryService} from 'core-app/modules/hal/services/hal-resource-factory.service'; +import {HalLinkInterface} from 'core-app/modules/hal/hal-link/hal-link'; +import {HalLinkService} from 'core-app/modules/hal/hal-link/hal-link.service'; +import {Injector} from '@angular/core'; +import {States} from 'core-components/states.service'; +import {I18nToken} from 'core-app/angular4-transition-utils'; +import {initializeHalResource} from 'core-app/modules/hal/helpers/hal-resource-builder'; + +export class HalResource { + [attribute:string]:any; + public _type:string; + + protected readonly halLinkService:HalLinkService = this.injector.get(HalLinkService); + protected readonly halResourceFactory:HalResourceFactoryService = this.injector.get(HalResourceFactoryService); + protected readonly states:States = this.injector.get(States); + protected readonly I18n:op.I18n = this.injector.get(I18nToken); + + constructor(public injector:Injector, + public $source:any = HalResource.getEmptyResource(), + public $loaded:boolean = true) { + this.$initialize($source); + } + + public static get attributeTypes():{[attrName:string]:string} { + return {}; + } + + public static getEmptyResource(self:{ href:string|null } = {href: null}):any { + return {_links: {self: self}}; + } + + public $links:any = {}; + public $embedded:any = {}; + public $self:Promise; + + public _name:string; + + public static idFromLink(href:string):string { + return href.split('/').pop()!; + } + + public get idFromLink():string { + if (this.$href) { + return HalResource.idFromLink(this.$href); + } + + return ''; + } + + public get $isHal():boolean { + return true; + } + + public get $link():HalLinkInterface { + return this.$links.self.$link; + } + + public get name():string { + return this._name || this.$link.title || ''; + } + + public set name(name:string) { + this._name = name; + } + + /** + * Alias for $href. + * Please use $href instead. + * + * @deprecated + */ + public get href():string|null { + return this.$link.href; + } + + public get $href():string|null { + return this.$link.href; + } + + /** + * Return the associated state to this HAL resource, if any. + */ + public get state():InputState|null { + return null; + } + + public $load(force = false):Promise { + if (!this.state) { + return this.$loadResource(force); + } + + const state = this.state; + + if (force) { + state.clear(); + } + + // If nobody has asked yet for the resource to be $loaded, do it ourselves. + // Otherwise, we risk returning a promise, that will never be resolved. + state.putFromPromiseIfPristine(() => this.$loadResource(force)); + + return > state.valuesPromise().then(source => { + this.$initialize(source); + this.$loaded = true; + return this; + }); + } + + protected $loadResource(force = false):Promise { + if (!force) { + if (this.$loaded) { + return Promise.resolve(this); + } + + if (!this.$loaded && this.$self) { + return this.$self; + } + } + + // Reset and load this resource + this.$loaded = false; + this.$self = this.$links.self({}).then((source:any) => { + this.$loaded = true; + this.$initialize(source); + return this; + }); + + return this.$self; + } + + /** + * Update the resource ignoring the cache. + */ + public $update() { + return this.$load(true); + } + + public $plain() { + return angular.copy(this.$source); + } + + public $copy():this { + const copy = _.cloneDeep(this.$source); + return this.halResourceFactory.createHalResource(copy, this.$loaded) as this; + } + + public $initialize(source:any) { + this.$source = source.$source || source; + initializeHalResource(this, this.halResourceFactory, this.halLinkService); + } + + /** + * Specify this resource's embedded keys that should be transformed with resources. + * Use this to restrict, e.g., links that should not be made properties if you have a custom get/setter. + */ + public $embeddableKeys():string[] { + const properties = Object.keys(this.$source); + return _.without(properties, '_links', '_embedded'); + } + + /** + * Specify this resource's keys that should not be transformed with resources. + * Use this to restrict, e.g., links that should not be made properties if you have a custom get/setter. + */ + public $linkableKeys():string[] { + const properties = Object.keys(this.$links); + return _.without(properties, 'self'); + } + + /** + * Get a linked resource from its HalLink with the correct ype + */ + public createLinkedResource(linkName:string, link:HalLinkInterface) { + const resource = HalResource.getEmptyResource(); + const type = this.constructor._type; + resource._links.self = link; + + return this.halResourceFactory.createLinkedHalResource(resource, type, linkName); + } +} diff --git a/frontend/app/components/api/api-v3/hal-resources/help-text-resource.service.ts b/frontend/app/modules/hal/resources/help-text-resource.ts similarity index 77% rename from frontend/app/components/api/api-v3/hal-resources/help-text-resource.service.ts rename to frontend/app/modules/hal/resources/help-text-resource.ts index 7e2ae535a8..badaa0234d 100644 --- a/frontend/app/components/api/api-v3/hal-resources/help-text-resource.service.ts +++ b/frontend/app/modules/hal/resources/help-text-resource.ts @@ -26,10 +26,8 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from './hal-resource.service'; -import {UserResource} from './user-resource.service'; -import {opApiModule} from '../../../../angular-modules'; -import {HalLink} from '../hal-link/hal-link.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {HalLink} from 'core-app/modules/hal/hal-link/hal-link'; export class HelpTextResource extends HalResource { @@ -39,12 +37,6 @@ export class HelpTextResource extends HalResource { public scope:string; } -export interface HelpTextResourceInterface extends HelpTextResource { +export interface HelpTextResource { editText?:HalLink; } - -function helpTextResource() { - return HelpTextResource; -} - -opApiModule.factory('HelpTextResource', helpTextResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/project-resource.service.ts b/frontend/app/modules/hal/resources/project-resource.ts similarity index 77% rename from frontend/app/components/api/api-v3/hal-resources/project-resource.service.ts rename to frontend/app/modules/hal/resources/project-resource.ts index 44dc4899e2..3b68b73b90 100644 --- a/frontend/app/components/api/api-v3/hal-resources/project-resource.service.ts +++ b/frontend/app/modules/hal/resources/project-resource.ts @@ -26,22 +26,7 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from './hal-resource.service'; -import {opApiModule} from '../../../../angular-modules'; - -interface ProjectResourceEmbedded { -} +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export class ProjectResource extends HalResource { - - public $embedded: ProjectResourceEmbedded; -} - -function projectResource() { - return ProjectResource; -} - -export interface ProjectResourceInterface extends ProjectResource { } - -opApiModule.factory('ProjectResource', projectResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/query-filter-instance-resource.service.ts b/frontend/app/modules/hal/resources/query-filter-instance-resource.ts similarity index 77% rename from frontend/app/components/api/api-v3/hal-resources/query-filter-instance-resource.service.ts rename to frontend/app/modules/hal/resources/query-filter-instance-resource.ts index df8a5c47c1..40de1d6cfd 100644 --- a/frontend/app/components/api/api-v3/hal-resources/query-filter-instance-resource.service.ts +++ b/frontend/app/modules/hal/resources/query-filter-instance-resource.ts @@ -26,25 +26,12 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from './hal-resource.service'; -import {opApiModule} from '../../../../angular-modules'; -import {QueryFilterResource} from './query-filter-resource.service'; -import {QueryOperatorResource} from './query-operator-resource.service'; -import {QueryFilterInstanceSchemaResource} from './query-filter-instance-schema-resource.service'; - -interface QueryFilterInstanceResourceEmbedded { - filter:QueryFilterResource; - schema:QueryFilterInstanceSchemaResource; -} - -interface QueryFilterInstanceResourceLinks extends QueryFilterInstanceResourceEmbedded { -} +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {QueryFilterResource} from 'core-app/modules/hal/resources/query-filter-resource'; +import {QueryFilterInstanceSchemaResource} from 'core-app/modules/hal/resources/query-filter-instance-schema-resource'; +import {QueryOperatorResource} from 'core-app/modules/hal/resources/query-operator-resource'; export class QueryFilterInstanceResource extends HalResource { - - public $embedded:QueryFilterInstanceResourceEmbedded; - public $links:QueryFilterInstanceResourceLinks; - public filter:QueryFilterResource; public operator:QueryOperatorResource; public values:HalResource[]|string[]; @@ -110,12 +97,3 @@ export class QueryFilterInstanceResource extends HalResource { (dependency:any) => dependency.values && dependency.values._links && dependency.values._links.allowedValues); } } - -function queryFilterInstanceResource() { - return QueryFilterInstanceResource; -} - -export interface QueryFilterInstanceResourceInterface extends QueryFilterInstanceResourceLinks, QueryFilterInstanceResource { -} - -opApiModule.factory('QueryFilterInstanceResource', queryFilterInstanceResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/query-filter-instance-schema-resource.service.ts b/frontend/app/modules/hal/resources/query-filter-instance-schema-resource.ts similarity index 68% rename from frontend/app/components/api/api-v3/hal-resources/query-filter-instance-schema-resource.service.ts rename to frontend/app/modules/hal/resources/query-filter-instance-schema-resource.ts index 2f4ceebd28..a09f2fa460 100644 --- a/frontend/app/components/api/api-v3/hal-resources/query-filter-instance-schema-resource.service.ts +++ b/frontend/app/modules/hal/resources/query-filter-instance-schema-resource.ts @@ -26,17 +26,13 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {opApiModule} from '../../../../angular-modules'; -import {SchemaResource, SchemaAttributeObject} from './schema-resource.service'; -import {HalResource} from './hal-resource.service'; -import {QueryFilterResource} from './query-filter-resource.service'; -import {QueryOperatorResource} from './query-operator-resource.service'; -import {SchemaDependencyResource} from './schema-dependency-resource.service' - -var $q:ng.IQService; - -interface QueryFilterInstanceSchemaResourceEmbedded { -} +import {QueryFilterResource} from 'core-app/modules/hal/resources/query-filter-resource'; +import { + SchemaAttributeObject, + SchemaResource +} from 'core-app/modules/hal/resources/schema-resource'; +import {SchemaDependencyResource} from 'core-app/modules/hal/resources/schema-dependency-resource'; +import {QueryOperatorResource} from 'core-app/modules/hal/resources/query-operator-resource'; interface QueryFilterInstanceSchemaResourceLinks { filter:QueryFilterResource; @@ -44,8 +40,7 @@ interface QueryFilterInstanceSchemaResourceLinks { export class QueryFilterInstanceSchemaResource extends SchemaResource { - public $embedded: QueryFilterInstanceSchemaResourceEmbedded; - public $links: QueryFilterInstanceSchemaResourceLinks; + public $links:QueryFilterInstanceSchemaResourceLinks; public operator:SchemaAttributeObject; public filter:SchemaAttributeObject; @@ -60,7 +55,7 @@ export class QueryFilterInstanceSchemaResource extends SchemaResource { super.$initialize(source); if (source._dependencies) { - this.dependency = new SchemaDependencyResource(source._dependencies[0]); + this.dependency = new SchemaDependencyResource(this.injector, source._dependencies[0]); } } @@ -79,15 +74,6 @@ export class QueryFilterInstanceSchemaResource extends SchemaResource { _.merge(resultingSchema, staticSchema, dependentSchema); - return new QueryFilterInstanceSchemaResource(resultingSchema); + return new QueryFilterInstanceSchemaResource(this.injector, resultingSchema); } } - -function qfisResource() { - return QueryFilterInstanceSchemaResource; -} - -export interface QueryFilterInstanceSchemaResourceInterface extends QueryFilterInstanceSchemaResource { -} - -opApiModule.factory('QueryFilterInstanceSchemaResource', qfisResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/query-filter-resource.service.ts b/frontend/app/modules/hal/resources/query-filter-resource.ts similarity index 75% rename from frontend/app/components/api/api-v3/hal-resources/query-filter-resource.service.ts rename to frontend/app/modules/hal/resources/query-filter-resource.ts index de244a6651..1f534f91c4 100644 --- a/frontend/app/components/api/api-v3/hal-resources/query-filter-resource.service.ts +++ b/frontend/app/modules/hal/resources/query-filter-resource.ts @@ -26,16 +26,15 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {opApiModule} from '../../../../angular-modules'; -import {HalResource} from './hal-resource.service'; -import {QueryFilterInstanceSchemaResource} from './query-filter-instance-schema-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {QueryFilterInstanceSchemaResource} from 'core-app/modules/hal/resources/query-filter-instance-schema-resource'; interface QueryFilterResourceEmbedded { - schema: QueryFilterInstanceSchemaResource; + schema:QueryFilterInstanceSchemaResource; } export class QueryFilterResource extends HalResource { - public $embedded: QueryFilterResourceEmbedded; + public $embedded:QueryFilterResourceEmbedded; public schema:QueryFilterInstanceSchemaResource; public values:any[]; @@ -47,12 +46,3 @@ export class QueryFilterResource extends HalResource { this.$source.id = newId; } } - -function queryFilterResource() { - return QueryFilterResource; -} - -export interface QueryFilterResourceInterface extends QueryFilterResource { -} - -opApiModule.factory('QueryFilterResource', queryFilterResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/query-form-resource.service.ts b/frontend/app/modules/hal/resources/query-form-resource.ts similarity index 73% rename from frontend/app/components/api/api-v3/hal-resources/query-form-resource.service.ts rename to frontend/app/modules/hal/resources/query-form-resource.ts index e74477d97c..9dfc5def34 100644 --- a/frontend/app/components/api/api-v3/hal-resources/query-form-resource.service.ts +++ b/frontend/app/modules/hal/resources/query-form-resource.ts @@ -26,11 +26,11 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {FormResource} from './form-resource.service'; -import {CollectionResource} from './collection-resource.service'; -import {SchemaResource} from './schema-resource.service'; -import {QueryFilterInstanceSchemaResource} from './query-filter-instance-schema-resource.service'; -import {opApiModule} from '../../../../angular-modules'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {QueryFilterInstanceSchemaResource} from 'core-app/modules/hal/resources/query-filter-instance-schema-resource'; +import {FormResource} from 'core-app/modules/hal/resources/form-resource'; +import {QuerySchemaResource} from 'core-app/modules/hal/resources/query-schema-resource'; +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; interface QueryFormResourceEmbedded { filtersSchemas:CollectionResource; @@ -38,21 +38,10 @@ interface QueryFormResourceEmbedded { } export class QueryFormResource extends FormResource { - - public $embedded: QueryFormResourceEmbedded; - + public $embedded:QueryFormResourceEmbedded; public schema:SchemaResource; public get filtersSchemas():QueryFilterInstanceSchemaResource[] { return this.$embedded.filtersSchemas.elements; } } - -function formResource() { - return QueryFormResource; -} - -export interface QueryFormResourceInterface extends QueryFormResource { -} - -opApiModule.factory('QueryFormResource', formResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/query-group-by-resource.service.ts b/frontend/app/modules/hal/resources/query-group-by-resource.ts similarity index 73% rename from frontend/app/components/api/api-v3/hal-resources/query-group-by-resource.service.ts rename to frontend/app/modules/hal/resources/query-group-by-resource.ts index a63e2ba373..78477fd526 100644 --- a/frontend/app/components/api/api-v3/hal-resources/query-group-by-resource.service.ts +++ b/frontend/app/modules/hal/resources/query-group-by-resource.ts @@ -26,22 +26,8 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from './hal-resource.service'; -import {opApiModule} from '../../../../angular-modules'; - -interface QueryGroupByResourceEmbedded { -} +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export class QueryGroupByResource extends HalResource { - public $embedded: QueryGroupByResourceEmbedded; - public id: string; -} - -function queryGroupByResource() { - return QueryGroupByResource; + public id:string; } - -export interface QueryGroupByResourceInterface extends QueryGroupByResourceEmbedded, QueryGroupByResource { -} - -opApiModule.factory('QueryGroupByResource', queryGroupByResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/query-operator-resource.service.ts b/frontend/app/modules/hal/resources/query-operator-resource.ts similarity index 75% rename from frontend/app/components/api/api-v3/hal-resources/query-operator-resource.service.ts rename to frontend/app/modules/hal/resources/query-operator-resource.ts index f3be2fbf0d..b3a25147ac 100644 --- a/frontend/app/components/api/api-v3/hal-resources/query-operator-resource.service.ts +++ b/frontend/app/modules/hal/resources/query-operator-resource.ts @@ -26,20 +26,10 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {opApiModule} from '../../../../angular-modules'; -import {HalResource} from './hal-resource.service'; -interface QueryOperatorResourceEmbedded { -} - -interface QueryOperatorResourceLinks { -} +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export class QueryOperatorResource extends HalResource { - - public $embedded:QueryOperatorResourceEmbedded; - public $links:QueryOperatorResourceLinks; - public get id():string { return this.$source.id || this.idFromLink; } @@ -58,11 +48,3 @@ export class QueryOperatorResource extends HalResource { } } -function queryOperatorResource() { - return QueryOperatorResource; -} - -export interface QueryOperatorResourceInterface extends QueryOperatorResource { -} - -opApiModule.factory('QueryOperatorResource', queryOperatorResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/query-resource.service.ts b/frontend/app/modules/hal/resources/query-resource.ts similarity index 72% rename from frontend/app/components/api/api-v3/hal-resources/query-resource.service.ts rename to frontend/app/modules/hal/resources/query-resource.ts index f86b231f3e..ceb3dfcf30 100644 --- a/frontend/app/components/api/api-v3/hal-resources/query-resource.service.ts +++ b/frontend/app/modules/hal/resources/query-resource.ts @@ -26,17 +26,16 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {opApiModule} from '../../../../angular-modules'; -import {QueryColumn} from '../../../wp-query/query-column'; -import {HalResource} from './hal-resource.service'; -import {ProjectResource} from './project-resource.service'; -import {QueryFilterInstanceResource} from './query-filter-instance-resource.service'; -import {QueryGroupByResource} from './query-group-by-resource.service'; -import {QuerySortByResource} from './query-sort-by-resource.service'; -import {WorkPackageCollectionResourceInterface} from './wp-collection-resource.service'; +import {QueryColumn} from 'core-components/wp-query/query-column'; +import {QueryGroupByResource} from 'core-app/modules/hal/resources/query-group-by-resource'; +import {ProjectResource} from 'core-app/modules/hal/resources/project-resource'; +import {QuerySortByResource} from 'core-app/modules/hal/resources/query-sort-by-resource'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource'; interface QueryResourceEmbedded { - results:WorkPackageCollectionResourceInterface; + results:WorkPackageCollectionResource; columns:QueryColumn[]; groupBy:QueryGroupByResource | undefined; project:ProjectResource; @@ -56,7 +55,7 @@ export interface TimelineLabels { export class QueryResource extends HalResource { public $embedded:QueryResourceEmbedded; public id:number; - public results:WorkPackageCollectionResourceInterface; + public results:WorkPackageCollectionResource; public columns:QueryColumn[]; public groupBy:QueryGroupByResource | undefined; public sortBy:QuerySortByResource[]; @@ -73,16 +72,6 @@ export class QueryResource extends HalResource { public $initialize(source:any) { super.$initialize(source); - this.filters = source.filters.map((filter:Object) => new QueryFilterInstanceResource(filter)); + this.filters = source.filters.map((filter:Object) => new QueryFilterInstanceResource(this.injector, filter)); } } - -function queryResource() { - return QueryResource; -} - -export interface QueryResourceInterface extends QueryResourceEmbedded, QueryResource { -} - - -opApiModule.factory('QueryResource', queryResource); diff --git a/frontend/app/modules/hal/resources/query-schema-resource.ts b/frontend/app/modules/hal/resources/query-schema-resource.ts new file mode 100644 index 0000000000..a66cc130dc --- /dev/null +++ b/frontend/app/modules/hal/resources/query-schema-resource.ts @@ -0,0 +1,41 @@ +//-- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See doc/COPYRIGHT.rdoc for more details. +//++ + +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; +import {QueryColumn} from 'core-components/wp-query/query-column'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {QueryFilterInstanceSchemaResource} from 'core-app/modules/hal/resources/query-filter-instance-schema-resource'; +import {QuerySortByResource} from 'core-app/modules/hal/resources/query-sort-by-resource'; +import {QueryGroupByResource} from 'core-app/modules/hal/resources/query-group-by-resource'; + +export class QuerySchemaResource extends SchemaResource { + columns:{ allowedValues:QueryColumn[] }; + filtersSchemas:CollectionResource; + sortBy:{ allowedValues:QuerySortByResource[] }; + groupBy:{ allowedValues:QueryGroupByResource[] }; +} diff --git a/frontend/app/components/api/api-v3/hal-resources/query-sort-by-resource.service.ts b/frontend/app/modules/hal/resources/query-sort-by-resource.ts similarity index 81% rename from frontend/app/components/api/api-v3/hal-resources/query-sort-by-resource.service.ts rename to frontend/app/modules/hal/resources/query-sort-by-resource.ts index 065dd926f5..7d71651775 100644 --- a/frontend/app/components/api/api-v3/hal-resources/query-sort-by-resource.service.ts +++ b/frontend/app/modules/hal/resources/query-sort-by-resource.ts @@ -26,9 +26,8 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from './hal-resource.service'; -import {opApiModule} from '../../../../angular-modules'; -import {QueryColumn} from '../../../wp-query/query-column'; +import {QueryColumn} from 'core-components/wp-query/query-column'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export const QUERY_SORT_BY_ASC = "urn:openproject-org:api:v3:queries:directions:asc" export const QUERY_SORT_BY_DESC = "urn:openproject-org:api:v3:queries:directions:desc" @@ -52,12 +51,3 @@ export class QuerySortByDirection extends HalResource { return this.$href!.split('/').pop()!; } } - -function querySortByResource() { - return QuerySortByResource; -} - -export interface QuerySortByResourceInterface extends QuerySortByResourceEmbedded, QuerySortByResource { -} - -opApiModule.factory('QuerySortByResource', querySortByResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/relation-resource.service.ts b/frontend/app/modules/hal/resources/relation-resource.ts similarity index 74% rename from frontend/app/components/api/api-v3/hal-resources/relation-resource.service.ts rename to frontend/app/modules/hal/resources/relation-resource.ts index ae3a870c0b..95469e2231 100644 --- a/frontend/app/components/api/api-v3/hal-resources/relation-resource.service.ts +++ b/frontend/app/modules/hal/resources/relation-resource.ts @@ -1,4 +1,3 @@ -import {opApiModule} from "../../../../angular-modules"; //-- copyright // OpenProject is a project management system. // Copyright (C) 2012-2015 the OpenProject Foundation (OPF) @@ -26,13 +25,14 @@ import {opApiModule} from "../../../../angular-modules"; // // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from "./hal-resource.service"; -import {WorkPackageResource, WorkPackageResourceInterface} from "./work-package-resource.service"; -import {$injectNow} from '../../../angular/angular-injector-bridge.functions'; + +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; interface RelationResourceLinks { - delete(): ng.IPromise; - updateImmediately(payload: any): ng.IPromise; + delete():Promise; + + updateImmediately(payload:any):Promise; } export class RelationResource extends HalResource { @@ -61,7 +61,6 @@ export class RelationResource extends HalResource { static LOCALIZED_RELATION_TYPES(includeParentchild:boolean = true) { const relationTypes = RelationResource.RELATION_TYPES(includeParentchild); - const I18n:op.I18n = $injectNow('I18n') as op.I18n; return relationTypes.map((key:string) => { return {name: key, label: I18n.t('js.relation_labels.' + key)}; @@ -80,11 +79,11 @@ export class RelationResource extends HalResource { public reverseType:string; // Links - public $links: RelationResourceLinks; - public to:WorkPackageResourceInterface; - public from:WorkPackageResourceInterface; + public $links:RelationResourceLinks; + public to:WorkPackageResource; + public from:WorkPackageResource; - public normalizedType(workPackage:WorkPackageResourceInterface) { + public normalizedType(workPackage:WorkPackageResource) { return this.denormalized(workPackage).relationType; } @@ -94,8 +93,8 @@ export class RelationResource extends HalResource { * @param workPackage * @return {{id, href, relationType: string, workPackageType}} */ - public denormalized(workPackage:WorkPackageResourceInterface):DenormalizedRelationData { - const target = (this.to.href === workPackage.href) ? 'from' : 'to'; + public denormalized(workPackage:WorkPackageResource):DenormalizedRelationData { + const target = (this.to.href === workPackage.$href) ? 'from' : 'to'; return { target: this[target], @@ -125,26 +124,21 @@ export class RelationResource extends HalResource { } public updateDescription(description:string) { - return this.$links.updateImmediately({ description: description }); + return this.$links.updateImmediately({description: description}); } public updateType(type:any) { - return this.$links.updateImmediately({ type: type }); + return this.$links.updateImmediately({type: type}); } } -export interface RelationResourceInterface extends RelationResourceLinks, RelationResource { +export interface RelationResource extends RelationResourceLinks { } export interface DenormalizedRelationData { - target:WorkPackageResourceInterface; + target:WorkPackageResource; targetId:string; relationType:string; reverseRelationType:string; } -function relationResource() { - return RelationResource; -} - -opApiModule.factory('RelationResource', relationResource); diff --git a/frontend/app/modules/hal/resources/resources.ts b/frontend/app/modules/hal/resources/resources.ts new file mode 100644 index 0000000000..9243e78ba0 --- /dev/null +++ b/frontend/app/modules/hal/resources/resources.ts @@ -0,0 +1,53 @@ +import {ConfigurationResource} from 'core-app/modules/hal/resources/configuration-resource'; +import {HelpTextResource} from 'core-app/modules/hal/resources/help-text-resource'; +import {QueryFilterInstanceSchemaResource} from 'core-app/modules/hal/resources/query-filter-instance-schema-resource'; +import {QueryFormResource} from 'core-app/modules/hal/resources/query-form-resource'; +import {QueryFilterResource} from 'core-app/modules/hal/resources/query-filter-resource'; +import {QueryOperatorResource} from 'core-app/modules/hal/resources/query-operator-resource'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {ProjectResource} from 'core-app/modules/hal/resources/project-resource'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {ErrorResource} from 'core-app/modules/hal/resources/error-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {AttachmentCollectionResource} from 'core-app/modules/hal/resources/attachment-collection-resource'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; +import {FormResource} from 'core-app/modules/hal/resources/form-resource'; +import {QueryGroupByResource} from 'core-app/modules/hal/resources/query-group-by-resource'; +import {CustomActionResource} from 'core-app/modules/hal/resources/custom-action-resource'; +import {QuerySortByResource} from 'core-app/modules/hal/resources/query-sort-by-resource'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; +import {RootResource} from 'core-app/modules/hal/resources/root-resource'; +import {SchemaDependencyResource} from 'core-app/modules/hal/resources/schema-dependency-resource'; +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; +import {TypeResource} from 'core-app/modules/hal/resources/type-resource'; +import {UserResource} from 'core-app/modules/hal/resources/user-resource'; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource'; + +export const coreHalResources = [ + AttachmentCollectionResource, + CollectionResource, + ConfigurationResource, + CustomActionResource, + ErrorResource, + FormResource, + HalResource, + HelpTextResource, + ProjectResource, + QueryFilterInstanceResource, + QueryFilterInstanceSchemaResource, + QueryFilterResource, + QueryFormResource, + QueryGroupByResource, + QueryOperatorResource, + QueryResource, + QuerySortByResource, + RelationResource, + RootResource, + SchemaDependencyResource, + SchemaResource, + TypeResource, + UserResource, + WorkPackageResource, + WorkPackageCollectionResource, +]; diff --git a/frontend/app/components/api/api-v3/hal-resources/root-resource.service.ts b/frontend/app/modules/hal/resources/root-resource.ts similarity index 73% rename from frontend/app/components/api/api-v3/hal-resources/root-resource.service.ts rename to frontend/app/modules/hal/resources/root-resource.ts index fd2f4063b9..b68337be0a 100644 --- a/frontend/app/components/api/api-v3/hal-resources/root-resource.service.ts +++ b/frontend/app/modules/hal/resources/root-resource.ts @@ -26,24 +26,12 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from './hal-resource.service'; -import {UserResource} from './user-resource.service'; -import {opApiModule} from '../../../../angular-modules'; -interface RootResourceEmbedded { -} +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {UserResource} from 'core-app/modules/hal/resources/user-resource'; export class RootResource extends HalResource { - public $embedded: RootResourceEmbedded; - public user: UserResource; -} - -function rootResource() { - return RootResource; -} - -export interface RootResourceInterface extends RootResourceEmbedded, RootResource { + public user:UserResource; } -opApiModule.factory('RootResource', rootResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/schema-dependency-resource.service.ts b/frontend/app/modules/hal/resources/schema-dependency-resource.ts similarity index 80% rename from frontend/app/components/api/api-v3/hal-resources/schema-dependency-resource.service.ts rename to frontend/app/modules/hal/resources/schema-dependency-resource.ts index fa8fc4bae3..e128bfefb8 100644 --- a/frontend/app/components/api/api-v3/hal-resources/schema-dependency-resource.service.ts +++ b/frontend/app/modules/hal/resources/schema-dependency-resource.ts @@ -26,8 +26,7 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {opApiModule} from '../../../../angular-modules'; -import {HalResource} from './hal-resource.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export class SchemaDependencyResource extends HalResource { @@ -37,12 +36,3 @@ export class SchemaDependencyResource extends HalResource { return this.dependencies[value]; } } - -function schemaDependencyResource() { - return SchemaDependencyResource; -} - -export interface SchemaDependencyResourceInterface extends SchemaDependencyResource { -} - -opApiModule.factory('SchemaDependencyResource', schemaDependencyResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/schema-resource.service.ts b/frontend/app/modules/hal/resources/schema-resource.ts similarity index 77% rename from frontend/app/components/api/api-v3/hal-resources/schema-resource.service.ts rename to frontend/app/modules/hal/resources/schema-resource.ts index 0a2904fad3..1d9fcb1e3c 100644 --- a/frontend/app/components/api/api-v3/hal-resources/schema-resource.service.ts +++ b/frontend/app/modules/hal/resources/schema-resource.ts @@ -26,19 +26,14 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {opApiModule} from '../../../../angular-modules'; -import {States} from '../../../states.service'; -import {CollectionResource} from './collection-resource.service'; -import {HalResource} from './hal-resource.service'; - -var states:States; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {InputState} from 'reactivestates'; export class SchemaResource extends HalResource { - [attribute:string]:any; - // @ts-ignore - public get state() { - return states.schemas.get(this.href as string); + public get state():InputState { + return this.states.schemas.get(this.href as string) as any; } public get availableAttributes() { @@ -68,7 +63,7 @@ function initializeSchemaResource(halResource:SchemaResource) { _.without(Object.keys(halResource.$source), '_links', '_embedded').forEach(property => { Object.defineProperty(halResource, property, { get() { - return HalResource.create(halResource.$source[property]); + return this.halResourceFactory.createHalResource(halResource.$source[property]); }, enumerable: true, @@ -77,16 +72,3 @@ function initializeSchemaResource(halResource:SchemaResource) { }); } } - -function schemaResource(...args:any[]) { - [ - states, - ] = args; - return SchemaResource; -} - -schemaResource.$inject = [ - 'states', -]; - -opApiModule.factory('SchemaResource', schemaResource); diff --git a/frontend/app/modules/hal/resources/type-resource.ts b/frontend/app/modules/hal/resources/type-resource.ts new file mode 100644 index 0000000000..7d6f841112 --- /dev/null +++ b/frontend/app/modules/hal/resources/type-resource.ts @@ -0,0 +1,38 @@ +//-- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See doc/COPYRIGHT.rdoc for more details. +//++ + +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {InputState, State} from 'reactivestates'; + +export class TypeResource extends HalResource { + public color:string; + + public get state():InputState { + return this.states.types.get(this.href as string) as any; + } +} diff --git a/frontend/app/components/api/api-v3/hal-resources/user-resource.service.ts b/frontend/app/modules/hal/resources/user-resource.ts similarity index 89% rename from frontend/app/components/api/api-v3/hal-resources/user-resource.service.ts rename to frontend/app/modules/hal/resources/user-resource.ts index c4d396339d..897aea51d2 100644 --- a/frontend/app/components/api/api-v3/hal-resources/user-resource.service.ts +++ b/frontend/app/modules/hal/resources/user-resource.ts @@ -26,8 +26,7 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from './hal-resource.service'; -import {opApiModule} from "../../../../angular-modules"; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; export class UserResource extends HalResource { @@ -47,7 +46,6 @@ export class UserResource extends HalResource { public delete:HalResource; public showUser:HalResource; - public static get active_user_statuses() { return ['active', 'registered']; } @@ -60,9 +58,3 @@ export class UserResource extends HalResource { return UserResource.active_user_statuses.indexOf(this.status) >= 0; } } - -function userResource() { - return UserResource; -} - -opApiModule.factory('UserResource', userResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/work-package-resource.service.ts b/frontend/app/modules/hal/resources/work-package-resource.ts similarity index 65% rename from frontend/app/components/api/api-v3/hal-resources/work-package-resource.service.ts rename to frontend/app/modules/hal/resources/work-package-resource.ts index 4e1efa9015..8d7d376f61 100644 --- a/frontend/app/components/api/api-v3/hal-resources/work-package-resource.service.ts +++ b/frontend/app/modules/hal/resources/work-package-resource.ts @@ -26,33 +26,34 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {HalResource} from './hal-resource.service'; -import {opApiModule} from '../../../../angular-modules'; -import {WorkPackageCacheService} from '../../../work-packages/work-package-cache.service'; -import {SchemaCacheService} from './../../../schemas/schema-cache.service'; -import {ApiWorkPackagesService} from '../../api-work-packages/api-work-packages.service'; -import {AttachmentCollectionResourceInterface} from './attachment-collection-resource.service'; -import {UploadFile} from '../../op-file-upload/op-file-upload.service'; -import {States} from '../../../states.service'; -import {SchemaResource} from './schema-resource.service'; -import {TypeResource} from './type-resource.service'; -import {RelationResourceInterface} from './relation-resource.service'; -import {WorkPackageCreateService} from '../../../wp-new/wp-create.service'; -import {WorkPackageNotificationService} from '../../../wp-edit/wp-notification.service'; -import {CollectionResource} from "core-components/api/api-v3/hal-resources/collection-resource.service"; -import IQService = angular.IQService; -import IPromise = angular.IPromise; -import ITimeoutService = angular.ITimeoutService; - -export interface WorkPackageResourceEmbedded { +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import { + I18nToken, + NotificationsServiceToken, + v3PathToken +} from 'core-app/angular4-transition-utils'; +import {AttachmentCollectionResource} from 'core-app/modules/hal/resources/attachment-collection-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {TypeResource} from 'core-app/modules/hal/resources/type-resource'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; +import {UploadFile} from 'core-components/api/op-file-upload/op-file-upload.service'; +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; +import {States} from 'core-components/states.service'; +import {ApiWorkPackagesService} from 'core-components/api/api-work-packages/api-work-packages.service'; +import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; +import {SchemaCacheService} from 'core-components/schemas/schema-cache.service'; +import {WorkPackageNotificationService} from 'core-components/wp-edit/wp-notification.service'; +import {WorkPackageCreateService} from 'core-components/wp-new/wp-create.service'; + +interface WorkPackageResourceEmbedded { activities:CollectionResource; - ancestors:WorkPackageResourceInterface[]; + ancestors:WorkPackageResource[]; assignee:HalResource | any; - attachments:AttachmentCollectionResourceInterface; + attachments:AttachmentCollectionResource; author:HalResource | any; availableWatchers:HalResource | any; category:HalResource | any; - children:WorkPackageResourceInterface[]; + children:WorkPackageResource[]; parent:HalResource | any; priority:HalResource | any; project:HalResource | any; @@ -69,48 +70,32 @@ export interface WorkPackageResourceEmbedded { dueDate:string; // Only for milestones date:string; - relatedBy:RelationResourceInterface | null; + relatedBy:RelationResource | null; } -export interface WorkPackageResourceLinks extends WorkPackageResourceEmbedded { - addAttachment(attachment:HalResource):ng.IPromise; - addChild(child:HalResource):ng.IPromise; - addComment(comment:{comment:string}, headers?:any):ng.IPromise; - addRelation(relation:any):ng.IPromise; - addWatcher(watcher:HalResource):ng.IPromise; - changeParent(params:any):ng.IPromise; - copy():ng.IPromise; - delete():ng.IPromise; - logTime():ng.IPromise; - move():ng.IPromise; - removeWatcher():ng.IPromise; - self():ng.IPromise; - update(payload:any):ng.IPromise; - updateImmediately(payload:any):ng.IPromise; - watch():ng.IPromise; +interface WorkPackageResourceLinks extends WorkPackageResourceEmbedded { + addAttachment(attachment:HalResource):Promise; + addChild(child:HalResource):Promise; + addComment(comment:{comment:string}, headers?:any):Promise; + addRelation(relation:any):Promise; + addWatcher(watcher:HalResource):Promise; + changeParent(params:any):Promise; + copy():Promise; + delete():Promise; + logTime():Promise; + move():Promise; + removeWatcher():Promise; + self():Promise; + update(payload:any):Promise; + updateImmediately(payload:any):Promise; + watch():Promise; } interface WorkPackageLinksObject extends WorkPackageResourceLinks { schema:HalResource; } -var $q:IQService; -var $stateParams:any; -var $timeout:ITimeoutService; -var I18n:op.I18n; -var states:States; -var apiWorkPackages:ApiWorkPackagesService; -var wpCacheService:WorkPackageCacheService; -var schemaCacheService:SchemaCacheService; -var NotificationsService:any; -var wpNotificationsService:WorkPackageNotificationService; -var AttachmentCollectionResource:any; -var v3Path:any; - export class WorkPackageResource extends HalResource { - // Add index signature for getter this[attr] - [attribute:string]:any; - public $embedded:WorkPackageResourceEmbedded; public $links:WorkPackageLinksObject; public subject:string; @@ -119,11 +104,21 @@ export class WorkPackageResource extends HalResource { public description:any; public inFlight:boolean; public activities:CollectionResource; - public attachments:AttachmentCollectionResourceInterface; + public attachments:AttachmentCollectionResource; public pendingAttachments:UploadFile[] = []; public overriddenSchema?:SchemaResource; + readonly I18n:op.I18n = this.injector.get(I18nToken); + readonly states:States = this.injector.get(States); + readonly apiWorkPackages:ApiWorkPackagesService = this.injector.get(ApiWorkPackagesService); + readonly wpCacheService:WorkPackageCacheService = this.injector.get(WorkPackageCacheService); + readonly schemaCacheService:SchemaCacheService = this.injector.get(SchemaCacheService); + readonly NotificationsService:any = this.injector.get(NotificationsServiceToken); + readonly wpNotificationsService:WorkPackageNotificationService = this.injector.get(WorkPackageNotificationService); + readonly wpCreate:WorkPackageCreateService = this.injector.get(WorkPackageCreateService); + readonly v3Path:any = this.injector.get(v3PathToken); + public get id():string { return this.$source.id || this.idFromLink; } @@ -188,6 +183,7 @@ export class WorkPackageResource extends HalResource { $loaded: false }; this.attachments = new AttachmentCollectionResource( + this.injector, attachments.$source, attachments.$loaded ); @@ -207,7 +203,7 @@ export class WorkPackageResource extends HalResource { this.updateAttachments(); }) .catch((error:any) => { - wpNotificationsService.handleErrorResponse(error, this as any); + this.wpNotificationsService.handleErrorResponse(error, this as any); this.attachments.elements.push(attachment); }); } @@ -220,7 +216,7 @@ export class WorkPackageResource extends HalResource { * Upload the pending attachments if the work package exists. * Do nothing, if the work package is being created. */ - public uploadPendingAttachments():ng.IPromise | void { + public uploadPendingAttachments():Promise | void { if (!this.pendingAttachments.length) { return undefined; } @@ -234,18 +230,18 @@ export class WorkPackageResource extends HalResource { * Upload the given attachments, update the resource and notify the user. * Return an updated AttachmentCollectionResource. */ - public uploadAttachments(files:UploadFile[]):IPromise { + public uploadAttachments(files:UploadFile[]):Promise { const {uploads, finished} = this.attachments.upload(files); const message = I18n.t('js.label_upload_notification', this); - const notification = NotificationsService.addWorkPackageUpload(message, uploads); + const notification = this.NotificationsService.addWorkPackageUpload(message, uploads); return finished .then(() => { - $timeout(() => NotificationsService.remove(notification), 700); + setTimeout(() => this.NotificationsService.remove(notification), 700); return this.updateAttachments(); }) - .catch(error => { - wpNotificationsService.handleRawError(error, this as any); + .catch((error:any) => { + this.wpNotificationsService.handleRawError(error, this as any); }); } @@ -259,7 +255,7 @@ export class WorkPackageResource extends HalResource { if (attachmentUpload) { attachmentUpload.then((attachmentsResource) => { if (attachmentsResource.count > 0) { - wpCacheService.loadWorkPackage(this.id, true); + this.wpCacheService.loadWorkPackage(this.id, true); } }); } @@ -273,7 +269,7 @@ export class WorkPackageResource extends HalResource { } } - public isParentOf(otherWorkPackage:WorkPackageResourceInterface) { + public isParentOf(otherWorkPackage:WorkPackageResource) { return otherWorkPackage.parent.$links.self.$link.href === this.$links.self.$link.href; } @@ -284,17 +280,17 @@ export class WorkPackageResource extends HalResource { * Return a promise that returns the linked resources as properties. * Return a rejected promise, if the resource is not a property of the work package. */ - public updateLinkedResources(...resourceNames:string[]):ng.IPromise { - const resources:{ [id:string]:IPromise } = {}; + public updateLinkedResources(...resourceNames:string[]):Promise { + const resources:{ [id:string]:Promise } = {}; resourceNames.forEach(name => { const linked = this[name]; - resources[name] = linked ? linked.$update() : $q.reject(); + resources[name] = linked ? linked.$update() : Promise.reject(undefined); }); - const promise = $q.all(resources); + const promise = Promise.all(_.values(resources)); promise.then(() => { - wpCacheService.touch(this.id); + this.wpCacheService.touch(this.id); }); return promise; @@ -307,7 +303,7 @@ export class WorkPackageResource extends HalResource { * Return a promise that returns the activities. Reject, if the work package has * no activities. */ - public updateActivities():IPromise { + public updateActivities():Promise { return this .updateLinkedResources('activities') .then((resources:any) => resources.activities); @@ -320,7 +316,7 @@ export class WorkPackageResource extends HalResource { * Return a promise that returns the attachments. Reject, if the work package has * no attachments. */ - public updateAttachments():IPromise { + public updateAttachments():Promise { return this .updateLinkedResources('activities', 'attachments') .then((resources:any) => resources.attachments); @@ -332,14 +328,14 @@ export class WorkPackageResource extends HalResource { */ public initializeNewResource(form:any) { this.overriddenSchema = form.schema; - this.form = $q.when(form); + this.form = Promise.resolve(form); this.$source.id = 'new'; // Set update link to form this['update'] = this.$links.update = form.$links.self; // Use POST /work_packages for saving link this['updateImmediately'] = this.$links.updateImmediately = (payload) => { - return apiWorkPackages.createWorkPackage(payload); + return this.apiWorkPackages.createWorkPackage(payload); }; } @@ -362,7 +358,7 @@ export class WorkPackageResource extends HalResource { return this.overriddenSchema!; } - const state = schemaCacheService.state(this as any); + const state = this.schemaCacheService.state(this as any); if (!state.hasValue()) { throw `Accessing schema of ${this.id} without it being loaded.`; @@ -376,39 +372,5 @@ export class WorkPackageResource extends HalResource { } } -export interface WorkPackageResourceInterface extends WorkPackageResourceLinks, WorkPackageResourceEmbedded, WorkPackageResource { +export interface WorkPackageResource extends WorkPackageResourceLinks, WorkPackageResourceEmbedded { } - -function wpResource(...args:any[]) { - [ - $q, - $stateParams, - $timeout, - I18n, - states, - apiWorkPackages, - wpCacheService, - schemaCacheService, - NotificationsService, - wpNotificationsService, - AttachmentCollectionResource, - v3Path] = args; - return WorkPackageResource; -} - -wpResource.$inject = [ - '$q', - '$stateParams', - '$timeout', - 'I18n', - 'states', - 'apiWorkPackages', - 'wpCacheService', - 'schemaCacheService', - 'NotificationsService', - 'wpNotificationsService', - 'AttachmentCollectionResource', - 'v3Path' -]; - -opApiModule.factory('WorkPackageResource', wpResource); diff --git a/frontend/app/components/api/api-v3/hal-resources/wp-collection-resource.service.ts b/frontend/app/modules/hal/resources/wp-collection-resource.ts similarity index 60% rename from frontend/app/components/api/api-v3/hal-resources/wp-collection-resource.service.ts rename to frontend/app/modules/hal/resources/wp-collection-resource.ts index 81e9d7af40..acd2a7eb51 100644 --- a/frontend/app/components/api/api-v3/hal-resources/wp-collection-resource.service.ts +++ b/frontend/app/modules/hal/resources/wp-collection-resource.ts @@ -26,28 +26,27 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {CollectionResource} from './collection-resource.service'; -import {WorkPackageResourceInterface} from './work-package-resource.service'; -import {HalResource} from './hal-resource.service'; -import {opApiModule} from '../../../../angular-modules'; -import {SchemaResource} from "core-components/api/api-v3/hal-resources/schema-resource.service"; +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; interface WorkPackageCollectionResourceEmbedded { - elements: WorkPackageResourceInterface[]; - groups: GroupObject[]; + elements:WorkPackageResource[]; + groups:GroupObject[]; } -export class WorkPackageCollectionResource extends CollectionResource { - public schemas: CollectionResource; +export class WorkPackageCollectionResource extends CollectionResource { + public schemas:CollectionResource; public createWorkPackage:any; - public elements: WorkPackageResourceInterface[]; - public groups: GroupObject[]; - public totalSums?: Object; - public sumsSchema?: SchemaResource; - public representations: Array; + public elements:WorkPackageResource[]; + public groups:GroupObject[]; + public totalSums?:Object; + public sumsSchema?:SchemaResource; + public representations:Array; } -export interface WorkPackageCollectionResourceInterface extends WorkPackageCollectionResourceEmbedded, WorkPackageCollectionResource { +export interface WorkPackageCollectionResource extends WorkPackageCollectionResourceEmbedded { } /** @@ -61,14 +60,8 @@ export interface GroupObject { index:number; identifier:string; href:{ href:string }[]; - _links: { - valueLink: { href:string }[]; - groupBy: { href:string }; - } + _links:{ + valueLink:{ href:string }[]; + groupBy:{ href:string }; + }; } - -function workPackageCollectionResource() { - return WorkPackageCollectionResource; -} - -opApiModule.factory('WorkPackageCollectionResource', workPackageCollectionResource); diff --git a/frontend/app/components/api/api-v3/hal-request/hal-request.service.ts b/frontend/app/modules/hal/services/hal-request.service.ts similarity index 64% rename from frontend/app/components/api/api-v3/hal-request/hal-request.service.ts rename to frontend/app/modules/hal/services/hal-request.service.ts index 34bfa574a0..c0093704ff 100644 --- a/frontend/app/components/api/api-v3/hal-request/hal-request.service.ts +++ b/frontend/app/modules/hal/services/hal-request.service.ts @@ -26,68 +26,50 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {Inject, Injectable} from '@angular/core'; -import {$httpToken, $qToken, halResourceFactoryToken} from 'core-app/angular4-transition-utils'; -import {opApiModule} from '../../../../angular-modules'; -import {HalResource} from '../hal-resources/hal-resource.service'; -import {HalResourceFactoryService} from '../hal-resource-factory/hal-resource-factory.service'; -import IPromise = angular.IPromise; -import {CollectionResource} from '../hal-resources/collection-resource.service'; +import {Injectable} from '@angular/core'; +import {HttpClient} from '@angular/common/http'; +import {tap} from 'rxjs/operators'; +import {Observable} from 'rxjs'; +import {HalResourceFactoryService} from 'core-app/modules/hal/services/hal-resource-factory.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; + +export type HTTPSupportedMethods = 'get'|'post'|'put'|'patch'|'delete'; @Injectable() export class HalRequestService { - /** - * Default headers sent with every request. - */ - public defaultHeaders = { - caching: { - enabled: true - }, - 'Content-Type': 'application/json' - }; - - constructor(@Inject($qToken) protected $q:ng.IQService, - @Inject($httpToken) protected $http:ng.IHttpService, - @Inject(halResourceFactoryToken) protected halResourceFactory:HalResourceFactoryService) { + constructor(readonly http:HttpClient, + readonly halResourceFactory:HalResourceFactoryService) { } /** * Perform a HTTP request and return a HalResource promise. */ - public request(method:string, href:string, data?:any, headers:any = {}):IPromise { - if (!href) { - return this.$q.reject(); - } - - if (method.toUpperCase() !== 'GET') { - data = data || {}; - } - - headers = angular.extend({}, this.defaultHeaders, headers); - + public request(method:HTTPSupportedMethods, href:string, data?:any, headers:any = {}):Observable { const config:any = { method: method, url: href, - data: data, + body: data || {}, headers: headers, - cache: headers.caching.enabled + withCredentials: true, + responseType: 'json' }; + const createResource = (response:any) => { if (!response.data) { - return null; + return response; } return this.halResourceFactory.createHalResource(response.data); }; - if (method === 'get') { - delete config.data; - config.params = data; - } - - return this.$http(config) - .then(createResource) - .catch(response => this.$q.reject(createResource(response) as T)) as ng.IPromise; + return this.http.request(method, href, config) + .pipe( + tap( + data => createResource(data), + error => createResource(error) + ) + ) as Observable; } /** @@ -96,9 +78,9 @@ export class HalRequestService { * @param href * @param params * @param headers - * @returns {ng.IPromise} + * @returns {Promise} */ - public get(href:string, params?:any, headers?:any):IPromise { + public get(href:string, params?:any, headers?:any):Observable { return this.request('get', href, params, headers); } @@ -112,7 +94,7 @@ export class HalRequestService { * @param headers * @return {Promise} */ - public async getAllPaginated(href:string, expected:number, params:any = {}, headers:any = {}) { + public async getAllPaginated(href:string, expected:number, params:any = {}, headers:any = {}) { // Total number retrieved let retrieved = 0; // Current offset page @@ -125,7 +107,8 @@ export class HalRequestService { while (retrieved < expected) { params.offset = page; - const results = await this.request('get', href, params, headers); + const promise = this.request('get', href, params, headers).toPromise(); + const results = await promise; if (results.count === 0) { throw 'No more results for this query, but expected more.'; @@ -145,9 +128,9 @@ export class HalRequestService { * @param href * @param data * @param headers - * @returns {ng.IPromise} + * @returns {Promise} */ - public put(href:string, data?:any, headers?:any):IPromise { + public put(href:string, data?:any, headers?:any):Observable { return this.request('put', href, data, headers); } @@ -157,9 +140,9 @@ export class HalRequestService { * @param href * @param data * @param headers - * @returns {ng.IPromise} + * @returns {Promise} */ - public post(href:string, data?:any, headers?:any):IPromise { + public post(href:string, data?:any, headers?:any):Observable { return this.request('post', href, data, headers); } @@ -169,9 +152,9 @@ export class HalRequestService { * @param href * @param data * @param headers - * @returns {ng.IPromise} + * @returns {Promise} */ - public patch(href:string, data?:any, headers?:any):IPromise { + public patch(href:string, data?:any, headers?:any):Observable { return this.request('patch', href, data, headers); } @@ -181,11 +164,10 @@ export class HalRequestService { * @param href * @param data * @param headers - * @returns {ng.IPromise} + * @returns {Promise} */ - public delete(href:string, data?:any, headers?:any):IPromise { + public delete(href:string, data?:any, headers?:any):Observable { return this.request('delete', href, data, headers); } } -opApiModule.service('halRequest', HalRequestService); diff --git a/frontend/app/modules/hal/services/hal-resource-factory.config.ts b/frontend/app/modules/hal/services/hal-resource-factory.config.ts new file mode 100644 index 0000000000..b7943f4ef4 --- /dev/null +++ b/frontend/app/modules/hal/services/hal-resource-factory.config.ts @@ -0,0 +1,143 @@ +// -- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See doc/COPYRIGHT.rdoc for more details. +// ++ + +import {WorkPackageResource} from 'core-app/modules/hal/resources/work-package-resource'; +import {RelationResource} from 'core-app/modules/hal/resources/relation-resource'; +import {SchemaResource} from 'core-app/modules/hal/resources/schema-resource'; +import {TypeResource} from 'core-app/modules/hal/resources/type-resource'; +import {SchemaDependencyResource} from 'core-app/modules/hal/resources/schema-dependency-resource'; +import {ErrorResource} from 'core-app/modules/hal/resources/error-resource'; +import {UserResource} from 'core-app/modules/hal/resources/user-resource'; +import {CollectionResource} from 'core-app/modules/hal/resources/collection-resource'; +import {WorkPackageCollectionResource} from 'core-app/modules/hal/resources/wp-collection-resource'; +import {QueryResource} from 'core-app/modules/hal/resources/query-resource'; +import {FormResource} from 'core-app/modules/hal/resources/form-resource'; +import {QueryFilterInstanceResource} from 'core-app/modules/hal/resources/query-filter-instance-resource'; +import {QueryFilterInstanceSchemaResource} from 'core-app/modules/hal/resources/query-filter-instance-schema-resource'; +import {QueryFilterResource} from 'core-app/modules/hal/resources/query-filter-resource'; +import {RootResource} from 'core-app/modules/hal/resources/root-resource'; +import {QueryOperatorResource} from 'core-app/modules/hal/resources/query-operator-resource'; +import {HelpTextResource} from 'core-app/modules/hal/resources/help-text-resource'; +import {CustomActionResource} from 'core-app/modules/hal/resources/custom-action-resource'; + +export interface HalResourceFactoryConfigInterface { + cls?:any; + attrTypes?:{ [attrName:string]:string }; +} + +export const halResourceDefaultConfig:{ [typeName:string]:HalResourceFactoryConfigInterface } = { + WorkPackage: { + cls: WorkPackageResource, + attrTypes: { + parent: 'WorkPackage', + ancestors: 'WorkPackage', + children: 'WorkPackage', + relations: 'Relation', + schema: 'Schema', + type: 'Type' + } + }, + Activity: { + attrTypes: { + user: 'User' + } + }, + 'Activity::Comment': { + attrTypes: { + user: 'User' + } + }, + 'Activity::Revision': { + attrTypes: { + user: 'User' + } + }, + Relation: { + cls: RelationResource, + attrTypes: { + from: 'WorkPackage', + to: 'WorkPackage' + } + }, + Schema: { + cls: SchemaResource + }, + Type: { + cls: TypeResource + }, + SchemaDependency: { + cls: SchemaDependencyResource + }, + Error: { + cls: ErrorResource + }, + User: { + cls: UserResource + }, + Collection: { + cls: CollectionResource + }, + WorkPackageCollection: { + cls: WorkPackageCollectionResource + }, + Query: { + cls: QueryResource, + attrTypes: { + filters: 'QueryFilterInstance' + } + }, + Form: { + cls: FormResource + }, + QueryFilterInstance: { + cls: QueryFilterInstanceResource, + attrTypes: { + schema: 'QueryFilterInstanceSchema', + filter: 'QueryFilter', + operator: 'QueryOperator' + } + }, + QueryFilterInstanceSchema: { + cls: QueryFilterInstanceSchemaResource, + }, + QueryFilter: { + cls: QueryFilterResource, + }, + Root: { + cls: RootResource, + }, + QueryOperator: { + cls: QueryOperatorResource, + }, + HelpText: { + cls: HelpTextResource, + }, + CustomAction: { + cls: CustomActionResource + } +}; diff --git a/frontend/app/components/api/api-v3/hal-resource-factory/hal-resource-factory.service.ts b/frontend/app/modules/hal/services/hal-resource-factory.service.ts similarity index 54% rename from frontend/app/components/api/api-v3/hal-resource-factory/hal-resource-factory.service.ts rename to frontend/app/modules/hal/services/hal-resource-factory.service.ts index 45fa9dad2c..9990c5a802 100644 --- a/frontend/app/components/api/api-v3/hal-resource-factory/hal-resource-factory.service.ts +++ b/frontend/app/modules/hal/services/hal-resource-factory.service.ts @@ -26,83 +26,78 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {opApiModule} from '../../../../angular-modules'; -import {HalResource} from '../hal-resources/hal-resource.service'; -import './hal-changeset-proxy'; - - -interface HalResourceFactoryConfigInterface { - cls?:typeof HalResource; - attrCls?:{[attrName:string]:typeof HalResource}; -} - +import {Injectable, Injector} from '@angular/core'; +import {HalLinkService} from 'core-app/modules/hal/hal-link/hal-link.service'; +import {HalResource} from 'core-app/modules/hal/resources/hal-resource'; +import { + halResourceDefaultConfig, HalResourceFactoryConfigInterface, +} from 'core-app/modules/hal/services/hal-resource-factory.config'; +import {HalLinkInterface} from 'core-app/modules/hal/hal-link/hal-link'; + +@Injectable() export class HalResourceFactoryService { - protected config:{[typeName:string]:HalResourceFactoryConfigInterface} = {}; /** - * Get the default class. - * Initially, it's HalResource. - * - * @returns {HalResource} + * List of all known hal resources, extendable. */ - public get defaultClass() { - return this.getResourceClassOfType('__default__'); + private config = halResourceDefaultConfig; + + constructor(readonly halLink:HalLinkService, + readonly injector:Injector) { + } /** - * Set the default class. - * - * @param cls + * Register a HalResource for use with the API. + * @param {HalResourceStatic} resource */ - public set defaultClass(cls:typeof HalResource) { - this.setResourceType('__default__', cls); + public registerResource(key:string, entry:HalResourceFactoryConfigInterface) { + this.config[key] = entry; } /** - * Configure the resource class for a resource type. + * Get the default class. + * Initially, it's HalResource. * - * @param typeName - * @param cls + * @returns {HalResource} */ - public setResourceType(typeName:string, cls:typeof HalResource) { - cls._type = typeName; - this.config[typeName] = { - cls: cls, - attrCls: {} - }; + public get defaultClass() { + return HalResource; } /** - * Set the attribute configuration for a certain type. + * Create a HalResource from a source object. + * If a _type attribute is defined and the type is configured, the + * respective class will be used for instantiation. * - * @param typeName - * @param attrTypes + * @param source + * @returns {HalResource} */ - public setResourceTypeAttributes(typeName:string, attrTypes:any) { - Object.keys(attrTypes).forEach(attrName => { - attrTypes[attrName] = this.getResourceClassOfType(attrTypes[attrName]); - }); + public createHalResource(source:any, loaded:boolean = false, force:boolean = false):HalResource|null { + if (_.isNil(source)) { + return null; + } - if (!this.config[typeName]) { - this.config[typeName] = {}; + if (!force && !(source._embedded || source._links)) { + return source; } - this.config[typeName].attrCls = attrTypes; + const resourceClass = this.getResourceClassOfType(source._type); + return new resourceClass(this.injector, source); } /** - * Create a HalResource from a source object. - * If a _type attribute is defined and the type is configured, the - * respective class will be used for instantiation. + * Create a linked HalResource from the given link. * - * @param source + * @param {HalLinkInterface} link * @returns {HalResource} */ - public createHalResource(source:any):HalResource { - const resourceClass = this.getResourceClassOfType(source._type); - return new resourceClass(source); + public fromLink(link:HalLinkInterface) { + const resource = HalResource.getEmptyResource(this.halLink.fromObject(link)); + return new HalResource(this.injector, resource, false); } + /** * Create an unloaded HalResource that is a linked property of its parent. * @@ -112,7 +107,7 @@ export class HalResourceFactoryService { */ public createLinkedHalResource(source:any, parentType:string, linkName:string):HalResource { const resourceClass = this.getResourceClassOfAttribute(parentType, linkName); - return new resourceClass(source, false); + return new resourceClass(this.injector, source, false); } /** @@ -122,7 +117,8 @@ export class HalResourceFactoryService { * @returns {HalResource} */ protected getResourceClassOfType(type:string):typeof HalResource { - return this.getTypeConfig(type).cls as typeof HalResource; + const config = this.config[type]; + return (config && config.cls) ? config.cls : this.defaultClass; } /** @@ -134,36 +130,14 @@ export class HalResourceFactoryService { * @returns {any} */ protected getResourceClassOfAttribute(type:string, attribute:string):typeof HalResource { - const typeConfig = this.getTypeConfig(type); - const resourceClass = (typeConfig.attrCls as any)[attribute]; + const typeConfig = this.config[type]; + const types = (typeConfig && typeConfig.attrTypes) || {}; + const resourceRef = types[attribute]; - if (resourceClass) { - return resourceClass; + if (resourceRef) { + return this.getResourceClassOfType(resourceRef); } return this.defaultClass; } - - /** - * Get the string of the type or the default string, if it doesn't exist. - * - * @param type - * @returns {string} - */ - protected getType(type:string):string { - return this.config[type] ? type : '__default__'; - } - - /** - * Get the type config for a certain type. - * Return the default config, if it doesn't exist. - * - * @param type - * @returns {any} - */ - protected getTypeConfig(type:string):HalResourceFactoryConfigInterface { - return this.config[this.getType(type)]; - } } - -opApiModule.service('halResourceFactory', HalResourceFactoryService); diff --git a/frontend/npm-shrinkwrap.json b/frontend/npm-shrinkwrap.json index 7c4ab06065..3213dd3bec 100644 --- a/frontend/npm-shrinkwrap.json +++ b/frontend/npm-shrinkwrap.json @@ -947,6 +947,12 @@ "safe-buffer": "5.1.1" } }, + "circular-dependency-plugin": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-4.4.0.tgz", + "integrity": "sha512-yEFtUNUYT4jBykEX5ZOHw+5goA3glGZr9wAXIQqoyakjz5H5TeUmScnWRc52douAhb9eYzK3s7V6bXfNnjFdzg==", + "dev": true + }, "clean-webpack-plugin": { "version": "0.1.18", "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-0.1.18.tgz", diff --git a/frontend/package.json b/frontend/package.json index 56d76c7db0..3caf72ba75 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,6 +6,7 @@ "body-parser": "^1.2.0", "chai": "^3.5.0", "chai-as-promised": "^5.3.0", + "circular-dependency-plugin": "^4.4.0", "es6-promise": "^4.1.0", "exec": "0.0.6", "jquery-mockjax": "~2.2.1", diff --git a/frontend/webpack-main-config.js b/frontend/webpack-main-config.js index 633a168f5e..e76ce5bcbf 100644 --- a/frontend/webpack-main-config.js +++ b/frontend/webpack-main-config.js @@ -40,6 +40,7 @@ var HappyPack = require('happypack'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var CleanWebpackPlugin = require('clean-webpack-plugin'); // var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; +var CircularDependencyPlugin = require('circular-dependency-plugin'); var mode = (process.env['RAILS_ENV'] || 'production').toLowerCase(); var production = (mode !== 'development'); @@ -290,8 +291,19 @@ function getWebpackMainConfig() { ), // Restrict loaded moment locales to the ones we load from translations - new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, new RegExp('(' + localeIds.join('|') + ')\.js$', 'i')) + new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, new RegExp('(' + localeIds.join('|') + ')\.js$', 'i')), + + // Uncomment to analyze current bundle size // new BundleAnalyzerPlugin() + + new CircularDependencyPlugin({ + // exclude detection of files based on a RegExp + exclude: /node_modules/, + // add errors to webpack instead of warnings + failOnError: false, + // set the current working directory for displaying module paths + cwd: process.cwd(), + }) ] };