diff --git a/apps/app/components/analytics/custom-analytics/sidebar.tsx b/apps/app/components/analytics/custom-analytics/sidebar.tsx index 6d92424a0..5988e654d 100644 --- a/apps/app/components/analytics/custom-analytics/sidebar.tsx +++ b/apps/app/components/analytics/custom-analytics/sidebar.tsx @@ -13,7 +13,12 @@ import useToast from "hooks/use-toast"; // ui import { PrimaryButton, SecondaryButton } from "components/ui"; // icons -import { ArrowDownTrayIcon, ArrowPathIcon, UserGroupIcon } from "@heroicons/react/24/outline"; +import { + ArrowDownTrayIcon, + ArrowPathIcon, + CalendarDaysIcon, + UserGroupIcon, +} from "@heroicons/react/24/outline"; import { ContrastIcon, LayerDiagonalIcon } from "components/icons"; // helpers import { renderShortDate } from "helpers/date-time.helper"; @@ -106,11 +111,14 @@ export const AnalyticsSidebar: React.FC = ({ ); }; + const selectedProjects = + params.project && params.project.length > 0 ? params.project : projects.map((p) => p.id); + return (
@@ -119,15 +127,27 @@ export const AnalyticsSidebar: React.FC = ({ {analytics ? analytics.total : "..."} Issues
+ {isProjectLevel && ( +
+ + {renderShortDate( + (cycleId + ? cycleDetails?.created_at + : moduleId + ? moduleDetails?.created_at + : projectDetails?.created_at) ?? "" + )} +
+ )}
{fullScreen ? ( <> - {!isProjectLevel && params.project && params.project.length > 0 && ( + {!isProjectLevel && selectedProjects && selectedProjects.length > 0 && (

Selected Projects

- {params.project.map((projectId) => { + {selectedProjects.map((projectId) => { const project: IProject = projects.find((p) => p.id === projectId); return ( diff --git a/apps/app/components/analytics/project-modal.tsx b/apps/app/components/analytics/project-modal.tsx index 293d4e891..c2072642c 100644 --- a/apps/app/components/analytics/project-modal.tsx +++ b/apps/app/components/analytics/project-modal.tsx @@ -10,6 +10,9 @@ import { useForm } from "react-hook-form"; import { Tab } from "@headlessui/react"; // services import analyticsService from "services/analytics.service"; +import projectService from "services/project.service"; +import cyclesService from "services/cycles.service"; +import modulesService from "services/modules.service"; // components import { CustomAnalytics, ScopeAndDemand } from "components/analytics"; // icons @@ -21,7 +24,7 @@ import { // types import { IAnalyticsParams } from "types"; // fetch-keys -import { ANALYTICS } from "constants/fetch-keys"; +import { ANALYTICS, CYCLE_DETAILS, MODULE_DETAILS, PROJECT_DETAILS } from "constants/fetch-keys"; type Props = { isOpen: boolean; @@ -59,6 +62,39 @@ export const AnalyticsProjectModal: React.FC = ({ isOpen, onClose }) => { workspaceSlug ? () => analyticsService.getAnalytics(workspaceSlug.toString(), params) : null ); + const { data: projectDetails } = useSWR( + workspaceSlug && projectId && !(cycleId || moduleId) + ? PROJECT_DETAILS(projectId.toString()) + : null, + workspaceSlug && projectId && !(cycleId || moduleId) + ? () => projectService.getProject(workspaceSlug.toString(), projectId.toString()) + : null + ); + + const { data: cycleDetails } = useSWR( + workspaceSlug && projectId && cycleId ? CYCLE_DETAILS(cycleId.toString()) : null, + workspaceSlug && projectId && cycleId + ? () => + cyclesService.getCycleDetails( + workspaceSlug.toString(), + projectId.toString(), + cycleId.toString() + ) + : null + ); + + const { data: moduleDetails } = useSWR( + workspaceSlug && projectId && moduleId ? MODULE_DETAILS(moduleId.toString()) : null, + workspaceSlug && projectId && moduleId + ? () => + modulesService.getModuleDetails( + workspaceSlug.toString(), + projectId.toString(), + moduleId.toString() + ) + : null + ); + const handleClose = () => { onClose(); }; @@ -74,12 +110,11 @@ export const AnalyticsProjectModal: React.FC = ({ isOpen, onClose }) => { fullScreen ? "rounded-lg border" : "border-l" }`} > -
-

Project Analytics

+
+

+ Analytics for{" "} + {cycleId ? cycleDetails?.name : moduleId ? moduleDetails?.name : projectDetails?.name} +

- + {tabsList.map((tab) => ( = ({ isOpen, onClose }) => { ))} + {/*

Analytics for

*/} diff --git a/apps/app/components/analytics/scope-and-demand/leaderboard.tsx b/apps/app/components/analytics/scope-and-demand/leaderboard.tsx index 21a278709..9e28d0f3e 100644 --- a/apps/app/components/analytics/scope-and-demand/leaderboard.tsx +++ b/apps/app/components/analytics/scope-and-demand/leaderboard.tsx @@ -14,32 +14,39 @@ type Props = { export const AnalyticsLeaderboard: React.FC = ({ users, title }) => (
{title}
-
- {users.map((user) => ( -
-
- {user && user.avatar && user.avatar !== "" ? ( -
- {user.email -
- ) : ( -
- {user.firstName !== "" ? user.firstName[0] : "?"} -
- )} - - {user.firstName !== "" ? `${user.firstName} ${user.lastName}` : "No assignee"} - + {users.length > 0 ? ( +
+ {users.map((user) => ( +
+
+ {user && user.avatar && user.avatar !== "" ? ( +
+ {user.email +
+ ) : ( +
+ {user.firstName !== "" ? user.firstName[0] : "?"} +
+ )} + + {user.firstName !== "" ? `${user.firstName} ${user.lastName}` : "No assignee"} + +
+ {user.count}
- {user.count} -
- ))} -
+ ))} +
+ ) : ( +
No matching data found.
+ )}
); diff --git a/apps/app/components/analytics/scope-and-demand/scope.tsx b/apps/app/components/analytics/scope-and-demand/scope.tsx index 93ea71091..6697b775b 100644 --- a/apps/app/components/analytics/scope-and-demand/scope.tsx +++ b/apps/app/components/analytics/scope-and-demand/scope.tsx @@ -13,56 +13,72 @@ export const AnalyticsScope: React.FC = ({ defaultAnalytics }) => (
Pending issues
- `#f97316`} - customYAxisTickValues={defaultAnalytics.pending_issue_user.map((d) => d.count)} - tooltip={(datum) => ( -
- - Issue count- {datum.indexValue ?? "No assignee"}:{" "} - - {datum.value} -
- )} - axisBottom={{ - renderTick: (datum) => { - const avatar = - defaultAnalytics.pending_issue_user[datum.tickIndex].assignees__avatar ?? ""; + {defaultAnalytics.pending_issue_user.length > 0 ? ( + `#f97316`} + customYAxisTickValues={defaultAnalytics.pending_issue_user.map((d) => d.count)} + tooltip={(datum) => { + const assignee = defaultAnalytics.pending_issue_user.find( + (a) => a.assignees__email === `${datum.indexValue}` + ); - if (avatar && avatar !== "") - return ( - - - - ); - else - return ( - - - - {datum.value ? `${datum.value}`.toUpperCase()[0] : "?"} - - - ); - }, - }} - margin={{ top: 20 }} - theme={{ - background: "rgb(var(--color-bg-base))", - axis: {}, - }} - /> + return ( +
+ + Issue count-{" "} + {assignee + ? assignee.assignees__first_name + " " + assignee.assignees__last_name + : "No assignee"} + :{" "} + + {datum.value} +
+ ); + }} + axisBottom={{ + renderTick: (datum) => { + const avatar = + defaultAnalytics.pending_issue_user[datum.tickIndex].assignees__avatar ?? ""; + + if (avatar && avatar !== "") + return ( + + + + ); + else + return ( + + + + {datum.value ? `${datum.value}`.toUpperCase()[0] : "?"} + + + ); + }, + }} + margin={{ top: 20 }} + theme={{ + background: "rgb(var(--color-bg-base))", + axis: {}, + }} + /> + ) : ( +
+ No matching data found. +
+ )}
diff --git a/apps/app/components/analytics/scope-and-demand/year-wise-issues.tsx b/apps/app/components/analytics/scope-and-demand/year-wise-issues.tsx index e8f03e736..863eb664b 100644 --- a/apps/app/components/analytics/scope-and-demand/year-wise-issues.tsx +++ b/apps/app/components/analytics/scope-and-demand/year-wise-issues.tsx @@ -17,34 +17,38 @@ export const AnalyticsYearWiseIssues: React.FC = ({ defaultAnalytics }) = return (

Issues closed in a year

- ({ - x: month.label.substring(0, 3), - y: - defaultAnalytics.issue_completed_month_wise.find( - (data) => data.month === month.value - )?.count || 0, - })), - }, - ]} - customYAxisTickValues={defaultAnalytics.issue_completed_month_wise.map((data) => { - if (quarterMonthsList.includes(data.month)) return data.count; + {defaultAnalytics.issue_completed_month_wise.length > 0 ? ( + ({ + x: month.label.substring(0, 3), + y: + defaultAnalytics.issue_completed_month_wise.find( + (data) => data.month === month.value + )?.count || 0, + })), + }, + ]} + customYAxisTickValues={defaultAnalytics.issue_completed_month_wise.map((data) => { + if (quarterMonthsList.includes(data.month)) return data.count; - return 0; - })} - height="300px" - colors={(datum) => datum.color} - curve="monotoneX" - margin={{ top: 20 }} - theme={{ - background: "rgb(var(--color-bg-base))", - }} - enableArea - /> + return 0; + })} + height="300px" + colors={(datum) => datum.color} + curve="monotoneX" + margin={{ top: 20 }} + theme={{ + background: "rgb(var(--color-bg-base))", + }} + enableArea + /> + ) : ( +
No matching data found.
+ )}
); }; diff --git a/apps/app/components/core/issues-view.tsx b/apps/app/components/core/issues-view.tsx index 0557603f8..0afd54237 100644 --- a/apps/app/components/core/issues-view.tsx +++ b/apps/app/components/core/issues-view.tsx @@ -6,6 +6,7 @@ import useSWR, { mutate } from "swr"; // react-beautiful-dnd import { DragDropContext, DropResult } from "react-beautiful-dnd"; +import StrictModeDroppable from "components/dnd/StrictModeDroppable"; // services import issuesService from "services/issues.service"; import stateService from "services/state.service"; @@ -19,7 +20,6 @@ import useIssuesView from "hooks/use-issues-view"; // components import { AllLists, AllBoards, FilterList, CalendarView } from "components/core"; import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues"; -import StrictModeDroppable from "components/dnd/StrictModeDroppable"; import { CreateUpdateViewModal } from "components/views"; import { TransferIssues, TransferIssuesModal } from "components/cycles"; // ui @@ -47,7 +47,6 @@ import { PROJECT_ISSUES_LIST_WITH_PARAMS, STATES_LIST, } from "constants/fetch-keys"; -// image type Props = { type?: "issue" | "cycle" | "module"; @@ -445,27 +444,25 @@ export const IssuesView: React.FC = ({ <>
- {areFiltersApplied && ( - { - if (viewId) { - setFilters({}, true); - setToastAlert({ - title: "View updated", - message: "Your view has been updated", - type: "success", - }); - } else - setCreateViewModal({ - query: filters, - }); - }} - className="flex items-center gap-2 text-sm" - > - {!viewId && } - {viewId ? "Update" : "Save"} view - - )} + { + if (viewId) { + setFilters({}, true); + setToastAlert({ + title: "View updated", + message: "Your view has been updated", + type: "success", + }); + } else + setCreateViewModal({ + query: filters, + }); + }} + className="flex items-center gap-2 text-sm" + > + {!viewId && } + {viewId ? "Update" : "Save"} view +
{
} @@ -477,14 +474,14 @@ export const IssuesView: React.FC = ({
- Drop issue here to delete + Drop here to delete the issue.
)} diff --git a/apps/app/components/issues/attachment-upload.tsx b/apps/app/components/issues/attachment-upload.tsx index 7ad8d1d35..7e5184ce8 100644 --- a/apps/app/components/issues/attachment-upload.tsx +++ b/apps/app/components/issues/attachment-upload.tsx @@ -74,7 +74,7 @@ export const IssueAttachmentUpload = () => { onDrop, maxSize: maxFileSize, multiple: false, - disabled: isLoading + disabled: isLoading, }); const fileError = @@ -85,8 +85,8 @@ export const IssueAttachmentUpload = () => { return (
diff --git a/apps/app/components/issues/sidebar.tsx b/apps/app/components/issues/sidebar.tsx index 6688effa8..869dda5c1 100644 --- a/apps/app/components/issues/sidebar.tsx +++ b/apps/app/components/issues/sidebar.tsx @@ -450,7 +450,7 @@ export const IssueDetailsSidebar: React.FC = ({ leaveFrom="opacity-100" leaveTo="opacity-0" > - +
{issueLabels ? ( issueLabels.length > 0 ? ( @@ -468,8 +468,8 @@ export const IssueDetailsSidebar: React.FC = ({ `${ active || selected ? "bg-brand-surface-1" : "" } ${ - selected ? "font-medium" : "" - } flex cursor-pointer select-none items-center gap-2 truncate p-2 text-brand-base` + selected ? "" : "text-brand-secondary" + } flex cursor-pointer select-none items-center gap-2 truncate p-2` } value={label.id} > @@ -489,7 +489,7 @@ export const IssueDetailsSidebar: React.FC = ({ return (
- {" "} + {label.name}
@@ -497,9 +497,9 @@ export const IssueDetailsSidebar: React.FC = ({ - `${active || selected ? "bg-indigo-50" : ""} ${ - selected ? "font-medium" : "" - } flex cursor-pointer select-none items-center gap-2 truncate p-2 text-brand-base` + `${active || selected ? "bg-brand-base" : ""} ${ + selected ? "" : "text-brand-secondary" + } flex cursor-pointer select-none items-center gap-2 truncate p-2` } value={child.id} >