@@ -13,7 +13,7 @@ import os, sys, importlib, inspect, json | |||||
from .exceptions import * | from .exceptions import * | ||||
from .utils.jinja import get_jenv, get_template, render_template | from .utils.jinja import get_jenv, get_template, render_template | ||||
__version__ = '8.0.20' | |||||
__version__ = '8.0.21' | |||||
__title__ = "Frappe Framework" | __title__ = "Frappe Framework" | ||||
local = Local() | local = Local() | ||||
@@ -3,7 +3,7 @@ | |||||
<h5 style="margin-top: 25px; margin-bottom: 5px;">{{ doctype.name }}</h5> | <h5 style="margin-top: 25px; margin-bottom: 5px;">{{ doctype.name }}</h5> | ||||
<div class="row"> | <div class="row"> | ||||
{% for f in doctype.fields %} | {% for f in doctype.fields %} | ||||
{% if (frappe.model.no_value_type.indexOf(f.fieldtype)===-1) && (f.fieldtype != "Attach") && (f.fieldtype != "Attach Image")%} | |||||
{% if (frappe.model.no_value_type.indexOf(f.fieldtype)===-1) %} | |||||
{% doctype.reqd||(f.reqd=0);%} | {% doctype.reqd||(f.reqd=0);%} | ||||
<div class="col-sm-4"> | <div class="col-sm-4"> | ||||
<div class="checkbox" style="margin: 5px 0px;"> | <div class="checkbox" style="margin: 5px 0px;"> | ||||
@@ -1,8 +1,7 @@ | |||||
You can setup the bench for production use by configuring two programs, Supervisor and nginx. If you want to revert your Production Setup to Development Setup refer to [these commands](https://github.com/frappe/bench/wiki/Stopping-Production-and-starting-Development) | You can setup the bench for production use by configuring two programs, Supervisor and nginx. If you want to revert your Production Setup to Development Setup refer to [these commands](https://github.com/frappe/bench/wiki/Stopping-Production-and-starting-Development) | ||||
####Easy Production Setup | ####Easy Production Setup | ||||
These steps are automated if you pass `--setup-production` to the easy install script | |||||
or run `sudo bench setup production` | |||||
These steps are automated if you run `sudo bench setup production` | |||||
####Manual Production Setup | ####Manual Production Setup | ||||
@@ -53,4 +52,4 @@ Note: When you restart nginx after the configuration change, it might fail if | |||||
you have another configuration with server block as default for port 80 (in most | you have another configuration with server block as default for port 80 (in most | ||||
cases for the nginx welcome page). You will have to disable this config. Most | cases for the nginx welcome page). You will have to disable this config. Most | ||||
probable places for it to exist are `/etc/nginx/conf.d/default.conf` and | probable places for it to exist are `/etc/nginx/conf.d/default.conf` and | ||||
`/etc/nginx/conf.d/default`. | |||||
`/etc/nginx/conf.d/default`. |
@@ -2,7 +2,21 @@ | |||||
Let us create a new site and call it `library`. | Let us create a new site and call it `library`. | ||||
You can install a new site, by the command `bench new-site library` | |||||
*Note: Before you create any new site, you need to activate the Barracuda storage engine on your MariaDB installation.* | |||||
*Copy the following default ERPNext database settings into your `my.cnf` file.* | |||||
[mysqld] | |||||
innodb-file-format=barracuda | |||||
innodb-file-per-table=1 | |||||
innodb-large-prefix=1 | |||||
character-set-client-handshake = FALSE | |||||
character-set-server = utf8mb4 | |||||
collation-server = utf8mb4_unicode_ci | |||||
[mysql] | |||||
default-character-set = utf8mb4 | |||||
You can then install a new site, by the command `bench new-site library`. | |||||
This will create a new database and site folder and install `frappe` (which is also an application!) in the new site. The `frappe` application has two built-in modules **Core** and **Website**. The Core module contains the basic models for the application. Frappe is a batteries included framework and comes with a lot of built-in models. These models are called **DocTypes**. More on that later. | This will create a new database and site folder and install `frappe` (which is also an application!) in the new site. The `frappe` application has two built-in modules **Core** and **Website**. The Core module contains the basic models for the application. Frappe is a batteries included framework and comes with a lot of built-in models. These models are called **DocTypes**. More on that later. | ||||
@@ -2,6 +2,21 @@ | |||||
Créons un site et appelons le `library`. | Créons un site et appelons le `library`. | ||||
*Remarque: Avant de créer un nouveau site, vous devez activer le moteur de stockage Barracuda sur votre installation MariaDB.* | |||||
*Copiez les paramètres de base de données ERPNext par défaut suivants dans votre fichier `my.cnf`.* | |||||
[mysqld] | |||||
innodb-file-format=barracuda | |||||
innodb-file-per-table=1 | |||||
innodb-large-prefix=1 | |||||
character-set-client-handshake = FALSE | |||||
character-set-server = utf8mb4 | |||||
collation-server = utf8mb4_unicode_ci | |||||
[mysql] | |||||
default-character-set = utf8mb4 | |||||
Vous pouvez installer un nouveau site avec la commande `bench new-site library` | Vous pouvez installer un nouveau site avec la commande `bench new-site library` | ||||
Cette commande va créer une nouvelle base de données, un repertoire et installer `frappe` (qui est aussi une application!) | Cette commande va créer une nouvelle base de données, un repertoire et installer `frappe` (qui est aussi une application!) | ||||
@@ -2,6 +2,21 @@ | |||||
Vamos criar um novo site e chamá-lo de `library`. | Vamos criar um novo site e chamá-lo de `library`. | ||||
*Nota: Antes de criar um novo site, é necessário ativar o mecanismo de armazenamento Barracuda na instalação do MariaDB.* | |||||
*Copie as seguintes configurações de banco de dados ERPNext padrão para o arquivo `my.cnf`.* | |||||
[mysqld] | |||||
innodb-file-format=barracuda | |||||
innodb-file-per-table=1 | |||||
innodb-large-prefix=1 | |||||
character-set-client-handshake = FALSE | |||||
character-set-server = utf8mb4 | |||||
collation-server = utf8mb4_unicode_ci | |||||
[mysql] | |||||
default-character-set = utf8mb4 | |||||
Você pode instalar um novo site, pelo comando `bench new-site library` | Você pode instalar um novo site, pelo comando `bench new-site library` | ||||
Isto irá criar uma nova pasta para o site e um banco de dados e instalar o `frappe` (que também é uma aplicação!) No novo site. A aplicação `frappe` tem dois módulos embutidos **Core** e **WebSite**. O módulo de Core contém os modelos básicos para a aplicação. Frappe é uma estrutura como as pilhas e vem com um monte de modelos internos. Estes modelos são chamados doctypes **Mais sobre isso mais tarde**. | Isto irá criar uma nova pasta para o site e um banco de dados e instalar o `frappe` (que também é uma aplicação!) No novo site. A aplicação `frappe` tem dois módulos embutidos **Core** e **WebSite**. O módulo de Core contém os modelos básicos para a aplicação. Frappe é uma estrutura como as pilhas e vem com um monte de modelos internos. Estes modelos são chamados doctypes **Mais sobre isso mais tarde**. | ||||
@@ -356,14 +356,25 @@ def check_if_ready_for_barracuda(): | |||||
}.items(): | }.items(): | ||||
if mariadb_variables.get(key) != value: | if mariadb_variables.get(key) != value: | ||||
print "="*80 | |||||
print "Please add this to MariaDB's my.cnf and restart MariaDB before proceeding" | |||||
print expected_config_for_barracuda | |||||
print "="*80 | |||||
site = frappe.local.site | |||||
msg = ("Creation of your site - {x} failed because MariaDB is not properly {sep}" | |||||
"configured to use the Barracuda storage engine. {sep}" | |||||
"Please add the settings below to MariaDB's my.cnf, restart MariaDB then {sep}" | |||||
"run `bench new-site site17.local` again.{sep2}" | |||||
"").format(x=site, sep2="\n"*2, sep="\n") | |||||
print_db_config(msg, expected_config_for_barracuda) | |||||
sys.exit(1) | sys.exit(1) | ||||
# raise Exception, "MariaDB needs to be configured!" | # raise Exception, "MariaDB needs to be configured!" | ||||
def print_db_config(explanation, config_text): | |||||
print ("="*80) | |||||
print (explanation) | |||||
print (config_text) | |||||
print ("="*80) | |||||
def extract_sql_gzip(sql_gz_path): | def extract_sql_gzip(sql_gz_path): | ||||
try: | try: | ||||
subprocess.check_call(['gzip', '-d', '-v', '-f', sql_gz_path]) | subprocess.check_call(['gzip', '-d', '-v', '-f', sql_gz_path]) | ||||
@@ -8,10 +8,10 @@ frappe.patches.v6_1.rename_file_data | |||||
frappe.patches.v7_0.re_route #2016-06-27 | frappe.patches.v7_0.re_route #2016-06-27 | ||||
frappe.patches.v7_2.remove_in_filter | frappe.patches.v7_2.remove_in_filter | ||||
execute:frappe.reload_doc('core', 'doctype', 'doctype', force=True) #2017-03-09 | execute:frappe.reload_doc('core', 'doctype', 'doctype', force=True) #2017-03-09 | ||||
frappe.patches.v8_0.drop_in_dialog | |||||
execute:frappe.reload_doc('core', 'doctype', 'docfield', force=True) #2017-03-03 | execute:frappe.reload_doc('core', 'doctype', 'docfield', force=True) #2017-03-03 | ||||
execute:frappe.reload_doc('core', 'doctype', 'docperm') #2017-03-03 | execute:frappe.reload_doc('core', 'doctype', 'docperm') #2017-03-03 | ||||
frappe.patches.v8_0.drop_is_custom_from_docperm | frappe.patches.v8_0.drop_is_custom_from_docperm | ||||
frappe.patches.v8_0.drop_in_dialog | |||||
frappe.patches.v8_0.update_records_in_global_search | frappe.patches.v8_0.update_records_in_global_search | ||||
frappe.patches.v8_0.update_published_in_global_search | frappe.patches.v8_0.update_published_in_global_search | ||||
execute:frappe.reload_doc('core', 'doctype', 'custom_docperm') | execute:frappe.reload_doc('core', 'doctype', 'custom_docperm') | ||||
@@ -583,6 +583,14 @@ fieldset[disabled] .form-control { | |||||
.file-upload .uploaded-filename-display { | .file-upload .uploaded-filename-display { | ||||
max-width: 150px; | max-width: 150px; | ||||
} | } | ||||
.file-upload .file-public-column { | |||||
flex: 0 0 36px; | |||||
order: -1; | |||||
justify-content: flex-end; | |||||
} | |||||
.file-upload .file-public-column input[type="checkbox"] { | |||||
margin-right: 0; | |||||
} | |||||
.frappe-rtl input, | .frappe-rtl input, | ||||
.frappe-rtl textarea { | .frappe-rtl textarea { | ||||
direction: rtl; | direction: rtl; | ||||
@@ -10,6 +10,9 @@ frappe.upload = { | |||||
opts.allow_multiple = 1 | opts.allow_multiple = 1 | ||||
} | } | ||||
// whether to show public/private checkbox or not | |||||
opts.show_private = !("is_private" in opts); | |||||
var d = null; | var d = null; | ||||
// create new dialog if no parent given | // create new dialog if no parent given | ||||
if(!opts.parent) { | if(!opts.parent) { | ||||
@@ -50,7 +53,7 @@ frappe.upload = { | |||||
$uploaded_files_wrapper.removeClass('hidden').empty(); | $uploaded_files_wrapper.removeClass('hidden').empty(); | ||||
file_array = file_array.map( | file_array = file_array.map( | ||||
file => Object.assign(file, {is_private: 1}) | |||||
file => Object.assign(file, {is_private: opts.is_private || 0}) | |||||
) | ) | ||||
$upload.data('attached_files', file_array); | $upload.data('attached_files', file_array); | ||||
@@ -60,22 +63,21 @@ frappe.upload = { | |||||
<div class="list-item__content list-item__content--flex-2"> | <div class="list-item__content list-item__content--flex-2"> | ||||
${__('Filename')} | ${__('Filename')} | ||||
</div> | </div> | ||||
<div class="list-item__content" style="flex: 0 0 64px"> | |||||
${__('Is Private')} | |||||
</div> | |||||
${opts.show_private | |||||
? `<div class="list-item__content file-public-column"> | |||||
${__('Public')} | |||||
</div>` | |||||
: ''} | |||||
<div class="list-item__content list-item__content--activity" style="flex: 0 0 32px"> | <div class="list-item__content list-item__content--activity" style="flex: 0 0 32px"> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
`); | `); | ||||
var file_pills = file_array.map( | var file_pills = file_array.map( | ||||
file => frappe.upload.make_file_row(file.name, !("is_private" in opts)) | |||||
file => frappe.upload.make_file_row(file, opts) | |||||
); | ); | ||||
$uploaded_files_wrapper.append(file_pills); | $uploaded_files_wrapper.append(file_pills); | ||||
} else { | } else { | ||||
$upload.find(".uploaded-filename").addClass("hidden") | |||||
$upload.find(".web-link-wrapper").removeClass("hidden"); | |||||
$upload.find(".private-file").addClass("hidden"); | |||||
$upload.find(".btn-browse").removeClass("btn-default").addClass("btn-primary"); | |||||
frappe.upload.show_empty_state($upload); | |||||
} | } | ||||
}); | }); | ||||
@@ -91,7 +93,7 @@ frappe.upload = { | |||||
var $target = $(e.target); | var $target = $(e.target); | ||||
if ($target.is(':checkbox')) { | if ($target.is(':checkbox')) { | ||||
var is_private = $target.is(':checked'); | |||||
var is_private = !$target.is(':checked'); | |||||
attached_files = attached_files.map(file => { | attached_files = attached_files.map(file => { | ||||
if (file.name === filename) { | if (file.name === filename) { | ||||
@@ -99,6 +101,10 @@ frappe.upload = { | |||||
} | } | ||||
return file; | return file; | ||||
}); | }); | ||||
$uploaded_files_wrapper | |||||
.find(`.list-item-container[data-filename="${filename}"] .fa.fa-fw`) | |||||
.toggleClass('fa-lock fa-unlock-alt'); | |||||
$upload.data('attached_files', attached_files); | $upload.data('attached_files', attached_files); | ||||
} | } | ||||
else if ($target.is('.uploaded-file-remove, .fa-remove')) { | else if ($target.is('.uploaded-file-remove, .fa-remove')) { | ||||
@@ -110,6 +116,10 @@ frappe.upload = { | |||||
$uploaded_files_wrapper | $uploaded_files_wrapper | ||||
.find(`.list-item-container[data-filename="${filename}"]`) | .find(`.list-item-container[data-filename="${filename}"]`) | ||||
.remove(); | .remove(); | ||||
if(attached_files.length === 0) { | |||||
frappe.upload.show_empty_state($upload); | |||||
} | |||||
} | } | ||||
}); | }); | ||||
@@ -144,16 +154,19 @@ frappe.upload = { | |||||
} | } | ||||
}); | }); | ||||
}, | }, | ||||
make_file_row: function(filename, show_private) { | |||||
make_file_row: function(file, { show_private } = {}) { | |||||
var template = ` | var template = ` | ||||
<div class="list-item-container" data-filename="${filename}"> | |||||
<div class="list-item-container" data-filename="${file.name}"> | |||||
<div class="list-item"> | <div class="list-item"> | ||||
<div class="list-item__content list-item__content--flex-2 ellipsis"> | <div class="list-item__content list-item__content--flex-2 ellipsis"> | ||||
${filename} | |||||
<span>${file.name}</span> | |||||
<span style="margin-top: 1px; margin-left: 5px;" | |||||
class="fa fa-fw text-warning ${file.is_private ? 'fa-lock': 'fa-unlock-alt'}"> | |||||
</span> | |||||
</div> | </div> | ||||
${show_private | ${show_private | ||||
? `<div class="list-item__content ellipsis" style="flex: 0 0 64px;"> | |||||
<input type="checkbox" checked/> | |||||
? `<div class="list-item__content file-public-column ellipsis"> | |||||
<input type="checkbox" ${!file.is_private ? 'checked' : ''}/> | |||||
</div>` | </div>` | ||||
: ''} | : ''} | ||||
<div class="list-item__content list-item__content--activity ellipsis" style="flex: 0 0 32px;"> | <div class="list-item__content list-item__content--activity ellipsis" style="flex: 0 0 32px;"> | ||||
@@ -166,6 +179,12 @@ frappe.upload = { | |||||
return $(template); | return $(template); | ||||
}, | }, | ||||
show_empty_state: function($upload) { | |||||
$upload.find(".uploaded-filename").addClass("hidden"); | |||||
$upload.find(".web-link-wrapper").removeClass("hidden"); | |||||
$upload.find(".private-file").addClass("hidden"); | |||||
$upload.find(".btn-browse").removeClass("btn-default").addClass("btn-primary"); | |||||
}, | |||||
upload_multiple_files: function(files /*FileData array*/, args, opts) { | upload_multiple_files: function(files /*FileData array*/, args, opts) { | ||||
var i = -1; | var i = -1; | ||||
@@ -426,6 +426,17 @@ textarea.form-control { | |||||
.uploaded-filename-display { | .uploaded-filename-display { | ||||
max-width: 150px; | max-width: 150px; | ||||
} | } | ||||
.file-public-column { | |||||
flex: 0 0 36px; | |||||
order: -1; | |||||
justify-content: flex-end; | |||||
input[type="checkbox"] { | |||||
margin-right: 0; | |||||
} | |||||
} | |||||
} | } | ||||
.frappe-rtl input ,.frappe-rtl textarea { | .frappe-rtl input ,.frappe-rtl textarea { | ||||