@rancher/shell 0.2.5 → 0.3.0

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 (493) hide show
  1. package/assets/styles/themes/_dark.scss +4 -0
  2. package/assets/styles/themes/_light.scss +5 -0
  3. package/assets/translations/en-us.yaml +14 -2
  4. package/assets/translations/zh-hans.yaml +7 -5
  5. package/chart/istio.vue +1 -1
  6. package/chart/monitoring/grafana/index.vue +1 -1
  7. package/chart/monitoring/index.vue +1 -1
  8. package/chart/monitoring/prometheus/index.vue +4 -4
  9. package/components/AlertTable.vue +1 -1
  10. package/components/AssignTo.vue +1 -1
  11. package/components/AsyncButton.vue +2 -2
  12. package/components/BrandImage.vue +1 -1
  13. package/components/ButtonGroup.vue +1 -1
  14. package/components/ClusterProviderIcon.vue +2 -2
  15. package/components/Collapse.vue +6 -2
  16. package/components/CollapsibleCard.vue +2 -2
  17. package/components/ConsumptionGauge.vue +4 -4
  18. package/components/ContainerResourceLimit.vue +1 -1
  19. package/components/CountBox.vue +1 -1
  20. package/components/CountGauge.vue +1 -1
  21. package/components/CruResource.vue +2 -1
  22. package/components/DashboardMetrics.vue +2 -2
  23. package/components/ExplorerProjectsNamespaces.vue +6 -6
  24. package/components/FixedBanner.vue +6 -6
  25. package/components/GlobalRoleBindings.vue +6 -6
  26. package/components/GradientBox.vue +2 -2
  27. package/components/IconMessage.vue +4 -4
  28. package/components/Import.vue +5 -5
  29. package/components/InputOrDisplay.vue +1 -1
  30. package/components/KeyValueView.vue +1 -1
  31. package/components/LabelValue.vue +1 -1
  32. package/components/ModalWithCard.vue +1 -1
  33. package/components/MoveModal.vue +1 -1
  34. package/components/PercentageBar.vue +2 -2
  35. package/components/PromptChangePassword.vue +1 -1
  36. package/components/PromptModal.vue +1 -1
  37. package/components/PromptRemove.vue +2 -2
  38. package/components/PromptRestore.vue +13 -13
  39. package/components/Questions/Question.js +1 -1
  40. package/components/ResourceCancelModal.vue +3 -3
  41. package/components/ResourceDetail/Masthead.vue +1 -1
  42. package/components/ResourceList/Masthead.vue +1 -1
  43. package/components/ResourceSummary.vue +4 -4
  44. package/components/RoleBindings.vue +19 -19
  45. package/components/SimpleBox.vue +5 -1
  46. package/components/SingleClusterInfo.vue +5 -5
  47. package/components/SortableTable/THead.vue +6 -2
  48. package/components/SortableTable/actions.js +4 -2
  49. package/components/SortableTable/index.vue +9 -9
  50. package/components/SortableTable/selection.js +2 -2
  51. package/components/TableSparkLine.vue +1 -1
  52. package/components/TypeDescription.vue +1 -1
  53. package/components/Wizard.vue +1 -1
  54. package/components/YamlEditor.vue +6 -6
  55. package/components/__tests__/ApplicationCard.test.ts +27 -0
  56. package/components/__tests__/Collapse.spec.ts +44 -0
  57. package/components/__tests__/CruResource.test.ts +3 -3
  58. package/components/__tests__/NamespaceFilter.test.ts +213 -0
  59. package/components/__tests__/SimpleBox.spec.ts +28 -0
  60. package/components/auth/RoleDetailEdit.vue +17 -15
  61. package/components/auth/SelectPrincipal.vue +9 -0
  62. package/components/auth/login/ldap.vue +3 -0
  63. package/components/cards/ApplicationCard.vue +10 -5
  64. package/components/fleet/FleetBundleResources.vue +8 -8
  65. package/components/fleet/FleetClusters.vue +10 -10
  66. package/components/fleet/FleetRepos.vue +5 -5
  67. package/components/fleet/FleetResources.vue +6 -6
  68. package/components/fleet/FleetSummary.vue +5 -5
  69. package/components/fleet/ResourcesSummary.vue +1 -1
  70. package/components/form/ArrayListGrouped.vue +1 -1
  71. package/components/form/ArrayListSelect.vue +3 -3
  72. package/components/form/BannerSettings.vue +6 -6
  73. package/components/form/ChangePassword.vue +3 -3
  74. package/components/form/Error.vue +2 -2
  75. package/components/form/FileSelector.vue +3 -3
  76. package/components/form/Footer.vue +1 -1
  77. package/components/form/GithubPicker.vue +4 -4
  78. package/components/form/KeyValue.vue +2 -2
  79. package/components/form/MatchExpressions.vue +1 -1
  80. package/components/form/Members/ClusterPermissionsEditor.vue +11 -11
  81. package/components/form/Members/MembershipEditor.vue +2 -2
  82. package/components/form/NodeAffinity.vue +1 -1
  83. package/components/form/Password.vue +3 -3
  84. package/components/form/PodAffinity.vue +1 -1
  85. package/components/form/ProjectMemberEditor.vue +1 -1
  86. package/components/form/ResourceQuota/shared.js +12 -12
  87. package/components/form/SecretSelector.vue +1 -1
  88. package/components/form/Security.vue +1 -1
  89. package/components/form/Select.vue +4 -0
  90. package/components/form/SimpleSecretSelector.vue +1 -1
  91. package/components/form/Taints.vue +1 -1
  92. package/components/form/UnitInput.vue +7 -7
  93. package/components/form/ValueFromResource.vue +1 -1
  94. package/components/form/WorkloadPorts.vue +1 -1
  95. package/components/formatter/AppSummaryGraph.vue +4 -4
  96. package/components/formatter/BadgeStateFormatter.vue +2 -2
  97. package/components/formatter/Checked.vue +1 -1
  98. package/components/formatter/ClusterLink.vue +3 -3
  99. package/components/formatter/Date.vue +1 -1
  100. package/components/formatter/DelayedValue.vue +1 -1
  101. package/components/formatter/Endpoints.vue +1 -1
  102. package/components/formatter/FleetSummaryGraph.vue +4 -4
  103. package/components/formatter/IconIsDefault.vue +1 -1
  104. package/components/formatter/IconText.vue +4 -4
  105. package/components/formatter/ImagePercentageBar.vue +4 -4
  106. package/components/formatter/IngressFullPath.vue +1 -1
  107. package/components/formatter/LinkDetail.vue +3 -3
  108. package/components/formatter/List.vue +1 -1
  109. package/components/formatter/ListLink.vue +1 -1
  110. package/components/formatter/ListLinkDetail.vue +1 -1
  111. package/components/formatter/LiveDate.vue +3 -3
  112. package/components/formatter/LivePodRestarts.vue +1 -1
  113. package/components/formatter/Number.vue +1 -1
  114. package/components/formatter/Percentage.vue +2 -2
  115. package/components/formatter/PercentageBar.vue +3 -3
  116. package/components/formatter/PodImages.vue +1 -1
  117. package/components/formatter/Principal.vue +1 -1
  118. package/components/formatter/PrincipalGroupBindings.vue +2 -2
  119. package/components/formatter/QualityText.vue +1 -1
  120. package/components/formatter/ReceiverIcons.vue +2 -2
  121. package/components/formatter/Scale.vue +1 -1
  122. package/components/formatter/ScanResult.vue +1 -1
  123. package/components/formatter/SecretData.vue +1 -1
  124. package/components/formatter/ServiceType.vue +1 -1
  125. package/components/formatter/Shortened.vue +1 -1
  126. package/components/formatter/VerticalScroll.vue +2 -2
  127. package/components/formatter/VirtualServiceGateways.vue +3 -3
  128. package/components/formatter/Weight.vue +2 -2
  129. package/components/formatter/WorkloadDetailEndpoints.vue +1 -1
  130. package/components/formatter/WorkloadHealthScale.vue +2 -2
  131. package/components/formatter/__tests__/Date.test.ts +60 -0
  132. package/components/formatter/__tests__/LinkDetail.test.ts +72 -0
  133. package/components/formatter/__tests__/LiveDate.test.ts +84 -0
  134. package/components/formatter/__tests__/Si.test.ts +35 -0
  135. package/components/graph/LinePlot.vue +1 -1
  136. package/components/graph/ProgressArc.vue +5 -5
  137. package/components/nav/GlobalLoading.vue +1 -1
  138. package/components/nav/Header.vue +1 -2
  139. package/components/nav/Jump.vue +3 -3
  140. package/components/nav/NamespaceFilter.vue +71 -22
  141. package/components/nav/TopLevelMenu.vue +4 -4
  142. package/components/nav/Type.vue +1 -1
  143. package/components/nav/WindowManager/ChartReadme.vue +1 -1
  144. package/components/nav/WindowManager/ContainerLogs.vue +3 -3
  145. package/components/nav/WindowManager/ContainerShell.vue +19 -0
  146. package/components/nav/WindowManager/KubectlShell.vue +6 -6
  147. package/components/nav/WindowManager/MachineSsh.vue +1 -1
  148. package/components/nav/WindowManager/index.vue +196 -25
  149. package/config/labels-annotations.js +19 -19
  150. package/config/product/apps.js +5 -5
  151. package/config/product/auth.js +20 -20
  152. package/config/product/cis.js +24 -24
  153. package/config/product/explorer.js +22 -21
  154. package/config/product/fleet.js +7 -7
  155. package/config/product/gatekeeper.js +7 -7
  156. package/config/product/harvester-manager.js +8 -8
  157. package/config/product/istio.js +7 -7
  158. package/config/product/legacy.js +21 -21
  159. package/config/product/logging.js +90 -90
  160. package/config/product/manager.js +14 -14
  161. package/config/product/monitoring.js +36 -36
  162. package/config/product/multi-cluster-apps.js +24 -24
  163. package/config/product/settings.js +42 -42
  164. package/config/settings.ts +16 -16
  165. package/config/table-headers.js +55 -48
  166. package/config/types.js +7 -7
  167. package/config/uiplugins.js +4 -4
  168. package/creators/app/app.package.json +4 -1
  169. package/creators/app/{.eslintignore → files/.eslintignore} +0 -0
  170. package/creators/app/{.eslintrc.js → files/.eslintrc.js} +0 -0
  171. package/creators/app/{.vscode → files/.vscode}/settings.json +0 -0
  172. package/creators/app/{babel.config.js → files/babel.config.js} +0 -0
  173. package/creators/app/{nuxt.config.js → files/nuxt.config.js} +0 -0
  174. package/creators/app/{tsconfig.json → files/tsconfig.json} +2 -1
  175. package/creators/app/init +16 -17
  176. package/creators/app/package.json +7 -1
  177. package/creators/pkg/{babel.config.js → files/babel.config.js} +0 -0
  178. package/creators/pkg/{index.ts → files/index.ts} +0 -0
  179. package/creators/pkg/{tsconfig.json → files/tsconfig.json} +13 -12
  180. package/creators/pkg/{vue.config.js → files/vue.config.js} +0 -0
  181. package/creators/pkg/init +1 -1
  182. package/creators/pkg/package.json +1 -1
  183. package/creators/update/init +56 -0
  184. package/creators/update/package.json +20 -0
  185. package/creators/update/upgrade +56 -0
  186. package/detail/cis.cattle.io.clusterscan.vue +6 -6
  187. package/detail/configmap.vue +1 -1
  188. package/detail/constraints.gatekeeper.sh.constraint.vue +1 -1
  189. package/detail/fleet.cattle.io.bundle.vue +5 -5
  190. package/detail/fleet.cattle.io.gitrepo.vue +5 -5
  191. package/detail/helm.cattle.io.projecthelmchart.vue +1 -1
  192. package/detail/management.cattle.io.user.vue +3 -3
  193. package/detail/namespace.vue +13 -13
  194. package/detail/node.vue +2 -2
  195. package/detail/pod.vue +1 -1
  196. package/detail/provisioning.cattle.io.cluster.vue +12 -1
  197. package/detail/secret.vue +2 -2
  198. package/detail/workload/index.vue +1 -1
  199. package/dialog/AddClusterMemberDialog.vue +1 -1
  200. package/dialog/AddCustomBadgeDialog.vue +4 -4
  201. package/dialog/AddProjectMemberDialog.vue +29 -22
  202. package/dialog/AddonConfigConfirmationDialog.vue +1 -1
  203. package/dialog/DiagnosticTimingsDialog.vue +1 -1
  204. package/dialog/DrainNode.vue +12 -12
  205. package/dialog/ForceMachineRemoveDialog.vue +1 -1
  206. package/dialog/GenericPrompt.vue +1 -1
  207. package/dialog/RollbackWorkloadDialog.vue +8 -8
  208. package/dialog/RotateCertificatesDialog.vue +4 -4
  209. package/dialog/RotateEncryptionKeyDialog.vue +1 -1
  210. package/dialog/SaveAsRKETemplateDialog.vue +1 -1
  211. package/dialog/ScaleMachineDownDialog.vue +1 -1
  212. package/edit/__tests__/management.cattle.io.setting.test.ts +1 -1
  213. package/edit/auth/azuread.vue +2 -2
  214. package/edit/auth/github.vue +2 -2
  215. package/edit/auth/ldap/index.vue +4 -4
  216. package/edit/auth/oidc.vue +3 -3
  217. package/edit/auth/saml.vue +4 -4
  218. package/edit/autoscaling.horizontalpodautoscaler/external-metric.vue +2 -2
  219. package/edit/autoscaling.horizontalpodautoscaler/metric-object-reference.vue +1 -1
  220. package/edit/autoscaling.horizontalpodautoscaler/object-metric.vue +2 -2
  221. package/edit/autoscaling.horizontalpodautoscaler/pod-metric.vue +2 -2
  222. package/edit/cis.cattle.io.clusterscan.vue +2 -2
  223. package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -1
  224. package/edit/fleet.cattle.io.clustergroup.vue +3 -3
  225. package/edit/fleet.cattle.io.gitrepo.vue +9 -9
  226. package/edit/group.principal.vue +2 -2
  227. package/edit/helm.cattle.io.projecthelmchart.vue +3 -3
  228. package/edit/logging-flow/index.vue +1 -1
  229. package/edit/logging.banzaicloud.io.output/providers/datadog.vue +1 -1
  230. package/edit/logging.banzaicloud.io.output/providers/elasticsearch.vue +1 -1
  231. package/edit/logging.banzaicloud.io.output/providers/gcs.vue +1 -1
  232. package/edit/logging.banzaicloud.io.output/providers/gelf.vue +1 -1
  233. package/edit/logging.banzaicloud.io.output/providers/kafka.vue +1 -1
  234. package/edit/logging.banzaicloud.io.output/providers/logz.vue +1 -1
  235. package/edit/logging.banzaicloud.io.output/providers/loki.vue +1 -1
  236. package/edit/logging.banzaicloud.io.output/providers/opensearch.vue +213 -0
  237. package/edit/logging.banzaicloud.io.output/providers/redis.vue +142 -0
  238. package/edit/logging.banzaicloud.io.output/providers/s3.vue +1 -1
  239. package/edit/logging.banzaicloud.io.output/providers/splunkHec.vue +1 -1
  240. package/edit/logging.banzaicloud.io.output/providers/syslog.vue +1 -1
  241. package/edit/management.cattle.io.fleetworkspace.vue +1 -1
  242. package/edit/management.cattle.io.project.vue +3 -3
  243. package/edit/management.cattle.io.projectroletemplatebinding.vue +5 -5
  244. package/edit/management.cattle.io.setting.vue +1 -1
  245. package/edit/management.cattle.io.user.vue +4 -4
  246. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +15 -15
  247. package/edit/monitoring.coreos.com.alertmanagerconfig/tls.vue +1 -1
  248. package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +4 -4
  249. package/edit/monitoring.coreos.com.alertmanagerconfig/types/opsgenie.vue +5 -5
  250. package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +3 -3
  251. package/edit/monitoring.coreos.com.alertmanagerconfig/types/slack.vue +3 -3
  252. package/edit/monitoring.coreos.com.alertmanagerconfig/types/webhook.vue +4 -4
  253. package/edit/monitoring.coreos.com.receiver/auth.vue +2 -2
  254. package/edit/monitoring.coreos.com.receiver/index.vue +1 -1
  255. package/edit/monitoring.coreos.com.receiver/types/email.vue +1 -1
  256. package/edit/monitoring.coreos.com.receiver/types/opsgenie.vue +1 -1
  257. package/edit/monitoring.coreos.com.receiver/types/pagerduty.vue +1 -1
  258. package/edit/monitoring.coreos.com.receiver/types/webhook.vue +1 -1
  259. package/edit/monitoring.coreos.com.route.vue +1 -1
  260. package/edit/networking.istio.io.destinationrule/LoadBalancer.vue +1 -1
  261. package/edit/networking.k8s.io.ingress/Certificates.vue +3 -3
  262. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +2 -2
  263. package/edit/networking.k8s.io.ingress/IngressClass.vue +1 -1
  264. package/edit/networking.k8s.io.ingress/Rule.vue +1 -1
  265. package/edit/networking.k8s.io.ingress/RulePath.vue +5 -5
  266. package/edit/networking.k8s.io.ingress/Rules.vue +7 -7
  267. package/edit/networking.k8s.io.networkpolicy/PolicyRule.vue +1 -1
  268. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +3 -3
  269. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -1
  270. package/edit/networking.k8s.io.networkpolicy/index.vue +5 -5
  271. package/edit/persistentvolume/index.vue +1 -1
  272. package/edit/persistentvolume/plugins/awsElasticBlockStore.vue +1 -1
  273. package/edit/persistentvolume/plugins/azureDisk.vue +1 -1
  274. package/edit/persistentvolume/plugins/azureFile.vue +1 -1
  275. package/edit/persistentvolume/plugins/cephfs.vue +2 -2
  276. package/edit/persistentvolume/plugins/cinder.vue +1 -1
  277. package/edit/persistentvolume/plugins/csi.vue +2 -2
  278. package/edit/persistentvolume/plugins/fc.vue +2 -2
  279. package/edit/persistentvolume/plugins/flexVolume.vue +2 -2
  280. package/edit/persistentvolume/plugins/flocker.vue +1 -1
  281. package/edit/persistentvolume/plugins/gcePersistentDisk.vue +1 -1
  282. package/edit/persistentvolume/plugins/glusterfs.vue +1 -1
  283. package/edit/persistentvolume/plugins/hostPath.vue +1 -1
  284. package/edit/persistentvolume/plugins/iscsi.vue +2 -2
  285. package/edit/persistentvolume/plugins/local.vue +1 -1
  286. package/edit/persistentvolume/plugins/longhorn.vue +2 -2
  287. package/edit/persistentvolume/plugins/nfs.vue +1 -1
  288. package/edit/persistentvolume/plugins/photonPersistentDisk.vue +1 -1
  289. package/edit/persistentvolume/plugins/portworxVolume.vue +1 -1
  290. package/edit/persistentvolume/plugins/quobyte.vue +1 -1
  291. package/edit/persistentvolume/plugins/rbd.vue +2 -2
  292. package/edit/persistentvolume/plugins/scaleIO.vue +1 -1
  293. package/edit/persistentvolume/plugins/storageos.vue +1 -1
  294. package/edit/persistentvolume/plugins/vsphereVolume.vue +1 -1
  295. package/edit/persistentvolumeclaim.vue +2 -2
  296. package/edit/provisioning.cattle.io.cluster/DrainOptions.vue +1 -1
  297. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +1 -1
  298. package/edit/provisioning.cattle.io.cluster/S3Config.vue +1 -1
  299. package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.tests.ts +1 -1
  300. package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
  301. package/edit/provisioning.cattle.io.cluster/index.vue +2 -2
  302. package/edit/provisioning.cattle.io.cluster/rke2.vue +18 -12
  303. package/edit/resources.cattle.io.backup.vue +2 -2
  304. package/edit/secret/generic.vue +1 -0
  305. package/edit/storage.k8s.io.storageclass/index.vue +2 -2
  306. package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/no-provisioner.vue +1 -1
  307. package/edit/token.vue +1 -1
  308. package/edit/ui.cattle.io.navlink.vue +8 -8
  309. package/edit/workload/Job.vue +3 -3
  310. package/edit/workload/Upgrading.vue +1 -1
  311. package/edit/workload/VolumeClaimTemplate.vue +1 -1
  312. package/edit/workload/index.vue +3 -3
  313. package/edit/workload/mixins/workload.js +23 -23
  314. package/edit/workload/storage/ContainerMountPaths.vue +1 -1
  315. package/edit/workload/storage/Mount.vue +1 -1
  316. package/edit/workload/storage/azureDisk.vue +1 -1
  317. package/edit/workload/storage/azureFile.vue +1 -1
  318. package/edit/workload/storage/csi/index.vue +1 -1
  319. package/edit/workload/storage/ephemeralVolume/index.vue +1 -1
  320. package/edit/workload/storage/gcePersistentDisk.vue +1 -1
  321. package/edit/workload/storage/hostPath.vue +1 -1
  322. package/edit/workload/storage/nfs.vue +1 -1
  323. package/edit/workload/storage/persistentVolumeClaim/index.vue +1 -1
  324. package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +1 -1
  325. package/edit/workload/storage/secret.vue +1 -1
  326. package/edit/workload/storage/vsphereVolume.vue +1 -1
  327. package/layouts/default.vue +77 -16
  328. package/list/__tests__/workload.test.ts +50 -0
  329. package/list/fleet.cattle.io.gitrepo.vue +1 -1
  330. package/list/group.principal.vue +8 -8
  331. package/list/harvesterhci.io.management.cluster.vue +1 -1
  332. package/list/helm.cattle.io.projecthelmchart.vue +1 -1
  333. package/list/management.cattle.io.feature.vue +1 -1
  334. package/list/node.vue +1 -1
  335. package/list/provisioning.cattle.io.cluster.vue +3 -3
  336. package/machine-config/amazonec2.vue +1 -1
  337. package/machine-config/harvester.vue +4 -4
  338. package/mixins/__tests__/create-edit-view.test.ts +1 -1
  339. package/mixins/chart.js +14 -14
  340. package/mixins/create-edit-view/index.js +5 -5
  341. package/mixins/form-validation.js +1 -1
  342. package/mixins/labeled-form-element.ts +6 -6
  343. package/mixins/resource-fetch.js +3 -3
  344. package/mixins/resource-manager.js +1 -1
  345. package/models/autoscaling.horizontalpodautoscaler.js +5 -5
  346. package/models/batch.cronjob.js +15 -15
  347. package/models/batch.job.js +22 -0
  348. package/models/catalog.cattle.io.app.js +6 -6
  349. package/models/catalog.cattle.io.clusterrepo.js +7 -7
  350. package/models/catalog.cattle.io.operation.js +5 -5
  351. package/models/chart.js +4 -4
  352. package/models/cis.cattle.io.clusterscan.js +10 -10
  353. package/models/cluster/node.js +36 -36
  354. package/models/cluster.x-k8s.io.machine.js +13 -13
  355. package/models/constraints.gatekeeper.sh.constraint.js +1 -1
  356. package/models/etcdbackup.js +4 -4
  357. package/models/fleet.cattle.io.cluster.js +15 -15
  358. package/models/fleet.cattle.io.clustergroup.js +1 -1
  359. package/models/fleet.cattle.io.gitrepo.js +15 -15
  360. package/models/group.principal.js +1 -1
  361. package/models/logging.banzaicloud.io.clusterflow.js +2 -2
  362. package/models/logging.banzaicloud.io.flow.js +2 -2
  363. package/models/logging.banzaicloud.io.output.js +15 -3
  364. package/models/management.cattle.io.authconfig.js +4 -4
  365. package/models/management.cattle.io.cluster.js +9 -9
  366. package/models/management.cattle.io.clusterroletemplatebinding.js +8 -8
  367. package/models/management.cattle.io.globalrole.js +24 -3
  368. package/models/management.cattle.io.node.js +9 -9
  369. package/models/management.cattle.io.nodepool.js +3 -3
  370. package/models/management.cattle.io.nodetemplate.js +21 -21
  371. package/models/management.cattle.io.project.js +2 -2
  372. package/models/management.cattle.io.projectroletemplatebinding.js +6 -6
  373. package/models/management.cattle.io.roletemplate.js +54 -31
  374. package/models/management.cattle.io.user.js +4 -4
  375. package/models/monitoring.coreos.com.alertmanagerconfig.js +4 -4
  376. package/models/monitoring.coreos.com.receiver.js +7 -7
  377. package/models/monitoring.coreos.com.route.js +2 -2
  378. package/models/namespace.js +13 -0
  379. package/models/persistentvolumeclaim.js +4 -4
  380. package/models/pod.js +10 -10
  381. package/models/provisioning.cattle.io.cluster.js +29 -29
  382. package/models/rbac.authorization.k8s.io.role.js +4 -4
  383. package/models/rke.cattle.io.etcdsnapshot.js +4 -4
  384. package/models/service.js +15 -15
  385. package/models/storage.k8s.io.storageclass.js +8 -8
  386. package/models/workload.js +28 -28
  387. package/nuxt.config.js +32 -17
  388. package/package.json +1 -1
  389. package/pages/about.vue +1 -1
  390. package/pages/account/index.vue +1 -1
  391. package/pages/auth/login.vue +37 -7
  392. package/pages/auth/setup.vue +11 -11
  393. package/pages/c/_cluster/_product/_resource/_id.vue +2 -2
  394. package/pages/c/_cluster/apps/charts/chart.vue +4 -4
  395. package/pages/c/_cluster/apps/charts/index.vue +18 -18
  396. package/pages/c/_cluster/apps/charts/install.vue +14 -14
  397. package/pages/c/_cluster/auth/config/_id.vue +2 -2
  398. package/pages/c/_cluster/auth/roles/_resource/_id.vue +2 -2
  399. package/pages/c/_cluster/auth/roles/index.vue +4 -6
  400. package/pages/c/_cluster/explorer/EventsTable.vue +8 -8
  401. package/pages/c/_cluster/explorer/index.vue +14 -14
  402. package/pages/c/_cluster/explorer/tools/index.vue +4 -4
  403. package/pages/c/_cluster/fleet/GitRepoGraphConfig.js +2 -2
  404. package/pages/c/_cluster/fleet/index.vue +10 -10
  405. package/pages/c/_cluster/gatekeeper/index.vue +1 -1
  406. package/pages/c/_cluster/legacy/index.vue +1 -1
  407. package/pages/c/_cluster/longhorn/index.vue +1 -1
  408. package/pages/c/_cluster/mcapps/index.vue +1 -1
  409. package/pages/c/_cluster/navlinks/_group.vue +1 -1
  410. package/pages/c/_cluster/neuvector/index.vue +1 -1
  411. package/pages/c/_cluster/settings/banners.vue +30 -30
  412. package/pages/c/_cluster/settings/brand.vue +9 -9
  413. package/pages/c/_cluster/settings/links.vue +6 -6
  414. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +1 -1
  415. package/pages/c/_cluster/uiplugins/InstallDialog.vue +1 -1
  416. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +25 -8
  417. package/pages/c/_cluster/uiplugins/index.vue +2 -2
  418. package/pages/prefs.vue +11 -11
  419. package/pages/rio/mesh.vue +4 -4
  420. package/pages/support/index.vue +7 -7
  421. package/pkg/vue.config.js +10 -1
  422. package/plugins/dashboard-store/mutations.js +6 -6
  423. package/plugins/dashboard-store/normalize.js +1 -1
  424. package/plugins/dashboard-store/resource-class.js +100 -100
  425. package/plugins/steve/subscribe.js +4 -4
  426. package/plugins/steve/web-worker.steve-sub-worker.js +3 -3
  427. package/promptRemove/management.cattle.io.project.vue +1 -1
  428. package/promptRemove/mixin/roleDeletionCheck.js +7 -7
  429. package/promptRemove/pod.vue +2 -2
  430. package/rancher-components/Card/Card.test.ts +39 -0
  431. package/rancher-components/Card/Card.vue +3 -3
  432. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +0 -1
  433. package/rancher-components/StringList/StringList.test.ts +420 -45
  434. package/rancher-components/StringList/StringList.vue +10 -1
  435. package/rancher-components/Utils/DraggableZone/DraggableZone.vue +181 -0
  436. package/rancher-components/Utils/DraggableZone/index.ts +1 -0
  437. package/rancher-components/components/BadgeState/BadgeState.spec.ts +12 -0
  438. package/rancher-components/components/BadgeState/BadgeState.vue +111 -0
  439. package/rancher-components/components/BadgeState/index.ts +1 -0
  440. package/rancher-components/components/Banner/Banner.test.ts +13 -0
  441. package/rancher-components/components/Banner/Banner.vue +174 -0
  442. package/rancher-components/components/Banner/index.ts +1 -0
  443. package/rancher-components/components/Card/Card.test.ts +37 -0
  444. package/rancher-components/components/Card/Card.vue +166 -0
  445. package/rancher-components/components/Card/index.ts +1 -0
  446. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +77 -0
  447. package/rancher-components/components/Form/Checkbox/Checkbox.vue +416 -0
  448. package/rancher-components/components/Form/Checkbox/index.ts +1 -0
  449. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +23 -0
  450. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +355 -0
  451. package/rancher-components/components/Form/LabeledInput/index.ts +1 -0
  452. package/rancher-components/components/Form/Radio/RadioButton.vue +276 -0
  453. package/rancher-components/components/Form/Radio/RadioGroup.vue +253 -0
  454. package/rancher-components/components/Form/Radio/index.ts +2 -0
  455. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +169 -0
  456. package/rancher-components/components/Form/TextArea/index.ts +1 -0
  457. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +94 -0
  458. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +149 -0
  459. package/rancher-components/components/Form/ToggleSwitch/index.ts +1 -0
  460. package/rancher-components/components/Form/index.ts +5 -0
  461. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +152 -0
  462. package/rancher-components/components/LabeledTooltip/index.ts +1 -0
  463. package/rancher-components/components/StringList/StringList.test.ts +483 -0
  464. package/rancher-components/components/StringList/StringList.vue +605 -0
  465. package/rancher-components/components/StringList/index.ts +1 -0
  466. package/rancher-components/components/Utils/DraggableZone/DraggableZone.vue +181 -0
  467. package/rancher-components/components/Utils/DraggableZone/index.ts +1 -0
  468. package/scripts/publish-shell.sh +38 -5
  469. package/scripts/record-deps.js +37 -0
  470. package/scripts/test-plugins-build.sh +11 -7
  471. package/scripts/typegen.sh +84 -0
  472. package/store/action-menu.js +3 -3
  473. package/store/auth.js +4 -4
  474. package/store/aws.js +4 -4
  475. package/store/catalog.js +22 -22
  476. package/store/index.js +4 -4
  477. package/store/plugins.js +2 -2
  478. package/store/prefs.js +9 -1
  479. package/store/type-map.js +46 -31
  480. package/store/uiplugins.ts +2 -2
  481. package/store/wm.js +10 -0
  482. package/types/shell/index.d.ts +3059 -0
  483. package/types/vue-shim.d +20 -0
  484. package/utils/alertmanagerconfig.js +6 -6
  485. package/utils/gc/gc-types.ts +1 -1
  486. package/utils/object.js +2 -2
  487. package/utils/parse-externalid.js +5 -5
  488. package/utils/time.js +6 -0
  489. package/utils/validators/formRules/__tests__/index.test.ts +3 -3
  490. package/components/.DS_Store +0 -0
  491. package/components/__tests__/.DS_Store +0 -0
  492. package/creators/pkg/nuxt.config.js +0 -6
  493. package/creators/pkg/package-lock.json +0 -37
@@ -1,80 +1,455 @@
1
- import { mount } from '@vue/test-utils';
1
+ import { mount, Wrapper } from '@vue/test-utils';
2
2
  import { StringList } from './index';
3
3
 
4
4
  describe('StringList.vue', () => {
5
5
 
6
- it('is empty', () => {
7
- const wrapper = mount(StringList, {
6
+ let wrapper: Wrapper<Vue>;
7
+
8
+ beforeEach(() => {
9
+ wrapper = mount(StringList, {
8
10
  propsData: { items: [] },
9
11
  });
10
- const box = wrapper.find('[data-testid="div-string-list-box"]').element as HTMLElement;
11
-
12
- expect(box.children.length).toBe(0);
13
12
  });
14
13
 
15
- it('is showing one element', () => {
16
- const wrapper = mount(StringList, {
17
- propsData: { items: ['test'] },
14
+ describe('List box', () => {
15
+
16
+ it('is empty', () => {
17
+ const box = wrapper.find('[data-testid="div-string-list-box"]').element as HTMLElement;
18
+
19
+ expect(box.children.length).toBe(0);
18
20
  });
19
- const box = wrapper.find('.string-list-box').element as HTMLElement;
20
21
 
21
- expect(box.children.length).toBe(1);
22
- });
22
+ it('show multiple items', async () => {
23
+ const items = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k' ];
24
+ await wrapper.setProps({ items });
25
+
26
+ const elements = wrapper.findAll('[data-testid^="div-item"]');
27
+
28
+ expect(elements.length).toBe(10);
29
+ });
30
+
31
+ it('double click triggers inline edit mode', async () => {
32
+ const items = [ 'test' ];
33
+ await wrapper.setProps({ items });
34
+
35
+ const item = wrapper.find('[data-testid="div-item-test"]');
36
+ await item.trigger('dblclick');
37
+
38
+ const inputField = wrapper.find('[data-testid^="item-edit"]');
39
+
40
+ expect(inputField.element).toBeDefined();
41
+ });
42
+
43
+ it('double click on empty space triggers create mode', async () => {
44
+ await wrapper.setProps({ items: [] });
45
+
46
+ // double click on empty space
47
+ const box = wrapper.find('[data-testid="div-string-list-box"]');
48
+ await box.trigger('dblclick');
49
+
50
+ const inputField = wrapper.find('[data-testid="item-create"]');
51
+
52
+ expect(inputField.element).toBeDefined();
53
+ });
54
+
55
+ it('select item when click on it', async () => {
56
+ const items = [ 'test' ];
57
+ await wrapper.setProps({ items });
58
+
59
+ // select item
60
+ const item = wrapper.find('[data-testid^="div-item"]');
61
+ await item.trigger('mousedown');
62
+
63
+ expect(item.element.className).toContain('selected');
64
+ });
65
+
66
+ it('double click to edit item not allowed when readonly', async () => {
67
+ const items = [ 'test' ];
68
+ await wrapper.setProps({
69
+ items,
70
+ readonly: true,
71
+ });
72
+
73
+ const item = wrapper.find('[data-testid="div-item-test"]');
74
+ await item.trigger('dblclick');
23
75
 
24
- it('action-buttons are visible', () => {
25
- const wrapper = mount(StringList, {
26
- propsData: { items: ['test'] },
76
+ const inputField = wrapper.find('[data-testid^="item-edit"]');
77
+
78
+ expect(inputField.element).toBeUndefined();
79
+ });
80
+
81
+ it('double click on empty space to create item not allowed when readonly', async () => {
82
+ await wrapper.setProps({
83
+ items: [],
84
+ readonly: true,
85
+ });
86
+
87
+ // double click on empty space
88
+ const box = wrapper.find('[data-testid="div-string-list-box"]');
89
+ await box.trigger('dblclick');
90
+
91
+ const inputField = wrapper.find('[data-testid="item-create"]');
92
+
93
+ expect(inputField.element).toBeUndefined();
94
+ });
95
+
96
+ it('select item not allowed when readonly', async () => {
97
+ const items = [ 'test' ];
98
+ await wrapper.setProps({
99
+ items,
100
+ readonly: true,
101
+ });
102
+
103
+ // select item
104
+ const item = wrapper.find('[data-testid^="div-item"]');
105
+ await item.trigger('mousedown');
106
+
107
+ expect(item.element.className).not.toContain('selected');
27
108
  });
28
- const actionButtons = wrapper.find('[data-testid="div-action-buttons"]').element as HTMLElement;
29
109
 
30
- expect(actionButtons).not.toBe(undefined);
31
110
  });
32
111
 
33
- it('action-buttons are hidden when is view-only mode', () => {
34
- const wrapper = mount(StringList, {
35
- propsData: {
36
- items: ['test'],
112
+ describe('Buttons', () => {
113
+
114
+ it('are visible by default', async () => {
115
+ const actionButtons = wrapper.find('[data-testid="div-action-buttons"]');
116
+
117
+ expect(actionButtons.element).toBeDefined();
118
+ });
119
+
120
+ it('are hidden when is view-only mode', async () => {
121
+ await wrapper.setProps({
37
122
  readonly: true,
38
- },
123
+ });
124
+ const actionButtons = wrapper.find('[data-testid="div-action-buttons"]');
125
+
126
+ expect(actionButtons.element).toBeUndefined();
127
+ });
128
+
129
+ describe('Add button', () => {
130
+
131
+ it('is enabled by default', async () => {
132
+ const addButton = wrapper.find('[data-testid="button-add"]')?.element as HTMLButtonElement;
133
+
134
+ expect(addButton.disabled).toBe(false);
135
+ });
136
+
137
+ it('show the input field when is clicked', async () => {
138
+ // click add button
139
+ const addButton = wrapper.find('[data-testid="button-add"]');
140
+ await addButton.trigger('click');
141
+
142
+ const inputField = wrapper.find('[data-testid="item-create"]');
143
+
144
+ expect(inputField.element).toBeDefined();
145
+ });
146
+
147
+ it('is disabled when create mode is active', async () => {
148
+ // click add button
149
+ const addButton = wrapper.find('[data-testid="button-add"]');
150
+ await addButton.trigger('click');
151
+
152
+ wrapper.find('[data-testid="item-create"]');
153
+
154
+ const buttonElem = addButton.element as HTMLButtonElement;
155
+
156
+ expect(buttonElem.disabled).toBe(true);
157
+ });
158
+
159
+ });
160
+
161
+ describe('Remove button', () => {
162
+
163
+ it('is disabled by default', async () => {
164
+ const removeButton = wrapper.find('[data-testid="button-remove"]');
165
+ const buttonElem = removeButton.element as HTMLButtonElement;
166
+
167
+ expect(buttonElem.disabled).toBe(true);
168
+ });
169
+
170
+ it('is enabled when create mode is active', async () => {
171
+ // click add button
172
+ const addButton = wrapper.find('[data-testid="button-add"]');
173
+ await addButton.trigger('click');
174
+
175
+ const removeButton = wrapper.find('[data-testid="button-remove"]');
176
+ const buttonElem = removeButton.element as HTMLButtonElement;
177
+
178
+ expect(buttonElem.disabled).toBe(false);
179
+ });
180
+
181
+ it('is enabled when edit mode is active', async () => {
182
+ const items = [ 'test' ];
183
+ await wrapper.setProps({ items });
184
+
185
+ // activate edit mode
186
+ await wrapper.setData({ editedItem: 'test' });
187
+
188
+ const removeButton = wrapper.find('[data-testid="button-remove"]');
189
+ const buttonElem = removeButton.element as HTMLButtonElement;
190
+
191
+ expect(buttonElem.disabled).toBe(false);
192
+ });
193
+
194
+ it('is enabled when an item is selected', async () => {
195
+ const items = [ 'test' ];
196
+ await wrapper.setProps({ items });
197
+
198
+ // select item
199
+ await wrapper.setData({ selected: 'test' });
200
+
201
+ // click remove button
202
+ const removeButton = wrapper.find('[data-testid="button-remove"]');
203
+ const buttonElem = removeButton.element as HTMLButtonElement;
204
+
205
+ expect(buttonElem.disabled).toBe(false);
206
+ });
207
+
208
+ it('removes items when an item is selected', async () => {
209
+ const items = [ 'a' ];
210
+ await wrapper.setProps({ items });
211
+
212
+ // select item
213
+ await wrapper.setData({ selected: 'a' });
214
+
215
+ // click remove button
216
+ const removeButton = wrapper.find('[data-testid="button-remove"]');
217
+ await removeButton.trigger('mousedown');
218
+
219
+ await wrapper.vm.$nextTick();
220
+
221
+ const itemsCount = (wrapper.emitted('change') as any)[0][0].length;
222
+
223
+ expect(itemsCount).toBe(0);
224
+ });
225
+
226
+ it('deactivates create mode', async () => {
227
+ // activate create mode
228
+ await wrapper.setData({ isCreateItem: true });
229
+
230
+ // click remove button
231
+ const removeButton = wrapper.find('[data-testid="button-remove"]');
232
+ await removeButton.trigger('mousedown');
233
+
234
+ const inputField = await wrapper.find('[data-testid="item-create"]');
235
+
236
+ expect(inputField.element).toBeUndefined();
237
+ });
238
+
239
+ it('deactivates edit mode', async () => {
240
+ const items = [ 'test' ];
241
+ await wrapper.setProps({ items });
242
+
243
+ // activate edit mode
244
+ await wrapper.setData({ editedItem: 'test' });
245
+
246
+ // click remove button
247
+ const removeButton = wrapper.find('[data-testid="button-remove"]');
248
+ await removeButton.trigger('mousedown');
249
+
250
+ const inputField = wrapper.find('[data-testid^="item-edit"]');
251
+
252
+ expect(inputField.element).toBeUndefined();
253
+ });
254
+
39
255
  });
40
- const actionButtons = wrapper.find('[data-testid="div-action-buttons"]').element as HTMLElement;
41
256
 
42
- expect(actionButtons).toBe(undefined);
43
257
  });
44
258
 
45
- it('show new item when "items" property change', async () => {
46
- const items = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k'];
259
+ describe('List edit', () => {
47
260
 
48
- const wrapper = mount(StringList, {
49
- propsData: {
50
- items,
51
- },
261
+ const validItem = ' item name ';
262
+ const emptyItem = ' ';
263
+
264
+ it('save a new item in create mode by pressing Enter key', async () => {
265
+ // activate create mode
266
+ await wrapper.setData({ isCreateItem: true });
267
+
268
+ // type item name
269
+ const inputField = wrapper.find('[data-testid="item-create"]');
270
+ await inputField.setValue(validItem);
271
+
272
+ // press enter
273
+ await inputField.trigger('keydown.enter');
274
+ await wrapper.vm.$nextTick();
275
+
276
+ const emitted = (wrapper.emitted('change') as any)[0][0][0];
277
+
278
+ expect(emitted).toBe(validItem.trim());
279
+ });
280
+
281
+ it('save item in edit mode by pressing Enter key', async () => {
282
+ const items = [ 'test' ];
283
+ await wrapper.setProps({ items });
284
+
285
+ // activate edit mode
286
+ await wrapper.setData({ editedItem: 'test' });
287
+ const inputField = wrapper.find('[data-testid^="item-edit"]');
288
+
289
+ // edit item name
290
+ await inputField.setValue(validItem);
291
+
292
+ // press enter
293
+ await inputField.trigger('keydown.enter');
294
+ await wrapper.vm.$nextTick();
295
+
296
+ const emitted = (wrapper.emitted('change') as any)[0][0][0];
297
+
298
+ expect(emitted).toBe(validItem.trim());
299
+ });
300
+
301
+ it('reject a new item in create mode when item name is empty', async () => {
302
+ // activate create mode
303
+ await wrapper.setData({ isCreateItem: true });
304
+
305
+ // type item name
306
+ const inputField = wrapper.find('[data-testid="item-create"]');
307
+ await inputField.setValue(emptyItem);
308
+
309
+ // press enter
310
+ await inputField.trigger('keydown.enter');
311
+ await wrapper.vm.$nextTick();
312
+
313
+ expect(wrapper.emitted('change')).toBeFalsy();
314
+ });
315
+
316
+ it('reject a new item in create mode when item name is duplicate', async () => {
317
+ const items = [ 'test' ];
318
+ await wrapper.setProps({ items });
319
+
320
+ // activate create mode
321
+ await wrapper.setData({ isCreateItem: true });
322
+
323
+ // type item name
324
+ const inputField = wrapper.find('[data-testid="item-create"]');
325
+ await inputField.setValue('test');
326
+
327
+ // press enter
328
+ await inputField.trigger('keydown.enter');
329
+ await wrapper.vm.$nextTick();
330
+
331
+ expect(wrapper.emitted('change')).toBeFalsy();
332
+ });
333
+
334
+ it('reject an item in edit mode when item name is empty', async () => {
335
+ const items = [ 'test' ];
336
+ await wrapper.setProps({ items });
337
+
338
+ // activate edit mode
339
+ await wrapper.setData({ editedItem: 'test' });
340
+ const inputField = wrapper.find('[data-testid^="item-edit"]');
341
+
342
+ // edit item name
343
+ await inputField.setValue(emptyItem);
344
+
345
+ // press enter
346
+ await inputField.trigger('keydown.enter');
347
+ await wrapper.vm.$nextTick();
348
+
349
+ expect(wrapper.emitted('change')).toBeFalsy();
52
350
  });
53
- const elements = wrapper.findAll('[data-testid^="div-item"]');
54
351
 
55
- expect(elements.length).toBe(10);
352
+ it('reject an item in edit mode when item name is duplicate', async () => {
353
+ const items = [ 'test', 'test-1' ];
354
+ await wrapper.setProps({ items });
355
+
356
+ // activate edit mode
357
+ await wrapper.setData({ editedItem: 'test' });
358
+ const inputField = wrapper.find('[data-testid^="item-edit"]');
56
359
 
57
- await wrapper.setProps({ items: [ ...items, 'new' ] });
360
+ // edit item name
361
+ await inputField.setValue('test-1');
362
+
363
+ // press enter
364
+ await inputField.trigger('keydown.enter');
365
+ await wrapper.vm.$nextTick();
366
+
367
+ expect(wrapper.emitted('change')).toBeFalsy();
368
+ });
58
369
 
59
- const newElements = wrapper.findAll('[data-testid^="div-item"]');
60
- expect(newElements.length).toBe(11);
61
370
  });
62
371
 
63
- it('remove item when "items" property change', async () => {
64
- const items = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k'];
372
+ describe('Errors handling', () => {
373
+
374
+ it('show duplicate warning icon when errorMessages is defined', async () => {
375
+ const items = [ 'test' ];
376
+ await wrapper.setProps({
377
+ items,
378
+ errorMessages: { duplicate: 'error, item is duplicate.' },
379
+ });
380
+
381
+ // activate edit mode
382
+ await wrapper.setData({ isCreateItem: true });
383
+
384
+ // type item name
385
+ const inputField = wrapper.find('[data-testid="item-create"]');
386
+ await inputField.setValue('test');
387
+
388
+ const icon = wrapper.find('[data-testid="i-warning-icon"]');
389
+
390
+ expect(icon.element).toBeDefined();
391
+ });
392
+
393
+ it('show duplicate warning message when errorMessages is defined', async () => {
394
+ const items = [ 'test' ];
395
+ await wrapper.setProps({
396
+ items,
397
+ errorMessages: { duplicate: 'error, item is duplicate.' },
398
+ });
399
+
400
+ // activate edit mode
401
+ await wrapper.setData({ isCreateItem: true });
402
+
403
+ // type item name
404
+ const inputField = wrapper.find('[data-testid="item-create"]');
405
+ await inputField.setValue('test');
406
+
407
+ const message = wrapper.find('[data-testid^="span-error-message"]');
408
+
409
+ expect(message.element).toBeDefined();
410
+ });
65
411
 
66
- const wrapper = mount(StringList, {
67
- propsData: {
412
+ it('emit duplicate errors', async () => {
413
+ const items = [ 'test' ];
414
+ await wrapper.setProps({
68
415
  items,
69
- },
416
+ });
417
+
418
+ // activate edit mode
419
+ await wrapper.setData({ isCreateItem: true });
420
+
421
+ // type item name
422
+ const inputField = wrapper.find('[data-testid="item-create"]');
423
+ await inputField.setValue('test');
424
+
425
+ const isDuplicate = (wrapper.emitted('errors') as any)[0][0].duplicate;
426
+
427
+ expect(isDuplicate).toBe(true);
70
428
  });
71
- const elements = wrapper.findAll('[data-testid^="div-item"]');
72
- expect(elements.length).toBe(10);
73
429
 
74
- await wrapper.setProps({ items: [ ...items.filter(f => f !== 'a') ] });
430
+ it('emit duplicate errors, reset error', async () => {
431
+ const items = [ 'test' ];
432
+ await wrapper.setProps({
433
+ items,
434
+ });
435
+
436
+ // activate edit mode
437
+ await wrapper.setData({ isCreateItem: true });
438
+
439
+ // type item name
440
+ const inputField = wrapper.find('[data-testid="item-create"]');
441
+
442
+ // emit duplicate errors
443
+ await inputField.setValue('test');
444
+
445
+ // it is not duplicate, reset duplicate error -> emit false
446
+ await inputField.setValue('test-1');
447
+
448
+ const isDuplicate = (wrapper.emitted('errors') as any)[0][0].duplicate;
449
+
450
+ expect(isDuplicate).toBe(false);
451
+ });
75
452
 
76
- const newElements = wrapper.findAll('[data-testid^="div-item"]');
77
- expect(newElements.length).toBe(9);
78
453
  });
79
454
 
80
455
  });
@@ -410,6 +410,7 @@ export default Vue.extend({
410
410
  <LabeledInput
411
411
  v-if="editedItem && editedItem === item"
412
412
  ref="item-edit"
413
+ :data-testid="`item-edit-${item}`"
413
414
  class="edit-input static"
414
415
  :value="value != null ? value : item"
415
416
  @input="onChange($event)"
@@ -423,6 +424,7 @@ export default Vue.extend({
423
424
  >
424
425
  <LabeledInput
425
426
  ref="item-create"
427
+ data-testid="item-create"
426
428
  class="create-input static"
427
429
  type="text"
428
430
  :value="value"
@@ -443,6 +445,7 @@ export default Vue.extend({
443
445
  class="action-buttons"
444
446
  >
445
447
  <button
448
+ data-testid="button-remove"
446
449
  class="btn btn-sm role-tertiary remove-button"
447
450
  :disabled="!selected && !isCreateItem && !editedItem"
448
451
  @mousedown.prevent="onClickMinusButton"
@@ -450,6 +453,7 @@ export default Vue.extend({
450
453
  <span class="icon icon-minus icon-sm" />
451
454
  </button>
452
455
  <button
456
+ data-testid="button-add"
453
457
  class="btn btn-sm role-tertiary add-button"
454
458
  :disabled="isCreateItem || editedItem"
455
459
  @click.prevent="onClickPlusButton"
@@ -458,10 +462,15 @@ export default Vue.extend({
458
462
  </button>
459
463
  </div>
460
464
  <div class="messages">
461
- <i v-if="errorMessagesArray.length > 0" class="icon icon-warning icon-lg" />
465
+ <i
466
+ v-if="errorMessagesArray.length > 0"
467
+ data-testid="i-warning-icon"
468
+ class="icon icon-warning icon-lg"
469
+ />
462
470
  <span
463
471
  v-for="(msg, idx) in errorMessagesArray"
464
472
  :key="idx"
473
+ :data-testid="`span-error-message-${msg}`"
465
474
  class="error"
466
475
  >
467
476
  {{ idx > 0 ? '; ' : '' }}