Compare commits
No commits in common. "8ba9d882bbbd8cd13f5a58e8724235738402bb71" and "44d5a52499bb25dcb7ef7ffadef81bc68072ccb1" have entirely different histories.
8ba9d882bb
...
44d5a52499
@ -1,3 +0,0 @@
|
|||||||
node_modules
|
|
||||||
dist
|
|
||||||
.git
|
|
||||||
23
Dockerfile
23
Dockerfile
@ -1,23 +0,0 @@
|
|||||||
# Stage 1: Build the Vue App
|
|
||||||
FROM node:22-alpine AS builder
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
COPY package.json package-lock.json ./
|
|
||||||
RUN npm install
|
|
||||||
|
|
||||||
COPY . .
|
|
||||||
RUN npm run build -- --force
|
|
||||||
|
|
||||||
|
|
||||||
# Stage 2: Serve the Built App Using Nginx
|
|
||||||
FROM nginx:alpine
|
|
||||||
|
|
||||||
WORKDIR /usr/share/nginx/html
|
|
||||||
RUN rm -rf ./*
|
|
||||||
COPY --from=builder /app/dist ./
|
|
||||||
|
|
||||||
# Nginx Config
|
|
||||||
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
|
||||||
|
|
||||||
EXPOSE 80
|
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
server {
|
|
||||||
listen 80;
|
|
||||||
|
|
||||||
# Serve Vue frontend
|
|
||||||
location / {
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
index index.html;
|
|
||||||
try_files $uri /index.html;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Reverse proxy for API requests
|
|
||||||
location /search {
|
|
||||||
proxy_pass https://192.168.99.121/search; # Backend API address
|
|
||||||
proxy_ssl_verify off;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
# CORS headers
|
|
||||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
|
|
||||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;
|
|
||||||
|
|
||||||
# Handle preflight OPTIONS requests
|
|
||||||
if ($request_method = OPTIONS) {
|
|
||||||
return 204;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
location /recommend {
|
|
||||||
proxy_pass https://192.168.99.121; # Forward request to backend
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
# Ensure query parameters are preserved
|
|
||||||
proxy_pass_request_body on;
|
|
||||||
proxy_pass_request_headers on;
|
|
||||||
proxy_set_header Connection "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
33
src/App.vue
33
src/App.vue
@ -1,20 +1,33 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { RouterLink, RouterView } from 'vue-router'
|
import { RouterLink, RouterView } from 'vue-router'
|
||||||
|
import HelloWorld from './components/HelloWorld.vue'
|
||||||
|
|
||||||
|
import NavBars from './components/NavBars.vue'
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="min-h-screen flex items-center justify-center">
|
|
||||||
<div class="flex-1 overflow-hidden">
|
<header class="w-[100%]">
|
||||||
<h2 class="text-xl font-semibold text-gray-800 text-center">
|
<NavBars/>
|
||||||
Query MFA Endpoints
|
<!-- <div class="wrapper w-[100%]">
|
||||||
</h2>
|
<nav class="text-[blue]">
|
||||||
<RouterView />
|
<RouterLink to="/">Home</RouterLink>
|
||||||
</div>
|
<RouterLink to="/about">About</RouterLink>
|
||||||
</div>
|
<RouterLink to="/">Home</RouterLink>
|
||||||
|
<RouterLink to="/about">About</RouterLink>
|
||||||
|
<RouterLink to="/">Home</RouterLink>
|
||||||
|
<RouterLink to="/about">About</RouterLink>
|
||||||
|
<RouterLink to="/">Home</RouterLink>
|
||||||
|
<RouterLink to="/about">About</RouterLink>
|
||||||
|
<RouterLink to="/">Home</RouterLink>
|
||||||
|
<RouterLink to="/about">About</RouterLink>
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
</div> -->
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<RouterView />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@ -1,4 +1,87 @@
|
|||||||
|
/* color palette from <https://github.com/vuejs/theme> */
|
||||||
|
:root {
|
||||||
|
--vt-c-white: #ffffff;
|
||||||
|
--vt-c-white-soft: #f8f8f8;
|
||||||
|
--vt-c-white-mute: #f2f2f2;
|
||||||
|
|
||||||
|
--vt-c-black: #181818;
|
||||||
|
--vt-c-black-soft: #222222;
|
||||||
|
--vt-c-black-mute: #282828;
|
||||||
|
|
||||||
|
--vt-c-indigo: #2c3e50;
|
||||||
|
|
||||||
|
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
|
||||||
|
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
|
||||||
|
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
|
||||||
|
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
|
||||||
|
|
||||||
|
--vt-c-text-light-1: var(--vt-c-indigo);
|
||||||
|
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
|
||||||
|
--vt-c-text-dark-1: var(--vt-c-white);
|
||||||
|
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* semantic color variables for this project */
|
||||||
|
:root {
|
||||||
|
--color-background: var(--vt-c-white);
|
||||||
|
--color-background-soft: var(--vt-c-white-soft);
|
||||||
|
--color-background-mute: var(--vt-c-white-mute);
|
||||||
|
|
||||||
|
--color-border: var(--vt-c-divider-light-2);
|
||||||
|
--color-border-hover: var(--vt-c-divider-light-1);
|
||||||
|
|
||||||
|
--color-heading: var(--vt-c-text-light-1);
|
||||||
|
--color-text: var(--vt-c-text-light-1);
|
||||||
|
|
||||||
|
--section-gap: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--color-background: var(--vt-c-black);
|
||||||
|
--color-background-soft: var(--vt-c-black-soft);
|
||||||
|
--color-background-mute: var(--vt-c-black-mute);
|
||||||
|
|
||||||
|
--color-border: var(--vt-c-divider-dark-2);
|
||||||
|
--color-border-hover: var(--vt-c-divider-dark-1);
|
||||||
|
|
||||||
|
--color-heading: var(--vt-c-text-dark-1);
|
||||||
|
--color-text: var(--vt-c-text-dark-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #2c3e50;
|
||||||
|
min-height: 100vh;
|
||||||
|
color: var(--color-text);
|
||||||
|
background: var(--color-background);
|
||||||
|
transition:
|
||||||
|
color 0.5s,
|
||||||
|
background-color 0.5s;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-family:
|
||||||
|
Inter,
|
||||||
|
-apple-system,
|
||||||
|
BlinkMacSystemFont,
|
||||||
|
'Segoe UI',
|
||||||
|
Roboto,
|
||||||
|
Oxygen,
|
||||||
|
Ubuntu,
|
||||||
|
Cantarell,
|
||||||
|
'Fira Sans',
|
||||||
|
'Droid Sans',
|
||||||
|
'Helvetica Neue',
|
||||||
|
sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,8 +1,14 @@
|
|||||||
/* @import './base.css'; */
|
@import './base.css';
|
||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@plugin "daisyui";
|
@plugin "daisyui";
|
||||||
|
|
||||||
|
#app {
|
||||||
|
/* max-width: 1280px; */
|
||||||
|
width:100vw;
|
||||||
|
/* margin: 0 0; */
|
||||||
|
/* padding: 2rem; */
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
41
src/components/HelloWorld.vue
Normal file
41
src/components/HelloWorld.vue
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
defineProps<{
|
||||||
|
msg: string
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="greetings">
|
||||||
|
<h1 class="green">{{ msg }}</h1>
|
||||||
|
<h3>
|
||||||
|
You’ve successfully created a project with
|
||||||
|
<a href="https://vite.dev/" target="_blank" rel="noopener">Vite</a> +
|
||||||
|
<a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>. What's next?
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
h1 {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 2.6rem;
|
||||||
|
position: relative;
|
||||||
|
top: -10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.greetings h1,
|
||||||
|
.greetings h3 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.greetings h1,
|
||||||
|
.greetings h3 {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<div class="mt-[20px]">
|
<div class="mt-[20px]">
|
||||||
<label for="searchType" class="block text-sm !font-bold">Search Type</label>
|
<label for="searchType" class="block text-sm !font-bold">Search Type</label>
|
||||||
<select v-model="selectedSearchType" @change="saveSearchType" id="searchType" class="mt-4 p-[10px] block w-full bg-[#1a1a1a] rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200">
|
<select v-model="selectedSearchType" id="searchType" class="mt-4 p-[10px] block w-full bg-[#1a1a1a] rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200">
|
||||||
<option v-for="option in searchTypes" :key="option" :value="option">
|
<option v-for="option in searchTypes" :key="option" :value="option">
|
||||||
{{ option }}
|
{{ option }}
|
||||||
</option>
|
</option>
|
||||||
@ -49,7 +49,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, onMounted} from "vue";
|
import {ref} from "vue";
|
||||||
import { useSearchStore } from "@/stores/searchStore";
|
import { useSearchStore } from "@/stores/searchStore";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
@ -61,25 +61,55 @@ const searchTypes = ref(["precise","associative","proximity","semantic"])
|
|||||||
const searchQuery = ref("")
|
const searchQuery = ref("")
|
||||||
const pageNumber = ref()
|
const pageNumber = ref()
|
||||||
const pageSize = ref()
|
const pageSize = ref()
|
||||||
onMounted(() => {
|
|
||||||
const savedType = localStorage.getItem("searchType");
|
const data = ref(null);
|
||||||
if (savedType) {
|
|
||||||
selectedSearchType.value = savedType;
|
const responseData = ref(null);
|
||||||
|
let error=ref(null)
|
||||||
|
const fetchData = async () => {
|
||||||
|
try {
|
||||||
|
console.log("fetchData called ")
|
||||||
|
const response = await fetch("/search", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": "ApiKey NS00TXlKUUIweUhWaGFuUUpUVTk6bWNVWXI1VXRSN2VWcFRtaEZ6NmdCUQ=="
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
query: "China",
|
||||||
|
search_type: "precise",
|
||||||
|
page_num: "2",
|
||||||
|
page_size: "2"
|
||||||
|
}),
|
||||||
|
mode: "cors"
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
console.log("response:", response.ok)
|
||||||
|
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
responseData.value = await response.json();
|
||||||
|
console.log("Response:", responseData.value);
|
||||||
|
} catch (err) {
|
||||||
|
|
||||||
|
console.error("Fetch error:", err);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
const searchStore = useSearchStore();
|
const searchStore = useSearchStore();
|
||||||
const saveSearchType = () => {
|
|
||||||
localStorage.setItem("searchType", selectedSearchType.value);
|
|
||||||
};
|
|
||||||
const sendRequest = async()=>{
|
const sendRequest = async()=>{
|
||||||
|
|
||||||
|
console.log("calling fetchData")
|
||||||
|
fetchData()
|
||||||
searchStore.searchParams = {
|
searchStore.searchParams = {
|
||||||
query: searchQuery.value,
|
query: searchQuery.value,
|
||||||
search_type: selectedSearchType.value,
|
searchType: selectedSearchType.value,
|
||||||
// page_num: pageNumber.value,
|
pageNumber: pageNumber.value,
|
||||||
// page_size: pageSize.value
|
pageSize: pageSize.value
|
||||||
};
|
};
|
||||||
|
console.log("searchStore: ", searchStore.searchParams)
|
||||||
router.push("/table");
|
router.push("/table");
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
76
src/components/NavBars.vue
Normal file
76
src/components/NavBars.vue
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<template>
|
||||||
|
<Disclosure as="nav" class="bg-gray-800" v-slot="{ open }">
|
||||||
|
<div class="mx-auto max-w-7xl px-2 sm:px-6 lg:px-8">
|
||||||
|
<div class="relative flex h-16 items-center justify-between">
|
||||||
|
<div class="absolute inset-y-0 left-0 flex items-center sm:hidden">
|
||||||
|
<!-- Mobile menu button-->
|
||||||
|
<DisclosureButton class="relative inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:ring-2 focus:ring-white focus:outline-hidden focus:ring-inset">
|
||||||
|
<span class="absolute -inset-0.5" />
|
||||||
|
<span class="sr-only">Open main menu</span>
|
||||||
|
<Bars3Icon v-if="!open" class="block size-6" aria-hidden="true" />
|
||||||
|
<XMarkIcon v-else class="block size-6" aria-hidden="true" />
|
||||||
|
</DisclosureButton>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-1 items-center justify-center sm:items-stretch sm:justify-start">
|
||||||
|
<div class="flex shrink-0 items-center">
|
||||||
|
<img class="h-8 w-auto" src="https://tailwindui.com/plus-assets/img/logos/mark.svg?color=indigo&shade=500" alt="Your Company" />
|
||||||
|
</div>
|
||||||
|
<div class="hidden sm:ml-6 sm:block">
|
||||||
|
<div class="flex space-x-4">
|
||||||
|
<a v-for="item in navigation" :key="item.name" :href="item.href" :class="[item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white', 'rounded-md px-3 py-2 text-sm font-medium']" :aria-current="item.current ? 'page' : undefined">{{ item.name }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0">
|
||||||
|
<button type="button" class="relative rounded-full bg-gray-800 p-1 text-gray-400 hover:text-white focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800 focus:outline-hidden">
|
||||||
|
<span class="absolute -inset-1.5" />
|
||||||
|
<span class="sr-only">View notifications</span>
|
||||||
|
<BellIcon class="size-6" aria-hidden="true" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Profile dropdown -->
|
||||||
|
<Menu as="div" class="relative ml-3">
|
||||||
|
<div>
|
||||||
|
<MenuButton class="relative flex rounded-full bg-gray-800 text-sm focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800 focus:outline-hidden">
|
||||||
|
<span class="absolute -inset-1.5" />
|
||||||
|
<span class="sr-only ">Open user menu</span>
|
||||||
|
<img class="size-8 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="" />
|
||||||
|
</MenuButton>
|
||||||
|
</div>
|
||||||
|
<transition enter-active-class="transition ease-out duration-100" enter-from-class="transform opacity-0 scale-95" enter-to-class="transform opacity-100 scale-100" leave-active-class="transition ease-in duration-75" leave-from-class="transform opacity-100 scale-100" leave-to-class="transform opacity-0 scale-95">
|
||||||
|
<MenuItems class="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 ring-1 shadow-lg ring-black/5 focus:outline-hidden">
|
||||||
|
<MenuItem v-slot="{ active }">
|
||||||
|
<a href="#" :class="[active ? 'bg-gray-100 outline-hidden' : '', 'block px-4 py-2 text-sm text-gray-700']">Your Profile</a>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem v-slot="{ active }">
|
||||||
|
<a href="#" :class="[active ? 'bg-gray-100 outline-hidden' : '', 'block px-4 py-2 text-sm text-gray-700']">Settings</a>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem v-slot="{ active }">
|
||||||
|
<a href="#" :class="[active ? 'bg-gray-100 outline-hidden' : '', 'block px-4 py-2 text-sm text-gray-700']">Sign out</a>
|
||||||
|
</MenuItem>
|
||||||
|
</MenuItems>
|
||||||
|
</transition>
|
||||||
|
</Menu>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DisclosurePanel class="sm:hidden">
|
||||||
|
<div class="space-y-1 px-2 pt-2 pb-3">
|
||||||
|
<DisclosureButton v-for="item in navigation" :key="item.name" as="a" :href="item.href" :class="[item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white', 'block rounded-md px-3 py-2 text-base font-medium']" :aria-current="item.current ? 'page' : undefined">{{ item.name }}</DisclosureButton>
|
||||||
|
</div>
|
||||||
|
</DisclosurePanel>
|
||||||
|
</Disclosure>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { Disclosure, DisclosureButton, DisclosurePanel, Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue'
|
||||||
|
import { Bars3Icon, BellIcon, XMarkIcon } from '@heroicons/vue/24/outline'
|
||||||
|
|
||||||
|
const navigation = [
|
||||||
|
{ name: 'Dashboard', href: '#', current: true },
|
||||||
|
{ name: 'Team', href: '#', current: false },
|
||||||
|
{ name: 'Projects', href: '#', current: false },
|
||||||
|
{ name: 'Calendar', href: '#', current: false },
|
||||||
|
]
|
||||||
|
</script>
|
||||||
@ -1,123 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
|
<h3>Search Parameters</h3>
|
||||||
|
<pre>{{ searchStore.searchParams }}</pre> <!-- ✅ Displays as JSON -->
|
||||||
|
|
||||||
<div class=" w-[100%] h-[100%] overflow-hidden">
|
<p>Query: {{ searchStore.searchParams.query }}</p>
|
||||||
<div class="flex justify-between mb-[20px]">
|
<p>Search Type: {{ searchStore.searchParams.searchType }}</p>
|
||||||
<div>
|
<p>Page Number: {{ searchStore.searchParams.pageNumber }}</p>
|
||||||
<div>Entity you searched for: <span class="!font-bold">{{ searchWhat || "You did not provide" }}</span></div>
|
<p>Page Size: {{ searchStore.searchParams.pageSize }}</p>
|
||||||
<div>Search Type: <span class="!font-bold">{{ searchStore.searchParams.search_type || "You did not provide" }}</span></div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button @click="goToSearchPage" class="btn rounded-[10px] bg-[#0000FF] text-[white]">Back To Search Page</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="!noData" class="pt-[0px] h-[90%] w-[100%] border border-[#000C66] overflow-scroll">
|
|
||||||
<table class="table table-pin-rows w-full">
|
|
||||||
<thead class="">
|
|
||||||
<!-- <tr class=""> -->
|
|
||||||
<!-- <th v-for="item in keys_of_a_data" class=" sticky top-0 z-10">{{item}}</th> -->
|
|
||||||
<!-- <th colspan="52">metadata</th>
|
|
||||||
<th>search</th>
|
|
||||||
</tr> -->
|
|
||||||
<tr class="sticky border-[0px] border-r border-l border-[#000C66] bg-[#000C66] text-[white]">
|
|
||||||
<th v-for="item in arr_col_items" class="sticky !border-[0px] ">{{ item }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="(item, index) in row_values" :key="index">
|
|
||||||
<td v-for="item2 in item" class="border-[#000C66]" :class="{'border': true, 'border-t-0': index === 0}">{{ item2 }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="h-[90%] w-[100%] flex justify-center items-center font-bold text-[red] text-[32px]" v-else>No search results</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref,reactive,onMounted,toRaw} from "vue";
|
import {ref} from "vue";
|
||||||
import { useSearchStore } from "@/stores/searchStore";
|
import { useSearchStore } from "@/stores/searchStore";
|
||||||
import {fetchData} from "@/utils/api.ts"
|
|
||||||
import { useRouter } from "vue-router";
|
|
||||||
const searchStore = useSearchStore();
|
const searchStore = useSearchStore();
|
||||||
// interface ApiResponse {
|
|
||||||
// data: any[]; // Adjust this type according to your API response
|
|
||||||
// }
|
|
||||||
const responseData = ref<any>({ data: [] })
|
|
||||||
const searchWhat = ref(searchStore.searchParams.query)
|
|
||||||
|
|
||||||
const query={...searchStore.searchParams}
|
|
||||||
const noData=ref(false)
|
|
||||||
|
|
||||||
const keys_of_a_data=ref<any[]>()
|
|
||||||
|
|
||||||
const arr_col_items=ref<any[]>([])
|
|
||||||
|
|
||||||
const row_values = ref<any[]>([])
|
|
||||||
const router = useRouter();
|
|
||||||
const goToSearchPage=()=>{
|
|
||||||
router.push ("/")
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(()=>{
|
|
||||||
|
|
||||||
let requestType="POST";
|
|
||||||
if (query.search_type==="semantic"){
|
|
||||||
requestType = "GET"
|
|
||||||
}
|
|
||||||
fetchData("/search",requestType,query).then(response =>{
|
|
||||||
|
|
||||||
if (response.data.length===0){
|
|
||||||
noData.value=true
|
|
||||||
|
|
||||||
// responseData.value={}
|
|
||||||
console.log("temporary")
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
noData.value=false
|
|
||||||
responseData.value = response
|
|
||||||
|
|
||||||
if(requestType==="POST"){
|
|
||||||
keys_of_a_data.value = Object.keys(response.data[0])
|
|
||||||
|
|
||||||
|
|
||||||
keys_of_a_data.value.forEach((item, index)=>{
|
|
||||||
|
|
||||||
arr_col_items.value.push(...Object.keys(response.data[0][item]))
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
response.data.map(item=>{
|
|
||||||
const values:any[]=[]
|
|
||||||
|
|
||||||
Object.keys(item).forEach(key=>{
|
|
||||||
// key here is metadata and search
|
|
||||||
|
|
||||||
values.push(...Object.values(item[key]))
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
row_values.value.push(values)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(requestType === "GET"){
|
|
||||||
|
|
||||||
arr_col_items.value =Object.keys(responseData.value.data[0])
|
|
||||||
|
|
||||||
row_values.value = responseData.value.data.map(item=> Object.values(item))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}).catch(error=>{
|
|
||||||
responseData.value = "error"
|
|
||||||
console.log(error)
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
7
src/components/TheWelcome.vue
Normal file
7
src/components/TheWelcome.vue
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<p>Home page</p>
|
||||||
|
</template>
|
||||||
@ -9,6 +9,14 @@ const router = createRouter({
|
|||||||
name: 'home',
|
name: 'home',
|
||||||
component: HomeView,
|
component: HomeView,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/about',
|
||||||
|
name: 'about',
|
||||||
|
// route level code-splitting
|
||||||
|
// this generates a separate chunk (About.[hash].js) for this route
|
||||||
|
// which is lazy-loaded when the route is visited.
|
||||||
|
component: () => import('../views/AboutView.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/table',
|
path: '/table',
|
||||||
name: 'table',
|
name: 'table',
|
||||||
|
|||||||
6
src/shims-vue.d.ts
vendored
6
src/shims-vue.d.ts
vendored
@ -1,6 +0,0 @@
|
|||||||
// src/shims-vue.d.ts
|
|
||||||
declare module "*.vue" {
|
|
||||||
import { DefineComponent } from "vue";
|
|
||||||
const component: DefineComponent<{}, {}, any>;
|
|
||||||
export default component;
|
|
||||||
}
|
|
||||||
@ -1,11 +1,8 @@
|
|||||||
import { reactive, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
export const useSearchStore = defineStore('search', () => {
|
export const useSearchStore = defineStore('search', () => {
|
||||||
const searchParams = reactive({
|
const searchParams = ref({})
|
||||||
query:"",
|
|
||||||
search_type:""
|
|
||||||
})
|
|
||||||
|
|
||||||
return { searchParams }
|
return { searchParams }
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,34 +1,22 @@
|
|||||||
export const fetchData = async(endpoints="", requestType="GET", requestBody:Record<string,any>|null =null)=>{
|
export const fetchData = async(endpoints="", requestType="GET", requestBody=null)=>{
|
||||||
|
console.log("requestBody:", requestBody)
|
||||||
|
console.log("requestType:", requestType)
|
||||||
|
console.log("endpoints:", `https://192.168.99.121/${endpoints}`)
|
||||||
try{
|
try{
|
||||||
const options:RequestInit={
|
const options={
|
||||||
method:requestType,
|
method:requestType,
|
||||||
headers:{
|
headers:{
|
||||||
"Content-Type":"application/json",
|
"Content-Type":"application/json",
|
||||||
"Authorization": "ApiKey NS00TXlKUUIweUhWaGFuUUpUVTk6bWNVWXI1VXRSN2VWcFRtaEZ6NmdCUQ=="
|
"Authorization": "ApiKey NS00TXlKUUIweUhWaGFuUUpUVTk6bWNVWXI1VXRSN2VWcFRtaEZ6NmdCUQ=="
|
||||||
},
|
}
|
||||||
mode: "cors"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestType !=="GET" && requestBody){
|
if (requestType !=="GET" && requestBody){
|
||||||
|
|
||||||
options.body = JSON.stringify(requestBody)
|
options.body = JSON.stringify(requestBody)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let response;
|
const response = await fetch(`http://192.168.99.121/${endpoints}`, options)
|
||||||
if (requestBody?.search_type==="semantic"){
|
console.log("response butrte: ", response)
|
||||||
const params = new URLSearchParams({
|
|
||||||
clause: requestBody?.query
|
|
||||||
}).toString();
|
|
||||||
|
|
||||||
|
|
||||||
response = await fetch(`/recommend?${params}`, options)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
response = await fetch("/search", options)
|
|
||||||
}
|
|
||||||
if (!response.ok){
|
if (!response.ok){
|
||||||
throw new Error(`HTTP error! Status: ${response.status}`)
|
throw new Error(`HTTP error! Status: ${response.status}`)
|
||||||
}
|
}
|
||||||
16
src/views/AboutView.vue
Normal file
16
src/views/AboutView.vue
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<template>
|
||||||
|
<main class="about">
|
||||||
|
<h1 class="text-[red]">This is an about page</h1>
|
||||||
|
</main>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.about {
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #2a4373;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -3,7 +3,7 @@ import InputFieldCard from '@/components/InputFieldCard.vue'
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main class="flex place-content-center p-4 ">
|
<main class="flex place-content-center p-4 h-[100%]">
|
||||||
<InputFieldCard/>
|
<InputFieldCard/>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<main class="flex p-4 w-[100%] h-[100%] overflow-hidden">
|
<main class="flex place-content-center p-4 h-[100%]">
|
||||||
<TableComp />
|
<TableComp />
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
"exclude": ["src/**/__tests__/*"],
|
"exclude": ["src/**/__tests__/*"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
"noImplicitAny": false,
|
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"]
|
"@/*": ["./src/*"]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,8 +10,5 @@
|
|||||||
{
|
{
|
||||||
"path": "./tsconfig.vitest.json"
|
"path": "./tsconfig.vitest.json"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"compilerOptions": {
|
|
||||||
"noImplicitAny": false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,18 +13,6 @@ export default defineConfig({
|
|||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
secure: false, // Ignores SSL certificate issues
|
secure: false, // Ignores SSL certificate issues
|
||||||
},
|
},
|
||||||
"/recommend": {
|
|
||||||
target: "https://192.168.99.121",
|
|
||||||
changeOrigin: true,
|
|
||||||
secure: false, // Ignores SSL certificate issues
|
|
||||||
// configure: (proxy) => {
|
|
||||||
// proxy.on('proxyReq', (proxyReq, req) => {
|
|
||||||
// console.log('Incoming request URL:', req.url); // Logs request URL
|
|
||||||
// console.log('Final URL sent to backend:', proxyReq.path); // Logs what Vite sends
|
|
||||||
// console.log('Final URL sent to backend:', proxyReq)
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user