refactor(FE-114): remove FieldMessage component usage and streamline error message handling in form inputs

This commit is contained in:
rstubryan
2025-10-23 13:14:16 +07:00
parent 6687f4af98
commit 7e53743b07
11 changed files with 196 additions and 305 deletions
+7 -6
View File
@@ -267,12 +267,13 @@ const CheckboxInput = ({
</p> </p>
)} )}
{/* Field Message */} {/* Error Message or Bottom Label */}
<FieldMessage {!isError && bottomLabel && (
message={feedbackMessage} <p className='w-full text-sm opacity-60'>{bottomLabel}</p>
tone={showErrorMessage ? 'error' : 'info'} )}
isVisible={showErrorMessage || Boolean(bottomLabel)} {isError && errorMessage && (
/> <p className='w-full text-sm text-error'>{errorMessage}</p>
)}
</div> </div>
); );
}; };
+5 -9
View File
@@ -2,7 +2,6 @@ import { Ref } from 'react';
import { cn } from '@/lib/helper'; import { cn } from '@/lib/helper';
import { TextInputProps } from '@/components/input/TextInput'; import { TextInputProps } from '@/components/input/TextInput';
import FieldMessage from '@/components/helper/FieldMessage';
interface FileInputProps interface FileInputProps
extends Omit< extends Omit<
@@ -38,9 +37,6 @@ const FileInput = ({
onBlur, onBlur,
readOnly = false, readOnly = false,
}: FileInputProps) => { }: FileInputProps) => {
const showErrorMessage = Boolean(isError && errorMessage);
const feedbackMessage = showErrorMessage ? errorMessage : bottomLabel;
return ( return (
<div <div
className={cn( className={cn(
@@ -80,11 +76,11 @@ const FileInput = ({
readOnly={readOnly} readOnly={readOnly}
/> />
<FieldMessage {bottomLabel && (
message={feedbackMessage} <p className='w-full text-sm opacity-60'>{bottomLabel}</p>
tone={showErrorMessage ? 'error' : 'info'} )}
isVisible={showErrorMessage || Boolean(bottomLabel)}
/> {isError && <p className='w-full text-sm text-error'>{errorMessage}</p>}
</div> </div>
); );
}; };
+150 -226
View File
@@ -11,67 +11,8 @@ import {
import { Icon } from '@iconify/react'; import { Icon } from '@iconify/react';
import { cn } from '@/lib/helper'; import { cn } from '@/lib/helper';
import FieldMessage from '@/components/helper/FieldMessage';
export type MaskType = 'currency' | 'weight' | 'decimal' | 'number'; // Utility Functions
export interface NumberInputProps {
// Basic Props
label?: string;
bottomLabel?: string;
name: string;
value?: number | string;
placeholder?: string;
// Styling Props
className?: {
wrapper?: string;
label?: string;
inputWrapper?: string;
input?: string;
};
// State Props
isError?: boolean;
isValid?: boolean;
errorMessage?: string;
disabled?: boolean;
readOnly?: boolean;
required?: boolean;
isLoading?: boolean;
// Adornment Props
startAdornment?: ReactNode;
endAdornment?: ReactNode;
// Event Handlers
onChange?: ChangeEventHandler<HTMLInputElement>;
onBlur?: FocusEventHandler<HTMLInputElement>;
onFocus?: FocusEventHandler<HTMLInputElement>;
// Masking Options
maskType?: MaskType;
decimals?: number;
thousandSeparator?: string;
decimalSeparator?: string;
currencyPrefix?: string;
weightUnit?: string;
// Validation Props
min?: number;
max?: number;
allowNegative?: boolean;
// Stepper Options
showSteppers?: boolean;
step?: number;
}
// UTILITY FUNCTIONS
/**
* Core number formatting function
* Formats number with thousand separator and decimal separator
*/
const formatNumber = ( const formatNumber = (
value: number | string, value: number | string,
decimals: number = 0, decimals: number = 0,
@@ -95,10 +36,6 @@ const formatNumber = (
: integerPart; : integerPart;
}; };
/**
* Parse formatted string to number
* Converts formatted input back to raw number for processing
*/
const parseNumber = ( const parseNumber = (
value: string, value: string,
thousandSeparator: string = '.', thousandSeparator: string = '.',
@@ -115,10 +52,26 @@ const parseNumber = (
return isNaN(parsed) ? 0 : parsed; return isNaN(parsed) ? 0 : parsed;
}; };
/** const formatCurrency = (
* Clean and validate numeric input while typing value: number | string,
* Ensures only valid characters are allowed prefix: string = 'Rp ',
*/ decimals: number = 0
): string => {
if (value === '' || value === null || value === undefined) return '';
const formatted = formatNumber(value, decimals);
return formatted ? `${prefix}${formatted}` : '';
};
const formatWeight = (
value: number | string,
unit: string = 'kg',
decimals: number = 2
): string => {
if (value === '' || value === null || value === undefined) return '';
const formatted = formatNumber(value, decimals);
return formatted ? `${formatted} ${unit}` : '';
};
const cleanNumericInput = ( const cleanNumericInput = (
value: string, value: string,
allowDecimal: boolean = false, allowDecimal: boolean = false,
@@ -146,6 +99,56 @@ const cleanNumericInput = (
return cleaned; return cleaned;
}; };
// Types
export type MaskType = 'currency' | 'weight' | 'decimal' | 'number';
export interface NumberInputProps {
label?: string;
bottomLabel?: string;
name: string;
value?: number | string;
placeholder?: string;
className?: {
wrapper?: string;
label?: string;
inputWrapper?: string;
input?: string;
};
isError?: boolean;
isValid?: boolean;
disabled?: boolean;
readOnly?: boolean;
required?: boolean;
isLoading?: boolean;
errorMessage?: string;
startAdornment?: ReactNode;
endAdornment?: ReactNode;
onChange?: ChangeEventHandler<HTMLInputElement>;
onBlur?: FocusEventHandler<HTMLInputElement>;
onFocus?: FocusEventHandler<HTMLInputElement>;
// Masking Options
maskType?: MaskType;
decimals?: number;
thousandSeparator?: string;
decimalSeparator?: string;
// Currency specific
currencyPrefix?: string;
// Weight specific
weightUnit?: string;
// Validation
min?: number;
max?: number;
allowNegative?: boolean;
// Stepper (Increment/Decrement buttons)
showSteppers?: boolean;
step?: number;
}
const NumberInput = ({ const NumberInput = ({
label, label,
bottomLabel, bottomLabel,
@@ -179,35 +182,20 @@ const NumberInput = ({
}: NumberInputProps) => { }: NumberInputProps) => {
const [displayValue, setDisplayValue] = useState<string>(''); const [displayValue, setDisplayValue] = useState<string>('');
// CONFIG & HELPERS // Determine if decimals are allowed based on maskType
const allowDecimal = const allowDecimal =
maskType === 'decimal' || maskType === 'weight' || decimals > 0; maskType === 'decimal' || maskType === 'weight' || decimals > 0;
const getInputPrefix = (): string => { // Format value for display based on maskType
switch (maskType) {
case 'currency':
return currencyPrefix;
default:
return '';
}
};
const getInputSuffix = (): string => {
switch (maskType) {
case 'weight':
return weightUnit;
default:
return '';
}
};
const getFormattedValue = (rawValue: number | string): string => { const getFormattedValue = (rawValue: number | string): string => {
if (rawValue === '' || rawValue === null || rawValue === undefined) if (rawValue === '' || rawValue === null || rawValue === undefined)
return ''; return '';
switch (maskType) { switch (maskType) {
case 'currency': case 'currency':
return formatCurrency(rawValue, currencyPrefix, decimals);
case 'weight': case 'weight':
return formatWeight(rawValue, weightUnit, decimals);
case 'decimal': case 'decimal':
case 'number': case 'number':
return formatNumber( return formatNumber(
@@ -221,14 +209,21 @@ const NumberInput = ({
} }
}; };
// EFFECTS // Initialize display value when value prop changes
useEffect(() => { useEffect(() => {
setDisplayValue(getFormattedValue(value || '')); setDisplayValue(getFormattedValue(value || ''));
}, [value]); }, [value]);
// EVENT HANDLERS
const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => { const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
const inputValue = e.target.value; let inputValue = e.target.value;
// Remove prefix/suffix for editing
if (maskType === 'currency' && inputValue.startsWith(currencyPrefix)) {
inputValue = inputValue.slice(currencyPrefix.length);
}
if (maskType === 'weight' && inputValue.endsWith(` ${weightUnit}`)) {
inputValue = inputValue.slice(0, -weightUnit.length - 1);
}
// Clean input // Clean input
const cleaned = cleanNumericInput( const cleaned = cleanNumericInput(
@@ -267,6 +262,7 @@ const NumberInput = ({
// Call onChange with modified event // Call onChange with modified event
if (onChange) { if (onChange) {
// Create a synthetic event with the numeric value
const syntheticEvent = { const syntheticEvent = {
...e, ...e,
target: { target: {
@@ -280,6 +276,7 @@ const NumberInput = ({
} }
}; };
// Handle Increment
const handleIncrement = () => { const handleIncrement = () => {
if (disabled || readOnly) return; if (disabled || readOnly) return;
@@ -317,6 +314,7 @@ const NumberInput = ({
} }
}; };
// Handle Decrement
const handleDecrement = () => { const handleDecrement = () => {
if (disabled || readOnly) return; if (disabled || readOnly) return;
@@ -357,12 +355,6 @@ const NumberInput = ({
} }
}; };
// RENDER CALCULATIONS
const showErrorMessage = Boolean(isError && errorMessage);
const feedbackMessage = showErrorMessage ? errorMessage : bottomLabel;
const inputPrefix = getInputPrefix();
const inputSuffix = getInputSuffix();
return ( return (
<div <div
className={cn( className={cn(
@@ -393,152 +385,84 @@ const NumberInput = ({
</label> </label>
)} )}
{/* Input Container */} <div
<div className='relative flex'> className={cn(
{/* Prefix Block */} 'input h-12 px-4 py-2 text-base font-normal leading-6 w-full rounded-lg! outline-none! transition-all duration-200',
{inputPrefix && ( {
<div 'border-error': isError,
'border-success!': isValid,
},
className?.inputWrapper
)}
>
{/* Decrement Button */}
{showSteppers && (
<button
type='button'
onClick={handleDecrement}
disabled={disabled || readOnly}
className={cn( className={cn(
'inline-flex items-center px-4 py-2 border border-r-0 rounded-l-md transition-all duration-200', 'btn btn-ghost btn-sm h-8 w-8 min-h-0 p-0 rounded-md',
{ {
'bg-gray-100 border-gray-300': !disabled, 'opacity-50 cursor-not-allowed': disabled || readOnly,
'bg-gray-50 border-gray-200': disabled,
} }
)} )}
tabIndex={-1}
> >
<span <Icon icon='ic:round-minus' width={20} height={20} />
className={cn( </button>
'text-sm font-medium select-none whitespace-nowrap', )}
{
'text-gray-600': !disabled, {startAdornment && startAdornment}
'text-gray-400': disabled,
} <input
)} type='text'
> id={name}
{inputPrefix} name={name}
</span> placeholder={placeholder}
value={displayValue}
onChange={handleInputChange}
onFocus={onFocus}
onBlur={onBlur}
disabled={disabled}
className={cn('grow', className?.input)}
readOnly={readOnly}
inputMode='decimal'
/>
{(isLoading || endAdornment) && (
<div className='flex flex-row gap-2'>
{isLoading && <span className='loading loading-spinner' />}
{endAdornment && endAdornment}
</div> </div>
)} )}
{/* Input Wrapper */} {/* Increment Button */}
<div {showSteppers && (
className={cn( <button
'input h-12 text-base font-normal leading-6 flex-1 rounded-lg! outline-none! transition-all duration-200 flex items-center bg-white', type='button'
{ onClick={handleIncrement}
'border-error': isError, disabled={disabled || readOnly}
'border-success!': isValid,
'rounded-l-none!': inputPrefix,
'rounded-r-none!': inputSuffix,
'input-disabled': disabled,
'cursor-not-allowed': disabled,
'bg-gray-50': disabled,
},
className?.inputWrapper
)}
>
{/* Stepper Buttons */}
{showSteppers && (
<button
type='button'
onClick={handleDecrement}
disabled={disabled || readOnly}
className={cn(
'btn btn-ghost btn-sm h-8 w-8 min-h-0 p-0 rounded-md',
{
'opacity-50 cursor-not-allowed': disabled || readOnly,
}
)}
tabIndex={-1}
>
<Icon icon='ic:round-minus' width={20} height={20} />
</button>
)}
{/* Start Adornment */}
{startAdornment && startAdornment}
{/* Main Input */}
<input
type='text'
id={name}
name={name}
placeholder={placeholder}
value={displayValue}
onChange={handleInputChange}
onFocus={onFocus}
onBlur={onBlur}
disabled={disabled}
className={cn( className={cn(
'grow bg-transparent outline-none', 'btn btn-ghost btn-sm h-8 w-8 min-h-0 p-0 rounded-md',
{ {
'cursor-not-allowed': disabled, 'opacity-50 cursor-not-allowed': disabled || readOnly,
'text-gray-500': disabled,
},
className?.input
)}
readOnly={readOnly}
inputMode='decimal'
/>
{/* End Adornment & Loading */}
{(isLoading || endAdornment) && (
<div className='flex flex-row gap-2'>
{isLoading && <span className='loading loading-spinner' />}
{endAdornment && endAdornment}
</div>
)}
{/* Increment Button */}
{showSteppers && (
<button
type='button'
onClick={handleIncrement}
disabled={disabled || readOnly}
className={cn(
'btn btn-ghost btn-sm h-8 w-8 min-h-0 p-0 rounded-md',
{
'opacity-50 cursor-not-allowed': disabled || readOnly,
}
)}
tabIndex={-1}
>
<Icon icon='ic:round-plus' width={20} height={20} />
</button>
)}
</div>
{/* Suffix Block */}
{inputSuffix && (
<div
className={cn(
'inline-flex items-center px-4 py-2 border border-l-0 rounded-r-md transition-all duration-200',
{
'bg-gray-100 border-gray-300': !disabled,
'bg-gray-50 border-gray-200': disabled,
} }
)} )}
tabIndex={-1}
> >
<span <Icon icon='ic:round-plus' width={20} height={20} />
className={cn( </button>
'text-sm font-medium select-none whitespace-nowrap',
{
'text-gray-600': !disabled,
'text-gray-400': disabled,
}
)}
>
{inputSuffix}
</span>
</div>
)} )}
</div> </div>
{/* Field Message */} {!isError && bottomLabel && (
<FieldMessage <p className='w-full text-sm opacity-60'>{bottomLabel}</p>
message={feedbackMessage} )}
tone={showErrorMessage ? 'error' : 'info'} {isError && errorMessage && (
isVisible={showErrorMessage || Boolean(bottomLabel)} <p className='w-full text-sm text-error'>{errorMessage}</p>
/> )}
</div> </div>
); );
}; };
+9 -8
View File
@@ -2,7 +2,6 @@
import { ChangeEventHandler, ReactNode } from 'react'; import { ChangeEventHandler, ReactNode } from 'react';
import { cn } from '@/lib/helper'; import { cn } from '@/lib/helper';
import FieldMessage from '@/components/helper/FieldMessage';
export interface RadioOption { export interface RadioOption {
label: string; label: string;
@@ -48,8 +47,6 @@ const RadioInput = ({
onChange, onChange,
onBlur, onBlur,
}: RadioInputProps) => { }: RadioInputProps) => {
const showErrorMessage = Boolean(isError && errorMessage);
const feedbackMessage = showErrorMessage ? errorMessage : bottomLabel;
return ( return (
<div className={cn('w-full flex flex-col gap-2', className?.wrapper)}> <div className={cn('w-full flex flex-col gap-2', className?.wrapper)}>
{/* Label atas */} {/* Label atas */}
@@ -100,11 +97,15 @@ const RadioInput = ({
))} ))}
</div> </div>
<FieldMessage {/* Label bawah */}
message={feedbackMessage} {!isError && bottomLabel && (
tone={showErrorMessage ? 'error' : 'info'} <p className='text-sm opacity-60'>{bottomLabel}</p>
isVisible={showErrorMessage || Boolean(bottomLabel)} )}
/>
{/* Pesan error */}
{isError && errorMessage && (
<p className='text-sm text-error'>{errorMessage}</p>
)}
</div> </div>
); );
}; };
+4 -9
View File
@@ -12,7 +12,6 @@ import CreatableSelect from 'react-select/creatable';
import makeAnimated from 'react-select/animated'; import makeAnimated from 'react-select/animated';
import { useDebounce } from 'use-debounce'; import { useDebounce } from 'use-debounce';
import { cn } from '@/lib/helper'; import { cn } from '@/lib/helper';
import FieldMessage from '@/components/helper/FieldMessage';
export interface OptionType { export interface OptionType {
value: string | number; value: string | number;
@@ -118,9 +117,6 @@ const SelectInput = <T extends OptionType>(props: SelectInputProps<T>) => {
} }
}; };
const showErrorMessage = Boolean(isError && errorMessage);
const feedbackMessage = showErrorMessage ? errorMessage : bottomLabel;
return ( return (
<div <div
className={cn( className={cn(
@@ -218,11 +214,10 @@ const SelectInput = <T extends OptionType>(props: SelectInputProps<T>) => {
}} }}
/> />
<FieldMessage {isError && <p className='w-full text-sm text-error'>{errorMessage}</p>}
message={feedbackMessage} {!isError && bottomLabel && (
tone={showErrorMessage ? 'error' : 'info'} <p className='w-full text-sm opacity-60'>{bottomLabel}</p>
isVisible={showErrorMessage || Boolean(bottomLabel)} )}
/>
</div> </div>
); );
}; };
+5 -9
View File
@@ -2,7 +2,6 @@
import React, { useState, KeyboardEvent, ChangeEvent, useEffect } from 'react'; import React, { useState, KeyboardEvent, ChangeEvent, useEffect } from 'react';
import { cn } from '@/lib/helper'; import { cn } from '@/lib/helper';
import FieldMessage from '@/components/helper/FieldMessage';
export interface TagInputProps { export interface TagInputProps {
label?: string; label?: string;
@@ -74,9 +73,6 @@ const TagInput: React.FC<TagInputProps> = ({
setInputValue(e.target.value); setInputValue(e.target.value);
}; };
const showErrorMessage = Boolean(isError && errorMessage);
const feedbackMessage = showErrorMessage ? errorMessage : bottomLabel;
return ( return (
<div <div
className={cn( className={cn(
@@ -161,11 +157,11 @@ const TagInput: React.FC<TagInputProps> = ({
)} )}
</div> </div>
<FieldMessage {/* Bottom label or error message */}
message={feedbackMessage} {!isError && bottomLabel && (
tone={showErrorMessage ? 'error' : 'info'} <p className='w-full text-sm opacity-60'>{bottomLabel}</p>
isVisible={showErrorMessage || Boolean(bottomLabel)} )}
/> {isError && <p className='w-full text-sm text-error'>{errorMessage}</p>}
</div> </div>
); );
}; };
+5 -10
View File
@@ -3,7 +3,6 @@
import { ChangeEventHandler, FocusEventHandler, ReactNode } from 'react'; import { ChangeEventHandler, FocusEventHandler, ReactNode } from 'react';
import { cn } from '@/lib/helper'; import { cn } from '@/lib/helper';
import FieldMessage from '@/components/helper/FieldMessage';
export interface TextAreaProps { export interface TextAreaProps {
label?: string; label?: string;
@@ -51,9 +50,6 @@ const TextArea = ({
isLoading = false, isLoading = false,
rows = 3, rows = 3,
}: TextAreaProps) => { }: TextAreaProps) => {
const showErrorMessage = Boolean(isError && errorMessage);
const feedbackMessage = showErrorMessage ? errorMessage : bottomLabel;
return ( return (
<div <div
className={cn( className={cn(
@@ -87,7 +83,7 @@ const TextArea = ({
<textarea <textarea
className={cn( className={cn(
'input h-auto px-4 py-2 text-base font-normal leading-6 w-full rounded-lg! outline-none! transition-all bg-white', 'input h-auto px-4 py-2 text-base font-normal leading-6 w-full rounded-lg! outline-none! transition-all',
{ {
'border-error': isError, 'border-error': isError,
'border-success!': isValid, 'border-success!': isValid,
@@ -113,11 +109,10 @@ const TextArea = ({
</div> </div>
)} )}
<FieldMessage {!isError && bottomLabel && (
message={feedbackMessage} <p className='w-full text-sm opacity-60'>{bottomLabel}</p>
tone={showErrorMessage ? 'error' : 'info'} )}
isVisible={showErrorMessage || Boolean(bottomLabel)} {isError && <p className='w-full text-sm text-error'>{errorMessage}</p>}
/>
</div> </div>
); );
}; };
+7 -10
View File
@@ -8,7 +8,6 @@ import {
} from 'react'; } from 'react';
import { cn } from '@/lib/helper'; import { cn } from '@/lib/helper';
import FieldMessage from '@/components/helper/FieldMessage';
export interface TextInputProps { export interface TextInputProps {
type?: HTMLInputTypeAttribute; type?: HTMLInputTypeAttribute;
@@ -56,9 +55,6 @@ const TextInput = ({
readOnly = false, readOnly = false,
isLoading = false, isLoading = false,
}: TextInputProps) => { }: TextInputProps) => {
const showErrorMessage = Boolean(isError && errorMessage);
const feedbackMessage = showErrorMessage ? errorMessage : bottomLabel;
return ( return (
<div <div
className={cn( className={cn(
@@ -91,7 +87,7 @@ const TextInput = ({
<div <div
className={cn( className={cn(
'input h-12 px-4 py-2 text-base font-normal leading-6 w-full rounded-lg! outline-none! transition-all duration-200 bg-white', 'input h-12 px-4 py-2 text-base font-normal leading-6 w-full rounded-lg! outline-none! transition-all duration-200',
{ {
'border-error': isError, 'border-error': isError,
'border-success!': isValid, 'border-success!': isValid,
@@ -123,11 +119,12 @@ const TextInput = ({
)} )}
</div> </div>
<FieldMessage {!isError && bottomLabel && (
message={feedbackMessage} <p className='w-full text-sm opacity-60'>{bottomLabel}</p>
tone={showErrorMessage ? 'error' : 'info'} )}
isVisible={showErrorMessage || Boolean(bottomLabel)} {isError && errorMessage && (
/> <p className='w-full text-sm text-error'>{errorMessage}</p>
)}
</div> </div>
); );
}; };
@@ -29,7 +29,6 @@ import { SupplierApi, WarehouseApi } from '@/services/api/master-data';
import { ProductWarehouseApi } from '@/services/api/inventory'; import { ProductWarehouseApi } from '@/services/api/inventory';
import { toast } from 'react-hot-toast'; import { toast } from 'react-hot-toast';
import FileInput from '@/components/input/FileInput'; import FileInput from '@/components/input/FileInput';
import FieldMessage from '@/components/helper/FieldMessage';
import CheckboxInput from '@/components/input/CheckboxInput'; import CheckboxInput from '@/components/input/CheckboxInput';
interface MovementFormProps { interface MovementFormProps {
@@ -910,7 +909,6 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
naked={true} naked={true}
size='sm' size='sm'
/> />
<FieldMessage message={null} isVisible={false} />
</div> </div>
</td> </td>
)} )}
@@ -1006,7 +1004,6 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
height={24} height={24}
/> />
</Button> </Button>
<FieldMessage message={null} isVisible={false} />
</div> </div>
</td> </td>
)} )}
@@ -1174,7 +1171,6 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
naked={true} naked={true}
size='sm' size='sm'
/> />
<FieldMessage message={null} isVisible={false} />
</div> </div>
</td> </td>
)} )}
@@ -1323,10 +1319,6 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
'-' '-'
)} )}
</Button> </Button>
<FieldMessage
message={null}
isVisible={false}
/>
</div> </div>
</> </>
) : ( ) : (
@@ -1444,7 +1436,6 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
height={24} height={24}
/> />
</Button> </Button>
<FieldMessage message={null} isVisible={false} />
</div> </div>
</td> </td>
)} )}
@@ -30,7 +30,6 @@ import { ProductWarehouseApi } from '@/services/api/inventory';
import { ProjectFlock } from '@/types/api/production/project-flock'; import { ProjectFlock } from '@/types/api/production/project-flock';
import { Warehouse } from '@/types/api/master-data/warehouse'; import { Warehouse } from '@/types/api/master-data/warehouse';
import { LocationApi } from '@/services/api/master-data'; import { LocationApi } from '@/services/api/master-data';
import FieldMessage from '@/components/helper/FieldMessage';
import Card from '@/components/Card'; import Card from '@/components/Card';
interface RecordingFormProps { interface RecordingFormProps {
@@ -829,7 +828,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
naked={true} naked={true}
size='sm' size='sm'
/> />
<FieldMessage message={null} isVisible={false} />
</div> </div>
</td> </td>
)} )}
@@ -948,7 +946,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
height={24} height={24}
/> />
</Button> </Button>
<FieldMessage message={null} isVisible={false} />
</div> </div>
</td> </td>
)} )}
@@ -1078,7 +1075,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
naked={true} naked={true}
size='sm' size='sm'
/> />
<FieldMessage message={null} isVisible={false} />
</div> </div>
</td> </td>
)} )}
@@ -1191,7 +1187,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
height={24} height={24}
/> />
</Button> </Button>
<FieldMessage message={null} isVisible={false} />
</div> </div>
</td> </td>
)} )}
@@ -1313,7 +1308,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
naked={true} naked={true}
size='sm' size='sm'
/> />
<FieldMessage message={null} isVisible={false} />
</div> </div>
</td> </td>
)} )}
@@ -1448,7 +1442,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
height={24} height={24}
/> />
</Button> </Button>
<FieldMessage message={null} isVisible={false} />
</div> </div>
</td> </td>
)} )}
@@ -1572,7 +1565,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
naked={true} naked={true}
size='sm' size='sm'
/> />
<FieldMessage message={null} isVisible={false} />
</div> </div>
</td> </td>
)} )}
@@ -1646,7 +1638,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
height={24} height={24}
/> />
</Button> </Button>
<FieldMessage message={null} isVisible={false} />
</div> </div>
</td> </td>
)} )}
+4
View File
@@ -8,4 +8,8 @@
--step-bg: var(--color-error); --step-bg: var(--color-error);
--step-fg: var(--color-error-content); --step-fg: var(--color-error-content);
} }
.table :where(th, td) {
vertical-align: top;
}
} }