@rancher/shell 0.3.5 → 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/assets/images/providers/outscale.svg +19 -0
  2. package/assets/styles/base/_basic.scss +18 -0
  3. package/assets/styles/base/_mixins.scss +0 -11
  4. package/assets/styles/base/_variables.scss +2 -4
  5. package/assets/styles/global/_button.scss +12 -2
  6. package/assets/translations/en-us.yaml +35 -1
  7. package/assets/translations/zh-hans.yaml +30 -10
  8. package/chart/gatekeeper.vue +3 -2
  9. package/chart/istio.vue +29 -3
  10. package/components/BrandImage.vue +1 -4
  11. package/components/Carousel.vue +85 -37
  12. package/components/EtcdInfoBanner.vue +7 -3
  13. package/components/ExplorerMembers.vue +100 -5
  14. package/components/ExplorerProjectsNamespaces.vue +32 -2
  15. package/components/GrafanaDashboard.vue +9 -2
  16. package/components/SortableTable/index.vue +23 -11
  17. package/components/SortableTable/selection.js +58 -50
  18. package/components/Wizard.vue +4 -2
  19. package/components/auth/AuthBanner.vue +6 -0
  20. package/components/auth/RoleDetailEdit.vue +2 -2
  21. package/components/form/HookOption.vue +14 -10
  22. package/components/form/Labels.vue +32 -27
  23. package/components/form/MatchExpressions.vue +2 -2
  24. package/components/form/Members/ClusterPermissionsEditor.vue +32 -7
  25. package/components/form/NameNsDescription.vue +1 -1
  26. package/components/form/ProjectMemberEditor.vue +46 -21
  27. package/components/form/Tolerations.vue +4 -1
  28. package/components/form/ValueFromResource.vue +14 -9
  29. package/components/form/WorkloadPorts.vue +2 -2
  30. package/components/form/__tests__/NameNsDescription.ts +27 -0
  31. package/components/formatter/WorkloadHealthScale.vue +8 -2
  32. package/components/nav/NamespaceFilter.vue +8 -0
  33. package/{nuxt/components → components/nuxt}/nuxt.js +1 -1
  34. package/{nuxt → config}/middleware.js +8 -8
  35. package/config/product/explorer.js +24 -3
  36. package/config/query-params.js +1 -0
  37. package/config/router.js +1 -1
  38. package/{nuxt → config}/store.js +82 -79
  39. package/config/table-headers.js +46 -12
  40. package/config/types.js +7 -0
  41. package/core/plugin.ts +4 -2
  42. package/core/types.ts +258 -1
  43. package/creators/app/files/tsconfig.json +0 -1
  44. package/creators/app/files/vue.config.js +0 -1
  45. package/creators/pkg/files/.github/workflows/build-extension.yml +3 -4
  46. package/creators/pkg/files/tsconfig.json +0 -1
  47. package/creators/pkg/pkg.package.json +3 -3
  48. package/detail/constraints.gatekeeper.sh.constraint.vue +14 -7
  49. package/detail/fleet.cattle.io.clustergroup.vue +7 -1
  50. package/edit/auth/ldap/config.vue +21 -1
  51. package/edit/auth/saml.vue +132 -37
  52. package/edit/fleet.cattle.io.gitrepo.vue +16 -1
  53. package/edit/logging.banzaicloud.io.output/index.vue +18 -5
  54. package/edit/logging.banzaicloud.io.output/providers/loki.vue +1 -0
  55. package/edit/namespace.vue +12 -8
  56. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +11 -4
  57. package/edit/provisioning.cattle.io.cluster/import.vue +23 -25
  58. package/edit/provisioning.cattle.io.cluster/rke2.vue +96 -18
  59. package/edit/workload/mixins/workload.js +6 -7
  60. package/edit/workload/storage/Mount.vue +3 -3
  61. package/initialize/App.js +206 -0
  62. package/{nuxt → initialize}/client.js +406 -360
  63. package/{nuxt → initialize}/index.js +21 -22
  64. package/layouts/standalone.vue +13 -0
  65. package/list/catalog.cattle.io.clusterrepo.vue +1 -0
  66. package/list/rbac.authorization.k8s.io.clusterrolebinding.vue +48 -0
  67. package/list/workload.vue +6 -4
  68. package/mixins/chart.js +29 -1
  69. package/mixins/fetch.client.js +95 -0
  70. package/{nuxt/mixins → mixins}/fetch.server.js +30 -26
  71. package/mixins/labeled-form-element.ts +2 -2
  72. package/models/constraints.gatekeeper.sh.constraint.js +37 -0
  73. package/models/pod.js +4 -0
  74. package/models/rbac.authorization.k8s.io.clusterrolebinding.js +16 -0
  75. package/models/rbac.authorization.k8s.io.rolebinding.js +16 -0
  76. package/package.json +9 -13
  77. package/pages/c/_cluster/apps/charts/install.vue +61 -39
  78. package/pages/diagnostic.vue +32 -25
  79. package/pages/rio/mesh.vue +1 -2
  80. package/pkg/tsconfig.json +0 -1
  81. package/plugins/clean-html-directive.js +3 -0
  82. package/plugins/dashboard-store/index.js +1 -1
  83. package/plugins/plugin.js +0 -14
  84. package/plugins/portal-vue.js +4 -0
  85. package/rancher-components/components/Banner/Banner.test.ts +3 -5
  86. package/rancher-components/components/Banner/Banner.vue +1 -0
  87. package/rancher-components/components/Form/Radio/RadioButton.test.ts +31 -0
  88. package/rancher-components/components/Form/Radio/RadioButton.vue +14 -3
  89. package/scripts/extension/publish +42 -23
  90. package/scripts/serve-pkgs +6 -2
  91. package/store/type-map.js +1 -1
  92. package/tsconfig.json +0 -1
  93. package/types/rancher/index.d.ts +2 -0
  94. package/types/shell/index.d.ts +353 -284
  95. package/utils/__tests__/grafana.test.ts +44 -0
  96. package/utils/axios.js +190 -0
  97. package/{nuxt → utils}/cookie-universal-nuxt.js +7 -6
  98. package/utils/dom.js +15 -0
  99. package/utils/gc/gc.ts +1 -1
  100. package/utils/grafana.js +35 -16
  101. package/{nuxt/utils.js → utils/nuxt.js} +265 -236
  102. package/utils/router.scrollBehavior.js +1 -1
  103. package/vue.config.js +30 -19
  104. package/nuxt/App.js +0 -210
  105. package/nuxt/axios.js +0 -186
  106. package/nuxt/empty.js +0 -1
  107. package/nuxt/jsonp.js +0 -82
  108. package/nuxt/loading.html +0 -39
  109. package/nuxt/mixins/fetch.client.js +0 -90
  110. package/nuxt/portal-vue.js +0 -4
  111. package/nuxt/server.js +0 -312
  112. package/nuxt/views/app.template.html +0 -9
  113. package/nuxt/views/error.html +0 -23
  114. package/plugins/dashboard-store/extensions.js +0 -22
  115. /package/{nuxt/components → components/nuxt}/nuxt-build-indicator.vue +0 -0
  116. /package/{nuxt/components → components/nuxt}/nuxt-child.js +0 -0
  117. /package/{nuxt/components → components/nuxt}/nuxt-error.vue +0 -0
  118. /package/{nuxt/components → components/nuxt}/nuxt-link.client.js +0 -0
  119. /package/{nuxt/components → components/nuxt}/nuxt-link.server.js +0 -0
  120. /package/{nuxt/components → components/nuxt}/nuxt-loading.vue +0 -0
@@ -1,7 +1,7 @@
1
- import $ from 'jquery';
2
1
  import { isMore, isRange, suppressContextMenu, isAlternate } from '@shell/utils/platform';
3
2
  import { get } from '@shell/utils/object';
4
3
  import { filterBy } from '@shell/utils/array';
4
+ import { getParent } from '@shell/utils/dom';
5
5
 
6
6
  export const ALL = 'all';
7
7
  export const SOME = 'some';
@@ -9,23 +9,23 @@ export const NONE = 'none';
9
9
 
10
10
  export default {
11
11
  mounted() {
12
- const $table = $('> TABLE', this.$el);
12
+ const table = this.$el.querySelector('TABLE');
13
13
 
14
14
  this._onRowClickBound = this.onRowClick.bind(this);
15
15
  this._onRowMousedownBound = this.onRowMousedown.bind(this);
16
16
  this._onRowContextBound = this.onRowContext.bind(this);
17
17
 
18
- $table.on('click', '> TBODY > TR', this._onRowClickBound);
19
- $table.on('mousedown', '> TBODY > TR', this._onRowMousedownBound);
20
- $table.on('contextmenu', '> TBODY > TR', this._onRowContextBound);
18
+ table.addEventListener('click', this._onRowClickBound);
19
+ table.addEventListener('mousedown', this._onRowMousedownBound);
20
+ table.addEventListener('contextmenu', this._onRowContextBound);
21
21
  },
22
22
 
23
23
  beforeDestroy() {
24
- const $table = $('> TABLE', this.$el);
24
+ const table = this.$el.querySelector('TABLE');
25
25
 
26
- $table.off('click', '> TBODY > TR', this._onRowClickBound);
27
- $table.off('mousedown', '> TBODY > TR', this._onRowMousedownBound);
28
- $table.off('contextmenu', '> TBODY > TR', this._onRowContextBound);
26
+ table.removeEventListener('click', this._onRowClickBound);
27
+ table.removeEventListener('mousedown', this._onRowMousedownBound);
28
+ table.removeEventListener('contextmenu', this._onRowContextBound);
29
29
  },
30
30
 
31
31
  computed: {
@@ -156,31 +156,31 @@ export default {
156
156
  },
157
157
 
158
158
  onRowMouseEnter(e) {
159
- const tr = $(e.target).closest('TR');
159
+ const tr = e.target.closest('TR');
160
160
 
161
- if (tr.hasClass('sub-row')) {
162
- const trMainRow = tr.prev('TR');
161
+ if (tr.classList.contains('sub-row')) {
162
+ const trMainRow = tr.previousElementSibling;
163
163
 
164
- trMainRow.toggleClass('sub-row-hovered', true);
164
+ trMainRow.classList.add('sub-row-hovered');
165
165
  }
166
166
  },
167
167
 
168
168
  onRowMouseLeave(e) {
169
- const tr = $(e.target).closest('TR');
169
+ const tr = e.target.closest('TR');
170
170
 
171
- if (tr.hasClass('sub-row')) {
172
- const trMainRow = tr.prev('TR');
171
+ if (tr.classList.contains('sub-row')) {
172
+ const trMainRow = tr.previousElementSibling;
173
173
 
174
- trMainRow.toggleClass('sub-row-hovered', false);
174
+ trMainRow.classList.remove('sub-row-hovered');
175
175
  }
176
176
  },
177
177
 
178
178
  nodeForEvent(e) {
179
179
  const tagName = e.target.tagName;
180
- const tgt = $(e.target);
181
- const actionElement = tgt.closest('.actions')[0];
180
+ const tgt = e.target;
181
+ const actionElement = tgt.closest('.actions');
182
182
 
183
- if ( tgt.hasClass('select-all-check') ) {
183
+ if ( tgt.classList.contains('select-all-check') ) {
184
184
  return;
185
185
  }
186
186
 
@@ -188,31 +188,31 @@ export default {
188
188
  if (
189
189
  tagName === 'A' ||
190
190
  tagName === 'BUTTON' ||
191
- tgt.parents('.btn').length
191
+ getParent(tgt, '.btn')
192
192
  ) {
193
193
  return;
194
194
  }
195
195
  }
196
196
 
197
- const tgtRow = $(e.currentTarget);
197
+ const tgtRow = e.target.closest('TR');
198
198
 
199
199
  return this.nodeForRow(tgtRow);
200
200
  },
201
201
 
202
202
  nodeForRow(tgtRow) {
203
- if ( tgtRow?.hasClass('separator-row') ) {
203
+ if ( tgtRow?.classList.contains('separator-row') ) {
204
204
  return;
205
205
  }
206
206
 
207
- while ( tgtRow && tgtRow.length && !tgtRow.hasClass('main-row') ) {
208
- tgtRow = tgtRow.prev();
207
+ while ( tgtRow && !tgtRow.classList.contains('main-row') ) {
208
+ tgtRow = tgtRow.previousElementSibling;
209
209
  }
210
210
 
211
- if ( !tgtRow || !tgtRow.length ) {
211
+ if ( !tgtRow ) {
212
212
  return;
213
213
  }
214
214
 
215
- const nodeId = tgtRow.data('node-id');
215
+ const nodeId = tgtRow.dataset.nodeId;
216
216
 
217
217
  if ( !nodeId ) {
218
218
  return;
@@ -225,15 +225,15 @@ export default {
225
225
 
226
226
  async onRowClick(e) {
227
227
  const node = this.nodeForEvent(e);
228
- const td = $(e.target).closest('TD');
229
- const skipSelect = td.hasClass('skip-select');
228
+ const td = e.target.closest('TD');
229
+ const skipSelect = td?.classList.contains('skip-select');
230
230
 
231
231
  if (skipSelect) {
232
232
  return;
233
233
  }
234
234
  const selection = this.selectedRows;
235
- const isCheckbox = this.isSelectionCheckbox(e.target) || td.hasClass('row-check');
236
- const isExpand = td.hasClass('row-expand');
235
+ const isCheckbox = this.isSelectionCheckbox(e.target) || td?.classList.contains('row-check');
236
+ const isExpand = td?.classList.contains('row-expand');
237
237
  const content = this.pagedRows;
238
238
 
239
239
  this.$emit('rowClick', e);
@@ -248,28 +248,30 @@ export default {
248
248
  return;
249
249
  }
250
250
 
251
- const actionElement = $(e.target).closest('.actions')[0];
251
+ const actionElement = e.target.closest('.actions');
252
252
 
253
253
  if ( actionElement ) {
254
254
  let resources = [node];
255
255
 
256
256
  if ( this.mangleActionResources ) {
257
- const i = $('i', actionElement);
257
+ const i = actionElement.querySelector('i');
258
258
 
259
- i.removeClass('icon-actions');
260
- i.addClass(['icon-spinner', 'icon-spin']);
259
+ i.classList.remove('icon-actions');
260
+ i.classList.add('icon-spinner');
261
+ i.classList.add('icon-spin');
261
262
 
262
263
  try {
263
264
  resources = await this.mangleActionResources(resources);
264
265
  } finally {
265
- i.removeClass(['icon-spinner', 'icon-spin']);
266
- i.addClass('icon-actions');
266
+ i.classList.remove('icon-spinner');
267
+ i.classList.remove('icon-spin');
268
+ i.classList.add('icon-actions');
267
269
  }
268
270
  }
269
271
 
270
272
  this.$store.commit(`action-menu/show`, {
271
273
  resources,
272
- event: e.originalEvent || e, // Handle jQuery event and raw event
274
+ event: e,
273
275
  elem: actionElement
274
276
  });
275
277
 
@@ -332,7 +334,7 @@ export default {
332
334
 
333
335
  this.$store.commit(`action-menu/show`, {
334
336
  resources,
335
- event: e.originalEvent,
337
+ event: e,
336
338
  });
337
339
  },
338
340
 
@@ -356,7 +358,7 @@ export default {
356
358
  isSelectionCheckbox(element) {
357
359
  return element.tagName === 'INPUT' &&
358
360
  element.type === 'checkbox' &&
359
- ($(element).closest('.selection-checkbox').length > 0);
361
+ element.closest('.selection-checkbox') !== null;
360
362
  },
361
363
 
362
364
  nodesBetween(a, b) {
@@ -445,7 +447,9 @@ export default {
445
447
  }
446
448
  });
447
449
 
448
- this.selectedRows.push(...toAdd);
450
+ if ( toAdd ) {
451
+ this.selectedRows.push(...toAdd);
452
+ }
449
453
 
450
454
  // Uncheck and check the checkboxes of nodes that have been added/removed
451
455
  if (toRemove.length) {
@@ -474,20 +478,24 @@ export default {
474
478
 
475
479
  if ( id ) {
476
480
  // Note: This is looking for the checkbox control for the row
477
- const input = $(`div[data-checkbox-ctrl][data-node-id="${ id }"]`);
481
+ const input = this.$el.querySelector(`div[data-checkbox-ctrl][data-node-id="${ id }"]`);
478
482
 
479
- if ( input && input.length && !input[0].disabled ) {
480
- const label = $(input[0]).find('label');
483
+ if ( input && !input.disabled ) {
484
+ const label = input.querySelector('label');
481
485
 
482
486
  if (label) {
483
- label.prop('value', on);
487
+ label.value = on;
484
488
  }
485
489
  let tr = input.closest('tr');
486
490
  let first = true;
487
491
 
488
- while ( tr && (first || tr.hasClass('sub-row') ) ) {
489
- tr.toggleClass('row-selected', on);
490
- tr = tr.next();
492
+ while ( tr && (first || tr.classList.contains('sub-row') ) ) {
493
+ if (on) {
494
+ tr.classList.add('row-selected');
495
+ } else {
496
+ tr.classList.remove('row-selected');
497
+ }
498
+ tr = tr.nextElementSibling;
491
499
  first = false;
492
500
  }
493
501
  }
@@ -497,9 +505,9 @@ export default {
497
505
  select(nodes) {
498
506
  nodes.forEach((node) => {
499
507
  const id = get(node, this.keyField);
500
- const input = $(`label[data-node-id="${ id }"]`);
508
+ const input = this.$el.querySelector(`label[data-node-id="${ id }"]`);
501
509
 
502
- input.trigger('click');
510
+ input.dispatchEvent(new Event('click'));
503
511
  });
504
512
  },
505
513
 
@@ -468,6 +468,9 @@ $spacer: 10px;
468
468
  flex-direction: column;
469
469
  flex: 1;
470
470
  padding: 0;
471
+ height: 100%;
472
+ position: relative;
473
+ justify-content: flex-start;
471
474
  }
472
475
 
473
476
  .header {
@@ -643,9 +646,8 @@ $spacer: 10px;
643
646
  flex-direction: column;
644
647
 
645
648
  &__step {
646
- display: flex;
647
- flex-direction: column;
648
649
  flex: 1;
650
+ overflow: auto;
649
651
  }
650
652
  }
651
653
 
@@ -73,6 +73,12 @@ export default {
73
73
  >
74
74
  <slot name="rows" />
75
75
  </table>
76
+
77
+ <slot
78
+ v-if="$slots.footer"
79
+ name="footer"
80
+ />
81
+
76
82
  <DisableAuthProviderModal
77
83
  ref="disableAuthProviderModal"
78
84
  @disable="disable"
@@ -648,7 +648,7 @@ export default {
648
648
  </div>
649
649
  </template>
650
650
  <template #columns="props">
651
- <div class="columns row">
651
+ <div class="columns row mr-20">
652
652
  <div :class="ruleClass">
653
653
  <Select
654
654
  :value="props.row.value.verbs"
@@ -713,7 +713,7 @@ export default {
713
713
  :mode="mode"
714
714
  >
715
715
  <template #columns="props">
716
- <div class="columns row">
716
+ <div class="columns row mr-20">
717
717
  <div class="col span-12">
718
718
  <Select
719
719
  v-model="props.row.value"
@@ -202,16 +202,17 @@ export default {
202
202
  :mode="mode"
203
203
  />
204
204
  </template>
205
-
206
- <button
207
- v-if="!isView"
208
- type="button"
209
- class="btn role-link"
210
- :disabled="mode==='view'"
211
- @click.stop="removeHeader(index)"
212
- >
213
- <t k="generic.remove" />
214
- </button>
205
+ <div class="remove">
206
+ <button
207
+ v-if="!isView"
208
+ type="button"
209
+ class="btn role-link ml0"
210
+ :disabled="mode==='view'"
211
+ @click.stop="removeHeader(index)"
212
+ >
213
+ <t k="generic.remove" />
214
+ </button>
215
+ </div>
215
216
  </div>
216
217
 
217
218
  <div>
@@ -244,5 +245,8 @@ export default {
244
245
  .labeled-select {
245
246
  min-height: $input-height;
246
247
  }
248
+ .remove BUTTON {
249
+ padding: 0px;
250
+ }
247
251
  }
248
252
  </style>
@@ -58,38 +58,43 @@ export default {
58
58
  return `${ this.displaySideBySide ? 'col span-6' : 'row' } ${ this.defaultSectionClass }`.trim();
59
59
  },
60
60
 
61
+ columnsClass() {
62
+ return `${ this.displaySideBySide ? 'col span-6' : 'row' }`.trim();
63
+ }
61
64
  }
62
65
  };
63
66
  </script>
64
67
  <template>
65
68
  <div :class="containerClass">
66
- <div class="labels">
67
- <div class="labels__header">
68
- <h3>
69
- <t k="labels.labels.title" />
70
- </h3>
71
- <ToggleSwitch
72
- v-if="value.hasSystemLabels"
73
- v-model="toggler"
74
- name="label-system-toggle"
75
- :on-label="t('labels.labels.show')"
76
- />
77
- </div>
78
- <p class="mt-10 mb-10">
79
- <t k="labels.labels.description" />
80
- </p>
81
- <div :class="sectionClass">
82
- <KeyValue
83
- key="labels"
84
- :value="value.labels"
85
- :protected-keys="value.systemLabels || []"
86
- :toggle-filter="toggler"
87
- :add-label="t('labels.addLabel')"
88
- :mode="mode"
89
- :read-allowed="false"
90
- :value-can-be-empty="true"
91
- @input="value.setLabels($event)"
92
- />
69
+ <div :class="defaultSectionClass">
70
+ <div class="labels">
71
+ <div class="labels__header">
72
+ <h3>
73
+ <t k="labels.labels.title" />
74
+ </h3>
75
+ <ToggleSwitch
76
+ v-if="value.hasSystemLabels"
77
+ v-model="toggler"
78
+ name="label-system-toggle"
79
+ :on-label="t('labels.labels.show')"
80
+ />
81
+ </div>
82
+ <p class="mt-10 mb-10">
83
+ <t k="labels.labels.description" />
84
+ </p>
85
+ <div :class="columnsClass">
86
+ <KeyValue
87
+ key="labels"
88
+ :value="value.labels"
89
+ :protected-keys="value.systemLabels || []"
90
+ :toggle-filter="toggler"
91
+ :add-label="t('labels.addLabel')"
92
+ :mode="mode"
93
+ :read-allowed="false"
94
+ :value-can-be-empty="true"
95
+ @input="value.setLabels($event)"
96
+ />
97
+ </div>
93
98
  </div>
94
99
  </div>
95
100
  <div class="spacer" />
@@ -334,14 +334,14 @@ export default {
334
334
  display: grid;
335
335
  grid-template-columns: 1fr 1fr 1fr;
336
336
  margin: 5px 0;
337
- grid-gap: 10px;
337
+ grid-gap: $column-gutter;
338
338
 
339
339
  & > LABEL {
340
340
  margin: 0;
341
341
  }
342
342
 
343
343
  &:not(.view){
344
- grid-template-columns: 1fr 1fr 1fr 100px;
344
+ grid-template-columns: repeat(3, 1fr) 50px;
345
345
  }
346
346
  }
347
347
  </style>
@@ -175,7 +175,20 @@ export default {
175
175
  opt: { url: `/v3/principals/${ principalId }` }
176
176
  }, { root: true });
177
177
  },
178
+ customPermissionsUpdate() {
179
+ return this.customPermissions.reduce((acc, customPermissionsItem) => {
180
+ const lockedExist = this.roleTemplates.find(roleTemplateItem => roleTemplateItem.displayName === customPermissionsItem.label);
181
+
182
+ if (lockedExist.locked) {
183
+ customPermissionsItem['locked'] = true;
184
+ customPermissionsItem['tooltip'] = this.t('members.clusterPermissions.custom.lockedRole');
185
+ }
186
+
187
+ return [...acc, customPermissionsItem];
188
+ }, []);
189
+ }
178
190
  },
191
+
179
192
  watch: {
180
193
  roleTemplateIds() {
181
194
  this.updateBindings();
@@ -208,7 +221,7 @@ export default {
208
221
  this.$emit('input', bindings);
209
222
  }
210
223
  }
211
- }
224
+ },
212
225
  };
213
226
  </script>
214
227
  <template>
@@ -253,13 +266,22 @@ export default {
253
266
  class="custom-permissions ml-20 mt-10"
254
267
  :class="{'two-column': useTwoColumnsForCustom}"
255
268
  >
256
- <Checkbox
257
- v-for="permission in customPermissions"
269
+ <div
270
+ v-for="permission in customPermissionsUpdate"
258
271
  :key="permission.key"
259
- v-model="permission.value"
260
- class="mb-5"
261
- :label="permission.label"
262
- />
272
+ >
273
+ <Checkbox
274
+ v-model="permission.value"
275
+ :disabled="permission.locked"
276
+ class="mb-5"
277
+ :label="permission.label"
278
+ />
279
+ <i
280
+ v-if="permission.locked"
281
+ v-tooltip="permission.tooltip"
282
+ class="icon icon-lock icon-fw"
283
+ />
284
+ </div>
263
285
  </div>
264
286
  </template>
265
287
  </Card>
@@ -282,5 +304,8 @@ label.radio {
282
304
  &.two-column {
283
305
  grid-template-columns: 1fr 1fr;
284
306
  }
307
+ ::v-deep .checkbox-label {
308
+ margin-right: 0;
309
+ }
285
310
  }
286
311
  </style>
@@ -330,7 +330,7 @@ export default {
330
330
  }
331
331
 
332
332
  if (this.namespaced) {
333
- this.$emit('isNamespaceNew', !val || (this.namespaces && !this.namespaces.find(n => n.value === val)));
333
+ this.$emit('isNamespaceNew', !val || (this.options && !this.options.find(n => n.value === val)));
334
334
  }
335
335
 
336
336
  if (this.namespaceKey) {
@@ -188,6 +188,18 @@ export default {
188
188
  value: 'custom'
189
189
  }
190
190
  ];
191
+ },
192
+ customPermissionsUpdate() {
193
+ return this.customPermissions.reduce((acc, customPermissionsItem) => {
194
+ const lockedExist = this.roleTemplates.find(roleTemplateItem => roleTemplateItem.displayName === customPermissionsItem.label);
195
+
196
+ if (lockedExist.locked) {
197
+ customPermissionsItem['locked'] = true;
198
+ customPermissionsItem['tooltip'] = this.t('members.clusterPermissions.custom.lockedRole');
199
+ }
200
+
201
+ return [...acc, customPermissionsItem];
202
+ }, []);
191
203
  }
192
204
  },
193
205
  watch: {
@@ -244,19 +256,19 @@ export default {
244
256
  <div v-else>
245
257
  <div class="row mt-10">
246
258
  <div class="col span-12">
247
- <SelectPrincipal
248
- project
249
- class="mb-20"
250
- :mode="mode"
251
- :retain-selection="true"
252
- @add="onAdd"
259
+ <SelectPrincipal
260
+ project
261
+ class="mb-20"
262
+ :mode="mode"
263
+ :retain-selection="true"
264
+ @add="onAdd"
253
265
  />
254
266
  </div>
255
267
  </div>
256
- <Card
257
- class="m-0"
258
- :show-highlight-border="false"
259
- :show-actions="false"
268
+ <Card
269
+ class="m-0"
270
+ :show-highlight-border="false"
271
+ :show-actions="false"
260
272
  >
261
273
  <template v-slot:title>
262
274
  <div class="type-title">
@@ -272,18 +284,27 @@ export default {
272
284
  :options="options"
273
285
  name="permission-group"
274
286
  />
275
- <div
276
- v-if="value.permissionGroup === 'custom'"
277
- class="custom-permissions ml-20 mt-10"
278
- :class="{'two-column': useTwoColumnsForCustom}"
287
+ <div
288
+ v-if="value.permissionGroup === 'custom'"
289
+ class="custom-permissions ml-20 mt-10"
290
+ :class="{'two-column': useTwoColumnsForCustom}"
279
291
  >
280
- <Checkbox
281
- v-for="permission in customPermissions"
282
- :key="permission.key"
283
- v-model="permission.value"
284
- class="mb-5"
285
- :label="permission.label"
286
- />
292
+ <div
293
+ v-for="permission in customPermissionsUpdate"
294
+ :key="permission.key"
295
+ >
296
+ <Checkbox
297
+ v-model="permission.value"
298
+ :disabled="permission.locked"
299
+ class="mb-5"
300
+ :label="permission.label"
301
+ />
302
+ <i
303
+ v-if="permission.locked"
304
+ v-tooltip="permission.tooltip"
305
+ class="icon icon-lock icon-fw"
306
+ />
307
+ </div>
287
308
  </div>
288
309
  </template>
289
310
  </Card>
@@ -306,5 +327,9 @@ label.radio {
306
327
  &.two-column {
307
328
  grid-template-columns: 1fr 1fr;
308
329
  }
330
+
331
+ ::v-deep .checkbox-label {
332
+ margin-right: 0;
333
+ }
309
334
  }
310
335
  </style>
@@ -198,7 +198,7 @@ export default {
198
198
  suffix="Seconds"
199
199
  />
200
200
  </div>
201
- <div class="col">
201
+ <div class="col remove">
202
202
  <button
203
203
  v-if="!isView"
204
204
  type="button"
@@ -244,4 +244,7 @@ export default {
244
244
  color: var(--input-label);
245
245
  margin-bottom: 10px;
246
246
  }
247
+ .remove BUTTON {
248
+ padding: 0px;
249
+ }
247
250
  </style>
@@ -359,15 +359,16 @@ export default {
359
359
  />
360
360
  </div>
361
361
  </template>
362
-
363
- <button
364
- v-if="!isView"
365
- type="button"
366
- class="btn btn-sm role-link"
367
- @click.stop="$emit('remove')"
368
- >
369
- {{ t('generic.remove') }}
370
- </button>
362
+ <div class="remove">
363
+ <button
364
+ v-if="!isView"
365
+ type="button"
366
+ class="btn role-link"
367
+ @click.stop="$emit('remove')"
368
+ >
369
+ {{ t('generic.remove') }}
370
+ </button>
371
+ </div>
371
372
  </div>
372
373
  </template>
373
374
 
@@ -382,6 +383,10 @@ export default {
382
383
  .single-value {
383
384
  grid-column: span 2;
384
385
  }
386
+
387
+ .remove BUTTON {
388
+ padding: 0px;
389
+ }
385
390
  }
386
391
 
387
392
  </style>