@rancher/shell 3.0.4 → 3.0.5-rc.1

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 (122) hide show
  1. package/assets/styles/base/_basic.scss +6 -0
  2. package/assets/styles/global/_button.scss +1 -0
  3. package/assets/translations/en-us.yaml +37 -3
  4. package/cloud-credential/aws.vue +2 -0
  5. package/components/AssignTo.vue +25 -11
  6. package/components/AsyncButton.vue +24 -7
  7. package/components/BannerGraphic.vue +1 -0
  8. package/components/CommunityLinks.vue +3 -3
  9. package/components/CopyToClipboardText.vue +2 -1
  10. package/components/DetailText.vue +5 -0
  11. package/components/DisableAuthProviderModal.vue +1 -0
  12. package/components/ExplorerMembers.vue +1 -1
  13. package/components/ExplorerProjectsNamespaces.vue +56 -14
  14. package/components/LandingPagePreference.vue +5 -3
  15. package/components/LocaleSelector.vue +38 -94
  16. package/components/ModalWithCard.vue +1 -0
  17. package/components/MoveModal.vue +1 -0
  18. package/components/PromptRemove.vue +1 -0
  19. package/components/PromptRestore.vue +1 -0
  20. package/components/ResourceCancelModal.vue +1 -0
  21. package/components/SortableTable/index.vue +10 -11
  22. package/components/__tests__/AsyncButton.test.ts +2 -2
  23. package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
  24. package/components/form/ArrayList.vue +66 -54
  25. package/components/form/Command.vue +6 -15
  26. package/components/form/EnvVars.vue +15 -8
  27. package/components/form/HealthCheck.vue +3 -3
  28. package/components/form/HookOption.vue +11 -16
  29. package/components/form/LabeledSelect.vue +2 -1
  30. package/components/form/LifecycleHooks.vue +3 -3
  31. package/components/form/MatchExpressions.vue +10 -7
  32. package/components/form/NameNsDescription.vue +123 -103
  33. package/components/form/Networking.vue +20 -12
  34. package/components/form/NodeAffinity.vue +31 -23
  35. package/components/form/NodeScheduling.vue +13 -3
  36. package/components/form/PodAffinity.vue +43 -43
  37. package/components/form/Probe.vue +67 -66
  38. package/components/form/ResourceQuota/Project.vue +5 -1
  39. package/components/form/ResourceSelector.vue +7 -9
  40. package/components/form/SSHKnownHosts/KnownHostsEditDialog.vue +6 -3
  41. package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +12 -1
  42. package/components/form/SSHKnownHosts/index.vue +16 -2
  43. package/components/form/Security.vue +54 -56
  44. package/components/form/Select.vue +31 -6
  45. package/components/form/ShellInput.vue +5 -1
  46. package/components/form/Tolerations.vue +5 -1
  47. package/components/form/ValueFromResource.vue +134 -121
  48. package/components/form/WorkloadPorts.vue +18 -18
  49. package/components/form/__tests__/ArrayList.test.ts +3 -0
  50. package/components/form/__tests__/MatchExpressions.test.ts +12 -12
  51. package/components/form/__tests__/NameNsDescription.test.ts +115 -14
  52. package/components/form/__tests__/Probe.test.ts +12 -8
  53. package/components/form/__tests__/SSHKnownHosts.test.ts +11 -0
  54. package/components/form/__tests__/Select.test.ts +37 -0
  55. package/components/formatter/InternalExternalIP.vue +2 -0
  56. package/components/formatter/SecretData.vue +20 -7
  57. package/components/nav/Group.vue +15 -1
  58. package/components/nav/Header.vue +1 -0
  59. package/components/nav/Type.vue +12 -1
  60. package/components/templates/blank.vue +4 -1
  61. package/components/templates/default.vue +2 -0
  62. package/components/templates/home.vue +4 -1
  63. package/components/templates/plain.vue +4 -1
  64. package/composables/useRuntimeFlag.ts +29 -0
  65. package/config/router/routes.js +20 -13
  66. package/core/types.ts +5 -0
  67. package/dialog/AddCustomBadgeDialog.vue +1 -0
  68. package/dialog/DeactivateDriverDialog.vue +1 -0
  69. package/dialog/ForceMachineRemoveDialog.vue +4 -1
  70. package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +16 -3
  71. package/edit/auth/__tests__/oidc.test.ts +152 -109
  72. package/edit/auth/azuread.vue +1 -0
  73. package/edit/auth/googleoauth.vue +4 -0
  74. package/edit/auth/oidc.vue +37 -4
  75. package/edit/cloudcredential.vue +1 -0
  76. package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +40 -9
  77. package/edit/networking.k8s.io.ingress/IngressClass.vue +7 -3
  78. package/edit/networking.k8s.io.ingress/__tests__/IngressClass.test.ts +58 -0
  79. package/edit/persistentvolume/__tests__/persistentvolume.test.ts +14 -2
  80. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +1 -0
  81. package/edit/provisioning.cattle.io.cluster/rke2.vue +25 -34
  82. package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +6 -1
  83. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +29 -1
  84. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +2 -2
  85. package/edit/token.vue +2 -0
  86. package/edit/workload/index.vue +1 -0
  87. package/edit/workload/mixins/workload.js +0 -2
  88. package/list/management.cattle.io.feature.vue +1 -0
  89. package/list/provisioning.cattle.io.cluster.vue +20 -12
  90. package/models/__tests__/namespace.test.ts +25 -1
  91. package/models/cloudcredential.js +5 -0
  92. package/models/kontainerdriver.js +6 -3
  93. package/models/management.cattle.io.node.js +3 -3
  94. package/models/namespace.js +4 -5
  95. package/models/nodedriver.js +6 -3
  96. package/models/workload.js +4 -1
  97. package/package.json +3 -3
  98. package/pages/account/index.vue +4 -1
  99. package/pages/auth/login.vue +11 -3
  100. package/pages/auth/logout.vue +4 -1
  101. package/pages/auth/setup.vue +1 -0
  102. package/pages/auth/verify.vue +4 -1
  103. package/pages/c/_cluster/apps/charts/chart.vue +1 -1
  104. package/pages/diagnostic.vue +47 -2
  105. package/pages/fail-whale.vue +6 -3
  106. package/pages/home.vue +24 -18
  107. package/pages/support/index.vue +4 -1
  108. package/rancher-components/Form/Radio/RadioGroup.vue +25 -23
  109. package/rancher-components/RcDropdown/RcDropdown.vue +3 -2
  110. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +10 -0
  111. package/rancher-components/RcDropdown/useDropdownCollection.ts +8 -0
  112. package/rancher-components/RcDropdown/useDropdownContext.ts +9 -3
  113. package/scripts/extension/publish +1 -0
  114. package/server/har-file.js +25 -3
  115. package/store/features.js +2 -1
  116. package/store/type-map.js +4 -0
  117. package/types/shell/index.d.ts +8 -1
  118. package/utils/cluster.js +35 -0
  119. package/utils/validators/machine-pool.ts +20 -0
  120. package/components/formatter/ExtensionCache.vue +0 -74
  121. package/components/formatter/Port.vue +0 -24
  122. package/components/formatter/SecretType.vue +0 -41
@@ -6,6 +6,7 @@ import { LabeledInput } from '@components/Form/LabeledInput';
6
6
  import LabeledSelect from '@shell/components/form/LabeledSelect';
7
7
  import ShellInput from '@shell/components/form/ShellInput';
8
8
  import KeyValue from '@shell/components/form/KeyValue';
9
+ import { computed, ref, watch } from 'vue';
9
10
 
10
11
  const KINDS = [
11
12
  'none',
@@ -43,29 +44,29 @@ export default {
43
44
  },
44
45
  },
45
46
 
46
- data() {
47
- let kind = 'none';
48
- let probe = null;
49
- let exec = null;
50
- let httpGet = null;
51
- let tcpSocket = null;
52
-
53
- if ( this.value ) {
54
- probe = clone(this.value);
55
-
56
- if ( probe.exec ) {
57
- kind = 'exec';
58
- } else if ( probe.httpGet ) {
59
- if ( (probe.httpGet.scheme || '').toLowerCase() === 'https' ) {
60
- kind = 'HTTPS';
47
+ setup(props, { emit }) {
48
+ const kind = ref('none');
49
+ const probe = ref(null);
50
+ const exec = ref(null);
51
+ const httpGet = ref(null);
52
+ const tcpSocket = ref(null);
53
+
54
+ if ( props.value ) {
55
+ probe.value = clone(props.value);
56
+
57
+ if ( probe.value.exec ) {
58
+ kind.value = 'exec';
59
+ } else if ( probe.value.httpGet ) {
60
+ if ( (probe.value.httpGet.scheme || '').toLowerCase() === 'https' ) {
61
+ kind.value = 'HTTPS';
61
62
  } else {
62
- kind = 'HTTP';
63
+ kind.value = 'HTTP';
63
64
  }
64
- } else if ( probe.tcpSocket ) {
65
- kind = 'tcp';
65
+ } else if ( probe.value.tcpSocket ) {
66
+ kind.value = 'tcp';
66
67
  }
67
68
  } else {
68
- probe = {
69
+ probe.value = {
69
70
  failureThreshold: 3,
70
71
  successThreshold: 1,
71
72
  initialDelaySeconds: 0,
@@ -77,68 +78,68 @@ export default {
77
78
  };
78
79
  }
79
80
 
80
- exec = probe.exec || {};
81
- httpGet = probe.httpGet || {};
82
- tcpSocket = probe.tcpSocket || {};
81
+ exec.value = probe.value.exec || {};
82
+ httpGet.value = probe.value.httpGet || {};
83
+ tcpSocket.value = probe.value.tcpSocket || {};
83
84
 
84
- return {
85
- probe, kind, exec, httpGet, tcpSocket
86
- };
87
- },
88
-
89
- computed: {
90
- isView() {
91
- return this.mode === _VIEW;
92
- },
93
-
94
- isNone() {
95
- return this.kind === 'none';
96
- },
85
+ const isNone = computed(() => {
86
+ return kind.value === 'none';
87
+ });
97
88
 
98
- kindOptions() {
99
- return KINDS.map((k) => {
100
- return { label: this.t(`workload.container.healthCheck.kind.${ k }`), value: k };
101
- });
102
- }
103
- },
104
-
105
- watch: {
106
- kind() {
107
- this.update();
108
- }
109
- },
110
-
111
- methods: {
112
- update() {
113
- const probe = this.probe;
114
-
115
- if ( this.isNone ) {
116
- this.$emit('update:value', null);
89
+ const update = () => {
90
+ if ( isNone.value ) {
91
+ emit('update:value', null);
117
92
 
118
93
  return;
119
94
  }
120
95
 
121
- switch ( this.kind ) {
96
+ switch ( kind.value ) {
122
97
  case 'HTTP':
123
98
  case 'HTTPS':
124
- this.httpGet.scheme = this.kind;
125
- probe.httpGet = this.httpGet;
126
- probe.tcpSocket = null;
127
- probe.exec = null;
99
+ httpGet.value.scheme = kind.value;
100
+ probe.value.httpGet = httpGet.value;
101
+ probe.value.tcpSocket = null;
102
+ probe.value.exec = null;
128
103
  break;
129
104
  case 'tcp':
130
- probe.httpGet = null;
131
- probe.tcpSocket = this.tcpSocket;
132
- probe.exec = null;
105
+ probe.value.httpGet = null;
106
+ probe.value.tcpSocket = tcpSocket.value;
107
+ probe.value.exec = null;
133
108
  break;
134
109
  case 'exec':
135
- probe.httpGet = null;
136
- probe.tcpSocket = null;
137
- probe.exec = this.exec;
110
+ probe.value.httpGet = null;
111
+ probe.value.tcpSocket = null;
112
+ probe.value.exec = exec.value;
138
113
  break;
139
114
  }
140
115
 
141
- this.$emit('update:value', probe);
116
+ emit('update:value', probe.value);
117
+ };
118
+
119
+ watch(kind, () => {
120
+ update();
121
+ });
122
+
123
+ return {
124
+ probe,
125
+ kind,
126
+ exec,
127
+ httpGet,
128
+ tcpSocket,
129
+ update,
130
+ isNone,
131
+ };
132
+ },
133
+
134
+ computed: {
135
+ isView() {
136
+ return this.mode === _VIEW;
137
+ },
138
+
139
+ kindOptions() {
140
+ return KINDS.map((k) => {
141
+ return { label: this.t(`workload.container.healthCheck.kind.${ k }`), value: k };
142
+ });
142
143
  }
143
144
  },
144
145
  };
@@ -28,11 +28,15 @@ export default {
28
28
  },
29
29
 
30
30
  data() {
31
+ return { typeValues: null };
32
+ },
33
+
34
+ created() {
31
35
  this.value['spec'] = this.value.spec || {};
32
36
  this.value.spec['namespaceDefaultResourceQuota'] = this.value.spec.namespaceDefaultResourceQuota || { limit: {} };
33
37
  this.value.spec['resourceQuota'] = this.value.spec.resourceQuota || { limit: {} };
34
38
 
35
- return { typeValues: Object.keys(this.value.spec.resourceQuota.limit) };
39
+ this.typeValues = Object.keys(this.value.spec.resourceQuota.limit);
36
40
  },
37
41
 
38
42
  computed: { ...QUOTA_COMPUTED },
@@ -45,16 +45,14 @@ export default {
45
45
  },
46
46
 
47
47
  data() {
48
- const matchingResources = {
49
- matched: 0,
50
- matches: [],
51
- none: true,
52
- sample: null,
53
- total: 0,
54
- };
55
-
56
48
  return {
57
- matchingResources,
49
+ matchingResources: {
50
+ matched: 0,
51
+ matches: [],
52
+ none: true,
53
+ sample: null,
54
+ total: 0,
55
+ },
58
56
  allResources: [],
59
57
  allResourcesInScope: [],
60
58
  tableHeaders: this.$store.getters['type-map/headersFor'](
@@ -22,7 +22,7 @@ export default {
22
22
  mode: {
23
23
  type: String,
24
24
  default: _EDIT
25
- },
25
+ }
26
26
  },
27
27
 
28
28
  data() {
@@ -40,8 +40,9 @@ export default {
40
40
 
41
41
  return {
42
42
  codeMirrorOptions,
43
- text: this.value,
44
- showModal: false,
43
+ text: this.value,
44
+ showModal: false,
45
+ returnFocusSelector: '#known-ssh-hosts-trigger'
45
46
  };
46
47
  },
47
48
 
@@ -83,6 +84,8 @@ export default {
83
84
  data-testid="sshKnownHostsDialog"
84
85
  height="auto"
85
86
  :scrollable="true"
87
+ :trigger-focus-trap="true"
88
+ :return-focus-selector="returnFocusSelector"
86
89
  @close="closeDialog(false)"
87
90
  >
88
91
  <div
@@ -14,6 +14,17 @@ const requiredSetup = () => {
14
14
  return { global: { mocks: { $store: mockedStore() } } };
15
15
  };
16
16
 
17
+ jest.mock('focus-trap', () => {
18
+ return {
19
+ createFocusTrap: jest.fn().mockImplementation(() => {
20
+ return {
21
+ activate: jest.fn(),
22
+ deactivate: jest.fn(),
23
+ };
24
+ }),
25
+ };
26
+ });
27
+
17
28
  describe('component: KnownHostsEditDialog', () => {
18
29
  beforeEach(() => {
19
30
  document.body.innerHTML = '<div id="modals"></div>';
@@ -21,7 +32,7 @@ describe('component: KnownHostsEditDialog', () => {
21
32
  attachTo: document.body,
22
33
  props: {
23
34
  mode: _EDIT,
24
- value: 'line1\nline2\n',
35
+ value: 'line1\nline2\n'
25
36
  },
26
37
  ...requiredSetup(),
27
38
  });
@@ -65,12 +65,18 @@ export default defineComponent({
65
65
  </div>
66
66
  <template v-if="!isViewMode">
67
67
  <button
68
+ id="known-ssh-hosts-trigger"
68
69
  ref="button"
70
+ role="button"
71
+ :aria-label="t('secret.ssh.editKnownHosts.title')"
69
72
  data-testid="input-known-ssh-hosts_open-dialog"
70
73
  class="show-dialog-btn btn"
71
74
  @click="openDialog"
72
75
  >
73
- <i class="icon icon-edit" />
76
+ <i
77
+ class="icon icon-edit"
78
+ :alt="t('secret.ssh.editKnownHosts.title')"
79
+ />
74
80
  </button>
75
81
 
76
82
  <KnownHostsEditDialog
@@ -94,8 +100,16 @@ export default defineComponent({
94
100
  }
95
101
 
96
102
  .show-dialog-btn {
97
- display: contents;
98
103
  background-color: transparent;
104
+ padding: 4px;
105
+ height: 22px;
106
+ margin: -3px -3px 0 0;
107
+ min-height: unset;
108
+
109
+ &:focus-visible {
110
+ @include focus-outline;
111
+ outline-offset: 1px;
112
+ }
99
113
  }
100
114
  }
101
115
  </style>
@@ -5,6 +5,45 @@ import { _VIEW } from '@shell/config/query-params';
5
5
  import { mapGetters } from 'vuex';
6
6
  import LabeledSelect from '@shell/components/form/LabeledSelect';
7
7
 
8
+ const allCapabilities = ['ALL',
9
+ 'AUDIT_CONTROL',
10
+ 'AUDIT_WRITE',
11
+ 'BLOCK_SUSPEND',
12
+ 'CHOWN',
13
+ 'DAC_OVERRIDE',
14
+ 'DAC_READ_SEARCH',
15
+ 'FOWNER',
16
+ 'FSETID',
17
+ 'IPC_LOCK',
18
+ 'IPC_OWNER',
19
+ 'KILL',
20
+ 'LEASE',
21
+ 'LINUX_IMMUTABLE',
22
+ 'MAC_ADMIN',
23
+ 'MAC_OVERRIDE',
24
+ 'MKNOD',
25
+ 'NET_ADMIN',
26
+ 'NET_BIND_SERVICE',
27
+ 'NET_BROADCAST',
28
+ 'NET_RAW',
29
+ 'SETFCAP',
30
+ 'SETGID',
31
+ 'SETPCAP',
32
+ 'SETUID',
33
+ 'SYSLOG',
34
+ 'SYS_ADMIN',
35
+ 'SYS_BOOT',
36
+ 'SYS_CHROOT',
37
+ 'SYS_MODULE',
38
+ 'SYS_NICE',
39
+ 'SYS_PACCT',
40
+ 'SYS_PTRACE',
41
+ 'SYS_RAWIO',
42
+ 'SYS_RESOURCE',
43
+ 'SYS_TIME',
44
+ 'SYS_TTY_CONFIG',
45
+ 'WAKE_ALARM'];
46
+
8
47
  export default {
9
48
  emits: ['update:value'],
10
49
 
@@ -25,68 +64,27 @@ export default {
25
64
  },
26
65
 
27
66
  data() {
28
- const allCapabilities = ['ALL',
29
- 'AUDIT_CONTROL',
30
- 'AUDIT_WRITE',
31
- 'BLOCK_SUSPEND',
32
- 'CHOWN',
33
- 'DAC_OVERRIDE',
34
- 'DAC_READ_SEARCH',
35
- 'FOWNER',
36
- 'FSETID',
37
- 'IPC_LOCK',
38
- 'IPC_OWNER',
39
- 'KILL',
40
- 'LEASE',
41
- 'LINUX_IMMUTABLE',
42
- 'MAC_ADMIN',
43
- 'MAC_OVERRIDE',
44
- 'MKNOD',
45
- 'NET_ADMIN',
46
- 'NET_BIND_SERVICE',
47
- 'NET_BROADCAST',
48
- 'NET_RAW',
49
- 'SETFCAP',
50
- 'SETGID',
51
- 'SETPCAP',
52
- 'SETUID',
53
- 'SYSLOG',
54
- 'SYS_ADMIN',
55
- 'SYS_BOOT',
56
- 'SYS_CHROOT',
57
- 'SYS_MODULE',
58
- 'SYS_NICE',
59
- 'SYS_PACCT',
60
- 'SYS_PTRACE',
61
- 'SYS_RAWIO',
62
- 'SYS_RESOURCE',
63
- 'SYS_TIME',
64
- 'SYS_TTY_CONFIG',
65
- 'WAKE_ALARM'];
67
+ return {
68
+ privileged: this.value.privileged || false,
69
+ allowPrivilegeEscalation: this.value.allowPrivilegeEscalation || false,
70
+ allCapabilities,
71
+ runAsNonRoot: this.value.runAsNonRoot || false,
72
+ readOnlyRootFilesystem: this.value.readOnlyRootFilesystem || false,
73
+ add: [],
74
+ drop: [],
75
+ runAsUser: this.value.runAsUser
76
+ };
77
+ },
66
78
 
67
- const {
68
- capabilities = {},
69
- runAsNonRoot = false,
70
- readOnlyRootFilesystem = false,
71
- privileged = false,
72
- allowPrivilegeEscalation = false,
73
- runAsUser
74
- } = this.value;
79
+ created() {
80
+ const { capabilities = {} } = this.value;
75
81
  const {
76
82
  add = [],
77
83
  drop = []
78
84
  } = capabilities;
79
85
 
80
- return {
81
- privileged,
82
- allowPrivilegeEscalation,
83
- allCapabilities,
84
- runAsNonRoot,
85
- readOnlyRootFilesystem,
86
- add,
87
- drop,
88
- runAsUser
89
- };
86
+ this.add = add;
87
+ this.drop = drop;
90
88
  },
91
89
 
92
90
  computed: {
@@ -2,11 +2,12 @@
2
2
  import { get } from '@shell/utils/object';
3
3
  import LabeledFormElement from '@shell/mixins/labeled-form-element';
4
4
  import VueSelectOverrides from '@shell/mixins/vue-select-overrides';
5
+ import { generateRandomAlphaString } from '@shell/utils/string';
5
6
  import { LabeledTooltip } from '@components/LabeledTooltip';
6
7
  import { onClickOption, calculatePosition } from '@shell/utils/select';
7
8
 
8
9
  export default {
9
- emits: ['update:value', 'createdListItem'],
10
+ emits: ['update:value', 'createdListItem', 'on-open', 'on-close'],
10
11
 
11
12
  components: { LabeledTooltip },
12
13
  mixins: [
@@ -90,9 +91,14 @@ export default {
90
91
  isLangSelect: {
91
92
  type: Boolean,
92
93
  default: false
93
- },
94
+ }
95
+ },
96
+ data() {
97
+ return {
98
+ isOpen: false,
99
+ generatedUid: `s-uid-${ generateRandomAlphaString(12) }`
100
+ };
94
101
  },
95
-
96
102
  methods: {
97
103
  // resizeHandler = in mixin
98
104
  getOptionLabel(option) {
@@ -191,14 +197,26 @@ export default {
191
197
  return Math.random(100000);
192
198
  }
193
199
  },
200
+
194
201
  report(e) {
195
202
  alert(e);
196
203
  },
204
+
197
205
  handleDropdownOpen(args) {
198
206
  // function that prevents the "opening dropdown on focus"
199
207
  // default behaviour of v-select
200
208
  return args.noDrop || args.disabled ? false : args.open;
201
- }
209
+ },
210
+ onOpen() {
211
+ this.isOpen = true;
212
+ this.$emit('on-open');
213
+ this.resizeHandler();
214
+ },
215
+
216
+ onClose() {
217
+ this.isOpen = false;
218
+ this.$emit('on-close');
219
+ },
202
220
  },
203
221
  computed: {
204
222
  requiredField() {
@@ -259,6 +277,10 @@ export default {
259
277
  [$attrs.class]: $attrs.class
260
278
  }"
261
279
  :tabindex="disabled || isView ? -1 : 0"
280
+ role="combobox"
281
+ :aria-expanded="isOpen"
282
+ :aria-label="$attrs['aria-label'] || undefined"
283
+ :aria-describedby="$attrs['aria-describedby'] || undefined"
262
284
  @click="focusSearch"
263
285
  @keydown.enter="focusSearch"
264
286
  @keydown.down.prevent="focusSearch"
@@ -286,11 +308,14 @@ export default {
286
308
  :modelValue="value != null ? value : ''"
287
309
  :dropdownShouldOpen="handleDropdownOpen"
288
310
  :tabindex="-1"
289
- role="listbox"
311
+ role="listitem"
312
+ :uid="generatedUid"
313
+ :aria-label="'-'"
290
314
  @update:modelValue="$emit('update:value', $event)"
291
315
  @search:blur="onBlur"
292
316
  @search:focus="onFocus"
293
- @open="resizeHandler"
317
+ @open="onOpen"
318
+ @close="onClose"
294
319
  @option:created="(e) => $emit('createdListItem', e)"
295
320
  >
296
321
  <template
@@ -21,6 +21,10 @@ export default {
21
21
  causes $emit 'input' of ["-c", "sleep 600"]
22
22
  */
23
23
  data() {
24
+ return { userValue: '' };
25
+ },
26
+
27
+ created() {
24
28
  let userValue = '';
25
29
 
26
30
  if ( this.value ) {
@@ -36,7 +40,7 @@ export default {
36
40
  }, '').trim();
37
41
  }
38
42
 
39
- return { userValue };
43
+ this.userValue = userValue;
40
44
  },
41
45
 
42
46
  methods: {
@@ -29,6 +29,10 @@ export default {
29
29
  },
30
30
 
31
31
  data() {
32
+ return { rules: [] };
33
+ },
34
+
35
+ created() {
32
36
  const rules = [];
33
37
 
34
38
  // on creation in agent configuration, the backend "eats"
@@ -49,7 +53,7 @@ export default {
49
53
  });
50
54
  }
51
55
 
52
- return { rules };
56
+ this.rules = rules;
53
57
  },
54
58
 
55
59
  computed: {