Prompt utilisé pour régénérer cette page :
Page "Laboratory Server" du toolbox de web-cylian-org.
Catégorie : Toolbox — interface de gestion de base de données connectée
Ă l'API REST api.cylian.org.
=== FRONT MATTER (index.md) ===
title: "Laboratory Server"
description: "Server management tools"
icon: "database"
tags: [database, documents, api]
features:
- Browse collections
- CRUD documents
- Permission-based access
=== WIDGET LEFT (_collections.left.md) ===
Front matter : title "Collections", weight 10.
Contenu HTML + script inline ES module :
<div id="collections-widget">
<h5>Collections</h5>
<div id="collections-loading">Loading...</div>
<ul id="collections-list"></ul>
<div id="collections-empty" class="hidden"></div>
</div>
<script type="module"> :
- Import db depuis /_lib/database_v1.js
- Constantes : API_URL = 'https://api.cylian.org', NAMESPACE = 'database'
- Connexion : _db = db.connect(API_URL, { namespace: NAMESPACE })
- loadCollections() : appelle _db.collections(), cache loading,
si échec → affiche erreur dans empty, si vide → "No collections",
sinon → crée des <li><a data-collection="name"> cliquables
- Click handler : appelle window.loadCollection(a.dataset.collection)
=== WIDGET LEFT (_permissions.left.md) ===
Front matter : title "Permissions", weight 20.
Contenu HTML + script inline ES module :
<div id="permissions-widget">
<h5>Auth</h5>
<ul id="auth-info"></ul>
<h5 id="permissions-namespace">database</h5>
<ul id="permissions-list"></ul>
</div>
<script type="module"> :
- Import db depuis /_lib/database_v1.js
- Import auth depuis /_lib/auth_v1.js
- MĂŞmes constantes API_URL et NAMESPACE
- loadAuth() : si auth.isSignedIn() → affiche user.email et user.role,
sinon "Not signed in"
- loadPermissions() : appelle _db.collections(), lit result.permissions,
affiche chaque paire clé/valeur en <li><strong>key</strong>: value
=== CONTENU HTML (index.md) ===
<div id="db-container"> :
1. Toolbar (div#db-toolbar class="hidden") :
- <button id="btn-create" class="button color-success">New Document</button>
- <button id="btn-refresh" class="button">Refresh</button>
- <span id="doc-count" class="badge"></span>
2. Content (div#db-content) :
- <div id="db-loading" class="hidden">Loading...</div>
- <div id="db-empty" class="hidden">No documents found.</div>
- <div id="db-list"></div>
3. Dialog (<dialog id="doc-dialog">) :
- <form method="dialog"> avec :
<h3 id="dialog-title">Document</h3>
div.form-group : label "ID" + input#doc-id (readonly)
div.form-group : label "Data (JSON)" + textarea#doc-data (rows=10)
div.dialog-actions :
<button id="btn-save" class="button color-primary">Save</button>
<button id="btn-delete" class="button color-danger">Delete</button>
<button type="submit" class="button">Close</button>
=== JAVASCRIPT (default.js) ===
ES module. Import db depuis /_lib/database_v1.js.
Constantes : API_URL = 'https://api.cylian.org', NAMESPACE = 'database'.
Connexion : _db = db.connect(API_URL, { namespace: NAMESPACE }).
État : currentCollection = '' (string), documents = [] (array).
init() :
- Récupère btn-create, btn-refresh, btn-save, btn-delete
- Event listeners : create → openDialog(null), refresh → loadDocuments,
save → saveDocument, delete → deleteDocument
- Expose window.loadCollection
loadCollection(name) : set currentCollection, appelle loadDocuments().
loadDocuments() :
- Affiche toolbar, loading ; cache empty, vide list
- Appelle _db.list(currentCollection)
- Cache loading, gère les erreurs
- Met Ă jour doc-count badge : "count / total"
- Crée div.doc-item pour chaque document avec :
div.doc-id (doc.id), div.doc-owner (doc.owner || '-'),
div.doc-date (new Date(doc.updated_at).toLocaleString())
- Click sur un item → openDialog(doc)
openDialog(doc) :
- Si doc : mode édition — titre "Edit Document", remplit id et data (JSON.stringify
avec indent 2), montre btn-delete
- Si null : mode création — titre "New Document", id "(auto)",
data "{\n \n}", cache btn-delete
- dialog.showModal()
saveDocument() :
- Parse JSON de textarea (try/catch → alert "Invalid JSON")
- Si isNew (id === "(auto)") → _db.create(collection, data)
- Sinon → _db.update(collection, id, data)
- Vérifie result.success, ferme dialog, recharge documents
deleteDocument() :
- Confirm dialog "Delete this document?"
- _db.delete(collection, id)
- Vérifie result.success, ferme dialog, recharge documents
createTestData() (exposée sur window) :
- Vérifie currentCollection existe, confirm "Create 5 test documents?"
- Crée 5 objets : Alpha/Beta/Gamma/Delta/Epsilon avec champs
name, status (active/pending/inactive), priority (1-5),
tags (combinaisons de test/sample/demo)
- Boucle _db.create pour chaque, recharge documents
Init : DOMContentLoaded → init().
=== SCSS (default.scss) ===
#db-container : flex column gap 1rem
#db-nav : flex gap 1rem, flex-wrap, selectors avec label+select min-width 150px
#db-toolbar : flex gap 0.5rem, .badge margin-left auto
#db-content : min-height 200px
#db-list : flex column gap 0.25rem
.doc-item : grid 3 colonnes (1fr 150px 180px), gap 1rem, padding,
background secondary, border-radius 4px, cursor pointer,
hover background tertiary
.doc-id monospace 0.875rem, .doc-owner opacity 0.7, .doc-date right 0.75rem
#doc-dialog : min-width 500px, max-width 90vw
form flex column gap 1rem
.form-group flex column gap 0.25rem, textarea monospace resize vertical
.dialog-actions flex gap 0.5rem justify-content flex-end
.hidden : display none !important
#collections-widget : #collections-list list-style none, a monospace 0.875rem
#permissions-widget : #permissions-list list-style none, strong monospace
=== OBJECTIF ===
Interface CRUD complète pour gérer des documents JSON dans une base de données
via l'API api.cylian.org. Deux widgets latéraux : un navigateur de collections
et un panneau d'authentification/permissions. La page principale affiche la
liste des documents avec id/owner/date, permet la création/édition/suppression
via un dialog modal, et inclut une fonction de génération de données de test.
Communication inter-composants via window globals (loadCollection, createTestData).
Page entièrement générée et maintenue par IA, sans intervention humaine.