Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
810 changes: 482 additions & 328 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions src/components/provider/Provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ import { customElement, WebComponent } from '@/lib/components'
import { provide } from '@lit/context'
import { html, type PropertyValues } from 'lit'
import { property } from 'lit/decorators.js'
import { solidLogicSingleton } from 'solid-logic'
import { authContext } from '@/lib/auth'
import { SolidAuth, DEFAULT_SIGNUP_URL } from '@/lib/auth'
import { storeContext } from '@/lib/store'
import type { LiveStore } from 'rdflib'

import '@/components/dialogs-root'

Expand All @@ -15,6 +18,9 @@ export default class Provider extends WebComponent {
@provide({ context: authContext })
private accessor auth = new SolidAuth()

@provide({ context: storeContext })
private accessor store: LiveStore = solidLogicSingleton.store

async connectedCallback () {
super.connectedCallback()

Expand All @@ -27,6 +33,11 @@ export default class Provider extends WebComponent {
if (changedProperties.has('signupUrl')) {
this.auth.signupUrl = this.signupUrl ?? DEFAULT_SIGNUP_URL
}

if (this.store) {
void this.store
}

}

protected render () {
Expand Down
6 changes: 3 additions & 3 deletions src/components/rdf-form/RDFForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import ns from '../../lib/ns'
import { fetchData, findForm, sortBySequence } from '../../lib/forms/rdfFormsHelper'
import { sym, LiveStore } from 'rdflib'
import '@/components/rdf-input'
import { DEFAULT_STORE, storeContext, StoreContext } from '@/lib/forms/store/StoreContext'
import { DEFAULT_STORE, storeContext } from '@/lib/store'

const urlConverter = {
fromAttribute (value: string | null): URL | null {
Expand All @@ -31,13 +31,13 @@ const hrefFromUrlValue = (value: URL | null): string =>
@customElement('solid-ui-rdf-form')
export default class RDFForm extends WebComponent {
@consume({ context: storeContext, subscribe: true })
private accessor storeContext: StoreContext = DEFAULT_STORE
private accessor store: LiveStore = DEFAULT_STORE

@property({ attribute: false })
accessor passedInStore: LiveStore | null = null

private get currentStore (): LiveStore {
return this.passedInStore ?? this.storeContext.store
return this.passedInStore ?? this.store
}

@state()
Expand Down
29 changes: 15 additions & 14 deletions src/components/rdf-input/RDFInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { Literal, NamedNode, st } from 'rdflib'
import { label } from '../../utils'
import { mostSpecificClassURI } from '../../lib/forms/rdfFormsHelper'
import { FieldParamsObject, fieldParams as fieldTypeParams, InputType } from '../../lib/forms/fieldParams'
import { DEFAULT_STORE, storeContext, StoreContext } from '@/lib/forms/store/StoreContext'
import { DEFAULT_STORE, storeContext } from '@/lib/store'
import { consume } from '@lit/context'
import '@/components/input'
import type { LiveStore } from 'rdflib'

@customElement('solid-ui-rdf-input')
export default class RDFInput extends WebComponent {
Expand All @@ -21,7 +22,7 @@ export default class RDFInput extends WebComponent {
// dataSubject points to the data resource containing the value

@consume({ context: storeContext, subscribe: true })
private accessor storeContext: StoreContext = DEFAULT_STORE
private accessor store: LiveStore = DEFAULT_STORE

@property({ attribute: false, type: Object })
accessor formSubject: NamedNode | null = null
Expand Down Expand Up @@ -55,7 +56,7 @@ export default class RDFInput extends WebComponent {
const inputLabel = this.getInputLabel(this.formSubject, uiPropertyTerm, formDocument)
const readonly = this.getReadOnly(this.readonly, this.formSubject, formDocument)

const fieldType = this.formSubject ? mostSpecificClassURI(this.storeContext.store, this.formSubject) : undefined
const fieldType = this.formSubject ? mostSpecificClassURI(this.store, this.formSubject) : undefined
const params = fieldType ? fieldTypeParams[fieldType] ?? {} : {}
const inputType: InputType = params.type ?? 'text'

Expand Down Expand Up @@ -84,19 +85,19 @@ export default class RDFInput extends WebComponent {

private getFormProperty (subject: NamedNode | null | undefined, property: NamedNode, graph?: any): NamedNode | undefined {
if (!subject) return undefined
return this.storeContext.store.any(subject, property, null, graph) as NamedNode | undefined
return this.store.any(subject, property, null, graph) as NamedNode | undefined
}

private getInputLabel (formFieldSubject: NamedNode | null | undefined, uiPropertyTerm?: NamedNode, graph?: any): string {
if (!formFieldSubject) return ''
const uiLabel = this.storeContext.store.any(formFieldSubject, ns.ui('label'), null, graph)
const uiLabel = this.store.any(formFieldSubject, ns.ui('label'), null, graph)
const propertyLabel = uiPropertyTerm ? label(uiPropertyTerm, true) : ''
return uiLabel ? uiLabel.value : propertyLabel
}

private getReadOnly (readonly: boolean, formFieldSubject?: NamedNode | null, graph?: any): boolean {
if (formFieldSubject && readonly === false) { // if readonly is false, we can ovverride it if the field is marked as uneditable in the form
return !!this.storeContext.store.anyJS(formFieldSubject, ns.ui('suppressEmptyUneditable'), null, graph)
return !!this.store.anyJS(formFieldSubject, ns.ui('suppressEmptyUneditable'), null, graph)
}
return readonly
}
Expand All @@ -108,14 +109,14 @@ export default class RDFInput extends WebComponent {
params?: { defaultInputValue?: string }
) {
const defaultTerm = formFieldSubject
? this.storeContext.store.any(formFieldSubject, ns.ui('default'))
? this.store.any(formFieldSubject, ns.ui('default'))
: undefined

if (!uiPropertyTerm || !dataSubject) {
return defaultTerm
}

const inputTerm = this.storeContext.store.any(dataSubject, uiPropertyTerm)
const inputTerm = this.store.any(dataSubject, uiPropertyTerm)
return inputTerm || defaultTerm
}

Expand Down Expand Up @@ -163,23 +164,23 @@ export default class RDFInput extends WebComponent {
}

const dataDocument = this.getDocument(this.dataSubject)
if (dataDocument && this.storeContext.store.updater?.editable(dataDocument) === false) {
if (dataDocument && this.store.updater?.editable(dataDocument) === false) {
this._updateInFlight = false
return
}

const toDeleteSt = this.storeContext.store.statementsMatching(this.dataSubject, uiPropertyTerm)
const toDeleteSt = this.store.statementsMatching(this.dataSubject, uiPropertyTerm)
let toInsertSt: Array<ReturnType<typeof st>> = []

if (newValue) {
let objectFromNewValue
const fieldType = this.formSubject ? mostSpecificClassURI(this.storeContext.store, this.formSubject) : undefined
const fieldType = this.formSubject ? mostSpecificClassURI(this.store, this.formSubject) : undefined
const params: FieldParamsObject = fieldType ? fieldTypeParams[fieldType] ?? {} : {}
if (params.namedNode) {
objectFromNewValue = this.storeContext.store.sym(newValue)
objectFromNewValue = this.store.sym(newValue)
} else if (params.defaultInputValue) {
objectFromNewValue = encodeURIComponent(newValue.replace(/ /g, ''))
objectFromNewValue = this.storeContext.store.sym(params.defaultInputValue + objectFromNewValue)
objectFromNewValue = this.store.sym(params.defaultInputValue + objectFromNewValue)
} else {
if (params.dt) {
objectFromNewValue = new Literal(
Expand All @@ -198,7 +199,7 @@ export default class RDFInput extends WebComponent {
}

try {
await this.storeContext.store.updater.updateMany(toDeleteSt, toInsertSt as any)
await this.store.updater.updateMany(toDeleteSt, toInsertSt as any)
this.storeVersion += 1
} catch (err) {
console.error('RDFInput update failed', err)
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,4 @@ export * from './lib/components'
export * from './lib/dialogs'
export * from './lib/file-explorer/context'
export * from './lib/code-editor'
export * from './lib/store'
2 changes: 0 additions & 2 deletions src/lib/file-explorer/context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { createContext } from '@lit/context'
import { LiveStore } from 'rdflib'
import type { NamedNode } from 'rdflib'
import type { PaneDefinition } from 'pane-registry'

Expand All @@ -10,7 +9,6 @@ export interface FileExplorerEdit {
}

export interface FileExplorerContext {
store: LiveStore | undefined
subjectUri: string | undefined
pane?: PaneDefinition
soloPane?: boolean
Expand Down
8 changes: 0 additions & 8 deletions src/lib/forms/store/NoopStore.ts

This file was deleted.

10 changes: 0 additions & 10 deletions src/lib/forms/store/StoreContext.ts

This file was deleted.

19 changes: 19 additions & 0 deletions src/lib/store/NoopStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { LiveStore } from 'rdflib'

const throwNoopStoreError = () => {
throw new Error('Cannot use RDF forms without a store')
}

const NoopStore = new Proxy({} as LiveStore, {
get: throwNoopStoreError,
set: throwNoopStoreError,
has: throwNoopStoreError,
ownKeys: throwNoopStoreError,
getOwnPropertyDescriptor: throwNoopStoreError,
defineProperty: throwNoopStoreError,
deleteProperty: throwNoopStoreError,
apply: throwNoopStoreError,
construct: throwNoopStoreError
}) as LiveStore

export default NoopStore
8 changes: 8 additions & 0 deletions src/lib/store/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { createContext } from '@lit/context'
import { LiveStore } from 'rdflib'
import NoopStore from './NoopStore'

export type StoreContext = LiveStore

export const DEFAULT_STORE: LiveStore = NoopStore
export const storeContext = createContext<LiveStore>(Symbol('storeContext'))
4 changes: 4 additions & 0 deletions src/lib/store/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './context'
export * from './NoopStore'

export { default as NoopStore } from './NoopStore'
8 changes: 5 additions & 3 deletions src/storybook/components/StorybookProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import StorybookAuth from '../auth/StorybookAuth'
import { Account, authContext } from '@/lib/auth'

import '@/components/dialogs-root'
import { storeContext, StoreContext } from '@/lib/forms/store/StoreContext'
import { storeContext } from '@/lib/store'
import type { LiveStore } from 'rdflib'
import StorybookStore from '../store/StorybookStore'

@customElement('storybook-provider')
Expand All @@ -24,7 +25,7 @@ export class StorybookProvider extends WebComponent {
private accessor auth = new StorybookAuth()

@provide({ context: storeContext })
private accessor store: StoreContext = new StorybookStore()
private accessor store: LiveStore = StorybookStore()

willUpdate (changedProperties: PropertyValues<this>) {
super.willUpdate(changedProperties)
Expand All @@ -40,8 +41,9 @@ export class StorybookProvider extends WebComponent {
this.auth.account = new Account(this.webId, this.avatarUrl)

if (this.store) {
// read `store` so the property is considered used
void this.store
}

}

protected render () {
Expand Down
5 changes: 2 additions & 3 deletions src/storybook/store/StorybookStore.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { StoreContext } from '@/lib/forms/store/StoreContext'
import * as rdf from 'rdflib'
import { LiveStore } from 'rdflib'

export default class StorybookStore implements StoreContext {
public store: LiveStore = createStore()
export default function StorybookStore (): LiveStore {
return createStore()
}

function createStore (): rdf.LiveStore {
Expand Down
1 change: 1 addition & 0 deletions src/styles/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
--solid-ui-color-white: #ffffff;
--solid-ui-color-error: #b00020;

--solid-ui-color-gray-50: #f9fafb;
--solid-ui-color-gray-100: #f3f4f6;
--solid-ui-color-gray-200: #cbd5e1;
--solid-ui-color-gray-400: #99a1af;
Expand Down