tickets
All repositories: gitoria
4.0 KB
// lib/tickets-helpers.hl — what tickets.hl, events.hl and the pages look up about tickets: the state names, the// small shapes a page shows (a related ticket's ref, the relation view, the list's filter links). Statics only;// the central logic (who may do what, the writes) is lib/tickets.hl.import { ticketHref, ticketApiHref } from './util.hl'import { projectSlugOf, projectRecords } from './projects.hl'// THE STATES, in the order a ticket usually walks them; the state's name is also its URL form.// The OLD names are still accepted (the scheduler and the tools use them): stateOf() maps them.static states = ['open' 'progress' 'pending' 'review' 'reopened' 'done' 'canceled']static stateAliases = { 'in progress' = 'progress' 'awaiting creator' = 'review' 'confirmed' = 'done' 'rejected' = 'reopened' 'on hold' = 'pending' }// the states a person moves a ticket to: the inbox onesstatic inboxStates = ['pending' 'review']// the state a name stands for (a new name, an old one, or its URL form with '-' / '+'), or nullstatic stateOf = (name) => {if (name == null || hlTypeName(name) != 'String') { return null }s = name.replaceAll('-', ' ').replaceAll('+', ' ').trim().toLowerCase()if (states.includes(s)) { return s }a = stateAliases[s]return a != null ? a : null}static slugOf = (state) => { return state == null ? '' : state.replaceAll(' ', '-') }static stateOfSlug = (slug) => { return stateOf(slug) }// ---- relations, as a page shows them (ticket #4) ------------------------------------------------// what a relation shows of a ticket (no relations of its own — no recursion)static refOf = (t) => {slug = slugOf(t.state)pslug = projectSlugOf(t)let href = ticketHref(pslug, t.number)let apiHref = ticketApiHref(pslug, t.number)let key = pslug + '#' + t.numberreturn { id = t.id project = pslug number = t.number ref = '#' + t.number key = key subject = t.subject state = t.state stateSlug = slug href = href apiHref = apiHref }}static keyOf = (t) => { return projectSlugOf(t) + '#' + t.number }// what the ticket PAGE shows of a row's relations (SSR members and the `ticketsRelated` push)static noRef = { id = '' project = '' number = 0 ref = '' key = '' subject = '' state = '' stateSlug = '' href = '/' apiHref = '' }static relationViewOf = (row) => {total = row.children.lengthlet done = 0for (c of row.children) { if (c.state == 'done') { done = done + 1 } }let note = ''if (total > 0) { note = done == total ? 'all children done (' + total + ')' : done + ' of ' + total + ' children done' }let hasParent = row.parent != nulllet hasChildren = total > 0let hasBlockedBy = row.blockedBy.length > 0let hasBlocks = row.blocks.length > 0return { id = row.id parent = hasParent ? row.parent : noRef hasParent = hasParent children = row.children hasChildren = hasChildrenchildNote = note childClass = row.allChildrenConfirmed ? 'done' : '' allChildrenConfirmed = row.allChildrenConfirmedblockedBy = row.blockedBy hasBlockedBy = hasBlockedBy blocks = row.blocks hasBlocks = hasBlockshasRelations = hasParent || hasChildren || hasBlockedBy || hasBlocks }}// ---- the list page's filter links -------------------------------------------------------------// [{ label, href, cls }] — `cls` is 'selected' on the one in effect. The href keeps the OTHER filter.static projectLinks = (project, state) => {tail = state != null ? '/state/' + slugOf(state) : ''out = [{ label = 'all projects' href = state != null ? tail : '/' cls = project == null ? 'selected' : '' }]for (p of projectRecords()) {out.push({ label = p.title href = '/project/' + p.slug + tail cls = p.slug == project ? 'selected' : '' })}return out}static stateLinks = (project, state) => {head = project != null ? '/project/' + project : ''out = [{ label = 'all states' href = project != null ? head : '/' cls = state == null ? 'selected' : '' }]for (s of states) {out.push({ label = s href = head + '/state/' + slugOf(s) cls = s == state ? 'selected ' + slugOf(s) : slugOf(s) })}return out}
Branches
- mainmain branch
Latest commits
- a75e0279mission 010 (code order) 3/4: let only where a variable is reassigned or re-bound in a loop body (456 lets → plain declarations; Hybriel refuses a plain declaration inside a loop on its 2nd pass). gate 249/0, connect 60/0, real-data reads identical, a 50-step write sequence (API + faces) identical to the old codemre
- e9d5c618mission 010 (code order) 2/4: one lib/ file per topic — store.hl split into projects / tickets (+ relations) / events / tickets-helpers, util.hl shared helpers (env, storage dir, URLs, sorts, Vienna time), the function routes out of project.hl into lib/api.hl (thin; auth/filters/Accept in api-helpers.hl), invite + member-removal logic out of the faces/routes into invites.hl / tickets.hl; project.hl is the map. /login/callback gets req + the session store by reference. gate 249/0, connect 60/0, real-data reads identicalmre
- 97e269b5mission 010 (code order) 1/4: .hl files out of the root — lib/ (store, users, connections, invites, migrate, markdown, mdview, import = ticketfile, util = localtime, jsoncheck, api-helpers = api), tools/import.hl, components/styles.hl; import paths only. gate 249/0, connect 60/0, real-data reads identicalmre
- 38f9d10ftickets: Hybriel master 06617221 (plugin allocators 3a781359 + 413f60e4, mpackdb 2cb7ae5e, http1 773de63e); gate 249/0, connect 60/0mre
- d3db6139tickets: Hybriel master 190aa11d (fc838894 GC correctness, #126 closure scopes, #127); gate 249/0, connect 60/0mre
- bce182e3tickets: Hybriel master 7eea0d32 (#126 memory, #48 lambda copies its argument); migrate.hl lambdas take &logmre
- 4137be0fantcolony#40: mission references point to the moved missionsmre
- 9bfba36aantcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre
- c7bd2645tickets: Hybriel master 73267707 (#122 fixed); compactNow workaround removed (#110 covered)mre
- 2ab91ee9tickets: gate checks rows appear once (session sync); re-vendor to ff51cf46 stopped on hybriel#122, stays 837fe120mre
- e01c2b1dtickets#24: installable app (manifest, service worker, offline list), own icon; gate waits for the hello's pongmre
- 752fbb7fdeploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
- 38bdd5e4deploy.sh: never send .git or .gitignore to Byrodinmre
- f12fa1bcState of 2026-09-27, before the move to gitoriamre