feat(member): let members tailor overview density and visible columns
The View dropdown drives row density and whether the Member and Address fields render as composite cells or split into their underlying columns; the column manager toggles visibility and resets to the curated default. All choices persist per browser through the URL/session/cookie/global chain, so a saved layout survives reloads without a per-account store.
This commit is contained in:
parent
af2cc2e0d4
commit
dfc616257d
21 changed files with 1643 additions and 263 deletions
|
|
@ -414,15 +414,46 @@ Hooks.LoadMorePrefetch = {
|
|||
}
|
||||
}
|
||||
|
||||
// Reads a browser cookie value by name (used to echo the persisted member
|
||||
// view-settings to the server on connect, since the live socket's connect-info
|
||||
// does not expose cookies).
|
||||
function getCookie(name) {
|
||||
const match = document.cookie.match(new RegExp("(?:^|; )" + name + "=([^;]*)"))
|
||||
return match ? decodeURIComponent(match[1]) : null
|
||||
}
|
||||
|
||||
let liveSocket = new LiveSocket("/live", Socket, {
|
||||
longPollFallbackMs: 2500,
|
||||
params: {
|
||||
_csrf_token: csrfToken,
|
||||
timezone: getBrowserTimezone()
|
||||
timezone: getBrowserTimezone(),
|
||||
view_settings: getCookie("member_view_settings")
|
||||
},
|
||||
hooks: Hooks
|
||||
})
|
||||
|
||||
// Persist the member-overview view settings per browser/device (§1.5/§1.20). The
|
||||
// LiveView pushes "store-view-settings" (density + compact field toggles) on
|
||||
// change; we write a long-lived cookie that the LiveView reads back on the next
|
||||
// full page load (via the request cookie on the dead render and via connect
|
||||
// params on the connected mount).
|
||||
// Return the members list to the top after a sort or filter change. The server
|
||||
// resets the keyset stream to page 1 on those changes and pushes this event; a
|
||||
// user scrolled down would otherwise be stranded past the shorter content with
|
||||
// infinite scroll not re-arming. No-op if the scroll container is absent.
|
||||
window.addEventListener("phx:members:scroll-top", () => {
|
||||
const el = document.getElementById("members-table-guard")
|
||||
if (el) el.scrollTop = 0
|
||||
})
|
||||
|
||||
window.addEventListener("phx:store-view-settings", (e) => {
|
||||
const json = e.detail && e.detail.view_settings
|
||||
if (typeof json === "string" && json.length > 0) {
|
||||
const maxAge = 365 * 24 * 60 * 60
|
||||
document.cookie = `member_view_settings=${encodeURIComponent(json)};path=/;max-age=${maxAge};samesite=lax`
|
||||
}
|
||||
})
|
||||
|
||||
// Listen for custom events from LiveView
|
||||
window.addEventListener("phx:set-input-value", (e) => {
|
||||
const {id, value} = e.detail
|
||||
|
|
@ -432,15 +463,6 @@ window.addEventListener("phx:set-input-value", (e) => {
|
|||
}
|
||||
})
|
||||
|
||||
// Return the members list to the top after a sort or filter change. The server
|
||||
// resets the keyset stream to page 1 on those changes and pushes this event; a
|
||||
// user scrolled down would otherwise be stranded past the shorter content with
|
||||
// infinite scroll not re-arming. No-op if the scroll container is absent.
|
||||
window.addEventListener("phx:members:scroll-top", () => {
|
||||
const el = document.getElementById("members-table-guard")
|
||||
if (el) el.scrollTop = 0
|
||||
})
|
||||
|
||||
// Show progress bar on live navigation and form submits
|
||||
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
|
||||
window.addEventListener("phx:page-loading-start", _info => topbar.show(300))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue