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 / dashboard / components / QuickEdit.js

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

396 lines 18.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import React, { useEffect, useState } from "react";
2 import { IconClose } from "../../../icons";
3 import { useDashboardContext } from "../DashboardContext";
4 import MultiSelect from "./MultiSelect";
5 import { __ } from "@wordpress/i18n";
6 import Select from "react-select";
7 import { applyFilters } from "@wordpress/hooks";
8 import { toast } from "react-toastify";
9 import { decodeEntities } from "@wordpress/html-entities";
10 import useAuthorsQuery from "../hooks/useAuthorsQuery";
11 import useAuthorsSearchQuery from "../hooks/useAuthorsSearchQuery";
12
13 const QuickEdit = ({ setDocuments }) => {
14 const { data, setData: setQuickEditContext } = useDashboardContext();
15 const { docData, docId: selectedDocId } = data;
16 const [saveText, setSaveText] = useState("Save");
17 const [quickEditData, setQuickEditData] = useState({
18 author: "",
19 title: "",
20 slug: "",
21 comment_status: "",
22 status: "",
23 date: "",
24 password: "",
25 });
26
27 const [currentDocUser, setCurrentDocUser] = useState({});
28
29 const { usersLoading, authors, authorParams, setAuthorParams, isNextPageAvailable } = useAuthorsQuery('authors-list-view', {
30 per_page:10,
31 page:1
32 });
33
34 const { searchLoading, searchedUsers, setUserSearchValue } = useAuthorsSearchQuery();
35 const [privacyOption, setPrivacyOption] = useState("");
36
37 useEffect(() => {
38 setQuickEditData({
39 author: docData?.author,
40 title: docData.title.rendered,
41 slug: docData.slug,
42 comment_status: docData.comment_status,
43 status: docData.status,
44 date: docData?.date,
45 password: docData?.password,
46 });
47 setCurrentDocUser({
48 value: docData.author,
49 label: docData.author_info.name,
50 });
51 if (docData.status == "private") {
52 setPrivacyOption("private");
53 } else if (docData?.content?.protected) {
54 setPrivacyOption("password");
55 } else {
56 setPrivacyOption("none");
57 }
58 }, [docData]);
59
60 const authorOptions = docData?.author_list?.map((author) => ({
61 value: author.ID,
62 label: author.display_name,
63 }));
64
65 const statusOptions = [
66 { value: "publish", label: __("Published", "betterdocs") },
67 { value: "pending", label: __("Pending review", "betterdocs") },
68 { value: "draft", label: __("Draft", "betterdocs") },
69 ];
70
71 return (
72 <div className="betterdocs-quick-edit-panel">
73 <div className="betterdocs-quick-edit-wrap">
74 <div className="betterdocs-quick-edit-header">
75 <h3 className="betterdocs-quick-edit-title">
76 {decodeEntities(docData.title.rendered)}
77 </h3>
78 <div
79 onClick={() => setQuickEditContext({ isOpen: false })}
80 className="betterdocs-quick-edit-close"
81 >
82 <svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true">
83 <path d="M1 1l12 12M13 1L1 13" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" />
84 </svg>
85 </div>
86 </div>
87 <div className="betterdocs-quick-edit-body">
88 <div className="betterdocs-quick-edit-form-group">
89 <label htmlFor="betterdocs-quick-edit-status">
90 {__("Authors:", "betterdocs")}
91 </label>
92 <Select
93 className="quick-edit-select-fields betterdocs-quick-edit-authors"
94 id="betterdocs-quick-edit-authors"
95 value={currentDocUser}
96 onInputChange={(e) => {
97 setUserSearchValue(e);
98 }}
99 onMenuScrollToBottom={(e) => {
100 if(e != null && isNextPageAvailable){
101 setAuthorParams((prev) => {
102 return {...prev, page:authorParams.page + 1}
103 })
104 }
105 }}
106 onChange={(selectedOption) => {
107 setQuickEditData((state) => ({
108 ...state,
109 author: selectedOption?.value,
110 }));
111 setCurrentDocUser(selectedOption);
112 }}
113 filterOption={(option, inputValue)=> {
114 return option;
115 }}
116 options={searchedUsers?.length > 0 ? searchedUsers : authors}
117 classNamePrefix="quick-edit-select-fields"
118 />
119 </div>
120 <div className="betterdocs-quick-edit-form-group">
121 <label htmlFor="betterdocs-quick-edit-status">
122 {__("Status:", "betterdocs")}
123 </label>
124 <Select
125 className="quick-edit-select-fields betterdocs-quick-edit-status"
126 id="betterdocs-quick-edit-status"
127 value={statusOptions.find(
128 (option) =>
129 option.value === quickEditData.status,
130 )}
131 onChange={(selectedOption) => {
132 setQuickEditData((state) => ({
133 ...state,
134 status: selectedOption?.value,
135 }));
136 }}
137 options={statusOptions}
138 classNamePrefix="quick-edit-select-fields"
139 />
140 </div>
141 <div className="betterdocs-quick-edit-form-group">
142 <label htmlFor="betterdocs-quick-edit-title">
143 {__("Title:", "betterdocs")}
144 </label>
145 <input
146 id="betterdocs-quick-edit-title"
147 type="text"
148 value={quickEditData.title}
149 onChange={(event) =>
150 setQuickEditData((state) => ({
151 ...state,
152 title: event.target.value,
153 }))
154 }
155 />
156 </div>
157 <div className="betterdocs-quick-edit-form-group">
158 <label htmlFor="betterdocs-quick-edit-slug">
159 {__("Slug", "betterdocs")}
160 </label>
161 <input
162 id="betterdocs-quick-edit-slug"
163 type="text"
164 placeholder="Slug"
165 value={quickEditData.slug}
166 onChange={(event) =>
167 setQuickEditData((state) => ({
168 ...state,
169 slug: event.target.value,
170 }))
171 }
172 />
173 </div>
174 <div className="betterdocs-quick-edit-form-group">
175 <label htmlFor="betterdocs-quick-date">
176 {__("Date:", "betterdocs")}
177 </label>
178 <input
179 id="betterdocs-quick-edit-date"
180 type="datetime-local"
181 placeholder="date"
182 value={quickEditData?.date}
183 onChange={(e) => {
184 setQuickEditData((state) => ({
185 ...state,
186 date: e?.target?.value,
187 }));
188 }}
189 />
190 </div>
191 <div className="betterdocs-quick-edit-form-group">
192 <label>{__("Select Privacy", "betterdocs")}</label>
193 <div className="betterdocs-quick-edit-privacy-radio">
194 <div className="betterdocs-quick-edit-privacy-radio-group">
195 <input
196 id="password"
197 type="radio"
198 name="privacy"
199 value="password"
200 checked={privacyOption === "password"}
201 onChange={(e) => {
202 setPrivacyOption(e.target.value);
203 }}
204 />
205 <label htmlFor="password">
206 {__("Password Protected", "betterdocs")}
207 </label>
208 </div>
209 <div className="betterdocs-quick-edit-privacy-radio-group">
210 <input
211 id="private"
212 type="radio"
213 name="privacy"
214 value="private"
215 checked={privacyOption === "private"}
216 onChange={(e) => {
217 setPrivacyOption(e.target.value);
218 if (
219 quickEditData?.hasOwnProperty(
220 "password",
221 )
222 ) {
223 delete quickEditData["password"];
224 }
225 setQuickEditData((prev) => ({
226 ...quickEditData,
227 status: "private",
228 }));
229 }}
230 />
231 <label htmlFor="private">
232 {__("Make Private", "betterdocs")}
233 </label>
234 </div>
235 <div className="betterdocs-quick-edit-privacy-radio-group">
236 <input
237 id="none"
238 type="radio"
239 name="privacy"
240 value="none"
241 checked={privacyOption === "none"}
242 onChange={(e) => {
243 setPrivacyOption(e.target.value);
244 if (
245 quickEditData?.hasOwnProperty(
246 "password",
247 )
248 ) {
249 delete quickEditData["password"];
250 }
251 setQuickEditData((prev) => ({
252 ...quickEditData,
253 title: quickEditData?.title?.replace(
254 "Private:",
255 "",
256 ),
257 status: "publish",
258 }));
259 }}
260 />
261 <label htmlFor="none">
262 {__("None", "betterdocs")}
263 </label>
264 </div>
265 </div>
266 </div>
267 {privacyOption === "password" && (
268 <div className="betterdocs-quick-edit-form-group betterdocs-quick-edit-password-field">
269 <label htmlFor="betterdocs-quick-edit-password">
270 {__("Password:", "betterdocs")}
271 </label>
272 <input
273 id="betterdocs-quick-edit-password"
274 type="text"
275 placeholder=""
276 value={
277 quickEditData?.password?.length > 0
278 ? quickEditData?.password
279 : ""
280 }
281 onChange={(e) => {
282 setQuickEditData((state) => ({
283 ...state,
284 status:
285 docData?.status == "private"
286 ? "publish"
287 : docData?.status,
288 password: e?.target?.value,
289 }));
290 }}
291 />
292 </div>
293 )}
294
295 {betterdocs_admin?.multiple_kb == 1 &&
296 applyFilters("quick_edit_mkb_filter", "", [
297 docData,
298 setQuickEditData,
299 MultiSelect,
300 ])}
301
302 <MultiSelect
303 name="doc_category"
304 endpoint="wp/v2/doc_category"
305 doc={docData}
306 setQuickEditData={setQuickEditData}
307 label={__("Category", "betterdocs")}
308 placeholder={__("Search Category", "betterdocs")}
309 />
310
311 <MultiSelect
312 name="doc_tag"
313 endpoint="wp/v2/doc_tag"
314 doc={docData}
315 setQuickEditData={setQuickEditData}
316 label={__("Tags", "betterdocs")}
317 placeholder={__("Search Tags", "betterdocs")}
318 />
319
320 <div className="betterdocs-quick-edit-form-group">
321 <div className="betterdocs-quick-edit-comments">
322 <input
323 type="checkbox"
324 id={docData.id}
325 checked={
326 quickEditData.comment_status === "open"
327 }
328 onChange={(event) =>
329 setQuickEditData((prev) => ({
330 ...prev,
331 comment_status: event.target.checked
332 ? "open"
333 : "closed",
334 }))
335 }
336 />
337 <label htmlFor={docData.id}>
338 {__("Allow Comments", "betterdocs")}
339 </label>
340 </div>
341 </div>
342 </div>
343 <div className="betterdocs-quick-edit-footer">
344 <div className="betterdocs-quick-edit-submit">
345 <button
346 type="button"
347 className="betterdocs-quick-edit-cancel-btn"
348 onClick={() => setQuickEditContext({ isOpen: false })}
349 >
350 {__("Cancel", "betterdocs")}
351 </button>
352 <button
353 type="submit"
354 className="betterdocs-quick-edit-submit-btn"
355 onClick={async (event) => {
356 event.preventDefault();
357 setSaveText("Saving...");
358 const response = await wp.apiFetch({
359 path: `/wp/v2/docs/${docData.id}`,
360 method: "POST",
361 data: quickEditData,
362 });
363 if (response != undefined) {
364 setDocuments((state) => {
365 let newDocList = state?.map((doc) => {
366 if (doc?.id == selectedDocId) {
367 return response;
368 } else {
369 return doc;
370 }
371 });
372 return [...newDocList];
373 });
374 setSaveText("Save");
375 toast.success(
376 __("Saved Successfully", "betterdocs"),
377 );
378 } else {
379 setSaveText("Save");
380 toast.error(
381 __("Error While Saving", "betterdocs"),
382 );
383 }
384 }}
385 >
386 {saveText}
387 </button>
388 </div>
389 </div>
390 </div>
391 </div>
392 );
393 };
394
395 export default QuickEdit;
396