Merge branch 'master' of github.com:ONLYOFFICE/CommunityServer-AspNetCore
This commit is contained in:
commit
b842f2d86f
@ -40,8 +40,7 @@ namespace ASC.Core.Users
|
||||
public UserInfo()
|
||||
{
|
||||
Status = EmployeeStatus.Active;
|
||||
ActivationStatus = EmployeeActivationStatus.NotActivated;
|
||||
Contacts = new List<string>();
|
||||
ActivationStatus = EmployeeActivationStatus.NotActivated;
|
||||
LastModified = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
@ -166,7 +165,7 @@ namespace ASC.Core.Users
|
||||
|
||||
internal string ContactsToString()
|
||||
{
|
||||
if (Contacts.Count == 0) return null;
|
||||
if (Contacts == null || Contacts.Count == 0) return null;
|
||||
var sBuilder = new StringBuilder();
|
||||
foreach (var contact in Contacts)
|
||||
{
|
||||
@ -177,12 +176,19 @@ namespace ASC.Core.Users
|
||||
|
||||
internal UserInfo ContactsFromString(string contacts)
|
||||
{
|
||||
if (string.IsNullOrEmpty(contacts)) return this;
|
||||
Contacts.Clear();
|
||||
foreach (var contact in contacts.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
Contacts.Add(contact);
|
||||
}
|
||||
if (string.IsNullOrEmpty(contacts)) return this;
|
||||
|
||||
if (Contacts == null)
|
||||
{
|
||||
Contacts = new List<string>();
|
||||
}
|
||||
else
|
||||
{
|
||||
Contacts.Clear();
|
||||
}
|
||||
|
||||
Contacts.AddRange(contacts.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries));
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -81,6 +81,8 @@ namespace ASC.Core.Users
|
||||
public static void ConvertExternalContactsToOrdinary(this UserInfo ui)
|
||||
{
|
||||
var ldapUserContacts = ui.Contacts;
|
||||
|
||||
if (ui.Contacts == null) return;
|
||||
|
||||
var newContacts = new List<string>();
|
||||
|
||||
|
@ -2,7 +2,7 @@ import React, { Suspense } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { BrowserRouter, Switch } from "react-router-dom";
|
||||
import { Loader } from "asc-web-components";
|
||||
import PeopleLayout from "./components/Layout";
|
||||
import PeopleLayout from "./components/Layout/index";
|
||||
import Home from "./components/pages/Home";
|
||||
import PrivateRoute from "./helpers/privateRoute";
|
||||
import Profile from './components/pages/Profile';
|
||||
|
58
products/ASC.People/Client/src/components/Layout/i18n.js
Normal file
58
products/ASC.People/Client/src/components/Layout/i18n.js
Normal file
@ -0,0 +1,58 @@
|
||||
import i18n from "i18next";
|
||||
import Backend from "i18next-xhr-backend";
|
||||
import config from "../../../package.json";
|
||||
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
newInstance
|
||||
.use(Backend)
|
||||
.init({
|
||||
lng: 'en',
|
||||
fallbackLng: "en",
|
||||
debug: true,
|
||||
|
||||
interpolation: {
|
||||
escapeValue: false, // not needed for react as it escapes by default
|
||||
format: function (value, format) {
|
||||
if (format === 'lowercase') return value.toLowerCase();
|
||||
return value;
|
||||
}
|
||||
},
|
||||
|
||||
react: {
|
||||
useSuspense: false
|
||||
},
|
||||
backend: {
|
||||
loadPath: `${config.homepage}/locales/Layout/{{lng}}/{{ns}}.json`
|
||||
}
|
||||
});
|
||||
} else if (process.env.NODE_ENV === "development") {
|
||||
|
||||
const resources = {
|
||||
en: {
|
||||
translation: require("./locales/en/translation.json")
|
||||
}
|
||||
};
|
||||
|
||||
newInstance.init({
|
||||
resources: resources,
|
||||
lng: 'en',
|
||||
fallbackLng: "en",
|
||||
debug: true,
|
||||
|
||||
interpolation: {
|
||||
escapeValue: false, // not needed for react as it escapes by default
|
||||
format: function (value, format) {
|
||||
if (format === 'lowercase') return value.toLowerCase();
|
||||
return value;
|
||||
}
|
||||
},
|
||||
|
||||
react: {
|
||||
useSuspense: false
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default newInstance;
|
@ -3,12 +3,13 @@ import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from "react-router";
|
||||
import { Layout, Toast } from 'asc-web-components';
|
||||
import { logout } from '../store/auth/actions';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { logout } from '../../store/auth/actions';
|
||||
import { withTranslation, I18nextProvider } from 'react-i18next';
|
||||
import i18n from "./i18n";
|
||||
|
||||
class PeopleLayout extends React.Component {
|
||||
class PurePeopleLayout extends React.Component {
|
||||
shouldComponentUpdate(nextProps) {
|
||||
if(this.props.hasChanges !== nextProps.hasChanges) {
|
||||
if (this.props.hasChanges !== nextProps.hasChanges) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -36,13 +37,13 @@ class PeopleLayout extends React.Component {
|
||||
|
||||
const currentUserActions = [
|
||||
{
|
||||
key: 'ProfileBtn', label: t('Resource:Profile'), onClick: this.onProfileClick
|
||||
key: 'ProfileBtn', label: t('Profile'), onClick: this.onProfileClick
|
||||
},
|
||||
{
|
||||
key: 'AboutBtn', label: t('Resource:AboutCompanyTitle'), onClick: this.onAboutClick
|
||||
key: 'AboutBtn', label: t('AboutCompanyTitle'), onClick: this.onAboutClick
|
||||
},
|
||||
{
|
||||
key: 'LogoutBtn', label: t('Resource:LogoutButton'), onClick: this.onLogoutClick
|
||||
key: 'LogoutBtn', label: t('LogoutButton'), onClick: this.onLogoutClick
|
||||
},
|
||||
];
|
||||
|
||||
@ -64,9 +65,6 @@ class PeopleLayout extends React.Component {
|
||||
}
|
||||
};
|
||||
|
||||
PeopleLayout.propTypes = {
|
||||
logout: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const getAvailableModules = (modules) => {
|
||||
const separator = { seporator: true, id: 'nav-seporator-1' };
|
||||
@ -95,4 +93,12 @@ function mapStateToProps(state) {
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, { logout })(withRouter(withTranslation()(PeopleLayout)));
|
||||
const PeopleLayoutContainer = withTranslation()(PurePeopleLayout);
|
||||
|
||||
const PeopleLayout = (props) => <I18nextProvider i18n={i18n}><PeopleLayoutContainer {...props} /></I18nextProvider>;
|
||||
|
||||
PeopleLayout.propTypes = {
|
||||
logout: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, { logout })(withRouter((PeopleLayout)));
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"Profile": "Profile",
|
||||
"AboutCompanyTitle": "About this program",
|
||||
"LogoutButton": "Sign Out"
|
||||
}
|
@ -59,7 +59,7 @@ const getGroup = filterValues => {
|
||||
return groupId || null;
|
||||
};
|
||||
|
||||
const SectionFilterContent = React.memo(({
|
||||
const SectionFilterContent = ({
|
||||
fetchPeople,
|
||||
filter,
|
||||
onLoading,
|
||||
@ -195,12 +195,12 @@ const SectionFilterContent = React.memo(({
|
||||
return (
|
||||
<FilterInput
|
||||
getFilterData={getData}
|
||||
getSortData={()=> getSortData(t)}
|
||||
getSortData={getSortData.bind(this, t)}
|
||||
selectedFilterData={selectedFilterData}
|
||||
onFilter={onFilter}
|
||||
/>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
|
@ -29,7 +29,7 @@ const wrapperStyle = {
|
||||
alignItems: "center"
|
||||
};
|
||||
|
||||
const SectionHeaderContent = React.memo(({
|
||||
const SectionHeaderContent = ({
|
||||
isHeaderVisible,
|
||||
isHeaderIndeterminate,
|
||||
isHeaderChecked,
|
||||
@ -151,14 +151,14 @@ const SectionHeaderContent = React.memo(({
|
||||
iconName='VerticalDotsIcon'
|
||||
size={16}
|
||||
color='#A3A9AE'
|
||||
getData={() => contextOptions(t)}
|
||||
getData={contextOptions.bind(this, t)}
|
||||
isDisabled={false}/>
|
||||
}
|
||||
</div>
|
||||
: <Text.ContentHeader>{t("People")}</Text.ContentHeader>
|
||||
)
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return {
|
||||
|
@ -20,7 +20,7 @@ import {
|
||||
} from "./Section";
|
||||
import { setSelected } from "../../../store/people/actions";
|
||||
|
||||
class Home extends React.Component {
|
||||
class PureHome extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
@ -101,7 +101,7 @@ class Home extends React.Component {
|
||||
} = this.state;
|
||||
const t = this.props.t;
|
||||
return (
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<>
|
||||
<RequestLoader
|
||||
visible={this.state.isLoading}
|
||||
zIndex={256}
|
||||
@ -138,17 +138,11 @@ class Home extends React.Component {
|
||||
<SectionPagingContent onLoading={this.onLoading} />
|
||||
}
|
||||
/>
|
||||
</I18nextProvider>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Home.propTypes = {
|
||||
users: PropTypes.array.isRequired,
|
||||
history: PropTypes.object.isRequired,
|
||||
isLoaded: PropTypes.bool
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
users: state.people.users,
|
||||
@ -158,7 +152,17 @@ function mapStateToProps(state) {
|
||||
};
|
||||
}
|
||||
|
||||
const HomeContainer = withTranslation()(PureHome);
|
||||
|
||||
const Home = (props) => <I18nextProvider i18n={i18n}><HomeContainer {...props}/></I18nextProvider>;
|
||||
|
||||
Home.propTypes = {
|
||||
users: PropTypes.array.isRequired,
|
||||
history: PropTypes.object.isRequired,
|
||||
isLoaded: PropTypes.bool
|
||||
};
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
{ setSelected }
|
||||
)(withRouter(withTranslation()(Home)));
|
||||
)(withRouter(Home));
|
||||
|
@ -1,5 +1,7 @@
|
||||
{
|
||||
"Article": {},
|
||||
"Article": {
|
||||
|
||||
},
|
||||
"pages": {
|
||||
"Profile": {
|
||||
"Resource": [
|
||||
|
@ -556,7 +556,6 @@ namespace ASC.Employee.Core.Controllers
|
||||
if (CoreContext.UserManager.IsSystemUser(user.ID))
|
||||
throw new SecurityException();
|
||||
|
||||
user.Contacts.Clear();
|
||||
UpdateContacts(memberModel.Contacts, user);
|
||||
CoreContext.UserManager.SaveUserInfo(Tenant, user);
|
||||
return new EmployeeWraperFull(user, ApiContext);
|
||||
@ -1165,9 +1164,18 @@ namespace ASC.Employee.Core.Controllers
|
||||
private void UpdateContacts(IEnumerable<Contact> contacts, UserInfo user)
|
||||
{
|
||||
SecurityContext.DemandPermissions(Tenant, new UserSecurityProvider(user.ID), Constants.Action_EditUser);
|
||||
user.Contacts.Clear();
|
||||
|
||||
if (contacts == null) return;
|
||||
|
||||
if (user.Contacts == null)
|
||||
{
|
||||
user.Contacts = new List<string>();
|
||||
}
|
||||
else
|
||||
{
|
||||
user.Contacts.Clear();
|
||||
}
|
||||
|
||||
foreach (var contact in contacts)
|
||||
{
|
||||
user.Contacts.Add(contact.Type);
|
||||
@ -1180,6 +1188,11 @@ namespace ASC.Employee.Core.Controllers
|
||||
SecurityContext.DemandPermissions(Tenant, new UserSecurityProvider(user.ID), Constants.Action_EditUser);
|
||||
if (contacts == null) return;
|
||||
|
||||
if (user.Contacts == null)
|
||||
{
|
||||
user.Contacts = new List<string>();
|
||||
}
|
||||
|
||||
foreach (var contact in contacts)
|
||||
{
|
||||
var index = user.Contacts.IndexOf(contact.Type);
|
||||
|
@ -217,7 +217,10 @@ namespace ASC.Web.Api.Models
|
||||
|
||||
private void FillConacts(UserInfo userInfo)
|
||||
{
|
||||
if (userInfo.Contacts == null) return;
|
||||
|
||||
var contacts = new List<Contact>();
|
||||
|
||||
for (var i = 0; i < userInfo.Contacts.Count; i += 2)
|
||||
{
|
||||
if (i + 1 < userInfo.Contacts.Count)
|
||||
|
@ -384,7 +384,6 @@ namespace ASC.Api.Settings
|
||||
throw new BillingException(Resource.ErrorNotAllowedOption, "WhiteLabel");
|
||||
}
|
||||
|
||||
var tenantId = TenantProvider.CurrentTenantID;
|
||||
var _tenantWhiteLabelSettings = TenantWhiteLabelSettings.Load();
|
||||
|
||||
if (model.Logo != null)
|
||||
@ -396,7 +395,7 @@ namespace ASC.Api.Settings
|
||||
}
|
||||
|
||||
_tenantWhiteLabelSettings.LogoText = model.LogoText;
|
||||
_tenantWhiteLabelSettings.Save(tenantId);
|
||||
_tenantWhiteLabelSettings.Save(Tenant.TenantId);
|
||||
|
||||
}
|
||||
|
||||
@ -407,7 +406,6 @@ namespace ASC.Api.Settings
|
||||
{
|
||||
if (model.Attachments != null && model.Attachments.Any())
|
||||
{
|
||||
var tenantId = TenantProvider.CurrentTenantID;
|
||||
var _tenantWhiteLabelSettings = TenantWhiteLabelSettings.Load();
|
||||
|
||||
foreach (var f in model.Attachments)
|
||||
@ -419,7 +417,7 @@ namespace ASC.Api.Settings
|
||||
using var inputStream = f.OpenReadStream();
|
||||
_tenantWhiteLabelSettings.SetLogoFromStream(logoType, fileExt, inputStream);
|
||||
}
|
||||
_tenantWhiteLabelSettings.Save(tenantId);
|
||||
_tenantWhiteLabelSettings.Save(Tenant.TenantId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -975,8 +973,8 @@ namespace ASC.Api.Settings
|
||||
});
|
||||
}
|
||||
|
||||
var hits = StatisticManager.GetHitsByPeriod(TenantProvider.CurrentTenantID, from, to);
|
||||
var hosts = StatisticManager.GetHostsByPeriod(TenantProvider.CurrentTenantID, from, to);
|
||||
var hits = StatisticManager.GetHitsByPeriod(Tenant.TenantId, from, to);
|
||||
var hosts = StatisticManager.GetHostsByPeriod(Tenant.TenantId, from, to);
|
||||
|
||||
if (hits.Count == 0 || hosts.Count == 0) return points;
|
||||
|
||||
|
@ -146,7 +146,7 @@ namespace ASC.Api.Settings
|
||||
return ToSmtpOperationStatus();
|
||||
}
|
||||
|
||||
private static SmtpOperationStatus ToSmtpOperationStatus()
|
||||
private SmtpOperationStatus ToSmtpOperationStatus()
|
||||
{
|
||||
var operations = SMTPTasks.GetTasks().ToList();
|
||||
|
||||
@ -162,7 +162,7 @@ namespace ASC.Api.Settings
|
||||
|
||||
var operation =
|
||||
operations
|
||||
.FirstOrDefault(t => t.GetProperty<int>(SmtpOperation.OWNER) == TenantProvider.CurrentTenantID);
|
||||
.FirstOrDefault(t => t.GetProperty<int>(SmtpOperation.OWNER) == Tenant.TenantId);
|
||||
|
||||
if (operation == null)
|
||||
{
|
||||
|
@ -31,7 +31,6 @@ using System.Web;
|
||||
using ASC.Core;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Core.Users;
|
||||
using ASC.Web.Studio.Utility;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using SecurityContext = ASC.Core.SecurityContext;
|
||||
|
||||
@ -175,9 +174,9 @@ namespace ASC.Web.Core
|
||||
httpContext.SetCookies(CookiesType.AuthKey, cookie);
|
||||
}
|
||||
|
||||
public static int GetLifeTime()
|
||||
public static int GetLifeTime(int tenantId)
|
||||
{
|
||||
return TenantCookieSettings.GetForTenant(TenantProvider.CurrentTenantID).LifeTime;
|
||||
return TenantCookieSettings.GetForTenant(tenantId).LifeTime;
|
||||
}
|
||||
|
||||
public static void ResetUserCookie(this HttpContext httpContext, int tenantId, Guid? userId = null)
|
||||
|
@ -115,11 +115,10 @@ namespace ASC.Web.Core.Users
|
||||
CacheNotify.Subscribe((data) =>
|
||||
{
|
||||
var userId = new Guid(data.UserID.ToByteArray());
|
||||
var size = FromCahe(data.Size);
|
||||
|
||||
try
|
||||
{
|
||||
Photofiles.TryGetValue(CacheSize.Big, out var dict);
|
||||
Photofiles.TryGetValue(data.Size, out var dict);
|
||||
dict?.TryRemove(userId, out _);
|
||||
//var storage = GetDataStore();
|
||||
//storage.DeleteFiles("", data.UserID + "*.*", false);
|
||||
|
Loading…
Reference in New Issue
Block a user