This repository contains the Open Water Foundation (OWF) Angular development web application (AngularDev), which is used to develop common library code. The libraries can then be used by other Angular applications such as OWF InfoMapper.
- Introduction
- Repository Contents
- Getting Started
- Angular Library Concepts
- Sharing Libraries with AngularDev
- Sharing Libraries with InfoMapper
- Angular Tasks
- Deploying the Site to AWS
- Contributing
- Maintainers
- Contributors
- License
This repository contains Angular software for common (shared) Angular libraries that can be used to streamline development of other Angular applications. Development uses a simple application (AngularDev) that is used for development and testing.
The focus of development is applications developed by OWF.
Libraries are currently not published to the public npm
registry.
However, it is possible that the libraries will be of benefit to others and
publishing to public npm
registry may occur in the future.
OWF is evaluating the best way to share libraries, for example using GitHub packages.
The following libraries are included in this repository, in addition to AngularDev application:
Library | npm package |
Description |
---|---|---|
common |
@OpenWaterFoundation/common |
Useful common code, including application utilities, classes ported from Java, and UI components based on Angular Material. |
owf-d3 |
@OpenWaterFoundation/d3 |
D3.js dynamic visualizations. |
owf-plotly |
@OpenWaterFoundation/plotly |
Plotly.js chart visualizations. |
owf-showdown |
@OpenWaterFoundation/showdown |
Markdown to HTML package using showdown.js. |
The library code is packaged with npm
to share locally with other applications,
including the following OWF applications.
Application | Description |
---|---|
OWF InfoMapper | Web mapping and visualization application. |
InfoMapper Map | Single map that can be embedded in a web page. |
SNODAS web application | Provides access to SNODAS snow data - OWF has developed an Angular version based on previous JavaScript/HTML prototype and needs to migrate to new integrated components. Conversion to use new libraries is planned. |
See the following resources for background information. This repository generally follows the conventions for an Angular "multi-project workspace".
- Angular web framework
- Angular - Architecture & Concepts
- Angular - Workspace and project file structure
- Angular - Creating Libraries
- Angular - Robust Library Architecture
npm
- Creating and publishing private packages- TypeScript - TSConfig Reference
The following folder structure is recommended for development.
Top-level folders should be created as necessary.
The following folder structure clearly separates user files (as per operating system),
development area (owf-dev
), product (AngularDev
),
repositories for product (git-repos
), and specific repositories for the product.
Currently the application only includes one repository;
however, additional repositories may be added in the future.
Folders within the Angular workspace adhere to Angular standards for a "multi-project
workspace", with the exception of library folder structuring. Libraries use a folder
architecture that is recommended by the developers of the compiler that builds Angular
libraries, ng-packagr
. If more granular import paths are desired, they recommend using
secondary entry points, similar to Angular Material, and Angular core. This removes the
need for the standard lib/
folder in the library. See Entry Points for more
information. Repository folder names should agree with
GitHub repository names. Scripts in repository folders that process data should detect their
starting location and then locate other folders using relative paths.
C:\Users\user\ User's home folder for Windows.
/c/Users/user/ User's home folder for Git Bash.
/cygdrive/C/Users/user/ User's home folder for Cygwin.
/home/user/ User's home folder for Linux.
owf-dev/ Work done on Open Water Foundation projects.
AngularDev/ Angular development application product files.
Other applications such as InfoMapper are similar.
------------------------------------------------------------------------------------------
---- Above are recommended, below folder names should match exactly. ----
------------------------------------------------------------------------------------------
git-repos/ Git repositories for AngularDev application.
owf-app-dev-ng/ Angular development application repository.
.gitattributes Main repository attributes.
.gitignore Main repository .gigitnore to ignore files.
README.md This file.
build-util/ Useful scripts for building software.
ng-workspace/ Angular workspace for the development application.
Use a generic name to emphasize Angular framework.
dist/ Built libraries (.gitignored since dynamic).
node_modules/ Third party libraries installed via `npm install`.
projects/ Standard Angular folder for multi-project workspace.
angulardev/ Application project containing main application.
src/ Standard Angular folder for source code.
app/ Standard Angular folder indicating application.
* Application source code.
assets/ Folder containing run-time configuration and data.
app-config.json Application configuration file.
common/ Library project containing common (shared) OWF code.
This library is used by other `owf-*` libraries
Specific examples are provided below for illustration.
src/ The library's main entry point folder.
index.ts Placeholder index.ts for main-entry point.
public-api.ts Exported members of the main entry point. NOTE:
The main entry point does not contain any
source code itself. All library source code
resides in secondary entry points.
ts/ Time series package (ported from Java).
TS.ts Time series class.
package.json Tells ng-packagr to compile this as a
secondary entry point into the library.
public-api.ts Exported members of this ts/ module as
a secondary entry point.
ui/ User interface components (based on Material).
dialog/ Code related to dialogs.
window-manager/ Code related to Window Manger for managing dialogs.
WindowManager.ts Class to manager windows.
package.json
public-api.ts
util/ Utility code package (ported from Java).
time/ Utility code for date/time.
DateTime.ts Class for date/time.
package.json
public-api.ts
owf-d3/ Library project containing D3.js visualizations.
* Follow Angular secondary entry point folder structure,
with folders to organize package's classes.
owf-plotly/ Library project containing plotly.js visualizations.
* Follow Angular secondary entry point folder structure,
with folders to organize package's classes.
owf-showdown/ Library project containing Showdown code
(Markdown viewer).
* Follow Angular secondary entry point folder structure,
with folders to organize package's classes.
This section explains how to initialize the development environment for AngularDev.
Development and deployment of this Angular based web application requires the following tools:
- Node.js (version 10.x or higher):
- Check which version of Node.js is installed by running
node -v
. To download Node.js, go to nodejs.org. Note that npm is installed with Node, but a separate npm package is recommended since npm updates far more often than Node does. The next step deals with this. - To update Node, visit nodejs.org and run the LTS installer.
- Check which version of Node.js is installed by running
- npm (version 5.5.1 or higher)
- Check which version of npm is installed by running
npm -v
. To install npm globally, runnpm install -g npm@latest
. - To update npm, run the same command above that installs it.
- Check which version of npm is installed by running
- Angular CLI (Command Line Interface):
- Check which version of Angular CLI is installed by running
ng --version
. If Angular CLI needs to be installed, runnpm install -g @angular/cli
. - To update Angular, follow the instructions at the Angular Updater. Note that Angular does not recommend updating multiple major versions at once, but step by step.
- Check which version of Angular CLI is installed by running
- Due to differences in environments, it is recommended that a single development environment is used. Do not mix the use of Git Bash and Cygwin on the same files on the same computer because they treat files differently with respect to line endings and executable permissions, which impacts Git.
- Unless noted otherwise, all commands should be run in the repo
owf-app-infomapper-ng/infomapper/
folder.
Currently, the Infomapper is installed by cloning the source repository into the
git-repos
folder. Change to git-repos
and execute:
git clone https://github.com/OpenWaterFoundation/owf-app-infomapper-ng.git
Run the following to install necessary software dependencies. This will install the OWF common Angular library and required third-party packages.
cd owf-app-infomapper-ng/infomapper
npm install
The above command may require several minutes.
The output will look something like this:
> core-js@3.8.3 postinstall C:\Users\sam\cdss-dev\StateMod-Web\git-repos\owf-app-infomapper-ng\infomapper\node_modules\@angular-devkit\build-angular\node_modules\core-js
> node -e "try{require('./postinstall')}catch(e){}"
Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!
The project needs your help! Please consider supporting of core-js on Open Collective or Patreon:
> https://opencollective.com/core-js
> https://www.patreon.com/zloirock
Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)
> @angular/cli@11.2.3 postinstall C:\Users\sam\cdss-dev\StateMod-Web\git-repos\owf-app-infomapper-ng\infomapper\node_modules\@angular\cli
> node ./bin/postinstall/script.js
The Angular application can be run locally in the typical way,
assuming that implementation files have been copied to the src/assets
folder.
cd infomapper
ng serve (will not open a web browser tab)
ng serve --open (will open a web browser tab)
The above may be slow the first time as code is compiled. After initial startup, changes to files will automatically result in a reload. View the website using the following URL:
http://localhost:4200
The default configuration will result in a website that appears as follows:
The default configuration and basic test data are distributed with InfoMapper in the
src/assets/app-default
folder.
The following table summarizes naming conventions used in a library, using common
as an
example.
Library Resource | Name                                                                      | Description |
---|---|---|
Library folder | common |
Folder in workspace/projects for library code. |
Import scope and path | import { TimeUtil } from @OpenWaterFoundation/common/util/time |
Import library classes using scope @OpenWaterFoundation and path to class folder (entry point). |
tsconfig.json paths | "paths": |
Creates an alias for imports. Any import starting with the path @OpenWaterFoundation/common/* will substitute dist/common/* for application compilation or projects/common/* for library compilation, and search for an entry point there. |
Main entry point public-api.ts |
export * from '@OpenWaterFoundation/common/util/time'; |
File exporting every secondary entry point in the library to be consumed by an application, class, module, etc. |
Secondary entry point public-api.ts |
export * from ./DateTimeUtil |
File exporting every class, component, module, etc. in the entry point folder to be found by the main entry point public-api.ts . |
Library package.json | "name": "@OpenWaterFoundation/common", |
The common library's package.json contains the library scope and name, the version of the library, and any peer dependencies and dependencies the library relies on. |
Secondary entry point package.json |
"ngPackage": { |
Contains basic information that declares this folder as a secondary entry point. This file is identical for every secondary entry point folder. |
npm zip file |
common-<version>.tgz |
The tarball file created after npm pack is run in the library's dist/ folder. The scope and version are taken from the library's package.json version name property. |
node_modules folder |
node_modules/@OpenWaterFoundation/common |
The npm installed common package in a consuming application's node_modules/ folder. Run npm install path/to/zip/file to install in node_modules . |
Git Packages | Needs to be researched |
A class is made known to code by using import
statements. It is desirable that import
statements use a full path to classes, to provide transparency and avoid ambiguity.
Angular libraries may contain many components and classes organized in folders. All Angular
libraries have a main entry point folder, located in the src/
folder under the library's
top-level folder. The src/
folder contains a public-api.ts
file that is needed to export all
modules, classes, etc. so that they can been seen by a consuming application. For example:
export * from '@OpenWaterFoundation/common/dwr/statemod';
export * from '@OpenWaterFoundation/common/services';
export * from '@OpenWaterFoundation/common/ts';
export * from '@OpenWaterFoundation/common/ts-command-processor/commands/delimited';
export * from '@OpenWaterFoundation/common/ts-command-processor/core';
export * from '@OpenWaterFoundation/common/ui/dialog';
export * from '@OpenWaterFoundation/common/ui/layer-manager';
export * from '@OpenWaterFoundation/common/ui/window-manager';
export * from '@OpenWaterFoundation/common/util/io';
export * from '@OpenWaterFoundation/common/util/string';
export * from '@OpenWaterFoundation/common/util/time';
The public-api.ts
file exports all modules under the folder and therefore can be used when
importing from the library; hence the term 'main entry point'. It is the single
entry point into the library for an application. For example, if the common
library only had a
main entry point, then a consuming application could import the following for the StateModTS
class:
import { StateModTS } from '@OpenWaterFoundation/common';
or the StringUtil
class:
import { StringUtil } from '@OpenWaterFoundation/common';
This would allow the module location to be resolved, but the exact folder for the class is not obvious. This is because the compiler uses the main entry point. Secondary entry points can be used to:
- Implement precise imports, e.g.
import { StateModTS } from '@OpenWaterFoundation/common/dwr/statemod'; import { StringUtil } from '@OpenWaterFoundation/common/util/string';
- Enable the ability for a library to split up its dependencies. The default import
statement (
import {} from '@OpenWaterFoundation/common
) resolves everything in the library, so even though a relatively small class is needed, the entire library with all dependencies would be required. Using a secondary entry point in a folder would only need the dependencies of the entry point, and wouldn't care about the rest of the library. This results in a smaller Webpack, and less dependencies for a developer or user when using the library.
OWF has implemented a configuration similar to Angular Material, the main Angular core, and other Google-made libraries supplied by Angular. The developers of the compiler that builds libraries also recommend this approach for the above reasons, as well as more that can be found at their Secondary Entry Points GitHub page. There is also an informative Medium article describing what has been implemented in this library.
The AngularDev application uses many different library modules under the common/
folder (e.g. ts/
, ui/
, and util/
) that can be shared with the angulardev
main
application. To use these modules from the common
library, the library must be
built using the following:
-
cd
intoprojects/
. -
Use the command
ng build common
to build the library into theng-workspace/dist/
folder. The library and its modules are then ready to be consumed by the application. -
If library code is also being updated, an option for the build command is useful. In the
projects/
folder ,ng build <lib-name> --watch
will not only build the library, but will keep listening to the file and watch for any other updates to it. This way, both the app and library can be updated simultaneously.Note:
ng build <lib-name> --watch
must be run beforeng serve
. If built after the app's server is running, warnings and errors will occur.<lib-name>
should be replaced with the name of the library to be built and/or watched.
The common
library was added using the command ng generate library common
.
Angular adds all the necessary references for the new common
library in workspace files,
one of them being the addition of a paths
property under compilerOptions in the
projects/tsconfig.ts
file. This property lists aliases that can be used when importing modules
from the library in the app. Override the default by adding the following:
"paths": {
"@OpenWaterFoundation/common/*": [
"projects/common/*",
"projects/common"
]
}
Using the *
wildcard in the path tells consuming modules/classes they need a more descriptive
path to the module to be imported, such as @OpenWaterFoundation/common/ui/window-manager
instead of
@OpenWaterFoundation/common
. Consequently, there will be no ambiguity as to the module origin.
The following is an example of import
to use a library class.
Goals of the implementation are:
- Follow standard Angular syntax and protocols.
- Clearly indicate "scope"
@OpenWaterFoundation
to distinguish as OWF library and avoid conflict with similarly named classes in other libraries. - Use folders to emphasize hierarchy of code, similar to other languages.
- Import statements should be the same whether the library is used in AngularDev application, InfoMapper, or other application.
import { WindowManager } from "@OpenWaterFoundation/common/ui/window-manager";
The projects/tsconfig.ts
file will look something like to following after the paths
property has been defined:
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"...": "...",
"paths": {
"@OpenWaterFoundation/common/*": [
"projects/common/*",
"dist/common/*"
]
}
},
"...": "..."
}
Since the libraries in this repository only use secondary entry points, the path to the entry
point must be supplied when importing a module. The above tells the ng-packagr
compiler that an
import using
import { WindowManager } from "@OpenWaterFoundation/common";
will not work, as there is no ending slash with the path to the Window Manager's public api TypeScript file. The previously shown WindowManager import statement containing the path to the class would work however:
import { WindowManager } from "@OpenWaterFoundation/common/ui/window-manager";
Libraries developed in this repository can be shared with other applications. This section uses the InfoMapper application as an example to explain how this occurs in both development & production.
The following is a summary of InfoMapper folder structure.
Note: InfoMapper will likely be converted to a multi-project workspace in the future, but the following currently uses a single application project folder structure.
C:\Users\user\ User's home folder for Windows.
/c/Users/user/ User's home folder for Git Bash.
/cygdrive/C/Users/user/ User's home folder for Cygwin.
/home/user/ User's home folder for Linux.
owf-dev/ Work done on Open Water Foundation projects.
InfoMapper/ InfoMapper product files
------------------------------------------------------------------------------------------
---- Above are recommended, below folder names should match exactly. ----
------------------------------------------------------------------------------------------
git-repos/ Git repositories for the InfoMapper application.
owf-app-infomapper-ng/ Angular web application.
infomapper/ InfoMapper Angular project folder.
node_modules/ Third party libraries installed via `npm install`.
Uses a specific name since only one project.
OWF libraries that are deployed from AngularDev application
will install here.
src/ Standard Angular folder for source code.
app/ Standard Angular folder indicating application.
* Application source code.
assets/ Standard Angular folder containing run-time configuration and data.
app-config.json Application configuration file.
* Other runtime configuration and data files.
It's possible to test a local Angular library with a separate local Angular application without having to build the library and install it into the application dependencies after every change. This greatly speeds up development in both app and library, and is not too labor intensive to set up. Here are the steps:
-
From the application top level folder (
infomapper/
for Infomapper), run:npm uninstall @OpenWaterFoundation/common
This uninstalls the current production-build npm-registry installed version from the project.
-
From the AppDev library top level folder, (
ng-workspace/
) enter the command:ng build @OpenWaterFoundation/common
This will create the
dist/OpenWaterFoundation/common/
folders, with the production ready library files in thecommon/
folder. There might be a built version in there from previous development sessions, but this confirms it's the most up-to-date. -
From the application top level folder, enter the command:
npm install file:../../../../AngularDev/git-repos/owf-app-dev-ng/ng-workspace/dist/OpenWaterFoundation/common/
NOTE:
npm pack
has not been run from the library, and no.tgz
file exists in thedist/OpenWaterFoundation/common/
folder. Thenpm install
command just looks for apackage.json
in the given folder.The Infomapper now has the local built AppDev library files.
-
In the AppDev top level folder, run:
ng build @OpenWaterFoundation/common --watch
This runs the build command on the library, then again whenever a file is changed. It is finished when the message
Compilation complete. Watching for file changes...
is displayed. -
Now that the previous command is in the library is waiting for updates, serve the application in the top level folder like normal:
ng serve --open
The application (Infomapper for this example) has the built files from the library dist installed in its
package.json
file, and the library is actively watching for updates to the library. This means when a file is saved in the library,ng build
is run, the dist files updated, and subsequently updated and recompiled in the application.
There are other options for testing local Angular libraries and applications, including using the npm pack tar file, and npm link which uses a global symlink to connect the two.
For detailed instructions on building and publishing the AppDev library, visit the library README file.
IMPORTANT: If testing the Common library using the above development instructions, the application
package.json @OpenWaterFoundation/common
property will contain the path to the local library files, instead of the library version to download from the npm GitHub registry. This needs to be changed back to the most recently published (or desired) version before pushing up any changes to GitHub.
The following sections contain checklists and notes about developing and consuming libraries from both a workspace and stand-alone application.
Libraries can have a few different top-level folders, normally the library name. This is not
always the case however. The common library, for example, uses common/
as
its top level folder name. When using the Angular Command Line Interface (CLI), Angular will
create the folder names. For example, using the command
ng generate library my-library
creates the top level folder my-library/
. Another option is to add a scope to the
library with the command
ng generate library @my-company/my-library
The CLI will create the top level folder @my-company/
, with my-library/
under that.
Names and scopes can also be manually changed. When the
ng generate library
command is used, one of the files it creates is the library's
package.json
file, which contains the property name
of the library, which is what
the library's compiler looks for when the ng build my-library
command is given. This name can
be altered so that another name can be used instead. In the common library, the command
ng generate library common
was used, creating the common/
folder. The library's package.json
was changed as follows:
{
"name": "@OpenWaterFoundation/common"
}
Even though the file structure still has the common/
top level file, the library's scope
and name have successfully been changed to @OpenWaterFoundation
and common
respectively.
Angular libraries can be consumed by applications in two different ways: using the library's main and/or secondary 'entry points'. An entry point corresponds to a folder where a class/componet/module exists. The common library only uses secondary entry points, meaning when a consuming application imports a class from the library, the following import statement
import { TS } from '@OpenWaterFoundation/common';
would not be enough, because it is attempting to use the library's main entry point, and a
specific folder is required. Using only the main entry point is by default how TypeScript
importing works, but thanks to Angular's ng-packagr compiler, options
for more granular imports are given by creating and using secondary entry points. After
research, OWF has decided to use the same structuring that the ng-packagr
developers and
Angular itself suggest and use.
Normally, a library's top-level structure would look something like the following:
my-library/ The library top-level folder.
src/ The library source folder.
lib/ The library lib folder where all source files reside.
* The source files of the library (classes, components, etc.)
The above import statement using the main entry point would work for this set up, does not
allow for granular import statements. According to one of the two main ng-packagr
developers,
when using secondary entry points, each entry point folder should exists beneath the library's
top level folder. A more in-depth description can be viewed under the common/
folder in the
Repository Contents section. Examples of articles that helped OWF
decide approach for library folder structuring can be found at ng-packagr
's GitHub
issues #900,
#959, and
#987.
The src/
folder only contains an empty index.ts
file and the main
entry point's public-api.ts
file that exports all secondary entry points. The library's
main entry point still needs to exist (as indicated by the existence of public-api.ts
file)
but contains no code.
Classes that do not include UI-components can be added to libraries. There are two different instances when a regular, non-UI class can be added: Adding it as a new entry point folder, and the simpler process of adding it to an already existing entry point folder.
To add a new class in a new folder:
-
Top-level folder: Create folder(s) for code
-
If necessary, create a folder directly underneath the top-level library folder. This will be the first folder given in the import path after the library scope and name, e.g.
"@OpenWaterFoundation/common/util"
Determine if more folders need to be created for the desired structuring. The longest / deepest folder will contain the entry point. In the
common
library for example, the pathts-command-processor/commands/delimited
has nested folders, withdelimited/
being the entry point.
If a branching import path wants to be added to the library:
- Create the sub folders if necessary, for additional levels of code hierarchy. For example
if
ts-command-processor/commands/
already exists and the sub-foldercore/
is to be added at the same level ascommands/
, thencd
intots-command-processor
and createcore/
. Any subsequent nested folders can be created as needed.
-
-
Convert the folder to an entry point by adding these 3 files with the following content:
index.ts
- Export the entry point'spublic-api.ts
. This file is always one line, exporting all content from thepublic-api
file.export * from './public-api';
public-api.ts
- Export the new class using the class name:export * from './WriteDelimitedFile_Command';
Note: Another name for this file has been confirmed to be
projects.ts
. If using the Angular CLI, any library created after the first will contain aprojects.ts
file in place of thepublic-api.ts
file. OWF is researching why the file name is changed, and how it still seems to serve the same purpose.ng-package.json
(package.json
is deprecated) - Finish lettingng-packagr
know this is a secondary entry point by adding the following:Schema details and an example of a basic{ "$schema": "path/to/../node_modules/ng-packagr/ng-package.schema.json", "lib": { "entryFile": "public-api.ts", "cssUrl": "inline" } }
ng-package.json
file can be found here and here respectively.
-
Create the class in the entry point folder:
export class MyClass { constructor() {} }
-
Export the newly created secondary entry point from the main entry point so it can be consumed by an application. This is done in the main entry point's
public-api.ts
file under the library'ssrc/
. Again, using thedelimited/
example:export * from '@OpenWaterFoundation/common/ts-command-processor/commands/delimited';
Note: Importing and exporting classes between entry points must use absolute paths (in this case scope and path), and not relative (
../../path/to/class
). See issue #987 for more information. Also confirm the workspacetsconfig.json
file has been updated so that the@
scope path-finding can be used. See Application Setup for information. -
In the consuming application, import the entry point in the desired location by importing the same path given in the main entry point export, e.g.
import { WriteDelimitedFile_Command } from '@OpenWaterFoundation/common/ts-command-processor/commands/delimited';
The class name itself is not required at the end of the path, because the compiler only cares about the entry point for the class.
Since the entry point has already been created and exported in the main entry point
public-api.ts
file, after the class has been created and placed in the entry point's folder,
adding it is simple:
- Export the class from the entry point's
public-api.ts
, e.g.export * from './newClass';
The new class can now be consumed by an application using an import statement with the path to the entry point.
A component is more complex than non-UI classes in that it contains features to manipulate the
DOM and change/update/show web page content to users. An example of the folder structure in the
common library is the dialog
entry point.
To create a component, first create entry point folders as per the
new entry point checklist for the
ui/dialog/
folder, including the creation of the 3 necessary files to
convert the dialog
folder into an entry point. Each dialog-*
folder in the above image
contains its own component. To keep things more compartmentalized, each component has its own
module.ts
that exports the component for use elsewhere. For more information on Angular
modules, components and services, see the
Angular Concepts Documentation.
- Change to
ui/dialog
folder. Create the component using:ng generate module dialog-data-table
- The CLI will create a new foldernew-module/
with adialog-data-table.module.ts
file.cd dialog-date-table/
ng generate component dialog-data-table
- The CLI will create the.css
,.html
,spec.ts
, and.ts
files
- Add the component and module to the entry point's
public-api.ts
orprojects.ts
file:export * from './dialog-data-table/dialog-data-table.component';
export * from './dialog-data-table/dialog-data-table.module';
- Export this entry point's
public-api.ts
file from the library's main entry point:export * from '@OpenWaterFoundation/common/ui/dialog';
- This only needs to be done once.
An application can now import the component in a component or class of its own to use it's TypeScript source code:
import { DialogDataTableComponent } from '@OpenWaterFoundation/common/ui/dialog';
or import its Module into its own to use the Component's HTML:
import { DialogDataTableModule } from '@OpenWaterFoundation/common/ui/dialog';
Creating an Angular library using the CLI will automatically update necessary files. There are 3 main ways to create a library in a workspace:
-
Use the CLI to create a new scope and library name by using the following commands:
cd ng-workspace/projects/
ng generate library @scope/lib-name
. For example,ng generate library @scope/lib-name
.
The CLI will set the correct scope and package name in the library's
package.json
, and create@scope/lib-name/
as two directories. -
Use the CLI to create a new library only:
cd ng-workspace/projects/
ng generate library lib-name
. For example,ng generate library common
If a scope is needed, it needs to be manually added to the library's
package.json
name property. Only alib-name/
folder will be used. -
Use the CLI to create a new library, then change the library name manually:
cd ng-workspace/projects/
ng generate library lib-name
. For example,ng generate library common
In the library
package.json
, add a scope to the library, and change the name in the name property. This way, The folder structure remains asng-workspace/projects/lib-name
, but the library scope and name are@scope/new-lib-name
. This was done for the@OpenWaterFoundation/common
library.
To be implemented.
To be implemented.
InfoMapper can be used to implement an integrated website containing maps and other information.
Currently, this is accomplished by creating a product folder, for example InfoMapper-MyRiver
,
and working with repositories for the software and implementation files.
Using a repository for implementation files allows important work to be saved and tracked.
In the future, a self-extracting executable to install InfoMapper may be provided.
An example folder structure for a project at the Open Water Foundation is shown below.
Note that the "product" folder in this case is "InfoMapper-MyRiver",
whereas the "product" for Infomapper software development is "InfoMapper".
C:\Users\user\ User's home folder for Windows.
/C/Users/user/ User's home folder for Git bash, corresonding to Windows user files.
/cygdrive/C/Users/user/ User's home folder for Cygdrive, corresonding to Windows user files.
owf-dev/ OWF (or any organization) development files.
InfoMapper-MyRiver/ InfoMapper files for "MyRiver" website.
git-repos/ Folder for Git repositories.
=============== above this line is a recommendation ======================================
owf-app-infomapper-ng/ Infomapper software repository.
owf-infomapper-myriver/ Infomapper implementation files.
See the links above for example implementations of Infomapper repository file structures.
Implementation generally involves copying files from the implementation folder into the
src/assets
InfoMapper folder, at which point the Angular application is able to use
implementation files. Once the Angular application is started (see
Running the Angular Application section).
To use Infomapper with an implementation, first check that the software is up to date by following instructions in Getting Started.
This section needs to be updated. It may be helpful to deploy the application to cloud server for testing. The following was copied from InfoMapper but has not been updated for AngularDev.
The site can be built in a dist
folder for local testing by using
the command
ng build --aot=true --baseHref=. --configuration production --extractCss=true --namedChunks=false --outputHashing=all --sourceMap=false
The content of the dist
folder can imitate a production build of the
InfoMapper. To run the InfoMapper in its distributable form, navigate to
the build-util
folder and run the run-http-server-8000.sh
file. In a
web browser, type in http://localhost:8000/
, then click on
dist/ > infomapper to run the InfoMapper.
Once checked locally, deploy to the Amazon S3 site by
running the following in the build-util
folder using a Windows command shell:
copy-to-owf-amazon-s3.bat
For example, see the deployment script for the Poudre Basin Information InfoMapper implementation. Poudre Basin Information
The above can be run if Amazon Web Services credentials are provided. A batch file is used to overcome known issues running in Git Bash.
NOTE: Going to the Angular Updater and using the
npx
commands do just fine for @angular scoped packages, but most of the issues ran into while updating were from third-party packages. It's important to make sure they are constantly being upgraded as well. If it seems like a package has been abandoned, another supported package might need to be considered. The full table of all installed packages for theng-workspace
can be found here.
Ever since the Infomapper and SNODAS started relying on the @OpenWaterFoundation/common library, updating the version of Angular has had a few steps added on to it. Updating from Angular 11 to 13 had it's share of growing pains and issues. One reason for this is because the Angular 12 to Angular 13 update removed support for the now deprecated View Engine compiler in favor of the Ivy compiler.
Packages need to make sure they are at least built with the tsconfig.lib.prod.ts
file's "compilationMode" : "partial"
property set. As mentioned above, an abandoned
or neglected package might not have this Ivy change, and could slow down updates.
Most have done a pretty good job though. The following steps will help pave
the way to a quicker Angular updates in the future:
- Do not update the Angular app (Infomapper, SNODAS) version first. The common library
versions and dependencies need to be updated first, so there are no conflicts when updating
the app's packages. Perform the update for the library via the
Angular Updater.
- For example, updating the Infomapper from Angular 11 to 12 will be in conflict with the common library. The library expects Angular 11, but 12 is now being used. Updating the library to the desired version, testing it, and resolving any issues first, allows the new library (package) version to be created. The app can then be updated and its own issues dealt with, without having to worry about the library.
- After the library has been updated, a new version will need to be created via npm and uploaded as a Github Package. Instructions can be found on the Common package page.
- Do not install the package into the Angular app yet (e.g. SNODAS, Infomapper), as
it seems
ng update
still runs into a bug if private repos are being used. The error showed404 Not Found - GET https://npm.pkg.github.com/OpenWaterFoundation/@angular%2fcli - Package [@angular/cli] was not found
. It was looking for @angular/cli in the OWF Github package instead of the main npm registry. Removing the previous common package resolves this issue. - Perform the update for the app via the Angular Updater.
jQuery - Leaves weird, extremely vague error message such as TypeError: (dl | Al | ol) is not a function. This Stack Overflow question has the way to deal with the issue.
Contributions can be made via normal Git/GitHub protocols:
- Those with commit permissions can make changes to the repository.
- Use GitHub Issues to suggest changes (preferred for small changes).
- Fork the repository and use pull requests. Any pull requests should be based on current master branch contents.
The AngularDev application and libraries are maintained by the Open Water Foundation.
The AngularDev and library code are licensed under the GPL v3+ license. See the GPL v3 license.