Skip to content

Commit 2e9e739

Browse files
authored
fix: storing of include collaborator toggle (#723)
Signed-off-by: Efren Lim <[email protected]>
1 parent 58d116b commit 2e9e739

File tree

3 files changed

+99
-76
lines changed

3 files changed

+99
-76
lines changed
Lines changed: 83 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,131 @@
11
// Copyright (c) 2025 The Linux Foundation and each contributor.
22
// SPDX-License-Identifier: MIT
3-
import { defineStore } from 'pinia';
4-
import { ref, computed } from 'vue';
5-
import { useRoute } from 'nuxt/app';
6-
import { DateTime } from 'luxon';
3+
import { defineStore } from 'pinia'
4+
import { ref, computed } from 'vue'
5+
import { useRoute } from 'nuxt/app'
6+
import { DateTime } from 'luxon'
77
import {
88
dateOptKeys,
99
lfxProjectDateOptions,
10-
} from '~/components/modules/project/config/date-options';
11-
import type {Project, ProjectRepository, ProjectRepositoryGroup} from '~~/types/project';
12-
import { Granularity } from '~~/types/shared/granularity';
13-
import { useQueryParam } from '~/components/shared/utils/query-param';
10+
} from '~/components/modules/project/config/date-options'
11+
import type { Project, ProjectRepository, ProjectRepositoryGroup } from '~~/types/project'
12+
import { Granularity } from '~~/types/shared/granularity'
13+
import { useQueryParam } from '~/components/shared/utils/query-param'
1414
import {
1515
processProjectParams,
16-
projectParamsSetter
17-
} from '~/components/modules/project/services/project.query.service';
16+
projectParamsSetter,
17+
} from '~/components/modules/project/services/project.query.service'
1818

1919
const calculateGranularity = (start: string | null, end: string | null): string[] => {
2020
// Return weekly if either date is null
2121
if (!start || !end) {
22-
return [Granularity.WEEKLY];
22+
return [Granularity.WEEKLY]
2323
}
2424

25-
const startDate = DateTime.fromISO(start);
26-
const endDate = DateTime.fromISO(end);
27-
const diffInDays = Math.ceil(endDate.diff(startDate, 'days').days);
25+
const startDate = DateTime.fromISO(start)
26+
const endDate = DateTime.fromISO(end)
27+
const diffInDays = Math.ceil(endDate.diff(startDate, 'days').days)
2828

2929
// TODO: verify with backend first if hourly granularity is doable
3030
switch (true) {
3131
case diffInDays <= 30:
32-
return [Granularity.DAILY];
32+
return [Granularity.DAILY]
3333
case diffInDays <= 90:
34-
return [Granularity.WEEKLY];
34+
return [Granularity.WEEKLY]
3535
case diffInDays <= 365:
36-
return [Granularity.WEEKLY, Granularity.MONTHLY];
36+
return [Granularity.WEEKLY, Granularity.MONTHLY]
3737
case diffInDays <= 730:
38-
return [Granularity.MONTHLY, Granularity.YEARLY];
38+
return [Granularity.MONTHLY, Granularity.YEARLY]
3939
default:
40-
return [Granularity.YEARLY];
40+
return [Granularity.YEARLY]
4141
}
42-
};
42+
}
4343

44-
export const defaultTimeRangeKey = dateOptKeys.past365days;
44+
export const defaultTimeRangeKey = dateOptKeys.past365days
4545
export const defaultDateOption = lfxProjectDateOptions.find(
46-
(option) => option.key === defaultTimeRangeKey
47-
);
46+
(option) => option.key === defaultTimeRangeKey,
47+
)
4848

4949
export const useProjectStore = defineStore('project', () => {
50-
const route = useRoute();
50+
const route = useRoute()
5151

52-
const { queryParams } = useQueryParam(processProjectParams, projectParamsSetter);
53-
const { timeRange, start, end } = queryParams.value;
52+
const { queryParams } = useQueryParam(processProjectParams, projectParamsSetter)
53+
const { timeRange, start, end } = queryParams.value
5454

55-
const selectedTimeRangeKey = ref<string>(timeRange!);
56-
const startDate = ref<string | null>(start || null);
57-
const endDate = ref<string | null>(end || null);
58-
const isProjectLoading = ref(false);
59-
const project = ref<Project | null>(null);
55+
const selectedTimeRangeKey = ref<string>(timeRange!)
56+
const startDate = ref<string | null>(start || null)
57+
const endDate = ref<string | null>(end || null)
58+
const isProjectLoading = ref(false)
59+
const project = ref<Project | null>(null)
60+
const collaborationSet = ref<string[]>([]) // stores the widget names that have includeCollaborations set to true
6061

6162
// List of all project repositories
62-
const projectRepos = computed<ProjectRepository[]>(() => project.value?.repositories || []);
63+
const projectRepos = computed<ProjectRepository[]>(() => project.value?.repositories || [])
6364

6465
// List of all project repository groups
65-
const projectRepositoryGroups = computed<ProjectRepositoryGroup[]>(() => project.value?.repositoryGroups || []);
66-
// List of archived repositories
67-
const archivedRepos = computed<string[]>(() => project.value?.archivedRepositories || []);
68-
// List of excluded repositories
69-
const excludedRepos = computed<string[]>(() => project.value?.excludedRepositories || []);
70-
71-
// Selected repositories from URL param 'repos' or single repo from route param 'name'
72-
const selectedRepoSlugs = computed(() => route.params.name
66+
const projectRepositoryGroups = computed<ProjectRepositoryGroup[]>(
67+
() => project.value?.repositoryGroups || [],
68+
)
69+
// List of archived repositories
70+
const archivedRepos = computed<string[]>(() => project.value?.archivedRepositories || [])
71+
// List of excluded repositories
72+
const excludedRepos = computed<string[]>(() => project.value?.excludedRepositories || [])
73+
74+
// Selected repositories from URL param 'repos' or single repo from route param 'name'
75+
const selectedRepoSlugs = computed(() =>
76+
route.params.name
7377
? [route.params.name as string]
74-
: (route.query.repos as string)?.split(',') || []);
78+
: (route.query.repos as string)?.split(',') || [],
79+
)
7580

7681
// Selected repository Group
7782
const selectedRepositoryGroup = computed<ProjectRepositoryGroup | null>(() => {
78-
const groupSlug = route.params.groupSlug as string | undefined || route.query.repositoryGroup;
83+
const groupSlug = (route.params.groupSlug as string | undefined) || route.query.repositoryGroup
7984
if (!groupSlug || !projectRepositoryGroups.value.length) {
80-
return null;
85+
return null
8186
}
82-
return projectRepositoryGroups.value.find((group) => group.slug === groupSlug) || null;
87+
return projectRepositoryGroups.value.find((group) => group.slug === groupSlug) || null
8388
})
8489

8590
// If a repository group is selected, filter repos by that group, otherwise use selectedRepoSlugs
8691
const selectedRepositories = computed<ProjectRepository[]>(() => {
8792
if (selectedRepositoryGroup.value) {
88-
return projectRepos.value.filter((repo) => selectedRepositoryGroup.value?.repositories.includes(repo.url));
93+
return projectRepos.value.filter((repo) =>
94+
selectedRepositoryGroup.value?.repositories.includes(repo.url),
95+
)
8996
}
90-
return projectRepos.value.filter((repo: ProjectRepository) => selectedRepoSlugs.value.includes(repo.slug) ||
91-
route.params.name === repo.slug)
92-
});
97+
return projectRepos.value.filter(
98+
(repo: ProjectRepository) =>
99+
selectedRepoSlugs.value.includes(repo.slug) || route.params.name === repo.slug,
100+
)
101+
})
93102

94-
// Selected repository URLs
95-
const selectedReposValues = computed<string[]>(() => selectedRepositories
96-
.value.map((repo: ProjectRepository) => repo.url));
103+
// Selected repository URLs
104+
const selectedReposValues = computed<string[]>(() =>
105+
selectedRepositories.value.map((repo: ProjectRepository) => repo.url),
106+
)
97107

98-
// Determine granularity options based on selected date range
99-
const customRangeGranularity = computed<string[]>(() => (startDate.value === null || endDate.value === null
108+
// Determine granularity options based on selected date range
109+
const customRangeGranularity = computed<string[]>(() =>
110+
startDate.value === null || endDate.value === null
100111
? [Granularity.WEEKLY]
101-
: calculateGranularity(startDate.value, endDate.value)));
112+
: calculateGranularity(startDate.value, endDate.value),
113+
)
102114

103115
// If all repos are archived or all selected repos are archived
104-
const allArchived = computed(() =>
105-
archivedRepos.value.length === projectRepos.value.length ||
106-
(
107-
!!selectedReposValues.value.length
108-
&& selectedReposValues.value.every((repo) => archivedRepos.value.includes(repo))
109-
)
110-
);
111-
112-
// If any selected repo is archived
113-
const hasSelectedArchivedRepos = computed(() =>
114-
!!archivedRepos.value.length && !selectedReposValues.value.length
115-
|| selectedReposValues.value.some((repo) => archivedRepos.value.includes(repo))
116-
);
116+
const allArchived = computed(
117+
() =>
118+
archivedRepos.value.length === projectRepos.value.length ||
119+
(!!selectedReposValues.value.length &&
120+
selectedReposValues.value.every((repo) => archivedRepos.value.includes(repo))),
121+
)
122+
123+
// If any selected repo is archived
124+
const hasSelectedArchivedRepos = computed(
125+
() =>
126+
(!!archivedRepos.value.length && !selectedReposValues.value.length) ||
127+
selectedReposValues.value.some((repo) => archivedRepos.value.includes(repo)),
128+
)
117129

118130
return {
119131
selectedTimeRangeKey,
@@ -131,6 +143,7 @@ export const useProjectStore = defineStore('project', () => {
131143
selectedRepositories,
132144
selectedReposValues,
133145
allArchived,
134-
hasSelectedArchivedRepos
135-
};
136-
});
146+
hasSelectedArchivedRepos,
147+
collaborationSet,
148+
}
149+
})

frontend/app/components/modules/widget/components/shared/widget.vue

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ SPDX-License-Identifier: MIT
7676
</template>
7777

7878
<script lang="ts" setup>
79-
import {computed, ref} from "vue";
79+
import {computed, ref, watch} from "vue";
8080
import {storeToRefs} from "pinia";
8181
import LfxCard from "~/components/uikit/card/card.vue";
8282
import type {Widget} from "~/components/modules/widget/types/widget";
@@ -101,20 +101,29 @@ const props = defineProps<{
101101
const {sanitize} = useSanitize();
102102
103103
const config = computed<WidgetConfig>(() => lfxWidgets[props.name]);
104+
const { project, collaborationSet } = storeToRefs(useProjectStore());
104105
105106
const model = ref(config.value.defaultValue || {});
106107
const includeCollaborations = computed({
107-
get: () => model.value.includeCollaborations || false,
108+
get: () => collaborationSet.value.includes(props.name),
108109
set: (value) => {
109-
model.value.includeCollaborations = value;
110+
if (value) {
111+
if (!collaborationSet.value.includes(props.name)) {
112+
collaborationSet.value.push(props.name);
113+
}
114+
} else {
115+
collaborationSet.value = collaborationSet.value.filter((name) => name !== props.name);
116+
}
110117
}
111118
});
112119
const isMenuOpen = ref(false);
113120
114-
const { project } = storeToRefs(useProjectStore());
115-
116121
const benchmarkScore = computed<BenchmarkScoreData | undefined>(() => props
117122
.benchmarkScores?.[config.value.key as keyof HealthScoreResults] as BenchmarkScoreData);
123+
124+
watch(includeCollaborations, (value) => {
125+
model.value.includeCollaborations = value;
126+
}, { immediate: true });
118127
</script>
119128

120129
<script lang="ts">

frontend/app/pages/project/[slug].vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import {
4848
const route = useRoute();
4949
const {slug} = route.params;
5050
const {
51-
project, isProjectLoading, selectedTimeRangeKey, startDate, endDate
51+
project, isProjectLoading, selectedTimeRangeKey, startDate, endDate, collaborationSet
5252
} = storeToRefs(useProjectStore());
5353
5454
const { queryParams } = useQueryParam(processProjectParams, projectParamsSetter);
@@ -100,6 +100,7 @@ watch(() => data.value, (value) => {
100100
}
101101
102102
project.value = value;
103+
collaborationSet.value = [];
103104
}
104105
}, { immediate: true });
105106

0 commit comments

Comments
 (0)