From 5f7aee6a8d3eb3fecebf80cae9c5da21cf8d10ea Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal Date: Tue, 20 Dec 2022 16:05:21 +0530 Subject: [PATCH] fix: assign issues to cycle, feat: settings sidebar --- .../cycles/cycle-issues-list-modal.tsx | 10 +- .../create-update-issue-modal/index.tsx | 2 +- .../issue-detail-sidebar/index.tsx | 2 +- ...Invitations.tsx => member-invitations.tsx} | 43 +-- .../components/project/settings/control.tsx | 197 ------------- .../components/project/settings/general.tsx | 158 ----------- .../components/project/settings/members.tsx | 261 ----------------- .../settings/{labels => }/single-label.tsx | 0 .../components/project/settings/states.tsx | 130 --------- apps/app/constants/api-routes.ts | 5 - apps/app/layouts/navbar/main-siderbar.tsx | 28 +- apps/app/layouts/navbar/settings-sidebar.tsx | 14 +- apps/app/layouts/settings-layout.tsx | 69 ++++- apps/app/lib/services/issues.service.ts | 18 +- .../projects/[projectId]/cycles/[cycleId].tsx | 2 +- .../pages/projects/[projectId]/settings.tsx | 224 --------------- .../projects/[projectId]/settings/control.tsx | 268 ++++++++++++++++++ .../projects/[projectId]/settings/index.tsx | 234 +++++++++++++++ .../projects/[projectId]/settings/labels.tsx} | 46 +-- .../projects/[projectId]/settings/members.tsx | 267 +++++++++++++++++ .../projects/[projectId]/settings/states.tsx | 130 +++++++++ apps/app/pages/projects/index.tsx | 2 +- 22 files changed, 1039 insertions(+), 1071 deletions(-) rename apps/app/components/project/{memberInvitations.tsx => member-invitations.tsx} (85%) delete mode 100644 apps/app/components/project/settings/control.tsx delete mode 100644 apps/app/components/project/settings/general.tsx delete mode 100644 apps/app/components/project/settings/members.tsx rename apps/app/components/project/settings/{labels => }/single-label.tsx (100%) delete mode 100644 apps/app/components/project/settings/states.tsx delete mode 100644 apps/app/pages/projects/[projectId]/settings.tsx create mode 100644 apps/app/pages/projects/[projectId]/settings/control.tsx create mode 100644 apps/app/pages/projects/[projectId]/settings/index.tsx rename apps/app/{components/project/settings/labels/index.tsx => pages/projects/[projectId]/settings/labels.tsx} (87%) create mode 100644 apps/app/pages/projects/[projectId]/settings/members.tsx create mode 100644 apps/app/pages/projects/[projectId]/settings/states.tsx diff --git a/apps/app/components/project/cycles/cycle-issues-list-modal.tsx b/apps/app/components/project/cycles/cycle-issues-list-modal.tsx index 4b033c444..74595d326 100644 --- a/apps/app/components/project/cycles/cycle-issues-list-modal.tsx +++ b/apps/app/components/project/cycles/cycle-issues-list-modal.tsx @@ -28,7 +28,7 @@ type Props = { }; type FormInput = { - issue_ids: string[]; + issue: string[]; }; const CycleIssuesListModal: React.FC = ({ @@ -56,12 +56,12 @@ const CycleIssuesListModal: React.FC = ({ formState: { isSubmitting }, } = useForm({ defaultValues: { - issue_ids: [], + issue: [], }, }); const handleAddToCycle: SubmitHandler = (data) => { - if (!data.issue_ids || data.issue_ids.length === 0) { + if (!data.issue || data.issue.length === 0) { setToastAlert({ title: "Error", type: "error", @@ -72,7 +72,7 @@ const CycleIssuesListModal: React.FC = ({ if (activeWorkspace && activeProject) { issuesServices - .bulkAddIssuesToCycle(activeWorkspace.slug, activeProject.id, cycleId, data) + .addIssueToCycle(activeWorkspace.slug, activeProject.id, cycleId, data) .then((res) => { console.log(res); mutate(CYCLE_ISSUES(cycleId)); @@ -120,7 +120,7 @@ const CycleIssuesListModal: React.FC = ({
(
diff --git a/apps/app/components/project/issues/create-update-issue-modal/index.tsx b/apps/app/components/project/issues/create-update-issue-modal/index.tsx index 0fc8edb94..c1078b794 100644 --- a/apps/app/components/project/issues/create-update-issue-modal/index.tsx +++ b/apps/app/components/project/issues/create-update-issue-modal/index.tsx @@ -118,7 +118,7 @@ const CreateUpdateIssuesModal: React.FC = ({ if (!activeWorkspace || !activeProject) return; await issuesServices .addIssueToCycle(activeWorkspace.slug, activeProject.id, cycleId, { - issue: issueId, + issue: [issueId], }) .then((res) => { mutate(CYCLE_ISSUES(cycleId)); diff --git a/apps/app/components/project/issues/issue-detail/issue-detail-sidebar/index.tsx b/apps/app/components/project/issues/issue-detail/issue-detail-sidebar/index.tsx index b0fe60a23..8b448a178 100644 --- a/apps/app/components/project/issues/issue-detail/issue-detail-sidebar/index.tsx +++ b/apps/app/components/project/issues/issue-detail/issue-detail-sidebar/index.tsx @@ -101,7 +101,7 @@ const IssueDetailSidebar: React.FC = ({ if (activeWorkspace && activeProject && issueDetail) issuesServices .addIssueToCycle(activeWorkspace.slug, activeProject.id, cycleId, { - issue: issueDetail.id, + issue: [issueDetail.id], }) .then(() => { submitChanges({}); diff --git a/apps/app/components/project/memberInvitations.tsx b/apps/app/components/project/member-invitations.tsx similarity index 85% rename from apps/app/components/project/memberInvitations.tsx rename to apps/app/components/project/member-invitations.tsx index bd25db10a..4bc44f632 100644 --- a/apps/app/components/project/memberInvitations.tsx +++ b/apps/app/components/project/member-invitations.tsx @@ -3,14 +3,13 @@ import React, { useState } from "react"; // next import Link from "next/link"; import useSWR from "swr"; +import { useRouter } from "next/router"; +// services +import projectService from "lib/services/project.service"; // hooks import useUser from "lib/hooks/useUser"; -// Services -import projectService from "lib/services/project.service"; -// fetch keys -import { PROJECT_MEMBERS } from "constants/fetch-keys"; -// commons -import { renderShortNumericDateFormat } from "constants/common"; +// ui +import { Button } from "ui"; // icons import { CalendarDaysIcon, @@ -20,9 +19,15 @@ import { PencilIcon, PlusIcon, TrashIcon, + ClipboardDocumentListIcon, } from "@heroicons/react/24/outline"; // types import type { IProject } from "types"; +// fetch-keys +import { PROJECT_MEMBERS } from "constants/fetch-keys"; +// common +import { renderShortNumericDateFormat } from "constants/common"; + type Props = { project: IProject; slug: string; @@ -40,6 +45,8 @@ const ProjectMemberInvitations: React.FC = ({ }) => { const { user } = useUser(); + const router = useRouter(); + const { data: members } = useSWR(PROJECT_MEMBERS(project.id), () => projectService.projectMembers(slug, project.id) ); @@ -93,13 +100,13 @@ const ProjectMemberInvitations: React.FC = ({ {isMember ? (
- + )} - - - - View - - +
diff --git a/apps/app/components/project/settings/control.tsx b/apps/app/components/project/settings/control.tsx deleted file mode 100644 index eea215256..000000000 --- a/apps/app/components/project/settings/control.tsx +++ /dev/null @@ -1,197 +0,0 @@ -// react -import React from "react"; -// swr -import useSWR from "swr"; -// react-hook-form -import { Control, Controller } from "react-hook-form"; -// services -import workspaceService from "lib/services/workspace.service"; -// hooks -import useUser from "lib/hooks/useUser"; -// headless ui -import { Listbox, Transition } from "@headlessui/react"; -// ui -import { Button } from "ui"; -// icons -import { CheckIcon, ChevronDownIcon } from "@heroicons/react/24/outline"; -// types -import { IProject } from "types"; -// fetch-keys -import { WORKSPACE_MEMBERS } from "constants/fetch-keys"; - -type Props = { - control: Control; - isSubmitting: boolean; -}; - -const ControlSettings: React.FC = ({ control, isSubmitting }) => { - const { activeWorkspace } = useUser(); - - const { data: people } = useSWR( - activeWorkspace ? WORKSPACE_MEMBERS : null, - activeWorkspace ? () => workspaceService.workspaceMembers(activeWorkspace.slug) : null - ); - return ( - <> -
-
-

Control

-

Set the control for the project.

-
-
-
-

Project Lead

-

Select the project leader.

- ( - - {({ open }) => ( - <> -
- - - {people?.find((person) => person.member.id === value)?.member - .first_name ?? "Select Lead"} - - - - - - {people?.map((person) => ( - - `${ - active ? "bg-indigo-50" : "" - } text-gray-900 cursor-default select-none relative px-3 py-2` - } - value={person.member.id} - > - {({ selected, active }) => ( - <> - - {person.member.first_name !== "" - ? person.member.first_name - : person.member.email} - - - {selected ? ( - - - ) : null} - - )} - - ))} - - -
- - )} -
- )} - /> -
-
-

Default Assignee

-

- Select the default assignee for the project. -

- ( - - {({ open }) => ( - <> -
- - - {people?.find((p) => p.member.id === value)?.member.first_name ?? - "Select Default Assignee"} - - - - - - {people?.map((person) => ( - - `${ - active ? "bg-indigo-50" : "" - } text-gray-900 cursor-default select-none relative px-3 py-2` - } - value={person.member.id} - > - {({ selected, active }) => ( - <> - - {person.member.first_name !== "" - ? person.member.first_name - : person.member.email} - - - {selected ? ( - - - ) : null} - - )} - - ))} - - -
- - )} -
- )} - /> -
-
-
- -
-
- - ); -}; - -export default ControlSettings; diff --git a/apps/app/components/project/settings/general.tsx b/apps/app/components/project/settings/general.tsx deleted file mode 100644 index 0330ef9d6..000000000 --- a/apps/app/components/project/settings/general.tsx +++ /dev/null @@ -1,158 +0,0 @@ -// react -import { useCallback } from "react"; -// react-hook-form -import { Controller } from "react-hook-form"; -import type { Control, UseFormRegister, UseFormSetError } from "react-hook-form"; -// services -import projectServices from "lib/services/project.service"; -// hooks -import useUser from "lib/hooks/useUser"; -// ui -import { Button, Input, Select, TextArea, EmojiIconPicker } from "ui"; -// types -import { IProject } from "types"; -// constants -import { debounce } from "constants/common"; - -type Props = { - register: UseFormRegister; - errors: any; - setError: UseFormSetError; - isSubmitting: boolean; - control: Control; -}; - -const NETWORK_CHOICES = { "0": "Secret", "2": "Public" }; - -const GeneralSettings: React.FC = ({ - register, - errors, - setError, - isSubmitting, - control, -}) => { - const { activeWorkspace } = useUser(); - - const checkIdentifier = (slug: string, value: string) => { - projectServices.checkProjectIdentifierAvailability(slug, value).then((response) => { - console.log(response); - if (response.exists) setError("identifier", { message: "Identifier already exists" }); - }); - }; - - // eslint-disable-next-line react-hooks/exhaustive-deps - const checkIdentifierAvailability = useCallback(debounce(checkIdentifier, 1500), []); - - return ( - <> -
-
-

General

-

- This information will be displayed to every member of the project. -

-
-
-
-

Icon & Name

-

Select an icon and a name for the project.

-
- ( - - )} - /> - -
-
-
-

Description

-

Give a description to the project.

-