stages/prompt: Add initial_data prompt field and ability to select a default choice for choice fields (#5095)

* Added initial_value to model

* Added initial_value to admin panel

* Added initial_value support to flows; updated tests

* Updated default blueprints

* update docs

* Fix test

* Fix another test

* Fix yet another test

* Add placeholder migration

* Remove unused import
This commit is contained in:
sdimovv
2023-04-19 11:27:51 +01:00
committed by GitHub
parent 04cc7817ee
commit ee6edec1d8
12 changed files with 418 additions and 138 deletions

View File

@ -372,8 +372,8 @@ export class PromptForm extends ModelForm<Prompt, string> {
>
</label>
<p class="pf-c-form__helper-text">
${t`When checked, the placeholder will be evaluated in the same way environment as a property mapping.
If the evaluation failed, the placeholder itself is returned.`}
${t`When checked, the placeholder will be evaluated in the same way a property mapping is.
If the evaluation fails, the placeholder itself is returned.`}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Placeholder`} name="placeholder">
@ -386,11 +386,41 @@ export class PromptForm extends ModelForm<Prompt, string> {
>
</ak-codemirror>
<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
${t`Optionally provide a short hint that describes the expected input value.
When creating a fixed choice field, enable interpreting as
expression and return a list to return multiple choices.`}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="initialValueExpression">
<label class="pf-c-switch">
<input
class="pf-c-switch__input"
type="checkbox"
?checked=${first(this.instance?.initialValueExpression, false)}
/>
<span class="pf-c-switch__toggle">
<span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label"
>${t`Interpret initial value as expression`}</span
>
</label>
<p class="pf-c-form__helper-text">
${t`When checked, the initial value will be evaluated in the same way a property mapping is.
If the evaluation fails, the initial value itself is returned.`}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Initial value`} name="initialValue">
<ak-codemirror mode="python" value="${ifDefined(this.instance?.initialValue)}">
</ak-codemirror>
<p class="pf-c-form__helper-text">
${t`Optionally pre-fill the input with an initial value.
When creating a fixed choice field, enable interpreting as
expression and return a list to return multiple default choices.`}}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Help text`} name="subText">
<ak-codemirror
mode="htmlmixed"

View File

@ -48,7 +48,7 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
];
}
renderPromptInner(prompt: StagePrompt, placeholderAsValue: boolean): string {
renderPromptInner(prompt: StagePrompt): string {
switch (prompt.type) {
case PromptTypeEnum.Text:
return `<input
@ -58,7 +58,7 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
autocomplete="off"
class="pf-c-form-control"
?required=${prompt.required}
value="${placeholderAsValue ? prompt.placeholder : ""}">`;
value="${prompt.initialValue}">`;
case PromptTypeEnum.TextArea:
return `<textarea
type="text"
@ -67,21 +67,23 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
autocomplete="off"
class="pf-c-form-control"
?required=${prompt.required}
value="${placeholderAsValue ? prompt.placeholder : ""}">`;
value="${prompt.initialValue}"">`;
case PromptTypeEnum.TextReadOnly:
return `<input
type="text"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
readonly
value="${prompt.placeholder}">`;
value="${prompt.initialValue}">`;
case PromptTypeEnum.TextAreaReadOnly:
return `<textarea
type="text"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
readonly
value="${prompt.placeholder}">`;
value="${prompt.initialValue}">`;
case PromptTypeEnum.Username:
return `<input
type="text"
@ -90,7 +92,7 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
autocomplete="username"
class="pf-c-form-control"
?required=${prompt.required}
value="${placeholderAsValue ? prompt.placeholder : ""}">`;
value="${prompt.initialValue}">`;
case PromptTypeEnum.Email:
return `<input
type="email"
@ -98,7 +100,7 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}
value="${placeholderAsValue ? prompt.placeholder : ""}">`;
value="${prompt.initialValue}">`;
case PromptTypeEnum.Password:
return `<input
type="password"
@ -113,46 +115,50 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}>`;
?required=${prompt.required}
value="${prompt.initialValue}">`;
case PromptTypeEnum.Date:
return `<input
type="date"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}>`;
?required=${prompt.required}
value="${prompt.initialValue}">`;
case PromptTypeEnum.DateTime:
return `<input
type="datetime"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}>`;
?required=${prompt.required}
value="${prompt.initialValue}">`;
case PromptTypeEnum.File:
return `<input
type="file"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}>`;
?required=${prompt.required}
value="${prompt.initialValue}">`;
case PromptTypeEnum.Separator:
return `<ak-divider>${prompt.placeholder}</ak-divider>`;
case PromptTypeEnum.Hidden:
return `<input
type="hidden"
name="${prompt.fieldKey}"
value="${prompt.placeholder}"
value="${prompt.initialValue}"
class="pf-c-form-control"
?required=${prompt.required}>`;
case PromptTypeEnum.Static:
return `<p>${prompt.placeholder}</p>`;
return `<p>${prompt.initialValue}</p>`;
case PromptTypeEnum.Dropdown:
return `<select class="pf-c-form-control" name="${prompt.fieldKey}">
${prompt.choices
?.map((choice) => {
return `<option
value="${choice}"
?selected=${prompt.placeholder === choice}
?selected=${prompt.initialValue === choice}
>
${choice}
</option>`;
@ -168,7 +174,7 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
type="radio"
class="pf-c-check__input"
name="${prompt.fieldKey}"
checked="${prompt.placeholder === choice}"
checked="${prompt.initialValue === choice}"
required="${prompt.required}"
value="${choice}"
/>
@ -180,7 +186,7 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
);
case PromptTypeEnum.AkLocale:
return `<select class="pf-c-form-control" name="${prompt.fieldKey}">
<option value="" ${prompt.placeholder === "" ? "selected" : ""}>
<option value="" ${prompt.initialValue === "" ? "selected" : ""}>
${t`Auto-detect (based on your browser)`}
</option>
${LOCALES.filter((locale) => {
@ -195,7 +201,7 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
.map((locale) => {
return `<option
value=${locale.code}
${prompt.placeholder === locale.code ? "selected" : ""}
${prompt.initialValue === locale.code ? "selected" : ""}
>
${locale.code.toUpperCase()} - ${locale.label}
</option>`;
@ -234,7 +240,7 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
type="checkbox"
class="pf-c-check__input"
name="${prompt.fieldKey}"
?checked=${prompt.placeholder !== ""}
?checked=${prompt.initialValue !== ""}
?required=${prompt.required}
/>
<label class="pf-c-check__label">${prompt.label}</label>
@ -251,11 +257,10 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
class="pf-c-form__group"
.errors=${(this.challenge?.responseErrors || {})[prompt.fieldKey]}
>
${unsafeHTML(this.renderPromptInner(prompt, false))}
${this.renderPromptHelpText(prompt)}
${unsafeHTML(this.renderPromptInner(prompt))} ${this.renderPromptHelpText(prompt)}
</ak-form-element>`;
}
return html` ${unsafeHTML(this.renderPromptInner(prompt, false))}
return html` ${unsafeHTML(this.renderPromptInner(prompt))}
${this.renderPromptHelpText(prompt)}`;
}

View File

@ -17,7 +17,7 @@ export class UserSettingsPromptStage extends PromptStage {
return super.styles.concat(PFCheck);
}
renderPromptInner(prompt: StagePrompt, placeholderAsValue: boolean): string {
renderPromptInner(prompt: StagePrompt): string {
switch (prompt.type) {
// Checkbox requires slightly different rendering here due to the use of horizontal form elements
case PromptTypeEnum.Checkbox:
@ -25,12 +25,12 @@ export class UserSettingsPromptStage extends PromptStage {
type="checkbox"
class="pf-c-check__input"
name="${prompt.fieldKey}"
?checked=${prompt.placeholder !== ""}
?checked=${prompt.initialValue !== ""}
?required=${prompt.required}
style="vertical-align: bottom"
/>`;
default:
return super.renderPromptInner(prompt, placeholderAsValue);
return super.renderPromptInner(prompt);
}
}
@ -47,13 +47,13 @@ export class UserSettingsPromptStage extends PromptStage {
return error.string;
})}
>
${unsafeHTML(this.renderPromptInner(prompt, true))}
${unsafeHTML(this.renderPromptInner(prompt))}
${this.renderPromptHelpText(prompt)}
</ak-form-element-horizontal>
`;
}
return html`
${unsafeHTML(this.renderPromptInner(prompt, true))} ${this.renderPromptHelpText(prompt)}
${unsafeHTML(this.renderPromptInner(prompt))} ${this.renderPromptHelpText(prompt)}
`;
}