From 78c077b8e72ec9790ed68efcd506d9400f5905fe Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal Date: Sat, 14 Oct 2023 12:01:11 +0530 Subject: [PATCH 1/3] fix: service imports --- .../scope-and-demand/scope-and-demand.tsx | 5 +- .../change-interface-theme.tsx | 3 +- web/components/command-palette/command-k.tsx | 15 +- .../command-palette/command-pallette.tsx | 9 +- .../issue/change-issue-assignee.tsx | 3 +- .../issue/change-issue-priority.tsx | 11 +- .../issue/change-issue-state.tsx | 14 +- .../common/product-updates-modal.tsx | 6 +- web/components/core/activity.tsx | 7 +- web/components/core/image-picker-popover.tsx | 10 +- .../core/modals/gpt-assistant-modal.tsx | 5 +- .../core/modals/image-upload-modal.tsx | 5 +- .../core/views/board-view/all-boards.tsx | 152 ----- .../core/views/board-view/board-header.tsx | 231 -------- web/components/core/views/board-view/index.ts | 5 - .../board-view/inline-create-issue-form.tsx | 62 -- .../core/views/board-view/single-board.tsx | 289 --------- .../core/views/board-view/single-issue.tsx | 547 ------------------ .../views/calendar-view/calendar-header.tsx | 153 ----- .../core/views/calendar-view/calendar.tsx | 217 ------- .../core/views/calendar-view/index.ts | 5 - .../inline-create-issue-form.tsx | 102 ---- .../core/views/calendar-view/single-date.tsx | 126 ---- .../core/views/calendar-view/single-issue.tsx | 403 ------------- web/components/core/views/list-view/index.ts | 4 - .../list-view/inline-create-issue-form.tsx | 62 -- .../core/views/list-view/single-issue.tsx | 511 ---------------- .../core/views/list-view/single-list.tsx | 337 ----------- .../cycles/active-cycle-details.tsx | 13 +- .../completed-cycles-list.tsx | 7 +- web/components/cycles/delete-cycle-modal.tsx | 5 +- web/components/cycles/modal.tsx | 5 +- web/components/estimates/single-estimate.tsx | 5 +- .../integration/delete-import-modal.tsx | 8 +- .../integration/single-integration-card.tsx | 10 +- web/components/ui/product-updates-modal.tsx | 10 +- web/components/web-view/select-blocker-to.tsx | 25 +- web/components/web-view/select-cycle.tsx | 22 +- web/components/web-view/select-module.tsx | 21 +- .../[projectId]/settings/integrations.tsx | 14 +- .../projects/[projectId]/settings/labels.tsx | 16 +- .../projects/[projectId]/settings/members.tsx | 8 +- .../projects/[projectId]/views/[viewId].tsx | 15 +- 43 files changed, 162 insertions(+), 3321 deletions(-) delete mode 100644 web/components/core/views/board-view/all-boards.tsx delete mode 100644 web/components/core/views/board-view/board-header.tsx delete mode 100644 web/components/core/views/board-view/index.ts delete mode 100644 web/components/core/views/board-view/inline-create-issue-form.tsx delete mode 100644 web/components/core/views/board-view/single-board.tsx delete mode 100644 web/components/core/views/board-view/single-issue.tsx delete mode 100644 web/components/core/views/calendar-view/calendar-header.tsx delete mode 100644 web/components/core/views/calendar-view/calendar.tsx delete mode 100644 web/components/core/views/calendar-view/index.ts delete mode 100644 web/components/core/views/calendar-view/inline-create-issue-form.tsx delete mode 100644 web/components/core/views/calendar-view/single-date.tsx delete mode 100644 web/components/core/views/calendar-view/single-issue.tsx delete mode 100644 web/components/core/views/list-view/index.ts delete mode 100644 web/components/core/views/list-view/inline-create-issue-form.tsx delete mode 100644 web/components/core/views/list-view/single-issue.tsx delete mode 100644 web/components/core/views/list-view/single-list.tsx diff --git a/web/components/analytics/scope-and-demand/scope-and-demand.tsx b/web/components/analytics/scope-and-demand/scope-and-demand.tsx index 1acb593add8..0f9e2c712d8 100644 --- a/web/components/analytics/scope-and-demand/scope-and-demand.tsx +++ b/web/components/analytics/scope-and-demand/scope-and-demand.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import analyticsService from "services/analytics.service"; +import { AnalyticsService } from "services/analytics.service"; // components import { AnalyticsDemand, AnalyticsLeaderBoard, AnalyticsScope, AnalyticsYearWiseIssues } from "components/analytics"; // ui @@ -15,6 +15,9 @@ type Props = { fullScreen?: boolean; }; +// services +const analyticsService = new AnalyticsService(); + export const ScopeAndDemand: React.FC = (props) => { const { fullScreen = true } = props; diff --git a/web/components/command-palette/change-interface-theme.tsx b/web/components/command-palette/change-interface-theme.tsx index 87d1289aec0..1285eeb21cd 100644 --- a/web/components/command-palette/change-interface-theme.tsx +++ b/web/components/command-palette/change-interface-theme.tsx @@ -5,7 +5,6 @@ import { Command } from "cmdk"; import { THEMES_OBJ } from "constants/themes"; import { useTheme } from "next-themes"; import { SettingIcon } from "components/icons"; -import userService from "services/user.service"; import useUser from "hooks/use-user"; // helper import { unsetCustomCssVariables } from "helpers/theme.helper"; @@ -25,7 +24,7 @@ export const ChangeInterfaceTheme: React.FC = observer(({ setIsPaletteOpe const { setTheme } = useTheme(); - const { user, mutateUser } = useUser(); + const { user } = useUser(); const updateUserTheme = (newTheme: string) => { if (!user) return; diff --git a/web/components/command-palette/command-k.tsx b/web/components/command-palette/command-k.tsx index 25a8de4887d..382acd19e6e 100644 --- a/web/components/command-palette/command-k.tsx +++ b/web/components/command-palette/command-k.tsx @@ -9,9 +9,9 @@ import { Command } from "cmdk"; // headless ui import { Dialog, Transition } from "@headlessui/react"; // services -import workspaceService from "services/workspace.service"; -import issuesService from "services/issue/issue.service"; -import inboxService from "services/inbox.service"; +import { WorkspaceService } from "services/workspace.service"; +import { IssueService } from "services/issue"; +import { InboxService } from "services/inbox.service"; // hooks import useProjectDetails from "hooks/use-project-details"; import useDebounce from "hooks/use-debounce"; @@ -44,6 +44,11 @@ type Props = { setIsPaletteOpen: React.Dispatch>; }; +// services +const workspaceService = new WorkspaceService(); +const issueService = new IssueService(); +const inboxService = new InboxService(); + export const CommandK: React.FC = ({ deleteIssue, isPaletteOpen, setIsPaletteOpen }) => { const [placeholder, setPlaceholder] = useState("Type a command or search..."); @@ -80,7 +85,7 @@ export const CommandK: React.FC = ({ deleteIssue, isPaletteOpen, setIsPal const { data: issueDetails } = useSWR( workspaceSlug && projectId && issueId ? ISSUE_DETAILS(issueId as string) : null, workspaceSlug && projectId && issueId - ? () => issuesService.retrieve(workspaceSlug as string, projectId as string, issueId as string) + ? () => issueService.retrieve(workspaceSlug as string, projectId as string, issueId as string) : null ); @@ -108,7 +113,7 @@ export const CommandK: React.FC = ({ deleteIssue, isPaletteOpen, setIsPal ); const payload = { ...formData }; - await issuesService + await issueService .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user) .then(() => { mutate(PROJECT_ISSUES_ACTIVITY(issueId as string)); diff --git a/web/components/command-palette/command-pallette.tsx b/web/components/command-palette/command-pallette.tsx index f4463d22a04..3b90f26997e 100644 --- a/web/components/command-palette/command-pallette.tsx +++ b/web/components/command-palette/command-pallette.tsx @@ -17,12 +17,15 @@ import { CreateUpdatePageModal } from "components/pages"; // helpers import { copyTextToClipboard } from "helpers/string.helper"; // services -import issuesService from "services/issue/issue.service"; +import { IssueService } from "services/issue"; // fetch keys import { ISSUE_DETAILS } from "constants/fetch-keys"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; +// services +const issueService = new IssueService(); + export const CommandPalette: React.FC = observer(() => { const store: any = useMobxStore(); @@ -47,7 +50,7 @@ export const CommandPalette: React.FC = observer(() => { const { data: issueDetails } = useSWR( workspaceSlug && projectId && issueId ? ISSUE_DETAILS(issueId as string) : null, workspaceSlug && projectId && issueId - ? () => issuesService.retrieve(workspaceSlug as string, projectId as string, issueId as string) + ? () => issueService.retrieve(workspaceSlug as string, projectId as string, issueId as string) : null ); @@ -117,7 +120,7 @@ export const CommandPalette: React.FC = observer(() => { } } }, - [copyIssueUrlToClipboard] + [copyIssueUrlToClipboard, store.theme] ); useEffect(() => { diff --git a/web/components/command-palette/issue/change-issue-assignee.tsx b/web/components/command-palette/issue/change-issue-assignee.tsx index 81d6982af86..dbab764d232 100644 --- a/web/components/command-palette/issue/change-issue-assignee.tsx +++ b/web/components/command-palette/issue/change-issue-assignee.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import { mutate } from "swr"; import { Command } from "cmdk"; // services -import IssueService from "services/issue/issue.service"; +import { IssueService } from "services/issue"; // hooks import useProjectMembers from "hooks/use-project-members"; // constants @@ -21,6 +21,7 @@ type Props = { user: IUser | undefined; }; +// services const issueService = new IssueService(); export const ChangeIssueAssignee: FC = ({ setIsPaletteOpen, issue, user }) => { diff --git a/web/components/command-palette/issue/change-issue-priority.tsx b/web/components/command-palette/issue/change-issue-priority.tsx index 2234c663fec..e38fb1b8323 100644 --- a/web/components/command-palette/issue/change-issue-priority.tsx +++ b/web/components/command-palette/issue/change-issue-priority.tsx @@ -7,9 +7,9 @@ import { mutate } from "swr"; // cmdk import { Command } from "cmdk"; // services -import issuesService from "services/issue/issue.service"; +import { IssueService } from "services/issue"; // types -import { ICurrentUserResponse, IIssue, TIssuePriorities } from "types"; +import { IIssue, IUser, TIssuePriorities } from "types"; // constants import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys"; import { PRIORITIES } from "constants/project"; @@ -19,9 +19,12 @@ import { CheckIcon, PriorityIcon } from "components/icons"; type Props = { setIsPaletteOpen: Dispatch>; issue: IIssue; - user: ICurrentUserResponse; + user: IUser; }; +// services +const issueService = new IssueService(); + export const ChangeIssuePriority: React.FC = ({ setIsPaletteOpen, issue, user }) => { const router = useRouter(); const { workspaceSlug, projectId, issueId } = router.query; @@ -44,7 +47,7 @@ export const ChangeIssuePriority: React.FC = ({ setIsPaletteOpen, issue, ); const payload = { ...formData }; - await issuesService + await issueService .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user) .then(() => { mutate(PROJECT_ISSUES_ACTIVITY(issueId as string)); diff --git a/web/components/command-palette/issue/change-issue-state.tsx b/web/components/command-palette/issue/change-issue-state.tsx index 10e6a781b6d..0dfa23e6aec 100644 --- a/web/components/command-palette/issue/change-issue-state.tsx +++ b/web/components/command-palette/issue/change-issue-state.tsx @@ -7,8 +7,8 @@ import useSWR, { mutate } from "swr"; // cmdk import { Command } from "cmdk"; // services -import issuesService from "services/issue/issue.service"; -import stateService from "services/project.service/project_state.service"; +import { IssueService } from "services/issue"; +import { ProjectStateService } from "services/project"; // ui import { Spinner } from "@plane/ui"; // icons @@ -16,16 +16,20 @@ import { CheckIcon, StateGroupIcon } from "components/icons"; // helpers import { getStatesList } from "helpers/state.helper"; // types -import { ICurrentUserResponse, IIssue } from "types"; +import { IUser, IIssue } from "types"; // fetch keys import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY, STATES_LIST } from "constants/fetch-keys"; type Props = { setIsPaletteOpen: Dispatch>; issue: IIssue; - user: ICurrentUserResponse | undefined; + user: IUser | undefined; }; +// services +const issueService = new IssueService(); +const stateService = new ProjectStateService(); + export const ChangeIssueState: React.FC = ({ setIsPaletteOpen, issue, user }) => { const router = useRouter(); const { workspaceSlug, projectId, issueId } = router.query; @@ -53,7 +57,7 @@ export const ChangeIssueState: React.FC = ({ setIsPaletteOpen, issue, use ); const payload = { ...formData }; - await issuesService + await issueService .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user) .then(() => { mutateIssueDetails(); diff --git a/web/components/common/product-updates-modal.tsx b/web/components/common/product-updates-modal.tsx index 2c88419ddd7..f309b830386 100644 --- a/web/components/common/product-updates-modal.tsx +++ b/web/components/common/product-updates-modal.tsx @@ -5,7 +5,7 @@ import useSWR from "swr"; // headless ui import { Dialog, Transition } from "@headlessui/react"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // components import { MarkdownRenderer } from "components/ui"; import { Loader } from "@plane/ui"; @@ -19,8 +19,12 @@ type Props = { setIsOpen: React.Dispatch>; }; +// services +const workspaceService = new WorkspaceService(); + export const ProductUpdatesModal: React.FC = ({ isOpen, setIsOpen }) => { const { data: updates } = useSWR("PRODUCT_UPDATES", () => workspaceService.getProductUpdates()); + return ( diff --git a/web/components/core/activity.tsx b/web/components/core/activity.tsx index 0d0013a52b6..affb2aa46c5 100644 --- a/web/components/core/activity.tsx +++ b/web/components/core/activity.tsx @@ -5,7 +5,7 @@ import useSWR from "swr"; // hook import useEstimateOption from "hooks/use-estimate-option"; // services -import issuesService from "services/issue/issue.service"; +import { IssueLabelService } from "services/issue"; // icons import { Tooltip } from "@plane/ui"; import { Icon } from "components/ui"; @@ -33,6 +33,9 @@ import { IIssueActivity } from "types"; // fetch-keys import { WORKSPACE_LABELS } from "constants/fetch-keys"; +// services +const issueLabelService = new IssueLabelService(); + const IssueLink = ({ activity }: { activity: IIssueActivity }) => { const router = useRouter(); const { workspaceSlug } = router.query; @@ -74,7 +77,7 @@ const LabelPill = ({ labelId }: { labelId: string }) => { const { data: labels } = useSWR( workspaceSlug ? WORKSPACE_LABELS(workspaceSlug.toString()) : null, - workspaceSlug ? () => issuesService.getWorkspaceLabels(workspaceSlug.toString()) : null + workspaceSlug ? () => issueLabelService.getWorkspaceIssueLabels(workspaceSlug.toString()) : null ); return ( diff --git a/web/components/core/image-picker-popover.tsx b/web/components/core/image-picker-popover.tsx index ea6ac68f332..9b6addbb5e0 100644 --- a/web/components/core/image-picker-popover.tsx +++ b/web/components/core/image-picker-popover.tsx @@ -6,7 +6,7 @@ import { useDropzone } from "react-dropzone"; import { Tab, Transition, Popover } from "@headlessui/react"; import { Control, Controller } from "react-hook-form"; // services -import fileService from "services/file.service"; +import { FileService } from "services/file.service"; // hooks import useWorkspaceDetails from "hooks/use-workspace-details"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; @@ -36,6 +36,9 @@ type Props = { disabled?: boolean; }; +// services +const fileService = new FileService(); + export const ImagePickerPopover: React.FC = ({ label, value, control, onChange, disabled = false }) => { const ref = useRef(null); @@ -65,11 +68,6 @@ export const ImagePickerPopover: React.FC = ({ label, value, control, onC revalidateOnReconnect: false, }); - const { data: projectCoverImages } = useSWR(`PROJECT_COVER_IMAGES`, () => fileService.getProjectCoverImages(), { - revalidateOnFocus: false, - revalidateOnReconnect: false, - }); - const imagePickerRef = useRef(null); const { workspaceDetails } = useWorkspaceDetails(); diff --git a/web/components/core/modals/gpt-assistant-modal.tsx b/web/components/core/modals/gpt-assistant-modal.tsx index 3a797ea2bb1..c95266a5be5 100644 --- a/web/components/core/modals/gpt-assistant-modal.tsx +++ b/web/components/core/modals/gpt-assistant-modal.tsx @@ -3,8 +3,8 @@ import { useRouter } from "next/router"; // react-hook-form import { Controller, useForm } from "react-hook-form"; // services -import AIService from "services/ai.service"; -import TrackEventService from "services/track_event.service"; +import { AIService } from "services/ai.service"; +import { TrackEventService } from "services/track_event.service"; // hooks import useToast from "hooks/use-toast"; import useUserAuth from "hooks/use-user-auth"; @@ -32,6 +32,7 @@ type FormData = { task: string; }; +// services const aiService = new AIService(); const trackEventService = new TrackEventService(); diff --git a/web/components/core/modals/image-upload-modal.tsx b/web/components/core/modals/image-upload-modal.tsx index 5f67c182be1..84f4b03b6b0 100644 --- a/web/components/core/modals/image-upload-modal.tsx +++ b/web/components/core/modals/image-upload-modal.tsx @@ -7,7 +7,7 @@ import { useDropzone } from "react-dropzone"; // headless ui import { Transition, Dialog } from "@headlessui/react"; // services -import fileService from "services/file.service"; +import { FileService } from "services/file.service"; // hooks import useWorkspaceDetails from "hooks/use-workspace-details"; // ui @@ -25,6 +25,9 @@ type Props = { userImage?: boolean; }; +// services +const fileService = new FileService(); + export const ImageUploadModal: React.FC = ({ value, onSuccess, diff --git a/web/components/core/views/board-view/all-boards.tsx b/web/components/core/views/board-view/all-boards.tsx deleted file mode 100644 index 37503043a36..00000000000 --- a/web/components/core/views/board-view/all-boards.tsx +++ /dev/null @@ -1,152 +0,0 @@ -import { useRouter } from "next/router"; - -//hook -import useMyIssues from "hooks/my-issues/use-my-issues"; -import useIssuesView from "hooks/use-issues-view"; -import useProfileIssues from "hooks/use-profile-issues"; -// components -import { SingleBoard } from "components/core/views/board-view/single-board"; -import { IssuePeekOverview } from "components/issues"; -// icons -import { StateGroupIcon } from "components/icons"; -// helpers -import { addSpaceIfCamelCase } from "helpers/string.helper"; -// types -import { ICurrentUserResponse, IIssue, IIssueViewProps, IState, UserAuth } from "types"; - -type Props = { - addIssueToGroup: (groupTitle: string) => void; - disableUserActions: boolean; - disableAddIssueOption?: boolean; - dragDisabled: boolean; - handleIssueAction: (issue: IIssue, action: "copy" | "delete" | "edit") => void; - handleDraftIssueAction?: (issue: IIssue, action: "edit" | "delete") => void; - handleTrashBox: (isDragging: boolean) => void; - openIssuesListModal?: (() => void) | null; - removeIssue: ((bridgeId: string, issueId: string) => void) | null; - myIssueProjectId?: string | null; - handleMyIssueOpen?: (issue: IIssue) => void; - states: IState[] | undefined; - user: ICurrentUserResponse | undefined; - userAuth: UserAuth; - viewProps: IIssueViewProps; -}; - -export const AllBoards: React.FC = ({ - addIssueToGroup, - disableUserActions, - disableAddIssueOption = false, - dragDisabled, - handleIssueAction, - handleDraftIssueAction, - handleTrashBox, - openIssuesListModal, - myIssueProjectId, - handleMyIssueOpen, - removeIssue, - states, - user, - userAuth, - viewProps, -}) => { - const router = useRouter(); - const { workspaceSlug, projectId, userId } = router.query; - - const isProfileIssue = - router.pathname.includes("assigned") || - router.pathname.includes("created") || - router.pathname.includes("subscribed"); - - const isMyIssue = router.pathname.includes("my-issues"); - - const { mutateIssues } = useIssuesView(); - const { mutateMyIssues } = useMyIssues(workspaceSlug?.toString()); - const { mutateProfileIssues } = useProfileIssues(workspaceSlug?.toString(), userId?.toString()); - - const { displayFilters, groupedIssues } = viewProps; - - return ( - <> - - isMyIssue ? mutateMyIssues() : isProfileIssue ? mutateProfileIssues() : mutateIssues() - } - projectId={myIssueProjectId ? myIssueProjectId : projectId?.toString() ?? ""} - workspaceSlug={workspaceSlug?.toString() ?? ""} - readOnly={disableUserActions} - /> - {groupedIssues ? ( -
- {Object.keys(groupedIssues).map((singleGroup, index) => { - const currentState = - displayFilters?.group_by === "state" - ? states?.find((s) => s.id === singleGroup) - : null; - - if (!displayFilters?.show_empty_groups && groupedIssues[singleGroup].length === 0) - return null; - - return ( - addIssueToGroup(singleGroup)} - currentState={currentState} - disableUserActions={disableUserActions} - disableAddIssueOption={disableAddIssueOption} - dragDisabled={dragDisabled} - groupTitle={singleGroup} - handleIssueAction={handleIssueAction} - handleDraftIssueAction={handleDraftIssueAction} - handleTrashBox={handleTrashBox} - openIssuesListModal={openIssuesListModal ?? null} - handleMyIssueOpen={handleMyIssueOpen} - removeIssue={removeIssue} - user={user} - userAuth={userAuth} - viewProps={viewProps} - /> - ); - })} - {!displayFilters?.show_empty_groups && ( -
-

Hidden groups

-
- {Object.keys(groupedIssues).map((singleGroup, index) => { - const currentState = - displayFilters?.group_by === "state" - ? states?.find((s) => s.id === singleGroup) - : null; - - if (groupedIssues[singleGroup].length === 0) - return ( -
-
- {currentState && ( - - )} -

- {displayFilters?.group_by === "state" - ? addSpaceIfCamelCase(currentState?.name ?? "") - : addSpaceIfCamelCase(singleGroup)} -

-
- 0 -
- ); - })} -
-
- )} -
- ) : null} - - ); -}; diff --git a/web/components/core/views/board-view/board-header.tsx b/web/components/core/views/board-view/board-header.tsx deleted file mode 100644 index 1c2bef60fb6..00000000000 --- a/web/components/core/views/board-view/board-header.tsx +++ /dev/null @@ -1,231 +0,0 @@ -import React from "react"; - -import { useRouter } from "next/router"; - -import useSWR from "swr"; - -// services -import issuesService from "services/issues.service"; -import projectService from "services/project.service"; -// hooks -import useProjects from "hooks/use-projects"; -// component -import { Avatar, Icon } from "components/ui"; -// icons -import { PlusIcon } from "@heroicons/react/24/outline"; -import { PriorityIcon, StateGroupIcon } from "components/icons"; -// helpers -import { addSpaceIfCamelCase } from "helpers/string.helper"; -import { renderEmoji } from "helpers/emoji.helper"; -// types -import { IIssueViewProps, IState, TIssuePriorities, TStateGroups } from "types"; -// fetch-keys -import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS, WORKSPACE_LABELS } from "constants/fetch-keys"; -// constants -import { STATE_GROUP_COLORS } from "constants/state"; - -type Props = { - currentState?: IState | null; - groupTitle: string; - addIssueToGroup: () => void; - isCollapsed: boolean; - setIsCollapsed: React.Dispatch>; - disableUserActions: boolean; - disableAddIssue: boolean; - viewProps: IIssueViewProps; -}; - -export const BoardHeader: React.FC = ({ - currentState, - groupTitle, - addIssueToGroup, - isCollapsed, - setIsCollapsed, - disableUserActions, - disableAddIssue, - viewProps, -}) => { - const router = useRouter(); - const { workspaceSlug, projectId } = router.query; - - const { displayFilters, groupedIssues } = viewProps; - - const { data: issueLabels } = useSWR( - workspaceSlug && projectId && displayFilters?.group_by === "labels" - ? PROJECT_ISSUE_LABELS(projectId.toString()) - : null, - workspaceSlug && projectId && displayFilters?.group_by === "labels" - ? () => issuesService.getIssueLabels(workspaceSlug.toString(), projectId.toString()) - : null - ); - - const { data: workspaceLabels } = useSWR( - workspaceSlug && displayFilters?.group_by === "labels" - ? WORKSPACE_LABELS(workspaceSlug.toString()) - : null, - workspaceSlug && displayFilters?.group_by === "labels" - ? () => issuesService.getWorkspaceLabels(workspaceSlug.toString()) - : null - ); - - const { data: members } = useSWR( - workspaceSlug && - projectId && - (displayFilters?.group_by === "created_by" || displayFilters?.group_by === "assignees") - ? PROJECT_MEMBERS(projectId.toString()) - : null, - workspaceSlug && - projectId && - (displayFilters?.group_by === "created_by" || displayFilters?.group_by === "assignees") - ? () => projectService.projectMembers(workspaceSlug.toString(), projectId.toString()) - : null - ); - - const { projects } = useProjects(); - - const getGroupTitle = () => { - let title = addSpaceIfCamelCase(groupTitle); - - switch (displayFilters?.group_by) { - case "state": - title = addSpaceIfCamelCase(currentState?.name ?? ""); - break; - case "labels": - title = - [...(issueLabels ?? []), ...(workspaceLabels ?? [])]?.find( - (label) => label.id === groupTitle - )?.name ?? "None"; - break; - case "project": - title = projects?.find((p) => p.id === groupTitle)?.name ?? "None"; - break; - case "assignees": - case "created_by": - const member = members?.find((member) => member.member.id === groupTitle)?.member; - title = member ? member.display_name : "None"; - - break; - } - - return title; - }; - - const getGroupIcon = () => { - let icon; - - switch (displayFilters?.group_by) { - case "state": - icon = currentState && ( - - ); - break; - case "state_detail.group": - icon = ( - - ); - break; - case "priority": - icon = ; - break; - case "project": - const project = projects?.find((p) => p.id === groupTitle); - icon = - project && - (project.emoji !== null - ? renderEmoji(project.emoji) - : project.icon_prop !== null - ? renderEmoji(project.icon_prop) - : null); - break; - case "labels": - const labelColor = - [...(issueLabels ?? []), ...(workspaceLabels ?? [])]?.find( - (label) => label.id === groupTitle - )?.color ?? "#000000"; - icon = ( - - ); - break; - case "assignees": - case "created_by": - const member = members?.find((member) => member.member.id === groupTitle)?.member; - icon = member ? : <>; - - break; - } - - return icon; - }; - - return ( -
-
-
- {getGroupIcon()} -

- {getGroupTitle()} -

- - {groupedIssues?.[groupTitle].length ?? 0} - -
-
- -
- - {!disableAddIssue && !disableUserActions && displayFilters?.group_by !== "created_by" && ( - - )} -
-
- ); -}; diff --git a/web/components/core/views/board-view/index.ts b/web/components/core/views/board-view/index.ts deleted file mode 100644 index a5a6ee497f1..00000000000 --- a/web/components/core/views/board-view/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./all-boards"; -export * from "./board-header"; -export * from "./single-board"; -export * from "./single-issue"; -export * from "./inline-create-issue-form"; diff --git a/web/components/core/views/board-view/inline-create-issue-form.tsx b/web/components/core/views/board-view/inline-create-issue-form.tsx deleted file mode 100644 index 1d6103d19df..00000000000 --- a/web/components/core/views/board-view/inline-create-issue-form.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { useEffect } from "react"; - -// react hook form -import { useFormContext } from "react-hook-form"; - -// components -import { InlineCreateIssueFormWrapper } from "components/core"; - -// hooks -import useProjectDetails from "hooks/use-project-details"; - -// types -import { IIssue } from "types"; - -type Props = { - isOpen: boolean; - handleClose: () => void; - onSuccess?: (data: IIssue) => Promise | void; - prePopulatedData?: Partial; -}; - -const InlineInput = () => { - const { projectDetails } = useProjectDetails(); - - const { register, setFocus } = useFormContext(); - - useEffect(() => { - setFocus("name"); - }, [setFocus]); - - return ( -
-

- {projectDetails?.identifier ?? "..."} -

- -
- ); -}; - -export const BoardInlineCreateIssueForm: React.FC = (props) => ( - <> - - - - {props.isOpen && ( -

- Press {"'"}Enter{"'"} to add another issue -

- )} - -); diff --git a/web/components/core/views/board-view/single-board.tsx b/web/components/core/views/board-view/single-board.tsx deleted file mode 100644 index 1325f8cab36..00000000000 --- a/web/components/core/views/board-view/single-board.tsx +++ /dev/null @@ -1,289 +0,0 @@ -import { useState } from "react"; - -import { useRouter } from "next/router"; - -// react-beautiful-dnd -import StrictModeDroppable from "components/dnd/StrictModeDroppable"; -import { Draggable } from "react-beautiful-dnd"; -// components -import { CreateUpdateDraftIssueModal } from "components/issues"; -import { BoardHeader, SingleBoardIssue, BoardInlineCreateIssueForm } from "components/core"; -// ui -import { CustomMenu } from "components/ui"; -// icons -import { PlusIcon } from "@heroicons/react/24/outline"; -// helpers -import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper"; -// types -import { ICurrentUserResponse, IIssue, IIssueViewProps, IState, UserAuth } from "types"; - -type Props = { - addIssueToGroup: () => void; - currentState?: IState | null; - disableUserActions: boolean; - disableAddIssueOption?: boolean; - dragDisabled: boolean; - groupTitle: string; - handleIssueAction: (issue: IIssue, action: "copy" | "delete" | "edit") => void; - handleDraftIssueAction?: (issue: IIssue, action: "edit" | "delete") => void; - handleTrashBox: (isDragging: boolean) => void; - openIssuesListModal?: (() => void) | null; - handleMyIssueOpen?: (issue: IIssue) => void; - removeIssue: ((bridgeId: string, issueId: string) => void) | null; - user: ICurrentUserResponse | undefined; - userAuth: UserAuth; - viewProps: IIssueViewProps; -}; - -export const SingleBoard: React.FC = (props) => { - const { - addIssueToGroup, - currentState, - groupTitle, - disableUserActions, - disableAddIssueOption = false, - dragDisabled, - handleIssueAction, - handleDraftIssueAction, - handleTrashBox, - openIssuesListModal, - handleMyIssueOpen, - removeIssue, - user, - userAuth, - viewProps, - } = props; - - // collapse/expand - const [isCollapsed, setIsCollapsed] = useState(true); - - const [isInlineCreateIssueFormOpen, setIsInlineCreateIssueFormOpen] = useState(false); - const [isCreateDraftIssueModalOpen, setIsCreateDraftIssueModalOpen] = useState(false); - - const { displayFilters, groupedIssues } = viewProps; - - const router = useRouter(); - const { cycleId, moduleId } = router.query; - - const isMyIssuesPage = router.pathname.split("/")[3] === "my-issues"; - const isProfileIssuesPage = router.pathname.split("/")[2] === "profile"; - const isDraftIssuesPage = router.pathname.split("/")[4] === "draft-issues"; - - const type = cycleId ? "cycle" : moduleId ? "module" : "issue"; - - // Check if it has at least 4 tickets since it is enough to accommodate the Calendar height - const issuesLength = groupedIssues?.[groupTitle].length; - const hasMinimumNumberOfCards = issuesLength ? issuesLength >= 4 : false; - - const isNotAllowed = userAuth.isGuest || userAuth.isViewer || disableUserActions; - - const scrollToBottom = () => { - const boardListElement = document.getElementById(`board-list-${groupTitle}`); - - // timeout is needed because the animation - // takes time to complete & we can scroll only after that - const timeoutId = setTimeout(() => { - if (boardListElement) - boardListElement.scrollBy({ - top: boardListElement.scrollHeight, - left: 0, - behavior: "smooth", - }); - clearTimeout(timeoutId); - }, 10); - }; - - const onCreateClick = () => { - setIsInlineCreateIssueFormOpen(true); - scrollToBottom(); - }; - - const handleAddIssueToGroup = () => { - if (isDraftIssuesPage) setIsCreateDraftIssueModalOpen(true); - else if (isMyIssuesPage || isProfileIssuesPage) addIssueToGroup(); - else onCreateClick(); - }; - - return ( -
- setIsCreateDraftIssueModalOpen(false)} - prePopulateData={{ - ...(cycleId && { cycle: cycleId.toString() }), - ...(moduleId && { module: moduleId.toString() }), - [displayFilters?.group_by! === "labels" ? "labels_list" : displayFilters?.group_by!]: - displayFilters?.group_by === "labels" ? [groupTitle] : groupTitle, - }} - /> - - - {isCollapsed && ( - - {(provided, snapshot) => ( -
- {displayFilters?.order_by !== "sort_order" && ( - <> -
-
- This board is ordered by{" "} - {replaceUnderscoreIfSnakeCase( - displayFilters?.order_by - ? displayFilters?.order_by[0] === "-" - ? displayFilters?.order_by.slice(1) - : displayFilters?.order_by - : "created_at" - )} -
- - )} -
- {groupedIssues?.[groupTitle].map((issue, index) => ( - - {(provided, snapshot) => ( - handleIssueAction(issue, "edit")} - makeIssueCopy={() => handleIssueAction(issue, "copy")} - handleDeleteIssue={() => handleIssueAction(issue, "delete")} - handleDraftIssueEdit={ - handleDraftIssueAction - ? () => handleDraftIssueAction(issue, "edit") - : undefined - } - handleDraftIssueDelete={() => - handleDraftIssueAction - ? handleDraftIssueAction(issue, "delete") - : undefined - } - handleTrashBox={handleTrashBox} - handleMyIssueOpen={handleMyIssueOpen} - removeIssue={() => { - if (removeIssue && issue.bridge_id) - removeIssue(issue.bridge_id, issue.id); - }} - disableUserActions={disableUserActions} - user={user} - userAuth={userAuth} - viewProps={viewProps} - /> - )} - - ))} - - <>{provided.placeholder} - - - setIsInlineCreateIssueFormOpen(false)} - onSuccess={() => scrollToBottom()} - prePopulatedData={{ - ...(cycleId && { cycle: cycleId.toString() }), - ...(moduleId && { module: moduleId.toString() }), - [displayFilters?.group_by! === "labels" - ? "labels_list" - : displayFilters?.group_by!]: - displayFilters?.group_by === "labels" ? [groupTitle] : groupTitle, - }} - /> -
- {displayFilters?.group_by !== "created_by" && ( -
- {type === "issue" - ? !disableAddIssueOption && - !isDraftIssuesPage && ( - - ) - : !disableUserActions && - !isDraftIssuesPage && ( - - - Add Issue -
- } - noBorder - > - { - if (isDraftIssuesPage) setIsCreateDraftIssueModalOpen(true); - else if (isMyIssuesPage || isProfileIssuesPage) addIssueToGroup(); - else onCreateClick(); - }} - > - Create new - - {openIssuesListModal && ( - - Add an existing issue - - )} - - )} -
- )} -
- )} -
- )} -
- ); -}; diff --git a/web/components/core/views/board-view/single-issue.tsx b/web/components/core/views/board-view/single-issue.tsx deleted file mode 100644 index 1a213bccc2a..00000000000 --- a/web/components/core/views/board-view/single-issue.tsx +++ /dev/null @@ -1,547 +0,0 @@ -import React, { useCallback, useEffect, useRef, useState } from "react"; - -import { useRouter } from "next/router"; - -import { mutate } from "swr"; - -// react-beautiful-dnd -import { - DraggableProvided, - DraggableStateSnapshot, - DraggingStyle, - NotDraggingStyle, -} from "react-beautiful-dnd"; -// services -import issuesService from "services/issues.service"; -import trackEventServices from "services/track-event.service"; -// hooks -import useToast from "hooks/use-toast"; -import useOutsideClickDetector from "hooks/use-outside-click-detector"; -// components -import { ViewDueDateSelect, ViewEstimateSelect, ViewStartDateSelect } from "components/issues"; -import { MembersSelect, LabelSelect, PrioritySelect } from "components/project"; -import { StateSelect } from "components/states"; -// ui -import { ContextMenu, CustomMenu, Tooltip } from "components/ui"; -// icons -import { - ClipboardDocumentCheckIcon, - LinkIcon, - PencilIcon, - TrashIcon, - XMarkIcon, - ArrowTopRightOnSquareIcon, - PaperClipIcon, - EllipsisHorizontalIcon, -} from "@heroicons/react/24/outline"; -import { LayerDiagonalIcon } from "components/icons"; -// helpers -import { handleIssuesMutation } from "constants/issue"; -import { copyTextToClipboard } from "helpers/string.helper"; -// types -import { - ICurrentUserResponse, - IIssue, - IIssueViewProps, - IState, - ISubIssueResponse, - TIssuePriorities, - UserAuth, -} from "types"; -// fetch-keys -import { CYCLE_DETAILS, MODULE_DETAILS, SUB_ISSUES } from "constants/fetch-keys"; - -type Props = { - type?: string; - provided: DraggableProvided; - snapshot: DraggableStateSnapshot; - issue: IIssue; - projectId: string; - groupTitle?: string; - index: number; - editIssue: () => void; - makeIssueCopy: () => void; - handleMyIssueOpen?: (issue: IIssue) => void; - removeIssue?: (() => void) | null; - handleDeleteIssue: (issue: IIssue) => void; - handleDraftIssueEdit?: () => void; - handleDraftIssueDelete?: () => void; - handleTrashBox: (isDragging: boolean) => void; - disableUserActions: boolean; - user: ICurrentUserResponse | undefined; - userAuth: UserAuth; - viewProps: IIssueViewProps; -}; - -export const SingleBoardIssue: React.FC = ({ - type, - provided, - snapshot, - issue, - projectId, - index, - editIssue, - makeIssueCopy, - handleMyIssueOpen, - removeIssue, - groupTitle, - handleDeleteIssue, - handleDraftIssueEdit, - handleDraftIssueDelete, - handleTrashBox, - disableUserActions, - user, - userAuth, - viewProps, -}) => { - // context menu - const [contextMenu, setContextMenu] = useState(false); - const [contextMenuPosition, setContextMenuPosition] = useState(null); - - const [isMenuActive, setIsMenuActive] = useState(false); - const [isDropdownActive, setIsDropdownActive] = useState(false); - - const actionSectionRef = useRef(null); - - const { displayFilters, properties, mutateIssues } = viewProps; - - const router = useRouter(); - const { workspaceSlug, cycleId, moduleId } = router.query; - - const isDraftIssue = router.pathname.includes("draft-issues"); - - const { setToastAlert } = useToast(); - - const partialUpdateIssue = useCallback( - (formData: Partial, issue: IIssue) => { - if (!workspaceSlug || !issue) return; - - if (issue.parent) { - mutate( - SUB_ISSUES(issue.parent.toString()), - (prevData) => { - if (!prevData) return prevData; - - return { - ...prevData, - sub_issues: (prevData.sub_issues ?? []).map((i) => { - if (i.id === issue.id) { - return { - ...i, - ...formData, - }; - } - return i; - }), - }; - }, - false - ); - } else { - mutateIssues( - (prevData: any) => - handleIssuesMutation( - formData, - groupTitle ?? "", - displayFilters?.group_by ?? null, - index, - displayFilters?.order_by ?? "-created_at", - prevData - ), - false - ); - } - - issuesService - .patchIssue(workspaceSlug as string, issue.project, issue.id, formData, user) - .then(() => { - mutateIssues(); - - if (cycleId) mutate(CYCLE_DETAILS(cycleId as string)); - if (moduleId) mutate(MODULE_DETAILS(moduleId as string)); - }); - }, - [displayFilters, workspaceSlug, cycleId, moduleId, groupTitle, index, mutateIssues, user] - ); - - const getStyle = ( - style: DraggingStyle | NotDraggingStyle | undefined, - snapshot: DraggableStateSnapshot - ) => { - if (displayFilters?.order_by === "sort_order") return style; - if (!snapshot.isDragging) return {}; - if (!snapshot.isDropAnimating) return style; - - return { - ...style, - transitionDuration: `0.001s`, - }; - }; - - const handleCopyText = () => { - const originURL = - typeof window !== "undefined" && window.location.origin ? window.location.origin : ""; - copyTextToClipboard( - `${originURL}/${workspaceSlug}/projects/${projectId}/issues/${issue.id}` - ).then(() => { - setToastAlert({ - type: "success", - title: "Link Copied!", - message: "Issue link copied to clipboard.", - }); - setIsMenuActive(false); - }); - }; - - const handleStateChange = (data: string, states: IState[] | undefined) => { - const oldState = states?.find((s) => s.id === issue.state); - const newState = states?.find((s) => s.id === data); - - partialUpdateIssue( - { - state: data, - state_detail: newState, - }, - issue - ); - trackEventServices.trackIssuePartialPropertyUpdateEvent( - { - workspaceSlug, - workspaceId: issue.workspace, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - "ISSUE_PROPERTY_UPDATE_STATE", - user - ); - if (oldState?.group !== "completed" && newState?.group !== "completed") { - trackEventServices.trackIssueMarkedAsDoneEvent( - { - workspaceSlug: issue.workspace_detail.slug, - workspaceId: issue.workspace_detail.id, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - user - ); - } - }; - - const handleAssigneeChange = (data: any) => { - const newData = issue.assignees ?? []; - - if (newData.includes(data)) newData.splice(newData.indexOf(data), 1); - else newData.push(data); - - partialUpdateIssue({ assignees_list: data }, issue); - - trackEventServices.trackIssuePartialPropertyUpdateEvent( - { - workspaceSlug, - workspaceId: issue.workspace, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - "ISSUE_PROPERTY_UPDATE_ASSIGNEE", - user - ); - }; - - const handleLabelChange = (data: any) => { - partialUpdateIssue({ labels_list: data }, issue); - }; - - const handlePriorityChange = (data: TIssuePriorities) => { - partialUpdateIssue({ priority: data }, issue); - trackEventServices.trackIssuePartialPropertyUpdateEvent( - { - workspaceSlug, - workspaceId: issue.workspace, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - "ISSUE_PROPERTY_UPDATE_PRIORITY", - user - ); - }; - - useEffect(() => { - if (snapshot.isDragging) handleTrashBox(snapshot.isDragging); - }, [snapshot, handleTrashBox]); - - useOutsideClickDetector(actionSectionRef, () => setIsMenuActive(false)); - - const openPeekOverview = () => { - const { query } = router; - - if (handleMyIssueOpen) handleMyIssueOpen(issue); - - router.push({ - pathname: router.pathname, - query: { ...query, peekIssue: issue.id }, - }); - }; - - const isNotAllowed = userAuth.isGuest || userAuth.isViewer || disableUserActions; - - return ( - <> - - {!isNotAllowed && ( - <> - { - if (isDraftIssue && handleDraftIssueEdit) handleDraftIssueEdit(); - else editIssue(); - }} - > - Edit issue - - {!isDraftIssue && ( - - Make a copy... - - )} - { - if (isDraftIssue && handleDraftIssueDelete) handleDraftIssueDelete(); - else handleDeleteIssue(issue); - }} - > - Delete issue - - - )} - {!isDraftIssue && ( - - Copy issue link - - )} - {!isDraftIssue && ( - - - Open issue in new tab - - - )} - -
{ - e.preventDefault(); - setContextMenu(true); - setContextMenuPosition(e); - }} - > -
- {!isNotAllowed && ( - - } - > - { - if (isDraftIssue && handleDraftIssueEdit) handleDraftIssueEdit(); - else editIssue(); - }} - > -
- - Edit issue -
-
- {type !== "issue" && removeIssue && !isDraftIssue && ( - -
- - Remove from {type} -
-
- )} - { - if (isDraftIssue && handleDraftIssueDelete) handleDraftIssueDelete(); - else handleDeleteIssue(issue); - }} - > -
- - Delete issue -
-
- {!isDraftIssue && ( - -
- - Copy issue Link -
-
- )} - - )} -
- )} - -
- {properties.key && ( -
- {issue.project_detail.identifier}-{issue.sequence_id} -
- )} - -
- -
- {properties.priority && ( - - )} - {properties.state && ( - - )} - {properties.start_date && issue.start_date && ( - setIsDropdownActive(true)} - handleOnClose={() => setIsDropdownActive(false)} - user={user} - isNotAllowed={isNotAllowed} - /> - )} - {properties.due_date && issue.target_date && ( - setIsDropdownActive(true)} - handleOnClose={() => setIsDropdownActive(false)} - user={user} - isNotAllowed={isNotAllowed} - /> - )} - {properties.labels && issue.labels.length > 0 && ( - - )} - {properties.assignee && ( - - )} - {properties.estimate && issue.estimate_point !== null && ( - - )} - {properties.sub_issue_count && issue.sub_issues_count > 0 && ( -
- -
- - {issue.sub_issues_count} -
-
-
- )} - {properties.link && issue.link_count > 0 && ( -
- -
- - {issue.link_count} -
-
-
- )} - {properties.attachment_count && issue.attachment_count > 0 && ( -
- -
- - {issue.attachment_count} -
-
-
- )} -
-
- - - ); -}; diff --git a/web/components/core/views/calendar-view/calendar-header.tsx b/web/components/core/views/calendar-view/calendar-header.tsx deleted file mode 100644 index fd69ed44315..00000000000 --- a/web/components/core/views/calendar-view/calendar-header.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import React from "react"; - -// headless ui -import { Popover, Transition } from "@headlessui/react"; -// ui -import { CustomMenu, ToggleSwitch } from "components/ui"; -// icons -import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/24/outline"; -// helpers -import { - formatDate, - isSameMonth, - isSameYear, - updateDateWithMonth, - updateDateWithYear, -} from "helpers/calendar.helper"; -// constants -import { MONTHS_LIST, YEARS_LIST } from "constants/calendar"; - -type Props = { - currentDate: Date; - setCurrentDate: React.Dispatch>; - showWeekEnds: boolean; - setShowWeekEnds: React.Dispatch>; -}; - -export const CalendarHeader: React.FC = ({ - currentDate, - setCurrentDate, - showWeekEnds, - setShowWeekEnds, -}) => ( -
-
- - {({ open }) => ( - <> - -
- {formatDate(currentDate, "Month")}{" "} - {formatDate(currentDate, "yyyy")} -
-
- - - -
- {YEARS_LIST.map((year) => ( - - ))} -
-
- {MONTHS_LIST.map((month) => ( - - ))} -
-
-
- - )} -
- -
- - -
-
- -
- - - - Options -
- } - > -
-

Show weekends

- setShowWeekEnds(!showWeekEnds)} /> -
- -
- -); - -export default CalendarHeader; diff --git a/web/components/core/views/calendar-view/calendar.tsx b/web/components/core/views/calendar-view/calendar.tsx deleted file mode 100644 index 7758f64cdbb..00000000000 --- a/web/components/core/views/calendar-view/calendar.tsx +++ /dev/null @@ -1,217 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { useRouter } from "next/router"; -import { mutate } from "swr"; -import { DragDropContext, DropResult } from "react-beautiful-dnd"; -// services -import issuesService from "services/issues.service"; -// hooks -import useCalendarIssuesView from "hooks/use-calendar-issues-view"; -// components -import { SingleCalendarDate, CalendarHeader } from "components/core"; -import { IssuePeekOverview } from "components/issues"; -// ui -import { Spinner } from "components/ui"; -// helpers -import { renderDateFormat } from "helpers/date-time.helper"; -import { - startOfWeek, - lastDayOfWeek, - eachDayOfInterval, - weekDayInterval, - formatDate, -} from "helpers/calendar.helper"; -// types -import { ICalendarRange, ICurrentUserResponse, IIssue, UserAuth } from "types"; -// fetch-keys -import { - CYCLE_ISSUES_WITH_PARAMS, - MODULE_ISSUES_WITH_PARAMS, - PROJECT_ISSUES_LIST_WITH_PARAMS, - VIEW_ISSUES, -} from "constants/fetch-keys"; - -type Props = { - handleIssueAction: (issue: IIssue, action: "copy" | "delete" | "edit") => void; - addIssueToDate: (date: string) => void; - disableUserActions: boolean; - user: ICurrentUserResponse | undefined; - userAuth: UserAuth; -}; - -export const CalendarView: React.FC = ({ - handleIssueAction, - addIssueToDate, - disableUserActions, - user, - userAuth, -}) => { - const [showWeekEnds, setShowWeekEnds] = useState(false); - - const { calendarIssues, mutateIssues, params, activeMonthDate, setActiveMonthDate } = - useCalendarIssuesView(); - - const [calendarDates, setCalendarDates] = useState({ - startDate: startOfWeek(activeMonthDate), - endDate: lastDayOfWeek(activeMonthDate), - }); - - const router = useRouter(); - const { workspaceSlug, projectId, cycleId, moduleId, viewId } = router.query; - - const currentViewDays = showWeekEnds - ? eachDayOfInterval({ - start: calendarDates.startDate, - end: calendarDates.endDate, - }) - : weekDayInterval({ - start: calendarDates.startDate, - end: calendarDates.endDate, - }); - - const currentViewDaysData = currentViewDays.map((date: Date) => { - const filterIssue = - calendarIssues.length > 0 - ? calendarIssues.filter( - (issue) => - issue.target_date && renderDateFormat(issue.target_date) === renderDateFormat(date) - ) - : []; - return { - date: renderDateFormat(date), - issues: filterIssue, - }; - }); - - const weeks = ((date: Date[]) => { - const weeks = []; - if (showWeekEnds) { - for (let day = 0; day <= 6; day++) { - weeks.push(date[day]); - } - } else { - for (let day = 0; day <= 4; day++) { - weeks.push(date[day]); - } - } - - return weeks; - })(currentViewDays); - - const onDragEnd = (result: DropResult) => { - const { source, destination, draggableId } = result; - - if (!destination || !workspaceSlug || !projectId) return; - - if (source.droppableId === destination.droppableId) return; - - const fetchKey = cycleId - ? CYCLE_ISSUES_WITH_PARAMS(cycleId.toString(), params) - : moduleId - ? MODULE_ISSUES_WITH_PARAMS(moduleId.toString(), params) - : viewId - ? VIEW_ISSUES(viewId.toString(), params) - : PROJECT_ISSUES_LIST_WITH_PARAMS(projectId.toString(), params); - - mutate( - fetchKey, - (prevData) => - (prevData ?? []).map((p) => { - if (p.id === draggableId) - return { - ...p, - target_date: destination.droppableId, - }; - - return p; - }), - false - ); - - issuesService - .patchIssue( - workspaceSlug as string, - projectId as string, - draggableId, - { - target_date: destination?.droppableId, - }, - user - ) - .then(() => mutate(fetchKey)); - }; - - useEffect(() => { - setCalendarDates({ - startDate: startOfWeek(activeMonthDate), - endDate: lastDayOfWeek(activeMonthDate), - }); - }, [activeMonthDate]); - - const isNotAllowed = userAuth.isGuest || userAuth.isViewer || disableUserActions; - - return ( - <> - mutateIssues()} - projectId={projectId?.toString() ?? ""} - workspaceSlug={workspaceSlug?.toString() ?? ""} - readOnly={disableUserActions} - /> - {calendarIssues ? ( -
- -
- - -
- {weeks.map((date, index) => ( -
- {formatDate(date, "eee").substring(0, 3)} -
- ))} -
- -
- {currentViewDaysData.map((date, index) => ( - - ))} -
-
-
-
- ) : ( -
- -
- )} - - ); -}; diff --git a/web/components/core/views/calendar-view/index.ts b/web/components/core/views/calendar-view/index.ts deleted file mode 100644 index 75d8a3a1eff..00000000000 --- a/web/components/core/views/calendar-view/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./calendar-header"; -export * from "./calendar"; -export * from "./single-date"; -export * from "./single-issue"; -export * from "./inline-create-issue-form"; diff --git a/web/components/core/views/calendar-view/inline-create-issue-form.tsx b/web/components/core/views/calendar-view/inline-create-issue-form.tsx deleted file mode 100644 index 51b6c518b42..00000000000 --- a/web/components/core/views/calendar-view/inline-create-issue-form.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { useEffect, useRef, useState } from "react"; - -// next -import { useRouter } from "next/router"; - -// react hook form -import { useFormContext } from "react-hook-form"; - -import { InlineCreateIssueFormWrapper } from "components/core"; - -// hooks -import useProjectDetails from "hooks/use-project-details"; - -// types -import { IIssue } from "types"; - -type Props = { - isOpen: boolean; - handleClose: () => void; - onSuccess?: (data: IIssue) => Promise | void; - prePopulatedData?: Partial; - dependencies: any[]; -}; - -const useCheckIfThereIsSpaceOnRight = (ref: React.RefObject, deps: any[]) => { - const [isThereSpaceOnRight, setIsThereSpaceOnRight] = useState(true); - - const router = useRouter(); - const { moduleId, cycleId, viewId } = router.query; - - const container = document.getElementById(`calendar-view-${cycleId ?? moduleId ?? viewId}`); - - useEffect(() => { - if (!ref.current) return; - - const { right } = ref.current.getBoundingClientRect(); - - const width = right; - - const innerWidth = container?.getBoundingClientRect().width ?? window.innerWidth; - - if (width > innerWidth) setIsThereSpaceOnRight(false); - else setIsThereSpaceOnRight(true); - }, [ref, deps, container]); - - return isThereSpaceOnRight; -}; - -const InlineInput = () => { - const { projectDetails } = useProjectDetails(); - - const { register, setFocus } = useFormContext(); - - useEffect(() => { - setFocus("name"); - }, [setFocus]); - - return ( - <> -

- {projectDetails?.identifier ?? "..."} -

- - - ); -}; - -export const CalendarInlineCreateIssueForm: React.FC = (props) => { - const { isOpen, dependencies } = props; - - const ref = useRef(null); - - const isSpaceOnRight = useCheckIfThereIsSpaceOnRight(ref, dependencies); - - return ( - <> -
- - - -
- {/* Added to make any other element as outside click. This will make input also to be outside. */} - {isOpen &&
} - - ); -}; diff --git a/web/components/core/views/calendar-view/single-date.tsx b/web/components/core/views/calendar-view/single-date.tsx deleted file mode 100644 index a67ca762b11..00000000000 --- a/web/components/core/views/calendar-view/single-date.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import React, { useState } from "react"; - -// next -import { useRouter } from "next/router"; - -// react-beautiful-dnd -import { Draggable } from "react-beautiful-dnd"; -// component -import StrictModeDroppable from "components/dnd/StrictModeDroppable"; -import { SingleCalendarIssue } from "./single-issue"; -import { CalendarInlineCreateIssueForm } from "./inline-create-issue-form"; -// icons -import { PlusSmallIcon } from "@heroicons/react/24/outline"; -// helper -import { formatDate } from "helpers/calendar.helper"; -// types -import { ICurrentUserResponse, IIssue } from "types"; - -type Props = { - handleIssueAction: (issue: IIssue, action: "copy" | "delete" | "edit") => void; - index: number; - date: { - date: string; - issues: IIssue[]; - }; - addIssueToDate: (date: string) => void; - showWeekEnds: boolean; - user: ICurrentUserResponse | undefined; - isNotAllowed: boolean; -}; - -export const SingleCalendarDate: React.FC = (props) => { - const { handleIssueAction, date, index, showWeekEnds, user, isNotAllowed } = props; - - const router = useRouter(); - const { cycleId, moduleId } = router.query; - - const [showAllIssues, setShowAllIssues] = useState(false); - const [isCreateIssueFormOpen, setIsCreateIssueFormOpen] = useState(false); - - const [formPosition, setFormPosition] = useState({ x: 0, y: 0 }); - - const totalIssues = date.issues.length; - - return ( - - {(provided) => ( -
- <> - {formatDate(new Date(date.date), "d")} - {totalIssues > 0 && - date.issues.slice(0, showAllIssues ? totalIssues : 4).map((issue: IIssue, index) => ( - - {(provided, snapshot) => ( - handleIssueAction(issue, "edit")} - handleDeleteIssue={() => handleIssueAction(issue, "delete")} - user={user} - isNotAllowed={isNotAllowed} - /> - )} - - ))} - - setIsCreateIssueFormOpen(false)} - prePopulatedData={{ - target_date: date.date, - ...(cycleId && { cycle: cycleId.toString() }), - ...(moduleId && { module: moduleId.toString() }), - }} - /> - - {totalIssues > 4 && ( - - )} - -
- -
- - {provided.placeholder} - -
- )} -
- ); -}; diff --git a/web/components/core/views/calendar-view/single-issue.tsx b/web/components/core/views/calendar-view/single-issue.tsx deleted file mode 100644 index e0e9aa2a52a..00000000000 --- a/web/components/core/views/calendar-view/single-issue.tsx +++ /dev/null @@ -1,403 +0,0 @@ -import React, { useCallback } from "react"; - -import { useRouter } from "next/router"; - -import { mutate } from "swr"; - -// react-beautiful-dnd -import { DraggableProvided, DraggableStateSnapshot } from "react-beautiful-dnd"; -// services -import issuesService from "services/issues.service"; -import trackEventServices from "services/track-event.service"; -// hooks -import useCalendarIssuesView from "hooks/use-calendar-issues-view"; -import useIssuesProperties from "hooks/use-issue-properties"; -import useToast from "hooks/use-toast"; -// components -import { CustomMenu, Tooltip } from "components/ui"; -import { ViewDueDateSelect, ViewEstimateSelect, ViewStartDateSelect } from "components/issues"; -import { LabelSelect, MembersSelect, PrioritySelect } from "components/project"; -import { StateSelect } from "components/states"; -// icons -import { LinkIcon, PaperClipIcon, PencilIcon, TrashIcon } from "@heroicons/react/24/outline"; -import { LayerDiagonalIcon } from "components/icons"; -// helper -import { copyTextToClipboard, truncateText } from "helpers/string.helper"; -// type -import { ICurrentUserResponse, IIssue, IState, ISubIssueResponse, TIssuePriorities } from "types"; -// fetch-keys -import { - CYCLE_ISSUES_WITH_PARAMS, - MODULE_ISSUES_WITH_PARAMS, - PROJECT_ISSUES_LIST_WITH_PARAMS, - SUB_ISSUES, - VIEW_ISSUES, -} from "constants/fetch-keys"; - -type Props = { - handleEditIssue: (issue: IIssue) => void; - handleDeleteIssue: (issue: IIssue) => void; - index: number; - provided: DraggableProvided; - snapshot: DraggableStateSnapshot; - issue: IIssue; - projectId: string; - user: ICurrentUserResponse | undefined; - isNotAllowed: boolean; -}; - -export const SingleCalendarIssue: React.FC = ({ - handleEditIssue, - handleDeleteIssue, - index, - provided, - snapshot, - issue, - projectId, - user, - isNotAllowed, -}) => { - const router = useRouter(); - const { workspaceSlug, cycleId, moduleId, viewId } = router.query; - - const { setToastAlert } = useToast(); - - const { params } = useCalendarIssuesView(); - - const [properties] = useIssuesProperties(workspaceSlug as string, projectId as string); - - const partialUpdateIssue = useCallback( - (formData: Partial, issue: IIssue) => { - if (!workspaceSlug || !projectId) return; - - const fetchKey = cycleId - ? CYCLE_ISSUES_WITH_PARAMS(cycleId.toString(), params) - : moduleId - ? MODULE_ISSUES_WITH_PARAMS(moduleId.toString(), params) - : viewId - ? VIEW_ISSUES(viewId.toString(), params) - : PROJECT_ISSUES_LIST_WITH_PARAMS(projectId.toString(), params); - - if (issue.parent) { - mutate( - SUB_ISSUES(issue.parent.toString()), - (prevData) => { - if (!prevData) return prevData; - - return { - ...prevData, - sub_issues: (prevData.sub_issues ?? []).map((i) => { - if (i.id === issue.id) { - return { - ...i, - ...formData, - }; - } - return i; - }), - }; - }, - false - ); - } else { - mutate( - fetchKey, - (prevData) => - (prevData ?? []).map((p) => { - if (p.id === issue.id) { - return { - ...p, - ...formData, - assignees: formData?.assignees_list ?? p.assignees, - }; - } - - return p; - }), - false - ); - } - - issuesService - .patchIssue( - workspaceSlug as string, - projectId as string, - issue.id as string, - formData, - user - ) - .then(() => { - mutate(fetchKey); - }) - .catch((error) => { - console.log(error); - }); - }, - [workspaceSlug, projectId, cycleId, moduleId, viewId, params, user] - ); - - const handleCopyText = () => { - const originURL = - typeof window !== "undefined" && window.location.origin ? window.location.origin : ""; - copyTextToClipboard( - `${originURL}/${workspaceSlug}/projects/${projectId}/issues/${issue.id}` - ).then(() => { - setToastAlert({ - type: "success", - title: "Link Copied!", - message: "Issue link copied to clipboard.", - }); - }); - }; - - const handleStateChange = (data: string, states: IState[] | undefined) => { - const oldState = states?.find((s) => s.id === issue.state); - const newState = states?.find((s) => s.id === data); - - partialUpdateIssue( - { - state: data, - state_detail: newState, - }, - issue - ); - trackEventServices.trackIssuePartialPropertyUpdateEvent( - { - workspaceSlug, - workspaceId: issue.workspace, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - "ISSUE_PROPERTY_UPDATE_STATE", - user - ); - if (oldState?.group !== "completed" && newState?.group !== "completed") { - trackEventServices.trackIssueMarkedAsDoneEvent( - { - workspaceSlug: issue.workspace_detail.slug, - workspaceId: issue.workspace_detail.id, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - user - ); - } - }; - - const handleAssigneeChange = (data: any) => { - const newData = issue.assignees ?? []; - - if (newData.includes(data)) newData.splice(newData.indexOf(data), 1); - else newData.push(data); - - partialUpdateIssue({ assignees_list: data }, issue); - - trackEventServices.trackIssuePartialPropertyUpdateEvent( - { - workspaceSlug, - workspaceId: issue.workspace, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - "ISSUE_PROPERTY_UPDATE_ASSIGNEE", - user - ); - }; - - const handleLabelChange = (data: any) => { - partialUpdateIssue({ labels_list: data }, issue); - }; - - const handlePriorityChange = (data: TIssuePriorities) => { - partialUpdateIssue({ priority: data }, issue); - trackEventServices.trackIssuePartialPropertyUpdateEvent( - { - workspaceSlug, - workspaceId: issue.workspace, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - "ISSUE_PROPERTY_UPDATE_PRIORITY", - user - ); - }; - - const displayProperties = properties - ? Object.values(properties).some((value) => value === true) - : false; - - const openPeekOverview = () => { - const { query } = router; - - router.push({ - pathname: router.pathname, - query: { ...query, peekIssue: issue.id }, - }); - }; - - return ( -
-
- {!isNotAllowed && ( -
- - handleEditIssue(issue)}> -
- - Edit issue -
-
- handleDeleteIssue(issue)}> -
- - Delete issue -
-
- -
- - Copy issue Link -
-
-
-
- )} - - - - {displayProperties && ( -
- {properties.priority && ( - - )} - {properties.state && ( - - )} - {properties.start_date && issue.start_date && ( - - )} - {properties.due_date && issue.target_date && ( - - )} - {properties.labels && issue.labels.length > 0 && ( - - )} - {properties.assignee && ( - - )} - {properties.estimate && issue.estimate_point !== null && ( - - )} - {properties.sub_issue_count && issue.sub_issues_count > 0 && ( -
- -
- - {issue.sub_issues_count} -
-
-
- )} - {properties.link && issue.link_count > 0 && ( -
- -
- - {issue.link_count} -
-
-
- )} - {properties.attachment_count && issue.attachment_count > 0 && ( -
- -
- - {issue.attachment_count} -
-
-
- )} -
- )} -
-
- ); -}; diff --git a/web/components/core/views/list-view/index.ts b/web/components/core/views/list-view/index.ts deleted file mode 100644 index 4d59be1654d..00000000000 --- a/web/components/core/views/list-view/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./all-lists"; -export * from "./single-issue"; -export * from "./single-list"; -export * from "./inline-create-issue-form"; diff --git a/web/components/core/views/list-view/inline-create-issue-form.tsx b/web/components/core/views/list-view/inline-create-issue-form.tsx deleted file mode 100644 index b61420fc82a..00000000000 --- a/web/components/core/views/list-view/inline-create-issue-form.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { useEffect } from "react"; -// react hook form -import { useFormContext } from "react-hook-form"; - -// hooks -import useProjectDetails from "hooks/use-project-details"; - -// components -import { InlineCreateIssueFormWrapper } from "../inline-issue-create-wrapper"; - -// types -import { IIssue } from "types"; - -type Props = { - isOpen: boolean; - handleClose: () => void; - onSuccess?: (data: IIssue) => Promise | void; - prePopulatedData?: Partial; -}; - -const InlineInput = () => { - const { projectDetails } = useProjectDetails(); - - const { register, setFocus } = useFormContext(); - - useEffect(() => { - setFocus("name"); - }, [setFocus]); - - return ( - <> -

- {projectDetails?.identifier ?? "..."} -

- - - ); -}; - -export const ListInlineCreateIssueForm: React.FC = (props) => ( - <> - - - - {props.isOpen && ( -

- Press {"'"}Enter{"'"} to add another issue -

- )} - -); diff --git a/web/components/core/views/list-view/single-issue.tsx b/web/components/core/views/list-view/single-issue.tsx deleted file mode 100644 index 7fa54b852ee..00000000000 --- a/web/components/core/views/list-view/single-issue.tsx +++ /dev/null @@ -1,511 +0,0 @@ -import React, { useCallback, useState } from "react"; - -import { useRouter } from "next/router"; - -import { mutate } from "swr"; - -// services -import issuesService from "services/issues.service"; -import trackEventServices from "services/track-event.service"; -// hooks -import useToast from "hooks/use-toast"; -// components -import { ViewDueDateSelect, ViewEstimateSelect, ViewStartDateSelect } from "components/issues"; -import { LabelSelect, MembersSelect, PrioritySelect } from "components/project"; -import { StateSelect } from "components/states"; -// ui -import { Tooltip, CustomMenu, ContextMenu } from "components/ui"; -// icons -import { - ClipboardDocumentCheckIcon, - LinkIcon, - PencilIcon, - TrashIcon, - XMarkIcon, - ArrowTopRightOnSquareIcon, - PaperClipIcon, -} from "@heroicons/react/24/outline"; -import { LayerDiagonalIcon } from "components/icons"; -// helpers -import { copyTextToClipboard } from "helpers/string.helper"; -import { handleIssuesMutation } from "constants/issue"; -// types -import { - ICurrentUserResponse, - IIssue, - IIssueViewProps, - IState, - ISubIssueResponse, - IUserProfileProjectSegregation, - TIssuePriorities, - UserAuth, -} from "types"; -// fetch-keys -import { - CYCLE_DETAILS, - MODULE_DETAILS, - SUB_ISSUES, - USER_PROFILE_PROJECT_SEGREGATION, -} from "constants/fetch-keys"; - -type Props = { - type?: string; - issue: IIssue; - projectId: string; - groupTitle?: string; - editIssue: () => void; - index: number; - makeIssueCopy: () => void; - removeIssue?: (() => void) | null; - handleDeleteIssue: (issue: IIssue) => void; - handleDraftIssueSelect?: (issue: IIssue) => void; - handleDraftIssueDelete?: (issue: IIssue) => void; - handleMyIssueOpen?: (issue: IIssue) => void; - disableUserActions: boolean; - user: ICurrentUserResponse | undefined; - userAuth: UserAuth; - viewProps: IIssueViewProps; -}; - -export const SingleListIssue: React.FC = ({ - type, - issue, - projectId, - editIssue, - index, - makeIssueCopy, - removeIssue, - groupTitle, - handleDraftIssueDelete, - handleDeleteIssue, - handleMyIssueOpen, - disableUserActions, - user, - userAuth, - viewProps, - handleDraftIssueSelect, -}) => { - // context menu - const [contextMenu, setContextMenu] = useState(false); - const [contextMenuPosition, setContextMenuPosition] = useState(null); - - const router = useRouter(); - const { workspaceSlug, cycleId, moduleId, userId } = router.query; - const isArchivedIssues = router.pathname.includes("archived-issues"); - const isDraftIssues = router.pathname?.split("/")?.[4] === "draft-issues"; - - const { setToastAlert } = useToast(); - - const { displayFilters, properties, mutateIssues } = viewProps; - - const partialUpdateIssue = useCallback( - (formData: Partial, issue: IIssue) => { - if (!workspaceSlug || !issue) return; - - if (issue.parent) { - mutate( - SUB_ISSUES(issue.parent.toString()), - (prevData) => { - if (!prevData) return prevData; - - return { - ...prevData, - sub_issues: (prevData.sub_issues ?? []).map((i) => { - if (i.id === issue.id) { - return { - ...i, - ...formData, - }; - } - return i; - }), - }; - }, - false - ); - } else { - mutateIssues( - (prevData: any) => - handleIssuesMutation( - formData, - groupTitle ?? "", - displayFilters?.group_by ?? null, - index, - displayFilters?.order_by ?? "-created_at", - prevData - ), - false - ); - } - - issuesService - .patchIssue(workspaceSlug as string, issue.project, issue.id, formData, user) - .then(() => { - mutateIssues(); - - if (userId) - mutate( - USER_PROFILE_PROJECT_SEGREGATION(workspaceSlug.toString(), userId.toString()) - ); - - if (cycleId) mutate(CYCLE_DETAILS(cycleId as string)); - if (moduleId) mutate(MODULE_DETAILS(moduleId as string)); - }); - }, - [ - displayFilters, - workspaceSlug, - cycleId, - moduleId, - userId, - groupTitle, - index, - mutateIssues, - user, - ] - ); - - const handleCopyText = () => { - const originURL = - typeof window !== "undefined" && window.location.origin ? window.location.origin : ""; - copyTextToClipboard( - `${originURL}/${workspaceSlug}/projects/${projectId}/issues/${issue.id}` - ).then(() => { - setToastAlert({ - type: "success", - title: "Link Copied!", - message: "Issue link copied to clipboard.", - }); - }); - }; - - const handleStateChange = (data: string, states: IState[] | undefined) => { - const oldState = states?.find((s) => s.id === issue.state); - const newState = states?.find((s) => s.id === data); - - partialUpdateIssue( - { - state: data, - state_detail: newState, - }, - issue - ); - trackEventServices.trackIssuePartialPropertyUpdateEvent( - { - workspaceSlug, - workspaceId: issue.workspace, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - "ISSUE_PROPERTY_UPDATE_STATE", - user - ); - if (oldState?.group !== "completed" && newState?.group !== "completed") { - trackEventServices.trackIssueMarkedAsDoneEvent( - { - workspaceSlug: issue.workspace_detail.slug, - workspaceId: issue.workspace_detail.id, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - user - ); - } - }; - - const handleAssigneeChange = (data: any) => { - const newData = issue.assignees ?? []; - - if (newData.includes(data)) newData.splice(newData.indexOf(data), 1); - else newData.push(data); - - partialUpdateIssue({ assignees_list: data }, issue); - - trackEventServices.trackIssuePartialPropertyUpdateEvent( - { - workspaceSlug, - workspaceId: issue.workspace, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - "ISSUE_PROPERTY_UPDATE_ASSIGNEE", - user - ); - }; - - const handleLabelChange = (data: any) => { - partialUpdateIssue({ labels_list: data }, issue); - }; - - const handlePriorityChange = (data: TIssuePriorities) => { - partialUpdateIssue({ priority: data }, issue); - trackEventServices.trackIssuePartialPropertyUpdateEvent( - { - workspaceSlug, - workspaceId: issue.workspace, - projectId: issue.project_detail.id, - projectIdentifier: issue.project_detail.identifier, - projectName: issue.project_detail.name, - issueId: issue.id, - }, - "ISSUE_PROPERTY_UPDATE_PRIORITY", - user - ); - }; - - const issuePath = isArchivedIssues - ? `/${workspaceSlug}/projects/${issue.project}/archived-issues/${issue.id}` - : isDraftIssues - ? `#` - : `/${workspaceSlug}/projects/${issue.project}/issues/${issue.id}`; - - const openPeekOverview = (issue: IIssue) => { - const { query } = router; - - if (handleMyIssueOpen) handleMyIssueOpen(issue); - router.push({ - pathname: router.pathname, - query: { ...query, peekIssue: issue.id }, - }); - }; - - const isNotAllowed = - userAuth.isGuest || userAuth.isViewer || disableUserActions || isArchivedIssues; - - return ( - <> - - {!isNotAllowed && ( - <> - { - if (isDraftIssues && handleDraftIssueSelect) handleDraftIssueSelect(issue); - else editIssue(); - }} - > - Edit issue - - {!isDraftIssues && ( - - Make a copy... - - )} - { - if (isDraftIssues && handleDraftIssueDelete) handleDraftIssueDelete(issue); - else handleDeleteIssue(issue); - }} - > - Delete issue - - - )} - {!isDraftIssues && ( - <> - - Copy issue link - - - - Open issue in new tab - - - - )} - - -
{ - e.preventDefault(); - setContextMenu(true); - setContextMenuPosition(e); - }} - > -
-
- {properties.key && ( - - - {issue.project_detail?.identifier}-{issue.sequence_id} - - - )} - - - -
-
- -
- {properties.priority && ( - - )} - {properties.state && ( - - )} - {properties.start_date && issue.start_date && ( - - )} - {properties.due_date && issue.target_date && ( - - )} - {properties.labels && ( - - )} - {properties.assignee && ( - - )} - {properties.estimate && issue.estimate_point !== null && ( - - )} - {properties.sub_issue_count && issue.sub_issues_count > 0 && ( -
- -
- - {issue.sub_issues_count} -
-
-
- )} - {properties.link && issue.link_count > 0 && ( -
- -
- - {issue.link_count} -
-
-
- )} - {properties.attachment_count && issue.attachment_count > 0 && ( -
- -
- - {issue.attachment_count} -
-
-
- )} - {type && !isNotAllowed && ( - - { - if (isDraftIssues && handleDraftIssueSelect) handleDraftIssueSelect(issue); - else editIssue(); - }} - > -
- - Edit issue -
-
- {type !== "issue" && removeIssue && ( - -
- - Remove from {type} -
-
- )} - { - if (isDraftIssues && handleDraftIssueDelete) handleDraftIssueDelete(issue); - else handleDeleteIssue(issue); - }} - > -
- - Delete issue -
-
- {!isDraftIssues && ( - -
- - Copy issue link -
-
- )} -
- )} -
-
- - ); -}; diff --git a/web/components/core/views/list-view/single-list.tsx b/web/components/core/views/list-view/single-list.tsx deleted file mode 100644 index 7bdd7c43885..00000000000 --- a/web/components/core/views/list-view/single-list.tsx +++ /dev/null @@ -1,337 +0,0 @@ -import { useState, FC } from "react"; -import { useRouter } from "next/router"; -import useSWR from "swr"; -import { Disclosure, Transition } from "@headlessui/react"; -// services -import { IssueLabelService } from "services/issue"; -import { ProjectService } from "services/project"; -// hooks -import useProjects from "hooks/use-projects"; -// components -import { CreateUpdateDraftIssueModal } from "components/issues"; -import { SingleListIssue, ListInlineCreateIssueForm } from "components/core"; -// ui -import { Avatar, CustomMenu } from "components/ui"; -// icons -import { PlusIcon } from "@heroicons/react/24/outline"; -import { PriorityIcon, StateGroupIcon } from "components/icons"; -// helpers -import { addSpaceIfCamelCase } from "helpers/string.helper"; -import { renderEmoji } from "helpers/emoji.helper"; -// types -import { IUser, IIssue, IIssueViewProps, IState, TIssuePriorities, TStateGroups, UserAuth } from "types"; -// fetch-keys -import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS, WORKSPACE_LABELS } from "constants/fetch-keys"; -// constants -import { STATE_GROUP_COLORS } from "constants/state"; - -type Props = { - currentState?: IState | null; - groupTitle: string; - addIssueToGroup: () => void; - handleIssueAction: (issue: IIssue, action: "copy" | "delete" | "edit") => void; - handleDraftIssueAction?: (issue: IIssue, action: "edit" | "delete") => void; - openIssuesListModal?: (() => void) | null; - handleMyIssueOpen?: (issue: IIssue) => void; - removeIssue: ((bridgeId: string, issueId: string) => void) | null; - disableUserActions: boolean; - disableAddIssueOption?: boolean; - user: IUser | undefined; - userAuth: UserAuth; - viewProps: IIssueViewProps; -}; - -const issueLabelService = new IssueLabelService(); -const projectService = new ProjectService(); - -export const SingleList: FC = (props) => { - const { - currentState, - groupTitle, - handleIssueAction, - openIssuesListModal, - handleDraftIssueAction, - handleMyIssueOpen, - addIssueToGroup, - removeIssue, - disableUserActions, - disableAddIssueOption = false, - user, - userAuth, - viewProps, - } = props; - - const router = useRouter(); - const { workspaceSlug, projectId, cycleId, moduleId } = router.query; - - const [isCreateIssueFormOpen, setIsCreateIssueFormOpen] = useState(false); - const [isDraftIssuesModalOpen, setIsDraftIssuesModalOpen] = useState(false); - - const isMyIssuesPage = router.pathname.split("/")[3] === "my-issues"; - const isProfileIssuesPage = router.pathname.split("/")[2] === "profile"; - const isDraftIssuesPage = router.pathname.split("/")[4] === "draft-issues"; - - const isArchivedIssues = router.pathname.includes("archived-issues"); - - const type = cycleId ? "cycle" : moduleId ? "module" : "issue"; - - const { displayFilters, groupedIssues } = viewProps; - - const { data: issueLabels } = useSWR( - workspaceSlug && projectId && displayFilters?.group_by === "labels" - ? PROJECT_ISSUE_LABELS(projectId.toString()) - : null, - workspaceSlug && projectId && displayFilters?.group_by === "labels" - ? () => issueLabelService.getProjectIssueLabels(workspaceSlug.toString(), projectId.toString()) - : null - ); - - const { data: workspaceLabels } = useSWR( - workspaceSlug && displayFilters?.group_by === "labels" ? WORKSPACE_LABELS(workspaceSlug.toString()) : null, - workspaceSlug && displayFilters?.group_by === "labels" - ? () => issueLabelService.getWorkspaceIssueLabels(workspaceSlug.toString()) - : null - ); - - const { data: members } = useSWR( - workspaceSlug && - projectId && - (displayFilters?.group_by === "created_by" || displayFilters?.group_by === "assignees") - ? PROJECT_MEMBERS(projectId as string) - : null, - workspaceSlug && - projectId && - (displayFilters?.group_by === "created_by" || displayFilters?.group_by === "assignees") - ? () => projectService.projectMembers(workspaceSlug as string, projectId as string) - : null - ); - - const { projects } = useProjects(); - - const getGroupTitle = () => { - let title = addSpaceIfCamelCase(groupTitle); - - switch (displayFilters?.group_by) { - case "state": - title = addSpaceIfCamelCase(currentState?.name ?? ""); - break; - case "labels": - title = - [...(issueLabels ?? []), ...(workspaceLabels ?? [])]?.find((label) => label.id === groupTitle)?.name ?? - "None"; - break; - case "project": - title = projects?.find((p) => p.id === groupTitle)?.name ?? "None"; - break; - case "assignees": - case "created_by": - const member = members?.find((member) => member.member.id === groupTitle)?.member; - title = member ? member.display_name : "None"; - break; - } - - return title; - }; - - const getGroupIcon = () => { - let icon; - - switch (displayFilters?.group_by) { - case "state": - icon = currentState && ( - - ); - break; - case "state_detail.group": - icon = ( - - ); - break; - case "priority": - icon = ; - break; - case "project": - const project = projects?.find((p) => p.id === groupTitle); - icon = - project && - (project.emoji !== null - ? renderEmoji(project.emoji) - : project.icon_prop !== null - ? renderEmoji(project.icon_prop) - : null); - break; - case "labels": - const labelColor = - [...(issueLabels ?? []), ...(workspaceLabels ?? [])]?.find((label) => label.id === groupTitle)?.color ?? - "#000000"; - icon = ; - break; - case "assignees": - case "created_by": - const member = members?.find((member) => member.member.id === groupTitle)?.member; - icon = member ? : <>; - - break; - } - - return icon; - }; - - if (!groupedIssues) return null; - - return ( - <> - setIsDraftIssuesModalOpen(false)} - prePopulateData={{ - ...(cycleId && { cycle: cycleId.toString() }), - ...(moduleId && { module: moduleId.toString() }), - [displayFilters?.group_by! === "labels" ? "labels_list" : displayFilters?.group_by!]: - displayFilters?.group_by === "labels" ? [groupTitle] : groupTitle, - }} - /> - - - {({ open }) => ( -
-
- -
- {displayFilters?.group_by !== null &&
{getGroupIcon()}
} - {displayFilters?.group_by !== null ? ( -

- {getGroupTitle()} -

- ) : ( -

All Issues

- )} - - {groupedIssues[groupTitle as keyof IIssue].length} - -
-
- {isArchivedIssues ? ( - "" - ) : type === "issue" ? ( - !disableAddIssueOption && ( - - ) - ) : disableUserActions ? ( - "" - ) : ( - - -
- } - noBorder - > - setIsCreateIssueFormOpen(true)}>Create new - {openIssuesListModal && ( - Add an existing issue - )} - - )} -
- - - {groupedIssues[groupTitle] ? ( - groupedIssues[groupTitle].length > 0 ? ( - groupedIssues[groupTitle].map((issue, index) => ( - handleIssueAction(issue, "edit")} - makeIssueCopy={() => handleIssueAction(issue, "copy")} - handleDeleteIssue={() => handleIssueAction(issue, "delete")} - handleDraftIssueSelect={ - handleDraftIssueAction ? () => handleDraftIssueAction(issue, "edit") : undefined - } - handleDraftIssueDelete={ - handleDraftIssueAction ? () => handleDraftIssueAction(issue, "delete") : undefined - } - handleMyIssueOpen={handleMyIssueOpen} - removeIssue={() => { - if (removeIssue !== null && issue.bridge_id) removeIssue(issue.bridge_id, issue.id); - }} - disableUserActions={disableUserActions} - user={user} - userAuth={userAuth} - viewProps={viewProps} - /> - )) - ) : ( -

No issues.

- ) - ) : ( -
Loading...
- )} - - setIsCreateIssueFormOpen(false)} - prePopulatedData={{ - ...(cycleId && { cycle: cycleId.toString() }), - ...(moduleId && { module: moduleId.toString() }), - [displayFilters?.group_by! === "labels" ? "labels_list" : displayFilters?.group_by!]: - displayFilters?.group_by === "labels" ? [groupTitle] : groupTitle, - }} - /> - - {!disableAddIssueOption && !isCreateIssueFormOpen && !isDraftIssuesPage && ( -
- -
- )} -
-
-
- )} - - - ); -}; diff --git a/web/components/cycles/active-cycle-details.tsx b/web/components/cycles/active-cycle-details.tsx index 066c8ef1e24..09ee9853d62 100644 --- a/web/components/cycles/active-cycle-details.tsx +++ b/web/components/cycles/active-cycle-details.tsx @@ -6,7 +6,7 @@ import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; // services -import cyclesService from "services/cycle.service"; +import { CycleService } from "services/cycle.service"; // hooks import useToast from "hooks/use-toast"; // ui @@ -69,6 +69,9 @@ const stateGroups = [ }, ]; +// services +const cycleService = new CycleService(); + export const ActiveCycleDetails: React.FC = () => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -78,7 +81,7 @@ export const ActiveCycleDetails: React.FC = () => { const { data: currentCycle } = useSWR( workspaceSlug && projectId ? CURRENT_CYCLE_LIST(projectId as string) : null, workspaceSlug && projectId - ? () => cyclesService.getCyclesWithParams(workspaceSlug as string, projectId as string, "current") + ? () => cycleService.getCyclesWithParams(workspaceSlug as string, projectId as string, "current") : null ); const cycle = currentCycle ? currentCycle[0] : null; @@ -87,7 +90,7 @@ export const ActiveCycleDetails: React.FC = () => { workspaceSlug && projectId && cycle?.id ? CYCLE_ISSUES_WITH_PARAMS(cycle?.id, { priority: "urgent,high" }) : null, workspaceSlug && projectId && cycle?.id ? () => - cyclesService.getCycleIssuesWithParams(workspaceSlug as string, projectId as string, cycle.id, { + cycleService.getCycleIssuesWithParams(workspaceSlug as string, projectId as string, cycle.id, { priority: "urgent,high", }) : null @@ -166,7 +169,7 @@ export const ActiveCycleDetails: React.FC = () => { false ); - cyclesService + cycleService .addCycleToFavorites(workspaceSlug as string, projectId as string, { cycle: cycle.id, }) @@ -202,7 +205,7 @@ export const ActiveCycleDetails: React.FC = () => { false ); - cyclesService.removeCycleFromFavorites(workspaceSlug as string, projectId as string, cycle.id).catch(() => { + cycleService.removeCycleFromFavorites(workspaceSlug as string, projectId as string, cycle.id).catch(() => { setToastAlert({ type: "error", title: "Error!", diff --git a/web/components/cycles/cycles-list-legacy/completed-cycles-list.tsx b/web/components/cycles/cycles-list-legacy/completed-cycles-list.tsx index ba1068efc96..dbe10bb890b 100644 --- a/web/components/cycles/cycles-list-legacy/completed-cycles-list.tsx +++ b/web/components/cycles/cycles-list-legacy/completed-cycles-list.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import cyclesService from "services/cycle.service"; +import { CycleService } from "services/cycle.service"; // components import { CyclesView } from "components/cycles"; // fetch-keys @@ -13,6 +13,9 @@ type Props = { viewType: string | null; }; +// services +const cycleService = new CycleService(); + export const CompletedCyclesList: React.FC = ({ viewType }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -20,7 +23,7 @@ export const CompletedCyclesList: React.FC = ({ viewType }) => { const { data: completedCyclesList, mutate } = useSWR( workspaceSlug && projectId ? COMPLETED_CYCLES_LIST(projectId.toString()) : null, workspaceSlug && projectId - ? () => cyclesService.getCyclesWithParams(workspaceSlug.toString(), projectId.toString(), "completed") + ? () => cycleService.getCyclesWithParams(workspaceSlug.toString(), projectId.toString(), "completed") : null ); diff --git a/web/components/cycles/delete-cycle-modal.tsx b/web/components/cycles/delete-cycle-modal.tsx index d1871db8c0c..bfb77d097b9 100644 --- a/web/components/cycles/delete-cycle-modal.tsx +++ b/web/components/cycles/delete-cycle-modal.tsx @@ -6,7 +6,7 @@ import { mutate } from "swr"; // headless ui import { Dialog, Transition } from "@headlessui/react"; // services -import cycleService from "services/cycle.service"; +import { CycleService } from "services/cycle.service"; // hooks import useToast from "hooks/use-toast"; // ui @@ -32,6 +32,9 @@ import { } from "constants/fetch-keys"; import { getDateRangeStatus } from "helpers/date-time.helper"; +// services +const cycleService = new CycleService(); + export const DeleteCycleModal: React.FC = ({ isOpen, setIsOpen, data, user }) => { const [isDeleteLoading, setIsDeleteLoading] = useState(false); diff --git a/web/components/cycles/modal.tsx b/web/components/cycles/modal.tsx index 8e4660be8df..e7906fdaaa4 100644 --- a/web/components/cycles/modal.tsx +++ b/web/components/cycles/modal.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import { mutate } from "swr"; import { Dialog, Transition } from "@headlessui/react"; // services -import cycleService from "services/cycle.service"; +import { CycleService } from "services/cycle.service"; // hooks import useToast from "hooks/use-toast"; // components @@ -30,6 +30,9 @@ type CycleModalProps = { user: ICurrentUserResponse | undefined; }; +// services +const cycleService = new CycleService(); + export const CreateUpdateCycleModal: React.FC = ({ isOpen, handleClose, data, user }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; diff --git a/web/components/estimates/single-estimate.tsx b/web/components/estimates/single-estimate.tsx index 093d1c8bcff..3f941de2227 100644 --- a/web/components/estimates/single-estimate.tsx +++ b/web/components/estimates/single-estimate.tsx @@ -3,7 +3,7 @@ import React, { useState } from "react"; import { useRouter } from "next/router"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // hooks import useToast from "hooks/use-toast"; import useProjectDetails from "hooks/use-project-details"; @@ -26,6 +26,9 @@ type Props = { handleEstimateDelete: (estimateId: string) => void; }; +// services +const projectService = new ProjectService(); + export const SingleEstimate: React.FC = ({ user, estimate, editEstimate, handleEstimateDelete }) => { const [isDeleteEstimateModalOpen, setIsDeleteEstimateModalOpen] = useState(false); diff --git a/web/components/integration/delete-import-modal.tsx b/web/components/integration/delete-import-modal.tsx index 93c421710ec..7016f865bca 100644 --- a/web/components/integration/delete-import-modal.tsx +++ b/web/components/integration/delete-import-modal.tsx @@ -7,7 +7,7 @@ import { mutate } from "swr"; // headless ui import { Dialog, Transition } from "@headlessui/react"; // services -import IntegrationService from "services/integrations/integration.service"; +import { IntegrationService } from "services/integrations/integration.service"; // hooks import useToast from "hooks/use-toast"; // ui @@ -26,6 +26,9 @@ type Props = { user: ICurrentUserResponse | undefined; }; +// services +const integrationService = new IntegrationService(); + export const DeleteImportModal: React.FC = ({ isOpen, handleClose, data, user }) => { const [deleteLoading, setDeleteLoading] = useState(false); const [confirmDeleteImport, setConfirmDeleteImport] = useState(false); @@ -46,7 +49,8 @@ export const DeleteImportModal: React.FC = ({ isOpen, handleClose, data, false ); - IntegrationService.deleteImporterService(workspaceSlug as string, data.service, data.id, user) + integrationService + .deleteImporterService(workspaceSlug as string, data.service, data.id, user) .catch(() => setToastAlert({ type: "error", diff --git a/web/components/integration/single-integration-card.tsx b/web/components/integration/single-integration-card.tsx index e6a67070d82..cf2b0c6611a 100644 --- a/web/components/integration/single-integration-card.tsx +++ b/web/components/integration/single-integration-card.tsx @@ -6,7 +6,7 @@ import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; // services -import IntegrationService from "services/integrations/integration.service"; +import { IntegrationService } from "services/integrations"; // hooks import useToast from "hooks/use-toast"; import useIntegrationPopup from "hooks/use-integration-popup"; @@ -38,6 +38,9 @@ const integrationDetails: { [key: string]: any } = { }, }; +// services +const integrationService = new IntegrationService(); + export const SingleIntegrationCard: React.FC = ({ integration }) => { const [deletingIntegration, setDeletingIntegration] = useState(false); @@ -50,7 +53,7 @@ export const SingleIntegrationCard: React.FC = ({ integration }) => { const { data: workspaceIntegrations } = useSWR( workspaceSlug ? WORKSPACE_INTEGRATIONS(workspaceSlug as string) : null, - () => (workspaceSlug ? IntegrationService.getWorkspaceIntegrationsList(workspaceSlug as string) : null) + () => (workspaceSlug ? integrationService.getWorkspaceIntegrationsList(workspaceSlug as string) : null) ); const handleRemoveIntegration = async () => { @@ -60,7 +63,8 @@ export const SingleIntegrationCard: React.FC = ({ integration }) => { setDeletingIntegration(true); - await IntegrationService.deleteWorkspaceIntegration(workspaceSlug as string, workspaceIntegrationId ?? "") + await integrationService + .deleteWorkspaceIntegration(workspaceSlug as string, workspaceIntegrationId ?? "") .then(() => { mutate( WORKSPACE_INTEGRATIONS(workspaceSlug as string), diff --git a/web/components/ui/product-updates-modal.tsx b/web/components/ui/product-updates-modal.tsx index 4f5bad7b3f1..1c27c224ce5 100644 --- a/web/components/ui/product-updates-modal.tsx +++ b/web/components/ui/product-updates-modal.tsx @@ -5,7 +5,7 @@ import useSWR from "swr"; // headless ui import { Dialog, Transition } from "@headlessui/react"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // components import { Loader, MarkdownRenderer } from "components/ui"; // icons @@ -18,6 +18,9 @@ type Props = { setIsOpen: React.Dispatch>; }; +// services +const workspaceService = new WorkspaceService(); + export const ProductUpdatesModal: React.FC = ({ isOpen, setIsOpen }) => { const { data: updates } = useSWR("PRODUCT_UPDATES", () => workspaceService.getProductUpdates()); return ( @@ -48,10 +51,7 @@ export const ProductUpdatesModal: React.FC = ({ isOpen, setIsOpen }) => { >
- + Product Updates - - ))} -
- - {showFilters && ( - <> - { - const key = option.key as keyof typeof filters.filters; - - if (key === "start_date" || key === "target_date") { - const valueExists = checkIfArraysHaveSameElements( - filters.filters?.[key] ?? [], - option.value - ); - - handleFilters("filters", { - ...filters, - [key]: valueExists ? null : option.value, - }); - } else { - if (!filters?.filters?.[key]?.includes(option.value)) - handleFilters("filters", { - ...filters, - [key]: [...((filters?.filters?.[key] as any[]) ?? []), option.value], - }); - else { - handleFilters("filters", { - ...filters, - [key]: (filters?.filters?.[key] as any[])?.filter( - (item) => item !== option.value - ), - }); - } - } - }} - direction="left" - /> - - )} - - ); -}; diff --git a/web/components/issues/workspace-views/workspace-subscribed-issue.tsx b/web/components/issues/workspace-views/workspace-subscribed-issue.tsx deleted file mode 100644 index d9db2f347fe..00000000000 --- a/web/components/issues/workspace-views/workspace-subscribed-issue.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import React, { useCallback, useState } from "react"; - -import { useRouter } from "next/router"; - -import useSWR from "swr"; - -// hook -import useUser from "hooks/use-user"; -// context -import { useProjectMyMembership } from "contexts/project-member.context"; -// services -import workspaceService from "services/workspace.service"; -// components -import { SpreadsheetView } from "components/core"; -import { WorkspaceViewsNavigation } from "components/workspace/views/workpace-view-navigation"; -import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues"; -import { CreateUpdateWorkspaceViewModal } from "components/workspace/views/modal"; -// fetch-keys -import { WORKSPACE_VIEW_ISSUES } from "constants/fetch-keys"; -// types -import { IIssue } from "types"; - -export const WorkspaceSubscribedIssues = () => { - const [createViewModal, setCreateViewModal] = useState(null); - - // create issue modal - const [createIssueModal, setCreateIssueModal] = useState(false); - const [preloadedData, setPreloadedData] = useState< - (Partial & { actionType: "createIssue" | "edit" | "delete" }) | undefined - >(undefined); - - // update issue modal - const [editIssueModal, setEditIssueModal] = useState(false); - const [issueToEdit, setIssueToEdit] = useState< - (IIssue & { actionType: "edit" | "delete" }) | undefined - >(undefined); - - // delete issue modal - const [deleteIssueModal, setDeleteIssueModal] = useState(false); - const [issueToDelete, setIssueToDelete] = useState(null); - - const router = useRouter(); - const { workspaceSlug } = router.query; - - const { user } = useUser(); - const { memberRole } = useProjectMyMembership(); - - const params: any = { - subscriber: user?.id ?? undefined, - sub_issue: false, - }; - - const { data: viewIssues, mutate: mutateIssues } = useSWR( - workspaceSlug ? WORKSPACE_VIEW_ISSUES(workspaceSlug.toString(), params) : null, - workspaceSlug ? () => workspaceService.getViewIssues(workspaceSlug.toString(), params) : null - ); - - const makeIssueCopy = useCallback( - (issue: IIssue) => { - setCreateIssueModal(true); - - setPreloadedData({ ...issue, name: `${issue.name} (Copy)`, actionType: "createIssue" }); - }, - [setCreateIssueModal, setPreloadedData] - ); - - const handleEditIssue = useCallback( - (issue: IIssue) => { - setEditIssueModal(true); - setIssueToEdit({ - ...issue, - actionType: "edit", - cycle: issue.issue_cycle ? issue.issue_cycle.cycle : null, - module: issue.issue_module ? issue.issue_module.module : null, - }); - }, - [setEditIssueModal, setIssueToEdit] - ); - - const handleDeleteIssue = useCallback( - (issue: IIssue) => { - setDeleteIssueModal(true); - setIssueToDelete(issue); - }, - [setDeleteIssueModal, setIssueToDelete] - ); - - const handleIssueAction = useCallback( - (issue: IIssue, action: "copy" | "edit" | "delete" | "updateDraft") => { - if (action === "copy") makeIssueCopy(issue); - else if (action === "edit") handleEditIssue(issue); - else if (action === "delete") handleDeleteIssue(issue); - }, - [makeIssueCopy, handleEditIssue, handleDeleteIssue] - ); - return ( - <> - setCreateIssueModal(false)} - prePopulateData={{ - ...preloadedData, - }} - onSubmit={async () => { - mutateIssues(); - }} - /> - setEditIssueModal(false)} - data={issueToEdit} - onSubmit={async () => { - mutateIssues(); - }} - /> - setDeleteIssueModal(false)} - isOpen={deleteIssueModal} - data={issueToDelete} - user={user} - onSubmit={async () => { - mutateIssues(); - }} - /> - setCreateViewModal(null)} - preLoadedData={createViewModal} - /> -
-
- setCreateViewModal(true)} /> - -
- -
-
-
- - ); -}; diff --git a/web/hooks/gantt-chart/cycle-issues-view.tsx b/web/hooks/gantt-chart/cycle-issues-view.tsx deleted file mode 100644 index c7b96990f94..00000000000 --- a/web/hooks/gantt-chart/cycle-issues-view.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import useSWR from "swr"; - -// services -import cyclesService from "services/cycle.service"; -// hooks -import useIssuesView from "hooks/use-issues-view"; -// fetch-keys -import { CYCLE_ISSUES_WITH_PARAMS } from "constants/fetch-keys"; - -const useGanttChartCycleIssues = ( - workspaceSlug: string | undefined, - projectId: string | undefined, - cycleId: string | undefined -) => { - const { displayFilters, filters } = useIssuesView(); - - const params: any = { - order_by: displayFilters.order_by, - type: displayFilters?.type ? displayFilters?.type : undefined, - sub_issue: displayFilters.sub_issue, - assignees: filters?.assignees ? filters?.assignees.join(",") : undefined, - state: filters?.state ? filters?.state.join(",") : undefined, - priority: filters?.priority ? filters?.priority.join(",") : undefined, - labels: filters?.labels ? filters?.labels.join(",") : undefined, - created_by: filters?.created_by ? filters?.created_by.join(",") : undefined, - start_date: filters?.start_date ? filters?.start_date.join(",") : undefined, - target_date: filters?.target_date ? filters?.target_date.join(",") : undefined, - start_target_date: true, // to fetch only issues with a start and target date - }; - - // all issues under the workspace and project - const { data: ganttIssues, mutate: mutateGanttIssues } = useSWR( - workspaceSlug && projectId && cycleId ? CYCLE_ISSUES_WITH_PARAMS(cycleId.toString(), params) : null, - workspaceSlug && projectId && cycleId - ? () => - cyclesService.getCycleIssuesWithParams( - workspaceSlug.toString(), - projectId.toString(), - cycleId.toString(), - params - ) - : null - ); - - return { - ganttIssues, - mutateGanttIssues, - }; -}; - -export default useGanttChartCycleIssues; diff --git a/web/hooks/gantt-chart/issue-view.tsx b/web/hooks/gantt-chart/issue-view.tsx deleted file mode 100644 index 1274d93d22a..00000000000 --- a/web/hooks/gantt-chart/issue-view.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import useSWR from "swr"; - -// services -import issuesService from "services/issue/issue.service"; -// hooks -import useIssuesView from "hooks/use-issues-view"; -// fetch-keys -import { PROJECT_ISSUES_LIST_WITH_PARAMS } from "constants/fetch-keys"; - -const useGanttChartIssues = (workspaceSlug: string | undefined, projectId: string | undefined) => { - const { displayFilters, filters } = useIssuesView(); - - const params: any = { - order_by: displayFilters.order_by, - type: displayFilters?.type ? displayFilters?.type : undefined, - sub_issue: displayFilters.sub_issue, - assignees: filters?.assignees ? filters?.assignees.join(",") : undefined, - state: filters?.state ? filters?.state.join(",") : undefined, - priority: filters?.priority ? filters?.priority.join(",") : undefined, - labels: filters?.labels ? filters?.labels.join(",") : undefined, - created_by: filters?.created_by ? filters?.created_by.join(",") : undefined, - start_date: filters?.start_date ? filters?.start_date.join(",") : undefined, - target_date: filters?.target_date ? filters?.target_date.join(",") : undefined, - start_target_date: true, // to fetch only issues with a start and target date - }; - - // all issues under the workspace and project - const { data: ganttIssues, mutate: mutateGanttIssues } = useSWR( - workspaceSlug && projectId ? PROJECT_ISSUES_LIST_WITH_PARAMS(projectId, params) : null, - workspaceSlug && projectId - ? () => issuesService.getIssuesWithParams(workspaceSlug.toString(), projectId.toString(), params) - : null - ); - - return { - ganttIssues, - mutateGanttIssues, - params, - }; -}; - -export default useGanttChartIssues; diff --git a/web/hooks/gantt-chart/view-issues-view.tsx b/web/hooks/gantt-chart/view-issues-view.tsx deleted file mode 100644 index e3343a69607..00000000000 --- a/web/hooks/gantt-chart/view-issues-view.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import useSWR from "swr"; - -// services -import issuesService from "services/issue/issue.service"; -// hooks -import useIssuesView from "hooks/use-issues-view"; -// fetch-keys -import { VIEW_ISSUES } from "constants/fetch-keys"; - -const useGanttChartViewIssues = ( - workspaceSlug: string | undefined, - projectId: string | undefined, - viewId: string | undefined -) => { - const { params } = useIssuesView(); - const { order_by, group_by, ...viewGanttParams } = params; - - // all issues under the view - const { data: ganttIssues, mutate: mutateGanttIssues } = useSWR( - workspaceSlug && projectId && viewId - ? VIEW_ISSUES(viewId.toString(), { ...viewGanttParams, order_by, start_target_date: true }) - : null, - workspaceSlug && projectId && viewId - ? () => - issuesService.getIssuesWithParams(workspaceSlug.toString(), projectId.toString(), { - ...viewGanttParams, - start_target_date: true, - }) - : null - ); - - return { - ganttIssues, - mutateGanttIssues, - }; -}; - -export default useGanttChartViewIssues; diff --git a/web/hooks/use-calendar-issues-view.tsx b/web/hooks/use-calendar-issues-view.tsx deleted file mode 100644 index a05383e000a..00000000000 --- a/web/hooks/use-calendar-issues-view.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import { useContext, useState } from "react"; - -import { useRouter } from "next/router"; - -import useSWR from "swr"; - -// contexts -import { issueViewContext } from "contexts/issue-view.context"; -// services -import issuesService from "services/issues.service"; -import cyclesService from "services/cycle.service"; -import modulesService from "services/module.service"; -// helpers -import { renderDateFormat } from "helpers/date-time.helper"; -// types -import { IIssue } from "types"; -// fetch-keys -import { - CYCLE_ISSUES_WITH_PARAMS, - MODULE_ISSUES_WITH_PARAMS, - PROJECT_ISSUES_LIST_WITH_PARAMS, - VIEW_ISSUES, -} from "constants/fetch-keys"; - -const useCalendarIssuesView = () => { - const { - display_filters: displayFilters, - filters, - setFilters, - resetFilterToDefault, - setNewFilterDefaultView, - } = useContext(issueViewContext); - - const [activeMonthDate, setActiveMonthDate] = useState(new Date()); - - // previous month's first date - const previousMonthYear = - activeMonthDate.getMonth() === 0 ? activeMonthDate.getFullYear() - 1 : activeMonthDate.getFullYear(); - const previousMonthMonth = activeMonthDate.getMonth() === 0 ? 11 : activeMonthDate.getMonth() - 1; - - const previousMonthFirstDate = new Date(previousMonthYear, previousMonthMonth, 1); - - // next month's last date - const nextMonthYear = - activeMonthDate.getMonth() === 11 ? activeMonthDate.getFullYear() + 1 : activeMonthDate.getFullYear(); - const nextMonthMonth = (activeMonthDate.getMonth() + 1) % 12; - const nextMonthFirstDate = new Date(nextMonthYear, nextMonthMonth, 1); - - const nextMonthLastDate = new Date(nextMonthFirstDate.getFullYear(), nextMonthFirstDate.getMonth() + 1, 0); - - const router = useRouter(); - const { workspaceSlug, projectId, cycleId, moduleId, viewId } = router.query; - - const params: any = { - assignees: filters?.assignees ? filters?.assignees.join(",") : undefined, - state: filters?.state ? filters?.state.join(",") : undefined, - priority: filters?.priority ? filters?.priority.join(",") : undefined, - type: displayFilters?.type ? displayFilters?.type : undefined, - labels: filters?.labels ? filters?.labels.join(",") : undefined, - created_by: filters?.created_by ? filters?.created_by.join(",") : undefined, - start_date: filters?.start_date ? filters?.start_date.join(",") : undefined, - target_date: `${renderDateFormat(previousMonthFirstDate)};after,${renderDateFormat(nextMonthLastDate)};before`, - }; - - const { data: projectCalendarIssues, mutate: mutateProjectCalendarIssues } = useSWR( - workspaceSlug && projectId ? PROJECT_ISSUES_LIST_WITH_PARAMS(projectId.toString(), params) : null, - workspaceSlug && projectId - ? () => issuesService.getIssuesWithParams(workspaceSlug.toString(), projectId.toString(), params) - : null - ); - - const { data: cycleCalendarIssues, mutate: mutateCycleCalendarIssues } = useSWR( - workspaceSlug && projectId && cycleId ? CYCLE_ISSUES_WITH_PARAMS(cycleId.toString(), params) : null, - workspaceSlug && projectId && cycleId - ? () => - cyclesService.getCycleIssuesWithParams( - workspaceSlug.toString(), - projectId.toString(), - cycleId.toString(), - params - ) - : null - ); - - const { data: moduleCalendarIssues, mutate: mutateModuleCalendarIssues } = useSWR( - workspaceSlug && projectId && moduleId ? MODULE_ISSUES_WITH_PARAMS(moduleId.toString(), params) : null, - workspaceSlug && projectId && moduleId - ? () => - modulesService.getModuleIssuesWithParams( - workspaceSlug.toString(), - projectId.toString(), - moduleId.toString(), - params - ) - : null - ); - - const { data: viewCalendarIssues, mutate: mutateViewCalendarIssues } = useSWR( - workspaceSlug && projectId && viewId && params ? VIEW_ISSUES(viewId.toString(), params) : null, - workspaceSlug && projectId && viewId && params - ? () => issuesService.getIssuesWithParams(workspaceSlug.toString(), projectId.toString(), params) - : null - ); - - const calendarIssues = cycleId - ? (cycleCalendarIssues as IIssue[]) - : moduleId - ? (moduleCalendarIssues as IIssue[]) - : viewId - ? (viewCalendarIssues as IIssue[]) - : (projectCalendarIssues as IIssue[]); - - return { - activeMonthDate, - setActiveMonthDate, - calendarIssues: calendarIssues ?? [], - mutateIssues: cycleId - ? mutateCycleCalendarIssues - : moduleId - ? mutateModuleCalendarIssues - : viewId - ? mutateViewCalendarIssues - : mutateProjectCalendarIssues, - filters, - setFilters, - params, - resetFilterToDefault, - setNewFilterDefaultView, - } as const; -}; - -export default useCalendarIssuesView; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/settings/features.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/settings/features.tsx index c10cfd824cb..2eb1f48584f 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/settings/features.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/settings/features.tsx @@ -5,8 +5,8 @@ import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; // services -import projectService from "services/project.service/project.service"; -import trackEventServices, { MiscellaneousEventType } from "services/track_event.service"; +import { ProjectService } from "services/project"; +import { TrackEventService, MiscellaneousEventType } from "services/track_event.service"; // layouts import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy"; // hooks @@ -80,6 +80,10 @@ const getEventType = (feature: string, toggle: boolean): MiscellaneousEventType } }; +// services +const projectService = new ProjectService(); +const trackEventService = new TrackEventService(); + const FeaturesSettings: NextPage = () => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -100,13 +104,6 @@ const FeaturesSettings: NextPage = () => { : null ); - const { data: memberDetails } = useSWR( - workspaceSlug && projectId ? USER_PROJECT_VIEW(projectId.toString()) : null, - workspaceSlug && projectId - ? () => projectService.projectMemberMe(workspaceSlug.toString(), projectId.toString()) - : null - ); - const handleSubmit = async (formData: Partial) => { if (!workspaceSlug || !projectId || !projectDetails) return; @@ -184,7 +181,7 @@ const FeaturesSettings: NextPage = () => { { - trackEventServices.trackMiscellaneousEvent( + trackEventService.trackMiscellaneousEvent( { workspaceId: (projectDetails?.workspace as any)?.id, workspaceSlug, diff --git a/web/pages/[workspaceSlug]/settings/billing.tsx b/web/pages/[workspaceSlug]/settings/billing.tsx index c852fe9e1ce..5469b6b4fd7 100644 --- a/web/pages/[workspaceSlug]/settings/billing.tsx +++ b/web/pages/[workspaceSlug]/settings/billing.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // layouts import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy"; // component @@ -20,6 +20,9 @@ import { WORKSPACE_DETAILS } from "constants/fetch-keys"; // helper import { truncateText } from "helpers/string.helper"; +// services +const workspaceService = new WorkspaceService(); + const BillingSettings: NextPage = () => { const { query: { workspaceSlug }, diff --git a/web/pages/[workspaceSlug]/settings/exports.tsx b/web/pages/[workspaceSlug]/settings/exports.tsx index f90a5da46e9..b0345d49896 100644 --- a/web/pages/[workspaceSlug]/settings/exports.tsx +++ b/web/pages/[workspaceSlug]/settings/exports.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // layouts import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy"; // components @@ -18,6 +18,9 @@ import { WORKSPACE_DETAILS } from "constants/fetch-keys"; // helper import { truncateText } from "helpers/string.helper"; +// services +const workspaceService = new WorkspaceService(); + const ImportExport: NextPage = () => { const router = useRouter(); const { workspaceSlug } = router.query; diff --git a/web/pages/[workspaceSlug]/settings/integrations.tsx b/web/pages/[workspaceSlug]/settings/integrations.tsx index ed96c56a5dd..7d6869ed289 100644 --- a/web/pages/[workspaceSlug]/settings/integrations.tsx +++ b/web/pages/[workspaceSlug]/settings/integrations.tsx @@ -5,8 +5,8 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import workspaceService from "services/workspace.service"; -import IntegrationService from "services/integrations/integration.service"; +import { WorkspaceService } from "services/workspace.service"; +import { IntegrationService } from "services/integrations"; // layouts import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy"; // components @@ -23,6 +23,10 @@ import { WORKSPACE_DETAILS, APP_INTEGRATIONS } from "constants/fetch-keys"; // helper import { truncateText } from "helpers/string.helper"; +// services +const workspaceService = new WorkspaceService(); +const integrationService = new IntegrationService(); + const WorkspaceIntegrations: NextPage = () => { const router = useRouter(); const { workspaceSlug } = router.query; @@ -32,7 +36,7 @@ const WorkspaceIntegrations: NextPage = () => { ); const { data: appIntegrations } = useSWR(workspaceSlug ? APP_INTEGRATIONS : null, () => - workspaceSlug ? IntegrationService.getAppIntegrationsList() : null + workspaceSlug ? integrationService.getAppIntegrationsList() : null ); return ( diff --git a/web/pages/create-workspace/index.tsx b/web/pages/create-workspace/index.tsx index 867f3f71f92..fea22f71264 100644 --- a/web/pages/create-workspace/index.tsx +++ b/web/pages/create-workspace/index.tsx @@ -8,7 +8,7 @@ import { mutate } from "swr"; // next-themes import { useTheme } from "next-themes"; // services -import userService from "services/user.service"; +import { UserService } from "services/user.service"; // hooks import useUser from "hooks/use-user"; // layouts @@ -25,6 +25,9 @@ import type { NextPage } from "next"; // fetch-keys import { CURRENT_USER } from "constants/fetch-keys"; +// services +const userService = new UserService(); + const CreateWorkspace: NextPage = () => { const [defaultValues, setDefaultValues] = useState({ name: "", diff --git a/web/pages/installations/[provider]/index.tsx b/web/pages/installations/[provider]/index.tsx index abdcf94cc10..cf249f875fe 100644 --- a/web/pages/installations/[provider]/index.tsx +++ b/web/pages/installations/[provider]/index.tsx @@ -3,17 +3,20 @@ import React, { useEffect } from "react"; import { useRouter } from "next/router"; // services -import appInstallationsService from "services/app_installation.service"; +import { AppInstallationService } from "services/app_installation.service"; // ui import { Spinner } from "@plane/ui"; +// services +const appInstallationService = new AppInstallationService(); + const AppPostInstallation = () => { const router = useRouter(); const { installation_id, setup_action, state, provider, code } = router.query; useEffect(() => { if (provider === "github" && state && installation_id) { - appInstallationsService + appInstallationService .addInstallationApp(state.toString(), provider, { installation_id }) .then(() => { window.opener = null; @@ -24,7 +27,7 @@ const AppPostInstallation = () => { console.log(err); }); } else if (provider === "slack" && state && code) { - appInstallationsService + appInstallationService .getSlackAuthDetails(code.toString()) .then((res) => { const [workspaceSlug, projectId, integrationId] = state.toString().split(","); @@ -36,7 +39,7 @@ const AppPostInstallation = () => { }, }; - appInstallationsService + appInstallationService .addInstallationApp(state.toString(), provider, payload) .then((r) => { window.opener = null; @@ -56,7 +59,7 @@ const AppPostInstallation = () => { team_name: res.team.name, scopes: res.scope, }; - appInstallationsService + appInstallationService .addSlackChannel(workspaceSlug, projectId, integrationId, payload) .then((r) => { window.opener = null; diff --git a/web/pages/invitations/index.tsx b/web/pages/invitations/index.tsx index 69a01517b31..5581c93cb8b 100644 --- a/web/pages/invitations/index.tsx +++ b/web/pages/invitations/index.tsx @@ -5,8 +5,8 @@ import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; import { useTheme } from "next-themes"; // services -import WorkspaceService from "services/workspace.service"; -import UserService from "services/user.service"; +import { WorkspaceService } from "services/workspace.service"; +import { UserService } from "services/user.service"; // hooks import useUser from "hooks/use-user"; import useToast from "hooks/use-toast"; @@ -31,6 +31,7 @@ import { ROLE } from "constants/workspace"; // components import { EmptyState } from "components/common"; +// services const workspaceService = new WorkspaceService(); const userService = new UserService(); diff --git a/web/pages/m/[workspaceSlug]/editor.tsx b/web/pages/m/[workspaceSlug]/editor.tsx index 6483f4e53de..da8c1e05459 100644 --- a/web/pages/m/[workspaceSlug]/editor.tsx +++ b/web/pages/m/[workspaceSlug]/editor.tsx @@ -16,8 +16,9 @@ import WebViewLayout from "layouts/web-view-layout"; // components import { Button, Spinner } from "@plane/ui"; import { RichTextEditor } from "@plane/rich-text-editor"; -import fileService from "services/file.service"; // services +import { FileService } from "services/file.service"; +const fileService = new FileService(); const Editor: NextPage = () => { const [isLoading, setIsLoading] = useState(false); diff --git a/web/pages/onboarding/index.tsx b/web/pages/onboarding/index.tsx index 169fa1db184..8c3d1e2ee88 100644 --- a/web/pages/onboarding/index.tsx +++ b/web/pages/onboarding/index.tsx @@ -7,8 +7,8 @@ import useSWR, { mutate } from "swr"; // next-themes import { useTheme } from "next-themes"; // services -import userService from "services/user.service"; -import workspaceService from "services/workspace.service"; +import { UserService } from "services/user.service"; +import { WorkspaceService } from "services/workspace.service"; // hooks import useUserAuth from "hooks/use-user-auth"; import useWorkspaces from "hooks/use-workspaces"; @@ -28,6 +28,10 @@ import type { NextPage } from "next"; // fetch-keys import { CURRENT_USER, USER_WORKSPACE_INVITATIONS } from "constants/fetch-keys"; +// services +const userService = new UserService(); +const workspaceService = new WorkspaceService(); + const Onboarding: NextPage = () => { const [step, setStep] = useState(null); diff --git a/web/pages/workspace-invitations/index.tsx b/web/pages/workspace-invitations/index.tsx index 86bce7f5192..dd97afd65ff 100644 --- a/web/pages/workspace-invitations/index.tsx +++ b/web/pages/workspace-invitations/index.tsx @@ -6,7 +6,7 @@ import useSWR from "swr"; import { CheckIcon, CubeIcon, ShareIcon, StarIcon, UserIcon, XMarkIcon } from "@heroicons/react/24/outline"; // swr // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // hooks import useUser from "hooks/use-user"; // layouts @@ -20,6 +20,9 @@ import type { NextPage } from "next"; // constants import { WORKSPACE_INVITATION } from "constants/fetch-keys"; +// services +const workspaceService = new WorkspaceService(); + const WorkspaceInvitation: NextPage = () => { const router = useRouter(); diff --git a/web/store/cycle/cycle_issue.store.ts b/web/store/cycle/cycle_issue.store.ts index b1d4f193a81..8ab84f0aeae 100644 --- a/web/store/cycle/cycle_issue.store.ts +++ b/web/store/cycle/cycle_issue.store.ts @@ -4,7 +4,7 @@ import { RootStore } from "../root"; // types import { IIssue } from "types"; // services -import CycleService from "services/cycle.service"; +import { CycleService } from "services/cycle.service"; // constants import { sortArrayByDate, sortArrayByPriority } from "constants/kanban-helpers"; diff --git a/web/store/cycle/cycle_issue_filters.store.ts b/web/store/cycle/cycle_issue_filters.store.ts index f61132c7ec1..c6818b6df21 100644 --- a/web/store/cycle/cycle_issue_filters.store.ts +++ b/web/store/cycle/cycle_issue_filters.store.ts @@ -1,6 +1,6 @@ import { observable, action, computed, makeObservable, runInAction } from "mobx"; // services -import CycleService from "services/cycle.service"; +import { CycleService } from "services/cycle.service"; // helpers import { handleIssueQueryParamsByLayout } from "helpers/issue.helper"; // types diff --git a/web/store/cycle/cycles.store.ts b/web/store/cycle/cycles.store.ts index 8db6d319139..d3767c88aef 100644 --- a/web/store/cycle/cycles.store.ts +++ b/web/store/cycle/cycles.store.ts @@ -5,7 +5,7 @@ import { ICycle } from "types"; // services import { ProjectService } from "services/project"; import { IssueService } from "services/issue"; -import CycleService from "services/cycle.service"; +import { CycleService } from "services/cycle.service"; export interface ICycleStore { loader: boolean; diff --git a/web/store/global-view/global_view_issues.store.ts b/web/store/global-view/global_view_issues.store.ts index fdb727eb213..1b28939334b 100644 --- a/web/store/global-view/global_view_issues.store.ts +++ b/web/store/global-view/global_view_issues.store.ts @@ -1,7 +1,7 @@ import { observable, action, makeObservable, runInAction } from "mobx"; // services import { ProjectService } from "services/project"; -import WorkspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // helpers import { handleIssueQueryParamsByLayout } from "helpers/issue.helper"; // types diff --git a/web/store/global-view/global_views.store.ts b/web/store/global-view/global_views.store.ts index fecfd71f6c1..c9915b8d898 100644 --- a/web/store/global-view/global_views.store.ts +++ b/web/store/global-view/global_views.store.ts @@ -1,7 +1,7 @@ import { observable, action, makeObservable, runInAction } from "mobx"; // services import { ProjectService } from "services/project"; -import WorkspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // types import { RootStore } from "../root"; import { IWorkspaceView } from "types/workspace-views"; diff --git a/web/store/issue/issue_detail.store.ts b/web/store/issue/issue_detail.store.ts index 0b3ebf9070f..650eaf99e30 100644 --- a/web/store/issue/issue_detail.store.ts +++ b/web/store/issue/issue_detail.store.ts @@ -1,6 +1,6 @@ import { observable, action, makeObservable, runInAction } from "mobx"; // services -import IssueService from "services/issue/issue.service"; +import { IssueService } from "services/issue"; // types import { RootStore } from "../root"; import { IUser, IIssue } from "types"; diff --git a/web/store/issue/issue_draft.store.ts b/web/store/issue/issue_draft.store.ts index bd44a74658e..747694a4394 100644 --- a/web/store/issue/issue_draft.store.ts +++ b/web/store/issue/issue_draft.store.ts @@ -1,7 +1,7 @@ // mobx import { action, observable, runInAction, makeAutoObservable } from "mobx"; // services -import issueService from "services/issue/issue.service"; +import { issueService } from "services/issue/issue.service"; // types import type { IIssue } from "types"; diff --git a/web/store/module/module_filters.store.ts b/web/store/module/module_filters.store.ts index f24ac4bd083..66ecb72787f 100644 --- a/web/store/module/module_filters.store.ts +++ b/web/store/module/module_filters.store.ts @@ -1,7 +1,7 @@ import { observable, action, computed, makeObservable, runInAction } from "mobx"; // services import { ProjectService } from "services/project"; -import ModuleService from "services/module.service"; +import { ModuleService } from "services/module.service"; // helpers import { handleIssueQueryParamsByLayout } from "helpers/issue.helper"; // types diff --git a/web/store/module/module_issue.store.ts b/web/store/module/module_issue.store.ts index 473ce9d2107..3d59fd5ece2 100644 --- a/web/store/module/module_issue.store.ts +++ b/web/store/module/module_issue.store.ts @@ -4,7 +4,7 @@ import { RootStore } from "../root"; // types import { IIssue } from "types"; // services -import ModuleService from "services/module.service"; +import { ModuleService } from "services/module.service"; // helpers import { sortArrayByDate, sortArrayByPriority } from "constants/kanban-helpers"; diff --git a/web/store/module/modules.store.ts b/web/store/module/modules.store.ts index b89ac5362c4..f73b5952f19 100644 --- a/web/store/module/modules.store.ts +++ b/web/store/module/modules.store.ts @@ -1,7 +1,7 @@ import { action, computed, observable, makeObservable, runInAction } from "mobx"; // services import { ProjectService } from "services/project"; -import ModuleService from "services/module.service"; +import { ModuleService } from "services/module.service"; // types import { RootStore } from "../root"; import { IIssue, IModule } from "types"; diff --git a/web/store/page.store.ts b/web/store/page.store.ts index 91abc0c40e6..23a8050aeea 100644 --- a/web/store/page.store.ts +++ b/web/store/page.store.ts @@ -4,7 +4,7 @@ import { RootStore } from "./root"; import { IPage } from "types"; // services import { ProjectService } from "services/project"; -import PageService from "services/page.service"; +import { PageService } from "services/page.service"; export interface IPageStore { loader: boolean; diff --git a/web/store/project-view/project_views.store.ts b/web/store/project-view/project_views.store.ts index 74c51234c16..4c4baf487cc 100644 --- a/web/store/project-view/project_views.store.ts +++ b/web/store/project-view/project_views.store.ts @@ -1,6 +1,6 @@ import { observable, action, makeObservable, runInAction } from "mobx"; // services -import ViewService from "services/view.service"; +import { ViewService } from "services/view.service"; // types import { RootStore } from "../root"; import { IProjectView } from "types"; diff --git a/web/store/user.store.ts b/web/store/user.store.ts index 46fbef66cfa..e376961599d 100644 --- a/web/store/user.store.ts +++ b/web/store/user.store.ts @@ -1,8 +1,8 @@ // mobx import { action, observable, runInAction, makeObservable } from "mobx"; // services -import UserService from "services/user.service"; -import WorkspaceService from "services/workspace.service"; +import { UserService } from "services/user.service"; +import { WorkspaceService } from "services/workspace.service"; // interfaces import { IUser, IUserSettings } from "types/users"; diff --git a/web/store/workspace/workspace.store.ts b/web/store/workspace/workspace.store.ts index 3bc1bd88151..a226720ad04 100644 --- a/web/store/workspace/workspace.store.ts +++ b/web/store/workspace/workspace.store.ts @@ -3,7 +3,7 @@ import { RootStore } from "../root"; // types import { IIssueLabels, IProject, IWorkspace, IWorkspaceMember } from "types"; // services -import WorkspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; import { ProjectService } from "services/project"; import { IssueService, IssueLabelService } from "services/issue"; diff --git a/web/store/workspace/workspace_filters.store.ts b/web/store/workspace/workspace_filters.store.ts index bea3d783b93..d33a560576e 100644 --- a/web/store/workspace/workspace_filters.store.ts +++ b/web/store/workspace/workspace_filters.store.ts @@ -1,6 +1,6 @@ import { observable, action, computed, makeObservable, runInAction } from "mobx"; // services -import WorkspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // helpers import { handleIssueQueryParamsByLayout } from "helpers/issue.helper"; // types From d6f5892eabc8f288974154b58702fa13f02061b7 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal Date: Sat, 14 Oct 2023 15:15:45 +0530 Subject: [PATCH 3/3] chore: fix remianing service imports --- web/components/issues/comment/add-comment.tsx | 9 +- web/components/issues/select/state.tsx | 7 +- .../issues/sidebar-select/assignee.tsx | 5 +- .../issues/sidebar-select/blocked.tsx | 9 +- .../issues/sidebar-select/blocker.tsx | 9 +- .../issues/sidebar-select/cycle.tsx | 12 +- .../issues/sidebar-select/duplicate.tsx | 9 +- .../issues/sidebar-select/state.tsx | 5 +- web/components/labels/delete-label-modal.tsx | 7 +- web/components/labels/single-label-group.tsx | 7 +- .../modules/delete-module-modal.tsx | 7 +- .../gantt-chart/modules-list-layout.tsx | 7 +- .../modules/sidebar-select/select-members.tsx | 5 +- web/components/onboarding/invite-members.tsx | 5 +- web/components/onboarding/join-workspaces.tsx | 5 +- .../pages/create-update-block-inline.tsx | 10 +- .../pages/create-update-page-modal.tsx | 9 +- web/components/pages/delete-page-modal.tsx | 7 +- .../pages/pages-list/all-pages-list.tsx | 7 +- .../pages/pages-list/favorite-pages-list.tsx | 7 +- .../pages/pages-list/my-pages-list.tsx | 7 +- .../pages/pages-list/other-pages-list.tsx | 7 +- .../pages/pages-list/recent-pages-list.tsx | 9 +- web/components/pages/pages-view.tsx | 16 +- web/components/pages/single-page-block.tsx | 9 +- web/components/profile/overview/activity.tsx | 5 +- .../profile/profile-issues-view.tsx | 13 +- web/components/profile/sidebar.tsx | 5 +- web/components/project/label-select.tsx | 7 +- web/components/project/member-select.tsx | 5 +- .../project/send-project-invitation-modal.tsx | 8 +- .../project/single-integration-card.tsx | 5 +- .../project/single-project-card.tsx | 37 +-- .../states/create-update-state-inline.tsx | 2 +- web/components/states/single-state.tsx | 13 +- web/components/states/state-select.tsx | 9 +- web/components/ui/avatar.tsx | 20 +- web/components/views/single-view-item.tsx | 169 ---------- web/components/web-view/comment-card.tsx | 53 +-- .../web-view/create-update-link-form.tsx | 2 +- web/components/web-view/issue-activity.tsx | 24 +- web/components/web-view/issue-attachments.tsx | 13 +- .../web-view/issue-web-view-form.tsx | 16 +- .../web-view/issues-select-bottom-sheet.tsx | 32 +- web/components/web-view/select-assignee.tsx | 12 +- web/components/web-view/select-blocked-by.tsx | 47 +-- web/components/web-view/select-duplicate.tsx | 47 +-- web/components/web-view/select-parent.tsx | 5 +- web/components/web-view/select-relates-to.tsx | 43 +-- web/components/web-view/select-state.tsx | 22 +- web/components/web-view/sub-issues.tsx | 22 +- .../workspace/create-workspace-form.tsx | 2 +- .../workspace/delete-workspace-modal.tsx | 5 +- .../send-workspace-invitation-modal.tsx | 2 +- web/components/workspace/sidebar-dropdown.tsx | 4 +- .../views/delete-workspace-view-modal.tsx | 141 -------- .../workspace/views/global-select-filters.tsx | 301 ------------------ .../views/single-workspace-view-item.tsx | 110 ------- .../views/workpace-view-navigation.tsx | 105 ------ web/contexts/project-member.context.tsx | 11 +- web/contexts/theme.context.tsx | 5 +- web/contexts/user.context.tsx | 5 +- web/contexts/workspace-member.context.tsx | 5 +- web/contexts/workspace-view-context.tsx | 235 -------------- web/contexts/workspace.context.tsx | 11 +- web/hooks/my-issues/use-my-issues.tsx | 9 +- web/hooks/use-comment-reaction.tsx | 14 +- web/hooks/use-estimate-option.tsx | 9 +- web/hooks/use-issue-reaction.tsx | 14 +- web/hooks/use-issues-view.tsx | 37 ++- web/hooks/use-profile-issues.tsx | 16 +- web/hooks/use-project-details.tsx | 4 +- web/hooks/use-project-members.tsx | 4 +- web/hooks/use-projects.tsx | 4 +- web/hooks/use-sub-issue.tsx | 8 +- web/hooks/use-user-auth.tsx | 7 +- web/hooks/use-user.tsx | 7 +- web/hooks/use-workspace-details.tsx | 4 +- web/hooks/use-workspace-members.tsx | 20 +- web/hooks/use-workspaces.tsx | 4 +- .../project-authorization-wrapper.tsx | 7 +- .../user-authorization-wrapper.tsx | 5 +- .../workspace-authorization-wrapper.tsx | 81 +++-- web/layouts/auth-layout/user-wrapper.tsx | 5 +- web/layouts/web-view-layout/index.tsx | 9 +- .../profile/[userId]/index.tsx | 14 +- .../archived-issues/[archivedIssueId].tsx | 16 +- .../[projectId]/archived-issues/index.tsx | 5 +- .../projects/[projectId]/cycles/[cycleId].tsx | 18 +- .../[projectId]/draft-issues/index.tsx | 6 +- .../projects/[projectId]/issues/[issueId].tsx | 11 +- .../projects/[projectId]/issues/index.tsx | 5 +- .../[projectId]/modules/[moduleId].tsx | 16 +- .../projects/[projectId]/modules/index.tsx | 13 +- .../projects/[projectId]/pages/[pageId].tsx | 32 +- .../projects/[projectId]/pages/index.tsx | 5 +- .../[projectId]/settings/automations.tsx | 5 +- .../[projectId]/settings/estimates.tsx | 13 +- .../projects/[projectId]/settings/index.tsx | 13 +- .../projects/[projectId]/settings/states.tsx | 9 +- .../[workspaceSlug]/settings/imports.tsx | 5 +- web/pages/[workspaceSlug]/settings/index.tsx | 8 +- .../[workspaceSlug]/settings/members.tsx | 5 +- web/pages/_error.tsx | 7 +- web/pages/accounts/magic-sign-in.tsx | 10 +- web/pages/accounts/reset-password.tsx | 6 +- web/pages/accounts/sign-up.tsx | 9 +- .../projects/[projectId]/issues/[issueId].tsx | 31 +- 108 files changed, 643 insertions(+), 1661 deletions(-) delete mode 100644 web/components/views/single-view-item.tsx delete mode 100644 web/components/workspace/views/delete-workspace-view-modal.tsx delete mode 100644 web/components/workspace/views/global-select-filters.tsx delete mode 100644 web/components/workspace/views/single-workspace-view-item.tsx delete mode 100644 web/components/workspace/views/workpace-view-navigation.tsx delete mode 100644 web/contexts/workspace-view-context.tsx diff --git a/web/components/issues/comment/add-comment.tsx b/web/components/issues/comment/add-comment.tsx index 56c809f201e..87d391f0107 100644 --- a/web/components/issues/comment/add-comment.tsx +++ b/web/components/issues/comment/add-comment.tsx @@ -1,7 +1,9 @@ import React from "react"; import { useRouter } from "next/router"; -// react-hook-form import { useForm, Controller } from "react-hook-form"; + +// services +import { FileService } from "services/file.service"; // components import { LiteTextEditorWithRef } from "@plane/lite-text-editor"; // ui @@ -9,8 +11,6 @@ import { Icon } from "components/ui"; import { Button, Tooltip } from "@plane/ui"; // types import type { IIssueComment } from "types"; -// services -import fileService from "services/file.service"; const defaultValues: Partial = { access: "INTERNAL", @@ -41,6 +41,9 @@ const commentAccess: commentAccessType[] = [ }, ]; +// services +const fileService = new FileService(); + export const AddComment: React.FC = ({ disabled = false, onSubmit, showAccessSpecifier = false }) => { const editorRef = React.useRef(null); diff --git a/web/components/issues/select/state.tsx b/web/components/issues/select/state.tsx index 48fe0ee04d5..b7424a52bb5 100644 --- a/web/components/issues/select/state.tsx +++ b/web/components/issues/select/state.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import stateService from "services/project.service/project_state.service"; +import { ProjectStateService } from "services/project"; // ui import { CustomSearchSelect } from "components/ui"; // icons @@ -23,6 +23,9 @@ type Props = { projectId: string; }; +// services +const projectStateService = new ProjectStateService(); + export const IssueStateSelect: React.FC = ({ setIsOpen, value, onChange, projectId }) => { // states const router = useRouter(); @@ -30,7 +33,7 @@ export const IssueStateSelect: React.FC = ({ setIsOpen, value, onChange, const { data: stateGroups } = useSWR( workspaceSlug && projectId ? STATES_LIST(projectId) : null, - workspaceSlug && projectId ? () => stateService.getStates(workspaceSlug as string, projectId) : null + workspaceSlug && projectId ? () => projectStateService.getStates(workspaceSlug as string, projectId) : null ); const states = getStatesList(stateGroups); diff --git a/web/components/issues/sidebar-select/assignee.tsx b/web/components/issues/sidebar-select/assignee.tsx index 9806cf2bc72..05fe6424332 100644 --- a/web/components/issues/sidebar-select/assignee.tsx +++ b/web/components/issues/sidebar-select/assignee.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // ui import { CustomSearchSelect } from "components/ui"; import { AssigneesList, Avatar } from "components/ui/avatar"; @@ -18,6 +18,9 @@ type Props = { disabled?: boolean; }; +// services +const projectService = new ProjectService(); + export const SidebarAssigneeSelect: React.FC = ({ value, onChange, disabled = false }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; diff --git a/web/components/issues/sidebar-select/blocked.tsx b/web/components/issues/sidebar-select/blocked.tsx index c47b5bbc3d7..3db9c718459 100644 --- a/web/components/issues/sidebar-select/blocked.tsx +++ b/web/components/issues/sidebar-select/blocked.tsx @@ -7,7 +7,7 @@ import { UseFormWatch } from "react-hook-form"; import useToast from "hooks/use-toast"; import useUser from "hooks/use-user"; // services -import issuesService from "services/issue/issue.service"; +import { IssueService } from "services/issue"; // components import { ExistingIssuesListModal } from "components/core"; // icons @@ -23,6 +23,9 @@ type Props = { disabled?: boolean; }; +// services +const issueService = new IssueService(); + export const SidebarBlockedSelect: React.FC = ({ issueId, submitChanges, watch, disabled = false }) => { const [isBlockedModalOpen, setIsBlockedModalOpen] = useState(false); @@ -64,7 +67,7 @@ export const SidebarBlockedSelect: React.FC = ({ issueId, submitChanges, if (!user) return; - issuesService + issueService .createIssueRelation(workspaceSlug as string, projectId as string, issueId as string, user, { related_list: [ ...selectedIssues.map((issue) => ({ @@ -127,7 +130,7 @@ export const SidebarBlockedSelect: React.FC = ({ issueId, submitChanges, if (!user) return; - issuesService.deleteIssueRelation( + issueService.deleteIssueRelation( workspaceSlug as string, projectId as string, issueId as string, diff --git a/web/components/issues/sidebar-select/blocker.tsx b/web/components/issues/sidebar-select/blocker.tsx index 7305b14a716..8d174e44879 100644 --- a/web/components/issues/sidebar-select/blocker.tsx +++ b/web/components/issues/sidebar-select/blocker.tsx @@ -10,7 +10,7 @@ import useUser from "hooks/use-user"; // components import { ExistingIssuesListModal } from "components/core"; // services -import issuesService from "services/issue/issue.service"; +import { IssueService } from "services/issue"; // icons import { XMarkIcon } from "@heroicons/react/24/outline"; import { BlockerIcon } from "components/icons"; @@ -24,6 +24,9 @@ type Props = { disabled?: boolean; }; +// services +const issueService = new IssueService(); + export const SidebarBlockerSelect: React.FC = ({ issueId, submitChanges, watch, disabled = false }) => { const [isBlockerModalOpen, setIsBlockerModalOpen] = useState(false); @@ -65,7 +68,7 @@ export const SidebarBlockerSelect: React.FC = ({ issueId, submitChanges, if (!user) return; - issuesService + issueService .createIssueRelation(workspaceSlug as string, projectId as string, issueId as string, user, { related_list: [ ...selectedIssues.map((issue) => ({ @@ -137,7 +140,7 @@ export const SidebarBlockerSelect: React.FC = ({ issueId, submitChanges, if (!user) return; - issuesService.deleteIssueRelation( + issueService.deleteIssueRelation( workspaceSlug as string, projectId as string, relation.issue_detail?.id as string, diff --git a/web/components/issues/sidebar-select/cycle.tsx b/web/components/issues/sidebar-select/cycle.tsx index cc8dd36a2b3..47ad5aecccd 100644 --- a/web/components/issues/sidebar-select/cycle.tsx +++ b/web/components/issues/sidebar-select/cycle.tsx @@ -5,8 +5,8 @@ import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; // services -import issuesService from "services/issue/issue.service"; -import cyclesService from "services/cycle.service"; +import { IssueService } from "services/issue"; +import { CycleService } from "services/cycle.service"; // ui import { CustomSelect } from "components/ui"; import { Spinner, Tooltip } from "@plane/ui"; @@ -23,6 +23,10 @@ type Props = { disabled?: boolean; }; +// services +const issueService = new IssueService(); +const cycleService = new CycleService(); + export const SidebarCycleSelect: React.FC = ({ issueDetail, handleCycleChange, disabled = false }) => { const router = useRouter(); const { workspaceSlug, projectId, issueId } = router.query; @@ -30,14 +34,14 @@ export const SidebarCycleSelect: React.FC = ({ issueDetail, handleCycleCh const { data: incompleteCycles } = useSWR( workspaceSlug && projectId ? INCOMPLETE_CYCLES_LIST(projectId as string) : null, workspaceSlug && projectId - ? () => cyclesService.getCyclesWithParams(workspaceSlug as string, projectId as string, "incomplete") + ? () => cycleService.getCyclesWithParams(workspaceSlug as string, projectId as string, "incomplete") : null ); const removeIssueFromCycle = (bridgeId: string, cycleId: string) => { if (!workspaceSlug || !projectId) return; - issuesService + issueService .removeIssueFromCycle(workspaceSlug as string, projectId as string, cycleId, bridgeId) .then(() => { mutate(ISSUE_DETAILS(issueId as string)); diff --git a/web/components/issues/sidebar-select/duplicate.tsx b/web/components/issues/sidebar-select/duplicate.tsx index 1c2f537dca6..976dae14bbc 100644 --- a/web/components/issues/sidebar-select/duplicate.tsx +++ b/web/components/issues/sidebar-select/duplicate.tsx @@ -12,7 +12,7 @@ import { X, CopyPlus } from "lucide-react"; import { BlockerIcon } from "components/icons"; import { ExistingIssuesListModal } from "components/core"; // services -import issuesService from "services/issue/issue.service"; +import { IssueService } from "services/issue"; // types import { BlockeIssueDetail, IIssue, ISearchIssueResponse } from "types"; @@ -23,6 +23,9 @@ type Props = { disabled?: boolean; }; +// services +const issueService = new IssueService(); + export const SidebarDuplicateSelect: React.FC = (props) => { const { issueId, submitChanges, watch, disabled = false } = props; @@ -64,7 +67,7 @@ export const SidebarDuplicateSelect: React.FC = (props) => { if (!user) return; - issuesService + issueService .createIssueRelation(workspaceSlug as string, projectId as string, issueId as string, user, { related_list: [ ...selectedIssues.map((issue) => ({ @@ -130,7 +133,7 @@ export const SidebarDuplicateSelect: React.FC = (props) => { onClick={() => { if (!user) return; - issuesService + issueService .deleteIssueRelation( workspaceSlug as string, projectId as string, diff --git a/web/components/issues/sidebar-select/state.tsx b/web/components/issues/sidebar-select/state.tsx index 5f2a33bb999..ca62831b659 100644 --- a/web/components/issues/sidebar-select/state.tsx +++ b/web/components/issues/sidebar-select/state.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import stateService from "services/project.service/project_state.service"; +import { ProjectStateService } from "services/project"; // ui import { CustomSelect } from "components/ui"; import { Spinner } from "@plane/ui"; @@ -23,6 +23,9 @@ type Props = { disabled?: boolean; }; +// services +const stateService = new ProjectStateService(); + export const SidebarStateSelect: React.FC = ({ value, onChange, disabled = false }) => { const router = useRouter(); const { workspaceSlug, projectId, inboxIssueId } = router.query; diff --git a/web/components/labels/delete-label-modal.tsx b/web/components/labels/delete-label-modal.tsx index 07f234d0f5a..85dd1038766 100644 --- a/web/components/labels/delete-label-modal.tsx +++ b/web/components/labels/delete-label-modal.tsx @@ -9,7 +9,7 @@ import { Dialog, Transition } from "@headlessui/react"; // icons import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; // services -import issuesService from "services/issue/issue.service"; +import { IssueLabelService } from "services/issue"; // hooks import useToast from "hooks/use-toast"; // ui @@ -26,6 +26,9 @@ type Props = { user: ICurrentUserResponse | undefined; }; +// services +const issueLabelService = new IssueLabelService(); + export const DeleteLabelModal: React.FC = ({ isOpen, onClose, data, user }) => { const [isDeleteLoading, setIsDeleteLoading] = useState(false); @@ -50,7 +53,7 @@ export const DeleteLabelModal: React.FC = ({ isOpen, onClose, data, user false ); - await issuesService + await issueLabelService .deleteIssueLabel(workspaceSlug.toString(), projectId.toString(), data.id, user) .then(() => handleClose()) .catch(() => { diff --git a/web/components/labels/single-label-group.tsx b/web/components/labels/single-label-group.tsx index 8fdd4f676ec..c03dfd5f65f 100644 --- a/web/components/labels/single-label-group.tsx +++ b/web/components/labels/single-label-group.tsx @@ -7,7 +7,7 @@ import { mutate } from "swr"; // headless ui import { Disclosure, Transition } from "@headlessui/react"; // services -import issuesService from "services/issue/issue.service"; +import { IssueLabelService } from "services/issue"; // ui import { CustomMenu } from "components/ui"; // icons @@ -27,6 +27,9 @@ type Props = { user: ICurrentUserResponse | undefined; }; +// services +const issueLabelService = new IssueLabelService(); + export const SingleLabelGroup: React.FC = ({ label, labelChildren, @@ -52,7 +55,7 @@ export const SingleLabelGroup: React.FC = ({ false ); - issuesService + issueLabelService .patchIssueLabel( workspaceSlug as string, projectId as string, diff --git a/web/components/modules/delete-module-modal.tsx b/web/components/modules/delete-module-modal.tsx index 2d44bce290a..e9434ec3223 100644 --- a/web/components/modules/delete-module-modal.tsx +++ b/web/components/modules/delete-module-modal.tsx @@ -7,7 +7,7 @@ import { mutate } from "swr"; // headless ui import { Dialog, Transition } from "@headlessui/react"; // services -import modulesService from "services/module.service"; +import { ModuleService } from "services/module.service"; // hooks import useToast from "hooks/use-toast"; // ui @@ -26,6 +26,9 @@ type Props = { user: ICurrentUserResponse | undefined; }; +// services +const moduleService = new ModuleService(); + export const DeleteModuleModal: React.FC = ({ isOpen, setIsOpen, data, user }) => { const [isDeleteLoading, setIsDeleteLoading] = useState(false); @@ -46,7 +49,7 @@ export const DeleteModuleModal: React.FC = ({ isOpen, setIsOpen, data, us mutate(MODULE_LIST(projectId as string), (prevData) => prevData?.filter((m) => m.id !== data.id), false); - await modulesService + await moduleService .deleteModule(workspaceSlug as string, projectId as string, data.id, user) .then(() => { if (moduleId) router.push(`/${workspaceSlug}/projects/${data.project}/modules`); diff --git a/web/components/modules/gantt-chart/modules-list-layout.tsx b/web/components/modules/gantt-chart/modules-list-layout.tsx index 67b46c7312d..f25b769212b 100644 --- a/web/components/modules/gantt-chart/modules-list-layout.tsx +++ b/web/components/modules/gantt-chart/modules-list-layout.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import { KeyedMutator } from "swr"; // services -import modulesService from "services/module.service"; +import { ModuleService } from "services/module.service"; // hooks import useUser from "hooks/use-user"; import useProjectDetails from "hooks/use-project-details"; @@ -20,6 +20,9 @@ type Props = { mutateModules: KeyedMutator; }; +// services +const moduleService = new ModuleService(); + export const ModulesListGanttChartView: FC = ({ modules, mutateModules }) => { const router = useRouter(); const { workspaceSlug } = router.query; @@ -56,7 +59,7 @@ export const ModulesListGanttChartView: FC = ({ modules, mutateModules }) if (newPayload.sort_order && payload.sort_order) newPayload.sort_order = payload.sort_order.newSortOrder; - modulesService.patchModule(workspaceSlug.toString(), module.project, module.id, newPayload, user); + moduleService.patchModule(workspaceSlug.toString(), module.project, module.id, newPayload, user); }; const blockFormat = (blocks: IModule[]) => diff --git a/web/components/modules/sidebar-select/select-members.tsx b/web/components/modules/sidebar-select/select-members.tsx index 2a83279554f..b37acc4c10f 100644 --- a/web/components/modules/sidebar-select/select-members.tsx +++ b/web/components/modules/sidebar-select/select-members.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // ui import { AssigneesList, Avatar, CustomSearchSelect } from "components/ui"; // icons @@ -18,6 +18,9 @@ type Props = { onChange: (val: string[]) => void; }; +// services +const projectService = new ProjectService(); + export const SidebarMembersSelect: React.FC = ({ value, onChange }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; diff --git a/web/components/onboarding/invite-members.tsx b/web/components/onboarding/invite-members.tsx index cf05bc9aeb4..e97fdc11761 100644 --- a/web/components/onboarding/invite-members.tsx +++ b/web/components/onboarding/invite-members.tsx @@ -5,7 +5,7 @@ import { Listbox, Transition } from "@headlessui/react"; // react-hook-form import { Control, Controller, FieldArrayWithId, UseFieldArrayRemove, useFieldArray, useForm } from "react-hook-form"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // hooks import useToast from "hooks/use-toast"; // ui @@ -45,6 +45,9 @@ type InviteMemberFormProps = { errors: any; }; +// services +const workspaceService = new WorkspaceService(); + const InviteMemberForm: React.FC = (props) => { const { control, index, fields, remove, errors } = props; diff --git a/web/components/onboarding/join-workspaces.tsx b/web/components/onboarding/join-workspaces.tsx index 43828961728..736480b556c 100644 --- a/web/components/onboarding/join-workspaces.tsx +++ b/web/components/onboarding/join-workspaces.tsx @@ -3,7 +3,7 @@ import React, { useState } from "react"; import useSWR, { mutate } from "swr"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // hooks import useUser from "hooks/use-user"; // ui @@ -25,6 +25,9 @@ type Props = { updateLastWorkspace: () => Promise; }; +// services +const workspaceService = new WorkspaceService(); + export const JoinWorkspaces: React.FC = ({ finishOnboarding, stepChange, updateLastWorkspace }) => { const [isJoiningWorkspaces, setIsJoiningWorkspaces] = useState(false); const [invitationsRespond, setInvitationsRespond] = useState([]); diff --git a/web/components/pages/create-update-block-inline.tsx b/web/components/pages/create-update-block-inline.tsx index f1bbc36138f..f87b1e6f3dc 100644 --- a/web/components/pages/create-update-block-inline.tsx +++ b/web/components/pages/create-update-block-inline.tsx @@ -4,9 +4,10 @@ import { mutate } from "swr"; import { SparklesIcon } from "@heroicons/react/24/outline"; import { Controller, useForm } from "react-hook-form"; // services -import PageService from "services/page.service"; -import IssueService from "services/issue/issue.service"; -import AIService from "services/ai.service"; +import { PageService } from "services/page.service"; +import { IssueService } from "services/issue/issue.service"; +import { AIService } from "services/ai.service"; +import { FileService } from "services/file.service"; // hooks import useToast from "hooks/use-toast"; // components @@ -17,8 +18,6 @@ import { RichTextEditorWithRef } from "@plane/rich-text-editor"; import { IUser, IPageBlock } from "types"; // fetch-keys import { PAGE_BLOCKS_LIST } from "constants/fetch-keys"; -// services -import fileService from "services/file.service"; type Props = { handleClose: () => void; @@ -38,6 +37,7 @@ const defaultValues = { const aiService = new AIService(); const pagesService = new PageService(); const issueService = new IssueService(); +const fileService = new FileService(); export const CreateUpdateBlockInline: FC = ({ handleClose, diff --git a/web/components/pages/create-update-page-modal.tsx b/web/components/pages/create-update-page-modal.tsx index 6a691274705..af4ddc0e799 100644 --- a/web/components/pages/create-update-page-modal.tsx +++ b/web/components/pages/create-update-page-modal.tsx @@ -7,7 +7,7 @@ import { mutate } from "swr"; // headless ui import { Dialog, Transition } from "@headlessui/react"; // services -import pagesService from "services/page.service"; +import { PageService } from "services/page.service"; // hooks import useToast from "hooks/use-toast"; // components @@ -24,6 +24,9 @@ type Props = { user: ICurrentUserResponse | undefined; }; +// services +const pageService = new PageService(); + export const CreateUpdatePageModal: React.FC = ({ isOpen, handleClose, data, user }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -35,7 +38,7 @@ export const CreateUpdatePageModal: React.FC = ({ isOpen, handleClose, da }; const createPage = async (payload: IPage) => { - await pagesService + await pageService .createPage(workspaceSlug as string, projectId as string, payload, user) .then((res) => { mutate(RECENT_PAGES_LIST(projectId as string)); @@ -77,7 +80,7 @@ export const CreateUpdatePageModal: React.FC = ({ isOpen, handleClose, da }; const updatePage = async (payload: IPage) => { - await pagesService + await pageService .patchPage(workspaceSlug as string, projectId as string, data?.id ?? "", payload, user) .then((res) => { mutate(RECENT_PAGES_LIST(projectId as string)); diff --git a/web/components/pages/delete-page-modal.tsx b/web/components/pages/delete-page-modal.tsx index 9b2d5d4538b..9317fa5533c 100644 --- a/web/components/pages/delete-page-modal.tsx +++ b/web/components/pages/delete-page-modal.tsx @@ -7,7 +7,7 @@ import { mutate } from "swr"; // headless ui import { Dialog, Transition } from "@headlessui/react"; // services -import pagesService from "services/page.service"; +import { PageService } from "services/page.service"; // hooks import useToast from "hooks/use-toast"; // ui @@ -26,6 +26,9 @@ type TConfirmPageDeletionProps = { user: ICurrentUserResponse | undefined; }; +// services +const pageService = new PageService(); + export const DeletePageModal: React.FC = ({ isOpen, setIsOpen, data, user }) => { const [isDeleteLoading, setIsDeleteLoading] = useState(false); @@ -43,7 +46,7 @@ export const DeletePageModal: React.FC = ({ isOpen, s setIsDeleteLoading(true); if (!data || !workspaceSlug || !projectId) return; - await pagesService + await pageService .deletePage(workspaceSlug as string, data.project, data.id, user) .then(() => { mutate(RECENT_PAGES_LIST(projectId as string)); diff --git a/web/components/pages/pages-list/all-pages-list.tsx b/web/components/pages/pages-list/all-pages-list.tsx index 353fa7b8770..22460f734ba 100644 --- a/web/components/pages/pages-list/all-pages-list.tsx +++ b/web/components/pages/pages-list/all-pages-list.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import pagesService from "services/page.service"; +import { PageService } from "services/page.service"; // components import { PagesView } from "components/pages"; // types @@ -11,6 +11,9 @@ import { TPagesListProps } from "./types"; // fetch-keys import { ALL_PAGES_LIST } from "constants/fetch-keys"; +// services +const pageService = new PageService(); + export const AllPagesList: React.FC = ({ viewType }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -18,7 +21,7 @@ export const AllPagesList: React.FC = ({ viewType }) => { const { data: pages } = useSWR( workspaceSlug && projectId ? ALL_PAGES_LIST(projectId as string) : null, workspaceSlug && projectId - ? () => pagesService.getPagesWithParams(workspaceSlug as string, projectId as string, "all") + ? () => pageService.getPagesWithParams(workspaceSlug as string, projectId as string, "all") : null ); diff --git a/web/components/pages/pages-list/favorite-pages-list.tsx b/web/components/pages/pages-list/favorite-pages-list.tsx index e6ba8ec321d..ef50f296a9d 100644 --- a/web/components/pages/pages-list/favorite-pages-list.tsx +++ b/web/components/pages/pages-list/favorite-pages-list.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import pagesService from "services/page.service"; +import { PageService } from "services/page.service"; // components import { PagesView } from "components/pages"; // types @@ -11,6 +11,9 @@ import { TPagesListProps } from "./types"; // fetch-keys import { FAVORITE_PAGES_LIST } from "constants/fetch-keys"; +// services +const pageService = new PageService(); + export const FavoritePagesList: React.FC = ({ viewType }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -18,7 +21,7 @@ export const FavoritePagesList: React.FC = ({ viewType }) => { const { data: pages } = useSWR( workspaceSlug && projectId ? FAVORITE_PAGES_LIST(projectId as string) : null, workspaceSlug && projectId - ? () => pagesService.getPagesWithParams(workspaceSlug as string, projectId as string, "favorite") + ? () => pageService.getPagesWithParams(workspaceSlug as string, projectId as string, "favorite") : null ); diff --git a/web/components/pages/pages-list/my-pages-list.tsx b/web/components/pages/pages-list/my-pages-list.tsx index 2bd4a20178a..889ffa3b6be 100644 --- a/web/components/pages/pages-list/my-pages-list.tsx +++ b/web/components/pages/pages-list/my-pages-list.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import pagesService from "services/page.service"; +import { PageService } from "services/page.service"; // components import { PagesView } from "components/pages"; // types @@ -11,6 +11,9 @@ import { TPagesListProps } from "./types"; // fetch-keys import { MY_PAGES_LIST } from "constants/fetch-keys"; +// services +const pageService = new PageService(); + export const MyPagesList: React.FC = ({ viewType }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -18,7 +21,7 @@ export const MyPagesList: React.FC = ({ viewType }) => { const { data: pages } = useSWR( workspaceSlug && projectId ? MY_PAGES_LIST(projectId as string) : null, workspaceSlug && projectId - ? () => pagesService.getPagesWithParams(workspaceSlug as string, projectId as string, "created_by_me") + ? () => pageService.getPagesWithParams(workspaceSlug as string, projectId as string, "created_by_me") : null ); diff --git a/web/components/pages/pages-list/other-pages-list.tsx b/web/components/pages/pages-list/other-pages-list.tsx index 72729f9e2da..176bd6cf5ca 100644 --- a/web/components/pages/pages-list/other-pages-list.tsx +++ b/web/components/pages/pages-list/other-pages-list.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import pagesService from "services/page.service"; +import { PageService } from "services/page.service"; // components import { PagesView } from "components/pages"; // types @@ -11,6 +11,9 @@ import { TPagesListProps } from "./types"; // fetch-keys import { OTHER_PAGES_LIST } from "constants/fetch-keys"; +// services +const pageService = new PageService(); + export const OtherPagesList: React.FC = ({ viewType }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -18,7 +21,7 @@ export const OtherPagesList: React.FC = ({ viewType }) => { const { data: pages } = useSWR( workspaceSlug && projectId ? OTHER_PAGES_LIST(projectId as string) : null, workspaceSlug && projectId - ? () => pagesService.getPagesWithParams(workspaceSlug as string, projectId as string, "created_by_other") + ? () => pageService.getPagesWithParams(workspaceSlug as string, projectId as string, "created_by_other") : null ); diff --git a/web/components/pages/pages-list/recent-pages-list.tsx b/web/components/pages/pages-list/recent-pages-list.tsx index f302d607b23..9f89fb486f5 100644 --- a/web/components/pages/pages-list/recent-pages-list.tsx +++ b/web/components/pages/pages-list/recent-pages-list.tsx @@ -5,11 +5,11 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import pagesService from "services/page.service"; +import { PageService } from "services/page.service"; // components import { PagesView } from "components/pages"; // ui -import { EmptyState } from "components/ui"; +import { EmptyState } from "components/common"; import { Loader } from "@plane/ui"; // icons import { PlusIcon } from "@heroicons/react/24/outline"; @@ -23,13 +23,16 @@ import { RecentPagesResponse } from "types"; // fetch-keys import { RECENT_PAGES_LIST } from "constants/fetch-keys"; +// services +const pageService = new PageService(); + export const RecentPagesList: React.FC = ({ viewType }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; const { data: pages } = useSWR( workspaceSlug && projectId ? RECENT_PAGES_LIST(projectId as string) : null, - workspaceSlug && projectId ? () => pagesService.getRecentPages(workspaceSlug as string, projectId as string) : null + workspaceSlug && projectId ? () => pageService.getRecentPages(workspaceSlug as string, projectId as string) : null ); const isEmpty = pages && Object.keys(pages).every((key) => pages[key].length === 0); diff --git a/web/components/pages/pages-view.tsx b/web/components/pages/pages-view.tsx index e53c8a476b3..942b68ba8cc 100644 --- a/web/components/pages/pages-view.tsx +++ b/web/components/pages/pages-view.tsx @@ -4,15 +4,15 @@ import useSWR, { mutate } from "swr"; import { useRouter } from "next/router"; // services -import pagesService from "services/page.service"; -import projectService from "services/project.service/project.service"; +import { PageService } from "services/page.service"; +import { ProjectService } from "services/project"; // hooks import useToast from "hooks/use-toast"; import useUserAuth from "hooks/use-user-auth"; // components import { CreateUpdatePageModal, DeletePageModal, SinglePageDetailedItem, SinglePageListItem } from "components/pages"; // ui -import { EmptyState } from "components/ui"; +import { EmptyState } from "components/common"; import { Loader } from "@plane/ui"; // icons import { PlusIcon } from "@heroicons/react/24/outline"; @@ -33,6 +33,10 @@ type Props = { viewType: TPageViewProps; }; +// services +const pageService = new PageService(); +const projectService = new ProjectService(); + export const PagesView: React.FC = ({ pages, viewType }) => { const [createUpdatePageModal, setCreateUpdatePageModal] = useState(false); const [selectedPageToUpdate, setSelectedPageToUpdate] = useState(null); @@ -89,7 +93,7 @@ export const PagesView: React.FC = ({ pages, viewType }) => { ); mutate(FAVORITE_PAGES_LIST(projectId.toString()), (prevData) => [page, ...(prevData ?? [])], false); - pagesService + pageService .addPageToFavorites(workspaceSlug.toString(), projectId.toString(), { page: page.id, }) @@ -139,7 +143,7 @@ export const PagesView: React.FC = ({ pages, viewType }) => { false ); - pagesService + pageService .removePageFromFavorites(workspaceSlug.toString(), projectId.toString(), page.id) .then(() => { mutate(RECENT_PAGES_LIST(projectId.toString())); @@ -177,7 +181,7 @@ export const PagesView: React.FC = ({ pages, viewType }) => { false ); - pagesService.patchPage(workspaceSlug.toString(), projectId.toString(), page.id, formData, user).then(() => { + pageService.patchPage(workspaceSlug.toString(), projectId.toString(), page.id, formData, user).then(() => { mutate(RECENT_PAGES_LIST(projectId.toString())); }); }; diff --git a/web/components/pages/single-page-block.tsx b/web/components/pages/single-page-block.tsx index 8960c394c18..ffad1a20092 100644 --- a/web/components/pages/single-page-block.tsx +++ b/web/components/pages/single-page-block.tsx @@ -5,9 +5,10 @@ import { mutate } from "swr"; import { useForm } from "react-hook-form"; import { Draggable } from "react-beautiful-dnd"; // services -import PageService from "services/page.service"; -import IssueService from "services/issue/issue.service"; -import AIService from "services/ai.service"; +import { PageService } from "services/page.service"; +import { IssueService } from "services/issue/issue.service"; +import { AIService } from "services/ai.service"; +import { FileService } from "services/file.service"; // hooks import useToast from "hooks/use-toast"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; @@ -35,7 +36,6 @@ import { copyTextToClipboard } from "helpers/string.helper"; import { IUser, IIssue, IPageBlock, IProject } from "types"; // fetch-keys import { PAGE_BLOCKS_LIST } from "constants/fetch-keys"; -import fileService from "services/file.service"; type Props = { block: IPageBlock; @@ -48,6 +48,7 @@ type Props = { const aiService = new AIService(); const pageService = new PageService(); const issueService = new IssueService(); +const fileService = new FileService(); export const SinglePageBlock: React.FC = ({ block, projectDetails, showBlockDetails, index, user }) => { const [isSyncing, setIsSyncing] = useState(false); diff --git a/web/components/profile/overview/activity.tsx b/web/components/profile/overview/activity.tsx index e2cc01c8f24..9a4973aaabb 100644 --- a/web/components/profile/overview/activity.tsx +++ b/web/components/profile/overview/activity.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import userService from "services/user.service"; +import { UserService } from "services/user.service"; // components import { ActivityMessage } from "components/core"; // ui @@ -16,6 +16,9 @@ import { timeAgo } from "helpers/date-time.helper"; // fetch-keys import { USER_PROFILE_ACTIVITY } from "constants/fetch-keys"; +// services +const userService = new UserService(); + export const ProfileActivity = () => { const router = useRouter(); const { workspaceSlug, userId } = router.query; diff --git a/web/components/profile/profile-issues-view.tsx b/web/components/profile/profile-issues-view.tsx index 14bc0f3012b..6c3cac11b49 100644 --- a/web/components/profile/profile-issues-view.tsx +++ b/web/components/profile/profile-issues-view.tsx @@ -7,8 +7,8 @@ import useSWR from "swr"; // react-beautiful-dnd import { DropResult } from "react-beautiful-dnd"; // services -import issuesService from "services/issue/issue.service"; -import userService from "services/user.service"; +import { IssueService, IssueLabelService } from "services/issue"; +import { UserService } from "services/user.service"; // hooks import useProfileIssues from "hooks/use-profile-issues"; import useUser from "hooks/use-user"; @@ -22,6 +22,11 @@ import { IIssue, IIssueFilterOptions, TIssuePriorities } from "types"; // fetch-keys import { USER_PROFILE_PROJECT_SEGREGATION, WORKSPACE_LABELS } from "constants/fetch-keys"; +// services +const issueService = new IssueService(); +const issueLabelService = new IssueLabelService(); +const userService = new UserService(); + export const ProfileIssuesView = () => { // create issue modal const [createIssueModal, setCreateIssueModal] = useState(false); @@ -66,7 +71,7 @@ export const ProfileIssuesView = () => { const { data: labels } = useSWR( workspaceSlug && (filters?.labels ?? []).length > 0 ? WORKSPACE_LABELS(workspaceSlug.toString()) : null, workspaceSlug && (filters?.labels ?? []).length > 0 - ? () => issuesService.getWorkspaceLabels(workspaceSlug.toString()) + ? () => issueLabelService.getWorkspaceIssueLabels(workspaceSlug.toString()) : null ); @@ -116,7 +121,7 @@ export const ProfileIssuesView = () => { }, false); // patch request - issuesService + issueService .patchIssue( workspaceSlug as string, draggedItem.project, diff --git a/web/components/profile/sidebar.tsx b/web/components/profile/sidebar.tsx index 1cccaf5a2a4..9284174869a 100644 --- a/web/components/profile/sidebar.tsx +++ b/web/components/profile/sidebar.tsx @@ -6,7 +6,7 @@ import useSWR from "swr"; // headless ui import { Disclosure, Transition } from "@headlessui/react"; // services -import userService from "services/user.service"; +import { UserService } from "services/user.service"; // hooks import useUser from "hooks/use-user"; // ui @@ -20,6 +20,9 @@ import { renderEmoji } from "helpers/emoji.helper"; // fetch-keys import { USER_PROFILE_PROJECT_SEGREGATION } from "constants/fetch-keys"; +// services +const userService = new UserService(); + export const ProfileSidebar = () => { const router = useRouter(); const { workspaceSlug, userId } = router.query; diff --git a/web/components/project/label-select.tsx b/web/components/project/label-select.tsx index 1d5b0c3333e..f5ffaef87af 100644 --- a/web/components/project/label-select.tsx +++ b/web/components/project/label-select.tsx @@ -7,7 +7,7 @@ import { useRouter } from "next/router"; // react-popper import { usePopper } from "react-popper"; // services -import issuesService from "services/issues.service"; +import { IssueLabelService } from "services/issue"; // headless ui import { Combobox } from "@headlessui/react"; // component @@ -38,6 +38,9 @@ type Props = { user: ICurrentUserResponse | undefined; }; +// services +const issueLabelService = new IssueLabelService(); + export const LabelSelect: React.FC = ({ value, projectId, @@ -70,7 +73,7 @@ export const LabelSelect: React.FC = ({ const { data: issueLabels } = useSWR( projectId && fetchStates ? PROJECT_ISSUE_LABELS(projectId) : null, workspaceSlug && projectId && fetchStates - ? () => issuesService.getIssueLabels(workspaceSlug as string, projectId) + ? () => issueLabelService.getProjectIssueLabels(workspaceSlug.toString(), projectId) : null ); diff --git a/web/components/project/member-select.tsx b/web/components/project/member-select.tsx index 0fa76ccf39a..d7de89e33bc 100644 --- a/web/components/project/member-select.tsx +++ b/web/components/project/member-select.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // ui import { Avatar, CustomSearchSelect } from "components/ui"; // icon @@ -19,6 +19,9 @@ type Props = { isDisabled?: boolean; }; +// services +const projectService = new ProjectService(); + export const MemberSelect: React.FC = ({ value, onChange, isDisabled = false }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; diff --git a/web/components/project/send-project-invitation-modal.tsx b/web/components/project/send-project-invitation-modal.tsx index c8638287dd3..ddf73f6c02b 100644 --- a/web/components/project/send-project-invitation-modal.tsx +++ b/web/components/project/send-project-invitation-modal.tsx @@ -14,8 +14,8 @@ import { Avatar, CustomSearchSelect, CustomSelect } from "components/ui"; import { PlusIcon, XMarkIcon } from "@heroicons/react/24/outline"; import { ChevronDownIcon } from "@heroicons/react/20/solid"; // services -import projectService from "services/project.service/project.service"; -import workspaceService from "services/workspace.service"; +import { ProjectService } from "services/project"; +import { WorkspaceService } from "services/workspace.service"; // contexts import { useProjectMyMembership } from "contexts/project-member.context"; // hooks @@ -53,6 +53,10 @@ const defaultValues: FormValues = { ], }; +// services +const projectService = new ProjectService(); +const workspaceService = new WorkspaceService(); + const SendProjectInvitationModal: React.FC = (props) => { const { isOpen, setIsOpen, members, user, onSuccess } = props; diff --git a/web/components/project/single-integration-card.tsx b/web/components/project/single-integration-card.tsx index ac697c4a9b6..ae916c782e9 100644 --- a/web/components/project/single-integration-card.tsx +++ b/web/components/project/single-integration-card.tsx @@ -5,7 +5,7 @@ import Image from "next/image"; import useSWR, { mutate } from "swr"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // hooks import { useRouter } from "next/router"; import useToast from "hooks/use-toast"; @@ -34,6 +34,9 @@ const integrationDetails: { [key: string]: any } = { }, }; +// services +const projectService = new ProjectService(); + export const SingleIntegration: React.FC = ({ integration }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; diff --git a/web/components/project/single-project-card.tsx b/web/components/project/single-project-card.tsx index eb88e738194..4f12dbfd01b 100644 --- a/web/components/project/single-project-card.tsx +++ b/web/components/project/single-project-card.tsx @@ -6,20 +6,13 @@ import Link from "next/link"; import { mutate } from "swr"; // services -import projectService from "services/project.service"; +import { ProjectService } from "services/project"; // hooks import useToast from "hooks/use-toast"; // ui import { CustomMenu, Tooltip } from "components/ui"; // icons -import { - CalendarDaysIcon, - LinkIcon, - PencilIcon, - PlusIcon, - StarIcon, - TrashIcon, -} from "@heroicons/react/24/outline"; +import { CalendarDaysIcon, LinkIcon, PencilIcon, PlusIcon, StarIcon, TrashIcon } from "@heroicons/react/24/outline"; // helpers import { renderShortDateWithYearFormat } from "helpers/date-time.helper"; import { copyTextToClipboard, truncateText } from "helpers/string.helper"; @@ -35,11 +28,10 @@ export type ProjectCardProps = { setDeleteProject: (id: string | null) => void; }; -export const SingleProjectCard: React.FC = ({ - project, - setToJoinProject, - setDeleteProject, -}) => { +// services +const projectService = new ProjectService(); + +export const SingleProjectCard: React.FC = ({ project, setToJoinProject, setDeleteProject }) => { const router = useRouter(); const { workspaceSlug } = router.query; @@ -53,8 +45,7 @@ export const SingleProjectCard: React.FC = ({ mutate( PROJECTS_LIST(workspaceSlug as string, { is_favorite: "all" }), - (prevData) => - (prevData ?? []).map((p) => (p.id === project.id ? { ...p, is_favorite: true } : p)), + (prevData) => (prevData ?? []).map((p) => (p.id === project.id ? { ...p, is_favorite: true } : p)), false ); @@ -83,8 +74,7 @@ export const SingleProjectCard: React.FC = ({ mutate( PROJECTS_LIST(workspaceSlug as string, { is_favorite: "all" }), - (prevData) => - (prevData ?? []).map((p) => (p.id === project.id ? { ...p, is_favorite: false } : p)), + (prevData) => (prevData ?? []).map((p) => (p.id === project.id ? { ...p, is_favorite: false } : p)), false ); @@ -107,8 +97,7 @@ export const SingleProjectCard: React.FC = ({ }; const handleCopyText = () => { - const originURL = - typeof window !== "undefined" && window.location.origin ? window.location.origin : ""; + const originURL = typeof window !== "undefined" && window.location.origin ? window.location.origin : ""; copyTextToClipboard(`${originURL}/${workspaceSlug}/projects/${project.id}/issues`).then(() => { setToastAlert({ @@ -148,9 +137,7 @@ export const SingleProjectCard: React.FC = ({ Select to Join ) : ( - - Joined - + Joined )} {project.is_favorite && ( @@ -174,9 +161,7 @@ export const SingleProjectCard: React.FC = ({ renderEmoji(project.icon_prop) ) : null} -

- {truncateText(project.description ?? "", 100)} -

+

{truncateText(project.description ?? "", 100)}

diff --git a/web/components/states/create-update-state-inline.tsx b/web/components/states/create-update-state-inline.tsx index e148e336c88..d5d0d9739c1 100644 --- a/web/components/states/create-update-state-inline.tsx +++ b/web/components/states/create-update-state-inline.tsx @@ -11,7 +11,7 @@ import { TwitterPicker } from "react-color"; // headless ui import { Popover, Transition } from "@headlessui/react"; // services -import ProjectStateService from "services/project.service/project_state.service"; +import { ProjectStateService } from "services/project"; // hooks import useToast from "hooks/use-toast"; // ui diff --git a/web/components/states/single-state.tsx b/web/components/states/single-state.tsx index 222a8379cc3..f7a6c35100b 100644 --- a/web/components/states/single-state.tsx +++ b/web/components/states/single-state.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import { mutate } from "swr"; // services -import stateService from "services/project.service/project_state.service"; +import { ProjectStateService } from "services/project"; // ui import { Tooltip } from "@plane/ui"; // icons @@ -31,6 +31,9 @@ type Props = { user: ICurrentUserResponse | undefined; }; +// services +const projectStateService = new ProjectStateService(); + export const SingleState: React.FC = ({ index, state, @@ -61,7 +64,7 @@ export const SingleState: React.FC = ({ mutate(STATES_LIST(projectId as string), orderStateGroups(groupBy(newStatesList, "group")), false); if (currentDefaultState) - stateService + projectStateService .patchState( workspaceSlug as string, projectId as string, @@ -72,7 +75,7 @@ export const SingleState: React.FC = ({ user ) .then(() => { - stateService + projectStateService .patchState( workspaceSlug as string, projectId as string, @@ -91,7 +94,7 @@ export const SingleState: React.FC = ({ }); }); else - stateService + projectStateService .patchState( workspaceSlug as string, projectId as string, @@ -129,7 +132,7 @@ export const SingleState: React.FC = ({ mutate(STATES_LIST(projectId as string), orderStateGroups(groupBy(newStatesList, "group")), false); - stateService + projectStateService .patchState( workspaceSlug as string, projectId as string, diff --git a/web/components/states/state-select.tsx b/web/components/states/state-select.tsx index 4442fadd38a..1d5846019ce 100644 --- a/web/components/states/state-select.tsx +++ b/web/components/states/state-select.tsx @@ -7,7 +7,7 @@ import useSWR from "swr"; // react-popper import { usePopper } from "react-popper"; // services -import stateService from "services/state.service"; +import { ProjectStateService } from "services/project"; // headless ui import { Combobox } from "@headlessui/react"; // icons @@ -35,6 +35,9 @@ type Props = { disabled?: boolean; }; +// services +const projectStateService = new ProjectStateService(); + export const StateSelect: React.FC = ({ value, onChange, @@ -62,7 +65,9 @@ export const StateSelect: React.FC = ({ const { data: stateGroups } = useSWR( workspaceSlug && projectId && fetchStates ? STATES_LIST(projectId) : null, - workspaceSlug && projectId && fetchStates ? () => stateService.getStates(workspaceSlug as string, projectId) : null + workspaceSlug && projectId && fetchStates + ? () => projectStateService.getStates(workspaceSlug.toString(), projectId) + : null ); const states = getStatesList(stateGroups); diff --git a/web/components/ui/avatar.tsx b/web/components/ui/avatar.tsx index d60baa56eeb..0c12093f413 100644 --- a/web/components/ui/avatar.tsx +++ b/web/components/ui/avatar.tsx @@ -6,7 +6,7 @@ import useSWR from "swr"; // component import { Icon } from "components/ui"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // icons import User from "public/user.png"; // types @@ -22,13 +22,10 @@ type AvatarProps = { fontSize?: string; }; -export const Avatar: React.FC = ({ - user, - index, - height = "24px", - width = "24px", - fontSize = "12px", -}) => ( +// services +const workspaceService = new WorkspaceService(); + +export const Avatar: React.FC = ({ user, index, height = "24px", width = "24px", fontSize = "12px" }) => (
= ({ - users, - userIds, - length = 3, - showLength = true, -}) => { +export const AssigneesList: React.FC = ({ users, userIds, length = 3, showLength = true }) => { const router = useRouter(); const { workspaceSlug } = router.query; diff --git a/web/components/views/single-view-item.tsx b/web/components/views/single-view-item.tsx deleted file mode 100644 index d73885403e8..00000000000 --- a/web/components/views/single-view-item.tsx +++ /dev/null @@ -1,169 +0,0 @@ -import React from "react"; -import { mutate } from "swr"; -import Link from "next/link"; -import { useRouter } from "next/router"; - -// icons -import { TrashIcon, StarIcon, PencilIcon } from "@heroicons/react/24/outline"; -import { PhotoFilterOutlined } from "@mui/icons-material"; -//components -import { CustomMenu } from "components/ui"; -// services -import viewsService from "services/view.service"; -// types -import { IView } from "types"; -// fetch keys -import { VIEWS_LIST } from "constants/fetch-keys"; -// hooks -import useToast from "hooks/use-toast"; -// helpers -import { truncateText } from "helpers/string.helper"; - -type Props = { - view: IView; - handleEditView: () => void; - handleDeleteView: () => void; -}; - -export const SingleViewItem: React.FC = ({ view, handleEditView, handleDeleteView }) => { - const router = useRouter(); - const { workspaceSlug, projectId } = router.query; - - const { setToastAlert } = useToast(); - - const handleAddToFavorites = () => { - if (!workspaceSlug || !projectId || !view) return; - - mutate( - VIEWS_LIST(projectId as string), - (prevData) => - (prevData ?? []).map((v) => ({ - ...v, - is_favorite: v.id === view.id ? true : v.is_favorite, - })), - false - ); - - viewsService - .addViewToFavorites(workspaceSlug as string, projectId as string, { - view: view.id, - }) - .catch(() => { - setToastAlert({ - type: "error", - title: "Error!", - message: "Couldn't add the view to favorites. Please try again.", - }); - }); - }; - - const handleRemoveFromFavorites = () => { - if (!workspaceSlug || !view) return; - - mutate( - VIEWS_LIST(projectId as string), - (prevData) => - (prevData ?? []).map((v) => ({ - ...v, - is_favorite: v.id === view.id ? false : v.is_favorite, - })), - false - ); - - viewsService.removeViewFromFavorites(workspaceSlug as string, projectId as string, view.id).catch(() => { - setToastAlert({ - type: "error", - title: "Error!", - message: "Couldn't remove the view from favorites. Please try again.", - }); - }); - }; - - const viewRedirectionUrl = `/${workspaceSlug}/projects/${projectId}/views/${view.id}`; - - return ( -
- - -
-
-
- -
-
-

{truncateText(view.name, 75)}

- {view?.description &&

{view.description}

} -
-
-
-
-

- {Object.keys(view.query_data) - .map((key: string) => - view.query_data[key as keyof typeof view.query_data] !== null - ? (view.query_data[key as keyof typeof view.query_data] as any).length - : 0 - ) - .reduce((curr, prev) => curr + prev, 0)}{" "} - filters -

- - {view.is_favorite ? ( - - ) : ( - - )} - - { - e.preventDefault(); - e.stopPropagation(); - handleEditView(); - }} - > - - - Edit View - - - { - e.preventDefault(); - e.stopPropagation(); - handleDeleteView(); - }} - > - - - Delete View - - - -
-
-
-
- -
- ); -}; diff --git a/web/components/web-view/comment-card.tsx b/web/components/web-view/comment-card.tsx index 9f0d40a6ba7..54ee30ad833 100644 --- a/web/components/web-view/comment-card.tsx +++ b/web/components/web-view/comment-card.tsx @@ -4,6 +4,8 @@ import React, { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; // icons import { ChatBubbleLeftEllipsisIcon, CheckIcon, XMarkIcon } from "@heroicons/react/24/outline"; +// service +import { FileService } from "services/file.service"; // hooks import useUser from "hooks/use-user"; // ui @@ -15,8 +17,6 @@ import { LiteTextEditorWithRef, LiteReadOnlyEditorWithRef } from "@plane/lite-te import { timeAgo } from "helpers/date-time.helper"; // types import type { IIssueComment } from "types"; -// service -import fileService from "services/file.service"; type Props = { comment: IIssueComment; @@ -27,15 +27,11 @@ type Props = { disabled?: boolean; }; +// services +const fileService = new FileService(); + export const CommentCard: React.FC = (props) => { - const { - comment, - handleCommentDeletion, - onSubmit, - showAccessSpecifier = false, - workspaceSlug, - disabled, - } = props; + const { comment, handleCommentDeletion, onSubmit, showAccessSpecifier = false, workspaceSlug, disabled } = props; const { user } = useUser(); @@ -75,18 +71,14 @@ export const CommentCard: React.FC = (props) => { { ) : ( -
+
{comment.actor_detail.is_bot ? comment.actor_detail.first_name.charAt(0) : comment.actor_detail.display_name.charAt(0)} @@ -94,22 +86,15 @@ export const CommentCard: React.FC = (props) => { )} -
- {comment.actor_detail.is_bot - ? comment.actor_detail.first_name + " Bot" - : comment.actor_detail.display_name} + {comment.actor_detail.is_bot ? comment.actor_detail.first_name + " Bot" : comment.actor_detail.display_name}
-

- commented {timeAgo(comment.created_at)} -

+

commented {timeAgo(comment.created_at)}

@@ -148,10 +133,7 @@ export const CommentCard: React.FC = (props) => {
{showAccessSpecifier && (
- +
)} = (props) => { value={comment.comment_html} customClassName="text-xs border border-custom-border-200 bg-custom-background-100" /> - +
{user?.id === comment.actor && !disabled && ( - setIsEditing(true)} - className="flex items-center gap-1" - > + setIsEditing(true)} className="flex items-center gap-1"> Edit comment diff --git a/web/components/web-view/create-update-link-form.tsx b/web/components/web-view/create-update-link-form.tsx index 01f34c82f25..85e16d34af9 100644 --- a/web/components/web-view/create-update-link-form.tsx +++ b/web/components/web-view/create-update-link-form.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import { mutate } from "swr"; import { Controller, useForm } from "react-hook-form"; // services -import IssueService from "services/issue/issue.service"; +import { IssueService } from "services/issue"; // fetch keys import { ISSUE_DETAILS } from "constants/fetch-keys"; // hooks diff --git a/web/components/web-view/issue-activity.tsx b/web/components/web-view/issue-activity.tsx index de50334e9eb..34bb0e907c4 100644 --- a/web/components/web-view/issue-activity.tsx +++ b/web/components/web-view/issue-activity.tsx @@ -1,30 +1,20 @@ // react import React from "react"; - -// next import { useRouter } from "next/router"; - -// swr import useSWR, { mutate } from "swr"; // fetch key import { PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys"; - // services -import issuesService from "services/issue/issue.service"; - +import { IssueService, IssueCommentService } from "services/issue"; // hooks import useUser from "hooks/use-user"; - // components import { Label, AddComment, ActivityMessage, ActivityIcon, CommentCard } from "components/web-view"; - // helpers import { timeAgo } from "helpers/date-time.helper"; - // ui import { Icon } from "components/ui"; - // types import type { IIssue, IIssueComment } from "types"; @@ -33,6 +23,10 @@ type Props = { issueDetails: IIssue; }; +// services +const issueService = new IssueService(); +const issueCommentService = new IssueCommentService(); + export const IssueActivity: React.FC = (props) => { const { issueDetails, allowed } = props; @@ -44,14 +38,14 @@ export const IssueActivity: React.FC = (props) => { const { data: issueActivities, mutate: mutateIssueActivity } = useSWR( workspaceSlug && projectId && issueId ? PROJECT_ISSUES_ACTIVITY(issueId.toString()) : null, workspaceSlug && projectId && issueId - ? () => issuesService.getIssueActivities(workspaceSlug.toString(), projectId.toString(), issueId.toString()) + ? () => issueService.getIssueActivities(workspaceSlug.toString(), projectId.toString(), issueId.toString()) : null ); const handleCommentUpdate = async (comment: any, formData: any) => { if (!workspaceSlug || !projectId || !issueId || !allowed) return; - await issuesService + await issueCommentService .patchIssueComment(workspaceSlug as string, projectId as string, issueId as string, comment, formData, user) .then(() => mutateIssueActivity()) .catch(() => @@ -70,7 +64,7 @@ export const IssueActivity: React.FC = (props) => { mutateIssueActivity((prevData: any) => prevData?.filter((p: any) => p.id !== commentId), false); - await issuesService + await issueCommentService .deleteIssueComment(workspaceSlug as string, projectId as string, issueId as string, commentId, user) .then(() => mutateIssueActivity()) .catch(() => @@ -87,7 +81,7 @@ export const IssueActivity: React.FC = (props) => { const handleAddComment = async (formData: IIssueComment) => { if (!workspaceSlug || !issueDetails || !allowed) return; - await issuesService + await issueCommentService .createIssueComment(workspaceSlug.toString(), issueDetails.project, issueDetails.id, formData, user) .then(() => { mutate(PROJECT_ISSUES_ACTIVITY(issueDetails.id)); diff --git a/web/components/web-view/issue-attachments.tsx b/web/components/web-view/issue-attachments.tsx index 2e6c7db863a..d04f59fcdc6 100644 --- a/web/components/web-view/issue-attachments.tsx +++ b/web/components/web-view/issue-attachments.tsx @@ -4,17 +4,15 @@ import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; import { useDropzone } from "react-dropzone"; // services -import IssueService from "services/issue/issue.service"; +import { IssueAttachmentService } from "services/issue"; // fetch key import { ISSUE_ATTACHMENTS, PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys"; // icons import { FileText, ChevronRight, X, Image as ImageIcon } from "lucide-react"; // components import { Label, WebViewModal, DeleteConfirmation } from "components/web-view"; - // helpers import { getFileName } from "helpers/attachment.helper"; - // types import type { IIssueAttachment } from "types"; @@ -24,7 +22,7 @@ type Props = { const isImage = (fileName: string) => /\.(gif|jpe?g|tiff?|png|webp|bmp)$/i.test(fileName); -const issueService = new IssueService(); +const issueAttachmentService = new IssueAttachmentService(); export const IssueAttachments: React.FC = (props) => { const { allowed } = props; @@ -53,7 +51,7 @@ export const IssueAttachments: React.FC = (props) => { ); setIsLoading(true); - issueService + issueAttachmentService .uploadIssueAttachment(workspaceSlug as string, projectId as string, issueId as string, formData) .then((res) => { mutate( @@ -97,7 +95,7 @@ export const IssueAttachments: React.FC = (props) => { false ); - await issuesService + await issueAttachmentService .deleteIssueAttachment(workspaceSlug as string, projectId as string, issueId as string, assetId as string) .then(() => mutate(PROJECT_ISSUES_ACTIVITY(issueId as string))) .catch(() => { @@ -120,7 +118,8 @@ export const IssueAttachments: React.FC = (props) => { const { data: attachments } = useSWR( workspaceSlug && projectId && issueId ? ISSUE_ATTACHMENTS(issueId as string) : null, workspaceSlug && projectId && issueId - ? () => issueService.getIssueAttachment(workspaceSlug.toString(), projectId.toString(), issueId.toString()) + ? () => + issueAttachmentService.getIssueAttachment(workspaceSlug.toString(), projectId.toString(), issueId.toString()) : null ); diff --git a/web/components/web-view/issue-web-view-form.tsx b/web/components/web-view/issue-web-view-form.tsx index c66531783c3..56e5f7ecc0b 100644 --- a/web/components/web-view/issue-web-view-form.tsx +++ b/web/components/web-view/issue-web-view-form.tsx @@ -1,28 +1,19 @@ -// react import React, { useCallback, useEffect, useState } from "react"; - -// next import { useRouter } from "next/router"; - -// react hook forms import { Controller } from "react-hook-form"; +// services +import { FileService } from "services/file.service"; // hooks - import { useDebouncedCallback } from "use-debounce"; import useReloadConfirmations from "hooks/use-reload-confirmation"; - // ui import { TextArea } from "@plane/ui"; - // components import { RichTextEditor } from "@plane/rich-text-editor"; import { Label } from "components/web-view"; - // types import type { IIssue } from "types"; -import fileService from "services/file.service"; -// services type Props = { isAllowed: boolean; @@ -34,6 +25,9 @@ type Props = { handleSubmit: any; }; +// services +const fileService = new FileService(); + export const IssueWebViewForm: React.FC = (props) => { const { isAllowed, issueDetails, submitChanges, control, watch, handleSubmit } = props; diff --git a/web/components/web-view/issues-select-bottom-sheet.tsx b/web/components/web-view/issues-select-bottom-sheet.tsx index 266f29a76a9..80bf13795e0 100644 --- a/web/components/web-view/issues-select-bottom-sheet.tsx +++ b/web/components/web-view/issues-select-bottom-sheet.tsx @@ -1,21 +1,15 @@ -// react import React, { useState, useEffect } from "react"; - -// next import { useRouter } from "next/router"; // hooks import useUser from "hooks/use-user"; import useDebounce from "hooks/use-debounce"; - // services -import projectService from "services/project.service"; - +import { ProjectService } from "services/project"; // components import { WebViewModal } from "components/web-view"; import { LayerDiagonalIcon } from "components/icons"; import { Loader, PrimaryButton, SecondaryButton, ToggleSwitch } from "components/ui"; - // types import { ISearchIssueResponse, TProjectIssuesSearchParams } from "types"; @@ -27,6 +21,9 @@ type IssuesSelectBottomSheetProps = { singleSelect?: boolean; }; +// services +const projectService = new ProjectService(); + export const IssuesSelectBottomSheet: React.FC = (props) => { const { isOpen, onClose, onSubmit, searchParams, singleSelect = false } = props; @@ -85,15 +82,7 @@ export const IssuesSelectBottomSheet: React.FC = ( }) .then((res) => setIssues(res)) .finally(() => setIsSearching(false)); - }, [ - debouncedSearchTerm, - isOpen, - isWorkspaceLevel, - issueId, - projectId, - workspaceSlug, - searchParams, - ]); + }, [debouncedSearchTerm, isOpen, isWorkspaceLevel, issueId, projectId, workspaceSlug, searchParams]); return ( @@ -112,15 +101,8 @@ export const IssuesSelectBottomSheet: React.FC = ( isWorkspaceLevel ? "text-custom-text-100" : "text-custom-text-200" }`} > - setIsWorkspaceLevel((prevData) => !prevData)} - /> -
diff --git a/web/components/web-view/select-assignee.tsx b/web/components/web-view/select-assignee.tsx index af8bbec929c..877452579c7 100644 --- a/web/components/web-view/select-assignee.tsx +++ b/web/components/web-view/select-assignee.tsx @@ -1,21 +1,14 @@ // react import React, { useState } from "react"; - -// next import { useRouter } from "next/router"; - -// swr import useSWR from "swr"; // icons import { ChevronDown } from "lucide-react"; - // services -import projectService from "services/project.service/project.service"; - +import { ProjectService } from "services/project"; // fetch key import { PROJECT_MEMBERS } from "constants/fetch-keys"; - // components import { Avatar } from "components/ui/avatar"; import { WebViewModal } from "./web-view-modal"; @@ -26,6 +19,9 @@ type Props = { disabled?: boolean; }; +// services +const projectService = new ProjectService(); + export const AssigneeSelect: React.FC = (props) => { const { value, onChange, disabled = false } = props; diff --git a/web/components/web-view/select-blocked-by.tsx b/web/components/web-view/select-blocked-by.tsx index 97eaf6d95b9..f7b96b64966 100644 --- a/web/components/web-view/select-blocked-by.tsx +++ b/web/components/web-view/select-blocked-by.tsx @@ -1,30 +1,18 @@ -// react import React, { useState } from "react"; - -// next import { useRouter } from "next/router"; - -// swr import { mutate } from "swr"; - -// react hook form import { useFormContext } from "react-hook-form"; // services -import issuesService from "services/issues.service"; - +import { IssueService } from "services/issue"; // hooks import useUser from "hooks/use-user"; - // fetch keys import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys"; - // icons import { ChevronDown } from "lucide-react"; - // components import { IssuesSelectBottomSheet } from "components/web-view"; - // types import type { IIssue, BlockeIssueDetail, ISearchIssueResponse } from "types"; @@ -32,6 +20,9 @@ type Props = { disabled?: boolean; }; +// services +const issueService = new IssueService(); + export const BlockedBySelect: React.FC = (props) => { const { disabled = false } = props; @@ -71,25 +62,19 @@ export const BlockedBySelect: React.FC = (props) => { const relatedIssues = watch("related_issues"); - await issuesService - .createIssueRelation( - workspaceSlug.toString(), - projectId.toString(), - issueId.toString(), - user, - { - related_list: [ - ...selectedIssues.map((issue) => ({ - issue: issueId as string, - relation_type: "blocked_by" as const, - issue_detail: issue.blocked_issue_detail, - related_issue: issue.blocked_issue_detail.id, - })), - ], - } - ) + await issueService + .createIssueRelation(workspaceSlug.toString(), projectId.toString(), issueId.toString(), user, { + related_list: [ + ...selectedIssues.map((issue) => ({ + issue: issueId as string, + relation_type: "blocked_by" as const, + issue_detail: issue.blocked_issue_detail, + related_issue: issue.blocked_issue_detail.id, + })), + ], + }) .then((response) => { - mutate(ISSUE_DETAILS(issueId as string), (prevData) => { + mutate(ISSUE_DETAILS(issueId as string), (prevData) => { if (!prevData) return prevData; return { ...prevData, diff --git a/web/components/web-view/select-duplicate.tsx b/web/components/web-view/select-duplicate.tsx index 16899b8336a..ae28a215ed3 100644 --- a/web/components/web-view/select-duplicate.tsx +++ b/web/components/web-view/select-duplicate.tsx @@ -1,27 +1,17 @@ -// react import React, { useState } from "react"; - -// next import { useRouter } from "next/router"; - -// swr import { mutate } from "swr"; // services -import issuesService from "services/issues.service"; - +import { IssueService } from "services/issue"; // hooks import useUser from "hooks/use-user"; - // fetch keys import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys"; - // icons import { ChevronDown } from "lucide-react"; - // components import { IssuesSelectBottomSheet } from "components/web-view"; - // types import { BlockeIssueDetail, ISearchIssueResponse } from "types"; @@ -29,6 +19,9 @@ type Props = { disabled?: boolean; }; +// services +const issueService = new IssueService(); + export const DuplicateSelect: React.FC = (props) => { const { disabled = false } = props; @@ -66,23 +59,17 @@ export const DuplicateSelect: React.FC = (props) => { if (!user) return; - issuesService - .createIssueRelation( - workspaceSlug.toString(), - projectId.toString(), - issueId.toString(), - user, - { - related_list: [ - ...selectedIssues.map((issue) => ({ - issue: issueId as string, - issue_detail: issue.blocker_issue_detail, - related_issue: issue.blocker_issue_detail.id, - relation_type: "duplicate" as const, - })), - ], - } - ) + issueService + .createIssueRelation(workspaceSlug.toString(), projectId.toString(), issueId.toString(), user, { + related_list: [ + ...selectedIssues.map((issue) => ({ + issue: issueId as string, + issue_detail: issue.blocker_issue_detail, + related_issue: issue.blocker_issue_detail.id, + relation_type: "duplicate" as const, + })), + ], + }) .then(() => { mutate(ISSUE_DETAILS(issueId as string)); mutate(PROJECT_ISSUES_ACTIVITY(issueId as string)); @@ -104,9 +91,7 @@ export const DuplicateSelect: React.FC = (props) => { type="button" disabled={disabled} onClick={() => setIsBottomSheetOpen(true)} - className={ - "relative w-full px-2.5 py-0.5 text-base flex justify-between items-center gap-0.5" - } + className={"relative w-full px-2.5 py-0.5 text-base flex justify-between items-center gap-0.5"} > Select issue diff --git a/web/components/web-view/select-parent.tsx b/web/components/web-view/select-parent.tsx index f2b40cf8272..77bfe0055d8 100644 --- a/web/components/web-view/select-parent.tsx +++ b/web/components/web-view/select-parent.tsx @@ -1,16 +1,15 @@ import React, { useState } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; + // services -import IssueService from "services/issue/issue.service"; +import { IssueService } from "services/issue"; // constants import { ISSUE_DETAILS } from "constants/fetch-keys"; // components import { IssuesSelectBottomSheet } from "components/web-view"; - // icons import { ChevronDown, X } from "lucide-react"; - // types import { ISearchIssueResponse } from "types"; diff --git a/web/components/web-view/select-relates-to.tsx b/web/components/web-view/select-relates-to.tsx index 56e509d2ff6..47a7c7853ec 100644 --- a/web/components/web-view/select-relates-to.tsx +++ b/web/components/web-view/select-relates-to.tsx @@ -1,27 +1,17 @@ -// react import React, { useState } from "react"; - -// next import { useRouter } from "next/router"; - -// swr import { mutate } from "swr"; // services -import issuesService from "services/issues.service"; - +import { IssueService } from "services/issue"; // hooks import useUser from "hooks/use-user"; - // fetch keys import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys"; - // icons import { ChevronDown } from "lucide-react"; - // components import { IssuesSelectBottomSheet } from "components/web-view"; - // types import { BlockeIssueDetail, ISearchIssueResponse } from "types"; @@ -29,6 +19,9 @@ type Props = { disabled?: boolean; }; +// services +const issueService = new IssueService(); + export const RelatesSelect: React.FC = (props) => { const { disabled = false } = props; @@ -64,23 +57,17 @@ export const RelatesSelect: React.FC = (props) => { }, })); - issuesService - .createIssueRelation( - workspaceSlug.toString(), - projectId.toString(), - issueId.toString(), - user, - { - related_list: [ - ...selectedIssues.map((issue) => ({ - issue: issueId as string, - issue_detail: issue.blocker_issue_detail, - related_issue: issue.blocker_issue_detail.id, - relation_type: "relates_to" as const, - })), - ], - } - ) + issueService + .createIssueRelation(workspaceSlug.toString(), projectId.toString(), issueId.toString(), user, { + related_list: [ + ...selectedIssues.map((issue) => ({ + issue: issueId as string, + issue_detail: issue.blocker_issue_detail, + related_issue: issue.blocker_issue_detail.id, + relation_type: "relates_to" as const, + })), + ], + }) .then(() => { mutate(ISSUE_DETAILS(issueId as string)); mutate(PROJECT_ISSUES_ACTIVITY(issueId as string)); diff --git a/web/components/web-view/select-state.tsx b/web/components/web-view/select-state.tsx index 051aaae6578..966a2f30061 100644 --- a/web/components/web-view/select-state.tsx +++ b/web/components/web-view/select-state.tsx @@ -1,25 +1,16 @@ -// react import React, { useState } from "react"; - -// next import { useRouter } from "next/router"; - -// swr import useSWR from "swr"; // icons import { ChevronDown } from "lucide-react"; - // services -import stateService from "services/project.service/project_state.service"; - +import { ProjectStateService } from "services/project"; // fetch key import { STATES_LIST } from "constants/fetch-keys"; - // components import { StateGroupIcon } from "components/icons"; import { WebViewModal } from "./web-view-modal"; - // helpers import { getStatesList } from "helpers/state.helper"; @@ -29,6 +20,9 @@ type Props = { disabled?: boolean; }; +// services +const projectStateService = new ProjectStateService(); + export const StateSelect: React.FC = (props) => { const { value, onChange, disabled = false } = props; @@ -39,7 +33,9 @@ export const StateSelect: React.FC = (props) => { const { data: stateGroups } = useSWR( workspaceSlug && projectId ? STATES_LIST(projectId as string) : null, - workspaceSlug && projectId ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null + workspaceSlug && projectId + ? () => projectStateService.getStates(workspaceSlug as string, projectId as string) + : null ); const states = getStatesList(stateGroups); @@ -75,9 +71,7 @@ export const StateSelect: React.FC = (props) => { type="button" disabled={disabled} onClick={() => setIsOpen(true)} - className={ - "relative w-full px-2.5 py-0.5 text-base flex justify-between items-center gap-0.5" - } + className={"relative w-full px-2.5 py-0.5 text-base flex justify-between items-center gap-0.5"} > {selectedState?.name || "Select a state"} diff --git a/web/components/web-view/sub-issues.tsx b/web/components/web-view/sub-issues.tsx index 917cb79751b..167c6e871ab 100644 --- a/web/components/web-view/sub-issues.tsx +++ b/web/components/web-view/sub-issues.tsx @@ -1,30 +1,19 @@ -// react import React, { useState } from "react"; - -// next import { useRouter } from "next/router"; - -// swr import useSWR, { mutate } from "swr"; // icons import { X, PlusIcon } from "lucide-react"; - // services -import issuesService from "services/issue/issue.service"; - +import { IssueService } from "services/issue"; // fetch key import { SUB_ISSUES } from "constants/fetch-keys"; - // hooks import useUser from "hooks/use-user"; - // ui import { Spinner } from "components/ui"; - // components import { Label, IssuesSelectBottomSheet, DeleteConfirmation } from "components/web-view"; - // types import { IIssue, ISearchIssueResponse } from "types"; @@ -32,6 +21,9 @@ type Props = { issueDetails?: IIssue; }; +// services +const issueService = new IssueService(); + export const SubIssueList: React.FC = (props) => { const { issueDetails } = props; @@ -48,7 +40,7 @@ export const SubIssueList: React.FC = (props) => { const { data: subIssuesResponse } = useSWR( workspaceSlug && issueDetails ? SUB_ISSUES(issueDetails.id) : null, workspaceSlug && issueDetails - ? () => issuesService.subIssues(workspaceSlug as string, issueDetails.project, issueDetails.id) + ? () => issueService.subIssues(workspaceSlug as string, issueDetails.project, issueDetails.id) : null ); @@ -73,7 +65,7 @@ export const SubIssueList: React.FC = (props) => { false ); - issuesService + issueService .patchIssue(workspaceSlug.toString(), issue.project, issue.id, { parent: null }, user) .finally(() => mutate(SUB_ISSUES(issueDetails.id))); }; @@ -84,7 +76,7 @@ export const SubIssueList: React.FC = (props) => { const payload = { sub_issue_ids: data.map((i) => i.id), }; - await issuesService + await issueService .addSubIssues(workspaceSlug.toString(), projectId.toString(), issueId.toString(), payload) .finally(() => { mutate(SUB_ISSUES(issueId.toString())); diff --git a/web/components/workspace/create-workspace-form.tsx b/web/components/workspace/create-workspace-form.tsx index 6ec6dbef67d..a84bf44706b 100644 --- a/web/components/workspace/create-workspace-form.tsx +++ b/web/components/workspace/create-workspace-form.tsx @@ -2,7 +2,7 @@ import { Dispatch, SetStateAction, useEffect, useState, FC } from "react"; import { mutate } from "swr"; import { Controller, useForm } from "react-hook-form"; // services -import WorkspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // hooks import useToast from "hooks/use-toast"; // ui diff --git a/web/components/workspace/delete-workspace-modal.tsx b/web/components/workspace/delete-workspace-modal.tsx index 3e18d7575e4..8557d51eb2c 100644 --- a/web/components/workspace/delete-workspace-modal.tsx +++ b/web/components/workspace/delete-workspace-modal.tsx @@ -9,7 +9,7 @@ import { Controller, useForm } from "react-hook-form"; // headless ui import { Dialog, Transition } from "@headlessui/react"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // hooks import useToast from "hooks/use-toast"; // icons @@ -33,6 +33,9 @@ const defaultValues = { confirmDelete: "", }; +// services +const workspaceService = new WorkspaceService(); + export const DeleteWorkspaceModal: React.FC = ({ isOpen, data, onClose, user }) => { const router = useRouter(); diff --git a/web/components/workspace/send-workspace-invitation-modal.tsx b/web/components/workspace/send-workspace-invitation-modal.tsx index dd0f6d3eb3e..5422c147db0 100644 --- a/web/components/workspace/send-workspace-invitation-modal.tsx +++ b/web/components/workspace/send-workspace-invitation-modal.tsx @@ -3,7 +3,7 @@ import { mutate } from "swr"; import { Controller, useFieldArray, useForm } from "react-hook-form"; import { Dialog, Transition } from "@headlessui/react"; // services -import WorkspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // hooks import useToast from "hooks/use-toast"; // ui diff --git a/web/components/workspace/sidebar-dropdown.tsx b/web/components/workspace/sidebar-dropdown.tsx index ac8040b41a5..ecd1c12493c 100644 --- a/web/components/workspace/sidebar-dropdown.tsx +++ b/web/components/workspace/sidebar-dropdown.tsx @@ -10,8 +10,8 @@ import useUser from "hooks/use-user"; import useWorkspaces from "hooks/use-workspaces"; import useToast from "hooks/use-toast"; // services -import UserService from "services/user.service"; -import AuthService from "services/auth.service"; +import { UserService } from "services/user.service"; +import { AuthService } from "services/auth.service"; // components import { Avatar, Icon } from "components/ui"; import { Loader } from "@plane/ui"; diff --git a/web/components/workspace/views/delete-workspace-view-modal.tsx b/web/components/workspace/views/delete-workspace-view-modal.tsx deleted file mode 100644 index 6030f630f11..00000000000 --- a/web/components/workspace/views/delete-workspace-view-modal.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import React, { useState } from "react"; - -import { useRouter } from "next/router"; - -import { mutate } from "swr"; - -// headless ui -import { Dialog, Transition } from "@headlessui/react"; -// services -import workspaceService from "services/workspace.service"; -// hooks -import useToast from "hooks/use-toast"; -// ui -import { DangerButton, SecondaryButton } from "components/ui"; -// icons -import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; -// types -import { IWorkspaceView } from "types/workspace-views"; -// fetch-keys -import { WORKSPACE_VIEWS_LIST } from "constants/fetch-keys"; - -type Props = { - isOpen: boolean; - setIsOpen: React.Dispatch>; - data: IWorkspaceView | null; -}; - -export const DeleteWorkspaceViewModal: React.FC = ({ isOpen, data, setIsOpen }) => { - const [isDeleteLoading, setIsDeleteLoading] = useState(false); - - const router = useRouter(); - const { workspaceSlug } = router.query; - - const { setToastAlert } = useToast(); - - const handleClose = () => { - setIsOpen(false); - setIsDeleteLoading(false); - }; - - const handleDeletion = async () => { - setIsDeleteLoading(true); - - if (!workspaceSlug || !data) return; - - await workspaceService - .deleteView(workspaceSlug as string, data.id) - .then(() => { - mutate(WORKSPACE_VIEWS_LIST(workspaceSlug as string), (views) => - views?.filter((view) => view.id !== data.id) - ); - - handleClose(); - - setToastAlert({ - type: "success", - title: "Success!", - message: "View deleted successfully.", - }); - }) - .catch(() => { - setToastAlert({ - type: "error", - title: "Error!", - message: "View could not be deleted. Please try again.", - }); - }) - .finally(() => { - setIsDeleteLoading(false); - }); - }; - - return ( - - - -
- - -
-
- - -
-
-
-
-
- - Delete View - -
-

- Are you sure you want to delete view-{" "} - - {data?.name} - - ? All of the data related to the view will be permanently removed. This - action cannot be undone. -

-
-
-
-
-
- Cancel - - {isDeleteLoading ? "Deleting..." : "Delete"} - -
-
-
-
-
-
-
- ); -}; diff --git a/web/components/workspace/views/global-select-filters.tsx b/web/components/workspace/views/global-select-filters.tsx deleted file mode 100644 index 967ee1bf800..00000000000 --- a/web/components/workspace/views/global-select-filters.tsx +++ /dev/null @@ -1,301 +0,0 @@ -import { useState } from "react"; - -import { useRouter } from "next/router"; - -import useSWR from "swr"; - -// hook -import useProjects from "hooks/use-projects"; -import useWorkspaceMembers from "hooks/use-workspace-members"; -// services -import issuesService from "services/issues.service"; -// components -import { DateFilterModal } from "components/core"; -// ui -import { Avatar, MultiLevelDropdown } from "components/ui"; -// icons -import { PriorityIcon, StateGroupIcon } from "components/icons"; -// helpers -import { checkIfArraysHaveSameElements } from "helpers/array.helper"; -// types -import { IWorkspaceIssueFilterOptions, TStateGroups } from "types"; -// fetch-keys -import { WORKSPACE_LABELS } from "constants/fetch-keys"; -// constants -import { GROUP_CHOICES, PRIORITIES } from "constants/project"; -import { DATE_FILTER_OPTIONS } from "constants/filters"; - -type Props = { - filters: Partial; - onSelect: (option: any) => void; - direction?: "left" | "right"; - height?: "sm" | "md" | "rg" | "lg"; -}; - -export const GlobalSelectFilters: React.FC = ({ - filters, - onSelect, - direction = "right", - height = "md", -}) => { - const [isDateFilterModalOpen, setIsDateFilterModalOpen] = useState(false); - const [dateFilterType, setDateFilterType] = useState<{ - title: string; - type: "start_date" | "target_date"; - }>({ - title: "", - type: "start_date", - }); - - const router = useRouter(); - const { workspaceSlug } = router.query; - - const { workspaceMembers } = useWorkspaceMembers(workspaceSlug?.toString() ?? ""); - - const { data: workspaceLabels } = useSWR( - workspaceSlug ? WORKSPACE_LABELS(workspaceSlug.toString()) : null, - workspaceSlug ? () => issuesService.getWorkspaceLabels(workspaceSlug.toString()) : null - ); - - const { projects: allProjects } = useProjects(); - const joinedProjects = allProjects?.filter((p) => p.is_member); - - const workspaceFilterOption = [ - { - id: "project", - label: "Project", - value: joinedProjects, - hasChildren: true, - children: joinedProjects?.map((project) => ({ - id: project.id, - label:
{project.name}
, - value: { - key: "project", - value: project.id, - }, - selected: filters?.project?.includes(project.id), - })), - }, - { - id: "state_group", - label: "State groups", - value: GROUP_CHOICES, - hasChildren: true, - children: [ - ...Object.keys(GROUP_CHOICES).map((key) => ({ - id: key, - label: ( -
- - {GROUP_CHOICES[key as keyof typeof GROUP_CHOICES]} -
- ), - value: { - key: "state_group", - value: key, - }, - selected: filters?.state_group?.includes(key), - })), - ], - }, - { - id: "labels", - label: "Labels", - value: workspaceLabels, - hasChildren: true, - children: workspaceLabels?.map((label) => ({ - id: label.id, - label: ( -
-
- {label.name} -
- ), - value: { - key: "labels", - value: label.id, - }, - selected: filters?.labels?.includes(label.id), - })), - }, - { - id: "priority", - label: "Priority", - value: PRIORITIES, - hasChildren: true, - children: PRIORITIES.map((priority) => ({ - id: priority === null ? "null" : priority, - label: ( -
- - {priority ?? "None"} -
- ), - value: { - key: "priority", - value: priority === null ? "null" : priority, - }, - selected: filters?.priority?.includes(priority === null ? "null" : priority), - })), - }, - { - id: "created_by", - label: "Created by", - value: workspaceMembers, - hasChildren: true, - children: workspaceMembers?.map((member) => ({ - id: member.member.id, - label: ( -
- - {member.member.display_name} -
- ), - value: { - key: "created_by", - value: member.member.id, - }, - selected: filters?.created_by?.includes(member.member.id), - })), - }, - { - id: "assignees", - label: "Assignees", - value: workspaceMembers, - hasChildren: true, - children: workspaceMembers?.map((member) => ({ - id: member.member.id, - label: ( -
- - {member.member.display_name} -
- ), - value: { - key: "assignees", - value: member.member.id, - }, - selected: filters?.assignees?.includes(member.member.id), - })), - }, - { - id: "subscriber", - label: "Subscriber", - value: workspaceMembers, - hasChildren: true, - children: workspaceMembers?.map((member) => ({ - id: member.member.id, - label: ( -
- - {member.member.display_name} -
- ), - value: { - key: "subscriber", - value: member.member.id, - }, - selected: filters?.subscriber?.includes(member.member.id), - })), - }, - { - id: "start_date", - label: "Start date", - value: DATE_FILTER_OPTIONS, - hasChildren: true, - children: [ - ...DATE_FILTER_OPTIONS.map((option) => ({ - id: option.name, - label: option.name, - value: { - key: "start_date", - value: option.value, - }, - selected: checkIfArraysHaveSameElements(filters?.start_date ?? [], option.value), - })), - { - id: "custom", - label: "Custom", - value: "custom", - element: ( - - ), - }, - ], - }, - { - id: "target_date", - label: "Due date", - value: DATE_FILTER_OPTIONS, - hasChildren: true, - children: [ - ...DATE_FILTER_OPTIONS.map((option) => ({ - id: option.name, - label: option.name, - value: { - key: "target_date", - value: option.value, - }, - selected: checkIfArraysHaveSameElements(filters?.target_date ?? [], option.value), - })), - { - id: "custom", - label: "Custom", - value: "custom", - element: ( - - ), - }, - ], - }, - ]; - - return ( - <> - {isDateFilterModalOpen && ( - setIsDateFilterModalOpen(false)} - isOpen={isDateFilterModalOpen} - onSelect={onSelect} - /> - )} - - - ); -}; diff --git a/web/components/workspace/views/single-workspace-view-item.tsx b/web/components/workspace/views/single-workspace-view-item.tsx deleted file mode 100644 index fd153bdfcb7..00000000000 --- a/web/components/workspace/views/single-workspace-view-item.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import React from "react"; - -import Link from "next/link"; -import { useRouter } from "next/router"; - -// icons -import { TrashIcon, PencilIcon } from "@heroicons/react/24/outline"; -import { PhotoFilterOutlined } from "@mui/icons-material"; -//components -import { CustomMenu } from "components/ui"; -import { IWorkspaceView } from "types/workspace-views"; -// helpers -import { truncateText } from "helpers/string.helper"; - -type Props = { - view: IWorkspaceView; - handleEditView: () => void; - handleDeleteView: () => void; -}; - -export const SingleWorkspaceViewItem: React.FC = ({ - view, - handleEditView, - handleDeleteView, -}) => { - const router = useRouter(); - const { workspaceSlug } = router.query; - - const viewRedirectionUrl = `/${workspaceSlug}/workspace-views/issues?globalViewId=${view.id}`; - - return ( -
- - -
-
-
- -
-
-

- {truncateText(view.name, 75)} -

- {view?.description && ( -

{view.description}

- )} -
-
-
-
-

- {view.query_data.filters && Object.keys(view.query_data.filters).length > 0 - ? `${Object.keys(view.query_data.filters) - .map((key: string) => - view.query_data.filters[key as keyof typeof view.query_data.filters] !== - null - ? isNaN( - ( - view.query_data.filters[ - key as keyof typeof view.query_data.filters - ] as any - ).length - ) - ? 0 - : ( - view.query_data.filters[ - key as keyof typeof view.query_data.filters - ] as any - ).length - : 0 - ) - .reduce((curr, prev) => curr + prev, 0)} filters` - : "0 filters"} -

- - { - e.preventDefault(); - e.stopPropagation(); - handleEditView(); - }} - > - - - Edit View - - - { - e.preventDefault(); - e.stopPropagation(); - handleDeleteView(); - }} - > - - - Delete View - - - -
-
-
-
- -
- ); -}; diff --git a/web/components/workspace/views/workpace-view-navigation.tsx b/web/components/workspace/views/workpace-view-navigation.tsx deleted file mode 100644 index 867764a5d7d..00000000000 --- a/web/components/workspace/views/workpace-view-navigation.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import React from "react"; - -import { useRouter } from "next/router"; - -import useSWR from "swr"; - -// icon -import { PlusIcon } from "lucide-react"; -// constant -import { WORKSPACE_VIEWS_LIST } from "constants/fetch-keys"; -// service -import workspaceService from "services/workspace.service"; - -type Props = { - handleAddView: () => void; -}; - -export const WorkspaceViewsNavigation: React.FC = ({ handleAddView }) => { - const router = useRouter(); - const { workspaceSlug, globalViewId } = router.query; - - const { data: workspaceViews } = useSWR( - workspaceSlug ? WORKSPACE_VIEWS_LIST(workspaceSlug.toString()) : null, - workspaceSlug ? () => workspaceService.getAllViews(workspaceSlug.toString()) : null - ); - - const isSelected = (pathName: string) => router.pathname.includes(pathName); - React.useEffect(() => { - const activeTabElement = document.getElementById("active-tab-global-view"); - if (activeTabElement) activeTabElement.scrollIntoView({ behavior: "smooth", inline: "center" }); - }, [globalViewId, workspaceViews]); - - const tabsList = [ - { - key: "all", - label: "All Issues", - selected: isSelected("workspace-views/all-issues"), - onClick: () => router.replace(`/${workspaceSlug}/workspace-views/all-issues`), - }, - { - key: "assigned", - label: "Assigned", - selected: isSelected("workspace-views/assigned"), - onClick: () => router.replace(`/${workspaceSlug}/workspace-views/assigned`), - }, - { - key: "created", - label: "Created", - selected: isSelected("workspace-views/created"), - onClick: () => router.replace(`/${workspaceSlug}/workspace-views/created`), - }, - { - key: "subscribed", - label: "Subscribed", - selected: isSelected("workspace-views/subscribed"), - onClick: () => router.replace(`/${workspaceSlug}/workspace-views/subscribed`), - }, - ]; - - return ( -
- {tabsList.map((tab) => ( - - ))} - - {workspaceViews && - workspaceViews.length > 0 && - workspaceViews?.map((view) => ( - - ))} - - -
- ); -}; diff --git a/web/contexts/project-member.context.tsx b/web/contexts/project-member.context.tsx index 5bd2636e432..5e594a73328 100644 --- a/web/contexts/project-member.context.tsx +++ b/web/contexts/project-member.context.tsx @@ -1,17 +1,11 @@ import { createContext, useContext } from "react"; - -// next import { useRouter } from "next/router"; - -// swr import useSWR from "swr"; // services -import projectService from "services/project.service/project.service"; - +import { ProjectService } from "services/project"; // keys import { USER_PROJECT_VIEW } from "constants/fetch-keys"; - // types import { IProjectMember } from "types"; @@ -21,6 +15,9 @@ type ContextType = { error: any; }; +// services +const projectService = new ProjectService(); + export const ProjectMemberContext = createContext({} as ContextType); type Props = { diff --git a/web/contexts/theme.context.tsx b/web/contexts/theme.context.tsx index 852f58a5cfd..e0c32328ecd 100644 --- a/web/contexts/theme.context.tsx +++ b/web/contexts/theme.context.tsx @@ -7,7 +7,7 @@ import ToastAlert from "components/toast-alert"; // hooks import useUserAuth from "hooks/use-user-auth"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // fetch-keys import { USER_PROJECT_VIEW } from "constants/fetch-keys"; // helper @@ -16,6 +16,9 @@ import { applyTheme, unsetCustomCssVariables } from "helpers/theme.helper"; export const themeContext = createContext({} as ContextType); +// services +const projectService = new ProjectService(); + type ThemeProps = { collapsed: boolean; }; diff --git a/web/contexts/user.context.tsx b/web/contexts/user.context.tsx index 3f076b326b1..474ea24f60e 100644 --- a/web/contexts/user.context.tsx +++ b/web/contexts/user.context.tsx @@ -3,7 +3,7 @@ import React, { createContext, ReactElement } from "react"; import useSWR, { KeyedMutator } from "swr"; // services -import userService from "services/user.service"; +import { UserService } from "services/user.service"; // constants import { CURRENT_USER } from "constants/fetch-keys"; // types @@ -17,6 +17,9 @@ interface IUserContextProps { workspaceInvitesLength?: number; } +// services +const userService = new UserService(); + export const UserContext = createContext({} as IUserContextProps); export const UserProvider = ({ children }: { children: ReactElement }) => { diff --git a/web/contexts/workspace-member.context.tsx b/web/contexts/workspace-member.context.tsx index dfba45b24f5..d312751feab 100644 --- a/web/contexts/workspace-member.context.tsx +++ b/web/contexts/workspace-member.context.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // types import { IWorkspaceMember } from "types"; // fetch-keys @@ -23,6 +23,9 @@ type Props = { children: React.ReactNode; }; +// services +const workspaceService = new WorkspaceService(); + export const WorkspaceMemberProvider: React.FC = (props) => { const { children } = props; diff --git a/web/contexts/workspace-view-context.tsx b/web/contexts/workspace-view-context.tsx deleted file mode 100644 index 9b936463756..00000000000 --- a/web/contexts/workspace-view-context.tsx +++ /dev/null @@ -1,235 +0,0 @@ -import { createContext, useEffect, useState } from "react"; -// next imports -import { useRouter } from "next/router"; -// swr -import useSWR, { KeyedMutator } from "swr"; -// services -import workspaceService from "services/workspace.service"; -// types -import { IIssue, IWorkspaceGlobalViewProps } from "types"; -import { IWorkspaceView } from "types/workspace-views"; -// fetch-keys -import { WORKSPACE_VIEW_DETAILS, WORKSPACE_VIEW_ISSUES } from "constants/fetch-keys"; - -export interface IWorkspaceViewContext { - params: any; - view: IWorkspaceView | undefined; - viewLoading: boolean; - viewIssues: IIssue[]; - mutateViewIssues: KeyedMutator; - viewIssueLoading: boolean; - filters: IWorkspaceGlobalViewProps; - handleFilters: ( - filterType: "filters" | "display_filters" | "display_properties", - payload: { [key: string]: any }, - saveFiltersToServer?: boolean - ) => void; -} - -export const WorkspaceIssueViewContext = createContext( - undefined -); - -export const initialState: IWorkspaceGlobalViewProps = { - filters: { - assignees: null, - created_by: null, - labels: null, - priority: null, - state_group: null, - subscriber: null, - start_date: null, - target_date: null, - project: null, - }, - display_filters: { - order_by: "-created_at", - sub_issue: false, - type: null, - layout: "spreadsheet", - }, - display_properties: { - assignee: true, - start_date: true, - due_date: true, - key: true, - labels: true, - priority: true, - state: true, - sub_issue_count: true, - attachment_count: true, - link: true, - estimate: true, - created_on: true, - updated_on: true, - }, -}; - -const saveViewFilters = async ( - workspaceSlug: string, - globalViewId: string, - state: IWorkspaceGlobalViewProps -) => { - await workspaceService.updateView(workspaceSlug, globalViewId, { - query_data: state, - }); -}; - -export const WorkspaceViewProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { - const router = useRouter(); - const { workspaceSlug, globalViewId } = router.query as { - workspaceSlug: string; - globalViewId: string; - }; - - const [filters, setFilters] = useState(initialState); - - const handleFilters = ( - filterType: "filters" | "display_filters" | "display_properties", - payload: { [key: string]: any }, - saveFiltersToServer?: boolean - ) => { - const updatedFilterPayload = { - ...filters, - [filterType]: { - ...filters[filterType], - ...payload, - }, - }; - setFilters(() => updatedFilterPayload); - - if (saveFiltersToServer) saveViewFilters(workspaceSlug, globalViewId, updatedFilterPayload); - }; - - const computedFilter = (filters: any) => { - const computedFilters: any = {}; - Object.keys(filters).map((key) => { - if (filters[key] != undefined) - computedFilters[key] = - typeof filters[key] === "string" || typeof filters[key] === "boolean" - ? filters[key] - : filters[key].join(","); - }); - return computedFilters; - }; - - const computedParams = (filters: any) => { - const params: any = { - assignees: (filters && filters?.filters?.assignees) || undefined, - created_by: (filters && filters?.filters?.created_by) || undefined, - labels: (filters && filters?.filters?.labels) || undefined, - priority: (filters && filters?.filters?.priority) || undefined, - state_group: (filters && filters?.filters?.state_group) || undefined, - subscriber: (filters && filters?.filters?.subscriber) || undefined, - start_date: (filters && filters?.filters?.start_date) || undefined, - target_date: (filters && filters?.filters?.target_date) || undefined, - project: (filters && filters?.filters?.project) || undefined, - order_by: (filters && filters?.display_filters?.order_by) || "-created_at", - sub_issue: (filters && filters?.display_filters?.sub_issue) || false, - type: filters && filters?.display_filters?.type, - }; - return params; - }; - - const params: any = { - assignees: filters?.filters.assignees ? filters?.filters?.assignees.join(",") : undefined, - created_by: filters?.filters.created_by ? filters?.filters?.created_by.join(",") : undefined, - labels: filters?.filters.labels ? filters?.filters?.labels.join(",") : undefined, - priority: filters?.filters.priority ? filters?.filters?.priority.join(",") : undefined, - state_group: filters?.filters.state_group ? filters?.filters?.state_group.join(",") : undefined, - subscriber: filters?.filters.subscriber ? filters?.filters?.subscriber.join(",") : undefined, - start_date: filters?.filters.start_date ? filters?.filters?.start_date.join(",") : undefined, - target_date: filters?.filters.target_date ? filters?.filters?.target_date.join(",") : undefined, - project: filters?.filters.project ? filters?.filters?.project.join(",") : undefined, - - order_by: filters?.display_filters?.order_by - ? filters?.display_filters?.order_by - : "-created_at", - sub_issue: filters?.display_filters?.sub_issue ? filters?.display_filters?.sub_issue : false, - type: filters?.display_filters?.type ? filters?.display_filters?.type : undefined, - layout: filters?.display_filters?.layout ? filters?.display_filters?.layout : undefined, - }; - - const { data: view, isLoading: viewLoading } = useSWR( - workspaceSlug && globalViewId ? WORKSPACE_VIEW_DETAILS(globalViewId.toString()) : null, - workspaceSlug && globalViewId - ? () => workspaceService.getViewDetails(workspaceSlug.toString(), globalViewId.toString()) - : null - ); - - const { - data: viewIssues, - mutate: mutateViewIssues, - isLoading: viewIssueLoading, - } = useSWR( - workspaceSlug && view && globalViewId && filters - ? WORKSPACE_VIEW_ISSUES(globalViewId.toString(), params) - : null, - workspaceSlug && view && globalViewId - ? () => - workspaceService.getViewIssues( - workspaceSlug.toString(), - computedFilter(computedParams(filters)) - ) - : null - ); - - useEffect(() => { - if (view && view?.query_data) { - const payload = { - filters: { - ...view?.query_data?.filters, - assignees: view?.query_data?.filters?.assignees || null, - created_by: view?.query_data?.filters?.created_by || null, - labels: view?.query_data?.filters?.labels || null, - priority: view?.query_data?.filters?.priority || null, - state_group: view?.query_data?.filters?.state_group || null, - subscriber: view?.query_data?.filters?.subscriber || null, - start_date: view?.query_data?.filters?.start_date || null, - target_date: view?.query_data?.filters?.target_date || null, - project: view?.query_data?.filters?.project || null, - }, - display_filters: { - ...view?.query_data?.display_filters, - order_by: view?.query_data?.display_filters?.order_by || "-created_at", - sub_issue: view?.query_data?.display_filters?.sub_issue || true, - type: view?.query_data?.display_filters?.type || null, - }, - display_properties: { - ...view?.query_data?.display_properties, - assignee: view?.query_data?.display_properties?.assignee || true, - start_date: view?.query_data?.display_properties?.start_date || true, - due_date: view?.query_data?.display_properties?.due_date || true, - key: view?.query_data?.display_properties?.key || true, - labels: view?.query_data?.display_properties?.labels || true, - priority: view?.query_data?.display_properties?.priority || true, - state: view?.query_data?.display_properties?.state || true, - sub_issue_count: view?.query_data?.display_properties?.sub_issue_count || true, - attachment_count: view?.query_data?.display_properties?.attachment_count || true, - link: view?.query_data?.display_properties?.link || true, - estimate: view?.query_data?.display_properties?.estimate || true, - created_on: view?.query_data?.display_properties?.created_on || true, - updated_on: view?.query_data?.display_properties?.updated_on || true, - }, - }; - setFilters(payload); - } - }, [view, setFilters]); - - return ( - - {children} - - ); -}; diff --git a/web/contexts/workspace.context.tsx b/web/contexts/workspace.context.tsx index 2ecbb2ef510..f389381f95a 100644 --- a/web/contexts/workspace.context.tsx +++ b/web/contexts/workspace.context.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // types import { IWorkspace } from "types"; // constants @@ -21,6 +21,9 @@ export interface WorkspaceContextProps { mutateWorkspaces: () => void; } +// services +const workspaceService = new WorkspaceService(); + export const WorkspaceContext = createContext({} as WorkspaceContextProps); export const WorkspaceProvider: FC = (props) => { @@ -29,11 +32,7 @@ export const WorkspaceProvider: FC = (props) => { const router = useRouter(); const { workspaceSlug } = router.query; // API to fetch user information - const { - data = [], - error, - mutate, - } = useSWR(USER_WORKSPACES, () => workspaceService.userWorkspaces()); + const { data = [], error, mutate } = useSWR(USER_WORKSPACES, () => workspaceService.userWorkspaces()); // active workspace const activeWorkspace = data?.find((w) => w.slug === workspaceSlug); diff --git a/web/hooks/my-issues/use-my-issues.tsx b/web/hooks/my-issues/use-my-issues.tsx index 3e79d6f1e3b..f9ced399029 100644 --- a/web/hooks/my-issues/use-my-issues.tsx +++ b/web/hooks/my-issues/use-my-issues.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import userService from "services/user.service"; +import { UserService } from "services/user.service"; // hooks import useMyIssuesFilters from "hooks/my-issues/use-my-issues-filter"; // types @@ -13,6 +13,9 @@ import { IIssue } from "types"; // fetch-keys import { USER_ISSUES } from "constants/fetch-keys"; +// services +const userService = new UserService(); + const useMyIssues = (workspaceSlug: string | undefined) => { const router = useRouter(); @@ -33,9 +36,7 @@ const useMyIssues = (workspaceSlug: string | undefined) => { }; const { data: myIssues, mutate: mutateMyIssues } = useSWR( - workspaceSlug && router.pathname.includes("my-issues") - ? USER_ISSUES(workspaceSlug.toString(), params) - : null, + workspaceSlug && router.pathname.includes("my-issues") ? USER_ISSUES(workspaceSlug.toString(), params) : null, workspaceSlug && router.pathname.includes("my-issues") ? () => userService.userIssues(workspaceSlug.toString(), params) : null diff --git a/web/hooks/use-comment-reaction.tsx b/web/hooks/use-comment-reaction.tsx index 1d3968d3b4b..af1d0a90f8d 100644 --- a/web/hooks/use-comment-reaction.tsx +++ b/web/hooks/use-comment-reaction.tsx @@ -2,16 +2,16 @@ import useSWR from "swr"; // fetch keys import { COMMENT_REACTION_LIST } from "constants/fetch-keys"; - // services -import reactionService from "services/issue/issue_reaction.service"; - +import { IssueReactionService } from "services/issue"; // helpers import { groupReactions } from "helpers/emoji.helper"; - // hooks import useUser from "./use-user"; +// services +const issueReactionService = new IssueReactionService(); + const useCommentReaction = ( workspaceSlug?: string | string[] | null, projectId?: string | string[] | null, @@ -27,7 +27,7 @@ const useCommentReaction = ( : null, workspaceSlug && projectId && commendId ? () => - reactionService.listIssueCommentReactions( + issueReactionService.listIssueCommentReactions( workspaceSlug.toString(), projectId.toString(), commendId.toString() @@ -48,7 +48,7 @@ const useCommentReaction = ( const handleReactionCreate = async (reaction: string) => { if (!workspaceSlug || !projectId || !commendId) return; - const data = await reactionService.createIssueCommentReaction( + const data = await issueReactionService.createIssueCommentReaction( workspaceSlug.toString(), projectId.toString(), commendId.toString(), @@ -73,7 +73,7 @@ const useCommentReaction = ( false ); - await reactionService.deleteIssueCommentReaction( + await issueReactionService.deleteIssueCommentReaction( workspaceSlug.toString(), projectId.toString(), commendId.toString(), diff --git a/web/hooks/use-estimate-option.tsx b/web/hooks/use-estimate-option.tsx index 9768ab3f47a..e2bb9086c52 100644 --- a/web/hooks/use-estimate-option.tsx +++ b/web/hooks/use-estimate-option.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import estimatesService from "services/project.service/project_estimates.service"; +import { ProjectEstimateServices } from "services/project"; // hooks import useProjectDetails from "hooks/use-project-details"; // helpers @@ -11,19 +11,22 @@ import { orderArrayBy } from "helpers/array.helper"; // fetch-keys import { ESTIMATE_DETAILS } from "constants/fetch-keys"; +// services +const projectEstimateService = new ProjectEstimateServices(); + const useEstimateOption = (estimateKey?: number | null) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; const { projectDetails } = useProjectDetails(); - const { data: estimateDetails, error: estimateDetailsError } = useSWR( + const { data: estimateDetails } = useSWR( workspaceSlug && projectId && projectDetails && projectDetails?.estimate ? ESTIMATE_DETAILS(projectDetails.estimate as string) : null, workspaceSlug && projectId && projectDetails && projectDetails.estimate ? () => - estimatesService.getEstimateDetails( + projectEstimateService.getEstimateDetails( workspaceSlug.toString(), projectId.toString(), projectDetails.estimate as string diff --git a/web/hooks/use-issue-reaction.tsx b/web/hooks/use-issue-reaction.tsx index 33f03811255..c4ea210ded2 100644 --- a/web/hooks/use-issue-reaction.tsx +++ b/web/hooks/use-issue-reaction.tsx @@ -2,16 +2,15 @@ import useSWR from "swr"; // fetch keys import { ISSUE_REACTION_LIST } from "constants/fetch-keys"; - // helpers import { groupReactions } from "helpers/emoji.helper"; - // services -import reactionService from "services/issue/issue_reaction.service"; - +import { IssueReactionService } from "services/issue"; // hooks import useUser from "./use-user"; +const issueReactionService = new IssueReactionService(); + const useIssueReaction = ( workspaceSlug?: string | string[] | null, projectId?: string | string[] | null, @@ -28,7 +27,8 @@ const useIssueReaction = ( ? ISSUE_REACTION_LIST(workspaceSlug.toString(), projectId.toString(), issueId.toString()) : null, workspaceSlug && projectId && issueId - ? () => reactionService.listIssueReactions(workspaceSlug.toString(), projectId.toString(), issueId.toString()) + ? () => + issueReactionService.listIssueReactions(workspaceSlug.toString(), projectId.toString(), issueId.toString()) : null ); @@ -43,7 +43,7 @@ const useIssueReaction = ( const handleReactionCreate = async (reaction: string) => { if (!workspaceSlug || !projectId || !issueId) return; - const data = await reactionService.createIssueReaction( + const data = await issueReactionService.createIssueReaction( workspaceSlug.toString(), projectId.toString(), issueId.toString(), @@ -68,7 +68,7 @@ const useIssueReaction = ( false ); - await reactionService.deleteIssueReaction( + await issueReactionService.deleteIssueReaction( workspaceSlug.toString(), projectId.toString(), issueId.toString(), diff --git a/web/hooks/use-issues-view.tsx b/web/hooks/use-issues-view.tsx index cc5141b3e47..feba952d9e7 100644 --- a/web/hooks/use-issues-view.tsx +++ b/web/hooks/use-issues-view.tsx @@ -7,10 +7,10 @@ import useSWR from "swr"; // contexts import { issueViewContext } from "contexts/issue-view.context"; // services -import issuesService from "services/issue/issue.service"; -import cyclesService from "services/cycle.service"; -import modulesService from "services/module.service"; -import stateService from "services/project.service/project_state.service"; +import { IssueService, IssueArchiveService, IssueDraftService } from "services/issue"; +import { CycleService } from "services/cycle.service"; +import { ModuleService } from "services/module.service"; +import { ProjectStateService } from "services/project"; // helpers import { getStatesList } from "helpers/state.helper"; // types @@ -26,6 +26,14 @@ import { VIEW_ISSUES, } from "constants/fetch-keys"; +// services +const issueService = new IssueService(); +const issueArchiveService = new IssueArchiveService(); +const issueDraftService = new IssueDraftService(); +const cycleService = new CycleService(); +const moduleService = new ModuleService(); +const projectStateService = new ProjectStateService(); + const useIssuesView = () => { const { display_filters: displayFilters, @@ -58,7 +66,7 @@ const useIssuesView = () => { const { data: projectIssues, mutate: mutateProjectIssues } = useSWR( workspaceSlug && projectId && params ? PROJECT_ISSUES_LIST_WITH_PARAMS(projectId as string, params) : null, workspaceSlug && projectId && params - ? () => issuesService.getIssuesWithParams(workspaceSlug as string, projectId as string, params) + ? () => issueService.getIssuesWithParams(workspaceSlug as string, projectId as string, params) : null ); @@ -67,7 +75,7 @@ const useIssuesView = () => { ? PROJECT_ARCHIVED_ISSUES_LIST_WITH_PARAMS(projectId as string, params) : null, workspaceSlug && projectId && params && isArchivedIssues && !archivedIssueId - ? () => issuesService.getArchivedIssues(workspaceSlug as string, projectId as string, params) + ? () => issueArchiveService.getArchivedIssues(workspaceSlug as string, projectId as string, params) : null ); @@ -76,7 +84,7 @@ const useIssuesView = () => { ? PROJECT_DRAFT_ISSUES_LIST_WITH_PARAMS(projectId as string, params) : null, workspaceSlug && projectId && params && isDraftIssues && !archivedIssueId - ? () => issuesService.getDraftIssues(workspaceSlug as string, projectId as string, params) + ? () => issueDraftService.getDraftIssues(workspaceSlug as string, projectId as string, params) : null ); @@ -84,12 +92,7 @@ const useIssuesView = () => { workspaceSlug && projectId && cycleId && params ? CYCLE_ISSUES_WITH_PARAMS(cycleId as string, params) : null, workspaceSlug && projectId && cycleId && params ? () => - cyclesService.getCycleIssuesWithParams( - workspaceSlug as string, - projectId as string, - cycleId as string, - params - ) + cycleService.getCycleIssuesWithParams(workspaceSlug as string, projectId as string, cycleId as string, params) : null ); @@ -97,7 +100,7 @@ const useIssuesView = () => { workspaceSlug && projectId && moduleId && params ? MODULE_ISSUES_WITH_PARAMS(moduleId as string, params) : null, workspaceSlug && projectId && moduleId && params ? () => - modulesService.getModuleIssuesWithParams( + moduleService.getModuleIssuesWithParams( workspaceSlug as string, projectId as string, moduleId as string, @@ -109,13 +112,15 @@ const useIssuesView = () => { const { data: viewIssues, mutate: mutateViewIssues } = useSWR( workspaceSlug && projectId && viewId && params ? VIEW_ISSUES(viewId.toString(), params) : null, workspaceSlug && projectId && viewId && params - ? () => issuesService.getIssuesWithParams(workspaceSlug.toString(), projectId.toString(), params) + ? () => issueService.getIssuesWithParams(workspaceSlug.toString(), projectId.toString(), params) : null ); const { data: states } = useSWR( workspaceSlug && projectId ? STATES_LIST(projectId as string) : null, - workspaceSlug && projectId ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null + workspaceSlug && projectId + ? () => projectStateService.getStates(workspaceSlug as string, projectId as string) + : null ); const statesList = getStatesList(states); const activeStatesList = statesList?.filter((state) => state.group === "started" || state.group === "unstarted"); diff --git a/web/hooks/use-profile-issues.tsx b/web/hooks/use-profile-issues.tsx index 263aa307c3a..fabe880140c 100644 --- a/web/hooks/use-profile-issues.tsx +++ b/web/hooks/use-profile-issues.tsx @@ -5,14 +5,16 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import userService from "services/user.service"; +import { UserService } from "services/user.service"; // contexts import { profileIssuesContext } from "contexts/profile-issues-context"; +import { useWorkspaceMyMembership } from "contexts/workspace-member.context"; // types import { IIssue } from "types"; // fetch-keys import { USER_PROFILE_ISSUES } from "constants/fetch-keys"; -import { useWorkspaceMyMembership } from "contexts/workspace-member.context"; + +const userService = new UserService(); const useProfileIssues = (workspaceSlug: string | undefined, userId: string | undefined) => { const { @@ -84,18 +86,12 @@ const useProfileIssues = (workspaceSlug: string | undefined, userId: string | un useEffect(() => { if (!userId || !filters) return; - if ( - router.pathname.includes("assigned") && - (!filters.assignees || !filters.assignees.includes(userId)) - ) { + if (router.pathname.includes("assigned") && (!filters.assignees || !filters.assignees.includes(userId))) { setFilters({ assignees: [...(filters.assignees ?? []), userId] }); return; } - if ( - router.pathname.includes("created") && - (!filters.created_by || !filters.created_by.includes(userId)) - ) { + if (router.pathname.includes("created") && (!filters.created_by || !filters.created_by.includes(userId))) { setFilters({ created_by: [...(filters.created_by ?? []), userId] }); return; } diff --git a/web/hooks/use-project-details.tsx b/web/hooks/use-project-details.tsx index a3582423f8e..4a6fdd690e2 100644 --- a/web/hooks/use-project-details.tsx +++ b/web/hooks/use-project-details.tsx @@ -3,10 +3,12 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // fetch-keys import { PROJECT_DETAILS } from "constants/fetch-keys"; +const projectService = new ProjectService(); + const useProjectDetails = () => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; diff --git a/web/hooks/use-project-members.tsx b/web/hooks/use-project-members.tsx index a60ce570ab9..4b7abe641dc 100644 --- a/web/hooks/use-project-members.tsx +++ b/web/hooks/use-project-members.tsx @@ -1,11 +1,13 @@ import useSWR from "swr"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // fetch-keys import { PROJECT_MEMBERS } from "constants/fetch-keys"; // hooks import useUser from "./use-user"; +const projectService = new ProjectService(); + const useProjectMembers = ( workspaceSlug: string | undefined, projectId: string | undefined, diff --git a/web/hooks/use-projects.tsx b/web/hooks/use-projects.tsx index 4050e3e59a6..c618ae7d32b 100644 --- a/web/hooks/use-projects.tsx +++ b/web/hooks/use-projects.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // helpers import { orderArrayBy } from "helpers/array.helper"; // types @@ -11,6 +11,8 @@ import { IProject } from "types"; // fetch-keys import { PROJECTS_LIST } from "constants/fetch-keys"; +const projectService = new ProjectService(); + const useProjects = (type?: "all" | boolean, fetchCondition?: boolean) => { fetchCondition = fetchCondition ?? true; diff --git a/web/hooks/use-sub-issue.tsx b/web/hooks/use-sub-issue.tsx index 3a0b801a2bc..a1d2e281cc7 100644 --- a/web/hooks/use-sub-issue.tsx +++ b/web/hooks/use-sub-issue.tsx @@ -1,16 +1,16 @@ -import { useEffect, useState } from "react"; - import { useRouter } from "next/router"; import useSWR from "swr"; // services -import issuesService from "services/issue/issue.service"; +import { IssueService } from "services/issue"; // types import { ISubIssueResponse } from "types"; // fetch-keys import { SUB_ISSUES } from "constants/fetch-keys"; +const issueService = new IssueService(); + const useSubIssue = (projectId: string, issueId: string, isExpanded: boolean) => { const router = useRouter(); const { workspaceSlug } = router.query; @@ -19,7 +19,7 @@ const useSubIssue = (projectId: string, issueId: string, isExpanded: boolean) => const { data: subIssuesResponse, isLoading } = useSWR( shouldFetch ? SUB_ISSUES(issueId as string) : null, - shouldFetch ? () => issuesService.subIssues(workspaceSlug as string, projectId as string, issueId as string) : null + shouldFetch ? () => issueService.subIssues(workspaceSlug as string, projectId as string, issueId as string) : null ); return { diff --git a/web/hooks/use-user-auth.tsx b/web/hooks/use-user-auth.tsx index d3116ce0677..c8ea78ee600 100644 --- a/web/hooks/use-user-auth.tsx +++ b/web/hooks/use-user-auth.tsx @@ -6,11 +6,14 @@ import useSWR from "swr"; // keys import { CURRENT_USER } from "constants/fetch-keys"; // services -import userService from "services/user.service"; -import workspaceService from "services/workspace.service"; +import { UserService } from "services/user.service"; +import { WorkspaceService } from "services/workspace.service"; // types import type { IWorkspace, ICurrentUserResponse } from "types"; +const userService = new UserService(); +const workspaceService = new WorkspaceService(); + const useUserAuth = (routeAuth: "sign-in" | "onboarding" | "admin" | null = "admin") => { const router = useRouter(); const { next_url } = router.query as { next_url: string }; diff --git a/web/hooks/use-user.tsx b/web/hooks/use-user.tsx index f9b6e36d8bf..0a65292be9f 100644 --- a/web/hooks/use-user.tsx +++ b/web/hooks/use-user.tsx @@ -2,11 +2,14 @@ import { useEffect } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; // services -import userService from "services/user.service"; +import { UserService } from "services/user.service"; // constants import { CURRENT_USER } from "constants/fetch-keys"; // types -import type { ICurrentUserResponse, IUser } from "types"; +import type { ICurrentUserResponse } from "types"; + +// services +const userService = new UserService(); export default function useUser({ redirectTo = "", redirectIfFound = false, options = {} } = {}) { const router = useRouter(); diff --git a/web/hooks/use-workspace-details.tsx b/web/hooks/use-workspace-details.tsx index 4a2f9762646..e0eaa3fe5bb 100644 --- a/web/hooks/use-workspace-details.tsx +++ b/web/hooks/use-workspace-details.tsx @@ -2,10 +2,12 @@ import { useEffect } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // fetch-keys import { WORKSPACE_DETAILS } from "constants/fetch-keys"; +const workspaceService = new WorkspaceService(); + const useWorkspaceDetails = () => { const router = useRouter(); const { workspaceSlug } = router.query; diff --git a/web/hooks/use-workspace-members.tsx b/web/hooks/use-workspace-members.tsx index d4104d3bdf6..e6fa6d2e387 100644 --- a/web/hooks/use-workspace-members.tsx +++ b/web/hooks/use-workspace-members.tsx @@ -1,11 +1,13 @@ import useSWR from "swr"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // fetch-keys import { WORKSPACE_MEMBERS } from "constants/fetch-keys"; // hooks import useUser from "./use-user"; +const workspaceService = new WorkspaceService(); + const useWorkspaceMembers = (workspaceSlug: string | undefined, fetchCondition?: boolean) => { fetchCondition = fetchCondition ?? true; @@ -18,18 +20,10 @@ const useWorkspaceMembers = (workspaceSlug: string | undefined, fetchCondition?: const hasJoined = workspaceMembers?.some((item: any) => item.member.id === (user as any)?.id); - const isOwner = workspaceMembers?.some( - (item) => item.member.id === (user as any)?.id && item.role === 20 - ); - const isMember = workspaceMembers?.some( - (item) => item.member.id === (user as any)?.id && item.role === 15 - ); - const isViewer = workspaceMembers?.some( - (item) => item.member.id === (user as any)?.id && item.role === 10 - ); - const isGuest = workspaceMembers?.some( - (item) => item.member.id === (user as any)?.id && item.role === 5 - ); + const isOwner = workspaceMembers?.some((item) => item.member.id === (user as any)?.id && item.role === 20); + const isMember = workspaceMembers?.some((item) => item.member.id === (user as any)?.id && item.role === 15); + const isViewer = workspaceMembers?.some((item) => item.member.id === (user as any)?.id && item.role === 10); + const isGuest = workspaceMembers?.some((item) => item.member.id === (user as any)?.id && item.role === 5); return { workspaceMembers, diff --git a/web/hooks/use-workspaces.tsx b/web/hooks/use-workspaces.tsx index d924d0f692f..7637ccffe2b 100644 --- a/web/hooks/use-workspaces.tsx +++ b/web/hooks/use-workspaces.tsx @@ -3,10 +3,12 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // fetch-keys import { USER_WORKSPACES } from "constants/fetch-keys"; +const workspaceService = new WorkspaceService(); + const useWorkspaces = () => { // router const router = useRouter(); diff --git a/web/layouts/auth-layout-legacy/project-authorization-wrapper.tsx b/web/layouts/auth-layout-legacy/project-authorization-wrapper.tsx index 98ee0d668f2..cb2abc56f4e 100644 --- a/web/layouts/auth-layout-legacy/project-authorization-wrapper.tsx +++ b/web/layouts/auth-layout-legacy/project-authorization-wrapper.tsx @@ -5,7 +5,6 @@ import { useRouter } from "next/router"; // contexts import { useProjectMyMembership, ProjectMemberProvider } from "contexts/project-member.context"; -import { WorkspaceViewProvider } from "contexts/workspace-view-context"; // layouts import AppHeader from "layouts/app-layout-legacy/app-header"; import AppSidebar from "layouts/app-layout-legacy/app-sidebar"; @@ -14,7 +13,7 @@ import { NotAuthorizedView, JoinProject } from "components/auth-screens"; import { CommandPalette } from "components/command-palette"; // ui import { Button, Spinner } from "@plane/ui"; -import { EmptyState } from "components/ui"; +import { EmptyState } from "components/common"; // icons import { LayerDiagonalIcon } from "components/icons"; // images @@ -31,9 +30,7 @@ type Props = { export const ProjectAuthorizationWrapper: React.FC = (props) => ( - - - + ); diff --git a/web/layouts/auth-layout-legacy/user-authorization-wrapper.tsx b/web/layouts/auth-layout-legacy/user-authorization-wrapper.tsx index 8f323268b88..33e414e287c 100644 --- a/web/layouts/auth-layout-legacy/user-authorization-wrapper.tsx +++ b/web/layouts/auth-layout-legacy/user-authorization-wrapper.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import userService from "services/user.service"; +import { UserService } from "services/user.service"; // ui import { Spinner } from "@plane/ui"; // fetch-keys @@ -13,6 +13,9 @@ type Props = { children: React.ReactNode; }; +// services +const userService = new UserService(); + export const UserAuthorizationLayout: React.FC = ({ children }) => { const router = useRouter(); diff --git a/web/layouts/auth-layout-legacy/workspace-authorization-wrapper.tsx b/web/layouts/auth-layout-legacy/workspace-authorization-wrapper.tsx index d121ab31233..cdaf04d037b 100644 --- a/web/layouts/auth-layout-legacy/workspace-authorization-wrapper.tsx +++ b/web/layouts/auth-layout-legacy/workspace-authorization-wrapper.tsx @@ -6,10 +6,9 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import workspaceServices from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // contexts import { WorkspaceMemberProvider } from "contexts/workspace-member.context"; -import { WorkspaceViewProvider } from "contexts/workspace-view-context"; // layouts import AppSidebar from "layouts/app-layout-legacy/app-sidebar"; import AppHeader from "layouts/app-layout-legacy/app-header"; @@ -82,47 +81,45 @@ export const WorkspaceAuthorizationLayout: React.FC = ({ return ( - - -
- - {settingsLayout && (memberType?.isGuest || memberType?.isViewer) ? ( - - - - Go to workspace - - - - } - type="workspace" + +
+ + {settingsLayout && (memberType?.isGuest || memberType?.isViewer) ? ( + + + + Go to workspace + + + + } + type="workspace" + /> + ) : ( +
+ - ) : ( -
- -
-
{children}
-
-
- )} -
- +
+
{children}
+
+ + )} +
); diff --git a/web/layouts/auth-layout/user-wrapper.tsx b/web/layouts/auth-layout/user-wrapper.tsx index 3c30910513b..c3d29aeb5f4 100644 --- a/web/layouts/auth-layout/user-wrapper.tsx +++ b/web/layouts/auth-layout/user-wrapper.tsx @@ -2,7 +2,7 @@ import { FC, ReactNode } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; // services -import userService from "services/user.service"; +import { UserService } from "services/user.service"; // ui import { Spinner } from "@plane/ui"; // fetch-keys @@ -12,6 +12,9 @@ export interface IUserAuthWrapper { children: ReactNode; } +// services +const userService = new UserService(); + export const UserAuthWrapper: FC = (props) => { const { children } = props; // router diff --git a/web/layouts/web-view-layout/index.tsx b/web/layouts/web-view-layout/index.tsx index 6814a6f257b..f50c23512ea 100644 --- a/web/layouts/web-view-layout/index.tsx +++ b/web/layouts/web-view-layout/index.tsx @@ -1,15 +1,11 @@ -// swr import useSWR from "swr"; // services -import userService from "services/user.service"; - +import { UserService } from "services/user.service"; // fetch keys import { CURRENT_USER } from "constants/fetch-keys"; - // icons import { AlertCircle } from "lucide-react"; - // ui import { Spinner } from "@plane/ui"; @@ -18,6 +14,9 @@ type Props = { fullScreen?: boolean; }; +// services +const userService = new UserService(); + const getIfInWebview = (userAgent: NavigatorID["userAgent"]) => { const safari = /safari/.test(userAgent); diff --git a/web/pages/[workspaceSlug]/profile/[userId]/index.tsx b/web/pages/[workspaceSlug]/profile/[userId]/index.tsx index 0cf54bb0d03..c674dcf3322 100644 --- a/web/pages/[workspaceSlug]/profile/[userId]/index.tsx +++ b/web/pages/[workspaceSlug]/profile/[userId]/index.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import userService from "services/user.service"; +import { UserService } from "services/user.service"; // layouts import { ProfileAuthWrapper } from "layouts/profile-layout"; // components @@ -23,15 +23,16 @@ import { IUserStateDistribution, TStateGroups } from "types"; import { USER_PROFILE_DATA } from "constants/fetch-keys"; import { GROUP_CHOICES } from "constants/project"; +// services +const userService = new UserService(); + const ProfileOverview: NextPage = () => { const router = useRouter(); const { workspaceSlug, userId } = router.query; const { data: userProfile } = useSWR( workspaceSlug && userId ? USER_PROFILE_DATA(workspaceSlug.toString(), userId.toString()) : null, - workspaceSlug && userId - ? () => userService.getUserProfileData(workspaceSlug.toString(), userId.toString()) - : null + workspaceSlug && userId ? () => userService.getUserProfileData(workspaceSlug.toString(), userId.toString()) : null ); const stateDistribution: IUserStateDistribution[] = Object.keys(GROUP_CHOICES).map((key) => { @@ -48,10 +49,7 @@ const ProfileOverview: NextPage = () => {
- +
diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/[archivedIssueId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/[archivedIssueId].tsx index f3ebbd8497a..a7729d847b0 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/[archivedIssueId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/[archivedIssueId].tsx @@ -7,7 +7,7 @@ import useSWR, { mutate } from "swr"; // react-hook-form import { useForm } from "react-hook-form"; // services -import issuesService from "services/issue/issue.service"; +import { IssueService, IssueArchiveService } from "services/issue"; // hooks import useUserAuth from "hooks/use-user-auth"; import useToast from "hooks/use-toast"; @@ -41,6 +41,10 @@ const defaultValues: Partial = { labels_list: [], }; +// services +const issueService = new IssueService(); +const issueArchiveService = new IssueArchiveService(); + const ArchivedIssueDetailsPage: NextPage = () => { const [isRestoring, setIsRestoring] = useState(false); @@ -54,7 +58,11 @@ const ArchivedIssueDetailsPage: NextPage = () => { workspaceSlug && projectId && archivedIssueId ? ISSUE_DETAILS(archivedIssueId as string) : null, workspaceSlug && projectId && archivedIssueId ? () => - issuesService.retrieveArchivedIssue(workspaceSlug as string, projectId as string, archivedIssueId as string) + issueArchiveService.retrieveArchivedIssue( + workspaceSlug as string, + projectId as string, + archivedIssueId as string + ) : null ); @@ -83,7 +91,7 @@ const ArchivedIssueDetailsPage: NextPage = () => { ...formData, }; - await issuesService + await issueService .patchIssue(workspaceSlug as string, projectId as string, archivedIssueId as string, payload, user) .then(() => { mutateIssueDetails(); @@ -113,7 +121,7 @@ const ArchivedIssueDetailsPage: NextPage = () => { setIsRestoring(true); - await issuesService + await issueArchiveService .unarchiveIssue(workspaceSlug as string, projectId as string, archivedIssueId as string) .then(() => { setToastAlert({ diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/index.tsx index 6a95a8e409f..debdd54258d 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/index.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // layouts import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy"; // contexts @@ -22,6 +22,9 @@ import type { NextPage } from "next"; // fetch-keys import { PROJECT_DETAILS } from "constants/fetch-keys"; +// services +const projectService = new ProjectService(); + const ProjectArchivedIssues: NextPage = () => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/[cycleId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/[cycleId].tsx index a2af08b68d3..500264027da 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/[cycleId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/[cycleId].tsx @@ -15,14 +15,14 @@ import { ExistingIssuesListModal } from "components/core"; import { CycleDetailsSidebar, TransferIssues, TransferIssuesModal } from "components/cycles"; import { CycleLayoutRoot } from "components/issues/issue-layouts"; // services -import issuesService from "services/issue/issue.service"; -import cycleServices from "services/cycle.service"; +import { IssueService } from "services/issue"; +import { CycleService } from "services/cycle.service"; // hooks import useToast from "hooks/use-toast"; import useUserAuth from "hooks/use-user-auth"; // ui -import { Button } from "@plane/ui"; -import { CustomMenu, EmptyState } from "components/ui"; +import { CustomMenu } from "components/ui"; +import { EmptyState } from "components/common"; import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; // images import emptyCycle from "public/empty-state/cycle.svg"; @@ -35,6 +35,10 @@ import { ISearchIssueResponse } from "types"; import { CYCLES_LIST, CYCLE_DETAILS } from "constants/fetch-keys"; import { CycleIssuesHeader } from "components/headers"; +// services +const issueService = new IssueService(); +const cycleService = new CycleService(); + const SingleCycle: React.FC = () => { const [cycleIssuesListModal, setCycleIssuesListModal] = useState(false); const [cycleSidebar, setCycleSidebar] = useState(true); @@ -51,14 +55,14 @@ const SingleCycle: React.FC = () => { const { data: cycles } = useSWR( workspaceSlug && projectId ? CYCLES_LIST(projectId as string) : null, workspaceSlug && projectId - ? () => cycleServices.getCyclesWithParams(workspaceSlug as string, projectId as string, "all") + ? () => cycleService.getCyclesWithParams(workspaceSlug as string, projectId as string, "all") : null ); const { data: cycleDetails, error } = useSWR( workspaceSlug && projectId && cycleId ? CYCLE_DETAILS(cycleId.toString()) : null, workspaceSlug && projectId && cycleId - ? () => cycleServices.getCycleDetails(workspaceSlug.toString(), projectId.toString(), cycleId.toString()) + ? () => cycleService.getCycleDetails(workspaceSlug.toString(), projectId.toString(), cycleId.toString()) : null ); @@ -74,7 +78,7 @@ const SingleCycle: React.FC = () => { issues: data.map((i) => i.id), }; - await issuesService + await issueService .addIssueToCycle(workspaceSlug as string, projectId as string, cycleId as string, payload, user) .catch(() => { setToastAlert({ diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/draft-issues/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/draft-issues/index.tsx index fac7f3e01ab..d2b073a329c 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/draft-issues/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/draft-issues/index.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // layouts import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy"; // contexts @@ -13,7 +13,6 @@ import { truncateText } from "helpers/string.helper"; // components import { IssuesFilterView, IssuesView } from "components/core"; // ui -import { Icon } from "components/ui"; import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; // icons import { X, PenSquare } from "lucide-react"; @@ -22,6 +21,9 @@ import type { NextPage } from "next"; // fetch-keys import { PROJECT_DETAILS } from "constants/fetch-keys"; +// services +const projectService = new ProjectService(); + const ProjectDraftIssues: NextPage = () => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx index 3944f5383db..158201aa890 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx @@ -7,7 +7,7 @@ import useSWR, { mutate } from "swr"; // react-hook-form import { useForm } from "react-hook-form"; // services -import issuesService from "services/issue/issue.service"; +import { IssueService } from "services/issue"; // hooks import useUserAuth from "hooks/use-user-auth"; // layouts @@ -15,7 +15,7 @@ import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy"; // components import { IssueDetailsSidebar, IssueMainContent } from "components/issues"; // ui -import { EmptyState } from "components/ui"; +import { EmptyState } from "components/common"; import { Breadcrumbs } from "components/breadcrumbs"; import { Loader } from "@plane/ui"; // images @@ -43,6 +43,9 @@ const defaultValues: Partial = { target_date: null, }; +// services +const issueService = new IssueService(); + const IssueDetailsPage: NextPage = () => { const router = useRouter(); const { workspaceSlug, projectId, issueId } = router.query; @@ -57,7 +60,7 @@ const IssueDetailsPage: NextPage = () => { } = useSWR( workspaceSlug && projectId && issueId ? ISSUE_DETAILS(issueId as string) : null, workspaceSlug && projectId && issueId - ? () => issuesService.retrieve(workspaceSlug as string, projectId as string, issueId as string) + ? () => issueService.retrieve(workspaceSlug as string, projectId as string, issueId as string) : null ); @@ -89,7 +92,7 @@ const IssueDetailsPage: NextPage = () => { delete payload.related_issues; delete payload.issue_relations; - await issuesService + await issueService .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user) .then(() => { mutateIssueDetails(); diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/issues/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/issues/index.tsx index cc7a7971945..ac193e32551 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/issues/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/issues/index.tsx @@ -5,7 +5,7 @@ import useSWR from "swr"; // mobx import { useMobxStore } from "lib/mobx/store-provider"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // layouts import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy"; // helper @@ -20,6 +20,9 @@ import type { NextPage } from "next"; // fetch-keys import { PROJECT_DETAILS } from "constants/fetch-keys"; +// services +const projectService = new ProjectService(); + const ProjectIssues: NextPage = () => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/modules/[moduleId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/modules/[moduleId].tsx index 43805dfa170..e291fe5cbc7 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/modules/[moduleId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/modules/[moduleId].tsx @@ -7,7 +7,7 @@ import useSWR from "swr"; // icons import { RectangleGroupIcon } from "@heroicons/react/24/outline"; // services -import modulesService from "services/module.service"; +import { ModuleService } from "services/module.service"; // hooks import useToast from "hooks/use-toast"; import useUserAuth from "hooks/use-user-auth"; @@ -19,7 +19,8 @@ import { ModuleDetailsSidebar } from "components/modules"; import { ModuleLayoutRoot } from "components/issues"; import { ModuleIssuesHeader } from "components/headers"; // ui -import { CustomMenu, EmptyState } from "components/ui"; +import { CustomMenu } from "components/ui"; +import { EmptyState } from "components/common"; import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; // images import emptyModule from "public/empty-state/module.svg"; @@ -30,6 +31,9 @@ import { ISearchIssueResponse } from "types"; // fetch-keys import { MODULE_DETAILS, MODULE_ISSUES, MODULE_LIST } from "constants/fetch-keys"; +// services +const moduleService = new ModuleService(); + const SingleModule: React.FC = () => { const [moduleIssuesListModal, setModuleIssuesListModal] = useState(false); const [moduleSidebar, setModuleSidebar] = useState(false); @@ -43,20 +47,20 @@ const SingleModule: React.FC = () => { const { data: modules } = useSWR( workspaceSlug && projectId ? MODULE_LIST(projectId as string) : null, - workspaceSlug && projectId ? () => modulesService.getModules(workspaceSlug as string, projectId as string) : null + workspaceSlug && projectId ? () => moduleService.getModules(workspaceSlug as string, projectId as string) : null ); const { data: moduleIssues } = useSWR( workspaceSlug && projectId && moduleId ? MODULE_ISSUES(moduleId as string) : null, workspaceSlug && projectId && moduleId - ? () => modulesService.getModuleIssues(workspaceSlug as string, projectId as string, moduleId as string) + ? () => moduleService.getModuleIssues(workspaceSlug as string, projectId as string, moduleId as string) : null ); const { data: moduleDetails, error } = useSWR( moduleId ? MODULE_DETAILS(moduleId as string) : null, workspaceSlug && projectId - ? () => modulesService.getModuleDetails(workspaceSlug as string, projectId as string, moduleId as string) + ? () => moduleService.getModuleDetails(workspaceSlug as string, projectId as string, moduleId as string) : null ); @@ -67,7 +71,7 @@ const SingleModule: React.FC = () => { issues: data.map((i) => i.id), }; - await modulesService + await moduleService .addIssuesToModule(workspaceSlug as string, projectId as string, moduleId as string, payload, user) .catch(() => setToastAlert({ diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/modules/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/modules/index.tsx index 03387d6ad76..4176ba426b6 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/modules/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/modules/index.tsx @@ -9,13 +9,14 @@ import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy"; // hooks import useUserAuth from "hooks/use-user-auth"; // services -import projectService from "services/project.service/project.service"; -import modulesService from "services/module.service"; +import { ProjectService } from "services/project"; +import { ModuleService } from "services/module.service"; // components import { CreateUpdateModuleModal, ModulesListGanttChartView, SingleModuleCard } from "components/modules"; // ui import { Button, Loader, Tooltip } from "@plane/ui"; -import { EmptyState, Icon } from "components/ui"; +import { Icon } from "components/ui"; +import { EmptyState } from "components/common"; import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; // icons import { PlusIcon } from "@heroicons/react/24/outline"; @@ -40,6 +41,10 @@ const moduleViewOptions: { type: "grid" | "gantt_chart"; icon: any }[] = [ }, ]; +// services +const projectService = new ProjectService(); +const moduleService = new ModuleService(); + const ProjectModules: NextPage = () => { const [selectedModule, setSelectedModule] = useState(); const [createUpdateModule, setCreateUpdateModule] = useState(false); @@ -58,7 +63,7 @@ const ProjectModules: NextPage = () => { const { data: modules, mutate: mutateModules } = useSWR( workspaceSlug && projectId ? MODULE_LIST(projectId as string) : null, - workspaceSlug && projectId ? () => modulesService.getModules(workspaceSlug as string, projectId as string) : null + workspaceSlug && projectId ? () => moduleService.getModules(workspaceSlug as string, projectId as string) : null ); const handleEditModule = (module: IModule) => { diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx index 68da2fac52f..92c4d6d2222 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx @@ -14,9 +14,9 @@ import { TwitterPicker } from "react-color"; import { DragDropContext, DropResult } from "react-beautiful-dnd"; import StrictModeDroppable from "components/dnd/StrictModeDroppable"; // services -import projectService from "services/project.service/project.service"; -import pagesService from "services/page.service"; -import issuesService from "services/issue/issue.service"; +import { ProjectService } from "services/project"; +import { PageService } from "services/page.service"; +import { IssueLabelService } from "services/issue"; // hooks import useToast from "hooks/use-toast"; import useUser from "hooks/use-user"; @@ -28,7 +28,8 @@ import { CreateLabelModal } from "components/labels"; import { CreateBlock } from "components/pages/create-block"; // ui import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; -import { CustomSearchSelect, EmptyState } from "components/ui"; +import { CustomSearchSelect } from "components/ui"; +import { EmptyState } from "components/common"; import { TextArea, Loader, ToggleSwitch, Tooltip } from "@plane/ui"; // images import emptyPage from "public/empty-state/page.svg"; @@ -60,6 +61,11 @@ import { USER_PROJECT_VIEW, } from "constants/fetch-keys"; +// services +const projectService = new ProjectService(); +const pageService = new PageService(); +const issueLabelService = new IssueLabelService(); + const SinglePage: NextPage = () => { const [createBlockForm, setCreateBlockForm] = useState(false); const [labelModal, setLabelModal] = useState(false); @@ -86,20 +92,22 @@ const SinglePage: NextPage = () => { const { data: pageDetails, error } = useSWR( workspaceSlug && projectId && pageId ? PAGE_DETAILS(pageId as string) : null, workspaceSlug && projectId - ? () => pagesService.getPageDetails(workspaceSlug as string, projectId as string, pageId as string) + ? () => pageService.getPageDetails(workspaceSlug as string, projectId as string, pageId as string) : null ); const { data: pageBlocks } = useSWR( workspaceSlug && projectId && pageId ? PAGE_BLOCKS_LIST(pageId as string) : null, workspaceSlug && projectId - ? () => pagesService.listPageBlocks(workspaceSlug as string, projectId as string, pageId as string) + ? () => pageService.listPageBlocks(workspaceSlug as string, projectId as string, pageId as string) : null ); const { data: labels } = useSWR( workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(projectId as string) : null, - workspaceSlug && projectId ? () => issuesService.getIssueLabels(workspaceSlug as string, projectId as string) : null + workspaceSlug && projectId + ? () => issueLabelService.getProjectIssueLabels(workspaceSlug as string, projectId as string) + : null ); const { data: memberDetails } = useSWR( @@ -114,7 +122,7 @@ const SinglePage: NextPage = () => { if (!formData.name || formData.name.length === 0 || formData.name === "") return; - await pagesService + await pageService .patchPage(workspaceSlug as string, projectId as string, pageId as string, formData, user) .then(() => { mutate( @@ -141,7 +149,7 @@ const SinglePage: NextPage = () => { false ); - await pagesService + await pageService .patchPage(workspaceSlug as string, projectId as string, pageId as string, formData, user) .then(() => { mutate(PAGE_DETAILS(pageId as string)); @@ -166,7 +174,7 @@ const SinglePage: NextPage = () => { }); }); - pagesService.addPageToFavorites(workspaceSlug as string, projectId as string, { + pageService.addPageToFavorites(workspaceSlug as string, projectId as string, { page: pageId as string, }); }; @@ -189,7 +197,7 @@ const SinglePage: NextPage = () => { }); }); - pagesService.removePageFromFavorites(workspaceSlug as string, projectId as string, pageId as string); + pageService.removePageFromFavorites(workspaceSlug as string, projectId as string, pageId as string); }; const handleOnDragEnd = (result: DropResult) => { @@ -219,7 +227,7 @@ const SinglePage: NextPage = () => { false ); - pagesService.patchPageBlock( + pageService.patchPageBlock( workspaceSlug as string, projectId as string, pageId as string, diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/pages/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/pages/index.tsx index 8c2409d3c73..ca6745f9424 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/pages/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/pages/index.tsx @@ -8,7 +8,7 @@ import useSWR from "swr"; // headless ui import { Tab } from "@headlessui/react"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // hooks import useLocalStorage from "hooks/use-local-storage"; import useUserAuth from "hooks/use-user-auth"; @@ -49,6 +49,9 @@ const OtherPagesList = dynamic(() => import("components/pages") const tabsList = ["Recent", "All", "Favorites", "Created by me", "Created by others"]; +// services +const projectService = new ProjectService(); + const ProjectPages: NextPage = () => { const [createUpdatePageModal, setCreateUpdatePageModal] = useState(false); diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/settings/automations.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/settings/automations.tsx index c3fd348bcf4..afa2c088e50 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/settings/automations.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/settings/automations.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // layouts import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy"; // hooks @@ -25,6 +25,9 @@ import { PROJECTS_LIST, PROJECT_DETAILS, USER_PROJECT_VIEW } from "constants/fet // helper import { truncateText } from "helpers/string.helper"; +// services +const projectService = new ProjectService(); + const AutomationsSettings: NextPage = () => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/settings/estimates.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/settings/estimates.tsx index e643ca25c8d..271472c202b 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/settings/estimates.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/settings/estimates.tsx @@ -5,8 +5,7 @@ import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; // services -import estimatesService from "services/project.service/project_estimates.service"; -import projectService from "services/project.service/project.service"; +import { ProjectService, ProjectEstimateServices } from "services/project"; // hooks import useProjectDetails from "hooks/use-project-details"; // layouts @@ -19,7 +18,7 @@ import useToast from "hooks/use-toast"; import useUserAuth from "hooks/use-user-auth"; // ui import { Button, Loader } from "@plane/ui"; -import { EmptyState } from "components/ui"; +import { EmptyState } from "components/common"; import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; // icons import { PlusIcon } from "@heroicons/react/24/outline"; @@ -33,6 +32,10 @@ import { ESTIMATES_LIST, PROJECT_DETAILS } from "constants/fetch-keys"; // helper import { truncateText } from "helpers/string.helper"; +// services +const projectService = new ProjectService(); +const projectEstimateService = new ProjectEstimateServices(); + const EstimatesSettings: NextPage = () => { const [estimateFormOpen, setEstimateFormOpen] = useState(false); @@ -50,7 +53,7 @@ const EstimatesSettings: NextPage = () => { const { data: estimatesList } = useSWR( workspaceSlug && projectId ? ESTIMATES_LIST(projectId as string) : null, workspaceSlug && projectId - ? () => estimatesService.getEstimatesList(workspaceSlug as string, projectId as string) + ? () => projectEstimateService.getEstimatesList(workspaceSlug as string, projectId as string) : null ); @@ -68,7 +71,7 @@ const EstimatesSettings: NextPage = () => { false ); - estimatesService.deleteEstimate(workspaceSlug as string, projectId as string, estimateId, user).catch(() => { + projectEstimateService.deleteEstimate(workspaceSlug as string, projectId as string, estimateId, user).catch(() => { setToastAlert({ type: "error", title: "Error!", diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/settings/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/settings/index.tsx index a874be35259..06a5f1b0f83 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/settings/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/settings/index.tsx @@ -5,7 +5,7 @@ import { Disclosure, Transition } from "@headlessui/react"; // layouts import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy"; // services -import projectService from "services/project.service/project.service"; +import { ProjectService } from "services/project"; // components import { DeleteProjectModal, ProjectDetailsForm, ProjectDetailsFormLoader, SettingsSidebar } from "components/project"; // hooks @@ -17,19 +17,14 @@ import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; // helpers import { truncateText } from "helpers/string.helper"; // types -import { IProject } from "types"; import type { NextPage } from "next"; // fetch-keys -import { PROJECT_DETAILS, USER_PROJECT_VIEW } from "constants/fetch-keys"; +import { USER_PROJECT_VIEW } from "constants/fetch-keys"; import { useMobxStore } from "lib/mobx/store-provider"; import { observer } from "mobx-react-lite"; -const defaultValues: Partial = { - name: "", - description: "", - identifier: "", - network: 0, -}; +// services +const projectService = new ProjectService(); const GeneralSettings: NextPage = observer(() => { const { project: projectStore } = useMobxStore(); diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/settings/states.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/settings/states.tsx index 91cf4971c5c..0da70905aa5 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/settings/states.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/settings/states.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import stateService from "services/project.service/project_state.service"; +import { ProjectStateService } from "services/project"; // hooks import useProjectDetails from "hooks/use-project-details"; import useUserAuth from "hooks/use-user-auth"; @@ -27,6 +27,9 @@ import type { NextPage } from "next"; // fetch-keys import { STATES_LIST } from "constants/fetch-keys"; +// services +const projectStateService = new ProjectStateService(); + const StatesSettings: NextPage = () => { const [activeGroup, setActiveGroup] = useState(null); const [selectedState, setSelectedState] = useState(null); @@ -41,7 +44,9 @@ const StatesSettings: NextPage = () => { const { data: states } = useSWR( workspaceSlug && projectId ? STATES_LIST(projectId as string) : null, - workspaceSlug && projectId ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null + workspaceSlug && projectId + ? () => projectStateService.getStates(workspaceSlug as string, projectId as string) + : null ); const orderedStateGroups = orderStateGroups(states); const statesList = getStatesList(orderedStateGroups); diff --git a/web/pages/[workspaceSlug]/settings/imports.tsx b/web/pages/[workspaceSlug]/settings/imports.tsx index 95ee3f32fa0..c0b500637b0 100644 --- a/web/pages/[workspaceSlug]/settings/imports.tsx +++ b/web/pages/[workspaceSlug]/settings/imports.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // layouts import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy"; // components @@ -18,6 +18,9 @@ import { WORKSPACE_DETAILS } from "constants/fetch-keys"; // helper import { truncateText } from "helpers/string.helper"; +// services +const workspaceService = new WorkspaceService(); + const ImportExport: NextPage = () => { const router = useRouter(); const { workspaceSlug } = router.query; diff --git a/web/pages/[workspaceSlug]/settings/index.tsx b/web/pages/[workspaceSlug]/settings/index.tsx index aadc38b2321..2acf2f9604b 100644 --- a/web/pages/[workspaceSlug]/settings/index.tsx +++ b/web/pages/[workspaceSlug]/settings/index.tsx @@ -7,8 +7,8 @@ import useSWR, { mutate } from "swr"; // react-hook-form import { Controller, useForm } from "react-hook-form"; // services -import workspaceService from "services/workspace.service"; -import fileService from "services/file.service"; +import { WorkspaceService } from "services/workspace.service"; +import { FileService } from "services/file.service"; // hooks import useToast from "hooks/use-toast"; import useUserAuth from "hooks/use-user-auth"; @@ -42,6 +42,10 @@ const defaultValues: Partial = { logo: null, }; +// services +const workspaceService = new WorkspaceService(); +const fileService = new FileService(); + const WorkspaceSettings: NextPage = () => { const [isOpen, setIsOpen] = useState(false); const [isImageUploading, setIsImageUploading] = useState(false); diff --git a/web/pages/[workspaceSlug]/settings/members.tsx b/web/pages/[workspaceSlug]/settings/members.tsx index a42a0d336ae..3408540dc04 100644 --- a/web/pages/[workspaceSlug]/settings/members.tsx +++ b/web/pages/[workspaceSlug]/settings/members.tsx @@ -6,7 +6,7 @@ import { useRouter } from "next/router"; import useSWR from "swr"; // services -import workspaceService from "services/workspace.service"; +import { WorkspaceService } from "services/workspace.service"; // hooks import useToast from "hooks/use-toast"; import useUser from "hooks/use-user"; @@ -32,6 +32,9 @@ import { ROLE } from "constants/workspace"; // helper import { truncateText } from "helpers/string.helper"; +// services +const workspaceService = new WorkspaceService(); + const MembersSettings: NextPage = () => { const [selectedRemoveMember, setSelectedRemoveMember] = useState(null); const [selectedInviteRemoveMember, setSelectedInviteRemoveMember] = useState(null); diff --git a/web/pages/_error.tsx b/web/pages/_error.tsx index 699b7c5b6da..e131c4e014c 100644 --- a/web/pages/_error.tsx +++ b/web/pages/_error.tsx @@ -3,7 +3,7 @@ import * as Sentry from "@sentry/nextjs"; import { useRouter } from "next/router"; // services -import authenticationService from "services/auth.service"; +import { AuthService } from "services/auth.service"; // hooks import useToast from "hooks/use-toast"; // layouts @@ -11,13 +11,16 @@ import DefaultLayout from "layouts/default-layout"; // ui import { Button } from "@plane/ui"; +// services +const authService = new AuthService(); + const CustomErrorComponent = () => { const router = useRouter(); const { setToastAlert } = useToast(); const handleSignOut = async () => { - await authenticationService + await authService .signOut() .catch(() => setToastAlert({ diff --git a/web/pages/accounts/magic-sign-in.tsx b/web/pages/accounts/magic-sign-in.tsx index 076684e2633..e7322eb8c2b 100644 --- a/web/pages/accounts/magic-sign-in.tsx +++ b/web/pages/accounts/magic-sign-in.tsx @@ -7,13 +7,15 @@ import { useTheme } from "next-themes"; // layouts import DefaultLayout from "layouts/default-layout"; // services -import authenticationService from "services/auth.service"; +import { AuthService } from "services/auth.service"; // hooks import useUserAuth from "hooks/use-user-auth"; import useToast from "hooks/use-toast"; // types import type { NextPage } from "next"; +const authService = new AuthService(); + const MagicSignIn: NextPage = () => { const router = useRouter(); const { password, key } = router.query; @@ -39,9 +41,9 @@ const MagicSignIn: NextPage = () => { return; } else { setIsSigningIn(() => true); - authenticationService + authService .magicSignIn({ token: password, key }) - .then(async (res) => { + .then(async () => { setIsSigningIn(false); await mutateUser(); }) @@ -70,7 +72,7 @@ const MagicSignIn: NextPage = () => { { - authenticationService + authService .emailCode({ email: (key as string).split("_")[1] }) .then(() => { setToastAlert({ diff --git a/web/pages/accounts/reset-password.tsx b/web/pages/accounts/reset-password.tsx index 533f9df1204..18310931c4e 100644 --- a/web/pages/accounts/reset-password.tsx +++ b/web/pages/accounts/reset-password.tsx @@ -10,7 +10,7 @@ import { Controller, useForm } from "react-hook-form"; // hooks import useToast from "hooks/use-toast"; // services -import userService from "services/user.service"; +import { UserService } from "services/user.service"; // layouts import DefaultLayout from "layouts/default-layout"; // ui @@ -25,6 +25,9 @@ type FormData = { confirmPassword: string; }; +// services +const userService = new UserService(); + const ResetPasswordPage: NextPage = () => { const [isLoading, setIsLoading] = useState(true); @@ -36,7 +39,6 @@ const ResetPasswordPage: NextPage = () => { const { setTheme } = useTheme(); const { - register, handleSubmit, control, formState: { errors, isSubmitting }, diff --git a/web/pages/accounts/sign-up.tsx b/web/pages/accounts/sign-up.tsx index 8ccc7f6e93a..0a9aee79727 100644 --- a/web/pages/accounts/sign-up.tsx +++ b/web/pages/accounts/sign-up.tsx @@ -4,14 +4,14 @@ import { useRouter } from "next/router"; // next-themes import { useTheme } from "next-themes"; // services -import authenticationService from "services/auth.service"; +import { AuthService } from "services/auth.service"; // hooks import useUserAuth from "hooks/use-user-auth"; import useToast from "hooks/use-toast"; // layouts import DefaultLayout from "layouts/default-layout"; // components -import { EmailPasswordForm, EmailSignUpForm } from "components/account"; +import { EmailSignUpForm } from "components/account"; // images import BluePlaneLogoWithoutText from "public/plane-logos/blue-without-text.png"; // types @@ -22,6 +22,9 @@ type EmailPasswordFormValues = { medium?: string; }; +// services +const authService = new AuthService(); + const SignUp: NextPage = () => { const router = useRouter(); @@ -37,7 +40,7 @@ const SignUp: NextPage = () => { password: formData.password ?? "", }; - await authenticationService + await authService .emailSignUp(payload) .then(async (response) => { setToastAlert({ diff --git a/web/pages/m/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx b/web/pages/m/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx index 997bdb12b57..167b89de742 100644 --- a/web/pages/m/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx +++ b/web/pages/m/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx @@ -1,31 +1,19 @@ -// react import React, { useCallback, useEffect } from "react"; - -// next import { useRouter } from "next/router"; - -// swr import useSWR, { mutate } from "swr"; - -// react hook forms import { useFormContext, useForm, FormProvider } from "react-hook-form"; // services -import issuesService from "services/issue/issue.service"; - +import { IssueService, IssueArchiveService } from "services/issue"; // fetch key import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys"; - // hooks import useUser from "hooks/use-user"; import useProjectMembers from "hooks/use-project-members"; - // layouts import WebViewLayout from "layouts/web-view-layout"; - // ui import { Spinner } from "@plane/ui"; - // components import { IssueWebViewForm, @@ -34,12 +22,14 @@ import { IssuePropertiesDetail, IssueLinks, IssueActivity, - Spinner, } from "components/web-view"; - // types import type { IIssue } from "types"; +// services +const issueService = new IssueService(); +const issueArchiveService = new IssueArchiveService(); + const MobileWebViewIssueDetail_ = () => { const router = useRouter(); const { workspaceSlug, projectId, issueId } = router.query; @@ -62,19 +52,20 @@ const MobileWebViewIssueDetail_ = () => { } = useSWR( workspaceSlug && projectId && issueId && !isArchive ? ISSUE_DETAILS(issueId.toString()) : null, workspaceSlug && projectId && issueId && !isArchive - ? () => issuesService.retrieve(workspaceSlug.toString(), projectId.toString(), issueId.toString()) + ? () => issueService.retrieve(workspaceSlug.toString(), projectId.toString(), issueId.toString()) : null ); - const { data: archiveIssueDetails, mutate: mutateaArchiveIssue } = useSWR( + const { data: archiveIssueDetails, mutate: mutateArchiveIssue } = useSWR( workspaceSlug && projectId && issueId && isArchive ? ISSUE_DETAILS(issueId as string) : null, workspaceSlug && projectId && issueId && isArchive - ? () => issuesService.retrieveArchivedIssue(workspaceSlug.toString(), projectId.toString(), issueId.toString()) + ? () => + issueArchiveService.retrieveArchivedIssue(workspaceSlug.toString(), projectId.toString(), issueId.toString()) : null ); const issueDetails = isArchive ? archiveIssueDetails : issue; - const mutateIssueDetails = isArchive ? mutateaArchiveIssue : mutateIssue; + const mutateIssueDetails = isArchive ? mutateArchiveIssue : mutateIssue; useEffect(() => { if (!issueDetails) return; @@ -114,7 +105,7 @@ const MobileWebViewIssueDetail_ = () => { delete payload.issue_relations; delete payload.related_issues; - await issuesService + await issueService .patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user) .then(() => { mutateIssueDetails();