Skip to content

Commit 98ef71f

Browse files
authored
Feat: Table Diff (#1005)
1 parent 301a914 commit 98ef71f

File tree

19 files changed

+1457
-354
lines changed

19 files changed

+1457
-354
lines changed

web/client/openapi.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,9 +1039,9 @@
10391039
},
10401040
"IntervalUnit": {
10411041
"title": "IntervalUnit",
1042-
"enum": ["day", "hour", "minute"],
1042+
"enum": ["year", "month", "day", "hour", "minute"],
10431043
"type": "string",
1044-
"description": "IntervalUnit is the inferred granularity of an incremental model.\n\nIntervalUnit can be one of 4 types, DAY, HOUR, MINUTE. The unit is inferred\nbased on the cron schedule of a model. The minimum time delta between a sample set of dates\nis used to determine which unit a model's schedule is."
1044+
"description": "IntervalUnit is the inferred granularity of an incremental model.\n\nIntervalUnit can be one of 5 types, YEAR, MONTH, DAY, HOUR, MINUTE. The unit is inferred\nbased on the cron schedule of a model. The minimum time delta between a sample set of dates\nis used to determine which unit a model's schedule is."
10451045
},
10461046
"LineageColumn": {
10471047
"title": "LineageColumn",
@@ -1112,6 +1112,7 @@
11121112
"tags": { "title": "Tags", "type": "string" },
11131113
"grain": { "title": "Grain", "type": "string" },
11141114
"partitioned_by": { "title": "Partitioned By", "type": "string" },
1115+
"clustered_by": { "title": "Clustered By", "type": "string" },
11151116
"lookback": { "title": "Lookback", "type": "integer" },
11161117
"cron_prev": {
11171118
"title": "Cron Prev",

web/client/src/api/index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ import {
3535
evaluateApiCommandsEvaluatePost,
3636
type EvaluateInput,
3737
type Model,
38+
getTableDiffApiTableDiffGet,
39+
type GetTableDiffApiTableDiffGetParams,
40+
type TableDiff,
3841
} from './client'
3942
import {
4043
useIDE,
@@ -218,6 +221,18 @@ export function useApiRender(options: RenderInput): UseQueryResult<Query> {
218221
})
219222
}
220223

224+
export function useApiTableDiff(
225+
options: GetTableDiffApiTableDiffGetParams,
226+
): UseQueryResult<TableDiff> {
227+
return useQuery<TableDiff, ErrorIDE>({
228+
queryKey: ['/api/commands/table_diff'],
229+
queryFn: async ({ signal }) =>
230+
await getTableDiffApiTableDiffGet(options, { signal }),
231+
enabled: false,
232+
cacheTime: 0,
233+
})
234+
}
235+
221236
export function useApiEvaluate(
222237
options: EvaluateInput,
223238
): UseQueryResult<unknown> {

web/client/src/context/editor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ interface EditorStore {
2626
previewQuery?: string
2727
previewTable?: any[]
2828
previewConsole?: [ErrorKey, ErrorIDE]
29+
previewDiff?: any
2930
direction: 'vertical' | 'horizontal'
3031
setDirection: (direction: 'vertical' | 'horizontal') => void
3132
selectTab: (tab?: EditorTab) => void
@@ -38,6 +39,7 @@ interface EditorStore {
3839
setPreviewQuery: (previewQuery?: string) => void
3940
setPreviewTable: (previewTable?: any[]) => void
4041
setPreviewConsole: (previewConsole?: [ErrorKey, ErrorIDE]) => void
42+
setPreviewDiff: (previewDiff?: any) => void
4143
}
4244

4345
interface EditorPreview<TTable = any> {
@@ -78,6 +80,7 @@ export const useStoreEditor = create<EditorStore>((set, get) => ({
7880
previewQuery: undefined,
7981
previewTable: undefined,
8082
previewConsole: undefined,
83+
previewDiff: undefined,
8184
direction: 'vertical',
8285
updateStoredTabsIds() {
8386
const s = get()
@@ -162,6 +165,9 @@ export const useStoreEditor = create<EditorStore>((set, get) => ({
162165
setPreviewConsole(previewConsole) {
163166
set(() => ({ previewConsole }))
164167
},
168+
setPreviewDiff(previewDiff) {
169+
set(() => ({ previewDiff }))
170+
},
165171
setDirection(direction) {
166172
set(() => ({ direction }))
167173
},

web/client/src/index.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@
123123
--color-accent-900: hsla(264, 100%, 8%, 1);
124124

125125
/* Success */
126+
--color-success-5: hsla(111, 66%, 55%, 0.05);
126127
--color-success-10: hsla(111, 66%, 55%, 0.1);
128+
--color-success-20: hsla(111, 66%, 55%, 0.2);
127129
--color-success-100: hsla(92, 90%, 92%, 1);
128130
--color-success-200: hsla(98, 90%, 84%, 1);
129131
--color-success-300: hsla(102, 81%, 75%, 1);
@@ -147,7 +149,9 @@
147149
--color-warning-900: hsla(18, 82%, 26%, 1);
148150

149151
/* Danger */
152+
--color-danger-5: hsla(21, 100%, 50%, 0.05);
150153
--color-danger-10: hsla(21, 100%, 50%, 0.1);
154+
--color-danger-20: hsla(21, 100%, 50%, 0.2);
151155
--color-danger-100: hsla(21, 100%, 93%, 1);
152156
--color-danger-200: hsla(16, 100%, 86%, 1);
153157
--color-danger-300: hsla(11, 100%, 78%, 1);

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

Lines changed: 51 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import CodeEditor, {
55
import { Disclosure, Tab } from '@headlessui/react'
66
import { MinusCircleIcon, PlusCircleIcon } from '@heroicons/react/24/solid'
77
import { EnumFileExtensions } from '@models/file'
8-
import { isFalse, isString, isTrue, toDateFormat } from '@utils/index'
8+
import { isString, isTrue, toDateFormat } from '@utils/index'
99
import clsx from 'clsx'
1010
import { type ModelSQLMeshModel } from '@models/sqlmesh-model'
1111
import { ModelColumns } from '@components/graph/Graph'
1212
import { useLineageFlow } from '@components/graph/context'
13+
import TabList from '@components/tab/Tab'
1314

1415
const Documentation = function Documentation({
1516
model,
@@ -92,85 +93,59 @@ const Documentation = function Documentation({
9293
<Section headline="SQL">
9394
<CodeEditor.RemoteFile path={model.path}>
9495
{({ file }) => (
95-
<>
96-
<Tab.Group defaultIndex={withQuery ? 1 : 0}>
97-
<Tab.List className="w-full whitespace-nowrap px-2 pt-3 flex justify-center items-center">
98-
<Tab
99-
disabled={isFalse(withCode)}
100-
className={({ selected }) =>
101-
clsx(
102-
'inline-block font-medium px-3 py-1 mr-2 last-child:mr-0 rounded-md relative',
103-
selected
104-
? 'bg-secondary-500 text-secondary-100 cursor-default'
105-
: 'bg-secondary-10 ',
106-
isFalse(withCode)
107-
? 'opacity-50 cursor-not-allowed'
108-
: 'cursor-pointer',
109-
)
110-
}
111-
>
112-
Source Code
113-
</Tab>
114-
<Tab
115-
disabled={isFalse(withQuery)}
116-
className={({ selected }) =>
117-
clsx(
118-
'inline-block font-medium px-3 py-1 mr-2 last-child:mr-0 rounded-md relative',
119-
selected
120-
? 'bg-secondary-500 text-secondary-100 cursor-default'
121-
: 'bg-secondary-10 ',
122-
isFalse(withQuery)
123-
? 'opacity-50 cursor-not-allowed'
124-
: 'cursor-pointer',
125-
)
126-
}
96+
<Tab.Group defaultIndex={withQuery ? 1 : 0}>
97+
<TabList
98+
list={
99+
[
100+
withCode && 'Source Code',
101+
withQuery && 'Compiled Query',
102+
].filter(Boolean) as string[]
103+
}
104+
className="!justify-center"
105+
/>
106+
107+
<Tab.Panels className="h-full w-full overflow-hidden bg-neutral-10 mt-4 rounded-lg">
108+
<Tab.Panel
109+
unmount={false}
110+
className={clsx(
111+
'flex flex-col w-full h-full relative px-2 overflow-hidden p-2',
112+
'ring-white ring-opacity-60 ring-offset-2 ring-offset-blue-400 focus:outline-none focus:ring-2',
113+
)}
114+
>
115+
<CodeEditor.SQLMeshDialect
116+
content={file.content}
117+
type={file.extension}
127118
>
128-
Compiled Query
129-
</Tab>
130-
</Tab.List>
131-
<Tab.Panels className="h-full w-full overflow-hidden bg-neutral-10 mt-4 rounded-lg">
132-
<Tab.Panel
133-
unmount={false}
134-
className={clsx(
135-
'flex flex-col w-full h-full relative px-2 overflow-hidden p-2',
136-
'ring-white ring-opacity-60 ring-offset-2 ring-offset-blue-400 focus:outline-none focus:ring-2',
119+
{({ extensions, content }) => (
120+
<CodeEditor
121+
extensions={extensions.concat(modelExtensions)}
122+
content={content}
123+
className="text-xs"
124+
/>
137125
)}
126+
</CodeEditor.SQLMeshDialect>
127+
</Tab.Panel>
128+
<Tab.Panel
129+
unmount={false}
130+
className={clsx(
131+
'w-full h-full ring-white ring-opacity-60 ring-offset-2 ring-offset-blue-400 focus:outline-none focus:ring-2 p-2',
132+
)}
133+
>
134+
<CodeEditor.Default
135+
type={EnumFileExtensions.SQL}
136+
content={model.sql ?? ''}
138137
>
139-
<CodeEditor.SQLMeshDialect
140-
content={file.content}
141-
type={file.extension}
142-
>
143-
{({ extensions, content }) => (
144-
<CodeEditor
145-
extensions={extensions.concat(modelExtensions)}
146-
content={content}
147-
className="text-xs"
148-
/>
149-
)}
150-
</CodeEditor.SQLMeshDialect>
151-
</Tab.Panel>
152-
<Tab.Panel
153-
unmount={false}
154-
className={clsx(
155-
'w-full h-full ring-white ring-opacity-60 ring-offset-2 ring-offset-blue-400 focus:outline-none focus:ring-2 p-2',
138+
{({ extensions, content }) => (
139+
<CodeEditor
140+
extensions={extensions.concat(modelExtensions)}
141+
content={content}
142+
className="text-xs"
143+
/>
156144
)}
157-
>
158-
<CodeEditor.Default
159-
type={EnumFileExtensions.SQL}
160-
content={model.sql ?? ''}
161-
>
162-
{({ extensions, content }) => (
163-
<CodeEditor
164-
extensions={extensions.concat(modelExtensions)}
165-
content={content}
166-
className="text-xs"
167-
/>
168-
)}
169-
</CodeEditor.Default>
170-
</Tab.Panel>
171-
</Tab.Panels>
172-
</Tab.Group>
173-
</>
145+
</CodeEditor.Default>
146+
</Tab.Panel>
147+
</Tab.Panels>
148+
</Tab.Group>
174149
)}
175150
</CodeEditor.RemoteFile>
176151
</Section>

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ function EditorMain({ tab }: { tab: EditorTab }): JSX.Element {
132132
const engine = useStoreEditor(s => s.engine)
133133
const previewTable = useStoreEditor(s => s.previewTable)
134134
const previewConsole = useStoreEditor(s => s.previewConsole)
135+
const previewDiff = useStoreEditor(s => s.previewDiff)
135136
const selectTab = useStoreEditor(s => s.selectTab)
136137
const createTab = useStoreEditor(s => s.createTab)
137138
const closeTab = useStoreEditor(s => s.closeTab)
@@ -175,11 +176,12 @@ function EditorMain({ tab }: { tab: EditorTab }): JSX.Element {
175176
const sizesCodeEditorAndPreview = useMemo(() => {
176177
const model = models.get(tab.file.path)
177178
const showPreview =
178-
(tab.file.isLocal && [previewTable, previewConsole].some(Boolean)) ||
179+
(tab.file.isLocal &&
180+
[previewTable, previewConsole, previewDiff].some(Boolean)) ||
179181
(tab.file.isSQLMeshModel && model != null)
180182

181183
return showPreview ? [70, 30] : [100, 0]
182-
}, [tab, models, previewConsole, previewTable])
184+
}, [tab, models, previewConsole, previewTable, previewDiff])
183185

184186
const keymaps: KeyBinding[] = useMemo(
185187
() =>

0 commit comments

Comments
 (0)