Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"dependencies": {
"@kubernetes/client-node": "^1.3.0",
"@rancher/components": "^0.3.0-alpha.1",
"@rancher/shell": "3.0.5-rc.7",
"@rancher/shell": "3.0.5-rc.8",
"vue": "^3.5.17",
"vue-router": "^4.5.0",
"vuex": "^4.1.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<script setup lang="ts">
import DetailPage from '@shell/components/Resource/Detail/Page.vue';
import Masthead from '@shell/components/Resource/Detail/Masthead/index.vue';
import { useStore } from 'vuex';
import { useI18n } from '@shell/composables/useI18n';
import UriExternalLink from '@sbombastic-image-vulnerability-scanner/formatters/UriExternalLink.vue';
import { computed } from 'vue';

const store = useStore();
const { t } = useI18n(store);
const props = defineProps<{
value: any;
}>();

const vexhub = props.value;

const defaultMastheadProps = computed(() => {
return {
titleBarProps: {
resource: vexhub,
resourceName: vexhub.metadata.name,
resourceTypeLabel: t('imageScanner.vexManagement.title'),
resourceTo: vexhub.listLocation,
badge: {
color: vexhub.spec.enabled ? ('bg-success' as 'bg-success') : ('bg-error' as 'bg-error'),
label: t(`imageScanner.enum.status.${vexhub.spec.enabled ? 'enabled' : 'disabled'}`)
},
actionMenuResource: vexhub,
showViewOptions: false
},
metadataProps: {
resource: vexhub,
identifyingInformation: [
{
label: 'URI',
value: vexhub.spec.url,
valueOverride: {
component: UriExternalLink,
props: {
value: vexhub.spec.url,
}
}
},
{
label: 'Created by',
value: Number(vexhub.metadata.generation) === 1 ? "Rancher" : "Manual entry"
},
{
label: 'Last sync',
value: null
},
{
label: 'Updated',
value: vexhub.metadata.creationTimestamp
}
],
annotations: [],
labels: []
}
};
})
</script>

<template>
<DetailPage>
<template #top-area>
<Masthead v-bind="defaultMastheadProps">
<template #additional-actions>
<button
data-testid="detail-explore-button"
type="button"
class="btn role-primary actions"
@click="value.toggle.invoke()"
>
<i :class="`icon ${value.toggle.icon}`"></i>
{{ value.toggle.label }}
</button>
</template>
</Masthead>
</template>
</DetailPage>
</template>

<style lang="scss" scoped>
.btn.actions {
gap: 12px;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ export default {
</script>

<template>
<RouterLink :to="`/c/${$route.params.cluster}/imageScanner/vex_management/${row.id}`">{{ value }}</RouterLink>
<RouterLink :to="`/c/${$route.params.cluster}/imageScanner/sbombastic.rancher.io.vexhub/${row.id}`">{{ value }}</RouterLink>
</template>
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import SteveModel from '@shell/plugins/steve/steve-class';
import { PRODUCT_NAME, PAGE } from "@sbombastic-image-vulnerability-scanner/types";
import { insertAt } from '@shell/utils/array';

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

// Check if we are in the details page
const isDetailsPage = this.$rootState.targetRoute && 'id' in this.$rootState.targetRoute.params;

// Remove download actions and View in API, keep edit YAML and clone
const remove = new Set([
'download',
Expand All @@ -17,30 +21,7 @@ export default class SbombasticRancherIoVexhub extends SteveModel {
out = out.filter((a) => !a?.action || !remove.has(a.action));

const isEnabled = !!this.spec?.enabled;

const toggle = isEnabled
? {
action: 'disable',
label: this.t('imageScanner.vexManagement.buttons.disable') || 'Disable',
icon: 'icon-pause',
enabled: true,
bulkable: true,
invoke: async() => {
this.spec = { ...(this.spec || {}), enabled: false };
await this.save();
}
}
: {
action: 'enable',
label: this.t('imageScanner.vexManagement.buttons.enable') || 'Enable',
icon: 'icon-play',
enabled: true,
bulkable: true,
invoke: async() => {
this.spec = { ...(this.spec || {}), enabled: true };
await this.save();
}
};
const toggle = this.toggle;

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

// Ensure all actions are enabled
return reordered.map(action => {
const returnActions = reordered.map(action => {
if (action && action.enabled === false) {
return { ...action, enabled: true };
}
return action;
});
return isDetailsPage ? returnActions.slice(1) : returnActions;
}

// When disabled: Enable, then Delete
const deleteAction = out.find((a) => a?.action === 'promptRemove');
return [toggle, ...(deleteAction ? [deleteAction] : [])];
const returnActions = [toggle, ...(deleteAction ? [deleteAction] : [])];
return isDetailsPage ? returnActions.slice(1) : returnActions;
}

get canDelete() {
return !this.spec?.enabled;
}

get listLocation() {
return { name: `c-cluster-${PRODUCT_NAME}-${PAGE.VEX_MANAGEMENT}`, };
}

get doneOverride() {
return this.listLocation;
}

get parentLocationOverride() {
return this.listLocation;
}

get fullDetailPageOverride() {
return true;
}

get toggle() {
const isEnabled = !!this.spec?.enabled;
return isEnabled
? {
action: 'disable',
label: this.t('imageScanner.vexManagement.buttons.disable') || 'Disable',
icon: 'icon-pause',
enabled: true,
bulkable: true,
invoke: async() => {
this.spec = { ...(this.spec || {}), enabled: false };
await this.save();
}
}
: {
action: 'enable',
label: this.t('imageScanner.vexManagement.buttons.enable') || 'Enable',
icon: 'icon-play',
enabled: true,
bulkable: true,
invoke: async() => {
this.spec = { ...(this.spec || {}), enabled: true };
await this.save();
}
};
}
}
Loading