mirror of
https://github.com/WowUp/WowUp.git
synced 2026-06-20 11:38:59 -04:00
Use material menu for column visibility
This commit is contained in:
@@ -1,19 +0,0 @@
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<div class="icon" [style.backgroundImage]="'url(' + addon.thumbnailUrl + ')'"></div>
|
||||
<div>
|
||||
<p>{{addon.name}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
<div style="visibility: hidden; position: fixed" [style.left]="xPos"
|
||||
[style.top]="yPos" [matMenuTriggerFor]="contextMenu">
|
||||
</div>
|
||||
<mat-menu #contextMenu="matMenu">
|
||||
<ng-template matMenuContent let-addon="addon">
|
||||
<div>{{addon.name}}</div>
|
||||
<button mat-menu-item (click)="onContextMenuAction1(item)">Action 1</button>
|
||||
<button mat-menu-item (click)="onContextMenuAction2(item)">Action 2</button>
|
||||
</ng-template>
|
||||
</mat-menu>
|
||||
</div>
|
||||
@@ -1,26 +0,0 @@
|
||||
@import "../../../variables.scss";
|
||||
|
||||
.container {
|
||||
padding: 0.5em;
|
||||
background-color: $dark-4;
|
||||
color: $white-1;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-bottom: 0.5em;
|
||||
|
||||
.icon {
|
||||
background-color: $dark-2;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-right: 0.5em;
|
||||
background-size: contain;
|
||||
background-repeat: none;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AddonContextMenuComponent } from './addon-context-menu.component';
|
||||
|
||||
describe('AddonContextMenuComponent', () => {
|
||||
let component: AddonContextMenuComponent;
|
||||
let fixture: ComponentFixture<AddonContextMenuComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ AddonContextMenuComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AddonContextMenuComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,28 +0,0 @@
|
||||
import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatMenuTrigger } from '@angular/material/menu';
|
||||
import { MyAddonsListItem } from 'app/business-objects/my-addons-list-item';
|
||||
import { Addon } from 'app/entities/addon';
|
||||
|
||||
@Component({
|
||||
selector: 'app-addon-context-menu',
|
||||
templateUrl: './addon-context-menu.component.html',
|
||||
styleUrls: ['./addon-context-menu.component.scss']
|
||||
})
|
||||
export class AddonContextMenuComponent implements OnInit, AfterViewInit {
|
||||
@Input('addon') addon: MyAddonsListItem;
|
||||
@Input('xPos') xPos: number;
|
||||
@Input('yPos') yPos: number;
|
||||
|
||||
@ViewChild(MatMenuTrigger) contextMenu: MatMenuTrigger;
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
console.log(this.contextMenu);
|
||||
this.contextMenu.openMenu();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,4 +2,5 @@ export interface ColumnState {
|
||||
name: string;
|
||||
display: string;
|
||||
visible: boolean;
|
||||
allowToggle?: boolean;
|
||||
}
|
||||
@@ -18,7 +18,6 @@ import { PotentialAddonTableColumnComponent } from 'app/components/potential-add
|
||||
import { PotentialAddonStatusColumnComponent } from 'app/components/potential-addon-status-column/potential-addon-status-column.component';
|
||||
import { MyAddonsAddonCellComponent } from 'app/components/my-addons-addon-cell/my-addons-addon-cell.component';
|
||||
import { MyAddonsStatusCellComponent } from 'app/components/my-addons-status-cell/my-addons-status-cell.component';
|
||||
import { AddonContextMenuComponent } from 'app/components/addon-context-menu/addon-context-menu.component';
|
||||
import { ProgressSpinnerComponent } from 'app/components/progress-spinner/progress-spinner.component';
|
||||
import { DownloadCountPipe } from 'app/pipes/download-count.pipe';
|
||||
import { TelemetryDialogComponent } from 'app/components/telemetry-dialog/telemetry-dialog.component';
|
||||
@@ -33,7 +32,6 @@ import { TelemetryDialogComponent } from 'app/components/telemetry-dialog/teleme
|
||||
ExternalLinkDirective,
|
||||
MyAddonsAddonCellComponent,
|
||||
MyAddonsStatusCellComponent,
|
||||
AddonContextMenuComponent,
|
||||
PotentialAddonStatusColumnComponent,
|
||||
ProgressSpinnerComponent,
|
||||
PotentialAddonTableColumnComponent,
|
||||
|
||||
@@ -38,12 +38,14 @@
|
||||
<th mat-header-cell *matHeaderCellDef> Status </th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<div class="status-column">
|
||||
<mat-icon *ngIf="element.addon.autoUpdateEnabled" class="auto-update-icon" matTooltip="Auto update enabled">update</mat-icon>
|
||||
<mat-icon *ngIf="element.addon.autoUpdateEnabled" class="auto-update-icon" matTooltip="Auto update enabled">
|
||||
update</mat-icon>
|
||||
<button *ngIf="element.needsInstall === true" mat-flat-button color="primary"
|
||||
(click)="onInstall()">Install</button>
|
||||
<button *ngIf="element.needsUpdate === true" mat-flat-button color="primary"
|
||||
(click)="onUpdateAddon(element)">Update</button>
|
||||
<div *ngIf="element.isUpToDate === true || element.isIgnored === true" class="status-text">{{element.statusText}}</div>
|
||||
<div *ngIf="element.isUpToDate === true || element.isIgnored === true" class="status-text">
|
||||
{{element.statusText}}</div>
|
||||
<div *ngIf="element.isInstalling === true" class="progress-container">
|
||||
<p class="progress-text">{{element.statusText}}</p>
|
||||
<mat-progress-bar class="addon-progress" mode="determinate" [value]="element.installProgress">
|
||||
@@ -89,19 +91,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #columnMenu let-user>
|
||||
<section class="column-menu bg-dark-4">
|
||||
<p>Visible Columns</p>
|
||||
<mat-divider></mat-divider>
|
||||
<div class="d-flex" *ngFor="let column of columns">
|
||||
<mat-checkbox class="example-margin" [checked]="column.visible" (change)="onColumnVisibleChange($event, column)">
|
||||
{{column.display}}</mat-checkbox>
|
||||
</div>
|
||||
</section>
|
||||
</ng-template>
|
||||
|
||||
<div style="visibility: hidden; position: fixed" [style.left]="contextMenuPosition.x"
|
||||
[style.top]="contextMenuPosition.y" [matMenuTriggerFor]="contextMenu">
|
||||
<div style="visibility: hidden; position: fixed" #addonContextMenuTrigger="matMenuTrigger"
|
||||
[style.left]="contextMenuPosition.x" [style.top]="contextMenuPosition.y" [matMenuTriggerFor]="contextMenu">
|
||||
</div>
|
||||
<mat-menu #contextMenu="matMenu" class="addon-context-menu">
|
||||
<ng-template matMenuContent let-listItem="listItem">
|
||||
@@ -113,9 +104,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
<mat-checkbox class="mat-menu-item" [checked]="listItem.addon.isIgnored" (change)="onClickIgnoreAddon($event, listItem)">Ignore
|
||||
<mat-checkbox class="mat-menu-item" [checked]="listItem.addon.isIgnored"
|
||||
(change)="onClickIgnoreAddon($event, listItem)">Ignore
|
||||
</mat-checkbox>
|
||||
<mat-checkbox *ngIf="listItem.addon.isIgnored === false" class="mat-menu-item" [checked]="listItem.addon.autoUpdateEnabled" (change)="onClickAutoUpdateAddon($event, listItem.addon)">Auto
|
||||
<mat-checkbox *ngIf="listItem.addon.isIgnored === false" class="mat-menu-item"
|
||||
[checked]="listItem.addon.autoUpdateEnabled" (change)="onClickAutoUpdateAddon($event, listItem.addon)">Auto
|
||||
Update
|
||||
</mat-checkbox>
|
||||
<button mat-menu-item [matMenuTriggerFor]="addonChannels">Channel</button>
|
||||
@@ -133,8 +126,18 @@
|
||||
</ng-template>
|
||||
</mat-menu>
|
||||
|
||||
|
||||
<!--
|
||||
<ng-template #addonMenu let-addon>
|
||||
<app-addon-context-menu [addon]="addon"></app-addon-context-menu>
|
||||
</ng-template> -->
|
||||
<div style="visibility: hidden; position: fixed" #columnContextMenuTrigger="matMenuTrigger"
|
||||
[style.left]="contextMenuPosition.x" [style.top]="contextMenuPosition.y" [matMenuTriggerFor]="columnContextMenu">
|
||||
</div>
|
||||
<mat-menu #columnContextMenu="matMenu" class="addon-context-menu">
|
||||
<ng-template matMenuContent let-columns="columns">
|
||||
<div class="addon-context-menu-header">
|
||||
<div class="addon-name">Show Columns</div>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
<mat-checkbox *ngFor="let column of columns" class="mat-menu-item" [checked]="column.visible"
|
||||
(change)="onColumnVisibleChange($event, column)">
|
||||
{{column.display}}
|
||||
</mat-checkbox>
|
||||
</ng-template>
|
||||
</mat-menu>
|
||||
@@ -8,7 +8,6 @@ import { AddonService } from 'app/services/addons/addon.service';
|
||||
import { SessionService } from 'app/services/session/session.service';
|
||||
import { GridApi, GridOptions } from 'ag-grid-community';
|
||||
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
|
||||
import { TemplatePortal } from '@angular/cdk/portal';
|
||||
import { ColumnState } from 'app/models/wowup/column-state';
|
||||
import { MatCheckboxChange } from '@angular/material/checkbox';
|
||||
import { MyAddonsListItem } from 'app/business-objects/my-addons-list-item';
|
||||
@@ -26,10 +25,8 @@ import { MatRadioChange } from '@angular/material/radio';
|
||||
})
|
||||
export class MyAddonsComponent implements OnInit, OnDestroy {
|
||||
|
||||
@ViewChild('columnMenu') columnMenu: TemplateRef<any>;
|
||||
@ViewChild('addonMenu') addonMenu: TemplateRef<any>;
|
||||
@ViewChild(MatMenuTrigger)
|
||||
contextMenu: MatMenuTrigger;
|
||||
@ViewChild('addonContextMenuTrigger') contextMenu: MatMenuTrigger;
|
||||
@ViewChild('columnContextMenuTrigger') columnContextMenu: MatMenuTrigger;
|
||||
|
||||
private readonly _displayAddonsSrc = new BehaviorSubject<MyAddonsListItem[]>([]);
|
||||
|
||||
@@ -39,24 +36,13 @@ export class MyAddonsComponent implements OnInit, OnDestroy {
|
||||
|
||||
contextMenuPosition = { x: '0px', y: '0px' };
|
||||
|
||||
gridOptions: GridOptions = {
|
||||
suppressMovableColumns: true,
|
||||
suppressDragLeaveHidesColumns: true,
|
||||
}
|
||||
|
||||
defaultColDef = {
|
||||
wrapText: true,
|
||||
sortable: true,
|
||||
autoHeight: true,
|
||||
};
|
||||
|
||||
columns: ColumnState[] = [
|
||||
{ name: 'addon', display: 'Addon', visible: true },
|
||||
{ name: 'status', display: 'Status', visible: true },
|
||||
{ name: 'latestVersion', display: 'Latest Version', visible: true },
|
||||
{ name: 'gameVersion', display: 'Game Version', visible: true },
|
||||
{ name: 'provider', display: 'Provider', visible: true },
|
||||
{ name: 'author', display: 'Author', visible: true },
|
||||
{ name: 'latestVersion', display: 'Latest Version', visible: true, allowToggle: true },
|
||||
{ name: 'gameVersion', display: 'Game Version', visible: true, allowToggle: true },
|
||||
{ name: 'provider', display: 'Provider', visible: true, allowToggle: true },
|
||||
{ name: 'author', display: 'Author', visible: true, allowToggle: true },
|
||||
]
|
||||
|
||||
public get displayedColumns(): string[] {
|
||||
@@ -142,20 +128,22 @@ export class MyAddonsComponent implements OnInit, OnDestroy {
|
||||
this.enableControls = true;
|
||||
}
|
||||
|
||||
onHeaderContext({ x, y }: MouseEvent) {
|
||||
this.showContextMenu(x, y, this.columnMenu, this.displayedColumns);
|
||||
onHeaderContext(event: MouseEvent) {
|
||||
event.preventDefault();
|
||||
this.contextMenuPosition.x = event.clientX + 'px';
|
||||
this.contextMenuPosition.y = event.clientY + 'px';
|
||||
this.columnContextMenu.menuData = { 'columns': this.columns.filter(col => col.allowToggle) };
|
||||
this.columnContextMenu.menu.focusFirstItem('mouse');
|
||||
this.columnContextMenu.openMenu();
|
||||
}
|
||||
|
||||
onCellContext(event: MouseEvent, listItem: MyAddonsListItem) {
|
||||
console.log(listItem)
|
||||
event.preventDefault();
|
||||
this.contextMenuPosition.x = event.clientX + 'px';
|
||||
this.contextMenuPosition.y = event.clientY + 'px';
|
||||
this.contextMenu.menuData = { 'listItem': listItem };
|
||||
this.contextMenu.menu.focusFirstItem('mouse');
|
||||
this.contextMenu.openMenu();
|
||||
|
||||
// this.showContextMenu(event.x, event.y, this.addonMenu, addon);
|
||||
}
|
||||
|
||||
onUpdateAddon(listItem: MyAddonsListItem) {
|
||||
@@ -185,7 +173,7 @@ export class MyAddonsComponent implements OnInit, OnDestroy {
|
||||
this.addonService.saveAddon(listItem.addon);
|
||||
}
|
||||
|
||||
onClickAutoUpdateAddon(evt: MatCheckboxChange, addon: Addon){
|
||||
onClickAutoUpdateAddon(evt: MatCheckboxChange, addon: Addon) {
|
||||
addon.autoUpdateEnabled = evt.checked;
|
||||
this.addonService.saveAddon(addon);
|
||||
}
|
||||
@@ -195,61 +183,6 @@ export class MyAddonsComponent implements OnInit, OnDestroy {
|
||||
this.addonService.saveAddon(addon);
|
||||
}
|
||||
|
||||
onGridReady(params) {
|
||||
this.gridApi = params.api;
|
||||
this.gridApi.sizeColumnsToFit();
|
||||
|
||||
// simple resize debouncer
|
||||
let resizeTime = 0;
|
||||
this.gridApi.addEventListener('columnResized', () => {
|
||||
clearTimeout(resizeTime);
|
||||
resizeTime = window.setTimeout(() => {
|
||||
this.gridApi?.resetRowHeights();
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
|
||||
private showContextMenu(x: number, y: number, template: TemplateRef<any>, data: any) {
|
||||
this.closeContext();
|
||||
|
||||
const positionStrategy = this.overlay.position()
|
||||
.flexibleConnectedTo({ x, y })
|
||||
.withPositions([
|
||||
{
|
||||
originX: 'end',
|
||||
originY: 'bottom',
|
||||
overlayX: 'end',
|
||||
overlayY: 'top',
|
||||
}
|
||||
]);
|
||||
|
||||
this.overlayRef = this.overlay.create({
|
||||
positionStrategy,
|
||||
scrollStrategy: this.overlay.scrollStrategies.close()
|
||||
});
|
||||
|
||||
this.overlayRef.attach(new TemplatePortal(template, this.viewContainerRef, {
|
||||
$implicit: data
|
||||
}));
|
||||
|
||||
this.sub = fromEvent<MouseEvent>(document, 'click')
|
||||
.pipe(
|
||||
filter(event => {
|
||||
const clickTarget = event.target as HTMLElement;
|
||||
return !!this.overlayRef && !this.overlayRef.overlayElement.contains(clickTarget);
|
||||
}),
|
||||
take(1)
|
||||
).subscribe(() => this.closeContext())
|
||||
}
|
||||
|
||||
private closeContext() {
|
||||
this.sub && this.sub.unsubscribe();
|
||||
if (this.overlayRef) {
|
||||
this.overlayRef.dispose();
|
||||
this.overlayRef = null;
|
||||
}
|
||||
}
|
||||
|
||||
private loadAddons(clientType: WowClientType, rescan = false) {
|
||||
this.isBusy = true;
|
||||
this.enableControls = false;
|
||||
|
||||
Reference in New Issue
Block a user