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,169 +1,159 @@
<div
class="consul-nspace-form"
...attributes
>
<DataWriter
@sink={{uri
'/${partition}/${nspace}/${dc}/nspace'
(hash
partition=''
nspace=''
dc=@item.Datacenter
)
}}
@type={{'nspace'}}
@label={{"Namespace"}}
@ondelete={{fn (if @ondelete @ondelete @onsubmit) @item}}
@onchange={{fn (optional @onsubmit) @item}}
as |writer|>
<BlockSlot @name="removed" as |after|>
<Consul::Nspace::Notifications
{{notification
after=(action after)
}}
@type="remove"
/>
</BlockSlot>
<div class="consul-nspace-form" ...attributes>
<DataWriter
@sink={{uri
"/${partition}/${nspace}/${dc}/nspace"
(hash partition="" nspace="" dc=@item.Datacenter)
}}
@type={{"nspace"}}
@label={{"Namespace"}}
@ondelete={{fn this.onDelete @item}}
@onchange={{fn this.onSubmit @item}}
as |writer|
>
<BlockSlot @name="removed" as |after|>
<Consul::Nspace::Notifications
{{notification after=(action after)}}
@type="remove"
/>
</BlockSlot>
<BlockSlot @name="content">
{{#let
(not (can "write nspaces"))
@item
(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.'
Name=(array
(hash
test='^[a-zA-Z0-9]([a-zA-Z0-9-]{0,62}[a-zA-Z0-9])?$'
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}}
>
<StateChart
@src={{state-chart 'validate'}}
as |State Guard ChartAction dispatch state|>
<fieldset>
{{#if (is "new nspace" item=item)}}
<TextInput
@name="Name"
@placeholder="Name"
@item={{item}}
@validations={{Name}}
@chart={{hash
state=state
dispatch=dispatch
{{#let
(not (can "write nspaces"))
@item
(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."
Name=(array
(hash
test="^[a-zA-Z0-9]([a-zA-Z0-9-]{0,62}[a-zA-Z0-9])?$"
error="Name must be a valid DNS hostname."
)
)
)
(hash Description=(array))
as |readOnly item Name Description|
}}
/>
{{/if}}
<TextInput
@expanded={{true}}
@name="Description"
@label="Description (Optional)"
@item={{item}}
@validations={{Description}}
@chart={{hash
state=state
dispatch=dispatch
}}
/>
</fieldset>
{{#if (can 'use acls')}}
<fieldset id="roles">
<h2>Roles</h2>
<p>
{{#if (can "write nspace" item=item)}}
By adding roles to this namespaces, you will apply them to all tokens created within this namespace.
{{else}}
The following roles are applied to all tokens created within this namespace.
{{/if}}
</p>
<RoleSelector
@dc={{@dc}}
@nspace="default"
@partition={{@partition}}
@disabled={{readOnly}}
@items={{item.ACLs.RoleDefaults}}
/>
</fieldset>
<fieldset id="policies">
<h2>Policies</h2>
<p>
{{#if (not readOnly)}}
By adding policies to this namespace, you will apply them to all tokens created within this namespace.
{{else}}
The following policies are applied to all tokens created within this namespace.
{{/if}}
</p>
<PolicySelector
@dc={{@dc}}
@nspace="default"
@partition={{@partition}}
@disabled={{readOnly}}
@allowIdentity={{false}}
@items={{item.ACLs.PolicyDefaults}}
/>
</fieldset>
{{/if}}
<div>
{{#if (and (is "new nspace" item=item) (can "create nspaces"))}}
<Action
@type="submit"
{{disabled (or (is "pristine nspace" item=item) (state-matches state "error"))}}
>
Save
</Action>
{{else if (can "write nspace" item=item)}}
<Action @type="submit">Save</Action>
{{/if}}
<form {{on "submit" (fn writer.persist item)}} {{disabled readOnly}}>
<Action
@type="reset"
{{on 'click' (if @oncancel (fn @oncancel item) (fn @onsubmit item))}}
>
Cancel
</Action>
{{#if (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|>
<Action
data-test-delete
class="type-delete"
{{on 'click' (fn confirm (fn writer.delete item))}}
<StateChart
@src={{state-chart "validate"}}
as |State Guard ChartAction dispatch state|
>
Delete
</Action>
</BlockSlot>
<BlockSlot @name="dialog" as |execute cancel message|>
<DeleteConfirmation
@message={{message}}
@execute={{execute}}
@cancel={{cancel}}
/>
</BlockSlot>
</ConfirmationDialog>
{{/if}}
</div>
</StateChart>
</form>
{{/let}}
</BlockSlot>
</DataWriter>
</div>
<fieldset>
{{#if (is "new nspace" item=item)}}
<TextInput
@name="Name"
@placeholder="Name"
@item={{item}}
@validations={{Name}}
@chart={{hash state=state dispatch=dispatch}}
/>
{{/if}}
<TextInput
@expanded={{true}}
@name="Description"
@label="Description (Optional)"
@item={{item}}
@validations={{Description}}
@chart={{hash state=state dispatch=dispatch}}
/>
</fieldset>
{{#if (can "use acls")}}
<fieldset id="roles">
<h2>Roles</h2>
<p>
{{#if (can "write nspace" item=item)}}
By adding roles to this namespaces, you will apply them to
all tokens created within this namespace.
{{else}}
The following roles are applied to all tokens created within
this namespace.
{{/if}}
</p>
<RoleSelector
@dc={{@dc}}
@nspace="default"
@partition={{@partition}}
@disabled={{readOnly}}
@items={{item.ACLs.RoleDefaults}}
/>
</fieldset>
<fieldset id="policies">
<h2>Policies</h2>
<p>
{{#if (not readOnly)}}
By adding policies to this namespace, you will apply them to
all tokens created within this namespace.
{{else}}
The following policies are applied to all tokens created
within this namespace.
{{/if}}
</p>
<PolicySelector
@dc={{@dc}}
@nspace="default"
@partition={{@partition}}
@disabled={{readOnly}}
@allowIdentity={{false}}
@items={{item.ACLs.PolicyDefaults}}
/>
</fieldset>
{{/if}}
<div>
{{#if (and (is "new nspace" item=item) (can "create nspaces"))}}
<Action
@type="submit"
{{disabled
(or
(is "pristine nspace" item=item)
(state-matches state "error")
)
}}
>
Save
</Action>
{{else if (can "write nspace" item=item)}}
<Action @type="submit">Save</Action>
{{/if}}
<Action @type="reset" {{on "click" (fn this.onCancel item)}}>
Cancel
</Action>
{{#if
(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|>
<Action
data-test-delete
class="type-delete"
{{on "click" (fn confirm (fn writer.delete item))}}
>
Delete
</Action>
</BlockSlot>
<BlockSlot @name="dialog" as |execute cancel message|>
<DeleteConfirmation
@message={{message}}
@execute={{execute}}
@cancel={{cancel}}
/>
</BlockSlot>
</ConfirmationDialog>
{{/if}}
</div>
</StateChart>
</form>
{{/let}}
</BlockSlot>
</DataWriter>
</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
// allow extra docfy config
let user = {sources: [], labels: {}};
let user = { sources: [], labels: {} };
const $CONSUL_DOCFY_CONFIG = process.env.CONSUL_DOCFY_CONFIG || '';
if($CONSUL_DOCFY_CONFIG.length > 0) {
if ($CONSUL_DOCFY_CONFIG.length > 0) {
try {
if(exists($CONSUL_DOCFY_CONFIG)) {
user = JSON.parse(read($CONSUL_DOCFY_CONFIG));
} else {
throw new Error(`Unable to locate ${$CONSUL_DOCFY_CONFIG}`);
}
} catch(e) {
if (exists($CONSUL_DOCFY_CONFIG)) {
user = JSON.parse(read($CONSUL_DOCFY_CONFIG));
} else {
throw new Error(`Unable to locate ${$CONSUL_DOCFY_CONFIG}`);
}
} catch (e) {
console.error(chalk.yellow(`Docfy: ${e.message}`));
}
}
@ -33,24 +33,20 @@ refractor.register(handlebars);
refractor.alias({
handlebars: ['hbs'],
shell: ['sh']
shell: ['sh'],
});
module.exports = {
remarkHbsOptions: {
escapeCurliesCode: false
escapeCurliesCode: false,
},
remarkPlugins: [
autolinkHeadings,
{
behavior: 'wrap'
}
],
rehypePlugins: [
prism
behavior: 'wrap',
},
],
rehypePlugins: [prism],
sources: [
{
root: path.resolve(__dirname, 'docs'),
@ -129,10 +125,10 @@ module.exports = {
pattern: '**/README.mdx',
urlSchema: 'auto',
urlPrefix: 'docs/consul-nspaces',
}
},
].concat(user.sources),
labels: {
"consul": "Consul Components",
...user.labels
}
consul: 'Consul Components',
...user.labels,
},
};

View File

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

View File

@ -9,24 +9,44 @@ module.exports = {
},
},
plugins: ['ember'],
extends: ['eslint:recommended', 'plugin:ember/recommended'],
extends: ['eslint:recommended', 'plugin:ember/recommended', 'plugin:prettier/recommended'],
env: {
browser: true,
},
rules: {
'no-console': ['error', {allow: ['error', 'info']}],
'no-console': ['error', { allow: ['error', 'info'] }],
'no-unused-vars': ['error', { args: 'none' }],
'ember/no-new-mixins': ['warn'],
'ember/no-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: [
// node files
{
files: [
'.eslintrc.js',
'.dev.eslintrc.js',
'.docfy-config.js',
'.prettierrc.js',
'.template-lintrc.js',
'ember-cli-build.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() {
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) {
return perm.Allow;
}
@ -64,7 +64,7 @@ export default class BaseAbility extends Ability {
get canList() {
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) {
return perm.Allow;
}
@ -74,7 +74,7 @@ export default class BaseAbility extends Ability {
get canWrite() {
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) {
return perm.Allow;
}

View File

@ -5,13 +5,12 @@ export default class IntentionAbility extends BaseAbility {
get canWrite() {
// 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 super.canWrite &&
(typeof this.item === 'undefined' || !this.canViewCRD);
return super.canWrite && (typeof this.item === 'undefined' || !this.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;
}
get canDelete() {
return ![
'DELETING',
'TERMINATED'
].includes(this.item.State) && super.canDelete;
return !['DELETING', 'TERMINATED'].includes(this.item.State) && super.canDelete;
}
get canUse() {

View File

@ -6,9 +6,11 @@ export default class ServiceInstanceAbility extends BaseAbility {
// 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
// so here we add intentions read/write for the specific segment/service prefix
return super.generateForSegment(...arguments).concat([
this.permissions.generate('intention', ACCESS_READ, segment),
this.permissions.generate('intention', ACCESS_WRITE, segment),
]);
return super
.generateForSegment(...arguments)
.concat([
this.permissions.generate('intention', ACCESS_READ, segment),
this.permissions.generate('intention', ACCESS_WRITE, segment),
]);
}
}

View File

@ -12,7 +12,7 @@ export default class ZerviceAbility extends BaseAbility {
return false;
}
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';
}
@ -22,7 +22,7 @@ export default class ZerviceAbility extends BaseAbility {
return false;
}
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';
}

View File

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

View File

@ -58,10 +58,10 @@ export default class NodeAdapter extends Adapter {
queryLeader(store, type, id, snapshot) {
return this.rpc(
function(adapter, request, serialized, unserialized) {
function (adapter, 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);
},
snapshot,

View File

@ -40,8 +40,8 @@ export default class NspaceAdapter extends Adapter {
Name: serialized.Name,
Description: serialized.Description,
ACLs: {
PolicyDefaults: serialized.ACLs.PolicyDefaults.map(item => ({ ID: item.ID })),
RoleDefaults: serialized.ACLs.RoleDefaults.map(item => ({ ID: item.ID })),
PolicyDefaults: serialized.ACLs.PolicyDefaults.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,
ACLs: {
PolicyDefaults: serialized.ACLs.PolicyDefaults.map(item => ({ ID: item.ID })),
RoleDefaults: serialized.ACLs.RoleDefaults.map(item => ({ ID: item.ID })),
PolicyDefaults: serialized.ACLs.PolicyDefaults.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) {
return this.rpc(
function(adapter, request, serialized, unserialized) {
function (adapter, 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);
},
snapshot,
@ -80,10 +80,10 @@ export default class OidcProviderAdapter extends Adapter {
logout(store, type, id, snapshot) {
return this.rpc(
function(adapter, request, serialized, unserialized) {
function (adapter, 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
return {};
},

View File

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

View File

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

View File

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

View File

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

View File

@ -8,10 +8,10 @@ import { task } from 'ember-concurrency';
import Slotted from 'block-slots';
export default Component.extend(Slotted, {
onchange: function() {},
onchange: function () {},
tagName: '',
error: function() {},
error: function () {},
type: '',
dom: service('dom'),
@ -21,17 +21,17 @@ export default Component.extend(Slotted, {
selectedOptions: alias('items'),
init: function() {
init: function () {
this._super(...arguments);
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 });
},
willDestroyElement: function() {
willDestroyElement: function () {
this._super(...arguments);
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
// losing reference as its just to figure out the diff
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
// selected/added
// 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;
}),
save: task(function*(item, items, success = function() {}) {
save: task(function* (item, items, success = function () {}) {
const repo = this.repo;
try {
item = yield repo.persist(item);
@ -64,14 +64,14 @@ export default Component.extend(Slotted, {
}
}),
actions: {
reset: function() {
reset: function () {
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 value = get(item, prop);
const pos = items.findIndex(function(item) {
const pos = items.findIndex(function (item) {
return get(item, prop) === value;
});
if (pos !== -1) {
@ -79,7 +79,7 @@ export default Component.extend(Slotted, {
}
this.onchange({ target: this });
},
change: function(e, value, item) {
change: function (e, value, item) {
const event = this.dom.normalizeEvent(...arguments);
const items = value;
switch (event.target.name) {

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
const getNodesByType = function(nodes = {}, type) {
return Object.values(nodes).filter(item => item.Type === type);
const getNodesByType = function (nodes = {}, 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') {
resolvers[service] = {
ID: `${service}.${nspace}.${partition}.${dc}`,
@ -11,16 +11,16 @@ const findResolver = function(resolvers, service, nspace = 'default', partition
}
return resolvers[service];
};
export const getAlternateServices = function(targets, a) {
export const getAlternateServices = function (targets, a) {
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
// 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
// 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'];
return bRev.find(function(item, i) {
return bRev.find(function (item, i) {
const res = item !== aRev[i];
if (res) {
type = types[i];
@ -34,8 +34,8 @@ export const getAlternateServices = function(targets, a) {
};
};
export const getSplitters = function(nodes) {
return getNodesByType(nodes, 'splitter').map(function(item) {
export const getSplitters = function (nodes) {
return getNodesByType(nodes, 'splitter').map(function (item) {
// Splitters need IDs adding so we can find them in the DOM later
// splitters have a service.nspace as a name
// 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) {
return getNodesByType(nodes, 'router').reduce(function(prev, item) {
export const getRoutes = function (nodes, uid) {
return getNodesByType(nodes, 'router').reduce(function (prev, item) {
return prev.concat(
item.Routes.map(function(route, i) {
item.Routes.map(function (route, i) {
// Routes also have IDs added via createRoute
return createRoute(route, item.Name, uid);
})
);
}, []);
};
export const getResolvers = function(
export const getResolvers = function (
dc,
partition = 'default',
nspace = 'default',
@ -72,8 +72,8 @@ export const getResolvers = function(
const resolvers = {};
// make all our resolver nodes
Object.values(nodes)
.filter(item => item.Type === 'resolver')
.forEach(function(item) {
.filter((item) => item.Type === 'resolver')
.forEach(function (item) {
const parts = item.Name.split('.');
let subset;
// 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
if (typeof nodes[`resolver:${target.ID}`] !== 'undefined') {
// 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);
};
export const createRoute = function(route, router, uid) {
export const createRoute = function (route, router, uid) {
return {
...route,
Default: route.Default || typeof route.Definition.Match === 'undefined',

View File

@ -1,10 +1,11 @@
export default (collection, text) => (scope = '.consul-health-check-list') => {
return {
scope,
item: collection('li', {
name: text('header h3'),
type: text('[data-health-check-type]'),
exposed: text('[data-test-exposed]'),
}),
export default (collection, text) =>
(scope = '.consul-health-check-list') => {
return {
scope,
item: collection('li', {
name: text('header h3'),
type: text('[data-health-check-type]'),
exposed: text('[data-test-exposed]'),
}),
};
};
};

View File

@ -192,7 +192,7 @@
<button
data-test-create-permission
type="button"
{{on "click" (optional this.modal.open)}}
{{on "click" (action this.openModal)}}
>
Add permission
</button>
@ -201,7 +201,7 @@
<Consul::Intention::Notice::Permissions />
<Consul::Intention::Permission::List
@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}}
/>
{{else}}

View File

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

View File

@ -79,7 +79,9 @@ export default class ConsulIntentionForm extends Component {
let items = e.data
.uniqBy('Name')
.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));
items = [{ Name: '*' }].concat(items);
let source = items.findBy('Name', item.SourceName);

View File

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

View File

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

View File

@ -12,10 +12,10 @@ export default Component.extend({
change: service('change'),
repo: service(`repository/${name}`),
onsubmit: function() {},
onreset: function() {},
onsubmit: function () {},
onreset: function () {},
changeset: computed('item', function() {
changeset: computed('item', function () {
return this.change.changesetFor(
name,
this.item ||
@ -27,7 +27,7 @@ export default Component.extend({
headerTypes: alias(`schema.${name}.HeaderType.allowedValues`),
headerLabels: computed(function() {
headerLabels: computed(function () {
return {
Exact: 'Exactly Matching',
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;
}),
@ -45,7 +45,7 @@ export default Component.extend({
shouldShowValueField: not('headerTypeEqualsPresent'),
actions: {
change: function(name, changeset, e) {
change: function (name, changeset, e) {
const value = typeof get(e, 'target.value') !== 'undefined' ? e.target.value : e;
switch (name) {
default:
@ -53,8 +53,8 @@ export default Component.extend({
}
changeset.validate();
},
submit: function(changeset) {
this.headerTypes.forEach(prop => {
submit: function (changeset) {
this.headerTypes.forEach((prop) => {
changeset.set(prop, undefined);
});
// 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();
},
},

View File

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

View File

@ -3,10 +3,10 @@ import { tracked } from '@glimmer/tracking';
const size = 336;
const insetSize = size / 2 - 8;
const inset = function(num) {
const inset = function (num) {
return insetSize * num;
};
const milliseconds = function(num, max) {
const milliseconds = function (num, max) {
return max > 0 ? parseInt(max * num) / 100 : 0;
};
export default class TomographyGraph extends Component {
@ -19,7 +19,7 @@ export default class TomographyGraph extends Component {
get milliseconds() {
const distances = this.args.distances || [];
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() {
@ -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
// the number around 360.
const sampling = 360 / len;
distances = distances.filter(function(_, i) {
distances = distances.filter(function (_, i) {
return i == 0 || i == len - 1 || Math.random() < sampling;
});
}

View File

@ -1,11 +1,12 @@
export default (collection, text) => (scope = '.consul-upstream-instance-list') => {
return {
scope,
item: collection('li', {
name: text('.header p'),
nspace: text('.nspace dd'),
datacenter: text('.datacenter dd'),
localAddress: text('.local-address dd'),
}),
export default (collection, text) =>
(scope = '.consul-upstream-instance-list') => {
return {
scope,
item: collection('li', {
name: text('.header p'),
nspace: text('.nspace dd'),
datacenter: text('.datacenter dd'),
localAddress: text('.local-address dd'),
}),
};
};
};

View File

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

View File

@ -9,17 +9,17 @@ export default Component.extend(Slotted, {
dom: service('dom'),
builder: service('form'),
create: false,
ondelete: function() {
ondelete: function () {
return this.onsubmit(...arguments);
},
oncancel: function() {
oncancel: function () {
return this.onsubmit(...arguments);
},
onsubmit: function() {},
onchange: function(e, form) {
onsubmit: function () {},
onchange: function (e, form) {
return form.handleEvent(e);
},
didReceiveAttrs: function() {
didReceiveAttrs: function () {
this._super(...arguments);
try {
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
}
},
willRender: function() {
willRender: function () {
this._super(...arguments);
set(this, 'hasError', this._isRegistered('error'));
},
willDestroyElement: function() {
willDestroyElement: function () {
this._super(...arguments);
if (get(this, 'data.isNew')) {
this.data.rollbackAttributes();
}
},
actions: {
setData: function(data) {
setData: function (data) {
let changeset = data;
// convert to a real changeset
if (!isChangeset(data) && typeof this.form !== 'undefined') {
@ -49,7 +49,7 @@ export default Component.extend(Slotted, {
// and autofill the new record if required
if (get(data, 'isNew')) {
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);
return prev;
}, changeset);
@ -57,7 +57,7 @@ export default Component.extend(Slotted, {
set(this, 'data', changeset);
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());
},
},

View File

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

View File

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

View File

@ -15,7 +15,7 @@ import { runInDebug } from '@ember/debug';
* @param value - value to use for replacement
* @param destroy {(prev: any, value: any) => any} - teardown function
*/
const replace = function(
const replace = function (
obj,
prop,
value,
@ -29,7 +29,7 @@ const replace = function(
};
const noop = () => {};
const optional = op => (typeof op === 'function' ? op : noop);
const optional = (op) => (typeof op === 'function' ? op : noop);
// possible values for @loading=""
const LOADING = ['eager', 'lazy'];
@ -74,7 +74,7 @@ export default class DataSource extends Component {
// otherwise its an array from the did-insert-helper
if (!Array.isArray($el)) {
this._lazyListeners.add(
this.dom.isInViewport($el, inViewport => {
this.dom.isInViewport($el, (inViewport) => {
this.isIntersecting = inViewport;
if (!this.isIntersecting) {
this.close();
@ -130,7 +130,7 @@ export default class DataSource extends Component {
this.dataSource.close(prev, this);
}
);
const error = err => {
const error = (err) => {
try {
const error = get(err, 'error.errors.firstObject') || {};
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)
const remove = this._listeners.add(this.source, {
message: e => {
message: (e) => {
try {
this.onchange(e);
} catch (err) {
error(err);
}
},
error: e => {
error: (e) => {
error(e);
},
});
@ -187,7 +187,7 @@ export default class DataSource extends Component {
this.disconnect();
schedule('afterRender', () => {
// TODO: Support lazy data-sources by keeping a reference to $el
runInDebug(_ =>
runInDebug((_) =>
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`
)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
export default triggerable => () => {
export default (triggerable) => () => {
return {
...{
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 = {
navigation: [
'services',
@ -12,7 +12,7 @@ export default (collection, clickable, attribute, is, authForm, emptyState) => s
'settings',
'auth',
].reduce(
function(prev, item, i, arr) {
function (prev, item, i, arr) {
const key = item;
return Object.assign({}, prev, {
[key]: clickable(`[data-test-main-nav-${item}] > *`),
@ -23,7 +23,7 @@ export default (collection, clickable, attribute, is, authForm, emptyState) => s
}
),
footer: ['copyright', 'docs'].reduce(
function(prev, item, i, arr) {
function (prev, item, i, arr) {
const key = item;
return Object.assign({}, prev, {
[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
this.source = fromPromise(this.repo.findCodeByURL(this.args.src));
this._listeners.add(this.source, {
message: e => this.onchange(e),
error: e => this.onerror(e),
message: (e) => this.onchange(e),
error: (e) => this.onerror(e),
});
}
onchange(e) {
if(typeof this.args.onchange === 'function') {
if (typeof this.args.onchange === 'function') {
this.args.onchange(...arguments);
}
}
onerror(e) {
if(typeof this.args.onerror === 'function') {
if (typeof this.args.onerror === 'function') {
this.args.onerror(...arguments);
}
}

View File

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

View File

@ -10,9 +10,9 @@ export default Component.extend(Slotted, {
dom: service('dom'),
isConfirmation: false,
actions: {
connect: function($el) {
connect: function ($el) {
next(() => {
if(!this.isDestroyed) {
if (!this.isDestroyed) {
// 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
// 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 $trigger = this.dom.element(`[for='${id}']`);
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, {
tagName: '',
onclose: function() {},
onopen: function() {},
onclose: function () {},
onopen: function () {},
isOpen: false,
actions: {
connect: function($el) {
connect: function ($el) {
this.dialog = new A11yDialog($el);
this.dialog.on('hide', () => {
schedule('afterRender', _ => set(this, 'isOpen', false));
this.onclose({ target: $el })
schedule('afterRender', (_) => set(this, 'isOpen', false));
this.onclose({ target: $el });
});
this.dialog.on('show', () => {
set(this, 'isOpen', true)
this.onopen({ target: $el })
set(this, 'isOpen', true);
this.onopen({ target: $el });
});
if (this.open) {
this.actions.open.apply(this, []);
}
},
disconnect: function($el) {
disconnect: function ($el) {
this.dialog.destroy();
},
open: function() {
open: function () {
this.dialog.show();
},
close: function() {
close: function () {
this.dialog.hide();
},
},

View File

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

View File

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

View File

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

View File

@ -1,16 +1,15 @@
export default (submitable, cancelable, radiogroup, text) => (
scope = '[data-test-policy-form]'
) => {
return {
// this should probably be settable
resetScope: true,
scope: scope,
prefix: 'policy',
...submitable(),
...cancelable(),
...radiogroup('template', ['', 'service-identity', 'node-identity'], 'policy'),
rules: {
error: text('[data-test-rules] strong'),
},
export default (submitable, cancelable, radiogroup, text) =>
(scope = '[data-test-policy-form]') => {
return {
// this should probably be settable
resetScope: true,
scope: scope,
prefix: 'policy',
...submitable(),
...cancelable(),
...radiogroup('template', ['', 'service-identity', 'node-identity'], 'policy'),
rules: {
error: text('[data-test-rules] strong'),
},
};
};
};

View File

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

View File

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

View File

@ -1,20 +1,18 @@
export default (clickable, deletable, collection, alias, policyForm) => (
scope = '#policies',
createSelector = '[data-test-policy-create]'
) => {
return {
scope: scope,
create: clickable(createSelector),
form: policyForm('#new-policy'),
policies: alias('selectedOptions'),
selectedOptions: collection(
'[data-test-policies] [data-test-tabular-row]',
deletable(
{
expand: clickable('label'),
},
'+ tr'
)
),
export default (clickable, deletable, collection, alias, policyForm) =>
(scope = '#policies', createSelector = '[data-test-policy-create]') => {
return {
scope: scope,
create: clickable(createSelector),
form: policyForm('#new-policy'),
policies: alias('selectedOptions'),
selectedOptions: collection(
'[data-test-policies] [data-test-tabular-row]',
deletable(
{
expand: clickable('label'),
},
'+ tr'
)
),
};
};
};

View File

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

View File

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

View File

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

View File

@ -1,9 +1,10 @@
export default (clickable, collection) => (scope = '.popover-select') => {
return {
scope: scope,
selected: clickable('button'),
options: collection('li[role="none"]', {
button: clickable('button'),
}),
export default (clickable, collection) =>
(scope = '.popover-select') => {
return {
scope: scope,
selected: clickable('button'),
options: collection('li[role="none"]', {
button: clickable('button'),
}),
};
};
};

View File

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

View File

@ -6,19 +6,19 @@ export default Component.extend({
tagName: '',
keyboardAccess: false,
dom: service('dom'),
init: function() {
init: function () {
this._super(...arguments);
this.name = this.dom.guid(this);
},
actions: {
keydown: function(e) {
keydown: function (e) {
if (e.keyCode === ENTER) {
e.target.dispatchEvent(new MouseEvent('click'));
}
},
change: function(e) {
change: function (e) {
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';
// TODO: We no longer need to use name here
// remove the arg in all objects
export default function(name, items, blankKey = 'all') {
return items.reduce(function(prev, item, i, arr) {
export default function (name, items, blankKey = 'all') {
return items.reduce(function (prev, item, i, arr) {
// if item is empty then it means 'all'
// otherwise camelCase based on something-here = somethingHere for the key
const key =
item === ''
? blankKey
: item.split('-').reduce(function(prev, item, i, arr) {
: item.split('-').reduce(function (prev, item, i, arr) {
if (i === 0) {
return item;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,12 @@
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 ucfirst from 'consul-ui/utils/ucfirst';
export default function(name, items, blankKey = 'all') {
return items.reduce(function(prev, item, i, arr) {
export default function (name, items, blankKey = 'all') {
return items.reduce(function (prev, item, i, arr) {
// if item is empty then it means 'all'
// otherwise camelCase based on something-here = somethingHere for the key
const key =
item === ''
? blankKey
: item.split('-').reduce(function(prev, item, i, arr) {
: item.split('-').reduce(function (prev, item, i, arr) {
if (i === 0) {
return item;
}

View File

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

View File

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

View File

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

View File

@ -20,7 +20,7 @@ export default class TokenSource extends Component {
@action
change(e) {
e.data.toJSON = function() {
e.data.toJSON = function () {
return {
AccessorID: this.AccessorID,
// 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
if(typeof this.args.onchange === 'function') {
if (typeof this.args.onchange === 'function') {
this.args.onchange(e);
}
}
}

View File

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

View File

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

View File

@ -24,17 +24,17 @@ export default Component.extend({
data: null,
empty: false,
actions: {
redraw: function(evt) {
redraw: function (evt) {
this.drawGraphs();
},
change: function(evt) {
change: function (evt) {
this.set('data', evt.data.series);
this.drawGraphs();
this.rerender();
},
},
drawGraphs: function() {
drawGraphs: function () {
if (!this.data) {
set(this, 'empty', true);
return;
@ -56,7 +56,7 @@ export default Component.extend({
let series = maybeData.data || [];
let labels = maybeData.labels || {};
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) {
// 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);
}
let st = stack()
.keys(keys)
.order(stackOrderReverse);
let st = stack().keys(keys).order(stackOrderReverse);
let stackData = st(series);
@ -77,16 +75,16 @@ export default Component.extend({
// 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
// in array etc. so this is simpler.
let summed = series.map(d => {
let summed = series.map((d) => {
let sum = 0;
keys.forEach(l => {
keys.forEach((l) => {
sum = sum + d[l];
});
return sum;
});
let x = scaleTime()
.domain(extent(series, d => d.time))
.domain(extent(series, (d) => d.time))
.range([0, w]);
let y = scaleLinear()
@ -94,9 +92,9 @@ export default Component.extend({
.range([h, 0]);
let a = area()
.x(d => x(d.data.time))
.y1(d => y(d[0]))
.y0(d => y(d[1]));
.x((d) => x(d.data.time))
.y1((d) => y(d[0]))
.y0((d) => y(d[1]));
// Use the grey/red we prefer by default but have more colors available in
// case user adds extra series with a custom provider.
@ -136,11 +134,7 @@ export default Component.extend({
.attr('class', 'sparkline-tt-legend-color')
.style('background-color', color(k));
legend
.append('span')
.text(k)
.append('span')
.attr('class', 'sparkline-tt-legend-value');
legend.append('span').text(k).append('span').attr('class', 'sparkline-tt-legend-value');
}
let tipVals = tooltip.selectAll('.sparkline-tt-legend-value');
@ -158,7 +152,7 @@ export default Component.extend({
let self = this;
svg
.on('mouseover', function(e) {
.on('mouseover', function (e) {
tooltip.style('visibility', 'visible');
cursor.style('visibility', 'visible');
// 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).
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);
})
.on('mouseout', function(e) {
.on('mouseout', function (e) {
tooltip.style('visibility', 'hidden');
cursor.style('visibility', 'hidden');
});
},
willDestroyElement: function() {
willDestroyElement: function () {
this._super(...arguments);
if (typeof this.svg !== 'undefined') {
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);
cursor.attr('x', mouseX);
let mouseTime = x.invert(mouseX);
var bisectTime = bisector(function(d) {
var bisectTime = bisector(function (d) {
return d.time;
}).left;
let tipIdx = bisectTime(series, mouseTime);

View File

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

View File

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

View File

@ -46,13 +46,13 @@ export default class ApplicationController extends Controller {
return container
.lookup('route:application')
.refresh()
.promise.catch(function(e) {
.promise.catch(function (e) {
// passthrough
// 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
// to get to originally anyway
})
.then(res => {
.then((res) => {
// Use transitionable if we need to change a section of the URL
// or routeName and currentRouteName aren't equal (i.e. error page)
if (
@ -68,7 +68,7 @@ export default class ApplicationController extends Controller {
});
},
e.type,
function(type, e) {
function (type, e) {
return type;
},
{}

View File

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

View File

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

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