mirror of
https://github.com/SecurityBrewery/catalyst.git
synced 2025-12-18 21:22:51 +01:00
Release catalyst
This commit is contained in:
64
ui/src/components/snippets/ArtifactSnippet.vue
Normal file
64
ui/src/components/snippets/ArtifactSnippet.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<v-list-item link dense>
|
||||
<v-list-item-content @click="goto">
|
||||
<v-list-item-title class="d-flex">
|
||||
<v-icon small class="mr-1">mdi-gauge</v-icon>
|
||||
<span class="text-truncate">{{ artifact.name }}</span>
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle class="d-flex">
|
||||
<v-icon small class="mr-1" :color="statusColor">{{ statusIcon }}</v-icon>
|
||||
<span :class="statusColor + '--text'">{{ artifact.status | capitalize }}</span>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
<v-icon small class="mr-1">mdi-information</v-icon>
|
||||
<span class="mr-1">{{ artifact.enrichments ? lodash.size(artifact.enrichments) : 0 }}</span>
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action v-if="action !== ''">
|
||||
<v-btn icon small>
|
||||
<v-icon small @click="actionClick">{{ action }}</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
import {Type, TypeColorEnum} from "../../client";
|
||||
|
||||
export default Vue.extend({
|
||||
name: "ArtifactSnippet",
|
||||
props: ["artifact", "to", "action"],
|
||||
computed: {
|
||||
statusIcon: function () {
|
||||
let icon = "mdi-help";
|
||||
this.lodash.forEach(this.$store.state.settings.artifactStates, (state: Type) => {
|
||||
if (this.artifact.status === state.id) {
|
||||
icon = state.icon;
|
||||
}
|
||||
})
|
||||
return icon;
|
||||
},
|
||||
statusColor: function () {
|
||||
let color = TypeColorEnum.Info;
|
||||
this.lodash.forEach(this.$store.state.settings.artifactStates, (state: Type) => {
|
||||
if (this.artifact.status === state.id && state.color) {
|
||||
color = state.color
|
||||
}
|
||||
})
|
||||
return color;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
actionClick: function () {
|
||||
this.$emit("actionClick", this.artifact)
|
||||
},
|
||||
goto: function () {
|
||||
this.$emit("click", this.artifact)
|
||||
if (this.to) {
|
||||
this.$router.push(this.to);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
60
ui/src/components/snippets/IDSnippet.vue
Normal file
60
ui/src/components/snippets/IDSnippet.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div>
|
||||
<TicketSnippet v-if="ticket !== undefined" :ticket="ticket" :to="{ name: 'Ticket', params: { type: ticket.type, id: ticket.id } }"></TicketSnippet>
|
||||
<ArtifactSnippet v-if="artifact !== undefined" :artifact="artifact" :to="{ name: 'Artifact', params: { artifact: artifact.name } }"></ArtifactSnippet>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
import {Artifact, TicketResponse} from "../../client";
|
||||
import {API} from "@/services/api";
|
||||
import TicketSnippet from "./TicketSnippet.vue";
|
||||
import ArtifactSnippet from "./ArtifactSnippet.vue";
|
||||
|
||||
interface State {
|
||||
ticket?: TicketResponse;
|
||||
artifact?: Artifact;
|
||||
}
|
||||
|
||||
export default Vue.extend({
|
||||
name: "IDSnippet",
|
||||
props: ["id"],
|
||||
data: (): State => ({
|
||||
ticket: undefined,
|
||||
artifact: undefined,
|
||||
}),
|
||||
components: {
|
||||
ArtifactSnippet,
|
||||
TicketSnippet
|
||||
},
|
||||
methods: {
|
||||
loadSnippet() {
|
||||
if (this.id.startsWith("tickets/")) {
|
||||
this.artifact = undefined;
|
||||
let ticketID = this.id.replace("tickets/", "")
|
||||
API.getTicket(ticketID).then(response => {
|
||||
this.ticket = response.data;
|
||||
});
|
||||
}
|
||||
if (this.id.startsWith("artifacts/")) {
|
||||
this.ticket = undefined;
|
||||
// TODO
|
||||
// let artifactID = this.id.replace("artifacts/", "")
|
||||
// API.getArtifact(artifactID).then(response => {
|
||||
// this.artifact = response.data;
|
||||
// });
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
"id": "loadSnippet",
|
||||
$route: "loadSnippet"
|
||||
},
|
||||
mounted() {
|
||||
this.loadSnippet();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
91
ui/src/components/snippets/TicketSnippet.vue
Normal file
91
ui/src/components/snippets/TicketSnippet.vue
Normal file
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<v-list-item link dense>
|
||||
<v-list-item-content @click="goto">
|
||||
<v-list-item-title class="d-flex">
|
||||
<v-icon small class="mr-1">{{ typeIcon }}</v-icon>
|
||||
<span class="text-truncate">{{ ticket.type | capitalize }} #{{ ticket.id }}: {{ ticket.name }}</span>
|
||||
<v-spacer></v-spacer>
|
||||
<v-icon small class="mr-1">mdi-calendar-plus</v-icon>
|
||||
{{ ticket.created | formatdate($store.state.settings.timeformat) }}
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle class="d-flex">
|
||||
<v-icon small class="mr-1" :color="statusColor">{{ statusIcon }}</v-icon>
|
||||
<span :class="statusColor + '--text'">{{ ticket.status | capitalize }}</span>
|
||||
|
||||
<v-icon small class="mx-1">mdi-account</v-icon>
|
||||
{{ ticket.owner ? ticket.owner : 'unassigned' }}
|
||||
<v-spacer></v-spacer>
|
||||
<v-icon small class="mr-1">mdi-source-branch</v-icon>
|
||||
<span class="mr-1">{{ ticket.playbooks ? lodash.size(ticket.playbooks) : 0 }}</span>
|
||||
<v-icon small class="mr-1">mdi-checkbox-multiple-marked-outline</v-icon>
|
||||
<span class="mr-1">{{ opentaskcount }}</span>
|
||||
<v-icon small class="mr-1">mdi-comment</v-icon>
|
||||
<span class="mr-1">{{ ticket.comments ? ticket.comments.length : 0 }}</span>
|
||||
<v-icon small class="mr-1">mdi-file</v-icon>
|
||||
<span class="mr-1">{{ ticket.files ? ticket.files.length : 0 }}</span>
|
||||
<v-icon small class="mr-1">mdi-link</v-icon>
|
||||
<span class="mr-1">{{ ticket.references ? ticket.references.length : 0 }}</span>
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action v-if="action !== ''">
|
||||
<v-btn icon small>
|
||||
<v-icon small @click="actionClick">{{ action }}</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
import {Playbook, Task, Type, TypeColorEnum} from "@/client";
|
||||
|
||||
export default Vue.extend({
|
||||
name: "TicketSnippet",
|
||||
props: ["ticket", "to", "action"],
|
||||
computed: {
|
||||
opentaskcount: function() {
|
||||
let count = 0;
|
||||
this.lodash.forEach(this.ticket.playbooks, (playbook: Playbook) => {
|
||||
this.lodash.forEach(playbook.tasks, (task: Task) => {
|
||||
if (task.done) {
|
||||
count++;
|
||||
}
|
||||
})
|
||||
})
|
||||
return count;
|
||||
},
|
||||
typeIcon: function () {
|
||||
let icon = "mdi-help";
|
||||
this.lodash.forEach(this.$store.state.settings.ticketTypes, (ticketType: Type) => {
|
||||
if (this.ticket.type === ticketType.id) {
|
||||
icon = ticketType.icon
|
||||
}
|
||||
})
|
||||
return icon;
|
||||
},
|
||||
statusIcon: function() {
|
||||
if (this.ticket.status === 'closed') {
|
||||
return "mdi-checkbox-marked-circle-outline";
|
||||
}
|
||||
return "mdi-arrow-right-drop-circle-outline";
|
||||
},
|
||||
statusColor: function() {
|
||||
if (this.ticket.status === 'closed') {
|
||||
return TypeColorEnum.Success;
|
||||
}
|
||||
return TypeColorEnum.Info;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
actionClick: function () {
|
||||
this.$emit("actionClick", this.ticket)
|
||||
},
|
||||
goto: function () {
|
||||
if (this.to === undefined) {
|
||||
return
|
||||
}
|
||||
this.$router.push(this.to);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user