issue-pane 2.4.10-e9bc48a6 → 2.4.10-f080faac
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.
- package/.github/workflows/ci.yml +1 -0
- package/.nvmrc +1 -1
- package/board.js +7 -8
- package/issue.js +51 -50
- package/issuePane.js +115 -137
- package/newIssue.js +3 -4
- package/newTracker.js +12 -12
- package/package.json +1 -1
package/.github/workflows/ci.yml
CHANGED
package/.nvmrc
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
v12.7.0
|
package/board.js
CHANGED
|
@@ -10,10 +10,9 @@
|
|
|
10
10
|
* @returns dom:Element
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import
|
|
13
|
+
import { ns, rdf, utils, widgets } from 'solid-ui'
|
|
14
14
|
import { store } from 'solid-logic'
|
|
15
|
-
const
|
|
16
|
-
const $rdf = UI.rdf
|
|
15
|
+
const $rdf = rdf
|
|
17
16
|
|
|
18
17
|
export function board (dom, columnValues, renderItem, options) {
|
|
19
18
|
const board = dom.createElement('div')
|
|
@@ -27,7 +26,7 @@ export function board (dom, columnValues, renderItem, options) {
|
|
|
27
26
|
const mainRow = table.appendChild(dom.createElement('tr'))
|
|
28
27
|
columnValues.forEach(x => {
|
|
29
28
|
const cell = headerRow.appendChild(dom.createElement('th'))
|
|
30
|
-
cell.textContent =
|
|
29
|
+
cell.textContent = utils.label(x, true) // Initial capital
|
|
31
30
|
cell.subject = x
|
|
32
31
|
cell.style = 'margin: 0.3em; padding: 0.5em 1em; font-treatment: bold; font-size: 120%;'
|
|
33
32
|
|
|
@@ -44,7 +43,7 @@ export function board (dom, columnValues, renderItem, options) {
|
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
if (options.columnDropHandler) {
|
|
47
|
-
|
|
46
|
+
widgets.makeDropTarget(column, droppedURIHandler)
|
|
48
47
|
}
|
|
49
48
|
})
|
|
50
49
|
|
|
@@ -57,7 +56,7 @@ export function board (dom, columnValues, renderItem, options) {
|
|
|
57
56
|
const classes = store.each(item, ns.rdf('type'))
|
|
58
57
|
const catColors = classes.map(cat => store.any(cat, ns.ui('backgroundColor'))).filter(c => c)
|
|
59
58
|
|
|
60
|
-
table.appendChild(
|
|
59
|
+
table.appendChild(widgets.personTR(dom, null, item))
|
|
61
60
|
table.subject = item
|
|
62
61
|
table.style = 'margin: 1em;' // @@ use style.js
|
|
63
62
|
const backgroundColor = catColors[0] || store.any(category, ns.ui('backgroundColor'))
|
|
@@ -76,7 +75,7 @@ export function board (dom, columnValues, renderItem, options) {
|
|
|
76
75
|
const actualRenderItem = renderItem || options.renderItem || defaultRenderItem
|
|
77
76
|
function localRenderItem (subject) {
|
|
78
77
|
const ele = actualRenderItem(subject)
|
|
79
|
-
|
|
78
|
+
widgets.makeDraggable(ele, subject)
|
|
80
79
|
ele.subject = subject
|
|
81
80
|
return ele
|
|
82
81
|
}
|
|
@@ -88,7 +87,7 @@ export function board (dom, columnValues, renderItem, options) {
|
|
|
88
87
|
items = items.filter(options.filter)
|
|
89
88
|
}
|
|
90
89
|
const sortedItems = sortedBy(items, sortBy, now, true)
|
|
91
|
-
|
|
90
|
+
utils.syncTableToArrayReOrdered(col, sortedItems, localRenderItem)
|
|
92
91
|
}
|
|
93
92
|
}
|
|
94
93
|
|
package/issue.js
CHANGED
|
@@ -5,6 +5,7 @@ import { authn, store } from 'solid-logic'
|
|
|
5
5
|
import { newIssueForm } from './newIssue'
|
|
6
6
|
|
|
7
7
|
const $rdf = rdf
|
|
8
|
+
const kb = store
|
|
8
9
|
|
|
9
10
|
const SET_MODIFIED_DATES = false
|
|
10
11
|
|
|
@@ -18,7 +19,7 @@ function complain (message, context) {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export function isOpen (issue) {
|
|
21
|
-
const types =
|
|
22
|
+
const types = kb.findTypeURIs(issue)
|
|
22
23
|
return !!types[ns.wf('Open').uri]
|
|
23
24
|
}
|
|
24
25
|
|
|
@@ -26,13 +27,13 @@ export function iconForIssue (issue) {
|
|
|
26
27
|
return isOpen(issue) ? TASK_ICON : CLOSED_TASK_ICON
|
|
27
28
|
}
|
|
28
29
|
export function getState (issue, classification) {
|
|
29
|
-
const tracker =
|
|
30
|
-
const states =
|
|
30
|
+
const tracker = kb.the(issue, ns.wf('tracker'), null, issue.doc())
|
|
31
|
+
const states = kb.any(tracker, ns.wf('issueClass'))
|
|
31
32
|
classification = classification || states
|
|
32
|
-
const types =
|
|
33
|
-
.filter(ty =>
|
|
33
|
+
const types = kb.each(issue, ns.rdf('type'))
|
|
34
|
+
.filter(ty => kb.holds(ty, ns.rdfs('subClassOf'), classification))
|
|
34
35
|
if (types.length !== 1) {
|
|
35
|
-
// const initialState =
|
|
36
|
+
// const initialState = kb.any(tracker, ns.wf('initialState')) No do NOT default
|
|
36
37
|
// if (initialState) return initialState
|
|
37
38
|
throw new Error('Issue must have one type as state: ' + types.length)
|
|
38
39
|
}
|
|
@@ -40,8 +41,8 @@ export function getState (issue, classification) {
|
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
export function getBackgroundColorFromTypes (issue) {
|
|
43
|
-
const classes =
|
|
44
|
-
const catColors = classes.map(cat =>
|
|
44
|
+
const classes = kb.each(issue, ns.rdf('type')) // @@ pick cats in order then state
|
|
45
|
+
const catColors = classes.map(cat => kb.any(cat, ns.ui('backgroundColor'))).filter(c => !!c)
|
|
45
46
|
|
|
46
47
|
if (catColors.length) return catColors[0].value // pick first one
|
|
47
48
|
return null
|
|
@@ -79,7 +80,7 @@ export function renderIssueCard (issue, context) {
|
|
|
79
80
|
if (uncategorized) {
|
|
80
81
|
const deleteButton = widgets.deleteButtonWithCheck(dom, buttonsCell, 'issue', async function () { // noun?
|
|
81
82
|
try {
|
|
82
|
-
await
|
|
83
|
+
await kb.updater.update(kb.connectedStatements(issue))
|
|
83
84
|
} catch (err) {
|
|
84
85
|
complain(`Unable to delete issue: ${err}`, context)
|
|
85
86
|
}
|
|
@@ -122,15 +123,15 @@ function renderSpacer (dom, backgroundColor) {
|
|
|
122
123
|
|
|
123
124
|
export function renderIssue (issue, context) {
|
|
124
125
|
// Don't bother changing the last modified dates of things: save time
|
|
125
|
-
function setModifiedDate (subj,
|
|
126
|
+
function setModifiedDate (subj, kb, doc) {
|
|
126
127
|
if (SET_MODIFIED_DATES) {
|
|
127
128
|
if (!getOption(tracker, 'trackLastModified')) return
|
|
128
|
-
const deletions =
|
|
129
|
-
.concat(
|
|
129
|
+
const deletions = kb.statementsMatching(issue, ns.dct('modified'))
|
|
130
|
+
.concat(kb.statementsMatching(issue, ns.wf('modifiedBy'))
|
|
130
131
|
)
|
|
131
132
|
const insertions = [$rdf.st(issue, ns.dct('modified'), new Date(), doc)]
|
|
132
133
|
if (me) insertions.push($rdf.st(issue, ns.wf('modifiedBy'), me, doc))
|
|
133
|
-
|
|
134
|
+
kb.updater.update(deletions, insertions, function (_uri, _ok, _body) {})
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
|
|
@@ -163,7 +164,7 @@ export function renderIssue (issue, context) {
|
|
|
163
164
|
}
|
|
164
165
|
function getOption (tracker, option) {
|
|
165
166
|
// eg 'allowSubIssues'
|
|
166
|
-
const opt =
|
|
167
|
+
const opt = kb.any(tracker, ns.ui(option))
|
|
167
168
|
return !!(opt && opt.value)
|
|
168
169
|
}
|
|
169
170
|
|
|
@@ -179,10 +180,10 @@ export function renderIssue (issue, context) {
|
|
|
179
180
|
|
|
180
181
|
const dom = context.dom
|
|
181
182
|
// eslint-disable-next-line no-use-before-define
|
|
182
|
-
const tracker =
|
|
183
|
+
const tracker = kb.the(issue, ns.wf('tracker'), null, issue.doc())
|
|
183
184
|
if (!tracker) throw new Error('No tracker')
|
|
184
185
|
// eslint-disable-next-line no-use-before-define
|
|
185
|
-
const stateStore =
|
|
186
|
+
const stateStore = kb.any(tracker, ns.wf('stateStore'))
|
|
186
187
|
const store = issue.doc()
|
|
187
188
|
|
|
188
189
|
const issueDiv = dom.createElement('div')
|
|
@@ -196,17 +197,17 @@ export function renderIssue (issue, context) {
|
|
|
196
197
|
const iconButton = issueDiv.appendChild(widgets.button(dom, iconForIssue(issue)))
|
|
197
198
|
widgets.makeDraggable(iconButton, issue) // Drag me wherever you need to do stuff with this issue
|
|
198
199
|
|
|
199
|
-
const states =
|
|
200
|
+
const states = kb.any(tracker, ns.wf('issueClass'))
|
|
200
201
|
if (!states) { throw new Error('This tracker ' + tracker + ' has no issueClass') }
|
|
201
202
|
const select = widgets.makeSelectForCategory(
|
|
202
203
|
dom,
|
|
203
|
-
|
|
204
|
+
kb,
|
|
204
205
|
issue,
|
|
205
206
|
states,
|
|
206
207
|
stateStore,
|
|
207
208
|
function (ok, body) {
|
|
208
209
|
if (ok) {
|
|
209
|
-
setModifiedDate(store,
|
|
210
|
+
setModifiedDate(store, kb, store)
|
|
210
211
|
widgets.refreshTree(issueDiv)
|
|
211
212
|
} else {
|
|
212
213
|
console.log('Failed to change state:\n' + body)
|
|
@@ -215,18 +216,18 @@ export function renderIssue (issue, context) {
|
|
|
215
216
|
)
|
|
216
217
|
issueDiv.appendChild(select)
|
|
217
218
|
|
|
218
|
-
const cats =
|
|
219
|
+
const cats = kb.each(tracker, ns.wf('issueCategory')) // zero or more
|
|
219
220
|
for (const cat of cats) {
|
|
220
221
|
issueDiv.appendChild(
|
|
221
222
|
widgets.makeSelectForCategory(
|
|
222
223
|
dom,
|
|
223
|
-
|
|
224
|
+
kb,
|
|
224
225
|
issue,
|
|
225
226
|
cat,
|
|
226
227
|
stateStore,
|
|
227
228
|
function (ok, body) {
|
|
228
229
|
if (ok) {
|
|
229
|
-
setModifiedDate(store,
|
|
230
|
+
setModifiedDate(store, kb, store)
|
|
230
231
|
widgets.refreshTree(issueDiv)
|
|
231
232
|
} else {
|
|
232
233
|
console.log('Failed to change category:\n' + body)
|
|
@@ -270,7 +271,7 @@ export function renderIssue (issue, context) {
|
|
|
270
271
|
wf:Task :creationForm core:coreIsueForm .
|
|
271
272
|
`
|
|
272
273
|
const CORE_ISSUE_FORM = ns.wf('coreIsueForm')
|
|
273
|
-
$rdf.parse(coreIssueFormText,
|
|
274
|
+
$rdf.parse(coreIssueFormText, kb, CORE_ISSUE_FORM.doc().uri, 'text/turtle')
|
|
274
275
|
const form = widgets.appendForm(
|
|
275
276
|
dom,
|
|
276
277
|
null, // was: container
|
|
@@ -285,11 +286,11 @@ export function renderIssue (issue, context) {
|
|
|
285
286
|
|
|
286
287
|
// Assigned to whom?
|
|
287
288
|
|
|
288
|
-
const assignments =
|
|
289
|
+
const assignments = kb.statementsMatching(issue, ns.wf('assignee'))
|
|
289
290
|
if (assignments.length > 1) {
|
|
290
291
|
say('Weird, was assigned to more than one person. Fixing ..')
|
|
291
292
|
const deletions = assignments.slice(1)
|
|
292
|
-
|
|
293
|
+
kb.updater.update(deletions, [], function (uri, ok, body) {
|
|
293
294
|
if (ok) {
|
|
294
295
|
say('Now fixed.')
|
|
295
296
|
} else {
|
|
@@ -302,15 +303,15 @@ export function renderIssue (issue, context) {
|
|
|
302
303
|
// Anyone assigned to any issue we know about
|
|
303
304
|
|
|
304
305
|
async function getPossibleAssignees () {
|
|
305
|
-
const devGroups =
|
|
306
|
-
await
|
|
307
|
-
const groupDevs = devGroups.map(group =>
|
|
306
|
+
const devGroups = kb.each(issue, ns.wf('assigneeGroup'))
|
|
307
|
+
await kb.fetcher.load(devGroups) // Load them all
|
|
308
|
+
const groupDevs = devGroups.map(group => kb.each(group, ns.vcard('member'), null, group.doc())).flat()
|
|
308
309
|
// Anyone who is a developer of any project which uses this tracker
|
|
309
|
-
const proj =
|
|
310
|
+
const proj = kb.any(null, ns.doap('bug-database'), tracker) // What project?
|
|
310
311
|
if (proj) {
|
|
311
|
-
await
|
|
312
|
+
await kb.fetcher.load(proj)
|
|
312
313
|
}
|
|
313
|
-
const projectDevs = proj ?
|
|
314
|
+
const projectDevs = proj ? kb.each(proj, ns.doap('developer')) : []
|
|
314
315
|
return groupDevs.concat(projectDevs)
|
|
315
316
|
}
|
|
316
317
|
|
|
@@ -323,7 +324,7 @@ export function renderIssue (issue, context) {
|
|
|
323
324
|
getPossibleAssignees().then(devs => {
|
|
324
325
|
if (devs.length) {
|
|
325
326
|
devs.forEach(function (person) {
|
|
326
|
-
|
|
327
|
+
kb.fetcher.lookUpThing(person)
|
|
327
328
|
}) // best effort async for names etc
|
|
328
329
|
const opts = {
|
|
329
330
|
// 'mint': '** Add new person **',
|
|
@@ -338,14 +339,14 @@ export function renderIssue (issue, context) {
|
|
|
338
339
|
issueDiv.appendChild(
|
|
339
340
|
widgets.makeSelectForOptions(
|
|
340
341
|
dom,
|
|
341
|
-
|
|
342
|
+
kb,
|
|
342
343
|
issue,
|
|
343
344
|
ns.wf('assignee'),
|
|
344
345
|
devs,
|
|
345
346
|
opts,
|
|
346
347
|
store,
|
|
347
348
|
function (ok, body) {
|
|
348
|
-
if (ok) setModifiedDate(store,
|
|
349
|
+
if (ok) setModifiedDate(store, kb, store)
|
|
349
350
|
else console.log('Failed to change assignee:\n' + body)
|
|
350
351
|
}
|
|
351
352
|
)
|
|
@@ -357,7 +358,7 @@ export function renderIssue (issue, context) {
|
|
|
357
358
|
*/
|
|
358
359
|
function supersOver (issue, stack) {
|
|
359
360
|
stack = stack || []
|
|
360
|
-
const sup =
|
|
361
|
+
const sup = kb.any(null, ns.wf('dependent'), issue, issue.doc())
|
|
361
362
|
if (sup) return supersOver(sup, [sup].concat(stack))
|
|
362
363
|
return stack
|
|
363
364
|
}
|
|
@@ -369,7 +370,7 @@ export function renderIssue (issue, context) {
|
|
|
369
370
|
const listOfSupers = subIssuePanel.appendChild(dom.createElement('div'))
|
|
370
371
|
listOfSupers.style.display = 'flex'
|
|
371
372
|
listOfSupers.refresh = function () {
|
|
372
|
-
// const supers =
|
|
373
|
+
// const supers = kb.each(null, ns.wf('dependent'), issue, issue.doc())
|
|
373
374
|
const supers = supersOver(issue)
|
|
374
375
|
utils.syncTableToArrayReOrdered(listOfSupers, supers, renderSubIssue)
|
|
375
376
|
}
|
|
@@ -381,7 +382,7 @@ export function renderIssue (issue, context) {
|
|
|
381
382
|
listOfSubs.style.display = 'flex'
|
|
382
383
|
listOfSubs.style.flexDirection = 'reverse' // Or center
|
|
383
384
|
listOfSubs.refresh = function () {
|
|
384
|
-
const subs =
|
|
385
|
+
const subs = kb.each(issue, ns.wf('dependent'), null, issue.doc())
|
|
385
386
|
utils.syncTableToArrayReOrdered(listOfSubs, subs, renderSubIssue)
|
|
386
387
|
}
|
|
387
388
|
listOfSubs.refresh()
|
|
@@ -395,7 +396,7 @@ export function renderIssue (issue, context) {
|
|
|
395
396
|
b.addEventListener(
|
|
396
397
|
'click',
|
|
397
398
|
function (_event) {
|
|
398
|
-
subIssuePanel.insertBefore(newIssueForm(dom,
|
|
399
|
+
subIssuePanel.insertBefore(newIssueForm(dom, kb, tracker, issue, listOfSubs.refresh), b.nextSibling) // Pop form just after button
|
|
399
400
|
},
|
|
400
401
|
false
|
|
401
402
|
)
|
|
@@ -404,7 +405,7 @@ export function renderIssue (issue, context) {
|
|
|
404
405
|
issueDiv.appendChild(dom.createElement('br'))
|
|
405
406
|
|
|
406
407
|
// Extras are stored centrally to the tracker
|
|
407
|
-
const extrasForm =
|
|
408
|
+
const extrasForm = kb.any(tracker, ns.wf('extrasEntryForm'))
|
|
408
409
|
if (extrasForm) {
|
|
409
410
|
widgets.appendForm(
|
|
410
411
|
dom,
|
|
@@ -422,31 +423,31 @@ export function renderIssue (issue, context) {
|
|
|
422
423
|
|
|
423
424
|
const spacer = issueDiv.appendChild(renderSpacer(dom, backgroundColor))
|
|
424
425
|
|
|
425
|
-
const template =
|
|
426
|
+
const template = kb.anyValue(tracker, ns.wf('issueURITemplate'))
|
|
426
427
|
/*
|
|
427
|
-
var chatDocURITemplate =
|
|
428
|
+
var chatDocURITemplate = kb.anyValue(tracker, ns.wf('chatDocURITemplate')) // relaive to issue
|
|
428
429
|
var chat
|
|
429
430
|
if (chatDocURITemplate) {
|
|
430
431
|
let template = $rdf.uri.join(chatDocURITemplate, issue.uri) // Template is relative to issue
|
|
431
|
-
chat =
|
|
432
|
+
chat = kb.sym(expandTemplate(template))
|
|
432
433
|
} else
|
|
433
434
|
*/
|
|
434
435
|
let messageStore
|
|
435
436
|
if (template) {
|
|
436
437
|
messageStore = issue.doc() // for now. Could go deeper
|
|
437
438
|
} else {
|
|
438
|
-
messageStore =
|
|
439
|
-
if (!messageStore) messageStore =
|
|
440
|
-
|
|
439
|
+
messageStore = kb.any(tracker, ns.wf('messageStore'))
|
|
440
|
+
if (!messageStore) messageStore = kb.any(tracker, ns.wf('stateStore'))
|
|
441
|
+
kb.sym(messageStore.uri + '#' + 'Chat' + timestring()) // var chat =
|
|
441
442
|
}
|
|
442
443
|
|
|
443
|
-
|
|
444
|
+
kb.fetcher.nowOrWhenFetched(messageStore, function (ok, body, _xhr) {
|
|
444
445
|
if (!ok) {
|
|
445
446
|
const er = dom.createElement('p')
|
|
446
447
|
er.textContent = body // @@ use nice error message
|
|
447
448
|
issueDiv.insertBefore(er, spacer)
|
|
448
449
|
} else {
|
|
449
|
-
const discussion = messageArea(dom,
|
|
450
|
+
const discussion = messageArea(dom, kb, issue, messageStore)
|
|
450
451
|
issueDiv.insertBefore(discussion, spacer)
|
|
451
452
|
issueDiv.insertBefore(renderSpacer(dom, backgroundColor), discussion)
|
|
452
453
|
} // Not sure why e stuck this in upwards rather than downwards
|
|
@@ -465,14 +466,14 @@ export function renderIssue (issue, context) {
|
|
|
465
466
|
widgets.attachmentList(dom, issue, issueDiv, {
|
|
466
467
|
doc: stateStore,
|
|
467
468
|
promptIcon: icons.iconBase + 'noun_25830.svg',
|
|
468
|
-
uploadFolder:
|
|
469
|
+
uploadFolder: kb.sym(uploadFolderURI), // Allow local files to be uploaded
|
|
469
470
|
predicate: ns.wf('attachment')
|
|
470
471
|
})
|
|
471
472
|
|
|
472
473
|
// Delete button to delete the issue
|
|
473
474
|
const deleteButton = widgets.deleteButtonWithCheck(dom, issueDiv, 'issue', async function () {
|
|
474
475
|
try {
|
|
475
|
-
await
|
|
476
|
+
await kb.updater.update(kb.connectedStatements(issue))
|
|
476
477
|
} catch (err) {
|
|
477
478
|
complain(`Unable to delete issue: ${err}`, context)
|
|
478
479
|
}
|
|
@@ -490,7 +491,7 @@ export function renderIssue (issue, context) {
|
|
|
490
491
|
'click',
|
|
491
492
|
async function (_event) {
|
|
492
493
|
try {
|
|
493
|
-
await
|
|
494
|
+
await kb.fetcher.load(messageStore, { force: true, clearPreviousData: true })
|
|
494
495
|
} catch (err) {
|
|
495
496
|
alert(err)
|
|
496
497
|
return
|
package/issuePane.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
**
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import
|
|
8
|
+
import { create, login, ns, icons, rdf, tabs, table, utils, widgets } from 'solid-ui'
|
|
9
9
|
import { store, authn } from 'solid-logic'
|
|
10
10
|
import { board } from './board' // @@ will later be in solid-UI
|
|
11
11
|
import { renderIssue, renderIssueCard, getState, exposeOverlay } from './issue'
|
|
@@ -14,9 +14,8 @@ import { newIssueForm } from './newIssue'
|
|
|
14
14
|
import { trackerSettingsFormText } from './trackerSettingsForm.js'
|
|
15
15
|
// import { trackerInstancesFormText } from './trackerInstancesForm.js'
|
|
16
16
|
|
|
17
|
-
const $rdf =
|
|
18
|
-
const
|
|
19
|
-
const widgets = UI.widgets
|
|
17
|
+
const $rdf = rdf
|
|
18
|
+
const kb = store
|
|
20
19
|
|
|
21
20
|
// const MY_TRACKERS_ICON = UI.icons.iconBase + 'noun_Document_998605.svg'
|
|
22
21
|
// const TRACKER_ICON = UI.icons.iconBase + 'noun_list_638112'
|
|
@@ -24,7 +23,7 @@ const widgets = UI.widgets
|
|
|
24
23
|
|
|
25
24
|
const OVERFLOW_STYLE = 'position: fixed; z-index: 100; top: 1.51em; right: 2em; left: 2em; bottom:1.5em; border: 0.1em grey; overflow: scroll;'
|
|
26
25
|
export default {
|
|
27
|
-
icon:
|
|
26
|
+
icon: icons.iconBase + 'noun_122196.svg', // was: js/panes/issue/tbl-bug-22.png
|
|
28
27
|
// noun_list_638112 is a checklist document
|
|
29
28
|
// noun_Document_998605.svg is a stack of twpo checklists
|
|
30
29
|
// noun_97839.svg is a ladybug
|
|
@@ -36,10 +35,10 @@ export default {
|
|
|
36
35
|
|
|
37
36
|
// Does the subject deserve an issue pane?
|
|
38
37
|
label: function (subject, _context) {
|
|
39
|
-
const t =
|
|
38
|
+
const t = kb.findTypeURIs(subject)
|
|
40
39
|
if (
|
|
41
40
|
t['http://www.w3.org/2005/01/wf/flow#Task'] ||
|
|
42
|
-
|
|
41
|
+
kb.holds(subject, ns.wf('tracker'))
|
|
43
42
|
) { return 'issue' } // in case ontology not available
|
|
44
43
|
if (t['http://www.w3.org/2005/01/wf/flow#Tracker']) return 'tracker'
|
|
45
44
|
// Later: Person. For a list of things assigned to them,
|
|
@@ -62,7 +61,6 @@ export default {
|
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
const kb = context.session.store
|
|
65
|
-
const ns = UI.ns
|
|
66
64
|
let stateStore
|
|
67
65
|
if (options.newInstance) {
|
|
68
66
|
stateStore = kb.sym(options.newInstance.doc().uri + '_state.ttl')
|
|
@@ -94,13 +92,13 @@ export default {
|
|
|
94
92
|
try {
|
|
95
93
|
await updateMany([], ins)
|
|
96
94
|
} catch (err) {
|
|
97
|
-
return
|
|
95
|
+
return widgets.complain(context, 'Error writing tracker configuration: ' + err)
|
|
98
96
|
}
|
|
99
97
|
/*
|
|
100
98
|
try {
|
|
101
99
|
await kb.updater.updateMany([], kb.statementsMatching(undefined, undefined, undefined, stateStore))
|
|
102
100
|
} catch (err) {
|
|
103
|
-
return
|
|
101
|
+
return widgets.complain(context, 'Error writing tracker state file: ' + err)
|
|
104
102
|
}
|
|
105
103
|
*/
|
|
106
104
|
const dom = context.dom
|
|
@@ -126,7 +124,7 @@ export default {
|
|
|
126
124
|
|
|
127
125
|
function complain (message) {
|
|
128
126
|
console.warn(message)
|
|
129
|
-
paneDiv.appendChild(
|
|
127
|
+
paneDiv.appendChild(widgets.errorMessageBlock(dom, message))
|
|
130
128
|
}
|
|
131
129
|
|
|
132
130
|
function complainIfBad (ok, message) {
|
|
@@ -146,26 +144,13 @@ export default {
|
|
|
146
144
|
if (!collection) throw new Error(`Classification ${klass} has no disjointUnionOf`)
|
|
147
145
|
if (!collection.elements) throw new Error(`Classification ${klass} has no array`)
|
|
148
146
|
const needed = new Set(collection.elements.map(x => x.uri))
|
|
149
|
-
|
|
150
147
|
const existing = new Set(kb.each(null, ns.rdfs('subClassOf'), klass, doc).map(x => x.uri))
|
|
151
|
-
|
|
148
|
+
|
|
149
|
+
const superfluous = [...existing].filter(sub => !needed.has(sub))
|
|
152
150
|
const deleteActions = superfluous.map(sub => { return { action: 'delete', st: $rdf.st(kb.sym(sub), ns.rdfs('subClassOf'), klass, doc) } })
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
deletables.push($rdf.st(kb.sym(sub), ns.rdfs('subClassOf'), klass, doc))
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
*/
|
|
160
|
-
const missing = needed.filter(sub => !existing.has(sub))
|
|
161
|
-
const insertActions = missing.ma(sub => { return { action: 'insert', st: $rdf.st(kb.sym(sub), ns.rdfs('subClassOf'), klass, doc) } })
|
|
162
|
-
/*
|
|
163
|
-
for (const sub of needed) {
|
|
164
|
-
if (!existing.has(sub)) {
|
|
165
|
-
insertables.push($rdf.st(kb.sym(sub), ns.rdfs('subClassOf'), klass, doc))
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
*/
|
|
151
|
+
|
|
152
|
+
const missing = [...needed].filter(sub => !existing.has(sub))
|
|
153
|
+
const insertActions = missing.map(sub => { return { action: 'insert', st: $rdf.st(kb.sym(sub), ns.rdfs('subClassOf'), klass, doc) } })
|
|
169
154
|
return deleteActions.concat(insertActions)
|
|
170
155
|
}
|
|
171
156
|
const doc = tracker.doc()
|
|
@@ -189,42 +174,42 @@ export default {
|
|
|
189
174
|
/** /////////////////////////// Board
|
|
190
175
|
*/
|
|
191
176
|
function renderBoard (tracker, klass) {
|
|
192
|
-
const states =
|
|
177
|
+
const states = kb.any(tracker, ns.wf('issueClass'))
|
|
193
178
|
klass = klass || states // default to states
|
|
194
179
|
const doingStates = klass.sameTerm(states)
|
|
195
180
|
|
|
196
181
|
// These are states we will show by default: the open issues.
|
|
197
|
-
const stateArray =
|
|
182
|
+
const stateArray = kb.any(klass, ns.owl('disjointUnionOf'))
|
|
198
183
|
if (!stateArray) {
|
|
199
184
|
return complain(`Configuration error: state ${states} does not have substates`)
|
|
200
185
|
}
|
|
201
186
|
let columnValues = stateArray.elements
|
|
202
187
|
if (doingStates && columnValues.length > 2 // and there are more than two
|
|
203
188
|
) { // strip out closed states
|
|
204
|
-
columnValues = columnValues.filter(state =>
|
|
189
|
+
columnValues = columnValues.filter(state => kb.holds(state, ns.rdfs('subClassOf'), ns.wf('Open')) || state.sameTerm(ns.wf('Open')))
|
|
205
190
|
}
|
|
206
191
|
|
|
207
192
|
async function columnDropHandler (issue, newState) {
|
|
208
193
|
const currentState = getState(issue, klass)
|
|
209
|
-
const tracker =
|
|
210
|
-
const stateStore =
|
|
194
|
+
const tracker = kb.the(issue, ns.wf('tracker'), null, issue.doc())
|
|
195
|
+
const stateStore = kb.any(tracker, ns.wf('stateStore'))
|
|
211
196
|
|
|
212
197
|
if (newState.sameTerm(currentState)) {
|
|
213
|
-
// alert('Same state ' +
|
|
198
|
+
// alert('Same state ' + utils.label(currentState)) // @@ remove
|
|
214
199
|
return
|
|
215
200
|
}
|
|
216
201
|
try {
|
|
217
|
-
await
|
|
202
|
+
await kb.updater.update(
|
|
218
203
|
[$rdf.st(issue, ns.rdf('type'), currentState, stateStore)],
|
|
219
204
|
[$rdf.st(issue, ns.rdf('type'), newState, stateStore)])
|
|
220
205
|
} catch (err) {
|
|
221
|
-
|
|
206
|
+
widgets.complain(context, 'Unable to change issue state: ' + err)
|
|
222
207
|
}
|
|
223
208
|
boardDiv.refresh() // reorganize board to match the new reality
|
|
224
209
|
}
|
|
225
210
|
|
|
226
211
|
function isOpen (issue) {
|
|
227
|
-
const types =
|
|
212
|
+
const types = kb.findTypeURIs(issue)
|
|
228
213
|
return !!types[ns.wf('Open').uri]
|
|
229
214
|
}
|
|
230
215
|
|
|
@@ -242,15 +227,15 @@ export default {
|
|
|
242
227
|
/** ////////////// Table
|
|
243
228
|
*/
|
|
244
229
|
function tableRefreshButton (stateStore, tableDiv) {
|
|
245
|
-
const refreshButton = widgets.button(dom,
|
|
230
|
+
const refreshButton = widgets.button(dom, icons.iconBase + 'noun_479395.svg',
|
|
246
231
|
'refresh table', async _event => {
|
|
247
232
|
try {
|
|
248
|
-
await
|
|
233
|
+
await kb.fetcher.load(stateStore, { force: true, clearPreviousData: true })
|
|
249
234
|
} catch (err) {
|
|
250
235
|
alert(err)
|
|
251
236
|
return
|
|
252
237
|
}
|
|
253
|
-
|
|
238
|
+
widgets.refreshTree(tableDiv)
|
|
254
239
|
})
|
|
255
240
|
return refreshButton
|
|
256
241
|
}
|
|
@@ -261,10 +246,10 @@ export default {
|
|
|
261
246
|
query.pat.optional.push(clause)
|
|
262
247
|
return clause
|
|
263
248
|
}
|
|
264
|
-
const states =
|
|
265
|
-
const cats =
|
|
249
|
+
const states = kb.any(subject, ns.wf('issueClass'))
|
|
250
|
+
const cats = kb.each(tracker, ns.wf('issueCategory')) // zero or more
|
|
266
251
|
const vars = ['issue', 'state', 'created']
|
|
267
|
-
const query = new $rdf.Query(
|
|
252
|
+
const query = new $rdf.Query(utils.label(subject))
|
|
268
253
|
for (let i = 0; i < cats.length; i++) {
|
|
269
254
|
vars.push('_cat_' + i)
|
|
270
255
|
}
|
|
@@ -286,7 +271,7 @@ export default {
|
|
|
286
271
|
clause.add(v['_cat_' + i], ns.rdfs('subClassOf'), cats[i])
|
|
287
272
|
}
|
|
288
273
|
|
|
289
|
-
const propertyList =
|
|
274
|
+
const propertyList = kb.any(tracker, ns.wf('propertyList')) // List of extra properties
|
|
290
275
|
if (propertyList) {
|
|
291
276
|
const properties = propertyList.elements
|
|
292
277
|
for (let p = 0; p < properties.length; p++) {
|
|
@@ -302,10 +287,10 @@ export default {
|
|
|
302
287
|
}
|
|
303
288
|
|
|
304
289
|
const selectedStates = {}
|
|
305
|
-
const possible =
|
|
290
|
+
const possible = kb.each(undefined, ns.rdfs('subClassOf'), states)
|
|
306
291
|
possible.forEach(function (s) {
|
|
307
292
|
if (
|
|
308
|
-
|
|
293
|
+
kb.holds(s, ns.rdfs('subClassOf'), ns.wf('Open')) ||
|
|
309
294
|
s.sameTerm(ns.wf('Open'))
|
|
310
295
|
) {
|
|
311
296
|
selectedStates[s.uri] = true
|
|
@@ -318,7 +303,7 @@ export default {
|
|
|
318
303
|
exposeOverlay(subject, context)
|
|
319
304
|
}
|
|
320
305
|
|
|
321
|
-
const tableDiv =
|
|
306
|
+
const tableDiv = table(dom, {
|
|
322
307
|
query: query,
|
|
323
308
|
keyVariable: '?issue', // Charactersic of row
|
|
324
309
|
sortBy: '?created', // By default, sort by date
|
|
@@ -329,7 +314,7 @@ export default {
|
|
|
329
314
|
'?state': { initialSelection: selectedStates, label: 'Status' }
|
|
330
315
|
}
|
|
331
316
|
})
|
|
332
|
-
const stateStore =
|
|
317
|
+
const stateStore = kb.any(subject, ns.wf('stateStore'))
|
|
333
318
|
tableDiv.appendChild(tableRefreshButton(stateStore, tableDiv))
|
|
334
319
|
return tableDiv
|
|
335
320
|
}
|
|
@@ -349,14 +334,14 @@ export default {
|
|
|
349
334
|
}
|
|
350
335
|
const issuePane = context.session.paneRegistry.byName('issue')
|
|
351
336
|
const relevantPanes = [issuePane]
|
|
352
|
-
|
|
337
|
+
create.newThingUI(creationContext, context, relevantPanes) // Have to pass panes down newUI
|
|
353
338
|
return creationDiv
|
|
354
339
|
}
|
|
355
340
|
|
|
356
341
|
function renderInstances (theClass) {
|
|
357
342
|
const instancesDiv = dom.createElement('div')
|
|
358
343
|
const context = { dom, div: instancesDiv, noun: 'tracker' }
|
|
359
|
-
|
|
344
|
+
login.registrationList(context, { public: true, private: true, type: theClass }).then(_context2 => {
|
|
360
345
|
instancesDiv.appendChild(renderCreationControl(instancesDiv))
|
|
361
346
|
/* // keep this code in case we need a form
|
|
362
347
|
const InstancesForm = ns.wf('TrackerInstancesForm')
|
|
@@ -370,12 +355,21 @@ export default {
|
|
|
370
355
|
}
|
|
371
356
|
function renderSettings (tracker) {
|
|
372
357
|
const settingsDiv = dom.createElement('div')
|
|
358
|
+
const states = kb.any(tracker, ns.wf('issueClass'))
|
|
359
|
+
const views = [tableView, states] // Possible default views
|
|
360
|
+
.concat(kb.each(tracker, ns.wf('issueCategory')))
|
|
361
|
+
const box = settingsDiv.appendChild(dom.createElement('div'))
|
|
362
|
+
const lhs = widgets.renderNameValuePair(dom, kb, box, null, 'Default view') // @@ use a predicate?
|
|
363
|
+
lhs.appendChild(widgets.makeSelectForOptions(dom, kb, tracker,
|
|
364
|
+
ns.wf('defaultView'),
|
|
365
|
+
views, {}, tracker.doc()))
|
|
366
|
+
|
|
373
367
|
// A registration control allows the to record this tracker in their type index
|
|
374
368
|
const context = { dom, div: settingsDiv, noun: 'tracker' }
|
|
375
|
-
|
|
369
|
+
login.registrationControl(context, tracker, ns.wf('Tracker')).then(_context2 => {
|
|
376
370
|
const settingsForm = ns.wf('TrackerSettingsForm')
|
|
377
371
|
const text = trackerSettingsFormText
|
|
378
|
-
$rdf.parse(text,
|
|
372
|
+
$rdf.parse(text, kb, settingsForm.doc().uri, 'text/turtle')
|
|
379
373
|
widgets.appendForm(dom, settingsDiv, {}, tracker, settingsForm,
|
|
380
374
|
tracker.doc(), complainIfBad)
|
|
381
375
|
})
|
|
@@ -393,76 +387,103 @@ export default {
|
|
|
393
387
|
ele.appendChild(renderSettings(tracker))
|
|
394
388
|
} else if (object.sameTerm(instancesView)) {
|
|
395
389
|
ele.appendChild(renderInstances(ns.wf('Tracker')))
|
|
396
|
-
} else if ((
|
|
397
|
-
(
|
|
390
|
+
} else if ((kb.holds(tracker, ns.wf('issueCategory'), object)) ||
|
|
391
|
+
(kb.holds(tracker, ns.wf('issueClass'), object))) {
|
|
398
392
|
ele.appendChild(renderBoard(tracker, object))
|
|
399
393
|
} else {
|
|
400
394
|
throw new Error('Unexpected tab type: ' + object)
|
|
401
395
|
}
|
|
402
396
|
}
|
|
403
|
-
const states =
|
|
397
|
+
const states = kb.any(tracker, ns.wf('issueClass'))
|
|
404
398
|
const items = [instancesView, tableView, states]
|
|
405
|
-
.concat(
|
|
399
|
+
.concat(kb.each(tracker, ns.wf('issueCategory')))
|
|
406
400
|
items.push(settingsView)
|
|
407
|
-
const selectedTab = tableView
|
|
401
|
+
const selectedTab = kb.any(tracker, ns.wf('defaultView'), null, tracker.doc()) || tableView
|
|
408
402
|
const options = { renderMain, items, selectedTab }
|
|
409
403
|
|
|
410
404
|
// Add stuff to the ontologies which we believe but they don't say
|
|
411
405
|
const doc = instancesView.doc()
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
406
|
+
kb.add(instancesView, ns.rdfs('label'), 'My Trackers', doc) // @@ squatting on wf ns
|
|
407
|
+
kb.add(settingsView, ns.rdfs('label'), 'Settings', doc) // @@ squatting on wf ns
|
|
408
|
+
kb.add(states, ns.rdfs('label'), 'By State', doc) // @@ squatting on wf ns
|
|
415
409
|
|
|
416
|
-
const
|
|
417
|
-
return
|
|
410
|
+
const myTabs = tabs.tabWidget(options)
|
|
411
|
+
return myTabs
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
async function renderSingleIssue () {
|
|
415
|
+
tracker = kb.any(subject, ns.wf('tracker'))
|
|
416
|
+
if (!tracker) throw new Error('This issue ' + subject + 'has no tracker')
|
|
417
|
+
|
|
418
|
+
// Much data is in the tracker instance, so wait for the data from it
|
|
419
|
+
try {
|
|
420
|
+
const _xhrs = await context.session.store.fetcher.load(tracker.doc())
|
|
421
|
+
} catch (err) {
|
|
422
|
+
const msg = 'Failed to load tracker config ' + tracker.doc() + ': ' + err
|
|
423
|
+
return complain(msg)
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const stateStore = kb.any(tracker, ns.wf('stateStore'))
|
|
427
|
+
if (!stateStore) {
|
|
428
|
+
return complain('Tracker has no state store: ' + tracker)
|
|
429
|
+
}
|
|
430
|
+
try {
|
|
431
|
+
await context.session.store.fetcher.load(subject)
|
|
432
|
+
} catch (err) {
|
|
433
|
+
return complain('Failed to load issue state ' + stateStore + ': ' + err)
|
|
434
|
+
}
|
|
435
|
+
paneDiv.appendChild(renderIssue(subject, context))
|
|
436
|
+
updater.addDownstreamChangeListener(stateStore, function () {
|
|
437
|
+
widgets.refreshTree(paneDiv)
|
|
438
|
+
}) // Live update
|
|
418
439
|
}
|
|
419
440
|
|
|
420
441
|
async function renderTracker () {
|
|
421
442
|
function showNewIssue (issue) {
|
|
422
|
-
|
|
443
|
+
widgets.refreshTree(paneDiv)
|
|
423
444
|
exposeOverlay(issue, context)
|
|
424
|
-
|
|
445
|
+
newIssueButton.disabled = false // https://stackoverflow.com/questions/41176582/enable-disable-a-button-in-pure-javascript
|
|
425
446
|
}
|
|
426
447
|
tracker = subject
|
|
427
448
|
|
|
428
449
|
try {
|
|
429
|
-
await fixSubClasses(
|
|
450
|
+
await fixSubClasses(kb, tracker)
|
|
430
451
|
} catch (err) {
|
|
431
452
|
console.log('@@@ Error fixing subclasses in config: ' + err)
|
|
432
453
|
}
|
|
433
454
|
|
|
434
|
-
const states =
|
|
455
|
+
const states = kb.any(subject, ns.wf('issueClass'))
|
|
435
456
|
if (!states) throw new Error('This tracker has no issueClass')
|
|
436
|
-
const stateStore =
|
|
457
|
+
const stateStore = kb.any(subject, ns.wf('stateStore'))
|
|
437
458
|
if (!stateStore) throw new Error('This tracker has no stateStore')
|
|
438
459
|
|
|
439
|
-
|
|
460
|
+
// const me = await authn.currentUser()
|
|
440
461
|
|
|
441
462
|
const h = dom.createElement('h2')
|
|
442
463
|
h.setAttribute('style', 'font-size: 150%')
|
|
443
464
|
paneDiv.appendChild(h)
|
|
444
|
-
const classLabel =
|
|
465
|
+
const classLabel = utils.label(states)
|
|
445
466
|
h.appendChild(dom.createTextNode(classLabel + ' list')) // Use class label @@I18n
|
|
446
467
|
|
|
447
468
|
// New Issue button
|
|
448
|
-
const
|
|
469
|
+
const newIssueButton = dom.createElement('button')
|
|
449
470
|
const container = dom.createElement('div')
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
container.appendChild(
|
|
471
|
+
newIssueButton.setAttribute('type', 'button')
|
|
472
|
+
newIssueButton.setAttribute('style', 'padding: 0.3em; font-size: 100%; margin: 0.5em;')
|
|
473
|
+
container.appendChild(newIssueButton)
|
|
453
474
|
paneDiv.appendChild(container)
|
|
454
475
|
const img = dom.createElement('img')
|
|
455
|
-
img.setAttribute('src',
|
|
476
|
+
img.setAttribute('src', icons.iconBase + 'noun_19460_green.svg')
|
|
456
477
|
img.setAttribute('style', 'width: 1em; height: 1em; margin: 0.2em;')
|
|
457
|
-
|
|
478
|
+
newIssueButton.appendChild(img)
|
|
458
479
|
const span = dom.createElement('span')
|
|
459
480
|
span.innerHTML = 'New ' + classLabel
|
|
460
|
-
|
|
461
|
-
|
|
481
|
+
newIssueButton.appendChild(span)
|
|
482
|
+
newIssueButton.addEventListener(
|
|
462
483
|
'click',
|
|
463
484
|
function (_event) {
|
|
464
|
-
|
|
465
|
-
container.appendChild(newIssueForm(dom,
|
|
485
|
+
newIssueButton.disabled = true
|
|
486
|
+
container.appendChild(newIssueForm(dom, kb, tracker, null, showNewIssue))
|
|
466
487
|
},
|
|
467
488
|
false
|
|
468
489
|
)
|
|
@@ -482,7 +503,7 @@ export default {
|
|
|
482
503
|
} else {
|
|
483
504
|
console.log('No table refresh function?!')
|
|
484
505
|
}
|
|
485
|
-
paneDiv.appendChild(newTrackerButton(subject))
|
|
506
|
+
paneDiv.appendChild(newTrackerButton(subject, context))
|
|
486
507
|
updater.addDownstreamChangeListener(stateStore, tableDiv.refresh) // Live update
|
|
487
508
|
})
|
|
488
509
|
.catch(function (err) {
|
|
@@ -498,73 +519,30 @@ export default {
|
|
|
498
519
|
const settingsView = ns.wf('SettingsView')
|
|
499
520
|
const instancesView = ns.wf('InstancesView')
|
|
500
521
|
|
|
501
|
-
const updater =
|
|
502
|
-
const t =
|
|
522
|
+
const updater = kb.updater
|
|
523
|
+
const t = kb.findTypeURIs(subject)
|
|
503
524
|
let tracker
|
|
504
525
|
|
|
505
526
|
// Whatever we are rendering, lets load the ontology
|
|
506
|
-
const flowOntology =
|
|
507
|
-
if (!
|
|
527
|
+
const flowOntology = ns.wf('').doc()
|
|
528
|
+
if (!kb.holds(undefined, undefined, undefined, flowOntology)) {
|
|
508
529
|
// If not loaded already
|
|
509
|
-
$rdf.parse(require('./wf.js'),
|
|
530
|
+
$rdf.parse(require('./wf.js'), kb, flowOntology.uri, 'text/turtle') // Load ontology directly
|
|
510
531
|
}
|
|
511
|
-
const userInterfaceOntology =
|
|
512
|
-
if (!
|
|
532
|
+
const userInterfaceOntology = ns.ui('').doc()
|
|
533
|
+
if (!kb.holds(undefined, undefined, undefined, userInterfaceOntology)) {
|
|
513
534
|
// If not loaded already
|
|
514
|
-
$rdf.parse(require('./ui.js'),
|
|
535
|
+
$rdf.parse(require('./ui.js'), kb, userInterfaceOntology.uri, 'text/turtle') // Load ontology directly
|
|
515
536
|
}
|
|
516
537
|
|
|
517
538
|
// Render a single issue
|
|
518
539
|
if (
|
|
519
540
|
t['http://www.w3.org/2005/01/wf/flow#Task'] ||
|
|
520
|
-
|
|
541
|
+
kb.holds(subject, ns.wf('tracker'))
|
|
521
542
|
) {
|
|
522
|
-
|
|
523
|
-
if (!tracker) throw new Error('This issue ' + subject + 'has no tracker')
|
|
524
|
-
|
|
525
|
-
// Much data is in the tracker instance, so wait for the data from it
|
|
526
|
-
|
|
527
|
-
context.session.store.fetcher
|
|
528
|
-
.load(tracker.doc())
|
|
529
|
-
.then(function (_xhrs) {
|
|
530
|
-
const stateStore = store.any(tracker, ns.wf('stateStore'))
|
|
531
|
-
context.session.store.fetcher.nowOrWhenFetched(
|
|
532
|
-
stateStore,
|
|
533
|
-
subject,
|
|
534
|
-
function drawIssuePane2 (ok, body) {
|
|
535
|
-
if (!ok) {
|
|
536
|
-
return console.log(
|
|
537
|
-
'Failed to load state ' + stateStore + ' ' + body
|
|
538
|
-
)
|
|
539
|
-
}
|
|
540
|
-
paneDiv.appendChild(renderIssue(subject, context))
|
|
541
|
-
updater.addDownstreamChangeListener(stateStore, function () {
|
|
542
|
-
UI.widgets.refreshTree(paneDiv)
|
|
543
|
-
}) // Live update
|
|
544
|
-
}
|
|
545
|
-
)
|
|
546
|
-
})
|
|
547
|
-
.catch(err => {
|
|
548
|
-
const msg = 'Failed to load config ' + tracker.doc() + ' ' + err
|
|
549
|
-
return complain(msg)
|
|
550
|
-
})
|
|
551
|
-
context.session.store.fetcher.nowOrWhenFetched(
|
|
552
|
-
tracker.doc(),
|
|
553
|
-
subject,
|
|
554
|
-
function drawIssuePane1 (ok, body) {
|
|
555
|
-
if (!ok) {
|
|
556
|
-
return console.log(
|
|
557
|
-
'Failed to load config ' + tracker.doc() + ' ' + body
|
|
558
|
-
)
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
) // End nowOrWhenFetched tracker
|
|
562
|
-
|
|
563
|
-
// /////////////////////////////////////////////////////////
|
|
564
|
-
//
|
|
565
|
-
// Render a Tracker instance
|
|
566
|
-
//
|
|
543
|
+
renderSingleIssue().then(() => console.log('Single issue rendered'))
|
|
567
544
|
} else if (t['http://www.w3.org/2005/01/wf/flow#Tracker']) {
|
|
545
|
+
// Render a Tracker instance
|
|
568
546
|
renderTracker().then(() => console.log('Tracker rendered'))
|
|
569
547
|
} else {
|
|
570
548
|
console.log(
|
|
@@ -588,9 +566,9 @@ export default {
|
|
|
588
566
|
return
|
|
589
567
|
}
|
|
590
568
|
|
|
591
|
-
loginOutButton =
|
|
569
|
+
loginOutButton = authn.loginStatusBox(dom, webIdUri => {
|
|
592
570
|
if (webIdUri) {
|
|
593
|
-
context.me =
|
|
571
|
+
context.me = kb.sym(webIdUri)
|
|
594
572
|
console.log('Web ID set from login button: ' + webIdUri)
|
|
595
573
|
paneDiv.removeChild(loginOutButton)
|
|
596
574
|
// enable things
|
package/newIssue.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// Form to collect data about a New Issue
|
|
2
2
|
//
|
|
3
|
-
import
|
|
3
|
+
import { ns, rdf, utils } from 'solid-ui'
|
|
4
4
|
|
|
5
|
-
const $rdf =
|
|
6
|
-
const ns = UI.ns
|
|
5
|
+
const $rdf = rdf
|
|
7
6
|
|
|
8
7
|
export function newIssueForm (dom, kb, tracker, superIssue, showNewIssue) {
|
|
9
8
|
const form = dom.createElement('div') // form is broken as HTML behaviour can resurface on js error
|
|
@@ -87,7 +86,7 @@ export function newIssueForm (dom, kb, tracker, superIssue, showNewIssue) {
|
|
|
87
86
|
}
|
|
88
87
|
|
|
89
88
|
const states = kb.any(tracker, ns.wf('issueClass'))
|
|
90
|
-
const classLabel =
|
|
89
|
+
const classLabel = utils.label(states)
|
|
91
90
|
form.innerHTML =
|
|
92
91
|
'<h2>Add new ' +
|
|
93
92
|
(superIssue ? 'sub ' : '') +
|
package/newTracker.js
CHANGED
|
@@ -3,6 +3,7 @@ import { store } from 'solid-logic'
|
|
|
3
3
|
|
|
4
4
|
const $rdf = UI.rdf
|
|
5
5
|
const ns = UI.ns
|
|
6
|
+
const kb = store
|
|
6
7
|
const updater = store.updater
|
|
7
8
|
|
|
8
9
|
/* Button for making a whole new tracker
|
|
@@ -28,18 +29,17 @@ export function newTrackerButton (thisTracker, context) {
|
|
|
28
29
|
if (u === stateStore.uri) return newStore // special case
|
|
29
30
|
if (u.slice(0, oldBase.length) === oldBase) {
|
|
30
31
|
u = base + u.slice(oldBase.length)
|
|
31
|
-
$rdf.log.debug(' Map ' + x.uri + ' to ' + u)
|
|
32
32
|
}
|
|
33
|
-
return
|
|
33
|
+
return kb.sym(u)
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
const appPathSegment = 'issuetracker.w3.org' // how to allocate this string and connect to
|
|
37
37
|
// console.log("Ready to make new instance at "+ws)
|
|
38
38
|
const sp = UI.ns.space
|
|
39
|
-
const
|
|
39
|
+
const kb = context.session.store
|
|
40
40
|
|
|
41
41
|
if (!base) {
|
|
42
|
-
base =
|
|
42
|
+
base = kb.any(ws, sp('uriPrefix')).value
|
|
43
43
|
if (base.slice(-1) !== '/') {
|
|
44
44
|
$rdf.log.error(
|
|
45
45
|
appPathSegment + ': No / at end of uriPrefix ' + base
|
|
@@ -52,8 +52,8 @@ export function newTrackerButton (thisTracker, context) {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const stateStore =
|
|
56
|
-
const newStore =
|
|
55
|
+
const stateStore = kb.any(thisTracker, ns.wf('stateStore'))
|
|
56
|
+
const newStore = kb.sym(base + 'store.ttl')
|
|
57
57
|
|
|
58
58
|
const here = thisTracker.doc()
|
|
59
59
|
|
|
@@ -62,7 +62,7 @@ export function newTrackerButton (thisTracker, context) {
|
|
|
62
62
|
const there = morph(here)
|
|
63
63
|
const newTracker = morph(thisTracker)
|
|
64
64
|
|
|
65
|
-
const myConfig =
|
|
65
|
+
const myConfig = kb.statementsMatching(
|
|
66
66
|
undefined,
|
|
67
67
|
undefined,
|
|
68
68
|
undefined,
|
|
@@ -70,7 +70,7 @@ export function newTrackerButton (thisTracker, context) {
|
|
|
70
70
|
)
|
|
71
71
|
for (let i = 0; i < myConfig.length; i++) {
|
|
72
72
|
const st = myConfig[i]
|
|
73
|
-
|
|
73
|
+
kb.add(
|
|
74
74
|
morph(st.subject),
|
|
75
75
|
morph(st.predicate),
|
|
76
76
|
morph(st.object),
|
|
@@ -80,15 +80,15 @@ export function newTrackerButton (thisTracker, context) {
|
|
|
80
80
|
|
|
81
81
|
// Keep a paper trail @@ Revisit when we have non-public ones @@ Privacy
|
|
82
82
|
//
|
|
83
|
-
|
|
83
|
+
kb.add(newTracker, UI.ns.space('inspiration'), thisTracker, stateStore)
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
kb.add(newTracker, UI.ns.space('inspiration'), thisTracker, there)
|
|
86
86
|
|
|
87
|
-
// $rdf.log.debug("\n Ready to put " +
|
|
87
|
+
// $rdf.log.debug("\n Ready to put " + kb.statementsMatching(undefined, undefined, undefined, there)); //@@
|
|
88
88
|
|
|
89
89
|
updater.put(
|
|
90
90
|
there,
|
|
91
|
-
|
|
91
|
+
kb.statementsMatching(undefined, undefined, undefined, there),
|
|
92
92
|
'text/turtle',
|
|
93
93
|
function (uri2, ok, message) {
|
|
94
94
|
if (ok) {
|