web/admin: show policy binding form when creating policy in bound list

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2022-12-25 14:59:45 +01:00
parent ae13fc3b92
commit bfa0360764
No known key found for this signature in database
5 changed files with 65 additions and 26 deletions

View File

@ -199,6 +199,10 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
${t`Create Binding`} ${t`Create Binding`}
</button> </button>
</ak-forms-modal> </ak-forms-modal>
<ak-policy-wizard createText=${t`Create Policy`}></ak-policy-wizard> `; <ak-policy-wizard
createText=${t`Create Policy`}
?showBindingPage=${true}
bindingTarget=${ifDefined(this.target)}
></ak-policy-wizard> `;
} }
} }

View File

@ -64,7 +64,7 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
policyOnly = false; policyOnly = false;
getSuccessMessage(): string { getSuccessMessage(): string {
if (this.instance) { if (this.instance?.pk) {
return t`Successfully updated binding.`; return t`Successfully updated binding.`;
} else { } else {
return t`Successfully created binding.`; return t`Successfully created binding.`;
@ -84,9 +84,9 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
} }
send = (data: PolicyBinding): Promise<PolicyBinding> => { send = (data: PolicyBinding): Promise<PolicyBinding> => {
if (this.instance) { if (this.instance?.pk) {
return new PoliciesApi(DEFAULT_CONFIG).policiesBindingsUpdate({ return new PoliciesApi(DEFAULT_CONFIG).policiesBindingsUpdate({
policyBindingUuid: this.instance.pk || "", policyBindingUuid: this.instance.pk,
policyBindingRequest: data, policyBindingRequest: data,
}); });
} else { } else {
@ -111,21 +111,18 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
`; `;
} }
getOrder(): Promise<number> { async getOrder(): Promise<number> {
if (this.instance) { if (this.instance?.pk) {
return Promise.resolve(this.instance.order); return this.instance.order;
} }
return new PoliciesApi(DEFAULT_CONFIG) const bindings = await new PoliciesApi(DEFAULT_CONFIG).policiesBindingsList({
.policiesBindingsList({ target: this.targetPk || "",
target: this.targetPk || "", });
}) const orders = bindings.results.map((binding) => binding.order);
.then((bindings) => { if (orders.length < 1) {
const orders = bindings.results.map((binding) => binding.order); return 0;
if (orders.length < 1) { }
return 0; return Math.max(...orders) + 1;
}
return Math.max(...orders) + 1;
});
} }
renderModeSelector(): TemplateResult { renderModeSelector(): TemplateResult {

View File

@ -1,3 +1,4 @@
import { PolicyBindingForm } from "@goauthentik/admin/policies/PolicyBindingForm";
import "@goauthentik/admin/policies/dummy/DummyPolicyForm"; import "@goauthentik/admin/policies/dummy/DummyPolicyForm";
import "@goauthentik/admin/policies/event_matcher/EventMatcherPolicyForm"; import "@goauthentik/admin/policies/event_matcher/EventMatcherPolicyForm";
import "@goauthentik/admin/policies/expiry/ExpiryPolicyForm"; import "@goauthentik/admin/policies/expiry/ExpiryPolicyForm";
@ -9,6 +10,7 @@ import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { AKElement } from "@goauthentik/elements/Base"; import { AKElement } from "@goauthentik/elements/Base";
import "@goauthentik/elements/forms/ProxyForm"; import "@goauthentik/elements/forms/ProxyForm";
import "@goauthentik/elements/wizard/FormWizardPage"; import "@goauthentik/elements/wizard/FormWizardPage";
import { FormWizardPage } from "@goauthentik/elements/wizard/FormWizardPage";
import "@goauthentik/elements/wizard/Wizard"; import "@goauthentik/elements/wizard/Wizard";
import { WizardPage } from "@goauthentik/elements/wizard/WizardPage"; import { WizardPage } from "@goauthentik/elements/wizard/WizardPage";
@ -24,7 +26,7 @@ import PFForm from "@patternfly/patternfly/components/Form/form.css";
import PFRadio from "@patternfly/patternfly/components/Radio/radio.css"; import PFRadio from "@patternfly/patternfly/components/Radio/radio.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { PoliciesApi, TypeCreate } from "@goauthentik/api"; import { PoliciesApi, Policy, PolicyBinding, TypeCreate } from "@goauthentik/api";
@customElement("ak-policy-wizard-initial") @customElement("ak-policy-wizard-initial")
export class InitialPolicyWizardPage extends WizardPage { export class InitialPolicyWizardPage extends WizardPage {
@ -46,10 +48,12 @@ export class InitialPolicyWizardPage extends WizardPage {
name="type" name="type"
id=${`${type.component}-${type.modelName}`} id=${`${type.component}-${type.modelName}`}
@change=${() => { @change=${() => {
this.host.steps = [ const idx = this.host.steps.indexOf("initial") + 1;
"initial", this.host.steps.splice(
idx,
0,
`type-${type.component}-${type.modelName}`, `type-${type.component}-${type.modelName}`,
]; );
this.host.isValid = true; this.host.isValid = true;
}} }}
/> />
@ -72,6 +76,12 @@ export class PolicyWizard extends AKElement {
@property() @property()
createText = t`Create`; createText = t`Create`;
@property({ type: Boolean })
showBindingPage = false;
@property()
bindingTarget?: string;
@property({ attribute: false }) @property({ attribute: false })
policyTypes: TypeCreate[] = []; policyTypes: TypeCreate[] = [];
@ -84,7 +94,7 @@ export class PolicyWizard extends AKElement {
render(): TemplateResult { render(): TemplateResult {
return html` return html`
<ak-wizard <ak-wizard
.steps=${["initial"]} .steps=${this.showBindingPage ? ["initial", "create-binding"] : ["initial"]}
header=${t`New policy`} header=${t`New policy`}
description=${t`Create a new policy.`} description=${t`Create a new policy.`}
> >
@ -100,6 +110,27 @@ export class PolicyWizard extends AKElement {
</ak-wizard-page-form> </ak-wizard-page-form>
`; `;
})} })}
${this.showBindingPage
? html`<ak-wizard-page-form
slot="create-binding"
.sidebarLabel=${() => t`Create Binding`}
.activePageCallback=${async (context: FormWizardPage) => {
const createSlot = context.host.steps[1];
const bindingForm =
context.querySelector<PolicyBindingForm>(
"ak-policy-binding-form",
);
if (!bindingForm) return;
bindingForm.instance = {
policy: (context.host.state[createSlot] as Policy).pk,
} as PolicyBinding;
}}
>
<ak-policy-binding-form
.targetPk=${this.bindingTarget}
></ak-policy-binding-form>
</ak-wizard-page-form>`
: html``}
<button slot="trigger" class="pf-c-button pf-m-primary">${this.createText}</button> <button slot="trigger" class="pf-c-button pf-m-primary">${this.createText}</button>
</ak-wizard> </ak-wizard>
`; `;

View File

@ -11,9 +11,15 @@ import { customElement } from "lit/decorators.js";
*/ */
@customElement("ak-wizard-page-form") @customElement("ak-wizard-page-form")
export class FormWizardPage extends WizardPage { export class FormWizardPage extends WizardPage {
activePageCallback: (context: FormWizardPage) => Promise<void> = async () => {
return Promise.resolve();
};
activeCallback = async () => { activeCallback = async () => {
this.host.isValid = true; this.host.isValid = true;
this.activePageCallback(this);
}; };
nextCallback = async () => { nextCallback = async () => {
const form = this.querySelector<Form<unknown>>("*"); const form = this.querySelector<Form<unknown>>("*");
if (!form) { if (!form) {
@ -24,7 +30,9 @@ export class FormWizardPage extends WizardPage {
return Promise.reject(t`Form didn't return a promise for submitting`); return Promise.reject(t`Form didn't return a promise for submitting`);
} }
return formPromise return formPromise
.then(() => { .then((data) => {
this.host.state[this.slot] = data;
this.host.canBack = false;
return true; return true;
}) })
.catch(() => { .catch(() => {

View File

@ -22,9 +22,8 @@ export class WizardPage extends AKElement {
return this.parentElement as Wizard; return this.parentElement as Wizard;
} }
activeCallback: () => Promise<void> = () => { activeCallback: () => Promise<void> = async () => {
this.host.isValid = false; this.host.isValid = false;
return Promise.resolve();
}; };
nextCallback: () => Promise<boolean> = async () => { nextCallback: () => Promise<boolean> = async () => {