* move list to component * use helper instead * add changelog * clarify changelog copy * delete components now that helper is in use * move helper to util, remove template helper invokation * add optional sorting to lazyPaginatedQuery based on sortBy query attribute * Add serialization to entity-alias and entity so that they can be sorted by name on list view * Same logic as base normalizeItems for extractLazyPaginatedData so that metadata shows on list * Add headers ---------
This commit is contained in:
parent
2d3e52fa92
commit
5917d9ae47
|
@ -0,0 +1,3 @@
|
|||
```release-note:improvement
|
||||
ui: Sort list view of entities and aliases alphabetically using the item name
|
||||
```
|
|
@ -18,6 +18,7 @@ export default Route.extend(ListRoute, {
|
|||
responsePath: 'data.keys',
|
||||
page: params.page,
|
||||
pageFilter: params.pageFilter,
|
||||
sortBy: 'name',
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.httpStatus === 404) {
|
||||
|
|
|
@ -18,6 +18,7 @@ export default Route.extend(ListRoute, {
|
|||
responsePath: 'data.keys',
|
||||
page: params.page,
|
||||
pageFilter: params.pageFilter,
|
||||
sortBy: 'name',
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.httpStatus === 404) {
|
||||
|
|
|
@ -9,6 +9,10 @@ import ApplicationSerializer from '../application';
|
|||
export default ApplicationSerializer.extend({
|
||||
normalizeItems(payload) {
|
||||
if (payload.data.keys && Array.isArray(payload.data.keys)) {
|
||||
if (typeof payload.data.keys[0] !== 'string') {
|
||||
// If keys is not an array of strings, it was already normalized into objects in extractLazyPaginatedData
|
||||
return payload.data.keys;
|
||||
}
|
||||
return payload.data.keys.map((key) => {
|
||||
const model = payload.data.key_info[key];
|
||||
model.id = key;
|
||||
|
|
|
@ -4,4 +4,15 @@
|
|||
*/
|
||||
|
||||
import IdentitySerializer from './_base';
|
||||
export default IdentitySerializer.extend();
|
||||
export default IdentitySerializer.extend({
|
||||
extractLazyPaginatedData(payload) {
|
||||
return payload.data.keys.map((key) => {
|
||||
const model = payload.data.key_info[key];
|
||||
model.id = key;
|
||||
if (payload.backend) {
|
||||
model.backend = payload.backend;
|
||||
}
|
||||
return model;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
@ -12,4 +12,14 @@ export default IdentitySerializer.extend(EmbeddedRecordsMixin, {
|
|||
attrs: {
|
||||
aliases: { embedded: 'always' },
|
||||
},
|
||||
extractLazyPaginatedData(payload) {
|
||||
return payload.data.keys.map((key) => {
|
||||
const model = payload.data.key_info[key];
|
||||
model.id = key;
|
||||
if (payload.backend) {
|
||||
model.backend = payload.backend;
|
||||
}
|
||||
return model;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
@ -12,6 +12,7 @@ import { assert } from '@ember/debug';
|
|||
import { set, get, computed } from '@ember/object';
|
||||
import clamp from 'vault/utils/clamp';
|
||||
import config from 'vault/config/environment';
|
||||
import sortObjects from 'vault/utils/sort-objects';
|
||||
|
||||
const { DEFAULT_PAGE_SIZE } = config.APP;
|
||||
|
||||
|
@ -185,11 +186,12 @@ export default Store.extend({
|
|||
// store data cache as { response, dataset}
|
||||
// also populated `lazyCaches` attribute
|
||||
storeDataset(modelName, query, response, array) {
|
||||
const dataSet = {
|
||||
const dataset = query.sortBy ? sortObjects(array, query.sortBy) : array;
|
||||
const value = {
|
||||
response,
|
||||
dataset: array,
|
||||
dataset,
|
||||
};
|
||||
this.setLazyCacheForModel(modelName, query, dataSet);
|
||||
this.setLazyCacheForModel(modelName, query, value);
|
||||
},
|
||||
|
||||
clearDataset(modelName) {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
export default function sortObjects(array, key) {
|
||||
if (Array.isArray(array) && array?.every((e) => e[key] && typeof e[key] === 'string')) {
|
||||
return array.sort((a, b) => {
|
||||
// ignore upper vs lowercase
|
||||
const valueA = a[key].toUpperCase();
|
||||
const valueB = b[key].toUpperCase();
|
||||
if (valueA < valueB) return -1;
|
||||
if (valueA > valueB) return 1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
// if not sortable, return original array
|
||||
return array;
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
import sortObjects from 'vault/utils/sort-objects';
|
||||
import { module, test } from 'qunit';
|
||||
|
||||
module('Unit | Utility | sort-objects', function () {
|
||||
test('it sorts array of objects', function (assert) {
|
||||
const originalArray = [
|
||||
{ foo: 'grape', bar: 'third' },
|
||||
{ foo: 'banana', bar: 'second' },
|
||||
{ foo: 'lemon', bar: 'fourth' },
|
||||
{ foo: 'apple', bar: 'first' },
|
||||
];
|
||||
const expectedArray = [
|
||||
{ bar: 'first', foo: 'apple' },
|
||||
{ bar: 'second', foo: 'banana' },
|
||||
{ bar: 'third', foo: 'grape' },
|
||||
{ bar: 'fourth', foo: 'lemon' },
|
||||
];
|
||||
|
||||
assert.propEqual(sortObjects(originalArray, 'foo'), expectedArray, 'it sorts array of objects');
|
||||
|
||||
const originalWithNumbers = [
|
||||
{ foo: 'Z', bar: 'fourth' },
|
||||
{ foo: '1', bar: 'first' },
|
||||
{ foo: '2', bar: 'second' },
|
||||
{ foo: 'A', bar: 'third' },
|
||||
];
|
||||
const expectedWithNumbers = [
|
||||
{ bar: 'first', foo: '1' },
|
||||
{ bar: 'second', foo: '2' },
|
||||
{ bar: 'third', foo: 'A' },
|
||||
{ bar: 'fourth', foo: 'Z' },
|
||||
];
|
||||
assert.propEqual(
|
||||
sortObjects(originalWithNumbers, 'foo'),
|
||||
expectedWithNumbers,
|
||||
'it sorts strings with numbers and letters'
|
||||
);
|
||||
});
|
||||
|
||||
test('it disregards capitalization', function (assert) {
|
||||
// sort() arranges capitalized values before lowercase, the helper removes case by making all strings toUppercase()
|
||||
const originalArray = [
|
||||
{ foo: 'something-a', bar: 'third' },
|
||||
{ foo: 'D-something', bar: 'second' },
|
||||
{ foo: 'SOMETHING-b', bar: 'fourth' },
|
||||
{ foo: 'a-something', bar: 'first' },
|
||||
];
|
||||
const expectedArray = [
|
||||
{ bar: 'first', foo: 'a-something' },
|
||||
{ bar: 'second', foo: 'D-something' },
|
||||
{ bar: 'third', foo: 'something-a' },
|
||||
{ bar: 'fourth', foo: 'SOMETHING-b' },
|
||||
];
|
||||
|
||||
assert.propEqual(
|
||||
sortObjects(originalArray, 'foo'),
|
||||
expectedArray,
|
||||
'it sorts array of objects regardless of capitalization'
|
||||
);
|
||||
});
|
||||
|
||||
test('it fails gracefully', function (assert) {
|
||||
const originalArray = [
|
||||
{ foo: 'b', bar: 'two' },
|
||||
{ foo: 'a', bar: 'one' },
|
||||
];
|
||||
assert.propEqual(
|
||||
sortObjects(originalArray, 'someKey'),
|
||||
originalArray,
|
||||
'it returns original array if key does not exist'
|
||||
);
|
||||
assert.deepEqual(sortObjects('not an array'), 'not an array', 'it returns original arg if not an array');
|
||||
|
||||
const notStrings = [
|
||||
{ foo: '1', bar: 'third' },
|
||||
{ foo: 'Z', bar: 'second' },
|
||||
{ foo: 1, bar: 'fourth' },
|
||||
{ foo: 2, bar: 'first' },
|
||||
];
|
||||
assert.propEqual(
|
||||
sortObjects(notStrings, 'foo'),
|
||||
notStrings,
|
||||
'it returns original array if values are not all strings'
|
||||
);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue