diff --git a/frontend/components/TaskCard.vue b/frontend/components/TaskCard.vue new file mode 100644 index 0000000..e0ccdd2 --- /dev/null +++ b/frontend/components/TaskCard.vue @@ -0,0 +1,72 @@ + + + diff --git a/frontend/components/TaskDrawer.vue b/frontend/components/TaskDrawer.vue new file mode 100644 index 0000000..54f8637 --- /dev/null +++ b/frontend/components/TaskDrawer.vue @@ -0,0 +1,225 @@ + + + diff --git a/frontend/components/TaskGroupDrawer.vue b/frontend/components/TaskGroupDrawer.vue new file mode 100644 index 0000000..a8714f2 --- /dev/null +++ b/frontend/components/TaskGroupDrawer.vue @@ -0,0 +1,108 @@ + + + diff --git a/frontend/i18n/locales/fr.json b/frontend/i18n/locales/fr.json index 36a49aa..e7c2342 100644 --- a/frontend/i18n/locales/fr.json +++ b/frontend/i18n/locales/fr.json @@ -28,5 +28,40 @@ "created": "Projet créé avec succès.", "updated": "Projet mis à jour avec succès.", "deleted": "Projet supprimé avec succès." + }, + "taskStatuses": { + "created": "Statut créé avec succès.", + "updated": "Statut mis à jour avec succès.", + "deleted": "Statut supprimé avec succès." + }, + "taskEfforts": { + "created": "Effort créé avec succès.", + "updated": "Effort mis à jour avec succès.", + "deleted": "Effort supprimé avec succès." + }, + "taskPriorities": { + "created": "Priorité créée avec succès.", + "updated": "Priorité mise à jour avec succès.", + "deleted": "Priorité supprimée avec succès." + }, + "taskTypes": { + "created": "Type créé avec succès.", + "updated": "Type mis à jour avec succès.", + "deleted": "Type supprimé avec succès." + }, + "taskGroups": { + "created": "Groupe créé avec succès.", + "updated": "Groupe mis à jour avec succès.", + "deleted": "Groupe supprimé avec succès." + }, + "tasks": { + "created": "Ticket créé avec succès.", + "updated": "Ticket mis à jour avec succès.", + "deleted": "Ticket supprimé avec succès." + }, + "users": { + "created": "Utilisateur créé avec succès.", + "updated": "Utilisateur mis à jour avec succès.", + "deleted": "Utilisateur supprimé avec succès." } } diff --git a/frontend/pages/projects/[id].vue b/frontend/pages/projects/[id].vue new file mode 100644 index 0000000..6f63992 --- /dev/null +++ b/frontend/pages/projects/[id].vue @@ -0,0 +1,308 @@ + + + diff --git a/frontend/pages/projects.vue b/frontend/pages/projects/index.vue similarity index 83% rename from frontend/pages/projects.vue rename to frontend/pages/projects/index.vue index d18b067..8ffd5d0 100644 --- a/frontend/pages/projects.vue +++ b/frontend/pages/projects/index.vue @@ -15,9 +15,17 @@ v-for="project in projects" :key="project.id" class="cursor-pointer rounded-lg border border-neutral-200 bg-tertiary-500 shadow-sm transition hover:shadow-md" - @click="openEdit(project)" + @click="navigateTo(`/projects/${project.id}`)" > -
+
+
+ +

{{ project.name }}

diff --git a/frontend/services/dto/task-effort.ts b/frontend/services/dto/task-effort.ts new file mode 100644 index 0000000..9d3e3e2 --- /dev/null +++ b/frontend/services/dto/task-effort.ts @@ -0,0 +1,9 @@ +export type TaskEffort = { + id: number + '@id'?: string + label: string +} + +export type TaskEffortWrite = { + label: string +} diff --git a/frontend/services/dto/task-group.ts b/frontend/services/dto/task-group.ts new file mode 100644 index 0000000..52bd804 --- /dev/null +++ b/frontend/services/dto/task-group.ts @@ -0,0 +1,17 @@ +import type { Project } from './project' + +export type TaskGroup = { + id: number + '@id'?: string + title: string + description: string | null + color: string + project: Project | null +} + +export type TaskGroupWrite = { + title: string + description: string | null + color: string + project: string +} diff --git a/frontend/services/dto/task-priority.ts b/frontend/services/dto/task-priority.ts new file mode 100644 index 0000000..2b71e6c --- /dev/null +++ b/frontend/services/dto/task-priority.ts @@ -0,0 +1,11 @@ +export type TaskPriority = { + id: number + '@id'?: string + label: string + color: string +} + +export type TaskPriorityWrite = { + label: string + color: string +} diff --git a/frontend/services/dto/task-status.ts b/frontend/services/dto/task-status.ts new file mode 100644 index 0000000..073c1ec --- /dev/null +++ b/frontend/services/dto/task-status.ts @@ -0,0 +1,13 @@ +export type TaskStatus = { + id: number + '@id'?: string + label: string + color: string + position: number +} + +export type TaskStatusWrite = { + label: string + color: string + position: number +} diff --git a/frontend/services/dto/task-type.ts b/frontend/services/dto/task-type.ts new file mode 100644 index 0000000..3153ab1 --- /dev/null +++ b/frontend/services/dto/task-type.ts @@ -0,0 +1,11 @@ +export type TaskType = { + id: number + '@id'?: string + label: string + color: string +} + +export type TaskTypeWrite = { + label: string + color: string +} diff --git a/frontend/services/dto/task.ts b/frontend/services/dto/task.ts new file mode 100644 index 0000000..8b103b4 --- /dev/null +++ b/frontend/services/dto/task.ts @@ -0,0 +1,31 @@ +import type { TaskStatus } from './task-status' +import type { TaskEffort } from './task-effort' +import type { TaskPriority } from './task-priority' +import type { TaskType } from './task-type' +import type { TaskGroup } from './task-group' +import type { UserData } from './user-data' + +export type Task = { + id: number + '@id'?: string + title: string + description: string | null + status: TaskStatus | null + effort: TaskEffort | null + priority: TaskPriority | null + assignee: UserData | null + group: TaskGroup | null + types: TaskType[] +} + +export type TaskWrite = { + title: string + description: string | null + status: string | null + effort: string | null + priority: string | null + assignee: string | null + group: string | null + project: string + types: string[] +} diff --git a/frontend/services/projects.ts b/frontend/services/projects.ts index 852824c..a61d98a 100644 --- a/frontend/services/projects.ts +++ b/frontend/services/projects.ts @@ -10,6 +10,10 @@ export function useProjectService() { return extractHydraMembers(data) } + async function getById(id: number): Promise { + return api.get(`/projects/${id}`) + } + async function create(payload: ProjectWrite): Promise { return api.post('/projects', payload as Record, { toastSuccessKey: 'projects.created', @@ -28,5 +32,5 @@ export function useProjectService() { }) } - return { getAll, create, update, remove } + return { getAll, getById, create, update, remove } } diff --git a/frontend/services/task-efforts.ts b/frontend/services/task-efforts.ts new file mode 100644 index 0000000..4f80833 --- /dev/null +++ b/frontend/services/task-efforts.ts @@ -0,0 +1,32 @@ +import type { TaskEffort, TaskEffortWrite } from './dto/task-effort' +import type { HydraCollection } from '~/utils/api' +import { extractHydraMembers } from '~/utils/api' + +export function useTaskEffortService() { + const api = useApi() + + async function getAll(): Promise { + const data = await api.get>('/task_efforts') + return extractHydraMembers(data) + } + + async function create(payload: TaskEffortWrite): Promise { + return api.post('/task_efforts', payload as Record, { + toastSuccessKey: 'taskEfforts.created', + }) + } + + async function update(id: number, payload: Partial): Promise { + return api.patch(`/task_efforts/${id}`, payload as Record, { + toastSuccessKey: 'taskEfforts.updated', + }) + } + + async function remove(id: number): Promise { + await api.delete(`/task_efforts/${id}`, {}, { + toastSuccessKey: 'taskEfforts.deleted', + }) + } + + return { getAll, create, update, remove } +} diff --git a/frontend/services/task-groups.ts b/frontend/services/task-groups.ts new file mode 100644 index 0000000..6866d77 --- /dev/null +++ b/frontend/services/task-groups.ts @@ -0,0 +1,39 @@ +import type { TaskGroup, TaskGroupWrite } from './dto/task-group' +import type { HydraCollection } from '~/utils/api' +import { extractHydraMembers } from '~/utils/api' + +export function useTaskGroupService() { + const api = useApi() + + async function getAll(): Promise { + const data = await api.get>('/task_groups') + return extractHydraMembers(data) + } + + async function getByProject(projectId: number): Promise { + const data = await api.get>('/task_groups', { + project: `/api/projects/${projectId}`, + }) + return extractHydraMembers(data) + } + + async function create(payload: TaskGroupWrite): Promise { + return api.post('/task_groups', payload as Record, { + toastSuccessKey: 'taskGroups.created', + }) + } + + async function update(id: number, payload: Partial): Promise { + return api.patch(`/task_groups/${id}`, payload as Record, { + toastSuccessKey: 'taskGroups.updated', + }) + } + + async function remove(id: number): Promise { + await api.delete(`/task_groups/${id}`, {}, { + toastSuccessKey: 'taskGroups.deleted', + }) + } + + return { getAll, getByProject, create, update, remove } +} diff --git a/frontend/services/task-priorities.ts b/frontend/services/task-priorities.ts new file mode 100644 index 0000000..963afbc --- /dev/null +++ b/frontend/services/task-priorities.ts @@ -0,0 +1,32 @@ +import type { TaskPriority, TaskPriorityWrite } from './dto/task-priority' +import type { HydraCollection } from '~/utils/api' +import { extractHydraMembers } from '~/utils/api' + +export function useTaskPriorityService() { + const api = useApi() + + async function getAll(): Promise { + const data = await api.get>('/task_priorities') + return extractHydraMembers(data) + } + + async function create(payload: TaskPriorityWrite): Promise { + return api.post('/task_priorities', payload as Record, { + toastSuccessKey: 'taskPriorities.created', + }) + } + + async function update(id: number, payload: Partial): Promise { + return api.patch(`/task_priorities/${id}`, payload as Record, { + toastSuccessKey: 'taskPriorities.updated', + }) + } + + async function remove(id: number): Promise { + await api.delete(`/task_priorities/${id}`, {}, { + toastSuccessKey: 'taskPriorities.deleted', + }) + } + + return { getAll, create, update, remove } +} diff --git a/frontend/services/task-statuses.ts b/frontend/services/task-statuses.ts new file mode 100644 index 0000000..28c4e06 --- /dev/null +++ b/frontend/services/task-statuses.ts @@ -0,0 +1,32 @@ +import type { TaskStatus, TaskStatusWrite } from './dto/task-status' +import type { HydraCollection } from '~/utils/api' +import { extractHydraMembers } from '~/utils/api' + +export function useTaskStatusService() { + const api = useApi() + + async function getAll(): Promise { + const data = await api.get>('/task_statuses') + return extractHydraMembers(data) + } + + async function create(payload: TaskStatusWrite): Promise { + return api.post('/task_statuses', payload as Record, { + toastSuccessKey: 'taskStatuses.created', + }) + } + + async function update(id: number, payload: Partial): Promise { + return api.patch(`/task_statuses/${id}`, payload as Record, { + toastSuccessKey: 'taskStatuses.updated', + }) + } + + async function remove(id: number): Promise { + await api.delete(`/task_statuses/${id}`, {}, { + toastSuccessKey: 'taskStatuses.deleted', + }) + } + + return { getAll, create, update, remove } +} diff --git a/frontend/services/task-types.ts b/frontend/services/task-types.ts new file mode 100644 index 0000000..22341be --- /dev/null +++ b/frontend/services/task-types.ts @@ -0,0 +1,32 @@ +import type { TaskType, TaskTypeWrite } from './dto/task-type' +import type { HydraCollection } from '~/utils/api' +import { extractHydraMembers } from '~/utils/api' + +export function useTaskTypeService() { + const api = useApi() + + async function getAll(): Promise { + const data = await api.get>('/task_types') + return extractHydraMembers(data) + } + + async function create(payload: TaskTypeWrite): Promise { + return api.post('/task_types', payload as Record, { + toastSuccessKey: 'taskTypes.created', + }) + } + + async function update(id: number, payload: Partial): Promise { + return api.patch(`/task_types/${id}`, payload as Record, { + toastSuccessKey: 'taskTypes.updated', + }) + } + + async function remove(id: number): Promise { + await api.delete(`/task_types/${id}`, {}, { + toastSuccessKey: 'taskTypes.deleted', + }) + } + + return { getAll, create, update, remove } +} diff --git a/frontend/services/tasks.ts b/frontend/services/tasks.ts new file mode 100644 index 0000000..6d9e1f6 --- /dev/null +++ b/frontend/services/tasks.ts @@ -0,0 +1,34 @@ +import type { Task, TaskWrite } from './dto/task' +import type { HydraCollection } from '~/utils/api' +import { extractHydraMembers } from '~/utils/api' + +export function useTaskService() { + const api = useApi() + + async function getByProject(projectId: number): Promise { + const data = await api.get>('/tasks', { + project: `/api/projects/${projectId}`, + }) + return extractHydraMembers(data) + } + + async function create(payload: TaskWrite): Promise { + return api.post('/tasks', payload as Record, { + toastSuccessKey: 'tasks.created', + }) + } + + async function update(id: number, payload: Partial): Promise { + return api.patch(`/tasks/${id}`, payload as Record, { + toastSuccessKey: 'tasks.updated', + }) + } + + async function remove(id: number): Promise { + await api.delete(`/tasks/${id}`, {}, { + toastSuccessKey: 'tasks.deleted', + }) + } + + return { getByProject, create, update, remove } +}