Compare commits

..

101 Commits

Author SHA1 Message Date
github-actions[bot]
e2646cab55 chore: update versions (#2709)
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@1.16.0

### Minor Changes

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

## @nhost/docs@2.12.0

### Minor Changes

-   d5077c7: feat: added docs about how to connect to postgres

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-05-15 09:36:54 +01:00
David Barroso
d5077c7ca4 feat (docs): added docs about how to connect to postgres (#2708) 2024-05-15 10:15:23 +02:00
Hassan Ben Jobrane
c6d5c5cc8c feat: dashboard: add toggle switch to enable/disable database public access (#2707) 2024-05-15 09:12:06 +01:00
github-actions[bot]
f1d9b472d1 chore: update versions (#2704)
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@7.0.2

### Patch Changes

-   Updated dependencies [4c35171]
-   Updated dependencies [3cea460]
    -   @nhost/nhost-js@3.1.2

## @nhost/react-apollo@11.0.4

### Patch Changes

-   @nhost/apollo@7.0.2
-   @nhost/react@3.4.4

## @nhost/react-urql@8.0.4

### Patch Changes

-   @nhost/react@3.4.4

## @nhost/nextjs@2.1.13

### Patch Changes

-   @nhost/react@3.4.4

## @nhost/nhost-js@3.1.2

### Patch Changes

- 4c35171: fix: update docstring to correctly reflect usage of
nhost.unsetRole method
- 3cea460: chore: update docs links for nhost-js setRole and unsetRole
methods

## @nhost/react@3.4.4

### Patch Changes

-   Updated dependencies [4c35171]
-   Updated dependencies [3cea460]
    -   @nhost/nhost-js@3.1.2

## @nhost/vue@2.5.4

### Patch Changes

-   Updated dependencies [4c35171]
-   Updated dependencies [3cea460]
    -   @nhost/nhost-js@3.1.2

## @nhost/docs@2.11.0

### Minor Changes

-   c6dc7f4: chore: docs: add Nhost client reference

## @nhost/dashboard@1.15.2

### Patch Changes

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

## @nhost-examples/cli@0.3.4

### Patch Changes

-   Updated dependencies [4c35171]
-   Updated dependencies [3cea460]
    -   @nhost/nhost-js@3.1.2

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

### Patch Changes

-   @nhost/react@3.4.4
-   @nhost/react-apollo@11.0.4

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

### Patch Changes

-   @nhost/react@3.4.4

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

### Patch Changes

-   @nhost/react@3.4.4
-   @nhost/react-urql@8.0.4

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

### Patch Changes

-   Updated dependencies [4c35171]
-   Updated dependencies [3cea460]
    -   @nhost/nhost-js@3.1.2

## @nhost-examples/nextjs@0.3.4

### Patch Changes

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

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

### Patch Changes

-   Updated dependencies [4c35171]
-   Updated dependencies [3cea460]
    -   @nhost/nhost-js@3.1.2

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

### Patch Changes

-   Updated dependencies [4c35171]
-   Updated dependencies [3cea460]
    -   @nhost/nhost-js@3.1.2

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

### Patch Changes

-   @nhost/react@3.4.4
-   @nhost/react-apollo@11.0.4

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

### Patch Changes

-   @nhost/react@3.4.4

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

### Patch Changes

-   Updated dependencies [4c35171]
-   Updated dependencies [3cea460]
    -   @nhost/nhost-js@3.1.2
    -   @nhost/apollo@7.0.2
    -   @nhost/vue@2.5.4

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

### Patch Changes

-   @nhost/apollo@7.0.2
-   @nhost/vue@2.5.4

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-05-14 13:56:40 +01:00
Nuno Pato
c6dc7f44df chore: docs: add Nhost client reference (#2698) 2024-05-14 13:49:31 +01:00
Hassan Ben Jobrane
3cea460c36 chore: update docs links for nhost-js setRole and unsetRole methods (#2706) 2024-05-14 12:52:30 +01:00
Hassan Ben Jobrane
4c351714f5 fix(sdk): update docstring to accurately reflect usage of nhost.unsetRole method (#2703) 2024-05-14 10:54:41 +01:00
github-actions[bot]
3143d66a8e chore: update versions (#2701)
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@7.0.1

### Patch Changes

-   @nhost/nhost-js@3.1.1

## @nhost/react-apollo@11.0.3

### Patch Changes

-   @nhost/apollo@7.0.1
-   @nhost/react@3.4.3

## @nhost/react-urql@8.0.3

### Patch Changes

-   @nhost/react@3.4.3

## @nhost/hasura-storage-js@2.5.1

### Patch Changes

- 8512a7f: fix: fix types StorageGetUrlParams and
StorageGetPresignedUrlParams to include missing StorageHeadersParam

## @nhost/nextjs@2.1.12

### Patch Changes

-   @nhost/react@3.4.3

## @nhost/nhost-js@3.1.1

### Patch Changes

-   Updated dependencies [8512a7f]
    -   @nhost/hasura-storage-js@2.5.1

## @nhost/react@3.4.3

### Patch Changes

-   @nhost/nhost-js@3.1.1

## @nhost/vue@2.5.3

### Patch Changes

-   @nhost/nhost-js@3.1.1

## @nhost/dashboard@1.15.1

### Patch Changes

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

## @nhost-examples/cli@0.3.3

### Patch Changes

-   @nhost/nhost-js@3.1.1

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

### Patch Changes

-   @nhost/react@3.4.3
-   @nhost/react-apollo@11.0.3

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

### Patch Changes

-   @nhost/react@3.4.3

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

### Patch Changes

-   @nhost/react@3.4.3
-   @nhost/react-urql@8.0.3

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

### Patch Changes

-   @nhost/nhost-js@3.1.1

## @nhost-examples/nextjs@0.3.3

### Patch Changes

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

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

### Patch Changes

-   @nhost/nhost-js@3.1.1

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

### Patch Changes

-   @nhost/nhost-js@3.1.1

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

### Patch Changes

-   @nhost/react@3.4.3
-   @nhost/react-apollo@11.0.3

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

### Patch Changes

-   @nhost/react@3.4.3

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

### Patch Changes

-   @nhost/nhost-js@3.1.1
-   @nhost/apollo@7.0.1
-   @nhost/vue@2.5.3

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

### Patch Changes

-   @nhost/apollo@7.0.1
-   @nhost/vue@2.5.3

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-05-13 21:58:21 +01:00
Hassan Ben Jobrane
8512a7f181 fix:(hasura-storage-js): add missing StorageHeadersParam to StorageGetUrlParams and StorageGetPresignedUrlParams (#2700) 2024-05-13 21:39:48 +01:00
github-actions[bot]
e503b8fe8b chore: update versions (#2691)
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/graphql-js@0.2.0

### Minor Changes

- 304065a: feat: add `setHeaders` method enabling global configuration
of storage, graphql, and functions client headers, alongside added
support for passing specific headers with individual calls

## @nhost/hasura-storage-js@2.5.0

### Minor Changes

- 304065a: feat: add `setHeaders` method enabling global configuration
of storage, graphql, and functions client headers, alongside added
support for passing specific headers with individual calls

## @nhost/nhost-js@3.1.0

### Minor Changes

- 304065a: feat: add `setHeaders` method enabling global configuration
of storage, graphql, and functions client headers, alongside added
support for passing specific headers with individual calls

### Patch Changes

-   Updated dependencies [68e0622]
-   Updated dependencies [304065a]
    -   @nhost/hasura-auth-js@2.4.2
    -   @nhost/hasura-storage-js@2.5.0
    -   @nhost/graphql-js@0.2.0

## @nhost/apollo@7.0.0

### Patch Changes

-   Updated dependencies [304065a]
    -   @nhost/nhost-js@3.1.0

## @nhost/react-apollo@11.0.2

### Patch Changes

-   @nhost/apollo@7.0.0
-   @nhost/react@3.4.2

## @nhost/react-urql@8.0.2

### Patch Changes

-   @nhost/react@3.4.2

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

### Patch Changes

- 68e0622: fix: resolved infinite loop occurring with requests to /token
when a user logs out in one tab while other tabs are open

## @nhost/nextjs@2.1.11

### Patch Changes

-   @nhost/react@3.4.2

## @nhost/react@3.4.2

### Patch Changes

-   Updated dependencies [304065a]
    -   @nhost/nhost-js@3.1.0

## @nhost/vue@2.5.2

### Patch Changes

-   Updated dependencies [304065a]
    -   @nhost/nhost-js@3.1.0

## @nhost/dashboard@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

## @nhost/docs@2.10.3

### Patch Changes

-   a58c5cf: fix: broken link

## @nhost-examples/cli@0.3.2

### Patch Changes

-   Updated dependencies [304065a]
    -   @nhost/nhost-js@3.1.0

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

### Patch Changes

-   @nhost/react@3.4.2
-   @nhost/react-apollo@11.0.2

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

### Patch Changes

-   @nhost/react@3.4.2

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

### Patch Changes

-   @nhost/react@3.4.2
-   @nhost/react-urql@8.0.2

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

### Patch Changes

-   Updated dependencies [304065a]
    -   @nhost/nhost-js@3.1.0

## @nhost-examples/nextjs@0.3.2

### Patch Changes

-   @nhost/react@3.4.2
-   @nhost/react-apollo@11.0.2
-   @nhost/nextjs@2.1.11

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

### Patch Changes

-   Updated dependencies [304065a]
    -   @nhost/nhost-js@3.1.0

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

### Patch Changes

-   Updated dependencies [304065a]
    -   @nhost/nhost-js@3.1.0

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

### Patch Changes

-   @nhost/react@3.4.2
-   @nhost/react-apollo@11.0.2

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

### Patch Changes

-   @nhost/react@3.4.2

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

### Patch Changes

-   Updated dependencies [304065a]
    -   @nhost/nhost-js@3.1.0
    -   @nhost/apollo@7.0.0
    -   @nhost/vue@2.5.2

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

### Patch Changes

-   @nhost/apollo@7.0.0
-   @nhost/vue@2.5.2

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-05-13 13:52:42 +01:00
Hassan Ben Jobrane
304065ae22 feat: sdk: add setHeaders for setting global headers and make sure all client calls have a headers arg (#2697)
resolves https://github.com/nhost/nhost/issues/2696
2024-05-13 13:38:28 +01:00
Hassan Ben Jobrane
68e0622eb0 fix: broadcast signout event to all tabs (#2686)
fixes https://github.com/nhost/nhost/issues/2635
2024-05-09 11:20:39 +01:00
Hassan Ben Jobrane
70c6834636 chore: add e2e test project (#2688) 2024-05-08 12:52:11 +01:00
Johanna Blom
a7bde37bba feat (dashboard): send metadata in the edit form (#2689)
resolves #2684

---------

Co-authored-by: Hassan Ben Jobrane <hsanbenjobrane@gmail.com>
2024-05-08 13:36:03 +02:00
Hassan Ben Jobrane
1bc615beca fix(dashboard): improve error toast message handling (#2692) 2024-05-08 12:35:21 +01:00
David Barroso
a58c5cfc96 fix (docs): broken link (#2690) 2024-05-08 12:42:58 +02:00
Daniel Olofsson
c61228e45d Fixed typo in README.md (#2687) 2024-05-07 14:39:31 +02:00
github-actions[bot]
6cec04bd6f chore: update versions (#2680)
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@1.14.0

### Minor Changes

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

## @nhost/docs@2.10.2

### Patch Changes

-   9480489: fix: update docs performance info

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-04-25 13:13:32 +01:00
David Barroso
a448d7d182 feat (dashboard): allow configuring postmark and deleting SMTP settings (#2678)
Co-authored-by: Hassan Ben Jobrane <hsanbenjobrane@gmail.com>
2024-04-25 12:58:47 +01:00
David Barroso
948048940e fix (docs): update docs performance info (#2679)
Co-authored-by: Nuno Pato <nunopato@gmail.com>
2024-04-25 13:50:45 +02:00
github-actions[bot]
5e91221d5a chore: update versions (#2672)
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@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

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-04-18 15:49:01 +01:00
Hassan Ben Jobrane
7278991a59 fix: dashboard: update graphql auto-embeddings configuration to use String type for model field (#2674) 2024-04-18 15:22:32 +01:00
Hassan Ben Jobrane
5924bc3248 fix: dashboard: include password in GetSmtpSettings query (#2673) 2024-04-18 15:14:02 +01:00
Hassan Ben Jobrane
c5ad634799 fix: dashboard: check for undefined router query on Safari when accessing base64config (#2671) 2024-04-18 10:04:18 +01:00
github-actions[bot]
426b93a19f chore: update versions (#2670)
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@1.13.2

### Patch Changes

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

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-04-17 14:15:04 +01:00
Hassan Ben Jobrane
026f84f466 fix: dashboard: use config server url from env variable (#2669)
related to https://github.com/nhost/cli/issues/862
2024-04-17 14:02:11 +01:00
github-actions[bot]
384fac00b1 chore: update versions (#2664)
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@1.13.1

### Patch Changes

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

## @nhost/docs@2.10.1

### Patch Changes

-   9525fd7: fix: update AI docs for 0.5.0
-   076fd4a: fix: update permissions page to indicate we use jsonpath

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-04-16 10:53:36 +01:00
Hassan Ben Jobrane
7e9a2ce136 fix: dashboard: fix isPlatform check when opening run services form (#2666) 2024-04-16 10:38:28 +01:00
David Barroso
076fd4a7c0 fix (docs): update permissions page to indicate we use jsonpath (#2663) 2024-04-15 14:50:21 +02:00
David Barroso
9525fd74b3 fix (docs): update AI docs for 0.5.0 (#2662) 2024-04-15 14:33:59 +02:00
github-actions[bot]
8a2bc98214 chore: update versions (#2648)
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@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

## @nhost/docs@2.10.0

### Minor Changes

-   87ae23b: feat: added "advanced graphql" documentation

### Patch Changes

-   b2be364: feat: added postmark native integration

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-04-15 13:12:24 +01:00
Hassan Ben Jobrane
dd5d262062 feat: dashboard: add model field to auto-embeddings form (#2661)
fixes https://github.com/nhost/nhost/issues/2660
2024-04-15 12:51:57 +01:00
Hassan Ben Jobrane
09962bef37 feat: dashboard: enable local settings (#2647)
fixes https://github.com/nhost/projects/issues/66
2024-04-15 12:49:20 +01:00
Hassan Ben Jobrane
9cdecb6b23 feat: dashboard: add email field to account settings (#2612)
fixes https://github.com/nhost/nhost/issues/2561
2024-04-11 10:47:03 +01:00
David Barroso
e7eb90318e fix: observability: amend export of graphql dashboard (#2655) 2024-04-11 11:44:56 +02:00
Hassan Ben Jobrane
f67f22d321 chore: update @google-cloud/translate to 8.2.0 (#2654) 2024-04-11 10:00:13 +01:00
David Barroso
87ae23ba05 feat (docs/observability): added docs and observability dashboard for "advanced graphql" (#2653)
Co-authored-by: Nuno Pato <nunopato@gmail.com>
2024-04-11 10:22:54 +02:00
David Barroso
b2be3642aa feat (docs): added postmark native integration (#2636) 2024-04-09 09:36:48 +02:00
github-actions[bot]
1230081ce6 chore: update versions (#2640)
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@1.12.2

### Patch Changes

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

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-04-05 12:48:55 +01:00
Hassan Ben Jobrane
c195c517de fix: send email upon signin for unverified users (#2639) 2024-04-05 11:48:14 +01:00
github-actions[bot]
6f419be2c1 chore: update versions (#2634)
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@6.2.1

### Patch Changes

-   @nhost/nhost-js@3.0.11

## @nhost/react-apollo@11.0.1

### Patch Changes

-   @nhost/apollo@6.2.1
-   @nhost/react@3.4.1

## @nhost/react-urql@8.0.1

### Patch Changes

-   @nhost/react@3.4.1

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

### Patch Changes

-   bcd889b: fix: change expiresAt format to RFC3339 in createPATPromise

## @nhost/nextjs@2.1.10

### Patch Changes

-   @nhost/react@3.4.1

## @nhost/nhost-js@3.0.11

### Patch Changes

-   Updated dependencies [bcd889b]
    -   @nhost/hasura-auth-js@2.4.1

## @nhost/react@3.4.1

### Patch Changes

-   @nhost/nhost-js@3.0.11

## @nhost/vue@2.5.1

### Patch Changes

-   @nhost/nhost-js@3.0.11

## @nhost/docs@2.9.0

### Minor Changes

-   3c31657: chore: update docs with provider connect

### Patch Changes

-   992939c: feat: added social connect docs

## @nhost/dashboard@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

## @nhost-examples/cli@0.3.1

### Patch Changes

-   @nhost/nhost-js@3.0.11

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

### Patch Changes

-   @nhost/react@3.4.1
-   @nhost/react-apollo@11.0.1

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

### Patch Changes

-   @nhost/react@3.4.1

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

### Patch Changes

-   @nhost/react@3.4.1
-   @nhost/react-urql@8.0.1

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

### Patch Changes

-   @nhost/nhost-js@3.0.11

## @nhost-examples/nextjs@0.3.1

### Patch Changes

-   @nhost/react@3.4.1
-   @nhost/react-apollo@11.0.1
-   @nhost/nextjs@2.1.10

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

### Patch Changes

-   @nhost/nhost-js@3.0.11

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

### Patch Changes

-   @nhost/nhost-js@3.0.11

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

### Patch Changes

-   @nhost/react@3.4.1
-   @nhost/react-apollo@11.0.1

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

### Patch Changes

-   @nhost/react@3.4.1

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

### Patch Changes

-   @nhost/nhost-js@3.0.11
-   @nhost/apollo@6.2.1
-   @nhost/vue@2.5.1

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

### Patch Changes

-   @nhost/apollo@6.2.1
-   @nhost/vue@2.5.1

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-04-04 10:49:02 +01:00
Hassan Ben Jobrane
93ebdf844f fix: dashboard: use service urls when running locally with the cli (#2622) 2024-04-04 10:28:38 +01:00
Hassan Ben Jobrane
bcd889b53a fix: hasura-auth-js: use RFC3339 format for expiresAt when creating a PAT (#2637) 2024-04-03 21:40:02 +01:00
David Barroso
992939cdcd feat (docs): added social connect docs (#2633)
Co-authored-by: Nuno Pato <nunopato@gmail.com>
2024-04-03 16:37:07 +02:00
Nuno Pato
3c31657c50 chore: update docs with provider connect (#2632)
Co-authored-by: David Barroso <dbarrosop@dravetech.com>
2024-04-03 14:27:49 +00:00
github-actions[bot]
a654d536e0 chore: update versions (#2618)
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@6.2.0

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.10

## @nhost/google-translation@0.2.0

### Minor Changes

-   768ca17: chore: update dependencies

## @nhost/react-apollo@11.0.0

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   Updated dependencies [768ca17]
    -   @nhost/apollo@6.2.0
    -   @nhost/react@3.4.0

## @nhost/react-urql@8.0.0

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   Updated dependencies [768ca17]
    -   @nhost/react@3.4.0

## @nhost/stripe-graphql-js@1.2.0

### Minor Changes

-   768ca17: chore: update dependencies

## @nhost/react@3.4.0

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.10

## @nhost/vue@2.5.0

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.10

## @nhost/nextjs@2.1.9

### Patch Changes

-   Updated dependencies [768ca17]
    -   @nhost/react@3.4.0

## @nhost/dashboard@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

## @nhost/docs@2.8.0

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   9f2bf9e: chore: added hasura's authHook settings

## @nhost-examples/cli@0.3.0

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.10

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

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   Updated dependencies [768ca17]
    -   @nhost/react-apollo@11.0.0
    -   @nhost/react@3.4.0

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

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   Updated dependencies [768ca17]
    -   @nhost/react@3.4.0

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

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   Updated dependencies [768ca17]
    -   @nhost/react-urql@8.0.0
    -   @nhost/react@3.4.0

## @nhost-examples/docker-compose@0.4.0

### Minor Changes

-   768ca17: chore: update dependencies

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

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.10

## @nhost-examples/nextjs@0.3.0

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   Updated dependencies [768ca17]
    -   @nhost/react-apollo@11.0.0
    -   @nhost/react@3.4.0
    -   @nhost/nextjs@2.1.9

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

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.10

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

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.10

## @nhost-examples/sveltekit@0.4.0

### Minor Changes

-   768ca17: chore: update dependencies

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

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   863b37d: chore: bump hasura-auth
-   Updated dependencies [768ca17]
    -   @nhost/react-apollo@11.0.0
    -   @nhost/react@3.4.0

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

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   Updated dependencies [768ca17]
    -   @nhost/react@3.4.0

## @nhost-examples/serverless-functions@0.2.0

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   Updated dependencies [768ca17]
    -   @nhost/stripe-graphql-js@1.2.0

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

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   Updated dependencies [768ca17]
    -   @nhost/apollo@6.2.0
    -   @nhost/vue@2.5.0
    -   @nhost/nhost-js@3.0.10

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

### Minor Changes

-   768ca17: chore: update dependencies

### Patch Changes

-   Updated dependencies [768ca17]
    -   @nhost/apollo@6.2.0
    -   @nhost/vue@2.5.0

## @nhost/docgen@0.3.0

### Minor Changes

-   768ca17: chore: update dependencies

## @nhost/sync-versions@0.2.0

### Minor Changes

-   768ca17: chore: update dependencies

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hassan Ben Jobrane <hsanbenjobrane@gmail.com>
2024-04-03 13:29:25 +01:00
Hassan Ben Jobrane
91c2bb6f53 feat: dashboard: restrict signup/signin to verified emails only (#2610)
resolves https://github.com/nhost/nhost/issues/2585
2024-04-03 12:52:47 +01:00
David Barroso
9f2bf9ec2b chore (docs): added hasura's authHook settings (#2630) 2024-04-03 09:01:28 +02:00
Nuno Pato
d62bd0fc9a fix: dashboard: SQL editor "track this" (#2626)
fixes https://github.com/nhost/nhost/issues/2625

---------

Co-authored-by: Hassan Ben Jobrane <hsanbenjobrane@gmail.com>
2024-04-02 16:50:26 +00:00
github-actions[bot]
768ca17494 [Scheduled] Update dependencies (#2627)
Dependencies updated

Note - If you see this PR and the checks haven't run, close and reopen
the PR. See
https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#triggering-further-workflow-runs

---------

Co-authored-by: dbarrosop <dbarrosop@users.noreply.github.com>
Co-authored-by: Hassan Ben Jobrane <hsanbenjobrane@gmail.com>
2024-04-02 16:44:24 +01:00
Hassan Ben Jobrane
943831fe2e fix: await unpauseApplication promise (#2621)
fixes https://github.com/nhost/nhost/issues/2620
2024-03-26 09:29:10 +01:00
Hassan Ben Jobrane
f242e4b92f feat: connect with github (#2616)
fixes https://github.com/nhost/nhost/issues/2581
2024-03-25 13:22:15 +01:00
David Barroso
863b37d313 chore (examples/apollo): bump hasura-auth (#2617) 2024-03-23 12:07:22 +01:00
github-actions[bot]
c8a8d4fca3 chore: update versions (#2609)
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/hasura-auth-js@2.4.0

### Minor Changes

- 311374e: fix: ensure that the user remains signed in even after being
redirected with an error following an attempt to connect with a social
provider

### Patch Changes

-   1623e9b: chore: update `@simplewebauthn/browser` to `9.0.1`

## @nhost/vue@2.4.0

### Minor Changes

-   311374e: feat: add `connect` param to `useProviderLink` hook

### Patch Changes

-   @nhost/nhost-js@3.0.10

## @nhost/apollo@6.1.2

### Patch Changes

-   @nhost/nhost-js@3.0.10

## @nhost/react-apollo@10.0.2

### Patch Changes

-   Updated dependencies [311374e]
    -   @nhost/react@3.3.2
    -   @nhost/apollo@6.1.2

## @nhost/react-urql@7.0.2

### Patch Changes

-   Updated dependencies [311374e]
    -   @nhost/react@3.3.2

## @nhost/nextjs@2.1.8

### Patch Changes

-   Updated dependencies [311374e]
    -   @nhost/react@3.3.2

## @nhost/nhost-js@3.0.10

### Patch Changes

-   Updated dependencies [1623e9b]
-   Updated dependencies [311374e]
    -   @nhost/hasura-auth-js@2.4.0

## @nhost/react@3.3.2

### Patch Changes

-   311374e: feat: add `connect` param to `useProviderLink` hook
    -   @nhost/nhost-js@3.0.10

## @nhost-examples/docker-compose@0.3.0

### Minor Changes

- e40a452: chore: clarification on greyed-out options in the dashboard
when self-hosting

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

### Minor Changes

- 311374e: feat: add example of how to connect a social auth provider to
an existing account

### Patch Changes

-   Updated dependencies [311374e]
    -   @nhost/react@3.3.2
    -   @nhost/react-apollo@10.0.2

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

### Minor Changes

- 311374e: feat: add example of how to connect a social auth provider to
an existing account

### Patch Changes

-   Updated dependencies [311374e]
    -   @nhost/vue@2.4.0
    -   @nhost/nhost-js@3.0.10
    -   @nhost/apollo@6.1.2

## @nhost/dashboard@1.11.2

### Patch Changes

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

## @nhost/docs@2.7.2

### Patch Changes

-   5c47e8e: feat: added hasura's stringifyNumericTypes setting

## @nhost-examples/cli@0.2.2

### Patch Changes

-   @nhost/nhost-js@3.0.10

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

### Patch Changes

-   Updated dependencies [311374e]
    -   @nhost/react@3.3.2
    -   @nhost/react-apollo@10.0.2

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

### Patch Changes

-   Updated dependencies [311374e]
    -   @nhost/react@3.3.2

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

### Patch Changes

-   Updated dependencies [311374e]
    -   @nhost/react@3.3.2
    -   @nhost/react-urql@7.0.2

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

### Patch Changes

-   @nhost/nhost-js@3.0.10

## @nhost-examples/nextjs@0.2.2

### Patch Changes

-   Updated dependencies [311374e]
    -   @nhost/react@3.3.2
    -   @nhost/react-apollo@10.0.2
    -   @nhost/nextjs@2.1.8

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

### Patch Changes

-   @nhost/nhost-js@3.0.10

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

### Patch Changes

-   @nhost/nhost-js@3.0.10

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

### Patch Changes

-   Updated dependencies [311374e]
    -   @nhost/react@3.3.2

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

### Patch Changes

-   Updated dependencies [311374e]
    -   @nhost/vue@2.4.0
    -   @nhost/apollo@6.1.2

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-03-21 17:54:02 +01:00
Hassan Ben Jobrane
311374e3fb feat: react-apollo: add example of how to connect github to an existing account (#2615)
fixes https://github.com/nhost/nhost/issues/2582
2024-03-21 17:38:54 +01:00
Seth Deegan
e40a4529b4 chore (examples/docker-compose): clarification on greyed-out options in the dashboard when self-hosting (#2564) 2024-03-18 11:03:10 +01:00
Hassan Ben Jobrane
1623e9bd20 chore: hasura-auth-js: upgrade @simplewebauthn/browser to 9.0.1 (#2611)
fixes https://github.com/nhost/nhost/issues/2597
2024-03-13 17:25:29 +01:00
David Barroso
5c47e8e675 feat (docs): added hasura's stringifyNumericTypes setting (#2608) 2024-03-12 11:29:53 +01:00
github-actions[bot]
9f9f1c64f4 chore: update versions (#2605)
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@1.11.1

### Patch Changes

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

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-03-11 11:02:17 +01:00
Hassan Ben Jobrane
981404f0b9 fix(dashboard): set default value for healthCheck field validation (#2604) 2024-03-11 10:45:33 +01:00
github-actions[bot]
4ad27e9d72 chore: update versions (#2599)
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@6.1.1

### Patch Changes

-   @nhost/nhost-js@3.0.9

## @nhost/react-apollo@10.0.1

### Patch Changes

-   @nhost/apollo@6.1.1
-   @nhost/react@3.3.1

## @nhost/react-urql@7.0.1

### Patch Changes

-   @nhost/react@3.3.1

## @nhost/stripe-graphql-js@1.1.1

### Patch Changes

-   7789469: chore: address linter errors and remove unnecessary imports

## @nhost/graphql-js@0.1.9

### Patch Changes

- 7789469: fix: resolve process is undefined error when running with
vitejs

## @nhost/nextjs@2.1.7

### Patch Changes

-   @nhost/react@3.3.1

## @nhost/nhost-js@3.0.9

### Patch Changes

-   Updated dependencies [7789469]
    -   @nhost/graphql-js@0.1.9

## @nhost/react@3.3.1

### Patch Changes

-   @nhost/nhost-js@3.0.9

## @nhost/vue@2.3.1

### Patch Changes

-   @nhost/nhost-js@3.0.9

## @nhost/dashboard@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

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

### Minor Changes

- 7789469: chore: upgrade dependency `@graphql-codegen/cli` to `5.0.2`
to address vulnerability

### Patch Changes

-   @nhost/react@3.3.1
-   @nhost/react-apollo@10.0.1

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

### Minor Changes

- 7789469: chore: upgrade dependency `@graphql-codegen/cli` to `5.0.2`
to address vulnerability

### Patch Changes

-   @nhost/react@3.3.1

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

### Minor Changes

- 7789469: chore: upgrade dependency `@graphql-codegen/cli` to `5.0.2`
to address vulnerability

### Patch Changes

-   @nhost/react@3.3.1
-   @nhost/react-urql@7.0.1

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

### Minor Changes

- 7789469: chore: upgrade dependency `@graphql-codegen/cli` to `5.0.2`
to address vulnerability

### Patch Changes

-   @nhost/react@3.3.1
-   @nhost/react-apollo@10.0.1

## @nhost-examples/cli@0.2.1

### Patch Changes

-   @nhost/nhost-js@3.0.9

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

### Patch Changes

-   @nhost/nhost-js@3.0.9

## @nhost-examples/nextjs@0.2.1

### Patch Changes

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

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

### Patch Changes

-   @nhost/nhost-js@3.0.9

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

### Patch Changes

-   @nhost/nhost-js@3.0.9

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

### Patch Changes

-   @nhost/react@3.3.1

## @nhost-examples/serverless-functions@0.1.1

### Patch Changes

-   Updated dependencies [7789469]
    -   @nhost/stripe-graphql-js@1.1.1

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

### Patch Changes

-   7789469: chore: address linter errors and remove unnecessary imports
    -   @nhost/nhost-js@3.0.9
    -   @nhost/apollo@6.1.1
    -   @nhost/vue@2.3.1

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

### Patch Changes

-   @nhost/apollo@6.1.1
-   @nhost/vue@2.3.1

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-03-08 15:51:16 +01:00
Hassan Ben Jobrane
778946998a fix: graphql-js: resolve process is undefined error when running with vitejs (#2601)
fixes https://github.com/nhost/nhost/issues/2600
2024-03-08 15:23:13 +01:00
Hassan Ben Jobrane
6c11b75807 feat: dashboard: add update user displayName section in account settings (#2598)
fixes https://github.com/nhost/nhost/issues/1489
2024-03-07 17:23:35 +01:00
github-actions[bot]
2dc031d16c chore: update versions (#2592)
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-examples/react-apollo@0.5.0

### Minor Changes

- 08a7dd9: feat: add example workaround to the reset password ticket
expired issue

### Patch Changes

- f0a994a: fix: update allowedUrls and redirectTo to point to the
profile page

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

### Minor Changes

- 08a7dd9: feat: add example workaround to the reset password ticket
expired issue

### Patch Changes

- f0a994a: fix: update allowedUrls and redirectTo to point to the
profile page

## @nhost/docs@2.7.1

### Patch Changes

-   6cb2b63: feat: added nhost run env documentation
-   40bd3e4: fix: fixed wrong links in documentation

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-03-06 16:56:26 +01:00
Nicolas Bourdin
40bd3e4572 doc(link): fix wrong links in documentation (#2596)
Co-authored-by: Nicolas Bourdin <nicolas@epeak.co>
Co-authored-by: David Barroso <dbarrosop@dravetech.com>
2024-03-06 14:50:32 +01:00
David Barroso
6cb2b6331a feat (docs): added nhost run env documentation (#2594) 2024-03-06 14:13:02 +01:00
Hassan Ben Jobrane
08a7dd9894 feat(examples): add reset password ticket expired workarounds in the examples (#2590)
fixes https://github.com/nhost/nhost/issues/2314
2024-03-05 15:48:46 +01:00
Hassan Ben Jobrane
f0a994a26e fix(examples): update allowedUrls and redirectTo to point to /profile (#2591) 2024-03-05 14:17:01 +01:00
Hassan Ben Jobrane
4fbd6bd4fa chore: fix release with missing changeset (#2588)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-03-04 16:51:57 +01:00
github-actions[bot]
67fc77486c chore: update versions (#2578)
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@6.1.0

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.8

## @nhost/google-translation@0.1.0

### Minor Changes

-   49a80c2: chore: update dependencies

## @nhost/react-apollo@10.0.0

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   Updated dependencies [49a80c2]
    -   @nhost/apollo@6.1.0
    -   @nhost/react@3.3.0

## @nhost/react-urql@7.0.0

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   Updated dependencies [49a80c2]
    -   @nhost/react@3.3.0

## @nhost/stripe-graphql-js@1.1.0

### Minor Changes

-   49a80c2: chore: update dependencies

## @nhost/react@3.3.0

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.8

## @nhost/vue@2.3.0

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.8

## @nhost/nextjs@2.1.6

### Patch Changes

-   Updated dependencies [49a80c2]
    -   @nhost/react@3.3.0

## @nhost/dashboard@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

## @nhost/docs@2.7.0

### Minor Changes

-   49a80c2: chore: update dependencies

## @nhost-examples/cli@0.2.0

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.8

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

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   Updated dependencies [49a80c2]
    -   @nhost/react-apollo@10.0.0
    -   @nhost/react@3.3.0

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

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   Updated dependencies [49a80c2]
    -   @nhost/react@3.3.0

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

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   Updated dependencies [49a80c2]
    -   @nhost/react-urql@7.0.0
    -   @nhost/react@3.3.0

## @nhost-examples/docker-compose@0.2.0

### Minor Changes

-   49a80c2: chore: update dependencies

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

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.8

## @nhost-examples/nextjs@0.2.0

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   Updated dependencies [49a80c2]
    -   @nhost/react-apollo@10.0.0
    -   @nhost/react@3.3.0
    -   @nhost/nextjs@2.1.6

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

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.8

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

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   @nhost/nhost-js@3.0.8

## @nhost-examples/sveltekit@0.3.0

### Minor Changes

-   49a80c2: chore: update dependencies

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

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

- 4f3fb34: fix: set redirectTo when doing sign in with github and
include vercel previews in allowed redirect URLs
-   Updated dependencies [49a80c2]
    -   @nhost/react-apollo@10.0.0
    -   @nhost/react@3.3.0

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

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   Updated dependencies [49a80c2]
    -   @nhost/react@3.3.0

## @nhost-examples/serverless-functions@0.1.0

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   Updated dependencies [49a80c2]
    -   @nhost/stripe-graphql-js@1.1.0

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

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

- 4f3fb34: fix: set redirectTo when doing sign in with github and
include vercel previews in allowed redirect URLs
-   Updated dependencies [49a80c2]
    -   @nhost/apollo@6.1.0
    -   @nhost/vue@2.3.0
    -   @nhost/nhost-js@3.0.8

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

### Minor Changes

-   49a80c2: chore: update dependencies

### Patch Changes

-   Updated dependencies [49a80c2]
    -   @nhost/apollo@6.1.0
    -   @nhost/vue@2.3.0

## @nhost/docgen@0.2.0

### Minor Changes

-   49a80c2: chore: update dependencies

## @nhost/sync-versions@0.1.0

### Minor Changes

-   49a80c2: chore: update dependencies

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hassan Ben Jobrane <hsanbenjobrane@gmail.com>
2024-03-04 16:16:06 +01:00
Hassan Ben Jobrane
4f3fb3446e fix: set redirectTo in oauth examples (#2586) 2024-03-04 15:33:24 +01:00
Hassan Ben Jobrane
49a80c22be chore: add changeset (#2584)
adds missing changeset for this PR
https://github.com/nhost/nhost/pull/2574
2024-03-04 13:52:38 +01:00
Hassan Ben Jobrane
28676f4cdc feat: dashboard: add min postgres version check to enable the ai service (#2576)
fixes https://github.com/nhost/nhost/issues/2439
2024-03-02 22:33:49 +01:00
Hassan Ben Jobrane
e03f14133c fix: dashboard: refactor database datagrid to allow insert/update/delete for tables auth and storage (#2577)
fixes https://github.com/nhost/nhost/issues/2476
2024-03-02 22:04:23 +01:00
Hassan Ben Jobrane
150c04a4f4 feat: dashboard: add healthcheck config to run services (#2575)
fixes https://github.com/nhost/nhost/issues/2410
2024-03-02 19:28:13 +01:00
github-actions[bot]
bccd67b1b1 [Scheduled] Update dependencies (#2574)
Dependencies updated

Note - If you see this PR and the checks haven't run, close and reopen
the PR. See
https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#triggering-further-workflow-runs

---------

Co-authored-by: David Barroso <dbarrosop@dravetech.com>
Co-authored-by: dbarrosop <dbarrosop@users.noreply.github.com>
Co-authored-by: Hassan Ben Jobrane <hsanbenjobrane@gmail.com>
2024-03-02 18:40:03 +01:00
David Barroso
b14fd2f14c chore: fix role to assume in gen update dependencies (#2573) 2024-03-01 12:21:38 +01:00
github-actions[bot]
68b3d23cd9 chore: update versions (#2572)
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@1.9.0

### Minor Changes

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

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-02-29 17:54:02 +01:00
Hassan Ben Jobrane
d86e5c9c16 feat(dashboard): query services list from be and filter the logs using a regex (#2552)
fixes: https://github.com/nhost/nhost/issues/2391
2024-02-29 17:38:38 +01:00
github-actions[bot]
b2cc1411d7 chore: update versions (#2571)
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@6.0.8

### Patch Changes

-   @nhost/nhost-js@3.0.8

## @nhost/react-apollo@9.0.3

### Patch Changes

-   @nhost/apollo@6.0.8
-   @nhost/react@3.2.3

## @nhost/react-urql@6.0.3

### Patch Changes

-   @nhost/react@3.2.3

## @nhost/graphql-js@0.1.8

### Patch Changes

- 407feea: fix: replace `jwt-decode` with `jose` to decode access tokens
in a non browser environment

## @nhost/nextjs@2.1.5

### Patch Changes

-   @nhost/react@3.2.3

## @nhost/nhost-js@3.0.8

### Patch Changes

-   Updated dependencies [407feea]
    -   @nhost/graphql-js@0.1.8

## @nhost/react@3.2.3

### Patch Changes

-   @nhost/nhost-js@3.0.8

## @nhost/vue@2.2.3

### Patch Changes

-   @nhost/nhost-js@3.0.8

## @nhost/dashboard@1.8.3

### Patch Changes

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

## @nhost-examples/cli@0.1.9

### Patch Changes

-   @nhost/nhost-js@3.0.8

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

### Patch Changes

-   @nhost/react@3.2.3
-   @nhost/react-apollo@9.0.3

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

### Patch Changes

-   @nhost/react@3.2.3

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

### Patch Changes

-   @nhost/react@3.2.3
-   @nhost/react-urql@6.0.3

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

### Patch Changes

-   @nhost/nhost-js@3.0.8

## @nhost-examples/nextjs@0.1.19

### Patch Changes

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

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

### Patch Changes

-   @nhost/nhost-js@3.0.8

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

### Patch Changes

-   @nhost/nhost-js@3.0.8

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

### Patch Changes

-   @nhost/react@3.2.3
-   @nhost/react-apollo@9.0.3

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

### Patch Changes

-   @nhost/react@3.2.3

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

### Patch Changes

-   @nhost/nhost-js@3.0.8
-   @nhost/apollo@6.0.8
-   @nhost/vue@2.2.3

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

### Patch Changes

-   @nhost/apollo@6.0.8
-   @nhost/vue@2.2.3

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-02-29 15:43:48 +01:00
Hassan Ben Jobrane
407feeac37 fix: sdk: graphql-js: replace jwt-decode with jose to decode access tokens in both node and the browser (#2570) 2024-02-29 14:51:33 +01:00
github-actions[bot]
7b25c37c26 chore: update versions (#2569)
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@1.8.2

### Patch Changes

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

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-02-29 13:10:09 +01:00
Hassan Ben Jobrane
6df4f02e95 fix(dashboard): show correct message when sending invite fails (#2567) 2024-02-29 12:52:25 +01:00
github-actions[bot]
aaae98f019 chore: update versions (#2559)
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/docs@2.6.0

### Minor Changes

-   dc23dc0: fix: docs run references

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-02-25 23:02:36 -01:00
Nuno Pato
dc23dc0f49 fix: docs run references (#2558) 2024-02-25 22:47:38 -01:00
github-actions[bot]
82728da100 chore: update versions (#2556)
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@6.0.7

### Patch Changes

-   @nhost/nhost-js@3.0.7

## @nhost/react-apollo@9.0.2

### Patch Changes

-   @nhost/apollo@6.0.7
-   @nhost/react@3.2.2

## @nhost/react-urql@6.0.2

### Patch Changes

-   @nhost/react@3.2.2

## @nhost/graphql-js@0.1.7

### Patch Changes

- 2d68fee: fix: resolve an issue where unauthenticated graphql requests
are not sent

## @nhost/nextjs@2.1.4

### Patch Changes

-   @nhost/react@3.2.2

## @nhost/nhost-js@3.0.7

### Patch Changes

-   Updated dependencies [2d68fee]
    -   @nhost/graphql-js@0.1.7

## @nhost/react@3.2.2

### Patch Changes

-   @nhost/nhost-js@3.0.7

## @nhost/vue@2.2.2

### Patch Changes

-   @nhost/nhost-js@3.0.7

## @nhost/dashboard@1.8.1

### Patch Changes

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

## @nhost-examples/cli@0.1.8

### Patch Changes

-   @nhost/nhost-js@3.0.7

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

### Patch Changes

-   @nhost/react@3.2.2
-   @nhost/react-apollo@9.0.2

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

### Patch Changes

-   @nhost/react@3.2.2

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

### Patch Changes

-   @nhost/react@3.2.2
-   @nhost/react-urql@6.0.2

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

### Patch Changes

-   @nhost/nhost-js@3.0.7

## @nhost-examples/nextjs@0.1.18

### Patch Changes

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

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

### Patch Changes

-   @nhost/nhost-js@3.0.7

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

### Patch Changes

-   @nhost/nhost-js@3.0.7

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

### Patch Changes

-   @nhost/react@3.2.2
-   @nhost/react-apollo@9.0.2

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

### Patch Changes

-   @nhost/react@3.2.2

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

### Patch Changes

-   @nhost/nhost-js@3.0.7
-   @nhost/apollo@6.0.7
-   @nhost/vue@2.2.2

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

### Patch Changes

-   @nhost/apollo@6.0.7
-   @nhost/vue@2.2.2

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-02-23 21:14:11 +01:00
Hassan Ben Jobrane
2d68fee54c fix(graphql-js): allow graphql requests with no access token (#2555) 2024-02-23 21:09:45 +01:00
github-actions[bot]
35010353c7 chore: update versions (#2547)
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@6.0.6

### Patch Changes

-   e0ab6d9: fix: add extra logic to check and wait for a valid JWT
    -   @nhost/nhost-js@3.0.6

## @nhost/react-apollo@9.0.1

### Patch Changes

-   Updated dependencies [e0ab6d9]
    -   @nhost/apollo@6.0.6
    -   @nhost/react@3.2.1

## @nhost/react-urql@6.0.1

### Patch Changes

-   @nhost/react@3.2.1

## @nhost/graphql-js@0.1.6

### Patch Changes

-   e0ab6d9: fix: add extra logic to check and wait for a valid JWT

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

### Patch Changes

- 7baee8a: fix(hasura-auth-js): replace `jwt-decode` with `jose` for
decoding access tokens that works on both the browser and Node.js
-   e0ab6d9: fix: add extra logic to check and wait for a valid JWT

## @nhost/nextjs@2.1.3

### Patch Changes

-   @nhost/react@3.2.1

## @nhost/nhost-js@3.0.6

### Patch Changes

-   Updated dependencies [7baee8a]
-   Updated dependencies [e0ab6d9]
    -   @nhost/hasura-auth-js@2.3.1
    -   @nhost/graphql-js@0.1.6

## @nhost/react@3.2.1

### Patch Changes

-   @nhost/nhost-js@3.0.6

## @nhost/vue@2.2.1

### Patch Changes

-   @nhost/nhost-js@3.0.6

## @nhost/dashboard@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

## @nhost-examples/cli@0.1.7

### Patch Changes

-   @nhost/nhost-js@3.0.6

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

### Patch Changes

-   @nhost/react-apollo@9.0.1
-   @nhost/react@3.2.1

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

### Patch Changes

-   @nhost/react@3.2.1

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

### Patch Changes

-   @nhost/react@3.2.1
-   @nhost/react-urql@6.0.1

## @nhost-examples/docker-compose@0.1.1

### Patch Changes

-   aff059e: fix: timers

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

### Patch Changes

-   @nhost/nhost-js@3.0.6

## @nhost-examples/nextjs@0.1.17

### Patch Changes

-   @nhost/react-apollo@9.0.1
-   @nhost/react@3.2.1
-   @nhost/nextjs@2.1.3

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

### Patch Changes

-   @nhost/nhost-js@3.0.6

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

### Patch Changes

-   @nhost/nhost-js@3.0.6

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

### Patch Changes

-   @nhost/react-apollo@9.0.1
-   @nhost/react@3.2.1

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

### Patch Changes

-   @nhost/react@3.2.1

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

### Patch Changes

-   Updated dependencies [e0ab6d9]
    -   @nhost/apollo@6.0.6
    -   @nhost/nhost-js@3.0.6
    -   @nhost/vue@2.2.1

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

### Patch Changes

-   Updated dependencies [e0ab6d9]
    -   @nhost/apollo@6.0.6
    -   @nhost/vue@2.2.1

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-02-23 10:07:53 +01:00
David Barroso
aff059ec71 fix (examples/docker-compose): timers (#2553) 2024-02-23 10:04:20 +01:00
Nuno Pato
713d53cfc0 feat: dashboard: add catch-all route (#2545) 2024-02-22 17:59:24 -01:00
Hassan Ben Jobrane
e0ab6d9a37 fix: JWT expired bug (#2533)
fixes: https://github.com/nhost/nhost/issues/2348

---------

Co-authored-by: David Barroso <dbarrosop@dravetech.com>
2024-02-22 18:44:43 +01:00
Hassan Ben Jobrane
7baee8a9cc fix(hasura-auth-js): use jose instead of jwt-decode to decode the accessToken and get the Hasura claims (#2550)
fixes https://github.com/nhost/nhost/issues/2513
2024-02-21 11:17:03 +01:00
Hassan Ben Jobrane
3db2999f60 fix(dashboard): refresh table list after running a SQL stmt using the editor (#2549)
fixes https://github.com/nhost/projects/issues/52
2024-02-20 13:40:46 +01:00
Hassan Ben Jobrane
3c4dd55045 fix(dashboard): handle Error alongside ApolloError properly in the ErrorToast component (#2548)
fixes https://github.com/nhost/nhost/issues/2525
2024-02-20 12:16:26 +01:00
Hassan Ben Jobrane
92b434e840 fix: refactor DataGridHeader component to allow for selecting all rows (#2546)
fixes https://github.com/nhost/nhost/issues/2526
2024-02-19 17:30:59 +01:00
github-actions[bot]
13d359602f chore: update versions (#2540)
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@1.7.0

### Minor Changes

-   0d8d0eb: Update docs and dashboard references

## @nhost/docs@2.5.0

### Minor Changes

-   0d8d0eb: Update docs and dashboard references

### Patch Changes

-   41617b9: feat: added elevated permissions docs
- 7db095f: chore: added a note about disk performance and CDN
information

## @nhost-examples/docker-compose@0.1.0

### Minor Changes

-   ed9df85: updated docker-compose.yaml and .env-example

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

### Patch Changes

-   c5c904b: fix: update signin methods settings

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-02-16 20:44:28 -01:00
Nuno Pato
0d8d0eb10f chore: update docs and fix dashboard references (#2543) 2024-02-16 18:21:30 -01:00
Seth Deegan
ed9df85778 Update docker-compose and .env-example (#2397)
The docker-compose example is severely outdated and the past
configuration used a docker image for the dashboard that did not allow
you to configure the URLs to the various API endpoints if you
self-hosted your own dashboard publicly.

The newest dashboard image allows you to do this so the docker-compose
has been updated to use this image and the env variables have been
updated accordingly.

Other variables have been updated in the docker-compose to support
self-hosting a public instance.

A commented traefik configuration in the docker-compose for the
dashboard service also allows the user to configure basic auth to
protect a publicly-facing dashboard.

---------

Co-authored-by: David Barroso <dbarrosop@dravetech.com>
Co-authored-by: Hassan Ben Jobrane <hsanbenjobrane@gmail.com>
2024-02-16 08:52:58 +01:00
David Barroso
41617b970a feat (docs): added elevated permissions docs (#2519)
Co-authored-by: Nuno Pato <nunopato@gmail.com>
2024-02-15 16:00:44 +01:00
Hassan Ben Jobrane
c5c904b716 fix(vue-apollo): update signin methods settings (#2541) 2024-02-15 13:48:41 +01:00
David Barroso
7db095fe92 chore: docs: added a note about disk performance and CDN information (#2539)
Fixes #2504
2024-02-15 11:47:33 +01:00
481 changed files with 16746 additions and 7999 deletions

View File

@@ -22,7 +22,7 @@ jobs:
- name: Configure aws
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_PRODUCTION_CORE_ACCOUNT_ID }}:role/github-actions-nhost-be
role-to-assume: arn:aws:iam::${{ secrets.AWS_PRODUCTION_CORE_ACCOUNT_ID }}:role/github-actions-nhost-${{ github.event.repository.name }}
aws-region: eu-central-1
- uses: nixbuild/nix-quick-install-action@v26

3
config/.husky/pre-commit Executable file → Normal file
View File

@@ -1,4 +1,7 @@
#!/bin/sh
#
[ -n "$CI" ] && exit 0
. "$(dirname "$0")/_/husky.sh"
pnpm dlx lint-staged --config config/.lintstagedrc.js

View File

@@ -1,5 +1,187 @@
# @nhost/dashboard
## 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

View File

@@ -28,6 +28,7 @@ ENV NEXT_PUBLIC_NHOST_STORAGE_URL __NEXT_PUBLIC_NHOST_STORAGE_URL__
ENV NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL __NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL__
ENV NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL __NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL__
ENV NEXT_PUBLIC_NHOST_HASURA_API_URL __NEXT_PUBLIC_NHOST_HASURA_API_URL__
ENV NEXT_PUBLIC_NHOST_CONFIGSERVER_URL __NEXT_PUBLIC_NHOST_CONFIGSERVER_URL__
RUN yarn global add pnpm@8.10.5
COPY .gitignore .gitignore

View File

@@ -21,5 +21,6 @@ find dashboard -type f -exec sed -i "s~__NEXT_PUBLIC_NHOST_STORAGE_URL__~${NEXT_
find dashboard -type f -exec sed -i "s~__NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL__~${NEXT_PUBLIC_NHOST_HASURA_CONSOLE_URL}~g" {} +
find dashboard -type f -exec sed -i "s~__NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL__~${NEXT_PUBLIC_NHOST_HASURA_MIGRATIONS_API_URL}~g" {} +
find dashboard -type f -exec sed -i "s~__NEXT_PUBLIC_NHOST_HASURA_API_URL__~${NEXT_PUBLIC_NHOST_HASURA_API_URL}~g" {} +
find dashboard -type f -exec sed -i "s~__NEXT_PUBLIC_NHOST_CONFIGSERVER_URL__~${NEXT_PUBLIC_NHOST_CONFIGSERVER_URL}~g" {} +
exec "$@"

View File

@@ -0,0 +1,2 @@
.secrets
.nhost

View File

@@ -0,0 +1 @@
version: 3

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Потвърдете смяната на вашия имейл</h2>
<p>Използвайте посочения линк, за да повърдите смяната на имейл:</p>
<p>
<a href="${link}">
Смени имейл
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Потвърждение за смяна на имейл

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Потвърдете вашия имейл</h2>
<p>Използвайте посочения линк, за да потвърдите вашия имейл:</p>
<p>
<a href="${link}">
Потвърдете имейл
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Потвърждаване на имейл

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Смяна на парола</h2>
<p>Използвайте посочения линк, за да смените вашата парола:</p>
<p>
<a href="${link}">
Смяна на парола
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Смяна на парола

View File

@@ -0,0 +1 @@
Вашият код е ${code}.

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Магически линк за вход</h2>
<p>Използвайте посочения линк за защитен и бърз вход:</p>
<p>
<a href="${link}">
Вход
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Магически линк за вход

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Potvrzení změny emailové adresy</h2>
<p>Použijte tento odkaz k potvrzení změny emailové adresy:</p>
<p>
<a href="${link}">
Změnit email
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Změna vaší emailové adresy

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Ověření emailové adresy</h2>
<p>Použijte tento odkaz k ověření vaší emailové adresy:</p>
<p>
<a href="${link}">
Ověřit emailovou adresu
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Ověření vaší emailové adresy

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Obnova hesla</h2>
<p>Použijte tento odkaz k obnovení vašeho hesla:</p>
<p>
<a href="${link}">
Obnova hesla
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Obnova hesla

View File

@@ -0,0 +1 @@
Váš kód je ${code}.

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Magický odkaz</h2>
<p>Použijte tento odkaz k bezpečnému přihlášení:</p>
<p>
<a href="${link}">
Přihlášení
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Bezpečný odkaz k přihlášení

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Confirm Email Change</h2>
<p>Use this link to confirm changing email:</p>
<p>
<a href="${link}">
Change email
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Change your email address

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Verify Email</h2>
<p>Use this link to verify your email:</p>
<p>
<a href="${link}">
Verify Email
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Verify your email

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Reset Password</h2>
<p>Use this link to reset your password:</p>
<p>
<a href="${link}">
Reset password
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Reset your password

View File

@@ -0,0 +1 @@
Your code is ${code}.

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Magic Link</h2>
<p>Use this link to securely sign in:</p>
<p>
<a href="${link}">
Sign In
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Secure sign-in link

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Confirmar cambio de correo electrónico</h2>
<p>Utiliza el siguiente enlace para confirmar el cambio de correo:</p>
<p>
<a href="${link}">
Cambiar correo electrónico
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Cambiar dirección de correo electrónico

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Verificar correo electrónico</h2>
<p>Utilza el siguiente enlace para verificar tu correo:</p>
<p>
<a href="${link}">
Verificar correo electrónico
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Verifica tu correo electrónico

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Recuperar contraseña</h2>
<p>Utiliza el siguiente enlace para recuperar tu contraseña:</p>
<p>
<a href="${link}">
Recuperar contraseña
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Recuperar contraseña

View File

@@ -0,0 +1 @@
Tu código es ${code}.

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Enlace mágico</h2>
<p>Utiliza este enlace para iniciar sesión de forma segura:</p>
<p>
<a href="${link}">
Iniciar sesión
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Enlace de acceso seguro

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Confirmer changement de courriel</h2>
<p>Utilisez ce lien pour confirmer le changement de courriel :</p>
<p>
<a href="${link}">
Changer courriel
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Changez votre adresse courriel

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>V&eacute;rifiez votre courriel</h2>
<p>Utilisez ce lien pour v&eacute;rifier votre courriel :</p>
<p>
<a href="${link}">
V&eacute;rifier courriel
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Vérifier votre courriel

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>R&eacute;initialiser votre mot de passe</h2>
<p>Utilisez ce lien pour r&eacute;initialiser votre mot de passe :</p>
<p>
<a href="${link}">
R&eacute;initialiser mot de passe
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Réinitialiser votre mot de passe

View File

@@ -0,0 +1 @@
Votre code est ${code}.

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h2>Lien magique</h2>
<p>Utilisez ce lien pour vous connecter de fa&ccedil;on s&eacute;curisée :</p>
<p>
<a href="${link}">
Connexion
</a>
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
Lien de connexion sécurisé

View File

@@ -0,0 +1,8 @@
${link},
${displayName},
${email},
${ticket},
${redirectTo},
${serverUrl},
${clientUrl},
${locale},

View File

@@ -0,0 +1 @@
${link}, ${displayName}, ${email}, ${ticket}, ${redirectTo}, ${serverUrl}, ${clientUrl}, ${locale}

View File

@@ -0,0 +1,151 @@
[global]
[hasura]
version = 'v2.33.4-ce'
adminSecret = '{{ secrets.HASURA_GRAPHQL_ADMIN_SECRET }}'
webhookSecret = '{{ secrets.NHOST_WEBHOOK_SECRET }}'
[[hasura.jwtSecrets]]
type = 'HS256'
key = '{{ secrets.HASURA_GRAPHQL_JWT_SECRET }}'
[hasura.settings]
corsDomain = ['*']
devMode = true
enableAllowList = false
enableConsole = true
enableRemoteSchemaPermissions = false
enabledAPIs = ['metadata', 'graphql', 'pgdump', 'config']
liveQueriesMultiplexedRefetchInterval = 1000
stringifyNumericTypes = false
[hasura.logs]
level = 'warn'
[hasura.events]
httpPoolSize = 100
[functions]
[functions.node]
version = 18
[auth]
version = '0.24.1'
[auth.elevatedPrivileges]
mode = 'disabled'
[auth.redirections]
clientUrl = 'http://localhost:3000'
[auth.signUp]
enabled = true
disableNewUsers = false
[auth.user]
[auth.user.roles]
default = 'user'
allowed = ['user', 'me']
[auth.user.locale]
default = 'en'
allowed = ['en']
[auth.user.gravatar]
enabled = true
default = 'blank'
rating = 'g'
[auth.user.email]
[auth.user.emailDomains]
[auth.session]
[auth.session.accessToken]
expiresIn = 900
[auth.session.refreshToken]
expiresIn = 2592000
[auth.method]
[auth.method.anonymous]
enabled = false
[auth.method.emailPasswordless]
enabled = false
[auth.method.emailPassword]
hibpEnabled = false
emailVerificationRequired = true
passwordMinLength = 9
[auth.method.smsPasswordless]
enabled = false
[auth.method.oauth]
[auth.method.oauth.apple]
enabled = false
[auth.method.oauth.azuread]
tenant = 'common'
enabled = false
[auth.method.oauth.bitbucket]
enabled = false
[auth.method.oauth.discord]
enabled = false
[auth.method.oauth.facebook]
enabled = false
[auth.method.oauth.github]
enabled = false
[auth.method.oauth.gitlab]
enabled = false
[auth.method.oauth.google]
enabled = false
[auth.method.oauth.linkedin]
enabled = false
[auth.method.oauth.spotify]
enabled = false
[auth.method.oauth.strava]
enabled = false
[auth.method.oauth.twitch]
enabled = false
[auth.method.oauth.twitter]
enabled = false
[auth.method.oauth.windowslive]
enabled = false
[auth.method.oauth.workos]
enabled = false
[auth.method.webauthn]
enabled = false
[auth.method.webauthn.attestation]
timeout = 60000
[auth.totp]
enabled = false
[postgres]
version = '14.6-20240129-1'
[provider]
[storage]
version = '0.6.0'
[observability]
[observability.grafana]
adminPassword = '{{ secrets.GRAFANA_ADMIN_PASSWORD }}'

View File

@@ -16,8 +16,6 @@ const cspHeader = `
form-action 'self';
frame-ancestors 'none';
frame-src 'self' js.stripe.com;
block-all-mixed-content;
upgrade-insecure-requests;
`;
module.exports = withBundleAnalyzer({
@@ -42,10 +40,6 @@ module.exports = withBundleAnalyzer({
key: 'X-Frame-Options',
value: 'SAMEORIGIN',
},
{
key: 'Content-Security-Policy',
value: cspHeader.replace(/\n/g, ''),
},
],
},
];

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/dashboard",
"version": "1.6.9",
"version": "1.16.0",
"private": true,
"scripts": {
"preinstall": "npx only-allow pnpm",
@@ -19,58 +19,58 @@
"e2e": "pnpm install-browsers && pnpm playwright test"
},
"dependencies": {
"@apollo/client": "^3.9.4",
"@codemirror/lang-sql": "^6.5.5",
"@apollo/client": "^3.9.9",
"@codemirror/lang-sql": "^6.6.2",
"@emotion/cache": "^11.11.0",
"@emotion/react": "^11.11.3",
"@emotion/react": "^11.11.4",
"@emotion/server": "^11.11.0",
"@emotion/styled": "^11.11.0",
"@fontsource/inter": "^5.0.16",
"@fontsource/roboto-mono": "^5.0.16",
"@graphiql/react": "^0.20.2",
"@emotion/styled": "^11.11.5",
"@fontsource/inter": "^5.0.17",
"@fontsource/roboto-mono": "^5.0.17",
"@graphiql/react": "^0.20.3",
"@graphiql/toolkit": "^0.9.1",
"@headlessui/react": "^1.7.18",
"@heroicons/react": "^1.0.6",
"@hookform/resolvers": "^3.3.4",
"@mui/base": "5.0.0-beta.31",
"@mui/material": "^5.15.7",
"@mui/system": "^5.15.7",
"@mui/material": "^5.15.14",
"@mui/system": "^5.15.14",
"@mui/x-date-pickers": "^5.0.20",
"@nhost/nextjs": "workspace:*",
"@nhost/react-apollo": "workspace:*",
"@segment/snippet": "^4.16.2",
"@stripe/react-stripe-js": "^2.4.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.11.7",
"@tanstack/react-virtual": "^3.0.2",
"@uiw/codemirror-theme-github": "^4.21.21",
"@uiw/react-codemirror": "^4.21.21",
"@tanstack/react-table": "^8.15.3",
"@tanstack/react-virtual": "^3.2.0",
"@uiw/codemirror-theme-github": "^4.21.25",
"@uiw/react-codemirror": "^4.21.25",
"analytics-node": "^6.2.0",
"bcryptjs": "^2.4.3",
"clsx": "^1.2.1",
"date-fns": "^2.30.0",
"framer-motion": "^10.18.0",
"generate-password": "^1.7.1",
"graphiql": "^3.1.0",
"graphiql": "^3.1.1",
"graphql": "16.8.1",
"graphql-request": "^6.1.0",
"graphql-tag": "^2.12.6",
"graphql-ws": "^5.14.3",
"graphql-ws": "^5.16.0",
"just-kebab-case": "^4.2.0",
"lodash.debounce": "^4.0.8",
"next": "^14.1.0",
"next-seo": "^6.4.0",
"next": "^14.1.4",
"next-seo": "^6.5.0",
"node-pg-format": "^1.3.5",
"pluralize": "^8.0.0",
"react": "18.2.0",
"react-children-utilities": "^2.10.0",
"react-dom": "18.2.0",
"react-error-boundary": "^4.0.12",
"react-hook-form": "^7.50.0",
"react-error-boundary": "^4.0.13",
"react-hook-form": "^7.51.2",
"react-hot-toast": "^2.4.1",
"react-intersection-observer": "^9.5.4",
"react-intersection-observer": "^9.8.1",
"react-is": "18.2.0",
"react-loading-skeleton": "^2.2.0",
"react-markdown": "^9.0.1",
@@ -87,13 +87,13 @@
"tailwind-merge": "^1.14.0",
"utility-types": "^3.11.0",
"validator": "^13.11.0",
"yup": "^1.3.3",
"yup": "^1.4.0",
"yup-password": "^0.2.2"
},
"devDependencies": {
"@babel/core": "^7.23.9",
"@babel/core": "^7.24.3",
"@faker-js/faker": "^7.6.0",
"@graphql-codegen/cli": "^3.3.1",
"@graphql-codegen/cli": "^5.0.2",
"@graphql-codegen/typescript": "^3.0.4",
"@graphql-codegen/typescript-operations": "^3.0.4",
"@graphql-codegen/typescript-react-apollo": "^3.3.7",
@@ -106,50 +106,50 @@
"@storybook/addon-postcss": "^2.0.0",
"@storybook/builder-webpack5": "^6.5.16",
"@storybook/manager-webpack5": "^6.5.16",
"@storybook/react": "^7.6.15",
"@storybook/react": "^7.6.17",
"@storybook/testing-library": "^0.2.2",
"@tailwindcss/typography": "^0.5.10",
"@tailwindcss/typography": "^0.5.12",
"@testing-library/dom": "^9.3.4",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^14.2.0",
"@testing-library/react": "^14.2.2",
"@testing-library/user-event": "^14.5.2",
"@types/ace": "^0.0.48",
"@types/bcryptjs": "^2.4.6",
"@types/jest": "^29.5.11",
"@types/jest": "^29.5.12",
"@types/lodash.debounce": "^4.0.9",
"@types/node": "^16.18.78",
"@types/node": "^16.18.93",
"@types/pluralize": "^0.0.30",
"@types/react": "^18.2.50",
"@types/react-dom": "^18.2.18",
"@types/react-table": "^7.7.19",
"@types/react": "^18.2.73",
"@types/react-dom": "^18.2.23",
"@types/react-table": "^7.7.20",
"@types/shell-quote": "^1.7.5",
"@types/testing-library__jest-dom": "^5.14.9",
"@types/validator": "^13.11.8",
"@typescript-eslint/eslint-plugin": "^6.20.0",
"@typescript-eslint/parser": "^6.20.0",
"@types/validator": "^13.11.9",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@vitejs/plugin-react": "^4.2.1",
"@vitest/coverage-v8": "^0.32.4",
"autoprefixer": "^10.4.17",
"autoprefixer": "^10.4.19",
"babel-loader": "^8.3.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"csstype": "^3.1.3",
"dotenv": "^16.4.1",
"dotenv": "^16.4.5",
"encoding": "^0.1.13",
"eslint": "^8.56.0",
"eslint": "^8.57.0",
"eslint-config-airbnb": "19.0.4",
"eslint-config-airbnb-typescript": "^17.1.0",
"eslint-config-next": "^13.5.6",
"eslint-config-prettier": "^8.10.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
"jsdom": "^22.1.0",
"lint-staged": "^15.2.1",
"msw": "^1.3.2",
"lint-staged": "^15.2.2",
"msw": "^1.3.3",
"msw-storybook-addon": "^1.10.0",
"node-fetch": "^3.3.2",
"postcss": "^8.4.33",
"postcss": "^8.4.38",
"prettier": "^2.8.8",
"prettier-plugin-organize-imports": "^3.2.4",
"prettier-plugin-tailwindcss": "^0.4.1",
@@ -157,11 +157,11 @@
"require-from-string": "^2.0.2",
"snake-case": "^3.0.4",
"storybook-addon-next-router": "^4.0.2",
"tailwindcss": "^3.4.1",
"tailwindcss": "^3.4.3",
"ts-node": "^10.9.2",
"tsconfig-paths-webpack-plugin": "^4.1.0",
"vite": "^5.0.12",
"vite-tsconfig-paths": "^4.3.1",
"vite": "^5.2.7",
"vite-tsconfig-paths": "^4.3.2",
"vitest": "^0.32.4"
},
"browserslist": {

View File

@@ -0,0 +1,30 @@
import { useDialog } from '@/components/common/DialogProvider';
import { Button } from '@/components/ui/v2/Button';
import { Text } from '@/components/ui/v2/Text';
export default function ApplyLocalSettingsDialog() {
const { closeDialog } = useDialog();
return (
<div className="flex flex-col gap-4 px-6 pb-6">
<div className="flex flex-col gap-2">
<Text color="secondary">
Run{' '}
<code className="px-1 py-px mx-1 rounded-md bg-slate-500 text-slate-100">
$ nhost up
</code>{' '}
using the cli to apply your changes
</Text>
</div>
<Button
className="w-full"
color="primary"
onClick={() => closeDialog()}
autoFocus
>
OK
</Button>
</div>
);
}

View File

@@ -0,0 +1 @@
export { default as ApplyLocalSettingsDialog } from './ApplyLocalSettingsDialog';

View File

@@ -35,7 +35,7 @@ function InsertPlaceholderTableRow({
...props
}: InsertPlaceholderTableRowProps) {
return (
<Box className="h-12 border-r-1 border-b-1" {...props}>
<Box className="h-12 border-b-1 border-r-1" {...props}>
<Button
onClick={onInsertRow}
variant="borderless"
@@ -209,7 +209,7 @@ export default function DataGridBody<T extends object>({
/>
) : (
<Box
className="inline-flex h-12 items-center border-b-1 border-r-1 py-1.5 px-2 text-xs"
className="inline-flex h-12 items-center border-b-1 border-r-1 px-2 py-1.5 text-xs"
sx={{ color: 'text.secondary' }}
style={{
width: allowInsertColumn
@@ -281,8 +281,8 @@ export default function DataGridBody<T extends object>({
}}
className={twMerge(
'h-12 font-display text-xs motion-safe:transition-colors',
'border-r-1 border-b-1',
'scroll-mt-[57px] scroll-ml-8',
'border-b-1 border-r-1',
'scroll-ml-8 scroll-mt-[57px]',
column.id === 'selection' &&
'sticky left-0 z-20 justify-center px-0',
)}
@@ -296,7 +296,7 @@ export default function DataGridBody<T extends object>({
})}
{allowInsertColumn && (
<Box className="h-12 w-25 border-r-1 border-b-1" />
<Box className="h-12 w-25 border-b-1 border-r-1" />
)}
</div>

View File

@@ -8,7 +8,15 @@ import type {
DataBrowserGridCellProps,
} from '@/features/database/dataGrid/types/dataBrowser';
import { triggerToast } from '@/utils/toast';
import type { FocusEvent, JSXElementConstructor, KeyboardEvent, MouseEvent, ReactElement, ReactNode, ReactPortal } from 'react';
import type {
FocusEvent,
JSXElementConstructor,
KeyboardEvent,
MouseEvent,
ReactElement,
ReactNode,
ReactPortal,
} from 'react';
import {
Children,
cloneElement,
@@ -308,7 +316,7 @@ function DataGridCellContent<TData extends object = {}, TValue = unknown>({
isEditable &&
'focus-within:outline-none focus-within:ring-0 focus:ring-0',
isSelected && 'shadow-outline',
isEditing ? 'p-0.5 shadow-outline-dark' : 'py-1.5 px-2',
isEditing ? 'p-0.5 shadow-outline-dark' : 'px-2 py-1.5',
className,
)}
onFocus={handleFocus}
@@ -320,20 +328,28 @@ function DataGridCellContent<TData extends object = {}, TValue = unknown>({
sx={{ backgroundColor: 'transparent' }}
{...props}
>
{Children.map(children, (child: ReactNode | ReactPortal | ReactElement<unknown, string | JSXElementConstructor<any>>) => {
if (!isValidElement(child)) {
return null;
}
{Children.map(
children,
(
child:
| ReactNode
| ReactPortal
| ReactElement<unknown, string | JSXElementConstructor<any>>,
) => {
if (!isValidElement(child)) {
return null;
}
return cloneElement(child, {
...child.props,
onSave: handleSave,
optimisticValue,
onOptimisticValueChange: setOptimisticValue,
temporaryValue,
onTemporaryValueChange: setTemporaryValue,
});
})}
return cloneElement(child, {
...child.props,
onSave: handleSave,
optimisticValue,
onOptimisticValueChange: setOptimisticValue,
temporaryValue,
onTemporaryValueChange: setTemporaryValue,
});
},
)}
</Box>
);

View File

@@ -96,45 +96,52 @@ export default function DataGridHeader<T extends object>({
}}
key={column.id}
>
<Dropdown.Trigger
className={twMerge(
'focus:outline-none motion-safe:transition-colors',
)}
disabled={
column.isDisabled ||
column.id === 'selection' ||
(column.disableSortBy && !onRemoveColumn)
}
hideChevron
>
{column.id === 'selection' ? (
<span
{...headerProps}
className="relative grid w-full grid-flow-col items-center justify-between p-2"
>
{column.render('Header')}
{allowSort && (
<Box component="span" sx={{ color: 'text.primary' }}>
{column.isSorted && !column.isSortedDesc && (
<ArrowUpIcon className="h-3 w-3" />
)}
{column.isSorted && column.isSortedDesc && (
<ArrowDownIcon className="h-3 w-3" />
)}
</Box>
)}
</span>
{allowResize && !column.disableResizing && (
) : (
<Dropdown.Trigger
className={twMerge(
'focus:outline-none motion-safe:transition-colors',
)}
disabled={
column.isDisabled || (column.disableSortBy && !onRemoveColumn)
}
hideChevron
>
<span
{...column.getResizerProps({
onClick: (event: Event) => event.stopPropagation(),
})}
className="absolute top-0 bottom-0 -right-0.5 z-10 h-full w-1.5 group-hover:bg-slate-900 group-hover:bg-opacity-20 group-active:bg-slate-900 group-active:bg-opacity-20 motion-safe:transition-colors"
/>
)}
</Dropdown.Trigger>
{...headerProps}
className="relative grid w-full grid-flow-col items-center justify-between p-2"
>
{column.render('Header')}
{allowSort && (
<Box component="span" sx={{ color: 'text.primary' }}>
{column.isSorted && !column.isSortedDesc && (
<ArrowUpIcon className="h-3 w-3" />
)}
{column.isSorted && column.isSortedDesc && (
<ArrowDownIcon className="h-3 w-3" />
)}
</Box>
)}
</span>
{allowResize && !column.disableResizing && (
<span
{...column.getResizerProps({
onClick: (event: Event) => event.stopPropagation(),
})}
className="absolute -right-0.5 bottom-0 top-0 z-10 h-full w-1.5 group-hover:bg-slate-900 group-hover:bg-opacity-20 group-active:bg-slate-900 group-active:bg-opacity-20 motion-safe:transition-colors"
/>
)}
</Dropdown.Trigger>
)}
<Dropdown.Content
menu

View File

@@ -11,7 +11,6 @@ import { useNotFoundRedirect } from '@/features/projects/common/hooks/useNotFoun
import { useProjectRoutes } from '@/features/projects/common/hooks/useProjectRoutes';
import { NextSeo } from 'next-seo';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import { twMerge } from 'tailwind-merge';
export interface ProjectLayoutProps extends AuthenticatedLayoutProps {
@@ -48,15 +47,16 @@ function ProjectLayoutContent({
useNotFoundRedirect();
useEffect(() => {
if (isPlatform || !router.isReady) {
return;
}
// useEffect(() => {
// if (isPlatform || !router.isReady) {
// return;
// }
if (isRestrictedPath) {
router.push('/local/local');
}
}, [isPlatform, isRestrictedPath, router]);
// TODO // Double check what restricted path means here
// if (isRestrictedPath) {
// router.push('/local/local');
// }
// }, [isPlatform, isRestrictedPath, router]);
if (isRestrictedPath || loading) {
return <LoadingScreen />;

View File

@@ -7,6 +7,7 @@ import { List } from '@/components/ui/v2/List';
import type { ListItemButtonProps } from '@/components/ui/v2/ListItem';
import { ListItem } from '@/components/ui/v2/ListItem';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
@@ -61,6 +62,7 @@ export default function SettingsSidebar({
className,
...props
}: SettingsSidebarProps) {
const isPlatform = useIsPlatform();
const [expanded, setExpanded] = useState(false);
const { currentProject } = useCurrentWorkspaceAndProject();
@@ -95,7 +97,7 @@ export default function SettingsSidebar({
<>
<Backdrop
open={expanded}
className="absolute top-0 left-0 bottom-0 right-0 z-[34] md:hidden"
className="absolute bottom-0 left-0 right-0 top-0 z-[34] md:hidden"
role="button"
tabIndex={-1}
onClick={() => setExpanded(false)}
@@ -112,7 +114,7 @@ export default function SettingsSidebar({
<Box
component="aside"
className={twMerge(
'absolute top-0 z-[35] h-full w-full overflow-auto border-r-1 px-2 pt-2 pb-17 motion-safe:transition-transform md:relative md:z-0 md:h-full md:py-2.5 md:transition-none',
'absolute top-0 z-[35] h-full w-full overflow-auto border-r-1 px-2 pb-17 pt-2 motion-safe:transition-transform md:relative md:z-0 md:h-full md:py-2.5 md:transition-none',
expanded ? 'translate-x-0' : '-translate-x-full md:translate-x-0',
className,
)}
@@ -181,7 +183,12 @@ export default function SettingsSidebar({
SMTP
</SettingsNavLink>
<SettingsNavLink href="/git" exact={false} onClick={handleSelect}>
<SettingsNavLink
href="/git"
exact={false}
onClick={handleSelect}
disabled={!isPlatform}
>
Git
</SettingsNavLink>

View File

@@ -1,6 +1,6 @@
import { PlusCircleIcon } from '@/components/ui/v2/icons/PlusCircleIcon';
import { PlusIcon } from '@/components/ui/v2/icons/PlusIcon';
import type { ComponentMeta, ComponentStory } from '@storybook/react';
import type { Meta, StoryFn } from '@storybook/react';
import type { ButtonProps } from './Button';
import Button from './Button';
@@ -24,9 +24,9 @@ export default {
control: { type: 'radio' },
},
},
} as ComponentMeta<typeof Button>;
} as Meta<typeof Button>;
const Template: ComponentStory<typeof Button> = function Template(
const Template: StoryFn<ButtonProps> = function TemplateFunction(
args: ButtonProps,
) {
return <Button {...args} />;

View File

@@ -5,7 +5,7 @@ import { XIcon } from '@/components/ui/v2/icons/XIcon';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { getToastBackgroundColor } from '@/utils/constants/settings';
import { copy } from '@/utils/copy';
import { type ApolloError } from '@apollo/client';
import type { ApolloError } from '@apollo/client';
import { useUserData } from '@nhost/nextjs';
import { AnimatePresence, motion } from 'framer-motion';
import { useRouter } from 'next/router';
@@ -20,6 +20,44 @@ interface ErrorDetails {
error: any;
}
const getInternalErrorMessage = (
error: Error | ApolloError | undefined,
): string | null => {
if (!error) {
return null;
}
if (error.name === 'ApolloError') {
// @ts-ignore
const graphqlError = error.graphQLErrors?.[0];
const graphqlExtensionsError = graphqlError?.extensions?.internal
?.error as { message: string };
return graphqlError.message || graphqlExtensionsError?.message || null;
}
if (error instanceof Error) {
return error.message;
}
return null;
};
const errorToObject = (error: ApolloError | Error) => {
if (error.name === 'ApolloError') {
return error;
}
if (error instanceof Error) {
return {
name: error.name,
message: error.message,
stack: error.stack,
};
}
return {};
};
export default function ErrorToast({
isVisible,
errorMessage,
@@ -28,7 +66,7 @@ export default function ErrorToast({
}: {
isVisible: boolean;
errorMessage: string;
error: ApolloError;
error: ApolloError | Error;
close: () => void;
}) {
const userData = useUserData();
@@ -43,19 +81,10 @@ export default function ErrorToast({
userId: userData?.id || 'local',
url: asPath,
},
error,
error: errorToObject(error),
};
const internalError = error?.graphQLErrors?.at(0)?.extensions?.internal as {
error: {
message: string;
};
};
const msg =
internalError?.error?.message ||
error?.graphQLErrors?.at(0).message ||
errorMessage;
const msg = getInternalErrorMessage(error) || errorMessage;
return (
<AnimatePresence>

View File

@@ -1,5 +1,5 @@
import { Option } from '@/components/ui/v2/Option';
import type { ComponentMeta, ComponentStory } from '@storybook/react';
import type { Meta, StoryFn } from '@storybook/react';
import type { SelectProps } from './Select';
import Select from './Select';
@@ -7,11 +7,9 @@ export default {
title: 'UI Library / Select',
component: Select,
argTypes: {},
} as ComponentMeta<typeof Select>;
} as Meta<typeof Select>;
const Template: ComponentStory<typeof Select> = function Template(
args: SelectProps<any>,
) {
const Template: StoryFn<SelectProps<any>> = function TemplateFunction(args) {
return (
<Select className="w-64" {...args}>
<Option value="value1">Value 1</Option>

View File

@@ -1,4 +1,4 @@
import type { ComponentMeta, ComponentStory } from '@storybook/react';
import type { Meta, StoryFn } from '@storybook/react';
import type { SwitchProps } from './Switch';
import Switch from './Switch';
@@ -6,9 +6,9 @@ export default {
title: 'UI Library / Switch',
component: Switch,
argTypes: {},
} as ComponentMeta<typeof Switch>;
} as Meta<typeof Switch>;
const Template: ComponentStory<typeof Switch> = function Template(
const Template: StoryFn<SwitchProps> = function TemplateFunction(
args: SwitchProps,
) {
return <Switch label="Accept Rules" {...args} />;

View File

@@ -0,0 +1,85 @@
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { Input } from '@/components/ui/v2/Input';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { useUpdateUserDisplayNameMutation } from '@/utils/__generated__/graphql';
import { yupResolver } from '@hookform/resolvers/yup';
import { useUserData } from '@nhost/nextjs';
import { FormProvider, useForm } from 'react-hook-form';
import * as Yup from 'yup';
const validationSchema = Yup.object({
displayName: Yup.string()
.label('Display Name')
.required('This field is required.'),
});
export type DisplayNameSettingFormValues = Yup.InferType<
typeof validationSchema
>;
export default function DisplayNameSetting() {
const { id: userID, displayName } = useUserData();
const [updateUserDisplayName] = useUpdateUserDisplayNameMutation();
const form = useForm<DisplayNameSettingFormValues>({
reValidateMode: 'onSubmit',
defaultValues: {
displayName,
},
resolver: yupResolver(validationSchema),
});
const { register, formState } = form;
const isDirty = Object.keys(formState.dirtyFields).length > 0;
async function handleSubmit(formValues: DisplayNameSettingFormValues) {
await execPromiseWithErrorToast(
async () => {
await updateUserDisplayName({
variables: {
id: userID,
displayName: formValues.displayName,
},
});
form.reset({ displayName: formValues.displayName });
},
{
loadingMessage: 'Updating your display name...',
successMessage: 'Your display name has been updated successfully.',
errorMessage:
'An error occurred while trying to update your display name. Please try again.',
},
);
}
return (
<FormProvider {...form}>
<Form onSubmit={handleSubmit}>
<SettingsContainer
title="Update your display name"
slotProps={{
submitButton: {
disabled: !isDirty,
loading: formState.isSubmitting,
},
}}
className="grid grid-flow-row lg:grid-cols-5"
>
<Input
{...register('displayName')}
className="col-span-2"
type="text"
id="display-name"
label="Display Name"
fullWidth
helperText={formState.errors.displayName?.message}
error={Boolean(formState.errors.displayName)}
/>
</SettingsContainer>
</Form>
</FormProvider>
);
}

View File

@@ -0,0 +1,2 @@
export * from './DisplayNameSetting';
export { default as DisplayNameSetting } from './DisplayNameSetting';

View File

@@ -0,0 +1,80 @@
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { Input } from '@/components/ui/v2/Input';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useNhostClient, useUserData } from '@nhost/nextjs';
import { FormProvider, useForm } from 'react-hook-form';
import * as Yup from 'yup';
const validationSchema = Yup.object({
email: Yup.string().label('Email').email().required(),
});
export type EmailSettingFormValues = Yup.InferType<typeof validationSchema>;
export default function EmailSetting() {
const nhost = useNhostClient();
const { email } = useUserData();
const form = useForm<EmailSettingFormValues>({
reValidateMode: 'onSubmit',
defaultValues: { email },
resolver: yupResolver(validationSchema),
});
const { register, formState } = form;
const isDirty = Object.keys(formState.dirtyFields).length > 0;
async function handleSubmit(formValues: EmailSettingFormValues) {
await execPromiseWithErrorToast(
async () => {
await nhost.auth.changeEmail({
newEmail: formValues.email,
options: {
redirectTo: `${window.location.origin}/account`,
},
});
form.reset({ email: formValues.email });
},
{
loadingMessage: 'Updating your email...',
successMessage:
'Please check your inbox. Follow the link to finalize changing your email.',
errorMessage:
'An error occurred while trying to update your email. Please try again.',
},
);
}
return (
<FormProvider {...form}>
<Form onSubmit={handleSubmit}>
<SettingsContainer
title="Update your email"
slotProps={{
submitButton: {
disabled: !isDirty,
loading: formState.isSubmitting,
},
}}
className="grid grid-flow-row lg:grid-cols-5"
>
<Input
{...register('email')}
className="col-span-2"
id="email"
spellCheck="false"
autoCapitalize="none"
type="email"
label="Email"
hideEmptyHelperText
fullWidth
helperText={formState.errors.email?.message}
error={Boolean(formState.errors.email)}
/>
</SettingsContainer>
</Form>
</FormProvider>
);
}

View File

@@ -0,0 +1,2 @@
export * from './EmailSetting';
export { default as EmailSetting } from './EmailSetting';

View File

@@ -0,0 +1,76 @@
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Box } from '@/components/ui/v2/Box';
import { Button } from '@/components/ui/v2/Button';
import { GitHubIcon } from '@/components/ui/v2/icons/GitHubIcon';
import { Text } from '@/components/ui/v2/Text';
import { useGetAuthUserProvidersQuery } from '@/utils/__generated__/graphql';
import { useProviderLink } from '@nhost/nextjs';
import NavLink from 'next/link';
export default function SocialProvidersSettings() {
const { data, loading, error } = useGetAuthUserProvidersQuery();
const isGithubConnected = data?.authUserProviders?.some(
(item) => item.providerId === 'github',
);
const { github } = useProviderLink({
connect: true,
redirectTo: `${window.location.origin}/account`,
});
if (!data && loading) {
return (
<ActivityIndicator
delay={1000}
label="Loading personal access tokens..."
/>
);
}
if (error) {
throw error;
}
return (
<SettingsContainer
title="Authentication providers"
description=""
rootClassName="gap-0 flex flex-col items-start"
className="my-2"
slotProps={{
submitButton: { className: 'hidden' },
footer: { className: 'hidden' },
}}
>
{isGithubConnected ? (
<Box
sx={{ backgroundColor: 'grey.200' }}
className="flex flex-row items-center justify-start space-x-2 rounded-md p-2"
>
<GitHubIcon />
<Text className="font-medium ">Connected</Text>
</Box>
) : (
<Box>
<NavLink
href={github}
passHref
target="_blank"
rel="noreferrer noopener"
legacyBehavior
>
<Button
className=""
variant="outlined"
color="secondary"
startIcon={<GitHubIcon />}
>
Connect with GitHub
</Button>
</NavLink>
</Box>
)}
</SettingsContainer>
);
}

View File

@@ -0,0 +1 @@
export { default as SocialProvidersSettings } from './SocialProvidersSettings';

View File

@@ -0,0 +1,6 @@
query getAuthUserProviders {
authUserProviders {
id
providerId
}
}

View File

@@ -0,0 +1,6 @@
mutation updateUserDisplayName($id: uuid!, $displayName: String!) {
updateUser(pk_columns: { id: $id }, _set: { displayName: $displayName }) {
id
displayName
}
}

View File

@@ -1,4 +1,5 @@
import { useDialog } from '@/components/common/DialogProvider';
import { ControlledSelect } from '@/components/form/ControlledSelect';
import { Form } from '@/components/form/Form';
import { Box } from '@/components/ui/v2/Box';
import { Button } from '@/components/ui/v2/Button';
@@ -6,6 +7,7 @@ import { ArrowsClockwise } from '@/components/ui/v2/icons/ArrowsClockwise';
import { InfoIcon } from '@/components/ui/v2/icons/InfoIcon';
import { PlusIcon } from '@/components/ui/v2/icons/PlusIcon';
import { Input } from '@/components/ui/v2/Input';
import { Option } from '@/components/ui/v2/Option';
import { Text } from '@/components/ui/v2/Text';
import { Tooltip } from '@/components/ui/v2/Tooltip';
import { useAdminApolloClient } from '@/features/projects/common/hooks/useAdminApolloClient';
@@ -20,11 +22,18 @@ import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import * as Yup from 'yup';
const AUTO_EMBEDDINGS_MODELS = [
'text-embedding-ada-002',
'text-embedding-3-small',
'text-embedding-3-large',
];
export const validationSchema = Yup.object({
name: Yup.string().required('The name is required.'),
schemaName: Yup.string().required('The schema is required'),
tableName: Yup.string().required('The table is required'),
columnName: Yup.string().required('The column is required'),
name: Yup.string().required('The name field is required.'),
model: Yup.string().oneOf(AUTO_EMBEDDINGS_MODELS),
schemaName: Yup.string().required('The schema field is required'),
tableName: Yup.string().required('The table field is required'),
columnName: Yup.string().required('The column field is required'),
query: Yup.string(),
mutation: Yup.string(),
});
@@ -40,7 +49,7 @@ export interface AutoEmbeddingsFormProps extends DialogFormProps {
/**
* if there is initialData then it's an update operation
*/
initialData?: AutoEmbeddingsFormValues;
initialData?: AutoEmbeddingsFormValues & { model: string };
/**
* Function to be called when the operation is cancelled.
@@ -74,7 +83,10 @@ export default function AutoEmbeddingsForm({
});
const form = useForm<AutoEmbeddingsFormValues>({
defaultValues: initialData,
defaultValues: {
...initialData,
model: initialData?.model ?? 'text-embedding-ada-002',
},
reValidateMode: 'onSubmit',
resolver: yupResolver(validationSchema),
});
@@ -106,7 +118,9 @@ export default function AutoEmbeddingsForm({
}
await insertGraphiteAutoEmbeddingsConfiguration({
variables: values,
variables: {
...values,
},
});
};
@@ -129,9 +143,9 @@ export default function AutoEmbeddingsForm({
<FormProvider {...form}>
<Form
onSubmit={handleSubmit}
className="flex h-full flex-col gap-4 overflow-hidden"
className="flex flex-col h-full gap-4 overflow-hidden"
>
<div className="flex flex-1 flex-col space-y-6 overflow-auto px-6">
<div className="flex flex-col flex-1 px-6 space-y-6 overflow-auto">
<Input
{...register('name')}
id="name"
@@ -141,7 +155,7 @@ export default function AutoEmbeddingsForm({
<Tooltip title="Name of the Auto-Embeddings">
<InfoIcon
aria-label="Info"
className="h-4 w-4"
className="w-4 h-4"
color="primary"
/>
</Tooltip>
@@ -155,6 +169,36 @@ export default function AutoEmbeddingsForm({
autoComplete="off"
autoFocus
/>
<ControlledSelect
slotProps={{
popper: { disablePortal: false, className: 'z-[10000]' },
}}
id="model"
name="model"
label={
<Box className="flex flex-row items-center space-x-2">
<Text>Model</Text>
<Tooltip title="Auto-Embeddings Model">
<InfoIcon
aria-label="Info"
className="w-4 h-4"
color="primary"
/>
</Tooltip>
</Box>
}
fullWidth
error={!!errors?.model?.message}
helperText={errors?.model?.message}
>
{AUTO_EMBEDDINGS_MODELS.map((model) => (
<Option key={model} value={model}>
{model}
</Option>
))}
</ControlledSelect>
<Input
{...register('schemaName')}
id="schemaName"
@@ -164,7 +208,7 @@ export default function AutoEmbeddingsForm({
<Tooltip title={<span>Schema where the table belongs to</span>}>
<InfoIcon
aria-label="Info"
className="h-4 w-4"
className="w-4 h-4"
color="primary"
/>
</Tooltip>
@@ -186,7 +230,7 @@ export default function AutoEmbeddingsForm({
<Tooltip title="Table Name">
<InfoIcon
aria-label="Info"
className="h-4 w-4"
className="w-4 h-4"
color="primary"
/>
</Tooltip>
@@ -208,7 +252,7 @@ export default function AutoEmbeddingsForm({
<Tooltip title="Column name">
<InfoIcon
aria-label="Info"
className="h-4 w-4"
className="w-4 h-4"
color="primary"
/>
</Tooltip>
@@ -230,7 +274,7 @@ export default function AutoEmbeddingsForm({
<Tooltip title="Query">
<InfoIcon
aria-label="Info"
className="h-4 w-4"
className="w-4 h-4"
color="primary"
/>
</Tooltip>
@@ -254,7 +298,7 @@ export default function AutoEmbeddingsForm({
<Tooltip title="Mutation">
<InfoIcon
aria-label="Info"
className="h-4 w-4"
className="w-4 h-4"
color="primary"
/>
</Tooltip>
@@ -271,7 +315,7 @@ export default function AutoEmbeddingsForm({
/>
</div>
<Box className="flex w-full flex-row justify-between rounded border-t px-6 py-4">
<Box className="flex flex-row justify-between w-full px-6 py-4 border-t rounded">
<Button variant="outlined" color="secondary" onClick={onCancel}>
Cancel
</Button>

View File

@@ -1,3 +1,4 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { ControlledAutocomplete } from '@/components/form/ControlledAutocomplete';
@@ -12,6 +13,7 @@ import { Switch } from '@/components/ui/v2/Switch';
import { Text } from '@/components/ui/v2/Text';
import { Tooltip } from '@/components/ui/v2/Tooltip';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import { COST_PER_VCPU } from '@/features/projects/resources/settings/utils/resourceSettingsValidationSchema';
import { ComputeFormSection } from '@/features/services/components/ServiceForm/components/ComputeFormSection';
import {
@@ -20,14 +22,19 @@ import {
useGetSoftwareVersionsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { RESOURCE_VCPU_MULTIPLIER } from '@/utils/constants/common';
import { getToastStyleProps } from '@/utils/constants/settings';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
import * as Yup from 'yup';
import { DisableAIServiceConfirmationDialog } from './DisableAIServiceConfirmationDialog';
const MIN_POSTGRES_VERSION_SUPPORTING_AI = '14.6-20231018-1';
const validationSchema = Yup.object({
version: Yup.object({
label: Yup.string().required(),
@@ -46,21 +53,28 @@ const validationSchema = Yup.object({
export type AISettingsFormValues = Yup.InferType<typeof validationSchema>;
export default function AISettings() {
const { maintenanceActive } = useUI();
const isPlatform = useIsPlatform();
const { openDialog } = useDialog();
const [updateConfig] = useUpdateConfigMutation();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const [updateConfig] = useUpdateConfigMutation({
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { currentProject } = useCurrentWorkspaceAndProject();
const [aiServiceEnabled, setAIServiceEnabled] = useState(true);
const {
data: { config: { ai } = {} } = {},
data: {
config: { ai, postgres: { version: postgresVersion } = {} } = {},
} = {},
loading: loadingAiSettings,
error: errorGettingAiSettings,
} = useGetAiSettingsQuery({
variables: {
appId: currentProject.id,
},
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data: graphiteVersionsData, loading: loadingGraphiteVersionsData } =
@@ -68,6 +82,7 @@ export default function AISettings() {
variables: {
software: Software_Type_Enum.Graphite,
},
skip: !isPlatform,
});
const graphiteVersions = graphiteVersionsData?.softwareVersions || [];
@@ -92,8 +107,8 @@ export default function AISettings() {
reValidateMode: 'onSubmit',
defaultValues: {
version: {
label: ai?.version ?? availableVersions?.at(0)?.label,
value: ai?.version ?? availableVersions?.at(0)?.value,
label: ai?.version || availableVersions?.at(0)?.label || '',
value: ai?.version || availableVersions?.at(0)?.value || '',
},
webhookSecret: '',
organization: '',
@@ -150,6 +165,17 @@ export default function AISettings() {
]);
const toggleAIService = async (enabled: boolean) => {
if (postgresVersion < MIN_POSTGRES_VERSION_SUPPORTING_AI) {
toast.error(
'In order to enable the AI service you need to update your database version to 14.6-20231018-1 or newer.',
{
style: getToastStyleProps().style,
...getToastStyleProps().error,
},
);
return;
}
setAIServiceEnabled(enabled);
if (!enabled && ai) {
@@ -208,6 +234,18 @@ export default function AISettings() {
});
form.reset(formValues);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'AI settings are being updated...',
@@ -230,7 +268,7 @@ export default function AISettings() {
return (
<Box className="space-y-4" sx={{ backgroundColor: 'background.default' }}>
<Box className="flex flex-row items-center justify-between rounded-lg border-1 p-4">
<Box className="flex flex-row items-center justify-between p-4 rounded-lg border-1">
<Text className="text-lg font-semibold">Enable AI service</Text>
<Switch
checked={aiServiceEnabled}
@@ -253,54 +291,58 @@ export default function AISettings() {
className="flex flex-col"
>
<Box className="space-y-4">
{availableVersions.length > 0 && (
<Box className="space-y-2">
<Box className="flex flex-row items-center space-x-2">
<Text className="text-lg font-semibold">Version</Text>
<Tooltip title="Version of the service to use.">
<InfoIcon
aria-label="Info"
className="h-4 w-4"
color="primary"
/>
</Tooltip>
</Box>
<ControlledAutocomplete
id="version"
name="version"
autoHighlight
isOptionEqualToValue={() => false}
filterOptions={(options, { inputValue }) => {
const inputValueLower = inputValue.toLowerCase();
const matched = [];
const otherOptions = [];
options.forEach((option) => {
const optionLabelLower = option.label.toLowerCase();
if (optionLabelLower.startsWith(inputValueLower)) {
matched.push(option);
} else {
otherOptions.push(option);
}
});
const result = [...matched, ...otherOptions];
return result;
}}
fullWidth
className="col-span-4"
options={availableVersions}
error={!!formState.errors?.version?.message}
helperText={formState.errors?.version?.message}
showCustomOption="auto"
customOptionLabel={(value) =>
`Use custom value: "${value}"`
}
/>
<Box className="space-y-2">
<Box className="flex flex-row items-center space-x-2">
<Text className="text-lg font-semibold">Version</Text>
<Tooltip title="Version of the service to use.">
<InfoIcon
aria-label="Info"
className="w-4 h-4"
color="primary"
/>
</Tooltip>
</Box>
)}
<ControlledAutocomplete
id="version"
name="version"
autoHighlight
isOptionEqualToValue={() => false}
filterOptions={(options, { inputValue }) => {
const inputValueLower = inputValue.toLowerCase();
const matched = [];
const otherOptions = [];
options.forEach((option) => {
const optionLabelLower = option.label.toLowerCase();
if (optionLabelLower.startsWith(inputValueLower)) {
matched.push(option);
} else {
otherOptions.push(option);
}
});
const result = [...matched, ...otherOptions];
return result;
}}
fullWidth
className="col-span-4"
options={availableVersions}
error={
!!formState.errors?.version?.message ||
!!formState.errors?.version?.value?.message
}
helperText={
formState.errors?.version?.message ||
formState.errors?.version?.value?.message
}
showCustomOption="auto"
customOptionLabel={(value) =>
`Use custom value: "${value}"`
}
/>
</Box>
<Box className="space-y-2">
<Box className="flex flex-row items-center space-x-2">
@@ -310,7 +352,7 @@ export default function AISettings() {
<Tooltip title="Used to validate requests between postgres and the AI service. The AI service will also include the header X-Graphite-Webhook-Secret with this value set when calling external webhooks so the source of the request can be validated.">
<InfoIcon
aria-label="Info"
className="h-4 w-4"
className="w-4 h-4"
color="primary"
/>
</Tooltip>
@@ -334,26 +376,28 @@ export default function AISettings() {
<Tooltip title="Dedicated resources allocated for the service.">
<InfoIcon
aria-label="Info"
className="h-4 w-4"
className="w-4 h-4"
color="primary"
/>
</Tooltip>
</Box>
<Alert
severity="info"
className="flex items-center justify-between space-x-2"
>
<span>{getAIResourcesCost()}</span>
<b>
$
{parseFloat(
(
aiSettingsFormValues.compute.cpu * COST_PER_VCPU
).toFixed(2),
)}
</b>
</Alert>
{isPlatform ? (
<Alert
severity="info"
className="flex items-center justify-between space-x-2"
>
<span>{getAIResourcesCost()}</span>
<b>
$
{parseFloat(
(
aiSettingsFormValues.compute.cpu * COST_PER_VCPU
).toFixed(2),
)}
</b>
</Alert>
) : null}
<ComputeFormSection />
</Box>
@@ -372,7 +416,7 @@ export default function AISettings() {
<Tooltip title="Key to use for authenticating API requests to OpenAI">
<InfoIcon
aria-label="Info"
className="h-4 w-4"
className="w-4 h-4"
color="primary"
/>
</Tooltip>
@@ -395,7 +439,7 @@ export default function AISettings() {
<Tooltip title="Optional. OpenAI organization to use.">
<InfoIcon
aria-label="Info"
className="h-4 w-4"
className="w-4 h-4"
color="primary"
/>
</Tooltip>
@@ -423,7 +467,7 @@ export default function AISettings() {
<Tooltip title="How often to run the job that keeps embeddings up to date.">
<InfoIcon
aria-label="Info"
className="h-4 w-4"
className="w-4 h-4"
color="primary"
/>
</Tooltip>

View File

@@ -1,8 +1,11 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { Box } from '@/components/ui/v2/Box';
import { Button } from '@/components/ui/v2/Button';
import { Text } from '@/components/ui/v2/Text';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { useUpdateConfigMutation } from '@/utils/__generated__/graphql';
import { useState } from 'react';
@@ -23,11 +26,14 @@ export default function DisableAIServiceConfirmationDialog({
onCancel,
onServiceDisabled,
}: DisableAIServiceConfirmationDialogProps) {
const { closeDialog } = useDialog();
const isPlatform = useIsPlatform();
const { openDialog, closeDialog } = useDialog();
const localMimirClient = useLocalMimirClient();
const [loading, setLoading] = useState(false);
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation();
const [updateConfig] = useUpdateConfigMutation({
...(!isPlatform ? { client: localMimirClient } : {}),
});
async function handleClick() {
setLoading(true);
@@ -45,6 +51,18 @@ export default function DisableAIServiceConfirmationDialog({
onServiceDisabled();
closeDialog();
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Disabling the AI service...',

View File

@@ -1,5 +1,8 @@
query GetAISettings($appId: uuid!) {
config(appID: $appId, resolve: false) {
postgres {
version
}
ai {
version
webhookSecret

View File

@@ -1,16 +1,21 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Input } from '@/components/ui/v2/Input';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import {
GetAuthenticationSettingsDocument,
useGetAuthenticationSettingsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { twMerge } from 'tailwind-merge';
import * as Yup from 'yup';
@@ -26,15 +31,19 @@ export type AllowedEmailSettingsFormValues = Yup.InferType<
>;
export default function AllowedEmailDomainsSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetAuthenticationSettingsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetAuthenticationSettingsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { email, emailDomains } = data?.config?.auth?.user || {};
@@ -54,6 +63,17 @@ export default function AllowedEmailDomainsSettings() {
const isDirty = Object.keys(formState.dirtyFields).length > 0;
useEffect(() => {
if (!loading && email && emailDomains) {
form.reset({
enabled:
email?.allowed?.length > 0 || emailDomains?.allowed?.length > 0,
allowedEmails: email?.allowed?.join(', ') || '',
allowedEmailDomains: emailDomains?.allowed?.join(', ') || '',
});
}
}, [loading, form, email, emailDomains]);
if (loading) {
return (
<ActivityIndicator
@@ -105,6 +125,18 @@ export default function AllowedEmailDomainsSettings() {
async () => {
await updateConfigPromise;
form.reset(values);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Allowed email settings are being updated...',
@@ -130,7 +162,7 @@ export default function AllowedEmailDomainsSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication#allowed-emails-and-domains"
docsLink="https://docs.nhost.io/guides/auth/overview#allowed-emails-and-domains"
switchId="enabled"
showSwitch
className={twMerge(

View File

@@ -1,16 +1,21 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Input } from '@/components/ui/v2/Input';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import {
GetAuthenticationSettingsDocument,
useGetAuthenticationSettingsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import * as Yup from 'yup';
@@ -23,15 +28,19 @@ export type AllowedRedirectURLFormValues = Yup.InferType<
>;
export default function AllowedRedirectURLsSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const localMimirClient = useLocalMimirClient();
const { maintenanceActive } = useUI();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetAuthenticationSettingsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetAuthenticationSettingsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { allowedUrls } = data?.config?.auth?.redirections || {};
@@ -44,6 +53,14 @@ export default function AllowedRedirectURLsSettings() {
resolver: yupResolver(validationSchema),
});
useEffect(() => {
if (!loading && allowedUrls) {
form.reset({
allowedUrls: allowedUrls?.join(', ') || '',
});
}
}, [loading, allowedUrls, form]);
if (loading) {
return (
<ActivityIndicator
@@ -82,6 +99,18 @@ export default function AllowedRedirectURLsSettings() {
async () => {
await updateConfigPromise;
form.reset(values);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Allowed redirect URL settings are being updated...',
@@ -105,7 +134,7 @@ export default function AllowedRedirectURLsSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication#allowed-redirect-urls"
docsLink="https://docs.nhost.io/guides/auth/overview#allowed-redirect-urls"
className="grid grid-flow-row px-4 lg:grid-cols-5"
>
<Input

View File

@@ -1,15 +1,20 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import {
GetSignInMethodsDocument,
useGetSignInMethodsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import * as Yup from 'yup';
@@ -20,15 +25,19 @@ const validationSchema = Yup.object({
export type AnonymousSignInFormValues = Yup.InferType<typeof validationSchema>;
export default function AnonymousSignInSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetSignInMethodsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetSignInMethodsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { enabled } = data?.config?.auth?.method?.anonymous || {};
@@ -41,6 +50,12 @@ export default function AnonymousSignInSettings() {
resolver: yupResolver(validationSchema),
});
useEffect(() => {
if (!loading) {
form.reset({ enabled });
}
}, [loading, enabled, form]);
if (loading) {
return (
<ActivityIndicator
@@ -75,6 +90,18 @@ export default function AnonymousSignInSettings() {
async () => {
await updateConfigPromise;
form.reset(values);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Anonymous sign-in settings are being updated...',

View File

@@ -1,3 +1,5 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
@@ -7,16 +9,19 @@ import { CopyIcon } from '@/components/ui/v2/icons/CopyIcon';
import { Input } from '@/components/ui/v2/Input';
import { InputAdornment } from '@/components/ui/v2/InputAdornment';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import { generateAppServiceUrl } from '@/features/projects/common/utils/generateAppServiceUrl';
import {
GetSignInMethodsDocument,
useGetSignInMethodsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { copy } from '@/utils/copy';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useTheme } from '@mui/material';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { twMerge } from 'tailwind-merge';
import * as Yup from 'yup';
@@ -53,15 +58,19 @@ export type AppleProviderFormValues = Yup.InferType<typeof validationSchema>;
export default function AppleProviderSettings() {
const theme = useTheme();
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetSignInMethodsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetSignInMethodsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { clientId, enabled, keyId, privateKey, teamId } =
@@ -79,6 +88,18 @@ export default function AppleProviderSettings() {
resolver: yupResolver(validationSchema),
});
useEffect(() => {
if (!loading) {
form.reset({
teamId: teamId || '',
keyId: keyId || '',
clientId: clientId || '',
privateKey: privateKey || '',
enabled: enabled || false,
});
}
}, [loading, teamId, keyId, clientId, privateKey, enabled, form]);
if (loading) {
return (
<ActivityIndicator
@@ -119,6 +140,18 @@ export default function AppleProviderSettings() {
async () => {
await updateConfigPromise;
form.reset(formValues);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Apple settings are being updated...',
@@ -141,7 +174,7 @@ export default function AppleProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication/sign-in-with-apple"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-apple"
docsTitle="how to sign in users with Apple"
icon={
theme.palette.mode === 'dark'
@@ -236,7 +269,7 @@ export default function AppleProviderSettings() {
);
}}
>
<CopyIcon className="h-4 w-4" />
<CopyIcon className="w-4 h-4" />
</IconButton>
</InputAdornment>
}

View File

@@ -1,9 +1,12 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { ControlledAutocomplete } from '@/components/form/ControlledAutocomplete';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import {
GetAuthenticationSettingsDocument,
Software_Type_Enum,
@@ -11,8 +14,10 @@ import {
useGetSoftwareVersionsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import * as Yup from 'yup';
@@ -28,21 +33,26 @@ export type AuthServiceVersionFormValues = Yup.InferType<
>;
export default function AuthServiceVersionSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const localMimirClient = useLocalMimirClient();
const { maintenanceActive } = useUI();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetAuthenticationSettingsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetAuthenticationSettingsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data: authVersionsData } = useGetSoftwareVersionsQuery({
variables: {
software: Software_Type_Enum.Auth,
},
skip: !isPlatform,
});
const { version } = data?.config?.auth || {};
@@ -59,10 +69,21 @@ export default function AuthServiceVersionSettings() {
const form = useForm<AuthServiceVersionFormValues>({
reValidateMode: 'onSubmit',
defaultValues: { version: { label: version, value: version } },
defaultValues: { version: { label: '', value: '' } },
resolver: yupResolver(validationSchema),
});
useEffect(() => {
if (!loading && version) {
form.reset({
version: {
label: version,
value: version,
},
});
}
}, [loading, version, form]);
if (loading) {
return (
<ActivityIndicator
@@ -97,6 +118,18 @@ export default function AuthServiceVersionSettings() {
async () => {
await updateConfigPromise;
form.reset(formValues);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Auth version is being updated...',
@@ -120,12 +153,20 @@ export default function AuthServiceVersionSettings() {
}}
docsLink="https://github.com/nhost/hasura-auth/releases"
docsTitle="the latest releases"
className="grid grid-flow-row gap-x-4 gap-y-2 px-4 lg:grid-cols-5"
className="grid grid-flow-row px-4 gap-x-4 gap-y-2 lg:grid-cols-5"
>
<ControlledAutocomplete
id="version"
name="version"
autoHighlight
freeSolo
getOptionLabel={(option) => {
if (typeof option === 'string') {
return option || '';
}
return option.value;
}}
isOptionEqualToValue={() => false}
filterOptions={(options, { inputValue }) => {
const inputValueLower = inputValue.toLowerCase();

View File

@@ -1,3 +1,5 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
@@ -8,15 +10,18 @@ import { Input } from '@/components/ui/v2/Input';
import { InputAdornment } from '@/components/ui/v2/InputAdornment';
import { BaseProviderSettings } from '@/features/authentication/settings/components/BaseProviderSettings';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import { generateAppServiceUrl } from '@/features/projects/common/utils/generateAppServiceUrl';
import {
GetSignInMethodsDocument,
useGetSignInMethodsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { copy } from '@/utils/copy';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { twMerge } from 'tailwind-merge';
import * as Yup from 'yup';
@@ -46,15 +51,19 @@ const validationSchema = Yup.object({
export type AzureADProviderFormValues = Yup.InferType<typeof validationSchema>;
export default function AzureADProviderSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const localMimirClient = useLocalMimirClient();
const { maintenanceActive } = useUI();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetSignInMethodsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetSignInMethodsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { clientId, clientSecret, tenant, enabled } =
@@ -71,6 +80,17 @@ export default function AzureADProviderSettings() {
resolver: yupResolver(validationSchema),
});
useEffect(() => {
if (!loading) {
form.reset({
clientId: clientId || '',
clientSecret: clientSecret || '',
tenant: tenant || '',
enabled: enabled || false,
});
}
}, [loading, clientId, clientSecret, tenant, enabled, form]);
if (loading) {
return (
<ActivityIndicator
@@ -108,6 +128,18 @@ export default function AzureADProviderSettings() {
async () => {
await updateConfigPromise;
form.reset(formValues);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Azure AD settings are being updated...',
@@ -182,7 +214,7 @@ export default function AzureADProviderSettings() {
);
}}
>
<CopyIcon className="h-4 w-4" />
<CopyIcon className="w-4 h-4" />
</IconButton>
</InputAdornment>
}

View File

@@ -1,16 +1,21 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Input } from '@/components/ui/v2/Input';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import {
GetAuthenticationSettingsDocument,
useGetAuthenticationSettingsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { twMerge } from 'tailwind-merge';
import * as Yup from 'yup';
@@ -24,15 +29,19 @@ const validationSchema = Yup.object({
export type BlockedEmailFormValues = Yup.InferType<typeof validationSchema>;
export default function BlockedEmailSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetAuthenticationSettingsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetAuthenticationSettingsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { email, emailDomains } = data?.config?.auth?.user || {};
@@ -51,6 +60,17 @@ export default function BlockedEmailSettings() {
const enabled = watch('enabled');
const isDirty = Object.keys(formState.dirtyFields).length > 0;
useEffect(() => {
if (!loading && email && emailDomains) {
form.reset({
enabled:
email?.blocked?.length > 0 || emailDomains?.blocked?.length > 0,
blockedEmails: email?.blocked?.join(', ') || '',
blockedEmailDomains: emailDomains?.blocked?.join(', ') || '',
});
}
}, [loading, email, emailDomains, form]);
if (loading) {
return (
<ActivityIndicator
@@ -112,6 +132,18 @@ export default function BlockedEmailSettings() {
async () => {
await updateConfigPromise;
form.reset(values);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage:
@@ -136,7 +168,7 @@ export default function BlockedEmailSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication#blocked-emails-and-domains"
docsLink="https://docs.nhost.io/guides/auth/overview#allowed-emails-and-domains"
switchId="enabled"
showSwitch
className={twMerge(

View File

@@ -1,16 +1,21 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Input } from '@/components/ui/v2/Input';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import {
GetAuthenticationSettingsDocument,
useGetAuthenticationSettingsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import * as Yup from 'yup';
@@ -21,15 +26,19 @@ const validationSchema = Yup.object({
export type ClientURLFormValues = Yup.InferType<typeof validationSchema>;
export default function ClientURLSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetAuthenticationSettingsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetAuthenticationSettingsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { clientUrl, allowedUrls } = data?.config?.auth?.redirections || {};
@@ -42,6 +51,12 @@ export default function ClientURLSettings() {
resolver: yupResolver(validationSchema),
});
useEffect(() => {
if (!loading && clientUrl) {
form.reset({ clientUrl });
}
}, [loading, clientUrl, form]);
if (loading) {
return (
<ActivityIndicator
@@ -77,6 +92,18 @@ export default function ClientURLSettings() {
async () => {
await updateConfigPromise;
form.reset(values);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Client URL is being updated...',
@@ -99,7 +126,7 @@ export default function ClientURLSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication#client-url"
docsLink="https://docs.nhost.io/guides/auth/overview#client-url"
className="grid grid-flow-row lg:grid-cols-5"
>
<Input

View File

@@ -0,0 +1,143 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { Box } from '@/components/ui/v2/Box';
import { Button } from '@/components/ui/v2/Button';
import { Text } from '@/components/ui/v2/Text';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import {
GetSmtpSettingsDocument,
useUpdateConfigMutation,
} from '@/utils/__generated__/graphql';
import { useState } from 'react';
import { twMerge } from 'tailwind-merge';
function ConfirmDeleteSMTPSettingsModal({
close,
onDelete,
}: {
onDelete?: () => Promise<any>;
close: () => void;
}) {
const onClickDelete = async () => {
await onDelete();
close();
};
return (
<Box className={twMerge('w-full rounded-lg p-6 text-left')}>
<div className="grid grid-flow-row gap-4">
<Text variant="h3" component="h2">
Delete SMTP Settings?
</Text>
<Text>This will reset all your SMTP and Postmark settings.</Text>
<div className="grid grid-flow-row gap-2">
<Button color="error" onClick={onClickDelete}>
Delete
</Button>
<Button variant="outlined" color="secondary" onClick={close}>
Cancel
</Button>
</div>
</div>
</Box>
);
}
export default function DeleteSMTPSettings() {
const { openDialog, closeDialog } = useDialog();
const isPlatform = useIsPlatform();
const localMimirClient = useLocalMimirClient();
const { maintenanceActive } = useUI();
const [loading, setLoading] = useState(false);
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetSmtpSettingsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const deleteSMTPSettings = async () => {
const updateConfigPromise = updateConfig({
variables: {
appId: currentProject.id,
config: {
provider: {
smtp: null,
},
},
},
});
setLoading(true);
await execPromiseWithErrorToast(
async () => {
await updateConfigPromise;
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'SMTP settings are being deleted...',
successMessage: 'SMTP settings have been deleted successfully.',
errorMessage:
'An error occurred while trying to delete the SMTP settings.',
},
);
setLoading(false);
};
const confirmDeleteSMTPSettings = async () => {
openDialog({
component: (
<ConfirmDeleteSMTPSettingsModal
close={closeDialog}
onDelete={deleteSMTPSettings}
/>
),
});
};
return (
<SettingsContainer
title="Delete SMTP Settings"
description="Delete SMTP settings and revert to default values"
className="px-0"
slotProps={{
submitButton: { className: 'hidden' },
footer: { className: 'hidden' },
}}
>
<Box className="grid grid-flow-row border-t-1">
<Button
color="error"
className="mx-4 mt-4 justify-self-end"
onClick={confirmDeleteSMTPSettings}
disabled={loading || maintenanceActive}
loading={loading}
>
Delete
</Button>
</Box>
</SettingsContainer>
);
}

View File

@@ -0,0 +1 @@
export { default as DeleteSTMPSettings } from './DeleteSMTPSettings';

View File

@@ -1,14 +1,19 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import {
GetAuthenticationSettingsDocument,
useGetAuthenticationSettingsQuery,
useUpdateConfigMutation,
} from '@/utils/__generated__/graphql';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import * as Yup from 'yup';
@@ -19,15 +24,19 @@ const validationSchema = Yup.object({
export type DisableNewUsersFormValues = Yup.InferType<typeof validationSchema>;
export default function DisableNewUsersSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetAuthenticationSettingsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetAuthenticationSettingsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const form = useForm<DisableNewUsersFormValues>({
@@ -37,6 +46,14 @@ export default function DisableNewUsersSettings() {
},
});
useEffect(() => {
if (!loading) {
form.reset({
disabled: !data?.config?.auth?.signUp?.enabled,
});
}
}, [loading, data, form]);
if (loading) {
return (
<ActivityIndicator
@@ -73,6 +90,18 @@ export default function DisableNewUsersSettings() {
async () => {
await updateConfigPromise;
form.reset(values);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Disabling new user sign ups...',
@@ -89,7 +118,7 @@ export default function DisableNewUsersSettings() {
<SettingsContainer
title="Disable New Users"
description="If set, newly registered users are disabled and won't be able to sign in."
docsLink="https://docs.nhost.io/authentication#disable-new-users"
docsLink="https://docs.nhost.io/guides/auth/overview#disable-new-users"
switchId="disabled"
showSwitch
slotProps={{

View File

@@ -1,3 +1,5 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
@@ -12,28 +14,35 @@ import {
baseProviderValidationSchema,
} from '@/features/authentication/settings/components/BaseProviderSettings';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import { generateAppServiceUrl } from '@/features/projects/common/utils/generateAppServiceUrl';
import {
GetSignInMethodsDocument,
useGetSignInMethodsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { copy } from '@/utils/copy';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { twMerge } from 'tailwind-merge';
export default function DiscordProviderSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetSignInMethodsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetSignInMethodsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { clientId, clientSecret, enabled } =
@@ -49,6 +58,16 @@ export default function DiscordProviderSettings() {
resolver: yupResolver(baseProviderValidationSchema),
});
useEffect(() => {
if (!loading) {
form.reset({
clientId: clientId || '',
clientSecret: clientSecret || '',
enabled: enabled || false,
});
}
}, [loading, clientId, clientSecret, enabled, form]);
if (loading) {
return (
<ActivityIndicator
@@ -89,6 +108,18 @@ export default function DiscordProviderSettings() {
async () => {
await updateConfigPromise;
form.reset(formValues);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Discord settings are being updated...',
@@ -111,7 +142,7 @@ export default function DiscordProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/platform/authentication/sign-in-with-discord"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-discord"
docsTitle="how to sign in users with Discord"
icon="/assets/brands/discord.svg"
switchId="enabled"
@@ -153,7 +184,7 @@ export default function DiscordProviderSettings() {
);
}}
>
<CopyIcon className="h-4 w-4" />
<CopyIcon className="w-4 h-4" />
</IconButton>
</InputAdornment>
}

View File

@@ -1,3 +1,5 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { ControlledCheckbox } from '@/components/form/ControlledCheckbox';
import { Form } from '@/components/form/Form';
@@ -6,13 +8,16 @@ import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Input } from '@/components/ui/v2/Input';
import { Text } from '@/components/ui/v2/Text';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import {
GetSignInMethodsDocument,
useGetSignInMethodsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import * as Yup from 'yup';
@@ -29,15 +34,19 @@ const validationSchema = Yup.object({
export type EmailAndPasswordFormValues = Yup.InferType<typeof validationSchema>;
export default function EmailAndPasswordSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetSignInMethodsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, error, loading } = useGetSignInMethodsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { hibpEnabled, emailVerificationRequired, passwordMinLength } =
@@ -53,6 +62,22 @@ export default function EmailAndPasswordSettings() {
resolver: yupResolver(validationSchema),
});
useEffect(() => {
if (!loading) {
form.reset({
hibpEnabled,
emailVerificationRequired,
passwordMinLength,
});
}
}, [
loading,
hibpEnabled,
emailVerificationRequired,
passwordMinLength,
form,
]);
if (loading) {
return (
<ActivityIndicator
@@ -87,6 +112,18 @@ export default function EmailAndPasswordSettings() {
async () => {
await updateConfigPromise;
form.reset(formValues);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: `Email and password sign-in settings are being updated...`,
@@ -104,7 +141,7 @@ export default function EmailAndPasswordSettings() {
<SettingsContainer
title="Email and Password"
description="Allow users to sign in with email and password."
docsLink="https://docs.nhost.io/authentication/sign-in-with-email-and-password"
docsLink="https://docs.nhost.io/guides/auth/sign-in-email-password"
docsTitle="how to sign in users with email and password"
className="grid grid-flow-row"
showSwitch

View File

@@ -1,3 +1,5 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
@@ -12,28 +14,35 @@ import {
baseProviderValidationSchema,
} from '@/features/authentication/settings/components/BaseProviderSettings';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import { generateAppServiceUrl } from '@/features/projects/common/utils/generateAppServiceUrl';
import {
GetSignInMethodsDocument,
useGetSignInMethodsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { copy } from '@/utils/copy';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { twMerge } from 'tailwind-merge';
export default function FacebookProviderSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetSignInMethodsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetSignInMethodsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { clientId, clientSecret, enabled } =
@@ -49,6 +58,16 @@ export default function FacebookProviderSettings() {
resolver: yupResolver(baseProviderValidationSchema),
});
useEffect(() => {
if (!loading) {
form.reset({
clientId: clientId || '',
clientSecret: clientSecret || '',
enabled: enabled || false,
});
}
}, [loading, clientId, clientSecret, enabled, form]);
if (loading) {
return (
<ActivityIndicator
@@ -89,6 +108,18 @@ export default function FacebookProviderSettings() {
async () => {
await updateConfigPromise;
form.reset(formValues);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Facebook settings are being updated...',
@@ -111,7 +142,7 @@ export default function FacebookProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/platform/authentication/sign-in-with-facebook"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-facebook"
docsTitle="how to sign in users with Facebook"
icon="/assets/brands/facebook.svg"
switchId="enabled"
@@ -153,7 +184,7 @@ export default function FacebookProviderSettings() {
);
}}
>
<CopyIcon className="h-4 w-4" />
<CopyIcon className="w-4 h-4" />
</IconButton>
</InputAdornment>
}

View File

@@ -1,3 +1,5 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
@@ -12,30 +14,37 @@ import {
baseProviderValidationSchema,
} from '@/features/authentication/settings/components/BaseProviderSettings';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import { generateAppServiceUrl } from '@/features/projects/common/utils/generateAppServiceUrl';
import {
GetSignInMethodsDocument,
useGetSignInMethodsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { copy } from '@/utils/copy';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useTheme } from '@mui/material';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { twMerge } from 'tailwind-merge';
export default function GitHubProviderSettings() {
const theme = useTheme();
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetSignInMethodsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetSignInMethodsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { clientId, clientSecret, enabled } =
@@ -51,6 +60,16 @@ export default function GitHubProviderSettings() {
resolver: yupResolver(baseProviderValidationSchema),
});
useEffect(() => {
if (!loading) {
form.reset({
clientId: clientId || '',
clientSecret: clientSecret || '',
enabled: enabled || false,
});
}
}, [loading, clientId, clientSecret, enabled, form]);
if (loading) {
return (
<ActivityIndicator
@@ -91,6 +110,18 @@ export default function GitHubProviderSettings() {
async () => {
await updateConfigPromise;
form.reset(formValues);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'GitHub settings are being updated...',
@@ -113,7 +144,7 @@ export default function GitHubProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/platform/authentication/sign-in-with-github"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-github"
docsTitle="how to sign in users with GitHub"
icon={
theme.palette.mode === 'dark'
@@ -159,7 +190,7 @@ export default function GitHubProviderSettings() {
);
}}
>
<CopyIcon className="h-4 w-4" />
<CopyIcon className="w-4 h-4" />
</IconButton>
</InputAdornment>
}

View File

@@ -1,3 +1,5 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
@@ -12,28 +14,35 @@ import {
baseProviderValidationSchema,
} from '@/features/authentication/settings/components/BaseProviderSettings';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import { generateAppServiceUrl } from '@/features/projects/common/utils/generateAppServiceUrl';
import {
GetSignInMethodsDocument,
useGetSignInMethodsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { copy } from '@/utils/copy';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { twMerge } from 'tailwind-merge';
export default function GoogleProviderSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetSignInMethodsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetSignInMethodsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { clientId, clientSecret, enabled } =
@@ -49,6 +58,16 @@ export default function GoogleProviderSettings() {
resolver: yupResolver(baseProviderValidationSchema),
});
useEffect(() => {
if (!loading) {
form.reset({
clientId: clientId || '',
clientSecret: clientSecret || '',
enabled: enabled || false,
});
}
}, [loading, clientId, clientSecret, enabled, form]);
if (loading) {
return (
<ActivityIndicator
@@ -89,6 +108,18 @@ export default function GoogleProviderSettings() {
async () => {
await updateConfigPromise;
form.reset(formValues);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Google settings are being updated...',
@@ -111,7 +142,7 @@ export default function GoogleProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/platform/authentication/sign-in-with-google"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-google"
docsTitle="how to sign in users with Google"
icon="/assets/brands/google.svg"
switchId="enabled"
@@ -153,7 +184,7 @@ export default function GoogleProviderSettings() {
);
}}
>
<CopyIcon className="h-4 w-4" />
<CopyIcon className="w-4 h-4" />
</IconButton>
</InputAdornment>
}

View File

@@ -1,3 +1,5 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { ControlledSelect } from '@/components/form/ControlledSelect';
import { Form } from '@/components/form/Form';
@@ -5,17 +7,20 @@ import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Option } from '@/components/ui/v2/Option';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import {
GetAuthenticationSettingsDocument,
useGetAuthenticationSettingsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import {
AUTH_GRAVATAR_DEFAULT,
AUTH_GRAVATAR_RATING,
} from '@/utils/constants/settings';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { twMerge } from 'tailwind-merge';
import * as Yup from 'yup';
@@ -29,15 +34,19 @@ const validationSchema = Yup.object({
export type GravatarFormValues = Yup.InferType<typeof validationSchema>;
export default function GravatarSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetAuthenticationSettingsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetAuthenticationSettingsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const {
@@ -56,6 +65,16 @@ export default function GravatarSettings() {
resolver: yupResolver(validationSchema),
});
useEffect(() => {
if (!loading) {
form.reset({
default: defaultGravatar || '',
rating: rating || '',
enabled: enabled || false,
});
}
}, [loading, defaultGravatar, rating, enabled, form]);
if (loading) {
return (
<ActivityIndicator
@@ -91,6 +110,18 @@ export default function GravatarSettings() {
async () => {
await updateConfigPromise;
form.reset(values);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Gravatar settings are being updated...',
@@ -113,7 +144,7 @@ export default function GravatarSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication#gravatar"
docsLink="https://docs.nhost.io/guides/auth/overview#gravatar"
switchId="enabled"
showSwitch
className={twMerge(

View File

@@ -1,3 +1,5 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
@@ -12,28 +14,35 @@ import {
baseProviderValidationSchema,
} from '@/features/authentication/settings/components/BaseProviderSettings';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import { generateAppServiceUrl } from '@/features/projects/common/utils/generateAppServiceUrl';
import {
GetSignInMethodsDocument,
useGetSignInMethodsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { copy } from '@/utils/copy';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { twMerge } from 'tailwind-merge';
export default function LinkedInProviderSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetSignInMethodsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetSignInMethodsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { clientId, clientSecret, enabled } =
@@ -49,6 +58,16 @@ export default function LinkedInProviderSettings() {
resolver: yupResolver(baseProviderValidationSchema),
});
useEffect(() => {
if (!loading) {
form.reset({
clientId: clientId || '',
clientSecret: clientSecret || '',
enabled: enabled || false,
});
}
}, [loading, clientId, clientSecret, enabled, form]);
if (loading) {
return (
<ActivityIndicator
@@ -89,6 +108,18 @@ export default function LinkedInProviderSettings() {
async () => {
await updateConfigPromise;
form.reset(formValues);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'LinkedIn settings are being updated...',
@@ -111,7 +142,7 @@ export default function LinkedInProviderSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/platform/authentication/sign-in-with-linkedin"
docsLink="https://docs.nhost.io/guides/auth/social/sign-in-linkedin"
docsTitle="how to sign in users with LinkedIn"
icon="/assets/brands/linkedin.svg"
switchId="enabled"
@@ -153,7 +184,7 @@ export default function LinkedInProviderSettings() {
);
}}
>
<CopyIcon className="h-4 w-4" />
<CopyIcon className="w-4 h-4" />
</IconButton>
</InputAdornment>
}

View File

@@ -1,16 +1,21 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Input } from '@/components/ui/v2/Input';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import {
GetAuthenticationSettingsDocument,
useGetAuthenticationSettingsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { twMerge } from 'tailwind-merge';
import * as Yup from 'yup';
@@ -23,15 +28,19 @@ const validationSchema = Yup.object({
export type MFASettingsFormValues = Yup.InferType<typeof validationSchema>;
export default function MFASettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetAuthenticationSettingsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetAuthenticationSettingsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { enabled, issuer } = data?.config?.auth?.totp || {};
@@ -45,6 +54,15 @@ export default function MFASettings() {
resolver: yupResolver(validationSchema),
});
useEffect(() => {
if (!loading && issuer && enabled) {
form.reset({
issuer,
enabled,
});
}
}, [loading, issuer, enabled, form]);
if (loading) {
return (
<ActivityIndicator
@@ -78,6 +96,18 @@ export default function MFASettings() {
async () => {
await updateConfigPromise;
form.reset(values);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage:
@@ -102,7 +132,7 @@ export default function MFASettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication#multi-factor-authentication"
docsLink="https://docs.nhost.io/guides/auth/overview#multi-factor-authentication"
switchId="enabled"
showSwitch
className={twMerge(

View File

@@ -1,15 +1,20 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import {
GetSignInMethodsDocument,
useGetSignInMethodsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import * as Yup from 'yup';
@@ -20,15 +25,19 @@ const validationSchema = Yup.object({
export type MagicLinkFormValues = Yup.InferType<typeof validationSchema>;
export default function MagicLinkSettings() {
const { openDialog } = useDialog();
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { currentProject } = useCurrentWorkspaceAndProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetSignInMethodsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetSignInMethodsQuery({
variables: { appId: currentProject?.id },
fetchPolicy: 'cache-only',
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { enabled } = data?.config?.auth?.method?.emailPasswordless || {};
@@ -41,6 +50,12 @@ export default function MagicLinkSettings() {
resolver: yupResolver(validationSchema),
});
useEffect(() => {
if (!loading) {
form.reset({ enabled });
}
}, [loading, enabled, form]);
if (loading) {
return (
<ActivityIndicator
@@ -75,6 +90,18 @@ export default function MagicLinkSettings() {
async () => {
await updateConfigPromise;
form.reset(values);
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
},
{
loadingMessage: 'Magic Link settings are being updated...',
@@ -97,7 +124,7 @@ export default function MagicLinkSettings() {
loading: formState.isSubmitting,
},
}}
docsLink="https://docs.nhost.io/authentication/sign-in-with-magic-link"
docsLink="https://docs.nhost.io/guides/auth/sign-in-magic-link"
docsTitle="how to sign in users with Magic Link"
switchId="enabled"
showSwitch

Some files were not shown because too many files have changed in this diff Show More