Skip to content

Commit 0533393

Browse files
authored
Merge pull request SolidOS#483 from solid/tabs-bug-fix
Tested locally and works
2 parents 9bf8c54 + f604a92 commit 0533393

14 files changed

Lines changed: 812 additions & 797 deletions

File tree

package-lock.json

Lines changed: 625 additions & 661 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/acl/access-groups.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* @packageDocumentation
55
*/
66

7-
import { NamedNode, sym, LiveStore } from 'rdflib'
7+
import { NamedNode, sym, Store } from 'rdflib'
88
import { ACLbyCombination, readACL } from './acl'
99
import * as widgets from '../widgets'
1010
import * as ns from '../ns'
@@ -58,13 +58,13 @@ export class AccessGroups {
5858
public aclMap: AgentMapMap
5959
private readonly addAgentButton: AddAgentButtons
6060
private readonly rootElement: HTMLElement
61-
private _store: LiveStore
61+
private _store: Store // @@ was LiveStore but does not need to be connected to web
6262

6363
constructor (
6464
private doc: NamedNode,
6565
private aclDoc: NamedNode,
6666
public controller: AccessController,
67-
store: LiveStore,
67+
store: Store, // @@ was LiveStore
6868
private options: AccessGroupsOptions = {}
6969
) {
7070
this.defaults = options.defaults || false

src/acl/acl-control.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import * as ns from '../ns'
99
import * as utils from '../utils'
1010
import { getACLorDefault, getProspectiveHolder } from './acl'
11-
import { IndexedFormula, NamedNode } from 'rdflib'
11+
import { Store, NamedNode } from 'rdflib'
1212
import { DataBrowserContext } from 'pane-registry'
1313
import { AccessController } from './access-controller'
1414
import { getClasses } from '../jss'
@@ -126,7 +126,7 @@ export function ACLControlBox5 (
126126
subject: NamedNode,
127127
context: DataBrowserContext,
128128
noun: string,
129-
kb: IndexedFormula
129+
kb: Store
130130
): HTMLElement {
131131
const dom = context.dom
132132
const doc = subject.doc() // The ACL is actually to the doc describing the thing
@@ -154,7 +154,7 @@ export function ACLControlBox5 (
154154

155155
async function loadController (
156156
doc: NamedNode,
157-
kb: IndexedFormula,
157+
kb: Store,
158158
subject: NamedNode,
159159
noun: string,
160160
context: DataBrowserContext,
@@ -200,7 +200,7 @@ function getDirectory (doc: NamedNode): string | null {
200200
return (q >= 0 && p < q + 2) || p < 0 ? null : str.slice(0, p + 1)
201201
}
202202

203-
function isStorage (doc: NamedNode, aclDoc: NamedNode, store: IndexedFormula): boolean {
203+
function isStorage (doc: NamedNode, aclDoc: NamedNode, store: Store): boolean {
204204
// @@ TODO: The methods used for targetIsStorage are HACKs - it should not be relied upon, and work is
205205
// @@ underway to standardize a behavior that does not rely upon this hack
206206
// @@ hopefully fixed as part of https://github.com/solid/data-interoperability-panel/issues/10

src/acl/acl.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { solidLogicSingleton, ACL_LINK } from 'solid-logic'
1010
import * as utils from '../utils'
1111
import { AgentMapMap, AgentMapUnion, ComboList } from './types'
1212
import * as debug from '../debug'
13-
import { graph, IndexedFormula, NamedNode, serialize, st, Statement, sym, LiveStore } from 'rdflib'
13+
import { graph, Store, NamedNode, serialize, st, Statement, sym, LiveStore } from 'rdflib'
1414

1515
const kb = solidLogicSingleton.store
1616

@@ -25,7 +25,7 @@ export function adoptACLDefault (
2525
aclDoc: NamedNode,
2626
defaultResource: NamedNode,
2727
defaultACLDoc: NamedNode
28-
): LiveStore {
28+
): Store {
2929
const ACL = ns.acl
3030
const isContainer = doc.uri.slice(-1) === '/' // Give default for all directories
3131

@@ -66,7 +66,7 @@ export function adoptACLDefault (
6666
export function readACL (
6767
doc: NamedNode,
6868
aclDoc: NamedNode,
69-
kb2: IndexedFormula = kb,
69+
kb2: Store = kb,
7070
getDefaults: boolean = false
7171
): AgentMapMap {
7272
const auths: Array<NamedNode> = getDefaults
@@ -211,7 +211,7 @@ export function ACLbyCombination (ac: AgentMapMap | AgentMapUnion): ComboList {
211211
/**
212212
* Write ACL graph to store from AC
213213
*/
214-
export function makeACLGraph (kb: IndexedFormula, x: NamedNode, ac: AgentMapMap, aclDoc: NamedNode): void {
214+
export function makeACLGraph (kb: Store, x: NamedNode, ac: AgentMapMap, aclDoc: NamedNode): void {
215215
const byCombo = ACLbyCombination(ac)
216216
return makeACLGraphbyCombo(kb, x, byCombo, aclDoc)
217217
}
@@ -220,7 +220,7 @@ export function makeACLGraph (kb: IndexedFormula, x: NamedNode, ac: AgentMapMap,
220220
* Write ACL graph to store from combo
221221
*/
222222
export function makeACLGraphbyCombo (
223-
kb: IndexedFormula,
223+
kb: Store,
224224
x: NamedNode,
225225
byCombo: ComboList,
226226
aclDoc: NamedNode,

src/footer/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
This file was copied from mashlib/src/global/footer.ts file. It is modified to
33
work in solid-ui by adjusting where imported functions are found.
44
*/
5-
import { IndexedFormula, NamedNode } from 'rdflib'
5+
import { LiveStore, NamedNode } from 'rdflib'
66
import { authn, authSession } from 'solid-logic'
77
import { addStyleClassToElement, getName, getPod, getPodOwner } from '../utils/headerFooterHelpers'
88

@@ -22,7 +22,7 @@ export type FooterOptions = {
2222
* @param store the data store
2323
* @returns the footer
2424
*/
25-
export async function initFooter (store: IndexedFormula, options?: FooterOptions) {
25+
export async function initFooter (store: LiveStore, options?: FooterOptions) {
2626
const footer = document.getElementById('PageFooter')
2727
if (!footer) {
2828
return
@@ -36,7 +36,7 @@ export async function initFooter (store: IndexedFormula, options?: FooterOptions
3636
/**
3737
* @ignore exporting this only for the unit test
3838
*/
39-
export function rebuildFooter (footer: HTMLElement, store: IndexedFormula, pod: NamedNode | null, podOwner: NamedNode | null, options?: FooterOptions) {
39+
export function rebuildFooter (footer: HTMLElement, store: LiveStore, pod: NamedNode | null, podOwner: NamedNode | null, options?: FooterOptions) {
4040
return async () => {
4141
const user = authn.currentUser()
4242
footer.innerHTML = ''
@@ -46,7 +46,7 @@ export function rebuildFooter (footer: HTMLElement, store: IndexedFormula, pod:
4646
/**
4747
* @ignore exporting this only for the unit test
4848
*/
49-
export function createControllerInfoBlock (store: IndexedFormula, user: NamedNode | null, pod: NamedNode | null, podOwner: NamedNode | null, options?: FooterOptions): HTMLElement {
49+
export function createControllerInfoBlock (store: LiveStore, user: NamedNode | null, pod: NamedNode | null, podOwner: NamedNode | null, options?: FooterOptions): HTMLElement {
5050
const profileLinkContainer = document.createElement('div')
5151
if (!pod || !podOwner || (user && user.equals(podOwner))) {
5252
return profileLinkContainer

src/login/login.ts

Lines changed: 90 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717
* * `containers` An array of nodes of containers of instances
1818
* * `div` A DOM element where UI can be displayed
1919
* * `statusArea` A DOM element (opt) progress stuff can be displayed, or error messages
20+
* *
21+
* * Vocabulary: "load" loads a file if it exists;
22+
* * 'Ensure" CREATES the file if it does not exist (if it can) and then loads it.
2023
* @packageDocumentation
2124
*/
2225
import { PaneDefinition } from 'pane-registry'
23-
import { BlankNode, IndexedFormula, NamedNode, st, Statement } from 'rdflib'
26+
import { BlankNode, NamedNode, st, Statement } from 'rdflib'
2427
// eslint-disable-next-line camelcase
2528
import { Quad_Object } from 'rdflib/lib/tf-types'
2629
import { AppDetails, AuthenticationContext, loadIndex, authn, authSession, CrossOriginForbiddenError, ensureTypeIndexes, FetchError, getSuggestedIssuers, NotFoundError, offlineTestID, SameOriginForbiddenError, solidLogicSingleton, UnauthorizedError } from 'solid-logic'
@@ -247,107 +250,118 @@ export async function findAppInstances (
247250
/**
248251
* UI to control registration of instance
249252
*/
250-
export function registrationControl (
253+
export async function registrationControl (
251254
context: AuthenticationContext,
252255
instance,
253256
theClass
254257
): Promise<AuthenticationContext | void> {
255258
const dom = context.dom
256259
if (!dom || !context.div) {
257-
return Promise.resolve()
260+
return context
258261
}
259262
const box = dom.createElement('div')
260263
context.div.appendChild(box)
264+
context.me = authn.currentUser() // @@
265+
if (!context.me) {
266+
box.innerHTML = '<p style="margin:2em;">(Log in to save a link to this)</p>'
267+
return context
268+
}
261269

262-
return ensureTypeIndexes(context)
263-
.then(function () {
264-
box.innerHTML = '<table><tbody><tr></tr><tr></tr></tbody></table>' // tbody will be inserted anyway
265-
box.setAttribute('style', 'font-size: 120%; text-align: right; padding: 1em; border: solid gray 0.05em;')
266-
const tbody = box.children[0].children[0]
267-
const form = new BlankNode() // @@ say for now
268-
269-
const registrationStatements = function (index) {
270-
const registrations = solidLogicSingleton.getRegistrations(instance, theClass)
271-
const reg = registrations.length
272-
? registrations[0]
273-
: widgets.newThing(index)
274-
return [
275-
st(reg, ns.solid('instance'), instance, index),
276-
st(reg, ns.solid('forClass'), theClass, index)
277-
]
278-
}
270+
let context2 // @@ const
271+
try {
272+
context2 = await ensureTypeIndexes(context)
273+
} catch (e) {
274+
let msg
275+
if (context.div && context.preferencesFileError) {
276+
msg = '(Preferences not available)'
277+
context.div.appendChild(dom.createElement('p')).textContent = msg
278+
} else if (context.div) {
279+
msg = `registrationControl: Type indexes not available: ${e}`
280+
context.div.appendChild(widgets.errorMessageBlock(context.dom, e))
281+
}
282+
debug.log(msg)
283+
}
279284

280-
let index, statements
281-
282-
if (context.index && context.index.public && context.index.public.length > 0) {
283-
index = context.index.public[0]
284-
statements = registrationStatements(index)
285-
tbody.children[0].appendChild(
286-
widgets.buildCheckBoxForm(
287-
context.dom,
288-
solidLogicSingleton.store,
289-
`Public link to this ${context.noun}`,
290-
null,
291-
statements,
292-
form,
293-
index
294-
)
285+
box.innerHTML = '<table><tbody><tr></tr><tr></tr></tbody></table>' // tbody will be inserted anyway
286+
box.setAttribute('style', 'font-size: 120%; text-align: right; padding: 1em; border: solid gray 0.05em;')
287+
const tbody = box.children[0].children[0]
288+
const form = new BlankNode() // @@ say for now
289+
290+
const registrationStatements = function (index) {
291+
const registrations = solidLogicSingleton.getRegistrations(instance, theClass)
292+
const reg = registrations.length
293+
? registrations[0]
294+
: widgets.newThing(index)
295+
return [
296+
st(reg, ns.solid('instance'), instance, index),
297+
st(reg, ns.solid('forClass'), theClass, index)
298+
]
299+
}
300+
301+
let index, statements
302+
303+
try {
304+
if (context2.index && context2.index.public && context2.index.public.length > 0) {
305+
index = context2.index.public[0]
306+
statements = registrationStatements(index)
307+
tbody.children[0].appendChild(
308+
widgets.buildCheckboxForm(
309+
context2.dom,
310+
solidLogicSingleton.store,
311+
`Public link to this ${context2.noun}`,
312+
null,
313+
statements,
314+
form,
315+
index
295316
)
296-
}
317+
)
318+
}
297319

298-
if (context.index && context.index.private && context.index.private.length > 0) {
299-
index = context.index.private[0]
300-
statements = registrationStatements(index)
301-
tbody.children[1].appendChild(
302-
widgets.buildCheckBoxForm(
303-
context.dom,
304-
solidLogicSingleton.store,
305-
`Personal note of this ${context.noun}`,
306-
null,
307-
statements,
308-
form,
309-
index
310-
)
320+
if (context2.index && context2.index.private && context2.index.private.length > 0) {
321+
index = context2.index.private[0]
322+
statements = registrationStatements(index)
323+
tbody.children[1].appendChild(
324+
widgets.buildCheckboxForm(
325+
context2.dom,
326+
solidLogicSingleton.store,
327+
`Personal note of this ${context2.noun}`,
328+
null,
329+
statements,
330+
form,
331+
index
311332
)
312-
}
313-
return context
314-
},
315-
function (e) {
316-
let msg
317-
if (context.div && context.preferencesFileError) {
318-
msg = '(Preferences not available)'
319-
context.div.appendChild(dom.createElement('p')).textContent = msg
320-
} else if (context.div) {
321-
msg = `registrationControl: Type indexes not available: ${e}`
322-
context.div.appendChild(widgets.errorMessageBlock(context.dom, e))
323-
}
324-
debug.log(msg)
333+
)
325334
}
326-
)
327-
.catch(function (e) {
328-
const msg = `registrationControl: Error making panel: ${e}`
329-
if (context.div) {
330-
context.div.appendChild(widgets.errorMessageBlock(context.dom, e))
331-
}
332-
debug.log(msg)
333-
})
335+
} catch (e) {
336+
const msg = `registrationControl: Error making panel: ${e}`
337+
if (context.div) {
338+
context.div.appendChild(widgets.errorMessageBlock(context.dom, e))
339+
}
340+
debug.log(msg)
341+
}
342+
return context2
334343
}
335344

336345
/**
337346
* UI to List at all registered things
338347
*/
339-
export function registrationList (context: AuthenticationContext, options: {
348+
export async function registrationList (context0: AuthenticationContext, options: {
340349
private?: boolean
341350
public?: boolean
342351
type?: NamedNode
343352
}): Promise<AuthenticationContext> {
344-
const dom = context.dom as HTMLDocument
345-
const div = context.div as HTMLElement
353+
const dom = context0.dom as HTMLDocument
354+
const div = context0.div as HTMLElement
346355

347356
const box = dom.createElement('div')
348357
div.appendChild(box)
358+
context0.me = authn.currentUser() // @@
359+
if (!context0.me) {
360+
box.innerHTML = '<p style="margin:2em;">(Log in list your stuff)</p>'
361+
return context0
362+
}
349363

350-
return ensureTypeIndexes(context).then(_indexes => {
364+
return ensureTypeIndexes(context0).then(context => {
351365
box.innerHTML = '<table><tbody></tbody></table>' // tbody will be inserted anyway
352366
box.setAttribute('style', 'font-size: 120%; text-align: right; padding: 1em; border: solid #eee 0.5em;')
353367
const table = box.firstChild as HTMLElement
@@ -356,10 +370,10 @@ export function registrationList (context: AuthenticationContext, options: {
356370
let sts: Statement[] = []
357371
const vs = ['private', 'public']
358372
vs.forEach(function (visibility) {
359-
if (context.index && options[visibility]) {
373+
if (context.index && context.index[visibility].length > 0 && options[visibility]) {
360374
ix = ix.concat(context.index[visibility][0])
361375
sts = sts.concat(
362-
(solidLogicSingleton.store as unknown as IndexedFormula).statementsMatching(
376+
solidLogicSingleton.store.statementsMatching(
363377
undefined,
364378
ns.solid('instance'),
365379
undefined,

src/style.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ export const style = { // styleModule
1717

1818
fieldLabelStyle: 'color: #3B5998; text-decoration: none;',
1919
formSelectSTyle:
20-
'background-color: #eef; padding: 0.5em; border: .05em solid #88c; border-radius:0.2em; font-size: 100%; margin:0.2em;',
20+
'background-color: #eef; padding: 0.5em; border: .05em solid #88c; border-radius:0.2em; font-size: 100%; margin:0.4em;',
2121
textInputStyle:
22-
'background-color: #eef; padding: 0.5em; border: .05em solid #88c; border-radius:0.2em; font-size: 100%; margin:0.2em;',
22+
'background-color: #eef; padding: 0.5em; border: .05em solid #88c; border-radius:0.2em; font-size: 100%; margin:0.4em;',
2323
textInputStyleUneditable: // Color difference only
24-
'background-color: white; padding: 0.5em; border: .05em solid white; border-radius:0.2em; font-size: 100%; margin:0.2em;',
24+
'background-color: white; padding: 0.5em; border: .05em solid white; border-radius:0.2em; font-size: 100%; margin:0.4em;',
2525
textInputSize: 20, // Default text input size in characters roughly
2626
buttonStyle:
2727
'background-color: #fff; padding: 0.7em; border: .01em solid white; border-radius:0.2em; font-size: 100%; margin: 0.3em;', // 'background-color: #eef;

0 commit comments

Comments
 (0)