issue-pane 2.4.10 → 2.4.11-4fce62b6
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/.eslintrc +3 -2
- package/.github/workflows/ci.yml +0 -1
- package/.nvmrc +1 -1
- package/Documentation/Configuration.html +0 -0
- package/Documentation/Configuration.md +0 -0
- package/Documentation/FooTracker/chat.ttl +0 -0
- package/Documentation/FooTracker/index.ttl +0 -0
- package/Documentation/FooTracker/state.ttl +0 -0
- package/Documentation/Makefile +0 -0
- package/Documentation/github-markdown.css +0 -0
- package/LICENSE.md +0 -0
- package/Makefile +0 -0
- package/README.md +0 -0
- package/board.js +7 -8
- package/issue.js +117 -108
- package/issuePane.js +130 -145
- package/newIssue.js +18 -23
- package/newTracker.js +22 -21
- package/package.json +10 -10
- package/tbl-bug-22.png +0 -0
- package/trackerSettingsForm.js +0 -0
- package/trackerSettingsForm.ttl +0 -0
- package/ui.js +0 -0
- package/ui.ttl +0 -0
- package/wf.js +0 -0
- package/wf.ttl +0 -0
package/.eslintrc
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
+
"root": true,
|
|
2
3
|
"env": {
|
|
3
4
|
"browser": true,
|
|
4
5
|
"es6": true,
|
|
5
6
|
"node": true
|
|
6
7
|
},
|
|
7
|
-
"extends": "standard",
|
|
8
8
|
"globals": {
|
|
9
9
|
"Atomics": "readonly",
|
|
10
10
|
"SharedArrayBuffer": "readonly"
|
|
@@ -14,5 +14,6 @@
|
|
|
14
14
|
"argsIgnorePattern": "^_",
|
|
15
15
|
"varsIgnorePattern": "^_"
|
|
16
16
|
}]
|
|
17
|
-
}
|
|
17
|
+
},
|
|
18
|
+
"extends": ["eslint:recommended", "plugin:import/recommended"]
|
|
18
19
|
}
|
package/.github/workflows/ci.yml
CHANGED
package/.nvmrc
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
v16.14.0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/Documentation/Makefile
CHANGED
|
File without changes
|
|
File without changes
|
package/LICENSE.md
CHANGED
|
File without changes
|
package/Makefile
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
File without changes
|
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,20 +5,33 @@ 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
|
|
|
12
|
+
export const TASK_ICON = icons.iconBase + 'noun_17020_gray-tick.svg'
|
|
13
|
+
export const OPEN_TASK_ICON = icons.iconBase + 'noun_17020_sans-tick.svg'
|
|
14
|
+
export const CLOSED_TASK_ICON = icons.iconBase + 'noun_17020.svg'
|
|
15
|
+
|
|
11
16
|
function complain (message, context) {
|
|
12
17
|
console.warn(message)
|
|
13
18
|
context.paneDiv.appendChild(widgets.errorMessageBlock(context.dom, message))
|
|
14
19
|
}
|
|
15
20
|
|
|
21
|
+
export function isOpen (issue) {
|
|
22
|
+
const types = kb.findTypeURIs(issue)
|
|
23
|
+
return !!types[ns.wf('Open').uri]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function iconForIssue (issue) {
|
|
27
|
+
return isOpen(issue) ? TASK_ICON : CLOSED_TASK_ICON
|
|
28
|
+
}
|
|
16
29
|
export function getState (issue, classification) {
|
|
17
|
-
const tracker =
|
|
18
|
-
const states =
|
|
30
|
+
const tracker = kb.the(issue, ns.wf('tracker'), null, issue.doc())
|
|
31
|
+
const states = kb.any(tracker, ns.wf('issueClass'))
|
|
19
32
|
classification = classification || states
|
|
20
|
-
const types =
|
|
21
|
-
.filter(ty =>
|
|
33
|
+
const types = kb.each(issue, ns.rdf('type'))
|
|
34
|
+
.filter(ty => kb.holds(ty, ns.rdfs('subClassOf'), classification))
|
|
22
35
|
if (types.length !== 1) {
|
|
23
36
|
// const initialState = kb.any(tracker, ns.wf('initialState')) No do NOT default
|
|
24
37
|
// if (initialState) return initialState
|
|
@@ -27,26 +40,27 @@ export function getState (issue, classification) {
|
|
|
27
40
|
return types[0]
|
|
28
41
|
}
|
|
29
42
|
|
|
30
|
-
export function
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const catColors = classes.map(cat => store.any(cat, ns.ui('backgroundColor'))).filter(c => !!c)
|
|
43
|
+
export function getBackgroundColorFromTypes (issue) {
|
|
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)
|
|
34
46
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
if (catColors.length) return catColors[0].value // pick first one
|
|
48
|
+
return null
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function renderIssueCard (issue, context) {
|
|
38
52
|
function refresh () {
|
|
39
|
-
const backgroundColor =
|
|
53
|
+
const backgroundColor = getBackgroundColorFromTypes(issue) || 'white'
|
|
40
54
|
card.style.backgroundColor = backgroundColor
|
|
41
55
|
editButton.style.backgroundColor = backgroundColor // Override white from style sheet
|
|
42
56
|
}
|
|
43
57
|
const dom = context.dom
|
|
44
|
-
const uncategorized = !
|
|
58
|
+
const uncategorized = !getBackgroundColorFromTypes(issue) // This is a suspect issue. Prompt to delete it
|
|
45
59
|
|
|
46
60
|
const card = dom.createElement('div')
|
|
47
61
|
const table = card.appendChild(dom.createElement('table'))
|
|
48
62
|
table.style.width = '100%'
|
|
49
|
-
const options = { draggable: false } // Let the
|
|
63
|
+
const options = { draggable: false } // Let the board make the whole card draggable
|
|
50
64
|
table.appendChild(widgets.personTR(dom, null, issue, options))
|
|
51
65
|
table.subject = issue
|
|
52
66
|
card.style = 'border-radius: 0.4em; border: 0.05em solid grey; margin: 0.3em;'
|
|
@@ -66,7 +80,7 @@ export function renderIssueCard (issue, context) {
|
|
|
66
80
|
if (uncategorized) {
|
|
67
81
|
const deleteButton = widgets.deleteButtonWithCheck(dom, buttonsCell, 'issue', async function () { // noun?
|
|
68
82
|
try {
|
|
69
|
-
await
|
|
83
|
+
await kb.updater.update(kb.connectedStatements(issue))
|
|
70
84
|
} catch (err) {
|
|
71
85
|
complain(`Unable to delete issue: ${err}`, context)
|
|
72
86
|
}
|
|
@@ -100,18 +114,24 @@ export function exposeOverlay (subject, context) {
|
|
|
100
114
|
overlay.firstChild.style.overflow = 'auto' // was scroll
|
|
101
115
|
}
|
|
102
116
|
|
|
117
|
+
function renderSpacer (dom, backgroundColor) {
|
|
118
|
+
const spacer = dom.createElement('div')
|
|
119
|
+
spacer.setAttribute('style', 'height: 1em; margin: 0.5em;') // spacer and placeHolder
|
|
120
|
+
spacer.style.backgroundColor = backgroundColor // try that
|
|
121
|
+
return spacer
|
|
122
|
+
}
|
|
123
|
+
|
|
103
124
|
export function renderIssue (issue, context) {
|
|
104
125
|
// Don't bother changing the last modified dates of things: save time
|
|
105
|
-
function setModifiedDate (subj,
|
|
126
|
+
function setModifiedDate (subj, kb, doc) {
|
|
106
127
|
if (SET_MODIFIED_DATES) {
|
|
107
128
|
if (!getOption(tracker, 'trackLastModified')) return
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
)
|
|
129
|
+
const deletions = kb.statementsMatching(issue, ns.dct('modified'))
|
|
130
|
+
.concat(kb.statementsMatching(issue, ns.wf('modifiedBy'))
|
|
131
|
+
)
|
|
112
132
|
const insertions = [$rdf.st(issue, ns.dct('modified'), new Date(), doc)]
|
|
113
133
|
if (me) insertions.push($rdf.st(issue, ns.wf('modifiedBy'), me, doc))
|
|
114
|
-
|
|
134
|
+
kb.updater.update(deletions, insertions, function (_uri, _ok, _body) {})
|
|
115
135
|
}
|
|
116
136
|
}
|
|
117
137
|
|
|
@@ -123,7 +143,7 @@ export function renderIssue (issue, context) {
|
|
|
123
143
|
return pre
|
|
124
144
|
}
|
|
125
145
|
|
|
126
|
-
|
|
146
|
+
function timestring () {
|
|
127
147
|
const now = new Date()
|
|
128
148
|
return '' + now.getTime()
|
|
129
149
|
// http://www.w3schools.com/jsref/jsref_obj_date.asp
|
|
@@ -144,52 +164,50 @@ export function renderIssue (issue, context) {
|
|
|
144
164
|
}
|
|
145
165
|
function getOption (tracker, option) {
|
|
146
166
|
// eg 'allowSubIssues'
|
|
147
|
-
const opt =
|
|
167
|
+
const opt = kb.any(tracker, ns.ui(option))
|
|
148
168
|
return !!(opt && opt.value)
|
|
149
169
|
}
|
|
150
170
|
|
|
151
171
|
function setPaneStyle () {
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
for (const uri in types) {
|
|
156
|
-
backgroundColor = store.any(
|
|
157
|
-
store.sym(uri),
|
|
158
|
-
store.sym('http://www.w3.org/ns/ui#backgroundColor')
|
|
159
|
-
)
|
|
160
|
-
if (backgroundColor) break
|
|
161
|
-
}
|
|
162
|
-
backgroundColor = backgroundColor ? backgroundColor.value : '#eee' // default grey
|
|
163
|
-
mystyle += 'background-color: ' + backgroundColor + '; '
|
|
172
|
+
const backgroundColor = getBackgroundColorFromTypes(issue) || '#eee' // default grey
|
|
173
|
+
const mystyle0 = 'padding: 0.5em 1.5em 1em 1.5em; border: 0.7em;'
|
|
174
|
+
const mystyle = mystyle0 + 'border-color: ' + backgroundColor + '; '
|
|
164
175
|
issueDiv.setAttribute('style', mystyle)
|
|
176
|
+
issueDiv.style.backgroundColor = 'white'
|
|
165
177
|
}
|
|
166
178
|
|
|
179
|
+
/// ////////////// Body of renderIssue
|
|
180
|
+
|
|
167
181
|
const dom = context.dom
|
|
168
182
|
// eslint-disable-next-line no-use-before-define
|
|
169
|
-
const tracker =
|
|
183
|
+
const tracker = kb.the(issue, ns.wf('tracker'), null, issue.doc())
|
|
170
184
|
if (!tracker) throw new Error('No tracker')
|
|
171
185
|
// eslint-disable-next-line no-use-before-define
|
|
172
|
-
const stateStore =
|
|
186
|
+
const stateStore = kb.any(tracker, ns.wf('stateStore'))
|
|
173
187
|
const store = issue.doc()
|
|
174
188
|
|
|
175
189
|
const issueDiv = dom.createElement('div')
|
|
176
190
|
const me = authn.currentUser()
|
|
191
|
+
const backgroundColor = getBackgroundColorFromTypes(issue) || 'white'
|
|
177
192
|
|
|
178
193
|
setPaneStyle()
|
|
179
194
|
|
|
180
195
|
authn.checkUser() // kick off async operation
|
|
181
196
|
|
|
182
|
-
const
|
|
197
|
+
const iconButton = issueDiv.appendChild(widgets.button(dom, iconForIssue(issue)))
|
|
198
|
+
widgets.makeDraggable(iconButton, issue) // Drag me wherever you need to do stuff with this issue
|
|
199
|
+
|
|
200
|
+
const states = kb.any(tracker, ns.wf('issueClass'))
|
|
183
201
|
if (!states) { throw new Error('This tracker ' + tracker + ' has no issueClass') }
|
|
184
202
|
const select = widgets.makeSelectForCategory(
|
|
185
203
|
dom,
|
|
186
|
-
|
|
204
|
+
kb,
|
|
187
205
|
issue,
|
|
188
206
|
states,
|
|
189
207
|
stateStore,
|
|
190
208
|
function (ok, body) {
|
|
191
209
|
if (ok) {
|
|
192
|
-
setModifiedDate(store,
|
|
210
|
+
setModifiedDate(store, kb, store)
|
|
193
211
|
widgets.refreshTree(issueDiv)
|
|
194
212
|
} else {
|
|
195
213
|
console.log('Failed to change state:\n' + body)
|
|
@@ -198,18 +216,18 @@ export function renderIssue (issue, context) {
|
|
|
198
216
|
)
|
|
199
217
|
issueDiv.appendChild(select)
|
|
200
218
|
|
|
201
|
-
const cats =
|
|
202
|
-
for (
|
|
219
|
+
const cats = kb.each(tracker, ns.wf('issueCategory')) // zero or more
|
|
220
|
+
for (const cat of cats) {
|
|
203
221
|
issueDiv.appendChild(
|
|
204
222
|
widgets.makeSelectForCategory(
|
|
205
223
|
dom,
|
|
206
|
-
|
|
224
|
+
kb,
|
|
207
225
|
issue,
|
|
208
|
-
|
|
226
|
+
cat,
|
|
209
227
|
stateStore,
|
|
210
228
|
function (ok, body) {
|
|
211
229
|
if (ok) {
|
|
212
|
-
setModifiedDate(store,
|
|
230
|
+
setModifiedDate(store, kb, store)
|
|
213
231
|
widgets.refreshTree(issueDiv)
|
|
214
232
|
} else {
|
|
215
233
|
console.log('Failed to change category:\n' + body)
|
|
@@ -253,40 +271,26 @@ export function renderIssue (issue, context) {
|
|
|
253
271
|
wf:Task :creationForm core:coreIsueForm .
|
|
254
272
|
`
|
|
255
273
|
const CORE_ISSUE_FORM = ns.wf('coreIsueForm')
|
|
256
|
-
$rdf.parse(coreIssueFormText,
|
|
257
|
-
widgets.appendForm(
|
|
274
|
+
$rdf.parse(coreIssueFormText, kb, CORE_ISSUE_FORM.doc().uri, 'text/turtle')
|
|
275
|
+
const form = widgets.appendForm(
|
|
258
276
|
dom,
|
|
259
|
-
|
|
277
|
+
null, // was: container
|
|
260
278
|
{},
|
|
261
279
|
issue,
|
|
262
280
|
CORE_ISSUE_FORM,
|
|
263
281
|
stateStore,
|
|
264
282
|
complainIfBad
|
|
265
283
|
)
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
/*
|
|
269
|
-
issueDiv.appendChild(
|
|
270
|
-
widgets.makeDescription(
|
|
271
|
-
dom,
|
|
272
|
-
kb,
|
|
273
|
-
issue,
|
|
274
|
-
ns.wf('description'),
|
|
275
|
-
store,
|
|
276
|
-
function (ok, body) {
|
|
277
|
-
if (ok) setModifiedDate(store, kb, store)
|
|
278
|
-
else console.log('Failed to change description:\n' + body)
|
|
279
|
-
}
|
|
280
|
-
)
|
|
281
|
-
) */
|
|
284
|
+
issueDiv.appendChild(form)
|
|
285
|
+
form.style.backgroundColor = backgroundColor
|
|
282
286
|
|
|
283
287
|
// Assigned to whom?
|
|
284
288
|
|
|
285
|
-
const assignments =
|
|
289
|
+
const assignments = kb.statementsMatching(issue, ns.wf('assignee'))
|
|
286
290
|
if (assignments.length > 1) {
|
|
287
291
|
say('Weird, was assigned to more than one person. Fixing ..')
|
|
288
292
|
const deletions = assignments.slice(1)
|
|
289
|
-
|
|
293
|
+
kb.updater.update(deletions, [], function (uri, ok, body) {
|
|
290
294
|
if (ok) {
|
|
291
295
|
say('Now fixed.')
|
|
292
296
|
} else {
|
|
@@ -299,20 +303,16 @@ export function renderIssue (issue, context) {
|
|
|
299
303
|
// Anyone assigned to any issue we know about
|
|
300
304
|
|
|
301
305
|
async function getPossibleAssignees () {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const group = devGroups[i]
|
|
306
|
-
await store.fetcher.load()
|
|
307
|
-
devs = devs.concat(store.each(group, ns.vcard('member')))
|
|
308
|
-
}
|
|
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()
|
|
309
309
|
// Anyone who is a developer of any project which uses this tracker
|
|
310
|
-
const proj =
|
|
310
|
+
const proj = kb.any(null, ns.doap('bug-database'), tracker) // What project?
|
|
311
311
|
if (proj) {
|
|
312
|
-
await
|
|
313
|
-
devs = devs.concat(store.each(proj, ns.doap('developer')))
|
|
312
|
+
await kb.fetcher.load(proj)
|
|
314
313
|
}
|
|
315
|
-
|
|
314
|
+
const projectDevs = proj ? kb.each(proj, ns.doap('developer')) : []
|
|
315
|
+
return groupDevs.concat(projectDevs)
|
|
316
316
|
}
|
|
317
317
|
|
|
318
318
|
// Super issues first - like parent directories .. maybe use breadcrums from?? @@
|
|
@@ -324,7 +324,7 @@ export function renderIssue (issue, context) {
|
|
|
324
324
|
getPossibleAssignees().then(devs => {
|
|
325
325
|
if (devs.length) {
|
|
326
326
|
devs.forEach(function (person) {
|
|
327
|
-
|
|
327
|
+
kb.fetcher.lookUpThing(person)
|
|
328
328
|
}) // best effort async for names etc
|
|
329
329
|
const opts = {
|
|
330
330
|
// 'mint': '** Add new person **',
|
|
@@ -339,14 +339,14 @@ export function renderIssue (issue, context) {
|
|
|
339
339
|
issueDiv.appendChild(
|
|
340
340
|
widgets.makeSelectForOptions(
|
|
341
341
|
dom,
|
|
342
|
-
|
|
342
|
+
kb,
|
|
343
343
|
issue,
|
|
344
344
|
ns.wf('assignee'),
|
|
345
345
|
devs,
|
|
346
346
|
opts,
|
|
347
347
|
store,
|
|
348
348
|
function (ok, body) {
|
|
349
|
-
if (ok) setModifiedDate(store,
|
|
349
|
+
if (ok) setModifiedDate(store, kb, store)
|
|
350
350
|
else console.log('Failed to change assignee:\n' + body)
|
|
351
351
|
}
|
|
352
352
|
)
|
|
@@ -354,27 +354,36 @@ export function renderIssue (issue, context) {
|
|
|
354
354
|
}
|
|
355
355
|
})
|
|
356
356
|
|
|
357
|
-
/* The trees of super
|
|
357
|
+
/* The trees of super-issues and sub-issues
|
|
358
358
|
*/
|
|
359
|
-
|
|
359
|
+
function supersOver (issue, stack) {
|
|
360
|
+
stack = stack || []
|
|
361
|
+
const sup = kb.any(null, ns.wf('dependent'), issue, issue.doc())
|
|
362
|
+
if (sup) return supersOver(sup, [sup].concat(stack))
|
|
363
|
+
return stack
|
|
364
|
+
}
|
|
360
365
|
if (getOption(tracker, 'allowSubIssues')) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
subIssuePanel.style = 'margin: 1em; padding: 1em;'
|
|
364
|
-
}
|
|
366
|
+
const subIssuePanel = issueDiv.appendChild(dom.createElement('div'))
|
|
367
|
+
subIssuePanel.style = 'margin: 1em; padding: 1em;'
|
|
365
368
|
|
|
366
369
|
subIssuePanel.appendChild(dom.createElement('h4')).textContent = 'Super Issues'
|
|
367
370
|
const listOfSupers = subIssuePanel.appendChild(dom.createElement('div'))
|
|
371
|
+
listOfSupers.style.display = 'flex'
|
|
368
372
|
listOfSupers.refresh = function () {
|
|
369
|
-
|
|
373
|
+
// const supers = kb.each(null, ns.wf('dependent'), issue, issue.doc())
|
|
374
|
+
const supers = supersOver(issue)
|
|
375
|
+
utils.syncTableToArrayReOrdered(listOfSupers, supers, renderSubIssue)
|
|
370
376
|
}
|
|
371
377
|
listOfSupers.refresh()
|
|
372
378
|
|
|
373
379
|
// Sub issues
|
|
374
380
|
subIssuePanel.appendChild(dom.createElement('h4')).textContent = 'Sub Issues'
|
|
375
381
|
const listOfSubs = subIssuePanel.appendChild(dom.createElement('div'))
|
|
382
|
+
listOfSubs.style.display = 'flex'
|
|
383
|
+
listOfSubs.style.flexDirection = 'reverse' // Or center
|
|
376
384
|
listOfSubs.refresh = function () {
|
|
377
|
-
|
|
385
|
+
const subs = kb.each(issue, ns.wf('dependent'), null, issue.doc())
|
|
386
|
+
utils.syncTableToArrayReOrdered(listOfSubs, subs, renderSubIssue)
|
|
378
387
|
}
|
|
379
388
|
listOfSubs.refresh()
|
|
380
389
|
|
|
@@ -387,7 +396,7 @@ export function renderIssue (issue, context) {
|
|
|
387
396
|
b.addEventListener(
|
|
388
397
|
'click',
|
|
389
398
|
function (_event) {
|
|
390
|
-
subIssuePanel.insertBefore(newIssueForm(dom,
|
|
399
|
+
subIssuePanel.insertBefore(newIssueForm(dom, kb, tracker, issue, listOfSubs.refresh), b.nextSibling) // Pop form just after button
|
|
391
400
|
},
|
|
392
401
|
false
|
|
393
402
|
)
|
|
@@ -396,7 +405,7 @@ export function renderIssue (issue, context) {
|
|
|
396
405
|
issueDiv.appendChild(dom.createElement('br'))
|
|
397
406
|
|
|
398
407
|
// Extras are stored centrally to the tracker
|
|
399
|
-
const extrasForm =
|
|
408
|
+
const extrasForm = kb.any(tracker, ns.wf('extrasEntryForm'))
|
|
400
409
|
if (extrasForm) {
|
|
401
410
|
widgets.appendForm(
|
|
402
411
|
dom,
|
|
@@ -407,14 +416,14 @@ export function renderIssue (issue, context) {
|
|
|
407
416
|
stateStore,
|
|
408
417
|
complainIfBad
|
|
409
418
|
)
|
|
419
|
+
// issueDiv.appendChild(renderSpacer(backgroundColor))
|
|
410
420
|
}
|
|
411
421
|
|
|
412
422
|
// Comment/discussion area
|
|
413
423
|
|
|
414
|
-
const spacer = issueDiv.appendChild(dom
|
|
415
|
-
spacer.setAttribute('style', 'height: 1em') // spacer and placeHolder
|
|
424
|
+
const spacer = issueDiv.appendChild(renderSpacer(dom, backgroundColor))
|
|
416
425
|
|
|
417
|
-
const template =
|
|
426
|
+
const template = kb.anyValue(tracker, ns.wf('issueURITemplate'))
|
|
418
427
|
/*
|
|
419
428
|
var chatDocURITemplate = kb.anyValue(tracker, ns.wf('chatDocURITemplate')) // relaive to issue
|
|
420
429
|
var chat
|
|
@@ -427,20 +436,21 @@ export function renderIssue (issue, context) {
|
|
|
427
436
|
if (template) {
|
|
428
437
|
messageStore = issue.doc() // for now. Could go deeper
|
|
429
438
|
} else {
|
|
430
|
-
messageStore =
|
|
431
|
-
if (!messageStore) messageStore =
|
|
432
|
-
|
|
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 =
|
|
433
442
|
}
|
|
434
443
|
|
|
435
|
-
|
|
444
|
+
kb.fetcher.nowOrWhenFetched(messageStore, function (ok, body, _xhr) {
|
|
436
445
|
if (!ok) {
|
|
437
446
|
const er = dom.createElement('p')
|
|
438
447
|
er.textContent = body // @@ use nice error message
|
|
439
448
|
issueDiv.insertBefore(er, spacer)
|
|
440
449
|
} else {
|
|
441
|
-
const discussion = messageArea(dom,
|
|
450
|
+
const discussion = messageArea(dom, kb, issue, messageStore)
|
|
442
451
|
issueDiv.insertBefore(discussion, spacer)
|
|
443
|
-
|
|
452
|
+
issueDiv.insertBefore(renderSpacer(dom, backgroundColor), discussion)
|
|
453
|
+
} // Not sure why e stuck this in upwards rather than downwards
|
|
444
454
|
})
|
|
445
455
|
|
|
446
456
|
// Draggable attachment list
|
|
@@ -448,23 +458,22 @@ export function renderIssue (issue, context) {
|
|
|
448
458
|
attachmentHint.innerHTML = `<h4>Attachments</h4>
|
|
449
459
|
<p>Drag files, emails,
|
|
450
460
|
web pages onto the paper clip, or click the file upload button.</p>`
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
}
|
|
461
|
+
const uploadFolderURI =
|
|
462
|
+
issue.uri.endsWith('/index.ttl#this') // This has a whole folder to itself
|
|
463
|
+
? issue.uri.slice(0, 14) + 'Files/' // back to slash
|
|
464
|
+
: issue.dir().uri + 'Files/' + issue.uri.split('#')[1] + '/' // New folder for issue in file with others
|
|
465
|
+
|
|
457
466
|
widgets.attachmentList(dom, issue, issueDiv, {
|
|
458
467
|
doc: stateStore,
|
|
459
468
|
promptIcon: icons.iconBase + 'noun_25830.svg',
|
|
460
|
-
uploadFolder:
|
|
469
|
+
uploadFolder: kb.sym(uploadFolderURI), // Allow local files to be uploaded
|
|
461
470
|
predicate: ns.wf('attachment')
|
|
462
471
|
})
|
|
463
472
|
|
|
464
473
|
// Delete button to delete the issue
|
|
465
474
|
const deleteButton = widgets.deleteButtonWithCheck(dom, issueDiv, 'issue', async function () {
|
|
466
475
|
try {
|
|
467
|
-
await
|
|
476
|
+
await kb.updater.update(kb.connectedStatements(issue))
|
|
468
477
|
} catch (err) {
|
|
469
478
|
complain(`Unable to delete issue: ${err}`, context)
|
|
470
479
|
}
|
|
@@ -482,7 +491,7 @@ export function renderIssue (issue, context) {
|
|
|
482
491
|
'click',
|
|
483
492
|
async function (_event) {
|
|
484
493
|
try {
|
|
485
|
-
await
|
|
494
|
+
await kb.fetcher.load(messageStore, { force: true, clearPreviousData: true })
|
|
486
495
|
} catch (err) {
|
|
487
496
|
alert(err)
|
|
488
497
|
return
|