Skip to content

Commit 12cb48d

Browse files
authored
Add ability to see all items on a server if one is an administrator (#322)
1 parent 9b3b5be commit 12cb48d

File tree

6 files changed

+60
-13
lines changed

6 files changed

+60
-13
lines changed

extensions/package-vulnerability-scanner/main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
client = connect.Client()
88

99
@app.get("/api/content")
10-
async def search_content(query: str = None):
10+
async def search_content(show_all: bool = False):
11+
if show_all:
12+
return client.content.find()
1113
return client.me.content.find()
1214

1315
@app.get("/api/packages/{guid}")

extensions/package-vulnerability-scanner/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,6 @@
4646
"requiredFeatures": [
4747
"API Publishing"
4848
],
49-
"version": "2.0.2"
49+
"version": "3.0.2"
5050
}
5151
}

extensions/package-vulnerability-scanner/src/components/ContentList.vue

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
<script setup lang="ts">
2-
import { computed, ref } from "vue";
2+
import { computed, ref, watch } from "vue";
3+
import { storeToRefs } from "pinia";
34
45
import { usePackagesStore } from "../stores/packages";
56
import { useContentStore } from "../stores/content";
67
import { useScannerStore } from "../stores/scanner";
8+
import { useUserStore } from "../stores/user";
79
import type { User } from "../stores/user";
810
import StatusMessage from "./ui/StatusMessage.vue";
911
import SkeletonText from "./ui/SkeletonText.vue";
@@ -18,10 +20,22 @@ const props = defineProps<{
1820
user: User;
1921
}>();
2022
23+
const userStore = useUserStore();
24+
2125
const packagesStore = usePackagesStore();
2226
const contentStore = useContentStore();
2327
const scannerStore = useScannerStore();
2428
29+
// Use store's showAllContent to persist state across remounts
30+
const { showAllContent } = storeToRefs(contentStore);
31+
32+
// Watch for toggle changes and refetch content
33+
watch(showAllContent, async () => {
34+
packagesStore.clearAllPackages();
35+
await contentStore.fetchContentList(true);
36+
fetchPackagesInBatches();
37+
});
38+
2539
// Fetch packages in batches to avoid overwhelming the server
2640
async function fetchPackagesInBatches(batchSize = 3) {
2741
const contentToFetch = contentStore.contentList.filter(
@@ -152,6 +166,10 @@ const filteredContent = computed(() => {
152166
});
153167
154168
const userHeader = computed(() => {
169+
if (showAllContent.value) {
170+
return "All Content on Connect";
171+
}
172+
155173
let name;
156174
157175
if (props.user.first_name && props.user.last_name) {
@@ -166,7 +184,7 @@ const userHeader = computed(() => {
166184
name = props.user.username;
167185
}
168186
169-
return `${name}'s Connect Content`;
187+
return `${name}'s Content on Connect`;
170188
});
171189
</script>
172190

@@ -189,9 +207,25 @@ const userHeader = computed(() => {
189207
</div>
190208

191209
<div v-else class="space-y-4">
192-
<h2 class="text-xl font-semibold text-gray-800">
193-
{{ userHeader }}
194-
</h2>
210+
<div class="flex items-center justify-between">
211+
<h2 class="text-xl font-semibold text-gray-800">
212+
{{ userHeader }}
213+
</h2>
214+
215+
<label v-if="userStore.isAdmin" class="flex items-center gap-2 cursor-pointer">
216+
<span class="text-sm text-gray-600">show:</span>
217+
<span class="text-sm" :class="showAllContent ? 'text-gray-600' : 'text-gray-800 font-medium'">only mine</span>
218+
<div class="relative">
219+
<input
220+
type="checkbox"
221+
v-model="showAllContent"
222+
class="sr-only peer"
223+
/>
224+
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
225+
</div>
226+
<span class="text-sm" :class="showAllContent ? 'text-gray-800 font-medium' : 'text-gray-600'">all</span>
227+
</label>
228+
</div>
195229

196230
<p class="text-gray-600">
197231
Found {{ scannerStore.content.length }} content items with

extensions/package-vulnerability-scanner/src/stores/content.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,22 @@ export const useContentStore = defineStore("content", () => {
2020
const contentList = ref<ContentListItem[]>([]);
2121
const isLoading = ref(false);
2222
const error = ref<Error | null>(null);
23+
const showAllContent = ref(false);
2324

24-
// Track if content has been loaded
25+
// Track if content has been loaded for the current mode
2526
const isContentLoaded = ref(false);
2627

2728
// Fetch all available content items
28-
async function fetchContentList() {
29-
// Skip if content is already loaded
30-
if (isContentLoaded.value && contentList.value.length > 0) return;
29+
async function fetchContentList(forceRefresh: boolean = false) {
30+
// Skip if content is already loaded for this mode (unless forcing refresh)
31+
if (!forceRefresh && isContentLoaded.value && contentList.value.length > 0) return;
3132

3233
isLoading.value = true;
3334
error.value = null;
3435

3536
try {
36-
const response = await fetch("api/content");
37+
const url = showAllContent.value ? "api/content?show_all=true" : "api/content";
38+
const response = await fetch(url);
3739

3840
if (!response.ok) {
3941
throw new Error(`HTTP error! Status: ${response.status}`);
@@ -57,6 +59,7 @@ export const useContentStore = defineStore("content", () => {
5759
isLoading,
5860
error,
5961
isContentLoaded,
62+
showAllContent,
6063

6164
// Actions
6265
fetchContentList,

extensions/package-vulnerability-scanner/src/stores/packages.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ export const usePackagesStore = defineStore("packages", () => {
7979
};
8080
}
8181

82+
function clearAllPackages() {
83+
contentItems.value = {};
84+
}
85+
8286
return {
8387
// State
8488
contentItems,
@@ -88,5 +92,6 @@ export const usePackagesStore = defineStore("packages", () => {
8892
// Actions
8993
fetchPackagesForContent,
9094
setPackagesForContent,
95+
clearAllPackages,
9196
};
9297
});

extensions/package-vulnerability-scanner/src/stores/user.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ref } from "vue";
1+
import { ref, computed } from "vue";
22
import { defineStore } from "pinia";
33

44
export interface User {
@@ -18,6 +18,8 @@ export interface User {
1818
export const useUserStore = defineStore("user", () => {
1919
const user = ref<User>();
2020

21+
const isAdmin = computed(() => user.value?.user_role === "administrator");
22+
2123
async function fetchCurrentUser() {
2224
const response = await fetch("api/user");
2325
const data = await response.json();
@@ -27,6 +29,7 @@ export const useUserStore = defineStore("user", () => {
2729

2830
return {
2931
user,
32+
isAdmin,
3033

3134
fetchCurrentUser,
3235
};

0 commit comments

Comments
 (0)