+
Willkommen zurück {{auth.profile.full_name}}
- bei {{auth.activeTenantData.name}}
+ bei {{auth.activeTenantData.name}}
diff --git a/components/mobile/FloatingActionButton.vue b/components/mobile/FloatingActionButton.vue
index be3450d..05a3f5d 100644
--- a/components/mobile/FloatingActionButton.vue
+++ b/components/mobile/FloatingActionButton.vue
@@ -2,46 +2,65 @@
const props = defineProps({
label: {
type: String,
- required: true,
+ required: false,
+ default: null
},
icon: {
type: String,
+ required: false
},
variant: {
type: String,
- default: 'solid'
+ default: "solid"
},
color: {
type: String,
- default: 'primary'
+ default: "primary"
},
pos: {
type: Number,
- default: 0
+ default: 6 // Abstand von unten in Rem (6 = 1.5rem * 6 = 9rem)
}
})
-const emit = defineEmits(['click'])
-
+const emit = defineEmits(["click"])
-
+
+
+
+
\ No newline at end of file
+
+/* Optional: Auto-Kreisen wenn kein Label */
+#fab:not([label]) {
+ @apply w-14 h-14 p-0 flex items-center justify-center text-2xl;
+}
+
diff --git a/layouts/mobile.vue b/layouts/mobile.vue
index 543a637..c014d8e 100644
--- a/layouts/mobile.vue
+++ b/layouts/mobile.vue
@@ -1,79 +1,58 @@
@@ -191,45 +170,49 @@ const footerLinks = [/*{
-
-
-
-
-
-
-
-
+
@@ -276,20 +259,9 @@ const footerLinks = [/*{
\ No newline at end of file
diff --git a/middleware/redirectToMobileIndex.ts b/middleware/redirectToMobileIndex.ts
index 2ccfddc..e332a1b 100644
--- a/middleware/redirectToMobileIndex.ts
+++ b/middleware/redirectToMobileIndex.ts
@@ -1,9 +1,9 @@
export default defineNuxtRouteMiddleware(async (to, _from) => {
const router = useRouter()
- console.log(await useCapacitor().getIsPhone())
+ console.log(useCapacitor().getIsNative())
- if(await useCapacitor().getIsPhone() && _from.path !== '/mobile') {
+ if(useCapacitor().getIsNative() && _from.path !== '/mobile') {
return router.push('/mobile')
}
})
diff --git a/pages/login.vue b/pages/login.vue
index 84b87fd..09ae74e 100644
--- a/pages/login.vue
+++ b/pages/login.vue
@@ -6,7 +6,7 @@ definePageMeta({
const auth = useAuthStore()
const toast = useToast()
-
+const platformIsNative = useCapacitor().getIsNative()
const doLogin = async (data:any) => {
@@ -14,7 +14,7 @@ const doLogin = async (data:any) => {
await auth.login(data.email, data.password)
// Weiterleiten nach erfolgreichem Login
toast.add({title:"Einloggen erfolgreich"})
- if(useCapacitor().getIsNative()) {
+ if(platformIsNative) {
return navigateTo("/mobile")
} else {
return navigateTo("/")
@@ -26,7 +26,7 @@ const doLogin = async (data:any) => {
-
+
{
+
+
+
+
+
+ Passwort vergessen?
+
+
+
\ No newline at end of file
diff --git a/pages/mobile/index.vue b/pages/mobile/index.vue
index 974f40b..71f1c29 100644
--- a/pages/mobile/index.vue
+++ b/pages/mobile/index.vue
@@ -1,13 +1,33 @@
@@ -42,6 +62,7 @@ definePageMeta({
>
+
diff --git a/pages/mobile/menu.vue b/pages/mobile/menu.vue
index d5e4a21..ee39712 100644
--- a/pages/mobile/menu.vue
+++ b/pages/mobile/menu.vue
@@ -13,30 +13,19 @@ const auth = useAuthStore()
Weiteres
Zeiten
-
Abwesenheiten
-
-
-
- Anwesenheiten
-
-
+
i.user_id === route.params.id)
console.log(profile.value)
+ setPageLayout(platformIsNative.value ? 'mobile' : 'default')
}
@@ -119,29 +122,30 @@ changeRange()
-
-
-
- Anwesenheiten
-
-
+
+
+
+
+ Anwesenheiten
+
+
-
-
- Auswertung Anwesenheiten: {{ profile?.full_name || '' }}
-
-
-
+
+
+ Auswertung Anwesenheiten: {{ profile?.full_name || '' }}
+
+
+
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
- Bericht
-
-
-
-
-
-
-
-
-
-
-
- Zusammenfassung
+
+
+
+
+
-
-
Eingereicht: {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesEingereicht) }}
-
Genehmigt: {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesApproved) }}
-
Feiertagsausgleich: {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesRecreationDays) }} / {{ workingTimeInfo.sumRecreationDays }} Tage
-
Urlaubs-/Berufsschulausgleich: {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesVacationDays) }} / {{ workingTimeInfo.sumVacationDays }} Tage
-
Krankheitsausgleich: {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesSickDays) }} / {{ workingTimeInfo.sumSickDays }} Tage
-
Soll-Stunden: {{ formatMinutesToHHMM(workingTimeInfo.timeSpanWorkingMinutes) }}
-
- Inoffizielles Saldo: {{ (workingTimeInfo.saldoInOfficial >= 0 ? '+' : '-') + formatMinutesToHHMM(Math.abs(workingTimeInfo.saldoInOfficial)) }}
-
-
- Saldo: {{ (workingTimeInfo.saldo >= 0 ? '+' : '-') + formatMinutesToHHMM(Math.abs(workingTimeInfo.saldo)) }}
-
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ Bericht
+
+
+
+
+
+
+
+
+
+
+
+ Zusammenfassung
+
+
+
Eingereicht: {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesEingereicht) }}
+
Genehmigt: {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesApproved) }}
+
Feiertagsausgleich: {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesRecreationDays) }} / {{ workingTimeInfo.sumRecreationDays }} Tage
+
Urlaubs-/Berufsschulausgleich: {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesVacationDays) }} / {{ workingTimeInfo.sumVacationDays }} Tage
+
Krankheitsausgleich: {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesSickDays) }} / {{ workingTimeInfo.sumSickDays }} Tage
+
Soll-Stunden: {{ formatMinutesToHHMM(workingTimeInfo.timeSpanWorkingMinutes) }}
+
+ Inoffizielles Saldo: {{ (workingTimeInfo.saldoInOfficial >= 0 ? '+' : '-') + formatMinutesToHHMM(Math.abs(workingTimeInfo.saldoInOfficial)) }}
+
+
+ Saldo: {{ (workingTimeInfo.saldo >= 0 ? '+' : '-') + formatMinutesToHHMM(Math.abs(workingTimeInfo.saldo)) }}
+
+
+
+
+
+ router.push(`/workingtimes/edit/${row.id}`)"
- >
-
- Genehmigt
- Eingereicht
- Entwurf
-
+ @select="(row) => router.push(`/workingtimes/edit/${row.id}`)"
+ >
+
+ Genehmigt
+ Eingereicht
+ Entwurf
+
-
- {{ $dayjs(row.started_at).format('HH:mm DD.MM.YY') }} Uhr
-
+
+ {{ $dayjs(row.started_at).format('HH:mm DD.MM.YY') }} Uhr
+
-
- {{ $dayjs(row.stopped_at).format('HH:mm DD.MM.YY') }} Uhr
-
+
+ {{ $dayjs(row.stopped_at).format('HH:mm DD.MM.YY') }} Uhr
+
-
- {{ useFormatDuration(row.duration_minutes) }}
-
-
-
+
+ {{ useFormatDuration(row.duration_minutes) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Zusammenfassung
+
+
+
+
Eingereicht: {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesEingereicht) }}
+
Genehmigt: {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesApproved) }}
+
+
+ Feiertagsausgleich:
+ {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesRecreationDays) }}
+ / {{ workingTimeInfo.sumRecreationDays }} Tage
+
+
+
+ Urlaubs-/Berufsschule:
+ {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesVacationDays) }}
+ / {{ workingTimeInfo.sumVacationDays }} Tage
+
+
+
+ Krankheitsausgleich:
+ {{ formatMinutesToHHMM(workingTimeInfo.sumWorkingMinutesSickDays) }}
+ / {{ workingTimeInfo.sumSickDays }} Tage
+
+
+
Soll: {{ formatMinutesToHHMM(workingTimeInfo.timeSpanWorkingMinutes) }}
+
+
+ Inoffizielles Saldo:
+ {{ (workingTimeInfo.saldoInOfficial >= 0 ? '+' : '-') + formatMinutesToHHMM(Math.abs(workingTimeInfo.saldoInOfficial)) }}
+
+
+
+ Saldo:
+ {{ (workingTimeInfo.saldo >= 0 ? '+' : '-') + formatMinutesToHHMM(Math.abs(workingTimeInfo.saldo)) }}
+
+
+
+
+
+
+
+
+
+
+ Bericht speichern
+
+
-
+
+
+
diff --git a/pages/staff/time/index.vue b/pages/staff/time/index.vue
index ab119da..6d4b8ba 100644
--- a/pages/staff/time/index.vue
+++ b/pages/staff/time/index.vue
@@ -1,20 +1,28 @@
-
+
+
+
+
+
-
-
-
-
-
-
- Läuft seit {{ useNuxtApp().$dayjs(active.started_at).format('HH:mm') }}
-
- Keine aktive Zeit
-
-
+
+
+
+
+
+ Läuft seit {{ useNuxtApp().$dayjs(active.started_at).format('HH:mm') }}
+
+ Keine aktive Zeit
+
+
-
-
-
- { editEntry = null; showModal = true }"
- />
-
-
-
-
-
-
-
+
+
{ editEntry = null; showModal = true }"
+ />
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Genehmigt
+ Eingereicht
+ Entwurf
+
+
+
+ {{ useNuxtApp().$dayjs(row.started_at).format("DD.MM.YY HH:mm") }}
+
+
+
+
+ {{ useNuxtApp().$dayjs(row.stopped_at).format("DD.MM.YY HH:mm") }}
+
+ läuft...
+
+
+
+ {{ row.duration_minutes ? useFormatDuration(row.duration_minutes) : "-" }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Aktive Zeit
+
+
+ Läuft seit {{ useNuxtApp().$dayjs(active.started_at).format('HH:mm') }}
+
+
Keine aktive Zeit
+
+
+
+
+
+
-
-
-
-
-
+
+
- ]"
- >
-
- Genehmigt
- Eingereicht
- Entwurf
-
-
- {{ useNuxtApp().$dayjs(row.started_at).format('DD.MM.YY HH:mm') }}
-
-
-
- {{ useNuxtApp().$dayjs(row.stopped_at).format('DD.MM.YY HH:mm') }}
-
- läuft...
-
-
- {{ row.duration_minutes ? useFormatDuration(row.duration_minutes) : '-' }}
-
-
- {{ row.user_id ? users.find(i => i.user_id === row.user_id).full_name : '-' }}
-
-
-
+
+
+
+
-
+
+ {{ row.description || 'Keine Beschreibung' }}
+
- />
-
-
-
+ {{
+ {
+ approved: 'Genehmigt',
+ submitted: 'Eingereicht',
+ draft: 'Entwurf'
+ }[row.state] || row.state
+ }}
+
- />
-
-
-
-
+
+
+ Start: {{ useNuxtApp().$dayjs(row.started_at).format('DD.MM.YY HH:mm') }}
+
-
-
-
+
+ Ende:
+
+ {{ useNuxtApp().$dayjs(row.stopped_at).format('DD.MM.YY HH:mm') }}
+
+ läuft...
+
+
+
+ Dauer:
+ {{ row.duration_minutes ? useFormatDuration(row.duration_minutes) : '-' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { editEntry = null; showModal = true }"
+ />
+
+
+
diff --git a/pages/standardEntity/[type]/[mode]/[[id]].vue b/pages/standardEntity/[type]/[mode]/[[id]].vue
index 456a378..450b5cd 100644
--- a/pages/standardEntity/[type]/[mode]/[[id]].vue
+++ b/pages/standardEntity/[type]/[mode]/[[id]].vue
@@ -9,7 +9,7 @@ const api = useNuxtApp().$api
const type = route.params.type
-const platform = await useCapacitor().getIsPhone() ? "mobile" : "default"
+const platform = await useCapacitor().getIsNative() ? "mobile" : "default"
const dataType = dataStore.dataTypes[route.params.type]
diff --git a/pages/standardEntity/[type]/index.vue b/pages/standardEntity/[type]/index.vue
index 5ef29a8..cb7d29b 100644
--- a/pages/standardEntity/[type]/index.vue
+++ b/pages/standardEntity/[type]/index.vue
@@ -3,9 +3,12 @@ import {useTempStore} from "~/stores/temp.js";
import FloatingActionButton from "~/components/mobile/FloatingActionButton.vue";
import EntityTable from "~/components/EntityTable.vue";
import EntityTableMobile from "~/components/EntityTableMobile.vue";
+import {setPageLayout} from "#app";
const { has } = usePermission()
+const platformIsNative = useCapacitor().getIsNative()
+
defineShortcuts({
'/': () => {
//console.log(searchinput)
@@ -67,8 +70,31 @@ const sort = ref({
const columnsToFilter = ref({})
+const showMobileFilter = ref(false)
+
+
//Functions
+function resetMobileFilters() {
+ if (!itemsMeta.value?.distinctValues) return
+
+ Object.keys(itemsMeta.value.distinctValues).forEach(key => {
+ columnsToFilter.value[key] = [...itemsMeta.value.distinctValues[key]]
+ })
+
+ showMobileFilter.value = false
+ setupPage()
+}
+
+function applyMobileFilters() {
+ Object.keys(columnsToFilter.value).forEach(key => {
+ tempStore.modifyFilter(type, key, columnsToFilter.value[key])
+ })
+
+ showMobileFilter.value = false
+ setupPage()
+}
+
const clearSearchString = () => {
tempStore.clearSearchString(type)
searchString.value = ''
@@ -77,13 +103,14 @@ const clearSearchString = () => {
const performSearch = async () => {
tempStore.modifySearchString(type,searchString)
+ changePage(1,true)
setupPage()
}
-const changePage = (number) => {
+const changePage = (number, noSetup = false) => {
page.value = number
tempStore.modifyPages(type, number)
- setupPage()
+ if(!noSetup) setupPage()
}
@@ -99,10 +126,23 @@ const changeSort = (column) => {
changePage(1)
}
+const isFiltered = computed(() => {
+ if (!itemsMeta.value?.distinctValues) return false
+
+ return Object.keys(columnsToFilter.value).some(key => {
+ const allValues = itemsMeta.value.distinctValues[key]
+ const selected = columnsToFilter.value[key]
+ if (!allValues || !selected) return false
+ return selected.length !== allValues.length
+ })
+})
+
//SETUP
const setupPage = async () => {
loading.value = true
+ setPageLayout(platformIsNative ? "mobile" : "default")
+
const filters = {
archived:false
@@ -160,17 +200,11 @@ const handleFilterChange = async (action,column) => {
-
-
+
-
+
{
-
+
-
{
- router.push(`/standardEntity/${type}/show/${i.id}`) "
- :empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: `Keine ${dataType.label} anzuzeigen` }"
- >
-
-
-
+
+
router.push(`/standardEntity/${type}/show/${i.id}`) "
+ :empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: `Keine ${dataType.label} anzuzeigen` }"
+ >
+
+
+
+
+
+
+
+
+
+
+
+ Keine Einträge in der Spalte {{column.label}}
+
+
+
+ {{ column.label }}
+
+
+
+
+
+
+
+
{{column.label}}
+
+
+
-
-
-
-
-
-
-
- Keine Einträge in der Spalte {{column.label}}
-
-
-
- {{ column.label }}
-
-
-
-
+
+ X
+
+
-
-
- {{column.label}}
+
-
-
-
- X
-
-
-
-
-
-
-
-
+
+
@@ -396,61 +390,236 @@ const handleFilterChange = async (action,column) => {
>
{{dataType.templateColumns.find(i => i.key === "name").maxLength ? (row.name.length > dataType.templateColumns.find(i => i.key === "name").maxLength ? `${row.name.substring(0,dataType.templateColumns.find(i => i.key === "name").maxLength)}...` : row.name ) : row.name}}
-
+
{{dataType.templateColumns.find(i => i.key === "name").maxLength ? (row.name.length > dataType.templateColumns.find(i => i.key === "name").maxLength ? `${row.name.substring(0,dataType.templateColumns.find(i => i.key === "name").maxLength)}...` : row.name ) : row.name}}
-
-
+
+
{{row.fullName}}
-
+
{{row.fullName}}
-
-
+
+
{{row.licensePlate}}
-
+
{{row.licensePlate}}
-
-
-
-
+
+
+
+
{{row[column.key] ? `${column.maxLength ? (row[column.key].length > column.maxLength ? `${row[column.key].substring(0,column.maxLength)}...` : row[column.key]) : row[column.key]} ${column.unit ? column.unit : ''}`: ''}}
-
-
-
-
+
+
-
- Keine {{dataType.label}} anzuzeigen
+
+
+ Keine {{dataType.label}} anzuzeigen
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+ {{
+ dataType.templateColumns.find(i => i.title)?.key
+ ? item[dataType.templateColumns.find(i => i.title).key]
+ : null
+ }}
+
+
+
+
+
+
+ {{ dataType.numberRangeHolder ? item[dataType.numberRangeHolder] : null }}
+
+
+
+ {{
+ (secondInfo.secondInfoKey && item[secondInfo.key])
+ ? item[secondInfo.key][secondInfo.secondInfoKey]
+ : item[secondInfo.key]
+ }}
+
+
+
+
+ changePage(i)"
+ show-first
+ show-last
+ :first-button="{ icon: 'i-heroicons-chevron-double-left', color: 'gray' }"
+ :last-button="{ icon: 'i-heroicons-chevron-double-right', trailing: true, color: 'gray' }"
+ />
+
+
+
+
+
+ Keine {{ dataType.label }} gefunden
+
+
+
+
+
+
+
+
+
+
+
+
Filter
+
+
+
+
+
+
+
+
{{ column.label }}
+
+
+
+
+
+
+
+
+
+ Zurücksetzen
+
+
+
+ Anwenden
+
+
+
+
+
+