Compare commits

..

No commits in common. "ai-dev" and "master" have entirely different histories.

3 changed files with 89 additions and 114 deletions

View File

@ -2,178 +2,234 @@ import * as icon from '@mdi/js';
import { MenuAsideItem } from './interfaces'
const menuAside: MenuAsideItem[] = [
{ href: '/story-studio', label: 'Story Studio', icon: icon.mdiRobot },
{
href: '/dashboard',
icon: icon.mdiViewDashboardOutline,
label: 'Dashboard',
},
{
href: '/users/users-list',
label: 'Users',
icon: icon.mdiAccountGroup,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: icon.mdiAccountGroup ?? icon.mdiTable,
permissions: 'READ_USERS'
},
{
href: '/roles/roles-list',
label: 'Roles',
icon: icon.mdiShieldAccountVariantOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: icon.mdiShieldAccountVariantOutline ?? icon.mdiTable,
permissions: 'READ_ROLES'
},
{
href: '/permissions/permissions-list',
label: 'Permissions',
icon: icon.mdiShieldAccountOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: icon.mdiShieldAccountOutline ?? icon.mdiTable,
permissions: 'READ_PERMISSIONS'
},
{
href: '/organizations/organizations-list',
label: 'Organizations',
icon: icon.mdiTable,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_ORGANIZATIONS'
},
{
href: '/teams/teams-list',
label: 'Teams',
icon: icon.mdiAccountGroup,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiAccountGroup' in icon ? icon['mdiAccountGroup' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_TEAMS'
},
{
href: '/oauth_accounts/oauth_accounts-list',
label: 'Oauth accounts',
icon: icon.mdiKey,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiKey' in icon ? icon['mdiKey' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_OAUTH_ACCOUNTS'
},
{
href: '/integrations/integrations-list',
label: 'Integrations',
icon: icon.mdiPuzzle,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiPuzzle' in icon ? icon['mdiPuzzle' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_INTEGRATIONS'
},
{
href: '/user_stories/user_stories-list',
label: 'User stories',
icon: icon.mdiBookOpenPageVariant,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiBookOpenPageVariant' in icon ? icon['mdiBookOpenPageVariant' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_USER_STORIES'
},
{
href: '/acceptance_criteria/acceptance_criteria-list',
label: 'Acceptance criteria',
icon: icon.mdiFormatListChecks,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiFormatListChecks' in icon ? icon['mdiFormatListChecks' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_ACCEPTANCE_CRITERIA'
},
{
href: '/documents/documents-list',
label: 'Documents',
icon: icon.mdiFileDocumentEditOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiFileDocumentEditOutline' in icon ? icon['mdiFileDocumentEditOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_DOCUMENTS'
},
{
href: '/document_folders/document_folders-list',
label: 'Document folders',
icon: icon.mdiSitemap,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiFolderTree' in icon ? icon['mdiFolderTree' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_DOCUMENT_FOLDERS'
},
{
href: '/document_versions/document_versions-list',
label: 'Document versions',
icon: icon.mdiSourceBranch,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiSourceBranch' in icon ? icon['mdiSourceBranch' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_DOCUMENT_VERSIONS'
},
{
href: '/story_document_links/story_document_links-list',
label: 'Story document links',
icon: icon.mdiLinkVariant,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiLinkVariant' in icon ? icon['mdiLinkVariant' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_STORY_DOCUMENT_LINKS'
},
{
href: '/collaboration_sessions/collaboration_sessions-list',
label: 'Collaboration sessions',
icon: icon.mdiAccountMultipleOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiAccountMultipleOutline' in icon ? icon['mdiAccountMultipleOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_COLLABORATION_SESSIONS'
},
{
href: '/comment_threads/comment_threads-list',
label: 'Comment threads',
icon: icon.mdiCommentQuoteOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiCommentQuoteOutline' in icon ? icon['mdiCommentQuoteOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_COMMENT_THREADS'
},
{
href: '/comments/comments-list',
label: 'Comments',
icon: icon.mdiCommentTextOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiCommentTextOutline' in icon ? icon['mdiCommentTextOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_COMMENTS'
},
{
href: '/comment_reactions/comment_reactions-list',
label: 'Comment reactions',
icon: icon.mdiEmoticonOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiEmoticonOutline' in icon ? icon['mdiEmoticonOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_COMMENT_REACTIONS'
},
{
href: '/mentions/mentions-list',
label: 'Mentions',
icon: icon.mdiAt,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiAt' in icon ? icon['mdiAt' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_MENTIONS'
},
{
href: '/approval_workflows/approval_workflows-list',
label: 'Approval workflows',
icon: icon.mdiClipboardCheckOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiClipboardCheckOutline' in icon ? icon['mdiClipboardCheckOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_APPROVAL_WORKFLOWS'
},
{
href: '/approvals/approvals-list',
label: 'Approvals',
icon: icon.mdiCheckDecagramOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiCheckDecagramOutline' in icon ? icon['mdiCheckDecagramOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_APPROVALS'
},
{
href: '/approval_reviewers/approval_reviewers-list',
label: 'Approval reviewers',
icon: icon.mdiAccountCheckOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiAccountCheckOutline' in icon ? icon['mdiAccountCheckOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_APPROVAL_REVIEWERS'
},
{
href: '/audit_events/audit_events-list',
label: 'Audit events',
icon: icon.mdiShieldSearch,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiShieldSearch' in icon ? icon['mdiShieldSearch' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_AUDIT_EVENTS'
},
{
href: '/notifications/notifications-list',
label: 'Notifications',
icon: icon.mdiBellOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiBellOutline' in icon ? icon['mdiBellOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_NOTIFICATIONS'
},
{
href: '/sprints/sprints-list',
label: 'Sprints',
icon: icon.mdiRunFast,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiRunFast' in icon ? icon['mdiRunFast' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_SPRINTS'
},
{
href: '/sprint_items/sprint_items-list',
label: 'Sprint items',
icon: icon.mdiClipboardListOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiClipboardListOutline' in icon ? icon['mdiClipboardListOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_SPRINT_ITEMS'
},
{
href: '/blockers/blockers-list',
label: 'Blockers',
icon: icon.mdiAlertOctagonOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiAlertOctagonOutline' in icon ? icon['mdiAlertOctagonOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_BLOCKERS'
},
{
href: '/activity_feed_items/activity_feed_items-list',
label: 'Activity feed items',
icon: icon.mdiTimelineTextOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiTimelineTextOutline' in icon ? icon['mdiTimelineTextOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_ACTIVITY_FEED_ITEMS'
},
{
href: '/ai_generations/ai_generations-list',
label: 'Ai generations',
icon: icon.mdiRobotOutline,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
icon: 'mdiRobotOutline' in icon ? icon['mdiRobotOutline' as keyof typeof icon] : icon.mdiTable ?? icon.mdiTable,
permissions: 'READ_AI_GENERATIONS'
},
{
@ -181,6 +237,8 @@ const menuAside: MenuAsideItem[] = [
label: 'Profile',
icon: icon.mdiAccountCircle,
},
{
href: '/api-docs',
target: '_blank',

View File

@ -466,7 +466,7 @@ const Dashboard = () => {
size={48}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
path={'mdiSitemap' in icon ? icon['mdiSitemap' as keyof typeof icon] : icon.mdiTable || icon.mdiTable}
path={'mdiFolderTree' in icon ? icon['mdiFolderTree' as keyof typeof icon] : icon.mdiTable || icon.mdiTable}
/>
</div>
</div>

View File

@ -1,83 +0,0 @@
import { mdiRobot, mdiContentSave } from '@mdi/js';
import Head from 'next/head';
import React, { ReactElement, useState } from 'react';
import CardBox from '../components/CardBox';
import LayoutAuthenticated from '../layouts/Authenticated';
import SectionMain from '../components/SectionMain';
import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton';
import FormField from '../components/FormField';
import BaseButton from '../components/BaseButton';
import BaseButtons from '../components/BaseButtons';
import { getPageTitle } from '../config';
import { useAppDispatch, useAppSelector } from '../stores/hooks';
import { aiResponse } from '../stores/openAiSlice';
import axios from 'axios';
const StoryStudio = () => {
const [idea, setIdea] = useState('');
const dispatch = useAppDispatch();
const { aiResponse: aiData, isAskingResponse } = useAppSelector((state) => state.openAi);
const handleGenerate = () => {
dispatch(aiResponse({
input: [
{ role: 'system', content: 'You are an expert Agile Product Owner. Convert raw product ideas into a structured User Story (As a, I want, So that) and provide 3 Acceptance Criteria.' },
{ role: 'user', content: idea },
],
options: { poll_interval: 5, poll_timeout: 300 }
}));
};
const handleSave = async () => {
// Basic extraction
const storyText = aiData?.output?.[0]?.content?.[0]?.text || '';
await axios.post('/user_stories', {
title: idea.substring(0, 50),
asA: 'User',
iWant: idea,
soThat: 'Value',
status: 'Draft'
});
alert('Story saved!');
};
return (
<>
<Head><title>{getPageTitle('Story Studio')}</title></Head>
<SectionMain>
<SectionTitleLineWithButton icon={mdiRobot} title="Story Studio" main />
<CardBox>
<FormField label="Raw Idea" labelFor="idea">
<textarea
id="idea"
className="w-full p-3 border border-gray-300 rounded"
rows={4}
value={idea}
onChange={(e) => setIdea(e.target.value)}
placeholder="e.g. Users should be able to reset their passwords..."
/>
</FormField>
<BaseButtons>
<BaseButton color="info" label={isAskingResponse ? 'Generating...' : 'Generate Story'} onClick={handleGenerate} disabled={isAskingResponse} />
</BaseButtons>
</CardBox>
{aiData && (
<CardBox className="mt-6">
<h2 className="text-xl font-bold mb-4 text-emerald-600">AI Generated Story</h2>
<div className="whitespace-pre-wrap">{aiData?.output?.[0]?.content?.[0]?.text}</div>
<BaseButtons className="mt-4">
<BaseButton color="success" icon={mdiContentSave} label="Save Story" onClick={handleSave} />
</BaseButtons>
</CardBox>
)}
</SectionMain>
</>
);
};
StoryStudio.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
};
export default StoryStudio;