mirror of
https://github.com/ae-utbm/sith.git
synced 2025-07-09 19:40:19 +00:00
Graph de famille en frontend (#820)
* Remove graphviz and use cytoscape.js instead * Frontend generated graphs * Make installation easier and faster * Better user experience * Family api and improved interface * Fix url history when using 0, improve button selection and reset reverse with reset button * Use klay layout * Add js translations and apply review comments
This commit is contained in:
committed by
GitHub
parent
bf96d8a10c
commit
f624b7c66d
@ -112,7 +112,7 @@
|
||||
|
||||
{% macro delete_godfather(user, profile, godfather, is_father) %}
|
||||
{% if user == profile or user.is_root or user.is_board_member %}
|
||||
<a href="{{ url("core:user_godfathers_delete", user_id=profile.id, godfather_id=godfather.id, is_father=is_father) }}">{% trans %}Delete{% endtrans %}</a>
|
||||
<a class="delete" href="{{ url("core:user_godfathers_delete", user_id=profile.id, godfather_id=godfather.id, is_father=is_father) }}">{% trans %}Delete{% endtrans %}</a>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
|
@ -11,14 +11,20 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<a href="{{ url('core:user_godfathers_tree_pict', user_id=profile.id) }}?family">
|
||||
{% trans %}Show family picture{% endtrans %}
|
||||
</a>
|
||||
{% if godchildren or godfathers %}
|
||||
<a
|
||||
href="{{ url('core:user_godfathers_tree', user_id=profile.id) }}"
|
||||
class="btn btn-blue"
|
||||
id="family-tree-link"
|
||||
>
|
||||
{% trans %}Show family tree{% endtrans %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<h4>{% trans %}Godfathers / Godmothers{% endtrans %}</h4>
|
||||
{% if profile.godfathers.exists() %}
|
||||
{% if godfathers %}
|
||||
<ul class="users">
|
||||
{% for u in profile.godfathers.all() %}
|
||||
{% for u in godfathers %}
|
||||
<li class="users-card">
|
||||
<a href="{{ url('core:user_godfathers', user_id=u.id) }}" class="mini_profile_link">
|
||||
{{ u.get_mini_item() | safe }}
|
||||
@ -28,17 +34,14 @@
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<a href="{{ url('core:user_godfathers_tree', user_id=profile.id) }}">
|
||||
{% trans %}Show ancestors tree{% endtrans %}
|
||||
</a>
|
||||
{% else %}
|
||||
<p>{% trans %}No godfathers / godmothers{% endtrans %}
|
||||
{% endif %}
|
||||
|
||||
<h4>{% trans %}Godchildren{% endtrans %}</h4>
|
||||
{% if profile.godchildren.exists() %}
|
||||
{% if godchildren %}
|
||||
<ul class="users">
|
||||
{% for u in profile.godchildren.all() %}
|
||||
{% for u in godchildren %}
|
||||
<li class="users-card">
|
||||
<a href="{{ url('core:user_godfathers', user_id=u.id) }}" class="mini_profile_link">
|
||||
{{ u.get_mini_item()|safe }}
|
||||
@ -47,10 +50,6 @@
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<a href="{{ url('core:user_godfathers_tree', user_id=profile.id) }}?descent">
|
||||
{% trans %}Show descent tree{% endtrans %}
|
||||
</a>
|
||||
{% else %}
|
||||
<p>{% trans %}No godchildren{% endtrans %}
|
||||
{% endif %}
|
||||
|
@ -1,54 +1,105 @@
|
||||
{% extends "core/base.jinja" %}
|
||||
{% set depth_min=0 %}
|
||||
{% set depth_max=10 %}
|
||||
|
||||
{%- block additional_css -%}
|
||||
<link rel="stylesheet" href="{{ scss('user/user_godfathers.scss') }}">
|
||||
{%- endblock -%}
|
||||
|
||||
{% block additional_js %}
|
||||
<script src="{{ static("vendored/cytoscape/cytoscape.min.js") }}" defer></script>
|
||||
<script src="{{ static("vendored/cytoscape/cytoscape-cxtmenu.min.js") }}" defer></script>
|
||||
|
||||
<script src="{{ static("vendored/cytoscape/klay.min.js") }}" defer></script>
|
||||
<script src="{{ static("vendored/cytoscape/cytoscape-klay.min.js") }}" defer></script>
|
||||
|
||||
<script src="{{ static("user/js/family_graph.js") }}" defer></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
{% if param == "godchildren" %}
|
||||
{% trans user_name=profile.get_display_name() %}{{ user_name }}'s godchildren{% endtrans %}
|
||||
{% else %}
|
||||
{% trans user_name=profile.get_display_name() %}{{ user_name }}'s godfathers{% endtrans %}
|
||||
{% endif %}
|
||||
{% trans user_name=profile.get_display_name() %}{{ user_name }}'s family tree{% endtrans %}
|
||||
{% endblock %}
|
||||
|
||||
{% macro display_members_list(user) %}
|
||||
{% if user.__getattribute__(param).exists() %}
|
||||
<ul>
|
||||
{% for u in user.__getattribute__(param).all() %}
|
||||
<li>
|
||||
<a href="{{ url("core:user_godfathers", user_id=u.id) }}">
|
||||
{{ u.get_short_name() }}
|
||||
</a>
|
||||
{% if u in members_set %}
|
||||
{% trans %}Already seen (check above){% endtrans %}
|
||||
{% else %}
|
||||
{{ members_set.add(u) or "" }}
|
||||
{{ display_members_list(u) }}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block content %}
|
||||
<p><a href="{{ url("core:user_godfathers", user_id=profile.id) }}">
|
||||
{% trans %}Back to family{% endtrans %}</a></p>
|
||||
{% if profile.__getattribute__(param).exists() %}
|
||||
{% if param == "godchildren" %}
|
||||
<p><a href="{{ url("core:user_godfathers_tree_pict", user_id=profile.id) }}?descent">
|
||||
{% trans %}Show a picture of the tree{% endtrans %}</a></p>
|
||||
<h4>{% trans u=profile.get_short_name() %}Descent tree of {{ u }}{% endtrans %}</h4>
|
||||
{% else %}
|
||||
<p><a href="{{ url("core:user_godfathers_tree_pict", user_id=profile.id) }}?ancestors">
|
||||
{% trans %}Show a picture of the tree{% endtrans %}</a></p>
|
||||
<h4>{% trans u=profile.get_short_name() %}Ancestors tree of {{ u }}{% endtrans %}</h4>
|
||||
{% endif %}
|
||||
{{ members_set.add(profile) or "" }}
|
||||
{{ display_members_list(profile) }}
|
||||
{% else %}
|
||||
{% if param == "godchildren" %}
|
||||
<p>{% trans %}No godchildren{% endtrans %}
|
||||
{% else %}
|
||||
<p>{% trans %}No godfathers / godmothers{% endtrans %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<div x-data="graph" :aria-busy="loading">
|
||||
<div class="graph-toolbar">
|
||||
<div class="toolbar-column">
|
||||
<div class="toolbar-input">
|
||||
<label for="godfather-depth-input">
|
||||
{% trans min=depth_min, max=depth_max %}Max godfather depth between {{ min }} and {{ max }}{% endtrans %}
|
||||
</label>
|
||||
<span class="depth-choice">
|
||||
<button
|
||||
@click="godfathers_depth--"
|
||||
:disabled="godfathers_depth <= {{ depth_min }}"
|
||||
><i class="fa fa-minus fa-xs"></i></button>
|
||||
<input
|
||||
x-model="godfathers_depth"
|
||||
x-ref="godfather_depth_input"
|
||||
type="number"
|
||||
name="godfathers_depth"
|
||||
id="godfather-depth-input"
|
||||
min="{{ depth_min }}"
|
||||
max="{{ depth_max }}"
|
||||
/>
|
||||
<button
|
||||
@click="godfathers_depth++"
|
||||
:disabled="godfathers_depth >= {{ depth_max }}"
|
||||
><i class="fa fa-plus"
|
||||
></i></button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-input">
|
||||
<label for="godchild-depth-input">
|
||||
{% trans min=depth_min, max=depth_max %}Max godchildren depth between {{ min }} and {{ max }}{% endtrans %}
|
||||
</label>
|
||||
<span class="depth-choice">
|
||||
<button
|
||||
@click="godchildren_depth--"
|
||||
:disabled="godchildren_depth <= {{ depth_min }}"
|
||||
><i
|
||||
class="fa fa-minus fa-xs"
|
||||
></i></button>
|
||||
<input
|
||||
x-model="godchildren_depth"
|
||||
type="number"
|
||||
name="godchildren_depth"
|
||||
id="godchild-depth-input"
|
||||
min="{{ depth_min }}"
|
||||
max="{{ depth_max }}"
|
||||
/>
|
||||
<button
|
||||
@click="godchildren_depth++"
|
||||
:disabled="godchildren_depth >= {{ depth_max }}"
|
||||
><i class="fa fa-plus"
|
||||
></i></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-column">
|
||||
<div class="toolbar-input">
|
||||
<label for="reverse-checkbox">{% trans %}Reverse{% endtrans %}</label>
|
||||
<input x-model="reverse" type="checkbox" name="reverse" id="reverse-checkbox">
|
||||
</div>
|
||||
<button class="btn btn-grey" @click="reset">
|
||||
{% trans %}Reset{% endtrans %}
|
||||
</button>
|
||||
<button class="btn btn-grey" @click="screenshot">
|
||||
<i class="fa fa-camera"></i>
|
||||
{% trans %}Save{% endtrans %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div x-ref="graph" class="graph"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const api_url = "{{ api_url }}";
|
||||
const active_user = "{{ object.id }}"
|
||||
const depth_min = {{ depth_min }};
|
||||
const depth_max = {{ depth_max }};
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
|
Reference in New Issue
Block a user