From 079a6240064203b2dd0ce552c89bbf2ba70088c2 Mon Sep 17 00:00:00 2001 From: b-saikrishnakanth <130811169+b-saikrishnakanth@users.noreply.github.com> Date: Wed, 10 Dec 2025 00:59:39 +0530 Subject: [PATCH] feat: add timezone selection to workspace settings (#8248) * feat: add timezone selection to workspace onboarding, creation and settings * refactor: remove timezone selection from workspace creation and onboarding forms --- apps/web/app/(all)/create-workspace/page.tsx | 6 +- .../onboarding/steps/workspace/create.tsx | 91 +++++++------- .../workspace/create-workspace-form.tsx | 82 ++++++------ .../workspace/settings/workspace-details.tsx | 117 +++++++++++------- packages/i18n/src/locales/cs/translations.ts | 1 + packages/i18n/src/locales/de/translations.ts | 1 + packages/i18n/src/locales/en/translations.ts | 1 + packages/i18n/src/locales/es/translations.ts | 1 + packages/i18n/src/locales/fr/translations.ts | 1 + packages/i18n/src/locales/id/translations.ts | 1 + packages/i18n/src/locales/it/translations.ts | 1 + packages/i18n/src/locales/ja/translations.ts | 1 + packages/i18n/src/locales/ko/translations.ts | 1 + packages/i18n/src/locales/pl/translations.ts | 1 + .../i18n/src/locales/pt-BR/translations.ts | 1 + packages/i18n/src/locales/ro/translations.ts | 1 + packages/i18n/src/locales/ru/translations.ts | 1 + packages/i18n/src/locales/sk/translations.ts | 1 + .../i18n/src/locales/tr-TR/translations.ts | 1 + packages/i18n/src/locales/ua/translations.ts | 1 + .../i18n/src/locales/vi-VN/translations.ts | 1 + .../i18n/src/locales/zh-CN/translations.ts | 1 + .../i18n/src/locales/zh-TW/translations.ts | 1 + packages/types/src/workspace.ts | 3 +- 24 files changed, 187 insertions(+), 131 deletions(-) diff --git a/apps/web/app/(all)/create-workspace/page.tsx b/apps/web/app/(all)/create-workspace/page.tsx index 7d8cfa82a..15ce00a16 100644 --- a/apps/web/app/(all)/create-workspace/page.tsx +++ b/apps/web/app/(all)/create-workspace/page.tsx @@ -18,7 +18,7 @@ import { AuthenticationWrapper } from "@/lib/wrappers/authentication-wrapper"; // plane web helpers import { getIsWorkspaceCreationDisabled } from "@/plane-web/helpers/instance.helper"; -function CreateWorkspacePage() { +const CreateWorkspacePage = observer(function CreateWorkspacePage() { const { t } = useTranslation(); // router const router = useAppRouter(); @@ -104,6 +104,6 @@ function CreateWorkspacePage() { ); -} +}); -export default observer(CreateWorkspacePage); +export default CreateWorkspacePage; diff --git a/apps/web/core/components/onboarding/steps/workspace/create.tsx b/apps/web/core/components/onboarding/steps/workspace/create.tsx index 949144a37..5c44923e1 100644 --- a/apps/web/core/components/onboarding/steps/workspace/create.tsx +++ b/apps/web/core/components/onboarding/steps/workspace/create.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import { useState } from "react"; import { observer } from "mobx-react"; import { Controller, useForm } from "react-hook-form"; import { CircleCheck } from "lucide-react"; @@ -71,47 +71,46 @@ export const WorkspaceCreateStep = observer(function WorkspaceCreateStep({ const handleCreateWorkspace = async (formData: IWorkspace) => { if (isSubmitting) return; - await workspaceService - .workspaceSlugCheck(formData.slug) - .then(async (res) => { - if (res.status === true && !RESTRICTED_URLS.includes(formData.slug)) { - setSlugError(false); - await createWorkspace(formData) - .then(async (workspaceResponse) => { - setToast({ - type: TOAST_TYPE.SUCCESS, - title: t("workspace_creation.toast.success.title"), - message: t("workspace_creation.toast.success.message"), - }); - captureSuccess({ - eventName: WORKSPACE_TRACKER_EVENTS.create, - payload: { slug: formData.slug }, - }); - await fetchWorkspaces(); - await completeStep(workspaceResponse.id); - onComplete(formData.organization_size === "Just myself"); - }) - .catch(() => { - captureError({ - eventName: WORKSPACE_TRACKER_EVENTS.create, - payload: { slug: formData.slug }, - error: new Error("Error creating workspace"), - }); - setToast({ - type: TOAST_TYPE.ERROR, - title: t("workspace_creation.toast.error.title"), - message: t("workspace_creation.toast.error.message"), - }); - }); - } else setSlugError(true); - }) - .catch(() => - setToast({ - type: TOAST_TYPE.ERROR, - title: t("workspace_creation.toast.error.title"), - message: t("workspace_creation.toast.error.message"), - }) - ); + try { + const res = (await workspaceService.workspaceSlugCheck(formData.slug)) as { status: boolean }; + if (res.status === true && !RESTRICTED_URLS.includes(formData.slug)) { + setSlugError(false); + try { + const workspaceResponse = await createWorkspace(formData); + setToast({ + type: TOAST_TYPE.SUCCESS, + title: t("workspace_creation.toast.success.title"), + message: t("workspace_creation.toast.success.message"), + }); + captureSuccess({ + eventName: WORKSPACE_TRACKER_EVENTS.create, + payload: { slug: formData.slug }, + }); + await fetchWorkspaces(); + await completeStep(workspaceResponse.id); + onComplete(formData.organization_size === "Just myself"); + } catch { + captureError({ + eventName: WORKSPACE_TRACKER_EVENTS.create, + payload: { slug: formData.slug }, + error: new Error("Error creating workspace"), + }); + setToast({ + type: TOAST_TYPE.ERROR, + title: t("workspace_creation.toast.error.title"), + message: t("workspace_creation.toast.error.message"), + }); + } + } else { + setSlugError(true); + } + } catch { + setToast({ + type: TOAST_TYPE.ERROR, + title: t("workspace_creation.toast.error.title"), + message: t("workspace_creation.toast.error.message"), + }); + } }; const completeStep = async (workspaceId: string) => { @@ -136,7 +135,12 @@ export const WorkspaceCreateStep = observer(function WorkspaceCreateStep({ ); } return ( -
+ { + void handleSubmit(handleCreateWorkspace)(e); + }} + >
@@ -181,6 +185,7 @@ export const WorkspaceCreateStep = observer(function WorkspaceCreateStep({ "border-red-500": errors.name, } )} + // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus />
diff --git a/apps/web/core/components/workspace/create-workspace-form.tsx b/apps/web/core/components/workspace/create-workspace-form.tsx index 4a85cd03e..028feddf8 100644 --- a/apps/web/core/components/workspace/create-workspace-form.tsx +++ b/apps/web/core/components/workspace/create-workspace-form.tsx @@ -67,47 +67,46 @@ export const CreateWorkspaceForm = observer(function CreateWorkspaceForm(props: } = useForm({ defaultValues, mode: "onChange" }); const handleCreateWorkspace = async (formData: IWorkspace) => { - await workspaceService - .workspaceSlugCheck(formData.slug) - .then(async (res) => { - if (res.status === true && !RESTRICTED_URLS.includes(formData.slug)) { - setSlugError(false); + try { + const res = (await workspaceService.workspaceSlugCheck(formData.slug)) as { status: boolean }; + if (res.status === true && !RESTRICTED_URLS.includes(formData.slug)) { + setSlugError(false); - await createWorkspace(formData) - .then(async (res) => { - captureSuccess({ - eventName: WORKSPACE_TRACKER_EVENTS.create, - payload: { slug: formData.slug }, - }); - setToast({ - type: TOAST_TYPE.SUCCESS, - title: t("workspace_creation.toast.success.title"), - message: t("workspace_creation.toast.success.message"), - }); + try { + const workspaceResponse = await createWorkspace(formData); + captureSuccess({ + eventName: WORKSPACE_TRACKER_EVENTS.create, + payload: { slug: formData.slug }, + }); + setToast({ + type: TOAST_TYPE.SUCCESS, + title: t("workspace_creation.toast.success.title"), + message: t("workspace_creation.toast.success.message"), + }); - if (onSubmit) await onSubmit(res); - }) - .catch(() => { - captureError({ - eventName: WORKSPACE_TRACKER_EVENTS.create, - payload: { slug: formData.slug }, - error: new Error("Error creating workspace"), - }); - setToast({ - type: TOAST_TYPE.ERROR, - title: t("workspace_creation.toast.error.title"), - message: t("workspace_creation.toast.error.message"), - }); - }); - } else setSlugError(true); - }) - .catch(() => { - setToast({ - type: TOAST_TYPE.ERROR, - title: t("workspace_creation.toast.error.title"), - message: t("workspace_creation.toast.error.message"), - }); + if (onSubmit) await onSubmit(workspaceResponse); + } catch { + captureError({ + eventName: WORKSPACE_TRACKER_EVENTS.create, + payload: { slug: formData.slug }, + error: new Error("Error creating workspace"), + }); + setToast({ + type: TOAST_TYPE.ERROR, + title: t("workspace_creation.toast.error.title"), + message: t("workspace_creation.toast.error.message"), + }); + } + } else { + setSlugError(true); + } + } catch { + setToast({ + type: TOAST_TYPE.ERROR, + title: t("workspace_creation.toast.error.title"), + message: t("workspace_creation.toast.error.message"), }); + } }; useEffect( @@ -119,7 +118,12 @@ export const CreateWorkspaceForm = observer(function CreateWorkspaceForm(props: ); return ( - + { + void handleSubmit(handleCreateWorkspace)(e); + }} + >
+ +
+

{t("workspace_settings.settings.general.workspace_timezone")}

+ ( + <> + + + )} + /> +
{isAdmin && ( @@ -277,7 +302,9 @@ export const WorkspaceDetails = observer(function WorkspaceDetails() {