210 lines
5.4 KiB
Vue
210 lines
5.4 KiB
Vue
<script setup>
|
|
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";
|
|
|
|
const { has } = usePermission()
|
|
|
|
|
|
const props = defineProps({
|
|
type: {
|
|
required: true,
|
|
type: String
|
|
},
|
|
items: {
|
|
required: true,
|
|
type: Array
|
|
},
|
|
platform: {
|
|
required: true,
|
|
},
|
|
loading: {
|
|
required: true,
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
})
|
|
|
|
const emit = defineEmits(["sort"]);
|
|
|
|
|
|
const {type} = props
|
|
|
|
defineShortcuts({
|
|
'/': () => {
|
|
//console.log(searchinput)
|
|
//searchinput.value.focus()
|
|
document.getElementById("searchinput").focus()
|
|
},
|
|
'+': () => {
|
|
router.push(`/standardEntity/${type}/create`)
|
|
},
|
|
'Enter': {
|
|
usingInput: true,
|
|
handler: () => {
|
|
router.push(`/standardEntity/${type}/show/${filteredRows.value[selectedItem.value].id}`)
|
|
}
|
|
},
|
|
'arrowdown': () => {
|
|
if(selectedItem.value < filteredRows.value.length - 1) {
|
|
selectedItem.value += 1
|
|
} else {
|
|
selectedItem.value = 0
|
|
}
|
|
},
|
|
'arrowup': () => {
|
|
if(selectedItem.value === 0) {
|
|
selectedItem.value = filteredRows.value.length - 1
|
|
} else {
|
|
selectedItem.value -= 1
|
|
}
|
|
}
|
|
})
|
|
|
|
|
|
const router = useRouter()
|
|
const dataStore = useDataStore()
|
|
const profileStore = useProfileStore()
|
|
const tempStore = useTempStore()
|
|
|
|
const dataType = dataStore.dataTypes[type]
|
|
const canCreate = computed(() => {
|
|
if (type === "members") {
|
|
return has("members-create") || has("customers-create")
|
|
}
|
|
return has(`${type}-create`)
|
|
})
|
|
|
|
const selectedColumns = ref(tempStore.columns[type] ? tempStore.columns[type] : dataType.templateColumns.filter(i => !i.disabledInTable))
|
|
const columns = computed(() => dataType.templateColumns.filter((column) => !column.disabledInTable && selectedColumns.value.find(i => i.key === column.key)))
|
|
|
|
const searchString = ref(tempStore.searchStrings[props.type] ||'')
|
|
|
|
const clearSearchString = () => {
|
|
tempStore.clearSearchString(type)
|
|
searchString.value = ''
|
|
}
|
|
|
|
const selectableFilters = ref(dataType.filters.map(i => i.name))
|
|
const selectedFilters = ref(dataType.filters.filter(i => i.default).map(i => i.name) || [])
|
|
|
|
const filteredRows = computed(() => {
|
|
|
|
let tempItems = props.items.map(i => {
|
|
return {
|
|
...i,
|
|
class: i.archived ? 'bg-red-500/50 dark:bg-red-400/50' : null
|
|
}
|
|
})
|
|
|
|
if(selectedFilters.value.length > 0) {
|
|
selectedFilters.value.forEach(filterName => {
|
|
let filter = dataType.filters.find(i => i.name === filterName)
|
|
tempItems = tempItems.filter(filter.filterFunction)
|
|
})
|
|
}
|
|
|
|
return useSearch(searchString.value, tempItems)
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<FloatingActionButton
|
|
:label="`+ ${dataType.labelSingle}`"
|
|
variant="outline"
|
|
v-if="platform === 'mobile'"
|
|
@click="router.push(`/standardEntity/${type}/create`)"
|
|
/>
|
|
<UDashboardNavbar :title="dataType.label" :badge="filteredRows.length">
|
|
<template #toggle>
|
|
<div v-if="platform === 'mobile'"></div>
|
|
</template>
|
|
<template #right>
|
|
<UInput
|
|
id="searchinput"
|
|
v-model="searchString"
|
|
icon="i-heroicons-funnel"
|
|
autocomplete="off"
|
|
placeholder="Suche..."
|
|
class="hidden lg:block"
|
|
@keydown.esc="$event.target.blur()"
|
|
@change="tempStore.modifySearchString(type,searchString)"
|
|
>
|
|
<template #trailing>
|
|
<UKbd value="/" />
|
|
</template>
|
|
</UInput>
|
|
<UButton
|
|
icon="i-heroicons-x-mark"
|
|
variant="outline"
|
|
color="rose"
|
|
@click="clearSearchString()"
|
|
v-if="searchString.length > 0"
|
|
/>
|
|
|
|
<UButton
|
|
v-if="platform !== 'mobile' && canCreate/*&& useRole().checkRight(`${type}-create`)*/"
|
|
@click="router.push(`/standardEntity/${type}/create`)"
|
|
class="ml-3"
|
|
>+ {{dataType.labelSingle}}</UButton>
|
|
</template>
|
|
</UDashboardNavbar>
|
|
|
|
|
|
<UDashboardToolbar>
|
|
<template #left v-if="$slots['left-toolbar']">
|
|
<slot name="left-toolbar"/>
|
|
</template>
|
|
|
|
<template #right>
|
|
<USelectMenu
|
|
v-model="selectedColumns"
|
|
icon="i-heroicons-adjustments-horizontal-solid"
|
|
:options="dataType.templateColumns.filter(i => !i.disabledInTable)"
|
|
multiple
|
|
class="hidden lg:block"
|
|
by="key"
|
|
:color="selectedColumns.length !== dataType.templateColumns.filter(i => !i.disabledInTable).length ? 'primary' : 'white'"
|
|
:ui-menu="{ width: 'min-w-max' }"
|
|
@change="tempStore.modifyColumns(type,selectedColumns)"
|
|
>
|
|
<template #label>
|
|
Spalten
|
|
</template>
|
|
</USelectMenu>
|
|
<USelectMenu
|
|
v-if="selectableFilters.length > 0"
|
|
icon="i-heroicons-adjustments-horizontal-solid"
|
|
multiple
|
|
v-model="selectedFilters"
|
|
:options="selectableFilters"
|
|
:color="selectedFilters.length > 0 ? 'primary' : 'white'"
|
|
:ui-menu="{ width: 'min-w-max' }"
|
|
>
|
|
<template #label>
|
|
Filter
|
|
</template>
|
|
</USelectMenu>
|
|
</template>
|
|
</UDashboardToolbar>
|
|
<EntityTableMobile
|
|
v-if="platform === 'mobile'"
|
|
:type="props.type"
|
|
:columns="columns"
|
|
:rows="filteredRows"
|
|
/>
|
|
<EntityTable
|
|
v-else
|
|
@sort="(i) => emit('sort',i)"
|
|
:type="props.type"
|
|
:columns="columns"
|
|
:rows="filteredRows"
|
|
:loading="props.loading"
|
|
/>
|
|
</template>
|
|
|
|
<style scoped>
|
|
|
|
</style>
|