mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-25 18:55:19 +02:00
ddd refactor - projects (#208)
This commit is contained in:
parent
4b095d16cc
commit
580ecc7f98
72 changed files with 2460 additions and 624 deletions
|
|
@ -4,7 +4,7 @@ import { Metadata } from "next";
|
|||
import { Spinner, Dropdown, DropdownMenu, DropdownItem, DropdownTrigger, Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Input, useDisclosure, Divider, Textarea } from "@heroui/react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ReactNode, useEffect, useState } from "react";
|
||||
import { getProjectConfig, updateProjectName, updateWebhookUrl, deleteProject, rotateSecret } from "../../../actions/project.actions";
|
||||
import { fetchProject, updateProjectName, updateWebhookUrl, deleteProject, rotateSecret } from "../../../actions/project.actions";
|
||||
import { CopyButton } from "../../../../components/common/copy-button";
|
||||
import { InputField } from "../../../lib/components/input-field";
|
||||
import { EyeIcon, EyeOffIcon, Settings, Plus, MoreVertical } from "lucide-react";
|
||||
|
|
@ -64,7 +64,7 @@ export function BasicSettingsSection({
|
|||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
getProjectConfig(projectId).then((project) => {
|
||||
fetchProject(projectId).then((project) => {
|
||||
setProjectName(project?.name);
|
||||
setLoading(false);
|
||||
});
|
||||
|
|
@ -117,7 +117,7 @@ export function SecretSection({
|
|||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
getProjectConfig(projectId).then((project) => {
|
||||
fetchProject(projectId).then((project) => {
|
||||
setSecret(project.secret);
|
||||
setLoading(false);
|
||||
});
|
||||
|
|
@ -191,7 +191,7 @@ export function WebhookUrlSection({
|
|||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
getProjectConfig(projectId).then((project) => {
|
||||
fetchProject(projectId).then((project) => {
|
||||
setWebhookUrl(project.webhookUrl || null);
|
||||
setLoading(false);
|
||||
});
|
||||
|
|
@ -230,6 +230,7 @@ export function WebhookUrlSection({
|
|||
</Section>;
|
||||
}
|
||||
|
||||
/*
|
||||
export function ChatWidgetSection({
|
||||
projectId,
|
||||
chatWidgetHost,
|
||||
|
|
@ -242,7 +243,7 @@ export function ChatWidgetSection({
|
|||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
getProjectConfig(projectId).then((project) => {
|
||||
fetchProject(projectId).then((project) => {
|
||||
setChatClientId(project.chatClientId);
|
||||
setLoading(false);
|
||||
});
|
||||
|
|
@ -282,6 +283,7 @@ export function ChatWidgetSection({
|
|||
/>}
|
||||
</Section>;
|
||||
}
|
||||
*/
|
||||
|
||||
export function DeleteProjectSection({
|
||||
projectId,
|
||||
|
|
@ -298,7 +300,7 @@ export function DeleteProjectSection({
|
|||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
getProjectConfig(projectId).then((project) => {
|
||||
fetchProject(projectId).then((project) => {
|
||||
setProjectName(project.name);
|
||||
setLoading(false);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@
|
|||
import { ReactNode, useEffect, useState, useCallback } from "react";
|
||||
import { Spinner, Dropdown, Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Input, useDisclosure } from "@heroui/react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { getProjectConfig, createApiKey, deleteApiKey, listApiKeys, deleteProject, rotateSecret, updateProjectName, saveWorkflow } from "../../../../actions/project.actions";
|
||||
import { fetchProject, createApiKey, deleteApiKey, listApiKeys, deleteProject, rotateSecret, updateProjectName, saveWorkflow } from "../../../../actions/project.actions";
|
||||
import { CopyButton } from "../../../../../components/common/copy-button";
|
||||
import { EyeIcon, EyeOffIcon, PlusIcon, Trash2Icon } from "lucide-react";
|
||||
import { WithStringId } from "../../../../lib/types/types";
|
||||
import { ApiKey } from "@/src/entities/models/api-key";
|
||||
import { z } from "zod";
|
||||
import { RelativeTime } from "@primer/react";
|
||||
|
|
@ -14,7 +13,7 @@ import { Label } from "../../../../lib/components/label";
|
|||
import { sectionHeaderStyles, sectionDescriptionStyles } from './shared-styles';
|
||||
import { clsx } from "clsx";
|
||||
import { InputField } from "../../../../lib/components/input-field";
|
||||
import { Project, ComposioConnectedAccount } from "../../../../lib/types/project_types";
|
||||
import { ComposioConnectedAccount } from "@/src/entities/models/project";
|
||||
import { getToolkit, listComposioTriggerDeployments, deleteComposioTriggerDeployment } from "../../../../actions/composio.actions";
|
||||
import { deleteConnectedAccount } from "../../../../actions/composio.actions";
|
||||
import { PictureImg } from "@/components/ui/picture-img";
|
||||
|
|
@ -80,7 +79,7 @@ function ProjectNameSection({
|
|||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
getProjectConfig(projectId).then((project) => {
|
||||
fetchProject(projectId).then((project) => {
|
||||
setProjectName(project?.name);
|
||||
setLoading(false);
|
||||
});
|
||||
|
|
@ -140,7 +139,7 @@ function SecretSection({ projectId }: { projectId: string }) {
|
|||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
getProjectConfig(projectId).then((project) => {
|
||||
fetchProject(projectId).then((project) => {
|
||||
setSecret(project.secret);
|
||||
setLoading(false);
|
||||
});
|
||||
|
|
@ -361,13 +360,14 @@ function ApiKeysSection({ projectId }: { projectId: string }) {
|
|||
</Section>;
|
||||
}
|
||||
|
||||
/*
|
||||
export function ChatWidgetSection({ projectId, chatWidgetHost }: { projectId: string, chatWidgetHost: string }) {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [chatClientId, setChatClientId] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
getProjectConfig(projectId).then((project) => {
|
||||
fetchProject(projectId).then((project) => {
|
||||
setChatClientId(project.chatClientId);
|
||||
setLoading(false);
|
||||
});
|
||||
|
|
@ -414,6 +414,7 @@ export function ChatWidgetSection({ projectId, chatWidgetHost }: { projectId: st
|
|||
</Section>
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
interface ConnectedToolkit {
|
||||
slug: string;
|
||||
|
|
@ -435,7 +436,7 @@ function DisconnectToolkitsSection({ projectId, onProjectConfigUpdated }: {
|
|||
const loadConnectedToolkits = useCallback(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const project = await getProjectConfig(projectId);
|
||||
const project = await fetchProject(projectId);
|
||||
const connectedAccounts = project.composioConnectedAccounts || {};
|
||||
const workflow = project.draftWorkflow;
|
||||
|
||||
|
|
@ -502,7 +503,7 @@ function DisconnectToolkitsSection({ projectId, onProjectConfigUpdated }: {
|
|||
setDisconnectingToolkit(selectedToolkit.slug);
|
||||
try {
|
||||
// Step 1: Get current project and workflow
|
||||
const project = await getProjectConfig(projectId);
|
||||
const project = await fetchProject(projectId);
|
||||
const currentWorkflow = project.draftWorkflow;
|
||||
|
||||
if (currentWorkflow) {
|
||||
|
|
@ -541,7 +542,6 @@ function DisconnectToolkitsSection({ projectId, onProjectConfigUpdated }: {
|
|||
await deleteConnectedAccount(
|
||||
projectId,
|
||||
selectedToolkit.slug,
|
||||
selectedToolkit.connectedAccount.id
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -695,7 +695,7 @@ function DeleteProjectSection({ projectId }: { projectId: string }) {
|
|||
|
||||
useEffect(() => {
|
||||
setLoadingInitial(true);
|
||||
getProjectConfig(projectId).then((project) => {
|
||||
fetchProject(projectId).then((project) => {
|
||||
setProjectName(project.name);
|
||||
setLoadingInitial(false);
|
||||
});
|
||||
|
|
@ -803,7 +803,7 @@ export function ProjectSection({
|
|||
<div className="p-6 space-y-6">
|
||||
<ProjectIdSection projectId={projectId} />
|
||||
<ApiKeysSection projectId={projectId} />
|
||||
{useChatWidget && <ChatWidgetSection projectId={projectId} chatWidgetHost={chatWidgetHost} />}
|
||||
{/*{useChatWidget && <ChatWidgetSection projectId={projectId} chatWidgetHost={chatWidgetHost} />}*/}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Input } from '@/components/ui/input';
|
|||
import { Info, Plus, Trash2 } from 'lucide-react';
|
||||
import { z } from 'zod';
|
||||
import { Workflow, WorkflowTool } from '@/app/lib/types/workflow_types';
|
||||
import { getProjectConfig } from '@/app/actions/project.actions';
|
||||
import { fetchProject } from '@/app/actions/project.actions';
|
||||
import { addServer, removeServer } from '@/app/actions/custom-mcp-server.actions';
|
||||
import { fetchTools } from "@/app/actions/custom-mcp-server.actions";
|
||||
import { ServerCard } from './ServerCard';
|
||||
|
|
@ -50,7 +50,7 @@ export function CustomMcpServers({ tools: workflowTools, onAddTool }: CustomMcpS
|
|||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const project = await getProjectConfig(projectId);
|
||||
const project = await fetchProject(projectId);
|
||||
setServers(project.customMcpServers || {});
|
||||
} catch (err: any) {
|
||||
setError(err?.message || 'Failed to load servers');
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ import { Button } from '@/components/ui/button';
|
|||
import { RefreshCw, Search } from 'lucide-react';
|
||||
import clsx from 'clsx';
|
||||
import { listToolkits } from '@/app/actions/composio.actions';
|
||||
import { getProjectConfig } from '@/app/actions/project.actions';
|
||||
import { fetchProject } from '@/app/actions/project.actions';
|
||||
import { z } from 'zod';
|
||||
import { ZToolkit, ZListResponse, ZTool } from '@/app/lib/composio/composio';
|
||||
import { Project } from '@/app/lib/types/project_types';
|
||||
import { Project } from "@/src/entities/models/project";
|
||||
import { ToolkitCard } from './ToolkitCard';
|
||||
import { Workflow } from '@/app/lib/types/workflow_types';
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ export function SelectComposioToolkit({
|
|||
|
||||
const loadProjectConfig = useCallback(async () => {
|
||||
try {
|
||||
const config = await getProjectConfig(projectId);
|
||||
const config = await fetchProject(projectId);
|
||||
setProjectConfig(config);
|
||||
} catch (err: any) {
|
||||
console.error('Error fetching project config:', err);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import { useState, useEffect } from "react";
|
||||
import { Spinner, Button, Input } from "@heroui/react";
|
||||
import { getProjectConfig, updateWebhookUrl } from "@/app/actions/project.actions";
|
||||
import { fetchProject, updateWebhookUrl } from "@/app/actions/project.actions";
|
||||
import { clsx } from "clsx";
|
||||
import { ProjectWideChangeConfirmationModal } from '@/components/common/project-wide-change-confirmation-modal';
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ export function WebhookConfig({ projectId }: { projectId: string }) {
|
|||
|
||||
async function loadConfig() {
|
||||
try {
|
||||
const project = await getProjectConfig(projectId);
|
||||
const project = await fetchProject(projectId);
|
||||
if (mounted) {
|
||||
setWebhookUrl(project.webhookUrl || null);
|
||||
setEditValue(project.webhookUrl || '');
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
"use client";
|
||||
import { MCPServer, WithStringId } from "../../../lib/types/types";
|
||||
import { DataSource } from "@/src/entities/models/data-source";
|
||||
import { Project } from "../../../lib/types/project_types";
|
||||
import { Project } from "@/src/entities/models/project";
|
||||
import { z } from "zod";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { WorkflowEditor } from "./workflow_editor";
|
||||
import { Spinner } from "@heroui/react";
|
||||
import { listDataSources } from "../../../actions/data-source.actions";
|
||||
import { revertToLiveWorkflow } from "@/app/actions/project.actions";
|
||||
import { getProjectConfig } from "@/app/actions/project.actions";
|
||||
import { fetchProject } from "@/app/actions/project.actions";
|
||||
import { Workflow, WorkflowTool } from "@/app/lib/types/workflow_types";
|
||||
import { getEligibleModels } from "@/app/actions/billing.actions";
|
||||
import { ModelsResponse } from "@/app/lib/types/billing_types";
|
||||
|
|
@ -31,12 +31,11 @@ export function App({
|
|||
chatWidgetHost: string;
|
||||
}) {
|
||||
const [mode, setMode] = useState<'draft' | 'live'>('draft');
|
||||
const [project, setProject] = useState<WithStringId<z.infer<typeof Project>> | null>(null);
|
||||
const [project, setProject] = useState<z.infer<typeof Project> | null>(null);
|
||||
const [dataSources, setDataSources] = useState<z.infer<typeof DataSource>[] | null>(null);
|
||||
const [projectConfig, setProjectConfig] = useState<z.infer<typeof Project> | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [eligibleModels, setEligibleModels] = useState<z.infer<typeof ModelsResponse> | "*">("*");
|
||||
const [projectMcpServers, setProjectMcpServers] = useState<Array<z.infer<typeof MCPServer>>>([]);
|
||||
|
||||
console.log('workflow app.tsx render');
|
||||
|
||||
|
|
@ -53,7 +52,7 @@ export function App({
|
|||
dataSources,
|
||||
eligibleModels,
|
||||
] = await Promise.all([
|
||||
getProjectConfig(projectId),
|
||||
fetchProject(projectId),
|
||||
listDataSources(projectId),
|
||||
getEligibleModels(),
|
||||
]);
|
||||
|
|
@ -61,23 +60,15 @@ export function App({
|
|||
setProject(project);
|
||||
setDataSources(dataSources);
|
||||
setEligibleModels(eligibleModels);
|
||||
if (project.mcpServers) {
|
||||
setProjectMcpServers(project.mcpServers);
|
||||
}
|
||||
setLoading(false);
|
||||
}, [projectId]);
|
||||
|
||||
const handleProjectToolsUpdate = useCallback(async () => {
|
||||
// Lightweight refresh for tool-only updates
|
||||
const projectConfig = await getProjectConfig(projectId);
|
||||
const projectConfig = await fetchProject(projectId);
|
||||
|
||||
setProject(projectConfig);
|
||||
setProjectConfig(projectConfig);
|
||||
|
||||
// Update MCP servers if they changed
|
||||
if (projectConfig.mcpServers) {
|
||||
setProjectMcpServers(projectConfig.mcpServers);
|
||||
}
|
||||
}, [projectId]);
|
||||
|
||||
const handleDataSourcesUpdate = useCallback(async () => {
|
||||
|
|
@ -88,7 +79,7 @@ export function App({
|
|||
|
||||
const handleProjectConfigUpdate = useCallback(async () => {
|
||||
// Refresh project config when project name or other settings change
|
||||
const updatedProjectConfig = await getProjectConfig(projectId);
|
||||
const updatedProjectConfig = await fetchProject(projectId);
|
||||
setProject(updatedProjectConfig);
|
||||
setProjectConfig(updatedProjectConfig);
|
||||
}, [projectId]);
|
||||
|
|
@ -146,7 +137,6 @@ export function App({
|
|||
useRagUploads={useRagUploads}
|
||||
useRagS3Uploads={useRagS3Uploads}
|
||||
useRagScraping={useRagScraping}
|
||||
mcpServerUrls={projectMcpServers}
|
||||
defaultModel={defaultModel}
|
||||
eligibleModels={eligibleModels}
|
||||
onChangeMode={handleSetMode}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { ComposioTriggerTypesPanel } from './ComposioTriggerTypesPanel';
|
|||
import { TriggerConfigForm } from './TriggerConfigForm';
|
||||
import { ToolkitAuthModal } from '../../tools/components/ToolkitAuthModal';
|
||||
import { ZToolkit } from '@/app/lib/composio/composio';
|
||||
import { Project } from '@/app/lib/types/project_types';
|
||||
import { Project } from "@/src/entities/models/project";
|
||||
|
||||
interface TriggersModalProps {
|
||||
isOpen: boolean;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React, { forwardRef, useImperativeHandle } from "react";
|
||||
import { z } from "zod";
|
||||
import { WorkflowPrompt, WorkflowAgent, WorkflowTool, WorkflowPipeline, Workflow } from "../../../lib/types/workflow_types";
|
||||
import { Project } from "../../../lib/types/project_types";
|
||||
import { Project } from "@/src/entities/models/project";
|
||||
import { DataSource } from "@/src/entities/models/data-source";
|
||||
import { WithStringId } from "../../../lib/types/types";
|
||||
import { Dropdown, DropdownItem, DropdownTrigger, DropdownMenu } from "@heroui/react";
|
||||
|
|
@ -1353,7 +1353,7 @@ const ComposioCard = ({
|
|||
const connectedAccountId = projectConfig?.composioConnectedAccounts?.[card.slug]?.id;
|
||||
try {
|
||||
if (connectedAccountId) {
|
||||
await deleteConnectedAccount(projectId, card.slug, connectedAccountId);
|
||||
await deleteConnectedAccount(projectId, card.slug);
|
||||
}
|
||||
} catch (err) {
|
||||
// ignore error, continue to remove tools
|
||||
|
|
@ -1375,7 +1375,7 @@ const ComposioCard = ({
|
|||
setIsProcessingAuth(true);
|
||||
try {
|
||||
if (connectedAccountId) {
|
||||
await deleteConnectedAccount(projectId, card.slug, connectedAccountId);
|
||||
await deleteConnectedAccount(projectId, card.slug);
|
||||
onProjectToolsUpdated?.();
|
||||
}
|
||||
} catch (err: any) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import { Metadata } from "next";
|
||||
import { App } from "./app";
|
||||
import { USE_RAG, USE_RAG_UPLOADS, USE_RAG_S3_UPLOADS, USE_RAG_SCRAPING } from "@/app/lib/feature_flags";
|
||||
import { projectsCollection } from "@/app/lib/mongodb";
|
||||
import { notFound } from "next/navigation";
|
||||
import { requireActiveBillingSubscription } from '@/app/lib/billing';
|
||||
import { migrate_versioned_workflows } from "@/app/lib/migrate_versioned_workflows";
|
||||
import { container } from "@/di/container";
|
||||
import { IProjectsRepository } from "@/src/application/repositories/projects.repository.interface";
|
||||
|
||||
const projectsRepository = container.resolve<IProjectsRepository>('projectsRepository');
|
||||
|
||||
const DEFAULT_MODEL = process.env.PROVIDER_DEFAULT_MODEL || "gpt-4.1";
|
||||
|
||||
|
|
@ -20,18 +22,11 @@ export default async function Page(
|
|||
const params = await props.params;
|
||||
await requireActiveBillingSubscription();
|
||||
console.log('->>> workflow page being rendered');
|
||||
const project = await projectsCollection.findOne({
|
||||
_id: params.projectId,
|
||||
});
|
||||
const project = await projectsRepository.fetch(params.projectId);
|
||||
if (!project) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
// migrate versioned workflows for this project
|
||||
if (!project.draftWorkflow) {
|
||||
await migrate_versioned_workflows(params.projectId);
|
||||
}
|
||||
|
||||
console.log('/workflow page.tsx serve');
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import React, { useReducer, Reducer, useState, useCallback, useEffect, useRef, c
|
|||
import { MCPServer, Message, WithStringId } from "../../../lib/types/types";
|
||||
import { Workflow, WorkflowTool, WorkflowPrompt, WorkflowAgent, WorkflowPipeline } from "../../../lib/types/workflow_types";
|
||||
import { DataSource } from "@/src/entities/models/data-source";
|
||||
import { Project } from "../../../lib/types/project_types";
|
||||
import { Project } from "@/src/entities/models/project";
|
||||
import { produce, applyPatches, enablePatches, produceWithPatches, Patch } from 'immer';
|
||||
import { AgentConfig } from "../entities/agent_config";
|
||||
import { PipelineConfig } from "../entities/pipeline_config";
|
||||
|
|
@ -36,7 +36,6 @@ import { Button as CustomButton } from "@/components/ui/button";
|
|||
import { ConfigApp } from "../config/app";
|
||||
import { InputField } from "@/app/lib/components/input-field";
|
||||
import { VoiceSection } from "../config/components/voice";
|
||||
import { ChatWidgetSection } from "../config/components/project";
|
||||
import { TriggersModal } from "./components/TriggersModal";
|
||||
import { TopBar } from "./components/TopBar";
|
||||
|
||||
|
|
@ -808,7 +807,6 @@ export function WorkflowEditor({
|
|||
useRagUploads,
|
||||
useRagS3Uploads,
|
||||
useRagScraping,
|
||||
mcpServerUrls,
|
||||
defaultModel,
|
||||
projectConfig,
|
||||
eligibleModels,
|
||||
|
|
@ -827,7 +825,6 @@ export function WorkflowEditor({
|
|||
useRagUploads: boolean;
|
||||
useRagS3Uploads: boolean;
|
||||
useRagScraping: boolean;
|
||||
mcpServerUrls: Array<z.infer<typeof MCPServer>>;
|
||||
defaultModel: string;
|
||||
projectConfig: z.infer<typeof Project>;
|
||||
eligibleModels: z.infer<typeof ModelsResponse> | "*";
|
||||
|
|
@ -1499,6 +1496,7 @@ export function WorkflowEditor({
|
|||
</Modal>
|
||||
|
||||
{/* Chat Widget Modal */}
|
||||
{/*
|
||||
<Modal
|
||||
isOpen={isChatWidgetModalOpen}
|
||||
onClose={onChatWidgetModalClose}
|
||||
|
|
@ -1519,6 +1517,7 @@ export function WorkflowEditor({
|
|||
</ModalBody>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
*/}
|
||||
|
||||
{/* Triggers Management Modal */}
|
||||
<TriggersModal
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { Project } from "../lib/types/project_types";
|
||||
import { Project } from "@/src/entities/models/project";
|
||||
import { useEffect, useState } from "react";
|
||||
import { z } from "zod";
|
||||
import { listProjects } from "../actions/project.actions";
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { TextareaWithSend } from "@/app/components/ui/textarea-with-send";
|
|||
import { Workflow } from '../../lib/types/workflow_types';
|
||||
import { PictureImg } from '@/components/ui/picture-img';
|
||||
import { Tabs, Tab } from "@/components/ui/tabs";
|
||||
import { Project } from "@/app/lib/types/project_types";
|
||||
import { Project } from "@/src/entities/models/project";
|
||||
import { z } from "zod";
|
||||
import Link from 'next/link';
|
||||
|
||||
|
|
@ -313,8 +313,8 @@ export function BuildAssistantSection({ defaultName }: BuildAssistantSectionProp
|
|||
<div className="space-y-2">
|
||||
{currentProjects.map((project) => (
|
||||
<Link
|
||||
key={project._id}
|
||||
href={`/projects/${project._id}/workflow`}
|
||||
key={project.id}
|
||||
href={`/projects/${project.id}/workflow`}
|
||||
className="flex items-center justify-between p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:border-blue-300 dark:hover:border-blue-600 hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-all group hover:shadow-sm"
|
||||
>
|
||||
<div className="flex-1 min-w-0">
|
||||
|
|
@ -325,7 +325,8 @@ export function BuildAssistantSection({ defaultName }: BuildAssistantSectionProp
|
|||
{project.name}
|
||||
</div>
|
||||
<div className="text-xs text-gray-500 dark:text-gray-400 mt-1">
|
||||
Created {new Date(project.createdAt).toLocaleDateString()} • Last updated {new Date(project.lastUpdatedAt).toLocaleDateString()}
|
||||
Created {new Date(project.createdAt).toLocaleDateString()}
|
||||
{project.lastUpdatedAt && `• Last updated ${new Date(project.lastUpdatedAt).toLocaleDateString()}`}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
'use client';
|
||||
import { Project } from "@/app/lib/types/project_types";
|
||||
import { Project } from "@/src/entities/models/project";
|
||||
import { z } from "zod";
|
||||
import { useState } from "react";
|
||||
import clsx from 'clsx';
|
||||
|
|
@ -48,8 +48,8 @@ export function ProjectList({ projects, isLoading, searchQuery }: ProjectListPro
|
|||
<div className="flex-1 overflow-y-auto" style={{ maxHeight: 'calc(100vh - 400px)' }}>
|
||||
{currentProjects.map((project) => (
|
||||
<Link
|
||||
key={project._id}
|
||||
href={`/projects/${project._id}`}
|
||||
key={project.id}
|
||||
href={`/projects/${project.id}`}
|
||||
className={clsx(
|
||||
"block px-4 py-3",
|
||||
tokens.transitions.default,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Project } from "@/app/lib/types/project_types";
|
||||
import { Project } from "@/src/entities/models/project";
|
||||
import { z } from "zod";
|
||||
import { ProjectList } from "./project-list";
|
||||
import { HorizontalDivider } from "@/components/ui/horizontal-divider";
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import {
|
|||
LogsIcon,
|
||||
Clock
|
||||
} from "lucide-react";
|
||||
import { getProjectConfig } from "@/app/actions/project.actions";
|
||||
import { fetchProject } from "@/app/actions/project.actions";
|
||||
import { createProjectWithOptions } from "../../lib/project-creation-utils";
|
||||
import { useTheme } from "@/app/providers/theme-provider";
|
||||
import { USE_PRODUCT_TOUR } from '@/app/lib/feature_flags';
|
||||
|
|
@ -56,7 +56,7 @@ export default function Sidebar({ projectId, useAuth, collapsed = false, onToggl
|
|||
async function fetchProjectName() {
|
||||
if (!isProjectsRoute && projectId) {
|
||||
try {
|
||||
const project = await getProjectConfig(projectId);
|
||||
const project = await fetchProject(projectId);
|
||||
setProjectName(project.name);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch project name:', error);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import Link from "next/link";
|
|||
import { useEffect, useState } from "react";
|
||||
import clsx from "clsx";
|
||||
import Menu from "./menu";
|
||||
import { getProjectConfig } from "@/app/actions/project.actions";
|
||||
import { fetchProject } from "@/app/actions/project.actions";
|
||||
import { FolderOpenIcon, PanelLeftCloseIcon, PanelLeftOpenIcon } from "lucide-react";
|
||||
|
||||
export function Nav({
|
||||
|
|
@ -17,7 +17,7 @@ export function Nav({
|
|||
|
||||
useEffect(() => {
|
||||
async function getProject() {
|
||||
const project = await getProjectConfig(projectId);
|
||||
const project = await fetchProject(projectId);
|
||||
setProjectName(project.name);
|
||||
}
|
||||
getProject();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue