ryoji-s 2 years ago
parent
commit
c2e231d643

+ 1 - 1
apps/app/.env.development

@@ -16,7 +16,7 @@ ELASTICSEARCH_REJECT_UNAUTHORIZED=true
 HACKMD_URI="http://localhost:3010"
 HACKMD_URI_FOR_SERVER="http://hackmd:3000"
 OGP_URI="http://ogp:8088"
-GROWI_QUESTIONNAIRE_SERVER_ORIGIN="http://host.docker.internal:3003"
+QUESTIONNAIRE_SERVER_ORIGIN="http://host.docker.internal:3003"
 # DRAWIO_URI="http://localhost:8080/?offline=1&https=0"
 # S2SMSG_PUBSUB_SERVER_TYPE=nchan
 # PUBLISH_OPEN_API=true

+ 2 - 1
apps/app/src/components/Navbar/PersonalDropdown.jsx

@@ -2,6 +2,7 @@ import { useRef, useState } from 'react';
 
 import { UserPicture } from '@growi/ui/dist/components/User/UserPicture';
 import { useTranslation } from 'next-i18next';
+import dynamic from 'next/dynamic';
 import Link from 'next/link';
 import { useRipple } from 'react-use-ripple';
 
@@ -9,7 +10,7 @@ import { apiv3Post } from '~/client/util/apiv3-client';
 import { toastError } from '~/client/util/toastr';
 import { useCurrentUser } from '~/stores/context';
 
-import ProactiveQuestionnaireModal from '../../features/questionnaire/client/components/ProactiveQuestionnaireModal';
+const ProactiveQuestionnaireModal = dynamic(() => import('~/features/questionnaire/client/components/ProactiveQuestionnaireModal'), { ssr: false });
 
 const PersonalDropdown = () => {
   const { t } = useTranslation('commons');

+ 1 - 1
apps/app/src/features/questionnaire/client/components/QuestionnaireModal.tsx

@@ -5,11 +5,11 @@ import { Modal, ModalBody } from 'reactstrap';
 
 import { apiv3Put } from '~/client/util/apiv3-client';
 import { toastSuccess, toastError } from '~/client/util/toastr';
+import { useQuestionnaireModal } from '~/features/questionnaire/client/stores/model';
 import { IAnswer } from '~/features/questionnaire/interfaces/answer';
 import { StatusType } from '~/features/questionnaire/interfaces/questionnaire-answer-status';
 import { IQuestionnaireOrderHasId } from '~/features/questionnaire/interfaces/questionnaire-order';
 import { useCurrentUser } from '~/stores/context';
-import { useQuestionnaireModal } from '~/stores/modal';
 import loggerFactory from '~/utils/logger';
 
 import { GuestQuestionnaireAnswerStatusService } from '../services/guest-questionnaire-answer-status';

+ 1 - 1
apps/app/src/features/questionnaire/client/components/QuestionnaireToast.tsx

@@ -4,8 +4,8 @@ import { useTranslation } from 'next-i18next';
 
 import { apiv3Put } from '~/client/util/apiv3-client';
 import { toastSuccess } from '~/client/util/toastr';
+import { useQuestionnaireModal } from '~/features/questionnaire/client/stores/model';
 import { useCurrentUser } from '~/stores/context';
-import { useQuestionnaireModal } from '~/stores/modal';
 import loggerFactory from '~/utils/logger';
 
 import { StatusType } from '../../interfaces/questionnaire-answer-status';

+ 39 - 0
apps/app/src/features/questionnaire/client/stores/model.tsx

@@ -0,0 +1,39 @@
+import { useStaticSWR } from '~/stores/use-static-swr';
+import loggerFactory from '~/utils/logger';
+import { SWRResponse } from 'swr';
+
+const logger = loggerFactory('growi:stores:modal');
+
+/*
+* QuestionnaireModals
+*/
+type QuestionnaireModalStatuses = {
+  openedQuestionnaireId: string | null,
+  closeToast?: () => void | Promise<void>,
+}
+
+type QuestionnaireModalStatusUtils = {
+  open(string: string, closeToast: () => void | Promise<void>): Promise<QuestionnaireModalStatuses | undefined>
+  close(shouldCloseToast?: boolean): Promise<QuestionnaireModalStatuses | undefined>
+}
+
+export const useQuestionnaireModal = (status?: QuestionnaireModalStatuses): SWRResponse<QuestionnaireModalStatuses, Error> & QuestionnaireModalStatusUtils => {
+  const initialData: QuestionnaireModalStatuses = { openedQuestionnaireId: null };
+  const swrResponse = useStaticSWR<QuestionnaireModalStatuses, Error>('questionnaireModalStatus', status, { fallbackData: initialData });
+
+  return {
+    ...swrResponse,
+    open: (questionnaireOrderId: string, closeToast: () => void | Promise<void>) => swrResponse.mutate({
+      openedQuestionnaireId: questionnaireOrderId,
+      closeToast,
+    }),
+    close: (shouldCloseToast?: boolean) => {
+      if (shouldCloseToast) {
+        swrResponse.data?.closeToast?.();
+        if (swrResponse.data?.closeToast === undefined) logger.debug('Tried to run `swrResponse.data?.closeToast` but it was `undefined`');
+      }
+
+      return swrResponse.mutate({ openedQuestionnaireId: null });
+    },
+  };
+};/

+ 4 - 4
apps/app/src/features/questionnaire/server/routes/apiv3/questionnaire.ts

@@ -79,7 +79,7 @@ module.exports = (crowi: Crowi): Router => {
 
   router.post('/proactive/answer', accessTokenParser, loginRequired, validators.proactiveAnswer, async(req: AuthorizedRequest, res: ApiV3Response) => {
     const sendQuestionnaireAnswer = async() => {
-      const growiQuestionnaireServerOrigin = crowi.configManager?.getConfig('crowi', 'app:growiQuestionnaireServerOrigin');
+      const questionnaireServerOrigin = crowi.configManager?.getConfig('crowi', 'app:questionnaireServerOrigin');
       const growiInfo = await crowi.questionnaireService!.getGrowiInfo();
       const userInfo = crowi.questionnaireService!.getUserInfo(req.user ?? null, growiInfo.appSiteUrlHashed);
 
@@ -95,7 +95,7 @@ module.exports = (crowi: Crowi): Router => {
       };
 
       try {
-        await axios.post(`${growiQuestionnaireServerOrigin}/questionnaire-answer/proactive`, proactiveQuestionnaireAnswer);
+        await axios.post(`${questionnaireServerOrigin}/questionnaire-answer/proactive`, proactiveQuestionnaireAnswer);
       }
       catch (err) {
         if (err.request != null) {
@@ -125,7 +125,7 @@ module.exports = (crowi: Crowi): Router => {
 
   router.put('/answer', accessTokenParser, loginRequired, validators.answer, async(req: AuthorizedRequest, res: ApiV3Response) => {
     const sendQuestionnaireAnswer = async(user: IUserHasId, answers: IAnswer[]) => {
-      const growiQuestionnaireServerOrigin = crowi.configManager?.getConfig('crowi', 'app:growiQuestionnaireServerOrigin');
+      const questionnaireServerOrigin = crowi.configManager?.getConfig('crowi', 'app:questionnaireServerOrigin');
       const growiInfo = await crowi.questionnaireService!.getGrowiInfo();
       const userInfo = crowi.questionnaireService!.getUserInfo(user, growiInfo.appSiteUrlHashed);
 
@@ -138,7 +138,7 @@ module.exports = (crowi: Crowi): Router => {
       };
 
       try {
-        await axios.post(`${growiQuestionnaireServerOrigin}/questionnaire-answer`, questionnaireAnswer);
+        await axios.post(`${questionnaireServerOrigin}/questionnaire-answer`, questionnaireAnswer);
       }
       catch (err) {
         if (err.request != null) {

+ 7 - 6
apps/app/src/features/questionnaire/server/service/questionnaire-cron.ts

@@ -2,7 +2,6 @@ import axiosRetry from 'axios-retry';
 
 import loggerFactory from '~/utils/logger';
 import { getRandomIntInRange } from '~/utils/rand';
-import { sleep } from '~/utils/sleep';
 
 import { StatusType } from '../../interfaces/questionnaire-answer-status';
 import { IQuestionnaireOrder } from '../../interfaces/questionnaire-order';
@@ -36,6 +35,8 @@ class QuestionnaireCronService {
     this.crowi = crowi;
   }
 
+  sleep = (msec: number): Promise<void> => new Promise(resolve => setTimeout(resolve, msec));
+
   startCron(): void {
     const cronSchedule = this.crowi.configManager?.getConfig('crowi', 'app:questionnaireCronSchedule');
     const maxHoursUntilRequest = this.crowi.configManager?.getConfig('crowi', 'app:questionnaireCronMaxHoursUntilRequest');
@@ -52,10 +53,10 @@ class QuestionnaireCronService {
   }
 
   async executeJob(): Promise<void> {
-    const growiQuestionnaireServerOrigin = this.crowi.configManager?.getConfig('crowi', 'app:growiQuestionnaireServerOrigin');
+    const questionnaireServerOrigin = this.crowi.configManager?.getConfig('crowi', 'app:questionnaireServerOrigin');
 
     const fetchQuestionnaireOrders = async(): Promise<IQuestionnaireOrder[]> => {
-      const response = await axios.get(`${growiQuestionnaireServerOrigin}/questionnaire-order/index`);
+      const response = await axios.get(`${questionnaireServerOrigin}/questionnaire-order/index`);
       return response.data.questionnaireOrders;
     };
 
@@ -78,11 +79,11 @@ class QuestionnaireCronService {
       const proactiveQuestionnaireAnswers = await ProactiveQuestionnaireAnswer.find()
         .select('-_id -growiInfo._id -userInfo._id');
 
-      axios.post(`${growiQuestionnaireServerOrigin}/questionnaire-answer/batch`, { questionnaireAnswers })
+      axios.post(`${questionnaireServerOrigin}/questionnaire-answer/batch`, { questionnaireAnswers })
         .then(async() => {
           await QuestionnaireAnswer.deleteMany();
         });
-      axios.post(`${growiQuestionnaireServerOrigin}/questionnaire-answer/proactive/batch`, { proactiveQuestionnaireAnswers })
+      axios.post(`${questionnaireServerOrigin}/questionnaire-answer/proactive/batch`, { proactiveQuestionnaireAnswers })
         .then(async() => {
           await ProactiveQuestionnaireAnswer.deleteMany();
         });
@@ -103,7 +104,7 @@ class QuestionnaireCronService {
     return nodeCron.schedule(cronSchedule, async() => {
       // sleep for a random amount to scatter request time from GROWI apps to questionnaire server
       const secToSleep = getRandomIntInRange(0, maxSecondsUntilRequest);
-      await sleep(secToSleep * 1000);
+      await this.sleep(secToSleep * 1000);
 
       try {
         this.executeJob();

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

@@ -21,9 +21,7 @@ import superjson from 'superjson';
 
 import { useCurrentGrowiLayoutFluidClassName, useEditorModeClassName } from '~/client/services/layout';
 import { PageView } from '~/components/Page/PageView';
-import { DrawioViewerScript } from '~/components/Script/DrawioViewerScript';
-import QuestionnaireModalManager from '~/features/questionnaire/client/components/QuestionnaireModalManager';
-import type { CrowiRequest } from '~/interfaces/crowi-request';
+import { DrawioViewerScript } from '~/components/Script/DrawioViewerScript'; import type { CrowiRequest } from '~/interfaces/crowi-request';
 import type { EditorConfig } from '~/interfaces/editor-settings';
 import type { IPageGrantData } from '~/interfaces/page';
 import type { RendererConfig } from '~/interfaces/services/renderer';
@@ -78,6 +76,7 @@ const DrawioModal = dynamic(() => import('../components/PageEditor/DrawioModal')
 const HandsontableModal = dynamic(() => import('../components/PageEditor/HandsontableModal').then(mod => mod.HandsontableModal), { ssr: false });
 const TemplateModal = dynamic(() => import('../components/TemplateModal').then(mod => mod.TemplateModal), { ssr: false });
 const PageStatusAlert = dynamic(() => import('../components/PageStatusAlert').then(mod => mod.PageStatusAlert), { ssr: false });
+const QuestionnaireModalManager = dynamic(() => import('~/features/questionnaire/client/components/QuestionnaireModalManager'), { ssr: false });
 
 const logger = loggerFactory('growi:pages:all');
 

+ 2 - 2
apps/app/src/server/service/config-loader.ts

@@ -640,9 +640,9 @@ const ENV_VAR_NAME_TO_CONFIG_INFO = {
     type: ValueType.STRING,
     default: null,
   },
-  GROWI_QUESTIONNAIRE_SERVER_ORIGIN: {
+  QUESTIONNAIRE_SERVER_ORIGIN: {
     ns: 'crowi',
-    key: 'app:growiQuestionnaireServerOrigin',
+    key: 'app:questionnaireServerOrigin',
     type: ValueType.STRING,
     default: null,
   },

+ 0 - 35
apps/app/src/stores/modal.tsx

@@ -2,7 +2,6 @@ import { useCallback, useMemo } from 'react';
 
 import { SWRResponse } from 'swr';
 
-
 import MarkdownTable from '~/client/models/MarkdownTable';
 import { IPageToDeleteWithMeta, IPageToRenameWithMeta } from '~/interfaces/page';
 import {
@@ -583,40 +582,6 @@ export const useConflictDiffModal = (): SWRResponse<ConflictDiffModalStatus, Err
   });
 };
 
-/*
-* QuestionnaireModals
-*/
-type QuestionnaireModalStatuses = {
-  openedQuestionnaireId: string | null,
-  closeToast?: () => void | Promise<void>,
-}
-
-type QuestionnaireModalStatusUtils = {
-  open(string: string, closeToast: () => void | Promise<void>): Promise<QuestionnaireModalStatuses | undefined>
-  close(shouldCloseToast?: boolean): Promise<QuestionnaireModalStatuses | undefined>
-}
-
-export const useQuestionnaireModal = (status?: QuestionnaireModalStatuses): SWRResponse<QuestionnaireModalStatuses, Error> & QuestionnaireModalStatusUtils => {
-  const initialData: QuestionnaireModalStatuses = { openedQuestionnaireId: null };
-  const swrResponse = useStaticSWR<QuestionnaireModalStatuses, Error>('questionnaireModalStatus', status, { fallbackData: initialData });
-
-  return {
-    ...swrResponse,
-    open: (questionnaireOrderId: string, closeToast: () => void | Promise<void>) => swrResponse.mutate({
-      openedQuestionnaireId: questionnaireOrderId,
-      closeToast,
-    }),
-    close: (shouldCloseToast?: boolean) => {
-      if (shouldCloseToast) {
-        swrResponse.data?.closeToast?.();
-        if (swrResponse.data?.closeToast === undefined) logger.debug('Tried to run `swrResponse.data?.closeToast` but it was `undefined`');
-      }
-
-      return swrResponse.mutate({ openedQuestionnaireId: null });
-    },
-  };
-};
-
 /*
  * TemplateModal
  */

+ 0 - 1
apps/app/src/utils/sleep.ts

@@ -1 +0,0 @@
-export const sleep = (msec: number): Promise<void> => new Promise(resolve => setTimeout(resolve, msec));