Skip to content

Commit 8cd6168

Browse files
authored
feat(project-tree): delete all checked items (#31004)
1 parent 14221c2 commit 8cd6168

File tree

2 files changed

+39
-8
lines changed

2 files changed

+39
-8
lines changed

frontend/src/layout/panel-layout/ProjectTree/ProjectTree.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export function ProjectTree(): JSX.Element {
4242
onItemChecked,
4343
moveCheckedItems,
4444
linkCheckedItems,
45+
deleteCheckedItems,
4546
setCheckedItems,
4647
assureVisibility,
4748
} = useActions(projectTreeLogic)
@@ -78,7 +79,7 @@ export function ProjectTree(): JSX.Element {
7879
<ButtonPrimitive menuItem>{checkedItems[item.id] ? 'Deselect' : 'Select'}</ButtonPrimitive>
7980
</MenuItem>
8081
) : null}
81-
{checkedItemsCount !== '0' && item.record?.type === 'folder' ? (
82+
{checkedItemCountNumeric > 0 && item.record?.type === 'folder' ? (
8283
<MenuItem
8384
asChild
8485
onClick={(e: any) => {
@@ -91,7 +92,7 @@ export function ProjectTree(): JSX.Element {
9192
</ButtonPrimitive>
9293
</MenuItem>
9394
) : null}
94-
{checkedItemsCount !== '0' && item.record?.type === 'folder' ? (
95+
{checkedItemCountNumeric > 0 && item.record?.type === 'folder' ? (
9596
<MenuItem
9697
asChild
9798
onClick={(e: any) => {
@@ -140,16 +141,24 @@ export function ProjectTree(): JSX.Element {
140141
<ButtonPrimitive menuItem>Rename</ButtonPrimitive>
141142
</MenuItem>
142143
) : null}
143-
{item.record?.created_at || item.record?.type === 'folder' ? (
144+
{item.record?.id || item.record?.type === 'folder' ? (
144145
<MenuItem
145146
asChild
146147
onClick={(e: any) => {
147148
e.stopPropagation()
148-
deleteItem(item.record as unknown as FileSystemEntry)
149+
if (checkedItemCountNumeric > 1 && checkedItems[item.id]) {
150+
deleteCheckedItems()
151+
} else {
152+
deleteItem(item.record as unknown as FileSystemEntry)
153+
}
149154
}}
150155
>
151156
<ButtonPrimitive menuItem>
152-
{item.record?.shortcut ? 'Remove shortcut' : "Delete and move back to 'Unfiled'"}
157+
{checkedItemCountNumeric > 1 && checkedItems[item.id]
158+
? `Delete ${checkedItemsCount} item${checkedItemCountNumeric === 1 ? '' : 's'}`
159+
: item.record?.shortcut
160+
? 'Remove shortcut'
161+
: "Delete and move back to 'Unfiled'"}
153162
</ButtonPrimitive>
154163
</MenuItem>
155164
) : null}
@@ -197,7 +206,7 @@ export function ProjectTree(): JSX.Element {
197206
<ButtonPrimitive onClick={() => createFolder('')} tooltip="New root folder">
198207
<IconFolderPlus className="text-tertiary" />
199208
</ButtonPrimitive>
200-
{checkedItemsCount !== '0' && checkedItemsCount !== '0+' ? (
209+
{checkedItemCountNumeric > 0 && checkedItemsCount !== '0+' ? (
201210
<ButtonPrimitive onClick={() => setCheckedItems({})} tooltip="Clear">
202211
<LemonTag type="highlight">{checkedItemsCount} selected</LemonTag>
203212
</ButtonPrimitive>
@@ -217,7 +226,7 @@ export function ProjectTree(): JSX.Element {
217226
}
218227
return window.location.href.endsWith(item.record?.href)
219228
}}
220-
enableMultiSelection={checkedItemsCount !== '0'}
229+
enableMultiSelection={checkedItemCountNumeric > 0}
221230
onItemChecked={onItemChecked}
222231
checkedItemCount={checkedItemCountNumeric}
223232
onNodeClick={(node) => {

frontend/src/layout/panel-layout/ProjectTree/projectTreeLogic.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export const projectTreeLogic = kea<projectTreeLogicType>([
7676
expandProjectFolder: (path: string) => ({ path }),
7777
moveCheckedItems: (path: string) => ({ path }),
7878
linkCheckedItems: (path: string) => ({ path }),
79+
deleteCheckedItems: true,
7980
checkSelectedFolders: true,
8081
syncTypeAndRef: (type: string, ref: string) => ({ type, ref }),
8182
updateSyncedFiles: (files: FileSystemEntry[]) => ({ files }),
@@ -509,7 +510,8 @@ export const projectTreeLogic = kea<projectTreeLogicType>([
509510
],
510511
sortedItems: [
511512
(s) => [s.viableItems],
512-
(viableItems): FileSystemEntry[] => [...viableItems].sort((a, b) => a.path.localeCompare(b.path)),
513+
(viableItems): FileSystemEntry[] =>
514+
[...viableItems].sort((a, b) => (a.path > b.path ? 1 : a.path < b.path ? -1 : 0)),
513515
],
514516
viableItemsById: [
515517
(s) => [s.viableItems],
@@ -913,6 +915,26 @@ export const projectTreeLogic = kea<projectTreeLogicType>([
913915
})
914916
}
915917
},
918+
deleteCheckedItems: () => {
919+
const { checkedItems } = values
920+
let skipInFolder: string | null = null
921+
for (const item of values.sortedItems) {
922+
if (skipInFolder !== null) {
923+
if (item.path.startsWith(skipInFolder + '/')) {
924+
continue
925+
} else {
926+
skipInFolder = null
927+
}
928+
}
929+
const itemId = item.type === 'folder' ? `project-folder/${item.path}` : `project/${item.id}`
930+
if (checkedItems[itemId]) {
931+
actions.deleteItem(item)
932+
if (item.type === 'folder') {
933+
skipInFolder = item.path
934+
}
935+
}
936+
}
937+
},
916938
deleteItem: async ({ item }) => {
917939
if (!item.id) {
918940
const response = await api.fileSystem.list({ type: 'folder', path: item.path })

0 commit comments

Comments
 (0)