node package manager
Painless code sharing. npm Orgs help your team discover, share, and reuse code. Create a free org »

react-application-core

React Application Core

A react-based application core for the business applications.

Description

The library is designed to quickly start developing business applications are based on React, Redux, Material-UI.

Demo

Dependencies

Usage

Containers

Roles container
import * as React from 'react';
 
import {
  listWrapperMapper,
  filterWrapperMapper,
  defaultMappers,
  BaseContainer,
  DefaultLayoutContainer,
  SearchToolbarContainer,
  ListContainer,
  ContainerVisibilityTypeEnum,
  IBaseContainerInternalProps,
  connector,
} from 'react-application-core';
 
import { ROUTER_PATHS } from '../../app.routers';
import { IRolesContainerInternalProps, ROLES_SECTION } from './roles.interface';
import { IAppState } from '../../app.interface';
import { AccessConfigT, IRoleEntity } from '../permission.interface';
import { AppPermissions } from '../../app.permissions';
 
@connector<IAppState, AccessConfigT>({
  routeConfig: {
    type: ContainerVisibilityTypeEnum.PRIVATE,
    path: ROUTER_PATHS.ROLES,
  },
  accessConfig: [AppPermissions.ROLES_VIEW],
  mappers: [
    ...defaultMappers,
    (state) => filterWrapperMapper(state.roles),
    (state) => listWrapperMapper(state.roles)
  ],
})
class RolesContainer extends BaseContainer<IRolesContainerInternalProps, {}> {
 
  public static defaultProps: IBaseContainerInternalProps = {
    sectionName: ROLES_SECTION,
  };
 
  constructor(props: IRolesContainerInternalProps) {
    super(props);
  }
 
  public render(): JSX.Element {
    const props = this.props;
    return (
        <DefaultLayoutContainer {...props}
                                headerItems={<SearchToolbarContainer {...props}/>}>
          <ListContainer listOptions={{
                           itemOptions: { tpl: this.tpl },
                           addAction: this.permissionService.isAccessible(AppPermissions.ROLE_ADD),
                         }}
                         {...props}/>
        </DefaultLayoutContainer>
    );
  }
 
  private tpl = (item: IRoleEntity): JSX.Element => (
     <span>
       {item.name} {this.nc.id(item.id)}
     </span>
  )
}
Role container
import * as React from 'react';
 
import {
  BaseContainer,
  FormContainer,
  FormDialog,
  TextField,
  toSelectOptions,
  listWrapperEntityMapper,
  formMapper,
  DefaultLayoutContainer,
  defaultMappers,
  ChipsField,
  ContainerVisibilityTypeEnum,
  IBaseContainerInternalProps,
  connector,
} from 'react-application-core';
 
import { IRoleContainerInternalProps, ROLE_SECTION } from './role.interface';
import { IAppState } from '../../../app.interface';
import { RIGHTS_DICTIONARY } from '../../../dictionary';
import { ROUTER_PATHS } from '../../../app.routers';
import { AccessConfigT } from '../../permission.interface';
import { AppPermissions } from '../../../app.permissions';
 
@connector<IAppState, AccessConfigT>({
  routeConfig: {
    type: ContainerVisibilityTypeEnum.PRIVATE,
    path: ROUTER_PATHS.ROLE,
  },
  accessConfig: [AppPermissions.ROLE_VIEW],
  mappers: [
    ...defaultMappers,
    (state) => formMapper(state.roles.role),
    (state: IAppState) => listWrapperEntityMapper(state.roles, state.roles.role)
  ],
})
class RoleContainer extends BaseContainer<IRoleContainerInternalProps, {}> {
 
  public static defaultProps: IBaseContainerInternalProps = {
    sectionName: ROLE_SECTION,
  };
 
  constructor(props: IRoleContainerInternalProps) {
    super(props);
    this.loadRights = this.loadRights.bind(this);
  }
 
  public render(): JSX.Element {
    const props = this.props;
    const entity = props.entity;
    const entityId = entity ? entity.id : null;
    const isNewEntity = !entityId;
    const dictionaries = props.dictionaries;
    const rights = dictionaries.rights && dictionaries.rights.data;
    const title = isNewEntity
        ? 'New role'
        : `Role ${this.nc.id(entityId)}`;
 
    return (
        <DefaultLayoutContainer navigationControlType='arrow_back'
                                navigationControlHandler={this.activateFormDialog}
                                title={title}
                                {...props}>
          <FormContainer {...props}>
            <TextField name='name'
                       label='Name'
                       autoFocus={true}
                       required={true}/>
            <ChipsField name='rights'
                        label='Rights'
                        options={toSelectOptions(rights)}
                        onEmptyOptions={this.loadRights}
                        useFilter={true}/>
          </FormContainer>
          <FormDialog ref='formDialog'
                      onAccept={this.navigateToBack}
                      {...props}>
          </FormDialog>
        </DefaultLayoutContainer>
    );
  }
 
  private loadRights(): void {
    this.dispatchLoadDictionary(RIGHTS_DICTIONARY);
  }
}

Effects

import { EffectsService, IEffectsAction } from 'redux-effects-promise';
 
import {
  buildEntityRoute,
  provideInSingleton,
  ListActionBuilder,
  BaseEffects,
  effectsBy,
  makeFilteredListEffectsProxy,
  makeUntouchedListEffectsProxy,
  makeFailedListEffectsProxy,
  makeEditedListEffectsProxy,
} from 'react-application-core';
 
import { IApi } from '../../api/api.interface';
import { ROUTER_PATHS } from '../../app.routers';
import { ROLES_SECTION } from './roles.interface';
import { IRoleEntity } from '../permission.interface';
import { IAppState } from '../../app.interface';
 
@provideInSingleton(RolesEffects)
@effectsBy(
    makeUntouchedListEffectsProxy<IAppState>({
      section: ROLES_SECTION,
      listWrapperStateResolver: (state) => state.roles,
    }),
    makeEditedListEffectsProxy<IRoleEntity, IAppState>({
      section: ROLES_SECTION,
      pathResolver: (role) => buildEntityRoute<IRoleEntity>(ROUTER_PATHS.ROLE, role),
    }),
    makeFilteredListEffectsProxy({ section: ROLES_SECTION }),
    makeFailedListEffectsProxy(ROLES_SECTION)
)
export class RolesEffects extends BaseEffects<IApi> {
 
  @EffectsService.effects(ListActionBuilder.buildLoadActionType(ROLES_SECTION))
  public onRolesSearch(_: IEffectsAction, state: IAppState): Promise<IRoleEntity[]> {
    return this.api.searchRoles(state.roles.filter.query);
  }
}
import { IEffectsAction, EffectsService } from 'redux-effects-promise';
 
import {
  provideInSingleton,
  FormActionBuilder,
  IApiEntity,
  BaseEffects,
  makeSucceedFormEffectsProxy,
  makeFailedFormEffectsProxy,
  effectsBy,
} from 'react-application-core';
 
import { ROLES_SECTION } from '../roles.interface';
import { ROLE_SECTION } from './role.interface';
import { IApi } from '../../../api/api.interface';
import { IRoleEntity } from '../../permission.interface';
 
@provideInSingleton(RoleEffects)
@effectsBy(
    makeFailedFormEffectsProxy(ROLE_SECTION),
    makeSucceedFormEffectsProxy({
      listSection: ROLES_SECTION,
      formSection: ROLE_SECTION,
    })
)
export class RoleEffects extends BaseEffects<IApi> {
 
  @EffectsService.effects(FormActionBuilder.buildSubmitActionType(ROLE_SECTION))
  public onSaveRole(action: IEffectsAction): Promise<IRoleEntity> {
    return this.api.saveRole(action.data as IApiEntity<IRoleEntity>);
  }
}

Contributors

apoterenkochge

License

Licensed under MIT.