taskai-cli 1.4.3__tar.gz → 1.5.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/.gitignore +1 -0
- taskai_cli-1.5.2/.readthedocs.yaml +13 -0
- taskai_cli-1.5.2/DEVLOG.md +558 -0
- taskai_cli-1.5.2/DEVPLAN.md +402 -0
- taskai_cli-1.5.2/PKG-INFO +136 -0
- taskai_cli-1.5.2/README.md +123 -0
- taskai_cli-1.5.2/docs/conf.py +12 -0
- taskai_cli-1.5.2/docs/index.rst +8 -0
- taskai_cli-1.5.2/docs/requirements.txt +3 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/pyproject.toml +4 -2
- taskai_cli-1.5.2/taskai/browser.py +78 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/taskai/cli.py +79 -81
- taskai_cli-1.5.2/taskai/help_menu.py +68 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/taskai/services/ai.py +42 -13
- taskai_cli-1.5.2/taskai/static/canvas.js +543 -0
- taskai_cli-1.5.2/taskai/static/console.js +53 -0
- taskai_cli-1.5.2/taskai/static/editpanel.js +171 -0
- taskai_cli-1.5.2/taskai/static/index.html +38 -0
- taskai_cli-1.5.2/taskai/static/style.css +220 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/taskai/views.py +21 -7
- taskai_cli-1.4.3/DEVLOG.md +0 -390
- taskai_cli-1.4.3/PKG-INFO +0 -61
- taskai_cli-1.4.3/README.md +0 -50
- taskai_cli-1.4.3/docs/index.md +0 -17
- taskai_cli-1.4.3/mkdocs.yml +0 -1
- taskai_cli-1.4.3/taskai/help_menu.py +0 -35
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/.github/workflows/publish-to-pypi.yml +0 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/scripts/bump_version.py +0 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/taskai/config.py +0 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/taskai/json_dir_database.py +0 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/taskai/models.py +0 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/taskai/services/pomodoro.py +0 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/taskai/services/repair_database.py +0 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/taskai/services/user_setup.py +0 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/test/test_cli.py +0 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/test/test_execution.py +0 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/test/test_json_dir_database.py +0 -0
- {taskai_cli-1.4.3 → taskai_cli-1.5.2}/test/test_view.py +0 -0
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
# 8-18
|
|
2
|
+
|
|
3
|
+
Continued the browser/`canvas.js` work in a later session (DEVLOG is a
|
|
4
|
+
stack now — newest first within a date — so this sits above the earlier
|
|
5
|
+
entries from today):
|
|
6
|
+
|
|
7
|
+
- Console got wired up for real: `POST /api/command` now exists in
|
|
8
|
+
`browser.py` (design: branch on whether the parsed command is `show` —
|
|
9
|
+
`show` never touches `execute_commands`, it's read-only from the
|
|
10
|
+
browser's perspective, it just resolves a target id and returns it as
|
|
11
|
+
`focus` for the frontend to `focusOnNode` on; everything else runs
|
|
12
|
+
through `execute_commands` with stdout captured, always returning the
|
|
13
|
+
fresh full tree). Found a real landmine while building it:
|
|
14
|
+
`Controller.throw_error` calls `sys.exit(-1)`, raising `SystemExit`,
|
|
15
|
+
which `execute_commands`'s own `except Exception` doesn't catch — any
|
|
16
|
+
bad console command would've thrown that straight through the request
|
|
17
|
+
handler. Caught at the server boundary only, `cli.py` untouched. Console
|
|
18
|
+
input now actually POSTs, echoes output, and applies the returned tree.
|
|
19
|
+
- Node labels now wrap up to 3 lines before truncating (was single-line
|
|
20
|
+
truncate only) — `wrapText` in `canvas.js`, refactored `fitText`'s
|
|
21
|
+
trimming logic into a shared `truncateWithEllipsis` helper.
|
|
22
|
+
- `completed` items get a soft green fill/border
|
|
23
|
+
(`STYLE.colors.nodeFill/BorderDone`). Each node also shows its id
|
|
24
|
+
(top-left, small muted gray) and, when set, its `status` (top-right,
|
|
25
|
+
small warm orange, ellipsis-truncated if it'd collide with the id).
|
|
26
|
+
- Tuned double-click focus after it read as too aggressive: scale down
|
|
27
|
+
1.4 → 0.85 (settles slightly zoomed *out*, not in), and it no longer
|
|
28
|
+
centers vertically — lands at 20% down from the top
|
|
29
|
+
(`STYLE.zoom.focusYRatio`) so there's room below to see a focused node's
|
|
30
|
+
children.
|
|
31
|
+
- Built the edit panel (right-side, collapsible, `editpanel.js` +
|
|
32
|
+
`.edit-panel` in `style.css`): collapsed is just a bare `44px` chevron
|
|
33
|
+
button pinned to its own top-left corner (no visible bar), expanded is a
|
|
34
|
+
`320px` white panel. Toggling animates the canvas's width/pan/zoom in
|
|
35
|
+
step with the panel's own 200ms CSS transition (`setRightPanelWidth` in
|
|
36
|
+
`canvas.js`), rescaling zoom in proportion to the width change (not just
|
|
37
|
+
re-panning) so the same amount of graph stays in view instead of getting
|
|
38
|
+
cropped. This required adding real click-to-select on the DAG first
|
|
39
|
+
(`selectedNode` in `canvas.js`, persistent blue border, re-resolved by
|
|
40
|
+
id after every tree refresh so it doesn't silently dangle) — the edit
|
|
41
|
+
panel piggybacks off that selection.
|
|
42
|
+
- Edit panel form: `name`, `description`, `status`, `priority`, `due_by`,
|
|
43
|
+
`completed`, `dependency_ids` ("Depends on"), each typed to match its
|
|
44
|
+
data (text/textarea/number/date/checkbox). No Save button — deliberate:
|
|
45
|
+
every field POSTs `update <id> --<field> <value>` to `/api/command`
|
|
46
|
+
directly. Checkbox sends immediately; everything else debounces 1s per
|
|
47
|
+
field (keyed by item+field) so typing doesn't spam a request per
|
|
48
|
+
keystroke.
|
|
49
|
+
- Confirmed against a throwaway test item (created + deleted, not real
|
|
50
|
+
data) that `name`/`description`/`priority`/`completed` all update
|
|
51
|
+
correctly end to end. `due_by` and `depends_on` don't — both trace to
|
|
52
|
+
`Controller.update_item` never calling `_parse_item_kwargs` the way
|
|
53
|
+
`create_item` does, so `due_by` throws a validation error and
|
|
54
|
+
`depends_on` silently no-ops. Documented in DEVPLAN's known quirks,
|
|
55
|
+
left unfixed on purpose (explicit call: wire the endpoint first, fix
|
|
56
|
+
bugs later).
|
|
57
|
+
|
|
58
|
+
Phase 1 status per the updated DEVPLAN checklist: only dependency/link
|
|
59
|
+
edges (1.4) and console up-arrow history (1.6) remain open. Everything
|
|
60
|
+
else in Phase 1 — tree render, pan/zoom, click-to-select, completed/status
|
|
61
|
+
display, the command endpoint, the edit panel, the console — is done.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
Working with Claude this session. Started a DEVPLAN.md with a roadmap
|
|
66
|
+
(Phase 0: bugfixes, Phase 1: browser UI, Phase 2: AI/aisuite rewrite,
|
|
67
|
+
Phase 3: polish) plus ground rules for how we want to work together.
|
|
68
|
+
|
|
69
|
+
Phase 0 (bugfixes), done:
|
|
70
|
+
- ai.py: the natural-language prompt was being built (with the command
|
|
71
|
+
grammar + task tree baked in) but the actual LLM call sent the raw
|
|
72
|
+
un-instructed prompt instead - fixed.
|
|
73
|
+
- ai.py: `_add_info` (used to build the task-tree context for the AI
|
|
74
|
+
prompt) referenced the wrong loop variable and would throw on the first
|
|
75
|
+
recursive call - fixed.
|
|
76
|
+
- ai.py: the natural-language service parsed the LLM's JSON command list
|
|
77
|
+
but never actually ran it - now it executes each parsed command through
|
|
78
|
+
`execute_commands`, same dispatcher the CLI uses.
|
|
79
|
+
- cli.py: `execute_commands` had a `raise e` ahead of the friendly
|
|
80
|
+
`throw_error` path, so errors always came out as raw tracebacks - removed.
|
|
81
|
+
- views.py: `view_item`/`view_items` called `db.read`/`db.items`, which
|
|
82
|
+
don't exist on `JsonDirectoryDatabase` - fixed to `get_item`/
|
|
83
|
+
`get_item_ids`. Also found and fixed a second bug on the same path:
|
|
84
|
+
`view_items` was passing the whole `TodoItem` object into `view_item`
|
|
85
|
+
instead of its `.id`.
|
|
86
|
+
|
|
87
|
+
Also did a pass on help_menu.py and the AI prompt in ai.py:
|
|
88
|
+
- help_menu.py's command reference was stale (referenced commands/syntax
|
|
89
|
+
that don't exist, missing others that do) - rewrote it to match
|
|
90
|
+
`execute_commands` exactly, including which commands need an id vs.
|
|
91
|
+
accept a name, and the `--field` table that wasn't documented anywhere.
|
|
92
|
+
- Added explicit rules to the AI prompt about not referencing items that
|
|
93
|
+
don't exist yet (create it first), preferring ids over names for the
|
|
94
|
+
commands that need them, and not inventing commands/fields.
|
|
95
|
+
- Removed "list" as a separate concept from both docs - it's a generic
|
|
96
|
+
item tree now. Clarified `create` = new root item, `add` = child of an
|
|
97
|
+
*existing* parent only.
|
|
98
|
+
|
|
99
|
+
Found (not fixed, tracked in DEVPLAN's "known quirks"): `update_item`
|
|
100
|
+
resolves a name to a model object but never unwraps `.id` before handing
|
|
101
|
+
it to the db layer, so `update`/`rename`/`status` only work with numeric
|
|
102
|
+
ids, not names.
|
|
103
|
+
|
|
104
|
+
Browser phase, started on the `browser` branch:
|
|
105
|
+
Already had FastAPI + uvicorn wired up (`task browser` -> launches
|
|
106
|
+
uvicorn on taskai.browser:app) and a canvas.js proof-of-concept
|
|
107
|
+
(hardcoded fake tree, circle nodes, click/hover hit-testing) from an
|
|
108
|
+
earlier session. Decided to build on that instead of the stdlib
|
|
109
|
+
http.server + SVG that DEVPLAN originally sketched, since it already ran
|
|
110
|
+
end to end. Wired it to real data:
|
|
111
|
+
- browser.py: added `GET /api/tree`, reusing the db connection already
|
|
112
|
+
established by importing `taskai.cli` (no second connection).
|
|
113
|
+
- canvas.js: replaced the hardcoded fake tree with `loadTree()`, which
|
|
114
|
+
fetches `/api/tree`, builds the real node tree from `parent_id`/
|
|
115
|
+
`child_ids`, and lays it out with a simple depth-first layout (y from
|
|
116
|
+
depth, x from a running leaf counter, parents centered over children).
|
|
117
|
+
Handles a forest of root items, not just a single root.
|
|
118
|
+
- Verified end to end against the real dev database.
|
|
119
|
+
|
|
120
|
+
Still open for Phase 1: the `/api/command` mutation endpoint, the edit
|
|
121
|
+
menu, the console panel, dependency/link edges, pan/zoom, node coloring.
|
|
122
|
+
Nothing there yet beyond the read-only tree render.
|
|
123
|
+
|
|
124
|
+
DEVPLAN.md now has a full "Project overview" section prepended (data
|
|
125
|
+
model, storage, CLI dispatch, known quirks, dev environment, etc.) so a
|
|
126
|
+
fresh session doesn't need to re-derive all of this by reading the whole
|
|
127
|
+
codebase. Also added a ground rule to keep this DEVLOG updated going
|
|
128
|
+
forward.
|
|
129
|
+
|
|
130
|
+
Kept going on the DAG view (`canvas.js`) in the same session, testing
|
|
131
|
+
live against `task browser` running throughout:
|
|
132
|
+
- Labels no longer overflow the node: truncated with an ellipsis to fit,
|
|
133
|
+
full label shown in a tooltip on hover. Hover also now visibly
|
|
134
|
+
highlights the node — previously tracked but had no effect.
|
|
135
|
+
- Added pan (drag) and zoom (wheel, zooms toward the cursor) via a `view`
|
|
136
|
+
{offsetX, offsetY, scale} object and canvas context transforms, not SVG
|
|
137
|
+
`viewBox` — same reasoning as the earlier canvas-not-SVG call. A drag
|
|
138
|
+
past a small threshold suppresses the trailing click so panning across
|
|
139
|
+
a node doesn't also fire its click handler.
|
|
140
|
+
- Added double-click a node to ease the view to center + zoom on it
|
|
141
|
+
(`focusOnNode`, ease-out cubic, ~250ms). Note: this is *not* the edit
|
|
142
|
+
menu trigger — double-click is now spoken for by center/zoom, so 1.5's
|
|
143
|
+
edit menu will open off a single-click "selected node" instead (that
|
|
144
|
+
selection state doesn't exist yet; today click only `console.log`s).
|
|
145
|
+
- Reworked the whole visual style: nodes went from small fixed circles to
|
|
146
|
+
much larger rounded squares (currently 160 world units), sized so
|
|
147
|
+
normal-length labels fit without truncating. Pulled every visual knob
|
|
148
|
+
(colors, node size/shape/font, spacing, zoom bounds, tooltip) out into
|
|
149
|
+
a `STYLE` config object at the top of `canvas.js` — deliberately plain
|
|
150
|
+
data, no functions, so it can later be swapped for a `GET /api/style`
|
|
151
|
+
response instead of hardcoded constants. Went through two style passes
|
|
152
|
+
with Alex: first a dark "sleek/modern" theme, then a full swap to a
|
|
153
|
+
TickTick-inspired light theme (off-white canvas, flat white node cards,
|
|
154
|
+
soft low-opacity shadow instead of a heavy one, blue accent on
|
|
155
|
+
hover/select, system font stack). Also made the canvas fill the
|
|
156
|
+
viewport (was a fixed 800x800 box) with a resize listener.
|
|
157
|
+
- Widened spacing to match the bigger nodes: sibling/parent-child spacing
|
|
158
|
+
up from 90/100 to 230/230, plus a dedicated extra gap (`treeGap`, 260)
|
|
159
|
+
inserted only *between* separate root trees in the forest, not between
|
|
160
|
+
siblings within one tree. Zoom's lower bound dropped 0.2 → 0.1 so a
|
|
161
|
+
bigger graph can still be zoomed out to fit; upper bound stayed at 4.
|
|
162
|
+
|
|
163
|
+
Still open for Phase 1, per the updated checklist in DEVPLAN.md: click-
|
|
164
|
+
to-select (persisted selection, needed before the edit menu can piggyback
|
|
165
|
+
off it), dependency/link edges, node coloring by status/completed, the
|
|
166
|
+
`/api/command` mutation endpoint, the edit menu itself, and the console
|
|
167
|
+
panel.
|
|
168
|
+
|
|
169
|
+
# 6-25
|
|
170
|
+
|
|
171
|
+
Alright let's start to think a bit about how I want to handle the pomo service.
|
|
172
|
+
|
|
173
|
+
task pomo 25 3
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
Let's start with spawning the timer, and then we can worry about logging and shit.
|
|
177
|
+
|
|
178
|
+
Pomo should spawn a process and write a log to a database. The process
|
|
179
|
+
should continuously monitor that log and see "am I active?"
|
|
180
|
+
- if so, it keeps running
|
|
181
|
+
- if not, we prompt the user for what they want to do?
|
|
182
|
+
- rest/reset/cancel
|
|
183
|
+
do I need this to be serialized even? maybe not if I'm just starting - we can start pomo in another thread (or just the same thread)
|
|
184
|
+
|
|
185
|
+
Yeah let's honestly not even worry about the multiprocessing part of it right now.
|
|
186
|
+
|
|
187
|
+
Let's just enter a loop and count down, while I keep clearing the screen
|
|
188
|
+
|
|
189
|
+
I need to figure out how to make it play a bell or have a screen pop up (if it's running in the background)
|
|
190
|
+
|
|
191
|
+
# 6-20
|
|
192
|
+
|
|
193
|
+
Let's think critically about what i want this API to lookk like. How should be people be
|
|
194
|
+
using the CLI?
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
task create {name} {**kwargs} -> create an item
|
|
198
|
+
task add {parent_id} ... -> create an item as a child
|
|
199
|
+
task show all
|
|
200
|
+
task show {id}
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
# 6-19
|
|
205
|
+
|
|
206
|
+
Really this whole thing should just be a tree abstraction, and I should have a root node class
|
|
207
|
+
and just built a tree database with some attrs depending on the type
|
|
208
|
+
|
|
209
|
+
idk why i'm being a dipshit
|
|
210
|
+
But that's gonna be the next iteration
|
|
211
|
+
|
|
212
|
+
# 6-18
|
|
213
|
+
|
|
214
|
+
Everything is fucked up anyways lol so might as qweell make some decisions about
|
|
215
|
+
the best way to do the database
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
class DB:
|
|
221
|
+
|
|
222
|
+
def get_item(id: int) -> TodoItem:
|
|
223
|
+
def get_comment(id: int) -> Comment:
|
|
224
|
+
def get_config() -> CLIConfig:
|
|
225
|
+
def create_item(name: str, parent: Optional[TodoItem]=None, ...) -> str:
|
|
226
|
+
def create_comment(content: str, parent: TodoItem) -> str:
|
|
227
|
+
def delete_item(name: str) -> bool:
|
|
228
|
+
def delete_comment(name: str) -> bool:
|
|
229
|
+
def update_item(id_: int, kwargs) -> bool:
|
|
230
|
+
def update_comment(id_: int, kwargs) -> bool:
|
|
231
|
+
def update_config(kwargs) -> bool:
|
|
232
|
+
|
|
233
|
+
def connect():
|
|
234
|
+
pass
|
|
235
|
+
def commit():
|
|
236
|
+
pass
|
|
237
|
+
def validate():
|
|
238
|
+
pass
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Important factors:
|
|
243
|
+
- do i want to serialize/deserialize every record twice? probably not
|
|
244
|
+
- so let's make sure that everything is read-only
|
|
245
|
+
|
|
246
|
+
How do i want to handle parentage?
|
|
247
|
+
i could:
|
|
248
|
+
- do it at the client level i.e. make sure to call (add parent)
|
|
249
|
+
- do it at the db level i.e. on every create, update, and delete method, validate
|
|
250
|
+
|
|
251
|
+
Let's do it at the db level - i want the database to be responsible for ensuring data
|
|
252
|
+
validation so I don't have to worry about it when I'm writing code downstream
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
# 6-17
|
|
256
|
+
|
|
257
|
+
Alright I find myself needing to make some design decisions about hierarchical lists.
|
|
258
|
+
|
|
259
|
+
I could:
|
|
260
|
+
- differentiate between child items and child lists, and have items only be leaf nodes
|
|
261
|
+
pros:
|
|
262
|
+
cons:
|
|
263
|
+
- treat everything as a single "item" and simply due away with the concept of lists as a
|
|
264
|
+
separate data point
|
|
265
|
+
- still distinguish between the two but treat them all as child ids - useful for sorting
|
|
266
|
+
|
|
267
|
+
Looking at it, i see no good reason to distinguish between items and lists - it complicates the
|
|
268
|
+
code without adding any additional functionality. There is nothing that a list does that an item
|
|
269
|
+
can't do apart from be a container, and there's no reason why an item can't also be a container.
|
|
270
|
+
|
|
271
|
+
So let's just go ahead and implement that change.
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
# 6-14
|
|
275
|
+
|
|
276
|
+
Damn it's been a productive couple of weeks. App is deployed on PyPi and I'm starting to think
|
|
277
|
+
a bit more about phase 2, how to rewrite it for ultimate success. What I'm thinking is that
|
|
278
|
+
things like help, argument patterns, and service logics should be bundled into one unit -
|
|
279
|
+
|
|
280
|
+
the core infrastructure should basically load all of the services in the config, and pull their
|
|
281
|
+
argument pattern matching, help menus, etc. That way, the core of the app just works as a dispatcher
|
|
282
|
+
|
|
283
|
+
Things I need to have clearly in mind before I start rearchitecting:
|
|
284
|
+
- How i'm going to handle modularity and reuse for major components
|
|
285
|
+
- How i'm going to handle multiple threads and processes
|
|
286
|
+
- a note on this - i'm leaning towards having a core metadata file that just keeps track
|
|
287
|
+
of all processes, that we just read/write to (with some sort of locking mechanism). That
|
|
288
|
+
will maintain process ids and any other shared state
|
|
289
|
+
|
|
290
|
+
But before all that good stuff, let's take what we have and polish the hell out of it
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
Also, as I'm doing this, it's becoming clear to me that I need to have records be a bit
|
|
294
|
+
more object oriented, as the number of different interactions that have to take place is
|
|
295
|
+
getting more and more annoying to keep track of and the best place for everything to be
|
|
296
|
+
put would be as methods on the objects, i.e. "item.updateList()", etc.
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
# 6-3
|
|
300
|
+
|
|
301
|
+
Alright so how are comments gonna look here:
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
Name:
|
|
305
|
+
Due By:
|
|
306
|
+
Description:
|
|
307
|
+
Depends On:
|
|
308
|
+
Comments
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
Let's think about what this cli refactor is gonna look like:
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
arg
|
|
317
|
+
arg
|
|
318
|
+
...
|
|
319
|
+
endpoint, *args, **kwargs
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
# 5-28
|
|
324
|
+
|
|
325
|
+
A couple things that I need to deal with:
|
|
326
|
+
- recursive deletes (so deleting hierarchical items)
|
|
327
|
+
- recursive completes
|
|
328
|
+
- better recurrence strategies
|
|
329
|
+
- how to deal with linking tasks that are recurrence of the same task
|
|
330
|
+
- database server
|
|
331
|
+
|
|
332
|
+
# 5-27
|
|
333
|
+
|
|
334
|
+
Let's think about this cli:
|
|
335
|
+
|
|
336
|
+
what do i want to be able to do?
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
- task add item|list|comment
|
|
342
|
+
- task show item|list|comment
|
|
343
|
+
- task complete {id}
|
|
344
|
+
- task delete {id}
|
|
345
|
+
- task {id} depends_on {id}
|
|
346
|
+
- task dependency_chain
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
- task {id} delete|done|show|edit
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
Let's start with some views
|
|
353
|
+
|
|
354
|
+
need to have recursive delete for lists
|
|
355
|
+
|
|
356
|
+
# 5-26
|
|
357
|
+
|
|
358
|
+
What can I build right now?
|
|
359
|
+
|
|
360
|
+
I want to have a basic CLI version of what I want. So we can use a pickle database,
|
|
361
|
+
define our models, and add the basic functionality to the core business logic.
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
How can we design this?
|
|
365
|
+
|
|
366
|
+
- I could have a core app session that is built through some composition
|
|
367
|
+
- for different concurrent users, we could spin up different processes?
|
|
368
|
+
- why don't I worry about scaling when it comes time to scale, let's just build osmething cool and useful right now
|
|
369
|
+
|
|
370
|
+
- So we have the app session object, and we can spin it up:
|
|
371
|
+
- on startup
|
|
372
|
+
- connect to a database
|
|
373
|
+
- call methods to perform the actions we care about
|
|
374
|
+
- commit changes as we want
|
|
375
|
+
OR
|
|
376
|
+
- have a plugin architecture where we can add views/operations that take in the session object
|
|
377
|
+
- on exit
|
|
378
|
+
|
|
379
|
+
CLI version
|
|
380
|
+
- do I want it to run in the background and communicate via pipes?
|
|
381
|
+
- feels like that falls under premature optimization, maybe just try running everything at once to start
|
|
382
|
+
- though that could be fun? maybe next start
|
|
383
|
+
- maybe not a pickle database, can do a local folder json database
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
so:
|
|
388
|
+
Session:
|
|
389
|
+
def __init__(
|
|
390
|
+
user: User,
|
|
391
|
+
database: Database
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
def on_exit():
|
|
395
|
+
...
|
|
396
|
+
|
|
397
|
+
cli/
|
|
398
|
+
views/ --> views of the core data
|
|
399
|
+
services/ --> core business operations we can perform
|
|
400
|
+
cli.py
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
# 5-11
|
|
413
|
+
|
|
414
|
+
Alright let's think about backend
|
|
415
|
+
|
|
416
|
+
What is the point of this app? What do I want to be able to support?
|
|
417
|
+
-
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
# 4-29
|
|
422
|
+
|
|
423
|
+
Alright let's think about frontend:
|
|
424
|
+
|
|
425
|
+
- Login Page:
|
|
426
|
+
- Page 1: login
|
|
427
|
+
- if logged in, show main
|
|
428
|
+
|
|
429
|
+
- Main Page
|
|
430
|
+
- SideBar
|
|
431
|
+
- MainPanel
|
|
432
|
+
- MainPanelOptions
|
|
433
|
+
|
|
434
|
+
- TodoPanel
|
|
435
|
+
- EditPanel
|
|
436
|
+
- CanvasPanel
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
What I want to do:
|
|
440
|
+
- build the threads part
|
|
441
|
+
- build the login and user context part
|
|
442
|
+
- build the database backend interactions
|
|
443
|
+
- build the canvas part
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
How do I want to handle components?
|
|
447
|
+
|
|
448
|
+
Brainstorm:
|
|
449
|
+
- I could construct a component tree
|
|
450
|
+
- each component could have a render call? Or just be called in its constructor, so when you instantiate
|
|
451
|
+
it, it shows up
|
|
452
|
+
- I want to have statically defined models so that I don't have to reconstitute things (since that's a pain)
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
Alright yeah, components can also have a commit-esque method (although maybe that's case by case) where I
|
|
457
|
+
commit their data
|
|
458
|
+
|
|
459
|
+
In that sense, I don't even really need to predefine my HTML - I can just generate it on the fly and have my core
|
|
460
|
+
div structure be defined
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
So what would that look like?
|
|
464
|
+
|
|
465
|
+
<LoginForm>
|
|
466
|
+
<Main>
|
|
467
|
+
<div> flex-col
|
|
468
|
+
<TopPanel>
|
|
469
|
+
|
|
470
|
+
<div> flex-row
|
|
471
|
+
<SideBar>
|
|
472
|
+
<TodoPanel>
|
|
473
|
+
<EditPanel>
|
|
474
|
+
<CanvasPanel>
|
|
475
|
+
|
|
476
|
+
<footer>
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
I can just have so many classes:
|
|
481
|
+
components/
|
|
482
|
+
loginForm.js
|
|
483
|
+
sidebar.js
|
|
484
|
+
todopanel.js
|
|
485
|
+
editpanel.js
|
|
486
|
+
canvaspanel.js
|
|
487
|
+
|
|
488
|
+
lib/
|
|
489
|
+
component.js
|
|
490
|
+
database.js
|
|
491
|
+
utils.js
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
Alright let's start to sketch these out:
|
|
495
|
+
|
|
496
|
+
We have our base:
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
class Component extends HTMLComponent{
|
|
500
|
+
|
|
501
|
+
db attribute
|
|
502
|
+
state attribute
|
|
503
|
+
|
|
504
|
+
constructor (
|
|
505
|
+
super()
|
|
506
|
+
const shadow = this.attachShadow({mode: 'open'})
|
|
507
|
+
customElements.define(this.constructor.name, this.constructor)
|
|
508
|
+
)
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
class LoginForm extends Component {
|
|
513
|
+
constructor(
|
|
514
|
+
super()
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
)
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
# 4-27
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
Alright sick progress, I'm in the process of populating the database. Now I need to:
|
|
536
|
+
- write the startup() method that pulls lists from the database and populates them in the sidebar
|
|
537
|
+
---> I'll put the populateDb method in there for now
|
|
538
|
+
|
|
539
|
+
- write the callback so that when I click on a list, it pulls its id from the database
|
|
540
|
+
- write the rendering functions so that the todo-list-panel renders the todos for the selected list
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
# 4-26
|
|
544
|
+
|
|
545
|
+
What do I want to add?
|
|
546
|
+
|
|
547
|
+
Pages:
|
|
548
|
+
- login page
|
|
549
|
+
- Main Page
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
# Features that I want to add
|
|
553
|
+
|
|
554
|
+
- Pop Up Card Editing
|
|
555
|
+
- Comments
|
|
556
|
+
- Text CLI
|
|
557
|
+
- Dockerize
|
|
558
|
+
-
|