Skip to content

Commit 5f116a5

Browse files
rushk014xingzhang-suse
authored andcommitted
Feat: Vex management - Detail
1 parent ec3febc commit 5f116a5

File tree

5 files changed

+923
-1664
lines changed

5 files changed

+923
-1664
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"dependencies": {
99
"@kubernetes/client-node": "^1.3.0",
1010
"@rancher/components": "^0.3.0-alpha.1",
11-
"@rancher/shell": "3.0.5-rc.7",
11+
"@rancher/shell": "3.0.5-rc.8",
1212
"vue": "^3.5.17",
1313
"vue-router": "^4.5.0",
1414
"vuex": "^4.1.0"
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<script setup lang="ts">
2+
import DetailPage from '@shell/components/Resource/Detail/Page.vue';
3+
import Masthead from '@shell/components/Resource/Detail/Masthead/index.vue';
4+
import { useStore } from 'vuex';
5+
import { useI18n } from '@shell/composables/useI18n';
6+
import UriExternalLink from '@sbombastic-image-vulnerability-scanner/formatters/UriExternalLink.vue';
7+
import { computed } from 'vue';
8+
9+
const store = useStore();
10+
const { t } = useI18n(store);
11+
const props = defineProps<{
12+
value: any;
13+
}>();
14+
15+
const vexhub = props.value;
16+
17+
const defaultMastheadProps = computed(() => {
18+
return {
19+
titleBarProps: {
20+
resource: vexhub,
21+
resourceName: vexhub.metadata.name,
22+
resourceTypeLabel: t('imageScanner.vexManagement.title'),
23+
resourceTo: vexhub.listLocation,
24+
badge: {
25+
color: vexhub.spec.enabled ? ('bg-success' as 'bg-success') : ('bg-error' as 'bg-error'),
26+
label: t(`imageScanner.enum.status.${vexhub.spec.enabled ? 'enabled' : 'disabled'}`)
27+
},
28+
actionMenuResource: vexhub,
29+
showViewOptions: false
30+
},
31+
metadataProps: {
32+
resource: vexhub,
33+
identifyingInformation: [
34+
{
35+
label: 'URI',
36+
value: vexhub.spec.url,
37+
valueOverride: {
38+
component: UriExternalLink,
39+
props: {
40+
value: vexhub.spec.url,
41+
}
42+
}
43+
},
44+
{
45+
label: 'Created by',
46+
value: Number(vexhub.metadata.generation) === 1 ? "Rancher" : "Manual entry"
47+
},
48+
{
49+
label: 'Last sync',
50+
value: null
51+
},
52+
{
53+
label: 'Updated',
54+
value: vexhub.metadata.creationTimestamp
55+
}
56+
],
57+
annotations: [],
58+
labels: []
59+
}
60+
};
61+
})
62+
</script>
63+
64+
<template>
65+
<DetailPage>
66+
<template #top-area>
67+
<Masthead v-bind="defaultMastheadProps">
68+
<template #additional-actions>
69+
<button
70+
data-testid="detail-explore-button"
71+
type="button"
72+
class="btn role-primary actions"
73+
@click="value.toggle.invoke()"
74+
>
75+
<i :class="`icon ${value.toggle.icon}`"></i>
76+
{{ value.toggle.label }}
77+
</button>
78+
</template>
79+
</Masthead>
80+
</template>
81+
</DetailPage>
82+
</template>
83+
84+
<style lang="scss" scoped>
85+
.btn.actions {
86+
gap: 12px;
87+
}
88+
</style>

pkg/sbombastic-image-vulnerability-scanner/formatters/VexNameLink.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ export default {
1515
</script>
1616

1717
<template>
18-
<RouterLink :to="`/c/${$route.params.cluster}/imageScanner/vex_management/${row.id}`">{{ value }}</RouterLink>
18+
<RouterLink :to="`/c/${$route.params.cluster}/imageScanner/sbombastic.rancher.io.vexhub/${row.id}`">{{ value }}</RouterLink>
1919
</template>
Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import SteveModel from '@shell/plugins/steve/steve-class';
2+
import { PRODUCT_NAME, PAGE } from "@sbombastic-image-vulnerability-scanner/types";
23
import { insertAt } from '@shell/utils/array';
34

45
export default class SbombasticRancherIoVexhub extends SteveModel {
56
get _availableActions() {
67
let out = super._availableActions || [];
78

9+
// Check if we are in the details page
10+
const isDetailsPage = this.$rootState.targetRoute && 'id' in this.$rootState.targetRoute.params;
11+
812
// Remove download actions and View in API, keep edit YAML and clone
913
const remove = new Set([
1014
'download',
@@ -17,30 +21,7 @@ export default class SbombasticRancherIoVexhub extends SteveModel {
1721
out = out.filter((a) => !a?.action || !remove.has(a.action));
1822

1923
const isEnabled = !!this.spec?.enabled;
20-
21-
const toggle = isEnabled
22-
? {
23-
action: 'disable',
24-
label: this.t('imageScanner.vexManagement.buttons.disable') || 'Disable',
25-
icon: 'icon-pause',
26-
enabled: true,
27-
bulkable: true,
28-
invoke: async() => {
29-
this.spec = { ...(this.spec || {}), enabled: false };
30-
await this.save();
31-
}
32-
}
33-
: {
34-
action: 'enable',
35-
label: this.t('imageScanner.vexManagement.buttons.enable') || 'Enable',
36-
icon: 'icon-play',
37-
enabled: true,
38-
bulkable: true,
39-
invoke: async() => {
40-
this.spec = { ...(this.spec || {}), enabled: true };
41-
await this.save();
42-
}
43-
};
24+
const toggle = this.toggle;
4425

4526
if (isEnabled) {
4627
// For enabled items: Disable, then other actions
@@ -57,20 +38,65 @@ export default class SbombasticRancherIoVexhub extends SteveModel {
5738
}
5839

5940
// Ensure all actions are enabled
60-
return reordered.map(action => {
41+
const returnActions = reordered.map(action => {
6142
if (action && action.enabled === false) {
6243
return { ...action, enabled: true };
6344
}
6445
return action;
6546
});
47+
return isDetailsPage ? returnActions.slice(1) : returnActions;
6648
}
6749

6850
// When disabled: Enable, then Delete
6951
const deleteAction = out.find((a) => a?.action === 'promptRemove');
70-
return [toggle, ...(deleteAction ? [deleteAction] : [])];
52+
const returnActions = [toggle, ...(deleteAction ? [deleteAction] : [])];
53+
return isDetailsPage ? returnActions.slice(1) : returnActions;
7154
}
7255

7356
get canDelete() {
7457
return !this.spec?.enabled;
7558
}
59+
60+
get listLocation() {
61+
return { name: `c-cluster-${PRODUCT_NAME}-${PAGE.VEX_MANAGEMENT}`, };
62+
}
63+
64+
get doneOverride() {
65+
return this.listLocation;
66+
}
67+
68+
get parentLocationOverride() {
69+
return this.listLocation;
70+
}
71+
72+
get fullDetailPageOverride() {
73+
return true;
74+
}
75+
76+
get toggle() {
77+
const isEnabled = !!this.spec?.enabled;
78+
return isEnabled
79+
? {
80+
action: 'disable',
81+
label: this.t('imageScanner.vexManagement.buttons.disable') || 'Disable',
82+
icon: 'icon-pause',
83+
enabled: true,
84+
bulkable: true,
85+
invoke: async() => {
86+
this.spec = { ...(this.spec || {}), enabled: false };
87+
await this.save();
88+
}
89+
}
90+
: {
91+
action: 'enable',
92+
label: this.t('imageScanner.vexManagement.buttons.enable') || 'Enable',
93+
icon: 'icon-play',
94+
enabled: true,
95+
bulkable: true,
96+
invoke: async() => {
97+
this.spec = { ...(this.spec || {}), enabled: true };
98+
await this.save();
99+
}
100+
};
101+
}
76102
}

0 commit comments

Comments
 (0)