imp/task, an oxal-ish task manager

hawk: render conversion error tanks

now, if a conversion goes wrong,
the frontend can display a nice box with the printed tank.

imp/task: implement %become and %prayer pokes

an imp/task node can become identical to another
by recieving a [%become =pith] poke.

upon hearing the [%become =pith], a task sends
a [%prayer =pith] poke to it's target.

the target, upon hearing the [%prayer =pith]
will %make over =pith with its contents.
(and will do so recursively for kids as well)
This commit is contained in:
Will Hanlen 2024-04-22 02:18:12 -05:00
parent 6512b7720c
commit 893e21dd8d
10 changed files with 505 additions and 26 deletions

View File

@ -923,6 +923,7 @@
:~
[(weld #/[p/our.bowl] here) %make %sky `!>([%system ~ 0]) ~]
[#/[p/our.bowl]/home/diary %make %diary `!>('') ~]
[#/[p/our.bowl]/home/tasks %make %task `!>(['' | ~]) ~]
[#/[p/our.bowl]/home/iframes/wiki %make %iframe `!>('https://en.wikipedia.org/wiki/Main_Page') ~]
==
|-
@ -965,25 +966,53 @@
::
=/ stud (@tas (~(got by pam.purl) 'stud'))
=/ conv !<($-([@ manx] vase) (all-grab %node))
?@ vert=(mole |.((conv [stud body])))
(send (manx-response:gen:serv ;/("failed to convert")))
=/ =pail:neo [stud u.vert]
=. run
%- poke-move
:- #/[p/our.bowl]/$/eyre/req/[eyre-id]
[(pave here) %poke pail]
%- send
::
%- manx-response:gen:serv
=+ !<(grow=$-(pail:neo $-(=bowl:neo manx)) (all-grow %htmx))
?^ man=(mole |.((grow pail)))
%- u.man
=+ b=*bowl.neo :: manually constructing a bowl. this is ugly
%= b
here (pave pax.purl)
==
;div: some sorta error occured
::
=/ vert (mule |.((conv [stud body])))
?- -.vert
%.n
%- send
=- -(status-code.response-header 400)
%- manx-response:gen:serv
;div.fc.p2.border.br1.scroll-x.scroll-y.wf.pre.mono
=style "max-height: 400px;"
=here (en-tape:pith:neo pith)
;*
%+ turn (tang p.vert)
|= =tank
;div: {(of-wall:format (~(win re tank) 0 55))}
==
%.y
=/ =pail:neo [stud p.vert]
=. run
%- poke-move
:- #/[p/our.bowl]/$/eyre/req/[eyre-id]
[(pave:neo here) %poke pail]
::
=+ !<(grow=$-(pail:neo $-(=bowl:neo manx)) (all-grow %htmx))
=/ man (mule |.((grow pail)))
%- send
?- -.man
%.y
%- manx-response:gen:serv
%- p.man
=+ b=*bowl.neo
%= b
here pith
==
%.n
=- -(status-code.response-header 500)
%- manx-response:gen:serv
;div.fc.p2.border.br1.scroll-x.scroll-y.wf.pre.mono
=style "max-height: 400px;"
=here (en-tape:pith:neo (pave:neo pax.purl))
;*
%+ turn (tang p.man)
|= =tank
;div: {(of-wall:format (~(win re tank) 0 55))}
==
::
==
::
==
?: =(%'PUT' method.request.req) :: %make
::
=/ stud (@tas (~(got by pam.purl) 'stud'))
@ -994,16 +1023,16 @@
=. run
%- poke-move
:- #/[p/our.bowl]/$/eyre/req/[eyre-id]
[(pave here) %make p.pail `q.pail ~]
%- send
[(pave:neo here) %make p.pail `q.pail ~]
::
%- send
%- manx-response:gen:serv
=+ !<(grow=$-(pail:neo $-(=bowl:neo manx)) (all-grow %htmx))
?^ man=(mole |.((grow pail)))
%- u.man
=+ b=*bowl.neo :: manually constructing a bowl. this is ugly
%= b
here (pave pax.purl)
here (pave:neo pax.purl)
==
;div: some sorta error occured
::

View File

@ -0,0 +1,53 @@
/@ node
/@ task-diff
:- [%node %task-diff]
|= nod=node
^- task-diff
=/ head (@tas (crip (~(got by (malt a.g.nod)) %head)))
%- task-diff
?+ head
~| [%unknown-head head]
!!
%become
=/ path-el (snag 0 c.nod)
~& path-el
=/ path (stab (crip (~(got by (malt a.g.path-el)) %value)))
[head (pave:neo path)]
::
%nest
=/ name-el (snag 0 c.nod)
=/ name (@tas (crip (~(got by (malt a.g.name-el)) %value)))
[head name '' | ~]
::
%prep
=/ name-el (snag 0 c.nod)
=/ name (@tas (crip (~(got by (malt a.g.name-el)) %value)))
[head name '' | ~]
::
%oust
=/ path (stab (crip (~(got by (malt a.g.nod)) %pith)))
[head (pave:neo path)]
::
%edit
=/ done-label (snag 0 c.nod)
=/ done-el (snag 0 c.done-label)
=/ text-el (snag 1 c.nod)
=/ text (crip (~(got by (malt a.g.text-el)) %value))
=/ done (~(has by (malt a.g.done-el)) %checked)
[head text done]
::
%kid-done
=/ path (stab (crip (~(got by (malt a.g.nod)) %pith)))
[head (pave:neo path)]
::
%reorder
=/ piths
%+ turn c.nod
|= =manx
=/ here (~(get by (malt a.g.manx)) %here)
?~ here
~& >>> [%bad-here manx]
!!
(pave:neo /[(rear (stab (crip (need here))))])
[head piths]
==

View File

@ -21,7 +21,7 @@
--f2: #999;
--f3: #777;
--f4: #555;
--f-error: orange;
--f-error: #531;
--f-success: lightgreen;
--link: lightblue;
--hover: 115%;

View File

@ -0,0 +1,12 @@
/@ task-diff
:- [%task-diff %htmx]
|= t=task-diff
|= =bowl:neo
;div.loading
=hx-get "/neo/hawk{(en-tape:pith:neo here.bowl)}"
=hx-target "closest ha-wk"
=hx-indicator "closest .loader"
=hx-swap "innerHTML"
=hx-trigger "load"
; +++
==

View File

@ -0,0 +1,273 @@
/@ task
:- [%task %htmx]
|= t=task
|= =bowl:neo
|^
shell
++ kids ~(tap by kids.bowl)
++ id
^- tape
%- zing
%+ turn (pout here.bowl)
|= smeg=@ta
%+ weld "--"
(trip smeg)
++ form-edit
^- manx
;form.fc.g2.br1
=hx-post "/neo/hawk{(en-tape:pith:neo here.bowl)}?stud=task-diff"
=hx-trigger "input changed delay:0.4s from:find textarea, input from:find input"
=hx-swap "none"
=head "edit"
;label.fr.g2.ac.js
;+ =- ?. done.t:+ -
-(a.g [[%checked ""] a.g.-])
^- manx
;input
=type "checkbox"
=onclick (trip 'if (this.checked) { this.setAttribute("checked", "")} else {this.removeAttribute("checked")}')
;
==
;span.grow: Done
;div.htmx-indicator
; ---
==
==
;textarea.wf.p2.border.br1.ma.mono
=name "text"
=autocomplete "off"
=spellcheck "false"
=rows "{<(add 2 (lent (fand ~[10] (trip text.t))))>}"
=oninput "this.setAttribute('value', this.value); this.rows = this.value.split('\\n').length"
=value (trip (@t text.t))
; {(trip (@t text.t))}
==
==
++ form-create
|= [head=@tas label=tape]
^- manx
;div.fc.g1
;button.b0.br1.hover.p2.wfc.mono.f3
=onclick
"""
this.classList.toggle('toggled');
this.nextElementSibling.classList.toggle('hidden');
this.nextElementSibling.firstChild.focus();
"""
; {label}
==
;form.fr.g1.hidden
=hx-post "/neo/hawk{(en-tape:pith:neo here.bowl)}?stud=task-diff"
=head (trip head)
=hx-swap "outerHTML"
=hx-target "find button .loading"
;input.wf.p1.border.br1.grow
=name "text"
=autocomplete "off"
=type "text"
=pattern (trip '[a-z]{1}[a-z0-9\\-]+')
=title "lowercase and heps"
=required ""
=placeholder "name"
=oninput "this.setAttribute('value', this.value);"
;
==
;button.b1.br1.hover.p1.wfc.loader
;span.loaded: create
;span.loading: ---
==
==
==
++ part-kid
|= [=pith =pail:neo]
=/ t=task !<(task q.pail)
=- ?. done.t -
-(a.g [[%done ""] a.g.-])
^- manx
;div.fc.g1
=here (en-tape:pith:neo (welp here.bowl pith))
;div.fr.g1
;button
=class "b0 br1 hover p1 tl action mono fr g3 f2"
=style "padding: 4px 9px;"
=type "button"
=onclick
"""
this.textContent = this.textContent === "=" ? "|" : "="; toggleChildren(this);
"""
;span.bold: =
==
;+ =-
=/ that -
=/ classes
%+ weld
"b0 br1 hover p1 grow tl action mono fr g3"
?:(done.t " strike f3" "")
that(a.g [[%class classes] a.g.that])
^- manx
;button
=type "button"
=onclick
"""
this.classList.toggle('toggled'); this.parentNode.nextElementSibling.classList.toggle('hidden');
"""
;span.bold: {(trip -:(pout pith))}
;span.break.f2: {(scag (fall (find [10 ~] (trip text.t)) 30) (trip text.t))}
==
;a
=class "b0 br1 hover p1 loader f3"
=hx-indicator "this"
=href "/neo/hawk{(en-tape:pith:neo here.bowl)}{(en-tape:pith:neo pith)}"
=hx-swap "innerHTML"
;span.loaded: →
;span.loading: .
==
==
;div.border.p2.br1.frw.g2.hidden
=hx-disinherit "hx-indicator"
=style "margin-left: 20px;"
;button.b1.br1.p2.hover
=onclick "this.parentNode.parentNode.parentNode?.insertAdjacentElement('beforeend', this.parentNode.parentNode); center(this);"
; ↧
==
;button.b1.br1.p2.hover
=onclick "this.parentNode.parentNode.nextElementSibling?.insertAdjacentElement('afterend', this.parentNode.parentNode); center(this);"
; ↓
==
;button.b1.br1.p2.hover
=onclick "this.parentNode.parentNode.previousElementSibling?.insertAdjacentElement('beforebegin', this.parentNode.parentNode); center(this);"
; ↑
==
;button.b1.br1.p2.hover
=onclick "this.parentNode.parentNode.parentNode?.insertAdjacentElement('afterbegin', this.parentNode.parentNode); center(this);"
; ↥
==
;div.htmx-indicator.reorder-indicator.p2.f2
; ---
==
;div.basis-full;
;button.b1.br1.p2.hover.loader
=type "button"
=hx-post "/neo/hawk{(en-tape:pith:neo here.bowl)}?stud=task-diff"
=hx-swap "outerHTML"
=hx-target "find .loading"
=head "kid-done"
=pith (en-tape:pith:neo pith)
;span.loaded: toggle
;span.loading: ---
==
;button.b1.br1.p2.hover.loader
=type "button"
=hx-post "/neo/hawk{(en-tape:pith:neo here.bowl)}?stud=task-diff"
=hx-swap "none"
=hx-on--after-request "this.parentNode.parentNode.remove();"
=head "oust"
=pith (en-tape:pith:neo pith)
;span.loaded: delete
;span.loading: ---
==
;button.b1.br1.p2.hover
=type "button"
=onclick "this.nextElementSibling.classList.toggle('hidden'); this.classList.toggle('toggled');"
; become
==
;div.basis-full.hidden.fr.g1
=hx-post "/neo/hawk{(en-tape:pith:neo (welp here.bowl pith))}?stud=task-diff"
=hx-trigger "become"
=hx-target "find .loading"
=hx-swap "outerHTML"
=head "become"
;input.grow.p2.br1.border
=type "text"
=value (en-tape:pith:neo (welp here.bowl pith))
=oninput "this.setAttribute('value', this.value);"
;
==
;button.p2.b1.hover.br1.loader
=type "button"
=onclick "this.dispatchEvent(new CustomEvent('become', \{composed:true, bubbles: true}))"
;span.loaded: become
;span.loading: ---
==
==
;div.basis-full.p2.pre.mono.scroll-x
; {(trip text.t)}
==
==
;div.fc.g2.hidden
=hx-disinherit "hx-indicator"
=style "margin-left: 20px;"
;
==
==
::
++ script
;script
;+ ;/ %- trip
'''
function center(el) {
el.scrollIntoView({
block: "center",
inline: "start",
behavior: "instant"
})
}
function toggleChildren(el) {
let kidsDiv = el.parentNode.nextElementSibling.nextElementSibling;
if (!kidsDiv.children.length) {
let here = el.parentNode.parentNode.getAttribute('here');
let stub = document.createElement("div");
stub.setAttribute("hx-get", `/neo/hawk${here}`);
stub.setAttribute("hx-trigger", 'load');
stub.setAttribute("hx-target", 'this');
stub.setAttribute("hx-select", '.kids');
stub.textContent = "+ + +"
stub.className = "fc as jc"
stub.style = "padding:10px; padding-left: 20px;"
stub.setAttribute("hx-swap", "outerHTML");
kidsDiv.appendChild(stub);
htmx.process(kidsDiv);
}
kidsDiv.classList.toggle('hidden');
}
'''
==
++ form-ordered-kids
;form.fc.g1
=hx-post "/neo/hawk{(en-tape:pith:neo here.bowl)}?stud=task-diff"
=head "reorder"
=hx-indicator ".reorder-indicator"
=hx-swap "none"
;*
%+ turn order.t
|= =pith
=/ kid (~(get by kids.bowl) pith)
?~ kid
;div: does not exist {(en-tape:pith:neo pith)}
(part-kid [pith (need kid)])
::;*
::=/ orphans
:: %+ skim kids
:: |= [=pith *]
:: =(~ (find [pith ~] order.t))
::%+ turn
:: %+ sort orphans
:: |= [a=[=pith *] b=[=pith *]]
:: (lth ->.pith.a ->.pith.b)
::part-kid
==
++ shell
;div.fc.js.af.p2.wf.p1.g5.ma
=here (en-tape:pith:neo here.bowl)
=style "max-width: 650px; padding-bottom: 50vh; padding-top: 30px;"
;+ script
;+ form-edit
;div.fc.g1.kids
::;+ ?~ (lent order.t) ;/("") (form-create %prep "+")
::;+ ?~ (lent order.t) (form-create %nest "+") ;/("")
;+ form-ordered-kids
::;+ ?~ (lent order.t) ;/("") (form-create %nest "+")
;+ (form-create %nest "+")
==
==
--

View File

@ -4,7 +4,7 @@
|= =bowl:neo
;form.fc.p2
=here (en-tape:pith:neo here.bowl)
=hx-post "/neo/hawk{(en-tape:pith:neo here.bowl)}?stud=txt"
=hx-post "/neo/hawk{(en-tape:pith:neo here.bowl)}?stud=txt&refresh"
=hx-trigger "input changed delay:0.4s from:find textarea"
=hx-swap "none"
;textarea.wf.p2.border.br1.ma

View File

@ -0,0 +1,92 @@
/@ task
/@ task-diff
|%
++ state %task
++ poke (sy %task-diff ~)
++ kids
^- kids:neo
%- ~(gas by *kids:neo)
:~ :- ~[|/%tas]
[%task %task-diff]
==
++ deps *deps:neo
++ form
^- form:neo
|_ [=bowl:neo =ever:neo state-vase=vase *]
++ poke
|= [=stud:neo vax=vase]
^- (quip card:neo vase)
=/ this (task !<(task state-vase))
=/ diff (task-diff !<(task-diff vax))
?- -.diff
%become
:: XX if you try to become your own ancestor, then infinite loop
=/ there (welp [p/our.bowl]~ pith.diff)
:_ state-vase
^- (list card:neo)
:~
[there %poke %task-diff !>([%prayer +.here.bowl])]
==
::
%prayer
:_ state-vase
%- flop
^- (list card:neo)
:-
[(welp [p/our.bowl]~ pith.diff) %make %task `!>(this) ~]
%- zing
%+ turn ~(tap by kids.bowl)
|= [=pith =pail:neo]
:~
[:(welp [p/our.bowl]~ pith.diff pith) %make %task `q.pail ~]
[(welp here.bowl pith) %poke %task-diff !>([%prayer (welp pith.diff pith)])]
==
::
%nest
:_ !> this(order `(list pith)`(snoc order.this `pith`[`@tas`name.diff ~]))
:_ ~
:* (snoc here.bowl name.diff)
%make %task `!>(task.diff) ~
==
::
%prep
:_ !> this(order `(list pith)`[[name.diff ~] order.this])
:_ ~
:* (snoc here.bowl name.diff)
%make %task `!>(task.diff) ~
==
::
%edit
:- ~
!> this(text text.diff, done done.diff)
::
%done
:- ~
!> this(done !done.this)
::
%kid-done
:_ !> this
:_ ~
:* (welp here.bowl pith.diff)
%poke %task-diff !>([%done ~])
==
::
%oust
=/ i (find [pith.diff ~] order.this)
?~ i `!>(this)
:_ !> this(order (oust [(need i) 1] order.this))
~
:::_ ~
:::* (welp here.bowl pith.diff)
:: %tomb
::==
::
%reorder
:- ~
!> this(order order.diff)
==
++ init
|= vas=(unit vase)
`(need vas)
--
--

View File

@ -0,0 +1,12 @@
/@ task
$%
[%become =pith]
[%prayer =pith]
[%prep name=@tas =task]
[%nest name=@tas =task]
[%edit text=cord done=?]
[%done ~] :: toggles
[%kid-done =pith] :: toggles
[%oust =pith]
[%reorder order=(list pith)]
==

View File

@ -0,0 +1 @@
,[text=cord done=? order=(list pith)]

View File

@ -15,8 +15,9 @@
font: inherit;
color: inherit;
}
form, p, li, ul, ol, div, button, h1, h2, h3, h4, h5, h6 {
form, a, input, p, li, ul, ol, div, button, h1, h2, h3, h4, h5, h6 {
margin: 0;
line-height: 1;
}
html {
height: 100%;
@ -36,6 +37,7 @@ body {
a {
cursor: pointer;
text-decoration: none;
font: inherit;
}
button, input, textarea, iframe {
border: unset;
@ -99,6 +101,9 @@ button, input, textarea, iframe {
.bold {
font-weight: bold;
}
.strike {
text-decoration: line-through;
}
.pre {
white-space: pre;
}
@ -324,11 +329,13 @@ select {
border-radius: 0;
background-color: inherit;
color: inherit;
font: inherit;
line-height: inherit;
}
textarea {
display: block;
outline: none;
resize: vertical;
resize: none;
border-radius: 0;
border: 0;
background-color: inherit;