diff --git a/apiserver/package.json b/apiserver/package.json index fb4f8441d..060944406 100644 --- a/apiserver/package.json +++ b/apiserver/package.json @@ -1,4 +1,4 @@ { "name": "plane-api", - "version": "0.15.1" + "version": "0.16.0" } diff --git a/apiserver/plane/app/views/inbox.py b/apiserver/plane/app/views/inbox.py index d70eec4f2..ed32a14fe 100644 --- a/apiserver/plane/app/views/inbox.py +++ b/apiserver/plane/app/views/inbox.py @@ -33,6 +33,7 @@ from plane.app.serializers import ( IssueSerializer, InboxSerializer, InboxIssueSerializer, + IssueDetailSerializer, ) from plane.utils.issue_filters import issue_filters from plane.bgtasks.issue_activites_task import issue_activity @@ -426,11 +427,10 @@ class InboxIssueViewSet(BaseViewSet): ) ) ).first() - if issue is None: return Response({"error": "Requested object was not found"}, status=status.HTTP_404_NOT_FOUND) - serializer = IssueSerializer(issue) + serializer = IssueDetailSerializer(issue) return Response(serializer.data, status=status.HTTP_200_OK) def destroy(self, request, slug, project_id, inbox_id, issue_id): diff --git a/apiserver/plane/app/views/project.py b/apiserver/plane/app/views/project.py index 5d2f95673..6f9b2618e 100644 --- a/apiserver/plane/app/views/project.py +++ b/apiserver/plane/app/views/project.py @@ -77,6 +77,12 @@ class ProjectViewSet(WebhookMixin, BaseViewSet): ] def get_queryset(self): + sort_order = ProjectMember.objects.filter( + member=self.request.user, + project_id=OuterRef("pk"), + workspace__slug=self.kwargs.get("slug"), + is_active=True, + ).values("sort_order") return self.filter_queryset( super() .get_queryset() @@ -147,6 +153,7 @@ class ProjectViewSet(WebhookMixin, BaseViewSet): ) ) ) + .annotate(sort_order=Subquery(sort_order)) .prefetch_related( Prefetch( "project_projectmember", @@ -166,16 +173,8 @@ class ProjectViewSet(WebhookMixin, BaseViewSet): for field in request.GET.get("fields", "").split(",") if field ] - - sort_order_query = ProjectMember.objects.filter( - member=request.user, - project_id=OuterRef("pk"), - workspace__slug=self.kwargs.get("slug"), - is_active=True, - ).values("sort_order") projects = ( self.get_queryset() - .annotate(sort_order=Subquery(sort_order_query)) .order_by("sort_order", "name") ) if request.GET.get("per_page", False) and request.GET.get( @@ -204,7 +203,7 @@ class ProjectViewSet(WebhookMixin, BaseViewSet): serializer.save() # Add the user as Administrator to the project - project_member = ProjectMember.objects.create( + _ = ProjectMember.objects.create( project_id=serializer.data["id"], member=request.user, role=20, diff --git a/package.json b/package.json index 762ce322a..9239a9b41 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "repository": "https://github.com/makeplane/plane.git", - "version": "0.15.1", + "version": "0.16.0", "license": "AGPL-3.0", "private": true, "workspaces": [ diff --git a/packages/editor/core/package.json b/packages/editor/core/package.json index 7f7f4831a..fcb6b57bb 100644 --- a/packages/editor/core/package.json +++ b/packages/editor/core/package.json @@ -1,6 +1,6 @@ { "name": "@plane/editor-core", - "version": "0.15.1", + "version": "0.16.0", "description": "Core Editor that powers Plane", "private": true, "main": "./dist/index.mjs", diff --git a/packages/editor/document-editor/package.json b/packages/editor/document-editor/package.json index b33bc12fb..bd1f2d90f 100644 --- a/packages/editor/document-editor/package.json +++ b/packages/editor/document-editor/package.json @@ -1,6 +1,6 @@ { "name": "@plane/document-editor", - "version": "0.15.1", + "version": "0.16.0", "description": "Package that powers Plane's Pages Editor", "main": "./dist/index.mjs", "module": "./dist/index.mjs", diff --git a/packages/editor/extensions/package.json b/packages/editor/extensions/package.json index 8481abdf3..0bdd70824 100644 --- a/packages/editor/extensions/package.json +++ b/packages/editor/extensions/package.json @@ -1,6 +1,6 @@ { "name": "@plane/editor-extensions", - "version": "0.15.1", + "version": "0.16.0", "description": "Package that powers Plane's Editor with extensions", "private": true, "main": "./dist/index.mjs", diff --git a/packages/editor/lite-text-editor/package.json b/packages/editor/lite-text-editor/package.json index 71d70399d..e033f620a 100644 --- a/packages/editor/lite-text-editor/package.json +++ b/packages/editor/lite-text-editor/package.json @@ -1,6 +1,6 @@ { "name": "@plane/lite-text-editor", - "version": "0.15.1", + "version": "0.16.0", "description": "Package that powers Plane's Comment Editor", "private": true, "main": "./dist/index.mjs", diff --git a/packages/editor/rich-text-editor/package.json b/packages/editor/rich-text-editor/package.json index a85a8b998..0f3d0d8f7 100644 --- a/packages/editor/rich-text-editor/package.json +++ b/packages/editor/rich-text-editor/package.json @@ -1,6 +1,6 @@ { "name": "@plane/rich-text-editor", - "version": "0.15.1", + "version": "0.16.0", "description": "Rich Text Editor that powers Plane", "private": true, "main": "./dist/index.mjs", diff --git a/packages/eslint-config-custom/package.json b/packages/eslint-config-custom/package.json index 6bfe67261..2fee408c9 100644 --- a/packages/eslint-config-custom/package.json +++ b/packages/eslint-config-custom/package.json @@ -1,7 +1,7 @@ { "name": "eslint-config-custom", "private": true, - "version": "0.15.1", + "version": "0.16.0", "main": "index.js", "license": "MIT", "dependencies": { diff --git a/packages/tailwind-config-custom/package.json b/packages/tailwind-config-custom/package.json index 50ede8674..d7e807b91 100644 --- a/packages/tailwind-config-custom/package.json +++ b/packages/tailwind-config-custom/package.json @@ -1,6 +1,6 @@ { "name": "tailwind-config-custom", - "version": "0.15.1", + "version": "0.16.0", "description": "common tailwind configuration across monorepo", "main": "index.js", "private": true, diff --git a/packages/tsconfig/package.json b/packages/tsconfig/package.json index 42ce3fed5..e0829e87b 100644 --- a/packages/tsconfig/package.json +++ b/packages/tsconfig/package.json @@ -1,6 +1,6 @@ { "name": "tsconfig", - "version": "0.15.1", + "version": "0.16.0", "private": true, "files": [ "base.json", diff --git a/packages/types/package.json b/packages/types/package.json index 0e5c2eb16..9c9938845 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@plane/types", - "version": "0.15.1", + "version": "0.16.0", "private": true, "main": "./src/index.d.ts" } diff --git a/packages/ui/package.json b/packages/ui/package.json index 912fcfeb8..756a0f2f1 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -2,7 +2,7 @@ "name": "@plane/ui", "description": "UI components shared across multiple apps internally", "private": true, - "version": "0.15.1", + "version": "0.16.0", "main": "./dist/index.js", "module": "./dist/index.mjs", "types": "./dist/index.d.ts", diff --git a/space/package.json b/space/package.json index 9ee7279cd..a1d600a60 100644 --- a/space/package.json +++ b/space/package.json @@ -1,6 +1,6 @@ { "name": "space", - "version": "0.15.1", + "version": "0.16.0", "private": true, "scripts": { "dev": "turbo run develop", diff --git a/web/components/dropdowns/cycle.tsx b/web/components/dropdowns/cycle.tsx index 09b0acde5..d1f552a99 100644 --- a/web/components/dropdowns/cycle.tsx +++ b/web/components/dropdowns/cycle.tsx @@ -148,6 +148,13 @@ export const CycleDropdown: React.FC = observer((props) => { toggleDropdown(); }; + const searchInputKeyDown = (e: React.KeyboardEvent) => { + if (query !== "" && e.key === "Escape") { + e.stopPropagation(); + setQuery(""); + } + }; + useOutsideClickDetector(dropdownRef, handleClose); useEffect(() => { @@ -231,6 +238,7 @@ export const CycleDropdown: React.FC = observer((props) => { onChange={(e) => setQuery(e.target.value)} placeholder="Search" displayValue={(assigned: any) => assigned?.name} + onKeyDown={searchInputKeyDown} />
diff --git a/web/components/dropdowns/estimate.tsx b/web/components/dropdowns/estimate.tsx index 2674fa902..61513cdba 100644 --- a/web/components/dropdowns/estimate.tsx +++ b/web/components/dropdowns/estimate.tsx @@ -137,6 +137,13 @@ export const EstimateDropdown: React.FC = observer((props) => { toggleDropdown(); }; + const searchInputKeyDown = (e: React.KeyboardEvent) => { + if (query !== "" && e.key === "Escape") { + e.stopPropagation(); + setQuery(""); + } + }; + useOutsideClickDetector(dropdownRef, handleClose); useEffect(() => { @@ -217,6 +224,7 @@ export const EstimateDropdown: React.FC = observer((props) => { onChange={(e) => setQuery(e.target.value)} placeholder="Search" displayValue={(assigned: any) => assigned?.name} + onKeyDown={searchInputKeyDown} />
diff --git a/web/components/dropdowns/member/project-member.tsx b/web/components/dropdowns/member/project-member.tsx index 0e2479849..db8702535 100644 --- a/web/components/dropdowns/member/project-member.tsx +++ b/web/components/dropdowns/member/project-member.tsx @@ -130,6 +130,13 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { toggleDropdown(); }; + const searchInputKeyDown = (e: React.KeyboardEvent) => { + if (query !== "" && e.key === "Escape") { + e.stopPropagation(); + setQuery(""); + } + }; + useOutsideClickDetector(dropdownRef, handleClose); useEffect(() => { @@ -215,6 +222,7 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { onChange={(e) => setQuery(e.target.value)} placeholder="Search" displayValue={(assigned: any) => assigned?.name} + onKeyDown={searchInputKeyDown} />
diff --git a/web/components/dropdowns/module.tsx b/web/components/dropdowns/module.tsx index f41ece121..cee0ed9f3 100644 --- a/web/components/dropdowns/module.tsx +++ b/web/components/dropdowns/module.tsx @@ -249,6 +249,13 @@ export const ModuleDropdown: React.FC = observer((props) => { toggleDropdown(); }; + const searchInputKeyDown = (e: React.KeyboardEvent) => { + if (query !== "" && e.key === "Escape") { + e.stopPropagation(); + setQuery(""); + } + }; + useOutsideClickDetector(dropdownRef, handleClose); const comboboxProps: any = { @@ -349,6 +356,7 @@ export const ModuleDropdown: React.FC = observer((props) => { onChange={(e) => setQuery(e.target.value)} placeholder="Search" displayValue={(assigned: any) => assigned?.name} + onKeyDown={searchInputKeyDown} />
diff --git a/web/components/dropdowns/priority.tsx b/web/components/dropdowns/priority.tsx index d519ad9f1..3aef22233 100644 --- a/web/components/dropdowns/priority.tsx +++ b/web/components/dropdowns/priority.tsx @@ -329,6 +329,13 @@ export const PriorityDropdown: React.FC = (props) => { toggleDropdown(); }; + const searchInputKeyDown = (e: React.KeyboardEvent) => { + if (query !== "" && e.key === "Escape") { + e.stopPropagation(); + setQuery(""); + } + }; + useOutsideClickDetector(dropdownRef, handleClose); const ButtonToRender = BORDER_BUTTON_VARIANTS.includes(buttonVariant) @@ -417,6 +424,7 @@ export const PriorityDropdown: React.FC = (props) => { onChange={(e) => setQuery(e.target.value)} placeholder="Search" displayValue={(assigned: any) => assigned?.name} + onKeyDown={searchInputKeyDown} />
diff --git a/web/components/dropdowns/state.tsx b/web/components/dropdowns/state.tsx index fa068fdd0..9591a7686 100644 --- a/web/components/dropdowns/state.tsx +++ b/web/components/dropdowns/state.tsx @@ -119,6 +119,13 @@ export const StateDropdown: React.FC = observer((props) => { toggleDropdown(); }; + const searchInputKeyDown = (e: React.KeyboardEvent) => { + if (query !== "" && e.key === "Escape") { + e.stopPropagation(); + setQuery(""); + } + }; + useOutsideClickDetector(dropdownRef, handleClose); useEffect(() => { @@ -205,6 +212,7 @@ export const StateDropdown: React.FC = observer((props) => { onChange={(e) => setQuery(e.target.value)} placeholder="Search" displayValue={(assigned: any) => assigned?.name} + onKeyDown={searchInputKeyDown} />
diff --git a/web/components/issues/issue-detail/label/select/label-select.tsx b/web/components/issues/issue-detail/label/select/label-select.tsx index 4cdbdcf59..11ff77d37 100644 --- a/web/components/issues/issue-detail/label/select/label-select.tsx +++ b/web/components/issues/issue-detail/label/select/label-select.tsx @@ -80,6 +80,13 @@ export const IssueLabelSelect: React.FC = observer((props) =>
); + const searchInputKeyDown = (e: React.KeyboardEvent) => { + if (query !== "" && e.key === "Escape") { + e.stopPropagation(); + setQuery(""); + } + }; + if (!issue) return <>; return ( @@ -118,6 +125,7 @@ export const IssueLabelSelect: React.FC = observer((props) => onChange={(e) => setQuery(e.target.value)} placeholder="Search" displayValue={(assigned: any) => assigned?.name} + onKeyDown={searchInputKeyDown} /> diff --git a/web/components/issues/issue-detail/root.tsx b/web/components/issues/issue-detail/root.tsx index 6252fc03a..02164cff9 100644 --- a/web/components/issues/issue-detail/root.tsx +++ b/web/components/issues/issue-detail/root.tsx @@ -360,7 +360,7 @@ export const IssueDetailRoot: FC = observer((props) => { />
= observer((props) => {
-
+
Properties
{/* TODO: render properties using a common component */}
diff --git a/web/components/issues/issue-detail/subscription.tsx b/web/components/issues/issue-detail/subscription.tsx index ab5983960..7321ef27f 100644 --- a/web/components/issues/issue-detail/subscription.tsx +++ b/web/components/issues/issue-detail/subscription.tsx @@ -67,7 +67,7 @@ export const IssueSubscription: FC = observer((props) => { > {loading ? ( - Loading... + Loading... ) : isSubscribed ? (
Unsubscribe
diff --git a/web/components/project/sidebar-list-item.tsx b/web/components/project/sidebar-list-item.tsx index f899a9b31..79d632c1e 100644 --- a/web/components/project/sidebar-list-item.tsx +++ b/web/components/project/sidebar-list-item.tsx @@ -37,6 +37,7 @@ type Props = { snapshot?: DraggableStateSnapshot; handleCopyText: () => void; shortContextMenu?: boolean; + disableDrag?: boolean; }; const navigation = (workspaceSlug: string, projectId: string) => [ @@ -79,7 +80,7 @@ const navigation = (workspaceSlug: string, projectId: string) => [ export const ProjectSidebarListItem: React.FC = observer((props) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { projectId, provided, snapshot, handleCopyText, shortContextMenu = false } = props; + const { projectId, provided, snapshot, handleCopyText, shortContextMenu = false, disableDrag } = props; // store hooks const { theme: themeStore } = useApplication(); const { setTrackElement } = useEventTracker(); @@ -163,7 +164,7 @@ export const ProjectSidebarListItem: React.FC = observer((props) => { snapshot?.isDragging ? "opacity-60" : "" } ${isMenuActive ? "!bg-custom-sidebar-background-80" : ""}`} > - {provided && ( + {provided && !disableDrag && ( { // states @@ -32,9 +34,9 @@ export const ProjectSidebarList: FC = observer(() => { membership: { currentWorkspaceRole }, } = useUser(); const { + getProjectById, joinedProjectIds: joinedProjects, favoriteProjectIds: favoriteProjects, - orderProjectsWithSortOrder, updateProjectView, } = useProject(); // router @@ -55,22 +57,27 @@ export const ProjectSidebarList: FC = observer(() => { }); }; - const onDragEnd = async (result: DropResult) => { + const onDragEnd = (result: DropResult) => { const { source, destination, draggableId } = result; - if (!destination || !workspaceSlug) return; - if (source.index === destination.index) return; - const updatedSortOrder = orderProjectsWithSortOrder(source.index, destination.index, draggableId); - - updateProjectView(workspaceSlug.toString(), draggableId, { sort_order: updatedSortOrder }).catch(() => { - setToastAlert({ - type: "error", - title: "Error!", - message: "Something went wrong. Please try again.", - }); + const joinedProjectsList: IProject[] = []; + joinedProjects.map((projectId) => { + const _project = getProjectById(projectId); + if (_project) joinedProjectsList.push(_project); }); + if (joinedProjectsList.length <= 0) return; + + const updatedSortOrder = orderJoinedProjects(source.index, destination.index, draggableId, joinedProjectsList); + if (updatedSortOrder != undefined) + updateProjectView(workspaceSlug.toString(), draggableId, { sort_order: updatedSortOrder }).catch(() => { + setToastAlert({ + type: "error", + title: "Error!", + message: "Something went wrong. Please try again.", + }); + }); }; const isCollapsed = sidebarCollapsed || false; @@ -176,6 +183,7 @@ export const ProjectSidebarList: FC = observer(() => { snapshot={snapshot} handleCopyText={() => handleCopyText(projectId)} shortContextMenu + disableDrag />
)} diff --git a/web/helpers/project.helper.ts b/web/helpers/project.helper.ts new file mode 100644 index 000000000..8d78964ee --- /dev/null +++ b/web/helpers/project.helper.ts @@ -0,0 +1,45 @@ +import { IProject } from "@plane/types"; + +/** + * Updates the sort order of the project. + * @param sortIndex + * @param destinationIndex + * @param projectId + * @returns number | undefined + */ +export const orderJoinedProjects = ( + sourceIndex: number, + destinationIndex: number, + currentProjectId: string, + joinedProjects: IProject[] +): number | undefined => { + if (!currentProjectId || sourceIndex < 0 || destinationIndex < 0 || joinedProjects.length <= 0) return undefined; + + let updatedSortOrder: number | undefined = undefined; + const sortOrderDefaultValue = 10000; + + if (destinationIndex === 0) { + // updating project at the top of the project + const currentSortOrder = joinedProjects[destinationIndex].sort_order || 0; + updatedSortOrder = currentSortOrder - sortOrderDefaultValue; + } else if (destinationIndex === joinedProjects.length - 1) { + // updating project at the bottom of the project + const currentSortOrder = joinedProjects[destinationIndex - 1].sort_order || 0; + updatedSortOrder = currentSortOrder + sortOrderDefaultValue; + } else { + // updating project in the middle of the project + if (sourceIndex > destinationIndex) { + const destinationTopProjectSortOrder = joinedProjects[destinationIndex - 1].sort_order || 0; + const destinationBottomProjectSortOrder = joinedProjects[destinationIndex].sort_order || 0; + const updatedValue = (destinationTopProjectSortOrder + destinationBottomProjectSortOrder) / 2; + updatedSortOrder = updatedValue; + } else { + const destinationTopProjectSortOrder = joinedProjects[destinationIndex].sort_order || 0; + const destinationBottomProjectSortOrder = joinedProjects[destinationIndex + 1].sort_order || 0; + const updatedValue = (destinationTopProjectSortOrder + destinationBottomProjectSortOrder) / 2; + updatedSortOrder = updatedValue; + } + } + + return updatedSortOrder; +}; diff --git a/web/lib/app-provider.tsx b/web/lib/app-provider.tsx index 64d323cf0..9c06947af 100644 --- a/web/lib/app-provider.tsx +++ b/web/lib/app-provider.tsx @@ -50,7 +50,7 @@ export const AppProvider: FC = observer((props) => { { issues: { fetchInboxIssues }, } = useInboxIssues(); // fetching the Inbox filters and issues - useSWR( + const { isLoading } = useSWR( workspaceSlug && projectId && currentProjectDetails && currentProjectDetails?.inbox_view ? `INBOX_ISSUES_${workspaceSlug.toString()}_${projectId.toString()}` : null, @@ -37,7 +38,12 @@ const ProjectInboxPage: NextPageWithLayout = observer(() => { // derived values const pageTitle = currentProjectDetails?.name ? `${currentProjectDetails?.name} - Inbox` : undefined; - if (!workspaceSlug || !projectId || !inboxId || !currentProjectDetails?.inbox_view) return <>; + if (!workspaceSlug || !projectId || !inboxId || !currentProjectDetails?.inbox_view || isLoading) + return ( +
+ +
+ ); return ( <> diff --git a/web/services/project/project.service.ts b/web/services/project/project.service.ts index 4956b952e..0a7c6e682 100644 --- a/web/services/project/project.service.ts +++ b/web/services/project/project.service.ts @@ -72,9 +72,6 @@ export class ProjectService extends APIService { workspaceSlug: string, projectId: string, data: { - view_props?: IProjectViewProps; - default_props?: IProjectViewProps; - preferences?: ProjectPreferences; sort_order?: number; } ): Promise { diff --git a/web/store/project/project.store.ts b/web/store/project/project.store.ts index ef88c5b0f..a47d459f8 100644 --- a/web/store/project/project.store.ts +++ b/web/store/project/project.store.ts @@ -1,12 +1,14 @@ import { observable, action, computed, makeObservable, runInAction } from "mobx"; import { computedFn } from "mobx-utils"; import set from "lodash/set"; +import sortBy from "lodash/sortBy"; // types import { RootStore } from "../root.store"; import { IProject } from "@plane/types"; // services import { IssueLabelService, IssueService } from "services/issue"; import { ProjectService, ProjectStateService } from "services/project"; +import { cloneDeep, update } from "lodash"; export interface IProjectStore { // observables searchQuery: string; @@ -28,8 +30,6 @@ export interface IProjectStore { // favorites actions addProjectToFavorites: (workspaceSlug: string, projectId: string) => Promise; removeProjectFromFavorites: (workspaceSlug: string, projectId: string) => Promise; - // project-order action - orderProjectsWithSortOrder: (sourceIndex: number, destinationIndex: number, projectId: string) => number; // project-view action updateProjectView: (workspaceSlug: string, projectId: string, viewProps: any) => Promise; // CRUD actions @@ -71,8 +71,6 @@ export class ProjectStore implements IProjectStore { // favorites actions addProjectToFavorites: action, removeProjectFromFavorites: action, - // project-order action - orderProjectsWithSortOrder: action, // project-view action updateProjectView: action, // CRUD actions @@ -128,7 +126,11 @@ export class ProjectStore implements IProjectStore { get joinedProjectIds() { const currentWorkspace = this.rootStore.workspaceRoot.currentWorkspace; if (!currentWorkspace) return []; - const projectIds = Object.values(this.projectMap ?? {}) + + let projects = Object.values(this.projectMap ?? {}); + projects = sortBy(projects, "sort_order"); + + const projectIds = projects .filter((project) => project.workspace === currentWorkspace.id && project.is_member) .map((project) => project.id); return projectIds; @@ -140,7 +142,11 @@ export class ProjectStore implements IProjectStore { get favoriteProjectIds() { const currentWorkspace = this.rootStore.workspaceRoot.currentWorkspace; if (!currentWorkspace) return []; - const projectIds = Object.values(this.projectMap ?? {}) + + let projects = Object.values(this.projectMap ?? {}); + projects = sortBy(projects, "created_at"); + + const projectIds = projects .filter((project) => project.workspace === currentWorkspace.id && project.is_favorite) .map((project) => project.id); return projectIds; @@ -253,41 +259,6 @@ export class ProjectStore implements IProjectStore { } }; - /** - * Updates the sort order of the project. - * @param sortIndex - * @param destinationIndex - * @param projectId - * @returns - */ - orderProjectsWithSortOrder = (sortIndex: number, destinationIndex: number, projectId: string) => { - try { - const workspaceSlug = this.rootStore.app.router.workspaceSlug; - if (!workspaceSlug) return 0; - const projectsList = Object.values(this.projectMap || {}) || []; - let updatedSortOrder = projectsList[sortIndex].sort_order; - if (destinationIndex === 0) updatedSortOrder = (projectsList[0].sort_order as number) - 1000; - else if (destinationIndex === projectsList.length - 1) - updatedSortOrder = (projectsList[projectsList.length - 1].sort_order as number) + 1000; - else { - const destinationSortingOrder = projectsList[destinationIndex].sort_order as number; - const relativeDestinationSortingOrder = - sortIndex < destinationIndex - ? (projectsList[destinationIndex + 1].sort_order as number) - : (projectsList[destinationIndex - 1].sort_order as number); - - updatedSortOrder = (destinationSortingOrder + relativeDestinationSortingOrder) / 2; - } - runInAction(() => { - set(this.projectMap, [projectId, "sort_order"], updatedSortOrder); - }); - return updatedSortOrder; - } catch (error) { - console.log("failed to update sort order of the projects"); - return 0; - } - }; - /** * Updates the project view * @param workspaceSlug @@ -295,12 +266,18 @@ export class ProjectStore implements IProjectStore { * @param viewProps * @returns */ - updateProjectView = async (workspaceSlug: string, projectId: string, viewProps: any) => { + updateProjectView = async (workspaceSlug: string, projectId: string, viewProps: { sort_order: number }) => { + const currentProjectSortOrder = this.getProjectById(projectId)?.sort_order; try { + runInAction(() => { + set(this.projectMap, [projectId, "sort_order"], viewProps?.sort_order); + }); const response = await this.projectService.setProjectView(workspaceSlug, projectId, viewProps); - await this.fetchProjects(workspaceSlug); return response; } catch (error) { + runInAction(() => { + set(this.projectMap, [projectId, "sort_order"], currentProjectSortOrder); + }); console.log("Failed to update sort order of the projects"); throw error; }