Merge branch 'dev/nicolas/staging-prep' of git.targo.ca:Targo/targo_frontend into dev/nicolas/staging-prep
This commit is contained in:
commit
0ac68d3d00
192
package-lock.json
generated
192
package-lock.json
generated
|
|
@ -123,9 +123,9 @@
|
|||
"license": "(Apache-2.0 AND BSD-3-Clause)"
|
||||
},
|
||||
"node_modules/@cypress/request": {
|
||||
"version": "3.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.9.tgz",
|
||||
"integrity": "sha512-I3l7FdGRXluAS44/0NguwWlO83J18p0vlr2FYHrJkWdNYhgVoiYo61IXPqaOsL+vNxU1ZqMACzItGK3/KKDsdw==",
|
||||
"version": "3.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.10.tgz",
|
||||
"integrity": "sha512-hauBrOdvu08vOsagkZ/Aju5XuiZx6ldsLfByg1htFeldhex+PeMrYauANzFsMJeAA0+dyPLbDoX2OYuvVoLDkQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
|
|
@ -142,7 +142,7 @@
|
|||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "6.14.0",
|
||||
"qs": "~6.14.1",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "^5.0.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
|
|
@ -3182,24 +3182,24 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "1.20.3",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
||||
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
|
||||
"version": "1.20.4",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz",
|
||||
"integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
"bytes": "~3.1.2",
|
||||
"content-type": "~1.0.5",
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"destroy": "1.2.0",
|
||||
"http-errors": "2.0.0",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "2.4.1",
|
||||
"qs": "6.13.0",
|
||||
"raw-body": "2.5.2",
|
||||
"destroy": "~1.2.0",
|
||||
"http-errors": "~2.0.1",
|
||||
"iconv-lite": "~0.4.24",
|
||||
"on-finished": "~2.4.1",
|
||||
"qs": "~6.14.0",
|
||||
"raw-body": "~2.5.3",
|
||||
"type-is": "~1.6.18",
|
||||
"unpipe": "1.0.0"
|
||||
"unpipe": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8",
|
||||
|
|
@ -3216,6 +3216,27 @@
|
|||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser/node_modules/http-errors": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
||||
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"depd": "~2.0.0",
|
||||
"inherits": "~2.0.4",
|
||||
"setprototypeof": "~1.2.0",
|
||||
"statuses": "~2.0.2",
|
||||
"toidentifier": "~1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
|
|
@ -3223,20 +3244,14 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/body-parser/node_modules/qs": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||
"node_modules/body-parser/node_modules/statuses": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.0.6"
|
||||
},
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/boolbase": {
|
||||
|
|
@ -4995,40 +5010,40 @@
|
|||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
||||
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
|
||||
"version": "4.22.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz",
|
||||
"integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.8",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.20.3",
|
||||
"content-disposition": "0.5.4",
|
||||
"body-parser": "~1.20.3",
|
||||
"content-disposition": "~0.5.4",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.7.1",
|
||||
"cookie-signature": "1.0.6",
|
||||
"cookie": "~0.7.1",
|
||||
"cookie-signature": "~1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"encodeurl": "~2.0.0",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "1.3.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "2.0.0",
|
||||
"finalhandler": "~1.3.1",
|
||||
"fresh": "~0.5.2",
|
||||
"http-errors": "~2.0.0",
|
||||
"merge-descriptors": "1.0.3",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "2.4.1",
|
||||
"on-finished": "~2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.12",
|
||||
"path-to-regexp": "~0.1.12",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "6.13.0",
|
||||
"qs": "~6.14.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.2.1",
|
||||
"send": "0.19.0",
|
||||
"serve-static": "1.16.2",
|
||||
"send": "~0.19.0",
|
||||
"serve-static": "~1.16.2",
|
||||
"setprototypeof": "1.2.0",
|
||||
"statuses": "2.0.1",
|
||||
"statuses": "~2.0.1",
|
||||
"type-is": "~1.6.18",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
|
|
@ -5058,22 +5073,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/express/node_modules/qs": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
|
|
@ -5578,9 +5577,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "10.4.5",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
|
||||
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
|
||||
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
|
|
@ -6310,9 +6309,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
|
||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
@ -7394,9 +7393,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/node-forge": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
|
||||
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz",
|
||||
"integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==",
|
||||
"dev": true,
|
||||
"license": "(BSD-3-Clause OR GPL-2.0)",
|
||||
"engines": {
|
||||
|
|
@ -8039,9 +8038,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.14.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
|
||||
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
|
||||
"version": "6.14.1",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
|
||||
"integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
|
|
@ -8111,21 +8110,52 @@
|
|||
}
|
||||
},
|
||||
"node_modules/raw-body": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
|
||||
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz",
|
||||
"integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
"http-errors": "2.0.0",
|
||||
"iconv-lite": "0.4.24",
|
||||
"unpipe": "1.0.0"
|
||||
"bytes": "~3.1.2",
|
||||
"http-errors": "~2.0.1",
|
||||
"iconv-lite": "~0.4.24",
|
||||
"unpipe": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/raw-body/node_modules/http-errors": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
||||
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"depd": "~2.0.0",
|
||||
"inherits": "~2.0.4",
|
||||
"setprototypeof": "~1.2.0",
|
||||
"statuses": "~2.0.2",
|
||||
"toidentifier": "~1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/raw-body/node_modules/statuses": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
|
||||
|
|
@ -9879,9 +9909,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "6.3.6",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.6.tgz",
|
||||
"integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==",
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
|
||||
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -3,14 +3,8 @@
|
|||
setup
|
||||
>
|
||||
import { useUiStore } from 'src/stores/ui-store';
|
||||
import { useAuthStore } from 'src/stores/auth-store';
|
||||
import { useChatbotStore } from 'src/stores/chatbot-store';
|
||||
|
||||
// import HeaderBarNotification from './main-layout-header-bar-notification.vue';
|
||||
|
||||
const uiStore = useUiStore();
|
||||
const chatbot_store = useChatbotStore();
|
||||
const auth_store = useAuthStore();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -37,19 +31,6 @@
|
|||
/>
|
||||
</q-btn>
|
||||
</q-toolbar-title>
|
||||
|
||||
<q-item class="q-pa-none">
|
||||
<!-- <HeaderBarNotification /> -->
|
||||
<q-btn
|
||||
v-if="auth_store.user?.user_module_access.includes('chatbot')"
|
||||
flat
|
||||
color="transparant"
|
||||
icon="las la-robot"
|
||||
size="lg"
|
||||
@click="chatbot_store.is_showing_chatbot = !chatbot_store.is_showing_chatbot"
|
||||
style="--q-icon-size: 28px; min-width: auto;"
|
||||
/>
|
||||
</q-item>
|
||||
</q-toolbar>
|
||||
</q-header>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@
|
|||
import { onMounted, watch, ref } from 'vue';
|
||||
import { RouterView } from 'vue-router';
|
||||
import { useUiStore } from 'src/stores/ui-store';
|
||||
import { useAuthStore } from 'src/stores/auth-store';
|
||||
|
||||
|
||||
const ui_store = useUiStore();
|
||||
const auth_store = useAuthStore();
|
||||
const user_preferences = ref(ui_store.user_preferences);
|
||||
|
||||
onMounted(async () => {
|
||||
|
|
@ -36,7 +38,7 @@
|
|||
|
||||
<LeftDrawer />
|
||||
|
||||
<ChatbotDrawer />
|
||||
<ChatbotDrawer v-if="auth_store.user?.user_module_access.includes('chatbot')"/>
|
||||
|
||||
<q-page-container>
|
||||
<router-view />
|
||||
|
|
|
|||
|
|
@ -12,10 +12,14 @@
|
|||
const chatbot_store = useChatbotStore();
|
||||
|
||||
const text = ref('');
|
||||
const is_showing_right_drawer = ref(true);
|
||||
const drawer_width = ref(85);
|
||||
|
||||
const handleSend = async () => {
|
||||
await chatbot_api.sendMessage(text.value.trim());
|
||||
const message = text.value.trim();
|
||||
text.value = '';
|
||||
console.log('message: ', message, ', length: ', message.length);
|
||||
await chatbot_api.sendMessage(message);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
|
|
@ -25,12 +29,35 @@
|
|||
|
||||
<template>
|
||||
<q-drawer
|
||||
v-model="chatbot_store.is_showing_chatbot"
|
||||
v-model="is_showing_right_drawer"
|
||||
overlay
|
||||
persistent
|
||||
:width="drawer_width"
|
||||
side="right"
|
||||
:width="500"
|
||||
class="column justify-end no-wrap"
|
||||
class="column justify-end no-wrap relative-position no-scroll"
|
||||
>
|
||||
<transition
|
||||
enter-active-class="animated fadeInRight"
|
||||
leave-active-class="animated fadeOutRight"
|
||||
mode="out-in"
|
||||
@after-leave="chatbot_store.is_showing_chatbot ? drawer_width = 500 : drawer_width = 85"
|
||||
>
|
||||
<div
|
||||
v-if="chatbot_store.is_showing_chatbot"
|
||||
class="col column"
|
||||
style="background: rgba(0, 0, 0, 0.7); overflow: hidden;"
|
||||
>
|
||||
<q-btn
|
||||
dense
|
||||
icon="las la-chevron-right"
|
||||
text-color="white"
|
||||
color="accent"
|
||||
align="left"
|
||||
size="2em"
|
||||
class="q-mb-sm"
|
||||
@click="chatbot_store.is_showing_chatbot = false"
|
||||
/>
|
||||
|
||||
<div class="col q-px-md relative-position">
|
||||
<DialogueContent class="absolute-full" />
|
||||
</div>
|
||||
|
|
@ -48,28 +75,33 @@
|
|||
label-color="white"
|
||||
class="col q-px-md"
|
||||
style="background: rgba(0, 0, 0, 0.3);"
|
||||
@keyup.enter="handleSend"
|
||||
@keydown.enter="handleSend"
|
||||
/>
|
||||
|
||||
<!-- <q-input
|
||||
v-model="custId"
|
||||
:label="'Customer Id'"
|
||||
:autogrow="false"
|
||||
class="col"
|
||||
style="margin-left: 8px;"
|
||||
@keyup.enter="handleCustomerId"
|
||||
/> -->
|
||||
</q-form>
|
||||
</div>
|
||||
|
||||
<!-- <div
|
||||
class="drag-handle"
|
||||
@mousedown.prevent="startDrag"
|
||||
></div> -->
|
||||
|
||||
<div
|
||||
v-else
|
||||
class="row col-auto q-pa-sm self-end"
|
||||
>
|
||||
<q-btn
|
||||
dense
|
||||
round
|
||||
icon="las la-robot"
|
||||
color="accent"
|
||||
size="2em"
|
||||
class="shadow-5"
|
||||
@click="chatbot_store.is_showing_chatbot = true"
|
||||
/>
|
||||
</div>
|
||||
</transition>
|
||||
</q-drawer>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.q-drawer) {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
background: rgba(0, 0, 0, 0);
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -14,34 +14,38 @@
|
|||
|
||||
watch(chatbot_store.messages, () => {
|
||||
if (scroll_area.value) {
|
||||
scroll_area.value.setScrollPercentage('vertical', 1.0, 500);
|
||||
scroll_area.value.setScrollPosition('vertical', 999999999, 300);
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-scroll-area ref="scroll_area">
|
||||
<q-scroll-area ref="scroll_area" class="no-wrap">
|
||||
<div
|
||||
v-for="(msg, index) in chatbot_store.messages"
|
||||
:key="index"
|
||||
class="q-px-md"
|
||||
class="col-auto q-px-md no-wrap"
|
||||
>
|
||||
<DialoguePhrase
|
||||
v-if="!msg.isThinking"
|
||||
:message="msg"
|
||||
class="col-auto"
|
||||
/>
|
||||
|
||||
<!-- thinking bubble while awaiting chatbot reply -->
|
||||
<div
|
||||
<q-chat-message
|
||||
v-else
|
||||
class="row flex-center q-px-md q-py-sm"
|
||||
name="TargoBot"
|
||||
bg-color="white"
|
||||
:stamp="$t('chatbot.chat_thinking')"
|
||||
>
|
||||
<div class="row flex-center">
|
||||
<q-spinner-dots
|
||||
size="20px"
|
||||
color="primary"
|
||||
class="col-auto self-center"
|
||||
/>
|
||||
<span class="q-ml-sm text-grey-7">{{ $t('chatbot.chat_thinking') }}</span>
|
||||
</div>
|
||||
</q-chat-message>
|
||||
</div>
|
||||
</q-scroll-area>
|
||||
</template>
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
lang="ts"
|
||||
>
|
||||
import { computed } from 'vue';
|
||||
import MarkdownIt from 'markdown-it'
|
||||
// import MarkdownIt from 'markdown-it'
|
||||
import { useAuthStore } from 'src/stores/auth-store';
|
||||
import type { Message } from 'src/modules/chatbot/models/dialogue-message.model';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
|
@ -15,41 +15,73 @@
|
|||
message: Message;
|
||||
}>();
|
||||
|
||||
const message_text = computed(() => message.text.includes('chatbot.') ? t(message.text) : message.text)
|
||||
|
||||
const is_error = computed(() => message.text.includes('NO_REPLY_RECEIVED') || message.text.includes('SEND_MESSAGE_FAILED'));
|
||||
|
||||
// Initialize Markdown parser
|
||||
const md = new MarkdownIt({
|
||||
breaks: false, // Support line breaks
|
||||
linkify: true, // Make URLs clickable
|
||||
html: false // Prevent raw HTML injection
|
||||
})
|
||||
// const md = new MarkdownIt({
|
||||
// // breaks: false, // Support line breaks
|
||||
// linkify: true, // Make URLs clickable
|
||||
// html: false // Prevent raw HTML injection
|
||||
// })
|
||||
|
||||
// Removes all the h1,h2,h3 to make the Md more user friendly
|
||||
const cleanMarkdown = (markdown: string): string => {
|
||||
if (!markdown) return ''
|
||||
return markdown
|
||||
.replace(/\r\n/g, '\n') // normalize Windows line endings
|
||||
.replace(/([.!?])(\s+)(?=[A-Z])/g, '$1\n') // insert line break after sentence-ending punctuation
|
||||
.replace(/\n{3,}/g, '\n\n') // squash triple+ line breaks
|
||||
.replace(/^#{1,3}\s(.*)$/gm, '#### $1') // downgrade headings
|
||||
}
|
||||
// // Removes all the h1,h2,h3 to make the Md more user friendly
|
||||
// const cleanMarkdown = (markdown: string): string => {
|
||||
// if (!markdown) return ''
|
||||
// return markdown
|
||||
// .replace(/\r\n/g, '\n') // normalize Windows line endings
|
||||
// .replace(/([.!?])(\s+)(?=[A-Z])/g, '$1\n') // insert line break after sentence-ending punctuation
|
||||
// .replace(/\n{3,}/g, '\n\n') // squash triple+ line breaks
|
||||
// .replace(/^#{1,3}\s(.*)$/gm, '#### $1') // downgrade headings
|
||||
// }
|
||||
|
||||
// Compute parsed content
|
||||
const parsedText = computed((): string => {
|
||||
const cleaned = cleanMarkdown(message.text || '')
|
||||
if (cleaned.includes('chatbot.')) {
|
||||
const translated_message = t(message.text);
|
||||
return md.render(translated_message);
|
||||
}
|
||||
return md.render(cleaned);
|
||||
})
|
||||
// // Compute parsed content
|
||||
// const parsedText = computed((): string => {
|
||||
// const cleaned = cleanMarkdown(message.text || '')
|
||||
// if (cleaned.includes('chatbot.')) {
|
||||
// const translated_message = t(message.text);
|
||||
// return md.render(translated_message);
|
||||
// }
|
||||
// return md.render(cleaned);
|
||||
// })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-chat-message
|
||||
v-if="is_error"
|
||||
name="SystemBot"
|
||||
bg-color="negative"
|
||||
text-color="white"
|
||||
>
|
||||
<div class="row flex-center">
|
||||
<q-icon
|
||||
name="las la-exclamation-triangle"
|
||||
class="col-auto q-pr-xs"
|
||||
size="2em"
|
||||
color="white"
|
||||
/>
|
||||
<span>{{ message_text }}</span>
|
||||
</div>
|
||||
</q-chat-message>
|
||||
|
||||
<q-chat-message
|
||||
v-else
|
||||
:sent="message.sent"
|
||||
:name="message.sent ? auth_store.user?.first_name : 'TargoBot'"
|
||||
:bg-color="message.sent ? 'accent' : 'white'"
|
||||
:bg-color="message.sent ? 'accent' : 'info'"
|
||||
:text-color="message.sent ? 'white' : ''"
|
||||
>
|
||||
<div v-html="parsedText"></div>
|
||||
</q-chat-message>
|
||||
:text="[message_text]"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.q-message-name) {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
:deep(.q-message-text) {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
import { RouteNames } from "src/router/router-constants";
|
||||
|
||||
export interface chatbotPageContext {
|
||||
export interface ChatbotPageContext {
|
||||
name: string;
|
||||
description: string;
|
||||
features: string[];
|
||||
path: RouteNames | null;
|
||||
}
|
||||
|
||||
export const dashboardContext: chatbotPageContext = {
|
||||
export const dashboardContext: ChatbotPageContext = {
|
||||
name: "Dashboard",
|
||||
description: "Landing page containing useful links and a carousel showcasing recent news, as well as a local weather widget in the top right corner",
|
||||
features: [
|
||||
|
|
@ -18,7 +18,7 @@ export const dashboardContext: chatbotPageContext = {
|
|||
path: RouteNames.DASHBOARD,
|
||||
};
|
||||
|
||||
export const leftDrawerContext: chatbotPageContext = {
|
||||
export const leftDrawerContext: ChatbotPageContext = {
|
||||
name: "Left Drawer",
|
||||
description: "A drawer that acts as a navigation bar, routes to different parts of the website. Some icons will be hidden according to user access",
|
||||
features: [
|
||||
|
|
@ -33,7 +33,7 @@ export const leftDrawerContext: chatbotPageContext = {
|
|||
path: null,
|
||||
};
|
||||
|
||||
export const profileContext: chatbotPageContext = {
|
||||
export const profileContext: ChatbotPageContext = {
|
||||
name: "Profile",
|
||||
description: "Display and edit user information",
|
||||
features: [
|
||||
|
|
@ -44,7 +44,7 @@ export const profileContext: chatbotPageContext = {
|
|||
path: RouteNames.PROFILE,
|
||||
};
|
||||
|
||||
export const employeeListContext: chatbotPageContext = {
|
||||
export const employeeListContext: ChatbotPageContext = {
|
||||
name: "Employee List",
|
||||
description: "View all the hired and currently active Staff",
|
||||
features: [
|
||||
|
|
@ -57,7 +57,7 @@ export const employeeListContext: chatbotPageContext = {
|
|||
path: RouteNames.EMPLOYEE_LIST,
|
||||
};
|
||||
|
||||
export const timesheetApprovalContext: chatbotPageContext = {
|
||||
export const timesheetApprovalContext: ChatbotPageContext = {
|
||||
name: "Timesheet Approval",
|
||||
description: "Page where employee hours and shifts are approved for accounting purposes. Requires timesheet_approval module access.",
|
||||
features: [
|
||||
|
|
@ -71,7 +71,7 @@ export const timesheetApprovalContext: chatbotPageContext = {
|
|||
path: RouteNames.TIMESHEET_APPROVALS,
|
||||
};
|
||||
|
||||
export const timesheetContext: chatbotPageContext = {
|
||||
export const timesheetContext: ChatbotPageContext = {
|
||||
name: "Timesheet",
|
||||
description:
|
||||
"Page where an employee can enter their hours for their day and week. Display in 2-week pay periods.",
|
||||
|
|
@ -86,7 +86,7 @@ export const timesheetContext: chatbotPageContext = {
|
|||
path: RouteNames.TIMESHEET,
|
||||
};
|
||||
|
||||
export const helpContext: chatbotPageContext = {
|
||||
export const helpContext: ChatbotPageContext = {
|
||||
name: "Help",
|
||||
description: "page containing common Q&A segments regarding website functionalities",
|
||||
features: [
|
||||
|
|
@ -98,7 +98,7 @@ export const helpContext: chatbotPageContext = {
|
|||
path: RouteNames.HELP,
|
||||
}
|
||||
|
||||
export const PageContexts: Record<RouteNames, chatbotPageContext | null> = {
|
||||
export const PageContexts: Record<RouteNames, ChatbotPageContext | null> = {
|
||||
"login": null,
|
||||
"login-success": null,
|
||||
"error": null,
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
import type { chatbotPageContext } from "src/modules/chatbot/models/page-context.model";
|
||||
import type { ChatbotPageContext } from "src/modules/chatbot/models/page-context.model";
|
||||
import type { Message } from "src/modules/chatbot/models/dialogue-message.model";
|
||||
import { api } from "src/boot/axios";
|
||||
|
||||
export const chatbotService = {
|
||||
// Function to send the message to the backend
|
||||
sendChatMessage: async (userInput: string): Promise<Message> => {
|
||||
const response = await api.post("/chatbot", { userInput });
|
||||
sendChatMessage: async (userInput: string, pageContext: ChatbotPageContext | undefined): Promise<Message> => {
|
||||
const response = await api.post("/chatbot", { userInput, pageContext });
|
||||
return response.data as Message;
|
||||
},
|
||||
|
||||
// Function to send context to backend
|
||||
sendPageContext: async (context: chatbotPageContext): Promise<string> => {
|
||||
const response = await api.post("/chatbot/context", context);
|
||||
return response.data;
|
||||
},
|
||||
// // Function to send context to backend
|
||||
// sendPageContext: async (context: chatbotPageContext): Promise<string> => {
|
||||
// const response = await api.post("/chatbot/context", context);
|
||||
// return response.data;
|
||||
// },
|
||||
|
||||
// Function to send user credentials to the backend to communicate with n8n.
|
||||
sendUserCredentials: async (email: string, role: string): Promise<boolean> => {
|
||||
const response = await api.post("/chatbot/user", { email, role });
|
||||
return response.data;
|
||||
},
|
||||
// // Function to send user credentials to the backend to communicate with n8n.
|
||||
// sendUserCredentials: async (email: string, role: string): Promise<boolean> => {
|
||||
// const response = await api.post("/chatbot/user", { email, role });
|
||||
// return response.data;
|
||||
// },
|
||||
|
||||
retrieveCustomerDiagnostics: async (id: string): Promise<string> => {
|
||||
const response = await api.get(`/chat/customer/${id}`);
|
||||
return response.data;
|
||||
},
|
||||
// retrieveCustomerDiagnostics: async (id: string): Promise<string> => {
|
||||
// const response = await api.get(`/chat/customer/${id}`);
|
||||
// return response.data;
|
||||
// },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
import { getHoursMinutesStringFromHoursFloat } from 'src/utils/date-and-time-utils';
|
||||
|
||||
interface ChartConfigHoursWorked {
|
||||
key: keyof Pick<TotalHours, 'regular' | 'evening' | 'emergency' | 'overtime'>;
|
||||
key: keyof Pick<TotalHours, 'regular' | 'evening' | 'emergency' | 'overtime'| 'vacation' | 'holiday'>;
|
||||
label: string;
|
||||
color: string;
|
||||
}
|
||||
|
|
@ -50,6 +50,16 @@ import { getHoursMinutesStringFromHoursFloat } from 'src/utils/date-and-time-uti
|
|||
label: t('shared.shift_type.overtime'),
|
||||
color: colors.getPaletteColor('negative'),
|
||||
},
|
||||
{
|
||||
key: 'holiday',
|
||||
label: t('shared.shift_type.holiday'),
|
||||
color: colors.getPaletteColor('purple-5'),
|
||||
},
|
||||
{
|
||||
key: 'vacation',
|
||||
label: t('shared.shift_type.vacation'),
|
||||
color: colors.getPaletteColor('deep-orange-5'),
|
||||
},
|
||||
];
|
||||
|
||||
const hours_worked_labels = ref<string[]>(all_days.map(day => day.date.slice(-5,)));
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
onMounted(() => {
|
||||
Object.values(overview_column_names).map(column => column_options.value.push({ label: `timesheet_approvals.table.${column}`, value: column as OverviewColumns }))
|
||||
column_options.value = column_options.value.filter(column => !EXCLUDED_COLUMNS.includes(column.value));
|
||||
console.log('filter column values: ', column_options.value )
|
||||
})
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@
|
|||
|
||||
const getListViewTimeCss = (column_name: OverviewColumns, value: number): { classes: string, style: string } => {
|
||||
if (WARNING_COLUMNS.includes(column_name) && value > 0)
|
||||
return { classes: 'bg-warning text-white rounded-5', style: '' };
|
||||
return { classes: 'bg-warning text-white text-bold rounded-5', style: '' };
|
||||
|
||||
if (NEGATIVE_COLUMNS.includes(column_name) && value > 0)
|
||||
return { classes: 'bg-negative text-white text-bold rounded-5', style: '' };
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
const is_timesheets_approved = computed(() => timesheet_store.timesheets.every(timesheet => timesheet.is_approved))
|
||||
|
||||
const total_hours = computed(() => timesheet_store.timesheets.reduce((sum, timesheet) =>
|
||||
sum + timesheet.weekly_hours.regular
|
||||
sum += timesheet.weekly_hours.regular
|
||||
+ timesheet.weekly_hours.evening
|
||||
+ timesheet.weekly_hours.emergency
|
||||
+ timesheet.weekly_hours.overtime,
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ export const SHIFT_TYPES: ShiftType[] = [
|
|||
'HOLIDAY',
|
||||
'VACATION',
|
||||
'SICK',
|
||||
'BANKING',
|
||||
// 'BANKING',
|
||||
'WITHDRAW_BANKED',
|
||||
];
|
||||
|
||||
export type ShiftType = 'REGULAR' | 'EVENING' | 'EMERGENCY' | 'HOLIDAY' | 'VACATION' | 'SICK' | 'BANKING' | 'WITHDRAW_BANKED';
|
||||
export type ShiftType = 'REGULAR' | 'EVENING' | 'EMERGENCY' | 'HOLIDAY' | 'VACATION' | 'SICK' | /*'BANKING'|*/ 'WITHDRAW_BANKED';
|
||||
|
||||
export type ShiftErrorCode = 'SHIFT_OVERLAP' | 'MISSING_START_TIME' | 'MISSING_END_TIME' | 'COMMENT_LENGTH_EXCEEDED' | 'APPROVAL_LOCK' | 'INVALID_DATE' | 'INVALID TYPE' | 'INVALID_TIMESHEET';
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,6 @@ export const SHIFT_OPTIONS: ShiftOption[] = [
|
|||
{ label: 'timesheet.shift.types.VACATION', value: 'VACATION', icon: 'beach_access', icon_color: 'deep-orange-5' },
|
||||
{ label: 'timesheet.shift.types.HOLIDAY', value: 'HOLIDAY', icon: 'event', icon_color: 'purple-5' },
|
||||
{ label: 'timesheet.shift.types.SICK', value: 'SICK', icon: 'medication_liquid', icon_color: 'light-blue-6' },
|
||||
{ label: 'timesheet.shift.types.BANKING', value: 'BANKING', icon: 'savings', icon_color: 'pink-3' },
|
||||
// { label: 'timesheet.shift.types.BANKING', value: 'BANKING', icon: 'savings', icon_color: 'pink-3' },
|
||||
{ label: 'timesheet.shift.types.WITHDRAW_BANKED', value: 'WITHDRAW_BANKED', icon: 'attach_money', icon_color: 'yellow-4' },
|
||||
];
|
||||
|
|
@ -45,12 +45,12 @@ export default defineRouter(function (/* { store, ssrContext } */) {
|
|||
}
|
||||
})
|
||||
|
||||
Router.afterEach( async (destination_page) => {
|
||||
Router.afterEach( (destination_page) => {
|
||||
const auth_store = useAuthStore();
|
||||
|
||||
if (auth_store.user?.user_module_access.includes('chatbot')) {
|
||||
const chatbot_store = useChatbotStore();
|
||||
await chatbot_store.updatePageContext(destination_page.name as RouteNames);
|
||||
chatbot_store.updatePageContext(destination_page.name as RouteNames);
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -2,19 +2,20 @@ import { ref } from "vue";
|
|||
import { defineStore } from "pinia";
|
||||
import { chatbotService } from "src/modules/chatbot/services/chatbot.service";
|
||||
import type { Message } from "src/modules/chatbot/models/dialogue-message.model";
|
||||
import { type ChatbotPageContext, PageContexts } from "src/modules/chatbot/models/page-context.model";
|
||||
import type { RouteNames } from "src/router/router-constants";
|
||||
import { PageContexts } from "src/modules/chatbot/models/page-context.model";
|
||||
|
||||
export const useChatbotStore = defineStore("chatbot", () => {
|
||||
const messages = ref<Message[]>([]);
|
||||
const has_shown_instructions = ref(false);
|
||||
const is_showing_chatbot = ref(false);
|
||||
const current_page_context = ref<ChatbotPageContext | undefined>(undefined);
|
||||
|
||||
const sendChatMessage = async (user_message: string) => {
|
||||
const last_chatbot_message = messages.value.at(messages.value.length - 1)!;
|
||||
|
||||
try {
|
||||
const chatbot_response = await chatbotService.sendChatMessage(user_message);
|
||||
const chatbot_response = await chatbotService.sendChatMessage(user_message, current_page_context.value);
|
||||
if (chatbot_response) {
|
||||
last_chatbot_message.text = chatbot_response.text;
|
||||
last_chatbot_message.isThinking = false;
|
||||
|
|
@ -30,11 +31,9 @@ export const useChatbotStore = defineStore("chatbot", () => {
|
|||
}
|
||||
};
|
||||
|
||||
const updatePageContext = async (page_name: RouteNames) => {
|
||||
const chatbot_page_context = PageContexts[page_name];
|
||||
const updatePageContext = (page_name: RouteNames) => {
|
||||
current_page_context.value = PageContexts[page_name] ?? undefined;
|
||||
|
||||
if (chatbot_page_context)
|
||||
await chatbotService.sendPageContext(chatbot_page_context);
|
||||
};
|
||||
|
||||
const showInstructionsOnce = () => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user