stages/prompt: Add Radio Button Group, Dropdown and Text Area prompt fields (#4822)

* Added radio-button prompt type in model

* Add radio-button prompt

* Refactored radio-button prompt; Added dropdown prompt

* Added tests

* Fixed unrelated to choice fields bug causing validation errors; Added more tests

* Added description for new prompts

* Added docs

* Fix lint

* Add forgotten file changes

* Fix lint

* Small fix

* Add text-area prompts

* Update authentik/stages/prompt/models.py

Co-authored-by: Jens L. <jens@beryju.org>
Signed-off-by: sdimovv <36302090+sdimovv@users.noreply.github.com>

* Update authentik/stages/prompt/models.py

Co-authored-by: Jens L. <jens@beryju.org>
Signed-off-by: sdimovv <36302090+sdimovv@users.noreply.github.com>

* Fix inline css

* remove AKGlobal, update schema

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: sdimovv <36302090+sdimovv@users.noreply.github.com>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@beryju.org>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
sdimovv
2023-03-19 19:56:17 +02:00
committed by GitHub
parent 4da18b5f0c
commit 8b52d711e8
9 changed files with 475 additions and 30 deletions

View File

@ -49,12 +49,24 @@ export class PromptForm extends ModelForm<Prompt, string> {
>
${t`Text: Simple Text input`}
</option>
<option
value=${PromptTypeEnum.TextArea}
?selected=${this.instance?.type === PromptTypeEnum.TextArea}
>
${t`Text Area: Multiline text input`}
</option>
<option
value=${PromptTypeEnum.TextReadOnly}
?selected=${this.instance?.type === PromptTypeEnum.TextReadOnly}
>
${t`Text (read-only): Simple Text input, but cannot be edited.`}
</option>
<option
value=${PromptTypeEnum.TextAreaReadOnly}
?selected=${this.instance?.type === PromptTypeEnum.TextAreaReadOnly}
>
${t`Text Area (read-only): Multiline text input, but cannot be edited.`}
</option>
<option
value=${PromptTypeEnum.Username}
?selected=${this.instance?.type === PromptTypeEnum.Username}
@ -85,6 +97,18 @@ export class PromptForm extends ModelForm<Prompt, string> {
>
${t`Checkbox`}
</option>
<option
value=${PromptTypeEnum.RadioButtonGroup}
?selected=${this.instance?.type === PromptTypeEnum.RadioButtonGroup}
>
${t`Radio Button Group (fixed choice)`}
</option>
<option
value=${PromptTypeEnum.Dropdown}
?selected=${this.instance?.type === PromptTypeEnum.Dropdown}
>
${t`Dropdown (fixed choice)`}
</option>
<option
value=${PromptTypeEnum.Date}
?selected=${this.instance?.type === PromptTypeEnum.Date}
@ -210,7 +234,11 @@ export class PromptForm extends ModelForm<Prompt, string> {
<ak-form-element-horizontal label=${t`Placeholder`} name="placeholder">
<ak-codemirror mode="python" value="${ifDefined(this.instance?.placeholder)}">
</ak-codemirror>
<p class="pf-c-form__helper-text">${t`Optionally pre-fill the input value`}</p>
<p class="pf-c-form__helper-text">
${t`Optionally pre-fill the input value.
When creating a "Radio Button Group" or "Dropdown", enable interpreting as
expression and return a list to return multiple choices.`}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Help text`} name="subText">
<ak-codemirror mode="htmlmixed" value="${ifDefined(this.instance?.subText)}">

View File

@ -6,7 +6,7 @@ import { BaseStage } from "@goauthentik/flow/stages/base";
import { t } from "@lingui/macro";
import { CSSResult, TemplateResult, html } from "lit";
import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement } from "lit/decorators.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
@ -28,7 +28,22 @@ import {
@customElement("ak-stage-prompt")
export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeResponseRequest> {
static get styles(): CSSResult[] {
return [PFBase, PFLogin, PFAlert, PFForm, PFFormControl, PFTitle, PFButton];
return [
PFBase,
PFLogin,
PFAlert,
PFForm,
PFFormControl,
PFTitle,
PFButton,
css`
textarea {
min-height: 4em;
max-height: 15em;
resize: vertical;
}
`,
];
}
renderPromptInner(prompt: StagePrompt, placeholderAsValue: boolean): string {
@ -42,6 +57,15 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
class="pf-c-form-control"
?required=${prompt.required}
value="${placeholderAsValue ? prompt.placeholder : ""}">`;
case PromptTypeEnum.TextArea:
return `<textarea
type="text"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
autocomplete="off"
class="pf-c-form-control"
?required=${prompt.required}
value="${placeholderAsValue ? prompt.placeholder : ""}">`;
case PromptTypeEnum.TextReadOnly:
return `<input
type="text"
@ -49,6 +73,13 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
class="pf-c-form-control"
readonly
value="${prompt.placeholder}">`;
case PromptTypeEnum.TextAreaReadOnly:
return `<textarea
type="text"
name="${prompt.fieldKey}"
class="pf-c-form-control"
readonly
value="${prompt.placeholder}">`;
case PromptTypeEnum.Username:
return `<input
type="text"
@ -113,6 +144,38 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
?required=${prompt.required}>`;
case PromptTypeEnum.Static:
return `<p>${prompt.placeholder}</p>`;
case PromptTypeEnum.Dropdown:
return `<select class="pf-c-form-control" name="${prompt.fieldKey}">
${prompt.choices
?.map((choice) => {
return `<option
value=${choice}
${prompt.placeholder === choice ? "selected" : ""}
>
${choice}
</option>`;
})
.join("")}
</select>`;
case PromptTypeEnum.RadioButtonGroup:
return (
prompt.choices
?.map((choice) => {
return ` <div class="pf-c-check">
<input
type="radio"
class="pf-c-check__input"
name="${prompt.fieldKey}"
checked="${prompt.placeholder === choice}"
required="${prompt.required}"
value="${choice}"
/>
<label class="pf-c-check__label">${choice}</label>
</div>
`;
})
.join("") || ""
);
case PromptTypeEnum.AkLocale:
return `<select class="pf-c-form-control" name="${prompt.fieldKey}">
<option value="" ${prompt.placeholder === "" ? "selected" : ""}>