Compare commits
30 Commits
@nhost/das
...
@nhost/vue
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22cdd7f8d7 | ||
|
|
f3a91a1f76 | ||
|
|
1e9b92fcf8 | ||
|
|
6cc56066c2 | ||
|
|
a3ad84925c | ||
|
|
b8611b6a1c | ||
|
|
a0e3030005 | ||
|
|
0cf1f1d938 | ||
|
|
88f026066f | ||
|
|
185bef878d | ||
|
|
a1c7b00e74 | ||
|
|
6da4562e79 | ||
|
|
e44cfcb2f2 | ||
|
|
23fabaf8a6 | ||
|
|
f4dca9836f | ||
|
|
f2704ea149 | ||
|
|
dd1b053212 | ||
|
|
d4ccc65655 | ||
|
|
2c2570fc82 | ||
|
|
a60f26966b | ||
|
|
a988de2d61 | ||
|
|
de54ca460e | ||
|
|
afdffab743 | ||
|
|
4c61520397 | ||
|
|
f02cd444d5 | ||
|
|
7f45a51aca | ||
|
|
08e70b9df9 | ||
|
|
bfaa5b4c4a | ||
|
|
a1a00b33ad | ||
|
|
a269f4ca3f |
@@ -1,5 +1,13 @@
|
|||||||
# @nhost/dashboard
|
# @nhost/dashboard
|
||||||
|
|
||||||
|
## 0.14.7
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- d4ccc656: chore: cleanup unused code
|
||||||
|
- @nhost/react-apollo@5.0.18
|
||||||
|
- @nhost/nextjs@1.13.21
|
||||||
|
|
||||||
## 0.14.6
|
## 0.14.6
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nhost/dashboard",
|
"name": "@nhost/dashboard",
|
||||||
"version": "0.14.6",
|
"version": "0.14.7",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"preinstall": "npx only-allow pnpm",
|
"preinstall": "npx only-allow pnpm",
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
"build": "next build --no-lint",
|
"build": "next build --no-lint",
|
||||||
"analyze": "ANALYZE=true pnpm build --no-lint",
|
"analyze": "ANALYZE=true pnpm build --no-lint",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint --max-warnings 1",
|
"lint": "next lint --max-warnings 0",
|
||||||
"test": "vitest",
|
"test": "vitest",
|
||||||
"codegen": "graphql-codegen --config graphql.config.yaml --errors-only",
|
"codegen": "graphql-codegen --config graphql.config.yaml --errors-only",
|
||||||
"nhost:dev": "nhost dev -d",
|
"nhost:dev": "nhost dev -d",
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
GetAllWorkspacesAndProjectsDocument,
|
GetAllWorkspacesAndProjectsDocument,
|
||||||
GetOneUserDocument,
|
|
||||||
useDeleteApplicationMutation,
|
useDeleteApplicationMutation,
|
||||||
} from '@/generated/graphql';
|
} from '@/generated/graphql';
|
||||||
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
||||||
@@ -11,6 +10,7 @@ import Text from '@/ui/v2/Text';
|
|||||||
import { copy } from '@/utils/copy';
|
import { copy } from '@/utils/copy';
|
||||||
import { getApplicationStatusString } from '@/utils/helpers';
|
import { getApplicationStatusString } from '@/utils/helpers';
|
||||||
import getServerError from '@/utils/settings/getServerError';
|
import getServerError from '@/utils/settings/getServerError';
|
||||||
|
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
||||||
import { formatDistance } from 'date-fns';
|
import { formatDistance } from 'date-fns';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { toast } from 'react-hot-toast';
|
import { toast } from 'react-hot-toast';
|
||||||
@@ -18,7 +18,7 @@ import { toast } from 'react-hot-toast';
|
|||||||
export default function ApplicationInfo() {
|
export default function ApplicationInfo() {
|
||||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||||
const [deleteApplication] = useDeleteApplicationMutation({
|
const [deleteApplication] = useDeleteApplicationMutation({
|
||||||
refetchQueries: [GetOneUserDocument, GetAllWorkspacesAndProjectsDocument],
|
refetchQueries: [GetAllWorkspacesAndProjectsDocument],
|
||||||
});
|
});
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -37,6 +37,7 @@ export default function ApplicationInfo() {
|
|||||||
'An error occurred while deleting the project. Please try again.',
|
'An error occurred while deleting the project. Please try again.',
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
getToastStyleProps(),
|
||||||
);
|
);
|
||||||
|
|
||||||
await router.push('/');
|
await router.push('/');
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { useDialog } from '@/components/common/DialogProvider';
|
|||||||
import Container from '@/components/layout/Container';
|
import Container from '@/components/layout/Container';
|
||||||
import {
|
import {
|
||||||
GetAllWorkspacesAndProjectsDocument,
|
GetAllWorkspacesAndProjectsDocument,
|
||||||
GetOneUserDocument,
|
|
||||||
useGetFreeAndActiveProjectsQuery,
|
useGetFreeAndActiveProjectsQuery,
|
||||||
useUnpauseApplicationMutation,
|
useUnpauseApplicationMutation,
|
||||||
} from '@/generated/graphql';
|
} from '@/generated/graphql';
|
||||||
@@ -26,8 +25,12 @@ import { toast } from 'react-hot-toast';
|
|||||||
import { RemoveApplicationModal } from './RemoveApplicationModal';
|
import { RemoveApplicationModal } from './RemoveApplicationModal';
|
||||||
|
|
||||||
export default function ApplicationPaused() {
|
export default function ApplicationPaused() {
|
||||||
const { openAlertDialog } = useDialog();
|
const { openDialog } = useDialog();
|
||||||
const { currentWorkspace, currentProject } = useCurrentWorkspaceAndProject();
|
const {
|
||||||
|
currentWorkspace,
|
||||||
|
currentProject,
|
||||||
|
refetch: refetchWorkspaceAndProject,
|
||||||
|
} = useCurrentWorkspaceAndProject();
|
||||||
const user = useUserData();
|
const user = useUserData();
|
||||||
const isOwner = currentWorkspace.workspaceMembers.some(
|
const isOwner = currentWorkspace.workspaceMembers.some(
|
||||||
({ id, type }) => id === user?.id && type === 'owner',
|
({ id, type }) => id === user?.id && type === 'owner',
|
||||||
@@ -35,7 +38,7 @@ export default function ApplicationPaused() {
|
|||||||
const [showDeletingModal, setShowDeletingModal] = useState(false);
|
const [showDeletingModal, setShowDeletingModal] = useState(false);
|
||||||
const [unpauseApplication, { loading: changingApplicationStateLoading }] =
|
const [unpauseApplication, { loading: changingApplicationStateLoading }] =
|
||||||
useUnpauseApplicationMutation({
|
useUnpauseApplicationMutation({
|
||||||
refetchQueries: [GetOneUserDocument, GetAllWorkspacesAndProjectsDocument],
|
refetchQueries: [GetAllWorkspacesAndProjectsDocument],
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data, loading } = useGetFreeAndActiveProjectsQuery({
|
const { data, loading } = useGetFreeAndActiveProjectsQuery({
|
||||||
@@ -70,6 +73,8 @@ export default function ApplicationPaused() {
|
|||||||
},
|
},
|
||||||
getToastStyleProps(),
|
getToastStyleProps(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await refetchWorkspaceAndProject();
|
||||||
} catch {
|
} catch {
|
||||||
// Note: The toast will handle the error.
|
// Note: The toast will handle the error.
|
||||||
}
|
}
|
||||||
@@ -118,9 +123,9 @@ export default function ApplicationPaused() {
|
|||||||
<Button
|
<Button
|
||||||
className="mx-auto w-full max-w-[280px]"
|
className="mx-auto w-full max-w-[280px]"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
openAlertDialog({
|
openDialog({
|
||||||
title: 'Upgrade your plan.',
|
title: 'Upgrade your plan.',
|
||||||
payload: <ChangePlanModal />,
|
component: <ChangePlanModal />,
|
||||||
props: {
|
props: {
|
||||||
PaperProps: { className: 'p-0' },
|
PaperProps: { className: 'p-0' },
|
||||||
hidePrimaryAction: true,
|
hidePrimaryAction: true,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
refetchGetApplicationPlanQuery,
|
refetchGetApplicationPlanQuery,
|
||||||
useGetAppPlanAndGlobalPlansQuery,
|
useGetAppPlanAndGlobalPlansQuery,
|
||||||
useGetPaymentMethodsQuery,
|
useGetPaymentMethodsQuery,
|
||||||
useUpdateAppMutation,
|
useUpdateApplicationMutation,
|
||||||
} from '@/generated/graphql';
|
} from '@/generated/graphql';
|
||||||
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
||||||
import { Modal } from '@/ui/Modal';
|
import { Modal } from '@/ui/Modal';
|
||||||
@@ -89,7 +89,7 @@ export function ChangePlanModalWithData({ app, plans, close }: any) {
|
|||||||
const isDowngrade = currentPlan.price > selectedPlan?.price;
|
const isDowngrade = currentPlan.price > selectedPlan?.price;
|
||||||
|
|
||||||
// graphql mutations
|
// graphql mutations
|
||||||
const [updateApp] = useUpdateAppMutation({
|
const [updateApp] = useUpdateApplicationMutation({
|
||||||
refetchQueries: [
|
refetchQueries: [
|
||||||
refetchGetApplicationPlanQuery({
|
refetchGetApplicationPlanQuery({
|
||||||
workspace: currentWorkspace.slug,
|
workspace: currentWorkspace.slug,
|
||||||
@@ -102,7 +102,7 @@ export function ChangePlanModalWithData({ app, plans, close }: any) {
|
|||||||
const handleUpdateAppPlan = async () => {
|
const handleUpdateAppPlan = async () => {
|
||||||
await updateApp({
|
await updateApp({
|
||||||
variables: {
|
variables: {
|
||||||
id: app.id,
|
appId: app.id,
|
||||||
app: {
|
app: {
|
||||||
planId: selectedPlan.id,
|
planId: selectedPlan.id,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import Divider from '@/ui/v2/Divider';
|
|||||||
import Text from '@/ui/v2/Text';
|
import Text from '@/ui/v2/Text';
|
||||||
import {
|
import {
|
||||||
GetAllWorkspacesAndProjectsDocument,
|
GetAllWorkspacesAndProjectsDocument,
|
||||||
GetOneUserDocument,
|
|
||||||
useDeleteApplicationMutation,
|
useDeleteApplicationMutation,
|
||||||
} from '@/utils/__generated__/graphql';
|
} from '@/utils/__generated__/graphql';
|
||||||
import { discordAnnounce } from '@/utils/discordAnnounce';
|
import { discordAnnounce } from '@/utils/discordAnnounce';
|
||||||
@@ -47,7 +46,7 @@ export function RemoveApplicationModal({
|
|||||||
className,
|
className,
|
||||||
}: RemoveApplicationModalProps) {
|
}: RemoveApplicationModalProps) {
|
||||||
const [deleteApplication] = useDeleteApplicationMutation({
|
const [deleteApplication] = useDeleteApplicationMutation({
|
||||||
refetchQueries: [GetOneUserDocument, GetAllWorkspacesAndProjectsDocument],
|
refetchQueries: [GetAllWorkspacesAndProjectsDocument],
|
||||||
});
|
});
|
||||||
const [loadingRemove, setLoadingRemove] = useState(false);
|
const [loadingRemove, setLoadingRemove] = useState(false);
|
||||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export function UnlockFeatureByUpgrading({
|
|||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
}: UnlockFeatureByUpgradingProps) {
|
}: UnlockFeatureByUpgradingProps) {
|
||||||
const { openAlertDialog } = useDialog();
|
const { openDialog } = useDialog();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={twMerge('flex', className)} {...props}>
|
<div className={twMerge('flex', className)} {...props}>
|
||||||
@@ -29,9 +29,9 @@ export function UnlockFeatureByUpgrading({
|
|||||||
<Button
|
<Button
|
||||||
variant="borderless"
|
variant="borderless"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
openAlertDialog({
|
openDialog({
|
||||||
title: 'Upgrade your plan.',
|
title: 'Upgrade your plan.',
|
||||||
payload: <ChangePlanModal />,
|
component: <ChangePlanModal />,
|
||||||
props: {
|
props: {
|
||||||
PaperProps: { className: 'p-0 max-w-xl w-full' },
|
PaperProps: { className: 'p-0 max-w-xl w-full' },
|
||||||
hidePrimaryAction: true,
|
hidePrimaryAction: true,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import type { EditRepositorySettingsFormData } from '@/components/applications/g
|
|||||||
import { useDialog } from '@/components/common/DialogProvider';
|
import { useDialog } from '@/components/common/DialogProvider';
|
||||||
import ErrorBoundaryFallback from '@/components/common/ErrorBoundaryFallback';
|
import ErrorBoundaryFallback from '@/components/common/ErrorBoundaryFallback';
|
||||||
import GithubIcon from '@/components/icons/GithubIcon';
|
import GithubIcon from '@/components/icons/GithubIcon';
|
||||||
import { useUpdateAppMutation } from '@/generated/graphql';
|
import { useUpdateApplicationMutation } from '@/generated/graphql';
|
||||||
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
||||||
import Button from '@/ui/v2/Button';
|
import Button from '@/ui/v2/Button';
|
||||||
import Text from '@/ui/v2/Text';
|
import Text from '@/ui/v2/Text';
|
||||||
@@ -29,7 +29,7 @@ export function EditRepositorySettingsModal({
|
|||||||
|
|
||||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||||
|
|
||||||
const [updateApp, { loading }] = useUpdateAppMutation();
|
const [updateApp, { loading }] = useUpdateApplicationMutation();
|
||||||
|
|
||||||
const client = useApolloClient();
|
const client = useApolloClient();
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ export function EditRepositorySettingsModal({
|
|||||||
if (!currentProject.githubRepository || selectedRepoId) {
|
if (!currentProject.githubRepository || selectedRepoId) {
|
||||||
await updateApp({
|
await updateApp({
|
||||||
variables: {
|
variables: {
|
||||||
id: currentProject.id,
|
appId: currentProject.id,
|
||||||
app: {
|
app: {
|
||||||
githubRepositoryId: selectedRepoId,
|
githubRepositoryId: selectedRepoId,
|
||||||
repositoryProductionBranch: data.productionBranch,
|
repositoryProductionBranch: data.productionBranch,
|
||||||
@@ -51,7 +51,7 @@ export function EditRepositorySettingsModal({
|
|||||||
} else {
|
} else {
|
||||||
await updateApp({
|
await updateApp({
|
||||||
variables: {
|
variables: {
|
||||||
id: currentProject.id,
|
appId: currentProject.id,
|
||||||
app: {
|
app: {
|
||||||
repositoryProductionBranch: data.productionBranch,
|
repositoryProductionBranch: data.productionBranch,
|
||||||
nhostBaseFolder: data.repoBaseFolder,
|
nhostBaseFolder: data.repoBaseFolder,
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import Form from '@/components/common/Form';
|
|||||||
import type { DialogFormProps } from '@/types/common';
|
import type { DialogFormProps } from '@/types/common';
|
||||||
import Button from '@/ui/v2/Button';
|
import Button from '@/ui/v2/Button';
|
||||||
import Input from '@/ui/v2/Input';
|
import Input from '@/ui/v2/Input';
|
||||||
import { slugifyString } from '@/utils/helpers';
|
|
||||||
import getServerError from '@/utils/settings/getServerError';
|
|
||||||
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
|
||||||
import {
|
import {
|
||||||
refetchGetOneUserQuery,
|
GetAllWorkspacesAndProjectsDocument,
|
||||||
useInsertWorkspaceMutation,
|
useInsertWorkspaceMutation,
|
||||||
useUpdateWorkspaceMutation,
|
useUpdateWorkspaceMutation,
|
||||||
} from '@/utils/__generated__/graphql';
|
} from '@/utils/__generated__/graphql';
|
||||||
|
import { slugifyString } from '@/utils/helpers';
|
||||||
|
import getServerError from '@/utils/settings/getServerError';
|
||||||
|
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
||||||
import { yupResolver } from '@hookform/resolvers/yup';
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
import { useUserData } from '@nhost/nextjs';
|
import { useUserData } from '@nhost/nextjs';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
@@ -85,11 +85,7 @@ export default function EditWorkspaceNameForm({
|
|||||||
const currentUser = useUserData();
|
const currentUser = useUserData();
|
||||||
const [insertWorkspace, { client }] = useInsertWorkspaceMutation();
|
const [insertWorkspace, { client }] = useInsertWorkspaceMutation();
|
||||||
const [updateWorkspaceName] = useUpdateWorkspaceMutation({
|
const [updateWorkspaceName] = useUpdateWorkspaceMutation({
|
||||||
refetchQueries: [
|
refetchQueries: [GetAllWorkspacesAndProjectsDocument],
|
||||||
refetchGetOneUserQuery({
|
|
||||||
userId: currentUser.id,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
awaitRefetchQueries: true,
|
awaitRefetchQueries: true,
|
||||||
ignoreResults: true,
|
ignoreResults: true,
|
||||||
});
|
});
|
||||||
@@ -196,7 +192,7 @@ export default function EditWorkspaceNameForm({
|
|||||||
}
|
}
|
||||||
|
|
||||||
await client.refetchQueries({
|
await client.refetchQueries({
|
||||||
include: ['getOneUser'],
|
include: [GetAllWorkspacesAndProjectsDocument],
|
||||||
});
|
});
|
||||||
|
|
||||||
// The form has been submitted, it's not dirty anymore
|
// The form has been submitted, it's not dirty anymore
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import { useGetWorkspaceMemberInvitesToManageQuery } from '@/generated/graphql';
|
import {
|
||||||
|
GetAllWorkspacesAndProjectsDocument,
|
||||||
|
GetWorkspaceMemberInvitesToManageDocument,
|
||||||
|
useGetWorkspaceMemberInvitesToManageQuery,
|
||||||
|
} from '@/generated/graphql';
|
||||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||||
import { useSubmitState } from '@/hooks/useSubmitState';
|
import { useSubmitState } from '@/hooks/useSubmitState';
|
||||||
import Box from '@/ui/v2/Box';
|
import Box from '@/ui/v2/Box';
|
||||||
@@ -114,7 +118,10 @@ export function InviteAnnounce() {
|
|||||||
|
|
||||||
// just refetch all data
|
// just refetch all data
|
||||||
await client.refetchQueries({
|
await client.refetchQueries({
|
||||||
include: ['getOneUser', 'getWorkspaceMemberInvitesToManage'],
|
include: [
|
||||||
|
GetAllWorkspacesAndProjectsDocument,
|
||||||
|
GetWorkspaceMemberInvitesToManageDocument,
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
setIgnoreState({
|
setIgnoreState({
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import type { AuthenticatedLayoutProps } from '@/components/layout/Authenticated
|
|||||||
import AuthenticatedLayout from '@/components/layout/AuthenticatedLayout';
|
import AuthenticatedLayout from '@/components/layout/AuthenticatedLayout';
|
||||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||||
import useProjectRoutes from '@/hooks/common/useProjectRoutes';
|
import useProjectRoutes from '@/hooks/common/useProjectRoutes';
|
||||||
import { useGetAllUserWorkspacesAndApplications } from '@/hooks/useGetAllUserWorkspacesAndApplications';
|
|
||||||
import { useNavigationVisible } from '@/hooks/useNavigationVisible';
|
import { useNavigationVisible } from '@/hooks/useNavigationVisible';
|
||||||
import useNotFoundRedirect from '@/hooks/useNotFoundRedirect';
|
import useNotFoundRedirect from '@/hooks/useNotFoundRedirect';
|
||||||
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
||||||
@@ -47,7 +46,6 @@ function ProjectLayoutContent({
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
useGetAllUserWorkspacesAndApplications(false);
|
|
||||||
useNotFoundRedirect();
|
useNotFoundRedirect();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export default function OverviewTopBar() {
|
|||||||
const isPlatform = useIsPlatform();
|
const isPlatform = useIsPlatform();
|
||||||
const { currentWorkspace, currentProject } = useCurrentWorkspaceAndProject();
|
const { currentWorkspace, currentProject } = useCurrentWorkspaceAndProject();
|
||||||
const isPro = !currentProject?.plan?.isFree;
|
const isPro = !currentProject?.plan?.isFree;
|
||||||
const { openAlertDialog } = useDialog();
|
const { openDialog } = useDialog();
|
||||||
const { maintenanceActive } = useUI();
|
const { maintenanceActive } = useUI();
|
||||||
|
|
||||||
if (!isPlatform) {
|
if (!isPlatform) {
|
||||||
@@ -92,9 +92,9 @@ export default function OverviewTopBar() {
|
|||||||
variant="borderless"
|
variant="borderless"
|
||||||
className="mr-2"
|
className="mr-2"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
openAlertDialog({
|
openDialog({
|
||||||
title: 'Upgrade your plan.',
|
title: 'Upgrade your plan.',
|
||||||
payload: <ChangePlanModal />,
|
component: <ChangePlanModal />,
|
||||||
props: {
|
props: {
|
||||||
PaperProps: { className: 'p-0 max-w-xl w-full' },
|
PaperProps: { className: 'p-0 max-w-xl w-full' },
|
||||||
hidePrimaryAction: true,
|
hidePrimaryAction: true,
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ import Form from '@/components/common/Form';
|
|||||||
import InlineCode from '@/components/common/InlineCode';
|
import InlineCode from '@/components/common/InlineCode';
|
||||||
import SettingsContainer from '@/components/settings/SettingsContainer';
|
import SettingsContainer from '@/components/settings/SettingsContainer';
|
||||||
import { useUI } from '@/context/UIContext';
|
import { useUI } from '@/context/UIContext';
|
||||||
import { useUpdateAppMutation } from '@/generated/graphql';
|
import {
|
||||||
|
GetAllWorkspacesAndProjectsDocument,
|
||||||
|
useUpdateApplicationMutation,
|
||||||
|
} from '@/generated/graphql';
|
||||||
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
||||||
import { Alert } from '@/ui/Alert';
|
import { Alert } from '@/ui/Alert';
|
||||||
import Input from '@/ui/v2/Input';
|
import Input from '@/ui/v2/Input';
|
||||||
@@ -24,7 +27,7 @@ export interface BaseDirectoryFormValues {
|
|||||||
export default function BaseDirectorySettings() {
|
export default function BaseDirectorySettings() {
|
||||||
const { maintenanceActive } = useUI();
|
const { maintenanceActive } = useUI();
|
||||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||||
const [updateApp] = useUpdateAppMutation();
|
const [updateApp] = useUpdateApplicationMutation();
|
||||||
const client = useApolloClient();
|
const client = useApolloClient();
|
||||||
|
|
||||||
const form = useForm<BaseDirectoryFormValues>({
|
const form = useForm<BaseDirectoryFormValues>({
|
||||||
@@ -45,7 +48,7 @@ export default function BaseDirectorySettings() {
|
|||||||
const handleBaseFolderChange = async (values: BaseDirectoryFormValues) => {
|
const handleBaseFolderChange = async (values: BaseDirectoryFormValues) => {
|
||||||
const updateAppMutation = updateApp({
|
const updateAppMutation = updateApp({
|
||||||
variables: {
|
variables: {
|
||||||
id: currentProject.id,
|
appId: currentProject.id,
|
||||||
app: {
|
app: {
|
||||||
...values,
|
...values,
|
||||||
},
|
},
|
||||||
@@ -67,7 +70,9 @@ export default function BaseDirectorySettings() {
|
|||||||
form.reset(values);
|
form.reset(values);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await client.refetchQueries({ include: ['getOneUser'] });
|
await client.refetchQueries({
|
||||||
|
include: [GetAllWorkspacesAndProjectsDocument],
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await discordAnnounce(
|
await discordAnnounce(
|
||||||
error.message || 'Error while trying to update application cache',
|
error.message || 'Error while trying to update application cache',
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import Form from '@/components/common/Form';
|
import Form from '@/components/common/Form';
|
||||||
import SettingsContainer from '@/components/settings/SettingsContainer';
|
import SettingsContainer from '@/components/settings/SettingsContainer';
|
||||||
import { useUI } from '@/context/UIContext';
|
import { useUI } from '@/context/UIContext';
|
||||||
import { useUpdateAppMutation } from '@/generated/graphql';
|
import {
|
||||||
|
GetAllWorkspacesAndProjectsDocument,
|
||||||
|
useUpdateApplicationMutation,
|
||||||
|
} from '@/generated/graphql';
|
||||||
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
||||||
import { Alert } from '@/ui/Alert';
|
import { Alert } from '@/ui/Alert';
|
||||||
import Input from '@/ui/v2/Input';
|
import Input from '@/ui/v2/Input';
|
||||||
@@ -23,7 +26,7 @@ export interface DeploymentBranchFormValues {
|
|||||||
export default function DeploymentBranchSettings() {
|
export default function DeploymentBranchSettings() {
|
||||||
const { maintenanceActive } = useUI();
|
const { maintenanceActive } = useUI();
|
||||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||||
const [updateApp] = useUpdateAppMutation();
|
const [updateApp] = useUpdateApplicationMutation();
|
||||||
const client = useApolloClient();
|
const client = useApolloClient();
|
||||||
|
|
||||||
const form = useForm<DeploymentBranchFormValues>({
|
const form = useForm<DeploymentBranchFormValues>({
|
||||||
@@ -46,7 +49,7 @@ export default function DeploymentBranchSettings() {
|
|||||||
) => {
|
) => {
|
||||||
const updateAppMutation = updateApp({
|
const updateAppMutation = updateApp({
|
||||||
variables: {
|
variables: {
|
||||||
id: currentProject.id,
|
appId: currentProject.id,
|
||||||
app: {
|
app: {
|
||||||
...values,
|
...values,
|
||||||
},
|
},
|
||||||
@@ -68,7 +71,9 @@ export default function DeploymentBranchSettings() {
|
|||||||
form.reset(values);
|
form.reset(values);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await client.refetchQueries({ include: ['getOneUser'] });
|
await client.refetchQueries({
|
||||||
|
include: [GetAllWorkspacesAndProjectsDocument],
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await discordAnnounce(
|
await discordAnnounce(
|
||||||
error.message || 'Error while trying to update application cache',
|
error.message || 'Error while trying to update application cache',
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
import { useDialog } from '@/components/common/DialogProvider';
|
|
||||||
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
|
||||||
import { Alert } from '@/ui/Alert';
|
|
||||||
import Button from '@/ui/v2/Button';
|
|
||||||
import Link from '@/ui/v2/Link';
|
|
||||||
import Text from '@/ui/v2/Text';
|
|
||||||
import ArrowSquareOutIcon from '@/ui/v2/icons/ArrowSquareOutIcon';
|
|
||||||
import { useConfirmProvidersUpdatedMutation } from '@/utils/__generated__/graphql';
|
|
||||||
import getServerError from '@/utils/settings/getServerError';
|
|
||||||
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import toast from 'react-hot-toast';
|
|
||||||
|
|
||||||
export default function ProvidersUpdatedAlert() {
|
|
||||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
|
||||||
const { openAlertDialog } = useDialog();
|
|
||||||
const [confirmed, setConfirmed] = useState(true);
|
|
||||||
|
|
||||||
const [confirmProvidersUpdated] = useConfirmProvidersUpdatedMutation({
|
|
||||||
variables: { id: currentProject?.id },
|
|
||||||
});
|
|
||||||
|
|
||||||
async function handleSubmitConfirmation() {
|
|
||||||
const confirmProvidersUpdatedPromise = confirmProvidersUpdated();
|
|
||||||
|
|
||||||
await toast.promise(
|
|
||||||
confirmProvidersUpdatedPromise,
|
|
||||||
{
|
|
||||||
loading: 'Confirming...',
|
|
||||||
success: 'Your settings have been updated successfully.',
|
|
||||||
error: getServerError(
|
|
||||||
'An error occurred while trying to confirm the message.',
|
|
||||||
),
|
|
||||||
},
|
|
||||||
getToastStyleProps(),
|
|
||||||
);
|
|
||||||
|
|
||||||
setConfirmed(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleOpenConfirmationDialog() {
|
|
||||||
openAlertDialog({
|
|
||||||
title: 'Confirm all providers updated?',
|
|
||||||
payload: (
|
|
||||||
<Text variant="subtitle1" component="span">
|
|
||||||
Please make sure to update all providers before continuing. Your
|
|
||||||
sign-in flows might break if you don't.
|
|
||||||
</Text>
|
|
||||||
),
|
|
||||||
props: {
|
|
||||||
onPrimaryAction: handleSubmitConfirmation,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!confirmed) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Alert className="grid grid-flow-row place-items-center items-center gap-2 bg-amber-500 p-4 lg:grid-flow-col lg:place-content-between">
|
|
||||||
<div className="grid grid-flow-row gap-1 text-left">
|
|
||||||
<Text className="font-semibold">
|
|
||||||
Please update the Redirect URL for all providers being used
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
<Text className="text-sm+">
|
|
||||||
We are deprecating your project's old DNS name in favor of
|
|
||||||
individual DNS names for each service. Please make sure to update your
|
|
||||||
providers to use the new auth specific URL under <b>Redirect URL</b>{' '}
|
|
||||||
before the 1st of February 2023.{' '}
|
|
||||||
<Link
|
|
||||||
href="https://github.com/nhost/nhost/discussions/1319"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
underline="hover"
|
|
||||||
className="font-medium"
|
|
||||||
>
|
|
||||||
Read the discussion here.
|
|
||||||
<ArrowSquareOutIcon className="ml-1 h-4 w-4" />
|
|
||||||
</Link>
|
|
||||||
</Text>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Button variant="borderless" onClick={handleOpenConfirmationDialog}>
|
|
||||||
I have updated all Redirect URLs
|
|
||||||
</Button>
|
|
||||||
</Alert>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { default } from './ProvidersUpdatedAlert';
|
|
||||||
@@ -1,19 +1,35 @@
|
|||||||
import { useUI } from '@/context/UIContext';
|
|
||||||
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
||||||
import { Alert } from '@/ui/Alert';
|
import { Alert } from '@/ui/Alert';
|
||||||
import Box from '@/ui/v2/Box';
|
import Box from '@/ui/v2/Box';
|
||||||
import Button from '@/ui/v2/Button';
|
import Button from '@/ui/v2/Button';
|
||||||
import Checkbox from '@/ui/v2/Checkbox';
|
import Checkbox from '@/ui/v2/Checkbox';
|
||||||
import Text from '@/ui/v2/Text';
|
import {
|
||||||
import { useDeleteWorkspaceMutation } from '@/utils/__generated__/graphql';
|
GetAllWorkspacesAndProjectsDocument,
|
||||||
|
useDeleteWorkspaceMutation,
|
||||||
|
} from '@/utils/__generated__/graphql';
|
||||||
import { getErrorMessage } from '@/utils/getErrorMessage';
|
import { getErrorMessage } from '@/utils/getErrorMessage';
|
||||||
import { triggerToast } from '@/utils/toast';
|
import getServerError from '@/utils/settings/getServerError';
|
||||||
|
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
||||||
import router from 'next/router';
|
import router from 'next/router';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { toast } from 'react-hot-toast';
|
||||||
|
|
||||||
export default function RemoveWorkspaceModal() {
|
export interface RemoveWorkspaceModalProps {
|
||||||
|
/**
|
||||||
|
* Function to be called when the form is submitted.
|
||||||
|
*/
|
||||||
|
onSubmit?: () => Promise<void>;
|
||||||
|
/**
|
||||||
|
* Function to be called when the operation is cancelled.
|
||||||
|
*/
|
||||||
|
onCancel?: VoidFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function RemoveWorkspaceModal({
|
||||||
|
onSubmit,
|
||||||
|
onCancel,
|
||||||
|
}: RemoveWorkspaceModalProps) {
|
||||||
const [remove, setRemove] = useState(false);
|
const [remove, setRemove] = useState(false);
|
||||||
const { closeDeleteWorkspaceModal } = useUI();
|
|
||||||
|
|
||||||
const [deleteWorkspace, { loading, error: mutationError, client }] =
|
const [deleteWorkspace, { loading, error: mutationError, client }] =
|
||||||
useDeleteWorkspaceMutation();
|
useDeleteWorkspaceMutation();
|
||||||
@@ -22,66 +38,63 @@ export default function RemoveWorkspaceModal() {
|
|||||||
|
|
||||||
async function handleClick() {
|
async function handleClick() {
|
||||||
try {
|
try {
|
||||||
await deleteWorkspace({
|
await toast.promise(
|
||||||
variables: {
|
deleteWorkspace({
|
||||||
id: currentWorkspace.id,
|
variables: {
|
||||||
|
id: currentWorkspace.id,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
loading: 'Deleting workspace...',
|
||||||
|
success: `Workspace "${currentWorkspace.name}" has been deleted successfully.`,
|
||||||
|
error: getServerError(
|
||||||
|
`An error occurred while trying to delete the workspace "${currentWorkspace.name}". Please try again.`,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
});
|
getToastStyleProps(),
|
||||||
triggerToast(`Workspace ${currentWorkspace.name} successfully deleted`);
|
);
|
||||||
closeDeleteWorkspaceModal();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// TODO: Display error to user and use a logging solution
|
// TODO: Display error to user and use a logging solution
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
await onSubmit?.();
|
||||||
await router.push('/');
|
await router.push('/');
|
||||||
await client.refetchQueries({ include: ['getOneUser'] });
|
await client.refetchQueries({
|
||||||
|
include: [GetAllWorkspacesAndProjectsDocument],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box className="w-modal rounded-lg p-6 text-left">
|
<Box className="grid grid-flow-row gap-4 px-6 pt-4 pb-6">
|
||||||
<div className="grid grid-flow-row gap-4">
|
<Box className="border-y py-2">
|
||||||
<div className="grid grid-flow-row gap-1">
|
<Checkbox
|
||||||
<Text variant="h3" component="h2">
|
id="accept-remove"
|
||||||
Delete Workspace
|
label={`I'm sure I want to delete ${currentWorkspace.name}`}
|
||||||
</Text>
|
className="py-2"
|
||||||
|
checked={remove}
|
||||||
|
onChange={(_event, checked) => setRemove(checked)}
|
||||||
|
aria-label="Confirm Delete Workspace"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<Text>There is no way to recover this workspace later.</Text>
|
<div className="grid grid-flow-row gap-2">
|
||||||
</div>
|
{mutationError && (
|
||||||
|
<Alert severity="error">{getErrorMessage(mutationError)}</Alert>
|
||||||
|
)}
|
||||||
|
|
||||||
<Box className="border-y py-2">
|
<Button
|
||||||
<Checkbox
|
color="error"
|
||||||
id="accept-remove"
|
onClick={handleClick}
|
||||||
label={`I'm sure I want to delete ${currentWorkspace.name}`}
|
disabled={!remove || !!mutationError}
|
||||||
className="py-2"
|
className=""
|
||||||
checked={remove}
|
loading={loading}
|
||||||
onChange={(_event, checked) => setRemove(checked)}
|
>
|
||||||
aria-label="Confirm Delete Workspace"
|
Delete
|
||||||
/>
|
</Button>
|
||||||
</Box>
|
|
||||||
|
|
||||||
<div className="grid grid-flow-row gap-2">
|
<Button variant="outlined" color="secondary" onClick={onCancel}>
|
||||||
{mutationError && (
|
Cancel
|
||||||
<Alert severity="error">{getErrorMessage(mutationError)}</Alert>
|
</Button>
|
||||||
)}
|
|
||||||
|
|
||||||
<Button
|
|
||||||
color="error"
|
|
||||||
onClick={handleClick}
|
|
||||||
disabled={!remove || !!mutationError}
|
|
||||||
className=""
|
|
||||||
loading={loading}
|
|
||||||
>
|
|
||||||
Delete Workspace
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
color="secondary"
|
|
||||||
onClick={closeDeleteWorkspaceModal}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import { useDialog } from '@/components/common/DialogProvider';
|
import { useDialog } from '@/components/common/DialogProvider';
|
||||||
import { EditWorkspaceNameForm } from '@/components/home/EditWorkspaceNameForm';
|
import { EditWorkspaceNameForm } from '@/components/home/EditWorkspaceNameForm';
|
||||||
import RemoveWorkspaceModal from '@/components/workspace/RemoveWorkspaceModal';
|
import RemoveWorkspaceModal from '@/components/workspace/RemoveWorkspaceModal';
|
||||||
import { useUI } from '@/context/UIContext';
|
|
||||||
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
||||||
import { Avatar } from '@/ui/Avatar';
|
import { Avatar } from '@/ui/Avatar';
|
||||||
import { Modal } from '@/ui/Modal';
|
|
||||||
import Button from '@/ui/v2/Button';
|
import Button from '@/ui/v2/Button';
|
||||||
import Divider from '@/ui/v2/Divider';
|
import Divider from '@/ui/v2/Divider';
|
||||||
import { Dropdown } from '@/ui/v2/Dropdown';
|
import { Dropdown } from '@/ui/v2/Dropdown';
|
||||||
@@ -16,12 +14,6 @@ import Image from 'next/image';
|
|||||||
export default function WorkspaceHeader() {
|
export default function WorkspaceHeader() {
|
||||||
const { currentWorkspace } = useCurrentWorkspaceAndProject();
|
const { currentWorkspace } = useCurrentWorkspaceAndProject();
|
||||||
|
|
||||||
const {
|
|
||||||
openDeleteWorkspaceModal,
|
|
||||||
closeDeleteWorkspaceModal,
|
|
||||||
deleteWorkspaceModal,
|
|
||||||
} = useUI();
|
|
||||||
|
|
||||||
const { openDialog } = useDialog();
|
const { openDialog } = useDialog();
|
||||||
|
|
||||||
const user = nhost.auth.getUser();
|
const user = nhost.auth.getUser();
|
||||||
@@ -36,11 +28,6 @@ export default function WorkspaceHeader() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto flex max-w-3xl flex-col">
|
<div className="mx-auto flex max-w-3xl flex-col">
|
||||||
<Modal
|
|
||||||
showModal={deleteWorkspaceModal}
|
|
||||||
close={closeDeleteWorkspaceModal}
|
|
||||||
Component={RemoveWorkspaceModal}
|
|
||||||
/>
|
|
||||||
<div className="flex flex-row place-content-between">
|
<div className="flex flex-row place-content-between">
|
||||||
<div className="flex flex-row items-center">
|
<div className="flex flex-row items-center">
|
||||||
{IS_DEFAULT_WORKSPACE &&
|
{IS_DEFAULT_WORKSPACE &&
|
||||||
@@ -98,7 +85,7 @@ export default function WorkspaceHeader() {
|
|||||||
</Dropdown.Trigger>
|
</Dropdown.Trigger>
|
||||||
|
|
||||||
<Dropdown.Content
|
<Dropdown.Content
|
||||||
PaperProps={{ className: 'mt-1 w-[280px]' }}
|
PaperProps={{ className: 'mt-1 max-w-[280px]' }}
|
||||||
menu
|
menu
|
||||||
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
|
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
|
||||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||||
@@ -125,7 +112,7 @@ export default function WorkspaceHeader() {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Change workspace name
|
Change Workspace Name
|
||||||
</Dropdown.Item>
|
</Dropdown.Item>
|
||||||
|
|
||||||
<Divider component="li" sx={{ margin: 0 }} />
|
<Divider component="li" sx={{ margin: 0 }} />
|
||||||
@@ -133,18 +120,34 @@ export default function WorkspaceHeader() {
|
|||||||
<Dropdown.Item
|
<Dropdown.Item
|
||||||
className="grid grid-flow-row whitespace-pre-wrap py-2 font-medium"
|
className="grid grid-flow-row whitespace-pre-wrap py-2 font-medium"
|
||||||
disabled={!noApplications}
|
disabled={!noApplications}
|
||||||
onClick={openDeleteWorkspaceModal}
|
onClick={() =>
|
||||||
|
openDialog({
|
||||||
|
title: (
|
||||||
|
<span className="grid grid-flow-row">
|
||||||
|
<span>Delete Workspace</span>
|
||||||
|
|
||||||
|
<Text variant="subtitle1" component="span">
|
||||||
|
There is no way to recover this workspace later.
|
||||||
|
</Text>
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
component: <RemoveWorkspaceModal />,
|
||||||
|
props: {
|
||||||
|
titleProps: { className: '!pb-0' },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
sx={{ color: 'error.main' }}
|
sx={{ color: 'error.main' }}
|
||||||
>
|
>
|
||||||
I want to remove this workspace
|
Delete Workspace
|
||||||
{!noApplications && (
|
{!noApplications && (
|
||||||
<Text
|
<Text
|
||||||
variant="caption"
|
variant="caption"
|
||||||
className="font-medium"
|
className="font-medium"
|
||||||
color="disabled"
|
color="disabled"
|
||||||
>
|
>
|
||||||
You can't remove this workspace because you have apps
|
You can't delete this workspace because you have
|
||||||
running. Remove all apps first.
|
projects running. Delete all projects first.
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</Dropdown.Item>
|
</Dropdown.Item>
|
||||||
|
|||||||
@@ -3,11 +3,6 @@ import type { PropsWithChildren } from 'react';
|
|||||||
import { createContext, useContext, useMemo, useReducer } from 'react';
|
import { createContext, useContext, useMemo, useReducer } from 'react';
|
||||||
|
|
||||||
export interface UIContextState {
|
export interface UIContextState {
|
||||||
newWorkspace: boolean;
|
|
||||||
modal: boolean;
|
|
||||||
deleteApplicationModal: boolean;
|
|
||||||
deleteWorkspaceModal: boolean;
|
|
||||||
resourcesCollapsible: boolean;
|
|
||||||
paymentModal: boolean;
|
paymentModal: boolean;
|
||||||
/**
|
/**
|
||||||
* Determines whether or not the dashboard is in maintenance mode.
|
* Determines whether or not the dashboard is in maintenance mode.
|
||||||
@@ -19,23 +14,14 @@ export interface UIContextState {
|
|||||||
maintenanceEndDate: Date;
|
maintenanceEndDate: Date;
|
||||||
openPaymentModal: () => void;
|
openPaymentModal: () => void;
|
||||||
closePaymentModal: () => void;
|
closePaymentModal: () => void;
|
||||||
openDeleteWorkspaceModal: () => void;
|
|
||||||
closeDeleteWorkspaceModal: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: UIContextState = {
|
const initialState: UIContextState = {
|
||||||
newWorkspace: false,
|
|
||||||
modal: false,
|
|
||||||
deleteApplicationModal: false,
|
|
||||||
deleteWorkspaceModal: false,
|
|
||||||
resourcesCollapsible: true,
|
|
||||||
paymentModal: false,
|
paymentModal: false,
|
||||||
maintenanceActive: false,
|
maintenanceActive: false,
|
||||||
maintenanceEndDate: null,
|
maintenanceEndDate: null,
|
||||||
openPaymentModal: () => {},
|
openPaymentModal: () => {},
|
||||||
closePaymentModal: () => {},
|
closePaymentModal: () => {},
|
||||||
openDeleteWorkspaceModal: () => {},
|
|
||||||
closeDeleteWorkspaceModal: () => {},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UIContext = createContext<UIContextState>(initialState);
|
export const UIContext = createContext<UIContextState>(initialState);
|
||||||
@@ -44,12 +30,6 @@ UIContext.displayName = 'UIContext';
|
|||||||
|
|
||||||
function sideReducer(state: any, action: any) {
|
function sideReducer(state: any, action: any) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'TOGGLE_DELETE_WORKSPACE_MODAL': {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
deleteWorkspaceModal: !state.deleteWorkspaceModal,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case 'TOGGLE_PAYMENT_MODAL': {
|
case 'TOGGLE_PAYMENT_MODAL': {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
@@ -67,10 +47,6 @@ export function UIProvider(props: PropsWithChildren<unknown>) {
|
|||||||
|
|
||||||
const openPaymentModal = () => dispatch({ type: 'TOGGLE_PAYMENT_MODAL' });
|
const openPaymentModal = () => dispatch({ type: 'TOGGLE_PAYMENT_MODAL' });
|
||||||
const closePaymentModal = () => dispatch({ type: 'TOGGLE_PAYMENT_MODAL' });
|
const closePaymentModal = () => dispatch({ type: 'TOGGLE_PAYMENT_MODAL' });
|
||||||
const openDeleteWorkspaceModal = () =>
|
|
||||||
dispatch({ type: 'TOGGLE_DELETE_WORKSPACE_MODAL' });
|
|
||||||
const closeDeleteWorkspaceModal = () =>
|
|
||||||
dispatch({ type: 'TOGGLE_DELETE_WORKSPACE_MODAL' });
|
|
||||||
|
|
||||||
const maintenanceUnlocked =
|
const maintenanceUnlocked =
|
||||||
process.env.NEXT_PUBLIC_MAINTENANCE_UNLOCK_SECRET &&
|
process.env.NEXT_PUBLIC_MAINTENANCE_UNLOCK_SECRET &&
|
||||||
@@ -80,8 +56,6 @@ export function UIProvider(props: PropsWithChildren<unknown>) {
|
|||||||
const value: UIContextState = useMemo(
|
const value: UIContextState = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
...state,
|
...state,
|
||||||
openDeleteWorkspaceModal,
|
|
||||||
closeDeleteWorkspaceModal,
|
|
||||||
openPaymentModal,
|
openPaymentModal,
|
||||||
closePaymentModal,
|
closePaymentModal,
|
||||||
maintenanceActive: maintenanceUnlocked
|
maintenanceActive: maintenanceUnlocked
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
import type { Workspace } from '@/types/workspace';
|
|
||||||
import type { PropsWithChildren } from 'react';
|
|
||||||
import { createContext, useContext, useMemo, useState } from 'react';
|
|
||||||
|
|
||||||
type Metadata = {
|
|
||||||
lastWorkspace: string;
|
|
||||||
template?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type UserContextData = {
|
|
||||||
workspaces: Workspace[];
|
|
||||||
metadata?: Metadata;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type UserDataContent = {
|
|
||||||
userContext: UserContextData;
|
|
||||||
setUserContext: (d: UserContextData) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const UserDataContext = createContext<UserDataContent>({
|
|
||||||
userContext: {
|
|
||||||
workspaces: [],
|
|
||||||
metadata: { lastWorkspace: '' },
|
|
||||||
},
|
|
||||||
setUserContext: () => {},
|
|
||||||
});
|
|
||||||
|
|
||||||
export interface UserDataProviderProps {
|
|
||||||
/**
|
|
||||||
* Initial workspaces to be used in the context.
|
|
||||||
*/
|
|
||||||
initialWorkspaces?: Workspace[];
|
|
||||||
/**
|
|
||||||
* Initial metadata to be used in the context.
|
|
||||||
*/
|
|
||||||
initialMetadata?: Record<string, any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function UserDataProvider({
|
|
||||||
children,
|
|
||||||
initialWorkspaces,
|
|
||||||
initialMetadata,
|
|
||||||
}: PropsWithChildren<UserDataProviderProps>) {
|
|
||||||
const [userContext, setUserContext] = useState({
|
|
||||||
workspaces: initialWorkspaces || [],
|
|
||||||
metadata: initialMetadata || {},
|
|
||||||
});
|
|
||||||
|
|
||||||
const value = useMemo(
|
|
||||||
() => ({ userContext, setUserContext }),
|
|
||||||
[userContext, setUserContext],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
// @ts-ignore
|
|
||||||
<UserDataContext.Provider value={value}>
|
|
||||||
{children}
|
|
||||||
</UserDataContext.Provider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useUserDataContext = () => {
|
|
||||||
const context = useContext(UserDataContext);
|
|
||||||
|
|
||||||
if (context === undefined) {
|
|
||||||
throw new Error(`useUserDataContext must be used under a UserDataProvider`);
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
};
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
query getAllAppsWhere($where: apps_bool_exp!) {
|
|
||||||
apps(where: $where) {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
slug
|
|
||||||
workspace {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
slug
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
fragment GetAppByWorkspaceAndName on apps {
|
|
||||||
updatedAt
|
|
||||||
id
|
|
||||||
slug
|
|
||||||
subdomain
|
|
||||||
name
|
|
||||||
createdAt
|
|
||||||
isProvisioned
|
|
||||||
providersUpdated
|
|
||||||
githubRepository {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
githubAppInstallation {
|
|
||||||
id
|
|
||||||
accountLogin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
repositoryProductionBranch
|
|
||||||
githubRepositoryId
|
|
||||||
region {
|
|
||||||
countryCode
|
|
||||||
city
|
|
||||||
}
|
|
||||||
workspace {
|
|
||||||
name
|
|
||||||
slug
|
|
||||||
id
|
|
||||||
}
|
|
||||||
workspaceId
|
|
||||||
config(resolve: true) {
|
|
||||||
hasura {
|
|
||||||
adminSecret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
query getAppByWorkspaceAndName($workspace: String!, $slug: String!) {
|
|
||||||
apps(
|
|
||||||
where: { workspace: { slug: { _eq: $workspace } }, slug: { _eq: $slug } }
|
|
||||||
) {
|
|
||||||
...GetAppByWorkspaceAndName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
query getApps {
|
|
||||||
apps(order_by: { createdAt: desc }) {
|
|
||||||
id
|
|
||||||
slug
|
|
||||||
name
|
|
||||||
subdomain
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
query getAppProvisionStatus($workspace: String!, $slug: String!) {
|
|
||||||
apps(
|
|
||||||
where: { workspace: { slug: { _eq: $workspace } }, slug: { _eq: $slug } }
|
|
||||||
) {
|
|
||||||
id
|
|
||||||
isProvisioned
|
|
||||||
subdomain
|
|
||||||
createdAt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
mutation updateApp($id: uuid!, $app: apps_set_input!) {
|
|
||||||
updateApp(pk_columns: { id: $id }, _set: $app) {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,17 +9,6 @@ fragment DeploymentRow on deployments {
|
|||||||
commitMessage
|
commitMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
query getDeployments($id: uuid!, $limit: Int!, $offset: Int!) {
|
|
||||||
deployments(
|
|
||||||
where: { appId: { _eq: $id } }
|
|
||||||
order_by: { deploymentStartedAt: desc }
|
|
||||||
limit: $limit
|
|
||||||
offset: $offset
|
|
||||||
) {
|
|
||||||
...DeploymentRow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
subscription ScheduledOrPendingDeploymentsSub($appId: uuid!) {
|
subscription ScheduledOrPendingDeploymentsSub($appId: uuid!) {
|
||||||
deployments(
|
deployments(
|
||||||
where: { deploymentStatus: { _in: ["SCHEDULED"] }, appId: { _eq: $appId } }
|
where: { deploymentStatus: { _in: ["SCHEDULED"] }, appId: { _eq: $appId } }
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
mutation insertFeatureFlag($flag: featureFlags_insert_input!) {
|
|
||||||
insertFeatureFlag(object: $flag){
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
mutation deleteFiles($fileIds: [uuid!]!) {
|
|
||||||
deleteFiles(where: { id: { _in: $fileIds } }) {
|
|
||||||
affected_rows
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
mutation changePaymentMethod(
|
|
||||||
$workspaceId: uuid!
|
|
||||||
$paymentMethod: paymentMethods_insert_input!
|
|
||||||
) {
|
|
||||||
# delete all cards on the current workspace
|
|
||||||
deletePaymentMethods(where: { workspaceId: { _eq: $workspaceId } }) {
|
|
||||||
affected_rows
|
|
||||||
}
|
|
||||||
# add new
|
|
||||||
insertPaymentMethod(object: $paymentMethod) {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
query getPlans {
|
|
||||||
plans(order_by: { sort: asc }) {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
isFree
|
|
||||||
price
|
|
||||||
isDefault
|
|
||||||
}
|
|
||||||
regions {
|
|
||||||
id
|
|
||||||
isGdprCompliant
|
|
||||||
city
|
|
||||||
country {
|
|
||||||
name
|
|
||||||
continent {
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
workspaces {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
slug
|
|
||||||
paymentMethods {
|
|
||||||
id
|
|
||||||
cardBrand
|
|
||||||
cardLast4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
query getRemoteAppFilesUsage {
|
|
||||||
filesAggregate {
|
|
||||||
aggregate {
|
|
||||||
count
|
|
||||||
sum {
|
|
||||||
size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
fragment GetRemoteAppUser on users {
|
|
||||||
id
|
|
||||||
createdAt
|
|
||||||
displayName
|
|
||||||
locale
|
|
||||||
avatarUrl
|
|
||||||
email
|
|
||||||
emailVerified
|
|
||||||
passwordHash
|
|
||||||
locale
|
|
||||||
disabled
|
|
||||||
phoneNumber
|
|
||||||
phoneNumberVerified
|
|
||||||
defaultRole
|
|
||||||
roles {
|
|
||||||
role
|
|
||||||
}
|
|
||||||
userProviders {
|
|
||||||
id
|
|
||||||
provider {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment GetRemoteAppUserAuthRoles on authRoles {
|
|
||||||
role
|
|
||||||
}
|
|
||||||
|
|
||||||
query getRemoteAppUser($id: uuid!) {
|
|
||||||
user(id: $id) {
|
|
||||||
...GetRemoteAppUser
|
|
||||||
}
|
|
||||||
authRoles {
|
|
||||||
role
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
query getRemoteAppUserWhere($where: users_bool_exp!) {
|
|
||||||
users(where: $where) {
|
|
||||||
id
|
|
||||||
displayName
|
|
||||||
email
|
|
||||||
defaultRole
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
query getRemoteAppById($id: uuid!) {
|
|
||||||
user(id: $id) {
|
|
||||||
id
|
|
||||||
displayName
|
|
||||||
email
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
mutation confirmProvidersUpdated($id: uuid!) {
|
|
||||||
updateApp(pk_columns: { id: $id }, _set: { providersUpdated: true }) {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
query getAllUserData {
|
|
||||||
workspaceMembers {
|
|
||||||
id
|
|
||||||
workspace {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
creatorUserId
|
|
||||||
apps {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
subdomain
|
|
||||||
config(resolve: true) {
|
|
||||||
hasura {
|
|
||||||
adminSecret
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
query GetAvatar($userId: uuid!) {
|
|
||||||
user(id: $userId) {
|
|
||||||
id
|
|
||||||
avatarUrl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
query getOneUser($userId: uuid!) {
|
|
||||||
user(id: $userId) {
|
|
||||||
id
|
|
||||||
displayName
|
|
||||||
avatarUrl
|
|
||||||
workspaceMembers {
|
|
||||||
id
|
|
||||||
userId
|
|
||||||
workspaceId
|
|
||||||
type
|
|
||||||
workspace {
|
|
||||||
creatorUserId
|
|
||||||
id
|
|
||||||
slug
|
|
||||||
name
|
|
||||||
apps {
|
|
||||||
...Project
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
query getUserAllWorkspaces {
|
|
||||||
workspaceMembers {
|
|
||||||
id
|
|
||||||
userId
|
|
||||||
workspace {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
slug
|
|
||||||
apps {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
plan {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
}
|
|
||||||
slug
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
query getAppsByWorkspace($workspace_id: uuid!) {
|
|
||||||
workspace(id: $workspace_id) {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
slug
|
|
||||||
apps {
|
|
||||||
name
|
|
||||||
plan {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
query getWorkspaceInvoices($id: uuid!) {
|
|
||||||
workspace(id: $id) {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
query getWorkspaceSettings($id: uuid!) {
|
|
||||||
workspace(id: $id) {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
addressLine1
|
|
||||||
addressLine2
|
|
||||||
addressPostalCode
|
|
||||||
addressPostalCode
|
|
||||||
addressCity
|
|
||||||
addressState
|
|
||||||
addressCountryCode
|
|
||||||
companyName
|
|
||||||
email
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
fragment GetWorkspace on workspaces {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
email
|
|
||||||
companyName
|
|
||||||
addressLine1
|
|
||||||
addressLine2
|
|
||||||
addressPostalCode
|
|
||||||
addressCity
|
|
||||||
addressCountryCode
|
|
||||||
slug
|
|
||||||
taxIdType
|
|
||||||
taxIdValue
|
|
||||||
apps {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
slug
|
|
||||||
createdAt
|
|
||||||
workspace {
|
|
||||||
id
|
|
||||||
slug
|
|
||||||
}
|
|
||||||
}
|
|
||||||
paymentMethods {
|
|
||||||
id
|
|
||||||
cardBrand
|
|
||||||
cardLast4
|
|
||||||
stripePaymentMethodId
|
|
||||||
}
|
|
||||||
workspaceMembers {
|
|
||||||
id
|
|
||||||
user {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
query getWorkspace($id: uuid!) {
|
|
||||||
workspace(id: $id) {
|
|
||||||
...GetWorkspace
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
query getWorkspaceWhere($where: workspaces_bool_exp!) {
|
|
||||||
workspaces(where: $where) {
|
|
||||||
...GetWorkspace
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
query GetWorkspacesAppsById($workspaceId: uuid!) {
|
|
||||||
workspace(id: $workspaceId) {
|
|
||||||
id
|
|
||||||
slug
|
|
||||||
apps {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
slug
|
|
||||||
updatedAt
|
|
||||||
plan {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
query getWorkspaces {
|
|
||||||
workspaces(order_by: { name: asc }) {
|
|
||||||
id
|
|
||||||
createdAt
|
|
||||||
name
|
|
||||||
slug
|
|
||||||
creatorUserId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,10 @@ import type {
|
|||||||
GetApplicationStateQuery,
|
GetApplicationStateQuery,
|
||||||
GetApplicationStateQueryVariables,
|
GetApplicationStateQueryVariables,
|
||||||
} from '@/utils/__generated__/graphql';
|
} from '@/utils/__generated__/graphql';
|
||||||
import { useGetApplicationStateQuery } from '@/utils/__generated__/graphql';
|
import {
|
||||||
|
GetAllWorkspacesAndProjectsDocument,
|
||||||
|
useGetApplicationStateQuery,
|
||||||
|
} from '@/utils/__generated__/graphql';
|
||||||
import type { QueryHookOptions } from '@apollo/client';
|
import type { QueryHookOptions } from '@apollo/client';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
@@ -31,7 +34,7 @@ export default function useProjectRedirectWhenReady(
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function updateOwnCache() {
|
async function updateOwnCache() {
|
||||||
await client.refetchQueries({
|
await client.refetchQueries({
|
||||||
include: ['getOneUser'],
|
include: [GetAllWorkspacesAndProjectsDocument],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
import { useGetUserAllWorkspacesQuery } from '@/utils/__generated__/graphql';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
|
|
||||||
function checkForApplicationsOnAllWorkspaces(workspaces, setNoApplications) {
|
|
||||||
let noApplications = true;
|
|
||||||
|
|
||||||
workspaces.forEach(({ workspace }) => {
|
|
||||||
if (noApplications && workspace.apps.length !== 0) {
|
|
||||||
noApplications = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
setNoApplications(noApplications);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useCheckApplications() {
|
|
||||||
const { data, loading, error } = useGetUserAllWorkspacesQuery();
|
|
||||||
const [noApplications, setNoApplications] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { workspaceMembers } = data;
|
|
||||||
const noWorkspaces = workspaceMembers?.length === 0;
|
|
||||||
|
|
||||||
if (noWorkspaces) {
|
|
||||||
setNoApplications(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
checkForApplicationsOnAllWorkspaces(workspaceMembers, setNoApplications);
|
|
||||||
}, [data, loading, noApplications, setNoApplications]);
|
|
||||||
|
|
||||||
return { data, loading, error, noApplications };
|
|
||||||
}
|
|
||||||
|
|
||||||
export default useCheckApplications;
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
GetAllWorkspacesAndProjectsDocument,
|
GetAllWorkspacesAndProjectsDocument,
|
||||||
GetOneUserDocument,
|
|
||||||
useGetApplicationStateQuery,
|
useGetApplicationStateQuery,
|
||||||
} from '@/generated/graphql';
|
} from '@/generated/graphql';
|
||||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||||
@@ -21,33 +20,33 @@ type ApplicationStateMetadata = {
|
|||||||
* it will update the entire cache with the application state.
|
* it will update the entire cache with the application state.
|
||||||
*/
|
*/
|
||||||
export function useCheckProvisioning() {
|
export function useCheckProvisioning() {
|
||||||
const { currentWorkspace } = useCurrentWorkspaceAndProject();
|
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||||
const [currentApplicationState, setCurrentApplicationState] =
|
const [currentApplicationState, setCurrentApplicationState] =
|
||||||
useState<ApplicationStateMetadata>({ state: ApplicationStatus.Empty });
|
useState<ApplicationStateMetadata>({ state: ApplicationStatus.Empty });
|
||||||
const isPlatform = useIsPlatform();
|
const isPlatform = useIsPlatform();
|
||||||
|
|
||||||
const { data, startPolling, stopPolling, client } =
|
const { data, startPolling, stopPolling, client } =
|
||||||
useGetApplicationStateQuery({
|
useGetApplicationStateQuery({
|
||||||
variables: { appId: currentWorkspace?.id },
|
variables: { appId: currentProject?.id },
|
||||||
skip: !isPlatform || !currentWorkspace?.id,
|
skip: !isPlatform || !currentProject?.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
async function updateOwnCache() {
|
async function updateOwnCache() {
|
||||||
await client.refetchQueries({
|
await client.refetchQueries({
|
||||||
include: [GetOneUserDocument, GetAllWorkspacesAndProjectsDocument],
|
include: [GetAllWorkspacesAndProjectsDocument],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const memoizedUpdateCache = useCallback(updateOwnCache, [client]);
|
const memoizedUpdateCache = useCallback(updateOwnCache, [client]);
|
||||||
|
|
||||||
const currentApplicationId = currentWorkspace?.id;
|
const currentApplicationId = currentProject?.id;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
startPolling(2000);
|
startPolling(2000);
|
||||||
}, [startPolling]);
|
}, [startPolling]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!data) {
|
if (!data?.app) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
import { useUserDataContext } from '@/context/UserDataContext';
|
|
||||||
import { useGetOneUserLazyQuery } from '@/generated/graphql';
|
|
||||||
import type { Workspace } from '@/types/workspace';
|
|
||||||
import { nhost } from '@/utils/nhost';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import useIsPlatform from './common/useIsPlatform';
|
|
||||||
import { useWithin } from './useWithin';
|
|
||||||
|
|
||||||
export type UserData = {
|
|
||||||
workspaces: Workspace[] | [];
|
|
||||||
};
|
|
||||||
|
|
||||||
export function useGetAllUserWorkspacesAndApplications(
|
|
||||||
fromState: boolean = false,
|
|
||||||
) {
|
|
||||||
const { userContext, setUserContext } = useUserDataContext();
|
|
||||||
const [userData, setUserData] = useState<UserData | null>(null);
|
|
||||||
const isPlatform = useIsPlatform();
|
|
||||||
const { within } = useWithin();
|
|
||||||
|
|
||||||
const user = nhost.auth.getUser();
|
|
||||||
|
|
||||||
const [getAllUserData, { loading, data, called }] = useGetOneUserLazyQuery({
|
|
||||||
variables: {
|
|
||||||
userId: user?.id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (data || !isPlatform) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
getAllUserData();
|
|
||||||
}, [data, isPlatform, getAllUserData]);
|
|
||||||
|
|
||||||
// TODO: This useEffect should be broken down into multiple smaller parts
|
|
||||||
// because dependency array is not expandable with the necessary dependencies
|
|
||||||
// in its current form.
|
|
||||||
useEffect(() => {
|
|
||||||
if (data && userData && userData.workspaces.length !== 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (within && !data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
within &&
|
|
||||||
data &&
|
|
||||||
data.user?.workspaceMembers &&
|
|
||||||
data.user?.workspaceMembers.length === 0
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
data?.user?.workspaceMembers &&
|
|
||||||
data?.user?.workspaceMembers.length !== 0
|
|
||||||
) {
|
|
||||||
const workspaces = data.user.workspaceMembers.map(({ workspace }) => {
|
|
||||||
// note: this could be rather defined by the infrastructure when
|
|
||||||
// creating the initial workspace
|
|
||||||
const isDefaultWorkspace =
|
|
||||||
workspace.name.toLowerCase() === 'default workspace' &&
|
|
||||||
workspace.creatorUserId === user?.id &&
|
|
||||||
/default-workspace-[a-z]+/i.test(workspace.slug);
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: workspace.id,
|
|
||||||
name: workspace.name,
|
|
||||||
slug: workspace.slug,
|
|
||||||
creatorUserId: workspace.creatorUserId,
|
|
||||||
default: isDefaultWorkspace,
|
|
||||||
members: data.user.workspaceMembers.filter(
|
|
||||||
({ workspaceId }) => workspaceId === workspace.id,
|
|
||||||
),
|
|
||||||
applications: workspace.apps.map((app) => {
|
|
||||||
const userContextAppProps: any = {
|
|
||||||
users: 0,
|
|
||||||
userMetrics: {
|
|
||||||
growth: 0,
|
|
||||||
difference: 0,
|
|
||||||
growthPercentage: 0,
|
|
||||||
totalUsers: 0,
|
|
||||||
},
|
|
||||||
dbSize: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (userContext.workspaces?.length > 0) {
|
|
||||||
const currentWorkspace = userContext.workspaces.find(
|
|
||||||
(x) => x.id === workspace.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
const currentApp = currentWorkspace?.applications.find(
|
|
||||||
(x) => x.id === app.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (currentWorkspace && currentApp) {
|
|
||||||
return {
|
|
||||||
...app,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
...app,
|
|
||||||
...userContextAppProps,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
} as Workspace;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (fromState) {
|
|
||||||
setUserData({ workspaces });
|
|
||||||
} else {
|
|
||||||
setUserContext({ workspaces, metadata: userContext.metadata });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [data, setUserData, called]);
|
|
||||||
|
|
||||||
return { userData, setUserData, getAllUserData, loading, data, called };
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import { useApolloClient } from '@apollo/client';
|
|
||||||
|
|
||||||
export function useLazyRefetchUserData() {
|
|
||||||
const client = useApolloClient();
|
|
||||||
|
|
||||||
const refetchUserData = async () => {
|
|
||||||
await client.refetchQueries({
|
|
||||||
include: ['getOneUser'],
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return { refetchUserData };
|
|
||||||
}
|
|
||||||
|
|
||||||
export default useLazyRefetchUserData;
|
|
||||||
@@ -24,6 +24,10 @@ export interface UseCurrentWorkspaceAndProjectReturnType {
|
|||||||
* The error if any.
|
* The error if any.
|
||||||
*/
|
*/
|
||||||
error?: Error;
|
error?: Error;
|
||||||
|
/**
|
||||||
|
* Refetch the query.
|
||||||
|
*/
|
||||||
|
refetch: (options?: any) => Promise<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function useCurrentWorkspaceAndProject(): UseCurrentWorkspaceAndProjectReturnType {
|
export default function useCurrentWorkspaceAndProject(): UseCurrentWorkspaceAndProjectReturnType {
|
||||||
@@ -39,7 +43,11 @@ export default function useCurrentWorkspaceAndProject(): UseCurrentWorkspaceAndP
|
|||||||
// We can't use the hook exported by the codegen here because there are cases
|
// We can't use the hook exported by the codegen here because there are cases
|
||||||
// where it doesn't target the Nhost backend, but the currently active project
|
// where it doesn't target the Nhost backend, but the currently active project
|
||||||
// instead.
|
// instead.
|
||||||
const { data: response, isFetching } = useQuery(
|
const {
|
||||||
|
data: response,
|
||||||
|
isFetching,
|
||||||
|
refetch,
|
||||||
|
} = useQuery(
|
||||||
['currentWorkspaceAndProject', workspaceSlug, appSlug],
|
['currentWorkspaceAndProject', workspaceSlug, appSlug],
|
||||||
() =>
|
() =>
|
||||||
client.graphql.request<{
|
client.graphql.request<{
|
||||||
@@ -105,6 +113,7 @@ export default function useCurrentWorkspaceAndProject(): UseCurrentWorkspaceAndP
|
|||||||
},
|
},
|
||||||
currentProject: localProject,
|
currentProject: localProject,
|
||||||
loading: false,
|
loading: false,
|
||||||
|
refetch: () => Promise.resolve(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,5 +131,6 @@ export default function useCurrentWorkspaceAndProject(): UseCurrentWorkspaceAndP
|
|||||||
error: response?.error
|
error: response?.error
|
||||||
? new Error(error?.message || 'Unknown error occurred.')
|
? new Error(error?.message || 'Unknown error occurred.')
|
||||||
: null,
|
: null,
|
||||||
|
refetch,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export default function AppIndexPage() {
|
|||||||
return <ApplicationLive />;
|
return <ApplicationLive />;
|
||||||
case ApplicationStatus.Errored:
|
case ApplicationStatus.Errored:
|
||||||
return <ApplicationErrored />;
|
return <ApplicationErrored />;
|
||||||
|
case ApplicationStatus.Pausing:
|
||||||
case ApplicationStatus.Paused:
|
case ApplicationStatus.Paused:
|
||||||
return <ApplicationPaused />;
|
return <ApplicationPaused />;
|
||||||
case ApplicationStatus.Unpausing:
|
case ApplicationStatus.Unpausing:
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import SettingsLayout from '@/components/settings/SettingsLayout';
|
|||||||
import { useUI } from '@/context/UIContext';
|
import { useUI } from '@/context/UIContext';
|
||||||
import {
|
import {
|
||||||
GetAllWorkspacesAndProjectsDocument,
|
GetAllWorkspacesAndProjectsDocument,
|
||||||
GetOneUserDocument,
|
|
||||||
useDeleteApplicationMutation,
|
useDeleteApplicationMutation,
|
||||||
usePauseApplicationMutation,
|
usePauseApplicationMutation,
|
||||||
useUpdateApplicationMutation,
|
useUpdateApplicationMutation,
|
||||||
@@ -44,11 +43,11 @@ export default function SettingsGeneralPage() {
|
|||||||
const client = useApolloClient();
|
const client = useApolloClient();
|
||||||
const [pauseApplication] = usePauseApplicationMutation({
|
const [pauseApplication] = usePauseApplicationMutation({
|
||||||
variables: { appId: currentProject?.id },
|
variables: { appId: currentProject?.id },
|
||||||
refetchQueries: [GetOneUserDocument],
|
refetchQueries: [GetAllWorkspacesAndProjectsDocument],
|
||||||
});
|
});
|
||||||
const [deleteApplication] = useDeleteApplicationMutation({
|
const [deleteApplication] = useDeleteApplicationMutation({
|
||||||
variables: { appId: currentProject?.id },
|
variables: { appId: currentProject?.id },
|
||||||
refetchQueries: [GetOneUserDocument],
|
refetchQueries: [GetAllWorkspacesAndProjectsDocument],
|
||||||
});
|
});
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { maintenanceActive } = useUI();
|
const { maintenanceActive } = useUI();
|
||||||
@@ -118,7 +117,7 @@ export default function SettingsGeneralPage() {
|
|||||||
`/${currentWorkspace.slug}/${newProjectSlug}/settings/general`,
|
`/${currentWorkspace.slug}/${newProjectSlug}/settings/general`,
|
||||||
);
|
);
|
||||||
await client.refetchQueries({
|
await client.refetchQueries({
|
||||||
include: [GetOneUserDocument, GetAllWorkspacesAndProjectsDocument],
|
include: [GetAllWorkspacesAndProjectsDocument],
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await discordAnnounce(
|
await discordAnnounce(
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import DeploymentBranchSettings from '@/components/settings/git/DeploymentBranch
|
|||||||
import SettingsContainer from '@/components/settings/SettingsContainer';
|
import SettingsContainer from '@/components/settings/SettingsContainer';
|
||||||
import SettingsLayout from '@/components/settings/SettingsLayout';
|
import SettingsLayout from '@/components/settings/SettingsLayout';
|
||||||
import { useUI } from '@/context/UIContext';
|
import { useUI } from '@/context/UIContext';
|
||||||
import { useUpdateAppMutation } from '@/generated/graphql';
|
import { useUpdateApplicationMutation } from '@/generated/graphql';
|
||||||
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
||||||
import Box from '@/ui/v2/Box';
|
import Box from '@/ui/v2/Box';
|
||||||
import Button from '@/ui/v2/Button';
|
import Button from '@/ui/v2/Button';
|
||||||
@@ -24,7 +24,7 @@ export default function SettingsGitPage() {
|
|||||||
const { openAlertDialog } = useDialog();
|
const { openAlertDialog } = useDialog();
|
||||||
const client = useApolloClient();
|
const client = useApolloClient();
|
||||||
|
|
||||||
const [updateApp] = useUpdateAppMutation();
|
const [updateApp] = useUpdateApplicationMutation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
@@ -73,7 +73,7 @@ export default function SettingsGitPage() {
|
|||||||
onPrimaryAction: async () => {
|
onPrimaryAction: async () => {
|
||||||
await updateApp({
|
await updateApp({
|
||||||
variables: {
|
variables: {
|
||||||
id: currentProject.id,
|
appId: currentProject.id,
|
||||||
app: {
|
app: {
|
||||||
githubRepositoryId: null,
|
githubRepositoryId: null,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import GitHubProviderSettings from '@/components/settings/signInMethods/GitHubPr
|
|||||||
import GoogleProviderSettings from '@/components/settings/signInMethods/GoogleProviderSettings';
|
import GoogleProviderSettings from '@/components/settings/signInMethods/GoogleProviderSettings';
|
||||||
import LinkedInProviderSettings from '@/components/settings/signInMethods/LinkedInProviderSettings';
|
import LinkedInProviderSettings from '@/components/settings/signInMethods/LinkedInProviderSettings';
|
||||||
import MagicLinkSettings from '@/components/settings/signInMethods/MagicLinkSettings';
|
import MagicLinkSettings from '@/components/settings/signInMethods/MagicLinkSettings';
|
||||||
import ProvidersUpdatedAlert from '@/components/settings/signInMethods/ProvidersUpdatedAlert';
|
|
||||||
import SMSSettings from '@/components/settings/signInMethods/SMSSettings';
|
import SMSSettings from '@/components/settings/signInMethods/SMSSettings';
|
||||||
import SpotifyProviderSettings from '@/components/settings/signInMethods/SpotifyProviderSettings';
|
import SpotifyProviderSettings from '@/components/settings/signInMethods/SpotifyProviderSettings';
|
||||||
import TwitchProviderSettings from '@/components/settings/signInMethods/TwitchProviderSettings';
|
import TwitchProviderSettings from '@/components/settings/signInMethods/TwitchProviderSettings';
|
||||||
@@ -55,7 +54,6 @@ export default function SettingsSignInMethodsPage() {
|
|||||||
<WebAuthnSettings />
|
<WebAuthnSettings />
|
||||||
<AnonymousSignInSettings />
|
<AnonymousSignInSettings />
|
||||||
<SMSSettings />
|
<SMSSettings />
|
||||||
{!currentProject.providersUpdated && <ProvidersUpdatedAlert />}
|
|
||||||
<AppleProviderSettings />
|
<AppleProviderSettings />
|
||||||
<AzureADProviderSettings />
|
<AzureADProviderSettings />
|
||||||
<DiscordProviderSettings />
|
<DiscordProviderSettings />
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import {
|
|||||||
} from '@/components/workspace';
|
} from '@/components/workspace';
|
||||||
import { WorkspaceInvoices } from '@/components/workspace/WorkspaceInvoices';
|
import { WorkspaceInvoices } from '@/components/workspace/WorkspaceInvoices';
|
||||||
import WorkspacePaymentMethods from '@/components/workspace/WorkspacePaymentMethods';
|
import WorkspacePaymentMethods from '@/components/workspace/WorkspacePaymentMethods';
|
||||||
import { useGetAllUserWorkspacesAndApplications } from '@/hooks/useGetAllUserWorkspacesAndApplications';
|
|
||||||
import useNotFoundRedirect from '@/hooks/useNotFoundRedirect';
|
import useNotFoundRedirect from '@/hooks/useNotFoundRedirect';
|
||||||
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
import { useCurrentWorkspaceAndProject } from '@/hooks/v2/useCurrentWorkspaceAndProject';
|
||||||
import { NextSeo } from 'next-seo';
|
import { NextSeo } from 'next-seo';
|
||||||
@@ -17,7 +16,6 @@ import type { ReactElement } from 'react';
|
|||||||
export default function WorkspaceDetailsPage() {
|
export default function WorkspaceDetailsPage() {
|
||||||
const { currentWorkspace, loading } = useCurrentWorkspaceAndProject();
|
const { currentWorkspace, loading } = useCurrentWorkspaceAndProject();
|
||||||
|
|
||||||
useGetAllUserWorkspacesAndApplications(false);
|
|
||||||
useNotFoundRedirect();
|
useNotFoundRedirect();
|
||||||
|
|
||||||
if (!currentWorkspace || loading) {
|
if (!currentWorkspace || loading) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import DialogProvider from '@/components/common/DialogProvider/DialogProvider';
|
import { DialogProvider } from '@/components/common/DialogProvider';
|
||||||
import ErrorBoundaryFallback from '@/components/common/ErrorBoundaryFallback';
|
import ErrorBoundaryFallback from '@/components/common/ErrorBoundaryFallback';
|
||||||
import { ManagedUIContext } from '@/context/UIContext';
|
import { ManagedUIContext } from '@/context/UIContext';
|
||||||
import { UserDataProvider } from '@/context/UserDataContext';
|
|
||||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||||
import '@/styles/fonts.css';
|
import '@/styles/fonts.css';
|
||||||
import '@/styles/globals.css';
|
import '@/styles/globals.css';
|
||||||
@@ -93,26 +92,24 @@ function MyApp({
|
|||||||
nhost={nhost}
|
nhost={nhost}
|
||||||
connectToDevTools={process.env.NEXT_PUBLIC_ENV === 'dev'}
|
connectToDevTools={process.env.NEXT_PUBLIC_ENV === 'dev'}
|
||||||
>
|
>
|
||||||
<UserDataProvider>
|
<ManagedUIContext>
|
||||||
<ManagedUIContext>
|
<Toaster position="bottom-center" />
|
||||||
<Toaster position="bottom-center" />
|
|
||||||
|
|
||||||
{isPlatform && (
|
{isPlatform && (
|
||||||
<Script
|
<Script
|
||||||
id="segment"
|
id="segment"
|
||||||
dangerouslySetInnerHTML={{ __html: renderSnippet() }}
|
dangerouslySetInnerHTML={{ __html: renderSnippet() }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<ThemeProvider
|
<ThemeProvider
|
||||||
colorPreferenceStorageKey={COLOR_PREFERENCE_STORAGE_KEY}
|
colorPreferenceStorageKey={COLOR_PREFERENCE_STORAGE_KEY}
|
||||||
>
|
>
|
||||||
<DialogProvider>
|
<DialogProvider>
|
||||||
{getLayout(<Component {...pageProps} />)}
|
{getLayout(<Component {...pageProps} />)}
|
||||||
</DialogProvider>
|
</DialogProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</ManagedUIContext>
|
</ManagedUIContext>
|
||||||
</UserDataProvider>
|
|
||||||
</NhostApolloProvider>
|
</NhostApolloProvider>
|
||||||
</NhostProvider>
|
</NhostProvider>
|
||||||
</CacheProvider>
|
</CacheProvider>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export default function IndexPage() {
|
|||||||
stopPolling();
|
stopPolling();
|
||||||
}, [data?.workspaces, stopPolling]);
|
}, [data?.workspaces, stopPolling]);
|
||||||
|
|
||||||
if (!data && loading) {
|
if ((!data && loading) || !user) {
|
||||||
return <LoadingScreen />;
|
return <LoadingScreen />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import AuthenticatedLayout from '@/components/layout/AuthenticatedLayout';
|
|||||||
import Container from '@/components/layout/Container';
|
import Container from '@/components/layout/Container';
|
||||||
import { useUI } from '@/context/UIContext';
|
import { useUI } from '@/context/UIContext';
|
||||||
import features from '@/data/features.json';
|
import features from '@/data/features.json';
|
||||||
import { useGetAllUserWorkspacesAndApplications } from '@/hooks/useGetAllUserWorkspacesAndApplications';
|
|
||||||
import { useLazyRefetchUserData } from '@/hooks/useLazyRefetchUserData';
|
|
||||||
import { useSubmitState } from '@/hooks/useSubmitState';
|
import { useSubmitState } from '@/hooks/useSubmitState';
|
||||||
import { Alert } from '@/ui/Alert';
|
import { Alert } from '@/ui/Alert';
|
||||||
import { Modal } from '@/ui/Modal';
|
import { Modal } from '@/ui/Modal';
|
||||||
@@ -12,7 +10,6 @@ import ActivityIndicator from '@/ui/v2/ActivityIndicator';
|
|||||||
import Box from '@/ui/v2/Box';
|
import Box from '@/ui/v2/Box';
|
||||||
import Button from '@/ui/v2/Button';
|
import Button from '@/ui/v2/Button';
|
||||||
import IconButton from '@/ui/v2/IconButton';
|
import IconButton from '@/ui/v2/IconButton';
|
||||||
import CopyIcon from '@/ui/v2/icons/CopyIcon';
|
|
||||||
import Input from '@/ui/v2/Input';
|
import Input from '@/ui/v2/Input';
|
||||||
import InputAdornment from '@/ui/v2/InputAdornment';
|
import InputAdornment from '@/ui/v2/InputAdornment';
|
||||||
import Option from '@/ui/v2/Option';
|
import Option from '@/ui/v2/Option';
|
||||||
@@ -22,7 +19,19 @@ import Select from '@/ui/v2/Select';
|
|||||||
import type { TextProps } from '@/ui/v2/Text';
|
import type { TextProps } from '@/ui/v2/Text';
|
||||||
import Text from '@/ui/v2/Text';
|
import Text from '@/ui/v2/Text';
|
||||||
import Tooltip from '@/ui/v2/Tooltip';
|
import Tooltip from '@/ui/v2/Tooltip';
|
||||||
|
import CopyIcon from '@/ui/v2/icons/CopyIcon';
|
||||||
import { MAX_FREE_PROJECTS } from '@/utils/CONSTANTS';
|
import { MAX_FREE_PROJECTS } from '@/utils/CONSTANTS';
|
||||||
|
import type {
|
||||||
|
PrefetchNewAppPlansFragment,
|
||||||
|
PrefetchNewAppRegionsFragment,
|
||||||
|
PrefetchNewAppWorkspaceFragment,
|
||||||
|
} from '@/utils/__generated__/graphql';
|
||||||
|
import {
|
||||||
|
GetAllWorkspacesAndProjectsDocument,
|
||||||
|
useGetFreeAndActiveProjectsQuery,
|
||||||
|
useInsertApplicationMutation,
|
||||||
|
usePrefetchNewAppQuery,
|
||||||
|
} from '@/utils/__generated__/graphql';
|
||||||
import { copy } from '@/utils/copy';
|
import { copy } from '@/utils/copy';
|
||||||
import { getErrorMessage } from '@/utils/getErrorMessage';
|
import { getErrorMessage } from '@/utils/getErrorMessage';
|
||||||
import { getCurrentEnvironment } from '@/utils/helpers';
|
import { getCurrentEnvironment } from '@/utils/helpers';
|
||||||
@@ -31,16 +40,6 @@ import generateRandomDatabasePassword from '@/utils/settings/generateRandomDatab
|
|||||||
import { resetDatabasePasswordValidationSchema } from '@/utils/settings/resetDatabasePasswordValidationSchema';
|
import { resetDatabasePasswordValidationSchema } from '@/utils/settings/resetDatabasePasswordValidationSchema';
|
||||||
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
||||||
import { triggerToast } from '@/utils/toast';
|
import { triggerToast } from '@/utils/toast';
|
||||||
import type {
|
|
||||||
PrefetchNewAppPlansFragment,
|
|
||||||
PrefetchNewAppRegionsFragment,
|
|
||||||
PrefetchNewAppWorkspaceFragment,
|
|
||||||
} from '@/utils/__generated__/graphql';
|
|
||||||
import {
|
|
||||||
useGetFreeAndActiveProjectsQuery,
|
|
||||||
useInsertApplicationMutation,
|
|
||||||
usePrefetchNewAppQuery,
|
|
||||||
} from '@/utils/__generated__/graphql';
|
|
||||||
import type { ApolloError } from '@apollo/client';
|
import type { ApolloError } from '@apollo/client';
|
||||||
import { useUserData } from '@nhost/nextjs';
|
import { useUserData } from '@nhost/nextjs';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
@@ -70,8 +69,6 @@ export function NewProjectPageContent({
|
|||||||
}: NewAppPageProps) {
|
}: NewAppPageProps) {
|
||||||
const { maintenanceActive } = useUI();
|
const { maintenanceActive } = useUI();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
// pre hook
|
|
||||||
useGetAllUserWorkspacesAndApplications();
|
|
||||||
|
|
||||||
// form
|
// form
|
||||||
const [name, setName] = useState('');
|
const [name, setName] = useState('');
|
||||||
@@ -111,8 +108,9 @@ export function NewProjectPageContent({
|
|||||||
|
|
||||||
// graphql mutations
|
// graphql mutations
|
||||||
|
|
||||||
const [insertApp] = useInsertApplicationMutation({});
|
const [insertApp] = useInsertApplicationMutation({
|
||||||
const { refetchUserData } = useLazyRefetchUserData();
|
refetchQueries: [GetAllWorkspacesAndProjectsDocument],
|
||||||
|
});
|
||||||
|
|
||||||
// options
|
// options
|
||||||
const workspaceOptions = workspaces.map((workspace) => ({
|
const workspaceOptions = workspaces.map((workspace) => ({
|
||||||
@@ -220,7 +218,6 @@ export function NewProjectPageContent({
|
|||||||
getToastStyleProps(),
|
getToastStyleProps(),
|
||||||
);
|
);
|
||||||
|
|
||||||
await refetchUserData();
|
|
||||||
await router.push(`/${selectedWorkspace.slug}/${slug}`);
|
await router.push(`/${selectedWorkspace.slug}/${slug}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setSubmitState({
|
setSubmitState({
|
||||||
|
|||||||
1577
dashboard/src/utils/__generated__/graphql.ts
generated
1577
dashboard/src/utils/__generated__/graphql.ts
generated
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,6 @@
|
|||||||
import { DialogProvider } from '@/components/common/DialogProvider';
|
import { DialogProvider } from '@/components/common/DialogProvider';
|
||||||
import RetryableErrorBoundary from '@/components/common/RetryableErrorBoundary';
|
import RetryableErrorBoundary from '@/components/common/RetryableErrorBoundary';
|
||||||
import { ManagedUIContext } from '@/context/UIContext';
|
import { ManagedUIContext } from '@/context/UIContext';
|
||||||
import { UserDataProvider } from '@/context/UserDataContext';
|
|
||||||
import createTheme from '@/ui/v2/createTheme';
|
import createTheme from '@/ui/v2/createTheme';
|
||||||
import { createHttpLink } from '@apollo/client';
|
import { createHttpLink } from '@apollo/client';
|
||||||
import { CacheProvider } from '@emotion/react';
|
import { CacheProvider } from '@emotion/react';
|
||||||
@@ -104,18 +103,18 @@ function Providers({ children }: PropsWithChildren<{}>) {
|
|||||||
<NhostProvider nhost={nhost} initial={mockSession}>
|
<NhostProvider nhost={nhost} initial={mockSession}>
|
||||||
<NhostApolloProvider
|
<NhostApolloProvider
|
||||||
nhost={nhost}
|
nhost={nhost}
|
||||||
link={createHttpLink({
|
generateLinks={() => [
|
||||||
uri: 'https://local.graphql.nhost.run/v1',
|
createHttpLink({
|
||||||
})}
|
uri: 'https://local.graphql.nhost.run/v1',
|
||||||
|
}),
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<UserDataProvider>
|
<ManagedUIContext>
|
||||||
<ManagedUIContext>
|
<Toaster position="bottom-center" />
|
||||||
<Toaster position="bottom-center" />
|
<ThemeProvider theme={theme}>
|
||||||
<ThemeProvider theme={theme}>
|
<DialogProvider>{children}</DialogProvider>
|
||||||
<DialogProvider>{children}</DialogProvider>
|
</ThemeProvider>
|
||||||
</ThemeProvider>
|
</ManagedUIContext>
|
||||||
</ManagedUIContext>
|
|
||||||
</UserDataProvider>
|
|
||||||
</NhostApolloProvider>
|
</NhostApolloProvider>
|
||||||
</NhostProvider>
|
</NhostProvider>
|
||||||
</CacheProvider>
|
</CacheProvider>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { ApolloClient, ApolloQueryResult } from '@apollo/client';
|
import type { ApolloClient, ApolloQueryResult } from '@apollo/client';
|
||||||
|
import { GetAllWorkspacesAndProjectsDocument } from './__generated__/graphql';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function will refetch the main query we use for the cache
|
* This function will refetch the main query we use for the cache
|
||||||
@@ -9,7 +10,7 @@ export async function updateOwnCache(
|
|||||||
client: ApolloClient<any>,
|
client: ApolloClient<any>,
|
||||||
): Promise<ApolloQueryResult<any>[]> {
|
): Promise<ApolloQueryResult<any>[]> {
|
||||||
return client.refetchQueries({
|
return client.refetchQueries({
|
||||||
include: ['getOneUser'],
|
include: [GetAllWorkspacesAndProjectsDocument],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
# @nhost/apollo
|
# @nhost/apollo
|
||||||
|
|
||||||
|
## 5.2.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- a1c7b00e: chore(links): add support for `generateLinks`
|
||||||
|
- Updated dependencies [08e70b9d]
|
||||||
|
- @nhost/nhost-js@2.2.1
|
||||||
|
|
||||||
## 5.2.1
|
## 5.2.1
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nhost/apollo",
|
"name": "@nhost/apollo",
|
||||||
"version": "5.2.1",
|
"version": "5.2.2",
|
||||||
"description": "Nhost Apollo Client library",
|
"description": "Nhost Apollo Client library",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ApolloClient,
|
ApolloClient,
|
||||||
|
ApolloLink,
|
||||||
createHttpLink,
|
createHttpLink,
|
||||||
from,
|
from,
|
||||||
InMemoryCache,
|
InMemoryCache,
|
||||||
@@ -23,8 +24,15 @@ export type NhostApolloClientOptions = {
|
|||||||
fetchPolicy?: WatchQueryFetchPolicy
|
fetchPolicy?: WatchQueryFetchPolicy
|
||||||
connectToDevTools?: boolean
|
connectToDevTools?: boolean
|
||||||
cache?: InMemoryCache
|
cache?: InMemoryCache
|
||||||
|
/**
|
||||||
|
* @deprecated Please use `generateLinks` instead.
|
||||||
|
*/
|
||||||
onError?: RequestHandler
|
onError?: RequestHandler
|
||||||
link?: ApolloClient<any>['link']
|
/**
|
||||||
|
* @deprecated Please use `generateLinks` instead.
|
||||||
|
*/
|
||||||
|
link?: ApolloLink
|
||||||
|
generateLinks?: (links: (ApolloLink | RequestHandler)[]) => (ApolloLink | RequestHandler)[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createApolloClient = ({
|
export const createApolloClient = ({
|
||||||
@@ -36,7 +44,8 @@ export const createApolloClient = ({
|
|||||||
cache = new InMemoryCache(),
|
cache = new InMemoryCache(),
|
||||||
connectToDevTools = isBrowser && process.env.NODE_ENV === 'development',
|
connectToDevTools = isBrowser && process.env.NODE_ENV === 'development',
|
||||||
onError,
|
onError,
|
||||||
link: customLink
|
link: customLink,
|
||||||
|
generateLinks
|
||||||
}: NhostApolloClientOptions) => {
|
}: NhostApolloClientOptions) => {
|
||||||
const backendUrl = graphqlUrl || nhost?.graphql.httpUrl
|
const backendUrl = graphqlUrl || nhost?.graphql.httpUrl
|
||||||
|
|
||||||
@@ -106,7 +115,7 @@ export const createApolloClient = ({
|
|||||||
}
|
}
|
||||||
})).concat(createHttpLink({ uri }))
|
})).concat(createHttpLink({ uri }))
|
||||||
|
|
||||||
const link = wsLink
|
const splitLink = wsLink
|
||||||
? split(
|
? split(
|
||||||
({ query }) => {
|
({ query }) => {
|
||||||
const mainDefinition = getMainDefinition(query)
|
const mainDefinition = getMainDefinition(query)
|
||||||
@@ -124,6 +133,20 @@ export const createApolloClient = ({
|
|||||||
)
|
)
|
||||||
: httpLink
|
: httpLink
|
||||||
|
|
||||||
|
const links = []
|
||||||
|
|
||||||
|
if (onError) {
|
||||||
|
links.push(onError)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customLink) {
|
||||||
|
links.push(customLink)
|
||||||
|
}
|
||||||
|
|
||||||
|
links.push(splitLink)
|
||||||
|
|
||||||
|
const link = from(generateLinks ? generateLinks(links) : links)
|
||||||
|
|
||||||
const client = new ApolloClient({
|
const client = new ApolloClient({
|
||||||
cache: cache || new InMemoryCache(),
|
cache: cache || new InMemoryCache(),
|
||||||
ssrMode: !isBrowser,
|
ssrMode: !isBrowser,
|
||||||
@@ -133,9 +156,7 @@ export const createApolloClient = ({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
connectToDevTools,
|
connectToDevTools,
|
||||||
link: customLink
|
link
|
||||||
? from([customLink])
|
|
||||||
: from(typeof onError === 'function' ? [onError, link] : [link])
|
|
||||||
})
|
})
|
||||||
|
|
||||||
interpreter?.onTransition(async (state, event) => {
|
interpreter?.onTransition(async (state, event) => {
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
# @nhost/react-apollo
|
# @nhost/react-apollo
|
||||||
|
|
||||||
|
## 5.0.18
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [a1c7b00e]
|
||||||
|
- @nhost/apollo@5.2.2
|
||||||
|
- @nhost/react@2.0.15
|
||||||
|
|
||||||
## 5.0.17
|
## 5.0.17
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nhost/react-apollo",
|
"name": "@nhost/react-apollo",
|
||||||
"version": "5.0.17",
|
"version": "5.0.18",
|
||||||
"description": "Nhost React Apollo client",
|
"description": "Nhost React Apollo client",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# @nhost/react-urql
|
# @nhost/react-urql
|
||||||
|
|
||||||
|
## 2.0.16
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @nhost/react@2.0.15
|
||||||
|
|
||||||
## 2.0.15
|
## 2.0.15
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nhost/react-urql",
|
"name": "@nhost/react-urql",
|
||||||
"version": "2.0.15",
|
"version": "2.0.16",
|
||||||
"description": "Nhost React URQL client",
|
"description": "Nhost React URQL client",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# @nhost/nextjs
|
# @nhost/nextjs
|
||||||
|
|
||||||
|
## 1.13.21
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- @nhost/react@2.0.15
|
||||||
|
|
||||||
## 1.13.20
|
## 1.13.20
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nhost/nextjs",
|
"name": "@nhost/nextjs",
|
||||||
"version": "1.13.20",
|
"version": "1.13.21",
|
||||||
"description": "Nhost NextJS library",
|
"description": "Nhost NextJS library",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# @nhost/nhost-js
|
# @nhost/nhost-js
|
||||||
|
|
||||||
|
## 2.2.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 08e70b9d: fix(functions): show more detailed error messages
|
||||||
|
|
||||||
## 2.2.0
|
## 2.2.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nhost/nhost-js",
|
"name": "@nhost/nhost-js",
|
||||||
"version": "2.2.0",
|
"version": "2.2.1",
|
||||||
"description": "Nhost JavaScript SDK",
|
"description": "Nhost JavaScript SDK",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@@ -39,20 +39,51 @@ export class NhostFunctionsClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use `nhost.functions.call` to call (sending a POST request to) a serverless function.
|
* Use `nhost.functions.call` to call (sending a POST request to) a serverless function. Use generic
|
||||||
|
* types to specify the expected response data, request body and error message.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
|
* ### Without generic types
|
||||||
* ```ts
|
* ```ts
|
||||||
* await nhost.functions.call('send-welcome-email', { email: 'joe@example.com', name: 'Joe Doe' })
|
* await nhost.functions.call('send-welcome-email', { email: 'joe@example.com', name: 'Joe Doe' })
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
|
* @example
|
||||||
|
* ### Using generic types
|
||||||
|
* ```ts
|
||||||
|
* type Data = {
|
||||||
|
* message: string
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* type Body = {
|
||||||
|
* email: string
|
||||||
|
* name: string
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* type ErrorMessage = {
|
||||||
|
* details: string
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // The function will only accept a body of type `Body`
|
||||||
|
* const { res, error } = await nhost.functions.call<Data, Body, ErrorMessage>(
|
||||||
|
* 'send-welcome-email',
|
||||||
|
* { email: 'joe@example.com', name: 'Joe Doe' }
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* // Now the response data is typed as `Data`
|
||||||
|
* console.log(res?.data.message)
|
||||||
|
*
|
||||||
|
* // Now the error message is typed as `ErrorMessage`
|
||||||
|
* console.log(error?.message.details)
|
||||||
|
* ```
|
||||||
|
*
|
||||||
* @docs https://docs.nhost.io/reference/javascript/nhost-js/functions/call
|
* @docs https://docs.nhost.io/reference/javascript/nhost-js/functions/call
|
||||||
*/
|
*/
|
||||||
async call<T = unknown, D = any>(
|
async call<TData = unknown, TBody = any, TErrorMessage = any>(
|
||||||
url: string,
|
url: string,
|
||||||
body: D | null,
|
body?: TBody | null,
|
||||||
config?: NhostFunctionCallConfig
|
config?: NhostFunctionCallConfig
|
||||||
): Promise<NhostFunctionCallResponse<T>> {
|
): Promise<NhostFunctionCallResponse<TData, TErrorMessage>> {
|
||||||
const headers: HeadersInit = {
|
const headers: HeadersInit = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
...this.generateAccessTokenHeaders(),
|
...this.generateAccessTokenHeaders(),
|
||||||
@@ -69,15 +100,30 @@ export class NhostFunctionsClient {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (!result.ok) {
|
if (!result.ok) {
|
||||||
throw new Error(result.statusText)
|
let message: TErrorMessage
|
||||||
|
|
||||||
|
if (result.headers.get('content-type')?.includes('application/json')) {
|
||||||
|
message = await result.json()
|
||||||
|
} else {
|
||||||
|
message = (await result.text()) as unknown as TErrorMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
res: null,
|
||||||
|
error: {
|
||||||
|
message,
|
||||||
|
error: result.statusText,
|
||||||
|
status: result.status
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let data: T
|
let data: TData
|
||||||
|
|
||||||
if (result.headers.get('content-type')?.includes('application/json')) {
|
if (result.headers.get('content-type')?.includes('application/json')) {
|
||||||
data = await result.json()
|
data = await result.json()
|
||||||
} else {
|
} else {
|
||||||
data = (await result.text()) as unknown as T
|
data = (await result.text()) as unknown as TData
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -89,7 +135,7 @@ export class NhostFunctionsClient {
|
|||||||
return {
|
return {
|
||||||
res: null,
|
res: null,
|
||||||
error: {
|
error: {
|
||||||
message: error.message,
|
message: error.message as unknown as TErrorMessage,
|
||||||
status: error.name === 'AbortError' ? 0 : 500,
|
status: error.name === 'AbortError' ? 0 : 500,
|
||||||
error: error.name === 'AbortError' ? 'abort-error' : 'unknown'
|
error: error.name === 'AbortError' ? 'abort-error' : 'unknown'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ export interface NhostFunctionsConstructorParams {
|
|||||||
adminSecret?: string
|
adminSecret?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type NhostFunctionCallResponse<T = unknown> =
|
export type NhostFunctionCallResponse<TData = unknown, TErrorMessage = any> =
|
||||||
| {
|
| {
|
||||||
res: {
|
res: {
|
||||||
data: T
|
data: TData
|
||||||
status: number
|
status: number
|
||||||
statusText: string
|
statusText: string
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ export type NhostFunctionCallResponse<T = unknown> =
|
|||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
res: null
|
res: null
|
||||||
error: ErrorPayload
|
error: ErrorPayload<TErrorMessage>
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Subset of RequestInit parameters that are supported by the functions client */
|
/** Subset of RequestInit parameters that are supported by the functions client */
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { NhostAuthConstructorParams } from '@nhost/hasura-auth-js'
|
import { NhostAuthConstructorParams } from '@nhost/hasura-auth-js'
|
||||||
|
|
||||||
// TODO shared with other packages
|
// TODO shared with other packages
|
||||||
export interface ErrorPayload {
|
export interface ErrorPayload<TMessage = any> {
|
||||||
error: string
|
error: string
|
||||||
status: number
|
status: number
|
||||||
message: string
|
message: TMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO shared with other packages
|
// TODO shared with other packages
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
# @nhost/react
|
# @nhost/react
|
||||||
|
|
||||||
|
## 2.0.15
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [08e70b9d]
|
||||||
|
- @nhost/nhost-js@2.2.1
|
||||||
|
|
||||||
## 2.0.14
|
## 2.0.14
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nhost/react",
|
"name": "@nhost/react",
|
||||||
"version": "2.0.14",
|
"version": "2.0.15",
|
||||||
"description": "Nhost React library",
|
"description": "Nhost React library",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
# @nhost/vue
|
# @nhost/vue
|
||||||
|
|
||||||
|
## 1.13.20
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 4c615203: fix(hooks): use correct return type for `useError`
|
||||||
|
- Updated dependencies [08e70b9d]
|
||||||
|
- @nhost/nhost-js@2.2.1
|
||||||
|
|
||||||
## 1.13.19
|
## 1.13.19
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@nhost/vue",
|
"name": "@nhost/vue",
|
||||||
"version": "1.13.19",
|
"version": "1.13.20",
|
||||||
"description": "Nhost Vue library",
|
"description": "Nhost Vue library",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { ErrorPayload, StateErrorTypes } from '@nhost/nhost-js'
|
import { AuthErrorPayload, StateErrorTypes } from '@nhost/nhost-js'
|
||||||
import { useSelector } from '@xstate/vue'
|
import { useSelector } from '@xstate/vue'
|
||||||
import { Ref } from 'vue'
|
import { Ref } from 'vue'
|
||||||
import { useAuthInterpreter } from './useAuthInterpreter'
|
import { useAuthInterpreter } from './useAuthInterpreter'
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export const useError = (type: StateErrorTypes): Ref<ErrorPayload | null> => {
|
export const useError = (type: StateErrorTypes): Ref<AuthErrorPayload | null> => {
|
||||||
const service = useAuthInterpreter()
|
const service = useAuthInterpreter()
|
||||||
return useSelector(
|
return useSelector(
|
||||||
service.value,
|
service.value,
|
||||||
|
|||||||
Reference in New Issue
Block a user