admin/home: show message for each update available

Massimo Melina committed Jul 19, 2023 at 16:42 UTC 7d4d972c3be9dea84d5aeb313b1450d3d5175862
3 files changed +21 -10
admin/src/HomePage.ts
+12 -6
@@ -1,7 +1,7 @@
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, ReactNode, useState } from 'react'
4 -import { Box, Button, LinearProgress, Link } from '@mui/material'
4 +import { Box, Button, Card, CardContent, LinearProgress, Link } from '@mui/material'
5 import { apiCall, useApi, useApiEx, useApiList } from './api'
6 import {
7 Btn,
@@ -114,11 +114,17 @@ export default function HomePage() {
114 : newer && !status.updatePossible ? entry('', `Version ${newer.name} available`)
115 : h(Flex, { vert: true },
116 updates.map((x: any) =>
117 - h(Btn, {
118 - icon: UpdateIcon,
119 - ...!x.isNewer && { color: 'warning', variant: 'outlined' },
120 - onClick: () => update(x.tag_name)
121 - }, prefix("Install ", x.name, x.isNewer ? '' : " (older)")))
117 + h(Flex, { alignItems: 'flex-start', flexWrap: 'wrap' },
118 + h(Card, {},
119 + h(CardContent, {},
120 + h(Btn, {
121 + icon: UpdateIcon,
122 + ...!x.isNewer && { color: 'warning', variant: 'outlined' },
123 + onClick: () => update(x.tag_name)
124 + }, prefix("Install ", x.name, x.isNewer ? '' : " (older)")),
125 + h(Box, { mt: 1 }, md(x.body, { linkTarget: '_blank' }))
126 + )),
127 + )),
128 ))
129 )
130 }
admin/src/index.css
+3 -1
@@ -10,7 +10,9 @@ body {
10 background: #000;
11 }
12 #root { min-height: 100%; display:flex; }
13 -
13 +main {
14 + word-break: break-word; /* avoid causing unnecessary horizontal scrolling */
15 +}
16 code {
17 font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
18 monospace;
admin/src/md.ts
+6 -3
@@ -1,18 +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 } from 'react'
4 +import { Link } from '@mui/material'
5
6 // markdown inspired syntax to transform text into react elements: * for bold, / for italic, _ for underline, ` for code
6 -export default function md(text: string | TemplateStringsArray) {
7 +export default function md(text: string | TemplateStringsArray, { linkTarget='' }={}) {
8 if (typeof text !== 'string')
9 text = text[0]
9 - const re = /([`*/_])(.+)\1|(\n)/g
10 + const re = /([`*/_])(.+)\1|(\n)|\[(.+)\]\((.+)\)/g
11 const res = []
12 let last = 0
13 let match
14 while (match = re.exec(text)) { //eslint-disable-line no-cond-assign
15 res.push( text.slice(last, match.index) )
15 - if (match[3])
16 + if (match[4])
17 + res.push(h(Link, { href: match[5], target: linkTarget }, match[4]))
18 + else if (match[3])
19 res.push(h('br'))
20 else {
21 const tag = ({