PluginProbe
Extendify / 2.2.0
Extendify v2.2.0
3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 0.7.0 All 126 releases
extendify / src / Recommendations / selectors / plugin-search.js

plugin-search.js in Extendify 2.2.0, at src/Recommendations/selectors/plugin-search.js

85 lines 2.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 const { products = [] } = window.extSharedData;
2
3 export const selectIsLoading = (state) =>
4 state.isSearchPluginsLoading || state.isInstalledPluginsLoading;
5
6 export const selectIsError = (state) =>
7 state.isSearchPluginsError || state.isInstalledPluginsError;
8
9 export const selectAllRecommendations = (state) => {
10 const triggeredBySlug = new Map();
11 const { searchPlugins, installedPlugins, searchPluginsLimit } = state;
12 const activePlugins = installedPlugins.filter(
13 ({ status }) => status === 'active',
14 );
15 const limitedSearchPlugins = searchPlugins.slice(0, searchPluginsLimit);
16
17 // We filter out products that:
18 const recommendations = products
19 // 1. Are not enabled for this slot.
20 .filter((product) => product.slots.includes('plugin-search'))
21 // 2. Are not triggering a match in plugin search results.
22 .filter((product) =>
23 product.pluginSearchTriggerSlugs.some((triggerSlug) => {
24 // We only compare against the results up to the set limit.
25 const included = limitedSearchPlugins.includes(triggerSlug);
26 if (included) {
27 triggeredBySlug.set(product.slug, triggerSlug);
28 }
29 return included;
30 }),
31 )
32 // 3. Are plugins and are already installed.
33 .filter(
34 (product) =>
35 product.ctaType !== 'plugin' ||
36 !installedPlugins.find(({ slug }) => slug === product.ctaPluginSlug),
37 )
38 // 4. Are excluded because a specified plugin is already active.
39 .filter((product) =>
40 product.pluginExclusions.every(
41 (pluginExclusion) =>
42 !activePlugins.find(({ slug }) => slug === pluginExclusion),
43 ),
44 )
45 // 5. Are excluded because a plugin dependency is not installed.
46 .filter((product) =>
47 product.pluginDependencies.every((pluginDependency) =>
48 installedPlugins.find(({ slug }) => slug === pluginDependency),
49 ),
50 )
51 .filter(Boolean)
52 .map((product) => ({
53 ...product,
54 title: product.pluginSearchCustomTitle || product.title,
55 description: product.pluginSearchCustomDescription || product.description,
56 ctaContent: product.pluginSearchCustomCtaContent || product.ctaContent,
57 triggerContent: triggeredBySlug.get(product.slug),
58 triggerType: 'plugin-slug',
59 }))
60 // Sort recommendations based on the order of their trigger slugs in the search results.
61 .sort(
62 (a, b) =>
63 limitedSearchPlugins.indexOf(a.triggerContent) -
64 limitedSearchPlugins.indexOf(b.triggerContent),
65 );
66
67 return recommendations;
68 };
69
70 export const selectRecommendations = (state) => {
71 const recommendations = selectAllRecommendations(state);
72 return recommendations.slice(0, state.recommendationsLimit);
73 };
74
75 export const selectSearchPlugins = (state) =>
76 state.searchPlugins.slice(0, state.searchPluginsLimit);
77
78 export const selectInstalledPlugins = (state) =>
79 state.installedPlugins.map((plugin) => plugin.slug);
80
81 export const selectActivePlugins = (state) =>
82 state.installedPlugins
83 .filter((plugin) => plugin.status === 'active')
84 .map((plugin) => plugin.slug);
85