Skip to content

Commit 68780ec

Browse files
lsongsusexingzhang-suse
authored andcommitted
Feat: Implement VexHub Add/Edit Page
1 parent 5f116a5 commit 68780ec

File tree

6 files changed

+284
-24
lines changed

6 files changed

+284
-24
lines changed

pkg/sbombastic-image-vulnerability-scanner/config/sbombastic-image-vulnerability-scanner.ts

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,6 @@ export function init($plugin: IPlugin, store: any) {
5252
},
5353
});
5454

55-
virtualType({
56-
labelKey: 'imageScanner.vexManagement.title',
57-
name: PAGE.VEX_MANAGEMENT,
58-
namespaced: false,
59-
route: {
60-
name: `c-cluster-${PRODUCT_NAME}-${PAGE.VEX_MANAGEMENT}`,
61-
params: {
62-
product: PRODUCT_NAME
63-
},
64-
meta: { pkg: PRODUCT_NAME, product: PRODUCT_NAME }
65-
}
66-
});
67-
6855
virtualType({
6956
label: "Components Demo",
7057
name: "demo",
@@ -84,6 +71,6 @@ export function init($plugin: IPlugin, store: any) {
8471
//"demo"
8572
]);
8673
// Prepend spaces on group name, as Rancher 2.12 render group name algin with sidemenu
87-
basicType([PAGE.REGISTRIES, PAGE.VEX_MANAGEMENT], '    Advanced');
74+
basicType([PAGE.REGISTRIES, RESOURCE.VEX_HUB], '    Advanced');
8875

8976
}

pkg/sbombastic-image-vulnerability-scanner/edit/sbombastic.rancher.io.registry.vue

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import NameNsDescription from '@shell/components/form/NameNsDescription';
66
import CruResource from '@shell/components/CruResource';
77
import SelectOrCreateAuthSecret from '@shell/components/form/SelectOrCreateAuthSecret';
88
import LabeledSelect from '@shell/components/form/LabeledSelect';
9-
import Banner from '@components/Banner/Banner.vue';
109
import { Checkbox } from '@components/Form/Checkbox';
1110
import { MANAGEMENT, NAMESPACE } from '@shell/config/types';
1211
import {
@@ -25,7 +24,6 @@ export default {
2524
NameNsDescription,
2625
CruResource,
2726
SelectOrCreateAuthSecret,
28-
Banner,
2927
Checkbox,
3028
LabeledSelect
3129
},
@@ -123,13 +121,11 @@ export default {
123121
124122
<template>
125123
<div class="filled-height">
126-
<Banner color="info">
127-
{{t('imageScanner.registries.configuration.cru.description')}}
128-
</Banner>
129124
<CruResource
130125
:done-route="doneRoute"
131126
:mode="mode"
132127
:resource="value"
128+
:description="t('imageScanner.registries.configuration.cru.description')"
133129
:subtypes="[]"
134130
:validation-passed="true"
135131
:errors="errors"
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<script>
2+
import NameNsDescription from "@shell/components/form/NameNsDescription.vue";
3+
import CruResource from "@shell/components/CruResource.vue";
4+
import Banner from "@components/Banner/Banner.vue";
5+
import { Checkbox } from '@components/Form/Checkbox';
6+
import { LabeledInput } from '@components/Form/LabeledInput';
7+
import CreateEditView from "@shell/mixins/create-edit-view";
8+
import {PAGE, PRODUCT_NAME} from "@sbombastic-image-vulnerability-scanner/types/sbombastic-image-vulnerability-scanner";
9+
10+
export default {
11+
name: 'CruVexHub',
12+
13+
components: {
14+
LabeledInput,
15+
NameNsDescription,
16+
CruResource,
17+
Banner,
18+
Checkbox,
19+
},
20+
21+
mixins: [CreateEditView],
22+
23+
data() {
24+
if (!this.value.spec) {
25+
this.value.spec = {
26+
url: '',
27+
enabled: true,
28+
};
29+
}
30+
31+
return {
32+
errors: null,
33+
PAGE,
34+
PRODUCT_NAME,
35+
};
36+
},
37+
}
38+
</script>
39+
<template>
40+
<div class="filled-height">
41+
<CruResource
42+
:done-route="doneRoute"
43+
:mode="mode"
44+
:resource="value"
45+
:description="t('imageScanner.vexManagement.cru.description')"
46+
:subtypes="[]"
47+
:validation-passed="true"
48+
:errors="errors"
49+
:cancel-event="true"
50+
@error="(e) => (errors = e)"
51+
@finish="apply"
52+
@cancel="done"
53+
>
54+
<NameNsDescription
55+
:value="value"
56+
:mode="mode"
57+
:namespaced=false
58+
@update:value="$emit('input', $event)"
59+
/>
60+
<div class="row">
61+
<div class="col span-9" >
62+
<LabeledInput
63+
v-model:value="value.spec.url"
64+
:mode="mode"
65+
:label="t('imageScanner.vexManagement.cru.uri.label')"
66+
:required="true"
67+
/>
68+
</div>
69+
</div>
70+
<div class="row mt-16">
71+
<Checkbox
72+
v-model:value="value.spec.enabled"
73+
:tooltip="t('imageScanner.vexManagement.cru.enable.tooltip')"
74+
data-testid="imageScanner-vexManagement-cru-enable-checkbox"
75+
class="check"
76+
type="checkbox"
77+
label-key="imageScanner.vexManagement.cru.enable.label"
78+
:mode="mode"
79+
/>
80+
</div>
81+
</CruResource>
82+
</div>
83+
</template>
84+
<style lang="scss" scoped>
85+
.mt-16 {
86+
margin-top: 16px;
87+
}
88+
</style>

pkg/sbombastic-image-vulnerability-scanner/l10n/en-us.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,14 @@ imageScanner:
107107
createdBy: Created by
108108
updated: Updated
109109
actions: Actions
110+
cru:
111+
description: Start from scratch by using the steps below or go back and clone an existing entry
112+
name: Name
113+
uri:
114+
label: VEX hub URI
115+
enable:
116+
label: Enabled
117+
tooltip: Controls whether this VEX entry is active in vulnerability assessments.
110118
enum:
111119
cve:
112120
critical: Critical
@@ -139,3 +147,4 @@ imageScanner:
139147

140148
typeLabel:
141149
sbombastic.rancher.io.registry: Registries configuration
150+
sbombastic.rancher.io.vexhub: Vex Management
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
<template>
2+
<div>
3+
4+
<Banner color="info">
5+
{{t('imageScanner.vexManagement.description')}}
6+
</Banner>
7+
8+
<ResourceTable
9+
ref="rt"
10+
:schema="schema"
11+
:rows="rows"
12+
:namespaced="false"
13+
:headers="headers"
14+
:key-field="'id'"
15+
:table-actions="true"
16+
:use-query-params-for-simple-filtering="true"
17+
:force-update-live-and-delayed="forceUpdateKey"
18+
>
19+
</ResourceTable>
20+
</div>
21+
</template>
22+
23+
<script>
24+
import { RESOURCE } from "@sbombastic-image-vulnerability-scanner/types";
25+
import ResourceTable from "@shell/components/ResourceTable";
26+
import Banner from '@components/Banner/Banner.vue';
27+
import RegisterStatusBadge from "@sbombastic-image-vulnerability-scanner/components/common/RegisterStatusBadge";
28+
import { VEX_MANAGEMENT_TABLE } from "@sbombastic-image-vulnerability-scanner/config/table-headers";
29+
import {
30+
PRODUCT_NAME,
31+
} from "@sbombastic-image-vulnerability-scanner/types";
32+
33+
export default {
34+
name: 'VexManagement',
35+
components: {
36+
Banner,
37+
ResourceTable,
38+
RegisterStatusBadge,
39+
},
40+
data() {
41+
return {
42+
PRODUCT_NAME: PRODUCT_NAME,
43+
headers: VEX_MANAGEMENT_TABLE,
44+
disabled: false,
45+
selectedRows: [],
46+
filterText: '',
47+
rows: [],
48+
forceUpdateKey: 0
49+
}
50+
},
51+
async fetch() {
52+
await this.$store.dispatch('cluster/findAll', { type: RESOURCE.VEX_HUB });
53+
const vexhubsCRD = this.$store.getters['cluster/all']?.(RESOURCE.VEX_HUB);
54+
this.rows = vexhubsCRD || [];
55+
},
56+
methods: {
57+
rowWithActions(r) { return r; },
58+
async switchStatus(desired, selected) {
59+
const resources = selected && selected.length ? selected : (this.selectedRows || []);
60+
if (!resources.length) return;
61+
await Promise.all(resources.map(async (m) => {
62+
m.spec = { ...(m.spec || {}), enabled: desired };
63+
await m.save();
64+
}));
65+
await this.$fetch();
66+
},
67+
createVexHub() {
68+
this.$router.push({
69+
name: `${ PRODUCT_NAME }-c-cluster-resource-create`,
70+
params: {
71+
resource: RESOURCE.VEX_HUB,
72+
cluster: this.$route.params.cluster,
73+
product: PRODUCT_NAME
74+
}
75+
});
76+
}
77+
},
78+
computed: {
79+
schema() {
80+
return this.$store.getters['cluster/schemaFor']?.(RESOURCE.VEX_HUB);
81+
},
82+
showMasthead(){
83+
const showMasthead = getters[`type-map/optionsFor`](this.resource).showListMasthead;
84+
console.log("=====showMasthead", showMasthead, this.resource);
85+
return false;
86+
}
87+
}
88+
}
89+
</script>
90+
91+
<style lang="scss" scoped>
92+
93+
.header-section {
94+
display: flex;
95+
align-items: flex-start;
96+
gap: 24px;
97+
align-self: stretch;
98+
margin-bottom: 24px;
99+
100+
.header-left {
101+
display: flex;
102+
flex-direction: column;
103+
justify-content: center;
104+
align-items: flex-start;
105+
gap: 8px;
106+
flex: 1 0 0;
107+
}
108+
109+
.title-wrap {
110+
display: flex;
111+
align-items: center;
112+
gap: 12px;
113+
align-self: stretch;
114+
115+
.title {
116+
color: #141419;
117+
font-family: Lato;
118+
font-size: 24px;
119+
font-style: normal;
120+
font-weight: 600;
121+
line-height: 32px;
122+
}
123+
}
124+
125+
.description {
126+
max-width: 900px;
127+
align-self: stretch;
128+
color: #717179;
129+
font-family: Lato;
130+
font-size: 14px;
131+
font-style: normal;
132+
font-weight: 400;
133+
line-height: 21px;
134+
}
135+
136+
.header-right {
137+
display: flex;
138+
align-items: flex-end;
139+
justify-content: end;
140+
flex: 1 0 0;
141+
gap: 24px;
142+
}
143+
144+
.header-btn {
145+
height: 40px;
146+
}
147+
}
148+
149+
// Status cell centering
150+
.status-cell {
151+
display: flex;
152+
align-items: center;
153+
justify-content: flex-start;
154+
height: 100%;
155+
min-height: 48px;
156+
padding: 8px 0;
157+
158+
:deep(.badge) {
159+
margin: 0;
160+
vertical-align: middle;
161+
}
162+
}
163+
164+
.uri-link .icon-external-link {
165+
margin-left: 6px;
166+
opacity: 0.7;
167+
}
168+
169+
/* Bulk header action buttons - align icons and text */
170+
.bulk-actions {
171+
display: flex;
172+
align-items: center;
173+
gap: 12px;
174+
}
175+
176+
.bulk-actions .btn {
177+
display: inline-flex;
178+
align-items: center;
179+
}
180+
181+
.bulk-actions .btn i {
182+
margin-right: 6px;
183+
line-height: 1;
184+
}
185+
</style>

pkg/sbombastic-image-vulnerability-scanner/routes/sbombastic-image-vulnerability-scanner-routes.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@ const routes = [
2222
path: `/c/:cluster/${PRODUCT_NAME}/${PAGE.VULNERABILITY_OVERVIEW}`,
2323
component: Vulnerabilities,
2424
},
25-
{
26-
name: `c-cluster-${PRODUCT_NAME}-${PAGE.VEX_MANAGEMENT}`,
27-
path: `/c/:cluster/${PRODUCT_NAME}/${PAGE.VEX_MANAGEMENT}`,
28-
component: VexManagement,
29-
},
3025
{
3126
name: `c-cluster-${PRODUCT_NAME}-demo`,
3227
path: `/c/:cluster/${PRODUCT_NAME}/demo`,

0 commit comments

Comments
 (0)