Skip to content

Commit 190e9b4

Browse files
committed
adjust edit mode to new design
1 parent 389e4ab commit 190e9b4

File tree

9 files changed

+146
-33
lines changed

9 files changed

+146
-33
lines changed

src/components/dagshub/data-engine/metadataKeyValue/CustomTextField.tsx

+19-7
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,32 @@
1-
import React, { useState, useRef, useEffect } from 'react';
1+
import React, {useEffect, useRef, useState} from 'react';
22
import IconButton from '@mui/material/IconButton';
33
import EditIcon from '@mui/icons-material/Edit';
44
import Box from '@mui/material/Box';
55
import CancelIcon from '@mui/icons-material/Cancel';
66
import StyledTextField from './StyledTextField';
77
import './style.scss';
8-
import { Tooltip } from '@mui/material';
8+
import {ErroredTooltip, TooltipVariant} from "../../../elements/tooltipV2/ErroredTooltip";
99

1010
function CustomTextField({
1111
readOnly,
1212
value,
13-
onSaveHandler,
1413
placeholder,
1514
helperText,
1615
shouldHighlightIfEmpty,
1716
autoFocus,
17+
isErrored,
18+
onInputChange,
19+
onInputSave,
1820
}: {
1921
readOnly: boolean;
2022
value?: string;
21-
onSaveHandler: (newVal?: string) => void;
2223
placeholder?: string;
2324
helperText?: string;
2425
shouldHighlightIfEmpty?: boolean;
2526
autoFocus?: boolean;
27+
isErrored?: boolean;
28+
onInputChange?: (newVal?: string) => void;
29+
onInputSave?: (newVal?: string) => void;
2630
}) {
2731
const [currentValue, setCurrentValue] = useState(value);
2832
const [isEditing, setEditing] = useState(false);
@@ -67,17 +71,22 @@ function CustomTextField({
6771

6872
const saveChangesHandler = () => {
6973
setCurrentValue(editedValue);
70-
onSaveHandler(editedValue);
74+
!!onInputSave && onInputSave(editedValue);
7175
setHovered(false);
7276
setEditing(false);
7377
textFieldRef.current?.blur();
7478
};
7579

7680
const handleKeyDown = (event: any) => {
81+
if(event.key === 'ArrowRight' || event.key === 'ArrowLeft'){
82+
event.stopPropagation();
83+
}
7784
if (isEditing && event.key === 'Enter') {
85+
event.stopPropagation();
7886
saveChangesHandler();
7987
}
8088
if (isEditing && event.key === 'Escape') {
89+
event.stopPropagation();
8190
handleCancelClick();
8291
}
8392
};
@@ -107,7 +116,7 @@ function CustomTextField({
107116
}, [currentValue, shouldHighlightIfEmpty]);
108117

109118
return (
110-
<Tooltip title={getValue()} placement={'top'} disableInteractive={true} arrow>
119+
<ErroredTooltip title={isErrored?"Value is not valid":''} placement={'top'} disableInteractive={true} open={isErrored || isHovered} tooltipVariant={TooltipVariant.Error}>
111120
<Box
112121
sx={{ width: '100%', height: '100%' }}
113122
onMouseEnter={() => {
@@ -153,13 +162,16 @@ function CustomTextField({
153162
onChange={(e: any) => {
154163
setEditing(true);
155164
setEditedValue(e.target.value);
165+
!!onInputChange && onInputChange(e.target.value);
156166
}}
157167
onKeyDown={handleKeyDown}
158168
value={getValue()}
159169
placeholder={placeholder}
170+
isErrored={isErrored}
171+
errorColor={"rgba(252, 165, 165, 1)"}
160172
/>
161173
</Box>
162-
</Tooltip>
174+
</ErroredTooltip>
163175
);
164176
}
165177

src/components/dagshub/data-engine/metadataKeyValue/MetadataKeyValueList.tsx

+11-6
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ export interface MetadataKeyValueListProps {
3030
editingEnabled: boolean;
3131
deletionEnabled: boolean;
3232
onDeleteHandler?: (keyName: string) => void;
33-
onChangeHandler?: (metadataList: NewMetadataField[]) => void;
33+
onSaveHandler?: (metadataList: NewMetadataField[]) => void;
34+
validateValueByType?: (valueType: MetadataType, value: string) => boolean;
3435
}
3536

3637
export function MetadataKeyValueList({
@@ -39,7 +40,8 @@ export function MetadataKeyValueList({
3940
editingEnabled,
4041
deletionEnabled,
4142
onDeleteHandler,
42-
onChangeHandler,
43+
onSaveHandler,
44+
validateValueByType,
4345
}: MetadataKeyValueListProps) {
4446
//Todo:
4547
// - Not sure what to do with the multiple field. (If I need to use it as part of the validations in the future, and also what value should I set for newly created fields).
@@ -66,10 +68,12 @@ export function MetadataKeyValueList({
6668
}
6769
}, [metadataList]);
6870

71+
//Todo: create a function to save changes
72+
// if (onSaveHandler) {
73+
// onSaveHandler({ ...temporaryMetadataList });
74+
// }
75+
6976
useEffect(() => {
70-
if (onChangeHandler) {
71-
onChangeHandler({ ...temporaryMetadataList });
72-
}
7377
if (shouldScrollToBottom && metadataFieldsSection.current) {
7478
// scroll to button only if + button was clicked
7579
(metadataFieldsSection.current as HTMLDivElement).scrollTop = (
@@ -172,7 +176,7 @@ export function MetadataKeyValueList({
172176
const checkIfPairIsRemovable = (metadataField: {
173177
key?: string;
174178
value?: string;
175-
valueType?: string;
179+
valueType?: MetadataType;
176180
multiple?: boolean;
177181
isAutoGenerated?: boolean;
178182
isNewlyCreated?: boolean;
@@ -228,6 +232,7 @@ export function MetadataKeyValueList({
228232
: permanentlyDeleteMetadataFieldByIndex
229233
}
230234
autoFocusKey={metadataField.isNewlyCreated && autoFocusNewlyCreatedFieldKey}
235+
validateValueByType={validateValueByType}
231236
/>
232237
))}
233238
</Box>

src/components/dagshub/data-engine/metadataKeyValue/MetadataKeyValuePair.tsx

+25-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export interface MetadataKeyValuePairProps {
1212
index: number;
1313
keyName?: string;
1414
value?: string;
15-
valueType?: string;
15+
valueType?: MetadataType;
1616
isEditable: boolean;
1717
description?: string;
1818
isNewlyCreated?: boolean;
@@ -23,6 +23,7 @@ export interface MetadataKeyValuePairProps {
2323
deleteFieldPermanently?: (index: number) => void;
2424
shouldHighlightEmptyFields?: boolean;
2525
autoFocusKey?: boolean;
26+
validateValueByType?: (valueType: MetadataType, value: string) => boolean;
2627
}
2728

2829
export function MetadataKeyValuePair({
@@ -40,7 +41,17 @@ export function MetadataKeyValuePair({
4041
deleteFieldPermanently,
4142
shouldHighlightEmptyFields,
4243
autoFocusKey,
44+
validateValueByType,
4345
}: MetadataKeyValuePairProps) {
46+
47+
const [isErrored, setIsErrored] = React.useState(false);
48+
49+
useEffect(()=>{
50+
if(!!validateValueByType && !!valueType){
51+
setIsErrored(!validateValueByType(valueType, value as string))
52+
}
53+
},[valueType])
54+
4455
const valueTypes: { id: MetadataType; label: string }[] = [
4556
{
4657
id: 'INTEGER',
@@ -90,7 +101,7 @@ export function MetadataKeyValuePair({
90101
<CustomTextField
91102
readOnly={!isNewlyCreated}
92103
value={keyName}
93-
onSaveHandler={(newVal) => {
104+
onInputSave={(newVal) => {
94105
if (saveKeyNameLocally) {
95106
saveKeyNameLocally(index, newVal);
96107
}
@@ -109,10 +120,11 @@ export function MetadataKeyValuePair({
109120
gap: '8px',
110121
flexShrink: 1,
111122
minWidth: '65%',
123+
height:"100%",
112124
}}
113125
>
114126
{isNewlyCreated && (
115-
<Box flexShrink={0}>
127+
<div style={{width:"100%", maxWidth:"130px"}}>
116128
<DropdownV2
117129
onChange={(event, value) => {
118130
if (saveValueTypeLocally) {
@@ -131,18 +143,26 @@ export function MetadataKeyValuePair({
131143
disableClearable
132144
shouldHighlightIfEmpty={shouldHighlightEmptyFields}
133145
/>
134-
</Box>
146+
</div>
135147
)}
136148
<CustomTextField
137149
readOnly={!isEditable}
138150
value={value}
139-
onSaveHandler={(newVal) => {
151+
onInputSave={(newVal) => {
152+
if (!!validateValueByType && !!valueType){
153+
setIsErrored(!validateValueByType(valueType, newVal as string))
154+
}
140155
if (saveValueLocally) {
141156
saveValueLocally(index, newVal);
142157
}
143158
}}
159+
onInputChange={(newVal) => {
160+
if (!!validateValueByType && !!valueType){
161+
setIsErrored(!validateValueByType(valueType, newVal as string))
162+
}}}
144163
placeholder={isNewlyCreated || !value ? 'Add value' : 'Typing...'}
145164
shouldHighlightIfEmpty={shouldHighlightEmptyFields}
165+
isErrored={isErrored}//TODO: add validation
146166
/>
147167
{isEditable && isRemovable && (
148168
<IconButton

src/components/dagshub/data-engine/metadataKeyValue/StyledTextField.tsx

+8-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ function StyledTextField({
1414
backgroundColorFocus = 'rgba(255, 255, 255, 1)',
1515
helperTextPaddingLeft = '8px',
1616
helperTextPaddingBottom = '8px',
17+
errorColor = 'rgba(239, 68, 68, 1)',
1718
...restProps
1819
}: {
1920
changeColorOnHover?: boolean;
@@ -28,6 +29,7 @@ function StyledTextField({
2829
backgroundColorFocus?: string;
2930
helperTextPaddingLeft?: string;
3031
helperTextPaddingBottom?: string;
32+
errorColor?: string;
3133
} & TextFieldProps) {
3234
return (
3335
<TextField
@@ -36,11 +38,11 @@ function StyledTextField({
3638
width: width ?? '100%',
3739
'.Mui-focused': {
3840
background: !focusModeDisabled ? `${backgroundColorFocus}!important` : undefined,
39-
boxShadow: !focusModeDisabled
41+
boxShadow: !focusModeDisabled && !isErrored
4042
? 'inset 0px 0px 0px 3px rgba(196, 181, 253, 0.5)!important'
4143
: undefined,
4244
'.MuiOutlinedInput-notchedOutline': {
43-
border: '0px!important',
45+
border: isErrored? `2px solid ${errorColor}!important`: '0px!important',
4446
},
4547
},
4648
'.MuiInputBase-root': {
@@ -64,14 +66,14 @@ function StyledTextField({
6466
},
6567
'.MuiOutlinedInput-notchedOutline': {
6668
borderColor: isErrored
67-
? 'rgba(239, 68, 68, 1)!important'
69+
? `${errorColor}!important`
6870
: 'rgba(226, 232, 240, 1)!important',
6971
'&:hover': {
7072
borderColor: isErrored
71-
? 'rgba(239, 68, 68, 1)!important'
73+
? `${errorColor}!important`
7274
: 'rgba(203, 213, 225, 1)!important',
7375
},
74-
border: setBorder ? (isErrored ? '2px solid' : '1px solid') : '0px',
76+
border: isErrored? '2px solid' : setBorder ? '1px solid' : '0px',
7577
},
7678
'.MuiSvgIcon-root ': {
7779
fill: 'rgba(148, 163, 184, 1)',
@@ -88,7 +90,7 @@ function StyledTextField({
8890
lineHeight: '16.8px',
8991
overflow: 'hidden',
9092
textOverflow: 'ellipsis',
91-
color: isErrored ? 'rgba(239, 68, 68, 1)' : 'rgba(71, 85, 105, 1)',
93+
color: isErrored ? errorColor : 'rgba(71, 85, 105, 1)',
9294
margin: '0px',
9395
paddingLeft: helperTextPaddingLeft,
9496
paddingBottom: helperTextPaddingBottom,

src/components/dagshub/data-engine/singleFileViewModal/SingleFileViewDataSection.tsx

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useRef, useState } from 'react';
22
import { Box } from '@mui/system';
3-
import { MetadataKeyValueList, NewMetadataField } from '../metadataKeyValue/MetadataKeyValueList';
3+
import {MetadataKeyValueList, MetadataType, NewMetadataField} from '../metadataKeyValue/MetadataKeyValueList';
44
import { Button, ButtonVariant, CustomAccordion } from '../../../elements';
55
import { Icon } from '../../../icons';
66
import { ItemData, SidebarProps, VisualizerProps } from './SingleFileViewModal';
@@ -18,6 +18,7 @@ export function SingleFileViewDataSection({
1818
enableMetadataDeletion,
1919
visualizerRenderer,
2020
sidebarRenderers,
21+
validateValueByType,
2122
}: {
2223
isSmallScreen: boolean;
2324
itemData: ItemData;
@@ -29,7 +30,9 @@ export function SingleFileViewDataSection({
2930
enableMetadataDeletion?: boolean;
3031
visualizerRenderer: (props: VisualizerProps) => React.ReactNode;
3132
sidebarRenderers?: React.ReactNode;
33+
validateValueByType?: (valueType: MetadataType, value: string) => boolean;
3234
}) {
35+
3336
const SIDEBAR_WIDTH = 350; //I decided on this number
3437
const ARROWS_SECTION_HEIGHT = 52;
3538

@@ -70,7 +73,8 @@ export function SingleFileViewDataSection({
7073
metadataList={itemData.metadataList}
7174
editingEnabled={!!enableMetadataEditing}
7275
deletionEnabled={!!enableMetadataDeletion}
73-
onChangeHandler={metadataOnChangeHandler}
76+
onSaveHandler={metadataOnChangeHandler}
77+
validateValueByType={validateValueByType}
7478
/>
7579
</CustomAccordion>
7680
</Box>
@@ -225,7 +229,8 @@ export function SingleFileViewDataSection({
225229
metadataList={itemData.metadataList}
226230
editingEnabled={!!enableMetadataEditing}
227231
deletionEnabled={!!enableMetadataDeletion}
228-
onChangeHandler={metadataOnChangeHandler}
232+
onSaveHandler={metadataOnChangeHandler}
233+
validateValueByType={validateValueByType}
229234
/>
230235
</CustomAccordion>
231236
{sidebarRenderers}

src/components/dagshub/data-engine/singleFileViewModal/SingleFileViewModal.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Box } from '@mui/system';
22
import React, { useEffect, useRef, useState } from 'react';
33
import { useMediaQuery } from '@mui/material';
4-
import { GenericModal, MetadataField, NewMetadataField, RGB } from '../../index';
4+
import {GenericModal, MetadataField, MetadataType, NewMetadataField, RGB} from '../../index';
55
import './style.scss';
66
import TopButtonsSection from './TopButtonsSection';
77
import { SingleFileViewDataSection } from './SingleFileViewDataSection';
@@ -48,6 +48,7 @@ export interface singleFileViewModalProps {
4848
enableFileDownloading?: boolean;
4949
visualizerRenderer: (props: VisualizerProps) => React.ReactNode;
5050
sidebarRenderers?: React.ReactNode;
51+
validateValueByType?: (valueType: MetadataType, value: string) => boolean;
5152
}
5253

5354
export function SingleFileViewModal({
@@ -65,6 +66,7 @@ export function SingleFileViewModal({
6566
enableFileDownloading,
6667
visualizerRenderer,
6768
sidebarRenderers,
69+
validateValueByType,
6870
}: singleFileViewModalProps) {
6971
const [showMetadataOverlay, setShowMetadataOverlay] = useState<boolean>(false);
7072
const breakpoint = useMediaQuery('(max-width: 800px)');
@@ -145,6 +147,7 @@ export function SingleFileViewModal({
145147
enableMetadataDeletion={enableMetadataDeletion}
146148
visualizerRenderer={visualizerRenderer}
147149
sidebarRenderers={sidebarRenderers}
150+
validateValueByType={validateValueByType}
148151
/>
149152
</Box>
150153
</Box>,

0 commit comments

Comments
 (0)