Skip to content

Commit 61797ee

Browse files
committed
feature to limit tags to policy
Signed-off-by: Sahiba Mittal <[email protected]>
1 parent 7845d41 commit 61797ee

File tree

4 files changed

+141
-7
lines changed

4 files changed

+141
-7
lines changed

src/i18n/locales/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"occurred_on": "Occurred On",
5252
"risk_type": "Risk Type",
5353
"project_name": "Project Name",
54+
"tag_name": "Tag Name",
5455
"version": "Version",
5556
"last_bom_import": "Last BOM Import",
5657
"bom_format": "BOM Format",
@@ -228,6 +229,7 @@
228229
"component_details": "Component Details",
229230
"snapshot_notification": "Snapshot Notification",
230231
"select_project": "Select Project",
232+
"select_tag": "Select Tag",
231233
"select": "Select",
232234
"identity": "Identity",
233235
"extended": "Extended",
@@ -471,6 +473,7 @@
471473
"delete_alert": "Delete Alert",
472474
"limit_to": "Limit To",
473475
"limit_to_projects": "Limit to projects",
476+
"limit_to_tags": "Limit to Tags",
474477
"alert_created": "Alert created",
475478
"alert_deleted": "Alert deleted",
476479
"change_password_next_login": "User must change password at next login",

src/shared/api.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"URL_USER_SELF": "api/v1/user/self",
2525
"URL_PERMISSION": "api/v1/permission",
2626
"URL_PROJECT": "api/v1/project",
27+
"URL_TAG": "api/v1/tag",
2728
"URL_FINDING": "api/v1/finding",
2829
"URL_LICENSE": "api/v1/license",
2930
"URL_LICENSE_CONCISE": "api/v1/license/concise",

src/views/policy/PolicyList.vue

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import PolicyCondition from "./PolicyCondition";
3030
import BToggleableDisplayButton from "@/views/components/BToggleableDisplayButton";
3131
import SelectProjectModal from "@/views/portfolio/projects/SelectProjectModal";
32+
import SelectTagModal from "@/views/portfolio/tags/SelectTagModal";
3233
3334
export default {
3435
mixins: [permissionsMixin, bootstrapTableMixin],
@@ -128,11 +129,19 @@
128129
<b-form-group v-if="limitToVisible === true" id="projectLimitsList" :label="this.$t('admin.limit_to_projects')">
129130
<div class="list-group">
130131
<span v-for="project in projects">
131-
<actionable-list-group-item :value="formatProjectLabel(project.name, project.version)" :delete-icon="true" v-on:actionClicked="deleteLimiter(project.uuid)"/>
132+
<actionable-list-group-item :value="formatLabel(project.name, project.version)" :delete-icon="true" v-on:actionClicked="deleteProjectLimiter(project.uuid)"/>
132133
</span>
133134
<actionable-list-group-item :add-icon="true" v-on:actionClicked="$root.$emit('bv::show::modal', 'selectProjectModal')"/>
134135
</div>
135136
</b-form-group>
137+
<b-form-group v-if="limitToVisible === true" id="tagLimitsList" :label="this.$t('admin.limit_to_tags')">
138+
<div class="list-group">
139+
<span v-for="tag in tags">
140+
<actionable-list-group-item :value="formatLabel(tag.name, tag.id)" :delete-icon="true" v-on:actionClicked="deleteTagLimiter(tag.name)"/>
141+
</span>
142+
<actionable-list-group-item :add-icon="true" v-on:actionClicked="$root.$emit('bv::show::modal', 'selectTagModal')"/>
143+
</div>
144+
</b-form-group>
136145
<div style="text-align:right">
137146
<b-toggleable-display-button variant="outline-primary" :label="$t('admin.limit_to')"
138147
v-permission="PERMISSIONS.VIEW_PORTFOLIO" v-on:toggle="limitToVisible = !limitToVisible" />
@@ -141,6 +150,7 @@
141150
</b-col>
142151
</b-row>
143152
<select-project-modal v-on:selection="updateProjectSelection"/>
153+
<select-tag-modal :policy="policy" v-on:selection="updateTagSelection"/>
144154
</div>
145155
`,
146156
mixins: [permissionsMixin],
@@ -150,6 +160,7 @@
150160
BInputGroupFormSelect,
151161
BToggleableDisplayButton,
152162
SelectProjectModal,
163+
SelectTagModal,
153164
PolicyCondition
154165
},
155166
data() {
@@ -169,15 +180,16 @@
169180
{ value: 'FAIL', text: this.$t('violation.fail') }
170181
],
171182
projects: row.projects,
172-
limitToVisible: false
183+
limitToVisible: false,
184+
tags: row.tags
173185
}
174186
},
175187
methods: {
176-
formatProjectLabel: function(projectName, projectVersion) {
177-
if (projectName && projectVersion) {
178-
return projectName + " " + projectVersion;
188+
formatLabel: function(labelName, labelProperty) {
189+
if (labelName && labelProperty) {
190+
return labelName + " " + labelProperty;
179191
} else {
180-
return projectName;
192+
return labelName;
181193
}
182194
},
183195
addCondition: function() {
@@ -229,7 +241,7 @@
229241
this.violationState = policy.violationState;
230242
this.conditions = policy.policyConditions;
231243
},
232-
deleteLimiter: function(projectUuid) {
244+
deleteProjectLimiter: function(projectUuid) {
233245
let url = `${this.$api.BASE_URL}/${this.$api.URL_POLICY}/${this.policy.uuid}/project/${projectUuid}`;
234246
this.axios.delete(url).then((response) => {
235247
let p = [];
@@ -244,6 +256,21 @@
244256
this.$toastr.w(this.$t('condition.unsuccessful_action'));
245257
});
246258
},
259+
deleteTagLimiter: function(tagName) {
260+
let url = `${this.$api.BASE_URL}/${this.$api.URL_POLICY}/${this.policy.uuid}/tag/${tagName}`;
261+
this.axios.delete(url).then((response) => {
262+
let p = [];
263+
for (let i=0; i<this.tags.length; i++) {
264+
if (this.tags[i].name !== tagName) {
265+
p.push(this.tags[i]);
266+
}
267+
}
268+
this.tags = p;
269+
this.$toastr.s(this.$t('message.updated'));
270+
}).catch((error) => {
271+
this.$toastr.w(this.$t('condition.unsuccessful_action'));
272+
});
273+
},
247274
updateProjectSelection: function(selections) {
248275
this.$root.$emit('bv::hide::modal', 'selectProjectModal');
249276
for (let i=0; i<selections.length; i++) {
@@ -260,6 +287,19 @@
260287
}
261288
});
262289
}
290+
},
291+
updateTagSelection: function(selections) {
292+
this.$root.$emit('bv::hide::modal', 'selectTagModal');
293+
for (let i=0; i<selections.length; i++) {
294+
let selection = selections[i];
295+
let url = `${this.$api.BASE_URL}/${this.$api.URL_POLICY}/${this.policy.uuid}/tag/${selection.name}`;
296+
this.axios.post(url).then((response) => {
297+
this.tags.push(selection);
298+
this.$toastr.s(this.$t('message.updated'));
299+
}).catch((error) => {
300+
this.$toastr.w(this.$t('condition.unsuccessful_action'));
301+
});
302+
}
263303
}
264304
},
265305
watch: {
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<template>
2+
<b-modal id="selectTagModal" size="lg" hide-header-close no-stacking
3+
v-permission="'VIEW_PORTFOLIO'" :title="$t('message.select_tag')">
4+
<bootstrap-table
5+
ref="table"
6+
:columns="columns"
7+
:data="data"
8+
:options="options">
9+
</bootstrap-table>
10+
<template v-slot:modal-footer="{ cancel }">
11+
<b-button size="md" variant="secondary" @click="cancel()">{{ $t('message.cancel') }}</b-button>
12+
<b-button size="md" variant="primary" @click="$emit('selection', $refs.table.getSelections())">{{ $t('message.select') }}</b-button>
13+
</template>
14+
</b-modal>
15+
</template>
16+
17+
<script>
18+
import xssFilters from "xss-filters";
19+
import permissionsMixin from "../../../mixins/permissionsMixin";
20+
import common from "../../../shared/common";
21+
22+
export default {
23+
props: {
24+
policy: Object
25+
},
26+
mixins: [permissionsMixin],
27+
methods: {
28+
apiUrl: function () {
29+
let url = `${this.$api.BASE_URL}/${this.$api.URL_TAG}/${this.policy.uuid}`;
30+
return url;
31+
},
32+
refreshTable: function() {
33+
this.$refs.table.refresh({
34+
url: this.apiUrl(),
35+
silent: true
36+
});
37+
}
38+
},
39+
watch:{
40+
showInactiveTags() {
41+
this.refreshTable();
42+
}
43+
},
44+
data() {
45+
return {
46+
showInactiveTags: false,
47+
labelIcon: {
48+
dataOn: '\u2713',
49+
dataOff: '\u2715'
50+
},
51+
columns: [
52+
{
53+
field: "state",
54+
checkbox: true,
55+
align: "center"
56+
},
57+
{
58+
title: this.$t('message.tag_name'),
59+
field: "name",
60+
sortable: true,
61+
formatter(value) {
62+
return xssFilters.inHTMLData(common.valueWithDefault(value, ""));
63+
}
64+
}
65+
],
66+
data: [],
67+
options: {
68+
search: true,
69+
showColumns: true,
70+
showRefresh: true,
71+
pagination: true,
72+
silentSort: false,
73+
sidePagination: 'server',
74+
queryParamsType: 'pageSize',
75+
pageList: '[10, 25, 50, 100]',
76+
pageSize: 10,
77+
icons: {
78+
refresh: 'fa-refresh'
79+
},
80+
toolbar: '#tagsToolbar',
81+
responseHandler: function (res, xhr) {
82+
res.total = xhr.getResponseHeader("X-Total-Count");
83+
return res;
84+
},
85+
url: this.apiUrl()
86+
}
87+
};
88+
}
89+
}
90+
</script>

0 commit comments

Comments
 (0)