Skip to content

Commit

Permalink
feat: add isSortable to arrays and blocks (#5962)
Browse files Browse the repository at this point in the history
  • Loading branch information
kendelljoseph committed May 3, 2024
1 parent 23f3eb1 commit 5c58bd3
Show file tree
Hide file tree
Showing 16 changed files with 82 additions and 10 deletions.
1 change: 1 addition & 0 deletions docs/fields/array.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ properties:
| Option | Description |
|---------------------------|----------------------------------------------------------------------------------------------------------------------|
| **`initCollapsed`** | Set the initial collapsed state |
| **`isSortable`** | Disable order sorting by setting this value to `false` |
| **`components.RowLabel`** | Function or React component to be rendered as the label on the array row. Receives `({ data, index, path })` as args |

### Example
Expand Down
1 change: 1 addition & 0 deletions docs/fields/blocks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ properties:
| Option | Description |
|---------------------|---------------------------------|
| **`initCollapsed`** | Set the initial collapsed state |
| **`isSortable`** | Disable order sorting by setting this value to `false` |

### Block configs

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const ArrayAction: React.FC<Props> = ({
duplicateRow,
hasMaxRows,
index,
isSortable,
moveRow,
removeRow,
rowCount,
Expand All @@ -33,7 +34,7 @@ export const ArrayAction: React.FC<Props> = ({
render={({ close }) => {
return (
<PopupList.ButtonGroup buttonSize="small">
{index !== 0 && (
{isSortable && index !== 0 && (
<PopupList.Button
className={`${baseClass}__action ${baseClass}__move-up`}
onClick={() => {
Expand All @@ -47,7 +48,7 @@ export const ArrayAction: React.FC<Props> = ({
{t('moveUp')}
</PopupList.Button>
)}
{index < rowCount - 1 && (
{isSortable && index < rowCount - 1 && (
<PopupList.Button
className={`${baseClass}__action`}
onClick={() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export type Props = {
duplicateRow: (current: number) => void
hasMaxRows: boolean
index: number
isSortable: boolean
moveRow: (from: number, to: number) => void
removeRow: (index: number) => void
rowCount: number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type ArrayRowProps = UseDraggableSortableReturn &
duplicateRow: (rowIndex: number) => void
forceRender?: boolean
hasMaxRows?: boolean
isSortable: boolean
moveRow: (fromIndex: number, toIndex: number) => void
readOnly?: boolean
removeRow: (rowIndex: number) => void
Expand All @@ -44,6 +45,7 @@ export const ArrayRow: React.FC<ArrayRowProps> = ({
forceRender = false,
hasMaxRows,
indexPath,
isSortable,
labels,
listeners,
moveRow,
Expand Down Expand Up @@ -94,6 +96,7 @@ export const ArrayRow: React.FC<ArrayRowProps> = ({
duplicateRow={duplicateRow}
hasMaxRows={hasMaxRows}
index={rowIndex}
isSortable={isSortable}
moveRow={moveRow}
removeRow={removeRow}
rowCount={rowCount}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const baseClass = 'array-field'
const ArrayFieldType: React.FC<Props> = (props) => {
const {
name,
admin: { className, components, condition, description, readOnly },
admin: { className, components, condition, description, isSortable = true, readOnly },
fieldTypes,
fields,
forceRender = false,
Expand Down Expand Up @@ -113,7 +113,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {

const duplicateRow = useCallback(
(rowIndex: number) => {
dispatchFields({ path, rowIndex, type: 'DUPLICATE_ROW' })
dispatchFields({ type: 'DUPLICATE_ROW', path, rowIndex })
setModified(true)

setTimeout(() => {
Expand All @@ -133,22 +133,22 @@ const ArrayFieldType: React.FC<Props> = (props) => {

const moveRow = useCallback(
(moveFromIndex: number, moveToIndex: number) => {
dispatchFields({ moveFromIndex, moveToIndex, path, type: 'MOVE_ROW' })
dispatchFields({ type: 'MOVE_ROW', moveFromIndex, moveToIndex, path })
setModified(true)
},
[dispatchFields, path, setModified],
)

const toggleCollapseAll = useCallback(
(collapsed: boolean) => {
dispatchFields({ collapsed, path, setDocFieldPreferences, type: 'SET_ALL_ROWS_COLLAPSED' })
dispatchFields({ type: 'SET_ALL_ROWS_COLLAPSED', collapsed, path, setDocFieldPreferences })
},
[dispatchFields, path, setDocFieldPreferences],
)

const setCollapse = useCallback(
(rowID: string, collapsed: boolean) => {
dispatchFields({ collapsed, path, rowID, setDocFieldPreferences, type: 'SET_ROW_COLLAPSED' })
dispatchFields({ type: 'SET_ROW_COLLAPSED', collapsed, path, rowID, setDocFieldPreferences })
},
[dispatchFields, path, setDocFieldPreferences],
)
Expand Down Expand Up @@ -227,7 +227,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {
onDragEnd={({ moveFromIndex, moveToIndex }) => moveRow(moveFromIndex, moveToIndex)}
>
{rows.map((row, i) => (
<DraggableSortableItem disabled={readOnly} id={row.id} key={row.id}>
<DraggableSortableItem disabled={readOnly || !isSortable} id={row.id} key={row.id}>
{(draggableSortableItemProps) => (
<ArrayRow
{...draggableSortableItemProps}
Expand All @@ -239,6 +239,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {
forceRender={forceRender}
hasMaxRows={hasMaxRows}
indexPath={indexPath}
isSortable={isSortable}
labels={labels}
moveRow={moveRow}
path={path}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type BlockFieldProps = UseDraggableSortableReturn &
duplicateRow: (rowIndex: number) => void
forceRender?: boolean
hasMaxRows?: boolean
isSortable?: boolean
moveRow: (fromIndex: number, toIndex: number) => void
readOnly: boolean
removeRow: (rowIndex: number) => void
Expand All @@ -44,6 +45,7 @@ export const BlockRow: React.FC<BlockFieldProps> = ({
forceRender,
hasMaxRows,
indexPath,
isSortable,
labels,
listeners,
moveRow,
Expand Down Expand Up @@ -90,6 +92,7 @@ export const BlockRow: React.FC<BlockFieldProps> = ({
blocks={blocks}
duplicateRow={duplicateRow}
hasMaxRows={hasMaxRows}
isSortable={isSortable}
labels={labels}
moveRow={moveRow}
removeRow={removeRow}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const RowActions: React.FC<{
blocks: Block[]
duplicateRow: (rowIndex: number, blockType: string) => void
hasMaxRows?: boolean
isSortable?: boolean
labels: Labels
moveRow: (fromIndex: number, toIndex: number) => void
removeRow: (rowIndex: number) => void
Expand All @@ -25,6 +26,7 @@ export const RowActions: React.FC<{
blocks,
duplicateRow,
hasMaxRows,
isSortable,
labels,
moveRow,
removeRow,
Expand Down Expand Up @@ -59,6 +61,7 @@ export const RowActions: React.FC<{
duplicateRow={() => duplicateRow(rowIndex, blockType)}
hasMaxRows={hasMaxRows}
index={rowIndex}
isSortable={isSortable}
moveRow={moveRow}
removeRow={removeRow}
rowCount={rowCount}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const BlocksField: React.FC<Props> = (props) => {

const {
name,
admin: { className, condition, description, readOnly },
admin: { className, condition, description, isSortable = true, readOnly },
blocks,
fieldTypes,
forceRender = false,
Expand Down Expand Up @@ -230,7 +230,7 @@ const BlocksField: React.FC<Props> = (props) => {

if (blockToRender) {
return (
<DraggableSortableItem disabled={readOnly} id={row.id} key={row.id}>
<DraggableSortableItem disabled={readOnly || !isSortable} id={row.id} key={row.id}>
{(draggableSortableItemProps) => (
<BlockRow
{...draggableSortableItemProps}
Expand All @@ -242,6 +242,7 @@ const BlocksField: React.FC<Props> = (props) => {
forceRender={forceRender}
hasMaxRows={hasMaxRows}
indexPath={indexPath}
isSortable={isSortable}
labels={labels}
moveRow={moveRow}
path={path}
Expand Down
6 changes: 6 additions & 0 deletions packages/payload/src/fields/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ export const array = baseField.keys({
RowLabel: componentSchema,
})
.default({}),
isSortable: joi.boolean(),
})
.default({}),
dbName: joi.alternatives().try(joi.string(), joi.func()),
Expand Down Expand Up @@ -408,6 +409,11 @@ export const relationship = baseField.keys({
export const blocks = baseField.keys({
name: joi.string().required(),
type: joi.string().valid('blocks').required(),
admin: baseAdminFields
.keys({
isSortable: joi.boolean(),
})
.default({}),
blocks: joi
.array()
.items(
Expand Down
8 changes: 8 additions & 0 deletions packages/payload/src/fields/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,10 @@ export type ArrayField = FieldBase & {
RowLabel?: RowLabel
} & Admin['components']
initCollapsed?: boolean | false
/**
* Disable drag and drop sorting
*/
isSortable?: boolean
}
/**
* Customize the SQL table name
Expand Down Expand Up @@ -631,6 +635,10 @@ export type Block = {
export type BlockField = FieldBase & {
admin?: Admin & {
initCollapsed?: boolean | false
/**
* Disable drag and drop sorting
*/
isSortable?: boolean
}
blocks: Block[]
defaultValue?: unknown
Expand Down
15 changes: 15 additions & 0 deletions test/fields/collections/Array/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@ const ArrayFields: CollectionConfig = {
minRows: 2,
type: 'array',
},
{
name: 'disableSortItems',
defaultValue: arrayDefaultValue,
admin: {
isSortable: false,
},
fields: [
{
name: 'text',
required: true,
type: 'text',
},
],
type: 'array',
},
],
slug: arrayFieldsSlug,
versions: true,
Expand Down
11 changes: 11 additions & 0 deletions test/fields/collections/Array/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,15 @@ export const anotherArrayDoc: Partial<ArrayField> = {
text: 'second row',
},
],
disableSortItems: [
{
text: 'un-sortable item 1',
},
{
text: 'un-sortable item 2',
},
{
text: 'un-sortable item 3',
},
],
}
1 change: 1 addition & 0 deletions test/fields/collections/Blocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ const BlockFields: CollectionConfig = {
name: 'collapsedByDefaultBlocks',
admin: {
initCollapsed: true,
isSortable: false,
},
localized: true,
},
Expand Down
12 changes: 12 additions & 0 deletions test/fields/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,12 @@ describe('fields', () => {
})
})
})

test('should have disabled admin sorting', async () => {
await page.goto(url.create)
const field = page.locator('#field-collapsedByDefaultBlocks .array-actions__action-chevron')
expect(await field.count()).toEqual(0)
})
})

describe('array', () => {
Expand All @@ -716,6 +722,12 @@ describe('fields', () => {
await expect(field).toHaveValue('defaultValue')
})

test('should have disabled admin sorting', async () => {
await page.goto(url.create)
const field = page.locator('#field-disableSortItems .array-actions__action-chevron')
expect(await field.count()).toEqual(0)
})

test('should render RowLabel using a function', async () => {
const label = 'custom row label as function'
await page.goto(url.create)
Expand Down
4 changes: 4 additions & 0 deletions test/fields/payload-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ export interface ArrayField {
id?: string | null
}[]
| null
disableSortItems?: {
text: string
id?: string | null
}[]
updatedAt: string
createdAt: string
}
Expand Down

0 comments on commit 5c58bd3

Please sign in to comment.