gridstack / gridstack.js

Build interactive dashboards in minutes.
https://gridstackjs.com
MIT License
6.69k stars 1.28k forks source link

Change disableResize and disableDrag on Angular on user interaction #2654

Closed mcrodriguezb closed 6 months ago

mcrodriguezb commented 6 months ago

Subject of the issue

I'm trying to update the grid options in angular. First I create a grid with the disableDrag and disableResize options set to true. Then I want to change the options so that the grid will be draggable and resizable. This is the same as https://github.com/gridstack/gridstack.js/issues/898, but now in angular.

This is the same as https://github.com/gridstack/gridstack.js/issues/2653, but after closing it with solution use static: true to start, then call grid.setStatic(false) to enable editing...

I posted two comments on the original post, but issue couldn't be reopen and I expected to notification was sent to the maintaner. The proposed solution is demoed at https://gridstackjs.com/demo/static.html# but using javascript and now angular.

IMPORTANT: My issue is related to Angular wrapper, and in order to implement the proposed solution I need to use grid, which I wasn't able to get using the wrapper.

Your environment

Steps to reproduce

In the demo click the button and it should allow to resize/drag grid items. https://stackblitz.com/edit/stackblitz-starters-ep5dpv

Expected behavior

Allow to resize and drag items when in edit mode.

Thanks again, and please, let me close the issue after having a working solution.

adumesny commented 6 months ago

please stop filling multiple 'bugs' and ask those question to slack channel instead... you always access the gridstack to make API call, irrelevant to the angualr wrapper. my prev answer is still correct.

GITOffMuhLawn commented 5 months ago

Or you could answer the question in a clear an concise way because the user isn't the only one trying to do the same thing and it's a joke when you have to comb through git, then something else, then something else to get the answer. The answer doesn't make sense for the angular wrapper.

adumesny commented 5 months ago

or you could pay to get my free time... the nerve people have for a free open source and expecting answers...

GITOffMuhLawn commented 5 months ago

It's the general attitude of the open source community being like this, and then everyone is shocked pikachu face when open source doesn't end up being viable because it's overly complicated to use (read: the documentation is shitty) and the people owning it refuse to answer a question about it. This is why people drop seven figures on servicenow over open source, which even I've been able to make CRUD app where you build the entire thing by just using a SPA front end with a huge performance improvement over SNOW. I no shit ported SNOW's IRM to React and I'm porting it to angular now because of React's licensing being kind of sketch.
When people are asking you how to use the thing that you keep telling them to use and nobody seems to be able to figure it out... yeah how dare there... There's at least two bugs on this and people posting in slack and the response is "just use the angular wrapper." I actually do pay/donate to open source projects I use. Dynamically changing static where grids are in multiple components (and hidden at times) doesn't work. This is why the opensource community never moves forward with products that take off aside from things put out by big tech because the humility of those involved with the projects is almost non-existent. It's "keeper of the badge" mentality, which by and large really is just insecurity because they don't have answers for basic use cases that are common sense or can't answer questions so they get defensive.

This is a bug.

A button on parent component A that toggles "editMode" on this service: // edit-mode.service.ts import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs';

@Injectable({ providedIn: 'root' }) export class EditModeService { public editModeSubject = new BehaviorSubject(false); editMode$ = this.editModeSubject.asObservable();

toggleEditMode() { const currentEditMode = this.editModeSubject.getValue(); const newEditMode = !currentEditMode; this.editModeSubject.next(newEditMode); return newEditMode; } }

There is a 1:many between component A and Comp B. there are 1-n Comp B's, with only one shown at a time and the others hidden using [hidden] with logic based on a flag set at component A. There are way more things than need/should be in component B to try this, but I included the extras just because.

Component B .TS: import {Component, Input, OnChanges, OnInit, OnDestroy, ChangeDetectorRef} from '@angular/core'; import {EditModeService} from '../../services/editMode.service'; import { GridStack, GridStackOptions, GridStackWidget } from 'gridstack'; import { NgGridStackOptions, GridstackComponent, gsCreateNgComponents, NgGridStackWidget, nodesCB, BaseWidget } from 'gridstack/dist/angular'; import 'gridstack/dist/gridstack.min.css'; import { BehaviorSubject, Subscription} from 'rxjs';

@Component({ selector: 'tabComp', templateUrl: './tabComp.html', styleUrls: [ '../../CSS/GRC.css', '../../CSS/GridStack.css' ] })

export class TabComp { constructor( private cdr: ChangeDetectorRef, public editModeService: EditModeService ) {

}

@Input() tabIndex: any;
isStatic = new BehaviorSubject<boolean>(true);
public isComponentVisible: boolean = true;

testStatic!: boolean

staticSub = new Subscription();

public gridOptions: GridStackOptions = {
    margin: 5,
    minRow: 40,
    disableDrag: /*shooters preference how you want to try and do it dynamically here, either this.editMode.getValue(), or this.getStatic(), or this.isStatic.getValue().... and yes those values do get updated because in the html you see the values displayed swap between true/false.  Whatever is set at load persists.  If I have to tear the component down just to get the settings to change dynamically it's just easier to use angular cdk */

  }

  items: GridStackWidget[] = [
    {id: '1', x: 0, y: 0, w: 2, h: 2}
  ]

  public identify(index: number, w: GridStackWidget) {
    return w.id; // or use index if no id is set and you only modify at the end...
  }

  editMode = new BehaviorSubject<boolean>(false);
  //editMode: boolean = false;
  editModeSub = new Subscription();

  ngOnInit() {
    console.log("ngonInit for tabcomp: ", this.tabIndex);
    this.staticSub.add(this.isStatic.subscribe(() => this.handleStaticChange()));
    this.editModeService.editMode$.subscribe(value => {
      this.editMode.next(value);
    })

    this.editModeSub.add(this.editMode.subscribe(() => this.handleEditChange()));

    this.editModeService.editMode$.subscribe(value => {
      this.testStatic = value;
    })
  }

  getStatic() {
    return this.isStatic.getValue();
  }

  handleEditChange() {
    console.log('handleEditChange called');
    this.setStatic();
  }

  handleStaticChange() {

    console.log('handleStaticchange called for tabcomp: ', this.tabIndex);
    if (this.isComponentVisible) {
      this.updateView();
    }
  }

  updateView() {
    this.cdr.detectChanges();
  }

  setStatic() {
    console.log("current static: ", this.isStatic.getValue())
    let currentVal = this.isStatic.getValue()
    this.isStatic.next(!currentVal);
    console.log('new static: ', this.isStatic.getValue());
  }

  onVisibilityChange(isVisible: boolean) {
    this.isComponentVisible = isVisible;
    if (isVisible) {
      this.updateView()
    }
  }

  ngOnChanges() {
    console.log("change for tabComp: ", this.tabIndex)
  }

}

Component B HTML: <button (click)="setStatic()">print static <gridstack [options]="gridOptions"> <gridstack-item *ngFor="let item of items; trackBy: identify" [options]="item"> {{item.id}}, editMode: {{this.editMode.getValue()}}, testStatic: {{this.testStatic}}