This commit is contained in:
Daniil Senkiv 2019-12-25 11:30:44 +03:00
commit c152d60950
16 changed files with 99 additions and 52 deletions

View File

@ -1,11 +1,15 @@
import React from "react";
import styled from "styled-components";
import isEqual from "lodash/isEqual";
import { ComboBox, TextInput } from "asc-web-components";
import { ComboBox, TextInput, IconButton } from "asc-web-components";
const Container = styled.div`
display: flex;
margin: 0 0 16px 0;
.remove_icon {
margin-left: 8px;
}
`;
class ContactField extends React.Component {
@ -26,7 +30,10 @@ class ContactField extends React.Component {
inputName,
inputValue,
inputOnChange
inputOnChange,
removeButtonName,
removeButtonOnChange
} = this.props;
return (
@ -46,6 +53,15 @@ class ContactField extends React.Component {
isDisabled={isDisabled}
onChange={inputOnChange}
/>
<IconButton
id={removeButtonName}
className="remove_icon"
size="16"
onClick={removeButtonOnChange}
iconName={"CatalogTrashIcon"}
isFill={true}
isClickable={true}
/>
</Container>
);
}

View File

@ -12,6 +12,10 @@ const Container = styled.div`
width: 120px;
margin: 0 8px 0 0;
}
.field-select > div > div:first-child.combo-button-label {
color: #A3A9AE;
}
`;
const getOptions = (patterns, keyPrefix) => {
@ -30,6 +34,7 @@ const renderItems = (
pattern,
onTypeChange,
onTextChange,
onRemove,
isDisabled
) => {
const items = contacts.map((contact, index) => {
@ -50,6 +55,8 @@ const renderItems = (
inputName={prefix + "value"}
inputValue={contact.value}
inputOnChange={onTextChange}
removeButtonName={prefix + "remove"}
removeButtonOnChange={onRemove}
/>
);
});
@ -72,6 +79,7 @@ class ContactsField extends React.Component {
onItemAdd,
onItemTypeChange,
onItemTextChange,
onItemRemove,
isDisabled
} = this.props;
@ -80,6 +88,7 @@ class ContactsField extends React.Component {
pattern,
onItemTypeChange,
onItemTextChange,
onItemRemove,
isDisabled
);

View File

@ -21,6 +21,7 @@ const MainContainer = styled.div`
.departments-field {
position: relative;
margin: 0 0 40px 0;
.department-add-btn {
margin: 0 8px 8px 0;

View File

@ -1,12 +1,13 @@
import React from "react";
import styled from "styled-components";
import { Headline } from 'asc-web-common';
import { Heading } from "asc-web-components";
const Container = styled.div`
margin: 0 0 40px 0;
max-width: 1024px;
`;
const StyledHeader = styled(Headline)`
const StyledHeader = styled(Heading)`
margin: 0 0 24px 0;
line-height: unset;
`;
@ -16,7 +17,7 @@ const InfoFieldContainer = React.memo(props => {
return (
<Container>
<StyledHeader type='content'>{headerText}</StyledHeader>
<StyledHeader level={2} size='small'>{headerText}</StyledHeader>
{children}
</Container>
);

View File

@ -4,7 +4,7 @@ import { connect } from 'react-redux'
import { Avatar, Button, Textarea, toastr, AvatarEditor, Text } from 'asc-web-components'
import { withTranslation, Trans } from 'react-i18next';
import { toEmployeeWrapper, getUserRole, getUserContactsPattern, getUserContacts, mapGroupsToGroupSelectorOptions, mapGroupSelectorOptionsToGroups, filterGroupSelectorOptions } from "../../../../../store/people/selectors";
import { createProfile, getUserPhoto } from '../../../../../store/profile/actions';
import { createProfile } from '../../../../../store/profile/actions';
import { MainContainer, AvatarContainer, MainFieldsContainer } from './FormFields/Form'
import TextField from './FormFields/TextField'
import PasswordField from './FormFields/PasswordField'
@ -38,6 +38,7 @@ class CreateUserForm extends React.Component {
this.onContactsItemAdd = this.onContactsItemAdd.bind(this);
this.onContactsItemTypeChange = this.onContactsItemTypeChange.bind(this);
this.onContactsItemTextChange = this.onContactsItemTextChange.bind(this);
this.onContactsItemRemove = this.onContactsItemRemove.bind(this);
this.onShowGroupSelector = this.onShowGroupSelector.bind(this);
this.onCloseGroupSelector = this.onCloseGroupSelector.bind(this);
@ -148,21 +149,6 @@ class CreateUserForm extends React.Component {
});
var allOptions = mapGroupsToGroupSelectorOptions(props.groups);
var selected = mapGroupsToGroupSelectorOptions(profile.groups);
getUserPhoto(profile.id).then(userPhotoData => {
if(userPhotoData.original){
let avatarDefaultSizes = /_(\d*)-(\d*)./g.exec(userPhotoData.original);
if (avatarDefaultSizes !== null && avatarDefaultSizes.length > 2) {
this.setState({
avatar: {
tmpFile: this.state.avatar.tmpFile,
defaultWidth: avatarDefaultSizes[1],
defaultHeight: avatarDefaultSizes[2],
image: userPhotoData.original ? userPhotoData.original.indexOf('default_user_photo') !== -1 ? null : userPhotoData.original : null
}
});
}
}
});
return {
visibleAvatarEditor: false,
croppedAvatarImage: "",
@ -286,6 +272,16 @@ class CreateUserForm extends React.Component {
this.setState(stateCopy);
}
onContactsItemRemove(event) {
const id = event.target.closest(".remove_icon").dataset.for.split("_")[0];
var stateCopy = Object.assign({}, this.state);
const filteredArray = stateCopy.profile.contacts.filter((element) => {
return element.id !== id;
});
stateCopy.profile.contacts = filteredArray;
this.setState(stateCopy);
}
onShowGroupSelector() {
var stateCopy = Object.assign({}, this.state);
stateCopy.selector.visible = true;
@ -485,7 +481,7 @@ class CreateUserForm extends React.Component {
</MainFieldsContainer>
</MainContainer>
<InfoFieldContainer headerText={t("Comments")}>
<Textarea name="notes" value={profile.notes} isDisabled={isLoading} onChange={this.onInputChange} tabIndex={9}/>
<Textarea placeholder={t("AddСomment")} name="notes" value={profile.notes} isDisabled={isLoading} onChange={this.onInputChange} tabIndex={9}/>
</InfoFieldContainer>
<InfoFieldContainer headerText={t("ContactInformation")}>
<ContactsField
@ -496,6 +492,7 @@ class CreateUserForm extends React.Component {
onItemAdd={this.onContactsItemAdd}
onItemTypeChange={this.onContactsItemTypeChange}
onItemTextChange={this.onContactsItemTextChange}
onItemRemove={this.onContactsItemRemove}
/>
</InfoFieldContainer>
<InfoFieldContainer headerText={t("SocialProfiles")}>
@ -507,6 +504,7 @@ class CreateUserForm extends React.Component {
onItemAdd={this.onContactsItemAdd}
onItemTypeChange={this.onContactsItemTypeChange}
onItemTextChange={this.onContactsItemTextChange}
onItemRemove={this.onContactsItemRemove}
/>
</InfoFieldContainer>
<div>

View File

@ -56,6 +56,7 @@ class UpdateUserForm extends React.Component {
this.onContactsItemAdd = this.onContactsItemAdd.bind(this);
this.onContactsItemTypeChange = this.onContactsItemTypeChange.bind(this);
this.onContactsItemTextChange = this.onContactsItemTextChange.bind(this);
this.onContactsItemRemove = this.onContactsItemRemove.bind(this);
this.openAvatarEditor = this.openAvatarEditor.bind(this);
this.onSaveAvatar = this.onSaveAvatar.bind(this);
@ -338,6 +339,16 @@ class UpdateUserForm extends React.Component {
this.setState(stateCopy);
}
onContactsItemRemove(event) {
const id = event.target.closest(".remove_icon").dataset.for.split("_")[0];
var stateCopy = Object.assign({}, this.state);
const filteredArray = stateCopy.profile.contacts.filter((element) => {
return element.id !== id;
});
stateCopy.profile.contacts = filteredArray;
this.setState(stateCopy);
}
openAvatarEditor(){
let avatarDefault = this.state.avatar.image;
let avatarDefaultSizes = /_orig_(\d*)-(\d*)./g.exec(this.state.avatar.image);
@ -697,7 +708,7 @@ class UpdateUserForm extends React.Component {
</MainFieldsContainer>
</MainContainer>
<InfoFieldContainer headerText={t("Comments")}>
<Textarea name="notes" value={profile.notes} isDisabled={isLoading} onChange={this.onInputChange} tabIndex={10}/>
<Textarea placeholder={t("AddСomment")} name="notes" value={profile.notes} isDisabled={isLoading} onChange={this.onInputChange} tabIndex={10}/>
</InfoFieldContainer>
<InfoFieldContainer headerText={t("ContactInformation")}>
<ContactsField
@ -708,6 +719,7 @@ class UpdateUserForm extends React.Component {
onItemAdd={this.onContactsItemAdd}
onItemTypeChange={this.onContactsItemTypeChange}
onItemTextChange={this.onContactsItemTextChange}
onItemRemove={this.onContactsItemRemove}
/>
</InfoFieldContainer>
<InfoFieldContainer headerText={t("SocialProfiles")}>
@ -719,6 +731,7 @@ class UpdateUserForm extends React.Component {
onItemAdd={this.onContactsItemAdd}
onItemTypeChange={this.onContactsItemTypeChange}
onItemTextChange={this.onContactsItemTextChange}
onItemRemove={this.onContactsItemRemove}
/>
</InfoFieldContainer>
<div>

View File

@ -13,9 +13,9 @@
"CopyEmailAndPassword": "Copy e-mail & password",
"UserType": "Type",
"AddButton": "Add",
"ContactInformation": "Contact Information",
"ContactInformation": "Contact information",
"AddContact": "Add contact",
"SocialProfiles": "Social Profiles",
"SocialProfiles": "Social profiles",
"Search": "Search",
"SelectAll": "Select all",
"EmailPopupHelper": "The main e-mail is needed to restore access to the portal in case of loss of the password and send notifications. <1> You can create a new mail on the domain as the primary. In this case, you must set a one-time password so that the user can log in to the portal for the first time.</1> The main e-mail can be used as a login when logging in to the portal.",
@ -32,6 +32,7 @@
"ActivationLink": "Activation link",
"AddPhoto": "Add photo",
"AddСomment": "Add comment",
"TemporaryPassword": "Temporary password",
"SexMale": "Male",
"SexFemale": "Female",

View File

@ -31,7 +31,8 @@
"Message": "Чат",
"ActivationLink": "Activation link",
"AddPhoto": "Add photo",
"AddPhoto": "Добавить фотографию",
"AddСomment": "Добавить комментарий",
"TemporaryPassword": "Temporary password",
"SexMale": "Мужской",
"SexFemale": "Женский",

View File

@ -1,6 +1,6 @@
{
"name": "asc-web-common",
"version": "1.0.22",
"version": "1.0.23",
"description": "Ascensio System SIA common components and solutions library",
"license": "AGPL-3.0",
"files": [

View File

@ -5,7 +5,7 @@ import { withRouter } from "react-router";
import { withTranslation } from "react-i18next";
import i18n from "./i18n";
import { logout } from "../../store/auth/actions";
import PureStudioLayout from "./pureStudioLayout";
import PureStudioLayout from "./PureStudioLayout";
const getSeparator = id => {
return {

View File

@ -1,6 +1,6 @@
{
"name": "asc-web-components",
"version": "1.0.261",
"version": "1.0.263",
"description": "Ascensio System SIA component library",
"license": "AGPL-3.0",
"main": "dist/asc-web-components.js",

View File

@ -109,7 +109,7 @@ const EditContainer = styled.div`
text-align: center;
line-height: 19px;
border-radius: 50%;
background: linear-gradient(180deg, rgba(6, 22, 38, 0) 24.48%, rgba(6, 22, 38, 0.75) 100%);
background: ${props => props.gradient ? "linear-gradient(180deg, rgba(6, 22, 38, 0) 24.48%, rgba(6, 22, 38, 0.75) 100%)" : "transparent"};
`;
const EmptyIcon = styled(Icons.CameraIcon)`
@ -177,13 +177,15 @@ const Avatar = memo(props => {
{avatarContent}
</AvatarWrapper>
{editing && (size === 'max') &&
<EditContainer>
<EditContainer gradient={!!source}>
<EditLink>
<Link
type='action'
title={editLabel}
isTextOverflow={true}
isHovered={true}
fontSize='14px'
fontWeight={600}
color={whiteColor}
onClick={editAction}
>

View File

@ -21,6 +21,7 @@ const StyledIconBlock = styled.div`
props.isDisabled || !props.isClickable ? "default" : "pointer"};
height: 100%;
padding-right: 7px;
-webkit-tap-highlight-color: rgba(0,0,0,0);
`;
const StyledChildrenBlock = styled.div`

View File

@ -14,12 +14,22 @@ const StyledPaging = styled.div`
margin-right: 8px;
max-width: 110px;
}
.buttonCustomStyle {
padding: 6px 8px 10px;
}
`;
const StyledOnPage = styled.div`
margin-left: auto;
margin-right: 0px;
.hideDisabled {
div[disabled] {
display: none;
}
}
@media (max-width: 450px) {
display: none;
}
@ -27,6 +37,13 @@ const StyledOnPage = styled.div`
const StyledPage = styled.div`
margin-right: 8px;
.manualWidth {
> div:last-of-type {
width: 120%;
}
}
}
`;
const Paging = props => {
@ -52,6 +69,7 @@ const Paging = props => {
style={style}
>
<Button
className="buttonCustomStyle"
size='medium'
scale={true}
label={previousLabel}
@ -60,6 +78,7 @@ const Paging = props => {
{pageItems &&
<StyledPage>
<ComboBox
className="manualWidth"
directionY={openDirection}
options={pageItems}
onSelect={onSelectPageAction}
@ -69,6 +88,7 @@ const Paging = props => {
</StyledPage>
}
<Button
className="buttonCustomStyle"
size='medium'
scale={true}
label={nextLabel}
@ -77,6 +97,7 @@ const Paging = props => {
{countItems &&
<StyledOnPage>
<ComboBox
className="hideDisabled"
directionY={openDirection}
directionX='right'
options={countItems}

View File

@ -8,8 +8,6 @@ import InputBlock from '../input-block'
import { Icons } from '../icons'
import Link from '../link'
import Text from '../text'
//import DropDown from '../drop-down'
import Tooltip from "../tooltip";
// eslint-disable-next-line no-unused-vars
@ -53,6 +51,7 @@ const PasswordProgress = styled.div`
const NewPasswordButton = styled.div`
margin-left: 16px;
-webkit-tap-highlight-color: rgba(0,0,0,0);
svg {
overflow: hidden;
@ -123,20 +122,12 @@ class PasswordInput extends React.Component {
}
}
/*onFocus = () => {
this.setState({
displayTooltip: true
});
}*/
onBlur = () => {
/*this.setState({
displayTooltip: false
});*/
this.refTooltip.current.hideTooltip();
}
changeInputType = () => {
this.refTooltip.current.hideTooltip();
const newType = this.state.type === 'text' ? 'password' : 'text';
this.setState({
@ -340,7 +331,6 @@ class PasswordInput extends React.Component {
validCapital,
validSpecial,
disableCopyAction
//displayTooltip
} = this.state;
const iconsColor = isDisabled ? '#D0D5DA' : '#A3A9AE';
@ -394,7 +384,6 @@ class PasswordInput extends React.Component {
type={type}
iconColor={`${iconsColor} !important`}
isIconFill={true}
//onFocus={this.onFocus}
onBlur={this.onBlur}
hasWarning={hasWarning}
placeholder={placeholder}
@ -501,10 +490,3 @@ PasswordInput.defaultProps = {
}
export default PasswordInput;
/*
{displayTooltip &&
<DropDown directionY='top' manualY='150%' open={true}>
{tooltipContent}
</DropDown>
}
*/

View File

@ -30,6 +30,7 @@ const StyledSpan = styled.span`
const StyledText = styled(Heading)`
height: 26px;
line-height: 26px;
box-sizing: border-box;
font-style: normal;
&:hover{
border-bottom: 1px dashed;
@ -67,7 +68,7 @@ class ToggleContent extends React.Component {
this.props.onChange && this.props.onChange(!this.state.isOpen);
}}>
<Arrow color="#333333" isfill={true} size='medium' isOpen={this.state.isOpen} />
<StyledText level={2} size='medium' isInline={true}>{this.props.label}</StyledText>
<StyledText level={2} size='small' isInline={true}>{this.props.label}</StyledText>
</StyledSpan>
<StyledContent isOpen={this.state.isOpen}>{this.props.children}</StyledContent>
</div>