extensions 1

This commit is contained in:
Yuri Kuznetsov
2014-09-18 12:22:42 +03:00
parent ce30c759a3
commit 8e177749ef
11 changed files with 389 additions and 5 deletions

View File

@@ -0,0 +1,82 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
namespace Espo\Controllers;
use \Espo\Core\Exceptions\Error;
use \Espo\Core\Exceptions\Forbidden;
class Extension extends \Espo\Core\Controllers\Record
{
protected function checkControllerAccess()
{
if (!$this->getUser()->isAdmin()) {
throw new Forbidden();
}
}
public function actionCreate()
{
throw new Forbidden();
}
public function actionUpdate()
{
throw new Forbidden();
}
public function actionPatch()
{
throw new Forbidden();
}
public function actionListLinked()
{
throw new Forbidden();
}
public function actionDelete()
{
throw new Forbidden();
}
public function actionMassUpdate()
{
throw new Forbidden();
}
public function actionMassDelete()
{
throw new Forbidden();
}
public function actionCreateLink()
{
throw new Forbidden();
}
public function actionRemoveLink()
{
throw new Forbidden();
}
}

View File

@@ -0,0 +1,29 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
namespace Espo\Entities;
class Extension extends \Espo\Core\ORM\Entity
{
}

View File

@@ -31,7 +31,11 @@
"Auth Tokens": "Auth Tokens",
"Authentication": "Authentication",
"Currency": "Currency",
"Integrations": "Integrations"
"Integrations": "Integrations",
"Extensions": "Extensions",
"Upload": "Upload",
"Installing...": "Installing...",
"Upgrading...": "Upgrading..."
},
"layouts": {
"list": "List",
@@ -97,7 +101,8 @@
"selectEntityType": "Select entity type in the left menu.",
"selectUpgradePackage": "Select upgrade package",
"downloadUpgradePackage": "Download needed upgrade package(s) <a href=\"https://sourceforge.net/projects/espocrm/files/Upgrades/\">here</a>.",
"selectLayout": "Select needed layout in the left menu and edit it."
"selectLayout": "Select needed layout in the left menu and edit it.",
"selectExtensionPackage": "Select extension package"
},
"descriptions": {
"settings": "System settings of application.",
@@ -117,7 +122,8 @@
"userInterface": "Configure UI.",
"authTokens": "Active auth sessions. IP address and last access date.",
"authentication": "Authentication settings.",
"currency": "Currency settings and rates."
"currency": "Currency settings and rates.",
"extensions": "Install or uninstall extensions."
},
"options": {
"previewSize": {

View File

@@ -8,7 +8,8 @@
"EmailAccount": "Email Account",
"OutboundEmail": "Outbound Email",
"ScheduledJob": "Scheduled Job",
"ExternalAccount": "External Account"
"ExternalAccount": "External Account",
"Extension": "Extension"
},
"scopeNamesPlural": {
"Email": "Emails",
@@ -19,7 +20,8 @@
"EmailAccount": "Email Accounts",
"OutboundEmail": "Outbound Emails",
"ScheduledJob": "Scheduled Jobs",
"ExternalAccount": "External Accounts"
"ExternalAccount": "External Accounts",
"Extension": "Extensions"
},
"labels": {
"Misc": "Misc",

View File

@@ -111,6 +111,11 @@
"url":"#Admin/userInterface",
"label":"User Interface",
"description":"userInterface"
},
{
"url":"#Admin/extensions",
"label":"Extensions",
"description":"extensions"
}
]
}

View File

@@ -0,0 +1,41 @@
{
"fields": {
"name": {
"type": "varchar",
"required": true
},
"status": {
"type": "enum",
"options": ["Enabled", "Disabled"]
},
"version": {
"type": "varchar",
"required": true,
"maxLength": 50
},
"fileList": {
"type": "jsonArray"
},
"description": {
"type": "text"
},
"createdAt": {
"type": "datetime",
"readOnly": true
},
"createdBy": {
"type": "link",
"readOnly": true
}
},
"links": {
"createdBy": {
"type": "belongsTo",
"entity": "User"
}
},
"collection": {
"sortBy": "createdAt",
"asc": false
}
}

View File

@@ -0,0 +1,7 @@
{
"entity": true,
"layouts": false,
"tab": false,
"acl": false,
"customizable": false
}

View File

@@ -0,0 +1,19 @@
<div class="page-header"><h3><a href="#Admin">{{translate 'Administration'}}</a> &raquo {{translate 'Extensions' scope='Admin'}}</h3></div>
<div class="panel panel-default upload">
<div class="panel-heading">
<h4 class="panel-title">{{translate 'selectExtensionPackage' category='messages' scope='Admin'}}</h4>
</div>
<div class="panel-body">
<div>
<input type="file" name="package" accept="application/zip">
</div>
<div class="message-container text-danger" style="height: 20px; margin-bottom: 10px; margin-top: 10px;"></div>
<div class="buttons-container">
<button class="btn btn-primary disabled" data-action="upload">{{translate 'Upload' scope='Admin'}}</button>
</div>
</div>
</div>
<div class="list-container">{{{list}}}</div>

View File

@@ -159,6 +159,10 @@ Espo.define('Controllers.Admin', 'Controller', function (Dep) {
this.main('Admin.Integrations.Index', {integration: integration});
},
extensions: function (options) {
this.main('Admin.Extensions.Index');
},
rebuild: function (options) {
var master = this.get('master');
Espo.Ui.notify(master.translate('Please wait...'));

View File

@@ -0,0 +1,148 @@
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
Espo.define('Views.Admin.Extensions.Index', 'View', function (Dep) {
return Dep.extend({
template: "admin.extensions.index",
packageContents: null,
events: {
'change input[name="package"]': function (e) {
this.$el.find('button[data-action="upload"]').addClass('disabled');
this.$el.find('.message-container').html('');
var files = e.currentTarget.files;
if (files.length) {
this.selectFile(files[0]);
}
},
'click button[data-action="upload"]': function () {
this.upload();
}
},
setup: function () {
this.getCollectionFactory().create('Extension', function (collection) {
this.collection = collection;
collection.maxSize = this.getConfig().get('recordsPerPage');
this.wait(true);
this.listenToOnce(collection, 'sync', function () {
this.createView('list', 'Extension.Record.List', {
collection: collection,
el: this.options.el + ' > .list-container',
});
this.wait(false);
});
collection.fetch();
}, this);
},
selectFile: function (file) {
var fileReader = new FileReader();
fileReader.onload = function (e) {
this.packageContents = e.target.result;
this.$el.find('button[data-action="upload"]').removeClass('disabled');
}.bind(this);
fileReader.readAsDataURL(file);
},
showError: function (msg) {
msg = this.translate(msg, 'errors', 'Admin');
this.$el.find('.message-container').html(msg);
},
upload: function () {
this.$el.find('button[data-action="upload"]').addClass('disabled');
this.notify('Uploading...');
$.ajax({
url: 'Extension/action/upload',
type: 'POST',
contentType: 'application/zip',
timeout: 0,
data: this.packageContents,
error: function (xhr, t, e) {
this.showError(xhr.getResponseHeader('X-Status-Reason'));
this.notify(false);
}.bind(this)
}).done(function (data) {
if (!data.id) {
this.showError(this.translate('Error occured'));
return;
}
this.notify(false);
this.createView('popup', 'Admin.Extensions.Ready', {
upgradeData: data
}, function (view) {
view.render();
this.$el.find('button[data-action="upload"]').removeClass('disabled');
view.once('run', function () {
view.close();
this.$el.find('.panel.upload').addClass('hidden');
this.run(data.id, data.version);
}, this);
}.bind(this));
}.bind(this)).error;
},
textNotification: function (text) {
this.$el.find('.notify-text').html(text);
},
run: function (id, version) {
var msg = this.translate('Installing...', 'labels', 'Admin');
this.notify('Please wait...');
this.textNotification(msg);
$.ajax({
url: 'Extension/action/install',
type: 'POST',
data: JSON.stringify({
id: id
}),
error: function (xhr) {
var msg = xhr.getResponseHeader('X-Status-Reason');
this.textNotification(this.translate('Error') + ': ' + msg);
}.bind(this)
}).done(function () {
var cache = this.getCache();
if (cache) {
cache.clear();
}
this.createView('popup', 'Admin.Extensions.Done', {
version: version
}, function (view) {
this.notify(false);
view.render();
}.bind(this));
}.bind(this));
},
});
});

View File

@@ -0,0 +1,41 @@
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
Espo.define('Views.Extension.Record.List', 'Views.Record.List', function (Dep) {
return Dep.extend({
checkboxes: false,
removeAction: false,
mergeAction: false,
massUpdateAction: false,
exportAction: false,
allowQuickEdit: false,
});
});