Add a demo mode

This commit is contained in:
Alexis Métaireau 2020-11-26 22:27:25 +01:00
parent ff58fe9d0d
commit b60a9abb84
8 changed files with 103 additions and 8 deletions

View file

@ -77,11 +77,39 @@ class Base:
@dataclass @dataclass
class PersistedBase(Base): class PersistedBase(Base):
@classmethod @classmethod
def get_root(cls): def get_root(cls):
return Path(config.DATA_ROOT) / cls.__root__ root = Path(config.DATA_ROOT)
if getattr(config, 'DEMO_MODE', False):
root = root / "demo"
return root / cls.__root__
@dataclass
class SavedConfiguration(PersistedBase):
__lock__ = threading.Lock()
demo_mode_enabled: bool = False
@classmethod
def get_path(cls):
return Path(config.DATA_ROOT) / "config.yml"
def persist(self):
with self.__lock__:
self.get_path().write_text(self.dump())
@classmethod
def load(cls):
path = cls.get_path()
if path.exists():
data = yaml.safe_load(path.read_text())
data = {k: v for k, v in data.items() if k in cls.__dataclass_fields__}
else:
data = {}
return cls(**data)
@dataclass @dataclass
class Person(Base): class Person(Base):
email: str email: str
@ -133,6 +161,12 @@ class Groups(PersistedBase):
data = {"groups": {}} data = {"groups": {}}
groups = cls(**data) groups = cls(**data)
return groups return groups
@classmethod
def is_defined(cls):
groups = cls.load()
return len(groups.groups) > 0
def persist(self): def persist(self):
with self.__lock__: with self.__lock__:
@ -384,6 +418,10 @@ class Delivery(PersistedBase):
for path in root.glob("*.yml"): for path in root.glob("*.yml"):
id_ = str(path.relative_to(cls.get_root())).replace(".yml", "") id_ = str(path.relative_to(cls.get_root())).replace(".yml", "")
yield Delivery.load(id_) yield Delivery.load(id_)
@classmethod
def is_defined(cls):
return len(list(cls.all())) > 0
@classmethod @classmethod
def incoming(cls): def incoming(cls):

View file

@ -720,3 +720,12 @@ ul.actions > li {
small { small {
font-size: 70% !important; font-size: 70% !important;
} }
.demo-mode {
background: var(--warning-color);
padding: 0em !important;
}
.header {
padding-bottom: 2em !important;
}

View file

@ -18,6 +18,13 @@
</head> </head>
<body> <body>
{% if config.DEMO_MODE %}
<div class="header">
<div class="home-menu pure-menu pure-menu-horizontal pure-menu-fixed demo-mode">
<p class="pure-menu-heading">Le site est en mode démo. <a href="{{ url_for('desactivate_demo') }}">désactiver</a></p>
</div>
</div>
{% endif %}
<div id="layout"> <div id="layout">
<a href="#menu" id="menuLink" class="menu-link"> <a href="#menu" id="menuLink" class="menu-link">

View file

@ -4,7 +4,6 @@
<div class="header"> <div class="header">
<h1>Distributions</h1> <h1>Distributions</h1>
</div> </div>
{% with deliveries=incoming %} {% with deliveries=incoming %}
{% include "includes/delivery_list.html" %} {% include "includes/delivery_list.html" %}
{% endwith %} {% endwith %}

View file

@ -0,0 +1,12 @@
{% extends "base.html" %}
{% block body %}
<h1>Bienvenue sur copanier</h1>
<p>On dirait que vous venez de lancer ce logiciel pour la première fois, bienvenue ici 😀.</p>
<p>Pour commencer, deux options :</p>
<ul>
<li><a href=" {{ url_for('activate_demo') }}">Activer le mode de démonstration</a>, cela va charger des données de démonstration pour que vous puissiez aller jeter un coup d'oeil au fonctionnement du logiciel ;</li>
<li>Ou alors si vous avez envie de commencer à utiliser le logiciel, vous devez commencer par <a href="{{ url_for('groups') }}">rejoindre un groupe</a> et commencer une distribution.</p></li>
</ul>
<p>Bon voyage 🙏 !</p>
{% endblock body %}

View file

@ -5,7 +5,7 @@ from roll import HttpError
from debts.solver import order_balance, check_balance, reduce_balance from debts.solver import order_balance, check_balance, reduce_balance
from .core import app, staff_only, session, env from .core import app, staff_only, session, env
from ..models import Delivery, Person, Order, ProductOrder from ..models import Delivery, Person, Order, ProductOrder, Groups, SavedConfiguration
from .. import utils, reports, emails, config from .. import utils, reports, emails, config
@ -16,8 +16,11 @@ async def on_startup():
@app.route("/", methods=["GET"]) @app.route("/", methods=["GET"])
async def home(request, response): async def home(request, response):
if not Delivery.is_defined() and not Groups.is_defined():
response.redirect = url_for("onboarding")
return
if not request["user"].group_id: if not request["user"].group_id:
response.redirect = "/groupes" response.redirect = url_for("groups")
return return
response.html( response.html(
"delivery/list_deliveries.html", "delivery/list_deliveries.html",

View file

@ -1,6 +1,6 @@
from .core import app, session, env, url from .core import app, session, env, url
from ..models import Groups, Person from ..models import Groups, Person, SavedConfiguration
from .. import utils, emails, config from .. import utils, emails, config
@ -11,6 +11,13 @@ async def auth_required(request, response):
# route as unprotected. # route as unprotected.
if request.path.startswith("/static/"): if request.path.startswith("/static/"):
return return
saved_config = SavedConfiguration.load()
if saved_config.demo_mode_enabled:
setattr(config, 'DEMO_MODE', True)
else:
setattr(config, 'DEMO_MODE', False)
if request.route.payload and not request.route.payload.get("unprotected"): if request.route.payload and not request.route.payload.get("unprotected"):
token = request.cookies.get("token") token = request.cookies.get("token")
email = None email = None
@ -83,3 +90,23 @@ async def set_sesame(request, response, token):
async def logout(request, response): async def logout(request, response):
response.cookies.set(name="token", value="", httponly=True) response.cookies.set(name="token", value="", httponly=True)
response.redirect = "/" response.redirect = "/"
@app.route("/premier-lancement", methods=["GET"])
async def onboarding(request, response):
response.html("onboarding.html")
@app.route("/premier-lancement/demo", methods=["GET"])
async def activate_demo(request, response):
saved_config = SavedConfiguration.load()
saved_config.demo_mode_enabled = True
saved_config.persist()
response.redirect = "/"
@app.route("/premier-lancement/demo/désactiver", methods=["GET"])
async def desactivate_demo(request, response):
saved_config = SavedConfiguration.load()
saved_config.demo_mode_enabled = False
saved_config.persist()
response.redirect = "/"

View file

@ -165,9 +165,9 @@ def test_productorder_quantity():
def test_group_management(): def test_group_management():
ndp = Group( ndp = Group(
id="nid-de-poules", name="Nid de poules", members=["someone@domain.tld"] id="passage-creuse", name="Nid de poules", members=["someone@domain.tld"]
) )
assert ndp.id == "nid-de-poules" assert ndp.id == "passage-creuse"
assert ndp.name == "Nid de poules" assert ndp.name == "Nid de poules"
assert len(ndp.members) == 1 assert len(ndp.members) == 1
groups = Groups.load() groups = Groups.load()
@ -177,7 +177,7 @@ def test_group_management():
groups.add_user("simon@tld", ndp.id) groups.add_user("simon@tld", ndp.id)
assert "simon@tld" in groups.groups[ndp.id].members assert "simon@tld" in groups.groups[ndp.id].members
ladouce = Group(id="la-douce", name="La douce", members=[]) ladouce = Group(id="la-lointaine", name="La douce", members=[])
groups.add_group(ladouce) groups.add_group(ladouce)
groups.add_user("simon@tld", ladouce.id) groups.add_user("simon@tld", ladouce.id)
assert "simon@tld" in groups.groups[ladouce.id].members assert "simon@tld" in groups.groups[ladouce.id].members