From 7652e5ef08750ca4423b7e12ae1c8f93feba06ee Mon Sep 17 00:00:00 2001 From: masaaki Date: Wed, 27 Dec 2023 02:24:39 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20662:=20[OMDS=E6=A7=98=E8=A6=81?= =?UTF-8?q?=E6=9C=9B]=20=E3=82=BF=E3=82=B9=E3=82=AF=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E7=94=BB=E9=9D=A2=E3=81=AE=E6=97=A5=E6=99=82=E8=A1=A8=E7=A4=BA?= =?UTF-8?q?=E3=82=92=E5=A4=89=E3=81=88=E3=81=9F=E3=81=84=EF=BC=88=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E3=82=BF=E3=82=B9=E3=82=AF=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3362: [OMDS様要望] タスク一覧画面の日時表示を変えたい(修正タスク)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3362) - 以下の画面について、日時の表示形式をブラウザのロケールに合わせて変換し、時差を考慮した内容になるよう修正しました。 - タスク一覧画面 - 音声メタ情報ポップアップ - 注文履歴画面(日付のみ表示) - サーバからUTCでのYYYY/MM/DDの文字列として返却していたので、ISOStringとして返却して画面で表示内容を変換するよう処理を修正しました - タスク一覧画面のFile Lengthについて、hh:mm:ss形式となるよう修正しました ## レビューポイント - formatMillisecondsToHHMMSSについて、他で使うシーンがなかったのでdictation内の関数としたが、全体の関数とした方がよいか - convertUtcToLocalについて不正な日付の文字列が渡された場合、変換せずに元の値を返却しているが、エラー対応として問題ないか ## UIの変更 - https://ndstokyo.sharepoint.com/:f:/r/sites/Piranha/Shared%20Documents/General/OMDS/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88/Task3362?csf=1&web=1&e=Nc7kPV ## 動作確認状況 - ローカルで確認、サーバ側はnpm run test実施済 ## 補足 - 相談、参考資料などがあれば --- .../src/common/convertUtcToLocal.ts | 15 +++++++ .../src/features/dictation/selectors.ts | 43 ++++++++++++++++++- .../license/licenseOrderHistory/selectors.ts | 23 +++++++++- .../src/features/accounts/accounts.service.ts | 18 +++----- 4 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 dictation_client/src/common/convertUtcToLocal.ts diff --git a/dictation_client/src/common/convertUtcToLocal.ts b/dictation_client/src/common/convertUtcToLocal.ts new file mode 100644 index 0000000..bbb4c0b --- /dev/null +++ b/dictation_client/src/common/convertUtcToLocal.ts @@ -0,0 +1,15 @@ +// UTCの日付に対してローカルのロケール+タイムゾーンを考慮して表示形式と時刻補正を行った文字列を返却する +export const convertUtcToLocal = ( + utcDateString: string, + formatOptions?: Intl.DateTimeFormatOptions +): string => { + if (Number.isNaN(Date.parse(utcDateString))) { + // 日付文字列が未定義または無効な場合は 変換を行わない + return utcDateString; + } + + const utcDate = new Date(utcDateString); + return formatOptions + ? utcDate.toLocaleString(undefined, formatOptions) + : utcDate.toLocaleString(); +}; diff --git a/dictation_client/src/features/dictation/selectors.ts b/dictation_client/src/features/dictation/selectors.ts index 3b6f494..41af21b 100644 --- a/dictation_client/src/features/dictation/selectors.ts +++ b/dictation_client/src/features/dictation/selectors.ts @@ -1,9 +1,50 @@ import { RootState } from "app/store"; +import { convertUtcToLocal } from "common/convertUtcToLocal"; import { ceil, floor } from "lodash"; import { BACKUP_POPUP_LIST_SIZE } from "./constants"; -export const selectTasks = (state: RootState) => state.dictation.domain.tasks; +// ミリ秒の数値をhh:mm:ss形式に変換する +const formatMillisecondsToHHMMSS = (milliseconds: number): string => { + const seconds = Math.floor(milliseconds / 1000); + if (seconds < 0) { + return "00:00:00"; + } + const hours = Math.floor(seconds / 3600); + const minutes = Math.floor((seconds % 3600) / 60); + const remainingSeconds = Math.floor(seconds % 60); + + // "0x"となるように0埋めする + const formattedHours = String(hours).padStart(2, "0"); + const formattedMinutes = String(minutes).padStart(2, "0"); + const formattedSeconds = String(remainingSeconds).padStart(2, "0"); + + return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`; +}; + +export const selectTasks = (state: RootState) => { + const { tasks } = state.dictation.domain; + + const tasksWithLocalDate = tasks.map((task) => ({ + ...task, + + // UTCからローカルタイムゾーンに変換して詰めなおす + audioCreatedDate: convertUtcToLocal(task.audioCreatedDate), + audioFinishedDate: convertUtcToLocal(task.audioFinishedDate), + audioUploadedDate: convertUtcToLocal(task.audioUploadedDate), + transcriptionStartedDate: + task.transcriptionStartedDate && + convertUtcToLocal(task.transcriptionStartedDate), + transcriptionFinishedDate: + task.transcriptionFinishedDate && + convertUtcToLocal(task.transcriptionFinishedDate), + + // ミリ秒からhh:mm:ss形式に変換して詰めなおす + audioDuration: formatMillisecondsToHHMMSS(parseInt(task.audioDuration, 10)), + })); + + return tasksWithLocalDate; +}; export const selectTotal = (state: RootState) => state.dictation.domain.total; export const seletctLimit = (state: RootState) => state.dictation.domain.limit; diff --git a/dictation_client/src/features/license/licenseOrderHistory/selectors.ts b/dictation_client/src/features/license/licenseOrderHistory/selectors.ts index e3e4ceb..7903a5a 100644 --- a/dictation_client/src/features/license/licenseOrderHistory/selectors.ts +++ b/dictation_client/src/features/license/licenseOrderHistory/selectors.ts @@ -1,8 +1,27 @@ import { RootState } from "app/store"; import { ceil, floor } from "lodash"; +import { convertUtcToLocal } from "common/convertUtcToLocal"; -export const selectOrderHisory = (state: RootState) => - state.licenseOrderHistory.domain.orderHistories; +export const selectOrderHisory = (state: RootState) => { + const { orderHistories } = state.licenseOrderHistory.domain; + + const dateOptions: Intl.DateTimeFormatOptions = { + year: "numeric", + month: "numeric", + day: "numeric", + }; + + const orderHistoriesWithLocalDate = orderHistories.map((orderHistory) => ({ + ...orderHistory, + // UTCからローカルタイムゾーンに変換して詰めなおす + orderDate: convertUtcToLocal(orderHistory.orderDate, dateOptions), + issueDate: + orderHistory.issueDate && + convertUtcToLocal(orderHistory.issueDate, dateOptions), + })); + + return orderHistoriesWithLocalDate; +}; export const selectCompanyName = (state: RootState) => state.licenseOrderHistory.domain.companyName; diff --git a/dictation_server/src/features/accounts/accounts.service.ts b/dictation_server/src/features/accounts/accounts.service.ts index 4e4b474..0a19cb9 100644 --- a/dictation_server/src/features/accounts/accounts.service.ts +++ b/dictation_server/src/features/accounts/accounts.service.ts @@ -430,14 +430,12 @@ export class AccountsService { } | params: { ` + `externalId: ${externalId}, };`, ); try { - let userInfo: User; - userInfo = await this.usersRepository.findUserByExternalId( + const userInfo = await this.usersRepository.findUserByExternalId( context, externalId, ); - let accountInfo: Account; - accountInfo = await this.accountRepository.findAccountById( + const accountInfo = await this.accountRepository.findAccountById( context, userInfo.account_id, ); @@ -948,7 +946,7 @@ export class AccountsService { for (const childPartnerLicenseFromRepository of getPartnerLicenseResult.childPartnerLicensesFromRepository) { const { allocatableLicenseWithMargin, expiringSoonLicense } = childPartnerLicenseFromRepository; - let childShortage: number = 0; + let childShortage = 0; if (childPartnerLicenseFromRepository.tier === TIERS.TIER5) { if ( allocatableLicenseWithMargin === undefined || @@ -1031,16 +1029,10 @@ export class AccountsService { const returnLicenseOrder: LicenseOrder = { issueDate: licenseOrder.issued_at !== null - ? new Date(licenseOrder.issued_at) - .toISOString() - .substring(0, 10) - .replace(/-/g, '/') + ? new Date(licenseOrder.issued_at).toISOString() : undefined, numberOfOrder: licenseOrder.quantity, - orderDate: new Date(licenseOrder.ordered_at) - .toISOString() - .substring(0, 10) - .replace(/-/g, '/'), + orderDate: new Date(licenseOrder.ordered_at).toISOString(), poNumber: licenseOrder.po_number, status: licenseOrder.status, };