Skip to content

Commit 29a69a1

Browse files
committed
chore(react): udpate edit style of BaseUserProfile
1 parent 1ed1629 commit 29a69a1

File tree

5 files changed

+83
-79
lines changed

5 files changed

+83
-79
lines changed

packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx

Lines changed: 75 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,17 @@ const BaseUserProfile: FC<BaseUserProfileProps> = ({
177177

178178
const mergedMappings = {...defaultAttributeMappings, ...attributeMapping};
179179

180-
const renderSchemaValue = (schema: Schema): ReactElement | null => {
180+
// Combines label and value/field rendering for both view and edit modes
181+
const renderSchemaField = (
182+
schema: Schema,
183+
isEditing: boolean,
184+
onEditValue?: (value: any) => void,
185+
): ReactElement | null => {
181186
if (!schema) return null;
187+
const {value, displayName, description, name, type, required, mutability, subAttributes} = schema;
188+
const label = displayName || description || name || '';
182189

183-
const {value, displayName, description, type, subAttributes} = schema;
184-
190+
// If complex or subAttributes, fallback to original renderSchemaValue
185191
if (subAttributes && Array.isArray(subAttributes)) {
186192
return (
187193
<>
@@ -202,83 +208,62 @@ const BaseUserProfile: FC<BaseUserProfileProps> = ({
202208
</>
203209
);
204210
}
205-
206211
if (Array.isArray(value)) {
207212
const displayValue = value
208213
.map(item => (typeof item === 'object' ? JSON.stringify(item) : String(item)))
209214
.join(', ');
210-
211215
return (
212216
<>
213-
<span style={styles.label}>{displayName || description || ''}</span>
217+
<span style={styles.label}>{label}</span>
214218
<div style={styles.value}>{displayValue}</div>
215219
</>
216220
);
217221
}
218-
219222
if (type === 'COMPLEX' && typeof value === 'object') {
220223
return <ObjectDisplay data={value} />;
221224
}
222-
223-
return (
224-
<>
225-
<span style={styles.label}>{displayName || description || ''}</span>
226-
<div style={styles.value}>{String(value)}</div>
227-
</>
228-
);
229-
};
230-
231-
const renderEditableField = (schema: Schema, onChange: (value: any) => void): ReactElement | null => {
232-
if (!schema) return null;
233-
234-
const {value, displayName, name, type, required, mutability} = schema;
235-
236-
if (mutability === 'READ_ONLY') {
225+
// If editing, show field instead of value
226+
if (isEditing && onEditValue && mutability !== 'READ_ONLY') {
227+
const commonProps = {
228+
label: undefined, // Don't show label in field, we render it outside
229+
required: required,
230+
value: value || '',
231+
onChange: (e: any) => onEditValue(e.target ? e.target.value : e),
232+
style: {
233+
marginBottom: 0,
234+
},
235+
};
236+
let field: ReactElement;
237+
switch (type) {
238+
case 'STRING':
239+
field = <TextField {...commonProps} />;
240+
break;
241+
case 'DATE_TIME':
242+
field = <DatePicker {...commonProps} />;
243+
break;
244+
case 'BOOLEAN':
245+
field = <Checkbox {...commonProps} checked={value} onChange={e => onEditValue(e.target.checked)} />;
246+
break;
247+
case 'COMPLEX':
248+
field = <TextField {...commonProps} />;
249+
break;
250+
default:
251+
field = <TextField {...commonProps} />;
252+
}
237253
return (
238254
<>
239-
<span style={styles.label}>{displayName || name}</span>
240-
<div style={styles.value}>{String(value)}</div>
255+
<span style={styles.label}>{label}</span>
256+
<div style={styles.value}>{field}</div>
241257
</>
242258
);
243259
}
244-
245-
const commonProps = {
246-
label: displayName || name,
247-
required: required,
248-
value: value || '',
249-
onChange: (e: any) => onChange(e.target.value),
250-
};
251-
252-
switch (type) {
253-
case 'STRING':
254-
return <TextField {...commonProps} />;
255-
case 'DATE_TIME':
256-
return <DatePicker {...commonProps} />;
257-
case 'BOOLEAN':
258-
return <Checkbox {...commonProps} checked={value} onChange={e => onChange(e.target.checked)} />;
259-
case 'COMPLEX':
260-
if (Array.isArray(value)) {
261-
return (
262-
<>
263-
{value.map((item, index) => (
264-
<TextField
265-
key={index}
266-
{...commonProps}
267-
value={item}
268-
onChange={e => {
269-
const newValue = [...value];
270-
newValue[index] = e.target.value;
271-
onChange(newValue);
272-
}}
273-
/>
274-
))}
275-
</>
276-
);
277-
}
278-
return <TextField {...commonProps} />;
279-
default:
280-
return <TextField {...commonProps} />;
281-
}
260+
// Default: view mode
261+
return (
262+
<>
263+
<span style={styles.label}>{label}</span>
264+
<div style={styles.value}>{String(value)}</div>
265+
</>
266+
);
282267
};
283268

284269
const renderUserInfo = (schema: Schema) => {
@@ -288,7 +273,7 @@ const BaseUserProfile: FC<BaseUserProfileProps> = ({
288273
const fieldStyle = {
289274
...styles.field,
290275
display: 'flex',
291-
alignItems: 'flex-start',
276+
alignItems: 'center',
292277
gap: theme.spacing.unit + 'px',
293278
};
294279
const actionButtonStyle = {
@@ -300,17 +285,22 @@ const BaseUserProfile: FC<BaseUserProfileProps> = ({
300285

301286
return (
302287
<div style={fieldStyle}>
303-
<div style={{flex: 1}}>
304-
{isFieldEditing
305-
? renderEditableField(schema, value => {
306-
const tempEditedUser = {...editedUser};
307-
tempEditedUser[schema.name!] = value;
308-
setEditedUser(tempEditedUser);
309-
})
310-
: renderSchemaValue(schema)}
288+
<div style={{flex: 1, display: 'flex', alignItems: 'center', gap: theme.spacing.unit + 'px'}}>
289+
{renderSchemaField(schema, isFieldEditing, value => {
290+
const tempEditedUser = {...editedUser};
291+
tempEditedUser[schema.name!] = value;
292+
setEditedUser(tempEditedUser);
293+
})}
311294
</div>
312295
{editable && schema.mutability !== 'READ_ONLY' && (
313-
<div style={{display: 'flex', gap: theme.spacing.unit / 2 + 'px', alignSelf: 'center'}}>
296+
<div
297+
style={{
298+
display: 'flex',
299+
gap: theme.spacing.unit / 2 + 'px',
300+
alignItems: 'center',
301+
marginLeft: theme.spacing.unit + 'px',
302+
}}
303+
>
314304
{isFieldEditing ? (
315305
<>
316306
<button
@@ -469,8 +459,9 @@ const useStyles = () => {
469459
field: {
470460
display: 'flex',
471461
alignItems: 'center',
472-
padding: theme.spacing.unit * 0.5 + 'px 0',
462+
padding: theme.spacing.unit + 'px 0',
473463
borderBottom: `1px solid ${theme.colors.border}`,
464+
minHeight: '32px',
474465
} as CSSProperties,
475466
lastField: {
476467
borderBottom: 'none',
@@ -481,18 +472,25 @@ const useStyles = () => {
481472
color: theme.colors.text.secondary,
482473
width: '120px',
483474
flexShrink: 0,
475+
lineHeight: '32px',
484476
} as CSSProperties,
485477
value: {
486478
color: theme.colors.text.primary,
487479
flex: 1,
480+
display: 'flex',
481+
alignItems: 'center',
482+
gap: theme.spacing.unit + 'px',
488483
overflow: 'hidden',
489-
textOverflow: 'ellipsis',
490-
whiteSpace: 'nowrap',
491-
maxWidth: 'calc(100% - 120px)', // Subtracting label width
484+
minHeight: '32px',
485+
'& input, & .MuiInputBase-root': {
486+
height: '32px',
487+
margin: 0,
488+
},
489+
lineHeight: '32px',
492490
'& table': {
493491
backgroundColor: theme.colors.background,
494492
borderRadius: theme.borderRadius.small,
495-
whiteSpace: 'normal', // Allow tables to wrap
493+
whiteSpace: 'normal',
496494
},
497495
'& td': {
498496
borderColor: theme.colors.border,

packages/react/src/components/primitives/Checkbox/Checkbox.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,14 @@ export interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement
4343
helperText?: string;
4444
}
4545

46-
export const Checkbox: FC<CheckboxProps> = ({label, error, className, required, helperText, ...rest}) => {
46+
export const Checkbox: FC<CheckboxProps> = ({label, error, className, required, helperText, style = {}, ...rest}) => {
4747
const {theme} = useTheme();
4848

4949
const containerStyle: CSSProperties = {
5050
marginBottom: theme.spacing.unit * 2 + 'px',
5151
display: 'flex',
5252
alignItems: 'center',
53+
...style
5354
};
5455

5556
const inputStyle: CSSProperties = {

packages/react/src/components/primitives/DatePicker/DatePicker.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,14 @@ export const DatePicker: FC<DatePickerProps> = ({
5959
disabled,
6060
helperText,
6161
dateFormat = 'yyyy-MM-dd',
62+
style = {},
6263
...rest
6364
}) => {
6465
const {theme} = useTheme();
6566

6667
const containerStyle: CSSProperties = {
6768
marginBottom: theme.spacing.unit * 2 + 'px',
69+
...style
6870
};
6971

7072
const labelStyle: CSSProperties = {

packages/react/src/components/primitives/Select/Select.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,14 @@ export const Select: FC<SelectProps> = ({
7070
disabled,
7171
helperText,
7272
options,
73+
style = {},
7374
...rest
7475
}) => {
7576
const {theme} = useTheme();
7677

7778
const containerStyle: CSSProperties = {
7879
marginBottom: theme.spacing.unit * 2 + 'px',
80+
...style,
7981
};
8082

8183
const labelStyle: CSSProperties = {

packages/react/src/components/primitives/TextField/TextField.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,12 @@ export interface TextFieldProps extends Omit<InputHTMLAttributes<HTMLInputElemen
4747
helperText?: string;
4848
}
4949

50-
export const TextField: FC<TextFieldProps> = ({label, error, required, className, disabled, helperText, ...rest}) => {
50+
export const TextField: FC<TextFieldProps> = ({label, error, required, className, disabled, helperText, style = {}, ...rest}) => {
5151
const {theme} = useTheme();
5252

5353
const containerStyle: CSSProperties = {
5454
marginBottom: theme.spacing.unit * 2 + 'px',
55+
...style
5556
};
5657

5758
const labelStyle: CSSProperties = {

0 commit comments

Comments
 (0)