home · contact · privacy
Add foreign key restraints, expand and fix tests, add deletion and forking.
[misc] / todo_templates / day_todos.html
1 {% extends 'base.html' %}
2
3
4
5 {% block css %}
6 td.checkbox { text-align: center; }
7 td { vertical-align: middle; }
8 td button { padding: 0em; }
9 th.centered { text-align: center; }
10 ul { padding-left: 1.5em; margin: 0; }
11 details > summary.todo {
12     list-style-type: '    ';
13 }
14 details > summary.has_dependers {
15     list-style-type: '[+]:';
16 }
17 details[open] > summary.has_dependers {
18     list-style-type: '[▼]:';
19 }
20 details > summary.has_deps::after {
21     content: ':[+]';
22 }
23 details[open] > summary.has_deps::after {
24     content: ':[▼]';
25 }
26 table.undone_todos tr.deps_undone {
27     background-color: #cccccc;
28 }
29 details.adoptables {
30     margin-bottom: 1em;
31 }
32 details.adoptables summary span {
33     background-color: #cccccc; 
34 }
35 table.undone_todos tr td {
36     border-bottom: 1px dotted black;
37 }
38 td.left { text-align: left; }
39 td.unbreakable { white-space: nowrap; }
40 {% endblock %}
41
42
43
44 {% macro todo_title_expandable(todo, show_deps_doneness, ignore=0) %}
45 {% if todo.has_dependers or todo.has_deps %}
46 <details>
47 <summary class="todo {% if todo.has_dependers %}has_dependers{% endif %} {% if todo.has_deps %}has_deps{% endif %}">
48 {% else %}
49 &nbsp;&nbsp;&nbsp;&nbsp;
50 {% endif %}
51 <a href="todo?id={{todo.id_}}">{{todo.title|e}}</a>
52 {% if todo.has_dependers or todo.has_deps %}
53 </summary>
54 {% if todo.has_dependers %}
55 dependers:
56 <ul>
57 {% for path in todo.depender_paths %}
58 <li>{% for depender_todo in path %}<a href="todo?id={{depender_todo.id_}}">{{ depender_todo.title|e }}</a>{% if not loop.last %}:{% endif %}{% endfor %}
59 {% endfor %}
60 </ul>
61 {% endif %}
62 {% if todo.has_deps %}
63 depends on:
64 <ul>
65 {% for dep_todo in todo.deps %}
66 <li>
67 {% if show_deps_doneness == true %}{{ macros.doneness_string(dep_todo) }}{% endif %}
68 <a href="todo?id={{dep_todo.id_}}">{{ dep_todo.title|e }}</a>{% if dep_todo.has_deps %}:+{% endif %}
69 {% endfor %}
70 </ul>
71 {% endif %}
72 </details>
73 {% endif %}
74 {% endmacro %}
75
76
77
78 {% macro todo_title_as_tree_node(todo, indent) %}
79 {% for i in range(indent-1) %}&nbsp; &nbsp;{% endfor %}
80 {% if indent>0 %}&nbsp;+{% endif %}
81 {% if todo.been_observed %}({% endif %}<a href="todo?id={{todo.id_}}">{{todo.title}}</a>{% if todo.been_observed %}){% endif %}
82 {% endmacro %}
83
84
85
86 {% macro draw_undone_todo_row(todo, title_drawer, indent_or_doneness) %}
87 <tr {% if todo.deps_done == false %}class="deps_undone"{% endif %}>
88 {% if todo.been_observed %}
89 <td class="checkbox"><input type="checkbox" disabled /></td>
90 <td class="number left"><input type="number" value="{{todo.day_effort}}" size=7 disabled /></td>
91 <td class="number"><input type="number" value="{{todo.importance}}" size=7 disabled /></td>
92 <td>
93 {{ title_drawer(todo, indent_or_doneness ) }}
94 </td>
95 <td><input value="{{todo.comment|e}}" size=100 disabled /></td>
96 {% else %}
97 <input name="todo_id" value="{{todo.id_}}" type="hidden" >
98 <td class="checkbox">
99 <input name="done" type="checkbox" value="{{todo.id_}}" {% if todo.done %}checked{% endif %} {% if todo.deps_done == false %}disabled{% endif %}>
100 </td>
101 <td class="number unbreakable">
102 <input class="effort_input" name="effort" type="number" step=0.1 size=7 value="{% if todo.day_effort is not none %}{{todo.day_effort}}{% endif %}" placeholder={{"%.1f"|format(todo.task.default_effort.then)}} >
103 </td>
104 <td class="number">
105 <input name="importance" type="number" step=0.1 size=7 value={{todo.importance}} } >
106 </td>
107 <td>
108 {{ title_drawer(todo, indent_or_doneness) }}
109 </td>
110 <td>
111 <input name="effort_comment" type="text" size=100 value="{{todo.comment|e}}" />
112 </td>
113 {% endif %}
114 </tr>
115 {% endmacro %}
116
117
118
119 {% macro draw_done_todo_row(todo, title_drawer, indent) %}
120 <tr>
121 <td class="number">{{ '{:4.1f}'.format(todo.effort_at_selected_date) }}</td>
122 <td class="number">{{ '{:4.1f}'.format(todo.effort_at_selected_date + todo.dep_efforts) }}</td>
123 <td>
124 {{ title_drawer(todo, indent) }}
125 </td>
126 </td>
127 </td>
128 <td>{{ todo.comment }}</td>
129 </tr>
130 {% endmacro %}
131
132
133
134 {% macro draw_todo_rows(todos, is_tree_shaped, todo_row_drawer, indent, show_deps_doneness=false) %}
135 {% for todo in todos %}
136 {% if is_tree_shaped %}
137 {{ todo_row_drawer(todo, todo_title_as_tree_node, indent) }}
138 {% if not todo.been_observed and todo.deps %}
139 {{ draw_todo_rows(todo.deps, is_tree_shaped, todo_row_drawer, indent+1) }}
140 {% endif %}
141 {% else %}
142 {{ todo_row_drawer(todo, todo_title_expandable, show_deps_doneness) }}
143 {% endif %}
144 {{ todo.observe() }}
145 {% endfor %}
146 {% endmacro %}
147
148
149
150 {% block content %}
151 <h3>day todos</h3>
152
153 <form id="form_to_watch" action="day_todos" method="POST">
154 {% include 'tagfilters.html' %}
155 <br />
156 <input id="filter_button" type="submit" name="filter" value="filter" />
157 <p>
158 | <a href="day_todos?date={{prev_date}}">prev</a> | {{day.date}} | <a href="day_todos?date={{next_date}}">next</a> | 
159 comment: <input name="day_comment" value="{{day.comment|e}}">
160 <input class="update" type="submit" name="update" value="update">
161 <input type="hidden" name="date" value="{{day.date}}" />
162 | show as {% if is_tree_shaped %}<a href="?tree=0">flat</a>|<b>tree</b>{% else %}<b>flat</b>|<a href="?tree=1">tree</a>{% endif %}
163 </p>
164
165 <h3>undone</h3>
166 <p>
167 task quick-add: <input name="choose_task" size=50 list="tasks" autocomplete="off">
168 {{ macros.parenthood_selector(parenthood) }}
169 </p>
170 {{ macros.datalist_tasks(all_tasks, with_weight=true) }}
171
172 {% if adoptable_past_todos %}
173 <details class="adoptables">
174 <summary><span>there are adoptable/unfinished past todos ({{adoptable_past_todos|count}})</span></summary>
175 <table class="alternating">
176 <tr>
177 <th>adopt?</th><th>date</th><th>title</th><th>comment</th>
178 </tr
179 {% for todo in adoptable_past_todos %}
180 <tr>
181 <td class="checkbox"><input name="choose_todo" type="checkbox" value="{{todo.id_}}"></td>
182 <td>{{todo.earliest_date}}</td>
183 <td><a href="todo?id={{todo.id_}}">{{todo.title|e}}</a></td>
184 <td>{{todo.comment|e}}</td>
185 </tr>
186 {% endfor %}
187 </table>
188 </details>
189 {% endif %}
190
191 {% if undone_todos %} 
192 <table class="undone_todos">
193 <tr>
194 {{ macros.sort_head(undone_sort, "sort_done", "done", "undone_sort") }}
195 {{ macros.sort_head(undone_sort, "default_effort", "effort", "undone_sort") }}
196 {{ macros.sort_head(undone_sort, "importance", "importance", "undone_sort") }}
197 {{ macros.sort_head(undone_sort, "title", "todo", "undone_sort") }}
198 <th>comment</th>
199 </tr>
200 {{ draw_todo_rows(undone_todos, is_tree_shaped, draw_undone_todo_row, 0, show_deps_doneness=true) }}
201 {% endif %}
202
203 </table>
204 <input id="update_button" class="update" type="submit" name="update" value="update">
205 </form>
206
207 {% if done_todos %}
208 <h3>done</h3>
209 <table class="alternating">
210 <tr>
211 {{ macros.sort_head(done_sort, "effort_at_selected_date", "single<br />effort", "done_sort") }}
212 {{ macros.sort_head(done_sort, "family_effort", "family<br />effort", "done_sort") }}
213 {{ macros.sort_head(done_sort, "title", "todo", "done_sort") }}
214 <th>comment</th>
215 </tr>
216 {{ draw_todo_rows(done_todos, is_tree_shaped, draw_done_todo_row, 0) }}
217 </table>
218 {% endif %}
219
220 {% include 'watch_form.html' %}
221 <script>
222 inputs_to_ignore += ['parenthood'];
223
224 var effort_inputs = document.getElementsByClassName("effort_input");
225 for (let i = 0; i < effort_inputs.length; i++) {
226     let input = effort_inputs[i];
227     let button = document.createElement('button');
228     button.innerHTML = '+' + parseFloat(input.placeholder).toFixed(1);
229     button.onclick = function(event) {
230         event.preventDefault();
231         if (input.value) {
232             input.value = parseFloat(input.value) + parseFloat(input.placeholder);
233         } else {
234             input.value = parseFloat(input.placeholder);
235         }
236         input.value = parseFloat(input.value).toFixed(1);
237         changes_to_commit = true; 
238     };
239     input.insertAdjacentElement('afterend', button);
240 }
241 </script>
242 {% endblock %}