feat!: store array values as actual array value (#3442)
This commit is contained in:
@@ -66,7 +66,7 @@ export const ArrayAction: React.FC<Props> = ({
|
||||
<PopupList.Button
|
||||
className={`${baseClass}__action ${baseClass}__add`}
|
||||
onClick={() => {
|
||||
addRow(index + 1)
|
||||
addRow(index)
|
||||
close()
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -140,8 +140,8 @@ export const addFieldStatePromise = async ({
|
||||
fieldState.value = null
|
||||
fieldState.initialValue = null
|
||||
} else {
|
||||
fieldState.value = arrayValue.length
|
||||
fieldState.initialValue = arrayValue.length
|
||||
fieldState.value = arrayValue
|
||||
fieldState.initialValue = arrayValue
|
||||
|
||||
if (arrayValue.length > 0) {
|
||||
fieldState.disableFormData = true
|
||||
@@ -230,8 +230,8 @@ export const addFieldStatePromise = async ({
|
||||
fieldState.value = null
|
||||
fieldState.initialValue = null
|
||||
} else {
|
||||
fieldState.value = blocksValue.length
|
||||
fieldState.initialValue = blocksValue.length
|
||||
fieldState.value = blocksValue
|
||||
fieldState.initialValue = blocksValue
|
||||
|
||||
if (blocksValue.length > 0) {
|
||||
fieldState.disableFormData = true
|
||||
|
||||
@@ -123,7 +123,7 @@ export function fieldReducer(state: Fields, action: FieldAction): Fields {
|
||||
...state[path],
|
||||
disableFormData: rows.length > 0,
|
||||
rows: rowsMetadata,
|
||||
value: rows.length,
|
||||
value: rows,
|
||||
},
|
||||
...flattenRows(path, rows),
|
||||
}
|
||||
@@ -136,7 +136,7 @@ export function fieldReducer(state: Fields, action: FieldAction): Fields {
|
||||
|
||||
const rowsMetadata = [...(state[path]?.rows || [])]
|
||||
rowsMetadata.splice(
|
||||
rowIndex + 1,
|
||||
rowIndex,
|
||||
0,
|
||||
// new row
|
||||
{
|
||||
@@ -158,7 +158,7 @@ export function fieldReducer(state: Fields, action: FieldAction): Fields {
|
||||
const { remainingFields, rows } = separateRows(path, state)
|
||||
|
||||
// actual form state (value saved in db)
|
||||
rows.splice(rowIndex + 1, 0, subFieldState)
|
||||
rows.splice(rowIndex, 0, subFieldState)
|
||||
|
||||
const newState: Fields = {
|
||||
...remainingFields,
|
||||
@@ -167,7 +167,7 @@ export function fieldReducer(state: Fields, action: FieldAction): Fields {
|
||||
...state[path],
|
||||
disableFormData: true,
|
||||
rows: rowsMetadata,
|
||||
value: rows.length,
|
||||
value: rows,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ export function fieldReducer(state: Fields, action: FieldAction): Fields {
|
||||
...state[path],
|
||||
disableFormData: true,
|
||||
rows: rowsMetadata,
|
||||
value: rows.length,
|
||||
value: rows,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ export function fieldReducer(state: Fields, action: FieldAction): Fields {
|
||||
...state[path],
|
||||
disableFormData: true,
|
||||
rows: rowsMetadata,
|
||||
value: rows.length,
|
||||
value: rows,
|
||||
},
|
||||
...flattenRows(path, rows),
|
||||
}
|
||||
|
||||
@@ -463,7 +463,7 @@ const Form: React.FC<Props> = (props) => {
|
||||
dispatchFields({
|
||||
blockType: data?.blockType,
|
||||
path,
|
||||
rowIndex: rowIndex - 1,
|
||||
rowIndex,
|
||||
subFieldState,
|
||||
type: 'ADD_ROW',
|
||||
})
|
||||
@@ -501,7 +501,7 @@ const Form: React.FC<Props> = (props) => {
|
||||
dispatchFields({
|
||||
blockType: data?.blockType,
|
||||
path,
|
||||
rowIndex: rowIndex - 1,
|
||||
rowIndex,
|
||||
subFieldState,
|
||||
type: 'REPLACE_ROW',
|
||||
})
|
||||
|
||||
@@ -20,9 +20,9 @@ import { useForm, useFormSubmitted } from '../../Form/context'
|
||||
import { NullifyLocaleField } from '../../NullifyField'
|
||||
import useField from '../../useField'
|
||||
import withCondition from '../../withCondition'
|
||||
import { fieldBaseClass } from '../shared'
|
||||
import { ArrayRow } from './ArrayRow'
|
||||
import './index.scss'
|
||||
import { fieldBaseClass } from '../shared'
|
||||
|
||||
const baseClass = 'array-field'
|
||||
|
||||
@@ -91,7 +91,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {
|
||||
showError,
|
||||
valid,
|
||||
value,
|
||||
} = useField<number>({
|
||||
} = useField<[]>({
|
||||
condition,
|
||||
hasRows: true,
|
||||
path,
|
||||
@@ -111,20 +111,20 @@ const ArrayFieldType: React.FC<Props> = (props) => {
|
||||
)
|
||||
|
||||
const duplicateRow = useCallback(
|
||||
async (rowIndex: number) => {
|
||||
(rowIndex: number) => {
|
||||
dispatchFields({ path, rowIndex, type: 'DUPLICATE_ROW' })
|
||||
setModified(true)
|
||||
|
||||
setTimeout(() => {
|
||||
scrollToID(`${path}-row-${rowIndex + 1}`)
|
||||
scrollToID(`${path}-row-${rowIndex}`)
|
||||
}, 0)
|
||||
},
|
||||
[dispatchFields, path, setModified],
|
||||
)
|
||||
|
||||
const removeRow = useCallback(
|
||||
(rowIndex: number) => {
|
||||
removeFieldRow({ path, rowIndex })
|
||||
async (rowIndex: number) => {
|
||||
await removeFieldRow({ path, rowIndex })
|
||||
setModified(true)
|
||||
},
|
||||
[removeFieldRow, path, setModified],
|
||||
@@ -139,14 +139,14 @@ const ArrayFieldType: React.FC<Props> = (props) => {
|
||||
)
|
||||
|
||||
const toggleCollapseAll = useCallback(
|
||||
async (collapsed: boolean) => {
|
||||
(collapsed: boolean) => {
|
||||
dispatchFields({ collapsed, path, setDocFieldPreferences, type: 'SET_ALL_ROWS_COLLAPSED' })
|
||||
},
|
||||
[dispatchFields, path, setDocFieldPreferences],
|
||||
)
|
||||
|
||||
const setCollapse = useCallback(
|
||||
async (rowID: string, collapsed: boolean) => {
|
||||
(rowID: string, collapsed: boolean) => {
|
||||
dispatchFields({ collapsed, path, rowID, setDocFieldPreferences, type: 'SET_ROW_COLLAPSED' })
|
||||
},
|
||||
[dispatchFields, path, setDocFieldPreferences],
|
||||
@@ -274,11 +274,11 @@ const ArrayFieldType: React.FC<Props> = (props) => {
|
||||
{!readOnly && !hasMaxRows && (
|
||||
<Button
|
||||
buttonStyle="icon-label"
|
||||
className={`${baseClass}__add-row`}
|
||||
icon="plus"
|
||||
iconPosition="left"
|
||||
iconStyle="with-border"
|
||||
onClick={() => addRow(value)}
|
||||
className={`${baseClass}__add-row`}
|
||||
onClick={() => addRow(value?.length || 0)}
|
||||
>
|
||||
{t('addLabel', { label: getTranslation(labels.singular, i18n) })}
|
||||
</Button>
|
||||
|
||||
@@ -90,7 +90,7 @@ const BlocksField: React.FC<Props> = (props) => {
|
||||
showError,
|
||||
valid,
|
||||
value,
|
||||
} = useField<number>({
|
||||
} = useField<[]>({
|
||||
condition,
|
||||
hasRows: true,
|
||||
path,
|
||||
@@ -99,7 +99,7 @@ const BlocksField: React.FC<Props> = (props) => {
|
||||
|
||||
const addRow = useCallback(
|
||||
async (rowIndex: number, blockType: string) => {
|
||||
addFieldRow({
|
||||
await addFieldRow({
|
||||
data: {
|
||||
blockType,
|
||||
},
|
||||
@@ -116,7 +116,7 @@ const BlocksField: React.FC<Props> = (props) => {
|
||||
)
|
||||
|
||||
const duplicateRow = useCallback(
|
||||
async (rowIndex: number) => {
|
||||
(rowIndex: number) => {
|
||||
dispatchFields({ path, rowIndex, type: 'DUPLICATE_ROW' })
|
||||
setModified(true)
|
||||
|
||||
@@ -128,8 +128,8 @@ const BlocksField: React.FC<Props> = (props) => {
|
||||
)
|
||||
|
||||
const removeRow = useCallback(
|
||||
(rowIndex: number) => {
|
||||
removeFieldRow({ path, rowIndex })
|
||||
async (rowIndex: number) => {
|
||||
await removeFieldRow({ path, rowIndex })
|
||||
setModified(true)
|
||||
},
|
||||
[path, removeFieldRow, setModified],
|
||||
@@ -144,14 +144,14 @@ const BlocksField: React.FC<Props> = (props) => {
|
||||
)
|
||||
|
||||
const toggleCollapseAll = useCallback(
|
||||
async (collapsed: boolean) => {
|
||||
(collapsed: boolean) => {
|
||||
dispatchFields({ collapsed, path, setDocFieldPreferences, type: 'SET_ALL_ROWS_COLLAPSED' })
|
||||
},
|
||||
[dispatchFields, path, setDocFieldPreferences],
|
||||
)
|
||||
|
||||
const setCollapse = useCallback(
|
||||
async (rowID: string, collapsed: boolean) => {
|
||||
(rowID: string, collapsed: boolean) => {
|
||||
dispatchFields({ collapsed, path, rowID, setDocFieldPreferences, type: 'SET_ROW_COLLAPSED' })
|
||||
},
|
||||
[dispatchFields, path, setDocFieldPreferences],
|
||||
@@ -297,7 +297,7 @@ const BlocksField: React.FC<Props> = (props) => {
|
||||
</DrawerToggler>
|
||||
<BlocksDrawer
|
||||
addRow={addRow}
|
||||
addRowIndex={value}
|
||||
addRowIndex={value?.length || 0}
|
||||
blocks={blocks}
|
||||
drawerSlug={drawerSlug}
|
||||
labels={labels}
|
||||
|
||||
@@ -92,14 +92,9 @@ export const promise = async ({
|
||||
|
||||
// Validate
|
||||
if (!skipValidationFromHere && field.validate) {
|
||||
let valueToValidate = siblingData[field.name]
|
||||
const valueToValidate = siblingData[field.name]
|
||||
let jsonError
|
||||
|
||||
if (['array', 'blocks'].includes(field.type)) {
|
||||
const rows = siblingData[field.name]
|
||||
valueToValidate = Array.isArray(rows) ? rows.length : 0
|
||||
}
|
||||
|
||||
if (field.type === 'json' && typeof siblingData[field.name] === 'string') {
|
||||
try {
|
||||
JSON.parse(siblingData[field.name] as string)
|
||||
|
||||
@@ -389,15 +389,17 @@ export const array: Validate<unknown, unknown, ArrayField> = (
|
||||
value,
|
||||
{ maxRows, minRows, required, t },
|
||||
) => {
|
||||
if (minRows && value < minRows) {
|
||||
const arrayLength = Array.isArray(value) ? value.length : 0
|
||||
|
||||
if (minRows && arrayLength < minRows) {
|
||||
return t('validation:requiresAtLeast', { count: minRows, label: t('rows') })
|
||||
}
|
||||
|
||||
if (maxRows && value > maxRows) {
|
||||
if (maxRows && arrayLength > maxRows) {
|
||||
return t('validation:requiresNoMoreThan', { count: maxRows, label: t('rows') })
|
||||
}
|
||||
|
||||
if (!value && required) {
|
||||
if (!arrayLength && required) {
|
||||
return t('validation:requiresAtLeast', { count: 1, label: t('row') })
|
||||
}
|
||||
|
||||
@@ -456,15 +458,17 @@ export const blocks: Validate<unknown, unknown, BlockField> = (
|
||||
value,
|
||||
{ maxRows, minRows, required, t },
|
||||
) => {
|
||||
if (minRows && value < minRows) {
|
||||
const arrayLength = Array.isArray(value) ? value.length : 0
|
||||
|
||||
if (minRows && arrayLength < minRows) {
|
||||
return t('validation:requiresAtLeast', { count: minRows, label: t('rows') })
|
||||
}
|
||||
|
||||
if (maxRows && value > maxRows) {
|
||||
if (maxRows && arrayLength > maxRows) {
|
||||
return t('validation:requiresNoMoreThan', { count: maxRows, label: t('rows') })
|
||||
}
|
||||
|
||||
if (!value && required) {
|
||||
if (!arrayLength && required) {
|
||||
return t('validation:requiresAtLeast', { count: 1, label: t('row') })
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export const AddCustomBlocks: React.FC = () => {
|
||||
const { addFieldRow, replaceFieldRow } = useForm()
|
||||
const { value } = useField({ path: 'customBlocks' })
|
||||
|
||||
const nextIndex = typeof value === 'number' ? value + 1 : 0
|
||||
const nextIndex = Array.isArray(value) ? value.length : 0
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
@@ -56,7 +56,7 @@ export const AddCustomBlocks: React.FC = () => {
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
Replace Block {nextIndex - 1}
|
||||
Replace Block {nextIndex}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user