Project

General

Profile

Actions

Cleanup #38765

open

mgr/dashboard: front-end form component refactoring

Added by Ernesto Puerta about 5 years ago. Updated about 3 years ago.

Status:
In Progress
Priority:
Normal
Category:
General
Target version:
-
% Done:

0%

Tags:
Backport:
Reviewed:
Affected Versions:
Pull request ID:

Description

Currently 75% of the dashboard code follows the template below, which exhibits a high degree of code duplication. For every back-end resource (pools, RBD images, RGW users, ...):
  • list-component: table-like component exposing the collection of resources (GET /api/<resource>). The table features action buttons to interact with listed resources, which commonly include:
    • create: mapping POST /api/<resource>, routing to a form-component
    • edit: mapping PUT /api/<resource>/<id>, routing to a form-component
    • delete: mapping DELETE /api/<resource>/<id>, it usually loads a different modal component.
  • form-component: 'reactive form' relying on some developed helpers, but mostly duplicating boilerplate code.
  • delete-modal (defined in list-component)

A suggestion for improvement would be to create a base form-component featuring the common layout and basic actions for every component (create, edit, remove). A basic interface for that component could be as follows:

import { Component, Input } from '@angular/core';                                                                                            
import { CdFormGroup } from '../../forms/cd-form-group';                                             
import { ActionLabelsI18n } from '../../constants/app.constants';                                    

@Component({                                                                                         
  selector: 'cd-resource-form',                                                                      
  templateUrl: './resource-form.component.html'                                                      
})                                                                                                   
export class ResourceFormComponent {                                                                 
  @Input() action:string;      //  the main action to perform by this form (Create|Edit|...)                   
  @Input() resource:string;    //  the resource kind ('pool', 'rbd', etc)                             
  @Input() form:FormGroup;     //  the form object                              
  @Input() submit: Function;   //  the onSubmit callback (could be replaced with an Emitter/@Output)                                                     
  @Input() cancelLink: string; //  the link to get back at for the cancel action (easily inferable)                                                                                                  
} 

And

<div class="col-sm-12 col-lg-6">                                                                                                             
  <ng-template>                                                                               
    <form name="form"                                                                                
          class="form-horizontal"                                                                    
          #formDir="ngForm"                                                                          
          [formGroup]="formGroup"                                                                    
          novalidate>                                                                                
      <div class="panel panel-default">                                                              
        <div class="panel-heading">                                                                  
          <h3 class="panel-title">                                                                   
            <span i18n>{{action + ' ' + resource | titlecase}}</span>                                
          </h3>                                                                                      
        </div>                                                                                       

        <div class="panel-body">                                                                     
          <ng-content></ng-content>                                                                  
        </div>                                                                                       

        <div class="panel-footer">                                                                   
          <div class="button-group text-right">                                                      
            <cd-submit-button [form]="formDir"                                                       
                              type="button"                                                          
                              (submitAction)="submit()">                                             
              <span i18n>{{ action + ' ' + resource | titlecase }}</span>                            
            </cd-submit-button>                                                                      
            <button i18n                                                                             
                    type="button"                                                                    
                    class="btn btn-sm btn-default"                                                   
                    [routerLink]="cancelLink">{{actionLabels.CANCEL}}</button>                       
          </div>                                                                                     
        </div>                                                                                       
      </div>                                                                                         
    </form>                                                                                          
  </ng-template>                                                                                     
</div>

A sample use would be:

<cd-resource-form [action]="actions.CREATE" [resource]="resources.POOL" [form]="form" [submit]="submit" cancelLink="/pool">
<!-- Add form controls -->
</cd-resource-form>

This move could be further developed and provide a templated component-list as well, which would remove even more duplication.

Actions #1

Updated by Ernesto Puerta about 5 years ago

  • Description updated (diff)
Actions #3

Updated by Ernesto Puerta about 4 years ago

  • Status changed from New to In Progress
  • Assignee set to Ernesto Puerta
Actions #4

Updated by Ernesto Puerta about 3 years ago

  • Project changed from mgr to Dashboard
  • Category changed from 132 to General
Actions

Also available in: Atom PDF