Browse Source

Storage App

couchdb
Ruel Tmeizeh - RuhNet 9 months ago
commit
1ecdd095a2
23 changed files with 1713 additions and 0 deletions
  1. +615
    -0
      app.js
  2. +33
    -0
      i18n/en-US.json
  3. +26
    -0
      metadata/app.json
  4. BIN
      metadata/icon/storage.png
  5. BIN
      metadata/screenshots/storage1.png
  6. +8
    -0
      storages.js
  7. +295
    -0
      style/app.css
  8. +442
    -0
      style/app.scss
  9. +23
    -0
      style/static/images/mts.svg
  10. +12
    -0
      submodules/mts/i18n/en-US.json
  11. BIN
      submodules/mts/img/logo.png
  12. +48
    -0
      submodules/mts/mts.js
  13. +26
    -0
      submodules/mts/views/formElements.html
  14. +1
    -0
      submodules/mts/views/logo.html
  15. +12
    -0
      submodules/s3/i18n/en-US.json
  16. BIN
      submodules/s3/img/logo.png
  17. +48
    -0
      submodules/s3/s3.js
  18. +25
    -0
      submodules/s3/views/formElements.html
  19. +1
    -0
      submodules/s3/views/logo.html
  20. +5
    -0
      views/field-path.html
  21. +17
    -0
      views/item-settings.html
  22. +32
    -0
      views/layout.html
  23. +44
    -0
      views/new-item.html

+ 615
- 0
app.js View File

@ -0,0 +1,615 @@
define(function(require) {
var $ = require('jquery'),
monster = require('monster'),
toastr = require('toastr'),
storagesConfig = require('./storages');
var settings = {
debug: false
};
var log = function(msg){
if(settings.debug) {
console.log(msg);
}
};
// Autoload submodules
// (Submodules should be described in /apps/storagemgmt/storages.js)
var storagesList = storagesConfig.storages;
var storagesPaths = [];
for (var i = 0, len = storagesList.length; i < len; i++) {
storagesPaths.push('./submodules/' + storagesList[i] + '/' + storagesList[i])
}
require(storagesPaths);
var storageManager = {
name: 'storagemgmt',
css: [ 'app' ],
requests: {},
subscribe: {
'storagemgmt.fetchStorages': 'define_storage_nodes' // For all submodules
},
subModules: storagesList,
storages: {},
i18n: {
'en-US': { customCss: false }
},
load: function(callback) {
var self = this;
self.initApp(function() {
callback && callback(self);
});
},
initApp: function(callback) {
var self = this;
monster.pub('auth.initApp', {
app: self,
callback: callback
});
},
render: function(container) {
var self = this;
monster.pub('storagemgmt.fetchStorages', {
storages: self.storages,
callback: function (args) {
self.extendI18nOfSubmodule(args);
}
});
monster.ui.generateAppLayout(self, {
menus: [
{
tabs: [
{
callback: self.storageManagerRender
}
]
}
]
});
$(document.body).addClass('storagemgmt-app'); // class for styles;
},
extendI18nOfSubmodule: function (args) {
var self = this;
if(args.i18n && args.submoduleName) {
var submoduleLanguages = args.i18n;
var curLanguage = self.i18n.hasOwnProperty(monster.config.whitelabel.language) ? monster.config.whitelabel.language : monster.defaultLanguage;
if (submoduleLanguages.length && submoduleLanguages.length > 0) {
if(submoduleLanguages.indexOf(curLanguage) > -1) {
$.getJSON('/apps/storagemgmt/submodules/' + args.submoduleName + '/i18n/' + curLanguage + '.json').done(function (newDict) {
var dict = self.data.i18n[curLanguage];
$.extend(true, dict, newDict);
})
}
}
} else {
log('Extend i18n of submodule failed');
}
},
storageManagerRender: function(pArgs) {
var self = this,
args = pArgs || {},
$container = args.container || $('.app-content-wrapper'),
callback = args.callback;
if(pArgs.hasOwnProperty('onSetDefault') && typeof(pArgs.onSetDefault) === 'function') {
self.storageManagerOnSetDefault = pArgs.onSetDefault;
}
if(!monster.util.isAdmin()) {
log('Permission error. Use admin account for change storage settings');
return;
}
self.getStorage(function(data) {
var storagesData = self.storageManagerFormatData(data);
for (var i = 0, len = storagesData.length; i < len; i++) {
storagesData[i].logo = self.storages[storagesData[i].type].getLogo()
}
log('Storages List:');
log(storagesData);
var template = $(self.getTemplate({
name: 'layout',
data: {
storages: storagesData
}
}));
self.storageManagerBind(template, args, storagesData);
$container.empty()
.append(template);
if(typeof(callback) === 'function') {
callback(data);
}
});
},
_doStorageInitialRequest: function(callback) {
var self = this;
self.callApi({
resource: 'storage.add',
data: {
accountId : self.accountId,
data : {
'attachments': {},
'plan': {}
},
removeMetadataAPI: true,
generateError: settings.debug
},
success: function(data) {
if(typeof(callback) === 'function') {
callback(data);
}
},
error: function(error) {
var errorMessage = self.i18n.active().storagemgmt.universalErrorMessageTemplate.replace('%api%', 'Storage');
monster.ui.alert(errorMessage);
log(error.status + ' - ' + error.error + ': ' + error.message + ' ');
}
});
},
getStorage: function(callback) {
var self = this;
self.callApi({
resource: 'storage.get',
data: {
accountId: self.accountId,
removeMetadataAPI: true,
generateError: false
},
success: function(data) {
log('Storage Data:');
log(data.data);
callback(data.data);
},
error: function(data, error, globalHandler) {
self._doStorageInitialRequest(function() {
self.getStorage(callback);
});
}
});
},
storageManagerUpdateStorage: function(storageData, callback) {
var self = this;
if(!monster.util.isAdmin()) {
log('Permission error. Use admin account for change storage settings');
return;
}
self.callApi({
resource: 'storage.update',
data: {
accountId: self.accountId,
removeMetadataAPI: true, // or generateError: false
data: storageData
},
success: function(data, status) {
if(typeof(callback) === 'function') {
callback(data);
}
},
error: function(data, error, globalHandler) {
if (error.status === 404) {
callback(undefined);
} else {
globalHandler(data);
}
}
});
},
storageManagerPatchStorage: function(storageData, callback) {
var self = this;
if(!monster.util.isAdmin()) {
log('Permission error. Use admin account for change storage settings');
return;
}
self.callApi({
resource: 'storage.patch',
data: {
accountId: self.accountId,
removeMetadataAPI: true, // or generateError: false
data: storageData
},
success: function(data, status) {
if(typeof(callback) === 'function') {
callback(data);
}
},
error: function(data, error, globalHandler) {
if (error.status === 404) {
callback(undefined);
} else {
globalHandler(data);
}
}
});
},
storageManagerFormatData: function(data) {
var activeStorageId = null;
try {
activeStorageId = data.plan.modb.types.call_recording.attachments.handler;
} catch(e) {
log('Active storage not found');
}
var itemData;
var storagesList = [];
if(data && data.hasOwnProperty('attachments') && Object.keys(data.attachments).length > 0) {
var attachments = data.attachments;
for(var i in attachments) if(attachments.hasOwnProperty(i)) {
itemData = {
id: i,
type: attachments[i].handler,
name: attachments[i].name,
settings: attachments[i].settings,
isActive: false
};
if(activeStorageId && itemData.id === activeStorageId) {
itemData.isActive = true;
}
storagesList.push(itemData)
}
}
return storagesList;
},
storageManagerBind: function(template, args, data) {
var self = this;
template.on('click', '.js-edit-storage', function(e) {
e.preventDefault();
var $editStorageBtn = $(this);
self.getStorage(function(data) {
var $storageItem = $editStorageBtn.closest('.js-storage-item');
var storageType = $storageItem.data('type');
var uuid = $storageItem.data('uuid');
var $container = $storageItem
.find('.js-item-settings-wrapper')
.hide();
if(data.attachments.hasOwnProperty(uuid)) {
var storageData = data.attachments[uuid];
}
var template = self.getTemplate({
name: 'item-settings',
data: {
formElements: self.storages[storageType].getFormElements(storageData)
}
});
$container.empty()
.append(template);
$container.slideDown();
self.storageManagerSettingsBind($container);
})
});
template.on('click', '.js-remove-storage', function(e) {
e.preventDefault();
var uuid = $(this).closest('.js-storage-item').data('uuid');
monster.ui.confirm(self.i18n.active().storagemgmt.confirmDeleteText, function() {
self.storageManagerDeleteStorage(uuid, function() {
$('.js-storage-item[data-uuid="' + uuid + '"]').slideUp(400, function() {
$(this).remove();
});
self.storageManagerShowMessage(self.i18n.active().storagemgmt.successRemovingMessage);
});
}, undefined, {
type: 'warning',
title: self.i18n.active().storagemgmt.confirmDeleteTitle,
confirmButtonText: self.i18n.active().storagemgmt.confirmDelete
});
});
template.on('click', '.js-create-storage', function(e) {
e.preventDefault();
var $newStorageItem = $('.js-storage-items .js-new-storage-item');
if ($newStorageItem.length === 0) {
self.storageManagerShowNewItemPanel();
} else {
$newStorageItem.addClass('flash-effect');
(function($newStorageItem){
var timeoutId = setTimeout(function() {
$newStorageItem.removeClass('flash-effect');
}, 2000)
})($newStorageItem)
}
});
template.on('click', '.js-set-default-storage', function(e) {
e.preventDefault();
var uuid = $(this).closest('.js-storage-item').data('uuid');
var isAlreadyActive = $(this).closest('.js-storage-item').hasClass('active-storage');
if(isAlreadyActive) {
self.storageManagerShowMessage(self.i18n.active().storagemgmt.alreadyActiveMessage, 'warning')
} else {
self.storageManagerSetDefaultStorage(uuid);
}
});
},
storageManagerShowNewItemPanel: function(){
var self = this;
var data = [];
var keyword = '';
var storagesList = Object.keys(self.storages);
for (var i = 0, len = storagesList.length; i < len; i++) {
keyword = storagesList[i];
data.push({
name: keyword,
type: keyword,
logo: self.storages[keyword].getLogo(),
tabId: keyword + '-new-item-content',
tabLink: '#' + keyword + '-new-item-content',
formElements: self.storages[keyword].getFormElements({})
})
}
var template = $(self.getTemplate({
name: 'new-item',
data: {
storages: data
}
}));
self.storageManagerNewItemBind(template);
$('.js-storage-items').append(template);
$('.js-new-storage-item').hide().slideDown(400, function(){});
$('.js-new-storage-tabs').tabs();
},
storageManagerNewItemBind: function(template) {
var self = this;
template.on('click', '.js-save', function (e) {
e.preventDefault();
var $tab = $(this).closest('.js-tab-content-item');
var $form = $tab.find('.js-storage-settings-form');
var formData = monster.ui.getFormData($form[0]);
var isNeedSetDefault = $tab.find('input[name="set_default"]').is(':checked');
var typeKeyword = $tab.data('type');
var newUuid = self.storageManagerGenerateUUID();
delete formData['set_default'];
var storageData = self.storageManagerMakeConfig(typeKeyword, formData, newUuid);
self.storageManagerPatchStorage(storageData, function(){
var renderArgs = {
callback: function () {
self.storageManagerShowMessage(self.i18n.active().storagemgmt.successSavingMessage, 'success');
}
};
if(isNeedSetDefault) {
self.storageManagerSetDefaultStorage(newUuid, function () {
self.storageManagerRender(renderArgs);
});
} else {
self.storageManagerRender(renderArgs);
}
});
});
template.on('click', '.js-cancel', function (e) {
e.preventDefault();
$('.js-new-storage-item').slideUp(400, function(){
$('.js-new-storage-item').remove();
});
});
},
storageManagerMakeConfig (storageKeyword, data, uuid) {
var self = this,
storageData = {
'attachments': {}
};
if(typeof(uuid) === 'undefined') {
uuid = self.storageManagerGenerateUUID();
}
if(storageKeyword && self.storages.hasOwnProperty(storageKeyword)) {
storageData.attachments[uuid] = data;
return storageData;
} else {
monster.ui.alert('Please install storage correctly (' + storageKeyword + ')');
}
},
storageManagerSetDefaultStorage: function(uuid, callback) {
var self = this;
if(!monster.util.isAdmin()) {
log('Permission error. Use admin account for change storage settings');
return;
}
var newData = {
plan: {
modb: {
types: {
call_recording: {
attachments: {
handler: uuid
}
},
mailbox_message: {
attachments: {
handler: uuid
}
}
}
},
account: {
types: {
media: {
attachments: {
handler: uuid
}
}
}
},
}
};
self.storageManagerPatchStorage(newData, function(data) {
$('#storage_manager_wrapper').find('.js-storage-item')
.removeClass('active-storage');
$('.js-storage-item[data-uuid="' + uuid + '"]').addClass('active-storage');
self.storageManagerOnSetDefault(data);
callback && callback(data);
});
},
storageManagerOnSetDefault: function(data) {},
storageManagerSettingsBind: function($settingsContainer) {
var self = this;
$settingsContainer.find('.js-cancel').on('click', function(e) {
e.preventDefault();
$settingsContainer.slideUp(400, function(){
$settingsContainer.empty();
});
});
$settingsContainer.find('.js-save').on('click', function(e) {
e.preventDefault();
var $storageItem = $(this).closest('.js-storage-item');
var $form = $storageItem.find('.js-storage-settings-form');
var formData = monster.ui.getFormData($form[0]);
var storageName = formData.name;
var typeKeyword = $storageItem.data('type');
var uuid = $storageItem.data('uuid');
var storageData = self.storageManagerMakeConfig(typeKeyword, formData, uuid);
self.getStorage(function(existStorageData) {
self.storageManagerPatchStorage(storageData, function(data) {
// update item name
$('.js-storage-item[data-uuid="' + uuid + '"]').find('.js-storage-name').text(storageName);
self.storageManagerShowMessage(self.i18n.active().storagemgmt.successUpdate, 'success');
});
});
});
},
storageManagerDeleteStorage: function(uuid, callback) {
var self = this;
if(!monster.util.isAdmin()) {
log('Permission error. Use admin account for change storage settings');
return;
}
self.getStorage(function(storagesData) {
var resultData = {};
if(storagesData.hasOwnProperty('attachments')) {
resultData.attachments = storagesData.attachments;
}
if(storagesData.hasOwnProperty('plan')) {
resultData.plan = storagesData.plan;
}
if(resultData.attachments && resultData.attachments.hasOwnProperty(uuid)) {
delete resultData.attachments[uuid];
}
try {
if(resultData.plan.modb.types.call_recording.attachments.handler === uuid) {
resultData.plan = {};
}
} catch (e) {}
self.storageManagerUpdateStorage(resultData, function() {
if(typeof(callback) === 'function') {
callback();
}
});
})
},
storageManagerGenerateUUID: function() {
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
},
storageManagerShowMessage: function(msg, msgType) {
var msgTypeClass;
if(typeof(msgType) === 'undefined') {
msgType = 'info';
}
switch(msgType) {
case 'warning':
msgTypeClass = 'storage-msg-warning';
break;
case 'success':
msgTypeClass = 'storage-msg-success';
break;
default: // 'info'
msgTypeClass = 'storage-msg-info';
}
var $msg = $('<div class="storage-message ' + msgTypeClass + '">' + msg + '</div>')
.appendTo($('.js-storage-msg-box')).hide().fadeIn();
$msg.animate({
backgroundColor: '#ffffff'
}, 1000
);
window.setTimeout(function(){
$msg.fadeOut(400, function() {
$msg.remove();
})
}, 4000);
}
};
return storageManager;
});

+ 33
- 0
i18n/en-US.json View File

@ -0,0 +1,33 @@
{
"storagemgmt": {
"title": "Storage Engine Management",
"description": "The Storage Engine Management app allows you manage your storage",
"universalErrorMessageTemplate": "Please contact your system administrator to configure %api% API, required for this application to work",
"welcome": "Welcome {{variable}} to the Storage Engine Management App",
"settingsBtnText": "Settings",
"settingsTitle": "Storage settings",
"newStorageBtnText": "New storage",
"itemSettings": {
"nameLabel": "Storage name",
"bucketLabel": "Bucket name",
"keyLabel": "Key",
"secretLabel": "Secret",
"saveBtnText": "Save Changes",
"cancelBtnText": "Cancel",
"successUpdate": "Your Storage Settings were successfully updated!",
"setDefaultLabel": "Set default"
},
"newItem": {
"saveNewItemText": "Create",
"cancelBtnText": "Cancel"
},
"confirmDelete": "Yes, Remove Storage",
"confirmDeleteText": "This will remove this Storage from this account.",
"confirmDeleteTitle": "Warning! Are you sure?",
"successRemovingMessage": "You successfully removed the storage.",
"successSavingMessage": "You successfully saved the storage.",
"successUpdate": "Your Storage Settings were successfully updated!",
"alreadyActiveMessage": "This storage is already active",
"storageError": "Stores do not work correctly. Contact your administrator to configure it."
}
}

+ 26
- 0
metadata/app.json View File

@ -0,0 +1,26 @@
{
"name": "storage",
"i18n": {
"en-US": {
"label": "Storage",
"description": "The storage management app allows you to configure storage"
}
},
"tags": [
"reseller"
],
"icon": "storage.png",
"api_url": "",
"author": "(C) 2019 CONVERBA LIMITED/2025 RuhNet",
"version": "1.0",
"license": "MPL",
"price": 0,
"screenshots": [
"storage1.png"
],
"urls": {
"documentation": "{documentation_url}",
"howto": "{howto_video_url}"
},
"pvt_type": "app"
}

BIN
metadata/icon/storage.png View File

Before After
Width: 512  |  Height: 512  |  Size: 18 KiB

BIN
metadata/screenshots/storage1.png View File

Before After
Width: 795  |  Height: 636  |  Size: 35 KiB

+ 8
- 0
storages.js View File

@ -0,0 +1,8 @@
define(function(require) {
return {
"storages": [
"s3",
"mts"
]
};
});

+ 295
- 0
style/app.css View File

@ -0,0 +1,295 @@
.storagemgmt-app .storages-settings {
display: block;
background: white;
padding: 13px 23px 2px;
margin-bottom: 24px;
border-radius: 8px;
position: relative; }
.storagemgmt-app .storages-settings .close-btn {
width: 31px;
display: inline-block;
text-align: center;
position: absolute;
top: 10px;
right: 10px; }
.storagemgmt-app .storages-settings .close-btn i.fa {
font-size: 20px; }
.storagemgmt-app .storages-settings .close-btn:hover i.fa {
color: #22A5FF; }
.storage-manager-wrapper {
padding: 0 0 15px 0;
margin-bottom: 15px; }
.storage-manager-wrapper .buttons-wrapper .dynamic-link {
font-size: 16px;
vertical-align: top;
margin-left: 18px;
line-height: 30px; }
.storage-manager-wrapper .btn {
vertical-align: top; }
.storage-manager-wrapper a.btn .fa {
margin-right: 5px;
vertical-align: -1px; }
.storage-manager-wrapper a.btn:hover .fa {
color: #22A5FF; }
.storage-manager-wrapper .storage-items-list {
margin-bottom: 10px; }
.storage-manager-wrapper h3 {
color: #555;
font-weight: normal;
line-height: 1;
font-size: 22px;
margin: 5px 0 13px; }
.storage-manager-wrapper .empty-storage {
border: 1px dashed #999;
height: 320px;
text-align: center; }
.storage-manager-wrapper .empty-storage button {
margin-top: 25px; }
.storage-manager-wrapper .empty-storage i.main-icon {
margin-top: 60px;
font-size: 72px; }
.storage-manager-wrapper .empty-storage .main-title {
font-size: 18px;
margin-top: 40px; }
.storage-manager-wrapper .empty-storage .sub-title {
color: #909099;
margin-top: 5px; }
.storage-manager-wrapper .storage-choice .logo-header {
display: inline-block;
vertical-align: top;
width: 118px;
height: 40px;
padding-top: 8px; }
.storage-manager-wrapper .storage-choice .logo-header img,
.storage-manager-wrapper .storage-choice .logo-header svg {
display: block;
max-height: 40px; }
.storage-manager-wrapper .storage-choice .item-settings-wrapper {
clear: both; }
.storage-manager-wrapper .storage-provider-wrapper {
opacity: 0.6;
max-width: 596px;
width: 49%;
display: inline-block;
vertical-align: top;
margin: 6px 12px 6px 0; }
.storage-manager-wrapper .storage-provider-wrapper.active-storage, .storage-manager-wrapper .storage-provider-wrapper.new-storage-item, .storage-manager-wrapper .storage-provider-wrapper:hover {
opacity: 1; }
.storage-manager-wrapper .storage-provider-wrapper button {
margin-right: 10px;
font-size: 14px; }
.storage-manager-wrapper .storage-provider-wrapper.active-storage .storage-choice .check-icon-wrapper {
visibility: visible; }
.storage-manager-wrapper .storage-provider-wrapper.active-storage .storage-choice a .check-icon {
color: #22A5FF;
opacity: 1; }
.storage-manager-wrapper .storage-provider-wrapper:hover .storage-choice .check-icon-wrapper {
visibility: visible;
opacity: 0.4;
/*webkit-animation: blinker 2s linear infinite;
animation: blinker 2s linear infinite; */ }
.storage-manager-wrapper .storage-provider-wrapper.active-storage:hover .storage-choice .check-icon-wrapper {
opacity: 1; }
.storage-manager-wrapper .storage-provider-wrapper .storage-choice a:hover .check-icon {
color: #22A5FF; }
.storage-manager-wrapper .storage-provider-wrapper .storage-item-settings > .row-fluid {
border-top: 1px solid #D0D0D9;
padding-top: 18px; }
.storage-manager-wrapper .storage-choice {
background: #FFF;
border: 1px solid #D0D0D9;
border-radius: 2px;
line-height: 46px;
padding: 7px 25px 7px; }
.storage-manager-wrapper .storage-choice::after {
content: '';
display: block;
clear: both; }
.storage-manager-wrapper .storage-choice .check-icon-wrapper {
width: 22px;
display: inline-block;
vertical-align: 5px;
margin-right: 15px;
visibility: hidden; }
.storage-manager-wrapper .storage-choice .check-icon {
font-size: 25px; }
.storage-manager-wrapper .storage-choice .right-section {
float: right;
line-height: 25px;
padding-top: 13px;
z-index: 10;
position: relative; }
.storage-manager-wrapper .storage-choice .right-section a {
margin-left: 11px;
vertical-align: top;
display: inline-block; }
.storage-manager-wrapper .storage-choice .right-section a.remove-storage-link {
position: relative;
top: -2px; }
.storage-manager-wrapper .storage-choice .right-section a:hover .fa {
color: #22A5FF; }
.storage-manager-wrapper .storage-choice .right-section a:hover .fa {
color: #22A5FF; }
.storage-manager-wrapper .storage-choice .storage-manager-wrapper .active-storage .select-storage-link:hover .fa {
cursor: default;
/*color: #555;*/ }
.storage-manager-wrapper .storage-choice .right-section a.remove-storage-link:hover .fa {
color: #ff0009; }
.storage-manager-wrapper .storage-choice a .fa {
font-size: 25px;
vertical-align: middle; }
.storage-manager-wrapper .storage-choice .edit-storage-link:hover {
color: #22A5FF; }
.storage-manager-wrapper .storage-choice .storage-name {
font-weight: 600;
text-align: left;
display: inline-block;
vertical-align: top;
margin-top: 0;
width: 160px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden; }
.storage-manager-wrapper .storage-choice .folder-icon {
color: #D0D0D9;
font-size: 20px;
margin-right: 10px;
vertical-align: middle; }
.storage-manager-wrapper .storage-choice .edit-path {
color: #505059;
cursor: pointer;
font-size: 20px;
margin-left: 10px;
vertical-align: middle; }
.storage-manager-wrapper .storage-choice #path {
margin: 0 5px; }
.storage-manager-wrapper .storage-choice .custom-path {
display: inline-block; }
.storage-item-settings .storage-item-logo {
text-align: center; }
.storage-item-settings .storage-item-logo img, .storage-item-settings .storage-item-logo svg {
max-height: 40px; }
.storage-item-settings .form-horizontal {
margin: 0 auto;
display: block;
max-width: 410px; }
.storage-item-settings .form-horizontal .control-label {
width: 110px;
display: inline-block;
vertical-align: top;
float: none;
padding-right: 14px; }
.storage-item-settings .form-horizontal .controls {
margin-left: 0;
display: inline-block;
vertical-align: top; }
.storage-item-settings input[type="text"],
.storage-item-settings input[type="password"] {
border-right: 1px solid #F5F5F5;
border-bottom: 1px solid #F5F5F5;
font-size: 14px; }
.storage-item-settings .buttons-wrapper {
text-align: center; }
.storage-item-settings .ui-tabs {
border: none;
background: none;
padding: 0; }
.storage-item-settings .ui-tabs .ui-tabs-nav {
background: none;
border: none;
padding: 0; }
.storage-item-settings .ui-tabs .ui-tabs-nav li {
border: 0;
border-radius: 0;
background: #9B9B9B;
margin: 0;
width: 50%; }
.storage-item-settings .ui-tabs .ui-tabs-nav li.ui-tabs-active, .storage-item-settings .ui-tabs .ui-tabs-nav li.ui-tabs-active.ui-state-hover {
border: none;
border-radius: 0;
margin: 0;
background: white; }
.storage-item-settings .ui-tabs .ui-tabs-nav li.ui-state-hover {
background: #CDCDCD;
border: none; }
.storage-item-settings .ui-tabs .ui-tabs-nav li a {
width: 100%;
box-sizing: border-box; }
.storage-item-settings .ui-tabs .ui-tabs-panel {
padding-bottom: 0; }
.new-storage-item.flash-effect > .storage-choice {
animation-name: flash_border;
animation-duration: 2s;
animation-timing-function: linear;
animation-iteration-count: 2; }
.new-storage-item .storage-choice {
padding: 0; }
.new-storage-item .storage-item-settings {
padding: 0; }
.new-storage-item .logo-header {
display: block;
margin: 0 auto; }
.new-storage-item .tab-content {
background: none;
border: none; }
.icon-loader {
width: 24px;
height: 24px;
display: inline-block;
vertical-align: top;
background: url("data:image/png;base64,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"); }
.storage-message {
padding: 10px;
border: none;
max-width: 596px;
width: 49%;
min-width: 250px;
margin-bottom: 10px;
font-size: 16px;
line-height: 1.2;
background: white;
color: black;
box-sizing: border-box; }
.storage-msg-warning {
background-color: #ff4200; }
.storage-msg-info {
background-color: #22A5FF; }
.storage-msg-success {
background-color: #00cc2e; }
.dynamic-link:hover {
border-bottom: 1px dashed; }
@media (max-width: 1000px) {
.storage-manager-wrapper .storage-provider-wrapper {
width: 100%; } }
/* ----------------------------
Animations ---------------*/
@keyframes blinker {
50% {
opacity: 0; } }
@keyframes flash_border {
0% {
border-color: #22A5FF; }
50% {
border-color: #D0D0D9; }
100% {
border-color: #22A5FF; } }

+ 442
- 0
style/app.scss View File

@ -0,0 +1,442 @@
.storagemgmt-app {
.storages-settings {
display: block;
background: white;
padding: 13px 23px 2px;
margin-bottom: 24px;
border-radius: 8px;
position: relative;
.close-btn {
width: 31px;
display: inline-block;
text-align: center;
position: absolute;
top: 10px;
right: 10px;
}
.close-btn {
i.fa {
font-size: 20px
}
&:hover i.fa {
color: #22A5FF;
}
}
}
}
.storage-manager-wrapper {
padding: 0 0 15px 0;
margin-bottom: 15px;
.buttons-wrapper .dynamic-link {
font-size: 16px;
vertical-align: top;
margin-left: 18px;
line-height: 30px;
}
.btn {
vertical-align: top;
}
a.btn .fa {
margin-right: 5px;
vertical-align: -1px;
}
a.btn:hover .fa {
color: #22A5FF;
}
.storage-items-list {
margin-bottom: 10px;
}
h3 {
color: #555;
font-weight: normal;
line-height: 1;
font-size: 22px;
margin: 5px 0 13px;
}
.empty-storage {
border: 1px dashed #999;
height: 320px;
text-align: center;
}
.empty-storage button {
margin-top: 25px;
}
.empty-storage i.main-icon {
margin-top: 60px;
font-size: 72px;
}
.empty-storage .main-title {
font-size: 18px;
margin-top: 40px;
}
.empty-storage .sub-title {
color: #909099;
margin-top: 5px;
}
.storage-choice .logo-header {
display: inline-block;
vertical-align: top;
width: 118px;
height: 40px;
padding-top: 8px;
img,
svg {
display: block;
max-height: 40px;
}
}
.storage-choice .item-settings-wrapper {
clear: both;
}
.storage-provider-wrapper {
opacity: 0.6;
max-width: 596px;
width: 49%;
display: inline-block;
vertical-align: top;
margin: 6px 12px 6px 0;
&.active-storage,
&.new-storage-item,
&:hover {
opacity: 1;
}
button {
margin-right: 10px;
font-size: 14px;
}
&.active-storage .storage-choice {
.check-icon-wrapper {
visibility: visible;
}
a .check-icon {
color: #22A5FF;
opacity: 1;
}
}
&:hover .storage-choice .check-icon-wrapper {
visibility: visible;
opacity: 0.4;
/*webkit-animation: blinker 2s linear infinite;
animation: blinker 2s linear infinite; */
}
&.active-storage:hover .storage-choice .check-icon-wrapper {
opacity: 1;
}
.storage-choice a:hover .check-icon {
color: #22A5FF;
}
.storage-item-settings >.row-fluid {
border-top: 1px solid #D0D0D9;
padding-top: 18px;
}
}
.storage-choice {
background: #FFF;
border: 1px solid #D0D0D9;
border-radius: 2px;
line-height: 46px;
padding: 7px 25px 7px;
&::after {
content: '';
display: block;
clear: both;
}
.check-icon-wrapper {
width: 22px;
display: inline-block;
vertical-align: 5px;
margin-right: 15px;
visibility: hidden;
}
.check-icon {
font-size: 25px;
}
.right-section {
float: right;
line-height: 25px;
padding-top: 13px;
z-index: 10;
position: relative;
}
.right-section a {
margin-left: 11px;
vertical-align: top;
display: inline-block;
}
.right-section a.remove-storage-link {
position: relative;
top: -2px;
}
.right-section a:hover .fa {
color: #22A5FF;
}
.right-section a:hover .fa {
color: #22A5FF;
}
.storage-manager-wrapper .active-storage .select-storage-link:hover .fa {
cursor: default;
/*color: #555;*/
}
.right-section a.remove-storage-link:hover .fa {
color: #ff0009;
}
a .fa {
font-size: 25px;
vertical-align: middle;
}
.edit-storage-link:hover {
color: #22A5FF;
}
.storage-name {
font-weight: 600;
text-align: left;
display: inline-block;
vertical-align: top;
margin-top: 0;
width: 160px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.folder-icon {
color: #D0D0D9;
font-size: 20px;
margin-right: 10px;
vertical-align: middle;
}
.edit-path {
color: #505059;
cursor: pointer;
font-size: 20px;
margin-left: 10px;
vertical-align: middle;
}
#path {
margin: 0 5px;
}
.custom-path {
display: inline-block;
}
}
}
.storage-item-settings {
.storage-item-logo {
text-align: center;
img, svg {
max-height: 40px;
}
}
.form-horizontal {
margin: 0 auto;
display: block;
max-width: 410px;
.control-label {
width: 110px;
display: inline-block;
vertical-align: top;
float: none;
padding-right: 14px;
}
.controls {
margin-left: 0;
display: inline-block;
vertical-align: top;
}
}
input[type="text"],
input[type="password"] {
border-right: 1px solid #F5F5F5;
border-bottom: 1px solid #F5F5F5;
font-size: 14px;
}
.buttons-wrapper {
text-align: center;
}
.ui-tabs {
border: none;
background: none;
padding: 0;
.ui-tabs-nav {
background: none;
border: none;
padding: 0;
li {
border: 0;
border-radius: 0;
background: #9B9B9B;
margin: 0;
width: 50%;
&.ui-tabs-active,
&.ui-tabs-active.ui-state-hover {
border: none;
border-radius: 0;
margin: 0;
background: white;
}
&.ui-state-hover {
background: #CDCDCD;
border: none;
}
a {
width: 100%;
box-sizing: border-box;
}
}
}
.ui-tabs-panel {
padding-bottom: 0;
}
}
}
.new-storage-item {
&.flash-effect > .storage-choice {
animation-name: flash_border;
animation-duration: 2s;
animation-timing-function: linear;
animation-iteration-count: 2;
}
.storage-choice {
padding: 0;
}
.storage-item-settings {
padding: 0;
}
.logo-header {
display: block;
margin: 0 auto;
}
.tab-content {
background: none;
border: none;
}
}
.icon-loader {
width: 24px;
height: 24px;
display: inline-block;
vertical-align: top;
background: url('data:image/png;base64,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');
}
.storage-message {
padding: 10px;
border: none;
max-width: 596px;
width: 49%;
min-width: 250px;
margin-bottom: 10px;
font-size: 16px;
line-height: 1.2;
background: white;
color: black;
box-sizing: border-box;
}
.storage-msg-warning {
background-color: #ff4200;
}
.storage-msg-info {
background-color: #22A5FF;
}
.storage-msg-success {
background-color: #00cc2e;
}
.dynamic-link:hover {
border-bottom: 1px dashed;
}
@media (max-width: 1000px) {
.storage-manager-wrapper .storage-provider-wrapper {
width: 100%;
}
}
/* ----------------------------
Animations ---------------*/
@keyframes blinker {
50% { opacity: 0; }
}
@keyframes flash_border {
0% {
border-color: #22A5FF;
}
50% {
border-color: #D0D0D9;
}
100% {
border-color: #22A5FF;
}
}

+ 23
- 0
style/static/images/mts.svg View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 98 35" style="enable-background:new 0 0 98 35;" xml:space="preserve">
<style type="text/css">
.st0{fill:#E30613;}
.st1{fill:#FFFFFF;}
</style>
<path class="st0" d="M97.6,21.4c0,0-2.1,0.3-4.6,0.3c-3,0-3.6-1-3.6-3.3v-2.9c0-2.4,0.5-3.4,3.6-3.4c2.2,0,4.3,0.3,4.3,0.3L97.7,8
c0,0-2.7-0.4-5.1-0.4c-6.3,0-8.5,2.1-8.5,7.1v4.4c0,5.5,2.8,7.1,8.5,7.1c2.3,0,5.4-0.4,5.4-0.4L97.6,21.4z"/>
<polygon class="st0" points="66.3,12.5 71.5,12.5 71.5,25.9 76.9,25.9 76.9,12.5 82.1,12.5 82.4,8 66,8 "/>
<polygon class="st0" points="55.3,24.1 58.2,17.3 58.5,17.3 59.1,25.9 64.3,25.9 63.1,8 58.1,8 53.8,18.2 53.5,18.2 48.9,8 44,8
42.8,25.9 47.9,25.9 48.4,17.3 48.7,17.3 51.9,24.1 "/>
<g id="XMLID_1_">
<g>
<path class="st0" d="M35,3.5v28c0,1.9-1.6,3.5-3.5,3.5h-28C1.6,35,0,33.4,0,31.5v-28C0,1.6,1.6,0,3.5,0h28C33.4,0,35,1.6,35,3.5z
M17.5,30.4C24,30.4,27,25.2,27,20c0-7.3-5-15.5-9.5-15.5C13.1,4.5,8,12.8,8,20.1C8,25.2,10.9,30.4,17.5,30.4z"/>
<path class="st1" d="M27,20c0,5.2-3,10.4-9.5,10.4c-6.6,0-9.5-5.2-9.5-10.3c0-7.3,5.1-15.6,9.5-15.6C22,4.5,27,12.7,27,20z"/>
</g>
<g>
</g>
</g>
</svg>

+ 12
- 0
submodules/mts/i18n/en-US.json View File

@ -0,0 +1,12 @@
{
"storagemgmt": {
"submodules": {
"mts": {
"nameLabel": "Name",
"bucketLabel": "Bucket",
"keyLabel": "Key",
"secretLabel": "Secret"
}
}
}
}

BIN
submodules/mts/img/logo.png View File

Before After
Width: 112  |  Height: 40  |  Size: 18 KiB

+ 48
- 0
submodules/mts/mts.js View File

@ -0,0 +1,48 @@
define(function(require){
var $ = require('jquery');
const CONFIG = {
submoduleName: 'mts',
i18n: [ 'en-US' ]
};
var app = {
requests: {},
subscribe: {
'storagemgmt.fetchStorages': 'defineStorageMTS'
},
defineStorageMTS: function(args) {
var self = this,
storage_nodes = args.storages;
var methods = {
getLogo: function () {
return self.getTemplate({
name: 'logo',
submodule: CONFIG.submoduleName,
data: {}
});
},
getFormElements: function (storageData) {
return self.getTemplate({
name: 'formElements',
submodule: CONFIG.submoduleName,
data: storageData
});
}
};
$.extend(true, storage_nodes, {
'mts': methods
}
);
args.callback && args.callback(CONFIG)
}
};
return app;
});

+ 26
- 0
submodules/mts/views/formElements.html View File

@ -0,0 +1,26 @@
<input type="hidden" name="handler" value="s3"/>
<input type="hidden" name="settings.host" value="s3.cloud.mts.ru"/>
<label class="control-group">
<span class="control-label">{{ @root.i18n.storagemgmt.submodules.s3.nameLabel }}</span>
<div class="controls">
<input type="text" value="{{name}}" name="name">
</div>
</label>
<label class="control-group">
<span class="control-label">{{ @root.i18n.storagemgmt.submodules.s3.bucketLabel }}</span>
<div class="controls">
<input type="text" value="{{settings.bucket}}" name="settings.bucket">
</div>
</label>
<label class="control-group">
<span class="control-label">{{ @root.i18n.storagemgmt.submodules.s3.keyLabel }}</span>
<div class="controls">
<input type="text" value="{{settings.key}}" name="settings.key">
</div>
</label>
<label class="control-group">
<span class="control-label">{{ @root.i18n.storagemgmt.submodules.s3.secretLabel }}</span>
<div class="controls">
<input type="text" value="{{settings.secret}}" name="settings.secret">
</div>
</label>

+ 1
- 0
submodules/mts/views/logo.html View File

@ -0,0 +1 @@
<img src="/apps/storagemgmt/submodules/mts/img/logo.png" alt="mts" />

+ 12
- 0
submodules/s3/i18n/en-US.json View File

@ -0,0 +1,12 @@
{
"storagemgmt": {
"submodules": {
"s3": {
"nameLabel": "Name",
"bucketLabel": "Bucket",
"keyLabel": "Key",
"secretLabel": "Secret"
}
}
}
}

BIN
submodules/s3/img/logo.png View File

Before After
Width: 67  |  Height: 40  |  Size: 5.4 KiB

+ 48
- 0
submodules/s3/s3.js View File

@ -0,0 +1,48 @@
define(function(require){
var $ = require('jquery');
const CONFIG = {
submoduleName: 's3',
i18n: [ 'en-US' ]
};
var app = {
requests: {},
subscribe: {
'storagemgmt.fetchStorages': 'defineStorageS3'
},
defineStorageS3: function(args) {
var self = this,
storage_nodes = args.storages;
var methods = {
getLogo: function () {
return self.getTemplate({
name: 'logo',
submodule: CONFIG.submoduleName,
data: {}
});
},
getFormElements: function (storageData) {
return self.getTemplate({
name: 'formElements',
submodule: CONFIG.submoduleName,
data: storageData
});
}
};
$.extend(true, storage_nodes, {
's3': methods
}
);
args.callback && args.callback(CONFIG)
}
};
return app;
});

+ 25
- 0
submodules/s3/views/formElements.html View File

@ -0,0 +1,25 @@
<input type="hidden" name="handler" value="s3"/>
<label class="control-group">
<span class="control-label">{{ @root.i18n.storagemgmt.submodules.s3.nameLabel }}</span>
<div class="controls">
<input type="text" value="{{name}}" name="name">
</div>
</label>
<label class="control-group">
<span class="control-label">{{ @root.i18n.storagemgmt.submodules.s3.bucketLabel }}</span>
<div class="controls">
<input type="text" value="{{settings.bucket}}" name="settings.bucket">
</div>
</label>
<label class="control-group">
<span class="control-label">{{ @root.i18n.storagemgmt.submodules.s3.keyLabel }}</span>
<div class="controls">
<input type="text" value="{{settings.key}}" name="settings.key">
</div>
</label>
<label class="control-group">
<span class="control-label">{{ @root.i18n.storagemgmt.submodules.s3.secretLabel }}</span>
<div class="controls">
<input type="text" value="{{settings.secret}}" name="settings.secret">
</div>
</label>

+ 1
- 0
submodules/s3/views/logo.html View File

@ -0,0 +1 @@
<img src="/apps/storagemgmt/submodules/s3/img/logo.png" alt="s3" />

+ 5
- 0
views/field-path.html View File

@ -0,0 +1,5 @@
<div class="path-wrapper">
<input class="input-small" type="text" id="path" placeholder="{{ i18n.storagemgmt.pathPlaceholder }}" value="{{path}}">
<button class="save-path monster-button-fit monster-button-success">{{ i18n.save }}</button>
<a href="javascript:void(0);" class="monster-link cancel-link">{{ i18n.cancel }}</a>
</div>

+ 17
- 0
views/item-settings.html View File

@ -0,0 +1,17 @@
<div class="storage-item-settings">
<div class="{{ type }} row-fluid">
<div class="span12">
<form class="form-horizontal js-storage-settings-form">
{{{ formElements }}}
<div class="buttons-wrapper clearfix">
<button type="submit" class="btn btn-primary js-save" >
{{ @root.i18n.storagemgmt.itemSettings.saveBtnText }}
</button>
<button type="button" class="btn js-cancel">
{{ @root.i18n.storagemgmt.itemSettings.cancelBtnText }}
</button>
</div>
</form>
</div>
</div>
</div>

+ 32
- 0
views/layout.html View File

@ -0,0 +1,32 @@
<div id="storage_manager_wrapper" class="storage-manager-wrapper">
<h3>{{ @root.i18n.storagemgmt.settingsTitle }}</h3>
<div class="js-storage-items storage-items-list">
{{#compare storages.length ">" 0}}
{{#each storages}}
<div class="js-storage-item storage-provider-wrapper {{#if isActive }}active-storage{{/if}}" data-type="{{type}}" data-uuid="{{id}}">
<div class="storage-choice">
<a href="" class="js-set-default-storage select-storage-link check-icon-wrapper">
<i class="check-icon fa fa-check-circle"></i>
</a>
<div class="logo-header">
{{{ logo }}}
</div>
<span class="js-storage-name storage-name">{{ name }}</span>
<div class="right-section">
<a class="js-edit-storage edit-storage-link" href="#"><i class="fa fa-pencil-square-o"></i></a>
<a class="js-remove-storage remove-storage-link" href="#"><i class="fa fa-trash-o"></i></a>
</div>
<div class="js-item-settings-wrapper item-settings-wrapper"></div>
</div>
</div>
{{/each}}
{{/compare}}
</div>
<div class="js-storage-msg-box"></div>
<div class="buttons-wrapper">
<a href="" class="js-create-storage btn">
<i class="fa fa-plus"></i>
{{ @root.i18n.storagemgmt.newStorageBtnText }}
</a>
</div>
</div>

+ 44
- 0
views/new-item.html View File

@ -0,0 +1,44 @@
<div class="js-new-storage-item new-storage-item storage-provider-wrapper">
<div class="storage-choice">
<div class="storage-item-settings">
<div class="js-new-storage-tabs">
{{#if storages.length}}
<ul>
{{#each storages}}
<li>
<a href="#{{ type }}-new-item-content" class="storage-item-logo">
{{{ logo }}}
</a>
</li>
{{/each}}
</ul>
<div class="tab-content">
{{#each storages}}
<div class="js-tab-content-item {{ type }} tab-content-item" data-type="{{ type }}" id="{{ type }}-new-item-content">
<form class="form-horizontal js-storage-settings-form">
{{{ formElements }}}
<label class="control-group">
<span class="control-label">{{ @root.i18n.storagemgmt.itemSettings.setDefaultLabel }}</span>
<div class="controls">
<input type="checkbox" checked="checked" value="" name="set_default" />
</div>
</label>
<div class="buttons-wrapper clearfix">
<button type="submit" class="btn btn-primary js-save" >
{{ @root.i18n.storagemgmt.newItem.saveNewItemText }}
</button>
<button type="button" class="btn js-cancel">
{{ @root.i18n.storagemgmt.newItem.cancelBtnText }}
</button>
</div>
</form>
</div>
{{/each}}
</div>
{{/if}}
</div>
</div>
</div>
</div>

Loading…
Cancel
Save