feat(admin): filter inventory by status directly, so Published and Unpublished are reachable (#132) #134
@@ -8,6 +8,10 @@ import Col from 'antd/es/col';
|
||||
import Alert from 'antd/es/alert';
|
||||
import Typography from 'antd/es/typography';
|
||||
import message from 'antd/es/message';
|
||||
import MDEditor from '@uiw/react-md-editor';
|
||||
import '@uiw/react-md-editor/markdown-editor.css';
|
||||
import '@uiw/react-markdown-preview/markdown.css';
|
||||
import { useThemeMode } from '../theme/ThemeContext';
|
||||
import {
|
||||
EmailTemplate,
|
||||
saveEmailTemplate,
|
||||
@@ -27,6 +31,7 @@ type Props = Readonly<{
|
||||
const PREVIEW_DEBOUNCE_MS = 400;
|
||||
|
||||
export default function EmailTemplateEditor({ template, onChanged }: Props) {
|
||||
const { mode } = useThemeMode();
|
||||
// Falls back to the default so the editor starts from the real copy rather
|
||||
// than an empty box. `subject`/`body` being null means "never customised",
|
||||
// which is why the badge on the tab can say so.
|
||||
@@ -111,13 +116,28 @@ export default function EmailTemplateEditor({ template, onChanged }: Props) {
|
||||
placeholder="Subject"
|
||||
style={{ marginBottom: 8 }}
|
||||
/>
|
||||
<Input.TextArea
|
||||
aria-label={`${template.label} body`}
|
||||
{/* The same editor the item description uses, so an admin who has
|
||||
learned one toolbar has learned both. data-color-mode is what makes
|
||||
it follow the admin's dark mode, exactly as on the item form.
|
||||
|
||||
preview="edit" rather than the item form's "live": MDEditor's own
|
||||
preview would render the markdown with a different renderer, showing
|
||||
a literal {{resetUrl}} and no consent footer. The pane on the right
|
||||
is the server's rendering of the actual email, and two previews
|
||||
disagreeing about the thing being edited is worse than one. */}
|
||||
<div data-color-mode={mode} style={{ marginBottom: 12 }}>
|
||||
<MDEditor
|
||||
value={body}
|
||||
onChange={(e) => setBody(e.target.value)}
|
||||
autoSize={{ minRows: 10, maxRows: 24 }}
|
||||
style={{ fontFamily: 'monospace', marginBottom: 12 }}
|
||||
onChange={(val) => setBody(val || '')}
|
||||
height={320}
|
||||
preview="edit"
|
||||
// Input.TextArea carried this attribute itself. MDEditor owns the
|
||||
// textarea, so the label has to be passed through — without it every
|
||||
// email template test loses its handle on the field, and a screen
|
||||
// reader loses the only thing naming it.
|
||||
textareaProps={{ 'aria-label': `${template.label} body` }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Space>
|
||||
<Button type="primary" loading={saving} onClick={handleSave}>
|
||||
|
||||
Reference in New Issue
Block a user