Просмотр исходного кода

feat(admin-ui): Persist Collection list expanded states to the url

Relates to #1532
Michael Bromley 3 лет назад
Родитель
Сommit
d67187e844

+ 2 - 1
packages/admin-ui/src/lib/catalog/src/components/collection-list/collection-list.component.html

@@ -11,7 +11,7 @@
                 class="expand-all-toggle ml3"
                 [ngClass]="(availableLanguages$ | async)?.length === 1 ? 'mt3' : 'mt1'"
             >
-                <input type="checkbox" clrCheckbox [(ngModel)]="expandAll" />
+                <input type="checkbox" clrCheckbox [(ngModel)]="expandAll" (change)="toggleExpandAll()"/>
                 <label>{{ 'catalog.expand-all-collections' | translate }}</label>
             </clr-checkbox-wrapper>
             <input
@@ -40,6 +40,7 @@
         [collections]="items$ | async"
         [activeCollectionId]="activeCollectionId$ | async"
         [expandAll]="expandAll"
+        [expandedIds]="expandedIds"
         (rearrange)="onRearrange($event)"
         (deleteCollection)="deleteCollection($event)"
     ></vdr-collection-tree>

+ 13 - 0
packages/admin-ui/src/lib/catalog/src/components/collection-list/collection-list.component.ts

@@ -39,6 +39,7 @@ export class CollectionListComponent implements OnInit, OnDestroy {
     availableLanguages$: Observable<LanguageCode[]>;
     contentLanguage$: Observable<LanguageCode>;
     expandAll = false;
+    expandedIds: string[] = [];
     private queryResult: QueryResult<any>;
     private destroy$ = new Subject<void>();
 
@@ -58,6 +59,8 @@ export class CollectionListComponent implements OnInit, OnDestroy {
             map(pm => pm.get('contents')),
             distinctUntilChanged(),
         );
+        this.expandedIds = this.route.snapshot.queryParamMap.get('expanded')?.split(',') ?? [];
+        this.expandAll = this.route.snapshot.queryParamMap.get('expanded') === 'all';
 
         this.activeCollectionTitle$ = combineLatest(this.activeCollectionId$, this.items$).pipe(
             map(([id, collections]) => {
@@ -85,6 +88,16 @@ export class CollectionListComponent implements OnInit, OnDestroy {
         this.destroy$.complete();
     }
 
+    toggleExpandAll() {
+        this.router.navigate(['./'], {
+            queryParams: {
+                expanded: this.expandAll ? 'all' : undefined,
+            },
+            queryParamsHandling: 'merge',
+            relativeTo: this.route,
+        });
+    }
+
     onRearrange(event: RearrangeEvent) {
         this.dataService.collection.moveCollection([event]).subscribe({
             next: () => {

+ 6 - 2
packages/admin-ui/src/lib/catalog/src/components/collection-tree/array-to-tree.ts

@@ -6,7 +6,11 @@ export type RootNode<T extends HasParent> = { id?: string; children: Array<TreeN
  * Builds a tree from an array of nodes which have a parent.
  * Based on https://stackoverflow.com/a/31247960/772859, modified to preserve ordering.
  */
-export function arrayToTree<T extends HasParent>(nodes: T[], currentState?: RootNode<T>): RootNode<T> {
+export function arrayToTree<T extends HasParent>(
+    nodes: T[],
+    currentState?: RootNode<T>,
+    expandedIds: string[] = [],
+): RootNode<T> {
     const topLevelNodes: Array<TreeNode<T>> = [];
     const mappedArr: { [id: string]: TreeNode<T> } = {};
     const currentStateMap = treeToMap(currentState);
@@ -19,7 +23,7 @@ export function arrayToTree<T extends HasParent>(nodes: T[], currentState?: Root
     for (const id of nodes.map(n => n.id)) {
         if (mappedArr.hasOwnProperty(id)) {
             const mappedElem = mappedArr[id];
-            mappedElem.expanded = currentStateMap.get(id)?.expanded ?? false;
+            mappedElem.expanded = currentStateMap.get(id)?.expanded ?? expandedIds.includes(id);
             const parent = mappedElem.parent;
             if (!parent) {
                 continue;

+ 1 - 1
packages/admin-ui/src/lib/catalog/src/components/collection-tree/collection-tree-node.component.html

@@ -23,7 +23,7 @@
                     class="icon-button folder-button"
                     [disabled]="expandAll"
                     *ngIf="collection.children?.length; else folderSpacer"
-                    (click)="collection.expanded = !collection.expanded"
+                    (click)="toggleExpanded(collection)"
                 >
                     <clr-icon shape="folder" *ngIf="!collection.expanded && !expandAll"></clr-icon>
                     <clr-icon shape="folder-open" *ngIf="collection.expanded || expandAll"></clr-icon>

+ 20 - 0
packages/admin-ui/src/lib/catalog/src/components/collection-tree/collection-tree-node.component.ts

@@ -9,6 +9,7 @@ import {
     SimpleChanges,
     SkipSelf,
 } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
 import { DataService, Permission } from '@vendure/admin-ui/core';
 import { Observable } from 'rxjs';
 import { map, shareReplay } from 'rxjs/operators';
@@ -36,6 +37,8 @@ export class CollectionTreeNodeComponent implements OnInit, OnChanges {
         @SkipSelf() @Optional() private parent: CollectionTreeNodeComponent,
         private root: CollectionTreeComponent,
         private dataService: DataService,
+        private router: Router,
+        private route: ActivatedRoute,
     ) {
         if (parent) {
             this.depth = parent.depth + 1;
@@ -75,6 +78,23 @@ export class CollectionTreeNodeComponent implements OnInit, OnChanges {
         return item.id;
     }
 
+    toggleExpanded(collection: TreeNode<CollectionPartial>) {
+        collection.expanded = !collection.expanded;
+        let expandedIds = this.route.snapshot.queryParamMap.get('expanded')?.split(',') ?? [];
+        if (collection.expanded) {
+            expandedIds.push(collection.id);
+        } else {
+            expandedIds = expandedIds.filter(id => id !== collection.id);
+        }
+        this.router.navigate(['./'], {
+            queryParams: {
+                expanded: expandedIds.filter(id => !!id).join(','),
+            },
+            queryParamsHandling: 'merge',
+            relativeTo: this.route,
+        });
+    }
+
     getMoveListItems(collection: CollectionPartial) {
         this.moveListItems = this.root.getMoveListItems(collection);
     }

+ 2 - 1
packages/admin-ui/src/lib/catalog/src/components/collection-tree/collection-tree.component.ts

@@ -25,6 +25,7 @@ export class CollectionTreeComponent implements OnChanges {
     @Input() collections: CollectionPartial[];
     @Input() activeCollectionId: string;
     @Input() expandAll = false;
+    @Input() expandedIds: string[] = [];
     @Output() rearrange = new EventEmitter<RearrangeEvent>();
     @Output() deleteCollection = new EventEmitter<string>();
     collectionTree: RootNode<CollectionPartial>;
@@ -32,7 +33,7 @@ export class CollectionTreeComponent implements OnChanges {
 
     ngOnChanges(changes: SimpleChanges) {
         if ('collections' in changes && this.collections) {
-            this.collectionTree = arrayToTree(this.collections, this.collectionTree);
+            this.collectionTree = arrayToTree(this.collections, this.collectionTree, this.expandedIds);
             this.allMoveListItems = [];
         }
     }