diff --git a/ui/src/elements/all-notes.ts b/ui/src/elements/all-notes.ts index a0191e1..bd66ade 100644 --- a/ui/src/elements/all-notes.ts +++ b/ui/src/elements/all-notes.ts @@ -6,9 +6,10 @@ import { joinAsyncMap, mapAndJoin, pipe, + sliceAndJoin, StoreSubscriber, } from "@holochain-open-dev/stores"; -import { synContext, SynStore, Document, WorkspaceStore } from "@holochain-syn/core"; +import { synContext, SynStore, Document, WorkspaceStore, Commit } from "@holochain-syn/core"; import { consume } from "@lit/context"; import { css, html, LitElement } from "lit"; import { customElement, query, state } from "lit/decorators.js"; @@ -31,6 +32,7 @@ import { TextEditorEphemeralState, TextEditorState } from "../grammar.js"; enum SortColumn { Created, + Modified, Title, Author } @@ -38,8 +40,10 @@ enum SortColumn { type NoteRow = { title: string, created: Timestamp, + modified: Timestamp|undefined author: AgentPubKey, actionHash: ActionHash, + state: TextEditorState, authorSort: number, archived: boolean } @@ -47,7 +51,8 @@ type NoteRow = { export interface NoteAndLatestState { workspace: WorkspaceStore, latestState: TextEditorState, - tip: EntryHash, + tip: EntryRecord | undefined, + document: EntryRecord } @localized() @@ -57,7 +62,7 @@ export class AllNotes extends LitElement { synStore!: SynStore; @state() - sortColumn = SortColumn.Created + sortColumn = SortColumn.Modified @state() sortDirection = SortDirection.Descending @@ -65,24 +70,50 @@ export class AllNotes extends LitElement { @state() showArchived = false - allNotes = new StoreSubscriber( + noteData = new LazyHoloHashMap( documentHash => { + const docStore = this.synStore.documents.get(documentHash) + + const workspace = pipe(docStore.allWorkspaces, + workspaces => new WorkspaceStore(docStore, Array.from(workspaces.keys())[0]) + ) + const latestState = pipe(workspace, + workspace => workspace.latestState + ) + const tip = pipe(workspace, + workspace => workspace.tip + ) + const document = pipe(docStore.record, + document => document + ) + + return alwaysSubscribed(pipe(joinAsync([workspace, latestState, tip, document]), ([workspace, latestState, tip, document]) => ( + {workspace,latestState, tip, document}))) + }) + + + activeNotes: StoreSubscriber>> = new StoreSubscriber( this, - () => - pipe(this.synStore.documentsByTag.get("note"), (map) => - mapAndJoin(map, (d) => d.record) - ), + () => { + const activeNoteHashes = asyncDerived(this.synStore.documentsByTag.get("note"),x=>Array.from(x.keys())) + return pipe(activeNoteHashes, + docHashes => sliceAndJoin(this.noteData, docHashes, {errors: "filter_out"}) + ) + }, () => [this.synStore] ); - archivedNotes = new StoreSubscriber( + archivedNotes: StoreSubscriber>> = new StoreSubscriber( this, - () => - pipe(this.synStore.documentsByTag.get("arc"), (map) => - mapAndJoin(map, (d) => d.record) - ), + () => { + const activeNoteHashes = asyncDerived(this.synStore.documentsByTag.get("arc"),x=>Array.from(x.keys())) + return pipe(activeNoteHashes, + docHashes => sliceAndJoin(this.noteData, docHashes, {errors: "filter_out"}) + ) + }, () => [this.synStore] ); + setSort(column: SortColumn, direction:SortDirection) { this.sortColumn = column this.sortDirection = direction @@ -98,47 +129,26 @@ export class AllNotes extends LitElement { @state() error = "" - // activeNoteHashes = asyncDerived(this.synStore.documentsByTag.get("note"),x=>Array.from(x.keys())) - - // archivedNoteHashes = asyncDerived(this.synStore.documentsByTag.get("arc"),x=>Array.from(x.keys())) - - // allNoteHashes = joinAsync([this.activeNoteHashes, this.archivedNoteHashes]) - - // noteData = new LazyHoloHashMap( documentHash => { - // const docStore = this.synStore.documents.get(documentHash) - - // const workspace = pipe(docStore.allWorkspaces, - // workspaces => new WorkspaceStore(docStore, Array.from(workspaces.keys())[0]) - // ) - // const latestState = pipe(workspace, - // workspace => workspace.latestState - // ) - // const tip = pipe(workspace, - // workspace => workspace.tip - // ) - - // return alwaysSubscribed(pipe(joinAsync([workspace, latestState, tip]), ([workspace, latestState, tip]) => ( - // {workspace,latestState, tip: tip ? tip.entryHash: undefined}))) - // }) - - processNoteRecord(note: EntryRecord, archived: boolean) : NoteRow { - const a = encodeHashToBase64(note.action.author) + processNoteRecord(note: NoteAndLatestState, archived: boolean) : NoteRow { + const a = encodeHashToBase64(note.document.action.author) let authorSort = this.authors.findIndex(x=>x===a) if (authorSort === -1) { authorSort = this.authors.length this.authors.push(a) } return { - title:(decode(note.entry.meta!) as any).title, - created: note.action.timestamp, - author:note.action.author, - actionHash:note.actionHash, + title:(decode(note.document.entry.meta!) as any).title, + modified: note.tip ? note.tip.action.timestamp : undefined, + created: note.document.action.timestamp, + author:note.document.action.author, + actionHash:note.document.actionHash, + state: note.latestState, authorSort, archived } } - processNoteRecords(subscriber: StoreSubscriber>>>, archived: boolean) { + processNoteRecords(subscriber: StoreSubscriber>>, archived: boolean) { switch (subscriber.value.status) { case "pending": break; @@ -158,6 +168,10 @@ export class AllNotes extends LitElement { notes: NoteRow[] ): Array { switch (this.sortColumn) { + case SortColumn.Modified: + if (this.sortDirection=== SortDirection.Descending) + return notes.sort((a, b) => (b.modified ? b.modified : b.created) - (a.modified ? a.modified : a.created)) + return notes.sort((b, a) => (b.modified ? b.modified : b.created) - (a.modified ? a.modified : a.created)) case SortColumn.Created: if (this.sortDirection=== SortDirection.Descending) return notes.sort((a, b) => b.created - a.created) @@ -176,6 +190,13 @@ export class AllNotes extends LitElement { renderNote(note: NoteRow) { const createDate = new Date(note.created) + const modifiedDate = note.modified ? new Date(note.modified) : undefined + let title = note.title + // @ts-ignore + const match = /^(#+ +)*(.*)/.exec(note.state.text); + if (match) { + title = match[2] + } return html`
- ${note.title} + ${title} ${note.archived ? html`${msg("Archived")}`:""} - + + ${modifiedDate ? html`${modifiedDate.toLocaleDateString()} ${modifiedDate.toLocaleTimeString()}` : "never"} + ${createDate.toLocaleDateString()} ${createDate.toLocaleTimeString()} @@ -254,40 +277,13 @@ export class AllNotes extends LitElement { render() { if (!this.noReset) { this.noteRows = [] - this.processNoteRecords(this.allNotes, false) + this.processNoteRecords(this.activeNotes, false) if (this.showArchived) this.processNoteRecords(this.archivedNotes, true) + } else this.noReset = false - // switch (this.allNotes.value.status) { - // case "pending": - // return html`
- // ${Array(3).map( - // () => html`` - // )} - //
`; - // case "complete": - - // Array.from(this.allNotes.value.value.values()) - // .forEach((note) => { - // const a = encodeHashToBase64(note.action.author) - // let authorSort = authors.findIndex(x=>x===a) - // if (authorSort === -1) { - // authorSort = authors.length - // authors.push(a) - // } - // noteRows.push( { - // title:(decode(note.entry.meta!) as any).title, - // created: note.action.timestamp, - // author:note.action.author, - // actionHash:note.actionHash, - // authorSort, - // archived:false, - // })}) - // break; - // } - return html`
@@ -312,6 +308,13 @@ export class AllNotes extends LitElement { ${msg("Title")} + + this.setSort(SortColumn.Modified, e.detail.direction)} + >${msg("Modified")} + + + ${ this._synStore ? html` { @@ -409,6 +410,7 @@ export class NotebooksApp extends LitElement { }; }} > + `:``}
@@ -569,7 +571,7 @@ export class NotebooksApp extends LitElement { } return html` - +

Notebooks is a demonstration Holochain app built by Lighning Rod Labs.

Developers: