feat: add markdown editor for page description

This commit is contained in:
moonrailgun 2024-04-30 19:44:51 +08:00
parent c950e4a3f8
commit 7e1faf8258
19 changed files with 863 additions and 38 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
import React from 'react';
import { Editor, EditorProps } from '@bytemd/react';
import { plugins } from './plugins';
import 'bytemd/dist/index.css';
import './style.less';
import { useLocale } from './useLocale';
interface MarkdownEditorProps extends EditorProps {}
export const MarkdownEditor: React.FC<MarkdownEditorProps> = React.memo(
(props) => {
const locale = useLocale();
return <Editor plugins={plugins} locale={locale} {...props} />;
}
);
MarkdownEditor.displayName = 'MarkdownEditor';

View File

@ -0,0 +1,9 @@
import loadable from '@loadable/component';
export const MarkdownEditor = loadable(() =>
import('./editor').then((module) => module.MarkdownEditor)
);
export const MarkdownViewer = loadable(() =>
import('./viewer').then((module) => module.MarkdownViewer)
);

View File

@ -0,0 +1,6 @@
import gfm from '@bytemd/plugin-gfm';
export const plugins = [
gfm(),
// Add more plugins here
];

View File

@ -0,0 +1,42 @@
.bytemd .bytemd-toolbar-right [bytemd-tippy-path='5'] {
// Hidden github icon
display: none;
}
.bytemd-fullscreen.bytemd {
z-index: 99;
}
.dark {
.bytemd {
@apply bg-zinc-900 border-zinc-800 text-foreground;
.bytemd-toolbar {
@apply bg-zinc-900 border-zinc-800;
.bytemd-toolbar-icon:hover {
@apply bg-muted;
}
}
.bytemd-preview {
@apply border-zinc-800;
}
.CodeMirror {
@apply bg-zinc-900 text-foreground;
.CodeMirror-cursor {
@apply border-foreground;
}
.CodeMirror-selected {
@apply bg-zinc-800;
}
}
.bytemd-status {
@apply border-zinc-800;
}
}
}

View File

@ -0,0 +1,54 @@
/**
* TODO: wait for i18n with namespace
*/
export function useLocale() {
return {
bold: 'Bold',
boldText: 'bold text',
cheatsheet: 'Markdown Cheatsheet',
closeHelp: 'Close help',
closeToc: 'Close table of contents',
code: 'Code',
codeBlock: 'Code block',
codeLang: 'lang',
codeText: 'code',
exitFullscreen: 'Exit fullscreen',
exitPreviewOnly: 'Exit preview only',
exitWriteOnly: 'Exit write only',
fullscreen: 'Fullscreen',
h1: 'Heading 1',
h2: 'Heading 2',
h3: 'Heading 3',
h4: 'Heading 4',
h5: 'Heading 5',
h6: 'Heading 6',
headingText: 'heading',
help: 'Help',
hr: 'Horizontal rule',
image: 'Image',
imageAlt: 'alt',
imageTitle: 'title',
italic: 'Italic',
italicText: 'italic text',
limited: 'The maximum character limit has been reached',
lines: 'Lines',
link: 'Link',
linkText: 'link text',
ol: 'Ordered list',
olItem: 'item',
preview: 'Preview',
previewOnly: 'Preview only',
quote: 'Quote',
quotedText: 'quoted text',
shortcuts: 'Shortcuts',
source: 'Source code',
sync: 'Scroll sync',
toc: 'Table of contents',
top: 'Scroll to top',
ul: 'Unordered list',
ulItem: 'item',
words: 'Words',
write: 'Write',
writeOnly: 'Write only',
};
}

View File

@ -0,0 +1,15 @@
import React from 'react';
import { Viewer } from '@bytemd/react';
import { plugins } from './plugins';
import 'bytemd/dist/index.css';
import './style.less';
interface MarkdownViewerProps {
value: string;
}
export const MarkdownViewer: React.FC<MarkdownViewerProps> = React.memo(
(props) => {
return <Viewer plugins={plugins} value={props.value ?? ''} />;
}
);
MarkdownViewer.displayName = 'MarkdownViewer';

View File

@ -5,12 +5,14 @@ import { domainValidator, urlSlugValidator } from '../../../utils/validator';
import { useTranslation } from '@i18next-toolkit/react';
import { Button } from '@/components/ui/button';
import { LuMinusCircle, LuPlus } from 'react-icons/lu';
import { MarkdownEditor } from '@/components/MarkdownEditor';
const { Text } = Typography;
export interface MonitorStatusPageEditFormValues {
title: string;
slug: string;
description: string;
monitorList: PrismaJson.MonitorStatusPageList;
domain: string;
}
@ -72,6 +74,10 @@ export const MonitorStatusPageEditForm: React.FC<MonitorStatusPageEditFormProps>
<Input addonBefore={`${window.origin}/status/`} />
</Form.Item>
<Form.Item label={t('Description')} name="description">
<MarkdownEditor value={''} />
</Form.Item>
<Form.Item
label={t('Custom Domain')}
name="domain"

View File

@ -13,6 +13,7 @@ import { useTranslation } from '@i18next-toolkit/react';
import { Link, useNavigate } from '@tanstack/react-router';
import { Helmet } from 'react-helmet';
import { Button } from '@/components/ui/button';
import { MarkdownViewer } from '@/components/MarkdownEditor';
interface MonitorStatusPageProps {
slug: string;
@ -126,6 +127,11 @@ export const MonitorStatusPage: React.FC<MonitorStatusPageProps> = React.memo(
</div>
)}
{/* Desc */}
<div className="mb-4">
<MarkdownViewer value={info?.description ?? ''} />
</div>
<div className="mb-2 text-lg">{t('Services')}</div>
{info && (

View File

@ -2,9 +2,10 @@
const config = {
locales: ['en', 'zh', 'jp', 'fr', 'de', 'pl', 'pt', 'ru'],
verbose: true,
namespaces: ['translation'],
translator: {
type: 'openai',
model: 'gpt-4'
model: 'gpt-4',
},
scanner: {
autoImport: false,
@ -44,7 +45,7 @@ const config = {
'YYYY-MM-DD HH:mm',
'CPU',
'RAM',
'HDD'
'HDD',
],
},
};

View File

@ -21,6 +21,8 @@
"@ant-design/icons": "^5.3.6",
"@antv/l7": "^2.20.14",
"@antv/larkmap": "^1.4.13",
"@bytemd/plugin-gfm": "^1.21.0",
"@bytemd/react": "^1.21.0",
"@hookform/resolvers": "^3.3.4",
"@i18next-toolkit/react": "^1.0.6",
"@loadable/component": "^5.16.3",
@ -52,6 +54,7 @@
"antd": "^5.13.1",
"array-move": "^3.0.1",
"axios": "^1.5.0",
"bytemd": "^1.21.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"cmdk": "^1.0.0",
@ -88,7 +91,7 @@
"zustand": "^4.4.1"
},
"devDependencies": {
"@i18next-toolkit/cli": "^1.2.1",
"@i18next-toolkit/cli": "^1.2.2",
"@tanstack/router-vite-plugin": "^1.20.5",
"@types/leaflet": "^1.9.8",
"@types/loadable__component": "^5.13.8",

View File

@ -120,6 +120,7 @@
"k85344b23": "Laden",
"k85c5fd4c": "Noch kein Monitor eingerichtet",
"k8746ec38": "Monitor auswählen",
"k87615a96": "Bestätigen Sie das Löschen dieser Seite?",
"k887ae5cd": "Erstellen",
"k88a9bf01": "Abzeichen anzeigen",
"k88d2647b": "Webseite",
@ -193,7 +194,7 @@
"kc4e91854": "Sind Sie sicher, dass Sie alle Herzschläge für diesen Monitor löschen möchten?",
"kc5573507": "Hinzufügen",
"kc5f82d53": "Zum Beispiel: pushdeer://pushKey",
"kc6888ac4": "Auto",
"kc6888ac4": "Automatisch",
"kc6cac621": "(Keine)",
"kc70d69ad": "Antwort",
"kc9b446d1": "Ausführung abgeschlossen",
@ -239,6 +240,7 @@
"ke9dcaa64": "Keine Benachrichtigung gefunden",
"kea954889": "Weiter",
"keaf7576f": "Titel",
"keb78cff1": "Description",
"ked37937b": "Metriken",
"ked7eea1a": "OBEN",
"ked8814bc": "Kopieren",

View File

@ -120,6 +120,7 @@
"k85344b23": "Load",
"k85c5fd4c": "No any monitor has been set",
"k8746ec38": "Select monitor",
"k87615a96": "Confirm to delete this page?",
"k887ae5cd": "Create",
"k88a9bf01": "Show Badge",
"k88d2647b": "Website",
@ -239,6 +240,7 @@
"ke9dcaa64": "Not found any notification",
"kea954889": "Continue",
"keaf7576f": "Title",
"keb78cff1": "Description",
"ked37937b": "Metrics",
"ked7eea1a": "UP",
"ked8814bc": "Copy",

View File

@ -101,7 +101,7 @@
"k721589c1": "Aujourd'hui",
"k7350bd93": "En même temps, nous pouvons également l'utiliser dans certains scénarios d'application côté client, comme la collecte de la fréquence d'utilisation du CLI, la collecte de l'installation d'applications auto-hébergées, etc.",
"k74a240": "Barre de santé",
"k75581e13": "CC",
"k75581e13": "Sous-titres",
"k75bfaaa6": "Ajoutez ce code dans le script de tête de votre site web",
"k763816ac": "Aperçu",
"k784dd132": "Test",
@ -120,6 +120,7 @@
"k85344b23": "Charge",
"k85c5fd4c": "Aucun moniteur n'a été défini",
"k8746ec38": "Sélectionner un moniteur",
"k87615a96": "Confirmer la suppression de cette page ?",
"k887ae5cd": "Créer",
"k88a9bf01": "Afficher le badge",
"k88d2647b": "Site Web",
@ -239,6 +240,7 @@
"ke9dcaa64": "Aucune notification trouvée",
"kea954889": "Continuer",
"keaf7576f": "Titre",
"keb78cff1": "Description",
"ked37937b": "Métriques",
"ked7eea1a": "EN LIGNE",
"ked8814bc": "Copier",

View File

@ -120,6 +120,7 @@
"k85344b23": "ロード",
"k85c5fd4c": "まだモニターが設定されていません",
"k8746ec38": "モニターを選択",
"k87615a96": "このページを削除しますか?",
"k887ae5cd": "作成",
"k88a9bf01": "バッジを表示",
"k88d2647b": "ウェブサイト",
@ -239,6 +240,7 @@
"ke9dcaa64": "通知は見つかりませんでした",
"kea954889": "続行",
"keaf7576f": "タイトル",
"keb78cff1": "Description",
"ked37937b": "メトリクス",
"ked7eea1a": "アップ",
"ked8814bc": "コピー",

View File

@ -120,6 +120,7 @@
"k85344b23": "Obciążenie",
"k85c5fd4c": "Nie ustawiono żadnego monitora",
"k8746ec38": "Wybierz monitor",
"k87615a96": "Potwierdź usunięcie tej strony?",
"k887ae5cd": "Utwórz",
"k88a9bf01": "Pokaż odznakę",
"k88d2647b": "Strona internetowa",
@ -239,6 +240,7 @@
"ke9dcaa64": "Nie znaleziono żadnych powiadomień",
"kea954889": "Kontynuuj",
"keaf7576f": "Tytuł",
"keb78cff1": "Description",
"ked37937b": "Metryki",
"ked7eea1a": "DZIAŁA",
"ked8814bc": "Kopiuj",

View File

@ -120,6 +120,7 @@
"k85344b23": "Carregar",
"k85c5fd4c": "Não foi definido qualquer monitor",
"k8746ec38": "Selecionar monitor",
"k87615a96": "Confirmar exclusão desta página?",
"k887ae5cd": "Criar",
"k88a9bf01": "Mostrar crachá",
"k88d2647b": "Sítio Web",
@ -177,7 +178,7 @@
"kb35cde91": "Pesquisar",
"kb5673707": "Últimos 7 dias",
"kb659c1bc": "Exp. do certificado",
"kb8de8c50": "BCC",
"kb8de8c50": "CCO",
"kbb31d3db": "Data da estatística",
"kbb4e12c5": "Escuro",
"kbb58c99c": "Eliminar com êxito",
@ -239,6 +240,7 @@
"ke9dcaa64": "Não encontrei nenhuma notificação",
"kea954889": "Continuar",
"keaf7576f": "Título",
"keb78cff1": "Description",
"ked37937b": "Métricas",
"ked7eea1a": "ATIVO",
"ked8814bc": "Copiar",

View File

@ -120,6 +120,7 @@
"k85344b23": "Нагрузка",
"k85c5fd4c": "Мониторы еще не настроены",
"k8746ec38": "Выбрать монитор",
"k87615a96": "Подтвердить удаление этой страницы?",
"k887ae5cd": "Создать",
"k88a9bf01": "Показать значок",
"k88d2647b": "Веб-сайт",
@ -239,6 +240,7 @@
"ke9dcaa64": "Уведомлений не найдено",
"kea954889": "Продолжить",
"keaf7576f": "Заголовок",
"keb78cff1": "Description",
"ked37937b": "Метрики",
"ked7eea1a": "ВВЕРХ",
"ked8814bc": "Копировать",

View File

@ -120,6 +120,7 @@
"k85344b23": "负载",
"k85c5fd4c": "还没有设置任何监控器",
"k8746ec38": "选择监控器",
"k87615a96": "确认删除此页面?",
"k887ae5cd": "创建",
"k88a9bf01": "显示徽章",
"k88d2647b": "网站",
@ -239,6 +240,7 @@
"ke9dcaa64": "没有找到任何通知",
"kea954889": "继续",
"keaf7576f": "标题",
"keb78cff1": "Description",
"ked37937b": "指标",
"ked7eea1a": "上线",
"ked8814bc": "复制",