diff --git a/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/KnowledgeManagementPortalCategoryController.php b/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/KnowledgeManagementPortalCategoryController.php index ad66977ad..f026df4e7 100644 --- a/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/KnowledgeManagementPortalCategoryController.php +++ b/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/KnowledgeManagementPortalCategoryController.php @@ -38,6 +38,7 @@ use Illuminate\Http\JsonResponse; use App\Http\Controllers\Controller; +use Illuminate\Database\Eloquent\Builder; use AidingApp\KnowledgeBase\Models\KnowledgeBaseCategory; use AidingApp\Portal\DataTransferObjects\KnowledgeBaseCategoryData; @@ -74,6 +75,12 @@ public function show(KnowledgeBaseCategory $category): JsonResponse 'articles' => $category->knowledgeBaseItems() ->with('tags') ->public() + ->when(request()->get('filter') === 'featured', function (Builder $query) { + $query->where('is_featured', true); + }) + ->when(request()->get('filter') === 'most-viewed', function (Builder $query) { + $query->where('portal_view_count', '>', 0)->orderBy('portal_view_count', 'desc'); + }) ->paginate(5) ->through(function ($category) { $category->name = $category->title; diff --git a/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/KnowledgeManagementPortalSearchController.php b/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/KnowledgeManagementPortalSearchController.php index 6eb587e35..a899a8f56 100644 --- a/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/KnowledgeManagementPortalSearchController.php +++ b/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/KnowledgeManagementPortalSearchController.php @@ -69,6 +69,12 @@ public function get(Request $request): KnowledgeManagementSearchData ->with('tags') ->when($search->isNotEmpty(), fn (Builder $query) => $query->tap(new SearchBy('title', $search))) ->when($tags->isNotEmpty(), fn (Builder $query) => $query->whereHas('tags', fn (Builder $query) => $query->whereIn('id', $tags))) + ->when($request->get('filter') === 'featured', function (Builder $query) { + $query->where('is_featured', true); + }) + ->when($request->get('filter') === 'most-viewed', function (Builder $query) { + $query->where('portal_view_count', '>', 0)->orderBy('portal_view_count', 'desc'); + }) ->paginate(5) ->through(function (KnowledgeBaseItem $article) { return [ diff --git a/portals/knowledge-management/src/Components/FilterComponent.vue b/portals/knowledge-management/src/Components/FilterComponent.vue new file mode 100644 index 000000000..6a33acb7e --- /dev/null +++ b/portals/knowledge-management/src/Components/FilterComponent.vue @@ -0,0 +1,85 @@ + + + diff --git a/portals/knowledge-management/src/Components/SearchResults.vue b/portals/knowledge-management/src/Components/SearchResults.vue index 65098e9ab..dd3322315 100644 --- a/portals/knowledge-management/src/Components/SearchResults.vue +++ b/portals/knowledge-management/src/Components/SearchResults.vue @@ -37,9 +37,10 @@ import { ChevronRightIcon, XMarkIcon } from '@heroicons/vue/20/solid'; import Tags from './Tags.vue'; import Article from './Article.vue'; + import FilterComponent from './FilterComponent.vue'; import Pagination from './Pagination.vue'; - const emit = defineEmits(['fetchNextPage', 'fetchPreviousPage', 'fetchPage']); + const emit = defineEmits(['fetchNextPage', 'fetchPreviousPage', 'fetchPage', 'change-filter']); defineProps({ searchQuery: { @@ -54,6 +55,10 @@ type: Boolean, required: true, }, + selectedFilter: { + type: String, + default: '', + }, currentPage: { type: Number, required: true, @@ -75,6 +80,11 @@ required: true, }, }); + + const updateFilter = (value) => { + emit('change-filter', value); + }; + function fetchNextPage() { emit('fetchNextPage'); } @@ -96,6 +106,7 @@ Search results: {{ searchQuery }} +

Articles ({{ totalArticles }})

diff --git a/portals/knowledge-management/src/Pages/Home.vue b/portals/knowledge-management/src/Pages/Home.vue index 6e7d92dad..afa0cf367 100644 --- a/portals/knowledge-management/src/Pages/Home.vue +++ b/portals/knowledge-management/src/Pages/Home.vue @@ -72,6 +72,7 @@ const selectedTags = ref([]); const route = useRoute(); const globalSearchInput = ref(null); + const filter = ref(''); const currentPage = ref(1); const nextPageUrl = ref(null); const prevPageUrl = ref(null); @@ -82,7 +83,6 @@ const debounceSearch = debounce((value, page = 1) => { const { post } = consumer(); - if (!value && selectedTags.value.length < 1) { searchQuery.value = null; searchResults.value = null; @@ -94,6 +94,7 @@ post(props.searchUrl, { search: JSON.stringify(value), tags: selectedTags.value.join(','), + filter: filter.value, page: page, }).then((response) => { searchResults.value = response.data; @@ -162,6 +163,11 @@ globalSearchInput.value.focus(); } + const changeSearchFilter = (value) => { + filter.value = value; + debounceSearch(searchQuery.value); + }; + const fetchNextPage = () => { currentPage.value = currentPage.value !== lastPage.value ? currentPage.value + 1 : lastPage.value; debounceSearch(searchQuery.value, currentPage.value); @@ -240,6 +246,8 @@ :searchQuery="searchQuery" :searchResults="searchResults" :loadingResults="loadingResults" + @change-filter="changeSearchFilter" + :selected-filter="filter" :currentPage="currentPage" :lastPage="lastPage" :fromArticle="fromArticle" diff --git a/portals/knowledge-management/src/Pages/ViewCategory.vue b/portals/knowledge-management/src/Pages/ViewCategory.vue index e3bf97016..823cb7ebd 100644 --- a/portals/knowledge-management/src/Pages/ViewCategory.vue +++ b/portals/knowledge-management/src/Pages/ViewCategory.vue @@ -44,6 +44,7 @@ import Article from '../Components/Article.vue'; import SearchResults from '../Components/SearchResults.vue'; import Badge from '../Components/Badge.vue'; + import FilterComponent from '../Components/FilterComponent.vue'; import Pagination from '../Components/Pagination.vue'; const route = useRoute(); @@ -81,6 +82,7 @@ const totalArticles = ref(0); const fromArticle = ref(0); const toArticle = ref(0); + const filter = ref(''); const fromSearch = ref(false); const debounceSearch = debounce((value, page = 1) => { @@ -97,6 +99,7 @@ post(props.searchUrl, { search: JSON.stringify(value), tags: selectedTags.value.join(','), + filter: filter.value, page: page, }).then((response) => { searchResults.value = response.data; @@ -116,6 +119,12 @@ }; watch(searchQuery, (value) => { + if (value == null) { + fromSearch.value = false; + getData(1); + + return; + } debounceSearch(value); }); @@ -157,6 +166,17 @@ currentPage.value = page; getData(currentPage.value); }; + + const changeFilter = (value) => { + filter.value = value; + getData(1); + }; + + const changeSearchFilter = (value) => { + filter.value = value; + debounceSearch(searchQuery.value); + }; + watch( route, async function (newRouteValue) { @@ -178,12 +198,14 @@ const { get } = consumer(); - await get(props.apiUrl + '/categories/' + route.params.categoryId, { page: page }).then((response) => { - category.value = response.data.category; - articles.value = response.data.articles.data; - setPagination(response.data.articles); - loadingResults.value = false; - }); + await get(props.apiUrl + '/categories/' + route.params.categoryId, { page: page, filter: filter.value }).then( + (response) => { + category.value = response.data.category; + articles.value = response.data.articles.data; + setPagination(response.data.articles); + loadingResults.value = false; + }, + ); } @@ -245,6 +267,8 @@ :searchQuery="searchQuery" :searchResults="searchResults" :loadingResults="loadingeSearchResults" + @change-filter="changeSearchFilter" + :selected-filter="filter" :currentPage="currentPage" :lastPage="lastPage" :fromArticle="fromArticle" @@ -262,7 +286,10 @@

{{ category.name }}

- +