← All workCase study 01 / 10Enterprise platform modernisation

Bolero, a WiseTech Global business

Bolero / WiseTech Global

Led large-scale Angular upgrades and modernisation across a global trade and logistics platform, from v8 through to v19.

Role
Senior front-end engineer
Engagement
Multi-application delivery
Selected images
2
An enterprise Angular platform interface showing a data grid alongside a Highcharts-style analytics chart.

The opportunity

Bolero, a WiseTech Global business, runs enterprise-scale platforms built on Angular, with a codebase that had grown over many major versions. Bringing that platform forward meant more than routine dependency bumps: it meant rethinking legacy architecture patterns while keeping complex, business- critical workflows running for platform teams and their users throughout.

Upgrading Angular from v8 to v19

Bolero’s platform had fallen many major Angular versions behind, carrying legacy architecture patterns, ageing dependency injection usage, and template-driven and reactive form patterns that pre-dated Angular’s current best practice. Jumping straight to the latest release wasn’t realistic: the upgrade had to happen one major version at a time, with every step verified before moving to the next, across a codebase relied on by multiple platform teams.

I moved the codebase forward version by version, ensuring the full unit and end-to-end test suites passed at each step before progressing, so regressions were caught immediately rather than compounding across several major versions at once. Each upgrade surfaced breaking changes in key third-party dependencies — Formly, Bootstrap and AG-Grid all shipped incompatible API and styling changes across the versions covered — and I worked through each of these in turn, updating usage across the codebase and re-verifying against the test suites before considering that version complete. Alongside the version-by-version migration, I modernised the codebase itself: adopting standalone components, signals, the modern control-flow syntax, refreshed dependency injection patterns, and strongly typed reactive forms to improve both performance and long-term maintainability. I also developed reusable Angular components and shared UI patterns that were adopted across multiple platform teams, and delivered complex, data-driven interfaces using AG-Grid, Highcharts, Formly and Bootstrap 5.

The result was a platform brought fully up to date across eleven major Angular versions with no unplanned regressions, and a modernised foundation that teams could keep building on with current Angular patterns rather than legacy workarounds.

Building a multi-tenant, white-label theming system

Galileo needed to serve several distinct bank-branded user interfaces — UBS, BBK — from a single codebase, without resorting to per-client forks that would have made every future change harder to maintain and roll out consistently.

I designed and implemented a multi-tenant theming system built around per-registrar SCSS bundles, a runtime cookie-driven stylesheet-switching mechanism, and a centralised Angular theming service. This let the application resolve and apply the correct bank-branded stylesheet at runtime based on the active registrar, rather than shipping separate builds or maintaining divergent branches per client.

The result eliminated the need for per-client forks entirely: a single codebase now serves every bank-branded UI, and adding support for a further registrar is a matter of adding a new SCSS bundle rather than branching the application.

Retiring a deprecated layout dependency at scale

One of the harder technical problems I solved was replacing Angular Flex Layout after it was deprecated. It was used across a large part of the workflow and UI layer, so this was a high-impact issue with no straightforward migration path and no tool that could safely transform existing usage to an equivalent solution with minimal regression risk.

Rather than a fragile, one-off fix, I needed a scalable replacement that worked consistently across the application and aligned with our existing stack. I identified everywhere Flex Layout was used and analysed the recurring patterns — fxLayout, fxLayoutAlign, fxLayoutGap and fxFlex — then mapped them to Bootstrap utility classes, since Bootstrap was already central to our codebase. Instead of doing ad hoc replacements screen by screen, I designed a directive-based solution in our shared library that centralised the default layout behaviour, applied the Bootstrap equivalents consistently, and supported layout variants like row, column, reverse and wrap, with room to extend the directive layer as further cases appeared.

The result was a clean, low-risk migration path that removed the dependency on a deprecated package, reduced the risk of inconsistent manual changes, and left a reusable, maintainable foundation for future layout work — handled through the shared directive approach rather than repeated custom fixes.

Visualising nested entity hierarchies in a permission-linking flow

Bolero’s client-administration screens let an admin link a user to entities that could nest up to five levels deep — entities, sub-entities and further nested extensions — across create, edit, view and permission-management flows. Every step of that journey, including the final confirmation before committing the change, needed to represent the hierarchy clearly, with selections at any level cascading sensibly to their children. There was no tree component anywhere in our shared library, and pulling in an external tree or org-chart library felt heavier than the problem warranted.

I built two components in our shared library to solve this. app-entity-grid-modal is an AG-Grid-based picker where admins search and multi-select entities and sub-entities, with selection rules that automatically cascaded a parent’s selection to its children (and back) and capped traversal at the fifth hierarchy level to keep deeply nested data safe to render. app-entity-relationship is a ControlValueAccessor component that renders the resulting selection as an actual branching tree — expandable parent rows fanning out through sub-entities and further nested extensions, drawn entirely with table markup and CSS pseudo-element borders acting as connector lines, without any canvas or charting dependency. That tree became the confirmation step of the linking flow itself: rather than a flat summary list, the admin sees the real branching structure of exactly what they’re about to link, several levels deep, rendered as its own connected diagram — a way of building a confirmation screen I hadn’t seen taken elsewhere.

The result was a clear, visual, before-you-commit view of precisely which entities and sub-entities a user was being linked to, reused across the create, edit, view, release and permission-management flows, without taking on a dedicated tree or graph-charting dependency.

Building a validated, multi-source documents workflow

Every ePresentation instrument — letters of credit, collections and open account transactions — needed a documents grid where users could add, edit, remove and validate electronic and paper documents, sourced from a local file browser, a paper-document library, or an existing entry in the document store. The grid itself was AG-Grid, with its own imperative state, sitting inside a declarative Formly-driven reactive form, and the two had to stay in lockstep so that an invalid row anywhere in the grid also invalidated the surrounding form — with no existing pattern in the codebase for bridging that gap cleanly.

I built a custom Formly field type, registered as a shared e-pres-documents-table type and reused across LC, collection and open account instruments, that wrapped the AG-Grid instance. It enriched column definitions at runtime with user column ordering, view/required state and Formly field metadata, and mapped between the grid’s flat row shape and the nested document domain model. A dedicated row validator kept a live, per-document validation cache so invalid rows were flagged in the grid and immediately reflected in the reactive form’s overall validity, while a single row-action dispatcher handled removing and replacing files, viewing documents, editing metadata, and triggering an EBL name-to-order reassignment workflow. Add-button visibility was itself gated by user authority, view-state configuration and instrument-specific business rules.

The result was one reusable, validated component instead of duplicated document-handling logic per instrument type, with new document sources, row actions and instrument-specific rules addable without touching the underlying grid or validation plumbing.

Working across the wider platform

Beyond these three pieces of work, I collaborated with backend engineers to build REST endpoints in Java and Spring Boot for end-to-end delivery, and worked with relational databases and SQL to query, analyse and troubleshoot application data in support of feature development and issue resolution. Quality was strengthened throughout with unit and integration testing using Jest.

Delivery was deeply collaborative: working closely with Product Managers and Product Specialists to refine requirements, clarify acceptance criteria and challenge assumptions, and with design and UX teams to improve accessibility, usability, responsiveness and consistency across enterprise applications. More recently, I’ve integrated GitHub Copilot CLI and Claude Code into daily development workflows, using them to investigate and resolve issues, refactor legacy code, and improve overall code quality and maintainability.

Contribution

  • Led Angular upgrades from v8 to v19 across large-scale enterprise platforms.
  • Adopted standalone components, signals, modern control flow, and strongly typed reactive forms.
  • Built reusable Angular components and shared UI patterns adopted across platform teams.
  • Delivered complex, data-driven interfaces with AG-Grid, Highcharts, Formly and Bootstrap 5.
  • Built a reusable, validated documents grid shared across LC, collection and open account instruments, bridging AG-Grid and Formly-driven reactive forms.
  • Designed a CSS-only nested tree visualisation for a five-level entity hierarchy, used as the confirmation step of a permission-linking flow.
  • Designed and led a multi-tenant, white-label theming system for Galileo (UBS, BBK).
  • Built a runtime cookie-driven stylesheet-switching mechanism and centralised Angular theming service.
  • Collaborated with backend engineers on REST endpoints using Java and Spring Boot.
  • Queried and troubleshot application data using SQL against relational databases.
  • Strengthened quality with unit and integration testing using Jest.
  • Partnered with Product and UX teams on requirements, accessibility and consistency.
  • Integrated GitHub Copilot CLI and Claude Code into daily development workflows.
  • Replaced deprecated Angular Flex Layout with a scalable, directive-based Bootstrap layout solution.

On any device

How it looks on your screen.

Laptop
An abstract representation of the enterprise Angular platform viewed on a phone.
Phone
An abstract representation of the enterprise Angular platform viewed on a tablet.
Tablet