mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
Merge branch 'develop' of gurusainath:makeplane/plane into feat/mobx-global-views
This commit is contained in:
commit
fe505e6b31
@ -243,6 +243,29 @@ class CycleAPIEndpoint(WebhookMixin, BaseAPIView):
|
|||||||
):
|
):
|
||||||
serializer = CycleSerializer(data=request.data)
|
serializer = CycleSerializer(data=request.data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
|
if (
|
||||||
|
request.data.get("external_id")
|
||||||
|
and request.data.get("external_source")
|
||||||
|
and Cycle.objects.filter(
|
||||||
|
project_id=project_id,
|
||||||
|
workspace__slug=slug,
|
||||||
|
external_source=request.data.get("external_source"),
|
||||||
|
external_id=request.data.get("external_id"),
|
||||||
|
).exists()
|
||||||
|
):
|
||||||
|
cycle = Cycle.objects.filter(
|
||||||
|
workspace__slug=slug,
|
||||||
|
project_id=project_id,
|
||||||
|
external_source=request.data.get("external_source"),
|
||||||
|
external_id=request.data.get("external_id"),
|
||||||
|
).first()
|
||||||
|
return Response(
|
||||||
|
{
|
||||||
|
"error": "Cycle with the same external id and external source already exists",
|
||||||
|
"cycle": str(cycle.id),
|
||||||
|
},
|
||||||
|
status=status.HTTP_409_CONFLICT,
|
||||||
|
)
|
||||||
serializer.save(
|
serializer.save(
|
||||||
project_id=project_id,
|
project_id=project_id,
|
||||||
owned_by=request.user,
|
owned_by=request.user,
|
||||||
@ -289,6 +312,23 @@ class CycleAPIEndpoint(WebhookMixin, BaseAPIView):
|
|||||||
|
|
||||||
serializer = CycleSerializer(cycle, data=request.data, partial=True)
|
serializer = CycleSerializer(cycle, data=request.data, partial=True)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
|
if (
|
||||||
|
request.data.get("external_id")
|
||||||
|
and (cycle.external_id != request.data.get("external_id"))
|
||||||
|
and Cycle.objects.filter(
|
||||||
|
project_id=project_id,
|
||||||
|
workspace__slug=slug,
|
||||||
|
external_source=request.data.get("external_source", cycle.external_source),
|
||||||
|
external_id=request.data.get("external_id"),
|
||||||
|
).exists()
|
||||||
|
):
|
||||||
|
return Response(
|
||||||
|
{
|
||||||
|
"error": "Cycle with the same external id and external source already exists",
|
||||||
|
"cycle_id": str(cycle.id),
|
||||||
|
},
|
||||||
|
status=status.HTTP_409_CONFLICT,
|
||||||
|
)
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
@ -220,6 +220,30 @@ class IssueAPIEndpoint(WebhookMixin, BaseAPIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
|
if (
|
||||||
|
request.data.get("external_id")
|
||||||
|
and request.data.get("external_source")
|
||||||
|
and Issue.objects.filter(
|
||||||
|
project_id=project_id,
|
||||||
|
workspace__slug=slug,
|
||||||
|
external_source=request.data.get("external_source"),
|
||||||
|
external_id=request.data.get("external_id"),
|
||||||
|
).exists()
|
||||||
|
):
|
||||||
|
issue = Issue.objects.filter(
|
||||||
|
workspace__slug=slug,
|
||||||
|
project_id=project_id,
|
||||||
|
external_id=request.data.get("external_id"),
|
||||||
|
external_source=request.data.get("external_source"),
|
||||||
|
).first()
|
||||||
|
return Response(
|
||||||
|
{
|
||||||
|
"error": "Issue with the same external id and external source already exists",
|
||||||
|
"issue_id": str(issue.id),
|
||||||
|
},
|
||||||
|
status=status.HTTP_409_CONFLICT,
|
||||||
|
)
|
||||||
|
|
||||||
serializer.save()
|
serializer.save()
|
||||||
|
|
||||||
# Track the issue
|
# Track the issue
|
||||||
@ -256,6 +280,24 @@ class IssueAPIEndpoint(WebhookMixin, BaseAPIView):
|
|||||||
partial=True,
|
partial=True,
|
||||||
)
|
)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
|
if (
|
||||||
|
str(request.data.get("external_id"))
|
||||||
|
and (issue.external_id != str(request.data.get("external_id")))
|
||||||
|
and Issue.objects.filter(
|
||||||
|
project_id=project_id,
|
||||||
|
workspace__slug=slug,
|
||||||
|
external_source=request.data.get("external_source", issue.external_source),
|
||||||
|
external_id=request.data.get("external_id"),
|
||||||
|
).exists()
|
||||||
|
):
|
||||||
|
return Response(
|
||||||
|
{
|
||||||
|
"error": "Issue with the same external id and external source already exists",
|
||||||
|
"issue_id": str(issue.id),
|
||||||
|
},
|
||||||
|
status=status.HTTP_409_CONFLICT,
|
||||||
|
)
|
||||||
|
|
||||||
serializer.save()
|
serializer.save()
|
||||||
issue_activity.delay(
|
issue_activity.delay(
|
||||||
type="issue.activity.updated",
|
type="issue.activity.updated",
|
||||||
@ -263,6 +305,8 @@ class IssueAPIEndpoint(WebhookMixin, BaseAPIView):
|
|||||||
actor_id=str(request.user.id),
|
actor_id=str(request.user.id),
|
||||||
issue_id=str(pk),
|
issue_id=str(pk),
|
||||||
project_id=str(project_id),
|
project_id=str(project_id),
|
||||||
|
external_id__isnull=False,
|
||||||
|
external_source__isnull=False,
|
||||||
current_instance=current_instance,
|
current_instance=current_instance,
|
||||||
epoch=int(timezone.now().timestamp()),
|
epoch=int(timezone.now().timestamp()),
|
||||||
)
|
)
|
||||||
|
@ -132,6 +132,29 @@ class ModuleAPIEndpoint(WebhookMixin, BaseAPIView):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
|
if (
|
||||||
|
request.data.get("external_id")
|
||||||
|
and request.data.get("external_source")
|
||||||
|
and Module.objects.filter(
|
||||||
|
project_id=project_id,
|
||||||
|
workspace__slug=slug,
|
||||||
|
external_source=request.data.get("external_source"),
|
||||||
|
external_id=request.data.get("external_id"),
|
||||||
|
).exists()
|
||||||
|
):
|
||||||
|
module = Module.objects.filter(
|
||||||
|
project_id=project_id,
|
||||||
|
workspace__slug=slug,
|
||||||
|
external_source=request.data.get("external_source"),
|
||||||
|
external_id=request.data.get("external_id"),
|
||||||
|
).first()
|
||||||
|
return Response(
|
||||||
|
{
|
||||||
|
"error": "Module with the same external id and external source already exists",
|
||||||
|
"module_id": str(module.id),
|
||||||
|
},
|
||||||
|
status=status.HTTP_409_CONFLICT,
|
||||||
|
)
|
||||||
serializer.save()
|
serializer.save()
|
||||||
module = Module.objects.get(pk=serializer.data["id"])
|
module = Module.objects.get(pk=serializer.data["id"])
|
||||||
serializer = ModuleSerializer(module)
|
serializer = ModuleSerializer(module)
|
||||||
@ -149,8 +172,25 @@ class ModuleAPIEndpoint(WebhookMixin, BaseAPIView):
|
|||||||
partial=True,
|
partial=True,
|
||||||
)
|
)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
|
if (
|
||||||
|
request.data.get("external_id")
|
||||||
|
and (module.external_id != request.data.get("external_id"))
|
||||||
|
and Module.objects.filter(
|
||||||
|
project_id=project_id,
|
||||||
|
workspace__slug=slug,
|
||||||
|
external_source=request.data.get("external_source", module.external_source),
|
||||||
|
external_id=request.data.get("external_id"),
|
||||||
|
).exists()
|
||||||
|
):
|
||||||
|
return Response(
|
||||||
|
{
|
||||||
|
"error": "Module with the same external id and external source already exists",
|
||||||
|
"module_id": str(module.id),
|
||||||
|
},
|
||||||
|
status=status.HTTP_409_CONFLICT,
|
||||||
|
)
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
def get(self, request, slug, project_id, pk=None):
|
def get(self, request, slug, project_id, pk=None):
|
||||||
|
@ -38,6 +38,30 @@ class StateAPIEndpoint(BaseAPIView):
|
|||||||
data=request.data, context={"project_id": project_id}
|
data=request.data, context={"project_id": project_id}
|
||||||
)
|
)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
|
if (
|
||||||
|
request.data.get("external_id")
|
||||||
|
and request.data.get("external_source")
|
||||||
|
and State.objects.filter(
|
||||||
|
project_id=project_id,
|
||||||
|
workspace__slug=slug,
|
||||||
|
external_source=request.data.get("external_source"),
|
||||||
|
external_id=request.data.get("external_id"),
|
||||||
|
).exists()
|
||||||
|
):
|
||||||
|
state = State.objects.filter(
|
||||||
|
workspace__slug=slug,
|
||||||
|
project_id=project_id,
|
||||||
|
external_id=request.data.get("external_id"),
|
||||||
|
external_source=request.data.get("external_source"),
|
||||||
|
).first()
|
||||||
|
return Response(
|
||||||
|
{
|
||||||
|
"error": "State with the same external id and external source already exists",
|
||||||
|
"state_id": str(state.id),
|
||||||
|
},
|
||||||
|
status=status.HTTP_409_CONFLICT,
|
||||||
|
)
|
||||||
|
|
||||||
serializer.save(project_id=project_id)
|
serializer.save(project_id=project_id)
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
@ -91,6 +115,23 @@ class StateAPIEndpoint(BaseAPIView):
|
|||||||
)
|
)
|
||||||
serializer = StateSerializer(state, data=request.data, partial=True)
|
serializer = StateSerializer(state, data=request.data, partial=True)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
|
if (
|
||||||
|
str(request.data.get("external_id"))
|
||||||
|
and (state.external_id != str(request.data.get("external_id")))
|
||||||
|
and State.objects.filter(
|
||||||
|
project_id=project_id,
|
||||||
|
workspace__slug=slug,
|
||||||
|
external_source=request.data.get("external_source", state.external_source),
|
||||||
|
external_id=request.data.get("external_id"),
|
||||||
|
).exists()
|
||||||
|
):
|
||||||
|
return Response(
|
||||||
|
{
|
||||||
|
"error": "State with the same external id and external source already exists",
|
||||||
|
"state_id": str(state.id),
|
||||||
|
},
|
||||||
|
status=status.HTTP_409_CONFLICT,
|
||||||
|
)
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
@ -47,6 +47,7 @@ export const PriorityIcon: React.FC<IPriorityIcon> = (props) => {
|
|||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
size={size}
|
size={size}
|
||||||
|
viewBox="0 0 23.5 24"
|
||||||
className={cn(
|
className={cn(
|
||||||
{
|
{
|
||||||
"text-white": priority === "urgent",
|
"text-white": priority === "urgent",
|
||||||
|
@ -89,8 +89,8 @@ export const DeactivateAccountModal: React.FC<Props> = (props) => {
|
|||||||
<div className="px-4 pb-4 pt-5 sm:p-6 sm:pb-4">
|
<div className="px-4 pb-4 pt-5 sm:p-6 sm:pb-4">
|
||||||
<div className="">
|
<div className="">
|
||||||
<div className="flex items-start gap-x-4">
|
<div className="flex items-start gap-x-4">
|
||||||
<div className="grid place-items-center rounded-full bg-red-500/20 p-4">
|
<div className="grid place-items-center rounded-full bg-red-500/20 p-2 sm:p-2 md:p-4 lg:p-4 mt-3 sm:mt-3 md:mt-0 lg:mt-0 ">
|
||||||
<Trash2 className="h-6 w-6 text-red-600" aria-hidden="true" />
|
<Trash2 className="h-4 w-4 sm:h-4 sm:w-4 md:h-6 md:w-6 lg:h-6 lg:w-6 text-red-600" aria-hidden="true" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Dialog.Title as="h3" className="my-4 text-2xl font-medium leading-6 text-custom-text-100">
|
<Dialog.Title as="h3" className="my-4 text-2xl font-medium leading-6 text-custom-text-100">
|
||||||
|
@ -26,11 +26,11 @@ export const DurationFilterDropdown: React.FC<Props> = (props) => {
|
|||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
closeOnSelect
|
closeOnSelect
|
||||||
>
|
>
|
||||||
{DURATION_FILTER_OPTIONS.map((option) => (
|
{DURATION_FILTER_OPTIONS.map((option) => (
|
||||||
<CustomMenu.MenuItem key={option.key} onClick={() => onChange(option.key)}>
|
<CustomMenu.MenuItem key={option.key} onClick={() => onChange(option.key)}>
|
||||||
{option.label}
|
{option.label}
|
||||||
</CustomMenu.MenuItem>
|
</CustomMenu.MenuItem>
|
||||||
))}
|
))}
|
||||||
</CustomMenu>
|
</CustomMenu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -77,7 +77,7 @@ export const WidgetIssuesList: React.FC<WidgetIssuesListProps> = (props) => {
|
|||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
Issues
|
Issues
|
||||||
<span className="flex-shrink-0 bg-custom-primary-100/20 text-custom-primary-100 text-xs font-medium rounded-xl h-4 min-w-6 flex items-center text-center justify-center">
|
<span className="flex-shrink-0 bg-custom-primary-100/20 text-custom-primary-100 text-xs font-medium rounded-xl px-3 flex items-center text-center justify-center">
|
||||||
{totalIssues}
|
{totalIssues}
|
||||||
</span>
|
</span>
|
||||||
</h6>
|
</h6>
|
||||||
|
@ -9,6 +9,7 @@ import { WidgetLoader } from "components/dashboard/widgets";
|
|||||||
import { renderFormattedPayloadDate } from "helpers/date-time.helper";
|
import { renderFormattedPayloadDate } from "helpers/date-time.helper";
|
||||||
// types
|
// types
|
||||||
import { TOverviewStatsWidgetResponse } from "@plane/types";
|
import { TOverviewStatsWidgetResponse } from "@plane/types";
|
||||||
|
import { cn } from "helpers/common.helper";
|
||||||
|
|
||||||
export type WidgetProps = {
|
export type WidgetProps = {
|
||||||
dashboardId: string;
|
dashboardId: string;
|
||||||
@ -71,10 +72,18 @@ export const OverviewStatsWidget: React.FC<WidgetProps> = observer((props) => {
|
|||||||
[&>div:nth-child(2)>a>div]:lg:border-r
|
[&>div:nth-child(2)>a>div]:lg:border-r
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{STATS_LIST.map((stat) => (
|
{STATS_LIST.map((stat, index) => (
|
||||||
<div className="w-full flex flex-col gap-2 hover:bg-custom-background-80 rounded-[10px]">
|
<div
|
||||||
|
className={cn(
|
||||||
|
`w-full flex flex-col gap-2 hover:bg-custom-background-80`,
|
||||||
|
index === 0 ? "rounded-tl-xl lg:rounded-l-xl" : "",
|
||||||
|
index === STATS_LIST.length - 1 ? "rounded-br-xl lg:rounded-r-xl" : "",
|
||||||
|
index === 1 ? "rounded-tr-xl lg:rounded-[0px]" : "",
|
||||||
|
index == 2 ? "rounded-bl-xl lg:rounded-[0px]" : ""
|
||||||
|
)}
|
||||||
|
>
|
||||||
<Link href={stat.link} className="py-4 duration-300 rounded-[10px] w-full ">
|
<Link href={stat.link} className="py-4 duration-300 rounded-[10px] w-full ">
|
||||||
<div className={`relative flex justify-center items-center`}>
|
<div className={`relative flex pl-10 sm:pl-20 md:pl-20 lg:pl-20 items-center`}>
|
||||||
<div>
|
<div>
|
||||||
<h5 className="font-semibold text-xl">{stat.count}</h5>
|
<h5 className="font-semibold text-xl">{stat.count}</h5>
|
||||||
<p className="text-custom-text-300 text-sm xl:text-base">{stat.title}</p>
|
<p className="text-custom-text-300 text-sm xl:text-base">{stat.title}</p>
|
||||||
|
@ -18,7 +18,7 @@ export const WorkspaceDashboardHeader = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ProductUpdatesModal isOpen={isProductUpdatesModalOpen} setIsOpen={setIsProductUpdatesModalOpen} />
|
<ProductUpdatesModal isOpen={isProductUpdatesModalOpen} setIsOpen={setIsProductUpdatesModalOpen} />
|
||||||
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
|
<div className="relative z-20 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
|
||||||
<div className="flex items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
<div className="flex items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||||
<SidebarHamburgerToggle />
|
<SidebarHamburgerToggle />
|
||||||
<div>
|
<div>
|
||||||
|
@ -237,7 +237,7 @@ export const BaseKanBanRoot: React.FC<IBaseKanBanLayout> = observer((props: IBas
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="horizontal-scroll-enable relative h-full w-full overflow-auto bg-custom-background-90">
|
<div className="horizontal-scroll-enable relative h-full w-full overflow-auto bg-custom-background-90">
|
||||||
<div className="relative h-full w-max min-w-full bg-custom-background-90 px-2">
|
<div className="relative h-max w-max min-w-full bg-custom-background-90 px-2">
|
||||||
<DragDropContext onDragStart={onDragStart} onDragEnd={onDragEnd}>
|
<DragDropContext onDragStart={onDragStart} onDragEnd={onDragEnd}>
|
||||||
{/* drag and delete component */}
|
{/* drag and delete component */}
|
||||||
<div
|
<div
|
||||||
|
@ -148,9 +148,15 @@ export const AllIssueLayoutRoot: React.FC = observer(() => {
|
|||||||
|
|
||||||
const handleDisplayFiltersUpdate = useCallback(
|
const handleDisplayFiltersUpdate = useCallback(
|
||||||
(updatedDisplayFilter: Partial<IIssueDisplayFilterOptions>) => {
|
(updatedDisplayFilter: Partial<IIssueDisplayFilterOptions>) => {
|
||||||
if (!workspaceSlug) return;
|
if (!workspaceSlug || !globalViewId) return;
|
||||||
|
|
||||||
updateFilters(workspaceSlug.toString(), undefined, EIssueFilterType.DISPLAY_FILTERS, { ...updatedDisplayFilter });
|
updateFilters(
|
||||||
|
workspaceSlug.toString(),
|
||||||
|
undefined,
|
||||||
|
EIssueFilterType.DISPLAY_FILTERS,
|
||||||
|
{ ...updatedDisplayFilter },
|
||||||
|
globalViewId.toString()
|
||||||
|
);
|
||||||
},
|
},
|
||||||
[updateFilters, workspaceSlug]
|
[updateFilters, workspaceSlug]
|
||||||
);
|
);
|
||||||
|
@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
|
|||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { Dialog, Transition } from "@headlessui/react";
|
import { Dialog, Transition } from "@headlessui/react";
|
||||||
// hooks
|
// hooks
|
||||||
import { useApplication, useCycle, useIssues, useModule, useProject, useUser, useWorkspace } from "hooks/store";
|
import { useApplication, useCycle, useIssues, useModule, useProject, useWorkspace } from "hooks/store";
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
import useLocalStorage from "hooks/use-local-storage";
|
import useLocalStorage from "hooks/use-local-storage";
|
||||||
// components
|
// components
|
||||||
@ -32,7 +32,6 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
|
|||||||
const {
|
const {
|
||||||
eventTracker: { postHogEventTracker },
|
eventTracker: { postHogEventTracker },
|
||||||
} = useApplication();
|
} = useApplication();
|
||||||
const { currentUser } = useUser();
|
|
||||||
const {
|
const {
|
||||||
router: { workspaceSlug, projectId, cycleId, moduleId, viewId: projectViewId },
|
router: { workspaceSlug, projectId, cycleId, moduleId, viewId: projectViewId },
|
||||||
} = useApplication();
|
} = useApplication();
|
||||||
@ -49,27 +48,22 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
|
|||||||
const issueStores = {
|
const issueStores = {
|
||||||
[EIssuesStoreType.PROJECT]: {
|
[EIssuesStoreType.PROJECT]: {
|
||||||
store: projectIssues,
|
store: projectIssues,
|
||||||
dataIdToUpdate: activeProjectId,
|
|
||||||
viewId: undefined,
|
viewId: undefined,
|
||||||
},
|
},
|
||||||
[EIssuesStoreType.PROJECT_VIEW]: {
|
[EIssuesStoreType.PROJECT_VIEW]: {
|
||||||
store: viewIssues,
|
store: viewIssues,
|
||||||
dataIdToUpdate: activeProjectId,
|
|
||||||
viewId: projectViewId,
|
viewId: projectViewId,
|
||||||
},
|
},
|
||||||
[EIssuesStoreType.PROFILE]: {
|
[EIssuesStoreType.PROFILE]: {
|
||||||
store: profileIssues,
|
store: profileIssues,
|
||||||
dataIdToUpdate: currentUser?.id || undefined,
|
|
||||||
viewId: undefined,
|
viewId: undefined,
|
||||||
},
|
},
|
||||||
[EIssuesStoreType.CYCLE]: {
|
[EIssuesStoreType.CYCLE]: {
|
||||||
store: cycleIssues,
|
store: cycleIssues,
|
||||||
dataIdToUpdate: activeProjectId,
|
|
||||||
viewId: cycleId,
|
viewId: cycleId,
|
||||||
},
|
},
|
||||||
[EIssuesStoreType.MODULE]: {
|
[EIssuesStoreType.MODULE]: {
|
||||||
store: moduleIssues,
|
store: moduleIssues,
|
||||||
dataIdToUpdate: activeProjectId,
|
|
||||||
viewId: moduleId,
|
viewId: moduleId,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -78,7 +72,7 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
|
|||||||
// local storage
|
// local storage
|
||||||
const { setValue: setLocalStorageDraftIssue } = useLocalStorage<any>("draftedIssue", {});
|
const { setValue: setLocalStorageDraftIssue } = useLocalStorage<any>("draftedIssue", {});
|
||||||
// current store details
|
// current store details
|
||||||
const { store: currentIssueStore, viewId, dataIdToUpdate } = issueStores[storeType];
|
const { store: currentIssueStore, viewId } = issueStores[storeType];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// if modal is closed, reset active project to null
|
// if modal is closed, reset active project to null
|
||||||
@ -129,13 +123,13 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleCreateIssue = async (payload: Partial<TIssue>): Promise<TIssue | undefined> => {
|
const handleCreateIssue = async (payload: Partial<TIssue>): Promise<TIssue | undefined> => {
|
||||||
if (!workspaceSlug || !dataIdToUpdate) return;
|
if (!workspaceSlug || !payload.project_id) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await currentIssueStore.createIssue(workspaceSlug, dataIdToUpdate, payload, viewId);
|
const response = await currentIssueStore.createIssue(workspaceSlug, payload.project_id, payload, viewId);
|
||||||
if (!response) throw new Error();
|
if (!response) throw new Error();
|
||||||
|
|
||||||
currentIssueStore.fetchIssues(workspaceSlug, dataIdToUpdate, "mutation", viewId);
|
currentIssueStore.fetchIssues(workspaceSlug, payload.project_id, "mutation", viewId);
|
||||||
|
|
||||||
if (payload.cycle_id && payload.cycle_id !== "" && storeType !== EIssuesStoreType.CYCLE)
|
if (payload.cycle_id && payload.cycle_id !== "" && storeType !== EIssuesStoreType.CYCLE)
|
||||||
await addIssueToCycle(response, payload.cycle_id);
|
await addIssueToCycle(response, payload.cycle_id);
|
||||||
@ -182,10 +176,10 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdateIssue = async (payload: Partial<TIssue>): Promise<TIssue | undefined> => {
|
const handleUpdateIssue = async (payload: Partial<TIssue>): Promise<TIssue | undefined> => {
|
||||||
if (!workspaceSlug || !dataIdToUpdate || !data?.id) return;
|
if (!workspaceSlug || !payload.project_id || !data?.id) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await currentIssueStore.updateIssue(workspaceSlug, dataIdToUpdate, data.id, payload, viewId);
|
const response = await currentIssueStore.updateIssue(workspaceSlug, payload.project_id, data.id, payload, viewId);
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
type: "success",
|
type: "success",
|
||||||
title: "Success!",
|
title: "Success!",
|
||||||
@ -226,7 +220,7 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleFormSubmit = async (formData: Partial<TIssue>) => {
|
const handleFormSubmit = async (formData: Partial<TIssue>) => {
|
||||||
if (!workspaceSlug || !dataIdToUpdate || !storeType) return;
|
if (!workspaceSlug || !formData.project_id || !storeType) return;
|
||||||
|
|
||||||
const payload: Partial<TIssue> = {
|
const payload: Partial<TIssue> = {
|
||||||
...formData,
|
...formData,
|
||||||
|
@ -229,7 +229,7 @@ export const PagesListItem: FC<IPagesListItem> = observer(({ pageId, projectId }
|
|||||||
)}
|
)}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
position="top-right"
|
position="top-right"
|
||||||
tooltipContent={`Created by ${ownerDetails?.member.display_name} on ${renderFormattedDate(
|
tooltipContent={`Created by ${ownerDetails?.member?.display_name} on ${renderFormattedDate(
|
||||||
created_at
|
created_at
|
||||||
)}`}
|
)}`}
|
||||||
>
|
>
|
||||||
|
@ -42,7 +42,7 @@ export const AppSidebar: FC<IAppSidebar> = observer(() => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`inset-y-0 z-20 flex h-full flex-shrink-0 flex-grow-0 flex-col border-r border-custom-sidebar-border-200 bg-custom-sidebar-background-100 duration-300
|
className={`inset-y-0 z-30 flex h-full flex-shrink-0 flex-grow-0 flex-col border-r border-custom-sidebar-border-200 bg-custom-sidebar-background-100 duration-300
|
||||||
fixed md:relative
|
fixed md:relative
|
||||||
${themStore.sidebarCollapsed ? "-ml-[280px]" : ""}
|
${themStore.sidebarCollapsed ? "-ml-[280px]" : ""}
|
||||||
sm:${themStore.sidebarCollapsed ? "-ml-[280px]" : ""}
|
sm:${themStore.sidebarCollapsed ? "-ml-[280px]" : ""}
|
||||||
|
Loading…
Reference in New Issue
Block a user