Skip to content

Commit

Permalink
Admin UI: Refactored handling of list state (#2827)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vultraz authored May 5, 2020
1 parent fcb9f2c commit 4d3efe0
Show file tree
Hide file tree
Showing 19 changed files with 212 additions and 272 deletions.
7 changes: 7 additions & 0 deletions .changeset/breezy-files-peel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@keystonejs/app-admin-ui': minor
---

Refactored the internal handling of list data fetching. This resolves two issues:
- Fixed two API requests being made when loading a list.
- Fixed Ract errors in the search and pagination components.
25 changes: 14 additions & 11 deletions packages/app-admin-ui/client/classes/List.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,38 +37,39 @@ export default class List {
}
}
`;

this.createManyMutation = gql`
mutation createMany($data: ${this.gqlNames.createManyInputName}!) {
${this.gqlNames.createManyMutationName}(data: $data) {
id
mutation createMany($data: ${this.gqlNames.createManyInputName}!) {
${this.gqlNames.createManyMutationName}(data: $data) {
id
}
}
}
`;
`;

this.updateMutation = gql`
mutation update(
$id: ID!,
$data: ${this.gqlNames.updateInputName})
{
mutation update($id: ID!, $data: ${this.gqlNames.updateInputName}) {
${this.gqlNames.updateMutationName}(id: $id, data: $data) {
id
}
}
`;

this.updateManyMutation = gql`
mutation updateMany($data: [${this.gqlNames.updateManyInputName}])
{
mutation updateMany($data: [${this.gqlNames.updateManyInputName}]) {
${this.gqlNames.updateManyMutationName}(data: $data) {
id
}
}
`;

this.deleteMutation = gql`
mutation delete($id: ID!) {
${this.gqlNames.deleteMutationName}(id: $id) {
id
}
}
`;

this.deleteManyMutation = gql`
mutation deleteMany($ids: [ID!]) {
${this.gqlNames.deleteManyMutationName}(ids: $ids) {
Expand Down Expand Up @@ -151,9 +152,11 @@ export default class List {
const count = Array.isArray(items) ? items.length : items;
return count === 1 ? `1 ${this.singular}` : `${count} ${this.plural}`;
}

getPersistedSearch() {
return localStorage.getItem(`search:${this.path}`);
}

setPersistedSearch(value) {
localStorage.setItem(`search:${this.path}`, value);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/app-admin-ui/client/components/ListTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ export default function ListTable(props) {
linkField = '_label_',
} = props;

const [sortBy, onSortChange] = useListSort(list.key);
const [sortBy, onSortChange] = useListSort();

const handleSelectAll = () => {
const allSelected = items && items.length === selectedItems.length;
Expand Down
2 changes: 1 addition & 1 deletion packages/app-admin-ui/client/components/NoResults.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const NoResultsWrapper = ({ children, ...props }) => (
);

export const NoResults = ({ currentPage, filters, list, search }) => {
const { onChange } = useListPagination(list.key);
const { onChange } = useListPagination();
const onResetPage = () => onChange(1);

const pageDepthMessage = (
Expand Down
12 changes: 3 additions & 9 deletions packages/app-admin-ui/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,9 @@ export const KeystoneAdminUI = () => {
}

return (
<ListProvider list={list}>
<ListProvider key={listKey} list={list}>
<Switch>
<Route
exact
path={`${adminPath}/:list`}
render={routeProps => (
<ListPage key={listKey} list={list} routeProps={routeProps} />
)}
/>
<Route exact path={`${adminPath}/:list`} render={() => <ListPage key={listKey} />} />
,
<Route
exact
Expand All @@ -89,7 +83,7 @@ export const KeystoneAdminUI = () => {
match: {
params: { itemId },
},
}) => <ItemPage key={`${listKey}-${itemId}`} list={list} itemId={itemId} />}
}) => <ItemPage key={`${listKey}-${itemId}`} itemId={itemId} />}
/>
,
<Route render={() => <InvalidRoutePage />} />,
Expand Down
1 change: 0 additions & 1 deletion packages/app-admin-ui/client/pages/Item/Search.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import Tooltip from '@arch-ui/tooltip';
import { useAdminMeta } from '../../providers/AdminMeta';

export function Search({ list }) {
// const { urlState } = useListUrlState(list.key);
const [value, setValue] = useState('');
const [formIsVisible, setFormVisible] = useState(false);
const inputRef = useRef(null);
Expand Down
35 changes: 22 additions & 13 deletions packages/app-admin-ui/client/pages/Item/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
import { ItemTitle } from './ItemTitle';
import { ItemProvider } from '../../providers/Item';
import { useAdminMeta } from '../../providers/AdminMeta';
import { useList } from '../../providers/List';

let Render = ({ children }) => children();

Expand Down Expand Up @@ -82,6 +83,8 @@ const ItemDetails = ({
const history = useHistory();
const { addToast } = useToasts();

const { query: listQuery } = useList();

const getFieldsObject = memoizeOne(() =>
arrayToObject(
// NOTE: We _exclude_ read only fields
Expand Down Expand Up @@ -116,20 +119,25 @@ const ItemDetails = ({
}
};

const onDelete = deletePromise => {
const onDelete = async deletePromise => {
deleteConfirmed.current = true;
deletePromise
.then(() => {
if (mounted) {
setShowDeleteModal(false);
}

history.replace(`${adminPath}/${list.path}`);
toastItemSuccess({ addToast }, initialData, 'Deleted successfully');
})
.catch(error => {
toastError({ addToast }, error);
});
try {
await deletePromise;
const refetch = listQuery.refetch();

if (mounted) {
setShowDeleteModal(false);
}

toastItemSuccess({ addToast }, initialData, 'Deleted successfully');

// Wait for the refetch to finish before returning to the list
await refetch;
history.replace(`${adminPath}/${list.path}`);
} catch (error) {
toastError({ addToast }, error);
}
};

const openDeleteModal = () => {
Expand Down Expand Up @@ -349,7 +357,8 @@ const ItemNotFound = ({ adminPath, errorMessage, list }) => (
</PageError>
);

const ItemPage = ({ list, itemId }) => {
const ItemPage = ({ itemId }) => {
const { list } = useList();
const { adminPath, getListByKey } = useAdminMeta();
const { addToast } = useToasts();

Expand Down
13 changes: 5 additions & 8 deletions packages/app-admin-ui/client/pages/List/ColumnSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@ import { jsx } from '@emotion/core';
import { OptionPrimitive, CheckMark } from '@arch-ui/options';

import { Popout, POPOUT_GUTTER } from '../../components/Popout';
import { useList, useListColumns } from './dataHooks';
import { useListColumns } from './dataHooks';
import { useList } from '../../providers/List';
import FieldSelect from './FieldSelect';

type Props = {
listKey: string,
};

export default function ColumnPopout({ listKey, target }: Props) {
const list = useList(listKey);
const [columns, handleColumnChange] = useListColumns(listKey);
export default function ColumnPopout({ target }) {
const { list } = useList();
const [columns, handleColumnChange] = useListColumns();
const cypresSelectId = 'ks-column-select';

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const elementOffsetStyles = {
};

export default function ActiveFilters({ list }) {
const { filters, onAdd, onRemove, onRemoveAll, onUpdate } = useListFilter(list.key);
const { filters, onAdd, onRemove, onRemoveAll, onUpdate } = useListFilter();

return (
<Fragment>
Expand Down
4 changes: 2 additions & 2 deletions packages/app-admin-ui/client/pages/List/MoreDropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import { useMeasure } from '@arch-ui/hooks';

import { useReset } from './dataHooks';

let dropdownTarget = props => (
const dropdownTarget = props => (
<IconButton {...props} variant="nuance" icon={KebabVerticalIcon} id="ks-list-dropdown">
<A11yText>Show more...</A11yText>
</IconButton>
);

export function MoreDropdown({ listKey, measureRef, isFullWidth, onFullWidthToggle }) {
let { width } = useMeasure(measureRef);
const { width } = useMeasure(measureRef);
const onReset = useReset(listKey);
const TableIcon = isFullWidth ? FoldIcon : UnfoldIcon;
const tableToggleIsAvailable = width > CONTAINER_WIDTH + CONTAINER_GUTTER * 2;
Expand Down
4 changes: 2 additions & 2 deletions packages/app-admin-ui/client/pages/List/Pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { useListPagination } from './dataHooks';

const CYPRESS_TEST_ID = 'ks-pagination';

export default function ListPagination({ isLoading, listKey }) {
const { data, onChange } = useListPagination(listKey);
export default function ListPagination({ isLoading }) {
const { data, onChange } = useListPagination();

return (
<Pagination
Expand Down
2 changes: 1 addition & 1 deletion packages/app-admin-ui/client/pages/List/Search.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { useListSearch } from './dataHooks';
import { elementOffsetStyles } from './Filters/ActiveFilters';

export default function Search({ isLoading, list }) {
const { searchValue, onChange, onClear, onSubmit } = useListSearch(list.key);
const { searchValue, onChange, onClear, onSubmit } = useListSearch();
const [value, setValue] = useState(searchValue);
const inputRef = useRef();

Expand Down
13 changes: 5 additions & 8 deletions packages/app-admin-ui/client/pages/List/SortSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@ import { Kbd } from '@arch-ui/typography';
import { Button } from '@arch-ui/button';

import { DisclosureArrow, Popout, POPOUT_GUTTER } from '../../components/Popout';
import { useList, useListSort, useKeyDown } from './dataHooks';
import { useListSort, useKeyDown } from './dataHooks';
import { useList } from '../../providers/List';

type Props = {
listKey: string,
};

export default function SortPopout({ listKey }: Props) {
const list = useList(listKey);
const [sortValue, handleSortChange] = useListSort(listKey);
export default function SortPopout() {
const { list } = useList();
const [sortValue, handleSortChange] = useListSort();
const altIsDown = useKeyDown('Alt');
const popoutRef = useRef();

Expand Down
Loading

0 comments on commit 4d3efe0

Please sign in to comment.