mkdir dialog in drive pages
This commit is contained in:
parent
7d362f0708
commit
38f91dd890
3 changed files with 119 additions and 25 deletions
|
@ -18,6 +18,7 @@ pub const routes = .{
|
|||
controllers.apiEndpoint(cluster.communities.create.page),
|
||||
controllers.apiEndpoint(cluster.communities.create.submit),
|
||||
controllers.apiEndpoint(drive.details),
|
||||
controllers.apiEndpoint(drive.form),
|
||||
};
|
||||
|
||||
const static = struct {
|
||||
|
@ -231,6 +232,31 @@ const user_details = struct {
|
|||
};
|
||||
|
||||
const drive = struct {
|
||||
const dir_tmpl = @embedFile("./web/drive/directory.tmpl.html");
|
||||
fn servePage(req: anytype, res: anytype, srv: anytype) !void {
|
||||
const info = try srv.driveGet(req.args.path);
|
||||
defer util.deepFree(srv.allocator, info);
|
||||
|
||||
var breadcrumbs = std.ArrayList([]const u8).init(srv.allocator);
|
||||
defer breadcrumbs.deinit();
|
||||
|
||||
var iter = util.PathIter.from(req.args.path);
|
||||
while (iter.next()) |p| {
|
||||
std.log.debug("breadcrumb: {s}", .{p});
|
||||
try breadcrumbs.append(if (p.len != 0) p else continue);
|
||||
}
|
||||
|
||||
switch (info) {
|
||||
.dir => |dir| try res.template(.ok, srv, dir_tmpl, .{
|
||||
.dir = dir,
|
||||
.breadcrumbs = breadcrumbs.items,
|
||||
.mount_path = req.mount_path,
|
||||
.base_drive_path = "drive",
|
||||
}),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
const details = struct {
|
||||
pub const path = "/drive/:path*";
|
||||
pub const method = .GET;
|
||||
|
@ -239,29 +265,41 @@ const drive = struct {
|
|||
path: []const u8,
|
||||
};
|
||||
|
||||
pub const dir_tmpl = @embedFile("./web/drive/directory.tmpl.html");
|
||||
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
|
||||
try servePage(req, res, srv);
|
||||
}
|
||||
};
|
||||
|
||||
const form = struct {
|
||||
pub const path = "/drive/:path*";
|
||||
pub const method = .POST;
|
||||
|
||||
pub const Args = struct {
|
||||
path: []const u8,
|
||||
};
|
||||
|
||||
const Action = enum {
|
||||
mkcol,
|
||||
};
|
||||
|
||||
pub const Body = struct {
|
||||
action: Action,
|
||||
data: union(Action) {
|
||||
mkcol: struct {
|
||||
name: []const u8,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
|
||||
const info = try srv.driveGet(req.args.path);
|
||||
defer util.deepFree(srv.allocator, info);
|
||||
if (req.body.action != req.body.data) return error.BadRequest;
|
||||
switch (req.body.data) {
|
||||
.mkcol => |data| {
|
||||
_ = try srv.driveMkdir(req.args.path, data.name);
|
||||
// TODO
|
||||
|
||||
var breadcrumbs = std.ArrayList([]const u8).init(srv.allocator);
|
||||
defer breadcrumbs.deinit();
|
||||
|
||||
var iter = util.PathIter.from(req.args.path);
|
||||
while (iter.next()) |p| {
|
||||
std.log.debug("breadcrumb: {s}", .{p});
|
||||
try breadcrumbs.append(if (p.len != 0) p else continue);
|
||||
}
|
||||
|
||||
switch (info) {
|
||||
.dir => |dir| try res.template(.ok, srv, dir_tmpl, .{
|
||||
.dir = dir,
|
||||
.breadcrumbs = breadcrumbs.items,
|
||||
.mount_path = req.mount_path,
|
||||
.base_drive_path = "drive",
|
||||
}),
|
||||
else => unreachable,
|
||||
try servePage(req, res, srv);
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -17,6 +17,28 @@
|
|||
</li>
|
||||
{/for =}
|
||||
</ol>
|
||||
|
||||
<div class="popup-buttons">
|
||||
<div class="popup" id="mkdir">
|
||||
<a class="button popup-open" href="#mkdir">
|
||||
<span class="fa-stack small">
|
||||
<i class="fa-solid fa-stack-2x fa-folder"></i>
|
||||
<i class="fa-solid fa-stack-1x fa-inverse fa-plus"></i>
|
||||
</span>
|
||||
</a>
|
||||
<a class="button popup-close" href="#">
|
||||
<i class="fa-solid fa-xmark"></i>
|
||||
</a>
|
||||
<form class="popup-dialog" method="post" enctype="multipart/form-data">
|
||||
<label>
|
||||
<div>Create Directory</div>
|
||||
<input type="text" name="mkcol.name" /> <!-- TODO: Rename this form param -->
|
||||
</label>
|
||||
<input type="hidden" name="action" value="mkcol" />
|
||||
<button type="submit">Create</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<table class="directory-listing">
|
||||
{#for .dir.children.? |$child| =}
|
||||
<tr>
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400;500;600;700&display=swap');
|
||||
|
||||
* {
|
||||
--theme-color: #713c8c;
|
||||
--theme-color-highlight: #9b52bf;
|
||||
--theme-accent: #713c8c;
|
||||
--theme-accent-highlight: #9b52bf;
|
||||
--theme-accent-contrast: #fff;
|
||||
--theme-fg-color: #000;
|
||||
--theme-bg-color: #fff;
|
||||
|
||||
--fa-inverse: var(--theme-accent);
|
||||
}
|
||||
|
||||
body {
|
||||
|
@ -92,7 +97,7 @@ form .textinput input:focus-visible{
|
|||
outline: none;
|
||||
}
|
||||
form .textinput:focus-within {
|
||||
outline: solid 2px var(--theme-color);
|
||||
outline: solid 2px var(--theme-accent);
|
||||
}
|
||||
form .textinput span.prefix {
|
||||
user-select: none;
|
||||
|
@ -124,14 +129,14 @@ button, a.button {
|
|||
border-radius: 10px;
|
||||
border: none;
|
||||
color: #fff;
|
||||
background-color: var(--theme-color);
|
||||
background-color: var(--theme-accent);
|
||||
font-weight: bold;
|
||||
transition: background-color 0.2s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover, a.button:hover {
|
||||
background-color: var(--theme-color-highlight);
|
||||
background-color: var(--theme-accent-highlight);
|
||||
}
|
||||
|
||||
.user-profile img.banner {
|
||||
|
@ -228,3 +233,32 @@ button:hover, a.button:hover {
|
|||
justify-content: flex-end;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.drive .buttons a[href="#mkdir"] span.fa-stack {
|
||||
font-size: 8pt;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.drive .buttons a[href="#mkdir"] .fa-plus {
|
||||
position: relative;
|
||||
bottom: -1px;
|
||||
}
|
||||
|
||||
.popup :is(.popup-close, .popup-dialog) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.popup:target .popup-open {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.popup:target :is(.popup-close, .popup-dialog) {
|
||||
display: unset;
|
||||
}
|
||||
|
||||
.popup:target .popup-dialog {
|
||||
position: absolute;
|
||||
color: var(--theme-fg-color);
|
||||
background-color: var(--theme-bg-color);
|
||||
border: 1px solid var(--theme-accent);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue