10000 Context values dnd by JulianWielga · Pull Request #8279 · TouK/nussknacker · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Context values dnd #8279

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
249 changes: 249 additions & 0 deletions designer/client/package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion designer/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
"@fontsource/inter": "5.0.16",
"@fontsource/roboto-mono": "4.5.8",
"@frsource/cypress-plugin-visual-regression-diff": "3.2.3",
"@microlink/react-json-view": "1.26.2",
"@pmmmwh/react-refresh-webpack-plugin": "0.5.4",
"@svgr/webpack": "8.0.1",
"@testing-library/dom": "9.3.1",
Expand Down Expand Up @@ -209,6 +210,7 @@
"postcss-move-props-to-bg-image-query": "4.0.0",
"prettier": "2.8.8",
"raw-loader": "4.0.2",
"react-json-tree": "0.20.0",
"react-refresh": "0.11.0",
"react-scrollbars-custom": "4.1.1",
"redux-mock-store": "1.5.4",
Expand Down Expand Up @@ -275,7 +277,7 @@
"start:backend-remote": "npm run clean-translations && webpack serve",
"start:backend-staging": "BACKEND_DOMAIN=https://staging.nussknacker.io npm run start:backend-remote",
"start:backend-demo": "BACKEND_DOMAIN=https://demo.nussknacker.io npm run start:backend-remote",
"start:backend-cloud": "BACKEND_DOMAIN=https://light-pink-silkworm-nussknacker.staging-cloud.nussknacker.io npm run start:backend-remote",
"start:backend-cloud": "BACKEND_DOMAIN=https://pink-snakes-nussknacker.staging-cloud.nussknacker.io npm run start:backend-remote",
"backend:docker": "docker-compose kill && docker-compose rm -f -v && docker-compose up --no-recreate > /dev/null",
"pretest": "npm run check",
"test:types": "tstyche",
Expand Down
2 changes: 0 additions & 2 deletions designer/client/src/actions/nk/editNode.ts
8000
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { getProcessDefinitionData } from "../../reducers/selectors/processDefini
import type { Edge, NodeType, ScenarioGraph, ValidationResult } from "../../types";
import type { ThunkAction } from "../reduxTypes";
import { calculateProcessAfterChange } from "./calculateProcessAfterChange";
import { clearProcessCounts } from "./displayProcessCounts";

export type EditNodeAction = {
type: "EDIT_NODE";
Expand All @@ -34,7 +33,6 @@ export function editNode(scenarioBefore: Scenario, before: NodeType, after: Node
const scenarioGraph = await dispatch(calculateProcessAfterChange(scenarioBefore, before, after, outputEdges));
const response = await HttpService.validateProcess(scenarioBefore.name, scenarioBefore.name, scenarioGraph);

dispatch(clearProcessCounts());
dispatch({
type: "EDIT_NODE",
before,
Expand Down
2 changes: 1 addition & 1 deletion designer/client/src/common/SVGUtils.ts
6D40
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ export function toXml(node: Node) {
return window.XMLSerializer ? new XMLSerializer().serializeToString(node) : xmlSerializerForIE(node);
}

export function svgTowDataURL(svgStr: string) {
export function svgToDataURL(svgStr: string) {
return `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(svgStr)))}`;
}
9 changes: 4 additions & 5 deletions designer/client/src/components/ComponentDragPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,18 @@ import { useDebouncedValue } from "rooks";
import type { NodeType } from "../types";
import type { ComponentPreviewProps } from "./ComponentPreview";
import { ComponentPreview } from "./ComponentPreview";
import { DndTypes } from "./DndTypes";
import { StickyNoteType } from "./graph/utils/stickyNotesUtils";
import { StickyNotePreview } from "./StickyNotePreview";
import { DndTypes } from "./toolbars/creator/Tool";

function useNotNull<T>(value: T) {
export function useNotNull<T>(value: T) {
const [current, setCurrent] = useState(() => value);
useEffect(() => {
if (!value) return;
setCurrent(value);
}, [value]);
return current;
}

function PreviewElement(props: ComponentPreviewProps) {
if (props.node.type === StickyNoteType) {
return <StickyNotePreview isActive={props.isActive} isOver={props.isOver} />;
Expand All @@ -34,8 +33,8 @@ export const ComponentDragPreview = forwardRef<HTMLDivElement, { scale: () => nu
const manager = useDragDropManager();
const monitor = manager.getMonitor();
const { currentOffset, active, data } = useDragLayer((monitor) => ({
data: monitor.getItem(),
active: monitor.isDragging() && monitor.getItemType() === DndTypes.ELEMENT,
data: monitor.getItemType() === DndTypes.ELEMENT && monitor.getItem(),
active: monitor.getItemType() === DndTypes.ELEMENT && monitor.isDragging(),
currentOffset: monitor.getClientOffset(),
}));

Expand Down
4 changes: 4 additions & 0 deletions designer/client/src/components/DndTypes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const DndTypes = {
ELEMENT: "element",
VALUE: "value",
};
113 changes: 113 additions & 0 deletions designer/client/src/components/ValueDragPreview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { Box, Paper, Typography } from "@mui/material";
import type { Dispatch, PropsWithChildren, SetStateAction } from "react";
import React, { createContext, forwardRef, useMemo, useState } from "react";
import { useDragDropManager, useDragLayer } from "react-dnd";
import { createPortal } from "react-dom";

import { useNotNull } from "./ComponentDragPreview";
import { DndTypes } from "./DndTypes";
import type { ExpressionLang } from "./graph/node-modal/editors/expression/types";
import { getPathString } from "./graph/node-modal/editors/expression/useAceDndTarget";
import type { SpelDndContext } from "./graph/node-modal/io/ContextTree";

export const AcceptedLangCtx = createContext<Dispatch<SetStateAction<ExpressionLang>>>(null);

function KeyPreview({ data }: { data: SpelDndContext }) {
return <>{getPathString(data?.path)}</>;
}

function ValuePreview({ data }: { data: SpelDndContext }) {
if (Array.isArray(data.value)) {
const size = data.value.length;
return (
<>
List ({size} {size === 1 ? "item" : "items"})
</>
);
}
if (typeof data.value === "object") {
const size = Object.keys(data.value).length;
return (
<>
Record ({size} {size === 1 ? "key" : "keys"})
</>
);
}
return <>{data.value}</>;
}

function KeyValuePreview({ data }: { data: SpelDndContext }) {
return (
<Paper sx={{ padding: 1.5, paddingY: 1 }} elevation={5}>
<Typography
variant={data.type === "value" ? "caption" : "subtitle2"}
sx={(theme) => ({
color: data.type === "key" ? theme.palette.info.main : "inherit",
opacity: data.type === "key" ? 1 : 0.5,
})}
>
<KeyPreview data={data} />
</Typography>
{data.type === "value" ? (
<Typography
variant="subtitle2"
sx={(theme) => ({
color: theme.palette.info.main,
})}
>
<ValuePreview data={data} />
</Typography>
) : null}
</Paper>
);
}

export const ValueDragPreview = forwardRef<HTMLDivElement, PropsWithChildren>(function ValueDragPreview({ children }, forwardedRef) {
const manager = useDragDropManager();
const monitor = manager.getMonitor();
const targetIds = monitor.getTargetIds();

const [_acceptedLang, setAcceptedLang] = useState<ExpressionLang>(null);
const acceptedLang = useMemo(() => {
const isOver = targetIds.some((id) => monitor.isOverTarget(id) && monitor.canDropOnTarget(id));
if (isOver) {
return _acceptedLang;
}
return null;
}, [_acceptedLang, monitor, targetIds]);

const { currentOffset, active, data } = useDragLayer((monitor) => ({
data: monitor.getItemType() === DndTypes.VALUE && (monitor.getItem() as SpelDndContext),
active: monitor.isDragging() && monitor.getItemType() === DndTypes.VALUE,
currentOffset: monitor.getClientOffset(),
}));

const { x = 0, y = 0 } = useNotNull(currentOffset) || {};

const portal = createPortal(
<Box
ref={forwardedRef}
sx={{
display: active && data && !acceptedLang ? "block" : "none",
position: "fixed",
top: 0,
left: 0,
zIndex: 1000000,
pointerEvents: "none",
userSelect: "none",
transformOrigin: "top left",
willChange: "transform",
}}
style={{ transform: `translate(${x}px, ${y}px)` }}
>
<KeyValuePreview data={data} />
</Box>,
document.body,
);
return (
<>
<AcceptedLangCtx.Provider value={setAcceptedLang}>{children}</AcceptedLangCtx.Provider>
{portal}
</>
);
});
2 changes: 1 addition & 1 deletion designer/client/src/components/graph/ProcessGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import { fetchScenarios, getScenariosNames } from "../../reducers/scenarios";
import { getLayout, getProcessCounts, getScenario } from "../../reducers/selectors/graph";
import type { Capabilities } from "../../reducers/selectors/other";
import type { NodeType } from "../../types";
import { DndTypes } from "../DndTypes";
import type { Scenario } from "../Process/types";
import { DndTypes } from "../toolbars/creator/Tool";
import { jsonToFileInFormData } from "./createFragment";
import { RECT_HEIGHT, RECT_WIDTH } from "./EspNode/esp";
import type { Graph } from "./Graph";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-disable i18next/no-literal-string */
import { GlobalStyles } from "@mui/material";
import { throttle } from "lodash";
import type { ForwardedRef } from "react";
import React, { forwardRef, useEffect, useMemo, useRef } from "react";
Expand All @@ -9,6 +10,7 @@ import { useUserSettings } from "../../../../../common/userSettings";
import type { UserSettings } from "../../../../../reducers/userSettings";
import type { AceKeyCommand, AceWrapperProps } from "./AceWrapper";
import AceWrapper from "./AceWrapper";
import { useAceDndTarget } from "./useAceDndTarget";

export default forwardRef(function AceWithSettings(
props: Omit<AceWrapperProps, "noWrap" | "showLines">,
Expand Down Expand Up @@ -64,13 +66,31 @@ export default forwardRef(function AceWithSettings(

const mergedRefs = useMergeRefs(editorRef, ref);

const { isOver } = useAceDndTarget(editorRef, props.inputProps.language);

return (
<AceWrapper
{...props}
ref={mergedRefs}
commands={commands}
showLineNumbers={userSettings[showLinesName]}
wrapEnabled={!userSettings[noWrapName]}
/>
<>
{isOver ? (
<GlobalStyles
styles={(theme) => ({
".ace_ghost_text": {
color: theme.palette.info.main,
fontStyle: "normal",
opacity: 1,
borderBottom: "2px dashed",
},
})}
/>
) : null}

<AceWrapper
{...props}
inputProps={{ ...props.inputProps, placeholder: isOver ? null : props.inputProps.placeholder }}
ref={mergedRefs}
commands={commands}
showLineNumbers={userSettings[showLinesName]}
wrapEnabled={!userSettings[noWrapName]}
/>
</>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import type { Ace } from "ace-builds";
import { trimStart } from "lodash";
import type { ForwardedRef, ReactNode } from "react";
import React, { forwardRef, useMemo } from "react";
import type { IAceEditorProps } from "react-ace/lib/ace";
import type ReactAce from "react-ace/lib/ace";
import type { IAceEditorProps } from "react-ace/lib/ace";
import type { ICommand } from "react-ace/lib/types";
import type { IAceOptions, IEditorProps } from "react-ace/src/types";

Expand All @@ -16,7 +16,7 @@ import type { EditorMode } from "./types";
import { ExpressionLang } from "./types";

export type AceWrapperInputProps = {
language: string;
language: ExpressionLang;
readOnly?: boolean;
editorMode?: EditorMode;
className?: string;
Expand Down
Loading
0