contacts-pane 3.0.2 → 3.0.3

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.
Files changed (45) hide show
  1. package/README.md +53 -1
  2. package/dist/contactsPane.js +6487 -763
  3. package/dist/contactsPane.js.map +1 -1
  4. package/dist/contactsPane.min.js +2 -0
  5. package/dist/contactsPane.min.js.map +1 -0
  6. package/dist/styles/contactsPane.css +602 -0
  7. package/dist/styles/contactsRDFFormsEnforced.css +513 -0
  8. package/dist/styles/groupMembership.css +115 -0
  9. package/dist/styles/individual.css +12 -0
  10. package/dist/styles/localUtils.css +49 -0
  11. package/dist/styles/mugshotGallery.css +17 -0
  12. package/dist/styles/toolsPane.css +43 -0
  13. package/dist/styles/utilities.css +69 -0
  14. package/dist/styles/webidControl.css +90 -0
  15. package/package.json +23 -17
  16. package/dist/autocompleteBar.d.ts +0 -3
  17. package/dist/autocompleteBar.d.ts.map +0 -1
  18. package/dist/autocompleteBar.js +0 -90
  19. package/dist/autocompleteBar.js.map +0 -1
  20. package/dist/autocompleteField.d.ts +0 -20
  21. package/dist/autocompleteField.d.ts.map +0 -1
  22. package/dist/autocompleteField.js +0 -165
  23. package/dist/autocompleteField.js.map +0 -1
  24. package/dist/autocompletePicker.d.ts +0 -15
  25. package/dist/autocompletePicker.d.ts.map +0 -1
  26. package/dist/autocompletePicker.js +0 -253
  27. package/dist/autocompletePicker.js.map +0 -1
  28. package/dist/contactLogic.js +0 -223
  29. package/dist/contactLogic.js.map +0 -1
  30. package/dist/groupMembershipControl.js +0 -107
  31. package/dist/groupMembershipControl.js.map +0 -1
  32. package/dist/individual.js +0 -115
  33. package/dist/individual.js.map +0 -1
  34. package/dist/mintNewAddressBook.js +0 -145
  35. package/dist/mintNewAddressBook.js.map +0 -1
  36. package/dist/mugshotGallery.js +0 -264
  37. package/dist/mugshotGallery.js.map +0 -1
  38. package/dist/publicData.d.ts +0 -82
  39. package/dist/publicData.d.ts.map +0 -1
  40. package/dist/publicData.js +0 -421
  41. package/dist/publicData.js.map +0 -1
  42. package/dist/toolsPane.js +0 -671
  43. package/dist/toolsPane.js.map +0 -1
  44. package/dist/webidControl.js +0 -320
  45. package/dist/webidControl.js.map +0 -1
package/dist/toolsPane.js DELETED
@@ -1,671 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.toolsPane = toolsPane;
7
- var UI = _interopRequireWildcard(require("solid-ui"));
8
- var _solidLogic = require("solid-logic");
9
- var _contactLogic = require("./contactLogic");
10
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
11
- // The tools pane is for managing and debugging and maintaining solid contacts databases
12
- //
13
- /* global confirm, $rdf */
14
-
15
- function toolsPane(selectAllGroups, selectedGroups, groupsMainTable, book, dataBrowserContext, me) {
16
- const dom = dataBrowserContext.dom;
17
- const kb = _solidLogic.store;
18
- const ns = UI.ns;
19
- const VCARD = ns.vcard;
20
- const buttonStyle = 'font-size: 100%; margin: 0.8em; padding:0.5em;';
21
- const pane = dom.createElement('div');
22
- const table = pane.appendChild(dom.createElement('table'));
23
- table.setAttribute('style', 'font-size:120%; margin: 1em; border: 0.1em #ccc ;');
24
- const headerRow = table.appendChild(dom.createElement('tr'));
25
- headerRow.textContent = UI.utils.label(book) + ' - tools';
26
- headerRow.setAttribute('style', 'min-width: 20em; padding: 1em; font-size: 150%; border-bottom: 0.1em solid red; margin-bottom: 2em;');
27
- const statusRow = table.appendChild(dom.createElement('tr'));
28
- const statusBlock = statusRow.appendChild(dom.createElement('div'));
29
- statusBlock.setAttribute('style', 'padding: 2em;');
30
- const MainRow = table.appendChild(dom.createElement('tr'));
31
- const box = MainRow.appendChild(dom.createElement('table'));
32
- table.appendChild(dom.createElement('tr')); // bottomRow
33
-
34
- const context = {
35
- target: book,
36
- me,
37
- noun: 'address book',
38
- div: pane,
39
- dom,
40
- statusRegion: statusBlock
41
- };
42
- function complain(message) {
43
- console.log(message);
44
- statusBlock.appendChild(UI.widgets.errorMessageBlock(dom, message, 'pink'));
45
- }
46
-
47
- // Body of main pane function
48
- async function main() {
49
- box.appendChild(UI.aclControl.ACLControlBox5(book.dir(), dataBrowserContext, 'book', kb, function (ok, body) {
50
- if (!ok) box.innerHTML = 'ACL control box Failed: ' + body;
51
- }));
52
-
53
- //
54
- try {
55
- await UI.login.registrationControl(context, book, ns.vcard('AddressBook'));
56
- } catch (e) {
57
- UI.widgets.complain(context, 'registrationControl: ' + e);
58
- }
59
- console.log('Registration control finished.');
60
-
61
- // Output stats in line mode form
62
- const logSpace = MainRow.appendChild(dom.createElement('pre'));
63
- function log(message) {
64
- console.log(message);
65
- logSpace.textContent += message + '\n';
66
- }
67
- function stats() {
68
- const totalCards = kb.each(undefined, VCARD('inAddressBook'), book).length;
69
- log('' + totalCards + ' cards loaded. ');
70
- let groups = kb.each(book, VCARD('includesGroup'));
71
- const strings = new Set(groups.map(group => group.uri)); // remove dups
72
- groups = [...strings].map(uri => kb.sym(uri));
73
- log('' + groups.length + ' total groups. ');
74
- const gg = [];
75
- for (const g in selectedGroups) {
76
- gg.push(g);
77
- }
78
- log('' + gg.length + ' selected groups. ');
79
- }
80
- async function loadIndexHandler(_event) {
81
- loadIndexButton.setAttribute('style', 'background-color: #ffc;');
82
- const nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex'));
83
- try {
84
- await kb.fetcher.load(nameEmailIndex);
85
- } catch (e) {
86
- loadIndexButton.setAttribute('style', 'background-color: #fcc;');
87
- log('Error: People index has NOT been loaded' + e + '\n');
88
- }
89
- loadIndexButton.setAttribute('style', 'background-color: #cfc;');
90
- log(' People index has been loaded\n');
91
- } // loadIndexHandler
92
- const loadIndexButton = pane.appendChild(dom.createElement('button'));
93
- loadIndexButton.textContent = 'Load main index';
94
- loadIndexButton.style.cssText = buttonStyle;
95
- loadIndexButton.addEventListener('click', loadIndexHandler);
96
- const statButton = pane.appendChild(dom.createElement('button'));
97
- statButton.textContent = 'Statistics';
98
- statButton.style.cssText = buttonStyle;
99
- statButton.addEventListener('click', stats);
100
- const checkAccessButton = pane.appendChild(dom.createElement('button'));
101
- checkAccessButton.textContent = 'Check individual card access of selected groups';
102
- checkAccessButton.style.cssText = buttonStyle;
103
- async function checkAcces(_event) {
104
- function doCard(card) {
105
- UI.acl.fixIndividualCardACL(card, log, function (ok, message) {
106
- if (ok) {
107
- log('Success for ' + UI.utils.label(card));
108
- } else {
109
- log('Failure for ' + UI.utils.label(card) + ': ' + message);
110
- }
111
- });
112
- }
113
- const gg = [];
114
- for (const g in selectedGroups) {
115
- gg.push(g);
116
- }
117
- for (let i = 0; i < gg.length; i++) {
118
- const g = kb.sym(gg[i]);
119
- const a = (0, _contactLogic.groupMembers)(kb, g);
120
- log(UI.utils.label(g) + ': ' + a.length + ' members');
121
- for (let j = 0; j < a.length; j++) {
122
- const card = a[j];
123
- log(UI.utils.label(card));
124
- doCard(card);
125
- }
126
- }
127
- }
128
- checkAccessButton.addEventListener('click', checkAcces);
129
-
130
- // ///////////////////////////////////////////////////////////////////////////
131
- //
132
- // DUPLICATES CHECK
133
- const checkDuplicates = pane.appendChild(dom.createElement('button'));
134
- checkDuplicates.textContent = 'Find duplicate cards';
135
- checkDuplicates.style.cssText = buttonStyle;
136
- checkDuplicates.addEventListener('click', function (_event) {
137
- const stats = {}; // global god context
138
-
139
- stats.book = book;
140
- stats.nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex'));
141
- log('Loading name index...');
142
- _solidLogic.store.fetcher.nowOrWhenFetched(stats.nameEmailIndex, undefined, function (_ok, _message) {
143
- log('Loaded name index.');
144
- stats.cards = [];
145
- stats.duplicates = [];
146
- stats.definitive = [];
147
- stats.nameless = [];
148
- stats.exactDuplicates = [];
149
- stats.nameOnlyDuplicates = [];
150
- stats.uniquesSet = [];
151
- stats.groupProblems = [];
152
-
153
- // Erase one card and all its files -> (err)
154
- //
155
- /*
156
- function eraseOne (card) {
157
- return new Promise(function (resolve, reject) {
158
- function removeFromMainIndex () {
159
- var indexBit = kb.connectedStatements(card, stats.nameEmailIndex)
160
- log('Bits of the name index file:' + indexBit)
161
- log('Patching main index file...')
162
- kb.updater.update(indexBit, [], function (uri, ok, body) {
163
- if (ok) {
164
- log('Success')
165
- resolve(null)
166
- } else {
167
- log('Error patching index file! ' + body)
168
- reject('Error patching index file! ' + body)
169
- }
170
- })
171
- }
172
- var filesToDelete = [ card.doc() ]
173
- var photos = kb.each(card, ns.vcard('hasPhoto')) // could be > 1
174
- if (photos.length) {
175
- filesToDelete = filesToDelete.concat(photos)
176
- }
177
- filesToDelete.push(card.dir()) // the folder last
178
- log('Files to delete: ' + filesToDelete)
179
- if (!confirm('DELETE card ' + card.dir() + ' for "' + kb.any(card, VCARD('fn')) + '", with ' + kb.each(card).length + 'statements?')) {
180
- return resolve('Cancelled by user')
181
- }
182
- function deleteNextFile () {
183
- var resource = filesToDelete.shift()
184
- if (!resource) {
185
- log('All deleted')
186
- removeFromMainIndex()
187
- resolve()
188
- }
189
- log('Deleting ... ' + resource)
190
- kb.fetcher.delete(resource)
191
- .then(function () {
192
- log('Deleted ok: ' + resource)
193
- deleteNextFile()
194
- })
195
- .catch(function (e) {
196
- var err = '*** ERROR deleting ' + resource + ': ' + e
197
- log(err)
198
- if (confirm('Patch out index file for card ' + card.dir() + ' EVEN THOUGH card DELETE errors?')) {
199
- removeFromMainIndex()
200
- } else {
201
- reject(err)
202
- }
203
- })
204
- }
205
- deleteNextFile()
206
- }) // Promise
207
- } // erase one
208
- */
209
- // Check actual records to see which are exact matches - slow
210
- stats.nameDupLog = kb.sym(book.dir().uri + 'dedup-nameDupLog.ttl');
211
- stats.exactDupLog = kb.sym(book.dir().uri + 'dedup-exactDupLog.ttl');
212
- /*
213
- function checkOne (card) {
214
- return new Promise(function (resolve, reject) {
215
- var name = kb.anyValue(card, ns.vcard('fn'))
216
- var other = stats.definitive[name]
217
- kb.fetcher.load([card, other]).then(function (xhrs) {
218
- var exclude = {}
219
- exclude[ns.vcard('hasUID').uri] = true
220
- exclude[ns.dc('created').uri] = true
221
- exclude[ns.dc('modified').uri] = true
222
- function filtered (x) {
223
- return kb.statementsMatching(null, null, null, x.doc()).filter(function (st) {
224
- return !exclude[st.predicate.uri]
225
- })
226
- }
227
- var desc = filtered(card)
228
- var desc2 = filtered(other)
229
- // var desc = connectedStatements(card, card.doc(), exclude)
230
- // var desc2 = connectedStatements(other, other.doc(), exclude)
231
- if (desc.length !== desc2.length) {
232
- log('CARDS to NOT match lengths ')
233
- stats.nameOnlyDuplicates.push(card)
234
- return resolve(false)
235
- }
236
- if (!desc.length) {
237
- log('@@@@@@ Zero length ')
238
- stats.nameOnlyDuplicates.push(card)
239
- return resolve(false)
240
- }
241
- // //////// Compare the two
242
- // Cheat: serialize and compare
243
- // var cardText = $rdf.serialize(card.doc(), kb, card.doc().uri, 'text/turtle')
244
- // var otherText = $rdf.serialize(other.doc(), kb, other.doc().uri, 'text/turtle')
245
- var cardText = (new $rdf.Serializer(kb)).setBase(card.doc().uri).statementsToN3(desc)
246
- var otherText = (new $rdf.Serializer(kb)).setBase(other.doc().uri).statementsToN3(desc2)
247
- //
248
- // log('Name: ' + name + ', statements: ' + desc.length)
249
- // log('___________________________________________')
250
- // log('KEEPING: ' + other.doc() + '\n' + cardText)
251
- // log('___________________________________________')
252
- // log('DELETING: '+ card.doc() + '\n' + otherText)
253
- // log('___________________________________________')
254
- //
255
- if (cardText !== otherText) {
256
- log('Texts differ')
257
- stats.nameOnlyDuplicates.push(card)
258
- return resolve(false)
259
- }
260
- var cardGroups = kb.each(null, ns.vcard('hasMember'), card)
261
- var otherGroups = kb.each(null, ns.vcard('hasMember'), other)
262
- for (var j = 0; j < cardGroups.length; j++) {
263
- var found = false
264
- for (var k = 0; k < otherGroups.length; k++) {
265
- if (otherGroups[k].sameTerm(cardGroups[j])) { found = true }
266
- }
267
- if (!found) {
268
- log('This one groups: ' + cardGroups)
269
- log('Other one groups: ' + otherGroups)
270
- log('Cant delete this one because it has a group, ' + cardGroups[j] + ', which the other does not.')
271
- stats.nameOnlyDuplicates.push(card)
272
- return resolve(false)
273
- }
274
- }
275
- console.log('Group check done -- exact duplicate: ' + card)
276
- stats.exactDuplicates.push(card)
277
- resolve(true)
278
- }).catch(function (e) {
279
- log('Cant load a card! ' + [card, other] + ': ' + e)
280
- stats.nameOnlyDuplicates.push(card)
281
- resolve(false)
282
- // if (confirm('Patch out index file for card ' + card.dir() + ' EVEN THOUGH card READ errors?')){
283
- // removeFromMainIndex()
284
- // }
285
- })
286
- })
287
- } // checkOne
288
- */
289
- stats.nameOnlyErrors = [];
290
- stats.nameLessZeroData = [];
291
- stats.nameLessIndex = [];
292
- stats.namelessUniques = [];
293
- stats.nameOnlyDuplicatesGroupDiff = [];
294
- function checkOneNameless(card) {
295
- return new Promise(function (resolve) {
296
- kb.fetcher.load(card).then(function (_xhr) {
297
- log(' Nameless check ' + card);
298
- const exclude = {};
299
- exclude[ns.vcard('hasUID').uri] = true;
300
- exclude[ns.dc('created').uri] = true;
301
- exclude[ns.dc('modified').uri] = true;
302
- function filtered(x) {
303
- return kb.statementsMatching(null, null, null, x.doc()).filter(function (st) {
304
- return !exclude[st.predicate.uri];
305
- });
306
- }
307
- const desc = filtered(card);
308
- // var desc = connectedStatements(card, card.doc(), exclude)
309
- // var desc2 = connectedStatements(other, other.doc(), exclude)
310
- if (!desc.length) {
311
- log(' Zero length ' + card);
312
- stats.nameLessZeroData.push(card);
313
- return resolve(false);
314
- }
315
- // Compare the two
316
- // Cheat: serialize and compare
317
- // var cardText = $rdf.serialize(card.doc(), kb, card.doc().uri, 'text/turtle')
318
- // var otherText = $rdf.serialize(other.doc(), kb, other.doc().uri, 'text/turtle')
319
- const cardText = new $rdf.Serializer(kb).setBase(card.doc().uri).statementsToN3(desc);
320
- const other = stats.nameLessIndex[cardText];
321
- if (other) {
322
- log(' Matches with ' + other);
323
- // alain not sure it works we may need to concat with 'sameAs' group.doc (.map(st => st.why))
324
- const cardGroups = kb.each(null, ns.vcard('hasMember'), card);
325
- const otherGroups = kb.each(null, ns.vcard('hasMember'), other);
326
- for (let j = 0; j < cardGroups.length; j++) {
327
- let found = false;
328
- for (let k = 0; k < otherGroups.length; k++) {
329
- if (otherGroups[k].sameTerm(cardGroups[j])) found = true;
330
- }
331
- if (!found) {
332
- log('This one groups: ' + cardGroups);
333
- log('Other one groups: ' + otherGroups);
334
- log('Cant skip this one because it has a group, ' + cardGroups[j] + ', which the other does not.');
335
- stats.nameOnlyDuplicatesGroupDiff.push(card);
336
- return resolve(false);
337
- }
338
- }
339
- console.log('Group check done -- exact duplicate: ' + card);
340
- } else {
341
- log('First nameless like: ' + card.doc());
342
- log('___________________________________________');
343
- log(cardText);
344
- log('___________________________________________');
345
- stats.nameLessIndex[cardText] = card;
346
- stats.namelessUniques.push(card);
347
- }
348
- resolve(true);
349
- }).catch(function (e) {
350
- log('Cant load a nameless card!: ' + e);
351
- stats.nameOnlyErrors.push(card);
352
- resolve(false);
353
- });
354
- });
355
- } // checkOneNameless
356
-
357
- function checkAllNameless() {
358
- stats.namelessToCheck = stats.namelessToCheck || stats.nameless.slice();
359
- log('Nameless check left: ' + stats.namelessToCheck.length);
360
- return new Promise(function (resolve) {
361
- const x = stats.namelessToCheck.shift();
362
- if (!x) {
363
- log('namelessUniques: ' + stats.namelessUniques.length);
364
- log('namelessUniques: ' + stats.namelessUniques);
365
- if (stats.namelessUniques.length > 0 && confirm('Add all ' + stats.namelessUniques.length + ' nameless cards to the rescued set?')) {
366
- stats.uniques = stats.uniques.concat(stats.namelessUniques);
367
- for (let k = 0; k < stats.namelessUniques.length; k++) {
368
- stats.uniqueSet[stats.namelessUniques[k].uri] = true;
369
- }
370
- }
371
- return resolve(true);
372
- }
373
- checkOneNameless(x).then(function (exact) {
374
- log(' Nameless check returns ' + exact);
375
- checkAllNameless(); // loop
376
- });
377
- });
378
- }
379
- function checkGroupMembers() {
380
- return new Promise(function (resolve) {
381
- // var inUniques = 0
382
- log('Groups loaded');
383
- for (let i = 0; i < stats.uniques.length; i++) {
384
- stats.uniquesSet[stats.uniques[i].uri] = true;
385
- }
386
- stats.groupMembers = [];
387
- kb.each(null, ns.vcard('hasMember')).forEach(group => {
388
- stats.groupMembers = stats.groupMembers.concat((0, _contactLogic.groupMembers)(kb, group));
389
- });
390
- log(' Naive group members ' + stats.groupMembers.length);
391
- stats.groupMemberSet = [];
392
- for (let j = 0; j < stats.groupMembers.length; j++) {
393
- stats.groupMemberSet[stats.groupMembers[j].uri] = stats.groupMembers[j];
394
- }
395
- stats.groupMembers2 = [];
396
- for (const g in stats.groupMemberSet) {
397
- stats.groupMembers2.push(stats.groupMemberSet[g]);
398
- }
399
- log(' Compact group members ' + stats.groupMembers2.length);
400
- if ($rdf.keepThisCodeForLaterButDisableFerossConstantConditionPolice) {
401
- // Don't inspect as seems groups membership is complete
402
- for (let i = 0; i < stats.groupMembers.length; i++) {
403
- const card = stats.groupMembers[i];
404
- if (stats.uniquesSet[card.uri]) {
405
- // inUniques += 1
406
- } else {
407
- log(' Not in uniques: ' + card);
408
- stats.groupProblems.push(card);
409
- if (stats.duplicateSet[card.uri]) {
410
- log(' ** IN duplicates alas:' + card);
411
- } else {
412
- log(' **** WTF?');
413
- }
414
- }
415
- }
416
- log('Problem cards: ' + stats.groupProblems.length);
417
- } // if
418
- resolve(true);
419
- });
420
- } // checkGroupMembers
421
-
422
- function scanForDuplicates() {
423
- return new Promise(function (resolve) {
424
- stats.cards = kb.each(undefined, VCARD('inAddressBook'), stats.book);
425
- log('' + stats.cards.length + ' total cards');
426
- let c, card, name;
427
- for (c = 0; c < stats.cards.length; c++) {
428
- card = stats.cards[c];
429
- name = kb.anyValue(card, ns.vcard('fn'));
430
- if (!name) {
431
- stats.nameless.push(card);
432
- continue;
433
- }
434
- if (stats.definitive[name] === card) {
435
- // pass
436
- } else if (stats.definitive[name]) {
437
- const n = stats.duplicates.length;
438
- if (n < 100 || n < 1000 && n % 10 === 0 || n % 100 === 0) {
439
- // log('' + n + ') Possible duplicate ' + card + ' of: ' + definitive[name])
440
- }
441
- stats.duplicates.push(card);
442
- } else {
443
- stats.definitive[name] = card;
444
- }
445
- }
446
- stats.duplicateSet = [];
447
- for (let i = 0; i < stats.duplicates.length; i++) {
448
- stats.duplicateSet[stats.duplicates[i].uri] = stats.duplicates[i];
449
- }
450
- stats.namelessSet = [];
451
- for (let i = 0; i < stats.nameless.length; i++) {
452
- stats.namelessSet[stats.nameless[i].uri] = stats.nameless[i];
453
- }
454
- stats.uniques = [];
455
- stats.uniqueSet = [];
456
- for (let i = 0; i < stats.cards.length; i++) {
457
- const uri = stats.cards[i].uri;
458
- if (!stats.duplicateSet[uri] && !stats.namelessSet[uri]) {
459
- stats.uniques.push(stats.cards[i]);
460
- stats.uniqueSet[uri] = stats.cards[i];
461
- }
462
- }
463
- log('Uniques: ' + stats.uniques.length);
464
- log('' + stats.nameless.length + ' nameless cards.');
465
- log('' + stats.duplicates.length + ' name-duplicate cards, leaving ' + (stats.cards.length - stats.duplicates.length));
466
- resolve(true);
467
- });
468
- }
469
-
470
- // Save a new clean version
471
- function saveCleanPeople() {
472
- let cleanPeople;
473
- return Promise.resolve().then(() => {
474
- cleanPeople = kb.sym(stats.book.dir().uri + 'clean-people.ttl');
475
- let sts = [];
476
- for (let i = 0; i < stats.uniques.length; i++) {
477
- sts = sts.concat(kb.connectedStatements(stats.uniques[i], stats.nameEmailIndex));
478
- }
479
- const sz = new $rdf.Serializer(kb).setBase(stats.nameEmailIndex.uri);
480
- log('Serializing index of uniques...');
481
- const data = sz.statementsToN3(sts);
482
- return kb.fetcher.webOperation('PUT', cleanPeople, {
483
- data,
484
- contentType: 'text/turtle'
485
- });
486
- }).then(function () {
487
- log('Done uniques log ' + cleanPeople);
488
- return true;
489
- }).catch(function (e) {
490
- log('Error saving uniques: ' + e);
491
- });
492
- }
493
- function saveCleanGroup(g) {
494
- let cleanGroup;
495
- return Promise.resolve().then(() => {
496
- const s = g.uri.replace('/Group/', '/NewGroup/');
497
- cleanGroup = kb.sym(s);
498
- let sts = [];
499
- for (let i = 0; i < stats.uniques.length; i++) {
500
- sts = sts.concat(kb.connectedStatements(stats.uniques[i], g.doc()));
501
- }
502
- const sz = new $rdf.Serializer(kb).setBase(g.uri);
503
- log(' Regenerating group of uniques...' + cleanGroup);
504
- const data = sz.statementsToN3(sts);
505
- return kb.fetcher.webOperation('PUT', cleanGroup, {
506
- data,
507
- contentType: 'text/turtle'
508
- });
509
- }).then(() => {
510
- log(' Done uniques group ' + cleanGroup);
511
- return true;
512
- }).catch(e => {
513
- log('Error saving : ' + e);
514
- });
515
- }
516
- function saveAllGroups() {
517
- log('Saving ALL GROUPS');
518
- return Promise.all(stats.groupObjects.map(saveCleanGroup));
519
- }
520
- const getAndSortGroups = function () {
521
- let groups = [];
522
- if (stats.book) {
523
- const books = [stats.book];
524
- books.forEach(function (book) {
525
- const gs = book ? kb.each(book, ns.vcard('includesGroup')) : [];
526
- const gs2 = gs.map(function (g) {
527
- return [book, kb.any(g, ns.vcard('fn')), g];
528
- });
529
- groups = groups.concat(gs2);
530
- });
531
- groups.sort();
532
- }
533
- return groups;
534
- };
535
- const groups = getAndSortGroups(); // Needed?
536
-
537
- stats.groupObjects = groups.map(gstr => gstr[2]);
538
- log('Loading ' + stats.groupObjects.length + ' groups... ');
539
- kb.fetcher.load(stats.groupObjects).then(scanForDuplicates).then(checkGroupMembers).then(checkAllNameless).then(() => {
540
- return new Promise(function (resolve, reject) {
541
- if (confirm('Write new clean versions?')) {
542
- resolve(true);
543
- } else {
544
- reject(new Error('User cancelled writing clean versions'));
545
- }
546
- });
547
- }).then(saveCleanPeople).then(saveAllGroups).then(function () {
548
- log('Done!');
549
- });
550
- });
551
- });
552
- async function fixGroupless(book) {
553
- const groupless = await getGroupless(book);
554
- if (groupless.length === 0) {
555
- log('No groupless cards found.');
556
- return;
557
- }
558
- const groupOfUngrouped = await (0, _contactLogic.saveNewGroup)(book, 'ZSortThese');
559
- if (confirm(`Add the ${groupless.length} cards without groups to a ZSortThese group?`)) {
560
- for (const person of groupless) {
561
- log(' adding ' + person);
562
- await (0, _contactLogic.addPersonToGroup)(person, groupOfUngrouped);
563
- }
564
- }
565
- log('People moved to group.');
566
- }
567
- async function getGroupless(book) {
568
- const groupIndex = kb.any(book, ns.vcard('groupIndex'));
569
- const nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex'));
570
- try {
571
- await kb.fetcher.load([nameEmailIndex, groupIndex]);
572
- const groups = kb.each(book, ns.vcard('includesGroup'));
573
- await kb.fetcher.load(groups);
574
- } catch (e) {
575
- complain('Error loading stuff:' + e);
576
- }
577
- const reverseIndex = {};
578
- const groupless = [];
579
- let groups = kb.each(book, VCARD('includesGroup'));
580
- const strings = new Set(groups.map(group => group.uri)); // remove dups
581
- groups = [...strings].map(uri => kb.sym(uri));
582
- log('' + groups.length + ' total groups. ');
583
- for (let i = 0; i < groups.length; i++) {
584
- const g = groups[i];
585
- const a = (0, _contactLogic.groupMembers)(kb, g);
586
- log(UI.utils.label(g) + ': ' + a.length + ' members');
587
- for (let j = 0; j < a.length; j++) {
588
- kb.allAliases(a[j]).forEach(function (y) {
589
- reverseIndex[y.uri] = g;
590
- });
591
- }
592
- }
593
- const cards = kb.each(undefined, VCARD('inAddressBook'), book);
594
- log('' + cards.length + ' total cards');
595
- for (let c = 0; c < cards.length; c++) {
596
- if (!reverseIndex[cards[c].uri]) {
597
- groupless.push(cards[c]);
598
- log(' groupless ' + UI.utils.label(cards[c]));
599
- }
600
- }
601
- log('' + groupless.length + ' groupless cards.');
602
- return groupless;
603
- }
604
- const checkGroupless = pane.appendChild(dom.createElement('button'));
605
- checkGroupless.style.cssText = buttonStyle;
606
- checkGroupless.textContent = 'Find individuals with no group';
607
- checkGroupless.addEventListener('click', function (_event) {
608
- log('Loading groups...');
609
- selectAllGroups(selectedGroups, groupsMainTable, async function (ok, message) {
610
- if (!ok) {
611
- log('Load all groups: failed: ' + message);
612
- return;
613
- }
614
- const nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex'));
615
- try {
616
- await kb.fetcher.load(nameEmailIndex);
617
- } catch (e) {
618
- complain(e);
619
- }
620
- log('Loaded groups and name index.');
621
- getGroupless(book);
622
- log('Groupless list finished..');
623
- }); // select all groups then
624
- });
625
- const fixGrouplessButton = pane.appendChild(dom.createElement('button'));
626
- fixGrouplessButton.style.cssText = buttonStyle;
627
- fixGrouplessButton.textContent = 'Put all individuals with no group in a new group';
628
- fixGrouplessButton.addEventListener('click', _event => fixGroupless(book));
629
- async function fixToOldDataModel(book) {
630
- async function updateToOldDataModel(groups) {
631
- let ds = [];
632
- let ins = [];
633
- groups.forEach(group => {
634
- let vcardOrWebids = kb.statementsMatching(null, ns.owl('sameAs'), null, group.doc()).map(st => st.subject);
635
- const strings = new Set(vcardOrWebids.map(contact => contact.uri)); // remove dups
636
- vcardOrWebids = [...strings].map(uri => kb.sym(uri));
637
- vcardOrWebids.forEach(item => {
638
- if (!kb.each(item, ns.vcard('fn'), null, group.doc()).length) {
639
- // delete item this is a new data model, item is a webid not a card.
640
- ds = ds.concat(kb.statementsMatching(item, ns.owl('sameAs'), null, group.doc()).concat(kb.statementsMatching(undefined, undefined, item, group.doc())));
641
- // add webid card to group
642
- const cards = kb.each(item, ns.owl('sameAs'), null, group.doc());
643
- cards.forEach(card => {
644
- ins = ins.concat($rdf.st(card, ns.owl('sameAs'), item, group.doc())).concat($rdf.st(group, ns.vcard('hasMember'), card, group.doc()));
645
- });
646
- }
647
- });
648
- });
649
- if (ds.length && confirm('Groups can be updated to old data model ?')) {
650
- await kb.updater.updateMany(ds, ins);
651
- alert('Update done');
652
- } else {
653
- if (!ds.length) alert('Nothing to update.\nAll Groups already use the old data model.');
654
- }
655
- }
656
- let groups = kb.each(book, VCARD('includesGroup'));
657
- const strings = new Set(groups.map(group => group.uri)); // remove dups
658
- groups = [...strings].map(uri => kb.sym(uri));
659
- updateToOldDataModel(groups);
660
- }
661
- const fixToOldDataModelButton = pane.appendChild(dom.createElement('button'));
662
- fixToOldDataModelButton.style.cssText = buttonStyle;
663
- fixToOldDataModelButton.textContent = 'Revert groups to old data model';
664
- fixToOldDataModelButton.addEventListener('click', _event => fixToOldDataModel(book));
665
- } // main
666
- main();
667
- return pane;
668
- } // toolsPane
669
-
670
- // ends
671
- //# sourceMappingURL=toolsPane.js.map