diff --git a/app/stores/CollectionsStore.js b/app/stores/CollectionsStore.js index 45c4dbb95..919e96dba 100644 --- a/app/stores/CollectionsStore.js +++ b/app/stores/CollectionsStore.js @@ -8,6 +8,7 @@ import stores from 'stores'; import Collection from 'models/Collection'; import ErrorsStore from 'stores/ErrorsStore'; import UiStore from 'stores/UiStore'; +import naturalSort from 'shared/utils/naturalSort'; import type { PaginationParams } from 'types'; type Options = { @@ -42,7 +43,7 @@ class CollectionsStore { @computed get orderedData(): Collection[] { - return _.sortBy(this.data.values(), 'name'); + return naturalSort(Array.from(this.data.values()), 'name'); } /** diff --git a/app/stores/CollectionsStore.test.js b/app/stores/CollectionsStore.test.js deleted file mode 100644 index 841ca4efa..000000000 --- a/app/stores/CollectionsStore.test.js +++ /dev/null @@ -1,43 +0,0 @@ -/* eslint-disable */ -import CollectionsStore from './CollectionsStore'; -const { client } = require('utils/ApiClient'); - -describe('CollectionsStore', () => { - let store; - - beforeEach(() => { - store = new CollectionsStore({}); - }); - - describe('#fetchPage', () => { - test('should load stores', async () => { - client.post = jest.fn(() => ({ - data: [ - { - id: 123, - name: 'New collection', - }, - ], - })) - - await store.fetchPage(); - - expect(client.post).toHaveBeenCalledWith('/collections.list', undefined); - expect(store.data.size).toBe(1); - expect(store.data.values()[0].name).toBe('New collection'); - }); - - test('should report errors', async () => { - client.post = jest.fn(() => Promise.reject()) - store.errors = { - add: jest.fn(), - }; - - await store.fetchPage(); - - expect(store.errors.add).toHaveBeenCalledWith( - 'Failed to load collections' - ); - }); - }); -}); diff --git a/package.json b/package.json index e0c92fcb6..b910fa018 100644 --- a/package.json +++ b/package.json @@ -136,6 +136,7 @@ "mobx-react": "^4.1.8", "mobx-react-devtools": "^4.2.11", "moment": "2.13.0", + "natural-sort": "^1.0.0", "node-dev": "3.1.0", "nodemailer": "^4.4.0", "normalize.css": "^7.0.0", diff --git a/server/presenters/collection.js b/server/presenters/collection.js index 89dfe11e8..965aad8ca 100644 --- a/server/presenters/collection.js +++ b/server/presenters/collection.js @@ -1,7 +1,7 @@ // @flow -import _ from 'lodash'; import { Collection } from '../models'; import presentDocument from './document'; +import naturalSort from '../../shared/utils/naturalSort'; type Document = { children: Document[], @@ -11,7 +11,7 @@ type Document = { }; const sortDocuments = (documents: Document[]) => { - const orderedDocs = _.sortBy(documents, ['title']); + const orderedDocs = naturalSort(documents, 'title'); return orderedDocs.map(document => ({ ...document, children: sortDocuments(document.children), diff --git a/shared/utils/naturalSort.js b/shared/utils/naturalSort.js new file mode 100644 index 000000000..3cfb0a251 --- /dev/null +++ b/shared/utils/naturalSort.js @@ -0,0 +1,10 @@ +// @flow + +import _ from 'lodash'; +import naturalSort from 'natural-sort'; + +export default (sortableArray: Object[], key: string) => { + let keys = sortableArray.map(object => object[key]); + keys.sort(naturalSort()); + return _.sortBy(sortableArray, object => keys.indexOf(object[key])); +}; diff --git a/yarn.lock b/yarn.lock index 1024d6ffe..406c66d79 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6628,6 +6628,10 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" +natural-sort@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/natural-sort/-/natural-sort-1.0.0.tgz#eac301fd86c268a771222c62dc7719402aa34380" + ncname@1.0.x: version "1.0.0" resolved "https://registry.yarnpkg.com/ncname/-/ncname-1.0.0.tgz#5b57ad18b1ca092864ef62b0b1ed8194f383b71c"