Cross-application styling / sync UI resources - Mendix Forum

Cross-application styling / sync UI resources

58

From a UI / frontend perpective the Mendix Desktop Modeller works well for designing and building standalone single apps that are branded for your organization. However there doesn’t seems to be a robust way to have multiple apps use or inherit the same set of styling and front-end features, in such a way that if a central UI Package is updated, that it automatically updates in all apps within a customer’s app portfolio. This has been an ongoing issue on my team, and I would like to suggest that Mendix R+D create a strategy or working group to enhance how UI Resource packages work towards the goal of “code css/scss once, deploy to all my company apps.”

The UI / Frontend dev team at my company has investigated some options described below, and currently have found some limited success. It’s not perfect, clean, or elegant, and still requires manual updating of each app anytime we release a new UI feature. But it has helped to gain some sanity from having each app have a completely different set of css/scss which was becoming very time-consuming and cumbersome to manage and keep all apps in sync from a styling perspective. Below are some approaches we have tried. I would encourage any UI teams who are building multiple apps in Mendix to upvote this issue.

Note: the following forum posts created by other Mendix users relate to aspects of this idea:

  1. https://community.mendix.com/link/questions/92064
  2. https://community.mendix.com/link/questions/17982

 

Goals:

  1. Avoid manual copy-pasting scss between different child projects for base UI features
  2. Keep AtlasUI pristine so that upgrading to future versions will be easier, and faster to implement by updating in base only.
  3. Still allow child scss to be applied
  4. Do not break the Mendix update/commit process
  5. Do not break the scss precompilation into css process
  6. Enable building and testing of new UI features within the base, before pushing out to all child apps

 

Requirements:

In order to be a viable solution to this problem, my team has come up with the following wish-list:

  1. Provide a central place for scss files to be created and edited so that new UI features can be built and tested before release.
  2. Require that all apps developed internally use this “core UI package” so that all apps have the same branded company look and feel
  3. If the core scss is updated and released, that it automatically pushes out these changes to all company apps.
  4. If a single company app needs specific scss / components / building blocks / widgets, that it can do so, and override the core.
  5. Easily revert core changes if they cause UI bugs or regressions in any company app.
  6. Maintain the existing svn workflow currently in the Mendix Modeller (keep update / commit working such that each app has it’s own repo, but with some common UI code

 

Option 1: Core “App Portfolio-wide styling” UI App for building and exporting a centralized Mendix UI Package

Following the Mendix standard documentation to use exported and imported UI packages, my team created a “core” UI app based on AtlasUI’s Reference / Custom Styling App (https://appstore.home.mendix.com/link/app/72335/) We use this to build and test new UI features (layouts, building blocks, components, css / scss), and apply company branding. We then export a UI package from this “core” app and commit it to our Private App Store. This enables any projects already created to import the UI resource package, and have a better chance of looking the way we want. We call this layer “Portfolio-wide styling.” But it has some drawbacks. When the core UI package is updated, it needs to be manually exported and imported into each of our apps. And we are planning to build over 30 apps, which is a lot of overhead for something that we wish could be done in a more automated way. Another issue is communicating the availability of this package to all groups within the organization has been a challenge, there is no obvious notification in the Mendix Modeller to a dev that they should use our company UI package, and we’re finding that apps are being built without it. Possibly we handle that with a communication / training strategy.

We also created an internal company “Starter App” and put this in the app store. This has the advantage of providing a company-branded “quickstart” app for any new projects being kicked off. It’s also more visible to other groups within the company as it shows up within the desktop modeller when creating a new project under “Starter Apps” (*as long as the mendix modeller version for the new app is newer than the version of the modeller used to create the starter app – a bit of a gotcha we discovered).

Sometimes a given project will need specific “app-only” styling. We do this by embedding a scss partial within the UI package of that app, not in the portfolio-wide layer. This is ok, however when we update the core UI package and import, we need to be careful to manually re-add this _project.scss partial otherwise app-specific styles are blown away by the Import UI package process.

 

Option 2: Hosting css externally (github or a CDN)

We didn’t explore this option too far, as we ran up against a few challenges / limitations. First it flattens the UI into css, and we lose any dynamic functionality provided by the Modeller. It also requires careful versioning of more than just css – including building blocks, components, and widgets. These entites are not easily separated from the Mendix project for external hosting. We quickly abandoned this idea.

 

Option 3: Leverage svn:externals

Using the Tortoise svn client in conjunction with the svn features already built into Mendix, we tried an svn feature called “externals.” (More about this feature of SVN can be found here: http://svnbook.red-bean.com/en/1.7/svn.advanced.externals.html) This method allows you to embed some code from one Mendix project into another. In our test we setup 2 Mendix projects, one “core” and one “child” for the purposes of UI package sharing from core-to-child. This seemed to work well – sass from the core could be updated and it would automatically get “pushed” into the child app UI codebase. Compiling scss into css worked, and could smartly combine variables and mixins that were defined in core when compiling the child app. It was relatively simple to setup. However it decoupled the sass from the mendix building blocks and components in such a way that we risked child projects having these objects available in the Modeller with no corresponding css to style them – especially when we found different groups within the org were using different versions of the Mendix Modeller for their projects. It also created a dependency on the Mendix team server which was a concern to our devops team given our need for different dev and production environments.

It may still be a viable option, however as was pointed out by one Mendix employee who was consulted, this approach lacks “explicit-ness.” Since it was all managed in the file explorer using Tortoise and svn – and there was no place within the Mendix Modeller for this configuration to be setup and managed – there was a risk that an untrained developer could inadvertently break it. We decided it was too obscure and opaque to be a viable option.

Conclusion

Given that the above options aren’t really a full solution, I would like to suggest that Mendix R+D create a working group (if they haven’t already) to enhance how UI Resource packages work towards the goal of “code css/scss once, deploy to all my company apps.” I would be happy to be a part of it in that case.

 

Footnote: The following use case scenarios were used to develop the options I described above. Not sure if they’re useful. I include them here in the case that this idea gains traction.

  1. UI team has a global change to apply to the frontend of all projects (ie new table header style). We make the edits to the scss in the core (base), compile to css using Koala, test in core Mendix project, and commit to base team server.
  2. Dev is working on child project 1. They need the new version of the table header css, and the knowledge that new classes exist and guidance from UI on how to apply them. A dev updates child 1 in Mendix which pulls down the new base css. They also check the base project on the cloud to find guidelines about implementation (like a living style guide)
  3. There's a new version of AtlasUI released. The UI group replaces the AtlasUI app in the base project and tests for any UI regressions. Once testing is complete changes are committed and the base project version is updated. Child project dependencies are updated so the base plus 1 revision is pulled in, and any conflicts are resolved. New Atlas changes should now appear in these updated child projects.
  4. Dev builds a new component in child 1. This exact component is useful, and child 2 needs to use it. The component is externalized into base and optimized. Once complete the component is committed into base+1 and pushed out into all child projcets (how? with versioning?) Child 2 now has the component available for use in Mendix. Child 1 now has an out of date instance of the component which may need refactoring. (could we reduce this refactoring risk through process somehow?)
  5. A custom widget is developed by dev for child 1. This widget is useful for child 2, but not for child 3. How do we ensure custom widgets are available for all projects, but not necessarily included in all? Mendix private app store?
  6. UI needs to globally change the colour of $brand-primary variable in variables.scss to apply to all apps. Instead of changing this variable in each child variables.scss, it's changed in base variables.scss. The next time each child scss is compiled in Koala it needs to grab the updated colour before generating the css. How to automatically trigger compilation of every child that references base/variables.scss?
  7. UI team needs to build and test new features and UI patterns. Once a new feature is ready for use in all child apps, UI needs to document and communicate these UI patterns through the dev teams.
  8. Other scenarios may exist from a devops perspective (changes x days before launch / change management throughout each environment i.e. local / dev cloud / production)
asked
7 answers

I think this is implemented in mx9

https://medium.com/mendix/setting-up-your-modular-design-system-in-mendix-9-6-eed2d0063411

There is still the issue of letting apps know there is an update available.
Some manual steps.
Dependency management.

But I think this is a step in the right direction?

Created

@rick This is something our team is going to need to solve very soon.

Im just going to hijack your post, and anything I learn, I’ll post here :D

alos if anyone has any tips, please share them.

Created

You got it Jason – that’s exactly the approach we’re using here at my office. We have a “Global UI” project in a lagging version of the desktop modeller to build, test, and centralize the UI package (sass, building blocks, page templates, and components). As you said, it’s messy and could benefit from streamlining. At the moment with 4 apps it takes some time to export from the “Global UI” project. I’m really concerned about how much more time this will take a year or two from now when we have 30 projects built with a broad range of modeller versions.

Created

o do you mean your own custom base ui that is built on atlas???

so this is how we have “solved” that issue (but its a horrible solution)

we have a module in a project that has been created in 7.16 where we create building blocks and layouts if there are new building blocks that we need (so we can import then in new projects).

and we have this sass structure that we copy/paste around

and where the _projectspecific isn’t overwritten.

its a mess but it works…

I would love to chat to someone at MX to see if there is a beter way to streamline this process.

Created

Hi Jason, thanks for your comment. In your screenshot that would be analogous to “Mx Project 1” in my diagram. What happens when you have 2 projects? How do you keep 2 different Atlas_UI_Resources in sync when certain “global” styles are created, without blowing away app-specific styles?

Now scale up to 30 apps. How would you keep 30 versions of Atlas_UI_Resources managable, such that a global change can be applied with minimum copy-pasting from app-to-app?

Created

is this not the centralized Atlas library?
or do you mean something else?

Created

Awesome post.

I think first of all there needs to be some “best practises”

Each designer or company seems to do things their own way.

Even within Atlas there seem to be inconsistancies.

Currently we have a cloud folder, and keep updating that and copypasting it around :D 

Created