14f0034a0a
* web/elements: only render form once instance is loaded Signed-off-by: Jens Langhammer <jens@goauthentik.io> * use radio for transport Signed-off-by: Jens Langhammer <jens@goauthentik.io> * only wait for instance to be loaded if set Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add hook to load additional data in form Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make send an abstract function instead of attribute Signed-off-by: Jens Langhammer <jens@goauthentik.io> * ensure form is updated after data is loaded Signed-off-by: Jens Langhammer <jens@goauthentik.io> * remove until for select and multi-selects in forms Signed-off-by: Jens Langhammer <jens@goauthentik.io> * don't use until for file uploads Signed-off-by: Jens Langhammer <jens@goauthentik.io> * remove last until from form Signed-off-by: Jens Langhammer <jens@goauthentik.io> * remove deprecated import Signed-off-by: Jens Langhammer <jens@goauthentik.io> * prevent form double load, add error handling for PreventFormSubmit Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix double creation of inner element in proxy form Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make PreventFormSubmit work correctly Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
92 lines
2.9 KiB
TypeScript
92 lines
2.9 KiB
TypeScript
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
|
import "@goauthentik/elements/EmptyState";
|
|
import { Form } from "@goauthentik/elements/forms/Form";
|
|
|
|
import { TemplateResult, html } from "lit";
|
|
import { property } from "lit/decorators.js";
|
|
|
|
export abstract class ModelForm<T, PKT extends string | number> extends Form<T> {
|
|
abstract loadInstance(pk: PKT): Promise<T>;
|
|
|
|
async load(): Promise<void> {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
@property({ attribute: false })
|
|
set instancePk(value: PKT) {
|
|
this._instancePk = value;
|
|
if (this.viewportCheck && !this.isInViewport) {
|
|
return;
|
|
}
|
|
if (this._isLoading) {
|
|
return;
|
|
}
|
|
this._isLoading = true;
|
|
this.load().then(() => {
|
|
this.loadInstance(value).then((instance) => {
|
|
this.instance = instance;
|
|
this._isLoading = false;
|
|
this.requestUpdate();
|
|
});
|
|
});
|
|
}
|
|
|
|
private _instancePk?: PKT;
|
|
|
|
// Keep track if we've loaded the model instance
|
|
private _initialLoad = false;
|
|
// Keep track if we've done the general data loading of load()
|
|
private _initialDataLoad = false;
|
|
|
|
private _isLoading = false;
|
|
|
|
@property({ attribute: false })
|
|
instance?: T = this.defaultInstance;
|
|
|
|
get defaultInstance(): T | undefined {
|
|
return undefined;
|
|
}
|
|
|
|
constructor() {
|
|
super();
|
|
this.addEventListener(EVENT_REFRESH, () => {
|
|
if (!this._instancePk) return;
|
|
this.loadInstance(this._instancePk).then((instance) => {
|
|
this.instance = instance;
|
|
});
|
|
});
|
|
}
|
|
|
|
resetForm(): void {
|
|
this.instance = undefined;
|
|
this._initialLoad = false;
|
|
}
|
|
|
|
renderVisible(): TemplateResult {
|
|
if ((this._instancePk && !this.instance) || !this._initialDataLoad) {
|
|
return html`<ak-empty-state ?loading=${true}></ak-empty-state>`;
|
|
}
|
|
return super.renderVisible();
|
|
}
|
|
|
|
render(): TemplateResult {
|
|
// if we're in viewport now and haven't loaded AND have a PK set, load now
|
|
// Or if we don't check for viewport in some cases
|
|
const viewportVisible = this.isInViewport || !this.viewportCheck;
|
|
if (this._instancePk && !this._initialLoad && viewportVisible) {
|
|
this.instancePk = this._instancePk;
|
|
this._initialLoad = true;
|
|
} else if (!this._initialDataLoad && viewportVisible) {
|
|
// else if since if the above case triggered that will also call this.load(), so
|
|
// ensure we don't load again
|
|
this.load().then(() => {
|
|
this._initialDataLoad = true;
|
|
// Class attributes changed in this.load() might not be @property()
|
|
// or @state() so let's trigger a re-render to be sure we get updated
|
|
this.requestUpdate();
|
|
});
|
|
}
|
|
return super.render();
|
|
}
|
|
}
|