[33392] Allow to cache requests in the course of the changeset

We need to reload requests whenever the changeset changes e.g., the
project.

By providing a cache within the temporary changeset, we can easily cache
requests until the changeset completes, or the form is reloaded.

https://community.openproject.com/wp/33392
pull/8395/head
Oliver Günther 5 years ago
parent bfe9d6b4c2
commit 4c575217bb
No known key found for this signature in database
GPG Key ID: A3A8BDAD7C0C552C
  1. 21
      frontend/src/app/modules/fields/changeset/resource-changeset.ts
  2. 14
      frontend/src/app/modules/fields/edit/field-types/select-edit-field.component.ts
  3. 4
      frontend/src/app/modules/fields/edit/field-types/te-work-package-edit-field.component.ts

@ -25,6 +25,9 @@ export class ResourceChangeset<T extends HalResource|{ [key:string]:unknown; } =
/** Reference and load promise for the current form */
protected form$ = input<FormResource>();
/** Request cache for objects within the changeset for the current form */
protected cache:{ [key:string]:Promise<unknown> } = {};
/** Flag whether this is currently being saved */
public inFlight = false;
@ -94,6 +97,10 @@ export class ResourceChangeset<T extends HalResource|{ [key:string]:unknown; } =
.toPromise();
}
/**
* Cache some promised value in the course of this changeset.
* Will get cleared automatically by the changeset on destroy/submission
*/
/**
* Posts to the form with the current changes
@ -106,6 +113,7 @@ export class ResourceChangeset<T extends HalResource|{ [key:string]:unknown; } =
.$links
.update(payload)
.then((form:FormResource) => {
this.cache = {};
this.form$.putValue(form);
this.setNewDefaults(form);
this.push();
@ -223,6 +231,7 @@ export class ResourceChangeset<T extends HalResource|{ [key:string]:unknown; } =
public clear() {
this.state && this.state.clear();
this.changeset.clear();
this.cache = {};
this.form$.clear();
}
@ -252,6 +261,18 @@ export class ResourceChangeset<T extends HalResource|{ [key:string]:unknown; } =
return this.form$.getValueOr(this.pristineResource).schema;
}
/**
* Access some promised value
* that should be cached for the lifetime duration of the form.
*/
public cacheValue<T>(key:string, request:() => Promise<T>):Promise<T> {
if (this.cache[key]) {
return this.cache[key] as Promise<T>;
}
return this.cache[key] = request();
}
protected get minimalPayload() {
return { lockVersion: this.pristineResource.lockVersion, _links: {} };
}

@ -153,7 +153,7 @@ export class SelectEditFieldComponent extends EditFieldComponent implements OnIn
protected loadValuesFromBackend(query?:string) {
return from(
this.allowedValuesFetch(query)
this.loadAllowedValues(query)
).pipe(
tap(collection => {
// if it is an unpaginated collection or if we get all possible entries when fetching with a blank
@ -174,7 +174,17 @@ export class SelectEditFieldComponent extends EditFieldComponent implements OnIn
);
}
protected allowedValuesFetch(query?:string) {
protected loadAllowedValues(query?:string):Promise<CollectionResource> {
// Cache the search without any params
if (!query) {
const cacheKey = this.schema.allowedValues.$link.href;
return this.change.cacheValue(cacheKey, this.fetchAllowedValueQuery.bind(this));
}
return this.fetchAllowedValueQuery(query);
}
protected fetchAllowedValueQuery(query?:string) {
return this.schema.allowedValues.$link.$fetch(this.allowedValuesFilter(query)) as Promise<CollectionResource>;
}

@ -93,10 +93,10 @@ export class TimeEntryWorkPackageEditFieldComponent extends WorkPackageEditField
.map((timeEntry) => timeEntry.workPackage.idFromLink)
.filter((v, i, a) => a.indexOf(v) === i);
return super.allowedValuesFetch(query);
return super.loadAllowedValues(query);
});
} else {
return super.allowedValuesFetch(query);
return super.loadAllowedValues(query);
}
}

Loading…
Cancel
Save