Skip to content

Commit 36bafc5

Browse files
feat: sort-ordering; nested object selection
Co-authored-by: Simeon Griggs <[email protected]>
1 parent 5ecc457 commit 36bafc5

13 files changed

+1936
-2063
lines changed

package-lock.json

+1,611-1,891
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+12-12
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,18 @@
3838
"@babel/preset-typescript": "7.15.0",
3939
"@rollup/plugin-babel": "5.3.0",
4040
"@rollup/plugin-node-resolve": "11.2.1",
41-
"@sanity/base": "2.13.1",
42-
"@sanity/cli": "^2.14.0",
43-
"@sanity/client": "2.13.0",
44-
"@sanity/components": "2.13.0",
45-
"@sanity/core": "2.13.1",
46-
"@sanity/default-layout": "2.13.1",
47-
"@sanity/default-login": "2.13.1",
48-
"@sanity/desk-tool": "2.13.1",
49-
"@sanity/google-maps-input": "2.13.1",
50-
"@sanity/icons": "1.1.5",
51-
"@sanity/ui": "0.36.3",
52-
"@sanity/vision": "2.13.1",
41+
"@sanity/base": "^2.17.0",
42+
"@sanity/cli": "^2.17.0",
43+
"@sanity/client": "^2.16.0",
44+
"@sanity/components": "^2.14.0",
45+
"@sanity/core": "^2.17.0",
46+
"@sanity/default-layout": "^2.17.0",
47+
"@sanity/default-login": "^2.17.0",
48+
"@sanity/desk-tool": "^2.17.0",
49+
"@sanity/google-maps-input": "^2.17.0",
50+
"@sanity/icons": "^1.1.5",
51+
"@sanity/ui": "0.34.7",
52+
"@sanity/vision": "^2.15.0",
5353
"@types/classnames": "2.3.0",
5454
"@types/react": "17.0.19",
5555
"@types/react-dom": "17.0.9",

schemas/movie.js

+32-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {MdLocalMovies as icon} from 'react-icons/md'
1+
import { MdLocalMovies as icon } from 'react-icons/md';
22

33
export default {
44
name: 'movie',
@@ -52,13 +52,36 @@ export default {
5252
name: 'castMembers',
5353
title: 'Cast Members',
5454
type: 'array',
55-
of: [{type: 'castMember'}],
55+
of: [{ type: 'castMember' }],
5656
},
5757
{
5858
name: 'crewMembers',
5959
title: 'Crew Members',
6060
type: 'array',
61-
of: [{type: 'crewMember'}],
61+
of: [{ type: 'crewMember' }],
62+
},
63+
{
64+
name: 'seo',
65+
title: 'SEO',
66+
type: 'object',
67+
fields: [
68+
{
69+
name: 'seoTitle',
70+
title: 'Seo Title',
71+
type: 'string',
72+
},
73+
{
74+
name: 'seoDescription',
75+
title: 'Seo Description',
76+
type: 'string',
77+
},
78+
],
79+
preview: {
80+
select: {
81+
title: 'seoTitle',
82+
subtitle: 'seoDescription',
83+
},
84+
},
6285
},
6386
],
6487
preview: {
@@ -70,15 +93,17 @@ export default {
7093
castName1: 'castMembers.1.person.name',
7194
},
7295
prepare(selection) {
73-
const year = selection.date && selection.date.split('-')[0]
74-
const cast = [selection.castName0, selection.castName1].filter(Boolean).join(', ')
96+
const year = selection.date && selection.date.split('-')[0];
97+
const cast = [selection.castName0, selection.castName1]
98+
.filter(Boolean)
99+
.join(', ');
75100

76101
return {
77102
title: `${selection.title} ${year ? `(${year})` : ''}`,
78103
date: selection.date,
79104
subtitle: cast,
80105
media: selection.media,
81-
}
106+
};
82107
},
83108
},
84-
}
109+
};

structure.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ export default () =>
55
S.list()
66
.title('Base')
77
.items([
8-
S.listItem().title('Normal List').child(createSuperPane('movie', S)),
8+
S.listItem().title('Normal List').child(createSuperPane('movie')),
99
]);

super-pane/bulk-actions-menu/index.tsx

+11-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
Dialog,
88
Button,
99
MenuButton,
10-
Label,
1110
useToast,
1211
} from '@sanity/ui';
1312
import {
@@ -24,6 +23,7 @@ import { ErrorBoundary } from 'react-error-boundary';
2423
const client = _client as import('@sanity/client').SanityClient;
2524

2625
interface Props {
26+
disabled: Boolean;
2727
className?: string;
2828
typeName: string;
2929
selectedIds: Set<string>;
@@ -63,6 +63,7 @@ const removeDraftPrefix = (s: string) =>
6363
s.startsWith('drafts.') ? s.substring('drafts.'.length) : s;
6464

6565
function BulkActionsMenu({
66+
disabled,
6667
className,
6768
selectedIds,
6869
typeName,
@@ -261,9 +262,15 @@ function BulkActionsMenu({
261262
<>
262263
<MenuButton
263264
button={
264-
<button className={className}>
265-
<Label>Bulk Actions</Label>
266-
</button>
265+
disabled ? (
266+
<Button fontSize={1} paddingY={1} paddingX={2} disabled>
267+
Bulk Actions
268+
</Button>
269+
) : (
270+
<Button fontSize={1} paddingY={1} paddingX={2}>
271+
Bulk Actions
272+
</Button>
273+
)
267274
}
268275
portal
269276
id={buttonId}

super-pane/cell/index.tsx

+10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react';
22
import SanityPreview from 'part:@sanity/base/preview';
33
import blockContentToString from '../block-content-to-string';
44
import styles from './styles.module.css';
5+
import { Text } from '@sanity/ui';
56

67
interface Props {
78
field: any;
@@ -10,6 +11,15 @@ interface Props {
1011

1112
function Cell({ field, value }: Props) {
1213
switch (field.type.name) {
14+
// Hacky! Format _just_ the updatedAt field
15+
case '_updatedAt': {
16+
return (
17+
<td key={field.name}>
18+
<Text size={1}>{new Date(value).toLocaleString()}</Text>
19+
</td>
20+
);
21+
}
22+
// The rest of these types are legit!
1323
case 'string':
1424
case 'number': {
1525
return <td key={field.name}>{value}</td>;

super-pane/column-selector/index.tsx

+37-36
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Dialog, Checkbox, Button } from '@sanity/ui';
33
import { nanoid } from 'nanoid';
44
import schema from 'part:@sanity/base/schema';
55
import styles from './styles.module.css';
6+
import { getSelectableFields } from '../helpers/get-selectable-fields';
67

78
interface Props {
89
typeName: string;
@@ -12,6 +13,13 @@ interface Props {
1213
initiallySelectedColumns: Set<string>;
1314
}
1415

16+
export interface SelectableField {
17+
field: any;
18+
fieldPath: string;
19+
title: string;
20+
level: number;
21+
}
22+
1523
function ColumnSelector({
1624
open,
1725
onClose,
@@ -21,7 +29,7 @@ function ColumnSelector({
2129
}: Props) {
2230
const schemaType = schema.get(typeName);
2331
const [selectedColumns, setSelectedColumns] = useState(
24-
initiallySelectedColumns,
32+
initiallySelectedColumns
2533
);
2634

2735
useEffect(() => {
@@ -31,6 +39,26 @@ function ColumnSelector({
3139
}, [open, initiallySelectedColumns]);
3240

3341
const dialogId = useMemo(() => nanoid(), []);
42+
43+
function handleSelect(fieldPath: string) {
44+
setSelectedColumns((set) => {
45+
const nextSet = new Set(set);
46+
47+
if (set.has(fieldPath)) {
48+
nextSet.delete(fieldPath);
49+
} else {
50+
nextSet.add(fieldPath);
51+
}
52+
53+
return nextSet;
54+
});
55+
}
56+
57+
const selectableFields = useMemo(
58+
() => getSelectableFields(schemaType.fields),
59+
[schemaType.fields]
60+
);
61+
3462
if (!open) {
3563
return null;
3664
}
@@ -62,52 +90,25 @@ function ColumnSelector({
6290
<Checkbox
6391
className={styles.checkbox}
6492
checked={selectedColumns.has('_updatedAt')}
65-
onChange={() => {
66-
setSelectedColumns((set) => {
67-
const nextSet = new Set(set);
68-
69-
if (set.has('_updatedAt')) {
70-
nextSet.delete('_updatedAt');
71-
} else {
72-
nextSet.add('_updatedAt');
73-
}
74-
75-
return nextSet;
76-
});
77-
}}
93+
onChange={() => handleSelect('_updatedAt')}
7894
/>
7995
<span>Updated At</span>
8096
</label>
8197
</li>
82-
{schemaType.fields.map((i: any) => {
83-
const fieldName: string = i.name;
84-
const title: string = i.type.title;
85-
86-
return (
87-
<li key={fieldName}>
98+
{selectableFields.map(
99+
({ fieldPath, title, level }: SelectableField) => (
100+
<li key={fieldPath} style={{ marginLeft: level > 0 ? `1rem` : `` }}>
88101
<label className={styles.label}>
89102
<Checkbox
90103
className={styles.checkbox}
91-
checked={selectedColumns.has(fieldName)}
92-
onChange={() => {
93-
setSelectedColumns((set) => {
94-
const nextSet = new Set(set);
95-
96-
if (set.has(fieldName)) {
97-
nextSet.delete(fieldName);
98-
} else {
99-
nextSet.add(fieldName);
100-
}
101-
102-
return nextSet;
103-
});
104-
}}
104+
checked={selectedColumns.has(fieldPath)}
105+
onChange={() => handleSelect(fieldPath)}
105106
/>
106107
<span>{title}</span>
107108
</label>
108109
</li>
109-
);
110-
})}
110+
)
111+
)}
111112
</ul>
112113
</Dialog>
113114
);

0 commit comments

Comments
 (0)