Skip to content

novichkov-lab/generix-ui

Repository files navigation

Generix UI

This is the user facing portion of the Generix Data Clearinghouse. It is designed to simplify tasks on our system that can be challenging for data producers and data consumers alike.

Installation

to get started, make sure you have npm and Angular installed. This app is built with Angular version 7.2.5.

npm install -g @angular/cli

Fork and clone a repo and then install all the necessary dependencies in package.json.

npm install

If you run into dependency problems you can't resolve, try installing an older version of @angular/cli. This app has been successfully deployed with Angular versions 7.2.5 and 7.2.15.

To run a development server, use the ng serve command and open your preferred browser to localhost:4200

Deployment

Once you are logged into the server, you can find a clone of the repository at /home/clearinghouse/env/generix-ui/generix-ui. Pull your changes and run the following build command:

npm install

sudo ng build --prod --base-href /generix-ui/

The build target directory is configured in angular.json to default to /var/www/html/generix-ui/. In order for the resources to be loaded correctly, the base href needs to be set to /generix-ui/. This can either be done with the --base-href flag as demonstrated above or you can manually change it in the index.html generated by the build command.

Note that everything in the build target directory will be deleted!

The --prod directive above configures the UI with the "prod" environment, which is configured via src/environments/environment.prod.ts

If there is not an .htaccess file in the build target directory, a new one will need to be generated for the page to load. paste the following code below in a new .htaccess file at /var/www/html/generix-ui/:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
  RewriteRule ^ - [L]

  RewriteRule ^ index.html
</IfModule>

Overview

generix-ui is structured into modules that pertain to the part of the site the user is visiting. The following diagram is a high level overview of the structure of the app.

app.module
|__ search.module
|   |__ search components
|__ upload.module
|   |__ upload components
|__ plot.module
|    |__ plot components
|__ shared folder
    |__ components
    |__ services
    |__ directives
    |__ models
    |__ pipes

  • components that do not require services (a simple display page) are declared at the app.module level and can be found in /src/app/shared/components.

  • each child module has 1 or more service(s) that act as controllers for the components within the modules. All service files can be found in /src/app/shared/services/.

  • to encourage type safety, patterns that are commonly used throughout the app are stored as ES6 classes and can be found in /src/app/shared/models.

Dependencies

The following is a list of some of the core UI dependencies that our app depends on. It is not a comprehensive list but provides the most widely used 3rd party modules throughout the app.

PlotlyJS

PlotlyJS is used to translate data bricks into data vizualizatoins that can be configured and viewed by the user. it is configured to work with angular using angular-plotly.

Angular-plotly provides us with a simple to use <plotly-plot> component that takes a data and layout input. Server calls typically provide data and layout in sebarate objects in the response.

Important: We are currently running angular-plotly at version 1.3.2 to prevent an issue that breaks changes for angular versions below 8. see here for more details.

jQuery

jQuery is installed in order to support custom UI element plugins, namely DataTables and Select2

DataTables

DataTables is used for rendering HTML tables with javascript to add search, filtering, and pagination to large tables. DataTables is currently implemented in generix-ui wihout an angular wrapper, so $ will need to be imported from jQuery in order to render a table as a DataTable. It is best to render a table in the AfterViewInit lifecycle hook with an ElementRef provided by angular as shown below:

import { ElementRef, ViewChild } from '@angular/core';
import * as $ from 'jquery';
import 'datatables.net';
import 'datatables.net-bs4'; // for bootstrap 4 styles
...
export class SomeComponent implements afterViewInit {
    @ViewChild('table') private el: ElementRef;
    dataTable: any;

    ngAfterViewInit() {
        this.someService.getSomeData().subscribe(data => {
            // assign data to table
            const table: any = $(this.el.nativeElement);
            this.dataTable = table.DataTable();
        });
    }
}

Select2

Select2 is used to create comboboxes that populate with data from our system. It is configured to work with angular using ng2-select2. Select2 elements can be rendered using a <select2> tag and take an input of options and data, where data is the data with will populate the dropdown and options take the congiguration for the dropdown. The cssImport input is necessary for select2 to add styles. User selection can be handled using the (valueChanged) event handler.

<select2
    [data]="data"
    [options]="options"
    [cssImport]="true"
    [value]="selectedValue"
    (valueChanged)="setValue($event)"
</select2>
>
import { Select2OptionData } from 'ng2-select2';

@Component({...})

export class ComponentWithSelect2 implements OnInit {

    selectedValue = '0';

    // typical select 2 options config
    public options: Select2Options = {
        width: '100%' // width is calculated here
        containerCssClass: 'select2-custom-container'
        // ^ class defined in styles.css, ensures consistent UI with the rest of app
        placeholder: 'placeholders can be put here'
        // placeholders only work if there is an empty data element in the data file
        query: (options: Select2QueryOptions) => {
            // this is the option used to get data asynchronously based on user search term
            const text = options.term;
            this.someService.getSomeData().subscribe((res: any) => {
                options.callback(res.results);
            })
        }
    }

    public data: Select2OptionData[] = [
        {id: '', text: ''}, // necessary to create placeholders and non default selections
        {id: '0', text: 'value that the user sees'}
    ];
}

Important things to note about Select2:

  • if a default placeholder value is specified, the valueChanged event is fired initially. In order to prevent unexpected behavior, it is best to check for an id of '' in your event handler.

  • Select 2 option data is in the format of {id: string, text: string}. When valueChanged is fired, the $event released has a property of value containing the ID of the item. The data itself can be found in $event.data.

  • In order to populate a select2 dropdown with a predefined element, the [value] input must be the id of the desired data item.

Bootstrap 4 and Ngx-Bootstrap

for CSS UI, Bootstrap 4 is used along with ngx-bootstrap for advanced javascript features (e.g modals and tooltips).

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •