Skip to content

Commit

Permalink
refactor: refactor ReplicateUserFromTable.component.js to FC. Adapt I…
Browse files Browse the repository at this point in the history
…mportTable to the replicate function.
  • Loading branch information
nshandra committed Nov 12, 2024
1 parent a78181e commit 80876a7
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 6 deletions.
37 changes: 31 additions & 6 deletions src/webapp/components/import-export/ImportTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import React, { useState, useEffect, useCallback, SetStateAction, ComponentType
import InfoDialog from "../../../legacy/components/InfoDialog";
import { generateUid } from "../../../utils/uid";
import i18n from "../../../locales";
import UserLegacy from "../../../legacy/models/user";
import { ApiUser } from "../../../data/repositories/UserD2ApiRepository";
import {
composeValidators,
Expand Down Expand Up @@ -88,9 +87,10 @@ type ImportTableProps = {
title: string;
usersFromFile: User[];
columns: Columns[];
onSave: (users: User[]) => void;
onSave?: (users: User[]) => void;
onSubmit?: (params: { users: User[] }) => void;
onRequestClose: () => void;
templateUser?: UserLegacy;
templateUser?: User;
actionText: string;
warnings: string[];
};
Expand All @@ -105,6 +105,7 @@ export const ImportTable: React.FC<ImportTableProps> = props => {
templateUser = null,
actionText,
warnings = [],
onSubmit: customOnSubmit,
} = props;
const [users, setUsers] = useState<User[]>(usersFromFile);
const [existingUsers, setExistingUsers] = React.useState<Record<string, User>>({});
Expand Down Expand Up @@ -217,14 +218,16 @@ export const ImportTable: React.FC<ImportTableProps> = props => {
);
};

const onSubmit = useCallback(
const defaultOnSubmit = useCallback(
({ users }: { users: User[] }) => {
loading.show(true, i18n.t("Importing users"));
return compositionRoot.users.import({ users }).run(
() => {
onRequestClose();
loading.hide();
onSave([]);
if (onSave) {
onSave([]);
}
snackbar.success(i18n.t("Users imported successfully"));
},
error => {
Expand All @@ -236,7 +239,9 @@ export const ImportTable: React.FC<ImportTableProps> = props => {
[loading, onRequestClose, onSave, snackbar, compositionRoot.users]
);

const addRow = useCallback((currentUsers: User[]) => {
const onSubmit = customOnSubmit || defaultOnSubmit;

const defaultAddRow = useCallback((currentUsers: User[]) => {
const newUser: User = {
...defaultUser,
id: generateUid(),
Expand All @@ -248,6 +253,26 @@ export const ImportTable: React.FC<ImportTableProps> = props => {
setUsers(currentUsers.concat(newUser));
}, []);

const replicateAddRow = useCallback(
(currentUsers: User[]) => {
if (templateUser) {
const existingNames = existingUsersNames.concat(currentUsers.map(user => user.username));
const makeUsername = (i = 0) => `${templateUser.username}_${i}`;
const index = _.range(1, 1000).find(i => !existingNames.some(username => username === makeUsername(i)));
const newUser = {
...templateUser,
username: makeUsername(index),
password: UserLogic.DEFAULT_PASSWORD,
id: generateUid(),
};
setUsers(currentUsers.concat(newUser));
}
},
[existingUsersNames, templateUser]
);

const addRow = templateUser ? replicateAddRow : defaultAddRow;

const renderTableRow = useCallback(
(user: User, rowIndex: number, users: User[]) => {
const currentUsername = users[rowIndex]?.username || user.username;
Expand Down
115 changes: 115 additions & 0 deletions src/webapp/components/replicate/ReplicateUserFromTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import React, { useCallback, useEffect } from "react";
import i18n from "../../../locales";
import { Id } from "../../../domain/entities/Ref";
import { useAppContext } from "../../contexts/app-context";
import { ImportTable, Columns } from "../import-export/ImportTable";
import { User, defaultUser } from "../../../domain/entities/User";
import { useLoading, useSnackbar } from "@eyeseetea/d2-ui-components";
import { generateUid } from "../../../utils/uid";
import { D2Api } from "@eyeseetea/d2-api/2.36";

interface ReplicateUserFromTableProps {
userToReplicateId: Id;
onRequestClose: () => void;
settings: any;
api: D2Api;
}

export const ReplicateUserFromTable: React.FC<ReplicateUserFromTableProps> = props => {
const { compositionRoot } = useAppContext();
const { userToReplicateId, onRequestClose } = props;

const [userToReplicate, setUserToReplicate] = React.useState<User>(defaultUser);
const [isMounted, setIsMounted] = React.useState(false);

const loading = useLoading();
const snackbar = useSnackbar();

useEffect(() => {
compositionRoot.users.get([userToReplicateId]).run(
([user]) => {
if (!user) {
snackbar.error(i18n.t(`Unable to load user: ${userToReplicateId}`));
onRequestClose();
} else {
setUserToReplicate(user);
setIsMounted(true);
}
},
error => {
snackbar.error(i18n.t(`Error loading user(${userToReplicateId}): ${error}`));
onRequestClose();
}
);
}, [compositionRoot, loading, onRequestClose, snackbar, userToReplicateId]);

const columns: Columns[] = [
"username",
"password",
"firstName",
"surname",
"email",
"userRoles",
"userGroups",
"dataViewOrganisationUnits",
"organisationUnits",
];

const replicateUsers = useCallback(
async ({ users }: { users: User[] }) => {
loading.show(true, i18n.t("Replicating users"));

const newUsers: User[] = users.map(tableUser => {
return {
...userToReplicate,
id: generateUid(),
username: tableUser.username,
password: tableUser.password,
firstName: tableUser.firstName,
surname: tableUser.surname,
email: tableUser.email,
userGroups: tableUser.userGroups,
userRoles: tableUser.userRoles,
dataViewOrganisationUnits: tableUser.dataViewOrganisationUnits,
organisationUnits: tableUser.organisationUnits,
externalAuth: false,
twoFA: false,
openId: "",
ldapId: "",
};
});

return compositionRoot.users.import({ users: newUsers }).run(
() => {
loading.hide();
onRequestClose();
snackbar.success(i18n.t("Users replicated successfully"));
},
error => {
loading.hide();
snackbar.error(error);
}
);
},
[loading, compositionRoot.users, userToReplicate, onRequestClose, snackbar]
);

if (!isMounted) {
return null;
}

return (
<ImportTable
title={i18n.t("Replicate user")}
actionText={i18n.t("Replicate")}
usersFromFile={[]}
columns={columns}
onSubmit={replicateUsers}
onRequestClose={props.onRequestClose}
templateUser={userToReplicate}
warnings={[]}
/>
);
};

export default ReplicateUserFromTable;

0 comments on commit 80876a7

Please sign in to comment.