Skip to content

Commit 3aad394

Browse files
samuelreichertclaude
authored andcommitted
fix(barcode-generator-web): scope property visibility to the selected format
The Advanced Data Matrix Settings group was never hidden, so it showed for Barcode, QR Code and Custom. The reverse leaked too: because the existing conditions enumerated QRCode/CODE128/Custom, selecting Data Matrix still showed bar width, code height, display value, EAN-128, Mod43 and the EAN addon properties. Replace the enumerated format checks with intent-named booleans so adding a format cannot silently reopen these, and gate check() to validate only the sizing properties that are visible. Also report QR size problems on qrSize instead of codeHeight, and validate static GS1 values at design time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 1f91051 commit 3aad394

2 files changed

Lines changed: 292 additions & 38 deletions

File tree

packages/pluggableWidgets/barcode-generator-web/src/BarcodeGenerator.editorConfig.ts

Lines changed: 71 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { hidePropertiesIn, hidePropertyIn, Properties } from "@mendix/pluggable-widgets-tools";
22
import { StructurePreviewProps } from "@mendix/widget-plugin-platform/preview/structure-preview-api";
33
import { BarcodeGeneratorPreviewProps, CodeFormatEnum, CustomCodeFormatEnum } from "../typings/BarcodeGeneratorProps";
4-
import { validateAddonValue, validateBarcodeValue } from "./config/validation";
4+
import { validateAddonValue, validateBarcodeValue, validateGs1DataMatrixValue } from "./config/validation";
55

66
export type Problem = {
77
property?: string; // key of the property, at which the problem exists
@@ -13,7 +13,12 @@ export type Problem = {
1313
};
1414

1515
export function getProperties(values: BarcodeGeneratorPreviewProps, defaultProperties: Properties): Properties {
16-
if (values.codeFormat === "QRCode") {
16+
const isQrCode = values.codeFormat === "QRCode";
17+
const isDataMatrix = values.codeFormat === "DataMatrix";
18+
// Both "Barcode" (CODE128) and "Custom" render as 1D barcodes through JsBarcode
19+
const isBarcode = !isQrCode && !isDataMatrix;
20+
21+
if (isQrCode) {
1722
hidePropertiesIn(defaultProperties, values, ["codeWidth", "codeHeight", "displayValue", "codeMargin"]);
1823
} else {
1924
hidePropertiesIn(defaultProperties, values, [
@@ -26,7 +31,15 @@ export function getProperties(values: BarcodeGeneratorPreviewProps, defaultPrope
2631
]);
2732
}
2833

29-
if (values.codeFormat !== "QRCode" || !values.qrOverlay) {
34+
if (isDataMatrix) {
35+
// Data Matrix is a 2D symbol: bar width/height, the human-readable value and the
36+
// pixel-based 1D margin don't apply — it uses dmMargin (module units) instead
37+
hidePropertiesIn(defaultProperties, values, ["codeWidth", "codeHeight", "displayValue", "codeMargin"]);
38+
} else {
39+
hidePropertiesIn(defaultProperties, values, ["dmGs1Mode", "dmShape", "dmSize", "dmMargin"]);
40+
}
41+
42+
if (!isQrCode || !values.qrOverlay) {
3043
hidePropertiesIn(defaultProperties, values, [
3144
"qrOverlaySrc",
3245
"qrOverlayCenter",
@@ -39,7 +52,8 @@ export function getProperties(values: BarcodeGeneratorPreviewProps, defaultPrope
3952
]);
4053
}
4154

42-
if (values.codeFormat === "QRCode" || (values.codeFormat !== "CODE128" && values.customCodeFormat !== "CODE128")) {
55+
// EAN-128 only applies to CODE128, either as the top-level format or the custom one
56+
if (!isBarcode || (values.codeFormat === "Custom" && values.customCodeFormat !== "CODE128")) {
4357
hidePropertyIn(defaultProperties, values, "enableEan128");
4458
}
4559

@@ -63,29 +77,20 @@ export function getProperties(values: BarcodeGeneratorPreviewProps, defaultPrope
6377
}
6478

6579
// EAN addons are only supported for EAN-13, EAN-8, and UPC
66-
if (
67-
values.codeFormat === "QRCode" ||
68-
values.codeFormat === "CODE128" ||
69-
(values.codeFormat === "Custom" &&
70-
values.customCodeFormat !== "EAN13" &&
71-
values.customCodeFormat !== "EAN8" &&
72-
values.customCodeFormat !== "UPC")
73-
) {
80+
const supportsAddons =
81+
values.codeFormat === "Custom" &&
82+
(values.customCodeFormat === "EAN13" ||
83+
values.customCodeFormat === "EAN8" ||
84+
values.customCodeFormat === "UPC");
85+
if (!supportsAddons) {
7486
hidePropertiesIn(defaultProperties, values, ["addonFormat", "addonValue", "addonSpacing"]);
7587
}
76-
if (
77-
values.codeFormat === "QRCode" ||
78-
values.codeFormat === "CODE128" ||
79-
(values.codeFormat === "Custom" && values.addonFormat !== "EAN5" && values.addonFormat !== "EAN2")
80-
) {
88+
if (!supportsAddons || (values.addonFormat !== "EAN5" && values.addonFormat !== "EAN2")) {
8189
hidePropertiesIn(defaultProperties, values, ["addonValue", "addonSpacing"]);
8290
}
8391

84-
if (
85-
values.codeFormat === "QRCode" ||
86-
values.codeFormat === "CODE128" ||
87-
(values.codeFormat === "Custom" && values.customCodeFormat !== "CODE39")
88-
) {
92+
// Mod43 is a CODE39 check digit
93+
if (!(values.codeFormat === "Custom" && values.customCodeFormat === "CODE39")) {
8994
hidePropertyIn(defaultProperties, values, "enableMod43");
9095
}
9196

@@ -118,30 +123,52 @@ export function getPreview(_: StructurePreviewProps, _isDarkMode: boolean): Stru
118123
export function check(_values: BarcodeGeneratorPreviewProps): Problem[] {
119124
const errors: Problem[] = [];
120125

121-
if (!_values.codeWidth || _values.codeWidth < 1) {
122-
errors.push({
123-
property: `codeWidth`,
124-
severity: "error",
125-
message: `The value of 'Bar width' must be at least 1.`
126-
});
127-
}
126+
// Only validate the sizing properties that are visible for the selected format
127+
if (_values.codeFormat !== "QRCode" && _values.codeFormat !== "DataMatrix") {
128+
if (!_values.codeWidth || _values.codeWidth < 1) {
129+
errors.push({
130+
property: `codeWidth`,
131+
severity: "error",
132+
message: `The value of 'Bar width' must be at least 1.`
133+
});
134+
}
128135

129-
if (!_values.codeHeight || _values.codeHeight < 20) {
130-
errors.push({
131-
property: `codeHeight`,
132-
severity: "error",
133-
message: `The value of 'Code height' must be at least 20.`
134-
});
136+
if (!_values.codeHeight || _values.codeHeight < 20) {
137+
errors.push({
138+
property: `codeHeight`,
139+
severity: "error",
140+
message: `The value of 'Code height' must be at least 20.`
141+
});
142+
}
135143
}
136144

137-
if (!_values.qrSize || _values.qrSize < 50) {
145+
if (_values.codeFormat === "QRCode" && (!_values.qrSize || _values.qrSize < 50)) {
138146
errors.push({
139-
property: `codeHeight`,
147+
property: `qrSize`,
140148
severity: "error",
141149
message: `The value of 'QR size' must be at least 50.`
142150
});
143151
}
144152

153+
if (_values.codeFormat === "DataMatrix") {
154+
if (!_values.dmSize || _values.dmSize < 32) {
155+
errors.push({
156+
property: `dmSize`,
157+
severity: "error",
158+
message: `The value of 'Data Matrix size' must be at least 32.`
159+
});
160+
}
161+
162+
// The Data Matrix spec requires a quiet zone of at least one module on every side
163+
if (!_values.dmMargin || _values.dmMargin < 1) {
164+
errors.push({
165+
property: `dmMargin`,
166+
severity: "warning",
167+
message: `A Data Matrix needs a quiet zone of at least 1 module unit to stay scannable.`
168+
});
169+
}
170+
}
171+
145172
// Design-time validation for static barcode value(s)
146173
const valueProblems = validateCodeValues(_values);
147174
return errors.concat(valueProblems);
@@ -183,7 +210,8 @@ function getFormatHint(format: string): string {
183210
MSI: "MSI: numeric only (max 30 digits)",
184211
pharmacode: "Pharmacode: numeric only (max 7 digits)",
185212
codabar: "Codabar: digits, A-D start/stop, and - $ : / . + (max 20 chars)",
186-
QRCode: "QR Code: any text (max 1200 chars recommended)"
213+
QRCode: "QR Code: any text (max 1200 chars recommended)",
214+
DataMatrix: "Data Matrix: any text; GS1 mode expects Application Identifier syntax, e.g. (01)09501101020917"
187215
};
188216
return hints[format] || "";
189217
}
@@ -214,6 +242,11 @@ function validateCodeValues(values: BarcodeGeneratorPreviewProps): Problem[] {
214242
if (!result.valid) {
215243
const msg = result.message || "Invalid barcode value for selected format.";
216244
problems.push({ property: "codeValue", severity: "error", message: msg });
245+
} else if (format === "DataMatrix" && values.dmGs1Mode) {
246+
const gs1Result = validateGs1DataMatrixValue(val);
247+
if (!gs1Result.valid) {
248+
problems.push({ property: "codeValue", severity: "error", message: gs1Result.message });
249+
}
217250
}
218251
}
219252
}

0 commit comments

Comments
 (0)