damanchola
damanchola

Reputation: 15

Gridstack.js with Ngx Spinner, Spinner fullscreen in Component

I'm building a DashBoard with GridStackJs and NgxSpinner to show a screen in each component every time I run a service, but the size of the grid-stack-item-content is too big, because it doesn't occupy the whole screen.

Checking using the relative property I see that it occupies the entire screen but up to a certain size and if I remove the property if it occupies it completely, but if I make the component smaller, the load component does not occupy all the space. Here is an example of the two cases in Stackblitz and some pictures of what happens.

With Relative

Without relative and smaller

Stackblitz Example

Upvotes: 1

Views: 92

Answers (1)

Naren Murali
Naren Murali

Reputation: 56793

Firstly I moved the spinner to the root of the component, since the grid height is irrelevant to the problem.

Then I used HostBinding of angular to set the height of the component based on the height of the grid stack item, for this I use dependency injection to get the parent grid stack height. The -10px is for the parent margin and padding adjustment.

export class Test1Component {
  @HostBinding('style.height')
  get height() {
    console.log(this.gridStack?.el?.getBoundingClientRect());
    const height = this.gridStack?.el?.getBoundingClientRect()?.height;
    return height ? `${height - 10}px !important` : '100% !important';
  }

  constructor(private spinnerService:NgxSpinnerService, 
    private gridStack: GridstackItemComponent){
      console.log(gridStack);
  }

I had to use the below CSS to make the container not have a scrollbar.

:host {
  display: block !important;
  overflow: hidden !important;
}

Full Code:

TS:

import { Component, HostBinding } from '@angular/core';
import { GridstackItemComponent } from 'gridstack/dist/angular';
import { NgxSpinnerModule, NgxSpinnerService } from 'ngx-spinner';
import { PrimengModule } from 'src/app/primeng/primeng.module';

interface Product {
  id?: string;
  code?: string;
  name?: string;
  description?: string;
  price?: number;
  quantity?: number;
  inventoryStatus?: string;
  category?: string;
  image?: string;
  rating?: number;
}

@Component({
  selector: 'app-test1',
  standalone: true,
  imports: [PrimengModule, NgxSpinnerModule],
  templateUrl: './test1.component.html',
  styles: [
    `
    :host {
      display: block !important;
      overflow: hidden !important;
    }
    `
  ],
  styleUrl: './test1.component.css'
})
export class Test1Component {
  @HostBinding('style.height')
  get height() {
    console.log(this.gridStack?.el?.getBoundingClientRect());
    const height = this.gridStack?.el?.getBoundingClientRect()?.height;
    return height ? `${height - 10}px !important` : '100% !important';
  }

  constructor(private spinnerService:NgxSpinnerService, 
    private gridStack: GridstackItemComponent){
      console.log(gridStack);
  }


  products: Product[] = [
    {
      "id": "1000",
      "code": "f230fh0g3",
      "name": "Bamboo Watch",
      "description": "Product Description",
      "image": "bamboo-watch.jpg",
      "price": 65,
      "category": "Accessories",
      "quantity": 24,
      "inventoryStatus": "INSTOCK",
      "rating": 5
    },
    {
      "id": "1001",
      "code": "nvklal433",
      "name": "Black Watch",
      "description": "Product Description",
      "image": "black-watch.jpg",
      "price": 72,
      "category": "Accessories",
      "quantity": 61,
      "inventoryStatus": "OUTOFSTOCK",
      "rating": 4
    },
    {
      "id": "1002",
      "code": "zz21cz3c1",
      "name": "Blue Band",
      "description": "Product Description",
      "image": "blue-band.jpg",
      "price": 79,
      "category": "Fitness",
      "quantity": 2,
      "inventoryStatus": "LOWSTOCK",
      "rating": 3
    },
    {
      "id": "1003",
      "code": "244wgerg2",
      "name": "Blue T-Shirt",
      "description": "Product Description",
      "image": "blue-t-shirt.jpg",
      "price": 29,
      "category": "Clothing",
      "quantity": 25,
      "inventoryStatus": "INSTOCK",
      "rating": 5
    },
    {
      "id": "1004",
      "code": "h456wer53",
      "name": "Bracelet",
      "description": "Product Description",
      "image": "bracelet.jpg",
      "price": 15,
      "category": "Accessories",
      "quantity": 73,
      "inventoryStatus": "INSTOCK",
      "rating": 4
    },
    {
      id: '1012',
      code: '250vm23cc',
      name: 'Green T-Shirt',
      description: 'Product Description',
      image: 'green-t-shirt.jpg',
      price: 49,
      category: 'Clothing',
      quantity: 74,
      inventoryStatus: 'INSTOCK',
      rating: 5
    },
    {
      id: '1013',
      code: 'fldsmn31b',
      name: 'Grey T-Shirt',
      description: 'Product Description',
      image: 'grey-t-shirt.jpg',
      price: 48,
      category: 'Clothing',
      quantity: 0,
      inventoryStatus: 'OUTOFSTOCK',
      rating: 3
    },
    {
      id: '1014',
      code: 'waas1x2as',
      name: 'Headphones',
      description: 'Product Description',
      image: 'headphones.jpg',
      price: 175,
      category: 'Electronics',
      quantity: 8,
      inventoryStatus: 'LOWSTOCK',
      rating: 5
    },
    {
      id: '1015',
      code: 'vb34btbg5',
      name: 'Light Green T-Shirt',
      description: 'Product Description',
      image: 'light-green-t-shirt.jpg',
      price: 49,
      category: 'Clothing',
      quantity: 34,
      inventoryStatus: 'INSTOCK',
      rating: 4
    },
    {
      id: '1016',
      code: 'k8l6j58jl',
      name: 'Lime Band',
      description: 'Product Description',
      image: 'lime-band.jpg',
      price: 79,
      category: 'Fitness',
      quantity: 12,
      inventoryStatus: 'INSTOCK',
      rating: 3
    },
    {
      id: '1017',
      code: 'v435nn85n',
      name: 'Mini Speakers',
      description: 'Product Description',
      image: 'mini-speakers.jpg',
      price: 85,
      category: 'Clothing',
      quantity: 42,
      inventoryStatus: 'INSTOCK',
      rating: 4
    },
    {
      id: '1018',
      code: '09zx9c0zc',
      name: 'Painted Phone Case',
      description: 'Product Description',
      image: 'painted-phone-case.jpg',
      price: 56,
      category: 'Accessories',
      quantity: 41,
      inventoryStatus: 'INSTOCK',
      rating: 5
    },
    {
      id: '1019',
      code: 'mnb5mb2m5',
      name: 'Pink Band',
      description: 'Product Description',
      image: 'pink-band.jpg',
      price: 79,
      category: 'Fitness',
      quantity: 63,
      inventoryStatus: 'INSTOCK',
      rating: 4
    },
  ]

  showSpinner(){
    this.spinnerService.show()
    this.hideSpinner()
  }

  hideSpinner(){
    setTimeout(() => {
      this.spinnerService.hide()
    }, 5000000);
  }

}

HTML:

   <div class="relative">
        <p-card>
            <ng-template pTemplate="header">
                <div class="flex justify-content-between flex-wrap">
                    <h1 class="m-4">Test1</h1>
                    <p-button icon="pi pi-times" severity="danger" class="m-4"></p-button>
                </div>
                <hr>
            </ng-template>
    
            <p-button label="RunSpinner" [raised]="true" class="m-2" (click)="showSpinner()"></p-button>
    
            <p-table [value]="products" [tableStyle]="{'min-width': '60rem'}">
                <ng-template pTemplate="header">
                    <tr>
                        <th pSortableColumn="code" style="width:20%">
                            Code <p-sortIcon field="code" />
                        </th>
                        <th pSortableColumn="name" style="width:20%">
                            Name <p-sortIcon field="name" />
                        </th>
                        <th pSortableColumn="category" style="width:20%">
                            Category <p-sortIcon field="category" />
                        </th>
                        <th pSortableColumn="quantity" style="width:20%">
                            Quantity <p-sortIcon field="quantity" />
                        </th>
                    </tr>
                </ng-template>
                <ng-template pTemplate="body" let-product>
                    <tr>
                        <td>{{ product.code }}</td>
                        <td>{{ product.name }}</td>
                        <td>{{ product.category }}</td>
                        <td>{{ product.quantity }}</td>
                    </tr>
                </ng-template>
            </p-table>
        </p-card>
    </div>
    <ngx-spinner type="ball-scale-multiple" [fullScreen]="false" [zIndex]="0"></ngx-spinner>

Upvotes: 0

Related Questions