refactor: improve setup and maintainability (#1067)

This commit is contained in:
Jonas Plum
2024-07-08 00:16:37 +02:00
committed by GitHub
parent f5fcee0096
commit 619c5c65ce
553 changed files with 11271 additions and 91670 deletions

View File

@@ -0,0 +1,22 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<template>
<div
:class="
cn(
'flex w-full items-center border-t px-2 py-1 first:rounded-t first:border-none last:rounded-b',
props.class
)
"
>
<slot />
</div>
</template>

View File

@@ -0,0 +1,49 @@
<script setup lang="ts">
import { formatDistanceToNow } from 'date-fns'
import { cn } from '@/lib/utils'
defineProps<{
title: string
subtitle: string
description: string
created: string
open: boolean
active: boolean
to: string | { name: string; params: Record<string, string | number> }
}>()
</script>
<template>
<RouterLink
:class="
cn(
'flex flex-col items-start gap-2 rounded-lg border bg-card p-3 text-left text-sm transition-all hover:bg-accent',
active && 'bg-accent'
)
"
:to="to"
>
<div class="flex w-full flex-col gap-1">
<div class="flex items-center">
<div class="flex items-center gap-2">
<div class="font-semibold">
{{ title }}
</div>
<span v-if="open" class="flex h-2 w-2 rounded-full bg-blue-600" />
</div>
<div :class="cn('ml-auto text-xs', active ? 'text-foreground' : 'text-muted-foreground')">
{{ formatDistanceToNow(new Date(created), { addSuffix: true }) }}
</div>
</div>
<div v-if="subtitle" class="text-xs font-medium">
{{ subtitle }}
</div>
</div>
<div v-if="description" class="line-clamp-2 text-xs text-muted-foreground">
{{ description }}
</div>
</RouterLink>
</template>

View File

@@ -0,0 +1,23 @@
<script setup lang="ts">
import UserSelectList from '@/components/common/UserSelectList.vue'
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
import { ref } from 'vue'
import type { User } from '@/lib/types'
const user = defineModel<User>()
const open = ref(false)
</script>
<template>
<Popover v-model:open="open">
<PopoverTrigger as-child>
<slot />
</PopoverTrigger>
<PopoverContent class="w-[150px] p-0">
<UserSelectList v-model="user" :key="user ? user.id : 'unassigned'" :user="user" />
</PopoverContent>
</Popover>
</template>

View File

@@ -0,0 +1,72 @@
<script setup lang="ts">
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList
} from '@/components/ui/command'
import { Check } from 'lucide-vue-next'
import { useQuery } from '@tanstack/vue-query'
import debounce from 'lodash.debounce'
import { ref, watch } from 'vue'
import { pb } from '@/lib/pocketbase'
import type { User } from '@/lib/types'
import { cn } from '@/lib/utils'
const user = defineModel<User>()
const open = ref(false)
const searchTerm = ref('')
const {
isPending: usersIsPending,
isError: usersIsError,
data: users,
error: usersError,
refetch
} = useQuery({
queryKey: ['users', 'search', searchTerm.value],
queryFn: () =>
pb.collection('users').getFullList({
sort: 'name',
perPage: 5,
filter: pb.filter(`name ~ {:search}`, { search: searchTerm.value })
})
})
const searchUserDebounced = debounce(() => refetch(), 300)
watch(searchTerm, () => searchUserDebounced())
</script>
<template>
<Command v-model="user" v-model:search-term="searchTerm">
<CommandInput placeholder="Search user..." />
<CommandEmpty>
<span v-if="usersIsPending"> Loading... </span>
<span v-else-if="usersIsError"> Error: {{ usersError }} </span>
<span>No user found.</span>
</CommandEmpty>
<CommandList>
<CommandGroup>
<CommandItem
v-for="u in users"
:key="u.id"
:value="u"
@select="open = false"
class="cursor-pointer"
>
<Check
:class="cn('mr-2 h-4 w-4', user && user.id === u.id ? 'opacity-100' : 'opacity-0')"
/>
{{ u.name }}
</CommandItem>
</CommandGroup>
</CommandList>
</Command>
</template>