mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-26 08:35:00 +00:00
reorganize assets: move files and adapt links, remove unused
* chill: chill theme entrypoint * lib: local libs, called in several place but don't have entrypoint * module: local libs with specific entrypoints * page: pages with specific entrypoints * vuejs: vue components with specific entrypoints remove local libs jquery and select2, they already exists in node_modules remove duplicate fonts
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
require("./layout.scss");
|
||||
|
||||
|
@@ -0,0 +1,21 @@
|
||||
nav.chill-breadcrumb {
|
||||
ul.list.on-left {
|
||||
li {
|
||||
border-right: 10px solid var(--chill-red);
|
||||
}
|
||||
li.active {
|
||||
border-right: 10px solid var(--chill-green);
|
||||
}
|
||||
li.past {
|
||||
border-right: 10px solid var(--chill-blue);
|
||||
}
|
||||
li.no-jump{
|
||||
border-right: 10px solid var(--chill-light-gray);
|
||||
background-color: var(--chill-yellow);
|
||||
padding: 0.3em 0.3em 0.3em 0.6em;
|
||||
color: var(--chill-dark-gray);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
div.chill-collection {
|
||||
padding: 1em;
|
||||
|
||||
ul.list-entry {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin-bottom: 1.5rem;
|
||||
|
||||
li.entry {
|
||||
padding: 1em;
|
||||
border: 1px solid var(--bs-chill-light-gray);
|
||||
|
||||
&:nth-child(even) {
|
||||
background-color: var(--bs-chill-light-gray);
|
||||
}
|
||||
}
|
||||
|
||||
button.remove-entry {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
button.add-entry {
|
||||
}
|
||||
}
|
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Javascript file which handle ChillCollectionType
|
||||
*
|
||||
* Two events are emitted by this module, both on window and on collection / ul.
|
||||
*
|
||||
* Collection (an UL element) and entry (a li element) are associated with those
|
||||
* events.
|
||||
*
|
||||
* ```
|
||||
* window.addEventListener('collection-add-entry', function(e) {
|
||||
* console.log(e.detail.collection);
|
||||
* console.log(e.detail.entry);
|
||||
* });
|
||||
*
|
||||
* window.addEventListener('collection-remove-entry', function(e) {
|
||||
* console.log(e.detail.collection);
|
||||
* console.log(e.detail.entry);
|
||||
* });
|
||||
*
|
||||
* collection.addEventListener('collection-add-entry', function(e) {
|
||||
* console.log(e.detail.collection);
|
||||
* console.log(e.detail.entry);
|
||||
* });
|
||||
*
|
||||
* collection.addEventListener('collection-remove-entry', function(e) {
|
||||
* console.log(e.detail.collection);
|
||||
* console.log(e.detail.entry);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
require('./collection.scss');
|
||||
|
||||
class CollectionEvent {
|
||||
constructor(collection, entry) {
|
||||
this.collection = collection;
|
||||
this.entry = entry;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {type} button
|
||||
* @returns {handleAdd}
|
||||
*/
|
||||
var handleAdd = function(button) {
|
||||
var
|
||||
form_name = button.dataset.collectionAddTarget,
|
||||
prototype = button.dataset.formPrototype,
|
||||
collection = document.querySelector('ul[data-collection-name="'+form_name+'"]'),
|
||||
entry = document.createElement('li'),
|
||||
event = new CustomEvent('collection-add-entry', { detail: { collection: collection, entry: entry } }),
|
||||
counter = collection.childNodes.length,
|
||||
content
|
||||
;
|
||||
content = prototype.replace(new RegExp('__name__', 'g'), counter);
|
||||
entry.innerHTML = content;
|
||||
entry.classList.add('entry');
|
||||
initializeRemove(collection, entry);
|
||||
collection.appendChild(entry);
|
||||
|
||||
collection.dispatchEvent(event);
|
||||
window.dispatchEvent(event);
|
||||
};
|
||||
|
||||
var initializeRemove = function(collection, entry) {
|
||||
var
|
||||
button = document.createElement('button'),
|
||||
isPersisted = entry.dataset.collectionIsPersisted,
|
||||
content = collection.dataset.collectionButtonRemoveLabel,
|
||||
allowDelete = collection.dataset.collectionAllowDelete,
|
||||
event = new CustomEvent('collection-remove-entry', { detail: { collection: collection, entry: entry } })
|
||||
;
|
||||
|
||||
if (allowDelete === '0' && isPersisted === '1') {
|
||||
return;
|
||||
}
|
||||
|
||||
button.classList.add('btn', 'btn-delete', 'remove-entry');
|
||||
button.textContent = content;
|
||||
|
||||
button.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
entry.remove();
|
||||
collection.dispatchEvent(event);
|
||||
window.dispatchEvent(event);
|
||||
});
|
||||
|
||||
entry.appendChild(button);
|
||||
};
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
var
|
||||
addButtons = document.querySelectorAll("button[data-collection-add-target]"),
|
||||
collections = document.querySelectorAll("ul[data-collection-name]")
|
||||
;
|
||||
|
||||
for (let i = 0; i < addButtons.length; i ++) {
|
||||
let addButton = addButtons[i];
|
||||
addButton.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
handleAdd(e.target);
|
||||
});
|
||||
}
|
||||
|
||||
for (let i = 0; i < collections.length; i ++) {
|
||||
let entries = collections[i].querySelectorAll(':scope > li');
|
||||
|
||||
for (let j = 0; j < entries.length; j ++) {
|
||||
initializeRemove(collections[i], entries[j]);
|
||||
}
|
||||
}
|
||||
});
|
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Champs Libres Cooperative <info@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
var mime = require('mime-types')
|
||||
|
||||
var download_report = (url, container) => {
|
||||
var download_text = container.dataset.downloadText,
|
||||
alias = container.dataset.alias;
|
||||
|
||||
window.fetch(url, { credentials: 'same-origin' })
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw Error(response.statusText);
|
||||
}
|
||||
|
||||
return response.blob();
|
||||
}).then(blob => {
|
||||
|
||||
var content = URL.createObjectURL(blob),
|
||||
link = document.createElement("a"),
|
||||
type = blob.type,
|
||||
hasForcedType = 'mimeType' in container.dataset,
|
||||
extension;
|
||||
|
||||
if (hasForcedType) {
|
||||
// force a type
|
||||
type = container.dataset.mimeType;
|
||||
blob = new Blob([ blob ], { 'type': type });
|
||||
content = URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
extension = mime.extension(type);
|
||||
|
||||
link.appendChild(document.createTextNode(download_text));
|
||||
link.classList.add("btn", "btn-action");
|
||||
link.href = content;
|
||||
link.download = alias;
|
||||
if (extension !== false) {
|
||||
link.download = link.download + '.' + extension;
|
||||
}
|
||||
container.innerHTML = "";
|
||||
container.appendChild(link);
|
||||
}).catch(function(error) {
|
||||
console.log(error);
|
||||
var problem_text =
|
||||
document.createTextNode("Problem during download");
|
||||
|
||||
container
|
||||
.replaceChild(problem_text, container.firstChild);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = download_report;
|
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Champs Libres Cooperative <info@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
chill.download_report = require("./download-report.js");
|
@@ -0,0 +1,6 @@
|
||||
.chill-entity__comment-embeddable {
|
||||
.chill-entity__comment-embeddable__metadata {
|
||||
font-size: smaller;
|
||||
color: var(--chill-light-gray);
|
||||
}
|
||||
}
|
@@ -0,0 +1,2 @@
|
||||
// css classes to render entities
|
||||
require('./comment_embeddable.scss');
|
@@ -0,0 +1,20 @@
|
||||
.container-export {
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem;
|
||||
|
||||
.export-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.export-list__element {
|
||||
min-width: 18rem;
|
||||
max-width: 20rem;
|
||||
padding: 1rem;
|
||||
margin: 1rem;
|
||||
flex-grow: 1;
|
||||
|
||||
border: 1px solid var(--chill-gray);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1 @@
|
||||
require('./export-list.scss');
|
@@ -0,0 +1,36 @@
|
||||
|
||||
window.addEventListener('load', function (e) {
|
||||
var
|
||||
postalCodes = document.querySelectorAll('[data-select-interactive-loading]')
|
||||
;
|
||||
|
||||
for (let i = 0; i < postalCodes.length; i++) {
|
||||
let
|
||||
searchUrl = postalCodes[i].dataset.searchUrl,
|
||||
noResultsLabel = postalCodes[i].dataset.noResultsLabel,
|
||||
errorLoadLabel = postalCodes[i].dataset.errorLoadLabel,
|
||||
searchingLabel = postalCodes[i].dataset.searchingLabel
|
||||
;
|
||||
|
||||
|
||||
$(postalCodes[i]).select2({
|
||||
allowClear: true,
|
||||
language: {
|
||||
errorLoading: function () {
|
||||
return errorLoadLabel;
|
||||
},
|
||||
noResults: function () {
|
||||
return noResultsLabel;
|
||||
},
|
||||
searching: function () {
|
||||
return searchingLabel;
|
||||
}
|
||||
},
|
||||
ajax: {
|
||||
url: searchUrl,
|
||||
dataType: 'json',
|
||||
delay: 250
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
@@ -0,0 +1 @@
|
||||
require("./show_hide.js");
|
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* Create a control to show or hide values
|
||||
*
|
||||
* Possible options are:
|
||||
*
|
||||
* - froms: an Element, an Array of Element, or a NodeList. A
|
||||
* listener will be attached to **all** input of those elements
|
||||
* and will trigger the check on changes
|
||||
* - test: a function which will test the element and will return true
|
||||
* if the content must be shown, false if it must be hidden.
|
||||
* The function will receive the `froms` as first argument, and the
|
||||
* event as second argument.
|
||||
* - container: an Element, an Array of Element, or a Node List. The
|
||||
* child nodes will be hidden / shown inside this container
|
||||
* - event_name: the name of the event to listen to. `'change'` by default.
|
||||
*
|
||||
* @param object options
|
||||
*/
|
||||
var ShowHide = function(options) {
|
||||
var
|
||||
froms = typeof options.froms[Symbol.iterator] === "function" ? options.froms : [ options.froms ], //options.froms;
|
||||
test = options.test,
|
||||
container = typeof options.container[Symbol.iterator] === "function" ? options.container : [ options.container ],
|
||||
is_shown = true,
|
||||
event_name = 'event_name' in options ? options.event_name : 'change',
|
||||
container_content = [],
|
||||
debug = 'debug' in options ? options.debug : false,
|
||||
load_event = 'load_event' in options ? options.load_event : 'load',
|
||||
id = 'uid' in options ? options.id : Math.random();
|
||||
|
||||
var bootstrap = function(event) {
|
||||
if (debug) {
|
||||
console.log('debug is activated on this show-hide', this);
|
||||
}
|
||||
// keep the content in memory
|
||||
for (let c of container.values()) {
|
||||
let contents = [];
|
||||
for (let el of c.childNodes.values()) {
|
||||
contents.push(el);
|
||||
}
|
||||
container_content.push(contents);
|
||||
}
|
||||
|
||||
// attach the listener on each input
|
||||
for (let f of froms.values()) {
|
||||
let
|
||||
inputs = f.querySelectorAll('input'),
|
||||
selects = f.querySelectorAll('select');
|
||||
|
||||
for (let input of inputs.values()) {
|
||||
if (debug) {
|
||||
console.log('attaching event to input', input);
|
||||
}
|
||||
input.addEventListener(event_name, function(e) {
|
||||
onChange(e);
|
||||
});
|
||||
}
|
||||
for (let input of selects.values()) {
|
||||
if (debug) {
|
||||
console.log('attaching event to selects', input);
|
||||
}
|
||||
input.addEventListener(event_name, function(e) {
|
||||
onChange(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// first launch of the show/hide
|
||||
onChange(event);
|
||||
};
|
||||
|
||||
|
||||
var onChange = function (event) {
|
||||
var result = test(froms, event), me;
|
||||
|
||||
if (result === true) {
|
||||
if (is_shown === false) {
|
||||
forceShow();
|
||||
me = new CustomEvent('show-hide-show', { detail: { id: id, container: container, froms: froms } });
|
||||
window.dispatchEvent(me);
|
||||
}
|
||||
} else if (result === false) {
|
||||
if (is_shown) {
|
||||
forceHide();
|
||||
me = new CustomEvent('show-hide-hide', { detail: { id: id, container: container, froms: froms } });
|
||||
window.dispatchEvent(me);
|
||||
}
|
||||
} else {
|
||||
throw "the result of test is not a boolean";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var forceHide = function() {
|
||||
if (debug) {
|
||||
console.log('force hide');
|
||||
}
|
||||
for (let contents of container_content.values()) {
|
||||
for (let el of contents.values()) {
|
||||
el.remove();
|
||||
}
|
||||
}
|
||||
is_shown = false;
|
||||
};
|
||||
|
||||
var forceShow = function() {
|
||||
if (debug) {
|
||||
console.log('show');
|
||||
}
|
||||
for (let i of container_content.keys()) {
|
||||
var contents = container_content[i];
|
||||
for (let el of contents.values()) {
|
||||
container[i].appendChild(el);
|
||||
}
|
||||
}
|
||||
is_shown = true;
|
||||
};
|
||||
|
||||
var forceCompute = function(event) {
|
||||
onChange(event);
|
||||
};
|
||||
|
||||
|
||||
if (load_event !== null) {
|
||||
window.addEventListener('load', bootstrap);
|
||||
} else {
|
||||
bootstrap(null);
|
||||
}
|
||||
|
||||
return {
|
||||
forceHide: forceHide,
|
||||
forceShow: forceShow,
|
||||
forceCompute: forceCompute,
|
||||
};
|
||||
};
|
||||
|
||||
export {ShowHide};
|
@@ -0,0 +1,2 @@
|
||||
require("./tabs.js");
|
||||
require("./tabs.scss");
|
118
src/Bundle/ChillMainBundle/Resources/public/lib/tabs/tabs.js
Normal file
118
src/Bundle/ChillMainBundle/Resources/public/lib/tabs/tabs.js
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Remove active class on both elements: link and content
|
||||
*/
|
||||
let resetActive = function(links, contents)
|
||||
{
|
||||
for (items of [links, contents]) {
|
||||
items.forEach(function(item) {
|
||||
if (item.classList.contains('active')) {
|
||||
item.classList.remove('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Count links array and return rank of given link
|
||||
*/
|
||||
let countNewActive = function(links, link)
|
||||
{
|
||||
let rank = 0;
|
||||
for (let i = 0; i < links.length; ++i) {
|
||||
rank++;
|
||||
if(links[i] == link) {
|
||||
return rank;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set class active on both new elements: link and content
|
||||
*/
|
||||
let setNewActive = function(links, contents, rank)
|
||||
{
|
||||
if (! links[rank-1]) { rank = 1; }
|
||||
link = links[rank-1];
|
||||
|
||||
link.classList.add('active');
|
||||
|
||||
count = 0;
|
||||
contents.forEach(function(pane) {
|
||||
count++;
|
||||
if (rank == count) {
|
||||
pane.classList.add('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Set height of content pane
|
||||
*/
|
||||
let setPaneHeight = function(contents)
|
||||
{
|
||||
contents.forEach(function(pane) {
|
||||
|
||||
// let computedStyle = getComputedStyle(pane);
|
||||
// console.log(computedStyle.height);
|
||||
// comment prendre la hauteur d'une div masquée avec display:none
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if links are defined in controller
|
||||
* If true, disable javascript listener
|
||||
*/
|
||||
let isLinkRef = function(link) {
|
||||
|
||||
if (link.getAttribute('href') == "#") {
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Main function
|
||||
*/
|
||||
window.addEventListener('load', function()
|
||||
{
|
||||
tabParams.forEach(function(unit) {
|
||||
|
||||
let tabPanel = document.querySelector('#'+ unit.id );
|
||||
if (tabPanel) {
|
||||
|
||||
let
|
||||
nav = tabPanel.querySelector('nav'),
|
||||
tabs = nav.querySelectorAll('ul.nav-tabs li.nav-item'),
|
||||
links = nav.querySelectorAll('ul.nav-tabs li.nav-item a.nav-link'),
|
||||
contents = tabPanel.querySelectorAll('div.tab-content div.tab-pane')
|
||||
;
|
||||
|
||||
if (unit.type == 'pill') {
|
||||
tabPanel.classList.add('pills');
|
||||
}
|
||||
|
||||
if (! unit.initPane) {
|
||||
unit.initPane = 1;
|
||||
}
|
||||
|
||||
setPaneHeight(contents);
|
||||
|
||||
// initial position
|
||||
setNewActive(links, contents, unit.initPane);
|
||||
|
||||
// listen
|
||||
links.forEach(function(link) {
|
||||
if (isLinkRef(link) == false) {
|
||||
link.addEventListener('click', function()
|
||||
{
|
||||
resetActive(links, contents);
|
||||
setNewActive(links, contents, countNewActive(links, link));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
});
|
@@ -0,0 +1,98 @@
|
||||
|
||||
$navigation-color: #334d5c;
|
||||
$body-font-color: #ffffff;
|
||||
$tab-font-color: #495057;
|
||||
$border-color: #dee2e6;
|
||||
$pills-color: #ed9345;
|
||||
$radius : .25rem;
|
||||
|
||||
div.tabs {
|
||||
margin: 3em;
|
||||
|
||||
nav {
|
||||
ul.nav-tabs {
|
||||
|
||||
display: flex;
|
||||
display: -ms-flexbox;
|
||||
flex-wrap: wrap;
|
||||
-ms-flex-wrap: wrap;
|
||||
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
margin-bottom: 0;
|
||||
|
||||
li.nav-item {
|
||||
margin-bottom: -1px;
|
||||
|
||||
a.nav-link {
|
||||
display: block;
|
||||
padding: .5rem 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
div.tab-content {
|
||||
|
||||
div.tab-pane {
|
||||
display: none;
|
||||
|
||||
&.fade {
|
||||
transition: opacity .15s linear;
|
||||
}
|
||||
&.active {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.pills) {
|
||||
nav {
|
||||
ul.nav-tabs {
|
||||
border-bottom: 1px solid $border-color;
|
||||
|
||||
li.nav-item {
|
||||
|
||||
a.nav-link {
|
||||
border: 1px solid transparent;
|
||||
border-top-left-radius: $radius;
|
||||
border-top-right-radius: $radius;
|
||||
color: $navigation-color;
|
||||
}
|
||||
|
||||
&.show a.nav-link,
|
||||
& a.nav-link.active {
|
||||
|
||||
color: $tab-font-color;
|
||||
background-color: $body-font-color;
|
||||
border-color: $border-color $border-color $body-font-color;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.pills {
|
||||
nav {
|
||||
ul.nav-tabs {
|
||||
|
||||
border-bottom: 0;
|
||||
li.nav-item {
|
||||
|
||||
& a.nav-link {
|
||||
border: 0;
|
||||
border-radius: $radius;
|
||||
}
|
||||
|
||||
&.show > a.nav-link,
|
||||
& a.nav-link.active {
|
||||
color: $body-font-color;
|
||||
background-color: $pills-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user