@@ -4,14 +4,17 @@ import { Link, useLocation, useNavigate } from "react-router-dom";
4
4
import type { MenuProps } from "antd" ;
5
5
import { Menu , Select , Button } from "antd" ;
6
6
7
- import { Vendor , ListVendorsResponse } from "@api/grpc-web/api_pb" ;
7
+ import { Vendor , ListVendorsResponse , ListDevicesRequest , ListDevicesResponse , Device , ListProfilesRequest , ListProfilesResponse , Profile , ListCodecsRequest , ListCodecsResponse , Codec } from "@api/grpc-web/api_pb" ;
8
8
import DeviceProfileStore from "../stores/DeviceProfileStore" ;
9
9
10
10
11
11
function SideMenu ( ) {
12
12
const [ vendor , setVendor ] = useState < string | undefined > ( undefined ) ;
13
13
const [ vendors , setVendors ] = useState < Vendor [ ] > ( [ ] ) ;
14
14
const [ selectedKey , setSelectedKey ] = useState < string > ( "" ) ;
15
+ const [ devices , setDevices ] = useState < Device [ ] > ( [ ] ) ;
16
+ const [ profiles , setProfiles ] = useState < Profile [ ] > ( [ ] ) ;
17
+ const [ codecs , setCodecs ] = useState < Codec [ ] > ( [ ] ) ;
15
18
16
19
const navigate = useNavigate ( ) ;
17
20
const location = useLocation ( ) ;
@@ -40,6 +43,47 @@ function SideMenu() {
40
43
} ;
41
44
} , [ ] ) ;
42
45
46
+ useEffect ( ( ) => {
47
+ if ( vendor == undefined ) {
48
+ return ;
49
+ }
50
+
51
+ const loadDevices = ( ) => {
52
+ const req = new ListDevicesRequest ( ) ;
53
+ req . setVendorDir ( vendor ) ;
54
+ DeviceProfileStore . listDevices ( req , ( resp : ListDevicesResponse ) => {
55
+ setDevices ( resp . getResultList ( ) ) ;
56
+ } ) ;
57
+ } ;
58
+
59
+ const loadProfiles = ( ) => {
60
+ const req = new ListProfilesRequest ( ) ;
61
+ req . setVendorDir ( vendor ) ;
62
+ DeviceProfileStore . listProfiles ( req , ( resp : ListProfilesResponse ) => {
63
+ setProfiles ( resp . getResultList ( ) ) ;
64
+ } ) ;
65
+ } ;
66
+
67
+ const loadCodecs = ( ) => {
68
+ const req = new ListCodecsRequest ( ) ;
69
+ req . setVendorDir ( vendor ) ;
70
+ DeviceProfileStore . listCodecs ( req , ( resp : ListCodecsResponse ) => {
71
+ setCodecs ( resp . getResultList ( ) ) ;
72
+ } ) ;
73
+ } ;
74
+
75
+ DeviceProfileStore . on ( "change" , loadDevices )
76
+ DeviceProfileStore . on ( "change" , loadProfiles ) ;
77
+ DeviceProfileStore . on ( "change" , loadCodecs ) ;
78
+ loadDevices ( ) ;
79
+ loadProfiles ( ) ;
80
+ loadCodecs ( ) ;
81
+
82
+ return ( ) => {
83
+ DeviceProfileStore . removeAllListeners ( "change" ) ;
84
+ } ;
85
+ } , [ vendor ] ) ;
86
+
43
87
useEffect ( ( ) => {
44
88
parseLocation ( ) ;
45
89
} , [ location ] )
@@ -73,30 +117,99 @@ function SideMenu() {
73
117
74
118
setSelectedKey ( "" ) ;
75
119
120
+ if ( path . includes ( "vendors" ) && path . endsWith ( "edit" ) ) {
121
+ setSelectedKey ( "vendor-edit" ) ;
122
+ }
76
123
if ( path . includes ( "profiles" ) ) {
77
- setSelectedKey ( "profiles" ) ;
124
+ setSelectedKey ( "devices" ) ;
125
+
126
+ if ( path . endsWith ( "create" ) ) {
127
+ setSelectedKey ( "profiles-create" ) ;
128
+ } else if ( path . endsWith ( ".toml" ) ) {
129
+ setSelectedKey ( "profiles-" + path . split ( "/" ) . slice ( - 1 ) ) ;
130
+ }
78
131
}
79
132
if ( path . includes ( "codecs" ) ) {
80
133
setSelectedKey ( "codecs" ) ;
134
+
135
+ if ( path . endsWith ( "create" ) ) {
136
+ setSelectedKey ( "codecs-create" ) ;
137
+ } else if ( path . endsWith ( ".js" ) ) {
138
+ setSelectedKey ( "codecs-" + path . split ( "/" ) . slice ( - 1 ) ) ;
139
+ }
81
140
}
82
141
if ( path . includes ( "devices" ) ) {
83
142
setSelectedKey ( "devices" ) ;
143
+
144
+ if ( path . endsWith ( "create" ) ) {
145
+ setSelectedKey ( "devices-create" ) ;
146
+ } else if ( path . endsWith ( ".toml" ) ) {
147
+ setSelectedKey ( "devices-" + path . split ( "/" ) . slice ( - 1 ) ) ;
148
+ }
84
149
}
85
150
} , [ location . pathname ] ) ;
86
151
87
152
let items : MenuProps [ "items" ] = [
88
153
{
89
- key : "devices" , label : < Link to = { `/vendors/${ vendor } /devices` } > Devices</ Link >
154
+ key : "vendor" ,
155
+ label : "Vendor" ,
156
+ children : [
157
+ {
158
+ key : "vendor-edit" ,
159
+ label : < Link to = { `/vendors/${ vendor } /edit` } > Update vendor</ Link > ,
160
+ } ,
161
+ ] ,
162
+ } ,
163
+ {
164
+ key : "devices" ,
165
+ label : "Devices" ,
166
+ children : [
167
+ {
168
+ key : "devices-create" , label : < Link to = { `/vendors/${ vendor } /devices/create` } > Add device</ Link > ,
169
+ } ,
170
+ ] . concat ( devices . map ( ( v ) => {
171
+ return {
172
+ key : "devices-" + v . getFile ( ) ,
173
+ label : < Link to = { `/vendors/${ vendor } /devices/${ v . getFile ( ) } ` } > { v . getFile ( ) } </ Link > ,
174
+ } ;
175
+ } ) ) ,
176
+ } ,
177
+ {
178
+ key : "profiles" ,
179
+ label : "Profiles" ,
180
+ children : [
181
+ {
182
+ key : "profiles-create" ,
183
+ label : < Link to = { `/vendors/${ vendor } /profiles/create` } > Add profile</ Link > ,
184
+ } ,
185
+ ] . concat ( profiles . map ( ( v ) => {
186
+ return {
187
+ key : "profiles-" + v . getFile ( ) ,
188
+ label : < Link to = { `/vendors/${ vendor } /profiles/${ v . getFile ( ) } ` } > { v . getFile ( ) } </ Link > ,
189
+ } ;
190
+ } ) ) ,
191
+ } ,
192
+ {
193
+ key : "codecs" , label : "Codecs" , children : [
194
+ {
195
+ key : "codecs-create" ,
196
+ label : < Link to = { `/vendors/${ vendor } /codecs/create` } > Add codec</ Link > ,
197
+ } ,
198
+ ] . concat ( codecs . map ( ( v ) => {
199
+ return {
200
+ key : "codecs-" + v . getFile ( ) ,
201
+ label : < Link to = { `/vendors/${ vendor } /codecs/${ v . getFile ( ) } ` } > { v . getFile ( ) } </ Link > ,
202
+ } ;
203
+ } ) )
90
204
} ,
91
- { key : "profiles" , label : < Link to = { `/vendors/${ vendor } /profiles` } > Profiles</ Link > } ,
92
- { key : "codecs" , label : < Link to = { `/vendors/${ vendor } /codecs` } > Codecs</ Link > } ,
93
205
] ;
94
206
95
207
return ( < div >
96
208
< Select showSearch allowClear placeholder = "Select vendor" options = { vendorOptions } value = { vendor } className = "vendor-select" onSelect = { onVendorSelect } onClear = { onVendorClear } />
97
209
{ vendor ? < Menu
98
210
items = { items }
99
211
selectedKeys = { [ selectedKey ] }
212
+ mode = "inline"
100
213
/> : < Link to = "/vendors/add" > < Button className = "vendor-add" type = "primary" > Add vendor</ Button > </ Link > }
101
214
</ div > ) ;
102
215
}
0 commit comments