Skip to content

karrla/ks-staging-frontend

 
 

Repository files navigation

+++ title = "Midgard-Angular" +++

Midgard-Angular

Summary

Midgard-Angular is an Angular web application that implements the core features of Midgard.

Midgard-Angular is your application root repository. When you create a Walhall application, Walhall forks Midgard-Angular to your GitHub account and gives it the same name as your application. It comes pre-configured to communicate with your application's API via BiFrost. This is where you develop your Walhall application.

Current Angular version: v7.2.13

Setup

Initialize the application

Install the npm packages and then initialize the application:

npm install
npm run init

The second command will initialize the Midgard-schematics Gulp task. Midgard-schematics injects the clients into the application as dependencies and puts together the UI based on their features and the core Midgard features.

Build application

To build the application:

ng build

The build artifacts will be stored in the /dist directory. Use the --prod flag for a production build.

Run development server

To start a development server:

ng serve

The default location is http://localhost:4200. The server will listen for changes to the source code and update automatically.

Run unit tests

To execute unit tests via Karma:

ng test

Run end-to-end tests

To execute end-to-end tests via Protractor:

ng e2e

Features

Midgard is divided to two main section, the first is the application itself, which containes the interface and the core migard modules and tools. The second part is the admin section, which kind of developer tools where a super user can manage entries, check the paths and possible http operations of each endpoint.

Both Midgard and Midgard-admin are using Freyja components. For further information about freyja please read its documentation

Midgard - The Frontend application

File tree

The Midgard-Angular source /midgard has six main sub-directories:

  • /components: Components shared throughout the application.
  • /helpers: The application's helpers.
  • /modules: The core modules of Midgard-angular, such as the store, CRUD, http, etc.
  • /pages: Where you find the user interfaces of the "smart components" of Midgard.
  • /state: Everything related to the state of the application, such as models, reducers, and epics.
  • /styles: Global styles for your frontend application
  • /testing: Helpful classes, mocks, and stubs for testing.

Core interfaces

Midgard-Angular provides the following core user interfaces:

Login screen

Uses the OAuth library from midgard-core for the OAuth password-flow authentication process with BiFrost.

  • Register screen: A form where the user can register an account with the application. They will also be redirected to this screen after accepting an invitation from a super user.
User management

A screen where an administrator can manage users, update their own profile, and handle permissions in the application.

Screenshot: User management screen Screenshot: User management screen

List of actions:

  • Edit User Profile

  • Invite a new user by clicking;

  • List users in the application

  • Delete a user

  • Edit user data

  • Affect a user to a user group to handle permissions

  • Deactivate/ Activate User

  • Create User groups

  • Manage permissions per user group

  • Settings: A screen for configuring application settings.

These can be found under /src/lib/pages, and they have routes that are specified in /src/libmidgard-routing.module.ts.

Store module

The store module is a class that initializes the Redux store with the Walhall application's reducers using methods exposed by redux from midgard-core.

Once initialized, the store has the following methods:

  • subscribe: (listener: () => void): Subscribes to the state.
  • dispatch: (action: any) => void;: Dispatches an action.
  • getState: () => any;: Gets the current state.

The store also has a property called observable, which will return an observable version of the store.

In order to return data from a single reducer instead of the entire state, we made an rxjs pipeable operator that takes a memoized selector of the data you want to return and returns an Observable with the requested data.

The signature of the select function:

/**
 * Function that returns a stream of the state depending on a given selector.
 * @param {Function} selector - memoized selector
 * @returns {<T>(source: Observable<T>) => Observable<T>}
 */
export const select = (selector: Function) => <T>(source: Observable<T>) => Observable<T>()

The store module contains a file called reducer.utilities.ts, which offers common CRUD functions to use in reducers.

Reducers & Epics

The store module also enables you to combine reducers and provide epics. The reducers and epics will be injected into your application after the midgard-schematics command (npm run init) is executed in the build process.

Custom reducers can be added to the reducers object under src/lib/modules/store/store.ts. Custom epics can be added to the array in this file.

Example:

const reducers = {
    apolloReducer,
    topBarReducer,
    coreuserReducer,
    authuserReducer,
    workflowTeamReducer,
    workflowlevel1Reducer,
    workflowlevel2Reducer
    // your reducer goes here
    };
const epics = [
    coreUserEpics,
    authUserEpics,
    workflowteamsEpics,
    workflowlevel1Epics,
    workflowlevel2Epics
    // your epic goes here
    ]

HttpService

Midgard-Angular implements the Midgard HTTP client as the HttpService. The main function of the HttpService is the makeRequest function:

  /**
   * function to send a Http request to the API
   * @param {string} method - Http verb of the request (GET,POST,PUT,...)
   * @param {string} url - url endpoint to send request to e.g ‘contacts’
   * @param {any} body - data of the request
   * @param {booelan} useJwt - boolean to check if we want to use JWT or not
   * @param {string} contentType - type of content to be requested
   * @param {string} responseType - the expected response type from the server
   * @returns {Observable} - response of the request or error
   */
  makeRequest(method: string, url: string, body = null, useJwt?: boolean, contentType?: string, responseType?: string): Observable<any>

CRUD Module

The CRUD module provides basic CRUD operations. It can be implemented either using a UI component or an Angular directive (i.e., in headless mode). You must import MidgardCrudModule into your Angular module in order to use this module.

To implement it using the UI component, do so as follows:

// crud.component.ts
// import the selector
selector = getAllProducts;

cardItemOptions = {
  title: {
    prop: 'name',
    label: 'Product Name'
  },
  subText: {
    prop: 'make',
    label: 'Product Brand'
  },
  link: {
    prop: 'style',
    label: 'Style'
  },
  description: {
    prop: 'description',
    label: 'Description'
  },
  belowMenuPrimaryAction: {
    label: 'New Product',
    value: 'new'
  },
  secondaryAction: {
    label: 'Publish',
    value: 'publish'
  },
};

The crud module comes with its own dynamic crud redux files that can be used to handle crud operations for any endpoint using bifrost, this is perfect if you don't need to create any custom redux files for each endpoint. to make it function that way you need to provide it with the endpoint, the id property(the key value of the primary key) like follows. Work in Progress

// crud.component.html
<mg-crud-list
    [endpoint]="'coreuser'"
    [idProp]="'id'"
    [title]="'Most recent products'"
    [cardItemOptions]="cardItemOptions"
    [deleteMessage]="'The product has been deleted'"
    [addButtonText]="'Add Product'"
    [detailsRoute]="'/products/details/'"
    [defaultLayout]="'list'"
    (cardItemActionClicked)="handleCardItemActionClicked($event)"
    (cardItemEdited)="handleCardItemEdited($event)"
>
</mg-crud-list>

or if you prefer using custom redux files you have to provide the actions that does the crud operations and the selector to get the data from the reducer as follows: Only this method is currently available

<mg-crud-list
    [loadAction]="'LOAD_ALL_PRODUCTS'"
    [title]="'Most recent products'"
    [cardItemOptions]="cardItemOptions"
    [selector]="selector"
    [deleteAction]="'DELETE_PRODUCT'"
    [updateAction]="'UPDATE_PRODUCT'"
    [createAction]="'CREATE_PRODUCT'"
    [deleteMessage]="'The product has been deleted'"
    [addButtonText]="'Add Product'"
    [detailsRoute]="'/products/details/'"
    [defaultLayout]="'list'"
    (cardItemActionClicked)="handleCardItemActionClicked($event)"
    (cardItemEdited)="handleCardItemEdited($event)"
>
</mg-crud-list>

To implement it headlessly, do so as follows:

  • without custom redux files (only by providing the endpoint) Work in Progress
<div 
    mgCrud
    #crud="mgCrud"
    [endpoint]="'coreuser'"
    [idProp]="'id'"
    [deleteMessage]="'The product has been deleted'"
    *ngFor="row of crud.rows">
        <span> I am an element of the crud module rows </span>
        <!-- delete item using delete function of the the crud module -->
        <button (click)="mgCrud.deleteItem(row)">Delete</button>
</div>
  • custom redux files Only this method is currently available
<div 
    mgCrud
    #crud="mgCrud"
    [loadAction]="'LOAD_ALL_PRODUCTS'"
    [deleteAction]="'DELETE_PRODUCT'"
    [updateAction]="'UPDATE_PRODUCT'"
    [createAction]="'CREATE_PRODUCT'"
    [selector]="selector"
    [deleteMessage]="'The product has been deleted'"
    *ngFor="row of crud.rows">
        <span> I am an element of the crud module rows </span>
        <!-- delete item using delete function of the the crud module -->
        <button (click)="mgCrud.deleteItem(row)">Delete</button>
</div>

Translation module

The translation module lets you internationalize your Walhall application. It uses the Angular package ngx-translate with a custom loader that connects to the BiFrost API using the HttpService. It pulls the translation values from a JSON file found under /assets/translations.

In order to use it in your HTML template, you must import MidgardTranslationModule. You must also define your translations in src/assets/i18n/lang.json and then use the translate pipe as follows:

<span>{{'HELLO' | translate}}</span>

OAuth module

The OAuth module connects to the OAuth implementation in midgard-core and provides functionalities related to authentication, e.g., logging in using the password flow, logging out, retrieving and saving the access token.

Midgard-admin (The devtools)

Midgard admin offers devtools to check bifrost API paths and to manage entries for different endpoints. that is only accessible by a super user under this url {midagard_url}/admin-panel.

Interface

Main Interface

After a user is logged in, he will be directed to the interface. In the right section is the list of all the endpointsthat are available via bifrost as navigation elements . The middle section is reserved for CRUD operations on a specific endpoint. The right section is where the user can find the possible paths and the http operations that they accept. If a user clicks on one of the Http verbs an overlay opens with details information about the endpoint API definition. Screenshot: Main midgard admin screen

License

Copyright ©2019 Humanitec GmbH.

This code is released under the Humanitec Affero GPL. See the LICENSE file for details.

About

Angular frontend for walhall applications

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 78.5%
  • HTML 12.5%
  • CSS 7.6%
  • Other 1.4%