import {LitElement, html} from './lit-core.min.js'; import * as tfrpc from '/static/tfrpc.js'; class TodosElement extends LitElement { static get properties() { return { lists: {type: Array}, }; } constructor() { super(); this.lists = []; let self = this; tfrpc.rpc .todo_get_all() .then(function (lists) { self.lists = lists; }) .catch(function (error) { console.log(error); }); } async new_list() { await tfrpc.rpc.todo_add('new list'); await this.refresh(); } async refresh() { this.lists = await tfrpc.rpc.todo_get_all(); } render() { return html`
${this.lists.map( (x) => html` ` )}
`; } } class TodoListElement extends LitElement { static get properties() { return { name: {type: String}, items: {type: Array}, editing: {type: Number}, editing_name: {type: Boolean}, }; } constructor() { super(); this.items = []; } save() { let self = this; console.log('saving', self.name, self.items); tfrpc.rpc .todo_set(self.name, self.items) .then(function () { console.log('saved', self.name, self.items); }) .catch(function (error) { console.log(error); }); } remove_item(item) { let index = this.items.indexOf(item); this.items = [].concat( this.items.slice(0, index), this.items.slice(index + 1) ); this.save(); } handle_check(event, item) { item.x = event.srcElement.checked; this.save(); } input_blur(item) { this.save(); this.editing = undefined; } input_change(event, item) { item.text = event.srcElement.value; } input_keydown(event, item) { if (event.key === 'Enter' || event.key === 'Escape') { item.text = event.srcElement.value; this.editing = undefined; this.save(); } } updated() { let edit = this.renderRoot.getElementById('edit'); if (edit) { edit.select(); } } render_item(item) { let index = this.items.indexOf(item); let self = this; if (index === this.editing) { return html`
self.handle_check(x, item)}> self.input_change(event, item)} @keydown=${(event) => self.input_keydown(event, item)} @blur=${(x) => self.input_blur(item)}> self.remove_item(item)} style="cursor: pointer">❎
`; } else { return html`
self.handle_check(x, item)}> (self.editing = index)}>${item.text || '(empty)'} `; } } add_item() { this.items = [].concat(this.items || [], [{text: 'new item'}]); this.editing = this.items.length - 1; this.save(); } async remove_list() { if (confirm(`Are you sure you want to remove "${this.name}"?`)) { await tfrpc.rpc.todo_remove(this.name); this.dispatchEvent(new Event('change')); } } rename(new_name) { let self = this; return tfrpc.rpc .todo_rename(this.name, new_name) .then(function () { self.dispatchEvent(new Event('change')); self.editing_name = false; }) .catch(function (error) { console.log(error); alert(error.message); self.editing_name = false; }); } name_blur(new_name) { this.rename(new_name); } name_keydown(event, item) { let self = this; if (event.key == 'Enter' || event.key === 'Escape') { let new_name = event.srcElement.value; this.rename(new_name); } } render() { let self = this; let name = this.editing_name ? html` self.name_keydown(event)} @blur=${(event) => self.name_blur(event.srcElement.value)} value=${this.name}>` : html`

(this.editing_name = true)}>${this.name}

`; return html`
${name} ${(this.items || []) .filter((item) => !item.x) .map((x) => self.render_item(x))} ${(this.items || []) .filter((item) => item.x) .map((x) => self.render_item(x))}
`; } } customElements.define('tf-todo-list', TodoListElement); customElements.define('tf-todos', TodosElement);