From e396424db793bbb71041dd23eff2ae7d3b94cc2c Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 10 May 2024 15:19:05 +0530 Subject: [PATCH 01/12] [WEB-1251] chore: view list enhancement (#4427) * chore: moved search query to mobx store * chore: moved view sub-header to app header * chore: created by avatar added in view item list --- web/components/headers/project-views.tsx | 2 + web/components/views/index.ts | 1 + web/components/views/view-list-header.tsx | 84 +++++++++++++++++++ .../views/view-list-item-action.tsx | 10 ++- web/components/views/views-list.tsx | 82 +----------------- web/store/project-view.store.ts | 12 +++ 6 files changed, 109 insertions(+), 82 deletions(-) create mode 100644 web/components/views/view-list-header.tsx diff --git a/web/components/headers/project-views.tsx b/web/components/headers/project-views.tsx index b733e6784c..c79934aec2 100644 --- a/web/components/headers/project-views.tsx +++ b/web/components/headers/project-views.tsx @@ -7,6 +7,7 @@ import { Breadcrumbs, PhotoFilterIcon, Button } from "@plane/ui"; import { BreadcrumbLink } from "@/components/common"; // helpers import { ProjectLogo } from "@/components/project"; +import { ViewListHeader } from "@/components/views"; import { EUserProjectRoles } from "@/constants/project"; // constants import { useCommandPalette, useProject, useUser } from "@/hooks/store"; @@ -58,6 +59,7 @@ export const ProjectViewsHeader: React.FC = observer(() => { {canUserCreateIssue && (
+
+ )} +
+ + updateSearchQuery(e.target.value)} + onKeyDown={handleInputKeyDown} + /> + {isSearchOpen && ( + + )} +
+
+
+ ); +}); diff --git a/web/components/views/view-list-item-action.tsx b/web/components/views/view-list-item-action.tsx index 563d1da41c..80ba5ba0ca 100644 --- a/web/components/views/view-list-item-action.tsx +++ b/web/components/views/view-list-item-action.tsx @@ -11,7 +11,8 @@ import { EUserProjectRoles } from "@/constants/project"; // helpers import { calculateTotalFilters } from "@/helpers/filter.helper"; // hooks -import { useProjectView, useUser } from "@/hooks/store"; +import { useMember, useProjectView, useUser } from "@/hooks/store"; +import { ButtonAvatars } from "../dropdowns/member/avatar"; type Props = { parentRef: React.RefObject; @@ -31,6 +32,7 @@ export const ViewListItemAction: FC = observer((props) => { membership: { currentProjectRole }, } = useUser(); const { addViewToFavorites, removeViewFromFavorites } = useProjectView(); + const { getUserDetails } = useMember(); // derived values const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER; @@ -50,6 +52,8 @@ export const ViewListItemAction: FC = observer((props) => { removeViewFromFavorites(workspaceSlug.toString(), projectId.toString(), view.id); }; + const createdByDetails = view.created_by ? getUserDetails(view.created_by) : undefined; + return ( <> {workspaceSlug && projectId && view && ( @@ -65,6 +69,10 @@ export const ViewListItemAction: FC = observer((props) => {

{totalFilters} {totalFilters === 1 ? "filter" : "filters"}

+ + {/* created by */} + {createdByDetails && } + {isEditingAllowed && ( { diff --git a/web/components/views/views-list.tsx b/web/components/views/views-list.tsx index 967469c792..ea300678ac 100644 --- a/web/components/views/views-list.tsx +++ b/web/components/views/views-list.tsx @@ -1,7 +1,4 @@ -import { useRef, useState } from "react"; import { observer } from "mobx-react-lite"; -// ui -import { Search, X } from "lucide-react"; // components import { ListLayout } from "@/components/core/list"; import { EmptyState } from "@/components/empty-state"; @@ -9,28 +6,13 @@ import { ViewListLoader } from "@/components/ui"; import { ProjectViewListItem } from "@/components/views"; // constants import { EmptyStateType } from "@/constants/empty-state"; -// helper -import { cn } from "@/helpers/common.helper"; // hooks import { useCommandPalette, useProjectView } from "@/hooks/store"; -import useOutsideClickDetector from "@/hooks/use-outside-click-detector"; export const ProjectViewsList = observer(() => { - // states - const [searchQuery, setSearchQuery] = useState(""); - const [isSearchOpen, setIsSearchOpen] = useState(searchQuery !== "" ? true : false); - - // refs - const inputRef = useRef(null); - // store hooks const { toggleCreateViewModal } = useCommandPalette(); - const { projectViewIds, getViewById, loader } = useProjectView(); - - // outside click detector hook - useOutsideClickDetector(inputRef, () => { - if (isSearchOpen && searchQuery.trim() === "") setIsSearchOpen(false); - }); + const { projectViewIds, getViewById, loader, searchQuery } = useProjectView(); if (loader || !projectViewIds) return ; @@ -39,72 +21,10 @@ export const ProjectViewsList = observer(() => { const filteredViewsList = viewsList.filter((v) => v?.name.toLowerCase().includes(searchQuery.toLowerCase())); - // handlers - const handleInputKeyDown = (e: React.KeyboardEvent) => { - if (e.key === "Escape") { - if (searchQuery && searchQuery.trim() !== "") setSearchQuery(""); - else { - setIsSearchOpen(false); - inputRef.current?.blur(); - } - } - }; - return ( <> {viewsList.length > 0 ? (
-
-
- Project Views -
-
-
- {!isSearchOpen && ( - - )} -
- - setSearchQuery(e.target.value)} - onKeyDown={handleInputKeyDown} - /> - {isSearchOpen && ( - - )} -
-
-
-
{filteredViewsList.length > 0 ? ( filteredViewsList.map((view) => ) diff --git a/web/store/project-view.store.ts b/web/store/project-view.store.ts index 95ecece58a..92b8719c14 100644 --- a/web/store/project-view.store.ts +++ b/web/store/project-view.store.ts @@ -12,11 +12,13 @@ export interface IProjectViewStore { loader: boolean; fetchedMap: Record; // observables + searchQuery: string; viewMap: Record; // computed projectViewIds: string[] | null; // computed actions getViewById: (viewId: string) => IProjectView; + updateSearchQuery: (query: string) => void; // fetch actions fetchViews: (workspaceSlug: string, projectId: string) => Promise; fetchViewDetails: (workspaceSlug: string, projectId: string, viewId: string) => Promise; @@ -38,6 +40,7 @@ export class ProjectViewStore implements IProjectViewStore { // observables loader: boolean = false; viewMap: Record = {}; + searchQuery: string = ""; //loaders fetchedMap: Record = {}; // root store @@ -51,6 +54,7 @@ export class ProjectViewStore implements IProjectViewStore { loader: observable.ref, viewMap: observable, fetchedMap: observable, + searchQuery: observable.ref, // computed projectViewIds: computed, // fetch actions @@ -60,6 +64,8 @@ export class ProjectViewStore implements IProjectViewStore { createView: action, updateView: action, deleteView: action, + // actions + updateSearchQuery: action, // favorites actions addViewToFavorites: action, removeViewFromFavorites: action, @@ -85,6 +91,12 @@ export class ProjectViewStore implements IProjectViewStore { */ getViewById = computedFn((viewId: string) => this.viewMap?.[viewId] ?? null); + /** + * @description update search query + * @param {string} query + */ + updateSearchQuery = (query: string) => (this.searchQuery = query); + /** * Fetches views for current project * @param workspaceSlug From 57eda3408221553f83ac79d8f7a78809941e8e40 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 10 May 2024 15:19:59 +0530 Subject: [PATCH 02/12] chore: notification action item enhancement (#4426) --- web/components/notifications/notification-card.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/components/notifications/notification-card.tsx b/web/components/notifications/notification-card.tsx index c98772f9bd..cfae8a7c12 100644 --- a/web/components/notifications/notification-card.tsx +++ b/web/components/notifications/notification-card.tsx @@ -173,7 +173,7 @@ export const NotificationCard: React.FC = (props) => {
{!notification.message ? ( -
+
{notificationTriggeredBy.is_bot ? notificationTriggeredBy.first_name From 0af55e7bbbc8ffd583bc1f460ec019e548e11081 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 10 May 2024 15:21:05 +0530 Subject: [PATCH 03/12] [WEB-1250] chore: module list enhancement (#4425) * chore: move module sub-header to app header * chore: gantt header improvement, remove title * chore: progress indicator size reduced * chore: replace members with lead and updated start and end date ui --- web/components/gantt-chart/chart/header.tsx | 4 +- web/components/gantt-chart/chart/root.tsx | 1 - web/components/headers/modules-list.tsx | 2 + web/components/modules/module-card-item.tsx | 40 ++++++++------- .../modules/module-list-item-action.tsx | 50 +++++++++---------- web/components/modules/module-list-item.tsx | 6 +-- .../projects/[projectId]/modules/index.tsx | 17 +++---- 7 files changed, 59 insertions(+), 61 deletions(-) diff --git a/web/components/gantt-chart/chart/header.tsx b/web/components/gantt-chart/chart/header.tsx index e2722b22ae..fe4d0c885c 100644 --- a/web/components/gantt-chart/chart/header.tsx +++ b/web/components/gantt-chart/chart/header.tsx @@ -15,18 +15,16 @@ type Props = { handleChartView: (view: TGanttViews) => void; handleToday: () => void; loaderTitle: string; - title: string; toggleFullScreenMode: () => void; }; export const GanttChartHeader: React.FC = observer((props) => { - const { blocks, fullScreenMode, handleChartView, handleToday, loaderTitle, title, toggleFullScreenMode } = props; + const { blocks, fullScreenMode, handleChartView, handleToday, loaderTitle, toggleFullScreenMode } = props; // chart hook const { currentView } = useGanttChart(); return (
-
{title}
{blocks ? `${blocks.length} ${loaderTitle}` : "Loading..."}
diff --git a/web/components/gantt-chart/chart/root.tsx b/web/components/gantt-chart/chart/root.tsx index a4ea8cbf2b..395e0771cd 100644 --- a/web/components/gantt-chart/chart/root.tsx +++ b/web/components/gantt-chart/chart/root.tsx @@ -172,7 +172,6 @@ export const ChartViewRoot: FC = observer((props) => { handleChartView={(key) => updateCurrentViewRenderPayload(null, key)} handleToday={handleToday} loaderTitle={loaderTitle} - title={title} /> {
+ {canUserCreateModule && (
@@ -217,11 +219,13 @@ export const ModuleCardItem: React.FC = observer((props) => {
{isDateValid ? ( - <> - - {renderFormattedDate(startDate) ?? "_ _"} - {renderFormattedDate(endDate) ?? "_ _"} - - +
+ + {renderFormattedDate(startDate)} + + + {renderFormattedDate(endDate)} +
) : ( No due date )} @@ -229,7 +233,7 @@ export const ModuleCardItem: React.FC = observer((props) => {
-
+
{isEditingAllowed && ( { diff --git a/web/components/modules/module-list-item-action.tsx b/web/components/modules/module-list-item-action.tsx index b34dc75557..fa7d71577c 100644 --- a/web/components/modules/module-list-item-action.tsx +++ b/web/components/modules/module-list-item-action.tsx @@ -2,11 +2,11 @@ import React, { FC } from "react"; import { observer } from "mobx-react"; import { useRouter } from "next/router"; // icons -import { User2 } from "lucide-react"; +import { CalendarCheck2, CalendarClock, MoveRight, User2 } from "lucide-react"; // types import { IModule } from "@plane/types"; // ui -import { Avatar, AvatarGroup, Tooltip, setPromiseToast } from "@plane/ui"; +import { Tooltip, setPromiseToast } from "@plane/ui"; // components import { FavoriteStar } from "@/components/core"; import { ModuleQuickActions } from "@/components/modules"; @@ -18,7 +18,7 @@ import { EUserProjectRoles } from "@/constants/project"; import { getDate, renderFormattedDate } from "@/helpers/date-time.helper"; // hooks import { useEventTracker, useMember, useModule, useUser } from "@/hooks/store"; -import { usePlatformOS } from "@/hooks/use-platform-os"; +import { ButtonAvatars } from "../dropdowns/member/avatar"; type Props = { moduleId: string; @@ -38,7 +38,6 @@ export const ModuleListItemAction: FC = observer((props) => { const { addModuleToFavorites, removeModuleFromFavorites } = useModule(); const { getUserDetails } = useMember(); const { captureEvent } = useEventTracker(); - const { isMobile } = usePlatformOS(); // derived values const endDate = getDate(moduleDetails.target_date); @@ -109,11 +108,23 @@ export const ModuleListItemAction: FC = observer((props) => { }); }; + const moduleLeadDetails = moduleDetails.lead_id ? getUserDetails(moduleDetails.lead_id) : undefined; + return ( <> + {renderDate && ( +
+ + {renderFormattedDate(startDate)} + + + {renderFormattedDate(endDate)} +
+ )} + {moduleStatus && ( = observer((props) => { )} - {renderDate && ( - - {renderFormattedDate(startDate) ?? "_ _"} - {renderFormattedDate(endDate) ?? "_ _"} + {moduleLeadDetails ? ( + + + ) : ( + + + + + )} - -
- {moduleDetails.member_ids.length > 0 ? ( - - {moduleDetails.member_ids.map((member_id) => { - const member = getUserDetails(member_id); - return ; - })} - - ) : ( - - - - )} -
-
- {isEditingAllowed && !moduleDetails.archived_at && ( { diff --git a/web/components/modules/module-list-item.tsx b/web/components/modules/module-list-item.tsx index 9ad7d22252..b745921125 100644 --- a/web/components/modules/module-list-item.tsx +++ b/web/components/modules/module-list-item.tsx @@ -77,7 +77,7 @@ export const ModuleListItem: React.FC = observer((props) => { ) : progress === 100 ? ( ) : ( - {`${progress}%`} + {`${progress}%`} )} } @@ -89,9 +89,7 @@ export const ModuleListItem: React.FC = observer((props) => { } - actionableItems={ - - } + actionableItems={} isMobile={isMobile} parentRef={parentRef} /> diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/modules/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/modules/index.tsx index 85be0c1400..08e621d0fe 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/modules/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/modules/index.tsx @@ -1,20 +1,23 @@ import { ReactElement, useCallback } from "react"; import { observer } from "mobx-react"; import { useRouter } from "next/router"; +// types import { TModuleFilters } from "@plane/types"; -// layouts // components import { PageHead } from "@/components/core"; import { EmptyState } from "@/components/empty-state"; import { ModulesListHeader } from "@/components/headers"; -import { ModuleViewHeader, ModuleAppliedFiltersList, ModulesListView } from "@/components/modules"; -// types -// hooks +import { ModuleAppliedFiltersList, ModulesListView } from "@/components/modules"; import ModulesListMobileHeader from "@/components/modules/moduels-list-mobile-header"; +// constants import { EmptyStateType } from "@/constants/empty-state"; +// helpers import { calculateTotalFilters } from "@/helpers/filter.helper"; +// hooks import { useModuleFilter, useProject } from "@/hooks/store"; +// layouts import { AppLayout } from "@/layouts/app-layout"; +// types import { NextPageWithLayout } from "@/lib/types"; const ProjectModulesPage: NextPageWithLayout = observer(() => { @@ -58,12 +61,6 @@ const ProjectModulesPage: NextPageWithLayout = observer(() => { <>
-
-
- Module name -
- -
{(calculateTotalFilters(currentProjectFilters ?? {}) !== 0 || currentProjectDisplayFilters?.favorites) && (
Date: Fri, 10 May 2024 15:22:01 +0530 Subject: [PATCH 04/12] chore: project card enhancement (#4424) --- web/components/project/card.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/web/components/project/card.tsx b/web/components/project/card.tsx index 5e94b1fb56..8f29b245b0 100644 --- a/web/components/project/card.tsx +++ b/web/components/project/card.tsx @@ -2,7 +2,7 @@ import React, { useRef, useState } from "react"; import { observer } from "mobx-react-lite"; import Link from "next/link"; import { useRouter } from "next/router"; -import { ArchiveRestoreIcon, Check, ExternalLink, LinkIcon, Lock, Pencil, Trash2, UserPlus } from "lucide-react"; +import { ArchiveRestoreIcon, Check, ExternalLink, LinkIcon, Lock, Settings, Trash2, UserPlus } from "lucide-react"; // types import type { IProject } from "@plane/types"; // ui @@ -105,10 +105,10 @@ export const ProjectCard: React.FC = observer((props) => { const MENU_ITEMS: TContextMenuItem[] = [ { - key: "edit", + key: "settings", action: () => router.push(`/${workspaceSlug}/projects/${project.id}/settings`), - title: "Edit", - icon: Pencil, + title: "Settings", + icon: Settings, shouldRender: !isArchived && (isOwner || isMember), }, { @@ -322,7 +322,7 @@ export const ProjectCard: React.FC = observer((props) => { }} href={`/${workspaceSlug}/projects/${project.id}/settings`} > - + ) : ( From 40560109b58ebc8d37c0ce6165871f8714547538 Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Fri, 10 May 2024 15:23:51 +0530 Subject: [PATCH 05/12] fix: admin app redirections --- .eslintrc.js | 2 +- admin/.env.example | 6 +- admin/app/ai/components/ai-config-form.tsx | 2 +- admin/app/ai/page.tsx | 2 +- .../components/email-config-switch.tsx | 2 +- .../components/password-config-switch.tsx | 2 +- .../github/components/github-config-form.tsx | 2 +- .../authentication/github/components/root.tsx | 2 +- admin/app/authentication/github/page.tsx | 2 +- .../google/components/google-config-form.tsx | 2 +- .../authentication/google/components/root.tsx | 2 +- admin/app/authentication/google/page.tsx | 2 +- admin/app/authentication/page.tsx | 2 +- .../email/components/email-config-form.tsx | 2 +- admin/app/email/page.tsx | 2 +- .../components/general-config-form.tsx | 2 +- admin/app/general/page.tsx | 2 +- .../image/components/image-config-form.tsx | 2 +- admin/app/image/page.tsx | 2 +- admin/app/layout.tsx | 58 +++++++++---------- .../components/admin-sidebar/help-section.tsx | 2 +- admin/components/admin-sidebar/root.tsx | 2 +- .../admin-sidebar/sidebar-dropdown.tsx | 2 +- .../sidebar-menu-hamburger-toogle.tsx | 2 +- .../components/admin-sidebar/sidebar-menu.tsx | 2 +- admin/components/new-user-popup.tsx | 2 +- admin/helpers/common.helper.ts | 11 +++- admin/hooks/index.ts | 6 -- admin/hooks/store/index.ts | 3 + admin/lib/wrappers/app-wrapper.tsx | 4 +- admin/lib/wrappers/auth-wrapper.tsx | 2 +- admin/lib/wrappers/instance-wrapper.tsx | 9 ++- admin/package.json | 2 +- admin/services/instance.service.ts | 4 +- space/helpers/common.helper.ts | 8 ++- space/package.json | 4 +- space/pages/onboarding/index.tsx | 5 +- web/Dockerfile.web | 8 +-- web/components/instance/not-ready-view.tsx | 12 +--- 39 files changed, 99 insertions(+), 91 deletions(-) delete mode 100644 admin/hooks/index.ts create mode 100644 admin/hooks/store/index.ts diff --git a/.eslintrc.js b/.eslintrc.js index c229c09526..b1a019e351 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,7 +4,7 @@ module.exports = { extends: ["custom"], settings: { next: { - rootDir: ["web/", "space/"], + rootDir: ["web/", "space/", "admin/"], }, }, }; diff --git a/admin/.env.example b/admin/.env.example index a86a8b4fba..fdeb05c4d7 100644 --- a/admin/.env.example +++ b/admin/.env.example @@ -1,5 +1,3 @@ NEXT_PUBLIC_API_BASE_URL="" -NEXT_PUBLIC_ADMIN_BASE_URL="" -NEXT_PUBLIC_SPACE_BASE_URL="" -NEXT_PUBLIC_WEB_BASE_URL="" -NEXT_PUBLIC_SPACE_BASE_PATH="/spaces" \ No newline at end of file +NEXT_PUBLIC_ADMIN_BASE_PATH="/god-mode" +NEXT_PUBLIC_WEB_BASE_URL="" \ No newline at end of file diff --git a/admin/app/ai/components/ai-config-form.tsx b/admin/app/ai/components/ai-config-form.tsx index d61eb9ed94..fda70611c2 100644 --- a/admin/app/ai/components/ai-config-form.tsx +++ b/admin/app/ai/components/ai-config-form.tsx @@ -6,7 +6,7 @@ import { IFormattedInstanceConfiguration, TInstanceAIConfigurationKeys } from "@ // components import { ControllerInput, TControllerInputFormField } from "components/common"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; type IInstanceAIForm = { config: IFormattedInstanceConfiguration; diff --git a/admin/app/ai/page.tsx b/admin/app/ai/page.tsx index 71af4a5ba9..5d002ca55b 100644 --- a/admin/app/ai/page.tsx +++ b/admin/app/ai/page.tsx @@ -7,7 +7,7 @@ import { Loader } from "@plane/ui"; import { PageHeader } from "@/components/core"; import { InstanceAIForm } from "./components"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; const InstanceAIPage = observer(() => { // store diff --git a/admin/app/authentication/components/email-config-switch.tsx b/admin/app/authentication/components/email-config-switch.tsx index 0958b3c424..9c23901fef 100644 --- a/admin/app/authentication/components/email-config-switch.tsx +++ b/admin/app/authentication/components/email-config-switch.tsx @@ -3,7 +3,7 @@ import React from "react"; import { observer } from "mobx-react-lite"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; // ui import { ToggleSwitch } from "@plane/ui"; // types diff --git a/admin/app/authentication/components/password-config-switch.tsx b/admin/app/authentication/components/password-config-switch.tsx index 92428e494d..ce33cd3294 100644 --- a/admin/app/authentication/components/password-config-switch.tsx +++ b/admin/app/authentication/components/password-config-switch.tsx @@ -3,7 +3,7 @@ import React from "react"; import { observer } from "mobx-react-lite"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; // ui import { ToggleSwitch } from "@plane/ui"; // types diff --git a/admin/app/authentication/github/components/github-config-form.tsx b/admin/app/authentication/github/components/github-config-form.tsx index 22eb11ff4e..43d2205757 100644 --- a/admin/app/authentication/github/components/github-config-form.tsx +++ b/admin/app/authentication/github/components/github-config-form.tsx @@ -2,7 +2,7 @@ import { FC, useState } from "react"; import { useForm } from "react-hook-form"; import Link from "next/link"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; // ui import { Button, TOAST_TYPE, getButtonStyling, setToast } from "@plane/ui"; // components diff --git a/admin/app/authentication/github/components/root.tsx b/admin/app/authentication/github/components/root.tsx index 742462c3b9..d820bc8a24 100644 --- a/admin/app/authentication/github/components/root.tsx +++ b/admin/app/authentication/github/components/root.tsx @@ -4,7 +4,7 @@ import React from "react"; import Link from "next/link"; import { observer } from "mobx-react-lite"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; // ui import { ToggleSwitch, getButtonStyling } from "@plane/ui"; // icons diff --git a/admin/app/authentication/github/page.tsx b/admin/app/authentication/github/page.tsx index 6470f812af..893762d472 100644 --- a/admin/app/authentication/github/page.tsx +++ b/admin/app/authentication/github/page.tsx @@ -11,7 +11,7 @@ import { PageHeader } from "@/components/core"; import { AuthenticationMethodCard } from "../components"; import { InstanceGithubConfigForm } from "./components"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; // helpers import { resolveGeneralTheme } from "@/helpers/common.helper"; // icons diff --git a/admin/app/authentication/google/components/google-config-form.tsx b/admin/app/authentication/google/components/google-config-form.tsx index 42cea78fd5..f070216940 100644 --- a/admin/app/authentication/google/components/google-config-form.tsx +++ b/admin/app/authentication/google/components/google-config-form.tsx @@ -2,7 +2,7 @@ import { FC, useState } from "react"; import { useForm } from "react-hook-form"; import Link from "next/link"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; // ui import { Button, TOAST_TYPE, getButtonStyling, setToast } from "@plane/ui"; // components diff --git a/admin/app/authentication/google/components/root.tsx b/admin/app/authentication/google/components/root.tsx index 6b287476dd..5432c95bf9 100644 --- a/admin/app/authentication/google/components/root.tsx +++ b/admin/app/authentication/google/components/root.tsx @@ -4,7 +4,7 @@ import React from "react"; import Link from "next/link"; import { observer } from "mobx-react-lite"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; // ui import { ToggleSwitch, getButtonStyling } from "@plane/ui"; // icons diff --git a/admin/app/authentication/google/page.tsx b/admin/app/authentication/google/page.tsx index f7fa6e6434..9b02842afe 100644 --- a/admin/app/authentication/google/page.tsx +++ b/admin/app/authentication/google/page.tsx @@ -10,7 +10,7 @@ import { PageHeader } from "@/components/core"; import { AuthenticationMethodCard } from "../components"; import { InstanceGoogleConfigForm } from "./components"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; // icons import GoogleLogo from "@/public/logos/google-logo.svg"; diff --git a/admin/app/authentication/page.tsx b/admin/app/authentication/page.tsx index 59e4056082..0685924683 100644 --- a/admin/app/authentication/page.tsx +++ b/admin/app/authentication/page.tsx @@ -14,7 +14,7 @@ import { GoogleConfiguration } from "./google/components"; import { GithubConfiguration } from "./github/components"; import { PageHeader } from "@/components/core"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; // helpers import { resolveGeneralTheme } from "@/helpers/common.helper"; // images diff --git a/admin/app/email/components/email-config-form.tsx b/admin/app/email/components/email-config-form.tsx index 38b50d50f7..50c8671325 100644 --- a/admin/app/email/components/email-config-form.tsx +++ b/admin/app/email/components/email-config-form.tsx @@ -1,7 +1,7 @@ import React, { FC, useMemo, useState } from "react"; import { useForm } from "react-hook-form"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; // ui import { Button, CustomSelect, TOAST_TYPE, setToast } from "@plane/ui"; // components diff --git a/admin/app/email/page.tsx b/admin/app/email/page.tsx index a3b0bed596..6ffebc904d 100644 --- a/admin/app/email/page.tsx +++ b/admin/app/email/page.tsx @@ -7,7 +7,7 @@ import { Loader } from "@plane/ui"; import { PageHeader } from "@/components/core"; import { InstanceEmailForm } from "./components"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; const InstanceEmailPage = observer(() => { // store diff --git a/admin/app/general/components/general-config-form.tsx b/admin/app/general/components/general-config-form.tsx index f45876419c..5e360e0481 100644 --- a/admin/app/general/components/general-config-form.tsx +++ b/admin/app/general/components/general-config-form.tsx @@ -6,7 +6,7 @@ import { Button, Input, TOAST_TYPE, ToggleSwitch, setToast } from "@plane/ui"; // components import { ControllerInput } from "components/common"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; export interface IGeneralConfigurationForm { instance: IInstance["instance"]; diff --git a/admin/app/general/page.tsx b/admin/app/general/page.tsx index 10429c1c9a..accaf01d12 100644 --- a/admin/app/general/page.tsx +++ b/admin/app/general/page.tsx @@ -5,7 +5,7 @@ import { observer } from "mobx-react-lite"; import { PageHeader } from "@/components/core"; import { GeneralConfigurationForm } from "./components"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; const GeneralPage = observer(() => { const { instance, instanceAdmins } = useInstance(); diff --git a/admin/app/image/components/image-config-form.tsx b/admin/app/image/components/image-config-form.tsx index 722051878b..1779468fa8 100644 --- a/admin/app/image/components/image-config-form.tsx +++ b/admin/app/image/components/image-config-form.tsx @@ -5,7 +5,7 @@ import { IFormattedInstanceConfiguration, TInstanceImageConfigurationKeys } from // components import { ControllerInput } from "components/common"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; type IInstanceImageConfigForm = { config: IFormattedInstanceConfiguration; diff --git a/admin/app/image/page.tsx b/admin/app/image/page.tsx index 68572c519f..cbf4a8f4d2 100644 --- a/admin/app/image/page.tsx +++ b/admin/app/image/page.tsx @@ -7,7 +7,7 @@ import { Loader } from "@plane/ui"; import { PageHeader } from "@/components/core"; import { InstanceImageConfigForm } from "./components"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; const InstanceImagePage = observer(() => { // store diff --git a/admin/app/layout.tsx b/admin/app/layout.tsx index d991f9d82c..3352cbfaec 100644 --- a/admin/app/layout.tsx +++ b/admin/app/layout.tsx @@ -7,6 +7,8 @@ import { StoreProvider } from "@/lib/store-context"; import { AppWrapper } from "@/lib/wrappers"; // constants import { SITE_NAME, SITE_DESCRIPTION, SITE_URL, TWITTER_USER_NAME, SITE_KEYWORDS, SITE_TITLE } from "@/constants/seo"; +// helpers +import { ASSET_PREFIX } from "@/helpers/common.helper"; // styles import "./globals.css"; @@ -14,35 +16,31 @@ interface RootLayoutProps { children: ReactNode; } -const RootLayout = ({ children, ...pageProps }: RootLayoutProps) => { - const prefix = "/god-mode/"; - - return ( - - - {SITE_TITLE} - - - - - - - - - - - - - - - - - {children} - - - - - ); -}; +const RootLayout = ({ children, ...pageProps }: RootLayoutProps) => ( + + + {SITE_TITLE} + + + + + + + + + + + + + + + + + {children} + + + + +); export default RootLayout; diff --git a/admin/components/admin-sidebar/help-section.tsx b/admin/components/admin-sidebar/help-section.tsx index ba8f2cba55..8b3f5baeb1 100644 --- a/admin/components/admin-sidebar/help-section.tsx +++ b/admin/components/admin-sidebar/help-section.tsx @@ -7,7 +7,7 @@ import { Transition } from "@headlessui/react"; import { ExternalLink, FileText, HelpCircle, MoveLeft } from "lucide-react"; import { DiscordIcon, GithubIcon, Tooltip } from "@plane/ui"; // hooks -import { useInstance, useTheme } from "@/hooks"; +import { useInstance, useTheme } from "@/hooks/store"; // assets import packageJson from "package.json"; diff --git a/admin/components/admin-sidebar/root.tsx b/admin/components/admin-sidebar/root.tsx index 3b754d8b2f..6547699244 100644 --- a/admin/components/admin-sidebar/root.tsx +++ b/admin/components/admin-sidebar/root.tsx @@ -3,7 +3,7 @@ import { FC, useEffect, useRef } from "react"; import { observer } from "mobx-react-lite"; // hooks -import { useTheme } from "@/hooks"; +import { useTheme } from "@/hooks/store"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; // components import { HelpSection, SidebarMenu, SidebarDropdown } from "@/components/admin-sidebar"; diff --git a/admin/components/admin-sidebar/sidebar-dropdown.tsx b/admin/components/admin-sidebar/sidebar-dropdown.tsx index 68212464e6..f248f852f1 100644 --- a/admin/components/admin-sidebar/sidebar-dropdown.tsx +++ b/admin/components/admin-sidebar/sidebar-dropdown.tsx @@ -7,7 +7,7 @@ import { LogOut, UserCog2, Palette } from "lucide-react"; import { Menu, Transition } from "@headlessui/react"; import { Avatar } from "@plane/ui"; // hooks -import { useTheme, useUser } from "@/hooks"; +import { useTheme, useUser } from "@/hooks/store"; // helpers import { API_BASE_URL, cn } from "@/helpers/common.helper"; // services diff --git a/admin/components/admin-sidebar/sidebar-menu-hamburger-toogle.tsx b/admin/components/admin-sidebar/sidebar-menu-hamburger-toogle.tsx index ba00afa7f6..d6ed655411 100644 --- a/admin/components/admin-sidebar/sidebar-menu-hamburger-toogle.tsx +++ b/admin/components/admin-sidebar/sidebar-menu-hamburger-toogle.tsx @@ -3,7 +3,7 @@ import { FC } from "react"; import { observer } from "mobx-react-lite"; // hooks -import { useTheme } from "@/hooks"; +import { useTheme } from "@/hooks/store"; // icons import { Menu } from "lucide-react"; diff --git a/admin/components/admin-sidebar/sidebar-menu.tsx b/admin/components/admin-sidebar/sidebar-menu.tsx index e7111aea22..dfb4100511 100644 --- a/admin/components/admin-sidebar/sidebar-menu.tsx +++ b/admin/components/admin-sidebar/sidebar-menu.tsx @@ -6,7 +6,7 @@ import { observer } from "mobx-react-lite"; import { Image, BrainCog, Cog, Lock, Mail } from "lucide-react"; import { Tooltip } from "@plane/ui"; // hooks -import { useTheme } from "@/hooks"; +import { useTheme } from "@/hooks/store"; // helpers import { cn } from "@/helpers/common.helper"; diff --git a/admin/components/new-user-popup.tsx b/admin/components/new-user-popup.tsx index d17e99d5ea..6b4cea340c 100644 --- a/admin/components/new-user-popup.tsx +++ b/admin/components/new-user-popup.tsx @@ -9,7 +9,7 @@ import { Button, getButtonStyling } from "@plane/ui"; // helpers import { resolveGeneralTheme } from "helpers/common.helper"; // hooks -import { useInstance, useTheme } from "@/hooks"; +import { useInstance, useTheme } from "@/hooks/store"; // icons import TakeoffIconLight from "/public/logos/takeoff-icon-light.svg"; import TakeoffIconDark from "/public/logos/takeoff-icon-dark.svg"; diff --git a/admin/helpers/common.helper.ts b/admin/helpers/common.helper.ts index 3bf03024bb..e7aae0698f 100644 --- a/admin/helpers/common.helper.ts +++ b/admin/helpers/common.helper.ts @@ -1,7 +1,16 @@ import { clsx, type ClassValue } from "clsx"; import { twMerge } from "tailwind-merge"; -export const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ? process.env.NEXT_PUBLIC_API_BASE_URL : ""; +export const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || ""; + +export const ADMIN_BASE_PATH = process.env.NEXT_PUBLIC_ADMIN_BASE_PATH || ""; + +export const SPACE_BASE_URL = process.env.NEXT_PUBLIC_SPACE_BASE_URL || ""; +export const SPACE_BASE_PATH = process.env.NEXT_PUBLIC_SPACE_BASE_PATH || ""; + +export const WEB_BASE_URL = process.env.NEXT_PUBLIC_WEB_BASE_URL || ""; + +export const ASSET_PREFIX = ADMIN_BASE_PATH; export const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs)); diff --git a/admin/hooks/index.ts b/admin/hooks/index.ts deleted file mode 100644 index 273970eda1..0000000000 --- a/admin/hooks/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from "./use-outside-click-detector"; - -// store-hooks -export * from "./store/use-theme"; -export * from "./store/use-instance"; -export * from "./store/use-user"; diff --git a/admin/hooks/store/index.ts b/admin/hooks/store/index.ts new file mode 100644 index 0000000000..7447064da7 --- /dev/null +++ b/admin/hooks/store/index.ts @@ -0,0 +1,3 @@ +export * from "./use-theme"; +export * from "./use-instance"; +export * from "./use-user"; diff --git a/admin/lib/wrappers/app-wrapper.tsx b/admin/lib/wrappers/app-wrapper.tsx index 6be1cec246..aa6e263305 100644 --- a/admin/lib/wrappers/app-wrapper.tsx +++ b/admin/lib/wrappers/app-wrapper.tsx @@ -4,11 +4,11 @@ import { FC, ReactNode, useEffect, Suspense } from "react"; import { observer } from "mobx-react-lite"; import { SWRConfig } from "swr"; // hooks -import { useTheme, useUser } from "@/hooks"; +import { useTheme, useUser } from "@/hooks/store"; // ui import { Toast } from "@plane/ui"; // constants -import { SWR_CONFIG } from "constants/swr-config"; +import { SWR_CONFIG } from "@/constants/swr-config"; // helpers import { resolveGeneralTheme } from "helpers/common.helper"; diff --git a/admin/lib/wrappers/auth-wrapper.tsx b/admin/lib/wrappers/auth-wrapper.tsx index 75e7c2accd..00f947047b 100644 --- a/admin/lib/wrappers/auth-wrapper.tsx +++ b/admin/lib/wrappers/auth-wrapper.tsx @@ -6,7 +6,7 @@ import { observer } from "mobx-react-lite"; import useSWR from "swr"; import { Spinner } from "@plane/ui"; // hooks -import { useInstance, useUser } from "@/hooks"; +import { useInstance, useUser } from "@/hooks/store"; // helpers import { EAuthenticationPageType } from "@/helpers"; diff --git a/admin/lib/wrappers/instance-wrapper.tsx b/admin/lib/wrappers/instance-wrapper.tsx index da02992aa3..6ee1dc247d 100644 --- a/admin/lib/wrappers/instance-wrapper.tsx +++ b/admin/lib/wrappers/instance-wrapper.tsx @@ -10,7 +10,7 @@ import { DefaultLayout } from "@/layouts"; // components import { InstanceNotReady } from "@/components/instance"; // hooks -import { useInstance } from "@/hooks"; +import { useInstance } from "@/hooks/store"; // helpers import { EInstancePageType } from "@/helpers"; @@ -28,6 +28,9 @@ export const InstanceWrapper: FC = observer((props) => { const { isLoading: isSWRLoading } = useSWR("INSTANCE_INFORMATION", () => fetchInstanceInfo(), { revalidateOnFocus: false, + revalidateIfStale: false, + revalidateOnReconnect: false, + errorRetryCount: 0, }); if (isSWRLoading || isLoading) @@ -37,6 +40,10 @@ export const InstanceWrapper: FC = observer((props) => {
); + if (!instance) { + return <>Something went wrong; + } + if (instance?.instance?.is_setup_done === false && authEnabled === "1") return ( diff --git a/admin/package.json b/admin/package.json index 6a63ea9372..936c612bb4 100644 --- a/admin/package.json +++ b/admin/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "dev": "turbo run develop", - "develop": "next dev --port 3333", + "develop": "next dev --port 3001", "build": "next build", "preview": "next build && next start", "start": "next start", diff --git a/admin/services/instance.service.ts b/admin/services/instance.service.ts index 519adc9f29..109b52e446 100644 --- a/admin/services/instance.service.ts +++ b/admin/services/instance.service.ts @@ -1,8 +1,8 @@ -import { APIService } from "services/api.service"; // types import type { IFormattedInstanceConfiguration, IInstance, IInstanceAdmin, IInstanceConfiguration } from "@plane/types"; // helpers -import { API_BASE_URL } from "helpers/common.helper"; +import { API_BASE_URL } from "@/helpers/common.helper"; +import { APIService } from "@/services/api.service"; export class InstanceService extends APIService { constructor() { diff --git a/space/helpers/common.helper.ts b/space/helpers/common.helper.ts index 085b34dc2b..f39cddc0ee 100644 --- a/space/helpers/common.helper.ts +++ b/space/helpers/common.helper.ts @@ -1,6 +1,12 @@ import { clsx, type ClassValue } from "clsx"; import { twMerge } from "tailwind-merge"; -export const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; +export const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || ""; + +export const SPACE_BASE_PATH = process.env.NEXT_PUBLIC_SPACE_BASE_PATH || ""; + +export const WEB_BASE_URL = process.env.NEXT_PUBLIC_WEB_BASE_URL || ""; + +export const ASSET_PREFIX = SPACE_BASE_PATH; export const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs)); diff --git a/space/package.json b/space/package.json index d27a231092..a10d190d23 100644 --- a/space/package.json +++ b/space/package.json @@ -4,9 +4,9 @@ "private": true, "scripts": { "dev": "turbo run develop", - "develop": "next dev -p 4000", + "develop": "next dev -p 3002", "build": "next build", - "start": "next start -p 4000", + "start": "next start", "lint": "next lint", "export": "next export" }, diff --git a/space/pages/onboarding/index.tsx b/space/pages/onboarding/index.tsx index 8318f03467..5c0b45e24f 100644 --- a/space/pages/onboarding/index.tsx +++ b/space/pages/onboarding/index.tsx @@ -9,6 +9,7 @@ import { Avatar } from "@plane/ui"; import { OnBoardingForm } from "@/components/accounts/onboarding-form"; // helpers import { EPageTypes } from "@/helpers/authentication.helper"; +import { ASSET_PREFIX } from "@/helpers/common.helper"; // hooks import { useUser, useUserProfile } from "@/hooks/store"; // wrappers @@ -17,8 +18,6 @@ import { AuthWrapper } from "@/lib/wrappers"; import ProfileSetupDark from "public/onboarding/profile-setup-dark.svg"; import ProfileSetup from "public/onboarding/profile-setup.svg"; -const imagePrefix = process.env.NEXT_PUBLIC_SPACE_BASE_PATH || ""; - const OnBoardingPage = observer(() => { // router const router = useRouter(); @@ -60,7 +59,7 @@ const OnBoardingPage = observer(() => {
Plane Logo { - // hooks - // const { instance } = useInstance(); - - const GOD_MODE_URL = encodeURI(ADMIN_BASE_URL + ADMIN_BASE_PATH + "setup/?auth_enabled=0"); +export const InstanceNotReady: FC = () => { + const GOD_MODE_URL = encodeURI(ADMIN_BASE_URL + ADMIN_BASE_PATH + "/setup/?auth_enabled=0"); return (
@@ -48,4 +42,4 @@ export const InstanceNotReady: FC = observer(() => {
); -}); +}; From da78933c614d45a52532deee57a6ffefc184aaa6 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 10 May 2024 15:24:18 +0530 Subject: [PATCH 06/12] [WEB-1274] chore: issue spreadsheet enhancement (#4423) * chore: border and background remove from cycle and module select * choe: indentation improvement --- web/components/dropdowns/module/index.tsx | 2 +- .../spreadsheet/columns/cycle-column.tsx | 2 +- .../spreadsheet/columns/module-column.tsx | 2 +- .../issues/issue-layouts/spreadsheet/index.ts | 1 + .../issue-layouts/spreadsheet/issue-row.tsx | 30 +++++++++++-------- .../spreadsheet/spreadsheet-header.tsx | 14 +++------ 6 files changed, 25 insertions(+), 26 deletions(-) diff --git a/web/components/dropdowns/module/index.tsx b/web/components/dropdowns/module/index.tsx index e1441efe9b..6883332e12 100644 --- a/web/components/dropdowns/module/index.tsx +++ b/web/components/dropdowns/module/index.tsx @@ -73,7 +73,7 @@ const ButtonContent: React.FC = (props) => { return ( <> {showCount ? ( -
+
{!hideIcon && } {(value.length > 0 || !!placeholder) && (
diff --git a/web/components/issues/issue-layouts/spreadsheet/columns/cycle-column.tsx b/web/components/issues/issue-layouts/spreadsheet/columns/cycle-column.tsx index 342a9208b5..a412c604fb 100644 --- a/web/components/issues/issue-layouts/spreadsheet/columns/cycle-column.tsx +++ b/web/components/issues/issue-layouts/spreadsheet/columns/cycle-column.tsx @@ -57,7 +57,7 @@ export const SpreadsheetCycleColumn: React.FC = observer((props) => { placeholder="Select cycle" buttonVariant="transparent-with-text" buttonContainerClassName="w-full relative flex items-center p-2" - buttonClassName="relative border-[0.5px] border-custom-border-400 h-4.5" + buttonClassName="relative leading-4 h-4.5 bg-transparent" onClose={onClose} />
diff --git a/web/components/issues/issue-layouts/spreadsheet/columns/module-column.tsx b/web/components/issues/issue-layouts/spreadsheet/columns/module-column.tsx index 75b9ac065e..fb742f7036 100644 --- a/web/components/issues/issue-layouts/spreadsheet/columns/module-column.tsx +++ b/web/components/issues/issue-layouts/spreadsheet/columns/module-column.tsx @@ -68,7 +68,7 @@ export const SpreadsheetModuleColumn: React.FC = observer((props) => { placeholder="Select modules" buttonVariant="transparent-with-text" buttonContainerClassName="w-full relative flex items-center p-2" - buttonClassName="relative border-[0.5px] border-custom-border-400 h-4.5" + buttonClassName="relative leading-4 h-4.5 bg-transparent" onClose={onClose} multiple showCount diff --git a/web/components/issues/issue-layouts/spreadsheet/index.ts b/web/components/issues/issue-layouts/spreadsheet/index.ts index 8f7c4a7fdb..8fa49e851e 100644 --- a/web/components/issues/issue-layouts/spreadsheet/index.ts +++ b/web/components/issues/issue-layouts/spreadsheet/index.ts @@ -2,3 +2,4 @@ export * from "./columns"; export * from "./roots"; export * from "./spreadsheet-view"; export * from "./quick-add-issue-form"; +export * from "./spreadsheet-header-column"; diff --git a/web/components/issues/issue-layouts/spreadsheet/issue-row.tsx b/web/components/issues/issue-layouts/spreadsheet/issue-row.tsx index 1bd8a8808c..1d1ea1e083 100644 --- a/web/components/issues/issue-layouts/spreadsheet/issue-row.tsx +++ b/web/components/issues/issue-layouts/spreadsheet/issue-row.tsx @@ -50,7 +50,7 @@ export const SpreadsheetIssueRow = observer((props: Props) => { containerRef, issueIds, spreadsheetColumnsList, - spacingLeft = 14, + spacingLeft = 6, } = props; const [isExpanded, setExpanded] = useState(false); @@ -96,7 +96,7 @@ export const SpreadsheetIssueRow = observer((props: Props) => { quickActions={quickActions} canEditProperties={canEditProperties} nestingLevel={nestingLevel + 1} - spacingLeft={spacingLeft + (displayProperties.key ? 16 : 28)} + spacingLeft={spacingLeft + (displayProperties.key ? 12 : 28)} isEstimateEnabled={isEstimateEnabled} updateIssue={updateIssue} portalElement={portalElement} @@ -140,7 +140,7 @@ const IssueRowDetails = observer((props: IssueRowDetailsProps) => { isExpanded, setExpanded, spreadsheetColumnsList, - spacingLeft = 14, + spacingLeft = 6, } = props; // states const [isMenuActive, setIsMenuActive] = useState(false); @@ -218,18 +218,22 @@ const IssueRowDetails = observer((props: IssueRowDetailsProps) => { disabled={!!issueDetail?.tempId} >
-
- {issueDetail.sub_issues_count > 0 && ( - - )} +
+ {/* bulk ops */} + +
+ {issueDetail.sub_issues_count > 0 && ( + + )} +
diff --git a/web/components/issues/issue-layouts/spreadsheet/spreadsheet-header.tsx b/web/components/issues/issue-layouts/spreadsheet/spreadsheet-header.tsx index 968aade3e5..63017f0e72 100644 --- a/web/components/issues/issue-layouts/spreadsheet/spreadsheet-header.tsx +++ b/web/components/issues/issue-layouts/spreadsheet/spreadsheet-header.tsx @@ -1,10 +1,9 @@ // ui import { IIssueDisplayFilterOptions, IIssueDisplayProperties } from "@plane/types"; +// types import { LayersIcon } from "@plane/ui"; -// constants // components -import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC"; -import { SpreadsheetHeaderColumn } from "./spreadsheet-header-column"; +import { SpreadsheetHeaderColumn } from "@/components/issues/issue-layouts"; interface Props { displayProperties: IIssueDisplayProperties; @@ -25,13 +24,8 @@ export const SpreadsheetHeader = (props: Props) => { className="sticky left-0 z-[15] h-11 w-[28rem] flex items-center bg-custom-background-90 text-sm font-medium before:absolute before:h-full before:right-0 before:border-[0.5px] before:border-custom-border-100" tabIndex={-1} > - - - #ID - - - - + + Issue From dc77e4afdb86574bf02a204908b66f185f43a1fa Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Fri, 10 May 2024 15:25:16 +0530 Subject: [PATCH 07/12] chore: project publish modal improvement (#4422) --- web/components/project/publish-project/modal.tsx | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/web/components/project/publish-project/modal.tsx b/web/components/project/publish-project/modal.tsx index 0b94c56f1c..6f2f68fad8 100644 --- a/web/components/project/publish-project/modal.tsx +++ b/web/components/project/publish-project/modal.tsx @@ -139,13 +139,7 @@ export const PublishProjectModal: React.FC = observer((props) => { const handlePublishProject = async (payload: IProjectPublishSettings) => { if (!workspaceSlug) return; - return publishProject(workspaceSlug.toString(), project.id, payload) - .then((res) => { - handleClose(); - // window.open(`${plane_deploy_url}/${workspaceSlug}/${project.id}`, "_blank"); - return res; - }) - .catch((err) => err); + return publishProject(workspaceSlug.toString(), project.id, payload); }; const handleUpdatePublishSettings = async (payload: IProjectPublishSettings) => { @@ -174,10 +168,6 @@ export const PublishProjectModal: React.FC = observer((props) => { setIsUnPublishing(true); await unPublishProject(workspaceSlug.toString(), project.id, publishId) - .then((res) => { - handleClose(); - return res; - }) .catch(() => setToast({ type: TOAST_TYPE.ERROR, From 74eb50aa1a911a3ca8ee996ea643c62c6dad97f2 Mon Sep 17 00:00:00 2001 From: Manish Gupta <59428681+mguptahub@users.noreply.github.com> Date: Fri, 10 May 2024 16:08:04 +0530 Subject: [PATCH 08/12] selfhosting fixes for custom branch and platform (#4431) --- deploy/selfhost/docker-compose.yml | 13 +++++++++++-- deploy/selfhost/install.sh | 10 ++++++---- deploy/selfhost/variables.env | 3 +++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/deploy/selfhost/docker-compose.yml b/deploy/selfhost/docker-compose.yml index 67f61d0ef4..6f58113bee 100644 --- a/deploy/selfhost/docker-compose.yml +++ b/deploy/selfhost/docker-compose.yml @@ -42,6 +42,7 @@ services: web: <<: *app-env image: ${DOCKERHUB_USER:-makeplane}/plane-frontend:${APP_RELEASE:-stable} + platform: ${DOCKER_PLATFORM:-} pull_policy: ${PULL_POLICY:-always} restart: unless-stopped command: node web/server.js web @@ -54,6 +55,7 @@ services: space: <<: *app-env image: ${DOCKERHUB_USER:-makeplane}/plane-space:${APP_RELEASE:-stable} + platform: ${DOCKER_PLATFORM:-} pull_policy: ${PULL_POLICY:-always} restart: unless-stopped command: node space/server.js space @@ -66,7 +68,8 @@ services: admin: <<: *app-env - image: ${DOCKERHUB_USER:-makeplane}/plane-space:${APP_RELEASE:-stable} + image: ${DOCKERHUB_USER:-makeplane}/plane-admin:${APP_RELEASE:-stable} + platform: ${DOCKER_PLATFORM:-} pull_policy: ${PULL_POLICY:-always} restart: unless-stopped command: node admin/server.js admin @@ -79,6 +82,7 @@ services: api: <<: *app-env image: ${DOCKERHUB_USER:-makeplane}/plane-backend:${APP_RELEASE:-stable} + platform: ${DOCKER_PLATFORM:-} pull_policy: ${PULL_POLICY:-always} restart: unless-stopped command: ./bin/takeoff @@ -93,6 +97,7 @@ services: worker: <<: *app-env image: ${DOCKERHUB_USER:-makeplane}/plane-backend:${APP_RELEASE:-stable} + platform: ${DOCKER_PLATFORM:-} pull_policy: ${PULL_POLICY:-always} restart: unless-stopped command: ./bin/worker @@ -106,6 +111,7 @@ services: beat-worker: <<: *app-env image: ${DOCKERHUB_USER:-makeplane}/plane-backend:${APP_RELEASE:-stable} + platform: ${DOCKER_PLATFORM:-} pull_policy: ${PULL_POLICY:-always} restart: unless-stopped command: ./bin/beat @@ -119,6 +125,7 @@ services: migrator: <<: *app-env image: ${DOCKERHUB_USER:-makeplane}/plane-backend:${APP_RELEASE:-stable} + platform: ${DOCKER_PLATFORM:-} pull_policy: ${PULL_POLICY:-always} restart: no command: > @@ -138,6 +145,7 @@ services: command: postgres -c 'max_connections=1000' volumes: - pgdata:/var/lib/postgresql/data + plane-redis: <<: *app-env image: redis:7.2.4-alpine @@ -148,7 +156,7 @@ services: plane-minio: <<: *app-env - image: minio/minio + image: minio/minio:latest pull_policy: if_not_present restart: unless-stopped command: server /export --console-address ":9090" @@ -159,6 +167,7 @@ services: proxy: <<: *app-env image: ${DOCKERHUB_USER:-makeplane}/plane-proxy:${APP_RELEASE:-stable} + platform: ${DOCKER_PLATFORM:-} pull_policy: ${PULL_POLICY:-always} ports: - ${NGINX_PORT}:80 diff --git a/deploy/selfhost/install.sh b/deploy/selfhost/install.sh index aaf1295241..b36d3b6b28 100755 --- a/deploy/selfhost/install.sh +++ b/deploy/selfhost/install.sh @@ -2,7 +2,8 @@ BRANCH=master SCRIPT_DIR=$PWD -PLANE_INSTALL_DIR=$PWD/plane-app +SERVICE_FOLDER=plane-app +PLANE_INSTALL_DIR=$PWD/$SERVICE_FOLDER export APP_RELEASE=$BRANCH export DOCKERHUB_USER=makeplane export PULL_POLICY=always @@ -140,7 +141,7 @@ function download() { function startServices() { /bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH --env-file=$DOCKER_ENV_PATH up -d --quiet-pull" - local migrator_container_id=$(docker container ls -aq -f "name=plane-app-migrator") + local migrator_container_id=$(docker container ls -aq -f "name=$SERVICE_FOLDER-migrator") if [ -n "$migrator_container_id" ]; then local idx=0 while docker inspect --format='{{.State.Status}}' $migrator_container_id | grep -q "running"; do @@ -168,7 +169,7 @@ function startServices() { fi fi - local api_container_id=$(docker container ls -q -f "name=plane-app-api") + local api_container_id=$(docker container ls -q -f "name=$SERVICE_FOLDER-api") local idx2=0 while ! docker logs $api_container_id 2>&1 | grep -m 1 -i "Application startup complete" | grep -q "."; do @@ -408,7 +409,8 @@ fi # REMOVE SPECIAL CHARACTERS FROM BRANCH NAME if [ "$BRANCH" != "master" ]; then - PLANE_INSTALL_DIR=$PWD/plane-app-$(echo $BRANCH | sed -r 's@(\/|" "|\.)@-@g') + SERVICE_FOLDER=plane-app-$(echo $BRANCH | sed -r 's@(\/|" "|\.)@-@g') + PLANE_INSTALL_DIR=$PWD/$SERVICE_FOLDER fi mkdir -p $PLANE_INSTALL_DIR/archive diff --git a/deploy/selfhost/variables.env b/deploy/selfhost/variables.env index 91e206bb49..62c4bc164a 100644 --- a/deploy/selfhost/variables.env +++ b/deploy/selfhost/variables.env @@ -43,3 +43,6 @@ FILE_SIZE_LIMIT=5242880 # Gunicorn Workers GUNICORN_WORKERS=1 + +# UNCOMMENT `DOCKER_PLATFORM` IF YOU ARE ON `ARM64` AND DOCKER IMAGE IS NOT AVAILABLE FOR RESPECTIVE `APP_RELEASE` +# DOCKER_PLATFORM=linux/amd64 \ No newline at end of file From b725c69882102436b382eca9d6e19e89e8e44a6f Mon Sep 17 00:00:00 2001 From: rahulramesha <71900764+rahulramesha@users.noreply.github.com> Date: Fri, 10 May 2024 16:14:15 +0530 Subject: [PATCH 09/12] list and spreadsheet sub issues mutation issue (#4415) --- web/components/issues/issue-detail/parent-select.tsx | 6 ++++-- web/components/issues/issue-layouts/list/block.tsx | 7 +++++-- .../issues/issue-layouts/spreadsheet/issue-row.tsx | 7 +++++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/web/components/issues/issue-detail/parent-select.tsx b/web/components/issues/issue-detail/parent-select.tsx index 6994dd5bdb..d8399fc02b 100644 --- a/web/components/issues/issue-detail/parent-select.tsx +++ b/web/components/issues/issue-detail/parent-select.tsx @@ -34,7 +34,7 @@ export const IssueParentSelect: React.FC = observer((props) isParentIssueModalOpen, toggleParentIssueModal, removeSubIssue, - subIssues: { setSubIssueHelpers }, + subIssues: { setSubIssueHelpers, fetchSubIssues }, } = useIssueDetail(); // derived values @@ -47,7 +47,8 @@ export const IssueParentSelect: React.FC = observer((props) try { await issueOperations.update(workspaceSlug, projectId, issueId, { parent_id: _issueId }); await issueOperations.fetch(workspaceSlug, projectId, issueId); - toggleParentIssueModal(issueId); + _issueId && (await fetchSubIssues(workspaceSlug, projectId, _issueId)); + toggleParentIssueModal(null); } catch (error) { console.error("something went wrong while fetching the issue"); } @@ -62,6 +63,7 @@ export const IssueParentSelect: React.FC = observer((props) try { setSubIssueHelpers(parentIssueId, "issue_loader", issueId); await removeSubIssue(workspaceSlug, projectId, parentIssueId, issueId); + await fetchSubIssues(workspaceSlug, projectId, parentIssueId); setSubIssueHelpers(parentIssueId, "issue_loader", issueId); } catch (error) { setToast({ diff --git a/web/components/issues/issue-layouts/list/block.tsx b/web/components/issues/issue-layouts/list/block.tsx index c68abac14f..46499020e0 100644 --- a/web/components/issues/issue-layouts/list/block.tsx +++ b/web/components/issues/issue-layouts/list/block.tsx @@ -57,11 +57,14 @@ export const IssueBlock: React.FC = observer((props: IssueBlock setPeekIssue({ workspaceSlug, projectId: issue.project_id, issueId: issue.id }); const issue = issuesMap[issueId]; + const subIssues = subIssuesStore.subIssuesByIssueId(issueId); const { isMobile } = usePlatformOS(); if (!issue) return null; const canEditIssueProperties = canEditProperties(issue.project_id); const projectIdentifier = getProjectIdentifierById(issue.project_id); + // if sub issues have been fetched for the issue, use that for count or use issue's sub_issues_count + const subIssuesCount = subIssues ? subIssues.length : issue.sub_issues_count; const paddingLeft = `${spacingLeft}px`; @@ -90,11 +93,11 @@ export const IssueBlock: React.FC = observer((props: IssueBlock } )} > -
+
- {issue.sub_issues_count > 0 && ( + {subIssuesCount > 0 && ( + )} + {secondaryButton} +
+
+
+); diff --git a/admin/components/common/index.ts b/admin/components/common/index.ts index 97248b999d..77f0e9327f 100644 --- a/admin/components/common/index.ts +++ b/admin/components/common/index.ts @@ -4,3 +4,4 @@ export * from "./controller-input"; export * from "./copy-field"; export * from "./password-strength-meter"; export * from "./banner"; +export * from "./empty-state"; diff --git a/admin/lib/wrappers/instance-wrapper.tsx b/admin/lib/wrappers/instance-wrapper.tsx index 6ee1dc247d..f86adfdce5 100644 --- a/admin/lib/wrappers/instance-wrapper.tsx +++ b/admin/lib/wrappers/instance-wrapper.tsx @@ -13,6 +13,7 @@ import { InstanceNotReady } from "@/components/instance"; import { useInstance } from "@/hooks/store"; // helpers import { EInstancePageType } from "@/helpers"; +import { EmptyState } from "@/components/common"; type TInstanceWrapper = { children: ReactNode; @@ -41,7 +42,12 @@ export const InstanceWrapper: FC = observer((props) => { ); if (!instance) { - return <>Something went wrong; + return ( + + ); } if (instance?.instance?.is_setup_done === false && authEnabled === "1") diff --git a/apiserver/plane/authentication/adapter/error.py b/apiserver/plane/authentication/adapter/error.py index 4b975939d5..73809b9ad5 100644 --- a/apiserver/plane/authentication/adapter/error.py +++ b/apiserver/plane/authentication/adapter/error.py @@ -1,51 +1,52 @@ AUTHENTICATION_ERROR_CODES = { # Global "INSTANCE_NOT_CONFIGURED": 5000, - "INVALID_EMAIL": 5012, - "EMAIL_REQUIRED": 5013, - "SIGNUP_DISABLED": 5001, + "INVALID_EMAIL": 5005, + "EMAIL_REQUIRED": 5010, + "SIGNUP_DISABLED": 5015, # Password strength - "INVALID_PASSWORD": 5002, - "SMTP_NOT_CONFIGURED": 5007, + "INVALID_PASSWORD": 5020, + "SMTP_NOT_CONFIGURED": 5025, # Sign Up - "USER_ALREADY_EXIST": 5003, - "AUTHENTICATION_FAILED_SIGN_UP": 5006, - "REQUIRED_EMAIL_PASSWORD_SIGN_UP": 5015, - "INVALID_EMAIL_SIGN_UP": 5017, - "INVALID_EMAIL_MAGIC_SIGN_UP": 5019, - "MAGIC_SIGN_UP_EMAIL_CODE_REQUIRED": 5023, + "USER_ALREADY_EXIST": 5030, + "AUTHENTICATION_FAILED_SIGN_UP": 5035, + "REQUIRED_EMAIL_PASSWORD_SIGN_UP": 5040, + "INVALID_EMAIL_SIGN_UP": 5045, + "INVALID_EMAIL_MAGIC_SIGN_UP": 5050, + "MAGIC_SIGN_UP_EMAIL_CODE_REQUIRED": 5055, # Sign In - "USER_DOES_NOT_EXIST": 5004, - "AUTHENTICATION_FAILED_SIGN_IN": 5005, - "REQUIRED_EMAIL_PASSWORD_SIGN_IN": 5014, - "INVALID_EMAIL_SIGN_IN": 5016, - "INVALID_EMAIL_MAGIC_SIGN_IN": 5018, - "MAGIC_SIGN_IN_EMAIL_CODE_REQUIRED": 5022, - # Both Sign in and Sign up - "INVALID_MAGIC_CODE": 5008, - "EXPIRED_MAGIC_CODE": 5009, + "USER_DOES_NOT_EXIST": 5060, + "AUTHENTICATION_FAILED_SIGN_IN": 5065, + "REQUIRED_EMAIL_PASSWORD_SIGN_IN": 5070, + "INVALID_EMAIL_SIGN_IN": 5075, + "INVALID_EMAIL_MAGIC_SIGN_IN": 5080, + "MAGIC_SIGN_IN_EMAIL_CODE_REQUIRED": 5085, + # Both Sign in and Sign up for magic + "INVALID_MAGIC_CODE": 5090, + "EXPIRED_MAGIC_CODE": 5095, + "EMAIL_CODE_ATTEMPT_EXHAUSTED": 5100, # Oauth - "GOOGLE_NOT_CONFIGURED": 5010, - "GITHUB_NOT_CONFIGURED": 5011, - "GOOGLE_OAUTH_PROVIDER_ERROR": 5021, - "GITHUB_OAUTH_PROVIDER_ERROR": 5020, + "GOOGLE_NOT_CONFIGURED": 5105, + "GITHUB_NOT_CONFIGURED": 5110, + "GOOGLE_OAUTH_PROVIDER_ERROR": 5115, + "GITHUB_OAUTH_PROVIDER_ERROR": 5120, # Reset Password - "INVALID_PASSWORD_TOKEN": 5024, - "EXPIRED_PASSWORD_TOKEN": 5025, + "INVALID_PASSWORD_TOKEN": 5125, + "EXPIRED_PASSWORD_TOKEN": 5130, # Change password - "INCORRECT_OLD_PASSWORD": 5026, - "INVALID_NEW_PASSWORD": 5027, + "INCORRECT_OLD_PASSWORD": 5135, + "INVALID_NEW_PASSWORD": 5140, # set passowrd - "PASSWORD_ALREADY_SET": 5028, + "PASSWORD_ALREADY_SET": 5145, # Admin - "ADMIN_ALREADY_EXIST": 5029, - "REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME": 5030, - "INVALID_ADMIN_EMAIL": 5031, - "INVALID_ADMIN_PASSWORD": 5032, - "REQUIRED_ADMIN_EMAIL_PASSWORD": 5033, - "ADMIN_AUTHENTICATION_FAILED": 5034, - "ADMIN_USER_ALREADY_EXIST": 5035, - "ADMIN_USER_DOES_NOT_EXIST": 5036, + "ADMIN_ALREADY_EXIST": 5150, + "REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME": 5155, + "INVALID_ADMIN_EMAIL": 5160, + "INVALID_ADMIN_PASSWORD": 5165, + "REQUIRED_ADMIN_EMAIL_PASSWORD": 5170, + "ADMIN_AUTHENTICATION_FAILED": 5175, + "ADMIN_USER_ALREADY_EXIST": 5180, + "ADMIN_USER_DOES_NOT_EXIST": 5185, } diff --git a/apiserver/plane/authentication/provider/credentials/magic_code.py b/apiserver/plane/authentication/provider/credentials/magic_code.py index 71451ef0d6..c1207d14d5 100644 --- a/apiserver/plane/authentication/provider/credentials/magic_code.py +++ b/apiserver/plane/authentication/provider/credentials/magic_code.py @@ -77,7 +77,13 @@ class MagicCodeProvider(CredentialAdapter): current_attempt = data["current_attempt"] + 1 if data["current_attempt"] > 2: - return key, "" + raise AuthenticationException( + error_code=AUTHENTICATION_ERROR_CODES[ + "EMAIL_CODE_ATTEMPT_EXHAUSTED" + ], + error_message="EMAIL_CODE_ATTEMPT_EXHAUSTED", + payload={"email": self.key}, + ) value = { "current_attempt": current_attempt, diff --git a/apiserver/plane/authentication/utils/host.py b/apiserver/plane/authentication/utils/host.py index b670eed41c..4046c1e207 100644 --- a/apiserver/plane/authentication/utils/host.py +++ b/apiserver/plane/authentication/utils/host.py @@ -5,21 +5,38 @@ from urllib.parse import urlsplit from django.conf import settings -def base_host(request, is_admin=False, is_space=False): +def base_host(request, is_admin=False, is_space=False, is_app=False): """Utility function to return host / origin from the request""" - - if is_admin and settings.ADMIN_BASE_URL: - return settings.ADMIN_BASE_URL - - if is_space and settings.SPACE_BASE_URL: - return settings.SPACE_BASE_URL - - return ( + # Calculate the base origin from request + base_origin = str( request.META.get("HTTP_ORIGIN") or f"{urlsplit(request.META.get('HTTP_REFERER')).scheme}://{urlsplit(request.META.get('HTTP_REFERER')).netloc}" or f"""{"https" if request.is_secure() else "http"}://{request.get_host()}""" ) + # Admin redirections + if is_admin: + if settings.ADMIN_BASE_URL: + return settings.ADMIN_BASE_URL + else: + return base_origin + "/god-mode/" + + # Space redirections + if is_space: + if settings.SPACE_BASE_URL: + return settings.SPACE_BASE_URL + else: + return base_origin + "/spaces/" + + # App Redirection + if is_app: + if settings.APP_BASE_URL: + return settings.APP_BASE_URL + else: + return base_origin + + return base_origin + def user_ip(request): return str(request.META.get("REMOTE_ADDR")) diff --git a/apiserver/plane/authentication/utils/login.py b/apiserver/plane/authentication/utils/login.py index 88a988c8f5..45dbdc2494 100644 --- a/apiserver/plane/authentication/utils/login.py +++ b/apiserver/plane/authentication/utils/login.py @@ -5,12 +5,17 @@ from django.contrib.auth import login from plane.authentication.utils.host import base_host -def user_login(request, user): +def user_login(request, user, is_app=False, is_admin=False, is_space=False): login(request=request, user=user) device_info = { "user_agent": request.META.get("HTTP_USER_AGENT", ""), "ip_address": request.META.get("REMOTE_ADDR", ""), - "domain": base_host(request=request), + "domain": base_host( + request=request, + is_app=is_app, + is_admin=is_admin, + is_space=is_space, + ), } request.session["device_info"] = device_info request.session.save() diff --git a/apiserver/plane/authentication/views/app/email.py b/apiserver/plane/authentication/views/app/email.py index 7ef6ac9f4c..4093be1080 100644 --- a/apiserver/plane/authentication/views/app/email.py +++ b/apiserver/plane/authentication/views/app/email.py @@ -42,8 +42,8 @@ class SignInAuthEndpoint(View): params["next_path"] = str(next_path) # Base URL join url = urljoin( - base_host(request=request), - "accounts/sign-in?" + urlencode(params), + base_host(request=request, is_app=True), + "sign-in?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -66,8 +66,8 @@ class SignInAuthEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), - "accounts/sign-in?" + urlencode(params), + base_host(request=request, is_app=True), + "sign-in?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -85,8 +85,8 @@ class SignInAuthEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), - "accounts/sign-in?" + urlencode(params), + base_host(request=request, is_app=True), + "sign-in?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -100,8 +100,8 @@ class SignInAuthEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), - "accounts/sign-in?" + urlencode(params), + base_host(request=request, is_app=True), + "sign-in?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -111,7 +111,7 @@ class SignInAuthEndpoint(View): ) user = provider.authenticate() # Login the user and record his device info - user_login(request=request, user=user) + user_login(request=request, user=user, is_app=True) # Process workspace and project invitations process_workspace_project_invitations(user=user) # Get the redirection path @@ -121,15 +121,15 @@ class SignInAuthEndpoint(View): path = get_redirection_path(user=user) # redirect to referer path - url = urljoin(base_host(request=request), path) + url = urljoin(base_host(request=request, is_app=True), path) return HttpResponseRedirect(url) except AuthenticationException as e: params = e.get_error_dict() if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), - "accounts/sign-in?" + urlencode(params), + base_host(request=request, is_app=True), + "sign-in?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -152,7 +152,7 @@ class SignUpAuthEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -173,7 +173,7 @@ class SignUpAuthEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -192,7 +192,7 @@ class SignUpAuthEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -207,7 +207,7 @@ class SignUpAuthEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -218,7 +218,7 @@ class SignUpAuthEndpoint(View): ) user = provider.authenticate() # Login the user and record his device info - user_login(request=request, user=user) + user_login(request=request, user=user, is_app=True) # Process workspace and project invitations process_workspace_project_invitations(user=user) # Get the redirection path @@ -227,14 +227,14 @@ class SignUpAuthEndpoint(View): else: path = get_redirection_path(user=user) # redirect to referer path - url = urljoin(base_host(request=request), path) + url = urljoin(base_host(request=request, is_app=True), path) return HttpResponseRedirect(url) except AuthenticationException as e: params = e.get_error_dict() if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "?" + urlencode(params), ) return HttpResponseRedirect(url) diff --git a/apiserver/plane/authentication/views/app/github.py b/apiserver/plane/authentication/views/app/github.py index 48b7e09d96..73afa674b9 100644 --- a/apiserver/plane/authentication/views/app/github.py +++ b/apiserver/plane/authentication/views/app/github.py @@ -24,7 +24,7 @@ class GitHubOauthInitiateEndpoint(View): def get(self, request): # Get host and next path - request.session["host"] = base_host(request=request) + request.session["host"] = base_host(request=request, is_app=True) next_path = request.GET.get("next_path") if next_path: request.session["next_path"] = str(next_path) @@ -42,7 +42,7 @@ class GitHubOauthInitiateEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -57,7 +57,7 @@ class GitHubOauthInitiateEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -110,7 +110,7 @@ class GitHubCallbackEndpoint(View): ) user = provider.authenticate() # Login the user and record his device info - user_login(request=request, user=user) + user_login(request=request, user=user, is_app=True) # Process workspace and project invitations process_workspace_project_invitations(user=user) # Get the redirection path diff --git a/apiserver/plane/authentication/views/app/google.py b/apiserver/plane/authentication/views/app/google.py index 690a9778bd..ea3afed896 100644 --- a/apiserver/plane/authentication/views/app/google.py +++ b/apiserver/plane/authentication/views/app/google.py @@ -24,7 +24,7 @@ from plane.authentication.adapter.error import ( class GoogleOauthInitiateEndpoint(View): def get(self, request): - request.session["host"] = base_host(request=request) + request.session["host"] = base_host(request=request, is_app=True) next_path = request.GET.get("next_path") if next_path: request.session["next_path"] = str(next_path) @@ -42,7 +42,7 @@ class GoogleOauthInitiateEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -58,7 +58,7 @@ class GoogleOauthInitiateEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -108,7 +108,7 @@ class GoogleCallbackEndpoint(View): ) user = provider.authenticate() # Login the user and record his device info - user_login(request=request, user=user) + user_login(request=request, user=user, is_app=True) # Process workspace and project invitations process_workspace_project_invitations(user=user) # Get the redirection path diff --git a/apiserver/plane/authentication/views/app/magic.py b/apiserver/plane/authentication/views/app/magic.py index 8f9f3633b4..0fa5296740 100644 --- a/apiserver/plane/authentication/views/app/magic.py +++ b/apiserver/plane/authentication/views/app/magic.py @@ -90,8 +90,8 @@ class MagicSignInEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), - "accounts/sign-in?" + urlencode(params), + base_host(request=request, is_app=True), + "sign-in?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -104,8 +104,8 @@ class MagicSignInEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), - "accounts/sign-in?" + urlencode(params), + base_host(request=request, is_app=True), + "sign-in?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -116,7 +116,7 @@ class MagicSignInEndpoint(View): user = provider.authenticate() profile = Profile.objects.get(user=user) # Login the user and record his device info - user_login(request=request, user=user) + user_login(request=request, user=user, is_app=True) # Process workspace and project invitations process_workspace_project_invitations(user=user) if user.is_password_autoset and profile.is_onboarded: @@ -129,7 +129,7 @@ class MagicSignInEndpoint(View): else str(process_workspace_project_invitations(user=user)) ) # redirect to referer path - url = urljoin(base_host(request=request), path) + url = urljoin(base_host(request=request, is_app=True), path) return HttpResponseRedirect(url) except AuthenticationException as e: @@ -137,8 +137,8 @@ class MagicSignInEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), - "accounts/sign-in?" + urlencode(params), + base_host(request=request, is_app=True), + "sign-in?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -163,7 +163,7 @@ class MagicSignUpEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -177,7 +177,7 @@ class MagicSignUpEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -188,7 +188,7 @@ class MagicSignUpEndpoint(View): ) user = provider.authenticate() # Login the user and record his device info - user_login(request=request, user=user) + user_login(request=request, user=user, is_app=True) # Process workspace and project invitations process_workspace_project_invitations(user=user) # Get the redirection path @@ -197,7 +197,7 @@ class MagicSignUpEndpoint(View): else: path = get_redirection_path(user=user) # redirect to referer path - url = urljoin(base_host(request=request), path) + url = urljoin(base_host(request=request, is_app=True), path) return HttpResponseRedirect(url) except AuthenticationException as e: @@ -205,7 +205,7 @@ class MagicSignUpEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "?" + urlencode(params), ) return HttpResponseRedirect(url) diff --git a/apiserver/plane/authentication/views/app/password_management.py b/apiserver/plane/authentication/views/app/password_management.py index 80803cd253..b26b577606 100644 --- a/apiserver/plane/authentication/views/app/password_management.py +++ b/apiserver/plane/authentication/views/app/password_management.py @@ -146,7 +146,7 @@ class ResetPasswordEndpoint(View): ) params = exc.get_error_dict() url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "accounts/reset-password?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -159,8 +159,9 @@ class ResetPasswordEndpoint(View): error_message="INVALID_PASSWORD", ) url = urljoin( - base_host(request=request), - "?" + urlencode(exc.get_error_dict()), + base_host(request=request, is_app=True), + "accounts/reset-password?" + + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) @@ -172,7 +173,7 @@ class ResetPasswordEndpoint(View): error_message="INVALID_PASSWORD", ) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "accounts/reset-password?" + urlencode(exc.get_error_dict()), ) @@ -184,8 +185,8 @@ class ResetPasswordEndpoint(View): user.save() url = urljoin( - base_host(request=request), - "accounts/sign-in?" + urlencode({"success": True}), + base_host(request=request, is_app=True), + "sign-in?" + urlencode({"success": True}), ) return HttpResponseRedirect(url) except DjangoUnicodeDecodeError: @@ -196,7 +197,7 @@ class ResetPasswordEndpoint(View): error_message="EXPIRED_PASSWORD_TOKEN", ) url = urljoin( - base_host(request=request), + base_host(request=request, is_app=True), "accounts/reset-password?" + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) diff --git a/apiserver/plane/authentication/views/app/signout.py b/apiserver/plane/authentication/views/app/signout.py index 967f398eb1..10461f240d 100644 --- a/apiserver/plane/authentication/views/app/signout.py +++ b/apiserver/plane/authentication/views/app/signout.py @@ -1,5 +1,5 @@ # Python imports -from urllib.parse import urlencode, urljoin +from urllib.parse import urljoin # Django imports from django.views import View @@ -23,12 +23,9 @@ class SignOutAuthEndpoint(View): user.save() # Log the user out logout(request) - url = urljoin( - base_host(request=request), - "accounts/sign-in?" + urlencode({"success": "true"}), - ) + url = urljoin(base_host(request=request, is_app=True), "sign-in") return HttpResponseRedirect(url) except Exception: return HttpResponseRedirect( - base_host(request=request), "accounts/sign-in" + base_host(request=request, is_app=True), "sign-in" ) diff --git a/apiserver/plane/authentication/views/common.py b/apiserver/plane/authentication/views/common.py index 4b93010de5..16ac058b02 100644 --- a/apiserver/plane/authentication/views/common.py +++ b/apiserver/plane/authentication/views/common.py @@ -70,7 +70,7 @@ class ChangePasswordEndpoint(APIView): user.set_password(serializer.data.get("new_password")) user.is_password_autoset = False user.save() - user_login(user=user, request=request) + user_login(user=user, request=request, is_app=True) return Response( {"message": "Password updated successfully"}, status=status.HTTP_200_OK, @@ -131,7 +131,7 @@ class SetUserPasswordEndpoint(APIView): user.is_password_autoset = False user.save() # Login the user as the session is invalidated - user_login(user=user, request=request) + user_login(user=user, request=request, is_app=True) # Return the user serializer = UserSerializer(user) return Response(serializer.data, status=status.HTTP_200_OK) diff --git a/apiserver/plane/authentication/views/space/email.py b/apiserver/plane/authentication/views/space/email.py index 4505332ebe..e11ab29b51 100644 --- a/apiserver/plane/authentication/views/space/email.py +++ b/apiserver/plane/authentication/views/space/email.py @@ -38,7 +38,7 @@ class SignInAuthSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "accounts/sign-in?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -60,7 +60,7 @@ class SignInAuthSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "spaces/accounts/sign-in?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -79,7 +79,7 @@ class SignInAuthSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "spaces/accounts/sign-in?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -94,7 +94,7 @@ class SignInAuthSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "spaces/accounts/sign-in?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -104,11 +104,11 @@ class SignInAuthSpaceEndpoint(View): ) user = provider.authenticate() # Login the user and record his device info - user_login(request=request, user=user) + user_login(request=request, user=user, is_space=True) # redirect to next path url = urljoin( base_host(request=request, is_space=True), - str(next_path) if next_path else "/", + str(next_path) if next_path else "", ) return HttpResponseRedirect(url) except AuthenticationException as e: @@ -117,7 +117,7 @@ class SignInAuthSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "spaces/accounts/sign-in?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -141,7 +141,7 @@ class SignUpAuthSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "spaces?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -162,7 +162,7 @@ class SignUpAuthSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "spaces?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) # Validate the email @@ -181,7 +181,7 @@ class SignUpAuthSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "spaces?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -196,7 +196,7 @@ class SignUpAuthSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "spaces?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -206,11 +206,11 @@ class SignUpAuthSpaceEndpoint(View): ) user = provider.authenticate() # Login the user and record his device info - user_login(request=request, user=user) + user_login(request=request, user=user, is_space=True) # redirect to referer path url = urljoin( base_host(request=request, is_space=True), - str(next_path) if next_path else "spaces", + str(next_path) if next_path else "", ) return HttpResponseRedirect(url) except AuthenticationException as e: @@ -219,6 +219,6 @@ class SignUpAuthSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "spaces?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) diff --git a/apiserver/plane/authentication/views/space/github.py b/apiserver/plane/authentication/views/space/github.py index 4a0f230984..8430cbdfb0 100644 --- a/apiserver/plane/authentication/views/space/github.py +++ b/apiserver/plane/authentication/views/space/github.py @@ -55,7 +55,7 @@ class GitHubOauthInitiateSpaceEndpoint(View): if next_path: params["next_path"] = str(next_path) url = urljoin( - base_host(request=request), + base_host(request=request, is_space=True), "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -108,10 +108,10 @@ class GitHubCallbackSpaceEndpoint(View): ) user = provider.authenticate() # Login the user and record his device info - user_login(request=request, user=user) + user_login(request=request, user=user, is_space=True) # Process workspace and project invitations # redirect to referer path - url = urljoin(base_host, str(next_path) if next_path else "/") + url = urljoin(base_host, str(next_path) if next_path else "") return HttpResponseRedirect(url) except AuthenticationException as e: params = e.get_error_dict() diff --git a/apiserver/plane/authentication/views/space/google.py b/apiserver/plane/authentication/views/space/google.py index 2f6b576993..502f146c31 100644 --- a/apiserver/plane/authentication/views/space/google.py +++ b/apiserver/plane/authentication/views/space/google.py @@ -103,7 +103,7 @@ class GoogleCallbackSpaceEndpoint(View): ) user = provider.authenticate() # Login the user and record his device info - user_login(request=request, user=user) + user_login(request=request, user=user, is_space=True) # redirect to referer path url = urljoin( base_host, str(next_path) if next_path else "/spaces" diff --git a/apiserver/plane/authentication/views/space/magic.py b/apiserver/plane/authentication/views/space/magic.py index 52771f71b9..45a8e37550 100644 --- a/apiserver/plane/authentication/views/space/magic.py +++ b/apiserver/plane/authentication/views/space/magic.py @@ -86,7 +86,7 @@ class MagicSignInSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "spaces/accounts/sign-in?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -99,7 +99,7 @@ class MagicSignInSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "accounts/sign-in?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -109,14 +109,14 @@ class MagicSignInSpaceEndpoint(View): ) user = provider.authenticate() # Login the user and record his device info - user_login(request=request, user=user) + user_login(request=request, user=user, is_space=True) # redirect to referer path profile = Profile.objects.get(user=user) if user.is_password_autoset and profile.is_onboarded: - path = "spaces/accounts/set-password" + path = "accounts/set-password" else: # Get the redirection path - path = str(next_path) if next_path else "spaces" + path = str(next_path) if next_path else "" url = urljoin(base_host(request=request, is_space=True), path) return HttpResponseRedirect(url) @@ -126,7 +126,7 @@ class MagicSignInSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "spaces/accounts/sign-in?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -152,7 +152,7 @@ class MagicSignUpSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "spaces/accounts/sign-in?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) @@ -176,7 +176,7 @@ class MagicSignUpSpaceEndpoint(View): ) user = provider.authenticate() # Login the user and record his device info - user_login(request=request, user=user) + user_login(request=request, user=user, is_space=True) # redirect to referer path url = urljoin( base_host(request=request, is_space=True), @@ -190,6 +190,6 @@ class MagicSignUpSpaceEndpoint(View): params["next_path"] = str(next_path) url = urljoin( base_host(request=request, is_space=True), - "spaces/accounts/sign-in?" + urlencode(params), + "?" + urlencode(params), ) return HttpResponseRedirect(url) diff --git a/apiserver/plane/authentication/views/space/password_management.py b/apiserver/plane/authentication/views/space/password_management.py index aeac9776d1..5263c89566 100644 --- a/apiserver/plane/authentication/views/space/password_management.py +++ b/apiserver/plane/authentication/views/space/password_management.py @@ -183,11 +183,9 @@ class ResetPasswordSpaceEndpoint(View): user.is_password_autoset = False user.save() - url = urljoin( - base_host(request=request, is_space=True), - "accounts/sign-in?" + urlencode({"success": True}), + return HttpResponseRedirect( + base_host(request=request, is_space=True) ) - return HttpResponseRedirect(url) except DjangoUnicodeDecodeError: exc = AuthenticationException( error_code=AUTHENTICATION_ERROR_CODES[ diff --git a/apiserver/plane/authentication/views/space/signout.py b/apiserver/plane/authentication/views/space/signout.py index 3cfd6d4711..655d8b1c8c 100644 --- a/apiserver/plane/authentication/views/space/signout.py +++ b/apiserver/plane/authentication/views/space/signout.py @@ -23,12 +23,10 @@ class SignOutAuthSpaceEndpoint(View): user.save() # Log the user out logout(request) - url = urljoin( - base_host(request=request, is_space=True), - "accounts/sign-in?" + urlencode({"success": "true"}), + return HttpResponseRedirect( + base_host(request=request, is_space=True) ) - return HttpResponseRedirect(url) except Exception: return HttpResponseRedirect( - base_host(request=request, is_space=True), "accounts/sign-in" + base_host(request=request, is_space=True) ) diff --git a/apiserver/plane/license/api/views/admin.py b/apiserver/plane/license/api/views/admin.py index ed3c00f17a..945f4b1b17 100644 --- a/apiserver/plane/license/api/views/admin.py +++ b/apiserver/plane/license/api/views/admin.py @@ -107,7 +107,7 @@ class InstanceAdminSignUpEndpoint(View): ) url = urljoin( base_host(request=request, is_admin=True), - "god-mode/setup?" + urlencode(exc.get_error_dict()), + "setup?" + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) @@ -119,7 +119,7 @@ class InstanceAdminSignUpEndpoint(View): ) url = urljoin( base_host(request=request, is_admin=True), - "god-mode/setup?" + urlencode(exc.get_error_dict()), + "setup?" + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) @@ -148,7 +148,7 @@ class InstanceAdminSignUpEndpoint(View): ) url = urljoin( base_host(request=request, is_admin=True), - "god-mode/setup?" + urlencode(exc.get_error_dict()), + "setup?" + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) @@ -170,7 +170,7 @@ class InstanceAdminSignUpEndpoint(View): ) url = urljoin( base_host(request=request, is_admin=True), - "god-mode/setup?" + urlencode(exc.get_error_dict()), + "setup?" + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) @@ -192,7 +192,7 @@ class InstanceAdminSignUpEndpoint(View): ) url = urljoin( base_host(request=request, is_admin=True), - "god-mode/setup?" + urlencode(exc.get_error_dict()), + "setup?" + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) else: @@ -214,7 +214,7 @@ class InstanceAdminSignUpEndpoint(View): ) url = urljoin( base_host(request=request, is_admin=True), - "god-mode/setup?" + urlencode(exc.get_error_dict()), + "setup?" + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) @@ -247,10 +247,8 @@ class InstanceAdminSignUpEndpoint(View): instance.save() # get tokens for user - user_login(request=request, user=user) - url = urljoin( - base_host(request=request, is_admin=True), "god-mode/general" - ) + user_login(request=request, user=user, is_admin=True) + url = urljoin(base_host(request=request, is_admin=True), "general") return HttpResponseRedirect(url) @@ -272,7 +270,7 @@ class InstanceAdminSignInEndpoint(View): ) url = urljoin( base_host(request=request, is_admin=True), - "god-mode/login?" + urlencode(exc.get_error_dict()), + "?" + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) @@ -293,7 +291,7 @@ class InstanceAdminSignInEndpoint(View): ) url = urljoin( base_host(request=request, is_admin=True), - "god-mode/login?" + urlencode(exc.get_error_dict()), + "?" + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) @@ -311,7 +309,7 @@ class InstanceAdminSignInEndpoint(View): ) url = urljoin( base_host(request=request, is_admin=True), - "god-mode/login?" + urlencode(exc.get_error_dict()), + "?" + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) @@ -331,7 +329,7 @@ class InstanceAdminSignInEndpoint(View): ) url = urljoin( base_host(request=request, is_admin=True), - "god-mode/login?" + urlencode(exc.get_error_dict()), + "?" + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) @@ -348,7 +346,7 @@ class InstanceAdminSignInEndpoint(View): ) url = urljoin( base_host(request=request, is_admin=True), - "god-mode/login?" + urlencode(exc.get_error_dict()), + "?" + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) @@ -365,7 +363,7 @@ class InstanceAdminSignInEndpoint(View): ) url = urljoin( base_host(request=request, is_admin=True), - "god-mode/login?" + urlencode(exc.get_error_dict()), + "?" + urlencode(exc.get_error_dict()), ) return HttpResponseRedirect(url) # settings last active for the user @@ -378,10 +376,8 @@ class InstanceAdminSignInEndpoint(View): user.save() # get tokens for user - user_login(request=request, user=user) - url = urljoin( - base_host(request=request, is_admin=True), "god-mode/general" - ) + user_login(request=request, user=user, is_admin=True) + url = urljoin(base_host(request=request, is_admin=True), "general") return HttpResponseRedirect(url) @@ -414,12 +410,9 @@ class InstanceAdminSignOutEndpoint(View): user.save() # Log the user out logout(request) - url = urljoin( - base_host(request=request, is_admin=True), - "accounts/sign-in?" + urlencode({"success": "true"}), - ) + url = urljoin(base_host(request=request, is_admin=True)) return HttpResponseRedirect(url) except Exception: return HttpResponseRedirect( - base_host(request=request, is_admin=True), "accounts/sign-in" + base_host(request=request, is_admin=True) ) diff --git a/apiserver/plane/settings/common.py b/apiserver/plane/settings/common.py index 4f5e6d4eef..f043340a29 100644 --- a/apiserver/plane/settings/common.py +++ b/apiserver/plane/settings/common.py @@ -346,4 +346,4 @@ CSRF_COOKIE_DOMAIN = os.environ.get("COOKIE_DOMAIN", None) # Base URLs ADMIN_BASE_URL = os.environ.get("ADMIN_BASE_URL", None) SPACE_BASE_URL = os.environ.get("SPACE_BASE_URL", None) -APP_BASE_URL = os.environ.get("ADMIN_BASE_URL", None) +APP_BASE_URL = os.environ.get("APP_BASE_URL") or os.environ.get("WEB_URL") diff --git a/apiserver/plane/settings/local.py b/apiserver/plane/settings/local.py index 2290262aef..b96d1ca31b 100644 --- a/apiserver/plane/settings/local.py +++ b/apiserver/plane/settings/local.py @@ -35,10 +35,10 @@ CORS_ALLOWED_ORIGINS = [ "http://127.0.0.1", "http://localhost:3000", "http://127.0.0.1:3000", - "http://localhost:4000", - "http://127.0.0.1:4000", - "http://localhost:3333", - "http://127.0.0.1:3333", + "http://localhost:3001", + "http://127.0.0.1:3001", + "http://localhost:3002", + "http://127.0.0.1:3002", ] CSRF_TRUSTED_ORIGINS = CORS_ALLOWED_ORIGINS CORS_ALLOW_ALL_ORIGINS = True diff --git a/apiserver/plane/settings/production.py b/apiserver/plane/settings/production.py index c56222c67e..806f83aca7 100644 --- a/apiserver/plane/settings/production.py +++ b/apiserver/plane/settings/production.py @@ -12,8 +12,6 @@ SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") INSTALLED_APPS += ("scout_apm.django",) # noqa -# Honor the 'X-Forwarded-Proto' header for request.is_secure() -SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") # Scout Settings SCOUT_MONITOR = os.environ.get("SCOUT_MONITOR", False) diff --git a/apiserver/runtime.txt b/apiserver/runtime.txt index cd0aac5427..8cf46af5fc 100644 --- a/apiserver/runtime.txt +++ b/apiserver/runtime.txt @@ -1 +1 @@ -python-3.11.9 \ No newline at end of file +python-3.12.3 \ No newline at end of file diff --git a/space/components/accounts/onboarding-form.tsx b/space/components/accounts/onboarding-form.tsx index 7a719d9385..768d5160fc 100644 --- a/space/components/accounts/onboarding-form.tsx +++ b/space/components/accounts/onboarding-form.tsx @@ -140,8 +140,11 @@ export const OnBoardingForm: React.FC = observer((props) => {
-
-