Skip to content

Commit 007090b

Browse files
committed
making progress on vscode lineage
1 parent 121a580 commit 007090b

44 files changed

Lines changed: 21525 additions & 58 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package-lock.json

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vscode/react/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"@tailwindcss/vite": "^4.1.3",
1616
"@tanstack/react-router": "^1.114.3",
1717
"@tanstack/react-router-devtools": "^1.114.3",
18+
"@tanstack/react-virtual": "^3.13.6",
1819
"@tanstack/router-plugin": "^1.114.3",
1920
"apache-arrow": "^19.0.1",
2021
"react": "^19.0.0",

vscode/react/src/api/index.ts

Lines changed: 8 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ export type UseQueryWithTimeoutOptions<
4444
}
4545

4646
export function useApiMeta(
47-
): UseQueryWithTimeoutOptions<Meta> {
48-
return useQueryWithTimeout(
47+
): UseQueryResult<Meta> {
48+
return useQuery(
4949
{
5050
queryKey: ['/api/meta'],
5151
queryFn: getApiMetaApiMetaGet,
@@ -55,8 +55,8 @@ export function useApiMeta(
5555
}
5656

5757
export function useApiModels(
58-
): UseQueryWithTimeoutOptions<GetModelsApiModelsGet200> {
59-
return useQueryWithTimeout(
58+
): UseQueryResult<GetModelsApiModelsGet200> {
59+
return useQuery(
6060
{
6161
queryKey: ['/api/models'],
6262
queryFn: getModelsApiModelsGet,
@@ -66,8 +66,8 @@ export function useApiModels(
6666

6767
export function useApiModel(
6868
modelName: string,
69-
): UseQueryWithTimeoutOptions<Model> {
70-
return useQueryWithTimeout(
69+
): UseQueryResult<Model> {
70+
return useQuery(
7171
{
7272
queryKey: ['/api/models', modelName],
7373
queryFn: async ({ signal }) =>
@@ -94,8 +94,8 @@ export function useApiColumnLineage(
9494
model: string,
9595
column: string,
9696
params?: ColumnLineageApiLineageModelNameColumnNameGetParams,
97-
): UseQueryWithTimeoutOptions<ColumnLineageApiLineageModelNameColumnNameGet200> {
98-
return useQueryWithTimeout(
97+
): UseQueryResult<ColumnLineageApiLineageModelNameColumnNameGet200> {
98+
return useQuery(
9999
{
100100
queryKey: ['/api/lineage', model, column],
101101
queryFn: async ({ signal }) =>
@@ -110,45 +110,3 @@ export function useApiColumnLineage(
110110
},
111111
)
112112
}
113-
114-
function useQueryWithTimeout<
115-
TQueryFnData = unknown,
116-
TError extends ApiExceptionPayload = ApiExceptionPayload,
117-
TData = TQueryFnData,
118-
TQueryKey extends QueryKey = QueryKey,
119-
>(
120-
options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey> & {
121-
meta?: ApiQueryMeta
122-
queryKey: TQueryKey
123-
},
124-
): UseQueryWithTimeoutOptions<TData, TError> {
125-
async function queryFn(...args: any[]): Promise<TQueryFnData> {
126-
return (options.queryFn as (...args: any[]) => Promise<TQueryFnData>)(
127-
...args,
128-
)
129-
}
130-
131-
const q = useQuery<TQueryFnData, TError, TData, TQueryKey>({
132-
cacheTime: 0,
133-
enabled: false,
134-
queryKey: options.queryKey,
135-
queryFn,
136-
meta: {
137-
...options.meta,
138-
},
139-
})
140-
141-
return {
142-
...q,
143-
refetch: async (...args: any[]) =>
144-
new Promise(resolve => {
145-
q.refetch(...args, { throwOnError: true })
146-
.then(resolve)
147-
.catch(err => err)
148-
}),
149-
cancel: () => {
150-
console.log('cancel')
151-
},
152-
isTimeout: false,
153-
}
154-
}
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
import React from 'react'
2+
import clsx from 'clsx'
3+
import {
4+
EnumSize,
5+
type Size,
6+
type Variant,
7+
type EnumVariant,
8+
} from '@/style/variants'
9+
10+
/**
11+
* Utility type that restricts a type T to only include keys from type K
12+
* This allows for creating a subset of a union type
13+
*/
14+
export type Subset<T, K extends T> = T extends K ? T : never
15+
16+
17+
export type ButtonVariant = Subset<
18+
Variant,
19+
| typeof EnumVariant.Primary
20+
| typeof EnumVariant.Secondary
21+
| typeof EnumVariant.Success
22+
| typeof EnumVariant.Danger
23+
| typeof EnumVariant.Warning
24+
| typeof EnumVariant.Alternative
25+
| typeof EnumVariant.Neutral
26+
| typeof EnumVariant.Info
27+
>
28+
29+
export type ButtonSize = Subset<
30+
Size,
31+
| typeof EnumSize.xs
32+
| typeof EnumSize.sm
33+
| typeof EnumSize.md
34+
| typeof EnumSize.lg
35+
>
36+
37+
export const EnumButtonShape = {
38+
Square: 'square',
39+
Rounded: 'rounded',
40+
Circle: 'circle',
41+
Pill: 'pill',
42+
} as const
43+
44+
export const EnumButtonFormat = {
45+
Solid: 'solid',
46+
Outline: 'outline',
47+
Ghost: 'ghost',
48+
Link: 'link',
49+
} as const
50+
51+
export type ButtonShape = (typeof EnumButtonShape)[keyof typeof EnumButtonShape]
52+
export type ButtonFormat =
53+
(typeof EnumButtonFormat)[keyof typeof EnumButtonFormat]
54+
55+
export interface PropsButton
56+
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
57+
variant?: ButtonVariant
58+
size?: ButtonSize
59+
shape?: ButtonShape
60+
format?: ButtonFormat
61+
value?: string
62+
form?: string
63+
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void
64+
}
65+
66+
const VARIANT = new Map<ButtonVariant, string>([
67+
[
68+
'primary',
69+
'border-primary-500 bg-primary-500 hover:bg-primary-400 active:bg-primary-400 text-light',
70+
],
71+
[
72+
'alternative',
73+
'border-neutral-300 bg-neutral-5 hover:bg-neutral-20 active:bg-neutral-200 text-neutral-600',
74+
],
75+
[
76+
'secondary',
77+
'border-secondary-500 bg-secondary-500 hover:bg-secondary-600 active:bg-secondary-400 text-neutral-100',
78+
],
79+
[
80+
'success',
81+
'border-success-500 bg-success-500 hover:bg-success-600 active:bg-success-400 text-neutral-100',
82+
],
83+
[
84+
'danger',
85+
'border-danger-500 bg-danger-500 hover:bg-danger-600 active:bg-danger-400 text-neutral-100',
86+
],
87+
[
88+
'warning',
89+
'border-warning-500 bg-warning-500 hover:bg-warning-600 active:bg-warning-400 text-neutral-100',
90+
],
91+
[
92+
'neutral',
93+
'border-neutral-200 bg-neutral-200 hover:bg-neutral-300 active:bg-neutral-300 text-primary-900',
94+
],
95+
[
96+
'info',
97+
'border-transparent bg-neutral-10 dark:bg-neutral-20 active:bg-neutral-10 text-neutral-700 dark:text-neutral-200',
98+
],
99+
])
100+
101+
const SHAPE = new Map<ButtonShape, string>([
102+
['rounded', `rounded-md`],
103+
['square', `rounded-none`],
104+
['circle', `rounded-full`],
105+
])
106+
107+
const SIZE = new Map<ButtonSize, string>([
108+
[EnumSize.xs, `text-xs leading-2 border`],
109+
[EnumSize.sm, `px-2 py-[0.125rem] text-xs leading-4 border-2`],
110+
[EnumSize.md, `px-3 py-2 text-base leading-6 border-2`],
111+
[EnumSize.lg, `px-4 py-3 text-lg border-4`],
112+
])
113+
114+
const Button = makeButton(
115+
React.forwardRef<HTMLButtonElement, PropsButton>(ButtonPlain),
116+
)
117+
118+
const ButtonLink = makeButton(
119+
React.forwardRef<HTMLDivElement, PropsButton>(ButtonLinkPlain),
120+
)
121+
122+
export { VARIANT, SHAPE, SIZE, Button, ButtonLink, makeButton }
123+
124+
function ButtonPlain(
125+
{
126+
type = 'button',
127+
disabled = false,
128+
children = [],
129+
form,
130+
autoFocus,
131+
tabIndex,
132+
onClick,
133+
className,
134+
}: PropsButton,
135+
ref?: React.ForwardedRef<HTMLButtonElement>,
136+
): JSX.Element {
137+
return (
138+
<button
139+
ref={ref}
140+
type={type}
141+
autoFocus={autoFocus}
142+
tabIndex={tabIndex}
143+
form={form}
144+
disabled={disabled}
145+
onClick={onClick}
146+
onKeyDown={(e: React.KeyboardEvent<HTMLButtonElement>) => {
147+
if (e.key === 'Enter' || e.key === ' ') {
148+
e.preventDefault()
149+
e.stopPropagation()
150+
151+
onClick?.(e as unknown as React.MouseEvent<HTMLButtonElement>)
152+
}
153+
}}
154+
className={className}
155+
>
156+
{children}
157+
</button>
158+
)
159+
}
160+
161+
function ButtonLinkPlain(
162+
{ children = [], autoFocus, tabIndex, className }: PropsButton,
163+
ref?: React.ForwardedRef<HTMLDivElement>,
164+
): JSX.Element {
165+
return (
166+
<div
167+
ref={ref}
168+
autoFocus={autoFocus}
169+
tabIndex={tabIndex}
170+
className={className}
171+
>
172+
{children}
173+
</div>
174+
)
175+
}
176+
177+
function makeButton<TElement = HTMLButtonElement>(
178+
Component: React.ElementType,
179+
): React.ForwardRefExoticComponent<
180+
PropsButton & React.RefAttributes<TElement>
181+
> {
182+
return React.forwardRef<TElement, PropsButton>(function Wrapper(
183+
{
184+
type = 'button',
185+
disabled = false,
186+
variant = 'primary',
187+
shape = 'rounded',
188+
size = EnumSize.md,
189+
children = [],
190+
className,
191+
form,
192+
autoFocus,
193+
tabIndex,
194+
onClick,
195+
}: PropsButton,
196+
ref?: React.ForwardedRef<TElement>,
197+
): JSX.Element {
198+
return (
199+
<Component
200+
ref={ref}
201+
type={type}
202+
disabled={disabled}
203+
form={form}
204+
autoFocus={autoFocus}
205+
tabIndex={tabIndex}
206+
onClick={onClick}
207+
className={clsx(
208+
'whitespace-nowrap flex m-1 items-center justify-center font-bold',
209+
'focus:ring-4 focus:outline-none focus:border-secondary-500',
210+
'ring-secondary-300 ring-opacity-60 ring-offset ring-offset-secondary-100',
211+
SHAPE.get(shape),
212+
SIZE.get(size),
213+
disabled
214+
? 'opacity-50 bg-neutral-10 dark:bg-neutral-20 border-transparent text-prose cursor-not-allowed'
215+
: VARIANT.get(variant),
216+
className,
217+
)}
218+
>
219+
{children}
220+
</Component>
221+
)
222+
})
223+
}

0 commit comments

Comments
 (0)