2024.12.13 02:40:05

This commit is contained in:
Christian Moser 2024-12-13 02:40:06 +01:00
parent 2be92ca3e5
commit 4a77602574
12 changed files with 328 additions and 100 deletions

View File

@ -1,4 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 8 0 c -4.410156 0 -8 3.589844 -8 8 s 3.589844 8 8 8 s 8 -3.589844 8 -8 s -3.589844 -8 -8 -8 z m 0 2 c 3.332031 0 6 2.667969 6 6 s -2.667969 6 -6 6 s -6 -2.667969 -6 -6 s 2.667969 -6 6 -6 z m -2.03125 2.96875 c -0.265625 0 -0.519531 0.105469 -0.707031 0.292969 c -0.390625 0.390625 -0.390625 1.023437 0 1.414062 l 1.292969 1.292969 l -1.292969 1.292969 c -0.390625 0.390625 -0.390625 1.023437 0 1.414062 s 1.023437 0.390625 1.414062 0 l 1.292969 -1.292969 l 1.292969 1.292969 c 0.390625 0.390625 1.023437 0.390625 1.414062 0 s 0.390625 -1.023437 0 -1.414062 l -1.292969 -1.292969 l 1.292969 -1.292969 c 0.390625 -0.390625 0.390625 -1.023437 0 -1.414062 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 s -0.519531 0.105469 -0.707031 0.292969 l -1.292969 1.292969 l -1.292969 -1.292969 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 z m 0 0" fill="#2e3436"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="16px"
viewBox="0 0 16 16"
width="16px"
version="1.1"
id="svg1"
sodipodi:docname="delete.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="73.3125"
inkscape:cx="8"
inkscape:cy="8"
inkscape:window-width="2339"
inkscape:window-height="1353"
inkscape:window-x="-16"
inkscape:window-y="71"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
d="m 8 0 c -4.410156 0 -8 3.589844 -8 8 s 3.589844 8 8 8 s 8 -3.589844 8 -8 s -3.589844 -8 -8 -8 z m 0 2 c 3.332031 0 6 2.667969 6 6 s -2.667969 6 -6 6 s -6 -2.667969 -6 -6 s 2.667969 -6 6 -6 z m -2.03125 2.96875 c -0.265625 0 -0.519531 0.105469 -0.707031 0.292969 c -0.390625 0.390625 -0.390625 1.023437 0 1.414062 l 1.292969 1.292969 l -1.292969 1.292969 c -0.390625 0.390625 -0.390625 1.023437 0 1.414062 s 1.023437 0.390625 1.414062 0 l 1.292969 -1.292969 l 1.292969 1.292969 c 0.390625 0.390625 1.023437 0.390625 1.414062 0 s 0.390625 -1.023437 0 -1.414062 l -1.292969 -1.292969 l 1.292969 -1.292969 c 0.390625 -0.390625 0.390625 -1.023437 0 -1.414062 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 s -0.519531 0.105469 -0.707031 0.292969 l -1.292969 1.292969 l -1.292969 -1.292969 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 z m 0 0"
fill="#2e3436"
id="path1"
style="fill:#e0d4a4;fill-opacity:1" />
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="16px"
viewBox="0 0 16 16"
width="16px"
version="1.1"
id="svg1"
sodipodi:docname="directory-new.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="73.3125"
inkscape:cx="7.9931799"
inkscape:cy="8"
inkscape:window-width="3440"
inkscape:window-height="1369"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 3 1 c -1.644531 0 -3 1.355469 -3 3 v 8 c 0 1.644531 1.355469 3 3 3 h 3 c 0.550781 0 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 h -3 c -0.5625 0 -1 -0.4375 -1 -1 v -7 h 11 c 0.5625 0 1 0.4375 1 1 v 1 c 0 0.550781 0.449219 1 1 1 s 1 -0.449219 1 -1 v -1 c 0 -1.644531 -1.355469 -3 -3 -3 h -3.585938 l -1.707031 -1.707031 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 z m 0 2 h 3.585938 l 1 1 h -5.585938 c 0 -0.5625 0.4375 -1 1 -1 z m 8 5 v 3 h -3 v 2 h 3 v 3 h 2 v -3 h 3 v -2 h -3 v -3 z m 0 0"
fill="#2e3436"
id="path1"
style="fill:#e0d4a4;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

40
assets/icons/upload.svg Normal file
View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="16px"
viewBox="0 0 16 16"
width="16px"
version="1.1"
id="svg1"
sodipodi:docname="upload.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="73.3125"
inkscape:cx="7.9931799"
inkscape:cy="8"
inkscape:window-width="3440"
inkscape:window-height="1369"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 4 0 c -1.644531 0 -3 1.355469 -3 3 v 10 c 0 1.644531 1.355469 3 3 3 h 1 c 0.550781 0 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 h -1 c -0.570312 0 -1 -0.429688 -1 -1 v -10 c 0 -0.570312 0.429688 -1 1 -1 h 5.585938 l 3.414062 3.414062 v 7.585938 c 0 0.570312 -0.429688 1 -1 1 h -1 c -0.550781 0 -1 0.449219 -1 1 s 0.449219 1 1 1 h 1 c 1.644531 0 3 -1.355469 3 -3 v -8 c 0 -0.265625 -0.105469 -0.519531 -0.292969 -0.707031 l -4 -4 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 z m 4 6 c -0.265625 0 -0.519531 0.105469 -0.707031 0.292969 l -3 3 c -0.390625 0.390625 -0.390625 1.023437 0 1.414062 s 1.023437 0.390625 1.414062 0 l 1.292969 -1.292969 v 6.585938 h 2 v -6.585938 l 1.292969 1.292969 c 0.390625 0.390625 1.023437 0.390625 1.414062 0 s 0.390625 -1.023437 0 -1.414062 l -3 -3 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 z m 0 0"
fill="#2e3436"
fill-rule="evenodd"
id="path1"
style="fill:#e0d4a4;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -191,6 +191,8 @@ th {
padding-bottom: 5px;
font-size: var(--font-size-th);
font-weight: var(--font-weight-th);
border-color:var(--color-th-background);
border-width:0px;
}
@ -199,6 +201,8 @@ td {
padding-right: 10px;
padding-top: 5px;
padding-bottom: 5px;
margin:0px;
border-width:0px;
color: var(--color-text);
font-size: var(--font-size-td);
}
@ -222,54 +226,6 @@ a:visited {
}
.left {
text-align: left;
}
.center {
text-align: center;
align-self: center;
align-items:center;
}
.right {
text-align: right;
}
.error {
color: var(--error-color);
}
.frame {
border-width: 2px;
border-radius: 5px;
border-style: solid;
border-color: var(--color-text);
}
.frame-table th,
.frame-table td {
padding: 5px;
border-width: 0px;
}
.center-box {
align-content:center;
text-align: center;
width: 100%;
}
.login-box {
min-width: 400px;
max-width: 600px;
position: relative;
display: inline-block;
padding: 20px;
}
.full-width {
width: 100%;
}
label {
font-size: 16px;
@ -321,15 +277,30 @@ select {
border-width: 0px;
}
.optional-input {
background-color: var(--color-optional-input);
}
code {
background-color: var(--color-code-background);
color: var(--color-code);
}
fieldset {
border: 3px solid var(--color-text);
border-radius: 8px;
margin-top: 5px;
margin-bottom: 5px;
}
dialog {
background-color: var(--color-background);
color: var(--color-text);
border: 2px, solid, white;
border-radius: 10px;
}
.optional-input {
background-color: var(--color-optional-input);
}
.td-color {
background-color: var(--color-background);
color: var(--color-text);
@ -340,16 +311,59 @@ code {
white-space:nowrap;
}
.left {
text-align: left;
}
.center {
text-align: center;
align-self: center;
align-items:center;
}
.right {
text-align: right;
}
.error {
color: var(--error-color);
}
.frame {
border-width: 2px;
border-radius: 5px;
border-style: solid;
border-color: var(--color-text);
}
.frame-table th,
.frame-table td {
padding: 5px;
border-width: 0px;
}
.center-box {
align-content:center;
text-align: center;
width: 100%;
}
.login-box {
min-width: 400px;
max-width: 600px;
position: relative;
display: inline-block;
padding: 20px;
}
.full-width {
width: 100%;
}
.standard-background {
background-color: var(--color-background);
}
fieldset {
border: 3px solid var(--color-text);
border-radius: 8px;
margin-top: 5px;
margin-bottom: 5px;
}
.margin-5 {
margin: 5px;
@ -388,6 +402,14 @@ fieldset {
content: url('../icons/file.svg');
}
.icon-upload {
content: url('../icons/upload.svg');
}
.icon-directory-new {
content: url('../icons/directory-new.svg');
}
.list-icon {
width: 24;
height: 24;
@ -395,9 +417,17 @@ fieldset {
.toolbar-button {
background-color: var(--background-color);
border: 1px solid var(--color-text);
border: 0px hidden var(--color-text);
cursor: pointer;
}
.toolbar-item {
margin-right: 5px;
}
.border-collapse {
border-collapse: collapse;
}
.tr-border-bottom {
border-bottom: 1px solid var(--color-text);
}

View File

@ -1,10 +1,4 @@
<?php
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Scripting/PHPClass.php to edit this template
*/
namespace App\Component\Sorter;
enum FileSortType {
@ -17,9 +11,3 @@ enum FileSortType {
case DATE_ASC;
case DATE_DESC;
}
/**
* Description of FileSortType
*
* @author c9mos
*/

View File

@ -1,7 +1,6 @@
<?php
namespace App\Component\Sorter;
use App\Component\Sorter\FileSortType;
/**

View File

@ -7,7 +7,6 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\KernelInterface;
@ -245,6 +244,18 @@ abstract class WebrootController extends AbstractController
'mtime' => $this->trans("directory.mtime",domain:'mydevel.webroot.app'),
'filesize' => $this->trans("directory.filesize",domain:'mydevel.webroot.app'),
'title' => $this->trans("directory.title",["url"=>$url],domain:'mydevel.webroot.app'),
'deletedialog' => [
'title' => $this->trans("directory.delete-dialog.title",domain:'mydevel.webroot.app'),
'message' => $this->trans("directory.delete-dialog.message",domain:'mydevel.webroot.app'),
'button_delete' => $this->trans("button.delete",domain:'mydevel.webroot.app'),
'button_close' => $this->trans("button.cancel",domain:'mydevel.webroot.app'),
],
'mkdirdialog' => [
'title' => $this->trans('directory.mkdir.title',domain:'mydevel.webroot.app'),
'message' => $this->trans('directory.mkdir.message',domain:'mydevel.webroot.app'),
'button_create' => $this->trans('button.cancel',domain:'mydevel.webroot.app'),
'button_close' => $this->trans('button.create',domain:'mydevel.webroot.app'),
],
],
"parent_url"=>$routeconf['parent_url'],
"url"=>$url,

View File

@ -10,6 +10,8 @@
{% block javascripts %}
{% block importmap %}{{ importmap('app') }}{% endblock %}
{% endblock %}
{% block headscript %}{%endblock%}
</head>
<body style="margin:0px;padding:0px;">
{% block body %}

View File

@ -13,8 +13,8 @@
This friendly message is coming from:
<ul>
<li>Your controller at <code>C:/msys64/home/c9mos/www/webroot/src/Controller/MainController.php</code></li>
<li>Your template at <code>C:/msys64/home/c9mos/www/webroot/templates/main/index.html.twig</code></li>
<li>Your controller at <code>{{ controller_class }}::{{ controller_function }}</code></li>
<li>Your template at <code>C:/msys64/home/c9mos/www/webroot/templates/webroot/controller.html.twig</code></li>
</ul>
</div>
{% endblock %}

View File

@ -1,49 +1,50 @@
{% extends 'base.html.twig' %}
{% block headscript %}
{% endblock %}
{% block main %}
<h3>{{ msg.title }}</em></h3>
<div class="toolbar">
{% if write %}
<span class="toolbar-item">
<button class="toolbar-button" href="{#{ 'create_dir' }#}">
<img src="{{ asset('icons/mkdir.svg') }}" width="32" height="32" alt="create-icon"/>
<button class="toolbar-button" onclick="dirCreateDialog('{{ url }}');">
<img class="icon-directory-new" width="32" height="32" alt="create-icon"/>
</button>
</span>
<span class="toolbar-item">
<button class="toolbar-button" href="{#{ 'upload_file' }#}">
<img alt="upload-icon" width="32" height="32" src="{{ asset('icons/upload.svg') }}"/>
<button class="toolbar-button" {# href="dirUploadDialog('{{ url }}');" #}>
<img class="icon-upload" alt="icon-upload" width="32" height="32"/>
</button>
</span>
{% endif %}
</div>
<table class="full-width"><!-- Directory Index -->
<tr>
<th class="td-color shrink-to-fit"><a href="{{ sort_url.type }}"><img class="list-icon icon-empty" alt="[icon]" /></a></th>
<th class="td-color fullwidth left"><a href="{{ sort_url.name }}">{{ msg.filename }}</a></th>
<th class="td-color shrink-to-fit left"></th>
<th class="td-color left"><a href="{{ sort_url.size }}">{{ msg.filesize }}</a></th>
<th class="td-color left"><a href="{{ sort_url.date }}">{{ msg.mtime }}</a></th>
<table class="full-width border-collapse"><!-- Directory Index -->
<tr style="background-color:white;">
<th class="shrink-to-fit"><a href="{{ sort_url.type }}"><img class="list-icon icon-empty" alt="[icon]" /></a></th>
<th class="fullwidth left"><a href="{{ sort_url.name }}">{{ msg.filename }}</a></th>
<th class="shrink-to-fit left"></th>
<th class="left"><a href="{{ sort_url.size }}">{{ msg.filesize }}</a></th>
<th class="left"><a href="{{ sort_url.date }}">{{ msg.mtime }}</a></th>
</tr>
<tr><td colspan="5"><strong><hr></strong></td></tr>
{% if parent_url %}
<tr>
<td><img class="list-icon icon-back" alt="[icon]"/></td>
<tr class="tr-border-bottom">
<td><a href="{{ parent_url }}"><img class="list-icon icon-back" alt="[icon]"/></a></td>
<td><a href="{{ parent_url }}">Back</a></td>
<td><img class="list-icon icon-empty" alt="[icon]"/></td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
{% endif %}
{% for entry in dir_entries %}
<tr>
<td><img class="list-icon {{ entry.icon }}" alt="[icon]" width="24" height="24" /></td>
<tr class="tr-border-bottom">
<td><img class="list-icon {{ entry.icon }}" alt="[icon]" width="20" height="20" /></td>
<td><a href="{{ entry.href }}">{{ entry.name }}</a></td>
<td>
{% if entry.delete %}
<a href="{{ entry.delete }}"<img class="list-icon icon-delete" alt="[icon]" /></a>
<button class="toolbar-button" onclick="fileDeleteDialog('{{ url }}','{{ entry.name }}');"><img class="list-icon icon-delete" alt="[icon]" /></button>
{% else %}
<img class="list-icon icon-empty" alt="[icon]" />
{% endif %}
@ -52,7 +53,78 @@
<td class="shrink-to-fit">{{ entry.display_mtime }}</td>
</tr>
{% endfor %}
<tr><td colspan="5"><strong><hr></strong></td></tr>
</table>
<dialog id="dir-create-dialog" style="width:420;position:fixed;left:calc(30%-220px);top:30%;">
<h4>{{ msg.mkdirdialog.title }}</h4>
<p>{{ msg.mkdirdialog.message }}</p>
<form>
<p>
<input id="dir-create-input" class="full-width" type="text" required />
</p>
<p class="right">
<button onclick="dirCreateDialogApply();">{{ msg.mkdirdialog.button_create }}</button>
<button onclick="dirCreateDialogClose();">{{ msg.mkdirdialog.button_close }}</button>
</p>
</form>
</dialog>
<dialog id="file-delete-dialog" style="width:420px;position:fixed;left:calc(50%-220px);top:30%;">
<h4>{{ msg.deletedialog.title }}</h4>
<p>{{ msg.deletedialog.message|raw }}</p>
<form>
<p>
<input id="file-delete-input" class="full-width" type="text" required />
</p>
<p class="right">
<button onclick="fileDeleteDialogApply();">{{ msg.deletedialog.button_delete }}</button>
<button onclick="fileDeleteDialogClose();">{{ msg.deletedialog.button_close }}</button>
</p>
</form>
</dialog>
<script>
var dir_create_url='';
var file_delete_basename='';
var file_delete_url='';
function fileDeleteDialog(url,basename)
{
file_delete_basename=basename;
var dialog = document.getElementById("file-delete-dialog");
document.getElementById("file-delete-name").textContent=basename;
dialog.showModal();
}
function fileDeleteDialogClose()
{
let dialog = document.getElementById("file-delete-dialog");
dialog.close();
}
function fileDeleteDialogApply(event)
{
let dialog = document.getElementById('file-delete-dialog');
let input = document.getElementById('file-delete-input')
let input_value = input.value;
if (input_value === file_delete_basename) {
console.log("basename matches");
dialog.close();
} else {
console.log("No match");
input.value="";
dialog.showModal();
}
}
function dirCreateDialog(url) {
dir_create_url = url;
let dialog = document.getElementById('dir-create-dialog');
dialog.showModal();
}
</script>
{% endblock %}

View File

@ -4,3 +4,9 @@ directory:
mtime: 'Zuletzt geändert'
filesize: Größe
title: 'Index für {url}'
delete-dialog:
title: "Datei löschen"
message: 'Wenn du wirklich die asugewählte Datei löschen willst, gib <em id="file-delete-name"></em> in das untere Feld ein.'
button:
delete: Löschen
close: Abbrechen

View File

@ -1,6 +1,12 @@
directory:
timefmt: 'Y.d.m H.i.s'
filename: 'Filename'
filename: Filename
mtime: 'Last changed'
filesize: 'Size'
filesize: Size
title: 'Index for {url}'
delete-dialog:
title: 'Delete file'
message: 'If you really want to delete the file or directory, type <em id=f"ile-delete-name"></em> into the field below!'
button:
delete: Delete
close: Close