u
This commit is contained in:
@@ -17,6 +17,7 @@ import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined
|
||||
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
|
||||
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
|
||||
import GoogleIcon from '@mui/icons-material/Google';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import AppDialog from './AppDialog';
|
||||
import { thumb, article as articleApi } from '../api';
|
||||
@@ -29,6 +30,7 @@ import {
|
||||
articleWithPhotoOrder,
|
||||
articleWithUploadedPhoto,
|
||||
articleWithoutPhoto,
|
||||
buildGoogleSearchQuery,
|
||||
formatPhotoDimensions,
|
||||
formatPhotoSizeKb,
|
||||
sortedPhotos,
|
||||
@@ -182,6 +184,22 @@ function resolveTitle(props, single) {
|
||||
}
|
||||
return single ? 'Bild' : 'Bilder';
|
||||
}
|
||||
|
||||
function resolveGoogleImagesQuery(props) {
|
||||
if (props.article) {
|
||||
return buildGoogleSearchQuery(props.article);
|
||||
}
|
||||
if (props.brand?.name) {
|
||||
return String(props.brand.name).trim();
|
||||
}
|
||||
if (props.category?.name) {
|
||||
return String(props.category.name).trim();
|
||||
}
|
||||
if (props.attributeValue) {
|
||||
return String(props.attributeValue.value || props.attributeValue.name || '').trim();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
// #endregion
|
||||
|
||||
/**
|
||||
@@ -400,6 +418,13 @@ export default class PicturesDialog extends PureComponent {
|
||||
handleSearchClose = () => {
|
||||
this.setState({ searchOpen: false });
|
||||
};
|
||||
|
||||
handleOpenGoogleImages = () => {
|
||||
const query = resolveGoogleImagesQuery(this.props);
|
||||
if (!query) return;
|
||||
const url = `https://www.google.com/search?tbm=isch&q=${encodeURIComponent(query)}`;
|
||||
window.open(url, '_blank', 'noopener,noreferrer');
|
||||
};
|
||||
// #endregion
|
||||
|
||||
// #region render helpers
|
||||
@@ -627,6 +652,7 @@ export default class PicturesDialog extends PureComponent {
|
||||
const pics = resolvePictures(this.props, single);
|
||||
const title = resolveTitle(this.props, single);
|
||||
const hasPic = Boolean(pics[0]?.fullHash || pics[0]?.thumbHash);
|
||||
const googleQuery = resolveGoogleImagesQuery(this.props);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -781,6 +807,16 @@ export default class PicturesDialog extends PureComponent {
|
||||
>
|
||||
Bild suchen
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
variant="outlined"
|
||||
startIcon={<GoogleIcon />}
|
||||
disabled={busy || disabled || !googleQuery}
|
||||
onClick={this.handleOpenGoogleImages}
|
||||
title={googleQuery ? `Google Bilder-Suche: ${googleQuery}` : 'Google'}
|
||||
>
|
||||
Google
|
||||
</Button>
|
||||
</Box>
|
||||
<Button
|
||||
size="small"
|
||||
|
||||
@@ -5,14 +5,24 @@ import Stack from '@mui/material/Stack';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import CallMergeIcon from '@mui/icons-material/CallMerge';
|
||||
import GoogleIcon from '@mui/icons-material/Google';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
|
||||
import { article as articleApi } from '../../../api';
|
||||
import { artikelAutomat, getArticle } from '../../../automats';
|
||||
import { notifyError } from '../../../utils/notify';
|
||||
import {
|
||||
articleEans,
|
||||
getArticleEan,
|
||||
getArticleBrand,
|
||||
getArticleName,
|
||||
buildGoogleSearchQuery,
|
||||
} from '../../../utils/articleDetail';
|
||||
import ArticleSearch from '../ArticleSearch';
|
||||
import ArticleUnifyDialog from '../ArticleUnifyDialog';
|
||||
|
||||
export { getArticleEan, getArticleBrand, getArticleName, buildGoogleSearchQuery };
|
||||
|
||||
export function isArticleFather(article) {
|
||||
if (!article) return false;
|
||||
return Boolean(
|
||||
@@ -48,6 +58,15 @@ export default class ArticleSettingsTab extends Component {
|
||||
this.handleDeleteArticle = this.handleDeleteArticle.bind(this);
|
||||
this.handleOpenSearch = this.handleOpenSearch.bind(this);
|
||||
this.handleSelectTargetArticle = this.handleSelectTargetArticle.bind(this);
|
||||
this.handleOpenGoogle = this.handleOpenGoogle.bind(this);
|
||||
}
|
||||
|
||||
handleOpenGoogle() {
|
||||
const { article: articleData } = this.props;
|
||||
const query = buildGoogleSearchQuery(articleData);
|
||||
if (!query) return;
|
||||
const url = `https://www.google.com/search?q=${encodeURIComponent(query)}`;
|
||||
window.open(url, '_blank', 'noopener,noreferrer');
|
||||
}
|
||||
|
||||
async handleDeleteArticle() {
|
||||
@@ -128,6 +147,7 @@ export default class ArticleSettingsTab extends Component {
|
||||
: isStueckliste
|
||||
? 'Ein Stücklisten-Artikel kann nicht vereint werden.'
|
||||
: null;
|
||||
const googleQuery = buildGoogleSearchQuery(articleData);
|
||||
|
||||
return (
|
||||
<Box>
|
||||
@@ -169,6 +189,18 @@ export default class ArticleSettingsTab extends Component {
|
||||
Artikel vereinen
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
startIcon={<GoogleIcon />}
|
||||
disabled={busy || !googleQuery}
|
||||
onClick={this.handleOpenGoogle}
|
||||
title={googleQuery ? `Google-Suche: ${googleQuery}` : 'Google'}
|
||||
>
|
||||
Google
|
||||
</Button>
|
||||
</Stack>
|
||||
|
||||
<ArticleSearch
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
netFromGross,
|
||||
parsePriceInput,
|
||||
} from './price';
|
||||
import brandAutomat from '../automats/brandAutomat';
|
||||
|
||||
export function sortedPhotos(article) {
|
||||
if (!Array.isArray(article?.photos)) return [];
|
||||
@@ -150,6 +151,51 @@ export function articleEans(article) {
|
||||
return article.eans.filter(Boolean);
|
||||
}
|
||||
|
||||
export function getArticleEan(article) {
|
||||
if (!article) return '';
|
||||
const eans = articleEans(article);
|
||||
if (eans.length > 0) {
|
||||
const first = eans[0];
|
||||
return String(typeof first === 'object' && first ? (first.ean ?? '') : first ?? '').trim();
|
||||
}
|
||||
if (article.ean) {
|
||||
return String(typeof article.ean === 'object' && article.ean ? (article.ean.ean ?? '') : article.ean).trim();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
export function getArticleBrand(article) {
|
||||
if (!article) return '';
|
||||
if (typeof article.brand === 'object' && article.brand?.name) {
|
||||
return String(article.brand.name).trim();
|
||||
}
|
||||
if (typeof article.brand === 'string' && article.brand.trim()) {
|
||||
return article.brand.trim();
|
||||
}
|
||||
if (article.brandName) {
|
||||
return String(article.brandName).trim();
|
||||
}
|
||||
if (article.brandId != null) {
|
||||
const brands = brandAutomat?.state?.brands || [];
|
||||
const b = brands.find((x) => x.id === article.brandId);
|
||||
if (b?.name) return String(b.name).trim();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
export function getArticleName(article) {
|
||||
if (!article) return '';
|
||||
return String(article.name ?? article.sku ?? '').trim();
|
||||
}
|
||||
|
||||
export function buildGoogleSearchQuery(article) {
|
||||
if (!article) return '';
|
||||
const ean = getArticleEan(article);
|
||||
const brand = getArticleBrand(article);
|
||||
const name = getArticleName(article);
|
||||
return [ean, brand, name].filter(Boolean).join(' ');
|
||||
}
|
||||
|
||||
export function formatPhotoSizeKb(fullSize) {
|
||||
return `${Math.round(fullSize / 1024)} KB`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user