diff --git a/backend/src/main/resources/metadata-sources-ui-schema.json b/backend/src/main/resources/metadata-sources-ui-schema.json index 5766e298f..4784deeea 100644 --- a/backend/src/main/resources/metadata-sources-ui-schema.json +++ b/backend/src/main/resources/metadata-sources-ui-schema.json @@ -1,20 +1,29 @@ { "type": "object", + "required": [ + "serviceProviderName", + "entityId" + ], "properties": { "entityId": { "title": "label.entity-id", "description": "tooltip.entity-id", - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 255 }, "serviceProviderName": { "title": "label.service-provider-name", "description": "tooltip.service-provider-name", - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 255 }, "serviceEnabled": { - "title": "label.enable-this-service-opon-saving", + "title": "label.enable-this-service-upon-saving", "description": "tooltip.enable-this-service-upon-saving", - "type": "boolean" + "type": "boolean", + "default": false }, "organization": { "type": "object", @@ -30,8 +39,8 @@ "type": "string" }, "url": { - "title": "label.organization-display-name", - "description": "tooltip.organization-display-name", + "title": "label.organization-url", + "description": "tooltip.organization-url", "type": "string" } }, @@ -60,6 +69,28 @@ }, "mdui": { "type": "object", + "widget": { + "id": "fieldset" + }, + "fieldsets": [ + { + "type": "group", + "fields": [ + "displayName", + "informationUrl", + "description" + ] + }, + { + "type": "group", + "fields": [ + "privacyStatementUrl", + "logoUrl", + "logoWidth", + "logoHeight" + ] + } + ], "properties": { "displayName": { "title": "label.display-name", @@ -79,7 +110,10 @@ "description": { "title": "label.description", "description": "tooltip.mdui-description", - "type": "string" + "type": "string", + "widget": { + "id": "textarea" + } }, "logoUrl": { "title": "label.logo-url", @@ -90,35 +124,107 @@ "title": "label.logo-height", "description": "tooltip.mdui-logo-height", "min": 0, - "type": "integer" + "type": "integer", + "default": 0 }, "logoWidth": { "title": "label.logo-width", "description": "tooltip.mdui-logo-width", "min": 0, - "type": "integer" + "type": "integer", + "default": 0 } } }, "securityInfo": { "type": "object", + "widget": { + "id": "fieldset" + }, + "fieldsets": [ + { + "type": "group", + "fields": [ + "x509CertificateAvailable", + "authenticationRequestsSigned", + "wantAssertionsSigned" + ] + }, + { + "type": "group", + "fields": [ + "x509Certificates" + ] + } + ], "properties": { "x509CertificateAvailable": { "title": "label.is-there-a-x509-certificate", "description": "tooltip.is-there-a-x509-certificate", "type": "boolean", + "widget": { + "id": "boolean-radio" + }, + "oneOf": [ + { + "enum": [ + true + ], + "description": "value.true" + }, + { + "enum": [ + false + ], + "description": "value.false" + } + ], "default": false }, "authenticationRequestsSigned": { "title": "label.authentication-requests-signed", "description": "tooltip.authentication-requests-signed", "type": "boolean", + "widget": { + "id": "boolean-radio" + }, + "oneOf": [ + { + "enum": [ + true + ], + "description": "value.true" + }, + { + "enum": [ + false + ], + "description": "value.false" + } + ], "default": false }, "wantAssertionsSigned": { "title": "label.want-assertions-signed", "description": "tooltip.want-assertions-signed", "type": "boolean", + "widget": { + "id": "boolean-radio" + }, + "oneOf": [ + { + "enum": [ + true + ], + "description": "value.true" + }, + { + "enum": [ + false + ], + "description": "value.false" + } + ], "default": false }, "x509Certificates": { @@ -140,12 +246,30 @@ }, "serviceProviderSsoDescriptor": { "type": "object", + "widget": { + "id": "fieldset" + }, + "fieldsets": [ + { + "type": "group", + "fields": [ + "protocolSupportEnum", + "nameIdFormats" + ] + } + ], + "required": [ + "nameIdFormats" + ], "properties": { "protocolSupportEnum": { "title": "label.protocol-support-enumeration", "description": "tooltip.protocol-support-enumeration", "type": "string", "placeholder": "label.select-protocol", + "widget": { + "id": "select" + }, "oneOf": [ { "enum": [ @@ -160,10 +284,10 @@ "description": "SAML 1.1" } ] + }, + "nameIdFormats": { + "$ref": "#/definitions/NameIdFormatList" } - }, - "nameIdFormats": { - "$ref": "#/definitions/NameIdFormatList" } }, "logoutEndpoints": { @@ -247,22 +371,31 @@ "definitions": { "Contact": { "type": "object", + "required": [ + "name", + "type", + "emailAddress" + ], "properties": { "name": { "title": "label.contact-name", "description": "tooltip.contact-name", - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 255 }, "type": { "title": "label.contact-type", "description": "tooltip.contact-type", "type": "string", + "widget": "select", + "minLength": 1, "oneOf": [ { "enum": [ "support" ], - "description": "value.support" + "description": "value.support" }, { "enum": [ @@ -288,46 +421,63 @@ "title": "label.contact-email-address", "description": "tooltip.contact-email", "type": "string", - "pattern": "^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$" + "pattern": "^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$", + "minLength": 1, + "maxLength": 255 } } }, "Certificate": { - "name": { - "title": "label.certificate-name-display-only", - "description": "tooltip.certificate-name", - "type": "string" - }, - "type": { - "title": "label.type", - "description": "tooltip.certificate-type", - "type": "string", - "oneOf": [ - { - "enum": [ - "signing" - ], - "description": "value.signing" - }, - { - "enum": [ - "encryption" - ], - "description": "value.encryption" - }, - { - "enum": [ - "both" - ], - "description": "value.both" - } - ], - "default": "both" + "type": "object", + "widget": { + "id": "fieldset" }, - "value": { - "title": "label.certificate", - "description": "tooltip.certificate", - "type": "string" + "required": [ + "name", + "type", + "value" + ], + "properties": { + "name": { + "title": "label.certificate-name-display-only", + "description": "tooltip.certificate-name", + "type": "string", + "minLength": 1, + "maxLength": 255 + }, + "type": { + "title": "label.type", + "description": "tooltip.certificate-type", + "type": "string", + "widget": "radio", + "oneOf": [ + { + "enum": [ + "signing" + ], + "description": "value.signing" + }, + { + "enum": [ + "encryption" + ], + "description": "value.encryption" + }, + { + "enum": [ + "both" + ], + "description": "value.both" + } + ], + "default": "both" + }, + "value": { + "title": "label.certificate", + "description": "tooltip.certificate", + "type": "string", + "minLength": 1 + } } }, "AssertionConsumerService": { @@ -340,7 +490,9 @@ "widget": { "id": "string", "help": "message.valid-url" - } + }, + "minLength": 1, + "maxLength": 255 }, "binding": { "title": "label.assertion-consumer-service-location-binding", @@ -376,13 +528,17 @@ "uniqueItems": true, "items": { "type": "string", - "widget": "datalist", - "data": [ - "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", - "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", - "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", - "urn:oasis:names:tc:SAML:2.0:nameid-format:transient" - ] + "minLength": 1, + "maxLength": 255, + "widget": { + "id": "datalist", + "data": [ + "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", + "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", + "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "urn:oasis:names:tc:SAML:2.0:nameid-format:transient" + ] + } }, "default": null }, @@ -395,6 +551,8 @@ "items": { "type": "string", "title": "label.authentication-method", + "minLength": 1, + "maxLength": 255, "widget": { "id": "datalist", "data": [ @@ -410,16 +568,35 @@ "title": "label.new-endpoint", "description": "tooltip.new-endpoint", "type": "object", + "widget": { + "id": "fieldset" + }, + "fieldsets": [ + { + "type": "section", + "fields": [ + "url", + "bindingType" + ] + } + ], + "required": [ + "url", + "bindingType" + ], "properties": { "url": { "title": "label.url", "description": "tooltip.url", - "type": "string" + "type": "string", + "minLength": 1, + "maxLength": 255 }, "bindingType": { "title": "label.binding-type", "description": "tooltip.binding-type", "type": "string", + "widget": "select", "oneOf": [ { "enum": [ @@ -434,7 +611,6 @@ "description": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" } ] - } } } diff --git a/ui/src/app/metadata/domain/entity/resolver/file-backed-http-metadata-resolver.ts b/ui/src/app/metadata/domain/entity/resolver/file-backed-http-metadata-resolver.ts index 982d86d35..9d71ee2b5 100644 --- a/ui/src/app/metadata/domain/entity/resolver/file-backed-http-metadata-resolver.ts +++ b/ui/src/app/metadata/domain/entity/resolver/file-backed-http-metadata-resolver.ts @@ -14,7 +14,7 @@ import { MetadataTypes } from '../../domain.type'; import { MetadataEntity } from '../../model/metadata-entity'; export class FileBackedHttpMetadataResolver implements MetadataResolver, MetadataEntity { - id = ''; + resourceId = ''; createdDate?: string; modifiedDate?: string; version: string; @@ -53,7 +53,7 @@ export class FileBackedHttpMetadataResolver implements MetadataResolver, Metadat } getId(): string { - return this.id ? this.id : this.entityId; + return this.resourceId; } getDisplayId(): string { @@ -61,7 +61,7 @@ export class FileBackedHttpMetadataResolver implements MetadataResolver, Metadat } isDraft(): boolean { - return this.id ? false : true; + return this.createdDate ? false : true; } getCreationDate(): Date { diff --git a/ui/src/app/metadata/domain/model/metadata-resolver.ts b/ui/src/app/metadata/domain/model/metadata-resolver.ts index 699ab615f..55776ea03 100644 --- a/ui/src/app/metadata/domain/model/metadata-resolver.ts +++ b/ui/src/app/metadata/domain/model/metadata-resolver.ts @@ -11,8 +11,8 @@ import { } from '../model'; export interface MetadataResolver extends MetadataBase { - resourceId?: string; - entityId: string; + resourceId: string; + entityId?: string; serviceProviderName: string; organization?: Organization; contacts?: Contact[]; @@ -22,6 +22,6 @@ export interface MetadataResolver extends MetadataBase { serviceProviderSsoDescriptor?: IdpSsoDescriptor; logoutEndpoints?: LogoutEndpoint[]; serviceEnabled?: boolean; - relyingPartyOverrides: RelyingPartyOverrides; - attributeRelease: string[]; + relyingPartyOverrides?: RelyingPartyOverrides; + attributeRelease?: string[]; } diff --git a/ui/src/app/metadata/domain/model/wizards/metadata-source-wizard.ts b/ui/src/app/metadata/domain/model/wizards/metadata-source-wizard.ts index 82a7a2763..32e938008 100644 --- a/ui/src/app/metadata/domain/model/wizards/metadata-source-wizard.ts +++ b/ui/src/app/metadata/domain/model/wizards/metadata-source-wizard.ts @@ -9,7 +9,7 @@ export class MetadataSourceWizard implements Wizard { index: 1, id: 'common', label: 'label.resolver-common-attributes', - schema: 'assets/schema/source/metadata-source.json', + schema: '/api/ui/MetadataSources', fields: [ 'serviceProviderName', 'entityId' @@ -28,7 +28,7 @@ export class MetadataSourceWizard implements Wizard { index: 2, id: 'org-info', label: 'label.org-info', - schema: 'assets/schema/source/metadata-source.json', + schema: '/api/ui/MetadataSources', fields: [ 'organization', 'contacts' @@ -52,7 +52,7 @@ export class MetadataSourceWizard implements Wizard { index: 3, id: 'metadata-ui', label: 'label.metadata-ui', - schema: 'assets/schema/source/metadata-source.json', + schema: '/api/ui/MetadataSources', fields: [ 'mdui' ] @@ -61,7 +61,7 @@ export class MetadataSourceWizard implements Wizard { index: 4, id: 'descriptor-info', label: 'label.descriptor-info', - schema: 'assets/schema/source/metadata-source.json', + schema: '/api/ui/MetadataSources', fields: [ 'serviceProviderSsoDescriptor' ] @@ -70,7 +70,7 @@ export class MetadataSourceWizard implements Wizard { index: 5, id: 'logout-endpoints', label: 'label.logout-endpoints', - schema: 'assets/schema/source/metadata-source.json', + schema: '/api/ui/MetadataSources', fields: [ 'logoutEndpoints' ], @@ -87,7 +87,7 @@ export class MetadataSourceWizard implements Wizard { index: 6, id: 'key-info', label: 'label.key-info', - schema: 'assets/schema/source/metadata-source.json', + schema: '/api/ui/MetadataSources', fields: [ 'securityInfo' ] @@ -96,7 +96,7 @@ export class MetadataSourceWizard implements Wizard { index: 7, id: 'assertion', label: 'label.assertion', - schema: 'assets/schema/source/metadata-source.json', + schema: '/api/ui/MetadataSources', fields: [ 'assertionConsumerServices' ] @@ -105,7 +105,7 @@ export class MetadataSourceWizard implements Wizard { index: 8, id: 'relying-party', label: 'label.relying-party', - schema: 'assets/schema/source/metadata-source.json', + schema: '/api/ui/MetadataSources', fields: [ 'relyingPartyOverrides' ] @@ -114,7 +114,7 @@ export class MetadataSourceWizard implements Wizard { index: 9, id: 'attribute', label: 'label.attribute-release', - schema: 'assets/schema/source/metadata-source.json', + schema: '/api/ui/MetadataSources', fields: [ 'attributeRelease' ] @@ -123,7 +123,7 @@ export class MetadataSourceWizard implements Wizard { index: 10, id: 'finish', label: 'label.finished', - schema: 'assets/schema/source/metadata-source.json', + schema: '/api/ui/MetadataSources', fields: [ 'serviceEnabled' ], diff --git a/ui/src/app/metadata/domain/service/draft.service.ts b/ui/src/app/metadata/domain/service/draft.service.ts index a31f8c798..76dcb9f85 100644 --- a/ui/src/app/metadata/domain/service/draft.service.ts +++ b/ui/src/app/metadata/domain/service/draft.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; -import { Observable, of } from 'rxjs'; +import { Observable, of, throwError } from 'rxjs'; import { switchMap } from 'rxjs/operators'; import { MetadataResolver } from '../../domain/model'; @@ -18,12 +18,13 @@ export class EntityDraftService { return of(this.storage.query()); } - find(entityId: string): Observable { + find(id: string, attr: string = 'resourceId'): Observable { + if (!id) { + return throwError(404); + } return this.query().pipe( switchMap( - list => of( - list.find(entity => entity.entityId === entityId) - ) + list => of(list.find(entity => entity[attr] === id)) ) ); } @@ -34,15 +35,19 @@ export class EntityDraftService { } remove(provider: MetadataResolver): Observable { - this.storage.removeByAttr(provider.entityId, 'entityId'); + this.storage.removeByAttr(provider.resourceId, 'resourceId'); return of(provider); } update(provider: MetadataResolver): Observable { - let stored = this.storage.findByAttr(provider.id, 'entityId'); - stored = Object.assign({}, stored, provider); - this.storage.removeByAttr(provider.entityId, 'entityId'); - this.storage.add(stored); - return of(stored); + let stored = this.storage.findByAttr(provider.resourceId, 'resourceId'); + if (stored) { + stored = { ...stored, ...provider }; + this.storage.removeByAttr(provider.resourceId, 'resourceId'); + this.storage.add(stored); + return of(stored); + } else { + return throwError(404); + } } } /* istanbul ignore next */ diff --git a/ui/src/app/metadata/domain/service/resolver.service.ts b/ui/src/app/metadata/domain/service/resolver.service.ts index c3486de76..f0c9f4b3c 100644 --- a/ui/src/app/metadata/domain/service/resolver.service.ts +++ b/ui/src/app/metadata/domain/service/resolver.service.ts @@ -33,7 +33,8 @@ export class ResolverService { } save(provider: MetadataResolver): Observable { - return this.http.post(`${this.base}${this.endpoint}`, provider); + const { id, ...p } = provider; + return this.http.post(`${this.base}${this.endpoint}`, p); } remove(provider: MetadataResolver): Observable { diff --git a/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.ts b/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.ts index b3d331387..8f8caca24 100644 --- a/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.ts +++ b/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.ts @@ -74,7 +74,7 @@ export class DashboardResolversListComponent implements OnInit { if (entity.isDraft()) { this.router.navigate(['metadata', 'resolver', 'new'], { queryParams: { - entityId: entity.getId() + id: entity.getId() } }); } else { diff --git a/ui/src/app/metadata/resolver/action/draft.action.ts b/ui/src/app/metadata/resolver/action/draft.action.ts index f4bba2744..5826b343c 100644 --- a/ui/src/app/metadata/resolver/action/draft.action.ts +++ b/ui/src/app/metadata/resolver/action/draft.action.ts @@ -4,7 +4,9 @@ import { MetadataResolver } from '../../domain/model'; export enum DraftActionTypes { FIND = '[Metadata Draft] Find', - SELECT = '[Metadata Draft] Select', + SELECT_REQUEST = '[Metadata Draft] Select Request', + SELECT_SUCCESS = '[Metadata Draft] Select Success', + SELECT_ERROR = '[Metadata Draft] Select Error', UPDATE_DRAFT_REQUEST = '[Metadata Draft] Update Request', UPDATE_DRAFT_SUCCESS = '[Metadata Draft] Update Success', UPDATE_DRAFT_FAIL = '[Metadata Draft] Update Fail', @@ -19,19 +21,24 @@ export enum DraftActionTypes { REMOVE_DRAFT_FAIL = '[Metadata Draft Collection] Remove Draft Fail' } - -export class FindDraft implements Action { - readonly type = DraftActionTypes.FIND; +export class SelectDraftRequest implements Action { + readonly type = DraftActionTypes.SELECT_REQUEST; constructor(public payload: string) { } } -export class SelectDraft implements Action { - readonly type = DraftActionTypes.SELECT; +export class SelectDraftSuccess implements Action { + readonly type = DraftActionTypes.SELECT_SUCCESS; constructor(public payload: string) { } } +export class SelectDraftError implements Action { + readonly type = DraftActionTypes.SELECT_ERROR; + + constructor() { } +} + export class UpdateDraftRequest implements Action { readonly type = DraftActionTypes.UPDATE_DRAFT_REQUEST; @@ -114,8 +121,9 @@ export type DraftActionsUnion = | RemoveDraftRequest | RemoveDraftSuccess | RemoveDraftFail - | FindDraft - | SelectDraft + | SelectDraftRequest + | SelectDraftSuccess + | SelectDraftError | UpdateDraftRequest | UpdateDraftSuccess | UpdateDraftFail; diff --git a/ui/src/app/metadata/resolver/container/draft.component.ts b/ui/src/app/metadata/resolver/container/draft.component.ts index e8c865c53..687ad2260 100644 --- a/ui/src/app/metadata/resolver/container/draft.component.ts +++ b/ui/src/app/metadata/resolver/container/draft.component.ts @@ -5,7 +5,7 @@ import { distinctUntilChanged, map } from 'rxjs/operators'; import { Store } from '@ngrx/store'; import { NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; -import { SelectDraft } from '../action/draft.action'; +import { SelectDraftRequest } from '../action/draft.action'; import * as fromCollection from '../reducer'; @Component({ @@ -23,7 +23,7 @@ export class DraftComponent implements OnDestroy { ) { this.actionsSubscription = route.params.pipe( distinctUntilChanged(), - map(params => new SelectDraft(params.entityId)) + map(params => new SelectDraftRequest(params.entityId)) ).subscribe(store); } diff --git a/ui/src/app/metadata/resolver/container/new-resolver.component.ts b/ui/src/app/metadata/resolver/container/new-resolver.component.ts index ce42ea511..cf654069c 100644 --- a/ui/src/app/metadata/resolver/container/new-resolver.component.ts +++ b/ui/src/app/metadata/resolver/container/new-resolver.component.ts @@ -2,7 +2,7 @@ import { Component } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Observable, Subscription } from 'rxjs'; import { map, withLatestFrom, distinctUntilChanged } from 'rxjs/operators'; -import { SelectDraft } from '../action/draft.action'; +import { SelectDraftRequest } from '../action/draft.action'; import { Store } from '@ngrx/store'; import * as fromCollection from '../reducer'; @@ -28,7 +28,7 @@ export class NewResolverComponent { this.actionsSubscription = this.route.queryParams.pipe( distinctUntilChanged(), - map(params => new SelectDraft(params.entityId)) - ).subscribe(store); + map(params => new SelectDraftRequest(params.id)) + ).subscribe(this.store); } } diff --git a/ui/src/app/metadata/resolver/container/resolver-wizard-step.component.ts b/ui/src/app/metadata/resolver/container/resolver-wizard-step.component.ts index 5e09b5215..6b37348aa 100644 --- a/ui/src/app/metadata/resolver/container/resolver-wizard-step.component.ts +++ b/ui/src/app/metadata/resolver/container/resolver-wizard-step.component.ts @@ -75,7 +75,9 @@ export class ResolverWizardStepComponent implements OnDestroy { map(([changes, original]) => ({ ...original, ...changes })) ) .subscribe(changes => { - this.store.dispatch(new UpdateChanges(changes)); + if (changes.resourceId) { + this.store.dispatch(new UpdateChanges(changes)); + } }); this.statusChangeEmitted$.pipe(distinctUntilChanged()).subscribe(errors => this.updateStatus(errors)); diff --git a/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts b/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts index 0a62978ab..1f98d87ed 100644 --- a/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts +++ b/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts @@ -62,7 +62,6 @@ export class ResolverWizardComponent implements OnDestroy, CanComponentDeactivat private store: Store, private route: ActivatedRoute, private router: Router, - private modalService: NgbModal, @Inject(METADATA_SOURCE_WIZARD) private sourceWizard: Wizard ) { this.store diff --git a/ui/src/app/metadata/resolver/effect/draft-collection.effects.ts b/ui/src/app/metadata/resolver/effect/draft-collection.effects.ts index 73daf4de8..8b73d331e 100644 --- a/ui/src/app/metadata/resolver/effect/draft-collection.effects.ts +++ b/ui/src/app/metadata/resolver/effect/draft-collection.effects.ts @@ -5,7 +5,12 @@ import { Router } from '@angular/router'; import { of } from 'rxjs'; import { switchMap, map, catchError, tap } from 'rxjs/operators'; -import { DraftActionTypes } from '../action/draft.action'; +import { + DraftActionTypes, + SelectDraftRequest, + SelectDraftError, + SelectDraftSuccess +} from '../action/draft.action'; import * as actions from '../action/draft.action'; import { EntityDraftService } from '../../domain/service/draft.service'; @@ -66,7 +71,6 @@ export class DraftCollectionEffects { ofType(DraftActionTypes.UPDATE_DRAFT_REQUEST), map(getPayload), switchMap(provider => { - console.log(provider); return this.draftService .update(provider) .pipe( @@ -80,29 +84,49 @@ export class DraftCollectionEffects { @Effect() selectDraft$ = this.actions$.pipe( - ofType(DraftActionTypes.SELECT), + ofType(DraftActionTypes.SELECT_REQUEST), map(getPayload), switchMap(id => this.draftService .find(id) .pipe( - map(p => new actions.FindDraft(p.entityId)) + map(p => new SelectDraftSuccess(p.resourceId)), + catchError(e => of(new SelectDraftError())) ) ) ); @Effect() - removeDraft$ = this.actions$.pipe( - ofType(DraftActionTypes.REMOVE_DRAFT), + selectDraftReload$ = this.actions$.pipe( + ofType(DraftActionTypes.SELECT_REQUEST), map(getPayload), - switchMap(provider => + map(id => new actions.LoadDraftRequest()) + ); + + @Effect() + selectDraftError$ = this.actions$.pipe( + ofType(DraftActionTypes.SELECT_ERROR), + map(getPayload), + switchMap(id => this.draftService - .remove(provider) + .save({ resourceId: `r-${ Date.now() }`, serviceProviderName: '' }) .pipe( - map(p => new actions.RemoveDraftSuccess(p)) + map(p => new SelectDraftRequest(p.resourceId)), + catchError(e => of(new SelectDraftError())) ) ) ); + + @Effect() + removeDraft$ = this.actions$.pipe( + ofType(DraftActionTypes.REMOVE_DRAFT), + map(getPayload), + switchMap(provider => this.draftService.find(provider.entityId, 'entityId').pipe( + switchMap(selected => this.draftService.remove(selected)), + map(p => new actions.RemoveDraftSuccess(p)) + ) + ) + ); @Effect() removeDraftSuccessReload$ = this.actions$.pipe( ofType(DraftActionTypes.REMOVE_DRAFT), diff --git a/ui/src/app/metadata/resolver/effect/wizard.effect.ts b/ui/src/app/metadata/resolver/effect/wizard.effect.ts index 3aa75c3f9..e8ece35c7 100644 --- a/ui/src/app/metadata/resolver/effect/wizard.effect.ts +++ b/ui/src/app/metadata/resolver/effect/wizard.effect.ts @@ -17,8 +17,7 @@ import { import * as fromResolver from '../reducer'; import { EntityDraftService } from '../../domain/service/draft.service'; -import { SetIndex, WizardActionTypes } from '../../../wizard/action/wizard.action'; -import { UpdateDraftRequest } from '../action/draft.action'; +import { UpdateDraftRequest, SelectDraftSuccess, DraftActionTypes } from '../action/draft.action'; @@ -41,19 +40,12 @@ export class WizardEffects { @Effect({ dispatch: false }) updateEntityIdInUrl$ = this.actions$.pipe( - ofType(ResolverEntityActionTypes.UPDATE_CHANGES), + ofType(DraftActionTypes.SELECT_SUCCESS), map(action => action.payload), - withLatestFrom( - this.store.select(fromResolver.getEntityChanges), - this.activatedRoute.queryParams - ), - tap(([id, changes, params]) => { + tap((id) => { this.router.navigate([], { relativeTo: this.activatedRoute, - queryParams: { - ...params, - entityId: changes.entityId - }, + queryParams: { id }, queryParamsHandling: 'merge' }); }) diff --git a/ui/src/app/metadata/resolver/reducer/draft.reducer.ts b/ui/src/app/metadata/resolver/reducer/draft.reducer.ts index e642d6b8a..d49cabf38 100644 --- a/ui/src/app/metadata/resolver/reducer/draft.reducer.ts +++ b/ui/src/app/metadata/resolver/reducer/draft.reducer.ts @@ -8,7 +8,7 @@ export interface DraftState extends EntityState { } export const adapter: EntityAdapter = createEntityAdapter({ - selectId: (model: MetadataResolver) => model.entityId + selectId: (model: MetadataResolver) => model.resourceId }); export const initialState: DraftState = adapter.getInitialState({ @@ -29,10 +29,10 @@ export function reducer(state = initialState, action: DraftActionsUnion): DraftS } case DraftActionTypes.REMOVE_DRAFT_SUCCESS: { - return adapter.removeOne(action.payload.entityId, state); + return adapter.removeOne(action.payload.resourceId, state); } - case DraftActionTypes.SELECT: { + case DraftActionTypes.SELECT_SUCCESS: { return { ...state, selectedDraftId: action.payload,