Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/configuring.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ For more info, see the **[Authentication Docs](/docs/authentication.md)**
**`timeout`** | `number` | _Optional_ | Request timeout in milliseconds, defaults to ½ a second (`500`)
**`ignoreErrors`** | `boolean` | _Optional_ | Prevent an error message being displayed, if a network request or something else fails. Useful for false-positives
**`label`** | `string` | _Optional_ | Add custom label to a given widget. Useful for identification, if there are multiple of the same type of widget in a single section
**`category`** | string | _Optional_ | Free-text category for this widget (e.g., Monitoring, CI/CD). Used by category filtering/search. Up to the user whatever category they want to set for a widget.

**[⬆️ Back to Top](#configuring)**

Expand All @@ -317,6 +318,7 @@ For more info, see the **[Authentication Docs](/docs/authentication.md)**
**`hideForGuests`** | `boolean` | _Optional_ | Current section will be visible for logged in users, but not for guests (see `appConfig.enableGuestAccess`). Defaults to `false`
**`hideForKeycloakUsers`** | `object` | _Optional_ | Current section will be visible to all keycloak users, except for those configured via these groups and roles. See `hideForKeycloakUsers`
**`showForKeycloakUsers`** | `object` | _Optional_ | Current section will be hidden from all keycloak users, except for those configured via these groups and roles. See `showForKeycloakUsers`
**`widgetCategories`** | string[] | _Optional_ | Free-text tags for this section, used for category filtering/search of widgets `section.widgets` from within the UI. Editable in the Edit Section modal. Example: ["DevOps", "Monitoring"]. This will work only if corrosponding widget category is setup in the widgets 'category' field.

**[⬆️ Back to Top](#configuring)**

Expand Down
1 change: 1 addition & 0 deletions src/components/InteractiveEditor/EditSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export default {
cols: displayDataSchema.cols,
collapsed: displayDataSchema.collapsed,
hideForGuests: displayDataSchema.hideForGuests,
widgetCategories: displayDataSchema.widgetCategories,
},
},
},
Expand Down
6 changes: 5 additions & 1 deletion src/mixins/HomeMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,11 @@ const HomeMixin = {
return [];
}
const visibleTiles = allTiles.filter((tile) => checkItemVisibility(tile));
return searchTiles(visibleTiles, this.searchValue);
return searchTiles(visibleTiles, this.searchValue, this.areWidgets(allTiles));
},
/* Checks if titles are widgets */
areWidgets(allTiles) {
return Array.isArray(allTiles) && allTiles.length > 0 && !('title' in allTiles[0]);
},
/* Checks if any sections or items use icons from a given CDN */
checkIfIconLibraryNeeded(prefix) {
Expand Down
15 changes: 15 additions & 0 deletions src/utils/ConfigSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,16 @@
"default": 1,
"description": "The amount of space that the section spans horizontally"
},
"widgetCategories": {
"type": "array",
"title": "Widget Categories",
"description": "Tags for this section (add/remove text tags).",
"items": {
"type": "string"
},
"uniqueItems": false,
"default": []
},
"sectionLayout": {
"title": "Layout Type",
"type": "string",
Expand Down Expand Up @@ -1170,6 +1180,11 @@
"title": "Widget Options",
"type": "object",
"description": "Configuration options for widget. Varies depending on widget type, see docs for all options"
},
"category": {
"title": "Category",
"type": "string",
"description": "Single category tag."
}
}
}
Expand Down
33 changes: 21 additions & 12 deletions src/utils/Search.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,31 @@ const filterHelper = (compareStr, searchStr) => {
* @param {array} allTiles An array of tiles
* @param {string} searchTerm The users search term
* @returns A filtered array of tiles
* if widgets are sent as allTiles, then the search is done based on options.category
*/
export const searchTiles = (allTiles, searchTerm) => {
export const searchTiles = (allTiles, searchTerm, isWidgets) => {
if (!searchTerm) return allTiles; // If no search term, then return all
if (!allTiles) return []; // If no data, then skip
return allTiles.filter((tile) => {
const {
title, description, provider, url, tags,
} = tile;
return filterHelper(title, searchTerm)
|| filterHelper(provider, searchTerm)
|| filterHelper(description, searchTerm)
|| filterHelper(tags, searchTerm)
|| filterHelper(getDomainFromUrl(url), searchTerm);
});
if (!isWidgets) {
return allTiles.filter((tile) => {
const {
title, description, provider, url, tags,
} = tile;
return filterHelper(title, searchTerm)
|| filterHelper(provider, searchTerm)
|| filterHelper(description, searchTerm)
|| filterHelper(tags, searchTerm)
|| filterHelper(getDomainFromUrl(url), searchTerm);
});
} else {
return allTiles.filter((tile) => {
const {
category,
} = tile;
return filterHelper(category, searchTerm);
});
}
};

/* From a list of search bangs, return the URL associated with it */
export const getSearchEngineFromBang = (searchQuery, bangList) => {
const bangNames = Object.keys(bangList);
Expand Down
27 changes: 25 additions & 2 deletions src/views/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@
:displayData="getDisplayData(section)"
:groupId="makeSectionId(section)"
:items="section.filteredItems"
:widgets="section.widgets"
:widgets="section.filteredWidgets"
:searchTerm="searchValue"
:itemSize="itemSizeBound"
@itemClicked="finishedSearching()"
@change-modal-visibility="updateModalVisibility"
:isWide="!!singleSectionView || layoutOrientation === 'horizontal'"
:class="(searchValue && section.filteredItems.length === 0) ? 'no-results' : ''"
:class="(searchValue &&
(section.filteredItems.length === 0 &&
section.filteredWidgets.length === 0)) ? 'no-results' : ''"
/>
</template>
<!-- Show add new section button, in edit mode -->
Expand Down Expand Up @@ -102,6 +104,15 @@ export default {
return sections.map((_section) => {
const section = _section;
section.filteredItems = this.filterTiles(section.items, this.searchValue);

const searchedWidgets = this.filterTiles(section.widgets, this.searchValue);
const widgetCategoriesArray = this.normalizeWidgetCats(
this.getDisplayData(section).widgetCategories,
);
section.filteredWidgets = this.filterWidgetsByCategories(
searchedWidgets, widgetCategoriesArray,
);

return section;
});
},
Expand All @@ -123,6 +134,18 @@ export default {
},
},
methods: {
/* returns only widgets that have category that are present in
widgetCategories array in section config displayData */
filterWidgetsByCategories(widgets, cats) {
if (!cats.length) return widgets || [];
return (widgets || []).filter(w => (typeof w.category === 'string'
&& cats.includes(w.category.toLowerCase().trim())));
},
/* Normalization of widget categories text inputs by user */
normalizeWidgetCats(cats) {
if (!Array.isArray(cats)) return [];
return cats.map(c => String(c).toLowerCase().trim()).filter(Boolean);
},
/* Clears input field, once a searched item is opened */
finishedSearching() {
if (this.$refs.filterComp) this.$refs.filterComp.clearFilterInput();
Expand Down