issue-pane 2.4.8-bbf45639 → 2.4.9-e1b104be

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 CHANGED
File without changes
@@ -0,0 +1,59 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - "**"
7
+ pull_request:
8
+ branches:
9
+ - "**"
10
+ workflow_dispatch:
11
+
12
+ jobs:
13
+ build:
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ matrix:
17
+ node-version:
18
+ - 12.x
19
+ - 14.x
20
+ - 16.x
21
+ steps:
22
+ - uses: actions/checkout@v2
23
+ - name: Use Node.js ${{ matrix.node-version }}
24
+ uses: actions/setup-node@v1
25
+ with:
26
+ node-version: ${{ matrix.node-version }}
27
+ - run: npm ci
28
+ - run: npm run lint --if-present
29
+ - run: npm test
30
+ - run: npm run build --if-present
31
+ - name: Save build
32
+ if: matrix.node-version == '14.x'
33
+ uses: actions/upload-artifact@v2
34
+ with:
35
+ name: build
36
+ path: |
37
+ .
38
+ !node_modules
39
+ retention-days: 1
40
+ npm-publish-build:
41
+ needs: build
42
+ runs-on: ubuntu-latest
43
+ steps:
44
+ - uses: actions/download-artifact@v2
45
+ with:
46
+ name: build
47
+ - uses: actions/setup-node@v1
48
+ with:
49
+ node-version: 14.x
50
+ - uses: rlespinasse/github-slug-action@v3.x
51
+ - name: Append commit hash to package version
52
+ run: 'sed -i -E "s/(\"version\": *\"[^\"]+)/\1-${GITHUB_SHA_SHORT}/" package.json'
53
+ - name: Disable pre- and post-publish actions
54
+ run: 'sed -i -E "s/\"((pre|post)publish)/\"ignore:\1/" package.json'
55
+ - uses: JS-DevTools/npm-publish@v1
56
+ with:
57
+ token: ${{ secrets.NPM_TOKEN }}
58
+ tag: ${{ env.GITHUB_REF_SLUG }}
59
+
package/.nvmrc CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
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
File without changes
package/issue.js CHANGED
@@ -8,11 +8,23 @@ 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
+
11
15
  function complain (message, context) {
12
16
  console.warn(message)
13
17
  context.paneDiv.appendChild(widgets.errorMessageBlock(context.dom, message))
14
18
  }
15
19
 
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
+ }
16
28
  export function getState (issue, classification) {
17
29
  const tracker = kb.the(issue, ns.wf('tracker'), null, issue.doc())
18
30
  const states = kb.any(tracker, ns.wf('issueClass'))
@@ -46,7 +58,7 @@ export function renderIssueCard (issue, context) {
46
58
  const card = dom.createElement('div')
47
59
  const table = card.appendChild(dom.createElement('table'))
48
60
  table.style.width = '100%'
49
- const options = { draggable: false } // Let the baord make th ewhole card draggable
61
+ const options = { draggable: false } // Let the baord make the whole card draggable
50
62
  table.appendChild(widgets.personTR(dom, null, issue, options))
51
63
  table.subject = issue
52
64
  card.style = 'border-radius: 0.4em; border: 0.05em solid grey; margin: 0.3em;'
@@ -105,10 +117,9 @@ export function renderIssue (issue, context) {
105
117
  function setModifiedDate (subj, kb, doc) {
106
118
  if (SET_MODIFIED_DATES) {
107
119
  if (!getOption(tracker, 'trackLastModified')) return
108
- let deletions = kb.statementsMatching(issue, ns.dct('modified'))
109
- deletions = deletions.concat(
110
- kb.statementsMatching(issue, ns.wf('modifiedBy'))
111
- )
120
+ const deletions = kb.statementsMatching(issue, ns.dct('modified'))
121
+ .concat(kb.statementsMatching(issue, ns.wf('modifiedBy'))
122
+ )
112
123
  const insertions = [$rdf.st(issue, ns.dct('modified'), new Date(), doc)]
113
124
  if (me) insertions.push($rdf.st(issue, ns.wf('modifiedBy'), me, doc))
114
125
  kb.updater.update(deletions, insertions, function (_uri, _ok, _body) {})
@@ -150,7 +161,7 @@ export function renderIssue (issue, context) {
150
161
 
151
162
  function setPaneStyle () {
152
163
  const types = kb.findTypeURIs(issue)
153
- let mystyle = 'padding: 0.5em 1.5em 1em 1.5em; '
164
+ const mystyle0 = 'padding: 0.5em 1.5em 1em 1.5em; '
154
165
  let backgroundColor = null
155
166
  for (const uri in types) {
156
167
  backgroundColor = kb.any(
@@ -160,10 +171,12 @@ export function renderIssue (issue, context) {
160
171
  if (backgroundColor) break
161
172
  }
162
173
  backgroundColor = backgroundColor ? backgroundColor.value : '#eee' // default grey
163
- mystyle += 'background-color: ' + backgroundColor + '; '
174
+ const mystyle = mystyle0 + 'background-color: ' + backgroundColor + '; '
164
175
  issueDiv.setAttribute('style', mystyle)
165
176
  }
166
177
 
178
+ /// ////////////// Body of renderIssue
179
+
167
180
  const dom = context.dom
168
181
  const tracker = kb.the(issue, ns.wf('tracker'), null, issue.doc())
169
182
  if (!tracker) throw new Error('No tracker')
@@ -171,12 +184,15 @@ export function renderIssue (issue, context) {
171
184
  const store = issue.doc()
172
185
 
173
186
  const issueDiv = dom.createElement('div')
174
- var me = authn.currentUser()
187
+ const me = authn.currentUser()
175
188
 
176
189
  setPaneStyle()
177
190
 
178
191
  authn.checkUser() // kick off async operation
179
192
 
193
+ const iconButton = issueDiv.appendChild(widgets.button(dom, iconForIssue(issue)))
194
+ widgets.makeDraggable(iconButton, issue) // Drag me wherever you need to do stuff with this issue
195
+
180
196
  const states = kb.any(tracker, ns.wf('issueClass'))
181
197
  if (!states) { throw new Error('This tracker ' + tracker + ' has no issueClass') }
182
198
  const select = widgets.makeSelectForCategory(
@@ -197,13 +213,13 @@ export function renderIssue (issue, context) {
197
213
  issueDiv.appendChild(select)
198
214
 
199
215
  const cats = kb.each(tracker, ns.wf('issueCategory')) // zero or more
200
- for (let i = 0; i < cats.length; i++) {
216
+ for (const cat of cats) {
201
217
  issueDiv.appendChild(
202
218
  widgets.makeSelectForCategory(
203
219
  dom,
204
220
  kb,
205
221
  issue,
206
- cats[i],
222
+ cat,
207
223
  stateStore,
208
224
  function (ok, body) {
209
225
  if (ok) {
@@ -297,20 +313,16 @@ export function renderIssue (issue, context) {
297
313
  // Anyone assigned to any issue we know about
298
314
 
299
315
  async function getPossibleAssignees () {
300
- let devs = []
301
316
  const devGroups = kb.each(issue, ns.wf('assigneeGroup'))
302
- for (let i = 0; i < devGroups.length; i++) {
303
- const group = devGroups[i]
304
- await kb.fetcher.load()
305
- devs = devs.concat(kb.each(group, ns.vcard('member')))
306
- }
317
+ await kb.fetcher.load(devGroups) // Load them all
318
+ const groupDevs = devGroups.map(group => kb.each(group, ns.vcard('member'), null, group.doc())).flat()
307
319
  // Anyone who is a developer of any project which uses this tracker
308
320
  const proj = kb.any(null, ns.doap('bug-database'), tracker) // What project?
309
321
  if (proj) {
310
322
  await kb.fetcher.load(proj)
311
- devs = devs.concat(kb.each(proj, ns.doap('developer')))
312
323
  }
313
- return devs
324
+ const projectDevs = proj ? kb.each(proj, ns.doap('developer')) : []
325
+ return groupDevs.concat(projectDevs)
314
326
  }
315
327
 
316
328
  // Super issues first - like parent directories .. maybe use breadcrums from?? @@
@@ -446,12 +458,11 @@ export function renderIssue (issue, context) {
446
458
  attachmentHint.innerHTML = `<h4>Attachments</h4>
447
459
  <p>Drag files, emails,
448
460
  web pages onto the paper clip, or click the file upload button.</p>`
449
- let uploadFolderURI
450
- if (issue.uri.endsWith('/index.ttl#this')) { // This has a whole folder to itself
451
- uploadFolderURI = issue.uri.slice(0, 14) + 'Files/' // back to slash
452
- } else { // like state.ttl#Iss1587852322438
453
- uploadFolderURI = issue.dir().uri + 'Files/' + issue.uri.split('#')[1] + '/' // New folder for issue in file with others
454
- }
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
+
455
466
  widgets.attachmentList(dom, issue, issueDiv, {
456
467
  doc: stateStore,
457
468
  promptIcon: icons.iconBase + 'noun_25830.svg',
package/issuePane.js CHANGED
@@ -61,7 +61,7 @@ export default {
61
61
  return Promise.all(updates)
62
62
  }
63
63
 
64
- var kb = context.session.store
64
+ const kb = context.session.store
65
65
  const ns = UI.ns
66
66
  let stateStore
67
67
  if (options.newInstance) {
@@ -148,33 +148,41 @@ 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
+ /*
151
154
  for (const sub of existing) {
152
155
  if (!needed.has(sub)) {
153
156
  deletables.push($rdf.st(kb.sym(sub), ns.rdfs('subClassOf'), klass, doc))
154
157
  }
155
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
+ /*
156
163
  for (const sub of needed) {
157
164
  if (!existing.has(sub)) {
158
165
  insertables.push($rdf.st(kb.sym(sub), ns.rdfs('subClassOf'), klass, doc))
159
166
  }
160
167
  }
168
+ */
169
+ return deleteActions.concat(insertActions)
161
170
  }
162
171
  const doc = tracker.doc()
163
172
  const states = kb.any(tracker, ns.wf('issueClass'))
164
- const cats = kb.each(tracker, ns.wf('issueCategory'))
165
- var insertables = []
166
- var deletables = []
167
- cats.push(states)
173
+ const cats = kb.each(tracker, ns.wf('issueCategory')).concat([states])
174
+ let damage = [] // to make totally functionaly need to deal with map over async.
168
175
  for (const klass of cats) {
169
- await checkOneSuperclass(klass)
176
+ damage = await damage.concat(checkOneSuperclass(klass))
170
177
  }
171
- const damage = insertables.length + deletables.length
172
- if (damage) {
173
- alert(`Internal error: s${damage} subclasses inconsistences!`)
174
- /*
178
+ if (damage.length) {
179
+ const insertables = damage.filter(fix => fix.action === 'insert').map(fix => fix.st)
180
+ const deletables = damage.filter(fix => fix.action === 'delete').map(fix => fix.st)
181
+ // alert(`Internal error: s${damage} subclasses inconsistences!`)
182
+ console.log('Damage:', damage)
175
183
  if (confirm(`Fix ${damage} inconsistent subclasses in tracker config?`)) {
176
184
  await kb.updater.update(deletables, insertables)
177
- */
185
+ }
178
186
  }
179
187
  }
180
188
 
@@ -256,7 +264,7 @@ export default {
256
264
  const states = kb.any(subject, ns.wf('issueClass'))
257
265
  const cats = kb.each(tracker, ns.wf('issueCategory')) // zero or more
258
266
  const vars = ['issue', 'state', 'created']
259
- var query = new $rdf.Query(UI.utils.label(subject))
267
+ const query = new $rdf.Query(UI.utils.label(subject))
260
268
  for (let i = 0; i < cats.length; i++) {
261
269
  vars.push('_cat_' + i)
262
270
  }
@@ -437,7 +445,7 @@ export default {
437
445
  h.appendChild(dom.createTextNode(classLabel + ' list')) // Use class label @@I18n
438
446
 
439
447
  // New Issue button
440
- var b = dom.createElement('button')
448
+ const b = dom.createElement('button')
441
449
  const container = dom.createElement('div')
442
450
  b.setAttribute('type', 'button')
443
451
  b.setAttribute('style', 'padding: 0.3em; font-size: 100%; margin: 0.5em;')
@@ -572,8 +580,6 @@ export default {
572
580
  overlay.style = OVERFLOW_STYLE
573
581
  overlay.style.visibility = 'hidden'
574
582
 
575
- // var overlayPane = null // overlay.appendChild(dom.createElement('div')) // avoid stomping on style by pane
576
-
577
583
  UI.authn.checkUser().then(webId => {
578
584
  if (webId) {
579
585
  console.log('Web ID set already: ' + webId)
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
- var titlefield = dom.createElement('input')
103
+ const titlefield = dom.createElement('input')
104
104
  titlefield.setAttribute('type', 'text')
105
105
  titlefield.setAttribute(
106
106
  'style',
package/newTracker.js CHANGED
@@ -20,6 +20,19 @@ export function newTrackerButton (thisTracker, context) {
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
+
23
36
  const appPathSegment = 'issuetracker.w3.org' // how to allocate this string and connect to
24
37
  // console.log("Ready to make new instance at "+ws)
25
38
  const sp = UI.ns.space
@@ -46,18 +59,6 @@ export function newTrackerButton (thisTracker, context) {
46
59
 
47
60
  const oldBase = here.uri.slice(0, here.uri.lastIndexOf('/') + 1)
48
61
 
49
- var 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 kb.sym(u)
60
- }
61
62
  const there = morph(here)
62
63
  const newTracker = morph(thisTracker)
63
64
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "issue-pane",
3
- "version": "2.4.8-bbf45639",
3
+ "version": "2.4.9-e1b104be",
4
4
  "description": "Solid-compatible Panes: issue editor",
5
5
  "main": "./issuePane.js",
6
6
  "scripts": {
@@ -8,8 +8,8 @@
8
8
  "lint": "eslint '*.js'",
9
9
  "lint-fix": "eslint '*.js' --fix",
10
10
  "test": "npm run lint",
11
- "prepublishOnly": "npm test",
12
- "postpublish": "git push origin main --follow-tags"
11
+ "ignore:prepublishOnly": "npm test",
12
+ "ignore:postpublish": "git push origin main --follow-tags"
13
13
  },
14
14
  "repository": {
15
15
  "type": "git",
@@ -34,9 +34,9 @@
34
34
  },
35
35
  "homepage": "https://github.com/solid/issue-pane",
36
36
  "dependencies": {
37
- "pane-registry": "^2.4.5-bbf45639",
38
- "rdflib": "^2.2.15-bbf45639",
39
- "solid-ui": "^2.4.14-bbf45639"
37
+ "pane-registry": "^2.4.6",
38
+ "rdflib": "^2.2.17",
39
+ "solid-ui": "^2.4.15"
40
40
  },
41
41
  "devDependencies": {
42
42
  "eslint": "^7.32.0",
package/tbl-bug-22.png CHANGED
File without changes
File without changes
File without changes
package/ui.js CHANGED
File without changes
package/ui.ttl CHANGED
File without changes
package/wf.js CHANGED
File without changes
package/wf.ttl CHANGED
File without changes