Просмотр исходного кода

Merge pull request #8645 from weseek/fix/143627-143628-page-preview-not-shown-in-duplicate-alert

fix: Page content preview not shown in duplicate alert page
Yuki Takei 2 лет назад
Родитель
Сommit
3a277db190

+ 1 - 1
apps/app/src/client/util/apiv3-client.ts

@@ -1,5 +1,5 @@
 // eslint-disable-next-line no-restricted-imports
 // eslint-disable-next-line no-restricted-imports
-import { AxiosResponse } from 'axios';
+import type { AxiosResponse } from 'axios';
 import urljoin from 'url-join';
 import urljoin from 'url-join';
 
 
 // eslint-disable-next-line no-restricted-imports
 // eslint-disable-next-line no-restricted-imports

+ 7 - 4
apps/app/src/features/external-user-group/server/models/external-user-group-relation.ts

@@ -1,12 +1,13 @@
-import { Schema, Model, Document } from 'mongoose';
+import type { Model, Document } from 'mongoose';
+import { Schema } from 'mongoose';
 
 
-import { ObjectIdLike } from '~/server/interfaces/mongoose-utils';
+import type { ObjectIdLike } from '~/server/interfaces/mongoose-utils';
 import UserGroupRelation from '~/server/models/user-group-relation';
 import UserGroupRelation from '~/server/models/user-group-relation';
 
 
 import { getOrCreateModel } from '../../../../server/util/mongoose-utils';
 import { getOrCreateModel } from '../../../../server/util/mongoose-utils';
-import { IExternalUserGroupRelation } from '../../interfaces/external-user-group';
+import type { IExternalUserGroupRelation } from '../../interfaces/external-user-group';
 
 
-import { ExternalUserGroupDocument } from './external-user-group';
+import type { ExternalUserGroupDocument } from './external-user-group';
 
 
 export interface ExternalUserGroupRelationDocument extends IExternalUserGroupRelation, Document {}
 export interface ExternalUserGroupRelationDocument extends IExternalUserGroupRelation, Document {}
 
 
@@ -24,6 +25,8 @@ export interface ExternalUserGroupRelationModel extends Model<ExternalUserGroupR
   countByGroupIdsAndUser: (userGroupIds: ObjectIdLike[], userData) => Promise<number>
   countByGroupIdsAndUser: (userGroupIds: ObjectIdLike[], userData) => Promise<number>
 
 
   findAllGroupsForUser: (user) => Promise<ExternalUserGroupDocument[]>
   findAllGroupsForUser: (user) => Promise<ExternalUserGroupDocument[]>
+
+  findAllUserGroupIdsRelatedToUser: (user) => Promise<string[]>
 }
 }
 
 
 const schema = new Schema<ExternalUserGroupRelationDocument, ExternalUserGroupRelationModel>({
 const schema = new Schema<ExternalUserGroupRelationDocument, ExternalUserGroupRelationModel>({

+ 3 - 3
apps/app/src/server/models/page.ts

@@ -75,7 +75,7 @@ export interface PageModel extends Model<PageDocument> {
   findTargetAndAncestorsByPathOrId(pathOrId: string): Promise<TargetAndAncestorsResult>
   findTargetAndAncestorsByPathOrId(pathOrId: string): Promise<TargetAndAncestorsResult>
   findRecentUpdatedPages(path: string, user, option, includeEmpty?: boolean): Promise<PaginatedPages>
   findRecentUpdatedPages(path: string, user, option, includeEmpty?: boolean): Promise<PaginatedPages>
   generateGrantCondition(
   generateGrantCondition(
-    user, userGroups, includeAnyoneWithTheLink?: boolean, showPagesRestrictedByOwner?: boolean, showPagesRestrictedByGroup?: boolean,
+    user, userGroups: string[] | null, includeAnyoneWithTheLink?: boolean, showPagesRestrictedByOwner?: boolean, showPagesRestrictedByGroup?: boolean,
   ): { $or: any[] }
   ): { $or: any[] }
   findNonEmptyClosestAncestor(path: string): Promise<PageDocument | undefined>
   findNonEmptyClosestAncestor(path: string): Promise<PageDocument | undefined>
   findNotEmptyParentByPathRecursively(path: string): Promise<PageDocument | undefined>
   findNotEmptyParentByPathRecursively(path: string): Promise<PageDocument | undefined>
@@ -417,7 +417,7 @@ export class PageQueryBuilder {
   }
   }
 
 
   addConditionToFilteringByViewer(
   addConditionToFilteringByViewer(
-      user, userGroups, includeAnyoneWithTheLink = false, showPagesRestrictedByOwner = false, showPagesRestrictedByGroup = false,
+      user, userGroups: string[] | null, includeAnyoneWithTheLink = false, showPagesRestrictedByOwner = false, showPagesRestrictedByGroup = false,
   ): PageQueryBuilder {
   ): PageQueryBuilder {
     const condition = generateGrantCondition(user, userGroups, includeAnyoneWithTheLink, showPagesRestrictedByOwner, showPagesRestrictedByGroup);
     const condition = generateGrantCondition(user, userGroups, includeAnyoneWithTheLink, showPagesRestrictedByOwner, showPagesRestrictedByGroup);
 
 
@@ -962,7 +962,7 @@ schema.statics.findParent = async function(pageId): Promise<PageDocument | null>
 schema.statics.PageQueryBuilder = PageQueryBuilder as any; // mongoose does not support constructor type as statics attrs type
 schema.statics.PageQueryBuilder = PageQueryBuilder as any; // mongoose does not support constructor type as statics attrs type
 
 
 export function generateGrantCondition(
 export function generateGrantCondition(
-    user, userGroups, includeAnyoneWithTheLink = false, showPagesRestrictedByOwner = false, showPagesRestrictedByGroup = false,
+    user, userGroups: string[] | null, includeAnyoneWithTheLink = false, showPagesRestrictedByOwner = false, showPagesRestrictedByGroup = false,
 ): { $or: any[] } {
 ): { $or: any[] } {
   const grantConditions: AnyObject[] = [
   const grantConditions: AnyObject[] = [
     { grant: null },
     { grant: null },

+ 11 - 6
apps/app/src/server/models/user-group-relation.ts

@@ -1,10 +1,13 @@
-import { isPopulated, type IUserGroupHasId, type IUserGroupRelation } from '@growi/core';
-import mongoose, { Model, Schema, Document } from 'mongoose';
+import {
+  getIdForRef, isPopulated, type IUserGroupHasId, type IUserGroupRelation,
+} from '@growi/core';
+import type { Model, Document } from 'mongoose';
+import mongoose, { Schema } from 'mongoose';
 
 
-import { ObjectIdLike } from '../interfaces/mongoose-utils';
+import type { ObjectIdLike } from '../interfaces/mongoose-utils';
 import { getOrCreateModel } from '../util/mongoose-utils';
 import { getOrCreateModel } from '../util/mongoose-utils';
 
 
-import { UserGroupDocument } from './user-group';
+import type { UserGroupDocument } from './user-group';
 
 
 const debug = require('debug')('growi:models:userGroupRelation');
 const debug = require('debug')('growi:models:userGroupRelation');
 const mongoosePaginate = require('mongoose-paginate-v2');
 const mongoosePaginate = require('mongoose-paginate-v2');
@@ -28,6 +31,8 @@ export interface UserGroupRelationModel extends Model<UserGroupRelationDocument>
   countByGroupIdsAndUser: (userGroupIds: ObjectIdLike[], userData) => Promise<number>
   countByGroupIdsAndUser: (userGroupIds: ObjectIdLike[], userData) => Promise<number>
 
 
   findAllGroupsForUser: (user) => Promise<UserGroupDocument[]>
   findAllGroupsForUser: (user) => Promise<UserGroupDocument[]>
+
+  findAllUserGroupIdsRelatedToUser: (user) => Promise<string[]>
 }
 }
 
 
 /*
 /*
@@ -138,12 +143,12 @@ schema.statics.findAllGroupsForUser = async function(user): Promise<UserGroupDoc
  * @param {User} user
  * @param {User} user
  * @returns {Promise<ObjectId[]>}
  * @returns {Promise<ObjectId[]>}
  */
  */
-schema.statics.findAllUserGroupIdsRelatedToUser = async function(user) {
+schema.statics.findAllUserGroupIdsRelatedToUser = async function(user): Promise<string[]> {
   const relations = await this.find({ relatedUser: user._id })
   const relations = await this.find({ relatedUser: user._id })
     .select('relatedGroup')
     .select('relatedGroup')
     .exec();
     .exec();
 
 
-  return relations.map((relation) => { return relation.relatedGroup });
+  return relations.map((relation) => { return getIdForRef(relation.relatedGroup) });
 };
 };
 
 
 /**
 /**

+ 11 - 5
apps/app/src/server/routes/apiv3/page-listing.ts

@@ -5,7 +5,7 @@ import { isIPageInfoForEntity } from '@growi/core';
 import { ErrorV3 } from '@growi/core/dist/models';
 import { ErrorV3 } from '@growi/core/dist/models';
 import type { Request, Router } from 'express';
 import type { Request, Router } from 'express';
 import express from 'express';
 import express from 'express';
-import { query, oneOf } from 'express-validator';
+import { query, oneOf, validationResult } from 'express-validator';
 import mongoose from 'mongoose';
 import mongoose from 'mongoose';
 
 
 
 
@@ -38,10 +38,16 @@ const validator = {
     query('id').isMongoId(),
     query('id').isMongoId(),
     query('path').isString(),
     query('path').isString(),
   ], 'id or path is required'),
   ], 'id or path is required'),
-  pageIdsOrPathRequired: oneOf([
-    query('pageIds').isArray(),
-    query('path').isString(),
-  ], 'pageIds or path is required'),
+  pageIdsOrPathRequired: [
+    // type check independent of existence check
+    query('pageIds').isArray().optional(),
+    query('path').isString().optional(),
+    // existence check
+    oneOf([
+      query('pageIds').exists(),
+      query('path').exists(),
+    ], 'pageIds or path is required'),
+  ],
   infoParams: [
   infoParams: [
     query('attachBookmarkCount').isBoolean().optional(),
     query('attachBookmarkCount').isBoolean().optional(),
     query('attachShortBody').isBoolean().optional(),
     query('attachShortBody').isBoolean().optional(),

+ 4 - 1
apps/app/src/stores/page-listing.tsx

@@ -111,7 +111,10 @@ export const useSWRxPageInfoForList = (
     shouldFetch ? ['/page-listing/info', pageIds, path, attachBookmarkCount, attachShortBody] : null,
     shouldFetch ? ['/page-listing/info', pageIds, path, attachBookmarkCount, attachShortBody] : null,
     ([endpoint, pageIds, path, attachBookmarkCount, attachShortBody]) => {
     ([endpoint, pageIds, path, attachBookmarkCount, attachShortBody]) => {
       return apiv3Get(endpoint, {
       return apiv3Get(endpoint, {
-        pageIds, path, attachBookmarkCount, attachShortBody,
+        pageIds: pageIds != null ? pageIds : undefined, // Do not pass null to avoid empty query parameter
+        path: path != null ? path : undefined, // Do not pass null to avoid empty query parameter
+        attachBookmarkCount,
+        attachShortBody,
       }).then(response => response.data);
       }).then(response => response.data);
     },
     },
   );
   );