diff --git a/frontend/webapp/reuseable-components/input-list/index.tsx b/frontend/webapp/reuseable-components/input-list/index.tsx index dde9630496..a786bb51a3 100644 --- a/frontend/webapp/reuseable-components/input-list/index.tsx +++ b/frontend/webapp/reuseable-components/input-list/index.tsx @@ -1,4 +1,5 @@ -import React, { type KeyboardEventHandler, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { isEmpty } from '@/utils'; import styled from 'styled-components'; import { PlusIcon, TrashIcon } from '@/assets'; import { Button, FieldError, FieldLabel, Input, Text } from '@/reuseable-components'; @@ -104,8 +105,9 @@ const InputList: React.FC = ({ initialValues = [], value, onChan }; // Check if any input field is empty + const isMinRows = rows.length <= 1; const isAddButtonDisabled = rows.some((input) => input.trim() === ''); - const isDelButtonDisabled = rows.length <= 1; + const isDelButtonDisabled = isMinRows && isAddButtonDisabled; return ( @@ -114,8 +116,17 @@ const InputList: React.FC = ({ initialValues = [], value, onChan {rows.map((val, idx) => ( - handleInputChange(e.target.value, idx)} hasError={!!errorMessage} autoFocus={!val && rows.length > 1 && idx === rows.length - 1} /> - handleDeleteInput(idx)}> + handleInputChange(e.target.value, idx)} hasError={!!errorMessage} autoFocus={isEmpty(val) && !isMinRows && idx === rows.length - 1} /> + { + if (isMinRows) { + handleInputChange('', idx); + } else { + handleDeleteInput(idx); + } + }} + > diff --git a/frontend/webapp/reuseable-components/input-table/index.tsx b/frontend/webapp/reuseable-components/input-table/index.tsx index 6e3046838e..a46cab4b88 100644 --- a/frontend/webapp/reuseable-components/input-table/index.tsx +++ b/frontend/webapp/reuseable-components/input-table/index.tsx @@ -1,8 +1,8 @@ -import React, { useState, useEffect, useRef, useMemo, type KeyboardEventHandler } from 'react'; +import React, { useState, useEffect, useRef, useMemo } from 'react'; +import { isEmpty } from '@/utils'; import styled from 'styled-components'; import { PlusIcon, TrashIcon } from '@/assets'; import { Button, FieldError, FieldLabel, Input, Text } from '@/reuseable-components'; -import { isEmpty } from '@/utils'; type Row = { [key: string]: any; @@ -106,8 +106,9 @@ export const InputTable: React.FC = ({ columns, initialValues = [], value }; // Check if any key or value field is empty - const isAddButtonDisabled = rows.some((row) => !!Object.values(row).filter((val) => !val).length); - const isDelButtonDisabled = rows.length <= 1; + const isMinRows = rows.length <= 1; + const isAddButtonDisabled = rows.some((row) => !!Object.values(row).filter((val) => isEmpty(val)).length); + const isDelButtonDisabled = isMinRows && isAddButtonDisabled; // adjust cell-width based on the amount of inputs on-screen, // the "0.4" is to consider the delete button @@ -141,7 +142,7 @@ export const InputTable: React.FC = ({ columns, initialValues = [], value placeholder={placeholder} value={value} onChange={({ target: { value: val } }) => handleChange(keyName, type === 'number' ? Number(val) : val, idx)} - autoFocus={isEmpty(value) && rows.length > 1 && idx === rows.length - 1 && innerIdx === 0} + autoFocus={isEmpty(value) && !isMinRows && idx === rows.length - 1 && innerIdx === 0} style={{ maxWidth, paddingLeft: 10 }} hasError={!!errorMessage && (!required || (required && isEmpty(value)))} /> @@ -150,7 +151,16 @@ export const InputTable: React.FC = ({ columns, initialValues = [], value })} - handleDeleteRow(idx)}> + { + if (isMinRows) { + columns.forEach(({ keyName }) => handleChange(keyName, '', idx)); + } else { + handleDeleteRow(idx); + } + }} + > diff --git a/frontend/webapp/reuseable-components/key-value-input-list/index.tsx b/frontend/webapp/reuseable-components/key-value-input-list/index.tsx index ba65375f66..db4ac74187 100644 --- a/frontend/webapp/reuseable-components/key-value-input-list/index.tsx +++ b/frontend/webapp/reuseable-components/key-value-input-list/index.tsx @@ -1,4 +1,5 @@ -import React, { useState, useEffect, useRef, useMemo, type KeyboardEventHandler } from 'react'; +import React, { useState, useEffect, useRef, useMemo } from 'react'; +import { isEmpty } from '@/utils'; import theme from '@/styles/theme'; import styled from 'styled-components'; import { ArrowIcon, PlusIcon, TrashIcon } from '@/assets'; @@ -77,7 +78,7 @@ export const KeyValueInputsList: React.FC = ({ initialK }, []); // Filter out rows where either key or value is empty - const validRows = useMemo(() => rows.filter(({ key, value }) => !!key.trim() && !!value.trim()), [rows]); + const validRows = useMemo(() => rows.filter(({ key, value }) => !isEmpty(key.trim()) && !isEmpty(value.trim())), [rows]); const recordedRows = useRef(JSON.stringify(validRows)); useEffect(() => { @@ -112,8 +113,9 @@ export const KeyValueInputsList: React.FC = ({ initialK }; // Check if any key or value field is empty + const isMinRows = rows.length <= 1; const isAddButtonDisabled = rows.some(({ key, value }) => key.trim() === '' || value.trim() === ''); - const isDelButtonDisabled = rows.length <= 1; + const isDelButtonDisabled = isMinRows && isAddButtonDisabled; return ( @@ -127,7 +129,7 @@ export const KeyValueInputsList: React.FC = ({ initialK value={key} onChange={(e) => handleChange('key', e.target.value, idx)} hasError={!!errorMessage && (!required || (required && !key))} - autoFocus={!value && rows.length > 1 && idx === rows.length - 1} + autoFocus={isEmpty(value) && !isMinRows && idx === rows.length - 1} />
@@ -136,10 +138,20 @@ export const KeyValueInputsList: React.FC = ({ initialK placeholder='Attribute value' value={value} onChange={(e) => handleChange('value', e.target.value, idx)} - hasError={!!errorMessage && (!required || (required && !value))} + hasError={!!errorMessage && (!required || (required && isEmpty(value)))} autoFocus={false} /> - handleDeleteRow(idx)}> + { + if (isMinRows) { + handleChange('key', '', idx); + handleChange('value', '', idx); + } else { + handleDeleteRow(idx); + } + }} + >