Multi drag & drop almost done
This commit is contained in:
parent
85da632e90
commit
299a557af1
9
src/assets/icons/more-actions.svg
Normal file
9
src/assets/icons/more-actions.svg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg height="20px" version="1.1" viewBox="0 0 20 20" width="20px" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g fill="none" fill-rule="evenodd" id="more-actions" stroke="none" stroke-width="1">
|
||||||
|
<polygon id="Shape" points="0 0 20 0 20 20 0 20"></polygon>
|
||||||
|
<path
|
||||||
|
d="M4,8 C2.9,8 2,8.9 2,10 C2,11.1 2.9,12 4,12 C5.1,12 6,11.1 6,10 C6,8.9 5.1,8 4,8 L4,8 Z M16,8 C14.9,8 14,8.9 14,10 C14,11.1 14.9,12 16,12 C17.1,12 18,11.1 18,10 C18,8.9 17.1,8 16,8 L16,8 Z M10,8 C8.9,8 8,8.9 8,10 C8,11.1 8.9,12 10,12 C11.1,12 12,11.1 12,10 C12,8.9 11.1,8 10,8 L10,8 Z"
|
||||||
|
fill="currentColor" id="Shape"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 679 B |
@ -28,6 +28,7 @@ export class IqserIconsModule {
|
|||||||
'list',
|
'list',
|
||||||
'logout',
|
'logout',
|
||||||
'menu',
|
'menu',
|
||||||
|
'more-actions',
|
||||||
'ocr',
|
'ocr',
|
||||||
'offline',
|
'offline',
|
||||||
'pages',
|
'pages',
|
||||||
@ -44,11 +45,7 @@ export class IqserIconsModule {
|
|||||||
'upload',
|
'upload',
|
||||||
]);
|
]);
|
||||||
icons.forEach(icon => {
|
icons.forEach(icon => {
|
||||||
_iconRegistry.addSvgIconInNamespace(
|
_iconRegistry.addSvgIconInNamespace('iqser', icon, _sanitizer.bypassSecurityTrustResourceUrl(`/assets/icons/${icon}.svg`));
|
||||||
'iqser',
|
|
||||||
icon,
|
|
||||||
_sanitizer.bypassSecurityTrustResourceUrl(`/assets/icons/${icon}.svg`),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,23 +14,23 @@ import { combineLatest, Observable } from 'rxjs';
|
|||||||
import { filter, map, tap } from 'rxjs/operators';
|
import { filter, map, tap } from 'rxjs/operators';
|
||||||
import { CircleButtonTypes } from '../../../buttons';
|
import { CircleButtonTypes } from '../../../buttons';
|
||||||
import { IListable } from '../../models';
|
import { IListable } from '../../models';
|
||||||
import { AutoUnsubscribe, Debounce, Required } from '../../../utils';
|
import { AutoUnsubscribe, Debounce } from '../../../utils';
|
||||||
import { WorkflowColumn } from '../workflow.component';
|
import { WorkflowColumn } from '../workflow.component';
|
||||||
import { ListingService } from '../../services';
|
import { ListingService } from '../../services';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'iqser-column-header',
|
selector: 'iqser-column-header [column] [selectionColumn]',
|
||||||
templateUrl: './column-header.component.html',
|
templateUrl: './column-header.component.html',
|
||||||
styleUrls: ['./column-header.component.css'],
|
styleUrls: ['./column-header.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class ColumnHeaderComponent<T extends IListable, K extends string> extends AutoUnsubscribe implements OnInit {
|
export class ColumnHeaderComponent<T extends IListable, K extends string> extends AutoUnsubscribe implements OnInit {
|
||||||
readonly circleButtonTypes = CircleButtonTypes;
|
readonly circleButtonTypes = CircleButtonTypes;
|
||||||
|
|
||||||
@Input() @Required() column!: WorkflowColumn<T, K>;
|
@Input() column!: WorkflowColumn<T, K>;
|
||||||
@Input() @Required() selectionColumn?: WorkflowColumn<T, K>;
|
@Input() selectionColumn?: WorkflowColumn<T, K>;
|
||||||
@Input() bulkActions?: TemplateRef<unknown>;
|
@Input() bulkActions?: TemplateRef<unknown>;
|
||||||
@Output() @Required() readonly selectionColumnChange = new EventEmitter<WorkflowColumn<T, K> | undefined>();
|
@Output() readonly selectionColumnChange = new EventEmitter<WorkflowColumn<T, K> | undefined>();
|
||||||
|
|
||||||
allSelected$!: Observable<boolean>;
|
allSelected$!: Observable<boolean>;
|
||||||
indeterminate$!: Observable<boolean>;
|
indeterminate$!: Observable<boolean>;
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
[text]="noDataText"
|
[text]="noDataText"
|
||||||
></iqser-empty-state>
|
></iqser-empty-state>
|
||||||
|
|
||||||
<div *ngIf="(entitiesService.noData$ | async) === false" cdkDropListGroup
|
<div *ngIf="(entitiesService.noData$ | async) === false && (draggingEntities$ | async) as draggingEntities" cdkDropListGroup
|
||||||
class="columns-wrapper">
|
class="columns-wrapper">
|
||||||
<div *ngFor="let column of config.columns" [class.dragging]="dragging"
|
<div *ngFor="let column of config.columns" [class.dragging]="dragging"
|
||||||
[class.list-can-receive]="isReceiving(column)"
|
[class.list-can-receive]="isReceiving(column)"
|
||||||
@ -26,34 +26,38 @@
|
|||||||
<iqser-column-header [(selectionColumn)]="selectionColumn" [bulkActions]="bulkActions" [column]="column"></iqser-column-header>
|
<iqser-column-header [(selectionColumn)]="selectionColumn" [bulkActions]="bulkActions" [column]="column"></iqser-column-header>
|
||||||
<div
|
<div
|
||||||
(cdkDropListDropped)="move($event)"
|
(cdkDropListDropped)="move($event)"
|
||||||
[cdkDropListData]="column.entities | async"
|
*ngIf="column.entities | async as entities"
|
||||||
[cdkDropListDisabled]="selectionColumn && selectionColumn !== column"
|
[cdkDropListData]="entities"
|
||||||
[cdkDropListEnterPredicate]="canMoveTo(column)"
|
[cdkDropListEnterPredicate]="canMoveTo(column)"
|
||||||
[id]="column.key"
|
[id]="column.key"
|
||||||
cdkDropList cdkDropListSortingDisabled>
|
cdkDropList cdkDropListSortingDisabled>
|
||||||
<div (cdkDragEnded)="stopDragging()" (cdkDragStarted)="startDragging(column)"
|
<div (cdkDragEnded)="stopDragging()" (cdkDragStarted)="startDragging(column, $event)"
|
||||||
(click)="selectionColumn === column && listingService.select(entity)"
|
(click)="selectionColumn === column && listingService.select(entity)"
|
||||||
*ngFor="let entity of (column.entities | async)" [cdkDragData]="entity"
|
*ngFor="let entity of entities" [cdkDragData]="entity"
|
||||||
[class.selected]="listingService.isSelected$(entity) | async"
|
[class.no-border]="dragging && draggingEntities.includes(entity)"
|
||||||
[ngClass]="getItemClasses(entity)" cdkDrag
|
[class.selected]="all[entity.id].isSelected$ | async"
|
||||||
|
[ngClass]="all[entity.id].classes$ | async" cdkDrag
|
||||||
>
|
>
|
||||||
|
<ng-container *ngIf="!draggingEntities.includes(entity)">
|
||||||
|
<ng-container *ngTemplateOutlet="itemTemplate; context: { entity: entity, itemWidth: itemWidth }">
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<div *cdkDragPlaceholder>
|
<div *cdkDragPlaceholder>
|
||||||
<!-- TODO: Check selected entities for single select -->
|
<div *ngFor="let e of draggingEntities" [style.min-height]="itemHeight + 'px'"
|
||||||
<div *ngFor="let e of (listingService.selectedEntities$ | async)" [style.min-height]="itemHeight + 'px'"
|
|
||||||
class="placeholder"></div>
|
class="placeholder"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *cdkDragPreview>
|
<div *cdkDragPreview>
|
||||||
<ng-container *ngFor="let e of (listingService.selectedEntities$ | async)">
|
<ng-container *ngFor="let e of draggingEntities">
|
||||||
<div [class.selected]="listingService.isSelected$(entity) | async" [ngClass]="getItemClasses(entity, true)"
|
<div [class.selected]="all[e.id].isSelected$ | async"
|
||||||
[style.max-width]="itemWidth + 'px'"
|
[ngClass]="all[e.id].classes$ | async"
|
||||||
>
|
[style.max-width]="itemWidth + 'px'">
|
||||||
<ng-container *ngTemplateOutlet="itemTemplate; context: { entity: e, itemWidth: itemWidth }"></ng-container>
|
<ng-container *ngTemplateOutlet="itemTemplate; context: { entity: e, itemWidth: itemWidth }"></ng-container>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
<ng-container *ngIf="!(dragging && (listingService.isSelected$(entity) | async)) ">
|
|
||||||
<ng-container *ngTemplateOutlet="itemTemplate; context: { entity: entity, itemWidth: itemWidth }"></ng-container>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
</div>
|
||||||
<div (click)="addElement.emit()" *ngIf="column.key === addElementColumn" class="add-btn">
|
<div (click)="addElement.emit()" *ngIf="column.key === addElementColumn" class="add-btn">
|
||||||
<mat-icon [svgIcon]="addElementIcon"></mat-icon>
|
<mat-icon [svgIcon]="addElementIcon"></mat-icon>
|
||||||
|
|||||||
@ -14,15 +14,15 @@ import {
|
|||||||
ViewChildren,
|
ViewChildren,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { ListingComponent } from '../listing-component.directive';
|
import { ListingComponent } from '../listing-component.directive';
|
||||||
import { CdkDrag, CdkDragDrop, CdkDropList } from '@angular/cdk/drag-drop';
|
import { CdkDrag, CdkDragDrop, CdkDragStart, CdkDropList } from '@angular/cdk/drag-drop';
|
||||||
import { AutoUnsubscribe, Debounce, Required } from '../../utils';
|
import { AutoUnsubscribe, Debounce, Required } from '../../utils';
|
||||||
import { LoadingService } from '../../loading';
|
import { LoadingService } from '../../loading';
|
||||||
import { IListable } from '../models';
|
import { IListable } from '../models';
|
||||||
import { EntitiesService, ListingService } from '../services';
|
import { EntitiesService, ListingService } from '../services';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { filter, tap } from 'rxjs/operators';
|
import { filter, tap } from 'rxjs/operators';
|
||||||
|
|
||||||
export interface WorkflowColumn<T, K> {
|
export interface WorkflowColumn<T extends IListable, K> {
|
||||||
key: K;
|
key: K;
|
||||||
label: string;
|
label: string;
|
||||||
color: string;
|
color: string;
|
||||||
@ -31,12 +31,35 @@ export interface WorkflowColumn<T, K> {
|
|||||||
entities: BehaviorSubject<T[]>;
|
entities: BehaviorSubject<T[]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkflowConfig<T, K> {
|
export interface WorkflowConfig<T extends IListable, K> {
|
||||||
columnIdentifierFn: (entity: T) => K;
|
columnIdentifierFn: (entity: T) => K;
|
||||||
itemVersionFn: (entity: T) => string;
|
itemVersionFn: (entity: T) => string;
|
||||||
columns: WorkflowColumn<T, K>[];
|
columns: WorkflowColumn<T, K>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class EntityWrapper<T extends IListable> {
|
||||||
|
readonly classes$: BehaviorSubject<Record<string, boolean>>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
readonly entity: T,
|
||||||
|
private readonly _itemClasses: Record<string, (e: T) => boolean>,
|
||||||
|
readonly isSelected$: Observable<boolean>,
|
||||||
|
) {
|
||||||
|
this.classes$ = new BehaviorSubject<Record<string, boolean>>(this._getItemClasses(entity));
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getItemClasses(entity: T): Record<string, boolean> {
|
||||||
|
const classes: { [key: string]: boolean } = {};
|
||||||
|
for (const key in this._itemClasses) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(this._itemClasses, key)) {
|
||||||
|
classes[key] = this._itemClasses[key](entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
classes.item = true;
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'iqser-workflow',
|
selector: 'iqser-workflow',
|
||||||
templateUrl: './workflow.component.html',
|
templateUrl: './workflow.component.html',
|
||||||
@ -47,7 +70,7 @@ export class WorkflowComponent<T extends IListable, K extends string> extends Au
|
|||||||
@Input() headerTemplate?: TemplateRef<unknown>;
|
@Input() headerTemplate?: TemplateRef<unknown>;
|
||||||
@Input() @Required() itemTemplate!: TemplateRef<T>;
|
@Input() @Required() itemTemplate!: TemplateRef<T>;
|
||||||
@Input() @Required() config!: WorkflowConfig<T, K>;
|
@Input() @Required() config!: WorkflowConfig<T, K>;
|
||||||
@Input() itemClasses?: { [key: string]: (e: T) => boolean };
|
@Input() itemClasses!: Record<string, (e: T) => boolean>;
|
||||||
@Input() addElementIcon?: string;
|
@Input() addElementIcon?: string;
|
||||||
@Input() addElementColumn?: K;
|
@Input() addElementColumn?: K;
|
||||||
@Input() noDataText?: string;
|
@Input() noDataText?: string;
|
||||||
@ -64,8 +87,9 @@ export class WorkflowComponent<T extends IListable, K extends string> extends Au
|
|||||||
dragging = false;
|
dragging = false;
|
||||||
sourceColumn?: WorkflowColumn<T, K>;
|
sourceColumn?: WorkflowColumn<T, K>;
|
||||||
selectionColumn?: WorkflowColumn<T, K>;
|
selectionColumn?: WorkflowColumn<T, K>;
|
||||||
|
readonly draggingEntities$ = new BehaviorSubject<T[]>([]);
|
||||||
|
all: { [key: string]: EntityWrapper<T> } = {};
|
||||||
@ViewChildren(CdkDropList) private readonly _dropLists!: QueryList<CdkDropList>;
|
@ViewChildren(CdkDropList) private readonly _dropLists!: QueryList<CdkDropList>;
|
||||||
private _existingEntities: { [key: string]: T } = {};
|
|
||||||
private _observer = new ResizeObserver((entries: ResizeObserverEntry[]) => {
|
private _observer = new ResizeObserver((entries: ResizeObserverEntry[]) => {
|
||||||
this._updateItemWidth(entries[0]);
|
this._updateItemWidth(entries[0]);
|
||||||
});
|
});
|
||||||
@ -85,31 +109,13 @@ export class WorkflowComponent<T extends IListable, K extends string> extends Au
|
|||||||
return this.listingComponent.tableHeaderLabel;
|
return this.listingComponent.tableHeaderLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
getItemClasses(entity: T, preview = false): { [key: string]: boolean } {
|
async move(event: CdkDragDrop<T[]>): Promise<void> {
|
||||||
const classes: { [key: string]: boolean } = {};
|
|
||||||
for (const key in this.itemClasses) {
|
|
||||||
if (Object.prototype.hasOwnProperty.call(this.itemClasses, key)) {
|
|
||||||
classes[key] = this.itemClasses[key](entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
classes.item = true;
|
|
||||||
if (!preview) {
|
|
||||||
classes['no-border'] = this.dragging && this.listingService.isSelected(entity);
|
|
||||||
}
|
|
||||||
return classes;
|
|
||||||
}
|
|
||||||
|
|
||||||
async move(event: CdkDragDrop<(T | number)[]>): Promise<void> {
|
|
||||||
if (event.previousContainer !== event.container) {
|
if (event.previousContainer !== event.container) {
|
||||||
const column = this._getColumnByKey((<unknown>event.container.id) as K);
|
const column = this._getColumnByKey((<unknown>event.container.id) as K);
|
||||||
|
|
||||||
if (this.selectionColumn) {
|
// TODO: Improve this
|
||||||
// TODO: Improve this
|
await Promise.all(this.draggingEntities$.value.map(entity => column.enterFn(entity)));
|
||||||
await Promise.all(this.listingService.selected.map(file => column.enterFn(file)));
|
this.listingService.setSelected([]); // TODO: Clear only when moving selected???
|
||||||
this.listingService.setSelected([]);
|
|
||||||
} else {
|
|
||||||
await column.enterFn(event.item.data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,12 +134,19 @@ export class WorkflowComponent<T extends IListable, K extends string> extends Au
|
|||||||
return (item: CdkDrag<T>) => column.enterPredicate(item.data);
|
return (item: CdkDrag<T>) => column.enterPredicate(item.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
startDragging(column: WorkflowColumn<T, K>): void {
|
startDragging(column: WorkflowColumn<T, K>, $event: CdkDragStart): void {
|
||||||
|
const entity: T = $event.source.data as T;
|
||||||
|
if (this.listingService.selected.includes(entity)) {
|
||||||
|
this.draggingEntities$.next(this.listingService.selected);
|
||||||
|
} else {
|
||||||
|
this.draggingEntities$.next([entity]);
|
||||||
|
}
|
||||||
this.dragging = true;
|
this.dragging = true;
|
||||||
this.sourceColumn = column;
|
this.sourceColumn = column;
|
||||||
}
|
}
|
||||||
|
|
||||||
stopDragging(): void {
|
stopDragging(): void {
|
||||||
|
this.draggingEntities$.next([]);
|
||||||
this.dragging = false;
|
this.dragging = false;
|
||||||
this.sourceColumn = undefined;
|
this.sourceColumn = undefined;
|
||||||
}
|
}
|
||||||
@ -159,9 +172,10 @@ export class WorkflowComponent<T extends IListable, K extends string> extends Au
|
|||||||
|
|
||||||
@Debounce(30)
|
@Debounce(30)
|
||||||
private _updateItemWidth(entry: ResizeObserverEntry): void {
|
private _updateItemWidth(entry: ResizeObserverEntry): void {
|
||||||
if (entry.contentRect.width === 0) {
|
if (entry.contentRect.height === 0) {
|
||||||
this._observer.unobserve(entry.target);
|
this._observer.unobserve(entry.target);
|
||||||
this._setupResizeObserver();
|
this._setupResizeObserver();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
this.itemWidth = entry.contentRect.width;
|
this.itemWidth = entry.contentRect.width;
|
||||||
this.itemHeight = entry.contentRect.height;
|
this.itemHeight = entry.contentRect.height;
|
||||||
@ -180,22 +194,20 @@ export class WorkflowComponent<T extends IListable, K extends string> extends Au
|
|||||||
|
|
||||||
// Remove deleted entities
|
// Remove deleted entities
|
||||||
const updatedIds = entities.map(entity => entity.id);
|
const updatedIds = entities.map(entity => entity.id);
|
||||||
for (const id of Object.keys(this._existingEntities)) {
|
for (const id of Object.keys(this.all)) {
|
||||||
if (!updatedIds.includes(id)) {
|
if (!updatedIds.includes(id)) {
|
||||||
this._removeEntity(this._existingEntities[id]);
|
this._removeEntity(this.all[id].entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add or move updated entities
|
// Add or move updated entities
|
||||||
entities.forEach(entity => {
|
entities.forEach(entity => {
|
||||||
const shouldAdd = this._shouldAdd(entity);
|
const shouldAdd = this._shouldAdd(entity);
|
||||||
const shouldMove = this._shouldMove(entity);
|
const shouldUpdate = this._shouldUpdate(entity);
|
||||||
|
|
||||||
if (shouldMove) {
|
if (shouldUpdate) {
|
||||||
this._removeEntity(entity);
|
this._updateEntity(entity);
|
||||||
}
|
} else if (shouldAdd) {
|
||||||
|
|
||||||
if (shouldAdd || shouldMove) {
|
|
||||||
this._addEntity(entity);
|
this._addEntity(entity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -208,29 +220,46 @@ export class WorkflowComponent<T extends IListable, K extends string> extends Au
|
|||||||
if (!column) {
|
if (!column) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._existingEntities[entity.id] = entity;
|
this.all[entity.id] = new EntityWrapper(entity, this.itemClasses, this.listingService.isSelected$(entity));
|
||||||
column.entities.next([...column.entities.value, entity]);
|
column.entities.next([...column.entities.value, entity]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _updateEntity(newEntity: T): void {
|
||||||
|
const existingEntity = this.all[newEntity.id];
|
||||||
|
const oldColumn = this._getColumnByKey(this.config.columnIdentifierFn(existingEntity.entity));
|
||||||
|
const newColumn = this._getColumnByKey(this.config.columnIdentifierFn(newEntity));
|
||||||
|
|
||||||
|
if (oldColumn === newColumn) {
|
||||||
|
this.all[newEntity.id] = new EntityWrapper(newEntity, this.itemClasses, this.listingService.isSelected$(newEntity));
|
||||||
|
const entitiesArr = [...oldColumn.entities.value];
|
||||||
|
const idx = entitiesArr.indexOf(existingEntity.entity);
|
||||||
|
entitiesArr[idx] = newEntity;
|
||||||
|
newColumn.entities.next(entitiesArr);
|
||||||
|
} else {
|
||||||
|
this._removeEntity(newEntity);
|
||||||
|
this._addEntity(newEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private _removeEntity(entity: T): void {
|
private _removeEntity(entity: T): void {
|
||||||
const existingEntity = this._existingEntities[entity.id];
|
const existingEntity = this.all[entity.id];
|
||||||
const column = this._getColumnByKey(this.config.columnIdentifierFn(existingEntity));
|
const column = this._getColumnByKey(this.config.columnIdentifierFn(existingEntity.entity));
|
||||||
if (column) {
|
if (column) {
|
||||||
const entities = column.entities.value;
|
const entities = column.entities.value;
|
||||||
const idx = entities.findIndex(item => item.id === entity.id);
|
const idx = entities.findIndex(item => item.id === entity.id);
|
||||||
entities.splice(idx, 1);
|
entities.splice(idx, 1);
|
||||||
column.entities.next(entities);
|
column.entities.next(entities);
|
||||||
}
|
}
|
||||||
delete this._existingEntities[entity.id];
|
delete this.all[entity.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
private _shouldMove(entity: T): boolean {
|
private _shouldUpdate(entity: T): boolean {
|
||||||
const existingEntity = this._existingEntities[entity.id];
|
const existingEntity = this.all[entity.id]?.entity;
|
||||||
return existingEntity && this.config.itemVersionFn(entity) !== this.config.itemVersionFn(existingEntity);
|
return existingEntity && this.config.itemVersionFn(entity) !== this.config.itemVersionFn(existingEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _shouldAdd(entity: T): boolean {
|
private _shouldAdd(entity: T): boolean {
|
||||||
return !this._existingEntities[entity.id];
|
return !this.all[entity.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getColumnByKey(key: K | undefined): WorkflowColumn<T, K> {
|
private _getColumnByKey(key: K | undefined): WorkflowColumn<T, K> {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user