ui: chore - upgrade ember and friends (#14518)

* v3.20.2...v3.24.0

* Fix handle undefined outlet in route component

* Don't use template helper for optional modal.open

Using the optional-helper here will trigger a computation
in the same runloop error. This is because we are setting
the `modal`-property when the `<Ref>` component gets
rendered which will update the `this.modal`-property which
will then recompute the `optional`-helper leading to this
error.

Instead we will create an action that will call the `open`-method
on the modal when it is defined. This gets rid of the double
computation error as we will not access the modal property
twice in the same runloop when `modal` is getting set.

* Fix - fn needs to be passed function tab-nav

We create functions in the component file instead
so that fn-helper stops complaining about the
need to pass a function.

* Update ember-exam to 6.1 version

"Makes it compatible" with ember-qunit v5

* scheduleOnce setMaxHeight paged-collection

We need to schedule to get around double-computation error.

* Fix - model.data is removed from ember-data

This has been private API all along - we need to
work around the removal.

Reference: https://github.com/emberjs/data/pull/7338/files#diff-9a8746fc5c86fd57e6122f00fef3155f76f0f3003a24b53fb7c4621d95dcd9bfL1310

* Fix `propContains` instead of `deepEqual` policy

Recent model.data works differently than iterating attributes.
We use `propContains` instead of `deepEqual`. We are only
interested in the properties we assert against and match
the previous behavior with this change.

* Fix `propContains` instead of `deepEqual` token

* Better handling single-records repo test-helper

`model.data` has been removed we need to handle proxies and
model instances differently.

* Fix remaining repository tests with propContains

We don't want to match entire objects - we don't care
about properties we haven't defined in the assertion.

* Don't use template helper for optional modal.open

Using a template helper will give us a recomputation error -
we work around it by creating an explicit action on
the component instead.

* Await `I $verb the $pageObject object` step

* Fix no more customization ember-can

No need to customize, the helper handles destruction
fine on its own.

* Fix - don't pass `optional` functions to fn

We will declare the functions on the component instead.
This gives us the same behavior but no error from
`fn`, which expects a function to be passed.

* Fix - handle `undefined` state on validate modifier

StateChart can yield out an undefined `state` we need
to handle that in the validate modifier

* Fix linting errors tests directory

* Warn / turn off new ember linting issues

We will tackle them one by one and don't want to
autofix issues that could be dangerous to auto-fix.

* Auto-fix linting issues

* More linting configuration

* Fix remaining linting issues

* Fix linting issues new files after rebase

* ui: Remove ember-cli-uglify config now we are using terser (#14574)

Co-authored-by: John Cowen <johncowen@users.noreply.github.com>
This commit is contained in:
Michael Klein 2022-09-15 10:43:17 +02:00 committed by GitHub
parent 057d28f90e
commit 03a1a86dfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
828 changed files with 6841 additions and 6517 deletions

View File

@ -1,96 +1,76 @@
<div <div class="consul-nspace-form" ...attributes>
class="consul-nspace-form"
...attributes
>
<DataWriter <DataWriter
@sink={{uri @sink={{uri
'/${partition}/${nspace}/${dc}/nspace' "/${partition}/${nspace}/${dc}/nspace"
(hash (hash partition="" nspace="" dc=@item.Datacenter)
partition=''
nspace=''
dc=@item.Datacenter
)
}} }}
@type={{'nspace'}} @type={{"nspace"}}
@label={{"Namespace"}} @label={{"Namespace"}}
@ondelete={{fn (if @ondelete @ondelete @onsubmit) @item}} @ondelete={{fn this.onDelete @item}}
@onchange={{fn (optional @onsubmit) @item}} @onchange={{fn this.onSubmit @item}}
as |writer|> as |writer|
>
<BlockSlot @name="removed" as |after|> <BlockSlot @name="removed" as |after|>
<Consul::Nspace::Notifications <Consul::Nspace::Notifications
{{notification {{notification after=(action after)}}
after=(action after)
}}
@type="remove" @type="remove"
/> />
</BlockSlot> </BlockSlot>
<BlockSlot @name="content"> <BlockSlot @name="content">
{{#let {{#let
(not (can "write nspaces")) (not (can "write nspaces"))
@item @item
(hash (hash
help='Must be a valid DNS hostname. Must contain 1-64 characters (numbers, letters, and hyphens), and must begin with a letter. Once created, this cannot be changed.' help="Must be a valid DNS hostname. Must contain 1-64 characters (numbers, letters, and hyphens), and must begin with a letter. Once created, this cannot be changed."
Name=(array Name=(array
(hash (hash
test='^[a-zA-Z0-9]([a-zA-Z0-9-]{0,62}[a-zA-Z0-9])?$' test="^[a-zA-Z0-9]([a-zA-Z0-9-]{0,62}[a-zA-Z0-9])?$"
error='Name must be a valid DNS hostname.' error="Name must be a valid DNS hostname."
) )
) )
) )
(hash Description=(array))
as |readOnly item Name Description|
}}
<form {{on "submit" (fn writer.persist item)}} {{disabled readOnly}}>
(hash <StateChart
Description=(array) @src={{state-chart "validate"}}
) as |State Guard ChartAction dispatch state|
>
as |readOnly item Name Description|}}
<form
{{on 'submit' (fn writer.persist item)}}
{{disabled readOnly}}
>
<StateChart
@src={{state-chart 'validate'}}
as |State Guard ChartAction dispatch state|>
<fieldset> <fieldset>
{{#if (is "new nspace" item=item)}} {{#if (is "new nspace" item=item)}}
<TextInput <TextInput
@name="Name" @name="Name"
@placeholder="Name" @placeholder="Name"
@item={{item}} @item={{item}}
@validations={{Name}} @validations={{Name}}
@chart={{hash @chart={{hash state=state dispatch=dispatch}}
state=state
dispatch=dispatch
}}
/> />
{{/if}} {{/if}}
<TextInput <TextInput
@expanded={{true}} @expanded={{true}}
@name="Description" @name="Description"
@label="Description (Optional)" @label="Description (Optional)"
@item={{item}} @item={{item}}
@validations={{Description}} @validations={{Description}}
@chart={{hash @chart={{hash state=state dispatch=dispatch}}
state=state
dispatch=dispatch
}}
/> />
</fieldset> </fieldset>
{{#if (can 'use acls')}} {{#if (can "use acls")}}
<fieldset id="roles"> <fieldset id="roles">
<h2>Roles</h2> <h2>Roles</h2>
<p> <p>
{{#if (can "write nspace" item=item)}} {{#if (can "write nspace" item=item)}}
By adding roles to this namespaces, you will apply them to all tokens created within this namespace. By adding roles to this namespaces, you will apply them to
{{else}} all tokens created within this namespace.
The following roles are applied to all tokens created within this namespace. {{else}}
{{/if}} The following roles are applied to all tokens created within
this namespace.
{{/if}}
</p> </p>
<RoleSelector <RoleSelector
@dc={{@dc}} @dc={{@dc}}
@ -103,11 +83,13 @@ as |State Guard ChartAction dispatch state|>
<fieldset id="policies"> <fieldset id="policies">
<h2>Policies</h2> <h2>Policies</h2>
<p> <p>
{{#if (not readOnly)}} {{#if (not readOnly)}}
By adding policies to this namespace, you will apply them to all tokens created within this namespace. By adding policies to this namespace, you will apply them to
{{else}} all tokens created within this namespace.
The following policies are applied to all tokens created within this namespace. {{else}}
{{/if}} The following policies are applied to all tokens created
within this namespace.
{{/if}}
</p> </p>
<PolicySelector <PolicySelector
@dc={{@dc}} @dc={{@dc}}
@ -118,33 +100,42 @@ as |State Guard ChartAction dispatch state|>
@items={{item.ACLs.PolicyDefaults}} @items={{item.ACLs.PolicyDefaults}}
/> />
</fieldset> </fieldset>
{{/if}} {{/if}}
<div> <div>
{{#if (and (is "new nspace" item=item) (can "create nspaces"))}} {{#if (and (is "new nspace" item=item) (can "create nspaces"))}}
<Action <Action
@type="submit" @type="submit"
{{disabled (or (is "pristine nspace" item=item) (state-matches state "error"))}} {{disabled
(or
(is "pristine nspace" item=item)
(state-matches state "error")
)
}}
> >
Save Save
</Action> </Action>
{{else if (can "write nspace" item=item)}} {{else if (can "write nspace" item=item)}}
<Action @type="submit">Save</Action> <Action @type="submit">Save</Action>
{{/if}} {{/if}}
<Action <Action @type="reset" {{on "click" (fn this.onCancel item)}}>
@type="reset"
{{on 'click' (if @oncancel (fn @oncancel item) (fn @onsubmit item))}}
>
Cancel Cancel
</Action> </Action>
{{#if (and (not (is "new nspace" item=item)) (can "delete nspace" item=item))}} {{#if
<ConfirmationDialog @message="Are you sure you want to delete this Namespace?"> (and
(not (is "new nspace" item=item))
(can "delete nspace" item=item)
)
}}
<ConfirmationDialog
@message="Are you sure you want to delete this Namespace?"
>
<BlockSlot @name="action" as |confirm|> <BlockSlot @name="action" as |confirm|>
<Action <Action
data-test-delete data-test-delete
class="type-delete" class="type-delete"
{{on 'click' (fn confirm (fn writer.delete item))}} {{on "click" (fn confirm (fn writer.delete item))}}
> >
Delete Delete
</Action> </Action>
@ -157,13 +148,12 @@ as |State Guard ChartAction dispatch state|>
/> />
</BlockSlot> </BlockSlot>
</ConfirmationDialog> </ConfirmationDialog>
{{/if}} {{/if}}
</div> </div>
</StateChart> </StateChart>
</form> </form>
{{/let}} {{/let}}
</BlockSlot> </BlockSlot>
</DataWriter> </DataWriter>
</div> </div>

View File

@ -0,0 +1,33 @@
import Component from "@glimmer/component";
import { action } from "@ember/object";
export default class NspaceForm extends Component {
@action onSubmit(item) {
const onSubmit = this.args.onsubmit;
if (onSubmit) return onSubmit(item);
}
@action onDelete(item) {
const { onsubmit, ondelete } = this.args;
if (ondelete) {
return ondelete(item);
} else {
if (onsubmit) {
return onsubmit(item);
}
}
}
@action onCancel(item) {
const { oncancel, onsubmit } = this.args;
if (oncancel) {
return oncancel(item);
} else {
if (onsubmit) {
return onsubmit(item);
}
}
}
}

View File

@ -13,16 +13,16 @@ const exists = fs.existsSync;
const chalk = require('chalk'); // comes with ember const chalk = require('chalk'); // comes with ember
// allow extra docfy config // allow extra docfy config
let user = {sources: [], labels: {}}; let user = { sources: [], labels: {} };
const $CONSUL_DOCFY_CONFIG = process.env.CONSUL_DOCFY_CONFIG || ''; const $CONSUL_DOCFY_CONFIG = process.env.CONSUL_DOCFY_CONFIG || '';
if($CONSUL_DOCFY_CONFIG.length > 0) { if ($CONSUL_DOCFY_CONFIG.length > 0) {
try { try {
if(exists($CONSUL_DOCFY_CONFIG)) { if (exists($CONSUL_DOCFY_CONFIG)) {
user = JSON.parse(read($CONSUL_DOCFY_CONFIG)); user = JSON.parse(read($CONSUL_DOCFY_CONFIG));
} else { } else {
throw new Error(`Unable to locate ${$CONSUL_DOCFY_CONFIG}`); throw new Error(`Unable to locate ${$CONSUL_DOCFY_CONFIG}`);
} }
} catch(e) { } catch (e) {
console.error(chalk.yellow(`Docfy: ${e.message}`)); console.error(chalk.yellow(`Docfy: ${e.message}`));
} }
} }
@ -33,24 +33,20 @@ refractor.register(handlebars);
refractor.alias({ refractor.alias({
handlebars: ['hbs'], handlebars: ['hbs'],
shell: ['sh'] shell: ['sh'],
}); });
module.exports = { module.exports = {
remarkHbsOptions: { remarkHbsOptions: {
escapeCurliesCode: false escapeCurliesCode: false,
}, },
remarkPlugins: [ remarkPlugins: [
autolinkHeadings, autolinkHeadings,
{ {
behavior: 'wrap' behavior: 'wrap',
} },
],
rehypePlugins: [
prism
], ],
rehypePlugins: [prism],
sources: [ sources: [
{ {
root: path.resolve(__dirname, 'docs'), root: path.resolve(__dirname, 'docs'),
@ -129,10 +125,10 @@ module.exports = {
pattern: '**/README.mdx', pattern: '**/README.mdx',
urlSchema: 'auto', urlSchema: 'auto',
urlPrefix: 'docs/consul-nspaces', urlPrefix: 'docs/consul-nspaces',
} },
].concat(user.sources), ].concat(user.sources),
labels: { labels: {
"consul": "Consul Components", consul: 'Consul Components',
...user.labels ...user.labels,
} },
}; };

View File

@ -15,6 +15,7 @@ app/utils/dom/event-target/event-target-shim/event.js
# misc # misc
/coverage/ /coverage/
!.* !.*
.eslintcache
# ember-try # ember-try
/.node_modules.ember-try/ /.node_modules.ember-try/

View File

@ -9,24 +9,44 @@ module.exports = {
}, },
}, },
plugins: ['ember'], plugins: ['ember'],
extends: ['eslint:recommended', 'plugin:ember/recommended'], extends: ['eslint:recommended', 'plugin:ember/recommended', 'plugin:prettier/recommended'],
env: { env: {
browser: true, browser: true,
}, },
rules: { rules: {
'no-console': ['error', {allow: ['error', 'info']}], 'no-console': ['error', { allow: ['error', 'info'] }],
'no-unused-vars': ['error', { args: 'none' }], 'no-unused-vars': ['error', { args: 'none' }],
'ember/no-new-mixins': ['warn'], 'ember/no-new-mixins': ['warn'],
'ember/no-jquery': 'warn', 'ember/no-jquery': 'warn',
'ember/no-global-jquery': 'warn', 'ember/no-global-jquery': 'warn',
// for 3.24 update
'ember/classic-decorator-no-classic-methods': ['warn'],
'ember/classic-decorator-hooks': ['warn'],
'ember/no-classic-classes': ['warn'],
'ember/no-mixins': ['warn'],
'ember/no-computed-properties-in-native-classes': ['warn'],
'ember/no-private-routing-service': ['warn'],
'ember/no-test-import-export': ['warn'],
'ember/no-actions-hash': ['warn'],
'ember/no-classic-components': ['warn'],
'ember/no-component-lifecycle-hooks': ['warn'],
'ember/require-tagless-components': ['warn'],
'ember/no-legacy-test-waiters': ['warn'],
'ember/no-empty-glimmer-component-classes': ['warn'],
'ember/no-get': ['off'], // be careful with autofix, might change behavior
'ember/require-computed-property-dependencies': ['off'], // be careful with autofix
'ember/use-ember-data-rfc-395-imports': ['off'], // be carful with autofix
'ember/require-super-in-lifecycle-hooks': ['off'], // be careful with autofix
'ember/require-computed-macros': ['off'], // be careful with autofix
}, },
overrides: [ overrides: [
// node files // node files
{ {
files: [ files: [
'.eslintrc.js', '.eslintrc.js',
'.dev.eslintrc.js',
'.docfy-config.js', '.docfy-config.js',
'.prettierrc.js',
'.template-lintrc.js', '.template-lintrc.js',
'ember-cli-build.js', 'ember-cli-build.js',
'testem.js', 'testem.js',

26
ui/packages/consul-ui/.gitignore vendored Normal file
View File

@ -0,0 +1,26 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist/
/tmp/
# dependencies
/bower_components/
/node_modules/
# misc
/.env*
/.pnp*
/.sass-cache
/.eslintcache
/connect.lock
/coverage/
/libpeerconnection.log
/npm-debug.log*
/testem.log
/yarn-error.log
# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/package.json.ember-try

View File

@ -0,0 +1,21 @@
# unconventional js
/blueprints/*/files/
/vendor/
# compiled output
/dist/
/tmp/
# dependencies
/bower_components/
/node_modules/
# misc
/coverage/
!.*
.eslintcache
# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/package.json.ember-try

View File

@ -0,0 +1,5 @@
'use strict';
module.exports = {
singleQuote: true,
};

View File

@ -54,7 +54,7 @@ export default class BaseAbility extends Ability {
get canRead() { get canRead() {
if (typeof this.item !== 'undefined') { if (typeof this.item !== 'undefined') {
const perm = (get(this, 'item.Resources') || []).find(item => item.Access === ACCESS_READ); const perm = (get(this, 'item.Resources') || []).find((item) => item.Access === ACCESS_READ);
if (perm) { if (perm) {
return perm.Allow; return perm.Allow;
} }
@ -64,7 +64,7 @@ export default class BaseAbility extends Ability {
get canList() { get canList() {
if (typeof this.item !== 'undefined') { if (typeof this.item !== 'undefined') {
const perm = (get(this, 'item.Resources') || []).find(item => item.Access === ACCESS_LIST); const perm = (get(this, 'item.Resources') || []).find((item) => item.Access === ACCESS_LIST);
if (perm) { if (perm) {
return perm.Allow; return perm.Allow;
} }
@ -74,7 +74,7 @@ export default class BaseAbility extends Ability {
get canWrite() { get canWrite() {
if (typeof this.item !== 'undefined') { if (typeof this.item !== 'undefined') {
const perm = (get(this, 'item.Resources') || []).find(item => item.Access === ACCESS_WRITE); const perm = (get(this, 'item.Resources') || []).find((item) => item.Access === ACCESS_WRITE);
if (perm) { if (perm) {
return perm.Allow; return perm.Allow;
} }

View File

@ -5,13 +5,12 @@ export default class IntentionAbility extends BaseAbility {
get canWrite() { get canWrite() {
// Peered intentions aren't writable // Peered intentions aren't writable
if(typeof this.item !== 'undefined' && typeof this.item.SourcePeer !== 'undefined') { if (typeof this.item !== 'undefined' && typeof this.item.SourcePeer !== 'undefined') {
return false; return false;
} }
return super.canWrite && return super.canWrite && (typeof this.item === 'undefined' || !this.canViewCRD);
(typeof this.item === 'undefined' || !this.canViewCRD);
} }
get canViewCRD() { get canViewCRD() {
return (typeof this.item !== 'undefined' && this.item.IsManagedByCRD); return typeof this.item !== 'undefined' && this.item.IsManagedByCRD;
} }
} }

View File

@ -11,10 +11,7 @@ export default class PeerAbility extends BaseAbility {
return this.canDelete; return this.canDelete;
} }
get canDelete() { get canDelete() {
return ![ return !['DELETING', 'TERMINATED'].includes(this.item.State) && super.canDelete;
'DELETING',
'TERMINATED'
].includes(this.item.State) && super.canDelete;
} }
get canUse() { get canUse() {

View File

@ -6,7 +6,9 @@ export default class ServiceInstanceAbility extends BaseAbility {
// When we ask for service-instances its almost like a request for a single service // When we ask for service-instances its almost like a request for a single service
// When we do that we also want to know if we can read/write intentions for services // When we do that we also want to know if we can read/write intentions for services
// so here we add intentions read/write for the specific segment/service prefix // so here we add intentions read/write for the specific segment/service prefix
return super.generateForSegment(...arguments).concat([ return super
.generateForSegment(...arguments)
.concat([
this.permissions.generate('intention', ACCESS_READ, segment), this.permissions.generate('intention', ACCESS_READ, segment),
this.permissions.generate('intention', ACCESS_WRITE, segment), this.permissions.generate('intention', ACCESS_WRITE, segment),
]); ]);

View File

@ -12,7 +12,7 @@ export default class ZerviceAbility extends BaseAbility {
return false; return false;
} }
const found = this.item.Resources.find( const found = this.item.Resources.find(
item => item.Resource === 'intention' && item.Access === 'read' && item.Allow === true (item) => item.Resource === 'intention' && item.Access === 'read' && item.Allow === true
); );
return typeof found !== 'undefined'; return typeof found !== 'undefined';
} }
@ -22,7 +22,7 @@ export default class ZerviceAbility extends BaseAbility {
return false; return false;
} }
const found = this.item.Resources.find( const found = this.item.Resources.find(
item => item.Resource === 'intention' && item.Access === 'write' && item.Allow === true (item) => item.Resource === 'intention' && item.Access === 'write' && item.Allow === true
); );
return typeof found !== 'undefined'; return typeof found !== 'undefined';
} }

View File

@ -15,24 +15,24 @@ import AdapterError, {
// `serialized, unserialized` and the other just `query` // `serialized, unserialized` and the other just `query`
// they could actually be one function now, but would be nice to think about // they could actually be one function now, but would be nice to think about
// the naming of things (serialized vs query etc) // the naming of things (serialized vs query etc)
const read = function(adapter, modelName, type, query = {}) { const read = function (adapter, modelName, type, query = {}) {
return adapter.rpc( return adapter.rpc(
function(adapter, ...rest) { function (adapter, ...rest) {
return adapter[`requestFor${type}`](...rest); return adapter[`requestFor${type}`](...rest);
}, },
function(serializer, ...rest) { function (serializer, ...rest) {
return serializer[`respondFor${type}`](...rest); return serializer[`respondFor${type}`](...rest);
}, },
query, query,
modelName modelName
); );
}; };
const write = function(adapter, modelName, type, snapshot) { const write = function (adapter, modelName, type, snapshot) {
return adapter.rpc( return adapter.rpc(
function(adapter, ...rest) { function (adapter, ...rest) {
return adapter[`requestFor${type}`](...rest); return adapter[`requestFor${type}`](...rest);
}, },
function(serializer, ...rest) { function (serializer, ...rest) {
return serializer[`respondFor${type}`](...rest); return serializer[`respondFor${type}`](...rest);
}, },
snapshot, snapshot,
@ -66,13 +66,13 @@ export default class HttpAdapter extends Adapter {
} }
return client return client
.request(function(request) { .request(function (request) {
return req(adapter, request, serialized, unserialized, modelClass); return req(adapter, request, serialized, unserialized, modelClass);
}) })
.catch(function(e) { .catch(function (e) {
return adapter.error(e); return adapter.error(e);
}) })
.then(function(respond) { .then(function (respond) {
// TODO: When HTTPAdapter:responder changes, this will also need to change // TODO: When HTTPAdapter:responder changes, this will also need to change
return resp(serializer, respond, serialized, unserialized, modelClass); return resp(serializer, respond, serialized, unserialized, modelClass);
}); });

View File

@ -58,10 +58,10 @@ export default class NodeAdapter extends Adapter {
queryLeader(store, type, id, snapshot) { queryLeader(store, type, id, snapshot) {
return this.rpc( return this.rpc(
function(adapter, request, serialized, unserialized) { function (adapter, request, serialized, unserialized) {
return adapter.requestForQueryLeader(request, serialized, unserialized); return adapter.requestForQueryLeader(request, serialized, unserialized);
}, },
function(serializer, respond, serialized, unserialized) { function (serializer, respond, serialized, unserialized) {
return serializer.respondForQueryLeader(respond, serialized, unserialized); return serializer.respondForQueryLeader(respond, serialized, unserialized);
}, },
snapshot, snapshot,

View File

@ -40,8 +40,8 @@ export default class NspaceAdapter extends Adapter {
Name: serialized.Name, Name: serialized.Name,
Description: serialized.Description, Description: serialized.Description,
ACLs: { ACLs: {
PolicyDefaults: serialized.ACLs.PolicyDefaults.map(item => ({ ID: item.ID })), PolicyDefaults: serialized.ACLs.PolicyDefaults.map((item) => ({ ID: item.ID })),
RoleDefaults: serialized.ACLs.RoleDefaults.map(item => ({ ID: item.ID })), RoleDefaults: serialized.ACLs.RoleDefaults.map((item) => ({ ID: item.ID })),
}, },
}} }}
`; `;
@ -57,8 +57,8 @@ export default class NspaceAdapter extends Adapter {
${{ ${{
Description: serialized.Description, Description: serialized.Description,
ACLs: { ACLs: {
PolicyDefaults: serialized.ACLs.PolicyDefaults.map(item => ({ ID: item.ID })), PolicyDefaults: serialized.ACLs.PolicyDefaults.map((item) => ({ ID: item.ID })),
RoleDefaults: serialized.ACLs.RoleDefaults.map(item => ({ ID: item.ID })), RoleDefaults: serialized.ACLs.RoleDefaults.map((item) => ({ ID: item.ID })),
}, },
}} }}
`; `;

View File

@ -67,10 +67,10 @@ export default class OidcProviderAdapter extends Adapter {
authorize(store, type, id, snapshot) { authorize(store, type, id, snapshot) {
return this.rpc( return this.rpc(
function(adapter, request, serialized, unserialized) { function (adapter, request, serialized, unserialized) {
return adapter.requestForAuthorize(request, serialized, unserialized); return adapter.requestForAuthorize(request, serialized, unserialized);
}, },
function(serializer, respond, serialized, unserialized) { function (serializer, respond, serialized, unserialized) {
return serializer.respondForAuthorize(respond, serialized, unserialized); return serializer.respondForAuthorize(respond, serialized, unserialized);
}, },
snapshot, snapshot,
@ -80,10 +80,10 @@ export default class OidcProviderAdapter extends Adapter {
logout(store, type, id, snapshot) { logout(store, type, id, snapshot) {
return this.rpc( return this.rpc(
function(adapter, request, serialized, unserialized) { function (adapter, request, serialized, unserialized) {
return adapter.requestForLogout(request, serialized, unserialized); return adapter.requestForLogout(request, serialized, unserialized);
}, },
function(serializer, respond, serialized, unserialized) { function (serializer, respond, serialized, unserialized) {
// its ok to return nothing here for the moment at least // its ok to return nothing here for the moment at least
return {}; return {};
}, },

View File

@ -16,10 +16,10 @@ export default class PermissionAdapter extends Adapter {
// ^ same goes for Partitions // ^ same goes for Partitions
if (this.env.var('CONSUL_NSPACES_ENABLED')) { if (this.env.var('CONSUL_NSPACES_ENABLED')) {
resources = resources.map(item => ({ ...item, Namespace: ns })); resources = resources.map((item) => ({ ...item, Namespace: ns }));
} }
if (this.env.var('CONSUL_PARTITIONS_ENABLED')) { if (this.env.var('CONSUL_PARTITIONS_ENABLED')) {
resources = resources.map(item => ({ ...item, Partition: partition })); resources = resources.map((item) => ({ ...item, Partition: partition }));
} }
return request` return request`
POST /v1/internal/acl/authorize?${{ dc }} POST /v1/internal/acl/authorize?${{ dc }}
@ -40,24 +40,24 @@ export default class PermissionAdapter extends Adapter {
// Same goes ^ for partitions // Same goes ^ for partitions
const nspacesEnabled = this.env.var('CONSUL_NSPACES_ENABLED'); const nspacesEnabled = this.env.var('CONSUL_NSPACES_ENABLED');
const partitionsEnabled = this.env.var('CONSUL_PARTITIONS_ENABLED'); const partitionsEnabled = this.env.var('CONSUL_PARTITIONS_ENABLED');
if(nspacesEnabled || partitionsEnabled) { if (nspacesEnabled || partitionsEnabled) {
const token = await this.settings.findBySlug('token'); const token = await this.settings.findBySlug('token');
if(nspacesEnabled) { if (nspacesEnabled) {
if(typeof serialized.ns === 'undefined' || serialized.ns.length === 0) { if (typeof serialized.ns === 'undefined' || serialized.ns.length === 0) {
serialized.ns = token.Namespace; serialized.ns = token.Namespace;
} }
} }
if(partitionsEnabled) { if (partitionsEnabled) {
if(typeof serialized.partition === 'undefined' || serialized.partition.length === 0) { if (typeof serialized.partition === 'undefined' || serialized.partition.length === 0) {
serialized.partition = token.Partition; serialized.partition = token.Partition;
} }
} }
} }
return adapter.requestForAuthorize(request, serialized); return adapter.requestForAuthorize(request, serialized);
}, },
function(serializer, respond, serialized, unserialized) { function (serializer, respond, serialized, unserialized) {
// Completely skip the serializer here // Completely skip the serializer here
return respond(function(headers, body) { return respond(function (headers, body) {
return body; return body;
}); });
}, },

View File

@ -134,10 +134,10 @@ export default class TokenAdapter extends Adapter {
// services/store.js // services/store.js
self(store, type, id, unserialized) { self(store, type, id, unserialized) {
return this.rpc( return this.rpc(
function(adapter, request, serialized, data) { function (adapter, request, serialized, data) {
return adapter.requestForSelf(request, serialized, data); return adapter.requestForSelf(request, serialized, data);
}, },
function(serializer, respond, serialized, data) { function (serializer, respond, serialized, data) {
return serializer.respondForSelf(respond, serialized, data); return serializer.respondForSelf(respond, serialized, data);
}, },
unserialized, unserialized,
@ -147,7 +147,7 @@ export default class TokenAdapter extends Adapter {
clone(store, type, id, snapshot) { clone(store, type, id, snapshot) {
return this.rpc( return this.rpc(
function(adapter, request, serialized, data) { function (adapter, request, serialized, data) {
return adapter.requestForCloneRecord(request, serialized, data); return adapter.requestForCloneRecord(request, serialized, data);
}, },
(serializer, respond, serialized, data) => { (serializer, respond, serialized, data) => {

View File

@ -14,20 +14,20 @@ const ARROW_DOWN = 40;
const keys = { const keys = {
vertical: { vertical: {
[ARROW_DOWN]: function($items, i = -1) { [ARROW_DOWN]: function ($items, i = -1) {
return (i + 1) % $items.length; return (i + 1) % $items.length;
}, },
[ARROW_UP]: function($items, i = 0) { [ARROW_UP]: function ($items, i = 0) {
if (i === 0) { if (i === 0) {
return $items.length - 1; return $items.length - 1;
} else { } else {
return i - 1; return i - 1;
} }
}, },
[HOME]: function($items, i) { [HOME]: function ($items, i) {
return 0; return 0;
}, },
[END]: function($items, i) { [END]: function ($items, i) {
return $items.length - 1; return $items.length - 1;
}, },
}, },
@ -43,29 +43,29 @@ export default Component.extend({
expanded: false, expanded: false,
orientation: 'vertical', orientation: 'vertical',
keyboardAccess: true, keyboardAccess: true,
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
set(this, 'guid', this.dom.guid(this)); set(this, 'guid', this.dom.guid(this));
this._listeners = this.dom.listeners(); this._listeners = this.dom.listeners();
this._routelisteners = this.dom.listeners(); this._routelisteners = this.dom.listeners();
}, },
didInsertElement: function() { didInsertElement: function () {
// TODO: How do you detect whether the children have changed? // TODO: How do you detect whether the children have changed?
// For now we know that these elements exist and never change // For now we know that these elements exist and never change
this.$menu = this.dom.element(`#${COMPONENT_ID}menu-${this.guid}`); this.$menu = this.dom.element(`#${COMPONENT_ID}menu-${this.guid}`);
const labelledBy = this.$menu.getAttribute('aria-labelledby'); const labelledBy = this.$menu.getAttribute('aria-labelledby');
this.$trigger = this.dom.element(`#${labelledBy}`); this.$trigger = this.dom.element(`#${labelledBy}`);
}, },
willDestroyElement: function() { willDestroyElement: function () {
this._super(...arguments); this._super(...arguments);
this._listeners.remove(); this._listeners.remove();
this._routelisteners.remove(); this._routelisteners.remove();
}, },
actions: { actions: {
keypressClick: function(e) { keypressClick: function (e) {
e.target.dispatchEvent(new MouseEvent('click')); e.target.dispatchEvent(new MouseEvent('click'));
}, },
keypress: function(e) { keypress: function (e) {
// If the event is from the trigger and its not an opening/closing // If the event is from the trigger and its not an opening/closing
// key then don't do anything // key then don't do anything
if (![ENTER, SPACE, ARROW_UP, ARROW_DOWN].includes(e.keyCode)) { if (![ENTER, SPACE, ARROW_UP, ARROW_DOWN].includes(e.keyCode)) {
@ -99,7 +99,7 @@ export default Component.extend({
const $focused = this.dom.element(`${MENU_ITEMS}:focus`, this.$menu); const $focused = this.dom.element(`${MENU_ITEMS}:focus`, this.$menu);
let i; let i;
if ($focused) { if ($focused) {
i = $items.findIndex(function($item) { i = $items.findIndex(function ($item) {
return $item === $focused; return $item === $focused;
}); });
} }
@ -108,7 +108,7 @@ export default Component.extend({
}, },
// TODO: The argument here needs to change to an event // TODO: The argument here needs to change to an event
// see toggle-button.change // see toggle-button.change
change: function(e) { change: function (e) {
const open = e.target.checked; const open = e.target.checked;
if (open) { if (open) {
this.actions.open.apply(this, [e]); this.actions.open.apply(this, [e]);
@ -116,7 +116,7 @@ export default Component.extend({
this.actions.close.apply(this, [e]); this.actions.close.apply(this, [e]);
} }
}, },
close: function(e) { close: function (e) {
this._listeners.remove(); this._listeners.remove();
set(this, 'expanded', false); set(this, 'expanded', false);
// TODO: Find a better way to do this without using next // TODO: Find a better way to do this without using next
@ -127,7 +127,7 @@ export default Component.extend({
this.$trigger.removeAttribute('tabindex'); this.$trigger.removeAttribute('tabindex');
}); });
}, },
open: function(e) { open: function (e) {
set(this, 'expanded', true); set(this, 'expanded', true);
const $items = [...this.dom.elements(MENU_ITEMS, this.$menu)]; const $items = [...this.dom.elements(MENU_ITEMS, this.$menu)];
if ($items.length === 0) { if ($items.length === 0) {
@ -138,7 +138,7 @@ export default Component.extend({
// Take the trigger out of the tabbing whilst the menu is open // Take the trigger out of the tabbing whilst the menu is open
this.$trigger.setAttribute('tabindex', '-1'); this.$trigger.setAttribute('tabindex', '-1');
this._listeners.add(this.dom.document(), { this._listeners.add(this.dom.document(), {
keydown: e => { keydown: (e) => {
// Keep focus on the trigger when you close via ESC // Keep focus on the trigger when you close via ESC
if (e.keyCode === ESC) { if (e.keyCode === ESC) {
this.$trigger.focus(); this.$trigger.focus();

View File

@ -1,6 +1,7 @@
export default (submitable, clickable, attribute) => (scope = '.auth-form') => { export default (submitable, clickable, attribute) =>
(scope = '.auth-form') => {
return { return {
scope: scope, scope: scope,
...submitable(), ...submitable(),
}; };
}; };

View File

@ -8,10 +8,10 @@ import { task } from 'ember-concurrency';
import Slotted from 'block-slots'; import Slotted from 'block-slots';
export default Component.extend(Slotted, { export default Component.extend(Slotted, {
onchange: function() {}, onchange: function () {},
tagName: '', tagName: '',
error: function() {}, error: function () {},
type: '', type: '',
dom: service('dom'), dom: service('dom'),
@ -21,17 +21,17 @@ export default Component.extend(Slotted, {
selectedOptions: alias('items'), selectedOptions: alias('items'),
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this._listeners = this.dom.listeners(); this._listeners = this.dom.listeners();
this.form = this.formContainer.form(this.type); set(this, 'form', this.formContainer.form(this.type));
this.form.clear({ Datacenter: this.dc, Namespace: this.nspace }); this.form.clear({ Datacenter: this.dc, Namespace: this.nspace });
}, },
willDestroyElement: function() { willDestroyElement: function () {
this._super(...arguments); this._super(...arguments);
this._listeners.remove(); this._listeners.remove();
}, },
options: computed('selectedOptions.[]', 'allOptions.[]', function() { options: computed('selectedOptions.[]', 'allOptions.[]', function () {
// It's not massively important here that we are defaulting `items` and // It's not massively important here that we are defaulting `items` and
// losing reference as its just to figure out the diff // losing reference as its just to figure out the diff
let options = this.allOptions || []; let options = this.allOptions || [];
@ -40,11 +40,11 @@ export default Component.extend(Slotted, {
// filter out any items from the available options that have already been // filter out any items from the available options that have already been
// selected/added // selected/added
// TODO: find a proper ember-data diff // TODO: find a proper ember-data diff
options = options.filter(item => !items.findBy('ID', get(item, 'ID'))); options = options.filter((item) => !items.findBy('ID', get(item, 'ID')));
} }
return options; return options;
}), }),
save: task(function*(item, items, success = function() {}) { save: task(function* (item, items, success = function () {}) {
const repo = this.repo; const repo = this.repo;
try { try {
item = yield repo.persist(item); item = yield repo.persist(item);
@ -64,14 +64,14 @@ export default Component.extend(Slotted, {
} }
}), }),
actions: { actions: {
reset: function() { reset: function () {
this.form.clear({ Datacenter: this.dc, Namespace: this.nspace, Partition: this.partition }); this.form.clear({ Datacenter: this.dc, Namespace: this.nspace, Partition: this.partition });
}, },
remove: function(item, items) { remove: function (item, items) {
const prop = this.repo.getSlugKey(); const prop = this.repo.getSlugKey();
const value = get(item, prop); const value = get(item, prop);
const pos = items.findIndex(function(item) { const pos = items.findIndex(function (item) {
return get(item, prop) === value; return get(item, prop) === value;
}); });
if (pos !== -1) { if (pos !== -1) {
@ -79,7 +79,7 @@ export default Component.extend(Slotted, {
} }
this.onchange({ target: this }); this.onchange({ target: this });
}, },
change: function(e, value, item) { change: function (e, value, item) {
const event = this.dom.normalizeEvent(...arguments); const event = this.dom.normalizeEvent(...arguments);
const items = value; const items = value;
switch (event.target.name) { switch (event.target.name) {

View File

@ -17,20 +17,20 @@ export default Component.extend({
readonly: false, readonly: false,
syntax: '', syntax: '',
// TODO: Change this to oninput to be consistent? We'll have to do it throughout the templates // TODO: Change this to oninput to be consistent? We'll have to do it throughout the templates
onkeyup: function() {}, onkeyup: function () {},
oninput: function() {}, oninput: function () {},
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
set(this, 'modes', this.helper.modes()); set(this, 'modes', this.helper.modes());
}, },
didReceiveAttrs: function() { didReceiveAttrs: function () {
this._super(...arguments); this._super(...arguments);
const editor = this.editor; const editor = this.editor;
if (editor) { if (editor) {
editor.setOption('readOnly', this.readonly); editor.setOption('readOnly', this.readonly);
} }
}, },
setMode: function(mode) { setMode: function (mode) {
let options = { let options = {
...DEFAULTS, ...DEFAULTS,
mode: mode.mime, mode: mode.mime,
@ -48,13 +48,13 @@ export default Component.extend({
this.helper.lint(editor, mode.mode); this.helper.lint(editor, mode.mode);
set(this, 'mode', mode); set(this, 'mode', mode);
}, },
willDestroyElement: function() { willDestroyElement: function () {
this._super(...arguments); this._super(...arguments);
if (this.observer) { if (this.observer) {
this.observer.disconnect(); this.observer.disconnect();
} }
}, },
didInsertElement: function() { didInsertElement: function () {
this._super(...arguments); this._super(...arguments);
const $code = this.dom.element('textarea ~ pre code', this.element); const $code = this.dom.element('textarea ~ pre code', this.element);
if ($code.firstChild) { if ($code.firstChild) {
@ -70,11 +70,11 @@ export default Component.extend({
set(this, 'value', $code.firstChild.wholeText); set(this, 'value', $code.firstChild.wholeText);
} }
set(this, 'editor', this.helper.getEditor(this.element)); set(this, 'editor', this.helper.getEditor(this.element));
this.settings.findBySlug('code-editor').then(mode => { this.settings.findBySlug('code-editor').then((mode) => {
const modes = this.modes; const modes = this.modes;
const syntax = this.syntax; const syntax = this.syntax;
if (syntax) { if (syntax) {
mode = modes.find(function(item) { mode = modes.find(function (item) {
return item.name.toLowerCase() == syntax.toLowerCase(); return item.name.toLowerCase() == syntax.toLowerCase();
}); });
} }
@ -82,11 +82,11 @@ export default Component.extend({
this.setMode(mode); this.setMode(mode);
}); });
}, },
didAppear: function() { didAppear: function () {
this.editor.refresh(); this.editor.refresh();
}, },
actions: { actions: {
change: function(value) { change: function (value) {
this.settings.persist({ this.settings.persist({
'code-editor': value, 'code-editor': value,
}); });

View File

@ -10,14 +10,14 @@ export default Component.extend(Slotted, {
confirming: false, confirming: false,
permanent: false, permanent: false,
actions: { actions: {
cancel: function() { cancel: function () {
set(this, 'confirming', false); set(this, 'confirming', false);
}, },
execute: function() { execute: function () {
set(this, 'confirming', false); set(this, 'confirming', false);
this.sendAction(...['actionName', ...this['arguments']]); this.sendAction(...['actionName', ...this['arguments']]);
}, },
confirm: function() { confirm: function () {
const [action, ...args] = arguments; const [action, ...args] = arguments;
set(this, 'actionName', action); set(this, 'actionName', action);
set(this, 'arguments', args); set(this, 'arguments', args);

View File

@ -11,13 +11,13 @@ export default Component.extend({
classNames: ['discovery-chain'], classNames: ['discovery-chain'],
classNameBindings: ['active'], classNameBindings: ['active'],
selectedId: '', selectedId: '',
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this._listeners = this.dom.listeners(); this._listeners = this.dom.listeners();
}, },
didInsertElement: function() { didInsertElement: function () {
this._listeners.add(this.dom.document(), { this._listeners.add(this.dom.document(), {
click: e => { click: (e) => {
// all route/splitter/resolver components currently // all route/splitter/resolver components currently
// have classes that end in '-card' // have classes that end in '-card'
if (!this.dom.closest('[class$="-card"]', e.target)) { if (!this.dom.closest('[class$="-card"]', e.target)) {
@ -27,21 +27,21 @@ export default Component.extend({
}, },
}); });
}, },
willDestroyElement: function() { willDestroyElement: function () {
this._super(...arguments); this._super(...arguments);
this._listeners.remove(); this._listeners.remove();
this.ticker.destroy(this); this.ticker.destroy(this);
}, },
splitters: computed('chain.Nodes', function() { splitters: computed('chain.Nodes', function () {
return getSplitters(get(this, 'chain.Nodes')); return getSplitters(get(this, 'chain.Nodes'));
}), }),
routes: computed('chain.Nodes', function() { routes: computed('chain.Nodes', function () {
const routes = getRoutes(get(this, 'chain.Nodes'), this.dom.guid); const routes = getRoutes(get(this, 'chain.Nodes'), this.dom.guid);
// if we have no routes with a PathPrefix of '/' or one with no definition at all // if we have no routes with a PathPrefix of '/' or one with no definition at all
// then add our own 'default catch all' // then add our own 'default catch all'
if ( if (
!routes.find(item => get(item, 'Definition.Match.HTTP.PathPrefix') === '/') && !routes.find((item) => get(item, 'Definition.Match.HTTP.PathPrefix') === '/') &&
!routes.find(item => typeof item.Definition === 'undefined') !routes.find((item) => typeof item.Definition === 'undefined')
) { ) {
let nextNode; let nextNode;
const resolverID = `resolver:${this.chain.ServiceName}.${this.chain.Namespace}.${this.chain.Partition}.${this.chain.Datacenter}`; const resolverID = `resolver:${this.chain.ServiceName}.${this.chain.Namespace}.${this.chain.Partition}.${this.chain.Datacenter}`;
@ -72,7 +72,7 @@ export default Component.extend({
} }
return routes; return routes;
}), }),
nodes: computed('routes', 'splitters', 'resolvers', function() { nodes: computed('routes', 'splitters', 'resolvers', function () {
let nodes = this.resolvers.reduce((prev, item) => { let nodes = this.resolvers.reduce((prev, item) => {
prev[`resolver:${item.ID}`] = item; prev[`resolver:${item.ID}`] = item;
item.Children.reduce((prev, item) => { item.Children.reduce((prev, item) => {
@ -94,7 +94,7 @@ export default Component.extend({
value.NextItem = nodes[value.NextNode]; value.NextItem = nodes[value.NextNode];
} }
if (typeof value.Splits !== 'undefined') { if (typeof value.Splits !== 'undefined') {
value.Splits.forEach(item => { value.Splits.forEach((item) => {
if (typeof item.NextNode !== 'undefined') { if (typeof item.NextNode !== 'undefined') {
item.NextItem = nodes[item.NextNode]; item.NextItem = nodes[item.NextNode];
} }
@ -103,7 +103,7 @@ export default Component.extend({
}); });
return ''; return '';
}), }),
resolvers: computed('chain.{Nodes,Targets}', function() { resolvers: computed('chain.{Nodes,Targets}', function () {
return getResolvers( return getResolvers(
this.chain.Datacenter, this.chain.Datacenter,
this.chain.Partition, this.chain.Partition,
@ -112,10 +112,10 @@ export default Component.extend({
get(this, 'chain.Nodes') get(this, 'chain.Nodes')
); );
}), }),
graph: computed('splitters', 'routes.[]', function() { graph: computed('splitters', 'routes.[]', function () {
const graph = this.dataStructs.graph(); const graph = this.dataStructs.graph();
this.splitters.forEach(item => { this.splitters.forEach((item) => {
item.Splits.forEach(splitter => { item.Splits.forEach((splitter) => {
graph.addLink(item.ID, splitter.NextNode); graph.addLink(item.ID, splitter.NextNode);
}); });
}); });
@ -124,7 +124,7 @@ export default Component.extend({
}); });
return graph; return graph;
}), }),
selected: computed('selectedId', 'graph', function() { selected: computed('selectedId', 'graph', function () {
if (this.selectedId === '' || !this.dom.element(`#${this.selectedId}`)) { if (this.selectedId === '' || !this.dom.element(`#${this.selectedId}`)) {
return {}; return {};
} }
@ -144,12 +144,12 @@ export default Component.extend({
}); });
}); });
return { return {
nodes: nodes.map(item => `#${CSS.escape(item)}`), nodes: nodes.map((item) => `#${CSS.escape(item)}`),
edges: edges.map(item => `#${CSS.escape(item)}`), edges: edges.map((item) => `#${CSS.escape(item)}`),
}; };
}), }),
actions: { actions: {
click: function(e) { click: function (e) {
const id = e.currentTarget.getAttribute('id'); const id = e.currentTarget.getAttribute('id');
if (id === this.selectedId) { if (id === this.selectedId) {
set(this, 'active', false); set(this, 'active', false);

View File

@ -4,7 +4,7 @@ import { get } from '@ember/object';
export default class RouteCard extends Component { export default class RouteCard extends Component {
get path() { get path() {
return Object.entries(get(this.args.item, 'Definition.Match.HTTP') || {}).reduce( return Object.entries(get(this.args.item, 'Definition.Match.HTTP') || {}).reduce(
function(prev, [key, value]) { function (prev, [key, value]) {
if (key.toLowerCase().startsWith('path')) { if (key.toLowerCase().startsWith('path')) {
return { return {
type: key.replace('Path', ''), type: key.replace('Path', ''),

View File

@ -1,7 +1,7 @@
const getNodesByType = function(nodes = {}, type) { const getNodesByType = function (nodes = {}, type) {
return Object.values(nodes).filter(item => item.Type === type); return Object.values(nodes).filter((item) => item.Type === type);
}; };
const findResolver = function(resolvers, service, nspace = 'default', partition = 'default', dc) { const findResolver = function (resolvers, service, nspace = 'default', partition = 'default', dc) {
if (typeof resolvers[service] === 'undefined') { if (typeof resolvers[service] === 'undefined') {
resolvers[service] = { resolvers[service] = {
ID: `${service}.${nspace}.${partition}.${dc}`, ID: `${service}.${nspace}.${partition}.${dc}`,
@ -11,16 +11,16 @@ const findResolver = function(resolvers, service, nspace = 'default', partition
} }
return resolvers[service]; return resolvers[service];
}; };
export const getAlternateServices = function(targets, a) { export const getAlternateServices = function (targets, a) {
let type; let type;
const Targets = targets.map(function(b) { const Targets = targets.map(function (b) {
// TODO: this isn't going to work past namespace for services // TODO: this isn't going to work past namespace for services
// with dots in the name, but by the time that becomes an issue // with dots in the name, but by the time that becomes an issue
// we might have more data from the endpoint so we don't have to guess // we might have more data from the endpoint so we don't have to guess
// right now the backend also doesn't support dots in service names // right now the backend also doesn't support dots in service names
const [aRev, bRev] = [a, b].map(item => item.split('.').reverse()); const [aRev, bRev] = [a, b].map((item) => item.split('.').reverse());
const types = ['Datacenter', 'Partition', 'Namespace', 'Service', 'Subset']; const types = ['Datacenter', 'Partition', 'Namespace', 'Service', 'Subset'];
return bRev.find(function(item, i) { return bRev.find(function (item, i) {
const res = item !== aRev[i]; const res = item !== aRev[i];
if (res) { if (res) {
type = types[i]; type = types[i];
@ -34,8 +34,8 @@ export const getAlternateServices = function(targets, a) {
}; };
}; };
export const getSplitters = function(nodes) { export const getSplitters = function (nodes) {
return getNodesByType(nodes, 'splitter').map(function(item) { return getNodesByType(nodes, 'splitter').map(function (item) {
// Splitters need IDs adding so we can find them in the DOM later // Splitters need IDs adding so we can find them in the DOM later
// splitters have a service.nspace as a name // splitters have a service.nspace as a name
// do the reverse dance to ensure we don't mess up any // do the reverse dance to ensure we don't mess up any
@ -52,17 +52,17 @@ export const getSplitters = function(nodes) {
}; };
}); });
}; };
export const getRoutes = function(nodes, uid) { export const getRoutes = function (nodes, uid) {
return getNodesByType(nodes, 'router').reduce(function(prev, item) { return getNodesByType(nodes, 'router').reduce(function (prev, item) {
return prev.concat( return prev.concat(
item.Routes.map(function(route, i) { item.Routes.map(function (route, i) {
// Routes also have IDs added via createRoute // Routes also have IDs added via createRoute
return createRoute(route, item.Name, uid); return createRoute(route, item.Name, uid);
}) })
); );
}, []); }, []);
}; };
export const getResolvers = function( export const getResolvers = function (
dc, dc,
partition = 'default', partition = 'default',
nspace = 'default', nspace = 'default',
@ -72,8 +72,8 @@ export const getResolvers = function(
const resolvers = {}; const resolvers = {};
// make all our resolver nodes // make all our resolver nodes
Object.values(nodes) Object.values(nodes)
.filter(item => item.Type === 'resolver') .filter((item) => item.Type === 'resolver')
.forEach(function(item) { .forEach(function (item) {
const parts = item.Name.split('.'); const parts = item.Name.split('.');
let subset; let subset;
// this will leave behind the service.name.nspace.partition.dc even if the service name contains a dot // this will leave behind the service.name.nspace.partition.dc even if the service name contains a dot
@ -113,7 +113,7 @@ export const getResolvers = function(
} }
} }
}); });
Object.values(targets).forEach(target => { Object.values(targets).forEach((target) => {
// Failovers don't have a specific node // Failovers don't have a specific node
if (typeof nodes[`resolver:${target.ID}`] !== 'undefined') { if (typeof nodes[`resolver:${target.ID}`] !== 'undefined') {
// We use this to figure out whether this target is a redirect target // We use this to figure out whether this target is a redirect target
@ -144,7 +144,7 @@ export const getResolvers = function(
}); });
return Object.values(resolvers); return Object.values(resolvers);
}; };
export const createRoute = function(route, router, uid) { export const createRoute = function (route, router, uid) {
return { return {
...route, ...route,
Default: route.Default || typeof route.Definition.Match === 'undefined', Default: route.Default || typeof route.Definition.Match === 'undefined',

View File

@ -1,4 +1,5 @@
export default (collection, text) => (scope = '.consul-health-check-list') => { export default (collection, text) =>
(scope = '.consul-health-check-list') => {
return { return {
scope, scope,
item: collection('li', { item: collection('li', {
@ -7,4 +8,4 @@ export default (collection, text) => (scope = '.consul-health-check-list') => {
exposed: text('[data-test-exposed]'), exposed: text('[data-test-exposed]'),
}), }),
}; };
}; };

View File

@ -192,7 +192,7 @@
<button <button
data-test-create-permission data-test-create-permission
type="button" type="button"
{{on "click" (optional this.modal.open)}} {{on "click" (action this.openModal)}}
> >
Add permission Add permission
</button> </button>
@ -201,7 +201,7 @@
<Consul::Intention::Notice::Permissions /> <Consul::Intention::Notice::Permissions />
<Consul::Intention::Permission::List <Consul::Intention::Permission::List
@items={{item.Permissions}} @items={{item.Permissions}}
@onclick={{queue (action (mut permission)) (action (optional this.modal.open))}} @onclick={{queue (action (mut permission)) (action this.openModal)}}
@ondelete={{action 'delete' 'Permissions' item}} @ondelete={{action 'delete' 'Permissions' item}}
/> />
{{else}} {{else}}

View File

@ -5,20 +5,24 @@ export default Component.extend({
shouldShowPermissionForm: false, shouldShowPermissionForm: false,
openModal() {
this.modal?.open();
},
actions: { actions: {
createNewLabel: function(template, term) { createNewLabel: function (template, term) {
return template.replace(/{{term}}/g, term); return template.replace(/{{term}}/g, term);
}, },
isUnique: function(items, term) { isUnique: function (items, term) {
return !items.findBy('Name', term); return !items.findBy('Name', term);
}, },
add: function(name, changeset, value) { add: function (name, changeset, value) {
if (!(changeset.get(name) || []).includes(value) && value.isNew) { if (!(changeset.get(name) || []).includes(value) && value.isNew) {
changeset.pushObject(name, value); changeset.pushObject(name, value);
changeset.validate(); changeset.validate();
} }
}, },
delete: function(name, changeset, value) { delete: function (name, changeset, value) {
if ((changeset.get(name) || []).includes(value)) { if ((changeset.get(name) || []).includes(value)) {
changeset.removeObject(name, value); changeset.removeObject(name, value);
changeset.validate(); changeset.validate();

View File

@ -79,7 +79,9 @@ export default class ConsulIntentionForm extends Component {
let items = e.data let items = e.data
.uniqBy('Name') .uniqBy('Name')
.toArray() .toArray()
.filter(item => !['connect-proxy', 'mesh-gateway', 'terminating-gateway'].includes(item.Kind)) .filter(
(item) => !['connect-proxy', 'mesh-gateway', 'terminating-gateway'].includes(item.Kind)
)
.sort((a, b) => a.Name.localeCompare(b.Name)); .sort((a, b) => a.Name.localeCompare(b.Name));
items = [{ Name: '*' }].concat(items); items = [{ Name: '*' }].concat(items);
let source = items.findBy('Name', item.SourceName); let source = items.findBy('Name', item.SourceName);

View File

@ -1,9 +1,11 @@
export default (collection, clickable, attribute, isPresent, deletable) => ( export default (collection, clickable, attribute, isPresent, deletable) =>
scope = '.consul-intention-list' (scope = '.consul-intention-list') => {
) => {
const row = { const row = {
source: attribute('data-test-intention-source', '[data-test-intention-source]'), source: attribute('data-test-intention-source', '[data-test-intention-source]'),
destination: attribute('data-test-intention-destination', '[data-test-intention-destination]'), destination: attribute(
'data-test-intention-destination',
'[data-test-intention-destination]'
),
action: attribute('data-test-intention-action', '[data-test-intention-action]'), action: attribute('data-test-intention-action', '[data-test-intention-action]'),
intention: clickable('a'), intention: clickable('a'),
actions: clickable('label'), actions: clickable('label'),
@ -14,4 +16,4 @@ export default (collection, clickable, attribute, isPresent, deletable) => (
customResourceNotice: isPresent('.consul-intention-notice-custom-resource'), customResourceNotice: isPresent('.consul-intention-notice-custom-resource'),
intentions: collection('[data-test-tabular-row]', row), intentions: collection('[data-test-tabular-row]', row),
}; };
}; };

View File

@ -12,18 +12,18 @@ export default Component.extend({
change: service('change'), change: service('change'),
repo: service(`repository/${name}`), repo: service(`repository/${name}`),
onsubmit: function() {}, onsubmit: function () {},
onreset: function() {}, onreset: function () {},
intents: alias(`schema.${name}.Action.allowedValues`), intents: alias(`schema.${name}.Action.allowedValues`),
methods: alias(`schema.${name}-http.Methods.allowedValues`), methods: alias(`schema.${name}-http.Methods.allowedValues`),
pathProps: alias(`schema.${name}-http.PathType.allowedValues`), pathProps: alias(`schema.${name}-http.PathType.allowedValues`),
pathTypes: computed('pathProps', function() { pathTypes: computed('pathProps', function () {
return ['NoPath'].concat(this.pathProps); return ['NoPath'].concat(this.pathProps);
}), }),
pathLabels: computed(function() { pathLabels: computed(function () {
return { return {
NoPath: 'No Path', NoPath: 'No Path',
PathExact: 'Exact', PathExact: 'Exact',
@ -32,7 +32,7 @@ export default Component.extend({
}; };
}), }),
pathInputLabels: computed(function() { pathInputLabels: computed(function () {
return { return {
PathExact: 'Exact Path', PathExact: 'Exact Path',
PathPrefix: 'Path Prefix', PathPrefix: 'Path Prefix',
@ -40,7 +40,7 @@ export default Component.extend({
}; };
}), }),
changeset: computed('item', function() { changeset: computed('item', function () {
const changeset = this.change.changesetFor(name, this.item || this.repo.create()); const changeset = this.change.changesetFor(name, this.item || this.repo.create());
if (changeset.isNew) { if (changeset.isNew) {
changeset.validate(); changeset.validate();
@ -48,7 +48,7 @@ export default Component.extend({
return changeset; return changeset;
}), }),
pathType: computed('changeset._changes.HTTP.PathType', 'pathTypes.firstObject', function() { pathType: computed('changeset._changes.HTTP.PathType', 'pathTypes.firstObject', function () {
return this.changeset.HTTP.PathType || this.pathTypes.firstObject; return this.changeset.HTTP.PathType || this.pathTypes.firstObject;
}), }),
noPathType: equal('pathType', 'NoPath'), noPathType: equal('pathType', 'NoPath'),
@ -57,14 +57,14 @@ export default Component.extend({
allMethods: false, allMethods: false,
shouldShowMethods: not('allMethods'), shouldShowMethods: not('allMethods'),
didReceiveAttrs: function() { didReceiveAttrs: function () {
if (!get(this, 'item.HTTP.Methods.length')) { if (!get(this, 'item.HTTP.Methods.length')) {
set(this, 'allMethods', true); set(this, 'allMethods', true);
} }
}, },
actions: { actions: {
change: function(name, changeset, e) { change: function (name, changeset, e) {
const value = typeof get(e, 'target.value') !== 'undefined' ? e.target.value : e; const value = typeof get(e, 'target.value') !== 'undefined' ? e.target.value : e;
switch (name) { switch (name) {
case 'allMethods': case 'allMethods':
@ -82,21 +82,21 @@ export default Component.extend({
} }
changeset.validate(); changeset.validate();
}, },
add: function(prop, changeset, value) { add: function (prop, changeset, value) {
changeset.pushObject(prop, value); changeset.pushObject(prop, value);
changeset.validate(); changeset.validate();
}, },
delete: function(prop, changeset, value) { delete: function (prop, changeset, value) {
changeset.removeObject(prop, value); changeset.removeObject(prop, value);
changeset.validate(); changeset.validate();
}, },
submit: function(changeset, e) { submit: function (changeset, e) {
const pathChanged = const pathChanged =
typeof changeset.changes.find( typeof changeset.changes.find(
({ key, value }) => key === 'HTTP.PathType' || key === 'HTTP.Path' ({ key, value }) => key === 'HTTP.PathType' || key === 'HTTP.Path'
) !== 'undefined'; ) !== 'undefined';
if (pathChanged) { if (pathChanged) {
this.pathProps.forEach(prop => { this.pathProps.forEach((prop) => {
changeset.set(`HTTP.${prop}`, undefined); changeset.set(`HTTP.${prop}`, undefined);
}); });
if (changeset.HTTP.PathType !== 'NoPath') { if (changeset.HTTP.PathType !== 'NoPath') {
@ -115,7 +115,7 @@ export default Component.extend({
this.repo.persist(changeset); this.repo.persist(changeset);
this.onsubmit(changeset.data); this.onsubmit(changeset.data);
}, },
reset: function(changeset, e) { reset: function (changeset, e) {
changeset.rollback(); changeset.rollback();
this.onreset(changeset.data); this.onreset(changeset.data);
}, },

View File

@ -12,10 +12,10 @@ export default Component.extend({
change: service('change'), change: service('change'),
repo: service(`repository/${name}`), repo: service(`repository/${name}`),
onsubmit: function() {}, onsubmit: function () {},
onreset: function() {}, onreset: function () {},
changeset: computed('item', function() { changeset: computed('item', function () {
return this.change.changesetFor( return this.change.changesetFor(
name, name,
this.item || this.item ||
@ -27,7 +27,7 @@ export default Component.extend({
headerTypes: alias(`schema.${name}.HeaderType.allowedValues`), headerTypes: alias(`schema.${name}.HeaderType.allowedValues`),
headerLabels: computed(function() { headerLabels: computed(function () {
return { return {
Exact: 'Exactly Matching', Exact: 'Exactly Matching',
Prefix: 'Prefixed by', Prefix: 'Prefixed by',
@ -37,7 +37,7 @@ export default Component.extend({
}; };
}), }),
headerType: computed('changeset.HeaderType', 'headerTypes.firstObject', function() { headerType: computed('changeset.HeaderType', 'headerTypes.firstObject', function () {
return this.changeset.HeaderType || this.headerTypes.firstObject; return this.changeset.HeaderType || this.headerTypes.firstObject;
}), }),
@ -45,7 +45,7 @@ export default Component.extend({
shouldShowValueField: not('headerTypeEqualsPresent'), shouldShowValueField: not('headerTypeEqualsPresent'),
actions: { actions: {
change: function(name, changeset, e) { change: function (name, changeset, e) {
const value = typeof get(e, 'target.value') !== 'undefined' ? e.target.value : e; const value = typeof get(e, 'target.value') !== 'undefined' ? e.target.value : e;
switch (name) { switch (name) {
default: default:
@ -53,8 +53,8 @@ export default Component.extend({
} }
changeset.validate(); changeset.validate();
}, },
submit: function(changeset) { submit: function (changeset) {
this.headerTypes.forEach(prop => { this.headerTypes.forEach((prop) => {
changeset.set(prop, undefined); changeset.set(prop, undefined);
}); });
// Present is a boolean, whereas all other header types have a value // Present is a boolean, whereas all other header types have a value
@ -78,7 +78,7 @@ export default Component.extend({
}) })
); );
}, },
reset: function(changeset, e) { reset: function (changeset, e) {
changeset.rollback(); changeset.rollback();
}, },
}, },

View File

@ -6,15 +6,15 @@ export default Component.extend({
tagName: '', tagName: '',
encoder: service('btoa'), encoder: service('btoa'),
json: true, json: true,
ondelete: function() { ondelete: function () {
this.onsubmit(...arguments); this.onsubmit(...arguments);
}, },
oncancel: function() { oncancel: function () {
this.onsubmit(...arguments); this.onsubmit(...arguments);
}, },
onsubmit: function() {}, onsubmit: function () {},
actions: { actions: {
change: function(e, form) { change: function (e, form) {
const item = form.getData(); const item = form.getData();
try { try {
form.handleEvent(e); form.handleEvent(e);

View File

@ -3,10 +3,10 @@ import { tracked } from '@glimmer/tracking';
const size = 336; const size = 336;
const insetSize = size / 2 - 8; const insetSize = size / 2 - 8;
const inset = function(num) { const inset = function (num) {
return insetSize * num; return insetSize * num;
}; };
const milliseconds = function(num, max) { const milliseconds = function (num, max) {
return max > 0 ? parseInt(max * num) / 100 : 0; return max > 0 ? parseInt(max * num) / 100 : 0;
}; };
export default class TomographyGraph extends Component { export default class TomographyGraph extends Component {
@ -19,7 +19,7 @@ export default class TomographyGraph extends Component {
get milliseconds() { get milliseconds() {
const distances = this.args.distances || []; const distances = this.args.distances || [];
const max = distances.reduce((prev, d) => Math.max(prev, d.distance), this.max); const max = distances.reduce((prev, d) => Math.max(prev, d.distance), this.max);
return [25, 50, 75, 100].map(item => milliseconds(item, max)); return [25, 50, 75, 100].map((item) => milliseconds(item, max));
} }
get distances() { get distances() {
@ -30,7 +30,7 @@ export default class TomographyGraph extends Component {
// We have more nodes than we want to show, take a random sampling to keep // We have more nodes than we want to show, take a random sampling to keep
// the number around 360. // the number around 360.
const sampling = 360 / len; const sampling = 360 / len;
distances = distances.filter(function(_, i) { distances = distances.filter(function (_, i) {
return i == 0 || i == len - 1 || Math.random() < sampling; return i == 0 || i == len - 1 || Math.random() < sampling;
}); });
} }

View File

@ -1,4 +1,5 @@
export default (collection, text) => (scope = '.consul-upstream-instance-list') => { export default (collection, text) =>
(scope = '.consul-upstream-instance-list') => {
return { return {
scope, scope,
item: collection('li', { item: collection('li', {
@ -8,4 +9,4 @@ export default (collection, text) => (scope = '.consul-upstream-instance-list')
localAddress: text('.local-address dd'), localAddress: text('.local-address dd'),
}), }),
}; };
}; };

View File

@ -11,17 +11,23 @@ const typeCast = (attributeInfo, value) => {
let type = attributeInfo.type; let type = attributeInfo.type;
const d = attributeInfo.default; const d = attributeInfo.default;
value = value == null ? attributeInfo.default : value; value = value == null ? attributeInfo.default : value;
if(type.indexOf('|') !== -1) { if (type.indexOf('|') !== -1) {
assert(`"${value} is not of type '${type}'"`, type.split('|').map(item => item.replaceAll('"', '').trim()).includes(value)); assert(
`"${value} is not of type '${type}'"`,
type
.split('|')
.map((item) => item.replaceAll('"', '').trim())
.includes(value)
);
type = 'string'; type = 'string';
} }
switch(type) { switch (type) {
case '<length>': case '<length>':
case '<percentage>': case '<percentage>':
case '<dimension>': case '<dimension>':
case 'number': { case 'number': {
const num = parseFloat(value); const num = parseFloat(value);
if(isNaN(num)) { if (isNaN(num)) {
return typeof d === 'undefined' ? 0 : d; return typeof d === 'undefined' ? 0 : d;
} else { } else {
return num; return num;
@ -33,7 +39,7 @@ const typeCast = (attributeInfo, value) => {
case 'string': case 'string':
return (value || '').toString(); return (value || '').toString();
} }
} };
const attributeChangingElement = (name, Cls = HTMLElement, attributes = {}, cssprops = {}) => { const attributeChangingElement = (name, Cls = HTMLElement, attributes = {}, cssprops = {}) => {
const attrs = Object.keys(attributes); const attrs = Object.keys(attributes);
@ -48,65 +54,58 @@ const attributeChangingElement = (name, Cls = HTMLElement, attributes = {}, cssp
const value = typeCast(attributes[name], newValue); const value = typeCast(attributes[name], newValue);
const cssProp = cssprops[`--${name}`]; const cssProp = cssprops[`--${name}`];
if(typeof cssProp !== 'undefined' && cssProp.track === `[${name}]`) { if (typeof cssProp !== 'undefined' && cssProp.track === `[${name}]`) {
this.style.setProperty( this.style.setProperty(`--${name}`, value);
`--${name}`,
value
);
} }
if(typeof super.attributeChangedCallback === 'function') { if (typeof super.attributeChangedCallback === 'function') {
super.attributeChangedCallback(name, prev, value); super.attributeChangedCallback(name, prev, value);
} }
this.dispatchEvent( this.dispatchEvent(
new CustomEvent( new CustomEvent(ATTRIBUTE_CHANGE, {
ATTRIBUTE_CHANGE,
{
detail: { detail: {
name: name, name: name,
previousValue: prev, previousValue: prev,
value: value value: value,
} },
} })
)
); );
}
} }
};
customElements.define(name, customClass); customElements.define(name, customClass);
return () => {}; return () => {};
} };
const infoFromArray = (arr, keys) => { const infoFromArray = (arr, keys) => {
return (arr || []).reduce((prev, info) => { return (arr || []).reduce((prev, info) => {
let key; let key;
const obj = {}; const obj = {};
keys.forEach((item, i) => { keys.forEach((item, i) => {
if(item === '_') { if (item === '_') {
key = i; key = i;
return; return;
} }
obj[item] = info[i] obj[item] = info[i];
}); });
prev[info[key]] = obj; prev[info[key]] = obj;
return prev; return prev;
}, {}); }, {});
} };
const debounceRAF = (cb, prev) => { const debounceRAF = (cb, prev) => {
if(typeof prev !== 'undefined') { if (typeof prev !== 'undefined') {
cancelAnimationFrame(prev); cancelAnimationFrame(prev);
} }
return requestAnimationFrame(cb); return requestAnimationFrame(cb);
} };
const createElementProxy = ($element, component) => { const createElementProxy = ($element, component) => {
return new Proxy($element, { return new Proxy($element, {
get: (target, prop, receiver) => { get: (target, prop, receiver) => {
switch(prop) { switch (prop) {
case 'attrs': case 'attrs':
return component.attributes; return component.attributes;
default: default:
if(typeof target[prop] === 'function') { if (typeof target[prop] === 'function') {
// need to ensure we use a MultiWeakMap here // need to ensure we use a MultiWeakMap here
// if(this.methods.has(prop)) { // if(this.methods.has(prop)) {
// return this.methods.get(prop); // return this.methods.get(prop);
@ -115,30 +114,27 @@ const createElementProxy = ($element, component) => {
// this.methods.set(prop, method); // this.methods.set(prop, method);
return method; return method;
} }
}
} }
},
}); });
} };
export default class CustomElementComponent extends Component { export default class CustomElementComponent extends Component {
@tracked $element; @tracked $element;
@tracked _attributes = {}; @tracked _attributes = {};
__attributes; __attributes;
_attchange; _attchange;
constructor(owner, args) { constructor(owner, args) {
super(...arguments); super(...arguments);
if(!elements.has(args.element)) { if (!elements.has(args.element)) {
const cb = attributeChangingElement( const cb = attributeChangingElement(
args.element, args.element,
args.class, args.class,
infoFromArray(args.attrs, ['_', 'type', 'default', 'description']), infoFromArray(args.attrs, ['_', 'type', 'default', 'description']),
infoFromArray(args.cssprops, ['_', 'type', 'track', 'description']) infoFromArray(args.cssprops, ['_', 'type', 'track', 'description'])
) );
elements.set(args.element, cb); elements.set(args.element, cb);
} }
} }
@ -148,8 +144,8 @@ export default class CustomElementComponent extends Component {
} }
get element() { get element() {
if(this.$element) { if (this.$element) {
if(proxies.has(this.$element)) { if (proxies.has(this.$element)) {
return proxies.get(this.$element); return proxies.get(this.$element);
} }
const proxy = createElementProxy(this.$element, this); const proxy = createElementProxy(this.$element, this);
@ -165,9 +161,9 @@ export default class CustomElementComponent extends Component {
this.$element = $element; this.$element = $element;
this.$element.addEventListener(ATTRIBUTE_CHANGE, this.attributeChange); this.$element.addEventListener(ATTRIBUTE_CHANGE, this.attributeChange);
(this.args.attrs || []).forEach(entry => { (this.args.attrs || []).forEach((entry) => {
const value = $element.getAttribute(entry[0]); const value = $element.getAttribute(entry[0]);
$element.attributeChangedCallback(entry[0], value, value) $element.attributeChangedCallback(entry[0], value, value);
}); });
} }
@ -183,7 +179,7 @@ export default class CustomElementComponent extends Component {
// they all change // they all change
this.__attributes = { this.__attributes = {
...this.__attributes, ...this.__attributes,
[e.detail.name]: e.detail.value [e.detail.name]: e.detail.value,
}; };
this._attchange = debounceRAF(() => { this._attchange = debounceRAF(() => {
// tell glimmer we changed the attrs // tell glimmer we changed the attrs

View File

@ -9,17 +9,17 @@ export default Component.extend(Slotted, {
dom: service('dom'), dom: service('dom'),
builder: service('form'), builder: service('form'),
create: false, create: false,
ondelete: function() { ondelete: function () {
return this.onsubmit(...arguments); return this.onsubmit(...arguments);
}, },
oncancel: function() { oncancel: function () {
return this.onsubmit(...arguments); return this.onsubmit(...arguments);
}, },
onsubmit: function() {}, onsubmit: function () {},
onchange: function(e, form) { onchange: function (e, form) {
return form.handleEvent(e); return form.handleEvent(e);
}, },
didReceiveAttrs: function() { didReceiveAttrs: function () {
this._super(...arguments); this._super(...arguments);
try { try {
this.form = this.builder.form(this.type); this.form = this.builder.form(this.type);
@ -28,18 +28,18 @@ export default Component.extend(Slotted, {
// this lets us load view only data that doesn't have a form // this lets us load view only data that doesn't have a form
} }
}, },
willRender: function() { willRender: function () {
this._super(...arguments); this._super(...arguments);
set(this, 'hasError', this._isRegistered('error')); set(this, 'hasError', this._isRegistered('error'));
}, },
willDestroyElement: function() { willDestroyElement: function () {
this._super(...arguments); this._super(...arguments);
if (get(this, 'data.isNew')) { if (get(this, 'data.isNew')) {
this.data.rollbackAttributes(); this.data.rollbackAttributes();
} }
}, },
actions: { actions: {
setData: function(data) { setData: function (data) {
let changeset = data; let changeset = data;
// convert to a real changeset // convert to a real changeset
if (!isChangeset(data) && typeof this.form !== 'undefined') { if (!isChangeset(data) && typeof this.form !== 'undefined') {
@ -49,7 +49,7 @@ export default Component.extend(Slotted, {
// and autofill the new record if required // and autofill the new record if required
if (get(data, 'isNew')) { if (get(data, 'isNew')) {
set(this, 'create', true); set(this, 'create', true);
changeset = Object.entries(this.autofill || {}).reduce(function(prev, [key, value]) { changeset = Object.entries(this.autofill || {}).reduce(function (prev, [key, value]) {
set(prev, key, value); set(prev, key, value);
return prev; return prev;
}, changeset); }, changeset);
@ -57,7 +57,7 @@ export default Component.extend(Slotted, {
set(this, 'data', changeset); set(this, 'data', changeset);
return this.data; return this.data;
}, },
change: function(e, value, item) { change: function (e, value, item) {
this.onchange(this.dom.normalizeEvent(e, value), this.form, this.form.getData()); this.onchange(this.dom.normalizeEvent(e, value), this.form, this.form.getData());
}, },
}, },

View File

@ -5,26 +5,26 @@ import Slotted from 'block-slots';
import chart from './chart.xstate'; import chart from './chart.xstate';
export default Component.extend(Slotted, { export default Component.extend(Slotted, {
tagName: '', tagName: '',
onchange: data => data, onchange: (data) => data,
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this.chart = chart; this.chart = chart;
}, },
didReceiveAttrs: function() { didReceiveAttrs: function () {
this._super(...arguments); this._super(...arguments);
if (typeof this.items !== 'undefined') { if (typeof this.items !== 'undefined') {
this.actions.change.apply(this, [this.items]); this.actions.change.apply(this, [this.items]);
} }
}, },
didInsertElement: function() { didInsertElement: function () {
this._super(...arguments); this._super(...arguments);
this.dispatch('LOAD'); this.dispatch('LOAD');
}, },
actions: { actions: {
isLoaded: function() { isLoaded: function () {
return typeof this.items !== 'undefined' || typeof this.src === 'undefined'; return typeof this.items !== 'undefined' || typeof this.src === 'undefined';
}, },
change: function(data) { change: function (data) {
set(this, 'data', this.onchange(data)); set(this, 'data', this.onchange(data));
}, },
}, },

View File

@ -11,10 +11,10 @@ export default Component.extend({
dom: service('dom'), dom: service('dom'),
logger: service('logger'), logger: service('logger'),
onchange: function(e) {}, onchange: function (e) {},
onerror: function(e) {}, onerror: function (e) {},
state: computed('instance', 'instance.{dirtyType,isSaving}', function() { state: computed('instance', 'instance.{dirtyType,isSaving}', function () {
let id; let id;
const isSaving = get(this, 'instance.isSaving'); const isSaving = get(this, 'instance.isSaving');
const dirtyType = get(this, 'instance.dirtyType'); const dirtyType = get(this, 'instance.dirtyType');
@ -36,21 +36,21 @@ export default Component.extend({
id = `active.${id}`; id = `active.${id}`;
} }
return { return {
matches: name => id.indexOf(name) !== -1, matches: (name) => id.indexOf(name) !== -1,
}; };
}), }),
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this._listeners = this.dom.listeners(); this._listeners = this.dom.listeners();
}, },
willDestroyElement: function() { willDestroyElement: function () {
this._super(...arguments); this._super(...arguments);
this._listeners.remove(); this._listeners.remove();
}, },
source: function(cb) { source: function (cb) {
const source = once(cb); const source = once(cb);
const error = err => { const error = (err) => {
set(this, 'instance', undefined); set(this, 'instance', undefined);
try { try {
this.onerror(err); this.onerror(err);
@ -60,7 +60,7 @@ export default Component.extend({
} }
}; };
this._listeners.add(source, { this._listeners.add(source, {
message: e => { message: (e) => {
try { try {
set(this, 'instance', undefined); set(this, 'instance', undefined);
this.onchange(e); this.onchange(e);
@ -68,17 +68,17 @@ export default Component.extend({
error(err); error(err);
} }
}, },
error: e => error(e), error: (e) => error(e),
}); });
return source; return source;
}, },
didInsertElement: function() { didInsertElement: function () {
this._super(...arguments); this._super(...arguments);
if (typeof this.data !== 'undefined' || typeof this.item !== 'undefined') { if (typeof this.data !== 'undefined' || typeof this.item !== 'undefined') {
this.actions.open.apply(this, [this.data, this.item]); this.actions.open.apply(this, [this.data, this.item]);
} }
}, },
persist: function(data, instance) { persist: function (data, instance) {
if (typeof data !== 'undefined') { if (typeof data !== 'undefined') {
set(this, 'instance', this.service.prepare(this.sink, data, instance)); set(this, 'instance', this.service.prepare(this.sink, data, instance));
} else { } else {
@ -86,12 +86,12 @@ export default Component.extend({
} }
this.source(() => this.service.persist(this.sink, this.instance)); this.source(() => this.service.persist(this.sink, this.instance));
}, },
remove: function(instance) { remove: function (instance) {
set(this, 'instance', instance); set(this, 'instance', instance);
this.source(() => this.service.remove(this.sink, instance)); this.source(() => this.service.remove(this.sink, instance));
}, },
actions: { actions: {
open: function(data, item) { open: function (data, item) {
if (item instanceof Event) { if (item instanceof Event) {
item = undefined; item = undefined;
} }

View File

@ -15,7 +15,7 @@ import { runInDebug } from '@ember/debug';
* @param value - value to use for replacement * @param value - value to use for replacement
* @param destroy {(prev: any, value: any) => any} - teardown function * @param destroy {(prev: any, value: any) => any} - teardown function
*/ */
const replace = function( const replace = function (
obj, obj,
prop, prop,
value, value,
@ -29,7 +29,7 @@ const replace = function(
}; };
const noop = () => {}; const noop = () => {};
const optional = op => (typeof op === 'function' ? op : noop); const optional = (op) => (typeof op === 'function' ? op : noop);
// possible values for @loading="" // possible values for @loading=""
const LOADING = ['eager', 'lazy']; const LOADING = ['eager', 'lazy'];
@ -74,7 +74,7 @@ export default class DataSource extends Component {
// otherwise its an array from the did-insert-helper // otherwise its an array from the did-insert-helper
if (!Array.isArray($el)) { if (!Array.isArray($el)) {
this._lazyListeners.add( this._lazyListeners.add(
this.dom.isInViewport($el, inViewport => { this.dom.isInViewport($el, (inViewport) => {
this.isIntersecting = inViewport; this.isIntersecting = inViewport;
if (!this.isIntersecting) { if (!this.isIntersecting) {
this.close(); this.close();
@ -130,7 +130,7 @@ export default class DataSource extends Component {
this.dataSource.close(prev, this); this.dataSource.close(prev, this);
} }
); );
const error = err => { const error = (err) => {
try { try {
const error = get(err, 'error.errors.firstObject') || {}; const error = get(err, 'error.errors.firstObject') || {};
if (get(error, 'status') !== '429') { if (get(error, 'status') !== '429') {
@ -143,14 +143,14 @@ export default class DataSource extends Component {
}; };
// set up the listeners (which auto cleanup on component destruction) // set up the listeners (which auto cleanup on component destruction)
const remove = this._listeners.add(this.source, { const remove = this._listeners.add(this.source, {
message: e => { message: (e) => {
try { try {
this.onchange(e); this.onchange(e);
} catch (err) { } catch (err) {
error(err); error(err);
} }
}, },
error: e => { error: (e) => {
error(e); error(e);
}, },
}); });
@ -187,7 +187,7 @@ export default class DataSource extends Component {
this.disconnect(); this.disconnect();
schedule('afterRender', () => { schedule('afterRender', () => {
// TODO: Support lazy data-sources by keeping a reference to $el // TODO: Support lazy data-sources by keeping a reference to $el
runInDebug(_ => runInDebug((_) =>
console.debug( console.debug(
`Invalidation is only supported for non-lazy data sources. If you want to use this you should fixup support for lazy data sources` `Invalidation is only supported for non-lazy data sources. If you want to use this you should fixup support for lazy data sources`
) )

View File

@ -5,31 +5,30 @@ import chart from './chart.xstate';
export default Component.extend(Slotted, { export default Component.extend(Slotted, {
tagName: '', tagName: '',
ondelete: function() { ondelete: function () {
return this.onchange(...arguments); return this.onchange(...arguments);
}, },
onchange: function() {}, onchange: function () {},
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this.chart = chart; this.chart = chart;
}, },
actions: { actions: {
persist: function(data, e) { persist: function (data, e) {
if (e && typeof e.preventDefault === 'function') { if (e && typeof e.preventDefault === 'function') {
e.preventDefault(); e.preventDefault();
} }
set(this, 'data', data); set(this, 'data', data);
this.dispatch('PERSIST'); this.dispatch('PERSIST');
}, },
error: function(data, e) { error: function (data, e) {
if (e && typeof e.preventDefault === 'function') { if (e && typeof e.preventDefault === 'function') {
e.preventDefault(); e.preventDefault();
} }
set( set(
this, this,
'error', 'error',
typeof data.error.errors !== 'undefined' ? typeof data.error.errors !== 'undefined' ? data.error.errors.firstObject : data.error
data.error.errors.firstObject : data.error
); );
this.dispatch('ERROR'); this.dispatch('ERROR');
}, },

View File

@ -2,6 +2,6 @@ import Component from '@ember/component';
export default Component.extend({ export default Component.extend({
tagName: '', tagName: '',
execute: function() {}, execute: function () {},
cancel: function() {}, cancel: function () {},
}); });

View File

@ -17,7 +17,7 @@ export default class DisclosureComponent extends Component {
remove(id) { remove(id) {
this.ids = this.ids this.ids = this.ids
.split(' ') .split(' ')
.filter(item => item !== id) .filter((item) => item !== id)
.join(' '); .join(' ');
} }
} }

View File

@ -22,11 +22,11 @@ export default (css) => {
border-radius: var(--decor-radius-999); border-radius: var(--decor-radius-999);
transition-property: transform; transition-property: transform;
transition-timing-function: ease-out; transition-timing-function: ease-out;
transition-duration: .1s; transition-duration: 0.1s;
} }
:host([type='linear']) dl:hover { :host([type='linear']) dl:hover {
transform: scaleY(3); transform: scaleY(3);
box-shadow: var(--decor-elevation-200); box-shadow: var(--decor-elevation-200);
} }
`; `;
} };

View File

@ -1,19 +1,22 @@
const parseFloatWithDefault = (val, d = 0) => { const parseFloatWithDefault = (val, d = 0) => {
const num = parseFloat(val); const num = parseFloat(val);
return isNaN(num) ? d : num; return isNaN(num) ? d : num;
} };
export default (Component) => { export default (Component) => {
return class extends Component { return class extends Component {
attributeChangedCallback(name, prev, value) { attributeChangedCallback(name, prev, value) {
const target = this; const target = this;
switch(name) { switch (name) {
case 'percentage': { case 'percentage': {
let prevSibling = target; let prevSibling = target;
while(prevSibling) { while (prevSibling) {
const nextSibling = prevSibling.nextElementSibling; const nextSibling = prevSibling.nextElementSibling;
const aggregatedPercentage = nextSibling ? parseFloatWithDefault(nextSibling.style.getPropertyValue('--aggregated-percentage')) : 0; const aggregatedPercentage = nextSibling
const perc = parseFloatWithDefault(prevSibling.getAttribute('percentage')) + aggregatedPercentage; ? parseFloatWithDefault(nextSibling.style.getPropertyValue('--aggregated-percentage'))
: 0;
const perc =
parseFloatWithDefault(prevSibling.getAttribute('percentage')) + aggregatedPercentage;
prevSibling.style.setProperty('--aggregated-percentage', perc); prevSibling.style.setProperty('--aggregated-percentage', perc);
prevSibling.setAttribute('aggregated-percentage', perc); prevSibling.setAttribute('aggregated-percentage', perc);
prevSibling = prevSibling.previousElementSibling; prevSibling = prevSibling.previousElementSibling;
@ -22,5 +25,5 @@ export default (Component) => {
} }
} }
} }
} };
} };

View File

@ -18,9 +18,10 @@ export default (css) => {
height: 100%; height: 100%;
transition-timing-function: ease-out; transition-timing-function: ease-out;
transition-duration: .5s; transition-duration: 0.5s;
} }
dt, dd meter { dt,
dd meter {
animation-name: visually-hidden; animation-name: visually-hidden;
animation-fill-mode: forwards; animation-fill-mode: forwards;
animation-play-state: paused; animation-play-state: paused;
@ -49,7 +50,7 @@ export default (css) => {
:host(.type-radial) circle, :host(.type-radial) circle,
:host(.type-circular) circle { :host(.type-circular) circle {
transition-timing-function: ease-out; transition-timing-function: ease-out;
transition-duration: .5s; transition-duration: 0.5s;
pointer-events: stroke; pointer-events: stroke;
transition-property: stroke-dashoffset, stroke-width; transition-property: stroke-dashoffset, stroke-width;
transform: rotate(-90deg); transform: rotate(-90deg);
@ -76,4 +77,4 @@ export default (css) => {
stroke-width: 14; stroke-width: 14;
} }
`; `;
} };

View File

@ -4,7 +4,7 @@ import Slotted from 'block-slots';
export default Component.extend(Slotted, { export default Component.extend(Slotted, {
tagName: '', tagName: '',
willRender: function() { willRender: function () {
this._super(...arguments); this._super(...arguments);
set(this, 'hasHeader', this._isRegistered('header') || this._isRegistered('subheader')); set(this, 'hasHeader', this._isRegistered('header') || this._isRegistered('subheader'));
}, },

View File

@ -1,6 +1,7 @@
export default present => (scope = '.empty-state') => { export default (present) =>
(scope = '.empty-state') => {
return { return {
scope: scope, scope: scope,
login: present('[data-test-empty-state-login]'), login: present('[data-test-empty-state-login]'),
}; };
}; };

View File

@ -2,7 +2,7 @@ import Component from '@ember/component';
import { inject as service } from '@ember/service'; import { inject as service } from '@ember/service';
import { get, set } from '@ember/object'; import { get, set } from '@ember/object';
const replace = function( const replace = function (
obj, obj,
prop, prop,
value, value,
@ -20,21 +20,21 @@ export default Component.extend({
logger: service('logger'), logger: service('logger'),
data: service('data-source/service'), data: service('data-source/service'),
closeOnDestroy: true, closeOnDestroy: true,
onerror: function(e) { onerror: function (e) {
this.logger.execute(e.error); this.logger.execute(e.error);
}, },
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this._listeners = this.dom.listeners(); this._listeners = this.dom.listeners();
}, },
willDestroyElement: function() { willDestroyElement: function () {
if (this.closeOnDestroy) { if (this.closeOnDestroy) {
this.actions.close.apply(this, []); this.actions.close.apply(this, []);
} }
this._listeners.remove(); this._listeners.remove();
this._super(...arguments); this._super(...arguments);
}, },
didReceiveAttrs: function() { didReceiveAttrs: function () {
this._super(...arguments); this._super(...arguments);
// only close and reopen if the uri changes // only close and reopen if the uri changes
// otherwise this will fire whenever the proxies data changes // otherwise this will fire whenever the proxies data changes
@ -43,7 +43,7 @@ export default Component.extend({
} }
}, },
actions: { actions: {
open: function() { open: function () {
replace(this, 'source', this.data.open(this.src, this), (prev, source) => { replace(this, 'source', this.data.open(this.src, this), (prev, source) => {
// Makes sure any previous source (if different) is ALWAYS closed // Makes sure any previous source (if different) is ALWAYS closed
if (typeof prev !== 'undefined') { if (typeof prev !== 'undefined') {
@ -56,7 +56,7 @@ export default Component.extend({
prev.destroy(); prev.destroy();
} }
}); });
const error = err => { const error = (err) => {
try { try {
const error = get(err, 'error.errors.firstObject'); const error = get(err, 'error.errors.firstObject');
if (get(error || {}, 'status') !== '429') { if (get(error || {}, 'status') !== '429') {
@ -71,13 +71,13 @@ export default Component.extend({
// we only need errors here as this only uses proxies which // we only need errors here as this only uses proxies which
// automatically update their data // automatically update their data
const remove = this._listeners.add(this.source, { const remove = this._listeners.add(this.source, {
error: e => { error: (e) => {
error(e); error(e);
}, },
}); });
replace(this, '_remove', remove); replace(this, '_remove', remove);
}, },
close: function() { close: function () {
if (typeof this.source !== 'undefined') { if (typeof this.source !== 'undefined') {
this.data.close(this.source, this); this.data.close(this.source, this);
replace(this, '_remove', undefined); replace(this, '_remove', undefined);

View File

@ -6,10 +6,10 @@ import { alias } from '@ember/object/computed';
const propRe = /([^[\]])+/g; const propRe = /([^[\]])+/g;
export default Component.extend(Slotted, { export default Component.extend(Slotted, {
tagName: '', tagName: '',
onreset: function() {}, onreset: function () {},
onchange: function() {}, onchange: function () {},
onerror: function() {}, onerror: function () {},
onsuccess: function() {}, onsuccess: function () {},
data: alias('form.data'), data: alias('form.data'),
item: alias('form.data'), item: alias('form.data'),
@ -20,7 +20,7 @@ export default Component.extend(Slotted, {
container: service('form'), container: service('form'),
actions: { actions: {
change: function(e, value, item) { change: function (e, value, item) {
let event = this.dom.normalizeEvent(e, value); let event = this.dom.normalizeEvent(e, value);
// currently form-components don't deal with deeply nested forms, only top level // currently form-components don't deal with deeply nested forms, only top level
// we therefore grab the end of the nest off here, // we therefore grab the end of the nest off here,

View File

@ -21,15 +21,12 @@ export default class Element extends Component {
} }
} }
get prop() { get prop() {
return `${this.args.name return `${this.args.name.toLowerCase().split('.').join('-')}`;
.toLowerCase()
.split('.')
.join('-')}`;
} }
get state() { get state() {
const error = this.touched && this.args.error; const error = this.touched && this.args.error;
return { return {
matches: name => name === 'error' && error, matches: (name) => name === 'error' && error,
}; };
} }

View File

@ -1,4 +1,4 @@
export default triggerable => () => { export default (triggerable) => () => {
return { return {
...{ ...{
search: triggerable('keypress', '[name="s"]'), search: triggerable('keypress', '[name="s"]'),

View File

@ -1,4 +1,4 @@
export default (collection, clickable, attribute, is, authForm, emptyState) => scope => { export default (collection, clickable, attribute, is, authForm, emptyState) => (scope) => {
const page = { const page = {
navigation: [ navigation: [
'services', 'services',
@ -12,7 +12,7 @@ export default (collection, clickable, attribute, is, authForm, emptyState) => s
'settings', 'settings',
'auth', 'auth',
].reduce( ].reduce(
function(prev, item, i, arr) { function (prev, item, i, arr) {
const key = item; const key = item;
return Object.assign({}, prev, { return Object.assign({}, prev, {
[key]: clickable(`[data-test-main-nav-${item}] > *`), [key]: clickable(`[data-test-main-nav-${item}] > *`),
@ -23,7 +23,7 @@ export default (collection, clickable, attribute, is, authForm, emptyState) => s
} }
), ),
footer: ['copyright', 'docs'].reduce( footer: ['copyright', 'docs'].reduce(
function(prev, item, i, arr) { function (prev, item, i, arr) {
const key = item; const key = item;
return Object.assign({}, prev, { return Object.assign({}, prev, {
[key]: clickable(`[data-test-main-nav-${item}`), [key]: clickable(`[data-test-main-nav-${item}`),

View File

@ -18,19 +18,19 @@ export default class JWTSource extends Component {
// TODO: Could this use once? Double check but I don't think it can // TODO: Could this use once? Double check but I don't think it can
this.source = fromPromise(this.repo.findCodeByURL(this.args.src)); this.source = fromPromise(this.repo.findCodeByURL(this.args.src));
this._listeners.add(this.source, { this._listeners.add(this.source, {
message: e => this.onchange(e), message: (e) => this.onchange(e),
error: e => this.onerror(e), error: (e) => this.onerror(e),
}); });
} }
onchange(e) { onchange(e) {
if(typeof this.args.onchange === 'function') { if (typeof this.args.onchange === 'function') {
this.args.onchange(...arguments); this.args.onchange(...arguments);
} }
} }
onerror(e) { onerror(e) {
if(typeof this.args.onerror === 'function') { if (typeof this.args.onerror === 'function') {
this.args.onerror(...arguments); this.args.onerror(...arguments);
} }
} }

View File

@ -13,19 +13,19 @@ export default Component.extend(Slotted, {
cellHeight: 70, cellHeight: 70,
checked: null, checked: null,
scroll: 'virtual', scroll: 'virtual',
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this.columns = [100]; this.columns = [100];
this.guid = this.dom.guid(this); this.guid = this.dom.guid(this);
}, },
didInsertElement: function() { didInsertElement: function () {
this._super(...arguments); this._super(...arguments);
this.$element = this.dom.element(`#${this.guid}`); this.$element = this.dom.element(`#${this.guid}`);
if (this.scroll === 'virtual') { if (this.scroll === 'virtual') {
this.actions.resize.apply(this, [{ target: this.dom.viewport() }]); this.actions.resize.apply(this, [{ target: this.dom.viewport() }]);
} }
}, },
didReceiveAttrs: function() { didReceiveAttrs: function () {
this._super(...arguments); this._super(...arguments);
this._cellLayout = this['cell-layout'] = new PercentageColumns( this._cellLayout = this['cell-layout'] = new PercentageColumns(
get(this, 'items.length'), get(this, 'items.length'),
@ -33,7 +33,7 @@ export default Component.extend(Slotted, {
get(this, 'cellHeight') get(this, 'cellHeight')
); );
const o = this; const o = this;
this['cell-layout'].formatItemStyle = function(itemIndex) { this['cell-layout'].formatItemStyle = function (itemIndex) {
let style = formatItemStyle.apply(this, arguments); let style = formatItemStyle.apply(this, arguments);
if (o.checked === itemIndex) { if (o.checked === itemIndex) {
style = `${style};z-index: 1`; style = `${style};z-index: 1`;
@ -41,7 +41,7 @@ export default Component.extend(Slotted, {
return style; return style;
}; };
}, },
style: computed('height', function() { style: computed('height', function () {
if (this.scroll !== 'virtual') { if (this.scroll !== 'virtual') {
return {}; return {};
} }
@ -50,7 +50,7 @@ export default Component.extend(Slotted, {
}; };
}), }),
actions: { actions: {
resize: function(e) { resize: function (e) {
// TODO: This top part is very similar to resize in tabular-collection // TODO: This top part is very similar to resize in tabular-collection
// see if it make sense to DRY out // see if it make sense to DRY out
const dom = get(this, 'dom'); const dom = get(this, 'dom');
@ -65,10 +65,10 @@ export default Component.extend(Slotted, {
this.updateScrollPosition(); this.updateScrollPosition();
} }
}, },
click: function(e) { click: function (e) {
return this.dom.clickFirstAnchor(e, '.list-collection > ul > li'); return this.dom.clickFirstAnchor(e, '.list-collection > ul > li');
}, },
change: function(index, e = {}) { change: function (index, e = {}) {
if (e.target.checked && index !== get(this, 'checked')) { if (e.target.checked && index !== get(this, 'checked')) {
set(this, 'checked', parseInt(index)); set(this, 'checked', parseInt(index));
this.$row = this.dom.closest('li', e.target); this.$row = this.dom.closest('li', e.target);

View File

@ -10,9 +10,9 @@ export default Component.extend(Slotted, {
dom: service('dom'), dom: service('dom'),
isConfirmation: false, isConfirmation: false,
actions: { actions: {
connect: function($el) { connect: function ($el) {
next(() => { next(() => {
if(!this.isDestroyed) { if (!this.isDestroyed) {
// if theres only a single choice in the menu and it doesn't have an // if theres only a single choice in the menu and it doesn't have an
// immediate button/link/label to click then it will be a // immediate button/link/label to click then it will be a
// confirmation/informed action // confirmation/informed action
@ -24,7 +24,7 @@ export default Component.extend(Slotted, {
} }
}); });
}, },
change: function(e) { change: function (e) {
const id = e.target.getAttribute('id'); const id = e.target.getAttribute('id');
const $trigger = this.dom.element(`[for='${id}']`); const $trigger = this.dom.element(`[for='${id}']`);
const $panel = this.dom.element('[role=menu]', $trigger.parentElement); const $panel = this.dom.element('[role=menu]', $trigger.parentElement);

View File

@ -6,31 +6,31 @@ import { schedule } from '@ember/runloop';
export default Component.extend(Slotted, { export default Component.extend(Slotted, {
tagName: '', tagName: '',
onclose: function() {}, onclose: function () {},
onopen: function() {}, onopen: function () {},
isOpen: false, isOpen: false,
actions: { actions: {
connect: function($el) { connect: function ($el) {
this.dialog = new A11yDialog($el); this.dialog = new A11yDialog($el);
this.dialog.on('hide', () => { this.dialog.on('hide', () => {
schedule('afterRender', _ => set(this, 'isOpen', false)); schedule('afterRender', (_) => set(this, 'isOpen', false));
this.onclose({ target: $el }) this.onclose({ target: $el });
}); });
this.dialog.on('show', () => { this.dialog.on('show', () => {
set(this, 'isOpen', true) set(this, 'isOpen', true);
this.onopen({ target: $el }) this.onopen({ target: $el });
}); });
if (this.open) { if (this.open) {
this.actions.open.apply(this, []); this.actions.open.apply(this, []);
} }
}, },
disconnect: function($el) { disconnect: function ($el) {
this.dialog.destroy(); this.dialog.destroy();
}, },
open: function() { open: function () {
this.dialog.show(); this.dialog.show();
}, },
close: function() { close: function () {
this.dialog.hide(); this.dialog.hide();
}, },
}, },

View File

@ -59,7 +59,7 @@ export default class Outlet extends Component {
} }
break; break;
case 'model': case 'model':
if(typeof this.route !== 'undefined') { if (typeof this.route !== 'undefined') {
this.route._model = value; this.route._model = value;
} }
break; break;

View File

@ -1,9 +1,9 @@
import Component from '@glimmer/component'; import Component from '@glimmer/component';
import { action } from '@ember/object'; import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking'; import { tracked } from '@glimmer/tracking';
import { scheduleOnce } from '@ember/runloop';
export default class PagedCollectionComponent extends Component { export default class PagedCollectionComponent extends Component {
@tracked $pane; @tracked $pane;
@tracked $viewport; @tracked $viewport;
@ -25,7 +25,7 @@ export default class PagedCollectionComponent extends Component {
get perPage() { get perPage() {
switch (this.type) { switch (this.type) {
case 'virtual-scroll': case 'virtual-scroll':
return this.visibleItems + (this.overflow * 2); return this.visibleItems + this.overflow * 2;
case 'index': case 'index':
return parseInt(this.args.perPage); return parseInt(this.args.perPage);
} }
@ -45,7 +45,7 @@ export default class PagedCollectionComponent extends Component {
} }
get itemsBefore() { get itemsBefore() {
if(typeof this.$viewport === 'undefined') { if (typeof this.$viewport === 'undefined') {
return 0; return 0;
} }
return Math.max(0, Math.round(this.top / this.rowHeight) - this.overflow); return Math.max(0, Math.round(this.top / this.rowHeight) - this.overflow);
@ -84,7 +84,7 @@ export default class PagedCollectionComponent extends Component {
@action @action
resize() { resize() {
if(this.$viewport.clientHeight > 0 && this.rowHeight > 0) { if (this.$viewport.clientHeight > 0 && this.rowHeight > 0) {
this.visibleItems = Math.ceil(this.$viewport.clientHeight / this.rowHeight); this.visibleItems = Math.ceil(this.$viewport.clientHeight / this.rowHeight);
} else { } else {
this.visibleItems = 0; this.visibleItems = 0;
@ -93,9 +93,10 @@ export default class PagedCollectionComponent extends Component {
@action @action
setViewport($viewport) { setViewport($viewport) {
this.$viewport = $viewport === 'html' ? [...document.getElementsByTagName('html')][0] : $viewport; this.$viewport =
$viewport === 'html' ? [...document.getElementsByTagName('html')][0] : $viewport;
this.$viewport.addEventListener('scroll', this.scroll); this.$viewport.addEventListener('scroll', this.scroll);
if($viewport === 'html') { if ($viewport === 'html') {
this.$viewport.addEventListener('resize', this.resize); this.$viewport.addEventListener('resize', this.resize);
} }
this.scroll(); this.scroll();
@ -111,8 +112,13 @@ export default class PagedCollectionComponent extends Component {
} }
@action setMaxHeight(str) { @action setMaxHeight(str) {
scheduleOnce('actions', this, '_setMaxHeight');
}
@action _setMaxHeight(str) {
const maxHeight = parseFloat(str); const maxHeight = parseFloat(str);
if(!isNaN(maxHeight)) {
if (!isNaN(maxHeight)) {
this._type = 'virtual-scroll'; this._type = 'virtual-scroll';
} }
} }

View File

@ -21,7 +21,7 @@ const BADGE_LOOKUP = {
tooltip: 'Someone in the other peer may have deleted this peering connection.', tooltip: 'Someone in the other peer may have deleted this peering connection.',
}, },
UNDEFINED: { UNDEFINED: {
tooltip: '' tooltip: '',
}, },
}; };
export default class PeeringsBadge extends Component { export default class PeeringsBadge extends Component {

View File

@ -8,7 +8,7 @@ export default FormComponent.extend({
classNames: ['policy-form'], classNames: ['policy-form'],
isScoped: false, isScoped: false,
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
set(this, 'isScoped', get(this, 'item.Datacenters.length') > 0); set(this, 'isScoped', get(this, 'item.Datacenters.length') > 0);
this.templates = [ this.templates = [
@ -27,7 +27,7 @@ export default FormComponent.extend({
]; ];
}, },
actions: { actions: {
change: function(e) { change: function (e) {
try { try {
this._super(...arguments); this._super(...arguments);
} catch (err) { } catch (err) {

View File

@ -1,6 +1,5 @@
export default (submitable, cancelable, radiogroup, text) => ( export default (submitable, cancelable, radiogroup, text) =>
scope = '[data-test-policy-form]' (scope = '[data-test-policy-form]') => {
) => {
return { return {
// this should probably be settable // this should probably be settable
resetScope: true, resetScope: true,
@ -13,4 +12,4 @@ export default (submitable, cancelable, radiogroup, text) => (
error: text('[data-test-rules] strong'), error: text('[data-test-rules] strong'),
}, },
}; };
}; };

View File

@ -20,7 +20,7 @@
<label <label
class="type-dialog" class="type-dialog"
data-test-policy-create data-test-policy-create
{{on "click" (optional this.modal.open)}} {{on "click" (action this.openModal)}}
> >
<span>Create new policy</span> <span>Create new policy</span>
</label> </label>

View File

@ -12,26 +12,26 @@ export default ChildSelectorComponent.extend({
type: 'policy', type: 'policy',
allowIdentity: true, allowIdentity: true,
classNames: ['policy-selector'], classNames: ['policy-selector'],
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
const source = this.source; const source = this.source;
if (source) { if (source) {
this._listeners.add(source, { this._listeners.add(source, {
save: e => { save: (e) => {
this.save.perform(...e.data); this.save.perform(...e.data);
}, },
}); });
} }
}, },
reset: function(e) { reset: function (e) {
this._super(...arguments); this._super(...arguments);
set(this, 'isScoped', false); set(this, 'isScoped', false);
}, },
refreshCodeEditor: function(e, target) { refreshCodeEditor: function (e, target) {
const selector = '.code-editor'; const selector = '.code-editor';
this.dom.component(selector, target).didAppear(); this.dom.component(selector, target).didAppear();
}, },
error: function(e) { error: function (e) {
const item = this.item; const item = this.item;
const err = e.error; const err = e.error;
if (typeof err.errors !== 'undefined') { if (typeof err.errors !== 'undefined') {
@ -57,8 +57,15 @@ export default ChildSelectorComponent.extend({
throw err; throw err;
} }
}, },
openModal: function () {
const { modal } = this;
if (modal) {
modal.open();
}
},
actions: { actions: {
open: function(e) { open: function (e) {
this.refreshCodeEditor(e, e.target.parentElement); this.refreshCodeEditor(e, e.target.parentElement);
}, },
}, },

View File

@ -1,7 +1,5 @@
export default (clickable, deletable, collection, alias, policyForm) => ( export default (clickable, deletable, collection, alias, policyForm) =>
scope = '#policies', (scope = '#policies', createSelector = '[data-test-policy-create]') => {
createSelector = '[data-test-policy-create]'
) => {
return { return {
scope: scope, scope: scope,
create: clickable(createSelector), create: clickable(createSelector),
@ -17,4 +15,4 @@ export default (clickable, deletable, collection, alias, policyForm) => (
) )
), ),
}; };
}; };

View File

@ -9,32 +9,32 @@ export default Component.extend(Slotted, {
dom: service('dom'), dom: service('dom'),
expanded: false, expanded: false,
keyboardAccess: true, keyboardAccess: true,
onchange: function() {}, onchange: function () {},
// TODO: this needs to be made dynamic/auto detect // TODO: this needs to be made dynamic/auto detect
// for now use this to set left/right explicitly // for now use this to set left/right explicitly
position: '', position: '',
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this.guid = this.dom.guid(this); this.guid = this.dom.guid(this);
this.submenus = []; this.submenus = [];
}, },
willRender: function() { willRender: function () {
set(this, 'hasHeader', this._isRegistered('header')); set(this, 'hasHeader', this._isRegistered('header'));
}, },
actions: { actions: {
addSubmenu: function(name) { addSubmenu: function (name) {
set(this, 'submenus', this.submenus.concat(name)); set(this, 'submenus', this.submenus.concat(name));
}, },
removeSubmenu: function(name) { removeSubmenu: function (name) {
const pos = this.submenus.indexOf(name); const pos = this.submenus.indexOf(name);
if (pos !== -1) { if (pos !== -1) {
this.submenus.splice(pos, 1); this.submenus.splice(pos, 1);
set(this, 'submenus', this.submenus); set(this, 'submenus', this.submenus);
} }
}, },
change: function(e) { change: function (e) {
if (!e.target.checked) { if (!e.target.checked) {
[...this.dom.elements(`[id^=popover-menu-${this.guid}]`)].forEach(function($item) { [...this.dom.elements(`[id^=popover-menu-${this.guid}]`)].forEach(function ($item) {
$item.checked = false; $item.checked = false;
}); });
} }
@ -43,7 +43,7 @@ export default Component.extend(Slotted, {
// Temporary send here so we can send route actions // Temporary send here so we can send route actions
// easily. It kind of makes sense that you'll want to perform // easily. It kind of makes sense that you'll want to perform
// route actions from a popup menu for the moment // route actions from a popup menu for the moment
send: function() { send: function () {
this.sendAction(...arguments); this.sendAction(...arguments);
}, },
}, },

View File

@ -7,19 +7,19 @@ import Slotted from 'block-slots';
export default Component.extend(Slotted, { export default Component.extend(Slotted, {
tagName: '', tagName: '',
dom: service('dom'), dom: service('dom'),
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this.guid = this.dom.guid(this); this.guid = this.dom.guid(this);
}, },
didInsertElement: function() { didInsertElement: function () {
this._super(...arguments); this._super(...arguments);
this.menu.addSubmenu(this.guid); this.menu.addSubmenu(this.guid);
}, },
didDestroyElement: function() { didDestroyElement: function () {
this._super(...arguments); this._super(...arguments);
this.menu.removeSubmenu(this.guid); this.menu.removeSubmenu(this.guid);
}, },
willRender: function() { willRender: function () {
this._super(...arguments); this._super(...arguments);
set(this, 'hasConfirmation', this._isRegistered('confirmation')); set(this, 'hasConfirmation', this._isRegistered('confirmation'));
}, },

View File

@ -7,31 +7,31 @@ export default Component.extend(Slotted, {
dom: service('dom'), dom: service('dom'),
multiple: false, multiple: false,
required: false, required: false,
onchange: function() {}, onchange: function () {},
addOption: function(option) { addOption: function (option) {
if (typeof this._options === 'undefined') { if (typeof this._options === 'undefined') {
this._options = new Set(); this._options = new Set();
} }
this._options.add(option); this._options.add(option);
}, },
removeOption: function(option) { removeOption: function (option) {
this._options.delete(option); this._options.delete(option);
}, },
actions: { actions: {
click: function(option, e) { click: function (option, e) {
// required={{true}} ? // required={{true}} ?
if (!this.multiple) { if (!this.multiple) {
if (option.selected && this.required) { if (option.selected && this.required) {
return e; return e;
} }
[...this._options] [...this._options]
.filter(item => item !== option) .filter((item) => item !== option)
.forEach(item => { .forEach((item) => {
item.selected = false; item.selected = false;
}); });
} else { } else {
if (option.selected && this.required) { if (option.selected && this.required) {
const other = [...this._options].find(item => item !== option && item.selected); const other = [...this._options].find((item) => item !== option && item.selected);
if (!other) { if (!other) {
return e; return e;
} }
@ -40,11 +40,11 @@ export default Component.extend(Slotted, {
option.selected = !option.selected; option.selected = !option.selected;
this.onchange( this.onchange(
this.dom.setEventTargetProperties(e, { this.dom.setEventTargetProperties(e, {
selected: target => option.args.value, selected: (target) => option.args.value,
selectedItems: target => { selectedItems: (target) => {
return [...this._options] return [...this._options]
.filter(item => item.selected) .filter((item) => item.selected)
.map(item => item.args.value) .map((item) => item.args.value)
.join(','); .join(',');
}, },
}) })

View File

@ -1,4 +1,5 @@
export default (clickable, collection) => (scope = '.popover-select') => { export default (clickable, collection) =>
(scope = '.popover-select') => {
return { return {
scope: scope, scope: scope,
selected: clickable('button'), selected: clickable('button'),
@ -6,4 +7,4 @@ export default (clickable, collection) => (scope = '.popover-select') => {
button: clickable('button'), button: clickable('button'),
}), }),
}; };
}; };

View File

@ -1,6 +1,6 @@
import { clickable, isPresent } from 'ember-cli-page-object'; import { clickable, isPresent } from 'ember-cli-page-object';
export default options => { export default (options) => {
return { return {
present: isPresent('.ember-power-select-trigger'), present: isPresent('.ember-power-select-trigger'),
click: clickable('.ember-power-select-trigger'), click: clickable('.ember-power-select-trigger'),

View File

@ -6,19 +6,19 @@ export default Component.extend({
tagName: '', tagName: '',
keyboardAccess: false, keyboardAccess: false,
dom: service('dom'), dom: service('dom'),
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this.name = this.dom.guid(this); this.name = this.dom.guid(this);
}, },
actions: { actions: {
keydown: function(e) { keydown: function (e) {
if (e.keyCode === ENTER) { if (e.keyCode === ENTER) {
e.target.dispatchEvent(new MouseEvent('click')); e.target.dispatchEvent(new MouseEvent('click'));
} }
}, },
change: function(e) { change: function (e) {
this.onchange( this.onchange(
this.dom.setEventTargetProperty(e, 'value', value => (value === '' ? undefined : value)) this.dom.setEventTargetProperty(e, 'value', (value) => (value === '' ? undefined : value))
); );
}, },
}, },

View File

@ -2,14 +2,14 @@ import { is, clickable } from 'ember-cli-page-object';
import ucfirst from 'consul-ui/utils/ucfirst'; import ucfirst from 'consul-ui/utils/ucfirst';
// TODO: We no longer need to use name here // TODO: We no longer need to use name here
// remove the arg in all objects // remove the arg in all objects
export default function(name, items, blankKey = 'all') { export default function (name, items, blankKey = 'all') {
return items.reduce(function(prev, item, i, arr) { return items.reduce(function (prev, item, i, arr) {
// if item is empty then it means 'all' // if item is empty then it means 'all'
// otherwise camelCase based on something-here = somethingHere for the key // otherwise camelCase based on something-here = somethingHere for the key
const key = const key =
item === '' item === ''
? blankKey ? blankKey
: item.split('-').reduce(function(prev, item, i, arr) { : item.split('-').reduce(function (prev, item, i, arr) {
if (i === 0) { if (i === 0) {
return item; return item;
} }

View File

@ -3,7 +3,7 @@ import { set } from '@ember/object';
export default Component.extend({ export default Component.extend({
tagName: '', tagName: '',
didReceiveAttrs: function() { didReceiveAttrs: function () {
set(this.target, this.name, this.value); set(this.target, this.name, this.value);
}, },
}); });

View File

@ -15,20 +15,20 @@ export default ChildSelectorComponent.extend({
// You have to alias data. // You have to alias data.
// If you just set it, it loses its reference? // If you just set it, it loses its reference?
policy: alias('policyForm.data'), policy: alias('policyForm.data'),
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this.policyForm = this.formContainer.form('policy'); set(this, 'policyForm', this.formContainer.form('policy'));
this.source = new EventSource(); this.source = new EventSource();
}, },
actions: { actions: {
reset: function(e) { reset: function (e) {
this._super(...arguments); this._super(...arguments);
this.policyForm.clear({ Datacenter: this.dc }); this.policyForm.clear({ Datacenter: this.dc });
}, },
dispatch: function(type, data) { dispatch: function (type, data) {
this.source.dispatchEvent({ type: type, data: data }); this.source.dispatchEvent({ type: type, data: data });
}, },
change: function() { change: function () {
const event = this.dom.normalizeEvent(...arguments); const event = this.dom.normalizeEvent(...arguments);
const target = event.target; const target = event.target;
switch (target.name) { switch (target.name) {

View File

@ -1,16 +1,14 @@
export default (clickable, deletable, collection, alias, roleForm) => (scope = '#roles') => { export default (clickable, deletable, collection, alias, roleForm) =>
(scope = '#roles') => {
return { return {
scope: scope, scope: scope,
create: clickable('[data-test-role-create]'), create: clickable('[data-test-role-create]'),
form: roleForm(), form: roleForm(),
roles: alias('selectedOptions'), roles: alias('selectedOptions'),
selectedOptions: collection( selectedOptions: collection('[data-test-roles] [data-test-tabular-row]', {
'[data-test-roles] [data-test-tabular-row]',
{
actions: clickable('label > button'), actions: clickable('label > button'),
delete: clickable('[data-test-delete]'), delete: clickable('[data-test-delete]'),
confirmDelete: clickable('.informed-action button'), confirmDelete: clickable('.informed-action button'),
} }),
), };
}; };
};

View File

@ -14,7 +14,7 @@ export default class RouteComponent extends Component {
constructor() { constructor() {
super(...arguments); super(...arguments);
this.intlKey = this.encoder.createRegExpEncoder(templateRe, _ => _); this.intlKey = this.encoder.createRegExpEncoder(templateRe, (_) => _);
} }
get params() { get params() {
@ -27,8 +27,11 @@ export default class RouteComponent extends Component {
} }
if (this.args.name) { if (this.args.name) {
const outlet = this.routlet.outletFor(this.args.name); const outlet = this.routlet.outletFor(this.args.name);
if (outlet) {
return this.routlet.modelFor(outlet.name); return this.routlet.modelFor(outlet.name);
} }
}
return undefined; return undefined;
} }

View File

@ -1,5 +1,5 @@
export const diff = (a, b) => { export const diff = (a, b) => {
return a.filter(item => !b.includes(item)); return a.filter((item) => !b.includes(item));
}; };
/** /**
* filters accepts the args.filter @attribute which is shaped like * filters accepts the args.filter @attribute which is shaped like
@ -11,7 +11,7 @@ export const diff = (a, b) => {
* There is more explanation in the unit tests for this function so thats worthwhile * There is more explanation in the unit tests for this function so thats worthwhile
* checking if you are in amongst this * checking if you are in amongst this
*/ */
export const filters = filters => { export const filters = (filters) => {
return Object.entries(filters) return Object.entries(filters)
.filter(([key, value]) => { .filter(([key, value]) => {
if (key === 'searchproperty') { if (key === 'searchproperty') {
@ -21,7 +21,7 @@ export const filters = filters => {
}) })
.reduce((prev, [key, value]) => { .reduce((prev, [key, value]) => {
return prev.concat( return prev.concat(
value.value.map(item => { value.value.map((item) => {
const obj = { const obj = {
key: key, key: key,
value: item, value: item,

View File

@ -3,12 +3,10 @@ import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking'; import { tracked } from '@glimmer/tracking';
export default class ShadowHostComponent extends Component { export default class ShadowHostComponent extends Component {
@tracked shadowRoot; @tracked shadowRoot;
@action @action
attachShadow($element) { attachShadow($element) {
this.shadowRoot = $element.attachShadow({ mode: 'open' }); this.shadowRoot = $element.attachShadow({ mode: 'open' });
} }
} }

View File

@ -2,11 +2,11 @@ import Component from '@ember/component';
export default Component.extend({ export default Component.extend({
tagName: '', tagName: '',
didInsertElement: function() { didInsertElement: function () {
this._super(...arguments); this._super(...arguments);
this.chart.addAction(this.name, (context, event) => this.exec(context, event)); this.chart.addAction(this.name, (context, event) => this.exec(context, event));
}, },
willDestroy: function() { willDestroy: function () {
this._super(...arguments); this._super(...arguments);
this.chart.removeAction(this.type); this.chart.removeAction(this.type);
}, },

View File

@ -2,10 +2,10 @@ import Component from '@ember/component';
export default Component.extend({ export default Component.extend({
tagName: '', tagName: '',
didInsertElement: function() { didInsertElement: function () {
this._super(...arguments); this._super(...arguments);
const component = this; const component = this;
this.chart.addGuard(this.name, function() { this.chart.addGuard(this.name, function () {
if (typeof component.cond === 'function') { if (typeof component.cond === 'function') {
return component.cond(...arguments); return component.cond(...arguments);
} else { } else {
@ -13,7 +13,7 @@ export default Component.extend({
} }
}); });
}, },
willDestroyElement: function() { willDestroyElement: function () {
this._super(...arguments); this._super(...arguments);
this.chart.removeGuard(this.name); this.chart.removeGuard(this.name);
}, },

View File

@ -5,13 +5,13 @@ import { set } from '@ember/object';
export default Component.extend({ export default Component.extend({
chart: service('state'), chart: service('state'),
tagName: '', tagName: '',
ontransition: function(e) {}, ontransition: function (e) {},
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this._actions = {}; this._actions = {};
this._guards = {}; this._guards = {};
}, },
didReceiveAttrs: function() { didReceiveAttrs: function () {
if (typeof this.machine !== 'undefined') { if (typeof this.machine !== 'undefined') {
this.machine.stop(); this.machine.stop();
} }
@ -19,11 +19,11 @@ export default Component.extend({
this.src.initial = this.initial; this.src.initial = this.initial;
} }
this.machine = this.chart.interpret(this.src, { this.machine = this.chart.interpret(this.src, {
onTransition: state => { onTransition: (state) => {
const e = new CustomEvent('transition', { detail: state }); const e = new CustomEvent('transition', { detail: state });
this.ontransition(e); this.ontransition(e);
if (!e.defaultPrevented) { if (!e.defaultPrevented) {
state.actions.forEach(item => { state.actions.forEach((item) => {
const action = this._actions[item.type]; const action = this._actions[item.type];
if (typeof action === 'function') { if (typeof action === 'function') {
this._actions[item.type](item.type, state.context, state.event); this._actions[item.type](item.type, state.context, state.event);
@ -37,35 +37,35 @@ export default Component.extend({
}, },
}); });
}, },
didInsertElement: function() { didInsertElement: function () {
this._super(...arguments); this._super(...arguments);
// xstate has initialState xstate/fsm has state // xstate has initialState xstate/fsm has state
set(this, 'state', this.machine.initialState || this.machine.state); set(this, 'state', this.machine.initialState || this.machine.state);
// set(this, 'state', this.machine.initialState); // set(this, 'state', this.machine.initialState);
this.machine.start(); this.machine.start();
}, },
willDestroy: function() { willDestroy: function () {
this._super(...arguments); this._super(...arguments);
this.machine.stop(); this.machine.stop();
}, },
addAction: function(name, value) { addAction: function (name, value) {
this._actions[name] = value; this._actions[name] = value;
}, },
removeAction: function(name) { removeAction: function (name) {
delete this._actions[name]; delete this._actions[name];
}, },
addGuard: function(name, value) { addGuard: function (name, value) {
this._guards[name] = value; this._guards[name] = value;
}, },
removeGuard: function(name) { removeGuard: function (name) {
delete this._guards[name]; delete this._guards[name];
}, },
dispatch: function(eventName, payload) { dispatch: function (eventName, payload) {
this.machine.state.context = payload; this.machine.state.context = payload;
this.machine.send({ type: eventName }); this.machine.send({ type: eventName });
}, },
actions: { actions: {
dispatch: function(eventName, e) { dispatch: function (eventName, e) {
if (e && e.preventDefault) { if (e && e.preventDefault) {
if (typeof e.target.nodeName === 'undefined' || e.target.nodeName.toLowerCase() !== 'a') { if (typeof e.target.nodeName === 'undefined' || e.target.nodeName.toLowerCase() !== 'a') {
e.preventDefault(); e.preventDefault();

View File

@ -1,4 +1,3 @@
import Component from '../state-chart/index'; import Component from '../state-chart/index';
export default Component.extend({}); export default Component.extend({});

View File

@ -13,8 +13,9 @@ export default class State extends Component {
if (typeof state === 'undefined') { if (typeof state === 'undefined') {
return; return;
} }
this.render = typeof matches !== 'undefined' ? this.render =
this.state.matches(state, matches) : typeof matches !== 'undefined'
!this.state.matches(state, notMatches); ? this.state.matches(state, matches)
: !this.state.matches(state, notMatches);
} }
} }

View File

@ -31,16 +31,10 @@ as |select name|}}
> >
<Action <Action
{{on 'click' {{on 'click'
(if (not-eq @onclick undefined) (fn this.onClick (uppercase item.label))
(fn @onclick (uppercase item.label))
(noop)
)
}} }}
{{on 'click' {{on 'click'
(if @onTabClicked (fn this.onTabClicked item)
(fn @onTabClicked item)
(noop)
)
}} }}
@href={{item.href}} @href={{item.href}}
> >

View File

@ -1,3 +1,12 @@
import Component from '@glimmer/component'; import Component from '@glimmer/component';
export default class TabNav extends Component {} function noop() {}
export default class TabNav extends Component {
get onClick() {
return this.args.onclick || noop;
}
get onTabClicked() {
return this.args.onTabClicked || noop;
}
}

View File

@ -1,13 +1,13 @@
import { is, clickable, attribute, isVisible } from 'ember-cli-page-object'; import { is, clickable, attribute, isVisible } from 'ember-cli-page-object';
import ucfirst from 'consul-ui/utils/ucfirst'; import ucfirst from 'consul-ui/utils/ucfirst';
export default function(name, items, blankKey = 'all') { export default function (name, items, blankKey = 'all') {
return items.reduce(function(prev, item, i, arr) { return items.reduce(function (prev, item, i, arr) {
// if item is empty then it means 'all' // if item is empty then it means 'all'
// otherwise camelCase based on something-here = somethingHere for the key // otherwise camelCase based on something-here = somethingHere for the key
const key = const key =
item === '' item === ''
? blankKey ? blankKey
: item.split('-').reduce(function(prev, item, i, arr) { : item.split('-').reduce(function (prev, item, i, arr) {
if (i === 0) { if (i === 0) {
return item; return item;
} }

View File

@ -15,13 +15,13 @@ export default CollectionComponent.extend(Slotted, {
maxHeight: 500, maxHeight: 500,
checked: null, checked: null,
hasCaption: false, hasCaption: false,
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this.guid = this.dom.guid(this); this.guid = this.dom.guid(this);
// TODO: The row height should auto calculate properly from the CSS // TODO: The row height should auto calculate properly from the CSS
const o = this; const o = this;
this['cell-layout'] = new Grid(get(this, 'width'), get(this, 'rowHeight')); this['cell-layout'] = new Grid(get(this, 'width'), get(this, 'rowHeight'));
this['cell-layout'].formatItemStyle = function(itemIndex) { this['cell-layout'].formatItemStyle = function (itemIndex) {
let style = formatItemStyle.apply(this, arguments); let style = formatItemStyle.apply(this, arguments);
if (o.checked === itemIndex) { if (o.checked === itemIndex) {
style = `${style};z-index: 1`; style = `${style};z-index: 1`;
@ -29,12 +29,12 @@ export default CollectionComponent.extend(Slotted, {
return style; return style;
}; };
}, },
didInsertElement: function() { didInsertElement: function () {
this._super(...arguments); this._super(...arguments);
this.$element = this.dom.element(`#${this.guid}`); this.$element = this.dom.element(`#${this.guid}`);
this.actions.resize.apply(this, [{ target: this.dom.viewport() }]); this.actions.resize.apply(this, [{ target: this.dom.viewport() }]);
}, },
style: computed('rowHeight', '_items', 'maxRows', 'maxHeight', function() { style: computed('rowHeight', '_items', 'maxRows', 'maxHeight', function () {
const maxRows = get(this, 'rows'); const maxRows = get(this, 'rows');
let height = get(this, 'maxHeight'); let height = get(this, 'maxHeight');
if (maxRows) { if (maxRows) {
@ -46,14 +46,14 @@ export default CollectionComponent.extend(Slotted, {
height: height, height: height,
}; };
}), }),
willRender: function() { willRender: function () {
this._super(...arguments); this._super(...arguments);
set(this, 'hasCaption', this._isRegistered('caption')); set(this, 'hasCaption', this._isRegistered('caption'));
set(this, 'hasActions', this._isRegistered('actions')); set(this, 'hasActions', this._isRegistered('actions'));
}, },
// `ember-collection` bug workaround // `ember-collection` bug workaround
// https://github.com/emberjs/ember-collection/issues/138 // https://github.com/emberjs/ember-collection/issues/138
_needsRevalidate: function() { _needsRevalidate: function () {
if (this.isDestroyed || this.isDestroying) { if (this.isDestroyed || this.isDestroying) {
return; return;
} }
@ -64,7 +64,7 @@ export default CollectionComponent.extend(Slotted, {
} }
}, },
actions: { actions: {
resize: function(e) { resize: function (e) {
const $tbody = this.$element; const $tbody = this.$element;
const $appContent = this.dom.element('.app-view'); const $appContent = this.dom.element('.app-view');
if ($appContent) { if ($appContent) {
@ -77,7 +77,7 @@ export default CollectionComponent.extend(Slotted, {
// TODO: The row height should auto calculate properly from the CSS // TODO: The row height should auto calculate properly from the CSS
this['cell-layout'] = new Grid($appContent.clientWidth, get(this, 'rowHeight')); this['cell-layout'] = new Grid($appContent.clientWidth, get(this, 'rowHeight'));
const o = this; const o = this;
this['cell-layout'].formatItemStyle = function(itemIndex) { this['cell-layout'].formatItemStyle = function (itemIndex) {
let style = formatItemStyle.apply(this, arguments); let style = formatItemStyle.apply(this, arguments);
if (o.checked === itemIndex) { if (o.checked === itemIndex) {
style = `${style};z-index: 1`; style = `${style};z-index: 1`;
@ -88,10 +88,10 @@ export default CollectionComponent.extend(Slotted, {
this.updateScrollPosition(); this.updateScrollPosition();
} }
}, },
click: function(e) { click: function (e) {
return this.dom.clickFirstAnchor(e); return this.dom.clickFirstAnchor(e);
}, },
change: function(index, e = {}) { change: function (index, e = {}) {
if (this.$tr) { if (this.$tr) {
this.$tr.style.zIndex = null; this.$tr.style.zIndex = null;
} }

View File

@ -4,16 +4,16 @@ import Slotted from 'block-slots';
export default Component.extend(Slotted, { export default Component.extend(Slotted, {
dom: service('dom'), dom: service('dom'),
onchange: function() {}, onchange: function () {},
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this.guid = this.dom.guid(this); this.guid = this.dom.guid(this);
}, },
actions: { actions: {
click: function(e) { click: function (e) {
this.dom.clickFirstAnchor(e); this.dom.clickFirstAnchor(e);
}, },
change: function(item, items, e) { change: function (item, items, e) {
this.onchange(e, item, items); this.onchange(e, item, items);
}, },
}, },

View File

@ -5,19 +5,19 @@ export default Component.extend({
dom: service('dom'), dom: service('dom'),
tagName: '', tagName: '',
checked: false, checked: false,
onchange: function() {}, onchange: function () {},
// TODO: reserved for the moment but we don't need it yet // TODO: reserved for the moment but we don't need it yet
onblur: function() {}, onblur: function () {},
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this.guid = this.dom.guid(this); this.guid = this.dom.guid(this);
this._listeners = this.dom.listeners(); this._listeners = this.dom.listeners();
}, },
willDestroyElement: function() { willDestroyElement: function () {
this._super(...arguments); this._super(...arguments);
this._listeners.remove(); this._listeners.remove();
}, },
didReceiveAttrs: function() { didReceiveAttrs: function () {
this._super(...arguments); this._super(...arguments);
if (this.checked) { if (this.checked) {
this.addClickOutsideListener(); this.addClickOutsideListener();
@ -25,10 +25,10 @@ export default Component.extend({
this._listeners.remove(); this._listeners.remove();
} }
}, },
addClickOutsideListener: function() { addClickOutsideListener: function () {
// default onblur event // default onblur event
this._listeners.remove(); this._listeners.remove();
this._listeners.add(this.dom.document(), 'click', e => { this._listeners.add(this.dom.document(), 'click', (e) => {
if (this.dom.isOutside(this.label, e.target)) { if (this.dom.isOutside(this.label, e.target)) {
if (this.dom.isOutside(this.label.nextElementSibling, e.target)) { if (this.dom.isOutside(this.label.nextElementSibling, e.target)) {
if (this.input.checked) { if (this.input.checked) {
@ -42,7 +42,7 @@ export default Component.extend({
}); });
}, },
actions: { actions: {
click: function(e) { click: function (e) {
// only preventDefault if the target isn't an external link // only preventDefault if the target isn't an external link
// TODO: this should be changed for an explicit close // TODO: this should be changed for an explicit close
if ((e.target.rel || '').indexOf('noopener') === -1) { if ((e.target.rel || '').indexOf('noopener') === -1) {
@ -56,7 +56,7 @@ export default Component.extend({
} }
this.actions.change.apply(this, [e]); this.actions.change.apply(this, [e]);
}, },
change: function(e) { change: function (e) {
if (this.input.checked) { if (this.input.checked) {
this.addClickOutsideListener(); this.addClickOutsideListener();
} }

View File

@ -20,7 +20,7 @@ export default class TokenSource extends Component {
@action @action
change(e) { change(e) {
e.data.toJSON = function() { e.data.toJSON = function () {
return { return {
AccessorID: this.AccessorID, AccessorID: this.AccessorID,
// TODO: In the past we've always ignored the SecretID returned // TODO: In the past we've always ignored the SecretID returned
@ -39,9 +39,8 @@ export default class TokenSource extends Component {
}; };
}; };
// TODO: We should probably put the component into idle state // TODO: We should probably put the component into idle state
if(typeof this.args.onchange === 'function') { if (typeof this.args.onchange === 'function') {
this.args.onchange(e); this.args.onchange(e);
} }
} }
} }

View File

@ -16,7 +16,7 @@ export default class TopoloyMetricsDownLines extends Component {
const view = this.args.view; const view = this.args.view;
const lines = [...document.querySelectorAll('#downstream-lines path')]; const lines = [...document.querySelectorAll('#downstream-lines path')];
this.iconPositions = lines.map(item => { this.iconPositions = lines.map((item) => {
const pathLen = parseFloat(item.getTotalLength()); const pathLen = parseFloat(item.getTotalLength());
const thirdLen = item.getPointAtLength(Math.ceil(pathLen / 3)); const thirdLen = item.getPointAtLength(Math.ceil(pathLen / 3));

View File

@ -24,7 +24,7 @@ export default class TopologyMetrics extends Component {
}; };
return items return items
.map(item => { .map((item) => {
const dimensions = item.getBoundingClientRect(); const dimensions = item.getBoundingClientRect();
const src = { const src = {
x: dimensions.x + dimensions.width, x: dimensions.x + dimensions.width,
@ -51,7 +51,7 @@ export default class TopologyMetrics extends Component {
}; };
return items return items
.map(item => { .map((item) => {
const dimensions = item.getBoundingClientRect(); const dimensions = item.getBoundingClientRect();
const dest = { const dest = {
x: dimensions.x - dimensions.width - 25, x: dimensions.x - dimensions.width - 25,
@ -104,7 +104,7 @@ export default class TopologyMetrics extends Component {
get upstreams() { get upstreams() {
const upstreams = get(this.args.topology, 'Upstreams') || []; const upstreams = get(this.args.topology, 'Upstreams') || [];
upstreams.forEach(u => { upstreams.forEach((u) => {
u.PeerOrDatacenter = u.PeerName || u.Datacenter; u.PeerOrDatacenter = u.PeerName || u.Datacenter;
}); });
const items = [...upstreams]; const items = [...upstreams];

View File

@ -24,17 +24,17 @@ export default Component.extend({
data: null, data: null,
empty: false, empty: false,
actions: { actions: {
redraw: function(evt) { redraw: function (evt) {
this.drawGraphs(); this.drawGraphs();
}, },
change: function(evt) { change: function (evt) {
this.set('data', evt.data.series); this.set('data', evt.data.series);
this.drawGraphs(); this.drawGraphs();
this.rerender(); this.rerender();
}, },
}, },
drawGraphs: function() { drawGraphs: function () {
if (!this.data) { if (!this.data) {
set(this, 'empty', true); set(this, 'empty', true);
return; return;
@ -56,7 +56,7 @@ export default Component.extend({
let series = maybeData.data || []; let series = maybeData.data || [];
let labels = maybeData.labels || {}; let labels = maybeData.labels || {};
let unitSuffix = maybeData.unitSuffix || ''; let unitSuffix = maybeData.unitSuffix || '';
let keys = Object.keys(labels).filter(l => l != 'Total'); let keys = Object.keys(labels).filter((l) => l != 'Total');
if (series.length == 0 || keys.length == 0) { if (series.length == 0 || keys.length == 0) {
// Put the graph in an error state that might get fixed if metrics show up // Put the graph in an error state that might get fixed if metrics show up
@ -67,9 +67,7 @@ export default Component.extend({
set(this, 'empty', false); set(this, 'empty', false);
} }
let st = stack() let st = stack().keys(keys).order(stackOrderReverse);
.keys(keys)
.order(stackOrderReverse);
let stackData = st(series); let stackData = st(series);
@ -77,16 +75,16 @@ export default Component.extend({
// stackData contains this but I didn't find reliable documentation on // stackData contains this but I didn't find reliable documentation on
// whether we can rely on the highest stacked area to always be first/last // whether we can rely on the highest stacked area to always be first/last
// in array etc. so this is simpler. // in array etc. so this is simpler.
let summed = series.map(d => { let summed = series.map((d) => {
let sum = 0; let sum = 0;
keys.forEach(l => { keys.forEach((l) => {
sum = sum + d[l]; sum = sum + d[l];
}); });
return sum; return sum;
}); });
let x = scaleTime() let x = scaleTime()
.domain(extent(series, d => d.time)) .domain(extent(series, (d) => d.time))
.range([0, w]); .range([0, w]);
let y = scaleLinear() let y = scaleLinear()
@ -94,9 +92,9 @@ export default Component.extend({
.range([h, 0]); .range([h, 0]);
let a = area() let a = area()
.x(d => x(d.data.time)) .x((d) => x(d.data.time))
.y1(d => y(d[0])) .y1((d) => y(d[0]))
.y0(d => y(d[1])); .y0((d) => y(d[1]));
// Use the grey/red we prefer by default but have more colors available in // Use the grey/red we prefer by default but have more colors available in
// case user adds extra series with a custom provider. // case user adds extra series with a custom provider.
@ -136,11 +134,7 @@ export default Component.extend({
.attr('class', 'sparkline-tt-legend-color') .attr('class', 'sparkline-tt-legend-color')
.style('background-color', color(k)); .style('background-color', color(k));
legend legend.append('span').text(k).append('span').attr('class', 'sparkline-tt-legend-value');
.append('span')
.text(k)
.append('span')
.attr('class', 'sparkline-tt-legend-value');
} }
let tipVals = tooltip.selectAll('.sparkline-tt-legend-value'); let tipVals = tooltip.selectAll('.sparkline-tt-legend-value');
@ -158,7 +152,7 @@ export default Component.extend({
let self = this; let self = this;
svg svg
.on('mouseover', function(e) { .on('mouseover', function (e) {
tooltip.style('visibility', 'visible'); tooltip.style('visibility', 'visible');
cursor.style('visibility', 'visible'); cursor.style('visibility', 'visible');
// We update here since we might redraw the graph with user's cursor // We update here since we might redraw the graph with user's cursor
@ -166,26 +160,26 @@ export default Component.extend({
// mousemove but the tooltip and cursor are wrong (based on old data). // mousemove but the tooltip and cursor are wrong (based on old data).
self.updateTooltip(e, series, stackData, summed, unitSuffix, x, tooltip, tipVals, cursor); self.updateTooltip(e, series, stackData, summed, unitSuffix, x, tooltip, tipVals, cursor);
}) })
.on('mousemove', function(e) { .on('mousemove', function (e) {
self.updateTooltip(e, series, stackData, summed, unitSuffix, x, tooltip, tipVals, cursor); self.updateTooltip(e, series, stackData, summed, unitSuffix, x, tooltip, tipVals, cursor);
}) })
.on('mouseout', function(e) { .on('mouseout', function (e) {
tooltip.style('visibility', 'hidden'); tooltip.style('visibility', 'hidden');
cursor.style('visibility', 'hidden'); cursor.style('visibility', 'hidden');
}); });
}, },
willDestroyElement: function() { willDestroyElement: function () {
this._super(...arguments); this._super(...arguments);
if (typeof this.svg !== 'undefined') { if (typeof this.svg !== 'undefined') {
this.svg.on('mouseover mousemove mouseout', null); this.svg.on('mouseover mousemove mouseout', null);
} }
}, },
updateTooltip: function(e, series, stackData, summed, unitSuffix, x, tooltip, tipVals, cursor) { updateTooltip: function (e, series, stackData, summed, unitSuffix, x, tooltip, tipVals, cursor) {
let [mouseX] = pointer(e); let [mouseX] = pointer(e);
cursor.attr('x', mouseX); cursor.attr('x', mouseX);
let mouseTime = x.invert(mouseX); let mouseTime = x.invert(mouseX);
var bisectTime = bisector(function(d) { var bisectTime = bisector(function (d) {
return d.time; return d.time;
}).left; }).left;
let tipIdx = bisectTime(series, mouseTime); let tipIdx = bisectTime(series, mouseTime);

View File

@ -17,7 +17,7 @@ export default class TopologyMetricsUpLines extends Component {
const view = this.args.view; const view = this.args.view;
const lines = [...document.querySelectorAll('#upstream-lines path')]; const lines = [...document.querySelectorAll('#upstream-lines path')];
this.iconPositions = lines.map(item => { this.iconPositions = lines.map((item) => {
const pathLen = parseFloat(item.getTotalLength()); const pathLen = parseFloat(item.getTotalLength());
const partLen = item.getPointAtLength(Math.ceil(pathLen * 0.666)); const partLen = item.getPointAtLength(Math.ceil(pathLen * 0.666));
return { return {

View File

@ -8,7 +8,7 @@ export default class PeeredResourceController extends Controller {
const { searchProperties } = this; const { searchProperties } = this;
if (!this.abilities.can('use peers')) { if (!this.abilities.can('use peers')) {
return searchProperties.filter(propertyName => propertyName !== 'PeerName'); return searchProperties.filter((propertyName) => propertyName !== 'PeerName');
} else { } else {
return searchProperties; return searchProperties;
} }

View File

@ -46,13 +46,13 @@ export default class ApplicationController extends Controller {
return container return container
.lookup('route:application') .lookup('route:application')
.refresh() .refresh()
.promise.catch(function(e) { .promise.catch(function (e) {
// passthrough // passthrough
// if you are on an error page a refresh of the application route will reject // if you are on an error page a refresh of the application route will reject
// thats ok as we then transition to the actual route you were trying // thats ok as we then transition to the actual route you were trying
// to get to originally anyway // to get to originally anyway
}) })
.then(res => { .then((res) => {
// Use transitionable if we need to change a section of the URL // Use transitionable if we need to change a section of the URL
// or routeName and currentRouteName aren't equal (i.e. error page) // or routeName and currentRouteName aren't equal (i.e. error page)
if ( if (
@ -68,7 +68,7 @@ export default class ApplicationController extends Controller {
}); });
}, },
e.type, e.type,
function(type, e) { function (type, e) {
return type; return type;
}, },
{} {}

View File

@ -4,11 +4,11 @@ export default Controller.extend({
dom: service('dom'), dom: service('dom'),
builder: service('form'), builder: service('form'),
isScoped: false, isScoped: false,
init: function() { init: function () {
this._super(...arguments); this._super(...arguments);
this.form = this.builder.form('token'); this.form = this.builder.form('token');
}, },
setProperties: function(model) { setProperties: function (model) {
// essentially this replaces the data with changesets // essentially this replaces the data with changesets
this._super( this._super(
Object.keys(model).reduce((prev, key, i) => { Object.keys(model).reduce((prev, key, i) => {
@ -22,7 +22,7 @@ export default Controller.extend({
); );
}, },
actions: { actions: {
change: function(e, value, item) { change: function (e, value, item) {
const event = this.dom.normalizeEvent(e, value); const event = this.dom.normalizeEvent(e, value);
const form = this.form; const form = this.form;
try { try {

View File

@ -3,18 +3,18 @@ import wayfarer from 'wayfarer';
const router = wayfarer(); const router = wayfarer();
const routes = {}; const routes = {};
export default path => (target, propertyKey, desc) => { export default (path) => (target, propertyKey, desc) => {
runInDebug(() => { runInDebug(() => {
routes[path] = { cls: target, method: propertyKey }; routes[path] = { cls: target, method: propertyKey };
}); });
router.on(path, function(params, owner, request) { router.on(path, function (params, owner, request) {
const container = owner.lookup('service:container'); const container = owner.lookup('service:container');
const instance = container.get(target); const instance = container.get(target);
return configuration => desc.value.apply(instance, [params, configuration, request]); return (configuration) => desc.value.apply(instance, [params, configuration, request]);
}); });
return desc; return desc;
}; };
export const match = path => { export const match = (path) => {
return router.match(path); return router.match(path);
}; };
@ -29,13 +29,10 @@ runInDebug(() => {
<pre> <pre>
${Object.entries(routes) ${Object.entries(routes)
.map(([key, value]) => { .map(([key, value]) => {
let cls = container let cls = container.keyForClass(value.cls).split('/').pop();
.keyForClass(value.cls)
.split('/')
.pop();
cls = cls cls = cls
.split('-') .split('-')
.map(item => `${item[0].toUpperCase()}${item.substr(1)}`) .map((item) => `${item[0].toUpperCase()}${item.substr(1)}`)
.join(''); .join('');
return `${key} return `${key}
${cls}Repository.${value.method}(params) ${cls}Repository.${value.method}(params)

Some files were not shown because too many files have changed in this diff Show More