Web: Client: added paging to accessRights page, added new translations, added filter to accessRights page, renamed actions, deleted unused selectors, added filter to getListAdmins api

This commit is contained in:
Nikita Gopienko 2019-11-08 09:27:00 +03:00
parent 90059f4c8b
commit 43fb0bd7b5
10 changed files with 388 additions and 146 deletions

View File

@ -7,9 +7,7 @@ import { I18nextProvider, withTranslation } from "react-i18next";
import styled from "styled-components";
import {
changeAdmins,
getListAdmins,
getListUsers,
getUserById
fetchPeople
} from "../../../../../store/settings/actions";
import {
Text,
@ -27,6 +25,7 @@ import {
toastr,
RequestLoader
} from "asc-web-components";
import { getUserRole } from "../../../../../store/settings/selectors";
const MainContainer = styled.div`
padding: 16px 16px 16px 24px;
@ -128,38 +127,23 @@ class PureAccessRights extends Component {
}
componentDidMount() {
const {
getListAdmins,
getListUsers,
getUserById,
ownerId,
productId
} = this.props;
const { fetchPeople } = this.props;
getUserById(ownerId).catch(error => {
toastr.error(error);
//console.log("accessRights getUserById", error);
});
const newFilter = this.onFilter();
getListUsers().catch(error => {
fetchPeople(newFilter).catch(error => {
toastr.error(error);
//console.log("accessRights getListAdmins", error);
});
getListAdmins(productId).catch(error => {
toastr.error(error);
//console.log("accessRights getListAdmins", error);
});
}
onChangeAdmin = (userIds, isAdmin) => {
this.onLoading(true);
const { changeAdmins, productId } = this.props;
const newFilter = this.onFilter();
changeAdmins(userIds, productId, isAdmin)
changeAdmins(userIds, productId, isAdmin, newFilter)
.catch(error => {
toastr.error("accessRights onChangeAdmin", error);
//console.log("accessRights onChangeAdmin", error)
})
.finally(() => {
this.onLoading(false);
@ -191,12 +175,86 @@ class PureAccessRights extends Component {
options.filter(option => option.label.indexOf(template) > -1);
onLoading = status => {
console.log("onLoading status", status);
this.setState({ isLoading: status });
};
onFilter = () => {
const { filter } = this.props;
const newFilter = filter.clone();
newFilter.page = 0;
newFilter.role = "admin";
return newFilter;
};
pageItems = () => {
const { t, filter } = this.props;
if (filter.total < filter.pageCount) return [];
const totalPages = Math.ceil(filter.total / filter.pageCount);
return [...Array(totalPages).keys()].map(item => {
return {
key: item,
label: t("PageOfTotalPage", { page: item + 1, totalPage: totalPages })
};
});
};
onChangePage = pageItem => {
const { filter, getListAdmins } = this.props;
const newFilter = filter.clone();
newFilter.page = pageItem.key;
this.onLoading(true);
getListAdmins(newFilter)
.catch(res => console.log(res))
.finally(() => this.onLoading(false));
};
onChangePageSize = pageItem => {
const { filter, getListAdmins } = this.props;
const newFilter = filter.clone();
newFilter.pageCount = pageItem.key;
newFilter.page = 0;
this.onLoading(true);
getListAdmins(newFilter)
.catch(res => console.log(res))
.finally(() => this.onLoading(false));
};
onPrevClick = e => {
const { filter, getListAdmins } = this.props;
if (!filter.hasPrev()) {
e.preventDefault();
return;
}
const newFilter = filter.clone();
newFilter.page--;
this.onLoading(true);
getListAdmins(newFilter)
.catch(res => console.log(res))
.finally(() => this.onLoading(false));
};
onNextClick = e => {
const { filter, getListAdmins } = this.props;
if (!filter.hasNext()) {
e.preventDefault();
return;
}
const newFilter = filter.clone();
newFilter.page++;
this.onLoading(true);
getListAdmins(newFilter)
.catch(res => console.log(res))
.finally(() => this.onLoading(false));
};
render() {
const { t, owner, admins } = this.props;
const { t, owner, admins, filter } = this.props;
const { showSelector, options, selectedOptions, isLoading } = this.state;
const OwnerOpportunities = t("AccessRightsOwnerOpportunities").split("|");
@ -206,6 +264,24 @@ class PureAccessRights extends Component {
{ key: 100, label: t("CountPerPage", { count: 100 }) }
];
const pageItems = this.pageItems();
const emptyPageSelection = {
key: 0,
label: t("PageOfTotalPage", { page: 1, totalPage: 1 })
};
const emptyCountSelection = {
key: 0,
label: t("CountPerPage", { count: 25 })
};
const selectedPageItem =
pageItems.find(x => x.key === filter.page) || emptyPageSelection;
const selectedCountItem =
countItems.find(x => x.key === filter.pageCount) || emptyCountSelection;
return (
<MainContainer>
<RequestLoader
@ -290,7 +366,7 @@ class PureAccessRights extends Component {
const element = (
<Avatar
size="small"
role="admin"
role={getUserRole(user)}
userName={user.displayName}
source={user.avatarSmall}
/>
@ -317,45 +393,48 @@ class PureAccessRights extends Component {
>
{user.displayName}
</Link>
<div style={{ maxWidth: 120 }} />
<div style={{ marginLeft: "60px" }}>
<IconButton
size="16"
isDisabled={isLoading}
onClick={this.onChangeAdmin.bind(
this,
[user.id],
false
)}
iconName={"CatalogTrashIcon"}
isFill={true}
isClickable={false}
/>
</div>
{!user.isOwner ? (
<div style={{ marginLeft: "60px" }}>
<IconButton
size="16"
isDisabled={isLoading}
onClick={this.onChangeAdmin.bind(
this,
[user.id],
false
)}
iconName={"CatalogTrashIcon"}
isFill={true}
isClickable={false}
/>
</div>
) : (
<div />
)}
</RowContent>
</Row>
);
})}
</RowContainer>
</div>
{admins.length > 25 ? (
{filter.total > filter.pageCount ? (
<div className="wrapper">
<Paging
previousLabel={t("PreviousPage")}
nextLabel={t("NextPage")}
openDirection="top"
displayItems={false}
countItems={countItems}
selectedPageItem={{ label: "1 of 1" }}
selectedCountItem={{ label: "25 per page" }}
previousAction={() => console.log("previousAction")}
nextAction={() => console.log("nextAction")}
onSelectPage={a => console.log(a)}
onSelectCount={a => console.log(a)}
//pageItems={pageItems}
//disablePrevious={!filter.hasPrev()}
//disableNext={!filter.hasNext()}
pageItems={pageItems}
displayItems={false}
selectedPageItem={selectedPageItem}
selectedCountItem={selectedCountItem}
onSelectPage={this.onChangePage}
onSelectCount={this.onChangePageSize}
previousAction={this.onPrevClick}
nextAction={this.onNextClick}
disablePrevious={!filter.hasPrev()}
disableNext={!filter.hasNext()}
/>
</div>
) : null}
@ -424,24 +503,21 @@ const AccessRights = props => {
};
function mapStateToProps(state) {
const { ownerId } = state.auth.settings;
const { admins, options, owner } = state.settings.accessRight;
//console.log("ADSelector options", users);
const { filter } = state.settings;
return {
admins,
productId: state.auth.modules[0].id,
owner,
ownerId,
options
options,
filter
};
}
AccessRights.defaultProps = {
admins: [],
productId: "",
ownerId: "",
owner: {},
options: []
};
@ -449,12 +525,11 @@ AccessRights.defaultProps = {
AccessRights.propTypes = {
admins: PropTypes.arrayOf(PropTypes.object),
productId: PropTypes.string,
ownerId: PropTypes.string,
owner: PropTypes.object,
options: PropTypes.arrayOf(PropTypes.object)
};
export default connect(
mapStateToProps,
{ getUserById, changeAdmins, getListAdmins, getListUsers }
{ changeAdmins, fetchPeople }
)(withRouter(AccessRights));

View File

@ -68,5 +68,6 @@
"Culture_en-US": "English (United States)",
"Culture_ru-RU": "Russian (Russia)",
"LearnMore": "Learn more...",
"CountPerPage": "{{count}} per page"
"CountPerPage": "{{count}} per page",
"PageOfTotalPage": "{{page}} of {{totalPage}}"
}

View File

@ -67,5 +67,6 @@
"Culture_en-US": "Английский (США)",
"Culture_ru-RU": "Русский (Россия)",
"LearnMore": "Подробнее...",
"CountPerPage": "{{count}} на странице"
"CountPerPage": "{{count}} на странице",
"PageOfTotalPage": "{{page}} из {{totalPage}}"
}

View File

@ -1,10 +1,10 @@
import { combineReducers } from 'redux';
import authReducer from './auth/reducer';
import peopleReducer from './settings/reducer';
import settingsReducer from './settings/reducer';
const rootReducer = combineReducers({
auth: authReducer,
settings: peopleReducer
settings: settingsReducer
});
export default rootReducer;

View File

@ -1,5 +1,6 @@
import { request, setAuthorizationToken } from "./client";
import axios from "axios";
import Filter from "../settings/filter";
export function login(userName, password) {
const data = {
@ -156,10 +157,11 @@ export function getUserList() {
});
}
export function getProductAdminsList(productId) {
export function getListAdmins(filter = Filter.getDefault()) {
const params = filter.toUrlParams();
return request({
method: "get",
url: `/settings/security/administrator/${productId}`
url: `/people/filter.json?${params}`
});
}
@ -178,7 +180,7 @@ export function changeProductAdmin(userId, productId, administrator) {
export function getUserById(userId) {
return request({
method: "get",
url: `/people/${userId}`,
url: `/people/${userId}`
});
}

View File

@ -0,0 +1,14 @@
export const toUrlParams = (obj, skipNull) => {
let str = "";
for (var key in obj) {
if (skipNull && !obj[key]) continue;
if (str !== "") {
str += "&";
}
str += key + "=" + encodeURIComponent(obj[key]);
}
return str;
};

View File

@ -1,16 +1,15 @@
import * as api from "../services/api";
import axios from "axios";
import {
getUsers,
//getAdmins,
getSelectorOptions,
getUserOptions
} from "./selectors";
import { getSelectorOptions, getUserOptions } from "./selectors";
import Filter from "./filter";
export const SET_USERS = "SET_USERS";
export const SET_ADMINS = "SET_ADMINS";
export const SET_OWNER = "SET_OWNER";
export const SET_FILTER = "SET_FILTER";
export const SET_GREETING_SETTINGS = "SET_GREETING_SETTINGS";
export function setUsers(options) {
return {
type: SET_USERS,
@ -19,7 +18,6 @@ export function setUsers(options) {
}
export function setAdmins(admins) {
console.log(admins)
return {
type: SET_ADMINS,
admins
@ -33,41 +31,26 @@ export function setOwner(owner) {
};
}
export function getListUsers() {
return (dispatch, getState) => {
return api.getUserList().then(users => {
const { auth } = getState();
const { /*settings,*/ modules } = auth;
//const { ownerId } = settings;
//const convertedUsers = getUsers(users, ownerId);
//const withoutAdmins = getAdmins(convertedUsers);
//const options = getSelectorOptions(withoutAdmins);
api.getProductAdminsList(modules[0].id).then(admins => {
const options = getUserOptions(users, admins);
const newOptions = getSelectorOptions(options);
dispatch(setUsers(newOptions));
});
});
export function setFilter(filter) {
return {
type: SET_FILTER,
filter
};
}
export function getListAdmins(productId) {
return (dispatch, getState) => {
return api.getProductAdminsList(productId).then(admins => {
const { auth } = getState();
const { settings } = auth;
const { ownerId } = settings;
const convertedAdmins = getUsers(admins, ownerId);
dispatch(setAdmins(convertedAdmins));
});
export function setGreetingSettings(title) {
return {
type: SET_GREETING_SETTINGS,
title
};
}
export function changeAdmins(userIds, productId, isAdmin) {
return (dispatch, getState) => {
export function changeAdmins(userIds, productId, isAdmin, filter) {
let filterData = filter && filter.clone();
if (!filterData) {
filterData = Filter.getDefault();
}
return dispatch => {
return axios
.all(
userIds.map(userId =>
@ -75,30 +58,58 @@ export function changeAdmins(userIds, productId, isAdmin) {
)
)
.then(() =>
axios.all([api.getUserList(), api.getProductAdminsList(productId)])
axios.all([api.getUserList(filterData), api.getListAdmins(filterData)])
)
.then(
axios.spread((users, admins) => {
const { auth } = getState();
const { settings } = auth;
const { ownerId } = settings;
//const convertedUsers = getUsers(users, ownerId);
//const withoutAdmins = getAdmins(convertedUsers);
//const options = getSelectorOptions(withoutAdmins);
const options = getUserOptions(users, admins);
const newOptions = getSelectorOptions(options);
filterData.total = admins.length;
dispatch(setUsers(newOptions));
const convertedAdmins = getUsers(admins, ownerId);
dispatch(setAdmins(convertedAdmins));
dispatch(setAdmins(admins));
dispatch(setFilter(filterData));
})
);
};
}
export function getUserById(userId) {
export function fetchPeople(filter) {
let filterData = filter && filter.clone();
if (!filterData) {
filterData = Filter.getDefault();
}
return dispatch => {
return api.getUserById(userId).then(owner => dispatch(setOwner(owner)));
return api.getUserList().then(users => {
api.getListAdmins(filterData).then(admins => {
const options = getUserOptions(users, admins);
const newOptions = getSelectorOptions(options);
filterData.total = admins.length;
const owner = admins.find(x => x.isOwner);
dispatch(setUsers(newOptions));
dispatch(setAdmins(admins));
dispatch(setFilter(filterData));
dispatch(setOwner(owner));
});
});
};
}
export function setGreetingTitle(greetingTitle) {
return dispatch => {
return api.setGreetingSettings(greetingTitle).then(res => {
dispatch(setGreetingSettings(greetingTitle));
});
};
}
export function restoreGreetingTitle() {
return dispatch => {
return api.restoreGreetingSettings().then(res => {
dispatch(setGreetingSettings(res.companyName));
});
};
}

View File

@ -0,0 +1,142 @@
import { toUrlParams } from "../services/converter";
const DEFAULT_PAGE = 0;
const DEFAULT_PAGE_COUNT = 25;
const DEFAULT_TOTAL = 0;
const DEFAULT_SORT_BY = "firstname";
const DEFAULT_SORT_ORDER = "ascending";
const DEFAULT_EMPLOYEE_STATUS = null;
const DEFAULT_ACTIVATION_STATUS = null;
const DEFAULT_ROLE = null;
const DEFAULT_SEARCH = null;
const DEFAULT_GROUP = null;
class Filter {
static getDefault(total = DEFAULT_TOTAL) {
return new Filter(DEFAULT_PAGE, DEFAULT_PAGE_COUNT, total);
}
constructor(
page = DEFAULT_PAGE,
pageCount = DEFAULT_PAGE_COUNT,
total = DEFAULT_TOTAL,
sortBy = DEFAULT_SORT_BY,
sortOrder = DEFAULT_SORT_ORDER,
employeeStatus = DEFAULT_EMPLOYEE_STATUS,
activationStatus = DEFAULT_ACTIVATION_STATUS,
role = DEFAULT_ROLE,
search = DEFAULT_SEARCH,
group = DEFAULT_GROUP
) {
this.page = page;
this.pageCount = pageCount;
this.sortBy = sortBy;
this.sortOrder = sortOrder;
this.employeeStatus = employeeStatus;
this.activationStatus = activationStatus;
this.role = role;
this.search = search;
this.total = total;
this.group = group;
}
getStartIndex = () => {
return this.page * this.pageCount;
};
hasNext = () => {
return this.total - this.getStartIndex() > this.pageCount;
};
hasPrev = () => {
return this.page > 0;
};
toDto = () => {
const {
pageCount,
sortBy,
sortOrder,
employeeStatus,
activationStatus,
role,
search,
group
} = this;
let dtoFilter = {
StartIndex: this.getStartIndex(),
Count: pageCount,
sortby: sortBy,
sortorder: sortOrder,
employeestatus: employeeStatus,
activationstatus: activationStatus,
filtervalue: search,
groupId: group
//fields: "id,status,isAdmin,isOwner,isVisitor,activationStatus,userName,email,displayName,avatarSmall,
//listAdminModules,birthday,title,location,isLDAP,isSSO"
};
switch (role) {
case "admin":
dtoFilter.isadministrator = true;
break;
case "user":
dtoFilter.employeeType = 1;
break;
case "guest":
dtoFilter.employeeType = 2;
break;
default:
break;
}
return dtoFilter;
};
toUrlParams = () => {
const dtoFilter = this.toDto();
const str = toUrlParams(dtoFilter, true);
return str;
};
clone(onlySorting) {
return onlySorting
? new Filter(
DEFAULT_PAGE,
DEFAULT_PAGE_COUNT,
DEFAULT_TOTAL,
this.sortBy,
this.sortOrder
)
: new Filter(
this.page,
this.pageCount,
this.total,
this.sortBy,
this.sortOrder,
this.employeeStatus,
this.activationStatus,
this.role,
this.search,
this.group
);
}
equals(filter) {
const equals =
this.employeeStatus === filter.employeeStatus &&
this.activationStatus === filter.activationStatus &&
this.role === filter.role &&
this.group === filter.group &&
this.search === filter.search &&
this.sortBy === filter.sortBy &&
this.sortOrder === filter.sortOrder &&
this.page === filter.page &&
this.pageCount === filter.pageCount;
return equals;
}
}
export default Filter;

View File

@ -1,4 +1,6 @@
import { SET_USERS, SET_ADMINS, SET_OWNER } from "./actions";
import { SET_USERS, SET_ADMINS, SET_OWNER, SET_GREETING_SETTINGS, SET_FILTER } from "./actions";
import Filter from "./filter";
const initialState = {
@ -7,6 +9,9 @@ const initialState = {
admins: [],
owner: {}
},
filter: Filter.getDefault(),
greetingSettings: ''
};
const peopleReducer = (state = initialState, action) => {
@ -29,16 +34,19 @@ const peopleReducer = (state = initialState, action) => {
owner: action.owner
})
});
case SET_FILTER:
return Object.assign({}, state, {
filter: action.filter
});
case SET_GREETING_SETTINGS:
return Object.assign({}, state, {
greetingSettings: action.title
});
default:
return state;
}
};
export default peopleReducer;
/*
return Object.assign({}, state, {
selector: Object.assign({}, state.selector, {
users: action.users
})
});
*/
export default peopleReducer;

View File

@ -1,24 +1,4 @@
import { filter, differenceBy } from "lodash";
export function getUsers(users, ownerId) {
return filter(users, function(f) {
return f.id !== ownerId;
});
}
/*export function getAdmins(users) {
const newArray = [];
users.map(user => {
if (user.listAdminModules !== undefined) {
if (!user.listAdminModules.includes("people")) {
newArray.push(user);
}
} else {
newArray.push(user);
}
});
return newArray.filter(user => !user.isVisitor);
}*/
import { differenceBy } from "lodash";
export function getSelectorOptions(users) {
return users.map(user => {
@ -34,3 +14,11 @@ export function getUserOptions(users, admins) {
const sorted = differenceBy(users, admins, "id");
return sorted.filter(user => !user.isVisitor);
}
export const getUserRole = user => {
if (user.isOwner) return "owner";
else if (user.isAdmin) return "admin";
else if (user.listAdminModules !== undefined && user.listAdminModules.includes("people")) return "admin";
else if (user.isVisitor) return "guest";
else return "user";
};