ui/app/utils/cattle.js

345 lines
8.5 KiB
JavaScript

/**
* !!!!!!!!!!!!!!!
* This file is deprecated, and nothing new should use it.
* !!!!!!!!!!!!!!!
*
*/
import Ember from 'ember';
import ApiError from 'ember-api-store/models/error';
import C from 'ui/utils/constants';
import Util from 'ui/utils/util';
function modelProxy(methodName) {
return function(/*arguments*/) {
var model = this.get('model');
return model[methodName].apply(model,arguments);
};
}
var ResourceController = Ember.ObjectController.extend({
cookies: Ember.inject.service(),
application: Ember.inject.controller(),
actions: {
goToApi: function() {
var url = this.get('links.self'); // http://a.b.c.d/v1/things/id, a.b.c.d is where the UI is running
var endpoint = this.get('application.absoluteEndpoint'); // http://e.f.g.h/ , does not include version. e.f.g.h is where the API actually is.
url = url.replace(/https?:\/\/[^\/]+\/?/,endpoint);
// Go to the project-specific version
var projectId = this.get('session').get(C.SESSION.PROJECT);
if ( projectId && this.get('type').toLowerCase() !== 'account' )
{
url = url.replace(/(.*?\/v1)(.*)/,"$1/projects/"+projectId+"$2");
}
// For local development where API doesn't match origin, add basic auth token
if ( url.indexOf(window.location.origin) !== 0 )
{
var token = this.get('cookies').get(C.COOKIE.TOKEN);
if ( token )
{
url = Util.addAuthorization(url, C.USER.BASIC_BEARER, token);
}
}
window.open(url, '_blank');
},
},
displayName: function() {
return this.get('name') || '('+this.get('id')+')';
}.property('name','id'),
isDeleted: Ember.computed.equal('state','removed'),
isPurged: Ember.computed.equal('state','purged'),
hasAction: modelProxy('hasAction'),
doAction: modelProxy('doAction'),
linkFor: modelProxy('linkFor'),
hasLink: modelProxy('hasLink'),
importLink: modelProxy('importLink'),
followLink: modelProxy('followLink'),
save: modelProxy('save'),
delete: modelProxy('delete'),
reload: modelProxy('reload'),
isInStore: modelProxy('isInStore'),
availableActions: function() {
/*
Override me and return [
{
enabled: true/false, // Whether it's enabled or greyed out
detail: true/false, // If true, this action will only be shown on detailed screens
label: 'Delete', // Label shown on hover or in menu
icon: 'icon icon-trash',// Icon shown on screen
action: 'promptDelete', // Action to call on the controller when clicked
altAction: 'delete' // Action to call on the controller when alt+clicked
divider: true, // Just this will make a divider
},
...
]
*/
return [];
},
});
var LegacyNewOrEditMixin = Ember.Mixin.create({
originalModel: null,
errors: null,
saving: false,
editing: true,
primaryResource: Ember.computed.alias('model'),
initFields: function() {
this._super();
this.set('errors',null);
this.set('saving',false);
},
validate: function() {
var model = this.get('primaryResource');
var errors = model.validationErrors();
if ( errors.get('length') )
{
this.set('errors', errors);
return false;
}
this.set('errors', null);
return true;
},
actions: {
error: function(err) {
if ( err instanceof ApiError )
{
if ( err.get('status') === 422 )
{
this.send('validationError',err);
}
else
{
var str = err.get('message');
if ( err.get('detail') )
{
str += ' (' + err.get('detail') + ')';
}
this.set('errors', [str]);
}
}
else if (err)
{
this.set('errors', [err]);
}
else
{
this.set('errors', null);
}
},
validationError: function(err) {
var str = 'Validation failed:';
var something = false;
if ( err.get('fieldName') )
{
str += ' ' + err.get('fieldName');
something = true;
}
if ( err.get('detail') )
{
str += ' (' + err.get('detail') + ')';
something = true;
}
if ( !something )
{
str += ' (' + err.get('code') + ')';
}
switch ( err.get('code') )
{
case 'NotUnique':
str += ' is not unique'; break;
}
this.set('errors', [str]);
},
save: function() {
var self = this;
if ( !this.willSave() )
{
// Validation or something else said not to save
return;
}
this.doSave()
.then(this.didSave.bind(this))
.then(this.doneSaving.bind(this))
.catch(function(err) {
self.send('error', err);
self.errorSaving(err);
}).finally(function() {
self.set('saving',false);
});
}
},
// willSave happens before save and can stop the save from happening
willSave: function() {
this.set('errors',null);
var ok = this.validate();
if ( !ok )
{
// Validation failed
return false;
}
if ( this.get('saving') )
{
// Already saving
return false;
}
this.set('saving',true);
return true;
},
doSave: function() {
var model = this.get('primaryResource');
return model.save().then((newData) => {
var original = this.get('originalModel');
if ( original )
{
original.merge(newData);
}
});
},
// didSave can be used to do additional saving of dependent resources
didSave: function() {
},
// doneSaving happens after didSave
doneSaving: function() {
return this.get('originalModel') || this.get('model');
},
// errorSaving cna be used to do additional cleanup of dependent resources on failure
errorSaving: function(/*err*/) {
},
});
var LegacyTransitioningResourceController = ResourceController.extend({
actions: {
// Common actions that almost all types have in common...
promptDelete: function() {
this.send('openOverlay', 'confirm-delete', 'confirm-delete', this.get('model'), this);
},
confirmDelete: function() {
this.send('delete');
this.send('closeOverlay');
},
cancelDelete: function() {
this.send('closeOverlay');
},
delete: function() {
return this.delete();
},
restore: function() {
return this.doAction('restore');
},
purge: function() {
return this.doAction('purge');
},
},
displayState: function() {
var state = this.get('state')||'';
return state.split(/-/).map((word) => {
return Util.ucFirst(word);
}).join('-');
}.property('state'),
showTransitioningMessage: function() {
var trans = this.get('transitioning');
return (trans === 'yes' || trans === 'error') && (this.get('transitioningMessage')||'').length > 0;
}.property('transitioning','transitioningMessage'),
stateIcon: function() {
var trans = this.get('transitioning');
if ( trans === 'yes' )
{
return 'icon icon-spinner icon-spin';
}
else if ( trans === 'error' )
{
return 'icon icon-alert text-danger';
}
else
{
var map = this.constructor.stateMap;
var key = (this.get('state')||'').toLowerCase();
if ( map && map[key] && map[key].icon !== undefined)
{
if ( typeof map[key].icon === 'function' )
{
return map[key].icon(this);
}
else
{
return map[key].icon;
}
}
return this.constructor.defaultStateIcon;
}
}.property('state','transitioning'),
stateColor: function() {
var map = this.constructor.stateMap;
var key = (this.get('state')||'').toLowerCase();
if ( map && map[key] && map[key].color !== undefined )
{
if ( typeof map[key].color === 'function' )
{
return map[key].color(this);
}
else
{
return map[key].color;
}
}
return this.constructor.defaultStateColor;
}.property('state','transitioning'),
stateBackground: function() {
return this.get('stateColor').replace("text-","bg-");
}.property('stateColor'),
});
// Override stateMap with a map of state -> icon classes
LegacyTransitioningResourceController.reopenClass({
stateMap: null,
defaultStateIcon: 'icon icon-help',
defaultStateColor: ''
});
export default {
LegacyNewOrEditMixin: LegacyNewOrEditMixin,
LegacyTransitioningResourceController: LegacyTransitioningResourceController,
};