Commit 988c642d authored by Cédric Anne's avatar Cédric Anne Committed by Johan Cwiklinski

Use webpack for JS/CSS libs

parent 97ef2faa
......@@ -35,7 +35,7 @@ shared: &shared
name: Coding standards
command: |
if [[ $(php --version|grep "7\.3") ]]; then vendor/bin/phpcs -d memory_limit=512M -p -n --extensions=php --standard=PSR2 ./src && vendor/bin/phpcs -d memory_limit=512M -p --extensions=php --standard=vendor/glpi-project/coding-standard/GlpiStandard/ --ignore=/.git,/config,/files,/lib,/node_modules,/plugins,/src,/tests/config,/vendor ./; else echo "No CS for this version"; fi
if [[ $(php --version|grep "7\.3") ]]; then node_modules/.bin/eslint ./js && echo "ESLint found no errors"; else echo "No CS for this version"; fi
if [[ $(php --version|grep "7\.3") ]]; then node_modules/.bin/eslint ./js && node_modules/.bin/eslint --env=node --parser-options=ecmaVersion:6 --rule 'indent: ["error", 4]' ./webpack.config.js && echo "ESLint found no errors"; else echo "No CS for this version"; fi
- run:
name: Update DB
command: |
......
......@@ -25,7 +25,6 @@ phpunit.xml
/css/compiled/
!/css/tiny_mce/**/*.min.css
/js/*.min.js
# ignore incomplete locale, fallback to ru.js
# see https://github.com/glpi-project/glpi/issues/3788
/lib/tiny_mce/langs/ru_RU.js
/node_modules/
/public/build/
/public/lib/
![GLPI Logo](https://raw.githubusercontent.com/glpi-project/glpi/master/pics/logos/logo-GLPI-250-black.png)
## How to install?
Installation procedure is entirely automated; there is an [installation documentation](https://readthedocs.org/projects/glpi-install/) you should rely on.
When you are using the source code, there are extra steps, to get all third party libraries installed.
First, [download and install composer](https://getcomposer.org/), a PHP dependency management tool. Once done, go to the GLPI directory and just run:
```bash
$ composer install --no-dev
```
The `--no-dev` flag will prevent development dependencies (such as [atoum, the unit test tool](https://atoum.org)) to be installed. Of course, if you plan to develop on this instance, you must have them installed.
Second, [download and install npm](https://www.npmjs.com/), a JS dependency management tool.
Once done, go to the GLPI directory and run following command to retrieve dependencies from npm repository:
```bash
$ npm install
```
Then, you run the following command to build dependencies into files used by GLPI:
```bash
$ npm run-script build
```
You can use `npm run-script build-dev` if you want to build dependencies for a development use.
......@@ -101,25 +101,6 @@ We are working on a [markdown version](https://github.com/glpi-project/doc)
* [Plugin development documentation](http://glpi-developer-documentation.readthedocs.io/en/master/plugins/index.html)
## Used JS libraries
* [Chartist.js v0.10.1](https://github.com/gionkunz/chartist-js) MIT/WTFPL
* [chartist-plugin-legend v0.6.0](https://github.com/CodeYellowBV/chartist-plugin-legend) ISC
* [chartist-plugin-tooltip v0.0.17](https://github.com/tmmdata/chartist-plugin-tooltip) MIT
* [Font-Awesome v5.5.0](https://github.com/FortAwesome/Font-Awesome) MIT
* [fuzzy v0.1.3](https://github.com/mattyork/fuzzy) MIT
* [gridstack.js v unknow-dev](https://github.com/gridstack/gridstack.js) MIT
* [htmLawed v1.2.4](http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/) LGPL3/GPL2+
* [jQuery v1.12.4](https://github.com/jquery/jquery) MIT
* [jQuery UI v1.10.4](https://github.com/jquery/jquery-ui) MIT
* jQuery plugins *
* [Leaflet v1.3.4](https://github.com/Leaflet/Leaflet) BSD2S
* [PrismJS v1.15.0](https://github.com/PrismJS/prism) MIT
* [spin.js v2.3.2](https://github.com/fgnass/spin.js) MIT
* [TinyMCE v4.9.0](https://github.com/tinymce/tinymce) LGPL2.1
* [Underscore.js v1.8.3](https://github.com/jashkenas/underscore) MIT
* [Lodash v4.17.11](https://github.com/lodash/lodash) MIT
## Support
GLPI is a living software. Improvements are continuously made, new functionalities are being developed, and issues are being fixed.
......
......@@ -35,8 +35,9 @@ include ('../inc/includes.php');
header("Content-Type: text/html; charset=UTF-8");
Html::header_nocache();
echo Html::css("lib/prism/prism.css");
echo Html::script("lib/prism/prism.js");
echo Html::css("public/lib/prismjs/themes/prism-coy.css");
echo Html::script("public/lib/prismjs/components/prism-core.js");
echo Html::script("public/lib/prismjs/components/prism-json.js");
$infos = Telemetry::getTelemetryInfos();
echo "<p>" . __("We only collect the following data : plugins usage, performance and responsiveness statistics about user interface features, memory, and hardware configuration.") . "</p>";
......
......@@ -893,7 +893,7 @@ $ curl -X GET \
Ex:
```javascript
```json
...
"criteria":
[
......@@ -945,7 +945,7 @@ $ curl -X GET \
Ex:
```javascript
```json
...
"metacriteria":
[
......@@ -986,7 +986,7 @@ $ curl -X GET \
* **Returns**:
* 200 (OK) with all rows data with this format:
```javascript
```json
{
"totalcount": ":numberofresults_without_pagination",
"range": ":start-:end",
......@@ -1220,7 +1220,7 @@ Uploading a file requires use of 'multipart/data' content_type. The input data m
Examples usage (CURL):
```shell
```bash
$ curl -X POST \
-H 'Content-Type: multipart/form-data' \
-H "Session-Token: 83af7e620c83a50a18d3eac2f6ed05a3ca0bea62" \
......@@ -1411,7 +1411,7 @@ We provide in root .htaccess of GLPI an example to enable API URL rewriting.
You need to uncomment (removing #) theses lines:
```apache
```apacheconf
#<IfModule mod_rewrite.c>
# RewriteEngine On
# RewriteCond %{REQUEST_FILENAME} !-f
......
......@@ -28,6 +28,26 @@
* along with GLPI. If not, see <http://www.gnu.org/licenses/>.
* ---------------------------------------------------------------------
*/
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default {
border: 1px solid #FFF;
background-color: #e6e6e6;
color: #555555;
}
.ui-state-active,
.ui-widget-content .ui-state-active,
.ui-widget-header .ui-state-active {
border: 1px solid #FFF;
background-color: #ffffff;
color: #212121;
}
.ui-state-active a,
.ui-state-active a:link,
.ui-state-active a:visited {
color: #212121;
}
.ui-dialog { z-index: 1000 !important ;}
.ui-widget-overlay.glpi_modal { z-index: 2000 !important ;}
.glpi_modal { z-index: 5000 !important ;}
......
......@@ -2261,8 +2261,13 @@ abstract class API extends CommonGLPI {
*/
public function inlineDocumentation($file) {
self::header(true, __("API Documentation"));
echo Html::css("lib/prism/prism.css");
echo Html::script("lib/prism/prism.js");
echo Html::css("public/lib/prismjs/themes/prism-coy.css");
echo Html::script("public/lib/prismjs/components/prism-core.js");
echo Html::script("public/lib/prismjs/components/prism-apacheconf.js");
echo Html::script("public/lib/prismjs/components/prism-bash.js");
echo Html::script("public/lib/prismjs/components/prism-clike.js");
echo Html::script("public/lib/prismjs/components/prism-json.js");
echo Html::script("public/lib/prismjs/components/prism-nginx.js");
echo "<div class='documentation'>";
$documentation = file_get_contents(GLPI_ROOT.'/'.$file);
......
......@@ -1109,7 +1109,7 @@ class Entity extends CommonTreeDropdown {
echo "<script type='text/javascript'>";
echo " $(function() {
$.getScript('{$CFG_GLPI["root_doc"]}/lib/jqueryplugins/jstree/jstree.min.js').done(function(data, textStatus, jqxhr) {
$.getScript('{$CFG_GLPI["root_doc"]}/public/lib/jstree/jstree.js').done(function(data, textStatus, jqxhr) {
$('#tree_projectcategory$rand')
// call `.jstree` with the options object
.jstree({
......
This diff is collapsed.
......@@ -188,8 +188,8 @@ class KnowbaseItem_Revision extends CommonDBTM {
echo "</tr>";
}
echo Html::script("lib/jqueryplugins/prettytextdiff/diff_match_patch.js");
echo Html::script("lib/jqueryplugins/prettytextdiff/jquery.pretty-text-diff.js");
echo Html::script("public/lib/diff-match-patch/index.js");
echo Html::script("public/lib/jquery-prettytextdiff/jquery.pretty-text-diff.js");
echo "<script type='text/javascript'>
$(function() {
$('.restore').on('click', function(e) {
......
......@@ -85,11 +85,11 @@ if (!file_exists(GLPI_CONFIG_DIR . "/config_db.php")) {
// Appel CSS
echo Html::scss('main_styles');
// font awesome icons
echo Html::css('lib/font-awesome/css/all.css');
echo Html::css('public/lib/fontawesome-free/css/all.css');
echo Html::script('lib/jquery/js/jquery.js');
echo Html::script('lib/jqueryplugins/select2/js/select2.full.js');
echo Html::css('lib/jqueryplugins/select2/css/select2.css');
echo Html::script('public/lib/jquery/jquery.js');
echo Html::script('public/lib/select2/js/select2.full.js');
echo Html::css('public/lib/select2/css/select2.css');
echo Html::script('js/common.js');
echo "</head>";
......
......@@ -55,14 +55,14 @@ function header_html($etape) {
echo "<title>Setup GLPI</title>";
// LIBS
echo Html::script("lib/jquery/js/jquery.js");
echo Html::script('lib/jquery/js/jquery-ui-1.10.4.custom.js');
echo Html::script("lib/jqueryplugins/select2/js/select2.js");
echo Html::script("public/lib/jquery/jquery.js");
echo Html::script('public/lib/jquery-ui-dist/jquery-ui.js');
echo Html::script("public/lib/select2/js/select2.full.js");
echo Html::script("js/common.js");
// CSS
echo Html::css('lib/jquery/css/smoothness/jquery-ui-1.10.4.custom.css');
echo Html::css("lib/jqueryplugins/select2/css/select2.css");
echo Html::css('public/lib/jquery-ui-dist/jquery-ui.css');
echo Html::css("public/lib/select2/css/select2.css");
echo Html::css("css/style_install.css");
echo "</head>";
echo "<body>";
......
......@@ -111,11 +111,11 @@ echo "<meta http-equiv='Content-Script-Type' content='text/javascript'>";
echo "<meta http-equiv='Content-Style-Type' content='text/css'>";
echo "<title>Setup GLPI</title>";
//JS
echo Html::script("lib/jquery/js/jquery.js");
echo Html::script('lib/jquery/js/jquery-ui-1.10.4.custom.js');
echo Html::script("public/lib/jquery/jquery.js");
echo Html::script('public/lib/jquery-ui-dist/jquery-ui.js');
// CSS
echo "<link rel='stylesheet' href='../css/style_install.css' type='text/css' media='screen' >";
echo Html::css('lib/jquery/css/smoothness/jquery-ui-1.10.4.custom.css');
echo Html::css('public/lib/jquery-ui-dist/jquery-ui.css');
echo "</head>";
echo "<body>";
echo "<div id='principal'>";
......
// This file is the entry point of webpack.
// TODO Make JS code splitted into modules that can be imported by the "import" directive
Copyright (c) 2013 Gion Kunz <gion.kunz@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Internet Systems Consortium license
===================================
Copyright (c) 2016, Code Yellow B.V.
Permission to use, copy, modify, and/or distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright notice
and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['chartist'], function (chartist) {
return (root.returnExportsGlobal = factory(chartist));
});
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like enviroments that support module.exports,
// like Node.
module.exports = factory(require('chartist'));
} else {
root['Chartist.plugins.legend'] = factory(root.Chartist);
}
}(this, function (Chartist) {
/**
* This Chartist plugin creates a legend to show next to the chart.
*
*/
'use strict';
var defaultOptions = {
className: '',
classNames: false,
removeAll: false,
legendNames: false,
clickable: true,
onClick: null,
position: 'top'
};
Chartist.plugins = Chartist.plugins || {};
Chartist.plugins.legend = function (options) {
function compareNumbers(a, b) {
return a - b;
}
// Catch invalid options
if (options && options.position) {
if (!(options.position === 'top' || options.position === 'bottom' || options.position instanceof HTMLElement)) {
throw Error('The position you entered is not a valid position');
}
if(options.position instanceof HTMLElement){
// Detatch DOM element from options object, because Chartist.extend currently chokes on circular references present in HTMLElements
var cachedDOMPosition = options.position;
delete options.position;
}
}
options = Chartist.extend({}, defaultOptions, options);
if(cachedDOMPosition){
// Reattatch the DOM Element position if it was removed before
options.position = cachedDOMPosition
}
return function legend(chart) {
var existingLegendElement = chart.container.querySelector('.ct-legend');
if (existingLegendElement) {
// Clear legend if already existing.
existingLegendElement.parentNode.removeChild(existingLegendElement);
}
// Set a unique className for each series so that when a series is removed,
// the other series still have the same color.
if (options.clickable) {
var newSeries = chart.data.series.map(function (series, seriesIndex) {
if (typeof series !== 'object') {
series = {
value: series
};
}
series.className = series.className || chart.options.classNames.series + '-' + Chartist.alphaNumerate(seriesIndex);
return series;
});
chart.data.series = newSeries;
}
var legendElement = document.createElement('ul'),
isPieChart = chart instanceof Chartist.Pie;
legendElement.className = 'ct-legend';
if (chart instanceof Chartist.Pie) {
legendElement.classList.add('ct-legend-inside');
}
if (typeof options.className === 'string' && options.className.length > 0) {
legendElement.classList.add(options.className);
}
if (chart.options.width) {
legendElement.style.cssText = 'width: ' + chart.options.width + 'px;margin: 0 auto;';
}
var removedSeries = [],
originalSeries = chart.data.series.slice(0);
// Get the right array to use for generating the legend.
var legendNames = chart.data.series,
useLabels = isPieChart && chart.data.labels;
if (useLabels) {
var originalLabels = chart.data.labels.slice(0);
legendNames = chart.data.labels;
}
legendNames = options.legendNames || legendNames;
// Check if given class names are viable to append to legends
var classNamesViable = (Array.isArray(options.classNames) && (options.classNames.length === legendNames.length));
// Loop through all legends to set each name in a list item.
legendNames.forEach(function (legend, i) {
var li = document.createElement('li');
li.className = 'ct-series-' + i;
// Append specific class to a legend element, if viable classes are given
if (classNamesViable) {
li.className += ' ' + options.classNames[i];
}
li.setAttribute('data-legend', i);
li.textContent = legend.name || legend;
legendElement.appendChild(li);
});
chart.on('created', function (data) {
// Append the legend element to the DOM
if(!(options.position instanceof HTMLElement))
{
switch (options.position) {
case 'top':
chart.container.insertBefore(legendElement, chart.container.childNodes[0]);
break;
case 'bottom':
chart.container.insertBefore(legendElement, null);
break;
}
}
else {
// Appends the legend element as the last child of a given HTMLElement
options.position.insertBefore(legendElement, null);
}
});
if (options.clickable) {
legendElement.addEventListener('click', function (e) {
var li = e.target;
if (li.parentNode !== legendElement || !li.hasAttribute('data-legend'))
return;
e.preventDefault();
var seriesIndex = parseInt(li.getAttribute('data-legend')),
removedSeriesIndex = removedSeries.indexOf(seriesIndex);
if (remov