Skip to content

Commit

Permalink
Fix knowledge edit feature
Browse files Browse the repository at this point in the history
Use the same knowledge form for edit, that it uses
for submitting new knowledge. That way, we don't
have to maintain two version of form for submit and
edit.

Signed-off-by: Anil Vishnoi <[email protected]>
  • Loading branch information
vishnoianil committed Sep 3, 2024
1 parent d4ab33b commit 3172e87
Show file tree
Hide file tree
Showing 10 changed files with 386 additions and 629 deletions.
1 change: 0 additions & 1 deletion src/app/api/pr/knowledge/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const BASE_BRANCH = 'main';

export async function POST(req: NextRequest) {
const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET! });
console.log('GitHub Token:', token);

if (!token || !token.accessToken) {
console.error('Unauthorized: Missing or invalid access token');
Expand Down
706 changes: 108 additions & 598 deletions src/app/edit-submission/knowledge/[id]/page.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { checkKnowledgeFormCompletion } from '../validation';

interface Props {
reset: boolean;
isEditForm?: boolean;
knowledgeFormData: KnowledgeFormData;
setDisableAction: React.Dispatch<React.SetStateAction<boolean>>;
titleWork: string;
Expand All @@ -26,6 +27,7 @@ interface Props {

const AttributionInformation: React.FC<Props> = ({
reset,
isEditForm,
knowledgeFormData,
setDisableAction,
titleWork,
Expand Down Expand Up @@ -53,6 +55,17 @@ const AttributionInformation: React.FC<Props> = ({
setValidCreators(ValidatedOptions.default);
}, [reset]);

useEffect(() => {
if (!isEditForm) {
return;
}
setValidTitle(ValidatedOptions.success);
setValidLink(ValidatedOptions.success);
setValidRevision(ValidatedOptions.success);
setValidLicense(ValidatedOptions.success);
setValidCreators(ValidatedOptions.success);
}, [isEditForm]);

const validateTitle = (title: string) => {
if (title.length > 0) {
setValidTitle(ValidatedOptions.success);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Modal, ModalVariant } from '@patternfly/react-core/dist/esm/components/

interface Props {
reset: boolean;
isEditForm?: boolean;
knowledgeFormData: KnowledgeFormData;
setDisableAction: React.Dispatch<React.SetStateAction<boolean>>;
knowledgeDocumentRepositoryUrl: string;
Expand All @@ -26,6 +27,7 @@ interface Props {

const DocumentInformation: React.FC<Props> = ({
reset,
isEditForm,
knowledgeFormData,
setDisableAction,
knowledgeDocumentRepositoryUrl,
Expand Down Expand Up @@ -57,6 +59,14 @@ const DocumentInformation: React.FC<Props> = ({
setValidDocumentName(ValidatedOptions.default);
}, [reset]);

useEffect(() => {
if (isEditForm) {
setValidRepo(ValidatedOptions.success);
setValidCommit(ValidatedOptions.success);
setValidDocumentName(ValidatedOptions.success);
}
}, [isEditForm]);

const validateRepo = (repo: string) => {
if (repo.length === 0) {
setDisableAction(true);
Expand Down Expand Up @@ -163,7 +173,6 @@ const DocumentInformation: React.FC<Props> = ({

const handleAutomaticUpload = () => {
if (knowledgeDocumentRepositoryUrl.length > 0 || knowledgeDocumentCommit.length > 0 || documentName.length > 0) {
console.log('Switching to automatic upload will clear the document information');
setModalText('Switching to automatic upload will clear the document information. Are you sure you want to continue?');
setIsModalOpen(true);
} else {
Expand All @@ -173,7 +182,6 @@ const DocumentInformation: React.FC<Props> = ({

const handleManualUpload = () => {
if (uploadedFiles.length > 0) {
console.log('Switching to manual upload will clear the uploaded files');
setModalText('Switching to manual upload will clear the uploaded files. Are you sure you want to continue?');
setIsModalOpen(true);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import PathService from '@/components/PathService/PathService';

interface Props {
reset?: boolean;
path: string;
setFilePath: React.Dispatch<React.SetStateAction<string>>;
}

const FilePathInformation: React.FC<Props> = ({ reset, setFilePath }) => {
const FilePathInformation: React.FC<Props> = ({ reset, path, setFilePath }) => {
return (
<FormFieldGroupExpandable
isExpanded
Expand All @@ -27,7 +28,7 @@ const FilePathInformation: React.FC<Props> = ({ reset, setFilePath }) => {
}
>
<FormGroup isRequired key={'file-path-service-id'}>
<PathService reset={reset} rootPath="knowledge" handlePathChange={setFilePath} />
<PathService reset={reset} rootPath="knowledge" path={path} handlePathChange={setFilePath} />
</FormGroup>
</FormFieldGroupExpandable>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { checkKnowledgeFormCompletion } from '../validation';

interface Props {
reset: boolean;
isEditForm?: boolean;
knowledgeFormData: KnowledgeFormData;
setDisableAction: React.Dispatch<React.SetStateAction<boolean>>;
submissionSummary: string;
Expand All @@ -23,6 +24,7 @@ interface Props {

const KnowledgeInformation: React.FC<Props> = ({
reset,
isEditForm,
knowledgeFormData,
setDisableAction,
submissionSummary,
Expand All @@ -42,6 +44,14 @@ const KnowledgeInformation: React.FC<Props> = ({
setValidOutline(ValidatedOptions.default);
}, [reset]);

useEffect(() => {
if (isEditForm) {
setValidDescription(ValidatedOptions.success);
setValidDomain(ValidatedOptions.success);
setValidOutline(ValidatedOptions.success);
}
}, [isEditForm]);

const validateDescription = (description: string) => {
if (description.length > 0 && description.length < 60) {
setValidDescription(ValidatedOptions.success);
Expand Down
150 changes: 150 additions & 0 deletions src/components/Contribute/Knowledge/Update/Update.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import React from 'react';
import { Button } from '@patternfly/react-core/dist/dynamic/components/Button';
import { ActionGroupAlertContent, KnowledgeFormData } from '..';
import { AttributionData, KnowledgeYamlData, PullRequestFile, SchemaVersion } from '@/types';
import { dumpYaml } from '@/utils/yamlConfig';
import { validateFields } from '../validation';
import { amendCommit, getGitHubUsername, updatePullRequest } from '@/utils/github';
import { useSession } from 'next-auth/react';
import { useRouter } from 'next/navigation';

const KNOWLEDGE_DIR = 'knowledge/';
interface Props {
disableAction: boolean;
knowledgeFormData: KnowledgeFormData;
pullRequestNumber: number;
yamlFile: PullRequestFile;
attributionFile: PullRequestFile;
branchName: string;
setActionGroupAlertContent: React.Dispatch<React.SetStateAction<ActionGroupAlertContent | undefined>>;
}

const Update: React.FC<Props> = ({
disableAction,
knowledgeFormData,
pullRequestNumber,
yamlFile,
attributionFile,
branchName,
setActionGroupAlertContent
}) => {
const { data: session } = useSession();
const router = useRouter();

const handleUpdate = async (event: React.FormEvent<HTMLButtonElement>) => {
event.preventDefault();
if (!validateFields(knowledgeFormData, setActionGroupAlertContent)) return;
if (session?.accessToken) {
try {
console.log(`Updating PR with number: ${pullRequestNumber}`);
await updatePullRequest(session.accessToken, pullRequestNumber, {
title: knowledgeFormData.submissionSummary,
body: knowledgeFormData.documentOutline
});

const githubUsername = await getGitHubUsername(session.accessToken);
console.log(`GitHub username: ${githubUsername}`);

const knowledgeYamlData: KnowledgeYamlData = {
created_by: githubUsername!,
version: SchemaVersion,
domain: knowledgeFormData.domain!,
document_outline: knowledgeFormData.documentOutline!,
seed_examples: knowledgeFormData.seedExamples.map((example) => ({
context: example.context,
questions_and_answers: example.questionAndAnswers.map((questionAndAnswer) => ({
question: questionAndAnswer.question,
answer: questionAndAnswer.answer
}))
})),
document: {
repo: knowledgeFormData.knowledgeDocumentRepositoryUrl!,
commit: knowledgeFormData.knowledgeDocumentCommit!,
patterns: knowledgeFormData.documentName!.split(',').map((pattern) => pattern.trim())
}
};

const yamlString = dumpYaml(knowledgeYamlData);
console.log('Updated YAML content:', yamlString);

const attributionData: AttributionData = {
title_of_work: knowledgeFormData.titleWork!,
link_to_work: knowledgeFormData.linkWork!,
revision: knowledgeFormData.revision!,
license_of_the_work: knowledgeFormData.licenseWork!,
creator_names: knowledgeFormData.creators!
};
const attributionContent = `Title of work: ${attributionData.title_of_work}
Link to work: ${attributionData.link_to_work}
Revision: ${attributionData.revision}
License of the work: ${attributionData.license_of_the_work}
Creator names: ${attributionData.creator_names}
`;

console.log('Updated Attribution content:', attributionData);

const commitMessage = `Amend commit with updated content\n\nSigned-off-by: ${knowledgeFormData.name} <${knowledgeFormData.email}>`;

// Ensure proper file paths for the edit
const finalYamlPath = KNOWLEDGE_DIR + knowledgeFormData.filePath.replace(/^\//, '').replace(/\/?$/, '/') + yamlFile.filename.split('/').pop();
const finalAttributionPath =
KNOWLEDGE_DIR + knowledgeFormData.filePath.replace(/^\//, '').replace(/\/?$/, '/') + attributionFile.filename.split('/').pop();
console.log('finalYamlPath:', finalYamlPath);

const origFilePath = yamlFile.filename.split('/').slice(0, -1).join('/');
const oldFilePath = {
yaml: origFilePath.replace(/^\//, '').replace(/\/?$/, '/') + yamlFile.filename.split('/').pop(),
attribution: origFilePath.replace(/^\//, '').replace(/\/?$/, '/') + attributionFile.filename.split('/').pop()
};

const newFilePath = {
yaml: finalYamlPath,
attribution: finalAttributionPath
};

const res = await fetch('/api/envConfig');
const envConfig = await res.json();

const amendedCommitResponse = await amendCommit(
session.accessToken,
githubUsername,
envConfig.UPSTREAM_REPO_NAME,
oldFilePath,
newFilePath,
yamlString,
attributionContent,
branchName,
commitMessage
);
console.log('Amended commit response:', amendedCommitResponse);

const prLink = `https://github.com/${envConfig.UPSTREAM_REPO_OWNER}/${envConfig.UPSTREAM_REPO_NAME}/pull/${pullRequestNumber}`;
const actionGroupAlertContent: ActionGroupAlertContent = {
title: 'Knowledge contribution updated successfully!',
message: `Thank you for your contribution!`,
url: `${prLink}`,
success: true
};
setActionGroupAlertContent(actionGroupAlertContent);
// Knowledge is updated, wait for a bit and let's go back to dashboard.
await new Promise((r) => setTimeout(r, 4000));
router.push('/dashboard');
} catch (error) {
console.error('Error updating PR:', error);
const actionGroupAlertContent: ActionGroupAlertContent = {
title: `Failed to update PR with number: ${pullRequestNumber}`,
message: `PR update failed because of ${error}`,
success: false
};
setActionGroupAlertContent(actionGroupAlertContent);
}
}
};
return (
<Button variant="primary" type="submit" isDisabled={disableAction} onClick={handleUpdate}>
Update Knowledge
</Button>
);
};

export default Update;
Loading

0 comments on commit 3172e87

Please sign in to comment.