Merge branch 'develop' into ccb

# Conflicts:
#	dictation_server/src/features/accounts/accounts.service.spec.ts
This commit is contained in:
SAITO-PC-3\saito.k 2024-02-19 12:00:01 +09:00
commit cdef84e269
7 changed files with 74 additions and 26 deletions

View File

@ -43,14 +43,18 @@ const App = (): JSX.Element => {
// Language読み取り
useLayoutEffect(() => {
const language = document.cookie
.trim()
.split(";")
.map((x) => x.split("="))
.find((x) => x.length === 2 && x[0] === "language");
const { cookie } = document;
if (language) {
i18n.changeLanguage(language[1]);
if (cookie) {
const cookieArray = cookie.split(";");
const language = cookieArray.find((x) =>
// 先頭の空白を削除してから判定
x.trim().startsWith("language=")
);
if (language) {
i18n.changeLanguage(language.split("=")[1]);
}
}
}, [i18n]);

View File

@ -45,7 +45,7 @@ export const worktypeSlice = createSlice({
action: PayloadAction<{ worktypeId: string }>
) => {
const { worktypeId } = action.payload;
state.apps.worktypeId = worktypeId;
state.apps.worktypeId = worktypeId.toUpperCase();
},
changeDescription: (
state,
@ -65,7 +65,12 @@ export const worktypeSlice = createSlice({
optionItem.defaultValueType !== OPTION_ITEMS_DEFAULT_VALUE_TYPE.DEFAULT
) {
optionItem.initialValue = "";
} else {
// defaultValueTypeがDefaultの場合はinitialValueを大文字にする
optionItem.initialValue = optionItem.initialValue.toUpperCase();
}
// itemLabelを大文字にする
optionItem.itemLabel = optionItem.itemLabel.toUpperCase();
// idが一致するoptionItemを削除して、新しいoptionItemを追加する。一致するidがない場合は何もしない
const optionItems = state.apps.optionItems?.filter(

View File

@ -50,16 +50,6 @@ export const FilePropertyPopup: React.FC<FilePropertyPopupProps> = (props) => {
<dd>{selectedFileTask?.fileSize ?? ""}</dd>
<dt>{t(getTranslationID("dictationPage.label.fileLength"))}</dt>
<dd>{selectedFileTask?.audioDuration ?? ""}</dd>
<dt>{t(getTranslationID("dictationPage.label.authorId"))}</dt>
<dd>{selectedFileTask?.authorId ?? ""}</dd>
<dt>{t(getTranslationID("dictationPage.label.workType"))}</dt>
<dd>{selectedFileTask?.workType ?? ""}</dd>
<dt>{t(getTranslationID("dictationPage.label.priority"))}</dt>
<dd>
{selectedFileTask?.priority === "01"
? PRIORITY.HIGH
: PRIORITY.NORMAL}
</dd>
<dt>
{t(getTranslationID("dictationPage.label.recordingStartedDate"))}
</dt>
@ -68,8 +58,6 @@ export const FilePropertyPopup: React.FC<FilePropertyPopupProps> = (props) => {
{t(getTranslationID("dictationPage.label.recordingFinishedDate"))}
</dt>
<dd>{selectedFileTask?.audioFinishedDate ?? ""}</dd>
<dt>{t(getTranslationID("dictationPage.label.uploadDate"))}</dt>
<dd>{selectedFileTask?.audioUploadedDate ?? ""}</dd>
<dt>{t(getTranslationID("dictationPage.label.encryption"))}</dt>
<dd>
{selectedFileTask?.isEncrypted ? (
@ -78,6 +66,16 @@ export const FilePropertyPopup: React.FC<FilePropertyPopupProps> = (props) => {
""
)}
</dd>
<dt>{t(getTranslationID("dictationPage.label.priority"))}</dt>
<dd>
{selectedFileTask?.priority === "01"
? PRIORITY.HIGH
: PRIORITY.NORMAL}
</dd>
<dt>{t(getTranslationID("dictationPage.label.authorId"))}</dt>
<dd>{selectedFileTask?.authorId ?? ""}</dd>
<dt>{t(getTranslationID("dictationPage.label.workType"))}</dt>
<dd>{selectedFileTask?.workType ?? ""}</dd>
<dt>{t(getTranslationID("dictationPage.label.optionItem1"))}</dt>
<dd>{selectedFileTask?.optionItemList[0].optionItemValue}</dd>
<dt>{t(getTranslationID("dictationPage.label.optionItem2"))}</dt>
@ -107,6 +105,10 @@ export const FilePropertyPopup: React.FC<FilePropertyPopupProps> = (props) => {
<dd>{selectedFileTask?.jobNumber ?? ""}</dd>
<dt>{t(getTranslationID("dictationPage.label.status"))}</dt>
<dd>{selectedFileTask?.status ?? ""}</dd>
<dt>{t(getTranslationID("dictationPage.label.uploadDate"))}</dt>
<dd>{selectedFileTask?.audioUploadedDate ?? ""}</dd>
<dt>{t(getTranslationID("dictationPage.label.transcriptionist"))}</dt>
<dd>{selectedFileTask?.typist?.name ?? ""}</dd>
<dt>
{t(
getTranslationID("dictationPage.label.transcriptionStartedDate")
@ -119,8 +121,6 @@ export const FilePropertyPopup: React.FC<FilePropertyPopupProps> = (props) => {
)}
</dt>
<dd>{selectedFileTask?.transcriptionFinishedDate ?? ""}</dd>
<dt>{t(getTranslationID("dictationPage.label.transcriptionist"))}</dt>
<dd>{selectedFileTask?.typist?.name ?? ""}</dd>
<dd className={`${styles.full} ${styles.alignRight}`}>
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
<a onClick={closePopup} className={`${styles.buttonText}`}>

View File

@ -0,0 +1,36 @@
import {
ValidatorConstraint,
ValidatorConstraintInterface,
ValidationArguments,
ValidationOptions,
registerDecorator,
} from 'class-validator';
// 大文字英数字とアンダースコアのみを許可するバリデータ
@ValidatorConstraint({ name: 'IsAuthorId', async: false })
export class IsAuthorId implements ValidatorConstraintInterface {
validate(value: any, args: ValidationArguments) {
return /^[A-Z0-9_]*$/.test(value);
}
defaultMessage(args: ValidationArguments) {
return `${args.property} should be uppercase alphanumeric and underscore only`;
}
}
/**
*
* @param [validationOptions]
* @returns
*/
export function IsAuthorIdValid(validationOptions?: ValidationOptions) {
return function (object: object, propertyName: string) {
registerDecorator({
name: 'IsAuthorId',
target: object.constructor,
propertyName: propertyName,
constraints: [],
options: validationOptions,
validator: IsAuthorId,
});
};
}

View File

@ -19,7 +19,7 @@ export class IsRecorderAllowedCharacters
}
// 正規表現でWorktypeIDのチェックを行う
// 以下の禁則文字を除く半角英数記号
// 以下の禁則文字を除く大文字英数記号
// \ (backslash)
// / (forward slash)
// : (colon)
@ -31,7 +31,7 @@ export class IsRecorderAllowedCharacters
// | (vertical bar)
// . (period)
const regex =
/^(?!.*\\)(?!.*\/)(?!.*:)(?!.*\*)(?!.*\?)(?!.*")(?!.*<)(?!.*>)(?!.*\|)(?!.*\.)[ -~]+$/;
/^(?!.*\\)(?!.*\/)(?!.*:)(?!.*\*)(?!.*\?)(?!.*")(?!.*<)(?!.*>)(?!.*\|)(?!.*\.)[A-Z0-9 !#$%&'()+,\-;=@\[\]^_`{}~]*$/;
return regex.test(value);
}

View File

@ -145,7 +145,7 @@ describe('createAccount', () => {
},
});
let _subject = '';
let _subject: string = '';
let _url: string | undefined = '';
overrideSendgridService(service, {
sendMail: async (
@ -6205,7 +6205,7 @@ describe('アカウント情報更新', () => {
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<AccountsService>(AccountsService);
let _subject = '';
let _subject: string = '';
let _url: string | undefined = '';
overrideSendgridService(service, {
sendMail: async (

View File

@ -18,6 +18,7 @@ import {
} from '../../../common/validators/encryptionPassword.validator';
import { IsRoleAuthorDataValid } from '../../../common/validators/roleAuthor.validator';
import { Type } from 'class-transformer';
import { IsAuthorIdValid } from '../../../common/validators/authorId.validator';
export class ConfirmRequest {
@ApiProperty()
@ -90,6 +91,7 @@ export class SignupRequest {
@ApiProperty({ required: false })
@IsRoleAuthorDataValid()
@IsAuthorIdValid()
authorId?: string;
@ApiProperty()
@ -225,6 +227,7 @@ export class PostUpdateUserRequest {
@ApiProperty({ required: false })
@IsRoleAuthorDataValid()
@IsAuthorIdValid()
authorId?: string;
@ApiProperty()