Compare commits

..

23 Commits

Author SHA1 Message Date
github-actions[bot]
2e3357b7a3 chore: update versions (#3143)
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-storage-js@2.7.0

### Minor Changes

-   5c6ff6e: fix: correct StorageErrorPayload TypeScript typing

## @nhost/apollo@8.0.4

### Patch Changes

-   @nhost/nhost-js@3.2.4

## @nhost/react-apollo@16.0.1

### Patch Changes

-   @nhost/apollo@8.0.4
-   @nhost/react@3.9.1

## @nhost/react-urql@13.0.1

### Patch Changes

-   @nhost/react@3.9.1

## @nhost/nextjs@2.2.2

### Patch Changes

-   @nhost/react@3.9.1

## @nhost/nhost-js@3.2.4

### Patch Changes

-   Updated dependencies [5c6ff6e]
    -   @nhost/hasura-storage-js@2.7.0

## @nhost/react@3.9.1

### Patch Changes

-   @nhost/nhost-js@3.2.4

## @nhost/vue@2.9.1

### Patch Changes

-   @nhost/nhost-js@3.2.4

## @nhost/dashboard@2.16.0

### Minor Changes

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

### Patch Changes

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

## @nhost/docs@2.27.0

### Minor Changes

-   81cc9b3: chore: add missing images to permissions API

### Patch Changes

-   af34015: chore: add note about encryption at rest
-   1956ed2: chore: added pgmq extension to postgres docs
-   88919a3: chore: added support for nodejs22 to functions

## @nhost-examples/cli@0.3.17

### Patch Changes

-   @nhost/nhost-js@3.2.4

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

### Patch Changes

-   @nhost/react@3.9.1
-   @nhost/react-apollo@16.0.1

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

### Patch Changes

-   @nhost/react@3.9.1

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

### Patch Changes

-   @nhost/react@3.9.1
-   @nhost/react-urql@13.0.1

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

### Patch Changes

-   @nhost/nhost-js@3.2.4

## @nhost-examples/nextjs@0.4.2

### Patch Changes

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

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

### Patch Changes

-   @nhost/nhost-js@3.2.4

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

### Patch Changes

-   @nhost/nhost-js@3.2.4

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

### Patch Changes

-   @nhost/react@3.9.1
-   @nhost/react-apollo@16.0.1

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

### Patch Changes

-   @nhost/react@3.9.1

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

### Patch Changes

-   @nhost/react@3.9.1
-   @nhost/react-apollo@16.0.1

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

### Patch Changes

-   @nhost/nhost-js@3.2.4
-   @nhost/apollo@8.0.4
-   @nhost/vue@2.9.1

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

### Patch Changes

-   @nhost/apollo@8.0.4
-   @nhost/vue@2.9.1

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-01-27 13:08:19 +01:00
David BM
4385524311 fix (dashboard): update url to check service health in local dashboard (#3158)
### **PR Type**
Bug fix, Enhancement


___

### **Description**
- Update health check URL from '/healthz' to '/v1/version'

- Change service from 'auth' to 'hasura' for app URL

- Modify query key to match new endpoint

- Remove duplicate hook file


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>useIsHealthy.ts</strong><dd><code>Update health check
endpoint and service</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/common/hooks/useIsHealthy/useIsHealthy.ts

<li>Changed app URL service from 'auth' to 'hasura'<br> <li> Updated
health check endpoint from '/healthz' to '/v1/version'<br> <li> Modified
query key to match new endpoint


</details>


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

</tr>
</table></td></tr><tr><td><strong>Miscellaneous</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>index.ts</strong><dd><code>No changes to index
file</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

dashboard/src/features/projects/common/hooks/useIsHealthy/index.ts

- No changes made to file content


</details>


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

</tr>
</table></td></tr><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>useIsHealthy.ts</strong><dd><code>Remove duplicate
useIsHealthy hook</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/projects/common/hooks/useIsHealthy/useIsHealthy.ts

- Removed entire file content


</details>


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

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

.changeset/two-llamas-arrive.md

<li>Added changeset file for '@nhost/dashboard' package<br> <li>
Described fix for service health check URL


</details>


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

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

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-01-24 13:45:11 -05:00
David BM
9e404c8fc9 fix (dashboard): not redirect to 404 page if using local Nhost backend (#3159)
### **PR Type**
Bug fix, Enhancement


___

### **Description**
- Fix 404 redirect for local Nhost backend

- Improve useNotFoundRedirect hook functionality

- Add isPlatform check for conditional routing

- Update documentation for useNotFoundRedirect hook


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>useNotFoundRedirect.ts</strong><dd><code>Enhance
useNotFoundRedirect hook for local backend support</code></dd></summary>
<hr>


dashboard/src/features/projects/common/hooks/useNotFoundRedirect/useNotFoundRedirect.ts

<li>Added isPlatform check to prevent 404 redirect for local backend<br>
<li> Updated useNotFoundRedirect hook documentation<br> <li> Imported
useIsPlatform hook and added it to dependencies<br> <li> Modified
conditional logic for pathname validation


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3159/files#diff-837279cf43199053bca09913f62c4af019063a2e8dc7bfb7643ec54b7cecd29d">+8/-1</a>&nbsp;
&nbsp; &nbsp; </td>

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

.changeset/olive-camels-laugh.md

<li>Added changeset file for version bump<br> <li> Described fix for 404
redirect issue


</details>


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

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

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-01-24 13:22:49 -05:00
David BM
f8e6b615dd fix (dashboard): postgres add rule group in table permissions (#3157)
### **User description**
Fixes #3156


___

### **PR Type**
Bug fix


___

### **Description**
- Fixed issue with adding rule groups in table permissions

- Updated validation schema for rule group operator

- Replaced useCurrentWorkspaceAndProject with useProject hook

- Added changeset for the bug fix


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>validationSchemas.ts</strong><dd><code>Simplify rule
group operator validation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/database/dataGrid/components/EditPermissionsForm/validationSchemas.ts

<li>Simplified operator validation in ruleGroupSchema<br> <li> Removed
complex test function for operator<br> <li> Made operator field required
with error message


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3157/files#diff-98f990165c3aca93bc01808ac0dcbde7b347ad2fd86fe52311d306a2fb3aaf0f">+1/-15</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>RuleGroupEditor.tsx</strong><dd><code>Update hooks and
imports in RuleGroupEditor</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>


dashboard/src/features/orgs/projects/database/dataGrid/components/RuleGroupEditor/RuleGroupEditor.tsx

<li>Replaced useCurrentWorkspaceAndProject with useProject hook<br> <li>
Updated import for generateAppServiceUrl<br> <li> Adjusted references
from currentProject to project


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3157/files#diff-967b5885eecb27e94308f351d7e1e9f563b8e1f593ac9cfec9efc7d155604ef4">+6/-6</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>lovely-moose-study.md</strong><dd><code>Add changeset
for table permissions fix</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/lovely-moose-study.md

<li>Added changeset file for the bug fix<br> <li> Specified minor
version bump for @nhost/dashboard


</details>


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

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

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-01-24 08:41:20 -05:00
David BM
ac4aa01ec9 fix (dashboard): can delete column in database page (#3153)
### **User description**
FIxes #3151


___

### **PR Type**
Bug fix


___

### **Description**
- Fixed column deletion in database page

- Updated imports for project and platform hooks

- Replaced currentProject with project in useDeleteColumnMutation

- Added changeset for minor version bump


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>useDeleteColumnMutation.ts</strong><dd><code>Update
project-related imports and references</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/database/dataGrid/hooks/useDeleteColumnMutation/useDeleteColumnMutation.ts

<li>Updated imports for useIsPlatform and useProject<br> <li> Replaced
useCurrentWorkspaceAndProject with useProject<br> <li> Changed
currentProject references to project<br> <li> Updated appUrl and
adminSecret generation


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3153/files#diff-eff2d2bcd4fa70a1ca2cfdc3ac5960d1a9ed27fe29d42b8baf31f8f74f0308fa">+6/-6</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>two-dodos-jam.md</strong><dd><code>Add changeset for
minor version bump</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/two-dodos-jam.md

<li>Added new changeset file<br> <li> Specified minor version bump for
@nhost/dashboard<br> <li> Included fix description for column deletion


</details>


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

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

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-01-23 13:23:13 -05:00
robertkasza
e515e71c8b chore: upgrade nodejs and pnpm version in nix config (#3152)
### **PR Type**
Enhancement


___

### **Description**
- Upgrade Node.js from v18 to v20

- Update PNPM from nodePackages.pnpm to pnpm_9

- Modify nix configuration files for dependencies


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Configuration
changes</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>flake.nix</strong><dd><code>Update PNPM version in
build inputs and dev shells</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

flake.nix

<li>Replace <code>nodePackages.pnpm</code> with <code>pnpm_9</code> in
nativeBuildInputs<br> <li> Update devShells to use <code>pnpm_9</code>
instead of <code>nodePackages.pnpm</code>


</details>


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

</tr>

<tr>
  <td>
    <details>
<summary><strong>overlay.nix</strong><dd><code>Upgrade Node.js version
in Nix overlay</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

nix/overlay.nix

- Upgrade Node.js from `nodejs-18_x` to `nodejs_20`


</details>


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

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

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
2025-01-23 15:04:31 +01:00
David BM
1246e0024a chore: update actions/upload-artifact to v4 (#3138)
### **PR Type**
Enhancement


___

### **Description**
- Update actions/upload-artifact from v3 to v4


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Dependencies</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>ci.yaml</strong><dd><code>Upgrade
actions/upload-artifact to latest version</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.github/workflows/ci.yaml

- Updated actions/upload-artifact from v3 to v4


</details>


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

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-22 12:02:31 -05:00
David BM
81cc9b3810 chore (docs): add missing images in permissions API (#3144)
### **PR Type**
Documentation


___

### **Description**
- Update image paths in permissions API documentation

- Add changeset for minor version bump

- Improve readability of permissions guide


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>five-panthers-swim.md</strong><dd><code>Add changeset
for minor docs update</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/five-panthers-swim.md

<li>Add new changeset file for minor version bump<br> <li> Specify
changes for '@nhost/docs' package


</details>


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

</tr>

<tr>
  <td>
    <details>
<summary><strong>permissions.mdx</strong><dd><code>Update image paths in
permissions guide</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

docs/guides/api/permissions.mdx

<li>Update image paths for insert and select permissions<br> <li>
Replace '/img/graphql/permissions/' with '/images/guides/graphql/'


</details>


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

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-20 06:41:58 -05:00
David BM
5c6ff6efc8 fix (dashboard): correct StorageErrorPayload TypeScript typing (#3137)
### **User description**
Resolves #2440


___

### **PR Type**
Bug fix


___

### **Description**
- Corrected StorageErrorPayload TypeScript typing

- Refactored error handling in file upload

- Improved consistency of error object structure

- Added changeset for version bump


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>upload.ts</strong><dd><code>Refactor error handling in
file upload</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

packages/hasura-storage-js/src/utils/upload.ts

<li>Refactored error handling in <code>fetchUpload</code> function<br>
<li> Created consistent <code>StorageErrorPayload</code> object<br> <li>
Updated error object structure in both success and error callbacks<br>
<li> Improved type safety and error message handling


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3137/files#diff-806cf228c0fefb0c00e2b79108f101e2a26776c19578512ffc3d47ecafe59a5a">+12/-6</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>wet-pants-promise.md</strong><dd><code>Add changeset
for StorageErrorPayload fix</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

.changeset/wet-pants-promise.md

<li>Added new changeset file<br> <li> Specified minor version bump for
'@nhost/hasura-storage-js'<br> <li> Described fix for
StorageErrorPayload TypeScript typing


</details>


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

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-20 06:40:50 -05:00
David Barroso
1956ed23f8 chore (docs): added pgmq extension to postgres docs (#3141)
Fixes #3131 

### **PR Type**
Enhancement, Documentation


___

### **Description**
- Added pgmq extension to Postgres docs

- Updated extensions table with pgmq details

- Included pgmq installation and uninstallation instructions

- Added GitHub resource link for pgmq


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>cyan-suits-provide.md</strong><dd><code>Add changeset
for pgmq documentation update</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

.changeset/cyan-suits-provide.md

<li>Added changeset file for documentation update<br> <li> Specified
patch version bump for @nhost/docs


</details>


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

</tr>

<tr>
  <td>
    <details>
<summary><strong>extensions.mdx</strong><dd><code>Add pgmq extension
details and instructions</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

docs/guides/database/extensions.mdx

<li>Added pgmq to the extensions table<br> <li> Included detailed
section on pgmq extension<br> <li> Provided installation and
uninstallation SQL commands<br> <li> Added GitHub resource link for pgmq


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3141/files#diff-7a41fa45d84db83a8c01a76ddb42ad614022ad94a4c3a6aa321f5b9a5300da8c">+25/-0</a>&nbsp;
&nbsp; </td>

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-17 14:48:28 +01:00
David Barroso
af34015dbe chore (docs): add note about encryption at rest (#3142)
### **PR Type**
Enhancement, Documentation


___

### **Description**
- Add note about encryption at rest

- Explain encryption for storage, database, and Run services

- Provide warning about volume encryption status

- Include instructions for enabling encryption on older volumes


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>brown-suits-drive.md</strong><dd><code>Add changeset
for encryption at rest documentation</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/brown-suits-drive.md

<li>Add changeset file for documentation update<br> <li> Specify patch
version bump for '@nhost/docs'


</details>


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

</tr>

<tr>
  <td>
    <details>
<summary><strong>compute-resources.mdx</strong><dd><code>Add Encryption
at Rest section to compute resources documentation</code></dd></summary>
<hr>

docs/platform/compute-resources.mdx

<li>Add new section on Encryption at Rest<br> <li> Explain encryption
for storage, database, and Run services<br> <li> Include warning about
volume encryption status<br> <li> Provide instructions for enabling
encryption on older volumes


</details>


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

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-17 14:46:38 +01:00
David Barroso
88919a3d99 chore (docs): added support for nodejs22 to functions (#3140)
### **PR Type**
Enhancement, Documentation


___

### **Description**
- Added support for Node.js 22 runtime in functions

- Updated documentation to include Node.js 22 option

- Added changeset for patch version bump


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>forty-keys-buy.md</strong><dd><code>Add changeset for
Node.js 22 support</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/forty-keys-buy.md

<li>Added new changeset file for patch version bump<br> <li> Specified
'@nhost/docs' package for the change


</details>


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

</tr>

<tr>
  <td>
    <details>
<summary><strong>runtimes.mdx</strong><dd><code>Update documentation
with Node.js 22 runtime support</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

docs/guides/functions/runtimes.mdx

<li>Added Node.js 22 to the list of supported runtimes<br> <li> Included
configuration example for Node.js 22 in <code>nhost.toml</code>


</details>


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

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-17 14:46:26 +01:00
github-actions[bot]
ab26a57d05 chore: update versions (#3134)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @nhost/dashboard@2.15.0

### Minor Changes

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

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-01-16 08:24:00 -05:00
David BM
f1052a8826 fix (dashboard): undefined is not an object issue with paused projects (#3136)
### **User description**
Fixes #3127


___

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


___

### **Description**
- Fix undefined errors in paused projects

- Improve loading states across components

- Handle project and org loading separately

- Update project.id usage for consistency


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><details><summary>1 files</summary><table>
<tr>
<td><strong>SubscriptionPlan.tsx</strong><dd><code>Fix undefined error
in org plan handling</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-2a5f070869055286b669e382b18d656935752803b9a1ef13390ac028c2a48ac4">+3/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

</table></details></td></tr><tr><td><strong>Enhancement</strong></td><td><details><summary>13
files</summary><table>
<tr>
<td><strong>TransferProjectDialog.tsx</strong><dd><code>Add loading
state for project and orgs</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-b68d4641a67e07a8bf8c14e1f705059c564e1bca53e591783581af27a488d86e">+7/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>AISettings.tsx</strong><dd><code>Improve loading handling in
AI settings</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-6ec092fc4af4c9acd11edb4ae69ff6ad6e8e984c761148836c9fde8daaa6e9a4">+12/-11</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>AppLoader.tsx</strong><dd><code>Add loading screen for
project data</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-fdef910b2c808595c77cb3c0ae573db3ff57cdb4a8161db2e36e86ec548b9b6f">+18/-13</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>AuthDomain.tsx</strong><dd><code>Handle project loading in
Auth Domain</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-4b8e1e15fc7df8fe284298d5ab47dbc3f554888f98e39f84c4ac995f35c10c86">+8/-4</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>HasuraDomain.tsx</strong><dd><code>Add project loading check
in Hasura Domain</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-334177cc61035493cfca775de96635b58d98a28856067048dcfba6cd7f255978">+8/-4</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>ServerlessFunctionsDomain.tsx</strong><dd><code>Include
project loading in Serverless Functions Domain</code>&nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-e7cf7b49535f816a9c2c60cf1f8b975036bd6a988e4295529e999075d72044ef">+8/-4</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>MetricsSettings.tsx</strong><dd><code>Improve loading state
in Metrics Settings</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-957bb404fee8d18aa45af9e878837d311b69d9805ac16fe8d2c0e9d3b431e906">+15/-6</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>backups.tsx</strong><dd><code>Refactor Backups page for
better loading</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-11c24d569a8109344819d2cc9ce6ffbcf3b75abfba604e299c01289690d322f9">+8/-8</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>authentication.tsx</strong><dd><code>Enhance loading logic
in Authentication Settings</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-d7d59ce72b8bf8a15db18d8dd5132db73cd00c6f99dd1cf58bc2eca676ea1e23">+3/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>custom-domains.tsx</strong><dd><code>Add loading indicator
for Custom Domains</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-e35b13396a4aa0b96e35dd7a0b1a27d188c0d45fe20cbda99e2fd59b83da5574">+6/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>database.tsx</strong><dd><code>Improve loading state in
Database Settings</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-00045ae38a73178045bcda39c80a03a0cb46413641586896a628c3a2a22c7855">+3/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>index.tsx</strong><dd><code>Enhance loading and form reset
in Settings</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-b4185be97a505e25badcdefe31ea86fa9d69f72264c4bb35eae17fba936a3d47">+11/-3</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>metrics.tsx</strong><dd><code>Refactor Metrics Settings page
loading</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-f1cb73960dad3c0714aa08f92457282533feaa9b97b1c4f8cac572244a9e070c">+11/-15</a>&nbsp;
</td>

</tr>

</table></details></td></tr><tr><td><strong>Formatting</strong></td><td><details><summary>1
files</summary><table>
<tr>
<td><strong>LogsHeader.tsx</strong><dd><code>Minor formatting changes in
Logs Header</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-ebb3285aa776c9c5ea8b72672c4aafd55994c6c694998bbf56ca9c56d1e77664">+10/-10</a>&nbsp;
</td>

</tr>

</table></details></td></tr><tr><td><strong>Documentation</strong></td><td><details><summary>1
files</summary><table>
<tr>
<td><strong>angry-zoos-learn.md</strong><dd><code>Add changeset for
dashboard stability improvements</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3136/files#diff-5ada479d7003769072ae842fdcc5555f7b336466da44dfce5f841b2698382cbc">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-15 18:02:09 -05:00
David BM
30daa4146e fix (dashboard): update links to docs in overview (#3135)
### **PR Type**
Bug fix, Documentation


___

### **Description**
- Update documentation links in project overview page

- Change 'platform' to 'product' in doc URLs

- Modify links for Database, GraphQL API, Authentication, Storage

- Add changeset for version tracking


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>features.tsx</strong><dd><code>Update documentation
links in features array</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

dashboard/src/features/orgs/projects/overview/features/features.tsx

<li>Updated documentation links for Database, GraphQL API,
Authentication, <br>and Storage features<br> <li> Changed URL path from
'platform' to 'product' in all links


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3135/files#diff-036778e07a1cdf33b7d90d8110f75338f8cd6870cc68bb75cff0c880318cd92d">+4/-4</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Configuration
changes</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>early-lobsters-grow.md</strong><dd><code>Add changeset
for documentation link updates</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/early-lobsters-grow.md

<li>Added new changeset file for version tracking<br> <li> Specified
minor version bump for '@nhost/dashboard'<br> <li> Included description
of the fix


</details>


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

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-13 11:08:08 -05:00
David BM
7537237465 feat (dashboard): image preview toggle in storage (#3122)
### **User description**
Resolves #2814


___

### **PR Type**
Enhancement


___

### **Description**
- Add image preview toggle in storage

- Implement preview header with switch control

- Refactor data grid components and imports

- Update file preview functionality


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>21
files</summary><table>
<tr>
<td><strong>DataBrowserGridControls.tsx</strong><dd><code>Update import
paths for data grid components</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-640ce3e15c8d5f35d8bbe74792c59493afe5bc69873d2a40f81233da2b02661c">+6/-6</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>DataGrid.tsx</strong><dd><code>Refactor import paths for
data grid components</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-3bc6476aed14d8e4f26134fa452d22c41b6d3ecb0989871a8a99230a82496474">+8/-8</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>DataGridBody.tsx</strong><dd><code>Update import paths for
data grid components</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-e5cdb81b2c99dbd7b9a669a63ed503f6964e9c0bc91ca2c0e61df5334eaa7a1b">+4/-4</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>DataGridBooleanCell.tsx</strong><dd><code>Update import
paths for data grid components</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-b700eacab9c73b147e248ce58d47a208c1e499124a20444efd73db7ecb68505f">+3/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>DataGridCell.tsx</strong><dd><code>Update import path for
DataBrowserGridCell type</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-0049e6acaddf9f9b60fe43a1fbb2657564bd019e690d0361aae39f44a03adaa2">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>DataGridConfigContext.ts</strong><dd><code>Update import
path for UseDataGridReturn type</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-597368f6e75d76d9a5956f816eaa8c82177b49e1e0d20c027fd85bef81347786">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>DataGridConfigProvider.tsx</strong><dd><code>Update import
path for UseDataGridReturn type</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-ec52aa04de1bfb16370e811e294efdb3389ee929c2f75f90981933e89ea26a5d">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>useDataGridConfig.ts</strong><dd><code>Update import path
for UseDataGridReturn type</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-dee956f638a871543fef38fc6b35f2f5e0e7dfcc449b61377d2c5613f24f13d4">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>DataGridDateCell.tsx</strong><dd><code>Update import paths
for data grid components</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-95e5b8780946ddb0c020be73a0646e7627c90ea7cc63a408346a434d1f12938e">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>DataGridDecimalCell.tsx</strong><dd><code>Update import
paths for data grid components</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-9ad38d4c8a67f8daf6020b9782cb1d7a4933e2901b4937a597a2c19c2367d7d0">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>DataGridFrame.tsx</strong><dd><code>Update import path for
useDataGridConfig hook</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-d4b27ea795d9008758b8eb7d54d4f4f982cf19818a8bde118afe1c46e12088bc">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>DataGridHeader.tsx</strong><dd><code>Refactor DataGridHeader
component and add DataGridHeaderButton</code></dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-3f5f16ea95a730255a07806c96b55fd4946c92eebcb869cdf83ad92bfe034b4c">+10/-51</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>DataGridHeaderButton.tsx</strong><dd><code>Add new
DataGridHeaderButton component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-4e9624559165361950af94e0775337d6937c300e4184106f08975e9b324c3010">+77/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>index.ts</strong><dd><code>Add index file for
DataGridHeaderButton component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-1afcdd509c37753c21ff73cc4d1c63d2f8ed30a7e629a676b48d60c6c2fe0fb8">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>DataGridIntegerCell.tsx</strong><dd><code>Update import
paths for data grid components</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-9db68b16a44a34c57b847023c1dd2f74e486b0a028f84fcc0cc1f29e0ff38f0d">+4/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>DataGridPreviewCell.tsx</strong><dd><code>Implement preview
toggle functionality in DataGridPreviewCell</code></dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-d7bffe5896d2c9bac505fa9675790c59549d4fb35a2ad0cce903cc0aa31a8321">+15/-4</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>DataGridTextCell.tsx</strong><dd><code>Update import paths
for data grid components</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-d1ed74fe8eb7a61053dfe908966311e13915ad2127ee107b62f725d6c5282492">+4/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>FilesDataGrid.tsx</strong><dd><code>Add PreviewHeader
component to FilesDataGrid</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-18c8df727e1a4fc6a94d03bd4a3a7a8cb3ad44d754803c4c7988c1c00a4b7caf">+5/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>FilesDataGridControls.tsx</strong><dd><code>Update import
paths for data grid components</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-b85b40168e9c149331a68cb1a0cbec570c75233fa34385945e094b8f4c032974">+3/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>PreviewHeader.tsx</strong><dd><code>Add new PreviewHeader
component with toggle switch</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-a435cd33ed8c3cd8cfde506860a5e4d2f84605548292bc0d92b63b55d664ddca">+23/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>index.ts</strong><dd><code>Add index file for PreviewHeader
component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-18b97d53e328ea33285d6a209f6d535a93d3fde2bcae2c21c59014807f7d0e7a">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

</table></details></td></tr><tr><td><strong>Documentation</strong></td><td><details><summary>1
files</summary><table>
<tr>
<td><strong>twelve-llamas-tap.md</strong><dd><code>Add changeset for
image preview toggle feature</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/nhost/nhost/pull/3122/files#diff-275dd9152aa4b1730808a63caaf49742e808c7b53b67b5505b828e6210c83c52">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-13 07:11:39 -05:00
github-actions[bot]
76e77da5de chore: update versions (#3124)
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.10.0

### Minor Changes

-   04d2ce1: feat: add signin security key with user handle

### Patch Changes

-   44c1e17: chore: update `msw` to v1.3.5 to fix vulnerabilities

## @nhost/react@3.9.0

### Minor Changes

-   04d2ce1: feat: add signin security key with user handle

### Patch Changes

-   @nhost/nhost-js@3.2.3

## @nhost/vue@2.9.0

### Minor Changes

-   04d2ce1: feat: add signin security key with user handle

### Patch Changes

-   @nhost/nhost-js@3.2.3

## @nhost/apollo@8.0.3

### Patch Changes

-   @nhost/nhost-js@3.2.3

## @nhost/react-apollo@16.0.0

### Patch Changes

-   Updated dependencies [04d2ce1]
    -   @nhost/react@3.9.0
    -   @nhost/apollo@8.0.3

## @nhost/react-urql@13.0.0

### Patch Changes

-   Updated dependencies [04d2ce1]
    -   @nhost/react@3.9.0

## @nhost/nextjs@2.2.1

### Patch Changes

-   Updated dependencies [04d2ce1]
    -   @nhost/react@3.9.0

## @nhost/nhost-js@3.2.3

### Patch Changes

-   Updated dependencies [44c1e17]
-   Updated dependencies [04d2ce1]
    -   @nhost/hasura-auth-js@2.10.0

## @nhost/dashboard@2.14.0

### Minor Changes

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

### Patch Changes

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

## @nhost/docs@2.26.0

### Minor Changes

-   04d2ce1: feat: add reference documentation for signin security key

### Patch Changes

-   1fa6cc4: chore: added docs for pg_jsonschema

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

### Minor Changes

- 04d2ce1: feat: update signin components to use `useSignInSecuritykey`
with user handle

### Patch Changes

-   Updated dependencies [04d2ce1]
    -   @nhost/react@3.9.0
    -   @nhost/react-apollo@16.0.0

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

### Minor Changes

- 04d2ce1: feat: update signin components to use `useSignInSecuritykey`
with user handle

### Patch Changes

-   Updated dependencies [04d2ce1]
    -   @nhost/vue@2.9.0
    -   @nhost/nhost-js@3.2.3
    -   @nhost/apollo@8.0.3

## @nhost-examples/cli@0.3.16

### Patch Changes

-   @nhost/nhost-js@3.2.3

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

### Patch Changes

-   Updated dependencies [04d2ce1]
    -   @nhost/react@3.9.0
    -   @nhost/react-apollo@16.0.0

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

### Patch Changes

-   Updated dependencies [04d2ce1]
    -   @nhost/react@3.9.0

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

### Patch Changes

-   Updated dependencies [04d2ce1]
    -   @nhost/react@3.9.0
    -   @nhost/react-urql@13.0.0

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

### Patch Changes

-   @nhost/nhost-js@3.2.3

## @nhost-examples/nextjs@0.4.1

### Patch Changes

-   Updated dependencies [04d2ce1]
    -   @nhost/react@3.9.0
    -   @nhost/react-apollo@16.0.0
    -   @nhost/nextjs@2.2.1

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

### Patch Changes

-   @nhost/nhost-js@3.2.3

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

### Patch Changes

-   @nhost/nhost-js@3.2.3

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

### Patch Changes

-   Updated dependencies [04d2ce1]
    -   @nhost/react@3.9.0

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

### Patch Changes

-   Updated dependencies [04d2ce1]
    -   @nhost/react@3.9.0
    -   @nhost/react-apollo@16.0.0

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

### Patch Changes

-   Updated dependencies [04d2ce1]
    -   @nhost/vue@2.9.0
    -   @nhost/apollo@8.0.3

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-01-10 17:48:29 +01:00
Hassan Ben Jobrane
04d2ce110a feat: add support for webauthn modern flow (#3097)
### **User description**
resolves https://github.com/nhost/nhost/issues/3031


___

### **PR Type**
Enhancement


___

### **Description**
- Implemented WebAuthn-based security key authentication flow
- Added new `useSignInSecurityKey` hook for React applications
- Updated authentication machine to support security key sign-in
- Simplified security key sign-in process by removing email input
requirement
- Added `useSignInEmailOTP` hook for email OTP authentication
- Updated auth version in example configuration



___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>8
files</summary><table>
<tr>
  <td>
    <details>
<summary><strong>sign-in-security-key.tsx</strong><dd><code>Simplify
security key sign-in process</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


examples/react-apollo/src/components/routes/auth/sign-in/sign-in-security-key.tsx

<li>Removed email input and form-related imports and components<br> <li>
Replaced <code>useSignInEmailSecurityKey</code> with
<code>useSignInSecurityKey</code><br> <li> Simplified sign-in process to
use <code>signInSecurityKey</code> without email<br>


</details>


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

</tr>

<tr>
  <td>
    <details>
<summary><strong>events.ts</strong><dd><code>Add new security key
sign-in event</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

packages/hasura-auth-js/src/machines/authentication/events.ts

- Added new event type `SIGNIN_SECURITY_KEY`



</details>


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

</tr>

<tr>
  <td>
    <details>
<summary><strong>machine.ts</strong><dd><code>Implement WebAuthn-based
security key authentication</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

packages/hasura-auth-js/src/machines/authentication/machine.ts

<li>Added <code>signInSecurityKey</code> service<br> <li> Implemented
new state for security key authentication<br> <li> Added WebAuthn-based
authentication logic<br>


</details>


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

</tr>

<tr>
  <td>
    <details>
<summary><strong>index.ts</strong><dd><code>Export new security key
sign-in module</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

packages/hasura-auth-js/src/promises/index.ts

- Exported `signInSecurityKey` module



</details>


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

</tr>

<tr>
  <td>
    <details>
<summary><strong>signInSecurityKey.ts</strong><dd><code>Add security key
sign-in promise and types</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

packages/hasura-auth-js/src/promises/signInSecurityKey.ts

<li>Implemented <code>signInSecurityKeyPromise</code> function<br> <li>
Added types and interfaces for security key sign-in<br>


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3097/files#diff-4bbb85594a3d42a1b0ae555ceb2cd468e4dba9904ba59b189bfc76bdd61a92b3">+70/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>index.ts</strong><dd><code>Export new security key
sign-in hook</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

packages/react/src/index.ts

- Exported `useSignInSecurityKey` hook



</details>


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

</tr>

<tr>
  <td>
    <details>
<summary><strong>useSignInEmailOTP.ts</strong><dd><code>Add email OTP
sign-in hook</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

packages/react/src/useSignInEmailOTP.ts

- Implemented `useSignInEmailOTP` hook for email OTP authentication



</details>


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

</tr>

<tr>
  <td>
    <details>
<summary><strong>useSignInSecurityKey.ts</strong><dd><code>Implement
security key sign-in hook</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

packages/react/src/useSignInSecurityKey.ts

<li>Implemented <code>useSignInSecurityKey</code> hook for
WebAuthn-based <br>authentication<br> <li> Added types and interfaces
for the hook<br>


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3097/files#diff-67332920be590dafee3e397f2134dcb174b61e23b65ce32a7cafcb38dd61e331">+94/-0</a>&nbsp;
&nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Configuration
changes</strong></td><td><details><summary>1 files</summary><table>
<tr>
  <td>
    <details>
<summary><strong>nhost.toml</strong><dd><code>Update auth version in
configuration</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

examples/react-apollo/nhost/nhost.toml

- Updated auth version from '0.32.1' to '0.36.1'



</details>


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

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-10 16:59:29 +01:00
David Barroso
b2755045c9 chore: added overlay for nhost cli (#3126)
### **PR Type**
Enhancement


___

### **Description**
- Add Nhost CLI package to Nix configuration

- Define Nhost CLI version and platform-specific distributions

- Implement Nix derivation for Nhost CLI installation

- Update overlay to include Nhost CLI package


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>nhost-cli.nix</strong><dd><code>Implement Nix package
for Nhost CLI</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

nix/nhost-cli.nix

<li>Define Nhost CLI version and platform-specific distributions<br>
<li> Implement Nix derivation for Nhost CLI installation<br> <li> Set up
build and installation process<br> <li> Define package metadata and
maintainer information


</details>


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

</tr>
</table></td></tr><tr><td><strong>Configuration
changes</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>overlay.nix</strong><dd><code>Update overlay to include
Nhost CLI package</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

nix/overlay.nix

- Add Nhost CLI package to the Nix overlay


</details>


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

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-09 15:36:17 +01:00
David BM
d43931e761 fix (dashboard): invalid organization slug/project subdomain opens 404 page (#3125)
### **User description**
Fixes #3119


___

### **PR Type**
Bug fix


___

### **Description**
- Fix 404 redirect for invalid org slug/project subdomain

- Improve conditional checks in useNotFoundRedirect hook

- Add project and org loading states

- Update URL parameter handling and comparisons


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>useNotFoundRedirect.ts</strong><dd><code>Enhance
useNotFoundRedirect hook for better 404 handling</code>&nbsp;
</dd></summary>
<hr>


dashboard/src/features/projects/common/hooks/useNotFoundRedirect/useNotFoundRedirect.ts

<li>Added imports for useCurrentOrg and useProject hooks<br> <li>
Updated URL parameter handling and comparisons<br> <li> Introduced
project and org loading states<br> <li> Improved conditional checks for
404 redirect


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3125/files#diff-837279cf43199053bca09913f62c4af019063a2e8dc7bfb7643ec54b7cecd29d">+31/-9</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>light-dryers-invite.md</strong><dd><code>Add changeset
for 404 page fix</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

.changeset/light-dryers-invite.md

<li>Added changeset file for version bump<br> <li> Described fix for
invalid org slug/project subdomain 404 issue


</details>


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

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-09 14:17:31 +01:00
Hassan Ben Jobrane
44c1e17fd5 chore: update dependencies with vulnerabilities (#3105)
### **User description**
resolves https://github.com/nhost/nhost/issues/3031


___

### **PR Type**
Enhancement


___

### **Description**
- Updated `audit-ci.jsonc` configuration:
- Removed 'micromatch' and 'path-to-regexp' from the allowlist,
potentially increasing security checks
- Modified `package.json`:
  - Added 'path-to-regexp' dependency (version ^8.2.0)
- These changes aim to address vulnerabilities and update dependencies



___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Configuration
changes</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>audit-ci.jsonc</strong><dd><code>Update allowlist in
audit-ci configuration</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

audit-ci.jsonc

- Removed 'micromatch' and 'path-to-regexp' from the allowlist


</details>


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

</tr>
</table></td></tr><tr><td><strong>Dependencies</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>package.json</strong><dd><code>Add path-to-regexp
dependency</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

package.json

- Added 'path-to-regexp' dependency with version '^8.2.0'


</details>


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

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-09 00:21:00 +01:00
David BM
5df6fa2d0b feat (dashboard): unencrypted disk warning (#3116)
### **User description**
Resolves #3050


___

### **PR Type**
Enhancement


___

### **Description**
- Add unencrypted disk warning in storage capacity settings

- Implement query for persistent volumes encryption status

- Display alert for enabling disk encryption

- Update GraphQL types and queries


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>DatabaseStorageCapacity.tsx</strong><dd><code>Add
unencrypted disk warning and encryption info</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


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

<li>Import new UI components (Alert, Link, Text)<br> <li> Add query for
persistent volumes encryption status<br> <li> Implement conditional
rendering of encryption warning<br> <li> Display alert with instructions
to enable encryption


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3116/files#diff-097a59d13b44816051386182a444eadfe2dcacd69b88c121af6733d7eca3ee43">+34/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>graphql.ts</strong><dd><code>Update GraphQL types and
add encryption query</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

dashboard/src/utils/__generated__/graphql.ts

<li>Add GetPersistentVolumesEncryptedQuery type and related
functions<br> <li> Update Organization_Member_Invites type


</details>


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

</tr>

<tr>
  <td>
    <details>

<summary><strong>getPersistentVolumesEncrypted.gql</strong><dd><code>Add
GraphQL query for persistent volumes encryption</code>&nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>


dashboard/src/features/orgs/projects/database/settings/gql/getPersistentVolumesEncrypted.gql

- Add new GraphQL query for persistent volumes encryption status


</details>


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

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>sour-bats-repair.md</strong><dd><code>Add changeset for
unencrypted disk warning feature</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/sour-bats-repair.md

<li>Add changeset for minor version bump<br> <li> Describe new feature:
unencrypted disk warning


</details>


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

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-08 17:35:18 +01:00
David Barroso
1fa6cc47ec chore (docs): added pg_jsonschema docs (#3123)
Fixes https://github.com/nhost/nhost/issues/3101
### **PR Type**
Enhancement, Documentation


___

### **Description**
- Added pg_jsonschema extension to available extensions list

- Included documentation for pg_jsonschema extension usage

- Updated extensions table with pg_jsonschema details

- Minor formatting changes in the document


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>loud-years-know.md</strong><dd><code>Add changeset for
pg_jsonschema documentation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

.changeset/loud-years-know.md

<li>Added changeset file for @nhost/docs patch<br> <li> Described change
as adding docs for pg_jsonschema


</details>


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

</tr>

<tr>
  <td>
    <details>
<summary><strong>extensions.mdx</strong><dd><code>Add pg_jsonschema
extension documentation</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

docs/guides/database/extensions.mdx

<li>Added pg_jsonschema to extensions table<br> <li> Included new
section with installation and usage instructions<br> <li> Provided
GitHub resource link for pg_jsonschema<br> <li> Minor formatting
adjustments


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3123/files#diff-7a41fa45d84db83a8c01a76ddb42ad614022ad94a4c3a6aa321f5b9a5300da8c">+25/-1</a>&nbsp;
&nbsp; </td>

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

___

> 💡 **PR-Agent usage**: Comment `/help "your question"` on any pull
request to receive relevant information
2025-01-08 15:04:17 +01:00
136 changed files with 2181 additions and 617 deletions

View File

@@ -163,7 +163,7 @@ jobs:
# * Run this step only if the previous step failed, and Playwright generated a report
- name: Upload Playwright Report
if: ${{ failure() && hashFiles(format('{0}/playwright-report/**', matrix.package.path)) != ''}}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: playwright-${{ steps.file-name.outputs.fileName }}
path: ${{format('{0}/playwright-report/**', matrix.package.path)}}

View File

@@ -2,5 +2,5 @@
// $schema provides code completion hints to IDEs.
"$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
"moderate": true,
"allowlist": ["vue-template-compiler", "micromatch", "path-to-regexp"]
"allowlist": ["vue-template-compiler"]
}

View File

@@ -1,5 +1,40 @@
# @nhost/dashboard
## 2.16.0
### Minor Changes
- f8e6b61: fix: can add rule groups in table permissions
- 9e404c8: fix: not redirect to 404 page if using local Nhost backend
- ac4aa01: fix: can delete column in database page
- 4385524: fix: update url to check service health in local dashboard
### Patch Changes
- @nhost/react-apollo@16.0.1
- @nhost/nextjs@2.2.2
## 2.15.0
### Minor Changes
- f1052a8: fix: improve stability of the dashboard when pausing projects
- 30daa41: fix: update links to docs in overview page
- 7537237: feat: add image preview toggle in storage
## 2.14.0
### Minor Changes
- d43931e: fix: invalid organization slug/project subdomain doesn't open 404 page
- 5df6fa2: feat: add unencrypted disk warning in storage capacity settings
### Patch Changes
- 44c1e17: chore: update `msw` to v1.3.5 to fix vulnerabilities
- @nhost/react-apollo@16.0.0
- @nhost/nextjs@2.2.1
## 2.13.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/dashboard",
"version": "2.13.0",
"version": "2.16.0",
"private": true,
"scripts": {
"preinstall": "npx only-allow pnpm",
@@ -177,7 +177,7 @@
"eslint-plugin-react-hooks": "^4.6.0",
"jsdom": "^22.1.0",
"lint-staged": "^15.2.2",
"msw": "^1.3.3",
"msw": "^1.3.5",
"msw-storybook-addon": "^1.10.0",
"node-fetch": "^3.3.2",
"postcss": "^8.4.38",

View File

@@ -8,6 +8,7 @@ import {
DialogTitle,
} from '@/components/ui/v3/dialog';
import { LoadingScreen } from '@/components/presentational/LoadingScreen';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import {
Form,
@@ -53,8 +54,8 @@ export default function TransferProjectDialog({
}: TransferProjectDialogProps) {
const { push } = useRouter();
const currentUserId = useUserId();
const { project } = useProject();
const { orgs, currentOrg } = useOrgs();
const { project, loading: projectLoading } = useProject();
const { orgs, currentOrg, loading: orgsLoading } = useOrgs();
const [transferProject] = useBillingTransferAppMutation();
const form = useForm<z.infer<typeof transferProjectFormSchema>>({
@@ -96,6 +97,10 @@ export default function TransferProjectDialog({
member.user.id === userId,
);
if (projectLoading || orgsLoading) {
return <LoadingScreen />;
}
return (
<Dialog
open={open}

View File

@@ -61,7 +61,7 @@ export default function AISettings() {
const [updateConfig] = useUpdateConfigMutation({
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { project } = useProject();
const { project, loading: loadingProject } = useProject();
const [aiServiceEnabled, setAIServiceEnabled] = useState(true);
@@ -73,9 +73,10 @@ export default function AISettings() {
error: errorGettingAiSettings,
} = useGetAiSettingsQuery({
variables: {
appId: project.id,
appId: project?.id,
},
...(!isPlatform ? { client: localMimirClient } : {}),
skip: !project?.id,
});
const { data: graphiteVersionsData, loading: loadingGraphiteVersionsData } =
@@ -192,11 +193,11 @@ export default function AISettings() {
}
};
if (loadingAiSettings || loadingGraphiteVersionsData) {
if (loadingProject || loadingAiSettings || loadingGraphiteVersionsData) {
return (
<ActivityIndicator
delay={1000}
label="Loading Postgres version..."
label="Loading AI settings..."
className="justify-center"
/>
);
@@ -269,7 +270,7 @@ export default function AISettings() {
return (
<Box className="space-y-4" sx={{ backgroundColor: 'background.default' }}>
<Box className="flex flex-row items-center justify-between p-4 rounded-lg border-1">
<Box className="flex flex-row items-center justify-between rounded-lg border-1 p-4">
<Text className="text-lg font-semibold">Enable AI service</Text>
<Switch
checked={aiServiceEnabled}
@@ -298,7 +299,7 @@ export default function AISettings() {
<Tooltip title="Version of the service to use.">
<InfoIcon
aria-label="Info"
className="w-4 h-4"
className="h-4 w-4"
color="primary"
/>
</Tooltip>
@@ -353,7 +354,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="w-4 h-4"
className="h-4 w-4"
color="primary"
/>
</Tooltip>
@@ -377,7 +378,7 @@ export default function AISettings() {
<Tooltip title="Dedicated resources allocated for the service.">
<InfoIcon
aria-label="Info"
className="w-4 h-4"
className="h-4 w-4"
color="primary"
/>
</Tooltip>
@@ -417,7 +418,7 @@ export default function AISettings() {
<Tooltip title="Key to use for authenticating API requests to OpenAI">
<InfoIcon
aria-label="Info"
className="w-4 h-4"
className="h-4 w-4"
color="primary"
/>
</Tooltip>
@@ -440,7 +441,7 @@ export default function AISettings() {
<Tooltip title="Optional. OpenAI organization to use.">
<InfoIcon
aria-label="Info"
className="w-4 h-4"
className="h-4 w-4"
color="primary"
/>
</Tooltip>
@@ -468,7 +469,7 @@ export default function AISettings() {
<Tooltip title="How often to run the job that keeps embeddings up to date.">
<InfoIcon
aria-label="Info"
className="w-4 h-4"
className="h-4 w-4"
color="primary"
/>
</Tooltip>

View File

@@ -1,4 +1,5 @@
import { ContactUs } from '@/components/common/ContactUs';
import { LoadingScreen } from '@/components/presentational/LoadingScreen';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Button } from '@/components/ui/v2/Button';
import { Dropdown } from '@/components/ui/v2/Dropdown';
@@ -6,7 +7,7 @@ import { Text } from '@/components/ui/v2/Text';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { useInterval } from '@/hooks/useInterval';
import { getRelativeDateByApplicationState } from '@/utils/helpers';
import { useState } from 'react';
import { useEffect, useState } from 'react';
export interface AppLoaderProps {
/**
@@ -33,25 +34,31 @@ export default function AppLoader({
date,
restoring,
}: AppLoaderProps) {
const { project } = useProject();
const { project, loading } = useProject();
const [timeElapsed, setTimeElapsed] = useState<number>(0);
let timeElapsedSinceEventCreation: number;
useEffect(() => {
if (!project || loading) {
return;
}
if (date) {
timeElapsedSinceEventCreation = getRelativeDateByApplicationState(date);
} else if (unpause) {
timeElapsedSinceEventCreation = getRelativeDateByApplicationState(
project.appStates[0].createdAt,
);
} else {
timeElapsedSinceEventCreation = getRelativeDateByApplicationState(
project.createdAt,
);
}
let timeElapsedSinceEventCreation: number;
const [timeElapsed, setTimeElapsed] = useState(timeElapsedSinceEventCreation);
if (date) {
timeElapsedSinceEventCreation = getRelativeDateByApplicationState(date);
} else if (unpause) {
timeElapsedSinceEventCreation = getRelativeDateByApplicationState(
project.appStates[0].createdAt,
);
} else {
timeElapsedSinceEventCreation = getRelativeDateByApplicationState(
project.createdAt,
);
}
setTimeElapsed(timeElapsedSinceEventCreation);
}, [project, date, unpause, loading]);
// Would be also valuable to check the appCreatedTime so this doesn't ever appear if not created under a time limit. @GC
useInterval(
() => {
setTimeElapsed(timeElapsed + 1);
@@ -59,6 +66,10 @@ export default function AppLoader({
startLoader ? 1000 : null,
);
if (loading) {
return <LoadingScreen />;
}
return (
<div className="grid grid-flow-row gap-2">
<div className="grid grid-flow-row gap-1">
@@ -86,9 +97,9 @@ export default function AppLoader({
<ActivityIndicator className="mx-auto" />
{timeElapsed > 180 && (
<Dropdown.Root className="flex flex-col mx-auto">
<Dropdown.Root className="mx-auto flex flex-col">
<Dropdown.Trigger
className="flex mx-auto font-medium"
className="mx-auto flex font-medium"
hideChevron
asChild
>

View File

@@ -13,12 +13,12 @@ export default function useIsHealthy() {
const appUrl = generateAppServiceUrl(
project?.subdomain,
project?.region,
'auth',
'hasura',
);
const { failureCount, status } = useQuery(
['/healthz'],
() => fetch(`${appUrl}/healthz`),
['/v1/version'],
() => fetch(`${appUrl}/v1/version`),
{
enabled: !isPlatform && !!project,
retry: true,

View File

@@ -1,3 +1,4 @@
import type { ProjectFragment } from '@/utils/__generated__/graphql';
import {
getAuthServiceUrl,
getDatabaseServiceUrl,
@@ -7,7 +8,6 @@ import {
getStorageServiceUrl,
isPlatform,
} from '@/utils/env';
import type { ProjectFragment } from '@/utils/__generated__/graphql';
export type NhostService =
| 'auth'
@@ -18,21 +18,6 @@ export type NhostService =
| 'hasura'
| 'grafana';
/**
* The default slugs that are used when running the dashboard locally. These
* values are used both in local mode and when running the dashboard locally
* against the remote (either staging or production) backend.
*/
export const defaultLocalBackendSlugs: Record<NhostService, string> = {
auth: '/v1/auth',
db: '',
graphql: '/v1/graphql',
functions: '/v1/functions',
storage: '/v1/files',
hasura: '',
grafana: '',
};
/**
* The default slugs that are used when running the dashboard against the
* remote (either staging or production) backend in a cloud environment.

View File

@@ -34,7 +34,11 @@ export default function AuthDomain() {
const localMimirClient = useLocalMimirClient();
const [isVerified, setIsVerified] = useState(false);
const { project, refetch: refetchProject } = useProject();
const {
project,
refetch: refetchProject,
loading: loadingProject,
} = useProject();
const [updateConfig] = useUpdateConfigMutation({
...(!isPlatform ? { client: localMimirClient } : {}),
@@ -48,7 +52,7 @@ export default function AuthDomain() {
const { data, loading, error } = useGetAuthenticationSettingsQuery({
variables: {
appId: project.id,
appId: project?.id,
},
...(!isPlatform ? { client: localMimirClient } : {}),
});
@@ -62,7 +66,7 @@ export default function AuthDomain() {
}
}, [data, loading, form, initialValue]);
if (loading) {
if (loadingProject || loading) {
return (
<ActivityIndicator
delay={1000}
@@ -147,7 +151,7 @@ export default function AuthDomain() {
loading: formState.isSubmitting,
},
}}
className="grid grid-flow-row px-4 gap-x-4 gap-y-4 lg:grid-cols-5"
className="grid grid-flow-row gap-x-4 gap-y-4 px-4 lg:grid-cols-5"
>
<Input
{...register('auth_fqdn')}

View File

@@ -14,10 +14,14 @@ const validationSchema = Yup.object({
export type DatabaseDomainFormValues = Yup.InferType<typeof validationSchema>;
export default function DatabaseDomain() {
const { project } = useProject();
const { project, loading } = useProject();
const [dbFQDN, setDbFQDN] = useState('');
if (loading) {
return null;
}
const postgresHost = generateAppServiceUrl(
project.subdomain,
project.region,
@@ -36,7 +40,7 @@ export default function DatabaseDomain() {
className: 'hidden',
},
}}
className="grid grid-flow-row px-4 gap-x-4 gap-y-4 lg:grid-cols-5"
className="grid grid-flow-row gap-x-4 gap-y-4 px-4 lg:grid-cols-5"
>
<Input
id="database_fqdn"

View File

@@ -33,7 +33,11 @@ export default function HasuraDomain() {
const localMimirClient = useLocalMimirClient();
const [isVerified, setIsVerified] = useState(false);
const { project, refetch: refetchProject } = useProject();
const {
project,
refetch: refetchProject,
loading: loadingProject,
} = useProject();
const [updateConfig] = useUpdateConfigMutation({
...(!isPlatform ? { client: localMimirClient } : {}),
@@ -47,7 +51,7 @@ export default function HasuraDomain() {
const { data, loading, error } = useGetHasuraSettingsQuery({
variables: {
appId: project.id,
appId: project?.id,
},
...(!isPlatform ? { client: localMimirClient } : {}),
});
@@ -61,7 +65,7 @@ export default function HasuraDomain() {
}
}, [data, loading, form, initialValue]);
if (loading) {
if (loadingProject || loading) {
return (
<ActivityIndicator
delay={0}
@@ -148,7 +152,7 @@ export default function HasuraDomain() {
loading: formState.isSubmitting,
},
}}
className="grid grid-flow-row px-4 gap-x-4 gap-y-4 lg:grid-cols-5"
className="grid grid-flow-row gap-x-4 gap-y-4 px-4 lg:grid-cols-5"
>
<Input
{...register('hasura_fqdn')}

View File

@@ -35,7 +35,11 @@ export default function ServerlessFunctionsDomain() {
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const [isVerified, setIsVerified] = useState(false);
const { project, refetch: refetchProject } = useProject();
const {
project,
refetch: refetchProject,
loading: loadingProject,
} = useProject();
const [updateConfig] = useUpdateConfigMutation({
...(!isPlatform ? { client: localMimirClient } : {}),
@@ -49,7 +53,7 @@ export default function ServerlessFunctionsDomain() {
const { data, loading, error } = useGetServerlessFunctionsSettingsQuery({
variables: {
appId: project.id,
appId: project?.id,
},
...(!isPlatform ? { client: localMimirClient } : {}),
});
@@ -63,7 +67,7 @@ export default function ServerlessFunctionsDomain() {
}
}, [data, loading, form, initialValue]);
if (loading) {
if (loadingProject || loading) {
return (
<ActivityIndicator
delay={1000}
@@ -151,7 +155,7 @@ export default function ServerlessFunctionsDomain() {
loading: formState.isSubmitting,
},
}}
className="grid grid-flow-row px-4 gap-x-4 gap-y-4 lg:grid-cols-5"
className="grid grid-flow-row gap-x-4 gap-y-4 px-4 lg:grid-cols-5"
>
<Input
{...register('functions_fqdn')}

View File

@@ -1,7 +1,4 @@
import { useDialog } from '@/components/common/DialogProvider';
import { useDataGridConfig } from '@/components/dataGrid/DataGridConfigProvider';
import type { DataGridPaginationProps } from '@/components/dataGrid/DataGridPagination';
import { DataGridPagination } from '@/components/dataGrid/DataGridPagination';
import type { BoxProps } from '@/components/ui/v2/Box';
import { Box } from '@/components/ui/v2/Box';
import { Button } from '@/components/ui/v2/Button';
@@ -13,6 +10,9 @@ import { RowIcon } from '@/components/ui/v2/icons/RowIcon';
import { useDeleteRecordMutation } from '@/features/orgs/projects/database/dataGrid/hooks/useDeleteRecordMutation';
import type { DataBrowserGridColumn } from '@/features/orgs/projects/database/dataGrid/types/dataBrowser';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { useDataGridConfig } from '@/features/orgs/projects/storage/dataGrid/components/DataGridConfigProvider';
import type { DataGridPaginationProps } from '@/features/orgs/projects/storage/dataGrid/components/DataGridPagination';
import { DataGridPagination } from '@/features/orgs/projects/storage/dataGrid/components/DataGridPagination';
import { triggerToast } from '@/utils/toast';
import { useQueryClient } from '@tanstack/react-query';
import { useState } from 'react';
@@ -120,7 +120,7 @@ export default function DataBrowserGridControls({
)}
>
{numberOfSelectedRows > 0 && (
<div className="grid items-center grid-flow-col gap-2 place-content-start">
<div className="grid grid-flow-col place-content-start items-center gap-2">
<Chip
size="small"
color="info"
@@ -161,7 +161,7 @@ export default function DataBrowserGridControls({
)}
{numberOfSelectedRows === 0 && (
<div className="grid items-center grid-flow-col col-span-6 gap-2">
<div className="col-span-6 grid grid-flow-col items-center gap-2">
{columns.length > 0 && (
<DataGridPagination
className={twMerge(
@@ -177,7 +177,7 @@ export default function DataBrowserGridControls({
<Dropdown.Root>
<Dropdown.Trigger asChild hideChevron>
<Button
startIcon={<PlusIcon className="w-4 h-4" />}
startIcon={<PlusIcon className="h-4 w-4" />}
size="small"
>
Insert

View File

@@ -18,21 +18,7 @@ const ruleSchema = Yup.object().shape({
});
const ruleGroupSchema = Yup.object().shape({
operator: Yup.string().test(
'operator',
'Please select an operator.',
(selectedOperator, ctx) => {
// `from` is part of the Yup API, but it's not typed.
// @ts-ignore
const [, { value }] = ctx.from;
if (Object.keys(value.filter).length > 0 && !selectedOperator) {
return false;
}
return true;
},
),
operator: Yup.string().required('Please select an operator.'),
rules: Yup.array().of(ruleSchema),
groups: Yup.array().of(Yup.lazy(() => ruleGroupSchema) as any),
});

View File

@@ -5,12 +5,12 @@ import { Button } from '@/components/ui/v2/Button';
import { PlusIcon } from '@/components/ui/v2/icons/PlusIcon';
import { Link } from '@/components/ui/v2/Link';
import { Text } from '@/components/ui/v2/Text';
import { generateAppServiceUrl } from '@/features/orgs/projects/common/utils/generateAppServiceUrl';
import type {
Rule,
RuleGroup,
} from '@/features/orgs/projects/database/dataGrid/types/dataBrowser';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { generateAppServiceUrl } from '@/features/projects/common/utils/generateAppServiceUrl';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { useMemo } from 'react';
import { useFieldArray, useFormContext } from 'react-hook-form';
import { twMerge } from 'tailwind-merge';
@@ -68,7 +68,7 @@ export default function RuleGroupEditor({
sx,
...props
}: RuleGroupEditorProps) {
const { currentProject } = useCurrentWorkspaceAndProject();
const { project } = useProject();
const form = useFormContext();
const { control, getValues } = form;
@@ -185,13 +185,13 @@ export default function RuleGroupEditor({
<Text>
This rule group contains one or more objects (e.g: _exists) that
are not supported by our dashboard yet.{' '}
{currentProject && (
{project && (
<span>
Please{' '}
<Link
href={`${generateAppServiceUrl(
currentProject.subdomain,
currentProject.region,
project.subdomain,
project.region,
'hasura',
)}/console/data/default/schema/${schema}/tables/${table}/permissions`}
underline="hover"

View File

@@ -1,5 +1,5 @@
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import { useIsPlatform } from '@/features/orgs/projects/common/hooks/useIsPlatform';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { generateAppServiceUrl } from '@/features/projects/common/utils/generateAppServiceUrl';
import { getHasuraAdminSecret } from '@/utils/env';
import type { MutationOptions } from '@tanstack/react-query';
@@ -39,10 +39,10 @@ export default function useDeleteColumnMutation({
const {
query: { dataSourceSlug, schemaSlug, tableSlug },
} = useRouter();
const { currentProject } = useCurrentWorkspaceAndProject();
const { project } = useProject();
const appUrl = generateAppServiceUrl(
currentProject?.subdomain,
currentProject?.region,
project?.subdomain,
project?.region,
'hasura',
);
const mutationFn = isPlatform ? deleteColumn : deleteColumnMigration;
@@ -55,7 +55,7 @@ export default function useDeleteColumnMutation({
adminSecret:
process.env.NEXT_PUBLIC_ENV === 'dev'
? getHasuraAdminSecret()
: customAdminSecret || currentProject?.config?.hasura.adminSecret,
: customAdminSecret || project?.config?.hasura.adminSecret,
dataSource: customDataSource || (dataSourceSlug as string),
schema: customSchema || (schemaSlug as string),
table: customTable || (tableSlug as string),

View File

@@ -2,9 +2,12 @@ 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 { Alert } from '@/components/ui/v2/Alert';
import { Box } from '@/components/ui/v2/Box';
import { Input } from '@/components/ui/v2/Input';
import { InputAdornment } from '@/components/ui/v2/InputAdornment';
import { Link } from '@/components/ui/v2/Link';
import { Text } from '@/components/ui/v2/Text';
import { UpgradeNotification } from '@/features/orgs/projects/common/components/UpgradeNotification';
import { useAppState } from '@/features/orgs/projects/common/hooks/useAppState';
import { useIsPlatform } from '@/features/orgs/projects/common/hooks/useIsPlatform';
@@ -14,6 +17,7 @@ import { useLocalMimirClient } from '@/features/orgs/projects/hooks/useLocalMimi
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { execPromiseWithErrorToast } from '@/features/orgs/utils/execPromiseWithErrorToast';
import {
useGetPersistentVolumesEncryptedQuery,
useGetPostgresSettingsQuery,
useUpdateConfigMutation,
} from '@/generated/graphql';
@@ -57,6 +61,15 @@ export default function DatabaseStorageCapacity() {
org?.plan?.featureMaxDbSize) ||
0;
const { data: encryptedVolumesData } = useGetPersistentVolumesEncryptedQuery({
variables: { appId: project?.id },
skip: !isPlatform,
});
const showEncryptionWarning = encryptedVolumesData
? !encryptedVolumesData?.systemConfig?.persistentVolumesEncrypted
: false;
const [updateConfig] = useUpdateConfigMutation({
...(!isPlatform ? { client: localMimirClient } : {}),
});
@@ -187,6 +200,28 @@ export default function DatabaseStorageCapacity() {
isDirty={isDirty}
/>
)}
{showEncryptionWarning ? (
<Alert severity="warning" className="flex flex-col gap-3 text-left">
<div className="flex flex-col gap-2 lg:flex-row lg:justify-between">
<Text className="flex items-start gap-1 font-semibold">
Disk encryption is now available!
</Text>
</div>
<div>
<Text>
To enable encryption in this project all you have to do is
pause & unpause it in{' '}
<Link
href={`/orgs/${org?.slug}/projects/${project?.subdomain}/settings`}
underline="hover"
>
General Settings
</Link>
.
</Text>
</div>
</Alert>
) : null}
</SettingsContainer>
</Form>
</FormProvider>

View File

@@ -0,0 +1,5 @@
query GetPersistentVolumesEncrypted($appId: uuid!) {
systemConfig(appID: $appId) {
persistentVolumesEncrypted
}
}

View File

@@ -13,8 +13,8 @@ import { Tooltip } from '@/components/ui/v2/Tooltip';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { LogsRangeSelector } from '@/features/orgs/projects/logs/components/LogsRangeSelector';
import { AvailableLogsService } from '@/features/orgs/projects/logs/utils/constants/services';
import { MINUTES_TO_DECREASE_FROM_CURRENT_DATE } from '@/utils/constants/common';
import { useGetServiceLabelValuesQuery } from '@/utils/__generated__/graphql';
import { MINUTES_TO_DECREASE_FROM_CURRENT_DATE } from '@/utils/constants/common';
import { yupResolver } from '@hookform/resolvers/yup';
import { subMinutes } from 'date-fns';
import { useEffect, useState } from 'react';
@@ -55,7 +55,7 @@ export default function LogsHeader({
const { data, loading: loadingServiceLabelValues } =
useGetServiceLabelValuesQuery({
variables: { appID: project.id },
variables: { appID: project?.id },
});
useEffect(() => {
@@ -121,7 +121,7 @@ export default function LogsHeader({
<Box className="flex flex-row space-x-2">
<ControlledSelect
{...register('service')}
className="w-full text-sm font-normal min-w-fit"
className="w-full min-w-fit text-sm font-normal"
placeholder="All Services"
aria-label="Select service"
hideEmptyHelperText
@@ -165,12 +165,12 @@ export default function LogsHeader({
},
}}
title={
<div className="p-2 space-y-4">
<div className="space-y-4 p-2">
<h2>Here are some useful regular expressions:</h2>
<ul className="pl-3 space-y-2 list-disc">
<ul className="list-disc space-y-2 pl-3">
<li>
use
<code className="px-1 py-px mx-1 rounded-md bg-slate-500 text-slate-100">
<code className="mx-1 rounded-md bg-slate-500 px-1 py-px text-slate-100">
(?i)error
</code>
to search for lines with the word <b>error</b> (case
@@ -178,7 +178,7 @@ export default function LogsHeader({
</li>
<li>
use
<code className="px-1 py-px mx-1 rounded-md bg-slate-500 text-slate-100">
<code className="mx-1 rounded-md bg-slate-500 px-1 py-px text-slate-100">
error
</code>
to search for lines with the word <b>error</b> (case
@@ -186,7 +186,7 @@ export default function LogsHeader({
</li>
<li>
use
<code className="px-1 py-px mx-1 rounded-md bg-slate-500 text-slate-100">
<code className="mx-1 rounded-md bg-slate-500 px-1 py-px text-slate-100">
/metadata.*error
</code>
to search for errors in hasura&apos;s metadata endpoint
@@ -208,10 +208,10 @@ export default function LogsHeader({
</div>
}
>
<Box className="ml-2 rounded-full cursor-pointer">
<Box className="ml-2 cursor-pointer rounded-full">
<InfoIcon
aria-label="Info"
className="w-5 h-5"
className="h-5 w-5"
color="info"
/>
</Box>
@@ -224,7 +224,7 @@ export default function LogsHeader({
className="h-10"
startIcon={
loading ? (
<ActivityIndicator className="w-4 h-4" />
<ActivityIndicator className="h-4 w-4" />
) : (
<SearchIcon />
)

View File

@@ -33,15 +33,24 @@ export default function MetricsSettings() {
const isPlatform = useIsPlatform();
const { maintenanceActive } = useUI();
const localMimirClient = useLocalMimirClient();
const { project, refetch: refetchProject } = useProject();
const {
project,
refetch: refetchProject,
loading: loadingProject,
} = useProject();
const [updateConfig] = useUpdateConfigMutation({
refetchQueries: [GetObservabilitySettingsDocument],
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { data, loading, error } = useGetObservabilitySettingsQuery({
const {
data,
loading: loadingObservabilitySettings,
error,
} = useGetObservabilitySettingsQuery({
variables: { appId: project?.id },
...(!isPlatform ? { client: localMimirClient } : {}),
skip: !project?.id,
});
const { enabled: alertingEnabled } =
@@ -59,14 +68,14 @@ export default function MetricsSettings() {
const alerting = watch('enabled');
useEffect(() => {
if (!loading) {
if (!loadingObservabilitySettings) {
alertingForm.reset({
enabled: alertingEnabled,
});
}
}, [loading, alertingEnabled, alertingForm]);
}, [loadingObservabilitySettings, alertingEnabled, alertingForm]);
if (loading) {
if (loadingProject || loadingObservabilitySettings) {
return (
<ActivityIndicator
delay={1000}
@@ -124,7 +133,7 @@ export default function MetricsSettings() {
}
return (
<div className="grid max-w-5xl grid-flow-row bg-transparent gap-y-6">
<div className="grid max-w-5xl grid-flow-row gap-y-6 bg-transparent">
<FormProvider {...alertingForm}>
<Form onSubmit={handleSubmit}>
<SettingsContainer

View File

@@ -10,28 +10,28 @@ const features: CardProps[] = [
description: 'Learn how to use Postgres with Nhost',
icon: <DatabaseIcon className="h-8 w-8" sx={{ color: 'text.secondary' }} />,
disableIconBackground: true,
link: 'https://docs.nhost.io/platform/database',
link: 'https://docs.nhost.io/product/database',
},
{
title: 'GraphQL API',
description: 'Learn how to interact with the GraphQL API',
icon: <GraphQLIcon className="h-8 w-8" sx={{ color: 'text.secondary' }} />,
disableIconBackground: true,
link: 'https://docs.nhost.io/platform/graphql',
link: 'https://docs.nhost.io/product/graphql',
},
{
title: 'Authentication',
description: 'Learn how to authenticate users with Nhost',
icon: <UserIcon className="h-8 w-8" sx={{ color: 'text.secondary' }} />,
disableIconBackground: true,
link: 'https://docs.nhost.io/platform/authentication',
link: 'https://docs.nhost.io/product/authentication',
},
{
title: 'Storage',
description: 'Learn how to use Storage with Nhost',
icon: <StorageIcon className="h-8 w-8" sx={{ color: 'text.secondary' }} />,
disableIconBackground: true,
link: 'https://docs.nhost.io/platform/storage',
link: 'https://docs.nhost.io/product/storage',
},
];

View File

@@ -46,7 +46,7 @@ export default function useRunServices() {
refetch: refetchPlatformServices,
} = useGetRunServicesQuery({
variables: {
appID: project.id,
appID: project?.id,
resolve: false,
limit: limit.current,
offset,
@@ -59,7 +59,7 @@ export default function useRunServices() {
data: localServicesData,
refetch: refetchLocalServices,
} = useGetLocalRunServiceConfigsQuery({
variables: { appID: project.id as any, resolve: false },
variables: { appID: project?.id as any, resolve: false },
skip: isPlatform,
client: localMimirClient,
});

View File

@@ -1,13 +1,13 @@
import type { UseDataGridOptions } from '@/components/dataGrid/DataGrid/useDataGrid';
import { DataGridBody } from '@/components/dataGrid/DataGridBody';
import { DataGridConfigProvider } from '@/components/dataGrid/DataGridConfigProvider';
import { DataGridFrame } from '@/components/dataGrid/DataGridFrame';
import type { DataGridHeaderProps } from '@/components/dataGrid/DataGridHeader';
import { DataGridHeader } from '@/components/dataGrid/DataGridHeader';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Box } from '@/components/ui/v2/Box';
import { DataBrowserEmptyState } from '@/features/database/dataGrid/components/DataBrowserEmptyState';
import type { DataBrowserGridColumn } from '@/features/database/dataGrid/types/dataBrowser';
import { DataBrowserEmptyState } from '@/features/orgs/projects/database/dataGrid/components/DataBrowserEmptyState';
import type { DataBrowserGridColumn } from '@/features/orgs/projects/database/dataGrid/types/dataBrowser';
import type { UseDataGridOptions } from '@/features/orgs/projects/storage/dataGrid/components/DataGrid/useDataGrid';
import { DataGridBody } from '@/features/orgs/projects/storage/dataGrid/components/DataGridBody';
import { DataGridConfigProvider } from '@/features/orgs/projects/storage/dataGrid/components/DataGridConfigProvider';
import { DataGridFrame } from '@/features/orgs/projects/storage/dataGrid/components/DataGridFrame';
import type { DataGridHeaderProps } from '@/features/orgs/projects/storage/dataGrid/components/DataGridHeader';
import { DataGridHeader } from '@/features/orgs/projects/storage/dataGrid/components/DataGridHeader';
import type { ForwardedRef } from 'react';
import { forwardRef, useEffect, useRef } from 'react';
import mergeRefs from 'react-merge-refs';

View File

@@ -1,11 +1,11 @@
import type { DataGridProps } from '@/components/dataGrid/DataGrid';
import { DataGridCell } from '@/components/dataGrid/DataGridCell';
import { useDataGridConfig } from '@/components/dataGrid/DataGridConfigProvider';
import type { BoxProps } from '@/components/ui/v2/Box';
import { Box } from '@/components/ui/v2/Box';
import { Button } from '@/components/ui/v2/Button';
import { PlusIcon } from '@/components/ui/v2/icons/PlusIcon';
import type { DataBrowserGridColumn } from '@/features/database/dataGrid/types/dataBrowser';
import type { DataBrowserGridColumn } from '@/features/orgs/projects/database/dataGrid/types/dataBrowser';
import type { DataGridProps } from '@/features/orgs/projects/storage/dataGrid/components/DataGrid/DataGrid';
import { DataGridCell } from '@/features/orgs/projects/storage/dataGrid/components/DataGridCell';
import { useDataGridConfig } from '@/features/orgs/projects/storage/dataGrid/components/DataGridConfigProvider';
import type { DetailedHTMLProps, HTMLProps, KeyboardEvent } from 'react';
import { Fragment, useMemo, useRef } from 'react';
import type { Row } from 'react-table';

View File

@@ -1,8 +1,8 @@
import type { CommonDataGridCellProps } from '@/components/dataGrid/DataGridCell';
import { useDataGridCell } from '@/components/dataGrid/DataGridCell';
import { ReadOnlyToggle } from '@/components/presentational/ReadOnlyToggle';
import { Dropdown } from '@/components/ui/v2/Dropdown';
import type { KeyboardEvent as ReactKeyboardEvent, MouseEvent } from 'react';
import type { CommonDataGridCellProps } from '@/features/orgs/projects/storage/dataGrid/components/DataGridCell';
import { useDataGridCell } from '@/features/orgs/projects/storage/dataGrid/components/DataGridCell';
import type { MouseEvent, KeyboardEvent as ReactKeyboardEvent } from 'react';
import { twMerge } from 'tailwind-merge';
export type DataGridBooleanCellProps<TData extends object> =

View File

@@ -6,7 +6,7 @@ import type {
ColumnType,
DataBrowserGridCell,
DataBrowserGridCellProps,
} from '@/features/database/dataGrid/types/dataBrowser';
} from '@/features/orgs/projects/database/dataGrid/types/dataBrowser';
import { triggerToast } from '@/utils/toast';
import type {
FocusEvent,

View File

@@ -1,4 +1,4 @@
import type { UseDataGridReturn } from '@/components/dataGrid/DataGrid';
import type { UseDataGridReturn } from '@/features/orgs/projects/storage/dataGrid/components/DataGrid/useDataGrid';
import { createContext } from 'react';
const DataGridConfigContext = createContext<Partial<UseDataGridReturn>>(null);

View File

@@ -1,4 +1,4 @@
import type { UseDataGridReturn } from '@/components/dataGrid/DataGrid';
import type { UseDataGridReturn } from '@/features/orgs/projects/storage/dataGrid/components/DataGrid/useDataGrid';
import type { PropsWithChildren } from 'react';
import DataGridConfigContext from './DataGridConfigContext';

View File

@@ -1,4 +1,4 @@
import type { UseDataGridReturn } from '@/components/dataGrid/DataGrid';
import type { UseDataGridReturn } from '@/features/orgs/projects/storage/dataGrid/components/DataGrid';
import { useContext } from 'react';
import DataGridConfigContext from './DataGridConfigContext';

View File

@@ -1,8 +1,8 @@
import type { CommonDataGridCellProps } from '@/components/dataGrid/DataGridCell';
import { useDataGridCell } from '@/components/dataGrid/DataGridCell';
import { Input, inputClasses } from '@/components/ui/v2/Input';
import type { TextProps } from '@/components/ui/v2/Text';
import { Text } from '@/components/ui/v2/Text';
import type { CommonDataGridCellProps } from '@/features/orgs/projects/storage/dataGrid/components/DataGridCell';
import { useDataGridCell } from '@/features/orgs/projects/storage/dataGrid/components/DataGridCell';
import { getDateComponents } from '@/utils/getDateComponents';
import type { ChangeEvent, KeyboardEvent } from 'react';
import { twMerge } from 'tailwind-merge';

View File

@@ -1,7 +1,7 @@
import type { CommonDataGridCellProps } from '@/components/dataGrid/DataGridCell';
import { useDataGridCell } from '@/components/dataGrid/DataGridCell';
import { Input, inputClasses } from '@/components/ui/v2/Input';
import { Text } from '@/components/ui/v2/Text';
import type { CommonDataGridCellProps } from '@/features/orgs/projects/storage/dataGrid/components/DataGridCell';
import { useDataGridCell } from '@/features/orgs/projects/storage/dataGrid/components/DataGridCell';
import type { ChangeEvent, KeyboardEvent } from 'react';
export type DataGridDecimalCellProps<TData extends object> =

View File

@@ -1,4 +1,4 @@
import { useDataGridConfig } from '@/components/dataGrid/DataGridConfigProvider';
import { useDataGridConfig } from '@/features/orgs/projects/storage/dataGrid/components/DataGridConfigProvider';
import clsx from 'clsx';
import type { DetailedHTMLProps, HTMLProps } from 'react';

View File

@@ -1,5 +1,3 @@
import type { DataGridProps } from '@/components/dataGrid/DataGrid';
import { useDataGridConfig } from '@/components/dataGrid/DataGridConfigProvider';
import { Box } from '@/components/ui/v2/Box';
import { Button } from '@/components/ui/v2/Button';
import { Divider } from '@/components/ui/v2/Divider';
@@ -9,7 +7,10 @@ import { ArrowUpIcon } from '@/components/ui/v2/icons/ArrowUpIcon';
import { PencilIcon } from '@/components/ui/v2/icons/PencilIcon';
import { PlusIcon } from '@/components/ui/v2/icons/PlusIcon';
import { TrashIcon } from '@/components/ui/v2/icons/TrashIcon';
import type { DataBrowserGridColumn } from '@/features/database/dataGrid/types/dataBrowser';
import type { DataBrowserGridColumn } from '@/features/orgs/projects/database/dataGrid/types/dataBrowser';
import type { DataGridProps } from '@/features/orgs/projects/storage/dataGrid/components/DataGrid';
import { useDataGridConfig } from '@/features/orgs/projects/storage/dataGrid/components/DataGridConfigProvider';
import { DataGridHeaderButton } from '@/features/orgs/projects/storage/dataGrid/components/DataGridHeaderButton';
import type { DetailedHTMLProps, HTMLProps } from 'react';
import { twMerge } from 'tailwind-merge';
@@ -54,7 +55,7 @@ export default function DataGridHeader<T extends object>({
componentsProps,
...props
}: DataGridHeaderProps<T>) {
const { flatHeaders, allowSort, allowResize } = useDataGridConfig<T>();
const { flatHeaders } = useDataGridConfig<T>();
return (
<div
@@ -96,53 +97,11 @@ export default function DataGridHeader<T extends object>({
}}
key={column.id}
>
{column.id === 'selection' ? (
<span
{...headerProps}
className="relative grid w-full grid-flow-col items-center justify-between p-2"
>
{column.render('Header')}
</span>
) : (
<Dropdown.Trigger
className={twMerge(
'focus:outline-none motion-safe:transition-colors',
)}
disabled={
column.isDisabled || (column.disableSortBy && !onRemoveColumn)
}
hideChevron
>
<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 && (
<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>
)}
<DataGridHeaderButton
column={column}
headerProps={headerProps}
onRemoveColumn={onRemoveColumn}
/>
<Dropdown.Content
menu
PaperProps={{ className: 'w-52 mt-1' }}

View File

@@ -0,0 +1,77 @@
import { Box } from '@/components/ui/v2/Box';
import { Dropdown } from '@/components/ui/v2/Dropdown';
import { ArrowDownIcon } from '@/components/ui/v2/icons/ArrowDownIcon';
import { ArrowUpIcon } from '@/components/ui/v2/icons/ArrowUpIcon';
import type { DataBrowserGridColumn } from '@/features/orgs/projects/database/dataGrid/types/dataBrowser';
import { useDataGridConfig } from '@/features/orgs/projects/storage/dataGrid/components/DataGridConfigProvider';
import type { TableHeaderProps } from 'react-table';
import { twMerge } from 'tailwind-merge';
interface DataGridHeaderButtonProps<T extends object> {
column: DataBrowserGridColumn<T>;
headerProps: TableHeaderProps;
onRemoveColumn: (column: DataBrowserGridColumn<T>) => void;
}
export default function DataGridHeaderButton<T extends object>({
column,
headerProps,
onRemoveColumn,
}: DataGridHeaderButtonProps<T>) {
const { allowSort, allowResize } = useDataGridConfig();
if (column.id === 'selection') {
return (
<span
{...headerProps}
className="relative grid w-full grid-flow-col items-center justify-between p-2"
>
{column.render('Header')}
</span>
);
}
if (column.id === 'preview') {
return (
<div className="focus:outline-none motion-safe:transition-colors">
{column.render('Header')}
</div>
);
}
return (
<Dropdown.Trigger
className={twMerge('focus:outline-none motion-safe:transition-colors')}
disabled={column.isDisabled || (column.disableSortBy && !onRemoveColumn)}
hideChevron
>
<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 && (
<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>
);
}

View File

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

View File

@@ -1,7 +1,9 @@
import type { CommonDataGridCellProps } from '@/components/dataGrid/DataGridCell';
import { useDataGridCell } from '@/components/dataGrid/DataGridCell';
import { Input, inputClasses } from '@/components/ui/v2/Input';
import { Text } from '@/components/ui/v2/Text';
import {
useDataGridCell,
type CommonDataGridCellProps,
} from '@/features/orgs/projects/storage/dataGrid/components/DataGridCell';
import type { ChangeEvent, KeyboardEvent } from 'react';
export type DataGridIntegerCellProps<TData extends object> =

View File

@@ -9,6 +9,8 @@ import { VideoPreviewIcon } from '@/components/ui/v2/icons/VideoPreviewIcon';
import { XIcon } from '@/components/ui/v2/icons/XIcon';
import { useAppClient } from '@/features/orgs/projects/hooks/useAppClient';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { usePreviewToggle } from '@/features/orgs/projects/storage/dataGrid/hooks/usePreviewToggle';
import { useSSRLocalStorage } from '@/hooks/useSSRLocalStorage';
import clsx from 'clsx';
import type { ReactNode } from 'react';
import { useEffect, useReducer, useState } from 'react';
@@ -46,11 +48,16 @@ function useBlob({
const [objectUrl, setObjectUrl] = useState<string>();
const [error, setError] = useState<Error>();
const [loading, setLoading] = useState<boolean>(false);
const [preview] = useSSRLocalStorage('preview', true);
// This side-effect fetches the blob of the file from the server and sets the
// relevant `objectUrl` state. Abort controller is reponsible for cancelling
// the fetch if the component is unmounted.
useEffect(() => {
if (!preview) {
return undefined;
}
const abortController = new AbortController();
async function generateOptimizedObjectUrl() {
@@ -104,7 +111,7 @@ function useBlob({
generateObjectUrl();
return () => abortController.abort();
}, [blob, fetchBlob, objectUrl, mimeType]);
}, [blob, fetchBlob, objectUrl, mimeType, preview]);
return { objectUrl, error, loading };
}
@@ -168,8 +175,13 @@ export default function DataGridPreviewCell<TData extends object>({
}: DataGridPreviewCellProps<TData>) {
const { project } = useProject();
const appClient = useAppClient();
const { objectUrl, loading, error } = useBlob({ fetchBlob, blob, mimeType });
const { objectUrl, loading, error } = useBlob({
fetchBlob,
blob,
mimeType,
});
const [showModal, setShowModal] = useState(false);
const { previewEnabled } = usePreviewToggle();
const [
{ loading: previewLoading, error: previewError, data: previewUrl },
@@ -365,7 +377,7 @@ export default function DataGridPreviewCell<TData extends object>({
</Modal>
<div className="flex h-full w-full justify-center">
{previewableImages.includes(mimeType) && objectUrl && (
{previewEnabled && previewableImages.includes(mimeType) && objectUrl ? (
<button
type="button"
aria-label={alt}
@@ -381,9 +393,11 @@ export default function DataGridPreviewCell<TData extends object>({
/>
</picture>
</button>
)}
) : null}
{(!previewableImages.includes(mimeType) || !objectUrl) && (
{(!previewableImages.includes(mimeType) ||
!objectUrl ||
!previewEnabled) && (
<button
type="button"
onClick={handleOpenPreview}

View File

@@ -1,9 +1,11 @@
import type { CommonDataGridCellProps } from '@/components/dataGrid/DataGridCell';
import { useDataGridCell } from '@/components/dataGrid/DataGridCell';
import { Button } from '@/components/ui/v2/Button';
import { CopyIcon } from '@/components/ui/v2/icons/CopyIcon';
import { Input, inputClasses } from '@/components/ui/v2/Input';
import { Text } from '@/components/ui/v2/Text';
import {
useDataGridCell,
type CommonDataGridCellProps,
} from '@/features/orgs/projects/storage/dataGrid/components/DataGridCell';
import { copy } from '@/utils/copy';
import type { ChangeEvent, KeyboardEvent, Ref } from 'react';
import { useEffect } from 'react';

View File

@@ -10,6 +10,7 @@ import { FilePreviewIcon } from '@/components/ui/v2/icons/FilePreviewIcon';
import { useAppClient } from '@/features/orgs/projects/hooks/useAppClient';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { FilesDataGridControls } from '@/features/orgs/projects/storage/dataGrid/components/FilesDataGridControls';
import { PreviewHeader } from '@/features/orgs/projects/storage/dataGrid/components/PreviewHeader';
import { useBuckets } from '@/features/orgs/projects/storage/dataGrid/hooks/useBuckets';
import { useFiles } from '@/features/orgs/projects/storage/dataGrid/hooks/useFiles';
import { useFilesAggregate } from '@/features/orgs/projects/storage/dataGrid/hooks/useFilesAggregate';
@@ -112,7 +113,8 @@ export default function FilesDataGrid(props: FilesDataGridProps) {
const memoizedColumns: Column<StoredFile>[] = useMemo(
() => [
{
Header: 'Preview',
id: 'preview',
Header: PreviewHeader,
accessor: 'preview',
Cell: (cellProps) =>
DataGridPreviewCell({
@@ -121,8 +123,8 @@ export default function FilesDataGrid(props: FilesDataGridProps) {
<FilePreviewIcon className="h-5 w-5 fill-current" />
),
}),
minWidth: 80,
width: 80,
minWidth: 120,
width: 120,
disableSortBy: true,
disableResizing: true,
},

View File

@@ -1,7 +1,4 @@
import { useDialog } from '@/components/common/DialogProvider';
import { useDataGridConfig } from '@/components/dataGrid/DataGridConfigProvider';
import type { DataGridPaginationProps } from '@/components/dataGrid/DataGridPagination';
import { DataGridPagination } from '@/components/dataGrid/DataGridPagination';
import type { BoxProps } from '@/components/ui/v2/Box';
import { Box } from '@/components/ui/v2/Box';
import { Button } from '@/components/ui/v2/Button';
@@ -10,6 +7,9 @@ import type { InputProps } from '@/components/ui/v2/Input';
import { Input } from '@/components/ui/v2/Input';
import { useAppClient } from '@/features/orgs/projects/hooks/useAppClient';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { useDataGridConfig } from '@/features/orgs/projects/storage/dataGrid/components/DataGridConfigProvider';
import type { DataGridPaginationProps } from '@/features/orgs/projects/storage/dataGrid/components/DataGridPagination';
import { DataGridPagination } from '@/features/orgs/projects/storage/dataGrid/components/DataGridPagination';
import type { FileUploadButtonProps } from '@/features/orgs/projects/storage/dataGrid/components/FileUploadButton';
import { FileUploadButton } from '@/features/orgs/projects/storage/dataGrid/components/FileUploadButton';
import type { Files } from '@/utils/__generated__/graphql';

View File

@@ -0,0 +1,22 @@
import { Switch } from '@/components/ui/v2/Switch';
import { usePreviewToggle } from '@/features/orgs/projects/storage/dataGrid/hooks/usePreviewToggle';
import { type ChangeEvent } from 'react';
export default function PreviewHeader() {
const { previewEnabled, setPreviewEnabled } = usePreviewToggle();
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
setPreviewEnabled(e.target.checked);
};
return (
<div className="flex flex-row items-center gap-2 p-2">
Preview
<Switch
className="self-center"
checked={previewEnabled}
onChange={handleChange}
/>
</div>
);
}

View File

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

View File

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

View File

@@ -0,0 +1,29 @@
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { useSSRLocalStorage } from '@/hooks/useSSRLocalStorage';
// Store {projectId: previewEnabled, projectId2: previewEnabled, ...}
type PreviewLocalStorage = {
[key: string]: boolean | undefined;
};
export default function usePreviewToggle() {
const [preview, setPreview] = useSSRLocalStorage<PreviewLocalStorage>(
'preview',
{},
);
const { project } = useProject();
// Default to previewEnabled true if not set
const previewEnabled = preview[project?.id] ?? true;
const setPreviewEnabled = (value: boolean) => {
const newPreview = { ...preview };
newPreview[project?.id] = value;
setPreview(newPreview);
};
return {
previewEnabled,
setPreviewEnabled,
};
}

View File

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

View File

@@ -1,31 +0,0 @@
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 { useQuery } from '@tanstack/react-query';
/**
* Returns whether or not the app is healthy.
*/
export default function useIsHealthy() {
const isPlatform = useIsPlatform();
const { currentProject } = useCurrentWorkspaceAndProject();
const appUrl = generateAppServiceUrl(
currentProject?.subdomain,
currentProject?.region,
'auth',
);
const { failureCount, status } = useQuery(
['/healthz'],
() => fetch(`${appUrl}/healthz`),
{
enabled: !isPlatform && !!currentProject,
retry: true,
retryDelay: 5000,
cacheTime: 0,
},
);
return isPlatform || (status === 'success' && failureCount === 0);
}

View File

@@ -1,17 +1,35 @@
import { useIsPlatform } from '@/features/orgs/projects/common/hooks/useIsPlatform';
import { useCurrentOrg } from '@/features/orgs/projects/hooks/useCurrentOrg';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
/**
* Redirects to 404 page if either currentWorkspace/currentProject resolves to undefined.
* Redirects to 404 page if either currentWorkspace/currentProject resolves to undefined
* or if the current pathname is not a valid organization/project.
* Not applicable if running dashboard with local Nhost backend.
*/
export default function useNotFoundRedirect() {
const router = useRouter();
const {
query: { orgSlug, workspaceSlug, appSubdomain, updating, appSlug },
query: {
orgSlug: urlOrgSlug,
workspaceSlug: urlWorkspaceSlug,
appSubdomain: urlAppSubdomain,
updating,
appSlug: urlAppSlug,
},
isReady,
} = router;
const { project, loading: projectLoading } = useProject();
const isPlatform = useIsPlatform();
const { org, loading: orgLoading } = useCurrentOrg();
const { subdomain: projectSubdomain } = project || {};
const { slug: currentOrgSlug } = org || {};
const { currentProject, currentWorkspace, loading } =
useCurrentWorkspaceAndProject();
@@ -23,6 +41,10 @@ export default function useNotFoundRedirect() {
!isReady ||
// If the current workspace and project are not loaded, we don't want to redirect to 404
loading ||
// If the project is loading, we don't want to redirect to 404
projectLoading ||
// If the org is loading, we don't want to redirect to 404
orgLoading ||
// If we're already on the 404 page, we don't want to redirect to 404
router.pathname === '/404' ||
router.pathname === '/' ||
@@ -31,12 +53,14 @@ export default function useNotFoundRedirect() {
router.pathname === '/run-one-click-install' ||
router.pathname.includes('/orgs/_') ||
router.pathname.includes('/orgs/_/projects/_') ||
orgSlug ||
(orgSlug && appSubdomain) ||
(!isPlatform &&
router.pathname.includes('/orgs/[orgSlug]/projects/[appSubdomain]')) ||
(urlOrgSlug === currentOrgSlug && !urlAppSubdomain) ||
(urlOrgSlug === currentOrgSlug && urlAppSubdomain === projectSubdomain) ||
// If we are on a valid workspace and project, we don't want to redirect to 404
(workspaceSlug && currentWorkspace && appSlug && currentProject) ||
(urlWorkspaceSlug && currentWorkspace && urlAppSlug && currentProject) ||
// If we are on a valid workspace and no project is selected, we don't want to redirect to 404
(workspaceSlug && currentWorkspace && !appSlug && !currentProject)
(urlWorkspaceSlug && currentWorkspace && !urlAppSlug && !currentProject)
) {
return;
}
@@ -47,11 +71,16 @@ export default function useNotFoundRedirect() {
currentWorkspace,
isReady,
loading,
appSubdomain,
appSlug,
urlAppSubdomain,
urlAppSlug,
router,
updating,
workspaceSlug,
orgSlug,
projectLoading,
orgLoading,
currentOrgSlug,
projectSubdomain,
urlWorkspaceSlug,
urlOrgSlug,
isPlatform,
]);
}

View File

@@ -11,7 +11,7 @@ import type { ReactElement } from 'react';
function BackupsContent() {
return (
<div className="grid w-full grid-flow-row gap-6 mt-6">
<div className="mt-6 grid w-full grid-flow-row gap-6">
<div>
<Text className="font-medium">Database</Text>
<Text color="secondary">
@@ -27,12 +27,13 @@ function BackupsContent() {
export default function BackupsPage() {
const { currentOrg: org, loading } = useOrgs();
const isPlanFree = org.plan.isFree;
if (loading) {
return <ActivityIndicator label="Loading project..." delay={1000} />;
}
const isPlanFree = org.plan.isFree;
if (isPlanFree) {
return (
<Container
@@ -44,20 +45,19 @@ export default function BackupsPage() {
description=""
/>
</Container>
)
);
}
return (
<Container className="grid max-w-5xl grid-flow-row bg-transparent gap-y-6">
<div className="grid justify-between grid-flow-col gap-2">
<Container className="grid max-w-5xl grid-flow-row gap-y-6 bg-transparent">
<div className="grid grid-flow-col justify-between gap-2">
<Text className="text-2xl font-medium" variant="h1">
Backups
</Text>
<Chip
color={org?.plan.isFree ? 'default' : 'success'}
label={org?.plan.isFree ? 'Off' : 'Live'}
color={isPlanFree ? 'default' : 'success'}
label={isPlanFree ? 'Off' : 'Live'}
size="small"
/>
</div>

View File

@@ -8,11 +8,11 @@ import {
} from '@/features/orgs/projects/logs/components/LogsHeader';
import { AvailableLogsService } from '@/features/orgs/projects/logs/utils/constants/services';
import { useRemoteApplicationGQLClientWithSubscriptions } from '@/hooks/useRemoteApplicationGQLClientWithSubscriptions';
import { MINUTES_TO_DECREASE_FROM_CURRENT_DATE } from '@/utils/constants/common';
import {
GetLogsSubscriptionDocument,
useGetProjectLogsQuery,
} from '@/utils/__generated__/graphql';
import { MINUTES_TO_DECREASE_FROM_CURRENT_DATE } from '@/utils/constants/common';
import { subMinutes } from 'date-fns';
import {
useCallback,
@@ -45,7 +45,7 @@ export default function LogsPage() {
const { data, error, subscribeToMore, client, loading, refetch } =
useGetProjectLogsQuery({
variables: { appID: project.id, ...filters },
variables: { appID: project?.id, ...filters },
client: clientWithSplit,
fetchPolicy: 'cache-and-network',
notifyOnNetworkStatusChange: true,
@@ -56,7 +56,7 @@ export default function LogsPage() {
subscribeToMore({
document: GetLogsSubscriptionDocument,
variables: {
appID: project.id,
appID: project?.id,
service: filters.service,
from: filters.from,
regexFilter: filters.regexFilter,
@@ -98,7 +98,7 @@ export default function LogsPage() {
};
},
}),
[subscribeToMore, project.id, filters],
[subscribeToMore, project?.id, filters],
);
useEffect(() => {
@@ -133,7 +133,7 @@ export default function LogsPage() {
);
return (
<div className="flex flex-col w-full h-full">
<div className="flex h-full w-full flex-col">
<RetryableErrorBoundary>
<LogsHeader
loading={loading}

View File

@@ -22,18 +22,18 @@ import { useLocalMimirClient } from '@/features/orgs/projects/hooks/useLocalMimi
import { useProject } from '@/features/orgs/projects/hooks/useProject';
export default function SettingsAuthenticationPage() {
const { project } = useProject();
const { project, loading: loadingProject } = useProject();
const isPlatform = useIsPlatform();
const localMimirClient = useLocalMimirClient();
const { data, loading, error } = useGetAuthenticationSettingsQuery({
variables: { appId: project?.id },
fetchPolicy: 'cache-and-network',
skip: !project,
skip: !project?.id,
...(!isPlatform ? { client: localMimirClient } : {}),
});
if (!data && loading) {
if (!data || loadingProject || loading) {
return (
<ActivityIndicator
delay={1000}

View File

@@ -1,5 +1,6 @@
import { UpgradeToProBanner } from '@/components/common/UpgradeToProBanner';
import { Container } from '@/components/layout/Container';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Box } from '@/components/ui/v2/Box';
import { ArrowSquareOutIcon } from '@/components/ui/v2/icons/ArrowSquareOutIcon';
import { Link } from '@/components/ui/v2/Link';
@@ -15,7 +16,11 @@ import { useCurrentOrg } from '@/features/orgs/projects/hooks/useCurrentOrg';
import { type ReactElement } from 'react';
export default function CustomDomains() {
const { org } = useCurrentOrg();
const { org, loading: loadingOrg } = useCurrentOrg();
if (loadingOrg) {
return <ActivityIndicator delay={1000} label="Loading project..." />;
}
if (org?.plan?.isFree) {
return (

View File

@@ -15,15 +15,15 @@ import type { ReactElement } from 'react';
export default function DatabaseSettingsPage() {
const isPlatform = useIsPlatform();
const localMimirClient = useLocalMimirClient();
const { project } = useProject();
const { project, loading: loadingProject } = useProject();
const { loading, error } = useGetPostgresSettingsQuery({
variables: { appId: project?.id },
skip: !project,
skip: !project?.id,
...(!isPlatform ? { client: localMimirClient } : {}),
});
if (loading) {
if (loadingProject || loading) {
return (
<ActivityIndicator
delay={1000}

View File

@@ -3,7 +3,7 @@ import { useUI } from '@/components/common/UIProvider';
import { Form } from '@/components/form/Form';
import { Container } from '@/components/layout/Container';
import { SettingsContainer } from '@/components/layout/SettingsContainer';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { LoadingScreen } from '@/components/presentational/LoadingScreen';
import { Alert } from '@/components/ui/v2/Alert';
import { Input } from '@/components/ui/v2/Input';
import { Link } from '@/components/ui/v2/Link';
@@ -29,7 +29,7 @@ import { ApplicationStatus } from '@/types/application';
import { slugifyString } from '@/utils/helpers';
import { yupResolver } from '@hookform/resolvers/yup';
import { useRouter } from 'next/router';
import { useMemo, type ReactElement } from 'react';
import { useEffect, useMemo, type ReactElement } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import * as Yup from 'yup';
@@ -96,6 +96,14 @@ export default function SettingsGeneralPage() {
const { register, formState } = form;
useEffect(() => {
if (!loading) {
form.reset({
name: project?.name,
});
}
}, [loading, project?.name, form]);
async function handleProjectNameChange(data: ProjectNameValidationSchema) {
const newProjectSlug = slugifyString(data.name);
@@ -186,7 +194,7 @@ export default function SettingsGeneralPage() {
}
if (loading) {
return <ActivityIndicator label="Loading project..." />;
return <LoadingScreen />;
}
return (

View File

@@ -1,5 +1,5 @@
import { Container } from '@/components/layout/Container';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { LoadingScreen } from '@/components/presentational/LoadingScreen';
import { ProjectLayout } from '@/features/orgs/layout/ProjectLayout';
import { SettingsLayout } from '@/features/orgs/layout/SettingsLayout';
import { useIsPlatform } from '@/features/orgs/projects/common/hooks/useIsPlatform';
@@ -12,21 +12,17 @@ import type { ReactElement } from 'react';
export default function MetricsSettingsPage() {
const isPlatform = useIsPlatform();
const localMimirClient = useLocalMimirClient();
const { project } = useProject();
const { project, loading: loadingProject } = useProject();
const { loading, error } = useGetObservabilitySettingsQuery({
variables: { appId: project?.id },
...(!isPlatform ? { client: localMimirClient } : {}),
});
const { loading: loadingObservabilitySettings, error } =
useGetObservabilitySettingsQuery({
variables: { appId: project?.id },
...(!isPlatform ? { client: localMimirClient } : {}),
skip: !project?.id,
});
if (loading) {
return (
<ActivityIndicator
delay={1000}
label="Loading Observability settings..."
className="justify-center"
/>
);
if (loadingProject || loadingObservabilitySettings) {
return <LoadingScreen />;
}
if (error) {
@@ -35,7 +31,7 @@ export default function MetricsSettingsPage() {
return (
<Container
className="grid max-w-5xl grid-flow-row bg-transparent gap-y-6"
className="grid max-w-5xl grid-flow-row gap-y-6 bg-transparent"
rootClassName="bg-transparent"
>
<MetricsSettings />

View File

@@ -27682,6 +27682,13 @@ export type GetBackupPresignedUrlQueryVariables = Exact<{
export type GetBackupPresignedUrlQuery = { __typename?: 'query_root', getBackupPresignedUrl: { __typename?: 'BackupPresignedURL', url: string, expiresAt: any } };
export type GetPersistentVolumesEncryptedQueryVariables = Exact<{
appId: Scalars['uuid'];
}>;
export type GetPersistentVolumesEncryptedQuery = { __typename?: 'query_root', systemConfig?: { __typename?: 'ConfigSystemConfig', persistentVolumesEncrypted?: boolean | null } | null };
export type GetJwtSecretsQueryVariables = Exact<{
appId: Scalars['uuid'];
}>;
@@ -29656,6 +29663,44 @@ export type GetBackupPresignedUrlQueryResult = Apollo.QueryResult<GetBackupPresi
export function refetchGetBackupPresignedUrlQuery(variables: GetBackupPresignedUrlQueryVariables) {
return { query: GetBackupPresignedUrlDocument, variables: variables }
}
export const GetPersistentVolumesEncryptedDocument = gql`
query GetPersistentVolumesEncrypted($appId: uuid!) {
systemConfig(appID: $appId) {
persistentVolumesEncrypted
}
}
`;
/**
* __useGetPersistentVolumesEncryptedQuery__
*
* To run a query within a React component, call `useGetPersistentVolumesEncryptedQuery` and pass it any options that fit your needs.
* When your component renders, `useGetPersistentVolumesEncryptedQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useGetPersistentVolumesEncryptedQuery({
* variables: {
* appId: // value for 'appId'
* },
* });
*/
export function useGetPersistentVolumesEncryptedQuery(baseOptions: Apollo.QueryHookOptions<GetPersistentVolumesEncryptedQuery, GetPersistentVolumesEncryptedQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<GetPersistentVolumesEncryptedQuery, GetPersistentVolumesEncryptedQueryVariables>(GetPersistentVolumesEncryptedDocument, options);
}
export function useGetPersistentVolumesEncryptedLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetPersistentVolumesEncryptedQuery, GetPersistentVolumesEncryptedQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<GetPersistentVolumesEncryptedQuery, GetPersistentVolumesEncryptedQueryVariables>(GetPersistentVolumesEncryptedDocument, options);
}
export type GetPersistentVolumesEncryptedQueryHookResult = ReturnType<typeof useGetPersistentVolumesEncryptedQuery>;
export type GetPersistentVolumesEncryptedLazyQueryHookResult = ReturnType<typeof useGetPersistentVolumesEncryptedLazyQuery>;
export type GetPersistentVolumesEncryptedQueryResult = Apollo.QueryResult<GetPersistentVolumesEncryptedQuery, GetPersistentVolumesEncryptedQueryVariables>;
export function refetchGetPersistentVolumesEncryptedQuery(variables: GetPersistentVolumesEncryptedQueryVariables) {
return { query: GetPersistentVolumesEncryptedDocument, variables: variables }
}
export const GetJwtSecretsDocument = gql`
query GetJWTSecrets($appId: uuid!) {
config(appID: $appId, resolve: false) {

View File

@@ -1,5 +1,27 @@
# @nhost/docs
## 2.27.0
### Minor Changes
- 81cc9b3: chore: add missing images to permissions API
### Patch Changes
- af34015: chore: add note about encryption at rest
- 1956ed2: chore: added pgmq extension to postgres docs
- 88919a3: chore: added support for nodejs22 to functions
## 2.26.0
### Minor Changes
- 04d2ce1: feat: add reference documentation for signin security key
### Patch Changes
- 1fa6cc4: chore: added docs for pg_jsonschema
## 2.25.0
### Minor Changes

View File

@@ -113,22 +113,22 @@ GraphQL requests from unauthenticated users resolve permissions using the `publi
## Insert Permissions
![Insert permissions](/img/graphql/permissions/insert-permissions.png)
![Insert permissions](/images/guides/todos-react-permissions-insert.png)
Here is a popular approach for insert permission for authenticated users.
1. At the top of the page, click **"insert"** on the **"user"** role.
1. Select **"Without any checks"**.
1. Select the columns you want to allow users to insert. In our example, we only mark `title`, because that's the only column that should be inserted by the user. The `id` is automatically generated by the database and `user_id` is set using a column preset.
1. Select the columns you want to allow users to insert. In our example, we do not mark `id` nor `user_id`, because they should not be inserted by the user. The `id` is automatically generated by the database and `user_id` is set using a column preset.
1. Under **Column presets**, set `user_id` to `x-hasura-user-id`. This way, every new record's `user_id` value is set to the ID of the user making the request.
Now, authenticated users are allowed to insert posts. Users are allowed to add a title when inserting a post. The post's `id` is automatically generated by the database and the `user_id` is automatically set to the user's id using the `user_id = x-hasura-user-id` column preset.
Now, authenticated users are allowed to insert todos. Users are allowed to add a title when inserting a todo. The todo's `id` is automatically generated by the database and the `user_id` is automatically set to the user's id using the `user_id = x-hasura-user-id` column preset.
## Select, Update and Delete Permissions
Select, update, and delete permissions usually follow the same pattern. Here's an example of how to add select permissions:
![Select permissions](/img/graphql/permissions/select-permissions.png)
![Select permissions](/images/guides/todos-react-permissions-select.png)
One of the most common permission requirements is that authenticated users should only be able to read their own data. This is how to do that:

View File

@@ -44,6 +44,7 @@ In the table below you can find a list of available extensions with Nhost Postgr
| pg_freespacemap | 1.2 | examine the free space map (FSM) |
| pg_hashids | 1.3 | pg_hashids |
| pg_ivm | 1.9 | incremental view maintenance on PostgreSQL |
| pg_jsonschema | 0.3.3 | pg_jsonschema |
| pg_prewarm | 1.2 | prewarm relation data |
| pg_repack | 1.5.1 | Reorganize tables in PostgreSQL databases with minimal locks |
| pg_squeeze | 1.7 | A tool to remove unused space from a relation. |
@@ -52,6 +53,7 @@ In the table below you can find a list of available extensions with Nhost Postgr
| pg_trgm | 1.6 | text similarity measurement and index searching based on trigrams |
| pg_visibility | 1.2 | examine the visibility map (VM) and page-level visibility info |
| pgcrypto | 1.3 | cryptographic functions |
| pgmq | 1.4.5 | A lightweight message queue. Like AWS SQS and RSMQ but on Postgres. |
| pgrowlocks | 1.2 | show row-level locking information |
| pgstattuple | 1.5 | show tuple-level statistics |
| plpgsql | 1.0 | PL/pgSQL procedural language |
@@ -75,7 +77,6 @@ In the table below you can find a list of available extensions with Nhost Postgr
In addition, you can find more information about some of the extensions below
## hypopg
HypoPG is a PostgreSQL extension adding support for hypothetical indexes.
@@ -147,6 +148,30 @@ DROP EXTENSION ip4r;
- [GitHub](https://github.com/RhodiumToad/ip4r)
## pgmq
A lightweight message queue. Like AWS SQS and RSMQ but on Postgres.
### Managing
To install the extension you can create a migration with the following contents:
```sql SQL
SET ROLE postgres;
CREATE EXTENSION pgmq;
```
To uninstall it, you can use the following migration:
```sql SQL
SET ROLE postgres;
DROP EXTENSION pgmq;
```
### Resources
- [GitHub](https://github.com/tembo-io/pgmq)
## postgis
PostGIS extends the capabilities of the PostgreSQL relational database by adding support storing, indexing and querying geographic data.
@@ -277,6 +302,30 @@ DROP EXTENSION pg_ivm;
- [GitHub](https://github.com/sraoss/pg_ivm)
## pg_jsonschema
pg_jsonschema is a PostgreSQL extension adding support for JSON schema validation on json and jsonb data types.
### Managing
To install the extension you can create a migration with the following contents:
```sql SQL
SET ROLE postgres;
CREATE EXTENSION pg_jsonschema;
```
To uninstall it, you can use the following migration:
```sql SQL
SET ROLE postgres;
DROP EXTENSION pg_jsonschema;
```
### Resources
- [GitHub](https://github.com/supabase/pg_jsonschema)
## pg_repack
pg_repack is a PostgreSQL extension which lets you remove bloat from tables and indexes, and optionally restore the physical order of clustered indexes. Unlike CLUSTER and VACUUM FULL it works online, without holding an exclusive lock on the processed tables during processing. pg_repack is efficient to boot, with performance comparable to using CLUSTER directly.

View File

@@ -10,6 +10,7 @@ The following runtimes are supported:
- [Node.js 18](https://nodejs.org)
- [Node.js 20](https://nodejs.org)
- [Node.js 22](https://nodejs.org)
To select your preferred runtime ensure the following configuration is present in your `nhost.toml` file:
@@ -27,6 +28,14 @@ version = 18
```toml
[functions.node]
version = 20
```
</Tab>
<Tab title="Node.js 22">
```toml
[functions.node]
version = 22
```
</Tab>

View File

@@ -354,7 +354,8 @@
"reference/javascript/auth/sign-in-email-otp",
"reference/javascript/auth/verify-email-otp",
"reference/javascript/auth/sign-in-id-token",
"reference/javascript/auth/link-id-token"
"reference/javascript/auth/link-id-token",
"reference/javascript/auth/sign-in-security-key"
]
},
{
@@ -440,7 +441,8 @@
"reference/react/use-user-roles",
"reference/react/use-sign-in-email-otp",
"reference/react/use-sign-in-id-token",
"reference/react/use-link-id-token"
"reference/react/use-link-id-token",
"reference/react/use-sign-in-security-key"
]
},
{
@@ -490,7 +492,8 @@
"reference/nextjs/use-user-roles",
"reference/nextjs/use-sign-in-email-otp",
"reference/nextjs/use-sign-in-id-token",
"reference/nextjs/use-link-id-token"
"reference/nextjs/use-link-id-token",
"reference/nextjs/use-sign-in-security-key"
]
},
{
@@ -535,7 +538,8 @@
"reference/vue/use-sign-up-email-security-key",
"reference/vue/use-sign-in-email-otp",
"reference/vue/use-sign-in-id-token",
"reference/vue/use-link-id-token"
"reference/vue/use-link-id-token",
"reference/vue/use-sign-in-security-key"
]
},
{

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/docs",
"version": "2.25.0",
"version": "2.27.0",
"private": true,
"scripts": {
"start": "mintlify dev"

View File

@@ -97,3 +97,11 @@ This borrowing of resources is convenient in case of short and unexpected bursts
## Disk Performance
By default disks are provisioned with a capacity for 3000 IOPS and 125 Mbps of throughput. If you need higher performance don't hesitate to contact us.
## Encryption at Rest
All files uploaded to the [storage](/product/storage) service are encrypted at rest using AES-256 encryption. Similarly, any volumes provisioned for your [database](/product/database) and [Run services](/product/run) are also encrypted using AES-256.
<Warning>
Only volumes provisioned after December 2024 are encrypted with AES-256. You can verify your volume's encryption status by navigating to your project's settings -> Database -> Storage capacity. If your volume is not encrypted, you'll see a warning message indicating this. To enable encryption on your volume, you can pause and then unpause your project. This action will provision new volumes with encryption enabled.
</Warning>

View File

@@ -0,0 +1,10 @@
---
title: signInSecurityKey()
sidebarTitle: signInSecurityKey()
---
Use `nhost.auth.signInSecurityKey` to sign in a user with a security key using the WebAuthn API
```ts
nhost.auth.signInSecurityKey()
```

View File

@@ -0,0 +1,10 @@
---
title: signInSecurityKey()
sidebarTitle: signInSecurityKey()
---
Use `nhost.auth.signInSecurityKey` to sign in a user with a security key using the WebAuthn API
```ts
nhost.auth.signInSecurityKey()
```

View File

@@ -0,0 +1,25 @@
---
title: useSignInSecurityKey()
sidebarTitle: useSignInSecurityKey()
---
Use the hook `useSignInSecurityKey` to sign in a user with a security key using the WebAuthn API.
```tsx
const {
signInSecurityKey,
needsEmailVerification,
isLoading,
isSuccess,
isError,
error
} = useSignInSecurityKey()
console.log({ needsEmailVerification, isLoading, isSuccess, isError, error })
const handleFormSubmit = async (e) => {
e.preventDefault()
await signInSecurityKey()
}
```

View File

@@ -0,0 +1,25 @@
---
title: useSignInSecurityKey()
sidebarTitle: useSignInSecurityKey()
---
Use the hook `useSignInSecurityKey` to sign in a user with a security key using the WebAuthn API.
```tsx
const {
signInSecurityKey,
needsEmailVerification,
isLoading,
isSuccess,
isError,
error
} = useSignInSecurityKey()
console.log({ needsEmailVerification, isLoading, isSuccess, isError, error })
const handleFormSubmit = async (e) => {
e.preventDefault()
await signInSecurityKey()
}
```

View File

@@ -0,0 +1,25 @@
---
title: useSignInSecurityKey()
sidebarTitle: useSignInSecurityKey()
---
Use the composable `useSignInSecurityKey` to sign in a user with a security key using the WebAuthn API
```tsx
const {
signInSecurityKey,
needsEmailVerification,
isLoading,
isSuccess,
isError,
error
} = useSignInSecurityKey()
console.log({ needsEmailVerification, isLoading, isSuccess, isError, error })
const handleFormSubmit = async (e) => {
e.preventDefault()
await signInSecurityKey()
}
```

View File

@@ -1,5 +1,17 @@
# @nhost-examples/cli
## 0.3.17
### Patch Changes
- @nhost/nhost-js@3.2.4
## 0.3.16
### Patch Changes
- @nhost/nhost-js@3.2.3
## 0.3.15
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/cli",
"version": "0.3.15",
"version": "0.3.17",
"main": "src/index.mjs",
"private": true,
"scripts": {

View File

@@ -1,5 +1,20 @@
# @nhost-examples/codegen-react-apollo
## 0.4.18
### Patch Changes
- @nhost/react@3.9.1
- @nhost/react-apollo@16.0.1
## 0.4.17
### Patch Changes
- Updated dependencies [04d2ce1]
- @nhost/react@3.9.0
- @nhost/react-apollo@16.0.0
## 0.4.16
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/codegen-react-apollo",
"version": "0.4.16",
"version": "0.4.18",
"private": true,
"scripts": {
"codegen": "graphql-codegen",

View File

@@ -1,5 +1,18 @@
# @nhost-examples/codegen-react-query
## 0.4.18
### Patch Changes
- @nhost/react@3.9.1
## 0.4.17
### Patch Changes
- Updated dependencies [04d2ce1]
- @nhost/react@3.9.0
## 0.4.16
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/codegen-react-query",
"version": "0.4.16",
"version": "0.4.18",
"private": true,
"scripts": {
"codegen": "graphql-codegen",

View File

@@ -1,5 +1,20 @@
# @nhost-examples/react-urql
## 0.3.18
### Patch Changes
- @nhost/react@3.9.1
- @nhost/react-urql@13.0.1
## 0.3.17
### Patch Changes
- Updated dependencies [04d2ce1]
- @nhost/react@3.9.0
- @nhost/react-urql@13.0.0
## 0.3.16
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "@nhost-examples/codegen-react-urql",
"private": true,
"version": "0.3.16",
"version": "0.3.18",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",

View File

@@ -1,5 +1,17 @@
# @nhost-examples/multi-tenant-one-to-many
## 2.2.18
### Patch Changes
- @nhost/nhost-js@3.2.4
## 2.2.17
### Patch Changes
- @nhost/nhost-js@3.2.3
## 2.2.16
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "@nhost-examples/multi-tenant-one-to-many",
"private": true,
"version": "2.2.16",
"version": "2.2.18",
"description": "",
"main": "index.js",
"scripts": {},

View File

@@ -1,5 +1,22 @@
# @nhost-examples/nextjs
## 0.4.2
### Patch Changes
- @nhost/react@3.9.1
- @nhost/react-apollo@16.0.1
- @nhost/nextjs@2.2.2
## 0.4.1
### Patch Changes
- Updated dependencies [04d2ce1]
- @nhost/react@3.9.0
- @nhost/react-apollo@16.0.0
- @nhost/nextjs@2.2.1
## 0.4.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/nextjs",
"version": "0.4.0",
"version": "0.4.2",
"private": true,
"scripts": {
"dev": "next dev",

View File

@@ -1,5 +1,17 @@
# @nhost-examples/node-storage
## 0.2.17
### Patch Changes
- @nhost/nhost-js@3.2.4
## 0.2.16
### Patch Changes
- @nhost/nhost-js@3.2.3
## 0.2.15
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/node-storage",
"version": "0.2.15",
"version": "0.2.17",
"private": true,
"description": "This is an example of how to use the Storage with Node.js",
"main": "src/index.mjs",

View File

@@ -1,5 +1,17 @@
# @nhost-examples/nextjs-server-components
## 0.5.2
### Patch Changes
- @nhost/nhost-js@3.2.4
## 0.5.1
### Patch Changes
- @nhost/nhost-js@3.2.3
## 0.5.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/nextjs-server-components",
"version": "0.5.0",
"version": "0.5.2",
"private": true,
"scripts": {
"dev": "next dev",

View File

@@ -1,5 +1,24 @@
# @nhost-examples/react-apollo
## 1.2.1
### Patch Changes
- @nhost/react@3.9.1
- @nhost/react-apollo@16.0.1
## 1.2.0
### Minor Changes
- 04d2ce1: feat: update signin components to use `useSignInSecuritykey` with user handle
### Patch Changes
- Updated dependencies [04d2ce1]
- @nhost/react@3.9.0
- @nhost/react-apollo@16.0.0
## 1.1.2
### Patch Changes

View File

@@ -29,7 +29,7 @@ httpPoolSize = 100
version = 18
[auth]
version = '0.32.1'
version = '0.37.0-beta1'
[auth.elevatedPrivileges]
mode = 'required'
@@ -47,6 +47,27 @@ disableNewUsers = false
default = 'user'
allowed = ['user', 'me']
[auth.rateLimit]
[auth.rateLimit.emails]
limit = 100
interval = '1h'
[auth.rateLimit.sms]
limit = 100
interval = '1h'
[auth.rateLimit.bruteForce]
limit = 100
interval = '5m'
[auth.rateLimit.signups]
limit = 100
interval = '5m'
[auth.rateLimit.global]
limit = 1000
interval = '1m'
[auth.user.locale]
default = 'en'
allowed = ['en']
@@ -158,6 +179,14 @@ issuer = 'nhost'
version = '16.2-20240718-1'
[provider]
[provider.smtp]
host = "smtp.test.com"
method = "LOGIN"
password = "test123123"
port = 587
secure = false
sender = "test@nhost.io"
user = "test"
[storage]
version = '0.6.1'

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/react-apollo",
"version": "1.1.2",
"version": "1.2.1",
"private": true,
"type": "module",
"scripts": {

View File

@@ -1,41 +1,21 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { useSignInEmailSecurityKey } from '@nhost/react'
import { ArrowLeft } from 'lucide-react'
import { useState } from 'react'
import { useForm } from 'react-hook-form'
import { Link, useNavigate } from 'react-router-dom'
import { toast } from 'sonner'
import { z } from 'zod'
import { cn } from '@/lib/utils'
import SignInFooter from '@/components/auth/sign-in-footer'
import { Button, buttonVariants } from '@/components/ui/button'
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { Form, FormControl, FormField, FormItem, FormMessage } from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { Separator } from '@/components/ui/separator'
const formSchema = z.object({
email: z.string().email()
})
import { cn } from '@/lib/utils'
import { useSignInSecurityKey } from '@nhost/react'
import { ArrowLeft } from 'lucide-react'
import { useState } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import { toast } from 'sonner'
export default function SignInSecurityKey() {
const navigate = useNavigate()
const { signInEmailSecurityKey } = useSignInEmailSecurityKey()
const { signInSecurityKey } = useSignInSecurityKey()
const [showEmailVerificationDialog, setShowEmailVerificationDialog] = useState(false)
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
email: ''
}
})
const onSubmit = async (values: z.infer<typeof formSchema>) => {
const { email } = values
const { isError, isSuccess, needsEmailVerification, error } = await signInEmailSecurityKey(
email
)
const handleSignInSecurityKey = async () => {
const { isError, isSuccess, needsEmailVerification, error } = await signInSecurityKey()
if (isError) {
toast.error(error?.message)
@@ -51,24 +31,9 @@ export default function SignInSecurityKey() {
<div className="flex flex-col items-center justify-center w-full max-w-md p-8 bg-white rounded-md shadow">
<h1 className="mb-8 text-3xl">Sign in with a security key</h1>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col w-full space-y-4">
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormControl>
<Input placeholder="email" type="email" {...field} />
</FormControl>
<FormMessage className="text-xs" />
</FormItem>
)}
/>
<Button type="submit">Sign In</Button>
</form>
</Form>
<Button onClick={handleSignInSecurityKey} className="w-full">
Sign In
</Button>
<Link to="/sign-in" className={cn(buttonVariants({ variant: 'link' }), 'my-2')}>
<ArrowLeft className="w-4 h-4" />

View File

@@ -1,5 +1,18 @@
# @nhost-examples/react-gqty
## 1.2.18
### Patch Changes
- @nhost/react@3.9.1
## 1.2.17
### Patch Changes
- Updated dependencies [04d2ce1]
- @nhost/react@3.9.0
## 1.2.16
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "@nhost-examples/react-gqty",
"private": true,
"version": "1.2.16",
"version": "1.2.18",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,20 @@
# @nhost-examples/react-native
## 0.1.3
### Patch Changes
- @nhost/react@3.9.1
- @nhost/react-apollo@16.0.1
## 0.1.2
### Patch Changes
- Updated dependencies [04d2ce1]
- @nhost/react@3.9.0
- @nhost/react-apollo@16.0.0
## 0.1.1
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/react-native",
"version": "0.1.1",
"version": "0.1.3",
"private": true,
"scripts": {
"android": "react-native run-android",

View File

@@ -1,5 +1,26 @@
# @nhost-examples/vue-apollo
## 0.8.1
### Patch Changes
- @nhost/nhost-js@3.2.4
- @nhost/apollo@8.0.4
- @nhost/vue@2.9.1
## 0.8.0
### Minor Changes
- 04d2ce1: feat: update signin components to use `useSignInSecuritykey` with user handle
### Patch Changes
- Updated dependencies [04d2ce1]
- @nhost/vue@2.9.0
- @nhost/nhost-js@3.2.3
- @nhost/apollo@8.0.3
## 0.7.2
### Patch Changes

View File

@@ -29,7 +29,7 @@ httpPoolSize = 100
version = 18
[auth]
version = '0.27.0-beta13'
version = '0.37.0-beta1'
[auth.elevatedPrivileges]
mode = 'required'

View File

@@ -0,0 +1,60 @@
[
{
"value": "disabled",
"op": "replace",
"path": "/auth/elevatedPrivileges/mode"
},
{
"value": "localhost",
"op": "replace",
"path": "/auth/method/webauthn/relyingParty/id"
},
{
"value": "http://localhost:5173",
"op": "replace",
"path": "/auth/method/webauthn/relyingParty/origins/0"
},
{
"value": "http://localhost:5173",
"op": "replace",
"path": "/auth/redirections/allowedUrls/0"
},
{
"value": "http://localhost:5173/profile",
"op": "replace",
"path": "/auth/redirections/allowedUrls/1"
},
{
"op": "remove",
"path": "/auth/redirections/allowedUrls/2"
},
{
"op": "remove",
"path": "/auth/redirections/allowedUrls/2"
},
{
"op": "remove",
"path": "/auth/redirections/allowedUrls/2"
},
{
"op": "remove",
"path": "/auth/redirections/allowedUrls/2"
},
{
"op": "remove",
"path": "/auth/redirections/allowedUrls/2"
},
{
"op": "remove",
"path": "/auth/redirections/allowedUrls/2"
},
{
"op": "remove",
"path": "/auth/redirections/allowedUrls/2"
},
{
"value": "http://localhost:5173",
"op": "replace",
"path": "/auth/redirections/clientUrl"
}
]

View File

@@ -1,7 +1,7 @@
{
"name": "@nhost-examples/vue-apollo",
"private": true,
"version": "0.7.2",
"version": "0.8.1",
"scripts": {
"dev": "vite",
"build": "vite build",

View File

@@ -1,6 +1,5 @@
<template>
<form @submit="handleSignIn">
<v-text-field v-model="email" label="Email" />
<v-btn
block
color="primary"
@@ -23,17 +22,15 @@
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { useSignInEmailSecurityKey } from '@nhost/vue'
const email = ref('')
import { useSignInSecurityKey } from '@nhost/vue'
const emailVerificationDialog = ref(false)
const router = useRouter()
const { signInEmailSecurityKey, error, isLoading } = useSignInEmailSecurityKey()
const { signInSecurityKey, error, isLoading } = useSignInSecurityKey()
const handleSignIn = async (e: Event) => {
e.preventDefault()
const { isSuccess, needsEmailVerification } = await signInEmailSecurityKey(email)
const { isSuccess, needsEmailVerification } = await signInSecurityKey()
if (isSuccess) {
router.replace('/')
}

View File

@@ -1,5 +1,5 @@
{
// "extends": "../../config/tsconfig.base.json",
"extends": "../../config/tsconfig.base.json",
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,

View File

@@ -1,5 +1,20 @@
# @nhost-examples/vue-quickstart
## 0.2.18
### Patch Changes
- @nhost/apollo@8.0.4
- @nhost/vue@2.9.1
## 0.2.17
### Patch Changes
- Updated dependencies [04d2ce1]
- @nhost/vue@2.9.0
- @nhost/apollo@8.0.3
## 0.2.16
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/vue-quickstart",
"version": "0.2.16",
"version": "0.2.18",
"private": true,
"scripts": {
"build": "vite build",

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