|
@@ -331,7 +331,8 @@ class PageService {
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const pageInfo = await this.constructBasicPageInfo(page, user);
|
|
|
|
|
|
|
+ const isGuestUser = user == null;
|
|
|
|
|
+ const pageInfo = this.constructBasicPageInfo(page, isGuestUser);
|
|
|
|
|
|
|
|
const Bookmark = this.crowi.model('Bookmark');
|
|
const Bookmark = this.crowi.model('Bookmark');
|
|
|
const bookmarkCount = await Bookmark.countByPageId(pageId);
|
|
const bookmarkCount = await Bookmark.countByPageId(pageId);
|
|
@@ -340,7 +341,7 @@ class PageService {
|
|
|
...pageInfo,
|
|
...pageInfo,
|
|
|
bookmarkCount,
|
|
bookmarkCount,
|
|
|
};
|
|
};
|
|
|
- const isGuestUser = user == null;
|
|
|
|
|
|
|
+
|
|
|
if (isGuestUser) {
|
|
if (isGuestUser) {
|
|
|
return {
|
|
return {
|
|
|
data: page,
|
|
data: page,
|
|
@@ -353,10 +354,22 @@ class PageService {
|
|
|
|
|
|
|
|
const subscription = await Subscription.findByUserIdAndTargetId(user._id, pageId);
|
|
const subscription = await Subscription.findByUserIdAndTargetId(user._id, pageId);
|
|
|
|
|
|
|
|
|
|
+ let creatorId = page.creator;
|
|
|
|
|
+ if (page.isEmpty) {
|
|
|
|
|
+ // Need non-empty ancestor page to get its creatorId because empty page does NOT have it.
|
|
|
|
|
+ // Use creatorId of ancestor page to determine whether the empty page is deletable
|
|
|
|
|
+ const notEmptyClosestAncestor = await Page.findNonEmptyClosestAncestor(page.path);
|
|
|
|
|
+ creatorId = notEmptyClosestAncestor.creator;
|
|
|
|
|
+ }
|
|
|
|
|
+ const isDeletable = this.canDelete(page.path, creatorId, user, false);
|
|
|
|
|
+ const isAbleToDeleteCompletely = this.canDeleteCompletely(page.path, creatorId, user, false); // use normal delete config
|
|
|
|
|
+
|
|
|
return {
|
|
return {
|
|
|
data: page,
|
|
data: page,
|
|
|
meta: {
|
|
meta: {
|
|
|
...metadataForGuest,
|
|
...metadataForGuest,
|
|
|
|
|
+ isDeletable,
|
|
|
|
|
+ isAbleToDeleteCompletely,
|
|
|
isBookmarked,
|
|
isBookmarked,
|
|
|
isLiked,
|
|
isLiked,
|
|
|
subscriptionStatus: subscription?.status,
|
|
subscriptionStatus: subscription?.status,
|
|
@@ -1422,7 +1435,7 @@ class PageService {
|
|
|
}
|
|
}
|
|
|
else { // always recursive
|
|
else { // always recursive
|
|
|
deletedPage = page;
|
|
deletedPage = page;
|
|
|
- await this.deleteEmptyTarget(page);
|
|
|
|
|
|
|
+ await Page.deleteOne({ _id: page._id, isEmpty: true });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 1. Update descendantCount
|
|
// 1. Update descendantCount
|
|
@@ -1489,12 +1502,6 @@ class PageService {
|
|
|
return deletedPage;
|
|
return deletedPage;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private async deleteEmptyTarget(page): Promise<void> {
|
|
|
|
|
- const Page = mongoose.model('Page') as unknown as PageModel;
|
|
|
|
|
-
|
|
|
|
|
- await Page.deleteOne({ _id: page._id, isEmpty: true });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
async deleteRecursivelyMainOperation(page, user, pageOpId: ObjectIdLike): Promise<void> {
|
|
async deleteRecursivelyMainOperation(page, user, pageOpId: ObjectIdLike): Promise<void> {
|
|
|
await this.deleteDescendantsWithStream(page, user, false);
|
|
await this.deleteDescendantsWithStream(page, user, false);
|
|
|
|
|
|
|
@@ -2169,27 +2176,16 @@ class PageService {
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- async constructBasicPageInfo(page: IPage, operator): Promise<IPageInfo | IPageInfoForEntity> {
|
|
|
|
|
- const Page = mongoose.model('Page') as unknown as PageModel;
|
|
|
|
|
-
|
|
|
|
|
- const isGuestUser = operator == null;
|
|
|
|
|
|
|
+ constructBasicPageInfo(page: IPage, isGuestUser?: boolean): IPageInfo | IPageInfoForEntity {
|
|
|
const isMovable = isGuestUser ? false : isMovablePage(page.path);
|
|
const isMovable = isGuestUser ? false : isMovablePage(page.path);
|
|
|
|
|
|
|
|
if (page.isEmpty) {
|
|
if (page.isEmpty) {
|
|
|
- // Need non-empty ancestor page to get its creator id because empty page does NOT have it.
|
|
|
|
|
- // Use creator id of ancestor page to determine whether the empty page is deletable
|
|
|
|
|
- const notEmptyClosestAncestor = await Page.findNotEmptyClosestAncestor(page.path);
|
|
|
|
|
- const creatorId = notEmptyClosestAncestor.creator;
|
|
|
|
|
-
|
|
|
|
|
- const isDeletable = this.canDelete(page.path, creatorId, operator, false);
|
|
|
|
|
- const isAbleToDeleteCompletely = this.canDeleteCompletely(page.path, creatorId, operator, false); // use normal delete config
|
|
|
|
|
-
|
|
|
|
|
return {
|
|
return {
|
|
|
isV5Compatible: true,
|
|
isV5Compatible: true,
|
|
|
isEmpty: true,
|
|
isEmpty: true,
|
|
|
isMovable,
|
|
isMovable,
|
|
|
- isDeletable,
|
|
|
|
|
- isAbleToDeleteCompletely,
|
|
|
|
|
|
|
+ isDeletable: false,
|
|
|
|
|
+ isAbleToDeleteCompletely: false,
|
|
|
isRevertible: false,
|
|
isRevertible: false,
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
@@ -2197,9 +2193,6 @@ class PageService {
|
|
|
const likers = page.liker.slice(0, 15) as Ref<IUserHasId>[];
|
|
const likers = page.liker.slice(0, 15) as Ref<IUserHasId>[];
|
|
|
const seenUsers = page.seenUsers.slice(0, 15) as Ref<IUserHasId>[];
|
|
const seenUsers = page.seenUsers.slice(0, 15) as Ref<IUserHasId>[];
|
|
|
|
|
|
|
|
- const isDeletable = this.canDelete(page.path, page.creator, operator, false);
|
|
|
|
|
- const isAbleToDeleteCompletely = this.canDeleteCompletely(page.path, page.creator, operator, false); // use normal delete config
|
|
|
|
|
-
|
|
|
|
|
return {
|
|
return {
|
|
|
isV5Compatible: isTopPage(page.path) || page.parent != null,
|
|
isV5Compatible: isTopPage(page.path) || page.parent != null,
|
|
|
isEmpty: false,
|
|
isEmpty: false,
|
|
@@ -2208,8 +2201,8 @@ class PageService {
|
|
|
seenUserIds: this.extractStringIds(seenUsers),
|
|
seenUserIds: this.extractStringIds(seenUsers),
|
|
|
sumOfSeenUsers: page.seenUsers.length,
|
|
sumOfSeenUsers: page.seenUsers.length,
|
|
|
isMovable,
|
|
isMovable,
|
|
|
- isDeletable,
|
|
|
|
|
- isAbleToDeleteCompletely,
|
|
|
|
|
|
|
+ isDeletable: isMovable,
|
|
|
|
|
+ isAbleToDeleteCompletely: false,
|
|
|
isRevertible: isTrashPage(page.path),
|
|
isRevertible: isTrashPage(page.path),
|
|
|
};
|
|
};
|
|
|
|
|
|