From ce47b822fecb4ea266efccd4d76616d7e194e561 Mon Sep 17 00:00:00 2001 From: NikolayRechkin Date: Fri, 27 Sep 2019 14:04:09 +0300 Subject: [PATCH 1/4] web: components: small change in avatar editor --- .../src/components/avatar-editor/index.js | 32 +++++++++---------- .../sub-components/avatar-editor-body.js | 1 + 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/web/ASC.Web.Components/src/components/avatar-editor/index.js b/web/ASC.Web.Components/src/components/avatar-editor/index.js index 15674d3540..d12be92a0d 100644 --- a/web/ASC.Web.Components/src/components/avatar-editor/index.js +++ b/web/ASC.Web.Components/src/components/avatar-editor/index.js @@ -32,6 +32,7 @@ class AvatarEditor extends React.Component { y: 0, width: 0, height: 0, + croppedImage: '', displayType: this.props.displayType !== 'auto' ? this.props.displayType : window.innerWidth <= desktop.match(/\d+/)[0] ? 'aside' : 'modal' } @@ -57,6 +58,9 @@ class AvatarEditor extends React.Component { } } onImageChange(file) { + this.setState({ + croppedImage: file + }) if (typeof this.props.onImageChange === 'function') this.props.onImageChange(file); } onDeleteImage() { @@ -69,17 +73,7 @@ class AvatarEditor extends React.Component { this.setState(data); } onLoadFileError(error) { - switch (error) { - case 0: - - break; - case 1: - - break; - case 2: - - break; - } + if (typeof this.props.onLoadFileError === 'function') this.props.onLoadFileError(error); } onLoadFile(file) { if (typeof this.props.onLoadFile === 'function') this.props.onLoadFile(file); @@ -87,12 +81,15 @@ class AvatarEditor extends React.Component { } onSaveButtonClick() { - this.props.onSave(this.state.isContainsFile, { - x: this.state.x, - y: this.state.y, - width: this.state.width, - height: this.state.height - }); + this.state.isContainsFile ? + this.props.onSave(this.state.isContainsFile, { + x: this.state.x, + y: this.state.y, + width: this.state.width, + height: this.state.height + },this.state.croppedImage) : + + this.props.onSave(this.state.isContainsFile); } onClose() { @@ -204,6 +201,7 @@ AvatarEditor.propTypes = { onDeleteImage: PropTypes.func, onLoadFile: PropTypes.func, onImageChange: PropTypes.func, + onLoadFileError: PropTypes.func, unknownTypeError: PropTypes.string, unknownError: PropTypes.string, displayType: PropTypes.oneOf(['auto', 'modal', 'aside']), diff --git a/web/ASC.Web.Components/src/components/avatar-editor/sub-components/avatar-editor-body.js b/web/ASC.Web.Components/src/components/avatar-editor/sub-components/avatar-editor-body.js index 70799a9d6b..6e1fa72420 100644 --- a/web/ASC.Web.Components/src/components/avatar-editor/sub-components/avatar-editor-body.js +++ b/web/ASC.Web.Components/src/components/avatar-editor/sub-components/avatar-editor-body.js @@ -227,6 +227,7 @@ class AvatarEditorBody extends React.Component { this.setState({ croppedImage: this.setEditorRef.current.getImage().toDataURL() }); + this.props.onImageChange(this.setEditorRef.current.getImage().toDataURL()); this.props.onPositionChange({ x: 0.5, y: 0.5, From 507a78c0e3fe177a87a3def1131ee5635135256b Mon Sep 17 00:00:00 2001 From: NikolayRechkin Date: Fri, 27 Sep 2019 14:05:35 +0300 Subject: [PATCH 2/4] web: people: create an avatar for a new user --- .../Section/Body/createUserForm.js | 129 ++++++++++++++---- 1 file changed, 101 insertions(+), 28 deletions(-) diff --git a/products/ASC.People/Client/src/components/pages/ProfileAction/Section/Body/createUserForm.js b/products/ASC.People/Client/src/components/pages/ProfileAction/Section/Body/createUserForm.js index 519df38fd1..341dd6420b 100644 --- a/products/ASC.People/Client/src/components/pages/ProfileAction/Section/Body/createUserForm.js +++ b/products/ASC.People/Client/src/components/pages/ProfileAction/Section/Body/createUserForm.js @@ -4,7 +4,7 @@ import { connect } from 'react-redux' import { Avatar, Button, Textarea, toastr, AvatarEditor } from 'asc-web-components' import { withTranslation } from 'react-i18next'; import { toEmployeeWrapper, getUserRole, getUserContactsPattern, getUserContacts, mapGroupsToGroupSelectorOptions, mapGroupSelectorOptionsToGroups, filterGroupSelectorOptions } from "../../../../../store/people/selectors"; -import { createProfile, loadAvatar } from '../../../../../store/profile/actions'; +import { createProfile, loadAvatar, createThumbnailsAvatar } from '../../../../../store/profile/actions'; import { MainContainer, AvatarContainer, MainFieldsContainer } from './FormFields/Form' import TextField from './FormFields/TextField' import PasswordField from './FormFields/PasswordField' @@ -43,38 +43,91 @@ class CreateUserForm extends React.Component { this.onSaveAvatar = this.onSaveAvatar.bind(this); this.onCloseAvatarEditor = this.onCloseAvatarEditor.bind(this); this.createAvatar = this.createAvatar.bind(this); + this.onLoadFileAvatar = this.onLoadFileAvatar.bind(this); + } createAvatar(userId,userName){ - this.props.updateAvatar( - userId, - { - croppedImage: this.state.croppedAvatarImage, - defaultImage: this.state.defaultAvatarImage - }) - .then((result) => { + this.props.createThumbnailsAvatar(userId, { + x: this.state.avatar.x, + y: this.state.avatar.y, + width: this.state.avatar.width, + height: this.state.avatar.height, + tmpFile: this.state.avatar.tmpFile + }) + .then((result) => { + if(result.status === 200){ toastr.success("Success"); this.props.history.push(`${this.props.settings.homepage}/view/${userName}`); - }) - .catch((error) => { - toastr.error(error.message); - this.props.history.push(`${this.props.settings.homepage}/view/${userName}`); - }); + } + }) + .catch((error) => { + toastr.error(error.message); + }); } openAvatarEditor(){ + let avatarDefault = this.state.profile.avatarDefault ? "data:image/png;base64," + this.state.profile.avatarDefault : null; + let _this = this; + if(avatarDefault !== null){ + let img = new Image(); + img.onload = function () { + _this.setState({ + avatar:{ + defaultWidth: img.width, + defaultHeight: img.height + } + }) + }; + img.src = avatarDefault; + } this.setState({ visibleAvatarEditor: true, }); } - onSaveAvatar(result){ - this.setState({ - croppedAvatarImage: result.croppedImage, - defaultAvatarImage: result.defaultImage, - }) + onLoadFileAvatar(file) { + let data = new FormData(); + let _this = this; + data.append("file", file); + data.append("Autosave", false); + this.props.loadAvatar(0, data) + .then((result) => { + var img = new Image(); + img.onload = function () { + var stateCopy = Object.assign({}, _this.state); + stateCopy.avatar = { + tmpFile: result.data.response.data, + image: result.data.response.data, + defaultWidth: img.width, + defaultHeight: img.height + } + _this.setState(stateCopy); + }; + img.src = result.data.response.data; + }) + .catch((error) => { + toastr.error(error.message); + }); + } + onSaveAvatar(isUpdate, result, file){ + var stateCopy = Object.assign({}, this.state); + + stateCopy.visibleAvatarEditor = false; + stateCopy.croppedAvatarImage = file; + if(isUpdate){ + stateCopy.avatar.x = Math.round(result.x*this.state.avatar.defaultWidth - result.width/2); + stateCopy.avatar.y = Math.round(result.y*this.state.avatar.defaultHeight - result.height/2); + stateCopy.avatar.width = result.width; + stateCopy.avatar.height = result.height; + } + this.setState(stateCopy); } onCloseAvatarEditor(){ this.setState({ visibleAvatarEditor: false, + croppedAvatarImage: "", + avatar:{ + tmpFile: "" + } }); } @@ -95,7 +148,6 @@ class CreateUserForm extends React.Component { return { visibleAvatarEditor: false, croppedAvatarImage: "", - defaultAvatarImage: "", isLoading: false, errors: { firstName: false, @@ -109,6 +161,16 @@ class CreateUserForm extends React.Component { allOptions: allOptions, options: [...allOptions], selected: selected + }, + avatar: { + tmpFile:"", + image: profile.avatarDefault ? "data:image/png;base64," + profile.avatarDefault : null, + defaultWidth: 0, + defaultHeight: 0, + x: 0, + y: 0, + width: 0, + height: 0 } }; } @@ -153,9 +215,12 @@ class CreateUserForm extends React.Component { this.props.createProfile(this.state.profile) .then((profile) => { - toastr.success("Success"); - this.props.history.push(`${this.props.settings.homepage}/view/${profile.userName}`); - //if(this.state.defaultImage !== '') this.createAvatar(profile.id,profile.userName); + if(this.state.avatar.tmpFile !== ""){ + this.createAvatar(profile.id,profile.userName); + }else{ + toastr.success("Success"); + this.props.history.push(`${this.props.settings.homepage}/view/${profile.userName}`); + } }) .catch((error) => { toastr.error(error.message) @@ -249,11 +314,18 @@ class CreateUserForm extends React.Component { editLabel={t("AddPhoto")} editAction={this.openAvatarEditor} /> - + + Date: Fri, 27 Sep 2019 14:06:13 +0300 Subject: [PATCH 3/4] web: components: bump version --- web/ASC.Web.Components/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/ASC.Web.Components/package.json b/web/ASC.Web.Components/package.json index 07e358583d..696fd1abcf 100644 --- a/web/ASC.Web.Components/package.json +++ b/web/ASC.Web.Components/package.json @@ -1,6 +1,6 @@ { "name": "asc-web-components", - "version": "1.0.100", + "version": "1.0.101", "description": "Ascensio System SIA component library", "license": "AGPL-3.0", "main": "dist/asc-web-components.js", From 1b293c6112511f4c8f5769e51042f76ab517b1ee Mon Sep 17 00:00:00 2001 From: Alexey Safronov Date: Fri, 27 Sep 2019 14:42:17 +0300 Subject: [PATCH 4/4] web: People: Fixed set filter by url --- .../components/pages/Home/Section/Filter/index.js | 12 ------------ products/ASC.People/Client/src/store/auth/actions.js | 10 ++++++++-- .../ASC.People/Client/src/store/people/actions.js | 6 +++++- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/products/ASC.People/Client/src/components/pages/Home/Section/Filter/index.js b/products/ASC.People/Client/src/components/pages/Home/Section/Filter/index.js index 8128d70c85..1d14adfc96 100644 --- a/products/ASC.People/Client/src/components/pages/Home/Section/Filter/index.js +++ b/products/ASC.People/Client/src/components/pages/Home/Section/Filter/index.js @@ -12,18 +12,6 @@ import { department } from "./../../../../../helpers/customNames"; import { withRouter } from "react-router"; -import Filter from "../../../../../store/people/filter"; -import { - EMPLOYEE_STATUS, - ACTIVATION_STATUS, - ROLE, - GROUP, - SEARCH, - SORT_BY, - SORT_ORDER, - PAGE, - PAGE_COUNT -} from "../../../../../helpers/constants"; import { getFilterByLocation } from "../../../../../helpers/converters"; const getEmployeeStatus = filterValues => { diff --git a/products/ASC.People/Client/src/store/auth/actions.js b/products/ASC.People/Client/src/store/auth/actions.js index 5d0441fea7..b7eed49761 100644 --- a/products/ASC.People/Client/src/store/auth/actions.js +++ b/products/ASC.People/Client/src/store/auth/actions.js @@ -2,6 +2,7 @@ import * as api from "../services/api"; import { setGroups, fetchPeopleAsync } from "../people/actions"; import setAuthorizationToken from "../../store/services/setAuthorizationToken"; import { getFilterByLocation } from "../../helpers/converters"; +import config from "../../../package.json"; export const LOGIN_POST = "LOGIN_POST"; export const SET_CURRENT_USER = "SET_CURRENT_USER"; @@ -60,9 +61,14 @@ export async function getUserInfo(dispatch) { dispatch(setGroups(groupResp.data.response)); - const newFilter = getFilterByLocation(window.location); + var re = new RegExp(`${config.homepage}((/?)$|/filter)`, "gm"); + const match = window.location.pathname.match(re); - await fetchPeopleAsync(dispatch, newFilter); + if (match && match.length > 0) + { + const newFilter = getFilterByLocation(window.location); + await fetchPeopleAsync(dispatch, newFilter); + } return dispatch(setIsLoaded(true)); } diff --git a/products/ASC.People/Client/src/store/people/actions.js b/products/ASC.People/Client/src/store/people/actions.js index 6a246de579..744a8553ff 100644 --- a/products/ASC.People/Client/src/store/people/actions.js +++ b/products/ASC.People/Client/src/store/people/actions.js @@ -86,7 +86,7 @@ export function deselectUser(user) { }; } -export function setFilter(filter) { +export function setFilterUrl(filter) { const defaultFilter = Filter.getDefault(); const params = []; @@ -121,6 +121,10 @@ export function setFilter(filter) { if (params.length > 0) { history.push(`${config.homepage}/filter?${params.join("&")}`); } +} + +export function setFilter(filter) { + setFilterUrl(filter); return { type: SET_FILTER, filter