Skip to content

Commit

Permalink
fix: add edit article functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
RitvikSardana committed Jan 2, 2025
1 parent 773d6c4 commit b1ffa54
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 22 deletions.
3 changes: 1 addition & 2 deletions desk/src/components/UserAvatar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
/>
<span
v-if="expand"
class="truncate"
class="truncate capitalize text-base text-ink-gray-9 font-medium"
:class="{
'text-gray-900': strong,
'font-medium': strong,
}"
>
Expand Down
123 changes: 116 additions & 7 deletions desk/src/pages/knowledge-base/EditArticle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@
</div>
</template>
<template #right-header>
<Button label="Edit" iconLeft="edit" />
<Button
label="Edit"
iconLeft="edit"
@click="handleEditMode"
v-if="!editable"
/>
<Button label="Save" @click="handleSave" v-if="editable" />
<Button
variant="solid"
:label="article.data?.status === 'Draft' ? 'Publish' : 'Unpublish'"
Expand All @@ -21,30 +27,111 @@
/>
</template>
</LayoutHeader>
<div class="pt-6 mx-auto w-full max-w-4xl px-5" v-if="!article.loading">
{{ article.data }}

<div class="pt-6 mx-auto w-full max-w-2xl px-5" v-if="!article.loading">
<div
class="flex flex-col gap-8 p-4"
:class="editable && 'border w-full rounded-lg '"
>
<!-- Top Element -->
<div class="flex gap-1 items-center">
<!-- Avatar -->
<div class="flex gap-1 items-center justify-center">
<Avatar
:image="article.data.author.image"
:label="article.data.author.name"
/>
<span
class="truncate capitalize text-base text-ink-gray-9 font-medium"
>
{{ user.full_name || user.name }}
</span>
</div>
<IconDot class="h-4 w-4 text-gray-600" />
<div class="text-xs text-gray-500">
{{
dayjs(article.data.published_on || article.data.creation).short()
}}
</div>
</div>
<!-- Title -->
<textarea
class="w-full resize-none border-0 text-3xl font-bold placeholder-ink-gray-3 p-0 pb-3 border-b border-gray-200 focus:ring-0 focus:border-gray-200"
v-model="title"
placeholder="Title"
rows="1"
wrap="soft"
maxlength="140"
autofocus
:disabled="!editable"
/>
<!-- Article Content -->
<TextEditor
ref="editorRef"
:content="content"
@change="(event:string) => {
content = event;
isDirty = true;
}"
placeholder="Write your article here..."
editor-class="rounded-b-lg max-w-[unset] prose-sm h-[calc(100vh-340px)] sm:h-[calc(100vh-250px)] overflow-auto"
>
<template #bottom v-if="editable">
<TextEditorFixedMenu
class="-ml-1 overflow-x-auto w-full"
:buttons="textEditorMenuButtons"
/>
</template>
</TextEditor>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { computed } from "vue";
import { Breadcrumbs, debounce, createResource, Badge } from "frappe-ui";
import LayoutHeader from "@/components/LayoutHeader.vue";
import { computed, ref } from "vue";
import {
Breadcrumbs,
debounce,
createResource,
Badge,
Avatar,
TextEditor,
TextEditorFixedMenu,
} from "frappe-ui";
import { dayjs } from "@/dayjs";
import { updateArticle } from "@/stores/article";
import { useUserStore } from "@/stores/user";
import LayoutHeader from "@/components/LayoutHeader.vue";
import { Resource, Article } from "@/types";
import IconDot from "~icons/lucide/dot";
import { createToast, textEditorMenuButtons } from "@/utils";
const props = defineProps({
articleId: {
type: String,
required: true,
},
});
const article = createResource({
const userStore = useUserStore();
const user = userStore.getUser();
const editorRef = ref(null);
const editable = ref(false);
const content = ref("");
const title = ref("");
const article: Resource<Article> = createResource({
url: "helpdesk.helpdesk.doctype.hd_article.api.get_article2",
params: {
name: props.articleId,
},
auto: true,
onSuccess: (data: Article) => {
content.value = data.content;
title.value = data.title;
},
});
const toggleStatus = debounce(() => {
Expand All @@ -64,6 +151,28 @@ const toggleStatus = debounce(() => {
);
}, 300);
function handleEditMode() {
editable.value = true;
editorRef.value.editor.chain().focus("start");
}
function handleSave() {
editable.value = false;
handleArticleUpdate();
}
let isDirty: Boolean = false;
function handleArticleUpdate() {
if (!isDirty) return;
updateArticle.submit({
doctype: "HD Article",
name: article.data.name,
fieldname: {
content: content.value,
title: title.value,
},
});
}
const breadcrumbs = computed(() => {
const items = [
{
Expand Down
14 changes: 3 additions & 11 deletions desk/src/pages/knowledge-base/NewArticle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,7 @@
<div class="flex flex-col gap-3 rounded-lg border w-full p-4">
<div class="flex justify-between items-center mb-3">
<!-- Author Info -->
<div class="flex gap-1 items-center">
<Avatar :image="user.user_image" :label="user.full_name" />
<span
class="truncate capitalize text-base text-ink-gray-9 font-medium"
>
{{ user.full_name || user.name }}
</span>
</div>
<UserAvatar :name="user.name" :expand="true" />
<!-- Action Buttons -->
<div class="flex gap-2">
<Button label="Discard" @click="handleArticleDiscard" />
Expand Down Expand Up @@ -62,15 +55,14 @@ import { ref, computed } from "vue";
import {
usePageMeta,
TextEditor,
Avatar,
TextEditorFixedMenu,
confirmDialog,
Breadcrumbs,
} from "frappe-ui";
import { useRouter } from "vue-router";
import { useUserStore } from "@/stores/user";
import { newArticle } from "@/stores/article";
import LayoutHeader from "@/components/LayoutHeader.vue";
import { useUserStore } from "@/stores/user";
import { LayoutHeader, UserAvatar } from "@/components";
import { createToast, textEditorMenuButtons } from "@/utils";
import { Article } from "@/types";
Expand Down
7 changes: 5 additions & 2 deletions desk/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Component } from "vue";

export interface Resource<A = unknown> {
export interface Resource<T = unknown> {
auto: boolean;
loading: boolean;
data: A;
data: T;
pageLength: number;
totalCount: number;
hasNextPage: boolean;
Expand Down Expand Up @@ -222,6 +222,9 @@ export interface Article {
subtitle: string;
article_image: string | null;
_user_tags: string | null;
status: string;
creation: string;
content: string;
}

export interface SubCategory {
Expand Down
1 change: 1 addition & 0 deletions helpdesk/helpdesk/doctype/hd_article/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def get_article2(name: str):
"author": author,
"creation": article.creation,
"status": article.status,
"published_on": article.published_on,
}

return article

0 comments on commit b1ffa54

Please sign in to comment.