Compare commits
No commits in common. "main" and "reorganisation" have entirely different histories.
main
...
reorganisa
16 changed files with 130 additions and 87 deletions
|
|
@ -8,22 +8,21 @@
|
|||
{{* config par défaut *}}
|
||||
{{:read file="./default.json" assign="config_defaut"}}
|
||||
{{:assign config_defaut=$config_defaut|json_decode}}
|
||||
|
||||
{{:assign var="directions.input" value="entrée"}}
|
||||
{{:assign var="directions.output" value="sortie"}}
|
||||
|
||||
{{#foreach from=$directions key="direction"}}
|
||||
{{* config par défaut *}}
|
||||
{{:assign var="nature_defaut" from="config_defaut.%ss"|args:$direction}}
|
||||
{{:assign keys_defaut=$nature_defaut|keys}}
|
||||
{{#foreach from=$nature_defaut item="elem"}}
|
||||
{{:assign var="config.%s_nature.%s"|args:$direction:$key value=$elem}}
|
||||
{{/foreach}}
|
||||
|
||||
{{* config enregistrée *}}
|
||||
{{:assign var="nature" from="module.config.%s_nature"|args:$direction}}
|
||||
{{#foreach from=$nature item="elem"}}
|
||||
{{if ! $elem.key|in:$keys_defaut}}
|
||||
{{if $nature != null}}
|
||||
{{#foreach from=$nature item="elem"}}
|
||||
{{:assign var="config.%s_nature.%s"|args:$direction:$key value=$elem}}
|
||||
{{/if}}
|
||||
{{/foreach}}
|
||||
{{/foreach}}
|
||||
{{else}}
|
||||
{{* pas de config enregistrée : utiliser la config par défaut *}}
|
||||
{{:assign var="nature" from="config_defaut.%ss"|args:$direction}}
|
||||
{{#foreach from=$nature item="elem"}}
|
||||
{{:assign var="config.%s_nature.%s"|args:$direction:$key value=$elem}}
|
||||
{{/foreach}}
|
||||
{{/if}}
|
||||
{{/foreach}}
|
||||
|
|
|
|||
|
|
@ -35,10 +35,8 @@
|
|||
{{else}}
|
||||
{{if $_GET.prop == -1}}
|
||||
{{:assign selected_prop=null}}
|
||||
{{elseif $_GET.prop == 1 || $_GET.prop == 0}}
|
||||
{{:assign selected_prop=$_GET.prop}}
|
||||
{{else}}
|
||||
{{:assign selected_prop=$user_filters.stock_prop}}
|
||||
{{:assign selected_prop=$_GET.prop}}
|
||||
{{/if}}
|
||||
{{:assign var="user_filters.stock_prop" value=$selected_prop}}
|
||||
{{:assign var="saved_filters.%s"|args:$logged_user.id value=$user_filters}}
|
||||
|
|
@ -124,11 +122,11 @@
|
|||
<td class="actions">
|
||||
{{:linkbutton
|
||||
label="Mouvements"
|
||||
href="equipment_history.html?key=%s&prop=%s"|args:$key:$selected_prop
|
||||
href="equipment_history.html?key=%s&prop=1"|args:$key
|
||||
shape="table"}}
|
||||
{{:linkbutton
|
||||
label="Modifier"
|
||||
href="modify_equipment.html?key=%s&prop=%s"|args:$key:$selected_prop
|
||||
href="modify_equipment.html?key=%s&prop=1"|args:$key
|
||||
shape="edit"
|
||||
target="_dialog"}}
|
||||
</td>
|
||||
|
|
|
|||
47
_nav.html
47
_nav.html
|
|
@ -3,7 +3,7 @@
|
|||
<nav class="tabs">
|
||||
{{if $current == 'inventaire'}}
|
||||
<aside>
|
||||
{{if $subcurrent != "mouvements"}}
|
||||
{{if $subcurrent == 'stock'}}
|
||||
{{if $cat == 0}}
|
||||
{{:linkbutton label="Ajouter une catégorie" shape="plus" href="categories/add_category.html" target="_dialog"}}
|
||||
{{else}}
|
||||
|
|
@ -17,16 +17,17 @@
|
|||
{{:linkbutton label="Entrée" shape="plus" href="movements/input_equipment.html?key=%s"|args:$key target="_dialog"}}
|
||||
{{/if}}
|
||||
</aside>
|
||||
{{elseif $current == 'archives'}}
|
||||
<aside>
|
||||
{{:exportmenu right=true}}
|
||||
</aside>
|
||||
{{elseif $current == 'config'}}
|
||||
{{if $subcurrent == "categories" || $subcurrent == "storage"}}
|
||||
<aside>
|
||||
{{:exportmenu right=true}}
|
||||
</aside>
|
||||
{{/if}}
|
||||
<aside>
|
||||
{{if $subcurrent == 'categories'}}
|
||||
{{:linkbutton label="Ajouter une catégorie" shape="plus" href="add_category.html" target="_dialog"}}
|
||||
{{elseif $subcurrent == 'storage'}}
|
||||
{{:linkbutton label="Ajouter un lieu de stockage" shape="plus" href="add_storage.html" target="_dialog"}}
|
||||
{{elseif $subcurrent == 'typesES'}}
|
||||
{{:linkbutton label="Ajouter un type d'entrée" shape="plus" href="config/add_movement_type.html?dir=input" target="_dialog"}}
|
||||
{{:linkbutton label="Ajouter un type de sortie" shape="plus" href="config/add_movement_type.html?dir=output" target="_dialog"}}
|
||||
{{/if}}
|
||||
</aside>
|
||||
{{/if}}
|
||||
|
||||
<ul>
|
||||
|
|
@ -48,40 +49,26 @@
|
|||
<ul class="sub">
|
||||
<li {{if $subcurrent == 'encours'}} class="current"{{/if}}><a href="{{$module.url}}loan_history.html?output_type=loan">En cours</a></li>
|
||||
<li {{if $subcurrent == 'historique'}} class="current"{{/if}}><a href="{{$module.url}}loan_movements.html?output_type=loan">Historique</a></li>
|
||||
<li {{if $subcurrent == 'membres'}} class="current"{{/if}}><a href="{{$module.url}}member_loan.html?output_type=loan">Membres</a></li>
|
||||
<li {{if $subcurrent == 'membres'}} class="current"{{/if}}><a href="{{$module.url}}member_loan.html?output_type=loan">Prêts en cours aux membres</a></li>
|
||||
</ul>
|
||||
{{elseif $current == 'location'}}
|
||||
<ul class="sub">
|
||||
<li {{if $subcurrent == 'encours'}} class="current"{{/if}}><a href="{{$module.url}}loan_history.html?output_type=rent">En cours</a></li>
|
||||
<li {{if $subcurrent == 'historique'}} class="current"{{/if}}><a href="{{$module.url}}loan_movements.html?output_type=rent">Historique</a></li>
|
||||
<li {{if $subcurrent == 'membres'}} class="current"{{/if}}><a href="{{$module.url}}member_loan.html?output_type=rent">Membres</a></li>
|
||||
<li {{if $subcurrent == 'membres'}} class="current"{{/if}}><a href="{{$module.url}}member_loan.html?output_type=rent">Locations en cours aux membres</a></li>
|
||||
</ul>
|
||||
{{elseif $current == 'archives'}}
|
||||
{{if $subcurrent == 'mouvements'}}
|
||||
<ul class="sub">
|
||||
<li class="title"><strong>Mouvements — {{$eqpmt}} ({{$category}})</strong></li>
|
||||
<li class="title"><strong>Historique — {{$eqpmt}} ({{$category}})</strong></li>
|
||||
</ul>
|
||||
{{/if}}
|
||||
{{elseif $current == 'config'}}
|
||||
{{if $subcurrent == 'categories'}}
|
||||
<aside>
|
||||
{{:linkbutton label="Ajouter une catégorie" shape="plus" href="add_category.html" target="_dialog"}}
|
||||
</aside>
|
||||
{{elseif $subcurrent == 'storage'}}
|
||||
<aside>
|
||||
{{:linkbutton label="Ajouter un lieu de stockage" shape="plus" href="add_storage.html" target="_dialog"}}
|
||||
</aside>
|
||||
{{elseif $subcurrent == 'typesES'}}
|
||||
<aside>
|
||||
{{:linkbutton label="Ajouter un type d'entrée" shape="plus" href="config/add_movement_type.html?dir=input" target="_dialog"}}
|
||||
{{:linkbutton label="Ajouter un type de sortie" shape="plus" href="config/add_movement_type.html?dir=output" target="_dialog"}}
|
||||
</aside>
|
||||
{{/if}}
|
||||
<ul class="sub">
|
||||
<li {{if $subcurrent == 'categories'}} class="current"{{/if}}><a href="{{$module.url}}categories/index.html">Catégories</a></li>
|
||||
<li {{if $subcurrent == 'storage'}} class="current"{{/if}}><a href="{{$module.url}}storage/index.html">Lieux de stockage</a></li>
|
||||
<li {{if $subcurrent == 'typesES'}} class="current"{{/if}}><a href="{{$module.url}}config.html">Types d'entrées/sorties</a></li>
|
||||
<li {{if $subcurrent == 'divers'}} class="current"{{/if}}><a href="{{$module.url}}config/misc.html">Divers</a></li>
|
||||
<li {{if $subcurrent == 'storage'}} class="current"{{/if}}><a href="{{$module.url}}storage/index.html">Lieux de stockage</a></li>
|
||||
<li {{if $subcurrent == 'typesES'}} class="current"{{/if}}><a href="{{$module.url}}config.html">Types d'entrées/sorties</a></li>
|
||||
<li {{if $subcurrent == 'divers'}} class="current"{{/if}}><a href="{{$module.url}}config/misc.html">Divers</a></li>
|
||||
</ul>
|
||||
{{/if}}
|
||||
</nav>
|
||||
|
|
|
|||
76
_temp_inventory.html
Normal file
76
_temp_inventory.html
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
{{* -*- brindille -*- *}}
|
||||
|
||||
{{*
|
||||
inventaire des entrées/sorties des matériels temporaires
|
||||
*}}
|
||||
|
||||
{{* Sélecteur catégories *}}
|
||||
{{:assign var="options." value="" label="Toutes les catégories" href="?prop=0"}}
|
||||
{{#load type="category" order="$$.name"}}
|
||||
{{:assign var="categories.%s"|args:$key value=$name}}
|
||||
{{:assign
|
||||
var="options."
|
||||
value=$key
|
||||
label=$name
|
||||
href="?cat_key=%s&prop=0"|args:$key
|
||||
}}
|
||||
{{/load}}
|
||||
|
||||
<fieldset class="shortFormRight">
|
||||
<legend>Filtrer par catégorie</legend>
|
||||
{{:dropdown
|
||||
title="Filtrer par catégorie"
|
||||
options=$options
|
||||
value="%s"|args:$_GET.cat_key
|
||||
}}
|
||||
</fieldset>
|
||||
|
||||
<div class="shortFormLeft">
|
||||
<p class="help">Inventaire des matériels empruntés ou loués</p>
|
||||
</div>
|
||||
|
||||
{{* filtrer selon la catégorie *}}
|
||||
{{if $_GET.cat_key == null}}
|
||||
{{:assign condition="1"}}
|
||||
{{else}}
|
||||
{{:assign cat_key=$_GET.cat_key|quote_sql}}
|
||||
{{:assign condition="$$.category = %s"|args:$cat_key}}
|
||||
{{/if}}
|
||||
|
||||
{{#list
|
||||
select="
|
||||
$$.name AS 'Matériel' ;
|
||||
(SELECT $$.name
|
||||
FROM @TABLE as cat
|
||||
WHERE cat.key = @TABLE.$$.category) AS 'Catégorie' ;
|
||||
$$.notowned AS 'Quantité'
|
||||
"
|
||||
type="equipment"
|
||||
where="$$.status <> 'archived' AND $$.notowned != 0 AND %s"|args:$condition
|
||||
order=1
|
||||
}}
|
||||
{{:assign var=cat_name from=categories.%s|args:$category}}
|
||||
<tr>
|
||||
<td>{{:link href="equipment_history.html?key=%s&prop=0"|args:$key" label=$name}}</td>
|
||||
<td>{{$cat_name}}</td>
|
||||
<td class="num">{{$col3}}</td>
|
||||
<td class="actions">
|
||||
{{:linkbutton
|
||||
label="Entrée"
|
||||
shape="plus"
|
||||
href="movements/input_equipment.html?key=%s"|args:$key
|
||||
target="_dialog"}}
|
||||
{{:linkbutton
|
||||
label="Historique"
|
||||
href="equipment_history.html?key=%s&prop=0"|args:$key
|
||||
shape="table"}}
|
||||
{{:linkbutton
|
||||
label="Modifier"
|
||||
href="modify_equipment.html?key=%s&prop=0"|args:$key
|
||||
shape="edit"
|
||||
target="_dialog"}}
|
||||
</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<p class="block alert">Aucun matériel.</p>
|
||||
{{/list}}
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
{{#foreach from=$directions key="direction" item="item"}}
|
||||
|
||||
{{* types de mouvements qui ne peuvent être supprimés *}}
|
||||
{{#load type="movement" where="$$.direction=:direction" :direction=$direction group="$$.operation"}}
|
||||
{{#load type="movement" where="$$.direction='%s'"|args:$direction group="$$.operation"}}
|
||||
{{:assign var="locked." value=$operation}}
|
||||
{{/load}}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
{{:assign equipment_key=$_GET.key|trim}}
|
||||
{{#load key=$equipment_key assign="equipment"}}
|
||||
{{else}}
|
||||
{{:error message="Aucun matériel avec la clé %s"|args:$equipment_key}}
|
||||
{{:error message="Pas de matériel avec la clé %s"|args:$equipment_key}}
|
||||
{{/load}}
|
||||
|
||||
{{#load type="category" where="key = :cle" :cle=$equipment.category assign="category"}}
|
||||
|
|
@ -26,7 +26,11 @@
|
|||
{{:admin_header title="Gestion des matériels" custom_css="./style.css" current="module_equipment"}}
|
||||
|
||||
{{* barre de navigation *}}
|
||||
{{:assign current=$_GET.current|or:"inventaire"}}
|
||||
{{if $_GET.current != null}}
|
||||
{{:assign current=$_GET.current}}
|
||||
{{else}}
|
||||
{{:assign current="inventaire"}}
|
||||
{{/if}}
|
||||
|
||||
{{* récupérer la config des entrées/sorties *}}
|
||||
{{:include file="./_get_config.html" keep="config"}}
|
||||
|
|
@ -40,10 +44,8 @@
|
|||
{{else}}
|
||||
{{if $_GET.prop == -1}}
|
||||
{{:assign selected_prop=null}}
|
||||
{{elseif $_GET.prop == 1 || $_GET.prop == 0}}
|
||||
{{:assign selected_prop=$_GET.prop}}
|
||||
{{else}}
|
||||
{{:assign selected_prop=$user_filters.eqpmt_hist_prop}}
|
||||
{{:assign selected_prop=$_GET.prop}}
|
||||
{{/if}}
|
||||
{{:assign var="user_filters.eqpmt_hist_prop value=$selected_prop}}
|
||||
{{:assign var="saved_filters.%s"|args:$logged_user.id value=$user_filters}}
|
||||
|
|
|
|||
|
|
@ -32,12 +32,11 @@
|
|||
|
||||
{{* condition de filtrage *}}
|
||||
{{if $selected_category != null}}
|
||||
{{:assign cat_key=$selected_category|quote_sql}}
|
||||
{{:assign cat_condition="(SELECT key
|
||||
FROM @TABLE AS cat
|
||||
WHERE cat.key = (SELECT $$.category
|
||||
FROM @TABLE AS mat
|
||||
WHERE mat.key = @TABLE.$$.equipment)) = %s"|args:$cat_key}}
|
||||
WHERE mat.key = @TABLE.$$.equipment)) = '%s'"|args:$selected_category}}
|
||||
{{else}}
|
||||
{{:assign cat_condition=1}}
|
||||
{{/if}}
|
||||
|
|
@ -48,10 +47,8 @@
|
|||
{{else}}
|
||||
{{if $_GET.prop == -1}}
|
||||
{{:assign selected_prop=null}}
|
||||
{{elseif $_GET.prop == 1 || $_GET.prop == 0}}
|
||||
{{:assign selected_prop=$_GET.prop}}
|
||||
{{else}}
|
||||
{{:assign selected_prop=$user_filters.hist_prop}}
|
||||
{{:assign selected_prop=$_GET.prop}}
|
||||
{{/if}}
|
||||
{{:assign var="user_filters.hist_prop" value=$selected_prop}}
|
||||
{{:assign var="saved_filters.%s"|args:$logged_user.id value=$user_filters}}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
{{#restrict block=true section="accounting" level="write"}}{{/restrict}}
|
||||
|
||||
{{#load type="category" count=true limit=1 assign="result"}}{{/load}}
|
||||
{{:include file="_nav.html" current="inventaire" cat="%d"|args:$result.count}}
|
||||
{{:include file="_nav.html" current="inventaire" cat="%d"|args:$result.count subcurrent="stock"}}
|
||||
|
||||
{{if $_GET.ok}}
|
||||
{{if $_GET.msg == "ajout" }}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,7 @@
|
|||
- id : id du membre
|
||||
*}}
|
||||
|
||||
{{if $_GET.id|intval !== $logged_user.id}}
|
||||
{{#restrict section="users" level="read" block=true}}{{/restrict}}
|
||||
{{/if}}
|
||||
{{#restrict}}{{/restrict}}
|
||||
|
||||
{{:admin_header title="Historique membre" custom_css="./style.css" current="module_equipment"}}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
name="Gestion des matériels"
|
||||
description="Permet de gérer un inventaire de matériels, ainsi que de suivre les prêts.\nversion 0.71.3"
|
||||
description="Permet de gérer un inventaire de matériels, ainsi que de suivre les prêts."
|
||||
author="Jean-Christophe Engel"
|
||||
author_url="https://gitea.zaclys.com/lesanges"
|
||||
home_button=true
|
||||
|
|
|
|||
|
|
@ -6,13 +6,9 @@
|
|||
Dupliquer un mouvement
|
||||
paramètres :
|
||||
- key : clé du mouvement à dupliquer
|
||||
- prop = 1 si matériel appartient à l'asso, 0 sinon
|
||||
- prop = 1 si matériel appartient à l'asso
|
||||
*}}
|
||||
|
||||
{{if $_GET.prop == null || $_GET.prop|intval != 0 && $_GET.prop|intval != 1}}
|
||||
{{:error message="Opération interdite"}}
|
||||
{{/if}}
|
||||
|
||||
{{* récupérer les infos du mouvement à dupliquer *}}
|
||||
{{#load key=$_GET.key assign="mvt_new"}}
|
||||
{{else}}
|
||||
|
|
@ -53,8 +49,8 @@
|
|||
{{if $mvt_new.direction == "input"}}
|
||||
{{* types d'entrées *}}
|
||||
{{#foreach from=$config.input_nature key=key}}
|
||||
{{if $_GET.prop|intval == 1 && $type == "définitif" ||
|
||||
$_GET.prop|intval == 0 && $type == "temporaire"
|
||||
{{if $_GET.prop && $type == "définitif" ||
|
||||
! $_GET.prop && $type == "temporaire"
|
||||
}}
|
||||
{{:assign var="input_labels.%s"|args:$key value=$label}}
|
||||
{{/if}}
|
||||
|
|
@ -62,7 +58,7 @@
|
|||
{{else}}
|
||||
{{* types de sorties *}}
|
||||
{{#foreach from=$config.output_nature key=key}}
|
||||
{{if $_GET.prop|intval == 1 && $type != "retour"}}
|
||||
{{if $_GET.prop && $type != "retour"}}
|
||||
{{:assign var="output_labels.%s"|args:$key value=$label}}
|
||||
{{/if}}
|
||||
{{/foreach}}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
|
||||
{{* récupérer les informations du matériel et de sa catégorie *}}
|
||||
{{#load key=$_GET.key assign="equipment"}}
|
||||
{{else}}
|
||||
{{:error message="Aucun matériel avec la clé « %s »"|args:$_GET.key}}
|
||||
{{/load}}
|
||||
{{#load where="key = :key" :key=$equipment.category assign="category"}}
|
||||
{{/load}}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
<dt>Matériel</dt>
|
||||
<dd>{{:link href="../equipment_history.html?key=%s&prop=%s"|args:$equipment.key:$_GET.prop label=$equipment.name}}</dd>
|
||||
<dt>Catégorie</dt>
|
||||
<dd>{{:link href="../index.html?cat_key=%s&prop=%s"|args:$category.key:$_GET.prop label=$category.name}}</dd>
|
||||
<dd>{{:link href="../index.html?cat_key=%s&prop=1"|args:$category.key label=$category.name}}</dd>
|
||||
<dt>Date</dt>
|
||||
<dd>{{$mvt.date|date_short}}</dd>
|
||||
<dt>Quantité</dt>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
{{*
|
||||
paramètres :
|
||||
- key : clé du matériel à sortir
|
||||
- output_type : (OBSOLÈTE ?) loan (prêt), rent (location), rien (cas général)
|
||||
- output_type : loan (prêt), rent (location), rien (cas général)
|
||||
*}}
|
||||
|
||||
{{* récupérer la config des entrées/sorties *}}
|
||||
|
|
@ -25,16 +25,11 @@
|
|||
{{:assign var="output_labels.%s"|args:$key value=$label}}
|
||||
{{elseif $type == 'temporaire' && $_GET.output_type == "rent" && $fee == 'payant'}}
|
||||
{{:assign var="output_labels.%s"|args:$key value=$label}}
|
||||
{{else}}
|
||||
{{:error message="Opération interdite"}}
|
||||
{{/if}}
|
||||
{{/foreach}}
|
||||
|
||||
{{* récupérer les infos du matériel *}}
|
||||
{{#load key=$_GET.key assign="equipment"}}
|
||||
{{else}}
|
||||
{{:error message="Aucun matériel avec la clé %s"|args:$_GET.key}}
|
||||
{{/load}}
|
||||
{{#load key=$_GET.key assign="equipment"}}{{/load}}
|
||||
|
||||
{{* Traiter l'envoi du formulaire *}}
|
||||
{{#form on="save"}}
|
||||
|
|
@ -77,7 +72,7 @@
|
|||
{{:assign insere=false}}
|
||||
|
||||
{{* lister tous les mouvements du matériel *}}
|
||||
{{#load type="movement" where="$$.equipment = :eqpmt_key" :eqpmt_key=$_GET.key assign="mvt" order="$$.date ASC"}}
|
||||
{{#load type="movement" where="$$.equipment = '%s'"|args:$_GET.key assign="mvt" order="$$.date ASC"}}
|
||||
{{* traiter le nouveau mouvement *}}
|
||||
{{if ! $insere && $mvt.date > $_POST.date|parse_date}}
|
||||
{{:assign insere=true}}
|
||||
|
|
|
|||
|
|
@ -22,10 +22,7 @@
|
|||
{{:admin_header title="Lieux de stockage" custom_css="../style.css" current="module_equipment"}}
|
||||
{{:form_errors}}
|
||||
|
||||
{{#load key=$_GET.key limit="1" assign="store"}}
|
||||
{{else}}
|
||||
{{:error message="Ce lieu de stockage n'existe pas !"}}
|
||||
{{/load}}
|
||||
{{#load key=$_GET.key limit="1" assign="store"}}{{/load}}
|
||||
{{:delete_form
|
||||
legend="Supprimer %s ?"|args:$store.name
|
||||
warning="Confirmer la suppression de « %s »"|args:$store.name
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
{{* récupérer les infos du lieu de stockage *}}
|
||||
{{#load key=$_GET.key assign="storage"}}
|
||||
{{else}}
|
||||
{{:error message="Ce lieu de stockage n'existe pas"}}
|
||||
{{:error message="Lieu de stockage introuvable"}}
|
||||
{{/load}}
|
||||
|
||||
{{* Traiter l'envoi du formulaire *}}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue