@rancher/shell 3.0.12-rc.1 → 3.0.12-rc.2

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 (134) hide show
  1. package/assets/images/providers/entraid-black.svg +4 -0
  2. package/assets/images/providers/entraid.svg +9 -0
  3. package/assets/images/vendor/entraid.svg +9 -0
  4. package/assets/styles/app.scss +0 -1
  5. package/assets/translations/en-us.yaml +19 -17
  6. package/assets/translations/zh-hans.yaml +4 -8
  7. package/chart/__tests__/S3.test.ts +10 -3
  8. package/components/CountBox.vue +20 -0
  9. package/components/CreateDriver.vue +0 -12
  10. package/components/DetailText.vue +12 -3
  11. package/components/SelectIconGrid.vue +5 -0
  12. package/components/__tests__/CountBox.test.ts +72 -0
  13. package/components/__tests__/DetailText.test.ts +113 -0
  14. package/components/fleet/FleetClusterTargets/index.vue +18 -1
  15. package/components/form/InputWithSelect.vue +18 -10
  16. package/components/form/KeyValue.vue +17 -1
  17. package/components/form/LabeledSelect.vue +82 -24
  18. package/components/form/Select.vue +73 -56
  19. package/components/form/ServiceNameSelect.vue +13 -11
  20. package/components/form/__tests__/KeyValue.test.ts +66 -0
  21. package/components/form/__tests__/NodeScheduling.test.ts +9 -0
  22. package/components/form/labeled-select-utils/useLabeledSelectPagination.ts +138 -0
  23. package/components/nav/Group.vue +7 -6
  24. package/components/nav/Header.vue +24 -3
  25. package/components/nav/NotificationCenter/Notification.vue +4 -1
  26. package/components/nav/NotificationCenter/NotificationHeader.vue +20 -8
  27. package/components/nav/NotificationCenter/__tests__/NotificationHeader.test.ts +80 -0
  28. package/components/nav/Type.vue +8 -7
  29. package/components/nav/WindowManager/index.vue +2 -1
  30. package/components/nav/WorkspaceSwitcher.vue +13 -0
  31. package/components/nav/__tests__/Group.test.ts +67 -0
  32. package/components/nav/__tests__/Header.test.ts +235 -0
  33. package/components/nav/__tests__/Type.test.ts +20 -3
  34. package/components/templates/default.vue +34 -4
  35. package/components/templates/home.vue +12 -25
  36. package/components/templates/plain.vue +13 -26
  37. package/composables/useLabeledFormElement.ts +10 -2
  38. package/composables/useLabeledSelect.ts +60 -0
  39. package/composables/useUserRetentionValidation.ts +1 -49
  40. package/config/cookies.js +0 -1
  41. package/config/labels-annotations.js +1 -0
  42. package/config/query-params.js +1 -0
  43. package/config/router/routes.js +0 -8
  44. package/core/__tests__/plugin-products.test.ts +616 -25
  45. package/core/plugin-products-base.ts +31 -14
  46. package/core/plugin-products-helpers.ts +5 -4
  47. package/core/plugin-types.ts +18 -3
  48. package/core/types.ts +3 -1
  49. package/detail/__tests__/management.cattle.io.fleetworkspace.test.ts +128 -0
  50. package/detail/management.cattle.io.fleetworkspace.vue +49 -0
  51. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +9 -0
  52. package/edit/__tests__/kontainerDriver.test.ts +0 -13
  53. package/edit/__tests__/nodeDriver.test.ts +5 -11
  54. package/edit/__tests__/resources.cattle.io.restore.test.ts +9 -0
  55. package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +6 -0
  56. package/edit/auth/__tests__/oidc.test.ts +54 -0
  57. package/edit/auth/azuread.vue +1 -1
  58. package/edit/auth/oidc.vue +8 -0
  59. package/edit/kontainerDriver.vue +1 -2
  60. package/edit/nodeDriver.vue +0 -2
  61. package/edit/provisioning.cattle.io.cluster/AgentEnv.vue +1 -0
  62. package/edit/provisioning.cattle.io.cluster/__tests__/AgentEnv.test.ts +25 -0
  63. package/edit/provisioning.cattle.io.cluster/index.vue +70 -99
  64. package/initialize/App.vue +29 -2
  65. package/initialize/install-plugins.js +0 -2
  66. package/list/__tests__/management.cattle.io.feature.test.ts +105 -0
  67. package/list/catalog.cattle.io.app.vue +25 -5
  68. package/list/management.cattle.io.feature.vue +1 -1
  69. package/list/management.cattle.io.fleetworkspace.vue +8 -0
  70. package/machine-config/amazonec2.vue +1 -0
  71. package/mixins/chart.js +40 -9
  72. package/models/__tests__/catalog.cattle.io.app.test.ts +15 -1
  73. package/models/__tests__/catalog.cattle.io.clusterrepo.test.ts +84 -0
  74. package/models/__tests__/chart.test.ts +99 -6
  75. package/models/__tests__/management.cattle.io.feature.test.ts +131 -0
  76. package/models/__tests__/monitoring.coreos.com.alertmanagerconfig.test.ts +98 -0
  77. package/models/catalog.cattle.io.app.js +21 -17
  78. package/models/catalog.cattle.io.clusterrepo.js +39 -11
  79. package/models/chart.js +33 -19
  80. package/models/fleet-application.js +1 -1
  81. package/models/fleet.cattle.io.bundle.js +1 -1
  82. package/models/kontainerdriver.js +11 -0
  83. package/models/management.cattle.io.authconfig.js +5 -1
  84. package/models/management.cattle.io.cluster.js +0 -53
  85. package/models/management.cattle.io.feature.js +3 -3
  86. package/models/management.cattle.io.kontainerdriver.js +1 -26
  87. package/models/monitoring.coreos.com.alertmanagerconfig.js +31 -17
  88. package/models/nodedriver.js +7 -0
  89. package/package.json +13 -12
  90. package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +189 -0
  91. package/pages/c/_cluster/apps/charts/__tests__/index.test.ts +55 -0
  92. package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +53 -0
  93. package/pages/c/_cluster/apps/charts/chart.vue +217 -33
  94. package/pages/c/_cluster/apps/charts/index.vue +2 -2
  95. package/pages/c/_cluster/apps/charts/install.vue +8 -3
  96. package/pages/c/_cluster/auth/user.retention/index.vue +55 -22
  97. package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +5 -7
  98. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +39 -2
  99. package/pages/c/_cluster/uiplugins/__tests__/PluginInfoPanel.test.ts +61 -0
  100. package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +15 -10
  101. package/pages/c/_cluster/uiplugins/index.vue +23 -25
  102. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +205 -1
  103. package/rancher-components/Form/LabeledInput/LabeledInput.vue +82 -4
  104. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +1 -1
  105. package/scripts/test-plugins-build.sh +5 -2
  106. package/server/server-middleware.js +2 -2
  107. package/static/humans.txt +1 -0
  108. package/static/robots.txt +34 -0
  109. package/static/welcome-cow.svg +18 -0
  110. package/store/__tests__/catalog.test.ts +161 -11
  111. package/store/auth.js +0 -3
  112. package/store/catalog.js +60 -8
  113. package/types/shell/index.d.ts +26 -22
  114. package/utils/__tests__/git.test.ts +270 -0
  115. package/utils/__tests__/inactivity.test.ts +316 -0
  116. package/utils/__tests__/object.test.ts +77 -0
  117. package/utils/__tests__/time.test.ts +14 -1
  118. package/utils/__tests__/url.test.ts +246 -0
  119. package/utils/object.js +33 -2
  120. package/utils/time.ts +5 -0
  121. package/vue.config.js +0 -9
  122. package/assets/images/providers/azuread-black.svg +0 -22
  123. package/assets/images/providers/azuread.svg +0 -25
  124. package/assets/images/vendor/azuread.svg +0 -18
  125. package/assets/styles/fonts/_dots.scss +0 -18
  126. package/components/EmberPage.vue +0 -622
  127. package/components/EmberPageView.vue +0 -39
  128. package/components/form/labeled-select-utils/labeled-select-pagination.ts +0 -116
  129. package/mixins/labeled-form-element.ts +0 -225
  130. package/pages/c/_cluster/explorer/tools/pages/_page.vue +0 -28
  131. package/pages/c/_cluster/manager/pages/_page.vue +0 -22
  132. package/pages/c/_cluster/mcapps/pages/_page.vue +0 -22
  133. package/plugins/ember-cookie.js +0 -17
  134. package/utils/ember-page.js +0 -30
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="uuid-224e3580-d59f-48a8-9bb3-c822840f911d" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
3
+ <path d="m17.558,9.638L10.436,1.632c-.358-.402-.881-.632-1.435-.632h0c-.554,0-1.078.231-1.435.632L.442,9.638c-.346.389-.5.9-.423,1.403.077.503.379.952.827,1.231l7.123,4.436c.313.195.672.293,1.031.293s.718-.098,1.031-.293l7.123-4.436c.448-.279.75-.728.827-1.231.077-.503-.077-1.014-.423-1.403Zm-8.557,2.564l-3.47-2.161,3.47-3.9,3.47,3.9-3.47,2.161Zm-4.821-1.975l3.995,2.489-1.137.708-.016.01c-.394.25-.854.382-1.33.382-.528,0-1.059-.214-1.38-.413l-2.969-1.849c-.235-.147-.387-.373-.428-.637-.04-.264.037-.521.219-.725L8.257,2.186c.185-.208.456-.327.743-.328.287,0,.558.119.743.328l1.576,1.771c-.009,0-.018,0-.028,0-.856,0-1.668.313-2.278.866l-4.833,5.404Zm12.905.69c-.041.264-.192.49-.428.637l-7.123,4.436c-.325.202-.744.202-1.068,0l-2.192-1.365c.451-.076.88-.238,1.264-.484l6.259-3.898-4.197-4.759c.448-.425,1.053-.667,1.692-.667.335,0,.661.07.97.201l4.605,5.175c.181.204.259.461.219.725Z"/>
4
+ </svg>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="uuid-f8d4d392-7c12-4bd9-baff-66fbf7814b91" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
3
+ <path d="m3.802,14.032c.388.242,1.033.511,1.715.511.621,0,1.198-.18,1.676-.487,0,0,.001,0,.002-.001l1.805-1.128v4.073c-.286,0-.574-.078-.824-.234l-4.374-2.734Z" fill="#225086"/>
4
+ <path d="m7.853,1.507L.353,9.967c-.579.654-.428,1.642.323,2.111,0,0,2.776,1.735,3.126,1.954.388.242,1.033.511,1.715.511.621,0,1.198-.18,1.676-.487,0,0,.001,0,.002-.001l1.805-1.128-4.364-2.728,4.365-4.924V1s0,0,0,0c-.424,0-.847.169-1.147.507Z" fill="#6df"/>
5
+ <polygon points="4.636 10.199 4.688 10.231 9 12.927 9.001 12.927 9.001 12.927 9.001 5.276 9 5.275 4.636 10.199" fill="#cbf8ff"/>
6
+ <path d="m17.324,12.078c.751-.469.902-1.457.323-2.111l-4.921-5.551c-.397-.185-.842-.291-1.313-.291-.925,0-1.752.399-2.302,1.026l-.109.123h0s4.364,4.924,4.364,4.924h0s0,0,0,0l-4.365,2.728v4.073c.287,0,.573-.078.823-.234l7.5-4.688Z" fill="#074793"/>
7
+ <path d="m9.001,1v4.275s.109-.123.109-.123c.55-.627,1.377-1.026,2.302-1.026.472,0,.916.107,1.313.291l-2.579-2.909c-.299-.338-.723-.507-1.146-.507Z" fill="#0294e4"/>
8
+ <polygon points="13.365 10.199 13.365 10.199 13.365 10.199 9.001 5.276 9.001 12.926 13.365 10.199" fill="#96bcc2"/>
9
+ </svg>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="uuid-f8d4d392-7c12-4bd9-baff-66fbf7814b91" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
3
+ <path d="m3.802,14.032c.388.242,1.033.511,1.715.511.621,0,1.198-.18,1.676-.487,0,0,.001,0,.002-.001l1.805-1.128v4.073c-.286,0-.574-.078-.824-.234l-4.374-2.734Z" fill="#225086"/>
4
+ <path d="m7.853,1.507L.353,9.967c-.579.654-.428,1.642.323,2.111,0,0,2.776,1.735,3.126,1.954.388.242,1.033.511,1.715.511.621,0,1.198-.18,1.676-.487,0,0,.001,0,.002-.001l1.805-1.128-4.364-2.728,4.365-4.924V1s0,0,0,0c-.424,0-.847.169-1.147.507Z" fill="#6df"/>
5
+ <polygon points="4.636 10.199 4.688 10.231 9 12.927 9.001 12.927 9.001 12.927 9.001 5.276 9 5.275 4.636 10.199" fill="#cbf8ff"/>
6
+ <path d="m17.324,12.078c.751-.469.902-1.457.323-2.111l-4.921-5.551c-.397-.185-.842-.291-1.313-.291-.925,0-1.752.399-2.302,1.026l-.109.123h0s4.364,4.924,4.364,4.924h0s0,0,0,0l-4.365,2.728v4.073c.287,0,.573-.078.823-.234l7.5-4.688Z" fill="#074793"/>
7
+ <path d="m9.001,1v4.275s.109-.123.109-.123c.55-.627,1.377-1.026,2.302-1.026.472,0,.916.107,1.313.291l-2.579-2.909c-.299-.338-.723-.507-1.146-.507Z" fill="#0294e4"/>
8
+ <polygon points="13.365 10.199 13.365 10.199 13.365 10.199 9.001 5.276 9.001 12.926 13.365 10.199" fill="#96bcc2"/>
9
+ </svg>
@@ -10,7 +10,6 @@
10
10
  @import "./base/spacing";
11
11
 
12
12
  @import "./fonts/fontstack";
13
- @import "./fonts/dots";
14
13
  @import "./fonts/zerowidthspace";
15
14
  @import "./fonts/icons";
16
15
 
@@ -132,6 +132,7 @@ generic:
132
132
  deprecated: Deprecated
133
133
  upgradeable: Upgradeable
134
134
  installed: Installed
135
+ installedMultiple: Installed (multiple)
135
136
  featured: Featured
136
137
  shortFeatured: Feat
137
138
  category: Category
@@ -184,6 +185,7 @@ locale:
184
185
  none: (None)
185
186
 
186
187
  nav:
188
+ skipToContent: Skip to main content
187
189
  ariaLabel:
188
190
  clusterIconKeyCombo: Cluster keyboard shortcut combination icon
189
191
  localClusterIcon: Local Cluster icon
@@ -712,7 +714,7 @@ authConfig:
712
714
  azuread:
713
715
  tenantId:
714
716
  label: Tenant ID
715
- tooltip: From the Azure AD portal
717
+ tooltip: From the Microsoft Entra admin center
716
718
  placeholder: A long UUID string
717
719
  applicationId:
718
720
  label: Application ID
@@ -739,17 +741,17 @@ authConfig:
739
741
  externalHelp: See the OData filter expression documentation for more information.
740
742
  externalHelpLink: https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/webservices/use-filter-expressions-in-odata-uris#filter-expressions
741
743
  reply:
742
- info: 'Azure AD requires a whitelisted URL for your Rancher server before beginning this setup. Please ensure that the following URL is set in the Reply URL section of your Azure Portal. Please note that it may take up to 5 minutes for the whitelisted URL to propagate.'
744
+ info: 'Microsoft Entra ID requires a whitelisted URL for your Rancher server before beginning this setup. Please ensure that the following URL is set in the Reply URL section of your Microsoft Entra admin center. Please note that it may take up to 5 minutes for the whitelisted URL to propagate.'
743
745
  label: Reply URL
744
746
  ariaLabel: Copy Reply URL to clipboard
745
747
  updateEndpoint:
746
748
  button: Update Endpoint
747
749
  banner:
748
- message: 'Azure AD Authentication must be updated: it is using the Azure Graph API, which will be deprecated at the end of 2022.'
750
+ message: 'Microsoft Entra ID Authentication must be updated: it is using the Azure AD Graph API, which was deprecated at the end of 2022.'
749
751
  linkText: 'Update it here.'
750
752
  modal:
751
753
  title: Are you sure? This update is irreversible.
752
- body: '<p><b>You may need to make some additional changes</b>. Please ensure the Azure AD app has the Directory.Read.All <b>Application</b> permission added to Microsoft Graph.<br> If any endpoints were customized while configuring Azure AD authentication in Rancher, they will not be automatically updated. </p>'
754
+ body: '<p><b>You may need to make some additional changes</b>. Please ensure the Microsoft Entra ID app has the Directory.Read.All <b>Application</b> permission added to Microsoft Graph.<br> If any endpoints were customized while configuring Microsoft Entra ID authentication in Rancher, they will not be automatically updated. </p>'
753
755
  oidc:
754
756
  endSessionEndpoint:
755
757
  title: End Session Endpoint
@@ -806,6 +808,9 @@ authConfig:
806
808
  groupSearch:
807
809
  label: Enable group search
808
810
  tooltip: Allows users with appropriate permissions to search and view all groups within the OIDC provider's realm. This can be useful for administrators who need to assign global roles to groups that they are not currently a member of.
811
+ clientAuthenticatedSearch:
812
+ label: Enable client authenticated search
813
+ tooltip: Use the OIDC Client Credentials to authenticate to Keycloak when searching for users or groups. This will bypass user-based RBAC within the realm
809
814
  stateBanner:
810
815
  disabled: 'The {provider} authentication provider is currently disabled.'
811
816
  enabled: 'The {provider} authentication provider is currently enabled.'
@@ -1138,7 +1143,6 @@ catalog:
1138
1143
  label: Chart Versions
1139
1144
  showMore: Show More
1140
1145
  showLess: Show Less
1141
- missingVersionDate: No date available for this chart version
1142
1146
  home: Homepage
1143
1147
  repository: Repository Page
1144
1148
  maintainers: Maintainers
@@ -1152,12 +1156,15 @@ catalog:
1152
1156
  deprecatedWarning: '{chartName} has been marked as deprecated. Use caution when installing this helm chart as it might be removed in the future.'
1153
1157
  experimentalWarning: '{chartName} has been marked as experimental. Use caution when installing this helm chart as it might not function as expected.'
1154
1158
  deprecatedAndExperimentalWarning: '{chartName} has been marked as deprecated and experimental. Use caution when installing this helm chart as it might be removed in the future and might not function as expected.'
1159
+ installedAppsSelector:
1160
+ ariaLabel: Select installed app instance
1155
1161
  chartButton:
1156
1162
  action:
1157
1163
  install: Install this version
1158
1164
  edit: Edit the current version
1159
1165
  upgrade: Upgrade to this version
1160
1166
  downgrade: Downgrade to this version
1167
+ installNew: Install as a new instance
1161
1168
  charts:
1162
1169
  browseAriaLabel: Show only charts grid
1163
1170
  iconAlt: Icon for {app} card/grid item
@@ -1183,15 +1190,11 @@ catalog:
1183
1190
  all: All Operating Systems
1184
1191
  linux: Linux
1185
1192
  windows: Windows
1186
- search: Search the catalogue...
1187
- deprecatedChartsFilter:
1188
- label: Show deprecated apps
1193
+ search: Search the catalog...
1189
1194
  addNewRepo:
1190
1195
  label: Add new
1191
1196
  ariaLabel: Add a new repository
1192
1197
  appChartCard:
1193
- subHeaderItem:
1194
- missingVersionDate: Last updated date is not available for this chart
1195
1198
  footerItem:
1196
1199
  ariaLabel: 'Apply {filter} filter'
1197
1200
  statusFilterCautions:
@@ -1435,6 +1438,8 @@ catalog:
1435
1438
  refreshInterval:
1436
1439
  label: Refresh Interval
1437
1440
  placeholder: 'default: {hours}'
1441
+ error:
1442
+ refresh: Error refreshing repository
1438
1443
  tools:
1439
1444
  iconAlt: Icon for {app} Cluster Tool
1440
1445
  header: Cluster Tools
@@ -2836,8 +2841,8 @@ providers:
2836
2841
  drivers:
2837
2842
  kontainer:
2838
2843
  title: Cluster Drivers
2839
- emberDeprecationMessage: 'Support for UI Plugins (based on Ember) for cluster and node drivers was deprecated in Rancher 2.11.0 and will be removed in a future release. These need to be migrated to the new <a href="https://extensions.rancher.io" target="_blank" rel="noopener noreferrer nofollow">UI Extensions framework</a>.'
2840
- refreshError: 'Error refreshing cluster drivers: {error}'
2844
+ emberRemovalMessage: 'Support for UI Plugins (based on Ember) for cluster and node drivers was deprecated in Rancher 2.11.0 and has been removed in 2.15.0. If you still need one of these plugins, it will need to be migrated to the new <a href="https://extensions.rancher.io/extensions/next/provisioning/hosted-provider/overview" target="_blank" rel="noopener noreferrer nofollow">UI Extensions framework</a>.'
2845
+ emberRemovalTooltip: 'Support for UI Plugins (based on Ember) for cluster and node drivers was deprecated in Rancher 2.11.0 and has been removed in 2.15.0. If you still need this plugin, it will need to be migrated to the new UI Extensions framework.'
2841
2846
  node:
2842
2847
  title: Node Drivers
2843
2848
  add:
@@ -5446,6 +5451,7 @@ inactivity:
5446
5451
  # Rancher Extensions
5447
5452
  plugins:
5448
5453
  altIcon: Icon for {extension} extension card
5454
+ deprecatedExtension: This extension is deprecated and may soon be removed from the catalog.
5449
5455
  incompatiblePrimeOnly: "The latest version of this extension ({ version }) needs Rancher Prime in order to be installed."
5450
5456
  incompatibleRancherVersion: "The latest version of this extension ({ version }) is not compatible with the current Rancher version ({ required })."
5451
5457
  incompatibleKubeVersion: "The latest version of this extension ({ version }) is not compatible with the current Kube version ({ required })."
@@ -7975,7 +7981,7 @@ model:
7975
7981
  local: Local
7976
7982
  multiple: Multiple
7977
7983
  activedirectory: ActiveDirectory
7978
- azuread: AzureAD
7984
+ azuread: Microsoft Entra ID
7979
7985
  github: GitHub
7980
7986
  githubapp: GitHub App
7981
7987
  keycloak: Keycloak
@@ -9174,10 +9180,6 @@ support:
9174
9180
  title: Innovate with Freedom
9175
9181
  text: Take advantage of our certified compatibility with a wide range of Kubernetes providers, operating systems, and open source software.
9176
9182
 
9177
- embedding:
9178
- retry: Retry
9179
- unavailable: Cluster Manager UI is not available
9180
-
9181
9183
  serverUpgrade:
9182
9184
  title: "{vendor} Server Changed"
9183
9185
  message: "The page reloaded because the version of {vendor} running on your server changed."
@@ -531,16 +531,16 @@ authConfig:
531
531
  tokenEndpoint: Token 端点
532
532
  authEndpoint: Auth 端点
533
533
  reply:
534
- info: '在开始设置之前,Azure AD 需要 Rancher Server 的白名单 URL。请确保在 Azure 门户的回复 URL 中设置了以下 URL。请注意,白名单 URL 可能需要 5 分钟才能生效。'
534
+ info: '在开始设置之前,Microsoft Entra ID 需要 Rancher Server 的白名单 URL。请确保在 Microsoft Entra 管理中心的回复 URL 中设置了以下 URL。请注意,白名单 URL 可能需要 5 分钟才能生效。'
535
535
  label: 回复 URL
536
536
  updateEndpoint:
537
537
  button: 更新端点
538
538
  banner:
539
- message: '必须更新 Azure AD 身份认证:它使用了 Azure Graph API,该 API 将于 2022 年底弃用。'
539
+ message: '必须更新 Microsoft Entra ID 身份认证:它使用了 Azure AD Graph API,该 API 已于 2022 年底弃用。'
540
540
  linkText: '在此处进行更新。'
541
541
  modal:
542
542
  title: 是否确认?此更新是不可逆的。
543
- body: '<p><b>你可能需要进行额外的更改</b>。请确保 Azure AD 应用已将 Directory.Read.All <b>Application</b> 权限添加到 Microsoft Graph。<br> 如果在 Rancher 中配置 Azure AD 身份认证时自定义了端点,这些端点将不会自动更新。</p>'
543
+ body: '<p><b>你可能需要进行额外的更改</b>。请确保 Microsoft Entra ID 应用已将 Directory.Read.All <b>Application</b> 权限添加到 Microsoft Graph。<br> 如果在 Rancher 中配置 Microsoft Entra ID 身份认证时自定义了端点,这些端点将不会自动更新。</p>'
544
544
  oidc:
545
545
  oidc: 配置 OIDC 账号
546
546
  keycloakoidc: 配置 Keycloak OIDC 账号
@@ -6269,7 +6269,7 @@ model:
6269
6269
  local: 本地
6270
6270
  multiple: Multiple
6271
6271
  activedirectory: Active Directory
6272
- azuread: AzureAD
6272
+ azuread: Microsoft Entra ID
6273
6273
  github: GitHub
6274
6274
  keycloak: Keycloak
6275
6275
  ldap: LDAP
@@ -7307,10 +7307,6 @@ support:
7307
7307
  title: 自由创新
7308
7308
  text: 基于我们与众多 Kubernetes 供应商、操作系统和开源软件认证的兼容性,实现自主创新。
7309
7309
 
7310
- embedding:
7311
- retry: 重试
7312
- unavailable: Cluster Manager UI 不可用
7313
-
7314
7310
  legacy:
7315
7311
  alerts: 告警
7316
7312
  apps: 应用
@@ -3,7 +3,7 @@ import { nextTick } from 'vue';
3
3
  import { mount } from '@vue/test-utils';
4
4
 
5
5
  import S3 from '@shell/chart/rancher-backup/S3';
6
- import Vuex from 'vuex';
6
+ import { createStore } from 'vuex';
7
7
 
8
8
  describe('rancher-backup: S3', () => {
9
9
  const mockStore = {
@@ -16,8 +16,15 @@ describe('rancher-backup: S3', () => {
16
16
  }
17
17
  };
18
18
  const wrapper = mount(S3, {
19
- plugins: [Vuex],
20
- global: { mocks: { $store: mockStore, $fetchState: { pending: false } } }
19
+ global: { mocks: { $store: mockStore, $fetchState: { pending: false } } },
20
+ provide: {
21
+ store: createStore({
22
+ getters: {
23
+ 'cluster/paginationEnabled': () => () => false,
24
+ currentStore: () => 'cluster'
25
+ }
26
+ })
27
+ },
21
28
  });
22
29
 
23
30
  it('should emit invalid when form is not filled', () => {
@@ -3,6 +3,8 @@
3
3
  export default {
4
4
  name: 'CountBox',
5
5
 
6
+ emits: ['click'],
7
+
6
8
  props: {
7
9
  name: {
8
10
  type: String,
@@ -19,6 +21,10 @@ export default {
19
21
  compact: {
20
22
  type: Boolean,
21
23
  default: false
24
+ },
25
+ clickable: {
26
+ type: Boolean,
27
+ default: false
22
28
  }
23
29
  },
24
30
  computed: {
@@ -34,6 +40,12 @@ export default {
34
40
  methods: {
35
41
  customizePrimaryColorOpacity(opacity) {
36
42
  return `rgba(var(${ this.primaryColorVar }), ${ opacity })`;
43
+ },
44
+
45
+ handleClick() {
46
+ if (this.clickable) {
47
+ this.$emit('click');
48
+ }
37
49
  }
38
50
  }
39
51
  };
@@ -42,7 +54,9 @@ export default {
42
54
  <template>
43
55
  <div
44
56
  class="count-container"
57
+ :class="{ 'clickable': clickable }"
45
58
  :style="sideStyle"
59
+ @click="handleClick"
46
60
  >
47
61
  <div
48
62
  class="count"
@@ -61,6 +75,12 @@ export default {
61
75
  </template>
62
76
 
63
77
  <style lang="scss" scoped>
78
+ .count-container {
79
+ &.clickable {
80
+ cursor: pointer;
81
+ }
82
+ }
83
+
64
84
  .count {
65
85
  $padding: 10px;
66
86
 
@@ -22,7 +22,6 @@ export default {
22
22
  rules: {
23
23
  default: () => ({
24
24
  url: [],
25
- uiUrl: [],
26
25
  checksum: [],
27
26
  whitelistDomains: []
28
27
  }),
@@ -56,17 +55,6 @@ export default {
56
55
  :data-testid="'driver-create-checksum-field'"
57
56
  />
58
57
  </div>
59
- <div class="row mb-20">
60
- <LabeledInput
61
- v-model:value.trim="value.uiUrl"
62
- :label="t('drivers.add.customUiUrl.label')"
63
- :tooltip="t('drivers.add.customUiUrl.tooltip', null, true)"
64
- :placeholder="t('drivers.add.customUiUrl.placeholder', null, true)"
65
- :mode="mode"
66
- :rules="rules.uiUrl"
67
- :data-testid="'driver-create-uiurl-field'"
68
- />
69
- </div>
70
58
  <div class="col span-6">
71
59
  <ArrayList
72
60
  v-model:value="value.whitelistDomains"
@@ -187,10 +187,9 @@ export default {
187
187
  >{{ body }}</span>
188
188
 
189
189
  <CodeMirror
190
- v-else-if="jsonStr"
190
+ v-else-if="jsonStr && !concealed"
191
191
  :options="{mode:{name:'javascript', json:true}, lineNumbers:false, foldGutter:false, readOnly:true}"
192
192
  :value="jsonStr"
193
- :class="{'conceal': concealed}"
194
193
  aria-live="polite"
195
194
  />
196
195
 
@@ -199,9 +198,16 @@ export default {
199
198
  :class="{'conceal-wrapper': concealed}"
200
199
  >
201
200
  <span
201
+ v-if="concealed"
202
+ data-testid="detail-top_html"
203
+ class="conceal"
204
+ aria-live="polite"
205
+ />
206
+ <span
207
+ v-else
202
208
  v-clean-html="bodyHtml"
203
209
  data-testid="detail-top_html"
204
- :class="{'conceal': concealed, 'monospace': monospace && !isBinary}"
210
+ :class="{'monospace': monospace && !isBinary}"
205
211
  aria-live="polite"
206
212
  />
207
213
  </div>
@@ -270,6 +276,9 @@ export default {
270
276
  .conceal {
271
277
  white-space: nowrap;
272
278
  display: block;
279
+ &::before {
280
+ content: '••••••••••••••••••••••••';
281
+ }
273
282
  }
274
283
 
275
284
  .action-group {
@@ -38,6 +38,10 @@ export default {
38
38
  type: String,
39
39
  default: 'disabled',
40
40
  },
41
+ tooltipField: {
42
+ type: String,
43
+ default: 'tooltip',
44
+ },
41
45
 
42
46
  asLink: {
43
47
  type: Boolean,
@@ -104,6 +108,7 @@ export default {
104
108
  :is="asLink ? 'a' : 'div'"
105
109
  v-for="(r, idx) in rows"
106
110
  :key="get(r, keyField)"
111
+ v-clean-tooltip="get(r, tooltipField) || null"
107
112
  :role="asLink ? 'link' : null"
108
113
  :aria-disabled="asLink && get(r, disabledField) === true ? true : null"
109
114
  :aria-label="get(r, nameField)"
@@ -0,0 +1,72 @@
1
+ import { shallowMount } from '@vue/test-utils';
2
+ import CountBox from '@shell/components/CountBox.vue';
3
+
4
+ describe('component: CountBox', () => {
5
+ const defaultProps = {
6
+ name: 'Test',
7
+ count: 5,
8
+ primaryColorVar: '--sizzle-1',
9
+ };
10
+
11
+ describe('when clickable is false', () => {
12
+ it('should render as a div', () => {
13
+ const wrapper = shallowMount(CountBox, { props: defaultProps });
14
+
15
+ expect(wrapper.element.tagName).toBe('DIV');
16
+ });
17
+
18
+ it('should not have the clickable class', () => {
19
+ const wrapper = shallowMount(CountBox, { props: defaultProps });
20
+
21
+ expect(wrapper.classes()).not.toContain('clickable');
22
+ });
23
+
24
+ it('should not emit click event when clicked', async() => {
25
+ const wrapper = shallowMount(CountBox, { props: defaultProps });
26
+
27
+ await wrapper.trigger('click');
28
+
29
+ expect(wrapper.emitted('click')).toBeUndefined();
30
+ });
31
+ });
32
+
33
+ describe('when clickable is true', () => {
34
+ it('should have the clickable class', () => {
35
+ const wrapper = shallowMount(CountBox, {
36
+ props: {
37
+ ...defaultProps,
38
+ clickable: true,
39
+ },
40
+ });
41
+
42
+ expect(wrapper.classes()).toContain('clickable');
43
+ });
44
+
45
+ it('should emit click event when clicked', async() => {
46
+ const wrapper = shallowMount(CountBox, {
47
+ props: {
48
+ ...defaultProps,
49
+ clickable: true,
50
+ },
51
+ });
52
+
53
+ await wrapper.trigger('click');
54
+
55
+ expect(wrapper.emitted('click')).toHaveLength(1);
56
+ });
57
+ });
58
+
59
+ describe('display', () => {
60
+ it('should display the count', () => {
61
+ const wrapper = shallowMount(CountBox, { props: defaultProps });
62
+
63
+ expect(wrapper.find('h1').text()).toBe('5');
64
+ });
65
+
66
+ it('should display the name', () => {
67
+ const wrapper = shallowMount(CountBox, { props: defaultProps });
68
+
69
+ expect(wrapper.find('label').text()).toBe('Test');
70
+ });
71
+ });
72
+ });
@@ -0,0 +1,113 @@
1
+ import { mount } from '@vue/test-utils';
2
+
3
+ import DetailText from '@shell/components/DetailText.vue';
4
+
5
+ jest.mock('@shell/utils/clipboard', () => ({ copyTextToClipboard: jest.fn() }));
6
+
7
+ describe('component: DetailText', () => {
8
+ const defaultMocks = {
9
+ $store: {
10
+ getters: {
11
+ 'i18n/t': jest.fn((key: string) => `%${ key }%`),
12
+ 'prefs/get': jest.fn(() => true),
13
+ }
14
+ }
15
+ };
16
+
17
+ describe('concealment', () => {
18
+ it('should not render the actual secret value in the content area when concealed', () => {
19
+ const secretValue = 'super-secret-password-xyz';
20
+ const wrapper = mount(DetailText, {
21
+ props: {
22
+ value: secretValue,
23
+ conceal: true,
24
+ label: 'Password',
25
+ },
26
+
27
+ global: {
28
+ mocks: defaultMocks,
29
+ directives: {
30
+ 'clean-html': () => {},
31
+ 'clean-tooltip': () => {},
32
+ t: () => {},
33
+ },
34
+ stubs: {
35
+ CopyToClipboard: true,
36
+ CodeMirror: true,
37
+ },
38
+ },
39
+ });
40
+
41
+ const concealedSpan = wrapper.find('[data-testid="detail-top_html"]');
42
+
43
+ expect(concealedSpan.exists()).toBe(true);
44
+ expect(concealedSpan.classes()).toContain('conceal');
45
+ expect(concealedSpan.text()).not.toContain(secretValue);
46
+ });
47
+
48
+ it('should render the actual value when not concealed', () => {
49
+ const visibleValue = 'visible-value-123';
50
+ const wrapper = mount(DetailText, {
51
+ props: {
52
+ value: visibleValue,
53
+ conceal: false,
54
+ label: 'Data',
55
+ },
56
+
57
+ global: {
58
+ mocks: defaultMocks,
59
+ directives: {
60
+ 'clean-html': (el: HTMLElement, binding: { value: string }) => {
61
+ el.innerHTML = binding.value;
62
+ },
63
+ 'clean-tooltip': () => {},
64
+ t: () => {},
65
+ },
66
+ stubs: {
67
+ CopyToClipboard: true,
68
+ CodeMirror: true,
69
+ },
70
+ },
71
+ });
72
+
73
+ const contentSpan = wrapper.find('[data-testid="detail-top_html"]');
74
+
75
+ expect(contentSpan.exists()).toBe(true);
76
+ expect(contentSpan.classes()).not.toContain('conceal');
77
+ });
78
+
79
+ it('should not render JSON secret values in CodeMirror when concealed', () => {
80
+ const jsonSecret = '{"api_key": "secret-key-123"}';
81
+ const wrapper = mount(DetailText, {
82
+ props: {
83
+ value: jsonSecret,
84
+ conceal: true,
85
+ label: 'Config',
86
+ },
87
+
88
+ global: {
89
+ mocks: defaultMocks,
90
+ directives: {
91
+ 'clean-html': () => {},
92
+ 'clean-tooltip': () => {},
93
+ t: () => {},
94
+ },
95
+ stubs: {
96
+ CopyToClipboard: true,
97
+ CodeMirror: true,
98
+ },
99
+ },
100
+ });
101
+
102
+ const codeMirror = wrapper.findComponent({ name: 'CodeMirror' });
103
+
104
+ expect(codeMirror.exists()).toBe(false);
105
+
106
+ const concealedSpan = wrapper.find('[data-testid="detail-top_html"]');
107
+
108
+ expect(concealedSpan.exists()).toBe(true);
109
+ expect(concealedSpan.classes()).toContain('conceal');
110
+ expect(concealedSpan.text()).not.toContain('secret-key-123');
111
+ });
112
+ });
113
+ });
@@ -124,6 +124,15 @@ export default {
124
124
  this.update();
125
125
  }
126
126
  },
127
+
128
+ allClusters(clusters: any[]) {
129
+ if (clusters.length) {
130
+ // Resolve metadata.name values to nameDisplay for UI display
131
+ this.selectedClusters = this.selectedClusters.map(
132
+ (name) => this.resolveClusterDisplayName(name)
133
+ );
134
+ }
135
+ },
127
136
  },
128
137
 
129
138
  computed: {
@@ -159,7 +168,7 @@ export default {
159
168
  clustersOptions() {
160
169
  return this.allClusters
161
170
  .filter((x) => x.metadata.namespace === this.namespace && !isHarvesterCluster(x))
162
- .map((x) => ({ label: x.nameDisplay, value: x.metadata.name }));
171
+ .map((x) => ({ label: x.nameDisplay, value: x.nameDisplay }));
163
172
  },
164
173
 
165
174
  clusterGroupsOptions() {
@@ -352,6 +361,14 @@ export default {
352
361
  return undefined;
353
362
  },
354
363
 
364
+ resolveClusterDisplayName(name: string): string {
365
+ const cluster = this.allClusters.find(
366
+ (c: any) => c.metadata.namespace === this.namespace && c.metadata.name === name
367
+ );
368
+
369
+ return cluster ? cluster.nameDisplay : name;
370
+ },
371
+
355
372
  reset() {
356
373
  this.targetMode = 'all';
357
374
  this.selectedClusters = [];
@@ -1,18 +1,22 @@
1
1
  <script>
2
- import labeledFormElement from '@shell/mixins/labeled-form-element';
3
2
  import { LabeledInput } from '@components/Form/LabeledInput';
4
3
  import LabeledSelect from '@shell/components/form/LabeledSelect';
5
4
  import Select from '@shell/components/form/Select';
5
+ import { computed } from 'vue';
6
+ import { _VIEW, _EDIT } from '@shell/config/query-params';
7
+
6
8
  export default {
7
- name: 'InputWithSelect',
9
+ name: 'InputWithSelect',
10
+
11
+ inheritAttrs: false,
12
+
8
13
  emits: ['update:value'],
9
14
  components: {
10
15
  LabeledInput,
11
16
  LabeledSelect,
12
17
  Select,
13
18
  },
14
- mixins: [labeledFormElement],
15
- props: {
19
+ props: {
16
20
  disabled: {
17
21
  type: Boolean,
18
22
  default: false,
@@ -84,10 +88,20 @@ export default {
84
88
  selectRules: {
85
89
  default: () => [],
86
90
  type: Array,
91
+ },
92
+ mode: {
93
+ type: String,
94
+ default: _EDIT,
87
95
  }
88
96
 
89
97
  },
90
98
 
99
+ setup(props) {
100
+ const isView = computed(() => props.mode === _VIEW);
101
+
102
+ return { isView };
103
+ },
104
+
91
105
  data() {
92
106
  return {
93
107
  selected: this.selectValue || this.options[0].value,
@@ -95,12 +109,6 @@ export default {
95
109
  };
96
110
  },
97
111
 
98
- computed: {
99
- canPaginate() {
100
- return false;
101
- }
102
- },
103
-
104
112
  methods: {
105
113
  focus() {
106
114
  const comp = this.$refs.text;