Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 120 additions & 75 deletions src/js/components/ManageMenu/SnippetsTable/SnippetsListTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -252,113 +252,158 @@
</>
}

const useBulkActions = (allSnippets: Snippet[]): ListTableBulkAction<Snippet['id']>[] => {
const { activate, deactivate, delete: trashOrDelete, create } = useSnippetsAPI()
const useBulkActions = (

Check warning on line 255 in src/js/components/ManageMenu/SnippetsTable/SnippetsListTable.tsx

View workflow job for this annotation

GitHub Actions / stylelint, eslint, phpcs

Arrow function has too many lines (115). Maximum allowed is 50
currentSnippets: Snippet[],
currentStatus: SnippetStatus
): ListTableBulkAction<Snippet['id']>[] => {
const { activate, deactivate, delete: trashOrDelete, restore, create } = useSnippetsAPI()
const { refreshSnippetsList } = useSnippetsList()

return useMemo(
() => [
{
name: __('Activate', 'code-snippets'),
apply: async (selected: Set<Snippet['id']>) => {
const targets = allSnippets.filter(snippet => selected.has(snippet.id) && !snippet.active)

if (0 === targets.length) {
return
() => {

Check warning on line 263 in src/js/components/ManageMenu/SnippetsTable/SnippetsListTable.tsx

View workflow job for this annotation

GitHub Actions / stylelint, eslint, phpcs

Arrow function has too many lines (105). Maximum allowed is 50
if ('trashed' === currentStatus) {
return [
{
name: __('Restore', 'code-snippets'),
apply: async (selected: Set<Snippet['id']>) => {
const targets = currentSnippets.filter(snippet => selected.has(snippet.id) && snippet.trashed)

if (0 === targets.length) {
return
}

for (const snippet of targets) {
await restore({ id: snippet.id, network: snippet.network }).catch(handleUnknownError)
}

await refreshSnippetsList()
}
},
{
name: __('Delete Permanently', 'code-snippets'),
apply: async (selected: Set<Snippet['id']>) => {
const targets = currentSnippets.filter(snippet => selected.has(snippet.id) && snippet.trashed)

if (0 === targets.length) {
return
}

for (const snippet of targets) {
await trashOrDelete({ id: snippet.id, network: snippet.network }).catch(handleUnknownError)
}

await refreshSnippetsList()
}
}
]
}

for (const snippet of targets) {
await activate({ id: snippet.id, network: snippet.network }).catch(handleUnknownError)
}
return [
{
name: __('Activate', 'code-snippets'),
apply: async (selected: Set<Snippet['id']>) => {
const targets = currentSnippets.filter(snippet => selected.has(snippet.id) && !snippet.active)

await refreshSnippetsList()
}
},
{
name: __('Deactivate', 'code-snippets'),
apply: async (selected: Set<Snippet['id']>) => {
const targets = allSnippets.filter(snippet => selected.has(snippet.id) && snippet.active)
if (0 === targets.length) {
return
}

if (0 === targets.length) {
return
}
for (const snippet of targets) {
await activate({ id: snippet.id, network: snippet.network }).catch(handleUnknownError)
}

for (const snippet of targets) {
await deactivate({ id: snippet.id, network: snippet.network }).catch(handleUnknownError)
await refreshSnippetsList()
}
},
{
name: __('Deactivate', 'code-snippets'),
apply: async (selected: Set<Snippet['id']>) => {
const targets = currentSnippets.filter(snippet => selected.has(snippet.id) && snippet.active)

await refreshSnippetsList()
}
},
{
name: __('Clone', 'code-snippets'),
apply: async (selected: Set<Snippet['id']>) => {
const targets = allSnippets.filter(snippet => selected.has(snippet.id) && !snippet.trashed)
if (0 === targets.length) {
return
}

if (0 === targets.length) {
return
}
for (const snippet of targets) {
await deactivate({ id: snippet.id, network: snippet.network }).catch(handleUnknownError)
}

for (const snippet of targets) {
await create(cloneSnippetObject(snippet)).catch(handleUnknownError)
await refreshSnippetsList()
}
},
{
name: __('Clone', 'code-snippets'),
apply: async (selected: Set<Snippet['id']>) => {
const targets = currentSnippets.filter(snippet => selected.has(snippet.id) && !snippet.trashed)

await refreshSnippetsList()
}
},
{
name: __('Export', 'code-snippets'),
apply: (selected: Set<Snippet['id']>) => {
downloadBulkSnippetExportFile(
allSnippets.filter(snippet => selected.has(snippet.id))
)
return Promise.resolve()
}
},
{
name: __('Download', 'code-snippets'),
apply: (selected: Set<Snippet['id']>) => {
const selectedSnippets = allSnippets.filter(snippet => selected.has(snippet.id))
if (0 === targets.length) {
return
}

for (const snippet of targets) {
await create(cloneSnippetObject(snippet)).catch(handleUnknownError)
}

if (1 < selectedSnippets.length && !window.CODE_SNIPPETS_MANAGE?.supportsZipDownloads) {
return submitBulkSnippetDownloadsIndividually(selectedSnippets)
await refreshSnippetsList()
}
},
{
name: __('Export', 'code-snippets'),
apply: (selected: Set<Snippet['id']>) => {
downloadBulkSnippetExportFile(
currentSnippets.filter(snippet => selected.has(snippet.id))
)
return Promise.resolve()
}
},
{
name: __('Download', 'code-snippets'),
apply: (selected: Set<Snippet['id']>) => {
const selectedSnippets = currentSnippets.filter(snippet => selected.has(snippet.id))

return submitBulkSnippetDownload(selectedSnippets)
}
},
{
name: __('Trash', 'code-snippets'),
apply: async (selected: Set<Snippet['id']>) => {
const targets = allSnippets.filter(snippet => selected.has(snippet.id))
if (1 < selectedSnippets.length && !window.CODE_SNIPPETS_MANAGE?.supportsZipDownloads) {
return submitBulkSnippetDownloadsIndividually(selectedSnippets)
}

if (0 === targets.length) {
return
return submitBulkSnippetDownload(selectedSnippets)
}
},
{
name: __('Trash', 'code-snippets'),
apply: async (selected: Set<Snippet['id']>) => {
const targets = currentSnippets.filter(snippet => selected.has(snippet.id))

for (const snippet of targets) {
await trashOrDelete({ id: snippet.id, network: snippet.network }).catch(handleUnknownError)
}
if (0 === targets.length) {
return
}

for (const snippet of targets) {
await trashOrDelete({ id: snippet.id, network: snippet.network }).catch(handleUnknownError)
}

await refreshSnippetsList()
await refreshSnippetsList()
}
}
}
],
[allSnippets, activate, deactivate, trashOrDelete, create, refreshSnippetsList]
]
},
[currentSnippets, currentStatus, activate, deactivate, trashOrDelete, restore, create, refreshSnippetsList]
)
}

export const SnippetsListTable: React.FC = () => {

Check warning on line 393 in src/js/components/ManageMenu/SnippetsTable/SnippetsListTable.tsx

View workflow job for this annotation

GitHub Actions / stylelint, eslint, phpcs

Arrow function has too many lines (51). Maximum allowed is 50
const { currentStatus, setCurrentStatus } = useSnippetsFilters()
const { snippetsByStatus } = useFilteredSnippets()
const { hiddenColumns, truncateRowValues } = useManageTableSettings()

const allSnippets = useMemo(() => snippetsByStatus.get('all') ?? [], [snippetsByStatus])
const totalItems = snippetsByStatus.get(currentStatus)?.length ?? 0
const currentSnippets = useMemo(
() => snippetsByStatus.get(currentStatus) ?? [],
[snippetsByStatus, currentStatus]
)
const totalItems = currentSnippets.length
const itemsPerPage = window.CODE_SNIPPETS_MANAGE?.snippetsPerPage

const columns = useMemo(() => getTableColumns(hiddenColumns), [hiddenColumns])
const actions = useBulkActions(allSnippets)
const actions = useBulkActions(currentSnippets, currentStatus)

useEffect(() => {
if (INDEX_STATUS !== currentStatus && !snippetsByStatus.has(currentStatus)) {
Expand All @@ -380,7 +425,7 @@
</p>

<ListTable
items={snippetsByStatus.get(currentStatus) ?? []}
items={currentSnippets}
getKey={snippet => snippet.id}
ariaLabel={__('Snippets list', 'code-snippets')}
getCheckboxAriaLabel={(snippet: Snippet) => sprintf(
Expand Down
4 changes: 2 additions & 2 deletions src/js/components/ManageMenu/SnippetsTable/TableColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,14 @@ const ActionLinks = ({ snippet }: { snippet: Snippet }) => {
{__('Clone', 'code-snippets')}
</Button>)

const Export = () =>
const Export = !snippet.trashed && (() =>
<Button link onClick={() => {
api.export(snippet)
.then(response => downloadSnippetExportFile(response, snippet))
.catch(handleUnknownError)
}}>
{__('Export', 'code-snippets')}
</Button>
</Button>)

const Restore = snippet.trashed && (() =>
<Button link onClick={() => {
Expand Down
15 changes: 12 additions & 3 deletions src/php/REST_API/Snippets/Snippets_REST_Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -572,17 +572,26 @@ public function update_item( $request ) {
*/
public function delete_item( $request ) {
$item = $this->prepare_item_for_database( $request );
$snippet = get_snippet( $item->id, $item->network );

if ( $item->trashed ) {
return delete_snippet( $item->id, $item->network )
if ( ! $snippet || ! $snippet->id ) {
return new WP_Error(
'rest_cannot_delete',
__( 'The snippet could not be found.', 'code-snippets' ),
[ 'status' => 404 ]
);
}

if ( $snippet->trashed ) {
return delete_snippet( $snippet->id, $snippet->network )
? new WP_REST_Response( null, 204 )
: new WP_Error(
'rest_cannot_delete',
__( 'The snippet could not be deleted.', 'code-snippets' ),
[ 'status' => 500 ]
);
} else {
return trash_snippet( $item->id, $item->network )
return trash_snippet( $snippet->id, $snippet->network )
? $this->get_item( $request )
: new WP_Error(
'rest_cannot_trash',
Expand Down
Loading