Skip to content
Open
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
348 changes: 181 additions & 167 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "solid-panes",
"version": "4.4.2-7",
"version": "4.4.2-8",
"description": "Solid-compatible Panes: applets and views for the mashlib and databrowser",
"main": "dist/index.cjs.js",
"types": "dist/index.d.ts",
Expand Down Expand Up @@ -59,7 +59,7 @@
"@solid/better-simple-slideshow": "^0.1.0",
"activitystreams-pane": "1.0.3-4",
"chat-pane": "3.0.4-3",
"contacts-pane": "3.2.1-5",
"contacts-pane": "3.2.1-6",
"dompurify": "^3.4.4",
"folder-pane": "3.1.1-3",
"issue-pane": "3.0.3-1",
Expand All @@ -70,10 +70,10 @@
"pane-registry": "3.1.2-2",
"profile-pane": "3.2.3-4",
"rdflib": "2.4.0",
"solid-logic": "4.0.8-2",
"solid-logic": "4.0.8-3",
"solid-namespace": "^0.5.4",
"solid-ui": "3.1.3-15",
"source-pane": "3.1.1-6"
"solid-ui": "3.1.3-17",
"source-pane": "3.1.1-7"
},
"overrides": {
"rdflib": "$rdflib"
Expand Down
53 changes: 34 additions & 19 deletions src/components/file-explorer-header/FileExplorerHeader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
import { customElement, property, state } from 'lit/decorators.js'
import { consume } from '@lit/context'
import { html } from 'lit'
import { solidLogicSingleton } from 'solid-logic'
import '~icons/lucide/share-2'
import '~icons/lucide/pencil'
import '~icons/lucide/ellipsis-vertical'
import styles from './FileExplorerHeader.styles.css'
import './FileExplorerHeaderSummary'
import './FileExplorerHeaderControls'
import { PaneIcon } from './types'
import { fetchContentAndMetadata, type FileExplorerResourceMetadata } from './helper'
import { PaneIcon, type FileExplorerHeaderMetadata } from './types'

@customElement('file-explorer-header')
export default class FileExplorerHeader extends WebComponent {
static styles = styles

private _loadedMetadataForUri: string | undefined
private _loadedMetadataForTargetUri: string | undefined

@consume({ context: fileExplorerContext, subscribe: true })
accessor fileExplorerContext: FileExplorerContext = undefined as unknown as FileExplorerContext
Expand All @@ -27,44 +27,57 @@
@property({ attribute: false })
accessor paneIcon: PaneIcon = undefined as unknown as PaneIcon

@property({ type: Boolean })
accessor isContainerResource: boolean = false

@state()
accessor responseMetadata: Pick<FileExplorerResourceMetadata, 'modified' | 'isPublic' | 'canEdit' | 'aclUri'> = {
accessor responseMetadata: FileExplorerHeaderMetadata = {
modified: undefined,
isPublic: false,
canEdit: false,
access: {
isPublic: false,
canEdit: false,
canDelete: false
},
aclUri: undefined
}

private getDefaultResponseMetadata (): Pick<FileExplorerResourceMetadata, 'modified' | 'isPublic' | 'canEdit' | 'aclUri'> {
private getDefaultResponseMetadata (): FileExplorerHeaderMetadata {
return {
modified: undefined,
isPublic: false,
canEdit: false,
access: {
isPublic: false,
canEdit: false,
canDelete: false
},
aclUri: undefined
}
}

protected updated () {
if (this.fileExplorerContext?.store && this.fileExplorerContext.subjectUri && this._loadedMetadataForUri !== this.fileExplorerContext.subjectUri) {
this._loadedMetadataForUri = this.fileExplorerContext.subjectUri
const loadTargetUri = this.fileExplorerContext?.deleteTargetUri ?? this.fileExplorerContext?.subjectUri

Check failure on line 57 in src/components/file-explorer-header/FileExplorerHeader.ts

View workflow job for this annotation

GitHub Actions / build (24)

Property 'deleteTargetUri' does not exist on type 'FileExplorerContext'.

Check failure on line 57 in src/components/file-explorer-header/FileExplorerHeader.ts

View workflow job for this annotation

GitHub Actions / build (22)

Property 'deleteTargetUri' does not exist on type 'FileExplorerContext'.
if (this.fileExplorerContext?.store && loadTargetUri && this._loadedMetadataForTargetUri !== loadTargetUri) {
this._loadedMetadataForTargetUri = loadTargetUri
this.loadResponseMetadata()
}
}

private async loadResponseMetadata () {
if (!this.fileExplorerContext?.store || !this.fileExplorerContext.subjectUri) return
if (!this.fileExplorerContext?.store) return

const subjectUri = this.fileExplorerContext.deleteTargetUri ?? this.fileExplorerContext.subjectUri

Check failure on line 67 in src/components/file-explorer-header/FileExplorerHeader.ts

View workflow job for this annotation

GitHub Actions / build (24)

Property 'deleteTargetUri' does not exist on type 'FileExplorerContext'.

Check failure on line 67 in src/components/file-explorer-header/FileExplorerHeader.ts

View workflow job for this annotation

GitHub Actions / build (22)

Property 'deleteTargetUri' does not exist on type 'FileExplorerContext'.
if (!subjectUri) return

const defaultMetadata = this.getDefaultResponseMetadata()

try {
const { metadata } = await fetchContentAndMetadata(this.fileExplorerContext.store, sym(this.fileExplorerContext.subjectUri))
const metadata = await solidLogicSingleton.resource.fetchMetadataWithDelete(sym(subjectUri))
this.responseMetadata = {
modified: metadata.modified,
isPublic: metadata.isPublic,
canEdit: metadata.canEdit,
aclUri: metadata.aclUri
modified: metadata?.modified ?? defaultMetadata.modified,
access: metadata?.access ?? defaultMetadata.access,
aclUri: metadata?.aclUri ?? defaultMetadata.aclUri
}
} catch (error) {
this.responseMetadata = this.getDefaultResponseMetadata()
console.warn('Failed to load response metadata', error)
}
}

Expand All @@ -78,7 +91,9 @@
></file-explorer-header-summary>
<file-explorer-header-controls
.menuItems=${this.menuItems}
.canEdit=${this.responseMetadata.canEdit}
.canEdit=${this.responseMetadata.access.canEdit}
.canDelete=${this.responseMetadata.access.canDelete ?? false}
.isContainerResource=${this.isContainerResource}
></file-explorer-header-controls>
</header>
`
Expand Down
38 changes: 36 additions & 2 deletions src/components/file-explorer-header/FileExplorerHeaderControls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
@property({ type: Boolean })
accessor canEdit: boolean = false

@property({ type: Boolean })
accessor canDelete: boolean = false

@property({ type: Boolean })
accessor isContainerResource: boolean = false

// TODO: Add broken then use this function to set tooltip and disable edit button
/* private setEditable() {
const sourcePaneState = this.sourceContext?.sourcePaneState
Expand All @@ -43,12 +49,31 @@
}

private renderDirtyIndicator () {
if (!this.fileExplorerContext.edit?.isDirty) return nothing
if (!this.fileExplorerContext.paneSupportsEditing || !this.fileExplorerContext.edit?.isDirty) return nothing

return html`<span class="dirtyIndicator" title="This file has unsaved changes">Unsaved</span>`
}

render () {
private renderContainerControl () {
if (!this.fileExplorerContext.subjectUri || !this.fileExplorerContext.store) return nothing

return html`
<div>
<resource-actions-menu
.store=${this.fileExplorerContext?.store}
.subjectUri=${this.fileExplorerContext?.subjectUri}
.deleteTargetUri=${this.fileExplorerContext?.deleteTargetUri}

Check failure on line 65 in src/components/file-explorer-header/FileExplorerHeaderControls.ts

View workflow job for this annotation

GitHub Actions / build (24)

Property 'deleteTargetUri' does not exist on type 'FileExplorerContext'.

Check failure on line 65 in src/components/file-explorer-header/FileExplorerHeaderControls.ts

View workflow job for this annotation

GitHub Actions / build (22)

Property 'deleteTargetUri' does not exist on type 'FileExplorerContext'.
.menuItems=${this.menuItems}
.showShareItem=${this.isContainerResource}
.canDelete=${this.canDelete}
></resource-actions-menu>
</div>
`
}

private renderResourceControls () {
if (!this.fileExplorerContext.subjectUri || !this.fileExplorerContext.store) return nothing

return html`
<div>
${this.renderDirtyIndicator()}
Expand All @@ -66,9 +91,18 @@
<resource-actions-menu
.store=${this.fileExplorerContext?.store}
.subjectUri=${this.fileExplorerContext?.subjectUri}
.deleteTargetUri=${this.fileExplorerContext?.deleteTargetUri}

Check failure on line 94 in src/components/file-explorer-header/FileExplorerHeaderControls.ts

View workflow job for this annotation

GitHub Actions / build (24)

Property 'deleteTargetUri' does not exist on type 'FileExplorerContext'.

Check failure on line 94 in src/components/file-explorer-header/FileExplorerHeaderControls.ts

View workflow job for this annotation

GitHub Actions / build (22)

Property 'deleteTargetUri' does not exist on type 'FileExplorerContext'.
.menuItems=${this.menuItems}
.showShareItem=${false}
.canDelete=${this.canDelete}
></resource-actions-menu>
</div>
`
}

render () {
return html`
${this.isContainerResource ? this.renderContainerControl() : this.renderResourceControls()}
`
}
}
11 changes: 7 additions & 4 deletions src/components/file-explorer-header/FileExplorerHeaderSummary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import '~icons/lucide/globe'
import '~icons/lucide/lock-keyhole'
import '~icons/lucide/arrow-left'
import styles from './FileExplorerHeaderSummary.styles.css'
import { type FileExplorerResourceMetadata } from './helper'
import { type FileExplorerHeaderMetadata } from './types'

@customElement('file-explorer-header-summary')
export default class FileExplorerHeaderSummary extends WebComponent {
Expand All @@ -28,9 +28,12 @@ export default class FileExplorerHeaderSummary extends WebComponent {
accessor onBackClick: (() => void) | undefined

@property({ attribute: false })
accessor responseMetadata: Pick<FileExplorerResourceMetadata, 'modified' | 'isPublic'> = {
accessor responseMetadata: Pick<FileExplorerHeaderMetadata, 'modified' | 'access'> = {
modified: undefined,
isPublic: false
access: {
isPublic: false,
canEdit: false
}
}

@state()
Expand Down Expand Up @@ -97,7 +100,7 @@ export default class FileExplorerHeaderSummary extends WebComponent {
const subject = this.fileExplorerContext?.subjectUri ? sym(this.fileExplorerContext.subjectUri) : undefined
const label = subject ? utils.label(subject) : ''
const modified = this.formatModifiedDate(this.responseMetadata.modified)
const isPublic = this.responseMetadata.isPublic
const isPublic = this.responseMetadata.access.isPublic

return html`
<div class="file-explorer-header-summary">
Expand Down
40 changes: 35 additions & 5 deletions src/components/file-explorer-header/FileExplorerProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import styles from './FileExplorerProvider.styles.css'
import personIcon from '../../icons/person.svg'
import friendsIcon from '../../icons/friends.svg'
import { solidLogicSingleton } from 'solid-logic'
import { deriveDeleteTargetUri } from './helper'

const PERSON_ICON = personIcon
const FRIENDS_ICON = friendsIcon
Expand All @@ -19,6 +21,8 @@
pane?: PaneDefinition
soloPane?: boolean
onBack?: () => void
refresh?: () => void
deleteTargetUri?: string
openPane?: (subject: NamedNode, paneName: string) => void
handleSharingClick?: () => void
paneSupportsEditing?: boolean
Expand All @@ -34,6 +38,8 @@
pane: value.pane,
soloPane: value.soloPane,
onBack: value.onBack,
refresh: value.refresh,

Check failure on line 41 in src/components/file-explorer-header/FileExplorerProvider.ts

View workflow job for this annotation

GitHub Actions / build (24)

Object literal may only specify known properties, and 'refresh' does not exist in type 'FileExplorerContext'.

Check failure on line 41 in src/components/file-explorer-header/FileExplorerProvider.ts

View workflow job for this annotation

GitHub Actions / build (22)

Object literal may only specify known properties, and 'refresh' does not exist in type 'FileExplorerContext'.
deleteTargetUri: value.deleteTargetUri,
openPane: value.openPane,
handleSharingClick: value.handleSharingClick,
paneSupportsEditing: value.paneSupportsEditing,
Expand All @@ -53,6 +59,12 @@
@property({ attribute: false })
accessor onBack: (() => void) | undefined = undefined

@property({ attribute: false })
accessor refresh: (() => void) | undefined = undefined

@property({ attribute: false })
accessor deleteTargetUri: string | undefined = undefined

@property({ attribute: false })
accessor relevantPanes: PaneDefinition[] = []

Expand Down Expand Up @@ -87,6 +99,9 @@
@state()
accessor paneSupportsEditing: boolean = false

@state()
accessor isContainerResourceValue: boolean = false

// TODO: For now this works, but check if there is a better way.
// because this means file explorer will know about the pane.
// what if other panes want to use this. If so maybe we should
Expand Down Expand Up @@ -124,6 +139,8 @@
pane: this.pane,
soloPane: this.soloPane,
onBack: this.onBack,
refresh: this.refresh,
deleteTargetUri: deriveDeleteTargetUri(this.context?.session.store as LiveStore, this.subjectUri, this.pane?.mintClass, this.deleteTargetUri),
openPane: this.openPane,
handleSharingClick: this.handleSharingClick,
paneSupportsEditing: false,
Expand All @@ -138,11 +155,12 @@
this.pane = pane
}

private getPaneIcon (pane, subject, context) {
// The icon method may be a function that returns a promise, so we need to handle that.
private async getPaneIcon (pane, subject, context) {
if (!pane) return undefined

const icon = typeof pane.icon === 'function'
? pane.icon(subject, context)
? await pane.icon(subject, context)
: pane.icon
return icon
}
Expand Down Expand Up @@ -174,12 +192,23 @@
}

private refreshFileExplorerContextValue () {
const store = this.context?.session.store as LiveStore
const deleteTargetUri =
deriveDeleteTargetUri(store, this.subjectUri, this.pane?.mintClass, this.deleteTargetUri) ??
this.fileExplorerContextValue?.deleteTargetUri

Check failure on line 198 in src/components/file-explorer-header/FileExplorerProvider.ts

View workflow job for this annotation

GitHub Actions / build (24)

Property 'deleteTargetUri' does not exist on type 'FileExplorerContext'.

Check failure on line 198 in src/components/file-explorer-header/FileExplorerProvider.ts

View workflow job for this annotation

GitHub Actions / build (22)

Property 'deleteTargetUri' does not exist on type 'FileExplorerContext'.

this.isContainerResourceValue = deleteTargetUri
? solidLogicSingleton.resource.isContainer(store.sym(deleteTargetUri))
: solidLogicSingleton.resource.isContainer(store.sym(this.subjectUri as string))

this.fileExplorerContextValue = createFileExplorerContextValue({
store: this.context?.session.store as LiveStore,
store,
subjectUri: this.subjectUri,
pane: this.pane,
soloPane: this.soloPane,
onBack: this.onBack,
refresh: this.refresh,
deleteTargetUri,
openPane: this.openPane,
handleSharingClick: this.handleSharingClick,
paneSupportsEditing: this.paneSupportsEditing,
Expand All @@ -190,7 +219,6 @@
private async refreshMenuItems () {
const store = this.context?.session.store as LiveStore
if (!store || !this.subjectUri) return

const subject = store.sym(this.subjectUri)
const menuItems = await this.getPaneItems(subject, this.context as DataBrowserContext, this.relevantPanes)

Expand Down Expand Up @@ -227,9 +255,10 @@
changedProperties.has('pane') ||
changedProperties.has('soloPane') ||
changedProperties.has('onBack') ||
changedProperties.has('refresh') ||
changedProperties.has('deleteTargetUri') ||
changedProperties.has('openPane') ||
changedProperties.has('handleSharingClick') ||
changedProperties.has('pane') ||
changedProperties.has('isDirty')
) {
this.refreshFileExplorerContextValue()
Expand All @@ -247,6 +276,7 @@
.paneIcon=${this.getPaneIcon(this.pane, subject, this.context as DataBrowserContext)}
.menuItems=${this.menuItems}
.paneSupportsEditing=${this.paneSupportsEditing}
.isContainerResource=${this.isContainerResourceValue}
></file-explorer-header>
`
: nothing}
Expand Down
Loading
Loading