1.0.112 • Published 10 months ago

@libreforge/libreforge-framework v1.0.112

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

LibreForge Framework

LibreForge Platform

LibreForge platform is WIX for enterprise - no code integrated development environment to let enterprises and agencies build user facing portals.

Overall Design

One of the main pillar of platform is open source LibreForge Framework.
The open source nature of framework empowers organizations to avoid vendor lock by providing freedom of choice, enabling customization and control over the source code, ensuring long-term viability independent of vendor roadmaps, promoting interoperability, and enhancing security through community-driven transparency and vigilance.

State Management

There are two types of state in LibreForge - Shared & Page states. Shared state is not cleared on page switch, Page state - is cleared.

Shared State

An example of Shared state usage is to keep the state of Loader, or keep the session information (like access token) and be sure that such information doesn't disappear, when user decides to move to another page. In other words, if we need the state to survive the page change, such state needs to be kept as shared.

E.g. if you inspect the default RouteToPageAction action, you will notice, that such action clears the page state, i.e.

dispatch.app.cleanCurrentPageState({})

Page State

Page state instead is used to keep the currently visible components values, metadata, etc - everything, which is needed to render the page, submit the data to backend, etc. On page change such data needs to be removed, as it isn't relevant for another page components.

Developer can assign DebugStateAction as the 'on click action' to the Button component to be able to debug state at a runtime (for dev testing purposes only). Such action requires the State Type parameter to be provided, which is either shared or page.

Framework Abstractions

This section delineates the framework's provided abstractions, essential for implementing a standardized collection of components, actions, etc. Furthermore, it defines the guiding principles of design that developers are expected to adhere to when crafting custom implementations.

AbstractAction

The framework furnishes a set of preconfigured UI actions, ready to be attached to UI components and triggered by the end-users, such as those triggered by button clicks. E.g. the actions triggered by the button click. For instance, the FormSubmitAction is usually attached to the FormSubmitButton component. Each action possesses unique characteristics, delineating specific conventions that developers must acknowledge and adhere to.

The framework offers flexibility beyond predefined actions, empowering developers to introduce custom actions seamlessly, thereby extending functionality accessible to both Designer and End Users Portal.

A prime illustration of this flexibility is evident in librepackage-security-oauth2-google, which provides Google based login capabilities, one of the enablement is OAuth2GoogleRedirectAction. This action initiates the OAuth 2.0 Authorization Code flow and is Google specific.

By inspecting the AbstractAction class, developers can understand, what is being available to the action at a time of execution.

@injectable()
export abstract class AbstractAction {

  abstract execute(context: ActionExecutionContext): Promise<{ next: boolean, result: any }>;

The ActionExecutionContext defines the next objects available during the action execution:

  • componentId - id of a component, the action is attached to and which has triggered it
  • collectionRefIdx - if UI component is rendered by iterating the collection (e.g. as it is done by forEach component), then index of collection item is propagated to an action execution
  • args - and object that keeps the value for action arguments, as it was defined during design time. E.g. if that's the FetchAction, then that one require url argument to be defined during the design time
  • pageComponents - page definition, i.e. all the components on a page, which is rendered. So that developer can get the component object by the componentId
  • currentPageState - object, which represents the temporary state (it's cleaned during the page switch) the current active page works with. All the components write to / read from this state
  • sharedState - object representing the state, which is capable to survive the page change. Such state is used to store the security token or loader state
  • dispatch - Redux dispatcher to let developer call reducers and change the currentPageState or sharedState during action execution
  • snackbar - to let developer show temporary end user notification
  • router - react router to let the end user be routed to another page
  • container - IoC/DI container to let reach any of the discoverable components / services / etc
  • prevExecutionState - currently the object, which contains the result of previous action execution. I.e. there may be multiple actions attached to the Button and these actions are executed one by one. It is possible to have a scenario, when 2nd action needs to work with result of 1st action execution (e.g. response from server)
  • pagination - pagination details (page, size), in case the action is executed in pagination context

As we can see the plenty of capabilities are made available to the action - it can interact with user, read / change the state, redirect and literally access any service through the IoC/DI context.

ComponentProvider

A "component provider" serves as an abstract interface enabling developers to seamlessly integrate new UI components. It acts as a conduit for the LibreForge framework to detect and incorporate these components, subsequently making them accessible to both Designer and the Portal.

To better understand the implementation, check

The Designer or Portal discovers about the component through the IoC/DI context, we make the component available by binding it to the context (see the binding details above). Then that's not the component itself, but the component provider the Designer & Portal deal with.

The ButtonProvider abstract class looks like

@injectable()
export abstract class ComponentProvider {
  abstract getCategory(): ComponentCategory;

  abstract getIcon(): ReactElement;
  abstract getName(): string;  
  abstract getComponent(...): ReactNode;

  abstract getInspectorControls(): {
    control: InspectorControlEnum;
    props: any;
  }[];

  abstract getDefaultProps(): any;
  abstract isContainer(): boolean;
}

where

  • getCategory - defines the category under which the component is rendered in Designer. The next categories are available right now layout, basic, fields, forms, wizard, tools, blocks
  • getIcon - icon rendered in Designer
  • getName - rendered in Designer, needs to be unique, as later it is stored in application configuration and is used to render the component on UI
  • getPreview - component itself
  • getInspectorControls - component specific controls enabled in Designer, e.g. FormSubmitButton needs url, Button doesn't need it
  • getDefaultProps - default values for components properties
  • isContainer - tells to Designer, that other components are droppable to the current one or not

For more information about the collection of components provided by the framework see the list of docs and read about each component separately in https://github.com/getlibreforge/libreforge-framework/tree/main/docs

AbstractValidationRule

This abstraction defines the validation rules for UI input components, which are executed upon form submission. I.e. during FormSubmitAction execution.

Inspect LengthBetweenValidationRule to understand the implementation by an example.

AbstractCallbackHandler

The callback handler enables developers to expose additional URLs, facilitating actions such as handling user clicks within an email or accepting redirects from third-party services along with associated data for processing.

The perfect example is the implementation of OAuth 2.0 Authorization Code protocol, when Service Provider needs to accept the redirect from Identity Provider with authorization code issued. This exact example is implemented in librepackage-security-oauth2-google, see OAuth2GoogleCallbackHandler

Security

LibreForge Framework provides the security abstractions to let developers implement end user authentication / authorization.

AuthorizationManager is an internal implementation, which drives the decision-making and undertakes the security related actions. AbstractAuthorizationConfigProvider tells to AuthorizationManager, which of urls are considered public and which are private. Developers shall override default implementation in projects in order to define project specific configuration.

E.g. inspect libreforge-general-dashboard-demo / DefaultAuthorizationConfigProvider. This is an example of end user portal with security configuration defined.

Additionally, AbstractSessionRefreshStrategy defines the mechanism to refresh the user session, e.g. OAuth2SessionRefreshStrategy defines the Google OAuth 2.0 specific implementation.

1.0.62

11 months ago

1.0.61

11 months ago

1.0.60

11 months ago

1.0.66

11 months ago

1.0.65

11 months ago

1.0.64

11 months ago

1.0.63

11 months ago

1.0.69

11 months ago

1.0.68

11 months ago

1.0.67

11 months ago

1.0.73

11 months ago

1.0.72

11 months ago

1.0.71

11 months ago

1.0.70

11 months ago

1.0.77

11 months ago

1.0.76

11 months ago

1.0.75

11 months ago

1.0.74

11 months ago

1.0.79

11 months ago

1.0.78

11 months ago

1.0.39

12 months ago

1.0.38

12 months ago

1.0.40

12 months ago

1.0.44

12 months ago

1.0.43

12 months ago

1.0.42

12 months ago

1.0.41

12 months ago

1.0.48

12 months ago

1.0.47

12 months ago

1.0.46

12 months ago

1.0.45

12 months ago

1.0.49

12 months ago

1.0.51

12 months ago

1.0.50

12 months ago

1.0.55

11 months ago

1.0.54

11 months ago

1.0.53

11 months ago

1.0.52

12 months ago

1.0.59

11 months ago

1.0.58

11 months ago

1.0.57

11 months ago

1.0.56

11 months ago

1.0.19

1 year ago

1.0.18

1 year ago

1.0.101

10 months ago

1.0.17

1 year ago

1.0.100

11 months ago

1.0.16

1 year ago

1.0.107

10 months ago

1.0.106

10 months ago

1.0.109

10 months ago

1.0.108

10 months ago

1.0.103

10 months ago

1.0.102

10 months ago

1.0.105

10 months ago

1.0.104

10 months ago

1.0.22

1 year ago

1.0.21

1 year ago

1.0.20

1 year ago

1.0.26

1 year ago

1.0.25

1 year ago

1.0.24

1 year ago

1.0.23

1 year ago

1.0.29

1 year ago

1.0.28

1 year ago

1.0.27

1 year ago

1.0.33

1 year ago

1.0.32

1 year ago

1.0.31

1 year ago

1.0.30

1 year ago

1.0.37

12 months ago

1.0.36

12 months ago

1.0.35

1 year ago

1.0.34

1 year ago

1.0.80

11 months ago

1.0.84

11 months ago

1.0.83

11 months ago

1.0.82

11 months ago

1.0.81

11 months ago

1.0.88

11 months ago

1.0.87

11 months ago

1.0.86

11 months ago

1.0.85

11 months ago

1.0.89

11 months ago

1.0.110

10 months ago

1.0.112

10 months ago

1.0.111

10 months ago

1.0.91

11 months ago

1.0.90

11 months ago

1.0.95

11 months ago

1.0.94

11 months ago

1.0.93

11 months ago

1.0.92

11 months ago

1.0.99

11 months ago

1.0.98

11 months ago

1.0.10

1 year ago

1.0.97

11 months ago

1.0.96

11 months ago

1.0.15

1 year ago

1.0.9

1 year ago

1.0.8

1 year ago

1.0.7

1 year ago

1.0.6

1 year ago