Compare commits
83 Commits
@nhost/apo
...
@nhost/das
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a74a97cd0 | ||
|
|
291185e609 | ||
|
|
d3f965048a | ||
|
|
9b0d4dde50 | ||
|
|
06d6ae0e86 | ||
|
|
1777c147b2 | ||
|
|
9d784b82c8 | ||
|
|
15d84a1966 | ||
|
|
8a1a1e06aa | ||
|
|
eb1d7137cf | ||
|
|
cf55e8e111 | ||
|
|
b47c797d73 | ||
|
|
dafc4b2635 | ||
|
|
0ccd9c82b1 | ||
|
|
0dd1883815 | ||
|
|
01ba429007 | ||
|
|
fdf5b3035c | ||
|
|
ae52ca6303 | ||
|
|
428222bf5f | ||
|
|
090ee51854 | ||
|
|
766c8431f1 | ||
|
|
4c62617472 | ||
|
|
01f3cbb07a | ||
|
|
62f5d8b69e | ||
|
|
88e2c05afc | ||
|
|
f1edbfdbf1 | ||
|
|
a9943eef3f | ||
|
|
431e61a684 | ||
|
|
87e7f7d4f5 | ||
|
|
5aab6b1896 | ||
|
|
e4e216da6d | ||
|
|
cd8ccdf59a | ||
|
|
9421dda73d | ||
|
|
f13dc75993 | ||
|
|
0a8b42d371 | ||
|
|
bd59d61e94 | ||
|
|
349622fca2 | ||
|
|
dfe8588a94 | ||
|
|
0167df5534 | ||
|
|
7c790b3afe | ||
|
|
1b3a8a1638 | ||
|
|
99edd0129a | ||
|
|
cfb759c34a | ||
|
|
6c5a645876 | ||
|
|
db459b09ec | ||
|
|
e4fa63a571 | ||
|
|
4ce552c8eb | ||
|
|
b847c6d003 | ||
|
|
daab7d8eeb | ||
|
|
1b4f074dfd | ||
|
|
cca7075721 | ||
|
|
4c1b96ccc6 | ||
|
|
084b7ce6d2 | ||
|
|
9b209ef419 | ||
|
|
a86d17c81f | ||
|
|
cc047b719a | ||
|
|
889b071134 | ||
|
|
eee3f5723e | ||
|
|
412520ac10 | ||
|
|
3cb63a6da9 | ||
|
|
985f648204 | ||
|
|
bbc3aa8896 | ||
|
|
3d51de4a60 | ||
|
|
b46afa37c6 | ||
|
|
8ad6358d76 | ||
|
|
f73f8366e4 | ||
|
|
cab803e5b7 | ||
|
|
59fea65eb6 | ||
|
|
23bac2d29c | ||
|
|
78739f77b1 | ||
|
|
8989202692 | ||
|
|
2ae463f11f | ||
|
|
18a786e880 | ||
|
|
c88fbe1e17 | ||
|
|
78c7109c46 | ||
|
|
c7b968868a | ||
|
|
77a3473166 | ||
|
|
91e2affa6f | ||
|
|
a8d747976b | ||
|
|
fc16fd5452 | ||
|
|
afc9de7994 | ||
|
|
37c1c18b43 | ||
|
|
67078b9a72 |
@@ -28,6 +28,8 @@ module.exports = {
|
||||
'import/no-named-as-default': 'off',
|
||||
'import/prefer-default-export': 'off',
|
||||
'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
|
||||
// TODO: Temporarily disable this rule because of a WIP refactoring
|
||||
'import/no-named-as-default': 'off',
|
||||
curly: ['error', 'all'],
|
||||
'no-restricted-exports': 'off',
|
||||
'no-undef': 'off',
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
# @nhost/dashboard
|
||||
|
||||
## 0.17.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 9b0d4dde: feat(secrets): enable secrets
|
||||
|
||||
## 0.17.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 15d84a19: Add postgres 14.6-20230525
|
||||
|
||||
## 0.16.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 4c626174: chore: updated import paths, improved directory structure
|
||||
- cc047b71: chore(deps): bump `@fontsource` monorepo to `v5.0.0`
|
||||
- 99edd012: feat(account): add support for personal access tokens
|
||||
|
||||
## 0.16.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 78c7109c: feat(settings): allow selecting service versions
|
||||
|
||||
## 0.16.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
51
dashboard/e2e/account/pat/manage-pat.test.ts
Normal file
51
dashboard/e2e/account/pat/manage-pat.test.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import type { Page } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
let page: Page;
|
||||
|
||||
test.beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
});
|
||||
|
||||
test.beforeEach(async () => {
|
||||
await page.goto('/');
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await page.close();
|
||||
});
|
||||
|
||||
test('should be able to create then delete a personal access token', async () => {
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByRole('banner').getByRole('button').last().click();
|
||||
await page.getByRole('link', { name: /account settings/i }).click();
|
||||
await page
|
||||
.getByRole('button', { name: /create personal access token/i })
|
||||
.click();
|
||||
|
||||
const patName = faker.lorem.slug(3);
|
||||
|
||||
await page.getByRole('textbox', { name: /name/i }).fill(patName);
|
||||
await page.getByRole('button', { name: /expiration/i }).click();
|
||||
await page.getByRole('option', { name: /7 days/i }).click();
|
||||
await page.getByRole('button', { name: /create/i }).click();
|
||||
|
||||
await expect(
|
||||
page.getByText(
|
||||
/this token will not be shown again. make sure to copy it now./i,
|
||||
),
|
||||
).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: /close/i }).click();
|
||||
|
||||
await expect(page.getByText(patName)).toBeVisible();
|
||||
|
||||
await page
|
||||
.getByRole('button', { name: `More options for ${patName}`, exact: true })
|
||||
.click();
|
||||
await page.getByRole('menuitem', { name: /delete/i }).click();
|
||||
await page.getByRole('button', { name: /delete/i }).click();
|
||||
|
||||
await expect(page.getByText(patName)).not.toBeVisible();
|
||||
});
|
||||
@@ -46,7 +46,7 @@ async function globalTeardown() {
|
||||
await hasuraPage.locator('a', { hasText: /data/i }).click();
|
||||
await hasuraPage.getByRole('link', { name: /sql/i }).click();
|
||||
|
||||
await hasuraPage.getByRole('textbox').fill(`
|
||||
await hasuraPage.locator('#raw_sql > textarea').fill(`
|
||||
DO $$ DECLARE
|
||||
tablename text;
|
||||
BEGIN
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/dashboard",
|
||||
"version": "0.16.12",
|
||||
"version": "0.17.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
@@ -15,7 +15,7 @@
|
||||
"format": "prettier --write \"src/**/*.{js,ts,tsx,jsx,json,md}\" --plugin-search-dir=.",
|
||||
"storybook": "start-storybook -p 6006 -s public",
|
||||
"build-storybook": "build-storybook",
|
||||
"e2e": "npx playwright@1.33.0 install --with-deps && playwright test"
|
||||
"e2e": "npx playwright@1.34.0 install --with-deps && playwright test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.7.10",
|
||||
@@ -24,8 +24,8 @@
|
||||
"@emotion/react": "^11.10.5",
|
||||
"@emotion/server": "^11.4.0",
|
||||
"@emotion/styled": "^11.10.5",
|
||||
"@fontsource/inter": "^4.5.14",
|
||||
"@fontsource/roboto-mono": "^4.5.8",
|
||||
"@fontsource/inter": "^5.0.0",
|
||||
"@fontsource/roboto-mono": "^5.0.0",
|
||||
"@graphiql/react": "^0.17.0",
|
||||
"@graphiql/toolkit": "^0.8.2",
|
||||
"@headlessui/react": "^1.6.5",
|
||||
@@ -84,11 +84,10 @@
|
||||
"@faker-js/faker": "^7.6.0",
|
||||
"@graphql-codegen/cli": "^3.0.0",
|
||||
"@graphql-codegen/typescript": "^3.0.0",
|
||||
"@graphql-codegen/typescript-graphql-request": "^4.5.1",
|
||||
"@graphql-codegen/typescript-operations": "^3.0.0",
|
||||
"@graphql-codegen/typescript-react-apollo": "^3.3.1",
|
||||
"@next/bundle-analyzer": "^12.3.1",
|
||||
"@playwright/test": "^1.33.0",
|
||||
"@playwright/test": "^1.34.0",
|
||||
"@storybook/addon-actions": "^6.5.14",
|
||||
"@storybook/addon-essentials": "^6.5.14",
|
||||
"@storybook/addon-interactions": "^6.5.14",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import FeedbackForm from '@/components/common/FeedbackForm';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { FeedbackForm } from '@/components/common/FeedbackForm';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useInterval } from '@/hooks/useInterval';
|
||||
import ActivityIndicator from '@/ui/v2/ActivityIndicator';
|
||||
import Button from '@/ui/v2/Button';
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import FeedbackForm from '@/components/common/FeedbackForm';
|
||||
import { FeedbackForm } from '@/components/common/FeedbackForm';
|
||||
import Container from '@/components/layout/Container';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useIsCurrentUserOwner } from '@/features/projects/common/hooks/useIsCurrentUserOwner';
|
||||
import { useAppCreatedAt } from '@/hooks/useAppCreatedAt';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useIsCurrentUserOwner } from '@/features/projects/hooks/useIsCurrentUserOwner';
|
||||
import { useCurrentDate } from '@/hooks/useCurrentDate';
|
||||
import type { ApplicationState } from '@/types/application';
|
||||
import { ApplicationStatus } from '@/types/application';
|
||||
@@ -11,16 +10,16 @@ import ActivityIndicator from '@/ui/v2/ActivityIndicator';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import { Dropdown } from '@/ui/v2/Dropdown';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import { discordAnnounce } from '@/utils/discordAnnounce';
|
||||
import { getPreviousApplicationState } from '@/utils/getPreviousApplicationState';
|
||||
import { getApplicationStatusString } from '@/utils/helpers';
|
||||
import { triggerToast } from '@/utils/toast';
|
||||
import {
|
||||
useDeleteApplicationMutation,
|
||||
useGetApplicationStateQuery,
|
||||
useInsertApplicationMutation,
|
||||
useUpdateApplicationMutation,
|
||||
} from '@/utils/__generated__/graphql';
|
||||
import { discordAnnounce } from '@/utils/discordAnnounce';
|
||||
import { getPreviousApplicationState } from '@/utils/getPreviousApplicationState';
|
||||
import { getApplicationStatusString } from '@/utils/helpers';
|
||||
import { triggerToast } from '@/utils/toast';
|
||||
import { useUserData } from '@nhost/nextjs';
|
||||
import Image from 'next/image';
|
||||
import { useState } from 'react';
|
||||
@@ -60,7 +59,7 @@ export default function ApplicationErrored() {
|
||||
const user = useUserData();
|
||||
const isOwner = useIsCurrentUserOwner();
|
||||
|
||||
const { appCreatedAt } = useAppCreatedAt();
|
||||
const appCreatedAt = new Date(currentProject.createdAt).getTime();
|
||||
|
||||
const FIVE_DAYS_IN_MILLISECONDS = 60 * 24 * 60 * 5 * 1000;
|
||||
const HALF_DAY_IN_MILLISECONDS = 60 * 12 * 60 * 1000;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import {
|
||||
GetAllWorkspacesAndProjectsDocument,
|
||||
useDeleteApplicationMutation,
|
||||
} from '@/generated/graphql';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import Link from '@/ui/v2/Link';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import ArrowRightIcon from '@/ui/v2/icons/ArrowRightIcon';
|
||||
import { Button } from '@/ui/v2/Button';
|
||||
import { ArrowRightIcon } from '@/ui/v2/icons/ArrowRightIcon';
|
||||
import { Link } from '@/ui/v2/Link';
|
||||
import { Text } from '@/ui/v2/Text';
|
||||
import { copy } from '@/utils/copy';
|
||||
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 { useRouter } from 'next/router';
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import MaintenanceAlert from '@/components/common/MaintenanceAlert';
|
||||
import RetryableErrorBoundary from '@/components/common/RetryableErrorBoundary';
|
||||
import { MaintenanceAlert } from '@/components/common/MaintenanceAlert';
|
||||
import { RetryableErrorBoundary } from '@/components/common/RetryableErrorBoundary';
|
||||
import Container from '@/components/layout/Container';
|
||||
import OverviewDeployments from '@/components/overview/OverviewDeployments';
|
||||
import OverviewDocumentation from '@/components/overview/OverviewDocumentation';
|
||||
import OverviewMetrics from '@/components/overview/OverviewMetrics/OverviewMetrics';
|
||||
import OverviewProjectInfo from '@/components/overview/OverviewProjectInfo';
|
||||
import OverviewRepository from '@/components/overview/OverviewRepository';
|
||||
import OverviewTopBar from '@/components/overview/OverviewTopBar';
|
||||
import OverviewUsage from '@/components/overview/OverviewUsage';
|
||||
import { features } from '@/components/overview/features';
|
||||
import { frameworks } from '@/components/overview/frameworks';
|
||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||
import { useIsPlatform } from '@/features/projects/hooks/useIsPlatform';
|
||||
import { OverviewDeployments } from '@/features/projects/overview/components/OverviewDeployments';
|
||||
import { OverviewDocumentation } from '@/features/projects/overview/components/OverviewDocumentation';
|
||||
import { OverviewMetrics } from '@/features/projects/overview/components/OverviewMetrics';
|
||||
import { OverviewProjectInfo } from '@/features/projects/overview/components/OverviewProjectInfo';
|
||||
import { OverviewRepository } from '@/features/projects/overview/components/OverviewRepository';
|
||||
import { OverviewTopBar } from '@/features/projects/overview/components/OverviewTopBar';
|
||||
import { OverviewUsage } from '@/features/projects/overview/components/OverviewUsage';
|
||||
import { features } from '@/features/projects/overview/features';
|
||||
import { frameworks } from '@/features/projects/overview/frameworks';
|
||||
import { Alert } from '@/ui/Alert';
|
||||
import Divider from '@/ui/v2/Divider';
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ import { ChangePlanModal } from '@/components/applications/ChangePlanModal';
|
||||
import { StagingMetadata } from '@/components/applications/StagingMetadata';
|
||||
import { useDialog } from '@/components/common/DialogProvider';
|
||||
import Container from '@/components/layout/Container';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useIsCurrentUserOwner } from '@/features/projects/common/hooks/useIsCurrentUserOwner';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useIsCurrentUserOwner } from '@/features/projects/hooks/useIsCurrentUserOwner';
|
||||
import {
|
||||
GetAllWorkspacesAndProjectsDocument,
|
||||
useGetFreeAndActiveProjectsQuery,
|
||||
@@ -40,7 +40,6 @@ export default function ApplicationPaused() {
|
||||
|
||||
const { data, loading } = useGetFreeAndActiveProjectsQuery({
|
||||
variables: { userId: user?.id },
|
||||
fetchPolicy: 'cache-and-network',
|
||||
skip: !user,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Container from '@/components/layout/Container';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useCheckProvisioning } from '@/hooks/useCheckProvisioning';
|
||||
import { ApplicationStatus } from '@/types/application';
|
||||
import ActivityIndicator from '@/ui/v2/ActivityIndicator';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Container from '@/components/layout/Container';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useCheckProvisioning } from '@/hooks/useCheckProvisioning';
|
||||
import { ApplicationStatus } from '@/types/application';
|
||||
import ActivityIndicator from '@/ui/v2/ActivityIndicator';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import FeedbackForm from '@/components/common/FeedbackForm';
|
||||
import { FeedbackForm } from '@/components/common/FeedbackForm';
|
||||
import Container from '@/components/layout/Container';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useIsCurrentUserOwner } from '@/features/projects/common/hooks/useIsCurrentUserOwner';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useIsCurrentUserOwner } from '@/features/projects/hooks/useIsCurrentUserOwner';
|
||||
import { Modal } from '@/ui/Modal';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import { Dropdown } from '@/ui/v2/Dropdown';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Container from '@/components/layout/Container';
|
||||
import { useProjectRedirectWhenReady } from '@/features/projects/common/hooks/useProjectRedirectWhenReady';
|
||||
import { useProjectRedirectWhenReady } from '@/features/projects/hooks/useProjectRedirectWhenReady';
|
||||
import Image from 'next/image';
|
||||
import { AppLoader } from './AppLoader';
|
||||
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
import Box from '@/ui/v2/Box';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import Input from '@/ui/v2/Input';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import { nhost } from '@/utils/nhost';
|
||||
import { triggerToast } from '@/utils/toast';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
export function ChangePasswordModal({ close }: any) {
|
||||
const [formState, setFormState] = useState<{
|
||||
loading: boolean;
|
||||
error: null | string;
|
||||
}>({
|
||||
loading: false,
|
||||
error: null,
|
||||
});
|
||||
|
||||
const [newPassword, setNewPassword] = useState('');
|
||||
const [newPasswordConfirm, setNewPasswordConfirm] = useState('');
|
||||
|
||||
const handleSubmit = async (e: React.SyntheticEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
|
||||
setFormState({
|
||||
loading: true,
|
||||
error: null,
|
||||
});
|
||||
|
||||
if (newPassword !== newPasswordConfirm) {
|
||||
setFormState({
|
||||
loading: false,
|
||||
error: 'Passwords do not match',
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const { error } = await nhost.auth.changePassword({ newPassword });
|
||||
|
||||
if (error) {
|
||||
setFormState({
|
||||
loading: false,
|
||||
error: error.message,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
triggerToast(`Your password has been updated`);
|
||||
close();
|
||||
};
|
||||
|
||||
return (
|
||||
<Box className="w-full max-w-md rounded-md px-6 py-6 text-left">
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="grid grid-flow-row gap-4">
|
||||
<div className="grid grid-flow-row gap-2">
|
||||
<Text variant="h3">Choose New Password</Text>
|
||||
|
||||
<Text className="mt-2 font-normal">
|
||||
Make sure to pick a strong password with at least 8 characters.
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-flow-row gap-2">
|
||||
<Input
|
||||
type="password"
|
||||
id="newPassword"
|
||||
name="newPassword"
|
||||
label="New Password"
|
||||
placeholder="New password"
|
||||
autoFocus
|
||||
value={newPassword}
|
||||
onChange={(event) => setNewPassword(event.target.value)}
|
||||
hideEmptyHelperText
|
||||
fullWidth
|
||||
required
|
||||
/>
|
||||
|
||||
<Input
|
||||
type="password"
|
||||
id="confirmNewPassword"
|
||||
name="confirmNewPassword"
|
||||
label="Confirm New Password"
|
||||
placeholder="Confirm new password"
|
||||
value={newPasswordConfirm}
|
||||
onChange={(event) => setNewPasswordConfirm(event.target.value)}
|
||||
hideEmptyHelperText
|
||||
fullWidth
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-flow-row gap-2">
|
||||
{formState.error && (
|
||||
<Text className="w-full px-4 text-center" color="error">
|
||||
Error: {formState.error}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
<Button type="submit" loading={formState.loading}>
|
||||
Set New Password
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
type="reset"
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={close}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default ChangePasswordModal;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useDialog } from '@/components/common/DialogProvider';
|
||||
import { BillingPaymentMethodForm } from '@/components/workspace/BillingPaymentMethodForm';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import {
|
||||
refetchGetApplicationPlanQuery,
|
||||
useGetAppPlanAndGlobalPlansQuery,
|
||||
@@ -9,15 +9,15 @@ import {
|
||||
} from '@/generated/graphql';
|
||||
import useApplicationState from '@/hooks/useApplicationState';
|
||||
import { ApplicationStatus } from '@/types/application';
|
||||
import ActivityIndicator from '@/ui/v2/ActivityIndicator';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import Checkbox from '@/ui/v2/Checkbox';
|
||||
import { ActivityIndicator } from '@/ui/v2/ActivityIndicator';
|
||||
import { Box } from '@/ui/v2/Box';
|
||||
import { Button } from '@/ui/v2/Button';
|
||||
import { Checkbox } from '@/ui/v2/Checkbox';
|
||||
import { BaseDialog } from '@/ui/v2/Dialog';
|
||||
import Link from '@/ui/v2/Link';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import { Link } from '@/ui/v2/Link';
|
||||
import { Text } from '@/ui/v2/Text';
|
||||
import { planDescriptions } from '@/utils/planDescriptions';
|
||||
import getServerError from '@/utils/settings/getServerError';
|
||||
import { getServerError } from '@/utils/settings/getServerError';
|
||||
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { LoadingScreen } from '@/components/common/LoadingScreen';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useIsPlatform } from '@/features/projects/hooks/useIsPlatform';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import IconButton from '@/ui/v2/IconButton';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import ArrowSquareOutIcon from '@/ui/v2/icons/ArrowSquareOutIcon';
|
||||
import CopyIcon from '@/ui/v2/icons/CopyIcon';
|
||||
import generateAppServiceUrl, {
|
||||
import Text from '@/ui/v2/Text';
|
||||
import {
|
||||
defaultLocalBackendSlugs,
|
||||
defaultRemoteBackendSlugs,
|
||||
generateAppServiceUrl,
|
||||
} from '@/utils/common/generateAppServiceUrl';
|
||||
import { copy } from '@/utils/copy';
|
||||
import { getHasuraConsoleServiceUrl } from '@/utils/env';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import Checkbox from '@/ui/v2/Checkbox';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import Checkbox from '@/ui/v2/Checkbox';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ChangePlanModal } from '@/components/applications/ChangePlanModal';
|
||||
import { useDialog } from '@/components/common/DialogProvider';
|
||||
import { useIsCurrentUserOwner } from '@/features/projects/common/hooks/useIsCurrentUserOwner';
|
||||
import { useIsCurrentUserOwner } from '@/features/projects/hooks/useIsCurrentUserOwner';
|
||||
import { Alert } from '@/ui/Alert';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import Text from '@/ui/v2/Text';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ConnectGithubModalState } from '@/components/applications/ConnectGithubModal';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import { EditRepositorySettingsModal } from './EditRepositorySettingsModal';
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { EditRepositorySettingsFormData } from '@/components/applications/g
|
||||
import { useDialog } from '@/components/common/DialogProvider';
|
||||
import ErrorBoundaryFallback from '@/components/common/ErrorBoundaryFallback';
|
||||
import GithubIcon from '@/components/icons/GithubIcon';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useUpdateApplicationMutation } from '@/generated/graphql';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import Text from '@/ui/v2/Text';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useRemoteApplicationGQLClient } from '@/hooks/useRemoteApplicationGQLClient';
|
||||
import ActivityIndicator from '@/ui/v2/ActivityIndicator';
|
||||
import Option from '@/ui/v2/Option';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import NavLink from '@/components/common/NavLink';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useIsPlatform } from '@/features/projects/hooks/useIsPlatform';
|
||||
import type { BoxProps } from '@/ui/v2/Box';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import Text from '@/ui/v2/Text';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './Breadcrumbs';
|
||||
export { default } from './Breadcrumbs';
|
||||
export { default as Breadcrumbs } from './Breadcrumbs';
|
||||
|
||||
@@ -2,7 +2,7 @@ import type {
|
||||
AutocompleteOption,
|
||||
AutocompleteProps,
|
||||
} from '@/ui/v2/Autocomplete';
|
||||
import Autocomplete from '@/ui/v2/Autocomplete';
|
||||
import { Autocomplete } from '@/ui/v2/Autocomplete';
|
||||
import callAll from '@/utils/callAll';
|
||||
import type { ForwardedRef } from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
export * from './ControlledAutocomplete';
|
||||
export { default } from './ControlledAutocomplete';
|
||||
export {
|
||||
default as ControlledAutocomplete,
|
||||
default,
|
||||
} from './ControlledAutocomplete';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './ControlledCheckbox';
|
||||
export { default } from './ControlledCheckbox';
|
||||
export { default as ControlledCheckbox, default } from './ControlledCheckbox';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { SelectProps } from '@/ui/v2/Select';
|
||||
import Select from '@/ui/v2/Select';
|
||||
import { Select } from '@/ui/v2/Select';
|
||||
import type { ForwardedRef } from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
import type { FieldValues, UseControllerProps } from 'react-hook-form';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './ControlledSelect';
|
||||
export { default } from './ControlledSelect';
|
||||
export { default as ControlledSelect, default } from './ControlledSelect';
|
||||
|
||||
@@ -2,11 +2,11 @@ import DataGridBody from '@/components/common/DataGridBody';
|
||||
import DataGridFrame from '@/components/common/DataGridFrame';
|
||||
import type { DataGridHeaderProps } from '@/components/common/DataGridHeader';
|
||||
import DataGridHeader from '@/components/common/DataGridHeader';
|
||||
import DataBrowserEmptyState from '@/components/dataBrowser/DataBrowserEmptyState';
|
||||
import { DataGridProvider } from '@/context/DataGridContext';
|
||||
import { DataBrowserEmptyState } from '@/features/database/dataGrid/components/DataBrowserEmptyState';
|
||||
import type { DataBrowserGridColumn } from '@/features/database/dataGrid/types/dataBrowser';
|
||||
import type { UseDataGridOptions } from '@/hooks/useDataGrid';
|
||||
import useDataGrid from '@/hooks/useDataGrid';
|
||||
import type { DataBrowserGridColumn } from '@/types/dataBrowser';
|
||||
import ActivityIndicator from '@/ui/v2/ActivityIndicator';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import type { ForwardedRef } from 'react';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { DataGridProps } from '@/components/common/DataGrid';
|
||||
import DataGridCell from '@/components/common/DataGridCell';
|
||||
import type { DataBrowserGridColumn } from '@/features/database/dataGrid/types/dataBrowser';
|
||||
import useDataGridConfig from '@/hooks/useDataGridConfig';
|
||||
import type { DataBrowserGridColumn } from '@/types/dataBrowser';
|
||||
import type { BoxProps } from '@/ui/v2/Box';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import Button from '@/ui/v2/Button';
|
||||
|
||||
@@ -3,7 +3,7 @@ import type {
|
||||
ColumnType,
|
||||
DataBrowserGridCell,
|
||||
DataBrowserGridCellProps,
|
||||
} from '@/types/dataBrowser';
|
||||
} from '@/features/database/dataGrid/types/dataBrowser';
|
||||
import type { BoxProps } from '@/ui/v2/Box';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import Tooltip, { useTooltip } from '@/ui/v2/Tooltip';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { DataGridProps } from '@/components/common/DataGrid';
|
||||
import type { DataBrowserGridColumn } from '@/features/database/dataGrid/types/dataBrowser';
|
||||
import useDataGridConfig from '@/hooks/useDataGridConfig';
|
||||
import type { DataBrowserGridColumn } from '@/types/dataBrowser';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import Divider from '@/ui/v2/Divider';
|
||||
|
||||
@@ -2,8 +2,8 @@ import AudioPreview from '@/components/icons/AudioPreview';
|
||||
import { FileIcon } from '@/components/icons/FileIcon';
|
||||
import PDFPreview from '@/components/icons/PDFPreview';
|
||||
import VideoPreview from '@/components/icons/VideoPreview';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useAppClient } from '@/hooks/useAppClient';
|
||||
import { useAppClient } from '@/features/projects/hooks/useAppClient';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { Modal } from '@/ui/Modal';
|
||||
import ActivityIndicator from '@/ui/v2/ActivityIndicator';
|
||||
import Box from '@/ui/v2/Box';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { IconLinkProps } from '@/components/common/IconLink';
|
||||
import IconLink from '@/components/common/IconLink';
|
||||
import { Nav } from '@/components/dashboard/Nav';
|
||||
import useProjectRoutes from '@/hooks/common/useProjectRoutes';
|
||||
import { useProjectRoutes } from '@/features/projects/hooks/useProjectRoutes';
|
||||
import type { BoxProps } from '@/ui/v2/Box';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './FeedbackForm';
|
||||
export { default } from './FeedbackForm';
|
||||
export { default as FeedbackForm } from './FeedbackForm';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './Form';
|
||||
export { default } from './Form';
|
||||
export { default as Form, default } from './Form';
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
export * from './FormActivityIndicator';
|
||||
export { default } from './FormActivityIndicator';
|
||||
export {
|
||||
default,
|
||||
default as FormActivityIndicator,
|
||||
} from './FormActivityIndicator';
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
import Breadcrumbs from '@/components/common/Breadcrumbs';
|
||||
import FeedbackForm from '@/components/common/FeedbackForm';
|
||||
import LocalAccountMenu from '@/components/common/LocalAccountMenu';
|
||||
import Logo from '@/components/common/Logo';
|
||||
import MobileNav from '@/components/common/MobileNav';
|
||||
import NavLink from '@/components/common/NavLink';
|
||||
import { Breadcrumbs } from '@/components/common/Breadcrumbs';
|
||||
import { FeedbackForm } from '@/components/common/FeedbackForm';
|
||||
import { LocalAccountMenu } from '@/components/common/LocalAccountMenu';
|
||||
import { Logo } from '@/components/common/Logo';
|
||||
import { MobileNav } from '@/components/common/MobileNav';
|
||||
import { NavLink } from '@/components/common/NavLink';
|
||||
import { AccountMenu } from '@/components/dashboard/AccountMenu';
|
||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useIsPlatform } from '@/features/projects/hooks/useIsPlatform';
|
||||
import { ApplicationStatus } from '@/types/application';
|
||||
import { Box } from '@/ui/v2/Box';
|
||||
import { Chip } from '@/ui/v2/Chip';
|
||||
import { Dropdown } from '@/ui/v2/Dropdown';
|
||||
import { useRouter } from 'next/router';
|
||||
import type { DetailedHTMLProps, HTMLProps, PropsWithoutRef } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
export interface HeaderProps
|
||||
@@ -20,6 +24,25 @@ export interface HeaderProps
|
||||
export default function Header({ className, ...props }: HeaderProps) {
|
||||
const router = useRouter();
|
||||
const isPlatform = useIsPlatform();
|
||||
const { currentProject, refetch: refetchProject } =
|
||||
useCurrentWorkspaceAndProject();
|
||||
const isProjectUpdating =
|
||||
currentProject?.appStates[0]?.stateId === ApplicationStatus.Updating;
|
||||
|
||||
// Poll for project updates
|
||||
useEffect(() => {
|
||||
if (!isProjectUpdating) {
|
||||
return () => {};
|
||||
}
|
||||
|
||||
const interval = setInterval(async () => {
|
||||
await refetchProject();
|
||||
}, 5000);
|
||||
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, [isProjectUpdating, refetchProject]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
@@ -39,6 +62,10 @@ export default function Header({ className, ...props }: HeaderProps) {
|
||||
{(router.query.workspaceSlug || router.query.appSlug) && (
|
||||
<Breadcrumbs aria-label="Workspace breadcrumbs" />
|
||||
)}
|
||||
|
||||
{isProjectUpdating && (
|
||||
<Chip size="small" label="Updating" color="warning" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="hidden grid-flow-col items-center gap-2 sm:grid">
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { default } from './HighlightedText';
|
||||
export { default as HighlightedText } from './HighlightedText';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './InlineCode';
|
||||
export { default } from './InlineCode';
|
||||
export { default, default as InlineCode } from './InlineCode';
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import ThemeSwitcher from '@/components/common/ThemeSwitcher';
|
||||
import { ThemeSwitcher } from '@/components/common/ThemeSwitcher';
|
||||
import { Avatar } from '@/ui/Avatar';
|
||||
import { Box } from '@/ui/v2/Box';
|
||||
import { Divider } from '@/ui/v2/Divider';
|
||||
import { Dropdown } from '@/ui/v2/Dropdown';
|
||||
import IconButton from '@/ui/v2/IconButton';
|
||||
import UserIcon from '@/ui/v2/icons/UserIcon';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import { IconButton } from '@/ui/v2/IconButton';
|
||||
import { UserIcon } from '@/ui/v2/icons/UserIcon';
|
||||
import { Text } from '@/ui/v2/Text';
|
||||
import getConfig from 'next/config';
|
||||
|
||||
export default function LocalAccountMenu() {
|
||||
@@ -25,14 +28,38 @@ export default function LocalAccountMenu() {
|
||||
|
||||
<Dropdown.Content
|
||||
PaperProps={{
|
||||
className: 'mt-1 p-6 grid grid-flow-row gap-4 w-full max-w-xs',
|
||||
className: 'mt-1 grid grid-flow-row w-full max-w-xs',
|
||||
}}
|
||||
>
|
||||
<ThemeSwitcher label="Theme" />
|
||||
<Box className="grid grid-flow-col items-center justify-start gap-4 p-4">
|
||||
<Avatar name="Local User" className="h-10 w-10" />
|
||||
|
||||
<Text className="text-center text-xs" color="disabled">
|
||||
Dashboard Version: {publicRuntimeConfig?.version || 'n/a'}
|
||||
</Text>
|
||||
<Box className="grid grid-flow-row gap-0.5">
|
||||
<Text className="font-semibold">Local User</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Box className="grid grid-flow-row gap-2 p-2">
|
||||
<ThemeSwitcher
|
||||
label="Theme"
|
||||
variant="inline"
|
||||
fullWidth
|
||||
className="grid-cols-auto justify-between px-2"
|
||||
slotProps={{
|
||||
label: { className: '!text-sm+' },
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Box className="py-4">
|
||||
<Text className="text-center text-xs" color="disabled">
|
||||
Dashboard Version: {publicRuntimeConfig?.version || 'n/a'}
|
||||
</Text>
|
||||
</Box>
|
||||
</Dropdown.Content>
|
||||
</Dropdown.Root>
|
||||
);
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { default } from './LocalAccountMenu';
|
||||
export { default as LocalAccountMenu } from './LocalAccountMenu';
|
||||
|
||||
1
dashboard/src/components/common/Logo/index.ts
Normal file
1
dashboard/src/components/common/Logo/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as Logo } from './Logo';
|
||||
@@ -1 +1 @@
|
||||
export { default } from './MaintenanceAlert';
|
||||
export { default as MaintenanceAlert } from './MaintenanceAlert';
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
import { ChangePasswordModal } from '@/components/applications/ChangePasswordModal';
|
||||
import FeedbackForm from '@/components/common/FeedbackForm';
|
||||
import NavLink from '@/components/common/NavLink';
|
||||
import ThemeSwitcher from '@/components/common/ThemeSwitcher';
|
||||
import { FeedbackForm } from '@/components/common/FeedbackForm';
|
||||
import { NavLink } from '@/components/common/NavLink';
|
||||
import { ThemeSwitcher } from '@/components/common/ThemeSwitcher';
|
||||
import { Nav } from '@/components/dashboard/Nav';
|
||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||
import useProjectRoutes from '@/hooks/common/useProjectRoutes';
|
||||
import { useIsPlatform } from '@/features/projects/hooks/useIsPlatform';
|
||||
import { useProjectRoutes } from '@/features/projects/hooks/useProjectRoutes';
|
||||
import { useNavigationVisible } from '@/hooks/useNavigationVisible';
|
||||
import { Modal } from '@/ui/Modal';
|
||||
import type { ButtonProps } from '@/ui/v2/Button';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import Divider from '@/ui/v2/Divider';
|
||||
import Drawer from '@/ui/v2/Drawer';
|
||||
import { Button } from '@/ui/v2/Button';
|
||||
import { Divider } from '@/ui/v2/Divider';
|
||||
import { Drawer } from '@/ui/v2/Drawer';
|
||||
import { Dropdown } from '@/ui/v2/Dropdown';
|
||||
import MenuIcon from '@/ui/v2/icons/MenuIcon';
|
||||
import XIcon from '@/ui/v2/icons/XIcon';
|
||||
import List from '@/ui/v2/List';
|
||||
import { MenuIcon } from '@/ui/v2/icons/MenuIcon';
|
||||
import { XIcon } from '@/ui/v2/icons/XIcon';
|
||||
import { List } from '@/ui/v2/List';
|
||||
import type { ListItemButtonProps } from '@/ui/v2/ListItem';
|
||||
import { ListItem } from '@/ui/v2/ListItem';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import { Text } from '@/ui/v2/Text';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { useSignOut } from '@nhost/nextjs';
|
||||
import getConfig from 'next/config';
|
||||
@@ -86,7 +84,6 @@ export default function MobileNav({ className, ...props }: MobileNavProps) {
|
||||
const { allRoutes } = useProjectRoutes();
|
||||
const shouldDisplayNav = useNavigationVisible();
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const [showChangePasswordModal, setShowChangePasswordModal] = useState(false);
|
||||
const { signOut } = useSignOut();
|
||||
const apolloClient = useApolloClient();
|
||||
const router = useRouter();
|
||||
@@ -94,14 +91,6 @@ export default function MobileNav({ className, ...props }: MobileNavProps) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
showModal={showChangePasswordModal}
|
||||
close={() => setShowChangePasswordModal(false)}
|
||||
>
|
||||
{/** TODO: Make use of `DialogProvider` here or create a separate page. */}
|
||||
<ChangePasswordModal close={() => setShowChangePasswordModal(false)} />
|
||||
</Modal>
|
||||
|
||||
<Button
|
||||
variant="borderless"
|
||||
color="secondary"
|
||||
@@ -228,15 +217,14 @@ export default function MobileNav({ className, ...props }: MobileNavProps) {
|
||||
<List className="grid grid-flow-row gap-2">
|
||||
<ListItem.Root>
|
||||
<ListItem.Button
|
||||
component={NavLink}
|
||||
variant="borderless"
|
||||
color="secondary"
|
||||
className="w-full justify-start border-none px-2 py-2.5 text-[16px]"
|
||||
onClick={() => {
|
||||
setMenuOpen(false);
|
||||
setShowChangePasswordModal(true);
|
||||
}}
|
||||
href="/account"
|
||||
onClick={() => setMenuOpen(false)}
|
||||
>
|
||||
Change Password
|
||||
Settings
|
||||
</ListItem.Button>
|
||||
</ListItem.Root>
|
||||
|
||||
@@ -245,7 +233,7 @@ export default function MobileNav({ className, ...props }: MobileNavProps) {
|
||||
<ListItem.Root>
|
||||
<ListItem.Button
|
||||
variant="borderless"
|
||||
color="secondary"
|
||||
sx={{ color: 'error.main' }}
|
||||
className="justify-start border-none px-2 py-2.5 text-[16px]"
|
||||
onClick={async () => {
|
||||
setMenuOpen(false);
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './MobileNav';
|
||||
export { default } from './MobileNav';
|
||||
export { default as MobileNav } from './MobileNav';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './NavLink';
|
||||
export { default } from './NavLink';
|
||||
export { default as NavLink, default } from './NavLink';
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
export * from './Pagination';
|
||||
export { default } from './Pagination';
|
||||
|
||||
export { default as Pagination } from './Pagination';
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
export * from './RetryableErrorBoundary';
|
||||
export { default } from './RetryableErrorBoundary';
|
||||
export {
|
||||
default,
|
||||
default as RetryableErrorBoundary,
|
||||
} from './RetryableErrorBoundary';
|
||||
|
||||
@@ -22,6 +22,7 @@ export default function ThemeSwitcher({
|
||||
onChange?.(event, value);
|
||||
}}
|
||||
slotProps={{
|
||||
...props?.slotProps,
|
||||
listbox: { className: 'min-w-0 w-full' },
|
||||
popper: {
|
||||
disablePortal: false,
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './ThemeSwitcher';
|
||||
export { default } from './ThemeSwitcher';
|
||||
export { default as ThemeSwitcher } from './ThemeSwitcher';
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
import { ChangePasswordModal } from '@/components/applications/ChangePasswordModal';
|
||||
import ThemeSwitcher from '@/components/common/ThemeSwitcher';
|
||||
import { Avatar } from '@/ui/Avatar';
|
||||
import { Modal } from '@/ui/Modal';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import { Dropdown, useDropdown } from '@/ui/v2/Dropdown';
|
||||
import PowerIcon from '@/ui/v2/icons/PowerIcon';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { useSignOut, useUserData } from '@nhost/nextjs';
|
||||
import getConfig from 'next/config';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
interface AccountMenuContentProps {
|
||||
onChangePasswordClick: VoidFunction;
|
||||
}
|
||||
|
||||
function AccountMenuContent({
|
||||
onChangePasswordClick,
|
||||
}: AccountMenuContentProps) {
|
||||
const user = useUserData();
|
||||
const { signOut } = useSignOut();
|
||||
const router = useRouter();
|
||||
const apolloClient = useApolloClient();
|
||||
const { handleClose } = useDropdown();
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
|
||||
return (
|
||||
<Box className="relative grid w-full grid-flow-row gap-5 p-6">
|
||||
<div className="grid grid-flow-row justify-center">
|
||||
<Avatar
|
||||
className="mx-auto mb-2 h-16 w-16 rounded-full"
|
||||
name={user?.displayName}
|
||||
avatarUrl={user?.avatarUrl}
|
||||
/>
|
||||
|
||||
<Text variant="h3" component="h2" className="text-center">
|
||||
{user?.displayName}
|
||||
</Text>
|
||||
|
||||
<Text className="text-center font-medium">{user?.email}</Text>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-flow-row gap-2">
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={() => {
|
||||
onChangePasswordClick();
|
||||
handleClose();
|
||||
}}
|
||||
>
|
||||
Change Password
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={async () => {
|
||||
await apolloClient.clearStore();
|
||||
await signOut();
|
||||
await router.push('/signin');
|
||||
}}
|
||||
endIcon={<PowerIcon className="mr-1 h-4 w-4" />}
|
||||
>
|
||||
Sign Out
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<ThemeSwitcher label="Theme" />
|
||||
|
||||
<Text className="text-center text-xs" color="disabled">
|
||||
Dashboard Version: {publicRuntimeConfig?.version || 'n/a'}
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export function AccountMenu() {
|
||||
const user = useUserData();
|
||||
const [changePasswordModal, setChangePasswordModal] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (window.location.hash.search('type=passwordReset') !== -1) {
|
||||
setChangePasswordModal(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
showModal={changePasswordModal}
|
||||
close={() => setChangePasswordModal(false)}
|
||||
>
|
||||
<ChangePasswordModal close={() => setChangePasswordModal(false)} />
|
||||
</Modal>
|
||||
|
||||
<Dropdown.Root>
|
||||
<Dropdown.Trigger hideChevron className="rounded-full">
|
||||
<Avatar
|
||||
className="h-7 w-7 self-center rounded-full"
|
||||
name={user?.displayName}
|
||||
avatarUrl={user?.avatarUrl}
|
||||
/>
|
||||
</Dropdown.Trigger>
|
||||
|
||||
<Dropdown.Content PaperProps={{ className: 'mt-1 max-w-xs w-full' }}>
|
||||
<AccountMenuContent
|
||||
onChangePasswordClick={() => setChangePasswordModal(true)}
|
||||
/>
|
||||
</Dropdown.Content>
|
||||
</Dropdown.Root>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default AccountMenu;
|
||||
113
dashboard/src/components/dashboard/AccountMenu/AccountMenu.tsx
Normal file
113
dashboard/src/components/dashboard/AccountMenu/AccountMenu.tsx
Normal file
@@ -0,0 +1,113 @@
|
||||
import { NavLink } from '@/components/common/NavLink';
|
||||
import { ThemeSwitcher } from '@/components/common/ThemeSwitcher';
|
||||
import { Avatar } from '@/ui/Avatar';
|
||||
import { Box } from '@/ui/v2/Box';
|
||||
import { Button } from '@/ui/v2/Button';
|
||||
import { Divider } from '@/ui/v2/Divider';
|
||||
import { Dropdown, useDropdown } from '@/ui/v2/Dropdown';
|
||||
import { Text } from '@/ui/v2/Text';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { useSignOut, useUserData } from '@nhost/nextjs';
|
||||
import getConfig from 'next/config';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
function AccountMenuContent() {
|
||||
const user = useUserData();
|
||||
const { signOut } = useSignOut();
|
||||
const router = useRouter();
|
||||
const apolloClient = useApolloClient();
|
||||
const { handleClose } = useDropdown();
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
|
||||
return (
|
||||
<Box className="grid grid-flow-row">
|
||||
<Box className="grid grid-flow-col items-center justify-start gap-4 p-4">
|
||||
<Avatar
|
||||
name={user?.displayName}
|
||||
avatarUrl={user?.avatarUrl}
|
||||
className="h-10 w-10"
|
||||
/>
|
||||
|
||||
<Box className="grid grid-flow-row gap-0.5">
|
||||
<Text className="font-semibold">{user?.displayName}</Text>
|
||||
<Text color="secondary" className="text-sm">
|
||||
{user?.email}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Box className="p-2">
|
||||
<ThemeSwitcher
|
||||
label="Theme"
|
||||
variant="inline"
|
||||
fullWidth
|
||||
className="grid-cols-auto justify-between px-2"
|
||||
slotProps={{
|
||||
label: { className: '!text-sm+' },
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Box className="grid grid-flow-row gap-1 p-2">
|
||||
<Button
|
||||
variant="borderless"
|
||||
color="secondary"
|
||||
className="w-full justify-start"
|
||||
LinkComponent={NavLink}
|
||||
href="/account"
|
||||
onClick={handleClose}
|
||||
>
|
||||
Account Settings
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
color="error"
|
||||
variant="borderless"
|
||||
className="w-full justify-start"
|
||||
onClick={async () => {
|
||||
handleClose();
|
||||
await apolloClient.clearStore();
|
||||
await signOut();
|
||||
await router.push('/signin');
|
||||
}}
|
||||
>
|
||||
Sign out
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Box className="py-4">
|
||||
<Text className="text-center text-xs" color="disabled">
|
||||
Dashboard Version: {publicRuntimeConfig?.version || 'n/a'}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function AccountMenu() {
|
||||
const user = useUserData();
|
||||
|
||||
return (
|
||||
<Dropdown.Root>
|
||||
<Dropdown.Trigger hideChevron className="rounded-full">
|
||||
<Avatar
|
||||
className="h-7 w-7 self-center rounded-full"
|
||||
name={user?.displayName}
|
||||
avatarUrl={user?.avatarUrl}
|
||||
/>
|
||||
</Dropdown.Trigger>
|
||||
|
||||
<Dropdown.Content PaperProps={{ className: 'mt-1 max-w-xs w-full' }}>
|
||||
<AccountMenuContent />
|
||||
</Dropdown.Content>
|
||||
</Dropdown.Root>
|
||||
);
|
||||
}
|
||||
|
||||
export default AccountMenu;
|
||||
1
dashboard/src/components/dashboard/AccountMenu/index.ts
Normal file
1
dashboard/src/components/dashboard/AccountMenu/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as AccountMenu } from './AccountMenu';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './BaseColumnForm';
|
||||
export { default } from './BaseColumnForm';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './BaseForeignKeyForm';
|
||||
export { BaseForeignKeyForm as default } from './BaseForeignKeyForm';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './BaseRecordForm';
|
||||
export { default } from './BaseRecordForm';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './BaseTableForm';
|
||||
export { default } from './BaseTableForm';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './ColumnAutocomplete';
|
||||
export { default } from './ColumnAutocomplete';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './CreateColumnForm';
|
||||
export { default } from './CreateColumnForm';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './CreateForeignKeyForm';
|
||||
export { default } from './CreateForeignKeyForm';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './CreateRecordForm';
|
||||
export { default } from './CreateRecordForm';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './CreateTableForm';
|
||||
export { default } from './CreateTableForm';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './DataBrowserEmptyState';
|
||||
export { default } from './DataBrowserEmptyState';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './DataBrowserGrid';
|
||||
export { default } from './DataBrowserGrid';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './DataBrowserGridControls';
|
||||
export { default } from './DataBrowserGridControls';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './DataBrowserLayout';
|
||||
export { default } from './DataBrowserLayout';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './DataBrowserSidebar';
|
||||
export { default } from './DataBrowserSidebar';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './DatabaseRecordInputGroup';
|
||||
export { default } from './DatabaseRecordInputGroup';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './EditColumnForm';
|
||||
export { default } from './EditColumnForm';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './EditForeignKeyForm';
|
||||
export { default } from './EditForeignKeyForm';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './EditPermissionsForm';
|
||||
export { default } from './EditPermissionsForm';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './EditTableForm';
|
||||
export { default } from './EditTableForm';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './RuleGroupEditor';
|
||||
export { default } from './RuleGroupEditor';
|
||||
@@ -1,2 +1,5 @@
|
||||
export * from './AppDeploymentDuration';
|
||||
export { default } from './AppDeploymentDuration';
|
||||
export {
|
||||
default as AppDeploymentDuration,
|
||||
default,
|
||||
} from './AppDeploymentDuration';
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import NavLink from '@/components/common/NavLink';
|
||||
import AppDeploymentDuration from '@/components/deployments/AppDeploymentDuration';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { NavLink } from '@/components/common/NavLink';
|
||||
import { AppDeploymentDuration } from '@/components/deployments/AppDeploymentDuration';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { Avatar } from '@/ui/Avatar';
|
||||
import type { DeploymentStatus } from '@/ui/StatusCircle';
|
||||
import { StatusCircle } from '@/ui/StatusCircle';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import { Button } from '@/ui/v2/Button';
|
||||
import { Chip } from '@/ui/v2/Chip';
|
||||
import { ArrowCounterclockwiseIcon } from '@/ui/v2/icons/ArrowCounterclockwiseIcon';
|
||||
import { ChevronRightIcon } from '@/ui/v2/icons/ChevronRightIcon';
|
||||
import { ListItem } from '@/ui/v2/ListItem';
|
||||
import { Tooltip } from '@/ui/v2/Tooltip';
|
||||
import ArrowCounterclockwiseIcon from '@/ui/v2/icons/ArrowCounterclockwiseIcon';
|
||||
import ChevronRightIcon from '@/ui/v2/icons/ChevronRightIcon';
|
||||
import { getServerError } from '@/utils/settings/getServerError';
|
||||
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
||||
import type { DeploymentRowFragment } from '@/utils/__generated__/graphql';
|
||||
import {
|
||||
GetAllWorkspacesAndProjectsDocument,
|
||||
useInsertDeploymentMutation,
|
||||
} from '@/utils/__generated__/graphql';
|
||||
import getServerError from '@/utils/settings/getServerError';
|
||||
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
||||
import { formatDistanceToNowStrict, parseISO } from 'date-fns';
|
||||
import type { MouseEvent } from 'react';
|
||||
import { toast } from 'react-hot-toast';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './DeploymentListItem';
|
||||
export { default } from './DeploymentListItem';
|
||||
export { default, default as DeploymentListItem } from './DeploymentListItem';
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './FilesDataGrid';
|
||||
export { default } from './FilesDataGrid';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './FilesDataGridControls';
|
||||
export { default } from './FilesDataGridControls';
|
||||
@@ -1,16 +1,16 @@
|
||||
import { useDialog } from '@/components/common/DialogProvider';
|
||||
import Form from '@/components/common/Form';
|
||||
import { Form } from '@/components/common/Form';
|
||||
import type { DialogFormProps } from '@/types/common';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import Input from '@/ui/v2/Input';
|
||||
import { Button } from '@/ui/v2/Button';
|
||||
import { Input } from '@/ui/v2/Input';
|
||||
import { slugifyString } from '@/utils/helpers';
|
||||
import { getServerError } from '@/utils/settings/getServerError';
|
||||
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
||||
import {
|
||||
GetAllWorkspacesAndProjectsDocument,
|
||||
useInsertWorkspaceMutation,
|
||||
useUpdateWorkspaceMutation,
|
||||
} 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 { useUserData } from '@nhost/nextjs';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useIsPlatform } from '@/features/projects/hooks/useIsPlatform';
|
||||
import {
|
||||
GetAllWorkspacesAndProjectsDocument,
|
||||
GetWorkspaceMemberInvitesToManageDocument,
|
||||
useGetWorkspaceMemberInvitesToManageQuery,
|
||||
} from '@/generated/graphql';
|
||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||
import { useSubmitState } from '@/hooks/useSubmitState';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import Button from '@/ui/v2/Button';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useInsertFeedbackOneMutation } from '@/generated/graphql';
|
||||
import { Avatar } from '@/ui/Avatar';
|
||||
import Button from '@/ui/v2/Button';
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import Header from '@/components/common/Header';
|
||||
import HighlightedText from '@/components/common/HighlightedText';
|
||||
import RetryableErrorBoundary from '@/components/common/RetryableErrorBoundary';
|
||||
import { HighlightedText } from '@/components/common/HighlightedText';
|
||||
import { RetryableErrorBoundary } from '@/components/common/RetryableErrorBoundary';
|
||||
import { InviteAnnounce } from '@/components/home/InviteAnnounce';
|
||||
import type { BaseLayoutProps } from '@/components/layout/BaseLayout';
|
||||
import BaseLayout from '@/components/layout/BaseLayout';
|
||||
import Container from '@/components/layout/Container';
|
||||
import useIsHealthy from '@/hooks/common/useIsHealthy';
|
||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||
import { useIsHealthy } from '@/features/projects/hooks/useIsHealthy';
|
||||
import { useIsPlatform } from '@/features/projects/hooks/useIsPlatform';
|
||||
import ActivityIndicator from '@/ui/v2/ActivityIndicator';
|
||||
import Link from '@/ui/v2/Link';
|
||||
import Text from '@/ui/v2/Text';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './AuthenticatedLayout';
|
||||
export { default } from './AuthenticatedLayout';
|
||||
export { default as AuthenticatedLayout, default } from './AuthenticatedLayout';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './Container';
|
||||
export { default } from './Container';
|
||||
export { default as Container, default } from './Container';
|
||||
|
||||
@@ -2,9 +2,9 @@ import DesktopNav from '@/components/common/DesktopNav';
|
||||
import { LoadingScreen } from '@/components/common/LoadingScreen';
|
||||
import type { AuthenticatedLayoutProps } from '@/components/layout/AuthenticatedLayout';
|
||||
import AuthenticatedLayout from '@/components/layout/AuthenticatedLayout';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||
import useProjectRoutes from '@/hooks/common/useProjectRoutes';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useIsPlatform } from '@/features/projects/hooks/useIsPlatform';
|
||||
import { useProjectRoutes } from '@/features/projects/hooks/useProjectRoutes';
|
||||
import { useNavigationVisible } from '@/hooks/useNavigationVisible';
|
||||
import useNotFoundRedirect from '@/hooks/useNotFoundRedirect';
|
||||
import type { BoxProps } from '@/ui/v2/Box';
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './ProjectLayout';
|
||||
export { default } from './ProjectLayout';
|
||||
export { default as ProjectLayout, default } from './ProjectLayout';
|
||||
|
||||
@@ -3,7 +3,7 @@ import RetryableErrorBoundary from '@/components/common/RetryableErrorBoundary';
|
||||
import type { BaseLayoutProps } from '@/components/layout/BaseLayout';
|
||||
import BaseLayout from '@/components/layout/BaseLayout';
|
||||
import Container from '@/components/layout/Container';
|
||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||
import { useIsPlatform } from '@/features/projects/hooks/useIsPlatform';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import ThemeProvider from '@/ui/v2/ThemeProvider';
|
||||
import GlobalStyles from '@mui/material/GlobalStyles';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import LogsDatePicker from '@/components/logs/LogsDatePicker';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/hooks/useCurrentWorkspaceAndProject';
|
||||
import type { AvailableLogsServices, LogsCustomInterval } from '@/types/logs';
|
||||
import type { BoxProps } from '@/ui/v2/Box';
|
||||
import Box from '@/ui/v2/Box';
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './InfoCard';
|
||||
export { default } from './InfoCard';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './OverviewCard';
|
||||
export { default } from './OverviewCard';
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './OverviewDeployments';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './OverviewDocumentation';
|
||||
export { default } from './OverviewDocumentation';
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './OverviewMetrics';
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './OverviewProjectInfo';
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './OverviewRepository';
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './OverviewTopBar';
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user