@rancher/shell 3.0.2-rc.2 → 3.0.2-rc.4

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 (172) hide show
  1. package/assets/styles/base/_basic.scss +7 -8
  2. package/assets/styles/global/_button.scss +10 -0
  3. package/assets/styles/global/_form.scss +2 -1
  4. package/assets/styles/global/_tooltip.scss +2 -2
  5. package/assets/styles/themes/_dark.scss +15 -3
  6. package/assets/styles/themes/_light.scss +7 -2
  7. package/assets/styles/vendor/vue-select.scss +4 -0
  8. package/assets/translations/en-us.yaml +66 -9
  9. package/assets/translations/zh-hans.yaml +2 -3
  10. package/components/AppModal.vue +50 -0
  11. package/components/BannerGraphic.vue +0 -42
  12. package/components/ButtonMultiAction.vue +1 -1
  13. package/components/Carousel.vue +88 -74
  14. package/components/CommunityLinks.vue +6 -1
  15. package/components/CopyToClipboardText.vue +3 -0
  16. package/components/Dialog.vue +20 -1
  17. package/components/GrowlManager.vue +9 -2
  18. package/components/LocaleSelector.vue +8 -1
  19. package/components/PaginatedResourceTable.vue +4 -7
  20. package/components/ProgressBarMulti.vue +14 -0
  21. package/components/PromptChangePassword.vue +3 -0
  22. package/components/Questions/Reference.vue +57 -28
  23. package/components/ResourceDetail/Masthead.vue +1 -1
  24. package/components/SelectIconGrid.vue +12 -1
  25. package/components/SideNav.vue +12 -38
  26. package/components/SortableTable/index.vue +1 -0
  27. package/components/Tabbed/index.vue +9 -1
  28. package/components/YamlEditor.vue +1 -0
  29. package/components/__tests__/Carousel.test.ts +56 -27
  30. package/components/auth/Principal.vue +5 -3
  31. package/components/fleet/FleetClusters.vue +82 -1
  32. package/components/fleet/FleetRepos.vue +13 -30
  33. package/components/fleet/ForceDirectedTreeChart/index.vue +2 -2
  34. package/components/form/ChangePassword.vue +2 -0
  35. package/components/form/ColorInput.vue +24 -1
  36. package/components/form/FileSelector.vue +2 -0
  37. package/components/form/KeyValue.vue +230 -160
  38. package/components/form/LabeledSelect.vue +2 -2
  39. package/components/form/PlusMinus.vue +14 -2
  40. package/components/form/ResourceLabeledSelect.vue +13 -53
  41. package/components/form/ResourceSelector.vue +1 -0
  42. package/components/form/ResourceTabs/index.vue +79 -36
  43. package/components/form/SSHKnownHosts/KnownHostsEditDialog.vue +192 -0
  44. package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +104 -0
  45. package/components/form/SSHKnownHosts/index.vue +101 -0
  46. package/components/form/SecretSelector.vue +2 -2
  47. package/components/form/Select.vue +1 -1
  48. package/components/form/SelectOrCreateAuthSecret.vue +43 -11
  49. package/components/form/__tests__/KeyValue.test.ts +1 -1
  50. package/components/form/__tests__/SSHKnownHosts.test.ts +59 -0
  51. package/components/formatter/FleetClusterSummaryGraph.vue +2 -2
  52. package/components/formatter/FleetSummaryGraph.vue +6 -7
  53. package/components/formatter/WorkloadHealthScale.vue +7 -0
  54. package/components/nav/Group.vue +30 -4
  55. package/components/nav/Header.vue +82 -114
  56. package/components/nav/HeaderPageActionMenu.vue +27 -131
  57. package/components/nav/NamespaceFilter.vue +1 -1
  58. package/components/nav/Type.vue +15 -0
  59. package/composables/focusTrap.ts +68 -0
  60. package/config/home-links.js +21 -13
  61. package/config/labels-annotations.js +2 -0
  62. package/config/page-actions.js +1 -0
  63. package/config/pagination-table-headers.js +15 -1
  64. package/config/product/explorer.js +7 -17
  65. package/config/table-headers.js +6 -0
  66. package/config/version.js +5 -1
  67. package/core/plugin.ts +41 -1
  68. package/core/plugins.js +125 -72
  69. package/core/types-provisioning.ts +91 -2
  70. package/core/types.ts +55 -0
  71. package/detail/__tests__/autoscaling.horizontalpodautoscaler.test.ts +12 -3
  72. package/detail/catalog.cattle.io.app.vue +1 -1
  73. package/detail/fleet.cattle.io.cluster.vue +3 -3
  74. package/detail/namespace.vue +13 -19
  75. package/detail/networking.k8s.io.ingress.vue +13 -53
  76. package/detail/provisioning.cattle.io.cluster.vue +12 -1
  77. package/detail/secret.vue +25 -0
  78. package/detail/workload/index.vue +3 -3
  79. package/dialog/AddCustomBadgeDialog.vue +5 -1
  80. package/edit/auth/ldap/__tests__/config.test.ts +18 -0
  81. package/edit/auth/ldap/config.vue +24 -0
  82. package/edit/auth/saml.vue +8 -6
  83. package/edit/fleet.cattle.io.gitrepo.vue +34 -23
  84. package/edit/logging-flow/index.vue +4 -19
  85. package/edit/networking.k8s.io.ingress/index.vue +18 -65
  86. package/edit/networking.k8s.io.networkpolicy/index.vue +4 -5
  87. package/edit/provisioning.cattle.io.cluster/index.vue +27 -8
  88. package/edit/provisioning.cattle.io.cluster/rke2.vue +31 -115
  89. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +2 -2
  90. package/edit/provisioning.cattle.io.cluster/tabs/networking/ACE.vue +14 -28
  91. package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +25 -12
  92. package/edit/secret/index.vue +1 -1
  93. package/edit/secret/ssh.vue +21 -3
  94. package/edit/service.vue +1 -2
  95. package/list/networking.k8s.io.ingress.vue +1 -1
  96. package/list/node.vue +15 -8
  97. package/list/persistentvolume.vue +12 -4
  98. package/list/provisioning.cattle.io.cluster.vue +1 -0
  99. package/list/service.vue +1 -1
  100. package/list/workload.vue +4 -0
  101. package/mixins/chart.js +4 -1
  102. package/models/catalog.cattle.io.app.js +3 -1
  103. package/models/catalog.cattle.io.clusterrepo.js +56 -7
  104. package/models/fleet.cattle.io.bundle.js +0 -11
  105. package/models/fleet.cattle.io.cluster.js +17 -1
  106. package/models/fleet.cattle.io.gitrepo.js +88 -52
  107. package/models/provisioning.cattle.io.cluster.js +36 -1
  108. package/models/secret.js +5 -0
  109. package/models/service.js +1 -0
  110. package/models/workload.js +19 -1
  111. package/package.json +5 -4
  112. package/pages/account/index.vue +4 -0
  113. package/pages/c/_cluster/apps/charts/index.vue +4 -0
  114. package/pages/c/_cluster/explorer/ConfigBadge.vue +4 -2
  115. package/pages/c/_cluster/explorer/index.vue +13 -6
  116. package/pages/c/_cluster/fleet/GitRepoGraphConfig.js +3 -3
  117. package/pages/c/_cluster/fleet/index.vue +75 -89
  118. package/pages/c/_cluster/settings/links.vue +2 -2
  119. package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +3 -1
  120. package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +3 -0
  121. package/pages/c/_cluster/uiplugins/CatalogList/CatalogUninstallDialog.vue +7 -1
  122. package/pages/c/_cluster/uiplugins/CatalogList/index.vue +3 -1
  123. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +10 -7
  124. package/pages/c/_cluster/uiplugins/InstallDialog.vue +7 -0
  125. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +181 -106
  126. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +2 -0
  127. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +9 -1
  128. package/pages/c/_cluster/uiplugins/index.vue +50 -12
  129. package/pages/diagnostic.vue +17 -15
  130. package/pages/home.vue +32 -6
  131. package/plugins/clean-html.js +50 -0
  132. package/plugins/dashboard-store/resource-class.js +4 -0
  133. package/plugins/plugin.js +54 -49
  134. package/plugins/steve/mutations.js +1 -1
  135. package/plugins/steve/steve-class.js +8 -0
  136. package/plugins/steve/steve-pagination-utils.ts +3 -1
  137. package/rancher-components/Accordion/Accordion.vue +4 -4
  138. package/rancher-components/BadgeState/BadgeState.vue +7 -0
  139. package/rancher-components/Card/Card.vue +12 -0
  140. package/rancher-components/Form/Checkbox/Checkbox.vue +9 -2
  141. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +18 -1
  142. package/rancher-components/Form/LabeledInput/LabeledInput.vue +19 -1
  143. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +39 -2
  144. package/rancher-components/RcButton/RcButton.vue +90 -0
  145. package/rancher-components/RcButton/index.ts +2 -0
  146. package/rancher-components/RcButton/types.ts +17 -0
  147. package/rancher-components/RcDropdown/RcDropdown.vue +122 -0
  148. package/rancher-components/RcDropdown/RcDropdownItem.vue +127 -0
  149. package/rancher-components/RcDropdown/RcDropdownSeparator.vue +6 -0
  150. package/rancher-components/RcDropdown/RcDropdownTrigger.vue +42 -0
  151. package/rancher-components/RcDropdown/index.ts +4 -0
  152. package/rancher-components/RcDropdown/types.ts +22 -0
  153. package/rancher-components/RcDropdown/useDropdownCollection.ts +46 -0
  154. package/rancher-components/RcDropdown/useDropdownContext.ts +110 -0
  155. package/scripts/test-plugins-build.sh +2 -0
  156. package/scripts/typegen.sh +2 -0
  157. package/store/catalog.js +1 -1
  158. package/tsconfig.json +2 -1
  159. package/types/components/paginatedResourceTable.ts +25 -0
  160. package/types/components/resourceLabeledSelect.ts +48 -0
  161. package/types/resources/fleet.d.ts +17 -0
  162. package/types/shell/index.d.ts +61 -0
  163. package/utils/auth.js +5 -1
  164. package/utils/cluster.js +106 -0
  165. package/utils/fleet.ts +35 -3
  166. package/utils/ingress.ts +64 -0
  167. package/utils/uiplugins.ts +56 -44
  168. package/utils/validators/cron-schedule.js +7 -2
  169. package/utils/validators/formRules/__tests__/index.test.ts +53 -17
  170. package/utils/validators/formRules/index.ts +20 -5
  171. package/vue.config.js +1 -1
  172. package/components/RelatedWorkloadsTable.vue +0 -50
@@ -0,0 +1,90 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * A button element used for performing actions, such as submitting forms or
4
+ * opening dialogs.
5
+ *
6
+ * Example:
7
+ *
8
+ * <rc-button primary @click="doAction">Perform an Action</rc-button>
9
+ */
10
+ import { computed, ref, defineExpose } from 'vue';
11
+ import { ButtonRoleProps, ButtonSizeProps } from './types';
12
+
13
+ const buttonRoles: { role: keyof ButtonRoleProps, className: string }[] = [
14
+ { role: 'primary', className: 'role-primary' },
15
+ { role: 'secondary', className: 'role-secondary' },
16
+ { role: 'tertiary', className: 'role-tertiary' },
17
+ { role: 'link', className: 'role-link' },
18
+ { role: 'ghost', className: 'role-ghost' },
19
+ ];
20
+
21
+ const buttonSizes: { size: keyof ButtonSizeProps, className: string }[] = [
22
+ { size: 'small', className: 'btn-sm' },
23
+ ];
24
+
25
+ const props = defineProps<ButtonRoleProps & ButtonSizeProps>();
26
+
27
+ const buttonClass = computed(() => {
28
+ const activeRole = buttonRoles.find(({ role }) => props[role]);
29
+ const isButtonSmall = buttonSizes.some(({ size }) => props[size]);
30
+
31
+ return {
32
+ btn: true,
33
+
34
+ [activeRole?.className || 'role-primary']: true,
35
+
36
+ 'btn-sm': isButtonSmall,
37
+ };
38
+ });
39
+
40
+ const RcFocusTarget = ref<HTMLElement | null>(null);
41
+
42
+ const focus = () => {
43
+ RcFocusTarget?.value?.focus();
44
+ };
45
+
46
+ defineExpose({ focus });
47
+ </script>
48
+
49
+ <template>
50
+ <button
51
+ ref="RcFocusTarget"
52
+ role="button"
53
+ :class="{ ...buttonClass, ...($attrs.class || { }) }"
54
+ >
55
+ <slot name="before">
56
+ <!-- Empty Content -->
57
+ </slot>
58
+ <slot>
59
+ <!-- Empty Content -->
60
+ </slot>
61
+ <slot name="after">
62
+ <!-- Empty Content -->
63
+ </slot>
64
+ </button>
65
+ </template>
66
+
67
+ <style lang="scss" scoped>
68
+ .role-link {
69
+ &:focus, &.focused {
70
+ outline: var(--outline-width) solid var(--border);
71
+ box-shadow: 0 0 0 var(--outline-width) var(--outline);
72
+ }
73
+ }
74
+
75
+ button {
76
+ &.role-ghost {
77
+ padding: 0;
78
+ background-color: transparent;
79
+
80
+ &:focus, &.focused {
81
+ outline: 2px solid var(--primary-keyboard-focus);
82
+ outline-offset: 0;
83
+ }
84
+
85
+ &:focus-visible {
86
+ outline: 2px solid var(--primary-keyboard-focus);
87
+ outline-offset: 0;
88
+ }
89
+ }
90
+ }</style>
@@ -0,0 +1,2 @@
1
+ export { default as RcButton } from './RcButton.vue';
2
+ export type { RcButtonType } from './types';
@@ -0,0 +1,17 @@
1
+ // TODO: 13211 Investigate why `InstanceType<typeof RcButton>` fails prod builds
2
+ // export type RcButtonType = InstanceType<typeof RcButton>
3
+ export type RcButtonType = {
4
+ focus: () => void;
5
+ }
6
+
7
+ export type ButtonRoleProps = {
8
+ primary?: boolean;
9
+ secondary?: boolean;
10
+ tertiary?: boolean;
11
+ link?: boolean;
12
+ ghost?: boolean;
13
+ }
14
+
15
+ export type ButtonSizeProps = {
16
+ small?: boolean;
17
+ }
@@ -0,0 +1,122 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Offers a list of choices to the user, such as a set of actions or functions.
4
+ * Opened by activating RcDropdownTrigger.
5
+ *
6
+ * Example:
7
+ *
8
+ * <rc-dropdown :aria-label="t('nav.actionMenu.label')">
9
+ * <rc-dropdown-trigger tertiary>
10
+ * <i class="icon icon-actions" />
11
+ * </rc-dropdown-trigger>
12
+ * <template #dropdownCollection>
13
+ * <rc-dropdown-item @click="performAction()">
14
+ * Action 1
15
+ * </rc-dropdown-item>
16
+ * <rc-dropdown-separator />
17
+ * <rc-dropdown-item @click="performAction()">
18
+ * Action 2
19
+ * </rc-dropdown-item>
20
+ * </template>
21
+ * </rc-dropdown>
22
+ */
23
+ import { useTemplateRef } from 'vue';
24
+ import { useClickOutside } from '@shell/composables/useClickOutside';
25
+ import { useDropdownContext } from '@components/RcDropdown/useDropdownContext';
26
+
27
+ defineProps<{
28
+ ariaLabel?: string
29
+ }>();
30
+
31
+ const {
32
+ isMenuOpen,
33
+ showMenu,
34
+ returnFocus,
35
+ setFocus,
36
+ provideDropdownContext,
37
+ registerDropdownCollection,
38
+ handleKeydown,
39
+ } = useDropdownContext();
40
+
41
+ provideDropdownContext();
42
+
43
+ const popperContainer = useTemplateRef<HTMLElement>('popperContainer');
44
+ const dropdownTarget = useTemplateRef<HTMLElement>('dropdownTarget');
45
+
46
+ useClickOutside(dropdownTarget, () => showMenu(false));
47
+
48
+ const applyShow = () => {
49
+ registerDropdownCollection(dropdownTarget.value);
50
+ setFocus();
51
+ };
52
+
53
+ </script>
54
+
55
+ <template>
56
+ <v-dropdown
57
+ no-auto-focus
58
+ :triggers="[]"
59
+ :shown="isMenuOpen"
60
+ :auto-hide="false"
61
+ :container="popperContainer"
62
+ :placement="'bottom-end'"
63
+ @apply-show="applyShow"
64
+ >
65
+ <slot name="default">
66
+ <!--Empty slot content Trigger-->
67
+ </slot>
68
+
69
+ <template #popper>
70
+ <div
71
+ ref="dropdownTarget"
72
+ class="dropdownTarget"
73
+ tabindex="-1"
74
+ role="menu"
75
+ aria-orientation="vertical"
76
+ dropdown-menu-collection
77
+ :aria-label="ariaLabel || 'Dropdown Menu'"
78
+ @keydown="handleKeydown"
79
+ @keydown.down="setFocus()"
80
+ >
81
+ <slot name="dropdownCollection">
82
+ <!--Empty slot content-->
83
+ </slot>
84
+ </div>
85
+ </template>
86
+ </v-dropdown>
87
+ <div
88
+ ref="popperContainer"
89
+ class="popperContainer"
90
+ @keydown.tab="showMenu(false)"
91
+ @keydown.escape="returnFocus"
92
+ >
93
+ <!--Empty container for mounting popper content-->
94
+ </div>
95
+ </template>
96
+
97
+ <style lang="scss" scoped>
98
+ .popperContainer {
99
+ display: contents;
100
+ &:deep(.v-popper__popper) {
101
+
102
+ .v-popper__wrapper {
103
+ box-shadow: 0px 6px 18px 0px rgba(0, 0, 0, 0.25), 0px 4px 10px 0px rgba(0, 0, 0, 0.15);
104
+ border-radius: var(--border-radius-lg);
105
+
106
+ .v-popper__arrow-container {
107
+ display: none;
108
+ }
109
+
110
+ .v-popper__inner {
111
+ padding: 10px 0 10px 0;
112
+ }
113
+ }
114
+ }
115
+ }
116
+
117
+ .dropdownTarget {
118
+ &:focus-visible, &:focus {
119
+ outline: none;
120
+ }
121
+ }
122
+ </style>
@@ -0,0 +1,127 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * An item for a dropdown menu. Used in conjunction with RcDropdown.
4
+ */
5
+ import { inject } from 'vue';
6
+ import { DropdownContext, defaultContext } from './types';
7
+
8
+ const props = defineProps({ disabled: Boolean });
9
+ const emits = defineEmits(['click']);
10
+
11
+ const { close, dropdownItems } = inject<DropdownContext>('dropdownContext') || defaultContext;
12
+
13
+ /**
14
+ * Handles keydown events to navigate between dropdown items.
15
+ * @param {KeyboardEvent} e - The keydown event.
16
+ */
17
+ const handleKeydown = (e: KeyboardEvent) => {
18
+ const activeItem = document.activeElement;
19
+
20
+ const activeIndex = dropdownItems.value.indexOf(activeItem || new HTMLElement());
21
+
22
+ if (activeIndex < 0) {
23
+ return;
24
+ }
25
+
26
+ const shouldAdvance = e.key === 'ArrowDown';
27
+
28
+ const newIndex = findNewIndex(shouldAdvance, activeIndex, dropdownItems.value);
29
+
30
+ if (dropdownItems.value[newIndex] instanceof HTMLElement) {
31
+ dropdownItems.value[newIndex].focus();
32
+ }
33
+ };
34
+
35
+ /**
36
+ * Finds the new index for the dropdown item based on the key pressed.
37
+ * @param shouldAdvance - Whether to advance to the next or previous item.
38
+ * @param activeIndex - Current active index.
39
+ * @param itemsArr - Array of dropdown items.
40
+ * @returns The new index.
41
+ */
42
+ const findNewIndex = (shouldAdvance: boolean, activeIndex: number, itemsArr: Element[]) => {
43
+ const newIndex = shouldAdvance ? activeIndex + 1 : activeIndex - 1;
44
+
45
+ if (newIndex > itemsArr.length - 1) {
46
+ return 0;
47
+ }
48
+
49
+ if (newIndex < 0) {
50
+ return itemsArr.length - 1;
51
+ }
52
+
53
+ return newIndex;
54
+ };
55
+
56
+ const handleClick = () => {
57
+ if (props.disabled) {
58
+ return;
59
+ }
60
+
61
+ emits('click');
62
+ close();
63
+ };
64
+
65
+ /**
66
+ * Handles keydown events to activate the dropdown item.
67
+ * @param e - The keydown event.
68
+ */
69
+ const handleActivate = (e: KeyboardEvent) => {
70
+ if (e?.target instanceof HTMLElement) {
71
+ e?.target?.click();
72
+ }
73
+ };
74
+
75
+ /**
76
+ * Handles keydown events to focus the dropdown item.
77
+ * @param e - The Mouse event.
78
+ */
79
+ const handleMouseEnter = (e: MouseEvent) => {
80
+ if (e?.target instanceof HTMLElement) {
81
+ e?.target?.focus();
82
+ }
83
+ };
84
+
85
+ </script>
86
+
87
+ <template>
88
+ <div
89
+ ref="dropdownMenuItem"
90
+ dropdown-menu-item
91
+ tabindex="-1"
92
+ role="menuitem"
93
+ :disabled="disabled || null"
94
+ :aria-disabled="disabled || false"
95
+ @click.stop="handleClick"
96
+ @keydown.enter.space="handleActivate"
97
+ @keydown.up.down.stop="handleKeydown"
98
+ @mouseenter="handleMouseEnter"
99
+ >
100
+ <slot name="default">
101
+ <!--Empty slot content-->
102
+ </slot>
103
+ </div>
104
+ </template>
105
+
106
+ <style lang="scss" scoped>
107
+ [dropdown-menu-item] {
108
+ padding: 9px 8px;
109
+ margin: 0 9px;
110
+ border-radius: 4px;
111
+
112
+ &:hover {
113
+ cursor: pointer;
114
+ background-color: var(--dropdown-hover-bg);
115
+ }
116
+ &:focus-visible, &:focus {
117
+ @include focus-outline;
118
+ outline-offset: 0;
119
+ }
120
+ &[disabled] {
121
+ color: var(--disabled-text);
122
+ &:hover {
123
+ cursor: not-allowed;
124
+ }
125
+ }
126
+ }
127
+ </style>
@@ -0,0 +1,6 @@
1
+ <template>
2
+ <hr
3
+ role="separator"
4
+ aria-orientation="horizontal"
5
+ >
6
+ </template>
@@ -0,0 +1,42 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * A button that opens a menu. Used in conjunction with `RcDropdown.vue`.
4
+ */
5
+ import { inject, onMounted, useTemplateRef } from 'vue';
6
+ import { RcButton, RcButtonType } from '@components/RcButton';
7
+ import { DropdownContext, defaultContext } from './types';
8
+
9
+ const {
10
+ showMenu,
11
+ registerTrigger,
12
+ isMenuOpen,
13
+ handleKeydown,
14
+ } = inject<DropdownContext>('dropdownContext') || defaultContext;
15
+
16
+ const dropdownTrigger = useTemplateRef<RcButtonType>('dropdownTrigger');
17
+
18
+ onMounted(() => {
19
+ registerTrigger(dropdownTrigger.value);
20
+ });
21
+
22
+ const focus = () => {
23
+ dropdownTrigger?.value?.focus();
24
+ };
25
+
26
+ defineExpose({ focus });
27
+ </script>
28
+
29
+ <template>
30
+ <RcButton
31
+ ref="dropdownTrigger"
32
+ role="button"
33
+ aria-haspopup="menu"
34
+ :aria-expanded="isMenuOpen"
35
+ @keydown.enter.space="handleKeydown"
36
+ @click="showMenu(true)"
37
+ >
38
+ <slot name="default">
39
+ <!--Empty slot content-->
40
+ </slot>
41
+ </RcButton>
42
+ </template>
@@ -0,0 +1,4 @@
1
+ export { default as RcDropdown } from './RcDropdown.vue';
2
+ export { default as RcDropdownItem } from './RcDropdownItem.vue';
3
+ export { default as RcDropdownSeparator } from './RcDropdownSeparator.vue';
4
+ export { default as RcDropdownTrigger } from './RcDropdownTrigger.vue';
@@ -0,0 +1,22 @@
1
+ import { Ref, ref } from 'vue';
2
+ import type { RcButtonType } from '@components/RcButton';
3
+
4
+ export type DropdownContext = {
5
+ handleKeydown: () => void;
6
+ showMenu: (show: boolean) => void;
7
+ registerTrigger: (triggerRef: RcButtonType | null) => void;
8
+ dropdownItems: Ref<Element[]>;
9
+ focusFirstElement: () => void;
10
+ isMenuOpen: Ref<boolean>;
11
+ close: () => void;
12
+ }
13
+
14
+ export const defaultContext: DropdownContext = {
15
+ handleKeydown: () => null,
16
+ showMenu: (_show: boolean | null) => null,
17
+ registerTrigger: (_triggerRef: RcButtonType | null) => null,
18
+ dropdownItems: ref([]),
19
+ focusFirstElement: () => null,
20
+ isMenuOpen: ref(false),
21
+ close: () => null,
22
+ };
@@ -0,0 +1,46 @@
1
+ import { ref } from 'vue';
2
+
3
+ /**
4
+ * Manages a collection of dropdown items. Includes methods for registering
5
+ * dropdown items and providing the collection to descendant components.
6
+ *
7
+ * @returns Dropdown collection methods and state.
8
+ */
9
+ export const useDropdownCollection = () => {
10
+ const dropdownItems = ref<Element[]>([]);
11
+ const dropdownContainer = ref<HTMLElement | null>(null);
12
+ const firstDropdownItem = ref<HTMLElement | null>(null);
13
+
14
+ /**
15
+ * Registers the dropdown container and initializes dropdown items.
16
+ * @param target - The dropdown container element.
17
+ */
18
+ const registerDropdownCollection = (target: HTMLElement | null) => {
19
+ dropdownContainer.value = target;
20
+ if (dropdownContainer.value?.firstElementChild instanceof HTMLElement) {
21
+ registerDropdownItems();
22
+ if (dropdownItems.value[0] instanceof HTMLElement) {
23
+ firstDropdownItem.value = dropdownItems.value[0];
24
+ }
25
+ }
26
+ };
27
+
28
+ /**
29
+ * Registers dropdown items by querying the dropdown container for elements.
30
+ */
31
+ const registerDropdownItems = () => {
32
+ dropdownItems.value = [];
33
+ const dropdownNodeList = dropdownContainer.value?.querySelectorAll('[dropdown-menu-item]');
34
+
35
+ dropdownNodeList?.forEach((element) => {
36
+ dropdownItems.value.push(element);
37
+ });
38
+ };
39
+
40
+ return {
41
+ dropdownItems,
42
+ firstDropdownItem,
43
+ dropdownContainer,
44
+ registerDropdownCollection,
45
+ };
46
+ };
@@ -0,0 +1,110 @@
1
+ import { ref, provide, nextTick } from 'vue';
2
+ import { useDropdownCollection } from './useDropdownCollection';
3
+ import { RcButtonType } from '@components/RcButton';
4
+
5
+ /**
6
+ * Composable that provides the context for a dropdown menu. Includes methods
7
+ * and state for managing the dropdown's visibility, focus, and keyboard
8
+ * interactions.
9
+ *
10
+ * @param firstDropdownItem - First item in the dropdown menu.
11
+ * @returns Dropdown context methods and state. Used for programmatic
12
+ * interactions and setting focus.
13
+ */
14
+ export const useDropdownContext = () => {
15
+ const {
16
+ dropdownItems,
17
+ firstDropdownItem,
18
+ dropdownContainer,
19
+ registerDropdownCollection,
20
+ } = useDropdownCollection();
21
+
22
+ const isMenuOpen = ref(false);
23
+
24
+ /**
25
+ * Controls the visibility of the dropdown menu.
26
+ * @param show - Whether to show or hide the dropdown menu.
27
+ */
28
+ const showMenu = (show: boolean) => {
29
+ if (!show) {
30
+ didKeydown.value = false;
31
+ }
32
+ isMenuOpen.value = show;
33
+ };
34
+
35
+ /**
36
+ * A ref for the dropdown trigger element. Used for programmatic
37
+ * interactions and setting focus.
38
+ */
39
+ const dropdownTrigger = ref<RcButtonType | null>(null);
40
+
41
+ /**
42
+ * Registers the dropdown trigger element.
43
+ * @param triggerRef - The dropdown trigger element.
44
+ */
45
+ const registerTrigger = (triggerRef: RcButtonType) => {
46
+ dropdownTrigger.value = triggerRef;
47
+ };
48
+
49
+ /**
50
+ * Returns focus to the dropdown trigger and closes the menu.
51
+ */
52
+ const returnFocus = () => {
53
+ showMenu(false);
54
+ dropdownTrigger?.value?.focus();
55
+ };
56
+
57
+ /**
58
+ * Tracks if a keydown event has occurred. Important for distinguishing keyboard
59
+ * events from mouse events.
60
+ */
61
+ const didKeydown = ref(false);
62
+
63
+ const handleKeydown = () => {
64
+ didKeydown.value = true;
65
+ };
66
+
67
+ /**
68
+ * Sets focus to the first dropdown item if a keydown event has occurred.
69
+ */
70
+ const setFocus = () => {
71
+ nextTick(() => {
72
+ if (!didKeydown.value) {
73
+ dropdownContainer.value?.focus();
74
+
75
+ return;
76
+ }
77
+
78
+ firstDropdownItem.value?.focus();
79
+ didKeydown.value = false;
80
+ });
81
+ };
82
+
83
+ /**
84
+ * Provides Dropdown Context data and methods to descendants of RcDropdown.
85
+ * Accessed in descendents with the `inject()` function.
86
+ */
87
+ const provideDropdownContext = () => {
88
+ provide('dropdownContext', {
89
+ showMenu,
90
+ registerTrigger,
91
+ isMenuOpen,
92
+ dropdownItems,
93
+ close: () => returnFocus(),
94
+ focusFirstElement: () => {
95
+ setFocus();
96
+ },
97
+ handleKeydown,
98
+ });
99
+ };
100
+
101
+ return {
102
+ isMenuOpen,
103
+ showMenu,
104
+ returnFocus,
105
+ setFocus,
106
+ provideDropdownContext,
107
+ registerDropdownCollection,
108
+ handleKeydown,
109
+ };
110
+ };
@@ -141,6 +141,8 @@ if [ "${SKIP_STANDALONE}" == "false" ]; then
141
141
  pushd test-app > /dev/null
142
142
 
143
143
  yarn install
144
+ # this is the "same" as doing a yarn dev (in a build sense)
145
+ # it's to make sure the dev environment is running properly
144
146
  FORCE_COLOR=true yarn build | cat
145
147
 
146
148
  # Add test list component to the test package
@@ -21,10 +21,12 @@ ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/config/query-params.js --declarat
21
21
  ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/config/table-headers.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/config > /dev/null
22
22
  ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/config/types.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/config > /dev/null
23
23
  ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/config/labels-annotations.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/config > /dev/null
24
+ ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/config/version.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/config > /dev/null
24
25
 
25
26
  # # store
26
27
  ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/store/features.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/store > /dev/null
27
28
  ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/store/prefs.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/store > /dev/null
29
+ ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/store/plugins.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/store > /dev/null
28
30
 
29
31
  # # plugins
30
32
  ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/plugins/dashboard-store/normalize.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/plugins/dashboard-store/ > /dev/null
package/store/catalog.js CHANGED
@@ -57,7 +57,7 @@ export const getters = {
57
57
  const clustered = state.clusterRepos || [];
58
58
  const namespaced = state.namespacedRepos || [];
59
59
 
60
- return [...clustered, ...namespaced];
60
+ return [...clustered, ...namespaced].filter((r) => r.spec?.enabled !== false);
61
61
  },
62
62
 
63
63
  // Raw charts
package/tsconfig.json CHANGED
@@ -29,7 +29,8 @@
29
29
  "./**/*.ts",
30
30
  "./**/*.d.ts",
31
31
  "./**/*.tsx",
32
- "./**/*.vue"
32
+ "./**/*.vue",
33
+ "../pkg/rancher-components/src/**/*"
33
34
  ],
34
35
  "exclude": [
35
36
  "node_modules",
@@ -0,0 +1,25 @@
1
+ import { StorePaginationResult } from '@shell/types/store/pagination.types';
2
+
3
+ /**
4
+ * see {@link PagTableFetchSecondaryResources}
5
+ */
6
+ export type PagTableFetchSecondaryResourcesOpts = { canPaginate: boolean }
7
+ /**
8
+ * see {@link PagTableFetchSecondaryResources}
9
+ */
10
+ export type PagTableFetchSecondaryResourcesReturns = Promise<any>
11
+ /**
12
+ * Function to fetch resources that are required to supplement information needed by rows in a PaginatedResourceTable
13
+ *
14
+ * Used in scenarios where ALL resources are expected
15
+ */
16
+ export type PagTableFetchSecondaryResources = (opts: PagTableFetchSecondaryResourcesOpts) => PagTableFetchSecondaryResourcesReturns
17
+
18
+ /**
19
+ * see {@link PagTableFetchPageSecondaryResources}
20
+ */
21
+ export type PagTableFetchPageSecondaryResourcesOpts = { canPaginate: boolean, force: boolean, page: any[], pagResult: StorePaginationResult }
22
+ /**
23
+ * Function to fetch resources that are required to supplement information needed by a single page in a PaginatedResourceTable
24
+ */
25
+ export type PagTableFetchPageSecondaryResources = (opts: PagTableFetchPageSecondaryResourcesOpts) => Promise<any>