issue-pane 2.4.9-e1b104be → 2.4.9-ee8ae54d
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/board.js +7 -7
- package/issue.js +71 -80
- package/issuePane.js +61 -67
- package/newIssue.js +1 -1
- package/newTracker.js +24 -25
- package/package.json +4 -3
package/board.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import * as UI from 'solid-ui'
|
|
14
|
-
|
|
14
|
+
import { store } from 'solid-logic'
|
|
15
15
|
const ns = UI.ns
|
|
16
16
|
const $rdf = UI.rdf
|
|
17
17
|
|
|
@@ -38,7 +38,7 @@ export function board (dom, columnValues, renderItem, options) {
|
|
|
38
38
|
function droppedURIHandler (uris) {
|
|
39
39
|
uris.forEach(function (u) {
|
|
40
40
|
console.log('Dropped on column: ' + u)
|
|
41
|
-
const item =
|
|
41
|
+
const item = store.sym(u)
|
|
42
42
|
options.columnDropHandler(item, x)
|
|
43
43
|
})
|
|
44
44
|
}
|
|
@@ -54,19 +54,19 @@ export function board (dom, columnValues, renderItem, options) {
|
|
|
54
54
|
function defaultRenderItem (item, category) {
|
|
55
55
|
const card = dom.createElement('div')
|
|
56
56
|
const table = card.appendChild(dom.createElement('table'))
|
|
57
|
-
const classes =
|
|
58
|
-
const catColors = classes.map(cat =>
|
|
57
|
+
const classes = store.each(item, ns.rdf('type'))
|
|
58
|
+
const catColors = classes.map(cat => store.any(cat, ns.ui('backgroundColor'))).filter(c => c)
|
|
59
59
|
|
|
60
60
|
table.appendChild(UI.widgets.personTR(dom, null, item))
|
|
61
61
|
table.subject = item
|
|
62
62
|
table.style = 'margin: 1em;' // @@ use style.js
|
|
63
|
-
const backgroundColor = catColors[0] ||
|
|
63
|
+
const backgroundColor = catColors[0] || store.any(category, ns.ui('backgroundColor'))
|
|
64
64
|
card.style.backgroundColor = backgroundColor ? backgroundColor.value : '#fff'
|
|
65
65
|
return card
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
function sortedBy (values, predicate, defaultSortValue, reverse) {
|
|
69
|
-
const toBeSorted = values.map(x => [
|
|
69
|
+
const toBeSorted = values.map(x => [store.any(x, predicate) || defaultSortValue, x])
|
|
70
70
|
toBeSorted.sort()
|
|
71
71
|
if (reverse) toBeSorted.reverse() // @@ check
|
|
72
72
|
return toBeSorted.map(pair => pair[1])
|
|
@@ -82,7 +82,7 @@ export function board (dom, columnValues, renderItem, options) {
|
|
|
82
82
|
}
|
|
83
83
|
for (let col = mainRow.firstChild; col; col = col.nextSibling) {
|
|
84
84
|
const category = col.subject
|
|
85
|
-
let items =
|
|
85
|
+
let items = store.each(null, ns.rdf('type'), category)
|
|
86
86
|
const sortBy = options.sortBy || ns.dct('created')
|
|
87
87
|
if (options.filter) {
|
|
88
88
|
items = items.filter(options.filter)
|
package/issue.js
CHANGED
|
@@ -1,36 +1,24 @@
|
|
|
1
1
|
// All the UI for a single issue, without store load or listening for changes
|
|
2
2
|
//
|
|
3
|
-
import {
|
|
3
|
+
import { icons, messageArea, ns, rdf, style, utils, widgets } from 'solid-ui'
|
|
4
|
+
import { authn, store } from 'solid-logic'
|
|
4
5
|
import { newIssueForm } from './newIssue'
|
|
5
6
|
|
|
6
7
|
const $rdf = rdf
|
|
7
|
-
const kb = store
|
|
8
8
|
|
|
9
9
|
const SET_MODIFIED_DATES = false
|
|
10
10
|
|
|
11
|
-
export const TASK_ICON = icons.iconBase + 'noun_17020_gray-tick.svg'
|
|
12
|
-
export const OPEN_TASK_ICON = icons.iconBase + 'noun_17020_sans-tick.svg'
|
|
13
|
-
export const CLOSED_TASK_ICON = icons.iconBase + 'noun_17020.svg'
|
|
14
|
-
|
|
15
11
|
function complain (message, context) {
|
|
16
12
|
console.warn(message)
|
|
17
13
|
context.paneDiv.appendChild(widgets.errorMessageBlock(context.dom, message))
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
export function isOpen (issue) {
|
|
21
|
-
const types = kb.findTypeURIs(issue)
|
|
22
|
-
return !!types[ns.wf('Open').uri]
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function iconForIssue (issue) {
|
|
26
|
-
return isOpen(issue) ? TASK_ICON : CLOSED_TASK_ICON
|
|
27
|
-
}
|
|
28
16
|
export function getState (issue, classification) {
|
|
29
|
-
const tracker =
|
|
30
|
-
const states =
|
|
17
|
+
const tracker = store.the(issue, ns.wf('tracker'), null, issue.doc())
|
|
18
|
+
const states = store.any(tracker, ns.wf('issueClass'))
|
|
31
19
|
classification = classification || states
|
|
32
|
-
const types =
|
|
33
|
-
.filter(ty =>
|
|
20
|
+
const types = store.each(issue, ns.rdf('type'))
|
|
21
|
+
.filter(ty => store.holds(ty, ns.rdfs('subClassOf'), classification))
|
|
34
22
|
if (types.length !== 1) {
|
|
35
23
|
// const initialState = kb.any(tracker, ns.wf('initialState')) No do NOT default
|
|
36
24
|
// if (initialState) return initialState
|
|
@@ -41,8 +29,8 @@ export function getState (issue, classification) {
|
|
|
41
29
|
|
|
42
30
|
export function renderIssueCard (issue, context) {
|
|
43
31
|
function getBackgroundColor () {
|
|
44
|
-
const classes =
|
|
45
|
-
const catColors = classes.map(cat =>
|
|
32
|
+
const classes = store.each(issue, ns.rdf('type')) // @@ pick cats in order then state
|
|
33
|
+
const catColors = classes.map(cat => store.any(cat, ns.ui('backgroundColor'))).filter(c => !!c)
|
|
46
34
|
|
|
47
35
|
if (catColors.length) return catColors[0].value // pick first one
|
|
48
36
|
return null
|
|
@@ -58,7 +46,7 @@ export function renderIssueCard (issue, context) {
|
|
|
58
46
|
const card = dom.createElement('div')
|
|
59
47
|
const table = card.appendChild(dom.createElement('table'))
|
|
60
48
|
table.style.width = '100%'
|
|
61
|
-
const options = { draggable: false } // Let the baord make
|
|
49
|
+
const options = { draggable: false } // Let the baord make th ewhole card draggable
|
|
62
50
|
table.appendChild(widgets.personTR(dom, null, issue, options))
|
|
63
51
|
table.subject = issue
|
|
64
52
|
card.style = 'border-radius: 0.4em; border: 0.05em solid grey; margin: 0.3em;'
|
|
@@ -78,7 +66,7 @@ export function renderIssueCard (issue, context) {
|
|
|
78
66
|
if (uncategorized) {
|
|
79
67
|
const deleteButton = widgets.deleteButtonWithCheck(dom, buttonsCell, 'issue', async function () { // noun?
|
|
80
68
|
try {
|
|
81
|
-
await
|
|
69
|
+
await store.updater.update(store.connectedStatements(issue))
|
|
82
70
|
} catch (err) {
|
|
83
71
|
complain(`Unable to delete issue: ${err}`, context)
|
|
84
72
|
}
|
|
@@ -114,15 +102,16 @@ export function exposeOverlay (subject, context) {
|
|
|
114
102
|
|
|
115
103
|
export function renderIssue (issue, context) {
|
|
116
104
|
// Don't bother changing the last modified dates of things: save time
|
|
117
|
-
function setModifiedDate (subj,
|
|
105
|
+
function setModifiedDate (subj, store, doc) {
|
|
118
106
|
if (SET_MODIFIED_DATES) {
|
|
119
107
|
if (!getOption(tracker, 'trackLastModified')) return
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
)
|
|
108
|
+
let deletions = store.statementsMatching(issue, ns.dct('modified'))
|
|
109
|
+
deletions = deletions.concat(
|
|
110
|
+
store.statementsMatching(issue, ns.wf('modifiedBy'))
|
|
111
|
+
)
|
|
123
112
|
const insertions = [$rdf.st(issue, ns.dct('modified'), new Date(), doc)]
|
|
124
113
|
if (me) insertions.push($rdf.st(issue, ns.wf('modifiedBy'), me, doc))
|
|
125
|
-
|
|
114
|
+
store.updater.update(deletions, insertions, function (_uri, _ok, _body) {})
|
|
126
115
|
}
|
|
127
116
|
}
|
|
128
117
|
|
|
@@ -155,32 +144,32 @@ export function renderIssue (issue, context) {
|
|
|
155
144
|
}
|
|
156
145
|
function getOption (tracker, option) {
|
|
157
146
|
// eg 'allowSubIssues'
|
|
158
|
-
const opt =
|
|
147
|
+
const opt = store.any(tracker, ns.ui(option))
|
|
159
148
|
return !!(opt && opt.value)
|
|
160
149
|
}
|
|
161
150
|
|
|
162
151
|
function setPaneStyle () {
|
|
163
|
-
const types =
|
|
164
|
-
|
|
152
|
+
const types = store.findTypeURIs(issue)
|
|
153
|
+
let mystyle = 'padding: 0.5em 1.5em 1em 1.5em; '
|
|
165
154
|
let backgroundColor = null
|
|
166
155
|
for (const uri in types) {
|
|
167
|
-
backgroundColor =
|
|
168
|
-
|
|
169
|
-
|
|
156
|
+
backgroundColor = store.any(
|
|
157
|
+
store.sym(uri),
|
|
158
|
+
store.sym('http://www.w3.org/ns/ui#backgroundColor')
|
|
170
159
|
)
|
|
171
160
|
if (backgroundColor) break
|
|
172
161
|
}
|
|
173
162
|
backgroundColor = backgroundColor ? backgroundColor.value : '#eee' // default grey
|
|
174
|
-
|
|
163
|
+
mystyle += 'background-color: ' + backgroundColor + '; '
|
|
175
164
|
issueDiv.setAttribute('style', mystyle)
|
|
176
165
|
}
|
|
177
166
|
|
|
178
|
-
/// ////////////// Body of renderIssue
|
|
179
|
-
|
|
180
167
|
const dom = context.dom
|
|
181
|
-
|
|
168
|
+
// eslint-disable-next-line no-use-before-define
|
|
169
|
+
const tracker = store.the(issue, ns.wf('tracker'), null, issue.doc())
|
|
182
170
|
if (!tracker) throw new Error('No tracker')
|
|
183
|
-
|
|
171
|
+
// eslint-disable-next-line no-use-before-define
|
|
172
|
+
const stateStore = store.any(tracker, ns.wf('stateStore'))
|
|
184
173
|
const store = issue.doc()
|
|
185
174
|
|
|
186
175
|
const issueDiv = dom.createElement('div')
|
|
@@ -190,20 +179,17 @@ export function renderIssue (issue, context) {
|
|
|
190
179
|
|
|
191
180
|
authn.checkUser() // kick off async operation
|
|
192
181
|
|
|
193
|
-
const
|
|
194
|
-
widgets.makeDraggable(iconButton, issue) // Drag me wherever you need to do stuff with this issue
|
|
195
|
-
|
|
196
|
-
const states = kb.any(tracker, ns.wf('issueClass'))
|
|
182
|
+
const states = store.any(tracker, ns.wf('issueClass'))
|
|
197
183
|
if (!states) { throw new Error('This tracker ' + tracker + ' has no issueClass') }
|
|
198
184
|
const select = widgets.makeSelectForCategory(
|
|
199
185
|
dom,
|
|
200
|
-
|
|
186
|
+
store,
|
|
201
187
|
issue,
|
|
202
188
|
states,
|
|
203
189
|
stateStore,
|
|
204
190
|
function (ok, body) {
|
|
205
191
|
if (ok) {
|
|
206
|
-
setModifiedDate(store,
|
|
192
|
+
setModifiedDate(store, store, store)
|
|
207
193
|
widgets.refreshTree(issueDiv)
|
|
208
194
|
} else {
|
|
209
195
|
console.log('Failed to change state:\n' + body)
|
|
@@ -212,18 +198,18 @@ export function renderIssue (issue, context) {
|
|
|
212
198
|
)
|
|
213
199
|
issueDiv.appendChild(select)
|
|
214
200
|
|
|
215
|
-
const cats =
|
|
216
|
-
for (
|
|
201
|
+
const cats = store.each(tracker, ns.wf('issueCategory')) // zero or more
|
|
202
|
+
for (let i = 0; i < cats.length; i++) {
|
|
217
203
|
issueDiv.appendChild(
|
|
218
204
|
widgets.makeSelectForCategory(
|
|
219
205
|
dom,
|
|
220
|
-
|
|
206
|
+
store,
|
|
221
207
|
issue,
|
|
222
|
-
|
|
208
|
+
cats[i],
|
|
223
209
|
stateStore,
|
|
224
210
|
function (ok, body) {
|
|
225
211
|
if (ok) {
|
|
226
|
-
setModifiedDate(store,
|
|
212
|
+
setModifiedDate(store, store, store)
|
|
227
213
|
widgets.refreshTree(issueDiv)
|
|
228
214
|
} else {
|
|
229
215
|
console.log('Failed to change category:\n' + body)
|
|
@@ -267,7 +253,7 @@ export function renderIssue (issue, context) {
|
|
|
267
253
|
wf:Task :creationForm core:coreIsueForm .
|
|
268
254
|
`
|
|
269
255
|
const CORE_ISSUE_FORM = ns.wf('coreIsueForm')
|
|
270
|
-
$rdf.parse(coreIssueFormText,
|
|
256
|
+
$rdf.parse(coreIssueFormText, store, CORE_ISSUE_FORM.doc().uri, 'text/turtle')
|
|
271
257
|
widgets.appendForm(
|
|
272
258
|
dom,
|
|
273
259
|
issueDiv,
|
|
@@ -296,11 +282,11 @@ export function renderIssue (issue, context) {
|
|
|
296
282
|
|
|
297
283
|
// Assigned to whom?
|
|
298
284
|
|
|
299
|
-
const assignments =
|
|
285
|
+
const assignments = store.statementsMatching(issue, ns.wf('assignee'))
|
|
300
286
|
if (assignments.length > 1) {
|
|
301
287
|
say('Weird, was assigned to more than one person. Fixing ..')
|
|
302
288
|
const deletions = assignments.slice(1)
|
|
303
|
-
|
|
289
|
+
store.updater.update(deletions, [], function (uri, ok, body) {
|
|
304
290
|
if (ok) {
|
|
305
291
|
say('Now fixed.')
|
|
306
292
|
} else {
|
|
@@ -313,16 +299,20 @@ export function renderIssue (issue, context) {
|
|
|
313
299
|
// Anyone assigned to any issue we know about
|
|
314
300
|
|
|
315
301
|
async function getPossibleAssignees () {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
302
|
+
let devs = []
|
|
303
|
+
const devGroups = store.each(issue, ns.wf('assigneeGroup'))
|
|
304
|
+
for (let i = 0; i < devGroups.length; i++) {
|
|
305
|
+
const group = devGroups[i]
|
|
306
|
+
await store.fetcher.load()
|
|
307
|
+
devs = devs.concat(store.each(group, ns.vcard('member')))
|
|
308
|
+
}
|
|
319
309
|
// Anyone who is a developer of any project which uses this tracker
|
|
320
|
-
const proj =
|
|
310
|
+
const proj = store.any(null, ns.doap('bug-database'), tracker) // What project?
|
|
321
311
|
if (proj) {
|
|
322
|
-
await
|
|
312
|
+
await store.fetcher.load(proj)
|
|
313
|
+
devs = devs.concat(store.each(proj, ns.doap('developer')))
|
|
323
314
|
}
|
|
324
|
-
|
|
325
|
-
return groupDevs.concat(projectDevs)
|
|
315
|
+
return devs
|
|
326
316
|
}
|
|
327
317
|
|
|
328
318
|
// Super issues first - like parent directories .. maybe use breadcrums from?? @@
|
|
@@ -334,7 +324,7 @@ export function renderIssue (issue, context) {
|
|
|
334
324
|
getPossibleAssignees().then(devs => {
|
|
335
325
|
if (devs.length) {
|
|
336
326
|
devs.forEach(function (person) {
|
|
337
|
-
|
|
327
|
+
store.fetcher.lookUpThing(person)
|
|
338
328
|
}) // best effort async for names etc
|
|
339
329
|
const opts = {
|
|
340
330
|
// 'mint': '** Add new person **',
|
|
@@ -349,14 +339,14 @@ export function renderIssue (issue, context) {
|
|
|
349
339
|
issueDiv.appendChild(
|
|
350
340
|
widgets.makeSelectForOptions(
|
|
351
341
|
dom,
|
|
352
|
-
|
|
342
|
+
store,
|
|
353
343
|
issue,
|
|
354
344
|
ns.wf('assignee'),
|
|
355
345
|
devs,
|
|
356
346
|
opts,
|
|
357
347
|
store,
|
|
358
348
|
function (ok, body) {
|
|
359
|
-
if (ok) setModifiedDate(store,
|
|
349
|
+
if (ok) setModifiedDate(store, store, store)
|
|
360
350
|
else console.log('Failed to change assignee:\n' + body)
|
|
361
351
|
}
|
|
362
352
|
)
|
|
@@ -376,7 +366,7 @@ export function renderIssue (issue, context) {
|
|
|
376
366
|
subIssuePanel.appendChild(dom.createElement('h4')).textContent = 'Super Issues'
|
|
377
367
|
const listOfSupers = subIssuePanel.appendChild(dom.createElement('div'))
|
|
378
368
|
listOfSupers.refresh = function () {
|
|
379
|
-
utils.syncTableToArrayReOrdered(listOfSupers,
|
|
369
|
+
utils.syncTableToArrayReOrdered(listOfSupers, store.each(null, ns.wf('dependent'), issue), renderSubIssue)
|
|
380
370
|
}
|
|
381
371
|
listOfSupers.refresh()
|
|
382
372
|
|
|
@@ -384,7 +374,7 @@ export function renderIssue (issue, context) {
|
|
|
384
374
|
subIssuePanel.appendChild(dom.createElement('h4')).textContent = 'Sub Issues'
|
|
385
375
|
const listOfSubs = subIssuePanel.appendChild(dom.createElement('div'))
|
|
386
376
|
listOfSubs.refresh = function () {
|
|
387
|
-
utils.syncTableToArrayReOrdered(listOfSubs,
|
|
377
|
+
utils.syncTableToArrayReOrdered(listOfSubs, store.each(issue, ns.wf('dependent')), renderSubIssue)
|
|
388
378
|
}
|
|
389
379
|
listOfSubs.refresh()
|
|
390
380
|
|
|
@@ -397,7 +387,7 @@ export function renderIssue (issue, context) {
|
|
|
397
387
|
b.addEventListener(
|
|
398
388
|
'click',
|
|
399
389
|
function (_event) {
|
|
400
|
-
subIssuePanel.insertBefore(newIssueForm(dom,
|
|
390
|
+
subIssuePanel.insertBefore(newIssueForm(dom, store, tracker, issue, listOfSubs.refresh), b.nextSibling) // Pop form just after button
|
|
401
391
|
},
|
|
402
392
|
false
|
|
403
393
|
)
|
|
@@ -406,7 +396,7 @@ export function renderIssue (issue, context) {
|
|
|
406
396
|
issueDiv.appendChild(dom.createElement('br'))
|
|
407
397
|
|
|
408
398
|
// Extras are stored centrally to the tracker
|
|
409
|
-
const extrasForm =
|
|
399
|
+
const extrasForm = store.any(tracker, ns.wf('extrasEntryForm'))
|
|
410
400
|
if (extrasForm) {
|
|
411
401
|
widgets.appendForm(
|
|
412
402
|
dom,
|
|
@@ -424,7 +414,7 @@ export function renderIssue (issue, context) {
|
|
|
424
414
|
const spacer = issueDiv.appendChild(dom.createElement('tr'))
|
|
425
415
|
spacer.setAttribute('style', 'height: 1em') // spacer and placeHolder
|
|
426
416
|
|
|
427
|
-
const template =
|
|
417
|
+
const template = store.anyValue(tracker, ns.wf('issueURITemplate'))
|
|
428
418
|
/*
|
|
429
419
|
var chatDocURITemplate = kb.anyValue(tracker, ns.wf('chatDocURITemplate')) // relaive to issue
|
|
430
420
|
var chat
|
|
@@ -437,18 +427,18 @@ export function renderIssue (issue, context) {
|
|
|
437
427
|
if (template) {
|
|
438
428
|
messageStore = issue.doc() // for now. Could go deeper
|
|
439
429
|
} else {
|
|
440
|
-
messageStore =
|
|
441
|
-
if (!messageStore) messageStore =
|
|
442
|
-
|
|
430
|
+
messageStore = store.any(tracker, ns.wf('messageStore'))
|
|
431
|
+
if (!messageStore) messageStore = store.any(tracker, ns.wf('stateStore'))
|
|
432
|
+
store.sym(messageStore.uri + '#' + 'Chat' + timestring()) // var chat =
|
|
443
433
|
}
|
|
444
434
|
|
|
445
|
-
|
|
435
|
+
store.fetcher.nowOrWhenFetched(messageStore, function (ok, body, _xhr) {
|
|
446
436
|
if (!ok) {
|
|
447
437
|
const er = dom.createElement('p')
|
|
448
438
|
er.textContent = body // @@ use nice error message
|
|
449
439
|
issueDiv.insertBefore(er, spacer)
|
|
450
440
|
} else {
|
|
451
|
-
const discussion = messageArea(dom,
|
|
441
|
+
const discussion = messageArea(dom, store, issue, messageStore)
|
|
452
442
|
issueDiv.insertBefore(discussion, spacer)
|
|
453
443
|
}
|
|
454
444
|
})
|
|
@@ -458,22 +448,23 @@ export function renderIssue (issue, context) {
|
|
|
458
448
|
attachmentHint.innerHTML = `<h4>Attachments</h4>
|
|
459
449
|
<p>Drag files, emails,
|
|
460
450
|
web pages onto the paper clip, or click the file upload button.</p>`
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
451
|
+
let uploadFolderURI
|
|
452
|
+
if (issue.uri.endsWith('/index.ttl#this')) { // This has a whole folder to itself
|
|
453
|
+
uploadFolderURI = issue.uri.slice(0, 14) + 'Files/' // back to slash
|
|
454
|
+
} else { // like state.ttl#Iss1587852322438
|
|
455
|
+
uploadFolderURI = issue.dir().uri + 'Files/' + issue.uri.split('#')[1] + '/' // New folder for issue in file with others
|
|
456
|
+
}
|
|
466
457
|
widgets.attachmentList(dom, issue, issueDiv, {
|
|
467
458
|
doc: stateStore,
|
|
468
459
|
promptIcon: icons.iconBase + 'noun_25830.svg',
|
|
469
|
-
uploadFolder:
|
|
460
|
+
uploadFolder: store.sym(uploadFolderURI), // Allow local files to be uploaded
|
|
470
461
|
predicate: ns.wf('attachment')
|
|
471
462
|
})
|
|
472
463
|
|
|
473
464
|
// Delete button to delete the issue
|
|
474
465
|
const deleteButton = widgets.deleteButtonWithCheck(dom, issueDiv, 'issue', async function () {
|
|
475
466
|
try {
|
|
476
|
-
await
|
|
467
|
+
await store.updater.update(store.connectedStatements(issue))
|
|
477
468
|
} catch (err) {
|
|
478
469
|
complain(`Unable to delete issue: ${err}`, context)
|
|
479
470
|
}
|
|
@@ -491,7 +482,7 @@ export function renderIssue (issue, context) {
|
|
|
491
482
|
'click',
|
|
492
483
|
async function (_event) {
|
|
493
484
|
try {
|
|
494
|
-
await
|
|
485
|
+
await store.fetcher.load(messageStore, { force: true, clearPreviousData: true })
|
|
495
486
|
} catch (err) {
|
|
496
487
|
alert(err)
|
|
497
488
|
return
|
package/issuePane.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import * as UI from 'solid-ui'
|
|
9
|
+
import { store, authn } from 'solid-logic'
|
|
9
10
|
import { board } from './board' // @@ will later be in solid-UI
|
|
10
11
|
import { renderIssue, renderIssueCard, getState, exposeOverlay } from './issue'
|
|
11
12
|
import { newTrackerButton } from './newTracker'
|
|
@@ -15,7 +16,6 @@ import { trackerSettingsFormText } from './trackerSettingsForm.js'
|
|
|
15
16
|
|
|
16
17
|
const $rdf = UI.rdf
|
|
17
18
|
const ns = UI.ns
|
|
18
|
-
const kb = UI.store
|
|
19
19
|
const widgets = UI.widgets
|
|
20
20
|
|
|
21
21
|
// const MY_TRACKERS_ICON = UI.icons.iconBase + 'noun_Document_998605.svg'
|
|
@@ -36,10 +36,10 @@ export default {
|
|
|
36
36
|
|
|
37
37
|
// Does the subject deserve an issue pane?
|
|
38
38
|
label: function (subject, _context) {
|
|
39
|
-
const t =
|
|
39
|
+
const t = store.findTypeURIs(subject)
|
|
40
40
|
if (
|
|
41
41
|
t['http://www.w3.org/2005/01/wf/flow#Task'] ||
|
|
42
|
-
|
|
42
|
+
store.holds(subject, UI.ns.wf('tracker'))
|
|
43
43
|
) { return 'issue' } // in case ontology not available
|
|
44
44
|
if (t['http://www.w3.org/2005/01/wf/flow#Tracker']) return 'tracker'
|
|
45
45
|
// Later: Person. For a list of things assigned to them,
|
|
@@ -61,7 +61,7 @@ export default {
|
|
|
61
61
|
return Promise.all(updates)
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
var kb = context.session.store
|
|
65
65
|
const ns = UI.ns
|
|
66
66
|
let stateStore
|
|
67
67
|
if (options.newInstance) {
|
|
@@ -73,7 +73,7 @@ export default {
|
|
|
73
73
|
const tracker = options.newInstance
|
|
74
74
|
const appDoc = tracker.doc()
|
|
75
75
|
|
|
76
|
-
const me =
|
|
76
|
+
const me = authn.currentUser()
|
|
77
77
|
if (me) {
|
|
78
78
|
kb.add(tracker, ns.dc('author'), me, appDoc)
|
|
79
79
|
}
|
|
@@ -148,73 +148,65 @@ export default {
|
|
|
148
148
|
const needed = new Set(collection.elements.map(x => x.uri))
|
|
149
149
|
const existing = new Set(kb.each(null, ns.rdfs('subClassOf'), klass, doc)
|
|
150
150
|
.map(x => x.uri))
|
|
151
|
-
const superfluous = existing.filter(sub => !needed.has(sub))
|
|
152
|
-
const deleteActions = superfluous.map(sub => { return { action: 'delete', st: $rdf.st(kb.sym(sub), ns.rdfs('subClassOf'), klass, doc) } })
|
|
153
|
-
/*
|
|
154
151
|
for (const sub of existing) {
|
|
155
152
|
if (!needed.has(sub)) {
|
|
156
153
|
deletables.push($rdf.st(kb.sym(sub), ns.rdfs('subClassOf'), klass, doc))
|
|
157
154
|
}
|
|
158
155
|
}
|
|
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
156
|
for (const sub of needed) {
|
|
164
157
|
if (!existing.has(sub)) {
|
|
165
158
|
insertables.push($rdf.st(kb.sym(sub), ns.rdfs('subClassOf'), klass, doc))
|
|
166
159
|
}
|
|
167
160
|
}
|
|
168
|
-
*/
|
|
169
|
-
return deleteActions.concat(insertActions)
|
|
170
161
|
}
|
|
171
162
|
const doc = tracker.doc()
|
|
172
163
|
const states = kb.any(tracker, ns.wf('issueClass'))
|
|
173
|
-
const cats = kb.each(tracker, ns.wf('issueCategory'))
|
|
174
|
-
|
|
164
|
+
const cats = kb.each(tracker, ns.wf('issueCategory'))
|
|
165
|
+
var insertables = []
|
|
166
|
+
var deletables = []
|
|
167
|
+
cats.push(states)
|
|
175
168
|
for (const klass of cats) {
|
|
176
|
-
|
|
169
|
+
await checkOneSuperclass(klass)
|
|
177
170
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
console.log('Damage:', damage)
|
|
171
|
+
const damage = insertables.length + deletables.length
|
|
172
|
+
if (damage) {
|
|
173
|
+
alert(`Internal error: s${damage} subclasses inconsistences!`)
|
|
174
|
+
/*
|
|
183
175
|
if (confirm(`Fix ${damage} inconsistent subclasses in tracker config?`)) {
|
|
184
176
|
await kb.updater.update(deletables, insertables)
|
|
185
|
-
|
|
177
|
+
*/
|
|
186
178
|
}
|
|
187
179
|
}
|
|
188
180
|
|
|
189
181
|
/** /////////////////////////// Board
|
|
190
182
|
*/
|
|
191
183
|
function renderBoard (tracker, klass) {
|
|
192
|
-
const states =
|
|
184
|
+
const states = store.any(tracker, ns.wf('issueClass'))
|
|
193
185
|
klass = klass || states // default to states
|
|
194
186
|
const doingStates = klass.sameTerm(states)
|
|
195
187
|
|
|
196
188
|
// These are states we will show by default: the open issues.
|
|
197
|
-
const stateArray =
|
|
189
|
+
const stateArray = store.any(klass, ns.owl('disjointUnionOf'))
|
|
198
190
|
if (!stateArray) {
|
|
199
191
|
return complain(`Configuration error: state ${states} does not have substates`)
|
|
200
192
|
}
|
|
201
193
|
let columnValues = stateArray.elements
|
|
202
194
|
if (doingStates && columnValues.length > 2 // and there are more than two
|
|
203
195
|
) { // strip out closed states
|
|
204
|
-
columnValues = columnValues.filter(state =>
|
|
196
|
+
columnValues = columnValues.filter(state => store.holds(state, ns.rdfs('subClassOf'), ns.wf('Open')) || state.sameTerm(ns.wf('Open')))
|
|
205
197
|
}
|
|
206
198
|
|
|
207
199
|
async function columnDropHandler (issue, newState) {
|
|
208
200
|
const currentState = getState(issue, klass)
|
|
209
|
-
const tracker =
|
|
210
|
-
const stateStore =
|
|
201
|
+
const tracker = store.the(issue, ns.wf('tracker'), null, issue.doc())
|
|
202
|
+
const stateStore = store.any(tracker, ns.wf('stateStore'))
|
|
211
203
|
|
|
212
204
|
if (newState.sameTerm(currentState)) {
|
|
213
205
|
// alert('Same state ' + UI.utils.label(currentState)) // @@ remove
|
|
214
206
|
return
|
|
215
207
|
}
|
|
216
208
|
try {
|
|
217
|
-
await
|
|
209
|
+
await store.updater.update(
|
|
218
210
|
[$rdf.st(issue, ns.rdf('type'), currentState, stateStore)],
|
|
219
211
|
[$rdf.st(issue, ns.rdf('type'), newState, stateStore)])
|
|
220
212
|
} catch (err) {
|
|
@@ -224,7 +216,7 @@ export default {
|
|
|
224
216
|
}
|
|
225
217
|
|
|
226
218
|
function isOpen (issue) {
|
|
227
|
-
const types =
|
|
219
|
+
const types = store.findTypeURIs(issue)
|
|
228
220
|
return !!types[ns.wf('Open').uri]
|
|
229
221
|
}
|
|
230
222
|
|
|
@@ -245,7 +237,7 @@ export default {
|
|
|
245
237
|
const refreshButton = widgets.button(dom, UI.icons.iconBase + 'noun_479395.svg',
|
|
246
238
|
'refresh table', async _event => {
|
|
247
239
|
try {
|
|
248
|
-
await
|
|
240
|
+
await store.fetcher.load(stateStore, { force: true, clearPreviousData: true })
|
|
249
241
|
} catch (err) {
|
|
250
242
|
alert(err)
|
|
251
243
|
return
|
|
@@ -261,10 +253,10 @@ export default {
|
|
|
261
253
|
query.pat.optional.push(clause)
|
|
262
254
|
return clause
|
|
263
255
|
}
|
|
264
|
-
const states =
|
|
265
|
-
const cats =
|
|
256
|
+
const states = store.any(subject, ns.wf('issueClass'))
|
|
257
|
+
const cats = store.each(tracker, ns.wf('issueCategory')) // zero or more
|
|
266
258
|
const vars = ['issue', 'state', 'created']
|
|
267
|
-
|
|
259
|
+
var query = new $rdf.Query(UI.utils.label(subject))
|
|
268
260
|
for (let i = 0; i < cats.length; i++) {
|
|
269
261
|
vars.push('_cat_' + i)
|
|
270
262
|
}
|
|
@@ -286,7 +278,7 @@ export default {
|
|
|
286
278
|
clause.add(v['_cat_' + i], ns.rdfs('subClassOf'), cats[i])
|
|
287
279
|
}
|
|
288
280
|
|
|
289
|
-
const propertyList =
|
|
281
|
+
const propertyList = store.any(tracker, ns.wf('propertyList')) // List of extra properties
|
|
290
282
|
if (propertyList) {
|
|
291
283
|
const properties = propertyList.elements
|
|
292
284
|
for (let p = 0; p < properties.length; p++) {
|
|
@@ -302,10 +294,10 @@ export default {
|
|
|
302
294
|
}
|
|
303
295
|
|
|
304
296
|
const selectedStates = {}
|
|
305
|
-
const possible =
|
|
297
|
+
const possible = store.each(undefined, ns.rdfs('subClassOf'), states)
|
|
306
298
|
possible.forEach(function (s) {
|
|
307
299
|
if (
|
|
308
|
-
|
|
300
|
+
store.holds(s, ns.rdfs('subClassOf'), ns.wf('Open')) ||
|
|
309
301
|
s.sameTerm(ns.wf('Open'))
|
|
310
302
|
) {
|
|
311
303
|
selectedStates[s.uri] = true
|
|
@@ -329,7 +321,7 @@ export default {
|
|
|
329
321
|
'?state': { initialSelection: selectedStates, label: 'Status' }
|
|
330
322
|
}
|
|
331
323
|
})
|
|
332
|
-
const stateStore =
|
|
324
|
+
const stateStore = store.any(subject, ns.wf('stateStore'))
|
|
333
325
|
tableDiv.appendChild(tableRefreshButton(stateStore, tableDiv))
|
|
334
326
|
return tableDiv
|
|
335
327
|
}
|
|
@@ -337,7 +329,7 @@ export default {
|
|
|
337
329
|
// Allow user to create new things within the folder
|
|
338
330
|
function renderCreationControl (refreshTarget) {
|
|
339
331
|
const creationDiv = dom.createElement('div')
|
|
340
|
-
const me =
|
|
332
|
+
const me = authn.currentUser()
|
|
341
333
|
const creationContext = {
|
|
342
334
|
// folder: subject,
|
|
343
335
|
div: creationDiv,
|
|
@@ -356,7 +348,7 @@ export default {
|
|
|
356
348
|
function renderInstances (theClass) {
|
|
357
349
|
const instancesDiv = dom.createElement('div')
|
|
358
350
|
const context = { dom, div: instancesDiv, noun: 'tracker' }
|
|
359
|
-
UI.
|
|
351
|
+
UI.login.registrationList(context, { public: true, private: true, type: theClass }).then(_context2 => {
|
|
360
352
|
instancesDiv.appendChild(renderCreationControl(instancesDiv))
|
|
361
353
|
/* // keep this code in case we need a form
|
|
362
354
|
const InstancesForm = ns.wf('TrackerInstancesForm')
|
|
@@ -372,10 +364,10 @@ export default {
|
|
|
372
364
|
const settingsDiv = dom.createElement('div')
|
|
373
365
|
// A registration control allows the to record this tracker in their type index
|
|
374
366
|
const context = { dom, div: settingsDiv, noun: 'tracker' }
|
|
375
|
-
UI.
|
|
367
|
+
UI.login.registrationControl(context, tracker, ns.wf('Tracker')).then(_context2 => {
|
|
376
368
|
const settingsForm = ns.wf('TrackerSettingsForm')
|
|
377
369
|
const text = trackerSettingsFormText
|
|
378
|
-
$rdf.parse(text,
|
|
370
|
+
$rdf.parse(text, store, settingsForm.doc().uri, 'text/turtle')
|
|
379
371
|
widgets.appendForm(dom, settingsDiv, {}, tracker, settingsForm,
|
|
380
372
|
tracker.doc(), complainIfBad)
|
|
381
373
|
})
|
|
@@ -393,25 +385,25 @@ export default {
|
|
|
393
385
|
ele.appendChild(renderSettings(tracker))
|
|
394
386
|
} else if (object.sameTerm(instancesView)) {
|
|
395
387
|
ele.appendChild(renderInstances(ns.wf('Tracker')))
|
|
396
|
-
} else if ((
|
|
397
|
-
(
|
|
388
|
+
} else if ((store.holds(tracker, ns.wf('issueCategory'), object)) ||
|
|
389
|
+
(store.holds(tracker, ns.wf('issueClass'), object))) {
|
|
398
390
|
ele.appendChild(renderBoard(tracker, object))
|
|
399
391
|
} else {
|
|
400
392
|
throw new Error('Unexpected tab type: ' + object)
|
|
401
393
|
}
|
|
402
394
|
}
|
|
403
|
-
const states =
|
|
395
|
+
const states = store.any(tracker, ns.wf('issueClass'))
|
|
404
396
|
const items = [instancesView, tableView, states]
|
|
405
|
-
.concat(
|
|
397
|
+
.concat(store.each(tracker, ns.wf('issueCategory')))
|
|
406
398
|
items.push(settingsView)
|
|
407
399
|
const selectedTab = tableView
|
|
408
400
|
const options = { renderMain, items, selectedTab }
|
|
409
401
|
|
|
410
402
|
// Add stuff to the ontologies which we believe but they don't say
|
|
411
403
|
const doc = instancesView.doc()
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
404
|
+
store.add(instancesView, ns.rdfs('label'), 'My Trackers', doc) // @@ squatting on wf ns
|
|
405
|
+
store.add(settingsView, ns.rdfs('label'), 'Settings', doc) // @@ squatting on wf ns
|
|
406
|
+
store.add(states, ns.rdfs('label'), 'By State', doc) // @@ squatting on wf ns
|
|
415
407
|
|
|
416
408
|
const tabs = UI.tabs.tabWidget(options)
|
|
417
409
|
return tabs
|
|
@@ -426,17 +418,17 @@ export default {
|
|
|
426
418
|
tracker = subject
|
|
427
419
|
|
|
428
420
|
try {
|
|
429
|
-
await fixSubClasses(
|
|
421
|
+
await fixSubClasses(store, tracker)
|
|
430
422
|
} catch (err) {
|
|
431
423
|
console.log('@@@ Error fixing subclasses in config: ' + err)
|
|
432
424
|
}
|
|
433
425
|
|
|
434
|
-
const states =
|
|
426
|
+
const states = store.any(subject, ns.wf('issueClass'))
|
|
435
427
|
if (!states) throw new Error('This tracker has no issueClass')
|
|
436
|
-
const stateStore =
|
|
428
|
+
const stateStore = store.any(subject, ns.wf('stateStore'))
|
|
437
429
|
if (!stateStore) throw new Error('This tracker has no stateStore')
|
|
438
430
|
|
|
439
|
-
|
|
431
|
+
authn.checkUser() // kick off async operation
|
|
440
432
|
|
|
441
433
|
const h = dom.createElement('h2')
|
|
442
434
|
h.setAttribute('style', 'font-size: 150%')
|
|
@@ -445,7 +437,7 @@ export default {
|
|
|
445
437
|
h.appendChild(dom.createTextNode(classLabel + ' list')) // Use class label @@I18n
|
|
446
438
|
|
|
447
439
|
// New Issue button
|
|
448
|
-
|
|
440
|
+
var b = dom.createElement('button')
|
|
449
441
|
const container = dom.createElement('div')
|
|
450
442
|
b.setAttribute('type', 'button')
|
|
451
443
|
b.setAttribute('style', 'padding: 0.3em; font-size: 100%; margin: 0.5em;')
|
|
@@ -462,7 +454,7 @@ export default {
|
|
|
462
454
|
'click',
|
|
463
455
|
function (_event) {
|
|
464
456
|
b.disabled = true
|
|
465
|
-
container.appendChild(newIssueForm(dom,
|
|
457
|
+
container.appendChild(newIssueForm(dom, store, tracker, null, showNewIssue))
|
|
466
458
|
},
|
|
467
459
|
false
|
|
468
460
|
)
|
|
@@ -498,28 +490,28 @@ export default {
|
|
|
498
490
|
const settingsView = ns.wf('SettingsView')
|
|
499
491
|
const instancesView = ns.wf('InstancesView')
|
|
500
492
|
|
|
501
|
-
const updater =
|
|
502
|
-
const t =
|
|
493
|
+
const updater = store.updater
|
|
494
|
+
const t = store.findTypeURIs(subject)
|
|
503
495
|
let tracker
|
|
504
496
|
|
|
505
497
|
// Whatever we are rendering, lets load the ontology
|
|
506
498
|
const flowOntology = UI.ns.wf('').doc()
|
|
507
|
-
if (!
|
|
499
|
+
if (!store.holds(undefined, undefined, undefined, flowOntology)) {
|
|
508
500
|
// If not loaded already
|
|
509
|
-
$rdf.parse(require('./wf.js'),
|
|
501
|
+
$rdf.parse(require('./wf.js'), store, flowOntology.uri, 'text/turtle') // Load ontology directly
|
|
510
502
|
}
|
|
511
503
|
const userInterfaceOntology = UI.ns.ui('').doc()
|
|
512
|
-
if (!
|
|
504
|
+
if (!store.holds(undefined, undefined, undefined, userInterfaceOntology)) {
|
|
513
505
|
// If not loaded already
|
|
514
|
-
$rdf.parse(require('./ui.js'),
|
|
506
|
+
$rdf.parse(require('./ui.js'), store, userInterfaceOntology.uri, 'text/turtle') // Load ontology directly
|
|
515
507
|
}
|
|
516
508
|
|
|
517
509
|
// Render a single issue
|
|
518
510
|
if (
|
|
519
511
|
t['http://www.w3.org/2005/01/wf/flow#Task'] ||
|
|
520
|
-
|
|
512
|
+
store.holds(subject, UI.ns.wf('tracker'))
|
|
521
513
|
) {
|
|
522
|
-
tracker =
|
|
514
|
+
tracker = store.any(subject, ns.wf('tracker'))
|
|
523
515
|
if (!tracker) throw new Error('This issue ' + subject + 'has no tracker')
|
|
524
516
|
|
|
525
517
|
// Much data is in the tracker instance, so wait for the data from it
|
|
@@ -527,7 +519,7 @@ export default {
|
|
|
527
519
|
context.session.store.fetcher
|
|
528
520
|
.load(tracker.doc())
|
|
529
521
|
.then(function (_xhrs) {
|
|
530
|
-
const stateStore =
|
|
522
|
+
const stateStore = store.any(tracker, ns.wf('stateStore'))
|
|
531
523
|
context.session.store.fetcher.nowOrWhenFetched(
|
|
532
524
|
stateStore,
|
|
533
525
|
subject,
|
|
@@ -580,7 +572,9 @@ export default {
|
|
|
580
572
|
overlay.style = OVERFLOW_STYLE
|
|
581
573
|
overlay.style.visibility = 'hidden'
|
|
582
574
|
|
|
583
|
-
|
|
575
|
+
// var overlayPane = null // overlay.appendChild(dom.createElement('div')) // avoid stomping on style by pane
|
|
576
|
+
|
|
577
|
+
authn.checkUser().then(webId => {
|
|
584
578
|
if (webId) {
|
|
585
579
|
console.log('Web ID set already: ' + webId)
|
|
586
580
|
context.me = webId
|
|
@@ -588,9 +582,9 @@ export default {
|
|
|
588
582
|
return
|
|
589
583
|
}
|
|
590
584
|
|
|
591
|
-
loginOutButton = UI.
|
|
585
|
+
loginOutButton = UI.login.loginStatusBox(dom, webIdUri => {
|
|
592
586
|
if (webIdUri) {
|
|
593
|
-
context.me =
|
|
587
|
+
context.me = store.sym(webIdUri)
|
|
594
588
|
console.log('Web ID set from login button: ' + webIdUri)
|
|
595
589
|
paneDiv.removeChild(loginOutButton)
|
|
596
590
|
// enable things
|
package/newIssue.js
CHANGED
|
@@ -100,7 +100,7 @@ export function newIssueForm (dom, kb, tracker, superIssue, showNewIssue) {
|
|
|
100
100
|
'</h2><p>Title of new ' +
|
|
101
101
|
classLabel +
|
|
102
102
|
':</p>'
|
|
103
|
-
|
|
103
|
+
var titlefield = dom.createElement('input')
|
|
104
104
|
titlefield.setAttribute('type', 'text')
|
|
105
105
|
titlefield.setAttribute(
|
|
106
106
|
'style',
|
package/newTracker.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as UI from 'solid-ui'
|
|
2
|
+
import { store } from 'solid-logic'
|
|
2
3
|
|
|
3
4
|
const $rdf = UI.rdf
|
|
4
5
|
const ns = UI.ns
|
|
5
|
-
const
|
|
6
|
-
const updater = kb.updater
|
|
6
|
+
const updater = store.updater
|
|
7
7
|
|
|
8
8
|
/* Button for making a whole new tracker
|
|
9
9
|
** This is the least tesetd part of the tracker system at the moment.
|
|
@@ -16,30 +16,17 @@ export function newTrackerButton (thisTracker, context) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
// const dom = context.dom
|
|
19
|
-
const button = UI.
|
|
19
|
+
const button = UI.login.newAppInstance(context.dom, { noun: 'tracker' }, function (
|
|
20
20
|
ws,
|
|
21
21
|
base
|
|
22
22
|
) {
|
|
23
|
-
function morph (x) {
|
|
24
|
-
// Move any URIs in this space into that space
|
|
25
|
-
if (x.elements !== undefined) return x.elements.map(morph) // Morph within lists
|
|
26
|
-
if (x.uri === undefined) return x
|
|
27
|
-
let u = x.uri
|
|
28
|
-
if (u === stateStore.uri) return newStore // special case
|
|
29
|
-
if (u.slice(0, oldBase.length) === oldBase) {
|
|
30
|
-
u = base + u.slice(oldBase.length)
|
|
31
|
-
$rdf.log.debug(' Map ' + x.uri + ' to ' + u)
|
|
32
|
-
}
|
|
33
|
-
return kb.sym(u)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
23
|
const appPathSegment = 'issuetracker.w3.org' // how to allocate this string and connect to
|
|
37
24
|
// console.log("Ready to make new instance at "+ws)
|
|
38
25
|
const sp = UI.ns.space
|
|
39
|
-
const
|
|
26
|
+
const store = context.session.store
|
|
40
27
|
|
|
41
28
|
if (!base) {
|
|
42
|
-
base =
|
|
29
|
+
base = store.any(ws, sp('uriPrefix')).value
|
|
43
30
|
if (base.slice(-1) !== '/') {
|
|
44
31
|
$rdf.log.error(
|
|
45
32
|
appPathSegment + ': No / at end of uriPrefix ' + base
|
|
@@ -52,17 +39,29 @@ export function newTrackerButton (thisTracker, context) {
|
|
|
52
39
|
}
|
|
53
40
|
}
|
|
54
41
|
|
|
55
|
-
const stateStore =
|
|
56
|
-
const newStore =
|
|
42
|
+
const stateStore = store.any(thisTracker, ns.wf('stateStore'))
|
|
43
|
+
const newStore = store.sym(base + 'store.ttl')
|
|
57
44
|
|
|
58
45
|
const here = thisTracker.doc()
|
|
59
46
|
|
|
60
47
|
const oldBase = here.uri.slice(0, here.uri.lastIndexOf('/') + 1)
|
|
61
48
|
|
|
49
|
+
const morph = function (x) {
|
|
50
|
+
// Move any URIs in this space into that space
|
|
51
|
+
if (x.elements !== undefined) return x.elements.map(morph) // Morph within lists
|
|
52
|
+
if (x.uri === undefined) return x
|
|
53
|
+
let u = x.uri
|
|
54
|
+
if (u === stateStore.uri) return newStore // special case
|
|
55
|
+
if (u.slice(0, oldBase.length) === oldBase) {
|
|
56
|
+
u = base + u.slice(oldBase.length)
|
|
57
|
+
$rdf.log.debug(' Map ' + x.uri + ' to ' + u)
|
|
58
|
+
}
|
|
59
|
+
return store.sym(u)
|
|
60
|
+
}
|
|
62
61
|
const there = morph(here)
|
|
63
62
|
const newTracker = morph(thisTracker)
|
|
64
63
|
|
|
65
|
-
const myConfig =
|
|
64
|
+
const myConfig = store.statementsMatching(
|
|
66
65
|
undefined,
|
|
67
66
|
undefined,
|
|
68
67
|
undefined,
|
|
@@ -70,7 +69,7 @@ export function newTrackerButton (thisTracker, context) {
|
|
|
70
69
|
)
|
|
71
70
|
for (let i = 0; i < myConfig.length; i++) {
|
|
72
71
|
const st = myConfig[i]
|
|
73
|
-
|
|
72
|
+
store.add(
|
|
74
73
|
morph(st.subject),
|
|
75
74
|
morph(st.predicate),
|
|
76
75
|
morph(st.object),
|
|
@@ -80,15 +79,15 @@ export function newTrackerButton (thisTracker, context) {
|
|
|
80
79
|
|
|
81
80
|
// Keep a paper trail @@ Revisit when we have non-public ones @@ Privacy
|
|
82
81
|
//
|
|
83
|
-
|
|
82
|
+
store.add(newTracker, UI.ns.space('inspiration'), thisTracker, stateStore)
|
|
84
83
|
|
|
85
|
-
|
|
84
|
+
store.add(newTracker, UI.ns.space('inspiration'), thisTracker, there)
|
|
86
85
|
|
|
87
86
|
// $rdf.log.debug("\n Ready to put " + kb.statementsMatching(undefined, undefined, undefined, there)); //@@
|
|
88
87
|
|
|
89
88
|
updater.put(
|
|
90
89
|
there,
|
|
91
|
-
|
|
90
|
+
store.statementsMatching(undefined, undefined, undefined, there),
|
|
92
91
|
'text/turtle',
|
|
93
92
|
function (uri2, ok, message) {
|
|
94
93
|
if (ok) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "issue-pane",
|
|
3
|
-
"version": "2.4.9-
|
|
3
|
+
"version": "2.4.9-ee8ae54d",
|
|
4
4
|
"description": "Solid-compatible Panes: issue editor",
|
|
5
5
|
"main": "./issuePane.js",
|
|
6
6
|
"scripts": {
|
|
@@ -34,9 +34,10 @@
|
|
|
34
34
|
},
|
|
35
35
|
"homepage": "https://github.com/solid/issue-pane",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"pane-registry": "
|
|
37
|
+
"pane-registry": "2.4.6-e0ddeef1",
|
|
38
38
|
"rdflib": "^2.2.17",
|
|
39
|
-
"solid-
|
|
39
|
+
"solid-logic": "1.3.13-53806f5e",
|
|
40
|
+
"solid-ui": "2.4.18-270aef4c"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"eslint": "^7.32.0",
|