www.spaceplanner.app

Web client to the spaceplanner API
git clone git://jacobedwards.org/www.spaceplanner.app
Log | Files | Refs

commit f21a7003196ce54dfc7b20337ecf55b81426da1f
parent 6524234726898991f9ac286541a4548dc645ae76
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date:   Thu, 17 Oct 2024 23:47:20 -0700

Update gallery style

Some changes include:

- Remove list view
- Fix grid sizing for small devices (by reducing the number of
  columns)
- No fixed aspect ratio for items (since the floorplan images aren't
  going to happen for a bit yet)
- Use textual buttons instead of icons
- Use a link for a link instead of a button-script-link

Some changes were made to the document structure to accommodate
these changes.

Diffstat:
Mfiles/floorplans/index.html | 6++----
Mfiles/floorplans/main.css | 85+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Mfiles/floorplans/main.js | 89+++++++++++++++++++++++++++++--------------------------------------------------
3 files changed, 82 insertions(+), 98 deletions(-)

diff --git a/files/floorplans/index.html b/files/floorplans/index.html @@ -11,10 +11,8 @@ <body> <h1>Floorplans</h1> - <input type="image" id="display_method"/> - <hr> - - <ul id="floorplans"></ul> + + <ul id="floorplans" class="grid"></ul> </body> </html> diff --git a/files/floorplans/main.css b/files/floorplans/main.css @@ -1,41 +1,57 @@ -.floorplan > header > input[type="button"] { - float: right; +#floorplans { + list-style: none; } #floorplans.grid { list-style: none; display: grid; - grid-template-columns: repeat(3, minmax(10em, 24em)); - grid-column-gap: .5em; + justify-content: center; + grid-template-columns: repeat(auto-fit, minmax(15em, 25vw)); + grid-column-gap: .65em; grid-row-gap: 1em; padding-left: 0; } #floorplans.grid > li { - aspect-ratio: 1; + //aspect-ratio: 1; } #floorplans.grid > li > .floorplan { box-sizing: border-box; display: block; height: 100%; - border: medium solid black; + border: .15em solid grey; border-radius: .4rem; /* NOTE: Required for footers to be slapped on the bottom, not sure why */ position: relative; overflow: hidden; } -#floorplans.grid > li > .floorplan > header { +.floorplan { + background-color: #FAFAFA; + padding: .5em .75em; +} + +.floorplan > header { padding: 4%; - background-color: rgba(0, 0, 0, .1); } -#floorplans.grid > li > .floorplan > header > h2 { - margin: 0 0 .5rem 0; +.floorplan > header > .fp_ops { + display: flex; + justify-content: space-between; + padding-bottom: .5em; + border-bottom: thin solid grey; +} + +.floorplan > header > .fp_ops > a { + margin-right: .25em; +} + +.floorplan > header > .fp_ops > .fp_buttons > input { + margin: 0 .2em; } -#floorplans.grid > li > .floorplan > footer { +.floorplan > footer { background-color: rgba(0, 0, 0, .05); position: absolute; bottom: 0; @@ -45,22 +61,10 @@ border-radius: .2rem 0 0 0; } -#floorplans.grid > li > .floorplan:hover > footer { +.floorplan:hover > footer { opacity: 100%; } -#floorplans.grid > li > .floorplan > header { - min-height: 25%; -} - -#floorplans:not(.grid) > li > .floorplan { - margin: 2rem; -} - -#floorplans:not(.grid) > li { - max-width: 32rem; -} - .name_div { display: flex; align-items: center; @@ -71,34 +75,41 @@ border: none; } -.fp_name { - font-size: large; - margin-bottom: .25em; +input.name, input.synopsis, input.address { + background-color: white; +} + +/* + * Maybe I should give these elements two classes: fp_metadata and + * one of the following: */ +input.synopsis, input.address { + display: block; + max-width: 60%; +} + +.name { + font-size: larger; + margin-top: .75em; + margin-bottom: .5em; + max-width: 90%; display: inline; } -.fp_address { +.address { font-style: italic; margin-bottom: .5em; } -.fp_terms { +.synopsis { margin-top: 0; } -.fp_address::before { +.address::before { content: "Address: "; font-size: smaller; } -/* Maybe I should give these elements two classes: fp_metadata and - * one of the following: */ -input.fp_synopsis, input.fp_address { - display: block; - max-width: 60%; -} - .delete_dialog { background-color: #F3F3F3; position: fixed; diff --git a/files/floorplans/main.js b/files/floorplans/main.js @@ -11,44 +11,19 @@ function init() { etc.authorize() etc.bar() - let display_button = document.getElementById("display_method") - if (!display_button) { - throw new Error("Expected #display_method") - } - - let list = { button: ui.button("List", "Switch to list view", "list"), func: listview } - let grid = { button: ui.button("Grid", "Switch to grid view", "grid"), func: gridview } - let toggle - if (localStorage.getItem("fp_gridview")) { - toggle = ui.toggle(list, grid, { init: true }) - } else { - toggle = ui.toggle(grid, list, { init: true }) - } - display_button.replaceWith(toggle) - api.fetch("GET", "floorplans/:user") .then(show_floorplans) .catch(etc.error) } -function listview() { - document.getElementById("floorplans").removeAttribute("class") - localStorage.removeItem("fp_gridview") -} - -function gridview() { - document.getElementById("floorplans").setAttribute("class", "grid") - localStorage.setItem("fp_gridview", "list") -} - function commit_editable_floorplan_func(element, data) { return function () { let patches = [] - let fields = Array.from(element.querySelectorAll('input.fp_name, input.fp_address, input.fp_synopsis')) + let fields = Array.from(element.querySelectorAll(".fp_metadata")) let updated = false let newdata = {} for (let i in fields) { - let name = floorplan_info_name(fields[i].getAttribute("class")) + let name = fields[i].name let value = fields[i].value if (value.length === 0) { value = null @@ -86,7 +61,7 @@ function editable_floorplan_create_func(element) { let data = {} let fields = Array.from(element.querySelectorAll("header > input")) for (let i in fields) { - let name = floorplan_info_name(fields[i].getAttribute("class")) + let name = fields[i].name let value = fields[i].value console.debug(fields[i], name, value) if (value) { @@ -122,20 +97,21 @@ function editable_floorplan_func(element, data) { let parent = element.querySelector("header") for (let i in editables) { let input - let c = floorplan_info_class(editables[i]) - let e = parent.querySelector("." + c) // .getElementsByClassName() let memo = "Edit floorplan " + editables[i] + let e = parent.querySelector("." + editables[i]) + + input = ui.input(editables[i], memo, { + attributes: { value: e ? e.textContent : "" } + }) + input.classList.add("fp_metadata") + input.classList.add(editables[i]) + input.name = editables[i] + if (e) { - input = ui.input(editables[i], memo, { - attributes: { value: e.textContent } - }) - input.setAttribute("class", c) e.replaceWith(input) } else { - input = ui.input(editables[i], memo) - input.setAttribute("class", c) if (prev) { - if (prev.classList.contains("fp_name")) { + if (prev.name === "name") { parent.append(input) } else { prev.after(input) @@ -149,17 +125,6 @@ function editable_floorplan_func(element, data) { } } -function floorplan_info_class(name) { - return "fp_" + name; -} - -function floorplan_info_name(classname) { - if (!classname.match("^fp_")) { - throw new Error("Expected floorplan info class") - } - return classname.substring(3) -} - function delete_floorplan_func(item, floorplan) { return function() { api.fetch("DELETE", `floorplans/:user/${floorplan.id}`) @@ -217,11 +182,18 @@ function create_floorplan(floorplan) { let root = document.createElement("div") root.classList.add("class", "floorplan") - let aside = document.createElement("aside") + let aside = document.createElement("div") + aside.classList.add("fp_ops") if (floorplan) { - aside.append(ui.button("Edit", "Open floorplan editor", "create", { handlers: { click: function() { document.location.href = `./floorplan/?id=${floorplan.id}` } } })) - aside.append(ui.button("Copy", "Copy floorplan", "copy", { handlers: { click: function() { copy_floorplan(floorplan) } } })) - aside.append(ui.button("Delete", "Delete floorplan", "trash", { handlers: { click: ask_delete_floorplan_func(root, floorplan) } })) + let a = aside.appendChild(document.createElement("a")) + a.href = `./floorplan/?id=${floorplan.id}` + a.append(document.createTextNode("Editor")) + + let ops = aside.appendChild(document.createElement("div")) + ops.classList.add("fp_buttons") + + ops.append(ui.button("Copy", "Copy floorplan", null, { handlers: { click: function() { copy_floorplan(floorplan) } } })) + ops.append(ui.button("Delete", "Delete floorplan", null, { handlers: { click: ask_delete_floorplan_func(root, floorplan) } })) } else { root.id = "adder" root.addEventListener("keydown", function(ev) { @@ -230,11 +202,11 @@ function create_floorplan(floorplan) { editable_floorplan_create_func(root)() } }) - aside.append(ui.button("Create", "Create floorplan", "create", { handlers: { click: editable_floorplan_create_func(root) } })) + aside.append(ui.button("Create", "Create floorplan", null, { handlers: { click: editable_floorplan_create_func(root) } })) } - root.append(aside) let header = document.createElement("header") + header.append(aside) root.append(header) if (!floorplan) { @@ -272,7 +244,8 @@ function create_floorplan(floorplan) { var create_field = { name: function(text, id) { let heading = document.createElement("h2") - heading.setAttribute("class", floorplan_info_class("name")) + heading.classList.add("fp_metadata") + heading.classList.add("name") let link = document.createElement("a") link.href = `./floorplan/?id=${id}` link.appendChild(document.createTextNode(text)) @@ -282,14 +255,16 @@ var create_field = { synopsis: function(text) { let synopsis = document.createElement("span") - synopsis.setAttribute("class", floorplan_info_class("synopsis")) + synopsis.classList.add("fp_metadata") + synopsis.classList.add("synopsis") synopsis.appendChild(document.createTextNode(text)) return synopsis }, address: function(text) { let address = document.createElement("address") - address.setAttribute("class", floorplan_info_class("address")) + address.classList.add("fp_metadata") + address.classList.add("address") address.appendChild(document.createTextNode(text)) return address }