mirror of https://github.com/rancher/ui.git
Stack tags
This commit is contained in:
parent
9ce9c5fd00
commit
20518f052d
|
|
@ -1,7 +1,7 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
import NewOrEdit from 'ui/mixins/new-or-edit';
|
import NewOrEdit from 'ui/mixins/new-or-edit';
|
||||||
import ModalBase from 'lacsso/components/modal-base';
|
import ModalBase from 'lacsso/components/modal-base';
|
||||||
import {normalizedChoices, tagsToArray} from 'ui/models/stack';
|
import {tagChoices, tagsToArray} from 'ui/models/stack';
|
||||||
|
|
||||||
export default ModalBase.extend(NewOrEdit, {
|
export default ModalBase.extend(NewOrEdit, {
|
||||||
classNames: ['lacsso', 'modal-container', 'large-modal'],
|
classNames: ['lacsso', 'modal-container', 'large-modal'],
|
||||||
|
|
@ -28,7 +28,7 @@ export default ModalBase.extend(NewOrEdit, {
|
||||||
},
|
},
|
||||||
|
|
||||||
tagChoices: function() {
|
tagChoices: function() {
|
||||||
return normalizedChoices(this.get('allStacks'));
|
return tagChoices(this.get('allStacks'));
|
||||||
}.property('allStacks.@each.group'),
|
}.property('allStacks.@each.group'),
|
||||||
|
|
||||||
doneSaving: function() {
|
doneSaving: function() {
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,6 @@ export default Ember.Component.extend({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let tmp = rules.objectAt(idx+1);
|
|
||||||
rules.removeAt(idx);
|
rules.removeAt(idx);
|
||||||
rules.insertAt(idx+1, rule);
|
rules.insertAt(idx+1, rule);
|
||||||
this.updatePriorities();
|
this.updatePriorities();
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ export default Ember.Mixin.create(NewOrEdit, ManageLabels, {
|
||||||
let errors = [];
|
let errors = [];
|
||||||
|
|
||||||
if ( !this.get('nameParts.prefix') ) {
|
if ( !this.get('nameParts.prefix') ) {
|
||||||
errors.push('Name is required')
|
errors.push('Name is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set('errors', errors);
|
this.set('errors', errors);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import Ember from 'ember';
|
||||||
import Resource from 'ember-api-store/models/resource';
|
import Resource from 'ember-api-store/models/resource';
|
||||||
import { parseExternalId } from 'ui/utils/parse-externalid';
|
import { parseExternalId } from 'ui/utils/parse-externalid';
|
||||||
import C from 'ui/utils/constants';
|
import C from 'ui/utils/constants';
|
||||||
import Util from 'ui/utils/util';
|
import { download } from 'ui/utils/util';
|
||||||
import { denormalizeServiceArray } from 'ui/utils/denormalize-snowflakes';
|
import { denormalizeServiceArray } from 'ui/utils/denormalize-snowflakes';
|
||||||
|
|
||||||
export function activeIcon(stack)
|
export function activeIcon(stack)
|
||||||
|
|
@ -27,15 +27,13 @@ export function tagsToArray(str) {
|
||||||
filter((tag) => tag.length > 0);
|
filter((tag) => tag.length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function normalizedChoices(all) {
|
export function tagChoices(all) {
|
||||||
let choices = [];
|
let choices = [];
|
||||||
(all||[]).forEach((stack) => {
|
(all||[]).forEach((stack) => {
|
||||||
choices.addObjects(stack.get('tags'));
|
choices.addObjects(stack.get('tags'));
|
||||||
});
|
});
|
||||||
|
|
||||||
return choices.sort((a,b) => {
|
return choices;
|
||||||
return a.toLowerCase().localeCompare(b.toLowerCase());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var Stack = Resource.extend({
|
var Stack = Resource.extend({
|
||||||
|
|
@ -101,7 +99,7 @@ var Stack = Resource.extend({
|
||||||
|
|
||||||
exportConfig: function() {
|
exportConfig: function() {
|
||||||
var url = this.get('endpointSvc').addAuthParams(this.linkFor('composeConfig'));
|
var url = this.get('endpointSvc').addAuthParams(this.linkFor('composeConfig'));
|
||||||
Util.download(url);
|
download(url);
|
||||||
},
|
},
|
||||||
|
|
||||||
viewCode: function() {
|
viewCode: function() {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
import Sortable from 'ui/mixins/sortable';
|
import Sortable from 'ui/mixins/sortable';
|
||||||
import C from 'ui/utils/constants';
|
import C from 'ui/utils/constants';
|
||||||
import { tagsToArray, normalizedChoices } from 'ui/models/stack';
|
import { tagsToArray, tagChoices } from 'ui/models/stack';
|
||||||
|
import { uniqKeys } from 'ui/utils/util';
|
||||||
|
|
||||||
export default Ember.Controller.extend(Sortable, {
|
export default Ember.Controller.extend(Sortable, {
|
||||||
stacksController: Ember.inject.controller('stacks'),
|
stacksController: Ember.inject.controller('stacks'),
|
||||||
|
|
@ -9,24 +10,21 @@ export default Ember.Controller.extend(Sortable, {
|
||||||
prefs: Ember.inject.service(),
|
prefs: Ember.inject.service(),
|
||||||
intl: Ember.inject.service(),
|
intl: Ember.inject.service(),
|
||||||
|
|
||||||
stacks: Ember.computed.alias('stacksController.stacks'),
|
|
||||||
infraTemplates: Ember.computed.alias('stacksController.infraTemplates'),
|
infraTemplates: Ember.computed.alias('stacksController.infraTemplates'),
|
||||||
which: Ember.computed.alias('stacksController.which'),
|
which: Ember.computed.alias('stacksController.which'),
|
||||||
tags: Ember.computed.alias('stacksController.tags'),
|
tags: Ember.computed.alias('stacksController.tags'),
|
||||||
showAddtlInfo: false,
|
showAddtlInfo: false,
|
||||||
selectedService: null,
|
selectedService: null,
|
||||||
|
|
||||||
tagsArray: null,
|
tag: null,
|
||||||
tagChoices: function() {
|
tagChoices: function() {
|
||||||
let out = normalizedChoices(this.get('model'));
|
let choices = tagChoices(this.get('model.stacks'));
|
||||||
tagsToArray(this.get('tags')).forEach((tag) => {
|
tagsToArray(this.get('tags')).forEach((tag) => {
|
||||||
out.addObject(tag);
|
choices.addObject(tag);
|
||||||
});
|
});
|
||||||
|
|
||||||
return out.sort((a,b) => {
|
return uniqKeys(choices);
|
||||||
return a.toLowerCase().localeCompare(b.toLowerCase());
|
}.property('model.stacks.@each.group'), // tags is derived from group..
|
||||||
});
|
|
||||||
}.property('model.@each.group'),
|
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
showAddtlInfo(service) {
|
showAddtlInfo(service) {
|
||||||
|
|
@ -44,18 +42,8 @@ export default Ember.Controller.extend(Sortable, {
|
||||||
this.send('setSort', name);
|
this.send('setSort', name);
|
||||||
},
|
},
|
||||||
|
|
||||||
updateTags(select) {
|
switchTag(str) {
|
||||||
let options = Array.prototype.slice.call(select.target.options, 0);
|
this.set('tags', str);
|
||||||
let selected = options.filterBy('selected',true).map(opt => opt.value);
|
|
||||||
|
|
||||||
if ( selected.length === 0 )
|
|
||||||
{
|
|
||||||
this.set('tags','');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.set('tags', selected.join(','));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,16 +12,6 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<!--
|
|
||||||
<div class="pull-right r-ml20">
|
|
||||||
<select class="form-control stack-tags" multiple="true" onchange={{action 'updateTags'}}>
|
|
||||||
{{#each tagChoices as |choice|}}
|
|
||||||
<option value={{choice}} selected={{include tagsArray choice}}>{{choice}}</option>
|
|
||||||
{{/each}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<label class="text-muted r-pr5" style="font-size: 13px;">{{t 'stacksPage.sort.label'}}: </label>
|
<label class="text-muted r-pr5" style="font-size: 13px;">{{t 'stacksPage.sort.label'}}: </label>
|
||||||
<div class="btn-group r-pr0" role="group" aria-label="{{t 'stacksPage.sort.label'}}">
|
<div class="btn-group r-pr0" role="group" aria-label="{{t 'stacksPage.sort.label'}}">
|
||||||
|
|
@ -29,9 +19,26 @@
|
||||||
<button {{action 'sortResults' 'name'}} type="button" class="btn btn-sm btn-default {{if (eq sortBy "name") 'active'}}">{{t 'stacksPage.sort.name'}}</button>
|
<button {{action 'sortResults' 'name'}} type="button" class="btn btn-sm btn-default {{if (eq sortBy "name") 'active'}}">{{t 'stacksPage.sort.name'}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{#if tagChoices.length}}
|
||||||
|
<div class="btn-group pull-right r-mr10">
|
||||||
|
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{t (if tags 'stacksPage.tags.one' 'stacksPage.tags.all' ) name=tags}} <i class="icon icon-chevron-down"></i></button>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-right">
|
||||||
|
<li class="{{if (eq tags '') 'active'}}"><a href="#" {{action 'switchTag' ''}}>{{t 'stacksPage.tags.all'}}</a></li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
{{#each tagChoices as |opt|}}
|
||||||
|
<li class="{{if (eq tags opt) 'active'}}">
|
||||||
|
<a href="#" {{action 'switchTag' opt}}>
|
||||||
|
{{opt}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="stacks-wrap">
|
<section class="stacks-wrap r-pl0 r-pr0">
|
||||||
<div>
|
<div>
|
||||||
{{#each arranged as |stack|}}
|
{{#each arranged as |stack|}}
|
||||||
{{stack-section model=stack showAddtlInfo='showAddtlInfo' showAddService=(not stack.system)}}
|
{{stack-section model=stack showAddtlInfo='showAddtlInfo' showAddService=(not stack.system)}}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
import NewOrEdit from 'ui/mixins/new-or-edit';
|
import NewOrEdit from 'ui/mixins/new-or-edit';
|
||||||
import C from 'ui/utils/constants';
|
import C from 'ui/utils/constants';
|
||||||
import {normalizedChoices} from 'ui/models/stack';
|
import {tagChoices} from 'ui/models/stack';
|
||||||
|
|
||||||
export default Ember.Controller.extend(NewOrEdit, {
|
export default Ember.Controller.extend(NewOrEdit, {
|
||||||
queryParams: ['githubRepo','githubBranch','composeFiles','system'],
|
queryParams: ['githubRepo','githubBranch','composeFiles','system'],
|
||||||
|
|
@ -20,7 +20,7 @@ export default Ember.Controller.extend(NewOrEdit, {
|
||||||
},
|
},
|
||||||
|
|
||||||
groupChoices: function() {
|
groupChoices: function() {
|
||||||
return normalizedChoices(this.get('allStacks'));
|
return tagChoices(this.get('allStacks'));
|
||||||
}.property('allStacks.@each.grouping'),
|
}.property('allStacks.@each.grouping'),
|
||||||
|
|
||||||
willSave: function() {
|
willSave: function() {
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,9 @@ function githubUrl(repo,branch,file) {
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default Ember.Route.extend({
|
||||||
model: function(params/*, transition*/) {
|
model: function(params/*, transition*/) {
|
||||||
let group = 'user';
|
|
||||||
var stack = this.get('store').createRecord({
|
var stack = this.get('store').createRecord({
|
||||||
type: 'stack',
|
type: 'stack',
|
||||||
startOnCreate: true,
|
startOnCreate: true,
|
||||||
group: group
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var dockerUrl = null;
|
var dockerUrl = null;
|
||||||
|
|
|
||||||
|
|
@ -312,6 +312,22 @@ export function pluralize(count,singular,plural) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function uniqKeys(data, field=undefined) {
|
||||||
|
// Make a map of all the unique category names.
|
||||||
|
// If multiple casings of the same name are present, first wins.
|
||||||
|
let cased = {};
|
||||||
|
data.map((obj) => (field ? obj[field] : obj))
|
||||||
|
.filter((str) => str && str.length)
|
||||||
|
.forEach((str) => {
|
||||||
|
let lc = str.toLowerCase();
|
||||||
|
if ( !cased[lc] ) {
|
||||||
|
cased[lc] = str;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return Object.keys(cased).uniq().sort().map((str) => cased[str]);
|
||||||
|
}
|
||||||
|
|
||||||
export function camelToTitle(str) {
|
export function camelToTitle(str) {
|
||||||
return (str||'').dasherize().split('-').map((str) => { return ucFirst(str); }).join(' ');
|
return (str||'').dasherize().split('-').map((str) => { return ucFirst(str); }).join(' ');
|
||||||
}
|
}
|
||||||
|
|
@ -341,7 +357,8 @@ var Util = {
|
||||||
formatKbps: formatKbps,
|
formatKbps: formatKbps,
|
||||||
formatSi: formatSi,
|
formatSi: formatSi,
|
||||||
pluralize: pluralize,
|
pluralize: pluralize,
|
||||||
camelToTitle: camelToTitle
|
camelToTitle: camelToTitle,
|
||||||
|
uniqKeys: uniqKeys,
|
||||||
};
|
};
|
||||||
|
|
||||||
window.Util = Util;
|
window.Util = Util;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "ui",
|
"name": "ui",
|
||||||
"version": "1.2.20",
|
"version": "1.2.22",
|
||||||
"private": true,
|
"private": true,
|
||||||
"directories": {
|
"directories": {
|
||||||
"doc": "doc",
|
"doc": "doc",
|
||||||
|
|
|
||||||
|
|
@ -1124,6 +1124,9 @@ stacksPage:
|
||||||
label: Sort By
|
label: Sort By
|
||||||
state: State
|
state: State
|
||||||
name: Name
|
name: Name
|
||||||
|
tags:
|
||||||
|
all: All Tags
|
||||||
|
one: 'Tag: {name}'
|
||||||
noInfra: You do not currently have any Infrastructure Stacks
|
noInfra: You do not currently have any Infrastructure Stacks
|
||||||
noMatch: No Stacks match the selected tags
|
noMatch: No Stacks match the selected tags
|
||||||
new:
|
new:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue