Updating the table configuration and data

Learn how to update the table configuration and data after the form has been submitted. In this lesson, you ensure that the form works correctly and prepare to populate data from REST APIs.

Procedure

  1. Submit the form:
    1. Go to the Create reservation page and input and submit a reservation. For example:
      Create reservation
    2. After you submit the form, you should see the following message:
      Submit
  2. In a terminal, go to the src-custom/app/features/create-reservation directory.
  3. Run the following command to generate a table for users to view and update the reservation values.
    This command uses the IBM code generation scripts that are included in the developer toolkit.
    ng g @buc/schematics:table-component \
    --name create-reservation \
    --extend ClientSidePaginationBaseTableComponent \
    --path packages/inventory-search-results/src-custom/app/features/create-reservation \
    --json-file-path packages/inventory-search-results/src-custom/assets/custom \
    --translation-file-path packages/inventory-search-results/src-custom/assets/custom/i18n
    • --name <table name>,
    • --path <path to where you want to create the table>
    • --json-file-path <path to buc-table-config.json where table configuration will be added>
    • --translation-file-path <path to the custom translation JSON file>
    • --extend <extendable table class name>
    For help with the schematic script, run
    ng g @buc/schematics:table-component --help
  4. After running the script, new files are created in the location that you specified, and the ext-search-module.ts file is updated with a new component, CreateReservationTableComponent.
  5. Since the custom component that you generated (CreateReservationTableComponent) needs to use IBM utilities and libraries, move the component to the app-customization.impl.ts file by completing the following steps.
    1. Edit the src-custom/app/features/ext-search.module.ts file with the following changes.
      • Delete the import {CreateReservationTableComponent} statement.
      • Delete CreateReservationTableComponent from the declarations array.
      The resulting code looks like this:
      import { NgModule } from '@angular/core';
      import { CommonModule } from '@angular/common';
      
      @NgModule({
        declarations: [
        ],
        imports: [
          CommonModule
        ]
      })
      export class ExtSearchModule { }
    2. Update the src-custom/app/app-customization.impl.ts file with the following changes.
      • Add the following import statement.
        import { CreateReservationTableComponent } from './features/create-reservation/create-reservation-table/create-reservation-table.component';
      • Add CreateReservationTableComponent to the components array.
        static readonly components = [CreateReservationComponent, CreateReservationTableComponent];
        
      After the module compiles successfully, a new entry create-reservation-table is added in the src-custom/assets/custom/buc-table-config.json file.
  6. Open the src-custom/app/features/create-reservation/create-reservation-table/create-reservation-table.component.ts file and find the selector value.
    In this case, the value is buc-create-reservation-table. You must use this value in the HTML to display the table.
  7. Add the following code to the src-custom/app/features/create-reservation/create-reservation.component.html file after the comment <!–Reservation table -->.
    <buc-create-reservation-table [parentPage]="this"></buc-create-reservation-table>
  8. Go back to Order Hub and reload frame.
    Go to the Create reservation page to verify that the table is displayed.
    Screen capture of the Create reservation page with an input box and table.
  9. Notice that the header includes a checkbox. To remove the checkbox, complete the following steps.
    1. Open the src-custom/app/features/create-reservation/create-reservation-table/create-reservation-table.component.html file.
    2. Add the following code to the end of the <buc-table> element.
      [showSelectionColumn]="false"
      Screen capture of the create-reservation-table-component.html with the showSelectionColumn property
  10. Open the packages/inventory-search-results/src-custom/assets/custom/buc-table-config.json file.
  11. Replace the create-reservation-table's headers array with the following code to update the table header strings.
            {
                "name": "Node id",
                "id": "nodeId",
                "sortKey": "nodeId",
                "dataBinding": "shipNode"
             },
             {
              "name": "Available On hand",
              "id": "availableOnHand",
              "sortKey": "availableOnHand",
              "dataBinding": "reservedQuantity"
             },
             {
                "name": "Reserved Total",
                "id": "totalReservedQty",
                "sortKey": "totalReservedQty",
                "dataBinding": "reservedQuantity"
             }
    After you replace the headers, ensure that the code looks like the following snippet.
    Screen capture of the buc-table-config.json
  12. Update the Table Headers section in the create-reservation-table.component.ts file.
    Notice that the IDs match with the buc-table-config.json values for this table.
    /* Table Headers */
      public readonly TABLE_HEADERS: any = {
        TH_NODE_ID: 'nodeId',
        TH_AVLBL_ON_HAND: 'availableOnHand',
        TH_TOTAL_RESRV: 'totalReservedQty'
      };
    
  13. Edit the src-custom/app/features/create-reservation/create-reservation-table/create-reservation-table.component.ts file with the following changes.
    1. To populate the table with data, you can use the query parameters from the buc-table-config.json and some variables that Order Hub stores in context.
      Add the InventoryContextService and InventoryAvailabilityService as constructor parameters.
      private ctx: InventoryContextService,
      private invAvlSvc: InventoryAvailabilityService,
      private reservationService: CreateReservationService
    2. Add the tenant ID, import statement, and code:
      1. Add the following variable to the CreateReservationTableComponent class. This variable is used in the API call.
        public tenantId;
      2. Add the following code to the ngOninit() method to populate the tenantId:
        this.tenantId =
        BucSvcAngularStaticAppInfoFacadeUtil.getInventoryTenantId();
      3. Add the corresponding import statement:
        import { BucSvcAngularStaticAppInfoFacadeUtil } from '@buc/svc-angular';
      4. Add the following code:
        getInventoryAvailabilityBreakup() {
        	const searchCriteria = this.ctx.getSearchCriteria();
        	const item = (this.reservationService.itemData?.itemId) ? [this.reservationService.itemData.itemId] : [''];
        	const nodes = searchCriteria.filterCriteria.nodes;
        	this.parentPage.nodesIds = nodes;
        	const data = [];
        	return this.invAvlSvc.getAvailabilityBreakupInventory(item, nodes,
        		[], [searchCriteria.operators.uom.value],
        		[searchCriteria.operators.pc.value], searchCriteria.filterCriteria,
        		searchCriteria.operators.org.value, '').pipe(
        		map((response: InventoryBreakupResponse) => {
        			response.nodes.forEach(el => {
        				const colD = {
        					breakup: {},
        					itemId: '',
        					availableOnHand: '',
        					nodeId: '',
        					totalReservedQuantity: ''
        				};
        				colD.breakup = el.breakup;
        				colD.availableOnHand = response.summary?.availToSell;
        				colD.nodeId = el.nodeId;
        				colD.totalReservedQuantity = el.breakup.totalReservedQuantity;
        				data.push(colD);
        			});
        			return data;
        		}),
        		catchError(() => {
        			this.multiModel.totalDataLength = 0;
        			return [];
        		})
        	);
        }
        getReservation() {
        	return this.reservationService.getReservation(this.tenantId,
        		this.reservationService.reservationRef).pipe(
        		catchError(() => {
        			this.multiModel.totalDataLength = 0;
        			return [];
        		})
        	);
        }
    3. Prepare the table to get the data from APIs:
      1. Replace the fetchTableData() method with the following code to call getReservation and getInventoryAvailabilityBreakup:
        protected fetchTableData(): Observable < any[] > {
        	const observables = [];
        	observables.push(this.getReservation());
        	observables.push(this.getInventoryAvailabilityBreakup());
        	return forkJoin(observables).pipe(map((res) => {
        		const reservationResp: any = res[0];
        		const nodebrkUp: any = res[1];
        		const rows = reservationResp.map((item: any) => ({
        			shipNode: item.shipNode,
        			reservedQuantity: item.reservedQuantity,
        			totalOnhandSupplyQuantity: nodebrkUp.map((data) => data.nodeId ===
        				item.shipNode ? data.breakup.totalOnhandSupplyQuantity[0] : '')
        		}))
        		return rows;
        	}));
        }
      2. To display information in the table, you need to use the existing getAvailabilityBreakupInventory API and getReservation API from the inventory-shared package. Therefore, you need to add the following import statements:
        import { InventoryAvailabilityService, InventoryContextService } from '@buc/inventory-shared';
        import { InventoryBreakupResponse } from '@buc/inventory-shared/lib/services/inventory-availability.service';
        import { CreateReservationService } from "../services/create-reservation.service";
        import { map, catchError } from 'rxjs/operators'; import { forkJoin } from 'rxjs';
    4. Add a handler method to show success or error notifications. Order Hub has services to show notifications.
      1. Add the BucNotificationService as constructor parameter:
        private bucNotificationService: BucNotificationService
      2. Add the showNotification method:
        // notification
        showNotification(statusType, message) {
        	const notification = new BucNotificationModel({
        		statusType,
        		statusContent: message
        	});
        	this.bucNotificationService.send([notification]);
        }
      3. Add the corresponding import statement:
        import { BucNotificationModel, BucNotificationService} from '@buc/common-components';
  14. Add a footer with Cancel and Create options.
    1. Open the src-custom/app/features/create-reservation/create-reservation.component.html file.
    2. Replace the existing <div class="screen-footer"> with the following code.
      <div class="screen-footer">
          <!-- button row -->
        <div class="bx--row">
          <div class="bx--col">
            <buc-button [attr.tid]="'create-rule-cancel'" class="padding-right--1rem" [type]="'secondary'"
                (click)="onCancel()" [btnSize]="'normal'">
                {{ 'custom.LABEL_CANCEL' | translate }}
            </buc-button>
            <buc-button id="saveBtn" [attr.tid]="'create-rule-save'" [type]="'primary'" [btnSize]="'normal'"
                (click)="onSave()">
                {{ 'custom.LABEL_CREATE' | translate }}
            </buc-button>
          </div>
        </div>
      </div>
      
    3. Update the src-custom/assets/custom/i18n/en.json file with translation strings for the Cancel and Create labels.
      "custom": {
      	"LABEL_CREATE_RESERVATION": "Create reservation",
      	"SUCCESS_RESERVATION": "Reservation successful",
      	"ERROR_RESERVATION": "Reservation failed:",
      	"LABEL_CREATE": "Create",
      	"LABEL_CANCEL": "Cancel"
      },
  15. Update the src-custom/app/features/create-reservation/create-reservation.component.ts file to handle the Cancel and Create actions.
    1. In class CreateReservationComponent, declare a new Boolean variable isCancelled.
        public isCancelled: boolean;
    2. In the constructor method, add the Router parameter.
      private router: Router
    3. Add the following methods to handle Cancel and Create actions.
      onCancel() {
      	this.isCancelled = true;
      	this.router.navigate([Constants.RESULTS_ROUTE]);
      }
      onSave() {}
    4. Add the following import statements.
      import { ActivatedRoute, Router } from '@angular/router';
      import { Constants } from '@buc/inventory-shared';
      
  16. Create a service to call the Create reservation API from Sterling Intelligent Promising Inventory Visibility to populate availability data.
    1. Open the src-custom/app/features/create-reservation/services/create-reservation-service.ts file.
      Update the file with the following code to call the Sterling Intelligent Promising Inventory Visibility Get Reservation API:
      getReservation(tenantId, referenceId = 'REF2'): Observable < any > {
      	if (tenantId === undefined || tenantId === null || tenantId === '') {
      		return throwError(new Error('Missing required parameter: tenantId'));
      	}
      	let path = '/{tenant}/v1/reservations?reference={referenceId}';
      	path = path.replace('{tenant}', tenantId).replace('{referenceId}',
      		referenceId);
      	const url = this.domain + path;
      	const obsToReturn$ = this.http.post(url, this.resourceDomain, null,
      		this.options);
      	return obsToReturn$;
      }
  17. If you are subscribed to Global Inventory Visibility, open the src-custom/app/features/create-reservation/create-reservation.component.ts file and add the following code.
    • Add a handler method to show success or error notifications. Order Hub has services to show notifications.
      • Add the BucNotificationService as constructor parameter.
            private bucNotificationService: BucNotificationService
      • Add the showNotification method.
        // notification
          showNotification(statusType, message) {
              const notification = new BucNotificationModel({ statusType, statusContent: message });
              this.bucNotificationService.send([notification]);
          }
        
      • Add the corresponding import statement.
        import { BucNotificationModel, BucNotificationService} from '@buc/common-components';
    • Modify the onSave() method as needed.
      async onSave() {
          // Call GIV API here
              try {
            alert('Call GIV API here');
            this.showNotification('success', this.nlsMap['custom.SUCCESS_RESERVATION']);
            this.router.navigate([Constants.RESULTS_ROUTE]);
          } catch (error) {
            this.showNotification('error', this.nlsMap['custom.ERROR_RESERVATION'] + ' ' + error.error_message);
          }
        }