Skip to content

Commit 79b1183

Browse files
authored
Feat: sync file system via sse (#1197)
1 parent 121c488 commit 79b1183

30 files changed

Lines changed: 987 additions & 677 deletions

web/client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"prettier": "prettier --write .",
99
"lint:fix": "eslint --fix .",
1010
"format": "npm run prettier && npm run lint:fix",
11-
"test": "npm run test:unit && npm run test:e2e",
11+
"test": "npm run generate:api npm run test:unit && npm run test:e2e",
1212
"test:unit:watch": "NODE_ENV=development vitest --watch=true",
1313
"test:unit": "NODE_ENV=testing vitest --watch=false",
1414
"test:e2e": "NODE_ENV=testing playwright test",

web/client/src/api/index.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,6 @@ export function useApiEvaluate(
272272

273273
export function useMutationApiSaveFile(
274274
client: QueryClient,
275-
callbacks: {
276-
onSuccess?: (file: File) => void
277-
onMutate?: () => void
278-
},
279275
): UseMutationResult<
280276
File,
281277
unknown,
@@ -289,15 +285,6 @@ export function useMutationApiSaveFile(
289285
await client.cancelQueries({
290286
queryKey: [`/api/files`, path],
291287
})
292-
293-
if (callbacks.onMutate != null) {
294-
callbacks.onMutate()
295-
}
296-
},
297-
async onSuccess({ path, ...args }) {
298-
if (callbacks.onSuccess != null) {
299-
callbacks.onSuccess({ path, ...args })
300-
}
301288
},
302289
})
303290
}

web/client/src/context/editor.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ interface EditorStore {
3838
selectTab: (tab?: EditorTab) => void
3939
replaceTab: (from: EditorTab, to: EditorTab) => void
4040
updateStoredTabsIds: () => void
41+
inTabs: (file: ModelFile) => boolean
4142
addTab: (tab: EditorTab) => void
4243
addTabs: (tabs: EditorTab[]) => void
4344
closeTab: (file: ModelFile) => void
@@ -97,6 +98,9 @@ export const useStoreEditor = create<EditorStore>((set, get) => ({
9798
previewConsole: undefined,
9899
previewDiff: undefined,
99100
direction: 'vertical',
101+
inTabs(file) {
102+
return get().tabs.has(file)
103+
},
100104
replaceTab(from, to) {
101105
const s = get()
102106

@@ -155,7 +159,7 @@ export const useStoreEditor = create<EditorStore>((set, get) => ({
155159
refreshTab() {
156160
const tab = get().tab
157161

158-
if (tab == null) return
162+
if (isNil(tab)) return
159163

160164
get().selectTab({ ...tab })
161165
},

web/client/src/context/project.ts

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,82 @@
11
import { create } from 'zustand'
22
import { ModelDirectory, type ModelFile } from '../models'
3+
import { type ModelArtifact } from '@models/artifact'
34

45
interface ProjectStore {
6+
activeRange: ModelArtifact[]
7+
setActiveRange: (activeRange?: ModelArtifact[]) => void
58
project: ModelDirectory
69
setProject: (project?: ModelDirectory) => void
710
files: Map<ID, ModelFile>
811
setFiles: (files: ModelFile[]) => void
912
selectedFile?: ModelFile
1013
setSelectedFile: (selectedFile?: ModelFile) => void
14+
findArtifactByPath: (path: string) => ModelArtifact | undefined
15+
findParentByPath: (path: string) => ModelDirectory | undefined
16+
refreshFiles: () => void
17+
inActiveRange: (artifact: ModelArtifact) => boolean
1118
}
1219

1320
export const useStoreProject = create<ProjectStore>((set, get) => ({
14-
selectedFile: undefined,
1521
project: new ModelDirectory(),
22+
selectedFile: undefined,
1623
files: new Map(),
24+
activeRange: [],
25+
setActiveRange(activeRange) {
26+
const s = get()
27+
28+
set(() => ({
29+
activeRange: s.project.allVisibleArtifacts.filter(artifact =>
30+
inActiveRange(artifact, activeRange ?? s.activeRange),
31+
),
32+
}))
33+
},
34+
inActiveRange(artifact) {
35+
const s = get()
36+
37+
return inActiveRange(artifact, s.activeRange)
38+
},
1739
setProject(project) {
1840
set(() => ({
1941
project,
2042
}))
2143
},
2244
setFiles(files) {
45+
const s = get()
46+
47+
s.files.clear()
48+
2349
set(() => ({
24-
files: files.reduce((acc, file) => acc.set(file.id, file), new Map()),
50+
files: new Map(
51+
files.reduce((acc, file) => acc.set(file.id, file), s.files),
52+
),
2553
}))
2654
},
2755
setSelectedFile(selectedFile) {
2856
set(() => ({
2957
selectedFile,
3058
}))
3159
},
60+
findArtifactByPath(path) {
61+
const s = get()
62+
63+
return ModelDirectory.findArtifactByPath(s.project, path)
64+
},
65+
findParentByPath(path) {
66+
const s = get()
67+
68+
return ModelDirectory.findParentByPath(s.project, path)
69+
},
70+
refreshFiles() {
71+
const s = get()
72+
73+
s.setFiles(s.project.allFiles)
74+
},
3275
}))
76+
77+
function inActiveRange(
78+
artifact: ModelArtifact,
79+
activeRange: ModelArtifact[],
80+
): boolean {
81+
return activeRange.includes(artifact)
82+
}

web/client/src/library/components/button/Button.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,10 @@ const SHAPE = new Map<ButtonShape, string>([
9393
])
9494

9595
const SIZE = new Map<ButtonSize, string>([
96-
[EnumSize.xs, `px-2 py-0 text-xs leading-2 border`],
97-
[EnumSize.sm, `px-2 py-[0.125rem] text-xs leading-2 border-2`],
98-
[EnumSize.md, `px-3 py-2 text-base leading-4 border-2`],
99-
[EnumSize.lg, `px-4 py-3 text-lg leading-6 border-4`],
96+
[EnumSize.xs, `text-xs leading-2 border`],
97+
[EnumSize.sm, `px-2 py-[0.125rem] text-xs leading-4 border-2`],
98+
[EnumSize.md, `px-3 py-2 text-base leading-6 border-2`],
99+
[EnumSize.lg, `px-4 py-3 text-lg border-4`],
100100
])
101101

102102
const Button = makeButton(

web/client/src/library/components/container/Container.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@ const Container = function Container({
88

99
function Page({ children }: { children: React.ReactNode }): JSX.Element {
1010
return (
11-
<div
12-
className="font-sans w-full h-full flex flex-col overflow-hidden"
13-
tabIndex={0}
14-
>
11+
<div className="font-sans w-full h-full flex flex-col overflow-hidden">
1512
{children}
1613
</div>
1714
)

web/client/src/library/components/documentation/Documentation.tsx

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ import { type ModelSQLMeshModel } from '@models/sqlmesh-model'
88
import { ModelColumns } from '@components/graph/Graph'
99
import { useLineageFlow } from '@components/graph/context'
1010
import TabList from '@components/tab/Tab'
11-
import CodeEditor from '@components/editor/EditorCode'
1211
import { useSQLMeshModelExtensions } from '@components/editor/hooks'
12+
import {
13+
CodeEditorDefault,
14+
CodeEditorRemoteFile,
15+
} from '@components/editor/EditorCode'
1316

1417
const Documentation = function Documentation({
1518
model,
@@ -90,7 +93,7 @@ const Documentation = function Documentation({
9093
)}
9194
{(withCode || withQuery) && (
9295
<Section headline="SQL">
93-
<CodeEditor.RemoteFile path={model.path}>
96+
<CodeEditorRemoteFile path={model.path}>
9497
{({ file }) => (
9598
<Tab.Group defaultIndex={withQuery ? 1 : 0}>
9699
<TabList
@@ -112,43 +115,31 @@ const Documentation = function Documentation({
112115
'ring-white ring-opacity-60 ring-offset-2 ring-offset-blue-400 focus:outline-none focus:ring-2',
113116
)}
114117
>
115-
<CodeEditor.Default
118+
<CodeEditorDefault
116119
content={file.content}
117120
type={file.extension}
118-
>
119-
{({ extensions, content }) => (
120-
<CodeEditor
121-
extensions={extensions.concat(modelExtensions)}
122-
content={content}
123-
className="text-xs"
124-
/>
125-
)}
126-
</CodeEditor.Default>
121+
extensions={modelExtensions}
122+
className="text-xs"
123+
/>
127124
</Tab.Panel>
128125
)}
129126
{withQuery && (
130127
<Tab.Panel
131128
unmount={false}
132129
className="w-full h-full ring-white ring-opacity-60 ring-offset-2 ring-offset-blue-400 focus:outline-none focus:ring-2 p-2"
133130
>
134-
<CodeEditor.Default
131+
<CodeEditorDefault
135132
type={EnumFileExtensions.SQL}
136133
content={model.sql ?? ''}
137-
>
138-
{({ extensions, content }) => (
139-
<CodeEditor
140-
extensions={extensions.concat(modelExtensions)}
141-
content={content}
142-
className="text-xs"
143-
/>
144-
)}
145-
</CodeEditor.Default>
134+
extensions={modelExtensions}
135+
className="text-xs"
136+
/>
146137
</Tab.Panel>
147138
)}
148139
</Tab.Panels>
149140
</Tab.Group>
150141
)}
151-
</CodeEditor.RemoteFile>
142+
</CodeEditorRemoteFile>
152143
</Section>
153144
)}
154145
</Container>

web/client/src/library/components/editor/Editor.tsx

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import Loading from '@components/loading/Loading'
1919
import Spinner from '@components/logo/Spinner'
2020
import { EnumFileExtensions } from '@models/file'
2121
import { useLineageFlow } from '@components/graph/context'
22-
import CodeEditor from './EditorCode'
22+
import { CodeEditorRemoteFile, CodeEditorDefault } from './EditorCode'
2323
import { useDefaultKeymapsEditorTab, useSQLMeshModelExtensions } from './hooks'
2424

2525
function Editor(): JSX.Element {
@@ -230,41 +230,28 @@ function EditorMain({ tab }: { tab: EditorTab }): JSX.Element {
230230
>
231231
<div className="flex flex-col h-full">
232232
{tab.file.isLocal && (
233-
<CodeEditor.Default
233+
<CodeEditorDefault
234234
key={tab.id}
235235
type={EnumFileExtensions.SQL}
236236
dialect={tab.dialect}
237237
content={tab.file.content}
238-
>
239-
{({ extensions, content }) => (
240-
<CodeEditor
241-
extensions={extensions}
242-
keymaps={defaultKeymapsEditorTab}
243-
content={content}
244-
onChange={updateFileContent}
245-
/>
246-
)}
247-
</CodeEditor.Default>
238+
keymaps={defaultKeymapsEditorTab}
239+
onChange={updateFileContent}
240+
/>
248241
)}
249242
{tab.file.isRemote && (
250-
<CodeEditor.RemoteFile path={tab.file.path}>
243+
<CodeEditorRemoteFile path={tab.file.path}>
251244
{({ file, keymaps }) => (
252-
<CodeEditor.Default
245+
<CodeEditorDefault
253246
type={file.extension}
254247
dialect={tab.dialect}
255248
content={file.content}
256-
>
257-
{({ extensions, content }) => (
258-
<CodeEditor
259-
content={content}
260-
extensions={extensions.concat(modelExtensions)}
261-
keymaps={keymaps.concat(defaultKeymapsEditorTab)}
262-
onChange={updateFileContent}
263-
/>
264-
)}
265-
</CodeEditor.Default>
249+
extensions={modelExtensions}
250+
keymaps={keymaps.concat(defaultKeymapsEditorTab)}
251+
onChange={updateFileContent}
252+
/>
266253
)}
267-
</CodeEditor.RemoteFile>
254+
</CodeEditorRemoteFile>
268255
)}
269256
</div>
270257
<div className="flex flex-col h-full">

0 commit comments

Comments
 (0)