diff --git a/package.json b/package.json index 8067034..bbfd127 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@trpc/server": "11.0.0-next-alpha.150", "@uiw/codemirror-extensions-langs": "^4.21.21", "@uiw/react-codemirror": "^4.21.21", + "ansi-to-react": "^6.1.6", "argon2": "^0.31.2", "better-sqlite3": "^9.2.2", "bufferutil": "^4.0.8", @@ -93,6 +94,7 @@ "@types/better-sqlite3": "^7.6.8", "@types/common-tags": "^1.8.4", "@types/cookie": "^0.6.0", + "@types/docker-modem": "^3.0.6", "@types/dockerode": "^3.3.23", "@types/eslint": "^8.56.1", "@types/node": "^20.10.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f78ba6a..001d7e1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -71,6 +71,9 @@ dependencies: '@uiw/react-codemirror': specifier: ^4.21.21 version: 4.21.21(@babel/runtime@7.23.9)(@codemirror/autocomplete@6.12.0)(@codemirror/language@6.10.1)(@codemirror/lint@6.5.0)(@codemirror/search@6.5.6)(@codemirror/state@6.4.0)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.24.0)(codemirror@6.0.1)(react-dom@18.2.0)(react@18.2.0) + ansi-to-react: + specifier: ^6.1.6 + version: 6.1.6(react-dom@18.2.0)(react@18.2.0) argon2: specifier: ^0.31.2 version: 0.31.2 @@ -226,6 +229,9 @@ devDependencies: '@types/cookie': specifier: ^0.6.0 version: 0.6.0 + '@types/docker-modem': + specifier: ^3.0.6 + version: 3.0.6 '@types/dockerode': specifier: ^3.3.23 version: 3.3.23 @@ -3331,6 +3337,10 @@ packages: uri-js: 4.4.1 dev: true + /anser@1.4.10: + resolution: {integrity: sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==} + dev: false + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -3356,6 +3366,18 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + /ansi-to-react@6.1.6(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-+HWn72GKydtupxX9TORBedqOMsJRiKTqaLUKW8txSBZw9iBpzPKLI8KOu4WzwD4R7hSv1zEspobY6LwlWvwZ6Q==} + peerDependencies: + react: ^16.3.2 || ^17.0.0 + react-dom: ^16.3.2 || ^17.0.0 + dependencies: + anser: 1.4.10 + escape-carriage: 1.3.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -4751,6 +4773,10 @@ packages: engines: {node: '>=6'} dev: true + /escape-carriage@1.3.1: + resolution: {integrity: sha512-GwBr6yViW3ttx1kb7/Oh+gKQ1/TrhYwxKqVmg5gS+BK+Qe2KrOa/Vh7w3HPBvgGf0LfcDGoY9I6NHKoA5Hozhw==} + dev: false + /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} diff --git a/src/app/(dashboard)/project/[projectId]/service/[serviceId]/deployments/_components/DeploymentCard.tsx b/src/app/(dashboard)/project/[projectId]/service/[serviceId]/deployments/_components/DeploymentCard.tsx index 8c7e81b..051e4d8 100644 --- a/src/app/(dashboard)/project/[projectId]/service/[serviceId]/deployments/_components/DeploymentCard.tsx +++ b/src/app/(dashboard)/project/[projectId]/service/[serviceId]/deployments/_components/DeploymentCard.tsx @@ -40,17 +40,10 @@ export function DeploymentCard({ }: { deployment: RouterOutputs["projects"]["services"]["deployments"][number]; }) { - const [deploymentId, setDeploymentId] = useQueryParam( - "deploymentId", - StringParam, - ); + const [_, setDeploymentId] = useQueryParam("deploymentId", StringParam); return ( - {deploymentId === deployment.id && ( - - )} -

diff --git a/src/app/(dashboard)/project/[projectId]/service/[serviceId]/deployments/_components/DeploymentLogs.tsx b/src/app/(dashboard)/project/[projectId]/service/[serviceId]/deployments/_components/DeploymentLogs.tsx index 7838922..cd3201a 100644 --- a/src/app/(dashboard)/project/[projectId]/service/[serviceId]/deployments/_components/DeploymentLogs.tsx +++ b/src/app/(dashboard)/project/[projectId]/service/[serviceId]/deployments/_components/DeploymentLogs.tsx @@ -7,62 +7,45 @@ import { useProject } from "../../../../_context/ProjectContext"; import { useState } from "react"; import { toast } from "sonner"; import { Drawer, DrawerContent } from "~/components/ui/drawer"; +import { LogWindow, type LogLine } from "~/components/LogWindow"; +import { StringParam, useQueryParam } from "use-query-params"; -export function DeploymentLogs({ - deployment, -}: { - deployment: RouterOutputs["projects"]["services"]["deployments"][number]; -}) { +export function DeploymentLogs() { const project = useProject(); - const [logs, setLogs] = useState(null); + const [logs, setLogs] = useState(null); + const [deploymentId, setDeploymentId] = useQueryParam( + "deploymentId", + StringParam, + ); api.projects.services.deploymentLogs.useSubscription( { serviceId: project.selectedService!.id, - deploymentId: deployment.id, + deploymentId: deploymentId ?? "", projectId: project.id, }, { onData(data) { - setLogs( - (existing) => - (existing += data - .split("\n") - .map((it) => { - try { - return JSON.parse(it); - } catch (error) { - return { m: it }; - } - }) - .map((it) => it.m) - .join("\n")), - ); + setLogs((existing) => existing?.concat(data) ?? [data]); }, onError(error) { console.error(error); toast.error("Failed to fetch logs: " + error.message); }, + + enabled: !!deploymentId, }, ); return ( - + setDeploymentId(null)}>

Logs

- {/*
{logs}
*/} -