Skip to content

Commit 949a4ee

Browse files
committed
Merge branch 'development' into pr/10786
2 parents 087ec60 + 6034bad commit 949a4ee

313 files changed

Lines changed: 5493 additions & 1802 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

assets/scss/_styles_project.scss

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,28 @@ img {
464464
}
465465
}
466466

467+
/* Olu - Position the mobile close button and remove extra top spacing so content aligns */
468+
#td-sidebar-menu > .d-flex.d-md-none {
469+
position: absolute;
470+
top: 0.5rem;
471+
right: 0.5rem;
472+
z-index: 1060;
473+
}
474+
475+
#td-sidebar-menu {
476+
padding-top: 0;
477+
}
478+
479+
#td-sidebar-menu .td-sidebar__search {
480+
margin-top: 0; /* ensure search sits at top level */
481+
padding-top: 0;
482+
}
483+
484+
#td-sidebar-menu nav.td-sidebar-nav {
485+
margin-top: 0;
486+
padding-top: 0.25rem;
487+
}
488+
467489
// Responsive tables
468490
//
469491
// Generate series of `.table-responsive-*` classes for configuring the screen
@@ -607,4 +629,54 @@ img.ToC-icon{
607629
&:hover {
608630
background-color: $gray-light;
609631
};
632+
}
633+
634+
// Olu - Mobile sidebar open/close behaviour (apply to small and medium screens)
635+
@include media-breakpoint-down(md) {
636+
body.td-sidebar-open {
637+
overflow: hidden;
638+
}
639+
640+
.td-sidebar {
641+
display: block !important;
642+
position: fixed;
643+
top: 0;
644+
left: 0;
645+
height: 100vh;
646+
width: 80%;
647+
max-width: 340px;
648+
z-index: 1055;
649+
background-color: $td-sidebar-bg-color;
650+
transform: translateX(-100%);
651+
transition: transform .25s ease-in-out;
652+
box-shadow: 0 0 0.5rem rgba(0,0,0,0.2);
653+
}
654+
655+
body.td-sidebar-open .td-sidebar {
656+
transform: translateX(0);
657+
}
658+
659+
.td-sidebar-overlay {
660+
display: none;
661+
position: fixed;
662+
inset: 0;
663+
z-index: 1050;
664+
background: rgba(0,0,0,0.45);
665+
}
666+
667+
body.td-sidebar-open .td-sidebar-overlay {
668+
display: block;
669+
}
670+
671+
/* adjustment for the close button in the sidebar */
672+
#td-mobile-sidebar-close {
673+
font-size: 1.1rem;
674+
}
675+
676+
// Ensure the scrolling container inside the off-canvas sidebar fills more of the viewport
677+
.td-sidebar__inner {
678+
height: calc(100vh - 1.5rem) !important;
679+
overflow-y: auto;
680+
padding-top: 1.25rem;
681+
}
610682
}

branch-cleanup-timestamp.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Last scan for stale merged branches: 2026-02-01 23:29:13 CET (UTC+01:00)
1+
Last scan for stale merged branches: 2026-03-01 23:28:32 CET (UTC+01:00)

config/_default/hugo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ replacements = "github.com/FortAwesome/Font-Awesome -> ., github.com/twbs/bootst
8484

8585
# Olu - Minification configuration
8686
[minify]
87-
minifyOutput = true
87+
minifyOutput = false
8888

8989
# Everything below this are Site Params
9090
# ======================================

content/en/docs/academy/_index.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
title: "Mendix Academy"
3+
url: /academy/
4+
description: "Provides information about the Mendix Academy."
5+
weight: 39
6+
---
7+
8+
## Introduction
9+
10+
The Mendix Academy offers a series of learning paths that align with your goals, skill level, role, and time commitment.
11+
12+
## Mendix Academy Home
13+
14+
The Mendix Academy **Home** page displays the following:
15+
16+
* A series of courses recommended for you, based on your current certification.
17+
* The next certification that you should aim to complete, based on your current certification.
18+
* A recommended blog article, along with the link to access the Mendix blog.
19+
* An article dedicated to the latest Studio Pro release, along with a link to access all release videos.
20+
21+
## Learning Paths
22+
23+
The **Explore** page of the **Learning Paths** section lists all available learning paths, grouped by skill level. Each learning path card includes the following details:
24+
25+
* The option to save the learning path
26+
* A star rating based on user reviews
27+
* The number of modules which make up the learning path
28+
* The number of hours necessary to complete the learning path
29+
* The completion percentage
30+
31+
Clicking a card opens the learning path.
32+
33+
The **Saved** page of the **Learning Paths** section displays all learning paths you have saved.
34+
35+
## Certifications
36+
37+
The **Program** page of the **Certifications** section lists the elements that make up the Mendix Developer Certification Program.
38+
Based on your current certification level, a certification is recommended to you.
39+
Click **View Details** on any certification to open its full details.
40+
41+
The **Exam Registrations** page of the **Certifications** section displays a list of your upcoming exams.
42+
Refer to the following pages for details on Mendix Academy exams:
43+
44+
* [Purchasing Mendix Exam Seats](/academy/purchasing-exams/)
45+
* [Managing Exam Seats](/academy/purchasing-exams/manage-exam-seats/)
46+
* [Managing Exam Admins](/academy/purchasing-exams/manage-exam-admins/)
47+

content/en/docs/community-tools/mendix-exams/_index.md renamed to content/en/docs/academy/mendix-exams/_index.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
---
2-
title: "Purchase Mendix Exam Seats"
2+
title: "Purchasing Mendix Exam Seats"
33
linktitle: "Mendix Exam Seats"
4-
url: /community-tools/purchasing-exams/
4+
url: /academy/purchasing-exams/
55
weight: 60
66
description: "Describes how to make a bulk order for exam seats and introduces the documents in this category."
77
no_list: false
88
description_list: true
9+
aliases:
10+
- /community-tools/purchasing-exams/
911
---
1012

1113
## Introduction

content/en/docs/community-tools/mendix-exams/manage-exam-admins.md renamed to content/en/docs/academy/mendix-exams/manage-exam-admins.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
---
22
title: "Managing Exam Admins"
3-
url: /community-tools/purchasing-exams/manage-exam-admins/
3+
url: /academy/purchasing-exams/manage-exam-admins/
44
weight: 20
55
description: "Describes how to manage exam admins in an organization."
6+
aliases:
7+
- /community-tools/purchasing-exams/manage-exam-admins/
68
---
79

810
## Introduction

content/en/docs/community-tools/mendix-exams/manage-exam-seats.md renamed to content/en/docs/academy/mendix-exams/manage-exam-seats.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
---
22
title: "Managing Exam Seats"
3-
url: /community-tools/purchasing-exams/manage-exam-seats/
3+
url: /academy/purchasing-exams/manage-exam-seats/
44
weight: 10
55
description: "Describes how an exam admin in an organization can manage exam seats."
6+
aliases:
7+
- /community-tools/purchasing-exams/manage-exam-seats/
68
---
79

810
## Introduction

content/en/docs/apidocs-mxsdk/apidocs/deployment/build-api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ URL: https://deploy.mendix.com/api/1/apps/<AppId>/packages
281281

282282
##### Payload
283283

284-
The payload depends on whether the app is held in a [Git repository or an SVN repository](/refguide/version-control-faq/#which-team-server).
284+
The payload depends on whether the app is held in a [Git repository or an SVN repository](/refguide/version-control/#which-team-server).
285285

286286
An object with the following key-value pairs:
287287

content/en/docs/apidocs-mxsdk/apidocs/studio-pro-10/pluggable-widgets/pluggable-widgets-client-apis/_index.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,149 @@ There is a way to use more the convenient `displayValue` and `setTextValue` whi
163163

164164
The optional field `universe` is used to indicate the set of all possible values that can be passed to a `setValue` if a set is limited. Currently, `universe` is provided only when the edited value is of the Boolean or enumeration [types](/refguide/attributes/#type).
165165

166+
#### Formatter Details {#formatter-details}
167+
168+
The `formatter` field on `EditableValue` is defined as follows:
169+
170+
```ts
171+
type ParseResult<T> = { valid: true; value: T } | { valid: false };
172+
173+
interface SimpleFormatter<T> {
174+
format(value: T | undefined): string;
175+
parse(value: string): ParseResult<T>;
176+
}
177+
```
178+
179+
##### Built-in Formatter Types {#built-in-formatter-types}
180+
181+
The Mendix platform provides two typed, configurable built-in formatters that extend `SimpleFormatter<T>`: `NumberFormatter` and `DateTimeFormatter`. The actual type of `EditableValue.formatter` is `ValueFormatter<T>` — a union that covers both built-in and plain formatters:
182+
183+
```ts
184+
type ValueFormatter<T> =
185+
| (TypedFormatter<T> & (NumberFormatter | DateTimeFormatter))
186+
| (SimpleFormatter<T> & { readonly type?: never });
187+
```
188+
189+
Use the `type` property as a type guard to narrow to a specific built-in formatter before accessing its extra API:
190+
191+
```ts
192+
if (myAttribute.formatter.type === "datetime") {
193+
// DateTimeFormatter — has withConfig, getFormatPlaceholder
194+
} else if (myAttribute.formatter.type === "number") {
195+
// NumberFormatter — has withConfig
196+
} else {
197+
// Plain SimpleFormatter — string, enum, or boolean
198+
}
199+
```
200+
201+
##### DateTimeFormatter
202+
203+
**Date/DateTime** attributes receive a `DateTimeFormatter`, which extends `SimpleFormatter<Date>`:
204+
205+
```ts
206+
interface DateTimeFormatter extends SimpleFormatter<Date> {
207+
readonly type: "datetime";
208+
readonly config: DateTimeFormatterConfig;
209+
withConfig(config: DateTimeFormatterConfig): DateTimeFormatter;
210+
getFormatPlaceholder(): string | undefined;
211+
}
212+
```
213+
214+
The `withConfig` method returns a **new formatter** with a different date pattern while preserving the user's locale. It accepts a `DateTimeFormatterConfig` with the following options:
215+
216+
* `{ type: "date" }`: platform default date format
217+
* `{ type: "time" }`: platform default time format
218+
* `{ type: "datetime" }`: platform default datetime format
219+
* `{ type: "custom", pattern: "..." }`: custom Unicode date pattern (for example `"EEEE"`, `"dd MMMM"`, `"MMMM YYYY"`)
220+
221+
The following example formats a date attribute using a custom month-year pattern:
222+
223+
```ts
224+
if (myDateAttribute.formatter.type === "datetime") {
225+
const customFormatter = myDateAttribute.formatter.withConfig({
226+
type: "custom",
227+
pattern: "MMMM YYYY"
228+
});
229+
const formatted = customFormatter.format(myDateAttribute.value); // e.g. "March 2026"
230+
}
231+
```
232+
233+
`getFormatPlaceholder` returns a locale-appropriate placeholder string for the active date pattern, useful for input field `placeholder` attributes:
234+
235+
```ts
236+
const placeholder = myDateAttribute.formatter.type === "datetime"
237+
? myDateAttribute.formatter.getFormatPlaceholder()
238+
: undefined;
239+
```
240+
241+
##### NumberFormatter
242+
243+
**Decimal**, **Integer**, and **Long** attributes receive a `NumberFormatter`, which extends `SimpleFormatter<Big>`:
244+
245+
```ts
246+
interface NumberFormatter extends SimpleFormatter<Big> {
247+
readonly type: "number";
248+
readonly config: NumberFormatterConfig;
249+
withConfig(config: NumberFormatterConfig): NumberFormatter;
250+
}
251+
```
252+
253+
`NumberFormatterConfig` has the following options:
254+
255+
```ts
256+
interface NumberFormatterConfig {
257+
readonly groupDigits: boolean; // e.g. 1,000,000
258+
readonly decimalPrecision?: number;
259+
}
260+
```
261+
262+
The following example disables the thousands separator and fixes the output to four decimal places:
263+
264+
```ts
265+
if (myNumberAttribute.formatter.type === "number") {
266+
const customFormatter = myNumberAttribute.formatter.withConfig({
267+
groupDigits: false,
268+
decimalPrecision: 4
269+
});
270+
const formatted = customFormatter.format(myNumberAttribute.value); // e.g. "1234.5600"
271+
}
272+
```
273+
274+
##### Plain SimpleFormatter
275+
276+
For **string**, **enumeration**, and **Boolean** attributes the platform provides a plain `SimpleFormatter<T>` without a `type` property. These formatters convert raw values to human-readable captions (for example, enum captions configured in Studio Pro) and parse text input back to the typed value. They do **not** have `withConfig` or `getFormatPlaceholder`:
277+
278+
```ts
279+
// myEnumAttribute is an EditableValue<string>
280+
const caption = myEnumAttribute.formatter.format(myEnumAttribute.value); // e.g. "In Progress"
281+
```
282+
283+
##### Custom Formatters via setFormatter
284+
285+
You can supply a fully custom formatter for any attribute type using `setFormatter`. The object must implement `format` and `parse`:
286+
287+
```ts
288+
myDecimalAttribute.setFormatter({
289+
format(value: Big | undefined): string {
290+
return value !== undefined ? `$${Number(value).toFixed(2)}` : "";
291+
},
292+
parse(text: string): { valid: true; value: Big } | { valid: false } {
293+
const num = Number(text.replace(/[$,]/g, ""));
294+
return isNaN(num) ? { valid: false } : { valid: true, value: new Big(num) };
295+
}
296+
});
297+
```
298+
299+
Call `setFormatter(undefined)` to reset the formatter to the platform default.
300+
301+
##### Quick Reference
302+
303+
| Formatter type | `type` value | `withConfig` | `getFormatPlaceholder` | Applies to |
304+
|---|---|---|---|---|
305+
| `DateTimeFormatter` | `"datetime"` |`DateTimeFormatterConfig` || `Date` |
306+
| `NumberFormatter` | `"number"` |`NumberFormatterConfig` || `Big` (Decimal, Integer, Long) |
307+
| `SimpleFormatter` | `undefined` ||| `string`, `boolean`, Enum |
308+
166309
### ModifiableValue {#modifiable-value}
167310

168311
`ModifiableValue` is used to represent values that can be changed by a pluggable widget client component. It is passed only to [association properties](/apidocs-mxsdk/apidocs/pluggable-widgets-property-types-10/#association), and is defined as follows:

0 commit comments

Comments
 (0)