Skip to content
Draft
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
88 changes: 64 additions & 24 deletions client/views/SearchResults.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
<template>
<div class="flex h-full max-w-[700px] flex-col">
<div class="flex h-full flex-col" :class="isGridView ? 'max-w-[1200px]' : 'max-w-[700px]'">
<!-- Search Input -->
<SearchInput :initialSearchTerm="props.searchTerm" class="mb-2" />

<LoadingIndicator ref="loadingIndicator" class="flex-1">
<!-- Sort By -->
<div class="flex justify-end">
<!-- Toolbar -->
<div class="flex justify-end gap-1">
<CustomButton
:iconPath="isGridView ? mdiViewList : mdiViewGrid"
class="mb-1"
@click="toggleViewMode"
/>
<CustomButton
:label="`Sort By: ${sortByName}`"
:iconPath="mdiSort"
Expand All @@ -15,29 +20,57 @@
<PrimeMenu ref="sortMenu" :model="menuItems" :popup="true" />
</div>

<!-- Search Results -->
<!-- List View -->
<div v-if="!isGridView">
<div
v-for="result in results"
class="mb-4 cursor-pointer rounded px-2 py-1 hover:bg-theme-background-elevated"
>
<RouterLink :to="{ name: 'note', params: { title: result.title } }">
<div>
<span v-html="result.titleHighlightsOrTitle" class="mr-2"></span>
<Tag v-for="tag in result.tagMatches" :tag="tag" class="mr-1" />
</div>
<div>
<span class="text-theme-text-muted">{{
result.lastModifiedAsString
}}</span>
<span v-if="result.contentHighlights"> - </span>
<span
v-html="result.contentHighlights"
class="text-theme-text-muted"
></span>
</div>
</RouterLink>
</div>
</div>

<!-- Grid View -->
<div
v-for="result in results"
class="mb-4 cursor-pointer rounded px-2 py-1 hover:bg-theme-background-elevated"
v-else
class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3"
>
<RouterLink :to="{ name: 'note', params: { title: result.title } }">
<!-- Title and Tags -->
<div>
<span v-html="result.titleHighlightsOrTitle" class="mr-2"></span>
<Tag v-for="tag in result.tagMatches" :tag="tag" class="mr-1" />
</div>
<!-- Last Modified and Content Highlights -->
<div>
<span class="text-theme-text-muted">{{
result.lastModifiedAsString
}}</span>
<span v-if="result.contentHighlights"> - </span>
<span
<div
v-for="result in results"
class="cursor-pointer rounded border border-theme-border p-3 hover:bg-theme-background-elevated"
>
<RouterLink :to="{ name: 'note', params: { title: result.title } }">
<div class="mb-2 font-medium">
<span v-html="result.titleHighlightsOrTitle"></span>
</div>
<div v-if="result.tagMatches?.length" class="mb-2">
<Tag v-for="tag in result.tagMatches" :tag="tag" class="mr-1" />
</div>
<div class="text-sm text-theme-text-muted">
{{ result.lastModifiedAsString }}
</div>
<div
v-if="result.contentHighlights"
v-html="result.contentHighlights"
class="text-theme-text-muted"
></span>
</div>
</RouterLink>
class="mt-1 line-clamp-3 text-sm text-theme-text-muted"
></div>
</RouterLink>
</div>
</div>
</LoadingIndicator>
</div>
Expand All @@ -48,7 +81,7 @@ import { useToast } from "primevue/usetoast";
import { computed, onMounted, ref, watch } from "vue";
import { useRouter } from "vue-router";

import { mdiMagnify, mdiSort } from "@mdi/js";
import { mdiMagnify, mdiSort, mdiViewGrid, mdiViewList } from "@mdi/js";
import { apiErrorHandler, getNotes } from "../api.js";
import CustomButton from "../components/CustomButton.vue";
import LoadingIndicator from "../components/LoadingIndicator.vue";
Expand All @@ -70,6 +103,13 @@ const results = ref([]);
const router = useRouter();
const sortMenu = ref();
const toast = useToast();
const viewMode = ref(localStorage.getItem("viewMode") || "list");
const isGridView = computed(() => viewMode.value === "grid");

function toggleViewMode() {
viewMode.value = viewMode.value === "list" ? "grid" : "list";
localStorage.setItem("viewMode", viewMode.value);
}

const sortByName = computed(() => {
const sortOptionNames = {
Expand Down