Skip to content

Commit 1de17a7

Browse files
authored
[WTF-2132] Generate types for actions with action variables (#115)
## Checklist - Contains unit tests ✅ - Contains breaking changes ❌ - Compatible with: MX 7️⃣, 8️⃣, 9️⃣ - Did you update version and changelog? ✅ ❌ - PR title properly formatted (`[XX-000]: description`)? ✅ ## This PR contains - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Other (describe) ## What is the purpose of this PR? With Mendix 10.21 it will be possible to pass primitive values to actions. This PR makes sure typing are generated accordingly Bonus fix included needed for ci is the updating of the deprecated action/cache dependency (see actions/cache#1510) _..._ ## Relevant changes Type genration will now consider `ActionVariables` in the XML to generate the typings for action properties. ## What should be covered while testing? _..._
2 parents 49eec82 + 69a7843 commit 1de17a7

File tree

9 files changed

+180
-13
lines changed

9 files changed

+180
-13
lines changed

packages/pluggable-widgets-tools/CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- We added support for action variables, introduced in Mendix 10.21.
12+
13+
### Changed
14+
15+
- We updated the Mendix package to 10.21.64362.
16+
917
## [10.18.2] - 2025-03-21
1018

1119
### Fixed

packages/pluggable-widgets-tools/package-lock.json

+9-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/pluggable-widgets-tools/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@mendix/pluggable-widgets-tools",
3-
"version": "10.18.2",
3+
"version": "10.21.0",
44
"description": "Mendix Pluggable Widgets Tools",
55
"engines": {
66
"node": ">=20"
@@ -81,7 +81,7 @@
8181
"jest-junit": "^13.0.0",
8282
"jest-react-hooks-shallow": "^1.5.1",
8383
"make-dir": "^3.1.0",
84-
"mendix": "^10.18.54340",
84+
"mendix": "^10.21.64362",
8585
"metro-react-native-babel-preset": "^0.74.1",
8686
"mime": "^3.0.0",
8787
"node-fetch": "^2.6.1",

packages/pluggable-widgets-tools/src/typings-generator/WidgetXml.ts

+12
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export interface Property {
6161
properties?: Properties[];
6262
enumerationValues?: Enumeration[];
6363
selectionTypes?: SelectionTypes[];
64+
actionVariables?: ActionVariableTypes[];
6465
}
6566

6667
export interface AttributeType {
@@ -123,3 +124,14 @@ export interface SelectionType {
123124
name: string;
124125
};
125126
}
127+
128+
export interface ActionVariableTypes {
129+
actionVariable: ActionVariableType[];
130+
}
131+
132+
export interface ActionVariableType {
133+
$: {
134+
key: string;
135+
type: string;
136+
};
137+
}

packages/pluggable-widgets-tools/src/typings-generator/__tests__/index.spec.ts

+12
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ import { attributeMetaDataNativeInput, attributeMetaDataWebInput } from "./input
4343
import { attributeMetaDataNativeOutput, attributeMetaDataWebOutput } from "./outputs/metadata-attribute";
4444
import { associationMetaDataNativeInput, associationMetaDataWebInput } from "./inputs/metadata-association";
4545
import { associationMetaDataNativeOutput, associationMetaDataWebOutput } from "./outputs/metadata-association";
46+
import {listActionWithVariablesInput, listActionWithVariablesInputNative} from "./inputs/list-action-with-variables";
47+
import {listActionWithVariablesOutput, listActionWithVariablesOutputNative} from "./outputs/list-action-with-variables";
4648

4749
describe("Generating tests", () => {
4850
it("Generates a parsed typing from XML for native", () => {
@@ -75,6 +77,16 @@ describe("Generating tests", () => {
7577
expect(newContent).toBe(listActionWebOutput);
7678
});
7779

80+
it("Generates a parsed typing from XML for native using list of actions with variables", () => {
81+
const newContent = generateNativeTypesFor(listActionWithVariablesInputNative);
82+
expect(newContent).toBe(listActionWithVariablesOutputNative);
83+
});
84+
85+
it("Generates a parsed typing from XML for web using list of actions with variables", () => {
86+
const newContent = generateFullTypesFor(listActionWithVariablesInput);
87+
expect(newContent).toBe(listActionWithVariablesOutput);
88+
});
89+
7890
it("Generates a parsed typing from XML for native using list of images", () => {
7991
const newContent = generateNativeTypesFor(listImageInputNative);
8092
expect(newContent).toBe(listImageNativeOutput);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
export const listActionWithVariablesInput = `<?xml version="1.0" encoding="utf-8"?>
2+
<widget id="mendix.mywidget.MyWidget" needsEntityContext="true" offlineCapable="true" pluginWidget="true"
3+
xmlns="http://www.mendix.com/widget/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../xsd/widget.xsd">
5+
<properties>
6+
<propertyGroup caption="Events">
7+
<property key="actions" type="object" isList="true">
8+
<caption>Actions</caption>
9+
<description />
10+
<properties>
11+
<propertyGroup caption="Action">
12+
<property key="description" type="attribute">
13+
<caption>Action</caption>
14+
<description />
15+
<attributeTypes>
16+
<attributeType name="String"/>
17+
</attributeTypes>
18+
</property>
19+
<property key="action" type="action">
20+
<caption>Action</caption>
21+
<description />
22+
<actionVariables>
23+
<actionVariable key="boolean_v" type="Boolean" caption="Boolean" />
24+
<actionVariable key="integer_v" type="Integer" caption="Integer" />
25+
<actionVariable key="datetime_v" type="DateTime" caption="DateTime" />
26+
<actionVariable key="string_v" type="String" caption="String" />
27+
<actionVariable key="decimal_v" type="Decimal" caption="Decimal" />
28+
</actionVariables>
29+
</property>
30+
</propertyGroup>
31+
</properties>
32+
</property>
33+
</propertyGroup>
34+
<propertyGroup caption="System Properties">
35+
<systemProperty key="Label"></systemProperty>
36+
<systemProperty key="TabIndex"></systemProperty>
37+
</propertyGroup>
38+
</properties>
39+
</widget>`;
40+
41+
export const listActionWithVariablesInputNative = `<?xml version="1.0" encoding="utf-8"?>
42+
<widget id="mendix.mywidget.MyWidget" needsEntityContext="true" offlineCapable="true" pluginWidget="true" supportedPlatform="Native"
43+
xmlns="http://www.mendix.com/widget/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
44+
xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../xsd/widget.xsd">
45+
<properties>
46+
<propertyGroup caption="Events">
47+
<property key="actions" type="object" isList="true">
48+
<caption>Actions</caption>
49+
<description />
50+
<properties>
51+
<propertyGroup caption="Action">
52+
<property key="description" type="attribute">
53+
<caption>Action</caption>
54+
<description />
55+
<attributeTypes>
56+
<attributeType name="String"/>
57+
</attributeTypes>
58+
</property>
59+
<property key="action" type="action">
60+
<caption>Action</caption>
61+
<description />
62+
<actionVariables>
63+
<actionVariable key="boolean_v" type="Boolean" caption="Boolean" />
64+
<actionVariable key="integer_v" type="Integer" caption="Integer" />
65+
<actionVariable key="datetime_v" type="DateTime" caption="DateTime" />
66+
<actionVariable key="string_v" type="String" caption="String" />
67+
<actionVariable key="decimal_v" type="Decimal" caption="Decimal" />
68+
</actionVariables>
69+
</property>
70+
</propertyGroup>
71+
</properties>
72+
</property>
73+
</propertyGroup>
74+
<propertyGroup caption="System Properties">
75+
<systemProperty key="Label"></systemProperty>
76+
<systemProperty key="TabIndex"></systemProperty>
77+
</propertyGroup>
78+
</properties>
79+
</widget>`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
export const listActionWithVariablesOutput = `/**
2+
* This file was generated from MyWidget.xml
3+
* WARNING: All changes made to this file will be overwritten
4+
* @author Mendix Widgets Framework Team
5+
*/
6+
import { ActionValue, EditableValue, Option } from "mendix";
7+
import { Big } from "big.js";
8+
9+
export interface ActionsType {
10+
description: EditableValue<string>;
11+
action?: ActionValue<{ boolean_v: Option<boolean>; integer_v: Option<Big>; datetime_v: Option<Date>; string_v: Option<string>; decimal_v: Option<Big> }>;
12+
}
13+
14+
export interface ActionsPreviewType {
15+
description: string;
16+
action: {} | null;
17+
}
18+
19+
export interface MyWidgetContainerProps {
20+
name: string;
21+
tabIndex?: number;
22+
id: string;
23+
actions: ActionsType[];
24+
}
25+
26+
export interface MyWidgetPreviewProps {
27+
readOnly: boolean;
28+
renderMode: "design" | "xray" | "structure";
29+
translate: (text: string) => string;
30+
actions: ActionsPreviewType[];
31+
}
32+
`;
33+
export const listActionWithVariablesOutputNative = `export interface ActionsType {
34+
description: EditableValue<string>;
35+
action?: ActionValue<{ boolean_v: Option<boolean>; integer_v: Option<Big>; datetime_v: Option<Date>; string_v: Option<string>; decimal_v: Option<Big> }>;
36+
}
37+
38+
export interface MyWidgetProps<Style> {
39+
name: string;
40+
style: Style[];
41+
actions: ActionsType[];
42+
}`;

packages/pluggable-widgets-tools/src/typings-generator/generate.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const mxExports = [
1414
"ListValue",
1515
"NativeIcon",
1616
"NativeImage",
17+
"Option",
1718
"ListActionValue",
1819
"ListAttributeValue",
1920
"ListAttributeListValue",

packages/pluggable-widgets-tools/src/typings-generator/generateClientTypes.ts

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Property, ReturnType, SystemProperty } from "./WidgetXml";
1+
import { ActionVariableTypes, Property, ReturnType, SystemProperty } from "./WidgetXml";
22
import { capitalizeFirstLetter, commasAnd, extractProperties } from "./helpers";
33

44
export function generateClientTypes(
@@ -100,6 +100,14 @@ export function hasOptionalDataSource(prop: Property, resolveProp: (key: string)
100100
return prop.$.dataSource && resolveProp(prop.$.dataSource)?.$.required === "false";
101101
}
102102

103+
function toActionVariablesOutputType(actionVariables?: ActionVariableTypes[]) {
104+
const types = actionVariables?.flatMap(av => av.actionVariable)
105+
.map(avt => `${avt.$.key}: ${toOption(toAttributeClientType(avt.$.type))}`)
106+
.join("; ");
107+
108+
return types ? `<{ ${types} }>` : "";
109+
}
110+
103111
function toClientPropType(
104112
prop: Property,
105113
isNative: boolean,
@@ -112,7 +120,8 @@ function toClientPropType(
112120
case "string":
113121
return "string";
114122
case "action":
115-
return prop.$.dataSource ? "ListActionValue" : "ActionValue";
123+
const variableTypes = toActionVariablesOutputType(prop.actionVariables);
124+
return (prop.$.dataSource ? "ListActionValue" : "ActionValue") + variableTypes;
116125
case "textTemplate":
117126
return prop.$.dataSource ? "ListExpressionValue<string>" : "DynamicValue<string>";
118127
case "integer":
@@ -328,6 +337,10 @@ function toSelectionClientType(xmlType: string) {
328337
}
329338
}
330339

340+
function toOption(type: string) {
341+
return `Option<${type}>`;
342+
}
343+
331344
export function toUniqueUnionType(types: string[]) {
332345
return types.length ? Array.from(new Set(types)).join(" | ") : "any";
333346
}

0 commit comments

Comments
 (0)