Supabase Removals Frontend

This commit is contained in:
2026-02-14 12:48:59 +01:00
parent 053f184a33
commit 55699da42c
28 changed files with 135 additions and 222 deletions

View File

@@ -60,7 +60,6 @@ const router = useRouter()
const createddocuments = ref([])
const setup = async () => {
//createddocuments.value = (await useSupabaseSelect("createddocuments")).filter(i => !i.archived)
createddocuments.value = (await useEntities("createddocuments").select()).filter(i => !i.archived)
}
setup()
@@ -308,4 +307,4 @@ const selectItem = (item) => {
<style scoped>
</style>
</style>

View File

@@ -1,9 +1,6 @@
<script setup>
import dayjs from "dayjs";
const supabase = useSupabaseClient()
const route = useRoute()
const router = useRouter()
const profileStore = useProfileStore()
const props = defineProps({
@@ -28,8 +25,6 @@ const statementallocations = ref([])
const incominginvoices = ref([])
const setup = async () => {
//statementallocations.value = (await supabase.from("statementallocations").select("*, bs_id(*)").eq("account", route.params.id).eq("tenant",profileStore.currentTenant).order("created_at",{ascending: true})).data
//incominginvoices.value = (await useSupabaseSelect("incominginvoices", "*, vendor(*)")).filter(i => i.accounts.find(x => x.account == route.params.id))
}
setup()
@@ -105,4 +100,4 @@ const renderedAllocations = computed(() => {
<style scoped>
</style>
</style>

View File

@@ -24,7 +24,6 @@ const emit = defineEmits(["updateNeeded"]);
const router = useRouter()
const profileStore = useProfileStore()
const supabase = useSupabaseClient()
const renderedPhases = computed(() => {
if(props.topLevelType === "projects" && props.item.phases) {
@@ -77,17 +76,6 @@ const changeActivePhase = async (key) => {
const res = await useEntities("projects").update(item.id, {phases:item.phases,active_phase: item.phases.find(i => i.active).label})
//const {error:updateError} = await supabase.from("projects").update({phases: item.phases}).eq("id",item.id)
/*const {error} = await supabase.from("historyitems").insert({
createdBy: profileStore.activeProfile.id,
tenant: profileStore.currentTenant,
text: `Aktive Phase zu "${phaseLabel}" gewechselt`,
project: item.id
})*/
emit("updateNeeded")
}
@@ -166,4 +154,4 @@ const changeActivePhase = async (key) => {
<style scoped>
</style>
</style>

View File

@@ -1,10 +1,5 @@
<script setup>
import dayjs from "dayjs";
const supabase = useSupabaseClient()
const route = useRoute()
const router = useRouter()
const profileStore = useProfileStore()
const props = defineProps({
queryStringData: {
@@ -114,4 +109,4 @@ const columns = [
<style scoped>
</style>
</style>

View File

@@ -57,7 +57,7 @@
const selectedItem = ref(0)
const sort = ref({
column: dataType.supabaseSortColumn || "date",
column: dataType.sortColumn || "date",
direction: 'desc'
})

View File

@@ -1,14 +1,17 @@
<script setup>
const supabase = useSupabaseClient()
const profileStore = useProfileStore()
const globalMessages = ref([])
const setup = async () => {
let {data} = await supabase.from("globalmessages").select("*, profiles(id)")
let data = []
try {
data = await useNuxtApp().$api("/api/resource/globalmessages")
} catch (e) {
data = []
}
data = data.filter((message) => message.profiles.length === 0)
data = (data || []).filter((message) => !message.profiles || message.profiles.length === 0)
globalMessages.value = data
@@ -29,10 +32,17 @@ const showMessage = (message) => {
showMessageModal.value = true
}
const markMessageAsRead = async () => {
await supabase.from("globalmessagesseen").insert({
profile: profileStore.activeProfile.id,
message: messageToShow.value.id,
})
try {
await useNuxtApp().$api("/api/resource/globalmessagesseen", {
method: "POST",
body: {
profile: profileStore.activeProfile.id,
message: messageToShow.value.id,
}
})
} catch (e) {
// noop: endpoint optional in newer backend versions
}
showMessageModal.value = false
setup()
@@ -86,4 +96,4 @@ setup()
<style scoped>
</style>
</style>

View File

@@ -3,10 +3,7 @@ const { isHelpSlideoverOpen } = useDashboard()
const { metaSymbol } = useShortcuts()
const shortcuts = ref(false)
const dataStore = useDataStore()
const profileStore = useProfileStore()
const query = ref('')
const supabase = useSupabaseClient()
const toast = useToast()
const router = useRouter()
@@ -228,4 +225,4 @@ const resetContactRequest = () => {
</div>
<UProgress class="mt-5" animation="carousel" v-else/>-->
</UDashboardSlideover>
</template>
</template>

View File

@@ -1,9 +1,6 @@
<script setup>
import {formatTimeAgo} from '@vueuse/core'
const supabase = useSupabaseClient()
const { isNotificationsSlideoverOpen } = useDashboard()
watch(isNotificationsSlideoverOpen, async (newVal,oldVal) => {
@@ -15,18 +12,24 @@ watch(isNotificationsSlideoverOpen, async (newVal,oldVal) => {
const notifications = ref([])
const setup = async () => {
notifications.value = (await supabase.from("notifications").select()).data
try {
notifications.value = await useNuxtApp().$api("/api/resource/notifications_items")
} catch (e) {
notifications.value = []
}
}
setup()
const setNotificationAsRead = async (notification) => {
console.log(notification)
const {data,error} = await supabase.from("notifications").update({read: true}).eq("id", notification.id)
console.log(error)
try {
await useNuxtApp().$api(`/api/resource/notifications_items/${notification.id}`, {
method: "PUT",
body: { readAt: new Date() }
})
} catch (e) {
// noop: endpoint optional in older/newer backend variants
}
setup()
}
@@ -41,7 +44,7 @@ const setNotificationAsRead = async (notification) => {
class="p-3 rounded-md hover:bg-gray-50 dark:hover:bg-gray-800/50 cursor-pointer flex items-center gap-3 relative"
@click="setNotificationAsRead(notification)"
>
<UChip color="primary" :show="!notification.read" inset>
<UChip color="primary" :show="!notification.read && !notification.readAt" inset>
<UAvatar alt="FEDEO" size="md" />
</UChip>
@@ -49,7 +52,7 @@ const setNotificationAsRead = async (notification) => {
<p class="flex items-center justify-between">
<span class="text-gray-900 dark:text-white font-medium">{{notification.title}}</span>
<time :datetime="notification.date" class="text-gray-500 dark:text-gray-400 text-xs" v-text="formatTimeAgo(new Date(notification.created_at))" />
<time :datetime="notification.date || notification.createdAt || notification.created_at" class="text-gray-500 dark:text-gray-400 text-xs" v-text="formatTimeAgo(new Date(notification.createdAt || notification.created_at))" />
</p>
<p class="text-gray-500 dark:text-gray-400">
{{ notification.message }}

View File

@@ -2,7 +2,6 @@
const toast = useToast()
const dataStore = useDataStore()
const supabase = useSupabaseClient()
const modal = useModal()
const props = defineProps({
type: {
@@ -35,11 +34,10 @@ const item = ref({})
const setupPage = async () => {
if(props.mode === "show") {
//Load Data for Show
item.value = await useEntities(props.type).selectSingle(props.id, dataType.supabaseSelectWithInformation || "*")
item.value = await useEntities(props.type).selectSingle(props.id, dataType.selectWithInformation || "*")
} else if(props.mode === "edit") {
//Load Data for Edit
const data = JSON.stringify(await useEntities(props.type).selectSingle(props.id)/*(await supabase.from(props.type).select().eq("id", props.id).single()).data*/)
//await useSupabaseSelectSingle(type, route.params.id)
const data = JSON.stringify(await useEntities(props.type).selectSingle(props.id))
item.value = data
} else if(props.mode === "create") {
@@ -48,7 +46,7 @@ const setupPage = async () => {
} else if(props.mode === "list") {
//Load Data for List
items.value = await useEntities(props.type).select(dataType.supabaseSelectWithInformation || "*", dataType.supabaseSortColumn,dataType.supabaseSortAscending || false)
items.value = await useEntities(props.type).select(dataType.selectWithInformation || "*", dataType.sortColumn,dataType.sortAscending || false)
}
loaded.value = true
@@ -95,4 +93,4 @@ setupPage()
<style scoped>
</style>
</style>

View File

@@ -3,11 +3,6 @@
const { isHelpSlideoverOpen } = useDashboard()
const { isDashboardSearchModalOpen } = useUIState()
const { metaSymbol } = useShortcuts()
const user = useSupabaseUser()
const dataStore = useDataStore()
const profileStore = useProfileStore()
const supabase = useSupabaseClient()
const router = useRouter()
const auth = useAuthStore()
const items = computed(() => [
@@ -59,4 +54,4 @@ const items = computed(() => [
</div>
</template>
</UDropdown>
</template>
</template>

View File

@@ -7,11 +7,9 @@ const props = defineProps({
}
})
const supabase = useSupabaseClient()
let inventoryitemgroups = await Promise.all(props.row.inventoryitemgroups.map(async (i) => {
return (await supabase.from("inventoryitemgroups").select("id,name").eq("id",i).single()).data.name
const group = await useEntities("inventoryitemgroups").selectSingle(i)
return group?.name
}))
</script>

View File

@@ -7,11 +7,9 @@ const props = defineProps({
}
})
const supabase = useSupabaseClient()
let inventoryitems = await Promise.all(props.row.inventoryitems.map(async (i) => {
return (await supabase.from("inventoryitems").select("id,name").eq("id",i).single()).data.name
const item = await useEntities("inventoryitems").selectSingle(i)
return item?.name
}))
</script>

View File

@@ -7,11 +7,9 @@ const props = defineProps({
}
})
const supabase = useSupabaseClient()
let vehicles = await Promise.all(props.row.vehicles.map(async (i) => {
return (await supabase.from("vehicles").select("id,licensePlate").eq("id",i).single()).data.licensePlate
const vehicle = await useEntities("vehicles").selectSingle(i)
return vehicle?.licensePlate
}))
</script>

View File

@@ -1,8 +1,4 @@
<script setup>
const supabase = useSupabaseClient()
const profileStore = useProfileStore()
const props = defineProps({
item: {
required: true,
@@ -27,4 +23,4 @@ setupPage()
<style scoped>
</style>
</style>

View File

@@ -8,15 +8,12 @@ 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 useEntities("createddocuments").select()).filter(i => i.state === "Gebucht" && ['invoices','advanceInvoices','cancellationInvoices'].includes(i.type))
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 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 = []
@@ -241,4 +238,4 @@ setup()
<style scoped>
</style>
</style>

View File

@@ -32,15 +32,7 @@ const default_data = {
const newProjectDescription = ref(data|| default_data.value);
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)*/
@@ -61,4 +53,4 @@ const saveProjectDescription = async () => {
<style scoped>
</style>
</style>

View File

@@ -1,10 +1,20 @@
<script setup>
const supabase = useSupabaseClient()
const profileStore = useProfileStore()
const workingtimes = ref([])
const setupPage = async () => {
workingtimes.value = (await supabase.from("workingtimes").select().eq("tenant",profileStore.currentTenant).is("endDate",null)).data
const profiles = profileStore.profiles || []
const checks = await Promise.all(profiles.map(async (profile) => {
try {
const spans = await useNuxtApp().$api(`/api/staff/time/spans?targetUserId=${profile.user_id || profile.id}`)
const openSpan = (spans || []).find((s) => !s.endedAt && s.type === "work")
if (openSpan) return { profile: profile.id }
} catch (e) {
return null
}
return null
}))
workingtimes.value = checks.filter(Boolean)
}
setupPage()
@@ -21,4 +31,4 @@ setupPage()
<style scoped>
</style>
</style>

View File

@@ -1,8 +1,5 @@
export const useSum = () => {
const supabase = useSupabaseClient()
const getIncomingInvoiceSum = (invoice) => {
let sum = 0
invoice.accounts.forEach(account => {
@@ -135,4 +132,4 @@ export const useSum = () => {
return {getIncomingInvoiceSum, getCreatedDocumentSum, getCreatedDocumentSumDetailed, getIsPaid}
}
}

View File

@@ -7,7 +7,7 @@ export default defineNuxtConfig({
}
},
modules: ['@vite-pwa/nuxt','@pinia/nuxt', '@nuxt/ui', '@nuxtjs/supabase', "nuxt-editorjs", '@nuxtjs/fontaine', 'nuxt-viewport', '@nuxtjs/leaflet', '@vueuse/nuxt'],
modules: ['@vite-pwa/nuxt','@pinia/nuxt', '@nuxt/ui', "nuxt-editorjs", '@nuxtjs/fontaine', 'nuxt-viewport', '@nuxtjs/leaflet', '@vueuse/nuxt'],
ssr: false,
@@ -154,4 +154,4 @@ export default defineNuxtConfig({
},
compatibilityDate: '2024-12-18'
})
})

View File

@@ -15,7 +15,7 @@ const showDocument = ref(false)
const uri = ref("")
const setupPage = async () => {
letterheads.value = await useSupabaseSelect("letterheads","*")
letterheads.value = await useEntities("letterheads").select("*")
preloadedContent.value = `<p></p><p></p><p></p>`
}
@@ -105,4 +105,4 @@ const contentChanged = (content) => {
.previewDocumentMobile {
aspect-ratio: 1 / 1.414;
}
</style>
</style>

View File

@@ -20,7 +20,6 @@ defineShortcuts({
})
const dataStore = useDataStore()
const supabase = useSupabaseClient()
const route = useRoute()
const router = useRouter()
const toast = useToast()
@@ -38,7 +37,7 @@ const openTab = ref(0)
//Functions
const setupPage = async () => {
if(mode.value === "show" || mode.value === "edit"){
itemInfo.value = await useSupabaseSelectSingle("roles",route.params.id,"*")
itemInfo.value = await useEntities("roles").selectSingle(route.params.id,"*")
}
}
@@ -195,4 +194,4 @@ td {
padding-bottom: 0.15em;
padding-top: 0.15em;
}
</style>
</style>

View File

@@ -3,7 +3,7 @@
const items = ref([])
const setup = async () => {
items.value = await useSupabaseSelect("roles","*")
items.value = await useEntities("roles").select("*")
}
setup()
@@ -19,4 +19,4 @@ setup()
<style scoped>
</style>
</style>

View File

@@ -1,8 +1,4 @@
<script setup>
import axios from "axios"
const supabase = useSupabaseClient()
const dataStore = useDataStore()
const profileStore = useProfileStore()
const createEMailAddress = ref("")
const createEMailType = ref("imap")
@@ -96,4 +92,4 @@ const columns = computed(() => templateColumns.filter((column) => selectedColumn
<style scoped>
</style>
</style>

View File

@@ -41,7 +41,6 @@ const setupPage = async (sort_column = null, sort_direction = null) => {
console.log(item.value)
} else if (mode.value === "list") {
//Load Data for List
//items.value = await useEntities(type).select(dataType.supabaseSelectWithInformation, sort_column || dataType.supabaseSortColumn, sort_direction === "asc", true)
items.value = await useEntities(type).select({
filters: {},
sort: [],

View File

@@ -64,7 +64,7 @@ const pageLimit = ref(15)
const page = ref(tempStore.pages[type] || 1)
const sort = ref({
column: dataType.supabaseSortColumn || "created_at",
column: dataType.sortColumn || "created_at",
direction: 'desc'
})
@@ -156,7 +156,7 @@ const setupPage = async () => {
const {data,meta} = await useEntities(type).selectPaginated({
select: dataType.supabaseSelectWithInformation || "*",
select: dataType.selectWithInformation || "*",
filters: filters,
sort: [{field: sort.value.column, direction: sort.value.direction}],
page: page.value,

View File

@@ -3,7 +3,6 @@
import {useFunctions} from "~/composables/useFunctions.js";
import dayjs from "dayjs";
const supabase = useSupabaseClient()
const profileStore = useProfileStore()
const toast = useToast()
const auth = useAuthStore()
@@ -143,4 +142,4 @@ const addMessage = async () => {
<style scoped>
</style>
</style>

View File

@@ -10,15 +10,6 @@ const showClosedTickets = ref(false)
const selectedTenant = ref(null)
const setup = async () => {
/*if(profileStore.currentTenant === 5) {
tickets.value = (await supabase.from("tickets").select("*,created_by(*), ticketmessages(*), tenant(*)").order("created_at", {ascending: false})).data
} else {
tickets.value = (await supabase.from("tickets").select("*,created_by(*), ticketmessages(*)").eq("tenant",profileStore.currentTenant).order("created_at", {ascending: false})).data
}
if(profileStore.currentTenant === 5) {
tenants.value = (await supabase.from("tenants").select().order("id")).data
}*/
tickets.value = await useEntities("tickets").select("*,created_by(*), ticketmessages(*)", "created_at", false)
@@ -107,4 +98,4 @@ const filteredRows = computed(() => {
<style scoped>
</style>
</style>

View File

@@ -1,152 +1,117 @@
import {defineStore} from 'pinia'
import OneSignal from "onesignal-cordova-plugin";
import {Capacitor} from "@capacitor/core";
// @ts-ignore
export const useProfileStore = defineStore('profile', () => {
import { defineStore } from "pinia"
import OneSignal from "onesignal-cordova-plugin"
import { Capacitor } from "@capacitor/core"
const supabase = useSupabaseClient()
export const useProfileStore = defineStore("profile", () => {
const auth = useAuthStore()
const dataStore = useDataStore()
const user = useSupabaseUser()
const toast = useToast()
const router = useRouter()
const tempStore = useTempStore()
const loaded = ref(false)
const showProfileSelection = ref(false)
const ownTenant = ref({
calendarConfig: {
eventTypes: []
},
timeConfig: {
timeTypes: []
},
tags: {
documents: [] ,
products: []
},
calendarConfig: { eventTypes: [] },
timeConfig: { timeTypes: [] },
tags: { documents: [], products: [] },
measures: []
})
const profiles = ref([])
const ownProfiles = ref([])
const activeProfile = ref([])
const activeProfile = ref(null)
const tenants = ref([])
const currentTenant = ref(null)
const syncFromAuth = () => {
currentTenant.value = auth.activeTenant || null
activeProfile.value = auth.profile || null
tenants.value = auth.tenants || []
}
async function initializeData (userId) {
let profileconnections = (await supabase.from("profileconnections").select()).data
let profiles = (await supabase.from("profiles").select("*, role(*)")).data
let activeProfileConnection = profileconnections.find(i => i.active)
if(activeProfileConnection) {
if(!false) {
toast.add({title: 'Aktives Profil ausgewählt'})
}
console.log("Active Profile selected")
activeProfile.value = profiles.find(i => i.id === activeProfileConnection.profile_id)
currentTenant.value = activeProfile.value.tenant
if(Capacitor.getPlatform() === "ios") {
OneSignal.initialize("1295d5ff-28f8-46a6-9c62-fe5d090016d7");
OneSignal.Location.setShared(false)
OneSignal.Notifications.requestPermission();
OneSignal.login(activeProfileConnection.user_id)
}
async function initializeData() {
await auth.fetchMe()
syncFromAuth()
if (activeProfile.value?.temp_config) {
tempStore.setStoredTempConfig(activeProfile.value.temp_config)
}
if (currentTenant.value) {
await fetchData()
await dataStore.fetchData()
if (Capacitor.getPlatform() === "ios" && activeProfile.value?.user_id) {
OneSignal.initialize("1295d5ff-28f8-46a6-9c62-fe5d090016d7")
OneSignal.Location.setShared(false)
OneSignal.Notifications.requestPermission()
OneSignal.login(activeProfile.value.user_id)
}
} else {
toast.add({title: 'Kein aktives Profil', color: 'orange'})
await fetchOwnProfiles()
await fetchTenants()
toast.add({ title: "Kein aktiver Tenant", color: "orange" })
showProfileSelection.value = true
}
}
async function changeProfile(newActiveProfileId) {
async function changeProfile(newActiveTenantId) {
loaded.value = false
let profileconnections = (await supabase.from("profileconnections").select()).data
let oldActiveProfileConnection = profileconnections.find(i => i.active)
const {error} = await supabase.from("profileconnections").update({active: true}).eq("profile_id", newActiveProfileId)
if(error) {
console.log(error)
} else {
if(oldActiveProfileConnection){
const {error} = await supabase.from("profileconnections").update({active: false}).eq("profile_id", oldActiveProfileConnection.profile_id)
}
reloadNuxtApp({
path:"/",
ttl: 10000
})
}
await auth.switchTenant(String(newActiveTenantId))
}
async function fetchData () {
async function fetchData() {
await fetchOwnProfiles()
await fetchProfiles()
await fetchTenants()
await fetchOwnTenant()
loaded.value = true
console.log("Finished Loading")
}
function clearStore () {
function clearStore() {
loaded.value = false
ownTenant.value = {}
ownTenant.value = {}
profiles.value = []
ownProfiles.value = []
tenants.value = []
}
async function fetchOwnTenant () {
ownTenant.value = (await supabase.from("tenants").select().eq('id', currentTenant.value).single()).data
async function fetchOwnTenant() {
syncFromAuth()
ownTenant.value = auth.activeTenantData || ownTenant.value
}
async function fetchProfiles () {
profiles.value = (await supabase.from("profiles").select().eq("tenant",currentTenant.value).order("lastName")).data
async function fetchProfiles() {
try {
const res = await useNuxtApp().$api("/api/tenant/profiles")
profiles.value = res?.data || []
} catch (e) {
profiles.value = activeProfile.value ? [activeProfile.value] : []
}
}
async function fetchOwnProfiles () {
let profiles = (await supabase.from("profiles").select().order("tenant")).data
let conns = (await supabase.from("profileconnections").select()).data.map(i => i.profile_id)
ownProfiles.value = profiles.filter(i => conns.includes(i.id))
async function fetchOwnProfiles() {
ownProfiles.value = profiles.value
}
async function fetchTenants () {
tenants.value = (await supabase.from("tenants").select().order("id",{ascending: true})).data
async function fetchTenants() {
syncFromAuth()
}
const getOwnProfile = computed(() => {
return profiles.value.find(i => i.id === user.value.id)
const getOwnProfile = computed(() => {
return activeProfile.value
})
const getProfileById = computed(() => (itemId) => {
return profiles.value.find(item => item.id === itemId)
return profiles.value.find((item) => item.id === itemId || item.user_id === itemId)
})
return {
//General
currentTenant,
loaded,
showProfileSelection,
ownTenant,
initializeData,
changeProfile,
//Data
profiles,
ownProfiles,
activeProfile,
@@ -157,6 +122,4 @@ export const useProfileStore = defineStore('profile', () => {
getOwnProfile,
getProfileById
}
})
})