Skip to content

Commit

Permalink
Merge pull request #45 from ricokahler/fix/missing-name
Browse files Browse the repository at this point in the history
fix: missing name in field, sortable and recursive objects
  • Loading branch information
SimeonGriggs authored Oct 18, 2021
2 parents 2d77f7f + 0ea4938 commit 1bc11db
Show file tree
Hide file tree
Showing 10 changed files with 16,175 additions and 794 deletions.
2,427 changes: 1,732 additions & 695 deletions package-lock.json

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@
"@babel/preset-typescript": "7.15.0",
"@rollup/plugin-babel": "5.3.0",
"@rollup/plugin-node-resolve": "11.2.1",
"@sanity/base": "2.20.0",
"@sanity/cli": "2.20.0",
"@sanity/client": "2.19.0",
"@sanity/base": "^2.21.4",
"@sanity/cli": "^2.21.4",
"@sanity/client": "^2.21.3",
"@sanity/components": "2.14.0",
"@sanity/core": "2.20.0",
"@sanity/default-layout": "2.20.0",
"@sanity/default-login": "2.19.0",
"@sanity/desk-tool": "2.20.0",
"@sanity/google-maps-input": "2.20.0",
"@sanity/core": "^2.21.4",
"@sanity/default-layout": "^2.21.4",
"@sanity/default-login": "^2.21.4",
"@sanity/desk-tool": "^2.21.4",
"@sanity/google-maps-input": "^2.21.4",
"@sanity/icons": "1.2.1",
"@sanity/ui": "0.36.12",
"@sanity/vision": "2.20.0",
"@sanity/vision": "^2.21.4",
"@types/classnames": "2.3.0",
"@types/react": "17.0.26",
"@types/react-dom": "17.0.9",
Expand Down
19 changes: 9 additions & 10 deletions super-pane/cell/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,32 @@ import { Text } from '@sanity/ui';

interface Props {
field: any;
fieldPath: string;
value: any;
}

function Cell({ field, value }: Props) {
function Cell({ field, fieldPath, value }: Props) {
switch (field.type.name) {
// Hacky! Format _just_ the updatedAt field
case '_updatedAt': {
return (
<td key={field.name}>
<td key={fieldPath}>
<Text size={1}>{new Date(value).toLocaleString()}</Text>
</td>
);
}
// The rest of these types are legit!
case 'string':
case 'number': {
return <td key={field.name}>{value}</td>;
return <td key={fieldPath}>{value}</td>;
}
case 'blockContent': {
const blockContentAsString = blockContentToString(value);

return (
<td
title={blockContentAsString}
key={field.name}
key={fieldPath}
className={styles.blockContent}
>
{blockContentAsString}
Expand All @@ -39,29 +40,27 @@ function Cell({ field, value }: Props) {
}
case 'datetime': {
return (
<td key={field.name}>
{value ? new Date(value).toLocaleString() : ''}
</td>
<td key={fieldPath}>{value ? new Date(value).toLocaleString() : ''}</td>
);
}
case 'date': {
return (
<td key={field.name}>
<td key={fieldPath}>
{value ? new Date(value).toLocaleDateString() : ''}
</td>
);
}
case 'array': {
return (
<td key={field.name}>
<td key={fieldPath}>
{value?.length || 0} item
{value?.length === 1 ? '' : 's'}
</td>
);
}
default: {
return (
<td key={field.name}>
<td key={fieldPath}>
{value && (
<SanityPreview type={field.type} layout="default" value={value} />
)}
Expand Down
3 changes: 2 additions & 1 deletion super-pane/column-selector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface SelectableField {
fieldPath: string;
title: string;
level: number;
sortable: boolean;
}

function ColumnSelector({
Expand Down Expand Up @@ -97,7 +98,7 @@ function ColumnSelector({
</li>
{selectableFields.map(
({ fieldPath, title, level }: SelectableField) => (
<li key={fieldPath} style={{ marginLeft: level > 0 ? `1rem` : `` }}>
<li key={fieldPath} style={{ marginLeft: level * 10 }}>
<label className={styles.label}>
<Checkbox
className={styles.checkbox}
Expand Down
139 changes: 74 additions & 65 deletions super-pane/create-super-pane.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState, useRef } from 'react';
import React, { useMemo, useEffect, useState, useRef } from 'react';
import S from '@sanity/desk-tool/structure-builder';
import { get } from 'lodash';
import classNames from 'classnames';
Expand Down Expand Up @@ -33,16 +33,14 @@ import {
SpinnerIcon,
ControlsIcon,
SearchIcon,
ChevronDownIcon,
ChevronUpIcon,
SortIcon,
} from '@sanity/icons';
import styles from './styles.module.css';
import SearchField from './search-field';
import { useStickyStateSet } from './hooks/use-sticky-state-set';
import { useStickyStateOrder } from './hooks/use-sticky-state-order';
import { getSelectableFields } from './helpers/get-selectable-fields';
import { SelectableField } from './column-selector/index';
import TableHeaderInner from './table-header-inner';

function parentHasClass(el: HTMLElement | null, className: string): boolean {
if (!el) return false;
Expand Down Expand Up @@ -81,7 +79,7 @@ function createSuperPane(typeName: string) {
const [selectedIds, setSelectedIds] = useState(new Set<string>());
const [selectedSearchField, setSelectedSearchField] = useState<
string | null
>(fieldsToChooseFrom[0]?.name || null);
>(fieldsToChooseFrom?.length ? fieldsToChooseFrom[0]?.name : null);
const [showSearch, setShowSearch] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);

Expand Down Expand Up @@ -111,11 +109,17 @@ function createSuperPane(typeName: string) {
fieldPath: '_updatedAt',
title: 'Updated At',
field: { type: { name: '_updatedAt' } },
level: 0,
sortable: true,
},
]
: [];
const selectableFields = getSelectableFields(schemaType.fields).filter(
(field: any) => selectedColumns.has(field.fieldPath)
const selectableFields = useMemo(
() =>
getSelectableFields(schemaType.fields).filter((field: any) =>
selectedColumns.has(field.fieldPath)
),
[selectedColumns]
);
const fields = [...defaultFields, ...selectableFields];

Expand Down Expand Up @@ -243,37 +247,32 @@ function createSuperPane(typeName: string) {
</th>
{fields.map((field: SelectableField) => (
<th key={field.fieldPath}>
<Button
mode={
orderColumn.key !== field.fieldPath
? 'bleed'
: 'default'
}
tone={
orderColumn.key === field.fieldPath
? 'primary'
: 'default'
}
padding={1}
onClick={() => handleOrder(field.fieldPath)}
>
<Flex align="center">
<Label>{field.title}</Label>
{orderColumn.key === field.fieldPath ? (
<>
{orderColumn.direction === 'asc' ? (
<ChevronDownIcon />
) : (
<ChevronUpIcon />
)}
</>
) : (
<>
<SortIcon />
</>
)}
</Flex>
</Button>
{field.sortable ? (
<Button
mode={
orderColumn.key !== field.fieldPath
? 'bleed'
: 'default'
}
tone={
orderColumn.key === field.fieldPath
? 'primary'
: 'default'
}
padding={1}
onClick={() => handleOrder(field.fieldPath)}
>
<TableHeaderInner
field={field}
orderColumn={orderColumn}
/>
</Button>
) : (
<TableHeaderInner
field={field}
orderColumn={orderColumn}
/>
)}
</th>
))}
<th className={styles.optionsCell} aria-label="Options" />
Expand Down Expand Up @@ -364,6 +363,7 @@ function createSuperPane(typeName: string) {
{fields.map((field: SelectableField) => (
<Cell
field={field.field}
fieldPath={field.fieldPath}
value={get(item, field.fieldPath)}
/>
))}
Expand Down Expand Up @@ -416,10 +416,14 @@ function createSuperPane(typeName: string) {
</table>
</div>

<div className={styles.footer}>
<label className={styles.selectLabel}>
<Label>Rows Per Page</Label>
<div className={styles.select}>
<Card
borderTop
style={{ position: `absolute`, bottom: 0, width: `100%` }}
padding={3}
>
<Flex align="center" gap={2}>
<Flex align="center" gap={2}>
<Label style={{ whiteSpace: `nowrap` }}>Rows Per Page</Label>
<Select
value={pageSize}
onChange={(e) =>
Expand All @@ -432,29 +436,34 @@ function createSuperPane(typeName: string) {
</option>
))}
</Select>
</div>
</label>
<Button
fontSize={1}
disabled={client.page === 0}
onClick={() => client.setPage(client.page - 1)}
icon={ChevronLeftIcon}
title="Previous page"
mode="bleed"
/>
<Label>
{client.totalPages === 0 ? 0 : client.page + 1}&nbsp;/&nbsp;
{client.totalPages}
</Label>
<Button
fontSize={1}
disabled={client.page >= client.totalPages - 1}
onClick={() => client.setPage(client.page + 1)}
icon={ChevronRightIcon}
title="Next Page"
mode="bleed"
/>
</div>
</Flex>

<Box flex={1}>
<Flex align="center" justify="flex-end" gap={2}>
<Button
fontSize={1}
disabled={client.page === 0}
onClick={() => client.setPage(client.page - 1)}
icon={ChevronLeftIcon}
title="Previous page"
mode="bleed"
/>
<Label>
{client.totalPages === 0 ? 0 : client.page + 1}&nbsp;/&nbsp;
{client.totalPages}
</Label>
<Button
fontSize={1}
disabled={client.page >= client.totalPages - 1}
onClick={() => client.setPage(client.page + 1)}
icon={ChevronRightIcon}
title="Next Page"
mode="bleed"
/>
</Flex>
</Box>
</Flex>
</Card>
</div>

<ColumnSelector
Expand Down
60 changes: 48 additions & 12 deletions super-pane/helpers/get-selectable-fields.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,58 @@
export function getSelectableFields(fields: Array<any> = []) {
import { SelectableField } from '../column-selector';

function getInnerFields(
childFields: any[],
parentPath: string,
currentLevel = 1
): SelectableField[] {
return childFields.reduce((acc: any, cur: any) => {
const fieldPath = parentPath + '.' + cur.name;
const level = currentLevel + 1;

const child = {
field: cur,
fieldPath,
title: cur.type.title,
level,
sortable: true,
};

if (cur.type?.fields?.length) {
child.sortable = false;
const children = cur.type.fields;
const innerFields = getInnerFields(children, fieldPath, level);

if (innerFields.length) {
return [...acc, child, ...innerFields];
}
}

return [...acc, child];
}, []);
}

export function getSelectableFields(
fields: Array<any> = []
): SelectableField[] {
if (!fields.length) return [];

return fields.reduce((acc: any, cur: any) => {
const selectable = fields.reduce((acc: any, cur: any) => {
const fieldPath: string = cur.name;
const title: string = cur.type.title;
const fields = [{ field: cur, fieldPath, title, level: 0 }];
const parent = { field: cur, fieldPath, title, level: 0, sortable: true };

if (cur.type?.fields?.length) {
const innerFields = cur.type.fields.map((inner: any) => ({
field: inner,
fieldPath: fieldPath + '.' + inner.name,
title: inner.type.title,
level: 1,
}));

fields.push(...innerFields);
parent.sortable = false;
const children = cur.type.fields;
const innerFields = getInnerFields(children, fieldPath, 1);

if (innerFields.length) {
return [...acc, parent, ...innerFields];
}
}

return [...acc, ...fields];
return [...acc, parent];
}, []);

return selectable;
}
Loading

1 comment on commit 1bc11db

@vercel
Copy link

@vercel vercel bot commented on 1bc11db Oct 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.