New Backend changes

This commit is contained in:
2025-09-02 18:47:12 +02:00
parent 6d76acc0bc
commit 27af6a0953
54 changed files with 485 additions and 684 deletions

View File

@@ -66,18 +66,18 @@ const showFile = (file) => {
<style scoped>
.documentListItem {
display:block;
display: block;
width: 15vw;
aspect-ratio: 1 / 1.414;
padding:1em;
padding: 1em;
margin: 0.7em;
border: 1px solid lightgrey;
border-radius: 15px;
transition: box-shadow 0.2s ease; /* für smooth hover */
}
.documentListItem:hover {
border: 1px solid #69c350;
cursor: pointer;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); /* sanfter Shadow beim Hover */
}
.previewEmbed {

View File

@@ -1,7 +1,6 @@
<script setup>
const toast = useToast()
const supabase = useSupabaseClient()
const dataStore = useDataStore()
const modal = useModal()
const props = defineProps({
@@ -27,7 +26,7 @@ const filetypes = ref([])
const documentboxes = ref([])
const setup = async () => {
const {data} = await supabase.from("folders").select().eq("tenant",useProfileStore().currentTenant)
const data = await useEntities("folders").select()
data.forEach(folder => {
let name = folder.name
@@ -55,20 +54,12 @@ const setup = async () => {
}
})
filetypes.value = await useSupabaseSelect("filetags")
documentboxes.value = await useSupabaseSelect("documentboxes")
filetypes.value = await useEntities("filetags").select()
documentboxes.value = await useEntities("documentboxes").select()
}
setup()
//Functions
const openDocument = async () => {
//selectedDocument.value = doc
openShowModal.value = true
console.log("open")
}
const updateDocument = async () => {
const {url, ...objData} = props.documentData
delete objData.url
@@ -91,12 +82,7 @@ const updateDocument = async () => {
console.log(objData)
const {data,error} = await supabase
.from("files")
.update(objData)
.eq('id',objData.id)
.select()
const {data,error} = await useEntities("files").update(objData.id, objData)
if(error) {
console.log(error)
@@ -114,13 +100,6 @@ const archiveDocument = async () => {
props.documentData.archived = true
await updateDocument()
const {data,error} = await supabase.from("historyitems").insert({
createdBy: useProfileStore().activeProfile.id,
tenant: useProfileStore().currentTenant,
text: "Datei archiviert",
file: props.documentData.id
})
modal.close()
emit("update")
}
@@ -139,19 +118,19 @@ const itemOptions = ref([])
const idToAssign = ref(null)
const getItemsBySelectedResource = async () => {
if(resourceToAssign.value === "project") {
itemOptions.value = await useSupabaseSelect("projects")
itemOptions.value = await useEntities("projects").select()
} else if(resourceToAssign.value === "customer") {
itemOptions.value = await useSupabaseSelect("customers")
itemOptions.value = await useEntities("customers").select()
} else if(resourceToAssign.value === "vendor") {
itemOptions.value = await useSupabaseSelect("vendors")
itemOptions.value = await useEntities("vendors").select()
} else if(resourceToAssign.value === "vehicle") {
itemOptions.value = await useSupabaseSelect("vehicles")
itemOptions.value = await useEntities("vehicles").select()
} else if(resourceToAssign.value === "product") {
itemOptions.value = await useSupabaseSelect("products")
itemOptions.value = await useEntities("products").select()
} else if(resourceToAssign.value === "plant") {
itemOptions.value = await useSupabaseSelect("plants")
itemOptions.value = await useEntities("plants").select()
} else if(resourceToAssign.value === "contract") {
itemOptions.value = await useSupabaseSelect("contracts")
itemOptions.value = await useEntities("contracts").select()
} else {
itemOptions.value = []
}
@@ -165,20 +144,9 @@ const updateDocumentAssignment = async () => {
const folderToMoveTo = ref(null)
const moveFile = async () => {
console.log(folderToMoveTo.value)
const {data,error} = await supabase
.from("files")
.update({folder: folderToMoveTo.value})
.eq("id",props.documentData.id)
.select()
if(error) {
console.log(error)
toast.add({title: "Fehler beim verschieben", color:"rose"})
} else {
toast.add({title: "Datei verschoben"})
console.log(data)
}
const res = await useEntities("files").update(props.documentData.id, {folder: folderToMoveTo.value})
modal.close()
}

View File

@@ -18,7 +18,7 @@ const uploadInProgress = ref(false)
const availableFiletypes = ref([])
const setup = async () => {
availableFiletypes.value = await useSupabaseSelect("filetags")
availableFiletypes.value = await useEntities("filetags").select()
}
setup()

View File

@@ -18,9 +18,17 @@ const props = defineProps({
},
platform: {
required: true,
},
loading: {
required: true,
type: Boolean,
default: false
}
})
const emit = defineEmits(["sort"]);
const {type} = props
defineShortcuts({
@@ -176,9 +184,11 @@ const filteredRows = computed(() => {
/>
<EntityTable
v-else
@sort="(i) => emit('sort',i)"
:type="props.type"
:columns="columns"
:rows="filteredRows"
:loading="props.loading"
/>
</template>

View File

@@ -158,22 +158,6 @@ const onTabChange = (index) => {
v-else-if="!props.inModal && platform === 'mobile'"
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
>
<!-- <template #left>
<UButton
icon="i-heroicons-chevron-left"
variant="outline"
@click="router.back()/*router.push(`/standardEntity/${type}`)*/"
>
Zurück
</UButton>
<UButton
icon="i-heroicons-chevron-left"
variant="outline"
@click="router.push(`/standardEntity/${type}`)"
>
Übersicht
</UButton>
</template>-->
<template #toggle>
<div></div>
</template>
@@ -217,7 +201,7 @@ const onTabChange = (index) => {
/>
</div>
<!--<EntityShowSubFiles
<EntityShowSubFiles
:item="props.item"
:query-string-data="getAvailableQueryStringData()"
v-else-if="tab.label === 'Dateien'"
@@ -226,6 +210,7 @@ const onTabChange = (index) => {
@updateNeeded="emit('updateNeeded')"
:platform="platform"
/>
<!-- TODO Change Active Phase -->
<EntityShowSubPhases
:item="props.item"
:top-level-type="type"
@@ -234,14 +219,14 @@ const onTabChange = (index) => {
@updateNeeded="emit('updateNeeded')"
:platform="platform"
/>
<EntityShowSubCreatedDocuments
<EntityShowSubCreatedDocuments
:item="props.item"
:top-level-type="type"
v-else-if="tab.label === 'Ausgangsbelege'"
:query-string-data="getAvailableQueryStringData()"
:platform="platform"
/>
<EntityShowSubCostCentreReport
<EntityShowSubCostCentreReport
:top-level-type="type"
:item="props.item"
v-else-if="tab.label === 'Auswertung Kostenstelle'"
@@ -259,16 +244,15 @@ const onTabChange = (index) => {
v-else-if="tab.label === 'Zeiten'"
:platform="platform"
/>
<EntityShowSub
:item="props.item"
:query-string-data="getAvailableQueryStringData()"
:tab-label="tab.label"
:top-level-type="type"
:type="tab.key"
v-else
:platform="platform"
/>-->
/>
</template>
</UTabs>
<UDashboardPanelContent v-else style="overflow-x: hidden;">

View File

@@ -27,8 +27,6 @@ const props = defineProps({
let type = ref("")
const dataStore = useDataStore()
const tempStore = useTempStore()
@@ -42,6 +40,7 @@ const columns = computed(() => dataType.templateColumns.filter((column) => !colu
const loaded = ref(false)
const setup = () => {
if(!props.type && props.tabLabel ) {
if(props.tabLabel === "Aufgaben") {
type.value = "tasks"

View File

@@ -61,7 +61,8 @@ const router = useRouter()
const createddocuments = ref([])
const setup = async () => {
createddocuments.value = (await useSupabaseSelect("createddocuments")).filter(i => !i.archived)
//createddocuments.value = (await useSupabaseSelect("createddocuments")).filter(i => !i.archived)
createddocuments.value = (await useEntities("createddocuments").select()).filter(i => !i.archived)
}
setup()
@@ -150,6 +151,7 @@ const selectItem = (item) => {
<span>Ausgangsbelege</span>
</template>
<Toolbar>
<!-- TODO Rendering when Screen is too small -->
<UButton
@click="invoiceDeliveryNotes"
v-if="props.topLevelType === 'projects'"

View File

@@ -31,7 +31,7 @@ const availableFiles = ref([])
const setup = async () => {
if(props.item.files) {
availableFiles.value = await files.selectSomeDocuments(props.item.files.map(i => i.id)) || []
availableFiles.value = (await files.selectSomeDocuments(props.item.files.map(i => i.id))) || []
}
}
@@ -51,12 +51,12 @@ setup()
@uploadFinished="emit('updateNeeded')"
/>
</Toolbar>
<DocumentList
:key="props.item.files.length"
:documents="availableFiles"
v-if="availableFiles.length > 0"
/>
<UAlert
v-else
icon="i-heroicons-x-mark"

View File

@@ -26,7 +26,6 @@
}
}
})
const props = defineProps({
rows: {
type: Array,
@@ -40,9 +39,16 @@
type: {
type: String,
required: true,
},
loading: {
type: Boolean,
required: true,
default: false
}
})
const emit = defineEmits(["sort"]);
const dataStore = useDataStore()
const router = useRouter()
@@ -50,12 +56,20 @@
const dataType = dataStore.dataTypes[props.type]
const selectedItem = ref(0)
const sort = ref({
column: dataType.supabaseSortColumn || "date",
direction: 'desc'
})
</script>
<template>
<UTable
:loading="props.loading"
:loading-state="{ icon: 'i-heroicons-arrow-path-20-solid', label: 'Loading...' }"
sort-mode="manual"
v-model:sort="sort"
@update:sort="emit('sort',{sort_column: sort.column, sort_direction: sort.direction})"
v-if="dataType && columns"
:rows="props.rows"
:columns="props.columns"
@@ -64,11 +78,11 @@
@select="(i) => router.push(`/standardEntity/${type}/show/${i.id}`) "
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: `Keine ${dataType.label} anzuzeigen` }"
>
<template
<!-- <template
v-for="column in dataType.templateColumns.filter(i => !i.disabledInTable)"
v-slot:[`${column.key}-header`]="{row}">
<span class="text-nowrap">{{column.label}}</span>
</template>
</template>-->
<template #name-data="{row}">
<span
v-if="row.id === props.rows[selectedItem].id"

View File

@@ -7,7 +7,7 @@ const {has} = usePermission()
const links = computed(() => {
return [
...auth.profile.pinned_on_navigation.map(pin => {
...(auth.profile?.pinned_on_navigation || []).map(pin => {
if(pin.type === "external") {
return {
label: pin.label,
@@ -92,7 +92,7 @@ const links = computed(() => {
label: "E-Mail",
to: "/email/new",
icon: "i-heroicons-envelope"
}, {
}/*, {
label: "Logbücher",
to: "/communication/historyItems",
icon: "i-heroicons-book-open"
@@ -100,7 +100,7 @@ const links = computed(() => {
label: "Chats",
to: "/chats",
icon: "i-heroicons-chat-bubble-left"
}
}*/
]
},
... (has("customers") || has("vendors") || has("contacts")) ? [{
@@ -152,7 +152,7 @@ const links = computed(() => {
},
]
},
... true ? [{
... [{
label: "Buchhaltung",
defaultOpen: false,
icon: "i-heroicons-chart-bar-square",
@@ -188,7 +188,7 @@ const links = computed(() => {
icon: "i-heroicons-document-text"
},
]
},] : [],
}],
... has("inventory") ? [{
label: "Lager",
icon: "i-heroicons-puzzle-piece",
@@ -345,11 +345,14 @@ const links = computed(() => {
<UButton
:variant="item.pinned ? 'ghost' : 'ghost'"
:color="(item.to && route.path === item.to) || (item.children?.some(c => route.path.includes(c.to))) ? 'primary' : (item.pinned ? 'amber' : 'gray')"
:icon="item.icon"
:icon="item.pinned ? 'i-heroicons-star' : item.icon"
class="w-full"
:to="item.to"
:target="item.target"
>
<UIcon
v-if="item.pinned"
:name="item.icon" class="w-5 h-5 me-2" />
{{ item.label }}
<template v-if="item.children" #trailing>
@@ -363,7 +366,7 @@ const links = computed(() => {
</template>
<template #item="{ item }">
<div class="flex flex-col">
<div class="flex flex-col" v-if="item.children?.length > 0">
<UButton
v-for="child in item.children"
:key="child.label"
@@ -379,55 +382,5 @@ const links = computed(() => {
</div>
</template>
</UAccordion>
<!-- <div
v-for="item in links"
>
<UAccordion
v-if="item.children"
:items="[item]"
>
<template #default="{item,index,open}">
<UButton
variant="ghost"
:color="item.children.find(i => route.path.includes(i.to)) ? 'primary' : 'gray'"
:icon="item.icon"
>
{{item.label}}
<template #trailing>
<UIcon
name="i-heroicons-chevron-right-20-solid"
class="w-5 h-5 ms-auto transform transition-transform duration-200"
:class="[open && 'rotate-90']"
/>
</template>
</UButton>
</template>
<template #item="{item, open}">
<div class="flex flex-col">
<UButton
variant="ghost"
:color="child.to === route.path ? 'primary' : 'gray'"
:icon="child.icon"
v-for="child in item.children"
class="ml-4"
:to="child.to"
:target="child.target"
>
{{child.label}}
</UButton>
</div>
</template>
</UAccordion>
<UButton
v-else
variant="ghost"
:color="item.to === route.path ? 'primary' : 'gray'"
class="w-full"
:icon="item.icon"
:to="item.to"
>
{{item.label}}
</UButton>
</div>-->
</template>

View File

@@ -13,7 +13,7 @@ const props = defineProps({
const incomingInvoices = ref({})
const setupPage = async () => {
incomingInvoices.value = (await supabase.from("incominginvoices").select().eq("tenant", profileStore.currentTenant)).data.filter(i => i.accounts.find(x => x.costCentre === props.item.id))
incomingInvoices.value = (await useEntities("incominginvoices").select()).filter(i => i.accounts.find(x => x.costCentre === props.item.id))
}
setupPage()

View File

@@ -7,9 +7,9 @@ let unallocatedStatements = ref(0)
let bankaccounts = ref([])
const setupPage = async () => {
let bankstatements = (await useSupabaseSelect("bankstatements","*, statementallocations(*)","date",true)).filter(i => !i.archived)
let bankstatements = (await useEntities("bankstatements").select("*, statementallocations(*)","date",true)).filter(i => !i.archived)
unallocatedStatements.value = bankstatements.filter(i => Number(calculateOpenSum(i)) !== 0).length
bankaccounts.value = await useSupabaseSelect("bankaccounts")
bankaccounts.value = await useEntities("bankaccounts").select()
}
setupPage()

View File

@@ -4,21 +4,20 @@ import dayjs from "dayjs";
dayjs.extend(customParseFormat)
const supabase = useSupabaseClient()
const dataStore = useDataStore()
const profileStore = useProfileStore()
let incomeData = ref({})
let expenseData = ref({})
const setup = async () => {
let incomeRawData = (await supabase.from("createddocuments").select().eq("tenant",profileStore.currentTenant).eq("state","Gebucht").in('type',['invoices','advanceInvoices','cancellationInvoices'])).data
//let incomeRawData = (await supabase.from("createddocuments").select().eq("tenant",profileStore.currentTenant).eq("state","Gebucht").in('type',['invoices','advanceInvoices','cancellationInvoices'])).data
let incomeRawData = (await useEntities("createddocuments").select()).filter(i => i.state === "Gebucht" && ['invoices','advanceInvoices','cancellationInvoices'].includes(i.type))
console.log(incomeRawData)
let incomeRawFilteredData = incomeRawData.filter(x => x.state === 'Gebucht' && incomeRawData.find(i => i.linkedDocument && i.linkedDocument.id === x.id && i.type === 'cancellationInvoices') && ['invoices','advanceInvoices'].includes(row.type))
let expenseRawData =(await supabase.from("incominginvoices").select().eq("tenant",profileStore.currentTenant)).data
let withoutInvoiceRawData = (await supabase.from("statementallocations").select().eq("tenant",profileStore.currentTenant).not("account","is",null)).data
//let expenseRawData =(await supabase.from("incominginvoices").select().eq("tenant",profileStore.currentTenant)).data
let expenseRawData =(await useEntities("incominginvoices").select())
//let withoutInvoiceRawData = (await supabase.from("statementallocations").select().eq("tenant",profileStore.currentTenant).not("account","is",null)).data
let withoutInvoiceRawData = (await useEntities("statementallocations").select()).filter(i => i.account)
let withoutInvoiceRawDataExpenses = []
let withoutInvoiceRawDataIncomes = []

View File

@@ -3,7 +3,6 @@
import dayjs from "dayjs";
const profileStore = useProfileStore();
const supabase = useSupabaseClient()
let unpaidInvoicesSum = ref(0)
let unpaidInvoicesCount = ref(0)
@@ -15,7 +14,7 @@ let draftInvoicesCount = ref(0)
let countPreparedOpenIncomingInvoices = ref(0)
const setupPage = async () => {
let items = (await useSupabaseSelect("createddocuments","*, statementallocations(*), customer(id,name), linkedDocument(*)")).filter(i => !i.archived)
let items = (await useEntities("createddocuments").select("*, statementallocations(*), customer(id,name), linkedDocument(*)")).filter(i => !i.archived)
let documents = items.filter(i => i.type === "invoices" ||i.type === "advanceInvoices")
let draftDocuments = documents.filter(i => i.state === "Entwurf")

View File

@@ -1,12 +1,12 @@
<script setup>
const openTasks = ref([])
const supabase = useSupabaseClient()
const router = useRouter()
const auth = useAuthStore()
const setupPage = async () => {
openTasks.value = (await supabase.from("tasks").select().eq("tenant",useProfileStore().currentTenant).not("archived","is",true).neq("categorie","Abgeschlossen").eq("profile", useProfileStore().activeProfile.id)).data
//TODO: BACKEND CHANGE Migrate to auth_users for profile
openTasks.value = (await useEntities("tasks").select().filter(i => !i.archived && i.user_id === auth.user.id))
}
setupPage()

View File

@@ -3,7 +3,7 @@
const phasesCounter = ref({})
const setupPage = async () => {
const projects = (await useSupabaseSelect("projects")).filter(i => !i.archived)
const projects = (await useEntities("projects").select()).filter(i => !i.archived)
projects.forEach(project => {
if(project.phases && project.phases.length > 0){