Skip to content

Commit 9ff1bcc

Browse files
authored
[schema] Make the output from the fallback preview.prepare more human friendly (#174)
* [schema] Make the output from the fallback preview.prepare more human-friendly * [schema] Remove dangling comma in fallback preview output
1 parent b565fdc commit 9ff1bcc

File tree

5 files changed

+120
-6
lines changed

5 files changed

+120
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import {pick} from 'lodash'
2+
3+
function isEmpty(object) {
4+
for (const key in object) {
5+
if (object.hasOwnProperty(key)) {
6+
return false
7+
}
8+
}
9+
return true
10+
}
11+
12+
function _stringify(value, options, depth) {
13+
if (depth > options.maxDepth) {
14+
return '...'
15+
}
16+
if (Array.isArray(value)) {
17+
if (value.length === 0) {
18+
return '[empty]'
19+
}
20+
const capLength = Math.max(value.length - options.maxBreadth)
21+
const asString = value.slice(0, options.maxBreadth)
22+
.map((item, index) => _stringify(item, options, depth + 1))
23+
.concat(capLength > 0 ? `…+${capLength}` : [])
24+
.join(', ')
25+
26+
return depth === 0 ? asString : `[${asString}]`
27+
}
28+
if (typeof value === 'object' && value !== null) {
29+
const keys = Object.keys(value)
30+
.filter(key => !options.ignoreKeys.includes(key) && typeof value[key] !== 'undefined')
31+
32+
if (isEmpty(pick(value, keys))) {
33+
return '{empty}'
34+
}
35+
36+
const asString = keys
37+
.slice(0, options.maxBreadth)
38+
.map(key => `${key}: ${_stringify(value[key], options, depth + 1)}`)
39+
.join(', ')
40+
41+
return depth === 0 ? asString : `{${asString}}`
42+
}
43+
const asString = String(value)
44+
return asString === '' ? '""' : asString
45+
}
46+
47+
export default function stringify(value, options = {}) {
48+
const opts = {
49+
maxDepth: 'maxDepth' in options ? options.maxDepth : 2,
50+
maxBreadth: 'maxBreadth' in options ? options.maxBreadth : 2,
51+
ignoreKeys: 'ignoreKeys' in options ? options.ignoreKeys : []
52+
}
53+
return _stringify(value, opts, 0)
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {pick} from 'lodash'
2+
import stringify from './JSONStringifyHuman'
3+
4+
const OPTIONS = {
5+
maxEntries: 2,
6+
maxDepth: 2,
7+
maxBreadth: 2,
8+
ignoreKeys: ['_id', '_type', '_key', '_ref']
9+
}
10+
11+
export function createFallbackPrepare(fieldNames) {
12+
return value => ({
13+
title: stringify(pick(value, fieldNames), OPTIONS)
14+
})
15+
}

packages/@sanity/schema/src/preview/guessPreviewConfig.js

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {omitBy, isUndefined} from 'lodash'
22
import arrify from 'arrify'
3+
import {createFallbackPrepare} from './fallbackPrepare'
34

45
const TITLE_CANDIDATES = ['title', 'name', 'label', 'heading', 'header', 'caption']
56
const DESCRIPTION_CANDIDATES = ['description', ...TITLE_CANDIDATES]
@@ -50,11 +51,7 @@ export default function guessPreviewFields(objectTypeDef) {
5051

5152
return {
5253
select: fieldMapping,
53-
prepare(data) {
54-
return {
55-
title: fieldNames.map(name => `${name}: ${JSON.stringify(data[name])}`).join(' / ')
56-
}
57-
}
54+
prepare: createFallbackPrepare(fieldNames)
5855
}
5956
}
6057

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Example type that has no obvious candidate fields for sort or preview
2+
export default {
3+
name: 'noTitleField',
4+
type: 'object',
5+
title: 'No title field',
6+
fields: [
7+
{
8+
name: 'isChecked',
9+
type: 'boolean',
10+
title: 'Is checked?'
11+
},
12+
{
13+
name: 'somethings',
14+
title: 'Some things',
15+
type: 'array',
16+
of: [
17+
{type: 'string'}
18+
]
19+
},
20+
{
21+
name: 'something',
22+
type: 'object',
23+
title: 'Some thing',
24+
fields: [
25+
{name: 'first', type: 'string'},
26+
{name: 'second', type: 'string'}
27+
]
28+
},
29+
{
30+
name: 'arrayOfBooks',
31+
type: 'array',
32+
title: 'Array of books',
33+
of: [
34+
{type: 'book', title: 'Book'}
35+
]
36+
},
37+
{
38+
name: 'arrayOfMyself',
39+
type: 'array',
40+
title: 'Array of my own type',
41+
of: [
42+
{type: 'noTitleField', title: 'My own type'}
43+
]
44+
}
45+
]
46+
}

packages/test-studio/schemas/schema.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import dates from './dates'
1919
import slugs from './slugs'
2020
import geopoint from './geopoint'
2121
import customInputs from './customInputs'
22+
import notitle from './notitle'
2223

2324
export default createSchema({
2425
name: 'test-examples',
@@ -42,6 +43,7 @@ export default createSchema({
4243
myImage,
4344
recursive,
4445
myObject,
45-
codeInputType
46+
codeInputType,
47+
notitle
4648
]
4749
})

0 commit comments

Comments
 (0)