ui: Change URI helper to a template based approach (#9344)

This moves our uri helper to use a the template renderer we already have for rendering URLs.
This commit is contained in:
John Cowen 2020-12-09 09:22:46 +00:00 committed by hashicorp-ci
parent 4f3a0836ea
commit c3218f1bee
7 changed files with 99 additions and 22 deletions

View File

@ -1,8 +1,28 @@
<DataLoader @items={{item}} @src={{uri nspace dc type src}} @onchange={{action "setData"}} @once={{true}}>
<DataLoader
@items={{item}}
@src={{uri
'/${nspace}/${dc}/${type}/${src}'
(hash
nspace=nspace
dc=dc
type=type
src=src
)
}}
@onchange={{action "setData"}}
@once={{true}}
>
<BlockSlot @name="loaded">
<DataWriter
@sink={{uri nspace (or data.Datacenter dc) type}}
@sink={{uri
'/${nspace}/${dc}/${type}'
(hash
nspace=nspace
dc=(or data.Datacenter dc)
type=type
)
}}
@type={{type}}
@label={{label}}
@ondelete={{action ondelete}}

View File

@ -1,6 +1,14 @@
{{#if (not @noMetricsReason)}}
<DataSource
@src={{uri @nspace @dc 'metrics' 'summary-for-service' @service @protocol}}
@src={{uri
'/${nspace}/${dc}/metrics/summary-for-service/${service}/${protocol}'
(hash
nspace=@nspace
dc=@dc
service=@service
protocol=@protocol
)
}}
@onchange={{action 'change'}}
@onerror={{action (mut error) value="error"}}
/>

View File

@ -1,6 +1,15 @@
{{#if (not @noMetricsReason)}}
<DataSource
@src={{uri @nspace @dc 'metrics' @endpoint @service @protocol}}
@src={{uri
'/${nspace}/${dc}/metrics/${endpoint}/${service}/${protocol}'
(hash
nspace=@nspace
dc=@dc
endpoint=@endpoint
service=@service
protocol=@protocol
)
}}
@onchange={{action 'statsUpdate'}}
@onerror={{action (mut error) value="error"}}
/>

View File

@ -1,18 +1,19 @@
import { helper } from '@ember/component/helper';
import { get } from '@ember/object';
import Helper from '@ember/component/helper';
import { inject as service } from '@ember/service';
// Covers alpha-capitalized dot separated API keys such as
// `{{Name}}`, `{{Service.Name}}` etc. but not `{{}}`
// simple mustache regexp `/{{item.Name}}/`
const templateRe = /{{([A-Za-z.0-9_-]+)}}/g;
export default helper(function renderTemplate([template, vars]) {
if (typeof vars !== 'undefined' && typeof template !== 'undefined') {
return template.replace(templateRe, function(match, group) {
try {
return encodeURIComponent(get(vars, group) || '');
} catch (e) {
return '';
}
});
let render;
export default class RenderTemplateHelper extends Helper {
@service('encoder') encoder;
constructor() {
super(...arguments);
if (typeof render !== 'function') {
render = this.encoder.createRegExpEncoder(templateRe, encodeURIComponent, false);
}
}
return '';
});
compute([template, vars]) {
return render(template, vars);
}
}

View File

@ -1,10 +1,18 @@
import Helper from '@ember/component/helper';
import { inject as service } from '@ember/service';
const templateRe = /\${([A-Za-z.0-9_-]+)}/g;
let render;
export default class UriHelper extends Helper {
@service('encoder') encoder;
constructor() {
super(...arguments);
if (typeof render !== 'function') {
render = this.encoder.createRegExpEncoder(templateRe, encodeURIComponent);
}
}
compute(params, hash) {
return this.encoder.uriJoin(params);
compute([template, vars]) {
return render(template, vars);
}
}

View File

@ -1,10 +1,32 @@
import Service from '@ember/service';
import { get } from '@ember/object';
import { runInDebug } from '@ember/debug';
import atob from 'consul-ui/utils/atob';
import btoa from 'consul-ui/utils/btoa';
const createRegExpEncoder = function(re, encoder = str => str, strict = true) {
return (template = '', vars = {}) => {
if (template !== '') {
return template.replace(re, (match, group) => {
const value = get(vars, group);
runInDebug(() => {
if (strict && typeof value === 'undefined') {
console.error(new Error(`${group} is undefined in ${template}`));
}
});
return encoder(value || '');
});
}
return '';
};
};
export default class EncoderService extends Service {
uriComponent = encodeURIComponent;
createRegExpEncoder(re, encoder) {
return createRegExpEncoder(re, encoder);
}
atob() {
return atob(...arguments);
}

View File

@ -1,4 +1,13 @@
<DataLoader @src={{uri nspace dc 'intentions' 'for-service' slug}} as |api|>
<DataLoader
@src={{uri
'/${nspace}/${dc}/intentions/for-service/${slug}'
(hash
nspace=nspace
dc=dc
slug=slug
)
}}
as |api|>
<BlockSlot @name="error">
<ErrorState @error={{api.error}} />
</BlockSlot>