PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.5
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.5
4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 All 203 releases
betterdocs / react-src / admin / faq-builder / components / FaqList.js

FaqList.js in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.9.5, at react-src/admin/faq-builder/components/FaqList.js

169 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { useQuery } from "@tanstack/react-query";
2 import React, { useEffect, useState } from "react";
3 import { Droppable } from "react-beautiful-dnd";
4 import EmptyCategory from "../utils/EmptyCategory";
5 import FaqLoader from "../utils/FaqLoader";
6 import { faqOrdering } from "../utils/reOrder";
7 import { getAllFaqBasedOnCategory, reOrderFaqList } from "./../utils/function";
8 import Faq from "./Faq";
9 import SettingsLoader from "../utils/SettingsLoader";
10 import { useFAQScope } from "../context/ScopeContext";
11
12
13 const FaqList = ({
14 category,
15 order,
16 allFaqCategories,
17 changeFaqSort,
18 reFetchFaqForCategory,
19 createFaqAt,
20 categoriesLoading,
21 reFetchCategories,
22 setCreateFaqAt,
23 faqExpanded,
24 setFaqExpanded,
25 setReFetchFaqForCategory,
26 setChangeFaqSort,
27 setReFetchData,
28 }) => {
29 const { taxonomy } = useFAQScope();
30 const {
31 isLoading: faqLoading,
32 data: allFaqList,
33 refetch: reFetchFaqList,
34 } = useQuery(["allFaqList", category?.id, taxonomy], getAllFaqBasedOnCategory);
35
36 const [sortedFaqList, setSortedFaqList] = useState([]);
37
38 useEffect(() => {
39 reFetchFaqList();
40 }, [allFaqCategories]);
41
42 useEffect(() => {
43 setReFetchData({ func: reFetchFaqList });
44 }, [allFaqList]);
45
46 useEffect(() => {
47 if (!allFaqList?.length) {
48 setSortedFaqList([]);
49 return;
50 }
51
52 if (order === 'a_to_z') {
53 setSortedFaqList(
54 [...allFaqList].sort((a, b) =>
55 (a.title?.rendered ?? '').localeCompare(b.title?.rendered ?? '')
56 )
57 );
58 return;
59 }
60 if (order === 'z_to_a') {
61 setSortedFaqList(
62 [...allFaqList].sort((a, b) =>
63 (b.title?.rendered ?? '').localeCompare(a.title?.rendered ?? '')
64 )
65 );
66 return;
67 }
68 if (order === 'most_recent') {
69 setSortedFaqList([...allFaqList].sort((a, b) => b.id - a.id));
70 return;
71 }
72 if (order === 'least_recent') {
73 setSortedFaqList([...allFaqList].sort((a, b) => a.id - b.id));
74 return;
75 }
76
77 // default / most_questions: use the manual drag-drop order stored in meta.
78 const sortingArr = (category?.meta?._betterdocs_faq_order[0] || '')
79 .split(',')
80 .filter(Boolean)
81 .map(Number);
82
83 if (sortingArr.length) {
84 const ordered = sortingArr
85 .map((id) => allFaqList.find((faq) => faq.id === id))
86 .filter(Boolean);
87 // Append any FAQs missing from the saved order — e.g. a FAQ created
88 // in a group that had no order meta yet (the backend seeds the meta
89 // with just the new id), which would otherwise hide every existing
90 // FAQ even though the count still includes them.
91 const orderedIds = new Set(ordered.map((faq) => faq.id));
92 const rest = allFaqList.filter((faq) => !orderedIds.has(faq.id));
93 setSortedFaqList([...ordered, ...rest]);
94 } else {
95 setSortedFaqList(allFaqList);
96 }
97 }, [allFaqList, order, category?.meta?._betterdocs_faq_order[0]]);
98
99 useEffect(() => {
100 if (changeFaqSort?.destination?.droppableId == category?.id) {
101 let updatedFaqsList = faqOrdering(changeFaqSort, sortedFaqList);
102 setSortedFaqList(updatedFaqsList);
103 reOrderFaqList(
104 category?.id,
105 updatedFaqsList?.map((data) => data?.id)?.toString()
106 ).then(() => {
107 reFetchCategories();
108 });
109 setChangeFaqSort({});
110 }
111 }, [changeFaqSort]);
112
113 useEffect(() => {
114 if (reFetchFaqForCategory && reFetchFaqForCategory == category?.id) {
115 reFetchFaqList();
116 setReFetchFaqForCategory(null);
117 }
118 }, [reFetchFaqForCategory]);
119
120 return (
121 <Droppable droppableId={category?.id.toString()} type="FAQ">
122 {(provided) => (
123 <div
124 {...provided.droppableProps}
125 ref={provided.innerRef}
126 className="bd-faq-list-droppable"
127 >
128 {!faqLoading ? (
129 sortedFaqList?.length > 0 ? (
130 sortedFaqList?.map((faq, index) => (
131 <Faq
132 key={faq?.id}
133 data={faq}
134 index={index}
135 order={order}
136 reFetchFaqList={reFetchFaqList}
137 category={category?.id}
138 categoriesLoading={categoriesLoading}
139 allFaqCategories={allFaqCategories}
140 reFetchCategories={reFetchCategories}
141 setCreateFaqAt={setCreateFaqAt}
142 faqExpanded={faqExpanded}
143 setFaqExpanded={setFaqExpanded}
144 setReFetchFaqForCategory={
145 setReFetchFaqForCategory
146 }
147 settings={betterdocsFaq?.betterdocs_settings}
148 />
149 ))
150 ) : (
151 createFaqAt !== category?.id && <EmptyCategory />
152 )
153 ) : (
154 <FaqLoader
155 count={
156 (Number(category?.count) || 0) +
157 (Number(category?.betterdocs_draft_count) || 0)
158 }
159 />
160 )}
161 {provided.placeholder}
162 </div>
163 )}
164 </Droppable>
165 );
166 };
167
168 export default FaqList;
169