open-consul/ui-v2/app/services/repository/service.js
John Cowen 52b1a73d3b
ui: Use X-Range header as a signal as to whether to reconcile the ember-data store (#8384)
* ui: Use `X-Range` header/meta to decide whether to reconcile or not

Previously we used a `shouldReconcile` method in order to decide whether
a response should trigger a reconciliation of the frontend ember-data
'source of truth' or not. It's a lot nicer/clearer if this 'flag' can be set
alongside the HTTP request information, moreover we almost have the same
functionality in `If-Range`/`Partial Content` HTTP functionality.

Here we partly follow this HTTP semantics but use a custom `X-Range` header
instead.
2020-07-29 10:16:09 +02:00

85 lines
2.8 KiB
JavaScript

import RepositoryService from 'consul-ui/services/repository';
import { get, set } from '@ember/object';
const modelName = 'service';
export default RepositoryService.extend({
getModelName: function() {
return modelName;
},
findBySlug: function(slug, dc) {
return this._super(...arguments).then(function(item) {
// TODO: Move this to the Serializer
const nodes = get(item, 'Nodes');
if (nodes.length === 0) {
// TODO: Add an store.error("404", "message") or similar
// or move all this to serializer
const e = new Error();
e.errors = [
{
status: '404',
title: 'Not found',
},
];
throw e;
}
const service = get(nodes, 'firstObject');
// TODO: Use [...new Set()] instead of uniq
const tags = nodes
.reduce(function(prev, item) {
return prev.concat(get(item, 'Service.Tags') || []);
}, [])
.uniq();
set(service, 'Tags', tags);
set(service, 'Nodes', nodes);
set(service, 'meta', get(item, 'meta'));
set(service, 'Namespace', get(item, 'Namespace'));
return service;
});
},
findInstanceBySlug: function(id, node, slug, dc, nspace, configuration) {
return this.findBySlug(slug, dc, nspace, configuration).then(function(item) {
// TODO: Move this to the Serializer
// Loop through all the service instances and pick out the one
// that has the same service id AND node name
// node names are unique per datacenter
const i = item.Nodes.findIndex(function(item) {
return item.Service.ID === id && item.Node.Node === node;
});
if (i !== -1) {
const service = item.Nodes[i].Service;
service.Node = item.Nodes[i].Node;
service.ServiceChecks = item.Nodes[i].Checks.filter(function(item) {
return item.ServiceID != '';
});
service.NodeChecks = item.Nodes[i].Checks.filter(function(item) {
return item.ServiceID == '';
});
set(service, 'meta', get(item, 'meta'));
set(service, 'Namespace', get(item, 'Namespace'));
return service;
}
// TODO: Add an store.error("404", "message") or similar
// or move all this to serializer
const e = new Error();
e.errors = [
{
status: '404',
title: 'Unable to find instance',
},
];
throw e;
});
},
findGatewayBySlug: function(slug, dc, nspace, configuration = {}) {
const query = {
dc: dc,
ns: nspace,
gateway: slug,
};
if (typeof configuration.cursor !== 'undefined') {
query.index = configuration.cursor;
query.uri = configuration.uri;
}
return this.store.query(this.getModelName(), query);
},
});