diff --git a/.gitignore b/.gitignore index 1d4edfc5a2..d21efa3c01 100644 --- a/.gitignore +++ b/.gitignore @@ -51,9 +51,9 @@ npm-debug.log* /backup /.project /.loadpath -/app/assets/javascripts/bundles/*.* /app/assets/javascripts/editor/* /app/assets/javascripts/locales/*.* +/frontend/src/locales/*.js /config/additional_environment.rb /config/configuration.yml /config/database.yml diff --git a/.jshintignore b/.jshintignore index 34fea6388e..3054c805e2 100644 --- a/.jshintignore +++ b/.jshintignore @@ -1,5 +1,2 @@ -app/assets/javascripts/date-de-DE.js -app/assets/javascripts/date-en-US.js -app/assets/javascripts/jquery_noconflict.js app/assets/javascripts/project/**/* app/assets/javascripts/lib/**/* diff --git a/.travis.yml b/.travis.yml index c091601d3f..4c134da9a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,8 +38,7 @@ cache: bundler: true directories: - public/assets - - app/assets/javascripts/bundles - - app/assets/javascripts/locales + - frontend/src/locales branches: only: diff --git a/Gemfile.lock b/Gemfile.lock index bcb1fd480d..e41cad4613 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -173,7 +173,6 @@ PATH remote: modules/reporting specs: openproject-reporting (1.0.0) - jquery-tablesorter (~> 1.27.0) openproject-costs reporting_engine @@ -559,8 +558,6 @@ GEM iso8601 (0.12.1) jaro_winkler (1.5.4) jmespath (1.4.0) - jquery-tablesorter (1.27.1) - railties (>= 3.2) json (2.3.0) json-jwt (1.11.0) activesupport (>= 4.2) diff --git a/app/assets/javascripts/action_menu.js b/app/assets/javascripts/action_menu.js deleted file mode 100644 index 8b692974b2..0000000000 --- a/app/assets/javascripts/action_menu.js +++ /dev/null @@ -1,100 +0,0 @@ -//-- copyright -// OpenProject is an open source project management software. -// Copyright (C) 2012-2020 the OpenProject GmbH -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2017 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program 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 2 -// of the License, or (at your option) any later version. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See docs/COPYRIGHT.rdoc for more details. -//++ - -/* - The action menu is a menu that usually belongs to an OpenProject entity (like an Issue, WikiPage, Meeting, ..). - Most likely it looks like this: -
- The following code is responsible to open and close the "more functions" submenu. -*/ - -jQuery(function ($) { - var animationSpeed = 100; // ms - - function menu_top_position(menu) { - // if an h2 tag follows the submenu should unfold out at the border - var menu_start_position; - if (menu.next().get(0) != undefined && (menu.next().get(0).tagName == 'H2')) { - menu_start_position = menu.next().innerHeight() + menu.next().position().top; - } - else if (menu.next().hasClass("wiki-content") && menu.next().children().next().first().get(0) != undefined && menu.next().children().next().first().get(0).tagName == 'H1') { - var wiki_heading = menu.next().children().next().first(); - menu_start_position = wiki_heading.innerHeight() + wiki_heading.position().top; - } - return menu_start_position; - } - - function close_menu(event) { - var menu = $(event.data.menu); - // do not close the menu, if the user accidentally clicked next to a menu item (but still within the menu) - if (event.target !== menu.find(" > li.drop-down.open > ul").get(0)) { - menu.find(" > li.drop-down.open").removeClass("open").find("> ul").slideUp(animationSpeed); - // no need to watch for clicks, when the menu is already closed - $('html').off('click', close_menu); - } - } - - function open_menu(menu) { - var drop_down = menu.find(" > li.drop-down"); - // do not open a menu, which is already open - if (!drop_down.hasClass('open')) { - drop_down.find('> ul').slideDown(animationSpeed, function () { - drop_down.find('li > a:first').focus(); - // when clicking on something, which is not the menu, close the menu - $('html').on('click', {menu: menu.get(0)}, close_menu); - }); - drop_down.addClass('open'); - } - } - - // open the given submenu when clicking on it - function install_menu_logic(menu) { - menu.find(" > li.drop-down").click(function (event) { - open_menu(menu); - // and prevent default action (href) for that element - // but not for the menu items. - var target = $(event.target); - if (target.is('.drop-down') || target.closest('li, ul').is('.drop-down')) { - event.preventDefault(); - } - }); - } - - $('.project-actions, .toolbar-items').each(function (idx, menu) { - install_menu_logic($(menu)); - }); -}); diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb deleted file mode 100644 index 494767196a..0000000000 --- a/app/assets/javascripts/application.js.erb +++ /dev/null @@ -1,397 +0,0 @@ -//-- copyright -// OpenProject is an open source project management software. -// Copyright (C) 2012-2020 the OpenProject GmbH -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License version 3. -// -// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -// Copyright (C) 2006-2013 Jean-Philippe Lang -// Copyright (C) 2010-2013 the ChiliProject Team -// -// This program 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 2 -// of the License, or (at your option) any later version. -// -// This program 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 this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// See docs/COPYRIGHT.rdoc for more details. -//++ - -//= require lib/jquery.colorcontrast -//= require lib/jquery.trap -//= require lib/jquery.is_visible_within - -//= require top_menu -//= require action_menu -//= require breadcrumb -//= require findDomElement -//= require settings -//= require openproject_plugins -//= require versions -//= require forums -//= require_tree ./specific - -//= require custom-fields -//= require date-range -//= require search -//= require colors -//= require tooltips -//= require danger_zone_validation -//= require flash_messages - -//= require_tree ./onboarding - - -function checkAll(selector, checked) { - jQuery('#' + selector + ' input:checkbox').not(':disabled').each(function() { - this.checked = checked; - }); -} - -function toggleCheckboxesBySelector(selector) { - boxes = jQuery(selector); - var all_checked = true; - for (i = 0; i < boxes.length; i++) { if (boxes[i].checked === false) { all_checked = false; } } - for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; } -} - -function setCheckboxesBySelector(checked, selector) { - var boxes = $(selector); - boxes.each(function(ele) { - ele.checked = checked; - }); -} - -var fileFieldCount = 1; - -function addFileField() { - fileFieldCount++; - if (fileFieldCount >= 10) return false; - var clone = jQuery('#attachment_template').clone(true); - clone.removeAttr('id'); - clone.html(clone.html().replace(/\[1\]/g, '['+ fileFieldCount + ']')); - jQuery('#attachments_fields').append(clone); -} - -function randomKey(size) { - var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'); - var key = ''; - for (i = 0; i < size; i++) { - key += chars[Math.floor(Math.random() * chars.length)]; - } - return key; -} - -// Automatic project identifier generation -var projectIdentifierLocked; -var projectIdentifierDefault; -var projectIdentifierMaxLength; - -function generateProjectIdentifier() { - var identifier = jQuery('#project_name').val(); // project name - var diacriticsMap = [ - {'base':'a', 'letters':/[\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F]/g}, - {'base':'aa','letters':/[\uA733\uA732]/g}, - {'base':'ae','letters':/[\u00E4\u00E6\u01FD\u01E3\u00C4\u00C6\u01FC\u01E2]/g}, - {'base':'ao','letters':/[\uA735\uA734]/g}, - {'base':'au','letters':/[\uA737\uA736]/g}, - {'base':'av','letters':/[\uA739\uA73B\uA738\uA73A]/g}, - {'base':'ay','letters':/[\uA73D\uA73C]/g}, - {'base':'b', 'letters':/[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181]/g}, - {'base':'c', 'letters':/[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E]/g}, - {'base':'d', 'letters':/[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779]/g}, - {'base':'dz','letters':/[\u01F3\u01C6\u01F1\u01C4\u01F2\u01C5]/g}, - {'base':'e', 'letters':/[\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E]/g}, - {'base':'f', 'letters':/[\u0066\u24D5\uFF46\u1E1F\u0192\uA77C\u0046\u24BB\uFF26\u1E1E\u0191\uA77B]/g}, - {'base':'g', 'letters':/[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E]/g}, - {'base':'h', 'letters':/[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D]/g}, - {'base':'hv','letters':/[\u0195]/g}, - {'base':'i', 'letters':/[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197]/g}, - {'base':'j', 'letters':/[\u006A\u24D9\uFF4A\u0135\u01F0\u0249\u004A\u24BF\uFF2A\u0134\u0248]/g}, - {'base':'k', 'letters':/[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2]/g}, - {'base':'l', 'letters':/[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780]/g}, - {'base':'lj','letters':/[\u01C9\u01C7\u01C8]/g}, - {'base':'m', 'letters':/[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C]/g}, - {'base':'n', 'letters':/[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4]/g}, - {'base':'nj','letters':/[\u01CC\u01CA\u01CB]/g}, - {'base':'o', 'letters':/[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C]/g}, - {'base':'oe','letters': /[\u00F6\u0153\u00D6\u0152]/g}, - {'base':'oi','letters':/[\u01A3\u01A2]/g}, - {'base':'ou','letters':/[\u0223\u0222]/g}, - {'base':'oo','letters':/[\uA74F\uA74E]/g}, - {'base':'p','letters':/[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754]/g}, - {'base':'q','letters':/[\u0071\u24E0\uFF51\u024B\uA757\uA759\u0051\u24C6\uFF31\uA756\uA758\u024A]/g}, - {'base':'r','letters':/[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782]/g}, - {'base':'s','letters':/[\u0073\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784]/g}, - {'base':'ss','letters':/[\u00DF]/g}, - {'base':'t','letters':/[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786]/g}, - {'base':'tz','letters':/[\uA729\uA728]/g}, - {'base':'u','letters':/[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244]/g}, - {'base':'ue','letters':/[\u00FC\u00DC]/g}, - {'base':'v','letters':/[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245]/g}, - {'base':'vy','letters':/[\uA761\uA760]/g}, - {'base':'w','letters':/[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72]/g}, - {'base':'x','letters':/[\u0078\u24E7\uFF58\u1E8B\u1E8D\u0058\u24CD\uFF38\u1E8A\u1E8C]/g}, - {'base':'y','letters':/[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE]/g}, - {'base':'z','letters':/[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762]/g} - ]; - - for(var i=0; i