From 65f2cd891b32f7d1c527be7384ab6caccc501bbe Mon Sep 17 00:00:00 2001 From: John Cowen Date: Fri, 18 Sep 2020 11:14:06 +0100 Subject: [PATCH] ui: Read-only CRD/Centralized Config Intentions (#8659) --- .../consul-external-source/index.hbs | 10 +- .../consul-intention-form/fieldsets/index.hbs | 170 +++++++ .../consul-intention-form/fieldsets/index.js | 13 + .../consul-intention-form/index.hbs | 145 ++---- .../components/consul-intention-form/index.js | 6 - .../consul-intention-list/index.hbs | 42 +- .../index.hbs | 35 ++ .../consul-intention-permission-list/index.js | 5 + .../consul-intention-view/index.hbs | 40 ++ .../components/consul-intention-view/index.js | 5 + ui-v2/app/components/data-form/index.hbs | 4 +- .../app/components/list-collection/index.hbs | 6 +- ui-v2/app/components/radio-card/index.hbs | 11 + ui-v2/app/components/radio-card/index.js | 6 + ui-v2/app/helpers/route-match.js | 14 +- .../intention-permission-http-header.js | 14 + ui-v2/app/models/intention-permission-http.js | 21 + ui-v2/app/models/intention-permission.js | 9 + ui-v2/app/models/intention.js | 17 +- ui-v2/app/router.js | 4 +- ui-v2/app/routes/dc/intentions/edit.js | 9 +- ui-v2/app/serializers/intention.js | 38 ++ ui-v2/app/services/repository/intention.js | 5 +- .../styles/base/components/pill/layout.scss | 5 + .../styles/base/icons/base-placeholders.scss | 6 + .../app/styles/base/icons/base-variables.scss | 1 + .../styles/base/icons/icon-placeholders.scss | 10 + ui-v2/app/styles/components.scss | 7 + .../app/styles/components/composite-row.scss | 1 + .../components/composite-row/index.scss | 46 +- .../components/composite-row/layout.scss | 81 +--- .../styles/components/composite-row/skin.scss | 24 +- .../consul-intention-fieldsets.scss | 4 + .../consul-intention-fieldsets/index.scss | 2 + .../consul-intention-fieldsets/layout.scss | 22 + .../consul-intention-fieldsets/skin.scss | 2 + .../components/consul-intention-list.scss | 4 + .../consul-intention-list/index.scss | 16 + .../consul-intention-list/layout.scss | 27 ++ .../consul-intention-list/skin.scss | 3 + .../consul-intention-permission-list.scss | 4 + .../index.scss | 11 + .../layout.scss | 3 + .../skin.scss | 9 + .../components/discovery-chain/layout.scss | 3 - .../components/discovery-chain/skin.scss | 3 +- .../app/styles/components/form-elements.scss | 3 + ui-v2/app/styles/components/list-row.scss | 4 + .../app/styles/components/list-row/index.scss | 2 + .../styles/components/list-row/layout.scss | 48 ++ .../app/styles/components/list-row/skin.scss | 23 + ui-v2/app/styles/components/pill.scss | 27 ++ ui-v2/app/styles/components/radio-card.scss | 4 + .../styles/components/radio-card/index.scss | 2 + .../styles/components/radio-card/layout.scss | 16 + .../styles/components/radio-card/skin.scss | 32 ++ ui-v2/app/styles/components/table.scss | 69 +-- ui-v2/app/styles/layouts/containers.scss | 2 +- ui-v2/app/styles/typography.scss | 1 + ui-v2/app/templates/dc/intentions/edit.hbs | 17 +- .../dc/services/show/intentions/index.hbs | 2 +- ui-v2/package.json | 3 +- .../acceptance/dc/intentions/delete.feature | 1 + .../dc/intentions/navigation.feature | 74 +-- .../dc/services/show/intentions.feature | 13 +- .../integration/serializers/intention-test.js | 8 +- .../services/repository/intention-test.js | 28 +- ui-v2/yarn.lock | 423 +++++++++++++++++- 68 files changed, 1331 insertions(+), 394 deletions(-) create mode 100644 ui-v2/app/components/consul-intention-form/fieldsets/index.hbs create mode 100644 ui-v2/app/components/consul-intention-form/fieldsets/index.js create mode 100644 ui-v2/app/components/consul-intention-permission-list/index.hbs create mode 100644 ui-v2/app/components/consul-intention-permission-list/index.js create mode 100644 ui-v2/app/components/consul-intention-view/index.hbs create mode 100644 ui-v2/app/components/consul-intention-view/index.js create mode 100644 ui-v2/app/components/radio-card/index.hbs create mode 100644 ui-v2/app/components/radio-card/index.js create mode 100644 ui-v2/app/models/intention-permission-http-header.js create mode 100644 ui-v2/app/models/intention-permission-http.js create mode 100644 ui-v2/app/models/intention-permission.js create mode 100644 ui-v2/app/styles/components/consul-intention-fieldsets.scss create mode 100644 ui-v2/app/styles/components/consul-intention-fieldsets/index.scss create mode 100644 ui-v2/app/styles/components/consul-intention-fieldsets/layout.scss create mode 100644 ui-v2/app/styles/components/consul-intention-fieldsets/skin.scss create mode 100644 ui-v2/app/styles/components/consul-intention-list.scss create mode 100644 ui-v2/app/styles/components/consul-intention-list/index.scss create mode 100644 ui-v2/app/styles/components/consul-intention-list/layout.scss create mode 100644 ui-v2/app/styles/components/consul-intention-list/skin.scss create mode 100644 ui-v2/app/styles/components/consul-intention-permission-list.scss create mode 100644 ui-v2/app/styles/components/consul-intention-permission-list/index.scss create mode 100644 ui-v2/app/styles/components/consul-intention-permission-list/layout.scss create mode 100644 ui-v2/app/styles/components/consul-intention-permission-list/skin.scss create mode 100644 ui-v2/app/styles/components/list-row.scss create mode 100644 ui-v2/app/styles/components/list-row/index.scss create mode 100644 ui-v2/app/styles/components/list-row/layout.scss create mode 100644 ui-v2/app/styles/components/list-row/skin.scss create mode 100644 ui-v2/app/styles/components/radio-card.scss create mode 100644 ui-v2/app/styles/components/radio-card/index.scss create mode 100644 ui-v2/app/styles/components/radio-card/layout.scss create mode 100644 ui-v2/app/styles/components/radio-card/skin.scss diff --git a/ui-v2/app/components/consul-external-source/index.hbs b/ui-v2/app/components/consul-external-source/index.hbs index f2e7e8c2f..cfa37d491 100644 --- a/ui-v2/app/components/consul-external-source/index.hbs +++ b/ui-v2/app/components/consul-external-source/index.hbs @@ -7,10 +7,14 @@ }} {{else}} - {{#if (eq externalSource 'aws')}} - Registered via {{uppercase externalSource}} + {{#if label}} + {{label}} {{else}} - Registered via {{capitalize externalSource}} + {{#if (eq externalSource 'aws')}} + Registered via {{uppercase externalSource}} + {{else}} + Registered via {{capitalize externalSource}} + {{/if}} {{/if}} {{/if}} diff --git a/ui-v2/app/components/consul-intention-form/fieldsets/index.hbs b/ui-v2/app/components/consul-intention-form/fieldsets/index.hbs new file mode 100644 index 000000000..f3b21e9b6 --- /dev/null +++ b/ui-v2/app/components/consul-intention-form/fieldsets/index.hbs @@ -0,0 +1,170 @@ +
+
+
+
+

Source

+ + {{#if (env 'CONSUL_NSPACES_ENABLED')}} + +{{/if}} +
+
+

Destination

+ + {{#if (env 'CONSUL_NSPACES_ENABLED')}} + +{{/if}} +
+
+
+ Should this source connect to the destination? +
+ {{#each + (array + (hash + intent="allow" + header="Allow" + body="The source service will be allowed to connect to the destination." + ) + (hash + intent="deny" + header="Deny" + body="The source service will not be allowed to connect to the destination." + ) + ) + as |_action|}} + +
+ {{_action.header}} +
+

+ {{_action.body}} +

+
+ {{/each}} +
+
+ +
+{{#if (not item.Legacy)}} +
+

Permissions

+{{#if (gt item.Permissions.length 0) }} +
+

+ Permissions are L7 attributes. If any of the following permissions match the request, the Intention will apply. Requests that fail to match any of the provided routes will do the opposite of the allow/deny action above. +

+

+ documentation +

+
+ +{{else}} + + +

+ Add permissions via CLI +

+
+ +

+ Permissions intercept an Intention's traffic using L7 criteria, such as path prefixes and http headers. You can use the CLI to add permissions to this intention. +

+
+ + + + +
+{{/if}} +
+{{/if}} +
\ No newline at end of file diff --git a/ui-v2/app/components/consul-intention-form/fieldsets/index.js b/ui-v2/app/components/consul-intention-form/fieldsets/index.js new file mode 100644 index 000000000..c09a8d717 --- /dev/null +++ b/ui-v2/app/components/consul-intention-form/fieldsets/index.js @@ -0,0 +1,13 @@ +import Component from '@ember/component'; + +export default Component.extend({ + tagName: '', + actions: { + createNewLabel: function(template, term) { + return template.replace(/{{term}}/g, term); + }, + isUnique: function(items, term) { + return !items.findBy('Name', term); + }, + }, +}); diff --git a/ui-v2/app/components/consul-intention-form/index.hbs b/ui-v2/app/components/consul-intention-form/index.hbs index 986d0f004..5d36f22c8 100644 --- a/ui-v2/app/components/consul-intention-form/index.hbs +++ b/ui-v2/app/components/consul-intention-form/index.hbs @@ -27,129 +27,36 @@ - +{{#let api.data as |item|}} + {{#if item.IsEditable}} {{#if (env 'CONSUL_NSPACES_ENABLED')}} {{/if}} -
- -
-
-
-

Source

- - {{#if (env 'CONSUL_NSPACES_ENABLED')}} - - {{/if}} -
-
-

Destination

- - {{#if (env 'CONSUL_NSPACES_ENABLED')}} - - {{/if}} -
-
-
- {{#each (array 'allow' 'deny') as |intent|}} - - {{/each}} -
- -
- +
- - - {{#if (not api.isCreate)}} - {{#if (not-eq form.item.ID 'anonymous') }} + + +{{#if (not api.isCreate)}} + {{#if (not-eq item.ID 'anonymous') }} @@ -158,11 +65,15 @@ - {{/if}} - {{/if}} + {{/if}} +{{/if}}
- - - + + {{else}} + + {{/if}} +{{/let}}
diff --git a/ui-v2/app/components/consul-intention-form/index.js b/ui-v2/app/components/consul-intention-form/index.js index 62351e380..faf8dd3b8 100644 --- a/ui-v2/app/components/consul-intention-form/index.js +++ b/ui-v2/app/components/consul-intention-form/index.js @@ -63,12 +63,6 @@ export default Component.extend({ DestinationNS: destination, }); }, - createNewLabel: function(template, term) { - return template.replace(/{{term}}/g, term); - }, - isUnique: function(items, term) { - return !items.findBy('Name', term); - }, change: function(e, form, item) { const target = e.target; diff --git a/ui-v2/app/components/consul-intention-list/index.hbs b/ui-v2/app/components/consul-intention-list/index.hbs index 99418e833..091e82f7b 100644 --- a/ui-v2/app/components/consul-intention-list/index.hbs +++ b/ui-v2/app/components/consul-intention-list/index.hbs @@ -6,12 +6,21 @@ {{#if (gt items.length 0)}} - + - Source -   - Destination - Precedence + Source +   + Destination + + Permissions + + Permissions intercept an Intention's traffic using L7 criteria, such as path prefixes and http headers. + + +   @@ -25,9 +34,11 @@ {{or item.SourceNS 'default'}} - - {{item.Action}} +{{#let (or item.Action "L7 rules") as |intent|}} + + {{capitalize intent}} +{{/let}} {{#if (eq item.DestinationName '*') }} @@ -39,8 +50,15 @@ {{or item.DestinationNS 'default'}} - - {{item.Precedence}} + + {{#if (gt item.Permissions.length 0)}} + {{pluralize item.Permissions.length 'Permission'}} + {{/if}} + + + {{#if item.IsManagedByCRD}} + + {{/if}} @@ -49,6 +67,7 @@ More + {{#if item.IsEditable}}
  • Edit
  • @@ -75,6 +94,11 @@ + {{else}} +
  • + View +
  • + {{/if}}
    diff --git a/ui-v2/app/components/consul-intention-permission-list/index.hbs b/ui-v2/app/components/consul-intention-permission-list/index.hbs new file mode 100644 index 000000000..2c860cab5 --- /dev/null +++ b/ui-v2/app/components/consul-intention-permission-list/index.hbs @@ -0,0 +1,35 @@ +{{#if (gt items.length 0)}} +
    + +
    +{{/if}} \ No newline at end of file diff --git a/ui-v2/app/components/consul-intention-permission-list/index.js b/ui-v2/app/components/consul-intention-permission-list/index.js new file mode 100644 index 000000000..479865264 --- /dev/null +++ b/ui-v2/app/components/consul-intention-permission-list/index.js @@ -0,0 +1,5 @@ +import Component from '@ember/component'; + +export default Component.extend({ + tagName: '', +}); diff --git a/ui-v2/app/components/consul-intention-view/index.hbs b/ui-v2/app/components/consul-intention-view/index.hbs new file mode 100644 index 000000000..3c9d8b1bc --- /dev/null +++ b/ui-v2/app/components/consul-intention-view/index.hbs @@ -0,0 +1,40 @@ +
    + +
    +
    +
    Destination
    +
    + {{item.DestinationName}}{{#if (env "CONSUL_NSPACES_ENABLED")}} / {{item.DestinationNS}}{{/if}} +
    +
    Source
    +
    + {{item.SourceName}}{{#if (env "CONSUL_NSPACES_ENABLED")}} / {{item.SourceNS}}{{/if}} +
    +{{#if item.Action}} +
    Action
    +
    + {{item.Action}} +
    +{{/if}} +
    Description
    +
    + {{or item.Description 'N/A'}} +
    +
    +
    + +{{#if (gt item.Permissions.length 0) }} +

    Permissions

    +
    +

    + Permissions are L7 attributes. If any of the following permissions match the request, the Intention will apply. Requests that fail to match any of the provided routes will do the opposite of the allow/deny action above. +

    +

    + Learn more about permissions +

    +
    + + +{{/if}} + +
    diff --git a/ui-v2/app/components/consul-intention-view/index.js b/ui-v2/app/components/consul-intention-view/index.js new file mode 100644 index 000000000..479865264 --- /dev/null +++ b/ui-v2/app/components/consul-intention-view/index.js @@ -0,0 +1,5 @@ +import Component from '@ember/component'; + +export default Component.extend({ + tagName: '', +}); diff --git a/ui-v2/app/components/data-form/index.hbs b/ui-v2/app/components/data-form/index.hbs index 39d8d426b..1e1cb912e 100644 --- a/ui-v2/app/components/data-form/index.hbs +++ b/ui-v2/app/components/data-form/index.hbs @@ -1,8 +1,8 @@ - + -
    {{yield cell.item cell.index}}
    -
    {{yield cell.item cell.index}}
    +
    {{yield cell.item cell.index}}
    +
    {{yield cell.item cell.index}}
    -
    +
    {{yield cell.item cell.index}}
    diff --git a/ui-v2/app/components/radio-card/index.hbs b/ui-v2/app/components/radio-card/index.hbs new file mode 100644 index 000000000..4a5348aac --- /dev/null +++ b/ui-v2/app/components/radio-card/index.hbs @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/ui-v2/app/components/radio-card/index.js b/ui-v2/app/components/radio-card/index.js new file mode 100644 index 000000000..a7be4db13 --- /dev/null +++ b/ui-v2/app/components/radio-card/index.js @@ -0,0 +1,6 @@ +import Component from '@ember/component'; +import Slotted from 'block-slots'; + +export default Component.extend(Slotted, { + tagName: '', +}); diff --git a/ui-v2/app/helpers/route-match.js b/ui-v2/app/helpers/route-match.js index 83895a7fd..e1fee0031 100644 --- a/ui-v2/app/helpers/route-match.js +++ b/ui-v2/app/helpers/route-match.js @@ -1,18 +1,18 @@ import { helper } from '@ember/component/helper'; -export default helper(function routeMatch([params] /*, hash*/) { - const keys = Object.keys(params); +export default helper(function routeMatch([item], hash) { + const keys = Object.keys(item.data || item); switch (true) { case keys.includes('Present'): - return `${params.Invert ? `NOT ` : ``}present`; + return `${item.Invert ? `NOT ` : ``}present`; case keys.includes('Exact'): - return `${params.Invert ? `NOT ` : ``}exactly matching "${params.Exact}"`; + return `${item.Invert ? `NOT ` : ``}exactly matching "${item.Exact}"`; case keys.includes('Prefix'): - return `${params.Invert ? `NOT ` : ``}prefixed by "${params.Prefix}"`; + return `${item.Invert ? `NOT ` : ``}prefixed by "${item.Prefix}"`; case keys.includes('Suffix'): - return `${params.Invert ? `NOT ` : ``}suffixed by "${params.Suffix}"`; + return `${item.Invert ? `NOT ` : ``}suffixed by "${item.Suffix}"`; case keys.includes('Regex'): - return `${params.Invert ? `NOT ` : ``}matching the regex "${params.Regex}"`; + return `${item.Invert ? `NOT ` : ``}matching the regex "${item.Regex}"`; } return ''; }); diff --git a/ui-v2/app/models/intention-permission-http-header.js b/ui-v2/app/models/intention-permission-http-header.js new file mode 100644 index 000000000..0060904d2 --- /dev/null +++ b/ui-v2/app/models/intention-permission-http-header.js @@ -0,0 +1,14 @@ +import attr from 'ember-data/attr'; + +import Fragment from 'ember-data-model-fragments/fragment'; + +export default Fragment.extend({ + Name: attr('string'), + + Exact: attr('string'), + Prefix: attr('string'), + Suffix: attr('string'), + Regex: attr('string'), + Present: attr('boolean'), + Invert: attr('boolean'), +}); diff --git a/ui-v2/app/models/intention-permission-http.js b/ui-v2/app/models/intention-permission-http.js new file mode 100644 index 000000000..8a988aefa --- /dev/null +++ b/ui-v2/app/models/intention-permission-http.js @@ -0,0 +1,21 @@ +import attr from 'ember-data/attr'; +import { computed } from '@ember/object'; +import { or } from '@ember/object/computed'; + +import Fragment from 'ember-data-model-fragments/fragment'; +import { fragmentArray, array } from 'ember-data-model-fragments/attributes'; + +const pathProps = ['PathPrefix', 'PathExact', 'PathRegex']; +export default Fragment.extend({ + PathExact: attr('string'), + PathPrefix: attr('string'), + PathRegex: attr('string'), + + Header: fragmentArray('intention-permission-http-header'), + Methods: array('string'), + + Path: or(...pathProps), + PathType: computed(...pathProps, function() { + return pathProps.find(prop => typeof this[prop] === 'string'); + }), +}); diff --git a/ui-v2/app/models/intention-permission.js b/ui-v2/app/models/intention-permission.js new file mode 100644 index 000000000..4786d23ea --- /dev/null +++ b/ui-v2/app/models/intention-permission.js @@ -0,0 +1,9 @@ +import attr from 'ember-data/attr'; + +import Fragment from 'ember-data-model-fragments/fragment'; +import { fragment } from 'ember-data-model-fragments/attributes'; + +export default Fragment.extend({ + Action: attr('string', { defaultValue: 'allow' }), + Http: fragment('intention-permission-http'), +}); diff --git a/ui-v2/app/models/intention.js b/ui-v2/app/models/intention.js index e5ec037dc..e954937bb 100644 --- a/ui-v2/app/models/intention.js +++ b/ui-v2/app/models/intention.js @@ -1,5 +1,8 @@ import Model from 'ember-data/model'; import attr from 'ember-data/attr'; +import { computed } from '@ember/object'; + +import { fragmentArray } from 'ember-data-model-fragments/attributes'; export const PRIMARY_KEY = 'uid'; export const SLUG_KEY = 'ID'; @@ -12,9 +15,21 @@ export default Model.extend({ DestinationName: attr('string', { defaultValue: '*' }), DestinationNS: attr('string'), Precedence: attr('number'), + Permissions: fragmentArray('intention-permission'), SourceType: attr('string', { defaultValue: 'consul' }), - Action: attr('string', { defaultValue: 'allow' }), + Action: attr('string'), Meta: attr(), + Legacy: attr('boolean', { defaultValue: true }), + + IsManagedByCRD: computed('Meta', function() { + const meta = Object.entries(this.Meta || {}).find( + ([key, value]) => key === 'external-source' && value === 'kubernetes' + ); + return typeof meta !== 'undefined'; + }), + IsEditable: computed('Legacy', 'IsManagedByCRD', function() { + return this.Legacy && !this.IsManagedByCRD; + }), SyncTime: attr('number'), Datacenter: attr('string'), CreatedAt: attr('date'), diff --git a/ui-v2/app/router.js b/ui-v2/app/router.js index a703dd1dc..eb2617e62 100644 --- a/ui-v2/app/router.js +++ b/ui-v2/app/router.js @@ -19,7 +19,7 @@ export const routes = { intentions: { _options: { path: '/intentions' }, edit: { - _options: { path: '/:intention' }, + _options: { path: '/:intention_id' }, }, create: { _options: { path: '/create' }, @@ -90,7 +90,7 @@ export const routes = { intentions: { _options: { path: '/intentions' }, edit: { - _options: { path: '/:id' }, + _options: { path: '/:intention_id' }, }, create: { _options: { path: '/create' }, diff --git a/ui-v2/app/routes/dc/intentions/edit.js b/ui-v2/app/routes/dc/intentions/edit.js index 53b7a5fb8..e434a2b2e 100644 --- a/ui-v2/app/routes/dc/intentions/edit.js +++ b/ui-v2/app/routes/dc/intentions/edit.js @@ -4,15 +4,18 @@ import { hash } from 'rsvp'; export default Route.extend({ repo: service('repository/intention'), - model: function(params, transition) { + model: function({ intention_id }, transition) { const dc = this.modelFor('dc').dc.Name; const nspace = '*'; return hash({ - isLoading: false, dc: dc, nspace: nspace, item: - typeof params.id !== 'undefined' ? this.repo.findBySlug(params.id, dc, nspace) : undefined, + typeof intention_id !== 'undefined' + ? this.repo.findBySlug(intention_id, dc, nspace) + : this.repo.create({ + Datacenter: dc, + }), }); }, setupController: function(controller, model) { diff --git a/ui-v2/app/serializers/intention.js b/ui-v2/app/serializers/intention.js index 8c6d169b9..3c7c1443d 100644 --- a/ui-v2/app/serializers/intention.js +++ b/ui-v2/app/serializers/intention.js @@ -1,7 +1,45 @@ import Serializer from './application'; +import { inject as service } from '@ember/service'; import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/intention'; export default Serializer.extend({ primaryKey: PRIMARY_KEY, slugKey: SLUG_KEY, + encoder: service('encoder'), + init: function() { + this._super(); + this.uri = this.encoder.uriTag(); + }, + ensureID: function(item) { + if (typeof item.ID !== 'string') { + item.ID = this + .uri`${item.SourceNS}:${item.SourceName}:${item.DestinationNS}:${item.DestinationName}`; + item.Legacy = false; + } else { + item.Legacy = true; + } + return item; + }, + respondForQuery: function(respond, query) { + return this._super( + cb => + respond((headers, body) => { + return cb( + headers, + body.map(item => this.ensureID(item)) + ); + }), + query + ); + }, + respondForQueryRecord: function(respond, query) { + return this._super( + cb => + respond((headers, body) => { + body = this.ensureID(body); + return cb(headers, body); + }), + query + ); + }, }); diff --git a/ui-v2/app/services/repository/intention.js b/ui-v2/app/services/repository/intention.js index e2ad0e697..8217ed07e 100644 --- a/ui-v2/app/services/repository/intention.js +++ b/ui-v2/app/services/repository/intention.js @@ -10,7 +10,10 @@ export default RepositoryService.extend({ }, create: function(obj) { delete obj.Namespace; - return this._super(obj); + return this._super({ + Action: 'allow', + ...obj, + }); }, findByService: function(slug, dc, nspace, configuration = {}) { const query = { diff --git a/ui-v2/app/styles/base/components/pill/layout.scss b/ui-v2/app/styles/base/components/pill/layout.scss index 56cf8623b..4133d21ce 100644 --- a/ui-v2/app/styles/base/components/pill/layout.scss +++ b/ui-v2/app/styles/base/components/pill/layout.scss @@ -11,6 +11,11 @@ margin-right: 4px; font-size: 0; } +%increased-pill { + @extend %pill; + padding: 5px 10px; + min-width: 87px; +} %reduced-pill { background-color: $gray-100; padding: 0 8px; diff --git a/ui-v2/app/styles/base/icons/base-placeholders.scss b/ui-v2/app/styles/base/icons/base-placeholders.scss index 421c2c320..37988e627 100644 --- a/ui-v2/app/styles/base/icons/base-placeholders.scss +++ b/ui-v2/app/styles/base/icons/base-placeholders.scss @@ -7,6 +7,12 @@ mask-position: center; background-color: currentColor; } +%with-glyph-icon { + font-weight: $typo-weight-normal; + background-color: $gray-100; + visibility: visible; + padding: 0 4px; +} %as-pseudo { display: inline-block; content: ''; diff --git a/ui-v2/app/styles/base/icons/base-variables.scss b/ui-v2/app/styles/base/icons/base-variables.scss index 09fc28c59..f5cec0145 100644 --- a/ui-v2/app/styles/base/icons/base-variables.scss +++ b/ui-v2/app/styles/base/icons/base-variables.scss @@ -79,6 +79,7 @@ $info-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); $key-svg: url('data:image/svg+xml;charset=UTF-8,'); $kubernetes-logo-color-svg: url('data:image/svg+xml;charset=UTF-8,'); +$layers-svg: url('data:image/svg+xml;charset=UTF-8,'); $learn-svg: url('data:image/svg+xml;charset=UTF-8,'); $link-svg: url('data:image/svg+xml;charset=UTF-8,'); $loading-svg: url('data:image/svg+xml;charset=UTF-8,'); diff --git a/ui-v2/app/styles/base/icons/icon-placeholders.scss b/ui-v2/app/styles/base/icons/icon-placeholders.scss index 6f7988dd3..095025c91 100644 --- a/ui-v2/app/styles/base/icons/icon-placeholders.scss +++ b/ui-v2/app/styles/base/icons/icon-placeholders.scss @@ -808,6 +808,16 @@ mask-image: $learn-svg; } +%with-layers-icon { + @extend %with-icon; + background-image: $layers-svg; +} +%with-layers-mask { + @extend %with-mask; + -webkit-mask-image: $layers-svg; + mask-image: $layers-svg; +} + %with-link-icon { @extend %with-icon; background-image: $link-svg; diff --git a/ui-v2/app/styles/components.scss b/ui-v2/app/styles/components.scss index 20100e9e7..9bcb8c879 100644 --- a/ui-v2/app/styles/components.scss +++ b/ui-v2/app/styles/components.scss @@ -8,6 +8,7 @@ @import './components/anchors'; @import './components/progress'; @import './components/buttons'; +@import './components/list-row'; @import './components/composite-row'; @import './components/secret-button'; @import './components/tabs'; @@ -38,6 +39,7 @@ @import './components/more-popover-menu'; @import './components/confirmation-alert'; @import './components/definition-table'; +@import './components/radio-card'; /**/ @@ -47,3 +49,8 @@ @import './components/main-nav-horizontal'; @import './components/app-view'; @import './components/footer'; + +/**/ +@import './components/consul-intention-list'; +@import './components/consul-intention-permission-list'; +@import './components/consul-intention-fieldsets'; diff --git a/ui-v2/app/styles/components/composite-row.scss b/ui-v2/app/styles/components/composite-row.scss index 7ffa99719..0b5d9b155 100644 --- a/ui-v2/app/styles/components/composite-row.scss +++ b/ui-v2/app/styles/components/composite-row.scss @@ -29,6 +29,7 @@ .consul-service-list li > div:first-child > dl:first-child dd { margin-top: 1px; } +.consul-intention-permission-list > ul, .proxy-exposed-paths > ul, .proxy-upstreams > ul { border-top: 1px solid $gray-200; diff --git a/ui-v2/app/styles/components/composite-row/index.scss b/ui-v2/app/styles/components/composite-row/index.scss index ee3a0b537..cb2246723 100644 --- a/ui-v2/app/styles/components/composite-row/index.scss +++ b/ui-v2/app/styles/components/composite-row/index.scss @@ -1,19 +1,47 @@ @import './layout'; @import './skin'; +%composite-row { + @extend %list-row; +} +%composite-row > .header { + @extend %composite-row-header, %list-row-header; +} +%composite-row > .detail { + @extend %composite-row-detail, %list-row-detail; +} +%composite-row > .actions { + @extend %composite-row-actions; +} %with-composite-row-intent:hover, %with-composite-row-intent:focus, %with-composite-row-intent:active { - @extend %composite-row-intent; + @extend %list-row-intent; } -%composite-row > :first-child { - @extend %composite-row-header; +%list-row-header > dl:first-child { + @extend %list-row-header-icon; } -%composite-row-header > dl:first-child { - @extend %composite-row-icon; + +// TODO: %defined-by-icon +// Copy Button +%composite-row .copy-button { + display: inline-flex; } -%composite-row > :nth-child(2) { - @extend %composite-row-detail; +%composite-row .copy-button button { + padding: 0 !important; + margin: 0 !important; } -%composite-row > :nth-child(3) { - @extend %composite-row-actions; +%composite-row-detail .copy-button { + margin-right: 4px; + margin-top: 2px; +} +%composite-row-header .copy-button { + margin-left: 4px; +} +/* buttons need to be displayed in order for the tooltip */ +/* to track them */ +%composite-row-header .copy-button button { + opacity: 0; +} +%composite-row-header:hover .copy-button button { + opacity: 1; } diff --git a/ui-v2/app/styles/components/composite-row/layout.scss b/ui-v2/app/styles/components/composite-row/layout.scss index 289dd4f3e..e865385f4 100644 --- a/ui-v2/app/styles/components/composite-row/layout.scss +++ b/ui-v2/app/styles/components/composite-row/layout.scss @@ -6,24 +6,10 @@ grid-template-areas: 'header actions' 'detail actions'; - - padding-top: 10px; - padding-bottom: 10px; - /* whilst this isn't in the designs this makes our temporary rollover look better */ - padding-left: 12px; } %with-one-action-row { - display: grid; + @extend %composite-row; grid-template-columns: 1fr auto; - grid-template-rows: 50% 50%; - - // only one action applies to these rows - grid-template-areas: - 'header actions' - 'detail actions'; - - padding-top: 10px; - padding-bottom: 10px; padding-right: 12px; } %composite-row-header { @@ -34,73 +20,8 @@ grid-area: detail; align-self: end; } -%composite-row-detail:not(:last-child) { - overflow-x: hidden; -} %composite-row-actions { grid-area: actions; justify-self: center; align-self: center; } -%composite-row-icon { - margin-right: 6px; - margin-left: -2px; -} -%composite-row-icon dt { - display: none; -} -%composite-row-icon dd::before { - font-size: 0.9em; -} -/* TODO Currently only here due to dl's in %form-row */ -%composite-row dl { - margin: 0; - padding: 0; -} -%composite-row-detail, -%composite-row-detail ul, -%composite-row-detail dl, -%composite-row-header, -%composite-row-header dl { - display: inline-flex; - flex-wrap: nowrap; -} -%composite-row-header *, -%composite-row-detail * { - white-space: nowrap; - flex-wrap: nowrap; -} -%composite-row-detail dl, -%composite-row-detail > span { - margin-right: 18px; -} -%composite-row-detail dl.node dt::before { - margin-top: 3px; -} -%composite-row-detail dl dt::before { - margin-right: 4px; - margin-top: 2px; -} -// Copy Button -%composite-row .copy-button button { - padding: 0 !important; - margin: 0 !important; -} -%composite-row-detail .copy-button { - margin-right: 4px; - margin-top: 2px; -} -%composite-row-header .copy-button { - margin-left: 4px; -} -%composite-row .copy-button { - display: inline-flex; -} -/* buttons need to be displayed in order for the tooltip */ -/* to track them */ -%composite-row-header .copy-button button { - opacity: 0; -} -%composite-row-header:hover .copy-button button { - opacity: 1; -} diff --git a/ui-v2/app/styles/components/composite-row/skin.scss b/ui-v2/app/styles/components/composite-row/skin.scss index 6bf4f212b..fef9fc925 100644 --- a/ui-v2/app/styles/components/composite-row/skin.scss +++ b/ui-v2/app/styles/components/composite-row/skin.scss @@ -1,26 +1,4 @@ -%composite-row { - list-style-type: none; - border: 1px solid; - border-top-color: $transparent; - border-bottom-color: $gray-200; - border-right-color: $transparent; - border-left-color: $transparent; -} -%composite-row-intent { - border-color: $gray-200; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - border-top-color: $transparent; - cursor: pointer; -} -%composite-row-header { - color: $black; -} -%composite-row-header * { - color: inherit; -} -%composite-row-detail { - color: $gray-500; -} +// TODO: %defined-by-icon %composite-row-detail .policy::before { @extend %with-file-fill-mask, %as-pseudo; diff --git a/ui-v2/app/styles/components/consul-intention-fieldsets.scss b/ui-v2/app/styles/components/consul-intention-fieldsets.scss new file mode 100644 index 000000000..aa137a88d --- /dev/null +++ b/ui-v2/app/styles/components/consul-intention-fieldsets.scss @@ -0,0 +1,4 @@ +@import './consul-intention-fieldsets/index'; +.consul-intention-fieldsets { + @extend %consul-intention-fieldsets; +} diff --git a/ui-v2/app/styles/components/consul-intention-fieldsets/index.scss b/ui-v2/app/styles/components/consul-intention-fieldsets/index.scss new file mode 100644 index 000000000..bc1825219 --- /dev/null +++ b/ui-v2/app/styles/components/consul-intention-fieldsets/index.scss @@ -0,0 +1,2 @@ +@import './skin'; +@import './layout'; diff --git a/ui-v2/app/styles/components/consul-intention-fieldsets/layout.scss b/ui-v2/app/styles/components/consul-intention-fieldsets/layout.scss new file mode 100644 index 000000000..4b4713d8a --- /dev/null +++ b/ui-v2/app/styles/components/consul-intention-fieldsets/layout.scss @@ -0,0 +1,22 @@ +%consul-intention-fieldsets [role='radiogroup'] { + overflow: visible !important; + display: grid; + grid-gap: 12px; + grid-template-columns: repeat(auto-fill, minmax(270px, 370px)); +} +%consul-intention-fieldsets .radio-card { + @extend %radio-card-with-icon; +} +%consul-intention-fieldsets .radio-card header > * { + display: inline; +} +%consul-intention-fieldsets .value-allow > :last-child::before { + @extend %with-arrow-right-color-icon, %as-pseudo; +} +%consul-intention-fieldsets .value-deny > :last-child::before { + @extend %with-deny-color-icon, %as-pseudo; +} +%consul-intention-fieldsets .radio-card header span.code::before { + @extend %with-deny-color-icon, %as-pseudo; + margin-right: 5px; +} diff --git a/ui-v2/app/styles/components/consul-intention-fieldsets/skin.scss b/ui-v2/app/styles/components/consul-intention-fieldsets/skin.scss new file mode 100644 index 000000000..6c239d264 --- /dev/null +++ b/ui-v2/app/styles/components/consul-intention-fieldsets/skin.scss @@ -0,0 +1,2 @@ +%consul-intention-fieldsets { +} diff --git a/ui-v2/app/styles/components/consul-intention-list.scss b/ui-v2/app/styles/components/consul-intention-list.scss new file mode 100644 index 000000000..642c10286 --- /dev/null +++ b/ui-v2/app/styles/components/consul-intention-list.scss @@ -0,0 +1,4 @@ +@import './consul-intention-list/index'; +.consul-intention-list { + @extend %consul-intention-list; +} diff --git a/ui-v2/app/styles/components/consul-intention-list/index.scss b/ui-v2/app/styles/components/consul-intention-list/index.scss new file mode 100644 index 000000000..8192f54e8 --- /dev/null +++ b/ui-v2/app/styles/components/consul-intention-list/index.scss @@ -0,0 +1,16 @@ +@import './skin'; +@import './layout'; + +%consul-intention-list td.source, +%consul-intention-list td.destination { + @extend %tbody-th; +} +%consul-intention-list td.intent-allow strong { + @extend %increased-pill, %pill-allow; +} +%consul-intention-list td.intent-deny strong { + @extend %increased-pill, %pill-deny; +} +%consul-intention-list td.intent-l7-rules strong { + @extend %increased-pill, %pill-l7; +} diff --git a/ui-v2/app/styles/components/consul-intention-list/layout.scss b/ui-v2/app/styles/components/consul-intention-list/layout.scss new file mode 100644 index 000000000..9b0185471 --- /dev/null +++ b/ui-v2/app/styles/components/consul-intention-list/layout.scss @@ -0,0 +1,27 @@ +%consul-intention-list td { + height: 59px; +} +%consul-intention-list tr > *:nth-child(1) { + width: calc(30% - 50px); +} +%consul-intention-list tr > *:nth-child(2) { + width: 100px; +} +%consul-intention-list tr > *:nth-child(3) { + width: calc(30% - 50px); +} +%consul-intention-list tr > *:nth-child(4) { + width: calc(40% - 220px); +} +%consul-intention-list tr > *:nth-child(5) { + width: 160px; +} +%consul-intention-list tr > *:last-child { + width: 60px; +} + +@media #{$--lt-horizontal-nav} { + %consul-intention-list tr > :not(.source):not(.destination):not(.intent) { + display: none; + } +} diff --git a/ui-v2/app/styles/components/consul-intention-list/skin.scss b/ui-v2/app/styles/components/consul-intention-list/skin.scss new file mode 100644 index 000000000..c96a4e7af --- /dev/null +++ b/ui-v2/app/styles/components/consul-intention-list/skin.scss @@ -0,0 +1,3 @@ +%consul-intention-list td.permissions { + color: $blue-500; +} diff --git a/ui-v2/app/styles/components/consul-intention-permission-list.scss b/ui-v2/app/styles/components/consul-intention-permission-list.scss new file mode 100644 index 000000000..139c5be69 --- /dev/null +++ b/ui-v2/app/styles/components/consul-intention-permission-list.scss @@ -0,0 +1,4 @@ +@import './consul-intention-permission-list/index'; +.consul-intention-permission-list { + @extend %consul-intention-permission-list; +} diff --git a/ui-v2/app/styles/components/consul-intention-permission-list/index.scss b/ui-v2/app/styles/components/consul-intention-permission-list/index.scss new file mode 100644 index 000000000..755ed8e6d --- /dev/null +++ b/ui-v2/app/styles/components/consul-intention-permission-list/index.scss @@ -0,0 +1,11 @@ +@import './skin'; +@import './layout'; +%consul-intention-permission-list > ul > li { + @extend %list-row, %list-row-detail; +} +%consul-intention-permission-list .intent-allow { + @extend %pill, %pill-allow; +} +%consul-intention-permission-list .intent-deny { + @extend %pill, %pill-deny; +} diff --git a/ui-v2/app/styles/components/consul-intention-permission-list/layout.scss b/ui-v2/app/styles/components/consul-intention-permission-list/layout.scss new file mode 100644 index 000000000..589ba10ca --- /dev/null +++ b/ui-v2/app/styles/components/consul-intention-permission-list/layout.scss @@ -0,0 +1,3 @@ +%consul-intention-permission-list strong { + margin-right: 8px; +} diff --git a/ui-v2/app/styles/components/consul-intention-permission-list/skin.scss b/ui-v2/app/styles/components/consul-intention-permission-list/skin.scss new file mode 100644 index 000000000..cb5b17de2 --- /dev/null +++ b/ui-v2/app/styles/components/consul-intention-permission-list/skin.scss @@ -0,0 +1,9 @@ +%consul-intention-permission-list dt::before { + @extend %with-glyph-icon; +} +%consul-intention-permission-list dl.route-path dt::before { + content: 'P'; +} +%consul-intention-permission-list dl.route-header dt::before { + content: 'H'; +} diff --git a/ui-v2/app/styles/components/discovery-chain/layout.scss b/ui-v2/app/styles/components/discovery-chain/layout.scss index f1da3118f..afff6b699 100644 --- a/ui-v2/app/styles/components/discovery-chain/layout.scss +++ b/ui-v2/app/styles/components/discovery-chain/layout.scss @@ -104,9 +104,6 @@ display: block; width: 33px; } -%route-card section header > *::before { - padding: 0 8px; -} /**/ /* resolver */ %resolver-card a { diff --git a/ui-v2/app/styles/components/discovery-chain/skin.scss b/ui-v2/app/styles/components/discovery-chain/skin.scss index 63606927d..fdfcf93aa 100644 --- a/ui-v2/app/styles/components/discovery-chain/skin.scss +++ b/ui-v2/app/styles/components/discovery-chain/skin.scss @@ -92,8 +92,7 @@ } %resolver-card dt, %route-card section header > *::before { - background-color: $gray-100; - visibility: visible; + @extend %with-glyph-icon; } %route-card .match-headers header *::before { content: 'H'; diff --git a/ui-v2/app/styles/components/form-elements.scss b/ui-v2/app/styles/components/form-elements.scss index ab9c71a09..40081f33b 100644 --- a/ui-v2/app/styles/components/form-elements.scss +++ b/ui-v2/app/styles/components/form-elements.scss @@ -13,6 +13,9 @@ label span { %main-content form { @extend %form; } +%form span.label { + @extend %form-element-label; +} %form table, %radio-group, %checkbox-group, diff --git a/ui-v2/app/styles/components/list-row.scss b/ui-v2/app/styles/components/list-row.scss new file mode 100644 index 000000000..b9db58f16 --- /dev/null +++ b/ui-v2/app/styles/components/list-row.scss @@ -0,0 +1,4 @@ +@import './list-row/index'; +.list-row { + @extend %list-row; +} diff --git a/ui-v2/app/styles/components/list-row/index.scss b/ui-v2/app/styles/components/list-row/index.scss new file mode 100644 index 000000000..bc1825219 --- /dev/null +++ b/ui-v2/app/styles/components/list-row/index.scss @@ -0,0 +1,2 @@ +@import './skin'; +@import './layout'; diff --git a/ui-v2/app/styles/components/list-row/layout.scss b/ui-v2/app/styles/components/list-row/layout.scss new file mode 100644 index 000000000..22df4a5ae --- /dev/null +++ b/ui-v2/app/styles/components/list-row/layout.scss @@ -0,0 +1,48 @@ +%list-row { + padding-top: 10px; + padding-bottom: 10px; + /* whilst this isn't in the designs this makes our temporary rollover look better */ + padding-left: 12px; +} +%list-row dl { + margin: 0; + padding: 0; +} +%list-row-detail, +%list-row-header { + display: flex; + flex-wrap: nowrap; + overflow-x: hidden; +} +%list-row-detail ul, +%list-row-detail dl, +%list-row-header dl { + display: inline-flex; +} +%list-row-header *, +%list-row-detail * { + white-space: nowrap; + flex-wrap: nowrap; +} + +%list-row-detail dl, +%list-row-detail > span { + margin-right: 18px; +} +%list-row-detail dl.node dt::before { + margin-top: 3px; +} +%list-row-detail dl dt::before { + margin-right: 4px; + margin-top: 2px; +} +%list-row-header-icon { + margin-right: 6px; + margin-left: -2px; +} +%list-row-header dt { + display: none; +} +%list-row-header dd::before { + font-size: 0.9em; +} diff --git a/ui-v2/app/styles/components/list-row/skin.scss b/ui-v2/app/styles/components/list-row/skin.scss new file mode 100644 index 000000000..38af5f0fd --- /dev/null +++ b/ui-v2/app/styles/components/list-row/skin.scss @@ -0,0 +1,23 @@ +%list-row { + list-style-type: none; + border: $decor-border-100; + border-top-color: $transparent; + border-bottom-color: $gray-200; + border-right-color: $transparent; + border-left-color: $transparent; +} +%list-row-intent { + border-color: $gray-200; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + border-top-color: $transparent; + cursor: pointer; +} +%list-row-header { + color: $black; +} +%list-row-header * { + color: inherit; +} +%list-row-detail { + color: $gray-500; +} diff --git a/ui-v2/app/styles/components/pill.scss b/ui-v2/app/styles/components/pill.scss index c9222f558..205ba65cb 100644 --- a/ui-v2/app/styles/components/pill.scss +++ b/ui-v2/app/styles/components/pill.scss @@ -1,3 +1,30 @@ +%pill-allow:before, +%pill-deny:before, +%pill-l7:before { + @extend %as-pseudo; + margin-right: 5px; + font-size: 0.9em; +} +%pill-allow { + color: $green-800; + background-color: $green-100; +} +%pill-allow::before { + @extend %with-arrow-right-color-mask; +} +%pill-deny { + color: $red-800; + background-color: $red-100; +} +%pill-deny::before { + @extend %with-deny-color-mask; +} +%pill-l7 { + @extend %frame-gray-900; +} +%pill-l7::before { + @extend %with-layers-mask; +} td strong { @extend %pill, %frame-gray-900; margin-right: 3px; diff --git a/ui-v2/app/styles/components/radio-card.scss b/ui-v2/app/styles/components/radio-card.scss new file mode 100644 index 000000000..f93c8e907 --- /dev/null +++ b/ui-v2/app/styles/components/radio-card.scss @@ -0,0 +1,4 @@ +@import './radio-card/index'; +.radio-card { + @extend %radio-card; +} diff --git a/ui-v2/app/styles/components/radio-card/index.scss b/ui-v2/app/styles/components/radio-card/index.scss new file mode 100644 index 000000000..bc1825219 --- /dev/null +++ b/ui-v2/app/styles/components/radio-card/index.scss @@ -0,0 +1,2 @@ +@import './skin'; +@import './layout'; diff --git a/ui-v2/app/styles/components/radio-card/layout.scss b/ui-v2/app/styles/components/radio-card/layout.scss new file mode 100644 index 000000000..1c9b4a64f --- /dev/null +++ b/ui-v2/app/styles/components/radio-card/layout.scss @@ -0,0 +1,16 @@ +%radio-card { + float: none !important; + margin-right: 0 !important; +} +%radio-card { + display: flex !important; +} +%radio-card > :first-child { + padding: 10px; + display: grid; + align-items: center; + justify-items: center; +} +%radio-card > :last-child { + padding: 18px; +} diff --git a/ui-v2/app/styles/components/radio-card/skin.scss b/ui-v2/app/styles/components/radio-card/skin.scss new file mode 100644 index 000000000..21417a492 --- /dev/null +++ b/ui-v2/app/styles/components/radio-card/skin.scss @@ -0,0 +1,32 @@ +%radio-card { + border: $decor-border-100; + border-radius: $decor-radius-100; + border-color: $gray-200; + box-shadow: $decor-elevation-400; + color: $gray-500; + cursor: pointer; +} +%radio-card.checked { + border-color: $blue-500; +} +%radio-card > :first-child { + background-color: $gray-050; +} +%radio-card.checked > :first-child { + background-color: $blue-050; +} +%radio-card header { + margin-bottom: 0.5em; +} +%radio-card header { + color: $black; +} +%radio-card-with-icon > :last-child { + padding-left: 47px; + position: relative; +} +%radio-card-with-icon > :last-child::before { + position: absolute; + left: 14px; + font-size: 1rem; +} diff --git a/ui-v2/app/styles/components/table.scss b/ui-v2/app/styles/components/table.scss index 5e8277817..61ae76c4f 100644 --- a/ui-v2/app/styles/components/table.scss +++ b/ui-v2/app/styles/components/table.scss @@ -23,72 +23,41 @@ --consul-icon: #{$consul-logo-color-svg}; --aws-icon: #{$aws-logo-color-svg}; } - -td.folder::before { - @extend %with-folder-outline-mask, %as-pseudo; - background-color: $gray-300; - margin-top: 1px; - margin-right: 5px; -} -td.destination { - @extend %tbody-th; -} -td.intent-allow strong, -td.intent-deny strong { - visibility: hidden; -} -td.intent-allow strong::before { - @extend %with-arrow-right-color-icon, %as-pseudo; - background-size: 24px; -} -td.intent-deny strong::before { - @extend %with-deny-color-icon, %as-pseudo; -} -table:not(.sessions) tbody tr { - cursor: pointer; -} -table:not(.sessions) td:first-child { - padding: 0; -} -table:not(.sessions) tbody tr:hover { - box-shadow: $decor-elevation-300; -} table.consul-metadata-list tbody tr { cursor: default; } table.consul-metadata-list tbody tr:hover { box-shadow: none; } -/* Header Tooltips/Icon*/ -th { - overflow: visible; + +%table th span::after { + @extend %with-info-circle-outline-mask, %as-pseudo; + color: $gray-500; + margin-left: 4px; } -th span::after { - @extend %with-info-circle-outline-icon, %as-pseudo; - opacity: 0.6; +%table tbody tr { + cursor: pointer; } -th span { - @extend %with-tooltip; - margin-left: 2px; +%table td:first-child { + padding: 0; } -th span em { - width: 250px; - font-style: normal; - white-space: normal !important; +%table tbody tr:hover { + box-shadow: $decor-elevation-300; +} + +%table td.folder::before { + @extend %with-folder-outline-mask, %as-pseudo; + background-color: $gray-300; + margin-top: 1px; + margin-right: 5px; } /**/ @media #{$--lt-wide-table} { /* hide actions on narrow screens, you can always click in do everything from there */ - tr > .actions { + %table tr > .actions { display: none; } - html.template-node.template-show #lock-sessions tr > :not(:first-child):not(:last-child) { - display: none; - } - html.template-node.template-show #lock-sessions td:last-child { - padding: 0; - } .consul-intention-list tr > :nth-last-child(2) { display: none; } diff --git a/ui-v2/app/styles/layouts/containers.scss b/ui-v2/app/styles/layouts/containers.scss index 697c8fb04..d6cd89dbc 100644 --- a/ui-v2/app/styles/layouts/containers.scss +++ b/ui-v2/app/styles/layouts/containers.scss @@ -52,7 +52,7 @@ $ideal-content-padding: 33px; padding-right: $ideal-viewport-padding; } } -form > fieldset [role='group'] { +fieldset [role='group'] { display: flex; flex-wrap: wrap; flex-direction: row; diff --git a/ui-v2/app/styles/typography.scss b/ui-v2/app/styles/typography.scss index 6500029f8..995e3c28f 100644 --- a/ui-v2/app/styles/typography.scss +++ b/ui-v2/app/styles/typography.scss @@ -14,6 +14,7 @@ h3 { @extend %h3; font-size: $typo-header-300; } +%radio-card header, fieldset > header, %main-nav-horizontal-action, %app-view-content div > dl > dt, diff --git a/ui-v2/app/templates/dc/intentions/edit.hbs b/ui-v2/app/templates/dc/intentions/edit.hbs index eeed2feca..4ebf47a87 100644 --- a/ui-v2/app/templates/dc/intentions/edit.hbs +++ b/ui-v2/app/templates/dc/intentions/edit.hbs @@ -11,20 +11,17 @@

    -{{#if item.ID }} - Edit Intention +{{#if item.IsEditable}} + {{#if item.ID}} + Edit Intention + {{else}} + New Intention + {{/if}} {{else}} - New Intention + View Intention {{/if}}

    - -{{#if item.ID}} - - Copy UUID - -{{/if}} - + diff --git a/ui-v2/package.json b/ui-v2/package.json index 423d4ab3c..ebed65fc1 100644 --- a/ui-v2/package.json +++ b/ui-v2/package.json @@ -55,7 +55,7 @@ "@ember/optional-features": "^1.3.0", "@glimmer/component": "^1.0.0", "@glimmer/tracking": "^1.0.0", - "@hashicorp/consul-api-double": "^3.0.0", + "@hashicorp/consul-api-double": "^5.0.0", "@hashicorp/ember-cli-api-double": "^3.1.0", "@xstate/fsm": "^1.4.0", "babel-eslint": "^10.0.3", @@ -90,6 +90,7 @@ "ember-composable-helpers": "~4.0.0", "ember-computed-style": "^0.3.0", "ember-data": "~3.16.0", + "ember-data-model-fragments": "5.0.0-beta.0", "ember-exam": "^4.0.0", "ember-export-application-global": "^2.0.1", "ember-href-to": "^3.1.0", diff --git a/ui-v2/tests/acceptance/dc/intentions/delete.feature b/ui-v2/tests/acceptance/dc/intentions/delete.feature index 470bee06b..dd8feec09 100644 --- a/ui-v2/tests/acceptance/dc/intentions/delete.feature +++ b/ui-v2/tests/acceptance/dc/intentions/delete.feature @@ -7,6 +7,7 @@ Feature: dc / intentions / deleting: Deleting items with confirmations, success --- SourceName: name ID: ee52203d-989f-4f7a-ab5a-2bef004164ca + Meta: ~ --- When I visit the intentions page for yaml --- diff --git a/ui-v2/tests/acceptance/dc/intentions/navigation.feature b/ui-v2/tests/acceptance/dc/intentions/navigation.feature index 76e24d034..38979f1a6 100644 --- a/ui-v2/tests/acceptance/dc/intentions/navigation.feature +++ b/ui-v2/tests/acceptance/dc/intentions/navigation.feature @@ -1,30 +1,44 @@ -@setupApplicationTest -Feature: dc / intentions / navigation - Scenario: Clicking a intention in the listing and back again - Given 1 datacenter model with the value "dc-1" - And 3 intention models - When I visit the intentions page for yaml - --- - dc: dc-1 - --- - Then the url should be /dc-1/intentions - And the title should be "Intentions - Consul" - Then I see 3 intention models - When I click intention on the intentions - Then a GET request was made to "/v1/internal/ui/services?dc=dc-1&ns=*" - And I click "[data-test-back]" - Then the url should be /dc-1/intentions - Scenario: Clicking the create button and back again - Given 1 datacenter model with the value "dc-1" - And 3 intention models - When I visit the intentions page for yaml - --- - dc: dc-1 - --- - Then the url should be /dc-1/intentions - And the title should be "Intentions - Consul" - Then I see 3 intention models - When I click create - Then the url should be /dc-1/intentions/create - And I click "[data-test-back]" - Then the url should be /dc-1/intentions +@setupApplicationTest +Feature: dc / intentions / navigation + Background: + Given 1 datacenter model with the value "dc-1" + And 3 intention models from yaml + --- + - ID: 755b72bd-f5ab-4c92-90cc-bed0e7d8e9f0 + Action: allow + Meta: ~ + - ID: 755b72bd-f5ab-4c92-90cc-bed0e7d8e9f1 + Action: deny + Meta: ~ + - ID: 0755b72bd-f5ab-4c92-90cc-bed0e7d8e9f2 + Action: deny + Meta: ~ + --- + Scenario: Clicking a intention in the listing and back again + When I visit the intentions page for yaml + --- + dc: dc-1 + --- + Then the url should be /dc-1/intentions + And the title should be "Intentions - Consul" + Then I see 3 intention models + Given 1 intention model from yaml + --- + ID: 755b72bd-f5ab-4c92-90cc-bed0e7d8e9f0 + --- + When I click intention on the intentions + Then a GET request was made to "/v1/internal/ui/services?dc=dc-1&ns=*" + And I click "[data-test-back]" + Then the url should be /dc-1/intentions + Scenario: Clicking the create button and back again + When I visit the intentions page for yaml + --- + dc: dc-1 + --- + Then the url should be /dc-1/intentions + And the title should be "Intentions - Consul" + Then I see 3 intention models + When I click create + Then the url should be /dc-1/intentions/create + And I click "[data-test-back]" + Then the url should be /dc-1/intentions diff --git a/ui-v2/tests/acceptance/dc/services/show/intentions.feature b/ui-v2/tests/acceptance/dc/services/show/intentions.feature index 5400dd177..3bde9f607 100644 --- a/ui-v2/tests/acceptance/dc/services/show/intentions.feature +++ b/ui-v2/tests/acceptance/dc/services/show/intentions.feature @@ -10,7 +10,18 @@ Feature: dc / services / show / intentions: Intentions per service Name: service-0 ID: service-0-with-id --- - And 3 intention models + And 3 intention models from yaml + --- + - ID: 755b72bd-f5ab-4c92-90cc-bed0e7d8e9f0 + Action: allow + Meta: ~ + - ID: 755b72bd-f5ab-4c92-90cc-bed0e7d8e9f1 + Action: deny + Meta: ~ + - ID: 0755b72bd-f5ab-4c92-90cc-bed0e7d8e9f2 + Action: deny + Meta: ~ + --- When I visit the service page for yaml --- dc: dc1 diff --git a/ui-v2/tests/integration/serializers/intention-test.js b/ui-v2/tests/integration/serializers/intention-test.js index 2f503ac47..17c89484f 100644 --- a/ui-v2/tests/integration/serializers/intention-test.js +++ b/ui-v2/tests/integration/serializers/intention-test.js @@ -36,7 +36,9 @@ module('Integration | Serializer | intention', function(hooks) { dc: dc, } ); - assert.deepEqual(actual, expected); + assert.equal(actual[0].Namespace, expected[0].Namespace); + assert.equal(actual[0].Datacenter, expected[0].Datacenter); + assert.equal(actual[0].uid, expected[0].uid); }); }); test('respondForQueryRecord returns the correct data for item endpoint', function(assert) { @@ -66,7 +68,9 @@ module('Integration | Serializer | intention', function(hooks) { dc: dc, } ); - assert.deepEqual(actual, expected); + assert.equal(actual.Namespace, expected.Namespace); + assert.equal(actual.Datacenter, expected.Datacenter); + assert.equal(actual.uid, expected.uid); }); }); }); diff --git a/ui-v2/tests/integration/services/repository/intention-test.js b/ui-v2/tests/integration/services/repository/intention-test.js index 3dedd97f4..07e9d6747 100644 --- a/ui-v2/tests/integration/services/repository/intention-test.js +++ b/ui-v2/tests/integration/services/repository/intention-test.js @@ -20,7 +20,7 @@ test('findAllByDatacenter returns the correct data for list endpoint', function( this.subject(), function retrieveStub(stub) { return stub(`/v1/connect/intentions?dc=${dc}`, { - CONSUL_INTENTION_COUNT: '100', + CONSUL_INTENTION_COUNT: '1', }); }, function performTest(service) { @@ -28,19 +28,20 @@ test('findAllByDatacenter returns the correct data for list endpoint', function( }, function performAssertion(actual, expected) { assert.deepEqual( - actual, + actual[0], expected(function(payload) { - return payload.map(item => - Object.assign({}, item, { - CreatedAt: new Date(item.CreatedAt), - UpdatedAt: new Date(item.UpdatedAt), - SyncTime: now, - Datacenter: dc, - // TODO: nspace isn't required here, once we've - // refactored out our Serializer this can go - uid: `["${nspace}","${dc}","${item.ID}"]`, - }) - ); + const item = payload[0]; + return { + ...item, + CreatedAt: new Date(item.CreatedAt), + UpdatedAt: new Date(item.UpdatedAt), + Legacy: true, + SyncTime: now, + Datacenter: dc, + // TODO: nspace isn't required here, once we've + // refactored out our Serializer this can go + uid: `["${nspace}","${dc}","${item.ID}"]`, + }; }) ); } @@ -63,6 +64,7 @@ test('findBySlug returns the correct data for item endpoint', function(assert) { expected(function(payload) { const item = payload; return Object.assign({}, item, { + Legacy: true, CreatedAt: new Date(item.CreatedAt), UpdatedAt: new Date(item.UpdatedAt), Datacenter: dc, diff --git a/ui-v2/yarn.lock b/ui-v2/yarn.lock index 4d4b02dbf..8c20a8f0d 100644 --- a/ui-v2/yarn.lock +++ b/ui-v2/yarn.lock @@ -18,6 +18,15 @@ invariant "^2.2.4" semver "^5.5.0" +"@babel/compat-data@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.11.0.tgz#e9f73efe09af1355b723a7f39b11bad637d7c99c" + integrity sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ== + dependencies: + browserslist "^4.12.0" + invariant "^2.2.4" + semver "^5.5.0" + "@babel/core@^7.0.0", "@babel/core@^7.1.6", "@babel/core@^7.10.2", "@babel/core@^7.2.2", "@babel/core@^7.3.4", "@babel/core@^7.7.7": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.4.tgz#780e8b83e496152f8dd7df63892b2e052bf1d51d" @@ -40,6 +49,28 @@ semver "^5.4.1" source-map "^0.5.0" +"@babel/core@^7.11.0": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.5.tgz#6ad96e2f71899ea3f9b651f0a911e85205d1ff6d" + integrity sha512-fsEANVOcZHzrsV6dMVWqpSeXClq3lNbYrfFGme6DE25FQWe7pyeYpXyx9guqUnpy466JLzZ8z4uwSr2iv60V5Q== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.5" + "@babel/helper-module-transforms" "^7.11.0" + "@babel/helpers" "^7.10.4" + "@babel/parser" "^7.11.5" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.11.5" + "@babel/types" "^7.11.5" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.19" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.6.1" + "@babel/generator@^7.10.4", "@babel/generator@^7.4.0": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.4.tgz#e49eeed9fe114b62fa5b181856a43a5e32f5f243" @@ -50,6 +81,15 @@ lodash "^4.17.13" source-map "^0.5.0" +"@babel/generator@^7.11.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.5.tgz#a5582773425a468e4ba269d9a1f701fbca6a7a82" + integrity sha512-9UqHWJ4IwRTy4l0o8gq2ef8ws8UPzvtMkVKjTLAiRmza9p9V6Z+OfuNd9fB1j5Q67F+dVJtPC2sZXI8NM9br4g== + dependencies: + "@babel/types" "^7.11.5" + jsesc "^2.5.1" + source-map "^0.6.1" + "@babel/helper-annotate-as-pure@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" @@ -97,6 +137,18 @@ "@babel/helper-replace-supers" "^7.10.4" "@babel/helper-split-export-declaration" "^7.10.4" +"@babel/helper-create-class-features-plugin@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz#9f61446ba80e8240b0a5c85c6fdac8459d6f259d" + integrity sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-member-expression-to-functions" "^7.10.5" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" + "@babel/helper-create-regexp-features-plugin@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" @@ -153,6 +205,13 @@ dependencies: "@babel/types" "^7.10.4" +"@babel/helper-member-expression-to-functions@^7.10.5": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" + integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q== + dependencies: + "@babel/types" "^7.11.0" + "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" @@ -173,6 +232,19 @@ "@babel/types" "^7.10.4" lodash "^4.17.13" +"@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" + integrity sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/template" "^7.10.4" + "@babel/types" "^7.11.0" + lodash "^4.17.19" + "@babel/helper-optimise-call-expression@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" @@ -221,6 +293,13 @@ "@babel/template" "^7.10.4" "@babel/types" "^7.10.4" +"@babel/helper-skip-transparent-expression-wrappers@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz#eec162f112c2f58d3af0af125e3bb57665146729" + integrity sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q== + dependencies: + "@babel/types" "^7.11.0" + "@babel/helper-split-export-declaration@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz#2c70576eaa3b5609b24cb99db2888cc3fc4251d1" @@ -228,6 +307,13 @@ dependencies: "@babel/types" "^7.10.4" +"@babel/helper-split-export-declaration@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" + integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== + dependencies: + "@babel/types" "^7.11.0" + "@babel/helper-validator-identifier@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" @@ -266,6 +352,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.4.tgz#9eedf27e1998d87739fb5028a5120557c06a1a64" integrity sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA== +"@babel/parser@^7.11.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" + integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== + "@babel/plugin-proposal-async-generator-functions@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.4.tgz#4b65abb3d9bacc6c657aaa413e56696f9f170fc6" @@ -292,6 +383,15 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-decorators" "^7.10.4" +"@babel/plugin-proposal-decorators@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.10.5.tgz#42898bba478bc4b1ae242a703a953a7ad350ffb4" + integrity sha512-Sc5TAQSZuLzgY0664mMDn24Vw2P8g/VhyLyGPaWiHahhgLqeZvcGeyBZOrJW0oSKIK2mvQ22a1ENXBIQLhrEiQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-decorators" "^7.10.4" + "@babel/plugin-proposal-dynamic-import@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz#ba57a26cb98b37741e9d5bca1b8b0ddf8291f17e" @@ -300,6 +400,14 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-dynamic-import" "^7.8.0" +"@babel/plugin-proposal-export-namespace-from@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz#570d883b91031637b3e2958eea3c438e62c05f54" + integrity sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-proposal-json-strings@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz#593e59c63528160233bd321b1aebe0820c2341db" @@ -308,6 +416,14 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.0" +"@babel/plugin-proposal-logical-assignment-operators@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz#9f80e482c03083c87125dee10026b58527ea20c8" + integrity sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4", "@babel/plugin-proposal-nullish-coalescing-operator@^7.4.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" @@ -333,6 +449,15 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.0" "@babel/plugin-transform-parameters" "^7.10.4" +"@babel/plugin-proposal-object-rest-spread@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz#bd81f95a1f746760ea43b6c2d3d62b11790ad0af" + integrity sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.10.4" + "@babel/plugin-proposal-optional-catch-binding@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz#31c938309d24a78a49d68fdabffaa863758554dd" @@ -349,6 +474,15 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-optional-chaining" "^7.8.0" +"@babel/plugin-proposal-optional-chaining@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz#de5866d0646f6afdaab8a566382fe3a221755076" + integrity sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-proposal-private-methods@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz#b160d972b8fdba5c7d111a145fc8c421fc2a6909" @@ -393,6 +527,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-json-strings@^7.8.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" @@ -400,6 +541,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" @@ -569,6 +717,15 @@ "@babel/helper-plugin-utils" "^7.10.4" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-amd@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz#1b9cddaf05d9e88b3aad339cb3e445c4f020a9b1" + integrity sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw== + dependencies: + "@babel/helper-module-transforms" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" + "@babel/plugin-transform-modules-commonjs@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz#66667c3eeda1ebf7896d41f1f16b17105a2fbca0" @@ -665,6 +822,16 @@ resolve "^1.8.1" semver "^5.5.1" +"@babel/plugin-transform-runtime@^7.11.0": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.5.tgz#f108bc8e0cf33c37da031c097d1df470b3a293fc" + integrity sha512-9aIoee+EhjySZ6vY5hnLjigHzunBlscx9ANKutkeWTJTx6m5Rbq6Ic01tLvO54lSusR+BxV7u4UDdCmXv5aagg== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + resolve "^1.8.1" + semver "^5.5.1" + "@babel/plugin-transform-shorthand-properties@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6" @@ -679,6 +846,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" +"@babel/plugin-transform-spread@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz#fa84d300f5e4f57752fe41a6d1b3c554f13f17cc" + integrity sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" + "@babel/plugin-transform-sticky-regex@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz#8f3889ee8657581130a29d9cc91d7c73b7c4a28d" @@ -711,6 +886,15 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-typescript" "^7.10.4" +"@babel/plugin-transform-typescript@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.11.0.tgz#2b4879676af37342ebb278216dd090ac67f13abb" + integrity sha512-edJsNzTtvb3MaXQwj8403B7mZoGu9ElDJQZOKjGUnvilquxBA3IQoEIOvkX/1O8xfAsnHS/oQhe2w/IXrr+w0w== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-typescript" "^7.10.4" + "@babel/plugin-transform-typescript@~7.4.0": version "7.4.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.4.5.tgz#ab3351ba35307b79981993536c93ff8be050ba28" @@ -760,6 +944,14 @@ core-js "^2.6.5" regenerator-runtime "^0.13.4" +"@babel/polyfill@^7.10.4": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.11.5.tgz#df550b2ec53abbc2ed599367ec59e64c7a707bb5" + integrity sha512-FunXnE0Sgpd61pKSj2OSOs1D44rKTD3pGOfGilZ6LGrrIH0QEtJlTjqOqdF8Bs98JmjfGhni2BBkTfv9KcKJ9g== + dependencies: + core-js "^2.6.5" + regenerator-runtime "^0.13.4" + "@babel/preset-env@^7.10.2": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.10.4.tgz#fbf57f9a803afd97f4f32e4f798bb62e4b2bef5f" @@ -830,6 +1022,80 @@ levenary "^1.1.1" semver "^5.5.0" +"@babel/preset-env@^7.11.0": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.5.tgz#18cb4b9379e3e92ffea92c07471a99a2914e4272" + integrity sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA== + dependencies: + "@babel/compat-data" "^7.11.0" + "@babel/helper-compilation-targets" "^7.10.4" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-proposal-async-generator-functions" "^7.10.4" + "@babel/plugin-proposal-class-properties" "^7.10.4" + "@babel/plugin-proposal-dynamic-import" "^7.10.4" + "@babel/plugin-proposal-export-namespace-from" "^7.10.4" + "@babel/plugin-proposal-json-strings" "^7.10.4" + "@babel/plugin-proposal-logical-assignment-operators" "^7.11.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4" + "@babel/plugin-proposal-numeric-separator" "^7.10.4" + "@babel/plugin-proposal-object-rest-spread" "^7.11.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.10.4" + "@babel/plugin-proposal-optional-chaining" "^7.11.0" + "@babel/plugin-proposal-private-methods" "^7.10.4" + "@babel/plugin-proposal-unicode-property-regex" "^7.10.4" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-class-properties" "^7.10.4" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.10.4" + "@babel/plugin-transform-arrow-functions" "^7.10.4" + "@babel/plugin-transform-async-to-generator" "^7.10.4" + "@babel/plugin-transform-block-scoped-functions" "^7.10.4" + "@babel/plugin-transform-block-scoping" "^7.10.4" + "@babel/plugin-transform-classes" "^7.10.4" + "@babel/plugin-transform-computed-properties" "^7.10.4" + "@babel/plugin-transform-destructuring" "^7.10.4" + "@babel/plugin-transform-dotall-regex" "^7.10.4" + "@babel/plugin-transform-duplicate-keys" "^7.10.4" + "@babel/plugin-transform-exponentiation-operator" "^7.10.4" + "@babel/plugin-transform-for-of" "^7.10.4" + "@babel/plugin-transform-function-name" "^7.10.4" + "@babel/plugin-transform-literals" "^7.10.4" + "@babel/plugin-transform-member-expression-literals" "^7.10.4" + "@babel/plugin-transform-modules-amd" "^7.10.4" + "@babel/plugin-transform-modules-commonjs" "^7.10.4" + "@babel/plugin-transform-modules-systemjs" "^7.10.4" + "@babel/plugin-transform-modules-umd" "^7.10.4" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4" + "@babel/plugin-transform-new-target" "^7.10.4" + "@babel/plugin-transform-object-super" "^7.10.4" + "@babel/plugin-transform-parameters" "^7.10.4" + "@babel/plugin-transform-property-literals" "^7.10.4" + "@babel/plugin-transform-regenerator" "^7.10.4" + "@babel/plugin-transform-reserved-words" "^7.10.4" + "@babel/plugin-transform-shorthand-properties" "^7.10.4" + "@babel/plugin-transform-spread" "^7.11.0" + "@babel/plugin-transform-sticky-regex" "^7.10.4" + "@babel/plugin-transform-template-literals" "^7.10.4" + "@babel/plugin-transform-typeof-symbol" "^7.10.4" + "@babel/plugin-transform-unicode-escapes" "^7.10.4" + "@babel/plugin-transform-unicode-regex" "^7.10.4" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.11.5" + browserslist "^4.12.0" + core-js-compat "^3.6.2" + invariant "^2.2.2" + levenary "^1.1.1" + semver "^5.5.0" + "@babel/preset-modules@^0.1.3": version "0.1.3" resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" @@ -867,6 +1133,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.11.0": + version "7.11.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" + integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.10.4", "@babel/template@^7.4.0": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" @@ -891,6 +1164,21 @@ globals "^11.1.0" lodash "^4.17.13" +"@babel/traverse@^7.11.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" + integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.5" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/parser" "^7.11.5" + "@babel/types" "^7.11.5" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.19" + "@babel/types@^7.1.6", "@babel/types@^7.10.4", "@babel/types@^7.3.2", "@babel/types@^7.3.4", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.7.2": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.4.tgz#369517188352e18219981efd156bfdb199fff1ee" @@ -900,6 +1188,15 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@babel/types@^7.11.0", "@babel/types@^7.11.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" + integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -1222,15 +1519,15 @@ faker "^4.1.0" js-yaml "^3.13.1" -"@hashicorp/consul-api-double@^3.0.0": - version "3.1.6" - resolved "https://registry.yarnpkg.com/@hashicorp/consul-api-double/-/consul-api-double-3.1.6.tgz#46095438b6989a12cab382a88fdb7b227d834794" - integrity sha512-mRH7X7k1zSu/Aq+rs5VoJYrIhD3pO57d+j98dicfs+3KaMO1mQYFYKgyugY/g0kY9FQH3+vySeZ0W5nQs45V1Q== +"@hashicorp/consul-api-double@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@hashicorp/consul-api-double/-/consul-api-double-5.0.0.tgz#099e56ded356421cdfa5e63b4a07c9a2232ffb88" + integrity sha512-2+Rg4mfxTTUrJiYeRWV5mEWVZTYUK1udFNMb79ygNdC/HScDvU8sTVwPrf6GuRve6oLakk1lB/D4d6AsMmtS4w== "@hashicorp/ember-cli-api-double@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@hashicorp/ember-cli-api-double/-/ember-cli-api-double-3.1.0.tgz#ce228ac5c8a46c7a10112f5bc0fb782c47775b60" - integrity sha512-G8dDSewInFZOeD5sprdZPw7ZKUYlkJ9bJxPkEaMRPbC6ZN4ZHqeFWB1xXeq2ROtR07J6Xbs+BrFIE6GHTshpEg== + version "3.1.1" + resolved "https://registry.yarnpkg.com/@hashicorp/ember-cli-api-double/-/ember-cli-api-double-3.1.1.tgz#ba16a514131ce409054d1ae1a71483941d937d37" + integrity sha512-VLvV/m+Sx+vG+tHK1FeVjiBXwt8KcIWqgFavglrEBTkVTA2o7uP0xN9nKOJjos49KK+h1K3fCwMK5ltz7Kt97w== dependencies: "@hashicorp/api-double" "^1.6.1" array-range "^1.0.1" @@ -2298,6 +2595,13 @@ babel-plugin-ember-modules-api-polyfill@^2.13.4, babel-plugin-ember-modules-api- dependencies: ember-rfc176-data "^0.3.13" +babel-plugin-ember-modules-api-polyfill@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-ember-modules-api-polyfill/-/babel-plugin-ember-modules-api-polyfill-3.1.1.tgz#c6e9ede43b64c4e36512f260e42e829b071d9b4f" + integrity sha512-hRTnr59fJ6cIiSiSgQLM9QRiVv/RrBAYRYggCPQDj4dvYhOWZeoX6e+1jFY1qC3tJnSDuMWu3OrDciSIi1MJ0A== + dependencies: + ember-rfc176-data "^0.3.15" + babel-plugin-filter-imports@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/babel-plugin-filter-imports/-/babel-plugin-filter-imports-3.0.0.tgz#a849683837ad29960da17492fb32789ab6b09a11" @@ -2995,6 +3299,24 @@ broccoli-babel-transpiler@^7.3.0, broccoli-babel-transpiler@^7.5.0: rsvp "^4.8.4" workerpool "^3.1.1" +broccoli-babel-transpiler@^7.7.0: + version "7.7.0" + resolved "https://registry.yarnpkg.com/broccoli-babel-transpiler/-/broccoli-babel-transpiler-7.7.0.tgz#271d401e713bfd338d5ef0435d3c4c68f6eddd2a" + integrity sha512-U8Cmnv0/AcQKehiIVi6UDzqq3jqhAEbY9CvOW5vdeNRmYhFpK6bXPmVczS/nUz5g4KsPc/FdnC3zbU6yVf4e7w== + dependencies: + "@babel/core" "^7.11.0" + "@babel/polyfill" "^7.10.4" + broccoli-funnel "^2.0.2" + broccoli-merge-trees "^3.0.2" + broccoli-persistent-filter "^2.2.1" + clone "^2.1.2" + hash-for-dep "^1.4.7" + heimdalljs "^0.2.1" + heimdalljs-logger "^0.1.9" + json-stable-stringify "^1.0.1" + rsvp "^4.8.4" + workerpool "^3.1.1" + broccoli-builder@^0.18.14: version "0.18.14" resolved "https://registry.yarnpkg.com/broccoli-builder/-/broccoli-builder-0.18.14.tgz#4b79e2f844de11a4e1b816c3f49c6df4776c312d" @@ -3807,6 +4129,13 @@ cacheable-request@^2.1.1: normalize-url "2.0.1" responselike "1.0.2" +calculate-cache-key-for-tree@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/calculate-cache-key-for-tree/-/calculate-cache-key-for-tree-1.2.3.tgz#5a5e4fcfa2d374a63e47fe967593f179e8282825" + integrity sha512-PPQorvdNw8K8k7UftCeradwOmKDSDJs8wcqYTtJPEt3fHbZyK8QsorybJA+lOmk0dgE61vX6R+5Kd3W9h4EMGg== + dependencies: + json-stable-stringify "^1.0.1" + calculate-cache-key-for-tree@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/calculate-cache-key-for-tree/-/calculate-cache-key-for-tree-2.0.0.tgz#7ac57f149a4188eacb0a45b210689215d3fef8d6" @@ -3849,11 +4178,16 @@ can-symlink@^1.0.0: dependencies: tmp "0.0.28" -caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001093: +caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805, caniuse-lite@^1.0.30001093: version "1.0.30001096" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001096.tgz#5a4541af5317dc21f91f5b24d453030a35f919c0" integrity sha512-PFTw9UyVfbkcMEFs82q8XVlRayj7HKvnhu5BLcmjGpv+SNyiWasCcWXPGJuO0rK0dhLRDJmtZcJ+LHUfypbw1w== +caniuse-lite@^1.0.30000844: + version "1.0.30001125" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001125.tgz#2a1a51ee045a0a2207474b086f628c34725e997b" + integrity sha512-9f+r7BW8Qli917mU3j0fUaTweT3f3vnX/Lcs+1C73V+RADmFme+Ih0Br8vONQi3X0lseOe6ZHfsZLCA8MSjxUA== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -4897,11 +5231,16 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.30, electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.488: +electron-to-chromium@^1.3.30, electron-to-chromium@^1.3.488: version "1.3.494" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.494.tgz#0d2dba65b69d696c5b71abb37552ff055fb32a5c" integrity sha512-EOZuaDT3L1sCIMAVN5J0nGuGWVq5dThrdl0d8XeDYf4MOzbXqZ19OLKesN8TZj0RxtpYjqHpiw/fR6BKWdMwYA== +electron-to-chromium@^1.3.47: + version "1.3.565" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.565.tgz#8511797ab2b66b767e1aef4eb17d636bf01a2c72" + integrity sha512-me5dGlHFd8Q7mKhqbWRLIYnKjw4i0fO6hmW0JBxa7tM87fBfNEjWokRnDF7V+Qme/9IYpwhfMn+soWs40tXWqg== + elliptic@^6.0.0, elliptic@^6.5.2: version "6.5.3" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" @@ -5022,6 +5361,38 @@ ember-cli-babel-plugin-helpers@^1.0.0, ember-cli-babel-plugin-helpers@^1.1.0: resolved "https://registry.yarnpkg.com/ember-cli-babel-plugin-helpers/-/ember-cli-babel-plugin-helpers-1.1.0.tgz#de3baedd093163b6c2461f95964888c1676325ac" integrity sha512-Zr4my8Xn+CzO0gIuFNXji0eTRml5AxZUTDQz/wsNJ5AJAtyFWCY4QtKdoELNNbiCVGt1lq5yLiwTm4scGKu6xA== +ember-cli-babel@7: + version "7.22.1" + resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.22.1.tgz#cad28b89cf0e184c93b863d09bc5ba4ce1d2e453" + integrity sha512-kCT8WbC1AYFtyOpU23ESm22a+gL6fWv8Nzwe8QFQ5u0piJzM9MEudfbjADEaoyKTrjMQTDsrWwEf3yjggDsOng== + dependencies: + "@babel/core" "^7.11.0" + "@babel/helper-compilation-targets" "^7.10.4" + "@babel/plugin-proposal-class-properties" "^7.10.4" + "@babel/plugin-proposal-decorators" "^7.10.5" + "@babel/plugin-transform-modules-amd" "^7.10.5" + "@babel/plugin-transform-runtime" "^7.11.0" + "@babel/plugin-transform-typescript" "^7.11.0" + "@babel/polyfill" "^7.10.4" + "@babel/preset-env" "^7.11.0" + "@babel/runtime" "^7.11.0" + amd-name-resolver "^1.2.1" + babel-plugin-debug-macros "^0.3.3" + babel-plugin-ember-data-packages-polyfill "^0.1.2" + babel-plugin-ember-modules-api-polyfill "^3.1.1" + babel-plugin-module-resolver "^3.1.1" + broccoli-babel-transpiler "^7.7.0" + broccoli-debug "^0.6.4" + broccoli-funnel "^2.0.1" + broccoli-source "^1.1.0" + clone "^2.1.2" + ember-cli-babel-plugin-helpers "^1.1.0" + ember-cli-version-checker "^4.1.0" + ensure-posix-path "^1.0.2" + fixturify-project "^1.10.0" + rimraf "^3.0.1" + semver "^5.5.0" + ember-cli-babel@^6.0.0, ember-cli-babel@^6.0.0-beta.4, ember-cli-babel@^6.11.0, ember-cli-babel@^6.12.0, ember-cli-babel@^6.16.0, ember-cli-babel@^6.3.0, ember-cli-babel@^6.6.0, ember-cli-babel@^6.8.1, ember-cli-babel@^6.8.2, ember-cli-babel@^6.9.0, ember-cli-babel@^6.9.2: version "6.18.0" resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-6.18.0.tgz#3f6435fd275172edeff2b634ee7b29ce74318957" @@ -5549,7 +5920,7 @@ ember-collection@^1.0.0-alpha.9: ember-cli-htmlbars "^3.0.1" layout-bin-packer "^1.4.0" -ember-compatibility-helpers@^1.1.1, ember-compatibility-helpers@^1.1.2, ember-compatibility-helpers@^1.2.0: +ember-compatibility-helpers@^1.1.1, ember-compatibility-helpers@^1.1.2, ember-compatibility-helpers@^1.2.0, ember-compatibility-helpers@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ember-compatibility-helpers/-/ember-compatibility-helpers-1.2.1.tgz#87c92c4303f990ff455c28ca39fb3ee11441aa16" integrity sha512-6wzYvnhg1ihQUT5yGqnLtleq3Nv5KNv79WhrEuNU9SwR4uIxCO+KpyC7r3d5VI0EM7/Nmv9Nd0yTkzmTMdVG1A== @@ -5594,13 +5965,27 @@ ember-concurrency@^1.2.1: ember-compatibility-helpers "^1.2.0" ember-maybe-import-regenerator "^0.1.6" -ember-copy@^1.0.0: +ember-copy@1.0.0, ember-copy@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ember-copy/-/ember-copy-1.0.0.tgz#426554ba6cf65920f31d24d0a3ca2cb1be16e4aa" integrity sha512-aiZNAvOmdemHdvZNn0b5b/0d9g3JFpcOsrDgfhYEbfd7SzE0b69YiaVK2y3wjqfjuuiA54vOllGN4pjSzECNSw== dependencies: ember-cli-babel "^6.6.0" +ember-data-model-fragments@5.0.0-beta.0: + version "5.0.0-beta.0" + resolved "https://registry.yarnpkg.com/ember-data-model-fragments/-/ember-data-model-fragments-5.0.0-beta.0.tgz#da90799970317ca852f96b2ea1548ca70094a5bb" + integrity sha512-vjApz3ZWSiLyUUU2IRi/ArKVBJe+iW+BvKkiQ6an/e7ln4Jt06P9xXm1Fu3hfqkQOQlfn7QkUnlzm4XxRtlMfg== + dependencies: + broccoli-file-creator "^2.1.1" + broccoli-merge-trees "^3.0.0" + calculate-cache-key-for-tree "^1.1.0" + ember-cli-babel "7" + ember-compatibility-helpers "^1.2.1" + ember-copy "1.0.0" + git-repo-info "^2.0.0" + npm-git-info "^1.0.3" + ember-data@~3.16.0: version "3.16.8" resolved "https://registry.yarnpkg.com/ember-data/-/ember-data-3.16.8.tgz#2d25a2cd37f4952ea92df464a5b10c70cd0b20e1" @@ -5824,11 +6209,16 @@ ember-resolver@^8.0.0: ember-cli-version-checker "^5.0.2" resolve "^1.15.1" -ember-rfc176-data@^0.3.12, ember-rfc176-data@^0.3.13: +ember-rfc176-data@^0.3.12: version "0.3.13" resolved "https://registry.yarnpkg.com/ember-rfc176-data/-/ember-rfc176-data-0.3.13.tgz#ed1712a26e65fec703655f35410414aa1982cf3b" integrity sha512-m9JbwQlT6PjY7x/T8HslnXP7Sz9bx/pz3FrNfNi2NesJnbNISly0Lix6NV1fhfo46572cpq4jrM+/6yYlMefTQ== +ember-rfc176-data@^0.3.13, ember-rfc176-data@^0.3.15: + version "0.3.15" + resolved "https://registry.yarnpkg.com/ember-rfc176-data/-/ember-rfc176-data-0.3.15.tgz#af3f1da5a0339b6feda380edc2f7190e0f416c2d" + integrity sha512-GPKa7zRDBblRy0orxTXt5yrpp/Pf5CkuRFSIR8qMFDww0CqCKjCRwdZnWYzCM4kAEfZnXRIDDefe1tBaFw7v7w== + ember-router-generator@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ember-router-generator/-/ember-router-generator-2.0.0.tgz#d04abfed4ba8b42d166477bbce47fccc672dbde0" @@ -7175,7 +7565,7 @@ git-repo-info@^1.4.1: resolved "https://registry.yarnpkg.com/git-repo-info/-/git-repo-info-1.4.1.tgz#2a072823254aaf62fcf0766007d7b6651bd41943" integrity sha1-KgcoIyVKr2L88HZgB9e2ZRvUGUM= -git-repo-info@^2.1.1: +git-repo-info@^2.0.0, git-repo-info@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/git-repo-info/-/git-repo-info-2.1.1.tgz#220ffed8cbae74ef8a80e3052f2ccb5179aed058" integrity sha512-8aCohiDo4jwjOwma4FmYFd3i97urZulL8XL24nIPxuE+GZnfsAyy/g2Shqx6OjUiFKUXZM+Yy+KHnOmmA3FVcg== @@ -8851,11 +9241,16 @@ lodash.uniqby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" integrity sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI= -lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.5.1, lodash@~4.17.10: +lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.15, lodash@^4.5.1, lodash@~4.17.10: version "4.17.19" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== +lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.4: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + log-symbols@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"