v5.5.0 Partage v2 : fenêtre Share rechargée, sidebar « Par moi »/« Avec moi », Library dir=made/received, badge 👥 + indicateurs
FlowDeck CI / test (push) Failing after 18s
FlowDeck CI / docker (push) Skipped

- Correctif : la fenêtre Share rechargait ses partages à chaque ouverture (before: liste vide après refresh)
- Sidebar « Shared » scindée en sous-groupes « Par moi » (partages nominatifs + liens) et « Avec moi » (partages reçus), sans doublons
- Bibliothèque : filtre « Tous / Par moi / Avec moi » sur l'onglet Shared ; /api/library/shared?dir=made|received|all + share_dir par élément
- Document : bouton barre affiche « 👥 Shared ▾ » quand la page est partagée (membre, lien ou publiée), recalculé à la volée
- Workspace local : emoji 👥 juste avant le nom des fichiers partagés (is_shared exposé par /api/local-workspace/tree)
- Tests +6 (tests/test_sharing.py) : direction made/received/all, fallback dir invalide, rendu pageIsShared ; suite 325 verte (+3 PDF pré-existants)
This commit is contained in:
2026-09-08 11:52:29 -04:00
parent b3c90efa73
commit 0112a5b5d8
15 changed files with 286 additions and 36 deletions
+90 -1
View File
@@ -199,4 +199,93 @@ def test_remove_share_unsets_is_shared(client):
with get_conn() as conn:
is_shared = conn.execute("SELECT is_shared FROM pages WHERE id=?", (pid,)).fetchone()["is_shared"]
assert is_shared == 0
assert is_shared == 0
# ── Library : direction des partages (dir=made|received|all) ──
def _make_page_with(conn, title, share_mode="private", published=0):
cur = conn.execute(
"INSERT INTO pages (workspace, title, content, content_format, parent_section, share_mode, published) "
"VALUES ('Private', ?, '[]', 'blocks', 'Private', ?, ?)",
(title, share_mode, published),
)
conn.commit()
return cur.lastrowid
def test_library_shared_dir_made_includes_nominal_and_link(client):
_auth(client, user_id=1, login="owner")
with get_conn_ctx() as conn:
a = _make_page_with(conn, "Shared A")
b = _make_page_with(conn, "Link B", share_mode="anyone")
_make_page_with(conn, "Private C")
r = client.post(f"/api/pages/{a}/share", json={"user_id": 2, "permission": "edit"})
assert r.status_code == 200
made = client.get("/api/library/shared?dir=made").json()["items"]
ids = [it["id"] for it in made]
assert a in ids, "page shared to a user should appear in made"
assert b in ids, "link-mode page should appear in made"
assert all(it["share_dir"] == "made" for it in made if it["id"] in (a, b))
def test_library_shared_dir_received(client):
_auth(client, user_id=1, login="owner")
with get_conn_ctx() as conn:
a = _make_page_with(conn, "Received A")
r = client.post(f"/api/pages/{a}/share", json={"user_id": 2, "permission": "view"})
assert r.status_code == 200
_auth(client, user_id=2, login="alice")
recv = client.get("/api/library/shared?dir=received").json()["items"]
ids = [it["id"] for it in recv]
assert a in ids
item = next(it for it in recv if it["id"] == a)
assert item["share_dir"] == "received"
def test_library_shared_dir_all_is_union(client):
_auth(client, user_id=1, login="owner")
with get_conn_ctx() as conn:
a = _make_page_with(conn, "Union A")
client.post(f"/api/pages/{a}/share", json={"user_id": 2, "permission": "comment"})
_auth(client, user_id=2, login="alice")
all_items = client.get("/api/library/shared").json()["items"]
ids = [it["id"] for it in all_items]
assert a in ids
def test_library_shared_invalid_dir_falls_back_to_all(client):
_auth(client, user_id=1, login="owner")
with get_conn_ctx() as conn:
a = _make_page_with(conn, "Fallback A", share_mode="anyone")
r = client.get("/api/library/shared?dir=bogus")
assert r.status_code == 200
assert a in [it["id"] for it in r.json()["items"]]
def test_library_shared_received_none(client):
_auth(client, user_id=2, login="alice")
r = client.get("/api/library/shared?dir=received")
assert r.status_code == 200
assert r.json()["items"] == []
def test_page_editor_renders_page_is_shared(client):
_auth(client, user_id=1, login="owner")
with get_conn_ctx() as conn:
a = _make_page_with(conn, "Marked A")
client.post(f"/api/pages/{a}/share", json={"user_id": 2, "permission": "view"})
r = client.get(f"/pages/{a}")
assert r.status_code == 200
assert "pageIsShared:true" in r.text
def get_conn_ctx():
from app.db import get_conn
return get_conn()