Skip to content

Commit

Permalink
Merge pull request #40 from galv-team/demo-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
mjaquiery authored Jan 21, 2025
2 parents f51e33b + 97809c4 commit 775cc82
Show file tree
Hide file tree
Showing 13 changed files with 151 additions and 74 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,24 @@ To deploy the frontend, you will need to set the following environment variables
You can set these variables either by editing the Dockerfile, or by passing them in as arguments to `docker run` or `docker-compose up`.
If you're using `docker-compose`, you can set them in the `environment` section of the `frontend` service in the `docker-compose.yml` file.

### Demo instance

A demo instance of the frontend is available at [galv-demo.fly.dev](https://galv-demo.fly.dev/).
This can be updated by running:

```bash
fly deploy --app galv-demo --config fly.demo.toml
```

If for some reason it needs to be recreated:

```bash
fly launch --name galv-demo --org oxrse --region lhr --config fly.demo.toml
```

You can copy the config, which should not need adjustment.
It will create you a `.github/workflows/fly.yml` file, which you should delete rather than committing because otherwise it will try to deploy using the main `fly.toml` file each time a commit is made to the primary branch; probably not what we want.

## Development

Development is most easily done by using the provided Dockerfile and docker-compose.yml files. The docker-compose.yml file will start a postgres database and the Django server. The Django server will automatically reload when changes are made to the code.
Expand Down
24 changes: 24 additions & 0 deletions fly.demo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# fly.toml app configuration file generated for galv-demo on 2025-01-17T14:49:31Z
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = 'galv-demo'
primary_region = 'lhr'

[build]
[build.args]
VITE_GALV_API_BASE_URL = "https://galv-demo-backend.fly.dev"

[http_service]
internal_port = 80
force_https = true
auto_stop_machines = 'stop'
auto_start_machines = true
min_machines_running = 0
processes = ['app']

[[vm]]
cpu_kind = 'shared'
cpus = 1
memory_mb = 2048
2 changes: 1 addition & 1 deletion fly.stage.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ primary_region = "lhr"
[[vm]]
cpu_kind = "shared"
cpus = 1
memory_mb = 1024
memory_mb = 2048
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@
"cypress:e2e": "start-server-and-test 'pnpm start --port 8002' http://localhost 'pnpm cypress:run'",
"storybook": "storybook dev -p 6006 --no-open",
"build-storybook": "storybook build",
"prepare": "husky"
"prepare": "husky",
"deploy-demo": "fly deploy --app galv-demo --config fly.demo.toml"
},
"eslintConfig": {
"extends": [
Expand Down
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export function Core() {
)

const mainListItems = (
<Stack>
<Stack className={classes.drawerMenu}>
<ListItemButton
key="dashboard"
selected={pathIs(PATHS.DASHBOARD)}
Expand Down
3 changes: 2 additions & 1 deletion src/Components/AxiosErrorAlert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default function AxiosErrorAlert({
error.response?.data instanceof Array
? Object.fromEntries(
error.response?.data.map((e: string, i: number) => [
`_${i}`,
`Error ${i + 1}`,
e,
]),
)
Expand Down Expand Up @@ -69,6 +69,7 @@ export default function AxiosErrorAlert({
{non_field_errors[0]}
</Alert>
)

const title =
alertTitle === false
? null
Expand Down
1 change: 0 additions & 1 deletion src/Components/CardActionBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ export default function CardActionBar(props: CardActionBarProps) {
const { classes, theme } = UseStyles()
const { apiResource } = useApiResource()
const iconProps: Partial<SvgIconProps> = {
fontSize: 'large',
...props.iconProps,
}
const selectable = props.selectable ?? typeof apiResource?.id === 'string'
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Mapping.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ function MappingTable({
)
})}
</TableRow>
{longest_column.map((arr, i) => {
{longest_column.map((_arr, i) => {
if (i >= dataRows) return null
return (
<TableRow
Expand Down
104 changes: 65 additions & 39 deletions src/Components/ResourceCreator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,14 @@ import {
} from './TypeValueNotation'
import { useAttachmentUpload } from './AttachmentUploadContext'
import {
useFetchResource,
CreateMutationVariablesType,
useFetchResource,
} from './FetchResourceContext'
import Alert from '@mui/material/Alert'
import AxiosErrorAlert from './AxiosErrorAlert'
import Collapse from '@mui/material/Collapse'
import { Link, useNavigate } from 'react-router-dom'
import CardActions from '@mui/material/CardActions'

type TokenCreatorProps = {
setModalOpen: (open: boolean) => void
Expand Down Expand Up @@ -158,9 +159,7 @@ export function TokenCreator({
<Button
variant="contained"
color="success"
onClick={() =>
create_mutation.mutate({ name, ttl: getTTL() })
}
onClick={() => create_mutation.mutate({ name, ttl: getTTL() })}
disabled={name === ''}
>
Create
Expand Down Expand Up @@ -235,8 +234,8 @@ export function TokenCreator({
export type ResourceCreatorProps = {
lookupKey: LookupKey
initial_data?: object
onCreate: (new_resource_url?: string, error?: unknown) => void
onDiscard: () => void
onCreate?: (new_resource_url?: string, error?: unknown) => void
onDiscard?: () => void
} & CardProps

export function ResourceCreator<T extends GalvResource>({
Expand Down Expand Up @@ -321,6 +320,7 @@ export function ResourceCreator<T extends GalvResource>({

const create_mutation = useCreateQuery<T>(lookupKey, {
after_cache: (data, variables) => {
console.log('Created', { data, variables })
if (data === undefined) {
console.warn('No data in mutation response', {
data,
Expand All @@ -345,7 +345,7 @@ export function ResourceCreator<T extends GalvResource>({
})
// Also invalidate autocomplete cache because we may have updated options
queryClient.invalidateQueries({ queryKey: ['autocomplete'] })
onCreate((data.data.url as string) ?? undefined)
onCreate && onCreate((data.data.url as string) ?? undefined)
},
on_error: (error, variables) => {
console.error(error, { variables })
Expand All @@ -358,11 +358,25 @@ export function ResourceCreator<T extends GalvResource>({
if (error) {
setError(error as AxiosError)
} else {
onCreate(new_data_url)
onCreate && onCreate(new_data_url)
}
},
)

const handleSave = () => {
if (lookupKey === LOOKUP_KEYS.ARBITRARY_FILE) {
create_attachment_mutation.mutate({
...clean(UndoRedo.current),
file,
} as unknown as ArbitraryFilesApiArbitraryFilesCreateRequest)
} else {
create_mutation.mutate(
clean(UndoRedo.current) as CreateMutationVariablesType<T>,
)
}
return false // Close action handled by mutation success callback
}

// The card action bar controls the expanded state and editing state
const action = (
<CardActionBar
Expand All @@ -376,29 +390,15 @@ export function ResourceCreator<T extends GalvResource>({
onRedo={UndoRedo.redo}
undoable={UndoRedo.can_undo}
redoable={UndoRedo.can_redo}
onEditSave={() => {
if (lookupKey === LOOKUP_KEYS.ARBITRARY_FILE) {
create_attachment_mutation.mutate({
...clean(UndoRedo.current),
file,
} as unknown as ArbitraryFilesApiArbitraryFilesCreateRequest)
} else {
create_mutation.mutate(
clean(
UndoRedo.current,
) as CreateMutationVariablesType<T>,
)
}
return false // Close action handled by mutation success callback
}}
onEditSave={handleSave}
onEditDiscard={() => {
if (
UndoRedo.can_undo &&
!window.confirm('Discard all changes?')
)
return false
UndoRedo.reset()
onDiscard()
onDiscard && onDiscard()
return true
}}
/>
Expand Down Expand Up @@ -456,6 +456,16 @@ export function ResourceCreator<T extends GalvResource>({
}
/>
)}

<CardActions>
<Button
variant="contained"
color="success"
onClick={handleSave}
>
Create
</Button>
</CardActions>
</CardContent>
)

Expand Down Expand Up @@ -549,24 +559,40 @@ export default function WrappedResourceCreator<T extends GalvResource>(
/>
) : (
<ResourceCreator<T>
{...props}
onCreate={(url, err) => {
if (
props.lookupKey === LOOKUP_KEYS.LAB &&
!user?.is_lab_admin
)
refresh_user()
setModalOpen(!!err)
if (url) {
const components =
get_url_components(url)
if (components)
navigate(
`${PATHS[components.lookupKey]}/${components.resourceId}/`,
)
console.log('Created', { url, err })
const p = props as {
lookupKey: LookupKey
} & ResourceCreatorProps
if (p.onCreate) {
p.onCreate(url, err)
} else {
if (
props.lookupKey ===
LOOKUP_KEYS.LAB &&
!user?.is_lab_admin
)
refresh_user()
setModalOpen(!!err)
if (url) {
const components =
get_url_components(url)
if (components)
navigate(
`${PATHS[components.lookupKey]}/${components.resourceId}/`,
)
}
}
setModalOpen(false)
}}
onDiscard={() => {
const p = props as {
lookupKey: LookupKey
} & ResourceCreatorProps
if (p.onDiscard) p.onDiscard()
setModalOpen(false)
}}
onDiscard={() => setModalOpen(false)}
{...props}
/>
)}
</ErrorBoundary>
Expand Down
14 changes: 2 additions & 12 deletions src/Components/ResourceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,7 @@ export function ResourceList<T extends GalvResource>({
</Button>
</>
)}
{user && (<>
{' '}
Why not get started by creating something?
</>)}
{user && <> Why not get started by creating something?</>}
</Typography>
)
}
Expand Down Expand Up @@ -147,18 +144,11 @@ export function ResourceList<T extends GalvResource>({
<ClientCodeDemo fileQueryLimit={itemsPerPage} />
)}
{content}
<ResourceCreator
key={'creator'}
lookupKey={lookupKey}
onCreate={() => {}}
onDiscard={() => {}}
/>
<ResourceCreator key={'creator'} lookupKey={lookupKey} />
{get_has_family(lookupKey) && (
<ResourceCreator
key={'family_creator'}
lookupKey={FAMILY_LOOKUP_KEYS[lookupKey]}
onCreate={() => {}}
onDiscard={() => {}}
/>
)}
</Stack>
Expand Down
26 changes: 20 additions & 6 deletions src/UserLogin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ import {
} from '@tanstack/react-query'
import Stack from '@mui/material/Stack'
import {
User,
UserRequest,
UsersApi,
ActivateApi,
Configuration,
ForgotPasswordApi,
ResetPasswordApi,
Configuration,
User,
UserRequest,
UsersApi,
} from '@galv/galv'
import { AxiosError, AxiosResponse } from 'axios'
import Alert, { AlertColor } from '@mui/material/Alert'
Expand Down Expand Up @@ -203,16 +203,22 @@ function RegisterForm({
export function ActivationForm({
_username,
onSuccess,
initialResult,
initialStatus,
}: {
_username: string
onSuccess?: () => void
initialResult?: string
initialStatus?: AlertColor
}) {
const [username, setUsername] = useState<string>(_username)
const [code, setCode] = useState<string>('')
const [result, setResult] = useState<string>(
'Please check your email for an activation code from Galv.',
initialResult ?? 'Enter your activation code',
)
const [status, setStatus] = useState<AlertColor | undefined>(
initialStatus ?? 'info',
)
const [status, setStatus] = useState<AlertColor | undefined>('success')

const { api_config } = useCurrentUser()

Expand Down Expand Up @@ -318,6 +324,8 @@ export function RegistrationForm() {
const [tab, setTab] = useState<number>(0)
const [username, setUsername] = useState<string>('')
const [password, setPassword] = useState<string>('')
const [initialResult, setInitialResult] = useState<string | undefined>()
const [initialStatus, setInitialStatus] = useState<AlertColor | undefined>()

return (
<Box sx={{ width: '100%' }}>
Expand All @@ -337,6 +345,10 @@ export function RegistrationForm() {
setUsername(data.data.username)
setPassword(password)
setTab(1)
setInitialResult(
'Please check your email for an activation code from Galv.',
)
setInitialStatus('success')
}}
/>
</CustomTabPanel>
Expand All @@ -349,6 +361,8 @@ export function RegistrationForm() {
setLoginFormOpen(false)
}, 1000)
}
initialResult={initialResult}
initialStatus={initialStatus}
/>
</CustomTabPanel>
</Box>
Expand Down
Loading

0 comments on commit 775cc82

Please sign in to comment.