usnistgov / oar-pdr

The NIST Open Access to Research (OAR) Public Data Repository (PDR) system software
11 stars 10 forks source link

Angular/Typescript Code Conventions #169

Open RayPlante opened 3 years ago

RayPlante commented 3 years ago

We are currently in the process of putting into place stricter code style conventions for our Java code, so it is appropriate that we start setting down similar conventions for our Typescript code. This issue is for proposing a set of such conventions.

This proposal assumes these policies build on the conventions set out for Angular projects (e.g. file naming conventions, class naming conventions, etc.). Exceptions to conventions are expected (but rare) to improve readability.

Spacing

Indentation and Line Length

  1. Standard indentation is 4 spaces; indentation must not include TAB (Ctrl-I) characters.
  2. Avoid statements longer than 120 characters. Longer statements should be either continued onto another line with line-breaks that optimize readability or otherwise broken into multiple, shorter statements.
  3. The last character of a source file should be a new-line (i.e. "return") character.

Classes, Functions, and Decorators

  1. Each decorator of a class, function, or variable (e.g. @Component({...) should begin on a new line.
  2. Decorators should be considered conceptually part of signature line they decorate: there should be no blank line between a decorator block and it class of function signature.
  3. When a decorator includes with an object argument (e.g. {...}), each property of the object should appear on a separate line and be indented by the standard amount (4); the closing object brace ({) and parenthesis (() should appear on its own line.

This example illustrates the above three recommendations:

@Component({
    moduleId: module.id,
    selector: 'pdr-headbar',
    templateUrl: 'headbar.component.html',
    styleUrls: ['headbar.component.css']
})
export class HeadbarComponent {
  1. When a function signature fits on one line, the opening brace ({) should appear on the same line as the signature. In this case, it is recommended that a blank line be inserted after after the brace and before the first line of the body for better readability.
  2. When a function signature does not fit on a single line:
    • continue signature on multiple lines, breaking after the comma following an argument
    • subsequent argument lines should be indented to the column that the first argument appears in.
    • the closing function parenthesis should appear on the same line as the last argument
    • the opening function body brace should appear on its own line, aligned with the start of the function signature.
    • the return type may appear on the same line as the last argument or on its own line; in the latter case, it should be indented four spaces from the start of the function signature

Multi-line function signature:

    public setDownloadStatus(resid: string, filePath: string, 
                             downloadedStatus: string = "downloaded") : boolean 
    {
        this.restore();
  1. When a class signature fits on one line, the opening brace should appear on the same line as the signature. In this case, it is recommended that a blank line be inserted after after the brace and before the first line of the body for better readability.

Comments and Documentation

The term "in-line documentation" here is intended to to refer to comment blocks that could be extracted and converted into human-readable API documentation (like with javadoc for Java code). We do not currently use a documentation extractor with our Typescript code; however, we may in the future. Nevertheless, extractable documentation markup is on can be highly readable and provides conventions for indicating what is being described.

  1. In-line class, interface, function, and variable documentation should follow the Java in-line documentation conventions, using /** ... */ comment blocks.
  2. In-line class, interface, function, and variable documentation should appear immediately above both the signature and any decorators; the comment opener, /**, should be indented to align with the start of the class, interface, function, or variable.

This example illustrates the above two recommendations:

/**
 * a data structure describing a file in the cart.  A CartEntryData object, in effect, is a NerdmComp 
 * that *must* have the filePath property and is expected to have some additional 
 * data cart-specific properties.  
 */
export interface DataCartItem {

    /**
     * a local identifier for resource.  This must not start with an underscore as this is reserved.  
     */
    resId? : string;
  1. In-line function documentation is recommended for any function marked with the public modifier.
  2. In-line class documentation is recommended for any exported class, interface or function.
  3. In-line variable documentation is recommended for properties of an exported interface.
  4. In-line class documentation is highly recommended for any exported component class (i.e., marked with the @Component decorator). It should briefly summarize what visually appears in the component when it is rendered.

Example Component documentation:

/**
 * A component for displaying access to landing page tools in a menu.
 * 
 * Items include:
 * * links to the different sections of the landing page
 * * links to view or export metadata
 * * information about usage (like Citation information in a pop-up)
 * * links for searching for similar resources
 */
@Component({
    selector: 'tools-menu',
    template: ;tools-menu.html',
    styleUrls: ['./toolmenu.component.css']
})
export class ToolMenuComponent implements OnChanges {
RayPlante commented 3 years ago

@chuanlin2018 Please review this and suggest any changes you'd like to see, but don't attempt to fix any existing code as yet.