diff --git a/VisualQnA/docker/ui/docker/Dockerfile b/VisualQnA/docker/ui/docker/Dockerfile new file mode 100644 index 000000000..ac2bb7da3 --- /dev/null +++ b/VisualQnA/docker/ui/docker/Dockerfile @@ -0,0 +1,26 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Use node 20.11.1 as the base image +FROM node:20.11.1 + +# Update package manager and install Git +RUN apt-get update -y && apt-get install -y git + +# Copy the front-end code repository +COPY svelte /home/user/svelte + +# Set the working directory +WORKDIR /home/user/svelte + +# Install front-end dependencies +RUN npm install + +# Build the front-end application +RUN npm run build + +# Expose the port of the front-end application +EXPOSE 5173 + +# Run the front-end application in preview mode +CMD ["npm", "run", "preview", "--", "--port", "5173", "--host", "0.0.0.0"] \ No newline at end of file diff --git a/VisualQnA/docker/ui/svelte/.editorconfig b/VisualQnA/docker/ui/svelte/.editorconfig new file mode 100644 index 000000000..2b7a6637f --- /dev/null +++ b/VisualQnA/docker/ui/svelte/.editorconfig @@ -0,0 +1,10 @@ +[*] +indent_style = tab + +[package.json] +indent_style = space +indent_size = 2 + +[*.md] +indent_style = space +indent_size = 2 diff --git a/VisualQnA/docker/ui/svelte/.env b/VisualQnA/docker/ui/svelte/.env new file mode 100644 index 000000000..c6eadaf96 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/.env @@ -0,0 +1 @@ +BACKEND_BASE_URL = 'http://backend_address:8888/v1/visualqna' \ No newline at end of file diff --git a/VisualQnA/docker/ui/svelte/.eslintignore b/VisualQnA/docker/ui/svelte/.eslintignore new file mode 100644 index 000000000..38972655f --- /dev/null +++ b/VisualQnA/docker/ui/svelte/.eslintignore @@ -0,0 +1,13 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example + +# Ignore files for PNPM, NPM and YARN +pnpm-lock.yaml +package-lock.json +yarn.lock diff --git a/VisualQnA/docker/ui/svelte/.eslintrc.cjs b/VisualQnA/docker/ui/svelte/.eslintrc.cjs new file mode 100644 index 000000000..a6592d11f --- /dev/null +++ b/VisualQnA/docker/ui/svelte/.eslintrc.cjs @@ -0,0 +1,34 @@ +// Copyright (c) 2024 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +module.exports = { + root: true, + parser: "@typescript-eslint/parser", + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"], + plugins: ["svelte3", "@typescript-eslint", "neverthrow"], + ignorePatterns: ["*.cjs"], + overrides: [{ files: ["*.svelte"], processor: "svelte3/svelte3" }], + settings: { + "svelte3/typescript": () => require("typescript"), + }, + parserOptions: { + sourceType: "module", + ecmaVersion: 2020, + }, + env: { + browser: true, + es2017: true, + node: true, + }, +}; diff --git a/VisualQnA/docker/ui/svelte/.prettierignore b/VisualQnA/docker/ui/svelte/.prettierignore new file mode 100644 index 000000000..38972655f --- /dev/null +++ b/VisualQnA/docker/ui/svelte/.prettierignore @@ -0,0 +1,13 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* +!.env.example + +# Ignore files for PNPM, NPM and YARN +pnpm-lock.yaml +package-lock.json +yarn.lock diff --git a/VisualQnA/docker/ui/svelte/.prettierrc b/VisualQnA/docker/ui/svelte/.prettierrc new file mode 100644 index 000000000..c932dd178 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/.prettierrc @@ -0,0 +1 @@ +{"pluginSearchDirs": ["."], "overrides": [{"files": "*.svelte", "options": {"parser": "svelte"}}]} diff --git a/VisualQnA/docker/ui/svelte/package.json b/VisualQnA/docker/ui/svelte/package.json new file mode 100644 index 000000000..f10053e73 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/package.json @@ -0,0 +1,59 @@ +{ + "name": "sveltekit-auth-example", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "lint": "prettier --check . && eslint .", + "format": "prettier --write ." + }, + "devDependencies": { + "@fortawesome/free-solid-svg-icons": "6.2.0", + "@playwright/test": "^1.45.2", + "@sveltejs/adapter-auto": "1.0.0-next.75", + "@sveltejs/kit": "^1.30.4", + "@tailwindcss/typography": "0.5.7", + "@types/debug": "4.1.7", + "@typescript-eslint/eslint-plugin": "^5.27.0", + "@typescript-eslint/parser": "^5.27.0", + "autoprefixer": "^10.4.7", + "daisyui": "3.5.1", + "date-picker-svelte": "^2.6.0", + "debug": "4.3.4", + "eslint": "^8.16.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-neverthrow": "1.1.4", + "eslint-plugin-svelte3": "^4.0.0", + "postcss": "^8.4.31", + "postcss-load-config": "^4.0.1", + "postcss-preset-env": "^8.3.2", + "prettier": "^2.8.8", + "prettier-plugin-svelte": "^2.7.0", + "prettier-plugin-tailwindcss": "^0.3.0", + "svelte": "^3.59.1", + "svelte-check": "^2.7.1", + "svelte-fa": "3.0.3", + "svelte-preprocess": "^4.10.7", + "tailwindcss": "^3.1.5", + "tslib": "^2.3.1", + "typescript": "^4.7.4", + "vite": "^4.5.2" + }, + "type": "module", + "dependencies": { + "date-fns": "^2.30.0", + "driver.js": "^1.3.0", + "flowbite-svelte": "^0.38.5", + "flowbite-svelte-icons": "^1.4.0", + "fuse.js": "^6.6.2", + "lodash": "^4.17.21", + "ramda": "^0.29.0", + "sse.js": "^0.6.1", + "svelte-notifications": "^0.9.98", + "svrollbar": "^0.12.0" + } +} diff --git a/VisualQnA/docker/ui/svelte/playwright.config.ts b/VisualQnA/docker/ui/svelte/playwright.config.ts new file mode 100644 index 000000000..578a1c287 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/playwright.config.ts @@ -0,0 +1,54 @@ +// Copyright (C) 2024 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +import { defineConfig, devices } from "@playwright/test"; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: "./tests", + /* Maximum time one test can run for. */ + timeout: 30 * 1000, + expect: { + /** + * Maximum time expect() should wait for the condition to be met. + * For example in `await expect(locator).toHaveText();` + */ + timeout: 5000, + }, + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: [["html", { open: "never" }]], + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ + actionTimeout: 0, + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: "http://localhost:5173", + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: "on-first-retry", + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: "webkit", + use: { ...devices["Desktop Safari"] }, + }, + ], +}); diff --git a/VisualQnA/docker/ui/svelte/postcss.config.cjs b/VisualQnA/docker/ui/svelte/postcss.config.cjs new file mode 100644 index 000000000..b384b43eb --- /dev/null +++ b/VisualQnA/docker/ui/svelte/postcss.config.cjs @@ -0,0 +1,27 @@ +// Copyright (c) 2024 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +const tailwindcss = require("tailwindcss"); +const autoprefixer = require("autoprefixer"); + +const config = { + plugins: [ + //Some plugins, like tailwindcss/nesting, need to run before Tailwind, + tailwindcss(), + //But others, like autoprefixer, need to run after, + autoprefixer, + ], +}; + +module.exports = config; diff --git a/VisualQnA/docker/ui/svelte/src/app.d.ts b/VisualQnA/docker/ui/svelte/src/app.d.ts new file mode 100644 index 000000000..fa6a0abf7 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/app.d.ts @@ -0,0 +1,19 @@ +// Copyright (c) 2024 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// See: https://kit.svelte.dev/docs/types#app +// import { Result} from "neverthrow"; +interface Window { + deviceType: string; +} diff --git a/VisualQnA/docker/ui/svelte/src/app.html b/VisualQnA/docker/ui/svelte/src/app.html new file mode 100644 index 000000000..db69926ea --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/app.html @@ -0,0 +1,28 @@ + + + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/VisualQnA/docker/ui/svelte/src/app.postcss b/VisualQnA/docker/ui/svelte/src/app.postcss new file mode 100644 index 000000000..1bb14630c --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/app.postcss @@ -0,0 +1,86 @@ +/* Write your global styles here, in PostCSS syntax */ +@tailwind base; +@tailwind components; +@tailwind utilities; + +html, body { + height: 100%; +} + +.btn { + @apply flex-nowrap; +} +a.btn { + @apply no-underline; +} +.input { + @apply text-base; +} + +.bg-dark-blue { + background-color: #004a86; +} + +.bg-light-blue { + background-color: #0068b5; +} + +.bg-turquoise { + background-color: #00a3f6; +} + +.bg-header { + background-color: #ffffff; +} + +.bg-button { + background-color: #0068b5; +} + +.bg-title { + background-color: #f7f7f7; +} + +.text-header { + color: #0068b5; +} + +.text-button { + color: #252e47; +} + +.text-title-color { + color: rgb(38,38,38); +} + +.font-intel { + font-family: "intel-clear","tahoma",Helvetica,"helvetica",Arial,sans-serif; +} + +.font-title-intel { + font-family: "intel-one","intel-clear",Helvetica,Arial,sans-serif; +} + +.bg-footer { + background-color: #e7e7e7; +} + +.bg-light-green { + background-color: #d7f3a1; +} + +.bg-purple { + background-color: #653171; +} + +.bg-dark-blue { + background-color: #224678; +} + +.border-input-color { + border-color: #605e5c; +} + +.w-12\/12 { + width: 100% +} \ No newline at end of file diff --git a/VisualQnA/docker/ui/svelte/src/lib/assets/avatar/svelte/Delete.svelte b/VisualQnA/docker/ui/svelte/src/lib/assets/avatar/svelte/Delete.svelte new file mode 100644 index 000000000..8847a2227 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/assets/avatar/svelte/Delete.svelte @@ -0,0 +1,30 @@ + + + + + + { + dispatch('DeleteAvatar') }} +viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="20" height="20"> + + diff --git a/VisualQnA/docker/ui/svelte/src/lib/assets/chat/svelte/Assistant.svelte b/VisualQnA/docker/ui/svelte/src/lib/assets/chat/svelte/Assistant.svelte new file mode 100644 index 000000000..b68d2a08c --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/assets/chat/svelte/Assistant.svelte @@ -0,0 +1,44 @@ + + + diff --git a/VisualQnA/docker/ui/svelte/src/lib/assets/chat/svelte/PaperAirplane.svelte b/VisualQnA/docker/ui/svelte/src/lib/assets/chat/svelte/PaperAirplane.svelte new file mode 100644 index 000000000..d1d14077f --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/assets/chat/svelte/PaperAirplane.svelte @@ -0,0 +1,68 @@ + + + + + + + + diff --git a/VisualQnA/docker/ui/svelte/src/lib/assets/chat/svelte/PersonOutlined.svelte b/VisualQnA/docker/ui/svelte/src/lib/assets/chat/svelte/PersonOutlined.svelte new file mode 100644 index 000000000..dd2f9fdb7 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/assets/chat/svelte/PersonOutlined.svelte @@ -0,0 +1,26 @@ + + + + + diff --git a/VisualQnA/docker/ui/svelte/src/lib/assets/header/intelLogo.svelte b/VisualQnA/docker/ui/svelte/src/lib/assets/header/intelLogo.svelte new file mode 100644 index 000000000..50039d5b3 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/assets/header/intelLogo.svelte @@ -0,0 +1,49 @@ + + + + + + + + + diff --git a/VisualQnA/docker/ui/svelte/src/lib/assets/layout/css/driver.css b/VisualQnA/docker/ui/svelte/src/lib/assets/layout/css/driver.css new file mode 100644 index 000000000..453db6082 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/assets/layout/css/driver.css @@ -0,0 +1,94 @@ +.driverjs-theme { + background: transparent; + color: #fff; + box-shadow: none; + padding: 0; +} + +.driver-popover-arrow { + border: 10px solid transparent; + animation: blink 1s 3 steps(1); +} + +@keyframes blink { + 0% { + opacity: 1; + } + 50% { + opacity: 0.2; + } + 100% { + opacity: 1; + } +} + +.driver-popover.driverjs-theme .driver-popover-arrow-side-left.driver-popover-arrow { + border-left-color: #174ed1; +} + +.driver-popover.driverjs-theme .driver-popover-arrow-side-right.driver-popover-arrow { + border-right-color: #174ed1; +} + +.driver-popover.driverjs-theme .driver-popover-arrow-side-top.driver-popover-arrow { + border-top-color: #174ed1; +} + +.driver-popover.driverjs-theme .driver-popover-arrow-side-bottom.driver-popover-arrow { + border-bottom-color: #174ed1; +} + +.driver-popover-footer { + background: transparent; + color: #fff; +} +.driver-popover-title { + border-top-left-radius: 5px; + border-top-right-radius: 5px; +} + +.driver-popover-title, +.driver-popover-description { + display: block; + padding: 15px 15px 7px 15px; + background: #174ed1; + border: none; +} + +.driver-popover-close-btn { + color: #fff; +} + +.driver-popover-footer button:hover, +.driver-popover-footer button:focus { + background: #174ed1; + color: #fff; +} + +.driver-popover-description { + padding: 5px 15px; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; +} + +.driver-popover-title[style*="block"] + .driver-popover-description { + margin: 0; +} +.driver-popover-progress-text { + color: #fff; +} + +.driver-popover-footer button { + background: #174ed1; + border: 2px #174ed1 dashed; + color: #fff; + border-radius: 50%; + text-shadow: none; +} +.driver-popover-close-btn:hover, +.driver-popover-close-btn:focus { + color: #fff; +} +.driver-popover-navigation-btns button + button { + margin-left: 10px; +} diff --git a/VisualQnA/docker/ui/svelte/src/lib/assets/upload/help.svelte b/VisualQnA/docker/ui/svelte/src/lib/assets/upload/help.svelte new file mode 100644 index 000000000..adccf7bb5 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/assets/upload/help.svelte @@ -0,0 +1,24 @@ + + + diff --git a/VisualQnA/docker/ui/svelte/src/lib/assets/upload/next.svelte b/VisualQnA/docker/ui/svelte/src/lib/assets/upload/next.svelte new file mode 100644 index 000000000..70f4fe25e --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/assets/upload/next.svelte @@ -0,0 +1,31 @@ + + + diff --git a/VisualQnA/docker/ui/svelte/src/lib/assets/upload/previous.svelte b/VisualQnA/docker/ui/svelte/src/lib/assets/upload/previous.svelte new file mode 100644 index 000000000..c47d9c49d --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/assets/upload/previous.svelte @@ -0,0 +1,31 @@ + + + diff --git a/VisualQnA/docker/ui/svelte/src/lib/assets/voice/svg/paste.svg b/VisualQnA/docker/ui/svelte/src/lib/assets/voice/svg/paste.svg new file mode 100644 index 000000000..9fe89acc1 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/assets/voice/svg/paste.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/VisualQnA/docker/ui/svelte/src/lib/assets/voice/svg/uploadFile.svg b/VisualQnA/docker/ui/svelte/src/lib/assets/voice/svg/uploadFile.svg new file mode 100644 index 000000000..362a6994e --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/assets/voice/svg/uploadFile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/VisualQnA/docker/ui/svelte/src/lib/modules/chat/ChatMessage.svelte b/VisualQnA/docker/ui/svelte/src/lib/modules/chat/ChatMessage.svelte new file mode 100644 index 000000000..12261aa82 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/modules/chat/ChatMessage.svelte @@ -0,0 +1,71 @@ + + + + +
+
+ +
+
+
+

+ {@html msg.content} +

+
+
+
+{#if time} +
+ { + dispatch("scrollTop"); + }} + /> +
+{/if} + + diff --git a/VisualQnA/docker/ui/svelte/src/lib/modules/chat/MessageAvatar.svelte b/VisualQnA/docker/ui/svelte/src/lib/modules/chat/MessageAvatar.svelte new file mode 100644 index 000000000..0f6a24b96 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/modules/chat/MessageAvatar.svelte @@ -0,0 +1,30 @@ + + + + +{#if role === MessageRole.User} + +{:else} + +{/if} diff --git a/VisualQnA/docker/ui/svelte/src/lib/modules/chat/MessageTimer.svelte b/VisualQnA/docker/ui/svelte/src/lib/modules/chat/MessageTimer.svelte new file mode 100644 index 000000000..9416cc879 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/modules/chat/MessageTimer.svelte @@ -0,0 +1,68 @@ + + + + +
+
+
+ + { + dispatch("handleTop"); + }} + > +
+
+
+ +
+
+ End to End Time: +

{time}s

+
+
+
+
diff --git a/VisualQnA/docker/ui/svelte/src/lib/modules/frame/Layout.svelte b/VisualQnA/docker/ui/svelte/src/lib/modules/frame/Layout.svelte new file mode 100644 index 000000000..0c5b997d2 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/modules/frame/Layout.svelte @@ -0,0 +1,48 @@ + + + + +
+
+
+ + + +
+
+
diff --git a/VisualQnA/docker/ui/svelte/src/lib/modules/upload/upload.svelte b/VisualQnA/docker/ui/svelte/src/lib/modules/upload/upload.svelte new file mode 100644 index 000000000..384deba9d --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/modules/upload/upload.svelte @@ -0,0 +1,60 @@ + + + + +
+

Upload Images

+ +
or +
+ + + + +
+

Parameters

+ +

Max output tokens: {stepValue}

+
+ +
+ + +
+
+
+ +{#if UseShow} +
+

Terms of use

+

+ By using this service, users are required to agree to the following terms: + The service is a research preview intended for non-commercial use only. It + only provides limited safety measures and may generate offensive content. + It must not be used for any illegal, harmful, violent, racist, or sexual + purposes. The service may collect user dialogue data for future research. + Please click the "Flag" button if you get any inappropriate answer! We + will collect those to keep improving our moderator. For an optimal + experience, please use desktop computers for this demo, as mobile devices + may compromise its quality. +

+
+{/if} diff --git a/VisualQnA/docker/ui/svelte/src/lib/modules/upload/uploadImg.svelte b/VisualQnA/docker/ui/svelte/src/lib/modules/upload/uploadImg.svelte new file mode 100644 index 000000000..3aade23e7 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/modules/upload/uploadImg.svelte @@ -0,0 +1,87 @@ + + + + + { + event.preventDefault(); + }} + on:change={handleChange} +> + + {#if value.length === 0} +

+ Click to upload or drag and drop +

+

+ SVG, PNG, JPG +

+ {:else} +

{showFiles(value)}

+ {/if} +
diff --git a/VisualQnA/docker/ui/svelte/src/lib/network/chat/Network.ts b/VisualQnA/docker/ui/svelte/src/lib/network/chat/Network.ts new file mode 100644 index 000000000..2381054c6 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/network/chat/Network.ts @@ -0,0 +1,34 @@ +// Copyright (c) 2024 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { env } from "$env/dynamic/public"; +import { SSE } from "sse.js"; + +const BACKEND_BASE_URL = env.BACKEND_BASE_URL; + +export async function fetchTextStream(query: string, knowledge_base_id: string, isCheckedStore: boolean) { + let payload = {}; + let url = ""; + + payload = { + messages: query, + stream: "True", + }; + url = `${BACKEND_BASE_URL}`; + + return new SSE(url, { + headers: { "Content-Type": "application/json" }, + payload: JSON.stringify(payload), + }); +} diff --git a/VisualQnA/docker/ui/svelte/src/lib/network/upload/Network.ts b/VisualQnA/docker/ui/svelte/src/lib/network/upload/Network.ts new file mode 100644 index 000000000..284494f85 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/network/upload/Network.ts @@ -0,0 +1,57 @@ +// Copyright (c) 2024 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { env } from "$env/dynamic/public"; + +const BACKEND_BASE_URL = env.BACKEND_BASE_URL; + +export async function fetchKnowledgeBaseId(file: Blob, fileName: string) { + const url = `${BACKEND_BASE_URL}/create`; + const formData = new FormData(); + formData.append("file", file, fileName); + const init: RequestInit = { + method: "POST", + body: formData, + }; + + try { + const response = await fetch(url, init); + if (!response.ok) throw response.status; + return await response.json(); + } catch (error) { + console.error("network error: ", error); + return undefined; + } +} + +export async function fetchKnowledgeBaseIdByPaste(pasteUrlList: any, urlType: string | undefined) { + const url = `${BACKEND_BASE_URL}/upload_link`; + const data = { + link_list: pasteUrlList, + }; + const init: RequestInit = { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(data), + }; + + try { + const response = await fetch(url, init); + if (!response.ok) throw response.status; + return await response.json(); + } catch (error) { + console.error("network error: ", error); + return undefined; + } +} diff --git a/VisualQnA/docker/ui/svelte/src/lib/shared/Utils.ts b/VisualQnA/docker/ui/svelte/src/lib/shared/Utils.ts new file mode 100644 index 000000000..fb182cef6 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/shared/Utils.ts @@ -0,0 +1,54 @@ +// Copyright (c) 2024 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +export function scrollToBottom(scrollToDiv: HTMLElement) { + if (scrollToDiv) { + setTimeout( + () => + scrollToDiv.scroll({ + behavior: "auto", + top: scrollToDiv.scrollHeight, + }), + 100, + ); + } +} + +export function scrollToTop(scrollToDiv: HTMLElement) { + if (scrollToDiv) { + setTimeout( + () => + scrollToDiv.scroll({ + behavior: "auto", + top: 0, + }), + 100, + ); + } +} + +export function getCurrentTimeStamp() { + return Math.floor(new Date().getTime()); +} + +export function fromTimeStampToTime(timeStamp: number) { + return new Date(timeStamp * 1000).toTimeString().slice(0, 8); +} + +export function formatTime(seconds) { + const hours = String(Math.floor(seconds / 3600)).padStart(2, "0"); + const minutes = String(Math.floor((seconds % 3600) / 60)).padStart(2, "0"); + const remainingSeconds = String(seconds % 60).padStart(2, "0"); + return `${hours}:${minutes}:${remainingSeconds}`; +} diff --git a/VisualQnA/docker/ui/svelte/src/lib/shared/components/header/header.svelte b/VisualQnA/docker/ui/svelte/src/lib/shared/components/header/header.svelte new file mode 100644 index 000000000..c851dec98 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/shared/components/header/header.svelte @@ -0,0 +1,33 @@ + + + +
+ +
diff --git a/VisualQnA/docker/ui/svelte/src/lib/shared/components/loading/Loading.svelte b/VisualQnA/docker/ui/svelte/src/lib/shared/components/loading/Loading.svelte new file mode 100644 index 000000000..51e89cfe7 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/shared/components/loading/Loading.svelte @@ -0,0 +1,48 @@ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/VisualQnA/docker/ui/svelte/src/lib/shared/components/scrollbar/Scrollbar.svelte b/VisualQnA/docker/ui/svelte/src/lib/shared/components/scrollbar/Scrollbar.svelte new file mode 100644 index 000000000..f18e23e69 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/shared/components/scrollbar/Scrollbar.svelte @@ -0,0 +1,48 @@ + + + + +
+ +
+ +
+
+
+ + diff --git a/VisualQnA/docker/ui/svelte/src/lib/shared/constant/Interface.ts b/VisualQnA/docker/ui/svelte/src/lib/shared/constant/Interface.ts new file mode 100644 index 000000000..221f17a26 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/shared/constant/Interface.ts @@ -0,0 +1,47 @@ +// Copyright (c) 2024 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +export enum MessageRole { + Assistant, + User, +} + +export enum MessageType { + Text, + SingleAudio, + AudioList, + SingleImage, + ImageList, + singleVideo, +} + +type Map = T extends MessageType.Text | MessageType.SingleAudio + ? string + : T extends MessageType.AudioList + ? string[] + : T extends MessageType.SingleImage + ? { imgSrc: string; imgId: string } + : { imgSrc: string; imgId: string }[]; + +export interface Message { + role: MessageRole; + type: MessageType; + content: Map; + time: number; +} + +export enum LOCAL_STORAGE_KEY { + STORAGE_CHAT_KEY = "chatMessages", + STORAGE_TIME_KEY = "initTime", +} diff --git a/VisualQnA/docker/ui/svelte/src/lib/shared/stores/common/Store.ts b/VisualQnA/docker/ui/svelte/src/lib/shared/stores/common/Store.ts new file mode 100644 index 000000000..19a120497 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/lib/shared/stores/common/Store.ts @@ -0,0 +1,41 @@ +// Copyright (c) 2024 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { writable } from "svelte/store"; + +export let open = writable(true); + +export let knowledgeAccess = writable(true); + +export let showTemplate = writable(false); + +export let showSidePage = writable(false); + +export let droppedObj = writable({}); + +export let isLoading = writable(false); + +export let newUploadNum = writable(0); + +export let ifStoreMsg = writable(true); + +export let isCheckedStore = writable(false); + +export const resetControl = writable(false); + +export const knowledge1 = writable<{ + id: string; +}>(); + +export const knowledgeName = writable(""); diff --git a/VisualQnA/docker/ui/svelte/src/routes/+layout.svelte b/VisualQnA/docker/ui/svelte/src/routes/+layout.svelte new file mode 100644 index 000000000..8141177d4 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/routes/+layout.svelte @@ -0,0 +1,48 @@ + + + + + + +
+ +
+ +
+
diff --git a/VisualQnA/docker/ui/svelte/src/routes/+page.svelte b/VisualQnA/docker/ui/svelte/src/routes/+page.svelte new file mode 100644 index 000000000..16ddab3ed --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/routes/+page.svelte @@ -0,0 +1,284 @@ + + + + +
+
+
+ +
+
+
+
+
+
+ { + if (event.key === "Enter" && !event.shiftKey && query) { + event.preventDefault(); + handleTextSubmit(); + } + }} + /> + +
+
+
+ + + {#if Array.isArray(chatMessages) && chatMessages.length > 0 && !loading} +
+
+ +
+
+ {/if} + + +
+ + {#each chatMessages as message, i} + handleTop()} + msg={message} + time={i === 0 || (message.time > 0 && message.time < 100) + ? message.time + : ""} + /> + {/each} + + + {#if loading} + + {/if} +
+ +
+
+ +
+ + diff --git a/VisualQnA/docker/ui/svelte/src/routes/+page.ts b/VisualQnA/docker/ui/svelte/src/routes/+page.ts new file mode 100644 index 000000000..f4de8d676 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/src/routes/+page.ts @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { browser } from "$app/environment"; +import { LOCAL_STORAGE_KEY } from "$lib/shared/constant/Interface"; + +export const load = async () => { + if (browser) { + const chat = localStorage.getItem(LOCAL_STORAGE_KEY.STORAGE_CHAT_KEY); + + return { + chatMsg: JSON.parse(chat || "[]"), + }; + } +}; diff --git a/VisualQnA/docker/ui/svelte/static/favicon.png b/VisualQnA/docker/ui/svelte/static/favicon.png new file mode 100644 index 000000000..75b997f81 Binary files /dev/null and b/VisualQnA/docker/ui/svelte/static/favicon.png differ diff --git a/VisualQnA/docker/ui/svelte/svelte.config.js b/VisualQnA/docker/ui/svelte/svelte.config.js new file mode 100644 index 000000000..0f2977ecc --- /dev/null +++ b/VisualQnA/docker/ui/svelte/svelte.config.js @@ -0,0 +1,38 @@ +// Copyright (c) 2024 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import adapter from "@sveltejs/adapter-auto"; +import preprocess from "svelte-preprocess"; +import postcssPresetEnv from "postcss-preset-env"; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://github.com/sveltejs/svelte-preprocess + // for more information about preprocessors + preprocess: preprocess({ + sourceMap: true, + postcss: { + plugins: [postcssPresetEnv({ features: { "nesting-rules": true } })], + }, + }), + + kit: { + adapter: adapter(), + env: { + publicPrefix: "", + }, + }, +}; + +export default config; diff --git a/VisualQnA/docker/ui/svelte/tailwind.config.cjs b/VisualQnA/docker/ui/svelte/tailwind.config.cjs new file mode 100644 index 000000000..6cc3a8b95 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/tailwind.config.cjs @@ -0,0 +1,43 @@ +// Copyright (c) 2024 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +const config = { + content: ["./src/**/*.{html,js,svelte,ts}", "./node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}"], + + plugins: [require("flowbite/plugin")], + + darkMode: "class", + + theme: { + extend: { + colors: { + // flowbite-svelte + primary: { + 50: "#FFF5F2", + 100: "#FFF1EE", + 200: "#FFE4DE", + 300: "#FFD5CC", + 400: "#FFBCAD", + 500: "#FE795D", + 600: "#EF562F", + 700: "#EB4F27", + 800: "#CC4522", + 900: "#A5371B", + }, + }, + }, + }, +}; + +module.exports = config; diff --git a/VisualQnA/docker/ui/svelte/tsconfig.json b/VisualQnA/docker/ui/svelte/tsconfig.json new file mode 100644 index 000000000..0f47472f7 --- /dev/null +++ b/VisualQnA/docker/ui/svelte/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + } +} diff --git a/VisualQnA/docker/ui/svelte/vite.config.ts b/VisualQnA/docker/ui/svelte/vite.config.ts new file mode 100644 index 000000000..1166165dc --- /dev/null +++ b/VisualQnA/docker/ui/svelte/vite.config.ts @@ -0,0 +1,23 @@ +// Copyright (c) 2024 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { sveltekit } from "@sveltejs/kit/vite"; +import type { UserConfig } from "vite"; + +const config: UserConfig = { + plugins: [sveltekit()], + server: {}, +}; + +export default config;