1
0
Fork 0

chore(chared): Updated flag UI and api

This commit is contained in:
Joost De Cock 2023-09-09 15:31:53 +02:00
parent 893490d42a
commit f5edf74936
13 changed files with 158 additions and 112 deletions

View file

@ -6,8 +6,10 @@
"neckBinding": "Neck opening knit binding"
},
"s": {
"cutArmBinding": "Not shown: the **Arm opening knit binding**, two strips of fabric {{{ width }}} wide and {{{ length }}} long <small>(this includes seam allowance)</small>",
"cutNeckBinding": "Not shown: the **Neck opening knit binding**, a strip of fabric {{{ width }}} wide and {{{ length }}} long <small>(this includes seam allowance)</small>",
"cutArmBinding.t": "The arm opening knit binding is not currently shown",
"cutArmBinding.d": "The **Arm opening knit binding** are two strips of fabric {{{ width }}} wide and {{{ length }}} long (this includes seam allowance). They are not shown because the **expand** core setting is currently disabled. Enable it to show this pattern part.",
"cutNeckBinding.t": "The neck opening knit binding is not currently shown",
"cutNeckBinding.d": "The **Neck opening knit binding** is a strip of fabric {{{ width }}} wide and {{{ length }}} long (this includes seam allowance). It is not shown because the **expand** core setting is currently disabled. Enable it to show this pattern part.",
"cutOneStripToFinishTheNeckOpening": "Cut one strip to finish the neck opening",
"cutTwoStripsToFinishTheArmholes": "Cut two strips to finish the armholes",
"length": "Length",

View file

@ -23,7 +23,8 @@ export const armBinding = {
if (!expand) {
// Expand is on, do not draw the part but flag this to the user
store.flag.note({
msg: `aaron:cutArmBinding`,
title: `aaron:cutArmBinding.t`,
desc: `aaron:cutArmBinding.d`,
replace: {
width: units(w),
length: units(l),

View file

@ -23,7 +23,8 @@ export const neckBinding = {
if (!expand) {
// Expand is on, do not draw the part but flag this to the user
store.flag.note({
msg: `aaron:cutNeckBinding`,
title: `aaron:cutNeckBinding.t`,
desc: `aaron:cutNeckBinding.d`,
replace: {
width: units(w),
length: units(l),

View file

@ -8,8 +8,10 @@
},
"s": {
"attachStrap": "Attach strap",
"cutPocket": "Not shown: the **Pocket**, a rectangle of {{{ width }}} wide and {{{ length }}} long <small>(this includes seam allowance)</small>",
"cutStrap": "Not shown: the **Straps**, two rectangles of {{{ width }}} wide and {{{ length }}} long <small>(this includes seam allowance)</small>",
"cutPocket.t": "The pocket is not currently shown",
"cutPocket.d": "The **Pocket** is a rectangular piece of fabric {{{ width }}} wide and {{{ length }}} long (this includes seam allowance). It is not shown because the **expand** core setting is currently disabled. Enable it to show this pattern part.",
"cutStrap.t": "The straps are not currently shown",
"cutStrap.d": "The **Straps** are two strips of fabric {{{ width }}} wide and {{{ length }}} long (this includes seam allowance)</small>. They are not shown because the **expand** core setting is currently disabled. Enable it to show this pattern part.",
"foldHere": "Fold here"
},
"o": {

View file

@ -22,7 +22,8 @@ export const pocket = {
if (!expand) {
// Expand is on, do not draw the part but flag this to the user
store.flag.note({
msg: `albert:cutPocket`,
title: `albert:cutPocket.t`,
desc: `albert:cutPocket.d`,
replace: {
width: units(pocketSize * 2 + 2 * sa),
length: units(pocketSize + 2 * sa + store.get('strapWidth')),

View file

@ -41,10 +41,11 @@ export const strap = {
if (!expand) {
// Expand is on, do not draw the part but flag this to the user
store.flag.note({
msg: `albert:cutStrap`,
title: `albert:cutStrap.t`,
desc: `albert:cutStrap.d`,
replace: {
width: units(store.get('strapWidth') + 2 * sa),
length: units(store.get('strapLength') + store.get('strapWidth') * 2 + 2 * sa),
width: units(strapWidth + 2 * sa),
length: units(strapLength + strapWidth * 2 + 2 * sa),
},
suggest: {
text: 'flag:show',

View file

@ -34,13 +34,13 @@ function flag(type, store, data) {
type = data.type
}
if (!data.id && !data.msg) {
store.log.warning(`store.flag.${type} called without an id or msg property`)
if (!data.id && !data.title) {
store.log.warn(`store.flag.${type} called without an id or title property`)
console.log(data)
return
}
store.set([...storeRoot, type, data.id ? data.id : data.msg], data)
store.set([...storeRoot, type, data.id ? data.id : data.title], data)
}
/*
@ -53,7 +53,7 @@ function flag(type, store, data) {
function unflag(type, store, id) {
if (type === 'preset' && presets[id]) {
type = presets[id].type
id = presets[id].id || presets[id].msg
id = presets[id].id || presets[id].title
}
store.unset([...storeRoot, type, id])
}
@ -64,7 +64,8 @@ function unflag(type, store, id) {
const presets = {
expand: {
type: 'tip',
msg: 'flag:expandIsOff',
title: 'flag:expandIsOff.t',
desc: 'flag:expandIsOff.d',
suggest: {
text: 'flag:enable',
icon: 'expand',

View file

@ -26,9 +26,12 @@ const BaseAccordion = ({
}) => {
const [active, setActive] = useState()
console.log(items)
return (
<nav>
{items.map((item, i) =>
{items
.filter((item) => item[0])
.map((item, i) =>
active === i ? (
<div key={i} {...propsGetter(active, i)}>
<button onClick={setActive} className="w-full">

View file

@ -318,6 +318,12 @@ export const FingerprintIcon = (props) => (
</IconWrapper>
)
export const FlagIcon = (props) => (
<IconWrapper {...props}>
<path d="M3 3v1.5M3 21v-6m0 0l2.77-.693a9 9 0 016.208.682l.108.054a9 9 0 006.086.71l3.114-.732a48.524 48.524 0 01-.005-10.499l-3.11.732a9 9 0 01-6.085-.711l-.108-.054a9 9 0 00-6.208-.682L3 4.5M3 15V4.5" />
</IconWrapper>
)
export const FreeSewingIcon = (props) => (
<IconWrapper {...props} stroke={0} fill>
<path d={logoPath} />

View file

@ -49,7 +49,6 @@ export const DraftView = ({
pattern: output,
setSettings,
Header: DraftHeader,
flags: pattern.setStores?.[0]?.plugins?.['plugin-annotations']?.flags,
menu: (
<DraftMenu
{...{
@ -66,6 +65,7 @@ export const DraftView = ({
renderProps,
view,
setView,
flags: pattern.setStores?.[0]?.plugins?.['plugin-annotations']?.flags,
}}
/>
),

View file

@ -9,8 +9,12 @@ import {
import { UiSettings, ns as uiNs } from 'shared/components/workbench/menus/ui-settings/index.mjs'
import { useTranslation } from 'next-i18next'
import { nsMerge } from 'shared/utils.mjs'
import { SettingsIcon, OptionsIcon, DesktopIcon } from 'shared/components/icons.mjs'
import { SettingsIcon, OptionsIcon, DesktopIcon, FlagIcon } from 'shared/components/icons.mjs'
import { Accordion } from 'shared/components/accordion.mjs'
import {
FlagsAccordionTitle,
FlagsAccordionEntries,
} from 'shared/components/workbench/views/flags.mjs'
export const ns = nsMerge(coreMenuNs, designMenuNs, uiNs)
@ -26,6 +30,7 @@ export const DraftMenu = ({
DynamicDocs,
view,
setView,
flags = false,
}) => {
const { t } = useTranslation()
const control = account.control
@ -61,9 +66,14 @@ export const DraftMenu = ({
},
]
return (
<Accordion
items={sections.map((section) => [
const items = []
if (flags)
items.push([
<FlagsAccordionTitle flags={flags} />,
<FlagsAccordionEntries {...{ update, control, flags }} />,
])
items.push(
...sections.map((section) => [
<>
<h5 className="flex flex-row gap-2 items-center justify-between w-full">
<span>{t(`${section.ns}:${section.name}.t`)}</span>
@ -72,7 +82,8 @@ export const DraftMenu = ({
<p className="text-left">{t(`${section.ns}:${section.name}.d`)}</p>
</>,
section.menu,
])}
/>
])
)
return <Accordion items={items} />
}

View file

@ -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, '&quot;': '"' })
: 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} />,
]
})}
/>
)
}

View file

@ -1,5 +1,9 @@
dismiss: Dismiss
expandIsOff: The **expand** core setting is disabled. Some parts are not fully drawn. Enable it to see them.
expandIsOff.t: This design saves space (and trees) because expand is disabled
expandIsOff.d: Because the **expand** core setting is currently disabled, some parts are not fully drawn or not shown at all. Typically, these are simple rectangles that only take up space. To expand all pattern parts to their full size, enable the expand setting.
enable: Enable
flagMenu.t: Messages from the designer
flagMenuOne.d: The designer of this pattern has flagged something about your current draft that deserves your attention.
flagMenuMany.d: The designer of this pattern has flagged some things about your current draft that deserve your attention.
hide: Hide
show: Show