PluginProbe
Code Snippets / 3.10.0
Code Snippets v3.10.0
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
code-snippets / js / components / ManageMenu / SnippetsTable / useApplyBulkAction.ts

useApplyBulkAction.ts in Code Snippets 3.10.0, at js/components/ManageMenu/SnippetsTable/useApplyBulkAction.ts

149 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { __ } from '@wordpress/i18n'
2 import { useSnippetsAPI } from '../../../hooks/useSnippetsAPI'
3 import { useSnippetsList } from '../../../hooks/useSnippetsList'
4 import { handleUnknownError } from '../../../utils/errors'
5 import { downloadBulkSnippetExportFile } from '../../../utils/files'
6 import { cloneSnippetObject } from '../../../utils/snippets/snippets'
7 import type { ListTableAction } from '../../common/ListTable'
8 import type { Snippet } from '../../../types/Snippet'
9
10 export type SnippetsTableAction =
11 'activate' | 'deactivate' |
12 'clone' | 'export' | 'download' |
13 'trash' | 'restore' | 'delete'
14
15 export const BULK_ACTIONS: ListTableAction<SnippetsTableAction>[] = [
16 { key: 'activate', label: __('Activate', 'code-snippets') },
17 { key: 'deactivate', label: __('Deactivate', 'code-snippets') },
18 { key: 'clone', label: __('Clone', 'code-snippets') },
19 { key: 'export', label: __('Export', 'code-snippets') },
20 { key: 'download', label: __('Download', 'code-snippets') },
21 { key: 'trash', label: __('Trash', 'code-snippets') }
22 ]
23
24 export const TRASHED_BULK_ACTIONS: ListTableAction<SnippetsTableAction>[] = [
25 { key: 'restore', label: __('Restore', 'code-snippets') },
26 { key: 'delete', label: __('Delete Permanently', 'code-snippets') }
27 ]
28
29 const BULK_DOWNLOAD_ACTION = 'bulk-download'
30 const INDIVIDUAL_DOWNLOAD_DELAY_MS = 200
31
32 const submitBulkSnippetDownload = (snippets: readonly Snippet[]): Promise<void> => {
33 if (0 === snippets.length) {
34 return Promise.resolve()
35 }
36
37 const form = document.createElement('form')
38
39 const appendHiddenField = (name: string, value: string) => {
40 const input = document.createElement('input')
41 input.type = 'hidden'
42 input.name = name
43 input.value = value
44 form.appendChild(input)
45 }
46
47 form.method = 'post'
48 form.action = window.location.href
49 form.hidden = true
50
51 appendHiddenField('code_snippets_action', BULK_DOWNLOAD_ACTION)
52 appendHiddenField('code_snippets_bulk_download_nonce', window.CODE_SNIPPETS_MANAGE?.bulkDownloadNonce ?? '')
53 appendHiddenField(
54 'snippets',
55 JSON.stringify(snippets.map(({ id, network }) => ({ id, network })))
56 )
57
58 document.body.appendChild(form)
59 form.submit()
60
61 window.setTimeout(() => {
62 form.remove()
63 }, 0)
64
65 return Promise.resolve()
66 }
67
68 const submitBulkSnippetDownloadsIndividually = (snippets: readonly Snippet[]): Promise<void> =>
69 snippets.reduce(
70 (promise, snippet) =>
71 promise.then(
72 () =>
73 new Promise<void>(resolve => {
74 void submitBulkSnippetDownload([snippet])
75 window.setTimeout(resolve, INDIVIDUAL_DOWNLOAD_DELAY_MS)
76 })
77 ),
78 Promise.resolve()
79 )
80
81 const applyAndRefresh = async (
82 targets: Snippet[],
83 action: (snippet: Snippet) => Promise<Snippet> | Promise<void>,
84 refresh: () => Promise<void>
85 ): Promise<void> => {
86 if (0 < targets.length) {
87 for (const snippet of targets) {
88 await action(snippet).catch(handleUnknownError)
89 }
90
91 await refresh()
92 }
93 }
94
95 export const useApplyBulkAction = (
96 allSnippets: Snippet[]
97 ): (action: SnippetsTableAction | undefined, selected: Set<Snippet['id']>) => Promise<void> => {
98 const api = useSnippetsAPI()
99 const { refreshSnippetsList } = useSnippetsList()
100
101 return async (action, selected) => {
102 switch (action) {
103 case 'activate':
104 await applyAndRefresh(
105 allSnippets.filter(snippet => selected.has(snippet.id) && !snippet.active),
106 snippet => api.activate({ id: snippet.id, network: snippet.network }),
107 refreshSnippetsList)
108 break
109
110 case 'deactivate':
111 await applyAndRefresh(
112 allSnippets.filter(snippet => selected.has(snippet.id) && snippet.active),
113 snippet => api.deactivate({ id: snippet.id, network: snippet.network }),
114 refreshSnippetsList)
115 break
116
117 case 'clone':
118 await applyAndRefresh(
119 allSnippets.filter(snippet => selected.has(snippet.id) && !snippet.trashed),
120 snippet => api.create(cloneSnippetObject(snippet)),
121 refreshSnippetsList)
122 break
123
124 case 'export':
125 downloadBulkSnippetExportFile(allSnippets.filter(snippet => selected.has(snippet.id)))
126 break
127
128 case 'download': {
129 const selectedSnippets = allSnippets.filter(snippet => selected.has(snippet.id))
130
131 return 1 < selectedSnippets.length && !window.CODE_SNIPPETS_MANAGE?.supportsZipDownloads
132 ? submitBulkSnippetDownloadsIndividually(selectedSnippets)
133 : submitBulkSnippetDownload(selectedSnippets)
134 }
135
136 case 'trash':
137 case 'delete':
138 await applyAndRefresh(
139 allSnippets.filter(snippet => selected.has(snippet.id)),
140 snippet => api.delete({ id: snippet.id, network: snippet.network }),
141 refreshSnippetsList)
142 break
143
144 case undefined:
145 break
146 }
147 }
148 }
149