diff --git a/components/response-form/response-page-settings.ts b/components/response-form/response-page-settings.ts new file mode 100644 index 0000000..d1ea80a --- /dev/null +++ b/components/response-form/response-page-settings.ts @@ -0,0 +1,50 @@ +export type ResponseSettingsText = { + type: 'Text'; + text: string; +}; + +export type ResponseSettingsTextLong = { + type: 'TextLong'; + textLong: string; +}; + +export type ResponseSettingsNumber = { + type: 'Number'; + number: number | null; +}; + +export type ResponseSettingsSingleChoice = { + type: 'SingleChoice'; + index: number; +}; + +export type ResponseSettingsMultipleChoice = { + type: 'MultipleChoice'; + indexes: number[]; +}; + +export type ResponseSettingsScale = { + type: 'Scale'; + number: number; +}; + +export type ResponseSettings = + | ResponseSettingsText + | ResponseSettingsTextLong + | ResponseSettingsNumber + | ResponseSettingsSingleChoice + | ResponseSettingsMultipleChoice + | ResponseSettingsScale; + +export type ResponseQuestionType = ResponseSettings['type']; + +export type ResponseFormBody = ResponseSettings[]; + +export const defaultQuestionSettingsByType = { + Text: { type: 'Text', text: '' }, + TextLong: { type: 'TextLong', textLong: '' }, + Number: { type: 'Number', number: null }, + SingleChoice: { type: 'SingleChoice', index: -1 }, + MultipleChoice: { type: 'MultipleChoice', indexes: [] }, + Scale: { type: 'Scale', number: -1 }, +} satisfies Record; diff --git a/components/response-form/response-page.vue b/components/response-form/response-page.vue new file mode 100644 index 0000000..838e2d6 --- /dev/null +++ b/components/response-form/response-page.vue @@ -0,0 +1,200 @@ + + + + + diff --git a/composables/type-fetch/anke-to/openapi.ts b/composables/type-fetch/anke-to/openapi.ts index 6bbbbb5..8bf80bc 100644 --- a/composables/type-fetch/anke-to/openapi.ts +++ b/composables/type-fetch/anke-to/openapi.ts @@ -75,17 +75,22 @@ export interface components { * @enum {string} */ ResShareType: "admins" | "respondents" | "anyone"; - NewQuestionnaire: components["schemas"]["QuestionnaireTitle"] & components["schemas"]["QuestionnaireDescription"] & components["schemas"]["QuestionnaireResponseDueDateTime"] & components["schemas"]["QuestionnaireResponseViewableBy"] & components["schemas"]["QuestionnaireIsAnonymous"] & components["schemas"]["QuestionnaireIsAllowingMultipleResponses"] & components["schemas"]["QuestionnaireIsPublished"] & components["schemas"]["QuestionnaireTargetsAndAdmins"] & { + QuestionnaireBase: components["schemas"]["QuestionnaireTitle"] & components["schemas"]["QuestionnaireDescription"] & components["schemas"]["QuestionnaireResponseDueDateTime"] & components["schemas"]["QuestionnaireResponseViewableBy"] & components["schemas"]["QuestionnaireIsAnonymous"] & components["schemas"]["QuestionnaireIsAllowingMultipleResponses"] & components["schemas"]["QuestionnaireIsPublished"] & components["schemas"]["QuestionnaireTargetsAndAdmins"]; + NewQuestionnaire: components["schemas"]["QuestionnaireBase"] & { questions: components["schemas"]["NewQuestion"][]; }; - QuestionnaireDetail: components["schemas"]["QuestionnaireID"] & components["schemas"]["NewQuestionnaire"] & components["schemas"]["QuestionnaireRespondents"] & components["schemas"]["QuestionnaireCreatedAt"] & components["schemas"]["QuestionnaireModifiedAt"]; + QuestionnaireDetail: components["schemas"]["QuestionnaireID"] & components["schemas"]["QuestionnaireBase"] & components["schemas"]["QuestionnaireCreatedAt"] & components["schemas"]["QuestionnaireModifiedAt"] & { + questions: components["schemas"]["Question"][]; + /** @description 回答者の一覧。匿名回答の場合はnull。 */ + respondents: components["schemas"]["Users"]; + }; QuestionnaireSummary: components["schemas"]["QuestionnaireID"] & components["schemas"]["QuestionnaireTitle"] & components["schemas"]["QuestionnaireDescription"] & components["schemas"]["QuestionnaireResponseDueDateTime"] & components["schemas"]["QuestionnaireResponseViewableBy"] & components["schemas"]["QuestionnaireIsAnonymous"] & components["schemas"]["QuestionnaireIsAllowingMultipleResponses"] & components["schemas"]["QuestionnaireIsPublished"] & components["schemas"]["QuestionnaireIsTargetingMe"] & components["schemas"]["QuestionnaireCreatedAt"] & components["schemas"]["QuestionnaireModifiedAt"] & { /** @description 下書きが存在する */ has_my_draft: boolean; /** @description 回答が存在する */ has_my_response: boolean; /** Format: date-time */ - responded_date_time_by_me: string; + responded_date_time_by_me?: string; /** * @description すべての対象者が回答済みの場合 true を返す。それ以外は false を返す。 (対象者が存在しない場合は true を返す) * @@ -176,9 +181,6 @@ export interface components { targets: components["schemas"]["UsersAndGroups"]; admins: components["schemas"]["UsersAndGroups"]; }; - QuestionnaireRespondents: { - respondents: components["schemas"]["Users"]; - }; QuestionnaireHasMyResponse: { /** @description 回答済みあるいは下書きが存在する */ has_response: boolean; @@ -197,7 +199,6 @@ export interface components { */ created_at: string; }; - Questions: components["schemas"]["Question"][]; QuestionBase: { /** @example 1 */ questionnaire_id: number; @@ -295,44 +296,20 @@ export interface components { ResponseBodyBaseInteger: { answer: number; }; - Result: { - /** @example 1 */ - questionnaire_id: number; - /** @example 1 */ - response_count: number; - body: components["schemas"]["ResultBody"][]; - }; - ResultBody: components["schemas"]["ResultBodyText"] | components["schemas"]["ResultBodyTextLong"] | components["schemas"]["ResultBodyNumber"] | components["schemas"]["ResultBodySingleChoice"] | components["schemas"]["ResultBodyMultipleChoice"] | components["schemas"]["ResultBodyScale"]; - /** @description 回答文ごとの回答数の配列 */ - ResultBodyText: components["schemas"]["QuestionTypeText"] & components["schemas"]["ResultBodyBaseStringAnswer"]; - /** @description 回答文ごとの回答数の配列 */ - ResultBodyTextLong: components["schemas"]["QuestionTypeTextLong"] & components["schemas"]["ResultBodyBaseStringAnswer"]; - /** @description 数値ごとの回答数の配列 */ - ResultBodyNumber: components["schemas"]["QuestionTypeNumber"] & components["schemas"]["ResultBodyBaseNumberAnswer"]; - /** @description 選択肢ごとの回答数の配列 */ - ResultBodySingleChoice: components["schemas"]["QuestionTypeSingleChoice"] & components["schemas"]["ResultBodyBaseIntegerAnswer"]; - /** @description 選択肢ごとの回答数の配列 */ - ResultBodyMultipleChoice: components["schemas"]["QuestionTypeMultipleChoice"] & components["schemas"]["ResultBodyBaseIntegerAnswer"]; - /** @description 数値ごとの回答数の配列 */ - ResultBodyScale: components["schemas"]["QuestionTypeScale"] & components["schemas"]["ResultBodyBaseIntegerAnswer"]; - ResultBodyBaseStringAnswer: { - aggregated_answers: { - answer: string; - answer_count: number; - }[]; - }; - ResultBodyBaseNumberAnswer: { - aggregated_answers: { - answer: number; - answer_count: number; - }[]; - }; - ResultBodyBaseIntegerAnswer: { - aggregated_answers: { - answer: number; - answer_count: number; - }[]; - }; + Result: (components["schemas"]["QuestionnaireID"] & { + /** @example 1 */ + response_id: number; + /** + * Format: date-time + * @example "2019-12-31T15:00:00.000Z" + */ + submitted_at: string; + /** + * Format: date-time + * @example "2019-12-31T15:00:00.000Z" + */ + modified_at: string; + } & components["schemas"]["NewResponse"])[]; UsersAndGroups: { users: components["schemas"]["Users"]; groups: components["schemas"]["Groups"]; diff --git a/pages/questionnaires/[questionnaireID]/index.vue b/pages/questionnaires/[questionnaireID]/index.vue index e9c0225..573d859 100644 --- a/pages/questionnaires/[questionnaireID]/index.vue +++ b/pages/questionnaires/[questionnaireID]/index.vue @@ -25,6 +25,8 @@ const questionnaireDetail: QuestionnaireDetail = { description: '質問1の説明', question_type: 'Text', is_required: true, + created_at: '2021-09-01T00:00:00+09:00', + question_id: 1, }, { questionnaire_id: 1, @@ -32,6 +34,8 @@ const questionnaireDetail: QuestionnaireDetail = { description: '質問2の説明', question_type: 'TextLong', is_required: true, + created_at: '2021-09-01T00:00:00+09:00', + question_id: 2, }, { questionnaire_id: 1, @@ -39,6 +43,8 @@ const questionnaireDetail: QuestionnaireDetail = { description: '質問3の説明', question_type: 'Number', is_required: true, + created_at: '2021-09-01T00:00:00+09:00', + question_id: 3, }, { questionnaire_id: 1, @@ -47,6 +53,8 @@ const questionnaireDetail: QuestionnaireDetail = { question_type: 'SingleChoice', is_required: true, options: ['選択肢1', '選択肢2', '選択肢3'], + created_at: '2021-09-01T00:00:00+09:00', + question_id: 4, }, { questionnaire_id: 1, @@ -55,6 +63,8 @@ const questionnaireDetail: QuestionnaireDetail = { question_type: 'MultipleChoice', is_required: true, options: ['選択肢1', '選択肢2', '選択肢3'], + created_at: '2021-09-01T00:00:00+09:00', + question_id: 5, }, { questionnaire_id: 1, @@ -63,9 +73,9 @@ const questionnaireDetail: QuestionnaireDetail = { question_type: 'Scale', is_required: true, min_value: 1, - min_label: '最小値', max_value: 5, - max_label: '最大値', + created_at: '2021-09-01T00:00:00+09:00', + question_id: 6, }, ], respondents: ['cp20'], diff --git a/pages/questionnaires/[questionnaireID]/result.vue b/pages/questionnaires/[questionnaireID]/result.vue index 65f891a..b01e282 100644 --- a/pages/questionnaires/[questionnaireID]/result.vue +++ b/pages/questionnaires/[questionnaireID]/result.vue @@ -23,6 +23,8 @@ const questionnaireDetail: QuestionnaireDetail = { description: '質問1の説明', question_type: 'Text', is_required: true, + created_at: '2021-09-01T00:00:00+09:00', + question_id: 1, }, { questionnaire_id: 1, @@ -30,6 +32,8 @@ const questionnaireDetail: QuestionnaireDetail = { description: '質問2の説明', question_type: 'TextLong', is_required: true, + created_at: '2021-09-01T00:00:00+09:00', + question_id: 2, }, { questionnaire_id: 1, @@ -37,6 +41,8 @@ const questionnaireDetail: QuestionnaireDetail = { description: '質問3の説明', question_type: 'Number', is_required: true, + created_at: '2021-09-01T00:00:00+09:00', + question_id: 3, }, { questionnaire_id: 1, @@ -45,6 +51,8 @@ const questionnaireDetail: QuestionnaireDetail = { question_type: 'SingleChoice', is_required: true, options: ['選択肢1', '選択肢2', '選択肢3'], + created_at: '2021-09-01T00:00:00+09:00', + question_id: 4, }, { questionnaire_id: 1, @@ -53,6 +61,8 @@ const questionnaireDetail: QuestionnaireDetail = { question_type: 'MultipleChoice', is_required: true, options: ['選択肢1', '選択肢2', '選択肢3'], + created_at: '2021-09-01T00:00:00+09:00', + question_id: 5, }, { questionnaire_id: 1, @@ -62,71 +72,81 @@ const questionnaireDetail: QuestionnaireDetail = { is_required: true, min_value: 1, max_value: 5, + created_at: '2021-09-01T00:00:00+09:00', + question_id: 6, }, ], respondents: ['cp20'], response_due_date_time: '2021-09-01T00:00:00+09:00', response_viewable_by: 'anyone', }; -const questionnaireResult: QuestionnaireResult = { - response_count: 1, - questionnaire_id: 1, - body: [ - { - question_type: 'Text', - aggregated_answers: [ - { answer: 'こっちは結構短めでもいいかも', answer_count: 1 }, - { answer: 'テスト回答テスト回答テスト回答テスト回答', answer_count: 1 }, - ], - }, - { - question_type: 'TextLong', - aggregated_answers: [ - { - answer: - 'けっこう長めの回答をする場合を考慮した方がいいんじゃないかな~けっこう長めの回答をする場合を考慮した方がいいんじゃないかな~けっこう長めの回答をする場合を考慮した方がいいんじゃないかな~', - answer_count: 1, - }, - { - answer: - '改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト', - answer_count: 1, - }, - ], - }, - { - question_type: 'Number', - aggregated_answers: [ - { answer: 100, answer_count: 1 }, - { answer: 50, answer_count: 1 }, - ], - }, - { - question_type: 'SingleChoice', - aggregated_answers: [ - { answer: 0, answer_count: 1 }, - { answer: 1, answer_count: 1 }, - ], - }, - { - question_type: 'MultipleChoice', - aggregated_answers: [ - { answer: 0, answer_count: 1 }, - { answer: 1, answer_count: 1 }, - { answer: 2, answer_count: 2 }, - ], - }, - { - question_type: 'Scale', - aggregated_answers: [ - { - answer: 3, - answer_count: 2, - }, - ], - }, - ], -}; +const questionnaireResult: QuestionnaireResult = [ + { + questionnaire_id: 1, + response_id: 1, + submitted_at: '2023-12-15T00:00:00+09:00', + modified_at: '2023-12-15T00:00:00+09:00', + is_draft: false, + body: [ + { + question_type: 'Text', + aggregated_answers: [ + { answer: 'こっちは結構短めでもいいかも', answer_count: 1 }, + { + answer: 'テスト回答テスト回答テスト回答テスト回答', + answer_count: 1, + }, + ], + }, + { + question_type: 'TextLong', + aggregated_answers: [ + { + answer: + 'けっこう長めの回答をする場合を考慮した方がいいんじゃないかな~けっこう長めの回答をする場合を考慮した方がいいんじゃないかな~けっこう長めの回答をする場合を考慮した方がいいんじゃないかな~', + answer_count: 1, + }, + { + answer: + '改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト\n改行のテスト', + answer_count: 1, + }, + ], + }, + { + question_type: 'Number', + aggregated_answers: [ + { answer: 100, answer_count: 1 }, + { answer: 50, answer_count: 1 }, + ], + }, + { + question_type: 'SingleChoice', + aggregated_answers: [ + { answer: 0, answer_count: 1 }, + { answer: 1, answer_count: 1 }, + ], + }, + { + question_type: 'MultipleChoice', + aggregated_answers: [ + { answer: 0, answer_count: 1 }, + { answer: 1, answer_count: 1 }, + { answer: 2, answer_count: 2 }, + ], + }, + { + question_type: 'Scale', + aggregated_answers: [ + { + answer: 3, + answer_count: 2, + }, + ], + }, + ], + }, +]; const questionnaireResponses: QuestionnaireResponses = [ { diff --git a/pages/responses.vue b/pages/responses/[responseID]/edit.vue similarity index 79% rename from pages/responses.vue rename to pages/responses/[responseID]/edit.vue index ab5393e..f1ca20f 100644 --- a/pages/responses.vue +++ b/pages/responses/[responseID]/edit.vue @@ -1,7 +1,7 @@ diff --git a/pages/responses/[responseID]/index.vue b/pages/responses/[responseID]/index.vue new file mode 100644 index 0000000..63ac853 --- /dev/null +++ b/pages/responses/[responseID]/index.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/pages/responses/index.vue b/pages/responses/index.vue new file mode 100644 index 0000000..f1ca20f --- /dev/null +++ b/pages/responses/index.vue @@ -0,0 +1,7 @@ + + + + +