Skip to content

Commit 714bff8

Browse files
authored
Merge branch 'main' into feat/community-voice-ui
2 parents 9858b7a + f458e2f commit 714bff8

File tree

4 files changed

+191
-166
lines changed

4 files changed

+191
-166
lines changed

frontend/app/components/modules/project/views/security.vue

Lines changed: 179 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -3,190 +3,205 @@ Copyright (c) 2025 The Linux Foundation and each contributor.
33
SPDX-License-Identifier: MIT
44
-->
55
<template>
6-
<div class="container pt-4 md:pt-12">
7-
<lfx-card class="pt-4 sm:pt-6">
8-
<div class="px-4 sm:px-6 flex justify-between items-start pb-4 sm:pb-5 flex-wrap gap-2">
9-
<div class="w-full sm:w-1/2 md:w-1/2">
10-
<!-- Title -->
11-
<div class="flex flex-col-reverse sm:flex-row items-start sm:items-center gap-2 sm:gap-4 pb-2">
12-
<h1 class="text-heading-3 font-secondary font-bold">Controls assessment</h1>
13-
<lfx-tag
14-
variation="warning"
15-
size="small"
16-
>
17-
Alpha version
18-
</lfx-tag>
6+
<div class="container pt-4 md:pt-12 flex md:gap-10 gap-5 md:flex-row flex-col-reverse">
7+
<div class="md:w-3/4 w-full">
8+
<lfx-card class="pt-4 sm:pt-6">
9+
<div class="px-4 sm:px-6 flex justify-between items-start pb-4 sm:pb-5 flex-wrap gap-2">
10+
<div class="w-full sm:w-1/2 md:w-1/2">
11+
<!-- Title -->
12+
<div class="flex flex-col-reverse sm:flex-row items-start sm:items-center gap-2 sm:gap-4 pb-2">
13+
<h1 class="text-heading-3 font-secondary font-bold">Controls assessment</h1>
14+
<lfx-tag
15+
variation="warning"
16+
size="small"
17+
>
18+
Alpha version
19+
</lfx-tag>
20+
</div>
21+
22+
<!-- Description -->
23+
<p class="text-xs text-neutral-500">
24+
Process of assessing a project's practices, policies, and technical measures against a set of predefined
25+
standards to determine its security posture, reliability, and maturity.
26+
<a
27+
:href="links.securityScore"
28+
class="text-brand-500"
29+
target="_blank"
30+
rel="noopener noreferrer"
31+
>Learn more</a
32+
>
33+
</p>
1934
</div>
2035

21-
<!-- Description -->
22-
<p class="text-xs text-neutral-500">
23-
Process of assessing a project's practices, policies, and technical measures against a set of predefined
24-
standards to determine its security posture, reliability, and maturity.
25-
<a
26-
:href="links.securityScore"
27-
class="text-brand-500"
28-
target="_blank"
29-
rel="noopener noreferrer"
30-
>Learn more</a
31-
>
32-
</p>
36+
<a
37+
href="https://revanite.io"
38+
target="_blank"
39+
rel="noopener noreferrer"
40+
class="flex items-center justify-center px-2.5 py-1 border border-neutral-200 rounded-full"
41+
>
42+
<p class="text-neutral-500 text-xs mr-2">Powered by:</p>
43+
<img
44+
src="~/assets/images/revanite.svg"
45+
alt="Revanite.io Logo"
46+
class="h-5 w-5.5 mr-1.5"
47+
/>
48+
<p class="text-neutral-900 text-xs">Revanite.io</p>
49+
</a>
50+
<!-- TODO: Enable when backend is ready -->
51+
<!-- <lfx-button-->
52+
<!-- type="tertiary"-->
53+
<!-- size="small"-->
54+
<!-- button-style="pill"-->
55+
<!-- class="whitespace-nowrap"-->
56+
<!-- >-->
57+
<!-- <lfx-icon name="arrows-rotate-reverse" />-->
58+
<!-- Update results-->
59+
<!-- </lfx-button>-->
3360
</div>
3461

35-
<a
36-
href="https://revanite.io"
37-
target="_blank"
38-
rel="noopener noreferrer"
39-
class="flex items-center justify-center px-2.5 py-1 border border-neutral-200 rounded-full"
62+
<!-- Disclaimer for aggregated view -->
63+
<div
64+
v-if="!isRepository"
65+
class="px-6 py-3 bg-neutral-50 border-y border-neutral-100 flex items-center gap-1.5 rounded-b-lg"
4066
>
41-
<p class="text-neutral-500 text-xs mr-2">Powered by:</p>
42-
<img
43-
src="~/assets/images/revanite.svg"
44-
alt="Revanite.io Logo"
45-
class="h-5 w-5.5 mr-1.5"
67+
<lfx-icon
68+
name="info-circle"
69+
:size="14"
70+
class="text-neutral-500"
4671
/>
47-
<p class="text-neutral-900 text-xs">Revanite.io</p>
48-
</a>
49-
<!-- TODO: Enable when backend is ready -->
50-
<!-- <lfx-button-->
51-
<!-- type="tertiary"-->
52-
<!-- size="small"-->
53-
<!-- button-style="pill"-->
54-
<!-- class="whitespace-nowrap"-->
55-
<!-- >-->
56-
<!-- <lfx-icon name="arrows-rotate-reverse" />-->
57-
<!-- Update results-->
58-
<!-- </lfx-button>-->
59-
</div>
72+
<p class="text-body-2 text-neutral-500 font-semibold">
73+
You’re viewing an aggregated score and controls assessment for the entire project. For a detailed analysis,
74+
choose a specific repository.
75+
</p>
76+
</div>
77+
<div class="px-4 sm:px-6 pt-1">
78+
<!-- Show spinner when loading -->
79+
<div
80+
v-if="isFetching"
81+
class="pt-5 border-t border-neutral-100"
82+
>
83+
<div class="flex flex-col items-center justify-center py-20">
84+
<lfx-spinner
85+
:size="40"
86+
type="light"
87+
class="text-neutral-300"
88+
/>
89+
<p class="text-neutral-500 text-center text-body-1 pt-5">Loading controls assessment...</p>
90+
</div>
91+
</div>
6092

61-
<!-- Disclaimer for aggregated view -->
62-
<div
63-
v-if="!isRepository"
64-
class="px-6 py-3 bg-neutral-50 border-y border-neutral-100 flex items-center gap-1.5 rounded-b-lg"
65-
>
66-
<lfx-icon
67-
name="info-circle"
68-
:size="14"
69-
class="text-neutral-500"
70-
/>
71-
<p class="text-body-2 text-neutral-500 font-semibold">
72-
You’re viewing an aggregated score and controls assessment for the entire project. For a detailed analysis,
73-
choose a specific repository.
74-
</p>
75-
</div>
76-
<div class="px-4 sm:px-6 pt-1">
77-
<!-- Show spinner when loading -->
78-
<div
79-
v-if="isFetching"
80-
class="pt-5 border-t border-neutral-100"
81-
>
82-
<div class="flex flex-col items-center justify-center py-20">
83-
<lfx-spinner
84-
:size="40"
85-
type="light"
86-
class="text-neutral-300"
87-
/>
88-
<p class="text-neutral-500 text-center text-body-1 pt-5">Loading controls assessment...</p>
93+
<!-- show if all repos are archived -->
94+
<lfx-empty-state
95+
v-else-if="allArchived"
96+
icon="archive"
97+
:title="pluralize('Archived Repository', archivedRepos.length)"
98+
description="Archived repositories are excluded from Health Score and Security & Best practices.
99+
You can still access historical data of Contributors, Popularity, or Development metrics."
100+
/>
101+
102+
<!-- Show if no data available -->
103+
<div
104+
v-else-if="data?.length === 0 || error"
105+
class="pt-5 border-t border-neutral-100"
106+
>
107+
<div class="flex flex-col items-center justify-center py-20">
108+
<lfx-icon
109+
name="eyes"
110+
class="text-neutral-300"
111+
:size="40"
112+
/>
113+
<p class="text-neutral-500 text-center text-body-1 pt-5">
114+
No data available to perform controls assessment
115+
</p>
116+
</div>
117+
</div>
118+
<div v-else>
119+
<!-- Display checks -->
120+
<lfx-accordion v-model="accordion">
121+
<lfx-project-security-evaluation-section
122+
v-for="(checks, title) in groupedData"
123+
:key="title"
124+
:name="title"
125+
:checks="checks"
126+
:tooltip="isRepository ? 'Category success rate' : 'Average category success rate of all repositories'"
127+
>
128+
<template v-if="isRepository">
129+
<template
130+
v-for="check in checks"
131+
:key="check.controlId"
132+
>
133+
<lfx-project-security-evaluation-assesment
134+
v-for="assessment in check.assessments"
135+
:key="assessment.requirementId"
136+
:assessment="assessment"
137+
/>
138+
</template>
139+
</template>
140+
<template v-else>
141+
<lfx-project-security-paginated-eval-repos :group-checks="groupChecksByRepository(checks || [])" />
142+
</template>
143+
</lfx-project-security-evaluation-section>
144+
</lfx-accordion>
89145
</div>
90146
</div>
147+
</lfx-card>
91148

92-
<!-- show if all repos are archived -->
93-
<lfx-empty-state
94-
v-else-if="allArchived"
95-
icon="archive"
96-
:title="pluralize('Archived Repository', archivedRepos.length)"
97-
description="Archived repositories are excluded from Health Score and Security & Best practices.
98-
You can still access historical data of Contributors, Popularity, or Development metrics."
149+
<div class="flex items-center justify-center mt-8">
150+
<lfx-repos-exclusion-footer
151+
v-if="hasSelectedArchivedRepos && !isFetching"
152+
page-content="security"
99153
/>
100-
101-
<!-- Show if no data available -->
154+
<!-- Generate YAML and Update buttons -->
102155
<div
103-
v-else-if="data?.length === 0 || error"
104-
class="pt-5 border-t border-neutral-100"
156+
v-if="!isFetching && data?.length && !allArchived"
157+
class="flex items-center gap-2 px-1.5"
105158
>
106-
<div class="flex flex-col items-center justify-center py-20">
159+
<p
160+
v-if="hasSelectedArchivedRepos && !isFetching"
161+
class="text-neutral-500 text-xs font-semibold"
162+
>
163+
164+
</p>
165+
</div>
166+
</div>
167+
</div>
168+
169+
<div class="md:w-1/4 w-full">
170+
<lfx-card
171+
class="p-5 bg-gradient-to-b from-brand-50 to-white to-30% flex flex-col justify-center items-start gap-5"
172+
>
173+
<div class="flex md:flex-col flex-row justify-center items-start gap-5">
174+
<div class="relative inline-block">
107175
<lfx-icon
108-
name="eyes"
109-
class="text-neutral-300"
110-
:size="40"
176+
name="file"
177+
:size="32"
178+
class="text-brand-500"
111179
/>
112-
<p class="text-neutral-500 text-center text-body-1 pt-5">
113-
No data available to perform controls assessment
180+
<div
181+
class="bg-brand-500 text-icon-label font-bold absolute bottom-0 w-[75%] py-0.5 text-white text-center ml-1"
182+
>
183+
YAML
184+
</div>
185+
</div>
186+
<div class="flex flex-col gap-2">
187+
<span class="text-sm font-semibold text-neutral-900">YAML security file</span>
188+
<p class="text-xs text-neutral-600">
189+
Generate a security metadata file to enable automated security assessments and provide clear contact
190+
information of your GitHub repository.
114191
</p>
115192
</div>
116193
</div>
117-
<div v-else>
118-
<!-- Display checks -->
119-
<lfx-accordion v-model="accordion">
120-
<lfx-project-security-evaluation-section
121-
v-for="(checks, title) in groupedData"
122-
:key="title"
123-
:name="title"
124-
:checks="checks"
125-
:tooltip="isRepository ? 'Category success rate' : 'Average category success rate of all repositories'"
126-
>
127-
<template v-if="isRepository">
128-
<template
129-
v-for="check in checks"
130-
:key="check.controlId"
131-
>
132-
<lfx-project-security-evaluation-assesment
133-
v-for="assessment in check.assessments"
134-
:key="assessment.requirementId"
135-
:assessment="assessment"
136-
/>
137-
</template>
138-
</template>
139-
<template v-else>
140-
<lfx-project-security-paginated-eval-repos :group-checks="groupChecksByRepository(checks || [])" />
141-
</template>
142-
</lfx-project-security-evaluation-section>
143-
</lfx-accordion>
144-
</div>
145-
</div>
146-
</lfx-card>
147194

148-
<div class="flex items-center justify-center mt-8">
149-
<lfx-repos-exclusion-footer
150-
v-if="hasSelectedArchivedRepos && !isFetching"
151-
page-content="security"
152-
/>
153-
<!-- Generate YAML and Update buttons -->
154-
<div
155-
v-if="!isFetching && data?.length && !allArchived"
156-
class="flex items-center gap-2 px-1.5"
157-
>
158-
<p
159-
v-if="hasSelectedArchivedRepos && !isFetching"
160-
class="text-neutral-500 text-xs font-semibold"
161-
>
162-
163-
</p>
164-
<lfx-tooltip
165-
v-if="!PROJECT_SECURITY_SERVICE.hasSecurityMdFile(data || [])"
166-
placement="top"
195+
<lfx-button
196+
type="tertiary"
197+
size="small"
198+
button-style="pill"
199+
class="flex justify-center w-full"
200+
@click="handleGenerateYamlClick"
167201
>
168-
<lfx-button
169-
type="transparent"
170-
size="small"
171-
button-style="pill"
172-
class="whitespace-nowrap !hidden lg:!flex"
173-
@click="handleGenerateYamlClick"
174-
>
175-
<lfx-icon name="file-shield" />
176-
Generate YAML file
177-
</lfx-button>
178-
179-
<template #content>
180-
<div class="flex flex-col gap-1 max-w-72">
181-
<div class="font-semibold text-white text-xs">YAML Security specifications file</div>
182-
<div class="text-neutral-300 text-xs">
183-
Generate a YAML security file, upload it to your repository, and ensure we can run all security
184-
assessments for your project.
185-
</div>
186-
</div>
187-
</template>
188-
</lfx-tooltip>
189-
</div>
202+
Generate YAML
203+
</lfx-button>
204+
</lfx-card>
190205
</div>
191206
</div>
192207
<lf-security-generate-yaml-modal
@@ -218,7 +233,6 @@ import LfxReposExclusionFooter from '~/components/shared/components/repos-exclus
218233
import LfxEmptyState from '~/components/shared/components/empty-state.vue';
219234
import LfxTag from '~/components/uikit/tag/tag.vue';
220235
import LfxButton from '~/components/uikit/button/button.vue';
221-
import LfxTooltip from '~/components/uikit/tooltip/tooltip.vue';
222236
import LfSecurityGenerateYamlModal from '~/components/modules/project/components/security/yaml/generate-yaml-modal.vue';
223237
import { SECURITY_API_SERVICE } from '~/components/modules/project/services/security.api.service';
224238
import { useQueryParam } from '~/components/shared/utils/query-param';

frontend/server/api/community/[slug].post.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,16 @@ export default defineEventHandler(async (event): Promise<boolean | Error> => {
1414
return createError({ statusCode: 422, statusMessage: 'Invalid request' });
1515
}
1616

17+
const data = { ...body.data };
18+
if (data.viewKeywords.length > 0 && !data.viewKeywords.includes(data.keyword)) {
19+
const commonKeywords = data.keywords.filter((kw) => data.viewKeywords.includes(kw));
20+
if (commonKeywords.length > 0) {
21+
data.keyword = commonKeywords[0];
22+
}
23+
}
24+
1725
await addDataToTinybirdDatasource('mentions', {
18-
...body.data,
26+
...data,
1927
projectSlug: slug,
2028
});
2129
return true;

0 commit comments

Comments
 (0)