diff --git a/src/components/Contribute/AuthorInformation.tsx b/src/components/Contribute/AuthorInformation.tsx index eb8f5d8b..bee52301 100644 --- a/src/components/Contribute/AuthorInformation.tsx +++ b/src/components/Contribute/AuthorInformation.tsx @@ -68,7 +68,8 @@ const AuthorInformation: React.FC = ({ formType, reset, formData, setDisa return ( <>

- Author Information * + Author Information + *

Provide your information required for a GitHub DCO sign-off.

diff --git a/src/components/Contribute/Skill/AttributionInformation/AttributionInformation.tsx b/src/components/Contribute/Skill/AttributionInformation/AttributionInformation.tsx index 81ff3036..6e42db05 100644 --- a/src/components/Contribute/Skill/AttributionInformation/AttributionInformation.tsx +++ b/src/components/Contribute/Skill/AttributionInformation/AttributionInformation.tsx @@ -1,16 +1,7 @@ import React, { useEffect } from 'react'; import { checkSkillFormCompletion } from '../validation'; import { SkillFormData } from '@/types'; -import { - ValidatedOptions, - FormFieldGroupExpandable, - FormFieldGroupHeader, - FormGroup, - TextInput, - FormHelperText, - HelperText, - HelperTextItem -} from '@patternfly/react-core'; +import { ValidatedOptions, FormGroup, TextInput, FormHelperText, HelperText, HelperTextItem } from '@patternfly/react-core'; import { ExclamationCircleIcon } from '@patternfly/react-icons'; interface Props { @@ -93,22 +84,12 @@ const AttributionInformation: React.FC = ({ }; return ( - - Attribution Information * -

- ), - id: 'attribution-info-id' - }} - titleDescription="Provide attribution information." - /> - } - > + <> +

+ Attribution Information * +

+

Provide attribution information for the skill.

+ = ({ )} -
+ ); }; diff --git a/src/components/Contribute/Skill/FilePathInformation/FilePathInformation.tsx b/src/components/Contribute/Skill/FilePathInformation/FilePathInformation.tsx index 19ef73da..187f7af5 100644 --- a/src/components/Contribute/Skill/FilePathInformation/FilePathInformation.tsx +++ b/src/components/Contribute/Skill/FilePathInformation/FilePathInformation.tsx @@ -1,6 +1,6 @@ import React from 'react'; import PathService from '@/components/PathService/PathService'; -import { FormFieldGroupExpandable, FormFieldGroupHeader, FormGroup } from '@patternfly/react-core'; +import { FormGroup } from '@patternfly/react-core'; interface Props { reset?: boolean; @@ -10,27 +10,16 @@ interface Props { const FilePathInformation: React.FC = ({ reset, path, setFilePath }) => { return ( - - Taxonomy Directory Path * -

- ), - id: 'file-path-info-id' - }} - titleDescription="Specify the directory location within taxonomy repository structure for the QnA Yaml and Attribution files." - /> - } - > + <> +

+ Taxonomy Directory Path * +

+

Specify the directory location within taxonomy repository structure for the QnA Yaml and Attribution files.

+ -
+ ); }; diff --git a/src/components/Contribute/Skill/Github/index.tsx b/src/components/Contribute/Skill/Github/index.tsx index def06c8e..d220ec22 100644 --- a/src/components/Contribute/Skill/Github/index.tsx +++ b/src/components/Contribute/Skill/Github/index.tsx @@ -1,7 +1,7 @@ // src/components/Contribute/Skill/Github/index.tsx 'use client'; import React, { useEffect, useState } from 'react'; -import './skills.css'; +import '../skills.css'; import { getGitHubUsername } from '../../../../utils/github'; import { useSession } from 'next-auth/react'; import FilePathInformation from '../FilePathInformation/FilePathInformation'; @@ -30,14 +30,16 @@ import { Title, Button, Content, - Form, AlertGroup, Alert, AlertActionCloseButton, Spinner, - ActionGroup + ActionGroup, + Wizard, + WizardStep } from '@patternfly/react-core'; import AuthorInformation, { FormType } from '../../AuthorInformation'; +import ReviewSubmission from '../ReviewSubmission'; export interface SkillEditFormData { isEditForm: boolean; @@ -89,7 +91,7 @@ export const SkillFormGithub: React.FunctionComponent = ({ skill const [disableAction, setDisableAction] = useState(true); const [reset, setReset] = useState(false); const [isModalOpen, setIsModalOpen] = React.useState(false); - + const [activeStepIndex] = useState(1); const router = useRouter(); const emptySeedExample: SkillSeedExample = { @@ -266,6 +268,13 @@ export const SkillFormGithub: React.FunctionComponent = ({ skill ); }; + const toggleSeedExampleExpansion = (index: number): void => { + setSeedExamples((prevSeedExamples) => + prevSeedExamples.map((seedExample, idx) => (idx === index ? { ...seedExample, isExpanded: !seedExample.isExpanded } : seedExample)) + ); + console.log(`toggleSeedExampleExpansion: Seed Example ${index + 1} expanded to ${!seedExamples[index].isExpanded}`); + }; + const addSeedExample = (): void => { const seedExample = emptySeedExample; seedExample.immutable = false; @@ -347,17 +356,98 @@ export const SkillFormGithub: React.FunctionComponent = ({ skill const handleCancel = () => { router.push('/dashboard'); }; + const steps = [ + { + id: 'author-skill-info', + name: 'Details', + component: ( + <> + + + + ) + }, + { + id: 'file-path-info', + name: 'File Path Information', + component: ( + + ) + }, + { + id: 'skill-seed-examples', + name: 'Create seed data', + component: ( + + ) + }, + { + id: 'attribution-info', + name: 'Attribution', + component: ( + + ) + }, + { + id: 'review-submission', + name: 'Review Submission', + component: , + footer: { + isNextDisabled: true + } + } + ]; return ( - + Dashboard Skill Contribution - + @@ -387,114 +477,67 @@ export const SkillFormGithub: React.FunctionComponent<SkillFormProps> = ({ skill onYamlUploadSkillsFillForm={onYamlUploadSkillsFillForm} /> - <Form className="form-s"> - <AuthorInformation - formType={FormType.Knowledge} - reset={reset} - formData={skillFormData} - setDisableAction={setDisableAction} - email={email} - setEmail={setEmail} - name={name} - setName={setName} - /> - - <SkillsInformation - reset={reset} - isEditForm={skillEditFormData?.isEditForm} - skillFormData={skillFormData} - setDisableAction={setDisableAction} - submissionSummary={submissionSummary} - setSubmissionSummary={setSubmissionSummary} - documentOutline={documentOutline} - setDocumentOutline={setDocumentOutline} - /> - - <FilePathInformation - reset={reset} - path={skillEditFormData ? skillEditFormData.skillFormData.filePath : filePath} - setFilePath={setFilePath} - /> - - <SkillsSeedExample - seedExamples={seedExamples} - handleContextInputChange={handleContextInputChange} - handleContextBlur={handleContextBlur} - handleQuestionInputChange={handleQuestionInputChange} - handleQuestionBlur={handleQuestionBlur} - handleAnswerInputChange={handleAnswerInputChange} - handleAnswerBlur={handleAnswerBlur} - addSeedExample={addSeedExample} - deleteSeedExample={deleteSeedExample} - /> - - <AttributionInformation - reset={reset} - isEditForm={skillEditFormData?.isEditForm} - skillFormData={skillFormData} - setDisableAction={setDisableAction} - titleWork={titleWork} - setTitleWork={setTitleWork} - licenseWork={licenseWork} - setLicenseWork={setLicenseWork} - creators={creators} - setCreators={setCreators} - /> - - {actionGroupAlertContent && ( - <AlertGroup isToast isLiveRegion> - <Alert - variant={actionGroupAlertContent.waitAlert ? 'info' : actionGroupAlertContent.success ? 'success' : 'danger'} - title={actionGroupAlertContent.title} - timeout={actionGroupAlertContent.timeout == false ? false : actionGroupAlertContent.timeout} - onTimeout={onCloseActionGroupAlert} - actionClose={<AlertActionCloseButton onClose={onCloseActionGroupAlert} />} - > - <p> - {actionGroupAlertContent.waitAlert && <Spinner size="md" />} - {actionGroupAlertContent.message} - <br /> - {!actionGroupAlertContent.waitAlert && - actionGroupAlertContent.success && - actionGroupAlertContent.url && - actionGroupAlertContent.url.trim().length > 0 && ( - <a href={actionGroupAlertContent.url} target="_blank" rel="noreferrer"> - View your pull request - </a> - )} - </p> - </Alert> - </AlertGroup> + <Wizard startIndex={activeStepIndex} onClose={handleCancel} height={600}> + {steps.map((step) => ( + <WizardStep key={step.id} id={step.id} name={step.name} footer={step.footer}> + {step.component} + </WizardStep> + ))} + </Wizard> + + {actionGroupAlertContent && ( + <AlertGroup isToast isLiveRegion> + <Alert + variant={actionGroupAlertContent.waitAlert ? 'info' : actionGroupAlertContent.success ? 'success' : 'danger'} + title={actionGroupAlertContent.title} + timeout={actionGroupAlertContent.timeout == false ? false : actionGroupAlertContent.timeout} + onTimeout={onCloseActionGroupAlert} + actionClose={<AlertActionCloseButton onClose={onCloseActionGroupAlert} />} + > + <p> + {actionGroupAlertContent.waitAlert && <Spinner size="md" />} + {actionGroupAlertContent.message} + <br /> + {!actionGroupAlertContent.waitAlert && + actionGroupAlertContent.success && + actionGroupAlertContent.url && + actionGroupAlertContent.url.trim().length > 0 && ( + <a href={actionGroupAlertContent.url} target="_blank" rel="noreferrer"> + View your pull request + </a> + )} + </p> + </Alert> + </AlertGroup> + )} + + <ActionGroup> + {skillEditFormData?.isEditForm && ( + <Update + disableAction={disableAction} + skillFormData={skillFormData} + pullRequestNumber={skillEditFormData.pullRequestNumber} + setActionGroupAlertContent={setActionGroupAlertContent} + yamlFile={skillEditFormData.yamlFile} + attributionFile={skillEditFormData.attributionFile} + branchName={skillEditFormData.branchName} + /> )} - - <ActionGroup> - {skillEditFormData?.isEditForm && ( - <Update - disableAction={disableAction} - skillFormData={skillFormData} - pullRequestNumber={skillEditFormData.pullRequestNumber} - setActionGroupAlertContent={setActionGroupAlertContent} - yamlFile={skillEditFormData.yamlFile} - attributionFile={skillEditFormData.attributionFile} - branchName={skillEditFormData.branchName} - /> - )} - {!skillEditFormData?.isEditForm && ( - <Submit - disableAction={disableAction} - skillFormData={skillFormData} - setActionGroupAlertContent={setActionGroupAlertContent} - githubUsername={githubUsername} - resetForm={resetForm} - /> - )} - <DownloadDropdown skillFormData={skillFormData} githubUsername={githubUsername} /> - <ViewDropdown skillFormData={skillFormData} githubUsername={githubUsername} /> - <Button variant="link" type="button" onClick={handleCancel}> - Cancel - </Button> - </ActionGroup> - </Form> + {!skillEditFormData?.isEditForm && ( + <Submit + disableAction={disableAction} + skillFormData={skillFormData} + setActionGroupAlertContent={setActionGroupAlertContent} + githubUsername={githubUsername} + resetForm={resetForm} + /> + )} + <DownloadDropdown skillFormData={skillFormData} githubUsername={githubUsername} /> + <ViewDropdown skillFormData={skillFormData} githubUsername={githubUsername} /> + <Button variant="link" type="button" onClick={handleCancel}> + Cancel + </Button> + </ActionGroup> </PageSection> </PageGroup> ); diff --git a/src/components/Contribute/Skill/Github/skills.css b/src/components/Contribute/Skill/Github/skills.css deleted file mode 100644 index 739f80d4..00000000 --- a/src/components/Contribute/Skill/Github/skills.css +++ /dev/null @@ -1,16 +0,0 @@ -/*!* Skill CSS *!*/ - -.form-s { - width: 80%; - margin-bottom: 50px; -} - -/*.submit:hover,*/ -/*.download-yaml:hover,*/ -/*.download-attribution:hover {*/ -/*}*/ - -.heading { - text-align: left; - font-size: medium; -} diff --git a/src/components/Contribute/Skill/Native/index.tsx b/src/components/Contribute/Skill/Native/index.tsx index 40036519..2d2be787 100644 --- a/src/components/Contribute/Skill/Native/index.tsx +++ b/src/components/Contribute/Skill/Native/index.tsx @@ -1,7 +1,7 @@ // src/components/Contribute/Skill/Native/index.tsx 'use client'; import React, { useEffect, useState } from 'react'; -import './skills.css'; +import '../skills.css'; import { useSession } from 'next-auth/react'; import AuthorInformation from '@/components/Contribute/AuthorInformation'; import { FormType } from '@/components/Contribute/AuthorInformation'; @@ -31,13 +31,15 @@ import { Title, Button, Content, - Form, AlertGroup, Alert, AlertActionCloseButton, Spinner, - ActionGroup + ActionGroup, + Wizard, + WizardStep } from '@patternfly/react-core'; +import ReviewSubmission from '../ReviewSubmission'; export interface SkillEditFormData { isEditForm: boolean; @@ -88,7 +90,7 @@ export const SkillFormNative: React.FunctionComponent<SkillFormProps> = ({ skill const [disableAction, setDisableAction] = useState<boolean>(true); const [reset, setReset] = useState<boolean>(false); const [isModalOpen, setIsModalOpen] = React.useState(false); - + const [activeStepIndex] = useState<number>(1); const router = useRouter(); const emptySeedExample: SkillSeedExample = { @@ -243,6 +245,13 @@ export const SkillFormNative: React.FunctionComponent<SkillFormProps> = ({ skill ); }; + const toggleSeedExampleExpansion = (index: number): void => { + setSeedExamples((prevSeedExamples) => + prevSeedExamples.map((seedExample, idx) => (idx === index ? { ...seedExample, isExpanded: !seedExample.isExpanded } : seedExample)) + ); + console.log(`toggleSeedExampleExpansion: Seed Example ${index + 1} expanded to ${!seedExamples[index].isExpanded}`); + }; + const addSeedExample = (): void => { const seedExample = emptySeedExample; seedExample.immutable = false; @@ -325,16 +334,98 @@ export const SkillFormNative: React.FunctionComponent<SkillFormProps> = ({ skill router.push('/dashboard'); }; + const steps = [ + { + id: 'author-skill-info', + name: 'Details', + component: ( + <> + <AuthorInformation + formType={FormType.Knowledge} + reset={reset} + formData={skillFormData} + setDisableAction={setDisableAction} + email={email} + setEmail={setEmail} + name={name} + setName={setName} + /> + <SkillsInformation + reset={reset} + isEditForm={skillEditFormData?.isEditForm} + skillFormData={skillFormData} + setDisableAction={setDisableAction} + submissionSummary={submissionSummary} + setSubmissionSummary={setSubmissionSummary} + documentOutline={documentOutline} + setDocumentOutline={setDocumentOutline} + /> + </> + ) + }, + { + id: 'file-path-info', + name: 'File Path Information', + component: ( + <FilePathInformation reset={reset} path={skillEditFormData ? skillEditFormData.skillFormData.filePath : filePath} setFilePath={setFilePath} /> + ) + }, + { + id: 'skill-seed-examples', + name: 'Create seed data', + component: ( + <SkillsSeedExample + seedExamples={seedExamples} + handleContextInputChange={handleContextInputChange} + handleContextBlur={handleContextBlur} + handleQuestionInputChange={handleQuestionInputChange} + handleQuestionBlur={handleQuestionBlur} + handleAnswerInputChange={handleAnswerInputChange} + handleAnswerBlur={handleAnswerBlur} + toggleSeedExampleExpansion={toggleSeedExampleExpansion} + addSeedExample={addSeedExample} + deleteSeedExample={deleteSeedExample} + /> + ) + }, + { + id: 'attribution-info', + name: 'Attribution', + component: ( + <AttributionInformation + reset={reset} + isEditForm={skillEditFormData?.isEditForm} + skillFormData={skillFormData} + setDisableAction={setDisableAction} + titleWork={titleWork} + setTitleWork={setTitleWork} + licenseWork={licenseWork} + setLicenseWork={setLicenseWork} + creators={creators} + setCreators={setCreators} + /> + ) + }, + { + id: 'review-submission', + name: 'Review Submission', + component: <ReviewSubmission skillFormData={skillFormData} />, + footer: { + isNextDisabled: true + } + } + ]; + return ( <PageGroup> - <PageBreadcrumb hasBodyWrapper={false}> + <PageBreadcrumb> <Breadcrumb> <BreadcrumbItem to="/"> Dashboard </BreadcrumbItem> <BreadcrumbItem isActive>Skill Contribution</BreadcrumbItem> </Breadcrumb> </PageBreadcrumb> - <PageSection hasBodyWrapper={false}> + <PageSection className="skill-form"> <Flex justifyContent={{ default: 'justifyContentSpaceBetween' }}> <FlexItem> <Title headingLevel="h1" size="2xl" style={{ paddingTop: '10px' }}> @@ -363,114 +454,67 @@ export const SkillFormNative: React.FunctionComponent<SkillFormProps> = ({ skill onYamlUploadSkillsFillForm={onYamlUploadSkillsFillForm} /> - <Form className="form-s"> - <AuthorInformation - formType={FormType.Knowledge} - reset={reset} - formData={skillFormData} - setDisableAction={setDisableAction} - email={email} - setEmail={setEmail} - name={name} - setName={setName} - /> - - <SkillsInformation - reset={reset} - isEditForm={skillEditFormData?.isEditForm} - skillFormData={skillFormData} - setDisableAction={setDisableAction} - submissionSummary={submissionSummary} - setSubmissionSummary={setSubmissionSummary} - documentOutline={documentOutline} - setDocumentOutline={setDocumentOutline} - /> - - <FilePathInformation - reset={reset} - path={skillEditFormData ? skillEditFormData.skillFormData.filePath : filePath} - setFilePath={setFilePath} - /> - - <SkillsSeedExample - seedExamples={seedExamples} - handleContextInputChange={handleContextInputChange} - handleContextBlur={handleContextBlur} - handleQuestionInputChange={handleQuestionInputChange} - handleQuestionBlur={handleQuestionBlur} - handleAnswerInputChange={handleAnswerInputChange} - handleAnswerBlur={handleAnswerBlur} - addSeedExample={addSeedExample} - deleteSeedExample={deleteSeedExample} - /> - - <AttributionInformation - reset={reset} - isEditForm={skillEditFormData?.isEditForm} - skillFormData={skillFormData} - setDisableAction={setDisableAction} - titleWork={titleWork} - setTitleWork={setTitleWork} - licenseWork={licenseWork} - setLicenseWork={setLicenseWork} - creators={creators} - setCreators={setCreators} - /> - - {actionGroupAlertContent && ( - <AlertGroup isToast isLiveRegion> - <Alert - variant={actionGroupAlertContent.waitAlert ? 'info' : actionGroupAlertContent.success ? 'success' : 'danger'} - title={actionGroupAlertContent.title} - timeout={actionGroupAlertContent.timeout == false ? false : actionGroupAlertContent.timeout} - onTimeout={onCloseActionGroupAlert} - actionClose={<AlertActionCloseButton onClose={onCloseActionGroupAlert} />} - > - <p> - {actionGroupAlertContent.waitAlert && <Spinner size="md" />} - {actionGroupAlertContent.message} - <br /> - {!actionGroupAlertContent.waitAlert && - actionGroupAlertContent.success && - actionGroupAlertContent.url && - actionGroupAlertContent.url.trim().length > 0 && ( - <a href={actionGroupAlertContent.url} rel="noreferrer"> - View your skill contribution - </a> - )} - </p> - </Alert> - </AlertGroup> + <Wizard startIndex={activeStepIndex} onClose={handleCancel} height={600}> + {steps.map((step) => ( + <WizardStep key={step.id} id={step.id} name={step.name} footer={step.footer}> + {step.component} + </WizardStep> + ))} + </Wizard> + + {actionGroupAlertContent && ( + <AlertGroup isToast isLiveRegion> + <Alert + variant={actionGroupAlertContent.waitAlert ? 'info' : actionGroupAlertContent.success ? 'success' : 'danger'} + title={actionGroupAlertContent.title} + timeout={actionGroupAlertContent.timeout == false ? false : actionGroupAlertContent.timeout} + onTimeout={onCloseActionGroupAlert} + actionClose={<AlertActionCloseButton onClose={onCloseActionGroupAlert} />} + > + <p> + {actionGroupAlertContent.waitAlert && <Spinner size="md" />} + {actionGroupAlertContent.message} + <br /> + {!actionGroupAlertContent.waitAlert && + actionGroupAlertContent.success && + actionGroupAlertContent.url && + actionGroupAlertContent.url.trim().length > 0 && ( + <a href={actionGroupAlertContent.url} rel="noreferrer"> + View your skill contribution + </a> + )} + </p> + </Alert> + </AlertGroup> + )} + + <ActionGroup> + {skillEditFormData?.isEditForm && ( + <Update + disableAction={disableAction} + skillFormData={skillFormData} + pullRequestNumber={skillEditFormData.pullRequestNumber} + setActionGroupAlertContent={setActionGroupAlertContent} + yamlFile={skillEditFormData.yamlFile} + attributionFile={skillEditFormData.attributionFile} + branchName={skillEditFormData.branchName} + /> )} - - <ActionGroup> - {skillEditFormData?.isEditForm && ( - <Update - disableAction={disableAction} - skillFormData={skillFormData} - pullRequestNumber={skillEditFormData.pullRequestNumber} - setActionGroupAlertContent={setActionGroupAlertContent} - yamlFile={skillEditFormData.yamlFile} - attributionFile={skillEditFormData.attributionFile} - branchName={skillEditFormData.branchName} - /> - )} - {!skillEditFormData?.isEditForm && ( - <Submit - disableAction={disableAction} - skillFormData={skillFormData} - setActionGroupAlertContent={setActionGroupAlertContent} - email={email} - resetForm={resetForm} - /> - )} - <DownloadDropdown skillFormData={skillFormData} githubUsername={githubUsername} /> - <ViewDropdown skillFormData={skillFormData} githubUsername={githubUsername} /> - <Button variant="link" type="button" onClick={handleCancel}> - Cancel - </Button> - </ActionGroup> - </Form> + {!skillEditFormData?.isEditForm && ( + <Submit + disableAction={disableAction} + skillFormData={skillFormData} + setActionGroupAlertContent={setActionGroupAlertContent} + email={email} + resetForm={resetForm} + /> + )} + <DownloadDropdown skillFormData={skillFormData} githubUsername={githubUsername} /> + <ViewDropdown skillFormData={skillFormData} githubUsername={githubUsername} /> + <Button variant="link" type="button" onClick={handleCancel}> + Cancel + </Button> + </ActionGroup> </PageSection> </PageGroup> ); diff --git a/src/components/Contribute/Skill/Native/skills.css b/src/components/Contribute/Skill/Native/skills.css deleted file mode 100644 index 8101556e..00000000 --- a/src/components/Contribute/Skill/Native/skills.css +++ /dev/null @@ -1,11 +0,0 @@ -/* Skill CSS */ - -.form-s { - width: 80%; - margin-bottom: 50px; -} - -.heading { - text-align: left; - font-size: medium; -} diff --git a/src/components/Contribute/Skill/ReviewSubmission/index.tsx b/src/components/Contribute/Skill/ReviewSubmission/index.tsx new file mode 100644 index 00000000..7d81aebb --- /dev/null +++ b/src/components/Contribute/Skill/ReviewSubmission/index.tsx @@ -0,0 +1,82 @@ +// src/components/Contribute/Skill/ReviewSubmission/ReviewSubmission.tsx +import { SkillFormData } from '@/types'; +import { Content, ContentVariants } from '@patternfly/react-core'; +import React from 'react'; + +interface ReviewSubmissionProps { + skillFormData: SkillFormData; +} + +export const ReviewSubmission: React.FC<ReviewSubmissionProps> = ({ skillFormData }) => { + return ( + <div> + <Content component={ContentVariants.h2}>Review Submission</Content> + {/* Author Information */} + <p> + <strong>Author Information</strong> + </p> + <p> + <i>Name:</i> {skillFormData.name} + </p> + <p> + <i>Email:</i> {skillFormData.email} + </p> + + {/* Skill Information */} + <p> + <strong>Skill Information</strong> + </p> + <p> + <i>Submission Summary:</i> {skillFormData.submissionSummary} + </p> + <p> + <i>Document Outline:</i> {skillFormData.documentOutline} + </p> + + {/* File Path Information */} + <p> + <strong>File Path Information</strong> + </p> + <p> + <i>File Path:</i> {skillFormData.filePath} + </p> + + {/* Seed Examples */} + <p> + <strong>Seed Examples</strong> + </p> + {skillFormData.seedExamples.map((seedExample, index) => ( + <div key={index}> + <p> + <strong>Seed Examples {index + 1}</strong> + </p> + <p> + <i>Context:</i> {seedExample.context} + </p> + <p> + <i>Question {index + 1}:</i> {seedExample.question} + </p> + <p> + <i>Answer {index + 1}:</i> {seedExample.answer} + </p> + </div> + ))} + + {/* Attribution Information */} + <p> + <strong>Attribution Information</strong> + </p> + <p> + <i>Title of Work:</i> {skillFormData.titleWork} + </p> + <p> + <i>License of Work:</i> {skillFormData.licenseWork} + </p> + <p> + <i>Creators:</i> {skillFormData.creators} + </p> + </div> + ); +}; + +export default ReviewSubmission; diff --git a/src/components/Contribute/Skill/SkillsInformation/SkillsInformation.tsx b/src/components/Contribute/Skill/SkillsInformation/SkillsInformation.tsx index 8e301035..b2354a8e 100644 --- a/src/components/Contribute/Skill/SkillsInformation/SkillsInformation.tsx +++ b/src/components/Contribute/Skill/SkillsInformation/SkillsInformation.tsx @@ -1,16 +1,7 @@ import React, { useEffect } from 'react'; import { checkSkillFormCompletion } from '../validation'; import { SkillFormData } from '@/types'; -import { - ValidatedOptions, - FormFieldGroupExpandable, - FormFieldGroupHeader, - FormGroup, - TextInput, - HelperText, - HelperTextItem, - TextArea -} from '@patternfly/react-core'; +import { ValidatedOptions, FormGroup, TextInput, HelperText, HelperTextItem, TextArea } from '@patternfly/react-core'; import { ExclamationCircleIcon } from '@patternfly/react-icons'; interface Props { @@ -72,24 +63,13 @@ const SkillsInformation: React.FC<Props> = ({ }; return ( - <FormFieldGroupExpandable - isExpanded - toggleAriaLabel="Details" - header={ - <FormFieldGroupHeader - titleText={{ - text: ( - <p> - Skill Information <span style={{ color: 'red' }}>*</span> - </p> - ), - id: 'skills-info-id' - }} - titleDescription="Provide brief information about the Skills." - /> - } - > - <FormGroup key={'skills-info-details-submission_summary'} label="Submission summary"> + <> + <h2> + <strong>Skill Information</strong> <span style={{ color: 'red' }}>*</span> + </h2> + <p>Provide brief information about the Skills.</p> + + <FormGroup isRequired key={'skills-info-details-submission_summary'} label="Submission summary"> <TextInput isRequired type="text" @@ -109,7 +89,7 @@ const SkillsInformation: React.FC<Props> = ({ </HelperText> )} </FormGroup> - <FormGroup key={'skills-info-details-document_outline'} label="Document Outline"> + <FormGroup isRequired key={'skills-info-details-document_outline'} label="Document Outline"> <TextArea isRequired type="text" @@ -130,7 +110,7 @@ const SkillsInformation: React.FC<Props> = ({ </HelperText> )} </FormGroup> - </FormFieldGroupExpandable> + </> ); }; diff --git a/src/components/Contribute/Skill/SkillsSeedExample/SkillsSeedExample.tsx b/src/components/Contribute/Skill/SkillsSeedExample/SkillsSeedExample.tsx index 41e53d64..1e7ebc31 100644 --- a/src/components/Contribute/Skill/SkillsSeedExample/SkillsSeedExample.tsx +++ b/src/components/Contribute/Skill/SkillsSeedExample/SkillsSeedExample.tsx @@ -1,7 +1,6 @@ import React from 'react'; import { SkillSeedExample } from '@/types'; import { - FormFieldGroupExpandable, FormFieldGroupHeader, Button, FormGroup, @@ -9,7 +8,11 @@ import { ValidatedOptions, FormHelperText, HelperText, - HelperTextItem + HelperTextItem, + Accordion, + AccordionItem, + AccordionToggle, + AccordionContent } from '@patternfly/react-core'; import { ExternalLinkAltIcon, TrashIcon, ExclamationCircleIcon, PlusCircleIcon } from '@patternfly/react-icons'; @@ -21,6 +24,7 @@ interface Props { handleQuestionBlur: (seedExampleIndex: number) => void; handleAnswerInputChange: (seedExampleIndex: number, answerValue: string) => void; handleAnswerBlur: (seedExampleIndex: number) => void; + toggleSeedExampleExpansion?: (index: number) => void; addSeedExample: () => void; deleteSeedExample: (seedExampleIndex: number) => void; } @@ -33,125 +37,111 @@ const SkillsSeedExample: React.FC<Props> = ({ handleQuestionBlur, handleAnswerInputChange, handleAnswerBlur, + toggleSeedExampleExpansion = () => {}, addSeedExample, deleteSeedExample }) => { return ( - <FormFieldGroupExpandable - style={{ justifyContent: 'left' }} - isExpanded - toggleAriaLabel="Details" - header={ - <FormFieldGroupHeader - titleText={{ - text: ( - <p> - Seed Examples <span style={{ color: 'red' }}>*</span> - </p> - ), - id: 'seed-examples-id' - }} - titleDescription={ + <div> + <FormFieldGroupHeader + titleText={{ + text: ( <p> - Add seed examples with question and answer pair and related context (optional). A minimum of five seed examples are required.{' '} - <a href="https://docs.instructlab.ai/taxonomy/skills/#skills-yaml-examples" target="_blank" rel="noopener noreferrer"> - {' '} - Learn more about seed examples - <ExternalLinkAltIcon style={{ padding: '3px' }}></ExternalLinkAltIcon> - </a> + <strong>Seed Examples</strong> <span style={{ color: 'red' }}>*</span> </p> - } - /> - } - > - {seedExamples.map((seedExample: SkillSeedExample, seedExampleIndex: number) => ( - <FormFieldGroupExpandable - isExpanded={seedExample.isExpanded} - toggleAriaLabel="Details" - key={seedExampleIndex} - header={ - <FormFieldGroupHeader - titleText={{ - text: ( - <p> - Seed Example {seedExampleIndex + 1} {seedExample.immutable && <span style={{ color: 'red' }}>*</span>} - </p> - ), - id: 'nested-field-group1-titleText-id' - }} - actions={ - !seedExample.immutable && ( + ), + id: 'seed-examples-id' + }} + titleDescription={ + <p> + Add seed examples with question and answer pair and related context (optional). A minimum of five seed examples are required.{' '} + <a href="https://docs.instructlab.ai/taxonomy/skills/#skills-yaml-examples" target="_blank" rel="noopener noreferrer"> + {' '} + Learn more about seed examples + <ExternalLinkAltIcon style={{ padding: '3px' }}></ExternalLinkAltIcon> + </a> + </p> + } + /> + <Accordion asDefinitionList={false}> + {seedExamples.map((seedExample: SkillSeedExample, seedExampleIndex: number) => ( + <AccordionItem key={seedExampleIndex} isExpanded={seedExample.isExpanded}> + <AccordionToggle onClick={() => toggleSeedExampleExpansion(seedExampleIndex)} id={`seed-example-toggle-${seedExampleIndex}`}> + <span style={{ display: 'flex', alignItems: 'normal', justifyContent: 'space-between', width: '100%' }}> + Seed Example {seedExampleIndex + 1} {seedExample.immutable && '*'} + {!seedExample.immutable && ( <Button icon={<TrashIcon />} variant="plain" aria-label="Remove" onClick={() => deleteSeedExample(seedExampleIndex)} /> - ) - } - /> - } - > - <FormGroup isRequired key={seedExampleIndex + '-question'} label="Question"> - <TextArea - key={seedExampleIndex * 10 + 2} - isRequired - type="text" - aria-label={`Question ${seedExampleIndex + 1}`} - placeholder={`Enter question ${seedExampleIndex + 1}`} - value={seedExample.question} - validated={seedExample.isQuestionValid} - onChange={(_event, questionValue) => handleQuestionInputChange(seedExampleIndex, questionValue)} - onBlur={() => handleQuestionBlur(seedExampleIndex)} - /> - {seedExample.isQuestionValid === ValidatedOptions.error && ( - <FormHelperText key={seedExampleIndex * 100 + 2}> - <HelperText> - <HelperTextItem icon={<ExclamationCircleIcon />} variant={seedExample.isQuestionValid}> - {seedExample.questionValidationError || 'Required field '} - </HelperTextItem> - </HelperText> - </FormHelperText> - )} - </FormGroup> - <FormGroup key={seedExampleIndex + '-context'} label="Context"> - <TextArea - key={seedExampleIndex * 10 + 1} - isRequired - type="text" - aria-label={`Context ${seedExampleIndex + 1}`} - placeholder="Enter the context for the question and answer pair. (optional)" - value={seedExample.context} - validated={seedExample.isContextValid} - onChange={(_event, contextValue: string) => handleContextInputChange(seedExampleIndex, contextValue)} - onBlur={() => handleContextBlur(seedExampleIndex)} - /> - </FormGroup> - <FormGroup isRequired key={seedExampleIndex + '-answer'} label="Answer"> - <TextArea - key={seedExampleIndex * 10 + 3} - isRequired - type="text" - aria-label={`Answer ${seedExampleIndex + 1}`} - placeholder={`Enter answer ${seedExampleIndex + 1}`} - value={seedExample.answer} - validated={seedExample.isAnswerValid} - onChange={(_event, answerValue) => handleAnswerInputChange(seedExampleIndex, answerValue)} - onBlur={() => handleAnswerBlur(seedExampleIndex)} - /> - {seedExample.isAnswerValid === ValidatedOptions.error && ( - <FormHelperText key={seedExampleIndex * 100 + 4}> - <HelperText> - <HelperTextItem icon={<ExclamationCircleIcon />} variant={seedExample.isAnswerValid}> - {seedExample.answerValidationError || 'Required field'} - </HelperTextItem> - </HelperText> - </FormHelperText> - )} - </FormGroup> - </FormFieldGroupExpandable> - ))} + )} + </span> + </AccordionToggle> + <AccordionContent id={`seed-example-content-${seedExampleIndex}`}> + <FormGroup isRequired key={seedExampleIndex + '-question'} label="Question"> + <TextArea + key={seedExampleIndex * 10 + 2} + isRequired + type="text" + aria-label={`Question ${seedExampleIndex + 1}`} + placeholder={`Enter question ${seedExampleIndex + 1}`} + value={seedExample.question} + validated={seedExample.isQuestionValid} + onChange={(_event, questionValue) => handleQuestionInputChange(seedExampleIndex, questionValue)} + onBlur={() => handleQuestionBlur(seedExampleIndex)} + /> + {seedExample.isQuestionValid === ValidatedOptions.error && ( + <FormHelperText key={seedExampleIndex * 100 + 2}> + <HelperText> + <HelperTextItem icon={<ExclamationCircleIcon />} variant={seedExample.isQuestionValid}> + {seedExample.questionValidationError || 'Required field '} + </HelperTextItem> + </HelperText> + </FormHelperText> + )} + </FormGroup> + <FormGroup key={seedExampleIndex + '-context'} label="Context"> + <TextArea + key={seedExampleIndex * 10 + 1} + isRequired + type="text" + aria-label={`Context ${seedExampleIndex + 1}`} + placeholder="Enter the context for the question and answer pair. (optional)" + value={seedExample.context} + validated={seedExample.isContextValid} + onChange={(_event, contextValue: string) => handleContextInputChange(seedExampleIndex, contextValue)} + onBlur={() => handleContextBlur(seedExampleIndex)} + /> + </FormGroup> + <FormGroup isRequired key={seedExampleIndex + '-answer'} label="Answer"> + <TextArea + key={seedExampleIndex * 10 + 3} + isRequired + type="text" + aria-label={`Answer ${seedExampleIndex + 1}`} + placeholder={`Enter answer ${seedExampleIndex + 1}`} + value={seedExample.answer} + validated={seedExample.isAnswerValid} + onChange={(_event, answerValue) => handleAnswerInputChange(seedExampleIndex, answerValue)} + onBlur={() => handleAnswerBlur(seedExampleIndex)} + /> + {seedExample.isAnswerValid === ValidatedOptions.error && ( + <FormHelperText key={seedExampleIndex * 100 + 4}> + <HelperText> + <HelperTextItem icon={<ExclamationCircleIcon />} variant={seedExample.isAnswerValid}> + {seedExample.answerValidationError || 'Required field'} + </HelperTextItem> + </HelperText> + </FormHelperText> + )} + </FormGroup> + </AccordionContent> + </AccordionItem> + ))} + </Accordion> <div style={{ display: 'flex', justifyContent: 'flex-start' }}> <Button icon={<PlusCircleIcon />} variant="link" type="button" onClick={addSeedExample}> Add Seed Example </Button> </div> - </FormFieldGroupExpandable> + </div> ); }; diff --git a/src/components/Contribute/Skill/skills.css b/src/components/Contribute/Skill/skills.css new file mode 100644 index 00000000..6cd383ae --- /dev/null +++ b/src/components/Contribute/Skill/skills.css @@ -0,0 +1,23 @@ +/* Skill CSS */ + +.form-s { + width: 80%; + margin-bottom: 50px; +} + +.heading { + text-align: left; + font-size: medium; +} + +.skill-form { + line-height: 3; +} + +.pf-v6-c-wizard { + display: flex; + flex-direction: column; + flex-grow: 1; + min-height: 60vh; + overflow: hidden; +} diff --git a/src/components/Dashboard/Github/dashboard.tsx b/src/components/Dashboard/Github/dashboard.tsx index 1c13501e..9cb0b3d7 100644 --- a/src/components/Dashboard/Github/dashboard.tsx +++ b/src/components/Dashboard/Github/dashboard.tsx @@ -29,7 +29,8 @@ import { CardBody, Flex, FlexItem, - Label + Label, + ModalBody } from '@patternfly/react-core'; import { ExternalLinkAltIcon, OutlinedQuestionCircleIcon, GithubIcon } from '@patternfly/react-icons'; @@ -130,10 +131,12 @@ const DashboardGithub: React.FunctionComponent = () => { <div style={{ marginBottom: '20px' }} /> {!isFirstPullDone && ( <Modal variant={ModalVariant.small} title="Retrieving your submissions" isOpen={isLoading} onClose={() => handleOnClose()}> - <div> - <Spinner size="md" /> - Retrieving all your skills and knowledge submissions from taxonomy repository. - </div> + <ModalBody> + <div> + <Spinner size="md" /> + Retrieving all your skills and knowledge submissions from taxonomy repository. + </div> + </ModalBody> </Modal> )} {isFirstPullDone && pullRequests.length === 0 ? ( diff --git a/src/components/Dashboard/Native/dashboard.tsx b/src/components/Dashboard/Native/dashboard.tsx index 3f8b1963..28a29a25 100644 --- a/src/components/Dashboard/Native/dashboard.tsx +++ b/src/components/Dashboard/Native/dashboard.tsx @@ -492,7 +492,6 @@ const DashboardNative: React.FunctionComponent = () => { <Button key="confirm" variant="primary" onClick={() => handleDeleteContributionConfirm()}> Delete </Button> - , <Button key="cancel" variant="secondary" onClick={() => handleDeleteContributionCancel()}> Cancel </Button> @@ -516,7 +515,6 @@ const DashboardNative: React.FunctionComponent = () => { Publish {' '} {isPublishing && <Spinner isInline aria-label="Publishing contribution" />} </Button> - , <Button key="cancel" variant="secondary" onClick={() => handlePublishContributionCancel()}> Cancel </Button> diff --git a/src/components/YamlCodeModal/index.tsx b/src/components/YamlCodeModal/index.tsx index f29929fc..1186611b 100644 --- a/src/components/YamlCodeModal/index.tsx +++ b/src/components/YamlCodeModal/index.tsx @@ -30,7 +30,6 @@ export const YamlCodeModal: React.FC<YamlCodeModalProps> = ({ isModalOpen, handl <Button key="close" variant="primary" onClick={handleModalToggle}> Close </Button> - , <CopyToClipboardButton key="copy" text={yamlContent} /> </ModalFooter> </Modal>