@@ -17,6 +17,8 @@ import {
17
17
TAPApiDisplayList
18
18
} from "../../../../displayServices/APApisDisplayService" ;
19
19
import APAdminPortalApisDisplayService from "../../../displayServices/APAdminPortalApisDisplayService" ;
20
+ import { OrganizationContext } from "../../../../components/APContextProviders/APOrganizationContextProvider" ;
21
+ import APOrganizationsDisplayService from "../../../../displayServices/APOrganizationsDisplayService/APOrganizationsDisplayService" ;
20
22
21
23
import '../../../../components/APComponents.css' ;
22
24
import "../ManageApiProducts.css" ;
@@ -36,14 +38,21 @@ export const SearchSelectApis: React.FC<ISearchSelectApisProps> = (props: ISearc
36
38
type TManagedObject = TAPApiDisplay ;
37
39
type TManagedObjectList = Array < TManagedObject > ;
38
40
39
- const DialogHeader = 'Search & Select API(s):' ;
41
+ const DialogHeaderPlural = 'Search & Select API(s):' ;
42
+ const DialogHeaderSingular = 'Search & Select one API:' ;
40
43
const MessageNoManagedObjectsFound = "No APIs found."
41
44
const MessageNoManagedObjectsFoundWithFilter = 'No APIs found for filter' ;
42
45
// const GlobalSearchPlaceholder = 'Enter search word list separated by <space> ...';
43
46
const GlobalSearchPlaceholder = 'search...' ;
44
47
48
+ const [ organizationContext ] = React . useContext ( OrganizationContext ) ;
49
+
50
+ const isSingleSelection : boolean = organizationContext . apMaxNumApis_Per_ApiProduct === 1 ;
51
+
52
+ const [ isMaxExceeded , setIsMaxExceeded ] = React . useState < boolean > ( false ) ;
45
53
const [ managedObjectList , setManagedObjectList ] = React . useState < TManagedObjectList > ( ) ;
46
54
const [ selectedManagedObjectList , setSelectedManagedObjectList ] = React . useState < TManagedObjectList > ( ) ;
55
+ const [ selectedManagedObject , setSelectedManagedObject ] = React . useState < TManagedObject > ( ) ;
47
56
const [ isInitialialized , setIsInitialized ] = React . useState < boolean > ( false ) ;
48
57
const [ apiCallStatus , setApiCallStatus ] = React . useState < TApiCallState | null > ( null ) ;
49
58
const [ globalFilter , setGlobalFilter ] = React . useState < string > ( ) ; // * Data Table *
@@ -79,16 +88,18 @@ export const SearchSelectApis: React.FC<ISearchSelectApisProps> = (props: ISearc
79
88
80
89
React . useEffect ( ( ) => {
81
90
if ( managedObjectList === undefined ) return ;
82
- setSelectedManagedObjectList ( APEntityIdsService . create_ApDisplayObjectList_FilteredBy_EntityIdList ( {
91
+ const selectedList : TAPApiDisplayList = APEntityIdsService . create_ApDisplayObjectList_FilteredBy_EntityIdList ( {
83
92
apDisplayObjectList : managedObjectList ,
84
93
filterByEntityIdList : props . selectedApiEntityIdList
85
- } ) ) ;
94
+ } ) ;
95
+ if ( isSingleSelection && selectedList . length > 0 ) setSelectedManagedObject ( selectedList [ 0 ] ) ;
96
+ setSelectedManagedObjectList ( selectedList ) ;
86
97
} , [ managedObjectList ] ) ; /* eslint-disable-line react-hooks/exhaustive-deps */
87
98
88
99
React . useEffect ( ( ) => {
89
100
if ( selectedManagedObjectList === undefined ) return ;
90
101
setIsInitialized ( true ) ;
91
- } , [ selectedManagedObjectList ] ) ; /* eslint-disable-line react-hooks/exhaustive-deps */
102
+ } , [ selectedManagedObjectList , selectedManagedObject ] ) ; /* eslint-disable-line react-hooks/exhaustive-deps */
92
103
93
104
React . useEffect ( ( ) => {
94
105
if ( apiCallStatus !== null ) {
@@ -101,8 +112,13 @@ export const SearchSelectApis: React.FC<ISearchSelectApisProps> = (props: ISearc
101
112
const onSaveSelectedApis = ( ) => {
102
113
const funcName = 'onSaveSelectedApis' ;
103
114
const logName = `${ ComponentName } .${ funcName } ()` ;
104
- if ( selectedManagedObjectList === undefined ) throw new Error ( `${ logName } : selectedManagedObjectList === undefined` ) ;
105
- props . onSave ( selectedManagedObjectList ) ;
115
+ if ( isSingleSelection ) {
116
+ if ( selectedManagedObject === undefined ) throw new Error ( `${ logName } : isSingleSelection && selectedManagedObject === undefined` ) ;
117
+ props . onSave ( [ selectedManagedObject ] ) ;
118
+ } else {
119
+ if ( selectedManagedObjectList === undefined ) throw new Error ( `${ logName } : selectedManagedObjectList === undefined` ) ;
120
+ props . onSave ( selectedManagedObjectList ) ;
121
+ }
106
122
}
107
123
108
124
// * Data Table *
@@ -115,7 +131,8 @@ export const SearchSelectApis: React.FC<ISearchSelectApisProps> = (props: ISearc
115
131
const funcName = 'renderDataTableHeader' ;
116
132
const logName = `${ ComponentName } .${ funcName } ()` ;
117
133
if ( selectedManagedObjectList === undefined ) throw new Error ( `${ logName } : selectedManagedObjectList === undefined` ) ;
118
- const isSaveDisabled : boolean = selectedManagedObjectList . length === 0 ;
134
+ // const isSaveDisabled: boolean = selectedManagedObjectList.length === 0;
135
+ const isSaveDisabled : boolean = isSingleSelection ? selectedManagedObject === undefined : selectedManagedObjectList . length === 0 ;
119
136
return (
120
137
< div className = "table-header" >
121
138
< div style = { { whiteSpace : "nowrap" } } >
@@ -137,69 +154,141 @@ export const SearchSelectApis: React.FC<ISearchSelectApisProps> = (props: ISearc
137
154
) ;
138
155
}
139
156
140
- const onSelectionChange = ( event : any ) : void => {
141
- setSelectedManagedObjectList ( event . value ) ;
157
+ const onListSelectionChange = ( event : any ) : void => {
158
+ const moList : TManagedObjectList = event . value ;
159
+ if ( APOrganizationsDisplayService . is_NumApis_Per_ApiProduct_Limited ( organizationContext . apMaxNumApis_Per_ApiProduct ) ) {
160
+ if ( moList . length > organizationContext . apMaxNumApis_Per_ApiProduct ) setIsMaxExceeded ( true ) ;
161
+ else {
162
+ setIsMaxExceeded ( false ) ;
163
+ setSelectedManagedObjectList ( event . value ) ;
164
+ }
165
+ } else {
166
+ setIsMaxExceeded ( false ) ;
167
+ setSelectedManagedObjectList ( event . value ) ;
168
+ }
169
+ }
170
+
171
+ const onSingleSelectionChange = ( event : any ) : void => {
172
+ setSelectedManagedObject ( event . value ) ;
142
173
}
143
174
144
175
const renderManagedObjectTableEmptyMessage = ( ) => {
145
176
if ( globalFilter && globalFilter !== '' ) return `${ MessageNoManagedObjectsFoundWithFilter } : ${ globalFilter } .` ;
146
177
else return MessageNoManagedObjectsFound ;
147
178
}
148
179
149
- const renderManagedObjectDataTable = ( ) : JSX . Element => {
180
+ const renderManagedObjectDataTableMultiple = ( ) : JSX . Element => {
150
181
const dataKey = APAdminPortalApisDisplayService . nameOf_ApEntityId ( 'id' ) ;
151
182
const sortField = APAdminPortalApisDisplayService . nameOf_ApEntityId ( 'displayName' ) ;
152
183
return (
153
- < div className = "card" >
154
- < DataTable
155
- ref = { dt }
156
- className = "p-datatable-sm"
157
- autoLayout = { true }
158
- resizableColumns
159
- columnResizeMode = "fit"
160
- showGridlines = { false }
161
- header = { renderDataTableHeader ( ) }
162
- value = { managedObjectList }
163
- globalFilter = { globalFilter }
164
- scrollable
165
- scrollHeight = "800px"
166
- dataKey = { dataKey }
167
- emptyMessage = { renderManagedObjectTableEmptyMessage ( ) }
168
- // selection
169
- selection = { selectedManagedObjectList }
170
- onSelectionChange = { onSelectionChange }
171
- // sorting
172
- sortMode = 'single'
173
- sortField = { sortField }
174
- sortOrder = { 1 }
175
- >
176
- < Column selectionMode = "multiple" style = { { width :'3em' } } />
177
- < Column header = "Name" field = { sortField } filterField = "apSearchContent" sortable />
178
- < Column header = "Service Name" field = "connectorEnvironmentResponse.serviceName" sortable />
179
- < Column header = "Msg Vpn Name" field = "connectorEnvironmentResponse.msgVpnName" sortable />
180
- < Column header = "Datacenter Provider" field = "connectorEnvironmentResponse.datacenterProvider" sortable />
181
- { /* <Column header="Description" field="connectorEnvironmentResponse.description" /> */ }
184
+ < div className = "card p-mt-2 " >
185
+ < DataTable
186
+ ref = { dt }
187
+ className = "p-datatable-sm"
188
+ autoLayout = { true }
189
+ resizableColumns
190
+ columnResizeMode = "fit"
191
+ showGridlines = { false }
192
+ header = { renderDataTableHeader ( ) }
193
+ value = { managedObjectList }
194
+ globalFilter = { globalFilter }
195
+ scrollable
196
+ scrollHeight = "800px"
197
+ dataKey = { dataKey }
198
+ emptyMessage = { renderManagedObjectTableEmptyMessage ( ) }
199
+ // selection
200
+ selection = { selectedManagedObjectList }
201
+ onSelectionChange = { onListSelectionChange }
202
+ // sorting
203
+ sortMode = 'single'
204
+ sortField = { sortField }
205
+ sortOrder = { 1 }
206
+ >
207
+ < Column selectionMode = "multiple" style = { { width :'3em' } } />
208
+ < Column header = "Name" field = { sortField } filterField = "apSearchContent" sortable />
209
+ < Column header = "Service Name" field = "connectorEnvironmentResponse.serviceName" sortable />
210
+ < Column header = "Msg Vpn Name" field = "connectorEnvironmentResponse.msgVpnName" sortable />
211
+ < Column header = "Datacenter Provider" field = "connectorEnvironmentResponse.datacenterProvider" sortable />
212
+ { /* <Column header="Description" field="connectorEnvironmentResponse.description" /> */ }
182
213
</ DataTable >
183
214
</ div >
184
215
) ;
185
216
}
186
217
218
+ const renderManagedObjectDataTableSingle = ( ) : JSX . Element => {
219
+ const dataKey = APAdminPortalApisDisplayService . nameOf_ApEntityId ( 'id' ) ;
220
+ const sortField = APAdminPortalApisDisplayService . nameOf_ApEntityId ( 'displayName' ) ;
221
+ return (
222
+ < div className = "card p-mt-2" >
223
+ < DataTable
224
+ ref = { dt }
225
+ className = "p-datatable-sm"
226
+ autoLayout = { true }
227
+ resizableColumns
228
+ columnResizeMode = "fit"
229
+ showGridlines = { false }
230
+ header = { renderDataTableHeader ( ) }
231
+ value = { managedObjectList }
232
+ globalFilter = { globalFilter }
233
+ scrollable
234
+ scrollHeight = "800px"
235
+ dataKey = { dataKey }
236
+ emptyMessage = { renderManagedObjectTableEmptyMessage ( ) }
237
+ // selection
238
+ selectionMode = "single"
239
+ selection = { selectedManagedObject }
240
+ onSelectionChange = { onSingleSelectionChange }
241
+ // sorting
242
+ sortMode = 'single'
243
+ sortField = { sortField }
244
+ sortOrder = { 1 }
245
+ >
246
+ < Column header = "Name" field = { sortField } filterField = "apSearchContent" sortable />
247
+ < Column header = "Service Name" field = "connectorEnvironmentResponse.serviceName" sortable />
248
+ < Column header = "Msg Vpn Name" field = "connectorEnvironmentResponse.msgVpnName" sortable />
249
+ < Column header = "Datacenter Provider" field = "connectorEnvironmentResponse.datacenterProvider" sortable />
250
+ { /* <Column header="Description" field="connectorEnvironmentResponse.description" /> */ }
251
+ </ DataTable >
252
+ </ div >
253
+ ) ;
254
+ }
255
+
256
+ const renderManagedObjectDataTable = ( ) : JSX . Element => {
257
+ if ( isSingleSelection ) return renderManagedObjectDataTableSingle ( ) ;
258
+ else return renderManagedObjectDataTableMultiple ( ) ;
259
+ }
260
+
261
+ const renderHeader = ( ) => {
262
+ if ( isSingleSelection ) {
263
+ return (
264
+ < APComponentHeader header = { DialogHeaderSingular } />
265
+ ) ;
266
+ } else {
267
+ return (
268
+ < APComponentHeader header = { DialogHeaderPlural } />
269
+ ) ;
270
+ }
271
+ }
272
+
273
+ const renderMaxExceededMessage = ( ) => {
274
+ return (
275
+ < div style = { { color : 'red' } } >
276
+ Max number of APIs per API Product exceeded. Max: { organizationContext . apMaxNumApis_Per_ApiProduct } .
277
+ </ div >
278
+ )
279
+ }
280
+
187
281
return (
188
282
< div className = "manage-api-products" >
189
283
190
- < APComponentHeader header = { DialogHeader } />
284
+ { renderHeader ( ) }
285
+
286
+ { isMaxExceeded && renderMaxExceededMessage ( ) }
191
287
192
288
< ApiCallStatusError apiCallStatus = { apiCallStatus } />
193
289
194
290
{ isInitialialized && renderManagedObjectDataTable ( ) }
195
291
196
- { /* DEBUG */ }
197
- { /* {managedObjectTableDataList.length > 0 && selectedManagedObjectTableDataList &&
198
- <pre style={ { fontSize: '12px' }} >
199
- {JSON.stringify(selectedManagedObjectTableDataList, null, 2)}
200
- </pre>
201
- } */ }
202
-
203
292
</ div >
204
293
) ;
205
294
}
0 commit comments