Skip to content

Commit

Permalink
#129 : add programming language filter
Browse files Browse the repository at this point in the history
  • Loading branch information
guillermau committed Jan 17, 2025
1 parent 08a6c34 commit 7da1b54
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 0 deletions.
140 changes: 140 additions & 0 deletions web/src/core/usecases/softwareCatalog/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const searchResults = (rootState: RootState) => rootState[name].searchResults;
const sort = (rootState: RootState) => rootState[name].sort;
const organization = (rootState: RootState) => rootState[name].organization;
const category = (rootState: RootState) => rootState[name].category;
const programmingLanguage = (rootState: RootState) => rootState[name].programmingLanguage;
const environment = (rootState: RootState) => rootState[name].environment;
const prerogatives = (rootState: RootState) => rootState[name].prerogatives;
const userEmail = (rootState: RootState) => rootState[name].userEmail;
Expand Down Expand Up @@ -54,6 +55,7 @@ const softwares = createSelector(
sort,
organization,
category,
programmingLanguage,
environment,
prerogatives,
(
Expand All @@ -62,6 +64,7 @@ const softwares = createSelector(
sort,
organization,
category,
programmingLanguage,
environment,
prerogatives
) => {
Expand Down Expand Up @@ -98,6 +101,13 @@ const softwares = createSelector(
});
}

if (programmingLanguage) {
tmpSoftwares = filterByProgrammingLanguage({
"softwares": tmpSoftwares,
"programmingLanguage": programmingLanguage
});
}

if (environment !== undefined) {
tmpSoftwares = filterByEnvironnement({
"softwares": tmpSoftwares,
Expand Down Expand Up @@ -197,12 +207,14 @@ const organizationOptions = createSelector(
internalSoftwares,
searchResults,
category,
programmingLanguage,
environment,
prerogatives,
(
internalSoftwares,
searchResults,
category,
programmingLanguage,
environment,
prerogatives
): { organization: string; softwareCount: number }[] => {
Expand Down Expand Up @@ -232,6 +244,13 @@ const organizationOptions = createSelector(
});
}

if (programmingLanguage) {
tmpSoftwares = filterByProgrammingLanguage({
"softwares": tmpSoftwares,
"programmingLanguage": programmingLanguage
});
}

if (environment !== undefined) {
tmpSoftwares = filterByEnvironnement({
"softwares": tmpSoftwares,
Expand Down Expand Up @@ -273,12 +292,14 @@ const categoryOptions = createSelector(
internalSoftwares,
searchResults,
organization,
programmingLanguage,
environment,
prerogatives,
(
internalSoftwares,
searchResults,
organization,
programmingLanguage,
environment,
prerogatives
): { category: string; softwareCount: number }[] => {
Expand Down Expand Up @@ -308,6 +329,13 @@ const categoryOptions = createSelector(
});
}

if (programmingLanguage) {
tmpSoftwares = filterByProgrammingLanguage({
"softwares": tmpSoftwares,
"programmingLanguage": programmingLanguage
});
}

if (environment !== undefined) {
tmpSoftwares = filterByEnvironnement({
"softwares": tmpSoftwares,
Expand Down Expand Up @@ -343,12 +371,14 @@ const environmentOptions = createSelector(
searchResults,
organization,
category,
programmingLanguage,
prerogatives,
(
internalSoftwares,
searchResults,
organization,
category,
programmingLanguage,
prerogatives
): { environment: State.Environment; softwareCount: number }[] => {
const softwareCountInCurrentFilterByEnvironment = new Map(
Expand Down Expand Up @@ -395,6 +425,13 @@ const environmentOptions = createSelector(
});
}

if (programmingLanguage) {
tmpSoftwares = filterByProgrammingLanguage({
"softwares": tmpSoftwares,
"programmingLanguage": programmingLanguage
});
}

if (category !== undefined) {
tmpSoftwares = filterByCategory({
"softwares": tmpSoftwares,
Expand Down Expand Up @@ -450,13 +487,15 @@ const prerogativeFilterOptions = createSelector(
searchResults,
organization,
category,
programmingLanguage,
environment,
prerogatives,
(
internalSoftwares,
searchResults,
organization,
category,
programmingLanguage,
environment,
prerogatives
): { prerogative: State.Prerogative; softwareCount: number }[] => {
Expand Down Expand Up @@ -501,6 +540,13 @@ const prerogativeFilterOptions = createSelector(
});
}

if (programmingLanguage) {
tmpSoftwares = filterByProgrammingLanguage({
"softwares": tmpSoftwares,
"programmingLanguage": programmingLanguage
});
}

if (environment !== undefined) {
tmpSoftwares = filterByEnvironnement({
"softwares": tmpSoftwares,
Expand Down Expand Up @@ -565,26 +611,110 @@ const prerogativeFilterOptions = createSelector(
}
);

const programmingLanguageOptions = createSelector(
internalSoftwares,
searchResults,
organization,
category,
environment,
prerogatives,
(
internalSoftwares,
searchResults,
organization,
category,
environment,
prerogatives
): { programmingLanguage: string; softwareCount: number }[] => {
const softwareCountInCurrentFilterByProgrammingLanguage = Object.fromEntries(
Array.from(
new Set(
internalSoftwares
.map(({ programmingLanguages }) => programmingLanguages)
.reduce((prev, curr) => [...prev, ...curr], [])
)
).map(category => [category, 0])
);

let tmpSoftwares = internalSoftwares;

if (searchResults !== undefined) {
tmpSoftwares = filterAndSortBySearch({
"softwares": tmpSoftwares,
searchResults
}).map(({ software }) => software);
}

if (organization !== undefined) {
tmpSoftwares = filterByOrganization({
"softwares": tmpSoftwares,
"organization": organization
});
}

if (category !== undefined) {
tmpSoftwares = filterByCategory({
"softwares": tmpSoftwares,
"category": category
});
}

if (environment !== undefined) {
tmpSoftwares = filterByEnvironnement({
"softwares": tmpSoftwares,
"environment": environment
});
}

for (const prerogative of prerogatives) {
tmpSoftwares = filterByPrerogative({
"softwares": tmpSoftwares,
prerogative
});
}

tmpSoftwares.forEach(({ programmingLanguages }) =>
programmingLanguages.forEach(
programmingLanguages =>
softwareCountInCurrentFilterByProgrammingLanguage[
programmingLanguages
]++
)
);

return Object.entries(softwareCountInCurrentFilterByProgrammingLanguage)
.map(([programmingLanguage, softwareCount]) => ({
programmingLanguage,
softwareCount
}))
.filter(({ softwareCount }) => softwareCount !== 0)
.sort((a, b) => b.softwareCount - a.softwareCount);
}
);

const main = createSelector(
softwares,
sortOptions,
organizationOptions,
categoryOptions,
environmentOptions,
programmingLanguageOptions,
prerogativeFilterOptions,
(
softwares,
sortOptions,
organizationOptions,
categoryOptions,
environmentOptions,
programmingLanguageOptions,
prerogativeFilterOptions
) => ({
softwares,
sortOptions,
organizationOptions,
categoryOptions,
environmentOptions,
programmingLanguageOptions,
prerogativeFilterOptions
})
);
Expand Down Expand Up @@ -640,6 +770,16 @@ function filterByCategory(params: {
);
}

function filterByProgrammingLanguage(params: {
softwares: State.Software.Internal[];
programmingLanguage: string;
}) {
const { softwares, programmingLanguage } = params;
return softwares.filter(({ programmingLanguages }) =>
programmingLanguages.includes(programmingLanguage)
);
}

function filterByEnvironnement(params: {
softwares: State.Software.Internal[];
environment: State.Environment;
Expand Down
3 changes: 3 additions & 0 deletions web/src/core/usecases/softwareCatalog/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type State = {
organization: string | undefined;
/** E.g: JavaScript */
category: string | undefined;
programmingLanguage: string | undefined;
environment: State.Environment | undefined;
prerogatives: State.Prerogative[];
sortBackup: State.Sort;
Expand Down Expand Up @@ -159,6 +160,7 @@ export const { reducer, actions } = createUsecaseActions({
"sortBackup": defaultSort,
"organization": undefined,
"category": undefined,
"programmingLanguage": undefined,
"environment": undefined,
"prerogatives": [],
"referentCount": undefined,
Expand Down Expand Up @@ -206,6 +208,7 @@ export const { reducer, actions } = createUsecaseActions({
state.prerogatives = [];
state.organization = undefined;
state.category = undefined;
state.programmingLanguage = undefined;
state.environment = undefined;
state.prerogatives = [];
}
Expand Down
1 change: 1 addition & 0 deletions web/src/ui/i18n/sill_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
"categoriesLabel": "Categories",
"environnement label": "Usage environnement ",
"prerogativesLabel": "Prerogatives",
"programmingLanguages label": "Coded in",
"filters": "Filters",
"isInstallableOnUserComputer": "Can be installed on user terminal",
"isAvailableAsMobileApp": "Mobile application available",
Expand Down
1 change: 1 addition & 0 deletions web/src/ui/i18n/sill_fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@
"categoriesLabel": "Catégories",
"environnement label": "Environnement d'utilisation",
"prerogativesLabel": "Prérogatives",
"programmingLanguages label": "Language de programmation",
"filters": "Filtres",
"isInstallableOnUserComputer": "Installable sur un poste agent",
"isAvailableAsMobileApp": "Application mobile disponible",
Expand Down
14 changes: 14 additions & 0 deletions web/src/ui/pages/softwareCatalog/SoftwareCatalog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default function SoftwareCatalog(props: Props) {
environmentOptions,
organizationOptions,
prerogativeFilterOptions,
programmingLanguageOptions,
softwares,
sortOptions
} = useCoreState("softwareCatalog", "main");
Expand Down Expand Up @@ -113,6 +114,16 @@ export default function SoftwareCatalog(props: Props) {
});
}, [route.params.category]);

useEffect(() => {
softwareCatalog.updateFilter({
"key": "programmingLanguage",
"value":
route.params.programmingLanguage !== undefined
? route.params.programmingLanguage
: undefined
});
}, [route.params.programmingLanguage]);

useEffect(() => {
softwareCatalog.updateFilter({
"key": "environment",
Expand Down Expand Up @@ -163,6 +174,9 @@ export default function SoftwareCatalog(props: Props) {
categoryOptions={categoryOptions}
category={route.params.category}
onCategoryChange={category => startTransition(() => updateRouteParams({ category }).replace())}
programmingLanguageOptions={programmingLanguageOptions}
programmingLanguage={route.params.programmingLanguage}
onProgrammingLanguageChange={programmingLanguage => startTransition(() => updateRouteParams({ programmingLanguage }).replace())}
environmentOptions={environmentOptions}
environment={route.params.environment}
onEnvironmentChange={environment => startTransition(() => updateRouteParams({ environment }).replace())}
Expand Down
13 changes: 13 additions & 0 deletions web/src/ui/pages/softwareCatalog/SoftwareCatalogControlled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ export type Props = {
category: string | undefined;
onCategoryChange: (category: string | undefined) => void;

programmingLanguageOptions: {
programmingLanguage: string;
softwareCount: number;
}[];
programmingLanguage: string | undefined;
onProgrammingLanguageChange: (programmingLanguage: string | undefined) => void;

environmentOptions: {
environment: SoftwareCatalogState.Environment;
softwareCount: number;
Expand Down Expand Up @@ -81,6 +88,9 @@ export function SoftwareCatalogControlled(props: Props) {
prerogativesOptions,
prerogatives,
onPrerogativesChange,
programmingLanguageOptions,
programmingLanguage,
onProgrammingLanguageChange,
...rest
} = props;

Expand All @@ -106,6 +116,9 @@ export function SoftwareCatalogControlled(props: Props) {
prerogativesOptions={prerogativesOptions}
prerogatives={prerogatives}
onPrerogativesChange={onPrerogativesChange}
programmingLanguage={programmingLanguage}
programmingLanguageOptions={programmingLanguageOptions}
onProgrammingLanguageChange={onProgrammingLanguageChange}
/>
<div>
<div className={classes.header}>
Expand Down
Loading

0 comments on commit 7da1b54

Please sign in to comment.