saito.k c4efaf1a1a Merged PR 671: 「LicenseAlert」を消す対応
## 概要
[Task3381: 対応](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3381)

- 以下の画面から「LicenseAlert」を削除
  - ユーザー追加Popup
  - ユーザー更新Popup
  - ユーザー一覧画面
- 以下のAPIの引数から「LicenseAlert」の設定をするパラメータを削除
  - ユーザー作成API(users/signup)
  - ユーザー更新API(users/update)
- ユーザー一覧取得APIのレスポンスから「LicenseAlert」を削除
- usersEntityから「LicenseAlert」を削除
- クライアントのAPI呼び出し部分を自動生成するopenapi-generator-cliのバージョンを7.1.0で固定
  - 最新バージョン(7.2.0)はaxiosのバージョン1.x用になるため
  - https://github.com/OpenAPITools/openapi-generator/releases/tag/v7.2.0

## レビューポイント
- openapi-generator-cliのバージョンを固定するのではなく、axiosのバージョンを上げたほうがよいか
  - axiosのバージョン1.xが出たのがおととしになるのでそろそろ上げてもいい?
  - このタイミングでメジャーバージョンを上げるのはどうか
    - 基本的な仕様について大きくは変わってない模様
    - 実際に上げてみて軽く動作確認してみたが問題なかった

## UIの変更
- Before/Afterのスクショなど
- 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/Task3381?csf=1&web=1&e=TpXHES

## 補足
- 相談、参考資料などがあれば
2024-01-11 06:58:01 +00:00

386 lines
9.6 KiB
TypeScript

import { createAsyncThunk } from "@reduxjs/toolkit";
import type { RootState } from "app/store";
import { USER_ROLES } from "components/auth/constants";
import { openSnackbar } from "features/ui/uiSlice";
import { getTranslationID } from "translation";
import { getAccessToken } from "features/auth";
import {
GetUsersResponse,
UsersApi,
LicensesApi,
GetAllocatableLicensesResponse,
} from "../../api/api";
import { Configuration } from "../../api/configuration";
import { ErrorObject, createErrorObject } from "../../common/errors";
export const listUsersAsync = createAsyncThunk<
// 正常時の戻り値の型
GetUsersResponse,
// 引数
void,
{
// rejectした時の返却値の型
rejectValue: {
error: ErrorObject;
};
}
>("users/listUsersAsync", async (args, thunkApi) => {
// apiのConfigurationを取得する
const { getState } = thunkApi;
const state = getState() as RootState;
const { configuration } = state.auth;
const accessToken = getAccessToken(state.auth);
const config = new Configuration(configuration);
const usersApi = new UsersApi(config);
try {
const res = await usersApi.getUsers({
headers: { authorization: `Bearer ${accessToken}` },
});
return { users: res.data.users };
} catch (e) {
// e ⇒ errorObjectに変換
const error = createErrorObject(e);
thunkApi.dispatch(
openSnackbar({
level: "error",
message: getTranslationID("common.message.internalServerError"),
})
);
return thunkApi.rejectWithValue({ error });
}
});
export const addUserAsync = createAsyncThunk<
{
/* Empty Object */
},
void,
{
// rejectした時の返却値の型
rejectValue: {
error: ErrorObject;
};
}
>("users/addUserAsync", async (args, thunkApi) => {
// apiのConfigurationを取得する
const { getState } = thunkApi;
const state = getState() as RootState;
const { configuration } = state.auth;
const accessToken = getAccessToken(state.auth);
const config = new Configuration(configuration);
const usersApi = new UsersApi(config);
const { addUser } = state.user.apps;
const newUser = { ...addUser };
// roleがAUTHOR以外の場合、不要なプロパティをundefinedにする
if (newUser.role !== USER_ROLES.AUTHOR) {
newUser.authorId = undefined;
newUser.encryption = undefined;
newUser.prompt = undefined;
newUser.encryptionPassword = undefined;
}
try {
await usersApi.signup(newUser, {
headers: { authorization: `Bearer ${accessToken}` },
});
thunkApi.dispatch(
openSnackbar({
level: "info",
message: getTranslationID("userListPage.message.addUserSuccess"),
})
);
return {};
} catch (e) {
// e ⇒ errorObjectに変換"z
const error = createErrorObject(e);
let errorMessage = getTranslationID("common.message.internalServerError");
if (error.code === "E010301") {
errorMessage = getTranslationID(
"signupConfirmPage.message.emailConflictError"
);
}
if (error.code === "E010302") {
errorMessage = getTranslationID(
"userListPage.message.authorIdConflictError"
);
}
thunkApi.dispatch(
openSnackbar({
level: "error",
message: errorMessage,
})
);
return thunkApi.rejectWithValue({ error });
}
});
export const updateUserAsync = createAsyncThunk<
{
/* Empty Object */
},
void,
{
// rejectした時の返却値の型
rejectValue: {
error: ErrorObject;
};
}
>("users/updateUserAsync", async (args, thunkApi) => {
// apiのConfigurationを取得する
const { getState } = thunkApi;
const state = getState() as RootState;
const { configuration } = state.auth;
const accessToken = getAccessToken(state.auth);
const config = new Configuration(configuration);
const usersApi = new UsersApi(config);
const { updateUser } = state.user.apps;
const authorId =
updateUser.role === USER_ROLES.AUTHOR ? updateUser.authorId : undefined;
const encryption =
updateUser.role === USER_ROLES.AUTHOR ? updateUser.encryption : undefined;
const encryptionPassword =
updateUser.role === USER_ROLES.AUTHOR
? updateUser.encryptionPassword
: undefined;
const prompt =
updateUser.role === USER_ROLES.AUTHOR ? updateUser.prompt : undefined;
try {
await usersApi.updateUser(
{
id: updateUser.id,
role: updateUser.role,
authorId,
encryption,
encryptionPassword,
prompt,
autoRenew: updateUser.autoRenew,
notification: updateUser.notification,
},
{
headers: { authorization: `Bearer ${accessToken}` },
}
);
thunkApi.dispatch(
openSnackbar({
level: "info",
message: getTranslationID("common.message.success"),
})
);
return {};
} catch (e) {
// e ⇒ errorObjectに変換"z
const error = createErrorObject(e);
let errorMessage = getTranslationID("common.message.internalServerError");
// Roleが変更できない
if (error.code === "E010207") {
errorMessage = getTranslationID("userListPage.message.roleChangeError");
}
// AuthorIdが重複している
if (error.code === "E010302") {
errorMessage = getTranslationID(
"userListPage.message.authorIdConflictError"
);
}
thunkApi.dispatch(
openSnackbar({
level: "error",
message: errorMessage,
})
);
return thunkApi.rejectWithValue({ error });
}
});
export const getAllocatableLicensesAsync = createAsyncThunk<
// 正常時の戻り値の型
GetAllocatableLicensesResponse,
// 引数
void,
{
// rejectした時の返却値の型
rejectValue: {
error: ErrorObject;
};
}
>("users/getAllocatableLicensesAsync", async (args, thunkApi) => {
// apiのConfigurationを取得する
const { getState } = thunkApi;
const state = getState() as RootState;
const { configuration } = state.auth;
const accessToken = getAccessToken(state.auth);
const config = new Configuration(configuration);
const licensesApi = new LicensesApi(config);
try {
const res = await licensesApi.getAllocatableLicenses({
headers: { authorization: `Bearer ${accessToken}` },
});
return res.data;
} catch (e) {
// e ⇒ errorObjectに変換
const error = createErrorObject(e);
const errorMessage = getTranslationID("common.message.internalServerError");
thunkApi.dispatch(
openSnackbar({
level: "error",
message: errorMessage,
})
);
return thunkApi.rejectWithValue({ error });
}
});
export const allocateLicenseAsync = createAsyncThunk<
// 正常時の戻り値の型
{
/* Empty Object */
},
// 引数
{
userId: number;
newLicenseId: number;
},
{
// rejectした時の返却値の型
rejectValue: {
error: ErrorObject;
};
}
>("users/allocateLicenseAsync", async (args, thunkApi) => {
const { userId, newLicenseId } = args;
// apiのConfigurationを取得する
const { getState } = thunkApi;
const state = getState() as RootState;
const { configuration } = state.auth;
const accessToken = getAccessToken(state.auth);
const config = new Configuration(configuration);
const usersApi = new UsersApi(config);
try {
await usersApi.allocateLicense(
{
userId,
newLicenseId,
},
{
headers: { authorization: `Bearer ${accessToken}` },
}
);
thunkApi.dispatch(
openSnackbar({
level: "info",
message: getTranslationID("common.message.success"),
})
);
return {};
} catch (e) {
// e ⇒ errorObjectに変換
const error = createErrorObject(e);
let errorMessage = getTranslationID("common.message.internalServerError");
if (error.code === "E010805") {
errorMessage = getTranslationID(
"allocateLicensePopupPage.message.licenseAllocationFailure"
);
} else if (error.code === "E010806") {
errorMessage = getTranslationID(
"allocateLicensePopupPage.message.licenseAllocationFailure"
);
}
thunkApi.dispatch(
openSnackbar({
level: "error",
message: errorMessage,
})
);
return thunkApi.rejectWithValue({ error });
}
});
export const deallocateLicenseAsync = createAsyncThunk<
// 正常時の戻り値の型
{
/* Empty Object */
},
// 引数
{
userId: number;
},
{
// rejectした時の返却値の型
rejectValue: {
error: ErrorObject;
};
}
>("users/deallocateLicenseAsync", async (args, thunkApi) => {
const { userId } = args;
// apiのConfigurationを取得する
const { getState } = thunkApi;
const state = getState() as RootState;
const { configuration } = state.auth;
const accessToken = getAccessToken(state.auth);
const config = new Configuration(configuration);
const usersApi = new UsersApi(config);
try {
await usersApi.deallocateLicense(
{
userId,
},
{
headers: { authorization: `Bearer ${accessToken}` },
}
);
thunkApi.dispatch(
openSnackbar({
level: "info",
message: getTranslationID("common.message.success"),
})
);
return {};
} catch (e) {
// e ⇒ errorObjectに変換
const error = createErrorObject(e);
let errorMessage = getTranslationID("common.message.internalServerError");
if (error.code === "E010807") {
errorMessage = getTranslationID(
"userListPage.message.alreadyLicenseDeallocatedError"
);
}
thunkApi.dispatch(
openSnackbar({
level: "error",
message: errorMessage,
})
);
return thunkApi.rejectWithValue({ error });
}
});