Skip to content

Commit

Permalink
Merge pull request #449 from aXenDeveloper/admin/diagnostic_tools
Browse files Browse the repository at this point in the history
feat(frontend): Add diagnostic tools view in AdminCP
  • Loading branch information
aXenDeveloper authored Aug 14, 2024
2 parents 0ec649a + b4a4e01 commit e1e82bc
Show file tree
Hide file tree
Showing 16 changed files with 195 additions and 39 deletions.
4 changes: 4 additions & 0 deletions apps/docs/content/docs/guides/diagnostic.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: Diagnostic Tools
description: How to use diagnostic tools to debug and monitor your app.
---
2 changes: 1 addition & 1 deletion apps/docs/content/docs/ui/alert-dialog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ import {
AlertDialogTrigger,
} from 'vitnode-frontend/components/ui/alert-dialog';

const Content = React.lazy(() =>
const Content = React.lazy(async () =>
import('./content').then(module => ({
default: module.ContentTest,
})),
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/ui/dialog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ import {
} from 'vitnode-frontend/components/ui/dialog';
import { Loader } from 'vitnode-frontend/components/ui/loader';

const Content = React.lazy(() =>
const Content = React.lazy(async () =>
import('./content').then(module => ({
default: module.ContentTest,
})),
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "GPL-3.0 license",
"scripts": {
"config:init": "vitnode-frontend init",
"dev": "next dev --turbo",
"dev": "rm -rf .next/cache && next dev --turbo",
"dev:turbo": "next dev --turbo",
"build": "next build",
"analyze": "cross-env ANALYZE=true pnpm build",
Expand Down
10 changes: 10 additions & 0 deletions apps/frontend/plugins/admin/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@
"submit": "Read How To Rebuild"
},
"core": {
"diagnostic": {
"title": "Diagnostic Tools",
"desc": "Use these tools to diagnose and fix common issues with your website.",
"clear_cache": {
"title": "Clear Cache",
"desc": "This action clean up the cache of your website. This can help fix issues with your website but may slow down your website temporarily.",
"confirm": "Yes, clear cache",
"success": "Cache has been cleared."
}
},
"email": {
"hello": "Hello",
"footer": "You're receiving this email because your account activity triggered this email. Please do not reply to this email. If you have any questions, please contact us at:"
Expand Down
60 changes: 40 additions & 20 deletions packages/backend/scripts/update-plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as fs from 'fs';
import { join } from 'path';

import { NodePgDatabase } from 'drizzle-orm/node-postgres';
import { eq } from 'drizzle-orm';
import { eq, sql } from 'drizzle-orm';

import { ConfigPlugin } from '../src/providers/plugins.type';
import coreSchemaDatabase from '../src/database';
Expand All @@ -25,6 +25,13 @@ export const updatePlugins = async ({
.filter(plugin => !['core', 'plugins.module.ts'].includes(plugin));

await db.transaction(async tx => {
const pluginsFromDatabase = await tx.query.core_plugins.findMany({
columns: {
code: true,
id: true,
},
});

await Promise.all(
plugins.map(async (code, index) => {
const pluginPath = join(pluginsPath, code);
Expand All @@ -36,9 +43,9 @@ export const updatePlugins = async ({
isDefaultIndex = index;
}

const plugin = await tx.query.core_plugins.findFirst({
where: (table, { eq }) => eq(table.code, code),
});
const plugin = pluginsFromDatabase.find(
plugin => plugin.code === config.code,
);

if (plugin) {
await tx
Expand All @@ -54,23 +61,36 @@ export const updatePlugins = async ({
version_code: config.version_code,
})
.where(eq(core_plugins.id, plugin.id));

return;
} else {
await tx.insert(core_plugins).values([
{
name: config.name,
description: config.description,
code: config.code,
support_url: config.support_url,
author: config.author,
author_url: config.author_url,
allow_default: config.allow_default,
version: config.version,
version_code: config.version_code,
default: isDefaultIndex === index && !defaultPlugin,
},
]);
}
await tx.insert(core_plugins).values([
{
name: config.name,
description: config.description,
code: config.code,
support_url: config.support_url,
author: config.author,
author_url: config.author_url,
allow_default: config.allow_default,
version: config.version,
version_code: config.version_code,
default: isDefaultIndex === index && !defaultPlugin,
},
]);

await tx.execute(sql`commit`);
}),
);

// Remove plugins that are not in the plugins folder
const pluginsToDelete = pluginsFromDatabase.filter(
plugin => !plugins.includes(plugin.code),
);

await Promise.all(
pluginsToDelete.map(async plugin => {
await tx.delete(core_plugins).where(eq(core_plugins.id, plugin.id));
await tx.execute(sql`commit`);
}),
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { ChangeFilesAdminPluginsService } from '../helpers/files/change/change.s

import { InternalDatabaseService } from '@/utils/database/internal_database.service';
import { CustomError, NotFoundError } from '@/errors';
import { core_migrations } from '@/database/schema/files';
import { ABSOLUTE_PATHS_BACKEND } from '@/index';
import { core_plugins } from '@/database/schema/plugins';
import { setRebuildRequired } from '@/functions/rebuild-required';
Expand Down Expand Up @@ -67,10 +66,8 @@ export class DeleteAdminPluginsService {
message: `Error deleting tables for plugin ${code}`,
});
}
// Delete migrations
await this.databaseService.db
.delete(core_migrations)
.where(eq(core_migrations.plugin, code));
// Generate migrations
// TODO: Generate migrations

// Change files when delete
this.changeFilesService.changeFilesWhenDelete({ code });
Expand Down
10 changes: 0 additions & 10 deletions packages/backend/src/database/schema/files.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import {
bigint,
index,
integer,
pgTable,
serial,
text,
timestamp,
varchar,
} from 'drizzle-orm/pg-core';
Expand Down Expand Up @@ -72,11 +70,3 @@ export const core_files_using_relations = relations(
}),
}),
);

export const core_migrations = pgTable('core_migrations', {
id: serial('id').primaryKey(),
hash: text('hash').notNull(),
plugin: varchar('plugin', { length: 255 }).notNull(),
created_migration: bigint('created_migration', { mode: 'bigint' }),
created: timestamp('created').notNull().defaultNow(),
});
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export const createPackagesJSON = ({
private: true,
scripts: {
'config:init': 'vitnode-frontend init',
dev: 'vitnode-frontend init && next dev --turbo',
dev: 'rm -rf .next/cache && vitnode-frontend init && next dev --turbo',
build: 'next build',
start: 'next start',
lint: 'eslint .',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import {
GitBranch,
Globe,
HammerIcon,
Home,
LogOut,
SquareArrowOutUpRight,
Expand Down Expand Up @@ -71,6 +72,12 @@ export const AvatarAsideAuthAdmin = () => {
<span>{tCore('user-bar.my_profile')}</span>
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link href="/admin/core/diagnostic">
<HammerIcon />
<span>{t('core.diagnostic.title')}</span>
</Link>
</DropdownMenuItem>
</DropdownMenuGroup>

<DropdownMenuSeparator />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use client';

import { ClearCacheActionDiagnostic } from './clear_cache/clear_cache';

export const ActionsDiagnosticTools = () => {
return <ClearCacheActionDiagnostic />;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { EraserIcon } from 'lucide-react';
import { useTranslations } from 'next-intl';
import React from 'react';

import {
AlertDialog,
AlertDialogContent,
AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import { Loader } from '@/components/ui/loader';

const Content = React.lazy(async () =>
import('./content').then(module => ({
default: module.ContentClearCacheActionDiagnostic,
})),
);

export const ClearCacheActionDiagnostic = () => {
const t = useTranslations('admin.core.diagnostic.clear_cache');

return (
<>
<AlertDialog>
<AlertDialogTrigger asChild>
<Button>
<EraserIcon />
{t('title')}
</Button>
</AlertDialogTrigger>

<AlertDialogContent>
<React.Suspense fallback={<Loader />}>
<Content />
</React.Suspense>
</AlertDialogContent>
</AlertDialog>
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useTranslations } from 'next-intl';
import { toast } from 'sonner';

import {
AlertDialogAction,
AlertDialogCancel,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import { mutationApi } from './hooks/mutation-api';

export const ContentClearCacheActionDiagnostic = () => {
const t = useTranslations('admin.core.diagnostic.clear_cache');
const tCore = useTranslations('core');

return (
<>
<AlertDialogHeader>
<AlertDialogTitle>{tCore('are_you_sure')}</AlertDialogTitle>
<AlertDialogDescription>{t('desc')}</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>{tCore('cancel')}</AlertDialogCancel>
<AlertDialogAction asChild>
<Button
variant="destructive"
onClick={async () => {
await mutationApi();

toast.success(t('success'));
}}
>
{t('confirm')}
</Button>
</AlertDialogAction>
</AlertDialogFooter>
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use server';

import { revalidatePath } from 'next/cache';

export const mutationApi = async () => {
revalidatePath('/', 'layout');
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Metadata } from 'next';
import { useTranslations } from 'next-intl';
import { getTranslations } from 'next-intl/server';

import { HeaderContent } from '@/components/ui/header-content';
import { ActionsDiagnosticTools } from './actions/actions';

export const generateMetadataDiagnosticAdmin = async (): Promise<Metadata> => {
const t = await getTranslations('admin.core.diagnostic');

return {
title: t('title'),
};
};

export const DiagnosticToolsView = () => {
const t = useTranslations('admin.core.diagnostic');

return (
<HeaderContent h1={t('title')} desc={t('desc')}>
<ActionsDiagnosticTools />
</HeaderContent>
);
};
8 changes: 8 additions & 0 deletions packages/frontend/src/views/admin/views/slug.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ import {
generateMetadataPluginsAdmin,
PluginsAdminView,
} from './core/plugins/plugins-admin-view';
import {
DiagnosticToolsView,
generateMetadataDiagnosticAdmin,
} from './core/diagnostic/diagnostic-tools-view';

export interface SlugAdminViewProps {
params: { locale: string; slug: string[] };
Expand All @@ -66,6 +70,8 @@ export const generateMetadataSlugAdmin = async ({
switch (slug[0]) {
case 'core':
switch (slug[1]) {
case 'diagnostic':
return generateMetadataDiagnosticAdmin();
case 'advanced':
switch (slug[2]) {
case 'files':
Expand Down Expand Up @@ -161,6 +167,8 @@ export const SlugAdminView = (props: SlugAdminViewProps) => {
return <LangsCoreAdminView {...props} />;
case 'plugins':
return <PluginsAdminView {...props} />;
case 'diagnostic':
return <DiagnosticToolsView />;
case 'dashboard':
return <DashboardCoreAdminView />;
}
Expand Down

0 comments on commit e1e82bc

Please sign in to comment.