dashboard: feat: raw TOML editor (#2752)

### **User description**
Closes #2727


___

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


___

### **Description**
- Introduced a new TOML editor component for editing project
configurations.
- Added new GraphQL queries and mutations to handle raw JSON
configurations.
- Updated SettingsSidebar and SettingsLayout components for better
layout and navigation.
- Added new SlidersIcon component and integrated it into the settings
navigation.
- Updated dependencies to support new features.
- Fixed various layout and style issues in the settings components.



___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement
</strong></td><td><details><summary>10 files</summary><table>
<tr>
  <td>
    <details>
<summary><strong>SettingsLayout.tsx</strong><dd><code>Adjust overflow
behavior in SettingsLayout component</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>
      
dashboard/src/components/layout/SettingsLayout/SettingsLayout.tsx

- Changed overflow behavior for better vertical scrolling.



</details>
    

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

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>SettingsSidebar.tsx</strong><dd><code>Update
SettingsSidebar layout and styles</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>
      
dashboard/src/components/layout/SettingsSidebar/SettingsSidebar.tsx

<li>Added new <code>SlidersIcon</code> import.<br> <li> Introduced
<code>textClassName</code> prop to <code>SettingsNavLink</code>.<br>
<li> Updated layout and styles for better alignment and spacing.<br>


</details>
    

  </td>
<td><a
href="https://github.com/nhost/nhost/pull/2752/files#diff-228be719ea3624edbfd2af99af3c076cebb3d0732026987306aa1032a795ba00">+23/-3</a>&nbsp;
&nbsp; </td>

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>SlidersIcon.tsx</strong><dd><code>Add SlidersIcon
component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>
      
dashboard/src/components/ui/v2/icons/SlidersIcon/SlidersIcon.tsx

- Added new `SlidersIcon` component.



</details>
    

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

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>index.ts</strong><dd><code>Export SlidersIcon
component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>
      
dashboard/src/components/ui/v2/icons/SlidersIcon/index.ts

- Exported `SlidersIcon` component.



</details>
    

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

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>TOMLEditor.tsx</strong><dd><code>Add TOMLEditor
component for TOML configurations</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>
      

dashboard/src/features/projects/common/components/settings/TOMLEditor/TOMLEditor.tsx

<li>Added new <code>TOMLEditor</code> component for editing TOML
configurations.<br> <li> Implemented TOML parsing and error
handling.<br> <li> Added save and revert functionality.<br>


</details>
    

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

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>index.ts</strong><dd><code>Export TOMLEditor
component</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>
      

dashboard/src/features/projects/common/components/settings/TOMLEditor/index.ts

- Exported `TOMLEditor` component.



</details>
    

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

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>index.tsx</strong><dd><code>Add TOML editor page under
settings</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>
      
dashboard/src/pages/[workspaceSlug]/[appSlug]/settings/editor/index.tsx

- Added new page for TOML editor under settings.



</details>
    

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

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>graphql.ts</strong><dd><code>Add GraphQL queries and
mutations for raw JSON configurations</code></dd></summary>
<hr>
      
dashboard/src/utils/__generated__/graphql.ts

<li>Added new GraphQL queries and mutations for handling raw JSON
<br>configurations.<br> <li> Updated types and schema for new
features.<br>


</details>
    

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

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>getConfigRawJSON.graphql</strong><dd><code>Add GraphQL
query for fetching raw JSON configuration</code>&nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>
      
dashboard/src/gql/app/settings/getConfigRawJSON.graphql

- Added GraphQL query for fetching raw JSON configuration.



</details>
    

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

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>replaceConfigRawJSON.graphql</strong><dd><code>Add
GraphQL mutation for replacing raw JSON
configuration</code></dd></summary>
<hr>
      
dashboard/src/gql/app/settings/replaceConfigRawJSON.graphql

- Added GraphQL mutation for replacing raw JSON configuration.



</details>
    

  </td>
<td><a
href="https://github.com/nhost/nhost/pull/2752/files#diff-5d49b4c5e9fa194a02a0a974c245f8c50faf437d6becadf7947ee73083ac8374">+3/-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>
    <details>
<summary><strong>tidy-shirts-kneel.md</strong><dd><code>Add changeset
for TOML editor feature</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>
      
.changeset/tidy-shirts-kneel.md

- Added changeset for TOML editor feature.



</details>
    

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

</tr>                    
</table></details></td></tr><tr><td><strong>Dependencies
</strong></td><td><details><summary>1 files</summary><table>
<tr>
  <td>
    <details>
<summary><strong>package.json</strong><dd><code>Update dependencies for
TOML editor</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>
      
dashboard/package.json

<li>Added new dependencies for TOML parsing and CodeMirror
integration.<br> <li> Updated existing dependencies.<br>


</details>
    

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

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

___

> 💡 **PR-Agent usage**:
>Comment `/help` on the PR to get a list of all available PR-Agent tools
and their descriptions
This commit is contained in:
Zephyr (David B.M.)
2024-06-26 19:35:43 +02:00
committed by GitHub
parent bedbb82cd7
commit dbadf59092
13 changed files with 5422 additions and 2417 deletions

View File

@@ -0,0 +1,5 @@
---
'@nhost/dashboard': minor
---
feat: add project configuration TOML editor to the settings page

View File

@@ -21,17 +21,20 @@
"dependencies": {
"@apollo/client": "^3.9.9",
"@codemirror/lang-sql": "^6.6.2",
"@codemirror/language": "^6.10.1",
"@codemirror/legacy-modes": "^6.4.0",
"@emotion/cache": "^11.11.0",
"@emotion/react": "^11.11.4",
"@emotion/server": "^11.11.0",
"@emotion/styled": "^11.11.5",
"@fontsource/inter": "^5.0.17",
"@fontsource/roboto-mono": "^5.0.17",
"@graphiql/react": "^0.20.3",
"@graphiql/react": "^0.22.3",
"@graphiql/toolkit": "^0.9.1",
"@headlessui/react": "^1.7.18",
"@heroicons/react": "^1.0.6",
"@hookform/resolvers": "^3.3.4",
"@iarna/toml": "^2.2.5",
"@mui/base": "5.0.0-beta.31",
"@mui/material": "^5.15.14",
"@mui/system": "^5.15.14",
@@ -45,6 +48,7 @@
"@tanstack/react-query": "^4.36.1",
"@tanstack/react-table": "^8.15.3",
"@tanstack/react-virtual": "^3.2.0",
"@uiw/codemirror-theme-bbedit": "^4.22.2",
"@uiw/codemirror-theme-github": "^4.21.25",
"@uiw/react-codemirror": "^4.21.25",
"analytics-node": "^6.2.0",
@@ -53,7 +57,7 @@
"date-fns": "^2.30.0",
"framer-motion": "^10.18.0",
"generate-password": "^1.7.1",
"graphiql": "^3.1.1",
"graphiql": "^3.3.1",
"graphql": "16.8.1",
"graphql-request": "^6.1.0",
"graphql-tag": "^2.12.6",

View File

@@ -45,7 +45,7 @@ export default function SettingsLayout({
<Box
sx={{ backgroundColor: 'background.default' }}
className="flex w-full flex-auto flex-col overflow-scroll overflow-x-hidden"
className="flex w-full flex-auto flex-col overflow-y-auto overflow-x-hidden"
>
<RetryableErrorBoundary>
<div className="flex flex-col space-y-2">

View File

@@ -3,6 +3,7 @@ import { Backdrop } from '@/components/ui/v2/Backdrop';
import type { BoxProps } from '@/components/ui/v2/Box';
import { Box } from '@/components/ui/v2/Box';
import { IconButton } from '@/components/ui/v2/IconButton';
import { SlidersIcon } from '@/components/ui/v2/icons/SlidersIcon';
import { List } from '@/components/ui/v2/List';
import type { ListItemButtonProps } from '@/components/ui/v2/ListItem';
import { ListItem } from '@/components/ui/v2/ListItem';
@@ -27,12 +28,17 @@ interface SettingsNavLinkProps extends ListItemButtonProps {
* @default true
*/
exact?: boolean;
/**
* Class name passed to the text element.
*/
textClassName?: string;
}
function SettingsNavLink({
exact = true,
href,
children,
textClassName,
...props
}: SettingsNavLinkProps) {
const router = useRouter();
@@ -52,7 +58,7 @@ function SettingsNavLink({
selected={active}
{...props}
>
<ListItem.Text>{children}</ListItem.Text>
<ListItem.Text className={textClassName}>{children}</ListItem.Text>
</ListItem.Button>
</ListItem.Root>
);
@@ -114,13 +120,13 @@ export default function SettingsSidebar({
<Box
component="aside"
className={twMerge(
'absolute top-0 z-[35] h-full w-full overflow-auto border-r-1 px-2 pb-17 pt-2 motion-safe:transition-transform md:relative md:z-0 md:h-full md:py-2.5 md:transition-none',
'absolute top-0 z-[35] flex h-full w-full flex-col justify-between overflow-auto border-r-1 pb-17 pt-2 motion-safe:transition-transform md:relative md:z-0 md:h-full md:pb-0 md:pt-2.5 md:transition-none',
expanded ? 'translate-x-0' : '-translate-x-full md:translate-x-0',
className,
)}
{...props}
>
<nav aria-label="Settings navigation">
<nav aria-label="Settings navigation" className="px-2">
<List className="grid gap-2">
<SettingsNavLink
href="/general"
@@ -220,6 +226,20 @@ export default function SettingsSidebar({
</SettingsNavLink>
</List>
</nav>
<Box className="border-t">
<SettingsNavLink
href="/editor"
exact={false}
onClick={handleSelect}
className="flex w-full border group-focus-within:pr-9 group-hover:pr-9 group-active:pr-9"
textClassName="flex w-full justify-center"
>
<div className="flex w-full flex-row items-center justify-center space-x-4 py-2.5">
<SlidersIcon />
<span className="flex">Configuration Editor</span>
</div>
</SettingsNavLink>
</Box>
</Box>
<IconButton

View File

@@ -0,0 +1,34 @@
import type { IconProps } from '@/components/ui/v2/icons';
import { SvgIcon } from '@/components/ui/v2/icons/SvgIcon';
function SlidersIcon(props: IconProps) {
return (
<SvgIcon
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
xmlns="http://www.w3.org/2000/svg"
aria-label="Sliders"
{...props}
>
<line x1="21" x2="14" y1="4" y2="4" />
<line x1="10" x2="3" y1="4" y2="4" />
<line x1="21" x2="12" y1="12" y2="12" />
<line x1="8" x2="3" y1="12" y2="12" />
<line x1="21" x2="16" y1="20" y2="20" />
<line x1="12" x2="3" y1="20" y2="20" />
<line x1="14" x2="14" y1="2" y2="6" />
<line x1="8" x2="8" y1="10" y2="14" />
<line x1="16" x2="16" y1="18" y2="22" />
</SvgIcon>
);
}
SlidersIcon.displayName = 'NhostSlidersIcon';
export default SlidersIcon;

View File

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

View File

@@ -0,0 +1,191 @@
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
import { useDialog } from '@/components/common/DialogProvider';
import { Box } from '@/components/ui/v2/Box';
import { Button } from '@/components/ui/v2/Button';
import { Text } from '@/components/ui/v2/Text';
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
import { getToastStyleProps } from '@/utils/constants/settings';
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
import {
useGetConfigRawJsonQuery,
useReplaceConfigRawJsonMutation,
} from '@/utils/__generated__/graphql';
import { StreamLanguage } from '@codemirror/language';
import { toml } from '@codemirror/legacy-modes/mode/toml';
import * as TOML from '@iarna/toml';
import { useTheme } from '@mui/material';
import { bbedit } from '@uiw/codemirror-theme-bbedit';
import { githubDark } from '@uiw/codemirror-theme-github';
import CodeMirror from '@uiw/react-codemirror';
import { useCallback, useEffect, useState } from 'react';
import toast from 'react-hot-toast';
export default function TOMLEditor() {
const theme = useTheme();
const isPlatform = useIsPlatform();
const [tomlCode, setTOMLCode] = useState('');
const [previousTOMLCode, setPreviousTOMLCode] = useState(''); // used to revert changes
const [isDirty, setIsDirty] = useState(false);
const [isSaving, setIsSaving] = useState(false); // used to show loading spinner on save
const { openDialog } = useDialog();
const { currentProject } = useCurrentWorkspaceAndProject();
const localMimirClient = useLocalMimirClient();
// fetch the initial TOML code from the server
const { data, loading } = useGetConfigRawJsonQuery({
variables: {
appID: currentProject?.id,
},
skip: !currentProject,
});
const [saveConfigMutation] = useReplaceConfigRawJsonMutation({
...(!isPlatform ? { client: localMimirClient } : {}),
});
const removeTOMLIndentation = (tomlStr: string) => {
const trimmedLines = tomlStr.split('\n').map((line) => line.trimStart());
return trimmedLines.join('\n');
};
useEffect(() => {
// Load TOML code from the server on initial load
if (!loading && data) {
const jsonData = JSON.parse(data?.configRawJSON);
const tomlStr = TOML.stringify(jsonData);
const unindentedTOMLConfig = removeTOMLIndentation(tomlStr);
setTOMLCode(unindentedTOMLConfig);
setPreviousTOMLCode(unindentedTOMLConfig);
}
}, [loading, data]);
const onChange = useCallback((value: string) => {
setTOMLCode(value);
setIsDirty(true);
}, []);
const handleRevert = () => {
setTOMLCode(previousTOMLCode);
setIsDirty(false);
};
const handleSave = async () => {
setIsSaving(true);
let jsonEditedConfig;
try {
jsonEditedConfig = TOML.parse(tomlCode);
} catch (error) {
const toastStyle = getToastStyleProps();
const { line, col } = error;
let message = `An error occurred while parsing the TOML file. Please check the syntax.`;
if (line !== undefined && col !== undefined) {
message = `An error occurred while parsing the TOML file. Please check the syntax at line ${line}, column ${col}.`;
}
toast.error(message, {
style: toastStyle.style,
...toastStyle.error,
});
setIsSaving(false);
return;
}
const rawJSONString = JSON.stringify(jsonEditedConfig);
await execPromiseWithErrorToast(
async () => {
const {
data: { replaceConfigRawJSON: updatedConfig },
} = await saveConfigMutation({
variables: {
appID: currentProject?.id,
rawJSON: rawJSONString,
},
});
if (updatedConfig) {
const jsonUpdatedConfig = JSON.parse(updatedConfig);
const updatedTOMLConfig = TOML.stringify(jsonUpdatedConfig);
const unindentedTOMLConfig = removeTOMLIndentation(updatedTOMLConfig);
setTOMLCode(unindentedTOMLConfig);
setPreviousTOMLCode(unindentedTOMLConfig);
}
if (!isPlatform) {
openDialog({
title: 'Apply your changes',
component: <ApplyLocalSettingsDialog />,
props: {
PaperProps: {
className: 'max-w-2xl',
},
},
});
}
setIsDirty(false);
setIsSaving(false);
},
{
loadingMessage: 'Saving configuration...',
successMessage: 'Configuration has been saved successfully.',
errorMessage:
'An error occurred while saving configuration. Please try again.',
onError: () => {
setIsSaving(false);
},
},
);
};
return (
<Box className="flex h-full flex-col">
<Box className="flex w-full flex-col space-y-2 border-b p-4">
<Text className="font-semibold">Configuration Editor</Text>
</Box>
<Box className="h-full overflow-auto">
{loading ? (
<Box
className="h-full w-full animate-pulse"
sx={{ backgroundColor: 'grey.200' }}
/>
) : (
<CodeMirror
value={tomlCode}
height="100%"
width="100%"
theme={theme.palette.mode === 'light' ? bbedit : githubDark}
basicSetup={{
searchKeymap: false,
}}
extensions={[StreamLanguage.define(toml)]}
onChange={onChange}
/>
)}
</Box>
<Box className="grid w-full grid-flow-col justify-end gap-3 place-self-end border-t-1 px-4 py-3 md:justify-between">
<Button
variant="outlined"
disabled={loading || !isDirty}
onClick={handleRevert}
color="secondary"
>
Revert changes
</Button>
<Button
type="submit"
disabled={loading || !isDirty}
loading={isSaving}
className="justify-self-end"
onClick={handleSave}
>
Save
</Button>
</Box>
</Box>
);
}

View File

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

View File

@@ -0,0 +1,3 @@
query getConfigRawJSON ($appID: uuid!) {
configRawJSON(appID: $appID, resolve: false)
}

View File

@@ -0,0 +1,3 @@
mutation ReplaceConfigRawJSON($appID: uuid!, $rawJSON: String!) {
replaceConfigRawJSON(appID: $appID, rawJSON: $rawJSON)
}

View File

@@ -0,0 +1,11 @@
import { SettingsLayout } from '@/components/layout/SettingsLayout';
import { TOMLEditor } from '@/features/projects/common/components/settings/TOMLEditor';
import type { ReactElement } from 'react';
export default function TOMLEditorPage() {
return <TOMLEditor />;
}
TOMLEditorPage.getLayout = function getLayout(page: ReactElement) {
return <SettingsLayout>{page}</SettingsLayout>;
};

View File

@@ -1037,6 +1037,26 @@ export type ConfigAuthsessionaccessTokenCustomClaimsUpdateInput = {
value?: InputMaybe<Scalars['String']>;
};
export type ConfigAutoscaler = {
__typename?: 'ConfigAutoscaler';
maxReplicas: Scalars['ConfigUint8'];
};
export type ConfigAutoscalerComparisonExp = {
_and?: InputMaybe<Array<ConfigAutoscalerComparisonExp>>;
_not?: InputMaybe<ConfigAutoscalerComparisonExp>;
_or?: InputMaybe<Array<ConfigAutoscalerComparisonExp>>;
maxReplicas?: InputMaybe<ConfigUint8ComparisonExp>;
};
export type ConfigAutoscalerInsertInput = {
maxReplicas: Scalars['ConfigUint8'];
};
export type ConfigAutoscalerUpdateInput = {
maxReplicas?: InputMaybe<Scalars['ConfigUint8']>;
};
export type ConfigBooleanComparisonExp = {
_eq?: InputMaybe<Scalars['Boolean']>;
_in?: InputMaybe<Array<Scalars['Boolean']>>;
@@ -1803,6 +1823,7 @@ export type ConfigPostgresInsertInput = {
/** Resources for the service */
export type ConfigPostgresResources = {
__typename?: 'ConfigPostgresResources';
autoscaler?: Maybe<ConfigAutoscaler>;
compute?: Maybe<ConfigResourcesCompute>;
enablePublicAccess?: Maybe<Scalars['Boolean']>;
networking?: Maybe<ConfigNetworking>;
@@ -1815,6 +1836,7 @@ export type ConfigPostgresResourcesComparisonExp = {
_and?: InputMaybe<Array<ConfigPostgresResourcesComparisonExp>>;
_not?: InputMaybe<ConfigPostgresResourcesComparisonExp>;
_or?: InputMaybe<Array<ConfigPostgresResourcesComparisonExp>>;
autoscaler?: InputMaybe<ConfigAutoscalerComparisonExp>;
compute?: InputMaybe<ConfigResourcesComputeComparisonExp>;
enablePublicAccess?: InputMaybe<ConfigBooleanComparisonExp>;
networking?: InputMaybe<ConfigNetworkingComparisonExp>;
@@ -1823,6 +1845,7 @@ export type ConfigPostgresResourcesComparisonExp = {
};
export type ConfigPostgresResourcesInsertInput = {
autoscaler?: InputMaybe<ConfigAutoscalerInsertInput>;
compute?: InputMaybe<ConfigResourcesComputeInsertInput>;
enablePublicAccess?: InputMaybe<Scalars['Boolean']>;
networking?: InputMaybe<ConfigNetworkingInsertInput>;
@@ -1831,6 +1854,7 @@ export type ConfigPostgresResourcesInsertInput = {
};
export type ConfigPostgresResourcesUpdateInput = {
autoscaler?: InputMaybe<ConfigAutoscalerUpdateInput>;
compute?: InputMaybe<ConfigResourcesComputeUpdateInput>;
enablePublicAccess?: InputMaybe<Scalars['Boolean']>;
networking?: InputMaybe<ConfigNetworkingUpdateInput>;
@@ -1992,6 +2016,7 @@ export type ConfigProviderUpdateInput = {
/** Resource configuration for a service */
export type ConfigResources = {
__typename?: 'ConfigResources';
autoscaler?: Maybe<ConfigAutoscaler>;
compute?: Maybe<ConfigResourcesCompute>;
networking?: Maybe<ConfigNetworking>;
/** Number of replicas for a service */
@@ -2002,6 +2027,7 @@ export type ConfigResourcesComparisonExp = {
_and?: InputMaybe<Array<ConfigResourcesComparisonExp>>;
_not?: InputMaybe<ConfigResourcesComparisonExp>;
_or?: InputMaybe<Array<ConfigResourcesComparisonExp>>;
autoscaler?: InputMaybe<ConfigAutoscalerComparisonExp>;
compute?: InputMaybe<ConfigResourcesComputeComparisonExp>;
networking?: InputMaybe<ConfigNetworkingComparisonExp>;
replicas?: InputMaybe<ConfigUint8ComparisonExp>;
@@ -2034,12 +2060,14 @@ export type ConfigResourcesComputeUpdateInput = {
};
export type ConfigResourcesInsertInput = {
autoscaler?: InputMaybe<ConfigAutoscalerInsertInput>;
compute?: InputMaybe<ConfigResourcesComputeInsertInput>;
networking?: InputMaybe<ConfigNetworkingInsertInput>;
replicas?: InputMaybe<Scalars['ConfigUint8']>;
};
export type ConfigResourcesUpdateInput = {
autoscaler?: InputMaybe<ConfigAutoscalerUpdateInput>;
compute?: InputMaybe<ConfigResourcesComputeUpdateInput>;
networking?: InputMaybe<ConfigNetworkingUpdateInput>;
replicas?: InputMaybe<Scalars['ConfigUint8']>;
@@ -2157,6 +2185,7 @@ export type ConfigRunServicePortUpdateInput = {
/** Resource configuration for a service */
export type ConfigRunServiceResources = {
__typename?: 'ConfigRunServiceResources';
autoscaler?: Maybe<ConfigAutoscaler>;
compute: ConfigComputeResources;
/** Number of replicas for a service */
replicas: Scalars['ConfigUint8'];
@@ -2167,12 +2196,14 @@ export type ConfigRunServiceResourcesComparisonExp = {
_and?: InputMaybe<Array<ConfigRunServiceResourcesComparisonExp>>;
_not?: InputMaybe<ConfigRunServiceResourcesComparisonExp>;
_or?: InputMaybe<Array<ConfigRunServiceResourcesComparisonExp>>;
autoscaler?: InputMaybe<ConfigAutoscalerComparisonExp>;
compute?: InputMaybe<ConfigComputeResourcesComparisonExp>;
replicas?: InputMaybe<ConfigUint8ComparisonExp>;
storage?: InputMaybe<ConfigRunServiceResourcesStorageComparisonExp>;
};
export type ConfigRunServiceResourcesInsertInput = {
autoscaler?: InputMaybe<ConfigAutoscalerInsertInput>;
compute: ConfigComputeResourcesInsertInput;
replicas: Scalars['ConfigUint8'];
storage?: InputMaybe<Array<ConfigRunServiceResourcesStorageInsertInput>>;
@@ -2209,6 +2240,7 @@ export type ConfigRunServiceResourcesStorageUpdateInput = {
};
export type ConfigRunServiceResourcesUpdateInput = {
autoscaler?: InputMaybe<ConfigAutoscalerUpdateInput>;
compute?: InputMaybe<ConfigComputeResourcesUpdateInput>;
replicas?: InputMaybe<Scalars['ConfigUint8']>;
storage?: InputMaybe<Array<ConfigRunServiceResourcesStorageUpdateInput>>;
@@ -12212,6 +12244,7 @@ export type Mutation_Root = {
pauseAppsExceedUsage: Array<Scalars['String']>;
pauseInactiveApps: Array<Scalars['String']>;
replaceConfig: ConfigConfig;
replaceConfigRawJSON: Scalars['String'];
replaceRunServiceConfig: ConfigRunServiceConfig;
resetPostgresPassword: Scalars['Boolean'];
restoreApplicationDatabase: Scalars['Boolean'];
@@ -13703,6 +13736,13 @@ export type Mutation_RootReplaceConfigArgs = {
};
/** mutation root */
export type Mutation_RootReplaceConfigRawJsonArgs = {
appID: Scalars['uuid'];
rawJSON: Scalars['String'];
};
/** mutation root */
export type Mutation_RootReplaceRunServiceConfigArgs = {
appID: Scalars['uuid'];
@@ -15209,6 +15249,7 @@ export type Plans = {
deprecated: Scalars['Boolean'];
featureAdvancedGraphql: Scalars['Boolean'];
featureBackupEnabled: Scalars['Boolean'];
featureBackupRetentionDays: Scalars['Int'];
featureCustomDomainsEnabled: Scalars['Boolean'];
featureCustomEmailTemplatesEnabled: Scalars['Boolean'];
featureCustomResources: Scalars['Boolean'];
@@ -15291,6 +15332,7 @@ export type Plans_Aggregate_FieldsCountArgs = {
/** aggregate avg on columns */
export type Plans_Avg_Fields = {
__typename?: 'plans_avg_fields';
featureBackupRetentionDays?: Maybe<Scalars['Float']>;
/** Function execution timeout in seconds */
featureFunctionExecutionTimeout?: Maybe<Scalars['Float']>;
featureMaxDbSize?: Maybe<Scalars['Float']>;
@@ -15312,6 +15354,7 @@ export type Plans_Bool_Exp = {
deprecated?: InputMaybe<Boolean_Comparison_Exp>;
featureAdvancedGraphql?: InputMaybe<Boolean_Comparison_Exp>;
featureBackupEnabled?: InputMaybe<Boolean_Comparison_Exp>;
featureBackupRetentionDays?: InputMaybe<Int_Comparison_Exp>;
featureCustomDomainsEnabled?: InputMaybe<Boolean_Comparison_Exp>;
featureCustomEmailTemplatesEnabled?: InputMaybe<Boolean_Comparison_Exp>;
featureCustomResources?: InputMaybe<Boolean_Comparison_Exp>;
@@ -15346,6 +15389,7 @@ export enum Plans_Constraint {
/** input type for incrementing numeric columns in table "plans" */
export type Plans_Inc_Input = {
featureBackupRetentionDays?: InputMaybe<Scalars['Int']>;
/** Function execution timeout in seconds */
featureFunctionExecutionTimeout?: InputMaybe<Scalars['Int']>;
featureMaxDbSize?: InputMaybe<Scalars['Int']>;
@@ -15363,6 +15407,7 @@ export type Plans_Insert_Input = {
deprecated?: InputMaybe<Scalars['Boolean']>;
featureAdvancedGraphql?: InputMaybe<Scalars['Boolean']>;
featureBackupEnabled?: InputMaybe<Scalars['Boolean']>;
featureBackupRetentionDays?: InputMaybe<Scalars['Int']>;
featureCustomDomainsEnabled?: InputMaybe<Scalars['Boolean']>;
featureCustomEmailTemplatesEnabled?: InputMaybe<Scalars['Boolean']>;
featureCustomResources?: InputMaybe<Scalars['Boolean']>;
@@ -15396,6 +15441,7 @@ export type Plans_Insert_Input = {
export type Plans_Max_Fields = {
__typename?: 'plans_max_fields';
createdAt?: Maybe<Scalars['timestamptz']>;
featureBackupRetentionDays?: Maybe<Scalars['Int']>;
/** Function execution timeout in seconds */
featureFunctionExecutionTimeout?: Maybe<Scalars['Int']>;
featureMaxDbSize?: Maybe<Scalars['Int']>;
@@ -15420,6 +15466,7 @@ export type Plans_Max_Fields = {
export type Plans_Min_Fields = {
__typename?: 'plans_min_fields';
createdAt?: Maybe<Scalars['timestamptz']>;
featureBackupRetentionDays?: Maybe<Scalars['Int']>;
/** Function execution timeout in seconds */
featureFunctionExecutionTimeout?: Maybe<Scalars['Int']>;
featureMaxDbSize?: Maybe<Scalars['Int']>;
@@ -15470,6 +15517,7 @@ export type Plans_Order_By = {
deprecated?: InputMaybe<Order_By>;
featureAdvancedGraphql?: InputMaybe<Order_By>;
featureBackupEnabled?: InputMaybe<Order_By>;
featureBackupRetentionDays?: InputMaybe<Order_By>;
featureCustomDomainsEnabled?: InputMaybe<Order_By>;
featureCustomEmailTemplatesEnabled?: InputMaybe<Order_By>;
featureCustomResources?: InputMaybe<Order_By>;
@@ -15512,6 +15560,8 @@ export enum Plans_Select_Column {
/** column name */
FeatureBackupEnabled = 'featureBackupEnabled',
/** column name */
FeatureBackupRetentionDays = 'featureBackupRetentionDays',
/** column name */
FeatureCustomDomainsEnabled = 'featureCustomDomainsEnabled',
/** column name */
FeatureCustomEmailTemplatesEnabled = 'featureCustomEmailTemplatesEnabled',
@@ -15567,6 +15617,7 @@ export type Plans_Set_Input = {
deprecated?: InputMaybe<Scalars['Boolean']>;
featureAdvancedGraphql?: InputMaybe<Scalars['Boolean']>;
featureBackupEnabled?: InputMaybe<Scalars['Boolean']>;
featureBackupRetentionDays?: InputMaybe<Scalars['Int']>;
featureCustomDomainsEnabled?: InputMaybe<Scalars['Boolean']>;
featureCustomEmailTemplatesEnabled?: InputMaybe<Scalars['Boolean']>;
featureCustomResources?: InputMaybe<Scalars['Boolean']>;
@@ -15599,6 +15650,7 @@ export type Plans_Set_Input = {
/** aggregate stddev on columns */
export type Plans_Stddev_Fields = {
__typename?: 'plans_stddev_fields';
featureBackupRetentionDays?: Maybe<Scalars['Float']>;
/** Function execution timeout in seconds */
featureFunctionExecutionTimeout?: Maybe<Scalars['Float']>;
featureMaxDbSize?: Maybe<Scalars['Float']>;
@@ -15612,6 +15664,7 @@ export type Plans_Stddev_Fields = {
/** aggregate stddev_pop on columns */
export type Plans_Stddev_Pop_Fields = {
__typename?: 'plans_stddev_pop_fields';
featureBackupRetentionDays?: Maybe<Scalars['Float']>;
/** Function execution timeout in seconds */
featureFunctionExecutionTimeout?: Maybe<Scalars['Float']>;
featureMaxDbSize?: Maybe<Scalars['Float']>;
@@ -15625,6 +15678,7 @@ export type Plans_Stddev_Pop_Fields = {
/** aggregate stddev_samp on columns */
export type Plans_Stddev_Samp_Fields = {
__typename?: 'plans_stddev_samp_fields';
featureBackupRetentionDays?: Maybe<Scalars['Float']>;
/** Function execution timeout in seconds */
featureFunctionExecutionTimeout?: Maybe<Scalars['Float']>;
featureMaxDbSize?: Maybe<Scalars['Float']>;
@@ -15649,6 +15703,7 @@ export type Plans_Stream_Cursor_Value_Input = {
deprecated?: InputMaybe<Scalars['Boolean']>;
featureAdvancedGraphql?: InputMaybe<Scalars['Boolean']>;
featureBackupEnabled?: InputMaybe<Scalars['Boolean']>;
featureBackupRetentionDays?: InputMaybe<Scalars['Int']>;
featureCustomDomainsEnabled?: InputMaybe<Scalars['Boolean']>;
featureCustomEmailTemplatesEnabled?: InputMaybe<Scalars['Boolean']>;
featureCustomResources?: InputMaybe<Scalars['Boolean']>;
@@ -15681,6 +15736,7 @@ export type Plans_Stream_Cursor_Value_Input = {
/** aggregate sum on columns */
export type Plans_Sum_Fields = {
__typename?: 'plans_sum_fields';
featureBackupRetentionDays?: Maybe<Scalars['Int']>;
/** Function execution timeout in seconds */
featureFunctionExecutionTimeout?: Maybe<Scalars['Int']>;
featureMaxDbSize?: Maybe<Scalars['Int']>;
@@ -15702,6 +15758,8 @@ export enum Plans_Update_Column {
/** column name */
FeatureBackupEnabled = 'featureBackupEnabled',
/** column name */
FeatureBackupRetentionDays = 'featureBackupRetentionDays',
/** column name */
FeatureCustomDomainsEnabled = 'featureCustomDomainsEnabled',
/** column name */
FeatureCustomEmailTemplatesEnabled = 'featureCustomEmailTemplatesEnabled',
@@ -15763,6 +15821,7 @@ export type Plans_Updates = {
/** aggregate var_pop on columns */
export type Plans_Var_Pop_Fields = {
__typename?: 'plans_var_pop_fields';
featureBackupRetentionDays?: Maybe<Scalars['Float']>;
/** Function execution timeout in seconds */
featureFunctionExecutionTimeout?: Maybe<Scalars['Float']>;
featureMaxDbSize?: Maybe<Scalars['Float']>;
@@ -15776,6 +15835,7 @@ export type Plans_Var_Pop_Fields = {
/** aggregate var_samp on columns */
export type Plans_Var_Samp_Fields = {
__typename?: 'plans_var_samp_fields';
featureBackupRetentionDays?: Maybe<Scalars['Float']>;
/** Function execution timeout in seconds */
featureFunctionExecutionTimeout?: Maybe<Scalars['Float']>;
featureMaxDbSize?: Maybe<Scalars['Float']>;
@@ -15789,6 +15849,7 @@ export type Plans_Var_Samp_Fields = {
/** aggregate variance on columns */
export type Plans_Variance_Fields = {
__typename?: 'plans_variance_fields';
featureBackupRetentionDays?: Maybe<Scalars['Float']>;
/** Function execution timeout in seconds */
featureFunctionExecutionTimeout?: Maybe<Scalars['Float']>;
featureMaxDbSize?: Maybe<Scalars['Float']>;
@@ -22941,6 +23002,21 @@ export type GetEnvironmentVariablesQueryVariables = Exact<{
export type GetEnvironmentVariablesQuery = { __typename?: 'query_root', config?: { __typename: 'ConfigConfig', id: 'ConfigConfig', global?: { __typename?: 'ConfigGlobal', environment?: Array<{ __typename?: 'ConfigGlobalEnvironmentVariable', name: string, value: string, id: string }> | null } | null, hasura: { __typename?: 'ConfigHasura', adminSecret: string, webhookSecret: string, jwtSecrets?: Array<{ __typename?: 'ConfigJWTSecret', issuer?: string | null, key?: string | null, type?: string | null, jwk_url?: any | null, header?: string | null, claims_namespace_path?: string | null, claims_namespace?: string | null, claims_format?: string | null, audience?: string | null, allowed_skew?: any | null }> | null } } | null };
export type GetConfigRawJsonQueryVariables = Exact<{
appID: Scalars['uuid'];
}>;
export type GetConfigRawJsonQuery = { __typename?: 'query_root', configRawJSON: string };
export type ReplaceConfigRawJsonMutationVariables = Exact<{
appID: Scalars['uuid'];
rawJSON: Scalars['String'];
}>;
export type ReplaceConfigRawJsonMutation = { __typename?: 'mutation_root', replaceConfigRawJSON: string };
export type PermissionVariableFragment = { __typename?: 'ConfigAuthsessionaccessTokenCustomClaims', key: string, value: string, id: string };
export type GetRolesPermissionsQueryVariables = Exact<{
@@ -25201,6 +25277,74 @@ export type GetEnvironmentVariablesQueryResult = Apollo.QueryResult<GetEnvironme
export function refetchGetEnvironmentVariablesQuery(variables: GetEnvironmentVariablesQueryVariables) {
return { query: GetEnvironmentVariablesDocument, variables: variables }
}
export const GetConfigRawJsonDocument = gql`
query getConfigRawJSON($appID: uuid!) {
configRawJSON(appID: $appID, resolve: false)
}
`;
/**
* __useGetConfigRawJsonQuery__
*
* To run a query within a React component, call `useGetConfigRawJsonQuery` and pass it any options that fit your needs.
* When your component renders, `useGetConfigRawJsonQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useGetConfigRawJsonQuery({
* variables: {
* appID: // value for 'appID'
* },
* });
*/
export function useGetConfigRawJsonQuery(baseOptions: Apollo.QueryHookOptions<GetConfigRawJsonQuery, GetConfigRawJsonQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<GetConfigRawJsonQuery, GetConfigRawJsonQueryVariables>(GetConfigRawJsonDocument, options);
}
export function useGetConfigRawJsonLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetConfigRawJsonQuery, GetConfigRawJsonQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<GetConfigRawJsonQuery, GetConfigRawJsonQueryVariables>(GetConfigRawJsonDocument, options);
}
export type GetConfigRawJsonQueryHookResult = ReturnType<typeof useGetConfigRawJsonQuery>;
export type GetConfigRawJsonLazyQueryHookResult = ReturnType<typeof useGetConfigRawJsonLazyQuery>;
export type GetConfigRawJsonQueryResult = Apollo.QueryResult<GetConfigRawJsonQuery, GetConfigRawJsonQueryVariables>;
export function refetchGetConfigRawJsonQuery(variables: GetConfigRawJsonQueryVariables) {
return { query: GetConfigRawJsonDocument, variables: variables }
}
export const ReplaceConfigRawJsonDocument = gql`
mutation ReplaceConfigRawJSON($appID: uuid!, $rawJSON: String!) {
replaceConfigRawJSON(appID: $appID, rawJSON: $rawJSON)
}
`;
export type ReplaceConfigRawJsonMutationFn = Apollo.MutationFunction<ReplaceConfigRawJsonMutation, ReplaceConfigRawJsonMutationVariables>;
/**
* __useReplaceConfigRawJsonMutation__
*
* To run a mutation, you first call `useReplaceConfigRawJsonMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useReplaceConfigRawJsonMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [replaceConfigRawJsonMutation, { data, loading, error }] = useReplaceConfigRawJsonMutation({
* variables: {
* appID: // value for 'appID'
* rawJSON: // value for 'rawJSON'
* },
* });
*/
export function useReplaceConfigRawJsonMutation(baseOptions?: Apollo.MutationHookOptions<ReplaceConfigRawJsonMutation, ReplaceConfigRawJsonMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<ReplaceConfigRawJsonMutation, ReplaceConfigRawJsonMutationVariables>(ReplaceConfigRawJsonDocument, options);
}
export type ReplaceConfigRawJsonMutationHookResult = ReturnType<typeof useReplaceConfigRawJsonMutation>;
export type ReplaceConfigRawJsonMutationResult = Apollo.MutationResult<ReplaceConfigRawJsonMutation>;
export type ReplaceConfigRawJsonMutationOptions = Apollo.BaseMutationOptions<ReplaceConfigRawJsonMutation, ReplaceConfigRawJsonMutationVariables>;
export const GetRolesPermissionsDocument = gql`
query GetRolesPermissions($appId: uuid!) {
config(appID: $appId, resolve: false) {

7410
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff