Skip to content
Snippets Groups Projects
Unverified Commit 23082730 authored by Anton Kulyk's avatar Anton Kulyk Committed by GitHub
Browse files

Clean up user selectors (#26477)

* Simplify null checks

* Use actual `User` type in plugins file

* Sort plugins file imports

* Add `login_attributes` type to `User`

* Convert user selectors to TypeScript

* Make `currentUser` in `State` nullable

* Simplify personal collection ID selectors

* Handle nullable current user

* Use `checkNotNull` to check nullable user object

* Remove explicit `User` type in `checkNotNull`

* Simplify `getIsSsoUser` selector
parent 5e06ef21
No related branches found
No related tags found
No related merge requests found
Showing
with 71 additions and 22 deletions
......@@ -8,6 +8,7 @@ export const createMockUser = (opts?: Partial<User>): User => ({
email: "user@metabase.test",
locale: null,
google_auth: false,
login_attributes: null,
is_active: true,
is_qbnewb: false,
is_superuser: false,
......
......@@ -19,6 +19,7 @@ export interface BaseUser {
export interface User extends BaseUser {
google_auth: boolean;
login_attributes: string[] | null;
is_installer: boolean;
has_invited_second_user: boolean;
has_question_and_dashboard: boolean;
......
......@@ -11,7 +11,7 @@ import { SetupState } from "./setup";
export interface State {
admin: AdminState;
app: AppState;
currentUser: User;
currentUser: User | null;
embed: EmbedState;
entities: EntitiesState;
form: FormState;
......
import { connect } from "react-redux";
import { checkNotNull } from "metabase/core/utils/types";
import { getUser } from "metabase/selectors/user";
import { State } from "metabase-types/store";
import type { State } from "metabase-types/store";
import { updatePassword, validatePassword } from "../../actions";
import UserPasswordForm from "../../components/UserPasswordForm";
const mapStateToProps = (state: State) => ({
user: getUser(state),
user: checkNotNull(getUser(state)),
onValidatePassword: validatePassword,
onSubmit: updatePassword,
});
......
import { connect } from "react-redux";
import { checkNotNull } from "metabase/core/utils/types";
import { getUser } from "metabase/selectors/user";
import { State } from "metabase-types/store";
import type { State } from "metabase-types/store";
import UserProfileForm from "../../components/UserProfileForm";
import { updateUser } from "../../actions";
import { getIsSsoUser, getLocales } from "../../selectors";
const mapStateToProps = (state: State) => ({
user: getUser(state),
user: checkNotNull(getUser(state)),
locales: getLocales(state),
isSsoUser: getIsSsoUser(state),
});
......
import { createSelector } from "reselect";
import { getUser } from "metabase/selectors/user";
import { PLUGIN_IS_PASSWORD_USER } from "metabase/plugins";
import { getSettings } from "metabase/selectors/settings";
export const getIsSsoUser = createSelector([getUser], user => {
import { PLUGIN_IS_PASSWORD_USER } from "metabase/plugins";
export const getIsSsoUser = createSelector(getUser, user => {
if (!user) {
return false;
}
return !PLUGIN_IS_PASSWORD_USER.every(predicate => predicate(user));
});
......
import { connect } from "react-redux";
import { checkNotNull } from "metabase/core/utils/types";
import { getUser } from "metabase/selectors/user";
import { State } from "metabase-types/store";
import type { State } from "metabase-types/store";
import HomeGreeting from "../../components/HomeGreeting";
const mapStateToProps = (state: State) => ({
user: getUser(state),
user: checkNotNull(getUser(state)),
showLogo: state.settings.values["show-metabot"],
});
......
import { t } from "ttag";
import React from "react";
import { t } from "ttag";
import PluginPlaceholder from "metabase/plugins/components/PluginPlaceholder";
import {
import type {
DatabaseEntityId,
PermissionSubject,
} from "metabase/admin/permissions/types";
import {
Collection,
import type {
Bookmark,
GroupsPermissions,
Collection,
Dataset,
Group,
GroupsPermissions,
User,
} from "metabase-types/api";
import { AdminPathKey, State } from "metabase-types/store";
import { User } from "metabase-types/types/User";
import Question from "metabase-lib/Question";
import type { AdminPathKey, State } from "metabase-types/store";
import type Question from "metabase-lib/Question";
import { PluginGroupManagersType } from "./types";
// Plugin integration points. All exports must be objects or arrays so they can be mutated by plugins.
......
......@@ -308,7 +308,7 @@ async function handleQBInit(
question = question.lockDisplay();
const currentUser = getUser(getState());
if (currentUser.is_qbnewb) {
if (currentUser?.is_qbnewb) {
uiControls.isShowingNewbModal = true;
MetabaseAnalytics.trackStructEvent("QueryBuilder", "Show Newb Modal");
}
......
import { createSelector } from "reselect";
import { PLUGIN_APPLICATION_PERMISSIONS } from "metabase/plugins";
export const getUser = state => state.currentUser;
import type { State } from "metabase-types/store";
export const getUser = (state: State) => state.currentUser;
export const getUserId = createSelector([getUser], user => user?.id);
export const getUserIsAdmin = createSelector(
[getUser],
user => (user && user.is_superuser) || false,
user => user?.is_superuser || false,
);
export const canManageSubscriptions = createSelector(
......@@ -21,10 +23,10 @@ export const canManageSubscriptions = createSelector(
export const getUserAttributes = createSelector(
[getUser],
user => (user && user.login_attributes) || [],
user => user?.login_attributes || [],
);
export const getUserPersonalCollectionId = createSelector(
[getUser],
user => (user && user.personal_collection_id) || null,
user => user?.personal_collection_id,
);
import { createMockUser } from "metabase-types/api/mocks";
import { createMockState } from "metabase-types/store/mocks";
import { getUserIsAdmin } from "./user";
describe("metabase/selectors/user", () => {
it("should return true if user is an admin", () => {
const state = {
currentUser: {
is_superuser: true,
},
};
const state = createMockState({
currentUser: createMockUser({ is_superuser: true }),
});
expect(getUserIsAdmin(state)).toBe(true);
});
it("should return false if user is not an admin", () => {
const state = {
currentUser: {
is_superuser: false,
},
};
const state = createMockState({
currentUser: createMockUser({ is_superuser: false }),
});
expect(getUserIsAdmin(state)).toBe(false);
});
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment