mirror of
https://github.com/makeplane/plane.git
synced 2026-02-25 04:35:21 +01:00
Sync: Community Changes #4267
This commit is contained in:
@@ -72,7 +72,7 @@ export const ProjectAutomationDetailsHeader = observer((props: TProps) => {
|
||||
.then(() => {
|
||||
captureSuccess({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.ENABLE,
|
||||
payload: { id: automationId }
|
||||
payload: { id: automationId },
|
||||
});
|
||||
setToast({
|
||||
title: t("automations.toasts.enable.success.title"),
|
||||
@@ -85,7 +85,7 @@ export const ProjectAutomationDetailsHeader = observer((props: TProps) => {
|
||||
captureError({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.ENABLE,
|
||||
error: err?.message || "Enable failed",
|
||||
payload: { id: automationId }
|
||||
payload: { id: automationId },
|
||||
});
|
||||
setToast({
|
||||
title: t("automations.toasts.enable.error.title"),
|
||||
@@ -101,7 +101,7 @@ export const ProjectAutomationDetailsHeader = observer((props: TProps) => {
|
||||
.then(() => {
|
||||
captureSuccess({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.DISABLE,
|
||||
payload: { id: automationId }
|
||||
payload: { id: automationId },
|
||||
});
|
||||
setToast({
|
||||
title: t("automations.toasts.disable.success.title"),
|
||||
@@ -114,7 +114,7 @@ export const ProjectAutomationDetailsHeader = observer((props: TProps) => {
|
||||
captureError({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.DISABLE,
|
||||
error: err?.message || "Disable failed",
|
||||
payload: { id: automationId }
|
||||
payload: { id: automationId },
|
||||
});
|
||||
setToast({
|
||||
title: t("automations.toasts.disable.error.title"),
|
||||
|
||||
@@ -15,7 +15,7 @@ import { useMember } from "@/hooks/store/use-member";
|
||||
import { useUserProfile } from "@/hooks/store/use-user-profile";
|
||||
// plane web hooks
|
||||
import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
|
||||
// plane web services
|
||||
// plane web service
|
||||
import { WorkspaceService } from "@/plane-web/services";
|
||||
import { LiteToolbar } from "./lite-toolbar";
|
||||
const workspaceService = new WorkspaceService();
|
||||
|
||||
@@ -3,7 +3,12 @@ import isEqual from "lodash/isEqual";
|
||||
import { observer } from "mobx-react";
|
||||
import { ChevronDown, Zap } from "lucide-react";
|
||||
// plane imports
|
||||
import { AUTOMATION_TRIGGER_SELECT_OPTIONS, DEFAULT_AUTOMATION_CONDITION_FILTER_EXPRESSION, AUTOMATION_TRACKER_ELEMENTS, AUTOMATION_TRACKER_EVENTS } from "@plane/constants";
|
||||
import {
|
||||
AUTOMATION_TRIGGER_SELECT_OPTIONS,
|
||||
DEFAULT_AUTOMATION_CONDITION_FILTER_EXPRESSION,
|
||||
AUTOMATION_TRACKER_ELEMENTS,
|
||||
AUTOMATION_TRACKER_EVENTS,
|
||||
} from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
// helpers
|
||||
import {
|
||||
@@ -82,13 +87,13 @@ export const AutomationDetailsSidebarTriggerRoot: React.FC<Props> = observer((pr
|
||||
});
|
||||
captureSuccess({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.TRIGGER_CREATED,
|
||||
payload: { id: automationId, handler_name: selectedTriggerNodeHandlerName }
|
||||
payload: { id: automationId, handler_name: selectedTriggerNodeHandlerName },
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to create trigger:", error);
|
||||
captureError({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.TRIGGER_CREATED,
|
||||
payload: { id: automationId, handler_name: selectedTriggerNodeHandlerName }
|
||||
payload: { id: automationId, handler_name: selectedTriggerNodeHandlerName },
|
||||
});
|
||||
}
|
||||
return;
|
||||
@@ -102,13 +107,13 @@ export const AutomationDetailsSidebarTriggerRoot: React.FC<Props> = observer((pr
|
||||
});
|
||||
captureSuccess({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.TRIGGER_UPDATED,
|
||||
payload: { id: automationId, handler_name: selectedTriggerNodeHandlerName }
|
||||
payload: { id: automationId, handler_name: selectedTriggerNodeHandlerName },
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to update trigger handler:", error);
|
||||
captureError({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.TRIGGER_UPDATED,
|
||||
payload: { id: automationId, handler_name: selectedTriggerNodeHandlerName }
|
||||
payload: { id: automationId, handler_name: selectedTriggerNodeHandlerName },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ export const CreateUpdateAutomationModal: React.FC<Props> = observer((props) =>
|
||||
const res = await createAutomation(workspaceSlug, projectId, payload);
|
||||
captureSuccess({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.CREATE,
|
||||
payload: { id: res?.id }
|
||||
payload: { id: res?.id },
|
||||
});
|
||||
if (res?.redirectionLink) {
|
||||
router.push(res?.redirectionLink);
|
||||
@@ -72,7 +72,7 @@ export const CreateUpdateAutomationModal: React.FC<Props> = observer((props) =>
|
||||
captureError({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.CREATE,
|
||||
error: error?.error || error?.message,
|
||||
payload: { workspace_slug: workspaceSlug, project_id: projectId }
|
||||
payload: { workspace_slug: workspaceSlug, project_id: projectId },
|
||||
});
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
@@ -89,13 +89,13 @@ export const CreateUpdateAutomationModal: React.FC<Props> = observer((props) =>
|
||||
await automation?.update(payload);
|
||||
captureSuccess({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.UPDATE,
|
||||
payload: { id: data.id }
|
||||
payload: { id: data.id },
|
||||
});
|
||||
} catch (error: any) {
|
||||
captureError({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.UPDATE,
|
||||
error: error?.error || error?.message,
|
||||
payload: { id: data.id }
|
||||
payload: { id: data.id },
|
||||
});
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
|
||||
@@ -41,7 +41,7 @@ export const DeleteAutomationModal: React.FC<Props> = observer((props) => {
|
||||
await handleDelete();
|
||||
captureSuccess({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.DELETE,
|
||||
payload: { id: automationId }
|
||||
payload: { id: automationId },
|
||||
});
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
@@ -55,7 +55,7 @@ export const DeleteAutomationModal: React.FC<Props> = observer((props) => {
|
||||
captureError({
|
||||
eventName: AUTOMATION_TRACKER_EVENTS.DELETE,
|
||||
error: error?.message || "Delete failed",
|
||||
payload: { id: automationId }
|
||||
payload: { id: automationId },
|
||||
});
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
|
||||
@@ -1293,7 +1293,8 @@ input[type="color"].custom-color-picker {
|
||||
}
|
||||
|
||||
@keyframes grow-shrink-vertically {
|
||||
0%, 100% {
|
||||
0%,
|
||||
100% {
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
50% {
|
||||
@@ -1301,7 +1302,6 @@ input[type="color"].custom-color-picker {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.animate-vertical-scale {
|
||||
transform-origin: center; /* ensures it grows from both ends */
|
||||
animation: grow-shrink-vertically 0.8s ease-in-out infinite;
|
||||
@@ -1373,41 +1373,33 @@ input[type="color"].custom-color-picker {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.shimmer {
|
||||
display: inline-block;
|
||||
background-color: rgb(var(--color-text-100));
|
||||
background-image: linear-gradient(
|
||||
to left,
|
||||
transparent 0%,
|
||||
rgb(var(--color-text-400)) 50%,
|
||||
transparent 100%
|
||||
);
|
||||
background-image: linear-gradient(to left, transparent 0%, rgb(var(--color-text-400)) 50%, transparent 100%);
|
||||
background-position: -4rem top;
|
||||
background-repeat: no-repeat;
|
||||
background-clip: text; /* non-prefixed fallback */
|
||||
-webkit-background-clip: text; /* required for Safari/WebKit */
|
||||
background-clip: text; /* non-prefixed fallback */
|
||||
-webkit-background-clip: text; /* required for Safari/WebKit */
|
||||
-webkit-text-fill-color: transparent;
|
||||
|
||||
-webkit-animation: shimmer-ltr 2.2s linear infinite;
|
||||
animation: shimmer-ltr 2.2s linear infinite;
|
||||
|
||||
-webkit-background-size: 60% 100%;
|
||||
background-size: 60% 100%; /* unprefixed too */
|
||||
background-size: 60% 100%; /* unprefixed too */
|
||||
}
|
||||
|
||||
@keyframes shimmer-ltr {
|
||||
0% {
|
||||
background-position: -4rem top; /*50px*/
|
||||
}
|
||||
0% {
|
||||
background-position: -4rem top; /*50px*/
|
||||
}
|
||||
|
||||
70% {
|
||||
background-position: 200% top; /*200px*/
|
||||
}
|
||||
70% {
|
||||
background-position: 200% top; /*200px*/
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 200% top; /*200px*/
|
||||
}
|
||||
}
|
||||
100% {
|
||||
background-position: 200% top; /*200px*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { forwardRef, useCallback } from "react";
|
||||
// components
|
||||
import { EditorWrapper } from "@/components/editors";
|
||||
import { EditorBubbleMenu } from "@/components/menus";
|
||||
import { BlockMenu, EditorBubbleMenu } from "@/components/menus";
|
||||
// extensions
|
||||
import { SideMenuExtension } from "@/extensions";
|
||||
// plane editor imports
|
||||
@@ -40,7 +40,12 @@ const RichTextEditor: React.FC<IRichTextEditorProps> = (props) => {
|
||||
|
||||
return (
|
||||
<EditorWrapper {...props} extensions={getExtensions()}>
|
||||
{(editor) => <>{editor && bubbleMenuEnabled && <EditorBubbleMenu editor={editor} />}</>}
|
||||
{(editor) => (
|
||||
<>
|
||||
{editor && bubbleMenuEnabled && <EditorBubbleMenu editor={editor} />}
|
||||
<BlockMenu editor={editor} flaggedExtensions={flaggedExtensions} disabledExtensions={disabledExtensions} />
|
||||
</>
|
||||
)}
|
||||
</EditorWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -91,6 +91,15 @@ export const BlockMenu = (props: Props) => {
|
||||
// Set the virtual reference as the reference element
|
||||
refs.setReference(virtualReferenceRef.current);
|
||||
|
||||
// Ensure the targeted block is selected
|
||||
const rect = dragHandle.getBoundingClientRect();
|
||||
const coords = { left: rect.left + rect.width / 2, top: rect.top + rect.height / 2 };
|
||||
const posAtCoords = editor.view.posAtCoords(coords);
|
||||
if (posAtCoords) {
|
||||
const $pos = editor.state.doc.resolve(posAtCoords.pos);
|
||||
const nodePos = $pos.before($pos.depth);
|
||||
editor.chain().setNodeSelection(nodePos).run();
|
||||
}
|
||||
// Show the menu
|
||||
setIsOpen(true);
|
||||
return;
|
||||
@@ -101,7 +110,7 @@ export const BlockMenu = (props: Props) => {
|
||||
setIsOpen(false);
|
||||
}
|
||||
},
|
||||
[refs]
|
||||
[editor, refs]
|
||||
);
|
||||
|
||||
const editorState = useEditorState({
|
||||
@@ -296,6 +305,11 @@ export const BlockMenu = (props: Props) => {
|
||||
setIsOpen(false);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
// Execute the delete action
|
||||
editor.chain().deleteSelection().focus().run();
|
||||
|
||||
setIsOpen(false);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -363,7 +377,6 @@ export const BlockMenu = (props: Props) => {
|
||||
if (!isOpen) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<FloatingPortal>
|
||||
<div
|
||||
@@ -373,6 +386,7 @@ export const BlockMenu = (props: Props) => {
|
||||
}}
|
||||
style={{
|
||||
...floatingStyles,
|
||||
zIndex: 99,
|
||||
animationFillMode: "forwards",
|
||||
transitionTimingFunction: "cubic-bezier(0.16, 1, 0.3, 1)", // Expo ease out
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user