render()

in source/idea/idea-cluster-manager/webapp/src/pages/hpc/update-hpc-application.tsx [479:809]


    render() {
        const isVariableReferencedInScript = (name: string) => {
            if (this.state.updatedApplication.job_script_type === "jinja2") {
                const matches = this.state.jobScriptTemplate.match(`{{.*(\\b${name}\\b).*}}`);
                if (matches == null || matches.length === 0) {
                    return false;
                }
                return matches[1] === name;
            } else {
                return this.state.jobScriptTemplate.search(`%${name}%`) >= 0;
            }
        };

        return (
            <IdeaAppLayout
                ideaPageId={this.props.ideaPageId}
                toolsOpen={this.props.toolsOpen}
                tools={this.props.tools}
                onToolsChange={this.props.onToolsChange}
                onPageChange={this.props.onPageChange}
                sideNavHeader={this.props.sideNavHeader}
                sideNavItems={this.props.sideNavItems}
                onSideNavChange={this.props.onSideNavChange}
                onFlashbarChange={this.props.onFlashbarChange}
                flashbarItems={this.props.flashbarItems}
                breadcrumbItems={[
                    {
                        text: "IDEA",
                        href: "#/",
                    },
                    {
                        text: "Scale-Out Computing",
                        href: "#/soca/active-jobs",
                    },
                    {
                        text: "Applications",
                        href: "#/soca/applications",
                    },
                    {
                        text: this.isCreate() ? "Create Application" : `Update Application${this.state.updatedApplication.title ? ": " + this.state.updatedApplication.title : ""}`,
                        href: "#",
                    },
                ]}
                contentType={"wizard"}
                content={
                    this.isReady() && (
                        <Wizard
                            i18nStrings={{
                                stepNumberLabel: (stepNumber) => `Step ${stepNumber}`,
                                collapsedStepsLabel: (stepNumber, stepsCount) => `Step ${stepNumber} of ${stepsCount}`,
                                skipToButtonLabel: (step, stepNumber) => `Skip to ${step.title}`,
                                cancelButton: "Cancel",
                                previousButton: "Previous",
                                nextButton: "Next",
                                submitButton: "Submit",
                                optional: "optional",
                            }}
                            onNavigate={(event) => {
                                this.onWizardNavigate(event.detail.requestedStepIndex);
                            }}
                            onSubmit={this.onSubmit}
                            onCancel={() => {
                                this.props.navigate("/soca/applications");
                            }}
                            activeStepIndex={this.state.activeStep}
                            steps={[
                                {
                                    title: "Design Job Submission Form",
                                    info: (
                                        <Link variant="info" onFollow={() => this.showHelp("job-design-form")}>
                                            Info
                                        </Link>
                                    ),
                                    content: (
                                        <IdeaFormBuilder
                                            ref={this.formBuilder}
                                            params={this.getRecommendedJobParameters()}
                                            infoSection={
                                                this.isCreate() && (
                                                    <div>
                                                        <p>
                                                            We have generated a test job submission form for you. You can customize it as needed or click <strong>Reset Form</strong> to start from scratch.
                                                        </p>
                                                    </div>
                                                )
                                            }
                                        />
                                    ),
                                },
                                {
                                    title: "Design the Job Script",
                                    content: (
                                        <Container variant="default">
                                            <SpaceBetween direction="vertical" size="xl">
                                                <IdeaForm
                                                    columns={2}
                                                    ref={this.jobScriptForm}
                                                    name="job-script-interpreter"
                                                    showHeader={false}
                                                    showActions={false}
                                                    onStateChange={(event) => {
                                                        if (event.param.name === "job_script_type") {
                                                            this.setState({
                                                                updatedApplication: {
                                                                    ...this.state.updatedApplication,
                                                                    job_script_type: event.value,
                                                                },
                                                            });
                                                        }
                                                    }}
                                                    values={{
                                                        job_script_interpreter: this.state.updatedApplication.job_script_interpreter,
                                                        job_script_type: this.state.updatedApplication.job_script_type,
                                                    }}
                                                    params={[
                                                        {
                                                            name: "job_script_interpreter",
                                                            title: "Script Interpreter",
                                                            description: "Select the interpreter you want to use",
                                                            data_type: "str",
                                                            param_type: "select",
                                                            default: "pbs",
                                                            choices: [
                                                                {
                                                                    title: "PBS Job Script",
                                                                    description: "This is a PBS job script (will use qsub)",
                                                                    value: "pbs",
                                                                },
                                                                {
                                                                    title: "Linux Shell Script",
                                                                    description: "This is a Linux shell script (will use /bin/bash)",
                                                                    value: "bash",
                                                                },
                                                            ],
                                                        },
                                                        {
                                                            name: "job_script_type",
                                                            title: "Script Template Type",
                                                            description: "Select the script template type",
                                                            data_type: "str",
                                                            param_type: "select",
                                                            default: "jinja2",
                                                            choices: [
                                                                {
                                                                    title: "Simple",
                                                                    description: "Simple replacement of %foo%",
                                                                    value: "default",
                                                                },
                                                                {
                                                                    title: "Advanced (Jinja2)",
                                                                    description: "Use Jinja2 template to write your job scripts",
                                                                    value: "jinja2",
                                                                },
                                                            ],
                                                        },
                                                    ]}
                                                />
                                                <FormField label="Available Variables" description="Below variables are available for use in your job script, based on the form designed in the previous step.">
                                                    <ul>
                                                        <li>
                                                            <AvailableVariable name="project_name" isReferenced={isVariableReferencedInScript("project_name")} isDefined={this.isVariableDefined("project_name")} required={true} description={"included automatically"} />
                                                        </li>
                                                        <li>
                                                            <AvailableVariable name="cpus" isReferenced={isVariableReferencedInScript("cpus")} required={true} isDefined={this.isVariableDefined("cpus")} description={"used for node count computation"} />
                                                        </li>
                                                        {this.isFormDesigned() &&
                                                            this.getDesignedFormVariables().map((param) => {
                                                                if (param.param_type!.startsWith("heading")) {
                                                                    return "";
                                                                }
                                                                if (param.name === "cpus") {
                                                                    return "";
                                                                }
                                                                if (param.name === "project_name") {
                                                                    return "";
                                                                }
                                                                if (!param.name) {
                                                                    return "";
                                                                }
                                                                return (
                                                                    <li key={param.name}>
                                                                        <AvailableVariable name={param.name} isReferenced={isVariableReferencedInScript(param.name)} isDefined={this.isVariableDefined(param.name)} required={Utils.isTrue(param.validate?.required)} />
                                                                    </li>
                                                                );
                                                            })}
                                                    </ul>
                                                </FormField>
                                                <FormField label="Job Script" description="Build the job script template based on your simulation requirements" stretch={true}>
                                                    <SpaceBetween size="xs" direction="vertical">
                                                        <CodeEditor
                                                            id="job-script-editor"
                                                            ace={this.state.ace}
                                                            language={this.state.language}
                                                            value={this.state.jobScriptTemplate}
                                                            preferences={this.state.preferences}
                                                            onPreferencesChange={(e) =>
                                                                this.setState({
                                                                    preferences: e.detail,
                                                                })
                                                            }
                                                            onChange={(e) => {
                                                                this.setState({
                                                                    jobScriptTemplate: e.detail.value,
                                                                });
                                                            }}
                                                            loading={false}
                                                            i18nStrings={{
                                                                loadingState: "Loading code editor",
                                                                errorState: "There was an error loading the code editor.",
                                                                errorStateRecovery: "Retry",
                                                                editorGroupAriaLabel: "Code editor",
                                                                statusBarGroupAriaLabel: "Status bar",
                                                                cursorPosition: (row, column) => `Ln ${row}, Col ${column}`,
                                                                errorsTab: "Errors",
                                                                warningsTab: "Warnings",
                                                                preferencesButtonAriaLabel: "Preferences",
                                                                paneCloseButtonAriaLabel: "Close",
                                                                preferencesModalHeader: "Preferences",
                                                                preferencesModalCancel: "Cancel",
                                                                preferencesModalConfirm: "Confirm",
                                                                preferencesModalWrapLines: "Wrap lines",
                                                                preferencesModalTheme: "Theme",
                                                                preferencesModalLightThemes: "Light themes",
                                                                preferencesModalDarkThemes: "Dark themes",
                                                            }}
                                                        />
                                                        <Button variant="normal" onClick={this.onResetJobScript}>
                                                            Reset Job Script
                                                        </Button>
                                                    </SpaceBetween>
                                                </FormField>
                                            </SpaceBetween>
                                        </Container>
                                    ),
                                },
                                {
                                    title: "Create Application Profile",
                                    content: (
                                        <ColumnLayout columns={2}>
                                            <Container variant="default">
                                                <SpaceBetween size="m" direction="vertical">
                                                    <IdeaFormField
                                                        ref={this.titleFormField}
                                                        module="submit-application-profile"
                                                        param={{
                                                            name: "title",
                                                            title: "Title",
                                                            description: "Enter a user friendly title for the application profile",
                                                            data_type: "str",
                                                            param_type: "text",
                                                            validate: {
                                                                required: true,
                                                            },
                                                            default: this.state.updatedApplication.title,
                                                        }}
                                                    />
                                                    <IdeaFormField
                                                        ref={this.projectsFormField}
                                                        module="submit-application-profile"
                                                        value={this.state.project_ids}
                                                        onFetchOptions={(event) => {
                                                            return AppContext.get()
                                                                .client()
                                                                .projects()
                                                                .listProjects({
                                                                    paginator: {
                                                                        page_size: 100,
                                                                    },
                                                                })
                                                                .then((result) => {
                                                                    let choices: any = [];
                                                                    result.listing?.forEach((project) => {
                                                                        choices.push({
                                                                            title: project.title,
                                                                            value: project.project_id,
                                                                            description: `Project Code: ${project.name}`,
                                                                        });
                                                                    });
                                                                    return {
                                                                        listing: choices,
                                                                    };
                                                                });
                                                        }}
                                                        param={{
                                                            name: "project_ids",
                                                            title: "Projects",
                                                            description: "Select applicable projects for the Queue Profile",
                                                            param_type: "select",
                                                            multiple: true,
                                                            data_type: "str",
                                                            validate: {
                                                                required: true,
                                                            },
                                                            dynamic_choices: true,
                                                        }}
                                                    />
                                                    <FormField label="Select Thumbnail" description="Select an image (.jpg or .png) to use as thumbnail">
                                                        <Box>
                                                            <input
                                                                type="file"
                                                                accept="image/png,image/jpeg"
                                                                onChange={(event) => {
                                                                    this.resizeImage(event.target.files![0])
                                                                        .then((file) => {
                                                                            let reader = new FileReader();
                                                                            reader.onload = () => {
                                                                                this.setState({
                                                                                    thumbnailData: `${reader.result}`,
                                                                                });
                                                                            };
                                                                            reader.readAsDataURL(file);
                                                                        })
                                                                        .catch((error) => console.error(error));
                                                                }}
                                                            />
                                                        </Box>
                                                        {this.state.thumbnailData && (
                                                            <Box padding="m">
                                                                <img width={80} src={this.state.thumbnailData} alt="thumbnail" />
                                                            </Box>
                                                        )}
                                                    </FormField>
                                                </SpaceBetween>
                                            </Container>
                                        </ColumnLayout>
                                    ),
                                },
                            ]}
                        />
                    )
                }