Skip to content

Commit

Permalink
Frontend changes for OT registration approvals
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielRyanSmith committed Oct 24, 2023
1 parent b28fe1b commit 5e682d1
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 34 deletions.
13 changes: 13 additions & 0 deletions client-src/css/forms-css.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@ export const FORM_STYLES = [
margin-top: 2em;
}
.fade-in {
animation:fadeIn 0.5s linear;
}
@keyframes fadeIn {
0% {
opacity:0
}
100% {
opacity:1;
}
}
#metadata, .stage_form, .flat_form, .final_buttons {
max-width: 67em;
padding: 1em;
Expand Down
7 changes: 5 additions & 2 deletions client-src/elements/chromedash-form-field.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class ChromedashFormField extends LitElement {
index: {type: Number}, // Represents which field this is on the form.
disabled: {type: Boolean},
checkboxLabel: {type: String}, // Optional override of default label.
shouldFadeIn: {type: Boolean},
loading: {type: Boolean},
fieldProps: {type: Object},
forEnterprise: {type: Boolean},
Expand All @@ -28,6 +29,7 @@ export class ChromedashFormField extends LitElement {
this.index = -1;
this.checkboxLabel = '';
this.disabled = false;
this.shouldFadeIn = false;
this.loading = false;
this.forEnterprise = false;
this.stageType = undefined;
Expand Down Expand Up @@ -234,15 +236,16 @@ export class ChromedashFormField extends LitElement {
this.forEnterprise && (this.fieldProps.enterprise_extra_help !== undefined) ?
this.fieldProps.enterprise_extra_help :
this.fieldProps.extra_help;
const fadeInClass = (this.shouldFadeIn) ? 'fade-in' : '';
return html`
${this.fieldProps.label ? html`
<tr>
<tr class="${fadeInClass}">
<th colspan="2">
<b>${this.fieldProps.label}:</b>
</th>
</tr>
`:nothing}
<tr>
<tr class=${fadeInClass}>
<td>${this.renderWidgets()}</td>
<td>
${helpText ? html`<span class="helptext"> ${helpText} </span>`: nothing}
Expand Down
119 changes: 87 additions & 32 deletions client-src/elements/chromedash-ot-creation-page.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {LitElement, css, html} from 'lit';
import {LitElement, css, html, nothing} from 'lit';
import {ref} from 'lit/directives/ref.js';
import {
formatFeatureChanges,
Expand All @@ -10,6 +10,7 @@ import './chromedash-form-field.js';
import {ORIGIN_TRIAL_CREATION_FIELDS} from './form-definition.js';
import {SHARED_STYLES} from '../css/shared-css.js';
import {FORM_STYLES} from '../css/forms-css.js';
import {ALL_FIELDS} from './form-field-specs.js';


export class ChromedashOTCreationPage extends LitElement {
Expand All @@ -31,6 +32,7 @@ export class ChromedashOTCreationPage extends LitElement {
appTitle: {type: String},
nextPage: {type: String},
fieldValues: {type: Array},
showApprovalsFields: {type: Boolean},
};
}

Expand All @@ -43,6 +45,7 @@ export class ChromedashOTCreationPage extends LitElement {
this.appTitle = '';
this.nextPage = '';
this.fieldValues = [];
this.showApprovalsFields = false;
}

connectedCallback() {
Expand All @@ -61,6 +64,11 @@ export class ChromedashOTCreationPage extends LitElement {
// The field has been updated, so it is considered touched.
this.fieldValues[index].touched = true;
this.fieldValues[index].value = value;

if (this.fieldValues[index].name === 'ot_require_approvals') {
this.showApprovalsFields = !this.showApprovalsFields;
this.requestUpdate();
}
};

fetchData() {
Expand All @@ -75,12 +83,78 @@ export class ChromedashOTCreationPage extends LitElement {
if (this.feature.name) {
document.title = `${this.feature.name} - ${this.appTitle}`;
}
this.setFieldValues();
this.loading = false;
}).catch(() => {
showToastMessage('Some errors occurred. Please refresh the page or try again later.');
});
}

addOptionalApprovalsFields() {
// Approval requirement fields are always hidden unless the feature owner
// opts in to using them.
const insertIndex = this.fieldValues.findIndex(
fieldInfo => fieldInfo.name === 'ot_require_approvals') + 1;
this.fieldValues.splice(insertIndex, 0,
{
name: 'ot_approval_buganizer_component',
touched: true,
value: '',
stageId: this.stage.id,
isApprovalsField: true,
},
{
name: 'ot_approval_group_email',
touched: true,
value: '',
stageId: this.stage.id,
isApprovalsField: true,
},
{
name: 'ot_approval_criteria_url',
touched: true,
value: '',
stageId: this.stage.id,
isApprovalsField: true,
});
}

addHiddenFields() {
// Add a field for updating that an OT creation request has been submitted.
this.fieldValues.push({
name: 'ot_action_requested',
touched: true,
value: true,
stageId: this.stage.id,
alwaysHidden: true,
});
}

setFieldValues() {
// OT creation page only has one section.
const section = ORIGIN_TRIAL_CREATION_FIELDS.sections[0];

this.fieldValues = section.fields.map(field => {
const featureJSONKey = ALL_FIELDS[field].name || field;
let value = getStageValue(this.stage, featureJSONKey);
let touched = false;

// The requester's email should be a contact by default.
if (featureJSONKey === 'ot_owner_email' && !value) {
value = [this.userEmail];
touched = true;
}

// Add the field to this component's stage before creating the field component.
return {
name: featureJSONKey,
touched,
value,
stageId: this.stage.id,
};
});
this.addOptionalApprovalsFields();
this.addHiddenFields();
}

disconnectedCallback() {
super.disconnectedCallback();
document.title = this.appTitle;
Expand Down Expand Up @@ -111,8 +185,6 @@ export class ChromedashOTCreationPage extends LitElement {
setTimeout(() => {
window.location.href = this.nextPage || `/feature/${this.featureId}`;
}, 1000);
}).catch(() => {
showToastMessage('Some errors occurred. Please refresh the page or try again later.');
});
}

Expand Down Expand Up @@ -156,41 +228,24 @@ export class ChromedashOTCreationPage extends LitElement {
`;
}

renderFields(section) {
const fields = section.fields.map(field => {
let value = getStageValue(this.stage, field);
let touched = false;
// The requester's email should be a contact by default.
if (field === 'ot_owner_email' && !value) {
value = [this.userEmail];
touched = true;
renderFields() {
const fields = this.fieldValues.map((fieldInfo, i) => {
if (fieldInfo.alwaysHidden || (fieldInfo.isApprovalsField && !this.showApprovalsFields)) {
return nothing;
}
// Add the field to this component's stage before creating the field component.
const index = this.fieldValues.length;
this.fieldValues.push({
name: field,
touched,
value,
stageId: this.stage.id,
});
// Fade in transition for the approvals fields if they're being displayed.
const shouldFadeIn = fieldInfo.isApprovalsField;

return html`
<chromedash-form-field
name=${field}
value=${value}
index=${index}
name=${fieldInfo.name}
.shouldFadeIn=${shouldFadeIn}
value=${fieldInfo.value}
index=${i}
@form-field-update="${this.handleFormFieldUpdate}">
</chromedash-form-field>
`;
});

// Add a field for updating that an OT creation request has been submitted.
this.fieldValues.push({
name: 'ot_action_requested',
touched: true,
value: true,
stageId: this.stage.id,
});
return fields;
}

Expand Down
1 change: 1 addition & 0 deletions client-src/elements/form-definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ export const ORIGIN_TRIAL_CREATION_FIELDS = {
'ot_is_deprecation_trial',
'ot_has_third_party_support',
'ot_is_critical_trial',
'ot_require_approvals',
'ot_request_note',
],
},
Expand Down
4 changes: 4 additions & 0 deletions client-src/elements/form-field-enums.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ export const STAGE_SPECIFIC_FIELDS = new Set([
'ot_creation__milestone_desktop_first',
'ot_creation__milestone_desktop_last',
'ot_extension__milestone_desktop_last',
'ot_require_approvals',
'ot_approval_buganizer_component',
'ot_approval_group_email',
'ot_approval_criteria_url',
'finch_url',
'experiment_goals',
'experiment_risks',
Expand Down
40 changes: 40 additions & 0 deletions client-src/elements/form-field-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,46 @@ export const ALL_FIELDS = {
>web_feature.mojom</a>.`,
},

'ot_require_approvals': {
type: 'checkbox',
initial: false,
label: 'Trial participation requires approval',
help_text: html`
Will this trial require registrants to receive approval before
participating? See information about this setting at
<a target="_blank" href="">Some link</a>`,
},

'ot_approval_buganizer_component': {
type: 'input',
attrs: {type: 'number'},
required: true,
label: 'Approvals Buganizer component ID',
help_text: html`
Buganizer component ID used for approvals requests.`,
},

'ot_approval_group_email': {
type: 'input',
required: true,
attrs: {...TEXT_FIELD_ATTRS, pattern: GOOGLE_EMAIL_ADDRESS_REGEX},
label: 'Registration request notifications group',
help_text: html`
<p>
Google group email to be used for new registration request notifications.
Please supply a '@google.com' domain email address only.
</p>`,
},

'ot_approval_criteria_url': {
type: 'input',
attrs: URL_FIELD_ATTRS,
required: true,
label: 'Approval criteria link',
help_text: html`
Link to documentation describing the requirements to be approved for trial participation.`,
},

'ot_creation__intent_to_experiment_url': {
name: 'intent_to_experiment_url',
type: 'input',
Expand Down

0 comments on commit 5e682d1

Please sign in to comment.