diff --git a/src/app/api/native/git/branches/route.ts b/src/app/api/native/git/branches/route.ts
index d79fa18d..088a7191 100644
--- a/src/app/api/native/git/branches/route.ts
+++ b/src/app/api/native/git/branches/route.ts
@@ -6,6 +6,8 @@ import path from 'path';
// Get the repository path from the environment variable
const LOCAL_TAXONOMY_ROOT_DIR = process.env.NEXT_PUBLIC_LOCAL_TAXONOMY_ROOT_DIR || `${process.env.HOME}/.instructlab-ui`;
+const REMOTE_TAXONOMY_REPO_DIR = process.env.NEXT_PUBLIC_TAXONOMY_REPO_DIR || '';
+const REMOTE_TAXONOMY_REPO_CONTAINER_MOUNT_DIR = process.env.NEXT_PUBLIC_TAXONOMY_REPO_CONTAINER_MOUNT_DIR || '/tmp/.instructlab-ui/taxonomy';
interface Diffs {
file: string;
@@ -28,15 +30,23 @@ export async function GET() {
const branchCommit = await git.resolveRef({ fs, dir: REPO_DIR, ref: branch });
const commitDetails = await git.readCommit({ fs, dir: REPO_DIR, oid: branchCommit });
+ const commitMessage = commitDetails.commit.message;
+
+ // Check for Signed-off-by line
+ const signoffMatch = commitMessage.match(/^Signed-off-by: (.+)$/m);
+ const signoff = signoffMatch ? signoffMatch[1] : null;
+ const messageStr = commitMessage.split('Signed-off-by');
branchDetails.push({
name: branch,
- creationDate: commitDetails.commit.committer.timestamp * 1000 // Convert to milliseconds
+ creationDate: commitDetails.commit.committer.timestamp * 1000, // Convert to milliseconds
+ message: messageStr[0].replace(/\n+$/, ''),
+ author: signoff
});
}
branchDetails.sort((a, b) => b.creationDate - a.creationDate); // Sort by creation date, newest first
- console.log('Branches present in native taxonomy:', branchDetails);
+ console.log('Total branches present in native taxonomy:', branchDetails.length);
return NextResponse.json({ branches: branchDetails }, { status: 200 });
} catch (error) {
console.error('Failed to list branches:', error);
@@ -47,8 +57,8 @@ export async function GET() {
// Handle POST requests for merge or branch comparison
export async function POST(req: NextRequest) {
const LOCAL_TAXONOMY_DIR = path.join(LOCAL_TAXONOMY_ROOT_DIR, '/taxonomy');
- const { branchName, action, remoteTaxonomyRepoDir } = await req.json();
- console.log('Received POST request:', { branchName, action, remoteTaxonomyRepoDir });
+ const { branchName, action } = await req.json();
+ console.log('Received POST request:', { branchName, action });
if (action === 'delete') {
return handleDelete(branchName, LOCAL_TAXONOMY_DIR);
@@ -59,6 +69,21 @@ export async function POST(req: NextRequest) {
}
if (action === 'publish') {
+ let remoteTaxonomyRepoDir: string = '';
+ // Check if directory pointed by remoteTaxonomyRepoDir exists and not empty
+ if (fs.existsSync(REMOTE_TAXONOMY_REPO_CONTAINER_MOUNT_DIR) && fs.readdirSync(REMOTE_TAXONOMY_REPO_CONTAINER_MOUNT_DIR).length !== 0) {
+ remoteTaxonomyRepoDir = REMOTE_TAXONOMY_REPO_CONTAINER_MOUNT_DIR;
+ } else {
+ if (fs.existsSync(REMOTE_TAXONOMY_REPO_DIR) && fs.readdirSync(REMOTE_TAXONOMY_REPO_DIR).length !== 0) {
+ remoteTaxonomyRepoDir = REMOTE_TAXONOMY_REPO_DIR;
+ }
+ }
+ if (remoteTaxonomyRepoDir === '') {
+ return NextResponse.json({ error: 'Remote taxonomy repository path does not exist.' }, { status: 400 });
+ }
+
+ console.log('Remote taxonomy repository path:', remoteTaxonomyRepoDir);
+
return handlePublish(branchName, LOCAL_TAXONOMY_DIR, remoteTaxonomyRepoDir);
}
return NextResponse.json({ error: 'Invalid action specified' }, { status: 400 });
@@ -73,7 +98,7 @@ async function handleDelete(branchName: string, localTaxonomyDir: string) {
// Delete the target branch
await git.deleteBranch({ fs, dir: localTaxonomyDir, ref: branchName });
- return NextResponse.json({ message: `Successfully deleted branch ${branchName}.` }, { status: 200 });
+ return NextResponse.json({ message: `Successfully deleted contribution ${branchName}.` }, { status: 200 });
} catch (error) {
console.error(`Failed to delete contribution ${branchName}:`, error);
return NextResponse.json(
@@ -182,7 +207,7 @@ async function getTopCommitDetails(dir: string, ref: string = 'HEAD') {
async function handlePublish(branchName: string, localTaxonomyDir: string, remoteTaxonomyDir: string) {
try {
if (!branchName || branchName === 'main') {
- return NextResponse.json({ error: 'Invalid branch name for publish' }, { status: 400 });
+ return NextResponse.json({ error: 'Invalid contribution name for publish' }, { status: 400 });
}
console.log(`Publishing contribution from ${branchName} to remote taxonomy repo at ${remoteTaxonomyDir}`);
@@ -244,9 +269,9 @@ async function handlePublish(branchName: string, localTaxonomyDir: string, remot
}
});
console.log(`Successfully published contribution from ${branchName} to remote taxonomy repo at ${remoteTaxonomyDir}`);
- return NextResponse.json({ message: `Successfully published contribution to ${remoteTaxonomyDir}.` }, { status: 200 });
+ return NextResponse.json({ message: `Successfully published contribution to ${REMOTE_TAXONOMY_REPO_DIR}.` }, { status: 200 });
} else {
- return NextResponse.json({ message: `No changes to publish from ${branchName}.` }, { status: 200 });
+ return NextResponse.json({ message: `No changes to publish from contribution ${branchName}.` }, { status: 200 });
}
} catch (error) {
console.error(`Failed to publish contribution from ${branchName}:`, error);
diff --git a/src/app/contribute/knowledge/page.tsx b/src/app/contribute/knowledge/page.tsx
index 19836b45..9caebe86 100644
--- a/src/app/contribute/knowledge/page.tsx
+++ b/src/app/contribute/knowledge/page.tsx
@@ -1,11 +1,23 @@
// src/app/contribute/knowledge/page.tsx
-import KnowledgeFormNative from '@/components/Contribute/Knowledge/Native';
-import * as React from 'react';
-import { AppLayout } from '../../../components/AppLayout';
-import { KnowledgeFormGithub } from '../../../components/Contribute/Knowledge/Github';
+'use client';
+import { AppLayout } from '@/components/AppLayout';
+import { KnowledgeFormGithub } from '@/components/Contribute/Knowledge/Github/index';
+import KnowledgeFormNative from '@/components/Contribute/Knowledge/Native/index';
+import { useEffect, useState } from 'react';
-const KnowledgeFormPage: React.FC = () => {
- return {process.env.IL_UI_DEPLOYMENT === 'native' ? : };
+const KnowledgeFormPage: React.FunctionComponent = () => {
+ const [deploymentType, setDeploymentType] = useState();
+
+ useEffect(() => {
+ const getEnvVariables = async () => {
+ const res = await fetch('/api/envConfig');
+ const envConfig = await res.json();
+ setDeploymentType(envConfig.DEPLOYMENT_TYPE);
+ };
+ getEnvVariables();
+ }, []);
+
+ return {deploymentType === 'native' ? : };
};
export default KnowledgeFormPage;
diff --git a/src/app/contribute/skill/page.tsx b/src/app/contribute/skill/page.tsx
index 01f1d1cb..b4d31d35 100644
--- a/src/app/contribute/skill/page.tsx
+++ b/src/app/contribute/skill/page.tsx
@@ -1,11 +1,23 @@
// src/app/contribute/skill/page.tsx
-import SkillFormNative from '@/components/Contribute/Skill/Native';
-import * as React from 'react';
-import { AppLayout } from '../../../components/AppLayout';
-import { SkillFormGithub } from '../../../components/Contribute/Skill/Github';
+'use client';
+import { AppLayout } from '@/components/AppLayout';
+import { SkillFormGithub } from '@/components/Contribute/Skill/Github/index';
+import { SkillFormNative } from '@/components/Contribute/Skill/Native/index';
+import { useEffect, useState } from 'react';
-const SkillFormPage: React.FC = () => {
- return {process.env.IL_UI_DEPLOYMENT === 'native' ? : };
+const SkillFormPage: React.FunctionComponent = () => {
+ const [deploymentType, setDeploymentType] = useState();
+
+ useEffect(() => {
+ const getEnvVariables = async () => {
+ const res = await fetch('/api/envConfig');
+ const envConfig = await res.json();
+ setDeploymentType(envConfig.DEPLOYMENT_TYPE);
+ };
+ getEnvVariables();
+ }, []);
+
+ return {deploymentType === 'native' ? : };
};
export default SkillFormPage;
diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx
index 2d0fa212..ee28b27a 100644
--- a/src/app/dashboard/page.tsx
+++ b/src/app/dashboard/page.tsx
@@ -1,15 +1,16 @@
-// src/app/page.tsx
+// src/app/dashboard/page.tsx
'use client';
-import * as React from 'react';
import '@patternfly/react-core/dist/styles/base.css';
import { AppLayout } from '@/components/AppLayout';
import { DashboardGithub } from '@/components/Dashboard/Github/dashboard';
import { DashboardNative } from '@/components/Dashboard/Native/dashboard';
+import { useEffect, useState } from 'react';
+
const Home: React.FunctionComponent = () => {
- const [deploymentType, setDeploymentType] = React.useState();
+ const [deploymentType, setDeploymentType] = useState();
- React.useEffect(() => {
+ useEffect(() => {
const getEnvVariables = async () => {
const res = await fetch('/api/envConfig');
const envConfig = await res.json();
diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx
index 740427f1..3ffc88a8 100644
--- a/src/components/AppLayout.tsx
+++ b/src/components/AppLayout.tsx
@@ -21,7 +21,7 @@ import { PageSidebar } from '@patternfly/react-core/dist/dynamic/components/Page
import { PageSidebarBody } from '@patternfly/react-core/dist/dynamic/components/Page';
import { SkipToContent } from '@patternfly/react-core/dist/dynamic/components/SkipToContent';
import { Spinner } from '@patternfly/react-core/dist/dynamic/components/Spinner';
-import { Bullseye } from '@patternfly/react-core';
+import { Bullseye } from '@patternfly/react-core/dist/dynamic/layouts/Bullseye';
import UserMenu from './UserMenu/UserMenu';
import { useSession } from 'next-auth/react';
// import { useTheme } from '../context/ThemeContext';
diff --git a/src/components/Contribute/Knowledge/DownloadAttribution/DownloadAttribution.tsx b/src/components/Contribute/Knowledge/DownloadAttribution/DownloadAttribution.tsx
index 53b4da89..d61394fe 100644
--- a/src/components/Contribute/Knowledge/DownloadAttribution/DownloadAttribution.tsx
+++ b/src/components/Contribute/Knowledge/DownloadAttribution/DownloadAttribution.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { DropdownItem } from '@patternfly/react-core/dist/esm/components/Dropdown/DropdownItem';
-import { Icon } from '@patternfly/react-core';
+import { Icon } from '@patternfly/react-core/dist/dynamic/components/Icon';
import FileIcon from '@patternfly/react-icons/dist/esm/icons/file-icon';
import { KnowledgeFormData } from '@/types';
diff --git a/src/components/Contribute/Knowledge/DownloadDropdown/DownloadDropdown.tsx b/src/components/Contribute/Knowledge/DownloadDropdown/DownloadDropdown.tsx
index 76a03b59..2dc99c3f 100644
--- a/src/components/Contribute/Knowledge/DownloadDropdown/DownloadDropdown.tsx
+++ b/src/components/Contribute/Knowledge/DownloadDropdown/DownloadDropdown.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { Dropdown } from '@patternfly/react-core/dist/dynamic/components/Dropdown';
import { DropdownList } from '@patternfly/react-core/dist/dynamic/components/Dropdown';
-import { Icon } from '@patternfly/react-core';
+import { Icon } from '@patternfly/react-core/dist/dynamic/components/Icon';
import { MenuToggle, MenuToggleElement } from '@patternfly/react-core/dist/dynamic/components/MenuToggle';
import DownloadYaml from '../DownloadYaml/DownloadYaml';
import DownloadAttribution from '../DownloadAttribution/DownloadAttribution';
diff --git a/src/components/Contribute/Knowledge/DownloadYaml/DownloadYaml.tsx b/src/components/Contribute/Knowledge/DownloadYaml/DownloadYaml.tsx
index 6edb94ad..f39b6c2a 100644
--- a/src/components/Contribute/Knowledge/DownloadYaml/DownloadYaml.tsx
+++ b/src/components/Contribute/Knowledge/DownloadYaml/DownloadYaml.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import { KnowledgeFormData, KnowledgeYamlData } from '@/types';
import { KnowledgeSchemaVersion } from '@/types/const';
import { dumpYaml } from '@/utils/yamlConfig';
-import { Icon } from '@patternfly/react-core';
+import { Icon } from '@patternfly/react-core/dist/dynamic/components/Icon';
import { DropdownItem } from '@patternfly/react-core/dist/esm/components/Dropdown/DropdownItem';
import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon';
diff --git a/src/components/Contribute/Knowledge/Github/index.tsx b/src/components/Contribute/Knowledge/Github/index.tsx
index 36cf3008..be899e8f 100644
--- a/src/components/Contribute/Knowledge/Github/index.tsx
+++ b/src/components/Contribute/Knowledge/Github/index.tsx
@@ -1,4 +1,4 @@
-// src/components/Experimental/ContributeLocal/Knowledge/index.tsx
+// src/components/Contribute/Knowledge/Github/index.tsx
'use client';
import React, { useEffect, useMemo, useState } from 'react';
import '../knowledge.css';
diff --git a/src/components/Contribute/Knowledge/Native/index.tsx b/src/components/Contribute/Knowledge/Native/index.tsx
index 6e43fc5c..ffb5b9d7 100644
--- a/src/components/Contribute/Knowledge/Native/index.tsx
+++ b/src/components/Contribute/Knowledge/Native/index.tsx
@@ -1,4 +1,4 @@
-// src/components/Experimental/ContributeLocal/Knowledge/index.tsx
+// src/components/Contribute/Native/Knowledge/index.tsx
'use client';
import React, { useEffect, useMemo, useState } from 'react';
import '../knowledge.css';
diff --git a/src/components/Contribute/Knowledge/ViewDropdown/ViewDropdown.tsx b/src/components/Contribute/Knowledge/ViewDropdown/ViewDropdown.tsx
index c30e85eb..2dad0480 100644
--- a/src/components/Contribute/Knowledge/ViewDropdown/ViewDropdown.tsx
+++ b/src/components/Contribute/Knowledge/ViewDropdown/ViewDropdown.tsx
@@ -8,7 +8,7 @@ import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon';
import { AttributionData, KnowledgeFormData, KnowledgeYamlData } from '@/types';
import { KnowledgeSchemaVersion } from '@/types/const';
import { dumpYaml } from '@/utils/yamlConfig';
-import { Icon } from '@patternfly/react-core';
+import { Icon } from '@patternfly/react-core/dist/dynamic/components/Icon';
import FileIcon from '@patternfly/react-icons/dist/dynamic/icons/file-icon';
import EyeIcon from '@patternfly/react-icons/dist/esm/icons/eye-icon';
diff --git a/src/components/Contribute/Skill/Github/index.tsx b/src/components/Contribute/Skill/Github/index.tsx
index f4924a66..6dfce0a0 100644
--- a/src/components/Contribute/Skill/Github/index.tsx
+++ b/src/components/Contribute/Skill/Github/index.tsx
@@ -1,4 +1,4 @@
-// src/components/Contribute/Skill/index.tsx
+// src/components/Contribute/Skill/Github/index.tsx
'use client';
import React, { useEffect, useState } from 'react';
import './skills.css';
diff --git a/src/components/Contribute/Skill/Native/index.tsx b/src/components/Contribute/Skill/Native/index.tsx
index 4a263e49..4bf8e368 100644
--- a/src/components/Contribute/Skill/Native/index.tsx
+++ b/src/components/Contribute/Skill/Native/index.tsx
@@ -1,4 +1,4 @@
-// src/components/contribute/Skill/index.tsx
+// src/components/Contribute/Skill/Native/index.tsx
'use client';
import React, { useEffect, useState } from 'react';
import './skills.css';
@@ -392,8 +392,8 @@ export const SkillFormNative: React.FunctionComponent = ({ skill
actionGroupAlertContent.success &&
actionGroupAlertContent.url &&
actionGroupAlertContent.url.trim().length > 0 && (
-
- View your new branch
+
+ View your skill contribution
)}
diff --git a/src/components/Dashboard/Native/dashboard.tsx b/src/components/Dashboard/Native/dashboard.tsx
index f5ffdf07..149c3b21 100644
--- a/src/components/Dashboard/Native/dashboard.tsx
+++ b/src/components/Dashboard/Native/dashboard.tsx
@@ -22,19 +22,16 @@ import { Alert, AlertProps, AlertVariant } from '@patternfly/react-core/dist/esm
import { AlertActionCloseButton } from '@patternfly/react-core/dist/esm/components/Alert/AlertActionCloseButton';
import { PencilAltIcon } from '@patternfly/react-icons/dist/esm/icons/pencil-alt-icon';
import { UploadIcon } from '@patternfly/react-icons/dist/esm/icons/upload-icon';
-import { ModalHeader } from '@patternfly/react-core/dist/esm/components/Modal/ModalHeader';
-import { ModalBody } from '@patternfly/react-core/dist/esm/components/Modal/ModalBody';
-import { FormGroup } from '@patternfly/react-core/dist/esm/components/Form/FormGroup';
-import { Form } from '@patternfly/react-core/dist/esm/components/Form/Form';
-import { TextInput } from '@patternfly/react-core/dist/esm/components/TextInput/TextInput';
-import { ModalFooter } from '@patternfly/react-core/dist/esm/components/Modal/ModalFooter';
+import { Content } from '@patternfly/react-core/dist/esm/components/Content/Content';
+import { Popover } from '@patternfly/react-core/dist/esm/components/Popover/Popover';
+import { ExternalLinkAltIcon } from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon';
+import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons/dist/esm/icons/outlined-question-circle-icon';
const InstructLabLogo: React.FC = () => ;
const DashboardNative: React.FunctionComponent = () => {
- const [branches, setBranches] = React.useState<{ name: string; creationDate: number }[]>([]);
- const [selectedTaxonomyRepoDir, setSelectedTaxonomyRepoDir] = React.useState('');
- const [defaultTaxonomyRepoDir, setDefaultTaxonomyRepoDir] = React.useState('');
+ const [branches, setBranches] = React.useState<{ name: string; creationDate: number; message: string; author: string }[]>([]);
+ const [taxonomyRepoDir, setTaxonomyRepoDir] = React.useState('');
const [isLoading, setIsLoading] = React.useState(true);
const [mergeStatus] = React.useState<{ branch: string; message: string; success: boolean } | null>(null);
const [diffData, setDiffData] = React.useState<{ branch: string; changes: { file: string; status: string }[] } | null>(null);
@@ -43,6 +40,7 @@ const DashboardNative: React.FunctionComponent = () => {
const [isDeleteModalOpen, setIsDeleteModalOpen] = React.useState(false);
const [isPublishModalOpen, setIsPublishModalOpen] = React.useState(false);
const [selectedBranch, setSelectedBranch] = React.useState(null);
+ const [isPublishing, setIsPublishing] = React.useState(false);
const getUniqueId = () => new Date().getTime();
@@ -53,8 +51,7 @@ const DashboardNative: React.FunctionComponent = () => {
const getEnvVariables = async () => {
const res = await fetch('/api/envConfig');
const envConfig = await res.json();
- setDefaultTaxonomyRepoDir(envConfig.TAXONOMY_REPO_DIR);
- setSelectedTaxonomyRepoDir(envConfig.TAXONOMY_REPO_DIR);
+ setTaxonomyRepoDir(envConfig.TAXONOMY_REPO_DIR);
};
getEnvVariables();
@@ -126,28 +123,6 @@ const DashboardNative: React.FunctionComponent = () => {
return `${date.toLocaleDateString()} ${date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;
};
- // Disabling Merge for now, leaving the code for when we re-implement the feature.
- // const handleMerge = async (branchName: string) => {
- // setMergeStatus(null); // Clear previous status
- // try {
- // const response = await fetch('/api/native/git/branches', {
- // method: 'POST',
- // headers: { 'Content-Type': 'application/json' },
- // body: JSON.stringify({ branchName, action: 'merge' })
- // });
- //
- // const result = await response.json();
- // if (response.ok) {
- // setMergeStatus({ branch: branchName, message: result.message, success: true });
- // } else {
- // setMergeStatus({ branch: branchName, message: result.error, success: false });
- // }
- // } catch (error) {
- // setMergeStatus({ branch: branchName, message: 'Merge failed due to an unexpected error.', success: false });
- // console.error('Error merging branch:', error);
- // }
- // };
-
const handleShowChanges = async (branchName: string) => {
try {
const response = await fetch('/api/native/git/branches', {
@@ -224,18 +199,19 @@ const DashboardNative: React.FunctionComponent = () => {
};
const handlePublishContributionConfirm = async () => {
+ setIsPublishing(true);
if (selectedBranch) {
try {
const response = await fetch('/api/native/git/branches', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ branchName: selectedBranch, action: 'publish', remoteTaxonomyRepoDir: selectedTaxonomyRepoDir })
+ body: JSON.stringify({ branchName: selectedBranch, action: 'publish' })
});
const result = await response.json();
if (response.ok) {
+ setIsPublishing(false);
addSuccessAlert(result.message);
- setSelectedTaxonomyRepoDir(defaultTaxonomyRepoDir);
setSelectedBranch(null);
setIsPublishModalOpen(false);
} else {
@@ -247,10 +223,10 @@ const DashboardNative: React.FunctionComponent = () => {
} else {
addDangerAlert('No branch selected to publish');
}
+ setIsPublishing(false);
};
const handlePublishContributionCancel = () => {
- setSelectedTaxonomyRepoDir(defaultTaxonomyRepoDir);
setSelectedBranch(null);
setIsPublishModalOpen(false);
};
@@ -264,8 +240,27 @@ const DashboardNative: React.FunctionComponent = () => {
- Local Git Repository Branches
+ My Submissions
+
+ View and manage your taxonomy contributions.
+
+ Taxonomy contributions help tune the InstructLab model. Contributions can include skills that teach the model how to do something or
+ knowledge that teaches the model facts, data, or references.{' '}
+
+ Learn more
+
+
+ }
+ >
+
+
+
@@ -329,6 +324,9 @@ const DashboardNative: React.FunctionComponent = () => {
Branch Name: {branch.name}
+ Contribution Title: {branch.message}
+
+ Author: {branch.author} {' '}
Created on: {formatDateTime(branch.creationDate)}
@@ -397,40 +395,21 @@ const DashboardNative: React.FunctionComponent = () => {
setIsPublishModalOpen(false)}
- aria-labelledby="form-modal-title"
- aria-describedby="modal-box-description-form"
- >
-
-
-
-
-
-
+ ]}
+ >
+ are you sure you want to publish contribution to remote taxonomy repository present at : {taxonomyRepoDir}?