diff --git a/.github/workflows/github_ci.yaml b/.github/workflows/github_ci.yaml index cb26270..3d16448 100644 --- a/.github/workflows/github_ci.yaml +++ b/.github/workflows/github_ci.yaml @@ -10,7 +10,7 @@ permissions: contents: read jobs: - build: + build-test-chatbot: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -44,4 +44,29 @@ jobs: hatch run dev:typecheck - name: Test run: | - hatch run dev:test \ No newline at end of file + hatch run dev:test + build-test-ui: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: "20" + - name: Install dependencies + run: | + npm install --legacy-peer-deps + working-directory: ./ui + - name: Lint + run: | + npm run lint + working-directory: ./ui + - name: Format + run: | + npm run format + working-directory: ./ui + - name: Test + run: | + npm run test_component + npm run test_e2e + working-directory: ./ui \ No newline at end of file diff --git a/api/main.py b/api/main.py index 6c451a0..b90d8ac 100644 --- a/api/main.py +++ b/api/main.py @@ -6,7 +6,9 @@ app = FastAPI() origins = [ + "http://127.0.0.1:3000", "http://localhost:3000", + "http://ui:3000", ] app.add_middleware( diff --git a/compose.yaml b/compose.yaml index 775e718..a17be38 100644 --- a/compose.yaml +++ b/compose.yaml @@ -43,3 +43,9 @@ services: image: chatbot-api:latest ports: - "8080:8080" + ui: + image: chatbot-ui:latest + ports: + - "3000:3000" + environment: + - HOSTNAME=0.0.0.0 diff --git a/src/chatbot/__about__.py b/src/chatbot/__about__.py index aefefb6..e581cd2 100644 --- a/src/chatbot/__about__.py +++ b/src/chatbot/__about__.py @@ -1,4 +1,4 @@ # SPDX-FileCopyrightText: 2025-present Nam Le # # SPDX-License-Identifier: MIT -__version__ = "0.0.7" +__version__ = "0.0.8" diff --git a/ui/.prettierrc b/ui/.prettierrc new file mode 100644 index 0000000..fcb051c --- /dev/null +++ b/ui/.prettierrc @@ -0,0 +1,6 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "es5", + "printWidth": 80 +} diff --git a/ui/Dockerfile b/ui/Dockerfile new file mode 100644 index 0000000..10bef73 --- /dev/null +++ b/ui/Dockerfile @@ -0,0 +1,66 @@ +# syntax=docker.io/docker/dockerfile:1 + +FROM node:18-alpine AS base + +# Install dependencies only when needed +FROM base AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* ./ +RUN \ + if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ + elif [ -f package-lock.json ]; then npm ci; \ + elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \ + else echo "Lockfile not found." && exit 1; \ + fi + + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +# ENV NEXT_TELEMETRY_DISABLED=1 + +RUN \ + if [ -f yarn.lock ]; then yarn run build; \ + elif [ -f package-lock.json ]; then npm run build; \ + elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \ + else echo "Lockfile not found." && exit 1; \ + fi + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV=production +# Uncomment the following line in case you want to disable telemetry during runtime. +# ENV NEXT_TELEMETRY_DISABLED=1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT=3000 + +# server.js is created by next build from the standalone output +# https://nextjs.org/docs/pages/api-reference/config/next-config-js/output +ENV HOSTNAME="0.0.0.0" +CMD ["node", "server.js"] \ No newline at end of file diff --git a/ui/app/components/HumanReviewForm.tsx b/ui/app/components/HumanReviewForm.tsx index ac55034..3bf6d63 100644 --- a/ui/app/components/HumanReviewForm.tsx +++ b/ui/app/components/HumanReviewForm.tsx @@ -1,58 +1,58 @@ -import React from "react"; -import { HumanReview } from "../page"; +import React from 'react'; +import { HumanReview } from '../models'; interface HumanReviewFormProps { - searchQuery: string; - humanReview: HumanReview; - setHumanReview: (review: HumanReview) => void; - sendHumanReview: () => void; + searchQuery: string; + humanReview: HumanReview; + setHumanReview: (review: HumanReview) => void; + sendHumanReview: () => void; } export default function HumanReviewForm({ - searchQuery, - humanReview, - setHumanReview, - sendHumanReview, + searchQuery, + humanReview, + setHumanReview, + sendHumanReview, }: HumanReviewFormProps) { - return ( -
- {/* Display the search query */} -

- Chat model wants to search using this query:{" "} - {searchQuery} -

+ return ( +
+ {/* Display the search query */} +

+ Chat model wants to search using this query:{' '} + {searchQuery} +

- {/* Human review form */} -
- - {humanReview.action === "feedback" && ( -