Skip to content

Commit

Permalink
Adjustment to api and layout (#16)
Browse files Browse the repository at this point in the history
* Add generic api config

* Order of location

* Prohibit build on PR conditional

* Add local dev proxy config

* Remove font integrations

* Scroll and layout adjustments

* Adjust build dist dirs

* remove folder dist on build

* Add Autogrow for ui input

* Add appsettings and toolbar

* Adjust appsettings to load onmounted

* Support html in disclaimer text

* Improve error handling

* Update ui/src/api/index.ts

Co-authored-by: Bourne93 <[email protected]>

---------

Co-authored-by: Bourne93 <[email protected]>
  • Loading branch information
selamanse and Bourne93 authored Nov 17, 2023
1 parent 7014613 commit 453711f
Show file tree
Hide file tree
Showing 12 changed files with 177 additions and 82 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/build_and_deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ on:
- "!jupyter/**"
- "!ui/**"
pull_request:
branches:
- main
paths:
- "!jupyter/**"
- "!ui/**"

env:
GCLOUD_PROJECT_ID: ${{ secrets.GCLOUD_PROJECT_ID }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build_ui.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
uses: actions/download-artifact@v3
with:
name: static-files
path: ui/dist/
path: ui/dist/spa/
- name: Display structure of downloaded files
run: ls -R
- name: Docker meta
Expand Down
3 changes: 2 additions & 1 deletion ui/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ FROM nginx:1.25
LABEL org.opencontainers.image.source = "https://github.com/deepshore/knowledge-chatbot"

# Copy the build output to replace the default nginx contents.
COPY dist /usr/share/nginx/html
COPY dist/spa /usr/share/nginx/html

COPY /webserver/nginx.conf /etc/nginx/conf.d/default.conf
COPY /webserver/appsettings.json /usr/share/nginx/html/appsettings.json

EXPOSE 80
2 changes: 1 addition & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"format": "prettier --write \"**/*.{js,ts,vue,scss,html,md,json}\" --ignore-path .gitignore",
"test": "echo \"No test specified\" && exit 0",
"dev": "quasar dev",
"build": "quasar build",
"build": "rimraf dist/ && quasar build",
"clean": "rimraf dist/ node_modules/"
},
"dependencies": {
Expand Down
62 changes: 38 additions & 24 deletions ui/quasar.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ module.exports = configure(function (ctx) {
tsCheckerConfig: {
eslint: {
enabled: true,
files: './src/**/*.{ts,tsx,js,jsx,vue}'
}
}
files: './src/**/*.{ts,tsx,js,jsx,vue}',
},
},
},

// https://v2.quasar.dev/quasar-cli-webpack/prefetch-feature
Expand All @@ -45,13 +45,13 @@ module.exports = configure(function (ctx) {
// 'line-awesome',
// 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!

'roboto-font', // optional, you are not bound to it
'material-icons' // optional, you are not bound to it
//'roboto-font', // optional, you are not bound to it
'material-icons', // optional, you are not bound to it
],

// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-build
build: {
vueRouterMode: 'hash' // available values: 'hash', 'history'
vueRouterMode: 'hash', // available values: 'hash', 'history'

// transpile: false,
// publicPath: '/',
Expand All @@ -77,11 +77,25 @@ module.exports = configure(function (ctx) {

// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-devServer
devServer: {
proxy: {
// proxy all requests starting with /chatbot
'/chatbot': {
target: 'http://localhost:8080',
changeOrigin: false,
secure: false,
},
'/appsettings': {
target: 'http://localhost:8080',
changeOrigin: false,
secure: false,
},
},
server: {
type: 'http'
type: 'http',
},
port: 8080,
open: true // opens browser window automatically
host: '0.0.0.0',
port: 8081,
open: true, // opens browser window automatically
},

// https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-framework
Expand All @@ -99,7 +113,7 @@ module.exports = configure(function (ctx) {
// directives: [],

// Quasar plugins
plugins: []
plugins: [],
},

// animations: 'all', // --- includes all animations
Expand All @@ -123,8 +137,8 @@ module.exports = configure(function (ctx) {

middlewares: [
ctx.prod ? 'compression' : '',
'render' // keep this as last one
]
'render', // keep this as last one
],
},

// https://v2.quasar.dev/quasar-cli-webpack/developing-pwa/configuring-pwa
Expand All @@ -148,30 +162,30 @@ module.exports = configure(function (ctx) {
{
src: 'icons/icon-128x128.png',
sizes: '128x128',
type: 'image/png'
type: 'image/png',
},
{
src: 'icons/icon-192x192.png',
sizes: '192x192',
type: 'image/png'
type: 'image/png',
},
{
src: 'icons/icon-256x256.png',
sizes: '256x256',
type: 'image/png'
type: 'image/png',
},
{
src: 'icons/icon-384x384.png',
sizes: '384x384',
type: 'image/png'
type: 'image/png',
},
{
src: 'icons/icon-512x512.png',
sizes: '512x512',
type: 'image/png'
}
]
}
type: 'image/png',
},
],
},
},

// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-cordova-apps/configuring-cordova
Expand All @@ -181,7 +195,7 @@ module.exports = configure(function (ctx) {

// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-capacitor-apps/configuring-capacitor
capacitor: {
hideSplashscreen: true
hideSplashscreen: true,
},

// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/developing-electron-apps/configuring-electron
Expand All @@ -202,7 +216,7 @@ module.exports = configure(function (ctx) {
builder: {
// https://www.electron.build/configuration/configuration

appId: 'knowledge-chatbot'
appId: 'knowledge-chatbot',
},

// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
Expand All @@ -215,7 +229,7 @@ module.exports = configure(function (ctx) {
chainWebpackPreload(/* chain */) {
// do something with the Electron main process Webpack cfg
// extendWebpackPreload also available besides this chainWebpackPreload
}
}
},
},
};
});
12 changes: 11 additions & 1 deletion ui/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { api } from 'boot/axios';
import { DeepshoreChatRequest, DeepshoreChatResponse } from 'src/types/chat';
import { AppSettings } from '../types/appsettings';

export async function sendQuestion(
data: DeepshoreChatRequest
): Promise<DeepshoreChatResponse> {
const response = await api.post('http://0.0.0.0:8080/chatbot', data);
try {
const response = await api.post('/chatbot', data);
return response.data;
} catch (e) {
return { 'error': JSON.stringify(e), 'answer': '', 'related_articles': [] }
}
}

export async function getAppSettings(): Promise<AppSettings> {
const response = await api.get('/appsettings');
return response.data;
}
84 changes: 67 additions & 17 deletions ui/src/components/ChatComponent.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
<template>
<div class="row justify-center chat-row">
<div class="chat-div">
<q-chat-message :label="chatLabel" role="heading" aria-level="1" />
<div class="justify-center chat-div">
<q-btn round size="sm" color="white" @click="loadToolbar" >
<q-avatar size="42px">
<img :src="'/user/themes/deepshore/images/' + appSettings.icon">
</q-avatar>
</q-btn>
<q-dialog v-model="toolbar">
<q-card>
<q-toolbar>
<q-avatar>
<img :src="'/user/themes/deepshore/images/' + appSettings.icon">
</q-avatar>

<q-toolbar-title><span class="text-weight-bold">{{ appSettings.title }}</span></q-toolbar-title>

<q-btn flat round dense icon="close" v-close-popup />
</q-toolbar>

<q-card-section>
<div v-html="appSettings.disclaimer"></div>
</q-card-section>
</q-card>
</q-dialog>
<q-scroll-area ref="chatScrollRef" class="chat-scroll">
<div class="chat-message"><q-chat-message :label="chatLabel" role="heading" aria-level="1" /></div>
<div class="chat-message">
<q-chat-message
v-for="msg in chat"
:key="msg.id"
Expand All @@ -11,7 +34,7 @@
:avatar="msg.avatar"
:sent="msg.sent"
:text-html="msg.textHtml"
size="10"
size="8"
>
<q-spinner-dots v-if="msg.text.length == 0" size="md" />
<div
Expand All @@ -23,12 +46,14 @@
</div>
</q-chat-message>
</div>
</q-scroll-area>
<div class="chat-input-div">
<q-input
outlined
v-model="message"
placeholder="Nachricht"
@keyup.enter="addMessage"
:autogrow="true"
>
<template v-slot:after>
<q-btn
Expand All @@ -48,25 +73,36 @@
</template>

<script setup lang="ts">
import { ref, computed, Ref } from 'vue';
import { ref, computed, Ref, onMounted } from 'vue';
import { date } from 'quasar';
import { sendQuestion } from 'src/api/index';
import { sendQuestion, getAppSettings } from 'src/api/index';
import {
DeepshoreChatMessage,
DeepshoreChatRequest,
DeepshoreChatResponse,
} from 'src/types/chat';
import { AppSettings } from 'src/types/appsettings';
// data
const chatScrollRef = ref('chatScrollRef')
let toolbar = ref(true)
const defaultAppSettings: AppSettings = {
title: 'Knowledge Chatbot',
disclaimer: 'Lorem ipsum<br />dolorem' ,
icon: 'deepshore.png'
}
const appSettings: Ref<AppSettings> = ref(defaultAppSettings)
onMounted(async () => {
appSettings.value = await getAppSettings()
})
let message = ref('');
let chat: Ref<Array<DeepshoreChatMessage>> = ref([]);
let blockedAPI = ref(false);
const errMessages = [
'Ich habe die Frage leider nicht verstanden. Bitte versuche es mit einer anderen Formulierung.',
'Ich habe leider keine Antwort parat. Kannst du die Frage anders formulieren?',
'Tut mir leid, aber ich kann deine Frage leider nicht beantworten. Bitte versuche es mit einer anderen Formulierung.',
'Könntest du die Frage bitte noch einmal anders formulieren?',
];
// computed
const isDisabled = computed(() => {
Expand All @@ -88,6 +124,14 @@ const chatLabel = computed(() => {
// Methods
/**
* Load toolbar content if not already done then show tooltip
*/
async function loadToolbar(): Promise<void> {
toolbar.value = true;
appSettings.value = await getAppSettings();
}
/**
* Add user question to chat, get answer from chatbot backend and add that answer to chat.
*/
Expand Down Expand Up @@ -130,14 +174,17 @@ async function addMessage(): Promise<void> {
const response = await sendQuestion(body);
let answer: string;
if (response.error) {
answer = errMessages[getRandomInt(errMessages.length - 1)];
answer = 'Leider ist ein Fehler aufgetreten. Bitte versuche es doch noch einmal.';
console.log(response.error)
} else {
answer = buildAnswerText(response);
}
// Update Answer
chat.value[chat.value.length - 1].text = answer;
// Allow more requests
blockedAPI.value = false;
adjustScroll()
}
/**
Expand All @@ -162,11 +209,8 @@ async function addMessage(): Promise<void> {
// Start of additional article answer part
let articleText = '</br></br>Weiterführende Artikel:<ul>';
for (let article of articles) {
// Get display name for article links if format: 'https://deepshore.de/knowledge/chatgpt-nlp'
let articleNames = article.split('/');
let articleName = articleNames[articleNames.length - 1];
// Concate links as <a> tag list entries
articleText = `${articleText}<li><a href="${article}" target="_blank">${articleName}</li>`;
articleText = `${articleText}<li><a href="${article}" target="_blank">${article}</li>`;
}
// Close unsorted list
articleText = `${articleText}</ul>`;
Expand All @@ -190,5 +234,11 @@ async function addMessage(): Promise<void> {
function getRandomInt(max: number): number {
return Math.floor(Math.random() * max);
}
function adjustScroll () {
chatScrollRef.value.setScrollPercentage('vertical', 1.5, 500)
}
}
</script>
18 changes: 10 additions & 8 deletions ui/src/css/app.scss
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
// app global css in SCSS form
body {
font-family: 'Saira', sans-serif;
}
.chat-div {
font-family: 'Saira', sans-serif;
width: 100%;
max-height: 85vh;
min-height: 50vh;
overflow-x: auto;
padding: 1em !important;
}

.chat-scroll {
width: 100%;
height: 90%;
max-height: 90%;
}

.chat-row {
width: 66%;
padding: 1em !important;
}
.chat-input-div {
width: 100%;
height: 10%;
width: 100%;
}
Loading

0 comments on commit 453711f

Please sign in to comment.