u
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
import { Component, PureComponent } from 'react';
|
import { Component, PureComponent } from 'react';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import InputAdornment from '@mui/material/InputAdornment';
|
|
||||||
import TextField from '@mui/material/TextField';
|
import TextField from '@mui/material/TextField';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import { EditablePanelTile, PanelTile } from 'dashgui/panels';
|
import { EditablePanelTile, PanelTile } from 'dashgui/panels';
|
||||||
@@ -45,12 +44,12 @@ const articlePriceTextSx = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const articlePriceFieldSx = {
|
const articlePriceFieldSx = {
|
||||||
flexShrink: 0,
|
flexShrink: 1,
|
||||||
width: 'auto',
|
width: '100%',
|
||||||
mr: 11,
|
|
||||||
'& .MuiOutlinedInput-root': {
|
'& .MuiOutlinedInput-root': {
|
||||||
alignItems: 'baseline',
|
alignItems: 'baseline',
|
||||||
flexShrink: 0,
|
width: '100%',
|
||||||
|
flexShrink: 1,
|
||||||
},
|
},
|
||||||
'& .MuiInputBase-input': {
|
'& .MuiInputBase-input': {
|
||||||
fontSize: '3.5rem',
|
fontSize: '3.5rem',
|
||||||
@@ -58,17 +57,6 @@ const articlePriceFieldSx = {
|
|||||||
height: 'auto',
|
height: 'auto',
|
||||||
...articlePriceTextSx,
|
...articlePriceTextSx,
|
||||||
},
|
},
|
||||||
'& .MuiInputAdornment-root': {
|
|
||||||
marginRight: 0.75,
|
|
||||||
height: 'auto',
|
|
||||||
maxHeight: 'none',
|
|
||||||
alignItems: 'baseline',
|
|
||||||
},
|
|
||||||
'& .MuiInputAdornment-root .MuiTypography-root': {
|
|
||||||
fontSize: '2rem',
|
|
||||||
fontWeight: 700,
|
|
||||||
lineHeight: 1.1,
|
|
||||||
},
|
|
||||||
'& .MuiOutlinedInput-notchedOutline': {
|
'& .MuiOutlinedInput-notchedOutline': {
|
||||||
borderWidth: '1px !important',
|
borderWidth: '1px !important',
|
||||||
},
|
},
|
||||||
@@ -96,6 +84,7 @@ const priceBodySx = {
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
gap: 0.75,
|
gap: 0.75,
|
||||||
|
pt: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
function articleHasPackUnit(art) {
|
function articleHasPackUnit(art) {
|
||||||
@@ -198,11 +187,6 @@ class PriceAmountField extends Component {
|
|||||||
slotProps={{
|
slotProps={{
|
||||||
input: {
|
input: {
|
||||||
readOnly,
|
readOnly,
|
||||||
startAdornment: (
|
|
||||||
<InputAdornment position="start">
|
|
||||||
<Typography component="span">€</Typography>
|
|
||||||
</InputAdornment>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
htmlInput: {
|
htmlInput: {
|
||||||
inputMode: 'decimal',
|
inputMode: 'decimal',
|
||||||
@@ -524,8 +508,8 @@ export default class ArticleViewPrice extends PureComponent {
|
|||||||
const max = Math.max(...prices);
|
const max = Math.max(...prices);
|
||||||
priceText =
|
priceText =
|
||||||
min === max
|
min === max
|
||||||
? `€ ${formatPriceAmount(min)}`
|
? formatPriceAmount(min)
|
||||||
: `€ ${formatPriceAmount(min)} bis € ${formatPriceAmount(max)}`;
|
: `${formatPriceAmount(min)} bis ${formatPriceAmount(max)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -533,24 +517,19 @@ export default class ArticleViewPrice extends PureComponent {
|
|||||||
wide={1}
|
wide={1}
|
||||||
minHeight={SECOND_ROW_MIN_HEIGHT}
|
minHeight={SECOND_ROW_MIN_HEIGHT}
|
||||||
color={BLUE_PANEL}
|
color={BLUE_PANEL}
|
||||||
|
title={
|
||||||
|
<Box component="span" sx={{ fontWeight: 700 }}>
|
||||||
|
€
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
contentAlignItems="flex-start"
|
contentAlignItems="flex-start"
|
||||||
>
|
>
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', height: '100%', width: '100%' }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', height: '100%', width: '100%' }}>
|
||||||
<Typography
|
<Box sx={{ width: '100%', mt: 0.5 }}>
|
||||||
variant="caption"
|
|
||||||
color="text.secondary"
|
|
||||||
sx={{
|
|
||||||
letterSpacing: 0.6,
|
|
||||||
fontWeight: 600,
|
|
||||||
display: 'block',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Preis auf Variantenebene pflegen
|
|
||||||
</Typography>
|
|
||||||
<Box sx={{ my: 0.75 }}>
|
|
||||||
<Typography
|
<Typography
|
||||||
component="div"
|
component="div"
|
||||||
sx={{
|
sx={{
|
||||||
|
width: '100%',
|
||||||
fontSize: '1.5rem',
|
fontSize: '1.5rem',
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
lineHeight: 1.2,
|
lineHeight: 1.2,
|
||||||
@@ -578,6 +557,7 @@ export default class ArticleViewPrice extends PureComponent {
|
|||||||
wide={1}
|
wide={1}
|
||||||
minHeight={SECOND_ROW_MIN_HEIGHT}
|
minHeight={SECOND_ROW_MIN_HEIGHT}
|
||||||
color={BLUE_PANEL}
|
color={BLUE_PANEL}
|
||||||
|
title={'€'}
|
||||||
contentAlignItems="flex-start"
|
contentAlignItems="flex-start"
|
||||||
value={priceValue}
|
value={priceValue}
|
||||||
onSave={this.handleSave}
|
onSave={this.handleSave}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { PureComponent, createRef } from 'react';
|
import { PureComponent, createRef } from 'react';
|
||||||
|
import { keyframes } from '@emotion/react';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import Chip from '@mui/material/Chip';
|
import Chip from '@mui/material/Chip';
|
||||||
import Fab from '@mui/material/Fab';
|
import Fab from '@mui/material/Fab';
|
||||||
@@ -15,6 +16,16 @@ import sseAutomat from '../automats/sseAutomat';
|
|||||||
|
|
||||||
const PANEL_WIDTH = 420;
|
const PANEL_WIDTH = 420;
|
||||||
const PANEL_HEIGHT = 380;
|
const PANEL_HEIGHT = 380;
|
||||||
|
const pulseAnimationA = keyframes`
|
||||||
|
0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); }
|
||||||
|
35% { transform: scale(1.16); box-shadow: 0 0 0 8px rgba(255, 255, 255, 0.55); }
|
||||||
|
100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); }
|
||||||
|
`;
|
||||||
|
const pulseAnimationB = keyframes`
|
||||||
|
0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); }
|
||||||
|
35% { transform: scale(1.15); box-shadow: 0 0 0 8px rgba(255, 255, 255, 0.55); }
|
||||||
|
100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); }
|
||||||
|
`;
|
||||||
|
|
||||||
function formatEventData(data) {
|
function formatEventData(data) {
|
||||||
if (!data) return '';
|
if (!data) return '';
|
||||||
@@ -34,6 +45,7 @@ class SseMonitor extends PureComponent {
|
|||||||
events: sseAutomat.state.events,
|
events: sseAutomat.state.events,
|
||||||
open: false,
|
open: false,
|
||||||
position: null,
|
position: null,
|
||||||
|
eventPulse: 0,
|
||||||
};
|
};
|
||||||
this.panelRef = createRef();
|
this.panelRef = createRef();
|
||||||
this.handleToggle = this.handleToggle.bind(this);
|
this.handleToggle = this.handleToggle.bind(this);
|
||||||
@@ -59,6 +71,14 @@ class SseMonitor extends PureComponent {
|
|||||||
window.removeEventListener('keydown', this.handleKeyDown);
|
window.removeEventListener('keydown', this.handleKeyDown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps, prevState) {
|
||||||
|
const previousEventId = prevState.events.at(-1)?.id;
|
||||||
|
const currentEventId = this.state.events.at(-1)?.id;
|
||||||
|
if (currentEventId != null && currentEventId !== previousEventId) {
|
||||||
|
this.setState((state) => ({ eventPulse: state.eventPulse + 1 }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleKeyDown(event) {
|
handleKeyDown(event) {
|
||||||
if (!event.altKey || !event.shiftKey || event.key?.toLowerCase() !== 's') return;
|
if (!event.altKey || !event.shiftKey || event.key?.toLowerCase() !== 's') return;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@@ -148,30 +168,29 @@ class SseMonitor extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { open, position, status, companyId, events } = this.state;
|
const { open, position, status, companyId, events, eventPulse } = this.state;
|
||||||
const statusColor =
|
const statusColor =
|
||||||
status === 'connected' ? 'success' : status === 'error' ? 'error' : status === 'connecting' ? 'warning' : 'default';
|
status === 'connected' ? 'success' : status === 'error' ? 'error' : status === 'connecting' ? 'warning' : 'default';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!open ? (
|
{!open ? (
|
||||||
<Tooltip title="SSE-Monitor (Alt+Shift+S)" placement="left">
|
<Fab
|
||||||
<Fab
|
size="small"
|
||||||
size="small"
|
color={statusColor}
|
||||||
color="primary"
|
aria-label={`SSE-Monitor umschalten (${status})`}
|
||||||
aria-label="SSE-Monitor umschalten"
|
aria-pressed={open}
|
||||||
aria-pressed={open}
|
onClick={this.handleToggle}
|
||||||
onClick={this.handleToggle}
|
sx={{
|
||||||
sx={{
|
position: 'fixed',
|
||||||
position: 'fixed',
|
left: { xs: 27, sm: 171 },
|
||||||
right: 16,
|
bottom: { xs: 132, sm: 142 },
|
||||||
bottom: 16,
|
zIndex: (theme) => theme.zIndex.tooltip,
|
||||||
zIndex: (theme) => theme.zIndex.tooltip,
|
animation: `${eventPulse % 2 === 0 ? pulseAnimationA : pulseAnimationB} 650ms ease-out`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SensorsIcon fontSize="small" />
|
<SensorsIcon fontSize="small" />
|
||||||
</Fab>
|
</Fab>
|
||||||
</Tooltip>
|
|
||||||
) : (
|
) : (
|
||||||
<Paper
|
<Paper
|
||||||
ref={this.panelRef}
|
ref={this.panelRef}
|
||||||
|
|||||||
Reference in New Issue
Block a user