Closes #2334 - Make column width of AccessID dynamic under Workbasket Access Overview

This commit is contained in:
SebastianRoseneck 2023-07-25 16:50:39 +02:00 committed by holgerhagen
parent 5d1668b958
commit 461408265f
5 changed files with 134 additions and 3 deletions

View File

@ -21,7 +21,7 @@
<thead>
<tr>
<th></th>
<th class="required-header">AccessID</th>
<th taskanaResizableWidth class="required-header test">AccessID</th>
<th class="rotated-th">
<div><span>Select all</span></div>
</th>

View File

@ -16,6 +16,7 @@
}
&__table {
table-layout: auto;
margin-top: 1%;
margin-left: 1%;
margin-right: auto;
@ -31,7 +32,7 @@
}
.rotated-th > div {
width: 100%;
min-width: 40px;
position: relative;
left: 40px;
height: 100%;
@ -55,7 +56,7 @@
}
& td {
width: 40px;
min-width: 40px;
vertical-align: center;
border: 1px solid #dee2e6;
}

View File

@ -0,0 +1,83 @@
import { Component, DebugElement, ElementRef, Renderer2 } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { ResizableWidthDirective } from './resizable-width.directive';
@Component({
template: ` <div taskanaResizableWidth></div>`
})
class TestComponent {}
describe('ResizableDirective', () => {
let fixture: ComponentFixture<TestComponent>;
let inputDebug: DebugElement;
let inputElement: HTMLInputElement;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TestComponent, ResizableWidthDirective]
});
fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
inputDebug = fixture.debugElement.query(By.directive(ResizableWidthDirective));
inputElement = inputDebug.nativeElement;
});
it('should create an instance', () => {
const renderer = fixture.componentRef.injector.get<Renderer2>(Renderer2 as any);
const directive = new ResizableWidthDirective(renderer, new ElementRef(inputElement));
expect(directive).toBeTruthy();
});
it('should handle mouseover', () => {
inputElement.dispatchEvent(new MouseEvent('mouseover'));
expect(document.body.style.cursor).toBe('col-resize');
expect(inputElement.style.userSelect).toBe('none');
});
it('should handle mouseout', () => {
inputElement.dispatchEvent(new MouseEvent('mouseout'));
expect(document.body.style.cursor).toBe('');
expect(inputElement.style.userSelect).toBe('');
});
it('should resize element after mousedown and mousemove', () => {
const startPosition: number = 100;
const endPosition: number = 200;
const mousedownEvent = new MouseEvent('mousedown', { bubbles: true, cancelable: true });
Object.defineProperty(mousedownEvent, 'pageX', { value: startPosition });
inputElement.dispatchEvent(mousedownEvent);
const initialWidth = inputElement.clientWidth;
const mousemoveEvent = new MouseEvent('mousemove', { bubbles: true, cancelable: true });
Object.defineProperty(mousemoveEvent, 'pageX', { value: endPosition });
inputElement.dispatchEvent(mousemoveEvent);
const expectedWidth = initialWidth + (endPosition - startPosition);
expect(inputElement.style.minWidth).toBe(`${expectedWidth}px`);
expect(inputElement.style.width).toBe(`${expectedWidth}px`);
});
it('should not resize element after mouseup', () => {
const startPosition: number = 100;
const endPosition: number = 200;
const mouseupEvent = new MouseEvent('mouseup', { bubbles: true, cancelable: true });
Object.defineProperty(mouseupEvent, 'pageX', { value: startPosition });
inputElement.dispatchEvent(mouseupEvent);
fixture.detectChanges();
const mousemoveEvent = new MouseEvent('mousemove', { bubbles: true, cancelable: true });
Object.defineProperty(mousemoveEvent, 'pageX', { value: endPosition });
inputElement.dispatchEvent(mousemoveEvent);
expect(inputElement.style.minWidth).toBe('');
expect(inputElement.style.width).toBe('');
});
});

View File

@ -0,0 +1,45 @@
import { Directive, HostListener, Renderer2, ElementRef } from '@angular/core';
@Directive({
selector: '[taskanaResizableWidth]'
})
export class ResizableWidthDirective {
private startX: number;
constructor(private renderer: Renderer2, private el: ElementRef) {}
@HostListener('mouseover', ['$event'])
onMouseover() {
this.renderer.setStyle(document.body, 'cursor', 'col-resize');
this.renderer.setStyle(this.el.nativeElement, 'user-select', 'none');
}
@HostListener('mouseout', ['$event'])
onMouseout() {
this.renderer.setStyle(document.body, 'cursor', '');
this.renderer.setStyle(this.el.nativeElement, 'user-select', '');
}
@HostListener('mousedown', ['$event'])
onMousedown(event: MouseEvent) {
this.startX = event.pageX;
}
@HostListener('document:mousemove', ['$event'])
onMousemove(event: MouseEvent) {
if (this.startX) {
const movementX = event.pageX - this.startX;
const newWidth = this.el.nativeElement.clientWidth + movementX;
this.renderer.setStyle(this.el.nativeElement, 'min-width', `${newWidth}px`);
this.renderer.setStyle(this.el.nativeElement, 'width', `${newWidth}px`);
this.startX = event.pageX;
}
}
@HostListener('document:mouseup')
onMouseup() {
this.startX = null;
}
}

View File

@ -60,6 +60,7 @@ import { ObtainMessageService } from './services/obtain-message/obtain-message.s
import { AccessIdsService } from './services/access-ids/access-ids.service';
import { DragAndDropDirective } from './directives/drag-and-drop.directive';
import { GermanTimeFormatPipe } from './pipes/german-time-format.pipe';
import { ResizableWidthDirective } from './directives/resizable-width.directive';
const MODULES = [
CommonModule,
@ -103,6 +104,7 @@ const DECLARATIONS = [
WorkbasketFilterComponent,
TaskFilterComponent,
DragAndDropDirective,
ResizableWidthDirective,
GermanTimeFormatPipe
];