mirror of https://github.com/rancher/ui.git
Merge branch 'master' of github.com:hubert-he/ui
This commit is contained in:
commit
106de7be6b
|
|
@ -26,7 +26,8 @@ export default Route.extend({
|
||||||
|
|
||||||
let agent = window.navigator.userAgent.toLowerCase();
|
let agent = window.navigator.userAgent.toLowerCase();
|
||||||
|
|
||||||
if ( agent.indexOf('msie ') >= 0 || agent.indexOf('trident/') >= 0 ) {
|
// Show the we don't support internet explorer or edge browsers (only edge html based browsers the mobile and chromium based browsers should be okay).
|
||||||
|
if ( agent.indexOf('msie ') >= 0 || agent.indexOf('trident/') >= 0 || agent.indexOf('edge/') >= 0) {
|
||||||
this.replaceWith('ie');
|
this.replaceWith('ie');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ export default Component.extend({
|
||||||
lastScrollTop = scrollTop;
|
lastScrollTop = scrollTop;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.exec();
|
|
||||||
var btn = $('.scroll-bottom')[0]; // eslint-disable-line
|
var btn = $('.scroll-bottom')[0]; // eslint-disable-line
|
||||||
|
|
||||||
if ( btn ) {
|
if ( btn ) {
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@
|
||||||
<br><br>
|
<br><br>
|
||||||
<div class="sad-ie"></div>
|
<div class="sad-ie"></div>
|
||||||
<br><br>
|
<br><br>
|
||||||
<h3s>Sorry, IE is not supported.</h3s>
|
<h3s>Sorry, IE and Edge are not supported.</h3s>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ export default Resource.extend({
|
||||||
return out;
|
return out;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
validationErrors() {
|
validationErrors(answersMap) {
|
||||||
const {
|
const {
|
||||||
intl, allQuestions, valuesYaml
|
intl, allQuestions, valuesYaml
|
||||||
} = this;
|
} = this;
|
||||||
|
|
@ -96,7 +96,7 @@ export default Resource.extend({
|
||||||
} else {
|
} else {
|
||||||
if ( filteredQuestions ) {
|
if ( filteredQuestions ) {
|
||||||
filteredQuestions.forEach((item) => {
|
filteredQuestions.forEach((item) => {
|
||||||
if ( item.required && item.type !== 'boolean' && !item.answer ) {
|
if ( item.required && item.type !== 'boolean' && isEmpty(answersMap[item.variable]) ) {
|
||||||
errors.push(intl.t('validation.required', { key: item.label }));
|
errors.push(intl.t('validation.required', { key: item.label }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -205,6 +205,11 @@
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-small {
|
||||||
|
line-height: 14px;
|
||||||
|
padding: 0 0 0 22px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
.list-unstyled { @include list-unstyled }
|
.list-unstyled { @include list-unstyled }
|
||||||
.no-select { @include no-select }
|
.no-select { @include no-select }
|
||||||
.no-resize { @include no-resize }
|
.no-resize { @include no-resize }
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ select {
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: $input-bg-hover;
|
border-color: $input-bg-hover;
|
||||||
background: rgba($input-bg-hover, .2);
|
background-color: rgba($input-bg-hover, .2);
|
||||||
&::placeholder {
|
&::placeholder {
|
||||||
color: rgba($input-color-placeholder, .35);
|
color: rgba($input-color-placeholder, .35);
|
||||||
}
|
}
|
||||||
|
|
@ -126,7 +126,7 @@ select {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&:focus {
|
&:focus {
|
||||||
background: rgba($input-border-focus, .2);
|
background-color: rgba($input-border-focus, .2);
|
||||||
border-color: $input-border-focus;
|
border-color: $input-border-focus;
|
||||||
transition: ease-in-out all .25s;
|
transition: ease-in-out all .25s;
|
||||||
&::placeholder {
|
&::placeholder {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
white-space: -pre-wrap;
|
white-space: -pre-wrap;
|
||||||
white-space: -o-pre-wrap;
|
white-space: -o-pre-wrap;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
width: auto;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ export default Component.extend(NewOrEdit, CatalogApp, {
|
||||||
selectedTemplateUrl: null,
|
selectedTemplateUrl: null,
|
||||||
multiClusterApp: { targets: [], },
|
multiClusterApp: { targets: [], },
|
||||||
},
|
},
|
||||||
|
mcAppIsSaving: false,
|
||||||
|
|
||||||
overridesHeaders: OVERRIDE_HEADERS,
|
overridesHeaders: OVERRIDE_HEADERS,
|
||||||
|
|
||||||
|
|
@ -277,6 +278,10 @@ export default Component.extend(NewOrEdit, CatalogApp, {
|
||||||
},
|
},
|
||||||
|
|
||||||
updateAnswerOverrides: observer('selectedTemplateModel', 'multiClusterApp.answers.@each.{values}', function() {
|
updateAnswerOverrides: observer('selectedTemplateModel', 'multiClusterApp.answers.@each.{values}', function() {
|
||||||
|
if (this.mcAppSaving) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let { selectedTemplateModel = {} } = this;
|
let { selectedTemplateModel = {} } = this;
|
||||||
|
|
||||||
const questions = get(selectedTemplateModel, 'questions')
|
const questions = get(selectedTemplateModel, 'questions')
|
||||||
|
|
@ -363,7 +368,7 @@ export default Component.extend(NewOrEdit, CatalogApp, {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
templateOrHelmChartQuestions: computed('selectedTemplateModel', function() {
|
templateOrHelmChartQuestions: computed('selectedTemplateModel', 'selectedTemplateModel.allQuestions.@each.{answer,variable}', function() {
|
||||||
let { selectedTemplateModel, multiClusterApp } = this;
|
let { selectedTemplateModel, multiClusterApp } = this;
|
||||||
let nueQuestions = [];
|
let nueQuestions = [];
|
||||||
|
|
||||||
|
|
@ -587,7 +592,7 @@ export default Component.extend(NewOrEdit, CatalogApp, {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
const errors = get(this, 'errors') || [];
|
const errors = get(this, 'errors') || [];
|
||||||
|
|
||||||
errors.pushObjects(get(this, 'selectedTemplateModel').validationErrors() || []);
|
errors.pushObjects(get(this, 'selectedTemplateModel').validationErrors(this.answers) || []);
|
||||||
errors.pushObjects(this.validateTargetsProjectIds());
|
errors.pushObjects(this.validateTargetsProjectIds());
|
||||||
|
|
||||||
set(this, 'errors', errors.uniq());
|
set(this, 'errors', errors.uniq());
|
||||||
|
|
|
||||||
|
|
@ -408,6 +408,7 @@
|
||||||
{{save-cancel
|
{{save-cancel
|
||||||
createLabel=(if editing saveUpgrade saveNew)
|
createLabel=(if editing saveUpgrade saveNew)
|
||||||
save=(action "save")
|
save=(action "save")
|
||||||
|
saving=mcAppSaving
|
||||||
cancel=(action "cancel")
|
cancel=(action "cancel")
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,7 @@ export default Component.extend(NodeDriver, {
|
||||||
this.initCustomAttributes();
|
this.initCustomAttributes();
|
||||||
this.initTag();
|
this.initTag();
|
||||||
this.initNetwork();
|
this.initNetwork();
|
||||||
|
this.initUseDataStoreCluster();
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
@ -166,6 +167,12 @@ export default Component.extend(NodeDriver, {
|
||||||
return keyContent.filter((keyContent) => {
|
return keyContent.filter((keyContent) => {
|
||||||
return keyValuePairs.findIndex((kvp) => kvp.key === keyContent.value) === -1;
|
return keyValuePairs.findIndex((kvp) => kvp.key === keyContent.value) === -1;
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
toggleUseDataStoreCluster(value) {
|
||||||
|
set(this, 'config.useDataStoreCluster', value);
|
||||||
|
const clearKey = value ? 'config.datastore' : 'config.datastoreCluster';
|
||||||
|
|
||||||
|
set(this, clearKey, '');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -236,6 +243,16 @@ export default Component.extend(NodeDriver, {
|
||||||
return this.mapPathOptionsToContent(options);
|
return this.mapPathOptionsToContent(options);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
dataStoreClusterContent: computed('config.datacenter', async function() {
|
||||||
|
const options = await this.requestOptions(
|
||||||
|
'data-store-clusters',
|
||||||
|
get(this, 'model.cloudCredentialId'),
|
||||||
|
get(this, 'config.datacenter')
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.mapPathOptionsToContent(options);
|
||||||
|
}),
|
||||||
|
|
||||||
folderContent: computed('config.datacenter', async function() {
|
folderContent: computed('config.datacenter', async function() {
|
||||||
const options = await this.requestOptions(
|
const options = await this.requestOptions(
|
||||||
'folders',
|
'folders',
|
||||||
|
|
@ -324,6 +341,7 @@ export default Component.extend(NodeDriver, {
|
||||||
|
|
||||||
let config = get(this, 'globalStore').createRecord({
|
let config = get(this, 'globalStore').createRecord({
|
||||||
type: CONFIG,
|
type: CONFIG,
|
||||||
|
useDataStoreCluster: false,
|
||||||
cpuCount: '2',
|
cpuCount: '2',
|
||||||
memorySize: '2048',
|
memorySize: '2048',
|
||||||
diskSize: '20000',
|
diskSize: '20000',
|
||||||
|
|
@ -406,6 +424,17 @@ export default Component.extend(NodeDriver, {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
initUseDataStoreCluster() {
|
||||||
|
const useDataStoreCluster = !!get(this, 'config.datastoreCluster');
|
||||||
|
|
||||||
|
set(this, 'config.useDataStoreCluster', useDataStoreCluster);
|
||||||
|
|
||||||
|
// Only one should be set at a time
|
||||||
|
const clearKey = useDataStoreCluster ? 'config.datastore' : 'config.datastoreCluster';
|
||||||
|
|
||||||
|
set(this, clearKey, '');
|
||||||
|
},
|
||||||
|
|
||||||
updateVappOptions(opts) {
|
updateVappOptions(opts) {
|
||||||
set(this, 'config.vappIpprotocol', opts.vappIpprotocol);
|
set(this, 'config.vappIpprotocol', opts.vappIpprotocol);
|
||||||
set(this, 'config.vappIpallocationpolicy', opts.vappIpallocationpolicy);
|
set(this, 'config.vappIpallocationpolicy', opts.vappIpallocationpolicy);
|
||||||
|
|
@ -418,6 +447,13 @@ export default Component.extend(NodeDriver, {
|
||||||
const configCustomAttribute = get(this, 'customAttribute').map((kvp) => `${ kvp.key }=${ kvp.value }`);
|
const configCustomAttribute = get(this, 'customAttribute').map((kvp) => `${ kvp.key }=${ kvp.value }`);
|
||||||
|
|
||||||
set(this, 'config.customAttribute', configCustomAttribute);
|
set(this, 'config.customAttribute', configCustomAttribute);
|
||||||
|
|
||||||
|
const clearKey = get(this, 'config.useDataStoreCluster')
|
||||||
|
? 'config.datastore'
|
||||||
|
: 'config.datastoreCluster';
|
||||||
|
|
||||||
|
set(this, clearKey, '');
|
||||||
|
|
||||||
const vappMode = get(this, 'vappMode')
|
const vappMode = get(this, 'vappMode')
|
||||||
|
|
||||||
if (vappMode === VAPP_MODE_DISABLED) {
|
if (vappMode === VAPP_MODE_DISABLED) {
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
{{t "nodeDriver.vmwarevsphere.dataCenter.help"}}
|
{{t "nodeDriver.vmwarevsphere.dataCenter.help"}}
|
||||||
</p>
|
</p>
|
||||||
|
<SelectValueCheck @values={{config.datacenter}} @options={{datacenterContent}} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
|
|
@ -64,6 +65,7 @@
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
{{t "nodeDriver.vmwarevsphere.pool.help"}}
|
{{t "nodeDriver.vmwarevsphere.pool.help"}}
|
||||||
</p>
|
</p>
|
||||||
|
<SelectValueCheck @values={{config.pool}} @options={{resourcePoolContent}} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -71,7 +73,30 @@
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
<label class="acc-label">
|
<label class="acc-label">
|
||||||
{{t "nodeDriver.vmwarevsphere.dataStore.label"}}
|
{{t "nodeDriver.vmwarevsphere.dataStore.label"}}
|
||||||
|
<TooltipElement
|
||||||
|
@type="tooltip-basic"
|
||||||
|
@tooltipTemplate="tooltip-static"
|
||||||
|
@model={{t "nodeDriver.vmwarevsphere.dataStore.cluster.tooltip"}}
|
||||||
|
@inlineBlock={{true}}
|
||||||
|
>
|
||||||
|
<BtnToggle
|
||||||
|
@toggled={{action "toggleUseDataStoreCluster"}}
|
||||||
|
@checked={{mut config.useDataStoreCluster}}
|
||||||
|
/>
|
||||||
|
</TooltipElement>
|
||||||
</label>
|
</label>
|
||||||
|
{{#if config.useDataStoreCluster}}
|
||||||
|
<NewSelect
|
||||||
|
@class="form-control"
|
||||||
|
@useContentForDefaultValue={{true}}
|
||||||
|
@content={{dataStoreClusterContent}}
|
||||||
|
@value={{config.datastoreCluster}}
|
||||||
|
/>
|
||||||
|
<p class="help-block">
|
||||||
|
{{t "nodeDriver.vmwarevsphere.dataStore.cluster.help"}}
|
||||||
|
</p>
|
||||||
|
<SelectValueCheck @values={{config.datastoreCluster}} @options={{dataStoreClusterContent}} />
|
||||||
|
{{else}}
|
||||||
<NewSelect
|
<NewSelect
|
||||||
@class="form-control"
|
@class="form-control"
|
||||||
@useContentForDefaultValue={{true}}
|
@useContentForDefaultValue={{true}}
|
||||||
|
|
@ -81,6 +106,8 @@
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
{{t "nodeDriver.vmwarevsphere.dataStore.help"}}
|
{{t "nodeDriver.vmwarevsphere.dataStore.help"}}
|
||||||
</p>
|
</p>
|
||||||
|
<SelectValueCheck @values={{config.datastore}} @options={{dataStoreContent}} />
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
<label class="acc-label">
|
<label class="acc-label">
|
||||||
|
|
@ -95,6 +122,7 @@
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
{{t "nodeDriver.vmwarevsphere.folder.help"}}
|
{{t "nodeDriver.vmwarevsphere.folder.help"}}
|
||||||
</p>
|
</p>
|
||||||
|
<SelectValueCheck @values={{config.folder}} @options={{folderContent}} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -112,6 +140,7 @@
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
{{t "nodeDriver.vmwarevsphere.host.help"}}
|
{{t "nodeDriver.vmwarevsphere.host.help"}}
|
||||||
</p>
|
</p>
|
||||||
|
<SelectValueCheck @values={{config.hostsystem}} @options={{hostContent}} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/accordion-list-item}}
|
{{/accordion-list-item}}
|
||||||
|
|
@ -274,6 +303,7 @@
|
||||||
@valueLabel="nodeDriver.vmwarevsphere.network.valueLabel"
|
@valueLabel="nodeDriver.vmwarevsphere.network.valueLabel"
|
||||||
@valuePlaceholder="nodeDriver.vmwarevsphere.network.valuePlaceholder"
|
@valuePlaceholder="nodeDriver.vmwarevsphere.network.valuePlaceholder"
|
||||||
/>
|
/>
|
||||||
|
<SelectValueCheck @values={{config.network}} @options={{networkContent}} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
{{#if applyClusterTemplate}}
|
{{#if applyClusterTemplate}}
|
||||||
{{#if (has-override questions=questions paramName=paramName)}}
|
{{#if (has-override questions=questions paramName=paramName)}}
|
||||||
{{yield}}
|
{{yield (hash
|
||||||
|
hasOverride=true
|
||||||
|
)}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<div>
|
<div>
|
||||||
{{#if value}}
|
{{#if value}}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
import Component from '@ember/component'
|
import Component from '@ember/component'
|
||||||
import ClusterDriver from 'shared/mixins/cluster-driver';
|
import ClusterDriver from 'shared/mixins/cluster-driver';
|
||||||
import layout from './template';
|
import layout from './template';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
get, set, computed, observer, setProperties
|
get, set, computed, observer, setProperties
|
||||||
} from '@ember/object';
|
} from '@ember/object';
|
||||||
import { sortableNumericSuffix } from 'shared/utils/util';
|
import { sortableNumericSuffix } from 'shared/utils/util';
|
||||||
import { reject, all } from 'rsvp';
|
import { reject, all } from 'rsvp';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import { equal } from '@ember/object/computed'
|
import { equal } from '@ember/object/computed';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
import { isEmpty } from '@ember/utils';
|
||||||
|
|
||||||
const times = [
|
const times = [
|
||||||
{
|
{
|
||||||
|
|
@ -224,6 +224,8 @@ export default Component.extend(ClusterDriver, {
|
||||||
diskType: 'pd-standard',
|
diskType: 'pd-standard',
|
||||||
region: 'us-west2',
|
region: 'us-west2',
|
||||||
taints: [],
|
taints: [],
|
||||||
|
useIpAliases: true,
|
||||||
|
ipPolicyCreateSubnetwork: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
setProperties(this, {
|
setProperties(this, {
|
||||||
|
|
@ -448,8 +450,14 @@ export default Component.extend(ClusterDriver, {
|
||||||
|
|
||||||
const subNetworkContent = get(this, 'subNetworkContent') || []
|
const subNetworkContent = get(this, 'subNetworkContent') || []
|
||||||
|
|
||||||
if (subNetworkContent.length > 0) {
|
if (subNetworkContent.length > 1) {
|
||||||
set(this, 'config.subNetwork', subNetworkContent[0] && subNetworkContent[0].value)
|
const firstNonNullSubnetMatch = subNetworkContent.find((sn) => !isEmpty(sn.value));
|
||||||
|
|
||||||
|
setProperties(this, {
|
||||||
|
'config.subNetwork': firstNonNullSubnetMatch.value,
|
||||||
|
'config.ipPolicyCreateSubnetwork': false,
|
||||||
|
})
|
||||||
|
|
||||||
const secondaryIpRangeContent = get(this, 'secondaryIpRangeContent') || []
|
const secondaryIpRangeContent = get(this, 'secondaryIpRangeContent') || []
|
||||||
|
|
||||||
if (secondaryIpRangeContent.length > 0) {
|
if (secondaryIpRangeContent.length > 0) {
|
||||||
|
|
@ -463,6 +471,20 @@ export default Component.extend(ClusterDriver, {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
subnetworkChange: observer('config.subNetwork', function() {
|
||||||
|
if (this.saving) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { config: { subNetwork } } = this;
|
||||||
|
|
||||||
|
if (isEmpty(subNetwork)) {
|
||||||
|
set(this, 'config.ipPolicyCreateSubnetwork', true);
|
||||||
|
} else {
|
||||||
|
set(this, 'config.ipPolicyCreateSubnetwork', false);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
secondaryIpRangeContentChange: observer('secondaryIpRangeContent.[]', 'config.useIpAliases', function() {
|
secondaryIpRangeContentChange: observer('secondaryIpRangeContent.[]', 'config.useIpAliases', function() {
|
||||||
if (this.saving) {
|
if (this.saving) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -480,8 +502,15 @@ export default Component.extend(ClusterDriver, {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get(this, 'config.useIpAliases')) {
|
if (get(this, 'config.useIpAliases')) {
|
||||||
set(this, 'config.enablePrivateNodes', false)
|
if (!isEmpty(this.config.subNetwork)) {
|
||||||
|
set(this, 'config.ipPolicyCreateSubnetwork', false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setProperties(this, {
|
||||||
|
'config.enablePrivateNodes': false,
|
||||||
|
'config.ipPolicyCreateSubnetwork': false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -544,43 +573,62 @@ export default Component.extend(ClusterDriver, {
|
||||||
return zoneChoices.filter((z) => (z.name || '').startsWith(locationName) && z.name !== zone)
|
return zoneChoices.filter((z) => (z.name || '').startsWith(locationName) && z.name !== zone)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
networkContent: computed('networks', function() {
|
networkContent: computed('networks', 'config.zone', function() {
|
||||||
return get(this, 'networks')
|
return get(this, 'networks')
|
||||||
}),
|
}),
|
||||||
|
|
||||||
subNetworkContent: computed('subNetworks.[]', 'config.network', function() {
|
subNetworkContent: computed('subNetworks.[]', 'config.network', 'config.zone', function() {
|
||||||
const subNetworks = get(this, 'subNetworks') || []
|
const {
|
||||||
const networkName = get(this, 'config.network')
|
config: { network: networkName },
|
||||||
|
networkContent,
|
||||||
|
subNetworks = [],
|
||||||
|
} = this;
|
||||||
|
|
||||||
const out = subNetworks.filter((s) => {
|
const filteredSubnets = (subNetworks || []).filter((s) => {
|
||||||
const { network = '' } = s
|
const network = networkContent.findBy('selfLink', s.network);
|
||||||
const arr = network.split('/') || []
|
const networkDisplayName = network.name;
|
||||||
const networkDisplayName = arr[arr.length - 1]
|
|
||||||
|
|
||||||
if (networkDisplayName === networkName) {
|
if (networkDisplayName === networkName) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
const mappedSubnets = filteredSubnets.map((o) => {
|
||||||
|
const network = networkContent.findBy('selfLink', o.network);
|
||||||
|
const networkDisplayName = network.name;
|
||||||
|
|
||||||
return out.map((o) => {
|
|
||||||
return {
|
return {
|
||||||
label: `${ o.name }(${ o.ipCidrRange })`,
|
label: `${ o.name }(${ o.ipCidrRange })`,
|
||||||
value: o.name,
|
value: o.name,
|
||||||
secondaryIpRanges: o.secondaryIpRanges,
|
secondaryIpRanges: o.secondaryIpRanges,
|
||||||
|
networkDisplayName
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
const defaultSubnetAry = [{
|
||||||
|
label: this.intl.t('clusterNew.googlegke.ipPolicyCreateSubnetwork.autoLabel'),
|
||||||
|
value: '',
|
||||||
|
}];
|
||||||
|
|
||||||
|
return [...defaultSubnetAry, ...mappedSubnets];
|
||||||
}),
|
}),
|
||||||
|
|
||||||
secondaryIpRangeContent: computed('subNetworkContent.[]', 'config.network', function() {
|
secondaryIpRangeContent: computed('subNetworkContent.[]', 'config.network', function() {
|
||||||
const subNetworkContent = get(this, 'subNetworkContent')
|
const { subNetworkContent = [], config: { network } } = this;
|
||||||
const { secondaryIpRanges = [] } = subNetworkContent
|
const subNetwork = subNetworkContent.findBy('networkDisplayName', network);
|
||||||
|
|
||||||
|
if (subNetwork) {
|
||||||
|
const { secondaryIpRanges = [] } = subNetwork;
|
||||||
|
|
||||||
return secondaryIpRanges.map((s) => {
|
return secondaryIpRanges.map((s) => {
|
||||||
return {
|
return {
|
||||||
lable: `${ s.rangeName }(${ s.ipCidrRange })`,
|
label: `${ s.rangeName }(${ s.ipCidrRange })`,
|
||||||
value: s.rangeName,
|
value: s.rangeName,
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
}),
|
}),
|
||||||
|
|
||||||
serviceAccountContent: computed('serviceAccounts', function() {
|
serviceAccountContent: computed('serviceAccounts', function() {
|
||||||
|
|
@ -593,6 +641,24 @@ export default Component.extend(ClusterDriver, {
|
||||||
return get(this, 'maintenanceWindowTimes').findBy('value', get(this, 'config.maintenanceWindow')) || { label: 'Any Time' };
|
return get(this, 'maintenanceWindowTimes').findBy('value', get(this, 'config.maintenanceWindow')) || { label: 'Any Time' };
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
shouldAllowDisableCreateSubNetwork: computed('config.subNetwork', function() {
|
||||||
|
const {
|
||||||
|
config: { subNetwork },
|
||||||
|
secondaryIpRangeContent,
|
||||||
|
editing,
|
||||||
|
} = this;
|
||||||
|
|
||||||
|
if (isEmpty(subNetwork)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (editing && isEmpty(secondaryIpRangeContent)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}),
|
||||||
|
|
||||||
fetchZones() {
|
fetchZones() {
|
||||||
return get(this, 'globalStore').rawRequest({
|
return get(this, 'globalStore').rawRequest({
|
||||||
url: '/meta/gkeZones',
|
url: '/meta/gkeZones',
|
||||||
|
|
|
||||||
|
|
@ -315,14 +315,16 @@
|
||||||
selection=config.enableHorizontalPodAutoscaling
|
selection=config.enableHorizontalPodAutoscaling
|
||||||
value=true
|
value=true
|
||||||
disabled=editing
|
disabled=editing
|
||||||
}} {{t "generic.enabled"}}
|
}}
|
||||||
|
{{t "generic.enabled"}}
|
||||||
</label>
|
</label>
|
||||||
<label class={{concat (if editing "text-muted") " hand"}}>
|
<label class={{concat (if editing "text-muted") " hand"}}>
|
||||||
{{radio-button
|
{{radio-button
|
||||||
selection=config.enableHorizontalPodAutoscaling
|
selection=config.enableHorizontalPodAutoscaling
|
||||||
value=false
|
value=false
|
||||||
disabled=editing
|
disabled=editing
|
||||||
}} {{t "generic.disabled"}}
|
}}
|
||||||
|
{{t "generic.disabled"}}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -345,6 +347,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
<label class="acc-label">
|
<label class="acc-label">
|
||||||
|
|
@ -385,9 +388,6 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#advanced-section advanced=clusterAdvanced}}
|
|
||||||
<h4 class="mt-20 mb-10">{{t "clusterNew.googlegke.header.iPAllocationPolicy"}}</h4>
|
|
||||||
<hr/>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
<label class="acc-label">
|
<label class="acc-label">
|
||||||
|
|
@ -400,43 +400,18 @@
|
||||||
value=true
|
value=true
|
||||||
disabled=editing
|
disabled=editing
|
||||||
}}
|
}}
|
||||||
{{t "generic.yes"}}
|
{{t "generic.enabled"}}
|
||||||
</label>
|
</label>
|
||||||
<label class={{concat (if editing "text-muted") " hand"}}>
|
<label class={{concat (if editing "text-muted") " hand"}}>
|
||||||
{{radio-button
|
{{radio-button
|
||||||
selection=config.useIpAliases
|
selection=config.useIpAliases
|
||||||
value=false
|
value=false
|
||||||
disabled=editing
|
disabled=(or editing (not config.subNetwork))
|
||||||
}}
|
|
||||||
{{t "generic.no"}}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{#if config.useIpAliases}}
|
|
||||||
<div class="col span-6">
|
|
||||||
<label class="acc-label">
|
|
||||||
{{t "clusterNew.googlegke.ipPolicyCreateSubnetwork.label"}}
|
|
||||||
</label>
|
|
||||||
<div class="form-control-static">
|
|
||||||
<label class={{concat (if editing "text-muted") " mr-20 hand"}}>
|
|
||||||
{{radio-button
|
|
||||||
selection=config.ipPolicyCreateSubnetwork
|
|
||||||
value=true
|
|
||||||
disabled=editing
|
|
||||||
}}
|
|
||||||
{{t "generic.enabled"}}
|
|
||||||
</label>
|
|
||||||
<label class={{concat (if editing "text-muted") " hand"}} class={{concat (if (eq secondaryIpRangeContent.length 0) "text-muted") " hand"}}>
|
|
||||||
{{radio-button
|
|
||||||
selection=config.ipPolicyCreateSubnetwork
|
|
||||||
value=false
|
|
||||||
disabled=(or editing (eq secondaryIpRangeContent.length 0))
|
|
||||||
}}
|
}}
|
||||||
{{t "generic.disabled"}}
|
{{t "generic.disabled"}}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
{{#if config.useIpAliases}}
|
{{#if config.useIpAliases}}
|
||||||
{{#if (and config.ipPolicyCreateSubnetwork config.useIpAliases)}}
|
{{#if (and config.ipPolicyCreateSubnetwork config.useIpAliases)}}
|
||||||
|
|
@ -490,6 +465,8 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
{{#advanced-section advanced=clusterAdvanced}}
|
||||||
<h4 class="mt-20 mb-10">
|
<h4 class="mt-20 mb-10">
|
||||||
{{t "clusterNew.googlegke.header.privateCluster"}}
|
{{t "clusterNew.googlegke.header.privateCluster"}}
|
||||||
</h4>
|
</h4>
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
@computedState={{not (eq selectedCloudProvider "none")}}
|
@computedState={{not (eq selectedCloudProvider "none")}}
|
||||||
>
|
>
|
||||||
{{#input-or-display
|
{{#input-or-display
|
||||||
editable=(not-eq mode "view")
|
editable=(or (and (eq mode "new") (or (not applyClusterTemplate) (and (eq mode "new") selectedCloudProviderOverrideAvailable))) clusterTemplateCreate)
|
||||||
value=selectedCloudProvider
|
value=selectedCloudProvider
|
||||||
}}
|
}}
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
|
|
@ -134,7 +134,7 @@
|
||||||
</div>
|
</div>
|
||||||
{{/input-or-display}}
|
{{/input-or-display}}
|
||||||
</CheckComputedOverride>
|
</CheckComputedOverride>
|
||||||
{{#unless (eq selectedCloudProvider "none")}}
|
{{#if (and (not-eq selectedCloudProvider "none") (eq mode "new"))}}
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
<BannerMessage
|
<BannerMessage
|
||||||
@color="bg-info mt-0 mb-0"
|
@color="bg-info mt-0 mb-0"
|
||||||
|
|
@ -142,7 +142,7 @@
|
||||||
@message={{t "cloudProvider.warning"}}
|
@message={{t "cloudProvider.warning"}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{{/unless}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if (eq selectedCloudProvider "azure")}}
|
{{#if (eq selectedCloudProvider "azure")}}
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,10 @@
|
||||||
@paramName="rancherKubernetesEngineConfig.network.plugin"
|
@paramName="rancherKubernetesEngineConfig.network.plugin"
|
||||||
@clusterTemplateRevision={{clusterTemplateRevision.clusterConfig}}
|
@clusterTemplateRevision={{clusterTemplateRevision.clusterConfig}}
|
||||||
@applyClusterTemplate={{applyClusterTemplate}}
|
@applyClusterTemplate={{applyClusterTemplate}}
|
||||||
|
as |override|
|
||||||
>
|
>
|
||||||
{{#input-or-display
|
{{#input-or-display
|
||||||
editable=(eq mode "new")
|
editable=(or (and (eq mode "new") (or (not applyClusterTemplate) override.hasOverride)) clusterTemplateCreate)
|
||||||
value=config.network.plugin
|
value=config.network.plugin
|
||||||
}}
|
}}
|
||||||
{{new-select
|
{{new-select
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
import Component from '@ember/component';
|
||||||
|
import layout from './template';
|
||||||
|
import { computed, get } from '@ember/object';
|
||||||
|
import StatefulPromise from 'shared/utils/stateful-promise';
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
layout,
|
||||||
|
|
||||||
|
optionValues: computed.mapBy('asyncOptions.value', 'value'),
|
||||||
|
asyncOptions: computed('content', function() {
|
||||||
|
return StatefulPromise.wrap(get(this, 'options'), []);
|
||||||
|
}),
|
||||||
|
valueArray: computed('values', function() {
|
||||||
|
const values = get(this, 'values');
|
||||||
|
|
||||||
|
return Array.isArray(values)
|
||||||
|
? values
|
||||||
|
: [values];
|
||||||
|
}),
|
||||||
|
missingValues: computed('valueArray', 'optionValues', function() {
|
||||||
|
const optionValues = get(this, 'optionValues');
|
||||||
|
|
||||||
|
if (optionValues.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return get(this, 'valueArray').filter((value) => {
|
||||||
|
return optionValues.indexOf(value) === -1
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
showMessaging: computed('values', 'missingValues.length', function() {
|
||||||
|
return get(this, 'values') && get(this, 'missingValues.length') > 0;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
{{#if showMessaging}}
|
||||||
|
<div class="select-value-check text-small text-warning">
|
||||||
|
{{t "selectValueCheck.message" values=missingValues.length}}
|
||||||
|
<ul class="list-small">
|
||||||
|
{{#each missingValues as |missingValue|}}
|
||||||
|
<li>"{{missingValue}}"</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { schedule, cancel, later } from '@ember/runloop';
|
import { schedule, cancel, later, next } from '@ember/runloop';
|
||||||
import Mixin from '@ember/object/mixin';
|
import Mixin from '@ember/object/mixin';
|
||||||
import { get, set, setProperties } from '@ember/object';
|
import { get, set, setProperties } from '@ember/object';
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
|
|
@ -121,17 +121,17 @@ export default Mixin.create({
|
||||||
|
|
||||||
// console.log(this.label, (forceRemove ? 'Remove' : 'Change'), type +':'+ event.data.id, projectId);
|
// console.log(this.label, (forceRemove ? 'Remove' : 'Change'), type +':'+ event.data.id, projectId);
|
||||||
|
|
||||||
if ( get(this, 'updateProjectStore') && projectId && projectStore.hasType(type) ) {
|
if ( get(this, 'updateProjectStore') && projectId && checkStoreHasType(projectStore, type) ) {
|
||||||
// console.log(' Update project store', type, event.data.id, projectId);
|
// console.log(' Update project store', type, event.data.id, projectId);
|
||||||
updateStore(projectStore, event.data, forceRemove);
|
updateStore(projectStore, event.data, forceRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( get(this, 'updateClusterStore') && clusterStore.hasType(type) ) {
|
if ( get(this, 'updateClusterStore') && checkStoreHasType(clusterStore, type) ) {
|
||||||
// console.log(' Update cluster store', type, event.data.id);
|
// console.log(' Update cluster store', type, event.data.id);
|
||||||
updateStore(clusterStore, event.data, forceRemove);
|
updateStore(clusterStore, event.data, forceRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( get(this, 'updateGlobalStore') && globalStore.hasType(type) ) {
|
if ( get(this, 'updateGlobalStore') && checkStoreHasType(globalStore, type)) {
|
||||||
// console.log(' Update global store', type, event.data.id);
|
// console.log(' Update global store', type, event.data.id);
|
||||||
updateStore(globalStore, event.data, forceRemove);
|
updateStore(globalStore, event.data, forceRemove);
|
||||||
}
|
}
|
||||||
|
|
@ -143,6 +143,10 @@ export default Mixin.create({
|
||||||
Ember.endPropertyChanges();
|
Ember.endPropertyChanges();
|
||||||
// console.log(`Processed ${count} ${this.label} change events`);
|
// console.log(`Processed ${count} ${this.label} change events`);
|
||||||
|
|
||||||
|
function checkStoreHasType(store, type) {
|
||||||
|
return next(() => store.hasType(type));
|
||||||
|
}
|
||||||
|
|
||||||
function updateStore(store, data, forceRemove = false) {
|
function updateStore(store, data, forceRemove = false) {
|
||||||
// Update the state to removed before we remove it from store
|
// Update the state to removed before we remove it from store
|
||||||
if ( forceRemove ) {
|
if ( forceRemove ) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export { default } from 'shared/components/select-value-check/component';
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ember/jquery": "^0.6.0",
|
"@ember/jquery": "^0.6.0",
|
||||||
"@ember/optional-features": "^0.7.0",
|
"@ember/optional-features": "^0.7.0",
|
||||||
"@rancher/ember-api-store": "2.9.4",
|
"@rancher/ember-api-store": "2.9.6",
|
||||||
"ansi_up": "^2.0.2",
|
"ansi_up": "^2.0.2",
|
||||||
"async": "2.1.2",
|
"async": "2.1.2",
|
||||||
"babel-eslint": "^9.0.0",
|
"babel-eslint": "^9.0.0",
|
||||||
|
|
@ -65,6 +65,7 @@
|
||||||
"ember-drag-drop": "^0.4.7",
|
"ember-drag-drop": "^0.4.7",
|
||||||
"ember-engines": "^0.8.2",
|
"ember-engines": "^0.8.2",
|
||||||
"ember-export-application-global": "^2.0.0",
|
"ember-export-application-global": "^2.0.0",
|
||||||
|
"ember-fetch": "^6.5.1",
|
||||||
"ember-flatpickr": "^2.7.0",
|
"ember-flatpickr": "^2.7.0",
|
||||||
"ember-href-to": "^2.0.1",
|
"ember-href-to": "^2.0.1",
|
||||||
"ember-intl": "^4.2.0",
|
"ember-intl": "^4.2.0",
|
||||||
|
|
|
||||||
|
|
@ -3620,12 +3620,13 @@ clusterNew:
|
||||||
label: Master IP range
|
label: Master IP range
|
||||||
placeholder: e.g. 10.42.0.0/28
|
placeholder: e.g. 10.42.0.0/28
|
||||||
useIpAliases:
|
useIpAliases:
|
||||||
label: Use Ip Aliases
|
label: Ip Aliases
|
||||||
ipPolicySubnetworkName:
|
ipPolicySubnetworkName:
|
||||||
label: Subnetwork Name
|
label: Subnetwork Name
|
||||||
placeholder: Your Subnetwork Name
|
placeholder: Your Subnetwork Name
|
||||||
ipPolicyCreateSubnetwork:
|
ipPolicyCreateSubnetwork:
|
||||||
label: Create Subnetwork
|
label: Create Subnetwork
|
||||||
|
autoLabel: Auto Create Subnetwork
|
||||||
ipPolicyClusterSecondaryRangeName:
|
ipPolicyClusterSecondaryRangeName:
|
||||||
label: Cluster Secondary Range Name
|
label: Cluster Secondary Range Name
|
||||||
placeholder: Your Cluster Secondary Range Name
|
placeholder: Your Cluster Secondary Range Name
|
||||||
|
|
@ -8313,6 +8314,9 @@ nodeDriver:
|
||||||
valuePlaceholder: "e.g. VM Network"
|
valuePlaceholder: "e.g. VM Network"
|
||||||
help: "Networks to attach VM to"
|
help: "Networks to attach VM to"
|
||||||
dataStore:
|
dataStore:
|
||||||
|
cluster:
|
||||||
|
tooltip: Use datastore cluster?
|
||||||
|
help: "Datastore cluster to create VM on"
|
||||||
label: Data Store
|
label: Data Store
|
||||||
placeholder: "e.g. datastore_cluster_name/datastore_name"
|
placeholder: "e.g. datastore_cluster_name/datastore_name"
|
||||||
help: "Datastore to create VM disk on"
|
help: "Datastore to create VM disk on"
|
||||||
|
|
@ -9823,3 +9827,10 @@ pipelineNotification:
|
||||||
recipients:
|
recipients:
|
||||||
required: Recipient is required
|
required: Recipient is required
|
||||||
asMessage: Send a message to
|
asMessage: Send a message to
|
||||||
|
|
||||||
|
selectValueCheck:
|
||||||
|
message: |
|
||||||
|
{values, plural,
|
||||||
|
=1 {Please select a new value. The following is no longer valid:}
|
||||||
|
other {Please select new values. The following are no longer valid:}
|
||||||
|
}
|
||||||
|
|
@ -1121,17 +1121,16 @@
|
||||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
|
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
|
||||||
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
|
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
|
||||||
|
|
||||||
"@rancher/ember-api-store@2.9.4":
|
"@rancher/ember-api-store@2.9.6":
|
||||||
version "2.9.4"
|
version "2.9.6"
|
||||||
resolved "https://registry.yarnpkg.com/@rancher/ember-api-store/-/ember-api-store-2.9.4.tgz#84920e719ce2c0306668db7fd031138c1fec8b72"
|
resolved "https://registry.yarnpkg.com/@rancher/ember-api-store/-/ember-api-store-2.9.6.tgz#296195610a418c860dc98325e8aacaa53a159b62"
|
||||||
integrity sha512-Jef11/K9qGZyrSbufnlfDhY9WNfuo1th+azjRjDNwGv/7wrKiOxOquGmdKViWQXxjy8Hvm7RwsjKK5h2f85wpQ==
|
integrity sha512-SkJsDQiBPRzjjggJLT3mLPMJJBTKRTQbSjNdUoS7wjMWGqOzp+/XYtF8raov3cfYRja2D9bPV1HJo8OW2cF7dA==
|
||||||
dependencies:
|
dependencies:
|
||||||
babel-eslint "^10.0.1"
|
babel-eslint "^10.0.1"
|
||||||
broccoli-file-creator "^2.1.1"
|
broccoli-file-creator "^2.1.1"
|
||||||
ember-auto-import "^1.2.19"
|
ember-auto-import "^1.2.19"
|
||||||
ember-cli-babel "^7.1.2"
|
ember-cli-babel "^7.1.2"
|
||||||
ember-cookies "^0.4.0"
|
ember-cookies "^0.4.0"
|
||||||
ember-fetch "^6.5.1"
|
|
||||||
eslint "^4.19.1"
|
eslint "^4.19.1"
|
||||||
node-fetch "^2.3.0"
|
node-fetch "^2.3.0"
|
||||||
set-cookie-parser "^2.2.1"
|
set-cookie-parser "^2.2.1"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue