diff --git a/e2e/clients.spec.ts b/e2e/clients.spec.ts index 5deee4ee..2eb34682 100644 --- a/e2e/clients.spec.ts +++ b/e2e/clients.spec.ts @@ -49,3 +49,5 @@ test('test that creating and deleting a new client via the modal works', async ( newClientName ); }); + +// TODO: Add Name Update Test diff --git a/e2e/projects.spec.ts b/e2e/projects.spec.ts index d9bb0038..cbb7e5b1 100644 --- a/e2e/projects.spec.ts +++ b/e2e/projects.spec.ts @@ -71,3 +71,5 @@ test('test that creating and deleting a new project via the modal works', async // Edit Project with billable rate // Edit Project Member Billable Rate + +// Edit Task Name diff --git a/e2e/tasks.spec.ts b/e2e/tasks.spec.ts index 54b7be78..f36c070f 100644 --- a/e2e/tasks.spec.ts +++ b/e2e/tasks.spec.ts @@ -107,3 +107,5 @@ test('test that creating and deleting a new tag in a new project works', async ( // Test that project task count is displayed correctly // Test that active / archive / all filter works (once implemented) + +// Test update task name diff --git a/resources/js/Components/Common/Client/ClientEditModal.vue b/resources/js/Components/Common/Client/ClientEditModal.vue new file mode 100644 index 00000000..4271466c --- /dev/null +++ b/resources/js/Components/Common/Client/ClientEditModal.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/resources/js/Components/Common/Client/ClientMoreOptionsDropdown.vue b/resources/js/Components/Common/Client/ClientMoreOptionsDropdown.vue index a57b9f9b..cafcd382 100644 --- a/resources/js/Components/Common/Client/ClientMoreOptionsDropdown.vue +++ b/resources/js/Components/Common/Client/ClientMoreOptionsDropdown.vue @@ -1,11 +1,12 @@ diff --git a/resources/js/Components/Common/Task/TaskEditModal.vue b/resources/js/Components/Common/Task/TaskEditModal.vue new file mode 100644 index 00000000..5787bdb1 --- /dev/null +++ b/resources/js/Components/Common/Task/TaskEditModal.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/resources/js/Components/Common/Task/TaskMoreOptionsDropdown.vue b/resources/js/Components/Common/Task/TaskMoreOptionsDropdown.vue index 218a55b9..f53ecaeb 100644 --- a/resources/js/Components/Common/Task/TaskMoreOptionsDropdown.vue +++ b/resources/js/Components/Common/Task/TaskMoreOptionsDropdown.vue @@ -1,9 +1,11 @@ diff --git a/resources/js/Components/Common/Task/TaskTableRow.vue b/resources/js/Components/Common/Task/TaskTableRow.vue index 0ba09c38..d0d52f21 100644 --- a/resources/js/Components/Common/Task/TaskTableRow.vue +++ b/resources/js/Components/Common/Task/TaskTableRow.vue @@ -5,6 +5,8 @@ import { useTasksStore } from '@/utils/useTasks'; import TaskMoreOptionsDropdown from '@/Components/Common/Task/TaskMoreOptionsDropdown.vue'; import TableRow from '@/Components/TableRow.vue'; import { canDeleteTasks } from '@/utils/permissions'; +import TaskEditModal from '@/Components/Common/Task/TaskEditModal.vue'; +import { ref } from 'vue'; const props = defineProps<{ task: Task; @@ -13,6 +15,7 @@ const props = defineProps<{ function deleteTask() { useTasksStore().deleteTask(props.task.id); } +const showTaskEditModal = ref(false); diff --git a/resources/js/utils/api.ts b/resources/js/utils/api.ts index d24a332f..7fd8122c 100644 --- a/resources/js/utils/api.ts +++ b/resources/js/utils/api.ts @@ -64,6 +64,7 @@ export type ProjectMember = ProjectMemberResponse['data'][0]; export type CreateTaskBody = ZodiosBodyByAlias; export type CreateClientBody = ZodiosBodyByAlias; +export type UpdateClientBody = ZodiosBodyByAlias; export type TagIndexResponse = ZodiosResponseByAlias; export type Tag = TagIndexResponse['data'][0]; @@ -71,6 +72,8 @@ export type Tag = TagIndexResponse['data'][0]; export type TaskIndexResponse = ZodiosResponseByAlias; export type Task = TaskIndexResponse['data'][0]; +export type UpdateTaskBody = ZodiosBodyByAlias; + export type ClientIndexResponse = ZodiosResponseByAlias< SolidTimeApi, 'getClients' diff --git a/resources/js/utils/permissions.ts b/resources/js/utils/permissions.ts index 30a22373..35016581 100644 --- a/resources/js/utils/permissions.ts +++ b/resources/js/utils/permissions.ts @@ -41,6 +41,10 @@ export function canCreateTasks() { return currentUserHasPermission('tasks:create'); } +export function canUpdateTasks() { + return currentUserHasPermission('tasks:update'); +} + export function canDeleteTasks() { return currentUserHasPermission('tasks:delete'); } @@ -49,6 +53,10 @@ export function canCreateClients() { return currentUserHasPermission('clients:create'); } +export function canUpdateClients() { + return currentUserHasPermission('clients:update'); +} + export function canDeleteClients() { return currentUserHasPermission('clients:delete'); } diff --git a/resources/js/utils/useClients.ts b/resources/js/utils/useClients.ts index faa28c4d..b744a347 100644 --- a/resources/js/utils/useClients.ts +++ b/resources/js/utils/useClients.ts @@ -5,6 +5,7 @@ import type { CreateClientBody, ClientIndexResponse, Client, + UpdateClientBody, } from '@/utils/api'; import { getCurrentOrganizationId } from '@/utils/useUser'; import { useNotificationsStore } from '@/utils/notification'; @@ -49,6 +50,27 @@ export const useClientsStore = defineStore('clients', () => { } } + async function updateClient( + clientId: string, + clientBody: UpdateClientBody + ) { + const organization = getCurrentOrganizationId(); + if (organization) { + await handleApiRequestNotifications( + () => + api.updateClient(clientBody, { + params: { + organization: organization, + client: clientId, + }, + }), + 'Client updated successfully', + 'Failed to update client' + ); + await fetchClients(); + } + } + async function deleteClient(clientId: string) { const organization = getCurrentOrganizationId(); if (organization) { @@ -74,5 +96,5 @@ export const useClientsStore = defineStore('clients', () => { return clientResponse.value?.data || []; }); - return { clients, fetchClients, createClient, deleteClient }; + return { clients, fetchClients, createClient, deleteClient, updateClient }; }); diff --git a/resources/js/utils/useTasks.ts b/resources/js/utils/useTasks.ts index ab10fd4d..5d2c2132 100644 --- a/resources/js/utils/useTasks.ts +++ b/resources/js/utils/useTasks.ts @@ -2,7 +2,7 @@ import { defineStore } from 'pinia'; import { getCurrentOrganizationId } from '@/utils/useUser'; import { api } from '../../../openapi.json.client'; import { reactive, ref } from 'vue'; -import type { CreateTaskBody, Task } from '@/utils/api'; +import type { CreateTaskBody, Task, UpdateTaskBody } from '@/utils/api'; import { useNotificationsStore } from '@/utils/notification'; export const useTasksStore = defineStore('tasks', () => { @@ -25,20 +25,21 @@ export const useTasksStore = defineStore('tasks', () => { } } - async function updateTask(task: Task) { + async function updateTask(taskId: string, taskBody: UpdateTaskBody) { const organizationId = getCurrentOrganizationId(); if (organizationId) { await handleApiRequestNotifications( () => - api.updateTask(task, { + api.updateTask(taskBody, { params: { + task: taskId, organization: organizationId, - task: task.id, }, }), 'Task updated successfully', 'Failed to update task' ); + await fetchTasks(); } }