v5.4.1 Partage : correctif permissions + autocomplete membres (inclut v5.4.0 Interactions de bloc)
FlowDeck CI / test (push) Failing after 18s
FlowDeck CI / docker (push) Skipped

- Fix "Invalid permission" : le client envoyait editor/commenter/viewer alors que
  l'API attend view/comment/edit (invitePermission -> 'edit', menu participants aligné)
- PUT /api/pages/{page_id}/share/{share_id} : mise à jour de permission persistée
- Autocomplete des membres existants dans le champ d'invitation (search users + debounce,
  navigation clavier, envoi user_id pour lier le partage au compte)
- Upsert anti-doublon dans le partage + trim email backend
- 12 tests tests/test_sharing.py ; suite 319 verte (+3 PDF pre-existants)

Sans oublier v5.4.0 (non publie jusque-la) :
- Undo/Redo (Ctrl+Z/Ctrl+Shift+Z/Ctrl+Y), duplicate (Ctrl+D), menu de bloc (turn
  into, couleurs, lien #fdblk-, move to, delete), drag&drop multi-selection,
  slash "Actions", en-tetes de tableau (has_header/first_col_header) + exports,
  sync realtime immédiat apres mutation ; 9 tests test_block_interactions.py
This commit is contained in:
2026-09-08 09:34:41 -04:00
parent f84ff201ea
commit b3c90efa73
12 changed files with 1055 additions and 119 deletions
+100
View File
@@ -2277,6 +2277,78 @@ button.breadcrumb-current { max-width: 260px; }
cursor: grabbing;
}
/* ── v5.10.0: selection multiple + menu contexte bloc ── */
.block-wrapper.selected {
background: rgba(35,131,226,0.06);
box-shadow: inset 0 0 0 1px rgba(35,131,226,0.35);
}
.block-wrapper.selected .block-handle { opacity: 1; fill: var(--accent, #2383E2); }
.block-menu {
background: var(--bg-modal, #1b1b1b);
border: 1px solid var(--border-light, #333);
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0,0,0,.5);
padding: 6px;
min-width: 200px;
max-width: 260px;
}
.block-menu .bm-item {
display: flex;
align-items: center;
gap: 10px;
padding: 7px 9px;
font-size: 13px;
color: var(--text-primary);
border-radius: 6px;
cursor: pointer;
user-select: none;
}
.block-menu .bm-item:hover { background: var(--bg-hover); }
.block-menu .bm-item .bm-ico { width: 18px; text-align: center; color: var(--text-secondary); flex-shrink: 0; }
.block-menu .bm-item .bm-arrow { margin-left: auto; color: var(--text-tertiary); font-size: 11px; }
.block-menu .bm-item .bm-hint { margin-left: auto; font-size: 11px; color: var(--text-tertiary); font-family: var(--font-mono, monospace); opacity: .7; }
.block-menu .bm-item.bm-danger { color: #e5484d; }
.block-menu .bm-item.bm-danger .bm-ico { color: #e5484d; }
.block-menu .bm-item.bm-danger:hover { background: rgba(229,72,77,.12); }
.block-menu .bm-sep { height: 1px; background: var(--border, #2a2a2a); margin: 5px 4px; }
.block-menu .bm-colors { padding: 6px 9px; }
.block-menu .bm-colors-label { font-size: 10px; font-weight: 600; color: var(--text-tertiary); text-transform: uppercase; letter-spacing: .4px; margin-bottom: 6px; }
.block-menu .bm-swatches { display: flex; flex-wrap: wrap; gap: 6px; }
.block-menu .bm-swatch {
width: 20px; height: 20px; border-radius: 50%;
border: 1px solid var(--border-light, #333);
cursor: pointer; padding: 0; flex-shrink: 0;
}
.block-menu .bm-swatch:hover { border-color: var(--text-secondary); }
.block-menu .bm-swatch.bm-default { display:flex; align-items:center; justify-content:center; font-size:11px; color:var(--text-secondary); background: var(--bg-secondary); }
.block-menu .bm-page {
display: block; width: 100%; text-align: left; padding: 8px 10px;
font-size: 13px; color: var(--text-primary);
background: var(--bg-hover, transparent);
border: none; border-radius: 6px; cursor: pointer; margin-bottom: 4px;
}
.block-menu .bm-page:hover { background: var(--bg-secondary); }
.block-menu .bm-page-list { max-height: 240px; overflow-y: auto; margin: 8px 0; }
.block-menu .bm-empty { font-size: 12px; color: var(--text-tertiary); padding: 12px; line-height: 1.5; }
.block-menu .bm-search {
width: 100%; box-sizing: border-box; padding: 8px 10px; margin-bottom: 6px;
background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 6px;
color: var(--text-primary); font-size: 13px; outline: none;
}
.block-menu .bm-cancel {
width: 100%; text-align: center; padding: 7px; border: none; background: transparent;
color: var(--text-secondary); cursor: pointer; font-size: 12px; border-radius: 6px;
}
.block-menu .bm-cancel:hover { background: var(--bg-hover); }
.block-menu-sub { min-width: 180px; max-height: 320px; overflow-y: auto; }
.ftable-hdr-toggle { margin-left: 12px; font-size: 12px; color: var(--text-tertiary); display:inline-flex; align-items:center; gap:2px; }
.ftable-hdr-toggle label { display:inline-flex; align-items:center; gap:4px; cursor:pointer; }
.ftable-hdr-toggle input { cursor:pointer; }
/* Block actions (+ button) */
.block-actions {
position: absolute;
@@ -3153,6 +3225,34 @@ button.breadcrumb-current { max-width: 260px; }
.sd-btn-primary:hover { background: var(--accent-hover); }
.sd-btn-full { width: 100%; height: 46px; font-size: 14px; }
/* Invite wrap + existing users autocomplete */
.sd-invite-wrap { position: relative; margin-bottom: 12px; }
.sd-invite-wrap .sd-invite-row { margin-bottom: 0; }
.sd-user-suggest {
position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 999;
max-height: 220px; overflow-y: auto; padding: 4px;
background: var(--bg-modal); border: 1px solid var(--border);
border-radius: var(--radius-lg); box-shadow: var(--shadow-popover);
}
.sd-user-item {
display: flex; align-items: center; gap: 10px; padding: 7px 10px;
border-radius: var(--radius-md); cursor: pointer;
}
.sd-user-item:hover, .sd-user-item.active { background: var(--bg-hover); }
.sd-user-avatar {
width: 28px; height: 28px; border-radius: 50%; color: #fff; flex: none;
display: flex; align-items: center; justify-content: center;
font-size: 12px; font-weight: 700; overflow: hidden;
}
.sd-user-meta { min-width: 0; }
.sd-user-login { font-size: 13px; font-weight: 500; color: var(--text-primary); }
.sd-user-name {
font-size: 11px; color: var(--text-secondary);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sd-user-add { margin-left: auto; font-size: 11px; color: var(--accent); flex: none; }
.sd-user-empty { padding: 10px; font-size: 13px; color: var(--text-dim); }
/* Context card */
.sd-context-card {
background: var(--bg-secondary); border-radius: var(--radius-md);