|
@@ -6,7 +6,7 @@ import { FileIcon } from "./file-icon"
|
|
|
import { Icon } from "./icon"
|
|
import { Icon } from "./icon"
|
|
|
import { StickyAccordionHeader } from "./sticky-accordion-header"
|
|
import { StickyAccordionHeader } from "./sticky-accordion-header"
|
|
|
import { getDirectory, getFilename } from "@opencode-ai/util/path"
|
|
import { getDirectory, getFilename } from "@opencode-ai/util/path"
|
|
|
-import { For, Match, Show, Switch, type JSX, splitProps } from "solid-js"
|
|
|
|
|
|
|
+import { For, Match, Show, Switch, type JSX } from "solid-js"
|
|
|
import { createStore } from "solid-js/store"
|
|
import { createStore } from "solid-js/store"
|
|
|
import { type FileDiff } from "@opencode-ai/sdk"
|
|
import { type FileDiff } from "@opencode-ai/sdk"
|
|
|
import { PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
|
|
import { PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
|
|
@@ -15,6 +15,7 @@ export interface SessionReviewProps {
|
|
|
split?: boolean
|
|
split?: boolean
|
|
|
class?: string
|
|
class?: string
|
|
|
classList?: Record<string, boolean | undefined>
|
|
classList?: Record<string, boolean | undefined>
|
|
|
|
|
+ classes?: { root?: string; header?: string; container?: string }
|
|
|
actions?: JSX.Element
|
|
actions?: JSX.Element
|
|
|
diffs: (FileDiff & { preloaded?: PreloadMultiFileDiffResult<any> })[]
|
|
diffs: (FileDiff & { preloaded?: PreloadMultiFileDiffResult<any> })[]
|
|
|
}
|
|
}
|
|
@@ -39,17 +40,21 @@ export const SessionReview = (props: SessionReviewProps) => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const [split] = splitProps(props, ["class", "classList"])
|
|
|
|
|
-
|
|
|
|
|
return (
|
|
return (
|
|
|
<div
|
|
<div
|
|
|
data-component="session-review"
|
|
data-component="session-review"
|
|
|
classList={{
|
|
classList={{
|
|
|
- ...(split.classList ?? {}),
|
|
|
|
|
- [split.class ?? ""]: !!split.class,
|
|
|
|
|
|
|
+ ...(props.classList ?? {}),
|
|
|
|
|
+ [props.classes?.root ?? ""]: !!props.classes?.root,
|
|
|
|
|
+ [props.class ?? ""]: !!props.class,
|
|
|
}}
|
|
}}
|
|
|
>
|
|
>
|
|
|
- <div data-slot="session-review-header">
|
|
|
|
|
|
|
+ <div
|
|
|
|
|
+ data-slot="session-review-header"
|
|
|
|
|
+ classList={{
|
|
|
|
|
+ [props.classes?.header ?? ""]: !!props.classes?.header,
|
|
|
|
|
+ }}
|
|
|
|
|
+ >
|
|
|
<div data-slot="session-review-title">Session changes</div>
|
|
<div data-slot="session-review-title">Session changes</div>
|
|
|
<div data-slot="session-review-actions">
|
|
<div data-slot="session-review-actions">
|
|
|
<Button size="normal" icon="chevron-grabber-vertical" onClick={handleExpandOrCollapseAll}>
|
|
<Button size="normal" icon="chevron-grabber-vertical" onClick={handleExpandOrCollapseAll}>
|
|
@@ -61,47 +66,54 @@ export const SessionReview = (props: SessionReviewProps) => {
|
|
|
{props.actions}
|
|
{props.actions}
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- <Accordion multiple value={store.open} onChange={handleChange}>
|
|
|
|
|
- <For each={props.diffs}>
|
|
|
|
|
- {(diff) => (
|
|
|
|
|
- <Accordion.Item forceMount value={diff.file} data-slot="session-review-accordion-item">
|
|
|
|
|
- <StickyAccordionHeader>
|
|
|
|
|
- <Accordion.Trigger>
|
|
|
|
|
- <div data-slot="session-review-trigger-content">
|
|
|
|
|
- <div data-slot="session-review-file-info">
|
|
|
|
|
- <FileIcon node={{ path: diff.file, type: "file" }} />
|
|
|
|
|
- <div data-slot="session-review-file-name-container">
|
|
|
|
|
- <Show when={diff.file.includes("/")}>
|
|
|
|
|
- <span data-slot="session-review-directory">{getDirectory(diff.file)}‎</span>
|
|
|
|
|
- </Show>
|
|
|
|
|
- <span data-slot="session-review-filename">{getFilename(diff.file)}</span>
|
|
|
|
|
|
|
+ <div
|
|
|
|
|
+ data-slot="session-review-container"
|
|
|
|
|
+ classList={{
|
|
|
|
|
+ [props.classes?.container ?? ""]: !!props.classes?.container,
|
|
|
|
|
+ }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Accordion multiple value={store.open} onChange={handleChange}>
|
|
|
|
|
+ <For each={props.diffs}>
|
|
|
|
|
+ {(diff) => (
|
|
|
|
|
+ <Accordion.Item forceMount value={diff.file} data-slot="session-review-accordion-item">
|
|
|
|
|
+ <StickyAccordionHeader>
|
|
|
|
|
+ <Accordion.Trigger>
|
|
|
|
|
+ <div data-slot="session-review-trigger-content">
|
|
|
|
|
+ <div data-slot="session-review-file-info">
|
|
|
|
|
+ <FileIcon node={{ path: diff.file, type: "file" }} />
|
|
|
|
|
+ <div data-slot="session-review-file-name-container">
|
|
|
|
|
+ <Show when={diff.file.includes("/")}>
|
|
|
|
|
+ <span data-slot="session-review-directory">{getDirectory(diff.file)}‎</span>
|
|
|
|
|
+ </Show>
|
|
|
|
|
+ <span data-slot="session-review-filename">{getFilename(diff.file)}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div data-slot="session-review-trigger-actions">
|
|
|
|
|
+ <DiffChanges changes={diff} />
|
|
|
|
|
+ <Icon name="chevron-grabber-vertical" size="small" />
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- <div data-slot="session-review-trigger-actions">
|
|
|
|
|
- <DiffChanges changes={diff} />
|
|
|
|
|
- <Icon name="chevron-grabber-vertical" size="small" />
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </Accordion.Trigger>
|
|
|
|
|
- </StickyAccordionHeader>
|
|
|
|
|
- <Accordion.Content data-slot="session-review-accordion-content">
|
|
|
|
|
- <Diff
|
|
|
|
|
- preloadedDiff={diff.preloaded}
|
|
|
|
|
- diffStyle={props.split ? "split" : "unified"}
|
|
|
|
|
- before={{
|
|
|
|
|
- name: diff.file!,
|
|
|
|
|
- contents: diff.before!,
|
|
|
|
|
- }}
|
|
|
|
|
- after={{
|
|
|
|
|
- name: diff.file!,
|
|
|
|
|
- contents: diff.after!,
|
|
|
|
|
- }}
|
|
|
|
|
- />
|
|
|
|
|
- </Accordion.Content>
|
|
|
|
|
- </Accordion.Item>
|
|
|
|
|
- )}
|
|
|
|
|
- </For>
|
|
|
|
|
- </Accordion>
|
|
|
|
|
|
|
+ </Accordion.Trigger>
|
|
|
|
|
+ </StickyAccordionHeader>
|
|
|
|
|
+ <Accordion.Content data-slot="session-review-accordion-content">
|
|
|
|
|
+ <Diff
|
|
|
|
|
+ preloadedDiff={diff.preloaded}
|
|
|
|
|
+ diffStyle={props.split ? "split" : "unified"}
|
|
|
|
|
+ before={{
|
|
|
|
|
+ name: diff.file!,
|
|
|
|
|
+ contents: diff.before!,
|
|
|
|
|
+ }}
|
|
|
|
|
+ after={{
|
|
|
|
|
+ name: diff.file!,
|
|
|
|
|
+ contents: diff.after!,
|
|
|
|
|
+ }}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Accordion.Content>
|
|
|
|
|
+ </Accordion.Item>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </For>
|
|
|
|
|
+ </Accordion>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|