Applies some beercss styling and layouting.

This commit is contained in:
Stefan Schallerl 2025-02-07 12:28:43 +01:00
parent 1d68957f96
commit 60309ec3c4
16 changed files with 289 additions and 121 deletions

View file

@ -48,9 +48,11 @@ fun formatHumanReadableSize(bytes: Long) = when (bytes) {
else -> "${bytes / 1_000_000_000} gb"
}
private val tagSplitRegex = Regex("\\s")
object TagAdapter {
fun parse(ser: String?): List<Tag> {
return ser?.let { if (it.isNotBlank()) it.split(",").map { Tag(it) } else emptyList() } ?: emptyList()
return ser?.let { if (it.isNotBlank()) it.split(tagSplitRegex).map { Tag(it) } else emptyList() } ?: emptyList()
}
fun List<Tag>.serialize() = if (this.isEmpty()) "" else this.joinToString(",") { it.value }
@ -62,10 +64,12 @@ fun List<Document>.grouped(): Map<Int, Map<Month, List<Document>>> =
values.groupBy { it.referenceDate.month }
}
private val htmlDtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT, FormatStyle.SHORT)
private val shortDtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT, FormatStyle.SHORT)
private val longDtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.SHORT)
val formDtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm")
fun LocalDateTime.formatHuman() = this.format(htmlDtf)
fun LocalDateTime.formatHumanShort() = this.format(shortDtf)
fun LocalDateTime.formatHumanLong() = this.format(longDtf)
fun LocalDateTime.formatHtmlForm() = this.format(formDtf)
private val dfMonth = DateTimeFormatter.ofPattern("MMMM")

View file

@ -32,10 +32,9 @@ class DocumentController(val modifiers: TemplateModifiers, val repository: Sqlit
content = Document(
modifiers = modifiers,
extId = document.extId.value,
title = document.title,
referenceDate = dtf.format(document.referenceDate),
referenceDate = document.referenceDate.formatHumanLong(),
tags = { document.tags.map { TagsBlock(tag = it.value) }.asSequence() },
description = document.description,
description = document.description.ifBlank { "-" },
files = FileList(
modifiers = modifiers,
delete = true,

View file

@ -16,7 +16,7 @@ class LimboController(val modifiers: TemplateModifiers, val repository: SqliteRe
ctx.tempolin(
Frame(
modifiers = modifiers,
title = "Filemure Limbo",
title = "Limbo",
target = "limbo",
back = "/",
content = Limbo(
@ -27,7 +27,7 @@ class LimboController(val modifiers: TemplateModifiers, val repository: SqliteRe
file = f.filename,
type = f.contentType ?: "",
size = formatHumanReadableSize(f.fileSize),
uploaded = f.created.formatHuman()
uploaded = f.created.formatHumanShort()
)
}.asSequence()
})

View file

@ -71,7 +71,7 @@ class OverviewController(private val modifiers: TemplateModifiers, private val r
documents.sortedBy { it.referenceDate }.map { document ->
DocumentBlock(
extId = document.extId.value,
referenceDate = document.referenceDate.formatHuman(),
referenceDate = document.referenceDate.formatHumanShort(),
title = document.title.ifBlank { "untitled" },
)
}.asSequence()

View file

@ -2,7 +2,7 @@ package net.h34t.filemure.controller
import io.javalin.http.Context
import net.h34t.filemure.TemplateModifiers
import net.h34t.filemure.formatHuman
import net.h34t.filemure.formatHumanShort
import net.h34t.filemure.repository.SqliteRepository
import net.h34t.filemure.requireSession
import net.h34t.filemure.tempolin
@ -21,7 +21,7 @@ class SearchController(val modifiers: TemplateModifiers, val repository: SqliteR
ctx.tempolin(
Frame(
modifiers = modifiers,
title = "Overview",
title = "Search",
target = "document",
back = "/",
content = Search(
@ -32,7 +32,7 @@ class SearchController(val modifiers: TemplateModifiers, val repository: SqliteR
DocumentBlock(
extId = d.extId.value,
title = d.title,
referenceDate = d.referenceDate.formatHuman()
referenceDate = d.referenceDate.formatHumanShort()
)
}.asSequence()
}

View file

@ -1,18 +1,39 @@
<h1>{*$title}</h1>
<fieldset>
<legend>Document</legend>
<p>Date: {*$referenceDate}</p>
<b>Date</b>
<div>{*$referenceDate}</div>
<p>Tags: <span id="tags">{for $tags}<span>{*$tag}</span>{/for}</span></p>
<div class="space"></div>
<p>Description:<br>
{*$description}
</p>
<b>Tags</b>
<div><span id="tags">{for $tags}<button class="chip fill round">{*$tag}</button>{/for}</span></div>
<div class="space"></div>
<b>Description</b>
<div>{*$description}</div>
</fieldset>
<fieldset>
<legend>Files</legend>
{template $files}
</fieldset>
<p><a href="/document/{*$extId}/edit">edit</a></p>
<fieldset>
<legend>Actions</legend>
<div class="row right-align">
<div class="min right">
<a href="/document/{*$extId}/edit">
<button><i>edit</i><span>edit</span></button>
</a>
</div>
<div class="min right">
<form action="/document/{*$extId}/delete" method="post">
<input type="submit" value="delete">
<button><i>delete</i><span>delete</span></button>
</form>
</div>
</div>
</fieldset>

View file

@ -1,24 +1,41 @@
<form action="/document/new" method="post">
<p><label>Document title:<br>
<input type="text" name="title" value="{*$title}"></label></p>
<p><label>Date:<br>
<input type="datetime-local" name="reference_date" value="{*$referenceDate}"></label></p>
<fieldset>
<legend>New Document</legend>
<p><label>Tags:<br>
<input type="text" name="tags"></label></p>
<div class="field border label">
<input id="title" type="text" name="title" value="{*$title}">
<label for="title">Document title</label>
</div>
<div class="field border label">
<input id="reference_date" type="datetime-local" name="reference_date" value="{*$referenceDate}">
<label for="reference_date">Date</label>
</div>
<div class="field border label">
<input id="itags" type="text" name="tags">
<label for="itags">Tags</label>
<div id="tags">{for $tags}<span>{*$tag}</span>{/for}</div>
</div>
<p><label>Description:<br>
<textarea name="description" rows="40" cols="80">{*$description}</textarea>
</label></p>
<div class="field textarea label border">
<textarea id="desc" name="description" rows="40" cols="80">{*$description}</textarea>
<label for="desc">Description</label>
</div>
{for $fileId}
<input type="hidden" name="file_id" value="{*$extId}">
{/for}
<p><input type="submit" value="create"></p>
<button>
<i>save</i>
<span>save</span>
</button>
{template $files}
</fieldset>
</form>

View file

@ -1,20 +1,36 @@
<form action="/document/{*$extId}/edit" method="post">
<p><label>Document title:<br>
<input type="text" name="title" value="{*$title}"></label></p>
<p><label>Date:<br>
<input type="datetime-local" name="reference_date" value="{*$referenceDate}"></label></p>
<fieldset>
<legend>New Document</legend>
<p><label>Tags:<br>
<input type="text" name="tags"></label></p>
<div class="field border label">
<input id="title" type="text" name="title" value="{*$title}">
<label for="title">Document title</label>
</div>
<div class="field border label">
<input id="reference_date" type="datetime-local" name="reference_date" value="{*$referenceDate}">
<label for="reference_date">Date</label>
</div>
<div class="field border label">
<input id="itags" type="text" name="tags">
<label for="itags">Tags</label>
<div id="tags">{for $tags}<span>{*$tag}</span>{/for}</div>
</div>
<p><label>Description:<br>
<textarea name="description" rows="40" cols="80">{*$description}</textarea>
</label></p>
<div class="field textarea label border">
<textarea id="desc" name="description" rows="40" cols="80">{*$description}</textarea>
<label for="desc">Description</label>
</div>
<p><input type="submit" value="save"></p>
<div class="right-align">
<button><i>save</i><span>save</span></button>
</div>
</fieldset>
<fieldset>
<legend>Files</legend>
{template $files}
</fieldset>
</form>

View file

@ -1,4 +1,5 @@
<table>
<table class="stripes">
<thead>
<tr>
<th>Filename</th>
<th>Type</th>
@ -8,17 +9,24 @@
<th>Delete</th>
{/if}
</tr>
</thead>
<tbody>
{for $files}
<tr>
<td>{*$filename}</td>
<td>{*$contentType}</td>
<td>{*$size}</td>
<td><a href="/file/{*$extId}/download">download</a></td>
<td><a href="/file/{*$extId}/download">
<button class="small"><i>download</i><span>download</span></button>
</a></td>
{if $delete}
<td><a href="/file/{*$extId}/delete">delete</a></td>
<td><a href="/file/{*$extId}/delete">
<button class="small"><i>delete</i><span>delete</span></button>
</a></td>
{/if}
</tr>
{/for}
</tbody>
</table>

View file

@ -1,9 +1,10 @@
<h1>Filemure Limbo</h1>
<p>{$limboFileCount} Files</p>
<form id="newdoc" action="/document/new" method="get">
</form>
<table>
<fieldset>
<legend>{$limboFileCount} Files</legend>
<table class="stripes">
<thead>
<tr>
<th>-</th>
<th>Filename</th>
@ -13,20 +14,33 @@
<th>view</th>
<th>delete</th>
</tr>
</thead>
<tbody>
{for $file}
<tr>
<td><label><input type="checkbox" name="file_id" value="{*$extId}" form="newdoc"></label></td>
<td><label class="checkbox"><input type="checkbox" name="file_id" value="{*$extId}"
form="newdoc"><span></span></label></td>
<td>{*$file}</td>
<td>{*$type}</td>
<td>{*$size}</td>
<td>{*$uploaded}</td>
<td class="nowrap">{*$type}</td>
<td class="nowrap">{*$size}</td>
<td class="nowrap">{*$uploaded}</td>
<td>
<a href="/file/{*$extId}/download"><button>view</button></a>
<a href="/file/{*$extId}/download">
<button class="small">view</button>
</a>
</td>
<td>
<form action="/file/{*$extId}/delete?return=limbo" method="POST"><input type="submit" value="delete"></form>
<form action="/file/{*$extId}/delete?return=limbo" method="POST">
<button class="small"><i>delete</i><span>delete</span></button>
</form>
</td>
</tr>
{/for}
</tbody>
</table>
<input type="submit" value="new document" form="newdoc">
</fieldset>
<fieldset>
<legend>Actions</legend>
<button form="newdoc"><i>add</i><span>new document</span></button>
</fieldset>

View file

@ -1,11 +1,26 @@
<h1>Hello to Filemure</h1>
<form action="/login" method="post">
<p><label>Your email:<br>
<input type="email" placeholder="your-email@example.com" name="username"></label></p>
<p><label>Your password:<br>
<input type="password" name="password"></label></p>
<fieldset>
<legend>Log In</legend>
<p><input type="submit" value="login"></p>
<div class="field border label">
<input id="email" type="email" placeholder="your-email@example.com" name="username">
<label for="email">Your email</label>
</div>
<div class="field border label">
<input id="password" type="password" name="password">
<label for="password">Your password</label>
</div>
<button>
<i>login</i>
<span>log in</span>
</button>
<!--<p><input type="submit" value="login"></p>-->
</fieldset>
</form>

View file

@ -1,21 +1,66 @@
<p>To add a document, just drag &amp; drop the file in here.</p>
<p>Files in <a href="/limbo">limbo: {$limboFileCount}</a>.</p>
<div class="row">
<div class="max">
<fieldset>
<legend>Limbo</legend>
<div class="row">
<div class="max">
Files in <a href="/limbo">limbo: {$limboFileCount}</a>
</div>
<div class="min">
<a href="/limbo"><button><i>folder_open</i><span>view</span></button></a>
</div>
</div>
</fieldset>
</div>
<div class="max">
<fieldset>
<legend>Search</legend>
<form action="/search" method="get">
<input type="search" name="q"> <input type="submit" value="search">
<div class="row">
<div class="max">
<div class="field label prefix border">
<i>search</i>
<input type="search" name="q">
<label>Query</label>
</div>
</div>
<div class="min">
<button><i>search</i><span>search</span></button>
</div>
</div>
</form>
</fieldset>
</div>
</div>
<table>
{for $year}
<table class="stripes">
<thead>
<tr>
<th colspan="2">{*$year}</th>
<th>Date</th>
<th>Files</th>
<th>View</th>
</tr>
</thead>
{for $year}
<thead>
<tr>
<th colspan="3">{*$year}</th>
</tr>
</thead>
{for $month}
<tbody>
<tr>
<td>{*$monthHuman}</td>
<td><a href="/overview/{*$year}/{*$month}">{*$count} Files</a></td>
<td>{*$count}</td>
<td><a href="/overview/{*$year}/{*$month}">
<button class="small"><span>view</span></button>
</a></td>
</tr>
</tbody>
{/for}
{/for}
</table>

View file

@ -1,17 +1,22 @@
<h1>Documents for {*$category}</h1>
<table>
<table class="striped">
<thead>
<tr>
<th>Date</th>
<th>Title</th>
<th>Details</th>
</tr>
</thead>
<tbody>
{for $document}
<tr>
<td>{*$referenceDate}</td>
<td>{*$title}</td>
<td><a href="/document/{*$extId}">details</a></td>
<td><a href="/document/{*$extId}">
<button class="small">details</button>
</a></td>
</tr>
{/for}
</tbody>
</table>

View file

@ -1,18 +1,36 @@
<h1>Search for &quot;{*$search}&quot;</h1>
<form action="/search" method="get">
<input type="search" name="q" value="{*$search}"> <input type="submit" value="search">
<fieldset>
<legend>Search</legend>
<form action="/search" method="get">
<div class="row">
<div class="max">
<div class="field label prefix border">
<i>search</i>
<input type="search" name="q" value="{*$search}">
<label>Query</label>
</div>
</div>
<div class="min">
<button><i>search</i><span>search</span></button>
</div>
</div>
</form>
</fieldset>
</form>
<h2>Results</h2>
<fieldset>
<legend>Search results for &quot;{*$search}&quot;</legend>
<table>
<table class="stripes">
<thead>
<tr>
<th>Date</th>
<th>Title</th>
<th>Details</th>
</tr>
</thead>
<tbody>
{for $document}
<tr>
<td>{*$referenceDate}</td>
@ -22,4 +40,6 @@
</a></td>
</tr>
{/for}
</tbody>
</table>
</fieldset>

View file

@ -30,3 +30,7 @@
top: 32px;
bottom: 64px;
}
.nowrap {
white-space: nowrap;
}

View file

@ -3,8 +3,8 @@ document.addEventListener("DOMContentLoaded", function () {
const targetContainer = document.querySelector('.dropzone')
if (targetContainer != null) {
console.log("target ready")
const target = targetContainer.dataset.target;
const target = targetContainer.dataset.target
console.log("file drag & drop ready with target \"" + target + "\"")
const progressDialog = document.querySelector('#upload_progress_dialog')
const progressBar = document.querySelector('#upload_progress')