Replies: 5 comments 2 replies
-
|
One thing we need to fix is the re-syncing state between client and server when the user has been disconnected from the server. We need to send and set a couple of things when the websocket reconnects after a disconnect - things like the current site (site selector) that the user was on, the user's language of choice for the backend, etc.... Without doing that resync, we have a disconnect between the client state and the user server session- where the user looks like they are on |
Beta Was this translation helpful? Give feedback.
-
|
Is it possible to granulate the store? And not have a big file full of logic? I remember when we implemented NgRx Store on the UVE, we had that problem, our store was way too big and we solved that migrating to Signal Store with the |
Beta Was this translation helpful? Give feedback.
-
|
This is a great proposal @nicobytes , thanks for sharing. I agree that Before committing, I think we should try to define how our global state will potentially look like. Without this, we risk adding unnecessary complexity. Suggested Next Steps
Happy to discuss this further once we have a better understanding of the actual state boundaries. |
Beta Was this translation helpful? Give feedback.
-
|
My take on this, Angular Signals IntegrationInitially, I had concerns about NgRx using observables while Angular is moving toward signals. However, NgRx now provides This means: Best of both worlds - signals for UI reactivity, observables for complex async operations. NgRx: Simple Solution to a Complex ProblemNgRx appears complex, but it's actually a simple solution to the complex problem we already have: creating a root store with dotCMS's inherent complexities. The complexity exists regardless - NgRx just manages it systematically. Strongly Defined PatternsHaving a well-defined pattern means that after 6-12 months without touching the code, any developer can immediately understand how the state behaves. No guessing, no reverse-engineering custom solutions. Single Source of Truth & ReusabilityAny feature in dotCMS that needs sites, languages, feature flags, etc., knows exactly where to find them. One source of truth, completely reusable across all features. No data duplication or synchronization issues. Traceable DebuggingWe get highly traceable debugging - we know exactly how the store behaves at any point in time. Critical for enterprise clients when something goes wrong in production. Native WebSocket SupportWebSocket integration is natively supported through Effects. No custom implementation needed. Critical Boundary DefinitionThe most important consideration: clearly define what belongs in the root store and what doesn't. |
Beta Was this translation helpful? Give feedback.
-
|
Hello! Continuing with the conversion here, a first version of our global store looks like this: interface AppGlobalState {
auth: {
currentUser: CurrentUser | null;
permissions: UserPermissions;
};
currentSite: SiteDetails | null;
featureFlags: Record<string, boolean>;
systemLanguages: LanguageInfo[];
userPreferences: {
languageCode: string;
timeZone: string;
uiTheme: {
primaryColor: string;
secondaryColor: string;
darkModeEnabled: boolean;
};
navigation: {
isCollapsed: boolean;
};
};
license: {
type: 'community' | 'enterprise' | string;
version: string;
buildNumber: string;
};
breadcrumbMenu: MenuItem[];
}This is pretty short and contains the common states using across the all app. In this doc, more detail about that: |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
This RFC proposes adopting NgRx Store as the primary solution for managing global state for dotCMS app and keep Signal Store for local/component state. The goal is to reduce unnecessary server requests, improve UI/UX responsiveness, and provide a consistent approach to application-wide state management.
Background
We currently have two viable options for global state management:
Both solutions offer advantages and trade-offs. However, based on our project needs—including managing complex, interconnected data and scaling our architecture—NgRx Store I think is the more appropriate choice.
When to Use NgRx Store
When to Use Signal Store
Why NgRx Store?
Pros
Cons
Why Not Signal Store (For Global State)?
While Signal Store is a compelling solution for local state due to its simplicity and lower boilerplate, it presents several challenges for global state:
Ecosystem Limitations
@ngrx/store-devtoolsor@ngrx/router-store. For example, the router-store lib will be useful to solve the problems with navigation state and solve some issues in our breadcrumb component.Limited Computed Reusability
Signal Store's
computed()values can't easily reference each other, making selector composition more difficult:By contrast, NgRx selectors are easily composable:
Signal-Compatible Selectors
NgRx allows selectors to be consumed as signals in component code:
How to Work with Global State Management Using Nx?
We need to explore how to structure and access global state effectively using the Nx libraries.
🔍 Spike Needed: Investigate and document the recommended patterns for managing global state in an Nx monorepo.
Key Questions:
Example Case:
The edit-content feature needs to read and update global application state. How should this interaction be designed using Nx boundaries, dependency rules, and shared libraries?
Outcome of this spike will help define our conventions and folder structure for scalable state access and sharing.
Conclusion
Given the complexity of our global state, our scale, and the need for a robust ecosystem, NgRx Store is the most suitable choice for our global state management strategy. While Signal Store remains useful for local component state, NgRx will offer the consistency, scalability, and tooling support needed for our application architecture.
Beta Was this translation helpful? Give feedback.
All reactions