bug fixed
This commit is contained in:
parent
a129584ce1
commit
186c0c337e
43
angular.json
43
angular.json
|
@ -1393,6 +1393,49 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ui-group": {
|
||||
"projectType": "library",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"style": "scss"
|
||||
}
|
||||
},
|
||||
"root": "projects/ui-group",
|
||||
"sourceRoot": "projects/ui-group/src",
|
||||
"prefix": "ucap-group",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||
"options": {
|
||||
"tsConfig": "projects/ui-group/tsconfig.lib.json",
|
||||
"project": "projects/ui-group/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "projects/ui-group/tsconfig.lib.prod.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "projects/ui-group/src/test.ts",
|
||||
"tsConfig": "projects/ui-group/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/ui-group/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"projects/ui-group/tsconfig.lib.json",
|
||||
"projects/ui-group/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ui-skin-default": {
|
||||
"projectType": "library",
|
||||
"schematics": {
|
||||
|
|
27
package-lock.json
generated
27
package-lock.json
generated
|
@ -3383,13 +3383,18 @@
|
|||
},
|
||||
"@ucap/ng-ui": {
|
||||
"version": "file:pack/ucap-ng-ui-0.0.4.tgz",
|
||||
"integrity": "sha512-DcrZx55uGvvc70vUxP2fkgQhORMMBgkKWRdG5zH1PpgB4wY1Od887DgFJISEQzbcFNBNr6TiX+I8e64maGQp0A=="
|
||||
"integrity": "sha512-DcrZx55uGvvc70vUxP2fkgQhORMMBgkKWRdG5zH1PpgB4wY1Od887DgFJISEQzbcFNBNr6TiX+I8e64maGQp0A==",
|
||||
"dev": true
|
||||
},
|
||||
"@ucap/ng-ui-authentication": {
|
||||
"version": "file:pack/ucap-ng-ui-authentication-0.0.16.tgz",
|
||||
"integrity": "sha512-j9JLn3btK2yVF3cthELaSwn5oe6qYW7z+knT8O9b/a36xuHGeMZLr60IGM6cF1QgRdFpFWaK2oN0DgdnU/s8Iw==",
|
||||
"dev": true
|
||||
},
|
||||
"@ucap/ng-ui-group": {
|
||||
"version": "file:pack/ucap-ng-ui-group-0.0.3.tgz",
|
||||
"integrity": "sha512-VH0X1xy2IaHwe0ihkKn9N3fmpz8KD5xAmf8tSTC/DbvoxCI2r7nlRddvh9emthOkdKIqXhbaO20Q1oKrXUGvxg=="
|
||||
},
|
||||
"@ucap/ng-ui-organization": {
|
||||
"version": "file:pack/ucap-ng-ui-organization-0.0.2.tgz",
|
||||
"integrity": "sha512-IzTDv19feOL76nxRrRJ3PMKuV86HQJrqUXHMurkUjvlQnZM/1yMa7gNSvQcERprwnMCAwB42VTvbI+mN5AxoAA==",
|
||||
|
@ -6603,7 +6608,7 @@
|
|||
"version": "4.0.0",
|
||||
"resolved": "http://10.81.13.221:8081/nexus/repository/npm-all/crypto-js/-/crypto-js-4.0.0.tgz",
|
||||
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg==",
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"crypto-random-string": {
|
||||
"version": "2.0.0",
|
||||
|
@ -12052,6 +12057,16 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ngx-perfect-scrollbar": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "http://10.81.13.221:8081/nexus/repository/npm-all/ngx-perfect-scrollbar/-/ngx-perfect-scrollbar-9.0.0.tgz",
|
||||
"integrity": "sha512-jiFrOLONf/w2PjSKkEjQeTnMdlMVcQgjzIrYcsor1HWTmE+95J2sZAd/WF4zoutbpIqfU8VQQoAp8HOa7U1c/g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"perfect-scrollbar": "1.5.0",
|
||||
"resize-observer-polyfill": "^1.5.0"
|
||||
}
|
||||
},
|
||||
"nice-try": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "http://10.81.13.221:8081/nexus/repository/npm-all/nice-try/-/nice-try-1.0.5.tgz",
|
||||
|
@ -13178,6 +13193,12 @@
|
|||
"integrity": "sha512-KGuODSTV6hcgdZvDrIDBUkN0utcAVj1LL7FfGbM0viKTtCHmtZcuEJ+lGqsp0fTFkGqesdtemV2yUSMeyy3ddA==",
|
||||
"dev": true
|
||||
},
|
||||
"perfect-scrollbar": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "http://10.81.13.221:8081/nexus/repository/npm-all/perfect-scrollbar/-/perfect-scrollbar-1.5.0.tgz",
|
||||
"integrity": "sha512-NrNHJn5mUGupSiheBTy6x+6SXCFbLlm8fVZh9moIzw/LgqElN5q4ncR4pbCBCYuCJ8Kcl9mYM0NgDxvW+b4LxA==",
|
||||
"dev": true
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "http://10.81.13.221:8081/nexus/repository/npm-all/performance-now/-/performance-now-2.1.0.tgz",
|
||||
|
@ -14461,7 +14482,7 @@
|
|||
"version": "0.3.4",
|
||||
"resolved": "http://10.81.13.221:8081/nexus/repository/npm-all/queueing-subject/-/queueing-subject-0.3.4.tgz",
|
||||
"integrity": "sha512-sdpymi9eq80oZyg74NrIGr1GHKIDRmBLZp+xqOct8Do5KpKalPsSz9NxApZb0S2j+EEDMzDlosBN5NJGFLmS7A==",
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"quick-lru": {
|
||||
"version": "1.1.0",
|
||||
|
|
14
package.json
14
package.json
|
@ -45,10 +45,11 @@
|
|||
"build:store-chat": "node ./scripts/build.js store-chat",
|
||||
"build:store-group": "node ./scripts/build.js store-group",
|
||||
"build:store-organization": "node ./scripts/build.js store-organization",
|
||||
"build:ui:all": "npm-run-all -s build:ui build:ui-organization build:ui-authentication",
|
||||
"build:ui:all": "npm-run-all -s build:ui build:ui-organization build:ui-authentication build:ui-group",
|
||||
"build:ui": "node ./scripts/build.js ui",
|
||||
"build:ui-organization": "node ./scripts/build.js ui-organization",
|
||||
"build:ui-authentication": "node ./scripts/build.js ui-authentication",
|
||||
"build:ui-group": "node ./scripts/build.js ui-group",
|
||||
"build:ui-skin:all": "npm-run-all -s build:ui-skin-default",
|
||||
"build:ui-skin-default": "node ./scripts/build.js ui-skin-default useScssBundle",
|
||||
"publish:all": "npm-run-all -s publish:logger publish:core publish:util:all publish:api:all publish:protocol:all publish:native:all publish:store:all publish:ui:all publish:ui-skin:all",
|
||||
|
@ -90,10 +91,11 @@
|
|||
"publish:store-chat": "cd ./dist/store-chat && npm publish",
|
||||
"publish:store-group": "cd ./dist/store-group && npm publish",
|
||||
"publish:store-organization": "cd ./dist/store-organization && npm publish",
|
||||
"publish:ui:all": "npm-run-all -s publish:ui publish:ui-organization publish:ui-authentication",
|
||||
"publish:ui:all": "npm-run-all -s publish:ui publish:ui-organization publish:ui-authentication publish:ui-group",
|
||||
"publish:ui": "cd ./dist/ui && npm publish",
|
||||
"publish:ui-organization": "cd ./dist/ui-organization && npm publish",
|
||||
"publish:ui-authentication": "cd ./dist/ui-authentication && npm publish",
|
||||
"publish:ui-group": "cd ./dist/ui-group && npm publish",
|
||||
"publish:ui-skin:all": "npm-run-all -s publish:ui-skin-default",
|
||||
"publish:ui-skin-default": "cd ./dist/ui-skin-default && npm publish",
|
||||
"test": "ng test",
|
||||
|
@ -181,6 +183,7 @@
|
|||
"@ucap/ng-store-organization": "file:pack/ucap-ng-store-organization-0.0.4.tgz",
|
||||
"@ucap/ng-ui": "file:pack/ucap-ng-ui-0.0.4.tgz",
|
||||
"@ucap/ng-ui-authentication": "file:pack/ucap-ng-ui-authentication-0.0.16.tgz",
|
||||
"@ucap/ng-ui-group": "file:pack/ucap-ng-ui-group-0.0.3.tgz",
|
||||
"@ucap/ng-ui-organization": "file:pack/ucap-ng-ui-organization-0.0.2.tgz",
|
||||
"@ucap/ng-ui-skin-default": "file:pack/ucap-ng-ui-skin-default-0.0.1.tgz",
|
||||
"@ucap/ng-web-socket": "file:pack/ucap-ng-web-socket-0.0.2.tgz",
|
||||
|
@ -209,6 +212,7 @@
|
|||
"babel-loader": "^8.1.0",
|
||||
"codelyzer": "^5.2.1",
|
||||
"concurrently": "^5.1.0",
|
||||
"crypto-js": "^4.0.0",
|
||||
"detect-browser": "^5.0.0",
|
||||
"file-type": "^14.1.4",
|
||||
"fs-extra": "^9.0.0",
|
||||
|
@ -225,8 +229,10 @@
|
|||
"moment-timezone": "^0.5.28",
|
||||
"move-cli": "^1.2.1",
|
||||
"ng-packagr": "^9.0.3",
|
||||
"ngx-perfect-scrollbar": "^9.0.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"protractor": "~5.4.3",
|
||||
"queueing-subject": "^0.3.4",
|
||||
"rimraf": "^3.0.2",
|
||||
"rxjs": "~6.5.4",
|
||||
"scss-bundle": "^3.1.1",
|
||||
|
@ -236,9 +242,5 @@
|
|||
"typescript": "~3.7.5",
|
||||
"webpack-bundle-analyzer": "^3.6.1",
|
||||
"zone.js": "~0.10.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"queueing-subject": "^0.3.4",
|
||||
"crypto-js": "^4.0.0"
|
||||
}
|
||||
}
|
||||
|
|
25
projects/ui-group/README.md
Normal file
25
projects/ui-group/README.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
# UiGroup
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.0.2.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project ui-group` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ui-group`.
|
||||
|
||||
> Note: Don't forget to add `--project ui-group` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build ui-group` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build ui-group`, go to the dist folder `cd dist/ui-group` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test ui-group` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
32
projects/ui-group/karma.conf.js
Normal file
32
projects/ui-group/karma.conf.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../coverage/ui-group'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
});
|
||||
};
|
11
projects/ui-group/ng-package.json
Normal file
11
projects/ui-group/ng-package.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"dest": "../../dist/ui-group",
|
||||
"lib": {
|
||||
"entryFile": "src/public-api.ts",
|
||||
"umdModuleIds": {
|
||||
"@ucap/core": "@ucap/core",
|
||||
"@ucap/ng-ui": "@ucap/ng-ui"
|
||||
}
|
||||
}
|
||||
}
|
16
projects/ui-group/package.json
Normal file
16
projects/ui-group/package.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "@ucap/ng-ui-group",
|
||||
"version": "0.0.3",
|
||||
"publishConfig": {
|
||||
"registry": "http://10.81.13.221:8081/nexus/repository/npm-ucap/"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/cdk": "^9.0.0",
|
||||
"@angular/common": "^9.0.2",
|
||||
"@angular/core": "^9.0.2",
|
||||
"@angular/material": "^9.0.0",
|
||||
"@ucap/core": "~0.0.1",
|
||||
"@ucap/ng-ui": "~0.0.1",
|
||||
"tslib": "^1.10.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<div>
|
||||
<cdk-virtual-scroll-viewport
|
||||
#cvsvList
|
||||
perfectScrollbar
|
||||
fxFlexFill
|
||||
virtualScrollStrategy="virtualScrollStrategy"
|
||||
>
|
||||
<ng-container
|
||||
*cdkVirtualFor="let node of dataSource.expandedData$"
|
||||
></ng-container>
|
||||
|
||||
<mat-tree #treeList [dataSource]="dataSource" [treeControl]="treeControl">
|
||||
<mat-tree-node
|
||||
*matTreeNodeDef="let node"
|
||||
[attr.node-type]="node?.nodeType"
|
||||
matRipple
|
||||
>
|
||||
<li>
|
||||
<div>
|
||||
<ng-container
|
||||
ngTemplateOutlet="nodeTemplate; context: {$implicit: node}"
|
||||
></ng-container>
|
||||
</div>
|
||||
</li>
|
||||
</mat-tree-node>
|
||||
|
||||
<mat-tree-node
|
||||
*matTreeNodeDef="let node; when: isHeader"
|
||||
class="tree-node-frame ucap-clickable"
|
||||
[attr.node-type]="node?.nodeType"
|
||||
matRipple
|
||||
>
|
||||
<li class="tree-node-header" matTreeNodeToggle>
|
||||
<div class="path">
|
||||
<button
|
||||
mat-icon-button
|
||||
[attr.aria-label]="'toggle '"
|
||||
class="btn-toggle"
|
||||
*ngIf="!checkable"
|
||||
>
|
||||
<mat-icon class="mat-icon-rtl-mirror">
|
||||
{{
|
||||
treeControl.isExpanded(node) ? 'expand_less' : 'expand_more'
|
||||
}}
|
||||
</mat-icon>
|
||||
</button>
|
||||
<div class="group-info">
|
||||
<ng-container [ngSwitch]="node.nodeType">
|
||||
<ng-container
|
||||
*ngSwitchCase="NodeType.Favorite"
|
||||
ngTemplateOutlet="favoriteHeaderTemplate; context: {$implicit: node}"
|
||||
>
|
||||
</ng-container>
|
||||
<ng-container
|
||||
*ngSwitchCase="NodeType.Default"
|
||||
ngTemplateOutlet="defaultHeaderTemplate; context: {$implicit: node}"
|
||||
>
|
||||
</ng-container>
|
||||
<ng-container
|
||||
*ngSwitchCase="NodeType.Buddy"
|
||||
ngTemplateOutlet="buddyHeaderTemplate; context: {$implicit: node}"
|
||||
>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<mat-checkbox
|
||||
*ngIf="checkable"
|
||||
#checkbox
|
||||
[checked]="isCheckedGroup(node)"
|
||||
[disabled]="!isCheckableGroup(node)"
|
||||
(change)="onChangeCheckGroup(checkbox.checked, node)"
|
||||
(click)="$event.stopPropagation()"
|
||||
class="group-check"
|
||||
>
|
||||
</mat-checkbox>
|
||||
<button
|
||||
mat-icon-button
|
||||
aria-label="group-header-menu"
|
||||
*ngIf="!checkable"
|
||||
(click)="onClickHeaderMenu($event, node)"
|
||||
>
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<ul [class.group-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>
|
||||
</li>
|
||||
</mat-tree-node>
|
||||
</mat-tree>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
</div>
|
|
@ -0,0 +1,27 @@
|
|||
/* tslint:disable:no-unused-variable */
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { DebugElement } from '@angular/core';
|
||||
|
||||
import { ExpansionListComponent } from './expansion-list.component';
|
||||
|
||||
describe('ucap::ui-group::ExpansionListComponent', () => {
|
||||
let component: ExpansionListComponent;
|
||||
let fixture: ComponentFixture<ExpansionListComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ExpansionListComponent]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ExpansionListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,16 @@
|
|||
import { action } from '@storybook/addon-actions';
|
||||
import { linkTo } from '@storybook/addon-links';
|
||||
|
||||
import { ExpansionListComponent } from './expansion-list.component';
|
||||
|
||||
export default {
|
||||
title: 'ExpansionListComponent',
|
||||
component: ExpansionListComponent
|
||||
};
|
||||
|
||||
export const Text = () => ({
|
||||
component: ExpansionListComponent,
|
||||
props: {
|
||||
text: 'Hello ExpansionListComponent'
|
||||
}
|
||||
});
|
286
projects/ui-group/src/lib/components/expansion-list.component.ts
Normal file
286
projects/ui-group/src/lib/components/expansion-list.component.ts
Normal file
|
@ -0,0 +1,286 @@
|
|||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
Input,
|
||||
Output,
|
||||
EventEmitter,
|
||||
ViewChild,
|
||||
ContentChild,
|
||||
TemplateRef
|
||||
} from '@angular/core';
|
||||
|
||||
import {
|
||||
VirtualScrollStrategy,
|
||||
CdkVirtualScrollViewport
|
||||
} from '@angular/cdk/scrolling';
|
||||
import { FlatTreeControl } from '@angular/cdk/tree';
|
||||
|
||||
import { MatTreeFlattener, MatTree } from '@angular/material/tree';
|
||||
|
||||
import { UserInfo, GroupDetailData } from '@ucap/protocol-sync';
|
||||
|
||||
import { VirtualScrollTreeFlatDataSource } from '@ucap/ng-ui';
|
||||
import { UserInfoSS, UserInfoF, UserInfoDN } from '@ucap/protocol-query';
|
||||
|
||||
export enum NodeType {
|
||||
None = 'None',
|
||||
Profile = 'Profile',
|
||||
Favorite = 'Favorite',
|
||||
Buddy = 'Buddy',
|
||||
Default = 'Default'
|
||||
}
|
||||
|
||||
export interface GroupNode {
|
||||
nodeType: NodeType;
|
||||
userInfo?: UserInfo;
|
||||
groupDetail?: GroupDetailData;
|
||||
children?: GroupNode[];
|
||||
}
|
||||
|
||||
export interface FlatNode {
|
||||
expandable: boolean;
|
||||
level: number;
|
||||
node: GroupNode;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-group-expansion-list',
|
||||
templateUrl: './expansion-list.component.html',
|
||||
styleUrls: ['./expansion-list.component.scss']
|
||||
})
|
||||
export class ExpansionListComponent implements OnInit, OnDestroy {
|
||||
@Input()
|
||||
virtualScrollStrategy: VirtualScrollStrategy;
|
||||
|
||||
@Input()
|
||||
set profile(userInfo: UserInfo) {
|
||||
if (!userInfo) {
|
||||
this.profileNodes = [];
|
||||
} else {
|
||||
const node: GroupNode = {
|
||||
nodeType: NodeType.Profile,
|
||||
userInfo,
|
||||
children: []
|
||||
};
|
||||
|
||||
this.profileNodes = [node];
|
||||
}
|
||||
|
||||
this.refreshNodes();
|
||||
}
|
||||
|
||||
@Input()
|
||||
set favorites(userInfos: UserInfo[]) {
|
||||
if (!userInfos || 0 === userInfos.length) {
|
||||
this.favoriteNodes = [];
|
||||
} else {
|
||||
const node: GroupNode = {
|
||||
nodeType: NodeType.Favorite,
|
||||
groupDetail: {
|
||||
seq: -9999,
|
||||
name: NodeType.Favorite,
|
||||
isActive: true,
|
||||
userSeqs: userInfos.map((userInfo) => String(userInfo.seq))
|
||||
} as GroupDetailData,
|
||||
children: []
|
||||
};
|
||||
|
||||
userInfos.forEach((userInfo) => {
|
||||
node.children.push({
|
||||
nodeType: NodeType.Favorite,
|
||||
userInfo
|
||||
});
|
||||
});
|
||||
|
||||
this.favoriteNodes = [node];
|
||||
}
|
||||
|
||||
this.refreshNodes();
|
||||
}
|
||||
|
||||
@Input()
|
||||
set groupBuddies(list: { group: GroupDetailData; buddyList: UserInfo[] }[]) {
|
||||
if (!list || 0 === list.length) {
|
||||
this.buddyNodes = [];
|
||||
} else {
|
||||
for (const item of list) {
|
||||
let nodeType = NodeType.Buddy;
|
||||
if (0 === item.group.seq) {
|
||||
nodeType = NodeType.Default;
|
||||
}
|
||||
|
||||
const node: GroupNode = {
|
||||
nodeType,
|
||||
groupDetail: item.group,
|
||||
children: []
|
||||
};
|
||||
|
||||
item.buddyList.sort((a, b) =>
|
||||
a.order < b.order
|
||||
? -1
|
||||
: a.order > b.order
|
||||
? 1
|
||||
: a.name < b.name
|
||||
? -1
|
||||
: a.name > b.name
|
||||
? 1
|
||||
: 0
|
||||
);
|
||||
|
||||
item.buddyList.forEach((userInfo) => {
|
||||
node.children.push({
|
||||
nodeType,
|
||||
groupDetail: item.group,
|
||||
userInfo
|
||||
});
|
||||
});
|
||||
|
||||
this.buddyNodes.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
this.refreshNodes();
|
||||
}
|
||||
|
||||
@Input()
|
||||
checkable = false;
|
||||
|
||||
@Input()
|
||||
selectedUserList?: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[] = [];
|
||||
|
||||
@Input()
|
||||
unselectableUserList?: (
|
||||
| UserInfo
|
||||
| UserInfoSS
|
||||
| UserInfoF
|
||||
| UserInfoDN
|
||||
)[] = [];
|
||||
|
||||
@ViewChild('treeList', { static: false })
|
||||
treeList: MatTree<FlatNode>;
|
||||
|
||||
@ViewChild('cvsvList', { static: false })
|
||||
cvsvList: CdkVirtualScrollViewport;
|
||||
|
||||
@ContentChild('[ucapGroupExpansionList="node"]', { read: TemplateRef })
|
||||
nodeTemplate: TemplateRef<any>;
|
||||
|
||||
@ContentChild('[ucapGroupExpansionList="favoriteHeader"]', {
|
||||
read: TemplateRef
|
||||
})
|
||||
favoriteHeaderTemplate: TemplateRef<any>;
|
||||
|
||||
@ContentChild('[ucapGroupExpansionList="defaultHeader"]', {
|
||||
read: TemplateRef
|
||||
})
|
||||
defaultHeaderTemplate: TemplateRef<any>;
|
||||
|
||||
@ContentChild('[ucapGroupExpansionList="buddyHeader"]', { read: TemplateRef })
|
||||
buddyHeaderTemplate: TemplateRef<any>;
|
||||
|
||||
rootNodeList: GroupNode[] = [];
|
||||
treeControl: FlatTreeControl<FlatNode>;
|
||||
treeFlattener: MatTreeFlattener<GroupNode, FlatNode>;
|
||||
dataSource: VirtualScrollTreeFlatDataSource<GroupNode, FlatNode>;
|
||||
|
||||
NodeType = NodeType;
|
||||
|
||||
private profileNodes: GroupNode[] = [];
|
||||
private favoriteNodes: GroupNode[] = [];
|
||||
private buddyNodes: GroupNode[] = [];
|
||||
|
||||
constructor() {
|
||||
this.treeControl = new FlatTreeControl<FlatNode>(
|
||||
(node) => node.level,
|
||||
(node) => node.expandable
|
||||
);
|
||||
|
||||
this.treeFlattener = new MatTreeFlattener<GroupNode, FlatNode>(
|
||||
(node: GroupNode, level: number) => {
|
||||
return {
|
||||
expandable: !!node.children && node.children.length > 0,
|
||||
level,
|
||||
nodeType: node.nodeType,
|
||||
node
|
||||
};
|
||||
},
|
||||
(node) => node.level,
|
||||
(node) => node.expandable,
|
||||
(node) => node.children
|
||||
);
|
||||
|
||||
this.dataSource = new VirtualScrollTreeFlatDataSource<GroupNode, FlatNode>(
|
||||
this.treeControl,
|
||||
this.treeFlattener
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
ngOnDestroy(): void {}
|
||||
|
||||
onClickHeaderMenu(event: MouseEvent, node: FlatNode) {}
|
||||
|
||||
isCheckedGroup(node: FlatNode): boolean {
|
||||
const groupDetail = node.node.groupDetail;
|
||||
|
||||
if (!groupDetail || groupDetail === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (groupDetail.userSeqs.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!!this.selectedUserList && this.selectedUserList.length > 0) {
|
||||
let allExist = true;
|
||||
groupDetail.userSeqs.some((seq) => {
|
||||
if (
|
||||
this.selectedUserList.filter((item) => item.seq === seq).length === 0
|
||||
) {
|
||||
allExist = false;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return allExist;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
isCheckableGroup(node: FlatNode): boolean {
|
||||
if (!!this.unselectableUserList && this.unselectableUserList.length > 0) {
|
||||
const groupDetail = node.node.groupDetail;
|
||||
let allExist = true;
|
||||
groupDetail.userSeqs.some((seq) => {
|
||||
if (
|
||||
this.unselectableUserList.filter((item) => item.seq === seq)
|
||||
.length === 0
|
||||
) {
|
||||
allExist = false;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (allExist) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
onChangeCheckGroup(value: boolean, node: FlatNode) {}
|
||||
|
||||
isHeader = (_: number, node: FlatNode) =>
|
||||
NodeType.Profile !== node.node.nodeType && 0 === node.level;
|
||||
|
||||
private refreshNodes() {
|
||||
this.rootNodeList = [
|
||||
...this.profileNodes,
|
||||
...this.favoriteNodes,
|
||||
...this.buddyNodes
|
||||
];
|
||||
this.dataSource.data = this.rootNodeList;
|
||||
}
|
||||
}
|
4
projects/ui-group/src/lib/config/module-config.ts
Normal file
4
projects/ui-group/src/lib/config/module-config.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { ModuleConfig as CoreModuleConfig } from '@ucap/core';
|
||||
|
||||
// tslint:disable-next-line: no-empty-interface
|
||||
export interface ModuleConfig extends CoreModuleConfig {}
|
5
projects/ui-group/src/lib/config/token.ts
Normal file
5
projects/ui-group/src/lib/config/token.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { InjectionToken } from '@angular/core';
|
||||
|
||||
export const _MODULE_CONFIG = new InjectionToken(
|
||||
'@ucap/ui-group config of module'
|
||||
);
|
61
projects/ui-group/src/lib/group-ui.module.ts
Normal file
61
projects/ui-group/src/lib/group-ui.module.ts
Normal file
|
@ -0,0 +1,61 @@
|
|||
import { NgModule, ModuleWithProviders } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { ScrollingModule } from '@angular/cdk/scrolling';
|
||||
|
||||
import { MatRippleModule } from '@angular/material/core';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatTreeModule } from '@angular/material/tree';
|
||||
|
||||
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
|
||||
|
||||
import { UiModule } from '@ucap/ng-ui';
|
||||
|
||||
import { ModuleConfig } from './config/module-config';
|
||||
import { _MODULE_CONFIG } from './config/token';
|
||||
|
||||
import { ExpansionListComponent } from './components/expansion-list.component';
|
||||
|
||||
const COMPONENTS = [ExpansionListComponent];
|
||||
const DIALOGS = [];
|
||||
const PIPES = [];
|
||||
const DIRECTIVES = [];
|
||||
const SERVICES = [];
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [],
|
||||
exports: []
|
||||
})
|
||||
export class GroupUiRootModule {}
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
ScrollingModule,
|
||||
|
||||
MatButtonModule,
|
||||
MatCheckboxModule,
|
||||
MatIconModule,
|
||||
MatRippleModule,
|
||||
MatTreeModule,
|
||||
|
||||
PerfectScrollbarModule,
|
||||
UiModule
|
||||
],
|
||||
exports: [...COMPONENTS, ...DIRECTIVES, ...PIPES],
|
||||
declarations: [...COMPONENTS, ...DIRECTIVES, ...PIPES],
|
||||
entryComponents: [...DIALOGS]
|
||||
})
|
||||
export class GroupUiModule {
|
||||
public static forRoot(
|
||||
config: ModuleConfig
|
||||
): ModuleWithProviders<GroupUiRootModule> {
|
||||
return {
|
||||
ngModule: GroupUiRootModule,
|
||||
providers: [{ provide: _MODULE_CONFIG, useValue: config }, ...SERVICES]
|
||||
};
|
||||
}
|
||||
}
|
9
projects/ui-group/src/public-api.ts
Normal file
9
projects/ui-group/src/public-api.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* Public API Surface of ui-group
|
||||
*/
|
||||
|
||||
export * from './lib/config/module-config';
|
||||
|
||||
export * from './lib/components/expansion-list.component';
|
||||
|
||||
export * from './lib/group-ui.module';
|
26
projects/ui-group/src/test.ts
Normal file
26
projects/ui-group/src/test.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/dist/zone';
|
||||
import 'zone.js/dist/zone-testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(path: string, deep?: boolean, filter?: RegExp): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
23
projects/ui-group/tsconfig.lib.json
Normal file
23
projects/ui-group/tsconfig.lib.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
6
projects/ui-group/tsconfig.lib.prod.json
Normal file
6
projects/ui-group/tsconfig.lib.prod.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"extends": "./tsconfig.lib.json",
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
17
projects/ui-group/tsconfig.spec.json
Normal file
17
projects/ui-group/tsconfig.spec.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
7
projects/ui-group/tslint.json
Normal file
7
projects/ui-group/tslint.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"extends": "../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [true, "attribute", "ucapGroup", "camelCase"],
|
||||
"component-selector": [true, "element", "ucap-group", "kebab-case"]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user