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

Merge pull request #7265 from weseek/imprv/i18n-questionnaire-text

imprv: i18n questionnaire text
Haku Mizuki 3 лет назад
Родитель
Сommit
28c58095a0

+ 7 - 1
packages/app/src/components/Questionnaire/Question.tsx

@@ -1,14 +1,20 @@
 import { IQuestionHasId } from '~/interfaces/questionnaire/question';
+import { useCurrentUser } from '~/stores/context';
 
 type QuestionProps = {
   question: IQuestionHasId,
 }
 
 const Question = ({ question }: QuestionProps): JSX.Element => {
+  const { data: currentUser } = useCurrentUser();
+  const lang = currentUser?.lang;
+
+  const questionText = lang === 'en_US' ? question.text.en_US : question.text.ja_JP;
+
   return <div className="row mt-4">
     <div className="col-6 d-flex align-items-center">
       <span>
-        {question.text}
+        {questionText}
       </span>
     </div>
     <div className="col-1 d-flex align-items-center p-0">

+ 4 - 1
packages/app/src/components/Questionnaire/QuestionnaireModal.tsx

@@ -17,6 +17,7 @@ type QuestionnaireModalProps = {
 
 const QuestionnaireModal = ({ questionnaireOrder }: QuestionnaireModalProps): JSX.Element => {
   const { data: currentUser } = useCurrentUser();
+  const lang = currentUser?.lang;
 
   const { data: questionnaireModalData, close: closeQuestionnaireModal } = useQuestionnaireModal();
   const isOpened = questionnaireModalData?.openedQuestionnaireId === questionnaireOrder._id;
@@ -37,6 +38,8 @@ const QuestionnaireModal = ({ questionnaireOrder }: QuestionnaireModalProps): JS
     closeQuestionnaireModal();
   };
 
+  const questionnaireOrderTitle = lang === 'en_US' ? questionnaireOrder.title.en_US : questionnaireOrder.title.ja_JP;
+
   return (<Modal
     size="lg"
     isOpen={isOpened}
@@ -50,7 +53,7 @@ const QuestionnaireModal = ({ questionnaireOrder }: QuestionnaireModalProps): JS
     </ModalHeader>
     <ModalBody className="my-4">
       <div className="container">
-        <h3 className="grw-modal-head">{questionnaireOrder.title}</h3>
+        <h3 className="grw-modal-head">{questionnaireOrderTitle}</h3>
         <div className="row mt-4">
           <div className="col-6"></div>
           <div className="col-1 p-0 font-weight-bold text-center align-items-center">{t('questionnaire.no_answer')}</div>

+ 7 - 1
packages/app/src/components/Questionnaire/QuestionnaireToast.tsx

@@ -3,6 +3,7 @@ import { useState } from 'react';
 import { useTranslation } from 'next-i18next';
 
 import { IQuestionnaireOrderHasId } from '~/interfaces/questionnaire/questionnaire-order';
+import { useCurrentUser } from '~/stores/context';
 import { useQuestionnaireModal } from '~/stores/modal';
 
 
@@ -12,6 +13,9 @@ type QuestionnaireToastProps = {
 
 const QuestionnaireToast = ({ questionnaireOrder }: QuestionnaireToastProps): JSX.Element => {
   const { open: openQuestionnaireModal } = useQuestionnaireModal();
+  const { data: currentUser } = useCurrentUser();
+  const lang = currentUser?.lang;
+
   const [isOpen, setIsOpen] = useState(true);
 
   const { t } = useTranslation();
@@ -21,9 +25,11 @@ const QuestionnaireToast = ({ questionnaireOrder }: QuestionnaireToastProps): JS
     openQuestionnaireModal(questionnaireOrder._id);
   };
 
+  const questionnaireOrderTitle = lang === 'en_US' ? questionnaireOrder.title.en_US : questionnaireOrder.title.ja_JP;
+
   return <div className={`toast ${isOpen ? 'show' : 'hide'}`}>
     <div className="toast-header bg-info">
-      <strong className="mr-auto text-light">{questionnaireOrder.title}</strong>
+      <strong className="mr-auto text-light">{questionnaireOrderTitle}</strong>
       <button type="button" className="ml-2 mb-1 close" onClick={() => setIsOpen(false)}>
         <span aria-hidden="true" className="text-light">&times;</span>
       </button>

+ 4 - 1
packages/app/src/interfaces/questionnaire/question.ts

@@ -6,7 +6,10 @@ type QuestionType = typeof QuestionType[keyof typeof QuestionType];
 
 export interface IQuestion {
   type: QuestionType
-  text: string
+  text: {
+    ja_JP: string
+    en_US: string
+  }
 }
 
 export type IQuestionHasId = IQuestion & HasObjectId;

+ 8 - 2
packages/app/src/interfaces/questionnaire/questionnaire-order.ts

@@ -4,7 +4,10 @@ import { ICondition, IConditionHasId } from './condition';
 import { IQuestion, IQuestionHasId } from './question';
 
 export interface IQuestionnaireOrder {
-  title: string,
+  title: {
+    ja_JP: string
+    en_US: string
+  }
   showFrom: Date
   showUntil: Date
   questions: IQuestion[]
@@ -12,7 +15,10 @@ export interface IQuestionnaireOrder {
 }
 
 export type IQuestionnaireOrderHasId = {
-  title: string,
+  title: {
+    ja_JP: string
+    en_US: string
+  }
   showFrom: Date
   showUntil: Date
   questions: IQuestionHasId[]

+ 6 - 1
packages/app/src/server/models/questionnaire/questionnaire-order.ts

@@ -10,8 +10,13 @@ export interface QuestionnaireOrderDocument extends IQuestionnaireOrder, Documen
 
 export type QuestionnaireOrderModel = Model<QuestionnaireOrderDocument>
 
+const questionnaireOrderTitleSchema = new Schema<IQuestionnaireOrder['title']>({
+  ja_JP: { type: String, required: true },
+  en_US: { type: String, required: true },
+}, { _id: false });
+
 const questionnaireOrderSchema = new Schema<QuestionnaireOrderDocument>({
-  title: { type: String, required: true },
+  title: { type: questionnaireOrderTitleSchema, required: true },
   showFrom: { type: Date, required: true },
   showUntil: {
     type: Date,

+ 6 - 1
packages/app/src/server/models/questionnaire/schema/question.ts

@@ -2,9 +2,14 @@ import { Schema } from 'mongoose';
 
 import { IQuestion, QuestionType } from '~/interfaces/questionnaire/question';
 
+const questionTextSchema = new Schema<IQuestion['text']>({
+  ja_JP: { type: String, required: true },
+  en_US: { type: String, required: true },
+}, { _id: false });
+
 const questionSchema = new Schema<IQuestion>({
   type: { type: String, required: true, enum: Object.values(QuestionType) },
-  text: { type: String, required: true },
+  text: { type: questionTextSchema, required: true },
 }, { timestamps: true });
 
 export default questionSchema;

+ 64 - 8
packages/app/test/integration/service/questionnaire-cron.test.ts

@@ -27,12 +27,19 @@ describe('QuestionnaireCronService', () => {
         // saved in db、not finished (user types is updated from the time it was saved)
         {
           _id: '63a8354837e7aa378e16f0b1',
+          title: {
+            ja_JP: 'GROWI に関するアンケート',
+            en_US: 'Questions about GROWI',
+          },
           showFrom: '2022-12-11',
           showUntil: '2100-12-12',
           questions: [
             {
               type: 'points',
-              text: 'Is Growi easy to use?',
+              text: {
+                ja_JP: 'GROWI は使いやすいですか?',
+                en_US: 'Is GROWI easy to use?',
+              },
             },
           ],
           condition: {
@@ -51,12 +58,19 @@ describe('QuestionnaireCronService', () => {
         // not saved, not finished
         {
           _id: '63a8354837e7aa378e16f0b2',
+          title: {
+            ja_JP: 'GROWI に関するアンケート',
+            en_US: 'Questions about GROWI',
+          },
           showFrom: '2021-12-11',
           showUntil: '2100-12-12',
           questions: [
             {
               type: 'points',
-              text: 'Is this questionnaire functioning properly?',
+              text: {
+                ja_JP: 'アンケート機能は正常動作していますか?',
+                en_US: 'Is this questionnaire functioning properly?',
+              },
             },
           ],
           condition: {
@@ -75,12 +89,19 @@ describe('QuestionnaireCronService', () => {
         // not saved, finished
         {
           _id: '63a8354837e7aa378e16f0b3',
+          title: {
+            ja_JP: 'GROWI に関するアンケート',
+            en_US: 'Questions about GROWI',
+          },
           showFrom: '2021-12-11',
           showUntil: '2021-12-12',
           questions: [
             {
               type: 'points',
-              text: 'Is this a good question?',
+              text: {
+                ja_JP: 'これはいい質問ですか?',
+                en_US: 'Is this a good question?',
+              },
             },
           ],
           condition: {
@@ -114,12 +135,19 @@ describe('QuestionnaireCronService', () => {
     await QuestionnaireOrder.insertMany([
       {
         _id: '63a8354837e7aa378e16f0b1',
+        title: {
+          ja_JP: 'GROWI に関するアンケート',
+          en_US: 'Questions about GROWI',
+        },
         showFrom: '2022-12-11',
         showUntil: '2100-12-12',
         questions: [
           {
             type: 'points',
-            text: 'Is Growi easy to use?',
+            text: {
+              ja_JP: 'GROWI は使いやすいですか?',
+              en_US: 'Is GROWI easy to use?',
+            },
           },
         ],
         condition: {
@@ -135,12 +163,19 @@ describe('QuestionnaireCronService', () => {
       // finished
       {
         _id: '63a8354837e7aa378e16f0b4',
+        title: {
+          ja_JP: 'GROWI に関するアンケート',
+          en_US: 'Questions about GROWI',
+        },
         showFrom: '2020-12-11',
         showUntil: '2021-12-12',
         questions: [
           {
             type: 'points',
-            text: 'Is ver 2.0 better than 1.0?',
+            text: {
+              ja_JP: 'ver 2.0 は 1.0 より良いですか?',
+              en_US: 'Is ver 2.0 better than 1.0?',
+            },
           },
         ],
         condition: {
@@ -156,12 +191,19 @@ describe('QuestionnaireCronService', () => {
       // questionnaire that doesn't exist in questionnaire server
       {
         _id: '63a8354837e7aa378e16f0b5',
+        title: {
+          ja_JP: 'GROWI に関するアンケート',
+          en_US: 'Questions about GROWI',
+        },
         showFrom: '2020-12-11',
         showUntil: '2100-12-12',
         questions: [
           {
             type: 'points',
-            text: 'How would you rate the latest design?',
+            text: {
+              ja_JP: '新しいデザインは良いですか?',
+              en_US: 'How would you rate the latest design?',
+            },
           },
         ],
         condition: {
@@ -210,12 +252,19 @@ describe('QuestionnaireCronService', () => {
     expect(JSON.parse(JSON.stringify(savedOrders))).toEqual([
       {
         _id: '63a8354837e7aa378e16f0b1',
+        title: {
+          ja_JP: 'GROWI に関するアンケート',
+          en_US: 'Questions about GROWI',
+        },
         showFrom: '2022-12-11T00:00:00.000Z',
         showUntil: '2100-12-12T00:00:00.000Z',
         questions: [
           {
             type: 'points',
-            text: 'Is Growi easy to use?',
+            text: {
+              ja_JP: 'GROWI は使いやすいですか?',
+              en_US: 'Is GROWI easy to use?',
+            },
           },
         ],
         condition: {
@@ -233,12 +282,19 @@ describe('QuestionnaireCronService', () => {
       },
       {
         _id: '63a8354837e7aa378e16f0b2',
+        title: {
+          ja_JP: 'GROWI に関するアンケート',
+          en_US: 'Questions about GROWI',
+        },
         showFrom: '2021-12-11T00:00:00.000Z',
         showUntil: '2100-12-12T00:00:00.000Z',
         questions: [
           {
             type: 'points',
-            text: 'Is this questionnaire functioning properly?',
+            text: {
+              ja_JP: 'アンケート機能は正常動作していますか?',
+              en_US: 'Is this questionnaire functioning properly?',
+            },
           },
         ],
         condition: {