Skip to main content
Version: 7.0

What's new in version 7.0

This article describes how version 7.0 differs from versions 6.x: which capabilities it adds and what has to be taken into account when moving to it. Version 7.0 has not been released yet: the article describes the current state of the master branch and is extended along with it.

The full list of issues included in a release is in the changelog CHANGELOG.md, which is generated when the release is made, in the branch of its version. Changes that can break an application after an upgrade, together with the ways to restore the previous behavior, are described in MIGRATION.md.

Moving to version 7.0​

  • The client and the server are upgraded together: the API version has changed, and a client of version 6.x does not connect to a server of version 7.0.
  • The external API is disabled by default: the working parameter enableAPI is now 0 (it used to be 1), so /exec, /eval and HTTP calls of actions are refused until the API is enabled globally or for the roles that need it. A user with access to the System.interpreter form keeps access to the API. Which other calls are allowed and how to restore the previous behavior is described in MIGRATION.md. A multipart /eval request no longer binds its script part to $1, so a client that took its first value from $2 takes it from $1 again (#1930).
  • Incorrect logic no longer goes unnoticed: an application that used to start may fail to start or fail at run time if another session or a user interaction runs inside a transaction (#1726), a property depends on itself, a top-level navigator folder has no WINDOW, the CUSTOM of a window or a container is inconsistent, the TO list of the bulk form of NEW leaves out or repeats a parameter introduced in WHERE (#1917, #1918), or the field names of two properties of one table differ only in letter case (#1946). The error messages and the ways back for each case are given in MIGRATION.md.
  • Query results and plans may change: order-dependent aggregations and the order of independent global events have become deterministic, and the planner uses indexes more often (see Query planning and performance and MIGRATION.md).
  • A selection's element type is taken only where the platform's own element draws the selection: a form giving SELECT 'type' (select = 'type' in the design) where a CUSTOM render function or a React view draws the property is refused, which stops the server from starting. NOCUSTOM makes the platform draw that element — what CUSTOM 'fn' SELECT 'type' meant in 6.x, where the setting given last won — and dropping the type leaves the selection to the render function or the view.
  • Removed are the JKanban, FrappeGantt, Chart and Carousel bundled modules (#1739), the design properties showGroup, changeKeyPriority and changeMousePriority, and the working parameters that had no effect or had not changed for years (#1809–#1812, #1820).
  • Deprecated are USERFILTERS (FILTERS ... USER is used instead), NEWTHREAD ... CONNECTION and the DOCKED keyword when opening a form (WINDOW is used instead).
  • Custom Java code (INTERNAL actions, Spring beans) may need changes because of library upgrades: jdom 1 is replaced with jdom2 (the org.jdom package became org.jdom2), log4j 1.2 with reload4j, and Apache POI is upgraded from 4.1 to 5.5.

Language​

  • Action return values. The RETURN operator can return the value of an expression, TO writes the result of a call to a property, and actions can be used in expressions (#1561). HTTP actions pass the returned value in the response (#1562).
  • Dates and times. Arithmetic operators are defined for dates and times (#1570), and a loop can iterate over numeric ranges and date and time intervals (#1571). Iteration operators respect explicitly specified parameter classes (#1489).
  • Threads and executors. NEWTHREAD ... TO writes the result of a thread to a property, NEWEXECUTOR CLIENT executes actions on the client, including with a delay (DELAY) and periodically (PERIOD) (#1626, #1627), and waiting with NEWEXECUTOR ... WAIT can be limited in time.
  • The XML type. The XML built-in class is added; XML namespaces are determined by the EXTID of the form (#1584, #1585, #1591). JSON, JSONTEXT and XML values are displayed formatted.
  • New operators. Capture (SCREENSHOT) captures the current state of the user interface as an image or HTML markup (#1629), the selection operators (SELECT) report which rows and columns of an object group the user has selected, and INPUT MULTI lets the user choose several files (#1608).
  • Time formulas return a whole number of seconds of class LONG (#1785), currentYear() returns a value of class YEAR.

Forms​

  • Form extension, inheritance and composition (#1559) are described in the Form extension article.
  • Filters and sortings. FILTER(S) and ORDER(S) use one USER | FIXED notation (#1594). The ORDER, FILTER and FILTERGROUP operators change the sortings and filters of a form from an action, on the server (#1856, #1857). The ORDERS and FILTERS handlers fire only on a change made by the user (#1871).
  • Windows for forms. Windows of the FORMS kind and the AUTOSIZE window option are added (WINDOW); a form can be opened in a named window, and SHOW ... ACTIVATE activates a form that is already open instead of opening another one. ACTIVATE FORM and CLOSE FORM address open forms (#1842–#1844).
  • Opening and editing. SHOW and DIALOG accept an init action (#1588). The APPLY property option saves the changes right after editing (#1647). An action with an explicit SHOWIF is not hidden because it is implicitly inapplicable in the current state of the form, for example when the current object is NULL (#1613).
  • Views of an object group. The properties of a group in TOOLBAR or POPUP view go to its toolbar or popup, unless a property is given a view of its own; they used to go to the group's panel (#1891).
  • User form customizations. A broken customization no longer prevents the form from opening, and the administrator sees and resets the customizations of other users (#1765, #1766).
  • Export to Excel includes the FOOTER row (#1593).

Custom views and the client​

  • React views. React draws object groups, containers (DESIGN ... custom), the forms window and the log window (#1679, #1742, #1743). A component given the platform's standard view — custom = NULL in the design, NOCUSTOM on a property or a navigator element — is drawn by the platform inside a view and placed by it with <Platform name/> (#1887); a table, a toolbar, filter controls, a filter group and a property's filter take a React component themselves, with no container around them (GRID(o) { custom = 'OrderCards'; }, #1893). A property given SELECT is drawn by a view from all its options at once (select), changed by what is picked; SELECT is apart from who draws the property, so with NOCUSTOM the platform draws its element of the selection, and with CUSTOM a render function draws it; an element type given to SELECT is the platform's element's, and a form with one where a render function or a React view draws the property is refused. .jsx modules work without a separate build step and are processed by the React Compiler without Node (#1708, #1709); the transformed files are kept on disk, so a restart of the web server does not transform them again, and how long a page waits for them is the jsxTransformTimeout parameter of the web server (#1907); a full build is also available for src/main/web (#1678).
  • Custom views. They support trees, sortings and user filters (#1672, #1859, #1860); a cell says loading while a change of it waits for the server, a tree node while its children load, and the form's Refresh button React draws (formRefresh) while the form waits for the answers to its asynchronous requests (#1669), useShown tells the server which of the containers a view draws itself it shows, so nothing in a hidden one is read, and useVisible tells a view whether it is on screen (#1673), and the Buckets primitive simplifies building pivot views (#1703). The platform's toolbar and user filters work over the rows a view draws, of a list or a tree, and the platform's filter controls and the filter keys of its table over the user filters a view draws, which list what a condition can be on (filterProperties). A view can also draw a group's or a tree's toolbar (TOOLBARSYSTEM) and filter controls (FILTERCONTROLS) and a group's filter groups (FILTERGROUP) and the filters of its properties (FILTER(<property>) — one the platform draws is its row, placed with <Platform>, over the conditions a view draws too, #1937), their state in its data and their commands on its controller — a tree's on a node of its own, data.<tree>, with the tree's user filters and, where the view draws the tree's rows, its sortings (orders), its current row (current) and expandCurrent() (#1884). A property's filter and a condition added by hand — F3, filters.change — are stated by one rule: a value takes the place of the first condition on its property, keeping what is not stated of its comparison, negation and junction (or, which a property's filter shows and states too), no value takes that one off, and a condition with no value in a list compares with NULL. A group's user filters are one list, whoever draws and states them: the manual apply mode (userFiltersManualApplyMode) holds back a view's change as it does the panel's, applyFilters() sends what waits, and a property's filter, never removed, keeps its comparison while it has no condition (#1936). See How-to: Custom React form views.
  • Keys and mouse bindings of React views. The keys and mouse bindings the design gives what a React view draws — CHANGEKEY and CHANGEMOUSE of an action or a property that asks no value in a cell, the form's own buttons (Esc closes the form), the filters of a filter group — work as in the standard form while the component is shown (#1901). See How-to: Custom React form views.
  • Custom view controller. exec, eval, evalAction and change are available from JavaScript in custom views and in INTERNAL CLIENT (#1648); the CUSTOMS form block exposes properties and actions of the form to the controller (#1650, #1692). A React view's controller is built on members, which mirror its data, and the form's controller, controller.form, on names: besides those calls it does what a view's members do to what another container or the platform draws — the current object, sortings, user filters, a filter group, the toolbar's calls, a tree's nodes, a property's suggestion list — named by a group's, a tree's or a property's name. A property member's change, exec and getValues and a batch return a Promise of their request. See How-to: Custom view controller API.
  • Tables. Rows and columns of a table can be selected, the selection copied, everything selected with Ctrl+A, and one value pasted into all selected columns (#1597). The design option resizeShrink of a table or a property lets the user drag a column narrower than its width. The sum and the count on the toolbar are calculated over the marked rows (#1712); the TOOLBARBOX container stays last in the BOX of the form, so the components a design adds are placed above the toolbar (#1764).
  • Modal dialogs. Esc closes only the topmost dialog, and the focus does not leave it (#1788–#1790).
  • Web agent. Through a local agent, the web client prints to the printers of the user's computer and writes files to it.
  • The desktop client shows HTML captions of forms and navigator elements (#1190) and runs on Java 24 and newer (#1815).

Server, integration and AI​

  • MCP server. An application can act as an MCP server (#1620) with a built-in OAuth 2.1 authorization server (#1621), through which AI clients access it. The File API lets external systems browse the server resources (#1639).
  • Horizontal database scaling with a master server and replica servers (#1458, #1518).
  • Checking logic without a database. The dryRun parameter checks the logic and finds cyclic property dependencies without connecting to the database (#1737, #1757). The check can report several errors at once (#1797, #1798), and logics.topModule accepts a list of modules (#1740).
  • Working parameters. Any working parameter can be set in .properties files, environment variables or with -Dsettings.* (#1814); all parameters are now described.
  • Other. INTERNAL actions are compiled from .java sources located in the resources (#1707). An exchange can be specified for RabbitMQ (#1768). IMPORT XML does not process external entities (#1728). The CSV separator and CHARSET of IMPORT and EXPORT are expressions evaluated when the action is executed (#1883).

Query planning and performance​

  • Determinism. Order-dependent aggregations and row picks always give the same result (#1700). Global events with no dependency between them run in an order that follows from the logic and does not change from start to start (#1835).
  • Indexes. The planner uses indexes for ordered aggregations over columns that allow NULL (#1727) and when the session has unsaved changes (#1767), and takes into account an interval on any index field, not only on the first one (#1761). Pushing conditions down into aggregations has been reworked (#1699).
  • Resources. Inside a transaction, temporary tables are emptied with DELETE (#1792). Startup memory no longer grows with the number of dependency cycles (#1831), and parsing of modules and server startup are faster.