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

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.



