Merge branch 'main' into avm99963-monorail
Merged commit 4137ed7879acadbf891e8c471108acb874dae886.
GitOrigin-RevId: b6100ffc5b1da355a35f37b13fcaaf746ee8b307
diff --git a/static_src/react/IssueWizard.tsx b/static_src/react/IssueWizard.tsx
index de5e8fb..ecb6664 100644
--- a/static_src/react/IssueWizard.tsx
+++ b/static_src/react/IssueWizard.tsx
@@ -6,62 +6,162 @@
import * as React from 'react'
import ReactDOM from 'react-dom';
import styles from './IssueWizard.css';
-import DotMobileStepper from './issue-wizard/DotMobileStepper.tsx';
import LandingStep from './issue-wizard/LandingStep.tsx';
import DetailsStep from './issue-wizard/DetailsStep.tsx'
+import {IssueWizardPersona} from './issue-wizard/IssueWizardTypes.tsx';
+import CustomQuestionsStep from './issue-wizard/CustomQuestionsStep.tsx';
+import {getOs, getChromeVersion, buildIssueDescription} from './issue-wizard/IssueWizardUtils.tsx'
+import Header from './issue-wizard/Header.tsx'
+
+import {GetQuestionsByCategory, buildIssueLabels, getCompValByCategory, getLabelsByCategory} from './issue-wizard/IssueWizardUtils.tsx';
+import {ISSUE_WIZARD_QUESTIONS, ISSUE_REPRODUCE_PLACEHOLDER, OS_CHANNEL_LIST} from './issue-wizard/IssueWizardConfig.ts';
+import {prpcClient} from 'prpc-client-instance.js';
+import {expandDescriptions} from './issue-wizard/IssueWizardDescriptionsUtils.tsx';
+import SubmitSuccessStep from './issue-wizard/SubmitSuccessStep.tsx';
+import {IssueWizardFeedback} from './issue-wizard/IssueWizardFeedback.tsx';
/**
* Base component for the issue filing wizard, wrapper for other components.
* @return Issue wizard JSX.
*/
-export function IssueWizard(): ReactElement {
- const [checkExisting, setCheckExisting] = React.useState(false);
- const [userType, setUserType] = React.useState('End User');
+ type Props = {
+ loginUrl: string,
+ userDisplayName: string,
+}
+export function IssueWizard(props: Props): ReactElement {
+ const {loginUrl, userDisplayName} = props;
+ React.useEffect(() => {
+ if(!userDisplayName) {
+ window.location.href = loginUrl;
+ }
+ },[loginUrl, userDisplayName]);
+
+ const [userPersona, setUserPersona] = React.useState(IssueWizardPersona.EndUser);
const [activeStep, setActiveStep] = React.useState(0);
const [category, setCategory] = React.useState('');
+ const [newIssueID, setnewIssueID] = React.useState('');
+ const [isRegression, setIsRegression] = React.useState(false);
const [textValues, setTextValues] = React.useState(
{
oneLineSummary: '',
- stepsToReproduce: '',
+ stepsToReproduce: ISSUE_REPRODUCE_PLACEHOLDER,
describeProblem: '',
- additionalComments: ''
+ chromeVersion: getChromeVersion(),
+ osName: getOs(),
+ channel: OS_CHANNEL_LIST[0].name,
});
+ const [enableFeedback, setEnableFeedback] = React.useState(false);
+ const questionByCategory = GetQuestionsByCategory(ISSUE_WIZARD_QUESTIONS);
- let nextEnabled;
+ const moveStep = (step: number) => {
+ window.scrollTo(0, 0);
+ setActiveStep(step);
+ }
+
+ const reset = () => {
+ setTextValues({
+ oneLineSummary: '',
+ stepsToReproduce: ISSUE_REPRODUCE_PLACEHOLDER,
+ describeProblem: '',
+ chromeVersion: getChromeVersion(),
+ osName: getOs(),
+ channel: OS_CHANNEL_LIST[0].name,
+ });
+ setIsRegression(false);
+ }
+
+ const updateCategory = (category: string) => {
+ setCategory(category);
+ reset();
+ }
+
let page;
- if (activeStep === 0){
+ if (activeStep === 0) {
page = <LandingStep
- checkExisting={checkExisting}
- setCheckExisting={setCheckExisting}
- userType={userType}
- setUserType={setUserType}
+ userPersona={userPersona}
+ setUserPersona={setUserPersona}
category={category}
- setCategory={setCategory}
+ setCategory={updateCategory}
+ setActiveStep={moveStep}
/>;
- nextEnabled = checkExisting && userType && (category != '');
- } else if (activeStep === 1){
- page = <DetailsStep textValues={textValues} setTextValues={setTextValues} category={category}/>;
- nextEnabled = (textValues.oneLineSummary.trim() !== '') &&
- (textValues.stepsToReproduce.trim() !== '') &&
- (textValues.describeProblem.trim() !== '');
+ } else if (activeStep === 1) {
+ page = <DetailsStep
+ textValues={textValues}
+ setTextValues={setTextValues}
+ category={category}
+ setActiveStep={moveStep}
+ setIsRegression={setIsRegression}
+ />;
+ } else if (activeStep === 2) {
+ const compValByCategory = getCompValByCategory(ISSUE_WIZARD_QUESTIONS);
+ const labelsByCategory = getLabelsByCategory(ISSUE_WIZARD_QUESTIONS);
+
+ const onSubmitIssue = (comments: string, customQuestionsAnswers: Array<string>, attachments: Array<any>,onSuccess: Function, onFailure: Function) => {
+ const summary = textValues.oneLineSummary;
+ const component = compValByCategory.get(category);
+ const description = buildIssueDescription(
+ textValues.stepsToReproduce,
+ textValues.describeProblem,
+ comments, textValues.osName,
+ textValues.chromeVersion,
+ textValues.channel);
+ const labels = buildIssueLabels(category, textValues.osName, textValues.chromeVersion, labelsByCategory.get(category));
+
+ const {expandDescription, expandLabels, compVal} =
+ expandDescriptions(category, customQuestionsAnswers, isRegression, description, labels, component);
+
+ const componentsArray = [];
+ if (compVal.length > 0) {
+ componentsArray.push({
+ component: 'projects/chromium/componentDefs/' + compVal
+ })
+ }
+
+ const response = prpcClient.call('monorail.v3.Issues', 'MakeIssue', {
+ parent: 'projects/chromium',
+ issue: {
+ summary,
+ status: {
+ status: 'Untriaged',
+ },
+ components: componentsArray,
+ labels: expandLabels,
+ },
+ description: expandDescription,
+ uploads: attachments,
+ });
+ response.then(onSuccess, onFailure);
+ }
+ page =
+ <CustomQuestionsStep
+ setActiveStep={moveStep}
+ questions={questionByCategory.get(category)}
+ onSubmit={onSubmitIssue}
+ setnewIssueID={setnewIssueID}
+ />;
+ } else if (activeStep === 3) {
+ page = <SubmitSuccessStep issueID={newIssueID}/>;
}
return (
<>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins"></link>
<div className={styles.container}>
+ <Header />
{page}
- <DotMobileStepper nextEnabled={nextEnabled} activeStep={activeStep} setActiveStep={setActiveStep}/>
+ <div className={styles.feedback} onClick={()=>{setEnableFeedback(true);}}>Report a problem with this wizard</div>
</div>
+ <IssueWizardFeedback enable={enableFeedback} setEnable={setEnableFeedback}/>
</>
);
}
/**
* Renders the issue filing wizard page.
- * @param mount HTMLElement that the React component should be
- * added to.
+ * @param mount HTMLElement that the React component should be added to.
+ * @param loginUrl redirect to login page
+ * @param userDisplayName login user
*/
-export function renderWizard(mount: HTMLElement): void {
- ReactDOM.render(<IssueWizard />, mount);
+export function renderWizard(mount: HTMLElement, loginUrl: string, userDisplayName: string): void {
+ ReactDOM.render(<IssueWizard loginUrl={loginUrl} userDisplayName={userDisplayName}/>, mount);
}