wip: Undo view
This commit is contained in:
parent
3ec1cbd01b
commit
987ba5419c
12 changed files with 158 additions and 82 deletions
|
@ -93,6 +93,7 @@ packageJson:
|
|||
"./components/LineDrawing": "./components/LineDrawing/index.mjs"
|
||||
"./components/Link": "./components/Link/index.mjs"
|
||||
"./components/Logo": "./components/Logo/index.mjs"
|
||||
"./components/Mini": "./components/Mini/index.mjs"
|
||||
"./components/Modal": "./components/Modal/index.mjs"
|
||||
"./components/New": "./components/New/index.mjs"
|
||||
"./components/Number": "./components/Number/index.mjs"
|
||||
|
|
|
@ -82,7 +82,7 @@ export const HeaderMenuDraftView = (props) => {
|
|||
}
|
||||
|
||||
export const HeaderMenuDropdown = (props) => {
|
||||
const { tooltip, toggle, open, setOpen, id } = props
|
||||
const { tooltip, toggle, open, setOpen, id, end = false } = props
|
||||
/*
|
||||
* We need to use both !fixed and md:!absolute here to override DaisyUI's
|
||||
* classes on dropdown-content to force the dropdown to use the available
|
||||
|
@ -95,14 +95,16 @@ export const HeaderMenuDropdown = (props) => {
|
|||
disabled
|
||||
tabIndex={0}
|
||||
role="button"
|
||||
className="tw-daisy-btn tw-daisy-btn-ghost hover:tw-bg-secondary hover:tw-bg-opacity-20 hover:tw-border-solid hover:tw-border-2 hover:tw-border-secondary tw-border tw-border-secondary tw-border-2 tw-border-dotted tw-daisy-btn-sm tw-px-2 tw-z-20 tw-relative"
|
||||
className={`tw-daisy-btn tw-daisy-btn-ghost hover:tw-bg-secondary hover:tw-bg-opacity-20 hover:tw-border-solid hover:tw-border-2 hover:tw-border-secondary tw-border tw-border-secondary tw-border-2 tw-border-dotted tw-daisy-btn-sm tw-px-2 tw-z-20 tw-relative`}
|
||||
>
|
||||
{toggle}
|
||||
</button>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Tooltip tip={tooltip}>
|
||||
<div className={`tw-daisy-dropdown ${open === id ? 'tw-daisy-dropdown-open tw-z-20' : ''}`}>
|
||||
<div
|
||||
className={`tw-daisy-dropdown ${open === id ? 'tw-daisy-dropdown-open tw-z-20' : ''} ${end ? ' tw-daisy-dropdown-end' : ''}`}
|
||||
>
|
||||
<div
|
||||
tabIndex={0}
|
||||
role="button"
|
||||
|
@ -113,7 +115,7 @@ export const HeaderMenuDropdown = (props) => {
|
|||
</div>
|
||||
<div
|
||||
tabIndex={0}
|
||||
className="tw-daisy-dropdown-content tw-bg-base-100 tw-bg-opacity-90 tw-z-20 tw-shadow tw-left-0 !tw-fixed md:!tw-absolute tw-top-12 tw-w-screen md:tw-max-w-lg tw-overflow-y-scroll tw-mb-12 tw-h-fit"
|
||||
className="tw-daisy-dropdown-content tw-bg-base-100 tw-bg-opacity-90 tw-z-20 tw-shadow tw-left-0 !tw-fixed md:!tw-absolute tw-top-12 tw-w-screen md:tw-max-w-md tw-overflow-y-scroll tw-mb-12 tw-h-fit"
|
||||
style={{ maxHeight: 'calc(100vh - 12rem)' }}
|
||||
>
|
||||
{props.children}
|
||||
|
@ -329,6 +331,7 @@ export const HeaderMenuUndoIcons = (props) => {
|
|||
<UndoIcon className={`${size} ${undos ? 'tw-text-secondary' : ''}`} text="A" />
|
||||
</Button>
|
||||
<HeaderMenuDropdown
|
||||
end
|
||||
{...props}
|
||||
tooltip={viewLabels.undos.t}
|
||||
id="undos"
|
||||
|
@ -341,19 +344,14 @@ export const HeaderMenuUndoIcons = (props) => {
|
|||
}
|
||||
>
|
||||
{undos ? (
|
||||
<ul className="tw-daisy-dropdown-content tw-bg-base-100 tw-bg-opacity-90 tw-z-20 tw-shadow tw-left-0 !tw-fixed md:!tw-absolute tw-w-screen md:tw-w-96 tw-px-4 md:tw-p-2 md:tw-pt-0">
|
||||
<ul className="tw-daisy-dropdown-content tw-bg-base-100 tw-bg-opacity-90 tw-z-20 tw-shadow tw-left-0 !tw-fixed md:!tw-absolute tw-w-screen md:tw-w-96 tw-px-4 md:tw-p-2 md:tw-pt-0 tw-contents">
|
||||
{undos.slice(0, 9).map((step, index) => (
|
||||
<li key={index}>
|
||||
<UndoStep {...{ step, update, state, Design, index }} compact />
|
||||
</li>
|
||||
))}
|
||||
<li key="view">
|
||||
<ButtonFrame
|
||||
dense
|
||||
onClick={() => {
|
||||
return null /*update.state(index, state._) */
|
||||
}}
|
||||
>
|
||||
<ButtonFrame dense onClick={() => update.view('undos')}>
|
||||
<div className="tw-flex tw-flex-row tw-items-center tw-align-center tw-justify-between tw-gap-2 tw-w-full">
|
||||
<div className="tw-flex tw-flex-row tw-items-center tw-align-start tw-gap-2 tw-grow">
|
||||
<UndoIcon className="tw-w-5 tw-h-5 tw-text-secondary" />
|
||||
|
@ -502,7 +500,7 @@ export const HeaderMenuViewMenu = (props) => {
|
|||
>
|
||||
<ul
|
||||
tabIndex={i}
|
||||
className="tw-dropdown-content tw-bg-base-100 tw-bg-opacity-95 tw-z-20 tw-shadow tw-left-0 !tw-fixed md:!tw-absolute tw-w-screen md:tw-max-w-lg md:tw-pt-0 tw-mt-14 md:tw-mt-0 tw-contents"
|
||||
className="tw-daisy-dropdown-content tw-bg-base-100 tw-bg-opacity-95 tw-z-20 tw-shadow tw-left-0 !tw-fixed md:!tw-absolute tw-w-screen md:tw-max-w-lg md:tw-pt-0 tw-mt-14 md:tw-mt-0 tw-contents"
|
||||
>
|
||||
{output}
|
||||
</ul>
|
||||
|
|
|
@ -4,7 +4,7 @@ import { TipIcon, OkIcon } from '@freesewing/react/components/Icon'
|
|||
import { Null } from './Null.mjs'
|
||||
|
||||
const config = {
|
||||
timeout: 2,
|
||||
timeout: 2.5,
|
||||
defaults: {
|
||||
color: 'secondary',
|
||||
icon: 'Spinner',
|
||||
|
|
|
@ -111,7 +111,13 @@ export const UserSetPicker = ({
|
|||
)
|
||||
}
|
||||
|
||||
export const BookmarkedSetPicker = ({ Design, clickHandler, missingClickHandler, size = 'lg' }) => {
|
||||
export const BookmarkedSetPicker = ({
|
||||
Design,
|
||||
config,
|
||||
clickHandler,
|
||||
missingClickHandler,
|
||||
size = 'lg',
|
||||
}) => {
|
||||
// Hooks
|
||||
const backend = useBackend()
|
||||
|
||||
|
|
|
@ -5,15 +5,10 @@ import { designOptionType } from '@freesewing/utils'
|
|||
import React, { useState, useMemo } from 'react'
|
||||
// Components
|
||||
import { SubAccordion } from '../Accordion.mjs'
|
||||
import {
|
||||
EditIcon,
|
||||
GroupIcon,
|
||||
OptionsIcon,
|
||||
ResetIcon,
|
||||
TipIcon,
|
||||
} from '@freesewing/react/components/Icon'
|
||||
import { EditIcon, GroupIcon, OptionsIcon, ResetIcon } from '@freesewing/react/components/Icon'
|
||||
import { CoreSettingsMenu } from './CoreSettingsMenu.mjs'
|
||||
import { FormControl } from '@freesewing/react/components/Input'
|
||||
import { MiniTip } from '@freesewing/react/components/Mini'
|
||||
|
||||
/** @type {String} class to apply to buttons on open menu items */
|
||||
const iconButtonClass = 'tw-daisy-btn tw-daisy-btn-xs tw-daisy-btn-ghost tw-px-0 tw-text-accent'
|
||||
|
@ -129,16 +124,7 @@ export const MenuItem = ({
|
|||
>
|
||||
<Input {...drillProps} />
|
||||
</FormControl>
|
||||
{config.about ? (
|
||||
<div className="tw-flex tw-flex-row tw-border tw-border-success tw-rounded">
|
||||
<div className="tw-bg-success tw-text-success-content tw-p-1 tw-rounded-l tw-flex tw-flex-row tw-items-center">
|
||||
<TipIcon className="tw-w-6 tw-h-6 tw-text-success-content" />
|
||||
</div>
|
||||
<div className="tw-p-1 tw-text-sm tw-font-medium tw-bg-success/10 tw-grow tw-rounded-r">
|
||||
{config.about}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
{config.about ? <MiniTip>{config.about}</MiniTip> : null}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,19 +3,23 @@ import { t, designMeasurements } from '../../lib/index.mjs'
|
|||
import { capitalize, horFlexClasses as horFlexClasses } from '@freesewing/utils'
|
||||
import { measurements as measurementsTranslations } from '@freesewing/i18n'
|
||||
// Hooks
|
||||
import React, { Fragment, useEffect } from 'react'
|
||||
import React, { Fragment, useState, useEffect } from 'react'
|
||||
import { useBackend } from '@freesewing/react/hooks/useBackend'
|
||||
// Components
|
||||
import { Popout } from '@freesewing/react/components/Popout'
|
||||
import { NumberInput } from '@freesewing/react/components/Input'
|
||||
import {
|
||||
BookmarkIcon,
|
||||
CuratedMeasurementsSetIcon,
|
||||
EditIcon,
|
||||
MeasurementsSetIcon,
|
||||
FingerprintIcon,
|
||||
} from '@freesewing/react/components/Icon'
|
||||
import { Accordion } from '../Accordion.mjs'
|
||||
import { MeasurementsEditor } from '../MeasurementsEditor.mjs'
|
||||
import { SetPicker, BookmarkedSetPicker, CuratedSetPicker, UserSetPicker } from '../Set.mjs'
|
||||
import { HeaderMenu } from '../HeaderMenu.mjs'
|
||||
import { H1, H5 } from '@freesewing/react/components/Heading'
|
||||
|
||||
const iconClasses = {
|
||||
className: 'tw-w-8 tw-h-8 md:tw-w-10 md:tw-h-10 lg:tw-w-12 lg:tw-h-12 tw-shrink-0',
|
||||
|
@ -35,7 +39,14 @@ const iconClasses = {
|
|||
* @param {Object} props.update - Helper object for updating the editor state
|
||||
* @return {Function} MeasurementsView - React component
|
||||
*/
|
||||
export const MeasurementsView = ({ config, Design, missingMeasurements, state, update }) => {
|
||||
export const MeasurementsView = ({
|
||||
config,
|
||||
Design,
|
||||
missingMeasurements,
|
||||
state,
|
||||
update,
|
||||
design,
|
||||
}) => {
|
||||
/*
|
||||
* If there is no view set, completing measurements will switch to the view picker
|
||||
* Which is a bit confusing. So in this case, set the view to measurements.
|
||||
|
@ -50,7 +61,7 @@ export const MeasurementsView = ({ config, Design, missingMeasurements, state, u
|
|||
},
|
||||
'missingMeasurements'
|
||||
)
|
||||
else update.notifySuccess(t('pe:measurementsAreOk'))
|
||||
else update.notifySuccess(`We have all measurements to draft ${capitalize(design)}`)
|
||||
}, [state.view, update])
|
||||
|
||||
const loadMeasurements = (set) => {
|
||||
|
@ -72,7 +83,7 @@ export const MeasurementsView = ({ config, Design, missingMeasurements, state, u
|
|||
[
|
||||
<Fragment key={1}>
|
||||
<div className={`${horFlexClasses} tw-w-full`}>
|
||||
<h4 id="ownsets">Choose one of your own measurements sets</h4>
|
||||
<H5 id="ownsets">Choose one of your own measurements sets</H5>
|
||||
<MeasurementsSetIcon {...iconClasses} />
|
||||
</div>
|
||||
<p className="tw-text-left">
|
||||
|
@ -92,7 +103,7 @@ export const MeasurementsView = ({ config, Design, missingMeasurements, state, u
|
|||
[
|
||||
<Fragment key={1}>
|
||||
<div className={`${horFlexClasses} tw-w-full`}>
|
||||
<h4 id="bookmarkedsets">Choose one of the measurements sets you have bookmarked</h4>
|
||||
<H5 id="bookmarkedsets">Choose one of the measurements sets you have bookmarked</H5>
|
||||
<BookmarkIcon {...iconClasses} />
|
||||
</div>
|
||||
<p className="tw-text-left">
|
||||
|
@ -111,7 +122,7 @@ export const MeasurementsView = ({ config, Design, missingMeasurements, state, u
|
|||
[
|
||||
<Fragment key={1}>
|
||||
<div className={`${horFlexClasses} tw-w-full`}>
|
||||
<h4 id="curatedsets">Choose one of FreeSewing's curated measurements sets</h4>
|
||||
<H5 id="curatedsets">Choose one of FreeSewing's curated measurements sets</H5>
|
||||
<CuratedMeasurementsSetIcon {...iconClasses} />
|
||||
</div>
|
||||
<p className="tw-text-left">
|
||||
|
@ -121,13 +132,27 @@ export const MeasurementsView = ({ config, Design, missingMeasurements, state, u
|
|||
</Fragment>,
|
||||
<CuratedSetPicker key={2} clickHandler={loadMeasurements} {...{ config, Design }} />,
|
||||
'csets',
|
||||
],
|
||||
[
|
||||
<Fragment key={1}>
|
||||
<div className={`${horFlexClasses} tw-w-full`}>
|
||||
<H5 id="loadid">Load a measurements set by ID</H5>
|
||||
<FingerprintIcon {...iconClasses} />
|
||||
</div>
|
||||
<p className="tw-text-left">
|
||||
If you know the ID of a measurements set — either one of your own or a public set — we
|
||||
can load it for you.
|
||||
</p>
|
||||
</Fragment>,
|
||||
<LoadMeasurementsSetById key={2} {...{ loadMeasurements, update }} />,
|
||||
'setid',
|
||||
]
|
||||
)
|
||||
// Manual editing is always an option
|
||||
items.push([
|
||||
<Fragment key={1}>
|
||||
<div className={`${horFlexClasses} tw-w-full`}>
|
||||
<h4 id="editmeasurements">Edit Measurements</h4>
|
||||
<H5 id="editmeasurements">Edit measurements by hand</H5>
|
||||
<EditIcon {...iconClasses} />
|
||||
</div>
|
||||
<p className="tw-text-left">You can manually set or override measurements below.</p>
|
||||
|
@ -140,7 +165,7 @@ export const MeasurementsView = ({ config, Design, missingMeasurements, state, u
|
|||
<>
|
||||
<HeaderMenu state={state} {...{ config, update }} />
|
||||
<div className="tw-max-w-7xl tw-mt-8 tw-mx-auto tw-px-4 tw-mb-4">
|
||||
<h1 className="tw-text-center">Measurements</h1>
|
||||
<H1>Measurements</H1>
|
||||
{missingMeasurements && missingMeasurements.length > 0 ? (
|
||||
<Popout note dense noP>
|
||||
<h3>
|
||||
|
@ -158,16 +183,16 @@ export const MeasurementsView = ({ config, Design, missingMeasurements, state, u
|
|||
</Popout>
|
||||
) : (
|
||||
<Popout tip dense noP>
|
||||
<h5>We have all required measurements to draft this pattern</h5>
|
||||
<H5>We have all required measurements to draft this pattern</H5>
|
||||
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-2 tw-mt-2">
|
||||
<button
|
||||
className="tw-daisy-btn tw-daisy-btn-primary lg:tw-daisy-btn-lg"
|
||||
className="tw-daisy-btn tw-daisy-btn-primary"
|
||||
onClick={() => update.view('draft')}
|
||||
>
|
||||
{viewLabels.draft.t}
|
||||
Draft Pattern
|
||||
</button>
|
||||
<button
|
||||
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline lg:tw-daisy-btn-lg"
|
||||
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline"
|
||||
onClick={() => update.view('picker')}
|
||||
>
|
||||
Choose a different view
|
||||
|
@ -180,3 +205,43 @@ export const MeasurementsView = ({ config, Design, missingMeasurements, state, u
|
|||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const LoadMeasurementsSetById = ({ loadMeasurements, update }) => {
|
||||
const backend = useBackend()
|
||||
const [id, setId] = useState('')
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-end">
|
||||
<NumberInput
|
||||
label="Measurements Set ID"
|
||||
update={setId}
|
||||
current={id}
|
||||
valid={(val) => Number(val) == val}
|
||||
/>
|
||||
<button
|
||||
className="tw-daisy-btn tw-daisy-btn-primary"
|
||||
onClick={() => loadMeasurementsSet(id, backend, loadMeasurements, update)}
|
||||
>
|
||||
Load set
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
async function loadMeasurementsSet(id, backend, loadMeasurements, update) {
|
||||
update.startLoading('getset', {
|
||||
msg: 'Loading measurements set from the FreeSewing backend',
|
||||
icon: 'spinner',
|
||||
})
|
||||
const result = await backend.getSet(id)
|
||||
if (result[0] === 200 && result[1].set) {
|
||||
loadMeasurements(result[1].set)
|
||||
update.clearLoading()
|
||||
update.notifySuccess('Measurements set loaded', 'getsetok')
|
||||
} else {
|
||||
update.clearLoading()
|
||||
update.notifySuccess('Measurements set loaded', 'getsetko')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import React from 'react'
|
||||
import { orderBy } from '@freesewing/utils'
|
||||
import { ButtonFrame } from '@freesewing/react/components/Input'
|
||||
import { UndoIcon } from '@freesewing/react/components/Icon'
|
||||
import { Popout } from '@freesewing/react/components/Popout'
|
||||
import { UndoIcon, TipIcon, LeftIcon } from '@freesewing/react/components/Icon'
|
||||
import { HeaderMenu } from '../HeaderMenu.mjs'
|
||||
import { H1 } from '@freesewing/react/components/Heading'
|
||||
import { MiniTip } from '@freesewing/react/components/Mini'
|
||||
|
||||
import { getUndoStepData } from '../../lib/index.mjs'
|
||||
|
||||
|
@ -12,18 +16,15 @@ import { getUndoStepData } from '../../lib/index.mjs'
|
|||
* @param {object} designs - Object holding all designs
|
||||
* @param {object} update - ViewWrapper state update object
|
||||
*/
|
||||
export const UndosView = ({ Design, update, state }) => {
|
||||
export const UndosView = ({ Design, update, state, config }) => {
|
||||
const steps = orderBy(state._.undos, 'time', 'desc')
|
||||
|
||||
return (
|
||||
<>
|
||||
<HeaderMenu state={state} {...{ update, Design }} />
|
||||
<HeaderMenu {...{ update, Design, config, state }} />
|
||||
<div className="tw-text-left tw-mt-8 tw-mb-24 tw-px-4 tw-max-w-xl tw-mx-auto">
|
||||
<h2>Undo History</h2>
|
||||
<p>Time-travel through your recent pattern changes</p>
|
||||
<small>
|
||||
<b>Tip:</b> Click on any change to undo all changes up to, and including, that change.
|
||||
</small>
|
||||
<H1>Undo History</H1>
|
||||
<p className="tw-mb-4">Time-travel through your recent pattern changes.</p>
|
||||
{steps.length < 1 ? (
|
||||
<Popout note>
|
||||
<h4>Your undo history is currently empty</h4>
|
||||
|
@ -38,11 +39,16 @@ export const UndosView = ({ Design, update, state }) => {
|
|||
<p>As soon as you do, the change will show up here, and you can undo it.</p>
|
||||
</Popout>
|
||||
) : (
|
||||
<>
|
||||
<MiniTip>
|
||||
Click on any change to undo all changes up to, and including, that change.
|
||||
</MiniTip>
|
||||
<div className="tw-flex tw-flex-col tw-gap-2 tw-mt-4">
|
||||
{steps.map((step, index) => (
|
||||
<UndoStep key={step.time} {...{ step, update, state, Design, index }} />
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
|
@ -93,7 +99,7 @@ export const UndoStep = ({ update, state, step, Design, compact = false, index =
|
|||
<ButtonFrame dense onClick={() => update.restore(index, state._)}>
|
||||
<div className="tw-flex tw-flex-row tw-items-center tw-align-start tw-gap-2 tw-w-full">
|
||||
<UndoIcon text={index} className="tw-w-5 tw-h-5 tw-text-secondary" />
|
||||
{data.msg ? data.msg : `pe:${data.optCode}`}
|
||||
{data.msg ? data.msg : data.title}
|
||||
</div>
|
||||
</ButtonFrame>
|
||||
)
|
||||
|
@ -107,10 +113,10 @@ export const UndoStep = ({ update, state, step, Design, compact = false, index =
|
|||
<div className="tw-flex tw-flex-row tw-items-center tw-justify-between tw-gap-2 tw-w-full tw-m-0 tw-p-0 tw--mt-2 tw-text-lg">
|
||||
<span className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
|
||||
{data.fieldIcon || null}
|
||||
{`pe:${data.optCode}`}
|
||||
{data.title}
|
||||
</span>
|
||||
<span className="tw-opacity-70 tw-flex tw-flex-row tw-gap-1 tw-items-center tw-text-base">
|
||||
{data.icon || null} {`pe:${data.titleCode}`}
|
||||
{data.icon || null} {data.menu}
|
||||
</span>
|
||||
</div>
|
||||
<div className="tw-flex tw-flex-row tw-gap-1 tw-items-center tw-align-start tw-w-full">
|
||||
|
|
|
@ -5,6 +5,7 @@ import { MeasurementsView } from './MeasurementsView.mjs'
|
|||
import { DraftView } from './DraftView.mjs'
|
||||
import { SaveView } from './SaveView.mjs'
|
||||
import { ExportView } from './ExportView.mjs'
|
||||
import { UndosView } from './UndosView.mjs'
|
||||
import { ErrorIcon } from '@freesewing/react/components/Icon'
|
||||
import {
|
||||
OptionsIcon,
|
||||
|
@ -55,6 +56,7 @@ export const View = (props) => {
|
|||
if (view === 'draft') return <DraftView {...props} />
|
||||
if (view === 'save') return <SaveView {...props} />
|
||||
if (view === 'export') return <ExportView {...props} />
|
||||
if (view === 'undos') return <UndosView {...props} />
|
||||
/*
|
||||
viewComponents: {
|
||||
draft: 'DraftView',
|
||||
|
|
|
@ -138,7 +138,7 @@ export const defaultConfig = {
|
|||
base: 'user',
|
||||
},
|
||||
// Ms before to fade out a notification
|
||||
notifyTimeout: 6660,
|
||||
notifyTimeout: 2500,
|
||||
degreeMeasurements: ['shoulderSlope'],
|
||||
}
|
||||
|
||||
|
|
|
@ -71,8 +71,8 @@ export function getUiPreferenceUndoStepData({ step }) {
|
|||
const data = {
|
||||
icon: <UiIcon />,
|
||||
field,
|
||||
optCode: `${field}.t`,
|
||||
titleCode: 'uiPreferences.t',
|
||||
title: structure.title,
|
||||
menu: 'UI Preferences',
|
||||
structure: menuUiPreferencesStructure()[field],
|
||||
}
|
||||
const FieldIcon = data.structure.icon
|
||||
|
@ -85,7 +85,7 @@ export function getUiPreferenceUndoStepData({ step }) {
|
|||
data[key + 'Val'] = t(
|
||||
structure.choiceTitles[
|
||||
structure.choiceTitles[String(step[key])] ? String(step[key]) : String(structure.dflt)
|
||||
] + '.t'
|
||||
]
|
||||
)
|
||||
|
||||
return data
|
||||
|
@ -102,8 +102,8 @@ export function getCoreSettingUndoStepData({ step, state, Design }) {
|
|||
|
||||
const data = {
|
||||
field,
|
||||
titleCode: 'coreSettings.t',
|
||||
optCode: `${field}.t`,
|
||||
menu: 'Core Settings',
|
||||
title: structure?.[field] ? structure[field].title : '',
|
||||
icon: <SettingsIcon />,
|
||||
structure: structure[field],
|
||||
}
|
||||
|
@ -125,9 +125,7 @@ export function getCoreSettingUndoStepData({ step, state, Design }) {
|
|||
case 'margin':
|
||||
case 'sa':
|
||||
case 'samm':
|
||||
if (data.field !== 'margin') {
|
||||
data.optCode = `samm.t`
|
||||
}
|
||||
if (data.field !== 'margin') data.title = 'Seam Allowance'
|
||||
data.oldVal = <Html html={formatMm(cord(step.old, data.structure.dflt))} />
|
||||
data.newVal = <Html html={formatMm(cord(step.new, data.structure.dflt))} />
|
||||
return data
|
||||
|
@ -136,23 +134,23 @@ export function getCoreSettingUndoStepData({ step, state, Design }) {
|
|||
data.newVal = cord(step.new, data.structure.dflt)
|
||||
return data
|
||||
case 'units':
|
||||
data.oldVal = t(step.new === 'imperial' ? 'pe:metricUnits' : 'pe:imperialUnits')
|
||||
data.newVal = t(step.new === 'imperial' ? 'pe:imperialUnits' : 'pe:metricUnits')
|
||||
data.oldVal = t(step.new === 'imperial' ? 'Metric Units' : 'Imperial Units')
|
||||
data.newVal = t(step.new === 'imperial' ? 'Imperial Units' : 'Metric Units')
|
||||
return data
|
||||
case 'only':
|
||||
data.oldVal = cord(step.old, data.structure.dflt) || t('pe:includeAllParts')
|
||||
data.newVal = cord(step.new, data.structure.dflt) || t('pe:includeAllParts')
|
||||
data.oldVal = cord(step.old, data.structure.dflt) || 'Include all parts'
|
||||
data.newVal = cord(step.new, data.structure.dflt) || 'Include all parts'
|
||||
return data
|
||||
default:
|
||||
data.oldVal = t(
|
||||
(data.structure.choiceTitles[String(step.old)]
|
||||
data.structure.choiceTitles[String(step.old)]
|
||||
? data.structure.choiceTitles[String(step.old)]
|
||||
: data.structure.choiceTitles[String(data.structure.dflt)]) + '.t'
|
||||
: data.structure.choiceTitles[String(data.structure.dflt)]
|
||||
)
|
||||
data.newVal = t(
|
||||
(data.structure.choiceTitles[String(step.new)]
|
||||
data.structure.choiceTitles[String(step.new)]
|
||||
? data.structure.choiceTitles[String(step.new)]
|
||||
: data.structure.choiceTitles[String(data.structure.dflt)]) + '.t'
|
||||
: data.structure.choiceTitles[String(data.structure.dflt)]
|
||||
)
|
||||
return data
|
||||
}
|
||||
|
@ -163,8 +161,8 @@ export function getDesignOptionUndoStepData({ step, state, Design }) {
|
|||
const data = {
|
||||
icon: <OptionsIcon />,
|
||||
field: step.path[2],
|
||||
optCode: `${state.design}:${step.path[2]}.t`,
|
||||
titleCode: `designOptions.t`,
|
||||
title: `${state.design}:${step.path[2]}`,
|
||||
menu: `Design Options`,
|
||||
oldVal: formatDesignOptionValue(option, step.old, state.units === 'imperial'),
|
||||
newVal: formatDesignOptionValue(option, step.new, state.units === 'imperial'),
|
||||
}
|
||||
|
@ -212,8 +210,8 @@ export function getUndoStepData(props) {
|
|||
const data = {
|
||||
icon: <MeasurementsIcon />,
|
||||
field: 'measurements',
|
||||
optCode: `measurements`,
|
||||
titleCode: 'measurements',
|
||||
title: `measurements`,
|
||||
menu: 'measurements',
|
||||
}
|
||||
/*
|
||||
* Single measurements change?
|
||||
|
@ -229,7 +227,7 @@ export function getUndoStepData(props) {
|
|||
for (const m of Object.keys(props.step.new)) {
|
||||
if (props.step.new[m] !== props.step.old?.[m]) count++
|
||||
}
|
||||
return { ...data, msg: t('pe:xMeasurementsChanged', { count }) }
|
||||
return { ...data, msg: `${count} measurements updated` }
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
13
packages/react/components/Mini/index.mjs
Normal file
13
packages/react/components/Mini/index.mjs
Normal file
|
@ -0,0 +1,13 @@
|
|||
import React from 'react'
|
||||
import { TipIcon } from '@freesewing/react/components/Icon'
|
||||
|
||||
export const MiniTip = ({ children }) => (
|
||||
<div className="tw-flex tw-flex-row tw-border tw-border-success tw-rounded">
|
||||
<div className="tw-bg-success tw-text-success-content tw-p-1 tw-rounded-l tw-flex tw-flex-row tw-items-center">
|
||||
<TipIcon className="tw-w-6 tw-h-6 tw-text-success-content" />
|
||||
</div>
|
||||
<div className="tw-p-1 tw-px-2 tw-text-sm tw-font-medium tw-bg-success/10 tw-grow tw-rounded-r">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
|
@ -46,6 +46,7 @@
|
|||
"./components/LineDrawing": "./components/LineDrawing/index.mjs",
|
||||
"./components/Link": "./components/Link/index.mjs",
|
||||
"./components/Logo": "./components/Logo/index.mjs",
|
||||
"./components/Mini": "./components/Mini/index.mjs",
|
||||
"./components/Modal": "./components/Modal/index.mjs",
|
||||
"./components/New": "./components/New/index.mjs",
|
||||
"./components/Number": "./components/Number/index.mjs",
|
||||
|
@ -86,12 +87,12 @@
|
|||
"html-react-parser": "^5.0.7",
|
||||
"luxon": "^3.5.0",
|
||||
"nuqs": "^1.17.6",
|
||||
"pdfkit": "^0.16.0",
|
||||
"react-markdown": "^9.0.1",
|
||||
"tlds": "^1.255.0",
|
||||
"use-local-storage-state": "19.1.0",
|
||||
"use-session-storage-state": "^19.0.0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"files": [
|
||||
"components/**",
|
||||
"hooks/**",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue