\r
onBeforeMount(() => {\r
getConfig()\r
- .then((response) => {\r
- globalStore.authType = response.data.authType;\r
+ .then((data) => {\r
+ globalStore.authType = data.authType;\r
})\r
.catch(function (error) {\r
if (!error.handled) {\r
import * as constants from "./constants.js";
+import { Note } from "./classes.js";
import axios from "axios";
import { getStoredToken } from "./tokenStorage.js";
import router from "./router.js";
},
);
-export function getConfig() {
- return api.get("/api/config");
+export async function getConfig() {
+ try {
+ const response = await api.get("/api/config");
+ return response.data;
+ } catch (error) {
+ return Promise.reject(error);
+ }
}
-export function getToken(username, password, totp) {
- return api.post("/api/token", {
- username: username,
- password: totp ? password + totp : password,
- });
+export async function getToken(username, password, totp) {
+ try {
+ const response = await api.post("/api/token", {
+ username: username,
+ password: totp ? password + totp : password,
+ });
+ return response.data.access_token;
+ } catch (response) {
+ return Promise.reject(response);
+ }
}
-export function getNotes(term, sort, order, limit) {
- return api.get("/api/search", {
- params: {
- term: term,
- sort: sort,
- order: order,
- limit: limit,
- },
- });
+export async function getNotes(term, sort, order, limit) {
+ try {
+ const response = await api.get("/api/search", {
+ params: {
+ term: term,
+ sort: sort,
+ order: order,
+ limit: limit,
+ },
+ });
+ return response.data.map(
+ (note) => new Note(note.title, note.lastModified, note.content),
+ );
+ } catch (response) {
+ return Promise.reject(response);
+ }
}
--- /dev/null
+import router from "./router.js";
+
+class Note {
+ constructor(title, lastModified, content) {
+ this.title = title;
+ this.lastModified = lastModified;
+ this.content = content;
+ }
+
+ get href() {
+ return `${router.resolve({ name: "note", params: { title: this.title } }).href}`;
+ }
+
+ get lastModifiedAsDate() {
+ return new Date(this.lastModified * 1000);
+ }
+
+ get lastModifiedAsString() {
+ return this.lastModifiedAsDate.toLocaleString();
+ }
+}
+
+class SearchResult extends Note {
+ constructor(searchResult) {
+ super(searchResult.title, searchResult.lastModified);
+ this.score = searchResult.score;
+ this.titleHighlights = searchResult.titleHighlights;
+ this.contentHighlights = searchResult.contentHighlights;
+ this.tagMatches = searchResult.tagMatches;
+ }
+
+ get titleHighlightsOrTitle() {
+ return this.titleHighlights ? this.titleHighlights : this.title;
+ }
+
+ get includesHighlights() {
+ if (
+ this.titleHighlights ||
+ this.contentHighlights ||
+ (this.tagMatches != null && this.tagMatches.length)
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+
+export { Note, SearchResult };
<template>\r
- <nav class="flex justify-between">\r
- <RouterLink to="/">\r
- <Logo :class="{ invisible: hideLogo }"></Logo>\r
+ <nav class="mb-4 flex justify-between align-top">\r
+ <RouterLink to="/" v-if="!hideLogo">\r
+ <Logo></Logo>\r
</RouterLink>\r
- <div class="flex">\r
+ <div class="flex grow items-start justify-end">\r
<CustomButton\r
:iconPath="mdilPlusCircle"\r
label="New Note"\r
\r
import CustomButton from "../components/CustomButton.vue";\r
import Logo from "../components/Logo.vue";\r
-import { clearStoredToken } from "../tokenStorage.js"\r
+import { clearStoredToken } from "../tokenStorage.js";\r
\r
const router = useRouter();\r
\r
+import * as constants from "./constants.js";\r
+\r
import { createRouter, createWebHistory } from "vue-router";\r
\r
const router = createRouter({\r
path: "/login",\r
name: "login",\r
component: () => import("./views/LogIn.vue"),\r
+ props: (route) => ({ [constants.params.redirect]: route.query.redirect }),\r
+ },\r
+ {\r
+ path: "/note/:title",\r
+ name: "note",\r
+ component: () => import("./views/Note.vue"),\r
+ props: true,\r
},\r
],\r
});\r
>
RECENTLY MODIFIED
</p>
- <CustomButton v-for="note in notes" :label="note.title" />
+ <RouterLink v-for="note in notes" :to="note.href">
+ <CustomButton :label="note.title" />
+ </RouterLink>
</div>
</div>
</div>
import CustomButton from "../components/CustomButton.vue";
import Logo from "../components/Logo.vue";
import SearchInput from "../partials/SearchInput.vue";
+import { RouterLink } from "vue-router";
const notes = ref([]);
-getNotes("*", "lastModified", "desc", 5).then((response) => {
- notes.value = response.data;
+getNotes("*", "lastModified", "desc", 5).then((data) => {
+ notes.value = data;
});
</script>
import { authTypes } from "../constants.js";
import { useGlobalStore } from "../globalStore.js";
import { storeToken } from "../tokenStorage.js";
-import * as constants from "../constants.js";
+
+const props = defineProps({ redirect: String });
const globalStore = useGlobalStore();
const router = useRouter();
function logIn() {
getToken(username.value, password.value, totp.value)
- .then((response) => {
- storeToken(response.data.access_token, rememberMe.value);
- const redirectPath = route.query[constants.params.redirect];
- if (redirectPath) {
- router.push(redirectPath);
+ .then((access_token) => {
+ storeToken(access_token, rememberMe.value);
+ if (props.redirect) {
+ router.push(props.redirect);
} else {
router.push({ name: "home" });
}
})
- .catch((error) => {
+ .catch((response) => {
username.value = "";
password.value = "";
totp.value = "";
- if (error.response?.status === 401) {
+ if (response.response?.status === 401) {
toast.add({
summary: "Login Failed",
detail: "Please check your credentials and try again.",
+ severity: "error",
closable: false,
life: 5000,
});
--- /dev/null
+<template>
+ {{ title }}
+</template>
+
+<script setup>
+defineProps({
+ title: String,
+});
+</script>