u
This commit is contained in:
@@ -32,6 +32,9 @@ import { artikelDetailPath } from '../components/article/articleRoute';
|
||||
import withSearchParams from '../components/article/withSearchParams';
|
||||
import { setLastArticleSku } from '../automats';
|
||||
import { BrandLabel } from '../components/brand';
|
||||
import {
|
||||
BLUE_BG,
|
||||
} from '../colors';
|
||||
|
||||
const resultRowSx = {
|
||||
alignItems: 'center',
|
||||
@@ -276,7 +279,6 @@ class ArtikelSearchPage extends Component {
|
||||
onChange={this.handleInputChange}
|
||||
slotProps={{
|
||||
htmlInput: {
|
||||
spellCheck: false,
|
||||
autoCapitalize: 'off',
|
||||
autoCorrect: 'off',
|
||||
},
|
||||
@@ -373,7 +375,7 @@ class ArtikelSearchPage extends Component {
|
||||
measureElement={
|
||||
<Box
|
||||
sx={{
|
||||
bgcolor: '#dbeafe',
|
||||
bgcolor: BLUE_BG,
|
||||
p: 2,
|
||||
borderRadius: 1,
|
||||
textAlign: 'center',
|
||||
|
||||
@@ -498,7 +498,10 @@ class ArtikelKategorienPage extends PureComponent {
|
||||
}}
|
||||
variant="standard"
|
||||
size="small"
|
||||
slotProps={{ inputLabel: { shrink: true }, input: { spellCheck: false } }}
|
||||
slotProps={{
|
||||
inputLabel: { shrink: true },
|
||||
htmlInput: { spellCheck: false },
|
||||
}}
|
||||
sx={{
|
||||
width: '100%',
|
||||
'& .MuiInput-underline:before, & .MuiInput-underline:after': {
|
||||
|
||||
@@ -21,6 +21,9 @@ import { backendErrorFrom } from '../../utils/backendError';
|
||||
import { notifyError } from '../../utils/notify';
|
||||
import { setLastArticleSku } from '../../automats';
|
||||
import warehouseAutomat from '../../automats/warehouseAutomat';
|
||||
import {
|
||||
GREEN_PANEL,
|
||||
} from '../../colors';
|
||||
|
||||
function draftsFrom(warehouses) {
|
||||
return Object.fromEntries(warehouses.map((row) => [row.id, row.name]));
|
||||
@@ -285,15 +288,9 @@ class ArtikelLagerPage extends PureComponent {
|
||||
return (
|
||||
<>
|
||||
{/* SortableJS ghost / chosen styling */}
|
||||
<style>{`
|
||||
.sortable-ghost { opacity: 0.35 !important; }
|
||||
.sortable-chosen { box-shadow: 0 4px 16px rgba(0,0,0,0.12); }
|
||||
.drag-handle { cursor: grab; touch-action: none; }
|
||||
.drag-handle:active { cursor: grabbing; }
|
||||
`}</style>
|
||||
|
||||
<PanelTileGrid>
|
||||
<PanelTile wide={2} minHeight={280} color="#bbf7d0">
|
||||
<PanelTile wide={2} minHeight={280} color={GREEN_PANEL}>
|
||||
<Stack spacing={2}>
|
||||
{returnTo ? (
|
||||
<Alert
|
||||
|
||||
@@ -19,6 +19,9 @@ import { setLastArticleSku } from '../../automats';
|
||||
import brandAutomat from '../../automats/brandAutomat';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import { BrandThumb, BrandImageSearchDialog } from '../../components/brand';
|
||||
import {
|
||||
PURPLE_PANEL,
|
||||
} from '../../colors';
|
||||
|
||||
function draftsFrom(brands) {
|
||||
return Object.fromEntries(brands.map((b) => [b.id, b.name]));
|
||||
@@ -180,7 +183,7 @@ class ArtikelMarkenPage extends PureComponent {
|
||||
|
||||
return (
|
||||
<PanelTileGrid>
|
||||
<PanelTile wide={2} minHeight={280} color="#ddd6fe">
|
||||
<PanelTile wide={2} minHeight={280} color={PURPLE_PANEL}>
|
||||
<List dense disablePadding>
|
||||
{brands.length === 0 ? (
|
||||
<Typography variant="body2" color="text.secondary" sx={{ py: 1 }}>
|
||||
|
||||
@@ -24,6 +24,15 @@ import { notifyError } from '../../utils/notify';
|
||||
import { setLastArticleSku } from '../../automats';
|
||||
import attributeAutomat, { selectAttributes } from '../../automats/attributeAutomat';
|
||||
import propertyAutomat, { selectProperties } from '../../automats/propertyAutomat';
|
||||
import {
|
||||
BLUE_PANEL,
|
||||
ORANGE_PANEL,
|
||||
PURPLE_PANEL,
|
||||
SELECT_BG,
|
||||
SELECT_BG_HOVER,
|
||||
SELECT_BORDER,
|
||||
TINT_SUBTLE,
|
||||
} from '../../colors';
|
||||
|
||||
function draftsFrom(items, key = 'name') {
|
||||
return Object.fromEntries((items || []).map((row) => [row.id, row[key]]));
|
||||
@@ -609,16 +618,10 @@ class ArtikelMerkmalePage extends PureComponent {
|
||||
return (
|
||||
<>
|
||||
{/* SortableJS ghost / chosen styling from /artikel/lager */}
|
||||
<style>{`
|
||||
.sortable-ghost { opacity: 0.35 !important; }
|
||||
.sortable-chosen { box-shadow: 0 4px 16px rgba(0,0,0,0.12); }
|
||||
.drag-handle { cursor: grab; touch-action: none; }
|
||||
.drag-handle:active { cursor: grabbing; }
|
||||
`}</style>
|
||||
|
||||
<PanelTileGrid>
|
||||
{/* Tile 1: Attribute (Auswahllisten) */}
|
||||
<PanelTile wide={2} minHeight={280} color="#bfdbfe">
|
||||
<PanelTile wide={2} minHeight={280} color={BLUE_PANEL}>
|
||||
<Stack spacing={2}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<StyleIcon sx={{ color: 'text.secondary', fontSize: 20 }} />
|
||||
@@ -642,11 +645,11 @@ class ArtikelMerkmalePage extends PureComponent {
|
||||
borderRadius: 1.5,
|
||||
alignItems: 'center',
|
||||
cursor: 'pointer',
|
||||
bgcolor: isSelected ? 'rgba(59, 130, 246, 0.12)' : 'transparent',
|
||||
border: isSelected ? '1px solid rgba(59, 130, 246, 0.3)' : '1px solid transparent',
|
||||
bgcolor: isSelected ? SELECT_BG : 'transparent',
|
||||
border: isSelected ? `1px solid ${SELECT_BORDER}` : '1px solid transparent',
|
||||
transition: 'all 0.15s ease',
|
||||
'&:hover': {
|
||||
bgcolor: isSelected ? 'rgba(59, 130, 246, 0.16)' : 'rgba(0, 0, 0, 0.04)',
|
||||
bgcolor: isSelected ? SELECT_BG_HOVER : TINT_SUBTLE,
|
||||
},
|
||||
}}
|
||||
data-id={a.id}
|
||||
@@ -764,7 +767,7 @@ class ArtikelMerkmalePage extends PureComponent {
|
||||
</PanelTile>
|
||||
|
||||
{/* Tile 2: Werte für das gewählte Attribut */}
|
||||
<PanelTile wide={2} minHeight={280} color="#ddd6fe">
|
||||
<PanelTile wide={2} minHeight={280} color={PURPLE_PANEL}>
|
||||
<Stack spacing={2}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<LabelImportantIcon sx={{ color: 'text.secondary', fontSize: 20 }} />
|
||||
@@ -867,7 +870,7 @@ class ArtikelMerkmalePage extends PureComponent {
|
||||
</PanelTile>
|
||||
|
||||
{/* Tile 3: Merkmale (Freitext) */}
|
||||
<PanelTile wide={2} minHeight={280} color="#fed7aa">
|
||||
<PanelTile wide={2} minHeight={280} color={ORANGE_PANEL}>
|
||||
<Stack spacing={2}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<TuneIcon sx={{ color: 'text.secondary', fontSize: 20 }} />
|
||||
|
||||
@@ -25,6 +25,10 @@ import { notifyError } from '../../utils/notify';
|
||||
import { setLastArticleSku } from '../../automats';
|
||||
import { labeltemplate } from '../../api';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import {
|
||||
BLUE_BG,
|
||||
SURFACE_BASE,
|
||||
} from '../../colors';
|
||||
|
||||
const CanvasEditor = lazy(async () => {
|
||||
await import('react-canvas-label-editor/style.css');
|
||||
@@ -465,7 +469,7 @@ class ArtikelVorlagenPage extends PureComponent {
|
||||
return (
|
||||
<>
|
||||
<PanelTileGrid>
|
||||
<PanelTile wide={3} color="#dbeafe">
|
||||
<PanelTile wide={3} color={BLUE_BG}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', mb: 2 }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
@@ -517,7 +521,7 @@ class ArtikelVorlagenPage extends PureComponent {
|
||||
onClick={() => this.handleOpenEdit(tmpl)}
|
||||
sx={{
|
||||
height: 100,
|
||||
bgcolor: '#f8f8f8',
|
||||
bgcolor: SURFACE_BASE,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
|
||||
@@ -8,6 +8,9 @@ import { PanelTile } from 'dashgui/panels';
|
||||
import { AutomatGrid } from 'react-virtual-aggridautomat';
|
||||
import { articleHistoryGridAutomat } from '../../automats';
|
||||
import { router } from '../../appRouter';
|
||||
import {
|
||||
LINK,
|
||||
} from '../../colors';
|
||||
|
||||
const COLUMN_DEFS = [
|
||||
{
|
||||
@@ -43,7 +46,7 @@ const COLUMN_DEFS = [
|
||||
e.preventDefault();
|
||||
void router.navigate(`/artikel/${encodeURIComponent(p.value)}`);
|
||||
}}
|
||||
style={{ color: '#2563eb', fontWeight: 600, textDecoration: 'none' }}
|
||||
style={{ color: LINK, fontWeight: 600, textDecoration: 'none' }}
|
||||
>
|
||||
{p.value}
|
||||
</a>
|
||||
|
||||
@@ -8,6 +8,9 @@ import customergroupAutomat from '../automats/customergroupAutomat';
|
||||
import { router } from '../appRouter';
|
||||
import { backendErrorFrom } from '../utils/backendError';
|
||||
import { notifyError } from '../utils/notify';
|
||||
import {
|
||||
BLUE_PANEL,
|
||||
} from '../colors';
|
||||
|
||||
function sortEntities(entities) {
|
||||
return [...entities].sort((a, b) => {
|
||||
@@ -142,7 +145,7 @@ class KundeListePage extends PureComponent {
|
||||
onDelete={this.handleDelete}
|
||||
deleteDisabled={busyId != null}
|
||||
emptyMessage="Noch keine Kunden."
|
||||
color="#bfdbfe"
|
||||
color={BLUE_PANEL}
|
||||
getEditLabel={(row) => `„${label(row)}“ bearbeiten`}
|
||||
getDeleteLabel={(row) => `„${label(row)}“ löschen`}
|
||||
/>
|
||||
|
||||
@@ -18,6 +18,11 @@ import { requireArray, requireDefined, requireObject } from '../../utils/apiShap
|
||||
import { backendErrorFrom } from '../../utils/backendError';
|
||||
import { notifyError } from '../../utils/notify';
|
||||
import withEntityRoute from '../../components/kunde/withEntityRoute';
|
||||
import {
|
||||
BLUE_PANEL,
|
||||
GREEN_PANEL,
|
||||
YELLOW_PANEL,
|
||||
} from '../../colors';
|
||||
|
||||
const ADDRESS_FIELDS = [
|
||||
'addressType',
|
||||
@@ -551,7 +556,7 @@ class KundeEditPage extends PureComponent {
|
||||
|
||||
return (
|
||||
<PanelTileGrid>
|
||||
<PanelTile wide={2} minHeight={200} color="#bfdbfe" title="Stammdaten">
|
||||
<PanelTile wide={2} minHeight={200} color={BLUE_PANEL} title="Stammdaten">
|
||||
<Stack spacing={2}>
|
||||
{groupName != null ? (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
@@ -586,7 +591,7 @@ class KundeEditPage extends PureComponent {
|
||||
</Stack>
|
||||
</PanelTile>
|
||||
|
||||
<PanelTile wide={3} minHeight={240} color="#bbf7d0" title="Adressen">
|
||||
<PanelTile wide={3} minHeight={240} color={GREEN_PANEL} title="Adressen">
|
||||
<Stack spacing={2}>
|
||||
{addresses.length === 0 ? (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
@@ -656,7 +661,7 @@ class KundeEditPage extends PureComponent {
|
||||
</Stack>
|
||||
</PanelTile>
|
||||
|
||||
<PanelTile wide={3} minHeight={200} color="#fde68a" title="Kontakte">
|
||||
<PanelTile wide={3} minHeight={200} color={YELLOW_PANEL} title="Kontakte">
|
||||
<Stack spacing={2}>
|
||||
{contacts.length === 0 ? (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
|
||||
@@ -20,6 +20,9 @@ import customergroupAutomat from '../../automats/customergroupAutomat';
|
||||
import { requireArray, requireDefined, requireObject } from '../../utils/apiShape';
|
||||
import { backendErrorFrom } from '../../utils/backendError';
|
||||
import { notifyError } from '../../utils/notify';
|
||||
import {
|
||||
PURPLE_BG,
|
||||
} from '../../colors';
|
||||
|
||||
function sortGroups(groups) {
|
||||
return [...groups].sort((a, b) => {
|
||||
@@ -231,7 +234,7 @@ class KundeGruppenPage extends PureComponent {
|
||||
|
||||
return (
|
||||
<PanelTileGrid>
|
||||
<PanelTile wide={2} minHeight={280} color="#e9d5ff">
|
||||
<PanelTile wide={2} minHeight={280} color={PURPLE_BG}>
|
||||
<Stack spacing={2}>
|
||||
<List dense disablePadding>
|
||||
{groups.length === 0 ? (
|
||||
|
||||
@@ -14,6 +14,9 @@ import customergroupAutomat from '../../automats/customergroupAutomat';
|
||||
import { router } from '../../appRouter';
|
||||
import { requireDefined, requireObject } from '../../utils/apiShape';
|
||||
import { notifyError } from '../../utils/notify';
|
||||
import {
|
||||
BLUE_PANEL,
|
||||
} from '../../colors';
|
||||
|
||||
class KundeNeuPage extends PureComponent {
|
||||
constructor(props) {
|
||||
@@ -95,7 +98,7 @@ class KundeNeuPage extends PureComponent {
|
||||
|
||||
return (
|
||||
<PanelTileGrid>
|
||||
<PanelTile wide={2} minHeight={220} color="#bfdbfe" title="Neuer Kunde">
|
||||
<PanelTile wide={2} minHeight={220} color={BLUE_PANEL} title="Neuer Kunde">
|
||||
<Stack spacing={2}>
|
||||
<TextField
|
||||
size="small"
|
||||
@@ -103,7 +106,7 @@ class KundeNeuPage extends PureComponent {
|
||||
value={number}
|
||||
disabled
|
||||
slotProps={{
|
||||
htmlInput: { spellCheck: false, autoComplete: 'off' },
|
||||
htmlInput: { autoComplete: 'off' },
|
||||
}}
|
||||
/>
|
||||
<Select
|
||||
@@ -112,9 +115,8 @@ class KundeNeuPage extends PureComponent {
|
||||
disabled={saving}
|
||||
onChange={this.handleGroupChange}
|
||||
displayEmpty
|
||||
inputProps={{
|
||||
spellCheck: false,
|
||||
autoComplete: 'off',
|
||||
slotProps={{
|
||||
htmlInput: { autoComplete: 'off' },
|
||||
}}
|
||||
>
|
||||
{groups.map((row) => (
|
||||
|
||||
@@ -21,6 +21,9 @@ import { notifyError } from '../../utils/notify';
|
||||
import { setLastDeliveryPath } from '../../automats';
|
||||
import supplierAutomat from '../../automats/supplierAutomat';
|
||||
import { deliveryDraftAutomat } from '../../automats/deliveryEditorAutomat';
|
||||
import {
|
||||
GREEN_PANEL,
|
||||
} from '../../colors';
|
||||
|
||||
|
||||
function sortSuppliers(suppliers) {
|
||||
@@ -224,7 +227,7 @@ class LieferungLieferantenPage extends PureComponent {
|
||||
|
||||
return (
|
||||
<PanelTileGrid>
|
||||
<PanelTile wide={2} minHeight={280} color="#bbf7d0">
|
||||
<PanelTile wide={2} minHeight={280} color={GREEN_PANEL}>
|
||||
<Stack spacing={2}>
|
||||
{returnTo ? (
|
||||
<Alert
|
||||
|
||||
@@ -50,6 +50,11 @@ import { getDeliveryEditorAutomat } from '../../automats/deliveryEditorAutomat';
|
||||
import { setLastDeliveryPath, userSettingsAutomat, setViewerPosition } from '../../automats';
|
||||
|
||||
import { fetchDeliveryLedgerSummary } from '../../utils/deliveryLedger';
|
||||
import {
|
||||
SURFACE_BASE,
|
||||
SURFACE_RAISED,
|
||||
YELLOW_BG,
|
||||
} from '../../colors';
|
||||
|
||||
class LieferungNeuPage extends PureComponent {
|
||||
constructor(props) {
|
||||
@@ -1266,7 +1271,7 @@ class LieferungNeuPage extends PureComponent {
|
||||
/>
|
||||
{this.state.viewerPosition === 'top' && this.renderViewerPanels(4)}
|
||||
{this.state.unmatchedSupplierName && (
|
||||
<PanelTile wide={4} color="#fef3c7" sx={{ gridColumn: { xs: '1 / -1', sm: '1 / -1', md: 'span 4' } }}>
|
||||
<PanelTile wide={4} color={YELLOW_BG} sx={{ gridColumn: { xs: '1 / -1', sm: '1 / -1', md: 'span 4' } }}>
|
||||
<Alert
|
||||
severity="warning"
|
||||
action={
|
||||
@@ -1316,7 +1321,7 @@ class LieferungNeuPage extends PureComponent {
|
||||
{this.state.viewerPosition === 'below' && this.renderViewerPanels(4)}
|
||||
{this.props.docId != null && this.renderLedgerPanel()}
|
||||
{notes && notes.length > 0 && (
|
||||
<PanelTile wide={4} color="#fffbeb" sx={{ gridColumn: { xs: '1 / -1', sm: '1 / -1', md: 'span 4' } }}>
|
||||
<PanelTile wide={4} color={YELLOW_BG} sx={{ gridColumn: { xs: '1 / -1', sm: '1 / -1', md: 'span 4' } }}>
|
||||
<Typography variant="subtitle2" fontWeight={700} color="warning.dark" sx={{ mb: 1.5 }}>
|
||||
Hinweise zur PDF-Analyse ({notes.length})
|
||||
</Typography>
|
||||
@@ -1401,7 +1406,7 @@ class LieferungNeuPage extends PureComponent {
|
||||
<PanelTile
|
||||
wide={4}
|
||||
title="Lagerstatus (Ledger)"
|
||||
color="#f8fafc"
|
||||
color={SURFACE_BASE}
|
||||
sx={{
|
||||
gridColumn: { xs: '1 / -1', sm: '1 / -1', md: 'span 4' },
|
||||
border: '1px solid',
|
||||
@@ -1519,7 +1524,7 @@ class LieferungNeuPage extends PureComponent {
|
||||
</Typography>
|
||||
<TableContainer component={Paper} variant="outlined">
|
||||
<Table size="small">
|
||||
<TableHead sx={{ bgcolor: '#f1f5f9' }}>
|
||||
<TableHead sx={{ bgcolor: SURFACE_RAISED }}>
|
||||
<TableRow>
|
||||
<TableCell sx={{ fontWeight: 600, py: 0.5 }}>Zeitpunkt</TableCell>
|
||||
<TableCell sx={{ fontWeight: 600, py: 0.5 }}>Typ</TableCell>
|
||||
|
||||
Reference in New Issue
Block a user