organization is modified
This commit is contained in:
parent
18b68e290e
commit
f2bd8aea17
|
@ -17,22 +17,37 @@
|
|||
<mat-tree-node
|
||||
*matTreeNodeDef="let node"
|
||||
matTreeNodePadding
|
||||
class="mat-tree-last-node"
|
||||
matTreeNodePaddingIndent="20"
|
||||
class="tree-no-child"
|
||||
>
|
||||
<li (click)="onClickNode(node)" matRipple>
|
||||
<div>
|
||||
{{ node.name }}
|
||||
<div class="tree-node-closer-container">
|
||||
<div class="tree-node-closer-top"></div>
|
||||
<div
|
||||
class="tree-node-closer-bottom"
|
||||
[attr.lastNode]="isLastNode(node) ? '' : null"
|
||||
></div>
|
||||
</div>
|
||||
<li (click)="onClickNode(node)" matRipple>
|
||||
<div class="tree-node-body">{{ node.name }}</div>
|
||||
</li>
|
||||
</mat-tree-node>
|
||||
<!-- This is the tree node template for expandable nodes -->
|
||||
<mat-tree-node
|
||||
*matTreeNodeDef="let node; when: hasChild"
|
||||
matTreeNodePadding
|
||||
class="tree-node-frame"
|
||||
matTreeNodePaddingIndent="20"
|
||||
class="tree-has-child"
|
||||
>
|
||||
<div *ngIf="0 !== node.level" class="tree-node-closer-container">
|
||||
<div class="tree-node-closer-top"></div>
|
||||
<div
|
||||
class="tree-node-closer-bottom"
|
||||
[attr.expanded]="treeControl.isExpanded(node) ? '' : null"
|
||||
[attr.lastNode]="isLastNode(node) ? '' : null"
|
||||
></div>
|
||||
</div>
|
||||
<li (click)="onClickNode(node)" matRipple>
|
||||
<div class="path">
|
||||
<div class="tree-node-body">
|
||||
<span class="horizontal-line"></span>
|
||||
<button
|
||||
mat-icon-button
|
||||
|
@ -40,23 +55,16 @@
|
|||
matTreeNodeToggle
|
||||
[attr.aria-label]="'toggle ' + node.filename"
|
||||
>
|
||||
<mat-icon class="mat-icon-rtl-mirror">
|
||||
<!-- {{ treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right' }}-->
|
||||
<mat-icon
|
||||
class="tree-node-expand-btn"
|
||||
[@romvoeAdd]="treeControl.isExpanded(node) ? 'remove' : 'add'"
|
||||
>
|
||||
{{ treeControl.isExpanded(node) ? 'remove' : 'add' }}
|
||||
</mat-icon>
|
||||
</button>
|
||||
<span class="dept-name">{{ node.name }}</span>
|
||||
</div>
|
||||
<ul
|
||||
[class.organization-tree-node-invisible]="
|
||||
!treeControl.isExpanded(node)
|
||||
"
|
||||
>
|
||||
<div *ngIf="treeControl.isExpanded(node)" class="boxnone">
|
||||
<div class="vertical-line"></div>
|
||||
<ng-container matTreeNodeOutlet></ng-container>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- <ul class="tree-node-closer"></ul> -->
|
||||
</li>
|
||||
</mat-tree-node>
|
||||
</mat-tree>
|
||||
|
|
|
@ -1,40 +1,50 @@
|
|||
@charset 'utf-8';
|
||||
.organization-tree {
|
||||
padding: 10px;
|
||||
ul,
|
||||
padding: 5px;
|
||||
|
||||
.tree-node-closer-container {
|
||||
position: relative;
|
||||
// border: 1px dotted grey;
|
||||
// border-width: 0 0 1px 1px;
|
||||
|
||||
.tree-node-closer-top {
|
||||
width: 15px;
|
||||
height: 40px;
|
||||
position: absolute;
|
||||
border: 1px dotted grey;
|
||||
border-width: 0 0 1px 1px;
|
||||
top: -40px;
|
||||
left: 20px;
|
||||
}
|
||||
.tree-node-closer-bottom {
|
||||
width: 15px;
|
||||
height: 40px;
|
||||
position: absolute;
|
||||
border: 1px dotted grey;
|
||||
border-width: 0 0 1px 1px;
|
||||
top: 0px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
.tree-node-closer-bottom[expanded] {
|
||||
border-width: 0 0 1px 0px;
|
||||
}
|
||||
.tree-node-closer-bottom[lastNode] {
|
||||
border-width: 0 0 1px 0px;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
.organization-tree-node-invisible {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/*.tree-node-frame {
|
||||
li {
|
||||
.path {
|
||||
.horizontal-line {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.mat-tree-node {
|
||||
min-height: 30px;
|
||||
font-size: 13px;
|
||||
padding-left: 20px;
|
||||
margin-top: 4px;
|
||||
&:hover {
|
||||
background-color: #f4f4f4;
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 4px rgba(32, 33, 36, 0.1);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
.organization-tree {
|
||||
.tree-node-frame {
|
||||
// li:last-child {
|
||||
// border-left: 1px solid white;
|
||||
// margin-left: -41px;
|
||||
// }
|
||||
|
||||
.tree-has-child {
|
||||
height: 40px;
|
||||
min-height: 40px;
|
||||
li {
|
||||
|
@ -42,84 +52,29 @@
|
|||
align-items: center;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
|
||||
.tree-node-body {
|
||||
.tree-node-expand-btn {
|
||||
background-color: white;
|
||||
}
|
||||
}
|
||||
.mat-tree-last-node {
|
||||
}
|
||||
}
|
||||
|
||||
.tree-no-child {
|
||||
height: 40px;
|
||||
min-height: 30px;
|
||||
min-height: 40px;
|
||||
font-size: 13px;
|
||||
li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-left: 10px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: #f4f4f4;
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 4px rgba(32, 33, 36, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul .tree-node-frame li .path > .horizontal-line {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.boxnone {
|
||||
position: relative;
|
||||
.vertical-line {
|
||||
background: rgba(189, 189, 189, 0.4);
|
||||
bottom: 6px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
width: 2px;
|
||||
}
|
||||
.mat-tree-node:last-child {
|
||||
padding-bottom: 10px;
|
||||
.tree-node-body {
|
||||
padding-left: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.path {
|
||||
padding: 6px 4px;
|
||||
+ ul {
|
||||
li:last-chlid {
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
}
|
||||
.horizontal-line {
|
||||
width: 10px;
|
||||
height: 1px;
|
||||
background-color: #dddddd;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-left: -10px;
|
||||
}
|
||||
.mat-icon-button {
|
||||
padding: 0;
|
||||
min-width: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
flex-shrink: 0;
|
||||
line-height: 20px;
|
||||
.mat-icon-rtl-mirror {
|
||||
border: 1px solid #dddddd;
|
||||
padding: 2px;
|
||||
font-size: 14px;
|
||||
min-width: 14px;
|
||||
min-height: 14px;
|
||||
line-height: 14px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
box-shadow: 0 2px 1px rgba(48, 48, 48, 0.2);
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.dept-name {
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
|||
import { FlatTreeControl } from '@angular/cdk/tree';
|
||||
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
||||
import { VirtualScrollTreeFlatDataSource } from '@ucap-webmessenger/ui';
|
||||
import { ucapAnimations } from '@ucap-webmessenger/ui';
|
||||
import { trigger, transition, style, animate } from '@angular/animations';
|
||||
|
||||
interface OrganizationNode {
|
||||
deptInfo: DeptInfo;
|
||||
|
@ -35,7 +37,19 @@ interface FlatNode {
|
|||
@Component({
|
||||
selector: 'ucap-organization-tree',
|
||||
templateUrl: './tree.component.html',
|
||||
styleUrls: ['./tree.component.scss']
|
||||
styleUrls: ['./tree.component.scss'],
|
||||
animations: [
|
||||
ucapAnimations,
|
||||
trigger('romvoeAdd', [
|
||||
transition('remove <=> add', [
|
||||
style({
|
||||
transform: `rotate(45deg)`,
|
||||
opacity: 0
|
||||
}),
|
||||
animate('.2s 0s ease-out')
|
||||
])
|
||||
])
|
||||
]
|
||||
})
|
||||
export class TreeComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
@Output()
|
||||
|
@ -139,6 +153,21 @@ export class TreeComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
|
||||
hasChild = (_: number, node: FlatNode) => node.expandable;
|
||||
|
||||
isLastNode(node: FlatNode): boolean {
|
||||
const i = this.dataSource.expandedDataSubject.value.findIndex(n => {
|
||||
return node.deptInfo.seq === n.deptInfo.seq;
|
||||
});
|
||||
|
||||
if (i === this.dataSource.expandedDataSubject.value.length - 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (node.level !== this.dataSource.expandedDataSubject.value[i + 1].level) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
onClickNode(node: OrganizationNode) {
|
||||
this.selected.emit(node.deptInfo);
|
||||
}
|
||||
|
|
|
@ -47,15 +47,21 @@ export const ucapAnimations = [
|
|||
|
||||
transition(
|
||||
'void => 50',
|
||||
query('@*', [stagger('50ms', [animateChild()])], { optional: true })
|
||||
query('@*', [stagger('50ms', [animateChild()])], {
|
||||
optional: true
|
||||
})
|
||||
),
|
||||
transition(
|
||||
'void => 100',
|
||||
query('@*', [stagger('100ms', [animateChild()])], { optional: true })
|
||||
query('@*', [stagger('100ms', [animateChild()])], {
|
||||
optional: true
|
||||
})
|
||||
),
|
||||
transition(
|
||||
'void => 200',
|
||||
query('@*', [stagger('200ms', [animateChild()])], { optional: true })
|
||||
query('@*', [stagger('200ms', [animateChild()])], {
|
||||
optional: true
|
||||
})
|
||||
)
|
||||
]),
|
||||
|
||||
|
@ -551,6 +557,24 @@ export const ucapAnimations = [
|
|||
)
|
||||
]),
|
||||
|
||||
trigger('treeToggler', [
|
||||
state(
|
||||
'0, void',
|
||||
style({
|
||||
opacity: 0
|
||||
})
|
||||
),
|
||||
state(
|
||||
'1, *',
|
||||
style({
|
||||
opacity: 1
|
||||
})
|
||||
),
|
||||
transition('1 => 0', animate('300ms ease-out')),
|
||||
transition('0 => 1', animate('300ms ease-in')),
|
||||
transition('void <=> *', animate('300ms ease-in'))
|
||||
]),
|
||||
|
||||
/**
|
||||
* Floating ACtion Button Animation.
|
||||
*/
|
||||
|
|
|
@ -14,7 +14,7 @@ import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
|||
export class VirtualScrollTreeFlatDataSource<T, F> extends DataSource<F> {
|
||||
private flattenedDataSubject = new BehaviorSubject<F[]>([]);
|
||||
|
||||
private expandedDataSubject = new BehaviorSubject<F[]>([]);
|
||||
expandedDataSubject = new BehaviorSubject<F[]>([]);
|
||||
expandedData$: Observable<F[]>;
|
||||
|
||||
private connectSubject: Subject<F[]>;
|
||||
|
|
Loading…
Reference in New Issue
Block a user