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/Dockerfile.admin b/admin/Dockerfile.admin index 901c39e27d..b2908f356c 100644 --- a/admin/Dockerfile.admin +++ b/admin/Dockerfile.admin @@ -32,7 +32,7 @@ ENV NEXT_PUBLIC_API_BASE_URL=$NEXT_PUBLIC_API_BASE_URL ARG NEXT_PUBLIC_WEB_BASE_URL="" ENV NEXT_PUBLIC_WEB_BASE_URL=$NEXT_PUBLIC_WEB_BASE_URL -ARG NEXT_PUBLIC_SPACE_BASE_URL="" +ARG NEXT_PUBLIC_SPACE_BASE_URL="/spaces" ENV NEXT_PUBLIC_SPACE_BASE_URL=$NEXT_PUBLIC_SPACE_BASE_URL ARG NEXT_PUBLIC_ADMIN_BASE_PATH="/god-mode" @@ -62,7 +62,7 @@ ENV NEXT_PUBLIC_API_BASE_URL=$NEXT_PUBLIC_API_BASE_URL ARG NEXT_PUBLIC_WEB_BASE_URL="" ENV NEXT_PUBLIC_WEB_BASE_URL=$NEXT_PUBLIC_WEB_BASE_URL -ARG NEXT_PUBLIC_SPACE_BASE_URL="" +ARG NEXT_PUBLIC_SPACE_BASE_URL="/spaces" ENV NEXT_PUBLIC_SPACE_BASE_URL=$NEXT_PUBLIC_SPACE_BASE_URL ARG NEXT_PUBLIC_ADMIN_BASE_PATH="/god-mode" 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 ( - -
-{description}
} +tag that is the first child of a td or th + if ( + (elem.matches("td > p:first-child") || elem.matches("th > p:first-child")) && + elem?.textContent?.trim() !== "" + ) { + return elem; // Return only if p tag is not empty + } + // apply general selector + if (elem.matches(generalSelectors)) { + return elem; + } + } + return null; } function nodePosAtDOM(node: Element, view: EditorView, options: DragHandleOptions) { @@ -86,15 +109,19 @@ function nodePosAtDOMForBlockquotes(node: Element, view: EditorView) { })?.inside; } -function calcNodePos(pos: number, view: EditorView) { +function calcNodePos(pos: number, view: EditorView, node: Element) { const maxPos = view.state.doc.content.size; const safePos = Math.max(0, Math.min(pos, maxPos)); const $pos = view.state.doc.resolve(safePos); if ($pos.depth > 1) { - const newPos = $pos.before($pos.depth); - return Math.max(0, Math.min(newPos, maxPos)); + if (node.matches("ul:not([data-type=taskList]) li, ol li")) { + // only for nested lists + const newPos = $pos.before($pos.depth); + return Math.max(0, Math.min(newPos, maxPos)); + } } + return safePos; } @@ -114,12 +141,12 @@ function DragHandle(options: DragHandleOptions) { let draggedNodePos = nodePosAtDOM(node, view, options); if (draggedNodePos == null || draggedNodePos < 0) return; - draggedNodePos = calcNodePos(draggedNodePos, view); + draggedNodePos = calcNodePos(draggedNodePos, view, node); const { from, to } = view.state.selection; const diff = from - to; - const fromSelectionPos = calcNodePos(from, view); + const fromSelectionPos = calcNodePos(from, view, node); let differentNodeSelected = false; const nodePos = view.state.doc.resolve(fromSelectionPos); @@ -148,6 +175,19 @@ function DragHandle(options: DragHandleOptions) { listType = node.parentElement!.tagName; } + if (node.matches("blockquote")) { + let nodePosForBlockquotes = nodePosAtDOMForBlockquotes(node, view); + if (nodePosForBlockquotes === null || nodePosForBlockquotes === undefined) return; + + const docSize = view.state.doc.content.size; + nodePosForBlockquotes = Math.max(0, Math.min(nodePosForBlockquotes, docSize)); + + if (nodePosForBlockquotes >= 0 && nodePosForBlockquotes <= docSize) { + const nodeSelection = NodeSelection.create(view.state.doc, nodePosForBlockquotes); + view.dispatch(view.state.tr.setSelection(nodeSelection)); + } + } + const slice = view.state.selection.content(); const { dom, text } = __serializeForClipboard(view, slice); @@ -190,7 +230,7 @@ function DragHandle(options: DragHandleOptions) { if (nodePos === null || nodePos === undefined) return; // Adjust the nodePos to point to the start of the node, ensuring NodeSelection can be applied - nodePos = calcNodePos(nodePos, view); + nodePos = calcNodePos(nodePos, view, node); // Use NodeSelection to select the node at the calculated position const nodeSelection = NodeSelection.create(view.state.doc, nodePos); @@ -279,9 +319,11 @@ function DragHandle(options: DragHandleOptions) { // Li markers if (node.matches("ul:not([data-type=taskList]) li, ol li")) { - rect.top += 4; rect.left -= 18; } + if (node.matches(".table-wrapper")) { + rect.top += 8; + } rect.width = options.dragHandleWidth; @@ -352,18 +394,3 @@ function DragHandle(options: DragHandleOptions) { }, }); } - -export const DragAndDrop = (setHideDragHandle?: (hideDragHandlerFromDragDrop: () => void) => void) => - Extension.create({ - name: "dragAndDrop", - - addProseMirrorPlugins() { - return [ - DragHandle({ - dragHandleWidth: 24, - scrollThreshold: { up: 300, down: 100 }, - setHideDragHandle, - }), - ]; - }, - }); diff --git a/packages/editor/extensions/src/extensions/slash-commands.tsx b/packages/editor/extensions/src/extensions/slash-commands.tsx index 752fbe63cb..c1b1ef9c04 100644 --- a/packages/editor/extensions/src/extensions/slash-commands.tsx +++ b/packages/editor/extensions/src/extensions/slash-commands.tsx @@ -315,7 +315,10 @@ const CommandList = ({ items, command }: { items: CommandItemProps[]; command: a "bg-custom-background-80": index === selectedIndex, } )} - onClick={() => selectItem(index)} + onClick={(e) => { + e.stopPropagation(); + selectItem(index); + }} > {item.icon}
{item.title}
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