| 1 |
import React, { useEffect, useState } from "react"; |
| 2 |
import { useQuery } from "@tanstack/react-query"; |
| 3 |
import apiFetch from "@wordpress/api-fetch"; |
| 4 |
import { __, _n, sprintf } from "@wordpress/i18n"; |
| 5 |
import AllDocsFilter from "./AllDocsFilter.js"; |
| 6 |
import AllDocsListTable from "./AllDocsListTable.js"; |
| 7 |
import AllDocsSearch from "./AllDocsSearch.js"; |
| 8 |
import NoDocsBody from "./NoDocsBody.js"; |
| 9 |
import NoDocsLoader from "../loaders/NoDocsLoader.js"; |
| 10 |
import QuickEdit from "./QuickEdit.js"; |
| 11 |
import { useDashboardContext } from "../DashboardContext"; |
| 12 |
import { addQueryArgs } from "@wordpress/url"; |
| 13 |
import { toast } from "react-toastify"; |
| 14 |
|
| 15 |
import { useOutletContext } from "react-router-dom"; |
| 16 |
|
| 17 |
import { useNavigate } from "react-router-dom"; |
| 18 |
import { makeRouteURL } from "../../../utils/history.js"; |
| 19 |
|
| 20 |
import { objectDifference } from "../helpers/Helpers.js"; |
| 21 |
|
| 22 |
import useFetch from "../hooks/useFetch"; |
| 23 |
import useDebounce from "../hooks/useDebounce.js"; |
| 24 |
|
| 25 |
import Swal from "sweetalert2"; |
| 26 |
|
| 27 |
const AllDocsList = ( { post_status } ) => { |
| 28 |
const [mkbFilterValue, refetch] = useOutletContext(); |
| 29 |
const [bulkData, setBulkData] = useState([]); |
| 30 |
const { data, setData } = useDashboardContext(); |
| 31 |
const [filterOptions, setFilterOptions] = useState(undefined); |
| 32 |
let [restoreIDS, setRestoreIDS] = useState([]); |
| 33 |
let [LoaderIDS, setLoaderIDS] = useState([]); |
| 34 |
const [searchKeyword, setSearchKeyword] = useState(''); |
| 35 |
const debouncedKeyword = useDebounce(searchKeyword); |
| 36 |
const [queryParams, setQueryParams] = useState({ |
| 37 |
per_page:20, |
| 38 |
// Default the "All Docs" panel to every status (drafts included), not just |
| 39 |
// published — otherwise generated sample docs, which are inserted as drafts, |
| 40 |
// aren't counted (totalItems stays 0 → isEmptyKB → "No Category Found") and |
| 41 |
// don't appear in the list until one is published. |
| 42 |
status:post_status || 'any', |
| 43 |
page:1, |
| 44 |
...(mkbFilterValue != '' ? {'knowledge_base_slug': mkbFilterValue} : {}) |
| 45 |
}); |
| 46 |
|
| 47 |
const { data: docs, isLoading, error, totalPages, totalItems, setRefetch, setIsLoading, setData:setDocsData} = useFetch({ |
| 48 |
path: addQueryArgs(`/wp/v2/docs`, queryParams), |
| 49 |
parse: false |
| 50 |
}); |
| 51 |
|
| 52 |
// Doc-category count — the empty state must agree with the grid view (and with the |
| 53 |
// server's kb_is_empty(), which is "no categories AND no docs"). A knowledge base |
| 54 |
// with categories but no docs yet is NOT empty: the grid shows those categories, so |
| 55 |
// the list must show the table (which renders its own "No Docs Found") rather than |
| 56 |
// the onboarding panel. Only the term count is needed, hence per_page=1 + the header. |
| 57 |
const langParam = betterdocs_admin?.current_admin_language ? { lang: betterdocs_admin.current_admin_language } : {}; |
| 58 |
const { isLoading: categoriesLoading, data: categoryCount } = useQuery( |
| 59 |
["docCategoriesCount", langParam], |
| 60 |
() => |
| 61 |
apiFetch({ |
| 62 |
path: addQueryArgs("wp/v2/doc_category", { per_page: 1, hide_empty: false, _fields: "id", ...langParam }), |
| 63 |
method: "GET", |
| 64 |
parse: false, |
| 65 |
}).then((response) => Number(response.headers.get("x-wp-total") || 0)), |
| 66 |
{ refetchOnMount: false, cacheTime: 0 } |
| 67 |
); |
| 68 |
|
| 69 |
const navigate = useNavigate(); |
| 70 |
|
| 71 |
const { quickAction, docId } = data; |
| 72 |
|
| 73 |
/** |
| 74 |
* This Effect Runs When Keyword Has Been Placed |
| 75 |
*/ |
| 76 |
useEffect(() => { |
| 77 |
if( ! isLoading ) { |
| 78 |
let defaultParams; |
| 79 |
if( debouncedKeyword != '' ) { |
| 80 |
defaultParams = { |
| 81 |
...(filterOptions != '' ? filterOptions : {} ), |
| 82 |
page:1, |
| 83 |
per_page:20, |
| 84 |
status:'any', |
| 85 |
search:debouncedKeyword |
| 86 |
}; |
| 87 |
} else { |
| 88 |
defaultParams = { |
| 89 |
...(filterOptions != '' ? filterOptions : {} ), |
| 90 |
page:1, |
| 91 |
status:'any', |
| 92 |
per_page:20, |
| 93 |
} |
| 94 |
} |
| 95 |
setIsLoading(true); |
| 96 |
setQueryParams({...defaultParams}); |
| 97 |
} |
| 98 |
}, [debouncedKeyword]); |
| 99 |
|
| 100 |
/** |
| 101 |
* If The Post Status Is Changes Set The Current Page to 1 For Trash/Any |
| 102 |
*/ |
| 103 |
useEffect(() => { |
| 104 |
if( ! isLoading ) { |
| 105 |
let defaultParams = { |
| 106 |
page:1, |
| 107 |
status:post_status || 'any', |
| 108 |
per_page:20, |
| 109 |
page:1 |
| 110 |
}; |
| 111 |
setQueryParams((prevState) => { |
| 112 |
setIsLoading(true); |
| 113 |
return {...defaultParams}; |
| 114 |
}); |
| 115 |
} |
| 116 |
if( bulkData?.length > 0 ){ |
| 117 |
setBulkData([]); |
| 118 |
} |
| 119 |
}, [post_status]); |
| 120 |
|
| 121 |
/** |
| 122 |
* This Effect Runs for mkb filter and search value are not empty |
| 123 |
*/ |
| 124 |
useEffect(() => { |
| 125 |
if( ! isLoading ) { |
| 126 |
if( post_status != 'trash' ) { |
| 127 |
setQueryParams((prevState) => { |
| 128 |
if( mkbFilterValue == '' ){ |
| 129 |
if( prevState['knowledge_base_slug'] != undefined ){ |
| 130 |
setIsLoading(true); |
| 131 |
delete prevState['knowledge_base_slug']; |
| 132 |
} |
| 133 |
} else { |
| 134 |
setIsLoading(true); |
| 135 |
prevState['knowledge_base_slug'] = mkbFilterValue; |
| 136 |
} |
| 137 |
|
| 138 |
return {...queryParams, ...prevState}; |
| 139 |
}); |
| 140 |
} |
| 141 |
} |
| 142 |
}, [mkbFilterValue, post_status]); |
| 143 |
|
| 144 |
useEffect(() => { |
| 145 |
if( quickAction != undefined ) { |
| 146 |
let { action, docId, forceDelete } = quickAction; |
| 147 |
|
| 148 |
if( action == 'trash' ){ |
| 149 |
LoaderIDS.push(docId); |
| 150 |
setLoaderIDS([...LoaderIDS]); |
| 151 |
wp.apiFetch({ path: `/wp/v2/docs/${docId}`, method:'DELETE'} ).then((result) => { |
| 152 |
if( result != undefined ){ |
| 153 |
let docsUpdated = docs?.filter((doc) => { |
| 154 |
return doc?.id != docId; |
| 155 |
}); |
| 156 |
if(typeof refetch == 'function'){ //refetch when trash is initiated |
| 157 |
refetch(true); |
| 158 |
} |
| 159 |
setDocsData([...docsUpdated]); |
| 160 |
setTimeout(() => { |
| 161 |
setLoaderIDS([]); |
| 162 |
}, 1000); |
| 163 |
setData((data) => { |
| 164 |
return {...data, quickAction:{}}; |
| 165 |
}); |
| 166 |
if( docsUpdated?.length == 0 ) { //when docs are zero in list and post_type 'any', set loading to true and refetch |
| 167 |
setIsLoading(true); |
| 168 |
setRefetch(true); |
| 169 |
} |
| 170 |
} |
| 171 |
}).catch((error) => { |
| 172 |
setData((data) => { |
| 173 |
return {...data, quickAction:{}}; |
| 174 |
}); |
| 175 |
setTimeout(() => { |
| 176 |
setLoaderIDS([]); |
| 177 |
}, 1000); |
| 178 |
}); |
| 179 |
} |
| 180 |
|
| 181 |
if( action == 'permanent-delete' ) { |
| 182 |
Swal.fire({ |
| 183 |
title: __("Are you sure you want to permanently delete this post?", "betterdocs"), |
| 184 |
icon: "warning", |
| 185 |
showConfirmButton: true, |
| 186 |
showCancelButton:true, |
| 187 |
confirmButtonText: __('Yes', 'betterdocs'), |
| 188 |
cancelButtonText: __('No', 'betterdocs'), |
| 189 |
customClass: { |
| 190 |
popup: 'betterdocs-bulk-action-popup' |
| 191 |
} |
| 192 |
}).then((result) => { |
| 193 |
if(result?.isConfirmed){ |
| 194 |
LoaderIDS.push(docId); |
| 195 |
setLoaderIDS([...LoaderIDS]); |
| 196 |
wp.apiFetch({ path: `/wp/v2/docs/${docId}`, method:'DELETE', data:{'force':true}} ).then((result) => { |
| 197 |
if( result != undefined ){ |
| 198 |
let docsUpdated = docs?.filter((doc) => { |
| 199 |
return doc?.id != docId; |
| 200 |
}); |
| 201 |
if(typeof refetch == 'function'){ //refetch when permanent-delete is initiated |
| 202 |
refetch(true); |
| 203 |
} |
| 204 |
setDocsData([...docsUpdated]); |
| 205 |
setTimeout(() => { |
| 206 |
setLoaderIDS([]); |
| 207 |
}, 1000); |
| 208 |
setData((data) => { |
| 209 |
return {...data, quickAction:{}}; |
| 210 |
}); |
| 211 |
if( docsUpdated?.length == 0 && totalPages == 1 ) { //when docs are zero, set default query params and redirect to post_type 'any' |
| 212 |
setQueryParams((prevState) => { |
| 213 |
return {...prevState, status:'any', page:1}; |
| 214 |
}) |
| 215 |
navigate(makeRouteURL("betterdocs-admin", { |
| 216 |
mode: "list", |
| 217 |
post_status: "any", |
| 218 |
})); |
| 219 |
} else if ( docsUpdated?.length == 0 ) { //refetch when docs are zero |
| 220 |
setIsLoading(true); |
| 221 |
setRefetch(true); |
| 222 |
} |
| 223 |
} |
| 224 |
}).catch((error) => { |
| 225 |
toast.error(__('Failed To Delete Permanently', 'betterdocs')); |
| 226 |
setData((data) => { |
| 227 |
return {...data, quickAction:{}}; |
| 228 |
}); |
| 229 |
setTimeout(() => { |
| 230 |
setLoaderIDS([]); |
| 231 |
}, 1000); |
| 232 |
}); |
| 233 |
} |
| 234 |
}); |
| 235 |
} |
| 236 |
|
| 237 |
if( action == 'bulk-delete' ){ |
| 238 |
let data = {}; |
| 239 |
let docsUpdated = docs; |
| 240 |
let updatedLoaders = LoaderIDS; |
| 241 |
if( forceDelete != undefined ) { |
| 242 |
data['force'] = forceDelete ? true : false; |
| 243 |
} |
| 244 |
//delete bulk data |
| 245 |
for( let id of bulkData ) { |
| 246 |
wp.apiFetch({ path: `/wp/v2/docs/${id}`, method:'DELETE', data:data } ).then((result) => { |
| 247 |
if(result != undefined){ |
| 248 |
docsUpdated = docsUpdated?.filter((doc) => { |
| 249 |
return doc?.id != id; |
| 250 |
}); |
| 251 |
updatedLoaders = updatedLoaders?.filter((docId) => { |
| 252 |
return docId != id; |
| 253 |
}); |
| 254 |
if(typeof refetch == 'function' && post_status == 'any' || typeof refetch == 'function' && post_status == 'trash' || typeof refetch == 'function' && post_status == undefined){ //refetch the trash count whenever bulk delete is initiated |
| 255 |
refetch(true); |
| 256 |
} |
| 257 |
setDocsData([...docsUpdated]); |
| 258 |
setLoaderIDS([...updatedLoaders]); |
| 259 |
if(docsUpdated?.length == 0 && post_status == 'any'){ //when list is empty refetch for more docs, and initiate loading effect |
| 260 |
setIsLoading(true); |
| 261 |
setRefetch(true); |
| 262 |
} |
| 263 |
if(docsUpdated?.length == 0 && post_status == 'trash' && totalPages == 1){ //when docs are zero in the list for bulk-delete & has only a single page, set default query params and redirect to post type 'any' |
| 264 |
setQueryParams((prevState) => { |
| 265 |
return {...prevState, status:'any', page:1}; |
| 266 |
}); |
| 267 |
navigate(makeRouteURL("betterdocs-admin", { |
| 268 |
mode: "list", |
| 269 |
post_status: "any", |
| 270 |
})); |
| 271 |
} else if (docsUpdated?.length == 0 && post_status == 'trash') { //refetch when docs are zero and post_status is trash |
| 272 |
setIsLoading(true); |
| 273 |
setRefetch(true); |
| 274 |
} |
| 275 |
} |
| 276 |
}); |
| 277 |
} |
| 278 |
setBulkData([]); |
| 279 |
setData((data) => { |
| 280 |
return {...data, quickAction:{}}; |
| 281 |
}); |
| 282 |
} |
| 283 |
|
| 284 |
if( action =='restore' ) { |
| 285 |
let statusUpdatedDoc = {'status':'publish'}; |
| 286 |
restoreIDS.push(docId); |
| 287 |
setRestoreIDS([...restoreIDS]); |
| 288 |
wp.apiFetch({ |
| 289 |
path: `/wp/v2/docs/${docId}`, |
| 290 |
method: "POST", |
| 291 |
data: statusUpdatedDoc, |
| 292 |
}).then((result) => { |
| 293 |
if(result != undefined){ |
| 294 |
let docsUpdated = docs?.filter((doc) => { |
| 295 |
return doc?.id != docId; |
| 296 |
}); |
| 297 |
if(typeof refetch == 'function'){ //refetch when restore is initiated |
| 298 |
refetch(true); |
| 299 |
} |
| 300 |
setDocsData([...docsUpdated]); |
| 301 |
setData((data) => { |
| 302 |
return {...data, quickAction:{}}; |
| 303 |
}); |
| 304 |
setTimeout(() => { |
| 305 |
setRestoreIDS([]) |
| 306 |
}, 1000); |
| 307 |
if(docsUpdated?.length == 0 && totalPages == 1) { //when docs are zero in the list for bulk-delete and total pages are 1, set default query params and redirect to post type 'any' |
| 308 |
setQueryParams((prevState) => { |
| 309 |
return {...prevState, status:'any', page:1}; |
| 310 |
}); |
| 311 |
navigate(makeRouteURL("betterdocs-admin", { |
| 312 |
mode: "list", |
| 313 |
post_status: "any", |
| 314 |
})); |
| 315 |
} else if ( docsUpdated?.length == 0 ) { //refetch when docs are zero |
| 316 |
setIsLoading(true); |
| 317 |
setRefetch(true); |
| 318 |
} |
| 319 |
} |
| 320 |
}).catch((error) => { |
| 321 |
setTimeout(() => { |
| 322 |
setRestoreIDS([]) |
| 323 |
}, 1000); |
| 324 |
setData((data) => { |
| 325 |
return {...data, quickAction:{}}; |
| 326 |
}); |
| 327 |
}); |
| 328 |
} |
| 329 |
|
| 330 |
if( action == 'bulk-restore' ){ |
| 331 |
let statusUpdatedDoc = {'status':'publish'}; |
| 332 |
let docsUpdated = docs; |
| 333 |
let updatedLoaders = restoreIDS; |
| 334 |
for( let id of bulkData ) { |
| 335 |
wp.apiFetch({ |
| 336 |
path: `/wp/v2/docs/${id}`, |
| 337 |
method: "POST", |
| 338 |
data: statusUpdatedDoc, |
| 339 |
}).then((result) => { |
| 340 |
if(result != undefined){ |
| 341 |
docsUpdated = docsUpdated?.filter((doc) => { |
| 342 |
return doc?.id != id; |
| 343 |
}); |
| 344 |
updatedLoaders = updatedLoaders?.filter((docId) => { |
| 345 |
return docId != id; |
| 346 |
}); |
| 347 |
if(typeof refetch == 'function'){ //refetch when bulk-restore is initiated |
| 348 |
refetch(true); |
| 349 |
} |
| 350 |
setDocsData([...docsUpdated]); |
| 351 |
setRestoreIDS([...updatedLoaders]); |
| 352 |
if( docsUpdated?.length == 0 && post_status == 'trash' && totalPages == 1 ){ //when docs are zero in the list for bulk-restore & total pages are 1, set default query params and redirect to post type 'any' |
| 353 |
setQueryParams((prevState) => { |
| 354 |
return {...prevState, status:'any', page:1}; |
| 355 |
}); |
| 356 |
navigate(makeRouteURL("betterdocs-admin", { |
| 357 |
mode: "list", |
| 358 |
post_status: "any", |
| 359 |
})); |
| 360 |
} else if ( docsUpdated?.length == 0 && post_status == 'trash' ) { //refetch when docs are zero and post_status is trash |
| 361 |
setIsLoading(true); |
| 362 |
setRefetch(true); |
| 363 |
} |
| 364 |
} |
| 365 |
}) |
| 366 |
} |
| 367 |
setBulkData([]); |
| 368 |
setData((data) => { |
| 369 |
return {...data, quickAction:{}}; |
| 370 |
}); |
| 371 |
} |
| 372 |
} |
| 373 |
}, [quickAction]); |
| 374 |
|
| 375 |
/** |
| 376 |
* Effect Runs When Filters Are Triggered |
| 377 |
*/ |
| 378 |
useEffect(() => { |
| 379 |
let defaultParams = { |
| 380 |
...queryParams, |
| 381 |
page:1, |
| 382 |
per_page:20, |
| 383 |
status:'any', |
| 384 |
} |
| 385 |
setQueryParams((prevState) => { |
| 386 |
if( filterOptions != undefined && Object.keys(filterOptions)?.length > 0 ) { |
| 387 |
defaultParams = objectDifference(prevState, filterOptions, ['author', 'doc_category', 'year_month', 'status', 'order']); |
| 388 |
setIsLoading(true); |
| 389 |
return {...defaultParams, ...filterOptions}; |
| 390 |
} |
| 391 |
if( filterOptions != undefined && Object.keys(filterOptions)?.length == 0 ) { |
| 392 |
defaultParams = objectDifference(prevState, filterOptions, ['author', 'doc_category', 'year_month', 'status', 'order']); |
| 393 |
setIsLoading(true); |
| 394 |
return {...defaultParams, status:'any'}; |
| 395 |
} |
| 396 |
return prevState; |
| 397 |
}); |
| 398 |
}, [filterOptions]); |
| 399 |
|
| 400 |
// Empty knowledge base: no docs at all, default view, no search / MKB filter. |
| 401 |
// Show the sample-doc generation panel only (hide the filter bar + table), |
| 402 |
// matching the grid view's empty state. |
| 403 |
const defaultView = post_status !== 'trash' |
| 404 |
&& !searchKeyword?.trim() |
| 405 |
&& (mkbFilterValue == null || mkbFilterValue === ''); |
| 406 |
// Genuinely-empty KB is known server-side at page load, so during the initial |
| 407 |
// fetch show a skeleton shaped like the No Category Found card instead of the |
| 408 |
// row skeleton it would immediately replace. |
| 409 |
const showEmptyLoader = (isLoading || categoriesLoading) && defaultView && Boolean(window.betterdocs_admin?.kb_is_empty); |
| 410 |
// No docs AND no categories — otherwise the categories the grid view happily shows |
| 411 |
// would be hidden here behind the onboarding panel. |
| 412 |
const isEmptyKB = !isLoading |
| 413 |
&& !categoriesLoading |
| 414 |
&& Number(totalItems) === 0 |
| 415 |
&& Number(categoryCount || 0) === 0 |
| 416 |
&& defaultView; |
| 417 |
|
| 418 |
return ( |
| 419 |
<section className="betterdocs-dashboard-body betterdocs-dashboard-category-list" onClick={(e) => { |
| 420 |
if( data?.isListMenuOpen ) { |
| 421 |
setData((state) => ({...state, isListMenuOpen:false})); |
| 422 |
} |
| 423 |
}}> |
| 424 |
<div className="betterdocs-dashboard-container"> |
| 425 |
{showEmptyLoader && <NoDocsLoader />} |
| 426 |
{isEmptyKB && <NoDocsBody isDocs={false} />} |
| 427 |
{!isEmptyKB && !showEmptyLoader && post_status != 'trash' && <div className="betterdocs-dashboard-category-list-filter"> |
| 428 |
<div className="betterdocs-row"> |
| 429 |
<div className="betterdocs-col betterdocs-col-md-3"> |
| 430 |
<AllDocsSearch |
| 431 |
setSearchKeyword={setSearchKeyword} |
| 432 |
/> |
| 433 |
</div> |
| 434 |
<div className="betterdocs-col betterdocs-col-md-9"> |
| 435 |
<div className="betterdocs-dashboard-filter-wrap"> |
| 436 |
<AllDocsFilter |
| 437 |
onFilterSelect={setFilterOptions} |
| 438 |
/> |
| 439 |
</div> |
| 440 |
</div> |
| 441 |
</div> |
| 442 |
</div>} |
| 443 |
{bulkData?.length > 0 && <div className="betterdocs-dashboard-bulk-option"> |
| 444 |
<div className="betterdocs-row"> |
| 445 |
<div className="betterdocs-col betterdocs-col-md-6"> |
| 446 |
{/* <span className="betterdocs-dashboard-custom-checkbox"> |
| 447 |
<input id="bulk-items" type="checkbox" checked={bulkData?.length > 0 ? true : false} onClick={(e) => { |
| 448 |
setBulkData([]); |
| 449 |
}}></input> |
| 450 |
<label For="bulk-items"></label> |
| 451 |
</span> */} |
| 452 |
<h5 className="bulk-option-item-count"> |
| 453 |
<span>{sprintf(_n('%d Item Selected', '%d Items Selected', bulkData?.length, 'betterdocs'), bulkData?.length)}</span> |
| 454 |
</h5> |
| 455 |
</div> |
| 456 |
<div className="betterdocs-col betterdocs-col-md-6"> |
| 457 |
<div className="betterdocs-dashboard-bulk-option-actions"> |
| 458 |
<button |
| 459 |
className="bulk-option-action-btn" |
| 460 |
type="button" |
| 461 |
onClick={(e) => { |
| 462 |
Swal.fire({ |
| 463 |
text: post_status == 'any' |
| 464 |
? sprintf(_n("Are you sure you want to move %d Doc to the trash?", "Are you sure you want to move %d Docs to the trash?", bulkData?.length, "betterdocs"), bulkData?.length) |
| 465 |
: sprintf(_n("Are you sure you want to permanently delete %d Doc?", "Are you sure you want to permanently delete %d Docs?", bulkData?.length, "betterdocs"), bulkData?.length), |
| 466 |
icon: "warning", |
| 467 |
showConfirmButton: true, |
| 468 |
showCancelButton:true, |
| 469 |
confirmButtonText: __('Yes', 'betterdocs'), |
| 470 |
cancelButtonText: __('No', 'betterdocs'), |
| 471 |
customClass: { |
| 472 |
popup: 'betterdocs-bulk-action-popup' |
| 473 |
} |
| 474 |
}).then((result) => { |
| 475 |
if( result?.isConfirmed ) { |
| 476 |
setLoaderIDS([...bulkData]); |
| 477 |
setData((state) => { |
| 478 |
return {...state, quickAction:{action:'bulk-delete', forceDelete:post_status == 'trash' ? true : false}} |
| 479 |
}); |
| 480 |
} |
| 481 |
}); |
| 482 |
}} |
| 483 |
> |
| 484 |
{post_status == 'trash' ? __('Delete Permanently', 'betterdocs') : __("Move to Trash", 'betterdocs')} |
| 485 |
</button> |
| 486 |
{post_status == 'trash' && <button |
| 487 |
className="bulk-option-action-btn" |
| 488 |
type="button" |
| 489 |
onClick={(e) => { |
| 490 |
Swal.fire({ |
| 491 |
text: sprintf(_n("Are you sure you want to restore %d Doc?", "Are you sure you want to restore %d Docs?", bulkData?.length, "betterdocs"), bulkData?.length), |
| 492 |
icon: "warning", |
| 493 |
showConfirmButton: true, |
| 494 |
showCancelButton:true, |
| 495 |
confirmButtonText: __('Yes', 'betterdocs'), |
| 496 |
cancelButtonText: __('No', 'betterdocs'), |
| 497 |
customClass: { |
| 498 |
popup: 'betterdocs-bulk-action-popup' |
| 499 |
} |
| 500 |
}).then((result) => { |
| 501 |
if( result?.isConfirmed ) { |
| 502 |
setRestoreIDS([...bulkData]); |
| 503 |
setData((state) => { |
| 504 |
return {...state, quickAction:{action:'bulk-restore'}} |
| 505 |
}); |
| 506 |
} |
| 507 |
}); |
| 508 |
}} |
| 509 |
> |
| 510 |
{__('Restore', 'betterdocs')} |
| 511 |
</button>} |
| 512 |
</div> |
| 513 |
</div> |
| 514 |
</div> |
| 515 |
</div>} |
| 516 |
{!isEmptyKB && !showEmptyLoader && <div className="betterdocs-dashboard-item-list-wrap"> |
| 517 |
<AllDocsListTable |
| 518 |
setLoading={setIsLoading} |
| 519 |
onFilterSelect={setFilterOptions} |
| 520 |
docs={docs} |
| 521 |
totalItems={totalItems} |
| 522 |
totalPages={totalPages} |
| 523 |
setCurrentPage={setQueryParams} |
| 524 |
currentPage={queryParams?.page} |
| 525 |
perPage={queryParams?.per_page} |
| 526 |
bulkData={bulkData} |
| 527 |
setBulkData={setBulkData} |
| 528 |
status={post_status} |
| 529 |
setLoaderIDS={setLoaderIDS} |
| 530 |
loaderIDS={LoaderIDS} |
| 531 |
isLoading={isLoading} |
| 532 |
restoreIDS={restoreIDS} |
| 533 |
/> |
| 534 |
{data?.isOpen && <QuickEdit setDocuments={setDocsData}/>} |
| 535 |
</div>} |
| 536 |
</div> |
| 537 |
</section> |
| 538 |
); |
| 539 |
}; |
| 540 |
|
| 541 |
export default AllDocsList; |
| 542 |
|