diff --git a/frontend/pages/admin/UserManagementPage/components/UserForm/_styles.scss b/frontend/pages/admin/UserManagementPage/components/UserForm/_styles.scss
index 8f5e357c42..58f9806a10 100644
--- a/frontend/pages/admin/UserManagementPage/components/UserForm/_styles.scss
+++ b/frontend/pages/admin/UserManagementPage/components/UserForm/_styles.scss
@@ -1,4 +1,9 @@
.create-user-form {
+ &__new-user-container {
+ margin-top: $pad-large;
+ margin-bottom: $pad-large;
+ }
+
&__sso-input {
margin-top: $pad-large;
margin-bottom: $pad-large;
@@ -51,6 +56,15 @@
&__radio-input {
margin-bottom: $pad-medium;
+
+ &.disabled {
+ .radio__control {
+ background-color: $ui-fleet-black-25;
+ }
+ .radio__label {
+ color: $ui-fleet-black-25;
+ }
+ }
}
&__btn-wrap {
@@ -66,9 +80,38 @@
margin-bottom: 8px;
}
+ &__password {
+ width: 98%;
+ float: left;
+ padding: 0 $pad-medium 0 0;
+ box-sizing: border-box;
+
+ .input-icon-field {
+ width: 100%;
+ }
+ }
+
+ &__details {
+ float: right;
+ width: 2%;
+
+ .icon-tooltip {
+ margin-top: 12px;
+ }
+
+ .hint {
+ color: $core-fleet-black;
+
+ &--brand {
+ color: $core-vibrant-blue;
+ }
+ }
+ }
+
.sublabel {
margin: 0px;
}
+
&__tooltip-text {
width: 300px;
}
diff --git a/frontend/pages/admin/UserManagementPage/helpers/userManagementHelpers.tests.ts b/frontend/pages/admin/UserManagementPage/helpers/userManagementHelpers.tests.ts
index 2dab0530b3..c290778a73 100644
--- a/frontend/pages/admin/UserManagementPage/helpers/userManagementHelpers.tests.ts
+++ b/frontend/pages/admin/UserManagementPage/helpers/userManagementHelpers.tests.ts
@@ -1,5 +1,5 @@
import { userStub, userTeamStub } from "test/stubs";
-import { IFormData } from "../components/UserForm/UserForm";
+import { IFormData, NewUserType } from "../components/UserForm/UserForm";
import userManagementHelpers from "./userManagementHelpers";
describe("userManagementHelpers module", () => {
@@ -19,6 +19,7 @@ describe("userManagementHelpers module", () => {
email: "newemail@test.com",
sso_enabled: false,
name: "Gnar Mike",
+ newUserType: NewUserType.AdminCreated, // TODO revisit test
global_role: "admin",
teams: [updatedTeam, newTeam],
};
diff --git a/frontend/redux/nodes/entities/users/actions.js b/frontend/redux/nodes/entities/users/actions.js
index 65d995f95a..559f46e9a2 100644
--- a/frontend/redux/nodes/entities/users/actions.js
+++ b/frontend/redux/nodes/entities/users/actions.js
@@ -3,12 +3,17 @@ import Fleet from "fleet";
import config from "redux/nodes/entities/users/config";
import { formatErrorResponse } from "redux/nodes/entities/base/helpers";
import { logoutUser, updateUserSuccess } from "redux/nodes/auth/actions";
+import { create } from "lodash";
const { actions } = config;
// Actions for admin to require password reset for a user
export const REQUIRE_PASSWORD_RESET_SUCCESS = "REQUIRE_PASSWORD_RESET_SUCCESS";
export const REQUIRE_PASSWORD_RESET_FAILURE = "REQUIRE_PASSWORD_RESET_FAILURE";
+export const CREATE_USER_WITHOUT_INVITE_SUCCESS =
+ "CREATE_USER_WITHOUT_INVITE_SUCCESS";
+export const CREATE_USER_WITHOUT_INVITE_FAILURE =
+ "CREATE_USER_WITHOUT_INVITE_FAILURE";
export const requirePasswordResetSuccess = (user) => {
return {
@@ -24,6 +29,21 @@ export const requirePasswordResetFailure = (errors) => {
};
};
+// TODO does below need user
+export const createUserWithoutInviteSuccess = () => {
+ return {
+ type: CREATE_USER_WITHOUT_INVITE_SUCCESS,
+ payload: {},
+ };
+};
+
+export const createUserWithoutInviteFailure = (errors) => {
+ return {
+ type: CREATE_USER_WITHOUT_INVITE_FAILURE,
+ payload: { errors },
+ };
+};
+
export const changePassword = (
user,
{ new_password: newPassword, old_password: oldPassword }
@@ -77,6 +97,23 @@ export const confirmEmailChange = (user, token) => {
};
};
+export const createUserWithoutInvitation = (formData) => {
+ return (dispatch) => {
+ return Fleet.users
+ .createUserWithoutInvitation(formData)
+ .then((response) => {
+ return dispatch(createUserWithoutInviteSuccess(response));
+ })
+ .catch((response) => {
+ const errorsObject = formatErrorResponse(response);
+
+ dispatch(createUserWithoutInviteFailure(errorsObject));
+
+ throw errorsObject;
+ });
+ };
+};
+
export const deleteSessions = (user) => {
const { successAction, destroyFailure, destroySuccess } = actions;
@@ -156,6 +193,7 @@ export default {
...actions,
changePassword,
confirmEmailChange,
+ createUserWithoutInvitation,
enableUser,
requirePasswordReset,
deleteSessions,
diff --git a/frontend/redux/nodes/entities/users/reducer.js b/frontend/redux/nodes/entities/users/reducer.js
index c21398fe65..5d2ee15e67 100644
--- a/frontend/redux/nodes/entities/users/reducer.js
+++ b/frontend/redux/nodes/entities/users/reducer.js
@@ -1,6 +1,8 @@
import {
REQUIRE_PASSWORD_RESET_FAILURE,
REQUIRE_PASSWORD_RESET_SUCCESS,
+ CREATE_USER_WITHOUT_INVITE_FAILURE,
+ CREATE_USER_WITHOUT_INVITE_SUCCESS,
} from "./actions";
import config, { initialState } from "./config";
@@ -22,6 +24,22 @@ export default (state = initialState, { type, payload }) => {
loading: false,
errors: payload.errors,
};
+ case CREATE_USER_WITHOUT_INVITE_SUCCESS:
+ return {
+ ...state,
+ errors: {},
+ loading: false,
+ data: {
+ ...state.data,
+ },
+ };
+ case CREATE_USER_WITHOUT_INVITE_FAILURE:
+ return {
+ ...state,
+ loading: false,
+ errors: payload.errors,
+ };
+
default:
return config.reducer(state, { type, payload });
}