implement action buttons

This commit is contained in:
Starbeamrainbowlabs 2024-07-13 03:34:51 +01:00
parent 0328fbe90c
commit 42673d9db2
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
6 changed files with 118 additions and 6 deletions

2
.gitignore vendored
View file

@ -1,5 +1,5 @@
*.html *.html
!src/*.html !src/**/*.html
# Created by https://www.toptal.com/developers/gitignore/api/git,node # Created by https://www.toptal.com/developers/gitignore/api/git,node
# Edit at https://www.toptal.com/developers/gitignore?templates=git,node # Edit at https://www.toptal.com/developers/gitignore?templates=git,node

View file

@ -50,7 +50,7 @@ for(let txt of tqdm(txts, { total: txts.length })) {
continue; continue;
} }
const result = await throttled(txt, false); // bool is whether we're pretend or not - i.e. not making anthropic/claude api calls const result = await throttled(txt, true); // bool is whether we're pretend or not - i.e. not making anthropic/claude api calls
result.i = i; result.i = i;
console.log(result); console.log(result);

View file

@ -8,8 +8,9 @@ import { NightInk } from 'nightink';
// HACK: Make sure __dirname is defined when using es6 modules. I forget where I found this - a PR with a source URL would be great! // HACK: Make sure __dirname is defined when using es6 modules. I forget where I found this - a PR with a source URL would be great!
const __dirname = import.meta.url.slice(7, import.meta.url.lastIndexOf("/")); const __dirname = import.meta.url.slice(7, import.meta.url.lastIndexOf("/"));
const template = fs.readFileSync(path.join(__dirname, `../template.html`), `utf-8`); const template = fs.readFileSync(path.join(__dirname, `../static/template.html`), `utf-8`);
const css = fs.readFileSync(path.join(__dirname, `../index.css`), `utf-8`); const css = fs.readFileSync(path.join(__dirname, `../static/index.css`), `utf-8`);
const js = fs.readFileSync(path.join(__dirname, `../static/index.js`), `utf-8`);
export default function(objs) { export default function(objs) {
let total = objs.reduce((acc, obj) => acc + obj.paid, 0); let total = objs.reduce((acc, obj) => acc + obj.paid, 0);
@ -18,7 +19,8 @@ export default function(objs) {
const values = { const values = {
objs, objs,
total, total,
css css,
js
}; };
console.debug(`VALUES`, values); console.debug(`VALUES`, values);

View file

@ -33,7 +33,17 @@ tr:hover {
background-color: #e8e8e8; background-color: #e8e8e8;
} }
.button {
cursor: pointer;
}
.align-right { .align-right {
text-align: right; text-align: right;
}
@media print {
.noprint {
display: none;
}
} }

93
src/static/index.js Normal file
View file

@ -0,0 +1,93 @@
function handle_remove_row(event) {
const el_tr = event.target.closest("tr");
if (el_tr === null) {
console.warn(`Click on .button.remove-row, but no tr could be found`);
return false;
}
el_tr.remove(); // Woah, we don't hafta node.parentNode.removeChild(node) anymore~!
}
function handle_add_row(event) {
const el_tr = event.target.closest("tr");
const el_new = document.createElement("tr");
const highest_number = [...document.querySelectorAll(".index")]
.map(el => { console.log(el, parseInt(el.textContent)); return parseInt(el.textContent); })
.filter(item => !isNaN(item))
.reduce((acc, next) => Math.max(acc, next), 0);
const limit = [...document.querySelector("tr").childNodes]
.filter(el => !(el instanceof Text))
.length;
for(let i = 0; i <= limit; i++) {
const el_next = document.createElement("td");
if(i == limit) {
el_next.classList.add("actions", "noprint");
const el_source = document.querySelector(".actions");
for(const el_child of [...el_source.childNodes]) {
const el_copy = el_child.cloneNode(true);
if(!(el_child instanceof Text)) {
switch(el_copy.getAttribute("class").trim()) {
case "button remove-row":
el_copy.addEventListener("click", handle_remove_row);
el_copy.addEventListener("touchend", handle_remove_row);
break;
case "button add-row":
el_copy.addEventListener("click", handle_add_row);
el_copy.addEventListener("touchend", handle_add_row);
}
}
el_next.append(el_copy);
}
}
else {
let txt = "placeholder";
switch (i) {
case 0:
txt = highest_number + 1;
el_next.classList.add("index");
break;
case 1:
txt = (new Date()).toISOString().split(`T`)[0];
break;
case 4:
case 5:
case 6:
txt = "0.00";
break;
}
el_next.append(document.createTextNode(txt));
}
el_next.setAttribute("contenteditable", "true");
el_new.append(el_next);
}
el_tr.after(el_new);
rewrite_indices();
}
function rewrite_indices() {
const els = [...document.querySelectorAll(".index")];
for(const i in els) {
els[i].textContent = `${i}`;
}
}
window.addEventListener("load", () => {
console.log(`BEGIN`);
const els_remove = [...document.querySelectorAll(".button.remove-row")];
console.log(els_remove);
for (const el of els_remove) {
el.addEventListener("click", handle_remove_row);
el.addEventListener("touchend", handle_remove_row);
}
const els_add = [...document.querySelectorAll(".button.add-row")];
for(const el of els_add) {
el.addEventListener("click", handle_add_row);
el.addEventListener("touchend", handle_add_row);
}
});

View file

@ -23,13 +23,17 @@
<tbody> <tbody>
{#each objs} {#each objs}
<tr> <tr>
<td contenteditable>{{i}}</td> <td contenteditable class="index">{{i}}</td>
<td contenteditable>{{date}}</td> <td contenteditable>{{date}}</td>
<td contenteditable>{{category}}</td> <td contenteditable>{{category}}</td>
<td contenteditable>{{item_name}}</td> <td contenteditable>{{item_name}}</td>
<td contenteditable>{{net}}</td> <td contenteditable>{{net}}</td>
<td contenteditable>{{vat}}</td> <td contenteditable>{{vat}}</td>
<td contenteditable>{{paid}}</td> <td contenteditable>{{paid}}</td>
<td class="actions noprint">
<span class="button remove-row"></span>
<span class="button add-row"></span>
</td>
</tr> </tr>
{#endeach} {#endeach}
</tbody> </tbody>
@ -44,5 +48,8 @@
<style> <style>
{css} {css}
</style> </style>
<script>
{js}
</script>
</body> </body>
</html> </html>