Skip to content

Commit

Permalink
Update JS Object Name Editor
Browse files Browse the repository at this point in the history
  • Loading branch information
hetunandu committed Oct 25, 2024
1 parent 8c61d86 commit ba3b95c
Showing 1 changed file with 42 additions and 128 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import { useSelector } from "react-redux";
import React, { useCallback, useMemo } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import type { ReduxAction } from "ee/constants/ReduxActionConstants";
import { getSavingStatusForJSObjectName } from "selectors/actionSelectors";
import { getAssetUrl } from "ee/utils/airgapHelpers";
import { Spinner, Text as ADSText, Tooltip, Flex } from "@appsmith/ads";
import { usePrevious } from "@mantine/hooks";
import { Text as ADSText, Flex } from "@appsmith/ads";
import styled from "styled-components";
import { useNameEditor } from "utils/hooks/useNameEditor";
import { useBoolean, useEventCallback, useEventListener } from "usehooks-ts";
import { useBoolean } from "usehooks-ts";
import { noop } from "lodash";
import { useParams } from "react-router";
import type { AppState } from "ee/reducers";
Expand All @@ -18,6 +16,7 @@ import {
getPlugin,
} from "ee/selectors/entitiesSelector";
import { JSObjectNameEditor as OldJSObjectNameEditor } from "./old/JSObjectNameEditor";
import { EditableName } from "IDE";

export interface SaveActionNameParams {
id: string;
Expand All @@ -35,7 +34,7 @@ export const NameWrapper = styled(Flex)`
height: 100%;
position: relative;
font-size: 12px;
color: var(--ads-v2-colors-text-default);
color: var(--ads-v2-color-fg);
cursor: pointer;
gap: var(--ads-v2-spaces-2);
align-items: center;
Expand All @@ -50,6 +49,7 @@ export const IconContainer = styled.div`
align-items: center;
justify-content: center;
flex-shrink: 0;
img {
width: 12px;
}
Expand All @@ -61,7 +61,10 @@ export const Text = styled(ADSText)`
font-weight: 500;
`;

export const JSObjectNameEditor = (props: JSObjectNameEditorProps) => {
export const JSObjectNameEditor = ({
disabled,
saveJSObjectName,
}: JSObjectNameEditorProps) => {
const params = useParams<{
baseCollectionId?: string;
baseQueryId?: string;
Expand All @@ -81,152 +84,63 @@ export const JSObjectNameEditor = (props: JSObjectNameEditorProps) => {
.isSaving,
);

const title = currentJSObjectConfig?.name || "";
const previousTitle = usePrevious(title);
const [editableTitle, setEditableTitle] = useState(title);
const [validationError, setValidationError] = useState<string | null>(null);
const inputRef = useRef<HTMLInputElement>(null);

const { handleNameSave, normalizeName, validateName } = useNameEditor({
entityId: params?.baseCollectionId || "",
entityName: title,
nameSaveAction: props.saveJSObjectName,
});
const name = currentJSObjectConfig?.name || "";

const {
setFalse: exitEditMode,
setTrue: enterEditMode,
value: isEditing,
} = useBoolean(false);

const currentTitle =
isEditing || isLoading || title !== editableTitle ? editableTitle : title;

const handleKeyUp = useEventCallback(
(e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter") {
const nameError = validateName(editableTitle);

if (nameError === null) {
exitEditMode();
handleNameSave(editableTitle);
} else {
setValidationError(nameError);
}
} else if (e.key === "Escape") {
exitEditMode();
setEditableTitle(title);
setValidationError(null);
} else {
setValidationError(null);
}
},
);
const handleDoubleClick = disabled ? noop : enterEditMode;

const handleTitleChange = useEventCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
setEditableTitle(normalizeName(e.target.value));
},
);
const dispatch = useDispatch();

const handleEnterEditMode = useEventCallback(() => {
setEditableTitle(title);
enterEditMode();
});

const handleDoubleClick = props.disabled ? noop : handleEnterEditMode;

const inputProps = useMemo(
() => ({
onKeyUp: handleKeyUp,
onChange: handleTitleChange,
autoFocus: true,
style: {
paddingTop: 0,
paddingBottom: 0,
left: -1,
top: -1,
},
}),
[handleKeyUp, handleTitleChange],
);

useEventListener(
"focusout",
function handleFocusOut() {
if (isEditing) {
const nameError = validateName(editableTitle);

exitEditMode();

if (nameError === null) {
handleNameSave(editableTitle);
} else {
setEditableTitle(title);
setValidationError(null);
}
const handleSaveName = useCallback(
(name: string) => {
if (currentJSObjectConfig) {
dispatch(saveJSObjectName({ id: currentJSObjectConfig.id, name }));
}
},
inputRef,
);

useEffect(
function syncEditableTitle() {
if (!isEditing && previousTitle !== title) {
setEditableTitle(title);
}
},
[title, previousTitle, isEditing],
);

useEffect(
function recaptureFocusInEventOfFocusRetention() {
const input = inputRef.current;

if (isEditing && input) {
setTimeout(() => {
input.focus();
}, 200);
}
},
[isEditing],
[currentJSObjectConfig, saveJSObjectName],
);

const isActionRedesignEnabled = useFeatureFlag(
FEATURE_FLAG.release_actions_redesign_enabled,
);

const icon = useMemo(() => {
if (!currentPlugin) return null;

return (
<IconContainer>
<img
alt={currentPlugin.name}
src={getAssetUrl(currentPlugin.iconLocation)}
/>
</IconContainer>
);
}, [currentPlugin]);

if (!isActionRedesignEnabled) {
return (
<OldJSObjectNameEditor
disabled={props.disabled}
saveJSObjectName={props.saveJSObjectName}
disabled={disabled}
saveJSObjectName={saveJSObjectName}
/>
);
}

return (
<NameWrapper onDoubleClick={handleDoubleClick}>
{currentPlugin && !isLoading ? (
<IconContainer>
<img
alt={currentPlugin.name}
src={getAssetUrl(currentPlugin.iconLocation)}
/>
</IconContainer>
) : null}
{isLoading && <Spinner size="sm" />}

<Tooltip content={validationError} visible={Boolean(validationError)}>
<Text
inputProps={inputProps}
inputRef={inputRef}
isEditable={isEditing}
kind="body-s"
>
{currentTitle}
</Text>
</Tooltip>
<EditableName
exitEditing={exitEditMode}
icon={icon}
isEditing={isEditing}
isLoading={isLoading}
name={name}
onNameSave={handleSaveName}
/>
</NameWrapper>
);
};

0 comments on commit ba3b95c

Please sign in to comment.