Skip to content

Commit 9f93244

Browse files
committed
feat(json-view): implement methods to expand / collapse view items
1 parent a1a270a commit 9f93244

File tree

9 files changed

+360
-12
lines changed

9 files changed

+360
-12
lines changed

packages/demo/src/app/json-view/documentation.json

Lines changed: 208 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,163 @@
3131
"extends": []
3232
}
3333
],
34-
"injectables": [],
34+
"injectables": [
35+
{
36+
"name": "ExpanderService",
37+
"id": "injectable-ExpanderService-65acdfec985b778f6bb9647fbfcbaf3c86cb54bccc480bffc32d39cf500f8ec56e57322f928386da584adb56dbd94b92d48157c08abc94bbbbe2db101fc20cf9",
38+
"file": "src/lib/expander/expander.service.ts",
39+
"properties": [],
40+
"methods": [
41+
{
42+
"name": "addItem",
43+
"args": [
44+
{
45+
"name": "item",
46+
"type": "JsonViewItemComponent",
47+
"deprecated": false,
48+
"deprecationMessage": ""
49+
}
50+
],
51+
"optional": false,
52+
"returnType": "void",
53+
"typeParameters": [],
54+
"line": 12,
55+
"deprecated": false,
56+
"deprecationMessage": "",
57+
"jsdoctags": [
58+
{
59+
"name": "item",
60+
"type": "JsonViewItemComponent",
61+
"deprecated": false,
62+
"deprecationMessage": "",
63+
"tagName": {
64+
"text": "param"
65+
}
66+
}
67+
]
68+
},
69+
{
70+
"name": "collapseTo",
71+
"args": [
72+
{
73+
"name": "level",
74+
"type": "number",
75+
"deprecated": false,
76+
"deprecationMessage": ""
77+
}
78+
],
79+
"optional": false,
80+
"returnType": "void",
81+
"typeParameters": [],
82+
"line": 29,
83+
"deprecated": false,
84+
"deprecationMessage": "",
85+
"jsdoctags": [
86+
{
87+
"name": "level",
88+
"type": "number",
89+
"deprecated": false,
90+
"deprecationMessage": "",
91+
"tagName": {
92+
"text": "param"
93+
}
94+
}
95+
]
96+
},
97+
{
98+
"name": "expandTo",
99+
"args": [
100+
{
101+
"name": "level",
102+
"type": "number",
103+
"deprecated": false,
104+
"deprecationMessage": ""
105+
}
106+
],
107+
"optional": false,
108+
"returnType": "void",
109+
"typeParameters": [],
110+
"line": 20,
111+
"deprecated": false,
112+
"deprecationMessage": "",
113+
"jsdoctags": [
114+
{
115+
"name": "level",
116+
"type": "number",
117+
"deprecated": false,
118+
"deprecationMessage": "",
119+
"tagName": {
120+
"text": "param"
121+
}
122+
}
123+
]
124+
},
125+
{
126+
"name": "removeItem",
127+
"args": [
128+
{
129+
"name": "item",
130+
"type": "JsonViewItemComponent",
131+
"deprecated": false,
132+
"deprecationMessage": ""
133+
}
134+
],
135+
"optional": false,
136+
"returnType": "void",
137+
"typeParameters": [],
138+
"line": 16,
139+
"deprecated": false,
140+
"deprecationMessage": "",
141+
"jsdoctags": [
142+
{
143+
"name": "item",
144+
"type": "JsonViewItemComponent",
145+
"deprecated": false,
146+
"deprecationMessage": "",
147+
"tagName": {
148+
"text": "param"
149+
}
150+
}
151+
]
152+
}
153+
],
154+
"deprecated": false,
155+
"deprecationMessage": "",
156+
"description": "",
157+
"rawdescription": "\n",
158+
"constructorObj": {
159+
"name": "constructor",
160+
"description": "",
161+
"deprecated": false,
162+
"deprecationMessage": "",
163+
"args": [],
164+
"line": 8
165+
},
166+
"extends": [],
167+
"type": "injectable"
168+
}
169+
],
35170
"guards": [],
36171
"interceptors": [],
37172
"classes": [],
38173
"directives": [],
39174
"components": [
40175
{
41176
"name": "JsonViewComponent",
42-
"id": "component-JsonViewComponent-eafe988ebc33bfa13c61732e2bb6dc37720d1f5a59bbf2035762f3f382448becfd7dd0676005aedbda4047126076445194c951c7117298e7a5ae87378a91a7f0",
177+
"id": "component-JsonViewComponent-43a4e5de5f43e9cf40f2a8c9c997b2d7f0ab8c0c8b2acc253f3709e593ff92052ea3c7c2becb5bbc7dbb7772881216104020c6e01e4aae4eac86db82f3a44b42",
43178
"file": "src/lib/json-view/json-view.component.ts",
44179
"encapsulation": [
45180
"ViewEncapsulation.Emulated"
46181
],
47182
"entryComponents": [],
48183
"inputs": [],
49184
"outputs": [],
50-
"providers": [],
185+
"providers": [
186+
{
187+
"name": "ExpanderService",
188+
"type": "injectable"
189+
}
190+
],
51191
"selector": "nxt-json-view",
52192
"styleUrls": [
53193
"./json-view.component.scss"
@@ -65,7 +205,7 @@
65205
"deprecationMessage": "",
66206
"rawdescription": "\nJSON data, any valid JSON object",
67207
"description": "<p>JSON data, any valid JSON object</p>\n",
68-
"line": 13,
208+
"line": 20,
69209
"type": "any",
70210
"decorators": []
71211
},
@@ -75,7 +215,7 @@
75215
"deprecationMessage": "",
76216
"rawdescription": "\nCustom labels for elements within the hierarcy",
77217
"description": "<p>Custom labels for elements within the hierarcy</p>\n",
78-
"line": 17,
218+
"line": 24,
79219
"type": "LevelLabels",
80220
"decorators": []
81221
},
@@ -85,14 +225,75 @@
85225
"deprecationMessage": "",
86226
"rawdescription": "\nInitial number of levels to be expanded",
87227
"description": "<p>Initial number of levels to be expanded</p>\n",
88-
"line": 15,
228+
"line": 22,
89229
"type": "number",
90230
"decorators": []
91231
}
92232
],
93233
"outputsClass": [],
94234
"propertiesClass": [],
95-
"methodsClass": [],
235+
"methodsClass": [
236+
{
237+
"name": "collapseTo",
238+
"args": [
239+
{
240+
"name": "level",
241+
"type": "number",
242+
"deprecated": false,
243+
"deprecationMessage": ""
244+
}
245+
],
246+
"optional": false,
247+
"returnType": "void",
248+
"typeParameters": [],
249+
"line": 35,
250+
"deprecated": false,
251+
"deprecationMessage": "",
252+
"rawdescription": "\nCollapse any open items above the given level",
253+
"description": "<p>Collapse any open items above the given level</p>\n",
254+
"jsdoctags": [
255+
{
256+
"name": "level",
257+
"type": "number",
258+
"deprecated": false,
259+
"deprecationMessage": "",
260+
"tagName": {
261+
"text": "param"
262+
}
263+
}
264+
]
265+
},
266+
{
267+
"name": "expandTo",
268+
"args": [
269+
{
270+
"name": "level",
271+
"type": "number",
272+
"deprecated": false,
273+
"deprecationMessage": ""
274+
}
275+
],
276+
"optional": false,
277+
"returnType": "void",
278+
"typeParameters": [],
279+
"line": 29,
280+
"deprecated": false,
281+
"deprecationMessage": "",
282+
"rawdescription": "\nExpand all items up to the given level",
283+
"description": "<p>Expand all items up to the given level</p>\n",
284+
"jsdoctags": [
285+
{
286+
"name": "level",
287+
"type": "number",
288+
"deprecated": false,
289+
"deprecationMessage": "",
290+
"tagName": {
291+
"text": "param"
292+
}
293+
}
294+
]
295+
}
296+
],
96297
"deprecated": false,
97298
"deprecationMessage": "",
98299
"hostBindings": [],
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<button type="button"
2+
class="btn btn-secondary"
3+
(click)="tree.expandTo(3)">
4+
Expand to level 3
5+
</button>
6+
7+
<button type="button"
8+
class="btn btn-secondary"
9+
(click)="tree.collapseTo(1)">
10+
Collapse to level 1
11+
</button>
12+
13+
<br><br>
14+
15+
<nxt-json-view [data]="data"
16+
[levelOpen]="2"
17+
#tree></nxt-json-view>

packages/demo/src/app/json-view/examples/expand-collapse/expand-collapse.component.scss

Whitespace-only changes.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Component, ViewEncapsulation } from '@angular/core'
2+
import { JsonViewModule } from 'nxt-json-view'
3+
4+
class TreeNode<V> {
5+
6+
readonly children = new Array<TreeNode<V>>()
7+
private parent?: TreeNode<V>
8+
9+
constructor(public value: V) { }
10+
11+
addChild(node: TreeNode<V>) {
12+
const i = this.children.indexOf(node)
13+
if (node.parent == this && i >= 0)
14+
return
15+
16+
if (node.parent)
17+
node.parent.removeChild(node)
18+
19+
this.children.push(node)
20+
node.parent = this
21+
}
22+
23+
removeChild(node: TreeNode<V>) {
24+
const i = this.children.indexOf(node)
25+
if (i >= 0) {
26+
this.children.splice(i, 1)
27+
node.parent = undefined
28+
}
29+
}
30+
}
31+
32+
const root = new TreeNode('root')
33+
root.addChild(new TreeNode('child1'))
34+
root.addChild(new TreeNode('child2'))
35+
36+
@Component({
37+
selector: 'app-expand-collapse',
38+
templateUrl: './expand-collapse.component.html',
39+
styleUrl: './expand-collapse.component.scss',
40+
encapsulation: ViewEncapsulation.Emulated,
41+
imports: [
42+
JsonViewModule
43+
]
44+
})
45+
export class ExpandCollapseComponent {
46+
data = root
47+
}

packages/demo/src/app/json-view/json-view/json-view.component.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ export class AppJsonViewComponent extends WaitLoad implements OnInit {
3434
name: 'With expansion parameters',
3535
include: ['html']
3636
},
37+
{
38+
path: 'expand-collapse',
39+
name: 'Expand / collapse the view',
40+
include: ['html']
41+
},
3742
{
3843
path: 'level-labels',
3944
name: 'With level labels',
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { TestBed } from '@angular/core/testing'
2+
import { ExpanderService } from './expander.service'
3+
4+
describe('ExpanderService', () => {
5+
let service: ExpanderService
6+
7+
beforeEach(() => {
8+
TestBed.configureTestingModule({})
9+
service = TestBed.inject(ExpanderService)
10+
})
11+
12+
it('should be created', () => {
13+
expect(service).toBeTruthy()
14+
})
15+
})
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Injectable } from '@angular/core'
2+
import { type JsonViewItemComponent } from '../json-view-item/json-view-item.component'
3+
4+
@Injectable({
5+
providedIn: 'root'
6+
})
7+
export class ExpanderService {
8+
private readonly items = new Set<JsonViewItemComponent>()
9+
10+
constructor() { }
11+
12+
addItem(item: JsonViewItemComponent) {
13+
this.items.add(item)
14+
}
15+
16+
removeItem(item: JsonViewItemComponent) {
17+
this.items.delete(item)
18+
}
19+
20+
expandTo(level: number) {
21+
this.items.forEach(i => {
22+
if (i.level <= level && !i.isOpen) {
23+
i.levelOpen = level
24+
i.toggle()
25+
}
26+
})
27+
}
28+
29+
collapseTo(level: number) {
30+
this.items.forEach(i => {
31+
if (i.level > level && i.isOpen)
32+
i.toggle()
33+
})
34+
}
35+
}

0 commit comments

Comments
 (0)