mirror of https://github.com/status-im/consul.git
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:
parent
057d28f90e
commit
03a1a86dfe
|
@ -1,169 +1,159 @@
|
||||||
<div
|
<div class="consul-nspace-form" ...attributes>
|
||||||
class="consul-nspace-form"
|
<DataWriter
|
||||||
...attributes
|
@sink={{uri
|
||||||
>
|
"/${partition}/${nspace}/${dc}/nspace"
|
||||||
<DataWriter
|
(hash partition="" nspace="" dc=@item.Datacenter)
|
||||||
@sink={{uri
|
}}
|
||||||
'/${partition}/${nspace}/${dc}/nspace'
|
@type={{"nspace"}}
|
||||||
(hash
|
@label={{"Namespace"}}
|
||||||
partition=''
|
@ondelete={{fn this.onDelete @item}}
|
||||||
nspace=''
|
@onchange={{fn this.onSubmit @item}}
|
||||||
dc=@item.Datacenter
|
as |writer|
|
||||||
)
|
>
|
||||||
}}
|
<BlockSlot @name="removed" as |after|>
|
||||||
@type={{'nspace'}}
|
<Consul::Nspace::Notifications
|
||||||
@label={{"Namespace"}}
|
{{notification after=(action after)}}
|
||||||
@ondelete={{fn (if @ondelete @ondelete @onsubmit) @item}}
|
@type="remove"
|
||||||
@onchange={{fn (optional @onsubmit) @item}}
|
/>
|
||||||
as |writer|>
|
</BlockSlot>
|
||||||
<BlockSlot @name="removed" as |after|>
|
|
||||||
<Consul::Nspace::Notifications
|
|
||||||
{{notification
|
|
||||||
after=(action after)
|
|
||||||
}}
|
|
||||||
@type="remove"
|
|
||||||
/>
|
|
||||||
</BlockSlot>
|
|
||||||
|
|
||||||
<BlockSlot @name="content">
|
<BlockSlot @name="content">
|
||||||
|
|
||||||
{{#let
|
{{#let
|
||||||
|
(not (can "write nspaces"))
|
||||||
(not (can "write nspaces"))
|
@item
|
||||||
|
(hash
|
||||||
@item
|
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
|
(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.'
|
test="^[a-zA-Z0-9]([a-zA-Z0-9-]{0,62}[a-zA-Z0-9])?$"
|
||||||
Name=(array
|
error="Name must be a valid DNS hostname."
|
||||||
(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|
|
||||||
)
|
|
||||||
|
|
||||||
(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
|
|
||||||
}}
|
}}
|
||||||
/>
|
<form {{on "submit" (fn writer.persist item)}} {{disabled readOnly}}>
|
||||||
{{/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
|
<StateChart
|
||||||
@type="reset"
|
@src={{state-chart "validate"}}
|
||||||
{{on 'click' (if @oncancel (fn @oncancel item) (fn @onsubmit item))}}
|
as |State Guard ChartAction dispatch state|
|
||||||
>
|
|
||||||
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>
|
<fieldset>
|
||||||
</StateChart>
|
{{#if (is "new nspace" item=item)}}
|
||||||
</form>
|
<TextInput
|
||||||
{{/let}}
|
@name="Name"
|
||||||
</BlockSlot>
|
@placeholder="Name"
|
||||||
</DataWriter>
|
@item={{item}}
|
||||||
</div>
|
@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>
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,16 +13,16 @@ const exists = fs.existsSync;
|
||||||
const chalk = require('chalk'); // comes with ember
|
const chalk = require('chalk'); // comes with ember
|
||||||
|
|
||||||
// allow extra docfy config
|
// allow extra docfy config
|
||||||
let user = {sources: [], labels: {}};
|
let user = { sources: [], labels: {} };
|
||||||
const $CONSUL_DOCFY_CONFIG = process.env.CONSUL_DOCFY_CONFIG || '';
|
const $CONSUL_DOCFY_CONFIG = process.env.CONSUL_DOCFY_CONFIG || '';
|
||||||
if($CONSUL_DOCFY_CONFIG.length > 0) {
|
if ($CONSUL_DOCFY_CONFIG.length > 0) {
|
||||||
try {
|
try {
|
||||||
if(exists($CONSUL_DOCFY_CONFIG)) {
|
if (exists($CONSUL_DOCFY_CONFIG)) {
|
||||||
user = JSON.parse(read($CONSUL_DOCFY_CONFIG));
|
user = JSON.parse(read($CONSUL_DOCFY_CONFIG));
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Unable to locate ${$CONSUL_DOCFY_CONFIG}`);
|
throw new Error(`Unable to locate ${$CONSUL_DOCFY_CONFIG}`);
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
console.error(chalk.yellow(`Docfy: ${e.message}`));
|
console.error(chalk.yellow(`Docfy: ${e.message}`));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,24 +33,20 @@ refractor.register(handlebars);
|
||||||
|
|
||||||
refractor.alias({
|
refractor.alias({
|
||||||
handlebars: ['hbs'],
|
handlebars: ['hbs'],
|
||||||
shell: ['sh']
|
shell: ['sh'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
remarkHbsOptions: {
|
remarkHbsOptions: {
|
||||||
escapeCurliesCode: false
|
escapeCurliesCode: false,
|
||||||
},
|
},
|
||||||
remarkPlugins: [
|
remarkPlugins: [
|
||||||
autolinkHeadings,
|
autolinkHeadings,
|
||||||
{
|
{
|
||||||
behavior: 'wrap'
|
behavior: 'wrap',
|
||||||
}
|
},
|
||||||
],
|
|
||||||
rehypePlugins: [
|
|
||||||
prism
|
|
||||||
],
|
],
|
||||||
|
rehypePlugins: [prism],
|
||||||
sources: [
|
sources: [
|
||||||
{
|
{
|
||||||
root: path.resolve(__dirname, 'docs'),
|
root: path.resolve(__dirname, 'docs'),
|
||||||
|
@ -129,10 +125,10 @@ module.exports = {
|
||||||
pattern: '**/README.mdx',
|
pattern: '**/README.mdx',
|
||||||
urlSchema: 'auto',
|
urlSchema: 'auto',
|
||||||
urlPrefix: 'docs/consul-nspaces',
|
urlPrefix: 'docs/consul-nspaces',
|
||||||
}
|
},
|
||||||
].concat(user.sources),
|
].concat(user.sources),
|
||||||
labels: {
|
labels: {
|
||||||
"consul": "Consul Components",
|
consul: 'Consul Components',
|
||||||
...user.labels
|
...user.labels,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,6 +15,7 @@ app/utils/dom/event-target/event-target-shim/event.js
|
||||||
# misc
|
# misc
|
||||||
/coverage/
|
/coverage/
|
||||||
!.*
|
!.*
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
# ember-try
|
# ember-try
|
||||||
/.node_modules.ember-try/
|
/.node_modules.ember-try/
|
||||||
|
|
|
@ -9,24 +9,44 @@ module.exports = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: ['ember'],
|
plugins: ['ember'],
|
||||||
extends: ['eslint:recommended', 'plugin:ember/recommended'],
|
extends: ['eslint:recommended', 'plugin:ember/recommended', 'plugin:prettier/recommended'],
|
||||||
env: {
|
env: {
|
||||||
browser: true,
|
browser: true,
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
'no-console': ['error', {allow: ['error', 'info']}],
|
'no-console': ['error', { allow: ['error', 'info'] }],
|
||||||
'no-unused-vars': ['error', { args: 'none' }],
|
'no-unused-vars': ['error', { args: 'none' }],
|
||||||
'ember/no-new-mixins': ['warn'],
|
'ember/no-new-mixins': ['warn'],
|
||||||
'ember/no-jquery': 'warn',
|
'ember/no-jquery': 'warn',
|
||||||
'ember/no-global-jquery': 'warn',
|
'ember/no-global-jquery': 'warn',
|
||||||
|
|
||||||
|
// for 3.24 update
|
||||||
|
'ember/classic-decorator-no-classic-methods': ['warn'],
|
||||||
|
'ember/classic-decorator-hooks': ['warn'],
|
||||||
|
'ember/no-classic-classes': ['warn'],
|
||||||
|
'ember/no-mixins': ['warn'],
|
||||||
|
'ember/no-computed-properties-in-native-classes': ['warn'],
|
||||||
|
'ember/no-private-routing-service': ['warn'],
|
||||||
|
'ember/no-test-import-export': ['warn'],
|
||||||
|
'ember/no-actions-hash': ['warn'],
|
||||||
|
'ember/no-classic-components': ['warn'],
|
||||||
|
'ember/no-component-lifecycle-hooks': ['warn'],
|
||||||
|
'ember/require-tagless-components': ['warn'],
|
||||||
|
'ember/no-legacy-test-waiters': ['warn'],
|
||||||
|
'ember/no-empty-glimmer-component-classes': ['warn'],
|
||||||
|
'ember/no-get': ['off'], // be careful with autofix, might change behavior
|
||||||
|
'ember/require-computed-property-dependencies': ['off'], // be careful with autofix
|
||||||
|
'ember/use-ember-data-rfc-395-imports': ['off'], // be carful with autofix
|
||||||
|
'ember/require-super-in-lifecycle-hooks': ['off'], // be careful with autofix
|
||||||
|
'ember/require-computed-macros': ['off'], // be careful with autofix
|
||||||
},
|
},
|
||||||
overrides: [
|
overrides: [
|
||||||
// node files
|
// node files
|
||||||
{
|
{
|
||||||
files: [
|
files: [
|
||||||
'.eslintrc.js',
|
'.eslintrc.js',
|
||||||
'.dev.eslintrc.js',
|
|
||||||
'.docfy-config.js',
|
'.docfy-config.js',
|
||||||
|
'.prettierrc.js',
|
||||||
'.template-lintrc.js',
|
'.template-lintrc.js',
|
||||||
'ember-cli-build.js',
|
'ember-cli-build.js',
|
||||||
'testem.js',
|
'testem.js',
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
singleQuote: true,
|
||||||
|
};
|
|
@ -54,7 +54,7 @@ export default class BaseAbility extends Ability {
|
||||||
|
|
||||||
get canRead() {
|
get canRead() {
|
||||||
if (typeof this.item !== 'undefined') {
|
if (typeof this.item !== 'undefined') {
|
||||||
const perm = (get(this, 'item.Resources') || []).find(item => item.Access === ACCESS_READ);
|
const perm = (get(this, 'item.Resources') || []).find((item) => item.Access === ACCESS_READ);
|
||||||
if (perm) {
|
if (perm) {
|
||||||
return perm.Allow;
|
return perm.Allow;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ export default class BaseAbility extends Ability {
|
||||||
|
|
||||||
get canList() {
|
get canList() {
|
||||||
if (typeof this.item !== 'undefined') {
|
if (typeof this.item !== 'undefined') {
|
||||||
const perm = (get(this, 'item.Resources') || []).find(item => item.Access === ACCESS_LIST);
|
const perm = (get(this, 'item.Resources') || []).find((item) => item.Access === ACCESS_LIST);
|
||||||
if (perm) {
|
if (perm) {
|
||||||
return perm.Allow;
|
return perm.Allow;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ export default class BaseAbility extends Ability {
|
||||||
|
|
||||||
get canWrite() {
|
get canWrite() {
|
||||||
if (typeof this.item !== 'undefined') {
|
if (typeof this.item !== 'undefined') {
|
||||||
const perm = (get(this, 'item.Resources') || []).find(item => item.Access === ACCESS_WRITE);
|
const perm = (get(this, 'item.Resources') || []).find((item) => item.Access === ACCESS_WRITE);
|
||||||
if (perm) {
|
if (perm) {
|
||||||
return perm.Allow;
|
return perm.Allow;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,12 @@ export default class IntentionAbility extends BaseAbility {
|
||||||
|
|
||||||
get canWrite() {
|
get canWrite() {
|
||||||
// Peered intentions aren't writable
|
// Peered intentions aren't writable
|
||||||
if(typeof this.item !== 'undefined' && typeof this.item.SourcePeer !== 'undefined') {
|
if (typeof this.item !== 'undefined' && typeof this.item.SourcePeer !== 'undefined') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return super.canWrite &&
|
return super.canWrite && (typeof this.item === 'undefined' || !this.canViewCRD);
|
||||||
(typeof this.item === 'undefined' || !this.canViewCRD);
|
|
||||||
}
|
}
|
||||||
get canViewCRD() {
|
get canViewCRD() {
|
||||||
return (typeof this.item !== 'undefined' && this.item.IsManagedByCRD);
|
return typeof this.item !== 'undefined' && this.item.IsManagedByCRD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,7 @@ export default class PeerAbility extends BaseAbility {
|
||||||
return this.canDelete;
|
return this.canDelete;
|
||||||
}
|
}
|
||||||
get canDelete() {
|
get canDelete() {
|
||||||
return ![
|
return !['DELETING', 'TERMINATED'].includes(this.item.State) && super.canDelete;
|
||||||
'DELETING',
|
|
||||||
'TERMINATED'
|
|
||||||
].includes(this.item.State) && super.canDelete;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get canUse() {
|
get canUse() {
|
||||||
|
|
|
@ -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 ask for service-instances its almost like a request for a single service
|
||||||
// When we do that we also want to know if we can read/write intentions for services
|
// When we do that we also want to know if we can read/write intentions for services
|
||||||
// so here we add intentions read/write for the specific segment/service prefix
|
// so here we add intentions read/write for the specific segment/service prefix
|
||||||
return super.generateForSegment(...arguments).concat([
|
return super
|
||||||
this.permissions.generate('intention', ACCESS_READ, segment),
|
.generateForSegment(...arguments)
|
||||||
this.permissions.generate('intention', ACCESS_WRITE, segment),
|
.concat([
|
||||||
]);
|
this.permissions.generate('intention', ACCESS_READ, segment),
|
||||||
|
this.permissions.generate('intention', ACCESS_WRITE, segment),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ export default class ZerviceAbility extends BaseAbility {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const found = this.item.Resources.find(
|
const found = this.item.Resources.find(
|
||||||
item => item.Resource === 'intention' && item.Access === 'read' && item.Allow === true
|
(item) => item.Resource === 'intention' && item.Access === 'read' && item.Allow === true
|
||||||
);
|
);
|
||||||
return typeof found !== 'undefined';
|
return typeof found !== 'undefined';
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ export default class ZerviceAbility extends BaseAbility {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const found = this.item.Resources.find(
|
const found = this.item.Resources.find(
|
||||||
item => item.Resource === 'intention' && item.Access === 'write' && item.Allow === true
|
(item) => item.Resource === 'intention' && item.Access === 'write' && item.Allow === true
|
||||||
);
|
);
|
||||||
return typeof found !== 'undefined';
|
return typeof found !== 'undefined';
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,24 +15,24 @@ import AdapterError, {
|
||||||
// `serialized, unserialized` and the other just `query`
|
// `serialized, unserialized` and the other just `query`
|
||||||
// they could actually be one function now, but would be nice to think about
|
// they could actually be one function now, but would be nice to think about
|
||||||
// the naming of things (serialized vs query etc)
|
// the naming of things (serialized vs query etc)
|
||||||
const read = function(adapter, modelName, type, query = {}) {
|
const read = function (adapter, modelName, type, query = {}) {
|
||||||
return adapter.rpc(
|
return adapter.rpc(
|
||||||
function(adapter, ...rest) {
|
function (adapter, ...rest) {
|
||||||
return adapter[`requestFor${type}`](...rest);
|
return adapter[`requestFor${type}`](...rest);
|
||||||
},
|
},
|
||||||
function(serializer, ...rest) {
|
function (serializer, ...rest) {
|
||||||
return serializer[`respondFor${type}`](...rest);
|
return serializer[`respondFor${type}`](...rest);
|
||||||
},
|
},
|
||||||
query,
|
query,
|
||||||
modelName
|
modelName
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const write = function(adapter, modelName, type, snapshot) {
|
const write = function (adapter, modelName, type, snapshot) {
|
||||||
return adapter.rpc(
|
return adapter.rpc(
|
||||||
function(adapter, ...rest) {
|
function (adapter, ...rest) {
|
||||||
return adapter[`requestFor${type}`](...rest);
|
return adapter[`requestFor${type}`](...rest);
|
||||||
},
|
},
|
||||||
function(serializer, ...rest) {
|
function (serializer, ...rest) {
|
||||||
return serializer[`respondFor${type}`](...rest);
|
return serializer[`respondFor${type}`](...rest);
|
||||||
},
|
},
|
||||||
snapshot,
|
snapshot,
|
||||||
|
@ -66,13 +66,13 @@ export default class HttpAdapter extends Adapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
return client
|
return client
|
||||||
.request(function(request) {
|
.request(function (request) {
|
||||||
return req(adapter, request, serialized, unserialized, modelClass);
|
return req(adapter, request, serialized, unserialized, modelClass);
|
||||||
})
|
})
|
||||||
.catch(function(e) {
|
.catch(function (e) {
|
||||||
return adapter.error(e);
|
return adapter.error(e);
|
||||||
})
|
})
|
||||||
.then(function(respond) {
|
.then(function (respond) {
|
||||||
// TODO: When HTTPAdapter:responder changes, this will also need to change
|
// TODO: When HTTPAdapter:responder changes, this will also need to change
|
||||||
return resp(serializer, respond, serialized, unserialized, modelClass);
|
return resp(serializer, respond, serialized, unserialized, modelClass);
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,10 +58,10 @@ export default class NodeAdapter extends Adapter {
|
||||||
|
|
||||||
queryLeader(store, type, id, snapshot) {
|
queryLeader(store, type, id, snapshot) {
|
||||||
return this.rpc(
|
return this.rpc(
|
||||||
function(adapter, request, serialized, unserialized) {
|
function (adapter, request, serialized, unserialized) {
|
||||||
return adapter.requestForQueryLeader(request, serialized, unserialized);
|
return adapter.requestForQueryLeader(request, serialized, unserialized);
|
||||||
},
|
},
|
||||||
function(serializer, respond, serialized, unserialized) {
|
function (serializer, respond, serialized, unserialized) {
|
||||||
return serializer.respondForQueryLeader(respond, serialized, unserialized);
|
return serializer.respondForQueryLeader(respond, serialized, unserialized);
|
||||||
},
|
},
|
||||||
snapshot,
|
snapshot,
|
||||||
|
|
|
@ -40,8 +40,8 @@ export default class NspaceAdapter extends Adapter {
|
||||||
Name: serialized.Name,
|
Name: serialized.Name,
|
||||||
Description: serialized.Description,
|
Description: serialized.Description,
|
||||||
ACLs: {
|
ACLs: {
|
||||||
PolicyDefaults: serialized.ACLs.PolicyDefaults.map(item => ({ ID: item.ID })),
|
PolicyDefaults: serialized.ACLs.PolicyDefaults.map((item) => ({ ID: item.ID })),
|
||||||
RoleDefaults: serialized.ACLs.RoleDefaults.map(item => ({ ID: item.ID })),
|
RoleDefaults: serialized.ACLs.RoleDefaults.map((item) => ({ ID: item.ID })),
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
`;
|
`;
|
||||||
|
@ -57,8 +57,8 @@ export default class NspaceAdapter extends Adapter {
|
||||||
${{
|
${{
|
||||||
Description: serialized.Description,
|
Description: serialized.Description,
|
||||||
ACLs: {
|
ACLs: {
|
||||||
PolicyDefaults: serialized.ACLs.PolicyDefaults.map(item => ({ ID: item.ID })),
|
PolicyDefaults: serialized.ACLs.PolicyDefaults.map((item) => ({ ID: item.ID })),
|
||||||
RoleDefaults: serialized.ACLs.RoleDefaults.map(item => ({ ID: item.ID })),
|
RoleDefaults: serialized.ACLs.RoleDefaults.map((item) => ({ ID: item.ID })),
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -67,10 +67,10 @@ export default class OidcProviderAdapter extends Adapter {
|
||||||
|
|
||||||
authorize(store, type, id, snapshot) {
|
authorize(store, type, id, snapshot) {
|
||||||
return this.rpc(
|
return this.rpc(
|
||||||
function(adapter, request, serialized, unserialized) {
|
function (adapter, request, serialized, unserialized) {
|
||||||
return adapter.requestForAuthorize(request, serialized, unserialized);
|
return adapter.requestForAuthorize(request, serialized, unserialized);
|
||||||
},
|
},
|
||||||
function(serializer, respond, serialized, unserialized) {
|
function (serializer, respond, serialized, unserialized) {
|
||||||
return serializer.respondForAuthorize(respond, serialized, unserialized);
|
return serializer.respondForAuthorize(respond, serialized, unserialized);
|
||||||
},
|
},
|
||||||
snapshot,
|
snapshot,
|
||||||
|
@ -80,10 +80,10 @@ export default class OidcProviderAdapter extends Adapter {
|
||||||
|
|
||||||
logout(store, type, id, snapshot) {
|
logout(store, type, id, snapshot) {
|
||||||
return this.rpc(
|
return this.rpc(
|
||||||
function(adapter, request, serialized, unserialized) {
|
function (adapter, request, serialized, unserialized) {
|
||||||
return adapter.requestForLogout(request, serialized, unserialized);
|
return adapter.requestForLogout(request, serialized, unserialized);
|
||||||
},
|
},
|
||||||
function(serializer, respond, serialized, unserialized) {
|
function (serializer, respond, serialized, unserialized) {
|
||||||
// its ok to return nothing here for the moment at least
|
// its ok to return nothing here for the moment at least
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,10 +16,10 @@ export default class PermissionAdapter extends Adapter {
|
||||||
// ^ same goes for Partitions
|
// ^ same goes for Partitions
|
||||||
|
|
||||||
if (this.env.var('CONSUL_NSPACES_ENABLED')) {
|
if (this.env.var('CONSUL_NSPACES_ENABLED')) {
|
||||||
resources = resources.map(item => ({ ...item, Namespace: ns }));
|
resources = resources.map((item) => ({ ...item, Namespace: ns }));
|
||||||
}
|
}
|
||||||
if (this.env.var('CONSUL_PARTITIONS_ENABLED')) {
|
if (this.env.var('CONSUL_PARTITIONS_ENABLED')) {
|
||||||
resources = resources.map(item => ({ ...item, Partition: partition }));
|
resources = resources.map((item) => ({ ...item, Partition: partition }));
|
||||||
}
|
}
|
||||||
return request`
|
return request`
|
||||||
POST /v1/internal/acl/authorize?${{ dc }}
|
POST /v1/internal/acl/authorize?${{ dc }}
|
||||||
|
@ -40,24 +40,24 @@ export default class PermissionAdapter extends Adapter {
|
||||||
// Same goes ^ for partitions
|
// Same goes ^ for partitions
|
||||||
const nspacesEnabled = this.env.var('CONSUL_NSPACES_ENABLED');
|
const nspacesEnabled = this.env.var('CONSUL_NSPACES_ENABLED');
|
||||||
const partitionsEnabled = this.env.var('CONSUL_PARTITIONS_ENABLED');
|
const partitionsEnabled = this.env.var('CONSUL_PARTITIONS_ENABLED');
|
||||||
if(nspacesEnabled || partitionsEnabled) {
|
if (nspacesEnabled || partitionsEnabled) {
|
||||||
const token = await this.settings.findBySlug('token');
|
const token = await this.settings.findBySlug('token');
|
||||||
if(nspacesEnabled) {
|
if (nspacesEnabled) {
|
||||||
if(typeof serialized.ns === 'undefined' || serialized.ns.length === 0) {
|
if (typeof serialized.ns === 'undefined' || serialized.ns.length === 0) {
|
||||||
serialized.ns = token.Namespace;
|
serialized.ns = token.Namespace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(partitionsEnabled) {
|
if (partitionsEnabled) {
|
||||||
if(typeof serialized.partition === 'undefined' || serialized.partition.length === 0) {
|
if (typeof serialized.partition === 'undefined' || serialized.partition.length === 0) {
|
||||||
serialized.partition = token.Partition;
|
serialized.partition = token.Partition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return adapter.requestForAuthorize(request, serialized);
|
return adapter.requestForAuthorize(request, serialized);
|
||||||
},
|
},
|
||||||
function(serializer, respond, serialized, unserialized) {
|
function (serializer, respond, serialized, unserialized) {
|
||||||
// Completely skip the serializer here
|
// Completely skip the serializer here
|
||||||
return respond(function(headers, body) {
|
return respond(function (headers, body) {
|
||||||
return body;
|
return body;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -134,10 +134,10 @@ export default class TokenAdapter extends Adapter {
|
||||||
// services/store.js
|
// services/store.js
|
||||||
self(store, type, id, unserialized) {
|
self(store, type, id, unserialized) {
|
||||||
return this.rpc(
|
return this.rpc(
|
||||||
function(adapter, request, serialized, data) {
|
function (adapter, request, serialized, data) {
|
||||||
return adapter.requestForSelf(request, serialized, data);
|
return adapter.requestForSelf(request, serialized, data);
|
||||||
},
|
},
|
||||||
function(serializer, respond, serialized, data) {
|
function (serializer, respond, serialized, data) {
|
||||||
return serializer.respondForSelf(respond, serialized, data);
|
return serializer.respondForSelf(respond, serialized, data);
|
||||||
},
|
},
|
||||||
unserialized,
|
unserialized,
|
||||||
|
@ -147,7 +147,7 @@ export default class TokenAdapter extends Adapter {
|
||||||
|
|
||||||
clone(store, type, id, snapshot) {
|
clone(store, type, id, snapshot) {
|
||||||
return this.rpc(
|
return this.rpc(
|
||||||
function(adapter, request, serialized, data) {
|
function (adapter, request, serialized, data) {
|
||||||
return adapter.requestForCloneRecord(request, serialized, data);
|
return adapter.requestForCloneRecord(request, serialized, data);
|
||||||
},
|
},
|
||||||
(serializer, respond, serialized, data) => {
|
(serializer, respond, serialized, data) => {
|
||||||
|
|
|
@ -14,20 +14,20 @@ const ARROW_DOWN = 40;
|
||||||
|
|
||||||
const keys = {
|
const keys = {
|
||||||
vertical: {
|
vertical: {
|
||||||
[ARROW_DOWN]: function($items, i = -1) {
|
[ARROW_DOWN]: function ($items, i = -1) {
|
||||||
return (i + 1) % $items.length;
|
return (i + 1) % $items.length;
|
||||||
},
|
},
|
||||||
[ARROW_UP]: function($items, i = 0) {
|
[ARROW_UP]: function ($items, i = 0) {
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
return $items.length - 1;
|
return $items.length - 1;
|
||||||
} else {
|
} else {
|
||||||
return i - 1;
|
return i - 1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[HOME]: function($items, i) {
|
[HOME]: function ($items, i) {
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
[END]: function($items, i) {
|
[END]: function ($items, i) {
|
||||||
return $items.length - 1;
|
return $items.length - 1;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -43,29 +43,29 @@ export default Component.extend({
|
||||||
expanded: false,
|
expanded: false,
|
||||||
orientation: 'vertical',
|
orientation: 'vertical',
|
||||||
keyboardAccess: true,
|
keyboardAccess: true,
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
set(this, 'guid', this.dom.guid(this));
|
set(this, 'guid', this.dom.guid(this));
|
||||||
this._listeners = this.dom.listeners();
|
this._listeners = this.dom.listeners();
|
||||||
this._routelisteners = this.dom.listeners();
|
this._routelisteners = this.dom.listeners();
|
||||||
},
|
},
|
||||||
didInsertElement: function() {
|
didInsertElement: function () {
|
||||||
// TODO: How do you detect whether the children have changed?
|
// TODO: How do you detect whether the children have changed?
|
||||||
// For now we know that these elements exist and never change
|
// For now we know that these elements exist and never change
|
||||||
this.$menu = this.dom.element(`#${COMPONENT_ID}menu-${this.guid}`);
|
this.$menu = this.dom.element(`#${COMPONENT_ID}menu-${this.guid}`);
|
||||||
const labelledBy = this.$menu.getAttribute('aria-labelledby');
|
const labelledBy = this.$menu.getAttribute('aria-labelledby');
|
||||||
this.$trigger = this.dom.element(`#${labelledBy}`);
|
this.$trigger = this.dom.element(`#${labelledBy}`);
|
||||||
},
|
},
|
||||||
willDestroyElement: function() {
|
willDestroyElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this._listeners.remove();
|
this._listeners.remove();
|
||||||
this._routelisteners.remove();
|
this._routelisteners.remove();
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
keypressClick: function(e) {
|
keypressClick: function (e) {
|
||||||
e.target.dispatchEvent(new MouseEvent('click'));
|
e.target.dispatchEvent(new MouseEvent('click'));
|
||||||
},
|
},
|
||||||
keypress: function(e) {
|
keypress: function (e) {
|
||||||
// If the event is from the trigger and its not an opening/closing
|
// If the event is from the trigger and its not an opening/closing
|
||||||
// key then don't do anything
|
// key then don't do anything
|
||||||
if (![ENTER, SPACE, ARROW_UP, ARROW_DOWN].includes(e.keyCode)) {
|
if (![ENTER, SPACE, ARROW_UP, ARROW_DOWN].includes(e.keyCode)) {
|
||||||
|
@ -99,7 +99,7 @@ export default Component.extend({
|
||||||
const $focused = this.dom.element(`${MENU_ITEMS}:focus`, this.$menu);
|
const $focused = this.dom.element(`${MENU_ITEMS}:focus`, this.$menu);
|
||||||
let i;
|
let i;
|
||||||
if ($focused) {
|
if ($focused) {
|
||||||
i = $items.findIndex(function($item) {
|
i = $items.findIndex(function ($item) {
|
||||||
return $item === $focused;
|
return $item === $focused;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ export default Component.extend({
|
||||||
},
|
},
|
||||||
// TODO: The argument here needs to change to an event
|
// TODO: The argument here needs to change to an event
|
||||||
// see toggle-button.change
|
// see toggle-button.change
|
||||||
change: function(e) {
|
change: function (e) {
|
||||||
const open = e.target.checked;
|
const open = e.target.checked;
|
||||||
if (open) {
|
if (open) {
|
||||||
this.actions.open.apply(this, [e]);
|
this.actions.open.apply(this, [e]);
|
||||||
|
@ -116,7 +116,7 @@ export default Component.extend({
|
||||||
this.actions.close.apply(this, [e]);
|
this.actions.close.apply(this, [e]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
close: function(e) {
|
close: function (e) {
|
||||||
this._listeners.remove();
|
this._listeners.remove();
|
||||||
set(this, 'expanded', false);
|
set(this, 'expanded', false);
|
||||||
// TODO: Find a better way to do this without using next
|
// TODO: Find a better way to do this without using next
|
||||||
|
@ -127,7 +127,7 @@ export default Component.extend({
|
||||||
this.$trigger.removeAttribute('tabindex');
|
this.$trigger.removeAttribute('tabindex');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
open: function(e) {
|
open: function (e) {
|
||||||
set(this, 'expanded', true);
|
set(this, 'expanded', true);
|
||||||
const $items = [...this.dom.elements(MENU_ITEMS, this.$menu)];
|
const $items = [...this.dom.elements(MENU_ITEMS, this.$menu)];
|
||||||
if ($items.length === 0) {
|
if ($items.length === 0) {
|
||||||
|
@ -138,7 +138,7 @@ export default Component.extend({
|
||||||
// Take the trigger out of the tabbing whilst the menu is open
|
// Take the trigger out of the tabbing whilst the menu is open
|
||||||
this.$trigger.setAttribute('tabindex', '-1');
|
this.$trigger.setAttribute('tabindex', '-1');
|
||||||
this._listeners.add(this.dom.document(), {
|
this._listeners.add(this.dom.document(), {
|
||||||
keydown: e => {
|
keydown: (e) => {
|
||||||
// Keep focus on the trigger when you close via ESC
|
// Keep focus on the trigger when you close via ESC
|
||||||
if (e.keyCode === ESC) {
|
if (e.keyCode === ESC) {
|
||||||
this.$trigger.focus();
|
this.$trigger.focus();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
export default (submitable, clickable, attribute) => (scope = '.auth-form') => {
|
export default (submitable, clickable, attribute) =>
|
||||||
return {
|
(scope = '.auth-form') => {
|
||||||
scope: scope,
|
return {
|
||||||
...submitable(),
|
scope: scope,
|
||||||
|
...submitable(),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
|
@ -8,10 +8,10 @@ import { task } from 'ember-concurrency';
|
||||||
import Slotted from 'block-slots';
|
import Slotted from 'block-slots';
|
||||||
|
|
||||||
export default Component.extend(Slotted, {
|
export default Component.extend(Slotted, {
|
||||||
onchange: function() {},
|
onchange: function () {},
|
||||||
tagName: '',
|
tagName: '',
|
||||||
|
|
||||||
error: function() {},
|
error: function () {},
|
||||||
type: '',
|
type: '',
|
||||||
|
|
||||||
dom: service('dom'),
|
dom: service('dom'),
|
||||||
|
@ -21,17 +21,17 @@ export default Component.extend(Slotted, {
|
||||||
|
|
||||||
selectedOptions: alias('items'),
|
selectedOptions: alias('items'),
|
||||||
|
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this._listeners = this.dom.listeners();
|
this._listeners = this.dom.listeners();
|
||||||
this.form = this.formContainer.form(this.type);
|
set(this, 'form', this.formContainer.form(this.type));
|
||||||
this.form.clear({ Datacenter: this.dc, Namespace: this.nspace });
|
this.form.clear({ Datacenter: this.dc, Namespace: this.nspace });
|
||||||
},
|
},
|
||||||
willDestroyElement: function() {
|
willDestroyElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this._listeners.remove();
|
this._listeners.remove();
|
||||||
},
|
},
|
||||||
options: computed('selectedOptions.[]', 'allOptions.[]', function() {
|
options: computed('selectedOptions.[]', 'allOptions.[]', function () {
|
||||||
// It's not massively important here that we are defaulting `items` and
|
// It's not massively important here that we are defaulting `items` and
|
||||||
// losing reference as its just to figure out the diff
|
// losing reference as its just to figure out the diff
|
||||||
let options = this.allOptions || [];
|
let options = this.allOptions || [];
|
||||||
|
@ -40,11 +40,11 @@ export default Component.extend(Slotted, {
|
||||||
// filter out any items from the available options that have already been
|
// filter out any items from the available options that have already been
|
||||||
// selected/added
|
// selected/added
|
||||||
// TODO: find a proper ember-data diff
|
// TODO: find a proper ember-data diff
|
||||||
options = options.filter(item => !items.findBy('ID', get(item, 'ID')));
|
options = options.filter((item) => !items.findBy('ID', get(item, 'ID')));
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}),
|
}),
|
||||||
save: task(function*(item, items, success = function() {}) {
|
save: task(function* (item, items, success = function () {}) {
|
||||||
const repo = this.repo;
|
const repo = this.repo;
|
||||||
try {
|
try {
|
||||||
item = yield repo.persist(item);
|
item = yield repo.persist(item);
|
||||||
|
@ -64,14 +64,14 @@ export default Component.extend(Slotted, {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
reset: function() {
|
reset: function () {
|
||||||
this.form.clear({ Datacenter: this.dc, Namespace: this.nspace, Partition: this.partition });
|
this.form.clear({ Datacenter: this.dc, Namespace: this.nspace, Partition: this.partition });
|
||||||
},
|
},
|
||||||
|
|
||||||
remove: function(item, items) {
|
remove: function (item, items) {
|
||||||
const prop = this.repo.getSlugKey();
|
const prop = this.repo.getSlugKey();
|
||||||
const value = get(item, prop);
|
const value = get(item, prop);
|
||||||
const pos = items.findIndex(function(item) {
|
const pos = items.findIndex(function (item) {
|
||||||
return get(item, prop) === value;
|
return get(item, prop) === value;
|
||||||
});
|
});
|
||||||
if (pos !== -1) {
|
if (pos !== -1) {
|
||||||
|
@ -79,7 +79,7 @@ export default Component.extend(Slotted, {
|
||||||
}
|
}
|
||||||
this.onchange({ target: this });
|
this.onchange({ target: this });
|
||||||
},
|
},
|
||||||
change: function(e, value, item) {
|
change: function (e, value, item) {
|
||||||
const event = this.dom.normalizeEvent(...arguments);
|
const event = this.dom.normalizeEvent(...arguments);
|
||||||
const items = value;
|
const items = value;
|
||||||
switch (event.target.name) {
|
switch (event.target.name) {
|
||||||
|
|
|
@ -17,20 +17,20 @@ export default Component.extend({
|
||||||
readonly: false,
|
readonly: false,
|
||||||
syntax: '',
|
syntax: '',
|
||||||
// TODO: Change this to oninput to be consistent? We'll have to do it throughout the templates
|
// TODO: Change this to oninput to be consistent? We'll have to do it throughout the templates
|
||||||
onkeyup: function() {},
|
onkeyup: function () {},
|
||||||
oninput: function() {},
|
oninput: function () {},
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
set(this, 'modes', this.helper.modes());
|
set(this, 'modes', this.helper.modes());
|
||||||
},
|
},
|
||||||
didReceiveAttrs: function() {
|
didReceiveAttrs: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
const editor = this.editor;
|
const editor = this.editor;
|
||||||
if (editor) {
|
if (editor) {
|
||||||
editor.setOption('readOnly', this.readonly);
|
editor.setOption('readOnly', this.readonly);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setMode: function(mode) {
|
setMode: function (mode) {
|
||||||
let options = {
|
let options = {
|
||||||
...DEFAULTS,
|
...DEFAULTS,
|
||||||
mode: mode.mime,
|
mode: mode.mime,
|
||||||
|
@ -48,13 +48,13 @@ export default Component.extend({
|
||||||
this.helper.lint(editor, mode.mode);
|
this.helper.lint(editor, mode.mode);
|
||||||
set(this, 'mode', mode);
|
set(this, 'mode', mode);
|
||||||
},
|
},
|
||||||
willDestroyElement: function() {
|
willDestroyElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
if (this.observer) {
|
if (this.observer) {
|
||||||
this.observer.disconnect();
|
this.observer.disconnect();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
didInsertElement: function() {
|
didInsertElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
const $code = this.dom.element('textarea ~ pre code', this.element);
|
const $code = this.dom.element('textarea ~ pre code', this.element);
|
||||||
if ($code.firstChild) {
|
if ($code.firstChild) {
|
||||||
|
@ -70,11 +70,11 @@ export default Component.extend({
|
||||||
set(this, 'value', $code.firstChild.wholeText);
|
set(this, 'value', $code.firstChild.wholeText);
|
||||||
}
|
}
|
||||||
set(this, 'editor', this.helper.getEditor(this.element));
|
set(this, 'editor', this.helper.getEditor(this.element));
|
||||||
this.settings.findBySlug('code-editor').then(mode => {
|
this.settings.findBySlug('code-editor').then((mode) => {
|
||||||
const modes = this.modes;
|
const modes = this.modes;
|
||||||
const syntax = this.syntax;
|
const syntax = this.syntax;
|
||||||
if (syntax) {
|
if (syntax) {
|
||||||
mode = modes.find(function(item) {
|
mode = modes.find(function (item) {
|
||||||
return item.name.toLowerCase() == syntax.toLowerCase();
|
return item.name.toLowerCase() == syntax.toLowerCase();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -82,11 +82,11 @@ export default Component.extend({
|
||||||
this.setMode(mode);
|
this.setMode(mode);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
didAppear: function() {
|
didAppear: function () {
|
||||||
this.editor.refresh();
|
this.editor.refresh();
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
change: function(value) {
|
change: function (value) {
|
||||||
this.settings.persist({
|
this.settings.persist({
|
||||||
'code-editor': value,
|
'code-editor': value,
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,14 +10,14 @@ export default Component.extend(Slotted, {
|
||||||
confirming: false,
|
confirming: false,
|
||||||
permanent: false,
|
permanent: false,
|
||||||
actions: {
|
actions: {
|
||||||
cancel: function() {
|
cancel: function () {
|
||||||
set(this, 'confirming', false);
|
set(this, 'confirming', false);
|
||||||
},
|
},
|
||||||
execute: function() {
|
execute: function () {
|
||||||
set(this, 'confirming', false);
|
set(this, 'confirming', false);
|
||||||
this.sendAction(...['actionName', ...this['arguments']]);
|
this.sendAction(...['actionName', ...this['arguments']]);
|
||||||
},
|
},
|
||||||
confirm: function() {
|
confirm: function () {
|
||||||
const [action, ...args] = arguments;
|
const [action, ...args] = arguments;
|
||||||
set(this, 'actionName', action);
|
set(this, 'actionName', action);
|
||||||
set(this, 'arguments', args);
|
set(this, 'arguments', args);
|
||||||
|
|
|
@ -11,13 +11,13 @@ export default Component.extend({
|
||||||
classNames: ['discovery-chain'],
|
classNames: ['discovery-chain'],
|
||||||
classNameBindings: ['active'],
|
classNameBindings: ['active'],
|
||||||
selectedId: '',
|
selectedId: '',
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this._listeners = this.dom.listeners();
|
this._listeners = this.dom.listeners();
|
||||||
},
|
},
|
||||||
didInsertElement: function() {
|
didInsertElement: function () {
|
||||||
this._listeners.add(this.dom.document(), {
|
this._listeners.add(this.dom.document(), {
|
||||||
click: e => {
|
click: (e) => {
|
||||||
// all route/splitter/resolver components currently
|
// all route/splitter/resolver components currently
|
||||||
// have classes that end in '-card'
|
// have classes that end in '-card'
|
||||||
if (!this.dom.closest('[class$="-card"]', e.target)) {
|
if (!this.dom.closest('[class$="-card"]', e.target)) {
|
||||||
|
@ -27,21 +27,21 @@ export default Component.extend({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
willDestroyElement: function() {
|
willDestroyElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this._listeners.remove();
|
this._listeners.remove();
|
||||||
this.ticker.destroy(this);
|
this.ticker.destroy(this);
|
||||||
},
|
},
|
||||||
splitters: computed('chain.Nodes', function() {
|
splitters: computed('chain.Nodes', function () {
|
||||||
return getSplitters(get(this, 'chain.Nodes'));
|
return getSplitters(get(this, 'chain.Nodes'));
|
||||||
}),
|
}),
|
||||||
routes: computed('chain.Nodes', function() {
|
routes: computed('chain.Nodes', function () {
|
||||||
const routes = getRoutes(get(this, 'chain.Nodes'), this.dom.guid);
|
const routes = getRoutes(get(this, 'chain.Nodes'), this.dom.guid);
|
||||||
// if we have no routes with a PathPrefix of '/' or one with no definition at all
|
// if we have no routes with a PathPrefix of '/' or one with no definition at all
|
||||||
// then add our own 'default catch all'
|
// then add our own 'default catch all'
|
||||||
if (
|
if (
|
||||||
!routes.find(item => get(item, 'Definition.Match.HTTP.PathPrefix') === '/') &&
|
!routes.find((item) => get(item, 'Definition.Match.HTTP.PathPrefix') === '/') &&
|
||||||
!routes.find(item => typeof item.Definition === 'undefined')
|
!routes.find((item) => typeof item.Definition === 'undefined')
|
||||||
) {
|
) {
|
||||||
let nextNode;
|
let nextNode;
|
||||||
const resolverID = `resolver:${this.chain.ServiceName}.${this.chain.Namespace}.${this.chain.Partition}.${this.chain.Datacenter}`;
|
const resolverID = `resolver:${this.chain.ServiceName}.${this.chain.Namespace}.${this.chain.Partition}.${this.chain.Datacenter}`;
|
||||||
|
@ -72,7 +72,7 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
return routes;
|
return routes;
|
||||||
}),
|
}),
|
||||||
nodes: computed('routes', 'splitters', 'resolvers', function() {
|
nodes: computed('routes', 'splitters', 'resolvers', function () {
|
||||||
let nodes = this.resolvers.reduce((prev, item) => {
|
let nodes = this.resolvers.reduce((prev, item) => {
|
||||||
prev[`resolver:${item.ID}`] = item;
|
prev[`resolver:${item.ID}`] = item;
|
||||||
item.Children.reduce((prev, item) => {
|
item.Children.reduce((prev, item) => {
|
||||||
|
@ -94,7 +94,7 @@ export default Component.extend({
|
||||||
value.NextItem = nodes[value.NextNode];
|
value.NextItem = nodes[value.NextNode];
|
||||||
}
|
}
|
||||||
if (typeof value.Splits !== 'undefined') {
|
if (typeof value.Splits !== 'undefined') {
|
||||||
value.Splits.forEach(item => {
|
value.Splits.forEach((item) => {
|
||||||
if (typeof item.NextNode !== 'undefined') {
|
if (typeof item.NextNode !== 'undefined') {
|
||||||
item.NextItem = nodes[item.NextNode];
|
item.NextItem = nodes[item.NextNode];
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ export default Component.extend({
|
||||||
});
|
});
|
||||||
return '';
|
return '';
|
||||||
}),
|
}),
|
||||||
resolvers: computed('chain.{Nodes,Targets}', function() {
|
resolvers: computed('chain.{Nodes,Targets}', function () {
|
||||||
return getResolvers(
|
return getResolvers(
|
||||||
this.chain.Datacenter,
|
this.chain.Datacenter,
|
||||||
this.chain.Partition,
|
this.chain.Partition,
|
||||||
|
@ -112,10 +112,10 @@ export default Component.extend({
|
||||||
get(this, 'chain.Nodes')
|
get(this, 'chain.Nodes')
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
graph: computed('splitters', 'routes.[]', function() {
|
graph: computed('splitters', 'routes.[]', function () {
|
||||||
const graph = this.dataStructs.graph();
|
const graph = this.dataStructs.graph();
|
||||||
this.splitters.forEach(item => {
|
this.splitters.forEach((item) => {
|
||||||
item.Splits.forEach(splitter => {
|
item.Splits.forEach((splitter) => {
|
||||||
graph.addLink(item.ID, splitter.NextNode);
|
graph.addLink(item.ID, splitter.NextNode);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -124,7 +124,7 @@ export default Component.extend({
|
||||||
});
|
});
|
||||||
return graph;
|
return graph;
|
||||||
}),
|
}),
|
||||||
selected: computed('selectedId', 'graph', function() {
|
selected: computed('selectedId', 'graph', function () {
|
||||||
if (this.selectedId === '' || !this.dom.element(`#${this.selectedId}`)) {
|
if (this.selectedId === '' || !this.dom.element(`#${this.selectedId}`)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -144,12 +144,12 @@ export default Component.extend({
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
nodes: nodes.map(item => `#${CSS.escape(item)}`),
|
nodes: nodes.map((item) => `#${CSS.escape(item)}`),
|
||||||
edges: edges.map(item => `#${CSS.escape(item)}`),
|
edges: edges.map((item) => `#${CSS.escape(item)}`),
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
click: function(e) {
|
click: function (e) {
|
||||||
const id = e.currentTarget.getAttribute('id');
|
const id = e.currentTarget.getAttribute('id');
|
||||||
if (id === this.selectedId) {
|
if (id === this.selectedId) {
|
||||||
set(this, 'active', false);
|
set(this, 'active', false);
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { get } from '@ember/object';
|
||||||
export default class RouteCard extends Component {
|
export default class RouteCard extends Component {
|
||||||
get path() {
|
get path() {
|
||||||
return Object.entries(get(this.args.item, 'Definition.Match.HTTP') || {}).reduce(
|
return Object.entries(get(this.args.item, 'Definition.Match.HTTP') || {}).reduce(
|
||||||
function(prev, [key, value]) {
|
function (prev, [key, value]) {
|
||||||
if (key.toLowerCase().startsWith('path')) {
|
if (key.toLowerCase().startsWith('path')) {
|
||||||
return {
|
return {
|
||||||
type: key.replace('Path', ''),
|
type: key.replace('Path', ''),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const getNodesByType = function(nodes = {}, type) {
|
const getNodesByType = function (nodes = {}, type) {
|
||||||
return Object.values(nodes).filter(item => item.Type === type);
|
return Object.values(nodes).filter((item) => item.Type === type);
|
||||||
};
|
};
|
||||||
const findResolver = function(resolvers, service, nspace = 'default', partition = 'default', dc) {
|
const findResolver = function (resolvers, service, nspace = 'default', partition = 'default', dc) {
|
||||||
if (typeof resolvers[service] === 'undefined') {
|
if (typeof resolvers[service] === 'undefined') {
|
||||||
resolvers[service] = {
|
resolvers[service] = {
|
||||||
ID: `${service}.${nspace}.${partition}.${dc}`,
|
ID: `${service}.${nspace}.${partition}.${dc}`,
|
||||||
|
@ -11,16 +11,16 @@ const findResolver = function(resolvers, service, nspace = 'default', partition
|
||||||
}
|
}
|
||||||
return resolvers[service];
|
return resolvers[service];
|
||||||
};
|
};
|
||||||
export const getAlternateServices = function(targets, a) {
|
export const getAlternateServices = function (targets, a) {
|
||||||
let type;
|
let type;
|
||||||
const Targets = targets.map(function(b) {
|
const Targets = targets.map(function (b) {
|
||||||
// TODO: this isn't going to work past namespace for services
|
// TODO: this isn't going to work past namespace for services
|
||||||
// with dots in the name, but by the time that becomes an issue
|
// with dots in the name, but by the time that becomes an issue
|
||||||
// we might have more data from the endpoint so we don't have to guess
|
// we might have more data from the endpoint so we don't have to guess
|
||||||
// right now the backend also doesn't support dots in service names
|
// right now the backend also doesn't support dots in service names
|
||||||
const [aRev, bRev] = [a, b].map(item => item.split('.').reverse());
|
const [aRev, bRev] = [a, b].map((item) => item.split('.').reverse());
|
||||||
const types = ['Datacenter', 'Partition', 'Namespace', 'Service', 'Subset'];
|
const types = ['Datacenter', 'Partition', 'Namespace', 'Service', 'Subset'];
|
||||||
return bRev.find(function(item, i) {
|
return bRev.find(function (item, i) {
|
||||||
const res = item !== aRev[i];
|
const res = item !== aRev[i];
|
||||||
if (res) {
|
if (res) {
|
||||||
type = types[i];
|
type = types[i];
|
||||||
|
@ -34,8 +34,8 @@ export const getAlternateServices = function(targets, a) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSplitters = function(nodes) {
|
export const getSplitters = function (nodes) {
|
||||||
return getNodesByType(nodes, 'splitter').map(function(item) {
|
return getNodesByType(nodes, 'splitter').map(function (item) {
|
||||||
// Splitters need IDs adding so we can find them in the DOM later
|
// Splitters need IDs adding so we can find them in the DOM later
|
||||||
// splitters have a service.nspace as a name
|
// splitters have a service.nspace as a name
|
||||||
// do the reverse dance to ensure we don't mess up any
|
// do the reverse dance to ensure we don't mess up any
|
||||||
|
@ -52,17 +52,17 @@ export const getSplitters = function(nodes) {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const getRoutes = function(nodes, uid) {
|
export const getRoutes = function (nodes, uid) {
|
||||||
return getNodesByType(nodes, 'router').reduce(function(prev, item) {
|
return getNodesByType(nodes, 'router').reduce(function (prev, item) {
|
||||||
return prev.concat(
|
return prev.concat(
|
||||||
item.Routes.map(function(route, i) {
|
item.Routes.map(function (route, i) {
|
||||||
// Routes also have IDs added via createRoute
|
// Routes also have IDs added via createRoute
|
||||||
return createRoute(route, item.Name, uid);
|
return createRoute(route, item.Name, uid);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
};
|
};
|
||||||
export const getResolvers = function(
|
export const getResolvers = function (
|
||||||
dc,
|
dc,
|
||||||
partition = 'default',
|
partition = 'default',
|
||||||
nspace = 'default',
|
nspace = 'default',
|
||||||
|
@ -72,8 +72,8 @@ export const getResolvers = function(
|
||||||
const resolvers = {};
|
const resolvers = {};
|
||||||
// make all our resolver nodes
|
// make all our resolver nodes
|
||||||
Object.values(nodes)
|
Object.values(nodes)
|
||||||
.filter(item => item.Type === 'resolver')
|
.filter((item) => item.Type === 'resolver')
|
||||||
.forEach(function(item) {
|
.forEach(function (item) {
|
||||||
const parts = item.Name.split('.');
|
const parts = item.Name.split('.');
|
||||||
let subset;
|
let subset;
|
||||||
// this will leave behind the service.name.nspace.partition.dc even if the service name contains a dot
|
// this will leave behind the service.name.nspace.partition.dc even if the service name contains a dot
|
||||||
|
@ -113,7 +113,7 @@ export const getResolvers = function(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Object.values(targets).forEach(target => {
|
Object.values(targets).forEach((target) => {
|
||||||
// Failovers don't have a specific node
|
// Failovers don't have a specific node
|
||||||
if (typeof nodes[`resolver:${target.ID}`] !== 'undefined') {
|
if (typeof nodes[`resolver:${target.ID}`] !== 'undefined') {
|
||||||
// We use this to figure out whether this target is a redirect target
|
// We use this to figure out whether this target is a redirect target
|
||||||
|
@ -144,7 +144,7 @@ export const getResolvers = function(
|
||||||
});
|
});
|
||||||
return Object.values(resolvers);
|
return Object.values(resolvers);
|
||||||
};
|
};
|
||||||
export const createRoute = function(route, router, uid) {
|
export const createRoute = function (route, router, uid) {
|
||||||
return {
|
return {
|
||||||
...route,
|
...route,
|
||||||
Default: route.Default || typeof route.Definition.Match === 'undefined',
|
Default: route.Default || typeof route.Definition.Match === 'undefined',
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
export default (collection, text) => (scope = '.consul-health-check-list') => {
|
export default (collection, text) =>
|
||||||
return {
|
(scope = '.consul-health-check-list') => {
|
||||||
scope,
|
return {
|
||||||
item: collection('li', {
|
scope,
|
||||||
name: text('header h3'),
|
item: collection('li', {
|
||||||
type: text('[data-health-check-type]'),
|
name: text('header h3'),
|
||||||
exposed: text('[data-test-exposed]'),
|
type: text('[data-health-check-type]'),
|
||||||
}),
|
exposed: text('[data-test-exposed]'),
|
||||||
|
}),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
|
@ -192,7 +192,7 @@
|
||||||
<button
|
<button
|
||||||
data-test-create-permission
|
data-test-create-permission
|
||||||
type="button"
|
type="button"
|
||||||
{{on "click" (optional this.modal.open)}}
|
{{on "click" (action this.openModal)}}
|
||||||
>
|
>
|
||||||
Add permission
|
Add permission
|
||||||
</button>
|
</button>
|
||||||
|
@ -201,7 +201,7 @@
|
||||||
<Consul::Intention::Notice::Permissions />
|
<Consul::Intention::Notice::Permissions />
|
||||||
<Consul::Intention::Permission::List
|
<Consul::Intention::Permission::List
|
||||||
@items={{item.Permissions}}
|
@items={{item.Permissions}}
|
||||||
@onclick={{queue (action (mut permission)) (action (optional this.modal.open))}}
|
@onclick={{queue (action (mut permission)) (action this.openModal)}}
|
||||||
@ondelete={{action 'delete' 'Permissions' item}}
|
@ondelete={{action 'delete' 'Permissions' item}}
|
||||||
/>
|
/>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|
|
@ -5,20 +5,24 @@ export default Component.extend({
|
||||||
|
|
||||||
shouldShowPermissionForm: false,
|
shouldShowPermissionForm: false,
|
||||||
|
|
||||||
|
openModal() {
|
||||||
|
this.modal?.open();
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
createNewLabel: function(template, term) {
|
createNewLabel: function (template, term) {
|
||||||
return template.replace(/{{term}}/g, term);
|
return template.replace(/{{term}}/g, term);
|
||||||
},
|
},
|
||||||
isUnique: function(items, term) {
|
isUnique: function (items, term) {
|
||||||
return !items.findBy('Name', term);
|
return !items.findBy('Name', term);
|
||||||
},
|
},
|
||||||
add: function(name, changeset, value) {
|
add: function (name, changeset, value) {
|
||||||
if (!(changeset.get(name) || []).includes(value) && value.isNew) {
|
if (!(changeset.get(name) || []).includes(value) && value.isNew) {
|
||||||
changeset.pushObject(name, value);
|
changeset.pushObject(name, value);
|
||||||
changeset.validate();
|
changeset.validate();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
delete: function(name, changeset, value) {
|
delete: function (name, changeset, value) {
|
||||||
if ((changeset.get(name) || []).includes(value)) {
|
if ((changeset.get(name) || []).includes(value)) {
|
||||||
changeset.removeObject(name, value);
|
changeset.removeObject(name, value);
|
||||||
changeset.validate();
|
changeset.validate();
|
||||||
|
|
|
@ -79,7 +79,9 @@ export default class ConsulIntentionForm extends Component {
|
||||||
let items = e.data
|
let items = e.data
|
||||||
.uniqBy('Name')
|
.uniqBy('Name')
|
||||||
.toArray()
|
.toArray()
|
||||||
.filter(item => !['connect-proxy', 'mesh-gateway', 'terminating-gateway'].includes(item.Kind))
|
.filter(
|
||||||
|
(item) => !['connect-proxy', 'mesh-gateway', 'terminating-gateway'].includes(item.Kind)
|
||||||
|
)
|
||||||
.sort((a, b) => a.Name.localeCompare(b.Name));
|
.sort((a, b) => a.Name.localeCompare(b.Name));
|
||||||
items = [{ Name: '*' }].concat(items);
|
items = [{ Name: '*' }].concat(items);
|
||||||
let source = items.findBy('Name', item.SourceName);
|
let source = items.findBy('Name', item.SourceName);
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
export default (collection, clickable, attribute, isPresent, deletable) => (
|
export default (collection, clickable, attribute, isPresent, deletable) =>
|
||||||
scope = '.consul-intention-list'
|
(scope = '.consul-intention-list') => {
|
||||||
) => {
|
const row = {
|
||||||
const row = {
|
source: attribute('data-test-intention-source', '[data-test-intention-source]'),
|
||||||
source: attribute('data-test-intention-source', '[data-test-intention-source]'),
|
destination: attribute(
|
||||||
destination: attribute('data-test-intention-destination', '[data-test-intention-destination]'),
|
'data-test-intention-destination',
|
||||||
action: attribute('data-test-intention-action', '[data-test-intention-action]'),
|
'[data-test-intention-destination]'
|
||||||
intention: clickable('a'),
|
),
|
||||||
actions: clickable('label'),
|
action: attribute('data-test-intention-action', '[data-test-intention-action]'),
|
||||||
...deletable(),
|
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),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
|
@ -12,18 +12,18 @@ export default Component.extend({
|
||||||
change: service('change'),
|
change: service('change'),
|
||||||
repo: service(`repository/${name}`),
|
repo: service(`repository/${name}`),
|
||||||
|
|
||||||
onsubmit: function() {},
|
onsubmit: function () {},
|
||||||
onreset: function() {},
|
onreset: function () {},
|
||||||
|
|
||||||
intents: alias(`schema.${name}.Action.allowedValues`),
|
intents: alias(`schema.${name}.Action.allowedValues`),
|
||||||
methods: alias(`schema.${name}-http.Methods.allowedValues`),
|
methods: alias(`schema.${name}-http.Methods.allowedValues`),
|
||||||
pathProps: alias(`schema.${name}-http.PathType.allowedValues`),
|
pathProps: alias(`schema.${name}-http.PathType.allowedValues`),
|
||||||
|
|
||||||
pathTypes: computed('pathProps', function() {
|
pathTypes: computed('pathProps', function () {
|
||||||
return ['NoPath'].concat(this.pathProps);
|
return ['NoPath'].concat(this.pathProps);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
pathLabels: computed(function() {
|
pathLabels: computed(function () {
|
||||||
return {
|
return {
|
||||||
NoPath: 'No Path',
|
NoPath: 'No Path',
|
||||||
PathExact: 'Exact',
|
PathExact: 'Exact',
|
||||||
|
@ -32,7 +32,7 @@ export default Component.extend({
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
pathInputLabels: computed(function() {
|
pathInputLabels: computed(function () {
|
||||||
return {
|
return {
|
||||||
PathExact: 'Exact Path',
|
PathExact: 'Exact Path',
|
||||||
PathPrefix: 'Path Prefix',
|
PathPrefix: 'Path Prefix',
|
||||||
|
@ -40,7 +40,7 @@ export default Component.extend({
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
changeset: computed('item', function() {
|
changeset: computed('item', function () {
|
||||||
const changeset = this.change.changesetFor(name, this.item || this.repo.create());
|
const changeset = this.change.changesetFor(name, this.item || this.repo.create());
|
||||||
if (changeset.isNew) {
|
if (changeset.isNew) {
|
||||||
changeset.validate();
|
changeset.validate();
|
||||||
|
@ -48,7 +48,7 @@ export default Component.extend({
|
||||||
return changeset;
|
return changeset;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
pathType: computed('changeset._changes.HTTP.PathType', 'pathTypes.firstObject', function() {
|
pathType: computed('changeset._changes.HTTP.PathType', 'pathTypes.firstObject', function () {
|
||||||
return this.changeset.HTTP.PathType || this.pathTypes.firstObject;
|
return this.changeset.HTTP.PathType || this.pathTypes.firstObject;
|
||||||
}),
|
}),
|
||||||
noPathType: equal('pathType', 'NoPath'),
|
noPathType: equal('pathType', 'NoPath'),
|
||||||
|
@ -57,14 +57,14 @@ export default Component.extend({
|
||||||
allMethods: false,
|
allMethods: false,
|
||||||
shouldShowMethods: not('allMethods'),
|
shouldShowMethods: not('allMethods'),
|
||||||
|
|
||||||
didReceiveAttrs: function() {
|
didReceiveAttrs: function () {
|
||||||
if (!get(this, 'item.HTTP.Methods.length')) {
|
if (!get(this, 'item.HTTP.Methods.length')) {
|
||||||
set(this, 'allMethods', true);
|
set(this, 'allMethods', true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
change: function(name, changeset, e) {
|
change: function (name, changeset, e) {
|
||||||
const value = typeof get(e, 'target.value') !== 'undefined' ? e.target.value : e;
|
const value = typeof get(e, 'target.value') !== 'undefined' ? e.target.value : e;
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case 'allMethods':
|
case 'allMethods':
|
||||||
|
@ -82,21 +82,21 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
changeset.validate();
|
changeset.validate();
|
||||||
},
|
},
|
||||||
add: function(prop, changeset, value) {
|
add: function (prop, changeset, value) {
|
||||||
changeset.pushObject(prop, value);
|
changeset.pushObject(prop, value);
|
||||||
changeset.validate();
|
changeset.validate();
|
||||||
},
|
},
|
||||||
delete: function(prop, changeset, value) {
|
delete: function (prop, changeset, value) {
|
||||||
changeset.removeObject(prop, value);
|
changeset.removeObject(prop, value);
|
||||||
changeset.validate();
|
changeset.validate();
|
||||||
},
|
},
|
||||||
submit: function(changeset, e) {
|
submit: function (changeset, e) {
|
||||||
const pathChanged =
|
const pathChanged =
|
||||||
typeof changeset.changes.find(
|
typeof changeset.changes.find(
|
||||||
({ key, value }) => key === 'HTTP.PathType' || key === 'HTTP.Path'
|
({ key, value }) => key === 'HTTP.PathType' || key === 'HTTP.Path'
|
||||||
) !== 'undefined';
|
) !== 'undefined';
|
||||||
if (pathChanged) {
|
if (pathChanged) {
|
||||||
this.pathProps.forEach(prop => {
|
this.pathProps.forEach((prop) => {
|
||||||
changeset.set(`HTTP.${prop}`, undefined);
|
changeset.set(`HTTP.${prop}`, undefined);
|
||||||
});
|
});
|
||||||
if (changeset.HTTP.PathType !== 'NoPath') {
|
if (changeset.HTTP.PathType !== 'NoPath') {
|
||||||
|
@ -115,7 +115,7 @@ export default Component.extend({
|
||||||
this.repo.persist(changeset);
|
this.repo.persist(changeset);
|
||||||
this.onsubmit(changeset.data);
|
this.onsubmit(changeset.data);
|
||||||
},
|
},
|
||||||
reset: function(changeset, e) {
|
reset: function (changeset, e) {
|
||||||
changeset.rollback();
|
changeset.rollback();
|
||||||
this.onreset(changeset.data);
|
this.onreset(changeset.data);
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,10 +12,10 @@ export default Component.extend({
|
||||||
change: service('change'),
|
change: service('change'),
|
||||||
repo: service(`repository/${name}`),
|
repo: service(`repository/${name}`),
|
||||||
|
|
||||||
onsubmit: function() {},
|
onsubmit: function () {},
|
||||||
onreset: function() {},
|
onreset: function () {},
|
||||||
|
|
||||||
changeset: computed('item', function() {
|
changeset: computed('item', function () {
|
||||||
return this.change.changesetFor(
|
return this.change.changesetFor(
|
||||||
name,
|
name,
|
||||||
this.item ||
|
this.item ||
|
||||||
|
@ -27,7 +27,7 @@ export default Component.extend({
|
||||||
|
|
||||||
headerTypes: alias(`schema.${name}.HeaderType.allowedValues`),
|
headerTypes: alias(`schema.${name}.HeaderType.allowedValues`),
|
||||||
|
|
||||||
headerLabels: computed(function() {
|
headerLabels: computed(function () {
|
||||||
return {
|
return {
|
||||||
Exact: 'Exactly Matching',
|
Exact: 'Exactly Matching',
|
||||||
Prefix: 'Prefixed by',
|
Prefix: 'Prefixed by',
|
||||||
|
@ -37,7 +37,7 @@ export default Component.extend({
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
headerType: computed('changeset.HeaderType', 'headerTypes.firstObject', function() {
|
headerType: computed('changeset.HeaderType', 'headerTypes.firstObject', function () {
|
||||||
return this.changeset.HeaderType || this.headerTypes.firstObject;
|
return this.changeset.HeaderType || this.headerTypes.firstObject;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ export default Component.extend({
|
||||||
shouldShowValueField: not('headerTypeEqualsPresent'),
|
shouldShowValueField: not('headerTypeEqualsPresent'),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
change: function(name, changeset, e) {
|
change: function (name, changeset, e) {
|
||||||
const value = typeof get(e, 'target.value') !== 'undefined' ? e.target.value : e;
|
const value = typeof get(e, 'target.value') !== 'undefined' ? e.target.value : e;
|
||||||
switch (name) {
|
switch (name) {
|
||||||
default:
|
default:
|
||||||
|
@ -53,8 +53,8 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
changeset.validate();
|
changeset.validate();
|
||||||
},
|
},
|
||||||
submit: function(changeset) {
|
submit: function (changeset) {
|
||||||
this.headerTypes.forEach(prop => {
|
this.headerTypes.forEach((prop) => {
|
||||||
changeset.set(prop, undefined);
|
changeset.set(prop, undefined);
|
||||||
});
|
});
|
||||||
// Present is a boolean, whereas all other header types have a value
|
// Present is a boolean, whereas all other header types have a value
|
||||||
|
@ -78,7 +78,7 @@ export default Component.extend({
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
reset: function(changeset, e) {
|
reset: function (changeset, e) {
|
||||||
changeset.rollback();
|
changeset.rollback();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,15 +6,15 @@ export default Component.extend({
|
||||||
tagName: '',
|
tagName: '',
|
||||||
encoder: service('btoa'),
|
encoder: service('btoa'),
|
||||||
json: true,
|
json: true,
|
||||||
ondelete: function() {
|
ondelete: function () {
|
||||||
this.onsubmit(...arguments);
|
this.onsubmit(...arguments);
|
||||||
},
|
},
|
||||||
oncancel: function() {
|
oncancel: function () {
|
||||||
this.onsubmit(...arguments);
|
this.onsubmit(...arguments);
|
||||||
},
|
},
|
||||||
onsubmit: function() {},
|
onsubmit: function () {},
|
||||||
actions: {
|
actions: {
|
||||||
change: function(e, form) {
|
change: function (e, form) {
|
||||||
const item = form.getData();
|
const item = form.getData();
|
||||||
try {
|
try {
|
||||||
form.handleEvent(e);
|
form.handleEvent(e);
|
||||||
|
|
|
@ -3,10 +3,10 @@ import { tracked } from '@glimmer/tracking';
|
||||||
|
|
||||||
const size = 336;
|
const size = 336;
|
||||||
const insetSize = size / 2 - 8;
|
const insetSize = size / 2 - 8;
|
||||||
const inset = function(num) {
|
const inset = function (num) {
|
||||||
return insetSize * num;
|
return insetSize * num;
|
||||||
};
|
};
|
||||||
const milliseconds = function(num, max) {
|
const milliseconds = function (num, max) {
|
||||||
return max > 0 ? parseInt(max * num) / 100 : 0;
|
return max > 0 ? parseInt(max * num) / 100 : 0;
|
||||||
};
|
};
|
||||||
export default class TomographyGraph extends Component {
|
export default class TomographyGraph extends Component {
|
||||||
|
@ -19,7 +19,7 @@ export default class TomographyGraph extends Component {
|
||||||
get milliseconds() {
|
get milliseconds() {
|
||||||
const distances = this.args.distances || [];
|
const distances = this.args.distances || [];
|
||||||
const max = distances.reduce((prev, d) => Math.max(prev, d.distance), this.max);
|
const max = distances.reduce((prev, d) => Math.max(prev, d.distance), this.max);
|
||||||
return [25, 50, 75, 100].map(item => milliseconds(item, max));
|
return [25, 50, 75, 100].map((item) => milliseconds(item, max));
|
||||||
}
|
}
|
||||||
|
|
||||||
get distances() {
|
get distances() {
|
||||||
|
@ -30,7 +30,7 @@ export default class TomographyGraph extends Component {
|
||||||
// We have more nodes than we want to show, take a random sampling to keep
|
// We have more nodes than we want to show, take a random sampling to keep
|
||||||
// the number around 360.
|
// the number around 360.
|
||||||
const sampling = 360 / len;
|
const sampling = 360 / len;
|
||||||
distances = distances.filter(function(_, i) {
|
distances = distances.filter(function (_, i) {
|
||||||
return i == 0 || i == len - 1 || Math.random() < sampling;
|
return i == 0 || i == len - 1 || Math.random() < sampling;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
export default (collection, text) => (scope = '.consul-upstream-instance-list') => {
|
export default (collection, text) =>
|
||||||
return {
|
(scope = '.consul-upstream-instance-list') => {
|
||||||
scope,
|
return {
|
||||||
item: collection('li', {
|
scope,
|
||||||
name: text('.header p'),
|
item: collection('li', {
|
||||||
nspace: text('.nspace dd'),
|
name: text('.header p'),
|
||||||
datacenter: text('.datacenter dd'),
|
nspace: text('.nspace dd'),
|
||||||
localAddress: text('.local-address dd'),
|
datacenter: text('.datacenter dd'),
|
||||||
}),
|
localAddress: text('.local-address dd'),
|
||||||
|
}),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
|
@ -11,17 +11,23 @@ const typeCast = (attributeInfo, value) => {
|
||||||
let type = attributeInfo.type;
|
let type = attributeInfo.type;
|
||||||
const d = attributeInfo.default;
|
const d = attributeInfo.default;
|
||||||
value = value == null ? attributeInfo.default : value;
|
value = value == null ? attributeInfo.default : value;
|
||||||
if(type.indexOf('|') !== -1) {
|
if (type.indexOf('|') !== -1) {
|
||||||
assert(`"${value} is not of type '${type}'"`, type.split('|').map(item => item.replaceAll('"', '').trim()).includes(value));
|
assert(
|
||||||
|
`"${value} is not of type '${type}'"`,
|
||||||
|
type
|
||||||
|
.split('|')
|
||||||
|
.map((item) => item.replaceAll('"', '').trim())
|
||||||
|
.includes(value)
|
||||||
|
);
|
||||||
type = 'string';
|
type = 'string';
|
||||||
}
|
}
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case '<length>':
|
case '<length>':
|
||||||
case '<percentage>':
|
case '<percentage>':
|
||||||
case '<dimension>':
|
case '<dimension>':
|
||||||
case 'number': {
|
case 'number': {
|
||||||
const num = parseFloat(value);
|
const num = parseFloat(value);
|
||||||
if(isNaN(num)) {
|
if (isNaN(num)) {
|
||||||
return typeof d === 'undefined' ? 0 : d;
|
return typeof d === 'undefined' ? 0 : d;
|
||||||
} else {
|
} else {
|
||||||
return num;
|
return num;
|
||||||
|
@ -33,7 +39,7 @@ const typeCast = (attributeInfo, value) => {
|
||||||
case 'string':
|
case 'string':
|
||||||
return (value || '').toString();
|
return (value || '').toString();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const attributeChangingElement = (name, Cls = HTMLElement, attributes = {}, cssprops = {}) => {
|
const attributeChangingElement = (name, Cls = HTMLElement, attributes = {}, cssprops = {}) => {
|
||||||
const attrs = Object.keys(attributes);
|
const attrs = Object.keys(attributes);
|
||||||
|
@ -48,65 +54,58 @@ const attributeChangingElement = (name, Cls = HTMLElement, attributes = {}, cssp
|
||||||
const value = typeCast(attributes[name], newValue);
|
const value = typeCast(attributes[name], newValue);
|
||||||
|
|
||||||
const cssProp = cssprops[`--${name}`];
|
const cssProp = cssprops[`--${name}`];
|
||||||
if(typeof cssProp !== 'undefined' && cssProp.track === `[${name}]`) {
|
if (typeof cssProp !== 'undefined' && cssProp.track === `[${name}]`) {
|
||||||
this.style.setProperty(
|
this.style.setProperty(`--${name}`, value);
|
||||||
`--${name}`,
|
|
||||||
value
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(typeof super.attributeChangedCallback === 'function') {
|
if (typeof super.attributeChangedCallback === 'function') {
|
||||||
super.attributeChangedCallback(name, prev, value);
|
super.attributeChangedCallback(name, prev, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new CustomEvent(
|
new CustomEvent(ATTRIBUTE_CHANGE, {
|
||||||
ATTRIBUTE_CHANGE,
|
detail: {
|
||||||
{
|
name: name,
|
||||||
detail: {
|
previousValue: prev,
|
||||||
name: name,
|
value: value,
|
||||||
previousValue: prev,
|
},
|
||||||
value: value
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
customElements.define(name, customClass);
|
customElements.define(name, customClass);
|
||||||
return () => {};
|
return () => {};
|
||||||
}
|
};
|
||||||
|
|
||||||
const infoFromArray = (arr, keys) => {
|
const infoFromArray = (arr, keys) => {
|
||||||
return (arr || []).reduce((prev, info) => {
|
return (arr || []).reduce((prev, info) => {
|
||||||
let key;
|
let key;
|
||||||
const obj = {};
|
const obj = {};
|
||||||
keys.forEach((item, i) => {
|
keys.forEach((item, i) => {
|
||||||
if(item === '_') {
|
if (item === '_') {
|
||||||
key = i;
|
key = i;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
obj[item] = info[i]
|
obj[item] = info[i];
|
||||||
});
|
});
|
||||||
prev[info[key]] = obj;
|
prev[info[key]] = obj;
|
||||||
return prev;
|
return prev;
|
||||||
}, {});
|
}, {});
|
||||||
}
|
};
|
||||||
const debounceRAF = (cb, prev) => {
|
const debounceRAF = (cb, prev) => {
|
||||||
if(typeof prev !== 'undefined') {
|
if (typeof prev !== 'undefined') {
|
||||||
cancelAnimationFrame(prev);
|
cancelAnimationFrame(prev);
|
||||||
}
|
}
|
||||||
return requestAnimationFrame(cb);
|
return requestAnimationFrame(cb);
|
||||||
}
|
};
|
||||||
const createElementProxy = ($element, component) => {
|
const createElementProxy = ($element, component) => {
|
||||||
return new Proxy($element, {
|
return new Proxy($element, {
|
||||||
get: (target, prop, receiver) => {
|
get: (target, prop, receiver) => {
|
||||||
switch(prop) {
|
switch (prop) {
|
||||||
case 'attrs':
|
case 'attrs':
|
||||||
return component.attributes;
|
return component.attributes;
|
||||||
default:
|
default:
|
||||||
if(typeof target[prop] === 'function') {
|
if (typeof target[prop] === 'function') {
|
||||||
// need to ensure we use a MultiWeakMap here
|
// need to ensure we use a MultiWeakMap here
|
||||||
// if(this.methods.has(prop)) {
|
// if(this.methods.has(prop)) {
|
||||||
// return this.methods.get(prop);
|
// return this.methods.get(prop);
|
||||||
|
@ -115,30 +114,27 @@ const createElementProxy = ($element, component) => {
|
||||||
// this.methods.set(prop, method);
|
// this.methods.set(prop, method);
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export default class CustomElementComponent extends Component {
|
export default class CustomElementComponent extends Component {
|
||||||
|
|
||||||
@tracked $element;
|
@tracked $element;
|
||||||
@tracked _attributes = {};
|
@tracked _attributes = {};
|
||||||
|
|
||||||
__attributes;
|
__attributes;
|
||||||
_attchange;
|
_attchange;
|
||||||
|
|
||||||
|
|
||||||
constructor(owner, args) {
|
constructor(owner, args) {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
if(!elements.has(args.element)) {
|
if (!elements.has(args.element)) {
|
||||||
const cb = attributeChangingElement(
|
const cb = attributeChangingElement(
|
||||||
args.element,
|
args.element,
|
||||||
args.class,
|
args.class,
|
||||||
infoFromArray(args.attrs, ['_', 'type', 'default', 'description']),
|
infoFromArray(args.attrs, ['_', 'type', 'default', 'description']),
|
||||||
infoFromArray(args.cssprops, ['_', 'type', 'track', 'description'])
|
infoFromArray(args.cssprops, ['_', 'type', 'track', 'description'])
|
||||||
)
|
);
|
||||||
elements.set(args.element, cb);
|
elements.set(args.element, cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,8 +144,8 @@ export default class CustomElementComponent extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
get element() {
|
get element() {
|
||||||
if(this.$element) {
|
if (this.$element) {
|
||||||
if(proxies.has(this.$element)) {
|
if (proxies.has(this.$element)) {
|
||||||
return proxies.get(this.$element);
|
return proxies.get(this.$element);
|
||||||
}
|
}
|
||||||
const proxy = createElementProxy(this.$element, this);
|
const proxy = createElementProxy(this.$element, this);
|
||||||
|
@ -165,9 +161,9 @@ export default class CustomElementComponent extends Component {
|
||||||
this.$element = $element;
|
this.$element = $element;
|
||||||
this.$element.addEventListener(ATTRIBUTE_CHANGE, this.attributeChange);
|
this.$element.addEventListener(ATTRIBUTE_CHANGE, this.attributeChange);
|
||||||
|
|
||||||
(this.args.attrs || []).forEach(entry => {
|
(this.args.attrs || []).forEach((entry) => {
|
||||||
const value = $element.getAttribute(entry[0]);
|
const value = $element.getAttribute(entry[0]);
|
||||||
$element.attributeChangedCallback(entry[0], value, value)
|
$element.attributeChangedCallback(entry[0], value, value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +179,7 @@ export default class CustomElementComponent extends Component {
|
||||||
// they all change
|
// they all change
|
||||||
this.__attributes = {
|
this.__attributes = {
|
||||||
...this.__attributes,
|
...this.__attributes,
|
||||||
[e.detail.name]: e.detail.value
|
[e.detail.name]: e.detail.value,
|
||||||
};
|
};
|
||||||
this._attchange = debounceRAF(() => {
|
this._attchange = debounceRAF(() => {
|
||||||
// tell glimmer we changed the attrs
|
// tell glimmer we changed the attrs
|
||||||
|
|
|
@ -9,17 +9,17 @@ export default Component.extend(Slotted, {
|
||||||
dom: service('dom'),
|
dom: service('dom'),
|
||||||
builder: service('form'),
|
builder: service('form'),
|
||||||
create: false,
|
create: false,
|
||||||
ondelete: function() {
|
ondelete: function () {
|
||||||
return this.onsubmit(...arguments);
|
return this.onsubmit(...arguments);
|
||||||
},
|
},
|
||||||
oncancel: function() {
|
oncancel: function () {
|
||||||
return this.onsubmit(...arguments);
|
return this.onsubmit(...arguments);
|
||||||
},
|
},
|
||||||
onsubmit: function() {},
|
onsubmit: function () {},
|
||||||
onchange: function(e, form) {
|
onchange: function (e, form) {
|
||||||
return form.handleEvent(e);
|
return form.handleEvent(e);
|
||||||
},
|
},
|
||||||
didReceiveAttrs: function() {
|
didReceiveAttrs: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
try {
|
try {
|
||||||
this.form = this.builder.form(this.type);
|
this.form = this.builder.form(this.type);
|
||||||
|
@ -28,18 +28,18 @@ export default Component.extend(Slotted, {
|
||||||
// this lets us load view only data that doesn't have a form
|
// this lets us load view only data that doesn't have a form
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
willRender: function() {
|
willRender: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
set(this, 'hasError', this._isRegistered('error'));
|
set(this, 'hasError', this._isRegistered('error'));
|
||||||
},
|
},
|
||||||
willDestroyElement: function() {
|
willDestroyElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
if (get(this, 'data.isNew')) {
|
if (get(this, 'data.isNew')) {
|
||||||
this.data.rollbackAttributes();
|
this.data.rollbackAttributes();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setData: function(data) {
|
setData: function (data) {
|
||||||
let changeset = data;
|
let changeset = data;
|
||||||
// convert to a real changeset
|
// convert to a real changeset
|
||||||
if (!isChangeset(data) && typeof this.form !== 'undefined') {
|
if (!isChangeset(data) && typeof this.form !== 'undefined') {
|
||||||
|
@ -49,7 +49,7 @@ export default Component.extend(Slotted, {
|
||||||
// and autofill the new record if required
|
// and autofill the new record if required
|
||||||
if (get(data, 'isNew')) {
|
if (get(data, 'isNew')) {
|
||||||
set(this, 'create', true);
|
set(this, 'create', true);
|
||||||
changeset = Object.entries(this.autofill || {}).reduce(function(prev, [key, value]) {
|
changeset = Object.entries(this.autofill || {}).reduce(function (prev, [key, value]) {
|
||||||
set(prev, key, value);
|
set(prev, key, value);
|
||||||
return prev;
|
return prev;
|
||||||
}, changeset);
|
}, changeset);
|
||||||
|
@ -57,7 +57,7 @@ export default Component.extend(Slotted, {
|
||||||
set(this, 'data', changeset);
|
set(this, 'data', changeset);
|
||||||
return this.data;
|
return this.data;
|
||||||
},
|
},
|
||||||
change: function(e, value, item) {
|
change: function (e, value, item) {
|
||||||
this.onchange(this.dom.normalizeEvent(e, value), this.form, this.form.getData());
|
this.onchange(this.dom.normalizeEvent(e, value), this.form, this.form.getData());
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,26 +5,26 @@ import Slotted from 'block-slots';
|
||||||
import chart from './chart.xstate';
|
import chart from './chart.xstate';
|
||||||
export default Component.extend(Slotted, {
|
export default Component.extend(Slotted, {
|
||||||
tagName: '',
|
tagName: '',
|
||||||
onchange: data => data,
|
onchange: (data) => data,
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.chart = chart;
|
this.chart = chart;
|
||||||
},
|
},
|
||||||
didReceiveAttrs: function() {
|
didReceiveAttrs: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
if (typeof this.items !== 'undefined') {
|
if (typeof this.items !== 'undefined') {
|
||||||
this.actions.change.apply(this, [this.items]);
|
this.actions.change.apply(this, [this.items]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
didInsertElement: function() {
|
didInsertElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.dispatch('LOAD');
|
this.dispatch('LOAD');
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
isLoaded: function() {
|
isLoaded: function () {
|
||||||
return typeof this.items !== 'undefined' || typeof this.src === 'undefined';
|
return typeof this.items !== 'undefined' || typeof this.src === 'undefined';
|
||||||
},
|
},
|
||||||
change: function(data) {
|
change: function (data) {
|
||||||
set(this, 'data', this.onchange(data));
|
set(this, 'data', this.onchange(data));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,10 +11,10 @@ export default Component.extend({
|
||||||
dom: service('dom'),
|
dom: service('dom'),
|
||||||
logger: service('logger'),
|
logger: service('logger'),
|
||||||
|
|
||||||
onchange: function(e) {},
|
onchange: function (e) {},
|
||||||
onerror: function(e) {},
|
onerror: function (e) {},
|
||||||
|
|
||||||
state: computed('instance', 'instance.{dirtyType,isSaving}', function() {
|
state: computed('instance', 'instance.{dirtyType,isSaving}', function () {
|
||||||
let id;
|
let id;
|
||||||
const isSaving = get(this, 'instance.isSaving');
|
const isSaving = get(this, 'instance.isSaving');
|
||||||
const dirtyType = get(this, 'instance.dirtyType');
|
const dirtyType = get(this, 'instance.dirtyType');
|
||||||
|
@ -36,21 +36,21 @@ export default Component.extend({
|
||||||
id = `active.${id}`;
|
id = `active.${id}`;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
matches: name => id.indexOf(name) !== -1,
|
matches: (name) => id.indexOf(name) !== -1,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this._listeners = this.dom.listeners();
|
this._listeners = this.dom.listeners();
|
||||||
},
|
},
|
||||||
willDestroyElement: function() {
|
willDestroyElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this._listeners.remove();
|
this._listeners.remove();
|
||||||
},
|
},
|
||||||
source: function(cb) {
|
source: function (cb) {
|
||||||
const source = once(cb);
|
const source = once(cb);
|
||||||
const error = err => {
|
const error = (err) => {
|
||||||
set(this, 'instance', undefined);
|
set(this, 'instance', undefined);
|
||||||
try {
|
try {
|
||||||
this.onerror(err);
|
this.onerror(err);
|
||||||
|
@ -60,7 +60,7 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this._listeners.add(source, {
|
this._listeners.add(source, {
|
||||||
message: e => {
|
message: (e) => {
|
||||||
try {
|
try {
|
||||||
set(this, 'instance', undefined);
|
set(this, 'instance', undefined);
|
||||||
this.onchange(e);
|
this.onchange(e);
|
||||||
|
@ -68,17 +68,17 @@ export default Component.extend({
|
||||||
error(err);
|
error(err);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: e => error(e),
|
error: (e) => error(e),
|
||||||
});
|
});
|
||||||
return source;
|
return source;
|
||||||
},
|
},
|
||||||
didInsertElement: function() {
|
didInsertElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
if (typeof this.data !== 'undefined' || typeof this.item !== 'undefined') {
|
if (typeof this.data !== 'undefined' || typeof this.item !== 'undefined') {
|
||||||
this.actions.open.apply(this, [this.data, this.item]);
|
this.actions.open.apply(this, [this.data, this.item]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
persist: function(data, instance) {
|
persist: function (data, instance) {
|
||||||
if (typeof data !== 'undefined') {
|
if (typeof data !== 'undefined') {
|
||||||
set(this, 'instance', this.service.prepare(this.sink, data, instance));
|
set(this, 'instance', this.service.prepare(this.sink, data, instance));
|
||||||
} else {
|
} else {
|
||||||
|
@ -86,12 +86,12 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
this.source(() => this.service.persist(this.sink, this.instance));
|
this.source(() => this.service.persist(this.sink, this.instance));
|
||||||
},
|
},
|
||||||
remove: function(instance) {
|
remove: function (instance) {
|
||||||
set(this, 'instance', instance);
|
set(this, 'instance', instance);
|
||||||
this.source(() => this.service.remove(this.sink, instance));
|
this.source(() => this.service.remove(this.sink, instance));
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
open: function(data, item) {
|
open: function (data, item) {
|
||||||
if (item instanceof Event) {
|
if (item instanceof Event) {
|
||||||
item = undefined;
|
item = undefined;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { runInDebug } from '@ember/debug';
|
||||||
* @param value - value to use for replacement
|
* @param value - value to use for replacement
|
||||||
* @param destroy {(prev: any, value: any) => any} - teardown function
|
* @param destroy {(prev: any, value: any) => any} - teardown function
|
||||||
*/
|
*/
|
||||||
const replace = function(
|
const replace = function (
|
||||||
obj,
|
obj,
|
||||||
prop,
|
prop,
|
||||||
value,
|
value,
|
||||||
|
@ -29,7 +29,7 @@ const replace = function(
|
||||||
};
|
};
|
||||||
|
|
||||||
const noop = () => {};
|
const noop = () => {};
|
||||||
const optional = op => (typeof op === 'function' ? op : noop);
|
const optional = (op) => (typeof op === 'function' ? op : noop);
|
||||||
|
|
||||||
// possible values for @loading=""
|
// possible values for @loading=""
|
||||||
const LOADING = ['eager', 'lazy'];
|
const LOADING = ['eager', 'lazy'];
|
||||||
|
@ -74,7 +74,7 @@ export default class DataSource extends Component {
|
||||||
// otherwise its an array from the did-insert-helper
|
// otherwise its an array from the did-insert-helper
|
||||||
if (!Array.isArray($el)) {
|
if (!Array.isArray($el)) {
|
||||||
this._lazyListeners.add(
|
this._lazyListeners.add(
|
||||||
this.dom.isInViewport($el, inViewport => {
|
this.dom.isInViewport($el, (inViewport) => {
|
||||||
this.isIntersecting = inViewport;
|
this.isIntersecting = inViewport;
|
||||||
if (!this.isIntersecting) {
|
if (!this.isIntersecting) {
|
||||||
this.close();
|
this.close();
|
||||||
|
@ -130,7 +130,7 @@ export default class DataSource extends Component {
|
||||||
this.dataSource.close(prev, this);
|
this.dataSource.close(prev, this);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const error = err => {
|
const error = (err) => {
|
||||||
try {
|
try {
|
||||||
const error = get(err, 'error.errors.firstObject') || {};
|
const error = get(err, 'error.errors.firstObject') || {};
|
||||||
if (get(error, 'status') !== '429') {
|
if (get(error, 'status') !== '429') {
|
||||||
|
@ -143,14 +143,14 @@ export default class DataSource extends Component {
|
||||||
};
|
};
|
||||||
// set up the listeners (which auto cleanup on component destruction)
|
// set up the listeners (which auto cleanup on component destruction)
|
||||||
const remove = this._listeners.add(this.source, {
|
const remove = this._listeners.add(this.source, {
|
||||||
message: e => {
|
message: (e) => {
|
||||||
try {
|
try {
|
||||||
this.onchange(e);
|
this.onchange(e);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
error(err);
|
error(err);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: e => {
|
error: (e) => {
|
||||||
error(e);
|
error(e);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -187,7 +187,7 @@ export default class DataSource extends Component {
|
||||||
this.disconnect();
|
this.disconnect();
|
||||||
schedule('afterRender', () => {
|
schedule('afterRender', () => {
|
||||||
// TODO: Support lazy data-sources by keeping a reference to $el
|
// TODO: Support lazy data-sources by keeping a reference to $el
|
||||||
runInDebug(_ =>
|
runInDebug((_) =>
|
||||||
console.debug(
|
console.debug(
|
||||||
`Invalidation is only supported for non-lazy data sources. If you want to use this you should fixup support for lazy data sources`
|
`Invalidation is only supported for non-lazy data sources. If you want to use this you should fixup support for lazy data sources`
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,31 +5,30 @@ import chart from './chart.xstate';
|
||||||
|
|
||||||
export default Component.extend(Slotted, {
|
export default Component.extend(Slotted, {
|
||||||
tagName: '',
|
tagName: '',
|
||||||
ondelete: function() {
|
ondelete: function () {
|
||||||
return this.onchange(...arguments);
|
return this.onchange(...arguments);
|
||||||
},
|
},
|
||||||
onchange: function() {},
|
onchange: function () {},
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.chart = chart;
|
this.chart = chart;
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
persist: function(data, e) {
|
persist: function (data, e) {
|
||||||
if (e && typeof e.preventDefault === 'function') {
|
if (e && typeof e.preventDefault === 'function') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
set(this, 'data', data);
|
set(this, 'data', data);
|
||||||
this.dispatch('PERSIST');
|
this.dispatch('PERSIST');
|
||||||
},
|
},
|
||||||
error: function(data, e) {
|
error: function (data, e) {
|
||||||
if (e && typeof e.preventDefault === 'function') {
|
if (e && typeof e.preventDefault === 'function') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
set(
|
set(
|
||||||
this,
|
this,
|
||||||
'error',
|
'error',
|
||||||
typeof data.error.errors !== 'undefined' ?
|
typeof data.error.errors !== 'undefined' ? data.error.errors.firstObject : data.error
|
||||||
data.error.errors.firstObject : data.error
|
|
||||||
);
|
);
|
||||||
this.dispatch('ERROR');
|
this.dispatch('ERROR');
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,6 +2,6 @@ import Component from '@ember/component';
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
tagName: '',
|
tagName: '',
|
||||||
execute: function() {},
|
execute: function () {},
|
||||||
cancel: function() {},
|
cancel: function () {},
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,7 +17,7 @@ export default class DisclosureComponent extends Component {
|
||||||
remove(id) {
|
remove(id) {
|
||||||
this.ids = this.ids
|
this.ids = this.ids
|
||||||
.split(' ')
|
.split(' ')
|
||||||
.filter(item => item !== id)
|
.filter((item) => item !== id)
|
||||||
.join(' ');
|
.join(' ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,11 @@ export default (css) => {
|
||||||
border-radius: var(--decor-radius-999);
|
border-radius: var(--decor-radius-999);
|
||||||
transition-property: transform;
|
transition-property: transform;
|
||||||
transition-timing-function: ease-out;
|
transition-timing-function: ease-out;
|
||||||
transition-duration: .1s;
|
transition-duration: 0.1s;
|
||||||
}
|
}
|
||||||
:host([type='linear']) dl:hover {
|
:host([type='linear']) dl:hover {
|
||||||
transform: scaleY(3);
|
transform: scaleY(3);
|
||||||
box-shadow: var(--decor-elevation-200);
|
box-shadow: var(--decor-elevation-200);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
const parseFloatWithDefault = (val, d = 0) => {
|
const parseFloatWithDefault = (val, d = 0) => {
|
||||||
const num = parseFloat(val);
|
const num = parseFloat(val);
|
||||||
return isNaN(num) ? d : num;
|
return isNaN(num) ? d : num;
|
||||||
}
|
};
|
||||||
|
|
||||||
export default (Component) => {
|
export default (Component) => {
|
||||||
return class extends Component {
|
return class extends Component {
|
||||||
attributeChangedCallback(name, prev, value) {
|
attributeChangedCallback(name, prev, value) {
|
||||||
const target = this;
|
const target = this;
|
||||||
switch(name) {
|
switch (name) {
|
||||||
case 'percentage': {
|
case 'percentage': {
|
||||||
let prevSibling = target;
|
let prevSibling = target;
|
||||||
while(prevSibling) {
|
while (prevSibling) {
|
||||||
const nextSibling = prevSibling.nextElementSibling;
|
const nextSibling = prevSibling.nextElementSibling;
|
||||||
const aggregatedPercentage = nextSibling ? parseFloatWithDefault(nextSibling.style.getPropertyValue('--aggregated-percentage')) : 0;
|
const aggregatedPercentage = nextSibling
|
||||||
const perc = parseFloatWithDefault(prevSibling.getAttribute('percentage')) + aggregatedPercentage;
|
? parseFloatWithDefault(nextSibling.style.getPropertyValue('--aggregated-percentage'))
|
||||||
|
: 0;
|
||||||
|
const perc =
|
||||||
|
parseFloatWithDefault(prevSibling.getAttribute('percentage')) + aggregatedPercentage;
|
||||||
prevSibling.style.setProperty('--aggregated-percentage', perc);
|
prevSibling.style.setProperty('--aggregated-percentage', perc);
|
||||||
prevSibling.setAttribute('aggregated-percentage', perc);
|
prevSibling.setAttribute('aggregated-percentage', perc);
|
||||||
prevSibling = prevSibling.previousElementSibling;
|
prevSibling = prevSibling.previousElementSibling;
|
||||||
|
@ -22,5 +25,5 @@ export default (Component) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
|
@ -18,9 +18,10 @@ export default (css) => {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
transition-timing-function: ease-out;
|
transition-timing-function: ease-out;
|
||||||
transition-duration: .5s;
|
transition-duration: 0.5s;
|
||||||
}
|
}
|
||||||
dt, dd meter {
|
dt,
|
||||||
|
dd meter {
|
||||||
animation-name: visually-hidden;
|
animation-name: visually-hidden;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
animation-play-state: paused;
|
animation-play-state: paused;
|
||||||
|
@ -49,7 +50,7 @@ export default (css) => {
|
||||||
:host(.type-radial) circle,
|
:host(.type-radial) circle,
|
||||||
:host(.type-circular) circle {
|
:host(.type-circular) circle {
|
||||||
transition-timing-function: ease-out;
|
transition-timing-function: ease-out;
|
||||||
transition-duration: .5s;
|
transition-duration: 0.5s;
|
||||||
pointer-events: stroke;
|
pointer-events: stroke;
|
||||||
transition-property: stroke-dashoffset, stroke-width;
|
transition-property: stroke-dashoffset, stroke-width;
|
||||||
transform: rotate(-90deg);
|
transform: rotate(-90deg);
|
||||||
|
@ -76,4 +77,4 @@ export default (css) => {
|
||||||
stroke-width: 14;
|
stroke-width: 14;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
}
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@ import Slotted from 'block-slots';
|
||||||
|
|
||||||
export default Component.extend(Slotted, {
|
export default Component.extend(Slotted, {
|
||||||
tagName: '',
|
tagName: '',
|
||||||
willRender: function() {
|
willRender: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
set(this, 'hasHeader', this._isRegistered('header') || this._isRegistered('subheader'));
|
set(this, 'hasHeader', this._isRegistered('header') || this._isRegistered('subheader'));
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
export default present => (scope = '.empty-state') => {
|
export default (present) =>
|
||||||
return {
|
(scope = '.empty-state') => {
|
||||||
scope: scope,
|
return {
|
||||||
login: present('[data-test-empty-state-login]'),
|
scope: scope,
|
||||||
|
login: present('[data-test-empty-state-login]'),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import Component from '@ember/component';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import { get, set } from '@ember/object';
|
import { get, set } from '@ember/object';
|
||||||
|
|
||||||
const replace = function(
|
const replace = function (
|
||||||
obj,
|
obj,
|
||||||
prop,
|
prop,
|
||||||
value,
|
value,
|
||||||
|
@ -20,21 +20,21 @@ export default Component.extend({
|
||||||
logger: service('logger'),
|
logger: service('logger'),
|
||||||
data: service('data-source/service'),
|
data: service('data-source/service'),
|
||||||
closeOnDestroy: true,
|
closeOnDestroy: true,
|
||||||
onerror: function(e) {
|
onerror: function (e) {
|
||||||
this.logger.execute(e.error);
|
this.logger.execute(e.error);
|
||||||
},
|
},
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this._listeners = this.dom.listeners();
|
this._listeners = this.dom.listeners();
|
||||||
},
|
},
|
||||||
willDestroyElement: function() {
|
willDestroyElement: function () {
|
||||||
if (this.closeOnDestroy) {
|
if (this.closeOnDestroy) {
|
||||||
this.actions.close.apply(this, []);
|
this.actions.close.apply(this, []);
|
||||||
}
|
}
|
||||||
this._listeners.remove();
|
this._listeners.remove();
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
},
|
},
|
||||||
didReceiveAttrs: function() {
|
didReceiveAttrs: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
// only close and reopen if the uri changes
|
// only close and reopen if the uri changes
|
||||||
// otherwise this will fire whenever the proxies data changes
|
// otherwise this will fire whenever the proxies data changes
|
||||||
|
@ -43,7 +43,7 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
open: function() {
|
open: function () {
|
||||||
replace(this, 'source', this.data.open(this.src, this), (prev, source) => {
|
replace(this, 'source', this.data.open(this.src, this), (prev, source) => {
|
||||||
// Makes sure any previous source (if different) is ALWAYS closed
|
// Makes sure any previous source (if different) is ALWAYS closed
|
||||||
if (typeof prev !== 'undefined') {
|
if (typeof prev !== 'undefined') {
|
||||||
|
@ -56,7 +56,7 @@ export default Component.extend({
|
||||||
prev.destroy();
|
prev.destroy();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const error = err => {
|
const error = (err) => {
|
||||||
try {
|
try {
|
||||||
const error = get(err, 'error.errors.firstObject');
|
const error = get(err, 'error.errors.firstObject');
|
||||||
if (get(error || {}, 'status') !== '429') {
|
if (get(error || {}, 'status') !== '429') {
|
||||||
|
@ -71,13 +71,13 @@ export default Component.extend({
|
||||||
// we only need errors here as this only uses proxies which
|
// we only need errors here as this only uses proxies which
|
||||||
// automatically update their data
|
// automatically update their data
|
||||||
const remove = this._listeners.add(this.source, {
|
const remove = this._listeners.add(this.source, {
|
||||||
error: e => {
|
error: (e) => {
|
||||||
error(e);
|
error(e);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
replace(this, '_remove', remove);
|
replace(this, '_remove', remove);
|
||||||
},
|
},
|
||||||
close: function() {
|
close: function () {
|
||||||
if (typeof this.source !== 'undefined') {
|
if (typeof this.source !== 'undefined') {
|
||||||
this.data.close(this.source, this);
|
this.data.close(this.source, this);
|
||||||
replace(this, '_remove', undefined);
|
replace(this, '_remove', undefined);
|
||||||
|
|
|
@ -6,10 +6,10 @@ import { alias } from '@ember/object/computed';
|
||||||
const propRe = /([^[\]])+/g;
|
const propRe = /([^[\]])+/g;
|
||||||
export default Component.extend(Slotted, {
|
export default Component.extend(Slotted, {
|
||||||
tagName: '',
|
tagName: '',
|
||||||
onreset: function() {},
|
onreset: function () {},
|
||||||
onchange: function() {},
|
onchange: function () {},
|
||||||
onerror: function() {},
|
onerror: function () {},
|
||||||
onsuccess: function() {},
|
onsuccess: function () {},
|
||||||
|
|
||||||
data: alias('form.data'),
|
data: alias('form.data'),
|
||||||
item: alias('form.data'),
|
item: alias('form.data'),
|
||||||
|
@ -20,7 +20,7 @@ export default Component.extend(Slotted, {
|
||||||
container: service('form'),
|
container: service('form'),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
change: function(e, value, item) {
|
change: function (e, value, item) {
|
||||||
let event = this.dom.normalizeEvent(e, value);
|
let event = this.dom.normalizeEvent(e, value);
|
||||||
// currently form-components don't deal with deeply nested forms, only top level
|
// currently form-components don't deal with deeply nested forms, only top level
|
||||||
// we therefore grab the end of the nest off here,
|
// we therefore grab the end of the nest off here,
|
||||||
|
|
|
@ -21,15 +21,12 @@ export default class Element extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
get prop() {
|
get prop() {
|
||||||
return `${this.args.name
|
return `${this.args.name.toLowerCase().split('.').join('-')}`;
|
||||||
.toLowerCase()
|
|
||||||
.split('.')
|
|
||||||
.join('-')}`;
|
|
||||||
}
|
}
|
||||||
get state() {
|
get state() {
|
||||||
const error = this.touched && this.args.error;
|
const error = this.touched && this.args.error;
|
||||||
return {
|
return {
|
||||||
matches: name => name === 'error' && error,
|
matches: (name) => name === 'error' && error,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export default triggerable => () => {
|
export default (triggerable) => () => {
|
||||||
return {
|
return {
|
||||||
...{
|
...{
|
||||||
search: triggerable('keypress', '[name="s"]'),
|
search: triggerable('keypress', '[name="s"]'),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export default (collection, clickable, attribute, is, authForm, emptyState) => scope => {
|
export default (collection, clickable, attribute, is, authForm, emptyState) => (scope) => {
|
||||||
const page = {
|
const page = {
|
||||||
navigation: [
|
navigation: [
|
||||||
'services',
|
'services',
|
||||||
|
@ -12,7 +12,7 @@ export default (collection, clickable, attribute, is, authForm, emptyState) => s
|
||||||
'settings',
|
'settings',
|
||||||
'auth',
|
'auth',
|
||||||
].reduce(
|
].reduce(
|
||||||
function(prev, item, i, arr) {
|
function (prev, item, i, arr) {
|
||||||
const key = item;
|
const key = item;
|
||||||
return Object.assign({}, prev, {
|
return Object.assign({}, prev, {
|
||||||
[key]: clickable(`[data-test-main-nav-${item}] > *`),
|
[key]: clickable(`[data-test-main-nav-${item}] > *`),
|
||||||
|
@ -23,7 +23,7 @@ export default (collection, clickable, attribute, is, authForm, emptyState) => s
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
footer: ['copyright', 'docs'].reduce(
|
footer: ['copyright', 'docs'].reduce(
|
||||||
function(prev, item, i, arr) {
|
function (prev, item, i, arr) {
|
||||||
const key = item;
|
const key = item;
|
||||||
return Object.assign({}, prev, {
|
return Object.assign({}, prev, {
|
||||||
[key]: clickable(`[data-test-main-nav-${item}`),
|
[key]: clickable(`[data-test-main-nav-${item}`),
|
||||||
|
|
|
@ -18,19 +18,19 @@ export default class JWTSource extends Component {
|
||||||
// TODO: Could this use once? Double check but I don't think it can
|
// TODO: Could this use once? Double check but I don't think it can
|
||||||
this.source = fromPromise(this.repo.findCodeByURL(this.args.src));
|
this.source = fromPromise(this.repo.findCodeByURL(this.args.src));
|
||||||
this._listeners.add(this.source, {
|
this._listeners.add(this.source, {
|
||||||
message: e => this.onchange(e),
|
message: (e) => this.onchange(e),
|
||||||
error: e => this.onerror(e),
|
error: (e) => this.onerror(e),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onchange(e) {
|
onchange(e) {
|
||||||
if(typeof this.args.onchange === 'function') {
|
if (typeof this.args.onchange === 'function') {
|
||||||
this.args.onchange(...arguments);
|
this.args.onchange(...arguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onerror(e) {
|
onerror(e) {
|
||||||
if(typeof this.args.onerror === 'function') {
|
if (typeof this.args.onerror === 'function') {
|
||||||
this.args.onerror(...arguments);
|
this.args.onerror(...arguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,19 +13,19 @@ export default Component.extend(Slotted, {
|
||||||
cellHeight: 70,
|
cellHeight: 70,
|
||||||
checked: null,
|
checked: null,
|
||||||
scroll: 'virtual',
|
scroll: 'virtual',
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.columns = [100];
|
this.columns = [100];
|
||||||
this.guid = this.dom.guid(this);
|
this.guid = this.dom.guid(this);
|
||||||
},
|
},
|
||||||
didInsertElement: function() {
|
didInsertElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.$element = this.dom.element(`#${this.guid}`);
|
this.$element = this.dom.element(`#${this.guid}`);
|
||||||
if (this.scroll === 'virtual') {
|
if (this.scroll === 'virtual') {
|
||||||
this.actions.resize.apply(this, [{ target: this.dom.viewport() }]);
|
this.actions.resize.apply(this, [{ target: this.dom.viewport() }]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
didReceiveAttrs: function() {
|
didReceiveAttrs: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this._cellLayout = this['cell-layout'] = new PercentageColumns(
|
this._cellLayout = this['cell-layout'] = new PercentageColumns(
|
||||||
get(this, 'items.length'),
|
get(this, 'items.length'),
|
||||||
|
@ -33,7 +33,7 @@ export default Component.extend(Slotted, {
|
||||||
get(this, 'cellHeight')
|
get(this, 'cellHeight')
|
||||||
);
|
);
|
||||||
const o = this;
|
const o = this;
|
||||||
this['cell-layout'].formatItemStyle = function(itemIndex) {
|
this['cell-layout'].formatItemStyle = function (itemIndex) {
|
||||||
let style = formatItemStyle.apply(this, arguments);
|
let style = formatItemStyle.apply(this, arguments);
|
||||||
if (o.checked === itemIndex) {
|
if (o.checked === itemIndex) {
|
||||||
style = `${style};z-index: 1`;
|
style = `${style};z-index: 1`;
|
||||||
|
@ -41,7 +41,7 @@ export default Component.extend(Slotted, {
|
||||||
return style;
|
return style;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
style: computed('height', function() {
|
style: computed('height', function () {
|
||||||
if (this.scroll !== 'virtual') {
|
if (this.scroll !== 'virtual') {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ export default Component.extend(Slotted, {
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
resize: function(e) {
|
resize: function (e) {
|
||||||
// TODO: This top part is very similar to resize in tabular-collection
|
// TODO: This top part is very similar to resize in tabular-collection
|
||||||
// see if it make sense to DRY out
|
// see if it make sense to DRY out
|
||||||
const dom = get(this, 'dom');
|
const dom = get(this, 'dom');
|
||||||
|
@ -65,10 +65,10 @@ export default Component.extend(Slotted, {
|
||||||
this.updateScrollPosition();
|
this.updateScrollPosition();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
click: function(e) {
|
click: function (e) {
|
||||||
return this.dom.clickFirstAnchor(e, '.list-collection > ul > li');
|
return this.dom.clickFirstAnchor(e, '.list-collection > ul > li');
|
||||||
},
|
},
|
||||||
change: function(index, e = {}) {
|
change: function (index, e = {}) {
|
||||||
if (e.target.checked && index !== get(this, 'checked')) {
|
if (e.target.checked && index !== get(this, 'checked')) {
|
||||||
set(this, 'checked', parseInt(index));
|
set(this, 'checked', parseInt(index));
|
||||||
this.$row = this.dom.closest('li', e.target);
|
this.$row = this.dom.closest('li', e.target);
|
||||||
|
|
|
@ -10,9 +10,9 @@ export default Component.extend(Slotted, {
|
||||||
dom: service('dom'),
|
dom: service('dom'),
|
||||||
isConfirmation: false,
|
isConfirmation: false,
|
||||||
actions: {
|
actions: {
|
||||||
connect: function($el) {
|
connect: function ($el) {
|
||||||
next(() => {
|
next(() => {
|
||||||
if(!this.isDestroyed) {
|
if (!this.isDestroyed) {
|
||||||
// if theres only a single choice in the menu and it doesn't have an
|
// if theres only a single choice in the menu and it doesn't have an
|
||||||
// immediate button/link/label to click then it will be a
|
// immediate button/link/label to click then it will be a
|
||||||
// confirmation/informed action
|
// confirmation/informed action
|
||||||
|
@ -24,7 +24,7 @@ export default Component.extend(Slotted, {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
change: function(e) {
|
change: function (e) {
|
||||||
const id = e.target.getAttribute('id');
|
const id = e.target.getAttribute('id');
|
||||||
const $trigger = this.dom.element(`[for='${id}']`);
|
const $trigger = this.dom.element(`[for='${id}']`);
|
||||||
const $panel = this.dom.element('[role=menu]', $trigger.parentElement);
|
const $panel = this.dom.element('[role=menu]', $trigger.parentElement);
|
||||||
|
|
|
@ -6,31 +6,31 @@ import { schedule } from '@ember/runloop';
|
||||||
|
|
||||||
export default Component.extend(Slotted, {
|
export default Component.extend(Slotted, {
|
||||||
tagName: '',
|
tagName: '',
|
||||||
onclose: function() {},
|
onclose: function () {},
|
||||||
onopen: function() {},
|
onopen: function () {},
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
actions: {
|
actions: {
|
||||||
connect: function($el) {
|
connect: function ($el) {
|
||||||
this.dialog = new A11yDialog($el);
|
this.dialog = new A11yDialog($el);
|
||||||
this.dialog.on('hide', () => {
|
this.dialog.on('hide', () => {
|
||||||
schedule('afterRender', _ => set(this, 'isOpen', false));
|
schedule('afterRender', (_) => set(this, 'isOpen', false));
|
||||||
this.onclose({ target: $el })
|
this.onclose({ target: $el });
|
||||||
});
|
});
|
||||||
this.dialog.on('show', () => {
|
this.dialog.on('show', () => {
|
||||||
set(this, 'isOpen', true)
|
set(this, 'isOpen', true);
|
||||||
this.onopen({ target: $el })
|
this.onopen({ target: $el });
|
||||||
});
|
});
|
||||||
if (this.open) {
|
if (this.open) {
|
||||||
this.actions.open.apply(this, []);
|
this.actions.open.apply(this, []);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
disconnect: function($el) {
|
disconnect: function ($el) {
|
||||||
this.dialog.destroy();
|
this.dialog.destroy();
|
||||||
},
|
},
|
||||||
open: function() {
|
open: function () {
|
||||||
this.dialog.show();
|
this.dialog.show();
|
||||||
},
|
},
|
||||||
close: function() {
|
close: function () {
|
||||||
this.dialog.hide();
|
this.dialog.hide();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -59,7 +59,7 @@ export default class Outlet extends Component {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'model':
|
case 'model':
|
||||||
if(typeof this.route !== 'undefined') {
|
if (typeof this.route !== 'undefined') {
|
||||||
this.route._model = value;
|
this.route._model = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import Component from '@glimmer/component';
|
import Component from '@glimmer/component';
|
||||||
import { action } from '@ember/object';
|
import { action } from '@ember/object';
|
||||||
import { tracked } from '@glimmer/tracking';
|
import { tracked } from '@glimmer/tracking';
|
||||||
|
import { scheduleOnce } from '@ember/runloop';
|
||||||
|
|
||||||
export default class PagedCollectionComponent extends Component {
|
export default class PagedCollectionComponent extends Component {
|
||||||
|
|
||||||
@tracked $pane;
|
@tracked $pane;
|
||||||
@tracked $viewport;
|
@tracked $viewport;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ export default class PagedCollectionComponent extends Component {
|
||||||
get perPage() {
|
get perPage() {
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
case 'virtual-scroll':
|
case 'virtual-scroll':
|
||||||
return this.visibleItems + (this.overflow * 2);
|
return this.visibleItems + this.overflow * 2;
|
||||||
case 'index':
|
case 'index':
|
||||||
return parseInt(this.args.perPage);
|
return parseInt(this.args.perPage);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ export default class PagedCollectionComponent extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
get itemsBefore() {
|
get itemsBefore() {
|
||||||
if(typeof this.$viewport === 'undefined') {
|
if (typeof this.$viewport === 'undefined') {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return Math.max(0, Math.round(this.top / this.rowHeight) - this.overflow);
|
return Math.max(0, Math.round(this.top / this.rowHeight) - this.overflow);
|
||||||
|
@ -84,7 +84,7 @@ export default class PagedCollectionComponent extends Component {
|
||||||
|
|
||||||
@action
|
@action
|
||||||
resize() {
|
resize() {
|
||||||
if(this.$viewport.clientHeight > 0 && this.rowHeight > 0) {
|
if (this.$viewport.clientHeight > 0 && this.rowHeight > 0) {
|
||||||
this.visibleItems = Math.ceil(this.$viewport.clientHeight / this.rowHeight);
|
this.visibleItems = Math.ceil(this.$viewport.clientHeight / this.rowHeight);
|
||||||
} else {
|
} else {
|
||||||
this.visibleItems = 0;
|
this.visibleItems = 0;
|
||||||
|
@ -93,9 +93,10 @@ export default class PagedCollectionComponent extends Component {
|
||||||
|
|
||||||
@action
|
@action
|
||||||
setViewport($viewport) {
|
setViewport($viewport) {
|
||||||
this.$viewport = $viewport === 'html' ? [...document.getElementsByTagName('html')][0] : $viewport;
|
this.$viewport =
|
||||||
|
$viewport === 'html' ? [...document.getElementsByTagName('html')][0] : $viewport;
|
||||||
this.$viewport.addEventListener('scroll', this.scroll);
|
this.$viewport.addEventListener('scroll', this.scroll);
|
||||||
if($viewport === 'html') {
|
if ($viewport === 'html') {
|
||||||
this.$viewport.addEventListener('resize', this.resize);
|
this.$viewport.addEventListener('resize', this.resize);
|
||||||
}
|
}
|
||||||
this.scroll();
|
this.scroll();
|
||||||
|
@ -111,8 +112,13 @@ export default class PagedCollectionComponent extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
@action setMaxHeight(str) {
|
@action setMaxHeight(str) {
|
||||||
|
scheduleOnce('actions', this, '_setMaxHeight');
|
||||||
|
}
|
||||||
|
|
||||||
|
@action _setMaxHeight(str) {
|
||||||
const maxHeight = parseFloat(str);
|
const maxHeight = parseFloat(str);
|
||||||
if(!isNaN(maxHeight)) {
|
|
||||||
|
if (!isNaN(maxHeight)) {
|
||||||
this._type = 'virtual-scroll';
|
this._type = 'virtual-scroll';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ const BADGE_LOOKUP = {
|
||||||
tooltip: 'Someone in the other peer may have deleted this peering connection.',
|
tooltip: 'Someone in the other peer may have deleted this peering connection.',
|
||||||
},
|
},
|
||||||
UNDEFINED: {
|
UNDEFINED: {
|
||||||
tooltip: ''
|
tooltip: '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
export default class PeeringsBadge extends Component {
|
export default class PeeringsBadge extends Component {
|
||||||
|
|
|
@ -8,7 +8,7 @@ export default FormComponent.extend({
|
||||||
classNames: ['policy-form'],
|
classNames: ['policy-form'],
|
||||||
|
|
||||||
isScoped: false,
|
isScoped: false,
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
set(this, 'isScoped', get(this, 'item.Datacenters.length') > 0);
|
set(this, 'isScoped', get(this, 'item.Datacenters.length') > 0);
|
||||||
this.templates = [
|
this.templates = [
|
||||||
|
@ -27,7 +27,7 @@ export default FormComponent.extend({
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
change: function(e) {
|
change: function (e) {
|
||||||
try {
|
try {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
export default (submitable, cancelable, radiogroup, text) => (
|
export default (submitable, cancelable, radiogroup, text) =>
|
||||||
scope = '[data-test-policy-form]'
|
(scope = '[data-test-policy-form]') => {
|
||||||
) => {
|
return {
|
||||||
return {
|
// this should probably be settable
|
||||||
// this should probably be settable
|
resetScope: true,
|
||||||
resetScope: true,
|
scope: scope,
|
||||||
scope: scope,
|
prefix: 'policy',
|
||||||
prefix: 'policy',
|
...submitable(),
|
||||||
...submitable(),
|
...cancelable(),
|
||||||
...cancelable(),
|
...radiogroup('template', ['', 'service-identity', 'node-identity'], 'policy'),
|
||||||
...radiogroup('template', ['', 'service-identity', 'node-identity'], 'policy'),
|
rules: {
|
||||||
rules: {
|
error: text('[data-test-rules] strong'),
|
||||||
error: text('[data-test-rules] strong'),
|
},
|
||||||
},
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<label
|
<label
|
||||||
class="type-dialog"
|
class="type-dialog"
|
||||||
data-test-policy-create
|
data-test-policy-create
|
||||||
{{on "click" (optional this.modal.open)}}
|
{{on "click" (action this.openModal)}}
|
||||||
>
|
>
|
||||||
<span>Create new policy</span>
|
<span>Create new policy</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -12,26 +12,26 @@ export default ChildSelectorComponent.extend({
|
||||||
type: 'policy',
|
type: 'policy',
|
||||||
allowIdentity: true,
|
allowIdentity: true,
|
||||||
classNames: ['policy-selector'],
|
classNames: ['policy-selector'],
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
const source = this.source;
|
const source = this.source;
|
||||||
if (source) {
|
if (source) {
|
||||||
this._listeners.add(source, {
|
this._listeners.add(source, {
|
||||||
save: e => {
|
save: (e) => {
|
||||||
this.save.perform(...e.data);
|
this.save.perform(...e.data);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
reset: function(e) {
|
reset: function (e) {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
set(this, 'isScoped', false);
|
set(this, 'isScoped', false);
|
||||||
},
|
},
|
||||||
refreshCodeEditor: function(e, target) {
|
refreshCodeEditor: function (e, target) {
|
||||||
const selector = '.code-editor';
|
const selector = '.code-editor';
|
||||||
this.dom.component(selector, target).didAppear();
|
this.dom.component(selector, target).didAppear();
|
||||||
},
|
},
|
||||||
error: function(e) {
|
error: function (e) {
|
||||||
const item = this.item;
|
const item = this.item;
|
||||||
const err = e.error;
|
const err = e.error;
|
||||||
if (typeof err.errors !== 'undefined') {
|
if (typeof err.errors !== 'undefined') {
|
||||||
|
@ -57,8 +57,15 @@ export default ChildSelectorComponent.extend({
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
openModal: function () {
|
||||||
|
const { modal } = this;
|
||||||
|
|
||||||
|
if (modal) {
|
||||||
|
modal.open();
|
||||||
|
}
|
||||||
|
},
|
||||||
actions: {
|
actions: {
|
||||||
open: function(e) {
|
open: function (e) {
|
||||||
this.refreshCodeEditor(e, e.target.parentElement);
|
this.refreshCodeEditor(e, e.target.parentElement);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
export default (clickable, deletable, collection, alias, policyForm) => (
|
export default (clickable, deletable, collection, alias, policyForm) =>
|
||||||
scope = '#policies',
|
(scope = '#policies', createSelector = '[data-test-policy-create]') => {
|
||||||
createSelector = '[data-test-policy-create]'
|
return {
|
||||||
) => {
|
scope: scope,
|
||||||
return {
|
create: clickable(createSelector),
|
||||||
scope: scope,
|
form: policyForm('#new-policy'),
|
||||||
create: clickable(createSelector),
|
policies: alias('selectedOptions'),
|
||||||
form: policyForm('#new-policy'),
|
selectedOptions: collection(
|
||||||
policies: alias('selectedOptions'),
|
'[data-test-policies] [data-test-tabular-row]',
|
||||||
selectedOptions: collection(
|
deletable(
|
||||||
'[data-test-policies] [data-test-tabular-row]',
|
{
|
||||||
deletable(
|
expand: clickable('label'),
|
||||||
{
|
},
|
||||||
expand: clickable('label'),
|
'+ tr'
|
||||||
},
|
)
|
||||||
'+ tr'
|
),
|
||||||
)
|
};
|
||||||
),
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
|
@ -9,32 +9,32 @@ export default Component.extend(Slotted, {
|
||||||
dom: service('dom'),
|
dom: service('dom'),
|
||||||
expanded: false,
|
expanded: false,
|
||||||
keyboardAccess: true,
|
keyboardAccess: true,
|
||||||
onchange: function() {},
|
onchange: function () {},
|
||||||
// TODO: this needs to be made dynamic/auto detect
|
// TODO: this needs to be made dynamic/auto detect
|
||||||
// for now use this to set left/right explicitly
|
// for now use this to set left/right explicitly
|
||||||
position: '',
|
position: '',
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.guid = this.dom.guid(this);
|
this.guid = this.dom.guid(this);
|
||||||
this.submenus = [];
|
this.submenus = [];
|
||||||
},
|
},
|
||||||
willRender: function() {
|
willRender: function () {
|
||||||
set(this, 'hasHeader', this._isRegistered('header'));
|
set(this, 'hasHeader', this._isRegistered('header'));
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
addSubmenu: function(name) {
|
addSubmenu: function (name) {
|
||||||
set(this, 'submenus', this.submenus.concat(name));
|
set(this, 'submenus', this.submenus.concat(name));
|
||||||
},
|
},
|
||||||
removeSubmenu: function(name) {
|
removeSubmenu: function (name) {
|
||||||
const pos = this.submenus.indexOf(name);
|
const pos = this.submenus.indexOf(name);
|
||||||
if (pos !== -1) {
|
if (pos !== -1) {
|
||||||
this.submenus.splice(pos, 1);
|
this.submenus.splice(pos, 1);
|
||||||
set(this, 'submenus', this.submenus);
|
set(this, 'submenus', this.submenus);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
change: function(e) {
|
change: function (e) {
|
||||||
if (!e.target.checked) {
|
if (!e.target.checked) {
|
||||||
[...this.dom.elements(`[id^=popover-menu-${this.guid}]`)].forEach(function($item) {
|
[...this.dom.elements(`[id^=popover-menu-${this.guid}]`)].forEach(function ($item) {
|
||||||
$item.checked = false;
|
$item.checked = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ export default Component.extend(Slotted, {
|
||||||
// Temporary send here so we can send route actions
|
// Temporary send here so we can send route actions
|
||||||
// easily. It kind of makes sense that you'll want to perform
|
// easily. It kind of makes sense that you'll want to perform
|
||||||
// route actions from a popup menu for the moment
|
// route actions from a popup menu for the moment
|
||||||
send: function() {
|
send: function () {
|
||||||
this.sendAction(...arguments);
|
this.sendAction(...arguments);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,19 +7,19 @@ import Slotted from 'block-slots';
|
||||||
export default Component.extend(Slotted, {
|
export default Component.extend(Slotted, {
|
||||||
tagName: '',
|
tagName: '',
|
||||||
dom: service('dom'),
|
dom: service('dom'),
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.guid = this.dom.guid(this);
|
this.guid = this.dom.guid(this);
|
||||||
},
|
},
|
||||||
didInsertElement: function() {
|
didInsertElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.menu.addSubmenu(this.guid);
|
this.menu.addSubmenu(this.guid);
|
||||||
},
|
},
|
||||||
didDestroyElement: function() {
|
didDestroyElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.menu.removeSubmenu(this.guid);
|
this.menu.removeSubmenu(this.guid);
|
||||||
},
|
},
|
||||||
willRender: function() {
|
willRender: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
set(this, 'hasConfirmation', this._isRegistered('confirmation'));
|
set(this, 'hasConfirmation', this._isRegistered('confirmation'));
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,31 +7,31 @@ export default Component.extend(Slotted, {
|
||||||
dom: service('dom'),
|
dom: service('dom'),
|
||||||
multiple: false,
|
multiple: false,
|
||||||
required: false,
|
required: false,
|
||||||
onchange: function() {},
|
onchange: function () {},
|
||||||
addOption: function(option) {
|
addOption: function (option) {
|
||||||
if (typeof this._options === 'undefined') {
|
if (typeof this._options === 'undefined') {
|
||||||
this._options = new Set();
|
this._options = new Set();
|
||||||
}
|
}
|
||||||
this._options.add(option);
|
this._options.add(option);
|
||||||
},
|
},
|
||||||
removeOption: function(option) {
|
removeOption: function (option) {
|
||||||
this._options.delete(option);
|
this._options.delete(option);
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
click: function(option, e) {
|
click: function (option, e) {
|
||||||
// required={{true}} ?
|
// required={{true}} ?
|
||||||
if (!this.multiple) {
|
if (!this.multiple) {
|
||||||
if (option.selected && this.required) {
|
if (option.selected && this.required) {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
[...this._options]
|
[...this._options]
|
||||||
.filter(item => item !== option)
|
.filter((item) => item !== option)
|
||||||
.forEach(item => {
|
.forEach((item) => {
|
||||||
item.selected = false;
|
item.selected = false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (option.selected && this.required) {
|
if (option.selected && this.required) {
|
||||||
const other = [...this._options].find(item => item !== option && item.selected);
|
const other = [...this._options].find((item) => item !== option && item.selected);
|
||||||
if (!other) {
|
if (!other) {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
@ -40,11 +40,11 @@ export default Component.extend(Slotted, {
|
||||||
option.selected = !option.selected;
|
option.selected = !option.selected;
|
||||||
this.onchange(
|
this.onchange(
|
||||||
this.dom.setEventTargetProperties(e, {
|
this.dom.setEventTargetProperties(e, {
|
||||||
selected: target => option.args.value,
|
selected: (target) => option.args.value,
|
||||||
selectedItems: target => {
|
selectedItems: (target) => {
|
||||||
return [...this._options]
|
return [...this._options]
|
||||||
.filter(item => item.selected)
|
.filter((item) => item.selected)
|
||||||
.map(item => item.args.value)
|
.map((item) => item.args.value)
|
||||||
.join(',');
|
.join(',');
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
export default (clickable, collection) => (scope = '.popover-select') => {
|
export default (clickable, collection) =>
|
||||||
return {
|
(scope = '.popover-select') => {
|
||||||
scope: scope,
|
return {
|
||||||
selected: clickable('button'),
|
scope: scope,
|
||||||
options: collection('li[role="none"]', {
|
selected: clickable('button'),
|
||||||
button: clickable('button'),
|
options: collection('li[role="none"]', {
|
||||||
}),
|
button: clickable('button'),
|
||||||
|
}),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { clickable, isPresent } from 'ember-cli-page-object';
|
import { clickable, isPresent } from 'ember-cli-page-object';
|
||||||
|
|
||||||
export default options => {
|
export default (options) => {
|
||||||
return {
|
return {
|
||||||
present: isPresent('.ember-power-select-trigger'),
|
present: isPresent('.ember-power-select-trigger'),
|
||||||
click: clickable('.ember-power-select-trigger'),
|
click: clickable('.ember-power-select-trigger'),
|
||||||
|
|
|
@ -6,19 +6,19 @@ export default Component.extend({
|
||||||
tagName: '',
|
tagName: '',
|
||||||
keyboardAccess: false,
|
keyboardAccess: false,
|
||||||
dom: service('dom'),
|
dom: service('dom'),
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.name = this.dom.guid(this);
|
this.name = this.dom.guid(this);
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
keydown: function(e) {
|
keydown: function (e) {
|
||||||
if (e.keyCode === ENTER) {
|
if (e.keyCode === ENTER) {
|
||||||
e.target.dispatchEvent(new MouseEvent('click'));
|
e.target.dispatchEvent(new MouseEvent('click'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
change: function(e) {
|
change: function (e) {
|
||||||
this.onchange(
|
this.onchange(
|
||||||
this.dom.setEventTargetProperty(e, 'value', value => (value === '' ? undefined : value))
|
this.dom.setEventTargetProperty(e, 'value', (value) => (value === '' ? undefined : value))
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,14 +2,14 @@ import { is, clickable } from 'ember-cli-page-object';
|
||||||
import ucfirst from 'consul-ui/utils/ucfirst';
|
import ucfirst from 'consul-ui/utils/ucfirst';
|
||||||
// TODO: We no longer need to use name here
|
// TODO: We no longer need to use name here
|
||||||
// remove the arg in all objects
|
// remove the arg in all objects
|
||||||
export default function(name, items, blankKey = 'all') {
|
export default function (name, items, blankKey = 'all') {
|
||||||
return items.reduce(function(prev, item, i, arr) {
|
return items.reduce(function (prev, item, i, arr) {
|
||||||
// if item is empty then it means 'all'
|
// if item is empty then it means 'all'
|
||||||
// otherwise camelCase based on something-here = somethingHere for the key
|
// otherwise camelCase based on something-here = somethingHere for the key
|
||||||
const key =
|
const key =
|
||||||
item === ''
|
item === ''
|
||||||
? blankKey
|
? blankKey
|
||||||
: item.split('-').reduce(function(prev, item, i, arr) {
|
: item.split('-').reduce(function (prev, item, i, arr) {
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { set } from '@ember/object';
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
tagName: '',
|
tagName: '',
|
||||||
didReceiveAttrs: function() {
|
didReceiveAttrs: function () {
|
||||||
set(this.target, this.name, this.value);
|
set(this.target, this.name, this.value);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,20 +15,20 @@ export default ChildSelectorComponent.extend({
|
||||||
// You have to alias data.
|
// You have to alias data.
|
||||||
// If you just set it, it loses its reference?
|
// If you just set it, it loses its reference?
|
||||||
policy: alias('policyForm.data'),
|
policy: alias('policyForm.data'),
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.policyForm = this.formContainer.form('policy');
|
set(this, 'policyForm', this.formContainer.form('policy'));
|
||||||
this.source = new EventSource();
|
this.source = new EventSource();
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
reset: function(e) {
|
reset: function (e) {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.policyForm.clear({ Datacenter: this.dc });
|
this.policyForm.clear({ Datacenter: this.dc });
|
||||||
},
|
},
|
||||||
dispatch: function(type, data) {
|
dispatch: function (type, data) {
|
||||||
this.source.dispatchEvent({ type: type, data: data });
|
this.source.dispatchEvent({ type: type, data: data });
|
||||||
},
|
},
|
||||||
change: function() {
|
change: function () {
|
||||||
const event = this.dom.normalizeEvent(...arguments);
|
const event = this.dom.normalizeEvent(...arguments);
|
||||||
const target = event.target;
|
const target = event.target;
|
||||||
switch (target.name) {
|
switch (target.name) {
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
export default (clickable, deletable, collection, alias, roleForm) => (scope = '#roles') => {
|
export default (clickable, deletable, collection, alias, roleForm) =>
|
||||||
return {
|
(scope = '#roles') => {
|
||||||
scope: scope,
|
return {
|
||||||
create: clickable('[data-test-role-create]'),
|
scope: scope,
|
||||||
form: roleForm(),
|
create: clickable('[data-test-role-create]'),
|
||||||
roles: alias('selectedOptions'),
|
form: roleForm(),
|
||||||
selectedOptions: collection(
|
roles: alias('selectedOptions'),
|
||||||
'[data-test-roles] [data-test-tabular-row]',
|
selectedOptions: collection('[data-test-roles] [data-test-tabular-row]', {
|
||||||
{
|
|
||||||
actions: clickable('label > button'),
|
actions: clickable('label > button'),
|
||||||
delete: clickable('[data-test-delete]'),
|
delete: clickable('[data-test-delete]'),
|
||||||
confirmDelete: clickable('.informed-action button'),
|
confirmDelete: clickable('.informed-action button'),
|
||||||
}
|
}),
|
||||||
),
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ export default class RouteComponent extends Component {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
this.intlKey = this.encoder.createRegExpEncoder(templateRe, _ => _);
|
this.intlKey = this.encoder.createRegExpEncoder(templateRe, (_) => _);
|
||||||
}
|
}
|
||||||
|
|
||||||
get params() {
|
get params() {
|
||||||
|
@ -27,7 +27,10 @@ export default class RouteComponent extends Component {
|
||||||
}
|
}
|
||||||
if (this.args.name) {
|
if (this.args.name) {
|
||||||
const outlet = this.routlet.outletFor(this.args.name);
|
const outlet = this.routlet.outletFor(this.args.name);
|
||||||
return this.routlet.modelFor(outlet.name);
|
|
||||||
|
if (outlet) {
|
||||||
|
return this.routlet.modelFor(outlet.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export const diff = (a, b) => {
|
export const diff = (a, b) => {
|
||||||
return a.filter(item => !b.includes(item));
|
return a.filter((item) => !b.includes(item));
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* filters accepts the args.filter @attribute which is shaped like
|
* filters accepts the args.filter @attribute which is shaped like
|
||||||
|
@ -11,7 +11,7 @@ export const diff = (a, b) => {
|
||||||
* There is more explanation in the unit tests for this function so thats worthwhile
|
* There is more explanation in the unit tests for this function so thats worthwhile
|
||||||
* checking if you are in amongst this
|
* checking if you are in amongst this
|
||||||
*/
|
*/
|
||||||
export const filters = filters => {
|
export const filters = (filters) => {
|
||||||
return Object.entries(filters)
|
return Object.entries(filters)
|
||||||
.filter(([key, value]) => {
|
.filter(([key, value]) => {
|
||||||
if (key === 'searchproperty') {
|
if (key === 'searchproperty') {
|
||||||
|
@ -21,7 +21,7 @@ export const filters = filters => {
|
||||||
})
|
})
|
||||||
.reduce((prev, [key, value]) => {
|
.reduce((prev, [key, value]) => {
|
||||||
return prev.concat(
|
return prev.concat(
|
||||||
value.value.map(item => {
|
value.value.map((item) => {
|
||||||
const obj = {
|
const obj = {
|
||||||
key: key,
|
key: key,
|
||||||
value: item,
|
value: item,
|
||||||
|
|
|
@ -3,12 +3,10 @@ import { action } from '@ember/object';
|
||||||
import { tracked } from '@glimmer/tracking';
|
import { tracked } from '@glimmer/tracking';
|
||||||
|
|
||||||
export default class ShadowHostComponent extends Component {
|
export default class ShadowHostComponent extends Component {
|
||||||
|
|
||||||
@tracked shadowRoot;
|
@tracked shadowRoot;
|
||||||
|
|
||||||
@action
|
@action
|
||||||
attachShadow($element) {
|
attachShadow($element) {
|
||||||
this.shadowRoot = $element.attachShadow({ mode: 'open' });
|
this.shadowRoot = $element.attachShadow({ mode: 'open' });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,11 @@ import Component from '@ember/component';
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
tagName: '',
|
tagName: '',
|
||||||
didInsertElement: function() {
|
didInsertElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.chart.addAction(this.name, (context, event) => this.exec(context, event));
|
this.chart.addAction(this.name, (context, event) => this.exec(context, event));
|
||||||
},
|
},
|
||||||
willDestroy: function() {
|
willDestroy: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.chart.removeAction(this.type);
|
this.chart.removeAction(this.type);
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,10 +2,10 @@ import Component from '@ember/component';
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
tagName: '',
|
tagName: '',
|
||||||
didInsertElement: function() {
|
didInsertElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
const component = this;
|
const component = this;
|
||||||
this.chart.addGuard(this.name, function() {
|
this.chart.addGuard(this.name, function () {
|
||||||
if (typeof component.cond === 'function') {
|
if (typeof component.cond === 'function') {
|
||||||
return component.cond(...arguments);
|
return component.cond(...arguments);
|
||||||
} else {
|
} else {
|
||||||
|
@ -13,7 +13,7 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
willDestroyElement: function() {
|
willDestroyElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.chart.removeGuard(this.name);
|
this.chart.removeGuard(this.name);
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,13 +5,13 @@ import { set } from '@ember/object';
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
chart: service('state'),
|
chart: service('state'),
|
||||||
tagName: '',
|
tagName: '',
|
||||||
ontransition: function(e) {},
|
ontransition: function (e) {},
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this._actions = {};
|
this._actions = {};
|
||||||
this._guards = {};
|
this._guards = {};
|
||||||
},
|
},
|
||||||
didReceiveAttrs: function() {
|
didReceiveAttrs: function () {
|
||||||
if (typeof this.machine !== 'undefined') {
|
if (typeof this.machine !== 'undefined') {
|
||||||
this.machine.stop();
|
this.machine.stop();
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,11 @@ export default Component.extend({
|
||||||
this.src.initial = this.initial;
|
this.src.initial = this.initial;
|
||||||
}
|
}
|
||||||
this.machine = this.chart.interpret(this.src, {
|
this.machine = this.chart.interpret(this.src, {
|
||||||
onTransition: state => {
|
onTransition: (state) => {
|
||||||
const e = new CustomEvent('transition', { detail: state });
|
const e = new CustomEvent('transition', { detail: state });
|
||||||
this.ontransition(e);
|
this.ontransition(e);
|
||||||
if (!e.defaultPrevented) {
|
if (!e.defaultPrevented) {
|
||||||
state.actions.forEach(item => {
|
state.actions.forEach((item) => {
|
||||||
const action = this._actions[item.type];
|
const action = this._actions[item.type];
|
||||||
if (typeof action === 'function') {
|
if (typeof action === 'function') {
|
||||||
this._actions[item.type](item.type, state.context, state.event);
|
this._actions[item.type](item.type, state.context, state.event);
|
||||||
|
@ -37,35 +37,35 @@ export default Component.extend({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
didInsertElement: function() {
|
didInsertElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
// xstate has initialState xstate/fsm has state
|
// xstate has initialState xstate/fsm has state
|
||||||
set(this, 'state', this.machine.initialState || this.machine.state);
|
set(this, 'state', this.machine.initialState || this.machine.state);
|
||||||
// set(this, 'state', this.machine.initialState);
|
// set(this, 'state', this.machine.initialState);
|
||||||
this.machine.start();
|
this.machine.start();
|
||||||
},
|
},
|
||||||
willDestroy: function() {
|
willDestroy: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.machine.stop();
|
this.machine.stop();
|
||||||
},
|
},
|
||||||
addAction: function(name, value) {
|
addAction: function (name, value) {
|
||||||
this._actions[name] = value;
|
this._actions[name] = value;
|
||||||
},
|
},
|
||||||
removeAction: function(name) {
|
removeAction: function (name) {
|
||||||
delete this._actions[name];
|
delete this._actions[name];
|
||||||
},
|
},
|
||||||
addGuard: function(name, value) {
|
addGuard: function (name, value) {
|
||||||
this._guards[name] = value;
|
this._guards[name] = value;
|
||||||
},
|
},
|
||||||
removeGuard: function(name) {
|
removeGuard: function (name) {
|
||||||
delete this._guards[name];
|
delete this._guards[name];
|
||||||
},
|
},
|
||||||
dispatch: function(eventName, payload) {
|
dispatch: function (eventName, payload) {
|
||||||
this.machine.state.context = payload;
|
this.machine.state.context = payload;
|
||||||
this.machine.send({ type: eventName });
|
this.machine.send({ type: eventName });
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
dispatch: function(eventName, e) {
|
dispatch: function (eventName, e) {
|
||||||
if (e && e.preventDefault) {
|
if (e && e.preventDefault) {
|
||||||
if (typeof e.target.nodeName === 'undefined' || e.target.nodeName.toLowerCase() !== 'a') {
|
if (typeof e.target.nodeName === 'undefined' || e.target.nodeName.toLowerCase() !== 'a') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import Component from '../state-chart/index';
|
import Component from '../state-chart/index';
|
||||||
|
|
||||||
export default Component.extend({});
|
export default Component.extend({});
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,9 @@ export default class State extends Component {
|
||||||
if (typeof state === 'undefined') {
|
if (typeof state === 'undefined') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.render = typeof matches !== 'undefined' ?
|
this.render =
|
||||||
this.state.matches(state, matches) :
|
typeof matches !== 'undefined'
|
||||||
!this.state.matches(state, notMatches);
|
? this.state.matches(state, matches)
|
||||||
|
: !this.state.matches(state, notMatches);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,16 +31,10 @@ as |select name|}}
|
||||||
>
|
>
|
||||||
<Action
|
<Action
|
||||||
{{on 'click'
|
{{on 'click'
|
||||||
(if (not-eq @onclick undefined)
|
(fn this.onClick (uppercase item.label))
|
||||||
(fn @onclick (uppercase item.label))
|
|
||||||
(noop)
|
|
||||||
)
|
|
||||||
}}
|
}}
|
||||||
{{on 'click'
|
{{on 'click'
|
||||||
(if @onTabClicked
|
(fn this.onTabClicked item)
|
||||||
(fn @onTabClicked item)
|
|
||||||
(noop)
|
|
||||||
)
|
|
||||||
}}
|
}}
|
||||||
@href={{item.href}}
|
@href={{item.href}}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
import Component from '@glimmer/component';
|
import Component from '@glimmer/component';
|
||||||
|
|
||||||
export default class TabNav extends Component {}
|
function noop() {}
|
||||||
|
export default class TabNav extends Component {
|
||||||
|
get onClick() {
|
||||||
|
return this.args.onclick || noop;
|
||||||
|
}
|
||||||
|
|
||||||
|
get onTabClicked() {
|
||||||
|
return this.args.onTabClicked || noop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { is, clickable, attribute, isVisible } from 'ember-cli-page-object';
|
import { is, clickable, attribute, isVisible } from 'ember-cli-page-object';
|
||||||
import ucfirst from 'consul-ui/utils/ucfirst';
|
import ucfirst from 'consul-ui/utils/ucfirst';
|
||||||
export default function(name, items, blankKey = 'all') {
|
export default function (name, items, blankKey = 'all') {
|
||||||
return items.reduce(function(prev, item, i, arr) {
|
return items.reduce(function (prev, item, i, arr) {
|
||||||
// if item is empty then it means 'all'
|
// if item is empty then it means 'all'
|
||||||
// otherwise camelCase based on something-here = somethingHere for the key
|
// otherwise camelCase based on something-here = somethingHere for the key
|
||||||
const key =
|
const key =
|
||||||
item === ''
|
item === ''
|
||||||
? blankKey
|
? blankKey
|
||||||
: item.split('-').reduce(function(prev, item, i, arr) {
|
: item.split('-').reduce(function (prev, item, i, arr) {
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,13 @@ export default CollectionComponent.extend(Slotted, {
|
||||||
maxHeight: 500,
|
maxHeight: 500,
|
||||||
checked: null,
|
checked: null,
|
||||||
hasCaption: false,
|
hasCaption: false,
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.guid = this.dom.guid(this);
|
this.guid = this.dom.guid(this);
|
||||||
// TODO: The row height should auto calculate properly from the CSS
|
// TODO: The row height should auto calculate properly from the CSS
|
||||||
const o = this;
|
const o = this;
|
||||||
this['cell-layout'] = new Grid(get(this, 'width'), get(this, 'rowHeight'));
|
this['cell-layout'] = new Grid(get(this, 'width'), get(this, 'rowHeight'));
|
||||||
this['cell-layout'].formatItemStyle = function(itemIndex) {
|
this['cell-layout'].formatItemStyle = function (itemIndex) {
|
||||||
let style = formatItemStyle.apply(this, arguments);
|
let style = formatItemStyle.apply(this, arguments);
|
||||||
if (o.checked === itemIndex) {
|
if (o.checked === itemIndex) {
|
||||||
style = `${style};z-index: 1`;
|
style = `${style};z-index: 1`;
|
||||||
|
@ -29,12 +29,12 @@ export default CollectionComponent.extend(Slotted, {
|
||||||
return style;
|
return style;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
didInsertElement: function() {
|
didInsertElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.$element = this.dom.element(`#${this.guid}`);
|
this.$element = this.dom.element(`#${this.guid}`);
|
||||||
this.actions.resize.apply(this, [{ target: this.dom.viewport() }]);
|
this.actions.resize.apply(this, [{ target: this.dom.viewport() }]);
|
||||||
},
|
},
|
||||||
style: computed('rowHeight', '_items', 'maxRows', 'maxHeight', function() {
|
style: computed('rowHeight', '_items', 'maxRows', 'maxHeight', function () {
|
||||||
const maxRows = get(this, 'rows');
|
const maxRows = get(this, 'rows');
|
||||||
let height = get(this, 'maxHeight');
|
let height = get(this, 'maxHeight');
|
||||||
if (maxRows) {
|
if (maxRows) {
|
||||||
|
@ -46,14 +46,14 @@ export default CollectionComponent.extend(Slotted, {
|
||||||
height: height,
|
height: height,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
willRender: function() {
|
willRender: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
set(this, 'hasCaption', this._isRegistered('caption'));
|
set(this, 'hasCaption', this._isRegistered('caption'));
|
||||||
set(this, 'hasActions', this._isRegistered('actions'));
|
set(this, 'hasActions', this._isRegistered('actions'));
|
||||||
},
|
},
|
||||||
// `ember-collection` bug workaround
|
// `ember-collection` bug workaround
|
||||||
// https://github.com/emberjs/ember-collection/issues/138
|
// https://github.com/emberjs/ember-collection/issues/138
|
||||||
_needsRevalidate: function() {
|
_needsRevalidate: function () {
|
||||||
if (this.isDestroyed || this.isDestroying) {
|
if (this.isDestroyed || this.isDestroying) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ export default CollectionComponent.extend(Slotted, {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
resize: function(e) {
|
resize: function (e) {
|
||||||
const $tbody = this.$element;
|
const $tbody = this.$element;
|
||||||
const $appContent = this.dom.element('.app-view');
|
const $appContent = this.dom.element('.app-view');
|
||||||
if ($appContent) {
|
if ($appContent) {
|
||||||
|
@ -77,7 +77,7 @@ export default CollectionComponent.extend(Slotted, {
|
||||||
// TODO: The row height should auto calculate properly from the CSS
|
// TODO: The row height should auto calculate properly from the CSS
|
||||||
this['cell-layout'] = new Grid($appContent.clientWidth, get(this, 'rowHeight'));
|
this['cell-layout'] = new Grid($appContent.clientWidth, get(this, 'rowHeight'));
|
||||||
const o = this;
|
const o = this;
|
||||||
this['cell-layout'].formatItemStyle = function(itemIndex) {
|
this['cell-layout'].formatItemStyle = function (itemIndex) {
|
||||||
let style = formatItemStyle.apply(this, arguments);
|
let style = formatItemStyle.apply(this, arguments);
|
||||||
if (o.checked === itemIndex) {
|
if (o.checked === itemIndex) {
|
||||||
style = `${style};z-index: 1`;
|
style = `${style};z-index: 1`;
|
||||||
|
@ -88,10 +88,10 @@ export default CollectionComponent.extend(Slotted, {
|
||||||
this.updateScrollPosition();
|
this.updateScrollPosition();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
click: function(e) {
|
click: function (e) {
|
||||||
return this.dom.clickFirstAnchor(e);
|
return this.dom.clickFirstAnchor(e);
|
||||||
},
|
},
|
||||||
change: function(index, e = {}) {
|
change: function (index, e = {}) {
|
||||||
if (this.$tr) {
|
if (this.$tr) {
|
||||||
this.$tr.style.zIndex = null;
|
this.$tr.style.zIndex = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,16 @@ import Slotted from 'block-slots';
|
||||||
|
|
||||||
export default Component.extend(Slotted, {
|
export default Component.extend(Slotted, {
|
||||||
dom: service('dom'),
|
dom: service('dom'),
|
||||||
onchange: function() {},
|
onchange: function () {},
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.guid = this.dom.guid(this);
|
this.guid = this.dom.guid(this);
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
click: function(e) {
|
click: function (e) {
|
||||||
this.dom.clickFirstAnchor(e);
|
this.dom.clickFirstAnchor(e);
|
||||||
},
|
},
|
||||||
change: function(item, items, e) {
|
change: function (item, items, e) {
|
||||||
this.onchange(e, item, items);
|
this.onchange(e, item, items);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,19 +5,19 @@ export default Component.extend({
|
||||||
dom: service('dom'),
|
dom: service('dom'),
|
||||||
tagName: '',
|
tagName: '',
|
||||||
checked: false,
|
checked: false,
|
||||||
onchange: function() {},
|
onchange: function () {},
|
||||||
// TODO: reserved for the moment but we don't need it yet
|
// TODO: reserved for the moment but we don't need it yet
|
||||||
onblur: function() {},
|
onblur: function () {},
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.guid = this.dom.guid(this);
|
this.guid = this.dom.guid(this);
|
||||||
this._listeners = this.dom.listeners();
|
this._listeners = this.dom.listeners();
|
||||||
},
|
},
|
||||||
willDestroyElement: function() {
|
willDestroyElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this._listeners.remove();
|
this._listeners.remove();
|
||||||
},
|
},
|
||||||
didReceiveAttrs: function() {
|
didReceiveAttrs: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
if (this.checked) {
|
if (this.checked) {
|
||||||
this.addClickOutsideListener();
|
this.addClickOutsideListener();
|
||||||
|
@ -25,10 +25,10 @@ export default Component.extend({
|
||||||
this._listeners.remove();
|
this._listeners.remove();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addClickOutsideListener: function() {
|
addClickOutsideListener: function () {
|
||||||
// default onblur event
|
// default onblur event
|
||||||
this._listeners.remove();
|
this._listeners.remove();
|
||||||
this._listeners.add(this.dom.document(), 'click', e => {
|
this._listeners.add(this.dom.document(), 'click', (e) => {
|
||||||
if (this.dom.isOutside(this.label, e.target)) {
|
if (this.dom.isOutside(this.label, e.target)) {
|
||||||
if (this.dom.isOutside(this.label.nextElementSibling, e.target)) {
|
if (this.dom.isOutside(this.label.nextElementSibling, e.target)) {
|
||||||
if (this.input.checked) {
|
if (this.input.checked) {
|
||||||
|
@ -42,7 +42,7 @@ export default Component.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
click: function(e) {
|
click: function (e) {
|
||||||
// only preventDefault if the target isn't an external link
|
// only preventDefault if the target isn't an external link
|
||||||
// TODO: this should be changed for an explicit close
|
// TODO: this should be changed for an explicit close
|
||||||
if ((e.target.rel || '').indexOf('noopener') === -1) {
|
if ((e.target.rel || '').indexOf('noopener') === -1) {
|
||||||
|
@ -56,7 +56,7 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
this.actions.change.apply(this, [e]);
|
this.actions.change.apply(this, [e]);
|
||||||
},
|
},
|
||||||
change: function(e) {
|
change: function (e) {
|
||||||
if (this.input.checked) {
|
if (this.input.checked) {
|
||||||
this.addClickOutsideListener();
|
this.addClickOutsideListener();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ export default class TokenSource extends Component {
|
||||||
|
|
||||||
@action
|
@action
|
||||||
change(e) {
|
change(e) {
|
||||||
e.data.toJSON = function() {
|
e.data.toJSON = function () {
|
||||||
return {
|
return {
|
||||||
AccessorID: this.AccessorID,
|
AccessorID: this.AccessorID,
|
||||||
// TODO: In the past we've always ignored the SecretID returned
|
// TODO: In the past we've always ignored the SecretID returned
|
||||||
|
@ -39,9 +39,8 @@ export default class TokenSource extends Component {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
// TODO: We should probably put the component into idle state
|
// TODO: We should probably put the component into idle state
|
||||||
if(typeof this.args.onchange === 'function') {
|
if (typeof this.args.onchange === 'function') {
|
||||||
this.args.onchange(e);
|
this.args.onchange(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ export default class TopoloyMetricsDownLines extends Component {
|
||||||
const view = this.args.view;
|
const view = this.args.view;
|
||||||
const lines = [...document.querySelectorAll('#downstream-lines path')];
|
const lines = [...document.querySelectorAll('#downstream-lines path')];
|
||||||
|
|
||||||
this.iconPositions = lines.map(item => {
|
this.iconPositions = lines.map((item) => {
|
||||||
const pathLen = parseFloat(item.getTotalLength());
|
const pathLen = parseFloat(item.getTotalLength());
|
||||||
const thirdLen = item.getPointAtLength(Math.ceil(pathLen / 3));
|
const thirdLen = item.getPointAtLength(Math.ceil(pathLen / 3));
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ export default class TopologyMetrics extends Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
return items
|
return items
|
||||||
.map(item => {
|
.map((item) => {
|
||||||
const dimensions = item.getBoundingClientRect();
|
const dimensions = item.getBoundingClientRect();
|
||||||
const src = {
|
const src = {
|
||||||
x: dimensions.x + dimensions.width,
|
x: dimensions.x + dimensions.width,
|
||||||
|
@ -51,7 +51,7 @@ export default class TopologyMetrics extends Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
return items
|
return items
|
||||||
.map(item => {
|
.map((item) => {
|
||||||
const dimensions = item.getBoundingClientRect();
|
const dimensions = item.getBoundingClientRect();
|
||||||
const dest = {
|
const dest = {
|
||||||
x: dimensions.x - dimensions.width - 25,
|
x: dimensions.x - dimensions.width - 25,
|
||||||
|
@ -104,7 +104,7 @@ export default class TopologyMetrics extends Component {
|
||||||
|
|
||||||
get upstreams() {
|
get upstreams() {
|
||||||
const upstreams = get(this.args.topology, 'Upstreams') || [];
|
const upstreams = get(this.args.topology, 'Upstreams') || [];
|
||||||
upstreams.forEach(u => {
|
upstreams.forEach((u) => {
|
||||||
u.PeerOrDatacenter = u.PeerName || u.Datacenter;
|
u.PeerOrDatacenter = u.PeerName || u.Datacenter;
|
||||||
});
|
});
|
||||||
const items = [...upstreams];
|
const items = [...upstreams];
|
||||||
|
|
|
@ -24,17 +24,17 @@ export default Component.extend({
|
||||||
data: null,
|
data: null,
|
||||||
empty: false,
|
empty: false,
|
||||||
actions: {
|
actions: {
|
||||||
redraw: function(evt) {
|
redraw: function (evt) {
|
||||||
this.drawGraphs();
|
this.drawGraphs();
|
||||||
},
|
},
|
||||||
change: function(evt) {
|
change: function (evt) {
|
||||||
this.set('data', evt.data.series);
|
this.set('data', evt.data.series);
|
||||||
this.drawGraphs();
|
this.drawGraphs();
|
||||||
this.rerender();
|
this.rerender();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
drawGraphs: function() {
|
drawGraphs: function () {
|
||||||
if (!this.data) {
|
if (!this.data) {
|
||||||
set(this, 'empty', true);
|
set(this, 'empty', true);
|
||||||
return;
|
return;
|
||||||
|
@ -56,7 +56,7 @@ export default Component.extend({
|
||||||
let series = maybeData.data || [];
|
let series = maybeData.data || [];
|
||||||
let labels = maybeData.labels || {};
|
let labels = maybeData.labels || {};
|
||||||
let unitSuffix = maybeData.unitSuffix || '';
|
let unitSuffix = maybeData.unitSuffix || '';
|
||||||
let keys = Object.keys(labels).filter(l => l != 'Total');
|
let keys = Object.keys(labels).filter((l) => l != 'Total');
|
||||||
|
|
||||||
if (series.length == 0 || keys.length == 0) {
|
if (series.length == 0 || keys.length == 0) {
|
||||||
// Put the graph in an error state that might get fixed if metrics show up
|
// Put the graph in an error state that might get fixed if metrics show up
|
||||||
|
@ -67,9 +67,7 @@ export default Component.extend({
|
||||||
set(this, 'empty', false);
|
set(this, 'empty', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let st = stack()
|
let st = stack().keys(keys).order(stackOrderReverse);
|
||||||
.keys(keys)
|
|
||||||
.order(stackOrderReverse);
|
|
||||||
|
|
||||||
let stackData = st(series);
|
let stackData = st(series);
|
||||||
|
|
||||||
|
@ -77,16 +75,16 @@ export default Component.extend({
|
||||||
// stackData contains this but I didn't find reliable documentation on
|
// stackData contains this but I didn't find reliable documentation on
|
||||||
// whether we can rely on the highest stacked area to always be first/last
|
// whether we can rely on the highest stacked area to always be first/last
|
||||||
// in array etc. so this is simpler.
|
// in array etc. so this is simpler.
|
||||||
let summed = series.map(d => {
|
let summed = series.map((d) => {
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
keys.forEach(l => {
|
keys.forEach((l) => {
|
||||||
sum = sum + d[l];
|
sum = sum + d[l];
|
||||||
});
|
});
|
||||||
return sum;
|
return sum;
|
||||||
});
|
});
|
||||||
|
|
||||||
let x = scaleTime()
|
let x = scaleTime()
|
||||||
.domain(extent(series, d => d.time))
|
.domain(extent(series, (d) => d.time))
|
||||||
.range([0, w]);
|
.range([0, w]);
|
||||||
|
|
||||||
let y = scaleLinear()
|
let y = scaleLinear()
|
||||||
|
@ -94,9 +92,9 @@ export default Component.extend({
|
||||||
.range([h, 0]);
|
.range([h, 0]);
|
||||||
|
|
||||||
let a = area()
|
let a = area()
|
||||||
.x(d => x(d.data.time))
|
.x((d) => x(d.data.time))
|
||||||
.y1(d => y(d[0]))
|
.y1((d) => y(d[0]))
|
||||||
.y0(d => y(d[1]));
|
.y0((d) => y(d[1]));
|
||||||
|
|
||||||
// Use the grey/red we prefer by default but have more colors available in
|
// Use the grey/red we prefer by default but have more colors available in
|
||||||
// case user adds extra series with a custom provider.
|
// case user adds extra series with a custom provider.
|
||||||
|
@ -136,11 +134,7 @@ export default Component.extend({
|
||||||
.attr('class', 'sparkline-tt-legend-color')
|
.attr('class', 'sparkline-tt-legend-color')
|
||||||
.style('background-color', color(k));
|
.style('background-color', color(k));
|
||||||
|
|
||||||
legend
|
legend.append('span').text(k).append('span').attr('class', 'sparkline-tt-legend-value');
|
||||||
.append('span')
|
|
||||||
.text(k)
|
|
||||||
.append('span')
|
|
||||||
.attr('class', 'sparkline-tt-legend-value');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let tipVals = tooltip.selectAll('.sparkline-tt-legend-value');
|
let tipVals = tooltip.selectAll('.sparkline-tt-legend-value');
|
||||||
|
@ -158,7 +152,7 @@ export default Component.extend({
|
||||||
|
|
||||||
let self = this;
|
let self = this;
|
||||||
svg
|
svg
|
||||||
.on('mouseover', function(e) {
|
.on('mouseover', function (e) {
|
||||||
tooltip.style('visibility', 'visible');
|
tooltip.style('visibility', 'visible');
|
||||||
cursor.style('visibility', 'visible');
|
cursor.style('visibility', 'visible');
|
||||||
// We update here since we might redraw the graph with user's cursor
|
// We update here since we might redraw the graph with user's cursor
|
||||||
|
@ -166,26 +160,26 @@ export default Component.extend({
|
||||||
// mousemove but the tooltip and cursor are wrong (based on old data).
|
// mousemove but the tooltip and cursor are wrong (based on old data).
|
||||||
self.updateTooltip(e, series, stackData, summed, unitSuffix, x, tooltip, tipVals, cursor);
|
self.updateTooltip(e, series, stackData, summed, unitSuffix, x, tooltip, tipVals, cursor);
|
||||||
})
|
})
|
||||||
.on('mousemove', function(e) {
|
.on('mousemove', function (e) {
|
||||||
self.updateTooltip(e, series, stackData, summed, unitSuffix, x, tooltip, tipVals, cursor);
|
self.updateTooltip(e, series, stackData, summed, unitSuffix, x, tooltip, tipVals, cursor);
|
||||||
})
|
})
|
||||||
.on('mouseout', function(e) {
|
.on('mouseout', function (e) {
|
||||||
tooltip.style('visibility', 'hidden');
|
tooltip.style('visibility', 'hidden');
|
||||||
cursor.style('visibility', 'hidden');
|
cursor.style('visibility', 'hidden');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
willDestroyElement: function() {
|
willDestroyElement: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
if (typeof this.svg !== 'undefined') {
|
if (typeof this.svg !== 'undefined') {
|
||||||
this.svg.on('mouseover mousemove mouseout', null);
|
this.svg.on('mouseover mousemove mouseout', null);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateTooltip: function(e, series, stackData, summed, unitSuffix, x, tooltip, tipVals, cursor) {
|
updateTooltip: function (e, series, stackData, summed, unitSuffix, x, tooltip, tipVals, cursor) {
|
||||||
let [mouseX] = pointer(e);
|
let [mouseX] = pointer(e);
|
||||||
cursor.attr('x', mouseX);
|
cursor.attr('x', mouseX);
|
||||||
|
|
||||||
let mouseTime = x.invert(mouseX);
|
let mouseTime = x.invert(mouseX);
|
||||||
var bisectTime = bisector(function(d) {
|
var bisectTime = bisector(function (d) {
|
||||||
return d.time;
|
return d.time;
|
||||||
}).left;
|
}).left;
|
||||||
let tipIdx = bisectTime(series, mouseTime);
|
let tipIdx = bisectTime(series, mouseTime);
|
||||||
|
|
|
@ -17,7 +17,7 @@ export default class TopologyMetricsUpLines extends Component {
|
||||||
const view = this.args.view;
|
const view = this.args.view;
|
||||||
const lines = [...document.querySelectorAll('#upstream-lines path')];
|
const lines = [...document.querySelectorAll('#upstream-lines path')];
|
||||||
|
|
||||||
this.iconPositions = lines.map(item => {
|
this.iconPositions = lines.map((item) => {
|
||||||
const pathLen = parseFloat(item.getTotalLength());
|
const pathLen = parseFloat(item.getTotalLength());
|
||||||
const partLen = item.getPointAtLength(Math.ceil(pathLen * 0.666));
|
const partLen = item.getPointAtLength(Math.ceil(pathLen * 0.666));
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -8,7 +8,7 @@ export default class PeeredResourceController extends Controller {
|
||||||
const { searchProperties } = this;
|
const { searchProperties } = this;
|
||||||
|
|
||||||
if (!this.abilities.can('use peers')) {
|
if (!this.abilities.can('use peers')) {
|
||||||
return searchProperties.filter(propertyName => propertyName !== 'PeerName');
|
return searchProperties.filter((propertyName) => propertyName !== 'PeerName');
|
||||||
} else {
|
} else {
|
||||||
return searchProperties;
|
return searchProperties;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,13 +46,13 @@ export default class ApplicationController extends Controller {
|
||||||
return container
|
return container
|
||||||
.lookup('route:application')
|
.lookup('route:application')
|
||||||
.refresh()
|
.refresh()
|
||||||
.promise.catch(function(e) {
|
.promise.catch(function (e) {
|
||||||
// passthrough
|
// passthrough
|
||||||
// if you are on an error page a refresh of the application route will reject
|
// if you are on an error page a refresh of the application route will reject
|
||||||
// thats ok as we then transition to the actual route you were trying
|
// thats ok as we then transition to the actual route you were trying
|
||||||
// to get to originally anyway
|
// to get to originally anyway
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then((res) => {
|
||||||
// Use transitionable if we need to change a section of the URL
|
// Use transitionable if we need to change a section of the URL
|
||||||
// or routeName and currentRouteName aren't equal (i.e. error page)
|
// or routeName and currentRouteName aren't equal (i.e. error page)
|
||||||
if (
|
if (
|
||||||
|
@ -68,7 +68,7 @@ export default class ApplicationController extends Controller {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
e.type,
|
e.type,
|
||||||
function(type, e) {
|
function (type, e) {
|
||||||
return type;
|
return type;
|
||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -4,11 +4,11 @@ export default Controller.extend({
|
||||||
dom: service('dom'),
|
dom: service('dom'),
|
||||||
builder: service('form'),
|
builder: service('form'),
|
||||||
isScoped: false,
|
isScoped: false,
|
||||||
init: function() {
|
init: function () {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.form = this.builder.form('token');
|
this.form = this.builder.form('token');
|
||||||
},
|
},
|
||||||
setProperties: function(model) {
|
setProperties: function (model) {
|
||||||
// essentially this replaces the data with changesets
|
// essentially this replaces the data with changesets
|
||||||
this._super(
|
this._super(
|
||||||
Object.keys(model).reduce((prev, key, i) => {
|
Object.keys(model).reduce((prev, key, i) => {
|
||||||
|
@ -22,7 +22,7 @@ export default Controller.extend({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
change: function(e, value, item) {
|
change: function (e, value, item) {
|
||||||
const event = this.dom.normalizeEvent(e, value);
|
const event = this.dom.normalizeEvent(e, value);
|
||||||
const form = this.form;
|
const form = this.form;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -3,18 +3,18 @@ import wayfarer from 'wayfarer';
|
||||||
|
|
||||||
const router = wayfarer();
|
const router = wayfarer();
|
||||||
const routes = {};
|
const routes = {};
|
||||||
export default path => (target, propertyKey, desc) => {
|
export default (path) => (target, propertyKey, desc) => {
|
||||||
runInDebug(() => {
|
runInDebug(() => {
|
||||||
routes[path] = { cls: target, method: propertyKey };
|
routes[path] = { cls: target, method: propertyKey };
|
||||||
});
|
});
|
||||||
router.on(path, function(params, owner, request) {
|
router.on(path, function (params, owner, request) {
|
||||||
const container = owner.lookup('service:container');
|
const container = owner.lookup('service:container');
|
||||||
const instance = container.get(target);
|
const instance = container.get(target);
|
||||||
return configuration => desc.value.apply(instance, [params, configuration, request]);
|
return (configuration) => desc.value.apply(instance, [params, configuration, request]);
|
||||||
});
|
});
|
||||||
return desc;
|
return desc;
|
||||||
};
|
};
|
||||||
export const match = path => {
|
export const match = (path) => {
|
||||||
return router.match(path);
|
return router.match(path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,13 +29,10 @@ runInDebug(() => {
|
||||||
<pre>
|
<pre>
|
||||||
${Object.entries(routes)
|
${Object.entries(routes)
|
||||||
.map(([key, value]) => {
|
.map(([key, value]) => {
|
||||||
let cls = container
|
let cls = container.keyForClass(value.cls).split('/').pop();
|
||||||
.keyForClass(value.cls)
|
|
||||||
.split('/')
|
|
||||||
.pop();
|
|
||||||
cls = cls
|
cls = cls
|
||||||
.split('-')
|
.split('-')
|
||||||
.map(item => `${item[0].toUpperCase()}${item.substr(1)}`)
|
.map((item) => `${item[0].toUpperCase()}${item.substr(1)}`)
|
||||||
.join('');
|
.join('');
|
||||||
return `${key}
|
return `${key}
|
||||||
${cls}Repository.${value.method}(params)
|
${cls}Repository.${value.method}(params)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue