Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 93c9e55

Browse files
feat: add ability to delete permanently in bulk
1 parent a5d685c commit 93c9e55

File tree

8 files changed

+126
-47
lines changed

8 files changed

+126
-47
lines changed

‎apps/app-server/src/trpc/api/groups/deletion/delete-permanently.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,21 @@ export async function deletePermanently({
3232
permission: 'editGroupSettings',
3333
});
3434

35-
// Check if group is deleted
35+
// Check if group is permanently deleted
36+
37+
const permanentlyDeletionDate = await ctx.dataAbstraction.hget(
38+
'group',
39+
input.groupId,
40+
'permanent-deletion-date',
41+
);
3642

3743
if (
38-
(await ctx.dataAbstraction.hget(
39-
'group',
40-
input.groupId,
41-
'permanent-deletion-date',
42-
)) == null
44+
permanentlyDeletionDate != null &&
45+
permanentlyDeletionDate < new Date()
4346
) {
4447
throw new TRPCError({
4548
code: 'BAD_REQUEST',
46-
message: 'Group is not deleted.',
49+
message: 'Group is already permanently deleted.',
4750
});
4851
}
4952

‎apps/app-server/src/trpc/api/pages/deletion/delete-permanently.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,21 @@ export async function deletePermanently({
4141
permission: 'editGroupPages',
4242
});
4343

44-
// Check if page is deleted
44+
// Check if page is permanently deleted
45+
46+
const permanentlyDeletionDate = await ctx.dataAbstraction.hget(
47+
'page',
48+
input.pageId,
49+
'permanent-deletion-date',
50+
);
4551

4652
if (
47-
(await ctx.dataAbstraction.hget(
48-
'page',
49-
input.pageId,
50-
'permanent-deletion-date',
51-
)) == null
53+
permanentlyDeletionDate != null &&
54+
permanentlyDeletionDate < new Date()
5255
) {
5356
throw new TRPCError({
5457
code: 'BAD_REQUEST',
55-
message: 'Page is not deleted.',
58+
message: 'Page is already permanently deleted.',
5659
});
5760
}
5861

‎apps/client/components.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ declare module '@vue/runtime-core' {
1818
CustomInfiniteScroll: typeof import('./src/components/CustomInfiniteScroll.vue')['default']
1919
DeepBtn: typeof import('./src/components/DeepBtn.vue')['default']
2020
DeepBtnDropdown: typeof import('./src/components/DeepBtnDropdown.vue')['default']
21+
DeletionDialog: typeof import('./src/components/DeletionDialog.vue')['default']
2122
DisplayBtn: typeof import('./src/components/DisplayBtn.vue')['default']
2223
EvaluatedPasswordField: typeof import('./src/components/EvaluatedPasswordField.vue')['default']
2324
Gap: typeof import('./src/components/Gap.vue')['default']
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<template>
2+
<q-dialog
3+
ref="dialogRef"
4+
@hide="onDialogHide"
5+
>
6+
<q-card :style="cardStyle">
7+
<q-card-section style="padding: 12px 20px">
8+
<div class="text-h6">Delete {{ subject }}</div>
9+
</q-card-section>
10+
11+
<q-card-section style="padding: 12px 20px">
12+
<div>
13+
Are you sure you want to delete
14+
{{ subject?.endsWith('s') ? 'these' : 'this' }} {{ subject }}?
15+
</div>
16+
17+
<Gap style="height: 10px" />
18+
19+
<div style="padding-left: 16px">
20+
<Checkbox
21+
v-model="deletePermanently"
22+
label="Delete permanently"
23+
/>
24+
</div>
25+
26+
<Gap style="height: 10px" />
27+
</q-card-section>
28+
29+
<q-card-actions align="right">
30+
<DeepBtn
31+
flat
32+
autofocus
33+
color="primary"
34+
label="No"
35+
@click="onDialogCancel"
36+
/>
37+
38+
<DeepBtn
39+
flat
40+
color="negative"
41+
label="Yes"
42+
@click="onDialogOK({ deletePermanently })"
43+
/>
44+
</q-card-actions>
45+
</q-card>
46+
</q-dialog>
47+
</template>
48+
49+
<script setup lang="ts">
50+
import type { QDialogProps } from 'quasar';
51+
52+
defineEmits([...useDialogPluginComponent.emits]);
53+
54+
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
55+
useDialogPluginComponent();
56+
57+
interface Props extends QDialogProps {
58+
cardStyle?: any;
59+
subject?: string;
60+
}
61+
62+
defineProps<Props>();
63+
64+
const deletePermanently = ref(false);
65+
</script>

‎apps/client/src/layouts/PagesLayout/LeftSidebar/SelectedPages.vue

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,11 @@
140140
import { negateProp, pluralS } from '@stdlib/misc';
141141
import type { QNotifyUpdateOptions } from 'quasar';
142142
import { deletePage } from 'src/code/api-interface/pages/deletion/delete';
143+
import { deletePagePermanently } from 'src/code/api-interface/pages/deletion/delete-permanently';
143144
import { movePage } from 'src/code/api-interface/pages/move';
144145
import { useRealtimeContext } from 'src/code/realtime/context';
145146
import { asyncDialog, handleError } from 'src/code/utils/misc';
147+
import DeletionDialog from 'src/components/DeletionDialog.vue';
146148
import { pageSelectionStore } from 'src/stores/page-selection';
147149
148150
import MovePageDialog from '../RightSidebar/PageProperties/MovePageDialog.vue';
@@ -226,13 +228,9 @@ async function movePages() {
226228
227229
async function deletePages() {
228230
try {
229-
await asyncDialog({
230-
title: 'Delete pages',
231-
message: 'Are you sure you want to delete these pages?',
232-
233-
focus: 'cancel',
234-
cancel: { label: 'No', flat: true, color: 'primary' },
235-
ok: { label: 'Yes', flat: true, color: 'negative' },
231+
const { deletePermanently } = await asyncDialog({
232+
component: DeletionDialog,
233+
componentProps: { subject: 'pages' },
236234
});
237235
238236
const notif = $quasar().notify({
@@ -254,7 +252,11 @@ async function deletePages() {
254252
caption: `${index} of ${selectedPageIds.length}`,
255253
});
256254
257-
await deletePage(pageId);
255+
if (deletePermanently) {
256+
await deletePagePermanently(pageId);
257+
} else {
258+
await deletePage(pageId);
259+
}
258260
259261
numSuccess++;
260262
} catch (error) {

‎apps/client/src/layouts/PagesLayout/RightSidebar/PageProperties/GroupSettingsDialog/GeneralTab/DeleteGroupBtn.vue

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88

99
<script setup lang="ts">
1010
import { deleteGroup } from 'src/code/api-interface/groups/deletion/delete';
11+
import { deleteGroupPermanently } from 'src/code/api-interface/groups/deletion/delete-permanently';
1112
import { asyncDialog, handleError } from 'src/code/utils/misc';
13+
import DeletionDialog from 'src/components/DeletionDialog.vue';
1214
import type { Ref } from 'vue';
1315
1416
const groupId = inject<string>('groupId')!;
@@ -17,17 +19,16 @@ const dialog = inject<Ref<InstanceType<typeof CustomDialog>>>('dialog')!;
1719
1820
async function _deleteGroup() {
1921
try {
20-
await asyncDialog({
21-
title: 'Delete group',
22-
message: 'Are you sure you want to delete this group?',
23-
24-
focus: 'cancel',
25-
26-
cancel: { label: 'No', flat: true, color: 'primary' },
27-
ok: { label: 'Yes', flat: true, color: 'negative' },
22+
const { deletePermanently } = await asyncDialog({
23+
component: DeletionDialog,
24+
componentProps: { subject: 'group' },
2825
});
2926
30-
await deleteGroup({ groupId });
27+
if (deletePermanently) {
28+
await deleteGroupPermanently({ groupId });
29+
} else {
30+
await deleteGroup({ groupId });
31+
}
3132
3233
$quasar().notify({
3334
message: 'Group deleted successfully.',

‎apps/client/src/layouts/PagesLayout/RightSidebar/PageProperties/GroupSettingsDialog/PagesTab/PagesTab.vue

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,13 @@ import { rolesMap } from '@deeplib/misc';
134134
import { pluralS } from '@stdlib/misc';
135135
import type { QNotifyUpdateOptions } from 'quasar';
136136
import { deletePage } from 'src/code/api-interface/pages/deletion/delete';
137+
import { deletePagePermanently } from 'src/code/api-interface/pages/deletion/delete-permanently';
137138
import { movePage } from 'src/code/api-interface/pages/move';
138139
import { getPageTitle } from 'src/code/pages/utils';
139140
import type { RealtimeContext } from 'src/code/realtime/context';
140141
import { asyncDialog, handleError } from 'src/code/utils/misc';
141142
import CustomInfiniteScroll from 'src/components/CustomInfiniteScroll.vue';
143+
import DeletionDialog from 'src/components/DeletionDialog.vue';
142144
import { pageSelectionStore } from 'src/stores/page-selection';
143145
import type { Ref } from 'vue';
144146
@@ -278,13 +280,9 @@ async function movePages() {
278280
279281
async function deletePages() {
280282
try {
281-
await asyncDialog({
282-
title: 'Delete pages',
283-
message: 'Are you sure you want to delete these pages?',
284-
285-
focus: 'cancel',
286-
cancel: { label: 'No', flat: true, color: 'primary' },
287-
ok: { label: 'Yes', flat: true, color: 'negative' },
283+
const { deletePermanently } = await asyncDialog({
284+
component: DeletionDialog,
285+
componentProps: { subject: 'pages' },
288286
});
289287
290288
const notif = $quasar().notify({
@@ -304,7 +302,11 @@ async function deletePages() {
304302
caption: `${index} of ${selectedPageIds.length}`,
305303
});
306304
307-
await deletePage(pageId);
305+
if (deletePermanently) {
306+
await deletePagePermanently(pageId);
307+
} else {
308+
await deletePage(pageId);
309+
}
308310
309311
numSuccess++;
310312
} catch (error) {

‎apps/client/src/layouts/PagesLayout/RightSidebar/PageProperties/PageProperties.vue

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,14 @@
140140
<script setup lang="ts">
141141
import { maxPageTitleLength } from '@deeplib/misc';
142142
import { deletePage } from 'src/code/api-interface/pages/deletion/delete';
143+
import { deletePagePermanently } from 'src/code/api-interface/pages/deletion/delete-permanently';
143144
import { movePage } from 'src/code/api-interface/pages/move';
144145
import { pageAbsoluteTitles } from 'src/code/pages/computed/page-absolute-titles';
145146
import { pageRelativeTitles } from 'src/code/pages/computed/page-relative-titles';
146147
import type { Page } from 'src/code/pages/page/page';
147148
import { setClipboardText } from 'src/code/utils/clipboard';
148149
import { asyncDialog, handleError } from 'src/code/utils/misc';
150+
import DeletionDialog from 'src/components/DeletionDialog.vue';
149151
import type { Ref } from 'vue';
150152
151153
import GroupSettingsDialog from './GroupSettingsDialog/GroupSettingsDialog.vue';
@@ -183,16 +185,16 @@ async function _movePage() {
183185
184186
async function _deletePage() {
185187
try {
186-
await asyncDialog({
187-
title: 'Delete page',
188-
message: 'Are you sure you want to delete this page?',
189-
190-
focus: 'cancel',
191-
cancel: { label: 'No', flat: true, color: 'primary' },
192-
ok: { label: 'Yes', flat: true, color: 'negative' },
188+
const { deletePermanently } = await asyncDialog({
189+
component: DeletionDialog,
190+
componentProps: { subject: 'page' },
193191
});
194192
195-
await deletePage(page.value.id);
193+
if (deletePermanently) {
194+
await deletePagePermanently(page.value.id);
195+
} else {
196+
await deletePage(page.value.id);
197+
}
196198
197199
$quasar().notify({
198200
message: 'Page deleted successfully.',

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /