mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-17 12:42:15 +01:00
refactor to shadcn components, dynamically load extension frontend
add jetstream permissions, add dynamic inertia module loading, add shadcn components, change modals and dropdowns to shadcn dismissable layer,
This commit is contained in:
@@ -6,7 +6,13 @@ import {
|
||||
} from '@heroicons/vue/20/solid';
|
||||
import type { Task } from '@/packages/api/src';
|
||||
import { canDeleteTasks, canUpdateTasks } from '@/utils/permissions';
|
||||
import MoreOptionsDropdown from '@/packages/ui/src/MoreOptionsDropdown.vue';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/Components/ui/dropdown-menu';
|
||||
|
||||
const emit = defineEmits<{
|
||||
delete: [];
|
||||
edit: [];
|
||||
@@ -18,38 +24,55 @@ const props = defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<MoreOptionsDropdown :label="'Actions for Task ' + props.task.name">
|
||||
<div class="min-w-[150px]">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger as-child>
|
||||
<button
|
||||
class="focus-visible:outline-none focus-visible:bg-card-background rounded-full focus-visible:ring-2 focus-visible:ring-ring focus-visible:opacity-100 hover:bg-card-background group-hover:opacity-100 opacity-20 transition-opacity text-text-secondary"
|
||||
:aria-label="'Actions for Task ' + props.task.name">
|
||||
<svg
|
||||
class="h-8 w-8 p-1 rounded-full"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="1.5"
|
||||
d="M12 5.92A.96.96 0 1 0 12 4a.96.96 0 0 0 0 1.92m0 7.04a.96.96 0 1 0 0-1.92a.96.96 0 0 0 0 1.92M12 20a.96.96 0 1 0 0-1.92a.96.96 0 0 0 0 1.92" />
|
||||
</svg>
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent class="min-w-[150px]" align="end">
|
||||
<DropdownMenuItem
|
||||
v-if="canUpdateTasks()"
|
||||
:aria-label="'Edit Task ' + props.task.name"
|
||||
data-testid="task_edit"
|
||||
class="flex items-center space-x-3 w-full px-3 py-2.5 text-start text-sm font-medium leading-5 text-text-primary hover:bg-card-background-active focus:outline-none focus:bg-card-background-active transition duration-150 ease-in-out"
|
||||
class="flex items-center space-x-3 cursor-pointer"
|
||||
@click="emit('edit')">
|
||||
<PencilSquareIcon
|
||||
class="w-5 text-icon-active"></PencilSquareIcon>
|
||||
<PencilSquareIcon class="w-5 text-icon-active" />
|
||||
<span>Edit</span>
|
||||
</button>
|
||||
<button
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
v-if="canUpdateTasks()"
|
||||
:aria-label="'Mark Task ' + props.task.name + ' as done'"
|
||||
class="flex items-center space-x-3 w-full px-3 py-2.5 text-start text-sm font-medium leading-5 text-text-primary hover:bg-card-background-active focus:outline-none focus:bg-card-background-active transition duration-150 ease-in-out"
|
||||
class="flex items-center space-x-3 cursor-pointer"
|
||||
@click="emit('done')">
|
||||
<CheckCircleIcon class="w-5 text-icon-active"></CheckCircleIcon>
|
||||
<CheckCircleIcon class="w-5 text-icon-active" />
|
||||
<span v-if="props.task.is_done">Mark as active</span>
|
||||
<span v-else>Mark as done</span>
|
||||
</button>
|
||||
<button
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
v-if="canDeleteTasks()"
|
||||
:aria-label="'Delete Task ' + props.task.name"
|
||||
data-testid="task_delete"
|
||||
class="flex items-center space-x-3 w-full px-3 py-2.5 text-start text-sm font-medium leading-5 text-text-primary hover:bg-card-background-active focus:outline-none focus:bg-card-background-active transition duration-150 ease-in-out"
|
||||
class="flex items-center space-x-3 cursor-pointer text-destructive focus:text-destructive"
|
||||
@click="emit('delete')">
|
||||
<TrashIcon class="w-5 text-icon-active"></TrashIcon>
|
||||
<TrashIcon class="w-5" />
|
||||
<span>Delete</span>
|
||||
</button>
|
||||
</div>
|
||||
</MoreOptionsDropdown>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -39,14 +39,14 @@ const showTaskEditModal = ref(false);
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="whitespace-nowrap px-3 py-4 text-sm text-muted flex space-x-1 items-center font-medium">
|
||||
class="whitespace-nowrap px-3 py-4 text-sm text-text-secondary flex space-x-1 items-center font-medium">
|
||||
<span v-if="task.spent_time">
|
||||
{{ formatHumanReadableDuration(task.spent_time) }}
|
||||
</span>
|
||||
<span v-else> -- </span>
|
||||
</div>
|
||||
<div
|
||||
class="whitespace-nowrap px-3 flex items-center text-sm text-muted">
|
||||
class="whitespace-nowrap px-3 flex items-center text-sm text-text-secondary">
|
||||
<UpgradeBadge
|
||||
v-if="!isAllowedToPerformPremiumAction()"></UpgradeBadge>
|
||||
<EstimatedTimeProgress
|
||||
@@ -56,7 +56,7 @@ const showTaskEditModal = ref(false);
|
||||
<span v-else> -- </span>
|
||||
</div>
|
||||
<div
|
||||
class="whitespace-nowrap px-3 py-4 text-sm text-muted flex space-x-1 items-center font-medium">
|
||||
class="whitespace-nowrap px-3 py-4 text-sm text-text-secondary flex space-x-1 items-center font-medium">
|
||||
<template v-if="task.is_done">
|
||||
<CheckCircleIcon class="w-5"></CheckCircleIcon>
|
||||
<span>Done</span>
|
||||
|
||||
Reference in New Issue
Block a user