Skip to content

Commit

Permalink
Pass form values into the SupportForm component.
Browse files Browse the repository at this point in the history
  • Loading branch information
sbruens committed Sep 26, 2023
1 parent 004e783 commit f70af2c
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 82 deletions.
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ docs/
resources/
third_party/
tools/
node_modules/
node_modules/
16 changes: 11 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
"outline-i18n": "Jigsaw-Code/outline-i18n#v0.0.7",
"postcss": "^7.0.39",
"postcss-rtl": "^1.7.3",
"prettier": "^1.19.1",
"prettier": "^2.8.0",
"pretty-quick": "^2.0.1",
"puppeteer": "^13.1.2",
"replace-in-file": "^6.3.5",
Expand Down
60 changes: 27 additions & 33 deletions src/www/views/contact_view/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export class ContactView extends LitElement {
];

@state() private showIssueSelector = false;
private formValues: FormValues = {};
private readonly formRef: Ref<SupportForm> = createRef();
@state() private isFormSubmitting = false;

Expand Down Expand Up @@ -190,28 +191,27 @@ export class ContactView extends LitElement {
private reset() {
this.showIssueSelector = false;
this.step = Step.ISSUE_WIZARD;
this.formRef.value.reset();
this.formValues = {};
}

private submitForm(e: CustomEvent) {
private submitForm() {
this.isFormSubmitting = true;

const formData: FormValues = e.detail;
if (!this.formRef.value.valid) {
throw Error('Cannot submit invalid form.');
}

// TODO: Actually send the form data using the error reporter.
console.log('Submitting form data...', formData);
console.log('Submitting form data...', this.formValues);

this.isFormSubmitting = false;
this.exitTemplate = html`
Thanks for helping us improve! We love hearing from you.
`;
this.exitTemplate = html` Thanks for helping us improve! We love hearing from you. `;
this.step = Step.EXIT;
}

private get renderIntroTemplate(): TemplateResult {
return html`
<p>
Tell us how we can help. Please do not enter personal information that is not requested below.
</p>
<p>Tell us how we can help. Please do not enter personal information that is not requested below.</p>
`;
}

Expand All @@ -226,6 +226,7 @@ export class ContactView extends LitElement {
${ref(this.formRef)}
.variant=${this.variant}
.disabled=${this.isFormSubmitting}
.values=${this.formValues}
@cancel=${this.reset}
@submit=${this.submitForm}
></support-form>
Expand All @@ -235,17 +236,11 @@ export class ContactView extends LitElement {
render() {
switch (this.step) {
case Step.FORM: {
return html`
${this.renderIntroTemplate} ${this.renderForm}
`;
return html` ${this.renderIntroTemplate} ${this.renderForm} `;
}

case Step.EXIT: {
return html`
<outline-card .type=${CardType.Elevated}>
${this.exitTemplate}
</outline-card>
`;
return html` <outline-card .type=${CardType.Elevated}> ${this.exitTemplate} </outline-card> `;
}

case Step.ISSUE_WIZARD:
Expand All @@ -256,21 +251,20 @@ export class ContactView extends LitElement {
<ol>
${this.openTicketSelectionOptions.map(
element =>
html`
<li>
<mwc-formfield label=${element.label}>
<mwc-radio
name="open-ticket"
.value="${element.value}"
required
@change=${this.selectHasOpenTicket}
${ref(element.ref)}
>
</mwc-radio>
</mwc-formfield>
</li>
`
element => html`
<li>
<mwc-formfield label=${element.label}>
<mwc-radio
name="open-ticket"
.value="${element.value}"
required
@change=${this.selectHasOpenTicket}
${ref(element.ref)}
>
</mwc-radio>
</mwc-formfield>
</li>
`
)}
</ol>
Expand Down
76 changes: 38 additions & 38 deletions src/www/views/contact_view/support_form/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import {html, css, LitElement, TemplateResult, nothing} from 'lit';
import {html, css, LitElement, TemplateResult, nothing, PropertyValues} from 'lit';
import {createRef, Ref, ref} from 'lit/directives/ref.js';
import {live} from 'lit/directives/live.js';
import {customElement, property, state} from 'lit/decorators.js';
Expand Down Expand Up @@ -78,21 +78,23 @@ export class SupportForm extends LitElement {

@property({type: Boolean}) disabled = false;
@property({type: String}) variant: AppType = AppType.CLIENT;
@property({type: Object}) values: FormValues = {};

private readonly formRef: Ref<HTMLFormElement> = createRef();
@state() private formData: FormValues = {};
@state() valid = false;

@state() private isFormValid = false;
override updated(changedProperties: PropertyValues<this>) {
super.updated(changedProperties);

if (changedProperties.has('values')) {
queueMicrotask(() => this.checkFormValidity());
}
}

/** Checks the entire form's validity state. */
private checkFormValidity() {
const fieldNodes = this.formRef.value.querySelectorAll<FormControl>('*[name]');
this.isFormValid = Array.from(fieldNodes).every(field => field.validity.valid);
}

/** Resets the form. */
reset() {
this.formData = {};
this.valid = Array.from(fieldNodes).every(field => field.validity.valid);
}

/** Cancels the form. */
Expand All @@ -108,14 +110,17 @@ export class SupportForm extends LitElement {
e.preventDefault();
e.stopPropagation();

if (!this.isFormValid) {
throw Error('Cannot submit invalid form.');
}

const event = new CustomEvent<FormValues>('submit', {detail: this.formData});
const event = new CustomEvent<boolean>('submit', {detail: true});
this.dispatchEvent(event);
}

private handleTextInput(e: Event) {
const key: keyof FormValues = (e.target as TextField).name as keyof FormValues;
const value = (e.target as TextField).value;
this.values[key] = value;
this.checkFormValidity();
}

private get renderCloudProviderInputField(): TemplateResult | typeof nothing {
if (this.variant !== AppType.MANAGER) return nothing;

Expand All @@ -138,23 +143,18 @@ export class SupportForm extends LitElement {
label="Cloud provider"
helper="Which cloud provider does this relate to?"
helperPersistent
.value=${live(this.formData.cloudProvider ?? '')}
.value=${live(this.values.cloudProvider ?? '')}
.disabled=${this.disabled}
required
outlined
@selected=${(e: CustomEvent<SelectedDetail<number>>) => {
if (e.detail.index !== -1) {
this.formData.cloudProvider = providers[e.detail.index][0];
this.values.cloudProvider = providers[e.detail.index][0];
}
}}
.disabled=${this.disabled}
required
outlined
@blur=${this.checkFormValidity}
>
${providers.map(
([value, label]) =>
html`
<mwc-list-item value="${value}">${label}</mwc-list-item>
`
)}
${providers.map(([value, label]) => html` <mwc-list-item value="${value}">${label}</mwc-list-item> `)}
</mwc-select>
`;
}
Expand All @@ -165,15 +165,15 @@ export class SupportForm extends LitElement {
return html`
<mwc-textfield
name="Where_did_you_get_your_access_key"
label="Source"
label="source"
helper="Where did you get your access key?"
helperPersistent
.value=${live(this.formData.source ?? '')}
@input=${(e: Event) => (this.formData.source = (e.target as TextField).value)}
.value=${live(this.values.source ?? '')}
.maxLength=${SupportForm.DEFAULT_MAX_LENGTH_INPUT}
.disabled=${this.disabled}
required
outlined
@input=${this.handleTextInput}
@blur=${this.checkFormValidity}
></mwc-textfield>
`;
Expand All @@ -184,47 +184,47 @@ export class SupportForm extends LitElement {
<form ${ref(this.formRef)} @submit=${this.submit}>
<outline-card .type=${CardType.Elevated}>
<mwc-textfield
name="Email"
name="email"
type="email"
label="Email address"
helper="Please provide an email address where we can reach you."
helperPersistent
.value=${live(this.formData.email ?? '')}
@input=${(e: Event) => (this.formData.email = (e.target as TextField).value)}
.value=${live(this.values.email ?? '')}
.maxLength=${SupportForm.DEFAULT_MAX_LENGTH_INPUT}
autoValidate
validationMessage="Please provide a correct email address."
.disabled=${this.disabled}
required
outlined
@input=${this.handleTextInput}
@blur=${this.checkFormValidity}
></mwc-textfield>
${this.renderCloudProviderInputField} ${this.renderAccessKeySourceInputField}
<mwc-textfield
name="Subject"
name="subject"
label="Subject"
.value=${live(this.formData.subject ?? '')}
@input=${(e: Event) => (this.formData.subject = (e.target as TextField).value)}
.value=${live(this.values.subject ?? '')}
.maxLength=${SupportForm.DEFAULT_MAX_LENGTH_INPUT}
.disabled=${this.disabled}
required
outlined
@input=${this.handleTextInput}
@blur=${this.checkFormValidity}
></mwc-textfield>
<mwc-textarea
name="Description"
name="description"
label="Description"
helper="Please provide a detailed description of your issue."
helperPersistent
.value=${live(this.formData.description ?? '')}
@input=${(e: Event) => (this.formData.description = (e.target as TextField).value)}
.value=${live(this.values.description ?? '')}
rows="5"
.maxLength=${SupportForm.MAX_LENGTH_DESCRIPTION}
.disabled=${this.disabled}
required
outlined
@input=${this.handleTextInput}
@blur=${this.checkFormValidity}
>
</mwc-textarea>
Expand All @@ -239,7 +239,7 @@ export class SupportForm extends LitElement {
<mwc-button
type="submit"
label="Submit"
.disabled=${!this.isFormValid || this.disabled}
.disabled=${!this.valid || this.disabled}
@click=${this.submit}
></mwc-button>
</span>
Expand Down
Loading

0 comments on commit f70af2c

Please sign in to comment.