def postJson(url, dataObject) fetch `${url}` with method:'POST', body:dataObject as JSON, headers:{content-type:'application/json'} return result end def getJsonUrlAsObject(url) fetch `${url}` with method:'GET', headers:{content-type:'application/json'} return result as Object end def countdownSeconds(el, sec) set i to sec set _s to el's textContent repeat until i is 0 put `${_s} (${i}s)` into el decrement i by 1 wait 1s end end def setCheckboxes(el, option) repeat for e in ( in el) if option == 'all' set e's @checked to 'true' set e.checked to true else if option == 'none' remove @checked from e set e.checked to false else if option == 'invert' if e.checked toggle [@checked='false'] on e set e.checked to false else toggle [@checked='true'] on e set e.checked to true end else if option == 'toggle' toggle [@checked='true'] on e if e's @checked set e.checked to true else set e.checked to false end end end end behavior trCheckboxSelect on click document.getSelection().removeAllRanges() if not event.shiftKey take .select-tr-element from in closest for me call setCheckboxes(me, 'toggle') unless event.target.tagName.toLowerCase() === 'a' else document.getSelection().removeAllRanges() get first .select-tr-element in closest
if it set toggleTo to 'none' if checked of first .multiselect in it set toggleTo to 'all' end set selectedTrElement to it if it.rowIndex < my.rowIndex repeat while selectedTrElement.nextElementSibling set selectedTrElement to selectedTrElement.nextElementSibling call setCheckboxes(selectedTrElement, toggleTo) if selectedTrElement is me break end end else repeat while selectedTrElement.previousElementSibling call setCheckboxes(selectedTrElement, toggleTo) if selectedTrElement is me break end set selectedTrElement to selectedTrElement.previousElementSibling end end end end end end behavior buttonCheckHtmxResponse on htmx:afterRequest from closest to me if (closest to me) != (event.target) exit end set :_v to my textContent unless :_v if event.detail.successful then put `👍` into me else put `🤖 An error occured` into me end wait 1s put :_v into me set :_v to null end end behavior confirmButton init set :inner to my.innerHTML end on every click halt the event end on click[event.detail==1] from me queue none set x to 3 repeat until x == 0 put `Confirm ${x}x` into me wait for a click or 1500ms if the result's type is 'click' decrement x else put :inner into me exit end end put :inner into me trigger confirmedButton end end behavior inlineHtmxRename init set :_textContent to my.textContent end on click halt the event end on htmx:afterRequest if event.detail.successful == true set :_textContent to my.textContent end set my.textContent to :_textContent end on htmx:confirm(issueRequest) halt the event call confirm(`${:_textContent} to ${my.textContent}?`) if not result set my.textContent to :_textContent else issueRequest() end end on blur if my.textContent == '' set my.textContent to :_textContent then exit end if my.textContent == :_textContent exit end set @hx-vals to `{"${my @data-patch-parameter}": "${my.textContent}"}` trigger editContent on me end on keydown[keyCode == 13] me.blur() halt the event end end behavior tresorToggle def setUnlocked get #vault-unlock-pin add @disabled to it set its @placeholder to 'Tresor is unlocked' set #vault-unlock's textContent to '🔓' end def setLocked get #vault-unlock-pin remove @disabled from it set its @placeholder to 'Tresor password' set #vault-unlock's textContent to '🔐' end def noTresor get #vault-unlock-pin add @disabled to it set its @placeholder to 'No tresor available' set #vault-unlock's textContent to '⛔' end init if window.vault.isUnlocked() call setUnlocked() else if #vault-unlock's @data-tresor != "" call setLocked() else call noTresor() end end end on keydown[keyCode == 13] from #vault-unlock-pin trigger click on #vault-unlock unless #vault-unlock-pin's value is empty end on click from #vault-unlock halt the event if not window.vault.isUnlocked() exit unless value of #vault-unlock-pin call JSON.parse(#vault-unlock's @data-tresor) set keyData to the result call VaultUnlockPrivateKey(value of #vault-unlock-pin, keyData) call setUnlocked() else call window.vault.lock() call setLocked() end set value of #vault-unlock-pin to '' on exception(error) trigger notification( title: 'Tresor error', level: 'validationError', message: 'Could not unlock tresor, check your PIN', duration: 3000, locations: ['vault-unlock-pin'] ) end end behavior bodydefault on htmx:wsError or htmx:wsClose set #ws-indicator's textContent to '⭕' end on keydown exit unless window.vault.isUnlocked() if navigator.platform.toUpperCase().indexOf('MAC') >= 0 set ctrlOrCmd to event.metaKey else set ctrlOrCmd to event.ctrlKey end if (event.key is "F5" or (ctrlOrCmd and event.key.toLowerCase() === "r")) or ((ctrlOrCmd and event.shiftKey and event.key.toLowerCase() === "r") or (event.shiftKey and e.key === "F5")) trigger notification( title: 'Unlocked session', level: 'user', message: 'Preventing window reload due to unlocked session', duration: 2000, locations: [] ) halt the event end end on htmx:responseError set status to event.detail.xhr.status if status >= 500 trigger notification(title: 'Server error', level: 'error', message: 'The server could not handle the given request', duration: 10000) else if status == 404 trigger notification(title: 'Not found', level: 'error', message: `Route not found: ${event.detail.xhr.responseURL}`, duration: 3000) end end on htmx:configRequest if window.vault.isUnlocked() repeat for p in event.detail.parameters log p end end end on htmx:beforeRequest remove @aria-invalid from <[aria-invalid]/> end end behavior objectFilters(submitForm) on click from in me halt the event put '' into .generated-filters in me repeat for btn in ( in me) if (btn is event.target and btn does not match .active) or (btn is not event.target and btn matches .active) render #filter-item with (value: btn's value) then put the result at the end of .generated-filters in me end end if length of <.generated-filters input/> is 0 render #filter-item with (value: '') then put the result at the end of .generated-filters in me end trigger submit on submitForm unless submitForm == '' end end