Skip to content

Commit

Permalink
Add notifications to graph, prevent from making changes to old sticky…
Browse files Browse the repository at this point in the history
…Notes versions
  • Loading branch information
philemone committed Dec 23, 2024
1 parent e64d453 commit e134034
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 3 deletions.
8 changes: 8 additions & 0 deletions designer/client/src/actions/notificationActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";
import Notifications from "react-notification-system-redux";
import CheckCircleOutlinedIcon from "@mui/icons-material/CheckCircleOutlined";
import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
import WarningAmberOutlinedIcon from "@mui/icons-material/WarningAmberOutlined";
import Notification from "../components/notifications/Notification";
import { Action } from "./reduxTypes";

Expand All @@ -26,3 +27,10 @@ export function info(message: string): Action {
children: <Notification type={"info"} icon={<InfoOutlinedIcon />} message={message} />,
});
}

export function warn(message: string): Action {
return Notifications.warning({
autoDismiss: 10,
children: <Notification type={"warning"} icon={<WarningAmberOutlinedIcon />} message={message} />,
});
}
31 changes: 31 additions & 0 deletions designer/client/src/components/graph/Graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ import { handleGraphEvent } from "./utils/graphUtils";
import { StickyNote } from "../../common/StickyNote";
import { StickyNoteElement, StickyNoteElementView } from "./StickyNoteElement";
import { STICKY_NOTE_CONSTRAINTS } from "./EspNode/stickyNote";
import { NotificationActions } from "../../http/HttpService";
import i18next from "i18next";

function clamp(number: number, max: number) {
return Math.round(Math.min(max, Math.max(-max, number)));
Expand All @@ -65,6 +67,7 @@ type Props = GraphProps & {
theme: Theme;
translation: UseTranslationResponse<any, any>;
handleStatisticsEvent: (event: TrackEventParams) => void;
notifications: NotificationActions;
};

export const nuGraphNamespace = {
Expand Down Expand Up @@ -233,6 +236,15 @@ export class Graph extends React.Component<Props> {
}
if (isStickyNoteElement(cell.model)) {
this.processGraphPaper.hideTools();
if (!this.props.isPristine) {
this.props.notifications.warn(
i18next.t(
"notification.warn.cannotDeleteOnUnsavedVersion",
"Save scenario before making any changes to sticky notes",
),
);
return;
}
cell.showTools();
const updatedStickyNote = getStickyNoteCopyFromCell(this.props.stickyNotes, cell.model);
if (!updatedStickyNote) return;
Expand Down Expand Up @@ -382,6 +394,7 @@ export class Graph extends React.Component<Props> {
if (this.props.isFragment === true) return;
this.processGraphPaper.hideTools();
if (isStickyNoteElement(cellView.model)) {
if (!this.props.isPristine) return;
showStickyNoteTools(cellView);
}
if (this.props.nodeSelectionEnabled) {
Expand Down Expand Up @@ -469,6 +482,12 @@ export class Graph extends React.Component<Props> {

this.graph.on(Events.CELL_RESIZED, (cell: dia.Element) => {
if (isStickyNoteElement(cell)) {
if (!this.props.isPristine) {
this.props.notifications.warn(
i18next.t("notification.warn.cannotDeleteOnUnsavedVersion", "Save scenario before resizing sticky note"),
);
return;
}
const updatedStickyNote = getStickyNoteCopyFromCell(this.props.stickyNotes, cell);
if (!updatedStickyNote) return;
const position = cell.get("position");
Expand All @@ -490,6 +509,12 @@ export class Graph extends React.Component<Props> {

this.graph.on(Events.CELL_CONTENT_UPDATED, (cell: dia.Element, content: string) => {
if (isStickyNoteElement(cell)) {
if (!this.props.isPristine) {
this.props.notifications.warn(
i18next.t("notification.warn.cannotDeleteOnUnsavedVersion", "Save scenario before updating sticky note"),
);
return;
}
const updatedStickyNote = getStickyNoteCopyFromCell(this.props.stickyNotes, cell);
if (!updatedStickyNote) return;
if (updatedStickyNote.content == content) return;
Expand All @@ -500,6 +525,12 @@ export class Graph extends React.Component<Props> {

this.graph.on(Events.CELL_DELETED, (cell: dia.Element) => {
if (isStickyNoteElement(cell)) {
if (!this.props.isPristine) {
this.props.notifications.warn(
i18next.t("notification.warn.cannotDeleteOnUnsavedVersion", "Save scenario before deleting sticky note"),
);
return;
}
const noteId = Number(cell.get("noteId"));
this.deleteStickyNote(this.props.scenario.name, noteId);
}
Expand Down
8 changes: 6 additions & 2 deletions designer/client/src/components/graph/GraphWrapped.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useTheme } from "@mui/material";
import React, { forwardRef, useRef } from "react";
import { useTranslation } from "react-i18next";
import { useSelector } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { useForkRef } from "rooks";
import { useEventTracking } from "../../containers/event-tracking";
import { getProcessCategory, getSelectionState, isPristine } from "../../reducers/selectors/graph";
Expand All @@ -12,10 +12,13 @@ import { Graph } from "./Graph";
import { GraphStyledWrapper } from "./graphStyledWrapper";
import { NodeDescriptionPopover } from "./NodeDescriptionPopover";
import { GraphProps } from "./types";
import { bindActionCreators } from "redux";
import * as NotificationActions from "../../actions/notificationActions";

// Graph wrapped to make partial (for now) refactor to TS and hooks
export default forwardRef<Graph, GraphProps>(function GraphWrapped(props, forwardedRef): JSX.Element {
const { openNodeWindow } = useWindows();
const dispatch = useDispatch();
const userSettings = useSelector(getUserSettings);
const pristine = useSelector(isPristine);
const processCategory = useSelector(getProcessCategory);
Expand All @@ -25,7 +28,7 @@ export default forwardRef<Graph, GraphProps>(function GraphWrapped(props, forwar
const theme = useTheme();
const translation = useTranslation();
const { trackEvent } = useEventTracking();

const notifications = bindActionCreators(NotificationActions, dispatch);
const graphRef = useRef<Graph>();
const ref = useForkRef(graphRef, forwardedRef);

Expand All @@ -45,6 +48,7 @@ export default forwardRef<Graph, GraphProps>(function GraphWrapped(props, forwar
theme={theme}
translation={translation}
handleStatisticsEvent={trackEvent}
notifications={notifications}
/>
</GraphStyledWrapper>
<NodeDescriptionPopover graphRef={graphRef} />
Expand Down
2 changes: 2 additions & 0 deletions designer/client/src/components/graph/StickyNoteElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const StickyNoteElementView = dia.ElementView.extend({
events: {
"click textarea": "stopPropagation",
"keydown textarea": "selectAll",
"blur textarea": "onChange",
"focusout textarea": "onChange",
"dblclick .sticky-note-content": "showEditor",
},
Expand All @@ -46,6 +47,7 @@ export const StickyNoteElementView = dia.ElementView.extend({

onChange: function (evt) {
this.model.trigger(Events.CELL_CONTENT_UPDATED, this.model, evt.target.value);
console.log(evt);
this.model.attr(`${MARKDOWN_EDITOR_NAME}/props/value`, evt.target.value);
this.model.attr(`${MARKDOWN_EDITOR_NAME}/props/disabled`, true);
},
Expand Down
3 changes: 2 additions & 1 deletion designer/client/src/http/HttpService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,10 @@ export type ComponentUsageType = {
lastAction: ProcessActionType;
};

type NotificationActions = {
export type NotificationActions = {
success(message: string): void;
error(message: string, error: string, showErrorText: boolean): void;
warn(message: string): void;
};

export interface TestProcessResponse {
Expand Down

0 comments on commit e134034

Please sign in to comment.