From 6c4256b27d176e6a7957fcbd452f18c7aabaae3f Mon Sep 17 00:00:00 2001 From: Gregor Vostrak Date: Tue, 1 Oct 2024 00:45:37 +0200 Subject: [PATCH] add project member role selection to create and update modals, fixes ST-446 --- .../ProjectMember/ProjectMemberResource.php | 2 + .../ProjectMemberCreateModal.vue | 19 +++++-- .../ProjectMember/ProjectMemberEditModal.vue | 49 ++++++++++------- .../ProjectMember/ProjectMemberRoleSelect.vue | 54 +++++++++++++++++++ .../ProjectMember/ProjectMemberTableRow.vue | 2 +- .../packages/api/src/openapi.json.client.ts | 10 +++- .../TimeTrackerProjectTaskDropdown.vue | 1 + resources/js/utils/useProjectMembers.ts | 1 + 8 files changed, 113 insertions(+), 25 deletions(-) create mode 100644 resources/js/Components/Common/ProjectMember/ProjectMemberRoleSelect.vue diff --git a/app/Http/Resources/V1/ProjectMember/ProjectMemberResource.php b/app/Http/Resources/V1/ProjectMember/ProjectMemberResource.php index 8e986b25..c4352d39 100644 --- a/app/Http/Resources/V1/ProjectMember/ProjectMemberResource.php +++ b/app/Http/Resources/V1/ProjectMember/ProjectMemberResource.php @@ -29,6 +29,8 @@ class ProjectMemberResource extends BaseResource 'member_id' => $this->resource->member_id, /** @var string $project_id ID of the project */ 'project_id' => $this->resource->project_id, + /** @var string $role Role of the project member */ + 'role' => $this->resource->role->value, ]; } } diff --git a/resources/js/Components/Common/ProjectMember/ProjectMemberCreateModal.vue b/resources/js/Components/Common/ProjectMember/ProjectMemberCreateModal.vue index 962def03..d77f428b 100644 --- a/resources/js/Components/Common/ProjectMember/ProjectMemberCreateModal.vue +++ b/resources/js/Components/Common/ProjectMember/ProjectMemberCreateModal.vue @@ -12,6 +12,8 @@ import { useProjectMembersStore } from '@/utils/useProjectMembers'; import MemberCombobox from '@/Components/Common/Member/MemberCombobox.vue'; import BillableRateInput from '@/packages/ui/src/Input/BillableRateInput.vue'; import { getOrganizationCurrencyString } from '@/utils/money'; +import { InputLabel } from '@/packages/ui/src'; +import ProjectMemberRoleSelect from '@/Components/Common/ProjectMember/ProjectMemberRoleSelect.vue'; const { createProjectMember } = useProjectMembersStore(); const show = defineModel('show', { default: false }); const saving = ref(false); @@ -24,6 +26,7 @@ const props = defineProps<{ const projectMember = ref({ member_id: '', billable_rate: null, + role: 'normal', }); async function submit() { @@ -32,6 +35,7 @@ async function submit() { projectMember.value = { member_id: '', billable_rate: null, + role: 'normal', }; } @@ -49,13 +53,17 @@ useFocus(projectNameInput, { initialValue: true }); diff --git a/resources/js/Components/Common/ProjectMember/ProjectMemberRoleSelect.vue b/resources/js/Components/Common/ProjectMember/ProjectMemberRoleSelect.vue new file mode 100644 index 00000000..f1c41f81 --- /dev/null +++ b/resources/js/Components/Common/ProjectMember/ProjectMemberRoleSelect.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/resources/js/Components/Common/ProjectMember/ProjectMemberTableRow.vue b/resources/js/Components/Common/ProjectMember/ProjectMemberTableRow.vue index c07a26c3..18f1e87d 100644 --- a/resources/js/Components/Common/ProjectMember/ProjectMemberTableRow.vue +++ b/resources/js/Components/Common/ProjectMember/ProjectMemberTableRow.vue @@ -57,7 +57,7 @@ const showEditModal = ref(false); }}
- {{ capitalizeFirstLetter(member?.role ?? '') }} + {{ capitalizeFirstLetter(projectMember?.role ?? '') }}
diff --git a/resources/js/packages/api/src/openapi.json.client.ts b/resources/js/packages/api/src/openapi.json.client.ts index ea962f36..26c51a4a 100644 --- a/resources/js/packages/api/src/openapi.json.client.ts +++ b/resources/js/packages/api/src/openapi.json.client.ts @@ -70,6 +70,7 @@ const ProjectResource = z is_billable: z.boolean(), estimated_time: z.union([z.number(), z.null()]), spent_time: z.number().int(), + limited_visibility: z.boolean(), }) .passthrough(); const ProjectStoreRequest = z @@ -99,16 +100,22 @@ const ProjectMemberResource = z billable_rate: z.union([z.number(), z.null()]), member_id: z.string(), project_id: z.string(), + role: z.string(), }) .passthrough(); +const ProjectMemberRole = z.enum(['manager', 'normal']); const ProjectMemberStoreRequest = z .object({ member_id: z.string().uuid(), billable_rate: z.union([z.number(), z.null()]).optional(), + role: ProjectMemberRole, }) .passthrough(); const ProjectMemberUpdateRequest = z - .object({ billable_rate: z.union([z.number(), z.null()]) }) + .object({ + billable_rate: z.union([z.number(), z.null()]), + role: ProjectMemberRole, + }) .partial() .passthrough(); const TagResource = z @@ -257,6 +264,7 @@ export const schemas = { ProjectStoreRequest, ProjectUpdateRequest, ProjectMemberResource, + ProjectMemberRole, ProjectMemberStoreRequest, ProjectMemberUpdateRequest, TagResource, diff --git a/resources/js/packages/ui/src/TimeTracker/TimeTrackerProjectTaskDropdown.vue b/resources/js/packages/ui/src/TimeTracker/TimeTrackerProjectTaskDropdown.vue index 91d640c8..d41b39a8 100644 --- a/resources/js/packages/ui/src/TimeTracker/TimeTrackerProjectTaskDropdown.vue +++ b/resources/js/packages/ui/src/TimeTracker/TimeTrackerProjectTaskDropdown.vue @@ -167,6 +167,7 @@ watchEffect(() => { tasks: [], estimated_time: null, spent_time: 0, + limited_visibility: false, }, ], }); diff --git a/resources/js/utils/useProjectMembers.ts b/resources/js/utils/useProjectMembers.ts index ac4614bf..39921313 100644 --- a/resources/js/utils/useProjectMembers.ts +++ b/resources/js/utils/useProjectMembers.ts @@ -9,6 +9,7 @@ import type { } from '@/packages/api/src'; import { getCurrentOrganizationId } from '@/utils/useUser'; import { useNotificationsStore } from '@/utils/notification'; +export type ProjectMemberRole = 'normal' | 'manager'; export const useProjectMembersStore = defineStore('project-members', () => { const projectMemberResponse = ref(null);