better code: prepare md to be shared with frontend
Massimo Melina committed
Mar 20, 2024 at 15:30 UTC
023f7c5e802c11396f67484a8561d8b3b43271e8
13 files changed
+24
-32
admin/src/AccountsPage.ts
+1
-2
@@ -4,12 +4,11 @@ import { createElement as h, useState, useEffect, Fragment } from "react"
4
import { apiCall, useApiEx } from './api'
5
import { Alert, Box, Card, CardContent, Grid, List, ListItem, ListItemText, Typography } from '@mui/material'
6
import { Close, Delete, DoNotDisturb, Group, MilitaryTech, Person, PersonAdd, Schedule } from '@mui/icons-material'
7
-import { newDialog, with_ } from './misc'
7
+import { newDialog, with_, md } from './misc'
8
import { Btn, Flex, IconBtn, iconTooltip, reloadBtn, useBreakpoint } from './mui'
9
import { TreeItem, TreeView } from '@mui/x-tree-view'
10
import MenuButton from './MenuButton'
11
import AccountForm from './AccountForm'
12
-import md from './md'
12
import _ from 'lodash'
13
import { alertDialog, confirmDialog } from './dialog'
14
import { useSnapState } from './state'
admin/src/CustomHtmlPage.ts
+1
-2
@@ -4,12 +4,11 @@ import { createElement as h, Fragment, useEffect, useMemo, useState } from 'reac
4
import { Field, SelectField } from '@hfs/mui-grid-form'
5
import { apiCall, useApiEx } from './api'
6
import { Alert, Box } from '@mui/material'
7
-import { Dict, HTTP_MESSAGES, isCtrlKey, prefix } from './misc';
7
+import { Dict, HTTP_MESSAGES, isCtrlKey, prefix, md } from './misc';
8
import { IconBtn, reloadBtn, wikiLink } from './mui';
9
import { Save } from '@mui/icons-material'
10
import _ from 'lodash'
11
import { useDebounce } from 'usehooks-ts'
12
-import md from './md'
12
import { TextEditor } from './TextEditor';
13
14
const names: any = {
admin/src/FileForm.ts
+1
-2
@@ -7,10 +7,9 @@ import { BoolField, DisplayField, Field, FieldProps, Form, MultiSelectField, Sel
7
} from '@hfs/mui-grid-form'
8
import { apiCall, UseApi, useApiEx } from './api'
9
import { basename, defaultPerms, formatBytes, formatTimestamp, isEqualLax, isWhoObject, newDialog, objSameKeys,
10
- onlyTruthy, prefix, VfsPerms, wantArray, Who, WhoObject, matches, HTTP_MESSAGES, xlate } from './misc'
10
+ onlyTruthy, prefix, VfsPerms, wantArray, Who, WhoObject, matches, HTTP_MESSAGES, xlate, md } from './misc'
11
import { Btn, IconBtn, LinkBtn, modifiedProps, useBreakpoint, wikiLink } from './mui'
12
import { reloadVfs, VfsNode } from './VfsPage'
13
-import md from './md'
13
import _ from 'lodash'
14
import FileField from './FileField'
15
import { alertDialog, toast, useDialogBarColors } from './dialog'
admin/src/HomePage.ts
+5
-8
@@ -3,11 +3,10 @@
3
import { createElement as h, ReactNode, useState } from 'react'
4
import { Box, Card, CardContent, LinearProgress, Link } from '@mui/material'
5
import { apiCall, useApiEx, useApiList } from './api'
6
-import { dontBotherWithKeys, objSameKeys, onlyTruthy, prefix, REPO_URL,
7
- wait, with_ } from './misc'
6
+import { dontBotherWithKeys, objSameKeys, onlyTruthy, prefix, REPO_URL, md,
7
+ replaceStringToReact, wait, with_ } from './misc'
8
import { Btn, Flex, InLink, LinkBtn, wikiLink, } from './mui'
9
import { BrowserUpdated as UpdateIcon, CheckCircle, Error, Info, Launch, OpenInNew, Warning } from '@mui/icons-material'
10
-import md, { replaceStringToReact } from './md'
10
import { state, useSnapState } from './state'
11
import { alertDialog, confirmDialog, promptDialog, toast } from './dialog'
12
import { isCertError, isKeyError, suggestMakingCert } from './OptionsPage'
@@ -132,12 +131,10 @@ export default function HomePage() {
131
}
132
133
function renderChangelog(s: string) {
135
- return md(s, { onText })
136
-
137
- function onText(s: string) {
138
- return replaceStringToReact(s, /(?<=^|\W)#(\d+)\b/g, m => // link issues
134
+ return md(s, {
135
+ onText: s => replaceStringToReact(s, /(?<=^|\W)#(\d+)\b/g, m => // link issues
136
h(Link, { href: REPO_URL + 'issues/' + m[1], target: '_blank' }, h(OpenInNew) ))
140
- }
137
+ })
138
}
139
140
async function update(tag?: string) {
admin/src/InternetPage.ts
+1
-2
@@ -3,12 +3,11 @@ import { Alert, Box, Button, Card, CardContent, CircularProgress, Divider, Linea
3
import { CardMembership, Check, Dns, HomeWorkTwoTone, Lock, Public, PublicTwoTone, RouterTwoTone, Send, Storage,
4
Error as ErrorIcon, SvgIconComponent } from '@mui/icons-material'
5
import { apiCall, useApiEvents, useApiEx } from './api'
6
-import { closeDialog, DAY, formatTimestamp, wait, wantArray, with_, PORT_DISABLED, isIP, CFG,
6
+import { closeDialog, DAY, formatTimestamp, wait, wantArray, with_, PORT_DISABLED, isIP, CFG, md,
7
useRequestRender, replace, restartAnimation, prefix } from './misc'
8
import { Flex, LinkBtn, Btn, Country } from './mui'
9
import { alertDialog, confirmDialog, formDialog, promptDialog, toast, waitDialog } from './dialog'
10
import { BoolField, Form, MultiSelectField, NumberField, SelectField } from '@hfs/mui-grid-form'
11
-import md from './md'
11
import { suggestMakingCert } from './OptionsPage'
12
import { changeBaseUrl } from './FileForm'
13
import { getNatInfo } from '../../src/nat'
admin/src/LogsPage.ts
+1
-2
@@ -4,7 +4,7 @@ import { createElement as h, Fragment, ReactNode, useMemo, useState } from 'reac
4
import { Box, Tab, Tabs } from '@mui/material'
5
import { API_URL, useApi, useApiList } from './api'
6
import { DataTable } from './DataTable'
7
-import { CFG, Dict, formatBytes, HTTP_UNAUTHORIZED, newDialog, prefix, shortenAgent, splitAt, tryJson,
7
+import { CFG, Dict, formatBytes, HTTP_UNAUTHORIZED, newDialog, prefix, shortenAgent, splitAt, tryJson, md,
8
typedKeys, NBSP, _dbg, mapFilter } from '@hfs/shared'
9
import { logLabels } from './OptionsPage'
10
import {
@@ -14,7 +14,6 @@ import {
14
import { GridColDef } from '@mui/x-data-grid'
15
import _ from 'lodash'
16
import { ClearAll, Download, Settings, SmartToy } from '@mui/icons-material'
17
-import md from './md'
17
import { ConfigForm } from './ConfigForm'
18
import { BoolField, SelectField } from '@hfs/mui-grid-form'
19
import { toast, useDialogBarColors } from './dialog'
admin/src/MainMenu.ts
+1
-2
@@ -17,10 +17,9 @@ import LogoutPage from './LogoutPage';
17
import LangPage from './LangPage'
18
import LogsPage from './LogsPage';
19
import PluginsPage from './PluginsPage';
20
-import { getHFS } from '@hfs/shared'
20
+import { getHFS, replaceStringToReact } from '@hfs/shared'
21
import CustomHtmlPage from './CustomHtmlPage';
22
import InternetPage from './InternetPage'
23
-import { replaceStringToReact } from './md'
23
import { useWindowSize } from 'usehooks-ts'
24
import { hTooltip } from './mui'
25
admin/src/MonitorPage.ts
+1
-2
@@ -7,9 +7,8 @@ import { LinkOff, Lock, Block, FolderZip, Upload, Download, ChevronRight, Chevro
7
import { Box, Chip, ChipProps } from '@mui/material'
8
import { DataTable } from './DataTable'
9
import { formatBytes, ipForUrl, manipulateConfig, CFG, formatSpeed, with_, createDurationFormatter, formatTimestamp,
10
- formatPerc } from "./misc"
10
+ formatPerc, md } from "./misc"
11
import { IconBtn, IconProgress, iconTooltip, usePauseButton, useBreakpoint, Country, hTooltip } from './mui'
12
-import md from './md'
12
import { Field, SelectField } from '@hfs/mui-grid-form'
13
import { StandardCSSProperties } from '@mui/system/styleFunctionSx/StandardCssProperties'
14
import { agentIcons } from './LogsPage'
admin/src/OptionsPage.ts
+1
-2
@@ -7,7 +7,7 @@ import { state, useSnapState } from './state'
7
import { Link as RouterLink } from 'react-router-dom'
8
import { CardMembership, EditNote, Refresh, Warning } from '@mui/icons-material'
9
import { Dict, MAX_TILE_SIZE, REPO_URL, isIpLocalHost, wait, with_, try_, ipForUrl, SORT_BY_OPTIONS, THEME_OPTIONS,
10
- CFG } from './misc'
10
+ CFG, md } from './misc'
11
import { iconTooltip, InLink, LinkBtn, modifiedProps, wikiLink, useBreakpoint, NetmaskField, WildcardsSupported } from './mui'
12
import { Form, BoolField, NumberField, SelectField, FieldProps, Field, StringField } from '@hfs/mui-grid-form';
13
import { ArrayField } from './ArrayField'
@@ -16,7 +16,6 @@ import { alertDialog, confirmDialog, newDialog, toast, waitDialog } from './dial
16
import { proxyWarning } from './HomePage'
17
import _ from 'lodash';
18
import { proxy, subscribe, useSnapshot } from 'valtio'
19
-import md from './md'
19
import { TextEditorField } from './TextEditor'
20
21
let loaded: Dict | undefined
admin/src/dialog.ts
+1
-2
@@ -7,12 +7,11 @@ import { createElement as h, Dispatch, Fragment, isValidElement, ReactElement, R
7
} from 'react'
8
import { Check, Close, Error as ErrorIcon, Forward, Info, Warning } from '@mui/icons-material'
9
import { newDialog, closeDialog, dialogsDefaults, DialogOptions, componentOrNode, pendingPromise,
10
- focusSelector } from '@hfs/shared'
10
+ focusSelector, md } from '@hfs/shared'
11
import { Form, FormProps } from '@hfs/mui-grid-form'
12
import { IconBtn, Flex, Center } from './mui'
13
import { useDark } from './theme'
14
import { useWindowSize } from 'usehooks-ts'
15
-import md from './md'
15
import _ from 'lodash'
16
import { err2msg } from './misc'
17
export * from '@hfs/shared/dialogs'
admin/src/misc.ts
+4
-1
@@ -1,9 +1,12 @@
1
// This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3
import { apiCall } from './api'
4
-import { HTTP_MESSAGES } from '@hfs/shared'
4
+import { HTTP_MESSAGES, MD_TAGS } from '@hfs/shared'
5
+import { Link } from '@mui/material'
6
export * from '@hfs/shared'
7
8
+;(MD_TAGS as any).a = Link
9
+
10
export async function manipulateConfig(k: string, work:(data:any) => any) {
11
const cfg = await apiCall('get_config', { only: [k] })
12
const was = cfg[k]
shared/index.ts
+1
@@ -5,6 +5,7 @@ import { apiCall } from './api'
5
import { DAY, HOUR, MINUTE, objSameKeys, typedEntries } from '../src/cross'
6
export * from './react'
7
export * from './dialogs'
8
+export * from './md'
9
export * from '../src/srp'
10
export * from '../src/cross'
11
shared/md.ts
renamed
+5
-5
@@ -1,21 +1,21 @@
1
// This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3
import { createElement as h, Fragment, ReactNode } from 'react'
4
-import { Link } from '@mui/material'
4
6
-const TAGS = {
5
+export const MD_TAGS = {
6
+ a: 'a',
7
'`': 'code',
8
'*': 'i',
9
'**': 'b',
10
}
11
type OnText = (s: string) => ReactNode
12
-export default function md(text: string | TemplateStringsArray, { linkTarget='_blank', onText=(x=>x) as OnText }={}) {
12
+export function md(text: string | TemplateStringsArray, { linkTarget='_blank', onText=(x=>x) as OnText }={}) {
13
if (typeof text !== 'string')
14
text = text[0]
15
return replaceStringToReact(text, /(`|_|\*\*?)(.+?)\1|(\n)|\[(.+?)\]\((.+?)\)|<([^ >/]+)>(.*?)<\/\6>|<([^ >/]+) *\/>/g, m =>
16
- m[4] ? h(Link, { href: m[5], target: linkTarget }, onText(m[4]))
16
+ m[4] ? h(MD_TAGS.a, { href: m[5], target: linkTarget }, onText(m[4]))
17
: m[3] ? h('br')
18
- : m[1] ? h((TAGS as any)[ m[1] ] || Fragment, {}, onText(m[2]))
18
+ : m[1] ? h((MD_TAGS as any)[ m[1] ] || Fragment, {}, onText(m[2]))
19
: h(m[6] || m[8], {}, m[7]),
20
onText)
21
}