Skip to content

Commit

Permalink
Current commit management
Browse files Browse the repository at this point in the history
  • Loading branch information
csansoon committed Jul 16, 2024
1 parent 3d6f249 commit d78192d
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 64 deletions.
19 changes: 19 additions & 0 deletions apps/web/src/actions/commits/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use server'

import { isCommitDraft } from '@latitude-data/core'
import { z } from 'zod'

import { authProcedure } from '../procedures'

export const checkCommitEditableAction = authProcedure
.createServerAction()
.input(
z.object({
commitUuid: z.string(),
}),
{ type: 'json' },
)
.handler(async ({ input }) => {
const res = await isCommitDraft({ uuid: input.commitUuid })
return res.unwrap()
})
11 changes: 11 additions & 0 deletions apps/web/src/app/(private)/editor/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { DocumentEditor } from '@latitude-data/web-ui'

export const dynamic = 'force-dynamic'

export default async function Editor() {
return (
<div className='w-full h-full relative'>
<DocumentEditor document='' />
</div>
)
}
15 changes: 8 additions & 7 deletions apps/web/src/app/(private)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ReactNode } from 'react'

import Sidebar from '$/components/Sidebar'
// import Sidebar from '$/components/Sidebar'
import { getSession } from '$/services/auth/getSession'
import { ROUTES } from '$/services/routes'
import { CommitProvider } from '$/stores/commitContext'
import { redirect } from 'next/navigation'

export default async function PrivateLayout({
Expand All @@ -15,11 +16,11 @@ export default async function PrivateLayout({
return redirect(ROUTES.auth.login)
}
return (
<main className='flex flex-row w-full'>
<div className='w-[280px]'>
<Sidebar />
</div>
<div className='flex-1'>{children}</div>
</main>
<CommitProvider>
<main className='flex flex-row w-full'>
<div className='w-[280px]'>{/* <Sidebar /> */}</div>
<div className='flex-1'>{children}</div>
</main>
</CommitProvider>
)
}
5 changes: 2 additions & 3 deletions apps/web/src/app/api/commits/[commitUuid]/documents/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import { materializeDocumentsAtCommit } from '@latitude-data/core'
import { NextRequest, NextResponse } from 'next/server'

export async function GET(
req: NextRequest,
_: NextRequest,
{ commitUuid }: { commitUuid: string },
) {
try {
const staged = Boolean(req.nextUrl.searchParams.get('staged') || false)
const nodes = await materializeDocumentsAtCommit({ commitUuid, staged })
const nodes = await materializeDocumentsAtCommit({ commitUuid })

return NextResponse.json(nodes)
} catch (err: unknown) {
Expand Down
7 changes: 0 additions & 7 deletions apps/web/src/app/page.tsx

This file was deleted.

24 changes: 18 additions & 6 deletions apps/web/src/components/Sidebar/DocumentTree/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { faker } from '@faker-js/faker'
import type { DocumentType, DocumentVersion } from '@latitude-data/core'
import { useCurrentCommit } from '$/stores/commitContext'
import useDocumentVersions from '$/stores/documentVersions'

import toTree, { Node } from '../toTree'
Expand All @@ -20,26 +21,36 @@ export function CreateNode({ parentId }: { parentId?: number }) {
}

function CreateFolder({ parentId }: { parentId?: number }) {
const { create } = useDocumentVersions({ staged: true })
const { currentCommit, isCommitEditable } = useCurrentCommit()
const { create } = useDocumentVersions({ commitUuid: currentCommit })
return (
<button
onClick={() =>
disabled={!isCommitEditable}
onClick={() => {
if (!isCommitEditable) return
create({
parentId,
documentType: 'folder' as DocumentType.Folder,
name: generateName(),
})
}
}}
>
+F
</button>
)
}

function CreateDocument({ parentId }: { parentId?: number }) {
const { create } = useDocumentVersions({ staged: true })
const { currentCommit, isCommitEditable } = useCurrentCommit()
const { create } = useDocumentVersions({ commitUuid: currentCommit })
return (
<button onClick={() => create({ parentId, name: generateName() })}>
<button
disabled={!isCommitEditable}
onClick={() => {
if (!isCommitEditable) return
create({ parentId, name: generateName() })
}}
>
+D
</button>
)
Expand Down Expand Up @@ -70,8 +81,9 @@ function TreeNode({ node, level = 0 }: { node: Node; level?: number }) {
}

export default function DocumentTree({ nodes }: { nodes: DocumentVersion[] }) {
const { currentCommit } = useCurrentCommit()
const { data } = useDocumentVersions(
{ staged: true },
{ commitUuid: currentCommit },
{ fallbackData: nodes },
)
const rootNode = toTree(data)
Expand Down
1 change: 0 additions & 1 deletion apps/web/src/components/Sidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import DocumentTree, { CreateNode } from './DocumentTree'
export default async function Sidebar() {
const nodes = await materializeDocumentsAtCommit({
commitUuid: HEAD_COMMIT,
staged: true,
})

return (
Expand Down
81 changes: 81 additions & 0 deletions apps/web/src/stores/commitContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import {
createContext,
ReactNode,
useContext,
useEffect,
useState,
} from 'react'

import { checkCommitEditableAction } from '$/actions/commits'

interface CommitContextType {
currentCommit?: string
isCommitEditable: boolean
setCurrentCommit: ({
commitUuid,
isEditable,
}: {
commitUuid?: string
isEditable: boolean
}) => void
}

const CommitContext = createContext<CommitContextType>({
currentCommit: undefined,
isCommitEditable: false,
setCurrentCommit: () => {},
})

export const CommitProvider = ({ children }: { children: ReactNode }) => {
const [currentCommit, setCurrentCommit] = useState<string | undefined>()
const [isCommitEditable, setIsCommitEditable] = useState<boolean>(false)

useEffect(() => {
const storedCommit = localStorage.getItem('commit')
if (!storedCommit) {
setCurrentCommit(undefined)
setIsCommitEditable(false)
return
}

setCurrentCommit(storedCommit)
checkCommitEditableAction({ commitUuid: storedCommit }).then((res) => {
setIsCommitEditable(res[0]!)
})
}, [])

const updateCurrentCommit = ({
commitUuid,
isEditable,
}: {
commitUuid?: string
isEditable: boolean
}) => {
setCurrentCommit(commitUuid)
setIsCommitEditable(isEditable)

if (commitUuid) {
localStorage.setItem('commit', commitUuid)
} else {
localStorage.removeItem('commit')
}
}

return (
<CommitContext.Provider
value={{
currentCommit,
isCommitEditable,
setCurrentCommit: updateCurrentCommit,
}}
>
{children}
</CommitContext.Provider>
)
}

export const useCurrentCommit = () => {
const { currentCommit, isCommitEditable, setCurrentCommit } =
useContext(CommitContext)
return { currentCommit, isCommitEditable, setCurrentCommit }
}
13 changes: 3 additions & 10 deletions apps/web/src/stores/documentVersions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,19 @@ import useSWR, { SWRConfiguration } from 'swr'

export default function useDocumentVersions(
{
commitUuid = HEAD_COMMIT,
staged = false,
commitUuid,
}: {
commitUuid?: string
staged?: boolean
},
opts?: SWRConfiguration,
) {
const key =
`/api/commits/${commitUuid}/documents?` +
new URLSearchParams({
staged: String(staged),
}).toString()
const key = `/api/commits/${commitUuid ?? HEAD_COMMIT}/documents`
const { mutate, data, ...rest } = useSWR(
key,
(url: string) => fetch(url).then((res) => res.json()),
opts,
)
const create = async (payload: {
commitUuid?: string
name: string
documentType?: DocumentVersion['documentType']
parentId?: number
Expand All @@ -34,7 +27,7 @@ export default function useDocumentVersions(
const doc = await createDocumentVersionAction({
...payload,
name: payload.name!,
commitUuid: payload.commitUuid || HEAD_COMMIT,
commitUuid: commitUuid || HEAD_COMMIT,
})
mutate([...data, doc])

Expand Down
32 changes: 29 additions & 3 deletions packages/core/src/data-access/commits.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { commits, database, HEAD_COMMIT } from '@latitude-data/core'
import {
commits,
database,
HEAD_COMMIT,
Result,
TypedResult,
} from '@latitude-data/core'
import { LatitudeError, NotFoundError } from '$core/lib/errors'
import { desc, eq, isNull } from 'drizzle-orm'

export async function findCommit({ uuid }: { uuid?: string }, tx = database) {
Expand Down Expand Up @@ -27,6 +34,25 @@ export async function listCommits() {
return database.select().from(commits)
}

export async function listStagedCommits() {
return database.select().from(commits).where(isNull(commits.nextCommitId))
export async function isCommitDraft(
{ uuid }: { uuid: string },
tx = database,
): Promise<TypedResult<boolean, LatitudeError>> {
const res = await tx
.select()
.from(commits)
.where(eq(commits.uuid, uuid))
.limit(1)

if (!res.length) return Result.error(new NotFoundError('Commit not found'))
const commit = res[0]!

if (commit.nextCommitId) return Result.ok(false)

const commitsReferencingCommit = await tx
.select({ id: commits.id })
.from(commits)
.where(eq(commits.nextCommitId, commit.id))

return Result.ok(commitsReferencingCommit.length === 0)
}
17 changes: 0 additions & 17 deletions packages/core/src/data-access/documentVersions.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,6 @@
import { commits, database, documentVersions } from '@latitude-data/core'
import { desc, eq, inArray, lte } from 'drizzle-orm'

import { listStagedCommits } from './commits'

export async function listStagedDocuments() {
const commits = await listStagedCommits()
if (!commits.length) return []

return database
.select()
.from(documentVersions)
.where(
inArray(
documentVersions.commitId,
commits.map((c) => c.id),
),
)
}

export async function getDocumentsAtCommit(commitUuid: string) {
const referenceCommitId = await database
.select({ id: commits.id })
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/schema/models/commits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ export const commits = latitudeSchema.table(

export const commitRelations = relations(commits, ({ one, many }) => ({
snapshots: many(documentSnapshots, { relationName: 'snapshots' }),
workspace: one(workspaces),
workspace: one(workspaces, {
fields: [commits.workspaceId],
references: [workspaces.id],
}),
}))

export type Commit = InferSelectModel<typeof commits> & {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,20 @@
import { uniqBy } from 'lodash-es'

import {
getDocumentsAtCommit,
listdocumentSnapshots,
listStagedDocuments,
} from '@latitude-data/core'

export const HEAD_COMMIT = 'HEAD'

export async function materializeDocumentsAtCommit({
commitUuid = HEAD_COMMIT,
staged = true,
}: {
commitUuid: string
staged: boolean
}) {
if (commitUuid === HEAD_COMMIT) {
const snapshots = (await listdocumentSnapshots()).map(
(snap) => snap.document_versions,
)
if (!staged) return snapshots

const versions = await listStagedDocuments()
return uniqBy([...versions, ...snapshots], (doc) => doc.documentUuid)
return snapshots
} else {
return await getDocumentsAtCommit(commitUuid)
}
Expand Down

0 comments on commit d78192d

Please sign in to comment.