diff --git a/ui/src/app/metadata/domain/model/wizards/metadata-source-base.ts b/ui/src/app/metadata/domain/model/wizards/metadata-source-base.ts index 8a6604c5a..ebc8921d8 100644 --- a/ui/src/app/metadata/domain/model/wizards/metadata-source-base.ts +++ b/ui/src/app/metadata/domain/model/wizards/metadata-source-base.ts @@ -85,7 +85,6 @@ export class MetadataSourceBase implements Wizard { errors.push(error); } }); - console.log(errors, form_current); return errors; }, '/entityId': (value, property, form) => { diff --git a/ui/src/app/metadata/domain/service/draft.service.ts b/ui/src/app/metadata/domain/service/draft.service.ts index b43713359..824e8ec64 100644 --- a/ui/src/app/metadata/domain/service/draft.service.ts +++ b/ui/src/app/metadata/domain/service/draft.service.ts @@ -29,6 +29,10 @@ export class EntityDraftService { ); } + exists(id: string, attr: string = 'id'): boolean { + return this.storage.query().some(entity => entity[attr] === id); + } + save(provider: MetadataResolver): Observable { this.storage.add(provider); return of(provider); 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 e6577886d..537cf198c 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 @@ -72,7 +72,7 @@ export class DashboardResolversListComponent implements OnInit { edit(entity: MetadataEntity): void { if (entity.isDraft()) { - this.router.navigate(['metadata', 'resolver', 'new', 'blank', 'org-info'], { + this.router.navigate(['metadata', 'resolver', 'new', 'blank', 'common'], { queryParams: { id: entity.getId() } diff --git a/ui/src/app/metadata/resolver/container/new-resolver.component.html b/ui/src/app/metadata/resolver/container/new-resolver.component.html index 924321a93..efaea7239 100644 --- a/ui/src/app/metadata/resolver/container/new-resolver.component.html +++ b/ui/src/app/metadata/resolver/container/new-resolver.component.html @@ -19,7 +19,8 @@

How are you ad class="btn btn-lg btn-block btn-secondary" aria-label="Upload local metadata file or use a metadata URL" role="button" - routerLink="upload" + [routerLink]="['./', 'upload']" + queryParamsHandling="merge" routerLinkActive="btn-success"> Upload/URL @@ -33,7 +34,8 @@

How are you ad class="btn btn-lg btn-block btn-secondary" aria-label="Create metadata source using the wizard" role="button" - [routerLink]="['./']" + [routerLink]="['./', 'blank', 'common']" + queryParamsHandling="merge" routerLinkActive="btn-info"> Create @@ -47,7 +49,8 @@

How are you ad class="btn btn-lg btn-block btn-secondary" aria-label="Copy a metadata source" role="button" - routerLink="copy" + [routerLink]="['./', 'copy']" + queryParamsHandling="merge" routerLinkActive="btn-warning"> Copy 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 ff916d836..fa51a426d 100644 --- a/ui/src/app/metadata/resolver/container/new-resolver.component.ts +++ b/ui/src/app/metadata/resolver/container/new-resolver.component.ts @@ -27,7 +27,7 @@ export class NewResolverComponent { debounceTime(10), map(url => { let child = this.route.snapshot.firstChild; - return child.routeConfig.path.match('blank').length === 0 || child.params.index === 'common'; + return !child.routeConfig.path.match('blank') || child.params.index === 'common'; }) ); 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 566291404..bd5dfced5 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 @@ -77,14 +77,10 @@ export class ResolverWizardStepComponent implements OnDestroy { this.valueChangeEmitted$.pipe( withLatestFrom(this.definition$), filter(([ changes, definition ]) => (!!definition && !!changes)), - map(([ changes, definition ]) => definition.parser(changes.value)), - withLatestFrom(this.store.select(fromResolver.getSelectedDraft)), - map(([changes, original]) => ({ ...original, ...changes })) + map(([ changes, definition ]) => definition.parser(changes.value)) ) .subscribe(changes => { - if (changes.id) { - this.store.dispatch(new UpdateChanges(changes)); - } + 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 d6cac6053..c3c7881f1 100644 --- a/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts +++ b/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts @@ -12,6 +12,7 @@ import { import { Observable, Subject, of, combineLatest as combine } from 'rxjs'; import { skipWhile, startWith, distinctUntilChanged, map, takeUntil, combineLatest } from 'rxjs/operators'; import { Store } from '@ngrx/store'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { MetadataResolver } from '../../domain/model/metadata-resolver'; import * as fromCollections from '../reducer'; @@ -26,8 +27,8 @@ import { SetDefinition, SetIndex, SetDisabled, ClearWizard } from '../../../wiza import * as fromWizard from '../../../wizard/reducer'; import { LoadSchemaRequest } from '../../../wizard/action/wizard.action'; import { UnsavedEntityComponent } from '../../domain/component/unsaved-entity.dialog'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { Clear } from '../action/entity.action'; +import { DifferentialService } from '../../../core/service/differential.service'; @Component({ selector: 'resolver-wizard-page', @@ -66,6 +67,7 @@ export class ResolverWizardComponent implements OnDestroy, CanComponentDeactivat private route: ActivatedRoute, private router: Router, private modalService: NgbModal, + private diffService: DifferentialService, @Inject(METADATA_SOURCE_WIZARD) private sourceWizard: Wizard ) { this.store @@ -113,6 +115,8 @@ export class ResolverWizardComponent implements OnDestroy, CanComponentDeactivat combineLatest(this.resolver$, (changes, base) => ({ ...base, ...changes })) ).subscribe(latest => this.latest = latest); + // this.changes$.subscribe(c => console.log(c)); + this.summary$ = combine( this.store.select(fromWizard.getWizardDefinition), this.store.select(fromWizard.getSchemaCollection), @@ -128,6 +132,7 @@ export class ResolverWizardComponent implements OnDestroy, CanComponentDeactivat ); this.changes$.pipe(takeUntil(this.ngUnsubscribe)).subscribe(c => this.changes = c); + this.resolver$.pipe(takeUntil(this.ngUnsubscribe)).subscribe(r => this.resolver = r); } next(): void { @@ -160,6 +165,18 @@ export class ResolverWizardComponent implements OnDestroy, CanComponentDeactivat this.store.dispatch(new SetIndex(page)); } + hasChanges(changes: MetadataResolver): boolean { + // const updated = this.diffService.updatedDiff(this.resolver, changes); + // const deleted = this.diffService.deletedDiff(this.resolver, changes); + let blacklist = ['id', 'resourceId']; + return Object.keys(changes).filter(key => !(blacklist.indexOf(key) > -1)).length > 0; + } + + isNew(changes: MetadataResolver): boolean { + let blacklist = ['id', 'resourceId']; + return Object.keys(changes).filter(key => !(blacklist.indexOf(key) > -1)).length === 0; + } + ngOnDestroy(): void { this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); @@ -171,18 +188,23 @@ export class ResolverWizardComponent implements OnDestroy, CanComponentDeactivat currentState: RouterStateSnapshot, nextState: RouterStateSnapshot ): Observable { - if (nextState.url.match('blank') && !!nextState.root.queryParams.id) { return of(true); } - if (Object.keys(this.changes).length > 0) { + if (nextState.url.match('blank') && !!nextState.root.queryParams.id) { + return of(true); + } + if (this.hasChanges(this.changes)) { let modal = this.modalService.open(UnsavedEntityComponent); modal.componentInstance.message = 'resolver'; modal.result.then( () => { this.store.dispatch(new Clear()); - this.router.navigate([nextState.url]); + this.router.navigateByUrl(nextState.url); }, () => console.warn('denied') ); } + if (this.isNew(this.latest)) { + return of(true); + } return this.store.select(fromResolver.getEntityIsSaved); } } diff --git a/ui/src/app/metadata/resolver/effect/collection.effects.ts b/ui/src/app/metadata/resolver/effect/collection.effects.ts index 8824a02b3..d56110a7e 100644 --- a/ui/src/app/metadata/resolver/effect/collection.effects.ts +++ b/ui/src/app/metadata/resolver/effect/collection.effects.ts @@ -111,7 +111,10 @@ export class ResolverCollectionEffects { addResolverSuccessRemoveDraft$ = this.actions$.pipe( ofType(ResolverCollectionActionTypes.ADD_RESOLVER_SUCCESS), map(action => action.payload), - map(provider => new draftActions.RemoveDraftRequest(provider)) + map(provider => { + console.log(provider); + return new draftActions.RemoveDraftRequest(provider); + }) ); @Effect() diff --git a/ui/src/app/metadata/resolver/effect/wizard.effect.ts b/ui/src/app/metadata/resolver/effect/wizard.effect.ts index 69d24f732..1632fb441 100644 --- a/ui/src/app/metadata/resolver/effect/wizard.effect.ts +++ b/ui/src/app/metadata/resolver/effect/wizard.effect.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { Effect, Actions, ofType } from '@ngrx/effects'; import { ActivatedRoute, Router } from '@angular/router'; -import { map, filter, tap } from 'rxjs/operators'; +import { map, filter, tap, withLatestFrom } from 'rxjs/operators'; import { Store } from '@ngrx/store'; import { @@ -29,7 +29,8 @@ export class WizardEffects { ofType(ResolverEntityActionTypes.UPDATE_CHANGES), map(action => action.payload), filter(provider => !provider.createdDate), - map(provider => new UpdateDraftRequest(provider)) + withLatestFrom(this.store.select(fromResolver.getSelectedDraft)), + map(([provider, draft]) => new UpdateDraftRequest({ ...draft, ...provider })) ); @Effect() diff --git a/ui/src/app/metadata/resolver/service/create-draft.resolver.ts b/ui/src/app/metadata/resolver/service/create-draft.resolver.ts index d928d4849..1c6cb84a0 100644 --- a/ui/src/app/metadata/resolver/service/create-draft.resolver.ts +++ b/ui/src/app/metadata/resolver/service/create-draft.resolver.ts @@ -5,19 +5,28 @@ import { Store } from '@ngrx/store'; import { MetadataResolver } from '../../domain/model'; import { AddDraftRequest } from '../action/draft.action'; import * as fromResolver from '../reducer'; +import { EntityDraftService } from '../../domain/service/draft.service'; @Injectable() export class CreateDraftResolverService { constructor( - private store: Store + private store: Store, + private draftService: EntityDraftService ) { } resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Observable { - let id = route.paramMap.get('id'); - let resolver = { - id: `r-${Date.now()}` - }; + let id = route.queryParamMap.get('id'); + if (id) { + let exists = this.draftService.exists(id); + if (!exists) { + let resolver = {id}; + this.store.dispatch(new AddDraftRequest(resolver)); + } + } if (!id) { + let resolver = { + id: `r-${Date.now()}` + }; id = resolver.id; this.store.dispatch(new AddDraftRequest(resolver)); }