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

convert grantedGroup to grantedGroups

Futa Arai 2 лет назад
Родитель
Сommit
eac5999dd3

+ 3 - 1
apps/app/src/components/PageAlert/PageGrantAlert.tsx

@@ -32,7 +32,9 @@ export const PageGrantAlert = (): JSX.Element => {
       if (pageData.grant === 5) {
         return (
           <>
-            <i className="icon-fw icon-organization"></i><strong>{pageData.grantedGroups[0].item.name}</strong>
+            <i className="icon-fw icon-organization"></i><strong>{
+              typeof pageData.grantedGroups[0].item !== 'string' && pageData.grantedGroups[0].item.name
+            }</strong>
           </>
         );
       }

+ 1 - 2
apps/app/src/components/SavePageControls.tsx

@@ -84,8 +84,7 @@ export const SavePageControls = (props: SavePageControlsProps): JSX.Element | nu
             <GrantSelector
               grant={grant}
               disabled={isRootPage}
-              grantGroupId={grantedGroup?.id}
-              grantGroupName={grantedGroup?.name}
+              grantedGroups={grantedGroups}
               onUpdateGrant={updateGrantHandler}
             />
           </div>

+ 10 - 8
apps/app/src/components/SavePageControls/GrantSelector.tsx

@@ -35,8 +35,11 @@ const AVAILABLE_GRANTS = [
 type Props = {
   disabled?: boolean,
   grant: number,
-  grantGroupId?: string,
-  grantGroupName?: string,
+  grantedGroups?: {
+    id: string,
+    name: string,
+    type: string,
+  }[]
 
   onUpdateGrant?: (grantData: IPageGrantData) => void,
 }
@@ -49,10 +52,9 @@ const GrantSelector = (props: Props): JSX.Element => {
 
   const {
     disabled,
-    grantGroupName,
+    grantedGroups,
     onUpdateGrant,
     grant: currentGrant,
-    grantGroupId,
   } = props;
 
 
@@ -101,7 +103,7 @@ const GrantSelector = (props: Props): JSX.Element => {
     let dropdownToggleLabelElm;
 
     const dropdownMenuElems = AVAILABLE_GRANTS.map((opt) => {
-      const label = ((opt.grant === 5 && opt.reselectLabel != null) && grantGroupId != null)
+      const label = ((opt.grant === 5 && opt.reselectLabel != null) && grantedGroups != null && grantedGroups.length > 0)
         ? opt.reselectLabel // when grantGroup is selected
         : opt.label;
 
@@ -122,11 +124,11 @@ const GrantSelector = (props: Props): JSX.Element => {
     });
 
     // add specified group option
-    if (grantGroupId != null) {
+    if (grantedGroups != null && grantedGroups.length > 0) {
       const labelElm = (
         <span>
           <i className="icon icon-fw icon-organization"></i>
-          <span className="label">{grantGroupName}</span>
+          <span className="label">{grantedGroups[0].name}</span>
         </span>
       );
 
@@ -148,7 +150,7 @@ const GrantSelector = (props: Props): JSX.Element => {
         </UncontrolledDropdown>
       </div>
     );
-  }, [changeGrantHandler, currentGrant, disabled, grantGroupId, grantGroupName, t]);
+  }, [changeGrantHandler, currentGrant, disabled, grantedGroups, t]);
 
   /**
    * Render select grantgroup modal.

+ 7 - 2
apps/app/src/features/external-user-group/server/routes/apiv3/external-user-group.ts

@@ -1,4 +1,4 @@
-import { ErrorV3 } from '@growi/core';
+import { ErrorV3, GroupType } from '@growi/core';
 import { Router, Request } from 'express';
 import {
   body, param, query, validationResult,
@@ -137,9 +137,14 @@ module.exports = (crowi: Crowi): Router => {
       const { id: deleteGroupId } = req.params;
       const { actionName, transferToUserGroupId } = req.query;
 
+      const transferGroupInfo = transferToUserGroupId != null ? {
+        item: transferToUserGroupId as string,
+        type: GroupType.externalUserGroup,
+      } : undefined;
+
       try {
         const userGroups = await (crowi.userGroupService as UserGroupService)
-          .removeCompletelyByRootGroupId(deleteGroupId, actionName, transferToUserGroupId, req.user, ExternalUserGroup, ExternalUserGroupRelation);
+          .removeCompletelyByRootGroupId(deleteGroupId, actionName, req.user, transferGroupInfo, ExternalUserGroup, ExternalUserGroupRelation);
 
         const parameters = { action: SupportedAction.ACTION_ADMIN_USER_GROUP_DELETE };
         activityEvent.emit('update', res.locals.activity._id, parameters);

+ 1 - 1
apps/app/src/pages/[[...path]].page.tsx

@@ -415,7 +415,7 @@ class MultiplePagesHitsError extends ExtensibleCustomError {
 
 // apply parent page grant fot creating page
 async function applyGrantToPage(props: Props, ancestor: any) {
-  await ancestor.populate('grantedGroup');
+  await ancestor.populate('grantedGroups');
   const grant = {
     grant: ancestor.grant,
   };

+ 17 - 8
apps/app/src/server/models/obsolete-page.js

@@ -1,9 +1,13 @@
-import { templateChecker, pagePathUtils, pathUtils } from '@growi/core';
+import {
+  templateChecker, pagePathUtils, pathUtils, GroupType,
+} from '@growi/core';
 import escapeStringRegexp from 'escape-string-regexp';
 
+import ExternalUserGroup from '~/features/external-user-group/server/models/external-user-group';
 import { PageGrant } from '~/interfaces/page';
 import loggerFactory from '~/utils/logger';
 
+import UserGroup from './user-group';
 import UserGroupRelation from './user-group-relation';
 
 
@@ -660,7 +664,7 @@ export const getPageSchema = (crowi) => {
 
     await builder.query.updateMany({}, {
       grant,
-      grantedGroup: grant === PageGrant.GRANT_USER_GROUP ? parentPage.grantedGroup : null,
+      grantedGroups: grant === PageGrant.GRANT_USER_GROUP ? parentPage.grantedGroups : null,
       grantedUsers: grant === PageGrant.GRANT_OWNER ? [user._id] : null,
     });
 
@@ -686,7 +690,7 @@ export const getPageSchema = (crowi) => {
         updateOne: {
           filter: { _id: page._id },
           update: {
-            grantedGroup: null,
+            grantedGroups: null,
             grant: this.GRANT_PUBLIC,
           },
         },
@@ -695,14 +699,19 @@ export const getPageSchema = (crowi) => {
     await this.bulkWrite(operationsToPublicize);
   };
 
-  pageSchema.statics.transferPagesToGroup = async function(pages, transferToUserGroupId) {
-    const UserGroup = mongoose.model('UserGroup');
+  /**
+   * transfer pages grant to specified user group
+   * @param {Page[]} pages
+   * @param {GrantedGroup} transferToUserGroup
+   */
+  pageSchema.statics.transferPagesToGroup = async function(pages, transferToUserGroup) {
+    const userGroupModel = transferToUserGroup.type === GroupType.userGroup ? UserGroup : ExternalUserGroup;
 
-    if ((await UserGroup.count({ _id: transferToUserGroupId })) === 0) {
-      throw Error('Cannot find the group to which private pages belong to. _id: ', transferToUserGroupId);
+    if ((await userGroupModel.count({ _id: transferToUserGroup.item })) === 0) {
+      throw Error('Cannot find the group to which private pages belong to. _id: ', transferToUserGroup.item);
     }
 
-    await this.updateMany({ _id: { $in: pages.map(p => p._id) } }, { grantedGroup: transferToUserGroupId });
+    await this.updateMany({ _id: { $in: pages.map(p => p._id) } }, { grantedGroups: [transferToUserGroup] });
   };
 
   /**

+ 7 - 2
apps/app/src/server/routes/apiv3/user-group.js

@@ -1,4 +1,4 @@
-import { ErrorV3 } from '@growi/core';
+import { ErrorV3, GroupType } from '@growi/core';
 
 import { SupportedAction } from '~/interfaces/activity';
 import { serializeUserGroupRelationSecurely } from '~/server/models/serializers/user-group-relation-serializer';
@@ -432,8 +432,13 @@ module.exports = (crowi) => {
     const { id: deleteGroupId } = req.params;
     const { actionName, transferToUserGroupId } = req.query;
 
+    const transferGroupInfo = transferToUserGroupId != null ? {
+      item: transferToUserGroupId,
+      type: GroupType.userGroup,
+    } : undefined;
+
     try {
-      const userGroups = await crowi.userGroupService.removeCompletelyByRootGroupId(deleteGroupId, actionName, transferToUserGroupId, req.user);
+      const userGroups = await crowi.userGroupService.removeCompletelyByRootGroupId(deleteGroupId, actionName, req.user, transferGroupInfo);
 
       const parameters = { action: SupportedAction.ACTION_ADMIN_USER_GROUP_DELETE };
       activityEvent.emit('update', res.locals.activity._id, parameters);

+ 2 - 2
apps/app/src/server/service/page.ts

@@ -2267,7 +2267,7 @@ class PageService {
   }
 
 
-  async handlePrivatePagesForGroupsToDelete(groupsToDelete, action, transferToUserGroupId, user) {
+  async handlePrivatePagesForGroupsToDelete(groupsToDelete, action, transferToUserGroup: GrantedGroup, user) {
     const Page = this.crowi.model('Page');
     const pages = await Page.find({
       grantedGroups: {
@@ -2284,7 +2284,7 @@ class PageService {
       case 'delete':
         return this.deleteMultipleCompletely(pages, user);
       case 'transfer':
-        await Page.transferPagesToGroup(pages, transferToUserGroupId);
+        await Page.transferPagesToGroup(pages, transferToUserGroup);
         break;
       default:
         throw new Error('Unknown action for private pages');

+ 3 - 3
apps/app/src/server/service/user-group.ts

@@ -1,3 +1,4 @@
+import { GrantedGroup } from '@growi/core';
 import { Model } from 'mongoose';
 
 import { IUser } from '~/interfaces/user';
@@ -114,7 +115,7 @@ class UserGroupService {
   }
 
   async removeCompletelyByRootGroupId(
-      deleteRootGroupId, action, transferToUserGroupId, user,
+      deleteRootGroupId, action, user, transferToUserGroup?: GrantedGroup,
       userGroupModel: Model<UserGroupDocument> & UserGroupModel = UserGroup,
       userGroupRelationModel: Model<UserGroupRelationDocument> & UserGroupRelationModel = UserGroupRelation,
   ) {
@@ -126,8 +127,7 @@ class UserGroupService {
     const groupsToDelete = await userGroupModel.findGroupsWithDescendantsRecursively([rootGroup]);
 
     // 1. update page & remove all groups
-    // TODO: update pageService logic to handle external user groups (https://redmine.weseek.co.jp/issues/124385)
-    await this.crowi.pageService.handlePrivatePagesForGroupsToDelete(groupsToDelete, action, transferToUserGroupId, user);
+    await this.crowi.pageService.handlePrivatePagesForGroupsToDelete(groupsToDelete, action, transferToUserGroup, user);
     // 2. remove all groups
     const deletedGroups = await userGroupModel.deleteMany({ _id: { $in: groupsToDelete.map(g => g._id) } });
     // 3. remove all relations