-
Notifications
You must be signed in to change notification settings - Fork 0
/
html.rs
145 lines (134 loc) · 5 KB
/
html.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
use crate::db;
use crate::models::List;
use maud::{html, Markup, DOCTYPE};
pub fn edit_card(card: db::Card) -> Markup {
let card_id = card.id;
let id = format!("card-{card_id}");
html! {
li.card.edit
draggable="false"
id=(id)
hx-include="this"
{
input type="hidden" name="card-id" value=(card.id) {}
textarea name="title" autofocus
hx-put=(format!("/card/edit/{card_id}"))
hx-target=(format!("#{id}"))
hx-trigger="keydown[keyCode==13&&!shiftKey]" { (card.title) }
div.center-two {
button hx-get=(format!("/card/{card_id}")) hx-target=(format!("#{id}")) { "❌" }
button hx-put=(format!("/card/edit/{card_id}")) hx-target=(format!("#{id}")) { "✅️" }
}
}
}
}
pub fn make_card(card: db::Card) -> Markup {
let id = format!("card-{}", card.id);
html! {
li.card.regular
draggable="true"
id=(id)
hx-include="this"
_="
on dragstart add .no-pointer-events to <.list>*/> when it is not me
// add .no-pointer-events to the children of .list when it is not me
then call event.dataTransfer.setData('text/plain', me.id)
on drop or dragend remove .no-pointer-events from <.list>*/>
then remove .hovered from .list
// remove .no-pointer-events from .no-pointer-events
"
{
input type="hidden" name="card-id" value=(card.id) {}
span { (card.title) }
div {
button hx-get=(format!("/card/edit/{}", card.id)) hx-target=(format!("#{id}")) { "🖊️" }
button.remove hx-delete="/card" hx-target="#board" { "❌" }
}
}
}
}
pub fn make_list(list: List) -> Markup {
let id = list.id();
html! {
ul.list id=(id) _="
on dragover or dragenter halt the event
remove .hovered from .list then add .hovered to me
on dragleave if event.target is me and event.fromElement.parentElement is not me
remove .hovered from me
end
on drop remove .hovered from me
get event.dataTransfer.getData('text/plain') then set card to #{it}
if card exists then
call determinePlacement(event, card) then set placement to it
if placement exists then
put placement.idx into #moved-new-position.value
if placement.placeBefore then put card before placement.closestLi
else put card after placement.closestLi end
else
put card at the end of me
put '-1' into #moved-new-position.value
end
put strip_id(card.id) into #moved-card-id.value
put strip_id(me.id) into #moved-to-list-id.value
send cardmoved to #move-card
end
"
{
h2 class="list-title" { (list.title) }
@for card in list.cards {
(make_card(card))
}
button.new-card _=(format!("on click toggle .hidden on .new-card in #{id}")) { "+ New card" }
form.hidden.new-card {
input type="hidden" name="list-id" value=(list.id) {}
textarea name="title" placeholder="Title" {}
div.center-two {
button _=(format!("on click toggle .hidden on .new-card in #{id}")) { "❌" }
button hx-post="/card" hx-target=(format!("#{id}")) { "✅️" }
}
}
}
}
}
pub fn make_board(lists: Vec<List>) -> Markup {
html! {
div #board {
@for list in lists {
(make_list(list))
}
form.hidden id="move-card" hx-post="/card/move" hx-target="#board" hx-trigger="cardmoved" {
input type="text" id="moved-card-id" name="card-id" value="" {}
input type="text" id="moved-to-list-id" name="to-list-id" value="" {}
input type="text" id="moved-new-position" name="new-position" value="" {}
}
}
}
}
pub fn base(board_title: String, lists: Vec<List>) -> Markup {
html! {
(DOCTYPE)
html {
head {
meta charset="utf-8";
meta name="viewport" content="width=device-width,initial-scale=1.0";
meta name="htmx-config" content=r#"{"defaultSwapStyle":"outerHTML"}"#r;
title { (format!("Board - {board_title}")) }
link rel="stylesheet" type="text/css" href="/static/index.css";
script src="/static/placement.js" {};
script src="/static/DragDropTouch.js" {};
script type="text/hyperscript" {
"
def strip_id(s)
return s.split('-').pop()
"
};
script src="https://unpkg.com/[email protected]" {};
script src="https://unpkg.com/[email protected]" {};
}
body {
h1 { (board_title) }
(make_board(lists))
}
}
}
}