1
1
<script >
2
- import { mapGetters , mapActions } from ' vuex' ;
2
+ import { computed , ref , toRef , watch } from ' vue' ;
3
+ import { mapActions , useStore } from ' vuex' ;
4
+
3
5
import { get , set } from ' @shell/utils/object' ;
4
6
import { sortBy } from ' @shell/utils/sort' ;
5
7
import { NAMESPACE } from ' @shell/config/types' ;
@@ -8,6 +10,7 @@ import { _VIEW, _EDIT, _CREATE } from '@shell/config/query-params';
8
10
import { LabeledInput } from ' @components/Form/LabeledInput' ;
9
11
import LabeledSelect from ' @shell/components/form/LabeledSelect' ;
10
12
import { normalizeName } from ' @shell/utils/kube' ;
13
+ import { useI18n } from ' @shell/composables/useI18n' ;
11
14
12
15
export default {
13
16
name: ' NameNsDescription' ,
@@ -169,106 +172,97 @@ export default {
169
172
},
170
173
171
174
data () {
172
- return {
173
- namespace: ' ' ,
174
- name: ' ' ,
175
- description: ' ' ,
176
- createNamespace: false ,
177
- };
175
+ return { createNamespace: false };
178
176
},
179
177
180
- created () {
181
- const v = this .value ;
182
- const metadata = v .metadata ;
183
- let namespace, name, description;
184
-
185
- if (this .nameKey ) {
186
- name = get (v, this .nameKey );
187
- } else {
188
- name = metadata? .name ;
189
- }
178
+ setup (props , { emit }) {
179
+ const v = toRef (props .value );
180
+ const metadata = v .value .metadata ;
181
+ const namespace = ref (null );
182
+ const name = ref (null );
183
+ const description = ref (null );
190
184
191
- if (this .namespaced ) {
192
- if (this .forceNamespace ) {
193
- namespace = this .forceNamespace ;
194
- this .updateNamespace (namespace);
195
- } else if (this .namespaceKey ) {
196
- namespace = get (v, this .namespaceKey );
197
- } else {
198
- namespace = metadata? .namespace ;
185
+ watch (name, (val ) => {
186
+ if (props .normalizeName ) {
187
+ val = normalizeName (val);
199
188
}
200
189
201
- if (! namespace && ! this .noDefaultNamespace ) {
202
- namespace = this .$store .getters [' defaultNamespace' ];
203
- if (metadata) {
204
- metadata .namespace = namespace;
205
- }
190
+ if (props .nameKey ) {
191
+ set (props .value , props .nameKey , val);
192
+ } else {
193
+ props .value .metadata [' name' ] = val;
206
194
}
207
- }
195
+ emit (' update:value' , props .value );
196
+ });
208
197
209
- if (this . descriptionKey ) {
210
- description = get (v, this . descriptionKey );
198
+ if (props . nameKey ) {
199
+ name . value = get (v, props . nameKey );
211
200
} else {
212
- description = metadata? .annotations ? .[ DESCRIPTION ] ;
201
+ name . value = metadata? .name || ' ' ;
213
202
}
214
203
215
- this .namespace = namespace;
216
- this .name = name;
217
- this .description = description;
218
- },
204
+ const isCreate = computed (() => {
205
+ return props .mode === _CREATE ;
206
+ });
219
207
220
- computed: {
221
- ... mapGetters ([' currentProduct' , ' currentCluster' , ' namespaces' , ' allowedNamespaces' ]),
222
- ... mapActions (' cru-resource' , [' setCreateNamespace' ]),
223
- namespaceReallyDisabled () {
224
- return (
225
- !! this .forceNamespace || this .namespaceDisabled || this .mode === _EDIT
226
- ); // namespace is never editable
227
- },
208
+ const store = useStore ();
209
+ const { t } = useI18n (store);
210
+ const allowedNamespaces = computed (() => store .getters .allowedNamespaces ());
211
+ const storeNamespaces = computed (() => store .getters .namespaces ());
212
+ const currentCluster = computed (() => store .getters .currentCluster );
228
213
229
- nameReallyDisabled () {
230
- return this .nameDisabled || (this .mode === _EDIT && ! this .nameEditable );
231
- },
214
+ const inStore = computed (() => {
215
+ return store .getters [' currentStore' ]();
216
+ });
217
+
218
+ const nsSchema = computed (() => {
219
+ return store .getters [` ${ inStore .value } /schemaFor` ](NAMESPACE );
220
+ });
221
+
222
+ const canCreateNamespace = computed (() => {
223
+ // Check if user can push to namespaces... and as the ns is outside of a project restrict to admins and cluster owners
224
+ return (nsSchema .value ? .collectionMethods || []).includes (' POST' ) && currentCluster .value ? .canUpdate ;
225
+ });
232
226
233
227
/**
234
228
* Map namespaces from the store to options, adding divider and create button
235
229
*/
236
- options () {
230
+ const options = computed (() => {
237
231
let namespaces;
238
232
239
- if (this .namespacesOverride ) {
233
+ if (props .namespacesOverride ) {
240
234
// Use the resources provided
241
- namespaces = this .namespacesOverride ;
235
+ namespaces = props .namespacesOverride ;
242
236
} else {
243
- if (this .namespaceOptions ) {
237
+ if (props .namespaceOptions ) {
244
238
// Use the namespaces provided
245
- namespaces = (this .namespaceOptions .map ((ns ) => ns .name ) || []).sort ();
239
+ namespaces = (props .namespaceOptions .map ((ns ) => ns .name ) || []).sort ();
246
240
} else {
247
241
// Determine the namespaces
248
- const namespaceObjs = this . isCreate ? this . allowedNamespaces () : this . namespaces () ;
242
+ const namespaceObjs = isCreate . value ? allowedNamespaces . value : storeNamespaces . value ;
249
243
250
244
namespaces = Object .keys (namespaceObjs);
251
245
}
252
246
}
253
247
254
248
const options = namespaces
255
249
.map ((namespace ) => ({ nameDisplay: namespace, id: namespace }))
256
- .map (this .namespaceMapper || ((obj ) => ({
250
+ .map (props .namespaceMapper || ((obj ) => ({
257
251
label: obj .nameDisplay ,
258
252
value: obj .id ,
259
253
})));
260
254
261
255
const sortedByLabel = sortBy (options, ' label' );
262
256
263
- if (this .forceNamespace ) {
257
+ if (props .forceNamespace ) {
264
258
sortedByLabel .unshift ({
265
- label: this .forceNamespace ,
266
- value: this .forceNamespace ,
259
+ label: props .forceNamespace ,
260
+ value: props .forceNamespace ,
267
261
});
268
262
}
269
263
270
264
const createButton = {
271
- label: this . t (' namespace.createNamespace' ),
265
+ label: t (' namespace.createNamespace' ),
272
266
value: ' ' ,
273
267
kind: ' highlighted'
274
268
};
@@ -278,20 +272,78 @@ export default {
278
272
kind: ' divider'
279
273
};
280
274
281
- const createOverhead = this . canCreateNamespace || this .createNamespaceOverride ? [createButton, divider] : [];
275
+ const createOverhead = canCreateNamespace . value || props .createNamespaceOverride ? [createButton, divider] : [];
282
276
283
277
return [
284
278
... createOverhead,
285
279
... sortedByLabel
286
280
];
281
+ });
282
+
283
+ const updateNamespace = (val ) => {
284
+ if (props .forceNamespace ) {
285
+ val = props .forceNamespace ;
286
+ }
287
+
288
+ if (props .namespaced ) {
289
+ emit (' isNamespaceNew' , ! val || (options .value && ! options .value .find ((n ) => n .value === val)));
290
+ }
291
+
292
+ if (props .namespaceKey ) {
293
+ set (props .value , props .namespaceKey , val);
294
+ } else {
295
+ props .value .metadata .namespace = val;
296
+ }
297
+ };
298
+
299
+ if (props .namespaced ) {
300
+ if (props .forceNamespace ) {
301
+ namespace .value = toRef (props .forceNamespace );
302
+ updateNamespace (namespace);
303
+ } else if (props .namespaceKey ) {
304
+ namespace .value = get (v, props .namespaceKey );
305
+ } else {
306
+ namespace .value = metadata? .namespace ;
307
+ }
308
+
309
+ if (! namespace .value && ! this .noDefaultNamespace ) {
310
+ namespace .value = store .getters [' defaultNamespace' ];
311
+ if (metadata) {
312
+ metadata .namespace = namespace;
313
+ }
314
+ }
315
+ }
316
+
317
+ if (props .descriptionKey ) {
318
+ description .value = get (v, props .descriptionKey );
319
+ } else {
320
+ description .value = metadata? .annotations ? .[DESCRIPTION ];
321
+ }
322
+
323
+ return {
324
+ namespace,
325
+ name,
326
+ description,
327
+ isCreate,
328
+ options,
329
+ updateNamespace,
330
+ };
331
+ },
332
+
333
+ computed: {
334
+ ... mapActions (' cru-resource' , [' setCreateNamespace' ]),
335
+ namespaceReallyDisabled () {
336
+ return (
337
+ !! this .forceNamespace || this .namespaceDisabled || this .mode === _EDIT
338
+ ); // namespace is never editable
287
339
},
288
340
289
- isView () {
290
- return this .mode === _VIEW ;
341
+ nameReallyDisabled () {
342
+ return this .nameDisabled || ( this . mode === _EDIT && ! this . nameEditable ) ;
291
343
},
292
344
293
- isCreate () {
294
- return this .mode === _CREATE ;
345
+ isView () {
346
+ return this .mode === _VIEW ;
295
347
},
296
348
297
349
showCustomize () {
@@ -310,35 +362,9 @@ export default {
310
362
311
363
return ` span-${ span } ` ;
312
364
},
313
-
314
- inStore () {
315
- return this .$store .getters [' currentStore' ]();
316
- },
317
-
318
- nsSchema () {
319
- return this .$store .getters [` ${ this .inStore } /schemaFor` ](NAMESPACE );
320
- },
321
-
322
- canCreateNamespace () {
323
- // Check if user can push to namespaces... and as the ns is outside of a project restrict to admins and cluster owners
324
- return (this .nsSchema ? .collectionMethods || []).includes (' POST' ) && this .currentCluster ? .canUpdate ;
325
- }
326
365
},
327
366
328
367
watch: {
329
- name (val ) {
330
- if (this .normalizeName ) {
331
- val = normalizeName (val);
332
- }
333
-
334
- if (this .nameKey ) {
335
- set (this .value , this .nameKey , val);
336
- } else {
337
- this .value .metadata [' name' ] = val;
338
- }
339
- this .$emit (' update:value' , this .value );
340
- },
341
-
342
368
namespace (val ) {
343
369
this .updateNamespace (val);
344
370
this .$emit (' update:value' , this .value );
@@ -356,29 +382,13 @@ export default {
356
382
357
383
mounted () {
358
384
this .$nextTick (() => {
359
- if (this .$refs .name ) {
360
- this .$refs .name .focus ();
385
+ if (this .$refs .nameInput ) {
386
+ this .$refs .nameInput .focus ();
361
387
}
362
388
});
363
389
},
364
390
365
391
methods: {
366
- updateNamespace (val ) {
367
- if (this .forceNamespace ) {
368
- val = this .forceNamespace ;
369
- }
370
-
371
- if (this .namespaced ) {
372
- this .$emit (' isNamespaceNew' , ! val || (this .options && ! this .options .find ((n ) => n .value === val)));
373
- }
374
-
375
- if (this .namespaceKey ) {
376
- set (this .value , this .namespaceKey , val);
377
- } else {
378
- this .value .metadata .namespace = val;
379
- }
380
- },
381
-
382
392
changeNameAndNamespace (e ) {
383
393
this .name = (e .text || ' ' ).toLowerCase ();
384
394
this .namespace = e .selected ;
@@ -399,7 +409,7 @@ export default {
399
409
true ,
400
410
);
401
411
this .$emit (' isNamespaceNew' , true );
402
- this .$nextTick (() => this .$refs .namespace .focus ());
412
+ this .$nextTick (() => this .$refs .namespaceInput .focus ());
403
413
} else {
404
414
this .createNamespace = false ;
405
415
this .$store .dispatch (
@@ -421,7 +431,7 @@ export default {
421
431
class = " col span-3"
422
432
>
423
433
< LabeledInput
424
- ref= " namespace "
434
+ ref= " namespaceInput "
425
435
v- model: value= " namespace"
426
436
: label= " t('namespace.label')"
427
437
: placeholder= " t('namespace.createNamespace')"
@@ -469,7 +479,7 @@ export default {
469
479
class = " col span-3"
470
480
>
471
481
< LabeledInput
472
- ref= " name "
482
+ ref= " nameInput "
473
483
key= " name"
474
484
v- model: value= " name"
475
485
: label= " t(nameLabel)"
@@ -483,7 +493,6 @@ export default {
483
493
< / div>
484
494
485
495
< slot name= " customize" / >
486
- <!-- // TODO: here goes the custom component -->
487
496
< div
488
497
v- show= " !descriptionHidden"
489
498
: data- testid= " componentTestid + '-description'"
0 commit comments