Skip to content

Commit

Permalink
fix/app list (#45)
Browse files Browse the repository at this point in the history
* fix: linting

* feat: alert UI component

* feat: Add base path to API configuration

* fix: error handling

* fix: dynamic workbench & app creation
  • Loading branch information
nicedexter authored Sep 30, 2024
1 parent 12c4296 commit 06cf7cb
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 45 deletions.
26 changes: 5 additions & 21 deletions src/components/actions/app-instance-view-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,8 @@ export async function appInstanceCreate(
const repository = await getRepository()
const useCase = new AppInstanceCreate(repository)

const id = formData.get('id') as string
let appId = ''
switch (id) {
case 'vscode':
appId = '2'
break
case 'arx':
appId = '3'
break
case 'jupyterlab':
appId = '5'
break
default:
appId = '4'
}

const appInstance: AppInstanceCreateModel = {
appId,
appId: formData.get('id') as string,
tenantId: formData.get('tenantId') as string,
ownerId: formData.get('ownerId') as string,
workspaceId: formData.get('workspaceId') as string,
Expand All @@ -65,16 +49,16 @@ export async function appInstanceCreate(
}

const nextAppInstance = AppInstanceCreateSchema.parse(appInstance)

console.log('appInstance', nextAppInstance)

const createdAppInstance = await useCase.execute(nextAppInstance)

console.log('createdAppInstance', createdAppInstance)
if (createdAppInstance.error) {
return { error: createdAppInstance.error }
}

revalidatePath(
`/workspaces/${formData.get('workspaceId')}/${formData.get('workbenchId')}`
)

return {
...prevState,
data: 'Successfully created appInstance',
Expand Down
23 changes: 5 additions & 18 deletions src/components/actions/workbench-view-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export async function workbenchCreate(
const useCase = new WorkbenchCreate(repository)

const workbench: WorkbenchCreateModel = {
name: formData.get('name') as string,
name: formData.get('id') as string,
tenantId: formData.get('tenantId') as string,
ownerId: formData.get('ownerId') as string,
description: formData.get('description') as string,
Expand All @@ -92,28 +92,15 @@ export async function workbenchCreate(
const nextWorkbench = WorkbenchCreateSchema.parse(workbench)
const createdWorkbench = await useCase.execute(nextWorkbench)

await delay(10 * 1000)
await delay(5 * 1000)

if (createdWorkbench.error) {
return { error: createdWorkbench.error }
}

revalidatePath('/')
revalidatePath(`/workspaces/${formData.get('workspaceId')}`)

let appId = ''
switch (workbench.name) {
case 'vscode':
appId = '2'
break
case 'arx':
appId = '3'
break
case 'jupyterlab':
appId = '5'
break
default:
appId = '4'
}
const appId = formData.get('id') as string

const appFormData = new FormData()
appFormData.set('tenantId', workbench.tenantId)
Expand All @@ -122,7 +109,7 @@ export async function workbenchCreate(
appFormData.set('workspaceId', workbench.workspaceId)
appFormData.set('workbenchId', createdWorkbench?.data?.id || '')

const app = await appInstanceCreate(prevState, appFormData)
await appInstanceCreate(prevState, appFormData)

return {
...prevState,
Expand Down
15 changes: 14 additions & 1 deletion src/components/forms/app-instance-forms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ import {
import { Input } from '~/components/ui/input'
import { Label } from '~/components/ui/label'
import { App } from '~/domain/model'
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'

import { appList } from '../actions/app-view-model'
import { IFormState } from '../actions/utils'
import { Icons } from '../ui/icons'
import { Textarea } from '../ui/textarea'
import { TriangleAlert } from 'lucide-react'

const initialState: IFormState = {
data: undefined,
Expand Down Expand Up @@ -61,13 +63,17 @@ export function AppInstanceCreateForm({
)
const [open, setOpen] = useState(false)
const [apps, setApps] = useState<App[]>([])
const [error, setError] = useState<string>()

useEffect(() => {
appList().then((res) => {
if (res.error) {
setError(res.error)
return
}

if (!res.data) {
setError('There is no apps available')
return
}

Expand Down Expand Up @@ -107,6 +113,13 @@ export function AppInstanceCreateForm({
</CardDescription>
</CardHeader>
<CardContent className="grid gap-4">
{error && (
<Alert variant="destructive">
<TriangleAlert className="h-4 w-4" />
<AlertTitle>Error</AlertTitle>
<AlertDescription>{error}</AlertDescription>
</Alert>
)}
<div className="grid gap-2">
{/* <Label htmlFor="name">Name</Label>
<Input id="name" name="name" placeholder="Enter workbench name" /> */}
Expand All @@ -115,7 +128,7 @@ export function AppInstanceCreateForm({
<select name="id" id="id">
<option value="">Choose an app</option>
{apps.map((app) => (
<option key={app.id} value={app.name}>
<option key={app.id} value={app.id}>
{app.name}
</option>
))}
Expand Down
20 changes: 16 additions & 4 deletions src/components/forms/workbench-forms.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import { useEffect, useState } from 'react'
import { ArrowRight } from 'lucide-react'
import { ArrowRight, TriangleAlert } from 'lucide-react'
import { useFormState, useFormStatus } from 'react-dom'

import {
Expand Down Expand Up @@ -32,6 +32,7 @@ import { App } from '~/domain/model'
import { appList } from '../actions/app-view-model'
import { IFormState } from '../actions/utils'
import { Textarea } from '../ui/textarea'
import { Alert, AlertTitle, AlertDescription } from '../ui/alert'

const initialState: IFormState = {
data: undefined,
Expand Down Expand Up @@ -72,13 +73,17 @@ export function WorkbenchCreateForm({
)
const [open, setOpen] = useState(false)
const [apps, setApps] = useState<App[]>([])
const [error, setError] = useState<string>()

useEffect(() => {
appList().then((res) => {
if (res.error) {
setError(res.error)
return
}

if (!res.data) {
setError('There is no apps available')
return
}

Expand Down Expand Up @@ -118,12 +123,19 @@ export function WorkbenchCreateForm({
</CardDescription>
</CardHeader>
<CardContent className="grid gap-4">
{error && (
<Alert variant="destructive">
<TriangleAlert className="h-4 w-4" />
<AlertTitle>Error</AlertTitle>
<AlertDescription>{error}</AlertDescription>
</Alert>
)}
<div className="grid gap-2">
{/* <Label htmlFor="name">Name</Label>
<Input id="name" name="name" placeholder="Enter workbench name" /> */}
<Input id="name" name="name" placeho lder="Enter workbench name" /> */}
<div className="grid gap-3">
<Label htmlFor="name">Name</Label>
<select name="name" id="name">
<select name="id" id="id">
<option value="">Choose an app</option>
{apps.map((app) => (
<option key={app.id} value={app.name}>
Expand All @@ -134,7 +146,7 @@ export function WorkbenchCreateForm({
</div>
<div className="text-xs text-red-500">
{
state?.issues?.find((e) => e.path.includes('name'))
state?.issues?.find((e) => e.path.includes('id'))
?.message
}
</div>
Expand Down
59 changes: 59 additions & 0 deletions src/components/ui/alert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import * as React from 'react'
import { cva, type VariantProps } from 'class-variance-authority'

import { cn } from '~/lib/utils'

const alertVariants = cva(
'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground',
{
variants: {
variant: {
default: 'bg-background text-foreground',
destructive:
'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive'
}
},
defaultVariants: {
variant: 'default'
}
}
)

const Alert = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
>(({ className, variant, ...props }, ref) => (
<div
ref={ref}
role="alert"
className={cn(alertVariants({ variant }), className)}
{...props}
/>
))
Alert.displayName = 'Alert'

const AlertTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h5
ref={ref}
className={cn('mb-1 font-medium leading-none tracking-tight', className)}
{...props}
/>
))
AlertTitle.displayName = 'AlertTitle'

const AlertDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn('text-sm [&_p]:leading-relaxed', className)}
{...props}
/>
))
AlertDescription.displayName = 'AlertDescription'

export { Alert, AlertTitle, AlertDescription }
4 changes: 3 additions & 1 deletion src/data/data-source/chorus-api/app-api-data-source-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AppServiceApi, ChorusApp } from '~/internal/client'
import { Configuration } from '~/internal/client'

import { AppDataSource } from '../app-data-source'
import { env } from '~/env'

// see src/internal/client/models/ChorusApp.ts
export const AppApiCreateSchema = z.object({
Expand Down Expand Up @@ -47,7 +48,8 @@ class AppDataSourceImpl implements AppDataSource {

constructor(token: string) {
this.configuration = new Configuration({
apiKey: `Bearer ${token}`
apiKey: `Bearer ${token}`,
basePath: env.DATA_SOURCE_API_URL
})
this.service = new AppServiceApi(this.configuration)
}
Expand Down

0 comments on commit 06cf7cb

Please sign in to comment.