Skip to content

Commit e17fd1e

Browse files
committed
fix(entities-plugins): freeform - default card appearance for record array
1 parent e714398 commit e17fd1e

File tree

5 files changed

+81
-67
lines changed

5 files changed

+81
-67
lines changed

packages/entities/entities-plugins/fixtures/schemas/free-form-mocking.ts

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -216,20 +216,18 @@ export function buildEnumFieldCases(): Array<{ [name: string]: StringFieldSchema
216216
default: 'option2',
217217
},
218218
},
219-
// fixme: this has a bug in number options
220-
// {
221-
// enum_number: {
222-
// type: 'number',
223-
// one_of: [1, 2, 3],
224-
// },
225-
// },
226-
// fixme: this has a bug in boolean options
227-
// {
228-
// enum_boolean: {
229-
// type: 'boolean',
230-
// one_of: [true, false],
231-
// },
232-
// },
219+
{
220+
enum_number: {
221+
type: 'number',
222+
one_of: [1, 2, 3],
223+
},
224+
},
225+
{
226+
enum_boolean: {
227+
type: 'boolean',
228+
one_of: [true, false],
229+
},
230+
},
233231
]
234232
}
235233

@@ -278,23 +276,22 @@ export function buildArrayFieldCases(): Array<{ [name: string]: ArrayLikeFieldSc
278276
default: [0],
279277
},
280278
},
281-
// fixme: should support `resetLabelPath` in tests
282-
// {
283-
// array_of_records: {
284-
// type: 'array',
285-
// elements: {
286-
// type: 'record',
287-
// fields: [
288-
// {
289-
// foo: {
290-
// type: 'string',
291-
// },
292-
// },
293-
// ],
294-
// },
295-
// description: 'An array of records',
296-
// },
297-
// },
279+
{
280+
array_of_records: {
281+
type: 'array',
282+
elements: {
283+
type: 'record',
284+
fields: [
285+
{
286+
foo: {
287+
type: 'string',
288+
},
289+
},
290+
],
291+
},
292+
description: 'An array of records',
293+
},
294+
},
298295
{
299296
array_of_array: {
300297
type: 'array',

packages/entities/entities-plugins/src/components/free-form/RequestCallout/ConfigForm.vue

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,6 @@
2222
:placeholder="t('plugins.free-form.request-callout.by_lua_placeholder')"
2323
/>
2424
</FieldRenderer>
25-
26-
<!-- Set appearance to `cluster_nodes` and `sentinel_nodes` -->
27-
<FieldRenderer
28-
v-slot="props"
29-
:match="({ path }) => ['cluster_nodes', 'sentinel_nodes']
30-
.some(n => path.endsWith(n))"
31-
>
32-
<ArrayField
33-
v-bind="props"
34-
appearance="card"
35-
/>
36-
</FieldRenderer>
3725
</template>
3826

3927
<ObjectField
@@ -44,15 +32,11 @@
4432
<CalloutsForm />
4533

4634
<ObjectField
47-
appearance="card"
4835
:fields-order="['headers', 'query', 'body', 'by_lua']"
4936
name="upstream"
5037
/>
5138

52-
<ObjectField
53-
appearance="card"
54-
name="cache"
55-
>
39+
<ObjectField name="cache">
5640
<template #[`redis`]="props">
5741
<ObjectField
5842
v-bind="props"
@@ -75,7 +59,6 @@
7559
import { cloneDeep } from 'lodash-es'
7660
import { FIELD_RENDERERS } from '../shared/composables'
7761
import { getCalloutId } from './utils'
78-
import ArrayField from '../shared/ArrayField.vue'
7962
import CalloutsForm from './CalloutsForm.vue'
8063
import FieldRenderer from '../shared/FieldRenderer.vue'
8164
import Form from '../shared/Form.vue'

packages/entities/entities-plugins/src/components/free-form/shared/ArrayField.vue

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,14 @@ const realItems = computed(() => props.items ?? toValue(fieldValue) ?? [])
198198
199199
const { getKey } = useItemKeys('ff-array-field', realItems)
200200
201-
const ListTag = computed(() => props.appearance === 'card' ? KCard : 'div')
201+
const isRecordArray = computed(() => subSchema.value.type === 'record')
202+
const appearance = computed(() => {
203+
if (props.appearance) return props.appearance
204+
if (isRecordArray.value) return 'card'
205+
return 'default'
206+
})
207+
208+
const ListTag = computed(() => appearance.value === 'card' ? KCard : 'div')
202209
203210
function getTabTitle(item: T, index: number) {
204211
return typeof props.itemLabel === 'function'
@@ -227,7 +234,7 @@ const addItem = async () => {
227234
fieldValue!.value.push(defaultItemValue)
228235
emit('add')
229236
230-
if (props.appearance === 'tabs') {
237+
if (appearance.value === 'tabs') {
231238
await nextTick()
232239
activeTab.value = tabs.value[tabs.value.length - 1]?.hash
233240
}
@@ -242,7 +249,7 @@ const removeItem = async (index: number) => {
242249
}
243250
emit('remove', index)
244251
245-
if (props.appearance === 'tabs') {
252+
if (appearance.value === 'tabs') {
246253
activeTab.value = tabs.value[Math.max(0, index - 1)]?.hash
247254
}
248255
}
@@ -261,8 +268,8 @@ function focus(index: number) {
261268
}
262269
263270
const stickyTop = computed(() => {
264-
const { appearance, stickyTabs } = props
265-
if (appearance !== 'tabs' || stickyTabs == null || stickyTabs === false) {
271+
const { stickyTabs } = props
272+
if (appearance.value !== 'tabs' || stickyTabs == null || stickyTabs === false) {
266273
return null
267274
}
268275

packages/entities/entities-plugins/src/components/free-form/shared/ObjectField.vue

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111
<!-- only render children, no wrapper -->
1212
<template v-else-if="asChild">
13-
<div
13+
<component
14+
:is="wrapper"
1415
class="ff-object-field ff-object-field-as-child"
1516
v-bind="$attrs"
1617
:data-testid="`ff-object-${field.path.value}`"
@@ -22,11 +23,12 @@
2223
:name="Object.keys(cfield)[0]"
2324
/>
2425
</slot>
25-
</div>
26+
</component>
2627
</template>
2728

2829
<!-- render children with wrapper -->
29-
<div
30+
<component
31+
:is="wrapper"
3032
v-else
3133
class="ff-object-field"
3234
:class="{ 'ff-object-field-collapsed': !realExpanded }"
@@ -99,7 +101,7 @@
99101
</slot>
100102
</div>
101103
</SlideTransition>
102-
</div>
104+
</component>
103105
</template>
104106

105107
<script setup lang="ts">
@@ -120,7 +122,7 @@ defineOptions({
120122
const {
121123
defaultExpanded = true, defaultAdded = true, collapsible = true, omit,
122124
required = undefined, asChild: defaultAsChild = undefined, resetLabelPath,
123-
fieldsOrder,
125+
fieldsOrder, appearance,
124126
...props
125127
} = defineProps<{
126128
name: string
@@ -164,6 +166,10 @@ const realResetLabelPath = computed(() => {
164166
165167
const fieldAttrs = useFieldAttrs(field.path!, toRef(() => ({ required, ...props, resetLabelPath: realResetLabelPath.value })))
166168
const realAdded = computed(() => !fieldAttrs.value.required ? added.value ?? defaultAdded : true)
169+
const wrapper = computed(() => {
170+
if (appearance === 'card') return 'KCard'
171+
return 'div'
172+
})
167173
168174
const asChild = computed(() => {
169175
if (defaultAsChild !== undefined) return defaultAsChild

packages/entities/entities-plugins/src/components/free-form/test/utils.ts

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isTagField, resolve } from '../shared/utils'
1+
import { getName, isTagField, resolve } from '../shared/utils'
22
import { buildAncestor, buildSchemaMap, defaultLabelFormatter, generalizePath } from '../shared/composables'
33

44
import type {
@@ -26,6 +26,7 @@ type AssertFieldFn<T extends UnionFieldSchema = UnionFieldSchema> = (option: Ass
2626
type AssertLabelOption = {
2727
hide?: boolean
2828
noAsterisk?: boolean
29+
forcePrefix?: string
2930
}
3031

3132
export function assertFormRendering(schema: FormSchema, options?: {
@@ -37,7 +38,7 @@ export function assertFormRendering(schema: FormSchema, options?: {
3738

3839
const schemaMap = buildSchemaMap(schema)
3940

40-
function assertFields(fields: NamedFieldSchema[], prefix?: string) {
41+
function assertFields(fields: NamedFieldSchema[], prefix?: string, labelOption?: AssertLabelOption) {
4142
for (const field of fields) {
4243
const fieldName = Object.keys(field)[0]
4344
const fieldKey = prefix ? resolve(prefix, fieldName) : fieldName
@@ -46,7 +47,7 @@ export function assertFormRendering(schema: FormSchema, options?: {
4647

4748
assert(fieldSchema, `Field schema for "${fieldKey}" should exist in the schema map`)
4849

49-
assertField({ fieldSchema, fieldKey })
50+
assertField({ fieldSchema, fieldKey, labelOption })
5051
}
5152
}
5253

@@ -62,7 +63,11 @@ export function assertFormRendering(schema: FormSchema, options?: {
6263
assertStringField({ fieldKey, fieldSchema, labelOption })
6364
}
6465
} else if (fieldSchema.type === 'boolean') {
65-
assertBooleanField({ fieldKey, fieldSchema, labelOption })
66+
if (fieldSchema.one_of) {
67+
assertEnumField({ fieldKey, fieldSchema, labelOption })
68+
} else {
69+
assertBooleanField({ fieldKey, fieldSchema, labelOption })
70+
}
6671
} else if (fieldSchema.type === 'record') {
6772
assertRecordField({ fieldKey, fieldSchema, labelOption })
6873
} else if (fieldSchema.type === 'integer' || fieldSchema.type === 'number') {
@@ -220,15 +225,15 @@ export function assertFormRendering(schema: FormSchema, options?: {
220225
fieldSchema,
221226
labelOption,
222227
}: AssertFieldOption<RecordFieldSchema>) => {
223-
const asChild = isArrayItem(fieldKey)
228+
const isChildOfArray = isArrayItem(fieldKey)
229+
const asChild = isChildOfArray
224230

225231
// Wrapper element should exist
226232
cy.getTestId(`ff-object-${fieldKey}`).should('exist')
227233

228234
// Check label
229235
assertLabel({
230236
fieldKey,
231-
labelText: asChild ? '' : defaultLabelFormatter(fieldKey),
232237
fieldSchema,
233238
labelOption: {
234239
...labelOption,
@@ -259,7 +264,7 @@ export function assertFormRendering(schema: FormSchema, options?: {
259264

260265
// Assert child fields
261266
if (fieldSchema.fields && fieldSchema.fields.length > 0) {
262-
assertFields(fieldSchema.fields, fieldKey)
267+
assertFields(fieldSchema.fields, fieldKey, { forcePrefix: isChildOfArray ? '' : undefined })
263268
}
264269

265270
// Click the 'fold/unfold' button
@@ -426,9 +431,11 @@ export function assertFormRendering(schema: FormSchema, options?: {
426431
fieldSchema: UnionFieldSchema
427432
labelOption?: AssertLabelOption
428433
}) {
434+
const formattedLabelText = labelText || formatLabelText(fieldKey, labelOption)
435+
429436
assertLabelBySelector({
430437
selector: () => cy.getTestId(`ff-label-${fieldKey}`),
431-
labelText: labelText || defaultLabelFormatter(fieldKey),
438+
labelText: formattedLabelText,
432439
fieldSchema,
433440
labelOption,
434441
})
@@ -493,3 +500,17 @@ function isStringArrayOfArray(fieldSchema: UnionFieldSchema) {
493500
&& fieldSchema.elements.type === 'array'
494501
&& fieldSchema.elements.elements.type === 'string'
495502
}
503+
504+
function formatLabelText(fieldKey: string, labelOption?: AssertLabelOption): string {
505+
let actualLabelText: string
506+
507+
if (labelOption?.forcePrefix !== undefined) {
508+
const name = getName(fieldKey)
509+
const newFieldKey = resolve(labelOption.forcePrefix, name)
510+
actualLabelText = defaultLabelFormatter(newFieldKey)
511+
} else {
512+
actualLabelText = defaultLabelFormatter(fieldKey)
513+
}
514+
515+
return actualLabelText
516+
}

0 commit comments

Comments
 (0)