Compare commits

...

32 Commits

Author SHA1 Message Date
github-actions[bot]
6921526cf5 chore: update versions (#3221)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @nhost/apollo@8.0.6

### Patch Changes

-   @nhost/nhost-js@3.2.6

## @nhost/react-apollo@17.0.2

### Patch Changes

-   Updated dependencies [ad57a9e]
    -   @nhost/react@3.10.2
    -   @nhost/apollo@8.0.6

## @nhost/react-urql@14.0.2

### Patch Changes

-   Updated dependencies [ad57a9e]
    -   @nhost/react@3.10.2

## @nhost/hasura-auth-js@2.10.2

### Patch Changes

-   ad57a9e: fix(auth): allow to pass custom headers to signup

## @nhost/nextjs@2.2.5

### Patch Changes

-   Updated dependencies [ad57a9e]
    -   @nhost/react@3.10.2

## @nhost/nhost-js@3.2.6

### Patch Changes

-   Updated dependencies [ad57a9e]
    -   @nhost/hasura-auth-js@2.10.2

## @nhost/react@3.10.2

### Patch Changes

-   ad57a9e: fix(auth): allow to pass custom headers to signup
    -   @nhost/nhost-js@3.2.6

## @nhost/vue@2.9.3

### Patch Changes

-   @nhost/nhost-js@3.2.6

## @nhost/dashboard@2.22.0

# @nhost/dashboard

## 2.17.0

### Minor Changes

-   fd59918: fix: redirect to 404 with nhost cli dashboard

## 2.16.0

### Minor Changes

-   f8e6b61: fix: can add rule groups in table permissions
-   9e404c8: fix: not redirect to 404 page if using local Nhost backend
-   ac4aa01: fix: can delete column in database page
-   4385524: fix: update url to check service health in local dashboard

### Patch Changes

-   @nhost/react-apollo@16.0.1
-   @nhost/nextjs@2.2.2

## 2.15.0

### Minor Changes

- f1052a8: fix: improve stability of the dashboard when pausing projects
-   30daa41: fix: update links to docs in overview page
-   7537237: feat: add image preview toggle in storage

## 2.14.0

### Minor Changes

- d43931e: fix: invalid organization slug/project subdomain doesn't open
404 page
- 5df6fa2: feat: add unencrypted disk warning in storage capacity
settings

### Patch Changes

-   44c1e17: chore: update `msw` to v1.3.5 to fix vulnerabilities
    -   @nhost/react-apollo@16.0.0
    -   @nhost/nextjs@2.2.1

## 2.13.0

### Minor Changes

- 21e90da: chore: remove restrictions on SMTP sender so My Name
[name@acme.com](mailto:name@acme.com) can be added
- 865dd93: fix: duplicate Run placeholders when there is an error in the
backend
- 6902a36: fix: can remove resources if postgres capacity is higher than
10
-   a535aa3: fix: fetch user roles locally in auth section
-   0c50816: fix: allow decimal numbers in database row insert
- aea6d18: chore: add warning when pausing a project about losing Run
services persistent volume data
- d3b4fc3: feat: allow to change postgres settings if project is paused
-   29d27e1: chore: update `next` to v14.2.22 to fix vulnerabilities
-   c9dca09: feat: add reset password form
-   b3bcacb: fix: paused project banner cannot read null project name

### Patch Changes

-   Updated dependencies [46fc520]
-   Updated dependencies [29d27e1]
    -   @nhost/nextjs@2.2.0
    -   @nhost/react-apollo@15.0.1

## 2.12.0

### Minor Changes

- eb95562: fix: show all available permission variables in permission
dropdown select

### Patch Changes

- 8b5c4a0: chore: cleanup layout and add disable duplicate atom key
checking in development mode

## 2.11.3

### Patch Changes

- 714dffa: fix: improve project polling logic and unify usage across
components

## 2.11.2

### Patch Changes

- 6a34f89: fix: improve project polling logic and unify usage across
components

## 2.11.1

### Patch Changes

-   0f6ce52: fix: consolidate useProject hook and fix jwt expired error

## 2.11.0

### Minor Changes

-   cea3ef5: Feat: add org and project placeholders

## 2.10.0

### Minor Changes

-   86ecf27: feat: add support for additional metrics in overview
- 21708be: feat: dashboard: add support for storage buckets to AI
assistants

## 1.30.0

### Minor Changes

- 50441a8: feat: add ui for project autoscaler settings and run services
autoscaler settings

## 1.29.0

### Minor Changes

-   55d8bb5: feat: integrate turnstile for signup verification
-   2a2e54c: fix: update docs url in run services form tooltip
- 18f942f: fix: display long error messages in error toast without
overflow

### Patch Changes

-   @nhost/react-apollo@13.0.0
-   @nhost/nextjs@2.1.22

## 1.28.2

### Patch Changes

- 52a38fe: chore: update dependencies to address security
vulnerabilities
-   Updated dependencies [52a38fe]
    -   @nhost/nextjs@2.1.21

## 1.28.1

### Patch Changes

-   9735fa2: chore: remove broken link

## 1.28.0

### Minor Changes

- 526183a: feat: allow filtering users in "make request as" in graphql
section
-   be3b85b: feat: add conceal errors toggle on auth settings page

### Patch Changes

- 35a2f12: fix: prevent run service details from opening when attempting
to delete
    -   @nhost/react-apollo@12.0.6
    -   @nhost/nextjs@2.1.20

## 1.27.0

### Minor Changes

-   a7cd02c: fix: resolve rate limit query

## 1.26.0

### Minor Changes

-   3773ad7: chore: update pricing information
- b63250d: fix: not allow run service creation form resubmission while
creating a run service
-   a44a1d4: feat: add rate limits settings page

### Patch Changes

-   @nhost/react-apollo@12.0.5
-   @nhost/nextjs@2.1.19

## 1.25.0

### Minor Changes

- d1ceede: feat: add setting to migrate postgres major and/or minor
versions
- e5d3d1a: fix: allow manually typing column for custom check in
database row permissions

### Patch Changes

-   @nhost/react-apollo@12.0.4
-   @nhost/nextjs@2.1.18

## 1.24.1

### Patch Changes

- 49f2e55: fix: use service subdomain in service form and service
details dialog
- 598b988: fix: use current project subdomain in ServiceDetailsDialog
component

## 1.24.0

### Minor Changes

-   abb24af: chore: add redirect to support page when project is locked
- 18a6455: feat: show contact us info and locked reason when project is
locked

### Patch Changes

-   e31eefa: fix: include ingresses field when updating run services

## 1.23.0

### Minor Changes

-   33284d3: fix: don't show double scrollbar in configuration editor

### Patch Changes

-   @nhost/react-apollo@12.0.3
-   @nhost/nextjs@2.1.17

## 1.22.0

### Minor Changes

-   998c037: fix: align drop-down list in select component
- 807b8c0: fix: show city name in region selection for project creation

## 1.21.0

### Minor Changes

- a2efeed: fix: improve project health error handling, add unknown state
and polling interval for health state

## 1.20.0

### Minor Changes

- 8ea4210: fix: error toasts can be closed individually, instead of
dismissing all toasts at once
- 58919ba: chore: add blink animation when project health service is
updating

## 1.19.0

### Minor Changes

- b519862: fix: get configuration in configuration editor using local
development environment

## 1.18.0

### Minor Changes

- 502abad: feat: add services health checks indicators to the overview
page
-   b3ff6ad: chore: update title text on service status modal
- dbadf59: feat: add project configuration TOML editor to the settings
page

## 1.17.0

### Minor Changes

- 77fba27: fix: postgres version validation when activating ai in ai
settings page
-   ac6d1b6: feat: use name instead of awsName

## 1.16.3

### Patch Changes

- 87a37cf: fix: remove unnecessary isPlatform check from verify button
disable logic on custom domains
    -   @nhost/react-apollo@12.0.2
    -   @nhost/nextjs@2.1.16

## 1.16.2

### Patch Changes

- a9413af: fix: update `GetAllWorkspacesAndProjects` query polling to
use exponential backoff
    -   @nhost/react-apollo@12.0.1
    -   @nhost/nextjs@2.1.15

## 1.16.1

### Patch Changes

-   @nhost/react-apollo@12.0.0
-   @nhost/nextjs@2.1.14

## 1.16.0

### Minor Changes

- c6d5c5c: feat: add toggle switch to enable/disable public access in
the database settings

## 1.15.2

### Patch Changes

-   @nhost/react-apollo@11.0.4
-   @nhost/nextjs@2.1.13

## 1.15.1

### Patch Changes

-   @nhost/react-apollo@11.0.3
-   @nhost/nextjs@2.1.12

## 1.15.0

### Minor Changes

-   a7bde37: feat: send metadata in the edit form

### Patch Changes

- 1bc615b: feat: improve error message handling in `ErrorToast`
component
    -   @nhost/react-apollo@11.0.2
    -   @nhost/nextjs@2.1.11

## 1.14.0

### Minor Changes

-   a448d7d: feat: allow configuring postmark and delete SMTP settings

## 1.13.3

### Patch Changes

-   5924bc3: fix: include password in `GetSmtpSettings` query
- c5ad634: fix: resolved an issue where one-click install links were
broken on Safari
- 7278991: fix: update graphql auto-embeddings configuration to use
String type for model field

## 1.13.2

### Patch Changes

-   026f84f: fix: use configuration server URL from environment variable

## 1.13.1

### Patch Changes

-   7e9a2ce: fix: resolve issue where run services form fails to open

## 1.13.0

### Minor Changes

-   dd5d262: feat: add model field to the auto-embeddings form
- 09962be: feat: enable settings and run services when running the
dashboard locally
- 9cdecb6: feat: enable users to update their email address from the
account settings page

## 1.12.2

### Patch Changes

-   c195c51: fix: send email upon signin for unverified users

## 1.12.1

### Patch Changes

- 93ebdf8: fix: use service urls when initilizaing NhostClient running
local dashboard
    -   @nhost/react-apollo@11.0.1
    -   @nhost/nextjs@2.1.10

## 1.12.0

### Minor Changes

- f242e4b: feat: add connect with github to the user's account settings
-   768ca17: chore: update dependencies
- d62bd0f: fix: "Track this" option within the SQL editor now correctly
updates the metadata
- 91c2bb6: feat: refactor sign-in and sign-up pages to enforce email
verification

### Patch Changes

-   943831f: fix: resolve an error toast issue when unpausing a project
-   Updated dependencies [768ca17]
    -   @nhost/react-apollo@11.0.0
    -   @nhost/nextjs@2.1.9

## 1.11.2

### Patch Changes

-   @nhost/react-apollo@10.0.2
-   @nhost/nextjs@2.1.8

## 1.11.1

### Patch Changes

-   981404f: fix: set default value for healthCheck field validation

## 1.11.0

### Minor Changes

- 7789469: chore: upgrade dependency `@graphql-codegen/cli` to `5.0.2`
to address vulnerability
- 6c11b75: feat: add update user displayName section in account settings

### Patch Changes

-   @nhost/react-apollo@10.0.1
-   @nhost/nextjs@2.1.7

## 1.10.0

### Minor Changes

-   49a80c2: chore: update dependencies
-   150c04a: feat: add healthcheck config to run services

### Patch Changes

- e03f141: fix: allow insert, update and delete on tables in `auth` and
`storage` schemas
- 28676f4: feat: add min postgres version check to enable the ai service
-   Updated dependencies [49a80c2]
    -   @nhost/react-apollo@10.0.0
    -   @nhost/nextjs@2.1.6

## 1.9.0

### Minor Changes

-   d86e5c9: feat: add support for filtering the logs using a RegExp

## 1.8.3

### Patch Changes

-   @nhost/react-apollo@9.0.3
-   @nhost/nextjs@2.1.5

## 1.8.2

### Patch Changes

- 6df4f02: fix: use custom error toast and show correct message when
sending an invite

## 1.8.1

### Patch Changes

-   @nhost/react-apollo@9.0.2
-   @nhost/nextjs@2.1.4

## 1.8.0

### Minor Changes

- 713d53c: feat: add catch-all route for workspace/project - useful for
documentation

### Patch Changes

-   3db2999: fix: refresh table list after running SQL using the editor
- 3c4dd55: fix: handle `Error` objects properly in the `ErrorToast`
component
- 92b434e: fix: resolve an issue where the checkbox in the data-grid
header did not select all rows
    -   @nhost/react-apollo@9.0.1
    -   @nhost/nextjs@2.1.3

## 1.7.0

### Minor Changes

-   0d8d0eb: Update docs and dashboard references

## 1.6.9

### Patch Changes

-   @nhost/react-apollo@9.0.0
-   @nhost/nextjs@2.1.2

## 1.6.8

### Patch Changes

-   @nhost/react-apollo@8.0.1
-   @nhost/nextjs@2.1.1

## 1.6.7

### Patch Changes

-   5ef5189: fix: update `@apollo/client` to `3.9.4` to fix a cache bug

## 1.6.6

### Patch Changes

-   3ba485e: fix: added discord.com to connect-src
-   e5bab6a: chore: update dependencies
-   Updated dependencies [b19ffed]
-   Updated dependencies [e5bab6a]
    -   @nhost/nextjs@2.1.0
    -   @nhost/react-apollo@8.0.0

## 1.6.5

### Patch Changes

- ba73bb4: fix: update ErrorToast component to show the internal graphql
error
- d5337ff: fix: utilize accumulator in the creation of validation schema
within data grid utils

## 1.6.4

### Patch Changes

-   7c2a1c2: feat: show error and debug info in the error toast

## 1.6.3

### Patch Changes

-   6b8aad5: fix: add bare nhost.run to CSP

## 1.6.2

### Patch Changes

-   b18edc0: feat: added CSP and X-Frame-Options

## 1.6.1

### Patch Changes

-   8d91f71: chore: update deps and enable pnpm audit
- 3b8473b: chore: update turbo to `1.11.3` and pnpm to `8.10.5` in
Dockerfile
-   Updated dependencies [8d91f71]
    -   @nhost/react-apollo@7.0.2
    -   @nhost/nextjs@2.0.2

## 1.6.0

### Minor Changes

-   3ff1c2b53: fix: show upgrade option for pro projects

## 1.5.0

### Minor Changes

-   c2ef17c0a: feat: add support for new Team plan

## 1.4.0

### Minor Changes

-   7883bbcbd: feat: don't show deprecated plans
- 44be6dc0a: feat: set redirectTo during sign-in to support preview
environments

### Patch Changes

- 3c3594898: fix: allow access to graphite when configured running in
local dashboard
-   32c246b7a: chore: update docs icon

## 1.3.2

### Patch Changes

-   174b4165b: chore: use env variables when running graphql codegen
-   7c977e714: chore: change `Allowed Roles` to `Default Allowed Roles`
-   46f028b9f: fix: remove hardcoded ai version setting

## 1.3.1

### Patch Changes

- af33c21d1: chore: remove backendUrl deprecation notice and remove all
references to `providersUpdated`

## 1.3.0

### Minor Changes

-   04784d880: Fix graphite's default version

## 1.2.0

### Minor Changes

-   5733162ed: feat: add settings and ui for graphite

## 1.1.0

### Minor Changes

-   e2b79b5ec: chore: remove sharp from deps

## 1.0.1

### Patch Changes

-   @nhost/react-apollo@7.0.1
-   @nhost/nextjs@2.0.1

## 1.0.0

### Major Changes

- bc9eff6e4: chore: remove support for using backendUrl when
instantiating the Nhost client

### Patch Changes

-   Updated dependencies [bc9eff6e4]
    -   @nhost/nextjs@2.0.0
    -   @nhost/react-apollo@7.0.0

## 0.21.1

### Patch Changes

-   97ced73a3: fix(dashboard): prevent dashboard from resolving secrets

## 0.21.0

### Minor Changes

- ed1a8d458: Update alert message on increasing PostgreSQL's volume
capacity
-   2e2248fd4: feat(dashboard): add SQL editor

## 0.20.28

### Patch Changes

-   7c2c31082: feat: add support for users to delete their account
    -   @nhost/react-apollo@6.0.1
    -   @nhost/nextjs@1.13.40

## 0.20.27

### Patch Changes

- fa79b7709: chore(dashboard): tweaks and fixes to the service form and
dialog
-   8df84d782: fix(dashboard): allow resetting custom domains
    -   @nhost/react-apollo@6.0.0
    -   @nhost/nextjs@1.13.39

## 0.20.26

### Patch Changes

- 331ba0376: feat(dashboard): add postgres storage capacity modifier in
the settings
-   b7f801874: feat(dashboard): add new settings page for custom domains

## 0.20.25

### Patch Changes

-   @nhost/react-apollo@5.0.38

## 0.20.24

### Patch Changes

-   e10389ecf: fix(dashboard): disable run tab when developing locally
    -   @nhost/react-apollo@5.0.37

## 0.20.23

### Patch Changes

-   c01568a7d: chore(dashboard): show alert to update oauth providers

## 0.20.22

### Patch Changes

-   c3efb7ec8: feat(dashboard): query latest announcement from platform

## 0.20.21

### Patch Changes

-   3e46d3873: chore: update link to node18 announcement

## 0.20.20

### Patch Changes

-   @nhost/react-apollo@5.0.36
-   @nhost/nextjs@1.13.38

## 0.20.19

### Patch Changes

-   75c4c8ae3: feat(dashboard): make env value input multiline

## 0.20.18

### Patch Changes

- 425d485f8: fix(dashboard): make sure dedicated resources pricing
follows total resources

## 0.20.17

### Patch Changes

-   ae324f67f: fix(dashboard): remove unused graphql fields

## 0.20.16

### Patch Changes

-   df5b4302c: chore(dashboard): remove run feature flag
- bf4a1f6c2: feat(dashboard): fetch auth, postgres, hasura and storage
versions from dashboard
- 34fc08ca7: fix(dashboard/run): show correct private registry in
service details
-   885d10620: chore(dashboard): change feedback to contact us

## 0.20.15

### Patch Changes

- ed16c8b5d: feat(run): add a confirmation dialog when deleting a run
service
- 216990888: fix(run): center loading indicator when selecting a project

## 0.20.14

### Patch Changes

-   9fbea9787: feat: add node18 announcement

## 0.20.13

### Patch Changes

- e84acf469: fix(run): handle subdomain undefined error when creating a
new service

## 0.20.12

### Patch Changes

-   b7c799d62: feat(run): add dialog to copy registry and URLs

## 0.20.11

### Patch Changes

-   8903e6abd: fix(dashboard): show correct egress limit in usage stats

## 0.20.10

### Patch Changes

- 666a75a23: feat(dashboard): add functions execution time and egress
volume to usage stats

## 0.20.9

### Patch Changes

-   5e1e80aa8: fix(dashboard): show correct locales in user details
    -   @nhost/react-apollo@5.0.35
    -   @nhost/nextjs@1.13.37

## 0.20.8

### Patch Changes

-   @nhost/react-apollo@5.0.34
-   @nhost/nextjs@1.13.36

## 0.20.7

### Patch Changes

-   4a7ede11e: fix: distinguish files that were not uploaded
- 202b64723: feat(nhost-run): add support for one-click-install run
services
- 074a0fa11: feat(dashboard): add settings toggle to enable/disable
antivirus
    -   @nhost/react-apollo@5.0.33
    -   @nhost/nextjs@1.13.35

## 0.20.6

### Patch Changes

-   b20761e97: feat(services): add pricing info and confirmation dialog
-   90df6d81d: fix(services): handle null values when editing a service
-   aa8508467: fix: query service logs correctly
    feat: enable multiline support for environment value input

## 0.20.5

### Patch Changes

-   8d7f84b8d: fix: make announcement adapt to theme

## 0.20.4

### Patch Changes

-   3b75bfce2: fix: make announcement close properly
- f49819075: fix: show correct values when dedicated resources are
disabled

## 0.20.3

### Patch Changes

-   e643bd362: fix(services): fix errors when config is null
-   bcdab66bf: feat: add annoucement for nhost run
-   f967a2e59: added note about storage not being able to be downsized
-   311c7756d: chore(services): consistent naming for compute

## 0.20.2

### Patch Changes

-   9073182d5: chore(dashboard): bump `turbo` to 1.10.11
-   ece717d6e: feat(logs): show services in the logs page
- 82b335311: feat(metrics): change grafana link to point to the
dashboards
- b135ef695: fix(services): set command as optional and set min replicas
to 0

## 0.20.1

### Patch Changes

-   3d5c34f4c: fix(auth): fix users pagination limit

## 0.20.0

### Minor Changes

-   c99d117d1: feat(services): add support for custom services

## 0.19.2

### Patch Changes

-   face99ccd: chore(deps): bump turbo version
-   cfe527307: style: tweak pull config warning in dark mode
- a9d7da8af: chore(deps): update dependency @types/pluralize to ^0.0.30
-   9aa4371ef: chore: add hasura-auth version 0.21.2
- d14e112bf: chore(deps): update dependency prettier-plugin-tailwindcss
to ^0.4.0
-   d3e8bb94a: chore(deps): update dependency vite-plugin-dts to v3

## 0.19.1

### Patch Changes

-   @nhost/react-apollo@5.0.32
-   @nhost/nextjs@1.13.34

## 0.19.0

### Minor Changes

- 9c61c69a7: chore(dashboard):add postgres 14.6-20230705-1 to the
version selector

### Patch Changes

-   47bda15ff: feat(settings): add warning to pull config

## 0.18.0

### Minor Changes

- ee0b9b8ed: chore(dashboard):add hasura v2.28.2 and v2.29.0 to the
version selector

## 0.17.20

### Patch Changes

-   @nhost/react-apollo@5.0.31
-   @nhost/nextjs@1.13.33

## 0.17.19

### Patch Changes

-   f866120a6: fix(users): use the password length from the config

## 0.17.18

### Patch Changes

-   @nhost/react-apollo@5.0.30
-   @nhost/nextjs@1.13.32

## 0.17.17

### Patch Changes

-   ea7b102c0: fix(pat): highlight expired tokens

## 0.17.16

### Patch Changes

- b3b64a3b7: chore(deps): bump `@types/react` to `v18.2.14` and
`@types/react-dom` to `v18.2.6`
-   32b221f94: chore(deps): bump `graphiql` to `v3`
-   3a56c12df: chore(deps): bump `turbo` to `v1.10.6`
-   Updated dependencies [b3b64a3b7]
    -   @nhost/react-apollo@5.0.29
    -   @nhost/nextjs@1.13.31

## 0.17.15

### Patch Changes

-   f41fdc12a: chore(deps): bump `turbo` to `1.10.5`
-   6199c1c55: fix(projects): don't redirect to 404 page
-   Updated dependencies [07a45fde0]
    -   @nhost/react-apollo@5.0.28
    -   @nhost/nextjs@1.13.30

## 0.17.14

### Patch Changes

- 80b22724d: chore(deps): bump `@types/react` to `v18.2.13`,
`@types/react-dom` to `v18.2.6` and `@storybook/testing-library` to
`v0.2.0`

## 0.17.13

### Patch Changes

-   cc02902cb: chore(docs): update environment variable documentation

## 0.17.12

### Patch Changes

-   660d339e1: fix(storybook): don't break storybook
-   660d339e1: fix(tests): prevent warnings during tests
    -   @nhost/react-apollo@5.0.27
    -   @nhost/nextjs@1.13.29

## 0.17.11

### Patch Changes

- bd4d0c270: chore(dashboard):add postgres 14.6-20230613-1 to the
version selector

## 0.17.10

### Patch Changes

-   c8c2a10b2: fix(database): don't break the password reset flow
- e70b45498: chore(deps): bump `@types/react` to `v18.2.12` and
`@types/react-dom` to `v18.2.5`

## 0.17.9

### Patch Changes

- 842055099: chore(deps): bump `turbo` to `v1.10.3` and `pnpm` to
`v8.6.2`
- fd12aa0a8: chore(projects): remove the postgres password input from
the project creation screen
-   022b76e78: chore(deps): bump `@types/react` to `v18.2.11`
-   3555ab2b7: chore(deps): bump `vitest` monorepo to `v0.32.0`
-   c43e54922: feat(backups): add download button to backups

## 0.17.8

### Patch Changes

-   d0457fe5c: feat(settings): improve the dashboard and config parity
    -   @nhost/react-apollo@5.0.26
    -   @nhost/nextjs@1.13.28

## 0.17.7

### Patch Changes

-   4f0368b95: fix(account): don't break account settings page

## 0.17.6

### Patch Changes

- 64a8f41d0: chore(resources): lower the maximum allowed resources per
service

## 0.17.5

### Patch Changes

-   @nhost/react-apollo@5.0.25
-   @nhost/nextjs@1.13.27

## 0.17.4

### Patch Changes

- 9b1d0f7a5: fix(deployments): use correct timestamp for deployment
details
-   6d2963ffa: chore(deps): bump `@types/react` to `v18.2.8`
- 8871267b9: chore(deps): downgrade `pnpm` to `v8.5.1` because of no
Turborepo support

## 0.17.3

### Patch Changes

-   01eeef9de: chore(misc): under the hood improvements
- 21e13db05: chore(deps): bump `@types/react` to `v18.2.7` and `turbo`
to `v1.10.1`
- f16433ae6: chore(secrets): allow empty secrets and environment
variables
-   aa3c62989: chore(cli): bump Nhost CLI version to v1.0
    -   @nhost/react-apollo@5.0.24
    -   @nhost/nextjs@1.13.26

## 0.17.2

### Patch Changes

-   88a4983f: chore(misc): under the hood improvements

## 0.17.1

### Patch Changes

-   9b0d4dde: feat(secrets): enable secrets

## 0.17.0

### Minor Changes

-   15d84a19: Add postgres 14.6-20230525

## 0.16.14

### Patch Changes

-   4c626174: chore: updated import paths, improved directory structure
-   cc047b71: chore(deps): bump `@fontsource` monorepo to `v5.0.0`
-   99edd012: feat(account): add support for personal access tokens

## 0.16.13

### Patch Changes

-   78c7109c: feat(settings): allow selecting service versions

## 0.16.12

### Patch Changes

- 399009d6: fix(gql): don't enter an infinite loop when fetching remote
app data
- 329e5a91: fix(deployments): use the same sorting of deployments
everywhere
- 6d559d6e: chore(settings): add under the hood improvements to the
settings page
- 12eb236c: chore(deps): bump `prettier-plugin-tailwindcss` to `v0.3.0`
-   f9b81a2a: chore(deps): bump `turbo` to `v1.9.8`
-   1345741b: fix(projects): don't redirect to 404 on project creation
-   Updated dependencies [7fea29a8]
    -   @nhost/react-apollo@5.0.23
    -   @nhost/nextjs@1.13.25

## 0.16.11

### Patch Changes

- 1230b722: fix(projects): don't redirect to 404 on when the project is
renamed
    -   @nhost/react-apollo@5.0.22
    -   @nhost/nextjs@1.13.24

## 0.16.10

### Patch Changes

-   Updated dependencies [da03bf39]
    -   @nhost/react-apollo@5.0.21
    -   @nhost/nextjs@1.13.23

## 0.16.9

### Patch Changes

- 349aac36: fix(settings): use region domain when constructing the
postgres connection string

## 0.16.8

### Patch Changes

- 20fb69fa: chore(projects): change the way how API URLs are constructed

## 0.16.7

### Patch Changes

- 49f9b837: chore(docker): bump `pnpm` to `v8.4.0` and `turbo` to
`v1.9.3`
- 3f478a4e: chore(deps): bump `vitest` to `v0.31.0`, `@types/react` to
`v18.2.6` and `@types/react-dom` to `v18.2.4`

## 0.16.6

### Patch Changes

- d926f156: fix(projects): redirect to 404 when an invalid project is
opened
- 49b99728: fix(projects): disable features for non-owner members of
workspaces

## 0.16.5

### Patch Changes

-   12e2855f: chore(deps): bump `jsdom` to v22
-   e4972b83: feat(metrics): add Grafana page

## 0.16.4

### Patch Changes

- 3f396a9e: fix(projects): unpause after upgrading a paused project to
pro
- 3f396a9e: fix(projects): don't redirect to 404 page after project
creation

## 0.16.3

### Patch Changes

-   Updated dependencies [90c60311]
    -   @nhost/react-apollo@5.0.20
    -   @nhost/nextjs@1.13.22

## 0.16.2

### Patch Changes

-   0f34f0c6: fix(projects): disallow downgrading to free plan
- 8da291ad: chore(deps): bump `@types/react` to v18.2.0 and
`@types/react-dom` to v18.2.1

## 0.16.1

### Patch Changes

- adc828a5: fix(gql): don't enter an infinite loop when fetching remote
app data

## 0.16.0

### Minor Changes

-   2fb1145f: feat(compute): add support for replicas

### Patch Changes

- d8ceccec: chore(env): remove deprecated `NHOST_BACKEND_URL`
environment variable

## 0.15.2

### Patch Changes

-   84b84ab7: fix(projects): filter projects by workspace

## 0.15.1

### Patch Changes

-   2faf7907: chore(deps): bump `graphql-request` to v6
-   f1b5a944: chore(deps): bump `@vitejs/plugin-react` to v4
-   7f1785ac: chore(deps): bump `@types/react` to v18.0.37
    -   @nhost/react-apollo@5.0.19

## 0.15.0

### Minor Changes

-   85889ee8: feat(dashboard): add Compute management to the settings

## 0.14.8

### Patch Changes

-   668c8771: chore(dialogs): unify dialog management of payment dialogs

## 0.14.7

### Patch Changes

-   d4ccc656: chore: cleanup unused code
    -   @nhost/react-apollo@5.0.18
    -   @nhost/nextjs@1.13.21

## 0.14.6

### Patch Changes

-   b299cfc9: chore(deps): bump `vitest` to v0.30.0
-   411cb65b: chore(projects): refactor workspace and project hooks
- 43b1b144: chore(deps): bump `@types/react` to v18.0.34 and
`@types/react-dom` to v18.0.11
-   Updated dependencies [43b1b144]
    -   @nhost/react-apollo@5.0.17
    -   @nhost/nextjs@1.13.20

## 0.14.5

### Patch Changes

-   ba0d57ee: fix(i18n): revert i18n library
-   3328ed05: feat(projects): improve overview when there is an error

## 0.14.4

### Patch Changes

-   5e0920ba: chore(deps): bump `next-seo` to v6
-   706c9dc3: chore(deps): bump `@types/react` to 18.0.33
-   99f8f6b3: feat(metrics): show metrics on the overview

## 0.14.3

### Patch Changes

-   @nhost/react-apollo@5.0.16

## 0.14.2

### Patch Changes

-   3cb67300: fix(logs): don't break UI when clearing time picker
-   7453bf3b: feat(projects): show project creator info
-   c166dad0: chore(tests): improve auth page tests
-   6a290bb2: chore(deps): bump `@types/react` to 18.0.32

## 0.14.1

### Patch Changes

-   @nhost/react-apollo@5.0.15
-   @nhost/nextjs@1.13.19

## 0.14.0

### Minor Changes

-   6e1f03ea: feat(dashboard): add support for the Azure AD provider

### Patch Changes

-   1bd2c373: chore(deps): bump `turbo` to 1.8.6
-   d329b621: chore(deps): bump `@types/react` to 18.0.30
-   cb248f0d: fix(tests): avoid name collision in database tests
-   867c8076: chore(deps): bump `@types/react` to 18.0.29

## 0.13.10

### Patch Changes

- e93b06ab: fix(dashboard): remove left margin from workspace list on
mobile
-   1c4806bf: chore(deps): bump `sharp` to 0.32.0
    -   @nhost/react-apollo@5.0.14
    -   @nhost/nextjs@1.13.18

## 0.13.9

### Patch Changes

-   912ed76c: chore(dashboard): bump `@apollo/client` to 3.7.10
-   Updated dependencies [912ed76c]
    -   @nhost/react-apollo@5.0.13

## 0.13.8

### Patch Changes

-   7c127372: chore(dashboard): bump `react-error-boundary` to v4

## 0.13.7

### Patch Changes

- 9130ab12: chore(dashboard): bump `yup` to v1 and `@hookform/resolvers`
to v3

## 0.13.6

### Patch Changes

- 253dd235: using new mutation to create projects + refactor Create
Project page.

## 0.13.5

### Patch Changes

-   @nhost/react-apollo@5.0.12
-   @nhost/nextjs@1.13.17

## 0.13.4

### Patch Changes

-   b48bc034: fix(dashboard): disable new users
-   798e591b: fix(dashboard): show correct date in data grid

## 0.13.3

### Patch Changes

-   bfb4c1a6: chore(dashboard): remove `useAxios` property
-   d8d8394b: Dashboard: allow to override hasura admin secret in docker
-   Updated dependencies [ce1ee40d]
    -   @nhost/nextjs@1.13.16
    -   @nhost/react-apollo@5.0.11

## 0.13.2

### Patch Changes

-   beed2eba: Fix docker entrypoint for dashboard
- 2c8559a3: fix(dashboard): refresh project list after deleting a
project
-   4329d048: chore(dashboard): bump `graphiql` dependencies

## 0.13.1

### Patch Changes

-   cbb1fc5b: chore(dashboard): cleanup GraphQL operations

## 0.13.0

### Minor Changes

-   088584e7: feat(dashboard): add support for custom local subdomains

### Patch Changes

-   2ac90dfd: fix(dashboard): improve mobile responsive layout
-   Updated dependencies [f375eacc]
    -   @nhost/nextjs@1.13.15
    -   @nhost/react-apollo@5.0.10

## 0.12.4

### Patch Changes

-   @nhost/react-apollo@5.0.9
-   @nhost/nextjs@1.13.14

## 0.12.3

### Patch Changes

-   2b1338f7: chore(dashboard): bump `turbo` to 1.8.3
- 5223ee93: fix(dashboard): show correct deployment status on the main
page
-   850a049c: chore(deps): update docker/build-push-action action to v4
-   Updated dependencies [850a049c]
    -   @nhost/nextjs@1.13.13
    -   @nhost/react-apollo@5.0.8

## 0.12.2

### Patch Changes

-   4bf40995: chore(deps): bump `typescript` to `4.9.5`
-   8bb097c9: chore(deps): bump `vitest`
- 35d52aab: chore(deps): replace `cross-fetch` with `isomorphic-unfetch`
-   Updated dependencies [4bf40995]
-   Updated dependencies [8bb097c9]
-   Updated dependencies [35d52aab]
    -   @nhost/react-apollo@5.0.7
    -   @nhost/nextjs@1.13.12

## 0.12.1

### Patch Changes

-   c96d7ccd: fix(dashboard): fix docker builds

## 0.12.0

### Minor Changes

-   d1671210: feat(dashboard): use mimir to manage project configuration

### Patch Changes

-   f65e4de9: chore(deps): bump @graphql-codegen monorepo to v3

## 0.11.20

### Patch Changes

-   4b4f0d01: chore(dashboard): improve dialog management

## 0.11.19

### Patch Changes

-   @nhost/react-apollo@5.0.6
-   @nhost/nextjs@1.13.11

## 0.11.18

### Patch Changes

-   01318860: fix(nhost-js): use correct URL for functions requests
-   Updated dependencies [01318860]
    -   @nhost/react-apollo@5.0.5
    -   @nhost/nextjs@1.13.10

## 0.11.17

### Patch Changes

-   f673adea: fix(dashboard): set correct Content-Type for user creation
-   445d8ef4: chore(deps): bump `@nhost/react-apollo` to 5.0.4
-   445d8ef4: chore(deps): bump `@nhost/nextjs` to 1.13.9
- 0368663d: fix(dashboard): allow permission editing for auth and
storage schemas
-   Updated dependencies [445d8ef4]
-   Updated dependencies [445d8ef4]
    -   @nhost/react-apollo@5.0.4
    -   @nhost/nextjs@1.13.9

## 0.11.16

### Patch Changes

-   b755e908: fix(dashboard): use correct date for last seen
-   2d9145f9: chore(deps): revert GraphQL client
- 1ddf704c: fix(dashboard): don't show false positive message for failed
user creation
    -   @nhost/react-apollo@5.0.3
    -   @nhost/nextjs@1.13.8

## 0.11.15

### Patch Changes

-   @nhost/react-apollo@5.0.2
-   @nhost/nextjs@1.13.7

## 0.11.14

### Patch Changes

- 2cc18dcb: fix(dashboard): prevent permission editor dropdown from
being always open

## 0.11.13

### Patch Changes

- 3343a363: chore(dashboard): bump `@testing-library/react` to v14 and
`@testing-library/dom` to v9
    -   @nhost/react-apollo@5.0.1
    -   @nhost/nextjs@1.13.6

## 0.11.12

### Patch Changes

- 87eda76e: chore(dashboard): bump `@types/react` to v18.0.28 and
`@types/react-dom` to v18.0.11
-   6f0ac570: feat(dashboard): show dashboard version in account menu

## 0.11.11

### Patch Changes

-   bf1e4071: chore(dashboard): bump `react-is` version to `18.2.0`
-   Updated dependencies [bf1e4071]
-   Updated dependencies [5013213b]
    -   @nhost/nextjs@1.13.5
    -   @nhost/react-apollo@4.13.5

## 0.11.10

### Patch Changes

- a37a430b: fix(dashboard): don't break UI when deployments are
unavailable
    -   @nhost/react-apollo@4.13.4
    -   @nhost/nextjs@1.13.4

## 0.11.9

### Patch Changes

-   7b970e68: fix(dashboard): fix header link color

## 0.11.8

### Patch Changes

- f33242f2: feat(dashboard): add new sign up, sign in and reset password
pages

## 0.11.7

### Patch Changes

-   e9c8909c: fix(dashboard): use correct theme color in dark mode

## 0.11.6

### Patch Changes

-   902f486b: fix(dashboard): re-enable Hasura on logs page

## 0.11.5

### Patch Changes

-   1f9720fa: fix(dashboard): apply select permissions properly

## 0.11.4

### Patch Changes

-   deb14b51: fix(dashboard): don't break billing form

## 0.11.3

### Patch Changes

-   @nhost/react-apollo@4.13.3
-   @nhost/nextjs@1.13.3

## 0.11.2

### Patch Changes

-   f143e51d: chore(dashboard): pin Turborepo to 1.6.3

## 0.11.1

### Patch Changes

-   c2b5a41a: chore(dashboard): select system colors by default

## 0.11.0

### Minor Changes

-   1ebaf429: feat(dashboard): introduce Dark Mode 🌚

### Patch Changes

- 63b445c4: fixed duplicated logs bug and made to date count during live
mode

## 0.10.1

### Patch Changes

-   e146d32e: chore(deps): update dependency @types/react to v18.0.27
-   59347fcd: correct allowed role name
-   5b65cac9: updated authentication documentation
-   963f9b5e: feat(dashboard): include project info in feedback

## 0.10.0

### Minor Changes

-   ed4c7801: chore(dashboard): remove Functions section

## 0.9.10

### Patch Changes

-   4e2f8ccd: fix(dashboard): don't break Auth page in local mode

## 0.9.9

### Patch Changes

-   31abbe5f: fix(dashboard): enable toggle when settings are filled in

## 0.9.8

### Patch Changes

- 5bdd31ad: chore(dashboard): list fewer images per page on the Storage
page
- 5121851c: fix(dashboard): don't throw validation error for valid
permission rules

## 0.9.7

### Patch Changes

-   c126b20d: fix(dashboard): correct redeployment button

## 0.9.6

### Patch Changes

-   36c3519c: feat(dashboard): retrigger deployments

## 0.9.5

### Patch Changes

- 200e9f77: chore(deps): update dependency @types/react-dom to v18.0.10
-   Updated dependencies [200e9f77]
    -   @nhost/nextjs@1.13.2
    -   @nhost/react-apollo@4.13.2

## 0.9.4

### Patch Changes

- dbd3ded5: fix(dashboard): workspaces creation, new form, correct
redirects.

## 0.9.3

### Patch Changes

-   85f0f943: fix(dashboard): don't break the table creation process

## 0.9.2

### Patch Changes

-   Updated dependencies [d42c27ae]
-   Updated dependencies [927be4a2]
    -   @nhost/nextjs@1.13.1
    -   @nhost/react-apollo@4.13.1

## 0.9.1

### Patch Changes

-   d0f80811: fix(dashboard): don't show error when signing out the user

## 0.9.0

### Minor Changes

- d92891b2: feat(dashboard): add Permission Editor to the Database
section

### Patch Changes

-   3d379128: fix(dashboard): create new user
    -   @nhost/react-apollo@4.13.0
    -   @nhost/nextjs@1.13.0

## 0.8.1

### Patch Changes

-   7cadd944: fix(dashboard): display Twitter provider settings

## 0.8.0

### Minor Changes

-   9a1aa7bb: add functions to the log dashboard
-   f29abe62: feat(dashboard): Users Management v2

### Patch Changes

-   7766624b: feat(dashboard): add JWT secret editor modal
    -   @nhost/react-apollo@4.12.1
    -   @nhost/nextjs@1.12.1

## 0.7.13

### Patch Changes

-   dd0738d5: fix(dashboard): provisioning status polling

## 0.7.12

### Patch Changes

-   b21222b3: chore(deps): update dependency @types/node to v16
-   9e0486a3: fix(dashboard): close modals when navigating
-   Updated dependencies [b21222b3]
-   Updated dependencies [65687bee]
-   Updated dependencies [54df0df4]
    -   @nhost/nextjs@1.12.0
    -   @nhost/react-apollo@4.12.0

## 0.7.11

### Patch Changes

-   d6527122: fix(dashboard): use correct service URLs

## 0.7.10

### Patch Changes

-   Updated dependencies [57db5b83]
    -   @nhost/nextjs@1.11.0
    -   @nhost/nhost-js@1.7.0
    -   @nhost/react@0.17.0
    -   @nhost/react-apollo@4.11.0

## 0.7.9

### Patch Changes

- a6d31dc2: fix(dashboard): don't break the UI when project is not
loaded yet

## 0.7.8

### Patch Changes

- 7f251111: Use `NhostProvider` instead of `NhostReactProvider` and
`NhostNextProvider`

    `NhostReactProvider` and `NhostNextProvider` are now deprecated

-   f4d70f88: fix(dashboard): do not break when region is nullish

- 4a9471cc: Windows Live Provider displayed link updated to match
backend url

- 594488e4: fix(dashboard): do not show error when submitting Apple
provider settings

-   Updated dependencies [7f251111]
    -   @nhost/nextjs@1.10.0
    -   @nhost/react@0.16.0
    -   @nhost/react-apollo@4.10.0

## 0.7.7

### Patch Changes

-   80b604ad: fix(dashboard): use correct Hasura slug

## 0.7.6

### Patch Changes

-   2d2beb53: fix(dashboard): prevent error on GraphQL page
-   ac8efcbd: chore(dashboard): deprecate old DNS name

## 0.7.5

### Patch Changes

-   132a4f4b: chore(dashboard): remove unused dependencies
- 132a4f4b: chore(deps): synchronize @types/react-dom and @types/react
versions
-   db57572f: fix(dashboard): correct section paddings when no env vars
-   Updated dependencies [132a4f4b]
    -   @nhost/react@0.15.2
    -   @nhost/react-apollo@4.9.2
    -   @nhost/nextjs@1.9.3

## 0.7.4

### Patch Changes

-   34d85e54: chore(deps): update dependency critters to ^0.0.16
- 9b93cf95: chore(deps): update dependency @netlify/functions to ^0.11.0
-   e0439030: chore(deps): update dependency @types/react-dom to v18.0.9
-   Updated dependencies [82124329]
    -   @nhost/nextjs@1.9.2

## 0.7.3

### Patch Changes

-   a1193da4: fix(dashboard): remove character limit from env var inputs

## 0.7.2

### Patch Changes

-   44f13f62: chore(dashboard): cleanup unused files

## 0.7.1

### Patch Changes

- e01cb2ed: chore(dashboard): change settings sidebar menu item density

## 0.7.0

### Minor Changes

- db342f45: chore(dashboard): refactor Roles and Permissions settings
sections
-   8b9fa0b1: feat(dashboard): add Environment Variables page

### Patch Changes

-   Updated dependencies [66b4f3d0]
-   Updated dependencies [2e6923dc]
-   Updated dependencies [ef117c28]
-   Updated dependencies [aebb8225]
    -   @nhost/core@0.9.4
    -   @nhost/nhost-js@1.6.2
    -   @nhost/nextjs@1.9.1
    -   @nhost/react@0.15.1
    -   @nhost/react-apollo@4.9.1

## 0.6.0

### Minor Changes

-   eef9c914: feat(dashboard): add Roles and Permissions page

## 0.5.0

### Minor Changes

-   a48dd5bf: feat(dashboard): make backend port configurable

## 0.4.3

### Patch Changes

-   5de965d9: fix(dashboard): alphabetic ordering of providers
-   b9087a4a: fix(dashboard): console -> dashboard terminology
-   ca012d79: docs(workos): WorkOS Docs

## 0.4.2

### Patch Changes

-   89bd37bc: fix(dashboard): correct redirect URL input opacity
-   Updated dependencies [4601d84e]
-   Updated dependencies [843087cb]
    -   @nhost/react@0.15.0
    -   @nhost/nextjs@1.9.0
    -   @nhost/react-apollo@4.9.0

## 0.4.1

### Patch Changes

-   766cb612: fix(dashboard): correct redirect URL for oauth providers
-   Updated dependencies [53bdc294]
-   Updated dependencies [f2aaff05]
    -   @nhost/nextjs@1.8.3
    -   @nhost/core@0.9.3
    -   @nhost/react@0.14.3
    -   @nhost/nhost-js@1.6.1
    -   @nhost/react-apollo@4.8.3

## 0.4.0

### Minor Changes

-   9211743d: feat(dashboard): migrate Settings page features

## 0.3.0

### Minor Changes

-   73da6a67: fix(dashboard): avoid using BACKEND_URL locally

## 0.2.0

### Minor Changes

-   db118f97: feat(dashboard): generate Docker image

## @nhost/docs@2.29.0

### Minor Changes

-   b40d375: feat: added pitr docs

## @nhost-examples/cli@0.3.19

### Patch Changes

-   @nhost/nhost-js@3.2.6

## @nhost-examples/codegen-react-apollo@0.5.2

### Patch Changes

-   Updated dependencies [ad57a9e]
    -   @nhost/react@3.10.2
    -   @nhost/react-apollo@17.0.2

## @nhost-examples/codegen-react-query@0.5.2

### Patch Changes

-   Updated dependencies [ad57a9e]
    -   @nhost/react@3.10.2

## @nhost-examples/codegen-react-urql@0.4.2

### Patch Changes

-   Updated dependencies [ad57a9e]
    -   @nhost/react@3.10.2
    -   @nhost/react-urql@14.0.2

## @nhost-examples/multi-tenant-one-to-many@2.2.20

### Patch Changes

-   @nhost/nhost-js@3.2.6

## @nhost-examples/nextjs@0.4.5

### Patch Changes

-   Updated dependencies [ad57a9e]
    -   @nhost/react@3.10.2
    -   @nhost/react-apollo@17.0.2
    -   @nhost/nextjs@2.2.5

## @nhost-examples/node-storage@0.2.19

### Patch Changes

-   @nhost/nhost-js@3.2.6

## @nhost-examples/nextjs-server-components@0.5.4

### Patch Changes

-   @nhost/nhost-js@3.2.6

## @nhost-examples/react-apollo@1.3.2

### Patch Changes

-   Updated dependencies [ad57a9e]
    -   @nhost/react@3.10.2
    -   @nhost/react-apollo@17.0.2

## @nhost-examples/react-gqty@1.3.2

### Patch Changes

-   Updated dependencies [ad57a9e]
    -   @nhost/react@3.10.2

## @nhost-examples/react-native@0.1.6

### Patch Changes

-   Updated dependencies [ad57a9e]
    -   @nhost/react@3.10.2
    -   @nhost/react-apollo@17.0.2

## @nhost-examples/vue-apollo@0.9.2

### Patch Changes

-   @nhost/nhost-js@3.2.6
-   @nhost/apollo@8.0.6
-   @nhost/vue@2.9.3

## @nhost-examples/vue-quickstart@0.3.2

### Patch Changes

-   @nhost/apollo@8.0.6
-   @nhost/vue@2.9.3

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-03-12 13:35:39 +01:00
robertkasza
ad57a9e473 fix (auth): allow to pass headers to email/password sign up (#3201)
### **PR Type**
Enhancement, Bug fix


___

### **Description**
- Allow passing headers to email/password sign-up

- Add tests for custom headers in sign-up

- Fix typos and improve comments

- Update e2e backend script


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>4
files</summary><table>
<tr>
<td><strong>hasura-auth-client.ts</strong><dd><code>Add RequestOptions
to signUp method</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3201/files#diff-0dbc30932ed723b7fd458066893f29f2f77658436c84adf42613813ea042c992">+7/-4</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>events.ts</strong><dd><code>Add RequestOptions to
SIGNUP_SECURITY_KEY event</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3201/files#diff-a1a1ecc9ad9d8ed8e460e0401007a8d479b4d9ba66bc909e1d1458947b5fdf85">+6/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>signUpEmailSecurityKey.ts</strong><dd><code>Add
RequestOptions to signUpEmailSecurityKeyPromise</code>&nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3201/files#diff-55c8c8ec957b0dc8c8c5a4fe262187b133109408b5664b72f1776e96ec9f1427">+5/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>useSignUpEmailSecurityKey.ts</strong><dd><code>Add
RequestOptions to signUpEmailSecurityKey handler</code>&nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3201/files#diff-2cf827b3455da361a3ee39b49c1cf1ce6a2dca411b34441a63f7fc1f9e897cf0">+6/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Bug
fix</strong></td><td><details><summary>3 files</summary><table>
<tr>
<td><strong>machine.ts</strong><dd><code>Fix typos and improve
comments</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3201/files#diff-a8fdfee087ad5a72ea0a64667e2a0c7f25baa84eaaf73ebfee3f5a5a1b7584d1">+9/-7</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>fetch.ts</strong><dd><code>Fix typo in FetchResponse
interface name</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3201/files#diff-b1af9daf6c51514d5d514540f2318d87e926c5e8a57079b6e2c258b98a1163a2">+6/-6</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>useSignUpEmailPassword.ts</strong><dd><code>Remove type
assertion for password parameter</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3201/files#diff-88cf86ab14d0ece9af1761ddcf1d940ba829317852964748a6033658519370af">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

</table></details></td></tr><tr><td><strong>Tests</strong></td><td><details><summary>1
files</summary><table>
<tr>
<td><strong>hasura-auth-client.test.ts</strong><dd><code>Add tests for
custom headers in sign-up</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3201/files#diff-f2aedf396c71758c8b69f56f94e22b7f1f8f5cc5b9a2791d1e339dbabd8a8970">+60/-0</a>&nbsp;
&nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Configuration
changes</strong></td><td><details><summary>1 files</summary><table>
<tr>
<td><strong>package.json</strong><dd><code>Update e2e:start-backend
script</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3201/files#diff-d95dc3391741287366ea2e61f70e9ccc64452e0d22b1db91d6bf524f5aa4331c">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-03-12 13:14:05 +01:00
David Barroso
b40d375039 feat (docs): added pitr docs (#3223)
### **PR Type**
Documentation


___

### **Description**
- Added comprehensive documentation for database backups and
restoration.

- Introduced details on Point-in-Time Recovery (PITR) feature.

- Updated navigation structure to include the new backups guide.

- Created a changeset file for versioning and release notes.


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Configuration
changes</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>afraid-seahorses-remain.md</strong><dd><code>Add
changeset for PITR documentation update</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

.changeset/afraid-seahorses-remain.md

<li>Added a changeset file for versioning.<br> <li> Marked the addition
of PITR documentation as a minor change.


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3223/files#diff-cb3faee18af54ae2c85e445324bfee0ebe6ca7dbea62802d63cbef12811e4431">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>mint.json</strong><dd><code>Update navigation to
include backups guide</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

docs/mint.json

<li>Updated navigation to include the new backups guide.<br> <li> Added
<code>guides/database/backups</code> to the database section.


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3223/files#diff-c91a604899dfef4b2494c317f4fd39a7f22b79986095f580399347293d534deb">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>backups.mdx</strong><dd><code>Add detailed guide for
database backups and PITR</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

docs/guides/database/backups.mdx

<li>Added a new guide for database backups.<br> <li> Included
instructions for restoring backups and PITR.<br> <li> Provided details
on backup retention and manual backups.<br> <li> Explained restoring
backups on different projects.


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3223/files#diff-06e71a9a155211a9c189660ca578f7471c6bbb7f41efa7571cb5140dbb88e9ef">+153/-0</a>&nbsp;
</td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-03-12 12:44:38 +01:00
David BM
af61cb737a fix (dashboard): correct user edit default role source (#3230)
### **User description**
Fixes #3219

Also adds 5 minutes timeout to CI install Nhost CLI action


___

### **PR Type**
Bug fix


___

### **Description**
- Correct default role source in user edit form

- Remove unused roles query and data processing

- Update default role options rendering

- Add changeset for version tracking


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>EditUserForm.tsx</strong><dd><code>Refactor default
role selection in EditUserForm</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/authentication/users/components/EditUserForm/EditUserForm.tsx

<li>Remove <code>useGetRolesPermissionsQuery</code> and related data
processing<br> <li> Update default role options to use
<code>roles</code> prop<br> <li> Replace
<code>allAvailableProjectRoles</code> with direct <code>roles</code>
mapping<br> <li> Adjust <code>Option</code> component key and value
props


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3230/files#diff-6867937d55b269352d4e146ff21b36ca939f6a838ee70b1b29efa9eabad88c2e">+7/-13</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>friendly-beans-arrive.md</strong><dd><code>Add
changeset for dashboard version update</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

.changeset/friendly-beans-arrive.md

<li>Add new changeset file for version tracking<br> <li> Specify minor
version bump for @nhost/dashboard<br> <li> Include fix description for
default role source


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3230/files#diff-bb459c54d9e0564d4a4f2ad8eb5b5431e0ac151f673bb49ae38ac19ba73def47">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-03-12 12:16:39 +01:00
robertkasza
f84cd550d9 feat (dashboard): Add PiTR to backups page (#3229)
### **PR Type**
Enhancement


___

### **Description**
- Add Point-in-Time Recovery (PiTR) feature

- Implement backup import functionality

- Update database settings and UI components

- Refactor and improve existing backup components


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>19
files</summary><table>
<tr>
<td><strong>DateTimePicker.tsx</strong><dd><code>Add new DateTimePicker
component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-1ad629af5bd959e35b4d7fa2ab0470d644e8762568b8eeda6c2b7190a17452d0">+125/-0</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>TimezoneSettings.tsx</strong><dd><code>Create
TimezoneSettings component for DateTimePicker</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-2cbffc4f494f4b7fb9e1d410a953bfd770da22331fb4cdec8145e06c0fee6478">+39/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>TimePicker.tsx</strong><dd><code>Implement new TimePicker
component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-6c4810545201a0dd4b0ee3fde901f736d745b184c289864ecbb06f8f3998c099">+64/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>VirtualizedCombobox.tsx</strong><dd><code>Add
VirtualizedCombobox component for efficient option
rendering</code></dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-1cc84483e00069f85c3c0288f25cd68cf24495439b5f1c40eac35a0f91933763">+245/-0</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>useDatabasePiTRSettings.ts</strong><dd><code>Create hook for
managing PiTR settings</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-e90e7eb41daf536c2d9b59e6212a8f31cb5b698507d87794834ba05aa1bf5b34">+24/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>

<td><strong>useImportBackupSourceProjectList.tsx</strong><dd><code>Implement
hook for fetching import backup source projects</code></dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-136414e9495d95c3328184caf2703a412d4702ccfc8d1717ef526c0a8da828fd">+33/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>useIsPiTREnabled.ts</strong><dd><code>Create hook to check
if PiTR is enabled</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-4c0d423babd527155f9f3886b0034806522fbaa8601b767f4aa8dcd25ea441e3">+0/-16</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>useIsPiTREnabledLazy.ts</strong><dd><code>Implement lazy
loading hook for PiTR status</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-521aa1cfda4f8601fe11d0e27e52c62a85323830e878785e91eb3730818fd5a2">+30/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>usePiTRBaseBackups.ts</strong><dd><code>Create hook for
fetching PiTR base backups</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-eff86f36e559ed015499f44d7d8285417b68a2c6362f8d938412d7b4927bd328">+33/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>

<td><strong>useRestoreApplicationDatabasePiTR.ts</strong><dd><code>Implement
hook for restoring database from PiTR</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-dd5774f502b63d2d443069bedb4c9531a77794a95aaa5c07287093695a4dc60a">+34/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>BackupsContent.tsx</strong><dd><code>Create new
BackupsContent component with tabs</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-e543f89d133a420d24302785cb201bdd02d8841d043a6b9c95df4fce8fbf4a45">+27/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>ImportBackupTabContent.tsx</strong><dd><code>Implement
ImportBackupTabContent component</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-cb278aa33b215fdf0550e658d9e91f3d826467878d2ab30afa5e7d18e02422ef">+43/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>PointInTimeTabsContent.tsx</strong><dd><code>Add
PointInTimeTabsContent component for PiTR</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-f3f19f0f85928cb5e9249ba6cd63b408df62fc8e681ae638816977c9f1b9016f">+17/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>ScheduledBackupTabContent.tsx</strong><dd><code>Refactor
ScheduledBackupTabContent component</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-546fc678d74ad6b3e7ffdafa83df0d58cc0a49df31b647cae6a9220f0e7c15ef">+36/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>PointInTimeBackupInfo.tsx</strong><dd><code>Create
PointInTimeBackupInfo component for PiTR</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-35be453f6605231bcee5b7f7f78564eb7aa2be723f5169509f9dddfe84477fe6">+63/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>backups.tsx</strong><dd><code>Update backups page to use new
components</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-11c24d569a8109344819d2cc9ce6ffbcf3b75abfba604e299c01289690d322f9">+5/-26</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>graphql.ts</strong><dd><code>Update GraphQL types and
queries for PiTR</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-fbd5db84b560b1c91675004448c6c7fa0dcbfb28b9eb05d53b03e6cb7b83ebac">+146/-0</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>getPiTRBaseBackups.graphql</strong><dd><code>Add GraphQL
query for PiTR base backups</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-66811bf0abb1c941e2501d90c4b7bffb39ef30338c98d6c9ee20facde3b5f2d5">+6/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>

<td><strong>restoreApplicationDatabasePiTR.graphql</strong><dd><code>Add
GraphQL mutation for PiTR database restore</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-4b8a543fb86cfca8e3041c00454ad9ff3cac7fc92b75ab3840e057961a169f34">+11/-0</a>&nbsp;
&nbsp; </td>

</tr>

</table></details></td></tr><tr><td><strong>Dependencies</strong></td><td><details><summary>1
files</summary><table>
<tr>
<td><strong>package.json</strong><dd><code>Update dependencies and add
new packages</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-2d8d55c799cd71f1b35e831f075f8178ed1734c4820a2ad548b4dd24d6938d7c">+6/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Additional
files</strong></td><td><details><summary>62 files</summary><table>
<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-e41e4cb8c926d6561aeed59ddaadd8a883462fbfc6e51081f48feb089599a982">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>TimePickerInput.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-970eb8f755f27a1e13f0d24230c403ffd1e5ad7829e14b67690373bcdade1277">+148/-0</a>&nbsp;
</td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-1c4caf14e81e8ebe413cd16c1fdf71a5b99059540eb8e6c230ec0ed7948eea70">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>time-picker-utils.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-539dd838376d43e44041d8ff8a8d3a9d3405661d2775788eadb50d4bad1db512">+244/-0</a>&nbsp;
</td>

</tr>

<tr>
  <td><strong>TimezonePicker.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-1219e627fa38850183eec3d695ae39c4b607b2ed62255789917672e999ceca55">+33/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-1da85db0b242da76756df5ac70f3068f2c53f1b9616ccbd3da08805a80c549af">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-daf57b3357b1698296dcc41422780614a29e9451007df41e7153c270e05c0085">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>button.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-3128c8a9c83cc7319d992e31c2cba551cde0d85037f42a5a74a47464d7e80f82">+14/-1</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>calendar.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-63f846015a12e66f0c36ec550d502d6d00a250959957652d14460807f1fbe68d">+80/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>dialog.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-f2ef2b36b8f85ecc699ce3c64158a9018a0a15242b9f945d2bedc40b7c59c102">+12/-2</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>spinner.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-0404df81ce8503d881cd2f3f1ac59865aafd65f559e6a335cd79e2c49fe31476">+56/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>tabs.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-bc5ee4fa7f3a98e85560de1abffcae71bc527bf8087ea152f3c5ae8246ed1b1a">+53/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>InfoAlert.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-4b78a2f0e1c6c2f6b37e430bc6cad016e884bb34735bd6aaebac906743748d7b">+31/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-1ed5caad9d58ebed38957a3d8db2a395b84a6f11abd4fc9455b9e895ba0a0a76">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-d3e8f38360bc461e1c7d52084c21729bd3af11ca4ff72fe6e07cbe78f4a756a5">+0/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>useUpdateDatabasePITRConfig.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-9c0f751418c04e20ce5b992961fe3ae779dd056e16188ad0684236e91debb333">+0/-24</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-9401c95cb391dc84bd88c87dc7bbb84f4a04a17ce3768a7aa03e4df600985ae8">+0/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-ee9a711d701edfc23d3fdee2d93d574e9c7335c620852dfd6b0042d91928bdca">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-ada2a14aa3c012af7ef896b6b5b34073c7122e2e76e02fc528e0f67ed3a0762a">+0/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>useIsPITREnabled.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-ccadf282438731d649162e5f7a2f778e235cee170c660e6db945107bac075485">+0/-16</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-7703cb7870d19609bb12fa3a5be2c0cc397cc017fbb723b896e789d9d475f185">+0/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-f7e86e2560ce15ecfc052a73c255d1bf2fcbf4c5ce93701cb3d7ea0cdf076da9">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-7276ebfe36c94d90f1b8d25753263d068d4ab5af794a2fc0ca926ba18b30c982">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-f635e9c12762de8ab4d9ff62302eeffda1e3c8b3efb3760cd59a7c16052f6fb6">+0/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-f1322a198c8a57293119cabf169954842e63df112322af72c7bdeb13366bf567">+0/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>useUpdateDatabasePiTRConfig.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-b91403cefffce18a9a12888f9c702c8567fad60130fca863b7c7e790fa2219ee">+8/-8</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-e25cc47626c366456dd2206f613fa5d4bdfcdec5c750b5ae99c4c8d44d8df47f">+0/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-b28f78fd315d021c6a3c1d46b90beac22d3a98eba6ca15f6ca79f75b84f84fa8">+0/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-45ea1cacd064ba79052f50bf5e9dace59c801c0b9c43b541c4b1fa1d1c53f76d">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>NoOtherProjectsInRegion.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-cb4d6fd1bc9222df18ec07bf803884bcd2abf2562b9ae9c4c66a66dbfc05c153">+18/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>PiTRNotEnabledOnSourceProject.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-bde1eb77a9da964612758a7795ef0bbc7d7ea40b9f4d278788e7f0d9ac0f74f4">+15/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>SourceProjectBackupInfo.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-4bf8851fed9997b78e62e1d94dced8ceff8eda855e11d1cfedb7d23130363c37">+28/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>SourceProjectSelect.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-a04579d221dea095e7af4b3ec68e7d07ce7fa3765e25708e3bec22f89160e9b4">+53/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-9ddf7da80e5964414404d5c715c3da5a614b97e3263698d4c0be4db1e7c1f8ed">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>PiTRNotEnabled.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-a1d251614eecca4406816b18302a1af226aee95d01d04858661a30e6fb07218d">+24/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>PointInTimeRecovery.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-b0756ee9cd0789a2de53c5389d6a102bac50500bef97b809f55357798a939b5a">+15/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>RecoveryRetentionPeriod.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-631ff2a064d17d9ee08a6fecbf204908dd2e72b0dab8c23670b343b74fd41e8c">+16/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-6bcbb9922adb6b20bb23a7dc1b1272751d9813391af6bcccc4cf3ed4f7a2c727">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-8ba7b8d6096ee695aa7c1a92402a4d377b6777296e5b13cb345964be623fcbf9">+0/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>BackupList.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-fbd66a866aec5e50da247ecf43eabf32909e0648f682525b9554dd908a40d910">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>BackupListItem.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-319aac4df7906607fc84a6e8d0ba510fbf49ea92d6ccda5ab48c50e8f1ec33d5">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>PiTREnabledInfoBanner.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-7dab58d90b66701b52fff767835c62a8218bfe3c844544869052d8d32a87e37e">+12/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>RestoreBackupModal.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-f7caf91cec87922fc8a3ea4941b0dd6f752a4d542652d93f6c9a6219763fcfd4">[link]</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-243bca977e6e898b72be8e6739efb1b14aedd34d616a367746d7e62705289a20">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>BackupScheduledInfo.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-b7b769edd56e42710aca4bfb85af7d6bd0173d67f024478e4c68f0f7d23dd957">+46/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>EarliestBackup.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-c4d1332e7f0b63d50f679d7b56696d5cc53712b22bb53d44b2fcf064d79c8cb0">+53/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>RestoreBackupDialogButton.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-eed1e2ca6d4002ec218cd16e69ed81160c8c8982877c65ace80d12b88aefd6ef">+208/-0</a>&nbsp;
</td>

</tr>

<tr>
  <td><strong>StartRestoreConfirmationCheck.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-56f1657d2302ecc9f2e34cc78363cfb90954791517b1ad23ec06f34b10bde37e">+35/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-77b497855973d099f547efc622b403bf1bdbd475b1503e36d581b7c48c525952">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>getDateTimeStringWithUTCOffset.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-420bbeebf0a8b98242780ea3b78ff843f33559c9b766b0c343b1c5d180a92e69">+17/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-94eeb0af5cef2989a172bef83e67e72d1dcfdd18da56b04c274c34eac5ac19eb">+0/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>DatabasePiTRSettings.test.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-85d1f82a571b56469eab40dcc164fdd1e107fba79611ddd5cca7c191fe5117b4">+11/-11</a>&nbsp;
</td>

</tr>

<tr>
  <td><strong>DatabasePiTRSettings.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-7a638c446af8419249770dc8da1ea522f950163b1d0045020927216c38db8cec">+12/-12</a>&nbsp;
</td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-398e23d6c879dd409f4ef19d13cba6372ec1e6044d3293a34e3c23fe2f8e02bd">+0/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>DeploymentStatusMessage.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-7e077798c520eb4aada9d1a39d2e3f1a1ac573a821d57c64608e682b41150390">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>DeploymentStatusMessage.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-54e74ec65ab87fbf5a4344bbaf282c68809608ca9cfa8566a515b3f31259cad0">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>utils.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-57035bfd3b91de326fec3e5a0bf19487f03130a9a09dc3e428c79f556677081b">+2/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>database.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-00045ae38a73178045bcda39c80a03a0cb46413641586896a628c3a2a22c7855">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-b6be6198288cbb31a42f700a54e21842f253626d36940f7011b5d29a9311d0fd">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>timezone-utils.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-f80a0f62570505fcb30922366a5aea365d62b1ba25065d7717277704c4161741">+73/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>package.json</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>package.json</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3229/files#diff-27f71682a447c654ff4a94d33944ebb70e10d07a4279107c230bd8ec7dce7391">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-03-12 12:13:49 +01:00
robertkasza
1986178f7a feat (dashboard): add PITR setting to database setting page (#3224)
### **PR Type**
Enhancement


___

### **Description**
- Add Point-in-Time Recovery (PITR) settings to database

- Implement hooks for PITR configuration management

- Create new components for PITR UI

- Update GraphQL schema for PITR support


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>15
files</summary><table>
<tr>
<td><strong>index.ts</strong><dd><code>Export useDatabasePITRSettings
hook</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-d3e8f38360bc461e1c7d52084c21729bd3af11ca4ff72fe6e07cbe78f4a756a5">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>useUpdateDatabasePITRConfig.ts</strong><dd><code>Implement
useDatabasePITRSettings hook</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-9c0f751418c04e20ce5b992961fe3ae779dd056e16188ad0684236e91debb333">+21/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>index.ts</strong><dd><code>Export useIsPITREnabled
hook</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-ada2a14aa3c012af7ef896b6b5b34073c7122e2e76e02fc528e0f67ed3a0762a">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>useIsPITREnabled.ts</strong><dd><code>Implement
useIsPITREnabled hook</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-ccadf282438731d649162e5f7a2f778e235cee170c660e6db945107bac075485">+16/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>index.ts</strong><dd><code>Export
useUpdateDatabasePITRConfig hook</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-f635e9c12762de8ab4d9ff62302eeffda1e3c8b3efb3760cd59a7c16052f6fb6">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>useUpdateDatabasePITRConfig.ts</strong><dd><code>Implement
useUpdateDatabasePITRConfig hook</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-e8f221b95a9e889c359f7b3ff35ce8ea5f3b7090abfdae57c4f1d2ef54d89fb7">+57/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>index.ts</strong><dd><code>Add export for
useIsNotPlatform</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-7e4f0dbd79622a9b7ff5b2e04717d645a98b1b723f107658e18c274f890ed627">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>useIsPlatform.ts</strong><dd><code>Add useIsNotPlatform
function</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-eea9e9627c2314fd248713d113a88db30a99809d00ebbfdcca83689a35c4bdbc">+4/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>postgresqlConstants.ts</strong><dd><code>Add
RECOVERY_RETENTION_PERIOD_7 constant</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-b497da90feca5bff94b0d38b69e519d171d43acc292098054d672a73a89b4717">+2/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>DatabasePitrSettings.tsx</strong><dd><code>Implement
DatabasePitrSettings component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-d7657adf6ee83cf09cebc9854dc4742bab9a23517e3277d09db923ca309be91b">+50/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>index.ts</strong><dd><code>Export DatabasePitrSettings
component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-20e8098340a0bcb8723cfd67e938f481d7172dcf6de4610e826a2d568948b0f4">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>database.tsx</strong><dd><code>Add DatabasePitrSettings to
database settings page</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-00045ae38a73178045bcda39c80a03a0cb46413641586896a628c3a2a22c7855">+3/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>graphql.ts</strong><dd><code>Update GraphQL types for PITR
support</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-fbd5db84b560b1c91675004448c6c7fa0dcbfb28b9eb05d53b03e6cb7b83ebac">+75/-1</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>getPostgresSettings.gql</strong><dd><code>Add PITR retention
to PostgreSQL settings query</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-1acee16f252288335d1bb4d8af5ca313d66f75edd0d62fe29e6d38d4653393f7">+3/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>getPostgresSettings.gql</strong><dd><code>Add PITR retention
to PostgreSQL settings query</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3224/files#diff-d77873957f82dd65a26ae7beca2440148d8ba6911f5bed4bdeb6cf1ad6de7f25">+3/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-03-12 08:55:53 +01:00
David BM
aa9210c838 fix (dashboard): run services with secrets in the command field (#3208)
### **User description**
Fixes #3070


___

### **PR Type**
Bug fix, Enhancement


___

### **Description**
- Refactor command input to list format

- Fix parsing issues with secrets in commands

- Improve UI for command input section

- Update related components and types


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>ServiceForm.tsx</strong><dd><code>Replace command input
with new CommandFormSection component</code></dd></summary>
<hr>


dashboard/src/features/orgs/projects/services/components/ServiceForm/ServiceForm.tsx

<li>Remove shell-quote parsing<br> <li> Replace single command input
with CommandFormSection<br> <li> Update service configuration to use new
command format


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3208/files#diff-a02746694d45a84390d09b49a1b3eec85c25a8bd9a70b4834ee5af1ba82cb88e">+3/-24</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>ServiceFormTypes.ts</strong><dd><code>Update command
validation schema and type definition</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/services/components/ServiceForm/ServiceFormTypes.ts

<li>Update command validation schema<br> <li> Change command type from
string to array of objects


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3208/files#diff-e9e0545b8c213ce04a08f9b04aedc81f96a031429e2ac9ac9e19d47982c112dc">+5/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>CommandFormSection.tsx</strong><dd><code>Create new
CommandFormSection component for improved command
input</code></dd></summary>
<hr>


dashboard/src/features/orgs/projects/services/components/ServiceForm/components/CommandFormSection/CommandFormSection.tsx

<li>Add new CommandFormSection component<br> <li> Implement dynamic
command input fields<br> <li> Add space detection warning<br> <li>
Include tooltip with usage instructions


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3208/files#diff-952b9cf5789c2075527c9289b6464a1a678bb3e2f1073e5493eb871eec33c650">+112/-0</a>&nbsp;
</td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>index.ts</strong><dd><code>Add index file for
CommandFormSection component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/services/components/ServiceForm/components/CommandFormSection/index.ts

- Export CommandFormSection component


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3208/files#diff-e39d0bfb2f4a8ea0386eb5852324a1aeb2a7da161ffed09929653703a8ec525e">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Bug fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>ServiceConfirmationDialog.tsx</strong><dd><code>Update
import path in ServiceConfirmationDialog</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/services/components/ServiceForm/components/ServiceConfirmationDialog/ServiceConfirmationDialog.tsx

- Update import path for ServiceFormValues type


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3208/files#diff-0f7e83b481fe5f81e80d03aa47ec2c7b812322519a9dda4cbe9dfab0d2c37d03">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>ServicesList.tsx</strong><dd><code>Adjust command
formatting in ServicesList component</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/services/components/ServicesList/ServicesList.tsx

- Update command formatting in initialData


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3208/files#diff-643c818a248c42950336289392ac97ed9ef5c670ff8e47b80588b9802844d28a">+3/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>run.tsx</strong><dd><code>Modify command formatting in
run page configuration</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

dashboard/src/pages/orgs/[orgSlug]/projects/[appSubdomain]/run.tsx

- Update command formatting in parsedConfig


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3208/files#diff-b113fc9ab0c229c90cdcb792b15404544813072a2d2ad9fb140746628b83db8c">+3/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>famous-seahorses-taste.md</strong><dd><code>Add
changeset for command field secrets fix</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

.changeset/famous-seahorses-taste.md

<li>Add changeset for minor version bump<br> <li> Describe fix for
secrets in command field


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3208/files#diff-c71b086d2f313eeb58415afe90205c8e3161c83587b659e9d5ae594bff48b96a">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-03-05 13:40:12 +01:00
David BM
695466df95 chore (dashboard): simplify personal project deletion checkboxes (#3225)
### **User description**
This PR removes the `I understand I need to delete the organization if I
want to cancel the subscription` checkbox when deleting a project if
it's part of a personal organization (`org.plan.isFree == true`)


___

### **PR Type**
Enhancement


___

### **Description**
- Simplify personal project deletion flow

- Remove subscription cancellation checkbox for free plans

- Add conditional rendering based on plan type

- Update project deletion button disabled state


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>

<summary><strong>RemoveApplicationModal.tsx</strong><dd><code>Conditional
rendering of deletion checkboxes based on plan
type</code></dd></summary>
<hr>


dashboard/src/features/orgs/projects/common/components/RemoveApplicationModal/RemoveApplicationModal.tsx

<li>Add <code>isPlanFree</code> variable to check if org plan is
free<br> <li> Conditionally render subscription cancellation
checkbox<br> <li> Update button disabled state based on
<code>isPlanFree</code>


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3225/files#diff-e454a42c12dcbfcfaa463ab3421037408634e3a539f460525c79d68adfc118ab">+12/-9</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>grumpy-pigs-cough.md</strong><dd><code>Add changeset
for personal project deletion simplification</code></dd></summary>
<hr>

.changeset/grumpy-pigs-cough.md

<li>Add changeset file for minor version bump<br> <li> Include
description of changes for personal project deletion


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3225/files#diff-55a0b89d9ef990ec3e8deec02e8bea4f55e8d236a6f1c1ad95837ecf4f428154">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-03-04 19:38:44 +01:00
David BM
fe23bde306 chore (ci): local dashboard e2e tests with CLI (#3222)
### **User description**
Resolves #3173


___

### **PR Type**
Enhancement, Tests


___

### **Description**
- Add e2e tests for local dashboard with CLI

- Create new playwright configuration for local tests

- Update GitHub Actions for local dashboard testing

- Modify Nhost CLI action to support initialization


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Tests</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>cli-local-dashboard.test.ts</strong><dd><code>Add e2e
tests for local dashboard</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

dashboard/e2e/cli-local-dashboard/cli-local-dashboard.test.ts

<li>Add test for redirecting '/' to correct project URL<br> <li> Add
test for loading project URL correctly<br> <li> Verify visibility of
'Subdomain' text on project page


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3222/files#diff-69ade2acd215d2133e01fc3034eb291819613037596b96d4114f2f4c8489e7c1">+21/-0</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Configuration
changes</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>playwright.config.ts</strong><dd><code>Update main
playwright config</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

dashboard/playwright.config.ts

- Exclude 'Local Dashboard CLI e2e tests' from main configuration


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3222/files#diff-3ce7004405593146d0b9c501fc50a6a5ae2da8bb48b57dee2faf79ca9c09cf62">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>playwright.local.config.ts</strong><dd><code>Add new
playwright config for local tests</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

dashboard/playwright.local.config.ts

<li>Create new playwright configuration for local dashboard tests<br>
<li> Set specific test matching for CLI local dashboard tests<br> <li>
Configure browser and test settings for local testing


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3222/files#diff-416d6b4a1c916809500432ef6baeba2fe8b3074f996ed53a7225524305d0c65d">+31/-0</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>dirty-snakes-tell.md</strong><dd><code>Add changeset
for dashboard e2e tests</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/dirty-snakes-tell.md

<li>Add changeset for minor version bump of @nhost/dashboard<br> <li>
Describe addition of e2e tests for local dashboard with CLI


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3222/files#diff-f6416bd6a9e76d07e7cc59b7ea9c6d6da84dee648655178167165ea9da135af6">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>action.yaml</strong><dd><code>Enhance Nhost CLI action
with new features</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.github/actions/nhost-cli/action.yaml

<li>Add 'init' input to initialize new projects<br> <li> Add
'dashboard-image' input for custom dashboard images<br> <li> Implement
logic for initializing projects and using custom images


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3222/files#diff-e8038d7890827f629d377142b37c3b82b2ad94feb50f655767ebef4bb6e91734">+19/-1</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>ci.yaml</strong><dd><code>Update CI workflow for local
dashboard testing</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.github/workflows/ci.yaml

<li>Add steps to build and test dashboard locally<br> <li> Implement
Nhost CLI initialization for dashboard tests<br> <li> Add step to run
local dashboard e2e tests


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3222/files#diff-944291df2c9c06359d37cc8833d182d705c9e8c3108e7cfe132d61a06e9133dd">+28/-1</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>test-nhost-cli-action.yaml</strong><dd><code>Refactor
Nhost CLI action test workflow</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.github/workflows/test-nhost-cli-action.yaml

<li>Update Nhost CLI action usage to use 'init' parameter<br> <li>
Modify version checks and expected output<br> <li> Adjust paths and
commands for testing


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3222/files#diff-defe9dba19ff27b93c6b21e6308904b606b75cad29218bf849d29f7a8506a30e">+8/-7</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>package.json</strong><dd><code>Add local e2e test
script to package.json</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

dashboard/package.json

<li>Add new 'e2e-local' script for running local dashboard tests<br>
<li> Update 'e2e' script to use specific playwright config


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3222/files#diff-2d8d55c799cd71f1b35e831f075f8178ed1734c4820a2ad548b4dd24d6938d7c">+2/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-03-04 17:35:27 +01:00
David BM
ea2dbf8734 fix (dashboard): can change minor database version with unhealthy project (#3210) 2025-03-04 14:26:44 +01:00
David BM
f4167e328c fix (dashboard): split postgres version if using a beta like 17.2-0.0.0-beta1 (#3211)
### **User description**
Fixes #3175


___

### **PR Type**
Bug fix, Enhancement


___

### **Description**
- Fix Postgres version splitting for beta versions

- Improve major version validation in settings

- Add utility function for version splitting

- Implement tests for version splitting function


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>

<summary><strong>DatabaseServiceVersionSettings.tsx</strong><dd><code>Update
version handling in DatabaseServiceVersionSettings</code></dd></summary>
<hr>


dashboard/src/features/orgs/projects/database/settings/components/DatabaseServiceVersionSettings/DatabaseServiceVersionSettings.tsx

<li>Import new <code>splitPostgresMajorMinorVersions</code> utility<br>
<li> Update major version validation to check for positive number<br>
<li> Use new utility function to split Postgres versions


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3211/files#diff-a982b817513fc173371f7468ad642f99ee0c914e5990a48992fc1fa5e230765f">+9/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>index.ts</strong><dd><code>Add export for new version
splitting utility</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/database/settings/utils/splitPostgresMajorMinorVersions/index.ts

- Export `splitPostgresMajorMinorVersions` function


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3211/files#diff-d1fd3a4c358d12a8141c71fa1b73ecfbb422c5ddab3b77212e4b45cbbb759a25">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>

<summary><strong>splitPostgresMajorMinorVersions.ts</strong><dd><code>Implement
Postgres version splitting utility</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>


dashboard/src/features/orgs/projects/database/settings/utils/splitPostgresMajorMinorVersions/splitPostgresMajorMinorVersions.ts

<li>Implement <code>splitPostgresMajorMinorVersions</code> function<br>
<li> Split version string into major and minor parts


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3211/files#diff-2c41895bcbcaa13eb34bfb8321640dcdc2757dd920e40e46f2dcd0670c3e56a2">+11/-0</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Tests</strong></td><td><table>
<tr>
  <td>
    <details>

<summary><strong>splitPostgresMajorMinorVersions.test.ts</strong><dd><code>Add
tests for Postgres version splitting utility</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/database/settings/utils/splitPostgresMajorMinorVersions/splitPostgresMajorMinorVersions.test.ts

<li>Add tests for <code>splitPostgresMajorMinorVersions</code>
function<br> <li> Test regular and beta Postgres versions


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3211/files#diff-d6320a0f90b9fc7d0d1e4bea1434daa2ece4b326a442256a2b727219dc958efb">+15/-0</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>twenty-pets-brake.md</strong><dd><code>Add changeset
for version bump and fix description</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/twenty-pets-brake.md

<li>Add changeset for minor version bump<br> <li> Describe fix for
Postgres beta version splitting


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3211/files#diff-da03f8241486698793641c7a3ec58e11cdbb185b5920bd6bd7b281cd8513f5c3">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>

---------

Co-authored-by: robertkasza <167509084+robertkasza@users.noreply.github.com>
2025-02-27 00:27:19 +01:00
Nuno Pato
56ebb1f719 fix: dashboard: run analytics only in prod (#3220)
### **User description**
- only run analytics on production


___

### **PR Type**
Enhancement


___

### **Description**
- Run analytics only in production environment

- Add `isDevOrStaging` check for analytics rendering

- Update `Analytics` component conditional rendering

- Include changeset for version bump


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>_app.tsx</strong><dd><code>Conditionally Render
Analytics Component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

dashboard/src/pages/_app.tsx

<li>Import <code>isDevOrStaging</code> helper function<br> <li> Modify
<code>Analytics</code> component rendering condition<br> <li> Add check
to prevent analytics in dev/staging


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3220/files#diff-944e6c6d89cc2a23522cb7246ab566c540c8a06660c9c5385363493d3fb613af">+2/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>short-games-sniff.md</strong><dd><code>Add Changeset
for Version Bump</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

.changeset/short-games-sniff.md

<li>Add new changeset file<br> <li> Specify minor version bump for
'@nhost/dashboard'<br> <li> Include fix description for analytics


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3220/files#diff-9a2390872c90159af419f7698ad33ffa24a4c95a5b920ab6703f6318c4ad47e7">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-25 22:13:57 -01:00
github-actions[bot]
2b6a4adf40 chore: update versions (#3202)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @nhost/apollo@8.0.5

### Patch Changes

-   Updated dependencies [6b8163d]
    -   @nhost/nhost-js@3.2.5

## @nhost/google-translation@0.2.2

### Patch Changes

- 6b8163d: fix(nhost-js) update service URL generation for local
environments

## @nhost/react-apollo@17.0.1

### Patch Changes

-   @nhost/apollo@8.0.5
-   @nhost/react@3.10.1

## @nhost/react-urql@14.0.1

### Patch Changes

-   @nhost/react@3.10.1

## @nhost/hasura-auth-js@2.10.1

### Patch Changes

- 6b8163d: fix(nhost-js) update service URL generation for local
environments

## @nhost/nextjs@2.2.4

### Patch Changes

-   @nhost/react@3.10.1

## @nhost/nhost-js@3.2.5

### Patch Changes

- 6b8163d: fix(nhost-js) update service URL generation for local
environments
-   Updated dependencies [6b8163d]
    -   @nhost/hasura-auth-js@2.10.1

## @nhost/react@3.10.1

### Patch Changes

-   Updated dependencies [6b8163d]
    -   @nhost/nhost-js@3.2.5

## @nhost/vue@2.9.2

### Patch Changes

-   Updated dependencies [6b8163d]
    -   @nhost/nhost-js@3.2.5

## @nhost/dashboard@2.21.0

# @nhost/dashboard

## 2.17.0

### Minor Changes

-   fd59918: fix: redirect to 404 with nhost cli dashboard

## 2.16.0

### Minor Changes

-   f8e6b61: fix: can add rule groups in table permissions
-   9e404c8: fix: not redirect to 404 page if using local Nhost backend
-   ac4aa01: fix: can delete column in database page
-   4385524: fix: update url to check service health in local dashboard

### Patch Changes

-   @nhost/react-apollo@16.0.1
-   @nhost/nextjs@2.2.2

## 2.15.0

### Minor Changes

- f1052a8: fix: improve stability of the dashboard when pausing projects
-   30daa41: fix: update links to docs in overview page
-   7537237: feat: add image preview toggle in storage

## 2.14.0

### Minor Changes

- d43931e: fix: invalid organization slug/project subdomain doesn't open
404 page
- 5df6fa2: feat: add unencrypted disk warning in storage capacity
settings

### Patch Changes

-   44c1e17: chore: update `msw` to v1.3.5 to fix vulnerabilities
    -   @nhost/react-apollo@16.0.0
    -   @nhost/nextjs@2.2.1

## 2.13.0

### Minor Changes

- 21e90da: chore: remove restrictions on SMTP sender so My Name
[name@acme.com](mailto:name@acme.com) can be added
- 865dd93: fix: duplicate Run placeholders when there is an error in the
backend
- 6902a36: fix: can remove resources if postgres capacity is higher than
10
-   a535aa3: fix: fetch user roles locally in auth section
-   0c50816: fix: allow decimal numbers in database row insert
- aea6d18: chore: add warning when pausing a project about losing Run
services persistent volume data
- d3b4fc3: feat: allow to change postgres settings if project is paused
-   29d27e1: chore: update `next` to v14.2.22 to fix vulnerabilities
-   c9dca09: feat: add reset password form
-   b3bcacb: fix: paused project banner cannot read null project name

### Patch Changes

-   Updated dependencies [46fc520]
-   Updated dependencies [29d27e1]
    -   @nhost/nextjs@2.2.0
    -   @nhost/react-apollo@15.0.1

## 2.12.0

### Minor Changes

- eb95562: fix: show all available permission variables in permission
dropdown select

### Patch Changes

- 8b5c4a0: chore: cleanup layout and add disable duplicate atom key
checking in development mode

## 2.11.3

### Patch Changes

- 714dffa: fix: improve project polling logic and unify usage across
components

## 2.11.2

### Patch Changes

- 6a34f89: fix: improve project polling logic and unify usage across
components

## 2.11.1

### Patch Changes

-   0f6ce52: fix: consolidate useProject hook and fix jwt expired error

## 2.11.0

### Minor Changes

-   cea3ef5: Feat: add org and project placeholders

## 2.10.0

### Minor Changes

-   86ecf27: feat: add support for additional metrics in overview
- 21708be: feat: dashboard: add support for storage buckets to AI
assistants

## 1.30.0

### Minor Changes

- 50441a8: feat: add ui for project autoscaler settings and run services
autoscaler settings

## 1.29.0

### Minor Changes

-   55d8bb5: feat: integrate turnstile for signup verification
-   2a2e54c: fix: update docs url in run services form tooltip
- 18f942f: fix: display long error messages in error toast without
overflow

### Patch Changes

-   @nhost/react-apollo@13.0.0
-   @nhost/nextjs@2.1.22

## 1.28.2

### Patch Changes

- 52a38fe: chore: update dependencies to address security
vulnerabilities
-   Updated dependencies [52a38fe]
    -   @nhost/nextjs@2.1.21

## 1.28.1

### Patch Changes

-   9735fa2: chore: remove broken link

## 1.28.0

### Minor Changes

- 526183a: feat: allow filtering users in "make request as" in graphql
section
-   be3b85b: feat: add conceal errors toggle on auth settings page

### Patch Changes

- 35a2f12: fix: prevent run service details from opening when attempting
to delete
    -   @nhost/react-apollo@12.0.6
    -   @nhost/nextjs@2.1.20

## 1.27.0

### Minor Changes

-   a7cd02c: fix: resolve rate limit query

## 1.26.0

### Minor Changes

-   3773ad7: chore: update pricing information
- b63250d: fix: not allow run service creation form resubmission while
creating a run service
-   a44a1d4: feat: add rate limits settings page

### Patch Changes

-   @nhost/react-apollo@12.0.5
-   @nhost/nextjs@2.1.19

## 1.25.0

### Minor Changes

- d1ceede: feat: add setting to migrate postgres major and/or minor
versions
- e5d3d1a: fix: allow manually typing column for custom check in
database row permissions

### Patch Changes

-   @nhost/react-apollo@12.0.4
-   @nhost/nextjs@2.1.18

## 1.24.1

### Patch Changes

- 49f2e55: fix: use service subdomain in service form and service
details dialog
- 598b988: fix: use current project subdomain in ServiceDetailsDialog
component

## 1.24.0

### Minor Changes

-   abb24af: chore: add redirect to support page when project is locked
- 18a6455: feat: show contact us info and locked reason when project is
locked

### Patch Changes

-   e31eefa: fix: include ingresses field when updating run services

## 1.23.0

### Minor Changes

-   33284d3: fix: don't show double scrollbar in configuration editor

### Patch Changes

-   @nhost/react-apollo@12.0.3
-   @nhost/nextjs@2.1.17

## 1.22.0

### Minor Changes

-   998c037: fix: align drop-down list in select component
- 807b8c0: fix: show city name in region selection for project creation

## 1.21.0

### Minor Changes

- a2efeed: fix: improve project health error handling, add unknown state
and polling interval for health state

## 1.20.0

### Minor Changes

- 8ea4210: fix: error toasts can be closed individually, instead of
dismissing all toasts at once
- 58919ba: chore: add blink animation when project health service is
updating

## 1.19.0

### Minor Changes

- b519862: fix: get configuration in configuration editor using local
development environment

## 1.18.0

### Minor Changes

- 502abad: feat: add services health checks indicators to the overview
page
-   b3ff6ad: chore: update title text on service status modal
- dbadf59: feat: add project configuration TOML editor to the settings
page

## 1.17.0

### Minor Changes

- 77fba27: fix: postgres version validation when activating ai in ai
settings page
-   ac6d1b6: feat: use name instead of awsName

## 1.16.3

### Patch Changes

- 87a37cf: fix: remove unnecessary isPlatform check from verify button
disable logic on custom domains
    -   @nhost/react-apollo@12.0.2
    -   @nhost/nextjs@2.1.16

## 1.16.2

### Patch Changes

- a9413af: fix: update `GetAllWorkspacesAndProjects` query polling to
use exponential backoff
    -   @nhost/react-apollo@12.0.1
    -   @nhost/nextjs@2.1.15

## 1.16.1

### Patch Changes

-   @nhost/react-apollo@12.0.0
-   @nhost/nextjs@2.1.14

## 1.16.0

### Minor Changes

- c6d5c5c: feat: add toggle switch to enable/disable public access in
the database settings

## 1.15.2

### Patch Changes

-   @nhost/react-apollo@11.0.4
-   @nhost/nextjs@2.1.13

## 1.15.1

### Patch Changes

-   @nhost/react-apollo@11.0.3
-   @nhost/nextjs@2.1.12

## 1.15.0

### Minor Changes

-   a7bde37: feat: send metadata in the edit form

### Patch Changes

- 1bc615b: feat: improve error message handling in `ErrorToast`
component
    -   @nhost/react-apollo@11.0.2
    -   @nhost/nextjs@2.1.11

## 1.14.0

### Minor Changes

-   a448d7d: feat: allow configuring postmark and delete SMTP settings

## 1.13.3

### Patch Changes

-   5924bc3: fix: include password in `GetSmtpSettings` query
- c5ad634: fix: resolved an issue where one-click install links were
broken on Safari
- 7278991: fix: update graphql auto-embeddings configuration to use
String type for model field

## 1.13.2

### Patch Changes

-   026f84f: fix: use configuration server URL from environment variable

## 1.13.1

### Patch Changes

-   7e9a2ce: fix: resolve issue where run services form fails to open

## 1.13.0

### Minor Changes

-   dd5d262: feat: add model field to the auto-embeddings form
- 09962be: feat: enable settings and run services when running the
dashboard locally
- 9cdecb6: feat: enable users to update their email address from the
account settings page

## 1.12.2

### Patch Changes

-   c195c51: fix: send email upon signin for unverified users

## 1.12.1

### Patch Changes

- 93ebdf8: fix: use service urls when initilizaing NhostClient running
local dashboard
    -   @nhost/react-apollo@11.0.1
    -   @nhost/nextjs@2.1.10

## 1.12.0

### Minor Changes

- f242e4b: feat: add connect with github to the user's account settings
-   768ca17: chore: update dependencies
- d62bd0f: fix: "Track this" option within the SQL editor now correctly
updates the metadata
- 91c2bb6: feat: refactor sign-in and sign-up pages to enforce email
verification

### Patch Changes

-   943831f: fix: resolve an error toast issue when unpausing a project
-   Updated dependencies [768ca17]
    -   @nhost/react-apollo@11.0.0
    -   @nhost/nextjs@2.1.9

## 1.11.2

### Patch Changes

-   @nhost/react-apollo@10.0.2
-   @nhost/nextjs@2.1.8

## 1.11.1

### Patch Changes

-   981404f: fix: set default value for healthCheck field validation

## 1.11.0

### Minor Changes

- 7789469: chore: upgrade dependency `@graphql-codegen/cli` to `5.0.2`
to address vulnerability
- 6c11b75: feat: add update user displayName section in account settings

### Patch Changes

-   @nhost/react-apollo@10.0.1
-   @nhost/nextjs@2.1.7

## 1.10.0

### Minor Changes

-   49a80c2: chore: update dependencies
-   150c04a: feat: add healthcheck config to run services

### Patch Changes

- e03f141: fix: allow insert, update and delete on tables in `auth` and
`storage` schemas
- 28676f4: feat: add min postgres version check to enable the ai service
-   Updated dependencies [49a80c2]
    -   @nhost/react-apollo@10.0.0
    -   @nhost/nextjs@2.1.6

## 1.9.0

### Minor Changes

-   d86e5c9: feat: add support for filtering the logs using a RegExp

## 1.8.3

### Patch Changes

-   @nhost/react-apollo@9.0.3
-   @nhost/nextjs@2.1.5

## 1.8.2

### Patch Changes

- 6df4f02: fix: use custom error toast and show correct message when
sending an invite

## 1.8.1

### Patch Changes

-   @nhost/react-apollo@9.0.2
-   @nhost/nextjs@2.1.4

## 1.8.0

### Minor Changes

- 713d53c: feat: add catch-all route for workspace/project - useful for
documentation

### Patch Changes

-   3db2999: fix: refresh table list after running SQL using the editor
- 3c4dd55: fix: handle `Error` objects properly in the `ErrorToast`
component
- 92b434e: fix: resolve an issue where the checkbox in the data-grid
header did not select all rows
    -   @nhost/react-apollo@9.0.1
    -   @nhost/nextjs@2.1.3

## 1.7.0

### Minor Changes

-   0d8d0eb: Update docs and dashboard references

## 1.6.9

### Patch Changes

-   @nhost/react-apollo@9.0.0
-   @nhost/nextjs@2.1.2

## 1.6.8

### Patch Changes

-   @nhost/react-apollo@8.0.1
-   @nhost/nextjs@2.1.1

## 1.6.7

### Patch Changes

-   5ef5189: fix: update `@apollo/client` to `3.9.4` to fix a cache bug

## 1.6.6

### Patch Changes

-   3ba485e: fix: added discord.com to connect-src
-   e5bab6a: chore: update dependencies
-   Updated dependencies [b19ffed]
-   Updated dependencies [e5bab6a]
    -   @nhost/nextjs@2.1.0
    -   @nhost/react-apollo@8.0.0

## 1.6.5

### Patch Changes

- ba73bb4: fix: update ErrorToast component to show the internal graphql
error
- d5337ff: fix: utilize accumulator in the creation of validation schema
within data grid utils

## 1.6.4

### Patch Changes

-   7c2a1c2: feat: show error and debug info in the error toast

## 1.6.3

### Patch Changes

-   6b8aad5: fix: add bare nhost.run to CSP

## 1.6.2

### Patch Changes

-   b18edc0: feat: added CSP and X-Frame-Options

## 1.6.1

### Patch Changes

-   8d91f71: chore: update deps and enable pnpm audit
- 3b8473b: chore: update turbo to `1.11.3` and pnpm to `8.10.5` in
Dockerfile
-   Updated dependencies [8d91f71]
    -   @nhost/react-apollo@7.0.2
    -   @nhost/nextjs@2.0.2

## 1.6.0

### Minor Changes

-   3ff1c2b53: fix: show upgrade option for pro projects

## 1.5.0

### Minor Changes

-   c2ef17c0a: feat: add support for new Team plan

## 1.4.0

### Minor Changes

-   7883bbcbd: feat: don't show deprecated plans
- 44be6dc0a: feat: set redirectTo during sign-in to support preview
environments

### Patch Changes

- 3c3594898: fix: allow access to graphite when configured running in
local dashboard
-   32c246b7a: chore: update docs icon

## 1.3.2

### Patch Changes

-   174b4165b: chore: use env variables when running graphql codegen
-   7c977e714: chore: change `Allowed Roles` to `Default Allowed Roles`
-   46f028b9f: fix: remove hardcoded ai version setting

## 1.3.1

### Patch Changes

- af33c21d1: chore: remove backendUrl deprecation notice and remove all
references to `providersUpdated`

## 1.3.0

### Minor Changes

-   04784d880: Fix graphite's default version

## 1.2.0

### Minor Changes

-   5733162ed: feat: add settings and ui for graphite

## 1.1.0

### Minor Changes

-   e2b79b5ec: chore: remove sharp from deps

## 1.0.1

### Patch Changes

-   @nhost/react-apollo@7.0.1
-   @nhost/nextjs@2.0.1

## 1.0.0

### Major Changes

- bc9eff6e4: chore: remove support for using backendUrl when
instantiating the Nhost client

### Patch Changes

-   Updated dependencies [bc9eff6e4]
    -   @nhost/nextjs@2.0.0
    -   @nhost/react-apollo@7.0.0

## 0.21.1

### Patch Changes

-   97ced73a3: fix(dashboard): prevent dashboard from resolving secrets

## 0.21.0

### Minor Changes

- ed1a8d458: Update alert message on increasing PostgreSQL's volume
capacity
-   2e2248fd4: feat(dashboard): add SQL editor

## 0.20.28

### Patch Changes

-   7c2c31082: feat: add support for users to delete their account
    -   @nhost/react-apollo@6.0.1
    -   @nhost/nextjs@1.13.40

## 0.20.27

### Patch Changes

- fa79b7709: chore(dashboard): tweaks and fixes to the service form and
dialog
-   8df84d782: fix(dashboard): allow resetting custom domains
    -   @nhost/react-apollo@6.0.0
    -   @nhost/nextjs@1.13.39

## 0.20.26

### Patch Changes

- 331ba0376: feat(dashboard): add postgres storage capacity modifier in
the settings
-   b7f801874: feat(dashboard): add new settings page for custom domains

## 0.20.25

### Patch Changes

-   @nhost/react-apollo@5.0.38

## 0.20.24

### Patch Changes

-   e10389ecf: fix(dashboard): disable run tab when developing locally
    -   @nhost/react-apollo@5.0.37

## 0.20.23

### Patch Changes

-   c01568a7d: chore(dashboard): show alert to update oauth providers

## 0.20.22

### Patch Changes

-   c3efb7ec8: feat(dashboard): query latest announcement from platform

## 0.20.21

### Patch Changes

-   3e46d3873: chore: update link to node18 announcement

## 0.20.20

### Patch Changes

-   @nhost/react-apollo@5.0.36
-   @nhost/nextjs@1.13.38

## 0.20.19

### Patch Changes

-   75c4c8ae3: feat(dashboard): make env value input multiline

## 0.20.18

### Patch Changes

- 425d485f8: fix(dashboard): make sure dedicated resources pricing
follows total resources

## 0.20.17

### Patch Changes

-   ae324f67f: fix(dashboard): remove unused graphql fields

## 0.20.16

### Patch Changes

-   df5b4302c: chore(dashboard): remove run feature flag
- bf4a1f6c2: feat(dashboard): fetch auth, postgres, hasura and storage
versions from dashboard
- 34fc08ca7: fix(dashboard/run): show correct private registry in
service details
-   885d10620: chore(dashboard): change feedback to contact us

## 0.20.15

### Patch Changes

- ed16c8b5d: feat(run): add a confirmation dialog when deleting a run
service
- 216990888: fix(run): center loading indicator when selecting a project

## 0.20.14

### Patch Changes

-   9fbea9787: feat: add node18 announcement

## 0.20.13

### Patch Changes

- e84acf469: fix(run): handle subdomain undefined error when creating a
new service

## 0.20.12

### Patch Changes

-   b7c799d62: feat(run): add dialog to copy registry and URLs

## 0.20.11

### Patch Changes

-   8903e6abd: fix(dashboard): show correct egress limit in usage stats

## 0.20.10

### Patch Changes

- 666a75a23: feat(dashboard): add functions execution time and egress
volume to usage stats

## 0.20.9

### Patch Changes

-   5e1e80aa8: fix(dashboard): show correct locales in user details
    -   @nhost/react-apollo@5.0.35
    -   @nhost/nextjs@1.13.37

## 0.20.8

### Patch Changes

-   @nhost/react-apollo@5.0.34
-   @nhost/nextjs@1.13.36

## 0.20.7

### Patch Changes

-   4a7ede11e: fix: distinguish files that were not uploaded
- 202b64723: feat(nhost-run): add support for one-click-install run
services
- 074a0fa11: feat(dashboard): add settings toggle to enable/disable
antivirus
    -   @nhost/react-apollo@5.0.33
    -   @nhost/nextjs@1.13.35

## 0.20.6

### Patch Changes

-   b20761e97: feat(services): add pricing info and confirmation dialog
-   90df6d81d: fix(services): handle null values when editing a service
-   aa8508467: fix: query service logs correctly
    feat: enable multiline support for environment value input

## 0.20.5

### Patch Changes

-   8d7f84b8d: fix: make announcement adapt to theme

## 0.20.4

### Patch Changes

-   3b75bfce2: fix: make announcement close properly
- f49819075: fix: show correct values when dedicated resources are
disabled

## 0.20.3

### Patch Changes

-   e643bd362: fix(services): fix errors when config is null
-   bcdab66bf: feat: add annoucement for nhost run
-   f967a2e59: added note about storage not being able to be downsized
-   311c7756d: chore(services): consistent naming for compute

## 0.20.2

### Patch Changes

-   9073182d5: chore(dashboard): bump `turbo` to 1.10.11
-   ece717d6e: feat(logs): show services in the logs page
- 82b335311: feat(metrics): change grafana link to point to the
dashboards
- b135ef695: fix(services): set command as optional and set min replicas
to 0

## 0.20.1

### Patch Changes

-   3d5c34f4c: fix(auth): fix users pagination limit

## 0.20.0

### Minor Changes

-   c99d117d1: feat(services): add support for custom services

## 0.19.2

### Patch Changes

-   face99ccd: chore(deps): bump turbo version
-   cfe527307: style: tweak pull config warning in dark mode
- a9d7da8af: chore(deps): update dependency @types/pluralize to ^0.0.30
-   9aa4371ef: chore: add hasura-auth version 0.21.2
- d14e112bf: chore(deps): update dependency prettier-plugin-tailwindcss
to ^0.4.0
-   d3e8bb94a: chore(deps): update dependency vite-plugin-dts to v3

## 0.19.1

### Patch Changes

-   @nhost/react-apollo@5.0.32
-   @nhost/nextjs@1.13.34

## 0.19.0

### Minor Changes

- 9c61c69a7: chore(dashboard):add postgres 14.6-20230705-1 to the
version selector

### Patch Changes

-   47bda15ff: feat(settings): add warning to pull config

## 0.18.0

### Minor Changes

- ee0b9b8ed: chore(dashboard):add hasura v2.28.2 and v2.29.0 to the
version selector

## 0.17.20

### Patch Changes

-   @nhost/react-apollo@5.0.31
-   @nhost/nextjs@1.13.33

## 0.17.19

### Patch Changes

-   f866120a6: fix(users): use the password length from the config

## 0.17.18

### Patch Changes

-   @nhost/react-apollo@5.0.30
-   @nhost/nextjs@1.13.32

## 0.17.17

### Patch Changes

-   ea7b102c0: fix(pat): highlight expired tokens

## 0.17.16

### Patch Changes

- b3b64a3b7: chore(deps): bump `@types/react` to `v18.2.14` and
`@types/react-dom` to `v18.2.6`
-   32b221f94: chore(deps): bump `graphiql` to `v3`
-   3a56c12df: chore(deps): bump `turbo` to `v1.10.6`
-   Updated dependencies [b3b64a3b7]
    -   @nhost/react-apollo@5.0.29
    -   @nhost/nextjs@1.13.31

## 0.17.15

### Patch Changes

-   f41fdc12a: chore(deps): bump `turbo` to `1.10.5`
-   6199c1c55: fix(projects): don't redirect to 404 page
-   Updated dependencies [07a45fde0]
    -   @nhost/react-apollo@5.0.28
    -   @nhost/nextjs@1.13.30

## 0.17.14

### Patch Changes

- 80b22724d: chore(deps): bump `@types/react` to `v18.2.13`,
`@types/react-dom` to `v18.2.6` and `@storybook/testing-library` to
`v0.2.0`

## 0.17.13

### Patch Changes

-   cc02902cb: chore(docs): update environment variable documentation

## 0.17.12

### Patch Changes

-   660d339e1: fix(storybook): don't break storybook
-   660d339e1: fix(tests): prevent warnings during tests
    -   @nhost/react-apollo@5.0.27
    -   @nhost/nextjs@1.13.29

## 0.17.11

### Patch Changes

- bd4d0c270: chore(dashboard):add postgres 14.6-20230613-1 to the
version selector

## 0.17.10

### Patch Changes

-   c8c2a10b2: fix(database): don't break the password reset flow
- e70b45498: chore(deps): bump `@types/react` to `v18.2.12` and
`@types/react-dom` to `v18.2.5`

## 0.17.9

### Patch Changes

- 842055099: chore(deps): bump `turbo` to `v1.10.3` and `pnpm` to
`v8.6.2`
- fd12aa0a8: chore(projects): remove the postgres password input from
the project creation screen
-   022b76e78: chore(deps): bump `@types/react` to `v18.2.11`
-   3555ab2b7: chore(deps): bump `vitest` monorepo to `v0.32.0`
-   c43e54922: feat(backups): add download button to backups

## 0.17.8

### Patch Changes

-   d0457fe5c: feat(settings): improve the dashboard and config parity
    -   @nhost/react-apollo@5.0.26
    -   @nhost/nextjs@1.13.28

## 0.17.7

### Patch Changes

-   4f0368b95: fix(account): don't break account settings page

## 0.17.6

### Patch Changes

- 64a8f41d0: chore(resources): lower the maximum allowed resources per
service

## 0.17.5

### Patch Changes

-   @nhost/react-apollo@5.0.25
-   @nhost/nextjs@1.13.27

## 0.17.4

### Patch Changes

- 9b1d0f7a5: fix(deployments): use correct timestamp for deployment
details
-   6d2963ffa: chore(deps): bump `@types/react` to `v18.2.8`
- 8871267b9: chore(deps): downgrade `pnpm` to `v8.5.1` because of no
Turborepo support

## 0.17.3

### Patch Changes

-   01eeef9de: chore(misc): under the hood improvements
- 21e13db05: chore(deps): bump `@types/react` to `v18.2.7` and `turbo`
to `v1.10.1`
- f16433ae6: chore(secrets): allow empty secrets and environment
variables
-   aa3c62989: chore(cli): bump Nhost CLI version to v1.0
    -   @nhost/react-apollo@5.0.24
    -   @nhost/nextjs@1.13.26

## 0.17.2

### Patch Changes

-   88a4983f: chore(misc): under the hood improvements

## 0.17.1

### Patch Changes

-   9b0d4dde: feat(secrets): enable secrets

## 0.17.0

### Minor Changes

-   15d84a19: Add postgres 14.6-20230525

## 0.16.14

### Patch Changes

-   4c626174: chore: updated import paths, improved directory structure
-   cc047b71: chore(deps): bump `@fontsource` monorepo to `v5.0.0`
-   99edd012: feat(account): add support for personal access tokens

## 0.16.13

### Patch Changes

-   78c7109c: feat(settings): allow selecting service versions

## 0.16.12

### Patch Changes

- 399009d6: fix(gql): don't enter an infinite loop when fetching remote
app data
- 329e5a91: fix(deployments): use the same sorting of deployments
everywhere
- 6d559d6e: chore(settings): add under the hood improvements to the
settings page
- 12eb236c: chore(deps): bump `prettier-plugin-tailwindcss` to `v0.3.0`
-   f9b81a2a: chore(deps): bump `turbo` to `v1.9.8`
-   1345741b: fix(projects): don't redirect to 404 on project creation
-   Updated dependencies [7fea29a8]
    -   @nhost/react-apollo@5.0.23
    -   @nhost/nextjs@1.13.25

## 0.16.11

### Patch Changes

- 1230b722: fix(projects): don't redirect to 404 on when the project is
renamed
    -   @nhost/react-apollo@5.0.22
    -   @nhost/nextjs@1.13.24

## 0.16.10

### Patch Changes

-   Updated dependencies [da03bf39]
    -   @nhost/react-apollo@5.0.21
    -   @nhost/nextjs@1.13.23

## 0.16.9

### Patch Changes

- 349aac36: fix(settings): use region domain when constructing the
postgres connection string

## 0.16.8

### Patch Changes

- 20fb69fa: chore(projects): change the way how API URLs are constructed

## 0.16.7

### Patch Changes

- 49f9b837: chore(docker): bump `pnpm` to `v8.4.0` and `turbo` to
`v1.9.3`
- 3f478a4e: chore(deps): bump `vitest` to `v0.31.0`, `@types/react` to
`v18.2.6` and `@types/react-dom` to `v18.2.4`

## 0.16.6

### Patch Changes

- d926f156: fix(projects): redirect to 404 when an invalid project is
opened
- 49b99728: fix(projects): disable features for non-owner members of
workspaces

## 0.16.5

### Patch Changes

-   12e2855f: chore(deps): bump `jsdom` to v22
-   e4972b83: feat(metrics): add Grafana page

## 0.16.4

### Patch Changes

- 3f396a9e: fix(projects): unpause after upgrading a paused project to
pro
- 3f396a9e: fix(projects): don't redirect to 404 page after project
creation

## 0.16.3

### Patch Changes

-   Updated dependencies [90c60311]
    -   @nhost/react-apollo@5.0.20
    -   @nhost/nextjs@1.13.22

## 0.16.2

### Patch Changes

-   0f34f0c6: fix(projects): disallow downgrading to free plan
- 8da291ad: chore(deps): bump `@types/react` to v18.2.0 and
`@types/react-dom` to v18.2.1

## 0.16.1

### Patch Changes

- adc828a5: fix(gql): don't enter an infinite loop when fetching remote
app data

## 0.16.0

### Minor Changes

-   2fb1145f: feat(compute): add support for replicas

### Patch Changes

- d8ceccec: chore(env): remove deprecated `NHOST_BACKEND_URL`
environment variable

## 0.15.2

### Patch Changes

-   84b84ab7: fix(projects): filter projects by workspace

## 0.15.1

### Patch Changes

-   2faf7907: chore(deps): bump `graphql-request` to v6
-   f1b5a944: chore(deps): bump `@vitejs/plugin-react` to v4
-   7f1785ac: chore(deps): bump `@types/react` to v18.0.37
    -   @nhost/react-apollo@5.0.19

## 0.15.0

### Minor Changes

-   85889ee8: feat(dashboard): add Compute management to the settings

## 0.14.8

### Patch Changes

-   668c8771: chore(dialogs): unify dialog management of payment dialogs

## 0.14.7

### Patch Changes

-   d4ccc656: chore: cleanup unused code
    -   @nhost/react-apollo@5.0.18
    -   @nhost/nextjs@1.13.21

## 0.14.6

### Patch Changes

-   b299cfc9: chore(deps): bump `vitest` to v0.30.0
-   411cb65b: chore(projects): refactor workspace and project hooks
- 43b1b144: chore(deps): bump `@types/react` to v18.0.34 and
`@types/react-dom` to v18.0.11
-   Updated dependencies [43b1b144]
    -   @nhost/react-apollo@5.0.17
    -   @nhost/nextjs@1.13.20

## 0.14.5

### Patch Changes

-   ba0d57ee: fix(i18n): revert i18n library
-   3328ed05: feat(projects): improve overview when there is an error

## 0.14.4

### Patch Changes

-   5e0920ba: chore(deps): bump `next-seo` to v6
-   706c9dc3: chore(deps): bump `@types/react` to 18.0.33
-   99f8f6b3: feat(metrics): show metrics on the overview

## 0.14.3

### Patch Changes

-   @nhost/react-apollo@5.0.16

## 0.14.2

### Patch Changes

-   3cb67300: fix(logs): don't break UI when clearing time picker
-   7453bf3b: feat(projects): show project creator info
-   c166dad0: chore(tests): improve auth page tests
-   6a290bb2: chore(deps): bump `@types/react` to 18.0.32

## 0.14.1

### Patch Changes

-   @nhost/react-apollo@5.0.15
-   @nhost/nextjs@1.13.19

## 0.14.0

### Minor Changes

-   6e1f03ea: feat(dashboard): add support for the Azure AD provider

### Patch Changes

-   1bd2c373: chore(deps): bump `turbo` to 1.8.6
-   d329b621: chore(deps): bump `@types/react` to 18.0.30
-   cb248f0d: fix(tests): avoid name collision in database tests
-   867c8076: chore(deps): bump `@types/react` to 18.0.29

## 0.13.10

### Patch Changes

- e93b06ab: fix(dashboard): remove left margin from workspace list on
mobile
-   1c4806bf: chore(deps): bump `sharp` to 0.32.0
    -   @nhost/react-apollo@5.0.14
    -   @nhost/nextjs@1.13.18

## 0.13.9

### Patch Changes

-   912ed76c: chore(dashboard): bump `@apollo/client` to 3.7.10
-   Updated dependencies [912ed76c]
    -   @nhost/react-apollo@5.0.13

## 0.13.8

### Patch Changes

-   7c127372: chore(dashboard): bump `react-error-boundary` to v4

## 0.13.7

### Patch Changes

- 9130ab12: chore(dashboard): bump `yup` to v1 and `@hookform/resolvers`
to v3

## 0.13.6

### Patch Changes

- 253dd235: using new mutation to create projects + refactor Create
Project page.

## 0.13.5

### Patch Changes

-   @nhost/react-apollo@5.0.12
-   @nhost/nextjs@1.13.17

## 0.13.4

### Patch Changes

-   b48bc034: fix(dashboard): disable new users
-   798e591b: fix(dashboard): show correct date in data grid

## 0.13.3

### Patch Changes

-   bfb4c1a6: chore(dashboard): remove `useAxios` property
-   d8d8394b: Dashboard: allow to override hasura admin secret in docker
-   Updated dependencies [ce1ee40d]
    -   @nhost/nextjs@1.13.16
    -   @nhost/react-apollo@5.0.11

## 0.13.2

### Patch Changes

-   beed2eba: Fix docker entrypoint for dashboard
- 2c8559a3: fix(dashboard): refresh project list after deleting a
project
-   4329d048: chore(dashboard): bump `graphiql` dependencies

## 0.13.1

### Patch Changes

-   cbb1fc5b: chore(dashboard): cleanup GraphQL operations

## 0.13.0

### Minor Changes

-   088584e7: feat(dashboard): add support for custom local subdomains

### Patch Changes

-   2ac90dfd: fix(dashboard): improve mobile responsive layout
-   Updated dependencies [f375eacc]
    -   @nhost/nextjs@1.13.15
    -   @nhost/react-apollo@5.0.10

## 0.12.4

### Patch Changes

-   @nhost/react-apollo@5.0.9
-   @nhost/nextjs@1.13.14

## 0.12.3

### Patch Changes

-   2b1338f7: chore(dashboard): bump `turbo` to 1.8.3
- 5223ee93: fix(dashboard): show correct deployment status on the main
page
-   850a049c: chore(deps): update docker/build-push-action action to v4
-   Updated dependencies [850a049c]
    -   @nhost/nextjs@1.13.13
    -   @nhost/react-apollo@5.0.8

## 0.12.2

### Patch Changes

-   4bf40995: chore(deps): bump `typescript` to `4.9.5`
-   8bb097c9: chore(deps): bump `vitest`
- 35d52aab: chore(deps): replace `cross-fetch` with `isomorphic-unfetch`
-   Updated dependencies [4bf40995]
-   Updated dependencies [8bb097c9]
-   Updated dependencies [35d52aab]
    -   @nhost/react-apollo@5.0.7
    -   @nhost/nextjs@1.13.12

## 0.12.1

### Patch Changes

-   c96d7ccd: fix(dashboard): fix docker builds

## 0.12.0

### Minor Changes

-   d1671210: feat(dashboard): use mimir to manage project configuration

### Patch Changes

-   f65e4de9: chore(deps): bump @graphql-codegen monorepo to v3

## 0.11.20

### Patch Changes

-   4b4f0d01: chore(dashboard): improve dialog management

## 0.11.19

### Patch Changes

-   @nhost/react-apollo@5.0.6
-   @nhost/nextjs@1.13.11

## 0.11.18

### Patch Changes

-   01318860: fix(nhost-js): use correct URL for functions requests
-   Updated dependencies [01318860]
    -   @nhost/react-apollo@5.0.5
    -   @nhost/nextjs@1.13.10

## 0.11.17

### Patch Changes

-   f673adea: fix(dashboard): set correct Content-Type for user creation
-   445d8ef4: chore(deps): bump `@nhost/react-apollo` to 5.0.4
-   445d8ef4: chore(deps): bump `@nhost/nextjs` to 1.13.9
- 0368663d: fix(dashboard): allow permission editing for auth and
storage schemas
-   Updated dependencies [445d8ef4]
-   Updated dependencies [445d8ef4]
    -   @nhost/react-apollo@5.0.4
    -   @nhost/nextjs@1.13.9

## 0.11.16

### Patch Changes

-   b755e908: fix(dashboard): use correct date for last seen
-   2d9145f9: chore(deps): revert GraphQL client
- 1ddf704c: fix(dashboard): don't show false positive message for failed
user creation
    -   @nhost/react-apollo@5.0.3
    -   @nhost/nextjs@1.13.8

## 0.11.15

### Patch Changes

-   @nhost/react-apollo@5.0.2
-   @nhost/nextjs@1.13.7

## 0.11.14

### Patch Changes

- 2cc18dcb: fix(dashboard): prevent permission editor dropdown from
being always open

## 0.11.13

### Patch Changes

- 3343a363: chore(dashboard): bump `@testing-library/react` to v14 and
`@testing-library/dom` to v9
    -   @nhost/react-apollo@5.0.1
    -   @nhost/nextjs@1.13.6

## 0.11.12

### Patch Changes

- 87eda76e: chore(dashboard): bump `@types/react` to v18.0.28 and
`@types/react-dom` to v18.0.11
-   6f0ac570: feat(dashboard): show dashboard version in account menu

## 0.11.11

### Patch Changes

-   bf1e4071: chore(dashboard): bump `react-is` version to `18.2.0`
-   Updated dependencies [bf1e4071]
-   Updated dependencies [5013213b]
    -   @nhost/nextjs@1.13.5
    -   @nhost/react-apollo@4.13.5

## 0.11.10

### Patch Changes

- a37a430b: fix(dashboard): don't break UI when deployments are
unavailable
    -   @nhost/react-apollo@4.13.4
    -   @nhost/nextjs@1.13.4

## 0.11.9

### Patch Changes

-   7b970e68: fix(dashboard): fix header link color

## 0.11.8

### Patch Changes

- f33242f2: feat(dashboard): add new sign up, sign in and reset password
pages

## 0.11.7

### Patch Changes

-   e9c8909c: fix(dashboard): use correct theme color in dark mode

## 0.11.6

### Patch Changes

-   902f486b: fix(dashboard): re-enable Hasura on logs page

## 0.11.5

### Patch Changes

-   1f9720fa: fix(dashboard): apply select permissions properly

## 0.11.4

### Patch Changes

-   deb14b51: fix(dashboard): don't break billing form

## 0.11.3

### Patch Changes

-   @nhost/react-apollo@4.13.3
-   @nhost/nextjs@1.13.3

## 0.11.2

### Patch Changes

-   f143e51d: chore(dashboard): pin Turborepo to 1.6.3

## 0.11.1

### Patch Changes

-   c2b5a41a: chore(dashboard): select system colors by default

## 0.11.0

### Minor Changes

-   1ebaf429: feat(dashboard): introduce Dark Mode 🌚

### Patch Changes

- 63b445c4: fixed duplicated logs bug and made to date count during live
mode

## 0.10.1

### Patch Changes

-   e146d32e: chore(deps): update dependency @types/react to v18.0.27
-   59347fcd: correct allowed role name
-   5b65cac9: updated authentication documentation
-   963f9b5e: feat(dashboard): include project info in feedback

## 0.10.0

### Minor Changes

-   ed4c7801: chore(dashboard): remove Functions section

## 0.9.10

### Patch Changes

-   4e2f8ccd: fix(dashboard): don't break Auth page in local mode

## 0.9.9

### Patch Changes

-   31abbe5f: fix(dashboard): enable toggle when settings are filled in

## 0.9.8

### Patch Changes

- 5bdd31ad: chore(dashboard): list fewer images per page on the Storage
page
- 5121851c: fix(dashboard): don't throw validation error for valid
permission rules

## 0.9.7

### Patch Changes

-   c126b20d: fix(dashboard): correct redeployment button

## 0.9.6

### Patch Changes

-   36c3519c: feat(dashboard): retrigger deployments

## 0.9.5

### Patch Changes

- 200e9f77: chore(deps): update dependency @types/react-dom to v18.0.10
-   Updated dependencies [200e9f77]
    -   @nhost/nextjs@1.13.2
    -   @nhost/react-apollo@4.13.2

## 0.9.4

### Patch Changes

- dbd3ded5: fix(dashboard): workspaces creation, new form, correct
redirects.

## 0.9.3

### Patch Changes

-   85f0f943: fix(dashboard): don't break the table creation process

## 0.9.2

### Patch Changes

-   Updated dependencies [d42c27ae]
-   Updated dependencies [927be4a2]
    -   @nhost/nextjs@1.13.1
    -   @nhost/react-apollo@4.13.1

## 0.9.1

### Patch Changes

-   d0f80811: fix(dashboard): don't show error when signing out the user

## 0.9.0

### Minor Changes

- d92891b2: feat(dashboard): add Permission Editor to the Database
section

### Patch Changes

-   3d379128: fix(dashboard): create new user
    -   @nhost/react-apollo@4.13.0
    -   @nhost/nextjs@1.13.0

## 0.8.1

### Patch Changes

-   7cadd944: fix(dashboard): display Twitter provider settings

## 0.8.0

### Minor Changes

-   9a1aa7bb: add functions to the log dashboard
-   f29abe62: feat(dashboard): Users Management v2

### Patch Changes

-   7766624b: feat(dashboard): add JWT secret editor modal
    -   @nhost/react-apollo@4.12.1
    -   @nhost/nextjs@1.12.1

## 0.7.13

### Patch Changes

-   dd0738d5: fix(dashboard): provisioning status polling

## 0.7.12

### Patch Changes

-   b21222b3: chore(deps): update dependency @types/node to v16
-   9e0486a3: fix(dashboard): close modals when navigating
-   Updated dependencies [b21222b3]
-   Updated dependencies [65687bee]
-   Updated dependencies [54df0df4]
    -   @nhost/nextjs@1.12.0
    -   @nhost/react-apollo@4.12.0

## 0.7.11

### Patch Changes

-   d6527122: fix(dashboard): use correct service URLs

## 0.7.10

### Patch Changes

-   Updated dependencies [57db5b83]
    -   @nhost/nextjs@1.11.0
    -   @nhost/nhost-js@1.7.0
    -   @nhost/react@0.17.0
    -   @nhost/react-apollo@4.11.0

## 0.7.9

### Patch Changes

- a6d31dc2: fix(dashboard): don't break the UI when project is not
loaded yet

## 0.7.8

### Patch Changes

- 7f251111: Use `NhostProvider` instead of `NhostReactProvider` and
`NhostNextProvider`

    `NhostReactProvider` and `NhostNextProvider` are now deprecated

-   f4d70f88: fix(dashboard): do not break when region is nullish

- 4a9471cc: Windows Live Provider displayed link updated to match
backend url

- 594488e4: fix(dashboard): do not show error when submitting Apple
provider settings

-   Updated dependencies [7f251111]
    -   @nhost/nextjs@1.10.0
    -   @nhost/react@0.16.0
    -   @nhost/react-apollo@4.10.0

## 0.7.7

### Patch Changes

-   80b604ad: fix(dashboard): use correct Hasura slug

## 0.7.6

### Patch Changes

-   2d2beb53: fix(dashboard): prevent error on GraphQL page
-   ac8efcbd: chore(dashboard): deprecate old DNS name

## 0.7.5

### Patch Changes

-   132a4f4b: chore(dashboard): remove unused dependencies
- 132a4f4b: chore(deps): synchronize @types/react-dom and @types/react
versions
-   db57572f: fix(dashboard): correct section paddings when no env vars
-   Updated dependencies [132a4f4b]
    -   @nhost/react@0.15.2
    -   @nhost/react-apollo@4.9.2
    -   @nhost/nextjs@1.9.3

## 0.7.4

### Patch Changes

-   34d85e54: chore(deps): update dependency critters to ^0.0.16
- 9b93cf95: chore(deps): update dependency @netlify/functions to ^0.11.0
-   e0439030: chore(deps): update dependency @types/react-dom to v18.0.9
-   Updated dependencies [82124329]
    -   @nhost/nextjs@1.9.2

## 0.7.3

### Patch Changes

-   a1193da4: fix(dashboard): remove character limit from env var inputs

## 0.7.2

### Patch Changes

-   44f13f62: chore(dashboard): cleanup unused files

## 0.7.1

### Patch Changes

- e01cb2ed: chore(dashboard): change settings sidebar menu item density

## 0.7.0

### Minor Changes

- db342f45: chore(dashboard): refactor Roles and Permissions settings
sections
-   8b9fa0b1: feat(dashboard): add Environment Variables page

### Patch Changes

-   Updated dependencies [66b4f3d0]
-   Updated dependencies [2e6923dc]
-   Updated dependencies [ef117c28]
-   Updated dependencies [aebb8225]
    -   @nhost/core@0.9.4
    -   @nhost/nhost-js@1.6.2
    -   @nhost/nextjs@1.9.1
    -   @nhost/react@0.15.1
    -   @nhost/react-apollo@4.9.1

## 0.6.0

### Minor Changes

-   eef9c914: feat(dashboard): add Roles and Permissions page

## 0.5.0

### Minor Changes

-   a48dd5bf: feat(dashboard): make backend port configurable

## 0.4.3

### Patch Changes

-   5de965d9: fix(dashboard): alphabetic ordering of providers
-   b9087a4a: fix(dashboard): console -> dashboard terminology
-   ca012d79: docs(workos): WorkOS Docs

## 0.4.2

### Patch Changes

-   89bd37bc: fix(dashboard): correct redirect URL input opacity
-   Updated dependencies [4601d84e]
-   Updated dependencies [843087cb]
    -   @nhost/react@0.15.0
    -   @nhost/nextjs@1.9.0
    -   @nhost/react-apollo@4.9.0

## 0.4.1

### Patch Changes

-   766cb612: fix(dashboard): correct redirect URL for oauth providers
-   Updated dependencies [53bdc294]
-   Updated dependencies [f2aaff05]
    -   @nhost/nextjs@1.8.3
    -   @nhost/core@0.9.3
    -   @nhost/react@0.14.3
    -   @nhost/nhost-js@1.6.1
    -   @nhost/react-apollo@4.8.3

## 0.4.0

### Minor Changes

-   9211743d: feat(dashboard): migrate Settings page features

## 0.3.0

### Minor Changes

-   73da6a67: fix(dashboard): avoid using BACKEND_URL locally

## 0.2.0

### Minor Changes

-   db118f97: feat(dashboard): generate Docker image

## @nhost/docs@2.28.1

### Patch Changes

- 6b8163d: fix(nhost-js) update service URL generation for local
environments

## @nhost-examples/cli@0.3.18

### Patch Changes

-   Updated dependencies [6b8163d]
    -   @nhost/nhost-js@3.2.5

## @nhost-examples/codegen-react-apollo@0.5.1

### Patch Changes

-   @nhost/react@3.10.1
-   @nhost/react-apollo@17.0.1

## @nhost-examples/codegen-react-query@0.5.1

### Patch Changes

- 6b8163d: fix(nhost-js) update service URL generation for local
environments
    -   @nhost/react@3.10.1

## @nhost-examples/codegen-react-urql@0.4.1

### Patch Changes

-   @nhost/react@3.10.1
-   @nhost/react-urql@14.0.1

## @nhost-examples/multi-tenant-one-to-many@2.2.19

### Patch Changes

-   Updated dependencies [6b8163d]
    -   @nhost/nhost-js@3.2.5

## @nhost-examples/nextjs@0.4.4

### Patch Changes

-   @nhost/react@3.10.1
-   @nhost/react-apollo@17.0.1
-   @nhost/nextjs@2.2.4

## @nhost-examples/node-storage@0.2.18

### Patch Changes

-   Updated dependencies [6b8163d]
    -   @nhost/nhost-js@3.2.5

## @nhost-examples/nextjs-server-components@0.5.3

### Patch Changes

- 6b8163d: fix(nhost-js) update service URL generation for local
environments
-   Updated dependencies [6b8163d]
    -   @nhost/nhost-js@3.2.5

## @nhost-examples/react-apollo@1.3.1

### Patch Changes

-   @nhost/react@3.10.1
-   @nhost/react-apollo@17.0.1

## @nhost-examples/react-gqty@1.3.1

### Patch Changes

-   @nhost/react@3.10.1

## @nhost-examples/react-native@0.1.5

### Patch Changes

-   @nhost/react@3.10.1
-   @nhost/react-apollo@17.0.1

## @nhost-examples/seed-data-storage@0.0.5

### Patch Changes

- 6b8163d: fix(nhost-js) update service URL generation for local
environments

## @nhost-examples/vue-apollo@0.9.1

### Patch Changes

-   Updated dependencies [6b8163d]
    -   @nhost/nhost-js@3.2.5
    -   @nhost/apollo@8.0.5
    -   @nhost/vue@2.9.2

## @nhost-examples/vue-quickstart@0.3.1

### Patch Changes

-   @nhost/apollo@8.0.5
-   @nhost/vue@2.9.2

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-25 15:11:23 -01:00
Nuno Pato
6cc8f954e1 chore: dashboard: add org slug and project subdomain properites to se… (#3216)
### **User description**
- adds 2 properties (org slug and project subdomain) to the page event
on segment


___

### **PR Type**
Enhancement


___

### **Description**
- Add organization slug and project subdomain to Segment page event

- Update Analytics component to include new properties

- Refactor route change handling for analytics

- Add changeset for minor version bump


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>analytics.tsx</strong><dd><code>Enhance Analytics
component with org and project data</code>&nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

dashboard/src/components/analytics/analytics.tsx

<li>Import hooks for current org and project<br> <li> Add org slug and
project subdomain to analytics page event<br> <li> Refactor route change
handling with custom properties<br> <li> Update dependency array in
useEffect


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3216/files#diff-8879790b4a5836d5613a5ee9442b801b87b3385be9b4767e85e880cefda4d52e">+15/-4</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>wild-rings-count.md</strong><dd><code>Add changeset for
analytics enhancement</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

.changeset/wild-rings-count.md

<li>Add changeset file for minor version bump<br> <li> Include
description of changes to Segment page event


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3216/files#diff-752a27afc38e7de05f5621253e536d3eec5ad48ff50eb97ae43e36ccb97e1a84">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-25 13:59:30 -01:00
David BM
1821df7a96 fix (ci): github actions signature checks when installing packages (#3217)
### **User description**
Should fix `dashboard: release form` action

Reference:
https://vercel.com/guides/corepack-errors-github-actions#how-to-fix-it


___

### **PR Type**
Enhancement, Bug fix


___

### **Description**
- Update Corepack to latest version

- Enable Corepack for package management

- Install and verify Corepack and pnpm versions

- Improve CI workflow for package installation


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>action.yaml</strong><dd><code>Update CI workflow with
Corepack and version checks</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

.github/actions/install-dependencies/action.yaml

<li>Add step to install and enable latest Corepack<br> <li> Display
Corepack and pnpm versions for verification<br> <li> Improve package
installation process in CI


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3217/files#diff-342d59190b4737ee45e2062eb625ada477bcea5b4a843b25900ad55d7982f200">+8/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-25 15:06:16 +01:00
David BM
ab8a55ede4 chore: update nix config to use pnpm10 (#3218)
### **PR Type**
Enhancement


___

### **Description**
- Update pnpm version from 9 to 10

- Modify flake.nix to use pnpm_10


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Configuration
changes</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>flake.nix</strong><dd><code>Upgrade pnpm from version 9
to 10</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

flake.nix

<li>Replace <code>pnpm_9</code> with <code>pnpm_10</code> in
nativeBuildInputs<br> <li> Update <code>pnpm_9</code> to
<code>pnpm_10</code> in devShells buildInputs


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3218/files#diff-206b9ce276ab5971a2489d75eb1b12999d4bf3843b7988cbe8d687cfde61dea0">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-25 14:35:40 +01:00
David BM
39eb70678b fix (dashboard): database storage capacity setting paywall (#3214)
### **PR Type**
Enhancement


___

### **Description**
- Add paywall for database storage capacity setting

- Implement UpgradeNotification component for free projects

- Replace legacy plan check with isFreeProject flag

- Add TransferProjectDialog for project upgrades


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>

<summary><strong>DatabaseStorageCapacity.tsx</strong><dd><code>Implement
paywall for database storage capacity</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/database/settings/components/DatabaseStorageCapacity/DatabaseStorageCapacity.tsx

<li>Implemented UpgradeNotification component for free projects<br> <li>
Added TransferProjectDialog for project upgrades<br> <li> Replaced
legacy plan check with isFreeProject flag<br> <li> Updated UI components
and imports


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3214/files#diff-097a59d13b44816051386182a444eadfe2dcacd69b88c121af6733d7eca3ee43">+61/-7</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>neat-bikes-provide.md</strong><dd><code>Add changeset
for paywall implementation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

.changeset/neat-bikes-provide.md

<li>Added changeset file for minor version bump<br> <li> Described fix
for database storage capacity setting paywall


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3214/files#diff-90c63b40b7b544622b40a21bc350f5f90b56bc65047bb2f8055fd6c59acc6aae">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-24 20:04:39 -01:00
Nuno Pato
e3cd5f858f chore: dashboard: add segment analytics (#3213)
### **User description**
- adds segment `page` event


___

### **PR Type**
Enhancement


___

### **Description**
- Add Segment analytics to dashboard

- Implement page tracking for route changes

- Replace Segment snippet with Analytics-Next library

- Update environment variables and dependencies


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>analytics.tsx</strong><dd><code>Add Analytics component
for Segment integration</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

dashboard/src/components/analytics/analytics.tsx

<li>Create new Analytics component<br> <li> Initialize Segment
analytics<br> <li> Set up page tracking on route changes


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3213/files#diff-8879790b4a5836d5613a5ee9442b801b87b3385be9b4767e85e880cefda4d52e">+19/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>segment.ts</strong><dd><code>Set up Segment
AnalyticsBrowser configuration</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

dashboard/src/lib/segment.ts

<li>Initialize AnalyticsBrowser from Segment<br> <li> Load Segment with
CDN URL and write key


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3213/files#diff-a23427ba42161ffe844159b21f2901e32e6518c61895d5b0e90c653df6876d0c">+6/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>_app.tsx</strong><dd><code>Integrate Analytics
component in _app.tsx</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

dashboard/src/pages/_app.tsx

<li>Import and use new Analytics component<br> <li> Remove old Segment
snippet implementation<br> <li> Update page tracking logic


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3213/files#diff-944e6c6d89cc2a23522cb7246ab566c540c8a06660c9c5385363493d3fb613af">+2/-22</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>weak-clocks-approve.md</strong><dd><code>Add changeset
for Segment analytics integration</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/weak-clocks-approve.md

<li>Add changeset for minor version bump<br> <li> Describe addition of
Segment and page event tracking


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3213/files#diff-9ae958fefce4c3b404dba6efd018e882be2e5c88c70bf695bb869d3bc4b97205">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Configuration
changes</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>.env.example</strong><dd><code>Update .env.example with
Segment CDN URL</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

dashboard/.env.example

- Add NEXT_PUBLIC_SEGMENT_CDN_URL environment variable


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3213/files#diff-b47cf46119af2f0298d96e5657e53e57161833e8b02d87526ac5c1ed9393d477">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Dependencies</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>package.json</strong><dd><code>Update dependencies for
Segment Analytics-Next</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

dashboard/package.json

<li>Replace @segment/snippet with @segment/analytics-next<br> <li>
Remove analytics-node dependency


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3213/files#diff-2d8d55c799cd71f1b35e831f075f8178ed1734c4820a2ad548b4dd24d6938d7c">+1/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-24 13:44:14 -01:00
David BM
69d9ab60c8 fix (CI): update PNPM overrides to address security vulnerabilities (#3204)
### **User description**
Fixes PNPM vulnerabilities with PNPM version overrides

vulnerable advisories were:

https://github.com/advisories/GHSA-67mh-4wv8-2f99
https://github.com/advisories/GHSA-76p7-773f-r4q5
https://github.com/advisories/GHSA-h5c3-5r3r-rr8q
https://github.com/advisories/GHSA-rmvr-2pp2-xj38
https://github.com/advisories/GHSA-xx4v-prfh-6cgc


___

### **PR Type**
Enhancement, Bug fix


___

### **Description**
- Update PNPM overrides to address security vulnerabilities

- Add new package version constraints for security

- Upgrade multiple dependencies to secure versions

- Enhance CI/CD pipeline security measures


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Dependencies</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>package.json</strong><dd><code>Update PNPM overrides to
address security vulnerabilities</code></dd></summary>
<hr>

package.json

<li>Added new PNPM overrides for @octokit packages<br> <li> Included
override for serialize-javascript<br> <li> Added override for
esbuild<br> <li> Updated existing overrides for better security


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3204/files#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519">+6/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-17 23:40:10 +01:00
David BM
a8961c0ab0 fix (dashboard): regex search with service filter (#3193)
### **User description**
Fixes #3154


___

### **PR Type**
Bug fix, Enhancement


___

### **Description**
- Fix regex search with service filter

- Refactor service label mapping

- Add new service types (Grafana, Backup Jobs, AI)

- Improve code maintainability and readability


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>LogsHeader.tsx</strong><dd><code>Refactor service label
mapping in LogsHeader</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/logs/components/LogsHeader/LogsHeader.tsx

<li>Import LOGS_SERVICE_TO_LABEL constant<br> <li> Replace hardcoded
label mappings with LOGS_SERVICE_TO_LABEL<br> <li> Simplify service
label mapping logic


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3193/files#diff-ebb3285aa776c9c5ea8b72672c4aafd55994c6c694998bbf56ca9c56d1e77664">+5/-13</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>services.ts</strong><dd><code>Enhance and centralize
service type definitions</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/logs/utils/constants/services/services.ts

<li>Add new service types: GRAFANA, JOB_BACKUP, AI<br> <li> Replace
LOGS_AVAILABLE_SERVICES array with LOGS_SERVICE_TO_LABEL <br>object<br>
<li> Simplify and centralize service label mappings


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3193/files#diff-8fcdaed33322718091b613ae22c65cc3eb61972904b5af46866b160c9bbbe48c">+16/-29</a>&nbsp;
</td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>twenty-icons-kneel.md</strong><dd><code>Add changeset
for version bump and bug fix</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

.changeset/twenty-icons-kneel.md

<li>Add changeset file for version bump<br> <li> Describe fix for regex
filtering with service type filter


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3193/files#diff-9b50bf5928d06c1e8c05f66991d39cf389309cc4235feb23e59880b4305c0085">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-17 17:16:54 +01:00
robertkasza
6b8163d21f fix(nhost-js): update service URL generation for local environments (#3197)
### **User description**
- remove unnecessary redirectTo option from nextjs quickstart/example
- update README for nextjs quickstart/example
- update local URL-s in the repo to use the correct format


___

### **PR Type**
Bug fix


___

### **Description**
- Update local service URLs to include '.local'

- Remove unnecessary redirectTo option in NextJS example

- Update README for NextJS quickstart/example


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><details><summary>19 files</summary><table>
<tr>
<td><strong>OverviewDeployments.test.tsx</strong><dd><code>Update local
GraphQL URL in tests</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-a9440d76cf165e4df8e9db020ee2ab3896281633dbe5ba3691e775d57188bc80">+148/-136</a></td>

</tr>

<tr>
<td><strong>OverviewDeployments.test.tsx</strong><dd><code>Update local
GraphQL URL in tests</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-7cc449a1b6f28a29590e4ea85aa4318961f1dcf9770447080b689432bb58e697">+117/-105</a></td>

</tr>

<tr>
<td><strong>nhostGraphQLLink.ts</strong><dd><code>Update local GraphQL
URL</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-c687b3a6fa4667366a494cee0a0cd8a956e97ab435d1dcca0e3d9758952db695">+3/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>hasuraMetadataQuery.ts</strong><dd><code>Update local Hasura
URL</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-2828f4a1163f0d281abf2517e76fc9dd393bb870478aea874019a42f9c4b7ac3">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>tableQuery.ts</strong><dd><code>Update local Hasura
URL</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-fdb6ad2a7e58c374f3a6772219e7f7e72ca2927def74ec75893b064caba12639">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>tokenQuery.ts</strong><dd><code>Update local Auth
URL</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-c86f0dec25fa37d82ed9765646ffaa9812f3b8b6f36d74056ab9e2dbe3416d0a">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>testUtils.tsx</strong><dd><code>Update local service URLs in
test utils</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-6ebbd73e167641a1706f1b8d30b00569336d10f3c2ab7626d81e639015383e5e">+9/-8</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>testUtils.tsx</strong><dd><code>Update local service URLs in
test utils</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-78f29250407edf853a353b48242d3cee59aa5724f38a60bb23bebdfc1ea2f9b5">+9/-8</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>env.ts</strong><dd><code>Update local service URLs in
environment utils</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-38801f053432e037993a6c8359ff512d7a6cfa9579597b92449f12c05c9c14e9">+11/-8</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>SignIn.tsx</strong><dd><code>Update local Mailhog
URL</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-0a87ee2c1dd8b5251f9b633fec0796102216844f7839e9182309fabe5c86dafe">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>config.ts</strong><dd><code>Update local Mailhog and Auth
URLs</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-2fb71947fac3f4de3e100b1e28b8c4a7141cdac93155b6635a19eb414eb62e8d">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>helpers.ts</strong><dd><code>Update local Auth
URL</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-4aa73c18d80efc7dbe2fe5c76039c0df6d155f6e43835a4aecbd08cd1186dd77">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>config.ts</strong><dd><code>Update local Auth
URL</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-ee105dd14f110b5642103092f69d3310bb652bfb12e68b1588c62a270fd3f603">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>helpers.ts</strong><dd><code>Update local Storage
URL</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-f50172c9dba0fa2de72135ff70ff1d96f8a524f1388a9429182d3e8809909d3f">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>helpers.ts</strong><dd><code>Update URL generation for local
services</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-772264ae234cf88eeab12134a272a425ac41273afc392a07316fb26d7c573023">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>utils.test.ts</strong><dd><code>Update local service URLs in
tests</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-940f24899a0f0f423f25dc4f3809920f2cfbdf3211f892f16011d964ac4ac319">+5/-5</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>seed-storage.sh</strong><dd><code>Update local Storage URL
in seed script</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-211c009c503a489da990b07865b1ad981ddcaae38b96fbb327e832d66eab63b9">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>test-nhost-cli-action.yaml</strong><dd><code>Update local
service URLs in CLI action tests</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-defe9dba19ff27b93c6b21e6308904b606b75cad29218bf849d29f7a8506a30e">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>graphite.graphql.config.yaml</strong><dd><code>Update local
GraphQL URL in config</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-74a8fb68417df04d2af42e94ab298fd54e22d42676b50572b16a2293446f0988">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

</table></details></td></tr><tr><td><strong>Enhancement</strong></td><td><details><summary>2
files</summary><table>
<tr>
<td><strong>sign-in-apple.ts</strong><dd><code>Remove redirectTo option
from Apple sign-in</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-1b6954885dd5b8b4406ed46dfd8102b5cc92175f093cd3c0ebe26477e1346d42">+1/-4</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>sign-in-google.ts</strong><dd><code>Remove redirectTo option
from Google sign-in</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-a155d7f9e27b15453c109c16e2d1c76d3632b28bfafcdaa4180caf40f50102d9">+1/-4</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

</table></details></td></tr><tr><td><strong>Documentation</strong></td><td><details><summary>21
files</summary><table>
<tr>
<td><strong>hip-falcons-applaud.md</strong><dd><code>Add changeset for
URL generation update</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-a41c3544b060502eb895d87553a84ecf238b60567347dafb4168d64fe119e385">+12/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>.env.example</strong><dd><code>Update local service URLs in
example env file</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-b47cf46119af2f0298d96e5657e53e57161833e8b02d87526ac5c1ed9393d477">+8/-8</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>README.md</strong><dd><code>Update local service URLs in
README</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-c15729e6c35a283a4b0eda60a991303b6c36c03903ba42dbf832bb8d0daa1a1a">+7/-7</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>commands.mdx</strong><dd><code>Update local service URLs in
CLI documentation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-2053eb5138f4c468b9aa94e6fd7302ad2f577839be107741f265ae1b2d9bfcaa">+17/-21</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>getting-started.mdx</strong><dd><code>Update local service
URLs in CLI documentation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-05cc8d760dce63f257bee91e9c0293424a63e0ed210d26c7bca78bc3a3d5d763">+8/-8</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>overview.mdx</strong><dd><code>Update local service URLs in
CLI overview</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-dfcca51e047037e649bbf76e68ab3aa9161a85c1bd25cf385acc5e764bea0cd3">+9/-9</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>assistants.mdx</strong><dd><code>Update local Functions URL
in AI assistants guide</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-3fe162cc8ef81dc6517dcd3e7a5531ed695df9fc300595d6b923677a2de7af99">+85/-116</a></td>

</tr>

<tr>
<td><strong>custom-jwts.mdx</strong><dd><code>Update local Functions URL
in custom JWTs guide</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-3e3f4be3ef4e3ddc1f5dbf30b76be0aa275309755cfbcc1afa865a13b433522c">+2/-5</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>local-development.mdx</strong><dd><code>Update local service
URLs in CLI guide</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-00fc275afa2ec0920232682aec7a0f553457675b09fede84fff1cf33fd928422">+14/-16</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>migrate-config.mdx</strong><dd><code>Update local service
URLs in migration guide</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-d85182dc59541186f337991dcbc95179140091cd62bc64acf484f7e9c74dd247">+7/-8</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>multiple-projects.mdx</strong><dd><code>Update local service
URLs in multiple projects guide</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-842182f7c0367b8667570df1f6903fb09b6e9ee5062feac58733dbb238e9c252">+7/-9</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>seeds.mdx</strong><dd><code>Update local Hasura URL in seeds
guide</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-3d5c1396d5c9c028ffa0c8493cb64f0dc06223e651665c173fdb6df30c7f5cb0">+12/-5</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>local-development.mdx</strong><dd><code>Update local GraphQL
URL in run guide</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-9ddcc07c6add2efbb2630dfa5b718656444e9c566e84d38f577eb6a026f4d870">+21/-7</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>overview.mdx</strong><dd><code>Update local Storage URL in
storage overview</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-c2641bf1319034c16ea03895511bac4dcabd62660fe49f713371529041495c5e">+7/-6</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>diagrams.txt</strong><dd><code>Update local Functions and
GraphQL URLs in diagrams</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-b0815782a1cb44a8e50e0616704b74f4e2b4785b4358ce705872f94bf635b573">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>openapi-auth-old.yaml</strong><dd><code>Update local Auth
URL in OpenAPI spec</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-bc23e66a45c276e58845db366df3759415034d4e045b655953a3c557b9c0f09f">+57/-63</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>openapi-storage.yaml</strong><dd><code>Update local Storage
URL in OpenAPI spec</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-81afd91a70cb5516a39e6900392de5136771981bec072a97e5f48975bbf6afd3">+8/-8</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>upload-file.mdx</strong><dd><code>Update local Storage URL
in file upload reference</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-d0a3eae50a19e63cf2d66ab4f644104fa20a946b24122254ec4a368f847292d1">+8/-10</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>README.md</strong><dd><code>Update README with new local
dashboard URL</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-411e8e55ab182bb59f03f2a8e1539b08afbc0f42796f73f5bfcb0c47a015c5c4">+24/-2</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>README.md</strong><dd><code>Update local Storage URLs in
seed data example</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-d2af072cf65c3cc8f02d82d7346a492ddb81a768948ccf02ccb2e8ec1800029c">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>README.md</strong><dd><code>Update local Functions URLs in
Google Translation README</code>&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-b3790312c229004898229cf8ee576c443fce25ef8fdfe6079e1242db932e9d94">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Configuration
changes</strong></td><td><details><summary>1 files</summary><table>
<tr>
<td><strong>nhost.toml</strong><dd><code>Update OAuth and WebAuthn
configurations</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3197/files#diff-eff7b73b949a7fd005b4c51ae54a7757b8447c831168c0d014b6034adc7539bb">+2/-4</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-17 11:11:21 +01:00
David BM
a21553c774 chore: update links in README (#3199)
### **PR Type**
Documentation


___

### **Description**
- Updated links in README to reflect new documentation structure

- Revised quickstart and CLI documentation URLs

- Updated links for framework-specific quickstart guides

- Refreshed 'Try out Nhost' link in contribution section


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>README.md</strong><dd><code>Update documentation and
quickstart guide links</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

README.md

<li>Updated quickstart link to new documentation structure<br> <li>
Revised CLI documentation link<br> <li> Updated links for Next.js,
React, and Vue.js quickstart guides<br> <li> Refreshed 'Try out Nhost'
link in contribution section


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3199/files#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5">+6/-6</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-14 16:47:30 +01:00
github-actions[bot]
2dd4df5170 chore: update versions (#3191)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @nhost/dashboard@2.20.0

# @nhost/dashboard

## 2.17.0

### Minor Changes

-   fd59918: fix: redirect to 404 with nhost cli dashboard

## 2.16.0

### Minor Changes

-   f8e6b61: fix: can add rule groups in table permissions
-   9e404c8: fix: not redirect to 404 page if using local Nhost backend
-   ac4aa01: fix: can delete column in database page
-   4385524: fix: update url to check service health in local dashboard

### Patch Changes

-   @nhost/react-apollo@16.0.1
-   @nhost/nextjs@2.2.2

## 2.15.0

### Minor Changes

- f1052a8: fix: improve stability of the dashboard when pausing projects
-   30daa41: fix: update links to docs in overview page
-   7537237: feat: add image preview toggle in storage

## 2.14.0

### Minor Changes

- d43931e: fix: invalid organization slug/project subdomain doesn't open
404 page
- 5df6fa2: feat: add unencrypted disk warning in storage capacity
settings

### Patch Changes

-   44c1e17: chore: update `msw` to v1.3.5 to fix vulnerabilities
    -   @nhost/react-apollo@16.0.0
    -   @nhost/nextjs@2.2.1

## 2.13.0

### Minor Changes

- 21e90da: chore: remove restrictions on SMTP sender so My Name
[name@acme.com](mailto:name@acme.com) can be added
- 865dd93: fix: duplicate Run placeholders when there is an error in the
backend
- 6902a36: fix: can remove resources if postgres capacity is higher than
10
-   a535aa3: fix: fetch user roles locally in auth section
-   0c50816: fix: allow decimal numbers in database row insert
- aea6d18: chore: add warning when pausing a project about losing Run
services persistent volume data
- d3b4fc3: feat: allow to change postgres settings if project is paused
-   29d27e1: chore: update `next` to v14.2.22 to fix vulnerabilities
-   c9dca09: feat: add reset password form
-   b3bcacb: fix: paused project banner cannot read null project name

### Patch Changes

-   Updated dependencies [46fc520]
-   Updated dependencies [29d27e1]
    -   @nhost/nextjs@2.2.0
    -   @nhost/react-apollo@15.0.1

## 2.12.0

### Minor Changes

- eb95562: fix: show all available permission variables in permission
dropdown select

### Patch Changes

- 8b5c4a0: chore: cleanup layout and add disable duplicate atom key
checking in development mode

## 2.11.3

### Patch Changes

- 714dffa: fix: improve project polling logic and unify usage across
components

## 2.11.2

### Patch Changes

- 6a34f89: fix: improve project polling logic and unify usage across
components

## 2.11.1

### Patch Changes

-   0f6ce52: fix: consolidate useProject hook and fix jwt expired error

## 2.11.0

### Minor Changes

-   cea3ef5: Feat: add org and project placeholders

## 2.10.0

### Minor Changes

-   86ecf27: feat: add support for additional metrics in overview
- 21708be: feat: dashboard: add support for storage buckets to AI
assistants

## 1.30.0

### Minor Changes

- 50441a8: feat: add ui for project autoscaler settings and run services
autoscaler settings

## 1.29.0

### Minor Changes

-   55d8bb5: feat: integrate turnstile for signup verification
-   2a2e54c: fix: update docs url in run services form tooltip
- 18f942f: fix: display long error messages in error toast without
overflow

### Patch Changes

-   @nhost/react-apollo@13.0.0
-   @nhost/nextjs@2.1.22

## 1.28.2

### Patch Changes

- 52a38fe: chore: update dependencies to address security
vulnerabilities
-   Updated dependencies [52a38fe]
    -   @nhost/nextjs@2.1.21

## 1.28.1

### Patch Changes

-   9735fa2: chore: remove broken link

## 1.28.0

### Minor Changes

- 526183a: feat: allow filtering users in "make request as" in graphql
section
-   be3b85b: feat: add conceal errors toggle on auth settings page

### Patch Changes

- 35a2f12: fix: prevent run service details from opening when attempting
to delete
    -   @nhost/react-apollo@12.0.6
    -   @nhost/nextjs@2.1.20

## 1.27.0

### Minor Changes

-   a7cd02c: fix: resolve rate limit query

## 1.26.0

### Minor Changes

-   3773ad7: chore: update pricing information
- b63250d: fix: not allow run service creation form resubmission while
creating a run service
-   a44a1d4: feat: add rate limits settings page

### Patch Changes

-   @nhost/react-apollo@12.0.5
-   @nhost/nextjs@2.1.19

## 1.25.0

### Minor Changes

- d1ceede: feat: add setting to migrate postgres major and/or minor
versions
- e5d3d1a: fix: allow manually typing column for custom check in
database row permissions

### Patch Changes

-   @nhost/react-apollo@12.0.4
-   @nhost/nextjs@2.1.18

## 1.24.1

### Patch Changes

- 49f2e55: fix: use service subdomain in service form and service
details dialog
- 598b988: fix: use current project subdomain in ServiceDetailsDialog
component

## 1.24.0

### Minor Changes

-   abb24af: chore: add redirect to support page when project is locked
- 18a6455: feat: show contact us info and locked reason when project is
locked

### Patch Changes

-   e31eefa: fix: include ingresses field when updating run services

## 1.23.0

### Minor Changes

-   33284d3: fix: don't show double scrollbar in configuration editor

### Patch Changes

-   @nhost/react-apollo@12.0.3
-   @nhost/nextjs@2.1.17

## 1.22.0

### Minor Changes

-   998c037: fix: align drop-down list in select component
- 807b8c0: fix: show city name in region selection for project creation

## 1.21.0

### Minor Changes

- a2efeed: fix: improve project health error handling, add unknown state
and polling interval for health state

## 1.20.0

### Minor Changes

- 8ea4210: fix: error toasts can be closed individually, instead of
dismissing all toasts at once
- 58919ba: chore: add blink animation when project health service is
updating

## 1.19.0

### Minor Changes

- b519862: fix: get configuration in configuration editor using local
development environment

## 1.18.0

### Minor Changes

- 502abad: feat: add services health checks indicators to the overview
page
-   b3ff6ad: chore: update title text on service status modal
- dbadf59: feat: add project configuration TOML editor to the settings
page

## 1.17.0

### Minor Changes

- 77fba27: fix: postgres version validation when activating ai in ai
settings page
-   ac6d1b6: feat: use name instead of awsName

## 1.16.3

### Patch Changes

- 87a37cf: fix: remove unnecessary isPlatform check from verify button
disable logic on custom domains
    -   @nhost/react-apollo@12.0.2
    -   @nhost/nextjs@2.1.16

## 1.16.2

### Patch Changes

- a9413af: fix: update `GetAllWorkspacesAndProjects` query polling to
use exponential backoff
    -   @nhost/react-apollo@12.0.1
    -   @nhost/nextjs@2.1.15

## 1.16.1

### Patch Changes

-   @nhost/react-apollo@12.0.0
-   @nhost/nextjs@2.1.14

## 1.16.0

### Minor Changes

- c6d5c5c: feat: add toggle switch to enable/disable public access in
the database settings

## 1.15.2

### Patch Changes

-   @nhost/react-apollo@11.0.4
-   @nhost/nextjs@2.1.13

## 1.15.1

### Patch Changes

-   @nhost/react-apollo@11.0.3
-   @nhost/nextjs@2.1.12

## 1.15.0

### Minor Changes

-   a7bde37: feat: send metadata in the edit form

### Patch Changes

- 1bc615b: feat: improve error message handling in `ErrorToast`
component
    -   @nhost/react-apollo@11.0.2
    -   @nhost/nextjs@2.1.11

## 1.14.0

### Minor Changes

-   a448d7d: feat: allow configuring postmark and delete SMTP settings

## 1.13.3

### Patch Changes

-   5924bc3: fix: include password in `GetSmtpSettings` query
- c5ad634: fix: resolved an issue where one-click install links were
broken on Safari
- 7278991: fix: update graphql auto-embeddings configuration to use
String type for model field

## 1.13.2

### Patch Changes

-   026f84f: fix: use configuration server URL from environment variable

## 1.13.1

### Patch Changes

-   7e9a2ce: fix: resolve issue where run services form fails to open

## 1.13.0

### Minor Changes

-   dd5d262: feat: add model field to the auto-embeddings form
- 09962be: feat: enable settings and run services when running the
dashboard locally
- 9cdecb6: feat: enable users to update their email address from the
account settings page

## 1.12.2

### Patch Changes

-   c195c51: fix: send email upon signin for unverified users

## 1.12.1

### Patch Changes

- 93ebdf8: fix: use service urls when initilizaing NhostClient running
local dashboard
    -   @nhost/react-apollo@11.0.1
    -   @nhost/nextjs@2.1.10

## 1.12.0

### Minor Changes

- f242e4b: feat: add connect with github to the user's account settings
-   768ca17: chore: update dependencies
- d62bd0f: fix: "Track this" option within the SQL editor now correctly
updates the metadata
- 91c2bb6: feat: refactor sign-in and sign-up pages to enforce email
verification

### Patch Changes

-   943831f: fix: resolve an error toast issue when unpausing a project
-   Updated dependencies [768ca17]
    -   @nhost/react-apollo@11.0.0
    -   @nhost/nextjs@2.1.9

## 1.11.2

### Patch Changes

-   @nhost/react-apollo@10.0.2
-   @nhost/nextjs@2.1.8

## 1.11.1

### Patch Changes

-   981404f: fix: set default value for healthCheck field validation

## 1.11.0

### Minor Changes

- 7789469: chore: upgrade dependency `@graphql-codegen/cli` to `5.0.2`
to address vulnerability
- 6c11b75: feat: add update user displayName section in account settings

### Patch Changes

-   @nhost/react-apollo@10.0.1
-   @nhost/nextjs@2.1.7

## 1.10.0

### Minor Changes

-   49a80c2: chore: update dependencies
-   150c04a: feat: add healthcheck config to run services

### Patch Changes

- e03f141: fix: allow insert, update and delete on tables in `auth` and
`storage` schemas
- 28676f4: feat: add min postgres version check to enable the ai service
-   Updated dependencies [49a80c2]
    -   @nhost/react-apollo@10.0.0
    -   @nhost/nextjs@2.1.6

## 1.9.0

### Minor Changes

-   d86e5c9: feat: add support for filtering the logs using a RegExp

## 1.8.3

### Patch Changes

-   @nhost/react-apollo@9.0.3
-   @nhost/nextjs@2.1.5

## 1.8.2

### Patch Changes

- 6df4f02: fix: use custom error toast and show correct message when
sending an invite

## 1.8.1

### Patch Changes

-   @nhost/react-apollo@9.0.2
-   @nhost/nextjs@2.1.4

## 1.8.0

### Minor Changes

- 713d53c: feat: add catch-all route for workspace/project - useful for
documentation

### Patch Changes

-   3db2999: fix: refresh table list after running SQL using the editor
- 3c4dd55: fix: handle `Error` objects properly in the `ErrorToast`
component
- 92b434e: fix: resolve an issue where the checkbox in the data-grid
header did not select all rows
    -   @nhost/react-apollo@9.0.1
    -   @nhost/nextjs@2.1.3

## 1.7.0

### Minor Changes

-   0d8d0eb: Update docs and dashboard references

## 1.6.9

### Patch Changes

-   @nhost/react-apollo@9.0.0
-   @nhost/nextjs@2.1.2

## 1.6.8

### Patch Changes

-   @nhost/react-apollo@8.0.1
-   @nhost/nextjs@2.1.1

## 1.6.7

### Patch Changes

-   5ef5189: fix: update `@apollo/client` to `3.9.4` to fix a cache bug

## 1.6.6

### Patch Changes

-   3ba485e: fix: added discord.com to connect-src
-   e5bab6a: chore: update dependencies
-   Updated dependencies [b19ffed]
-   Updated dependencies [e5bab6a]
    -   @nhost/nextjs@2.1.0
    -   @nhost/react-apollo@8.0.0

## 1.6.5

### Patch Changes

- ba73bb4: fix: update ErrorToast component to show the internal graphql
error
- d5337ff: fix: utilize accumulator in the creation of validation schema
within data grid utils

## 1.6.4

### Patch Changes

-   7c2a1c2: feat: show error and debug info in the error toast

## 1.6.3

### Patch Changes

-   6b8aad5: fix: add bare nhost.run to CSP

## 1.6.2

### Patch Changes

-   b18edc0: feat: added CSP and X-Frame-Options

## 1.6.1

### Patch Changes

-   8d91f71: chore: update deps and enable pnpm audit
- 3b8473b: chore: update turbo to `1.11.3` and pnpm to `8.10.5` in
Dockerfile
-   Updated dependencies [8d91f71]
    -   @nhost/react-apollo@7.0.2
    -   @nhost/nextjs@2.0.2

## 1.6.0

### Minor Changes

-   3ff1c2b53: fix: show upgrade option for pro projects

## 1.5.0

### Minor Changes

-   c2ef17c0a: feat: add support for new Team plan

## 1.4.0

### Minor Changes

-   7883bbcbd: feat: don't show deprecated plans
- 44be6dc0a: feat: set redirectTo during sign-in to support preview
environments

### Patch Changes

- 3c3594898: fix: allow access to graphite when configured running in
local dashboard
-   32c246b7a: chore: update docs icon

## 1.3.2

### Patch Changes

-   174b4165b: chore: use env variables when running graphql codegen
-   7c977e714: chore: change `Allowed Roles` to `Default Allowed Roles`
-   46f028b9f: fix: remove hardcoded ai version setting

## 1.3.1

### Patch Changes

- af33c21d1: chore: remove backendUrl deprecation notice and remove all
references to `providersUpdated`

## 1.3.0

### Minor Changes

-   04784d880: Fix graphite's default version

## 1.2.0

### Minor Changes

-   5733162ed: feat: add settings and ui for graphite

## 1.1.0

### Minor Changes

-   e2b79b5ec: chore: remove sharp from deps

## 1.0.1

### Patch Changes

-   @nhost/react-apollo@7.0.1
-   @nhost/nextjs@2.0.1

## 1.0.0

### Major Changes

- bc9eff6e4: chore: remove support for using backendUrl when
instantiating the Nhost client

### Patch Changes

-   Updated dependencies [bc9eff6e4]
    -   @nhost/nextjs@2.0.0
    -   @nhost/react-apollo@7.0.0

## 0.21.1

### Patch Changes

-   97ced73a3: fix(dashboard): prevent dashboard from resolving secrets

## 0.21.0

### Minor Changes

- ed1a8d458: Update alert message on increasing PostgreSQL's volume
capacity
-   2e2248fd4: feat(dashboard): add SQL editor

## 0.20.28

### Patch Changes

-   7c2c31082: feat: add support for users to delete their account
    -   @nhost/react-apollo@6.0.1
    -   @nhost/nextjs@1.13.40

## 0.20.27

### Patch Changes

- fa79b7709: chore(dashboard): tweaks and fixes to the service form and
dialog
-   8df84d782: fix(dashboard): allow resetting custom domains
    -   @nhost/react-apollo@6.0.0
    -   @nhost/nextjs@1.13.39

## 0.20.26

### Patch Changes

- 331ba0376: feat(dashboard): add postgres storage capacity modifier in
the settings
-   b7f801874: feat(dashboard): add new settings page for custom domains

## 0.20.25

### Patch Changes

-   @nhost/react-apollo@5.0.38

## 0.20.24

### Patch Changes

-   e10389ecf: fix(dashboard): disable run tab when developing locally
    -   @nhost/react-apollo@5.0.37

## 0.20.23

### Patch Changes

-   c01568a7d: chore(dashboard): show alert to update oauth providers

## 0.20.22

### Patch Changes

-   c3efb7ec8: feat(dashboard): query latest announcement from platform

## 0.20.21

### Patch Changes

-   3e46d3873: chore: update link to node18 announcement

## 0.20.20

### Patch Changes

-   @nhost/react-apollo@5.0.36
-   @nhost/nextjs@1.13.38

## 0.20.19

### Patch Changes

-   75c4c8ae3: feat(dashboard): make env value input multiline

## 0.20.18

### Patch Changes

- 425d485f8: fix(dashboard): make sure dedicated resources pricing
follows total resources

## 0.20.17

### Patch Changes

-   ae324f67f: fix(dashboard): remove unused graphql fields

## 0.20.16

### Patch Changes

-   df5b4302c: chore(dashboard): remove run feature flag
- bf4a1f6c2: feat(dashboard): fetch auth, postgres, hasura and storage
versions from dashboard
- 34fc08ca7: fix(dashboard/run): show correct private registry in
service details
-   885d10620: chore(dashboard): change feedback to contact us

## 0.20.15

### Patch Changes

- ed16c8b5d: feat(run): add a confirmation dialog when deleting a run
service
- 216990888: fix(run): center loading indicator when selecting a project

## 0.20.14

### Patch Changes

-   9fbea9787: feat: add node18 announcement

## 0.20.13

### Patch Changes

- e84acf469: fix(run): handle subdomain undefined error when creating a
new service

## 0.20.12

### Patch Changes

-   b7c799d62: feat(run): add dialog to copy registry and URLs

## 0.20.11

### Patch Changes

-   8903e6abd: fix(dashboard): show correct egress limit in usage stats

## 0.20.10

### Patch Changes

- 666a75a23: feat(dashboard): add functions execution time and egress
volume to usage stats

## 0.20.9

### Patch Changes

-   5e1e80aa8: fix(dashboard): show correct locales in user details
    -   @nhost/react-apollo@5.0.35
    -   @nhost/nextjs@1.13.37

## 0.20.8

### Patch Changes

-   @nhost/react-apollo@5.0.34
-   @nhost/nextjs@1.13.36

## 0.20.7

### Patch Changes

-   4a7ede11e: fix: distinguish files that were not uploaded
- 202b64723: feat(nhost-run): add support for one-click-install run
services
- 074a0fa11: feat(dashboard): add settings toggle to enable/disable
antivirus
    -   @nhost/react-apollo@5.0.33
    -   @nhost/nextjs@1.13.35

## 0.20.6

### Patch Changes

-   b20761e97: feat(services): add pricing info and confirmation dialog
-   90df6d81d: fix(services): handle null values when editing a service
-   aa8508467: fix: query service logs correctly
    feat: enable multiline support for environment value input

## 0.20.5

### Patch Changes

-   8d7f84b8d: fix: make announcement adapt to theme

## 0.20.4

### Patch Changes

-   3b75bfce2: fix: make announcement close properly
- f49819075: fix: show correct values when dedicated resources are
disabled

## 0.20.3

### Patch Changes

-   e643bd362: fix(services): fix errors when config is null
-   bcdab66bf: feat: add annoucement for nhost run
-   f967a2e59: added note about storage not being able to be downsized
-   311c7756d: chore(services): consistent naming for compute

## 0.20.2

### Patch Changes

-   9073182d5: chore(dashboard): bump `turbo` to 1.10.11
-   ece717d6e: feat(logs): show services in the logs page
- 82b335311: feat(metrics): change grafana link to point to the
dashboards
- b135ef695: fix(services): set command as optional and set min replicas
to 0

## 0.20.1

### Patch Changes

-   3d5c34f4c: fix(auth): fix users pagination limit

## 0.20.0

### Minor Changes

-   c99d117d1: feat(services): add support for custom services

## 0.19.2

### Patch Changes

-   face99ccd: chore(deps): bump turbo version
-   cfe527307: style: tweak pull config warning in dark mode
- a9d7da8af: chore(deps): update dependency @types/pluralize to ^0.0.30
-   9aa4371ef: chore: add hasura-auth version 0.21.2
- d14e112bf: chore(deps): update dependency prettier-plugin-tailwindcss
to ^0.4.0
-   d3e8bb94a: chore(deps): update dependency vite-plugin-dts to v3

## 0.19.1

### Patch Changes

-   @nhost/react-apollo@5.0.32
-   @nhost/nextjs@1.13.34

## 0.19.0

### Minor Changes

- 9c61c69a7: chore(dashboard):add postgres 14.6-20230705-1 to the
version selector

### Patch Changes

-   47bda15ff: feat(settings): add warning to pull config

## 0.18.0

### Minor Changes

- ee0b9b8ed: chore(dashboard):add hasura v2.28.2 and v2.29.0 to the
version selector

## 0.17.20

### Patch Changes

-   @nhost/react-apollo@5.0.31
-   @nhost/nextjs@1.13.33

## 0.17.19

### Patch Changes

-   f866120a6: fix(users): use the password length from the config

## 0.17.18

### Patch Changes

-   @nhost/react-apollo@5.0.30
-   @nhost/nextjs@1.13.32

## 0.17.17

### Patch Changes

-   ea7b102c0: fix(pat): highlight expired tokens

## 0.17.16

### Patch Changes

- b3b64a3b7: chore(deps): bump `@types/react` to `v18.2.14` and
`@types/react-dom` to `v18.2.6`
-   32b221f94: chore(deps): bump `graphiql` to `v3`
-   3a56c12df: chore(deps): bump `turbo` to `v1.10.6`
-   Updated dependencies [b3b64a3b7]
    -   @nhost/react-apollo@5.0.29
    -   @nhost/nextjs@1.13.31

## 0.17.15

### Patch Changes

-   f41fdc12a: chore(deps): bump `turbo` to `1.10.5`
-   6199c1c55: fix(projects): don't redirect to 404 page
-   Updated dependencies [07a45fde0]
    -   @nhost/react-apollo@5.0.28
    -   @nhost/nextjs@1.13.30

## 0.17.14

### Patch Changes

- 80b22724d: chore(deps): bump `@types/react` to `v18.2.13`,
`@types/react-dom` to `v18.2.6` and `@storybook/testing-library` to
`v0.2.0`

## 0.17.13

### Patch Changes

-   cc02902cb: chore(docs): update environment variable documentation

## 0.17.12

### Patch Changes

-   660d339e1: fix(storybook): don't break storybook
-   660d339e1: fix(tests): prevent warnings during tests
    -   @nhost/react-apollo@5.0.27
    -   @nhost/nextjs@1.13.29

## 0.17.11

### Patch Changes

- bd4d0c270: chore(dashboard):add postgres 14.6-20230613-1 to the
version selector

## 0.17.10

### Patch Changes

-   c8c2a10b2: fix(database): don't break the password reset flow
- e70b45498: chore(deps): bump `@types/react` to `v18.2.12` and
`@types/react-dom` to `v18.2.5`

## 0.17.9

### Patch Changes

- 842055099: chore(deps): bump `turbo` to `v1.10.3` and `pnpm` to
`v8.6.2`
- fd12aa0a8: chore(projects): remove the postgres password input from
the project creation screen
-   022b76e78: chore(deps): bump `@types/react` to `v18.2.11`
-   3555ab2b7: chore(deps): bump `vitest` monorepo to `v0.32.0`
-   c43e54922: feat(backups): add download button to backups

## 0.17.8

### Patch Changes

-   d0457fe5c: feat(settings): improve the dashboard and config parity
    -   @nhost/react-apollo@5.0.26
    -   @nhost/nextjs@1.13.28

## 0.17.7

### Patch Changes

-   4f0368b95: fix(account): don't break account settings page

## 0.17.6

### Patch Changes

- 64a8f41d0: chore(resources): lower the maximum allowed resources per
service

## 0.17.5

### Patch Changes

-   @nhost/react-apollo@5.0.25
-   @nhost/nextjs@1.13.27

## 0.17.4

### Patch Changes

- 9b1d0f7a5: fix(deployments): use correct timestamp for deployment
details
-   6d2963ffa: chore(deps): bump `@types/react` to `v18.2.8`
- 8871267b9: chore(deps): downgrade `pnpm` to `v8.5.1` because of no
Turborepo support

## 0.17.3

### Patch Changes

-   01eeef9de: chore(misc): under the hood improvements
- 21e13db05: chore(deps): bump `@types/react` to `v18.2.7` and `turbo`
to `v1.10.1`
- f16433ae6: chore(secrets): allow empty secrets and environment
variables
-   aa3c62989: chore(cli): bump Nhost CLI version to v1.0
    -   @nhost/react-apollo@5.0.24
    -   @nhost/nextjs@1.13.26

## 0.17.2

### Patch Changes

-   88a4983f: chore(misc): under the hood improvements

## 0.17.1

### Patch Changes

-   9b0d4dde: feat(secrets): enable secrets

## 0.17.0

### Minor Changes

-   15d84a19: Add postgres 14.6-20230525

## 0.16.14

### Patch Changes

-   4c626174: chore: updated import paths, improved directory structure
-   cc047b71: chore(deps): bump `@fontsource` monorepo to `v5.0.0`
-   99edd012: feat(account): add support for personal access tokens

## 0.16.13

### Patch Changes

-   78c7109c: feat(settings): allow selecting service versions

## 0.16.12

### Patch Changes

- 399009d6: fix(gql): don't enter an infinite loop when fetching remote
app data
- 329e5a91: fix(deployments): use the same sorting of deployments
everywhere
- 6d559d6e: chore(settings): add under the hood improvements to the
settings page
- 12eb236c: chore(deps): bump `prettier-plugin-tailwindcss` to `v0.3.0`
-   f9b81a2a: chore(deps): bump `turbo` to `v1.9.8`
-   1345741b: fix(projects): don't redirect to 404 on project creation
-   Updated dependencies [7fea29a8]
    -   @nhost/react-apollo@5.0.23
    -   @nhost/nextjs@1.13.25

## 0.16.11

### Patch Changes

- 1230b722: fix(projects): don't redirect to 404 on when the project is
renamed
    -   @nhost/react-apollo@5.0.22
    -   @nhost/nextjs@1.13.24

## 0.16.10

### Patch Changes

-   Updated dependencies [da03bf39]
    -   @nhost/react-apollo@5.0.21
    -   @nhost/nextjs@1.13.23

## 0.16.9

### Patch Changes

- 349aac36: fix(settings): use region domain when constructing the
postgres connection string

## 0.16.8

### Patch Changes

- 20fb69fa: chore(projects): change the way how API URLs are constructed

## 0.16.7

### Patch Changes

- 49f9b837: chore(docker): bump `pnpm` to `v8.4.0` and `turbo` to
`v1.9.3`
- 3f478a4e: chore(deps): bump `vitest` to `v0.31.0`, `@types/react` to
`v18.2.6` and `@types/react-dom` to `v18.2.4`

## 0.16.6

### Patch Changes

- d926f156: fix(projects): redirect to 404 when an invalid project is
opened
- 49b99728: fix(projects): disable features for non-owner members of
workspaces

## 0.16.5

### Patch Changes

-   12e2855f: chore(deps): bump `jsdom` to v22
-   e4972b83: feat(metrics): add Grafana page

## 0.16.4

### Patch Changes

- 3f396a9e: fix(projects): unpause after upgrading a paused project to
pro
- 3f396a9e: fix(projects): don't redirect to 404 page after project
creation

## 0.16.3

### Patch Changes

-   Updated dependencies [90c60311]
    -   @nhost/react-apollo@5.0.20
    -   @nhost/nextjs@1.13.22

## 0.16.2

### Patch Changes

-   0f34f0c6: fix(projects): disallow downgrading to free plan
- 8da291ad: chore(deps): bump `@types/react` to v18.2.0 and
`@types/react-dom` to v18.2.1

## 0.16.1

### Patch Changes

- adc828a5: fix(gql): don't enter an infinite loop when fetching remote
app data

## 0.16.0

### Minor Changes

-   2fb1145f: feat(compute): add support for replicas

### Patch Changes

- d8ceccec: chore(env): remove deprecated `NHOST_BACKEND_URL`
environment variable

## 0.15.2

### Patch Changes

-   84b84ab7: fix(projects): filter projects by workspace

## 0.15.1

### Patch Changes

-   2faf7907: chore(deps): bump `graphql-request` to v6
-   f1b5a944: chore(deps): bump `@vitejs/plugin-react` to v4
-   7f1785ac: chore(deps): bump `@types/react` to v18.0.37
    -   @nhost/react-apollo@5.0.19

## 0.15.0

### Minor Changes

-   85889ee8: feat(dashboard): add Compute management to the settings

## 0.14.8

### Patch Changes

-   668c8771: chore(dialogs): unify dialog management of payment dialogs

## 0.14.7

### Patch Changes

-   d4ccc656: chore: cleanup unused code
    -   @nhost/react-apollo@5.0.18
    -   @nhost/nextjs@1.13.21

## 0.14.6

### Patch Changes

-   b299cfc9: chore(deps): bump `vitest` to v0.30.0
-   411cb65b: chore(projects): refactor workspace and project hooks
- 43b1b144: chore(deps): bump `@types/react` to v18.0.34 and
`@types/react-dom` to v18.0.11
-   Updated dependencies [43b1b144]
    -   @nhost/react-apollo@5.0.17
    -   @nhost/nextjs@1.13.20

## 0.14.5

### Patch Changes

-   ba0d57ee: fix(i18n): revert i18n library
-   3328ed05: feat(projects): improve overview when there is an error

## 0.14.4

### Patch Changes

-   5e0920ba: chore(deps): bump `next-seo` to v6
-   706c9dc3: chore(deps): bump `@types/react` to 18.0.33
-   99f8f6b3: feat(metrics): show metrics on the overview

## 0.14.3

### Patch Changes

-   @nhost/react-apollo@5.0.16

## 0.14.2

### Patch Changes

-   3cb67300: fix(logs): don't break UI when clearing time picker
-   7453bf3b: feat(projects): show project creator info
-   c166dad0: chore(tests): improve auth page tests
-   6a290bb2: chore(deps): bump `@types/react` to 18.0.32

## 0.14.1

### Patch Changes

-   @nhost/react-apollo@5.0.15
-   @nhost/nextjs@1.13.19

## 0.14.0

### Minor Changes

-   6e1f03ea: feat(dashboard): add support for the Azure AD provider

### Patch Changes

-   1bd2c373: chore(deps): bump `turbo` to 1.8.6
-   d329b621: chore(deps): bump `@types/react` to 18.0.30
-   cb248f0d: fix(tests): avoid name collision in database tests
-   867c8076: chore(deps): bump `@types/react` to 18.0.29

## 0.13.10

### Patch Changes

- e93b06ab: fix(dashboard): remove left margin from workspace list on
mobile
-   1c4806bf: chore(deps): bump `sharp` to 0.32.0
    -   @nhost/react-apollo@5.0.14
    -   @nhost/nextjs@1.13.18

## 0.13.9

### Patch Changes

-   912ed76c: chore(dashboard): bump `@apollo/client` to 3.7.10
-   Updated dependencies [912ed76c]
    -   @nhost/react-apollo@5.0.13

## 0.13.8

### Patch Changes

-   7c127372: chore(dashboard): bump `react-error-boundary` to v4

## 0.13.7

### Patch Changes

- 9130ab12: chore(dashboard): bump `yup` to v1 and `@hookform/resolvers`
to v3

## 0.13.6

### Patch Changes

- 253dd235: using new mutation to create projects + refactor Create
Project page.

## 0.13.5

### Patch Changes

-   @nhost/react-apollo@5.0.12
-   @nhost/nextjs@1.13.17

## 0.13.4

### Patch Changes

-   b48bc034: fix(dashboard): disable new users
-   798e591b: fix(dashboard): show correct date in data grid

## 0.13.3

### Patch Changes

-   bfb4c1a6: chore(dashboard): remove `useAxios` property
-   d8d8394b: Dashboard: allow to override hasura admin secret in docker
-   Updated dependencies [ce1ee40d]
    -   @nhost/nextjs@1.13.16
    -   @nhost/react-apollo@5.0.11

## 0.13.2

### Patch Changes

-   beed2eba: Fix docker entrypoint for dashboard
- 2c8559a3: fix(dashboard): refresh project list after deleting a
project
-   4329d048: chore(dashboard): bump `graphiql` dependencies

## 0.13.1

### Patch Changes

-   cbb1fc5b: chore(dashboard): cleanup GraphQL operations

## 0.13.0

### Minor Changes

-   088584e7: feat(dashboard): add support for custom local subdomains

### Patch Changes

-   2ac90dfd: fix(dashboard): improve mobile responsive layout
-   Updated dependencies [f375eacc]
    -   @nhost/nextjs@1.13.15
    -   @nhost/react-apollo@5.0.10

## 0.12.4

### Patch Changes

-   @nhost/react-apollo@5.0.9
-   @nhost/nextjs@1.13.14

## 0.12.3

### Patch Changes

-   2b1338f7: chore(dashboard): bump `turbo` to 1.8.3
- 5223ee93: fix(dashboard): show correct deployment status on the main
page
-   850a049c: chore(deps): update docker/build-push-action action to v4
-   Updated dependencies [850a049c]
    -   @nhost/nextjs@1.13.13
    -   @nhost/react-apollo@5.0.8

## 0.12.2

### Patch Changes

-   4bf40995: chore(deps): bump `typescript` to `4.9.5`
-   8bb097c9: chore(deps): bump `vitest`
- 35d52aab: chore(deps): replace `cross-fetch` with `isomorphic-unfetch`
-   Updated dependencies [4bf40995]
-   Updated dependencies [8bb097c9]
-   Updated dependencies [35d52aab]
    -   @nhost/react-apollo@5.0.7
    -   @nhost/nextjs@1.13.12

## 0.12.1

### Patch Changes

-   c96d7ccd: fix(dashboard): fix docker builds

## 0.12.0

### Minor Changes

-   d1671210: feat(dashboard): use mimir to manage project configuration

### Patch Changes

-   f65e4de9: chore(deps): bump @graphql-codegen monorepo to v3

## 0.11.20

### Patch Changes

-   4b4f0d01: chore(dashboard): improve dialog management

## 0.11.19

### Patch Changes

-   @nhost/react-apollo@5.0.6
-   @nhost/nextjs@1.13.11

## 0.11.18

### Patch Changes

-   01318860: fix(nhost-js): use correct URL for functions requests
-   Updated dependencies [01318860]
    -   @nhost/react-apollo@5.0.5
    -   @nhost/nextjs@1.13.10

## 0.11.17

### Patch Changes

-   f673adea: fix(dashboard): set correct Content-Type for user creation
-   445d8ef4: chore(deps): bump `@nhost/react-apollo` to 5.0.4
-   445d8ef4: chore(deps): bump `@nhost/nextjs` to 1.13.9
- 0368663d: fix(dashboard): allow permission editing for auth and
storage schemas
-   Updated dependencies [445d8ef4]
-   Updated dependencies [445d8ef4]
    -   @nhost/react-apollo@5.0.4
    -   @nhost/nextjs@1.13.9

## 0.11.16

### Patch Changes

-   b755e908: fix(dashboard): use correct date for last seen
-   2d9145f9: chore(deps): revert GraphQL client
- 1ddf704c: fix(dashboard): don't show false positive message for failed
user creation
    -   @nhost/react-apollo@5.0.3
    -   @nhost/nextjs@1.13.8

## 0.11.15

### Patch Changes

-   @nhost/react-apollo@5.0.2
-   @nhost/nextjs@1.13.7

## 0.11.14

### Patch Changes

- 2cc18dcb: fix(dashboard): prevent permission editor dropdown from
being always open

## 0.11.13

### Patch Changes

- 3343a363: chore(dashboard): bump `@testing-library/react` to v14 and
`@testing-library/dom` to v9
    -   @nhost/react-apollo@5.0.1
    -   @nhost/nextjs@1.13.6

## 0.11.12

### Patch Changes

- 87eda76e: chore(dashboard): bump `@types/react` to v18.0.28 and
`@types/react-dom` to v18.0.11
-   6f0ac570: feat(dashboard): show dashboard version in account menu

## 0.11.11

### Patch Changes

-   bf1e4071: chore(dashboard): bump `react-is` version to `18.2.0`
-   Updated dependencies [bf1e4071]
-   Updated dependencies [5013213b]
    -   @nhost/nextjs@1.13.5
    -   @nhost/react-apollo@4.13.5

## 0.11.10

### Patch Changes

- a37a430b: fix(dashboard): don't break UI when deployments are
unavailable
    -   @nhost/react-apollo@4.13.4
    -   @nhost/nextjs@1.13.4

## 0.11.9

### Patch Changes

-   7b970e68: fix(dashboard): fix header link color

## 0.11.8

### Patch Changes

- f33242f2: feat(dashboard): add new sign up, sign in and reset password
pages

## 0.11.7

### Patch Changes

-   e9c8909c: fix(dashboard): use correct theme color in dark mode

## 0.11.6

### Patch Changes

-   902f486b: fix(dashboard): re-enable Hasura on logs page

## 0.11.5

### Patch Changes

-   1f9720fa: fix(dashboard): apply select permissions properly

## 0.11.4

### Patch Changes

-   deb14b51: fix(dashboard): don't break billing form

## 0.11.3

### Patch Changes

-   @nhost/react-apollo@4.13.3
-   @nhost/nextjs@1.13.3

## 0.11.2

### Patch Changes

-   f143e51d: chore(dashboard): pin Turborepo to 1.6.3

## 0.11.1

### Patch Changes

-   c2b5a41a: chore(dashboard): select system colors by default

## 0.11.0

### Minor Changes

-   1ebaf429: feat(dashboard): introduce Dark Mode 🌚

### Patch Changes

- 63b445c4: fixed duplicated logs bug and made to date count during live
mode

## 0.10.1

### Patch Changes

-   e146d32e: chore(deps): update dependency @types/react to v18.0.27
-   59347fcd: correct allowed role name
-   5b65cac9: updated authentication documentation
-   963f9b5e: feat(dashboard): include project info in feedback

## 0.10.0

### Minor Changes

-   ed4c7801: chore(dashboard): remove Functions section

## 0.9.10

### Patch Changes

-   4e2f8ccd: fix(dashboard): don't break Auth page in local mode

## 0.9.9

### Patch Changes

-   31abbe5f: fix(dashboard): enable toggle when settings are filled in

## 0.9.8

### Patch Changes

- 5bdd31ad: chore(dashboard): list fewer images per page on the Storage
page
- 5121851c: fix(dashboard): don't throw validation error for valid
permission rules

## 0.9.7

### Patch Changes

-   c126b20d: fix(dashboard): correct redeployment button

## 0.9.6

### Patch Changes

-   36c3519c: feat(dashboard): retrigger deployments

## 0.9.5

### Patch Changes

- 200e9f77: chore(deps): update dependency @types/react-dom to v18.0.10
-   Updated dependencies [200e9f77]
    -   @nhost/nextjs@1.13.2
    -   @nhost/react-apollo@4.13.2

## 0.9.4

### Patch Changes

- dbd3ded5: fix(dashboard): workspaces creation, new form, correct
redirects.

## 0.9.3

### Patch Changes

-   85f0f943: fix(dashboard): don't break the table creation process

## 0.9.2

### Patch Changes

-   Updated dependencies [d42c27ae]
-   Updated dependencies [927be4a2]
    -   @nhost/nextjs@1.13.1
    -   @nhost/react-apollo@4.13.1

## 0.9.1

### Patch Changes

-   d0f80811: fix(dashboard): don't show error when signing out the user

## 0.9.0

### Minor Changes

- d92891b2: feat(dashboard): add Permission Editor to the Database
section

### Patch Changes

-   3d379128: fix(dashboard): create new user
    -   @nhost/react-apollo@4.13.0
    -   @nhost/nextjs@1.13.0

## 0.8.1

### Patch Changes

-   7cadd944: fix(dashboard): display Twitter provider settings

## 0.8.0

### Minor Changes

-   9a1aa7bb: add functions to the log dashboard
-   f29abe62: feat(dashboard): Users Management v2

### Patch Changes

-   7766624b: feat(dashboard): add JWT secret editor modal
    -   @nhost/react-apollo@4.12.1
    -   @nhost/nextjs@1.12.1

## 0.7.13

### Patch Changes

-   dd0738d5: fix(dashboard): provisioning status polling

## 0.7.12

### Patch Changes

-   b21222b3: chore(deps): update dependency @types/node to v16
-   9e0486a3: fix(dashboard): close modals when navigating
-   Updated dependencies [b21222b3]
-   Updated dependencies [65687bee]
-   Updated dependencies [54df0df4]
    -   @nhost/nextjs@1.12.0
    -   @nhost/react-apollo@4.12.0

## 0.7.11

### Patch Changes

-   d6527122: fix(dashboard): use correct service URLs

## 0.7.10

### Patch Changes

-   Updated dependencies [57db5b83]
    -   @nhost/nextjs@1.11.0
    -   @nhost/nhost-js@1.7.0
    -   @nhost/react@0.17.0
    -   @nhost/react-apollo@4.11.0

## 0.7.9

### Patch Changes

- a6d31dc2: fix(dashboard): don't break the UI when project is not
loaded yet

## 0.7.8

### Patch Changes

- 7f251111: Use `NhostProvider` instead of `NhostReactProvider` and
`NhostNextProvider`

    `NhostReactProvider` and `NhostNextProvider` are now deprecated

-   f4d70f88: fix(dashboard): do not break when region is nullish

- 4a9471cc: Windows Live Provider displayed link updated to match
backend url

- 594488e4: fix(dashboard): do not show error when submitting Apple
provider settings

-   Updated dependencies [7f251111]
    -   @nhost/nextjs@1.10.0
    -   @nhost/react@0.16.0
    -   @nhost/react-apollo@4.10.0

## 0.7.7

### Patch Changes

-   80b604ad: fix(dashboard): use correct Hasura slug

## 0.7.6

### Patch Changes

-   2d2beb53: fix(dashboard): prevent error on GraphQL page
-   ac8efcbd: chore(dashboard): deprecate old DNS name

## 0.7.5

### Patch Changes

-   132a4f4b: chore(dashboard): remove unused dependencies
- 132a4f4b: chore(deps): synchronize @types/react-dom and @types/react
versions
-   db57572f: fix(dashboard): correct section paddings when no env vars
-   Updated dependencies [132a4f4b]
    -   @nhost/react@0.15.2
    -   @nhost/react-apollo@4.9.2
    -   @nhost/nextjs@1.9.3

## 0.7.4

### Patch Changes

-   34d85e54: chore(deps): update dependency critters to ^0.0.16
- 9b93cf95: chore(deps): update dependency @netlify/functions to ^0.11.0
-   e0439030: chore(deps): update dependency @types/react-dom to v18.0.9
-   Updated dependencies [82124329]
    -   @nhost/nextjs@1.9.2

## 0.7.3

### Patch Changes

-   a1193da4: fix(dashboard): remove character limit from env var inputs

## 0.7.2

### Patch Changes

-   44f13f62: chore(dashboard): cleanup unused files

## 0.7.1

### Patch Changes

- e01cb2ed: chore(dashboard): change settings sidebar menu item density

## 0.7.0

### Minor Changes

- db342f45: chore(dashboard): refactor Roles and Permissions settings
sections
-   8b9fa0b1: feat(dashboard): add Environment Variables page

### Patch Changes

-   Updated dependencies [66b4f3d0]
-   Updated dependencies [2e6923dc]
-   Updated dependencies [ef117c28]
-   Updated dependencies [aebb8225]
    -   @nhost/core@0.9.4
    -   @nhost/nhost-js@1.6.2
    -   @nhost/nextjs@1.9.1
    -   @nhost/react@0.15.1
    -   @nhost/react-apollo@4.9.1

## 0.6.0

### Minor Changes

-   eef9c914: feat(dashboard): add Roles and Permissions page

## 0.5.0

### Minor Changes

-   a48dd5bf: feat(dashboard): make backend port configurable

## 0.4.3

### Patch Changes

-   5de965d9: fix(dashboard): alphabetic ordering of providers
-   b9087a4a: fix(dashboard): console -> dashboard terminology
-   ca012d79: docs(workos): WorkOS Docs

## 0.4.2

### Patch Changes

-   89bd37bc: fix(dashboard): correct redirect URL input opacity
-   Updated dependencies [4601d84e]
-   Updated dependencies [843087cb]
    -   @nhost/react@0.15.0
    -   @nhost/nextjs@1.9.0
    -   @nhost/react-apollo@4.9.0

## 0.4.1

### Patch Changes

-   766cb612: fix(dashboard): correct redirect URL for oauth providers
-   Updated dependencies [53bdc294]
-   Updated dependencies [f2aaff05]
    -   @nhost/nextjs@1.8.3
    -   @nhost/core@0.9.3
    -   @nhost/react@0.14.3
    -   @nhost/nhost-js@1.6.1
    -   @nhost/react-apollo@4.8.3

## 0.4.0

### Minor Changes

-   9211743d: feat(dashboard): migrate Settings page features

## 0.3.0

### Minor Changes

-   73da6a67: fix(dashboard): avoid using BACKEND_URL locally

## 0.2.0

### Minor Changes

-   db118f97: feat(dashboard): generate Docker image

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-11 08:34:08 +01:00
David Barroso
403a45d2cf chore (dashboard): update schema (#3192)
### **PR Type**
Enhancement


___

### **Description**
- Update schema for resource configuration

- Remove replicas and autoscaler from Postgres

- Refactor initial resource retrieval logic

- Adjust GraphQL types for Postgres resources


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>ResourcesForm.tsx</strong><dd><code>Refactor initial
resource retrieval logic</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>


dashboard/src/features/orgs/projects/resources/settings/components/ResourcesForm/ResourcesForm.tsx

<li>Refactored <code>getInitialServiceResources</code> function<br> <li>
Added checks for <code>replicas</code> and <code>autoscaler</code>
properties<br> <li> Initialized <code>replicas</code> to 1 if not
present


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3192/files#diff-0a7e99e6ee09c17eec103656a9aa088b379c7927a182098538b793488a1f9337">+11/-1</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>ResourcesForm.tsx</strong><dd><code>Update resource
form logic and submission</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>


dashboard/src/features/projects/resources/settings/components/ResourcesForm/ResourcesForm.tsx

<li>Updated <code>getInitialServiceResources</code> function similar to
org version<br> <li> Removed <code>replicas</code> and
<code>autoscaler</code> from database resources in form <br>submission


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3192/files#diff-6d00a7b503dbd4b76f86d3949458d7f0bd62622cf17c523e0d668e3b459b67b5">+11/-7</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>graphql.ts</strong><dd><code>Update GraphQL types for
Postgres resources</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

dashboard/src/utils/__generated__/graphql.ts

<li>Updated <code>ConfigPostgresResources</code> type<br> <li> Removed
<code>replicas</code>, <code>autoscaler</code>, and
<code>networking</code> fields<br> <li> Added
<code>ConfigPostgresResourcesStorage</code> type<br> <li> Updated
related comparison, insert, and update types


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3192/files#diff-fbd5db84b560b1c91675004448c6c7fa0dcbfb28b9eb05d53b03e6cb7b83ebac">+28/-46</a>&nbsp;
</td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>getResources.gql</strong><dd><code>Update Postgres
resources GraphQL query</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/resources/settings/gql/getResources.gql

<li>Removed <code>replicas</code> and <code>autoscaler</code> fields
from Postgres resources query


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3192/files#diff-45c2f030236a2836bd4ba61e46a20bc0b40f2ab08874c056c49b285a9c2c80eb">+0/-4</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>

---------

Co-authored-by: robertkasza <robert@nhost.io>
2025-02-11 08:29:06 +01:00
David BM
05f063b8e2 fix (dashboard): undefined is not an object in logs page (#3139)
### **PR Type**
Bug fix


___

### **Description**
- Fixed undefined object evaluation in logs page

- Improved error handling in LogsHeader component

- Enhanced data loading checks in LogsPage

- Refactored imports for better organization


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>LogsHeader.tsx</strong><dd><code>Improve error handling
in LogsHeader component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/logs/components/LogsHeader/LogsHeader.tsx

<li>Added null check for <code>data</code> in useEffect hooks<br> <li>
Reordered imports for better organization


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3139/files#diff-ebb3285aa776c9c5ea8b72672c4aafd55994c6c694998bbf56ca9c56d1e77664">+3/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>logs.tsx</strong><dd><code>Enhance data loading and
error handling in LogsPage</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

dashboard/src/pages/orgs/[orgSlug]/projects/[appSubdomain]/logs.tsx

<li>Added <code>loadingProject</code> to useProject hook<br> <li>
Destructured <code>loadingLogs</code> from useGetProjectLogsQuery<br>
<li> Created combined <code>loading</code> state<br> <li> Fixed
potential undefined <code>project</code> in subscription


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3139/files#diff-77489a68a7526d74f06d59019ad68c44728b7620637308d70fba38d6649b73fa">+18/-10</a>&nbsp;
</td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>empty-dancers-do.md</strong><dd><code>Add changeset for
bug fix in logs page</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/empty-dancers-do.md

<li>Added changeset file for version bump<br> <li> Described fix for
undefined object in logs page


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3139/files#diff-1b8f8750870d40489590edead6484834991c219568156c38b95a55aa55d9362b">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-02-06 21:23:03 +01:00
github-actions[bot]
09f5bed1e8 chore: update versions (#3187)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @nhost/dashboard@2.19.0

# @nhost/dashboard

## 2.17.0

### Minor Changes

-   fd59918: fix: redirect to 404 with nhost cli dashboard

## 2.16.0

### Minor Changes

-   f8e6b61: fix: can add rule groups in table permissions
-   9e404c8: fix: not redirect to 404 page if using local Nhost backend
-   ac4aa01: fix: can delete column in database page
-   4385524: fix: update url to check service health in local dashboard

### Patch Changes

-   @nhost/react-apollo@16.0.1
-   @nhost/nextjs@2.2.2

## 2.15.0

### Minor Changes

- f1052a8: fix: improve stability of the dashboard when pausing projects
-   30daa41: fix: update links to docs in overview page
-   7537237: feat: add image preview toggle in storage

## 2.14.0

### Minor Changes

- d43931e: fix: invalid organization slug/project subdomain doesn't open
404 page
- 5df6fa2: feat: add unencrypted disk warning in storage capacity
settings

### Patch Changes

-   44c1e17: chore: update `msw` to v1.3.5 to fix vulnerabilities
    -   @nhost/react-apollo@16.0.0
    -   @nhost/nextjs@2.2.1

## 2.13.0

### Minor Changes

- 21e90da: chore: remove restrictions on SMTP sender so My Name
[name@acme.com](mailto:name@acme.com) can be added
- 865dd93: fix: duplicate Run placeholders when there is an error in the
backend
- 6902a36: fix: can remove resources if postgres capacity is higher than
10
-   a535aa3: fix: fetch user roles locally in auth section
-   0c50816: fix: allow decimal numbers in database row insert
- aea6d18: chore: add warning when pausing a project about losing Run
services persistent volume data
- d3b4fc3: feat: allow to change postgres settings if project is paused
-   29d27e1: chore: update `next` to v14.2.22 to fix vulnerabilities
-   c9dca09: feat: add reset password form
-   b3bcacb: fix: paused project banner cannot read null project name

### Patch Changes

-   Updated dependencies [46fc520]
-   Updated dependencies [29d27e1]
    -   @nhost/nextjs@2.2.0
    -   @nhost/react-apollo@15.0.1

## 2.12.0

### Minor Changes

- eb95562: fix: show all available permission variables in permission
dropdown select

### Patch Changes

- 8b5c4a0: chore: cleanup layout and add disable duplicate atom key
checking in development mode

## 2.11.3

### Patch Changes

- 714dffa: fix: improve project polling logic and unify usage across
components

## 2.11.2

### Patch Changes

- 6a34f89: fix: improve project polling logic and unify usage across
components

## 2.11.1

### Patch Changes

-   0f6ce52: fix: consolidate useProject hook and fix jwt expired error

## 2.11.0

### Minor Changes

-   cea3ef5: Feat: add org and project placeholders

## 2.10.0

### Minor Changes

-   86ecf27: feat: add support for additional metrics in overview
- 21708be: feat: dashboard: add support for storage buckets to AI
assistants

## 1.30.0

### Minor Changes

- 50441a8: feat: add ui for project autoscaler settings and run services
autoscaler settings

## 1.29.0

### Minor Changes

-   55d8bb5: feat: integrate turnstile for signup verification
-   2a2e54c: fix: update docs url in run services form tooltip
- 18f942f: fix: display long error messages in error toast without
overflow

### Patch Changes

-   @nhost/react-apollo@13.0.0
-   @nhost/nextjs@2.1.22

## 1.28.2

### Patch Changes

- 52a38fe: chore: update dependencies to address security
vulnerabilities
-   Updated dependencies [52a38fe]
    -   @nhost/nextjs@2.1.21

## 1.28.1

### Patch Changes

-   9735fa2: chore: remove broken link

## 1.28.0

### Minor Changes

- 526183a: feat: allow filtering users in "make request as" in graphql
section
-   be3b85b: feat: add conceal errors toggle on auth settings page

### Patch Changes

- 35a2f12: fix: prevent run service details from opening when attempting
to delete
    -   @nhost/react-apollo@12.0.6
    -   @nhost/nextjs@2.1.20

## 1.27.0

### Minor Changes

-   a7cd02c: fix: resolve rate limit query

## 1.26.0

### Minor Changes

-   3773ad7: chore: update pricing information
- b63250d: fix: not allow run service creation form resubmission while
creating a run service
-   a44a1d4: feat: add rate limits settings page

### Patch Changes

-   @nhost/react-apollo@12.0.5
-   @nhost/nextjs@2.1.19

## 1.25.0

### Minor Changes

- d1ceede: feat: add setting to migrate postgres major and/or minor
versions
- e5d3d1a: fix: allow manually typing column for custom check in
database row permissions

### Patch Changes

-   @nhost/react-apollo@12.0.4
-   @nhost/nextjs@2.1.18

## 1.24.1

### Patch Changes

- 49f2e55: fix: use service subdomain in service form and service
details dialog
- 598b988: fix: use current project subdomain in ServiceDetailsDialog
component

## 1.24.0

### Minor Changes

-   abb24af: chore: add redirect to support page when project is locked
- 18a6455: feat: show contact us info and locked reason when project is
locked

### Patch Changes

-   e31eefa: fix: include ingresses field when updating run services

## 1.23.0

### Minor Changes

-   33284d3: fix: don't show double scrollbar in configuration editor

### Patch Changes

-   @nhost/react-apollo@12.0.3
-   @nhost/nextjs@2.1.17

## 1.22.0

### Minor Changes

-   998c037: fix: align drop-down list in select component
- 807b8c0: fix: show city name in region selection for project creation

## 1.21.0

### Minor Changes

- a2efeed: fix: improve project health error handling, add unknown state
and polling interval for health state

## 1.20.0

### Minor Changes

- 8ea4210: fix: error toasts can be closed individually, instead of
dismissing all toasts at once
- 58919ba: chore: add blink animation when project health service is
updating

## 1.19.0

### Minor Changes

- b519862: fix: get configuration in configuration editor using local
development environment

## 1.18.0

### Minor Changes

- 502abad: feat: add services health checks indicators to the overview
page
-   b3ff6ad: chore: update title text on service status modal
- dbadf59: feat: add project configuration TOML editor to the settings
page

## 1.17.0

### Minor Changes

- 77fba27: fix: postgres version validation when activating ai in ai
settings page
-   ac6d1b6: feat: use name instead of awsName

## 1.16.3

### Patch Changes

- 87a37cf: fix: remove unnecessary isPlatform check from verify button
disable logic on custom domains
    -   @nhost/react-apollo@12.0.2
    -   @nhost/nextjs@2.1.16

## 1.16.2

### Patch Changes

- a9413af: fix: update `GetAllWorkspacesAndProjects` query polling to
use exponential backoff
    -   @nhost/react-apollo@12.0.1
    -   @nhost/nextjs@2.1.15

## 1.16.1

### Patch Changes

-   @nhost/react-apollo@12.0.0
-   @nhost/nextjs@2.1.14

## 1.16.0

### Minor Changes

- c6d5c5c: feat: add toggle switch to enable/disable public access in
the database settings

## 1.15.2

### Patch Changes

-   @nhost/react-apollo@11.0.4
-   @nhost/nextjs@2.1.13

## 1.15.1

### Patch Changes

-   @nhost/react-apollo@11.0.3
-   @nhost/nextjs@2.1.12

## 1.15.0

### Minor Changes

-   a7bde37: feat: send metadata in the edit form

### Patch Changes

- 1bc615b: feat: improve error message handling in `ErrorToast`
component
    -   @nhost/react-apollo@11.0.2
    -   @nhost/nextjs@2.1.11

## 1.14.0

### Minor Changes

-   a448d7d: feat: allow configuring postmark and delete SMTP settings

## 1.13.3

### Patch Changes

-   5924bc3: fix: include password in `GetSmtpSettings` query
- c5ad634: fix: resolved an issue where one-click install links were
broken on Safari
- 7278991: fix: update graphql auto-embeddings configuration to use
String type for model field

## 1.13.2

### Patch Changes

-   026f84f: fix: use configuration server URL from environment variable

## 1.13.1

### Patch Changes

-   7e9a2ce: fix: resolve issue where run services form fails to open

## 1.13.0

### Minor Changes

-   dd5d262: feat: add model field to the auto-embeddings form
- 09962be: feat: enable settings and run services when running the
dashboard locally
- 9cdecb6: feat: enable users to update their email address from the
account settings page

## 1.12.2

### Patch Changes

-   c195c51: fix: send email upon signin for unverified users

## 1.12.1

### Patch Changes

- 93ebdf8: fix: use service urls when initilizaing NhostClient running
local dashboard
    -   @nhost/react-apollo@11.0.1
    -   @nhost/nextjs@2.1.10

## 1.12.0

### Minor Changes

- f242e4b: feat: add connect with github to the user's account settings
-   768ca17: chore: update dependencies
- d62bd0f: fix: "Track this" option within the SQL editor now correctly
updates the metadata
- 91c2bb6: feat: refactor sign-in and sign-up pages to enforce email
verification

### Patch Changes

-   943831f: fix: resolve an error toast issue when unpausing a project
-   Updated dependencies [768ca17]
    -   @nhost/react-apollo@11.0.0
    -   @nhost/nextjs@2.1.9

## 1.11.2

### Patch Changes

-   @nhost/react-apollo@10.0.2
-   @nhost/nextjs@2.1.8

## 1.11.1

### Patch Changes

-   981404f: fix: set default value for healthCheck field validation

## 1.11.0

### Minor Changes

- 7789469: chore: upgrade dependency `@graphql-codegen/cli` to `5.0.2`
to address vulnerability
- 6c11b75: feat: add update user displayName section in account settings

### Patch Changes

-   @nhost/react-apollo@10.0.1
-   @nhost/nextjs@2.1.7

## 1.10.0

### Minor Changes

-   49a80c2: chore: update dependencies
-   150c04a: feat: add healthcheck config to run services

### Patch Changes

- e03f141: fix: allow insert, update and delete on tables in `auth` and
`storage` schemas
- 28676f4: feat: add min postgres version check to enable the ai service
-   Updated dependencies [49a80c2]
    -   @nhost/react-apollo@10.0.0
    -   @nhost/nextjs@2.1.6

## 1.9.0

### Minor Changes

-   d86e5c9: feat: add support for filtering the logs using a RegExp

## 1.8.3

### Patch Changes

-   @nhost/react-apollo@9.0.3
-   @nhost/nextjs@2.1.5

## 1.8.2

### Patch Changes

- 6df4f02: fix: use custom error toast and show correct message when
sending an invite

## 1.8.1

### Patch Changes

-   @nhost/react-apollo@9.0.2
-   @nhost/nextjs@2.1.4

## 1.8.0

### Minor Changes

- 713d53c: feat: add catch-all route for workspace/project - useful for
documentation

### Patch Changes

-   3db2999: fix: refresh table list after running SQL using the editor
- 3c4dd55: fix: handle `Error` objects properly in the `ErrorToast`
component
- 92b434e: fix: resolve an issue where the checkbox in the data-grid
header did not select all rows
    -   @nhost/react-apollo@9.0.1
    -   @nhost/nextjs@2.1.3

## 1.7.0

### Minor Changes

-   0d8d0eb: Update docs and dashboard references

## 1.6.9

### Patch Changes

-   @nhost/react-apollo@9.0.0
-   @nhost/nextjs@2.1.2

## 1.6.8

### Patch Changes

-   @nhost/react-apollo@8.0.1
-   @nhost/nextjs@2.1.1

## 1.6.7

### Patch Changes

-   5ef5189: fix: update `@apollo/client` to `3.9.4` to fix a cache bug

## 1.6.6

### Patch Changes

-   3ba485e: fix: added discord.com to connect-src
-   e5bab6a: chore: update dependencies
-   Updated dependencies [b19ffed]
-   Updated dependencies [e5bab6a]
    -   @nhost/nextjs@2.1.0
    -   @nhost/react-apollo@8.0.0

## 1.6.5

### Patch Changes

- ba73bb4: fix: update ErrorToast component to show the internal graphql
error
- d5337ff: fix: utilize accumulator in the creation of validation schema
within data grid utils

## 1.6.4

### Patch Changes

-   7c2a1c2: feat: show error and debug info in the error toast

## 1.6.3

### Patch Changes

-   6b8aad5: fix: add bare nhost.run to CSP

## 1.6.2

### Patch Changes

-   b18edc0: feat: added CSP and X-Frame-Options

## 1.6.1

### Patch Changes

-   8d91f71: chore: update deps and enable pnpm audit
- 3b8473b: chore: update turbo to `1.11.3` and pnpm to `8.10.5` in
Dockerfile
-   Updated dependencies [8d91f71]
    -   @nhost/react-apollo@7.0.2
    -   @nhost/nextjs@2.0.2

## 1.6.0

### Minor Changes

-   3ff1c2b53: fix: show upgrade option for pro projects

## 1.5.0

### Minor Changes

-   c2ef17c0a: feat: add support for new Team plan

## 1.4.0

### Minor Changes

-   7883bbcbd: feat: don't show deprecated plans
- 44be6dc0a: feat: set redirectTo during sign-in to support preview
environments

### Patch Changes

- 3c3594898: fix: allow access to graphite when configured running in
local dashboard
-   32c246b7a: chore: update docs icon

## 1.3.2

### Patch Changes

-   174b4165b: chore: use env variables when running graphql codegen
-   7c977e714: chore: change `Allowed Roles` to `Default Allowed Roles`
-   46f028b9f: fix: remove hardcoded ai version setting

## 1.3.1

### Patch Changes

- af33c21d1: chore: remove backendUrl deprecation notice and remove all
references to `providersUpdated`

## 1.3.0

### Minor Changes

-   04784d880: Fix graphite's default version

## 1.2.0

### Minor Changes

-   5733162ed: feat: add settings and ui for graphite

## 1.1.0

### Minor Changes

-   e2b79b5ec: chore: remove sharp from deps

## 1.0.1

### Patch Changes

-   @nhost/react-apollo@7.0.1
-   @nhost/nextjs@2.0.1

## 1.0.0

### Major Changes

- bc9eff6e4: chore: remove support for using backendUrl when
instantiating the Nhost client

### Patch Changes

-   Updated dependencies [bc9eff6e4]
    -   @nhost/nextjs@2.0.0
    -   @nhost/react-apollo@7.0.0

## 0.21.1

### Patch Changes

-   97ced73a3: fix(dashboard): prevent dashboard from resolving secrets

## 0.21.0

### Minor Changes

- ed1a8d458: Update alert message on increasing PostgreSQL's volume
capacity
-   2e2248fd4: feat(dashboard): add SQL editor

## 0.20.28

### Patch Changes

-   7c2c31082: feat: add support for users to delete their account
    -   @nhost/react-apollo@6.0.1
    -   @nhost/nextjs@1.13.40

## 0.20.27

### Patch Changes

- fa79b7709: chore(dashboard): tweaks and fixes to the service form and
dialog
-   8df84d782: fix(dashboard): allow resetting custom domains
    -   @nhost/react-apollo@6.0.0
    -   @nhost/nextjs@1.13.39

## 0.20.26

### Patch Changes

- 331ba0376: feat(dashboard): add postgres storage capacity modifier in
the settings
-   b7f801874: feat(dashboard): add new settings page for custom domains

## 0.20.25

### Patch Changes

-   @nhost/react-apollo@5.0.38

## 0.20.24

### Patch Changes

-   e10389ecf: fix(dashboard): disable run tab when developing locally
    -   @nhost/react-apollo@5.0.37

## 0.20.23

### Patch Changes

-   c01568a7d: chore(dashboard): show alert to update oauth providers

## 0.20.22

### Patch Changes

-   c3efb7ec8: feat(dashboard): query latest announcement from platform

## 0.20.21

### Patch Changes

-   3e46d3873: chore: update link to node18 announcement

## 0.20.20

### Patch Changes

-   @nhost/react-apollo@5.0.36
-   @nhost/nextjs@1.13.38

## 0.20.19

### Patch Changes

-   75c4c8ae3: feat(dashboard): make env value input multiline

## 0.20.18

### Patch Changes

- 425d485f8: fix(dashboard): make sure dedicated resources pricing
follows total resources

## 0.20.17

### Patch Changes

-   ae324f67f: fix(dashboard): remove unused graphql fields

## 0.20.16

### Patch Changes

-   df5b4302c: chore(dashboard): remove run feature flag
- bf4a1f6c2: feat(dashboard): fetch auth, postgres, hasura and storage
versions from dashboard
- 34fc08ca7: fix(dashboard/run): show correct private registry in
service details
-   885d10620: chore(dashboard): change feedback to contact us

## 0.20.15

### Patch Changes

- ed16c8b5d: feat(run): add a confirmation dialog when deleting a run
service
- 216990888: fix(run): center loading indicator when selecting a project

## 0.20.14

### Patch Changes

-   9fbea9787: feat: add node18 announcement

## 0.20.13

### Patch Changes

- e84acf469: fix(run): handle subdomain undefined error when creating a
new service

## 0.20.12

### Patch Changes

-   b7c799d62: feat(run): add dialog to copy registry and URLs

## 0.20.11

### Patch Changes

-   8903e6abd: fix(dashboard): show correct egress limit in usage stats

## 0.20.10

### Patch Changes

- 666a75a23: feat(dashboard): add functions execution time and egress
volume to usage stats

## 0.20.9

### Patch Changes

-   5e1e80aa8: fix(dashboard): show correct locales in user details
    -   @nhost/react-apollo@5.0.35
    -   @nhost/nextjs@1.13.37

## 0.20.8

### Patch Changes

-   @nhost/react-apollo@5.0.34
-   @nhost/nextjs@1.13.36

## 0.20.7

### Patch Changes

-   4a7ede11e: fix: distinguish files that were not uploaded
- 202b64723: feat(nhost-run): add support for one-click-install run
services
- 074a0fa11: feat(dashboard): add settings toggle to enable/disable
antivirus
    -   @nhost/react-apollo@5.0.33
    -   @nhost/nextjs@1.13.35

## 0.20.6

### Patch Changes

-   b20761e97: feat(services): add pricing info and confirmation dialog
-   90df6d81d: fix(services): handle null values when editing a service
-   aa8508467: fix: query service logs correctly
    feat: enable multiline support for environment value input

## 0.20.5

### Patch Changes

-   8d7f84b8d: fix: make announcement adapt to theme

## 0.20.4

### Patch Changes

-   3b75bfce2: fix: make announcement close properly
- f49819075: fix: show correct values when dedicated resources are
disabled

## 0.20.3

### Patch Changes

-   e643bd362: fix(services): fix errors when config is null
-   bcdab66bf: feat: add annoucement for nhost run
-   f967a2e59: added note about storage not being able to be downsized
-   311c7756d: chore(services): consistent naming for compute

## 0.20.2

### Patch Changes

-   9073182d5: chore(dashboard): bump `turbo` to 1.10.11
-   ece717d6e: feat(logs): show services in the logs page
- 82b335311: feat(metrics): change grafana link to point to the
dashboards
- b135ef695: fix(services): set command as optional and set min replicas
to 0

## 0.20.1

### Patch Changes

-   3d5c34f4c: fix(auth): fix users pagination limit

## 0.20.0

### Minor Changes

-   c99d117d1: feat(services): add support for custom services

## 0.19.2

### Patch Changes

-   face99ccd: chore(deps): bump turbo version
-   cfe527307: style: tweak pull config warning in dark mode
- a9d7da8af: chore(deps): update dependency @types/pluralize to ^0.0.30
-   9aa4371ef: chore: add hasura-auth version 0.21.2
- d14e112bf: chore(deps): update dependency prettier-plugin-tailwindcss
to ^0.4.0
-   d3e8bb94a: chore(deps): update dependency vite-plugin-dts to v3

## 0.19.1

### Patch Changes

-   @nhost/react-apollo@5.0.32
-   @nhost/nextjs@1.13.34

## 0.19.0

### Minor Changes

- 9c61c69a7: chore(dashboard):add postgres 14.6-20230705-1 to the
version selector

### Patch Changes

-   47bda15ff: feat(settings): add warning to pull config

## 0.18.0

### Minor Changes

- ee0b9b8ed: chore(dashboard):add hasura v2.28.2 and v2.29.0 to the
version selector

## 0.17.20

### Patch Changes

-   @nhost/react-apollo@5.0.31
-   @nhost/nextjs@1.13.33

## 0.17.19

### Patch Changes

-   f866120a6: fix(users): use the password length from the config

## 0.17.18

### Patch Changes

-   @nhost/react-apollo@5.0.30
-   @nhost/nextjs@1.13.32

## 0.17.17

### Patch Changes

-   ea7b102c0: fix(pat): highlight expired tokens

## 0.17.16

### Patch Changes

- b3b64a3b7: chore(deps): bump `@types/react` to `v18.2.14` and
`@types/react-dom` to `v18.2.6`
-   32b221f94: chore(deps): bump `graphiql` to `v3`
-   3a56c12df: chore(deps): bump `turbo` to `v1.10.6`
-   Updated dependencies [b3b64a3b7]
    -   @nhost/react-apollo@5.0.29
    -   @nhost/nextjs@1.13.31

## 0.17.15

### Patch Changes

-   f41fdc12a: chore(deps): bump `turbo` to `1.10.5`
-   6199c1c55: fix(projects): don't redirect to 404 page
-   Updated dependencies [07a45fde0]
    -   @nhost/react-apollo@5.0.28
    -   @nhost/nextjs@1.13.30

## 0.17.14

### Patch Changes

- 80b22724d: chore(deps): bump `@types/react` to `v18.2.13`,
`@types/react-dom` to `v18.2.6` and `@storybook/testing-library` to
`v0.2.0`

## 0.17.13

### Patch Changes

-   cc02902cb: chore(docs): update environment variable documentation

## 0.17.12

### Patch Changes

-   660d339e1: fix(storybook): don't break storybook
-   660d339e1: fix(tests): prevent warnings during tests
    -   @nhost/react-apollo@5.0.27
    -   @nhost/nextjs@1.13.29

## 0.17.11

### Patch Changes

- bd4d0c270: chore(dashboard):add postgres 14.6-20230613-1 to the
version selector

## 0.17.10

### Patch Changes

-   c8c2a10b2: fix(database): don't break the password reset flow
- e70b45498: chore(deps): bump `@types/react` to `v18.2.12` and
`@types/react-dom` to `v18.2.5`

## 0.17.9

### Patch Changes

- 842055099: chore(deps): bump `turbo` to `v1.10.3` and `pnpm` to
`v8.6.2`
- fd12aa0a8: chore(projects): remove the postgres password input from
the project creation screen
-   022b76e78: chore(deps): bump `@types/react` to `v18.2.11`
-   3555ab2b7: chore(deps): bump `vitest` monorepo to `v0.32.0`
-   c43e54922: feat(backups): add download button to backups

## 0.17.8

### Patch Changes

-   d0457fe5c: feat(settings): improve the dashboard and config parity
    -   @nhost/react-apollo@5.0.26
    -   @nhost/nextjs@1.13.28

## 0.17.7

### Patch Changes

-   4f0368b95: fix(account): don't break account settings page

## 0.17.6

### Patch Changes

- 64a8f41d0: chore(resources): lower the maximum allowed resources per
service

## 0.17.5

### Patch Changes

-   @nhost/react-apollo@5.0.25
-   @nhost/nextjs@1.13.27

## 0.17.4

### Patch Changes

- 9b1d0f7a5: fix(deployments): use correct timestamp for deployment
details
-   6d2963ffa: chore(deps): bump `@types/react` to `v18.2.8`
- 8871267b9: chore(deps): downgrade `pnpm` to `v8.5.1` because of no
Turborepo support

## 0.17.3

### Patch Changes

-   01eeef9de: chore(misc): under the hood improvements
- 21e13db05: chore(deps): bump `@types/react` to `v18.2.7` and `turbo`
to `v1.10.1`
- f16433ae6: chore(secrets): allow empty secrets and environment
variables
-   aa3c62989: chore(cli): bump Nhost CLI version to v1.0
    -   @nhost/react-apollo@5.0.24
    -   @nhost/nextjs@1.13.26

## 0.17.2

### Patch Changes

-   88a4983f: chore(misc): under the hood improvements

## 0.17.1

### Patch Changes

-   9b0d4dde: feat(secrets): enable secrets

## 0.17.0

### Minor Changes

-   15d84a19: Add postgres 14.6-20230525

## 0.16.14

### Patch Changes

-   4c626174: chore: updated import paths, improved directory structure
-   cc047b71: chore(deps): bump `@fontsource` monorepo to `v5.0.0`
-   99edd012: feat(account): add support for personal access tokens

## 0.16.13

### Patch Changes

-   78c7109c: feat(settings): allow selecting service versions

## 0.16.12

### Patch Changes

- 399009d6: fix(gql): don't enter an infinite loop when fetching remote
app data
- 329e5a91: fix(deployments): use the same sorting of deployments
everywhere
- 6d559d6e: chore(settings): add under the hood improvements to the
settings page
- 12eb236c: chore(deps): bump `prettier-plugin-tailwindcss` to `v0.3.0`
-   f9b81a2a: chore(deps): bump `turbo` to `v1.9.8`
-   1345741b: fix(projects): don't redirect to 404 on project creation
-   Updated dependencies [7fea29a8]
    -   @nhost/react-apollo@5.0.23
    -   @nhost/nextjs@1.13.25

## 0.16.11

### Patch Changes

- 1230b722: fix(projects): don't redirect to 404 on when the project is
renamed
    -   @nhost/react-apollo@5.0.22
    -   @nhost/nextjs@1.13.24

## 0.16.10

### Patch Changes

-   Updated dependencies [da03bf39]
    -   @nhost/react-apollo@5.0.21
    -   @nhost/nextjs@1.13.23

## 0.16.9

### Patch Changes

- 349aac36: fix(settings): use region domain when constructing the
postgres connection string

## 0.16.8

### Patch Changes

- 20fb69fa: chore(projects): change the way how API URLs are constructed

## 0.16.7

### Patch Changes

- 49f9b837: chore(docker): bump `pnpm` to `v8.4.0` and `turbo` to
`v1.9.3`
- 3f478a4e: chore(deps): bump `vitest` to `v0.31.0`, `@types/react` to
`v18.2.6` and `@types/react-dom` to `v18.2.4`

## 0.16.6

### Patch Changes

- d926f156: fix(projects): redirect to 404 when an invalid project is
opened
- 49b99728: fix(projects): disable features for non-owner members of
workspaces

## 0.16.5

### Patch Changes

-   12e2855f: chore(deps): bump `jsdom` to v22
-   e4972b83: feat(metrics): add Grafana page

## 0.16.4

### Patch Changes

- 3f396a9e: fix(projects): unpause after upgrading a paused project to
pro
- 3f396a9e: fix(projects): don't redirect to 404 page after project
creation

## 0.16.3

### Patch Changes

-   Updated dependencies [90c60311]
    -   @nhost/react-apollo@5.0.20
    -   @nhost/nextjs@1.13.22

## 0.16.2

### Patch Changes

-   0f34f0c6: fix(projects): disallow downgrading to free plan
- 8da291ad: chore(deps): bump `@types/react` to v18.2.0 and
`@types/react-dom` to v18.2.1

## 0.16.1

### Patch Changes

- adc828a5: fix(gql): don't enter an infinite loop when fetching remote
app data

## 0.16.0

### Minor Changes

-   2fb1145f: feat(compute): add support for replicas

### Patch Changes

- d8ceccec: chore(env): remove deprecated `NHOST_BACKEND_URL`
environment variable

## 0.15.2

### Patch Changes

-   84b84ab7: fix(projects): filter projects by workspace

## 0.15.1

### Patch Changes

-   2faf7907: chore(deps): bump `graphql-request` to v6
-   f1b5a944: chore(deps): bump `@vitejs/plugin-react` to v4
-   7f1785ac: chore(deps): bump `@types/react` to v18.0.37
    -   @nhost/react-apollo@5.0.19

## 0.15.0

### Minor Changes

-   85889ee8: feat(dashboard): add Compute management to the settings

## 0.14.8

### Patch Changes

-   668c8771: chore(dialogs): unify dialog management of payment dialogs

## 0.14.7

### Patch Changes

-   d4ccc656: chore: cleanup unused code
    -   @nhost/react-apollo@5.0.18
    -   @nhost/nextjs@1.13.21

## 0.14.6

### Patch Changes

-   b299cfc9: chore(deps): bump `vitest` to v0.30.0
-   411cb65b: chore(projects): refactor workspace and project hooks
- 43b1b144: chore(deps): bump `@types/react` to v18.0.34 and
`@types/react-dom` to v18.0.11
-   Updated dependencies [43b1b144]
    -   @nhost/react-apollo@5.0.17
    -   @nhost/nextjs@1.13.20

## 0.14.5

### Patch Changes

-   ba0d57ee: fix(i18n): revert i18n library
-   3328ed05: feat(projects): improve overview when there is an error

## 0.14.4

### Patch Changes

-   5e0920ba: chore(deps): bump `next-seo` to v6
-   706c9dc3: chore(deps): bump `@types/react` to 18.0.33
-   99f8f6b3: feat(metrics): show metrics on the overview

## 0.14.3

### Patch Changes

-   @nhost/react-apollo@5.0.16

## 0.14.2

### Patch Changes

-   3cb67300: fix(logs): don't break UI when clearing time picker
-   7453bf3b: feat(projects): show project creator info
-   c166dad0: chore(tests): improve auth page tests
-   6a290bb2: chore(deps): bump `@types/react` to 18.0.32

## 0.14.1

### Patch Changes

-   @nhost/react-apollo@5.0.15
-   @nhost/nextjs@1.13.19

## 0.14.0

### Minor Changes

-   6e1f03ea: feat(dashboard): add support for the Azure AD provider

### Patch Changes

-   1bd2c373: chore(deps): bump `turbo` to 1.8.6
-   d329b621: chore(deps): bump `@types/react` to 18.0.30
-   cb248f0d: fix(tests): avoid name collision in database tests
-   867c8076: chore(deps): bump `@types/react` to 18.0.29

## 0.13.10

### Patch Changes

- e93b06ab: fix(dashboard): remove left margin from workspace list on
mobile
-   1c4806bf: chore(deps): bump `sharp` to 0.32.0
    -   @nhost/react-apollo@5.0.14
    -   @nhost/nextjs@1.13.18

## 0.13.9

### Patch Changes

-   912ed76c: chore(dashboard): bump `@apollo/client` to 3.7.10
-   Updated dependencies [912ed76c]
    -   @nhost/react-apollo@5.0.13

## 0.13.8

### Patch Changes

-   7c127372: chore(dashboard): bump `react-error-boundary` to v4

## 0.13.7

### Patch Changes

- 9130ab12: chore(dashboard): bump `yup` to v1 and `@hookform/resolvers`
to v3

## 0.13.6

### Patch Changes

- 253dd235: using new mutation to create projects + refactor Create
Project page.

## 0.13.5

### Patch Changes

-   @nhost/react-apollo@5.0.12
-   @nhost/nextjs@1.13.17

## 0.13.4

### Patch Changes

-   b48bc034: fix(dashboard): disable new users
-   798e591b: fix(dashboard): show correct date in data grid

## 0.13.3

### Patch Changes

-   bfb4c1a6: chore(dashboard): remove `useAxios` property
-   d8d8394b: Dashboard: allow to override hasura admin secret in docker
-   Updated dependencies [ce1ee40d]
    -   @nhost/nextjs@1.13.16
    -   @nhost/react-apollo@5.0.11

## 0.13.2

### Patch Changes

-   beed2eba: Fix docker entrypoint for dashboard
- 2c8559a3: fix(dashboard): refresh project list after deleting a
project
-   4329d048: chore(dashboard): bump `graphiql` dependencies

## 0.13.1

### Patch Changes

-   cbb1fc5b: chore(dashboard): cleanup GraphQL operations

## 0.13.0

### Minor Changes

-   088584e7: feat(dashboard): add support for custom local subdomains

### Patch Changes

-   2ac90dfd: fix(dashboard): improve mobile responsive layout
-   Updated dependencies [f375eacc]
    -   @nhost/nextjs@1.13.15
    -   @nhost/react-apollo@5.0.10

## 0.12.4

### Patch Changes

-   @nhost/react-apollo@5.0.9
-   @nhost/nextjs@1.13.14

## 0.12.3

### Patch Changes

-   2b1338f7: chore(dashboard): bump `turbo` to 1.8.3
- 5223ee93: fix(dashboard): show correct deployment status on the main
page
-   850a049c: chore(deps): update docker/build-push-action action to v4
-   Updated dependencies [850a049c]
    -   @nhost/nextjs@1.13.13
    -   @nhost/react-apollo@5.0.8

## 0.12.2

### Patch Changes

-   4bf40995: chore(deps): bump `typescript` to `4.9.5`
-   8bb097c9: chore(deps): bump `vitest`
- 35d52aab: chore(deps): replace `cross-fetch` with `isomorphic-unfetch`
-   Updated dependencies [4bf40995]
-   Updated dependencies [8bb097c9]
-   Updated dependencies [35d52aab]
    -   @nhost/react-apollo@5.0.7
    -   @nhost/nextjs@1.13.12

## 0.12.1

### Patch Changes

-   c96d7ccd: fix(dashboard): fix docker builds

## 0.12.0

### Minor Changes

-   d1671210: feat(dashboard): use mimir to manage project configuration

### Patch Changes

-   f65e4de9: chore(deps): bump @graphql-codegen monorepo to v3

## 0.11.20

### Patch Changes

-   4b4f0d01: chore(dashboard): improve dialog management

## 0.11.19

### Patch Changes

-   @nhost/react-apollo@5.0.6
-   @nhost/nextjs@1.13.11

## 0.11.18

### Patch Changes

-   01318860: fix(nhost-js): use correct URL for functions requests
-   Updated dependencies [01318860]
    -   @nhost/react-apollo@5.0.5
    -   @nhost/nextjs@1.13.10

## 0.11.17

### Patch Changes

-   f673adea: fix(dashboard): set correct Content-Type for user creation
-   445d8ef4: chore(deps): bump `@nhost/react-apollo` to 5.0.4
-   445d8ef4: chore(deps): bump `@nhost/nextjs` to 1.13.9
- 0368663d: fix(dashboard): allow permission editing for auth and
storage schemas
-   Updated dependencies [445d8ef4]
-   Updated dependencies [445d8ef4]
    -   @nhost/react-apollo@5.0.4
    -   @nhost/nextjs@1.13.9

## 0.11.16

### Patch Changes

-   b755e908: fix(dashboard): use correct date for last seen
-   2d9145f9: chore(deps): revert GraphQL client
- 1ddf704c: fix(dashboard): don't show false positive message for failed
user creation
    -   @nhost/react-apollo@5.0.3
    -   @nhost/nextjs@1.13.8

## 0.11.15

### Patch Changes

-   @nhost/react-apollo@5.0.2
-   @nhost/nextjs@1.13.7

## 0.11.14

### Patch Changes

- 2cc18dcb: fix(dashboard): prevent permission editor dropdown from
being always open

## 0.11.13

### Patch Changes

- 3343a363: chore(dashboard): bump `@testing-library/react` to v14 and
`@testing-library/dom` to v9
    -   @nhost/react-apollo@5.0.1
    -   @nhost/nextjs@1.13.6

## 0.11.12

### Patch Changes

- 87eda76e: chore(dashboard): bump `@types/react` to v18.0.28 and
`@types/react-dom` to v18.0.11
-   6f0ac570: feat(dashboard): show dashboard version in account menu

## 0.11.11

### Patch Changes

-   bf1e4071: chore(dashboard): bump `react-is` version to `18.2.0`
-   Updated dependencies [bf1e4071]
-   Updated dependencies [5013213b]
    -   @nhost/nextjs@1.13.5
    -   @nhost/react-apollo@4.13.5

## 0.11.10

### Patch Changes

- a37a430b: fix(dashboard): don't break UI when deployments are
unavailable
    -   @nhost/react-apollo@4.13.4
    -   @nhost/nextjs@1.13.4

## 0.11.9

### Patch Changes

-   7b970e68: fix(dashboard): fix header link color

## 0.11.8

### Patch Changes

- f33242f2: feat(dashboard): add new sign up, sign in and reset password
pages

## 0.11.7

### Patch Changes

-   e9c8909c: fix(dashboard): use correct theme color in dark mode

## 0.11.6

### Patch Changes

-   902f486b: fix(dashboard): re-enable Hasura on logs page

## 0.11.5

### Patch Changes

-   1f9720fa: fix(dashboard): apply select permissions properly

## 0.11.4

### Patch Changes

-   deb14b51: fix(dashboard): don't break billing form

## 0.11.3

### Patch Changes

-   @nhost/react-apollo@4.13.3
-   @nhost/nextjs@1.13.3

## 0.11.2

### Patch Changes

-   f143e51d: chore(dashboard): pin Turborepo to 1.6.3

## 0.11.1

### Patch Changes

-   c2b5a41a: chore(dashboard): select system colors by default

## 0.11.0

### Minor Changes

-   1ebaf429: feat(dashboard): introduce Dark Mode 🌚

### Patch Changes

- 63b445c4: fixed duplicated logs bug and made to date count during live
mode

## 0.10.1

### Patch Changes

-   e146d32e: chore(deps): update dependency @types/react to v18.0.27
-   59347fcd: correct allowed role name
-   5b65cac9: updated authentication documentation
-   963f9b5e: feat(dashboard): include project info in feedback

## 0.10.0

### Minor Changes

-   ed4c7801: chore(dashboard): remove Functions section

## 0.9.10

### Patch Changes

-   4e2f8ccd: fix(dashboard): don't break Auth page in local mode

## 0.9.9

### Patch Changes

-   31abbe5f: fix(dashboard): enable toggle when settings are filled in

## 0.9.8

### Patch Changes

- 5bdd31ad: chore(dashboard): list fewer images per page on the Storage
page
- 5121851c: fix(dashboard): don't throw validation error for valid
permission rules

## 0.9.7

### Patch Changes

-   c126b20d: fix(dashboard): correct redeployment button

## 0.9.6

### Patch Changes

-   36c3519c: feat(dashboard): retrigger deployments

## 0.9.5

### Patch Changes

- 200e9f77: chore(deps): update dependency @types/react-dom to v18.0.10
-   Updated dependencies [200e9f77]
    -   @nhost/nextjs@1.13.2
    -   @nhost/react-apollo@4.13.2

## 0.9.4

### Patch Changes

- dbd3ded5: fix(dashboard): workspaces creation, new form, correct
redirects.

## 0.9.3

### Patch Changes

-   85f0f943: fix(dashboard): don't break the table creation process

## 0.9.2

### Patch Changes

-   Updated dependencies [d42c27ae]
-   Updated dependencies [927be4a2]
    -   @nhost/nextjs@1.13.1
    -   @nhost/react-apollo@4.13.1

## 0.9.1

### Patch Changes

-   d0f80811: fix(dashboard): don't show error when signing out the user

## 0.9.0

### Minor Changes

- d92891b2: feat(dashboard): add Permission Editor to the Database
section

### Patch Changes

-   3d379128: fix(dashboard): create new user
    -   @nhost/react-apollo@4.13.0
    -   @nhost/nextjs@1.13.0

## 0.8.1

### Patch Changes

-   7cadd944: fix(dashboard): display Twitter provider settings

## 0.8.0

### Minor Changes

-   9a1aa7bb: add functions to the log dashboard
-   f29abe62: feat(dashboard): Users Management v2

### Patch Changes

-   7766624b: feat(dashboard): add JWT secret editor modal
    -   @nhost/react-apollo@4.12.1
    -   @nhost/nextjs@1.12.1

## 0.7.13

### Patch Changes

-   dd0738d5: fix(dashboard): provisioning status polling

## 0.7.12

### Patch Changes

-   b21222b3: chore(deps): update dependency @types/node to v16
-   9e0486a3: fix(dashboard): close modals when navigating
-   Updated dependencies [b21222b3]
-   Updated dependencies [65687bee]
-   Updated dependencies [54df0df4]
    -   @nhost/nextjs@1.12.0
    -   @nhost/react-apollo@4.12.0

## 0.7.11

### Patch Changes

-   d6527122: fix(dashboard): use correct service URLs

## 0.7.10

### Patch Changes

-   Updated dependencies [57db5b83]
    -   @nhost/nextjs@1.11.0
    -   @nhost/nhost-js@1.7.0
    -   @nhost/react@0.17.0
    -   @nhost/react-apollo@4.11.0

## 0.7.9

### Patch Changes

- a6d31dc2: fix(dashboard): don't break the UI when project is not
loaded yet

## 0.7.8

### Patch Changes

- 7f251111: Use `NhostProvider` instead of `NhostReactProvider` and
`NhostNextProvider`

    `NhostReactProvider` and `NhostNextProvider` are now deprecated

-   f4d70f88: fix(dashboard): do not break when region is nullish

- 4a9471cc: Windows Live Provider displayed link updated to match
backend url

- 594488e4: fix(dashboard): do not show error when submitting Apple
provider settings

-   Updated dependencies [7f251111]
    -   @nhost/nextjs@1.10.0
    -   @nhost/react@0.16.0
    -   @nhost/react-apollo@4.10.0

## 0.7.7

### Patch Changes

-   80b604ad: fix(dashboard): use correct Hasura slug

## 0.7.6

### Patch Changes

-   2d2beb53: fix(dashboard): prevent error on GraphQL page
-   ac8efcbd: chore(dashboard): deprecate old DNS name

## 0.7.5

### Patch Changes

-   132a4f4b: chore(dashboard): remove unused dependencies
- 132a4f4b: chore(deps): synchronize @types/react-dom and @types/react
versions
-   db57572f: fix(dashboard): correct section paddings when no env vars
-   Updated dependencies [132a4f4b]
    -   @nhost/react@0.15.2
    -   @nhost/react-apollo@4.9.2
    -   @nhost/nextjs@1.9.3

## 0.7.4

### Patch Changes

-   34d85e54: chore(deps): update dependency critters to ^0.0.16
- 9b93cf95: chore(deps): update dependency @netlify/functions to ^0.11.0
-   e0439030: chore(deps): update dependency @types/react-dom to v18.0.9
-   Updated dependencies [82124329]
    -   @nhost/nextjs@1.9.2

## 0.7.3

### Patch Changes

-   a1193da4: fix(dashboard): remove character limit from env var inputs

## 0.7.2

### Patch Changes

-   44f13f62: chore(dashboard): cleanup unused files

## 0.7.1

### Patch Changes

- e01cb2ed: chore(dashboard): change settings sidebar menu item density

## 0.7.0

### Minor Changes

- db342f45: chore(dashboard): refactor Roles and Permissions settings
sections
-   8b9fa0b1: feat(dashboard): add Environment Variables page

### Patch Changes

-   Updated dependencies [66b4f3d0]
-   Updated dependencies [2e6923dc]
-   Updated dependencies [ef117c28]
-   Updated dependencies [aebb8225]
    -   @nhost/core@0.9.4
    -   @nhost/nhost-js@1.6.2
    -   @nhost/nextjs@1.9.1
    -   @nhost/react@0.15.1
    -   @nhost/react-apollo@4.9.1

## 0.6.0

### Minor Changes

-   eef9c914: feat(dashboard): add Roles and Permissions page

## 0.5.0

### Minor Changes

-   a48dd5bf: feat(dashboard): make backend port configurable

## 0.4.3

### Patch Changes

-   5de965d9: fix(dashboard): alphabetic ordering of providers
-   b9087a4a: fix(dashboard): console -> dashboard terminology
-   ca012d79: docs(workos): WorkOS Docs

## 0.4.2

### Patch Changes

-   89bd37bc: fix(dashboard): correct redirect URL input opacity
-   Updated dependencies [4601d84e]
-   Updated dependencies [843087cb]
    -   @nhost/react@0.15.0
    -   @nhost/nextjs@1.9.0
    -   @nhost/react-apollo@4.9.0

## 0.4.1

### Patch Changes

-   766cb612: fix(dashboard): correct redirect URL for oauth providers
-   Updated dependencies [53bdc294]
-   Updated dependencies [f2aaff05]
    -   @nhost/nextjs@1.8.3
    -   @nhost/core@0.9.3
    -   @nhost/react@0.14.3
    -   @nhost/nhost-js@1.6.1
    -   @nhost/react-apollo@4.8.3

## 0.4.0

### Minor Changes

-   9211743d: feat(dashboard): migrate Settings page features

## 0.3.0

### Minor Changes

-   73da6a67: fix(dashboard): avoid using BACKEND_URL locally

## 0.2.0

### Minor Changes

-   db118f97: feat(dashboard): generate Docker image

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-02-06 14:36:09 +01:00
David BM
91d5fbba42 fix (dashboard): invalid slug/subdomain should open 404 (#3172)
### **User description**
Fixes #3119


___

### **PR Type**
Bug fix, Enhancement


___

### **Description**
- Fix invalid slug/subdomain to open 404 page

- Disable inaccessible pages in local CLI dashboard

- Improve project page navigation and accessibility

- Enhance not found redirect logic


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>OrgPagesComboBox.tsx</strong><dd><code>Disable
organization pages combo box for non-platform use</code></dd></summary>
<hr>

dashboard/src/components/layout/Header/OrgPagesComboBox.tsx

<li>Import useIsPlatform hook<br> <li> Disable PopoverTrigger when not
on platform


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3172/files#diff-b70a46a4233201c9a2650c930192b4417f35a27303ff5c78872c05a41a92c8ac">+4/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>ProjectPagesComboBox.tsx</strong><dd><code>Enhance
project pages combo box with platform-specific
disabling</code></dd></summary>
<hr>

dashboard/src/components/layout/Header/ProjectPagesComboBox.tsx

<li>Refactor projectPages to use useMemo<br> <li> Add 'disabled'
property to project page options<br> <li> Disable certain pages based on
isPlatform value


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3172/files#diff-70b3af41358f0a22b83e502409a70a0df15e8946d958dbaee4c32b6ebdb38cf6">+106/-83</a></td>

</tr>
</table></td></tr><tr><td><strong>Bug fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>useNotFoundRedirect.ts</strong><dd><code>Improve 404
redirect logic for invalid slugs and subdomains</code></dd></summary>
<hr>


dashboard/src/features/projects/common/hooks/useNotFoundRedirect/useNotFoundRedirect.ts

<li>Add checks for valid organization and project<br> <li> Implement
platform-specific redirect logic<br> <li> Include additional loading
states in redirect decision


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3172/files#diff-837279cf43199053bca09913f62c4af019063a2e8dc7bfb7643ec54b7cecd29d">+41/-10</a>&nbsp;
</td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>heavy-eyes-smile.md</strong><dd><code>Add changeset for
dashboard improvements</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

.changeset/heavy-eyes-smile.md

<li>Add changeset for @nhost/dashboard package<br> <li> Describe fix for
invalid slug/subdomain and local CLI dashboard


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3172/files#diff-9a0418cf1a2622ce3bbec8df535fa44974433329d5386f0a90eee7e60167b1c6">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-06 14:30:00 +01:00
David Barroso
498363db25 chore (dashboard): regenerate graphql bindings (#3188)
### **PR Type**
Enhancement


___

### **Description**
- Updated GraphQL bindings in dashboard

- Changed postgres config from optional to required

- Removed 'Graphite' from Software_Type_Enum

- Modified ConfigPostgres and related types


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>graphql.ts</strong><dd><code>Update GraphQL types and
queries for Postgres</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

dashboard/src/utils/__generated__/graphql.ts

<li>Changed <code>postgres</code> from optional to required in
ConfigConfig<br> <li> Updated ConfigPostgres and related types<br> <li>
Removed 'Graphite' from Software_Type_Enum<br> <li> Modified query and
mutation types to reflect changes


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3188/files#diff-fbd5db84b560b1c91675004448c6c7fa0dcbfb28b9eb05d53b03e6cb7b83ebac">+12/-14</a>&nbsp;
</td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>perfect-hairs-wave.md</strong><dd><code>Add changeset
for GraphQL bindings update</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

.changeset/perfect-hairs-wave.md

<li>Added changeset file for patch version bump<br> <li> Described
change as regenerating GraphQL bindings


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3188/files#diff-a0885845ed7d68d0b6922f52b710db28275617df1ae791a850f16f58d90a6097">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-06 14:08:33 +01:00
robertkasza
8c2779930b fix (dashboard): fetch allowed roles from the project's auth.roles table (#3179)
### **User description**
fetch allowed roles from the project's auth.roles table


___

### **PR Type**
Enhancement, Bug fix


___

### **Description**
- Fetch allowed roles from project's auth.roles table

- Implement useAllowedUserRoles custom hook

- Update UsersBody component to use new hook

- Add GraphQL query for fetching allowed roles


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>index.ts</strong><dd><code>Export new
useAllowedUserRoles hook</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

dashboard/src/features/orgs/hooks/useAllowedUserRoles/index.ts

- Export useAllowedUserRoles hook


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3179/files#diff-d6a91d913b67d5e22fab8ee1ad0998e13e23be19fee0bff8329bd2e7e49d3ac4">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>useAllowedUserRoles.ts</strong><dd><code>Implement
useAllowedUserRoles custom hook</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/hooks/useAllowedUserRoles/useAllowedUserRoles.ts

<li>Implement useAllowedUserRoles custom hook<br> <li> Fetch auth roles
from remote application<br> <li> Process and return allowed user roles


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3179/files#diff-aa27d882a97f3ae9286266919c70218e5df29b1419769d8cd2886e80d4e95c04">+17/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>UsersBody.tsx</strong><dd><code>Refactor UsersBody to
use new useAllowedUserRoles hook</code>&nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>


dashboard/src/features/orgs/projects/authentication/users/components/UsersBody/UsersBody.tsx

<li>Replace useGetRolesPermissionsQuery with useAllowedUserRoles<br>
<li> Remove unused imports and variables<br> <li> Simplify code by using
new hook


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3179/files#diff-33b33017f46d5cb8e4652c183619f3dc86c5377125ed3a612888739e0da22484">+3/-25</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>graphql.ts</strong><dd><code>Add generated types for
new allowed roles query</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

dashboard/src/utils/__generated__/graphql.ts

<li>Add GetRemoteAppAllowedRolesQuery type and related functions<br>
<li> Generate GraphQL hooks for new query


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3179/files#diff-fbd5db84b560b1c91675004448c6c7fa0dcbfb28b9eb05d53b03e6cb7b83ebac">+42/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>getAllowedRoles.graphql</strong><dd><code>Add GraphQL
query for fetching allowed roles</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

dashboard/src/gql/remote-app/getAllowedRoles.graphql

- Add GraphQL query to fetch allowed roles from authRoles table


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3179/files#diff-442c2503cc0e462029c952852520773a1ea1a8526949398ce59f2535d7131aec">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>tall-houses-mix.md</strong><dd><code>Add changeset for
allowed roles fix</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/tall-houses-mix.md

<li>Add changeset for minor version bump<br> <li> Describe fix for
fetching allowed roles


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3179/files#diff-a7caacd8e8e971694232815f20297858ecefe39e86e80190e776b5fb47652191">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-05 17:28:16 +01:00
robertkasza
0aa27a2fd1 feat (dashboard): allow to create new org from the transfer project dialog (#3169)
### **User description**
feat (dashboard): allow to create new org from the transfer project
dialog

___

### **PR Type**
Enhancement, Bug fix


___

### **Description**
- Allow creating new org from transfer project dialog

- Improve upgrade to pro button functionality

- Add unit tests for new features

- Fix error after redirecting from checkout


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>15
files</summary><table>
<tr>
<td><strong>OpenTransferDialogButton.tsx</strong><dd><code>Add new
OpenTransferDialogButton component</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-e86a4216c48c54e1a2652ff3609575d6bf193d085ad42849a85dc6d4abba950c">+40/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>index.ts</strong><dd><code>Export OpenTransferDialogButton
component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-c1fd683ba66a0e7f6a4622051d9e548ee32f215f29bcf0dd22b0827f8c38bc12">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>UpgradeToProBanner.tsx</strong><dd><code>Refactor
UpgradeToProBanner to use OpenTransferDialogButton</code></dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-f38fc14d24ec6ee22f9a100cc473c641dcdc66284d41d030c456bf505094ed9d">+5/-28</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>CreateOrgFormDialog.tsx</strong><dd><code>Enhance
CreateOrgDialog with new props and functionality</code>&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-9a1ed9e851328393b81356d80ade3509016aa55c254ed1f4deb692b0bd96f02e">+47/-18</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>FinishOrgCreationProcess.tsx</strong><dd><code>Add new
FinishOrgCreationProcess component</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-7602855e6aaab1dd3810c866acbedd5b9eb22c271806969eb9a3435f1c76ca8d">+53/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>index.ts</strong><dd><code>Export FinishOrgCreationProcess
component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-a9faaff5f8d044125799178a6e33aa49ebed3aa1aaa8c2261162e2b25e24e0bd">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>FinishOrgCreation.tsx</strong><dd><code>Add new
FinishOrgCreation component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-bf22866bc3f80e45cdf18035146a8c7be6a38d1f6726b0e28d63879aacd263a4">+24/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>TransferProjectDialog.tsx</strong><dd><code>Enhance
TransferProjectDialog with new org creation</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-b68d4641a67e07a8bf8c14e1f705059c564e1bca53e591783581af27a488d86e">+221/-114</a></td>

</tr>

<tr>
<td><strong>NotificationsTray.tsx</strong><dd><code>Update
NotificationsTray to handle session_id</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-8b559ee1d3176203e8a4e1588924d57944d09d792117ed578b27cd5401ee5d4f">+15/-4</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>index.ts</strong><dd><code>Export useFinishOrgCreation
hook</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-de59152f45a5fbf6b999d3cd9e4e14eefbde27e4cccf0d6ed6da5e2956db24ec">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>useFinishOrgCreation.ts</strong><dd><code>Add new
useFinishOrgCreation custom hook</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-3b8bf7608ab36d8ab0df895e400f0d2d9e29fad2055b40b33d8d9912a27c99c3">+92/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>OverviewTopBar.tsx</strong><dd><code>Add
UpgradeProjectDialog to OverviewTopBar</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-560ae107ed8e458fa4b4a226b9f5c24e24b042b5f9bcea9317c78e75929faa4b">+20/-15</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>UpgradeProjectDialog.tsx</strong><dd><code>Add new
UpgradeProjectDialog component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-7bfab4ad088dbc503c1304f5620e22e02f70602bf14ba6b495969b882b2eb30e">+20/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>utils.ts</strong><dd><code>Add isEmptyValue and
isNotEmptyValue utilities</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-57035bfd3b91de326fec3e5a0bf19487f03130a9a09dc3e428c79f556677081b">+17/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>verify.tsx</strong><dd><code>Refactor verify page to use
FinishOrgCreationProcess</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-5fa0ea2519bed6649a8aa98826526945868bd7a925c5ce5edb3fd14e81273947">+24/-104</a></td>

</tr>

</table></details></td></tr><tr><td><strong>Tests</strong></td><td><details><summary>5
files</summary><table>
<tr>
<td><strong>TransferProjectDialog.test.tsx</strong><dd><code>Add unit
tests for TransferProjectDialog</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-d4ebdb8af76a7c9e73606708718c3448445545259ad553d73b6d322408e3eb8c">+233/-0</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>NotificationsTray.test.tsx</strong><dd><code>Add unit tests
for NotificationsTray</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-727f6debec6a102557407e55c56363e0c75486e30a732158f85c81ada892f77c">+167/-0</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>utils.test.ts</strong><dd><code>Add unit tests for
isEmptyValue utility</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-d85d96942b9d8ae1eae8781e4f092ee9c8183affd76669a6195df713bc801184">+35/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>setupTests.ts</strong><dd><code>Mock ResizeObserver in test
setup</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-20b15fc9d6987586d0a853c077a4aff66b005fdb2e2b99bb5eb494d4c8c38366">+11/-1</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>mocks.ts</strong><dd><code>Add mock data for
organizations</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-d1ef12c0f15123bb4e23a0c513fc3d9b5c16af421c71c2909fde3717e09a9d89">+53/-0</a>&nbsp;
&nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Additional
files</strong></td><td><details><summary>8 files</summary><table>
<tr>
  <td><strong>shiny-feet-rest.md</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-a358ec02ec88d2af39c757f5cb97adcd184ba2614974df53dcb358591b6ca8d0">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>settings.json</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-5ea4d30be0c6c4cf5c0f1980f0dfe7cd7bdecee565746acb5ec90b0f79ff9314">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>getOrganizationQuery.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-8a0d854ee3a00b7a8b6661eb8008f3fe2140190fc6543a9674d287f786466d21">+22/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>getProjectQuery.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-01bab55f0611d27001640c4215cb6d97f8e2b1d45bc56e519d78b282a12c05e7">+12/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>organizationRequests.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-3cf4d908676a8050fe83c1bf53a57e6577a24fcae13b142ada89da7072d0975e">+22/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>prefetchNewAppQuery.ts</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-0a3a444a14b5f5495ef86c90f200a3a672732770e90d4b7206468e2ac265d9fe">+73/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>testUtils.tsx</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-6ebbd73e167641a1706f1b8d30b00569336d10f3c2ab7626d81e639015383e5e">+50/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>tsconfig.test.json</strong></td>
<td><a
href="https://github.com/nhost/nhost/pull/3169/files#diff-e7bc653278c33281fda4e64da0f34c8c613b99891a16611366edc1c05870a935">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-05 17:04:18 +01:00
David BM
8656749e5a fix (dashboard CI): e2e tests teardown (#3186)
### **PR Type**
Tests, Enhancement


___

### **Description**
- Added new e2e tests for database permissions.

- Implemented a new teardown process for database cleanup.

- Removed global teardown script and updated configuration.

- Enhanced utility functions for test operations.


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Tests</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>permissions-table.test.ts</strong><dd><code>Add e2e
tests for database permissions</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

dashboard/e2e/database/permissions-table.test.ts

<li>Added tests for creating tables with role permissions.<br> <li>
Included tests for custom checks on row selection.<br> <li> Utilized
Playwright for browser automation in tests.


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3186/files#diff-f4b586f5b8f3bb97ddf64f8f38c461ac0424e101789f61e325d1b80bb8dc1047">+149/-0</a>&nbsp;
</td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>database.teardown.ts</strong><dd><code>Implement
database cleanup teardown script</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

dashboard/e2e/teardown/database.teardown.ts

<li>Implemented new teardown script for database cleanup.<br> <li>
Automated table deletion using SQL in Playwright.<br> <li> Set up
browser context for teardown operations.


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3186/files#diff-4c0d8019f6c1586d9dc41b89d10e9a71f5913559112fdf6eed38094d832a126d">+61/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>global-teardown.ts</strong><dd><code>Remove global
teardown script</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

dashboard/global-teardown.ts

<li>Removed global teardown script.<br> <li> Deprecated old teardown
approach using Hasura.


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3186/files#diff-1ee3d64258c498cdfa30665ec61605ab817622c7dae2a09bd4b6b23606c13e9f">+0/-67</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>utils.ts</strong><dd><code>Add utility function for
permission button clicks</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

dashboard/e2e/utils.ts

<li>Added utility function for clicking permission buttons.<br> <li>
Enhanced test utilities for role-based operations.


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3186/files#diff-490448aa83585151d8c61d698273c43486fdcac6a5d28a9b7e5be2729bbffd12">+20/-0</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Configuration
changes</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>playwright.config.ts</strong><dd><code>Update
Playwright configuration for new teardown</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

dashboard/playwright.config.ts

<li>Updated Playwright config to remove global teardown.<br> <li> Added
new teardown project configuration.


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3186/files#diff-3ce7004405593146d0b9c501fc50a6a5ae2da8bb48b57dee2faf79ca9c09cf62">+5/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-05 16:08:00 +01:00
robertkasza
d097eb8feb fix (dashboard): fix edit permission form cannot be saved (#3183)
### **PR Type**
Bug fix


___

### **Description**
- Fix edit permission form saving issue

- Update validation schema for rule groups

- Modify operator validation in EditPermissionsForm

- Add new development script for dashboard


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>validationSchemas.ts</strong><dd><code>Update
validation schema for EditPermissionsForm</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/database/dataGrid/components/EditPermissionsForm/validationSchemas.ts

<li>Updated operator validation message<br> <li> Added custom test for
operator in ruleGroupSchema<br> <li> Implemented conditional validation
for operator based on filter <br>presence


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3183/files#diff-98f990165c3aca93bc01808ac0dcbde7b347ad2fd86fe52311d306a2fb3aaf0f">+19/-2</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>curly-toys-peel.md</strong><dd><code>Add changeset for
dashboard patch</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/curly-toys-peel.md

<li>Added changeset file for @nhost/dashboard patch<br> <li> Described
fix for edit permission form saving issue


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3183/files#diff-ee0a00268ee800059ef11e5531cc42195a54f4b8779466be210968e2bb2e30f3">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>package.json</strong><dd><code>Add development script
for dashboard</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

package.json

<li>Added new script 'dev:dashboard' for running dashboard in
development <br>mode


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3183/files#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-02-05 10:05:51 +01:00
280 changed files with 8101 additions and 2706 deletions

View File

@@ -30,6 +30,14 @@ runs:
uses: actions/setup-node@v3
with:
node-version: 20
- shell: bash
name: Use Latest Corepack
run: |
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
npm install -g corepack@latest
echo "After : corepack version => $(corepack --version)"
corepack enable
pnpm --version
- shell: bash
name: Install packages
run: pnpm install --frozen-lockfile

View File

@@ -1,6 +1,9 @@
name: Nhost CLI
description: 'Action to install the Nhost CLI and to run an application'
inputs:
init:
description: 'Initialize the application'
default: 'false'
start:
description: "Start the application. If false, the application won't be started"
default: 'false'
@@ -16,6 +19,9 @@ inputs:
version:
description: 'Version of the Nhost CLI'
default: 'latest'
dashboard-image:
description: 'Image of the dashboard'
default: 'nhost/dashboard:latest'
config:
description: 'Values to be injected into nhost/config.yaml'
@@ -40,6 +46,13 @@ runs:
timeout_minutes: 3
max_attempts: 10
command: bash <(curl --silent -L https://raw.githubusercontent.com/nhost/cli/main/get.sh) ${{ inputs.version }}
- name: Initialize a new project from scratch
if: ${{ inputs.init == 'true' }}
shell: bash
working-directory: ${{ inputs.path }}
run: |
rm -rf ./*
nhost init
- name: Set custom configuration
if: ${{ inputs.config }}
shell: bash
@@ -50,7 +63,12 @@ runs:
shell: bash
working-directory: ${{ inputs.path }}
run: |
cp .secrets.example .secrets
if [ -n "${{ inputs.dashboard-image }}" ]; then
export NHOST_DASHBOARD_VERSION=${{ inputs.dashboard-image }}
fi
if [ -f .secrets.example ]; then
cp .secrets.example .secrets
fi
nhost up
- name: Log on failure
if: steps.wait.outcome == 'failure'

View File

@@ -134,10 +134,27 @@ jobs:
with:
TURBO_TOKEN: ${{ env.TURBO_TOKEN }}
TURBO_TEAM: ${{ env.TURBO_TEAM }}
# * Build Dashboard image to test it locally
- name: Build Dashboard local image
if: matrix.package.path == 'dashboard'
run: |
docker build -t nhost/dashboard:0.0.0-dev -f ${{ matrix.package.path }}/Dockerfile .
mkdir -p nhost-test-project
# * Install Nhost CLI if a `nhost/config.yaml` file is found
- name: Install Nhost CLI
if: hashFiles(format('{0}/nhost/config.yaml', matrix.package.path)) != ''
if: hashFiles(format('{0}/nhost/config.yaml', matrix.package.path)) != '' && matrix.package.path != 'dashboard'
uses: ./.github/actions/nhost-cli
# * Install Nhost CLI to test Dashboard locally
- name: Install Nhost CLI (Local Dashboard tests)
timeout-minutes: 5
if: matrix.package.path == 'dashboard'
uses: ./.github/actions/nhost-cli
with:
init: 'true' # Initialize the application
start: 'true' # Start the application
path: ./nhost-test-project
wait: 'true' # Wait until the application is ready
dashboard-image: 'nhost/dashboard:0.0.0-dev'
- name: Fetch Dashboard Preview URL
id: fetch-dashboard-preview-url
uses: zentered/vercel-preview-url@v1.1.9
@@ -157,6 +174,17 @@ jobs:
- name: Run e2e tests
timeout-minutes: 20
run: pnpm --filter="${{ matrix.package.name }}" run e2e
# * Run the `e2e-local` script of the dashboard
- name: Run Local Dashboard e2e tests
if: matrix.package.path == 'dashboard'
timeout-minutes: 5
run: |
pnpm --filter="${{ matrix.package.name }}" run e2e-local
- name: Stop Nhost CLI
if: matrix.package.path == 'dashboard'
working-directory: ./nhost-test-project
run: nhost down
- id: file-name
if: ${{ failure() }}
name: Transform package name into a valid file name

View File

@@ -25,10 +25,10 @@ jobs:
- name: Install the Nhost CLI and start the application
uses: ./.github/actions/nhost-cli
with:
path: packages/nhost-js
init: true
start: true
- name: should be running
run: curl -sSf 'https://local.hasura.nhost.run' > /dev/null
run: curl -sSf 'https://local.hasura.local.nhost.run/' > /dev/null
stop:
runs-on: ubuntu-latest
@@ -37,7 +37,7 @@ jobs:
- name: Install the Nhost CLI, start and stop the application
uses: ./.github/actions/nhost-cli
with:
path: packages/nhost-js
init: true
start: true
stop: true
- name: should have no live docker container
@@ -55,12 +55,13 @@ jobs:
- name: Install the Nhost CLI and run the application
uses: ./.github/actions/nhost-cli
with:
path: packages/nhost-js
init: true
version: v1.29.3
start: true
- name: should find the injected hasura-auth version
run: |
VERSION=$(curl -sSf 'https://local.auth.nhost.run/v1/version')
EXPECTED_VERSION='{"version":"v0.20.1"}'
VERSION=$(curl -sSf 'https://local.auth.local.nhost.run/v1/version')
EXPECTED_VERSION='{"version":"0.36.1"}'
if [ "$VERSION" != "$EXPECTED_VERSION" ]; then
echo "Expected version $EXPECTED_VERSION but got $VERSION"
exit 1
@@ -73,6 +74,6 @@ jobs:
- name: Install the Nhost CLI
uses: ./.github/actions/nhost-cli
with:
version: v1.0.1
version: v1.27.2
- name: should find the correct version
run: nhost --version | head -n 1 | grep v1.0.1 || exit 1
run: nhost --version | head -n 1 | grep v1.27.2 || exit 1

2
.gitignore vendored
View File

@@ -63,3 +63,5 @@ out/
# Nix
.envrc
.direnv/
/.vscode/

View File

@@ -4,7 +4,7 @@
# Nhost
<a href="https://docs.nhost.io/#quickstart">Quickstart</a>
<a href="https://docs.nhost.io/introduction#quick-start-guides">Quickstart</a>
<span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
<a href="http://nhost.io/">Website</a>
<span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
@@ -36,7 +36,7 @@ Nhost consists of open source software:
- Authentication: [Hasura Auth](https://github.com/nhost/hasura-auth/)
- Storage: [Hasura Storage](https://github.com/nhost/hasura-storage)
- Serverless Functions: Node.js (JavaScript and TypeScript)
- [Nhost CLI](https://docs.nhost.io/cli) for local development
- [Nhost CLI](https://docs.nhost.io/development/cli/overview) for local development
## Architecture of Nhost
@@ -89,12 +89,12 @@ await nhost.graphql.request(`{
Nhost is frontend agnostic, which means Nhost works with all frontend frameworks.
<div align="center">
<a href="https://docs.nhost.io/platform/quickstarts/nextjs"><img src="assets/nextjs.svg"/></a>
<a href="https://docs.nhost.io/guides/quickstarts/nextjs"><img src="assets/nextjs.svg"/></a>
<a href="https://docs.nhost.io/reference/javascript"><img src="assets/nuxtjs.svg"/></a>
<a href="https://docs.nhost.io/platform/quickstarts/react"><img src="assets/react.svg"/></a>
<a href="https://docs.nhost.io/guides/quickstarts/react"><img src="assets/react.svg"/></a>
<a href="https://docs.nhost.io/reference/javascript"><img src="assets/react-native.svg"/></a>
<a href="https://docs.nhost.io/reference/javascript"><img src="assets/svelte.svg"/></a>
<a href="https://docs.nhost.io/platform/quickstarts/vue"><img src="assets/vuejs.svg"/></a>
<a href="https://docs.nhost.io/guides/quickstarts/vue"><img src="assets/vuejs.svg"/></a>
</div>
# Resources
@@ -140,7 +140,7 @@ This repository, and most of our other open source projects, are licensed under
Here are some ways of contributing to making Nhost better:
- **[Try out Nhost](https://docs.nhost.io/get-started/quick-start)**, and think of ways to make the service better. Let us know here on GitHub.
- **[Try out Nhost](https://docs.nhost.io/introduction)**, and think of ways to make the service better. Let us know here on GitHub.
- Join our [Discord](https://discord.com/invite/9V7Qb2U) and connect with other members to share and learn from.
- Send a pull request to any of our [open source repositories](https://github.com/nhost) on Github. Check our [contribution guide](https://github.com/nhost/nhost/blob/main/CONTRIBUTING.md) and our [developers guide](https://github.com/nhost/nhost/blob/main/DEVELOPERS.md) for more details about how to contribute. We're looking forward to your contribution!

View File

@@ -3,18 +3,19 @@ NEXT_PUBLIC_ENV=dev
NEXT_PUBLIC_NHOST_PLATFORM=false
# Environment Variables for Self Hosting and Local Development
NEXT_PUBLIC_NHOST_AUTH_URL=https://local.auth.nhost.run/v1
NEXT_PUBLIC_NHOST_FUNCTIONS_URL=https://local.functions.nhost.run/v1
NEXT_PUBLIC_NHOST_GRAPHQL_URL=https://local.graphql.nhost.run/v1
NEXT_PUBLIC_NHOST_STORAGE_URL=https://local.storage.nhost.run/v1
NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL=https://local.hasura.nhost.run
NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL=https://local.hasura.nhost.run/v1/migrations
NEXT_PUBLIC_NHOST_HASURA_API_URL=https://local.hasura.nhost.run
NEXT_PUBLIC_NHOST_AUTH_URL=https://local.auth.nhost.local.run/v1
NEXT_PUBLIC_NHOST_FUNCTIONS_URL=https://local.functions.local.nhost.run/v1
NEXT_PUBLIC_NHOST_GRAPHQL_URL=https://local.graphql.local.nhost.run/v1
NEXT_PUBLIC_NHOST_STORAGE_URL=https://local.storage.local.nhost.run/v1
NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL=https://local.hasura.local.nhost.run
NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL=https://local.hasura.local.nhost.run/v1/migrations
NEXT_PUBLIC_NHOST_HASURA_API_URL=https://local.hasura.local.nhost.run
# Environment Variables when running the Nhost Dashboard against the Nhost Backend
NEXT_PUBLIC_STRIPE_PK=<nhost_stripe_public_key>
NEXT_PUBLIC_GITHUB_APP_INSTALL_URL=<github_app_install_url>
NEXT_PUBLIC_ANALYTICS_WRITE_KEY=<analytics_write_key>
NEXT_PUBLIC_SEGMENT_CDN_URL=<segment_cdn_url>
NEXT_PUBLIC_NHOST_BRAGI_WEBSOCKET=<nhost_bragi_websocket>
NEXT_PUBLIC_ZENDESK_URL=
@@ -22,6 +23,6 @@ NEXT_PUBLIC_ZENDESK_API_KEY=
NEXT_PUBLIC_ZENDESK_USER_EMAIL=
CODEGEN_GRAPHQL_URL=https://local.graphql.nhost.run/v1
CODEGEN_GRAPHQL_URL=https://local.graphql.local.nhost.run/v1
CODEGEN_HASURA_ADMIN_SECRET=nhost-admin-secret
NEXT_PUBLIC_TURNSTILE_SITE_KEY=FIXME

View File

@@ -1,6 +1,6 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"editor.codeActionsOnSave": {
"source.organizeImports": true
"source.organizeImports": "explicit"
}
}

View File

@@ -33,7 +33,7 @@ ENV NEXT_PUBLIC_NHOST_CONFIGSERVER_URL=__NEXT_PUBLIC_NHOST_CONFIGSERVER_URL__
RUN yarn global add pnpm@9.15.0
COPY .gitignore .gitignore
COPY --from=pruner /app/out/json/ .
COPY --from=pruner /app/out/pnpm-*.yaml .
COPY --from=pruner /app/out/pnpm-*.yaml ./
RUN pnpm install --frozen-lockfile
COPY --from=pruner /app/out/full/ .

View File

@@ -51,13 +51,13 @@ You can connect the Nhost Dashboard to your locally running backend by setting t
```bash
NEXT_PUBLIC_ENV=dev
NEXT_PUBLIC_NHOST_PLATFORM=false
NEXT_PUBLIC_NHOST_AUTH_URL=https://local.auth.nhost.run/v1
NEXT_PUBLIC_NHOST_FUNCTIONS_URL=https://local.functions.nhost.run/v1
NEXT_PUBLIC_NHOST_GRAPHQL_URL=https://local.graphql.nhost.run/v1
NEXT_PUBLIC_NHOST_STORAGE_URL=https://local.storage.nhost.run/v1
NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL=https://local.hasura.nhost.run
NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL=https://local.hasura.nhost.run/v1/migrations
NEXT_PUBLIC_NHOST_HASURA_API_URL=https://local.hasura.nhost.run
NEXT_PUBLIC_NHOST_AUTH_URL=https://local.auth.local.nhost.run/v1
NEXT_PUBLIC_NHOST_FUNCTIONS_URL=https://local.functions.local.nhost.run/v1
NEXT_PUBLIC_NHOST_GRAPHQL_URL=https://local.graphql.local.nhost.run/v1
NEXT_PUBLIC_NHOST_STORAGE_URL=https://local.storage.local.nhost.run/v1
NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL=https://local.hasura.local.nhost.run
NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL=https://local.hasura.local.nhost.run/v1/migrations
NEXT_PUBLIC_NHOST_HASURA_API_URL=https://local.hasura.local.nhost.run
```
This will connect the Nhost Dashboard to your locally running Nhost backend.

View File

@@ -0,0 +1,43 @@
import { TEST_ORGANIZATION_SLUG, TEST_PROJECT_SUBDOMAIN } from '@/e2e/env';
import { createUser, generateTestEmail } from '@/e2e/utils';
import { faker } from '@faker-js/faker';
import type { Page } from '@playwright/test';
import test, { expect } from '@playwright/test';
let page: Page;
test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
});
test.beforeEach(async () => {
const authUrl = `/orgs/${TEST_ORGANIZATION_SLUG}/projects/${TEST_PROJECT_SUBDOMAIN}/users`;
await page.goto(authUrl);
await page.waitForURL(authUrl, { waitUntil: 'networkidle' });
});
test.afterAll(async () => {
await page.close();
});
test('should be able to edit user roles from the details page', async () => {
const email = generateTestEmail();
const password = faker.internet.password();
await createUser({ page, email, password });
await page
.getByRole('button', { name: `View ${email}`, exact: true })
.click();
await page.locator('#defaultRole').click();
await page.getByRole('option', { name: /anonymous/i }).click();
await page.getByLabel('anonymous').click();
await page.getByRole('button', { name: /save/i }).click();
await expect(
page.getByText('User settings have been updated successfully.'),
).toBeVisible();
});

View File

@@ -0,0 +1,21 @@
import { expect, test } from '@playwright/test';
test.describe('Local Dashboard CLI e2e tests', () => {
test('should redirect / to the correct project URL', async ({ page }) => {
await page.goto('https://local.dashboard.local.nhost.run/');
await page.waitForURL(
'https://local.dashboard.local.nhost.run/orgs/local/projects/local',
);
expect(page.url()).toBe(
'https://local.dashboard.local.nhost.run/orgs/local/projects/local',
);
});
test('should load the project URL correctly', async ({ page }) => {
const projectUrl =
'https://local.dashboard.local.nhost.run/orgs/local/projects/local';
await page.goto(projectUrl);
await expect(page).toHaveURL(projectUrl);
await expect(page.getByText(/Subdomain/i)).toBeVisible();
});
});

View File

@@ -0,0 +1,149 @@
import { TEST_ORGANIZATION_SLUG, TEST_PROJECT_SUBDOMAIN } from '@/e2e/env';
import {
clickPermissionButton,
navigateToProject,
prepareTable,
} from '@/e2e/utils';
import { faker } from '@faker-js/faker';
import type { Page } from '@playwright/test';
import { expect, test } from '@playwright/test';
import { snakeCase } from 'snake-case';
let page: Page;
test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
});
test.beforeEach(async () => {
await page.goto('/');
await navigateToProject({
page,
orgSlug: TEST_ORGANIZATION_SLUG,
projectSubdomain: TEST_PROJECT_SUBDOMAIN,
});
const databaseRoute = `/orgs/${TEST_ORGANIZATION_SLUG}/projects/${TEST_PROJECT_SUBDOMAIN}/database/browser/default`;
await page.goto(databaseRoute);
await page.waitForURL(databaseRoute);
});
test.afterAll(async () => {
await page.close();
});
test('should create a table with role permissions to select row', async () => {
await page.getByRole('button', { name: /new table/i }).click();
await expect(page.getByText(/create a new table/i)).toBeVisible();
const tableName = snakeCase(faker.lorem.words(3));
await prepareTable({
page,
name: tableName,
primaryKey: 'id',
columns: [
{ name: 'id', type: 'uuid', defaultValue: 'gen_random_uuid()' },
{ name: 'title', type: 'text' },
],
});
// create table
await page.getByRole('button', { name: /create/i }).click();
await page.waitForURL(
`/orgs/${TEST_ORGANIZATION_SLUG}/projects/${TEST_PROJECT_SUBDOMAIN}/database/browser/default/public/${tableName}`,
);
await expect(
page.getByRole('link', { name: tableName, exact: true }),
).toBeVisible();
// Press three horizontal dots more options button next to the table name
await page
.locator(`li:has-text("${tableName}") #table-management-menu button`)
.click();
await page.getByRole('menuitem', { name: /edit permissions/i }).click();
await clickPermissionButton({ page, role: 'user', permission: 'Select' });
await page.getByLabel('Without any checks').click();
await page.getByRole('button', { name: /select all/i }).click();
await page.getByRole('button', { name: /save/i }).click();
await expect(
page.getByText(/permission has been saved successfully/i),
).toBeVisible();
});
test('should create a table with role permissions and a custom check to select rows', async () => {
await page.getByRole('button', { name: /new table/i }).click();
await expect(page.getByText(/create a new table/i)).toBeVisible();
const tableName = snakeCase(faker.lorem.words(3));
await prepareTable({
page,
name: tableName,
primaryKey: 'id',
columns: [
{ name: 'id', type: 'uuid', defaultValue: 'gen_random_uuid()' },
{ name: 'title', type: 'text' },
],
});
// create table
await page.getByRole('button', { name: /create/i }).click();
await page.waitForURL(
`/orgs/${TEST_ORGANIZATION_SLUG}/projects/${TEST_PROJECT_SUBDOMAIN}/database/browser/default/public/${tableName}`,
);
await expect(
page.getByRole('link', { name: tableName, exact: true }),
).toBeVisible();
// Press three horizontal dots more options button next to the table name
await page
.locator(`li:has-text("${tableName}") #table-management-menu button`)
.click();
await page.getByRole('menuitem', { name: /edit permissions/i }).click();
await clickPermissionButton({ page, role: 'user', permission: 'Select' });
await page.getByLabel('With custom check').click();
// await page.getByRole('combobox', { name: /select a column/i }).click();
await page.getByText('Select a column', { exact: true }).click();
const columnSelector = page.locator('input[role="combobox"]');
await columnSelector.fill('id');
await columnSelector.press('Enter');
await expect(page.getByText(/_eq/i)).toBeVisible();
// limit on number of rows fetched per request.
await page.locator('#limit').fill('100');
await page.getByText('Select variable...', { exact: true }).click();
const variableSelector = await page.locator('input[role="combobox"]');
await variableSelector.fill('X-Hasura-User-Id');
await variableSelector.press('Enter');
await page.getByRole('button', { name: /select all/i }).click();
await page.getByRole('button', { name: /save/i }).click();
await expect(
page.getByText(/permission has been saved successfully/i),
).toBeVisible();
});

View File

@@ -0,0 +1,61 @@
import {
TEST_DASHBOARD_URL,
TEST_ORGANIZATION_SLUG,
TEST_PROJECT_SUBDOMAIN,
} from '@/e2e/env';
import { navigateToProject } from '@/e2e/utils';
import { type Page, expect, test as teardown } from '@playwright/test';
let page: Page;
teardown.beforeAll(async ({ browser }) => {
const context = await browser.newContext({
baseURL: TEST_DASHBOARD_URL,
storageState: 'e2e/.auth/user.json',
});
page = await context.newPage();
});
teardown.beforeEach(async () => {
await page.goto('/');
await navigateToProject({
page,
orgSlug: TEST_ORGANIZATION_SLUG,
projectSubdomain: TEST_PROJECT_SUBDOMAIN,
});
const databaseRoute = `/orgs/${TEST_ORGANIZATION_SLUG}/projects/${TEST_PROJECT_SUBDOMAIN}/database/browser/default`;
await page.goto(databaseRoute);
await page.waitForURL(databaseRoute);
});
teardown.afterAll(async () => {
await page.close();
});
teardown('clean up database tables', async () => {
await page.getByRole('link', { name: /sql editor/i }).click();
await page.waitForURL(
`/orgs/${TEST_ORGANIZATION_SLUG}/projects/${TEST_PROJECT_SUBDOMAIN}/database/browser/default/editor`,
);
const inputField = page.locator('[contenteditable]');
await inputField.fill(`
DO $$ DECLARE
tablename text;
BEGIN
FOR tablename IN
SELECT table_name FROM information_schema.tables
WHERE table_schema = 'public'
LOOP
EXECUTE 'DROP TABLE IF EXISTS public.' || quote_ident(tablename) || ' CASCADE';
END LOOP;
END $$;
`);
await page.locator('button[type="button"]', { hasText: /run/i }).click();
await expect(page.getByText(/success/i)).toBeVisible();
});

View File

@@ -191,3 +191,23 @@ export function generateTestEmail(prefix: string = 'Nhost_Test_') {
return [prefix, email].join('');
}
export async function clickPermissionButton({
page,
role,
permission,
}: {
page: Page;
role: string;
permission: 'Insert' | 'Select' | 'Update' | 'Delete';
}) {
const permissionIndex =
['Insert', 'Select', 'Update', 'Delete'].indexOf(permission) + 1;
await page
.locator('tr', { hasText: role })
.locator('td')
.nth(permissionIndex)
.locator('button')
.click();
}

View File

@@ -1,67 +0,0 @@
import {
TEST_DASHBOARD_URL,
TEST_ORGANIZATION_SLUG,
TEST_PROJECT_ADMIN_SECRET,
TEST_PROJECT_SUBDOMAIN,
} from '@/e2e/env';
import { navigateToProject } from '@/e2e/utils';
import { chromium } from '@playwright/test';
async function globalTeardown() {
const browser = await chromium.launch({ slowMo: 1000 });
const context = await browser.newContext({
baseURL: TEST_DASHBOARD_URL,
storageState: 'e2e/.auth/user.json',
});
const page = await context.newPage();
await navigateToProject({
page,
orgSlug: TEST_ORGANIZATION_SLUG,
projectSubdomain: TEST_PROJECT_SUBDOMAIN,
});
const pagePromise = context.waitForEvent('page');
await page.getByRole('link', { name: /hasura/i }).click();
await page.getByRole('link', { name: /open hasura/i }).click();
const hasuraPage = await pagePromise;
await hasuraPage.waitForLoadState();
const adminSecretInput = hasuraPage.getByPlaceholder(/enter admin-secret/i);
// note: a more ideal way would be to paste from clipboard, but Playwright
// doesn't support that yet
await adminSecretInput.fill(TEST_PROJECT_ADMIN_SECRET);
await adminSecretInput.press('Enter');
// note: getByRole doesn't work here
await hasuraPage.locator('a', { hasText: /data/i }).nth(0).click();
await hasuraPage.locator('[data-test="sql-link"]').click();
// Set the value of the Ace code editor using JavaScript evaluation in the browser context
await hasuraPage.evaluate(() => {
const editor = ace.edit('raw_sql');
editor.setValue(`
DO $$ DECLARE
tablename text;
BEGIN
FOR tablename IN
SELECT table_name FROM information_schema.tables
WHERE table_schema = 'public'
LOOP
EXECUTE 'DROP TABLE IF EXISTS public.' || quote_ident(tablename) || ' CASCADE';
END LOOP;
END $$;
`);
});
await hasuraPage.getByRole('button', { name: /run!/i }).click();
await hasuraPage.getByText(/sql executed!/i).waitFor();
}
export default globalTeardown;

View File

@@ -1,5 +1,5 @@
schema:
- https://local.graphql.nhost.run/v1:
- https://local.graphql.local.nhost.run/v1:
headers:
x-hasura-admin-secret: nhost-admin-secret
generates:

View File

@@ -7,7 +7,7 @@ const { version } = require('./package.json');
const cspHeader = `
default-src 'self' *.nhost.run ws://*.nhost.run nhost.run ws://nhost.run;
script-src 'self' 'unsafe-eval' 'unsafe-inline' cdn.segment.com js.stripe.com;
connect-src 'self' *.nhost.run ws://*.nhost.run nhost.run ws://nhost.run discord.com;
connect-src 'self' *.nhost.run ws://*.nhost.run nhost.run ws://nhost.run discord.com api.segment.io api.segment.com cdn.segment.com;
style-src 'self' 'unsafe-inline';
img-src 'self' blob: data: avatars.githubusercontent.com s.gravatar.com *.nhost.run nhost.run;
font-src 'self' data:;
@@ -16,6 +16,8 @@ const cspHeader = `
form-action 'self';
frame-ancestors 'none';
frame-src 'self' js.stripe.com;
block-all-mixed-content;
upgrade-insecure-requests;
`;
module.exports = withBundleAnalyzer({
@@ -36,9 +38,13 @@ module.exports = withBundleAnalyzer({
{
source: '/(.*)',
headers: [
{
key: 'Content-Security-Policy',
value: cspHeader.replace(/\s+/g, ' ').trim(),
},
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN',
value: 'DENY',
},
],
},

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/dashboard",
"version": "2.18.0",
"version": "2.22.0",
"private": true,
"scripts": {
"preinstall": "npx only-allow pnpm",
@@ -16,13 +16,15 @@
"storybook": "start-storybook -p 6006 -s public",
"build-storybook": "build-storybook",
"install-browsers": "pnpm playwright install && pnpm playwright install-deps",
"e2e": "pnpm install-browsers && pnpm playwright test"
"e2e": "pnpm install-browsers && pnpm playwright test --config=playwright.config.ts",
"e2e-local": "pnpm install-browsers && pnpm playwright test --config=playwright.local.config.ts"
},
"dependencies": {
"@apollo/client": "^3.9.9",
"@codemirror/lang-sql": "^6.6.2",
"@codemirror/language": "^6.10.1",
"@codemirror/legacy-modes": "^6.4.0",
"@date-fns/tz": "^1.2.0",
"@emotion/cache": "^11.11.0",
"@emotion/react": "^11.11.4",
"@emotion/server": "^11.11.0",
@@ -55,24 +57,25 @@
"@radix-ui/react-select": "^2.1.2",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.3",
"@radix-ui/react-tooltip": "^1.1.2",
"@segment/snippet": "^4.16.2",
"@segment/analytics-next": "^1.77.0",
"@stripe/react-stripe-js": "^2.6.2",
"@stripe/stripe-js": "^1.54.2",
"@tailwindcss/forms": "^0.5.7",
"@tanstack/react-query": "^4.36.1",
"@tanstack/react-table": "^8.15.3",
"@tanstack/react-virtual": "^3.2.0",
"@tanstack/react-virtual": "^3.5.0",
"@uidotdev/usehooks": "^2.4.1",
"@uiw/codemirror-theme-bbedit": "^4.22.2",
"@uiw/codemirror-theme-github": "^4.21.25",
"@uiw/react-codemirror": "^4.21.25",
"analytics-node": "^6.2.0",
"bcryptjs": "^2.4.3",
"class-variance-authority": "^0.7.0",
"clsx": "^1.2.1",
"cmdk": "1.0.0",
"date-fns": "^2.30.0",
"date-fns-v4": "npm:date-fns@4.1.0",
"dequal": "^2.0.3",
"framer-motion": "^10.18.0",
"generate-password": "^1.7.1",
@@ -93,6 +96,7 @@
"react": "18.2.0",
"react-children-utilities": "^2.10.0",
"react-complex-tree": "^2.4.5",
"react-day-picker": "8.10.1",
"react-dom": "18.2.0",
"react-error-boundary": "^4.0.13",
"react-hook-form": "^7.53.0",
@@ -113,6 +117,7 @@
"stripe": "^10.17.0",
"tailwind-merge": "^1.14.0",
"tailwindcss-animate": "^1.0.7",
"timezones-list": "^3.1.0",
"utility-types": "^3.11.0",
"uuid": "^9.0.1",
"validator": "^13.11.0",

View File

@@ -15,7 +15,6 @@ export default defineConfig({
retries: process.env.CI ? 2 : 0,
workers: 1,
reporter: 'html',
globalTeardown: require.resolve('./global-teardown'),
use: {
actionTimeout: 0,
trace: 'on-first-retry',
@@ -28,6 +27,11 @@ export default defineConfig({
{
name: 'setup',
testMatch: ['**/setup/*.setup.ts'],
teardown: 'teardown',
},
{
name: 'teardown',
testMatch: ['**/teardown/*.teardown.ts'],
},
{
name: 'chromium',
@@ -36,6 +40,7 @@ export default defineConfig({
storageState: 'e2e/.auth/user.json',
},
dependencies: ['setup'],
grepInvert: [/Local Dashboard CLI e2e tests/],
},
],
});

View File

@@ -0,0 +1,31 @@
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './e2e',
timeout: 30 * 1000,
expect: {
timeout: 5000,
},
fullyParallel: false,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: 1,
reporter: 'html',
use: {
actionTimeout: 0,
trace: 'on-first-retry',
baseURL: '', // Local dashboard URL
launchOptions: {
slowMo: 500,
},
},
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
},
testMatch: ['**/e2e/cli-local-dashboard/**'],
},
],
});

View File

@@ -0,0 +1,30 @@
import { useCurrentOrg } from '@/features/orgs/projects/hooks/useCurrentOrg';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { analytics } from '@/lib/segment';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
export default function Analytics() {
const router = useRouter();
const { org } = useCurrentOrg();
const { project } = useProject();
useEffect(() => {
const customProperties = {
organizationSlug: org?.slug || '',
projectSubdomain: project?.subdomain || '',
};
analytics.page(customProperties);
const handleRouteChange = () => analytics.page(customProperties);
router.events.on('routeChangeComplete', handleRouteChange);
return () => {
router.events.off('routeChangeComplete', handleRouteChange);
};
}, [router.events, org?.slug, project?.subdomain]);
return null;
}

View File

@@ -0,0 +1,164 @@
'use client';
import { TimePicker } from '@/components/common/TimePicker';
import { Button } from '@/components/ui/v3/button';
import { Calendar } from '@/components/ui/v3/calendar';
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/components/ui/v3/popover';
import { cn } from '@/lib/utils';
import { guessTimezone } from '@/utils/timezoneUtils';
import { TZDate } from '@date-fns/tz';
import { add, format, parseISO } from 'date-fns-v4';
import { Calendar as CalendarIcon } from 'lucide-react';
import { useState } from 'react';
import TimezoneSettings from './TimezoneSettings';
export interface DateTimePickerProps {
dateTime: string;
onDateTimeChange: (newDate: string) => void;
withTimezone?: boolean;
defaultTimezone?: string;
formatDateFn?: (date: Date | string) => string;
isCalendarDayDisabled?: (date: Date) => boolean;
align?: 'start' | 'center' | 'end';
validateDateFn?: (date: Date) => string;
}
// in: UTC datetime
// out: UTC dateTime
function DateTimePicker({
dateTime,
withTimezone = false,
defaultTimezone,
formatDateFn,
onDateTimeChange,
isCalendarDayDisabled,
align = 'start',
validateDateFn,
}: DateTimePickerProps) {
const [date, setDate] = useState(() => {
if (withTimezone) {
const tz = defaultTimezone || guessTimezone();
return new TZDate(dateTime, tz);
}
return parseISO(dateTime);
});
const [open, setOpen] = useState(false);
function emitNewDateTime() {
onDateTimeChange(new Date(date.getTime()).toISOString());
}
/**
* carry over the current time when a user clicks a new day
* instead of resetting to 00:00
*/
function handleSelect(newDay: Date | undefined) {
if (!newDay) {
return;
}
if (!date) {
setDate(newDay);
return;
}
const diff = newDay.getTime() - date.getTime();
const diffInDays = diff / (1000 * 60 * 60 * 24);
const newDateFull = add(date, { days: Math.ceil(diffInDays) });
setDate(newDateFull);
}
function handleTimezoneChange(newTimezone: string) {
const newDateWithTimezone = new TZDate(date.toISOString(), newTimezone);
setDate(newDateWithTimezone);
}
function handleOpenChange(newOpenState: boolean) {
if (!newOpenState) {
if (withTimezone) {
const tz = defaultTimezone || guessTimezone();
setDate(new TZDate(dateTime, tz));
}
setDate(parseISO(dateTime));
}
setOpen(newOpenState);
}
function onSelect() {
emitNewDateTime();
setOpen(false);
}
const dateString = formatDateFn?.(date) || format(date, 'PPP HH:mm:ss');
const errorText = validateDateFn?.(date);
const hasError = !!errorText;
return (
<Popover open={open} onOpenChange={handleOpenChange}>
<PopoverTrigger asChild>
<Button
variant="outline"
className={cn(
'w-full justify-between text-left font-normal',
!date && 'text-muted-foreground',
{ 'border-destructive': hasError },
)}
onClick={() => setOpen(true)}
>
{date ? dateString : <span>Pick a date</span>}
<CalendarIcon className="h-4 w-4" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align={align}>
<div className="flex">
<div className="flex">
<Calendar
mode="single"
selected={date}
onSelect={(d) => handleSelect(d)}
initialFocus
disabled={isCalendarDayDisabled}
/>
<div className="flex flex-col justify-between">
<div>
<div className="border-t border-border p-3">
<TimePicker setDate={setDate} date={date} />
</div>
{withTimezone && (
<div className="border-t border-border p-3">
<TimezoneSettings
dateTime={dateTime}
onTimezoneChange={handleTimezoneChange}
/>
</div>
)}
</div>
<div className="flex flex-row justify-between gap-5 p-3">
<Button
className="w-full"
onClick={onSelect}
disabled={hasError}
>
Select
</Button>
</div>
</div>
</div>
</div>
<div
className={cn('p-3 text-center text-[11px] text-destructive', {
invisible: !hasError,
})}
>
{errorText}
</div>
</PopoverContent>
</Popover>
);
}
export default DateTimePicker;

View File

@@ -0,0 +1,39 @@
import { TimezonePicker } from '@/components/common/TimezonePicker';
import { Button } from '@/components/ui/v3/button';
import { getUTCOffsetInHours, guessTimezone } from '@/utils/timezoneUtils';
import { Settings2 } from 'lucide-react';
import { useState } from 'react';
interface Props {
dateTime: string;
onTimezoneChange: (timezone: string) => void;
}
function TimezoneSettings({ dateTime, onTimezoneChange }: Props) {
const [selectedTimezone, setTimezone] = useState<string>(() =>
guessTimezone(),
);
function handleTimezoneSelect(tz: { value: string; label: string }) {
setTimezone(tz.value);
onTimezoneChange?.(tz.value);
}
const utcOffset = getUTCOffsetInHours(selectedTimezone, dateTime, 'OOOO');
return (
<div className="flex w-full items-center justify-between">
Timezone: {utcOffset}{' '}
<TimezonePicker
dateTime={dateTime}
selectedTimezone={selectedTimezone}
onTimezoneSelect={handleTimezoneSelect}
button={
<Button variant="ghost" size="icon">
<Settings2 className="h-4 w-4 dark:text-foreground" />
</Button>
}
/>
</div>
);
}
export default TimezoneSettings;

View File

@@ -0,0 +1 @@
export { default as DateTimePicker } from './DateTimePicker';

View File

@@ -0,0 +1,40 @@
import { useDialog } from '@/components/common/DialogProvider';
import { Button } from '@/components/ui/v2/Button';
import { Text } from '@/components/ui/v2/Text';
import { useIsCurrentUserOwner } from '@/features/orgs/projects/common/hooks/useIsCurrentUserOwner';
interface Props {
buttonText?: string;
onClick?: () => void;
}
function OpenTransferDialogButton({ buttonText, onClick }: Props) {
const text = buttonText ?? 'Transfer Project';
const isOwner = useIsCurrentUserOwner();
const { openAlertDialog } = useDialog();
const handleClick = () => {
if (isOwner) {
onClick();
} else {
openAlertDialog({
title: "You can't migrate this project",
payload: (
<Text variant="subtitle1" component="span">
Ask an owner of this organization to migrate the project.
</Text>
),
props: {
secondaryButtonText: 'I understand',
hidePrimaryAction: true,
},
});
}
};
return (
<Button className="max-w-xs lg:w-auto" onClick={handleClick}>
{text}
</Button>
);
}
export default OpenTransferDialogButton;

View File

@@ -0,0 +1 @@
export { default as OpenTransferDialogButton } from './OpenTransferDialogButton';

View File

@@ -0,0 +1,105 @@
import { render, screen } from '@/tests/orgs/testUtils';
import { guessTimezone } from '@/utils/timezoneUtils';
import { TZDate } from '@date-fns/tz';
import userEvent from '@testing-library/user-event';
import { parseISO } from 'date-fns';
import { format } from 'date-fns-v4';
import { useState } from 'react';
import TimePicker from './TimePicker';
function TestComponent({
dateTime,
withTimezone,
}: {
dateTime: string;
withTimezone?: boolean;
}) {
const [date, setDate] = useState(() => {
if (withTimezone) {
const tz = guessTimezone();
return new TZDate(dateTime, tz);
}
return parseISO(dateTime);
});
return (
<>
<h1>Time: {format(date, 'HH:mm:ss')}</h1>
<h1>Date class: {date instanceof TZDate ? 'TZDate' : 'Date'}</h1>
<TimePicker date={date} setDate={setDate} />
</>
);
}
describe('TimePicker', () => {
test('Updates only the hour of the date object', async () => {
render(<TestComponent dateTime="2025-03-10T03:00:05" />);
expect(await screen.getByText(/Time:/i)).toHaveTextContent(
'Time: 03:00:05',
);
const user = userEvent.setup();
const hoursInput = await screen.getByLabelText('Hours');
await user.type(hoursInput, '18');
expect(await screen.getByText(/Time:/i)).toHaveTextContent(
'Time: 18:00:05',
);
});
test('only valid hours(0-23), minutes(0-59) and seconds(0-59) are allowed', async () => {
render(<TestComponent dateTime="2025-03-10T03:00:05" />);
const user = userEvent.setup();
const hoursInput = await screen.getByLabelText('Hours');
await user.type(hoursInput, '30');
expect(await screen.getByText(/Time:/i)).toHaveTextContent(
'Time: 23:00:05',
);
const minutesInput = await screen.getByLabelText('Minutes');
await user.type(minutesInput, '66');
expect(await screen.getByText(/Time:/i)).toHaveTextContent(
'Time: 23:59:05',
);
});
test('Updates only the minutes of the date object', async () => {
render(<TestComponent dateTime="2025-03-10T03:00:05" />);
const user = userEvent.setup();
const minutesInput = await screen.getByLabelText('Minutes');
await user.type(minutesInput, '44');
expect(await screen.getByText(/Time:/i)).toHaveTextContent(
'Time: 03:44:05',
);
});
test('Updates only the seconds of the date object', async () => {
render(<TestComponent dateTime="2025-03-10T03:00:05" />);
const user = userEvent.setup();
const secondsInput = await screen.getByLabelText('Seconds');
await user.type(secondsInput, '11');
expect(await screen.getByText(/Time:/i)).toHaveTextContent(
'Time: 03:00:11',
);
});
test("will preserve the date's class after changing the date", async () => {
render(<TestComponent dateTime="2025-03-10T03:00:05" withTimezone />);
expect(await screen.getByText(/Date class:/i)).toHaveTextContent(
'Date class: TZDate',
);
const user = userEvent.setup();
const hoursInput = await screen.getByLabelText('Hours');
await user.type(hoursInput, '18');
expect(await screen.getByText(/Date class:/i)).toHaveTextContent(
'Date class: TZDate',
);
const secondsInput = await screen.getByLabelText('Seconds');
await user.type(secondsInput, '11');
expect(await screen.getByText(/Date class:/i)).toHaveTextContent(
'Date class: TZDate',
);
const minutesInput = await screen.getByLabelText('Minutes');
await user.type(minutesInput, '44');
expect(await screen.getByText(/Date class:/i)).toHaveTextContent(
'Date class: TZDate',
);
});
});

View File

@@ -0,0 +1,64 @@
'use client';
import { Label } from '@/components/ui/v3/label';
import { Clock } from 'lucide-react';
import * as React from 'react';
import { TimePickerInput } from './TimePickerInput';
interface TimePickerProps {
date: Date | undefined;
setDate: (date: Date | undefined) => void;
}
function TimePicker({ date, setDate }: TimePickerProps) {
const minuteRef = React.useRef<HTMLInputElement>(null);
const hourRef = React.useRef<HTMLInputElement>(null);
const secondRef = React.useRef<HTMLInputElement>(null);
return (
<div className="flex items-end gap-2">
<div className="grid gap-1 text-center">
<Label htmlFor="hours" className="text-xs">
Hours
</Label>
<TimePickerInput
picker="hours"
date={date}
setDate={setDate}
ref={hourRef}
onRightFocus={() => minuteRef.current?.focus()}
/>
</div>
<div className="grid gap-1 text-center">
<Label htmlFor="minutes" className="text-xs">
Minutes
</Label>
<TimePickerInput
picker="minutes"
date={date}
setDate={setDate}
ref={minuteRef}
onLeftFocus={() => hourRef.current?.focus()}
onRightFocus={() => secondRef.current?.focus()}
/>
</div>
<div className="grid gap-1 text-center">
<Label htmlFor="seconds" className="text-xs">
Seconds
</Label>
<TimePickerInput
picker="seconds"
date={date}
setDate={setDate}
ref={secondRef}
onLeftFocus={() => minuteRef.current?.focus()}
/>
</div>
<div className="flex h-10 items-center">
<Clock className="ml-2 h-4 w-4" />
</div>
</div>
);
}
export default TimePicker;

View File

@@ -0,0 +1,148 @@
import { Input } from '@/components/ui/v3/input';
import { cn } from '@/lib/utils';
import React from 'react';
import {
type Period,
type TimePickerType,
copyDate,
getArrowByType,
getDateByType,
setDateByType,
} from './time-picker-utils';
export interface TimePickerInputProps
extends React.InputHTMLAttributes<HTMLInputElement> {
picker: TimePickerType;
date: Date | undefined;
setDate: (date: Date | undefined) => void;
period?: Period;
onRightFocus?: () => void;
onLeftFocus?: () => void;
}
const TimePickerInput = React.forwardRef<
HTMLInputElement,
TimePickerInputProps
>(
(
{
className,
type = 'tel',
value,
id,
name,
date = new Date(new Date().setHours(0, 0, 0, 0)),
setDate,
onChange,
onKeyDown,
picker,
period,
onLeftFocus,
onRightFocus,
...props
},
ref,
) => {
const [flag, setFlag] = React.useState<boolean>(false);
const [prevIntKey, setPrevIntKey] = React.useState<string>('0');
/**
* allow the user to enter the second digit within 2 seconds
* otherwise start again with entering first digit
*/
// eslint-disable-next-line consistent-return
React.useEffect(() => {
if (flag) {
const timer = setTimeout(() => {
setFlag(false);
}, 2000);
return () => clearTimeout(timer);
}
}, [flag]);
const calculatedValue = React.useMemo(
() => getDateByType(date, picker),
[date, picker],
);
const calculateNewValue = (key: string) => {
/*
* If picker is '12hours' and the first digit is 0, then the second digit is automatically set to 1.
* The second entered digit will break the condition and the value will be set to 10-12.
*/
if (picker === '12hours') {
if (flag && calculatedValue.slice(1, 2) === '1' && prevIntKey === '0') {
return `0${key}`;
}
}
return !flag ? `0${key}` : calculatedValue.slice(1, 2) + key;
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Tab') {
return;
}
e.preventDefault();
if (e.key === 'ArrowRight') {
onRightFocus?.();
}
if (e.key === 'ArrowLeft') {
onLeftFocus?.();
}
if (['ArrowUp', 'ArrowDown'].includes(e.key)) {
const step = e.key === 'ArrowUp' ? 1 : -1;
const newValue = getArrowByType(calculatedValue, step, picker);
if (flag) {
setFlag(false);
}
const tempDate = copyDate(date);
setDate(setDateByType(tempDate, newValue, picker, period));
}
if (e.key >= '0' && e.key <= '9') {
if (picker === '12hours') {
setPrevIntKey(e.key);
}
const newValue = calculateNewValue(e.key);
if (flag) {
onRightFocus?.();
}
setFlag((prev) => !prev);
const tempDate = copyDate(date);
setDate(setDateByType(tempDate, newValue, picker, period));
}
};
return (
<Input
ref={ref}
id={id || picker}
name={name || picker}
className={cn(
'w-[48px] text-center font-mono text-base tabular-nums focus:bg-accent focus:text-accent-foreground [&::-webkit-inner-spin-button]:appearance-none',
className,
)}
value={value || calculatedValue}
onChange={(e) => {
e.preventDefault();
onChange?.(e);
}}
type={type}
inputMode="decimal"
onKeyDown={(e) => {
onKeyDown?.(e);
handleKeyDown(e);
}}
{...props}
/>
);
},
);
TimePickerInput.displayName = 'TimePickerInput';
export { TimePickerInput };

View File

@@ -0,0 +1 @@
export { default as TimePicker } from './TimePicker';

View File

@@ -0,0 +1,336 @@
import { vi } from 'vitest';
import {
convert12HourTo24Hour,
display12HourValue,
getArrowByType,
getDateByType,
getValid12Hour,
getValidArrow12Hour,
getValidArrowHour,
getValidArrowMinuteOrSecond,
getValidArrowNumber,
getValidHour,
getValidMinuteOrSecond,
getValidNumber,
isValid12Hour,
isValidHour,
isValidMinuteOrSecond,
set12Hours,
setDateByType,
setHours,
setMinutes,
setSeconds,
type TimePickerType,
} from './time-picker-utils';
// Mock TZDate if needed
vi.mock('@date-fns/tz', () => ({
TZDate: class MockTZDate extends Date {
timeZone: string;
constructor(date: string | Date, timeZone: string) {
super(date);
this.timeZone = timeZone;
}
},
}));
describe('time-picker-utils', () => {
describe('validation functions', () => {
test('isValidHour validates hour format correctly', () => {
// Valid hours
expect(isValidHour('00')).toBe(true);
expect(isValidHour('01')).toBe(true);
expect(isValidHour('12')).toBe(true);
expect(isValidHour('23')).toBe(true);
// Invalid hours
expect(isValidHour('24')).toBe(false);
expect(isValidHour('-1')).toBe(false);
expect(isValidHour('1')).toBe(false); // not padded
expect(isValidHour('ab')).toBe(false);
});
test('isValid12Hour validates 12-hour format correctly', () => {
// Valid 12-hour values
expect(isValid12Hour('01')).toBe(true);
expect(isValid12Hour('09')).toBe(true);
expect(isValid12Hour('12')).toBe(true);
// Invalid 12-hour values
expect(isValid12Hour('00')).toBe(false);
expect(isValid12Hour('13')).toBe(false);
expect(isValid12Hour('1')).toBe(false); // not padded
expect(isValid12Hour('ab')).toBe(false);
});
test('isValidMinuteOrSecond validates minute/second format correctly', () => {
// Valid minutes/seconds
expect(isValidMinuteOrSecond('00')).toBe(true);
expect(isValidMinuteOrSecond('01')).toBe(true);
expect(isValidMinuteOrSecond('30')).toBe(true);
expect(isValidMinuteOrSecond('59')).toBe(true);
// Invalid minutes/seconds
expect(isValidMinuteOrSecond('60')).toBe(false);
expect(isValidMinuteOrSecond('-1')).toBe(false);
expect(isValidMinuteOrSecond('1')).toBe(false); // not padded
expect(isValidMinuteOrSecond('ab')).toBe(false);
});
});
describe('number validation and correction functions', () => {
test('getValidNumber handles number validation correctly', () => {
// Basic validation
expect(getValidNumber('5', { max: 10 })).toBe('05');
expect(getValidNumber('15', { max: 10 })).toBe('10');
expect(getValidNumber('-1', { max: 10, min: 0 })).toBe('00');
// With looping
expect(getValidNumber('15', { max: 10, min: 0, loop: true })).toBe('00');
expect(getValidNumber('-1', { max: 10, min: 0, loop: true })).toBe('10');
// Invalid input
expect(getValidNumber('abc', { max: 10 })).toBe('00');
});
test('getValidHour returns valid 24-hour format', () => {
expect(getValidHour('12')).toBe('12');
expect(getValidHour('23')).toBe('23');
expect(getValidHour('24')).toBe('23'); // Capped at 23
expect(getValidHour('-1')).toBe('00'); // Min is 0
expect(getValidHour('abc')).toBe('00'); // Invalid input
});
test('getValid12Hour returns valid 12-hour format', () => {
// expect(getValid12Hour('06')).toBe('06');
// expect(getValid12Hour('12')).toBe('12');
expect(getValid12Hour('00')).toBe('01'); // Min is 1
expect(getValid12Hour('13')).toBe('12'); // Capped at 12
expect(getValid12Hour('abc')).toBe('00'); // Invalid input defaults to 00
});
test('getValidMinuteOrSecond returns valid minute/second format', () => {
expect(getValidMinuteOrSecond('30')).toBe('30');
expect(getValidMinuteOrSecond('59')).toBe('59');
expect(getValidMinuteOrSecond('60')).toBe('59'); // Capped at 59
expect(getValidMinuteOrSecond('-1')).toBe('00'); // Min is 0
expect(getValidMinuteOrSecond('abc')).toBe('00'); // Invalid input
});
});
describe('arrow navigation functions', () => {
test('getValidArrowNumber handles arrow navigation with looping', () => {
// Incrementing
expect(getValidArrowNumber('05', { min: 0, max: 10, step: 1 })).toBe(
'06',
);
expect(getValidArrowNumber('10', { min: 0, max: 10, step: 1 })).toBe(
'00',
); // Loops back to min
// Decrementing
expect(getValidArrowNumber('05', { min: 0, max: 10, step: -1 })).toBe(
'04',
);
expect(getValidArrowNumber('00', { min: 0, max: 10, step: -1 })).toBe(
'10',
); // Loops to max
// Invalid input
expect(getValidArrowNumber('abc', { min: 0, max: 10, step: 1 })).toBe(
'00',
);
});
test('getValidArrowHour handles hour navigation correctly', () => {
expect(getValidArrowHour('05', 1)).toBe('06');
expect(getValidArrowHour('23', 1)).toBe('00'); // Loops to 0
expect(getValidArrowHour('00', -1)).toBe('23'); // Loops to 23
});
test('getValidArrow12Hour handles 12-hour navigation correctly', () => {
expect(getValidArrow12Hour('05', 1)).toBe('06');
expect(getValidArrow12Hour('12', 1)).toBe('01'); // Loops to 1
expect(getValidArrow12Hour('01', -1)).toBe('12'); // Loops to 12
});
test('getValidArrowMinuteOrSecond handles minute/second navigation correctly', () => {
expect(getValidArrowMinuteOrSecond('30', 1)).toBe('31');
expect(getValidArrowMinuteOrSecond('59', 1)).toBe('00'); // Loops to 0
expect(getValidArrowMinuteOrSecond('00', -1)).toBe('59'); // Loops to 59
});
});
describe('date manipulation functions', () => {
test('setMinutes sets minutes correctly on a Date object', () => {
const date = new Date(2023, 0, 1, 12, 0, 0);
setMinutes(date, '30');
expect(date.getMinutes()).toBe(30);
// Invalid values are corrected
setMinutes(date, '60');
expect(date.getMinutes()).toBe(59);
});
test('setSeconds sets seconds correctly on a Date object', () => {
const date = new Date(2023, 0, 1, 12, 30, 0);
setSeconds(date, '45');
expect(date.getSeconds()).toBe(45);
// Invalid values are corrected
setSeconds(date, '60');
expect(date.getSeconds()).toBe(59);
});
test('setHours sets hours correctly on a Date object', () => {
const date = new Date(2023, 0, 1, 12, 30, 0);
setHours(date, '14');
expect(date.getHours()).toBe(14);
// Invalid values are corrected
setHours(date, '24');
expect(date.getHours()).toBe(23);
});
test('convert12HourTo24Hour converts 12-hour to 24-hour format correctly', () => {
// AM conversions
expect(convert12HourTo24Hour(1, 'AM')).toBe(1);
expect(convert12HourTo24Hour(11, 'AM')).toBe(11);
expect(convert12HourTo24Hour(12, 'AM')).toBe(0); // 12 AM is 00:00
// PM conversions
expect(convert12HourTo24Hour(1, 'PM')).toBe(13);
expect(convert12HourTo24Hour(11, 'PM')).toBe(23);
expect(convert12HourTo24Hour(12, 'PM')).toBe(12); // 12 PM is 12:00
});
test('set12Hours sets 12-hour format correctly on a Date object', () => {
const date = new Date(2023, 0, 1, 0, 0, 0);
// Morning hours (AM)
set12Hours(date, '09', 'AM');
expect(date.getHours()).toBe(9);
// 12 AM
set12Hours(date, '12', 'AM');
expect(date.getHours()).toBe(0);
// Afternoon/evening hours (PM)
set12Hours(date, '03', 'PM');
expect(date.getHours()).toBe(15);
// 12 PM
set12Hours(date, '12', 'PM');
expect(date.getHours()).toBe(12);
});
test('display12HourValue converts 24-hour to 12-hour display format', () => {
expect(display12HourValue(0)).toBe('12'); // 00:00 -> 12 AM
expect(display12HourValue(1)).toBe('01'); // 01:00 -> 1 AM
expect(display12HourValue(11)).toBe('11'); // 11:00 -> 11 AM
expect(display12HourValue(12)).toBe('12'); // 12:00 -> 12 PM
expect(display12HourValue(13)).toBe('01'); // 13:00 -> 1 PM
expect(display12HourValue(23)).toBe('11'); // 23:00 -> 11 PM
expect(display12HourValue(22)).toBe('10'); // 22:00 -> 10 PM
});
});
describe('integrated date manipulation functions', () => {
test('getDateByType returns date component according to the picker type', () => {
const date = new Date(2023, 0, 1, 14, 30, 45);
// Test hours
expect(getDateByType(date, 'hours')).toBe('14');
// Test minutes
expect(getDateByType(date, 'minutes')).toBe('30');
// Test seconds
expect(getDateByType(date, 'seconds')).toBe('45');
// Test 12-hour format
expect(getDateByType(date, '12hours')).toBe('02'); // 14:00 -> 2 PM
// Test 12 noon and midnight special cases
const noon = new Date(2023, 0, 1, 12, 0, 0);
expect(getDateByType(noon, '12hours')).toBe('12');
const midnight = new Date(2023, 0, 1, 0, 0, 0);
expect(getDateByType(midnight, '12hours')).toBe('12');
// Test with invalid picker type
expect(getDateByType(date, 'invalid' as TimePickerType)).toBe('00');
});
test('getArrowByType handles arrow navigation based on picker type', () => {
// Test hours
expect(getArrowByType('14', 1, 'hours')).toBe('15');
expect(getArrowByType('23', 1, 'hours')).toBe('00'); // Loops back to 00
// Test minutes
expect(getArrowByType('30', 1, 'minutes')).toBe('31');
expect(getArrowByType('59', 1, 'minutes')).toBe('00'); // Loops back to 00
// Test seconds
expect(getArrowByType('45', 1, 'seconds')).toBe('46');
expect(getArrowByType('59', 1, 'seconds')).toBe('00'); // Loops back to 00
// Test 12-hour format
expect(getArrowByType('09', 1, '12hours')).toBe('10');
expect(getArrowByType('12', 1, '12hours')).toBe('01'); // Loops back to 01
// Test with invalid picker type
expect(getArrowByType('14', 1, 'invalid' as TimePickerType)).toBe('00');
});
test('setDateByType updates date according to the picker type', () => {
const date = new Date(2023, 0, 1, 12, 30, 45);
// Test updating hours
const hourDate = setDateByType(date, '14', 'hours');
expect(hourDate.getHours()).toBe(14);
expect(hourDate.getMinutes()).toBe(30); // Other fields unchanged
expect(hourDate.getSeconds()).toBe(45); // Other fields unchanged
// Test updating minutes
const minuteDate = setDateByType(date, '15', 'minutes');
expect(minuteDate.getHours()).toBe(14); // Other fields unchanged
expect(minuteDate.getMinutes()).toBe(15);
expect(minuteDate.getSeconds()).toBe(45); // Other fields unchanged
// Test updating seconds
const secondDate = setDateByType(date, '20', 'seconds');
expect(secondDate.getHours()).toBe(14); // Other fields unchanged
expect(secondDate.getMinutes()).toBe(15); // Other fields unchanged
expect(secondDate.getSeconds()).toBe(20);
// Test updating 12-hour format with AM
const amDate = setDateByType(date, '09', '12hours', 'AM');
expect(amDate.getHours()).toBe(9);
// Test updating 12-hour format with PM
const pmDate = setDateByType(date, '09', '12hours', 'PM');
expect(pmDate.getHours()).toBe(21);
// Test 12 AM (midnight)
const midnightDate = setDateByType(date, '12', '12hours', 'AM');
expect(midnightDate.getHours()).toBe(0);
// Test 12 PM (noon)
const noonDate = setDateByType(date, '12', '12hours', 'PM');
expect(noonDate.getHours()).toBe(12);
// Test with missing period for 12-hour format
const missingPeriodDate = setDateByType(date, '09', '12hours');
expect(missingPeriodDate).toBe(date); // Should return original date unchanged
// Test with invalid picker type
const invalidTypeDate = setDateByType(
date,
'14',
'invalid' as TimePickerType,
);
expect(invalidTypeDate).toBe(date); // Should return original date unchanged
});
});
});

View File

@@ -0,0 +1,244 @@
import { TZDate } from '@date-fns/tz';
/**
* regular expression to check for valid hour format (01-23)
*/
export function isValidHour(value: string) {
return /^(0[0-9]|1[0-9]|2[0-3])$/.test(value);
}
/**
* regular expression to check for valid 12 hour format (01-12)
*/
export function isValid12Hour(value: string) {
return /^(0[1-9]|1[0-2])$/.test(value);
}
/**
* regular expression to check for valid minute format (00-59)
*/
export function isValidMinuteOrSecond(value: string) {
return /^[0-5][0-9]$/.test(value);
}
type GetValidNumberConfig = { max: number; min?: number; loop?: boolean };
export function getValidNumber(
value: string,
{ max, min = 0, loop = false }: GetValidNumberConfig,
) {
let numericValue = parseInt(value, 10);
if (!Number.isNaN(numericValue)) {
if (!loop) {
if (numericValue > max) {
numericValue = max;
}
if (numericValue < min) {
numericValue = min;
}
} else {
if (numericValue > max) {
numericValue = min;
}
if (numericValue < min) {
numericValue = max;
}
}
return numericValue.toString().padStart(2, '0');
}
return '00';
}
export function getValidHour(value: string) {
if (isValidHour(value)) {
return value;
}
return getValidNumber(value, { max: 23 });
}
export function getValid12Hour(value: string) {
if (isValid12Hour(value)) {
return value;
}
return getValidNumber(value, { min: 1, max: 12 });
}
export function getValidMinuteOrSecond(value: string) {
if (isValidMinuteOrSecond(value)) {
return value;
}
return getValidNumber(value, { max: 59 });
}
type GetValidArrowNumberConfig = {
min: number;
max: number;
step: number;
};
export function getValidArrowNumber(
value: string,
{ min, max, step }: GetValidArrowNumberConfig,
) {
let numericValue = parseInt(value, 10);
if (!Number.isNaN(numericValue)) {
numericValue += step;
return getValidNumber(String(numericValue), { min, max, loop: true });
}
return '00';
}
export function getValidArrowHour(value: string, step: number) {
return getValidArrowNumber(value, { min: 0, max: 23, step });
}
export function getValidArrow12Hour(value: string, step: number) {
return getValidArrowNumber(value, { min: 1, max: 12, step });
}
export function getValidArrowMinuteOrSecond(value: string, step: number) {
return getValidArrowNumber(value, { min: 0, max: 59, step });
}
export function setMinutes(date: Date, value: string) {
const minutes = getValidMinuteOrSecond(value);
date.setMinutes(parseInt(minutes, 10));
return date;
}
export function setSeconds(date: Date, value: string) {
const seconds = getValidMinuteOrSecond(value);
date.setSeconds(parseInt(seconds, 10));
return date;
}
export function setHours(date: Date, value: string) {
const hours = getValidHour(value);
date.setHours(parseInt(hours, 10));
return date;
}
/**
* handles value change of 12-hour input
* 12:00 PM is 12:00
* 12:00 AM is 00:00
*/
export function convert12HourTo24Hour(hour: number, period: Period) {
if (period === 'PM') {
if (hour <= 11) {
return hour + 12;
}
return hour;
}
if (period === 'AM') {
if (hour === 12) {
return 0;
}
return hour;
}
return hour;
}
export function set12Hours(date: Date, value: string, period: Period) {
const hours = parseInt(getValid12Hour(value), 10);
const convertedHours = convert12HourTo24Hour(hours, period);
date.setHours(convertedHours);
return date;
}
export type TimePickerType = 'minutes' | 'seconds' | 'hours' | '12hours';
export type Period = 'AM' | 'PM';
export function setDateByType(
date: Date,
value: string,
type: TimePickerType,
period?: Period,
) {
switch (type) {
case 'minutes':
return setMinutes(date, value);
case 'seconds':
return setSeconds(date, value);
case 'hours':
return setHours(date, value);
case '12hours': {
if (!period) {
return date;
}
return set12Hours(date, value, period);
}
default:
return date;
}
}
/**
* time is stored in the 24-hour form,
* but needs to be displayed to the user
* in its 12-hour representation
*/
export function display12HourValue(hours: number) {
if (hours === 0 || hours === 12) {
return '12';
}
if (hours >= 22) {
return `${hours - 12}`;
}
if (hours % 12 > 9) {
return `${hours}`;
}
return `0${hours % 12}`;
}
export function getDateByType(date: Date, type: TimePickerType) {
switch (type) {
case 'minutes':
return getValidMinuteOrSecond(String(date.getMinutes()));
case 'seconds':
return getValidMinuteOrSecond(String(date.getSeconds()));
case 'hours':
return getValidHour(String(date.getHours()));
case '12hours': {
const hours = display12HourValue(date.getHours());
return getValid12Hour(String(hours));
}
default:
return '00';
}
}
export function getArrowByType(
value: string,
step: number,
type: TimePickerType,
) {
switch (type) {
case 'minutes':
return getValidArrowMinuteOrSecond(value, step);
case 'seconds':
return getValidArrowMinuteOrSecond(value, step);
case 'hours':
return getValidArrowHour(value, step);
case '12hours':
return getValidArrow12Hour(value, step);
default:
return '00';
}
}
function isTZDate(date: Date | TZDate): date is TZDate {
return date instanceof TZDate;
}
export function copyDate(date: Date | TZDate) {
if (isTZDate(date)) {
const { timeZone } = date;
const dateTime = date.toISOString();
return new TZDate(dateTime, timeZone);
}
return new Date(date);
}

View File

@@ -0,0 +1,34 @@
import { VirtualizedCombobox } from '@/components/common/VirtualizedCombobox';
import { createTimezoneOptions } from '@/utils/timezoneUtils';
import { memo, useMemo } from 'react';
interface Props {
selectedTimezone: string;
onTimezoneSelect: (timezone: { value: string; label: string }) => void;
button?: React.JSX.Element;
dateTime: string;
}
function TimezonePicker({
selectedTimezone,
onTimezoneSelect,
button,
dateTime,
}: Props) {
const timezoneOptions = useMemo(
() => createTimezoneOptions(dateTime),
[dateTime],
);
return (
<VirtualizedCombobox
options={timezoneOptions}
selectedOption={selectedTimezone}
onSelectOption={onTimezoneSelect}
searchPlaceholder="Search timezones..."
button={button}
side="right"
/>
);
}
export default memo(TimezonePicker);

View File

@@ -0,0 +1 @@
export { default as TimezonePicker } from './TimezonePicker';

View File

@@ -1,14 +1,13 @@
import { useDialog } from '@/components/common/DialogProvider';
import { NhostIcon } from '@/components/presentational/NhostIcon';
import { Box } from '@/components/ui/v2/Box';
import { Button } from '@/components/ui/v2/Button';
import { ArrowSquareOutIcon } from '@/components/ui/v2/icons/ArrowSquareOutIcon';
import { Link } from '@/components/ui/v2/Link';
import { Text } from '@/components/ui/v2/Text';
import { TransferProjectDialog } from '@/features/orgs/components/common/TransferProjectDialog';
import { useIsCurrentUserOwner } from '@/features/orgs/projects/common/hooks/useIsCurrentUserOwner';
import { useState } from 'react';
import { OpenTransferDialogButton } from '@/components/common/OpenTransferDialogButton';
import Image from 'next/image';
import { type ReactNode } from 'react';
@@ -21,11 +20,11 @@ export default function UpgradeToProBanner({
title,
description,
}: UpgradeToProBannerProps) {
const isOwner = useIsCurrentUserOwner();
const { openAlertDialog } = useDialog();
const [transferProjectDialogOpen, setTransferProjectDialogOpen] =
useState(false);
const handleTransferDialogOpen = () => setTransferProjectDialogOpen(true);
return (
<Box
sx={{ backgroundColor: 'primary.light' }}
@@ -51,29 +50,7 @@ export default function UpgradeToProBanner({
</div>
<div className="flex flex-col gap-2 space-y-2 lg:flex-row lg:items-center lg:space-x-2 lg:space-y-0">
<Button
className="max-w-xs lg:w-auto"
onClick={() => {
if (isOwner) {
setTransferProjectDialogOpen(true);
} else {
openAlertDialog({
title: "You can't migrate this project",
payload: (
<Text variant="subtitle1" component="span">
Ask an owner of this organization to migrate the project.
</Text>
),
props: {
secondaryButtonText: 'I understand',
hidePrimaryAction: true,
},
});
}
}}
>
Transfer Project
</Button>
<OpenTransferDialogButton onClick={handleTransferDialogOpen} />
<TransferProjectDialog
open={transferProjectDialogOpen}
setOpen={setTransferProjectDialogOpen}

View File

@@ -0,0 +1,252 @@
import { Button } from '@/components/ui/v3/button';
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from '@/components/ui/v3/command';
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/components/ui/v3/popover';
import { cn } from '@/lib/utils';
import { useVirtualizer } from '@tanstack/react-virtual';
import { Check, ChevronsUpDown } from 'lucide-react';
import * as React from 'react';
type Option = {
value: string;
label: string;
key?: string;
};
interface VirtualizedCommandProps<O extends Option> {
height: string;
options: O[];
placeholder: string;
selectedOption: string;
onSelectOption?: (option: O) => void;
emptyText?: string;
}
function VirtualizedCommand<O extends Option>({
height,
options,
placeholder,
selectedOption,
onSelectOption,
emptyText,
}: VirtualizedCommandProps<O>) {
const [filteredOptions, setFilteredOptions] = React.useState<O[]>(options);
const [focusedIndex, setFocusedIndex] = React.useState(0);
const [isKeyboardNavActive, setIsKeyboardNavActive] = React.useState(false);
const parentRef = React.useRef(null);
const virtualizer = useVirtualizer({
count: filteredOptions.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 35,
});
const virtualOptions = virtualizer.getVirtualItems();
const scrollToIndex = (index: number) => {
virtualizer.scrollToIndex(index, {
align: 'center',
});
};
const handleSearch = (search: string) => {
setIsKeyboardNavActive(false);
setFilteredOptions(
options.filter((option) =>
option.label.toLowerCase().includes(search.toLowerCase()),
),
);
};
const handleKeyDown = (event: React.KeyboardEvent) => {
switch (event.key) {
case 'ArrowDown': {
event.preventDefault();
setIsKeyboardNavActive(true);
setFocusedIndex((prev) => {
const newIndex =
prev === -1 ? 0 : Math.min(prev + 1, filteredOptions.length - 1);
scrollToIndex(newIndex);
return newIndex;
});
break;
}
case 'ArrowUp': {
event.preventDefault();
setIsKeyboardNavActive(true);
setFocusedIndex((prev) => {
const newIndex =
prev === -1 ? filteredOptions.length - 1 : Math.max(prev - 1, 0);
scrollToIndex(newIndex);
return newIndex;
});
break;
}
case 'Enter': {
event.preventDefault();
if (filteredOptions[focusedIndex]) {
onSelectOption?.(filteredOptions[focusedIndex]);
}
break;
}
default:
break;
}
};
React.useEffect(() => {
if (selectedOption) {
const option = filteredOptions.find(
(opt) => opt.value === selectedOption,
);
if (option) {
const index = filteredOptions.indexOf(option);
setFocusedIndex(index);
}
}
}, [selectedOption, filteredOptions, virtualizer]);
return (
<Command shouldFilter={false} onKeyDown={handleKeyDown}>
<CommandInput onValueChange={handleSearch} placeholder={placeholder} />
<CommandList
ref={parentRef}
style={{
height,
width: '100%',
overflow: 'auto',
}}
onMouseDown={() => setIsKeyboardNavActive(false)}
onMouseMove={() => setIsKeyboardNavActive(false)}
>
<CommandEmpty>{emptyText || 'No item found.'}</CommandEmpty>
<CommandGroup>
<div
style={{
height: `${virtualizer.getTotalSize()}px`,
width: '100%',
position: 'relative',
}}
>
{virtualOptions.map((virtualOption) => (
<CommandItem
key={
filteredOptions[virtualOption.index].key ??
filteredOptions[virtualOption.index].value
}
disabled={isKeyboardNavActive}
className={cn(
'absolute left-0 top-0 w-full bg-transparent',
focusedIndex === virtualOption.index &&
'bg-accent text-accent-foreground',
isKeyboardNavActive &&
focusedIndex !== virtualOption.index &&
'aria-selected:bg-transparent aria-selected:text-primary',
)}
style={{
height: `${virtualOption.size}px`,
transform: `translateY(${virtualOption.start}px)`,
}}
value={filteredOptions[virtualOption.index].value}
onMouseEnter={() =>
!isKeyboardNavActive && setFocusedIndex(virtualOption.index)
}
onMouseLeave={() => !isKeyboardNavActive && setFocusedIndex(-1)}
onSelect={() => onSelectOption?.(filteredOptions[focusedIndex])}
>
<Check
className={cn(
'mr-2 h-4 w-4',
selectedOption ===
filteredOptions[virtualOption.index].value
? 'opacity-100'
: 'opacity-0',
)}
/>
{filteredOptions[virtualOption.index].label}
</CommandItem>
))}
</div>
</CommandGroup>
</CommandList>
</Command>
);
}
interface VirtualizedComboboxProps<O extends Option> {
options: O[];
searchPlaceholder?: string;
width?: string;
height?: string;
button?: React.JSX.Element;
onSelectOption?: (option: O) => void;
selectedOption: string;
align?: 'start' | 'center' | 'end';
side?: 'right' | 'top' | 'bottom' | 'left';
}
function VirtualizedCombobox<O extends Option>({
options,
searchPlaceholder = 'Search items...',
width,
height,
button,
onSelectOption,
selectedOption,
align = 'start',
side,
}: VirtualizedComboboxProps<O>) {
const [open, setOpen] = React.useState(false);
const defaultButton = (
<Button
variant="outline"
role="combobox"
aria-expanded={open}
className="justify-between"
style={{
width,
}}
>
{selectedOption
? options.find((option) => option.value === selectedOption).value
: searchPlaceholder}
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
);
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>{button || defaultButton}</PopoverTrigger>
<PopoverContent
className="p-0"
style={{ width }}
align={align}
side={side}
>
<VirtualizedCommand
height={height}
options={options}
placeholder={searchPlaceholder}
selectedOption={selectedOption}
onSelectOption={(currentValue) => {
onSelectOption(currentValue);
setOpen(false);
}}
/>
</PopoverContent>
</Popover>
);
}
export default VirtualizedCombobox;

View File

@@ -0,0 +1 @@
export { default as VirtualizedCombobox } from './VirtualizedCombobox';

View File

@@ -18,6 +18,7 @@ import {
PopoverTrigger,
} from '@/components/ui/v3/popover';
import { useIsPlatform } from '@/features/orgs/projects/common/hooks/useIsPlatform';
import { Check, ChevronsUpDown } from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';
@@ -40,6 +41,8 @@ export default function OrgPagesComboBox() {
asPath,
} = useRouter();
const isPlatform = useIsPlatform();
const pathSegments = useMemo(() => asPath.split('/'), [asPath]);
const orgPageFromUrl = pathSegments[3] || null;
@@ -64,7 +67,7 @@ export default function OrgPagesComboBox() {
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<PopoverTrigger disabled={!isPlatform} asChild>
<Button
variant="ghost"
size="sm"

View File

@@ -32,6 +32,7 @@ import {
PopoverContent,
PopoverTrigger,
} from '@/components/ui/v3/popover';
import { useIsPlatform } from '@/features/orgs/projects/common/hooks/useIsPlatform';
import { cn } from '@/lib/utils';
import { useRouter } from 'next/router';
import { useEffect, useMemo, useState, type ReactElement } from 'react';
@@ -40,88 +41,10 @@ type Option = {
value: string;
label: string;
icon: ReactElement;
disabled: boolean;
};
const projectPages = [
{
label: 'Overview',
value: 'overview',
icon: <HomeIcon className="h-4 w-4" />,
slug: '',
},
{
label: 'Database',
value: 'database',
icon: <DatabaseIcon className="h-4 w-4" />,
slug: '/database/browser/default',
},
{
label: 'GraphQL',
value: 'graphql',
icon: <GraphQLIcon className="h-4 w-4" />,
slug: 'graphql',
},
{
label: 'Hasura',
value: 'hasura',
icon: <HasuraIcon className="h-4 w-4" />,
slug: 'hasura',
},
{
label: 'Auth',
value: 'users',
icon: <UserIcon className="h-4 w-4" />,
slug: 'users',
},
{
label: 'Storage',
value: 'storage',
icon: <StorageIcon className="h-4 w-4" />,
slug: 'storage',
},
{
label: 'Run',
value: 'run',
icon: <ServicesIcon className="h-4 w-4" />,
slug: 'run',
},
{
label: 'AI',
value: 'ai',
icon: <AIIcon className="h-4 w-4" />,
slug: 'ai/auto-embeddings',
},
{
label: 'Deployments',
value: 'deployments',
icon: <RocketIcon className="h-4 w-4" />,
slug: 'deployments',
},
{
label: 'Backups',
value: 'backups',
icon: <CloudIcon className="h-4 w-4" />,
slug: 'backups',
},
{
label: 'Logs',
value: 'logs',
icon: <FileTextIcon className="h-4 w-4" />,
slug: 'logs',
},
{
label: 'Metrics',
value: 'metrics',
icon: <GaugeIcon className="h-4 w-4" />,
slug: 'metrics',
},
{
label: 'Settings',
value: 'settings',
icon: <CogIcon className="h-4 w-4" />,
slug: 'settings',
},
];
type SelectedOption = Omit<Option, 'disabled'>;
export default function ProjectPagesComboBox() {
const {
@@ -130,6 +53,105 @@ export default function ProjectPagesComboBox() {
asPath,
} = useRouter();
const isPlatform = useIsPlatform();
const projectPages = useMemo(
() => [
{
label: 'Overview',
value: 'overview',
icon: <HomeIcon className="h-4 w-4" />,
slug: '',
disabled: false,
},
{
label: 'Database',
value: 'database',
icon: <DatabaseIcon className="h-4 w-4" />,
slug: '/database/browser/default',
disabled: false,
},
{
label: 'GraphQL',
value: 'graphql',
icon: <GraphQLIcon className="h-4 w-4" />,
slug: 'graphql',
disabled: false,
},
{
label: 'Hasura',
value: 'hasura',
icon: <HasuraIcon className="h-4 w-4" />,
slug: 'hasura',
disabled: false,
},
{
label: 'Auth',
value: 'users',
icon: <UserIcon className="h-4 w-4" />,
slug: 'users',
disabled: false,
},
{
label: 'Storage',
value: 'storage',
icon: <StorageIcon className="h-4 w-4" />,
slug: 'storage',
disabled: false,
},
{
label: 'Run',
value: 'run',
icon: <ServicesIcon className="h-4 w-4" />,
slug: 'run',
disabled: false,
},
{
label: 'AI',
value: 'ai',
icon: <AIIcon className="h-4 w-4" />,
slug: 'ai/auto-embeddings',
disabled: false,
},
{
label: 'Deployments',
value: 'deployments',
icon: <RocketIcon className="h-4 w-4" />,
slug: 'deployments',
disabled: !isPlatform,
},
{
label: 'Backups',
value: 'backups',
icon: <CloudIcon className="h-4 w-4" />,
slug: 'backups',
disabled: !isPlatform,
},
{
label: 'Logs',
value: 'logs',
icon: <FileTextIcon className="h-4 w-4" />,
slug: 'logs',
disabled: !isPlatform,
},
{
label: 'Metrics',
value: 'metrics',
icon: <GaugeIcon className="h-4 w-4" />,
slug: 'metrics',
disabled: !isPlatform,
},
{
label: 'Settings',
value: 'settings',
icon: <CogIcon className="h-4 w-4" />,
slug: 'settings',
disabled: false,
},
],
[isPlatform],
);
const pathSegments = useMemo(() => asPath.split('/'), [asPath]);
const projectPageFromUrl = appSubdomain
? pathSegments[5] || 'overview'
@@ -137,9 +159,8 @@ export default function ProjectPagesComboBox() {
const selectedProjectPageFromUrl = projectPages.find(
(item) => item.value === projectPageFromUrl,
);
const [selectedProjectPage, setSelectedProjectPage] = useState<Option | null>(
null,
);
const [selectedProjectPage, setSelectedProjectPage] =
useState<SelectedOption | null>(null);
useEffect(() => {
if (selectedProjectPageFromUrl) {
@@ -155,6 +176,7 @@ export default function ProjectPagesComboBox() {
label: app.label,
value: app.slug,
icon: app.icon,
disabled: app.disabled,
}));
const [open, setOpen] = useState(false);
@@ -188,6 +210,7 @@ export default function ProjectPagesComboBox() {
<CommandItem
key={option.value}
value={option.label}
disabled={option.disabled}
onSelect={() => {
setSelectedProjectPage(option);
setOpen(false);

View File

@@ -3,6 +3,7 @@ import { cva, type VariantProps } from 'class-variance-authority';
import * as React from 'react';
import { cn } from '@/lib/utils';
import { Loader2 } from 'lucide-react';
const buttonVariants = cva(
'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
@@ -53,4 +54,16 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
);
Button.displayName = 'Button';
export { Button, buttonVariants };
const ButtonWithLoading = React.forwardRef<
HTMLButtonElement,
ButtonProps & { loading?: boolean }
>(({ loading, disabled, children, ...props }, ref) => {
return (
<Button disabled={loading || disabled} ref={ref} {...props}>
{loading && <Loader2 className="mr-2 animate-spin" />}
{children}
</Button>
);
});
export { Button, buttonVariants, ButtonWithLoading };

View File

@@ -0,0 +1,80 @@
'use client';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import {
DayPicker,
type DayPickerProps,
type StyledComponent,
} from 'react-day-picker';
import { buttonVariants } from '@/components/ui/v3/button';
import { cn } from '@/lib/utils';
const IconLeft = ({ className, ...props }: StyledComponent) => (
<ChevronLeft className={cn('h-4 w-4', className)} {...props} />
);
const IconRight = ({ className, ...props }: StyledComponent) => (
<ChevronRight className={cn('h-4 w-4', className)} {...props} />
);
function Calendar({
className,
classNames,
showOutsideDays = true,
...props
}: DayPickerProps) {
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn('p-3', className)}
classNames={{
months: 'flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0',
month: 'space-y-4',
caption: 'flex justify-center pt-1 relative items-center',
caption_label: 'text-sm font-medium',
nav: 'space-x-1 flex items-center',
nav_button: cn(
buttonVariants({ variant: 'outline' }),
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
),
nav_button_previous: 'absolute left-1',
nav_button_next: 'absolute right-1',
table: 'w-full border-collapse space-y-1',
head_row: 'flex',
head_cell:
'text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]',
row: 'flex w-full mt-2',
cell: cn(
'relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md',
props.mode === 'range'
? '[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md'
: '[&:has([aria-selected])]:rounded-md',
),
day: cn(
buttonVariants({ variant: 'ghost' }),
'h-8 w-8 p-0 font-normal aria-selected:opacity-100',
),
day_range_start: 'day-range-start',
day_range_end: 'day-range-end',
day_selected:
'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground',
day_today: 'bg-accent text-accent-foreground',
day_outside:
'day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground',
day_disabled: 'text-muted-foreground opacity-50',
day_range_middle:
'aria-selected:bg-accent aria-selected:text-accent-foreground',
day_hidden: 'invisible',
...classNames,
}}
components={{
IconLeft,
IconRight,
}}
{...props}
/>
);
}
Calendar.displayName = 'Calendar';
export { Calendar };

View File

@@ -27,10 +27,15 @@ const DialogOverlay = React.forwardRef<
));
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
interface DialogContentProps
extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
disableOutsideClick?: boolean;
}
const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
DialogContentProps
>(({ className, children, disableOutsideClick, ...props }, ref) => (
<DialogPortal>
<DialogOverlay>
<DialogPrimitive.Content
@@ -39,6 +44,11 @@ const DialogContent = React.forwardRef<
'relative z-50 grid w-full max-w-lg gap-4 bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 sm:rounded-lg md:w-full',
className,
)}
onInteractOutside={
disableOutsideClick
? (e) => e.preventDefault()
: props.onInteractOutside
}
{...props}
>
{children}

View File

@@ -0,0 +1,56 @@
import { cn } from '@/lib/utils';
import { type VariantProps, cva } from 'class-variance-authority';
import { Loader2 } from 'lucide-react';
import React from 'react';
const spinnerVariants = cva('flex-col items-center justify-center', {
variants: {
show: {
true: 'flex',
false: 'hidden',
},
},
defaultVariants: {
show: true,
},
});
const loaderVariants = cva('animate-spin text-primary', {
variants: {
size: {
small: 'size-6',
medium: 'size-8',
large: 'size-12',
},
},
defaultVariants: {
size: 'medium',
},
});
interface SpinnerContentProps
extends VariantProps<typeof spinnerVariants>,
VariantProps<typeof loaderVariants> {
className?: string;
children?: React.ReactNode;
}
export function Spinner({
size,
show,
children,
className,
}: SpinnerContentProps) {
return (
<span className={spinnerVariants({ show })}>
<Loader2
className={cn(
loaderVariants({ size }),
className,
'stroke-[#1e324b] dark:stroke-[#dfecf5]',
)}
/>
{children}
</span>
);
}

View File

@@ -0,0 +1,53 @@
import * as TabsPrimitive from '@radix-ui/react-tabs';
import * as React from 'react';
import { cn } from '@/lib/utils';
const Tabs = TabsPrimitive.Root;
const TabsList = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.List>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
>(({ className, ...props }, ref) => (
<TabsPrimitive.List
ref={ref}
className={cn(
'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',
className,
)}
{...props}
/>
));
TabsList.displayName = TabsPrimitive.List.displayName;
const TabsTrigger = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Trigger
ref={ref}
className={cn(
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm',
className,
)}
{...props}
/>
));
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
const TabsContent = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Content
ref={ref}
className={cn(
'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
className,
)}
{...props}
/>
));
TabsContent.displayName = TabsPrimitive.Content.displayName;
export { Tabs, TabsContent, TabsList, TabsTrigger };

View File

@@ -20,7 +20,7 @@ import { getUserRoles } from '@/features/projects/roles/settings/utils/getUserRo
import { useRemoteApplicationGQLClient } from '@/hooks/useRemoteApplicationGQLClient';
import type { DialogFormProps } from '@/types/common';
import {
RemoteAppGetUsersDocument,
RemoteAppGetUsersAndAuthRolesDocument,
useGetProjectLocalesQuery,
useGetRolesPermissionsQuery,
useUpdateRemoteAppUserMutation,
@@ -116,7 +116,7 @@ export default function EditUserForm({
const [updateUser] = useUpdateRemoteAppUserMutation({
client: remoteProjectGQLClient,
refetchQueries: [RemoteAppGetUsersDocument],
refetchQueries: [RemoteAppGetUsersAndAuthRolesDocument],
});
const form = useForm<EditUserFormValues>({

View File

@@ -6,7 +6,7 @@ import { Input } from '@/components/ui/v2/Input';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useRemoteApplicationGQLClient } from '@/hooks/useRemoteApplicationGQLClient';
import type { DialogFormProps } from '@/types/common';
import type { RemoteAppGetUsersQuery } from '@/utils/__generated__/graphql';
import type { RemoteAppGetUsersAndAuthRolesQuery } from '@/utils/__generated__/graphql';
import {
useGetSignInMethodsQuery,
useUpdateRemoteAppUserMutation,
@@ -26,7 +26,7 @@ export interface EditUserPasswordFormProps extends DialogFormProps {
/**
* The selected user.
*/
user: RemoteAppGetUsersQuery['users'][0];
user: RemoteAppGetUsersAndAuthRolesQuery['users'][0];
}
export default function EditUserPasswordForm({

View File

@@ -15,6 +15,9 @@ query GetPostgresSettings($appId: uuid!) {
}
enablePublicAccess
}
pitr {
retention
}
}
}
}

View File

@@ -175,7 +175,23 @@ function CreateOrgForm({ plans, onSubmit, onCancel }: CreateOrgFormProps) {
);
}
export default function CreateOrgDialog() {
interface CreateOrgDialogProps {
hideNewOrgButton?: boolean;
isOpen?: boolean;
onOpenStateChange?: (newState: boolean) => void;
redirectUrl?: string;
}
function isPropSet(prop: any) {
return prop !== undefined;
}
export default function CreateOrgDialog({
hideNewOrgButton,
isOpen,
onOpenStateChange,
redirectUrl,
}: CreateOrgDialogProps) {
const { maintenanceActive } = useUI();
const user = useUserData();
const isPlatform = useIsPlatform();
@@ -186,6 +202,16 @@ export default function CreateOrgDialog() {
const [createOrganizationRequest] = useCreateOrganizationRequestMutation();
const [stripeClientSecret, setStripeClientSecret] = useState('');
const handleOpenChange = (newOpenState: boolean) => {
const controlledFromOutSide =
isPropSet(isOpen) && isPropSet(onOpenStateChange);
if (controlledFromOutSide) {
onOpenStateChange(newOpenState);
} else {
setOpen(newOpenState);
}
};
const createOrg = async ({
name,
plan,
@@ -195,16 +221,17 @@ export default function CreateOrgDialog() {
}) => {
await execPromiseWithErrorToast(
async () => {
const defaultRedirectUrl = `${window.location.origin}/orgs/verify`;
const {
data: { billingCreateOrganizationRequest: clientSecret },
} = await createOrganizationRequest({
variables: {
organizationName: name,
planID: plan,
redirectURL: `${window.location.origin}/orgs/verify`,
redirectURL: redirectUrl ?? defaultRedirectUrl,
},
});
setStripeClientSecret(clientSecret);
},
{
@@ -224,20 +251,22 @@ export default function CreateOrgDialog() {
}
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button
disabled={maintenanceActive}
className={cn(
'flex h-8 w-full flex-row justify-start gap-3 px-2',
'bg-background text-foreground hover:bg-accent dark:hover:bg-muted',
)}
onClick={() => setStripeClientSecret('')}
>
<Plus className="h-4 w-4 font-bold" strokeWidth={3} />
New Organization
</Button>
</DialogTrigger>
<Dialog open={isOpen ?? open} onOpenChange={handleOpenChange}>
{!hideNewOrgButton && (
<DialogTrigger asChild>
<Button
disabled={maintenanceActive}
className={cn(
'flex h-8 w-full flex-row justify-start gap-3 px-2',
'bg-background text-foreground hover:bg-accent dark:hover:bg-muted',
)}
onClick={() => setStripeClientSecret('')}
>
<Plus className="h-4 w-4 font-bold" strokeWidth={3} />
New Organization
</Button>
</DialogTrigger>
)}
<DialogContent
className={cn(
'text-foreground sm:max-w-xl',
@@ -264,7 +293,7 @@ export default function CreateOrgDialog() {
<CreateOrgForm
plans={data?.plans}
onSubmit={createOrg}
onCancel={() => setOpen(false)}
onCancel={() => handleOpenChange(false)}
/>
)}
{!loading && stripeClientSecret && (

View File

@@ -0,0 +1,31 @@
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/v3/alert';
import { cn } from '@/lib/utils';
import { type PropsWithChildren, type ReactNode } from 'react';
interface Props {
title?: string;
icon?: ReactNode;
}
function InfoAlert({ children, title, icon }: PropsWithChildren<Props>) {
const alertClassNames = cn('bg-[#ebf3ff] dark:bg-muted', {
'flex gap-2 items-center': !!icon,
});
const descClassNames = cn('text-[0.9375rem] leading-[22px]', {
'text-[0.875rem] leading-[1rem]': !!icon,
});
return (
<Alert className={alertClassNames}>
{icon && <div>{icon}</div>}
<div>
{title && <AlertTitle>{title}</AlertTitle>}
<AlertDescription className={descClassNames}>
{children}
</AlertDescription>
</div>
</Alert>
);
}
export default InfoAlert;

View File

@@ -0,0 +1 @@
export { default as InfoAlert } from './InfoAlert';

View File

@@ -0,0 +1,53 @@
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { CheckoutStatus } from '@/utils/__generated__/graphql';
import { memo } from 'react';
interface Props {
loading: boolean;
status: CheckoutStatus | null;
successMessage: string;
loadingMessage: string;
errorMessage: string;
pendingMessage: string;
}
function FinishOrgCreationProcess({
loading,
status,
successMessage,
loadingMessage,
errorMessage,
pendingMessage,
}: Props) {
let message: string | undefined;
switch (status) {
case CheckoutStatus.Completed: {
message = successMessage;
break;
}
case CheckoutStatus.Expired: {
message = errorMessage;
break;
}
case CheckoutStatus.Open: {
message = pendingMessage;
break;
}
default:
message = loadingMessage;
}
return (
<div className="relative flex flex-auto overflow-x-hidden">
<div className="flex h-full w-full flex-col items-center justify-center space-y-2">
{(loading || status === CheckoutStatus.Completed) && (
<ActivityIndicator circularProgressProps={{ className: 'w-6 h-6' }} />
)}
<span>{message}</span>
</div>
</div>
);
}
export default memo(FinishOrgCreationProcess);

View File

@@ -0,0 +1 @@
export { default as FinishOrgCreationProcess } from './FinishOrgCreationProcess';

View File

@@ -0,0 +1,24 @@
import { FinishOrgCreationProcess } from '@/features/orgs/components/common/FinishOrgCreationProcess';
import { useFinishOrgCreation } from '@/features/orgs/hooks/useFinishOrgCreation';
import { type FinishOrgCreationOnCompletedCb } from '@/features/orgs/hooks/useFinishOrgCreation/useFinishOrgCreation';
interface Props {
onCompleted: FinishOrgCreationOnCompletedCb;
onError: () => void;
}
function FinishOrgCreation({ onCompleted, onError }: Props) {
const [loading, status] = useFinishOrgCreation({ onCompleted, onError });
return (
<FinishOrgCreationProcess
loading={loading}
status={status}
loadingMessage="Processing new organization request"
successMessage="Organization created successfully."
pendingMessage="Organization creation is pending..."
errorMessage="Error occurred while creating the organization. Please try again."
/>
);
}
export default FinishOrgCreation;

View File

@@ -0,0 +1,233 @@
import {
mockMatchMediaValue,
mockOrganization,
mockOrganizations,
mockOrganizationsWithNewOrg,
newOrg,
} from '@/tests/mocks';
import { getOrganization } from '@/tests/msw/mocks/graphql/getOrganizationQuery';
import { getProjectQuery } from '@/tests/msw/mocks/graphql/getProjectQuery';
import { prefetchNewAppQuery } from '@/tests/msw/mocks/graphql/prefetchNewAppQuery';
import tokenQuery from '@/tests/msw/mocks/rest/tokenQuery';
import {
createGraphqlMockResolver,
fireEvent,
mockPointerEvent,
queryClient,
render,
screen,
waitFor,
} from '@/tests/orgs/testUtils';
import userEvent from '@testing-library/user-event';
import { setupServer } from 'msw/node';
import { useState } from 'react';
import { afterAll, beforeAll, vi } from 'vitest';
import TransferProjectDialog from './TransferProjectDialog';
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: vi.fn().mockImplementation(mockMatchMediaValue),
});
mockPointerEvent();
const getUseRouterObject = (session_id?: string) => ({
basePath: '',
pathname: '/orgs/xyz/projects/test-project',
route: '/orgs/[orgSlug]/projects/[appSubdomain]',
asPath: '/orgs/xyz/projects/test-project',
isLocaleDomain: false,
isReady: true,
isPreview: false,
query: {
orgSlug: 'xyz',
appSubdomain: 'test-project',
session_id,
},
push: vi.fn(),
replace: vi.fn(),
reload: vi.fn(),
back: vi.fn(),
prefetch: vi.fn(),
beforePopState: vi.fn(),
events: {
on: vi.fn(),
off: vi.fn(),
emit: vi.fn(),
},
isFallback: false,
});
const mocks = vi.hoisted(() => ({
useRouter: vi.fn(),
useOrgs: vi.fn(),
}));
vi.mock('@/features/orgs/projects/hooks/useOrgs', async () => {
const actualUseOrgs = await vi.importActual<any>(
'@/features/orgs/projects/hooks/useOrgs',
);
return {
...actualUseOrgs,
useOrgs: mocks.useOrgs,
};
});
const postOrganizationRequestResolver = createGraphqlMockResolver(
'postOrganizationRequest',
'mutation',
);
vi.mock('next/router', () => ({
useRouter: mocks.useRouter,
}));
export function DialogWrapper({
defaultOpen = true,
}: {
defaultOpen?: boolean;
}) {
const [open, setOpen] = useState(defaultOpen);
return <TransferProjectDialog open={open} setOpen={setOpen} />;
}
const server = setupServer(tokenQuery);
beforeAll(() => {
process.env.NEXT_PUBLIC_NHOST_PLATFORM = 'true';
process.env.NEXT_PUBLIC_ENV = 'production';
server.listen();
});
afterEach(() => {
queryClient.clear();
mocks.useRouter.mockRestore();
});
afterAll(() => {
server.close();
vi.restoreAllMocks();
});
test('opens create org dialog when selecting "create new org" and closes transfer dialog', async () => {
mocks.useRouter.mockImplementation(() => getUseRouterObject());
const user = userEvent.setup();
server.use(getProjectQuery);
server.use(getOrganization);
mocks.useOrgs.mockImplementation(() => ({
orgs: mockOrganizations,
currentOrg: mockOrganization,
loading: false,
refetch: vi.fn(),
}));
server.use(prefetchNewAppQuery);
render(<DialogWrapper />);
const organizationCombobox = await screen.findByRole('combobox', {
name: /Organization/i,
});
expect(organizationCombobox).toBeInTheDocument();
await user.click(organizationCombobox);
const newOrgOption = await screen.findByRole('option', {
name: 'New Organization',
});
await user.click(newOrgOption);
expect(organizationCombobox).toHaveTextContent('New Organization');
const submitButton = await screen.findByText('Continue');
expect(submitButton).toHaveTextContent('Continue');
fireEvent(
submitButton,
new MouseEvent('click', {
bubbles: true,
cancelable: true,
}),
);
await waitFor(() => {
expect(submitButton).not.toBeInTheDocument();
});
const newOrgTitle = await screen.findByText('New Organization');
expect(newOrgTitle).toBeInTheDocument();
const closeButton = await screen.findByText('Close');
fireEvent(
closeButton,
new MouseEvent('click', {
bubbles: true,
cancelable: true,
}),
);
await waitFor(() => {
expect(newOrgTitle).not.toBeInTheDocument();
});
const submitButtonAfterClosingNewOrgDialog =
await screen.findByText('Continue');
await waitFor(() => {
expect(submitButtonAfterClosingNewOrgDialog).toHaveTextContent('Continue');
});
});
test(`transfer dialog opens automatically when there is a session_id and selects the ${newOrg.name} from the dropdown`, async () => {
mocks.useRouter.mockImplementation(() => getUseRouterObject('session_id'));
server.use(getProjectQuery);
server.use(getOrganization);
mocks.useOrgs.mockImplementation(() => ({
orgs: mockOrganizations,
currentOrg: mockOrganization,
loading: false,
refetch: vi.fn(),
}));
server.use(prefetchNewAppQuery);
server.use(postOrganizationRequestResolver.handler);
render(<DialogWrapper defaultOpen={false} />);
const processingNewOrgText = await screen.findByText(
'Processing new organization request',
);
expect(processingNewOrgText).toBeInTheDocument();
const closeButton = await screen.findByText('Close');
fireEvent(
closeButton,
new MouseEvent('click', {
bubbles: true,
cancelable: true,
}),
);
await waitFor(() => {});
expect(closeButton).toBeInTheDocument();
postOrganizationRequestResolver.resolve({
billingPostOrganizationRequest: {
Status: 'COMPLETED',
Slug: newOrg.slug,
ClientSecret: null,
__typename: 'PostOrganizationRequestResponse',
},
});
mocks.useOrgs.mockImplementation(() => ({
orgs: mockOrganizationsWithNewOrg,
currentOrg: mockOrganization,
loading: false,
refetch: vi.fn(),
}));
const organizationCombobox = await screen.findByRole('combobox', {
name: /Organization/i,
});
expect(organizationCombobox).toHaveTextContent(newOrg.name);
const submitButton = await screen.findByText('Transfer');
expect(submitButton).not.toBeDisabled();
});

View File

@@ -1,5 +1,3 @@
import { Badge } from '@/components/ui/v3/badge';
import { Button } from '@/components/ui/v3/button';
import {
Dialog,
DialogContent,
@@ -10,6 +8,8 @@ import {
import { LoadingScreen } from '@/components/presentational/LoadingScreen';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Badge } from '@/components/ui/v3/badge';
import { Button } from '@/components/ui/v3/button';
import {
Form,
FormControl,
@@ -25,20 +25,26 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/v3/select';
import FinishOrgCreation from '@/features/orgs/components/common/TransferProjectDialog/FinishOrgCreation';
import CreateOrgDialog from '@/features/orgs/components/CreateOrgFormDialog/CreateOrgFormDialog';
import type { FinishOrgCreationOnCompletedCb } from '@/features/orgs/hooks/useFinishOrgCreation/useFinishOrgCreation';
import { useOrgs, type Org } from '@/features/orgs/projects/hooks/useOrgs';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { execPromiseWithErrorToast } from '@/features/orgs/utils/execPromiseWithErrorToast';
import { cn } from '@/lib/utils';
import { cn, isNotEmptyValue } from '@/lib/utils';
import {
Organization_Members_Role_Enum,
useBillingTransferAppMutation,
} from '@/utils/__generated__/graphql';
import { zodResolver } from '@hookform/resolvers/zod';
import { useUserId } from '@nhost/nextjs';
import { Plus } from 'lucide-react';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
const CREATE_NEW_ORG = 'createNewOrg';
interface TransferProjectDialogProps {
open: boolean;
setOpen: (value: boolean) => void;
@@ -52,11 +58,21 @@ export default function TransferProjectDialog({
open,
setOpen,
}: TransferProjectDialogProps) {
const { push } = useRouter();
const { push, asPath, query, replace, pathname } = useRouter();
const { session_id, test, ...remainingQuery } = query;
const currentUserId = useUserId();
const { project, loading: projectLoading } = useProject();
const { orgs, currentOrg, loading: orgsLoading } = useOrgs();
const {
orgs,
currentOrg,
loading: orgsLoading,
refetch: refetchOrgs,
} = useOrgs();
const [transferProject] = useBillingTransferAppMutation();
const [showCreateOrgModal, setShowCreateOrgModal] = useState(false);
const [finishOrgCreation, setFinishOrgCreation] = useState(false);
const [preventClose, setPreventClose] = useState(false);
const [newOrgSlug, setNewOrgSlug] = useState<string | undefined>();
const form = useForm<z.infer<typeof transferProjectFormSchema>>({
resolver: zodResolver(transferProjectFormSchema),
@@ -65,29 +81,62 @@ export default function TransferProjectDialog({
},
});
useEffect(() => {
if (session_id) {
setOpen(true);
setFinishOrgCreation(true);
setPreventClose(true);
}
}, [session_id, setOpen]);
useEffect(() => {
if (isNotEmptyValue(newOrgSlug)) {
const newOrg = orgs.find((org) => org.slug === newOrgSlug);
if (newOrg) {
form.setValue('organization', newOrg?.id, { shouldDirty: true });
}
}
}, [newOrgSlug, orgs, form]);
const createNewFormSelected = form.watch('organization') === CREATE_NEW_ORG;
const submitButtonText = createNewFormSelected ? 'Continue' : 'Transfer';
const path = asPath.split('?')[0];
const redirectUrl = `${window.location.origin}${path}`;
const handleCreateDialogOpenStateChange = (newState: boolean) => {
setShowCreateOrgModal(newState);
setOpen(true);
};
const onSubmit = async (
values: z.infer<typeof transferProjectFormSchema>,
) => {
const { organization } = values;
await execPromiseWithErrorToast(
async () => {
await transferProject({
variables: {
appID: project?.id,
organizationID: organization,
},
});
if (organization === CREATE_NEW_ORG) {
setShowCreateOrgModal(true);
setOpen(false);
} else {
await execPromiseWithErrorToast(
async () => {
await transferProject({
variables: {
appID: project?.id,
organizationID: organization,
},
});
const targetOrg = orgs.find((o) => o.id === organization);
await push(`/orgs/${targetOrg.slug}/projects`);
},
{
loadingMessage: 'Transferring project...',
successMessage: 'Project transferred successfully!',
errorMessage: 'Error transferring project. Please try again.',
},
);
const targetOrg = orgs.find((o) => o.id === organization);
await push(`/orgs/${targetOrg.slug}/projects`);
},
{
loadingMessage: 'Transferring project...',
successMessage: 'Project transferred successfully!',
errorMessage: 'Error transferring project. Please try again.',
},
);
}
};
const isUserAdminOfOrg = (org: Org, userId: string) =>
@@ -97,103 +146,161 @@ export default function TransferProjectDialog({
member.user.id === userId,
);
const removeSessionIdFromQuery = () => {
replace({ pathname, query: remainingQuery }, undefined, { shallow: true });
};
const handleFinishOrgCreationCompleted: FinishOrgCreationOnCompletedCb =
async (data) => {
const { Slug } = data;
await refetchOrgs();
setNewOrgSlug(Slug);
setFinishOrgCreation(false);
removeSessionIdFromQuery();
setPreventClose(false);
};
const handleTransferProjectDialogOpenChange = (newValue: boolean) => {
if (preventClose) {
return;
}
if (!newValue) {
setNewOrgSlug(undefined);
}
form.reset();
setOpen(newValue);
};
if (projectLoading || orgsLoading) {
return <LoadingScreen />;
}
return (
<Dialog
open={open}
onOpenChange={(value) => {
form.reset();
setOpen(value);
}}
>
<DialogContent className="z-[9999] text-foreground sm:max-w-xl">
<DialogHeader className="flex gap-2">
<DialogTitle>
Move the current project to a different organization.
</DialogTitle>
<DialogDescription>
To transfer a project between organizations, you must be an{' '}
<span className="font-bold">ADMIN</span> in both.
</DialogDescription>
</DialogHeader>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField
control={form.control}
name="organization"
render={({ field }) => (
<FormItem>
<FormLabel>Organization</FormLabel>
<Select
onValueChange={field.onChange}
defaultValue={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Organization" />
</SelectTrigger>
</FormControl>
<SelectContent>
{orgs.map((org) => (
<SelectItem
key={org.id}
value={org.id}
disabled={
org.plan.isFree || // disable the personal org
org.id === currentOrg.id || // disable the current org as it can't be a destination org
!isUserAdminOfOrg(org, currentUserId) // disable orgs that the current user is not admin of
}
>
{org.name}
<Badge
variant={org.plan.isFree ? 'outline' : 'default'}
className={cn(
org.plan.isFree ? 'bg-muted' : '',
'hover:none ml-2 h-5 px-[6px] text-[10px]',
)}
>
{org.plan.name}
</Badge>
</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
<>
<Dialog open={open} onOpenChange={handleTransferProjectDialogOpenChange}>
<DialogContent className="z-[9999] text-foreground sm:max-w-xl">
<DialogHeader className="flex gap-2">
<DialogTitle>
Move the current project to a different organization.{' '}
</DialogTitle>
<div className="flex justify-end space-x-2">
<Button
variant="secondary"
type="button"
disabled={form.formState.isSubmitting}
onClick={() => {
form.reset();
setOpen(false);
}}
{!finishOrgCreation && (
<DialogDescription>
To transfer a project between organizations, you must be an{' '}
<span className="font-bold">ADMIN</span> in both.
<br />
When transferred to a new organization, the project will adopt
that organizations plan.
</DialogDescription>
)}
</DialogHeader>
{finishOrgCreation ? (
<FinishOrgCreation
onCompleted={handleFinishOrgCreationCompleted}
onError={() => setPreventClose(false)}
/>
) : (
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-4"
>
Cancel
</Button>
<Button
type="submit"
disabled={
form.formState.isSubmitting || !form.formState.isDirty
}
>
{form.formState.isSubmitting ? (
<ActivityIndicator />
) : (
'Transfer'
)}
</Button>
</div>
</form>
</Form>
</DialogContent>
</Dialog>
<FormField
control={form.control}
name="organization"
render={({ field }) => (
<FormItem>
<FormLabel>Organization</FormLabel>
<Select
onValueChange={field.onChange}
value={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Organization" />
</SelectTrigger>
</FormControl>
<SelectContent>
{orgs.map((org) => (
<SelectItem
key={org.id}
value={org.id}
disabled={
org.plan.isFree || // disable the personal org
org.id === currentOrg.id || // disable the current org as it can't be a destination org
!isUserAdminOfOrg(org, currentUserId) // disable orgs that the current user is not admin of
}
>
{org.name}
<Badge
variant={
org.plan.isFree ? 'outline' : 'default'
}
className={cn(
org.plan.isFree ? 'bg-muted' : '',
'hover:none ml-2 h-5 px-[6px] text-[10px]',
)}
>
{org.plan.name}
</Badge>
</SelectItem>
))}
<SelectItem
key={CREATE_NEW_ORG}
value={CREATE_NEW_ORG}
>
<div className="flex items-center justify-center gap-2">
<Plus
className="h-4 w-4 font-bold"
strokeWidth={3}
/>{' '}
<span>New Organization</span>
</div>
</SelectItem>
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end space-x-2">
<Button
variant="secondary"
type="button"
disabled={form.formState.isSubmitting || preventClose}
onClick={() => {
form.reset();
setOpen(false);
}}
>
Cancel
</Button>
<Button
type="submit"
disabled={
form.formState.isSubmitting || !form.formState.isDirty
}
>
{form.formState.isSubmitting ? (
<ActivityIndicator />
) : (
submitButtonText
)}
</Button>
</div>
</form>
</Form>
)}
</DialogContent>
</Dialog>
<CreateOrgDialog
hideNewOrgButton
isOpen={showCreateOrgModal}
onOpenStateChange={handleCreateDialogOpenStateChange}
redirectUrl={redirectUrl}
/>
</>
);
}

View File

@@ -0,0 +1,167 @@
import { mockMatchMediaValue } from '@/tests/mocks';
import { getOrganizations } from '@/tests/msw/mocks/graphql/getOrganizationQuery';
import tokenQuery from '@/tests/msw/mocks/rest/tokenQuery';
import { mockSession } from '@/tests/orgs/mocks';
import { queryClient, render, waitFor } from '@/tests/orgs/testUtils';
import { CheckoutStatus } from '@/utils/__generated__/graphql';
import { setupServer } from 'msw/node';
import { afterAll, beforeAll, vi } from 'vitest';
import NotificationsTray from './NotificationsTray';
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: vi.fn().mockImplementation(mockMatchMediaValue),
});
export const getUseRouterObject = (session_id?: string) => ({
basePath: '',
pathname: '/orgs/xyz/projects/test-project',
route: '/orgs/[orgSlug]/projects/[appSubdomain]',
asPath: '/orgs/xyz/projects/test-project',
isLocaleDomain: false,
isReady: true,
isPreview: false,
query: {
orgSlug: 'xyz',
appSubdomain: 'test-project',
session_id,
},
push: vi.fn(),
replace: vi.fn(),
reload: vi.fn(),
back: vi.fn(),
prefetch: vi.fn(),
beforePopState: vi.fn(),
events: {
on: vi.fn(),
off: vi.fn(),
emit: vi.fn(),
},
isFallback: false,
});
const mocks = vi.hoisted(() => ({
useRouter: vi.fn(),
useOrganizationNewRequestsLazyQuery: vi.fn(),
usePostOrganizationRequestMutation: vi.fn(),
useOrganizationMemberInvitesLazyQuery: vi.fn(),
fetchPostOrganizationResponseMock: vi.fn(),
userData: vi.fn(),
}));
vi.mock('next/router', () => ({
useRouter: mocks.useRouter,
}));
vi.mock('@nhost/nextjs', async () => {
const actualNhostNextjs = await vi.importActual<any>('@nhost/nextjs');
return {
...actualNhostNextjs,
userData: mocks.userData,
};
});
vi.mock('@/utils/__generated__/graphql', async () => {
const actual = await vi.importActual<any>('@/utils/__generated__/graphql');
return {
...actual,
useOrganizationNewRequestsLazyQuery:
mocks.useOrganizationNewRequestsLazyQuery,
usePostOrganizationRequestMutation:
mocks.usePostOrganizationRequestMutation,
useOrganizationMemberInvitesLazyQuery:
mocks.useOrganizationMemberInvitesLazyQuery,
};
});
const server = setupServer(tokenQuery);
beforeAll(() => {
process.env.NEXT_PUBLIC_NHOST_PLATFORM = 'true';
process.env.NEXT_PUBLIC_ENV = 'production';
});
afterEach(() => {
queryClient.clear();
vi.restoreAllMocks();
});
afterAll(() => {
server.close();
});
const fetchOrganizationMemberInvitesMock = () => [
async () => ({ data: { organizationMemberInvites: [] } }),
{
loading: true,
refetch: vi.fn(),
data: { organizationMemberInvites: [] },
},
];
const fetchOrganizationNewRequestsResponseMock = async () => ({
data: {
organizationNewRequests: [
{
id: 'org-request-id-1',
sessionID: 'session-id-1',
__typename: 'organization_new_request',
},
],
},
});
const fetchPostOrganizationResponseMock = vi.fn();
test('if there is NO session_id in the url the billingPostOrganizationRequest is fetched from the server', async () => {
server.use(getOrganizations);
mocks.useOrganizationMemberInvitesLazyQuery.mockImplementation(
fetchOrganizationMemberInvitesMock,
);
mocks.useRouter.mockImplementation(() => getUseRouterObject());
mocks.userData.mockImplementation(() => mockSession.user);
mocks.useOrganizationNewRequestsLazyQuery.mockImplementation(() => [
fetchOrganizationNewRequestsResponseMock,
]);
mocks.usePostOrganizationRequestMutation.mockImplementation(() => [
fetchPostOrganizationResponseMock.mockImplementation(() => ({
data: {
billingPostOrganizationRequest: {
Status: CheckoutStatus.Open,
Slug: 'newOrgSlug',
ClientSecret: 'very_secret_secret',
__typename: 'PostOrganizationRequestResponse',
},
},
})),
]);
render(<NotificationsTray />);
await waitFor(() => {
/* Wait for the component to be update */
});
expect(fetchPostOrganizationResponseMock).toHaveBeenCalled();
});
test('if there is a session_id in the url the billingPostOrganizationRequest is NOT fetched from the server ', async () => {
server.use(getOrganizations);
mocks.useOrganizationMemberInvitesLazyQuery.mockImplementation(
fetchOrganizationMemberInvitesMock,
);
mocks.useRouter.mockImplementation(() => getUseRouterObject('SESSION_ID'));
mocks.userData.mockImplementation(() => mockSession.user);
mocks.useOrganizationNewRequestsLazyQuery.mockImplementation(() => [
fetchOrganizationNewRequestsResponseMock,
]);
mocks.usePostOrganizationRequestMutation.mockImplementation(() => [
fetchPostOrganizationResponseMock,
]);
render(<NotificationsTray />);
await waitFor(() => {
/* Wait for the component to be update */
});
expect(fetchPostOrganizationResponseMock).not.toHaveBeenCalled();
});

View File

@@ -18,6 +18,7 @@ import {
import { StripeEmbeddedForm } from '@/features/orgs/components/StripeEmbeddedForm';
import { useOrgs } from '@/features/orgs/projects/hooks/useOrgs';
import { execPromiseWithErrorToast } from '@/features/orgs/utils/execPromiseWithErrorToast';
import { isEmptyValue } from '@/lib/utils';
import {
CheckoutStatus,
useDeleteOrganizationMemberInviteMutation,
@@ -38,7 +39,8 @@ type Invite = OrganizationMemberInvitesQuery['organizationMemberInvites'][0];
export default function NotificationsTray() {
const userData = useUserData();
const { asPath, route, push } = useRouter();
const { asPath, route, push, query } = useRouter();
const { session_id } = query;
const { refetch: refetchOrgs } = useOrgs();
const [open, setOpen] = useState(false);
@@ -76,7 +78,6 @@ export default function NotificationsTray() {
userID: userData.id,
},
});
if (organizationNewRequests.length > 0) {
const { sessionID } = organizationNewRequests.at(0);
@@ -109,10 +110,20 @@ export default function NotificationsTray() {
}
};
if (userData && !['/', '/orgs/verify'].includes(route)) {
if (
userData &&
!['/', '/orgs/verify'].includes(route) &&
isEmptyValue(session_id)
) {
checkForPendingOrgRequests();
}
}, [route, userData, getOrganizationNewRequests, postOrganizationRequest]);
}, [
route,
userData,
getOrganizationNewRequests,
postOrganizationRequest,
session_id,
]);
const [acceptInvite] = useOrganizationMemberInviteAcceptMutation();
const [deleteInvite] = useDeleteOrganizationMemberInviteMutation();

View File

@@ -0,0 +1 @@
export { default as useDatabasePiTRSettings } from './useDatabasePiTRSettings';

View File

@@ -0,0 +1,24 @@
import { useIsPiTREnabled } from '@/features/orgs/hooks/useIsPiTREnabled';
import { useEffect, useState } from 'react';
function useDatabasePiTRSettings() {
const [isPiTREnabled, setIsPiTREnabled] = useState(false);
const [isNotSwitchTouched, setIsNotSwitchTouched] = useState(true);
const { isPiTREnabled: isPiTREnabledData } = useIsPiTREnabled();
useEffect(() => {
setIsPiTREnabled(isPiTREnabledData);
}, [isPiTREnabledData]);
const isSwitchDisabled =
isPiTREnabled === isPiTREnabledData || isNotSwitchTouched;
return {
isPiTREnabled,
setIsPiTREnabled,
isSwitchDisabled,
setIsNotSwitchTouched,
};
}
export default useDatabasePiTRSettings;

View File

@@ -0,0 +1 @@
export { default as useFinishOrgCreation } from './useFinishOrgCreation';

View File

@@ -0,0 +1,92 @@
import {
CheckoutStatus,
type PostOrganizationRequestMutation,
usePostOrganizationRequestMutation,
} from '@/utils/__generated__/graphql';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { useAuthenticationStatus } from '@nhost/nextjs';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
export type FinishOrgCreationOnCompletedCb = (
data: PostOrganizationRequestMutation['billingPostOrganizationRequest'],
) => void;
interface UseFinishOrgCreationProps {
onCompleted: FinishOrgCreationOnCompletedCb;
onError?: () => void;
}
function useFinishOrgCreation({
onCompleted,
onError,
}: UseFinishOrgCreationProps): [boolean, CheckoutStatus] {
const router = useRouter();
const { session_id } = router.query;
const { isAuthenticated } = useAuthenticationStatus();
const [loading, setLoading] = useState(false);
const [postOrganizationRequest] = usePostOrganizationRequestMutation();
const [status, setPostOrganizationRequestStatus] =
useState<CheckoutStatus | null>(null);
useEffect(() => {
async function finishOrgCreation() {
if (session_id && isAuthenticated) {
setLoading(true);
execPromiseWithErrorToast(
async () => {
const {
data: { billingPostOrganizationRequest },
} = await postOrganizationRequest({
variables: {
sessionID: session_id as string,
},
});
const { Status } = billingPostOrganizationRequest;
setLoading(false);
setPostOrganizationRequestStatus(Status);
switch (Status) {
case CheckoutStatus.Completed:
onCompleted(billingPostOrganizationRequest);
break;
case CheckoutStatus.Expired:
onError();
throw new Error('Request to create organization has expired');
case CheckoutStatus.Open:
// TODO discuss what to do in this case
onError();
throw new Error(
'Request to create organization with status "Open"',
);
default:
break;
}
},
{
loadingMessage: 'Processing new organization request',
successMessage:
'The new organization has been created successfully.',
errorMessage:
'An error occurred while creating the new organization.',
onError,
},
);
}
}
finishOrgCreation();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [session_id, isAuthenticated]);
return [loading, status];
}
export default useFinishOrgCreation;

View File

@@ -0,0 +1 @@
export { default as useImportBackupSourceProjectList } from './useImportBackupSourceProjectList';

View File

@@ -0,0 +1,33 @@
import { useCurrentOrg } from '@/features/orgs/projects/hooks/useCurrentOrg';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { useGetProjectsQuery } from '@/utils/__generated__/graphql';
import { useMemo } from 'react';
function useImportBackupSourceProjectList() {
const { org } = useCurrentOrg();
const { project } = useProject();
const currentProjectRegionId = project?.region.id;
const projectId = project?.id;
const { data, loading } = useGetProjectsQuery({
variables: {
orgSlug: org?.slug,
},
});
const filteredProjects = useMemo(
() =>
(data?.apps || [])
.filter(
(app) =>
app.id !== projectId && app.region.id === currentProjectRegionId,
)
.map((app) => ({
label: `${app.name} (${app.region.name})`,
id: app.id,
})),
[data?.apps, currentProjectRegionId, projectId],
);
return { filteredProjects, loading };
}
export default useImportBackupSourceProjectList;

View File

@@ -0,0 +1 @@
export { default as useIsPiTREnabled } from './useIsPiTREnabled';

View File

@@ -0,0 +1,20 @@
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { isNotEmptyValue as isNotNull } from '@/lib/utils';
import { useGetPostgresSettingsQuery } from '@/utils/__generated__/graphql';
import { useMemo } from 'react';
function useIsPiTREnabled() {
const { project } = useProject();
const { data, loading } = useGetPostgresSettingsQuery({
variables: { appId: project?.id },
});
const isPiTREnabled = useMemo(
() => isNotNull(data?.config.postgres.pitr?.retention),
[data?.config.postgres.pitr?.retention],
);
return { isPiTREnabled, loading };
}
export default useIsPiTREnabled;

View File

@@ -0,0 +1 @@
export { default as useIsPiTREnabledLazy } from './useIsPiTREnabledLazy';

View File

@@ -0,0 +1,30 @@
import { isNotEmptyValue } from '@/lib/utils';
import { useGetPostgresSettingsLazyQuery } from '@/utils/__generated__/graphql';
import { useEffect, useMemo, useRef } from 'react';
function useIsPiTREnabledLazy(appId?: string) {
const [getPostgresSettings, { data, loading }] =
useGetPostgresSettingsLazyQuery({
fetchPolicy: 'no-cache',
});
const prevAppId = useRef<string>();
useEffect(() => {
async function fetchPiTRSettings() {
if (isNotEmptyValue(appId) && prevAppId.current !== appId) {
await getPostgresSettings({ variables: { appId } });
prevAppId.current = appId;
}
}
fetchPiTRSettings();
}, [appId, getPostgresSettings]);
const isPiTREnabled = useMemo(
() => isNotEmptyValue(data?.config.postgres.pitr?.retention),
[data?.config.postgres.pitr?.retention],
);
return { isPiTREnabled, loading };
}
export default useIsPiTREnabledLazy;

View File

@@ -0,0 +1,33 @@
import { isNotEmptyValue } from '@/lib/utils';
import { useGetPiTrBaseBackupsLazyQuery } from '@/utils/__generated__/graphql';
import { triggerToast } from '@/utils/toast';
import { useEffect, useState } from 'react';
function usePiTRBaseBackups(appId: string) {
const [earliestBackupDate, setEarliestBackup] = useState<string>();
const [fetchPiTRBaseBackups, { loading }] = useGetPiTrBaseBackupsLazyQuery();
useEffect(() => {
async function getPiTRBaseBackups() {
if (appId) {
const { data, error } = await fetchPiTRBaseBackups({
variables: { appId },
});
if (error) {
triggerToast(
'An error occurred while fetching the Point-in-Time backup data. Please try again later.',
);
}
if (isNotEmptyValue(data.getPiTRBaseBackups)) {
const earliestBackup = data.getPiTRBaseBackups.slice(-1).pop();
setEarliestBackup(earliestBackup.date);
}
}
}
getPiTRBaseBackups();
}, [appId, fetchPiTRBaseBackups]);
return { earliestBackupDate, loading };
}
export default usePiTRBaseBackups;

View File

@@ -0,0 +1 @@
export { default as useRestoreApplicationDatabasePiTR } from './useRestoreApplicationDatabasePiTR';

View File

@@ -0,0 +1,34 @@
import { useRestoreApplicationDatabasePiTrMutation } from '@/utils/__generated__/graphql';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
function useRestoreApplicationDatabasePiTR() {
const [restoreApplicationDatabaseMutation, { loading }] =
useRestoreApplicationDatabasePiTrMutation();
async function restoreApplicationDatabase(
variables: { appId: string; recoveryTarget: string; fromAppId?: string },
onCompleted?: () => void,
) {
await execPromiseWithErrorToast(
async () => {
await restoreApplicationDatabaseMutation({
variables,
onCompleted,
});
},
{
loadingMessage: 'Starting restore from backup...',
successMessage: 'Backup has been scheduled successfully.',
errorMessage:
'An error occurred while attempting to schedule a backup. Please try again.',
},
);
}
return {
restoreApplicationDatabase,
loading,
};
}
export default useRestoreApplicationDatabasePiTR;

View File

@@ -0,0 +1 @@
export { default as useUpdateDatabasePiTRConfig } from './useUpdateDatabasePiTRConfig';

View File

@@ -0,0 +1,51 @@
import { useCallback, useState } from 'react';
import { RECOVERY_RETENTION_PERIOD_7 } from '@/features/orgs/projects/database/dataGrid/utils/postgresqlConstants/postgresqlConstants';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { execPromiseWithErrorToast } from '@/features/orgs/utils/execPromiseWithErrorToast';
import { useUpdateConfigMutation } from '@/utils/__generated__/graphql';
function useUpdateDatabasePiTRConfig() {
const { project } = useProject();
const [loading, setLoading] = useState(false);
const [updateConfig] = useUpdateConfigMutation();
const updatePiTRConfig = useCallback(
async (isPiTREnabled: boolean) => {
const pitr = isPiTREnabled
? { retention: RECOVERY_RETENTION_PERIOD_7 }
: null;
const updateConfigMutationPromise = updateConfig({
variables: {
appId: project?.id,
config: {
postgres: {
pitr,
},
},
},
});
await execPromiseWithErrorToast(
async () => {
setLoading(true);
await updateConfigMutationPromise;
setLoading(false);
},
{
loadingMessage: `${isPiTREnabled ? 'Enabling' : 'Disabling'} Point-in-Time recovery...`,
successMessage: `Point-in-Time has been ${isPiTREnabled ? 'enabled' : 'disabled'} successfully.`,
errorMessage:
'An error occurred while trying to enable Point-in-Time recovery.',
onError: () => setLoading(false),
},
);
},
[updateConfig, project?.id],
);
return { updatePiTRConfig, loading };
}
export default useUpdateDatabasePiTRConfig;

View File

@@ -20,13 +20,11 @@ import { useIsPlatform } from '@/features/orgs/projects/common/hooks/useIsPlatfo
import { useLocalMimirClient } from '@/features/orgs/projects/hooks/useLocalMimirClient';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { execPromiseWithErrorToast } from '@/features/orgs/utils/execPromiseWithErrorToast';
import { getUserRoles } from '@/features/projects/roles/settings/utils/getUserRoles';
import { type RemoteAppUser } from '@/pages/orgs/[orgSlug]/projects/[appSubdomain]/users';
import type { DialogFormProps } from '@/types/common';
import {
RemoteAppGetUsersDocument,
RemoteAppGetUsersAndAuthRolesDocument,
useGetProjectLocalesQuery,
useGetRolesPermissionsQuery,
useUpdateRemoteAppUserMutation,
} from '@/utils/__generated__/graphql';
import { copy } from '@/utils/copy';
@@ -114,13 +112,12 @@ export default function EditUserForm({
const { onDirtyStateChange, openDialog } = useDialog();
const { project } = useProject();
const isAnonymous = user.roles.some((role) => role.role === 'anonymous');
const [isUserBanned, setIsUserBanned] = useState(user.disabled);
const remoteProjectGQLClient = useRemoteApplicationGQLClient();
const [updateUser] = useUpdateRemoteAppUserMutation({
client: remoteProjectGQLClient,
refetchQueries: [RemoteAppGetUsersDocument],
refetchQueries: [RemoteAppGetUsersAndAuthRolesDocument],
});
const form = useForm<EditUserFormValues>({
@@ -198,15 +195,6 @@ export default function EditUserForm({
});
}
const { data: dataRoles } = useGetRolesPermissionsQuery({
variables: { appId: project?.id },
...(!isPlatform ? { client: localMimirClient } : {}),
});
const allAvailableProjectRoles = getUserRoles(
dataRoles?.config?.auth?.user?.roles?.allowed,
);
const { data } = useGetProjectLocalesQuery({
variables: {
appId: project?.id,
@@ -489,47 +477,46 @@ export default function EditUserForm({
))}
</div>
</Box>
{!isAnonymous && (
<Box
component="section"
className="grid grid-flow-row gap-y-10 p-6"
<Box component="section" className="grid grid-flow-row gap-y-10 p-6">
<ControlledSelect
{...register('defaultRole')}
id="defaultRole"
name="defaultRole"
variant="inline"
label="Default Role"
slotProps={{ root: { className: 'truncate' } }}
hideEmptyHelperText
fullWidth
error={!!errors.defaultRole}
helperText={errors?.defaultRole?.message}
>
<ControlledSelect
{...register('defaultRole')}
id="defaultRole"
name="defaultRole"
variant="inline"
label="Default Role"
slotProps={{ root: { className: 'truncate' } }}
hideEmptyHelperText
fullWidth
error={!!errors.defaultRole}
helperText={errors?.defaultRole?.message}
>
{allAvailableProjectRoles.map((role) => (
<Option key={role.name} value={role.name}>
{role.name}
</Option>
{roles.map((role, i) => (
<Option
// eslint-disable-next-line react/no-array-index-key
key={`defaultRoles.${i}`}
value={Object.keys(role)[0]}
>
{Object.keys(role)[0]}
</Option>
))}
</ControlledSelect>
<div className="grid grid-flow-row place-content-start gap-6 lg:grid-flow-col lg:grid-cols-8">
<InputLabel as="h3" className="col-span-2">
Allowed Roles
</InputLabel>
<div className="col-span-3 grid grid-flow-row gap-6">
{roles.map((role, i) => (
<ControlledCheckbox
id={`roles.${i}`}
label={Object.keys(role)[0]}
name={`roles.${i}`}
// eslint-disable-next-line react/no-array-index-key
key={`roles.${i}`}
/>
))}
</ControlledSelect>
<div className="grid grid-flow-row place-content-start gap-6 lg:grid-flow-col lg:grid-cols-8">
<InputLabel as="h3" className="col-span-2">
Allowed Roles
</InputLabel>
<div className="col-span-3 grid grid-flow-row gap-6">
{roles.map((role, i) => (
<ControlledCheckbox
id={`roles.${i}`}
label={Object.keys(role)[0]}
name={`roles.${i}`}
// eslint-disable-next-line react/no-array-index-key
key={`roles.${i}`}
/>
))}
</div>
</div>
</Box>
)}
</div>
</Box>
<Box component="section" className="grid grid-flow-row gap-8 p-6">
<Input
{...register('metadata', { onChange: handleMetadataChange })}

View File

@@ -7,7 +7,7 @@ import { useRemoteApplicationGQLClient } from '@/features/orgs/hooks/useRemoteAp
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { execPromiseWithErrorToast } from '@/features/orgs/utils/execPromiseWithErrorToast';
import type { DialogFormProps } from '@/types/common';
import type { RemoteAppGetUsersQuery } from '@/utils/__generated__/graphql';
import type { RemoteAppGetUsersAndAuthRolesQuery } from '@/utils/__generated__/graphql';
import {
useGetSignInMethodsQuery,
useUpdateRemoteAppUserMutation,
@@ -26,7 +26,7 @@ export interface EditUserPasswordFormProps extends DialogFormProps {
/**
* The selected user.
*/
user: RemoteAppGetUsersQuery['users'][0];
user: RemoteAppGetUsersAndAuthRolesQuery['users'][0];
}
export default function EditUserPasswordForm({

View File

@@ -15,15 +15,11 @@ import { Text } from '@/components/ui/v2/Text';
import { useRemoteApplicationGQLClient } from '@/features/orgs/hooks/useRemoteApplicationGQLClient';
import type { EditUserFormValues } from '@/features/orgs/projects/authentication/users/components/EditUserForm';
import { getReadableProviderName } from '@/features/orgs/projects/authentication/users/utils/getReadableProviderName';
import { useIsPlatform } from '@/features/orgs/projects/common/hooks/useIsPlatform';
import { useLocalMimirClient } from '@/features/orgs/projects/hooks/useLocalMimirClient';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { execPromiseWithErrorToast } from '@/features/orgs/utils/execPromiseWithErrorToast';
import { getUserRoles } from '@/features/projects/roles/settings/utils/getUserRoles';
import type { RemoteAppUser } from '@/pages/orgs/[orgSlug]/projects/[appSubdomain]/users';
import type { Role } from '@/types/application';
import {
useDeleteRemoteAppUserRolesMutation,
useGetRolesPermissionsQuery,
useInsertRemoteAppUserRolesMutation,
useRemoteAppDeleteUserMutation,
useUpdateRemoteAppUserMutation,
@@ -33,7 +29,7 @@ import { formatDistance } from 'date-fns';
import kebabCase from 'just-kebab-case';
import dynamic from 'next/dynamic';
import Image from 'next/image';
import { Fragment, useMemo } from 'react';
import { Fragment } from 'react';
const EditUserForm = dynamic(
() =>
@@ -59,14 +55,16 @@ export interface UsersBodyProps {
* @example onSuccessfulAction={() => router.reload()}
*/
onSubmit?: () => Promise<any>;
allAvailableProjectRoles: Role[];
}
export default function UsersBody({ users, onSubmit }: UsersBodyProps) {
export default function UsersBody({
users,
onSubmit,
allAvailableProjectRoles,
}: UsersBodyProps) {
const theme = useTheme();
const isPlatform = useIsPlatform();
const localMimirClient = useLocalMimirClient();
const { openAlertDialog, openDrawer, closeDrawer } = useDialog();
const { project } = useProject();
const remoteProjectGQLClient = useRemoteApplicationGQLClient();
const [deleteUser] = useRemoteAppDeleteUserMutation({
@@ -85,23 +83,6 @@ export default function UsersBody({ users, onSubmit }: UsersBodyProps) {
client: remoteProjectGQLClient,
});
/**
* We want to fetch the queries of the application on this page since we're
* going to use once the user selects a user of their application; we use it
* in the drawer form.
*/
const { data: dataRoles } = useGetRolesPermissionsQuery({
variables: { appId: project?.id },
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { allowed: allowedRoles } = dataRoles?.config?.auth?.user?.roles || {};
const allAvailableProjectRoles = useMemo(
() => getUserRoles(allowedRoles),
[allowedRoles],
);
async function handleEditUser(
values: EditUserFormValues,
user: RemoteAppUser,

View File

@@ -1 +0,0 @@
export { default as BackupList } from './BackupList';

View File

@@ -1,2 +0,0 @@
export * from './BackupListItem';
export { default as BackupListItem } from './BackupListItem';

View File

@@ -0,0 +1,27 @@
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/v3/tabs';
import { ImportBackupTabContent } from '@/features/orgs/projects/backups/components/ImportBackupTabContent';
import { PointInTimeTabsContent } from '@/features/orgs/projects/backups/components/PointInTimeTabsContent';
import { ScheduledBackupTabContent } from '@/features/orgs/projects/backups/components/ScheduledBackupTabContent';
import { memo, useState } from 'react';
function BackupsContent({ isPiTREnabled }: { isPiTREnabled: boolean }) {
const [tab, setTab] = useState(() =>
isPiTREnabled ? 'pointInTime' : 'scheduledBackups',
);
return (
<Tabs value={tab} onValueChange={setTab}>
<TabsList>
<TabsTrigger value="scheduledBackups">Scheduled backups</TabsTrigger>
<TabsTrigger value="pointInTime">Point-in-time</TabsTrigger>
<TabsTrigger value="importBackup">Import backup</TabsTrigger>
</TabsList>
<div className="pt-7">
<ScheduledBackupTabContent />
{tab === 'pointInTime' && <PointInTimeTabsContent />}
{tab === 'importBackup' && <ImportBackupTabContent />}
</div>
</Tabs>
);
}
export default memo(BackupsContent);

View File

@@ -0,0 +1 @@
export { default as BackupsContent } from './BackupsContent';

View File

@@ -0,0 +1,43 @@
import { TabsContent } from '@/components/ui/v3/tabs';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { useState } from 'react';
import SourceProjectBackupInfo from './SourceProjectBackupInfo';
import SourceProjectSelect from './SourceProjectSelect';
function ImportBackupContent() {
const { project } = useProject();
const [sourceProject, setSourceProject] = useState<{
label: string;
id: string;
}>();
function handleProjectSelect(selectedProject: { label: string; id: string }) {
setSourceProject(selectedProject);
}
const title = sourceProject
? `Import backup from ${sourceProject.label}`
: '';
return (
<TabsContent value="importBackup">
<div className="flex flex-col gap-8">
<div>
<h1 className="mb-4 text-base leading-5">
<strong>Target project:</strong> {project?.name} (
{project?.region.name})
</h1>
<SourceProjectSelect
projectId={sourceProject?.id}
onProjectSelect={handleProjectSelect}
/>
</div>
{sourceProject && (
<SourceProjectBackupInfo appId={sourceProject.id} title={title} />
)}
</div>
</TabsContent>
);
}
export default ImportBackupContent;

View File

@@ -0,0 +1,18 @@
import { InfoAlert } from '@/features/orgs/components/InfoAlert';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { CircleAlert } from 'lucide-react';
function NoOtherProjectsInRegion() {
const { project } = useProject();
return (
<InfoAlert
title={`There are no other projects within the region: ${project.region.name}`}
icon={<CircleAlert className="h-[38px] w-[38px]" />}
>
Backups may be imported from projects that are in the same region and
organization.
</InfoAlert>
);
}
export default NoOtherProjectsInRegion;

View File

@@ -0,0 +1,15 @@
import { InfoAlert } from '@/features/orgs/components/InfoAlert';
import { DatabaseZap } from 'lucide-react';
function PiTRNotEnabledOnSourceProject() {
return (
<InfoAlert
title="Point-in-Time recovery is not enabled on the selected project"
icon={<DatabaseZap className="h-[38px] w-[38px]" />}
>
Importing from scheduled backups is not supported yet. Coming soon!
</InfoAlert>
);
}
export default PiTRNotEnabledOnSourceProject;

View File

@@ -0,0 +1,25 @@
import { useIsPiTREnabledLazy } from '@/features/orgs/hooks/useIsPiTREnabledLazy';
import { PointInTimeBackupInfo } from '@/features/orgs/projects/backups/components/common/PointInTimeBackupInfo';
import PiTRNotEnabledOnSourceProject from './PiTRNotEnabledOnSourceProject';
interface Props {
appId: string;
title?: string;
}
function SourceProjectBackupInfo({ appId, title }: Props) {
const { isPiTREnabled } = useIsPiTREnabledLazy(appId);
return isPiTREnabled ? (
<PointInTimeBackupInfo
appId={appId}
title={title}
dialogTitle="Import backup"
dialogButtonText="Import backup"
dialogTriggerText="Start import"
/>
) : (
<PiTRNotEnabledOnSourceProject />
);
}
export default SourceProjectBackupInfo;

View File

@@ -0,0 +1,53 @@
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/v3/select';
import { useImportBackupSourceProjectList } from '@/features/orgs/hooks/useImportBackupSourceProjectList';
import { isEmptyValue } from '@/lib/utils';
import NoOtherProjectsInRegion from './NoOtherProjectsInRegion';
interface Props {
onProjectSelect: (project: { label: string; id: string }) => void;
projectId: string;
}
function SourceProjectSelect({ onProjectSelect, projectId }: Props) {
const { filteredProjects, loading } = useImportBackupSourceProjectList();
if (!loading && isEmptyValue(filteredProjects)) {
return <NoOtherProjectsInRegion />;
}
function handleChange(value: string) {
const selectedProject = filteredProjects.find((fp) => fp.id === value);
onProjectSelect(selectedProject);
}
return (
<div className="w-max">
<p className="pb-1 text-[#21324B] dark:text-[#DFECF5]">Source project</p>
<Select value={projectId} onValueChange={handleChange} disabled={loading}>
<SelectTrigger>
<SelectValue placeholder="Select a project to import backup from" />
</SelectTrigger>
<SelectContent>
{filteredProjects.map((project) => (
<SelectItem key={project.id} value={project.id}>
{project.label}
</SelectItem>
))}
</SelectContent>
</Select>
<p className="pt-1 text-[#9CA7B7] dark:text-[#68717A]">
Backups can be imported from projects that are in the same organization
and region.
</p>
</div>
);
}
export default SourceProjectSelect;

View File

@@ -0,0 +1 @@
export { default as ImportBackupTabContent } from './ImportBackupTabContent';

View File

@@ -0,0 +1,24 @@
import { InfoAlert } from '@/features/orgs/components/InfoAlert';
import { useCurrentOrg } from '@/features/orgs/projects/hooks/useCurrentOrg';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import Link from 'next/link';
function PiTRNotEnabled() {
const { org } = useCurrentOrg();
const { project } = useProject();
return (
<InfoAlert>
To enable Point-in-Time recovery, enable it in the{' '}
<Link
href={`/orgs/${org?.slug}/projects/${project?.subdomain}/settings/database`}
className="text-[0.9375rem] leading-[1.375rem] text-[#0052cd] hover:underline dark:text-[#3888ff]"
target="_blank"
rel="noopener noreferrer"
>
database settings.
</Link>
</InfoAlert>
);
}
export default PiTRNotEnabled;

View File

@@ -0,0 +1,15 @@
import { PointInTimeBackupInfo } from '@/features/orgs/projects/backups/components/common/PointInTimeBackupInfo';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import RecoveryRetentionPeriod from './RecoveryRetentionPeriod';
function PointInTimeRecovery() {
const { project } = useProject();
return (
<div className="flex flex-col gap-[1.875rem]">
<RecoveryRetentionPeriod />
<PointInTimeBackupInfo appId={project?.id} />
</div>
);
}
export default PointInTimeRecovery;

View File

@@ -0,0 +1,17 @@
import { Spinner } from '@/components/ui/v3/spinner';
import { TabsContent } from '@/components/ui/v3/tabs';
import { useIsPiTREnabled } from '@/features/orgs/hooks/useIsPiTREnabled';
import PiTRNotEnabled from './PiTRNotEnabled';
import PointInTimeRecovery from './PointInTimeRecovery';
function PointInTimeTabsContent() {
const { isPiTREnabled, loading } = useIsPiTREnabled();
const content = isPiTREnabled ? <PointInTimeRecovery /> : <PiTRNotEnabled />;
return (
<TabsContent value="pointInTime">
{loading ? <Spinner /> : content}
</TabsContent>
);
}
export default PointInTimeTabsContent;

View File

@@ -0,0 +1,16 @@
import { InfoAlert } from '@/features/orgs/components/InfoAlert';
import { CalendarClock } from 'lucide-react';
function RecoveryRetentionPeriod() {
return (
<InfoAlert
title="Recovery retention period"
icon={<CalendarClock className="h-[38px] w-[38px]" />}
>
Database changes are retained for up to 7 days, allowing restoration to
any point within this period.
</InfoAlert>
);
}
export default RecoveryRetentionPeriod;

View File

@@ -0,0 +1 @@
export { default as PointInTimeTabsContent } from './PointInTimeTabsContent';

View File

@@ -1,2 +0,0 @@
export * from './RestoreBackupModal';
export { default as RestoreBackupModal } from './RestoreBackupModal';

View File

@@ -6,9 +6,9 @@ import { TableContainer } from '@/components/ui/v2/TableContainer';
import { TableHead } from '@/components/ui/v2/TableHead';
import { TableRow } from '@/components/ui/v2/TableRow';
import { Text } from '@/components/ui/v2/Text';
import { BackupListItem } from '@/features/orgs/projects/backups/components/BackupListItem';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { useGetApplicationBackupsQuery } from '@/utils/__generated__/graphql';
import BackupListItem from './BackupListItem';
export default function BackupList() {
const { project, loading: loadingProject } = useProject();

View File

@@ -2,13 +2,13 @@ import { useDialog } from '@/components/common/DialogProvider';
import { Button } from '@/components/ui/v2/Button';
import { TableCell } from '@/components/ui/v2/TableCell';
import { TableRow } from '@/components/ui/v2/TableRow';
import { RestoreBackupModal } from '@/features/orgs/projects/backups/components/RestoreBackupModal';
import type { Backup } from '@/types/application';
import { useGetBackupPresignedUrlLazyQuery } from '@/utils/__generated__/graphql';
import { prettifySize } from '@/utils/prettifySize';
import { triggerToast } from '@/utils/toast';
import { format, formatDistanceStrict, parseISO } from 'date-fns';
import { twMerge } from 'tailwind-merge';
import RestoreBackupModal from './RestoreBackupModal';
export interface BackupListItemProps {
/**

View File

@@ -0,0 +1,12 @@
import { InfoAlert } from '@/features/orgs/components/InfoAlert';
function PiTREnabledInfoBanner() {
return (
<InfoAlert>
With PiTR enabled, Scheduled backups are no longer taken. PiTR provides
more precise recovery, making additional backups unnecessary.
</InfoAlert>
);
}
export default PiTREnabledInfoBanner;

View File

@@ -0,0 +1,36 @@
import { Text } from '@/components/ui/v2/Text';
import { Spinner } from '@/components/ui/v3/spinner';
import { TabsContent } from '@/components/ui/v3/tabs';
import { useIsPiTREnabled } from '@/features/orgs/hooks/useIsPiTREnabled';
import BackupList from './BackupList';
import PiTREnabledInfoBanner from './PiTREnabledInfoBanner';
function ScheduledBackupTabContent() {
const { isPiTREnabled, loading } = useIsPiTREnabled();
const content = isPiTREnabled ? (
<PiTREnabledInfoBanner />
) : (
<>
<div>
<Text variant="h3" className="pb-2">
Database
</Text>
<Text color="secondary">
The database backup includes database schema, database data and Hasura
metadata. It does not include the actual files in Storage.
</Text>
</div>
<BackupList />
</>
);
return (
<TabsContent value="scheduledBackups">
<div className="grid w-full grid-flow-row gap-6">
{loading ? <Spinner /> : content}
</div>
</TabsContent>
);
}
export default ScheduledBackupTabContent;

View File

@@ -0,0 +1 @@
export { default as ScheduledBackupTabContent } from './ScheduledBackupTabContent';

View File

@@ -0,0 +1,46 @@
import { Button } from '@/components/ui/v3/button';
import { DialogFooter } from '@/components/ui/v3/dialog';
import Link from 'next/link';
import type { PropsWithChildren } from 'react';
import { memo } from 'react';
function LogsLink({ href, children }: PropsWithChildren<{ href: string }>) {
return (
<Link
href={href}
className="text-[0.9375rem] leading-[1.375rem] text-[#0052cd] hover:underline dark:text-[#3888ff]"
target="_blank"
rel="noopener noreferrer"
>
{children}
</Link>
);
}
interface Props {
onClose: () => void;
orgSlug: string;
subdomain: string;
}
//
function BackupScheduledInfo({ onClose, orgSlug, subdomain }: Props) {
return (
<>
<p>Your backup has been scheduled successfully and will start shortly.</p>
<p>
To follow its process go to the{' '}
<LogsLink href={`/orgs/${orgSlug}/projects/${subdomain}/logs`}>
Logs page
</LogsLink>{' '}
and select the service &quot;Backup Job&quot; to see the restore logs.
</p>
<DialogFooter>
<Button type="button" onClick={onClose}>
Close
</Button>
</DialogFooter>
</>
);
}
export default memo(BackupScheduledInfo);

View File

@@ -0,0 +1,55 @@
import { TimezonePicker } from '@/components/common/TimezonePicker';
import { Button } from '@/components/ui/v3/button';
import { Spinner } from '@/components/ui/v3/spinner';
import { getDateTimeStringWithUTCOffset } from '@/features/orgs/projects/backups/utils/getDateTimeStringWithUTCOffset';
import { isEmptyValue } from '@/lib/utils';
import { guessTimezone } from '@/utils/timezoneUtils';
import { useState } from 'react';
interface Props {
dateTime: string;
loading: boolean;
}
function EarliestBackupDateTime({ dateTime }: Pick<Props, 'dateTime'>) {
const [selectedTimezone, setTimezone] = useState<string>(() =>
guessTimezone(),
);
function handleSelect(tz: { value: string; label: string }) {
setTimezone(tz.value);
}
return (
<p className="flex items-center gap-2 text-[1.125rem]">
<span data-testid="EarliestBackupDateTime">
{getDateTimeStringWithUTCOffset(dateTime, selectedTimezone)}
</span>
<TimezonePicker
dateTime={dateTime}
selectedTimezone={selectedTimezone}
onTimezoneSelect={handleSelect}
button={
<Button className="h-auto p-0" variant="link">
Change timezone
</Button>
}
/>
</p>
);
}
function EarliestBackup({ dateTime, loading }: Props) {
if (loading) {
return (
<div className="flex h-[27px] max-w-fit">
<Spinner size="small" />
</div>
);
}
const hasNoPiTRBackups = !loading && isEmptyValue(dateTime);
if (hasNoPiTRBackups) {
return <p className="text-[1.125rem]">Project has no backups yet.</p>;
}
return <EarliestBackupDateTime dateTime={dateTime} />;
}
export default EarliestBackup;

Some files were not shown because too many files have changed in this diff Show More