mirror of https://github.com/Squidex/squidex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
4.1 KiB
139 lines
4.1 KiB
/*
|
|
* Squidex Headless CMS
|
|
*
|
|
* @license
|
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
|
|
*/
|
|
|
|
import { ChangeDetectorRef, Component, forwardRef, Input } from '@angular/core';
|
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
import { ModalModel, StatefulControlComponent, Types } from '@app/framework';
|
|
import { AppsState, AssetsService, ROOT_ITEM } from '@app/shared/internal';
|
|
import { AssetFolderDropdowNode } from './asset-folder-dropdown.state';
|
|
|
|
export const SQX_ASSETS_FOLDER_DROPDOWN_CONTROL_VALUE_ACCESSOR: any = {
|
|
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => AssetFolderDropdownComponent), multi: true,
|
|
};
|
|
|
|
@Component({
|
|
selector: 'sqx-asset-folder-dropdown',
|
|
styleUrls: ['./asset-folder-dropdown.component.scss'],
|
|
templateUrl: './asset-folder-dropdown.component.html',
|
|
providers: [
|
|
SQX_ASSETS_FOLDER_DROPDOWN_CONTROL_VALUE_ACCESSOR,
|
|
],
|
|
})
|
|
export class AssetFolderDropdownComponent extends StatefulControlComponent<any, string> {
|
|
@Input()
|
|
public set disabled(value: boolean | undefined | null) {
|
|
this.setDisabledState(value === true);
|
|
}
|
|
|
|
public get appName() {
|
|
return this.appsState.appName;
|
|
}
|
|
|
|
public root: AssetFolderDropdowNode = { item: ROOT_ITEM, children: [], parent: null };
|
|
|
|
public selection = this.root;
|
|
public selectionPath: string;
|
|
|
|
public dropdown = new ModalModel();
|
|
|
|
constructor(changeDetector: ChangeDetectorRef,
|
|
private readonly appsState: AppsState,
|
|
private readonly assetsService: AssetsService,
|
|
) {
|
|
super(changeDetector, {});
|
|
}
|
|
|
|
public writeValue(obj: string) {
|
|
if (!Types.isString(obj)) {
|
|
obj = ROOT_ITEM.id;
|
|
}
|
|
|
|
const node = this.findNode(this.root, obj);
|
|
|
|
if (node?.isLoaded) {
|
|
this.select(node, false);
|
|
return;
|
|
}
|
|
|
|
this.assetsService.getAssetFolders(this.appName, obj, 'PathAndItems')
|
|
.subscribe(dto => {
|
|
let parent = this.root;
|
|
|
|
for (const item of dto.path) {
|
|
let newParent = parent.children.find(x => x.item.id === item.id);
|
|
|
|
if (!newParent) {
|
|
newParent = { item, children: [], parent };
|
|
parent.children.push(newParent);
|
|
parent.children.sortByString(x => x.item.folderName);
|
|
}
|
|
|
|
parent = newParent;
|
|
}
|
|
|
|
if (dto.items.length > 0) {
|
|
for (const item of dto.items) {
|
|
if (!parent.children.find(x => x.item.id === item.id)) {
|
|
parent.children.push({ item, children: [], parent });
|
|
}
|
|
}
|
|
|
|
parent.children.sortByString(x => x.item.folderName);
|
|
}
|
|
|
|
this.select(parent, false);
|
|
});
|
|
}
|
|
|
|
public select(selected: AssetFolderDropdowNode, emit = true) {
|
|
this.resetSelected(this.root);
|
|
|
|
const path: AssetFolderDropdowNode[] = [];
|
|
|
|
let current: AssetFolderDropdowNode | null = selected.parent;
|
|
|
|
while (current) {
|
|
path.push(current);
|
|
|
|
current.isExpanded = true;
|
|
current = current.parent;
|
|
}
|
|
|
|
this.selection = selected;
|
|
this.selection.isSelected = true;
|
|
this.selectionPath = path.filter(x => x.item !== ROOT_ITEM).map(x => x.item.folderName).join('/');
|
|
|
|
if (emit) {
|
|
this.callChange(selected.item.id);
|
|
this.callTouched();
|
|
|
|
this.dropdown.hide();
|
|
}
|
|
}
|
|
|
|
private resetSelected(node: AssetFolderDropdowNode) {
|
|
node.isSelected = false;
|
|
|
|
for (const child of node.children) {
|
|
this.resetSelected(child);
|
|
}
|
|
}
|
|
|
|
private findNode(node: AssetFolderDropdowNode, id: string) {
|
|
if (node.item.id === id) {
|
|
return node;
|
|
}
|
|
|
|
for (const child of node.children) {
|
|
if (this.findNode(child, id)) {
|
|
return child;
|
|
}
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
}
|
|
|