chore(chared): Updated flag UI and api
This commit is contained in:
parent
893490d42a
commit
f5edf74936
13 changed files with 158 additions and 112 deletions
|
@ -13,16 +13,10 @@ import {
|
|||
ErrorIcon,
|
||||
WrenchIcon as FixmeIcon,
|
||||
ExpandIcon,
|
||||
FlagIcon,
|
||||
} from 'shared/components/icons.mjs'
|
||||
import Markdown from 'react-markdown'
|
||||
|
||||
const flagColors = {
|
||||
note: 'primary',
|
||||
tip: 'accent',
|
||||
warn: 'error',
|
||||
error: 'error',
|
||||
fixme: 'warning',
|
||||
}
|
||||
import { SubAccordion } from 'shared/components/accordion.mjs'
|
||||
|
||||
const flagIcons = {
|
||||
note: ChatIcon,
|
||||
|
@ -34,39 +28,14 @@ const flagIcons = {
|
|||
expand: ExpandIcon,
|
||||
}
|
||||
|
||||
export const Flags = ({ flags, update }) => {
|
||||
const handleUpdate = (config) => {
|
||||
if (config.settings) update.settings(...config.settings)
|
||||
if (config.ui) update.ui(...config.settings)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="p-4 flex flex-row overflow-x-auto w-full gap-4 max-w-screen">
|
||||
{flagTypes.map((type) =>
|
||||
flags[type]
|
||||
? Object.values(flags[type]).map((flag) => (
|
||||
<Flag type={type} data={flag} handleUpdate={handleUpdate} key={flag.id} />
|
||||
))
|
||||
: null
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const Flag = ({ type, data, handleUpdate }) => {
|
||||
const { t } = useTranslation(nsMerge('flag', data.ns, data.msg.split(':').shift()))
|
||||
const [hide, setHide] = useState(false)
|
||||
|
||||
if (hide || !data.msg) return null
|
||||
|
||||
const color = flagColors[type]
|
||||
export const Flag = ({ type, data, t, handleUpdate }) => {
|
||||
const Icon = flagIcons[type]
|
||||
const BtnIcon = data.suggest?.icon ? flagIcons[data.suggest.icon] : false
|
||||
|
||||
const button =
|
||||
data.suggest?.text && data.suggest?.update ? (
|
||||
<button
|
||||
className={`btn btn-sm sm:btn-normal btn-neutral btn-outline grow flex flex-row items-center justify-between sm:grow-0 shrink-0 z-10 ${
|
||||
className={`btn btn-secondary btn-outline flex flex-row items-center ${
|
||||
BtnIcon ? 'gap-6' : ''
|
||||
}`}
|
||||
onClick={() => handleUpdate(data.suggest.update)}
|
||||
|
@ -76,43 +45,87 @@ export const Flag = ({ type, data, handleUpdate }) => {
|
|||
</button>
|
||||
) : null
|
||||
|
||||
const msg = data.replace
|
||||
? mustache.render(t(data.msg), { ...data.replace, '"': '"' })
|
||||
: t(data.msg)
|
||||
const desc = data.replace ? mustache.render(t(data.desc), data.replace) : t(data.desc)
|
||||
|
||||
return (
|
||||
<div className="w-4/5 max-w-md shrink-0">
|
||||
<div className={`relative bg-${color} bg-opacity-10`}>
|
||||
<div className="p-3 rounded-lg shadow text-base">
|
||||
<div className="flex flex-row flex-wrap sm:flex-nowrap gap-2 items-start z-10">
|
||||
<div className="first:mt-0 popout-content grow z-10 md flag">
|
||||
<Markdown>{msg}</Markdown>
|
||||
</div>
|
||||
{button ? (
|
||||
<div className="flex flex-row justify-between sm:flex-col gap-2 shrink-0 z-10 w-full sm:w-auto">
|
||||
{button}
|
||||
<button
|
||||
className="w-1/2 sm:w-full btn btn-ghost btn-sm z-10 flex flex-row items-center justify-between w-full"
|
||||
onClick={() => setHide(true)}
|
||||
>
|
||||
{t('flag:dismiss')}
|
||||
<Icon className="w-5 h-6 sm:w-6 h-6" />
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col gap-2">
|
||||
<button
|
||||
className="btn btn-sm btn-circle btn-ghost"
|
||||
onClick={() => setHide(true)}
|
||||
title={t('flag:hide')}
|
||||
>
|
||||
<Icon className="w-5 h-5 sm:w-6 h-6" />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2 items-start">
|
||||
<div className="first:mt-0 grow md flag">
|
||||
<Markdown children={desc} />
|
||||
</div>
|
||||
{button ? <div className="mt-2 w-full flex flex-row justify-end">{button}</div> : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const flattenFlags = (flags) => {
|
||||
const all = {}
|
||||
const ns = ['flag']
|
||||
for (const type of flagTypes) {
|
||||
let i = 0
|
||||
if (flags[type]) {
|
||||
for (const [key, flag] of Object.entries(flags[type])) {
|
||||
i++
|
||||
all[`${type}-${i}`] = { ...flag, type }
|
||||
if (flag.ns) ns.push(flag.ns)
|
||||
if (flag.title.includes(':')) ns.push(flag.title.split(':').shift())
|
||||
if (flag.desc.includes(':')) ns.push(flag.desc.split(':').shift())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [all, ns]
|
||||
}
|
||||
|
||||
export const FlagsAccordionTitle = ({ flags }) => {
|
||||
const { t } = useTranslation(['flag'])
|
||||
const [flagList] = flattenFlags(flags)
|
||||
|
||||
if (Object.keys(flagList).length < 1) return null
|
||||
|
||||
return (
|
||||
<>
|
||||
<h5 className="flex flex-row gap-2 items-center justify-between w-full">
|
||||
<span>
|
||||
{t('flag:flagMenu.t')} ({Object.keys(flagList).length})
|
||||
</span>
|
||||
<FlagIcon className="w-8 h-8" />
|
||||
</h5>
|
||||
<p className="text-left">
|
||||
{Object.keys(flagList).length > 1 ? t('flag:flagMenuMany.d') : t('flag:flagMenuOne.d')}
|
||||
</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const FlagsAccordionEntries = ({ flags, update }) => {
|
||||
const [flagList, ns] = flattenFlags(flags)
|
||||
const { t } = useTranslation(nsMerge(ns))
|
||||
const [all, setAll] = useState(flagList)
|
||||
|
||||
if (Object.keys(flagList).length < 1) return null
|
||||
|
||||
const handleUpdate = (config) => {
|
||||
if (config.settings) update.settings(...config.settings)
|
||||
if (config.ui) update.ui(...config.settings)
|
||||
}
|
||||
|
||||
return (
|
||||
<SubAccordion
|
||||
items={Object.entries(all).map(([key, flag], i) => {
|
||||
const Icon = flagIcons[flag.type]
|
||||
const title = flag.replace ? mustache.render(t(flag.title), flag.replace) : t(flag.title)
|
||||
|
||||
return [
|
||||
<div className="w-full flex flex-row gap2 justify-between" key={i}>
|
||||
<div className="flex flex-row items-center gap-2">
|
||||
<Icon />
|
||||
<span className="font-medium">{title}</span>
|
||||
</div>
|
||||
<span className="uppercase font-bold">{flag.type}</span>
|
||||
</div>,
|
||||
<Flag key={key} t={t} type={flag.type} data={flag} handleUpdate={handleUpdate} />,
|
||||
]
|
||||
})}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue