NT Highlights for October

Highlights on what has been done during October and more. Tips and tricks for some functionality developed in new tech.
Modestas Dromantas
Modestas Dromantas

Highlights for October an more.

Apps redirect concept

In order to replace CT apps with NT versions there is BetaRedirectUrl field, which should be used to have NT app ID, for system to know to which NT app it should be redirected.

It can be changed on /system-applications and /appdesigner-articlelist and it is published with an app. All links should be auto redirected as well. 

To access CT version just add '/ct/' prefix before NT App ID. https://omega.omega365.com/ct/workflows should load CT version.

Please be carefully and verify NT app before publish in order not to disappoint clients, collogues and especially NT tech :)

Master and details app concept

One of our most used case is having grid and details panel IFrame. So when you do changes it would be nice for them to reflect in both places. One of the downside of an IFrame is also when changing indexes in grid, details panel gets reloaded all the time.

So concept used in CT was transferred in NT in a easier to use way. Base idea is not to reload an Iframe, but to reload data source instead, also same thing applies when doing changes in details, data source in parent be reloaded and vise versa.

Iframe component which is not reloading once source changes: 'o365.vue.components.DetailsIframe.vue'. Idea for it is to load source only one time. It is also used to post message to IFrame component.

Messaging utility: 'o365.modules.utils.GlobalMessenger.ts'. It has methods to listen and post messages, so in Master app we use it to listen changes from IFrame and in details it can listen and post data. 

This is already implemented in workflows-sprint app and snippet with full code can be found in appdesigner.

Lookup multiselect 

Data lookup has multiselect property, which opens list where user can select multiple values, so user selects and in bind function we get selected items, which in some sort of form we add into database. it can be stored as comma separated list or as JSON. But in order to show selected values once multiselect lookup is opened :itemLoad function needs to be added in order to mark row as selected, in function row from lookup and current row is passed and there 'lkpItem.isSelected = selectedTags.includes(lkpItem.Tag);' can be checked. When filtering, it will still maintain user selection as it is enabling keep selection after reload by default for all multiselect lookups. 

More on this can be found under Data Lookup snippet in appdesigner.

Data Grid & Data Object

Edit mode activated with single instead of double click.

All grid menu tabs can be still accessible from a hamburger menu in footer. Useful when grid menu is hidden.           

Download of Import/update templates added. Can be enabled with importData prop on grid component. Buttons are visible depending on data object allowInsert and allowUpdate setting. Once template imported backend will resolve data by PrimKey's, so if PrimKey do not exist it will insert, otherwise update.

ODataColumn new 'required' prop added, which will style new rows accordingly with '*'. Style will be also added if field meets some criteria, see snippet bellow. 

dataObject.selectionControl.enableKeepSelectionAfterLoad() - will maintain selection always, no matter if it exists after filtering. It is disabled by default, as not everyone is used to this behavior in grids so selection is gone after data reload. 

Distinct filter. In order to have better performance when filtering, use ID columns. Check snippets for distinct.

New Components

Content editable alternative: Marked component can be used to support clickable links. <marked v-model=""/>. Also it renders markdown pretty well, so simple things as bold, italic or list can be used.

Person image component system.vue.components.PersonImage.vue. It renders image tag with src to user image.

Full text search component o365.vue.components.FullTextSearch.vue. Requires data object and search function. Check snippets or workflow app.

Live Updates

It is possible to enable live listeners for specific data objects on the app, it means, if 2 users has same app opened and one changes something, another one instantly will see that change. It is build on top of the SignalR library which uses websockets or server-sent events, and once data is changed in one window, it is sending affected PrimKey to everyone who is listening. Once it is received on client, it reloads specific row. Due to security reasons it send only affected PrimKey's in order not to expose data via this channel. Do not use this with sensitive/confidential data as you can do manual things as well. Be responsible.

This is already enabled in workflow sprints app. More details can be found under snippets.

Other

Data object FileUpload extension extended to support base64 string and direct blob uploads when using dsObject.fileUpload.upload method.

New Orgunits app '/nt/orgunits' in play as a showcase for data grid tree concept, Check this app to get inspiration for your new tree control concept :)

System properties concept has been introduced, you can check it on workflows register, filtering works out the box. Check snippets on more info.

Download of files and especially when previewing images should be much faster as we do direct stream from azure from now on.

Some notes, ongoing tasks

Db manager query app is already integrated in Appdesigner which is already covering almost all functionality, except autocomplete is still missing and hopefully we will be able to implement it in smarter way. 

As for /nt/db-manager, table designer is still missing and once it is complete we will publish new blog post.

We are trying our best to implement proper intellisense in Vue and typescript files to boost development experience.

Some tips

When defining master details binding without setup, without fields, selected dataobject will be reloaded automatically.

ODataLookup has dropdown icon by default, but it would be better to use bootstrap form-select class instead of form-control one.

In NT having instead of triggers on views no longer requires having all fields synchronized between app datasource and trigger return statement, now it is enough just to type select * .

On the other hand, in some cases we don't need to use instead of triggers anymore as data object events like BeforSave, BeforeCreate has params of not only row, but also props which is being sent as payload so there is possibility to intercept and change it. We use it in such cases when we have View with Union like in system-applications app, and depending on situation we need to change data and which table to update, just by changing values and uniqueTable.

In grid, try using loadDataObject prop in order for grid to invoke data load when it is needed on load, this is especially relevant in combination with onDemandFields prop, which makes a query to select only user selected columns and make query to perform better, other columns will be loaded async once they are added by the user.