u
This commit is contained in:
@@ -7,7 +7,7 @@ import CategoryIcon from '@mui/icons-material/Category';
|
||||
import HistoryIcon from '@mui/icons-material/History';
|
||||
import LabelIcon from '@mui/icons-material/Label';
|
||||
import LocalShippingIcon from '@mui/icons-material/LocalShipping';
|
||||
import ManageSearchIcon from '@mui/icons-material/ManageSearch';
|
||||
import DescriptionIcon from '@mui/icons-material/Description';
|
||||
import PushPinIcon from '@mui/icons-material/PushPin';
|
||||
import SettingsIcon from '@mui/icons-material/Settings';
|
||||
import {
|
||||
@@ -27,7 +27,7 @@ import { PANEL_TILE_BORDER_RADIUS, responsiveColumnSpan } from 'dashgui/panels/p
|
||||
import ArticleAttributesTab from './tabs/ArticleAttributesTab';
|
||||
import ArticleHistoryTab from './tabs/ArticleHistoryTab';
|
||||
import ArticleLabelTab from './tabs/ArticleLabelTab';
|
||||
import ArticleSeoTab from './tabs/ArticleSeoTab';
|
||||
import ArticleDescTab from './tabs/ArticleDescTab';
|
||||
import ArticleSettingsTab from './tabs/ArticleSettingsTab';
|
||||
import ArticleSupplierTab from './tabs/ArticleSupplierTab';
|
||||
import HelpBadge from '../HelpBadge';
|
||||
@@ -58,11 +58,11 @@ const ALWAYS_TABS = [
|
||||
help: 'Zugeordnete Lieferanten, Einkaufspreise und Lieferanten-Artikelnummern',
|
||||
},
|
||||
{
|
||||
id: ARTICLE_TAB.seo,
|
||||
label: 'SEO & Beschreibung',
|
||||
id: ARTICLE_TAB.desc,
|
||||
label: 'Beschreibung',
|
||||
color: PETROL_PANEL,
|
||||
Icon: ManageSearchIcon,
|
||||
help: 'Shop-Texte, Beschreibungen und Suchmaschinen-Metadaten',
|
||||
Icon: DescriptionIcon,
|
||||
help: 'Shop-Texte, Beschreibungen und Produktdetails',
|
||||
},
|
||||
{
|
||||
id: ARTICLE_TAB.label,
|
||||
@@ -184,8 +184,8 @@ class ArticleTileTab extends PureComponent {
|
||||
return <ArticleHistoryTab sku={articleData.sku} />;
|
||||
case ARTICLE_TAB.supplier:
|
||||
return <ArticleSupplierTab article={articleData} />;
|
||||
case ARTICLE_TAB.seo:
|
||||
return <ArticleSeoTab article={articleData} />;
|
||||
case ARTICLE_TAB.desc:
|
||||
return <ArticleDescTab article={articleData} />;
|
||||
case ARTICLE_TAB.label:
|
||||
return <ArticleLabelTab article={articleData} />;
|
||||
case ARTICLE_TAB.attributes:
|
||||
|
||||
@@ -3,14 +3,15 @@ import { matchPath } from 'react-router-dom';
|
||||
export const ARTICLE_TAB = {
|
||||
history: 'history',
|
||||
supplier: 'supplier',
|
||||
seo: 'seo',
|
||||
desc: 'desc',
|
||||
seo: 'desc',
|
||||
label: 'label',
|
||||
attributes: 'attributes',
|
||||
settings: 'settings',
|
||||
};
|
||||
|
||||
/** Factory fallback when nothing is stored in localStorage. */
|
||||
export const DEFAULT_ARTICLE_TAB = ARTICLE_TAB.seo;
|
||||
export const DEFAULT_ARTICLE_TAB = ARTICLE_TAB.desc;
|
||||
|
||||
const PREFERRED_ARTICLE_TAB_KEY = 'dashfront:article-default-tab';
|
||||
|
||||
@@ -19,7 +20,7 @@ const ALL_ARTICLE_TAB_IDS = new Set(Object.values(ARTICLE_TAB));
|
||||
const BASE_ARTICLE_TAB_IDS = [
|
||||
ARTICLE_TAB.history,
|
||||
ARTICLE_TAB.supplier,
|
||||
ARTICLE_TAB.seo,
|
||||
ARTICLE_TAB.desc,
|
||||
ARTICLE_TAB.label,
|
||||
ARTICLE_TAB.attributes,
|
||||
];
|
||||
@@ -45,6 +46,7 @@ export function isArticleTabId(tab) {
|
||||
export function readPreferredArticleTab() {
|
||||
try {
|
||||
const raw = localStorage.getItem(PREFERRED_ARTICLE_TAB_KEY);
|
||||
if (raw === 'seo') return ARTICLE_TAB.desc;
|
||||
if (raw && isArticleTabId(raw)) return raw;
|
||||
} catch {
|
||||
// ignore quota / private mode
|
||||
@@ -71,6 +73,7 @@ export function preferredArticleTab(article) {
|
||||
|
||||
export function resolveArticleTab(tabParam, article) {
|
||||
const ids = articleTabIds(article);
|
||||
if (tabParam === 'seo') return ARTICLE_TAB.desc;
|
||||
if (tabParam && ids.includes(tabParam)) return tabParam;
|
||||
return preferredArticleTab(article);
|
||||
}
|
||||
@@ -92,9 +95,10 @@ export function artikelDetailPath(articleOrSku, tab) {
|
||||
: articleSku(articleOrSku);
|
||||
if (!sku) return null;
|
||||
|
||||
const normalizedTab = tab === 'seo' ? ARTICLE_TAB.desc : tab;
|
||||
let segment;
|
||||
if (isArticleTabId(tab)) {
|
||||
segment = tab;
|
||||
if (isArticleTabId(normalizedTab)) {
|
||||
segment = normalizedTab;
|
||||
} else if (articleOrSku && typeof articleOrSku === 'object') {
|
||||
segment = preferredArticleTab(articleOrSku);
|
||||
} else {
|
||||
|
||||
68
src/components/article/tabs/ArticleDescTab.jsx
Normal file
68
src/components/article/tabs/ArticleDescTab.jsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import { Component } from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import PageMinimap from '../../PageMinimap';
|
||||
|
||||
function PanelHtmlValue({ html }) {
|
||||
if (html == null || html === '') return null;
|
||||
return (
|
||||
<Box sx={{ mb: 1.5 }}>
|
||||
<Box
|
||||
sx={(theme) => ({
|
||||
p: 1.5,
|
||||
borderRadius: 1.5,
|
||||
bgcolor:
|
||||
theme.palette.mode === 'dark'
|
||||
? 'rgba(255, 255, 255, 0.08)'
|
||||
: 'rgba(255, 255, 255, 0.85)',
|
||||
border: '1px solid',
|
||||
borderColor:
|
||||
theme.palette.mode === 'dark'
|
||||
? 'rgba(255, 255, 255, 0.12)'
|
||||
: 'rgba(255, 255, 255, 0.95)',
|
||||
boxShadow:
|
||||
theme.palette.mode === 'dark'
|
||||
? 'none'
|
||||
: '0 1px 3px rgba(0, 0, 0, 0.04)',
|
||||
fontSize: '0.875rem',
|
||||
lineHeight: 1.55,
|
||||
color: 'text.primary',
|
||||
wordBreak: 'break-word',
|
||||
'& h1, & h2, & h3, & h4, & h5, & h6': {
|
||||
fontSize: '1rem',
|
||||
fontWeight: 600,
|
||||
mt: 1.25,
|
||||
mb: 0.5,
|
||||
'&:first-child': { mt: 0 },
|
||||
},
|
||||
'& p': {
|
||||
my: 0.5,
|
||||
'&:first-child': { mt: 0 },
|
||||
'&:last-child': { mb: 0 },
|
||||
},
|
||||
'& ul, & ol': {
|
||||
pl: 2.5,
|
||||
my: 0.5,
|
||||
},
|
||||
'& a': {
|
||||
color: 'primary.main',
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
})}
|
||||
dangerouslySetInnerHTML={{ __html: html }}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default class ArticleDescTab extends Component {
|
||||
render() {
|
||||
const { article: articleData } = this.props;
|
||||
const desc = articleData.desc ?? articleData.description;
|
||||
return (
|
||||
<>
|
||||
<PanelHtmlValue html={desc} />
|
||||
<PageMinimap />
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,68 +1,2 @@
|
||||
import { Component } from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import PageMinimap from '../../PageMinimap';
|
||||
export { default } from './ArticleDescTab';
|
||||
|
||||
function PanelHtmlValue({ html }) {
|
||||
if (html == null || html === '') return null;
|
||||
return (
|
||||
<Box sx={{ mb: 1.5 }}>
|
||||
<Box
|
||||
sx={(theme) => ({
|
||||
p: 1.5,
|
||||
borderRadius: 1.5,
|
||||
bgcolor:
|
||||
theme.palette.mode === 'dark'
|
||||
? 'rgba(255, 255, 255, 0.08)'
|
||||
: 'rgba(255, 255, 255, 0.85)',
|
||||
border: '1px solid',
|
||||
borderColor:
|
||||
theme.palette.mode === 'dark'
|
||||
? 'rgba(255, 255, 255, 0.12)'
|
||||
: 'rgba(255, 255, 255, 0.95)',
|
||||
boxShadow:
|
||||
theme.palette.mode === 'dark'
|
||||
? 'none'
|
||||
: '0 1px 3px rgba(0, 0, 0, 0.04)',
|
||||
fontSize: '0.875rem',
|
||||
lineHeight: 1.55,
|
||||
color: 'text.primary',
|
||||
wordBreak: 'break-word',
|
||||
'& h1, & h2, & h3, & h4, & h5, & h6': {
|
||||
fontSize: '1rem',
|
||||
fontWeight: 600,
|
||||
mt: 1.25,
|
||||
mb: 0.5,
|
||||
'&:first-child': { mt: 0 },
|
||||
},
|
||||
'& p': {
|
||||
my: 0.5,
|
||||
'&:first-child': { mt: 0 },
|
||||
'&:last-child': { mb: 0 },
|
||||
},
|
||||
'& ul, & ol': {
|
||||
pl: 2.5,
|
||||
my: 0.5,
|
||||
},
|
||||
'& a': {
|
||||
color: 'primary.main',
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
})}
|
||||
dangerouslySetInnerHTML={{ __html: html }}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default class ArticleSeoTab extends Component {
|
||||
render() {
|
||||
const { article: articleData } = this.props;
|
||||
const desc = articleData.desc ?? articleData.description;
|
||||
return (
|
||||
<>
|
||||
<PanelHtmlValue html={desc} />
|
||||
<PageMinimap />
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user