@rancher/shell 3.0.5-rc.3 → 3.0.5-rc.5

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 (200) hide show
  1. package/assets/images/icons/document.svg +3 -0
  2. package/assets/images/vendor/cognito.svg +1 -0
  3. package/assets/styles/app.scss +1 -0
  4. package/assets/styles/base/_basic.scss +10 -0
  5. package/assets/styles/base/_spacing.scss +29 -0
  6. package/assets/styles/global/_layout.scss +1 -1
  7. package/assets/styles/themes/_dark.scss +25 -0
  8. package/assets/styles/themes/_light.scss +65 -0
  9. package/assets/translations/en-us.yaml +322 -24
  10. package/assets/translations/zh-hans.yaml +8 -5
  11. package/components/Certificates.vue +5 -0
  12. package/components/FilterPanel.vue +156 -0
  13. package/components/{fleet/ForceDirectedTreeChart/index.vue → ForceDirectedTreeChart.vue} +47 -41
  14. package/components/IconOrSvg.vue +14 -35
  15. package/components/PromptRemove.vue +5 -1
  16. package/components/Resource/Detail/Card/PodsCard/Bubble.vue +13 -0
  17. package/components/Resource/Detail/Card/PodsCard/composable.ts +30 -0
  18. package/components/Resource/Detail/Card/PodsCard/index.vue +118 -0
  19. package/components/Resource/Detail/Card/ResourceUsageCard/composable.ts +51 -0
  20. package/components/Resource/Detail/Card/ResourceUsageCard/index.vue +79 -0
  21. package/components/Resource/Detail/Card/Scaler.vue +89 -0
  22. package/components/Resource/Detail/Card/StateCard/composables.ts +112 -0
  23. package/components/Resource/Detail/Card/StateCard/index.vue +39 -0
  24. package/components/Resource/Detail/Card/VerticalGap.vue +11 -0
  25. package/components/Resource/Detail/Card/__tests__/Card.test.ts +36 -0
  26. package/components/Resource/Detail/Card/__tests__/PodsCard.test.ts +84 -0
  27. package/components/Resource/Detail/Card/__tests__/ResourceUsageCard.test.ts +72 -0
  28. package/components/Resource/Detail/Card/__tests__/Scaler.test.ts +87 -0
  29. package/components/Resource/Detail/Card/__tests__/StateCard.test.ts +53 -0
  30. package/components/Resource/Detail/Card/__tests__/VerticalGap.test.ts +14 -0
  31. package/components/Resource/Detail/Card/__tests__/index.test.ts +36 -0
  32. package/components/Resource/Detail/Card/index.vue +56 -0
  33. package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +19 -0
  34. package/components/Resource/Detail/Metadata/Annotations/composable.ts +12 -0
  35. package/components/Resource/Detail/Metadata/Annotations/index.vue +26 -0
  36. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/index.test.ts +103 -0
  37. package/components/Resource/Detail/Metadata/IdentifyingInformation/composable.ts +281 -0
  38. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +111 -0
  39. package/components/Resource/Detail/Metadata/KeyValue.vue +130 -0
  40. package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +18 -0
  41. package/components/Resource/Detail/Metadata/Labels/composable.ts +12 -0
  42. package/components/Resource/Detail/Metadata/Labels/index.vue +27 -0
  43. package/components/Resource/Detail/Metadata/Rectangle.vue +32 -0
  44. package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +107 -0
  45. package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +24 -0
  46. package/components/Resource/Detail/Metadata/__tests__/index.test.ts +91 -0
  47. package/components/Resource/Detail/Metadata/composables.ts +29 -0
  48. package/components/Resource/Detail/Metadata/index.vue +66 -0
  49. package/components/Resource/Detail/Page.vue +22 -0
  50. package/components/Resource/Detail/PercentageBar.vue +40 -0
  51. package/components/Resource/Detail/ResourceRow.vue +119 -0
  52. package/components/Resource/Detail/SpacedRow.vue +14 -0
  53. package/components/Resource/Detail/StatusBar.vue +59 -0
  54. package/components/Resource/Detail/StatusRow.vue +61 -0
  55. package/components/Resource/Detail/TitleBar/Title.vue +13 -0
  56. package/components/Resource/Detail/TitleBar/Top.vue +14 -0
  57. package/components/Resource/Detail/TitleBar/__tests__/Title.test.ts +17 -0
  58. package/components/Resource/Detail/TitleBar/__tests__/Top.test.ts +17 -0
  59. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +142 -0
  60. package/components/Resource/Detail/TitleBar/composable.ts +31 -0
  61. package/components/Resource/Detail/TitleBar/index.vue +124 -0
  62. package/components/Resource/Detail/Top/index.vue +34 -0
  63. package/components/Resource/Detail/__tests__/Page.test.ts +32 -0
  64. package/components/ResourceDetail/__tests__/index.test.ts +114 -0
  65. package/components/ResourceDetail/index.vue +64 -562
  66. package/components/ResourceDetail/legacy.vue +545 -0
  67. package/components/ResourceTable.vue +41 -7
  68. package/components/SlideInPanelManager.vue +76 -8
  69. package/components/SortableTable/index.vue +13 -2
  70. package/components/SortableTable/selection.js +21 -8
  71. package/components/StatusBadge.vue +6 -4
  72. package/components/SubtleLink.vue +25 -0
  73. package/components/Wizard.vue +12 -1
  74. package/components/YamlEditor.vue +1 -1
  75. package/components/__tests__/FilterPanel.test.ts +81 -0
  76. package/components/auth/AuthBanner.vue +2 -3
  77. package/components/auth/RoleDetailEdit.vue +45 -3
  78. package/components/auth/login/oidc.vue +6 -1
  79. package/components/fleet/FleetApplications.vue +181 -0
  80. package/components/fleet/FleetHelmOps.vue +115 -0
  81. package/components/fleet/FleetIntro.vue +58 -28
  82. package/components/fleet/FleetNoWorkspaces.vue +5 -1
  83. package/components/fleet/FleetOCIStorageSecret.vue +171 -0
  84. package/components/fleet/FleetRepos.vue +38 -76
  85. package/components/fleet/FleetResources.vue +50 -22
  86. package/components/fleet/FleetSummary.vue +26 -51
  87. package/components/fleet/__tests__/FleetOCIStorageSecret.test.ts +213 -0
  88. package/components/fleet/__tests__/FleetSummary.test.ts +39 -39
  89. package/components/fleet/dashboard/Empty.vue +73 -0
  90. package/components/fleet/dashboard/ResourceCard.vue +183 -0
  91. package/components/fleet/dashboard/ResourceCardSummary.vue +199 -0
  92. package/components/fleet/dashboard/ResourceDetails.vue +196 -0
  93. package/components/fleet/dashboard/ResourcePanel.vue +376 -0
  94. package/components/form/ArrayList.vue +6 -0
  95. package/components/form/SimpleSecretSelector.vue +8 -2
  96. package/components/form/ValueFromResource.vue +31 -19
  97. package/components/formatter/FleetApplicationClustersReady.vue +77 -0
  98. package/components/formatter/FleetApplicationSource.vue +71 -0
  99. package/components/formatter/FleetSummaryGraph.vue +7 -0
  100. package/components/nav/Header.vue +8 -7
  101. package/components/nav/TopLevelMenu.helper.ts +55 -34
  102. package/components/nav/TopLevelMenu.vue +11 -0
  103. package/components/nav/Type.vue +4 -1
  104. package/composables/useI18n.ts +12 -11
  105. package/config/labels-annotations.js +14 -11
  106. package/config/product/auth.js +1 -0
  107. package/config/product/fleet.js +70 -17
  108. package/config/query-params.js +3 -1
  109. package/config/roles.ts +1 -0
  110. package/config/router/routes.js +20 -2
  111. package/config/secret.ts +15 -0
  112. package/config/settings.ts +3 -2
  113. package/config/table-headers.js +52 -22
  114. package/config/types.js +2 -0
  115. package/core/plugin-helpers.ts +3 -2
  116. package/detail/fleet.cattle.io.cluster.vue +28 -15
  117. package/detail/fleet.cattle.io.gitrepo.vue +10 -1
  118. package/detail/fleet.cattle.io.helmop.vue +157 -0
  119. package/dialog/HelmOpForceUpdateDialog.vue +132 -0
  120. package/dialog/RedeployWorkloadDialog.vue +164 -0
  121. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +56 -67
  122. package/edit/auth/oidc.vue +159 -93
  123. package/edit/fleet.cattle.io.gitrepo.vue +26 -33
  124. package/edit/fleet.cattle.io.helmop.vue +997 -0
  125. package/edit/management.cattle.io.fleetworkspace.vue +43 -10
  126. package/list/fleet.cattle.io.gitrepo.vue +1 -1
  127. package/list/fleet.cattle.io.helmop.vue +108 -0
  128. package/list/namespace.vue +5 -2
  129. package/mixins/auth-config.js +8 -1
  130. package/mixins/preset.js +100 -0
  131. package/mixins/resource-fetch-api-pagination.js +2 -0
  132. package/mixins/resource-fetch.js +1 -1
  133. package/mixins/resource-table-watch.js +45 -0
  134. package/models/__tests__/chart.test.ts +273 -0
  135. package/models/__tests__/fleet.cattle.io.gitrepo.test.ts +1 -1
  136. package/models/chart.js +144 -2
  137. package/models/fleet-application.js +385 -0
  138. package/models/fleet.cattle.io.bundle.js +9 -8
  139. package/models/fleet.cattle.io.gitrepo.js +41 -365
  140. package/models/fleet.cattle.io.helmop.js +228 -0
  141. package/models/management.cattle.io.authconfig.js +1 -0
  142. package/models/management.cattle.io.fleetworkspace.js +12 -0
  143. package/models/workload.js +14 -18
  144. package/package.json +2 -1
  145. package/pages/auth/verify.vue +13 -1
  146. package/pages/c/_cluster/apps/charts/AddRepoLink.vue +37 -0
  147. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +80 -0
  148. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +54 -0
  149. package/pages/c/_cluster/apps/charts/StatusLabel.vue +33 -0
  150. package/pages/c/_cluster/apps/charts/index.vue +302 -484
  151. package/pages/c/_cluster/explorer/EventsTable.vue +1 -1
  152. package/pages/c/_cluster/fleet/__tests__/index.test.ts +426 -0
  153. package/pages/c/_cluster/fleet/application/_resource/_id.vue +14 -0
  154. package/pages/c/_cluster/fleet/application/_resource/create.vue +14 -0
  155. package/pages/c/_cluster/fleet/application/create.vue +340 -0
  156. package/pages/c/_cluster/fleet/application/index.vue +139 -0
  157. package/pages/c/_cluster/fleet/graph/config.js +277 -0
  158. package/pages/c/_cluster/fleet/index.vue +772 -330
  159. package/pages/explorer/resource/detail/configmap.vue +19 -0
  160. package/plugins/dashboard-store/actions.js +31 -9
  161. package/plugins/dashboard-store/getters.js +34 -21
  162. package/plugins/dashboard-store/mutations.js +51 -7
  163. package/plugins/dashboard-store/resource-class.js +14 -2
  164. package/plugins/steve/__tests__/subscribe.spec.ts +66 -1
  165. package/plugins/steve/actions.js +3 -0
  166. package/plugins/steve/steve-pagination-utils.ts +14 -13
  167. package/plugins/steve/subscribe.js +229 -42
  168. package/rancher-components/BadgeState/BadgeState.vue +3 -1
  169. package/rancher-components/Form/Checkbox/Checkbox.vue +2 -2
  170. package/rancher-components/RcItemCard/RcItemCard.test.ts +189 -0
  171. package/rancher-components/RcItemCard/RcItemCard.vue +425 -0
  172. package/rancher-components/RcItemCard/RcItemCardAction.vue +24 -0
  173. package/rancher-components/RcItemCard/index.ts +2 -0
  174. package/store/auth.js +1 -0
  175. package/store/catalog.js +62 -24
  176. package/store/index.js +33 -14
  177. package/store/slideInPanel.ts +6 -0
  178. package/store/type-map.js +1 -0
  179. package/types/fleet.d.ts +35 -0
  180. package/types/resources/settings.d.ts +19 -1
  181. package/types/shell/index.d.ts +339 -272
  182. package/types/store/dashboard-store.types.ts +17 -3
  183. package/types/store/pagination.types.ts +6 -1
  184. package/types/store/subscribe.types.ts +50 -0
  185. package/utils/auth.js +32 -3
  186. package/utils/fleet-types.ts +0 -0
  187. package/utils/fleet.ts +200 -1
  188. package/utils/pagination-utils.ts +26 -1
  189. package/utils/pagination-wrapper.ts +132 -50
  190. package/utils/settings.ts +4 -1
  191. package/utils/style.ts +39 -0
  192. package/utils/validators/formRules/__tests__/index.test.ts +36 -3
  193. package/utils/validators/formRules/index.ts +10 -3
  194. package/utils/window.js +11 -7
  195. package/components/__tests__/ApplicationCard.test.ts +0 -27
  196. package/components/cards/ApplicationCard.vue +0 -145
  197. package/components/fleet/ForceDirectedTreeChart/chartIcons.js +0 -17
  198. package/config/secret.js +0 -14
  199. package/pages/c/_cluster/fleet/GitRepoGraphConfig.js +0 -249
  200. /package/{components/form/SSHKnownHosts → dialog}/__tests__/KnownHostsEditDialog.test.ts +0 -0
@@ -0,0 +1,183 @@
1
+ <script lang="ts">
2
+ import { PropType } from 'vue';
3
+ import { clone } from '@shell/utils/object';
4
+ import ActionMenu from '@shell/components/ActionMenuShell.vue';
5
+ import { RcItemCard } from '@components/RcItemCard';
6
+ import ResourceCardSummary from '@shell/components/fleet/dashboard/ResourceCardSummary.vue';
7
+ import FleetUtils from '@shell/utils/fleet';
8
+ import { FleetDashboardState, FleetResourceState } from '@shell/types/fleet';
9
+
10
+ export default {
11
+
12
+ name: 'FleetDashboardResourceCard',
13
+
14
+ emits: ['click'],
15
+
16
+ components: {
17
+ ActionMenu,
18
+ RcItemCard,
19
+ ResourceCardSummary,
20
+ },
21
+
22
+ props: {
23
+ value: {
24
+ type: Object,
25
+ required: true
26
+ },
27
+
28
+ statePanel: {
29
+ type: Object as PropType<FleetDashboardState>,
30
+ required: true
31
+ },
32
+ },
33
+
34
+ data() {
35
+ let resourcesDefaultStates: FleetResourceState | object = {};
36
+
37
+ try {
38
+ resourcesDefaultStates = FleetUtils.getResourcesDefaultState(this.$store.getters['i18n/withFallback'], 'fleet.fleetSummary.state');
39
+ } catch (error) {
40
+ }
41
+
42
+ return { resourcesDefaultStates };
43
+ },
44
+
45
+ computed: {
46
+ statuses() {
47
+ const state = this.statePanel;
48
+
49
+ if (state.id === 'success') {
50
+ if (this.noClusters) {
51
+ return [{
52
+ id: state.id,
53
+ icon: 'icon-warning',
54
+ customColor: '#DAC342',
55
+ tooltip: {},
56
+ handleClick: () => {},
57
+ }];
58
+ }
59
+
60
+ return [];
61
+ }
62
+
63
+ return [{
64
+ id: state.id,
65
+ icon: state.icon,
66
+ color: '',
67
+ customColor: state.color,
68
+ tooltip: {},
69
+ handleClick: () => {},
70
+ }];
71
+ },
72
+
73
+ /**
74
+ * Returns the count of the status for each resource in the GitRepo
75
+ */
76
+ resourceCounts() {
77
+ const out: Record<string, FleetResourceState> = clone(this.resourcesDefaultStates);
78
+
79
+ const resourceStatuses: Record<string, number> = this.value.allResourceStatuses;
80
+
81
+ Object.entries(resourceStatuses.states)
82
+ .filter(([_, count]) => count > 0)
83
+ .forEach(([state, count]) => {
84
+ const k = state?.toLowerCase();
85
+
86
+ if (out[k]) {
87
+ out[k].count += count;
88
+ } else {
89
+ out.unknown.count += count;
90
+ }
91
+ });
92
+
93
+ return Object.values(out).reduce((acc, { label, count }) => {
94
+ if (count > 0) {
95
+ return [...acc, { label, count }];
96
+ }
97
+
98
+ return acc;
99
+ }, [] as FleetResourceState[]).reverse();
100
+ },
101
+
102
+ resourcesTooltip() {
103
+ return this.resourceCounts.reduce((acc, state, i) => `${ acc }${ i > 0 ? '<br>' : '' }${ state.label }: ${ state.count }`, '');
104
+ },
105
+
106
+ noClusters() {
107
+ return !this.value.status?.desiredReadyClusters;
108
+ },
109
+
110
+ nameTooltip() {
111
+ if (this.value.nameDisplay?.length >= 15) {
112
+ return this.value.nameDisplay;
113
+ }
114
+
115
+ return null;
116
+ }
117
+ },
118
+
119
+ methods: {
120
+ select(value: PointerEvent) {
121
+ const elem = value?.target as HTMLElement;
122
+
123
+ if (elem?.tagName === 'A' || elem?.tagName === 'BUTTON' || elem?.className.includes('icon icon-actions')) {
124
+ return;
125
+ }
126
+
127
+ this.$emit('click');
128
+ },
129
+ }
130
+ };
131
+ </script>
132
+
133
+ <template>
134
+ <RcItemCard
135
+ :id="`${ value.metadata.namespace }-${ value.type }-${ value.id }`"
136
+ class="dashboard-resource-card"
137
+ variant="small"
138
+ :header="{
139
+ title: { text: value.nameDisplay },
140
+ statuses,
141
+ }"
142
+ :content="{}"
143
+ :value="value"
144
+ @click="select"
145
+ @keydown.self.enter.stop.prevent="select"
146
+ @keydown.self.space.stop.prevent="$router.push(value.detailLocation)"
147
+ >
148
+ <template #item-card-image>
149
+ <i
150
+ class="icon-lg"
151
+ :class="value.dashboardIcon"
152
+ />
153
+ </template>
154
+ <template #item-card-actions>
155
+ <ActionMenu
156
+ :resource="value"
157
+ :button-aria-label="t('sortableTable.tableActionsLabel', { resource: value?.id || '' })"
158
+ />
159
+ </template>
160
+ <template #item-card-content>
161
+ <ResourceCardSummary
162
+ v-clean-tooltip="{content: resourcesTooltip, triggers: ['hover']}"
163
+ :value="value"
164
+ :no-clusters="noClusters"
165
+ />
166
+ </template>
167
+ </RcItemCard>
168
+ </template>
169
+
170
+ <style lang="scss" scoped>
171
+ .dashboard-resource-card {
172
+ margin: 1px;
173
+ }
174
+
175
+ .icon-lg {
176
+ font-size: 25px;
177
+ margin-right: 8px;
178
+ }
179
+
180
+ // .item-card-body {
181
+ // width: -webkit-fill-available;
182
+ // }
183
+ </style>
@@ -0,0 +1,199 @@
1
+ <script lang="ts">
2
+ import { colorForState, stateSort } from '@shell/plugins/dashboard-store/resource-class';
3
+ import { sortBy } from '@shell/utils/sort';
4
+ import ProgressBarMulti from '@shell/components/ProgressBarMulti.vue';
5
+
6
+ export default {
7
+
8
+ name: 'FleetDashboardResourceCardSummary',
9
+
10
+ components: { ProgressBarMulti },
11
+
12
+ props: {
13
+ value: {
14
+ type: Object,
15
+ required: true
16
+ },
17
+ noClusters: {
18
+ type: Boolean,
19
+ default: false
20
+ }
21
+ },
22
+
23
+ data() {
24
+ return { typeLabel: this.t(`typeLabel."${ this.value.type }"`, { count: 1 }) };
25
+ },
26
+
27
+ computed: {
28
+ counts() {
29
+ return this.value.status?.resourceCounts || {};
30
+ },
31
+
32
+ countsPerCluster() {
33
+ return ((this.value.targetClusters || []) as { id: string }[]).map(({ id }) => this.value.status?.perClusterResourceCounts?.[id] || { desiredReady: 0 });
34
+ },
35
+
36
+ summary() {
37
+ const { desiredReady, ready } = this.counts;
38
+
39
+ const partial = desiredReady === ready ? ready : desiredReady - ready;
40
+ const total = desiredReady;
41
+ const clusters = partial !== total && total !== 0 ? this.countsPerCluster.filter((c) => c.desiredReady !== c.ready).length : this.countsPerCluster.length;
42
+
43
+ return {
44
+ partial,
45
+ total,
46
+ clusters
47
+ };
48
+ },
49
+
50
+ stateParts() {
51
+ const keys = Object.keys(this.counts).filter((x) => !x.startsWith('desired'));
52
+
53
+ const out = keys.map((key) => {
54
+ const textColor = colorForState(key);
55
+
56
+ return {
57
+ color: textColor.replace(/text-/, 'bg-'),
58
+ value: this.counts[key],
59
+ sort: stateSort(textColor, key),
60
+ };
61
+ }).filter((x) => x.value > 0);
62
+
63
+ return sortBy(out, 'sort:asc');
64
+ },
65
+
66
+ noClustersWarning() {
67
+ if (this.noClusters) {
68
+ return this.t('fleet.dashboard.cards.noClusters', { type: this.typeLabel });
69
+ }
70
+
71
+ return null;
72
+ },
73
+ },
74
+ };
75
+ </script>
76
+
77
+ <template>
78
+ <div class="summary-panel">
79
+ <div class="details">
80
+ <ProgressBarMulti
81
+ class="state-parts"
82
+ :values="stateParts"
83
+ />
84
+ </div>
85
+ <div class="mt-5 summary">
86
+ <div
87
+ v-if="value.stateDescription"
88
+ class="error mt-10"
89
+ >
90
+ <span
91
+ v-clean-tooltip="value.stateDescription"
92
+ class="label wrap-text fixed-height"
93
+ :class="{ 'text-error' : value.stateObj.error }"
94
+ >
95
+ {{ value.stateDescription }}
96
+ </span>
97
+ </div>
98
+ <div
99
+ v-else-if="noClusters"
100
+ class="no-clusters"
101
+ >
102
+ <span
103
+ v-clean-tooltip="noClustersWarning"
104
+ class="wrap-text"
105
+ >
106
+ {{ noClustersWarning }}
107
+ </span>
108
+ </div>
109
+ <div
110
+ v-else
111
+ class="count"
112
+ >
113
+ <div class="label">
114
+ <div>
115
+ <span class="large">{{ summary.partial }}</span>
116
+ <span
117
+ v-if="summary.partial !== summary.total && summary.total !== 0"
118
+ class="label-secondary"
119
+ >/{{ summary.total }}</span>
120
+ </div>
121
+ <div>
122
+ <span class="label-secondary">{{ t('fleet.dashboard.cards.resourceSummary.part1') }}</span>
123
+ <span class="large">{{ summary.clusters }}</span>
124
+ <span class="label-secondary">{{ t('fleet.dashboard.cards.resourceSummary.part2', { count: summary.clusters }) }}</span>
125
+ </div>
126
+ </div>
127
+ </div>
128
+ </div>
129
+ </div>
130
+ </template>
131
+
132
+ <style lang="scss" scoped>
133
+ .summary-panel {
134
+ width: 100%;
135
+
136
+ .progress {
137
+ width: 100%;
138
+ margin-top: 4px;
139
+ }
140
+
141
+ .progress, .progress * {
142
+ height: 6px;
143
+ border-right: 1px solid var(--body-bg);
144
+ }
145
+
146
+ .details {
147
+ display: flex;
148
+ align-items: center;
149
+ }
150
+
151
+ .summary {
152
+ margin-top: 5px;
153
+
154
+ .no-clusters {
155
+ display: flex;
156
+ align-items: center;
157
+ margin-top: 10px;
158
+
159
+ .icon {
160
+ margin-right: 5px;
161
+ }
162
+ }
163
+
164
+ .count {
165
+ display: flex;
166
+ align-items: center;
167
+
168
+ .icon {
169
+ margin-right: 3px;
170
+ }
171
+
172
+ .label {
173
+ display: flex;
174
+ gap: 8px;
175
+
176
+ .large {
177
+ font-size: 18px;
178
+ }
179
+
180
+ .label-secondary{
181
+ color: var(--label-secondary);
182
+ }
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ .wrap-text {
189
+ overflow: hidden;
190
+ text-overflow: ellipsis;
191
+ display: -webkit-box;
192
+ -webkit-line-clamp: 5;
193
+ -webkit-box-orient: vertical;
194
+ }
195
+
196
+ .fixed-height {
197
+ height: 80px;
198
+ }
199
+ </style>
@@ -0,0 +1,196 @@
1
+ <script lang="ts">
2
+ import { PropType } from 'vue';
3
+ import { FLEET } from '@shell/config/types';
4
+ import LabeledSelect from '@shell/components/form/LabeledSelect.vue';
5
+ import FleetResources from '@shell/components/fleet/FleetResources.vue';
6
+ import { RcButton } from '@components/RcButton';
7
+ import { FleetDashboardState } from '@shell/types/fleet';
8
+ import FleetApplicationSource from '@shell/components/formatter/FleetApplicationSource.vue';
9
+
10
+ export default {
11
+ name: 'FleetDashboardResourceDetails',
12
+
13
+ components: {
14
+ LabeledSelect,
15
+ FleetResources,
16
+ FleetApplicationSource,
17
+ RcButton,
18
+ },
19
+
20
+ props: {
21
+ value: {
22
+ type: Object,
23
+ required: true
24
+ },
25
+
26
+ statePanel: {
27
+ type: Object as PropType<FleetDashboardState>,
28
+ required: true
29
+ },
30
+
31
+ workspace: {
32
+ type: Object,
33
+ required: true
34
+ }
35
+ },
36
+
37
+ data() {
38
+ return {
39
+ FLEET,
40
+ clusterId: '',
41
+ detailLocation: {
42
+ ...this.value._detailLocation,
43
+ name: 'c-cluster-fleet-application-resource-namespace-id'
44
+ }
45
+ };
46
+ },
47
+
48
+ mounted() {
49
+ this.clusterId = this.clusters[0]?.value || '';
50
+ },
51
+
52
+ computed: {
53
+ clusters() {
54
+ return this.value.targetClusters.map((cluster: { id: string, nameDisplay: string }) => ({
55
+ label: cluster.nameDisplay,
56
+ value: cluster.id
57
+ }));
58
+ },
59
+
60
+ noResources() {
61
+ return !this.value.resourcesStatuses?.length;
62
+ },
63
+ },
64
+
65
+ methods: {
66
+ closePanel() {
67
+ this.$store.commit('slideInPanel/close');
68
+ }
69
+ }
70
+ };
71
+ </script>
72
+
73
+ <template>
74
+ <div class="details-panel">
75
+ <div
76
+ class="header"
77
+ :data-testid="'fleet-dashboard-resource-details-header'"
78
+ >
79
+ <div class="title">
80
+ <i :class="value.dashboardIcon" />
81
+ <router-link
82
+ class="label"
83
+ :to="detailLocation"
84
+ >
85
+ {{ value.id }}
86
+ </router-link>
87
+ <i
88
+ v-if="statePanel.id !== 'success'"
89
+ class="ml-5 state-icon"
90
+ :class="statePanel.icon"
91
+ :style="{ color: statePanel.color }"
92
+ />
93
+ </div>
94
+ <RcButton
95
+ small
96
+ ghost
97
+ data-testid="slide-in-close"
98
+ :aria-label="'slide-in-close'"
99
+ tabindex="0"
100
+ @click="closePanel"
101
+ @keydown.space.enter.stop.prevent="closePanel"
102
+ >
103
+ <i class="icon icon-close" />
104
+ </RcButton>
105
+ </div>
106
+
107
+ <h3>
108
+ {{ t('fleet.dashboard.source') }}
109
+ </h3>
110
+ <div class="mb-15">
111
+ <FleetApplicationSource
112
+ v-if="value.source.value"
113
+ :row="value"
114
+ />
115
+ <div
116
+ v-else
117
+ class="text-muted"
118
+ >
119
+ &mdash;
120
+ </div>
121
+ </div>
122
+
123
+ <h3>
124
+ {{ t('fleet.dashboard.resources') }}
125
+ </h3>
126
+ <FleetResources
127
+ :rows="value.resourcesStatuses"
128
+ :cluster-id="clusterId"
129
+ :search="!noResources"
130
+ >
131
+ <template
132
+ v-if="!noResources"
133
+ #header-left
134
+ >
135
+ <div class="row">
136
+ <div class="col span-10">
137
+ <LabeledSelect
138
+ v-model:value="clusterId"
139
+ :label="'Cluster'"
140
+ :options="clusters"
141
+ :mode="'edit'"
142
+ :disabled="workspace.id === 'fleet-local'"
143
+ />
144
+ </div>
145
+ </div>
146
+ </template>
147
+ </FleetResources>
148
+ </div>
149
+ </template>
150
+
151
+ <style lang="scss">
152
+ .details-panel {
153
+ padding: 10px;
154
+
155
+ .sortable-table-header {
156
+ .fixed-header-actions {
157
+ align-items: center;
158
+ }
159
+ }
160
+
161
+ .header {
162
+ display: flex;
163
+ align-items: center;
164
+ padding: 0;
165
+ margin: 0 0 20px 0;
166
+
167
+ .title {
168
+ display: flex;
169
+ align-items: center;
170
+ flex: 1;
171
+ font-style: normal;
172
+ font-weight: 600;
173
+ font-size: 18px;
174
+
175
+ .icon {
176
+ font-size: 2em;
177
+ margin-right: 16px;
178
+ }
179
+
180
+ .label {
181
+ margin-right: 8px;
182
+ }
183
+
184
+ .state-icon {
185
+ font-size: 1.5em;
186
+ }
187
+ }
188
+ }
189
+ }
190
+
191
+ .col {
192
+ .labeled-select {
193
+ min-width: 250px;
194
+ }
195
+ }
196
+ </style>