Compare commits

...

18 Commits

Author SHA1 Message Date
github-actions[bot]
196cd38018 chore: update versions (#3163)
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.17.0

### Minor Changes

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

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-01-27 18:39:50 +01:00
David BM
fd5991845b fix (dashboard): redirect 404 local, revert changes (#3162)
### **User description**
Revert to old `useNotFoundRedirect.ts` changes 

[d43931e](d43931e761)


___

### **PR Type**
Bug fix


___

### **Description**
- Simplified 404 redirect logic in useNotFoundRedirect hook

- Removed platform-specific checks and unused imports

- Updated conditions for redirecting to 404 page

- 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>useNotFoundRedirect.ts</strong><dd><code>Simplify
useNotFoundRedirect hook logic</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/projects/common/hooks/useNotFoundRedirect/useNotFoundRedirect.ts

<li>Removed unused imports and variables<br> <li> Simplified redirect
conditions<br> <li> Removed platform-specific checks<br> <li> Updated
dependencies in useEffect hook


</details>


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

</tr>
</table></td></tr><tr><td><strong>Documentation</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>quick-seahorses-draw.md</strong><dd><code>Add changeset
for 404 redirect 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; </dd></summary>
<hr>

.changeset/quick-seahorses-draw.md

<li>Added changeset file for minor version bump<br> <li> Described fix
for 404 redirect in Nhost CLI dashboard


</details>


  </td>
<td><a
href="https://github.com/nhost/nhost/pull/3162/files#diff-df782a89bb7c2193ff124ea1262479d2d492088f1bf865064ead79328913642c">+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-27 18:36:50 +01:00
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
104 changed files with 663 additions and 360 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

@@ -1,5 +1,33 @@
# @nhost/dashboard
## 2.17.0
### Minor Changes
- fd59918: fix: redirect to 404 with nhost cli dashboard
## 2.16.0
### Minor Changes
- f8e6b61: fix: can add rule groups in table permissions
- 9e404c8: fix: not redirect to 404 page if using local Nhost backend
- ac4aa01: fix: can delete column in database page
- 4385524: fix: update url to check service health in local dashboard
### Patch Changes
- @nhost/react-apollo@16.0.1
- @nhost/nextjs@2.2.2
## 2.15.0
### Minor Changes
- f1052a8: fix: improve stability of the dashboard when pausing projects
- 30daa41: fix: update links to docs in overview page
- 7537237: feat: add image preview toggle in storage
## 2.14.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/dashboard",
"version": "2.14.0",
"version": "2.17.0",
"private": true,
"scripts": {
"preinstall": "npx only-allow pnpm",

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

@@ -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,5 +1,3 @@
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';
@@ -10,22 +8,10 @@ import { useEffect } from 'react';
export default function useNotFoundRedirect() {
const router = useRouter();
const {
query: {
orgSlug: urlOrgSlug,
workspaceSlug: urlWorkspaceSlug,
appSubdomain: urlAppSubdomain,
updating,
appSlug: urlAppSlug,
},
query: { orgSlug, workspaceSlug, appSubdomain, updating, appSlug },
isReady,
} = router;
const { project, loading: projectLoading } = useProject();
const { org, loading: orgLoading } = useCurrentOrg();
const { subdomain: projectSubdomain } = project || {};
const { slug: currentOrgSlug } = org || {};
const { currentProject, currentWorkspace, loading } =
useCurrentWorkspaceAndProject();
@@ -37,10 +23,6 @@ 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 === '/' ||
@@ -49,12 +31,12 @@ export default function useNotFoundRedirect() {
router.pathname === '/run-one-click-install' ||
router.pathname.includes('/orgs/_') ||
router.pathname.includes('/orgs/_/projects/_') ||
(urlOrgSlug === currentOrgSlug && !urlAppSubdomain) ||
(urlOrgSlug === currentOrgSlug && urlAppSubdomain === projectSubdomain) ||
orgSlug ||
(orgSlug && appSubdomain) ||
// If we are on a valid workspace and project, we don't want to redirect to 404
(urlWorkspaceSlug && currentWorkspace && urlAppSlug && currentProject) ||
(workspaceSlug && currentWorkspace && appSlug && currentProject) ||
// If we are on a valid workspace and no project is selected, we don't want to redirect to 404
(urlWorkspaceSlug && currentWorkspace && !urlAppSlug && !currentProject)
(workspaceSlug && currentWorkspace && !appSlug && !currentProject)
) {
return;
}
@@ -65,15 +47,11 @@ export default function useNotFoundRedirect() {
currentWorkspace,
isReady,
loading,
urlAppSubdomain,
urlAppSlug,
appSubdomain,
appSlug,
router,
updating,
projectLoading,
orgLoading,
currentOrgSlug,
projectSubdomain,
urlWorkspaceSlug,
urlOrgSlug,
workspaceSlug,
orgSlug,
]);
}

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

@@ -1,5 +1,17 @@
# @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

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

@@ -53,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 |
@@ -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.

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

@@ -1,6 +1,6 @@
{
"name": "@nhost/docs",
"version": "2.26.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

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

View File

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

View File

@@ -1,5 +1,12 @@
# @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

View File

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

View File

@@ -1,5 +1,11 @@
# @nhost-examples/codegen-react-query
## 0.4.18
### Patch Changes
- @nhost/react@3.9.1
## 0.4.17
### Patch Changes

View File

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

View File

@@ -1,5 +1,12 @@
# @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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,13 @@
# @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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost-examples/node-storage",
"version": "0.2.16",
"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,11 @@
# @nhost-examples/nextjs-server-components
## 0.5.2
### Patch Changes
- @nhost/nhost-js@3.2.4
## 0.5.1
### Patch Changes

View File

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

View File

@@ -1,5 +1,12 @@
# @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

View File

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

View File

@@ -1,5 +1,11 @@
# @nhost-examples/react-gqty
## 1.2.18
### Patch Changes
- @nhost/react@3.9.1
## 1.2.17
### Patch Changes

View File

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

View File

@@ -1,5 +1,12 @@
# @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

View File

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

View File

@@ -1,5 +1,13 @@
# @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

View File

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

View File

@@ -1,5 +1,12 @@
# @nhost-examples/vue-quickstart
## 0.2.18
### Patch Changes
- @nhost/apollo@8.0.4
- @nhost/vue@2.9.1
## 0.2.17
### Patch Changes

View File

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

24
flake.lock generated
View File

@@ -5,11 +5,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
@@ -20,11 +20,11 @@
},
"nix-filter": {
"locked": {
"lastModified": 1710156097,
"narHash": "sha256-1Wvk8UP7PXdf8bCCaEoMnOT1qe5/Duqgj+rL8sRQsSM=",
"lastModified": 1731533336,
"narHash": "sha256-oRam5PS1vcrr5UPgALW0eo1m/5/pls27Z/pabHNy2Ms=",
"owner": "numtide",
"repo": "nix-filter",
"rev": "3342559a24e85fc164b295c3444e8a139924675b",
"rev": "f7653272fd234696ae94229839a99b73c9ab7de0",
"type": "github"
},
"original": {
@@ -40,11 +40,11 @@
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1718635840,
"narHash": "sha256-yAc2I1Y05hzAMI8atcxg3g7eXehsJIifTl/BOWIvD3o=",
"lastModified": 1736258395,
"narHash": "sha256-G55pFLtWxy8pzR5k/UOXBSgHoU8oO263YyYkxbaWzXM=",
"owner": "nhost",
"repo": "nixops",
"rev": "9ea5d933111bcfb1e2ff881e98dd2c48d1b80965",
"rev": "52d9d8ff772a58b2cedac9f2f8a89517a86b35a4",
"type": "github"
},
"original": {
@@ -55,11 +55,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1716715802,
"narHash": "sha256-usk0vE7VlxPX8jOavrtpOqphdfqEQpf9lgedlY/r66c=",
"lastModified": 1732238832,
"narHash": "sha256-sQxuJm8rHY20xq6Ah+GwIUkF95tWjGRd1X8xF+Pkk38=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e2dd4e18cc1c7314e24154331bae07df76eb582f",
"rev": "8edf06bea5bcbee082df1b7369ff973b91618b8d",
"type": "github"
},
"original": {

View File

@@ -36,7 +36,7 @@
pname = "node_modules";
nativeBuildInputs = with pkgs; [
nodePackages.pnpm
pnpm_9
cacert
nodejs
];
@@ -131,7 +131,7 @@
buildInputs = with pkgs; [
nhost-cli
nodejs
nodePackages.pnpm
pnpm_9
go
golangci-lint
] ++ buildInputs ++ nativeBuildInputs;

View File

@@ -1,5 +1,11 @@
# @nhost/apollo
## 8.0.4
### Patch Changes
- @nhost/nhost-js@3.2.4
## 8.0.3
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/apollo",
"version": "8.0.3",
"version": "8.0.4",
"description": "Nhost Apollo Client library",
"license": "MIT",
"keywords": [

View File

@@ -1,5 +1,12 @@
# @nhost/react-apollo
## 16.0.1
### Patch Changes
- @nhost/apollo@8.0.4
- @nhost/react@3.9.1
## 16.0.0
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/react-apollo",
"version": "16.0.0",
"version": "16.0.1",
"description": "Nhost React Apollo client",
"license": "MIT",
"keywords": [

View File

@@ -1,5 +1,11 @@
# @nhost/react-urql
## 13.0.1
### Patch Changes
- @nhost/react@3.9.1
## 13.0.0
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/react-urql",
"version": "13.0.0",
"version": "13.0.1",
"description": "Nhost React URQL client",
"license": "MIT",
"keywords": [

View File

@@ -1,5 +1,5 @@
(final: prev: rec {
nodejs = final.nodejs-18_x;
nodejs = final.nodejs_20;
nodePackages = nodejs.pkgs;
nhost-cli = final.callPackage ./nhost-cli.nix { inherit final; };
})

View File

@@ -1,5 +1,11 @@
# @nhost/hasura-storage-js
## 2.7.0
### Minor Changes
- 5c6ff6e: fix: correct StorageErrorPayload TypeScript typing
## 2.6.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/hasura-storage-js",
"version": "2.6.0",
"version": "2.7.0",
"description": "Hasura-storage client",
"license": "MIT",
"keywords": [

View File

@@ -92,13 +92,14 @@ export const fetchUpload = async (
xhr.onload = () => {
if (xhr.status < 200 || xhr.status >= 300) {
const error: StorageErrorPayload = {
error: xhr.response?.error?.message ?? xhr.response?.error ?? xhr.response,
message: xhr.response?.error?.message ?? xhr.response,
status: xhr.status
}
return resolve({
fileMetadata: null,
error: {
error: xhr.response?.error ?? xhr.response,
message: xhr.response?.error?.message ?? xhr.response,
status: xhr.status
}
error
})
}
return resolve({ fileMetadata: xhr.response, error: null })
@@ -106,9 +107,14 @@ export const fetchUpload = async (
xhr.onerror = () => {
// only triggers if the request couldn't be made at all e.g. network error
const error: StorageErrorPayload = {
error: xhr.statusText,
message: xhr.statusText,
status: xhr.status
}
return resolve({
fileMetadata: null,
error: { error: xhr.statusText, message: xhr.statusText, status: xhr.status }
error
})
}

View File

@@ -1,5 +1,11 @@
# @nhost/nextjs
## 2.2.2
### Patch Changes
- @nhost/react@3.9.1
## 2.2.1
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/nextjs",
"version": "2.2.1",
"version": "2.2.2",
"description": "Nhost NextJS library",
"license": "MIT",
"keywords": [

View File

@@ -1,5 +1,12 @@
# @nhost/nhost-js
## 3.2.4
### Patch Changes
- Updated dependencies [5c6ff6e]
- @nhost/hasura-storage-js@2.7.0
## 3.2.3
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/nhost-js",
"version": "3.2.3",
"version": "3.2.4",
"description": "Nhost JavaScript SDK",
"license": "MIT",
"keywords": [

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