contacts-pane 2.5.7 → 2.5.8-b63e0080
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/contactLogic.js +21 -21
- package/contactsPane.js +9 -21
- package/individual.js +10 -10
- package/lib/autocompletePicker.js +4 -4
- package/lib/publicData.js +8 -8
- package/mintNewAddressBook.js +3 -20
- package/mugshotGallery.js +19 -19
- package/package.json +1 -1
- package/toolsPane.js +43 -43
- package/webidControl.js +11 -11
package/contactLogic.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// Logic for solid contacts
|
|
2
2
|
|
|
3
3
|
import * as UI from 'solid-ui'
|
|
4
|
-
import { store } from 'solid-logic'
|
|
5
4
|
import { getPersonas } from './webidControl'
|
|
6
5
|
|
|
7
6
|
const ns = UI.ns
|
|
8
7
|
const $rdf = UI.rdf
|
|
9
8
|
const utils = UI.utils
|
|
10
|
-
const
|
|
9
|
+
const kb = UI.store
|
|
10
|
+
const updater = kb.updater
|
|
11
11
|
|
|
12
12
|
/** Perform updates on more than one document @@ Move to rdflib!
|
|
13
13
|
*/
|
|
@@ -18,7 +18,7 @@ export async function updateMany (deletions, insertions = []) {
|
|
|
18
18
|
if (!uniqueDocs.find(uniqueDoc => uniqueDoc.equals(doc))) uniqueDocs.push(doc)
|
|
19
19
|
})
|
|
20
20
|
const updates = uniqueDocs.map(doc =>
|
|
21
|
-
|
|
21
|
+
kb.updater.update(deletions.filter(st => st.why.sameTerm(doc)),
|
|
22
22
|
insertions.filter(st => st.why.sameTerm(doc))))
|
|
23
23
|
return Promise.all(updates)
|
|
24
24
|
}
|
|
@@ -29,11 +29,11 @@ export async function updateMany (deletions, insertions = []) {
|
|
|
29
29
|
* @returns {NamedNode} the person
|
|
30
30
|
*/
|
|
31
31
|
export async function saveNewContact (book, name, selectedGroups, klass) {
|
|
32
|
-
await
|
|
33
|
-
const nameEmailIndex =
|
|
32
|
+
await kb.fetcher.load(book.doc())
|
|
33
|
+
const nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex'))
|
|
34
34
|
|
|
35
35
|
const uuid = utils.genUuid()
|
|
36
|
-
const person =
|
|
36
|
+
const person = kb.sym(
|
|
37
37
|
book.dir().uri + 'Person/' + uuid + '/index.ttl#this'
|
|
38
38
|
)
|
|
39
39
|
const doc = person.doc()
|
|
@@ -52,7 +52,7 @@ export async function saveNewContact (book, name, selectedGroups, klass) {
|
|
|
52
52
|
]
|
|
53
53
|
|
|
54
54
|
for (const gu in selectedGroups) {
|
|
55
|
-
const g =
|
|
55
|
+
const g = kb.sym(gu)
|
|
56
56
|
const gd = g.doc()
|
|
57
57
|
agenda.push(
|
|
58
58
|
$rdf.st(g, ns.vcard('hasMember'), person, gd),
|
|
@@ -79,19 +79,19 @@ export function sanitizeToAlpha (name) { // https://mathiasbynens.be/notes/es6-u
|
|
|
79
79
|
* @returns group
|
|
80
80
|
*/
|
|
81
81
|
export async function saveNewGroup (book, name) {
|
|
82
|
-
await
|
|
83
|
-
const gix =
|
|
82
|
+
await kb.fetcher.load(book.doc())
|
|
83
|
+
const gix = kb.any(book, ns.vcard('groupIndex'))
|
|
84
84
|
|
|
85
85
|
const gname = sanitizeToAlpha(name)
|
|
86
|
-
const group =
|
|
86
|
+
const group = kb.sym(book.dir().uri + 'Group/' + gname + '.ttl#this')
|
|
87
87
|
const doc = group.doc()
|
|
88
88
|
console.log(' New group will be: ' + group + '\n')
|
|
89
89
|
try {
|
|
90
|
-
await
|
|
90
|
+
await kb.fetcher.load(gix)
|
|
91
91
|
} catch (err) {
|
|
92
92
|
throw new Error('Error loading group index!' + gix.uri + ': ' + err)
|
|
93
93
|
}
|
|
94
|
-
if (
|
|
94
|
+
if (kb.holds(book, ns.vcard('includesGroup'), group, gix)) {
|
|
95
95
|
return group // Already exists
|
|
96
96
|
}
|
|
97
97
|
const insertTriples = [
|
|
@@ -121,12 +121,12 @@ export async function saveNewGroup (book, name) {
|
|
|
121
121
|
export async function addPersonToGroup (thing, group) {
|
|
122
122
|
const toBeFetched = [thing.doc(), group.doc()]
|
|
123
123
|
try {
|
|
124
|
-
await
|
|
124
|
+
await kb.fetcher.load(toBeFetched)
|
|
125
125
|
} catch (e) {
|
|
126
126
|
throw new Error('addPersonToGroup: ' + e)
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
const types =
|
|
129
|
+
const types = kb.findTypeURIs(thing)
|
|
130
130
|
for (const ty in types) {
|
|
131
131
|
console.log(' drop object type includes: ' + ty) // @@ Allow email addresses and phone numbers to be dropped?
|
|
132
132
|
}
|
|
@@ -134,10 +134,10 @@ export async function addPersonToGroup (thing, group) {
|
|
|
134
134
|
ns.vcard('Organization').uri in types)) {
|
|
135
135
|
return alert(`Can't add ${thing} to a group: it has to be an individual or another group.`)
|
|
136
136
|
}
|
|
137
|
-
const pname =
|
|
138
|
-
const gname =
|
|
137
|
+
const pname = kb.any(thing, ns.vcard('fn'))
|
|
138
|
+
const gname = kb.any(group, ns.vcard('fn'))
|
|
139
139
|
if (!pname) { return alert('No vcard name known for ' + thing) }
|
|
140
|
-
const already =
|
|
140
|
+
const already = kb.holds(group, ns.vcard('hasMember'), thing, group.doc())
|
|
141
141
|
if (already) {
|
|
142
142
|
return alert(
|
|
143
143
|
'ALREADY added ' + pname + ' to group ' + gname
|
|
@@ -150,15 +150,15 @@ export async function addPersonToGroup (thing, group) {
|
|
|
150
150
|
$rdf.st(thing, ns.vcard('fn'), pname, group.doc())
|
|
151
151
|
]
|
|
152
152
|
// find person webIDs
|
|
153
|
-
const webIDs = getPersonas(
|
|
153
|
+
const webIDs = getPersonas(kb, thing).map(webid => webid.value)
|
|
154
154
|
webIDs.forEach(webid => {
|
|
155
|
-
ins.push($rdf.st(thing, ns.owl('sameAs'),
|
|
155
|
+
ins.push($rdf.st(thing, ns.owl('sameAs'), kb.sym(webid), group.doc()))
|
|
156
156
|
})
|
|
157
157
|
try {
|
|
158
158
|
await updater.update([], ins)
|
|
159
159
|
// to allow refresh of card groupList
|
|
160
|
-
|
|
161
|
-
await
|
|
160
|
+
kb.fetcher.unload(group.doc())
|
|
161
|
+
await kb.fetcher.load(group.doc())
|
|
162
162
|
} catch (e) {
|
|
163
163
|
throw new Error(`Error adding ${pname} to group ${gname}:` + e)
|
|
164
164
|
}
|
package/contactsPane.js
CHANGED
|
@@ -15,7 +15,6 @@ to change its state according to an ontology, comment on it, etc.
|
|
|
15
15
|
/* global alert, confirm */
|
|
16
16
|
|
|
17
17
|
import * as UI from 'solid-ui'
|
|
18
|
-
import { authn, solidLogicSingleton } from 'solid-logic'
|
|
19
18
|
import { toolsPane } from './toolsPane'
|
|
20
19
|
import { mintNewAddressBook } from './mintNewAddressBook'
|
|
21
20
|
import { renderIndividual } from './individual'
|
|
@@ -64,7 +63,7 @@ export default {
|
|
|
64
63
|
|
|
65
64
|
// Reproduction: Spawn a new instance of this app
|
|
66
65
|
function newAddressBookButton (thisAddressBook) {
|
|
67
|
-
return UI.
|
|
66
|
+
return UI.authn.newAppInstance(
|
|
68
67
|
dom,
|
|
69
68
|
{ noun: 'address book', appPathSegment: 'contactorator.timbl.com' },
|
|
70
69
|
function (ws, newBase) {
|
|
@@ -80,7 +79,7 @@ export default {
|
|
|
80
79
|
const dom = dataBrowserContext.dom
|
|
81
80
|
const kb = dataBrowserContext.session.store
|
|
82
81
|
const div = dom.createElement('div')
|
|
83
|
-
const me = authn.currentUser() // If already logged on
|
|
82
|
+
const me = UI.authn.currentUser() // If already logged on
|
|
84
83
|
|
|
85
84
|
UI.aclControl.preventBrowserDropEvents(dom) // protect drag and drop
|
|
86
85
|
|
|
@@ -97,7 +96,7 @@ export default {
|
|
|
97
96
|
|
|
98
97
|
const t = kb.findTypeURIs(subject)
|
|
99
98
|
|
|
100
|
-
let me = authn.currentUser()
|
|
99
|
+
let me = UI.authn.currentUser()
|
|
101
100
|
|
|
102
101
|
const context = {
|
|
103
102
|
target: subject,
|
|
@@ -778,7 +777,7 @@ export default {
|
|
|
778
777
|
const container = dom.createElement('div')
|
|
779
778
|
newContactButton.setAttribute('type', 'button')
|
|
780
779
|
if (!me) newContactButton.setAttribute('disabled', 'true')
|
|
781
|
-
authn.checkUser().then(webId => {
|
|
780
|
+
UI.authn.checkUser().then(webId => {
|
|
782
781
|
if (webId) {
|
|
783
782
|
me = webId
|
|
784
783
|
newContactButton.removeAttribute('disabled')
|
|
@@ -794,7 +793,7 @@ export default {
|
|
|
794
793
|
const container2 = dom.createElement('div')
|
|
795
794
|
newOrganizationButton.setAttribute('type', 'button')
|
|
796
795
|
if (!me) newOrganizationButton.setAttribute('disabled', 'true')
|
|
797
|
-
authn.checkUser().then(webId => {
|
|
796
|
+
UI.authn.checkUser().then(webId => {
|
|
798
797
|
if (webId) {
|
|
799
798
|
me = webId
|
|
800
799
|
newOrganizationButton.removeAttribute('disabled')
|
|
@@ -861,7 +860,7 @@ export default {
|
|
|
861
860
|
// Render a Group instance
|
|
862
861
|
} else if (t[ns.vcard('Group').uri]) {
|
|
863
862
|
// If we have a main address book, then render this group as a guest group within it
|
|
864
|
-
UI.
|
|
863
|
+
UI.authn
|
|
865
864
|
.findAppInstances(context, ns.vcard('AddressBook'))
|
|
866
865
|
.then(function (context) {
|
|
867
866
|
const addressBooks = context.instances
|
|
@@ -889,23 +888,12 @@ export default {
|
|
|
889
888
|
)
|
|
890
889
|
}
|
|
891
890
|
|
|
892
|
-
me = authn.currentUser()
|
|
891
|
+
me = UI.authn.currentUser()
|
|
893
892
|
if (!me) {
|
|
894
893
|
console.log(
|
|
895
894
|
'(You do not have your Web Id set. Sign in or sign up to make changes.)'
|
|
896
895
|
)
|
|
897
|
-
|
|
898
|
-
const renderContext = await UI.login.loggedInContext(context)
|
|
899
|
-
// load profile
|
|
900
|
-
me = renderContext.me
|
|
901
|
-
console.log('Logged in as ' + me)
|
|
902
|
-
renderContext.publicProfile = await solidLogicSingleton.loadProfile(me)
|
|
903
|
-
// load preferences
|
|
904
|
-
renderContext.preferencesFile = await solidLogicSingleton.loadPreferences(me)
|
|
905
|
-
} catch (err) {
|
|
906
|
-
div.appendChild(UI.widgets.errorMessageBlock(err))
|
|
907
|
-
}
|
|
908
|
-
/* UI.authn.logInLoadProfile(context).then(
|
|
896
|
+
UI.authn.logInLoadProfile(context).then(
|
|
909
897
|
context => {
|
|
910
898
|
console.log('Logged in as ' + context.me)
|
|
911
899
|
me = context.me
|
|
@@ -913,7 +901,7 @@ export default {
|
|
|
913
901
|
err => {
|
|
914
902
|
div.appendChild(UI.widgets.errorMessageBlock(err))
|
|
915
903
|
}
|
|
916
|
-
)
|
|
904
|
+
)
|
|
917
905
|
} else {
|
|
918
906
|
// console.log("(Your webid is "+ me +")")
|
|
919
907
|
}
|
package/individual.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as UI from 'solid-ui'
|
|
2
|
-
import { store, authn } from 'solid-logic'
|
|
3
2
|
import { renderMugshotGallery } from './mugshotGallery'
|
|
4
3
|
import { renderWebIdControl, renderPublicIdControl } from './webidControl'
|
|
5
4
|
import { renderGroupMemberships } from './groupMembershipControl.js'
|
|
@@ -8,6 +7,7 @@ import VCARD_ONTOLOGY_TEXT from './lib/vcard.js'
|
|
|
8
7
|
|
|
9
8
|
const $rdf = UI.rdf
|
|
10
9
|
const ns = UI.ns
|
|
10
|
+
const kb = UI.store
|
|
11
11
|
const style = UI.style
|
|
12
12
|
|
|
13
13
|
export function loadTurtleText (kb, thing, text) {
|
|
@@ -40,35 +40,35 @@ export async function renderIndividual (dom, div, subject, dataBrowserContext) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/// ///////////////////////////
|
|
43
|
-
const t =
|
|
43
|
+
const t = kb.findTypeURIs(subject)
|
|
44
44
|
const isOrganization = !!(t[ns.vcard('Organization').uri] || t[ns.schema('Organization').uri])
|
|
45
|
-
const editable =
|
|
45
|
+
const editable = kb.updater.editable(subject.doc().uri, kb)
|
|
46
46
|
|
|
47
|
-
const individualForm =
|
|
47
|
+
const individualForm = kb.sym(
|
|
48
48
|
'https://solid.github.io/solid-panes/contact/individualForm.ttl#form1'
|
|
49
49
|
)
|
|
50
|
-
loadTurtleText(
|
|
50
|
+
loadTurtleText(kb, individualForm, textOfForms)
|
|
51
51
|
|
|
52
|
-
const orgDetailsForm =
|
|
52
|
+
const orgDetailsForm = kb.sym( // orgDetailsForm organizationForm
|
|
53
53
|
'https://solid.github.io/solid-panes/contact/individualForm.ttl#orgDetailsForm'
|
|
54
54
|
)
|
|
55
55
|
|
|
56
56
|
// Ontology metadata for this pane we bundle with the JS
|
|
57
57
|
const vcardOnt = UI.ns.vcard('Type').doc()
|
|
58
|
-
if (!
|
|
58
|
+
if (!kb.holds(undefined, undefined, undefined, vcardOnt)) {
|
|
59
59
|
// If not loaded already
|
|
60
|
-
$rdf.parse(VCARD_ONTOLOGY_TEXT,
|
|
60
|
+
$rdf.parse(VCARD_ONTOLOGY_TEXT, kb, vcardOnt.uri, 'text/turtle') // Load ontology directly
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
try {
|
|
64
|
-
await
|
|
64
|
+
await kb.fetcher.load(subject.doc())
|
|
65
65
|
} catch (err) {
|
|
66
66
|
complain('Error: Failed to load contact card: ' + err)
|
|
67
67
|
} // end of try catch on load
|
|
68
68
|
|
|
69
69
|
div.style = style.paneDivStyle || 'padding: 0.5em 1.5em 1em 1.5em;'
|
|
70
70
|
|
|
71
|
-
authn.checkUser() // kick off async operation @@@ use async version
|
|
71
|
+
UI.authn.checkUser() // kick off async operation @@@ use async version
|
|
72
72
|
|
|
73
73
|
div.appendChild(renderMugshotGallery(dom, subject))
|
|
74
74
|
|
|
@@ -146,7 +146,7 @@ callback) {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
if (hits == 1) { // Maybe require green confirmation button be clicked?
|
|
149
|
-
console.log(" auto complete elimination: \""
|
|
149
|
+
console.log(" auto complete elimination: \"".concat(filter, "\" -> \"").concat(pickedName, "\""));
|
|
150
150
|
gotIt(kb.sym(pick), pickedName); // uri, name
|
|
151
151
|
}
|
|
152
152
|
}
|
|
@@ -174,7 +174,7 @@ callback) {
|
|
|
174
174
|
switch (_a.label) {
|
|
175
175
|
case 0:
|
|
176
176
|
if (inputEventHandlerLock) {
|
|
177
|
-
console.log("Ignoring \""
|
|
177
|
+
console.log("Ignoring \"".concat(searchInput.value, "\" because of lock "));
|
|
178
178
|
return [2 /*return*/];
|
|
179
179
|
}
|
|
180
180
|
inputEventHandlerLock = true;
|
|
@@ -222,7 +222,7 @@ callback) {
|
|
|
222
222
|
numberOfRows = slimmed.length; // stretch if it means we get all items
|
|
223
223
|
}
|
|
224
224
|
allDisplayed = loadedEnough && slimmed.length <= numberOfRows;
|
|
225
|
-
console.log(" Filter:\""
|
|
225
|
+
console.log(" Filter:\"".concat(filter, "\" bindings: ").concat(bindings.length, ", slimmed to ").concat(slimmed.length, "; rows: ").concat(numberOfRows, ", Enough? ").concat(loadedEnough, ", All displayed? ").concat(allDisplayed));
|
|
226
226
|
slimmed.slice(0, numberOfRows).forEach(function (binding) {
|
|
227
227
|
var row = table.appendChild(dom.createElement('tr'));
|
|
228
228
|
solid_ui_1.style.setStyle(row, 'autocompleteRowStyle');
|
|
@@ -256,7 +256,7 @@ callback) {
|
|
|
256
256
|
*/
|
|
257
257
|
function sparqlForSearch(name, theType) {
|
|
258
258
|
var clean = name.replace(/\W/g, ''); // Remove non alphanum so as to protect regexp
|
|
259
|
-
var sparql = "select distinct ?subject, ?name where {\n ?subject a <"
|
|
259
|
+
var sparql = "select distinct ?subject, ?name where {\n ?subject a <".concat(theType.uri, ">; rdfs:label ?name\n FILTER regex(?name, \"").concat(clean, "\", \"i\")\n } LIMIT ").concat(publicData_1.AUTOCOMPLETE_LIMIT);
|
|
260
260
|
return sparql;
|
|
261
261
|
}
|
|
262
262
|
var queryParams, OrgClass, candidatesLoaded, runningTimeout, inputEventHandlerLock, allDisplayed, lastFilter, numberOfRows, div, foundName, foundObject, table, head, cell, searchInput, searchInputStyle;
|
package/lib/publicData.js
CHANGED
|
@@ -121,7 +121,7 @@ function filterByLanguage(bindings, languagePrefs) {
|
|
|
121
121
|
sortMe.reverse(); // best at the top
|
|
122
122
|
slimmed.push(sortMe[0][1]);
|
|
123
123
|
} // map u
|
|
124
|
-
console.log(" Filter by language: "
|
|
124
|
+
console.log(" Filter by language: ".concat(bindings.length, " -> ").concat(slimmed.length));
|
|
125
125
|
return slimmed;
|
|
126
126
|
}
|
|
127
127
|
exports.filterByLanguage = filterByLanguage;
|
|
@@ -144,8 +144,8 @@ exports.predMap = {
|
|
|
144
144
|
};
|
|
145
145
|
function loadFromBindings(kb, solidSubject, bindings, doc) {
|
|
146
146
|
var results = {};
|
|
147
|
-
console.log("loadFromBindings: subject: "
|
|
148
|
-
console.log(" doc: "
|
|
147
|
+
console.log("loadFromBindings: subject: ".concat(solidSubject));
|
|
148
|
+
console.log(" doc: ".concat(doc));
|
|
149
149
|
bindings.forEach(function (binding) {
|
|
150
150
|
for (var key in binding) {
|
|
151
151
|
var result = binding[key];
|
|
@@ -156,7 +156,7 @@ function loadFromBindings(kb, solidSubject, bindings, doc) {
|
|
|
156
156
|
});
|
|
157
157
|
var _loop_1 = function (key) {
|
|
158
158
|
var values = results[key];
|
|
159
|
-
console.log(" results "
|
|
159
|
+
console.log(" results ".concat(key, " -> ").concat(values));
|
|
160
160
|
values.forEach(function (combined) {
|
|
161
161
|
var result = JSON.parse(combined);
|
|
162
162
|
var type = result.type, value = result.value;
|
|
@@ -168,7 +168,7 @@ function loadFromBindings(kb, solidSubject, bindings, doc) {
|
|
|
168
168
|
obj = new rdflib_1.Literal(value, result.language, result.datatype);
|
|
169
169
|
}
|
|
170
170
|
else {
|
|
171
|
-
throw new Error("loadFromBindings: unexpected type: "
|
|
171
|
+
throw new Error("loadFromBindings: unexpected type: ".concat(type));
|
|
172
172
|
}
|
|
173
173
|
if (key == 'type') {
|
|
174
174
|
if (exports.wikidataClassMap[value]) {
|
|
@@ -192,7 +192,7 @@ function loadFromBindings(kb, solidSubject, bindings, doc) {
|
|
|
192
192
|
else if (exports.predMap[key]) {
|
|
193
193
|
var pred = exports.predMap[key] || solid_ui_1.ns.schema(key); // fallback to just using schema.org
|
|
194
194
|
kb.add(solidSubject, pred, obj, doc); // @@ deal with non-string and objects
|
|
195
|
-
console.log(" public data "
|
|
195
|
+
console.log(" public data ".concat(pred, " ").concat(obj, "."));
|
|
196
196
|
}
|
|
197
197
|
});
|
|
198
198
|
};
|
|
@@ -334,7 +334,7 @@ function loadPublicDataThing(kb, subject, publicDataID) {
|
|
|
334
334
|
case 1:
|
|
335
335
|
if (!publicDataID.uri.match(/^https?:\/\/www\.wikidata\.org\/entity\/.*/)) return [3 /*break*/, 3];
|
|
336
336
|
QId = publicDataID.uri.split('/')[4];
|
|
337
|
-
dataURI = "http://www.wikidata.org/wiki/Special:EntityData/"
|
|
337
|
+
dataURI = "http://www.wikidata.org/wiki/Special:EntityData/".concat(QId, ".ttl");
|
|
338
338
|
// In fact loading the data URI gives much to much irrelevant data, from wikidata.
|
|
339
339
|
return [4 /*yield*/, getWikidataDetails(kb, subject, publicDataID)
|
|
340
340
|
// await getWikidataLocation(kb, subject, publicDataID) -- should get that in the details query now
|
|
@@ -416,7 +416,7 @@ function getDbpediaDetails(kb, solidSubject, publicDataID) {
|
|
|
416
416
|
return __generator(this, function (_a) {
|
|
417
417
|
switch (_a.label) {
|
|
418
418
|
case 0:
|
|
419
|
-
sparql = "select distinct ?city, ?state, ?country, ?homepage, ?logo, ?lat, ?long, WHERE {\n OPTIONAL { <"
|
|
419
|
+
sparql = "select distinct ?city, ?state, ?country, ?homepage, ?logo, ?lat, ?long, WHERE {\n OPTIONAL { <".concat(publicDataID, "> <http://dbpedia.org/ontology/city> ?city }\n OPTIONAL { ").concat(publicDataID, " <http://dbpedia.org/ontology/state> ?state }\n OPTIONAL { ").concat(publicDataID, " <http://dbpedia.org/ontology/country> ?country }\n OPTIONAL { ").concat(publicDataID, " foaf:homepage ?homepage }\n OPTIONAL { ").concat(publicDataID, " foaf:lat ?lat; foaf:long ?long }\n OPTIONAL { ").concat(publicDataID, " <http://dbpedia.org/ontology/country> ?country }\n }");
|
|
420
420
|
predMap = {
|
|
421
421
|
city: solid_ui_1.ns.vcard('locality'),
|
|
422
422
|
state: solid_ui_1.ns.vcard('region'),
|
package/mintNewAddressBook.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { solidLogicSingleton, aclLogic } from 'solid-logic'
|
|
1
|
+
const UI = require('solid-ui')
|
|
3
2
|
|
|
4
3
|
// const mime = require('mime-types')
|
|
5
4
|
// const toolsPane0 = require('./toolsPane')
|
|
@@ -13,23 +12,7 @@ const $rdf = UI.rdf
|
|
|
13
12
|
|
|
14
13
|
export function mintNewAddressBook (dataBrowserContext, context) {
|
|
15
14
|
return new Promise(function (resolve, reject) {
|
|
16
|
-
|
|
17
|
-
let loggedInContext
|
|
18
|
-
try {
|
|
19
|
-
loggedInContext = await UI.login.loggedInContext(context)
|
|
20
|
-
// load profile
|
|
21
|
-
loggedInContext.publicProfile = await solidLogicSingleton.loadProfile(loggedInContext.me)
|
|
22
|
-
// load preferences
|
|
23
|
-
loggedInContext.preferencesFile = await solidLogicSingleton.loadPreferences(loggedInContext.me)
|
|
24
|
-
} catch (err) {
|
|
25
|
-
const error = `Could not login and load profile and preferences: ${err}`
|
|
26
|
-
console.log(error)
|
|
27
|
-
context.div.appendChild(UI.widgets.errorMessageBlock(error))
|
|
28
|
-
}
|
|
29
|
-
return loggedInContext
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
loadPreference(context).then(
|
|
15
|
+
UI.authn.logInLoadProfile(context).then(
|
|
33
16
|
context => {
|
|
34
17
|
// 20180713
|
|
35
18
|
console.log('Logged in as ' + context.me)
|
|
@@ -137,7 +120,7 @@ export function mintNewAddressBook (dataBrowserContext, context) {
|
|
|
137
120
|
return reject(new Error('Error writing new file ' + task.to))
|
|
138
121
|
}
|
|
139
122
|
|
|
140
|
-
|
|
123
|
+
UI.authn
|
|
141
124
|
.setACLUserPublic(dest, me, aclOptions)
|
|
142
125
|
.then(() => doNextTask())
|
|
143
126
|
.catch(err => {
|
package/mugshotGallery.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as UI from 'solid-ui'
|
|
2
|
-
import { store } from 'solid-logic'
|
|
3
2
|
import * as mime from 'mime-types'
|
|
4
3
|
|
|
5
4
|
const $rdf = UI.rdf
|
|
6
5
|
const ns = UI.ns
|
|
7
6
|
const utils = UI.utils
|
|
7
|
+
const kb = UI.store
|
|
8
8
|
|
|
9
9
|
/* Mugshot Gallery
|
|
10
10
|
*
|
|
@@ -23,9 +23,9 @@ export function renderMugshotGallery (dom, subject) {
|
|
|
23
23
|
]
|
|
24
24
|
try {
|
|
25
25
|
if (remove) {
|
|
26
|
-
await
|
|
26
|
+
await kb.updater.update(link, [])
|
|
27
27
|
} else {
|
|
28
|
-
await
|
|
28
|
+
await kb.updater.update([], link)
|
|
29
29
|
}
|
|
30
30
|
} catch (err) {
|
|
31
31
|
const msg = ' Write back image link FAIL ' + pic + ', Error: ' + err
|
|
@@ -35,16 +35,16 @@ export function renderMugshotGallery (dom, subject) {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
function handleDroppedThing (thing) {
|
|
38
|
-
|
|
38
|
+
kb.fetcher.nowOrWhenFetched(thing.doc(), function (ok, mess) {
|
|
39
39
|
if (!ok) {
|
|
40
40
|
console.log('Error looking up dropped thing ' + thing + ': ' + mess)
|
|
41
41
|
} else {
|
|
42
|
-
const types =
|
|
42
|
+
const types = kb.findTypeURIs(thing)
|
|
43
43
|
for (const ty in types) {
|
|
44
44
|
console.log(' drop object type includes: ' + ty) // @@ Allow email addresses and phone numbers to be dropped?
|
|
45
45
|
}
|
|
46
46
|
console.log('Default: assume web page ' + thing) // icon was: UI.icons.iconBase + 'noun_25830.svg'
|
|
47
|
-
|
|
47
|
+
kb.add(subject, ns.wf('attachment'), thing, subject.doc())
|
|
48
48
|
// @@ refresh UI
|
|
49
49
|
}
|
|
50
50
|
})
|
|
@@ -70,8 +70,8 @@ export function renderMugshotGallery (dom, subject) {
|
|
|
70
70
|
let n, pic
|
|
71
71
|
for (n = 0; ; n++) {
|
|
72
72
|
// Check filename is not used or invent new one
|
|
73
|
-
pic =
|
|
74
|
-
if (!
|
|
73
|
+
pic = kb.sym(subject.dir().uri + filename)
|
|
74
|
+
if (!kb.holds(subject, ns.vcard('hasPhoto'), pic)) {
|
|
75
75
|
break
|
|
76
76
|
}
|
|
77
77
|
filename = prefix + n + '.' + extension
|
|
@@ -84,7 +84,7 @@ export function renderMugshotGallery (dom, subject) {
|
|
|
84
84
|
' to ' +
|
|
85
85
|
pic
|
|
86
86
|
)
|
|
87
|
-
|
|
87
|
+
kb.fetcher
|
|
88
88
|
.webOperation('PUT', pic.uri, {
|
|
89
89
|
data: data,
|
|
90
90
|
contentType: contentType
|
|
@@ -95,8 +95,8 @@ export function renderMugshotGallery (dom, subject) {
|
|
|
95
95
|
return
|
|
96
96
|
}
|
|
97
97
|
console.log(' Upload: put OK: ' + pic)
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
kb.add(subject, predicate, pic, subject.doc())
|
|
99
|
+
kb.fetcher
|
|
100
100
|
.putBack(subject.doc(), { contentType: 'text/turtle' })
|
|
101
101
|
.then(
|
|
102
102
|
function (_response) {
|
|
@@ -126,7 +126,7 @@ export function renderMugshotGallery (dom, subject) {
|
|
|
126
126
|
}
|
|
127
127
|
const options = { withCredentials: false, credentials: 'omit' }
|
|
128
128
|
try {
|
|
129
|
-
var result = await
|
|
129
|
+
var result = await kb.fetcher.webOperation('GET', thing.uri, options)
|
|
130
130
|
} catch (err) {
|
|
131
131
|
complain(
|
|
132
132
|
`Gallery: fetch error trying to read picture ${thing} data: ${err}`
|
|
@@ -205,7 +205,7 @@ export function renderMugshotGallery (dom, subject) {
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
function syncMugshots () {
|
|
208
|
-
let images =
|
|
208
|
+
let images = kb.each(subject, ns.vcard('hasPhoto')) // Priviledge vcard ones
|
|
209
209
|
images.sort() // arbitrary consistency
|
|
210
210
|
images = images.slice(0, 5) // max number for the space
|
|
211
211
|
if (images.length === 0) {
|
|
@@ -220,7 +220,7 @@ export function renderMugshotGallery (dom, subject) {
|
|
|
220
220
|
|
|
221
221
|
// Good URI for a Camera picture
|
|
222
222
|
function getImageDoc () {
|
|
223
|
-
const imageDoc =
|
|
223
|
+
const imageDoc = kb.sym(
|
|
224
224
|
subject.dir().uri + 'Image_' + Date.now() + '.png'
|
|
225
225
|
)
|
|
226
226
|
return imageDoc
|
|
@@ -240,7 +240,7 @@ export function renderMugshotGallery (dom, subject) {
|
|
|
240
240
|
'Drag here to delete'
|
|
241
241
|
)
|
|
242
242
|
async function droppedURIHandler (uris) {
|
|
243
|
-
const images =
|
|
243
|
+
const images = kb
|
|
244
244
|
.each(subject, ns.vcard('hasPhoto'))
|
|
245
245
|
.map(x => x.uri)
|
|
246
246
|
for (const uri of uris) {
|
|
@@ -250,10 +250,10 @@ export function renderMugshotGallery (dom, subject) {
|
|
|
250
250
|
}
|
|
251
251
|
if (confirm(`Permanently DELETE image ${uri} completely?`)) {
|
|
252
252
|
console.log('Unlinking image file ' + uri)
|
|
253
|
-
await linkToPicture(subject,
|
|
253
|
+
await linkToPicture(subject, kb.sym(uri), true)
|
|
254
254
|
try {
|
|
255
255
|
console.log('Deleting image file ' + uri)
|
|
256
|
-
await
|
|
256
|
+
await kb.fetcher.webOperation('DELETE', uri)
|
|
257
257
|
} catch (err) {
|
|
258
258
|
alert('Unable to delete picture! ' + err)
|
|
259
259
|
}
|
|
@@ -273,7 +273,7 @@ export function renderMugshotGallery (dom, subject) {
|
|
|
273
273
|
const right = row.appendChild(dom.createElement('td'))
|
|
274
274
|
|
|
275
275
|
left.appendChild(
|
|
276
|
-
UI.media.cameraButton(dom,
|
|
276
|
+
UI.media.cameraButton(dom, kb, getImageDoc, tookPicture)
|
|
277
277
|
) // 20190812
|
|
278
278
|
try {
|
|
279
279
|
middle.appendChild(
|
|
@@ -288,7 +288,7 @@ export function renderMugshotGallery (dom, subject) {
|
|
|
288
288
|
|
|
289
289
|
// Body of renderMugshotGallery
|
|
290
290
|
|
|
291
|
-
const editable =
|
|
291
|
+
const editable = kb.updater.editable(subject.doc().uri, kb)
|
|
292
292
|
const galleryDiv = dom.createElement('div')
|
|
293
293
|
const mugshotDiv = galleryDiv.appendChild(dom.createElement('div'))
|
|
294
294
|
const placeholder = elementForImage()
|
package/package.json
CHANGED
package/toolsPane.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
/* global confirm, $rdf */
|
|
4
4
|
|
|
5
5
|
import * as UI from 'solid-ui'
|
|
6
|
-
import { store } from 'solid-logic'
|
|
7
6
|
import { saveNewGroup, addPersonToGroup } from './contactLogic'
|
|
8
7
|
export function toolsPane (
|
|
9
8
|
selectAllGroups,
|
|
@@ -14,6 +13,7 @@ export function toolsPane (
|
|
|
14
13
|
me
|
|
15
14
|
) {
|
|
16
15
|
const dom = dataBrowserContext.dom
|
|
16
|
+
const kb = UI.store
|
|
17
17
|
const ns = UI.ns
|
|
18
18
|
const VCARD = ns.vcard
|
|
19
19
|
|
|
@@ -59,7 +59,7 @@ export function toolsPane (
|
|
|
59
59
|
book.dir(),
|
|
60
60
|
dataBrowserContext,
|
|
61
61
|
'book',
|
|
62
|
-
|
|
62
|
+
kb,
|
|
63
63
|
function (ok, body) {
|
|
64
64
|
if (!ok) box.innerHTML = 'ACL control box Failed: ' + body
|
|
65
65
|
}
|
|
@@ -68,7 +68,7 @@ export function toolsPane (
|
|
|
68
68
|
|
|
69
69
|
//
|
|
70
70
|
try {
|
|
71
|
-
await UI.
|
|
71
|
+
await UI.authn.registrationControl(context, book, ns.vcard('AddressBook'))
|
|
72
72
|
} catch (e) {
|
|
73
73
|
UI.widgets.complain(context, 'registrationControl: ' + e)
|
|
74
74
|
}
|
|
@@ -82,9 +82,9 @@ export function toolsPane (
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
function stats () {
|
|
85
|
-
const totalCards =
|
|
85
|
+
const totalCards = kb.each(undefined, VCARD('inAddressBook'), book).length
|
|
86
86
|
log('' + totalCards + ' cards loaded. ')
|
|
87
|
-
const groups =
|
|
87
|
+
const groups = kb.each(book, VCARD('includesGroup'))
|
|
88
88
|
log('' + groups.length + ' total groups. ')
|
|
89
89
|
const gg = []
|
|
90
90
|
for (const g in selectedGroups) {
|
|
@@ -95,9 +95,9 @@ export function toolsPane (
|
|
|
95
95
|
|
|
96
96
|
async function loadIndexHandler (_event) {
|
|
97
97
|
loadIndexButton.setAttribute('style', 'background-color: #ffc;')
|
|
98
|
-
const nameEmailIndex =
|
|
98
|
+
const nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex'))
|
|
99
99
|
try {
|
|
100
|
-
await
|
|
100
|
+
await kb.fetcher.load(nameEmailIndex)
|
|
101
101
|
} catch (e) {
|
|
102
102
|
loadIndexButton.setAttribute('style', 'background-color: #fcc;')
|
|
103
103
|
log('Error: People index has NOT been loaded' + e + '\n')
|
|
@@ -135,8 +135,8 @@ export function toolsPane (
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
for (let i = 0; i < gg.length; i++) {
|
|
138
|
-
const g =
|
|
139
|
-
const a =
|
|
138
|
+
const g = kb.sym(gg[i])
|
|
139
|
+
const a = kb.each(g, ns.vcard('hasMember'))
|
|
140
140
|
log(UI.utils.label(g) + ': ' + a.length + ' members')
|
|
141
141
|
for (let j = 0; j < a.length; j++) {
|
|
142
142
|
const card = a[j]
|
|
@@ -157,10 +157,10 @@ export function toolsPane (
|
|
|
157
157
|
const stats = {} // global god context
|
|
158
158
|
|
|
159
159
|
stats.book = book
|
|
160
|
-
stats.nameEmailIndex =
|
|
160
|
+
stats.nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex'))
|
|
161
161
|
log('Loading name index...')
|
|
162
162
|
|
|
163
|
-
store.fetcher.nowOrWhenFetched(
|
|
163
|
+
UI.store.fetcher.nowOrWhenFetched(
|
|
164
164
|
stats.nameEmailIndex,
|
|
165
165
|
undefined,
|
|
166
166
|
function (_ok, _message) {
|
|
@@ -235,8 +235,8 @@ export function toolsPane (
|
|
|
235
235
|
} // erase one
|
|
236
236
|
*/
|
|
237
237
|
// Check actual records to see which are exact matches - slow
|
|
238
|
-
stats.nameDupLog =
|
|
239
|
-
stats.exactDupLog =
|
|
238
|
+
stats.nameDupLog = kb.sym(book.dir().uri + 'dedup-nameDupLog.ttl')
|
|
239
|
+
stats.exactDupLog = kb.sym(book.dir().uri + 'dedup-exactDupLog.ttl')
|
|
240
240
|
/*
|
|
241
241
|
function checkOne (card) {
|
|
242
242
|
return new Promise(function (resolve, reject) {
|
|
@@ -322,7 +322,7 @@ export function toolsPane (
|
|
|
322
322
|
|
|
323
323
|
function checkOneNameless (card) {
|
|
324
324
|
return new Promise(function (resolve) {
|
|
325
|
-
|
|
325
|
+
kb.fetcher
|
|
326
326
|
.load(card)
|
|
327
327
|
.then(function (_xhr) {
|
|
328
328
|
log(' Nameless check ' + card)
|
|
@@ -331,7 +331,7 @@ export function toolsPane (
|
|
|
331
331
|
exclude[ns.dc('created').uri] = true
|
|
332
332
|
exclude[ns.dc('modified').uri] = true
|
|
333
333
|
function filtered (x) {
|
|
334
|
-
return
|
|
334
|
+
return kb
|
|
335
335
|
.statementsMatching(null, null, null, x.doc())
|
|
336
336
|
.filter(function (st) {
|
|
337
337
|
return !exclude[st.predicate.uri]
|
|
@@ -350,14 +350,14 @@ export function toolsPane (
|
|
|
350
350
|
// Cheat: serialize and compare
|
|
351
351
|
// var cardText = $rdf.serialize(card.doc(), kb, card.doc().uri, 'text/turtle')
|
|
352
352
|
// var otherText = $rdf.serialize(other.doc(), kb, other.doc().uri, 'text/turtle')
|
|
353
|
-
const cardText = new $rdf.Serializer(
|
|
353
|
+
const cardText = new $rdf.Serializer(kb)
|
|
354
354
|
.setBase(card.doc().uri)
|
|
355
355
|
.statementsToN3(desc)
|
|
356
356
|
const other = stats.nameLessIndex[cardText]
|
|
357
357
|
if (other) {
|
|
358
358
|
log(' Matches with ' + other)
|
|
359
|
-
const cardGroups =
|
|
360
|
-
const otherGroups =
|
|
359
|
+
const cardGroups = kb.each(null, ns.vcard('hasMember'), card)
|
|
360
|
+
const otherGroups = kb.each(null, ns.vcard('hasMember'), other)
|
|
361
361
|
for (let j = 0; j < cardGroups.length; j++) {
|
|
362
362
|
let found = false
|
|
363
363
|
for (let k = 0; k < otherGroups.length; k++) {
|
|
@@ -431,7 +431,7 @@ export function toolsPane (
|
|
|
431
431
|
for (let i = 0; i < stats.uniques.length; i++) {
|
|
432
432
|
stats.uniquesSet[stats.uniques[i].uri] = true
|
|
433
433
|
}
|
|
434
|
-
stats.groupMembers =
|
|
434
|
+
stats.groupMembers = kb
|
|
435
435
|
.statementsMatching(null, ns.vcard('hasMember'))
|
|
436
436
|
.map(st => st.object)
|
|
437
437
|
log(' Naive group members ' + stats.groupMembers.length)
|
|
@@ -472,13 +472,13 @@ export function toolsPane (
|
|
|
472
472
|
|
|
473
473
|
function scanForDuplicates () {
|
|
474
474
|
return new Promise(function (resolve) {
|
|
475
|
-
stats.cards =
|
|
475
|
+
stats.cards = kb.each(undefined, VCARD('inAddressBook'), stats.book)
|
|
476
476
|
log('' + stats.cards.length + ' total cards')
|
|
477
477
|
|
|
478
478
|
let c, card, name
|
|
479
479
|
for (c = 0; c < stats.cards.length; c++) {
|
|
480
480
|
card = stats.cards[c]
|
|
481
|
-
name =
|
|
481
|
+
name = kb.anyValue(card, ns.vcard('fn'))
|
|
482
482
|
if (!name) {
|
|
483
483
|
stats.nameless.push(card)
|
|
484
484
|
continue
|
|
@@ -532,18 +532,18 @@ export function toolsPane (
|
|
|
532
532
|
|
|
533
533
|
return Promise.resolve()
|
|
534
534
|
.then(() => {
|
|
535
|
-
cleanPeople =
|
|
535
|
+
cleanPeople = kb.sym(stats.book.dir().uri + 'clean-people.ttl')
|
|
536
536
|
let sts = []
|
|
537
537
|
for (let i = 0; i < stats.uniques.length; i++) {
|
|
538
538
|
sts = sts.concat(
|
|
539
|
-
|
|
539
|
+
kb.connectedStatements(stats.uniques[i], stats.nameEmailIndex)
|
|
540
540
|
)
|
|
541
541
|
}
|
|
542
|
-
const sz = new $rdf.Serializer(
|
|
542
|
+
const sz = new $rdf.Serializer(kb).setBase(stats.nameEmailIndex.uri)
|
|
543
543
|
log('Serializing index of uniques...')
|
|
544
544
|
const data = sz.statementsToN3(sts)
|
|
545
545
|
|
|
546
|
-
return
|
|
546
|
+
return kb.fetcher.webOperation('PUT', cleanPeople, {
|
|
547
547
|
data: data,
|
|
548
548
|
contentType: 'text/turtle'
|
|
549
549
|
})
|
|
@@ -563,18 +563,18 @@ export function toolsPane (
|
|
|
563
563
|
return Promise.resolve()
|
|
564
564
|
.then(() => {
|
|
565
565
|
const s = g.uri.replace('/Group/', '/NewGroup/')
|
|
566
|
-
cleanGroup =
|
|
566
|
+
cleanGroup = kb.sym(s)
|
|
567
567
|
let sts = []
|
|
568
568
|
for (let i = 0; i < stats.uniques.length; i++) {
|
|
569
569
|
sts = sts.concat(
|
|
570
|
-
|
|
570
|
+
kb.connectedStatements(stats.uniques[i], g.doc())
|
|
571
571
|
)
|
|
572
572
|
}
|
|
573
|
-
const sz = new $rdf.Serializer(
|
|
573
|
+
const sz = new $rdf.Serializer(kb).setBase(g.uri)
|
|
574
574
|
log(' Regenerating group of uniques...' + cleanGroup)
|
|
575
575
|
const data = sz.statementsToN3(sts)
|
|
576
576
|
|
|
577
|
-
return
|
|
577
|
+
return kb.fetcher.webOperation('PUT', cleanGroup, { data })
|
|
578
578
|
})
|
|
579
579
|
.then(() => {
|
|
580
580
|
log(' Done uniques group ' + cleanGroup)
|
|
@@ -595,9 +595,9 @@ export function toolsPane (
|
|
|
595
595
|
if (stats.book) {
|
|
596
596
|
const books = [stats.book]
|
|
597
597
|
books.forEach(function (book) {
|
|
598
|
-
const gs = book ?
|
|
598
|
+
const gs = book ? kb.each(book, ns.vcard('includesGroup')) : []
|
|
599
599
|
const gs2 = gs.map(function (g) {
|
|
600
|
-
return [book,
|
|
600
|
+
return [book, kb.any(g, ns.vcard('fn')), g]
|
|
601
601
|
})
|
|
602
602
|
groups = groups.concat(gs2)
|
|
603
603
|
})
|
|
@@ -609,7 +609,7 @@ export function toolsPane (
|
|
|
609
609
|
|
|
610
610
|
stats.groupObjects = groups.map(gstr => gstr[2])
|
|
611
611
|
log('Loading ' + stats.groupObjects.length + ' groups... ')
|
|
612
|
-
|
|
612
|
+
kb.fetcher
|
|
613
613
|
.load(stats.groupObjects)
|
|
614
614
|
.then(scanForDuplicates)
|
|
615
615
|
.then(checkGroupMembers)
|
|
@@ -647,34 +647,34 @@ export function toolsPane (
|
|
|
647
647
|
}
|
|
648
648
|
|
|
649
649
|
async function getGroupless (book) {
|
|
650
|
-
const groupIndex =
|
|
651
|
-
const nameEmailIndex =
|
|
650
|
+
const groupIndex = kb.any(book, ns.vcard('groupIndex'))
|
|
651
|
+
const nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex'))
|
|
652
652
|
try {
|
|
653
|
-
await
|
|
654
|
-
const groups =
|
|
655
|
-
await
|
|
653
|
+
await kb.fetcher.load([nameEmailIndex, groupIndex])
|
|
654
|
+
const groups = kb.each(book, ns.vcard('includesGroup'))
|
|
655
|
+
await kb.fetcher.load(groups)
|
|
656
656
|
} catch (e) {
|
|
657
657
|
complain('Error loading stuff:' + e)
|
|
658
658
|
}
|
|
659
659
|
|
|
660
660
|
const reverseIndex = {}
|
|
661
661
|
const groupless = []
|
|
662
|
-
const groups =
|
|
662
|
+
const groups = kb.each(book, VCARD('includesGroup'))
|
|
663
663
|
|
|
664
664
|
log('' + groups.length + ' total groups. ')
|
|
665
665
|
|
|
666
666
|
for (let i = 0; i < groups.length; i++) {
|
|
667
667
|
const g = groups[i]
|
|
668
|
-
const a =
|
|
668
|
+
const a = kb.each(g, ns.vcard('hasMember'))
|
|
669
669
|
log(UI.utils.label(g) + ': ' + a.length + ' members')
|
|
670
670
|
for (let j = 0; j < a.length; j++) {
|
|
671
|
-
|
|
671
|
+
kb.allAliases(a[j]).forEach(function (y) {
|
|
672
672
|
reverseIndex[y.uri] = g
|
|
673
673
|
})
|
|
674
674
|
}
|
|
675
675
|
}
|
|
676
676
|
|
|
677
|
-
const cards =
|
|
677
|
+
const cards = kb.each(undefined, VCARD('inAddressBook'), book)
|
|
678
678
|
log('' + cards.length + ' total cards')
|
|
679
679
|
for (let c = 0; c < cards.length; c++) {
|
|
680
680
|
if (!reverseIndex[cards[c].uri]) {
|
|
@@ -697,9 +697,9 @@ export function toolsPane (
|
|
|
697
697
|
return
|
|
698
698
|
}
|
|
699
699
|
|
|
700
|
-
const nameEmailIndex =
|
|
700
|
+
const nameEmailIndex = kb.any(book, ns.vcard('nameEmailIndex'))
|
|
701
701
|
try {
|
|
702
|
-
await
|
|
702
|
+
await kb.fetcher.load(nameEmailIndex)
|
|
703
703
|
} catch (e) {
|
|
704
704
|
complain(e)
|
|
705
705
|
}
|
package/webidControl.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Render a control to record the webids we have for this agent
|
|
2
2
|
/* eslint-disable multiline-ternary */
|
|
3
3
|
import * as UI from 'solid-ui'
|
|
4
|
-
import { store } from 'solid-logic'
|
|
5
4
|
import { updateMany } from './contactLogic'
|
|
6
5
|
// import { renderAutoComplete } from './lib/autocompletePicker' // dbpediaParameters
|
|
7
6
|
import { renderAutocompleteControl } from './lib/autocompleteBar'
|
|
@@ -11,6 +10,7 @@ const $rdf = UI.rdf
|
|
|
11
10
|
const ns = UI.ns
|
|
12
11
|
const widgets = UI.widgets
|
|
13
12
|
const utils = UI.utils
|
|
13
|
+
const kb = UI.store
|
|
14
14
|
const style = UI.style
|
|
15
15
|
|
|
16
16
|
const wikidataClasses = widgets.publicData.wikidataClasses // @@ move to solid-logic
|
|
@@ -134,8 +134,8 @@ export function vcardWebIDs (kb, person, urlType) {
|
|
|
134
134
|
|
|
135
135
|
export function isOrganization (agent) {
|
|
136
136
|
const doc = agent.doc()
|
|
137
|
-
return
|
|
138
|
-
|
|
137
|
+
return kb.holds(agent, ns.rdf('type'), ns.vcard('Organization'), doc) ||
|
|
138
|
+
kb.holds(agent, ns.rdf('type'), ns.schema('Organization'), doc)
|
|
139
139
|
}
|
|
140
140
|
/// ////////////////////////////////////////////////////////////// UI
|
|
141
141
|
|
|
@@ -163,11 +163,11 @@ export async function renderWebIdControl (person, dataBrowserContext) {
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
export async function renderPublicIdControl (person, dataBrowserContext) {
|
|
166
|
-
let orgClass =
|
|
166
|
+
let orgClass = kb.sym('http://www.wikidata.org/wiki/Q43229')
|
|
167
167
|
let orgClassId = 'Organization'
|
|
168
168
|
for (const classId in wikidataClasses) {
|
|
169
|
-
if (
|
|
170
|
-
orgClass =
|
|
169
|
+
if (kb.holds(person, ns.rdf('type'), ns.schema(classId), person.doc())) {
|
|
170
|
+
orgClass = kb.sym(wikidataClasses[classId])
|
|
171
171
|
orgClassId = classId
|
|
172
172
|
console.log(` renderPublicIdControl bingo: ${classId} -> ${orgClass}`)
|
|
173
173
|
}
|
|
@@ -266,14 +266,14 @@ export async function renderIdControl (person, dataBrowserContext, options) {
|
|
|
266
266
|
} // renderPersona
|
|
267
267
|
|
|
268
268
|
async function refreshWebIDTable () {
|
|
269
|
-
const personas = getPersonas(
|
|
269
|
+
const personas = getPersonas(kb, person)
|
|
270
270
|
console.log('WebId personas: ' + person + ' -> ' + personas.map(p => p.uri).join(',\n '))
|
|
271
271
|
prompt.style.display = personas.length ? 'none' : ''
|
|
272
|
-
utils.syncTableToArrayReOrdered(profileArea, personas, persona => renderPersona(dom, persona,
|
|
272
|
+
utils.syncTableToArrayReOrdered(profileArea, personas, persona => renderPersona(dom, persona, kb))
|
|
273
273
|
}
|
|
274
274
|
async function addOneIdAndRefresh (person, webid) {
|
|
275
275
|
try {
|
|
276
|
-
await addWebIDToContacts(person, webid, options.urlType,
|
|
276
|
+
await addWebIDToContacts(person, webid, options.urlType, kb)
|
|
277
277
|
} catch (err) {
|
|
278
278
|
div.appendChild(widgets.errorMessageBlock(dom, `Error adding Id ${webid} to ${person}: ${err}`))
|
|
279
279
|
}
|
|
@@ -282,11 +282,11 @@ export async function renderIdControl (person, dataBrowserContext, options) {
|
|
|
282
282
|
|
|
283
283
|
const { dom } = dataBrowserContext
|
|
284
284
|
options = options || {}
|
|
285
|
-
options.editable =
|
|
285
|
+
options.editable = kb.updater.editable(person.doc().uri, kb)
|
|
286
286
|
const div = dom.createElement('div')
|
|
287
287
|
div.style = 'border-radius:0.3em; border: 0.1em solid #888;' // padding: 0.8em;
|
|
288
288
|
|
|
289
|
-
if (getPersonas(
|
|
289
|
+
if (getPersonas(kb, person).length === 0 && !options.editable) {
|
|
290
290
|
div.style.display = 'none'
|
|
291
291
|
return div // No point listing an empty list you can't change
|
|
292
292
|
}
|