Changes
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
.idea
|
.idea
|
||||||
/test/csvparser/data.csv
|
/test/csvparser/data.csv
|
||||||
/test/imaps/.env
|
/test/imaps/.env
|
||||||
|
/test/csvparser/node_modules/
|
||||||
|
|||||||
@@ -23,6 +23,14 @@ services:
|
|||||||
- "traefik.http.routers.spaces-frontend-secure.entrypoints=web-secured" #
|
- "traefik.http.routers.spaces-frontend-secure.entrypoints=web-secured" #
|
||||||
- "traefik.http.routers.spaces-frontend-secure.tls.certresolver=mytlschallenge"
|
- "traefik.http.routers.spaces-frontend-secure.tls.certresolver=mytlschallenge"
|
||||||
|
|
||||||
|
imapsync:
|
||||||
|
image: registry.gitlab.com/cmykmedia/spaces:main-IMAPSYNC
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
SUPABASE_URL: "https://uwppvcxflrcsibuzsbil.supabase.co"
|
||||||
|
SUPABASE_KEY: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV3cHB2Y3hmbHJjc2lidXpzYmlsIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcwMDkzODE5NCwiZXhwIjoyMDE2NTE0MTk0fQ.6hOkD1J8XBkVJUm-swv0ngLQ74xrEYr28EEbo0rUrts"
|
||||||
|
INTERVAL: 30
|
||||||
|
|
||||||
# backend:
|
# backend:
|
||||||
# image: registry.gitlab.com/cmykmedia/manordsonne:master-BACKEND
|
# image: registry.gitlab.com/cmykmedia/manordsonne:master-BACKEND
|
||||||
# restart: always
|
# restart: always
|
||||||
|
|||||||
1
spaces/.npmrc
Normal file
1
spaces/.npmrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
@bryntum:registry=https://npm.bryntum.com
|
||||||
116
spaces/app.vue
116
spaces/app.vue
@@ -1,10 +1,99 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const user = useSupabaseUser()
|
const user = useSupabaseUser()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
const supabase = useSupabaseClient()
|
const supabase = useSupabaseClient()
|
||||||
const tenants = (await supabase.from("tenants").select()).data
|
const tenants = (await supabase.from("tenants").select()).data
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const dataStore = useDataStore()
|
||||||
|
const {loaded} = storeToRefs(useDataStore())
|
||||||
|
const {fetchData} = dataStore
|
||||||
|
fetchData()
|
||||||
|
|
||||||
|
const navLinks = [
|
||||||
|
{
|
||||||
|
label: "Home",
|
||||||
|
link: "",
|
||||||
|
icon: 'i-heroicons-home'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Aufgaben",
|
||||||
|
link: "tasks",
|
||||||
|
icon: "i-heroicons-rectangle-stack"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Kunden",
|
||||||
|
link: "customers",
|
||||||
|
icon: "i-heroicons-user-group"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Projekte",
|
||||||
|
link: "projects",
|
||||||
|
icon: "i-heroicons-clipboard-document-check"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Zeiterfassung",
|
||||||
|
link: "timetracking",
|
||||||
|
icon: "i-heroicons-clock"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Artikel",
|
||||||
|
link: "products"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Dokumente",
|
||||||
|
link: "documents",
|
||||||
|
icon: "i-heroicons-document"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Inventar",
|
||||||
|
link: "inventory"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const linksForBreadcrumbs = ref([])
|
||||||
|
|
||||||
|
const generateLinks = () => {
|
||||||
|
let pathSteps = route.fullPath.split("/")
|
||||||
|
let returnArr = []
|
||||||
|
|
||||||
|
pathSteps.forEach((step,index) => {
|
||||||
|
|
||||||
|
let stepLink = navLinks.find(link => link.link == step)
|
||||||
|
|
||||||
|
if(stepLink) {
|
||||||
|
returnArr[index] = {
|
||||||
|
label: stepLink.label,
|
||||||
|
icon: stepLink.icon,
|
||||||
|
to: '/' + stepLink.link
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
linksForBreadcrumbs.value = returnArr
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => route.path,
|
||||||
|
() => {
|
||||||
|
generateLinks()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
generateLinks()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const userTenant = ref({})
|
const userTenant = ref({})
|
||||||
if(user) userTenant.value = tenants.find(tenant => tenant.id === user.value.app_metadata.tenant)
|
if(user) userTenant.value = tenants.find(tenant => tenant.id === user.value.app_metadata.tenant)
|
||||||
const userDropdownItems = [
|
const userDropdownItems = [
|
||||||
@@ -33,20 +122,39 @@ const userDropdownItems = [
|
|||||||
<UCard id="page">
|
<UCard id="page">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div id="menu">
|
<div id="menu">
|
||||||
<router-link to="/tasks" class="mr-2"><UButton>Aufgaben</UButton></router-link>
|
<router-link
|
||||||
<router-link to="/customers" class="mr-2"><UButton>Kunden</UButton></router-link>
|
v-for="link in navLinks"
|
||||||
|
:to="'/' + link.link"
|
||||||
|
class="mr-2"
|
||||||
|
>
|
||||||
|
<UButton>{{link.label}}</UButton>
|
||||||
|
</router-link>
|
||||||
|
<!--<router-link to="/customers" class="mr-2"><UButton>Kunden</UButton></router-link>
|
||||||
<router-link to="/projects" class="mr-2"><UButton>Projekte</UButton></router-link>
|
<router-link to="/projects" class="mr-2"><UButton>Projekte</UButton></router-link>
|
||||||
|
-
|
||||||
<router-link to="/vendorinvoices" class="mr-2"><UButton>Eingangsrechnungen</UButton></router-link>
|
<router-link to="/vendorinvoices" class="mr-2"><UButton>Eingangsrechnungen</UButton></router-link>
|
||||||
|
|
||||||
<router-link to="/timetracking" class="mr-2"><UButton>Zeiterfassung</UButton></router-link>
|
<router-link to="/timetracking" class="mr-2"><UButton>Zeiterfassung</UButton></router-link>
|
||||||
<router-link to="/products" class="mr-2"><UButton>Artikel</UButton></router-link>
|
<router-link to="/products" class="mr-2"><UButton>Artikel</UButton></router-link>
|
||||||
<router-link to="/documents" class="mr-2"><UButton>Dokumente</UButton></router-link>
|
<router-link to="/documents" class="mr-2"><UButton>Dokumente</UButton></router-link>
|
||||||
<router-link to="/inventory" class="mr-2"><UButton>Inventar</UButton></router-link>
|
<router-link to="/inventory" class="mr-2"><UButton>Inventar</UButton></router-link>-->
|
||||||
<UDropdown :items="userDropdownItems" :popper="{placement: 'bottom-start'}">
|
<UDropdown :items="userDropdownItems" :popper="{placement: 'bottom-start'}">
|
||||||
<UButton color="white" label="Benutzer" trailing-icon="i-heroicons-chevron-down-20-solid" />
|
<UButton color="white" label="Benutzer" trailing-icon="i-heroicons-chevron-down-20-solid" />
|
||||||
</UDropdown>
|
</UDropdown>
|
||||||
</div>
|
</div>
|
||||||
|
<UBreadcrumb
|
||||||
|
class="my-3"
|
||||||
|
:links="linksForBreadcrumbs"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<NuxtPage/>
|
<NuxtPage
|
||||||
|
v-if="loaded"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
>
|
||||||
|
<UProgress animation="carousel" />
|
||||||
|
</div>
|
||||||
</UCard>
|
</UCard>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
devtools: { enabled: true },
|
devtools: { enabled: true },
|
||||||
|
imports: {
|
||||||
|
dirs: ['stores']
|
||||||
|
},
|
||||||
modules: [
|
modules: [
|
||||||
'@pinia/nuxt',
|
'@pinia/nuxt',
|
||||||
'@nuxt/ui',
|
'@nuxt/ui',
|
||||||
|
|||||||
7318
spaces/package-lock.json
generated
7318
spaces/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -17,21 +17,17 @@
|
|||||||
"vue-router": "^4.2.5"
|
"vue-router": "^4.2.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@huntersofbook/naive-ui-nuxt": "^1.2.0",
|
"@nuxt/ui": "^2.11.0",
|
||||||
"@nuxt/ui": "^2.10.0",
|
|
||||||
"@nuxtjs/strapi": "^1.9.3",
|
"@nuxtjs/strapi": "^1.9.3",
|
||||||
"@pinia/nuxt": "^0.5.1",
|
"@pinia/nuxt": "^0.5.1",
|
||||||
"@tato30/vue-pdf": "^1.8.1",
|
|
||||||
"@vicons/ionicons5": "^0.12.0",
|
"@vicons/ionicons5": "^0.12.0",
|
||||||
"axios": "^1.6.2",
|
"axios": "^1.6.2",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"csv-parser": "^3.0.0",
|
|
||||||
"jsprintmanager": "^6.0.3",
|
"jsprintmanager": "^6.0.3",
|
||||||
"neat-csv": "^7.0.0",
|
|
||||||
"nuxt-editorjs": "^1.0.4",
|
"nuxt-editorjs": "^1.0.4",
|
||||||
"papaparse": "^5.4.1",
|
"papaparse": "^5.4.1",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"uuidv4": "^6.2.13",
|
"sass": "^1.69.5",
|
||||||
"vue-pdf-embed": "^1.2.1"
|
"uuidv4": "^6.2.13"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
spaces/pages/banking/[account].vue
Normal file
18
spaces/pages/banking/[account].vue
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<script setup>
|
||||||
|
const route = useRoute()
|
||||||
|
const supabase = useSupabaseClient()
|
||||||
|
console.log(route.params.account)
|
||||||
|
|
||||||
|
const accounts = (await supabase.from("bankAccounts").select()).data
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
103
spaces/pages/banking/index.vue
Normal file
103
spaces/pages/banking/index.vue
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<script setup>
|
||||||
|
import Papa from 'papaparse'
|
||||||
|
|
||||||
|
const supabase = useSupabaseClient()
|
||||||
|
|
||||||
|
const accounts = (supabase.from("bankAccounts").select()).data
|
||||||
|
|
||||||
|
let items = ref([])
|
||||||
|
async function readSingleFile(evt) {
|
||||||
|
var f = document.getElementById('fileInput').files[0];
|
||||||
|
if (f) {
|
||||||
|
let results = []
|
||||||
|
let text = await f.text()
|
||||||
|
results = Papa.parse(text).data
|
||||||
|
console.log(results[0])
|
||||||
|
results = results.slice(1)
|
||||||
|
results = results.map(temp => {
|
||||||
|
return {
|
||||||
|
iban: temp[1],
|
||||||
|
bank: temp[3],
|
||||||
|
date: temp[4],
|
||||||
|
partnerName: temp[6],
|
||||||
|
partnerIban: temp[7],
|
||||||
|
type: temp[9],
|
||||||
|
text: temp[10],
|
||||||
|
value: temp[11],
|
||||||
|
currency: temp[12]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(results)
|
||||||
|
items.value = results
|
||||||
|
|
||||||
|
parseStatements()
|
||||||
|
|
||||||
|
} else {
|
||||||
|
alert("Failed to load file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const newStatements = ref([])
|
||||||
|
|
||||||
|
const parseStatements = async () => {
|
||||||
|
items.value.forEach(item => {
|
||||||
|
if(item.date) {
|
||||||
|
let returnObj = {
|
||||||
|
date: item.date,
|
||||||
|
partnerIban: item.partnerIban,
|
||||||
|
partnerName: item.partnerName,
|
||||||
|
text: item.text,
|
||||||
|
value: Number(item.value.replace(",",".")),
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
newStatements.value.push(returnObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
const {data,error} = await supabase
|
||||||
|
.from("bankStatements")
|
||||||
|
.insert(newStatements.value)
|
||||||
|
.select()
|
||||||
|
|
||||||
|
console.log(data)
|
||||||
|
console.log(error)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<UInput
|
||||||
|
type="file"
|
||||||
|
id="fileInput"
|
||||||
|
/>
|
||||||
|
<UButton
|
||||||
|
@click="readSingleFile"
|
||||||
|
>Test</UButton>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr
|
||||||
|
v-for="temp in items"
|
||||||
|
>
|
||||||
|
<td>{{temp.date}}</td>
|
||||||
|
<td>{{temp.partnerName}}</td>
|
||||||
|
<td>{{temp.text}}</td>
|
||||||
|
<td>{{temp.value}}</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
28
spaces/pages/calendar/planningBoard.vue
Normal file
28
spaces/pages/calendar/planningBoard.vue
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<script setup>
|
||||||
|
/*import '@bryntum/scheduler'
|
||||||
|
import { BryntumScheduler } from '@bryntum/scheduler-vue-3'
|
||||||
|
import '@bryntum/scheduler/scheduler.material.css'
|
||||||
|
const config = reactive({
|
||||||
|
startDate: new Date(2024,0,1,6),
|
||||||
|
endDate: new Date(2024,0,1,20),
|
||||||
|
viewPreset: "hourAndDay",
|
||||||
|
rowHeight: 50,
|
||||||
|
columns: [{text: "Name", field: "name", width: 130}]
|
||||||
|
})*/
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- <bryntum-scheduler
|
||||||
|
:width="800"
|
||||||
|
:height="600"
|
||||||
|
start-date="2023-04-16"
|
||||||
|
end-date="2023-05-15"
|
||||||
|
></bryntum-scheduler>-->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="main">
|
<div id="main">
|
||||||
|
<!-- TODO: Kontakte erstellen und dem Kunden zuweisen -->
|
||||||
<div id="left">
|
<div id="left">
|
||||||
|
|
||||||
<UButton @click="showCreateCustomer = true">+ Kunde</UButton>
|
<UButton @click="showCreateCustomer = true">+ Kunde</UButton>
|
||||||
@@ -57,7 +58,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- TODO: Scrollcontainer -->
|
||||||
</UCard>
|
</UCard>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -70,11 +71,7 @@ definePageMeta({
|
|||||||
|
|
||||||
const supabase = useSupabaseClient()
|
const supabase = useSupabaseClient()
|
||||||
|
|
||||||
//const {find,create} = useStrapi4()
|
const {customers } = storeToRefs(useDataStore())
|
||||||
//const customers = (await find('customers',{populate: "*"})).data
|
|
||||||
|
|
||||||
const customers = (await supabase.from("customers").select().order('customerNumber', {ascending: true})).data
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let showCreateCustomer = ref(false)
|
let showCreateCustomer = ref(false)
|
||||||
|
|||||||
@@ -68,72 +68,37 @@
|
|||||||
v-model="showDocumentModal"
|
v-model="showDocumentModal"
|
||||||
fullscreen
|
fullscreen
|
||||||
>
|
>
|
||||||
<UCard>
|
<UCard class="h-full">
|
||||||
|
|
||||||
<!-- <a
|
|
||||||
v-if="selectedDocument"
|
|
||||||
target="_blank"
|
|
||||||
:href="`http://localhost:1337${selectedDocument.file.data.url}`"
|
|
||||||
class="p-2"
|
|
||||||
>
|
|
||||||
Anzeigen
|
|
||||||
|
|
||||||
|
|
||||||
</a>-->
|
|
||||||
|
|
||||||
{{selectedDocument}}
|
|
||||||
|
|
||||||
<embed
|
<embed
|
||||||
:src="pdfSource"
|
class="bigPreview mb-3"
|
||||||
|
:src="selectedDocument.url"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<UBadge
|
||||||
|
v-for="tag in selectedDocument.tags"
|
||||||
>
|
>
|
||||||
|
{{tag}}
|
||||||
|
</UBadge>
|
||||||
|
|
||||||
|
|
||||||
<!-- <UFormGroup
|
<UFormGroup
|
||||||
label="Tags:"
|
label="Ordner ändern:"
|
||||||
>
|
>
|
||||||
<USelectMenu
|
<USelectMenu
|
||||||
v-if="selectedDocument"
|
:options="folders"
|
||||||
multiple
|
v-on:change="changeFolder"
|
||||||
searchable
|
v-model="newFolder"
|
||||||
searchable-placeholder="Suchen..."
|
value-attribute="label"
|
||||||
:options="tags"
|
|
||||||
v-on:change="update('documents',selectedDocument.id, {tags: selectedDocument.tags})"
|
|
||||||
v-model="selectedDocument.tags"
|
|
||||||
/>
|
/>
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
|
|
||||||
<UFormGroup
|
|
||||||
label="Status:"
|
|
||||||
class="mb-3"
|
|
||||||
>
|
|
||||||
<USelectMenu
|
|
||||||
:options="states"
|
|
||||||
v-model="selectedDocument.state"
|
|
||||||
v-on:change="update('documents',selectedDocument.id,{state: selectedDocument.state})"
|
|
||||||
/>
|
|
||||||
</UFormGroup>-->
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<VuePDF
|
|
||||||
ref="vuePDFRef"
|
|
||||||
:pdf="pdf"
|
|
||||||
fit-parent
|
|
||||||
:page="page"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="mt-3">
|
|
||||||
<UButton @click="page = page > 1 ? page - 1 : page">
|
|
||||||
Prev
|
|
||||||
</UButton>
|
|
||||||
<span class="mx-3">{{ page }} / {{ pages }}</span>
|
|
||||||
<UButton @click="page = page < pages ? page + 1 : page">
|
|
||||||
Next
|
|
||||||
</UButton>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</UCard>
|
</UCard>
|
||||||
</USlideover>
|
</USlideover>
|
||||||
|
<!-- TODO: Tab Height always Full -->
|
||||||
<UTabs
|
<UTabs
|
||||||
:items="folders"
|
:items="folders"
|
||||||
orientation="vertical"
|
orientation="vertical"
|
||||||
@@ -143,8 +108,8 @@
|
|||||||
<template #item="{item}">
|
<template #item="{item}">
|
||||||
<div class="documentList">
|
<div class="documentList">
|
||||||
<div
|
<div
|
||||||
v-if="documentsComposed.filter(doc => doc.folder === item.label).length > 0"
|
v-if="documents.filter(doc => doc.folder === item.label).length > 0"
|
||||||
v-for="document in documentsComposed.filter(doc => doc.folder === item.label)"
|
v-for="document in documents.filter(doc => doc.folder === item.label)"
|
||||||
class="documentListItem"
|
class="documentListItem"
|
||||||
>
|
>
|
||||||
<embed
|
<embed
|
||||||
@@ -187,25 +152,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
middleware: "auth"
|
middleware: "auth"
|
||||||
})
|
})
|
||||||
const supabase = useSupabaseClient()
|
const supabase = useSupabaseClient()
|
||||||
const user = useSupabaseUser()
|
const user = useSupabaseUser()
|
||||||
|
|
||||||
const documents = (await supabase.from("documents").select()).data
|
const {documents} = storeToRefs(useDataStore())
|
||||||
|
|
||||||
const documentsComposed = ref([])
|
|
||||||
async function composeDocs () {
|
|
||||||
for(const doc of documents){
|
|
||||||
let fileurl = (await supabase.storage.from('documents').createSignedUrl(doc.path,60*60)).data.signedUrl
|
|
||||||
|
|
||||||
documentsComposed.value.push({...doc, url: fileurl})
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await composeDocs()
|
|
||||||
|
|
||||||
const tabOpen = ref(0)
|
const tabOpen = ref(0)
|
||||||
const uploadModalOpen = ref(false)
|
const uploadModalOpen = ref(false)
|
||||||
@@ -271,10 +225,28 @@ const uploadFile = async () => {
|
|||||||
uploadModalOpen.value = false;
|
uploadModalOpen.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateDocument = async () => {
|
|
||||||
await update('documents', selectedDocument.id, {tags: selectedDocument.tags, state: selectedDocument.state})
|
|
||||||
|
const changeFolder = async () => {
|
||||||
|
console.log("Change Folder")
|
||||||
|
console.log(selectedDocument.value.path)
|
||||||
|
|
||||||
|
let filename = selectedDocument.value.path.split("/")[2]
|
||||||
|
let newPath = `${user.value.app_metadata.tenant}/${newFolder.value}/${filename}`
|
||||||
|
console.log(newPath)
|
||||||
|
|
||||||
|
const { data, error } = await supabase
|
||||||
|
.storage
|
||||||
|
.from('documents')
|
||||||
|
.move(selectedDocument.value.path, newPath )
|
||||||
|
|
||||||
|
console.log(data)
|
||||||
|
console.log(error)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const newFolder = ref("")
|
||||||
|
|
||||||
const selectedDocument = ref({})
|
const selectedDocument = ref({})
|
||||||
const showDocumentModal = ref(false)
|
const showDocumentModal = ref(false)
|
||||||
|
|
||||||
@@ -290,12 +262,13 @@ const openDocument = async (document) => {
|
|||||||
.documentList {
|
.documentList {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.documentListItem {
|
.documentListItem {
|
||||||
display:block;
|
display:block;
|
||||||
width: 15vw;
|
width: 15vw;
|
||||||
height: 25vh;
|
height: 30vh;
|
||||||
padding:1em;
|
padding:1em;
|
||||||
margin: 0.7em;
|
margin: 0.7em;
|
||||||
border: 1px solid lightgrey;
|
border: 1px solid lightgrey;
|
||||||
@@ -309,7 +282,7 @@ const openDocument = async (document) => {
|
|||||||
|
|
||||||
.previewEmbed {
|
.previewEmbed {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 18vh;
|
height: 22vh;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
-ms-overflow-style: none; /* IE and Edge */
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
scrollbar-width: none; /* Firefox */
|
scrollbar-width: none; /* Firefox */
|
||||||
@@ -318,4 +291,9 @@ const openDocument = async (document) => {
|
|||||||
.previewEmbed::-webkit-scrollbar {
|
.previewEmbed::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bigPreview {
|
||||||
|
height: 70vh;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
88
spaces/pages/formSubmissions/[id].vue
Normal file
88
spaces/pages/formSubmissions/[id].vue
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<script setup>
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
const supabase = useSupabaseClient()
|
||||||
|
|
||||||
|
|
||||||
|
const currentSubmission = (await supabase.from("formSubmits").select().eq('id',route.params.id)).data[0]
|
||||||
|
const form = (await supabase.from("forms").select().eq('id',currentSubmission.formType)).data[0]
|
||||||
|
|
||||||
|
const formData = ref({})
|
||||||
|
const submitted = ref(currentSubmission.submitted)
|
||||||
|
|
||||||
|
const submitForm = async () => {
|
||||||
|
|
||||||
|
submitted.value = true
|
||||||
|
|
||||||
|
console.log(formData.value)
|
||||||
|
const {data,error} = await supabase
|
||||||
|
.from("formSubmits")
|
||||||
|
.update({values: formData.value, submitted: true})
|
||||||
|
.eq('id',currentSubmission.id)
|
||||||
|
.select()
|
||||||
|
|
||||||
|
if(error) {
|
||||||
|
console.log(error)
|
||||||
|
} else if( data) {
|
||||||
|
formData.value = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<UForm
|
||||||
|
v-if="!submitted"
|
||||||
|
@submit="submitForm"
|
||||||
|
@reset="formData = {}"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="item in form.fields"
|
||||||
|
>
|
||||||
|
<p v-if="item.type === 'header'">{{item.label}}</p>
|
||||||
|
<UFormGroup
|
||||||
|
v-else-if="item.type.includes('Input')"
|
||||||
|
:label="item.required ? item.label + '*' : item.label"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-if="item.type === 'textInput'"
|
||||||
|
v-model="formData[item.key]"
|
||||||
|
:required="item.required"
|
||||||
|
/>
|
||||||
|
<UInput
|
||||||
|
v-else-if="item.type === 'numberInput'"
|
||||||
|
v-model="formData[item.key]"
|
||||||
|
:required="item.required"
|
||||||
|
type="number"
|
||||||
|
inputmode="numeric"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<UButton type="submit">
|
||||||
|
Abschicken
|
||||||
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
type="reset"
|
||||||
|
color="rose"
|
||||||
|
class="m-2"
|
||||||
|
>
|
||||||
|
Zurücksetzen
|
||||||
|
</UButton>
|
||||||
|
|
||||||
|
|
||||||
|
</UForm>
|
||||||
|
<div v-else>
|
||||||
|
Dieses Formular wurde bereits abgeschickt. Möchten Sie erneut Daten abschicken, sprechen Sie bitte Ihren Ansprechpartner an, um das Formular freizuschalten.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
|
Offene Aufgaben: {{openTasks}}<br>
|
||||||
|
Laufende Projekte:
|
||||||
|
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -7,15 +11,13 @@ definePageMeta({
|
|||||||
middleware: "auth"
|
middleware: "auth"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const {getOpenTasksCount} = useDataStore()
|
||||||
|
const openTasks = getOpenTasksCount
|
||||||
|
|
||||||
const supabase = useSupabaseClient()
|
const supabase = useSupabaseClient()
|
||||||
|
|
||||||
const tasks = (await supabase.from("tasks").select()).data
|
|
||||||
|
|
||||||
const user = useSupabaseUser()
|
const user = useSupabaseUser()
|
||||||
console.log(user)
|
|
||||||
|
|
||||||
console.log(tasks)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -66,21 +66,17 @@ function checkSpaceId(spaceId) {
|
|||||||
<div id="main">
|
<div id="main">
|
||||||
<router-link to="/inventory/spaces"><UButton>Lagerplätze</UButton></router-link>
|
<router-link to="/inventory/spaces"><UButton>Lagerplätze</UButton></router-link>
|
||||||
|
|
||||||
<!--<UInput
|
|
||||||
icon="i-heroicons-magnifying-glass-20-solid"
|
|
||||||
variant="outline"
|
|
||||||
color="primary"
|
|
||||||
placeholder="Barcode / Suche"
|
|
||||||
v-model="searchinput"
|
|
||||||
/>-->
|
|
||||||
|
|
||||||
<UButton @click="mode = 'incoming'" class="ml-3" >Wareneingang</UButton>
|
<div class="my-3">
|
||||||
<UButton @click="mode = 'outgoing'" class="ml-1">Warenausgang</UButton>
|
<UButton @click="mode = 'incoming'" class="ml-3" >Wareneingang</UButton>
|
||||||
<UButton @click="mode = 'change'" class="ml-1" disabled>Umlagern</UButton>
|
<UButton @click="mode = 'outgoing'" class="ml-1">Warenausgang</UButton>
|
||||||
|
<UButton @click="mode = 'change'" class="ml-1" disabled>Umlagern</UButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="Artikel:"
|
label="Artikel:"
|
||||||
class="mt-3"
|
class="mt-3 w-80"
|
||||||
>
|
>
|
||||||
<UInput
|
<UInput
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@@ -92,7 +88,7 @@ function checkSpaceId(spaceId) {
|
|||||||
|
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="Lagerplatz:"
|
label="Lagerplatz:"
|
||||||
class="mt-3"
|
class="mt-3 w-80"
|
||||||
><!--.map(space => {return {id: space.id, name: space.spaceNumber}}-->
|
><!--.map(space => {return {id: space.id, name: space.spaceNumber}}-->
|
||||||
<USelectMenu
|
<USelectMenu
|
||||||
:options="spaces"
|
:options="spaces"
|
||||||
@@ -106,7 +102,7 @@ function checkSpaceId(spaceId) {
|
|||||||
|
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="Anzahl:"
|
label="Anzahl:"
|
||||||
class="mt-3"
|
class="mt-3 w-80"
|
||||||
>
|
>
|
||||||
<UInput
|
<UInput
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@@ -132,8 +128,9 @@ function checkSpaceId(spaceId) {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
#main {
|
#main {
|
||||||
/*display: flex;
|
display: flex;
|
||||||
flex-direction: row;*/
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
#left {
|
#left {
|
||||||
width: 25vw;
|
width: 25vw;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {move} from "@antfu/utils";
|
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
middleware: "auth"
|
middleware: "auth"
|
||||||
@@ -7,23 +6,19 @@ definePageMeta({
|
|||||||
|
|
||||||
const supabase = useSupabaseClient()
|
const supabase = useSupabaseClient()
|
||||||
|
|
||||||
const spaces = (await supabase.from("spaces").select()).data
|
const {spaces,movements,products,units} = storeToRefs(useDataStore())
|
||||||
const movements = (await supabase.from("movements").select()).data
|
const {movementsBySpace, getProductById} = useDataStore()
|
||||||
const products = (await supabase.from("products").select()).data
|
|
||||||
const units = (await supabase.from("units").select()).data
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
console.log(movements)
|
||||||
let selectedItem = ref({})
|
let selectedItem = ref({})
|
||||||
const showCreateSpace = ref(false)
|
const showCreateSpace = ref(false)
|
||||||
|
|
||||||
const selectItem = (item) => {
|
const selectItem = (item) => {
|
||||||
selectedItem.value = item
|
selectedItem.value = item
|
||||||
spaceMovements.value = movements.filter(movement => movement.spaceId === selectedItem.value.id)
|
spaceMovements.value = movementsBySpace(item.id)//movements.filter(movement => movement.spaceId === selectedItem.value.id)
|
||||||
spaceProducts.value = []
|
spaceProducts.value = []
|
||||||
spaceMovements.value.forEach(movement => {
|
spaceMovements.value.forEach(movement => {
|
||||||
if(spaceProducts.value.filter(product => product.id === movement.productId).length === 0) spaceProducts.value.push(products.find(product => product.id === movement.productId))
|
if(spaceProducts.value.filter(product => product.id === movement.productId).length === 0) spaceProducts.value.push(getProductById(movement.productId))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -31,7 +26,7 @@ const selectItem = (item) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const spaceTypes = ["Regalplatz", "Kiste", "Palettenplatz"]
|
const spaceTypes = ["Regalplatz", "Kiste", "Palettenplatz","KFZ"]
|
||||||
|
|
||||||
const createSpaceData = ref({})
|
const createSpaceData = ref({})
|
||||||
const createSpace = async () => {
|
const createSpace = async () => {
|
||||||
@@ -112,11 +107,23 @@ function getSpaceProductCount(productId) {
|
|||||||
</template>
|
</template>
|
||||||
{{selectedItem.description}}
|
{{selectedItem.description}}
|
||||||
|
|
||||||
|
|
||||||
</UCard>
|
</UCard>
|
||||||
<div v-if="spaceProducts.length > 0">
|
<div v-if="spaceProducts.length > 0">
|
||||||
<p class="mt-5">Artikel in diesem Lagerplatz</p>
|
<p class="mt-5">Artikel in diesem Lagerplatz</p>
|
||||||
<p v-for="product in spaceProducts">{{product.name}} - {{getSpaceProductCount(product.id)}} {{units.find(unit => unit.id === product.unit).name}}</p>
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Artikel</th>
|
||||||
|
<th>Anzahl</th>
|
||||||
|
<th>Einheit</th>
|
||||||
|
</tr>
|
||||||
|
<tr v-for="product in spaceProducts">
|
||||||
|
<td>{{product.name}}</td>
|
||||||
|
<td>{{getSpaceProductCount(product.id)}}</td>
|
||||||
|
<td>{{units.find(unit => unit.id === product.unit).name}}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -138,4 +145,9 @@ function getSpaceProductCount(productId) {
|
|||||||
width: 60vw;
|
width: 60vw;
|
||||||
padding-left: 3vw;
|
padding-left: 3vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td, th {
|
||||||
|
padding: 1em;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -13,7 +13,8 @@ const onSubmit = async () => {
|
|||||||
password: password.value
|
password: password.value
|
||||||
})
|
})
|
||||||
if(error) {
|
if(error) {
|
||||||
console.log(error)
|
console.log(error.toString())
|
||||||
|
alert(error.toString())
|
||||||
} else {
|
} else {
|
||||||
console.log("Login Successful")
|
console.log("Login Successful")
|
||||||
router.push("/")
|
router.push("/")
|
||||||
|
|||||||
@@ -127,13 +127,11 @@ definePageMeta({
|
|||||||
|
|
||||||
const supabase = useSupabaseClient()
|
const supabase = useSupabaseClient()
|
||||||
|
|
||||||
const products = (await supabase.from("products").select()).data
|
const {products,units} = storeToRefs(useDataStore())
|
||||||
const units = (await supabase.from("units").select()).data
|
|
||||||
|
|
||||||
const showCreateProduct = ref(false)
|
const showCreateProduct = ref(false)
|
||||||
const createProductData = ref({})
|
const createProductData = ref({})
|
||||||
|
|
||||||
|
|
||||||
let selectedItem = ref({})
|
let selectedItem = ref({})
|
||||||
|
|
||||||
const history = ref([
|
const history = ref([
|
||||||
|
|||||||
@@ -3,9 +3,48 @@ definePageMeta({
|
|||||||
middleware: "auth"
|
middleware: "auth"
|
||||||
})
|
})
|
||||||
|
|
||||||
//const {find, findOne,create, update} = useStrapi4()
|
const supabase = useSupabaseClient()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
//let project = (await findOne('projects',route.params.id)).data
|
|
||||||
|
const {getProjectById, getFormSubmitsWithLabelProp} = useDataStore()
|
||||||
|
const {forms, formSubmits} = storeToRefs(useDataStore())
|
||||||
|
|
||||||
|
const currentProject = getProjectById(Number(route.params.id))
|
||||||
|
|
||||||
|
|
||||||
|
const formSubmissionsComposed = getFormSubmitsWithLabelProp
|
||||||
|
const formModalOpen = ref(false)
|
||||||
|
const newFormSubmissionData = ref({
|
||||||
|
formType: "",
|
||||||
|
values: {},
|
||||||
|
submitted: false
|
||||||
|
})
|
||||||
|
|
||||||
|
const addNewFormSubmission = async () => {
|
||||||
|
//Add Form Submission
|
||||||
|
const {data:insertData,error:insertError} = await supabase
|
||||||
|
.from("formSubmits")
|
||||||
|
.insert([newFormSubmissionData.value])
|
||||||
|
.select()
|
||||||
|
|
||||||
|
console.log(insertData)
|
||||||
|
console.log(insertError)
|
||||||
|
|
||||||
|
let projectForms = [...currentProject.forms, insertData[0].id ]
|
||||||
|
console.log(projectForms)
|
||||||
|
|
||||||
|
//Add Form ID to project.forms
|
||||||
|
const {data:updateData,error:updateError} = await supabase
|
||||||
|
.from("projects")
|
||||||
|
.update({forms: projectForms})
|
||||||
|
.eq('id',currentProject.id)
|
||||||
|
.select()
|
||||||
|
|
||||||
|
console.log(updateData)
|
||||||
|
console.log(updateError)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const tabItems = [
|
const tabItems = [
|
||||||
{
|
{
|
||||||
key: "phases",
|
key: "phases",
|
||||||
@@ -25,6 +64,8 @@ const selectedPhase = ref({})
|
|||||||
const changesSaved = ref(true)
|
const changesSaved = ref(true)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const default_data = {
|
const default_data = {
|
||||||
time: 1660335428612,
|
time: 1660335428612,
|
||||||
blocks: [
|
blocks: [
|
||||||
@@ -43,87 +84,25 @@ const default_data = {
|
|||||||
text: "This is a nuxt3 plugin for editorjs.",
|
text: "This is a nuxt3 plugin for editorjs.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: "R3o5BpI-r9",
|
|
||||||
type: "paragraph",
|
|
||||||
data: {
|
|
||||||
text: "<b>A paragraph of text:</b> Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore perspiciatis molestias neque autem cumque provident? Laudantium ad, quisquam quos nulla amet, perferendis recusandae voluptates eligendi cupiditate consectetur veniam! Ipsum, ullam?",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "b9mkw6ZO92",
|
|
||||||
type: "header",
|
|
||||||
data: {
|
|
||||||
text: "Heading 1",
|
|
||||||
level: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "P2PZsHo2lq",
|
|
||||||
type: "header",
|
|
||||||
data: {
|
|
||||||
text: "Heading 2",
|
|
||||||
level: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "hHJZjkW-TO",
|
|
||||||
type: "header",
|
|
||||||
data: {
|
|
||||||
text: "Heading 3",
|
|
||||||
level: 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "k8EDwa0oVG",
|
|
||||||
type: "header",
|
|
||||||
data: {
|
|
||||||
text: "Heading 4",
|
|
||||||
level: 4,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "62ciFnEFjZ",
|
|
||||||
type: "header",
|
|
||||||
data: {
|
|
||||||
text: "Heading 5",
|
|
||||||
level: 5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "YCBcKhNqib",
|
|
||||||
type: "header",
|
|
||||||
data: {
|
|
||||||
text: "Heading 6",
|
|
||||||
level: 6,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "s_J3d5U8DA",
|
|
||||||
type: "list",
|
|
||||||
data: {
|
|
||||||
style: "ordered",
|
|
||||||
items: [
|
|
||||||
"An ordered list item",
|
|
||||||
"Another ordered list item",
|
|
||||||
"One more",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "kMyQbO156y",
|
|
||||||
type: "list",
|
|
||||||
data: {
|
|
||||||
style: "unordered",
|
|
||||||
items: ["An unordered list item!", "In italics?", "Or bold?"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
version: "2.25.0",
|
version: "2.25.0",
|
||||||
};
|
};
|
||||||
const dat = ref(default_data);
|
const newProjectDescription = ref(currentProject.description || default_data.value);
|
||||||
const save = () => {
|
|
||||||
console.log(foo);
|
const saveProjectDescription = async () => {
|
||||||
|
//Update Project Description
|
||||||
|
const {data:updateData,error:updateError} = await supabase
|
||||||
|
.from("projects")
|
||||||
|
.update({description: newProjectDescription.value})
|
||||||
|
.eq('id',currentProject.id)
|
||||||
|
.select()
|
||||||
|
|
||||||
|
console.log(updateData)
|
||||||
|
console.log(updateError)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -182,12 +161,68 @@ const phaseInfo = ref({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.key === 'password'" class="space-y-3">
|
<div v-else-if="item.key === 'forms'" class="space-y-3">
|
||||||
|
<UButton
|
||||||
|
@click="formModalOpen = true"
|
||||||
|
>
|
||||||
|
+ Formular
|
||||||
|
</UButton>
|
||||||
|
<UModal
|
||||||
|
v-model="formModalOpen"
|
||||||
|
>
|
||||||
|
<UCard>
|
||||||
|
<template #header>
|
||||||
|
Formular hinzufügen
|
||||||
|
</template>
|
||||||
|
<UFormGroup>
|
||||||
|
<USelectMenu
|
||||||
|
:options="forms"
|
||||||
|
option-attribute="name"
|
||||||
|
value-attribute="id"
|
||||||
|
v-model="newFormSubmissionData.formType"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<template #footer>
|
||||||
|
<UButton
|
||||||
|
@click="addNewFormSubmission"
|
||||||
|
>
|
||||||
|
Hinzufügen
|
||||||
|
</UButton>
|
||||||
|
</template>
|
||||||
|
</UCard>
|
||||||
|
</UModal>
|
||||||
|
|
||||||
|
|
||||||
|
<UAccordion :items="formSubmissionsComposed">
|
||||||
|
<template #item="{item}">
|
||||||
|
|
||||||
|
<p class="my-3">Formular Link: <a :href="'https://app.spaces.software/formSubmissions/' + item.id">{{'https://app.spaces.software/formSubmissions/' + item.id}}</a></p>
|
||||||
|
|
||||||
|
|
||||||
|
<div v-if="Object.keys(item.values).length == 0">
|
||||||
|
<p>Es wurden noch keine Daten über das Formular abgegeben</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table v-else>
|
||||||
|
<tr v-for="key in Object.keys(item.values)">
|
||||||
|
<td>{{key}}</td>
|
||||||
|
<td>{{ item.values[key] }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</UAccordion>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.key === 'description'" class="space-y-3">
|
<div v-else-if="item.key === 'description'" class="space-y-3">
|
||||||
<client-only><editor-js v-model="dat" /></client-only>
|
<UButton
|
||||||
|
:disabled="false/*newProjectDescription.time === currentProject.description.time*/"
|
||||||
|
@click="saveProjectDescription"
|
||||||
|
>
|
||||||
|
Speichern
|
||||||
|
</UButton>
|
||||||
|
<client-only><editor-js v-model="newProjectDescription" /></client-only>
|
||||||
</div>
|
</div>
|
||||||
|
{{item}}
|
||||||
</template>
|
</template>
|
||||||
</UTabs>
|
</UTabs>
|
||||||
<!-- <div id="left">
|
<!-- <div id="left">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="main">
|
<div id="main">
|
||||||
<div id="left">
|
<div id="left">
|
||||||
|
<!-- TODO: Projekt Auflistung überarbeiten, Rechte Seite wird nicht genutzt -->
|
||||||
<UButton @click="showCreateProject = true">+ Projekt</UButton>
|
<UButton @click="showCreateProject = true">+ Projekt</UButton>
|
||||||
<UModal v-model="showCreateProject">
|
<UModal v-model="showCreateProject">
|
||||||
<UCard>
|
<UCard>
|
||||||
@@ -89,8 +89,11 @@ definePageMeta({
|
|||||||
|
|
||||||
const supabase = useSupabaseClient()
|
const supabase = useSupabaseClient()
|
||||||
|
|
||||||
const projects = (await supabase.from("projects").select()).data
|
const {projects,customers} = storeToRefs(useDataStore())
|
||||||
const customers = (await supabase.from("customers").select()).data
|
const {fetchProjects} = useDataStore()
|
||||||
|
|
||||||
|
//const projects = (await supabase.from("projects").select()).data
|
||||||
|
//const customers = (await supabase.from("customers").select()).data
|
||||||
|
|
||||||
const showCreateProject = ref(false)
|
const showCreateProject = ref(false)
|
||||||
const createProjectData = ref({
|
const createProjectData = ref({
|
||||||
@@ -114,6 +117,8 @@ const createProject = async () => {
|
|||||||
|
|
||||||
showCreateProject.value = false
|
showCreateProject.value = false
|
||||||
createProjectData.value = {phases: []}
|
createProjectData.value = {phases: []}
|
||||||
|
fetchProjects()
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<!-- TODO: Benutzer Aufgaben zuweisen und nach diesen Filtern -->
|
||||||
<UModal
|
<UModal
|
||||||
v-model="showCreateTask"
|
v-model="showCreateTask"
|
||||||
>
|
>
|
||||||
@@ -112,7 +113,7 @@
|
|||||||
<div id="taskCatList">
|
<div id="taskCatList">
|
||||||
<div id="catNew">
|
<div id="catNew">
|
||||||
<h3>Neue Aufgaben</h3>
|
<h3>Neue Aufgaben</h3>
|
||||||
<div class="taskScrollList">
|
<div class="taskScrollList" v-if="tasks.length > 0">
|
||||||
<a
|
<a
|
||||||
v-for="taskNew in tasks.filter(task => task.categorie == 'Neu')"
|
v-for="taskNew in tasks.filter(task => task.categorie == 'Neu')"
|
||||||
@click="inspectTask(taskNew)"
|
@click="inspectTask(taskNew)"
|
||||||
@@ -134,7 +135,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="catInProgress">
|
<div id="catInProgress">
|
||||||
<h3>Aufgaben in Bearbeitung</h3>
|
<h3>Aufgaben in Bearbeitung</h3>
|
||||||
<div class="taskScrollList">
|
<div class="taskScrollList" v-if="tasks.length > 0">
|
||||||
<a
|
<a
|
||||||
v-for="taskNew in tasks.filter(task => task.categorie == 'In Bearbeitung')"
|
v-for="taskNew in tasks.filter(task => task.categorie == 'In Bearbeitung')"
|
||||||
@click="inspectTask(taskNew)"
|
@click="inspectTask(taskNew)"
|
||||||
@@ -154,7 +155,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="catUrgent">
|
<div id="catUrgent">
|
||||||
<h3>Dringende Aufgaben</h3>
|
<h3>Dringende Aufgaben</h3>
|
||||||
<div class="taskScrollList">
|
<div class="taskScrollList" v-if="tasks.length > 0">
|
||||||
<a
|
<a
|
||||||
v-for="taskNew in tasks.filter(task => task.categorie == 'Dringend')"
|
v-for="taskNew in tasks.filter(task => task.categorie == 'Dringend')"
|
||||||
@click="inspectTask(taskNew)"
|
@click="inspectTask(taskNew)"
|
||||||
@@ -184,15 +185,12 @@ definePageMeta({
|
|||||||
|
|
||||||
|
|
||||||
const supabase = useSupabaseClient()
|
const supabase = useSupabaseClient()
|
||||||
|
const {tasks} = storeToRefs(useDataStore())
|
||||||
const tasks = (await supabase.from("tasks").select()).data
|
const {fetchTasks} = useDataStore()
|
||||||
|
|
||||||
|
|
||||||
let refTasks = ref([])
|
let refTasks = ref([])
|
||||||
|
|
||||||
|
|
||||||
//const users = (await find('users',{populate: "*"}))
|
|
||||||
//const users = (await supabase.from("users").select()).data
|
|
||||||
let usersForList = []
|
let usersForList = []
|
||||||
//users.forEach(user => usersForList.push(user.username))
|
//users.forEach(user => usersForList.push(user.username))
|
||||||
const usersSelected = ref([])
|
const usersSelected = ref([])
|
||||||
@@ -223,6 +221,7 @@ const createTask = async () => {
|
|||||||
|
|
||||||
showCreateTask.value = false
|
showCreateTask.value = false
|
||||||
createTaskData.value = {}
|
createTaskData.value = {}
|
||||||
|
fetchTasks()
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateTask = async () => {
|
const updateTask = async () => {
|
||||||
@@ -260,7 +259,7 @@ const finishTask = async () => {
|
|||||||
showTaskModal.value = false
|
showTaskModal.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
filterTasks()
|
//filterTasks()
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
121
spaces/pages/vendorinvoices/[id].vue
Normal file
121
spaces/pages/vendorinvoices/[id].vue
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<div id="main">
|
||||||
|
<div
|
||||||
|
class="previewDoc"
|
||||||
|
>
|
||||||
|
<embed
|
||||||
|
:src="fileurl"
|
||||||
|
|
||||||
|
>
|
||||||
|
{{documents}}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="inputData"
|
||||||
|
>
|
||||||
|
<UFormGroup label="Lieferant:" required>
|
||||||
|
<UInput />
|
||||||
|
</UFormGroup>
|
||||||
|
|
||||||
|
<UFormGroup label="Rechnungsreferenz:" required>
|
||||||
|
<UInput />
|
||||||
|
</UFormGroup>
|
||||||
|
|
||||||
|
<UFormGroup label="Rechnungsdatum:" required>
|
||||||
|
<UInput />
|
||||||
|
</UFormGroup>
|
||||||
|
|
||||||
|
<UButton @click="vendorInvoiceData.lineItems.push({})">+ Reihe</UButton>
|
||||||
|
|
||||||
|
|
||||||
|
<div v-for="lineItem in vendorInvoiceData.lineItems" class="lineItemRow">
|
||||||
|
<UFormGroup label="Text:" required>
|
||||||
|
<UInput v-model="lineItem.text"/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup label="Produkt:" required>
|
||||||
|
<UInput v-model="lineItem.productId"/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup label="Projekt:" required>
|
||||||
|
<UInput v-model="lineItem.projectId"/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup label="Anzahl:" required>
|
||||||
|
<UInput v-model="lineItem.quantity"/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup label="Einheit:" required>
|
||||||
|
<UInput v-model="lineItem.unit"/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup label="Einzelpreis:" required>
|
||||||
|
<UInput v-model="lineItem.unitPriceNet"/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup label="USt:" required>
|
||||||
|
<UInput v-model="lineItem.vat"/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup label="Rabatt:" required>
|
||||||
|
<UInput v-model="lineItem.discount"/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup label="Buchungskonto:" required>
|
||||||
|
<UInput v-model="lineItem.skrAccountId"/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup label="Positionspreis:" required>
|
||||||
|
<UInput disabled/>
|
||||||
|
</UFormGroup>
|
||||||
|
</div>
|
||||||
|
{{vendorInvoiceData}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const supabase = useSupabaseClient()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
const currentVendorInvoice = (await supabase.from('vendorInvoices').select().eq('id', route.params.id)).data
|
||||||
|
const document = (await supabase.from('documents').select().eq("id",18)).data[0]
|
||||||
|
|
||||||
|
console.log(currentVendorInvoice)
|
||||||
|
console.log(document)
|
||||||
|
|
||||||
|
let fileurl = (await supabase.storage.from('documents').createSignedUrl(document.path,60*60)).data.signedUrl
|
||||||
|
|
||||||
|
|
||||||
|
let vendorInvoiceData = ref({
|
||||||
|
reference: "",
|
||||||
|
date: "",
|
||||||
|
vendorId: 0,
|
||||||
|
lineItems: []
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
#main {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.previewDoc {
|
||||||
|
width: 50vw;
|
||||||
|
min-height: 80vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.previewDoc embed {
|
||||||
|
width: 90%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputData {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.lineItemRow {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div id="main">
|
|
||||||
<UFormGroup label="Lieferant:" required>
|
|
||||||
<UInput />
|
|
||||||
</UFormGroup>
|
|
||||||
|
|
||||||
<UFormGroup label="Rechnungsreferenz:" required>
|
|
||||||
<UInput />
|
|
||||||
</UFormGroup>
|
|
||||||
|
|
||||||
<UFormGroup label="Rechnungsdatum:" required>
|
|
||||||
<UInput />
|
|
||||||
</UFormGroup>
|
|
||||||
|
|
||||||
<UButton @click="vendorInvoiceData.lineItems.push({})">+ Reihe</UButton>
|
|
||||||
|
|
||||||
|
|
||||||
<div v-for="lineItem in vendorInvoiceData.lineItems" class="lineItemRow">
|
|
||||||
<UFormGroup label="Text:" required>
|
|
||||||
<UInput v-model="lineItem.text"/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup label="Produkt:" required>
|
|
||||||
<UInput v-model="lineItem.productId"/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup label="Projekt:" required>
|
|
||||||
<UInput v-model="lineItem.projectId"/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup label="Anzahl:" required>
|
|
||||||
<UInput v-model="lineItem.quantity"/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup label="Einheit:" required>
|
|
||||||
<UInput v-model="lineItem.unit"/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup label="Einzelpreis:" required>
|
|
||||||
<UInput v-model="lineItem.unitPriceNet"/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup label="USt:" required>
|
|
||||||
<UInput v-model="lineItem.vat"/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup label="Rabatt:" required>
|
|
||||||
<UInput v-model="lineItem.discount"/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup label="Buchungskonto:" required>
|
|
||||||
<UInput v-model="lineItem.skrAccountId"/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup label="Positionspreis:" required>
|
|
||||||
<UInput disabled/>
|
|
||||||
</UFormGroup>
|
|
||||||
</div>
|
|
||||||
{{vendorInvoiceData}}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
|
|
||||||
let vendorInvoiceData = ref({
|
|
||||||
reference: "",
|
|
||||||
date: "",
|
|
||||||
vendorId: 0,
|
|
||||||
lineItems: []
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.lineItemRow {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
import {useDataStore} from "../../store/data";
|
import {useDataStore} from "~/stores/data.ts";
|
||||||
import {storeToRefs} from "pinia"
|
import {storeToRefs} from "pinia"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
BIN
spaces/public/fonts/Roboto-Bold.woff
Executable file
BIN
spaces/public/fonts/Roboto-Bold.woff
Executable file
Binary file not shown.
BIN
spaces/public/fonts/Roboto-Bold.woff2
Executable file
BIN
spaces/public/fonts/Roboto-Bold.woff2
Executable file
Binary file not shown.
BIN
spaces/public/fonts/Roboto-Light.woff
Executable file
BIN
spaces/public/fonts/Roboto-Light.woff
Executable file
Binary file not shown.
BIN
spaces/public/fonts/Roboto-Light.woff2
Executable file
BIN
spaces/public/fonts/Roboto-Light.woff2
Executable file
Binary file not shown.
BIN
spaces/public/fonts/Roboto-Medium.woff
Executable file
BIN
spaces/public/fonts/Roboto-Medium.woff
Executable file
Binary file not shown.
BIN
spaces/public/fonts/Roboto-Medium.woff2
Executable file
BIN
spaces/public/fonts/Roboto-Medium.woff2
Executable file
Binary file not shown.
BIN
spaces/public/fonts/Roboto-Regular.woff
Executable file
BIN
spaces/public/fonts/Roboto-Regular.woff
Executable file
Binary file not shown.
BIN
spaces/public/fonts/Roboto-Regular.woff2
Executable file
BIN
spaces/public/fonts/Roboto-Regular.woff2
Executable file
Binary file not shown.
BIN
spaces/public/fonts/fa-brands-400.ttf
Executable file
BIN
spaces/public/fonts/fa-brands-400.ttf
Executable file
Binary file not shown.
BIN
spaces/public/fonts/fa-brands-400.woff2
Executable file
BIN
spaces/public/fonts/fa-brands-400.woff2
Executable file
Binary file not shown.
BIN
spaces/public/fonts/fa-regular-400.ttf
Executable file
BIN
spaces/public/fonts/fa-regular-400.ttf
Executable file
Binary file not shown.
BIN
spaces/public/fonts/fa-regular-400.woff2
Executable file
BIN
spaces/public/fonts/fa-regular-400.woff2
Executable file
Binary file not shown.
BIN
spaces/public/fonts/fa-solid-900.ttf
Executable file
BIN
spaces/public/fonts/fa-solid-900.ttf
Executable file
Binary file not shown.
BIN
spaces/public/fonts/fa-solid-900.woff2
Executable file
BIN
spaces/public/fonts/fa-solid-900.woff2
Executable file
Binary file not shown.
BIN
spaces/public/fonts/fa-v4compatibility.ttf
Executable file
BIN
spaces/public/fonts/fa-v4compatibility.ttf
Executable file
Binary file not shown.
BIN
spaces/public/fonts/fa-v4compatibility.woff2
Executable file
BIN
spaces/public/fonts/fa-v4compatibility.woff2
Executable file
Binary file not shown.
1
spaces/public/grid.stockholm.css.map
Normal file
1
spaces/public/grid.stockholm.css.map
Normal file
File diff suppressed because one or more lines are too long
16
spaces/public/grid.stockholm.min.css
vendored
Normal file
16
spaces/public/grid.stockholm.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
7
spaces/public/grid.stockholm.min.css.map
Normal file
7
spaces/public/grid.stockholm.min.css.map
Normal file
File diff suppressed because one or more lines are too long
@@ -1,236 +0,0 @@
|
|||||||
import {defineStore} from 'pinia'
|
|
||||||
import {CustomerInfo, ProjectInfo, VendorInvoice, ProductInfo} from "@/misc/interfaces";
|
|
||||||
|
|
||||||
export const useDataStore = defineStore('dataStore', {
|
|
||||||
state: () => {
|
|
||||||
return {
|
|
||||||
customers: [
|
|
||||||
{
|
|
||||||
id: 10069,
|
|
||||||
name: "NOA Service GmbH",
|
|
||||||
addresses: [
|
|
||||||
{
|
|
||||||
type: "invoice",
|
|
||||||
street: "Oldenburger Str. ",
|
|
||||||
number: "52",
|
|
||||||
zip: 26340,
|
|
||||||
city: "Zetel"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
contacts: [
|
|
||||||
{
|
|
||||||
name: "Noa",
|
|
||||||
firstname: "Stefanie",
|
|
||||||
role: "Geschäftsführerin",
|
|
||||||
email: ""
|
|
||||||
}, {
|
|
||||||
name: "Kramer",
|
|
||||||
firstname: "Lena",
|
|
||||||
role: "",
|
|
||||||
email: ""
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10083,
|
|
||||||
name: "Specht Reepsholt e.K.",
|
|
||||||
addresses: [
|
|
||||||
{
|
|
||||||
type: "invoice",
|
|
||||||
street: "Reepsholter Hauptstr. ",
|
|
||||||
number: "17",
|
|
||||||
zip: 26446,
|
|
||||||
city: "Reepsholt"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
contacts: [
|
|
||||||
{
|
|
||||||
name: "Specht",
|
|
||||||
firstname: "Oliver",
|
|
||||||
role: "",
|
|
||||||
email: ""
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10023,
|
|
||||||
name: "M&K Nordsonne GmbH & Co. KG",
|
|
||||||
addresses: [
|
|
||||||
{
|
|
||||||
type: "invoice",
|
|
||||||
street: "Berghamm",
|
|
||||||
number: "1",
|
|
||||||
zip: 26434,
|
|
||||||
city: "Wangerland"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
contacts: [
|
|
||||||
{
|
|
||||||
name: "Mick",
|
|
||||||
firstname: "Martin",
|
|
||||||
role: "Geschäftsführer",
|
|
||||||
email: ""
|
|
||||||
}, {
|
|
||||||
name: "Obst",
|
|
||||||
firstname: "Yvonne",
|
|
||||||
role: "",
|
|
||||||
email: ""
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
] as CustomerInfo[],
|
|
||||||
projects: [
|
|
||||||
{
|
|
||||||
id: 1001,
|
|
||||||
name: "FRIOS052PV001",
|
|
||||||
customerId: 10069,
|
|
||||||
notes: ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 1002,
|
|
||||||
name: "WTMRH017PV001",
|
|
||||||
customerId: 10083,
|
|
||||||
notes: ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 1003,
|
|
||||||
name: "Kamerainstallation WHVAS19",
|
|
||||||
customerId: 10069,
|
|
||||||
notes: ""
|
|
||||||
}
|
|
||||||
] as ProjectInfo[],
|
|
||||||
vendorInvoices: [
|
|
||||||
{
|
|
||||||
id: 230001,
|
|
||||||
vendorId: 10001,
|
|
||||||
date: "2023-11-01",
|
|
||||||
reference: "2023-11-01-1000",
|
|
||||||
lineItems: [
|
|
||||||
{
|
|
||||||
pos: 0,
|
|
||||||
text: "Ja Solar",
|
|
||||||
projectId: 1001,
|
|
||||||
quantity: 10,
|
|
||||||
unit: "Stk",
|
|
||||||
unitPriceNet: 120.50,
|
|
||||||
vat: 19,
|
|
||||||
skrAccountId: 3400
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 230002,
|
|
||||||
vendorId: 10001,
|
|
||||||
date: "2023-10-29",
|
|
||||||
reference: "2023-11-01-1001",
|
|
||||||
lineItems: [
|
|
||||||
{
|
|
||||||
pos: 0,
|
|
||||||
productId: 10003,
|
|
||||||
projectId: 1003,
|
|
||||||
quantity: 3,
|
|
||||||
unit: "Stk",
|
|
||||||
unitPriceNet: 96.00,
|
|
||||||
vat: 19,
|
|
||||||
skrAccountId: 3400
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
] as VendorInvoice[],
|
|
||||||
products: [
|
|
||||||
{
|
|
||||||
id:10001,
|
|
||||||
name: "STP-10SE",
|
|
||||||
manufacturer: "SMA",
|
|
||||||
purchasePriceNet: 1500.00,
|
|
||||||
profitPercentage: 20,
|
|
||||||
retailPriceNet: 1800.00,
|
|
||||||
tags: ["pv","wechselrichter"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id:10002,
|
|
||||||
name: "RLC-810A",
|
|
||||||
manufacturer: "Reolink",
|
|
||||||
purchasePriceNet: 80.00,
|
|
||||||
profitPercentage: 20,
|
|
||||||
retailPriceNet: 96.00,
|
|
||||||
tags: ["kamera","outdoor","lan","poe"],
|
|
||||||
optionalProductIds: [10003]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id:10003,
|
|
||||||
name: "RLC-510WA",
|
|
||||||
manufacturer: "Reolink",
|
|
||||||
purchasePriceNet: 80.00,
|
|
||||||
profitPercentage: 20,
|
|
||||||
retailPriceNet: 96.00,
|
|
||||||
tags: ["kamera","outdoor","wlan"],
|
|
||||||
optionalProductIds: [10002]
|
|
||||||
}
|
|
||||||
] as ProductInfo[],
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
async getData(){
|
|
||||||
const {data} = await useFetch("/api/customers")
|
|
||||||
console.log(data)
|
|
||||||
// @ts-ignore
|
|
||||||
this.customers = data
|
|
||||||
|
|
||||||
},
|
|
||||||
addCustomer(value: CustomerInfo) {
|
|
||||||
this.customers.push(value)
|
|
||||||
},
|
|
||||||
addProject(value: ProjectInfo){
|
|
||||||
this.projects.push(value)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getters: {
|
|
||||||
customerList(state){
|
|
||||||
return state.customers
|
|
||||||
},
|
|
||||||
customersForSelect(state){
|
|
||||||
return state.customers.map((customer:any) => {return {label: customer.name, value: customer.id}})
|
|
||||||
},
|
|
||||||
getCustomerById: (state) => (id:number) => state.customers.find((customer:any) => customer.id === id),
|
|
||||||
projectList(state){
|
|
||||||
return state.projects
|
|
||||||
},
|
|
||||||
getVendorInvoiceList: (state) => state.vendorInvoices,
|
|
||||||
getVendorInvoicesByProjectId: (state) => (id:number) => {
|
|
||||||
let invoices:any[] = []
|
|
||||||
|
|
||||||
state.vendorInvoices.forEach((invoice:any) => {
|
|
||||||
//Store Current Invoice Data
|
|
||||||
let temp:any = {
|
|
||||||
vendorInvoiceId: 0,
|
|
||||||
value: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check if Current Invoice Contains Relevant Data
|
|
||||||
if(invoice.lineItems.filter((lineItem:any) => lineItem.projectId === id).length > 0) {
|
|
||||||
console.log("in if")
|
|
||||||
temp.vendorInvoiceId = invoice.id
|
|
||||||
invoice.lineItems.filter((lineItem:any) => lineItem.projectId === id).forEach((lineItem:any) => {
|
|
||||||
console.log(temp)
|
|
||||||
temp.value = Number(temp.value) + lineItem.quantity * lineItem.unitPriceNet
|
|
||||||
console.log(lineItem)
|
|
||||||
})
|
|
||||||
|
|
||||||
temp.value = String(temp.value.toFixed(2)) + "€"
|
|
||||||
|
|
||||||
invoices.push(temp)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
return invoices
|
|
||||||
},
|
|
||||||
getProductsList: (state) => state.products
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
92
spaces/stores/data.ts
Normal file
92
spaces/stores/data.ts
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import {defineStore} from 'pinia'
|
||||||
|
|
||||||
|
import {createClient} from '@supabase/supabase-js'
|
||||||
|
|
||||||
|
const supabase = createClient('https://uwppvcxflrcsibuzsbil.supabase.co','eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV3cHB2Y3hmbHJjc2lidXpzYmlsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDA5MzgxOTQsImV4cCI6MjAxNjUxNDE5NH0.CkxYSQH0uLfwx9GVUlO6AYMU2FMLAxGMrwEKvyPv7Oo')
|
||||||
|
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
export const useDataStore = defineStore('data', {
|
||||||
|
state: () => ({
|
||||||
|
loaded: false,
|
||||||
|
customers: [] as any[],
|
||||||
|
tasks: [] as any[],
|
||||||
|
projects: [] as any[],
|
||||||
|
documents: [] as any[],
|
||||||
|
spaces: [] as any[],
|
||||||
|
units: [] as any[],
|
||||||
|
times: [] as any[],
|
||||||
|
products: [] as any[],
|
||||||
|
movements: [] as any[],
|
||||||
|
forms: [] as any[],
|
||||||
|
formSubmits: [] as any[],
|
||||||
|
contact: [] as any[]
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
async fetchData() {
|
||||||
|
await this.fetchCustomers()
|
||||||
|
await this.fetchTasks()
|
||||||
|
await this.fetchForms()
|
||||||
|
await this.fetchFormSubmits()
|
||||||
|
await this.fetchProducts()
|
||||||
|
await this.fetchUnits()
|
||||||
|
await this.fetchProjects()
|
||||||
|
await this.fetchDocuments()
|
||||||
|
await this.fetchMovements()
|
||||||
|
await this.fetchSpaces()
|
||||||
|
this.loaded = true
|
||||||
|
},
|
||||||
|
async fetchCustomers() {
|
||||||
|
// @ts-ignore
|
||||||
|
this.customers = (await supabase.from("customers").select().order('customerNumber', {ascending: true})).data
|
||||||
|
},
|
||||||
|
async fetchTasks() {
|
||||||
|
// @ts-ignore
|
||||||
|
this.tasks = (await supabase.from("tasks").select()).data
|
||||||
|
},
|
||||||
|
async fetchForms() {
|
||||||
|
// @ts-ignore
|
||||||
|
this.forms = (await supabase.from("forms").select()).data
|
||||||
|
},
|
||||||
|
async fetchFormSubmits() {
|
||||||
|
// @ts-ignore
|
||||||
|
this.formSubmits = (await supabase.from("formSubmits").select()).data
|
||||||
|
},
|
||||||
|
async fetchProducts() {
|
||||||
|
// @ts-ignore
|
||||||
|
this.products = (await supabase.from("products").select()).data
|
||||||
|
},
|
||||||
|
async fetchUnits() {
|
||||||
|
// @ts-ignore
|
||||||
|
this.units = (await supabase.from("units").select()).data
|
||||||
|
},
|
||||||
|
async fetchProjects() {
|
||||||
|
// @ts-ignore
|
||||||
|
this.projects = (await supabase.from("projects").select()).data
|
||||||
|
},
|
||||||
|
async fetchSpaces() {
|
||||||
|
// @ts-ignore
|
||||||
|
this.spaces = (await supabase.from("spaces").select().order('spaceNumber', {ascending: true})).data
|
||||||
|
},
|
||||||
|
async fetchMovements() {
|
||||||
|
// @ts-ignore
|
||||||
|
this.movements = (await supabase.from("movements").select()).data
|
||||||
|
},
|
||||||
|
async fetchDocuments() {
|
||||||
|
// @ts-ignore
|
||||||
|
this.documents = (await supabase.from("documents").select()).data
|
||||||
|
|
||||||
|
for(const [index,doc] of this.documents.entries()){
|
||||||
|
// @ts-ignore
|
||||||
|
this.documents[index].url = (await supabase.storage.from('documents').createSignedUrl(doc.path, 60 * 60)).data.signedUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
getOpenTasksCount: (state) => state.tasks.filter(task => task.categorie != "Erledigt").length,
|
||||||
|
movementsBySpace: (state) => (spaceId:number) => state.movements.filter(move => move.spaceId === spaceId),
|
||||||
|
getProductById: (state) => (productId:number) => state.products.find(product => product.id === productId),
|
||||||
|
getProjectById: (state) => (projectId:number) => state.projects.find(project => project.id === projectId),
|
||||||
|
getFormSubmitsWithLabelProp: (state) => (state.formSubmits.map(submit => {return{...submit, label: submit.id}}))
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -50,7 +50,8 @@ const uploadAttachmentToSupabase = async (tenant, folder ,file ) => {
|
|||||||
object: storageData.id,
|
object: storageData.id,
|
||||||
folder: folder,
|
folder: folder,
|
||||||
tags: ["E-Mail Anhang"],
|
tags: ["E-Mail Anhang"],
|
||||||
path: storageData.path
|
path: storageData.path,
|
||||||
|
tenant: tenant
|
||||||
|
|
||||||
})
|
})
|
||||||
.select()
|
.select()
|
||||||
|
|||||||
Reference in New Issue
Block a user