From f5ead4aa16b1e0cd3bba46e3836a16f0c44a204e Mon Sep 17 00:00:00 2001 From: Anil Vishnoi Date: Thu, 12 Dec 2024 11:21:56 -0800 Subject: [PATCH] Updated github knowledge form to wizard based form. Signed-off-by: Anil Vishnoi --- .../EditKnowledge/EditKnowledge.tsx | 12 +- .../AttributionInformation.tsx | 2 +- .../Contribute/Knowledge/AutoFill.ts | 4 +- .../DownloadAttribution.tsx | 2 +- .../DownloadDropdown/DownloadDropdown.tsx | 2 +- .../Knowledge/DownloadYaml/DownloadYaml.tsx | 3 +- .../DocumentInformation.tsx | 2 +- .../Knowledge/Github/Submit/Submit.tsx | 4 +- .../Contribute/Knowledge/Github/index.tsx | 467 ++++++++---------- .../KnowledgeInformation.tsx | 2 +- .../KnowledgeQuestionAnswerPairs.tsx | 4 +- .../KnowledgeSeedExample.tsx | 6 +- .../DocumentInformation.tsx | 2 +- .../Knowledge/Native/Submit/Submit.tsx | 4 +- .../Contribute/Knowledge/Native/index.tsx | 67 +-- .../{Native => }/ReviewSubmission/index.tsx | 2 +- .../Contribute/Knowledge/validation.tsx | 9 +- src/types/index.ts | 47 ++ 18 files changed, 301 insertions(+), 340 deletions(-) rename src/components/Contribute/Knowledge/{Native => }/ReviewSubmission/index.tsx (97%) diff --git a/src/components/Contribute/EditKnowledge/EditKnowledge.tsx b/src/components/Contribute/EditKnowledge/EditKnowledge.tsx index e9287a81..3a8a2639 100644 --- a/src/components/Contribute/EditKnowledge/EditKnowledge.tsx +++ b/src/components/Contribute/EditKnowledge/EditKnowledge.tsx @@ -8,16 +8,12 @@ import { KnowledgeSchemaVersion } from '@/types/const'; import { fetchPullRequest, fetchFileContent, fetchPullRequestFiles } from '@/utils/github'; import yaml from 'js-yaml'; import axios from 'axios'; -import KnowledgeFormGithub, { - KnowledgeEditFormData, - KnowledgeFormData, - QuestionAndAnswerPair, - SeedExample -} from '@/components/Contribute/Knowledge/Github'; +import { KnowledgeEditFormData, KnowledgeFormData, QuestionAndAnswerPair, KnowledgeSeedExample } from '@/types'; import { ValidatedOptions } from '@patternfly/react-core/dist/esm/helpers/constants'; import { useEffect, useState } from 'react'; import { Modal, ModalVariant } from '@patternfly/react-core/dist/esm/deprecated/components/Modal/Modal'; import { useRouter } from 'next/navigation'; +import KnowledgeFormGithub from '../Knowledge/Github'; interface EditKnowledgeClientComponentProps { prNumber: number; @@ -88,10 +84,10 @@ const EditKnowledge: React.FC = ({ prNumber } knowledgeExistingFormData.knowledgeDocumentCommit = yamlData.document.commit; knowledgeExistingFormData.documentName = yamlData.document.patterns.join(', '); - const seedExamples: SeedExample[] = []; + const seedExamples: KnowledgeSeedExample[] = []; yamlData.seed_examples.forEach((seed, index) => { // iterate through questions_and_answers and create a new object for each - const example: SeedExample = { + const example: KnowledgeSeedExample = { immutable: index < 5 ? true : false, isExpanded: true, context: seed.context, diff --git a/src/components/Contribute/Knowledge/AttributionInformation/AttributionInformation.tsx b/src/components/Contribute/Knowledge/AttributionInformation/AttributionInformation.tsx index 38c4e8fd..b606a3ce 100644 --- a/src/components/Contribute/Knowledge/AttributionInformation/AttributionInformation.tsx +++ b/src/components/Contribute/Knowledge/AttributionInformation/AttributionInformation.tsx @@ -5,8 +5,8 @@ import { HelperText } from '@patternfly/react-core/dist/dynamic/components/Helpe import { HelperTextItem } from '@patternfly/react-core/dist/dynamic/components/HelperText'; import ExclamationCircleIcon from '@patternfly/react-icons/dist/dynamic/icons/exclamation-circle-icon'; import { ValidatedOptions } from '@patternfly/react-core/dist/esm/helpers/constants'; -import { KnowledgeFormData } from '../Github'; import { checkKnowledgeFormCompletion } from '../validation'; +import { KnowledgeFormData } from '@/types'; interface Props { reset: boolean; diff --git a/src/components/Contribute/Knowledge/AutoFill.ts b/src/components/Contribute/Knowledge/AutoFill.ts index d188144b..7c079595 100644 --- a/src/components/Contribute/Knowledge/AutoFill.ts +++ b/src/components/Contribute/Knowledge/AutoFill.ts @@ -1,4 +1,4 @@ -import { KnowledgeFormData, QuestionAndAnswerPair, SeedExample } from './Github'; +import { KnowledgeFormData, QuestionAndAnswerPair, KnowledgeSeedExample } from './Github'; import { ValidatedOptions } from '@patternfly/react-core/dist/esm/helpers/constants'; const questionAndAnswerPairs1: QuestionAndAnswerPair[] = [ @@ -127,7 +127,7 @@ const questionAndAnswerPairs5: QuestionAndAnswerPair[] = [ } ]; -const seedExamples: SeedExample[] = [ +const seedExamples: KnowledgeSeedExample[] = [ { immutable: true, isExpanded: true, diff --git a/src/components/Contribute/Knowledge/DownloadAttribution/DownloadAttribution.tsx b/src/components/Contribute/Knowledge/DownloadAttribution/DownloadAttribution.tsx index 92d6a512..571682af 100644 --- a/src/components/Contribute/Knowledge/DownloadAttribution/DownloadAttribution.tsx +++ b/src/components/Contribute/Knowledge/DownloadAttribution/DownloadAttribution.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { KnowledgeFormData } from '../Github'; import { DropdownItem } from '@patternfly/react-core/dist/esm/components/Dropdown/DropdownItem'; import FileIcon from '@patternfly/react-icons/dist/esm/icons/file-icon'; +import { KnowledgeFormData } from '@/types'; interface Props { knowledgeFormData: KnowledgeFormData; diff --git a/src/components/Contribute/Knowledge/DownloadDropdown/DownloadDropdown.tsx b/src/components/Contribute/Knowledge/DownloadDropdown/DownloadDropdown.tsx index e8f962d8..2e216ab1 100644 --- a/src/components/Contribute/Knowledge/DownloadDropdown/DownloadDropdown.tsx +++ b/src/components/Contribute/Knowledge/DownloadDropdown/DownloadDropdown.tsx @@ -4,8 +4,8 @@ import { DropdownList } from '@patternfly/react-core/dist/dynamic/components/Dro import { MenuToggle, MenuToggleElement } from '@patternfly/react-core/dist/dynamic/components/MenuToggle'; import DownloadYaml from '../DownloadYaml/DownloadYaml'; import DownloadAttribution from '../DownloadAttribution/DownloadAttribution'; -import { KnowledgeFormData } from '../Github'; import DownloadIcon from '@patternfly/react-icons/dist/esm/icons/download-icon'; +import { KnowledgeFormData } from '@/types'; interface Props { knowledgeFormData: KnowledgeFormData; diff --git a/src/components/Contribute/Knowledge/DownloadYaml/DownloadYaml.tsx b/src/components/Contribute/Knowledge/DownloadYaml/DownloadYaml.tsx index a451f55f..78649408 100644 --- a/src/components/Contribute/Knowledge/DownloadYaml/DownloadYaml.tsx +++ b/src/components/Contribute/Knowledge/DownloadYaml/DownloadYaml.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import { KnowledgeFormData } from '../Github'; -import { KnowledgeYamlData } from '@/types'; +import { KnowledgeFormData, KnowledgeYamlData } from '@/types'; import { KnowledgeSchemaVersion } from '@/types/const'; import { dumpYaml } from '@/utils/yamlConfig'; import { DropdownItem } from '@patternfly/react-core/dist/esm/components/Dropdown/DropdownItem'; diff --git a/src/components/Contribute/Knowledge/Github/DocumentInformation/DocumentInformation.tsx b/src/components/Contribute/Knowledge/Github/DocumentInformation/DocumentInformation.tsx index 53cbf0fd..788063c4 100644 --- a/src/components/Contribute/Knowledge/Github/DocumentInformation/DocumentInformation.tsx +++ b/src/components/Contribute/Knowledge/Github/DocumentInformation/DocumentInformation.tsx @@ -8,9 +8,9 @@ import { HelperText } from '@patternfly/react-core/dist/dynamic/components/Helpe import { HelperTextItem } from '@patternfly/react-core/dist/dynamic/components/HelperText'; import ExclamationCircleIcon from '@patternfly/react-icons/dist/dynamic/icons/exclamation-circle-icon'; import { ValidatedOptions } from '@patternfly/react-core/dist/esm/helpers/constants'; -import { KnowledgeFormData } from '..'; import { checkKnowledgeFormCompletion } from '../../validation'; import { Modal, ModalVariant } from '@patternfly/react-core/dist/esm/deprecated/components/Modal/Modal'; +import { KnowledgeFormData } from '@/types'; interface Props { reset: boolean; diff --git a/src/components/Contribute/Knowledge/Github/Submit/Submit.tsx b/src/components/Contribute/Knowledge/Github/Submit/Submit.tsx index d2ca4043..9d7416df 100644 --- a/src/components/Contribute/Knowledge/Github/Submit/Submit.tsx +++ b/src/components/Contribute/Knowledge/Github/Submit/Submit.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Button } from '@patternfly/react-core/dist/dynamic/components/Button'; -import { ActionGroupAlertContent, KnowledgeFormData } from '..'; -import { AttributionData, KnowledgeYamlData } from '@/types'; +import { ActionGroupAlertContent } from '..'; +import { AttributionData, KnowledgeFormData, KnowledgeYamlData } from '@/types'; import { KnowledgeSchemaVersion } from '@/types/const'; import { dumpYaml } from '@/utils/yamlConfig'; import { validateFields } from '../../validation'; diff --git a/src/components/Contribute/Knowledge/Github/index.tsx b/src/components/Contribute/Knowledge/Github/index.tsx index f15c4142..36cf3008 100644 --- a/src/components/Contribute/Knowledge/Github/index.tsx +++ b/src/components/Contribute/Knowledge/Github/index.tsx @@ -1,87 +1,39 @@ -// src/components/Contribute/Knowledge/index.tsx +// src/components/Experimental/ContributeLocal/Knowledge/index.tsx 'use client'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import '../knowledge.css'; import { Alert, AlertActionCloseButton } from '@patternfly/react-core/dist/dynamic/components/Alert'; import { ActionGroup } from '@patternfly/react-core/dist/dynamic/components/Form'; -import { Form } from '@patternfly/react-core/dist/dynamic/components/Form'; -import { getGitHubUsername } from '../../../../utils/github'; +import { getGitHubUsername } from '@/utils/github'; import { useSession } from 'next-auth/react'; -import AuthorInformation from '../../AuthorInformation'; -import { FormType } from '../../AuthorInformation'; -import KnowledgeInformation from '../KnowledgeInformation/KnowledgeInformation'; -import FilePathInformation from '../FilePathInformation/FilePathInformation'; -import DocumentInformation from './DocumentInformation/DocumentInformation'; -import AttributionInformation from '../AttributionInformation/AttributionInformation'; +import AuthorInformation from '@/components/Contribute/AuthorInformation'; +import { FormType } from '@/components/Contribute/AuthorInformation'; +import KnowledgeInformation from '@/components/Contribute/Knowledge/KnowledgeInformation/KnowledgeInformation'; +import FilePathInformation from '@/components/Contribute/Knowledge/FilePathInformation/FilePathInformation'; +import DocumentInformation from '@/components/Contribute/Knowledge/Github/DocumentInformation/DocumentInformation'; +import AttributionInformation from '@/components/Contribute/Knowledge/AttributionInformation/AttributionInformation'; import Submit from './Submit/Submit'; import { Breadcrumb } from '@patternfly/react-core/dist/dynamic/components/Breadcrumb'; import { BreadcrumbItem } from '@patternfly/react-core/dist/dynamic/components/Breadcrumb'; import { PageBreadcrumb } from '@patternfly/react-core/dist/dynamic/components/Page'; import { PageGroup } from '@patternfly/react-core/dist/dynamic/components/Page'; import { PageSection } from '@patternfly/react-core/dist/dynamic/components/Page'; -import { Content } from '@patternfly/react-core/dist/dynamic/components/Content'; import { Title } from '@patternfly/react-core/dist/dynamic/components/Title'; -import { Flex, FlexItem } from '@patternfly/react-core/dist/dynamic/layouts/Flex'; -import KnowledgeDescriptionContent from '../KnowledgeDescription/KnowledgeDescriptionContent'; -import KnowledgeSeedExample from '../KnowledgeSeedExample/KnowledgeSeedExample'; -import { checkKnowledgeFormCompletion } from '../validation'; +import KnowledgeDescriptionContent from '@/components/Contribute/Knowledge/KnowledgeDescription/KnowledgeDescriptionContent'; +import KnowledgeSeedExample from '@/components/Contribute/Knowledge/KnowledgeSeedExample/KnowledgeSeedExample'; +import { checkKnowledgeFormCompletion } from '@/components/Contribute/Knowledge/validation'; import { ValidatedOptions } from '@patternfly/react-core/dist/esm/helpers/constants'; -import { DownloadDropdown } from '../DownloadDropdown/DownloadDropdown'; -import { ViewDropdown } from '../ViewDropdown/ViewDropdown'; -import Update from './Update/Update'; -import { KnowledgeYamlData, PullRequestFile } from '@/types'; +import { DownloadDropdown } from '@/components/Contribute/Knowledge/DownloadDropdown/DownloadDropdown'; +import { ViewDropdown } from '@/components/Contribute/Knowledge/ViewDropdown/ViewDropdown'; +import Update from '@/components/Contribute/Knowledge/Github/Update/Update'; +import { KnowledgeEditFormData, KnowledgeFormData, QuestionAndAnswerPair } from '@/types'; import { Button } from '@patternfly/react-core/dist/esm/components/Button/Button'; import { useRouter } from 'next/navigation'; -import { autoFillKnowledgeFields } from '../AutoFill'; +import { autoFillKnowledgeFields } from '@/components/Contribute/Knowledge/AutoFill'; import { Spinner } from '@patternfly/react-core/dist/esm/components/Spinner'; -import { YamlFileUploadModal } from '../../YamlFileUploadModal'; - -export interface QuestionAndAnswerPair { - immutable: boolean; - question: string; - isQuestionValid: ValidatedOptions; - questionValidationError?: string; - answer: string; - isAnswerValid: ValidatedOptions; - answerValidationError?: string; -} - -export interface SeedExample { - immutable: boolean; - isExpanded: boolean; - context: string; - isContextValid: ValidatedOptions; - validationError?: string; - questionAndAnswers: QuestionAndAnswerPair[]; -} - -export interface KnowledgeFormData { - email: string; - name: string; - submissionSummary: string; - domain: string; - documentOutline: string; - filePath: string; - seedExamples: SeedExample[]; - knowledgeDocumentRepositoryUrl: string; - knowledgeDocumentCommit: string; - documentName: string; - titleWork: string; - linkWork: string; - revision: string; - licenseWork: string; - creators: string; -} - -export interface KnowledgeEditFormData { - isEditForm: boolean; - knowledgeVersion: number; - pullRequestNumber: number; - branchName: string; - yamlFile: PullRequestFile; - attributionFile: PullRequestFile; - knowledgeFormData: KnowledgeFormData; -} +import { Wizard, WizardStep } from '@patternfly/react-core/dist/esm/components/Wizard'; +import { Content } from '@patternfly/react-core/dist/dynamic/components/Content'; +import ReviewSubmission from '@/components/Contribute/Knowledge/ReviewSubmission'; export interface ActionGroupAlertContent { title: string; @@ -131,11 +83,11 @@ export const KnowledgeFormGithub: React.FunctionComponent = const [disableAction, setDisableAction] = useState(true); const [reset, setReset] = useState(false); - const [isModalOpen, setIsModalOpen] = React.useState(false); - const router = useRouter(); - const emptySeedExample: SeedExample = { + const [activeStepIndex] = useState(1); + + const emptySeedExample: KnowledgeSeedExample = { immutable: true, isExpanded: false, context: '', @@ -165,7 +117,7 @@ export const KnowledgeFormGithub: React.FunctionComponent = ] }; - const [seedExamples, setSeedExamples] = useState([ + const [seedExamples, setSeedExamples] = useState([ emptySeedExample, emptySeedExample, emptySeedExample, @@ -189,7 +141,7 @@ export const KnowledgeFormGithub: React.FunctionComponent = } }, [session?.user]); - useEffect(() => { + useMemo(() => { const fetchUsername = async () => { if (session?.accessToken) { try { @@ -237,7 +189,7 @@ export const KnowledgeFormGithub: React.FunctionComponent = const contextStr = context.trim(); if (contextStr.length == 0) { setDisableAction(true); - return { msg: 'Required field', status: ValidatedOptions.error }; + return { msg: 'Context is required', status: ValidatedOptions.error }; } const tokens = contextStr.split(/\s+/); if (tokens.length > 0 && tokens.length <= 500) { @@ -253,7 +205,7 @@ export const KnowledgeFormGithub: React.FunctionComponent = const questionStr = question.trim(); if (questionStr.length == 0) { setDisableAction(true); - return { msg: 'Required field', status: ValidatedOptions.error }; + return { msg: 'Question is required', status: ValidatedOptions.error }; } const tokens = questionStr.split(/\s+/); if (tokens.length > 0 && tokens.length < 250) { @@ -268,7 +220,7 @@ export const KnowledgeFormGithub: React.FunctionComponent = const answerStr = answer.trim(); if (answerStr.length == 0) { setDisableAction(true); - return { msg: 'Required field', status: ValidatedOptions.error }; + return { msg: 'Answer is required', status: ValidatedOptions.error }; } const tokens = answerStr.split(/\s+/); if (tokens.length > 0 && tokens.length < 250) { @@ -281,7 +233,7 @@ export const KnowledgeFormGithub: React.FunctionComponent = const handleContextInputChange = (seedExampleIndex: number, contextValue: string): void => { setSeedExamples( - seedExamples.map((seedExample: SeedExample, index: number) => + seedExamples.map((seedExample: KnowledgeSeedExample, index: number) => index === seedExampleIndex ? { ...seedExample, @@ -293,7 +245,7 @@ export const KnowledgeFormGithub: React.FunctionComponent = }; const handleContextBlur = (seedExampleIndex: number): void => { - const updatedSeedExamples = seedExamples.map((seedExample: SeedExample, index: number): SeedExample => { + const updatedSeedExamples = seedExamples.map((seedExample: KnowledgeSeedExample, index: number): KnowledgeSeedExample => { if (index === seedExampleIndex) { const { msg, status } = validateContext(seedExample.context); return { @@ -309,7 +261,7 @@ export const KnowledgeFormGithub: React.FunctionComponent = const handleQuestionInputChange = (seedExampleIndex: number, questionAndAnswerIndex: number, questionValue: string): void => { setSeedExamples( - seedExamples.map((seedExample: SeedExample, index: number) => + seedExamples.map((seedExample: KnowledgeSeedExample, index: number) => index === seedExampleIndex ? { ...seedExample, @@ -329,7 +281,7 @@ export const KnowledgeFormGithub: React.FunctionComponent = const handleQuestionBlur = (seedExampleIndex: number, questionAndAnswerIndex: number): void => { setSeedExamples( - seedExamples.map((seedExample: SeedExample, index: number) => + seedExamples.map((seedExample: KnowledgeSeedExample, index: number) => index === seedExampleIndex ? { ...seedExample, @@ -352,7 +304,7 @@ export const KnowledgeFormGithub: React.FunctionComponent = const handleAnswerInputChange = (seedExampleIndex: number, questionAndAnswerIndex: number, answerValue: string): void => { setSeedExamples( - seedExamples.map((seedExample: SeedExample, index: number) => + seedExamples.map((seedExample: KnowledgeSeedExample, index: number) => index === seedExampleIndex ? { ...seedExample, @@ -372,7 +324,7 @@ export const KnowledgeFormGithub: React.FunctionComponent = const handleAnswerBlur = (seedExampleIndex: number, questionAndAnswerIndex: number): void => { setSeedExamples( - seedExamples.map((seedExample: SeedExample, index: number) => + seedExamples.map((seedExample: KnowledgeSeedExample, index: number) => index === seedExampleIndex ? { ...seedExample, @@ -393,6 +345,14 @@ export const KnowledgeFormGithub: React.FunctionComponent = ); }; + // const toggleSeedExampleExpansion = (index: number): void => { + // setSeedExamples(seedExamples.map((seedExample, idx) => (idx === index ? { ...seedExample, isExpanded: !seedExample.isExpanded } : seedExample))); + // }; + + const toggleSeedExampleExpansion = (index: number): void => { + setSeedExamples(seedExamples.map((seedExample, idx) => (idx === index ? { ...seedExample, isExpanded: !seedExample.isExpanded } : seedExample))); + }; + const onCloseActionGroupAlert = () => { setActionGroupAlertContent(undefined); }; @@ -436,32 +396,6 @@ export const KnowledgeFormGithub: React.FunctionComponent = setSeedExamples(autoFillKnowledgeFields.seedExamples); }; - const yamlSeedExampleToFormSeedExample = ( - yamlSeedExamples: { context: string; questions_and_answers: { question: string; answer: string }[] }[] - ) => { - return yamlSeedExamples.map((yamlSeedExample) => ({ - immutable: true, - isExpanded: false, - context: yamlSeedExample.context ?? '', - isContextValid: ValidatedOptions.default, - questionAndAnswers: yamlSeedExample.questions_and_answers.map((questionAndAnswer) => ({ - question: questionAndAnswer.question ?? '', - answer: questionAndAnswer.answer ?? '' - })) - })) as SeedExample[]; - }; - - const onYamlUploadKnowledgeFillForm = (data: KnowledgeYamlData): void => { - setName(data.created_by ?? ''); - setDocumentOutline(data.document_outline ?? ''); - setSubmissionSummary(data.document_outline ?? ''); - setDomain(data.domain ?? ''); - setKnowledgeDocumentRepositoryUrl(data.document.repo ?? ''); - setKnowledgeDocumentCommit(data.document.commit ?? ''); - setDocumentName(data.document.patterns.join(', ') ?? ''); - setSeedExamples(yamlSeedExampleToFormSeedExample(data.seed_examples)); - }; - const knowledgeFormData: KnowledgeFormData = { email: email, name: name, @@ -488,29 +422,131 @@ export const KnowledgeFormGithub: React.FunctionComponent = router.push('/dashboard'); }; + const steps = [ + { + id: 'author-info', + name: 'Author Information', + component: ( + + ) + }, + { + id: 'knowledge-info', + name: 'Knowledge Information', + component: ( + + ) + }, + { + id: 'file-path-info', + name: 'File Path Information', + component: ( + + ) + }, + { + id: 'seed-examples', + name: 'Seed Examples', + component: ( + + ) + }, + { + id: 'document-info', + name: 'Document Information', + component: ( + + ) + }, + { + id: 'attribution-info', + name: 'Attribution Information', + component: ( + + ) + }, + { + id: 'review-submission', + name: 'Review Submission', + component: , + footer: { + isNextDisabled: true + } + } + ]; + return ( - + Dashboard Knowledge Contribution - - - - - Knowledge Contribution - - - - - - - + + + Knowledge Contribution + @@ -520,136 +556,65 @@ export const KnowledgeFormGithub: React.FunctionComponent = )} - + + {steps.map((step) => ( + + {step.component} + + ))} + + + {actionGroupAlertContent && ( + } + > +

+ {actionGroupAlertContent.waitAlert && } + {actionGroupAlertContent.message} +
+ {!actionGroupAlertContent.waitAlert && + actionGroupAlertContent.success && + actionGroupAlertContent.url && + actionGroupAlertContent.url.trim().length > 0 && ( + + View your new branch + + )} +

+
+ )} -
- - - - - - - - - - - - - {actionGroupAlertContent && ( - } - > -

- {actionGroupAlertContent.waitAlert && } - {actionGroupAlertContent.message} -
- {!actionGroupAlertContent.waitAlert && - actionGroupAlertContent.success && - actionGroupAlertContent.url && - actionGroupAlertContent.url.trim().length > 0 && ( - - View your pull request - - )} -

-
+ + {knowledgeEditFormData?.isEditForm && ( + )} - - - {knowledgeEditFormData?.isEditForm && ( - - )} - {!knowledgeEditFormData?.isEditForm && ( - - )} - - - - - + {!knowledgeEditFormData?.isEditForm && ( + + )} + + + +
); diff --git a/src/components/Contribute/Knowledge/KnowledgeInformation/KnowledgeInformation.tsx b/src/components/Contribute/Knowledge/KnowledgeInformation/KnowledgeInformation.tsx index 29ce1026..4dc0435c 100644 --- a/src/components/Contribute/Knowledge/KnowledgeInformation/KnowledgeInformation.tsx +++ b/src/components/Contribute/Knowledge/KnowledgeInformation/KnowledgeInformation.tsx @@ -6,8 +6,8 @@ import { HelperText } from '@patternfly/react-core/dist/dynamic/components/Helpe import { HelperTextItem } from '@patternfly/react-core/dist/dynamic/components/HelperText'; import ExclamationCircleIcon from '@patternfly/react-icons/dist/dynamic/icons/exclamation-circle-icon'; import { ValidatedOptions } from '@patternfly/react-core/dist/esm/helpers/constants'; -import { KnowledgeFormData } from '../Github'; import { checkKnowledgeFormCompletion } from '../validation'; +import { KnowledgeFormData } from '@/types'; interface Props { reset: boolean; diff --git a/src/components/Contribute/Knowledge/KnowledgeQuestionAnswerPairs/KnowledgeQuestionAnswerPairs.tsx b/src/components/Contribute/Knowledge/KnowledgeQuestionAnswerPairs/KnowledgeQuestionAnswerPairs.tsx index 314aa7e3..de6f1ecc 100644 --- a/src/components/Contribute/Knowledge/KnowledgeQuestionAnswerPairs/KnowledgeQuestionAnswerPairs.tsx +++ b/src/components/Contribute/Knowledge/KnowledgeQuestionAnswerPairs/KnowledgeQuestionAnswerPairs.tsx @@ -2,13 +2,13 @@ import React from 'react'; import { FormFieldGroupHeader, FormGroup, FormHelperText } from '@patternfly/react-core/dist/dynamic/components/Form'; import { TextArea } from '@patternfly/react-core/dist/dynamic/components/TextArea'; import { ExclamationCircleIcon } from '@patternfly/react-icons/dist/dynamic/icons/'; -import { QuestionAndAnswerPair, SeedExample } from '../Github'; +import { QuestionAndAnswerPair, KnowledgeSeedExample } from '../Github'; import { ValidatedOptions } from '@patternfly/react-core/dist/esm/helpers/constants'; import { HelperText } from '@patternfly/react-core/dist/dynamic/components/HelperText'; import { HelperTextItem } from '@patternfly/react-core/dist/dynamic/components/HelperText'; interface Props { - seedExample: SeedExample; + seedExample: KnowledgeSeedExample; seedExampleIndex: number; handleContextInputChange: (seedExampleIndex: number, contextValue: string) => void; handleContextBlur: (seedExampleIndex: number) => void; diff --git a/src/components/Contribute/Knowledge/KnowledgeSeedExample/KnowledgeSeedExample.tsx b/src/components/Contribute/Knowledge/KnowledgeSeedExample/KnowledgeSeedExample.tsx index e68bc503..5f659f83 100644 --- a/src/components/Contribute/Knowledge/KnowledgeSeedExample/KnowledgeSeedExample.tsx +++ b/src/components/Contribute/Knowledge/KnowledgeSeedExample/KnowledgeSeedExample.tsx @@ -3,11 +3,11 @@ import React from 'react'; import { Accordion, AccordionItem, AccordionContent, AccordionToggle } from '@patternfly/react-core/dist/dynamic/components/Accordion'; import { FormFieldGroupHeader } from '@patternfly/react-core/dist/dynamic/components/Form'; import KnowledgeQuestionAnswerPairs from '../KnowledgeQuestionAnswerPairs/KnowledgeQuestionAnswerPairs'; -import { SeedExample } from '../Github'; +import { KnowledgeSeedExample } from '@/types'; import ExternalLinkAltIcon from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon'; interface Props { - seedExamples: SeedExample[]; + seedExamples: KnowledgeSeedExample[]; handleContextInputChange: (seedExampleIndex: number, contextValue: string) => void; handleContextBlur: (seedExampleIndex: number) => void; handleQuestionInputChange: (seedExampleIndex: number, questionAndAnswerIndex: number, questionValue: string) => void; @@ -51,7 +51,7 @@ const KnowledgeSeedExample: React.FC = ({ /> - {seedExamples.map((seedExample: SeedExample, seedExampleIndex: number) => ( + {seedExamples.map((seedExample: KnowledgeSeedExample, seedExampleIndex: number) => ( toggleSeedExampleExpansion(seedExampleIndex)} id={`seed-example-toggle-${seedExampleIndex}`}> Seed Example {seedExampleIndex + 1} {seedExample.immutable && *} diff --git a/src/components/Contribute/Knowledge/Native/DocumentInformation/DocumentInformation.tsx b/src/components/Contribute/Knowledge/Native/DocumentInformation/DocumentInformation.tsx index a0511345..63f043c6 100644 --- a/src/components/Contribute/Knowledge/Native/DocumentInformation/DocumentInformation.tsx +++ b/src/components/Contribute/Knowledge/Native/DocumentInformation/DocumentInformation.tsx @@ -7,10 +7,10 @@ import { HelperText } from '@patternfly/react-core/dist/dynamic/components/Helpe import { HelperTextItem } from '@patternfly/react-core/dist/dynamic/components/HelperText'; import ExclamationCircleIcon from '@patternfly/react-icons/dist/dynamic/icons/exclamation-circle-icon'; import { ValidatedOptions } from '@patternfly/react-core/dist/esm/helpers/constants'; -import { KnowledgeFormData } from '..'; import { Modal, ModalVariant } from '@patternfly/react-core/dist/esm/deprecated/components/Modal/Modal'; import { UploadFile } from '@/components/Contribute/Knowledge/UploadFile'; import { checkKnowledgeFormCompletion } from '@/components/Contribute/Knowledge/validation'; +import { KnowledgeFormData } from '@/types'; interface Props { reset: boolean; diff --git a/src/components/Contribute/Knowledge/Native/Submit/Submit.tsx b/src/components/Contribute/Knowledge/Native/Submit/Submit.tsx index 059053bb..13255701 100644 --- a/src/components/Contribute/Knowledge/Native/Submit/Submit.tsx +++ b/src/components/Contribute/Knowledge/Native/Submit/Submit.tsx @@ -1,8 +1,8 @@ // src/components/contribute/native/Knowledge/Submit/Submit.tsx import React from 'react'; import { Button } from '@patternfly/react-core/dist/dynamic/components/Button'; -import { ActionGroupAlertContent, KnowledgeFormData } from '..'; -import { AttributionData, KnowledgeYamlData } from '@/types'; +import { ActionGroupAlertContent } from '..'; +import { AttributionData, KnowledgeFormData, KnowledgeYamlData } from '@/types'; import { KnowledgeSchemaVersion } from '@/types/const'; import { dumpYaml } from '@/utils/yamlConfig'; import { validateFields } from '@/components/Contribute/Knowledge/validation'; diff --git a/src/components/Contribute/Knowledge/Native/index.tsx b/src/components/Contribute/Knowledge/Native/index.tsx index 57668733..5c8b7f0e 100644 --- a/src/components/Contribute/Knowledge/Native/index.tsx +++ b/src/components/Contribute/Knowledge/Native/index.tsx @@ -26,61 +26,14 @@ import { ValidatedOptions } from '@patternfly/react-core/dist/esm/helpers/consta import { DownloadDropdown } from '@/components/Contribute/Knowledge/DownloadDropdown/DownloadDropdown'; import { ViewDropdown } from '@/components/Contribute/Knowledge/ViewDropdown/ViewDropdown'; import Update from '@/components/Contribute/Knowledge/Github/Update/Update'; -import { PullRequestFile } from '@/types'; +import { KnowledgeEditFormData, KnowledgeFormData, QuestionAndAnswerPair } from '@/types'; import { Button } from '@patternfly/react-core/dist/esm/components/Button/Button'; import { useRouter } from 'next/navigation'; import { autoFillKnowledgeFields } from '@/components/Contribute/Knowledge/AutoFill'; import { Spinner } from '@patternfly/react-core/dist/esm/components/Spinner'; import { Wizard, WizardStep } from '@patternfly/react-core/dist/esm/components/Wizard'; import { Content } from '@patternfly/react-core/dist/dynamic/components/Content'; -import ReviewSubmission from '@/components/Contribute/Knowledge/Native/ReviewSubmission'; - -export interface QuestionAndAnswerPair { - immutable: boolean; - question: string; - isQuestionValid: ValidatedOptions; - questionValidationError?: string; - answer: string; - isAnswerValid: ValidatedOptions; - answerValidationError?: string; -} - -export interface SeedExample { - immutable: boolean; - isExpanded: boolean; - context: string; - isContextValid: ValidatedOptions; - validationError?: string; - questionAndAnswers: QuestionAndAnswerPair[]; -} - -export interface KnowledgeFormData { - email: string; - name: string; - submissionSummary: string; - domain: string; - documentOutline: string; - filePath: string; - seedExamples: SeedExample[]; - knowledgeDocumentRepositoryUrl: string; - knowledgeDocumentCommit: string; - documentName: string; - titleWork: string; - linkWork: string; - revision: string; - licenseWork: string; - creators: string; -} - -export interface KnowledgeEditFormData { - isEditForm: boolean; - knowledgeVersion: number; - pullRequestNumber: number; - branchName: string; - yamlFile: PullRequestFile; - attributionFile: PullRequestFile; - knowledgeFormData: KnowledgeFormData; -} +import ReviewSubmission from '../ReviewSubmission'; export interface ActionGroupAlertContent { title: string; @@ -134,7 +87,7 @@ export const KnowledgeFormNative: React.FunctionComponent = const [activeStepIndex] = useState(1); - const emptySeedExample: SeedExample = { + const emptySeedExample: KnowledgeSeedExample = { immutable: true, isExpanded: false, context: '', @@ -164,7 +117,7 @@ export const KnowledgeFormNative: React.FunctionComponent = ] }; - const [seedExamples, setSeedExamples] = useState([ + const [seedExamples, setSeedExamples] = useState([ emptySeedExample, emptySeedExample, emptySeedExample, @@ -280,7 +233,7 @@ export const KnowledgeFormNative: React.FunctionComponent = const handleContextInputChange = (seedExampleIndex: number, contextValue: string): void => { setSeedExamples( - seedExamples.map((seedExample: SeedExample, index: number) => + seedExamples.map((seedExample: KnowledgeSeedExample, index: number) => index === seedExampleIndex ? { ...seedExample, @@ -292,7 +245,7 @@ export const KnowledgeFormNative: React.FunctionComponent = }; const handleContextBlur = (seedExampleIndex: number): void => { - const updatedSeedExamples = seedExamples.map((seedExample: SeedExample, index: number): SeedExample => { + const updatedSeedExamples = seedExamples.map((seedExample: KnowledgeSeedExample, index: number): KnowledgeSeedExample => { if (index === seedExampleIndex) { const { msg, status } = validateContext(seedExample.context); return { @@ -308,7 +261,7 @@ export const KnowledgeFormNative: React.FunctionComponent = const handleQuestionInputChange = (seedExampleIndex: number, questionAndAnswerIndex: number, questionValue: string): void => { setSeedExamples( - seedExamples.map((seedExample: SeedExample, index: number) => + seedExamples.map((seedExample: KnowledgeSeedExample, index: number) => index === seedExampleIndex ? { ...seedExample, @@ -328,7 +281,7 @@ export const KnowledgeFormNative: React.FunctionComponent = const handleQuestionBlur = (seedExampleIndex: number, questionAndAnswerIndex: number): void => { setSeedExamples( - seedExamples.map((seedExample: SeedExample, index: number) => + seedExamples.map((seedExample: KnowledgeSeedExample, index: number) => index === seedExampleIndex ? { ...seedExample, @@ -351,7 +304,7 @@ export const KnowledgeFormNative: React.FunctionComponent = const handleAnswerInputChange = (seedExampleIndex: number, questionAndAnswerIndex: number, answerValue: string): void => { setSeedExamples( - seedExamples.map((seedExample: SeedExample, index: number) => + seedExamples.map((seedExample: KnowledgeSeedExample, index: number) => index === seedExampleIndex ? { ...seedExample, @@ -371,7 +324,7 @@ export const KnowledgeFormNative: React.FunctionComponent = const handleAnswerBlur = (seedExampleIndex: number, questionAndAnswerIndex: number): void => { setSeedExamples( - seedExamples.map((seedExample: SeedExample, index: number) => + seedExamples.map((seedExample: KnowledgeSeedExample, index: number) => index === seedExampleIndex ? { ...seedExample, diff --git a/src/components/Contribute/Knowledge/Native/ReviewSubmission/index.tsx b/src/components/Contribute/Knowledge/ReviewSubmission/index.tsx similarity index 97% rename from src/components/Contribute/Knowledge/Native/ReviewSubmission/index.tsx rename to src/components/Contribute/Knowledge/ReviewSubmission/index.tsx index e9f4d30c..3e39715c 100644 --- a/src/components/Contribute/Knowledge/Native/ReviewSubmission/index.tsx +++ b/src/components/Contribute/Knowledge/ReviewSubmission/index.tsx @@ -1,6 +1,6 @@ // src/components/Contribute/Knowledge/ReviewSubmission/ReviewSubmission.tsx +import { KnowledgeFormData } from '@/types'; import React from 'react'; -import { KnowledgeFormData } from '@/components/Contribute/Knowledge/Native'; interface ReviewSubmissionProps { knowledgeFormData: KnowledgeFormData; diff --git a/src/components/Contribute/Knowledge/validation.tsx b/src/components/Contribute/Knowledge/validation.tsx index 2e40c9ad..54d10d2c 100644 --- a/src/components/Contribute/Knowledge/validation.tsx +++ b/src/components/Contribute/Knowledge/validation.tsx @@ -1,12 +1,13 @@ +import { KnowledgeFormData, KnowledgeSeedExample } from '@/types'; import { ValidatedOptions } from '@patternfly/react-core/dist/esm/helpers/constants'; -import { ActionGroupAlertContent, KnowledgeFormData, SeedExample } from './Github'; +import { ActionGroupAlertContent } from './Github'; const validateEmail = (email: string): boolean => { const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/; return emailRegex.test(email); }; -const hasDuplicateSeedExamples = (seedExamples: SeedExample[]): { duplicate: boolean; index: number } => { +const hasDuplicateSeedExamples = (seedExamples: KnowledgeSeedExample[]): { duplicate: boolean; index: number } => { const contexts = new Set(); for (let index = 0; index < seedExamples.length; index++) { const seedExample = seedExamples[index]; @@ -20,7 +21,7 @@ const hasDuplicateSeedExamples = (seedExamples: SeedExample[]): { duplicate: boo }; // Check if the question in Q&A pairs in a each seed example are unique -const hasDuplicateQuestionAndAnswerPairs = (seedExample: SeedExample): { duplicate: boolean; index: number } => { +const hasDuplicateQuestionAndAnswerPairs = (seedExample: KnowledgeSeedExample): { duplicate: boolean; index: number } => { const questions = new Set(); for (let index = 0; index < seedExample.questionAndAnswers.length; index++) { const questionAndAnswerPair = seedExample.questionAndAnswers[index]; @@ -36,7 +37,7 @@ const hasDuplicateQuestionAndAnswerPairs = (seedExample: SeedExample): { duplica // Validate that the total length of all the question and answer pairs // and context in a seed example is not more than 750 characters. -const validateQuestionAndAnswerPairs = (seedExample: SeedExample): { success: boolean; currLength: number } => { +const validateQuestionAndAnswerPairs = (seedExample: KnowledgeSeedExample): { success: boolean; currLength: number } => { const totalQnAPairsTokenCount = seedExample.questionAndAnswers.reduce((acc, questionAndAnswerPair) => { const questionTokens = questionAndAnswerPair.question.trim().split(/\s+/); const answerTokens = questionAndAnswerPair.answer.trim().split(/\s+/); diff --git a/src/types/index.ts b/src/types/index.ts index 2f8de3ed..a1f0ead9 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -107,3 +107,50 @@ export interface SkillFormData { licenseWork: string; creators: string; } + +export interface QuestionAndAnswerPair { + immutable: boolean; + question: string; + isQuestionValid: ValidatedOptions; + questionValidationError?: string; + answer: string; + isAnswerValid: ValidatedOptions; + answerValidationError?: string; +} + +export interface KnowledgeSeedExample { + immutable: boolean; + isExpanded: boolean; + context: string; + isContextValid: ValidatedOptions; + validationError?: string; + questionAndAnswers: QuestionAndAnswerPair[]; +} + +export interface KnowledgeFormData { + email: string; + name: string; + submissionSummary: string; + domain: string; + documentOutline: string; + filePath: string; + seedExamples: KnowledgeSeedExample[]; + knowledgeDocumentRepositoryUrl: string; + knowledgeDocumentCommit: string; + documentName: string; + titleWork: string; + linkWork: string; + revision: string; + licenseWork: string; + creators: string; +} + +export interface KnowledgeEditFormData { + isEditForm: boolean; + knowledgeVersion: number; + pullRequestNumber: number; + branchName: string; + yamlFile: PullRequestFile; + attributionFile: PullRequestFile; + knowledgeFormData: KnowledgeFormData; +}