Merge branch 'develop' into feature/webhooks-page
This commit is contained in:
commit
b2546b1c96
@ -12,4 +12,4 @@ Write-Host "Run Document server" -ForegroundColor Green
|
|||||||
$DOCUMENT_SERVER_IMAGE_NAME = "onlyoffice/documentserver-de:latest"
|
$DOCUMENT_SERVER_IMAGE_NAME = "onlyoffice/documentserver-de:latest"
|
||||||
|
|
||||||
|
|
||||||
docker run -i -t -d -p 8085:80 -e JWT_ENABLED=false -e JWT_IN_BODY=false --restart=always -v $RootDir/Data:/var/www/onlyoffice/Data $DOCUMENT_SERVER_IMAGE_NAME
|
docker run -i -t -d -p 8085:80 -e JWT_ENABLED=true -e JWT_SECRET=secret -e JWT_HEADER=AuthorizationJwt --restart=always -v $RootDir/Data:/var/www/onlyoffice/Data $DOCUMENT_SERVER_IMAGE_NAME
|
@ -186,7 +186,7 @@ WORKDIR ${BUILD_PATH}/services/ASC.Data.Backup.BackgroundTasks/
|
|||||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Data.Backup.BackgroundTasks/service/ .
|
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Data.Backup.BackgroundTasks/service/ .
|
||||||
|
|
||||||
CMD ["ASC.Data.Backup.BackgroundTasks.dll", "ASC.Data.Backup.BackgroundTasks"]
|
CMD ["ASC.Data.Backup.BackgroundTasks.dll", "ASC.Data.Backup.BackgroundTasks", "core:eventBus:subscriptionClientName=asc_event_bus_backup_queue"]
|
||||||
|
|
||||||
# ASC.ApiSystem ##
|
# ASC.ApiSystem ##
|
||||||
FROM dotnetrun AS api_system
|
FROM dotnetrun AS api_system
|
||||||
@ -231,7 +231,7 @@ WORKDIR ${BUILD_PATH}/products/ASC.Files/service/
|
|||||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Files.Service/service/ .
|
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Files.Service/service/ .
|
||||||
|
|
||||||
CMD ["ASC.Files.Service.dll", "ASC.Files.Service"]
|
CMD ["ASC.Files.Service.dll", "ASC.Files.Service", "core:eventBus:subscriptionClientName=asc_event_bus_files_service_queue"]
|
||||||
|
|
||||||
## ASC.Notify ##
|
## ASC.Notify ##
|
||||||
FROM dotnetrun AS notify
|
FROM dotnetrun AS notify
|
||||||
@ -240,7 +240,7 @@ WORKDIR ${BUILD_PATH}/services/ASC.Notify/service
|
|||||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Notify/service/ .
|
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Notify/service/ .
|
||||||
|
|
||||||
CMD ["ASC.Notify.dll", "ASC.Notify"]
|
CMD ["ASC.Notify.dll", "ASC.Notify", "core:eventBus:subscriptionClientName=asc_event_bus_notify_queue"]
|
||||||
|
|
||||||
## ASC.People ##
|
## ASC.People ##
|
||||||
FROM dotnetrun AS people_server
|
FROM dotnetrun AS people_server
|
||||||
|
@ -38,8 +38,9 @@ ELK_PORT = os.environ["ELK_PORT"] if environ.get("ELK_PORT") else "9200"
|
|||||||
ELK_THREADS = os.environ["ELK_THREADS"] if environ.get("ELK_THREADS") else "1"
|
ELK_THREADS = os.environ["ELK_THREADS"] if environ.get("ELK_THREADS") else "1"
|
||||||
|
|
||||||
KAFKA_HOST = os.environ["KAFKA_HOST"] if environ.get("KAFKA_HOST") else "kafka:9092"
|
KAFKA_HOST = os.environ["KAFKA_HOST"] if environ.get("KAFKA_HOST") else "kafka:9092"
|
||||||
RUN_FILE = sys.argv[1] if sys.argv[1] else "none"
|
RUN_FILE = sys.argv[1] if (len(sys.argv) > 1) else "none"
|
||||||
LOG_FILE = sys.argv[2] if sys.argv[2] else "none"
|
LOG_FILE = sys.argv[2] if (len(sys.argv) > 2) else "none"
|
||||||
|
CORE_EVENT_BUS = sys.argv[3] if (len(sys.argv) > 3) else ""
|
||||||
|
|
||||||
REDIS_HOST = os.environ["REDIS_HOST"] if environ.get("REDIS_HOST") else "onlyoffice-redis"
|
REDIS_HOST = os.environ["REDIS_HOST"] if environ.get("REDIS_HOST") else "onlyoffice-redis"
|
||||||
REDIS_PORT = os.environ["REDIS_PORT"] if environ.get("REDIS_PORT") else "6379"
|
REDIS_PORT = os.environ["REDIS_PORT"] if environ.get("REDIS_PORT") else "6379"
|
||||||
@ -84,7 +85,8 @@ class RunServices:
|
|||||||
" --log:dir=" + LOG_DIR +\
|
" --log:dir=" + LOG_DIR +\
|
||||||
" --log:name=" + LOG_FILE +\
|
" --log:name=" + LOG_FILE +\
|
||||||
" core:products:folder=/var/www/products/" +\
|
" core:products:folder=/var/www/products/" +\
|
||||||
" core:products:subfolder=server")
|
" core:products:subfolder=server" + " " +\
|
||||||
|
CORE_EVENT_BUS)
|
||||||
else:
|
else:
|
||||||
os.system("dotnet " + RUN_FILE + " --urls=" + URLS + self.SERVICE_PORT +\
|
os.system("dotnet " + RUN_FILE + " --urls=" + URLS + self.SERVICE_PORT +\
|
||||||
" --\'$STORAGE_ROOT\'=" + APP_STORAGE_ROOT +\
|
" --\'$STORAGE_ROOT\'=" + APP_STORAGE_ROOT +\
|
||||||
@ -93,7 +95,8 @@ class RunServices:
|
|||||||
" --log:name=" + LOG_FILE +\
|
" --log:name=" + LOG_FILE +\
|
||||||
" --ENVIRONMENT=" + ENV_EXTENSION +\
|
" --ENVIRONMENT=" + ENV_EXTENSION +\
|
||||||
" core:products:folder=/var/www/products/" +\
|
" core:products:folder=/var/www/products/" +\
|
||||||
" core:products:subfolder=server")
|
" core:products:subfolder=server" + " " +\
|
||||||
|
CORE_EVENT_BUS)
|
||||||
|
|
||||||
def openJsonFile(filePath):
|
def openJsonFile(filePath):
|
||||||
try:
|
try:
|
||||||
|
@ -57,13 +57,13 @@ public class LdapNotifyService : BackgroundService
|
|||||||
{
|
{
|
||||||
var tId = t.Id;
|
var tId = t.Id;
|
||||||
|
|
||||||
var ldapSettings = settingsManager.LoadForTenant<LdapSettings>(tId);
|
var ldapSettings = settingsManager.Load<LdapSettings>(tId);
|
||||||
if (!ldapSettings.EnableLdapAuthentication)
|
if (!ldapSettings.EnableLdapAuthentication)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cronSettings = settingsManager.LoadForTenant<LdapCronSettings>(tId);
|
var cronSettings = settingsManager.Load<LdapCronSettings>(tId);
|
||||||
if (string.IsNullOrEmpty(cronSettings.Cron))
|
if (string.IsNullOrEmpty(cronSettings.Cron))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -103,13 +103,13 @@ public class LdapNotifyService : BackgroundService
|
|||||||
{
|
{
|
||||||
using var scope = _serviceScopeFactory.CreateScope();
|
using var scope = _serviceScopeFactory.CreateScope();
|
||||||
var settingsManager = scope.ServiceProvider.GetRequiredService<SettingsManager>();
|
var settingsManager = scope.ServiceProvider.GetRequiredService<SettingsManager>();
|
||||||
var ldapSettings = settingsManager.LoadForTenant<LdapSettings>(tenant.Id);
|
var ldapSettings = settingsManager.Load<LdapSettings>(tenant.Id);
|
||||||
|
|
||||||
if (!ldapSettings.EnableLdapAuthentication)
|
if (!ldapSettings.EnableLdapAuthentication)
|
||||||
{
|
{
|
||||||
var cronSettings = settingsManager.LoadForTenant<LdapCronSettings>(tenant.Id);
|
var cronSettings = settingsManager.Load<LdapCronSettings>(tenant.Id);
|
||||||
cronSettings.Cron = "";
|
cronSettings.Cron = "";
|
||||||
settingsManager.SaveForTenant(cronSettings, tenant.Id);
|
settingsManager.Save(cronSettings, tenant.Id);
|
||||||
UnregisterAutoSync(tenant);
|
UnregisterAutoSync(tenant);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ public class LdapUserManager
|
|||||||
var quotaSettings = _settingsManager.Load<TenantUserQuotaSettings>();
|
var quotaSettings = _settingsManager.Load<TenantUserQuotaSettings>();
|
||||||
if (quotaSettings.EnableUserQuota)
|
if (quotaSettings.EnableUserQuota)
|
||||||
{
|
{
|
||||||
_settingsManager.SaveForUser(new UserQuotaSettings { UserQuota = ldapUserInfo.LdapQouta }, ldapUserInfo.Id);
|
_settingsManager.Save(new UserQuotaSettings { UserQuota = ldapUserInfo.LdapQouta }, ldapUserInfo.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,25 +64,26 @@ public abstract class BaseStartup
|
|||||||
|
|
||||||
public virtual void ConfigureServices(IServiceCollection services)
|
public virtual void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddCustomHealthCheck(_configuration);
|
services.AddCustomHealthCheck(_configuration);
|
||||||
services.AddHttpContextAccessor();
|
services.AddHttpContextAccessor();
|
||||||
services.AddMemoryCache();
|
services.AddMemoryCache();
|
||||||
services.AddHttpClient();
|
services.AddHttpClient();
|
||||||
|
|
||||||
services.AddScoped<EFLoggerFactory>();
|
services.AddScoped<EFLoggerFactory>();
|
||||||
services.AddBaseDbContextPool<AccountLinkContext>();
|
|
||||||
services.AddBaseDbContextPool<CoreDbContext>();
|
services.AddBaseDbContextPool<AccountLinkContext>()
|
||||||
services.AddBaseDbContextPool<TenantDbContext>();
|
.AddBaseDbContextPool<CoreDbContext>()
|
||||||
services.AddBaseDbContextPool<UserDbContext>();
|
.AddBaseDbContextPool<TenantDbContext>()
|
||||||
services.AddBaseDbContextPool<TelegramDbContext>();
|
.AddBaseDbContextPool<UserDbContext>()
|
||||||
services.AddBaseDbContextPool<FirebaseDbContext>();
|
.AddBaseDbContextPool<TelegramDbContext>()
|
||||||
services.AddBaseDbContextPool<CustomDbContext>();
|
.AddBaseDbContextPool<FirebaseDbContext>()
|
||||||
services.AddBaseDbContextPool<WebstudioDbContext>();
|
.AddBaseDbContextPool<CustomDbContext>()
|
||||||
services.AddBaseDbContextPool<InstanceRegistrationContext>();
|
.AddBaseDbContextPool<WebstudioDbContext>()
|
||||||
services.AddBaseDbContextPool<IntegrationEventLogContext>();
|
.AddBaseDbContextPool<InstanceRegistrationContext>()
|
||||||
services.AddBaseDbContextPool<FeedDbContext>();
|
.AddBaseDbContextPool<IntegrationEventLogContext>()
|
||||||
services.AddBaseDbContextPool<MessagesContext>();
|
.AddBaseDbContextPool<FeedDbContext>()
|
||||||
services.AddBaseDbContextPool<WebhooksDbContext>();
|
.AddBaseDbContextPool<MessagesContext>()
|
||||||
|
.AddBaseDbContextPool<WebhooksDbContext>();
|
||||||
|
|
||||||
if (AddAndUseSession)
|
if (AddAndUseSession)
|
||||||
{
|
{
|
||||||
@ -294,20 +295,35 @@ public abstract class BaseStartup
|
|||||||
|
|
||||||
app.UseLoggerMiddleware();
|
app.UseLoggerMiddleware();
|
||||||
|
|
||||||
app.UseEndpoints(async endpoints =>
|
app.UseEndpoints(async endpoints =>
|
||||||
{
|
{
|
||||||
await endpoints.MapCustom(WebhooksEnabled, app.ApplicationServices);
|
await endpoints.MapCustomAsync(WebhooksEnabled, app.ApplicationServices);
|
||||||
|
|
||||||
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
|
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
|
||||||
{
|
{
|
||||||
Predicate = _ => true,
|
Predicate = _ => true,
|
||||||
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
|
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
|
||||||
});
|
});
|
||||||
|
|
||||||
|
endpoints.MapHealthChecks("/ready", new HealthCheckOptions
|
||||||
|
{
|
||||||
|
Predicate = r => r.Name.Contains("services")
|
||||||
|
});
|
||||||
|
|
||||||
endpoints.MapHealthChecks("/liveness", new HealthCheckOptions
|
endpoints.MapHealthChecks("/liveness", new HealthCheckOptions
|
||||||
{
|
{
|
||||||
Predicate = r => r.Name.Contains("self")
|
Predicate = r => r.Name.Contains("self")
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.Map("/switch", appBuilder =>
|
||||||
|
{
|
||||||
|
appBuilder.Run(async context =>
|
||||||
|
{
|
||||||
|
CustomHealthCheck.Running = !CustomHealthCheck.Running;
|
||||||
|
await context.Response.WriteAsync($"{Environment.MachineName} running {CustomHealthCheck.Running}");
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConfigureContainer(ContainerBuilder builder)
|
public void ConfigureContainer(ContainerBuilder builder)
|
||||||
|
@ -83,7 +83,7 @@ public static class EndpointExtension
|
|||||||
"DELETE"
|
"DELETE"
|
||||||
};
|
};
|
||||||
|
|
||||||
public static async Task<IEndpointRouteBuilder> MapCustom(this IEndpointRouteBuilder endpoints, bool webhooksEnabled = false, IServiceProvider serviceProvider = null)
|
public static async Task<IEndpointRouteBuilder> MapCustomAsync(this IEndpointRouteBuilder endpoints, bool webhooksEnabled = false, IServiceProvider serviceProvider = null)
|
||||||
{
|
{
|
||||||
endpoints.MapControllers();
|
endpoints.MapControllers();
|
||||||
|
|
||||||
|
@ -23,67 +23,35 @@
|
|||||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||||
|
|
||||||
namespace ASC.Api.Core.Core;
|
namespace ASC.Api.Core.Core;
|
||||||
|
|
||||||
public static class CustomHealthCheck
|
public static class CustomHealthCheck
|
||||||
{
|
{
|
||||||
|
public static bool Running { get; set;}
|
||||||
|
|
||||||
|
static CustomHealthCheck()
|
||||||
|
{
|
||||||
|
Running = true;
|
||||||
|
}
|
||||||
|
|
||||||
public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration)
|
public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
var hcBuilder = services.AddHealthChecks();
|
var hcBuilder = services.AddHealthChecks();
|
||||||
|
|
||||||
hcBuilder.AddCheck("self", () => HealthCheckResult.Healthy());
|
|
||||||
|
|
||||||
var configurationExtension = new ConfigurationExtension(configuration);
|
|
||||||
|
|
||||||
var connectionString = configurationExtension.GetConnectionStrings("default");
|
|
||||||
|
|
||||||
if (string.Equals(connectionString.ProviderName, "MySql.Data.MySqlClient"))
|
hcBuilder.AddCheck("self", () => Running ? HealthCheckResult.Healthy()
|
||||||
{
|
: HealthCheckResult.Unhealthy())
|
||||||
hcBuilder.AddMySql(connectionString.ConnectionString,
|
.AddDatabase(configuration)
|
||||||
name: "mysqldb",
|
.AddDistibutedCache(configuration)
|
||||||
tags: new string[] { "mysqldb" },
|
.AddMessageQueue(configuration)
|
||||||
timeout: new TimeSpan(0, 0, 15));
|
.AddSearch(configuration);
|
||||||
}
|
|
||||||
|
return services;
|
||||||
if (string.Equals(connectionString.ProviderName, "Npgsql"))
|
}
|
||||||
{
|
|
||||||
hcBuilder.AddNpgSql(connectionString.ConnectionString,
|
|
||||||
name: "postgredb",
|
|
||||||
tags: new string[] { "postgredb" },
|
|
||||||
timeout: new TimeSpan(0, 0, 15));
|
|
||||||
}
|
|
||||||
|
|
||||||
var kafkaSettings = configurationExtension.GetSetting<KafkaSettings>("kafka");
|
|
||||||
if (kafkaSettings != null && !string.IsNullOrEmpty(kafkaSettings.BootstrapServers))
|
|
||||||
{
|
|
||||||
var clientConfig = new ClientConfig { BootstrapServers = kafkaSettings.BootstrapServers };
|
|
||||||
|
|
||||||
hcBuilder.AddKafka(new ProducerConfig(clientConfig),
|
|
||||||
name: "kafka",
|
|
||||||
tags: new string[] { "kafka" },
|
|
||||||
timeout: new TimeSpan(0,0,15)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var elasticSettings = configuration.GetSection("elastic");
|
|
||||||
|
|
||||||
if (elasticSettings != null && elasticSettings.GetChildren().Any())
|
|
||||||
{
|
|
||||||
var host = elasticSettings.GetSection("Host").Value ?? "localhost";
|
|
||||||
var scheme = elasticSettings.GetSection("Scheme").Value ?? "http";
|
|
||||||
var port = elasticSettings.GetSection("Port").Value ?? "9200";
|
|
||||||
var elasticSearchUri = $"{scheme}://{host}:{port}";
|
|
||||||
|
|
||||||
if (Uri.IsWellFormedUriString(elasticSearchUri, UriKind.Absolute))
|
|
||||||
{
|
|
||||||
hcBuilder.AddElasticsearch(elasticSearchUri,
|
|
||||||
name: "elasticsearch",
|
|
||||||
tags: new string[] { "elasticsearch" });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public static IHealthChecksBuilder AddDistibutedCache(
|
||||||
|
this IHealthChecksBuilder hcBuilder, IConfiguration configuration)
|
||||||
|
{
|
||||||
var redisConfiguration = configuration.GetSection("Redis").Get<RedisConfiguration>();
|
var redisConfiguration = configuration.GetSection("Redis").Get<RedisConfiguration>();
|
||||||
|
|
||||||
if (redisConfiguration != null)
|
if (redisConfiguration != null)
|
||||||
@ -97,20 +65,97 @@ public static class CustomHealthCheck
|
|||||||
|
|
||||||
hcBuilder.AddRedis(redisConfiguration.ConfigurationOptions.ToString(),
|
hcBuilder.AddRedis(redisConfiguration.ConfigurationOptions.ToString(),
|
||||||
name: "redis",
|
name: "redis",
|
||||||
tags: new string[] { "redis" },
|
tags: new string[] { "redis", "services" },
|
||||||
timeout: new TimeSpan(0, 0, 15));
|
timeout: new TimeSpan(0, 0, 15));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return hcBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static IHealthChecksBuilder AddSearch(
|
||||||
|
this IHealthChecksBuilder hcBuilder, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
var elasticSettings = configuration.GetSection("elastic");
|
||||||
|
|
||||||
|
if (elasticSettings != null && elasticSettings.GetChildren().Any())
|
||||||
|
{
|
||||||
|
var host = elasticSettings.GetSection("Host").Value ?? "localhost";
|
||||||
|
var scheme = elasticSettings.GetSection("Scheme").Value ?? "http";
|
||||||
|
var port = elasticSettings.GetSection("Port").Value ?? "9200";
|
||||||
|
var elasticSearchUri = $"{scheme}://{host}:{port}";
|
||||||
|
|
||||||
|
if (Uri.IsWellFormedUriString(elasticSearchUri, UriKind.Absolute))
|
||||||
|
{
|
||||||
|
hcBuilder.AddElasticsearch(elasticSearchUri,
|
||||||
|
name: "elasticsearch",
|
||||||
|
tags: new string[] { "elasticsearch", "services" },
|
||||||
|
timeout: new TimeSpan(0, 0, 15));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hcBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHealthChecksBuilder AddDatabase(
|
||||||
|
this IHealthChecksBuilder hcBuilder, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
var configurationExtension = new ConfigurationExtension(configuration);
|
||||||
|
|
||||||
|
var connectionString = configurationExtension.GetConnectionStrings("default");
|
||||||
|
|
||||||
|
if (string.Equals(connectionString.ProviderName, "MySql.Data.MySqlClient"))
|
||||||
|
{
|
||||||
|
hcBuilder.AddMySql(connectionString.ConnectionString,
|
||||||
|
name: "mysqldb",
|
||||||
|
tags: new string[] { "mysqldb", "services" },
|
||||||
|
timeout: new TimeSpan(0, 0, 15));
|
||||||
|
}
|
||||||
|
else if (string.Equals(connectionString.ProviderName, "Npgsql"))
|
||||||
|
{
|
||||||
|
hcBuilder.AddNpgSql(connectionString.ConnectionString,
|
||||||
|
name: "postgredb",
|
||||||
|
tags: new string[] { "postgredb", "services" },
|
||||||
|
timeout: new TimeSpan(0, 0, 15));
|
||||||
|
}
|
||||||
|
|
||||||
|
return hcBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static IHealthChecksBuilder AddMessageQueue(
|
||||||
|
this IHealthChecksBuilder hcBuilder, IConfiguration configuration)
|
||||||
|
{
|
||||||
var rabbitMQConfiguration = configuration.GetSection("RabbitMQ").Get<RabbitMQSettings>();
|
var rabbitMQConfiguration = configuration.GetSection("RabbitMQ").Get<RabbitMQSettings>();
|
||||||
|
|
||||||
if (rabbitMQConfiguration != null)
|
if (rabbitMQConfiguration != null)
|
||||||
{
|
{
|
||||||
hcBuilder.AddRabbitMQ(x => rabbitMQConfiguration.GetConnectionFactory(),
|
hcBuilder.AddRabbitMQ(x => rabbitMQConfiguration.GetConnectionFactory(),
|
||||||
name: "rabbitMQ",
|
name: "rabbitMQ",
|
||||||
tags: new string[] { "rabbitMQ" },
|
tags: new string[] { "rabbitMQ", "services" },
|
||||||
timeout: new TimeSpan(0, 0, 15));
|
timeout: new TimeSpan(0, 0, 15));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return services;
|
{
|
||||||
}
|
var configurationExtension = new ConfigurationExtension(configuration);
|
||||||
|
var kafkaSettings = configurationExtension.GetSetting<KafkaSettings>("kafka");
|
||||||
|
|
||||||
|
if (kafkaSettings != null && !string.IsNullOrEmpty(kafkaSettings.BootstrapServers))
|
||||||
|
{
|
||||||
|
var clientConfig = new ClientConfig { BootstrapServers = kafkaSettings.BootstrapServers };
|
||||||
|
|
||||||
|
hcBuilder.AddKafka(new ProducerConfig(clientConfig),
|
||||||
|
name: "kafka",
|
||||||
|
tags: new string[] { "kafka", "services" },
|
||||||
|
timeout: new TimeSpan(0, 0, 15)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hcBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -29,11 +29,11 @@ public static class QuotaExtension
|
|||||||
{
|
{
|
||||||
public static IServiceCollection RegisterFeature(this IServiceCollection services)
|
public static IServiceCollection RegisterFeature(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddScoped<ITenantQuotaFeatureChecker, CountRoomAdminChecker>();
|
services.AddScoped<ITenantQuotaFeatureChecker, CountPaidUserChecker>();
|
||||||
services.AddScoped<TenantQuotaFeatureCheckerCount<CountRoomAdminFeature>, CountRoomAdminChecker>();
|
services.AddScoped<TenantQuotaFeatureCheckerCount<CountPaidUserFeature>, CountPaidUserChecker>();
|
||||||
services.AddScoped<CountRoomAdminChecker>();
|
services.AddScoped<CountPaidUserChecker>();
|
||||||
services.AddScoped<ITenantQuotaFeatureStat<CountRoomAdminFeature, int>, CountRoomAdminStatistic>();
|
services.AddScoped<ITenantQuotaFeatureStat<CountPaidUserFeature, int>, CountPaidUserStatistic>();
|
||||||
services.AddScoped<CountRoomAdminStatistic>();
|
services.AddScoped<CountPaidUserStatistic>();
|
||||||
|
|
||||||
services.AddScoped<ITenantQuotaFeatureChecker, CountUserChecker>();
|
services.AddScoped<ITenantQuotaFeatureChecker, CountUserChecker>();
|
||||||
services.AddScoped<TenantQuotaFeatureCheckerCount<CountUserFeature>, CountUserChecker>();
|
services.AddScoped<TenantQuotaFeatureCheckerCount<CountUserFeature>, CountUserChecker>();
|
||||||
|
@ -49,7 +49,7 @@ public static class ServiceCollectionExtension
|
|||||||
{
|
{
|
||||||
services.AddSingleton(typeof(ICacheNotify<>), typeof(RabbitMQCache<>));
|
services.AddSingleton(typeof(ICacheNotify<>), typeof(RabbitMQCache<>));
|
||||||
}
|
}
|
||||||
else if (kafkaConfiguration != null)
|
else if (kafkaConfiguration != null && !string.IsNullOrEmpty(kafkaConfiguration.BootstrapServers))
|
||||||
{
|
{
|
||||||
services.AddSingleton(typeof(ICacheNotify<>), typeof(KafkaCacheNotify<>));
|
services.AddSingleton(typeof(ICacheNotify<>), typeof(KafkaCacheNotify<>));
|
||||||
}
|
}
|
||||||
|
@ -1,139 +1,140 @@
|
|||||||
// (c) Copyright Ascensio System SIA 2010-2022
|
// (c) Copyright Ascensio System SIA 2010-2022
|
||||||
//
|
//
|
||||||
// This program is a free software product.
|
// This program is a free software product.
|
||||||
// You can redistribute it and/or modify it under the terms
|
// You can redistribute it and/or modify it under the terms
|
||||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||||
// any third-party rights.
|
// any third-party rights.
|
||||||
//
|
//
|
||||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||||
//
|
//
|
||||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||||
//
|
//
|
||||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||||
//
|
//
|
||||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||||
// trademark law for use of our trademarks.
|
// trademark law for use of our trademarks.
|
||||||
//
|
//
|
||||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||||
|
|
||||||
namespace ASC.Web.Api.Models;
|
namespace ASC.Web.Api.Models;
|
||||||
|
|
||||||
public class EmployeeFullDto : EmployeeDto
|
public class EmployeeFullDto : EmployeeDto
|
||||||
{
|
{
|
||||||
public string FirstName { get; set; }
|
public string FirstName { get; set; }
|
||||||
public string LastName { get; set; }
|
public string LastName { get; set; }
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
public string Email { get; set; }
|
public string Email { get; set; }
|
||||||
public List<Contact> Contacts { get; set; }
|
public List<Contact> Contacts { get; set; }
|
||||||
public ApiDateTime Birthday { get; set; }
|
public ApiDateTime Birthday { get; set; }
|
||||||
public string Sex { get; set; }
|
public string Sex { get; set; }
|
||||||
public EmployeeStatus Status { get; set; }
|
public EmployeeStatus Status { get; set; }
|
||||||
public EmployeeActivationStatus ActivationStatus { get; set; }
|
public EmployeeActivationStatus ActivationStatus { get; set; }
|
||||||
public ApiDateTime Terminated { get; set; }
|
public ApiDateTime Terminated { get; set; }
|
||||||
public string Department { get; set; }
|
public string Department { get; set; }
|
||||||
public ApiDateTime WorkFrom { get; set; }
|
public ApiDateTime WorkFrom { get; set; }
|
||||||
public List<GroupSummaryDto> Groups { get; set; }
|
public List<GroupSummaryDto> Groups { get; set; }
|
||||||
public string Location { get; set; }
|
public string Location { get; set; }
|
||||||
public string Notes { get; set; }
|
public string Notes { get; set; }
|
||||||
public string AvatarMax { get; set; }
|
public string AvatarMax { get; set; }
|
||||||
public string AvatarMedium { get; set; }
|
public string AvatarMedium { get; set; }
|
||||||
public string Avatar { get; set; }
|
public string Avatar { get; set; }
|
||||||
public bool IsAdmin { get; set; }
|
public bool IsAdmin { get; set; }
|
||||||
public bool IsLDAP { get; set; }
|
public bool IsLDAP { get; set; }
|
||||||
public List<string> ListAdminModules { get; set; }
|
public List<string> ListAdminModules { get; set; }
|
||||||
public bool IsOwner { get; set; }
|
public bool IsOwner { get; set; }
|
||||||
public bool IsVisitor { get; set; }
|
public bool IsVisitor { get; set; }
|
||||||
public string CultureName { get; set; }
|
public bool IsCollaborator { get; set; }
|
||||||
public string MobilePhone { get; set; }
|
public string CultureName { get; set; }
|
||||||
public MobilePhoneActivationStatus MobilePhoneActivationStatus { get; set; }
|
public string MobilePhone { get; set; }
|
||||||
|
public MobilePhoneActivationStatus MobilePhoneActivationStatus { get; set; }
|
||||||
public bool IsSSO { get; set; }
|
public bool IsSSO { get; set; }
|
||||||
public DarkThemeSettingsEnum? Theme { get; set; }
|
public DarkThemeSettingsEnum? Theme { get; set; }
|
||||||
public long QuotaLimit { get; set; }
|
public long QuotaLimit { get; set; }
|
||||||
public double UsedSpace { get; set; }
|
public double UsedSpace { get; set; }
|
||||||
|
|
||||||
public static new EmployeeFullDto GetSample()
|
public static new EmployeeFullDto GetSample()
|
||||||
{
|
{
|
||||||
return new EmployeeFullDto
|
return new EmployeeFullDto
|
||||||
{
|
{
|
||||||
Avatar = "url to big avatar",
|
Avatar = "url to big avatar",
|
||||||
AvatarSmall = "url to small avatar",
|
AvatarSmall = "url to small avatar",
|
||||||
AvatarMax = "url to max avatar",
|
AvatarMax = "url to max avatar",
|
||||||
Contacts = new List<Contact> { Contact.GetSample() },
|
Contacts = new List<Contact> { Contact.GetSample() },
|
||||||
Email = "my@gmail.com",
|
Email = "my@gmail.com",
|
||||||
FirstName = "Mike",
|
FirstName = "Mike",
|
||||||
Id = Guid.Empty,
|
Id = Guid.Empty,
|
||||||
IsAdmin = false,
|
IsAdmin = false,
|
||||||
ListAdminModules = new List<string> { "projects", "crm" },
|
ListAdminModules = new List<string> { "projects", "crm" },
|
||||||
UserName = "Mike.Zanyatski",
|
UserName = "Mike.Zanyatski",
|
||||||
LastName = "Zanyatski",
|
LastName = "Zanyatski",
|
||||||
Title = "Manager",
|
Title = "Manager",
|
||||||
Groups = new List<GroupSummaryDto> { GroupSummaryDto.GetSample() },
|
Groups = new List<GroupSummaryDto> { GroupSummaryDto.GetSample() },
|
||||||
AvatarMedium = "url to medium avatar",
|
AvatarMedium = "url to medium avatar",
|
||||||
Birthday = ApiDateTime.GetSample(),
|
Birthday = ApiDateTime.GetSample(),
|
||||||
Department = "Marketing",
|
Department = "Marketing",
|
||||||
Location = "Palo Alto",
|
Location = "Palo Alto",
|
||||||
Notes = "Notes to worker",
|
Notes = "Notes to worker",
|
||||||
Sex = "male",
|
Sex = "male",
|
||||||
Status = EmployeeStatus.Active,
|
Status = EmployeeStatus.Active,
|
||||||
WorkFrom = ApiDateTime.GetSample(),
|
WorkFrom = ApiDateTime.GetSample(),
|
||||||
Terminated = ApiDateTime.GetSample(),
|
Terminated = ApiDateTime.GetSample(),
|
||||||
CultureName = "en-EN",
|
CultureName = "en-EN",
|
||||||
IsLDAP = false,
|
IsLDAP = false,
|
||||||
IsSSO = false
|
IsSSO = false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Scope]
|
[Scope]
|
||||||
public class EmployeeFullDtoHelper : EmployeeDtoHelper
|
public class EmployeeFullDtoHelper : EmployeeDtoHelper
|
||||||
{
|
{
|
||||||
private readonly ApiContext _context;
|
private readonly ApiContext _context;
|
||||||
private readonly WebItemSecurity _webItemSecurity;
|
private readonly WebItemSecurity _webItemSecurity;
|
||||||
private readonly ApiDateTimeHelper _apiDateTimeHelper;
|
private readonly ApiDateTimeHelper _apiDateTimeHelper;
|
||||||
private readonly WebItemManager _webItemManager;
|
private readonly WebItemManager _webItemManager;
|
||||||
private readonly SettingsManager _settingsManager;
|
private readonly SettingsManager _settingsManager;
|
||||||
private readonly IQuotaService _quotaService;
|
private readonly IQuotaService _quotaService;
|
||||||
|
|
||||||
public EmployeeFullDtoHelper(
|
public EmployeeFullDtoHelper(
|
||||||
ApiContext context,
|
ApiContext context,
|
||||||
UserManager userManager,
|
UserManager userManager,
|
||||||
UserPhotoManager userPhotoManager,
|
UserPhotoManager userPhotoManager,
|
||||||
WebItemSecurity webItemSecurity,
|
WebItemSecurity webItemSecurity,
|
||||||
CommonLinkUtility commonLinkUtility,
|
CommonLinkUtility commonLinkUtility,
|
||||||
DisplayUserSettingsHelper displayUserSettingsHelper,
|
DisplayUserSettingsHelper displayUserSettingsHelper,
|
||||||
ApiDateTimeHelper apiDateTimeHelper,
|
ApiDateTimeHelper apiDateTimeHelper,
|
||||||
WebItemManager webItemManager,
|
WebItemManager webItemManager,
|
||||||
SettingsManager settingsManager,
|
SettingsManager settingsManager,
|
||||||
IQuotaService quotaService)
|
IQuotaService quotaService)
|
||||||
: base(context, displayUserSettingsHelper, userPhotoManager, commonLinkUtility, userManager)
|
: base(context, displayUserSettingsHelper, userPhotoManager, commonLinkUtility, userManager)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_webItemSecurity = webItemSecurity;
|
_webItemSecurity = webItemSecurity;
|
||||||
_apiDateTimeHelper = apiDateTimeHelper;
|
_apiDateTimeHelper = apiDateTimeHelper;
|
||||||
_webItemManager = webItemManager;
|
_webItemManager = webItemManager;
|
||||||
_settingsManager = settingsManager;
|
_settingsManager = settingsManager;
|
||||||
_quotaService = quotaService;
|
_quotaService = quotaService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Expression<Func<User, UserInfo>> GetExpression(ApiContext apiContext)
|
public static Expression<Func<User, UserInfo>> GetExpression(ApiContext apiContext)
|
||||||
{
|
{
|
||||||
if (apiContext?.Fields == null)
|
if (apiContext?.Fields == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newExpr = Expression.New(typeof(UserInfo));
|
var newExpr = Expression.New(typeof(UserInfo));
|
||||||
|
|
||||||
//i => new UserInfo { ID = i.id }
|
//i => new UserInfo { ID = i.id }
|
||||||
var parameter = Expression.Parameter(typeof(User), "i");
|
var parameter = Expression.Parameter(typeof(User), "i");
|
||||||
var bindExprs = new List<MemberAssignment>();
|
var bindExprs = new List<MemberAssignment>();
|
||||||
|
|
||||||
//foreach (var field in apiContext.Fields)
|
//foreach (var field in apiContext.Fields)
|
||||||
@ -151,12 +152,12 @@ public class EmployeeFullDtoHelper : EmployeeDtoHelper
|
|||||||
bindExprs.Add(Expression.Bind(typeof(UserInfo).GetProperty("Id"),
|
bindExprs.Add(Expression.Bind(typeof(UserInfo).GetProperty("Id"),
|
||||||
Expression.Property(parameter, typeof(User).GetProperty("Id"))));
|
Expression.Property(parameter, typeof(User).GetProperty("Id"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
var body = Expression.MemberInit(newExpr, bindExprs);
|
var body = Expression.MemberInit(newExpr, bindExprs);
|
||||||
var lambda = Expression.Lambda<Func<User, UserInfo>>(body, parameter);
|
var lambda = Expression.Lambda<Func<User, UserInfo>>(body, parameter);
|
||||||
|
|
||||||
return lambda;
|
return lambda;
|
||||||
}
|
}
|
||||||
public async Task<EmployeeFullDto> GetSimple(UserInfo userInfo)
|
public async Task<EmployeeFullDto> GetSimple(UserInfo userInfo)
|
||||||
{
|
{
|
||||||
var result = new EmployeeFullDto
|
var result = new EmployeeFullDto
|
||||||
@ -176,97 +177,97 @@ public class EmployeeFullDtoHelper : EmployeeDtoHelper
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EmployeeFullDto> GetFull(UserInfo userInfo)
|
public async Task<EmployeeFullDto> GetFull(UserInfo userInfo)
|
||||||
{
|
{
|
||||||
var result = new EmployeeFullDto
|
var result = new EmployeeFullDto
|
||||||
{
|
{
|
||||||
UserName = userInfo.UserName,
|
UserName = userInfo.UserName,
|
||||||
FirstName = userInfo.FirstName,
|
FirstName = userInfo.FirstName,
|
||||||
LastName = userInfo.LastName,
|
LastName = userInfo.LastName,
|
||||||
Birthday = _apiDateTimeHelper.Get(userInfo.BirthDate),
|
Birthday = _apiDateTimeHelper.Get(userInfo.BirthDate),
|
||||||
Status = userInfo.Status,
|
Status = userInfo.Status,
|
||||||
ActivationStatus = userInfo.ActivationStatus & ~EmployeeActivationStatus.AutoGenerated,
|
ActivationStatus = userInfo.ActivationStatus & ~EmployeeActivationStatus.AutoGenerated,
|
||||||
Terminated = _apiDateTimeHelper.Get(userInfo.TerminatedDate),
|
Terminated = _apiDateTimeHelper.Get(userInfo.TerminatedDate),
|
||||||
WorkFrom = _apiDateTimeHelper.Get(userInfo.WorkFromDate),
|
WorkFrom = _apiDateTimeHelper.Get(userInfo.WorkFromDate),
|
||||||
Email = userInfo.Email,
|
Email = userInfo.Email,
|
||||||
IsVisitor = _userManager.IsUser(userInfo),
|
IsVisitor = _userManager.IsUser(userInfo),
|
||||||
IsAdmin = _userManager.IsDocSpaceAdmin(userInfo),
|
IsAdmin = _userManager.IsDocSpaceAdmin(userInfo),
|
||||||
IsOwner = userInfo.IsOwner(_context.Tenant),
|
IsOwner = userInfo.IsOwner(_context.Tenant),
|
||||||
IsLDAP = userInfo.IsLDAP(),
|
IsCollaborator = _userManager.IsCollaborator(userInfo),
|
||||||
|
IsLDAP = userInfo.IsLDAP(),
|
||||||
IsSSO = userInfo.IsSSO()
|
IsSSO = userInfo.IsSSO()
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
await Init(result, userInfo);
|
await Init(result, userInfo);
|
||||||
|
|
||||||
var quotaSettings = _settingsManager.Load<TenantUserQuotaSettings>();
|
var quotaSettings = _settingsManager.Load<TenantUserQuotaSettings>();
|
||||||
|
|
||||||
if (quotaSettings.EnableUserQuota)
|
if (quotaSettings.EnableUserQuota)
|
||||||
{
|
{
|
||||||
result.UsedSpace = Math.Max(0, _quotaService.FindUserQuotaRows(_context.Tenant.Id, userInfo.Id).Where(r => !string.IsNullOrEmpty(r.Tag)).Sum(r => r.Counter));
|
result.UsedSpace = Math.Max(0, _quotaService.FindUserQuotaRows(_context.Tenant.Id, userInfo.Id).Where(r => !string.IsNullOrEmpty(r.Tag)).Sum(r => r.Counter));
|
||||||
var userQuotaSettings = _settingsManager.LoadForUser<UserQuotaSettings>(userInfo);
|
var userQuotaSettings = _settingsManager.Load<UserQuotaSettings>(userInfo);
|
||||||
result.QuotaLimit = userQuotaSettings != null ? userQuotaSettings.UserQuota : quotaSettings.DefaultUserQuota;
|
result.QuotaLimit = userQuotaSettings != null ? userQuotaSettings.UserQuota : quotaSettings.DefaultUserQuota;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userInfo.Sex.HasValue)
|
if (userInfo.Sex.HasValue)
|
||||||
{
|
{
|
||||||
result.Sex = userInfo.Sex.Value ? "male" : "female";
|
result.Sex = userInfo.Sex.Value ? "male" : "female";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(userInfo.Location))
|
if (!string.IsNullOrEmpty(userInfo.Location))
|
||||||
{
|
{
|
||||||
result.Location = userInfo.Location;
|
result.Location = userInfo.Location;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(userInfo.Notes))
|
if (!string.IsNullOrEmpty(userInfo.Notes))
|
||||||
{
|
{
|
||||||
result.Notes = userInfo.Notes;
|
result.Notes = userInfo.Notes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(userInfo.MobilePhone))
|
if (!string.IsNullOrEmpty(userInfo.MobilePhone))
|
||||||
{
|
{
|
||||||
result.MobilePhone = userInfo.MobilePhone;
|
result.MobilePhone = userInfo.MobilePhone;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.MobilePhoneActivationStatus = userInfo.MobilePhoneActivationStatus;
|
result.MobilePhoneActivationStatus = userInfo.MobilePhoneActivationStatus;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(userInfo.CultureName))
|
if (!string.IsNullOrEmpty(userInfo.CultureName))
|
||||||
{
|
{
|
||||||
result.CultureName = userInfo.CultureName;
|
result.CultureName = userInfo.CultureName;
|
||||||
}
|
}
|
||||||
|
|
||||||
FillConacts(result, userInfo);
|
FillConacts(result, userInfo);
|
||||||
FillGroups(result, userInfo);
|
FillGroups(result, userInfo);
|
||||||
|
|
||||||
var cacheKey = Math.Abs(userInfo.LastModified.GetHashCode());
|
var cacheKey = Math.Abs(userInfo.LastModified.GetHashCode());
|
||||||
|
|
||||||
|
|
||||||
if (_context.Check("avatarMax"))
|
if (_context.Check("avatarMax"))
|
||||||
{
|
{
|
||||||
result.AvatarMax = await _userPhotoManager.GetMaxPhotoURL(userInfo.Id) + $"?hash={cacheKey}";
|
result.AvatarMax = await _userPhotoManager.GetMaxPhotoURL(userInfo.Id) + $"?hash={cacheKey}";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_context.Check("avatarMedium"))
|
if (_context.Check("avatarMedium"))
|
||||||
{
|
{
|
||||||
result.AvatarMedium = await _userPhotoManager.GetMediumPhotoURL(userInfo.Id) + $"?hash={cacheKey}";
|
result.AvatarMedium = await _userPhotoManager.GetMediumPhotoURL(userInfo.Id) + $"?hash={cacheKey}";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_context.Check("avatar"))
|
if (_context.Check("avatar"))
|
||||||
{
|
{
|
||||||
result.Avatar = await _userPhotoManager.GetBigPhotoURL(userInfo.Id) + $"?hash={cacheKey}";
|
result.Avatar = await _userPhotoManager.GetBigPhotoURL(userInfo.Id) + $"?hash={cacheKey}";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_context.Check("listAdminModules"))
|
if (_context.Check("listAdminModules"))
|
||||||
{
|
{
|
||||||
var listAdminModules = userInfo.GetListAdminModules(_webItemSecurity, _webItemManager);
|
var listAdminModules = userInfo.GetListAdminModules(_webItemSecurity, _webItemManager);
|
||||||
if (listAdminModules.Count > 0)
|
if (listAdminModules.Count > 0)
|
||||||
{
|
{
|
||||||
result.ListAdminModules = listAdminModules;
|
result.ListAdminModules = listAdminModules;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
private void FillGroups(EmployeeFullDto result, UserInfo userInfo)
|
private void FillGroups(EmployeeFullDto result, UserInfo userInfo)
|
||||||
{
|
{
|
||||||
@ -289,27 +290,27 @@ public class EmployeeFullDtoHelper : EmployeeDtoHelper
|
|||||||
result.Department = "";
|
result.Department = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FillConacts(EmployeeFullDto employeeWraperFull, UserInfo userInfo)
|
private void FillConacts(EmployeeFullDto employeeWraperFull, UserInfo userInfo)
|
||||||
{
|
{
|
||||||
if (userInfo.ContactsList == null)
|
if (userInfo.ContactsList == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var contacts = new List<Contact>();
|
|
||||||
|
|
||||||
for (var i = 0; i < userInfo.ContactsList.Count; i += 2)
|
|
||||||
{
|
|
||||||
if (i + 1 < userInfo.ContactsList.Count)
|
|
||||||
{
|
|
||||||
contacts.Add(new Contact(userInfo.ContactsList[i], userInfo.ContactsList[i + 1]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contacts.Count > 0)
|
var contacts = new List<Contact>();
|
||||||
{
|
|
||||||
employeeWraperFull.Contacts = contacts;
|
for (var i = 0; i < userInfo.ContactsList.Count; i += 2)
|
||||||
}
|
{
|
||||||
}
|
if (i + 1 < userInfo.ContactsList.Count)
|
||||||
|
{
|
||||||
|
contacts.Add(new Contact(userInfo.ContactsList[i], userInfo.ContactsList[i + 1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contacts.Count > 0)
|
||||||
|
{
|
||||||
|
employeeWraperFull.Contacts = contacts;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -106,3 +106,4 @@ global using RabbitMQ.Client.Events;
|
|||||||
global using StackExchange.Redis.Extensions.Core.Abstractions;
|
global using StackExchange.Redis.Extensions.Core.Abstractions;
|
||||||
|
|
||||||
global using ILogger = Microsoft.Extensions.Logging.ILogger;
|
global using ILogger = Microsoft.Extensions.Logging.ILogger;
|
||||||
|
global using System.Threading.Channels;
|
||||||
|
@ -28,19 +28,12 @@ namespace ASC.Common.Security.Authorizing;
|
|||||||
|
|
||||||
public static class Constants
|
public static class Constants
|
||||||
{
|
{
|
||||||
public static readonly Role DocSpaceAdmin = new Role(new Guid("cd84e66b-b803-40fc-99f9-b2969a54a1de"), "Admin");
|
public static readonly Role DocSpaceAdmin = new Role(new Guid("cd84e66b-b803-40fc-99f9-b2969a54a1de"), "DocSpaceAdmin");
|
||||||
|
|
||||||
public static readonly Role Everyone = new Role(new Guid("c5cc67d1-c3e8-43c0-a3ad-3928ae3e5b5e"), "Everyone");
|
public static readonly Role Everyone = new Role(new Guid("c5cc67d1-c3e8-43c0-a3ad-3928ae3e5b5e"), "Everyone");
|
||||||
|
public static readonly Role RoomAdmin = new Role(new Guid("abef62db-11a8-4673-9d32-ef1d8af19dc0"), "RoomAdmin");
|
||||||
|
public static readonly Role Collaborator = new Role(new Guid("88f11e7c-7407-4bea-b4cb-070010cdbb6b"), "Collaborator");
|
||||||
public static readonly Role RoomAdmin = new Role(new Guid("abef62db-11a8-4673-9d32-ef1d8af19dc0"), "User");
|
public static readonly Role User = new Role(new Guid("aced04fa-dd96-4b35-af3e-346bf1eb972d"), "User");
|
||||||
|
|
||||||
public static readonly Role User = new Role(new Guid("aced04fa-dd96-4b35-af3e-346bf1eb972d"), "Visitor");
|
|
||||||
|
|
||||||
|
|
||||||
public static readonly Role Member = new Role(new Guid("ba74ca02-873f-43dc-8470-8620c156bc67"), "Member");
|
public static readonly Role Member = new Role(new Guid("ba74ca02-873f-43dc-8470-8620c156bc67"), "Member");
|
||||||
|
|
||||||
public static readonly Role Owner = new Role(new Guid("bba32183-a14d-48ed-9d39-c6b4d8925fbf"), "Owner");
|
public static readonly Role Owner = new Role(new Guid("bba32183-a14d-48ed-9d39-c6b4d8925fbf"), "Owner");
|
||||||
|
|
||||||
public static readonly Role Self = new Role(new Guid("5d5b7260-f7f7-49f1-a1c9-95fbb6a12604"), "Self");
|
public static readonly Role Self = new Role(new Guid("5d5b7260-f7f7-49f1-a1c9-95fbb6a12604"), "Self");
|
||||||
}
|
}
|
||||||
|
114
common/ASC.Common/Threading/Channel/ChannelExtension.cs
Normal file
114
common/ASC.Common/Threading/Channel/ChannelExtension.cs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
// (c) Copyright Ascensio System SIA 2010-2022
|
||||||
|
//
|
||||||
|
// This program is a free software product.
|
||||||
|
// You can redistribute it and/or modify it under the terms
|
||||||
|
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||||
|
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||||
|
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||||
|
// any third-party rights.
|
||||||
|
//
|
||||||
|
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||||
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||||
|
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||||
|
//
|
||||||
|
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||||
|
//
|
||||||
|
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||||
|
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||||
|
//
|
||||||
|
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||||
|
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||||
|
// trademark law for use of our trademarks.
|
||||||
|
//
|
||||||
|
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||||
|
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||||
|
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||||
|
|
||||||
|
namespace ASC.Common.Threading;
|
||||||
|
public static class ChannelExtension
|
||||||
|
{
|
||||||
|
public static IList<ChannelReader<T>> Split<T>(this ChannelReader<T> ch, int n, Func<int, int, T, int> selector = null, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var outputs = new Channel<T>[n];
|
||||||
|
|
||||||
|
for (var i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
outputs[i] = Channel.CreateUnbounded<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
var index = 0;
|
||||||
|
|
||||||
|
await foreach (var item in ch.ReadAllAsync(cancellationToken))
|
||||||
|
{
|
||||||
|
if (selector == null)
|
||||||
|
{
|
||||||
|
index = (index + 1) % n;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index = selector(n, index, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
await outputs[index].Writer.WriteAsync(item, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
// TODO: catch error via additional channel
|
||||||
|
// var error = Channel.CreateUnbounded<T>();
|
||||||
|
// await error.Writer.WriteAsync(ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
foreach (var ch in outputs)
|
||||||
|
{
|
||||||
|
ch.Writer.Complete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return outputs.Select(ch => ch.Reader).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChannelReader<T> Merge<T>(this IEnumerable<ChannelReader<T>> inputs, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var output = Channel.CreateUnbounded<T>();
|
||||||
|
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
async Task Redirect(ChannelReader<T> input)
|
||||||
|
{
|
||||||
|
await foreach (var item in input.ReadAllAsync(cancellationToken))
|
||||||
|
{
|
||||||
|
await output.Writer.WriteAsync(item, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.WhenAll(inputs.Select(i => Redirect(i)).ToArray());
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
// TODO: catch error via additional channel
|
||||||
|
// var error = Channel.CreateUnbounded<T>();
|
||||||
|
// await error.Writer.WriteAsync(ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
output.Writer.Complete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -39,16 +39,17 @@ public class SubscriptionManager
|
|||||||
{
|
{
|
||||||
Constants.DocSpaceAdmin.ID,
|
Constants.DocSpaceAdmin.ID,
|
||||||
Constants.Everyone.ID,
|
Constants.Everyone.ID,
|
||||||
Constants.RoomAdmin.ID
|
Constants.RoomAdmin.ID,
|
||||||
|
Constants.Collaborator.ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
public SubscriptionManager(CachedSubscriptionService service, TenantManager tenantManager, ICache cache)
|
public SubscriptionManager(CachedSubscriptionService service, TenantManager tenantManager, ICache cache)
|
||||||
{
|
{
|
||||||
_service = service ?? throw new ArgumentNullException("subscriptionManager");
|
_service = service ?? throw new ArgumentNullException("subscriptionManager");
|
||||||
_tenantManager = tenantManager;
|
_tenantManager = tenantManager;
|
||||||
_cache = cache;
|
_cache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Subscribe(string sourceID, string actionID, string objectID, string recipientID)
|
public void Subscribe(string sourceID, string actionID, string objectID, string recipientID)
|
||||||
{
|
{
|
||||||
var s = new SubscriptionRecord
|
var s = new SubscriptionRecord
|
||||||
@ -79,7 +80,7 @@ public class SubscriptionManager
|
|||||||
|
|
||||||
_service.SaveSubscription(s);
|
_service.SaveSubscription(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unsubscribe(string sourceID, string actionID, string objectID, string recipientID)
|
public void Unsubscribe(string sourceID, string actionID, string objectID, string recipientID)
|
||||||
{
|
{
|
||||||
var s = new SubscriptionRecord
|
var s = new SubscriptionRecord
|
||||||
@ -110,17 +111,17 @@ public class SubscriptionManager
|
|||||||
|
|
||||||
_service.SaveSubscription(s);
|
_service.SaveSubscription(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UnsubscribeAll(string sourceID, string actionID, string objectID)
|
public void UnsubscribeAll(string sourceID, string actionID, string objectID)
|
||||||
{
|
{
|
||||||
_service.RemoveSubscriptions(GetTenant(), sourceID, actionID, objectID);
|
_service.RemoveSubscriptions(GetTenant(), sourceID, actionID, objectID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UnsubscribeAll(string sourceID, string actionID)
|
public void UnsubscribeAll(string sourceID, string actionID)
|
||||||
{
|
{
|
||||||
_service.RemoveSubscriptions(GetTenant(), sourceID, actionID);
|
_service.RemoveSubscriptions(GetTenant(), sourceID, actionID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string[] GetSubscriptionMethod(string sourceID, string actionID, string recipientID)
|
public string[] GetSubscriptionMethod(string sourceID, string actionID, string recipientID)
|
||||||
{
|
{
|
||||||
IEnumerable<SubscriptionMethod> methods;
|
IEnumerable<SubscriptionMethod> methods;
|
||||||
@ -144,27 +145,27 @@ public class SubscriptionManager
|
|||||||
|
|
||||||
return m != null ? m.Methods : Array.Empty<string>();
|
return m != null ? m.Methods : Array.Empty<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string[] GetRecipients(string sourceID, string actionID, string objectID)
|
public string[] GetRecipients(string sourceID, string actionID, string objectID)
|
||||||
{
|
{
|
||||||
return _service.GetRecipients(GetTenant(), sourceID, actionID, objectID);
|
return _service.GetRecipients(GetTenant(), sourceID, actionID, objectID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public object GetSubscriptionRecord(string sourceID, string actionID, string recipientID, string objectID)
|
public object GetSubscriptionRecord(string sourceID, string actionID, string recipientID, string objectID)
|
||||||
{
|
{
|
||||||
return _service.GetSubscription(GetTenant(), sourceID, actionID, recipientID, objectID);
|
return _service.GetSubscription(GetTenant(), sourceID, actionID, recipientID, objectID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string[] GetSubscriptions(string sourceID, string actionID, string recipientID, bool checkSubscribe = true)
|
public string[] GetSubscriptions(string sourceID, string actionID, string recipientID, bool checkSubscribe = true)
|
||||||
{
|
{
|
||||||
return _service.GetSubscriptions(GetTenant(), sourceID, actionID, recipientID, checkSubscribe);
|
return _service.GetSubscriptions(GetTenant(), sourceID, actionID, recipientID, checkSubscribe);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsUnsubscribe(string sourceID, string recipientID, string actionID, string objectID)
|
public bool IsUnsubscribe(string sourceID, string recipientID, string actionID, string objectID)
|
||||||
{
|
{
|
||||||
return _service.IsUnsubscribe(GetTenant(), sourceID, actionID, recipientID, objectID);
|
return _service.IsUnsubscribe(GetTenant(), sourceID, actionID, recipientID, objectID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateSubscriptionMethod(string sourceID, string actionID, string recipientID, string[] senderNames)
|
public void UpdateSubscriptionMethod(string sourceID, string actionID, string recipientID, string[] senderNames)
|
||||||
{
|
{
|
||||||
var m = new SubscriptionMethod
|
var m = new SubscriptionMethod
|
||||||
@ -215,5 +216,5 @@ public class SubscriptionManager
|
|||||||
private int GetTenant()
|
private int GetTenant()
|
||||||
{
|
{
|
||||||
return _tenantManager.GetCurrentTenant().Id;
|
return _tenantManager.GetCurrentTenant().Id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,8 @@ public class TenantManager
|
|||||||
internal CoreBaseSettings CoreBaseSettings { get; set; }
|
internal CoreBaseSettings CoreBaseSettings { get; set; }
|
||||||
internal CoreSettings CoreSettings { get; set; }
|
internal CoreSettings CoreSettings { get; set; }
|
||||||
|
|
||||||
|
private readonly static object _lock = new object();
|
||||||
|
|
||||||
static TenantManager()
|
static TenantManager()
|
||||||
{
|
{
|
||||||
_thisCompAddresses.Add("localhost");
|
_thisCompAddresses.Add("localhost");
|
||||||
@ -333,7 +335,10 @@ public class TenantManager
|
|||||||
|
|
||||||
public void SetTenantQuotaRow(TenantQuotaRow row, bool exchange)
|
public void SetTenantQuotaRow(TenantQuotaRow row, bool exchange)
|
||||||
{
|
{
|
||||||
QuotaService.SetTenantQuotaRow(row, exchange);
|
lock (_lock)
|
||||||
|
{
|
||||||
|
QuotaService.SetTenantQuotaRow(row, exchange);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TenantQuotaRow> FindTenantQuotaRows(int tenantId)
|
public List<TenantQuotaRow> FindTenantQuotaRows(int tenantId)
|
||||||
|
@ -61,7 +61,7 @@ public class UserManager
|
|||||||
private readonly CardDavAddressbook _cardDavAddressbook;
|
private readonly CardDavAddressbook _cardDavAddressbook;
|
||||||
private readonly ILogger<UserManager> _log;
|
private readonly ILogger<UserManager> _log;
|
||||||
private readonly ICache _cache;
|
private readonly ICache _cache;
|
||||||
private readonly TenantQuotaFeatureCheckerCount<CountRoomAdminFeature> _countRoomAdminChecker;
|
private readonly TenantQuotaFeatureCheckerCount<CountPaidUserFeature> _countPaidUserChecker;
|
||||||
private readonly TenantQuotaFeatureCheckerCount<CountUserFeature> _activeUsersFeatureChecker;
|
private readonly TenantQuotaFeatureCheckerCount<CountUserFeature> _activeUsersFeatureChecker;
|
||||||
private readonly Constants _constants;
|
private readonly Constants _constants;
|
||||||
private readonly UserFormatter _userFormatter;
|
private readonly UserFormatter _userFormatter;
|
||||||
@ -86,7 +86,7 @@ public class UserManager
|
|||||||
CardDavAddressbook cardDavAddressbook,
|
CardDavAddressbook cardDavAddressbook,
|
||||||
ILogger<UserManager> log,
|
ILogger<UserManager> log,
|
||||||
ICache cache,
|
ICache cache,
|
||||||
TenantQuotaFeatureCheckerCount<CountRoomAdminFeature> countRoomAdrminChecker,
|
TenantQuotaFeatureCheckerCount<CountPaidUserFeature> countPaidUserChecker,
|
||||||
TenantQuotaFeatureCheckerCount<CountUserFeature> activeUsersFeatureChecker,
|
TenantQuotaFeatureCheckerCount<CountUserFeature> activeUsersFeatureChecker,
|
||||||
UserFormatter userFormatter
|
UserFormatter userFormatter
|
||||||
)
|
)
|
||||||
@ -102,7 +102,7 @@ public class UserManager
|
|||||||
_cardDavAddressbook = cardDavAddressbook;
|
_cardDavAddressbook = cardDavAddressbook;
|
||||||
_log = log;
|
_log = log;
|
||||||
_cache = cache;
|
_cache = cache;
|
||||||
_countRoomAdminChecker = countRoomAdrminChecker;
|
_countPaidUserChecker = countPaidUserChecker;
|
||||||
_activeUsersFeatureChecker = activeUsersFeatureChecker;
|
_activeUsersFeatureChecker = activeUsersFeatureChecker;
|
||||||
_constants = _userManagerConstants.Constants;
|
_constants = _userManagerConstants.Constants;
|
||||||
_userFormatter = userFormatter;
|
_userFormatter = userFormatter;
|
||||||
@ -120,7 +120,7 @@ public class UserManager
|
|||||||
CardDavAddressbook cardDavAddressbook,
|
CardDavAddressbook cardDavAddressbook,
|
||||||
ILogger<UserManager> log,
|
ILogger<UserManager> log,
|
||||||
ICache cache,
|
ICache cache,
|
||||||
TenantQuotaFeatureCheckerCount<CountRoomAdminFeature> tenantQuotaFeatureChecker,
|
TenantQuotaFeatureCheckerCount<CountPaidUserFeature> tenantQuotaFeatureChecker,
|
||||||
TenantQuotaFeatureCheckerCount<CountUserFeature> activeUsersFeatureChecker,
|
TenantQuotaFeatureCheckerCount<CountUserFeature> activeUsersFeatureChecker,
|
||||||
IHttpContextAccessor httpContextAccessor,
|
IHttpContextAccessor httpContextAccessor,
|
||||||
UserFormatter userFormatter)
|
UserFormatter userFormatter)
|
||||||
@ -157,10 +157,16 @@ public class UserManager
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case EmployeeType.RoomAdmin:
|
case EmployeeType.RoomAdmin:
|
||||||
users = users.Where(u => !this.IsUser(u));
|
users = users.Where(u => !this.IsUser(u) && !this.IsCollaborator(u) && !this.IsDocSpaceAdmin(u));
|
||||||
|
break;
|
||||||
|
case EmployeeType.DocSpaceAdmin:
|
||||||
|
users = users.Where(this.IsDocSpaceAdmin);
|
||||||
|
break;
|
||||||
|
case EmployeeType.Collaborator:
|
||||||
|
users = users.Where(this.IsCollaborator);
|
||||||
break;
|
break;
|
||||||
case EmployeeType.User:
|
case EmployeeType.User:
|
||||||
users = users.Where(u => this.IsUser(u));
|
users = users.Where(this.IsUser);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,15 +360,14 @@ public class UserManager
|
|||||||
return newUser;
|
return newUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<UserInfo> SaveUserInfo(UserInfo u, bool isVisitor = false, bool syncCardDav = false)
|
public async Task<UserInfo> SaveUserInfo(UserInfo u, EmployeeType type = EmployeeType.RoomAdmin, bool syncCardDav = false, bool paidUserQuotaCheck = true)
|
||||||
{
|
{
|
||||||
if (IsSystemUser(u.Id))
|
if (IsSystemUser(u.Id))
|
||||||
{
|
{
|
||||||
return SystemUsers[u.Id];
|
return SystemUsers[u.Id];
|
||||||
}
|
}
|
||||||
|
|
||||||
_permissionContext.DemandPermissions(new UserSecurityProvider(u.Id, isVisitor ? EmployeeType.User : EmployeeType.RoomAdmin),
|
_permissionContext.DemandPermissions(new UserSecurityProvider(u.Id, type), Constants.Action_AddRemoveUser);
|
||||||
Constants.Action_AddRemoveUser);
|
|
||||||
|
|
||||||
if (!_coreBaseSettings.Personal)
|
if (!_coreBaseSettings.Personal)
|
||||||
{
|
{
|
||||||
@ -379,13 +384,13 @@ public class UserManager
|
|||||||
throw new InvalidOperationException("User already exist.");
|
throw new InvalidOperationException("User already exist.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isVisitor)
|
if (type is EmployeeType.User)
|
||||||
{
|
{
|
||||||
await _activeUsersFeatureChecker.CheckAppend();
|
await _activeUsersFeatureChecker.CheckAppend();
|
||||||
}
|
}
|
||||||
else
|
else if (paidUserQuotaCheck)
|
||||||
{
|
{
|
||||||
await _countRoomAdminChecker.CheckAppend();
|
await _countPaidUserChecker.CheckAppend();
|
||||||
}
|
}
|
||||||
|
|
||||||
var newUser = _userService.SaveUser(_tenantManager.GetCurrentTenant().Id, u);
|
var newUser = _userService.SaveUser(_tenantManager.GetCurrentTenant().Id, u);
|
||||||
@ -886,16 +891,23 @@ public class UserManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
UserGroupRef r;
|
UserGroupRef r;
|
||||||
if (groupId == Constants.GroupManager.ID || groupId == Constants.GroupUser.ID)
|
if (groupId == Constants.GroupManager.ID || groupId == Constants.GroupUser.ID || groupId == Constants.GroupCollaborator.ID)
|
||||||
{
|
{
|
||||||
var user = refs.TryGetValue(UserGroupRef.CreateKey(Tenant.Id, userId, Constants.GroupUser.ID, UserGroupRefType.Contains), out r) && !r.Removed;
|
var isUser = refs.TryGetValue(UserGroupRef.CreateKey(Tenant.Id, userId, Constants.GroupUser.ID, UserGroupRefType.Contains), out r) && !r.Removed;
|
||||||
if (groupId == Constants.GroupUser.ID)
|
if (groupId == Constants.GroupUser.ID)
|
||||||
{
|
{
|
||||||
return user;
|
return isUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isCollaborator = refs.TryGetValue(UserGroupRef.CreateKey(Tenant.Id, userId, Constants.GroupCollaborator.ID, UserGroupRefType.Contains), out r) && !r.Removed;
|
||||||
|
if (groupId == Constants.GroupCollaborator.ID)
|
||||||
|
{
|
||||||
|
return isCollaborator;
|
||||||
|
}
|
||||||
|
|
||||||
if (groupId == Constants.GroupManager.ID)
|
if (groupId == Constants.GroupManager.ID)
|
||||||
{
|
{
|
||||||
return !user;
|
return !isUser && !isCollaborator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,4 +38,5 @@ public enum EmployeeType
|
|||||||
RoomAdmin = 1,
|
RoomAdmin = 1,
|
||||||
User = 2,
|
User = 2,
|
||||||
DocSpaceAdmin = 3,
|
DocSpaceAdmin = 3,
|
||||||
}
|
Collaborator = 4,
|
||||||
|
}
|
@ -88,16 +88,9 @@ public class DbLoginEventsManager
|
|||||||
{
|
{
|
||||||
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
var events = await loginEventContext.LoginEvents
|
await loginEventContext.LoginEvents
|
||||||
.Where(r => r.Id == loginEventId)
|
.Where(r => r.Id == loginEventId)
|
||||||
.ToListAsync();
|
.ExecuteUpdateAsync(r => r.SetProperty(p => p.Active, false));
|
||||||
|
|
||||||
foreach (var e in events)
|
|
||||||
{
|
|
||||||
e.Active = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
await loginEventContext.SaveChangesAsync();
|
|
||||||
|
|
||||||
ResetCache();
|
ResetCache();
|
||||||
}
|
}
|
||||||
@ -106,16 +99,9 @@ public class DbLoginEventsManager
|
|||||||
{
|
{
|
||||||
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
var events = await loginEventContext.LoginEvents
|
await loginEventContext.LoginEvents
|
||||||
.Where(r => r.TenantId == tenantId && r.UserId == userId && r.Active)
|
.Where(r => r.TenantId == tenantId && r.UserId == userId && r.Active)
|
||||||
.ToListAsync();
|
.ExecuteUpdateAsync(r => r.SetProperty(p => p.Active, false));
|
||||||
|
|
||||||
foreach (var e in events)
|
|
||||||
{
|
|
||||||
e.Active = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
await loginEventContext.SaveChangesAsync();
|
|
||||||
|
|
||||||
ResetCache(tenantId, userId);
|
ResetCache(tenantId, userId);
|
||||||
}
|
}
|
||||||
@ -124,32 +110,18 @@ public class DbLoginEventsManager
|
|||||||
{
|
{
|
||||||
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
var events = await loginEventContext.LoginEvents
|
await loginEventContext.LoginEvents
|
||||||
.Where(r => r.TenantId == tenantId && r.Active)
|
.Where(r => r.TenantId == tenantId && r.Active)
|
||||||
.ToListAsync();
|
.ExecuteUpdateAsync(r => r.SetProperty(p => p.Active, false));
|
||||||
|
|
||||||
foreach (var e in events)
|
|
||||||
{
|
|
||||||
e.Active = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
await loginEventContext.SaveChangesAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task LogOutAllActiveConnectionsExceptThis(int loginEventId, int tenantId, Guid userId)
|
public async Task LogOutAllActiveConnectionsExceptThis(int loginEventId, int tenantId, Guid userId)
|
||||||
{
|
{
|
||||||
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
var events = await loginEventContext.LoginEvents
|
await loginEventContext.LoginEvents
|
||||||
.Where(r => r.TenantId == tenantId && r.UserId == userId && r.Id != loginEventId && r.Active)
|
.Where(r => r.TenantId == tenantId && r.UserId == userId && r.Id != loginEventId && r.Active)
|
||||||
.ToListAsync();
|
.ExecuteUpdateAsync(r => r.SetProperty(p => p.Active, false));
|
||||||
|
|
||||||
foreach (var e in events)
|
|
||||||
{
|
|
||||||
e.Active = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
await loginEventContext.SaveChangesAsync();
|
|
||||||
|
|
||||||
ResetCache(tenantId, userId);
|
ResetCache(tenantId, userId);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||||
|
|
||||||
namespace ASC.Core.Data;
|
namespace ASC.Core.Common.Settings;
|
||||||
|
|
||||||
[Singletone]
|
[Singletone]
|
||||||
public class DbSettingsManagerCache
|
public class DbSettingsManagerCache
|
||||||
@ -46,11 +46,11 @@ public class DbSettingsManagerCache
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Scope]
|
[Scope]
|
||||||
public class DbSettingsManager
|
public class SettingsManager
|
||||||
{
|
{
|
||||||
private readonly TimeSpan _expirationTimeout = TimeSpan.FromMinutes(5);
|
private readonly TimeSpan _expirationTimeout = TimeSpan.FromMinutes(5);
|
||||||
|
|
||||||
private readonly ILogger<DbSettingsManager> _logger;
|
private readonly ILogger<SettingsManager> _logger;
|
||||||
private readonly ICache _cache;
|
private readonly ICache _cache;
|
||||||
private readonly IServiceProvider _serviceProvider;
|
private readonly IServiceProvider _serviceProvider;
|
||||||
private readonly DbSettingsManagerCache _dbSettingsManagerCache;
|
private readonly DbSettingsManagerCache _dbSettingsManagerCache;
|
||||||
@ -58,10 +58,10 @@ public class DbSettingsManager
|
|||||||
private readonly TenantManager _tenantManager;
|
private readonly TenantManager _tenantManager;
|
||||||
private readonly IDbContextFactory<WebstudioDbContext> _dbContextFactory;
|
private readonly IDbContextFactory<WebstudioDbContext> _dbContextFactory;
|
||||||
|
|
||||||
public DbSettingsManager(
|
public SettingsManager(
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
DbSettingsManagerCache dbSettingsManagerCache,
|
DbSettingsManagerCache dbSettingsManagerCache,
|
||||||
ILogger<DbSettingsManager> logger,
|
ILogger<SettingsManager> logger,
|
||||||
AuthContext authContext,
|
AuthContext authContext,
|
||||||
TenantManager tenantManager,
|
TenantManager tenantManager,
|
||||||
IDbContextFactory<WebstudioDbContext> dbContextFactory)
|
IDbContextFactory<WebstudioDbContext> dbContextFactory)
|
||||||
@ -100,96 +100,100 @@ public class DbSettingsManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SaveSettings<T>(T settings, int tenantId) where T : class, ISettings<T>
|
public void ClearCache<T>() where T : class, ISettings<T>
|
||||||
{
|
{
|
||||||
return SaveSettingsFor(settings, tenantId, Guid.Empty);
|
ClearCache<T>(TenantID);
|
||||||
}
|
|
||||||
|
|
||||||
public T LoadSettings<T>(int tenantId) where T : class, ISettings<T>
|
|
||||||
{
|
|
||||||
return LoadSettingsFor<T>(tenantId, Guid.Empty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearCache<T>(int tenantId) where T : class, ISettings<T>
|
public void ClearCache<T>(int tenantId) where T : class, ISettings<T>
|
||||||
{
|
{
|
||||||
var settings = LoadSettings<T>(tenantId);
|
var settings = Load<T>(tenantId, Guid.Empty);
|
||||||
var key = settings.ID.ToString() + tenantId + Guid.Empty;
|
var key = settings.ID.ToString() + tenantId + Guid.Empty;
|
||||||
|
|
||||||
_dbSettingsManagerCache.Remove(key);
|
_dbSettingsManagerCache.Remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T GetDefault<T>() where T : class, ISettings<T>
|
||||||
public bool SaveSettingsFor<T>(T settings, int tenantId, Guid userId) where T : class, ISettings<T>
|
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(settings);
|
var settingsInstance = ActivatorUtilities.CreateInstance<T>(_serviceProvider);
|
||||||
|
return settingsInstance.GetDefault();
|
||||||
using var webstudioDbContext = _dbContextFactory.CreateDbContext();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var key = settings.ID.ToString() + tenantId + userId;
|
|
||||||
var data = Serialize(settings);
|
|
||||||
var def = GetDefault<T>();
|
|
||||||
|
|
||||||
var defaultData = Serialize(def);
|
|
||||||
|
|
||||||
if (data.SequenceEqual(defaultData))
|
|
||||||
{
|
|
||||||
var strategy = webstudioDbContext.Database.CreateExecutionStrategy();
|
|
||||||
|
|
||||||
strategy.Execute(() =>
|
|
||||||
{
|
|
||||||
using var tr = webstudioDbContext.Database.BeginTransaction();
|
|
||||||
// remove default settings
|
|
||||||
var s = webstudioDbContext.WebstudioSettings
|
|
||||||
.Where(r => r.Id == settings.ID)
|
|
||||||
.Where(r => r.TenantId == tenantId)
|
|
||||||
.Where(r => r.UserId == userId)
|
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
if (s != null)
|
|
||||||
{
|
|
||||||
webstudioDbContext.WebstudioSettings.Remove(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
webstudioDbContext.SaveChanges();
|
|
||||||
|
|
||||||
tr.Commit();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var s = new DbWebstudioSettings
|
|
||||||
{
|
|
||||||
Id = settings.ID,
|
|
||||||
UserId = userId,
|
|
||||||
TenantId = tenantId,
|
|
||||||
Data = data
|
|
||||||
};
|
|
||||||
|
|
||||||
webstudioDbContext.AddOrUpdate(webstudioDbContext.WebstudioSettings, s);
|
|
||||||
|
|
||||||
webstudioDbContext.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
_dbSettingsManagerCache.Remove(key);
|
|
||||||
|
|
||||||
_cache.Insert(key, settings, _expirationTimeout);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.ErrorSaveSettingsFor(ex);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal T LoadSettingsFor<T>(int tenantId, Guid userId) where T : class, ISettings<T>
|
public T Load<T>() where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
return Load<T>(TenantID, Guid.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Load<T>(Guid userId) where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
return Load<T>(TenantID, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Load<T>(UserInfo user) where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
return Load<T>(TenantID, user.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Load<T>(int tenantId) where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
return Load<T>(tenantId, Guid.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T LoadForDefaultTenant<T>() where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
return Load<T>(Tenant.DefaultTenant);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T LoadForCurrentUser<T>() where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
return Load<T>(CurrentUserID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Save<T>(T data) where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
return Save(data, TenantID, Guid.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Save<T>(T data, Guid userId) where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
return Save(data, TenantID, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Save<T>(T data, UserInfo user) where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
return Save(data, TenantID, user.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Save<T>(T data, int tenantId) where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
return Save(data, tenantId, Guid.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SaveForDefaultTenant<T>(T data) where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
return Save(data, Tenant.DefaultTenant);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SaveForCurrentUser<T>(T data) where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
return Save(data, CurrentUserID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Manage<T>(Action<T> action) where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
var settings = Load<T>();
|
||||||
|
action(settings);
|
||||||
|
return Save(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ManageForCurrentUser<T>(Action<T> action) where T : class, ISettings<T>
|
||||||
|
{
|
||||||
|
var settings = LoadForCurrentUser<T>();
|
||||||
|
action(settings);
|
||||||
|
return SaveForCurrentUser(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal T Load<T>(int tenantId, Guid userId) where T : class, ISettings<T>
|
||||||
{
|
{
|
||||||
var def = GetDefault<T>();
|
var def = GetDefault<T>();
|
||||||
var key = def.ID.ToString() + tenantId + userId;
|
var key = def.ID.ToString() + tenantId + userId;
|
||||||
@ -231,75 +235,71 @@ public class DbSettingsManager
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T GetDefault<T>() where T : class, ISettings<T>
|
private bool Save<T>(T settings, int tenantId, Guid userId) where T : class, ISettings<T>
|
||||||
{
|
{
|
||||||
var settingsInstance = ActivatorUtilities.CreateInstance<T>(_serviceProvider);
|
ArgumentNullException.ThrowIfNull(settings);
|
||||||
return settingsInstance.GetDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
public T Load<T>() where T : class, ISettings<T>
|
using var webstudioDbContext = _dbContextFactory.CreateDbContext();
|
||||||
{
|
|
||||||
return LoadSettings<T>(TenantID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T LoadForCurrentUser<T>() where T : class, ISettings<T>
|
try
|
||||||
{
|
{
|
||||||
return LoadForUser<T>(CurrentUserID);
|
var key = settings.ID.ToString() + tenantId + userId;
|
||||||
}
|
var data = Serialize(settings);
|
||||||
|
var def = GetDefault<T>();
|
||||||
|
|
||||||
public T LoadForUser<T>(Guid userId) where T : class, ISettings<T>
|
var defaultData = Serialize(def);
|
||||||
{
|
|
||||||
return LoadSettingsFor<T>(TenantID, userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T LoadForUser<T>(UserInfo user) where T : class, ISettings<T>
|
if (data.SequenceEqual(defaultData))
|
||||||
{
|
{
|
||||||
return LoadSettingsFor<T>(TenantID, user.Id);
|
var strategy = webstudioDbContext.Database.CreateExecutionStrategy();
|
||||||
}
|
|
||||||
|
|
||||||
public T LoadForDefaultTenant<T>() where T : class, ISettings<T>
|
strategy.Execute(() =>
|
||||||
{
|
{
|
||||||
return LoadForTenant<T>(Tenant.DefaultTenant);
|
using var tr = webstudioDbContext.Database.BeginTransaction();
|
||||||
}
|
// remove default settings
|
||||||
|
var s = webstudioDbContext.WebstudioSettings
|
||||||
|
.Where(r => r.Id == settings.ID)
|
||||||
|
.Where(r => r.TenantId == tenantId)
|
||||||
|
.Where(r => r.UserId == userId)
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
public T LoadForTenant<T>(int tenantId) where T : class, ISettings<T>
|
if (s != null)
|
||||||
{
|
{
|
||||||
return LoadSettings<T>(tenantId);
|
webstudioDbContext.WebstudioSettings.Remove(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool Save<T>(T data) where T : class, ISettings<T>
|
webstudioDbContext.SaveChanges();
|
||||||
{
|
|
||||||
return SaveSettings(data, TenantID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SaveForCurrentUser<T>(T data) where T : class, ISettings<T>
|
tr.Commit();
|
||||||
{
|
});
|
||||||
return SaveForUser(data, CurrentUserID);
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
var s = new DbWebstudioSettings
|
||||||
|
{
|
||||||
|
Id = settings.ID,
|
||||||
|
UserId = userId,
|
||||||
|
TenantId = tenantId,
|
||||||
|
Data = data
|
||||||
|
};
|
||||||
|
|
||||||
public bool SaveForUser<T>(T data, Guid userId) where T : class, ISettings<T>
|
webstudioDbContext.AddOrUpdate(webstudioDbContext.WebstudioSettings, s);
|
||||||
{
|
|
||||||
return SaveSettingsFor(data, TenantID, userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SaveForUser<T>(T data, UserInfo user) where T : class, ISettings<T>
|
webstudioDbContext.SaveChanges();
|
||||||
{
|
}
|
||||||
return SaveSettingsFor(data, TenantID, user.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SaveForDefaultTenant<T>(T data) where T : class, ISettings<T>
|
_dbSettingsManagerCache.Remove(key);
|
||||||
{
|
|
||||||
return SaveForTenant(data, Tenant.DefaultTenant);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SaveForTenant<T>(T data, int tenantId) where T : class, ISettings<T>
|
_cache.Insert(key, settings, _expirationTimeout);
|
||||||
{
|
|
||||||
return SaveSettings(data, tenantId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearCache<T>() where T : class, ISettings<T>
|
return true;
|
||||||
{
|
}
|
||||||
ClearCache<T>(TenantID);
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorSaveSettingsFor(ex);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private T Deserialize<T>(string data)
|
private T Deserialize<T>(string data)
|
||||||
|
@ -227,7 +227,8 @@ public class EFUserService : IUserService
|
|||||||
if (sortBy == "type")
|
if (sortBy == "type")
|
||||||
{
|
{
|
||||||
var q1 = from user in q
|
var q1 = from user in q
|
||||||
join userGroup in userDbContext.UserGroups.Where(g => !g.Removed && (g.UserGroupId == Users.Constants.GroupAdmin.ID || g.UserGroupId == Users.Constants.GroupUser.ID))
|
join userGroup in userDbContext.UserGroups.Where(g => !g.Removed && (g.UserGroupId == Users.Constants.GroupAdmin.ID || g.UserGroupId == Users.Constants.GroupUser.ID
|
||||||
|
|| g.UserGroupId == Users.Constants.GroupCollaborator.ID))
|
||||||
on user.Id equals userGroup.Userid into joinedGroup
|
on user.Id equals userGroup.Userid into joinedGroup
|
||||||
from @group in joinedGroup.DefaultIfEmpty()
|
from @group in joinedGroup.DefaultIfEmpty()
|
||||||
select new { user, @group };
|
select new { user, @group };
|
||||||
@ -235,12 +236,18 @@ public class EFUserService : IUserService
|
|||||||
if (sortOrderAsc)
|
if (sortOrderAsc)
|
||||||
{
|
{
|
||||||
q = q1.OrderBy(r => r.user.ActivationStatus == EmployeeActivationStatus.Pending)
|
q = q1.OrderBy(r => r.user.ActivationStatus == EmployeeActivationStatus.Pending)
|
||||||
.ThenBy(r => r.group != null && r.group.UserGroupId == Users.Constants.GroupAdmin.ID ? 1 : r.group == null ? 2 : 3).Select(r => r.user);
|
.ThenBy(r => r.group == null ? 2 :
|
||||||
|
r.group.UserGroupId == Users.Constants.GroupAdmin.ID ? 1 :
|
||||||
|
r.group.UserGroupId == Users.Constants.GroupCollaborator.ID ? 3 : 4)
|
||||||
|
.Select(r => r.user);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
q = q1.OrderBy(r => r.user.ActivationStatus == EmployeeActivationStatus.Pending)
|
q = q1.OrderBy(r => r.user.ActivationStatus == EmployeeActivationStatus.Pending)
|
||||||
.ThenByDescending(u => u.group != null && u.group.UserGroupId == Users.Constants.GroupAdmin.ID ? 1 : u.group == null ? 2 : 3).Select(r => r.user);
|
.ThenByDescending(u => u.group == null ? 2 :
|
||||||
|
u.group.UserGroupId == Users.Constants.GroupAdmin.ID ? 1 :
|
||||||
|
u.group.UserGroupId == Users.Constants.GroupCollaborator.ID ? 3 : 4)
|
||||||
|
.Select(r => r.user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -300,33 +307,29 @@ public class EFUserService : IUserService
|
|||||||
using var userDbContext = _dbContextFactory.CreateDbContext();
|
using var userDbContext = _dbContextFactory.CreateDbContext();
|
||||||
using var tr = userDbContext.Database.BeginTransaction();
|
using var tr = userDbContext.Database.BeginTransaction();
|
||||||
|
|
||||||
userDbContext.Acl.RemoveRange(userDbContext.Acl.Where(r => r.Tenant == tenant && ids.Any(i => i == r.Subject)));
|
userDbContext.Acl.Where(r => r.Tenant == tenant && ids.Any(i => i == r.Subject)).ExecuteDelete();
|
||||||
userDbContext.Subscriptions.RemoveRange(userDbContext.Subscriptions.Where(r => r.Tenant == tenant && stringIds.Any(i => i == r.Recipient)));
|
userDbContext.Subscriptions.Where(r => r.Tenant == tenant && stringIds.Any(i => i == r.Recipient)).ExecuteDelete();
|
||||||
userDbContext.SubscriptionMethods.RemoveRange(userDbContext.SubscriptionMethods.Where(r => r.Tenant == tenant && stringIds.Any(i => i == r.Recipient)));
|
userDbContext.SubscriptionMethods.Where(r => r.Tenant == tenant && stringIds.Any(i => i == r.Recipient)).ExecuteDelete();
|
||||||
|
|
||||||
var userGroups = userDbContext.UserGroups.Where(r => r.Tenant == tenant && ids.Any(i => i == r.UserGroupId));
|
var userGroups = userDbContext.UserGroups.Where(r => r.Tenant == tenant && ids.Any(i => i == r.UserGroupId));
|
||||||
var groups = userDbContext.Groups.Where(r => r.Tenant == tenant && ids.Any(i => i == r.Id));
|
var groups = userDbContext.Groups.Where(r => r.Tenant == tenant && ids.Any(i => i == r.Id));
|
||||||
|
|
||||||
if (immediate)
|
if (immediate)
|
||||||
{
|
{
|
||||||
userDbContext.UserGroups.RemoveRange(userGroups);
|
userGroups.ExecuteDelete();
|
||||||
userDbContext.Groups.RemoveRange(groups);
|
groups.ExecuteDelete();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (var ug in userGroups)
|
userGroups.ExecuteUpdate(ug => ug
|
||||||
{
|
.SetProperty(p => p.Removed, true)
|
||||||
ug.Removed = true;
|
.SetProperty(p => p.LastModified, DateTime.UtcNow));
|
||||||
ug.LastModified = DateTime.UtcNow;
|
|
||||||
}
|
groups.ExecuteUpdate(g => g
|
||||||
foreach (var g in groups)
|
.SetProperty(p => p.Removed, true)
|
||||||
{
|
.SetProperty(p => p.LastModified, DateTime.UtcNow));
|
||||||
g.Removed = true;
|
|
||||||
g.LastModified = DateTime.UtcNow;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
userDbContext.SaveChanges();
|
|
||||||
tr.Commit();
|
tr.Commit();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -346,10 +349,10 @@ public class EFUserService : IUserService
|
|||||||
using var userDbContext = _dbContextFactory.CreateDbContext();
|
using var userDbContext = _dbContextFactory.CreateDbContext();
|
||||||
using var tr = userDbContext.Database.BeginTransaction();
|
using var tr = userDbContext.Database.BeginTransaction();
|
||||||
|
|
||||||
userDbContext.Acl.RemoveRange(userDbContext.Acl.Where(r => r.Tenant == tenant && r.Subject == id));
|
userDbContext.Acl.Where(r => r.Tenant == tenant && r.Subject == id).ExecuteDelete();
|
||||||
userDbContext.Subscriptions.RemoveRange(userDbContext.Subscriptions.Where(r => r.Tenant == tenant && r.Recipient == id.ToString()));
|
userDbContext.Subscriptions.Where(r => r.Tenant == tenant && r.Recipient == id.ToString()).ExecuteDelete();
|
||||||
userDbContext.SubscriptionMethods.RemoveRange(userDbContext.SubscriptionMethods.Where(r => r.Tenant == tenant && r.Recipient == id.ToString()));
|
userDbContext.SubscriptionMethods.Where(r => r.Tenant == tenant && r.Recipient == id.ToString()).ExecuteDelete();
|
||||||
userDbContext.Photos.RemoveRange(userDbContext.Photos.Where(r => r.Tenant == tenant && r.UserId == id));
|
userDbContext.Photos.Where(r => r.Tenant == tenant && r.UserId == id).ExecuteDelete();
|
||||||
|
|
||||||
var userGroups = userDbContext.UserGroups.Where(r => r.Tenant == tenant && r.Userid == id);
|
var userGroups = userDbContext.UserGroups.Where(r => r.Tenant == tenant && r.Userid == id);
|
||||||
var users = userDbContext.Users.Where(r => r.Tenant == tenant && r.Id == id);
|
var users = userDbContext.Users.Where(r => r.Tenant == tenant && r.Id == id);
|
||||||
@ -357,29 +360,24 @@ public class EFUserService : IUserService
|
|||||||
|
|
||||||
if (immediate)
|
if (immediate)
|
||||||
{
|
{
|
||||||
userDbContext.UserGroups.RemoveRange(userGroups);
|
userGroups.ExecuteDelete();
|
||||||
userDbContext.Users.RemoveRange(users);
|
users.ExecuteDelete();
|
||||||
userDbContext.UserSecurity.RemoveRange(userSecurity);
|
userSecurity.ExecuteDelete();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (var ug in userGroups)
|
userGroups.ExecuteUpdate(ug => ug
|
||||||
{
|
.SetProperty(p => p.Removed, true)
|
||||||
ug.Removed = true;
|
.SetProperty(p => p.LastModified, DateTime.UtcNow));
|
||||||
ug.LastModified = DateTime.UtcNow;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var u in users)
|
users.ExecuteUpdate(ug => ug
|
||||||
{
|
.SetProperty(p => p.Removed, true)
|
||||||
u.Removed = true;
|
.SetProperty(p => p.LastModified, DateTime.UtcNow)
|
||||||
u.Status = EmployeeStatus.Terminated;
|
.SetProperty(p => p.TerminatedDate, DateTime.UtcNow)
|
||||||
u.TerminatedDate = DateTime.UtcNow;
|
.SetProperty(p => p.Status, EmployeeStatus.Terminated)
|
||||||
u.LastModified = DateTime.UtcNow;
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
userDbContext.SaveChanges();
|
|
||||||
|
|
||||||
tr.Commit();
|
tr.Commit();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -402,16 +400,15 @@ public class EFUserService : IUserService
|
|||||||
var userGroups = userDbContext.UserGroups.Where(r => r.Tenant == tenant && r.Userid == userId && r.UserGroupId == groupId && r.RefType == refType);
|
var userGroups = userDbContext.UserGroups.Where(r => r.Tenant == tenant && r.Userid == userId && r.UserGroupId == groupId && r.RefType == refType);
|
||||||
if (immediate)
|
if (immediate)
|
||||||
{
|
{
|
||||||
userDbContext.UserGroups.RemoveRange(userGroups);
|
userGroups.ExecuteDelete();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (var u in userGroups)
|
userGroups.ExecuteUpdate(ug => ug
|
||||||
{
|
.SetProperty(p => p.Removed, true)
|
||||||
u.LastModified = DateTime.UtcNow;
|
.SetProperty(p => p.LastModified, DateTime.UtcNow));
|
||||||
u.Removed = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = userDbContext.Users.First(r => r.Tenant == tenant && r.Id == userId);
|
var user = userDbContext.Users.First(r => r.Tenant == tenant && r.Id == userId);
|
||||||
user.LastModified = DateTime.UtcNow;
|
user.LastModified = DateTime.UtcNow;
|
||||||
userDbContext.SaveChanges();
|
userDbContext.SaveChanges();
|
||||||
@ -749,4 +746,4 @@ public class DbUserSecurity
|
|||||||
{
|
{
|
||||||
public User User { get; set; }
|
public User User { get; set; }
|
||||||
public UserSecurity UserSecurity { get; set; }
|
public UserSecurity UserSecurity { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ public class HostedSolution
|
|||||||
internal UserFormatter UserFormatter { get; set; }
|
internal UserFormatter UserFormatter { get; set; }
|
||||||
internal TenantManager ClientTenantManager { get; set; }
|
internal TenantManager ClientTenantManager { get; set; }
|
||||||
internal TenantUtil TenantUtil { get; set; }
|
internal TenantUtil TenantUtil { get; set; }
|
||||||
internal DbSettingsManager SettingsManager { get; set; }
|
internal SettingsManager SettingsManager { get; set; }
|
||||||
internal CoreSettings CoreSettings { get; set; }
|
internal CoreSettings CoreSettings { get; set; }
|
||||||
|
|
||||||
public string Region { get; private set; }
|
public string Region { get; private set; }
|
||||||
@ -51,7 +51,7 @@ public class HostedSolution
|
|||||||
UserFormatter userFormatter,
|
UserFormatter userFormatter,
|
||||||
TenantManager clientTenantManager,
|
TenantManager clientTenantManager,
|
||||||
TenantUtil tenantUtil,
|
TenantUtil tenantUtil,
|
||||||
DbSettingsManager settingsManager,
|
SettingsManager settingsManager,
|
||||||
CoreSettings coreSettings)
|
CoreSettings coreSettings)
|
||||||
{
|
{
|
||||||
TenantService = tenantService;
|
TenantService = tenantService;
|
||||||
@ -196,9 +196,9 @@ public class HostedSolution
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tenantSettings = SettingsManager.LoadSettingsFor<TenantCookieSettings>(tenantId, Guid.Empty);
|
var tenantSettings = SettingsManager.Load<TenantCookieSettings>(tenantId, Guid.Empty);
|
||||||
var expires = tenantSettings.IsDefault() ? DateTime.UtcNow.AddYears(1) : DateTime.UtcNow.AddMinutes(tenantSettings.LifeTime);
|
var expires = tenantSettings.IsDefault() ? DateTime.UtcNow.AddYears(1) : DateTime.UtcNow.AddMinutes(tenantSettings.LifeTime);
|
||||||
var userSettings = SettingsManager.LoadSettingsFor<TenantCookieSettings>(tenantId, user.Id);
|
var userSettings = SettingsManager.Load<TenantCookieSettings>(tenantId, user.Id);
|
||||||
|
|
||||||
return cookieStorage.EncryptCookie(tenantId, user.Id, tenantSettings.Index, expires, userSettings.Index, 0);
|
return cookieStorage.EncryptCookie(tenantId, user.Id, tenantSettings.Index, expires, userSettings.Index, 0);
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ namespace ASC.Core.Common.Log;
|
|||||||
internal static partial class DbSettingsManagerLogger
|
internal static partial class DbSettingsManagerLogger
|
||||||
{
|
{
|
||||||
[LoggerMessage(Level = LogLevel.Error, Message = "SaveSettingsFor")]
|
[LoggerMessage(Level = LogLevel.Error, Message = "SaveSettingsFor")]
|
||||||
public static partial void ErrorSaveSettingsFor(this ILogger<DbSettingsManager> logger, Exception exception);
|
public static partial void ErrorSaveSettingsFor(this ILogger<SettingsManager> logger, Exception exception);
|
||||||
|
|
||||||
[LoggerMessage(Level = LogLevel.Error, Message = "LoadSettingsFor")]
|
[LoggerMessage(Level = LogLevel.Error, Message = "LoadSettingsFor")]
|
||||||
public static partial void ErrorLoadSettingsFor(this ILogger<DbSettingsManager> logger, Exception exception);
|
public static partial void ErrorLoadSettingsFor(this ILogger<SettingsManager> logger, Exception exception);
|
||||||
}
|
}
|
||||||
|
@ -445,7 +445,8 @@ public enum MessageAction
|
|||||||
DocumentsForcesave = 5049,
|
DocumentsForcesave = 5049,
|
||||||
DocumentsStoreForcesave = 5048,
|
DocumentsStoreForcesave = 5048,
|
||||||
DocumentsUploadingFormatsSettingsUpdated = 5033,
|
DocumentsUploadingFormatsSettingsUpdated = 5033,
|
||||||
DocumentsExternalShareSettingsUpdated = 5069, // last
|
DocumentsExternalShareSettingsUpdated = 5069,
|
||||||
|
DocumentsKeepNewFileNameSettingsUpdated = 5083, // last
|
||||||
|
|
||||||
FileConverted = 5035,
|
FileConverted = 5035,
|
||||||
|
|
||||||
|
@ -71,24 +71,18 @@ public class TelegramDao
|
|||||||
{
|
{
|
||||||
using var dbContext = _dbContextFactory.CreateDbContext();
|
using var dbContext = _dbContextFactory.CreateDbContext();
|
||||||
|
|
||||||
var toRemove = dbContext.Users
|
dbContext.Users
|
||||||
.Where(r => r.PortalUserId == userId)
|
.Where(r => r.PortalUserId == userId)
|
||||||
.Where(r => r.TenantId == tenantId)
|
.Where(r => r.TenantId == tenantId)
|
||||||
.ToList();
|
.ExecuteDelete();
|
||||||
|
|
||||||
dbContext.Users.RemoveRange(toRemove);
|
|
||||||
dbContext.SaveChanges();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(long telegramId)
|
public void Delete(long telegramId)
|
||||||
{
|
{
|
||||||
using var dbContext = _dbContextFactory.CreateDbContext();
|
using var dbContext = _dbContextFactory.CreateDbContext();
|
||||||
|
|
||||||
var toRemove = dbContext.Users
|
dbContext.Users
|
||||||
.Where(r => r.TelegramUserId == telegramId)
|
.Where(r => r.TelegramUserId == telegramId)
|
||||||
.ToList();
|
.ExecuteDelete();
|
||||||
|
|
||||||
dbContext.Users.RemoveRange(toRemove);
|
|
||||||
dbContext.SaveChanges();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,36 @@
|
|||||||
// (c) Copyright Ascensio System SIA 2010-2022
|
// (c) Copyright Ascensio System SIA 2010-2022
|
||||||
//
|
//
|
||||||
// This program is a free software product.
|
// This program is a free software product.
|
||||||
// You can redistribute it and/or modify it under the terms
|
// You can redistribute it and/or modify it under the terms
|
||||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||||
// any third-party rights.
|
// any third-party rights.
|
||||||
//
|
//
|
||||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||||
//
|
//
|
||||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||||
//
|
//
|
||||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||||
//
|
//
|
||||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||||
// trademark law for use of our trademarks.
|
// trademark law for use of our trademarks.
|
||||||
//
|
//
|
||||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||||
|
|
||||||
namespace ASC.Core.Common.Quota.Features;
|
namespace ASC.Core.Common.Quota.Features;
|
||||||
|
|
||||||
public class CountRoomAdminFeature : TenantQuotaFeatureCount
|
public class CountPaidUserFeature : TenantQuotaFeatureCount
|
||||||
{
|
{
|
||||||
public override bool Paid { get => true; }
|
public override bool Paid { get => true; }
|
||||||
public override string Name { get => "manager"; }
|
public override string Name { get => "manager"; }
|
||||||
public CountRoomAdminFeature(TenantQuota tenantQuota) : base(tenantQuota)
|
public CountPaidUserFeature(TenantQuota tenantQuota) : base(tenantQuota)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,6 +24,8 @@
|
|||||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||||
|
|
||||||
|
using Constants = ASC.Common.Security.Authorizing.Constants;
|
||||||
|
|
||||||
namespace ASC.Core.Security.Authorizing;
|
namespace ASC.Core.Security.Authorizing;
|
||||||
|
|
||||||
[Scope]
|
[Scope]
|
||||||
@ -50,6 +52,11 @@ class RoleProvider : IRoleProvider
|
|||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (roles.Any(r => r.ID == Constants.Collaborator.ID || r.ID == Constants.User.ID))
|
||||||
|
{
|
||||||
|
roles = roles.Where(r => r.ID != Constants.RoomAdmin.ID).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
@ -75,4 +82,4 @@ class RoleProvider : IRoleProvider
|
|||||||
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,23 +31,30 @@ namespace ASC.Core.Common.Security;
|
|||||||
|
|
||||||
public static class Security
|
public static class Security
|
||||||
{
|
{
|
||||||
public static readonly Dictionary<Guid, Dictionary<Guid, HashSet<Rule>>> Rules = new Dictionary<Guid, Dictionary<Guid, HashSet<Rule>>>
|
public static readonly Dictionary<Guid, Dictionary<Guid, HashSet<Rule>>> Rules = new()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
Constants.RoomAdmin.ID, new Dictionary<Guid, HashSet<Rule>>()
|
Constants.RoomAdmin.ID, new Dictionary<Guid, HashSet<Rule>>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
Constants.User.ID, new HashSet<Rule>()
|
Constants.User.ID, new HashSet<Rule>
|
||||||
{
|
{
|
||||||
new Rule(UserConstants.Action_EditGroups.ID, Constants.User),
|
new(UserConstants.Action_EditGroups.ID, Constants.User),
|
||||||
new Rule(UserConstants.Action_AddRemoveUser.ID),
|
new(UserConstants.Action_AddRemoveUser.ID),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Constants.RoomAdmin.ID, new HashSet<Rule>()
|
Constants.RoomAdmin.ID, new HashSet<Rule>
|
||||||
{
|
{
|
||||||
new Rule(UserConstants.Action_EditGroups.ID, Constants.User),
|
new(UserConstants.Action_EditGroups.ID, Constants.User),
|
||||||
new Rule(UserConstants.Action_AddRemoveUser.ID),
|
new(UserConstants.Action_AddRemoveUser.ID),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Constants.Collaborator.ID, new HashSet<Rule>
|
||||||
|
{
|
||||||
|
new(UserConstants.Action_EditGroups.ID, Constants.Collaborator),
|
||||||
|
new(UserConstants.Action_AddRemoveUser.ID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,29 +24,44 @@
|
|||||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||||
|
|
||||||
|
using AuthConstants = ASC.Common.Security.Authorizing.Constants;
|
||||||
|
|
||||||
namespace ASC.Core.Common.Security;
|
namespace ASC.Core.Common.Security;
|
||||||
|
|
||||||
public class UserGroupObject : SecurityObject
|
public class UserGroupObject : SecurityObject
|
||||||
{
|
{
|
||||||
private ISubject User { get; set; }
|
private readonly Guid _groupId;
|
||||||
private Guid GroupId { get; set; }
|
|
||||||
|
|
||||||
public UserGroupObject(ISubject user, Guid groupId)
|
public UserGroupObject(ISubject user, Guid groupId)
|
||||||
{
|
{
|
||||||
SecurityId = user.ID;
|
SecurityId = user.ID;
|
||||||
User = user;
|
_groupId = groupId;
|
||||||
GroupId = groupId;
|
|
||||||
ObjectType = typeof(UserGroupObject);
|
ObjectType = typeof(UserGroupObject);
|
||||||
FullId = $"{ObjectType.FullName}|{User.ID}|{GroupId}";
|
FullId = $"{ObjectType.FullName}|{user.ID}|{_groupId}";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IEnumerable<IRole> GetTargetRoles(IRoleProvider roleProvider)
|
protected override IEnumerable<IRole> GetTargetRoles(IRoleProvider roleProvider)
|
||||||
{
|
{
|
||||||
return roleProvider.GetRoles(User);
|
if (_groupId == Users.Constants.GroupAdmin.ID)
|
||||||
|
{
|
||||||
|
return new[] { AuthConstants.DocSpaceAdmin };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_groupId == Users.Constants.GroupUser.ID)
|
||||||
|
{
|
||||||
|
return new[] { AuthConstants.User };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_groupId == Users.Constants.GroupCollaborator.ID)
|
||||||
|
{
|
||||||
|
return new[] { AuthConstants.Collaborator };
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.Empty<IRole>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IRuleData GetRuleData()
|
protected override IRuleData GetRuleData()
|
||||||
{
|
{
|
||||||
return new Role(GroupId, "ruleData");
|
return new Role(_groupId, "ruleData");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -67,6 +67,7 @@ public class UserSecurityProvider : SecurityObject
|
|||||||
{
|
{
|
||||||
EmployeeType.DocSpaceAdmin => new[] { AuthConstants.DocSpaceAdmin },
|
EmployeeType.DocSpaceAdmin => new[] { AuthConstants.DocSpaceAdmin },
|
||||||
EmployeeType.RoomAdmin => new[] { AuthConstants.RoomAdmin },
|
EmployeeType.RoomAdmin => new[] { AuthConstants.RoomAdmin },
|
||||||
|
EmployeeType.Collaborator => new[] { AuthConstants.Collaborator },
|
||||||
EmployeeType.User => new[] { AuthConstants.User },
|
EmployeeType.User => new[] { AuthConstants.User },
|
||||||
_ => Array.Empty<IRole>(),
|
_ => Array.Empty<IRole>(),
|
||||||
};
|
};
|
||||||
|
@ -72,7 +72,7 @@ public class TenantCookieSettingsHelper
|
|||||||
public TenantCookieSettings GetForTenant(int tenantId)
|
public TenantCookieSettings GetForTenant(int tenantId)
|
||||||
{
|
{
|
||||||
return IsVisibleSettings
|
return IsVisibleSettings
|
||||||
? _settingsManager.LoadForTenant<TenantCookieSettings>(tenantId)
|
? _settingsManager.Load<TenantCookieSettings>(tenantId)
|
||||||
: TenantCookieSettings.GetInstance();
|
: TenantCookieSettings.GetInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,20 +83,20 @@ public class TenantCookieSettingsHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_settingsManager.SaveForTenant(settings ?? TenantCookieSettings.GetInstance(), tenantId);
|
_settingsManager.Save(settings ?? TenantCookieSettings.GetInstance(), tenantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TenantCookieSettings GetForUser(Guid userId)
|
public TenantCookieSettings GetForUser(Guid userId)
|
||||||
{
|
{
|
||||||
return IsVisibleSettings
|
return IsVisibleSettings
|
||||||
? _settingsManager.LoadForUser<TenantCookieSettings>(userId)
|
? _settingsManager.Load<TenantCookieSettings>(userId)
|
||||||
: TenantCookieSettings.GetInstance();
|
: TenantCookieSettings.GetInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TenantCookieSettings GetForUser(int tenantId, Guid userId)
|
public TenantCookieSettings GetForUser(int tenantId, Guid userId)
|
||||||
{
|
{
|
||||||
return IsVisibleSettings
|
return IsVisibleSettings
|
||||||
? _settingsManager.LoadSettingsFor<TenantCookieSettings>(tenantId, userId)
|
? _settingsManager.Load<TenantCookieSettings>(tenantId, userId)
|
||||||
: TenantCookieSettings.GetInstance();
|
: TenantCookieSettings.GetInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ public class TenantCookieSettingsHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_settingsManager.SaveForUser(settings ?? TenantCookieSettings.GetInstance(), userId);
|
_settingsManager.Save(settings ?? TenantCookieSettings.GetInstance(), userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateTime GetExpiresTime(int tenantId)
|
public DateTime GetExpiresTime(int tenantId)
|
||||||
|
@ -90,11 +90,11 @@ public class TenantQuota : IMapFrom<DbQuota>
|
|||||||
set => _countUserFeature.Value = value;
|
set => _countUserFeature.Value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly CountRoomAdminFeature _countRoomAdminFeature;
|
private readonly CountPaidUserFeature _countPaidUserFeature;
|
||||||
public int CountRoomAdmin
|
public int CountRoomAdmin
|
||||||
{
|
{
|
||||||
get => _countRoomAdminFeature.Value;
|
get => _countPaidUserFeature.Value;
|
||||||
set => _countRoomAdminFeature.Value = value;
|
set => _countPaidUserFeature.Value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly UsersInRoomFeature _usersInRoomFeature;
|
private readonly UsersInRoomFeature _usersInRoomFeature;
|
||||||
@ -221,7 +221,7 @@ public class TenantQuota : IMapFrom<DbQuota>
|
|||||||
_featuresList = new List<string>();
|
_featuresList = new List<string>();
|
||||||
|
|
||||||
_countUserFeature = new CountUserFeature(this) { Order = 1 };
|
_countUserFeature = new CountUserFeature(this) { Order = 1 };
|
||||||
_countRoomAdminFeature = new CountRoomAdminFeature(this);
|
_countPaidUserFeature = new CountPaidUserFeature(this);
|
||||||
_usersInRoomFeature = new UsersInRoomFeature(this) { Order = 8 };
|
_usersInRoomFeature = new UsersInRoomFeature(this) { Order = 8 };
|
||||||
_countRoomFeature = new CountRoomFeature(this) { Order = 2 };
|
_countRoomFeature = new CountRoomFeature(this) { Order = 2 };
|
||||||
_maxTotalSizeFeature = new MaxTotalSizeFeature(this);
|
_maxTotalSizeFeature = new MaxTotalSizeFeature(this);
|
||||||
@ -245,7 +245,7 @@ public class TenantQuota : IMapFrom<DbQuota>
|
|||||||
TenantQuotaFeatures = new List<TenantQuotaFeature>
|
TenantQuotaFeatures = new List<TenantQuotaFeature>
|
||||||
{
|
{
|
||||||
_countUserFeature,
|
_countUserFeature,
|
||||||
_countRoomAdminFeature,
|
_countPaidUserFeature,
|
||||||
_usersInRoomFeature,
|
_usersInRoomFeature,
|
||||||
_countRoomFeature,
|
_countRoomFeature,
|
||||||
_maxTotalSizeFeature,
|
_maxTotalSizeFeature,
|
||||||
|
@ -24,9 +24,9 @@
|
|||||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||||
|
|
||||||
using Action = ASC.Common.Security.Authorizing.Action;
|
using Action = ASC.Common.Security.Authorizing.Action;
|
||||||
using AuthConst = ASC.Common.Security.Authorizing.Constants;
|
using AuthConst = ASC.Common.Security.Authorizing.Constants;
|
||||||
|
|
||||||
namespace ASC.Core.Users;
|
namespace ASC.Core.Users;
|
||||||
|
|
||||||
[Singletone]
|
[Singletone]
|
||||||
@ -59,7 +59,7 @@ public sealed class Constants
|
|||||||
|
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
#region system group and category groups
|
#region system group and category groups
|
||||||
|
|
||||||
public static readonly Guid SysGroupCategoryId = new Guid("{7717039D-FBE9-45ad-81C1-68A1AA10CE1F}");
|
public static readonly Guid SysGroupCategoryId = new Guid("{7717039D-FBE9-45ad-81C1-68A1AA10CE1F}");
|
||||||
|
|
||||||
@ -87,12 +87,19 @@ public sealed class Constants
|
|||||||
Name = AuthConst.DocSpaceAdmin.Name,
|
Name = AuthConst.DocSpaceAdmin.Name,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static readonly GroupInfo GroupCollaborator = new(SysGroupCategoryId)
|
||||||
|
{
|
||||||
|
ID = AuthConst.Collaborator.ID,
|
||||||
|
Name = AuthConst.Collaborator.Name,
|
||||||
|
};
|
||||||
|
|
||||||
public static readonly GroupInfo[] BuildinGroups = new[]
|
public static readonly GroupInfo[] BuildinGroups = new[]
|
||||||
{
|
{
|
||||||
GroupEveryone,
|
GroupEveryone,
|
||||||
GroupUser,
|
GroupUser,
|
||||||
GroupManager,
|
GroupManager,
|
||||||
GroupAdmin,
|
GroupAdmin,
|
||||||
|
GroupCollaborator,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly UserInfo LostUser = new UserInfo
|
public static readonly UserInfo LostUser = new UserInfo
|
||||||
@ -119,10 +126,10 @@ public sealed class Constants
|
|||||||
Name = "Unknown"
|
Name = "Unknown"
|
||||||
};
|
};
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region authorization rules module to work with users
|
#region authorization rules module to work with users
|
||||||
|
|
||||||
public static readonly Action Action_EditUser = new Action(
|
public static readonly Action Action_EditUser = new Action(
|
||||||
new Guid("{EF5E6790-F346-4b6e-B662-722BC28CB0DB}"),
|
new Guid("{EF5E6790-F346-4b6e-B662-722BC28CB0DB}"),
|
||||||
@ -136,5 +143,5 @@ public sealed class Constants
|
|||||||
new Guid("{1D4FEEAC-0BF3-4aa9-B096-6D6B104B79B5}"),
|
new Guid("{1D4FEEAC-0BF3-4aa9-B096-6D6B104B79B5}"),
|
||||||
"Edit categories and groups");
|
"Edit categories and groups");
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,12 @@ public static class UserExtensions
|
|||||||
|
|
||||||
public static bool IsMe(this UserInfo ui, AuthContext authContext)
|
public static bool IsMe(this UserInfo ui, AuthContext authContext)
|
||||||
{
|
{
|
||||||
return ui != null && ui.Id == authContext.CurrentAccount.ID;
|
return IsMe(ui, authContext.CurrentAccount.ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsMe(this UserInfo user, Guid id)
|
||||||
|
{
|
||||||
|
return user != null && user.Id == id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsDocSpaceAdmin(this UserManager userManager, Guid id)
|
public static bool IsDocSpaceAdmin(this UserManager userManager, Guid id)
|
||||||
@ -65,6 +70,17 @@ public static class UserExtensions
|
|||||||
return ui != null && userManager.IsUserInGroup(ui.Id, Constants.GroupUser.ID);
|
return ui != null && userManager.IsUserInGroup(ui.Id, Constants.GroupUser.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsCollaborator(this UserManager userManager, UserInfo userInfo)
|
||||||
|
{
|
||||||
|
return userInfo != null && userManager.IsUserInGroup(userInfo.Id, Constants.GroupCollaborator.ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsCollaborator(this UserManager userManager, Guid id)
|
||||||
|
{
|
||||||
|
var userInfo = userManager.GetUsers(id);
|
||||||
|
return userManager.IsCollaborator(userInfo);
|
||||||
|
}
|
||||||
|
|
||||||
public static bool IsOutsider(this UserManager userManager, Guid id)
|
public static bool IsOutsider(this UserManager userManager, Guid id)
|
||||||
{
|
{
|
||||||
return userManager.IsUser(id) && id == Constants.OutsideUser.Id;
|
return userManager.IsUser(id) && id == Constants.OutsideUser.Id;
|
||||||
@ -98,7 +114,15 @@ public static class UserExtensions
|
|||||||
|
|
||||||
public static EmployeeType GetUserType(this UserManager userManager, Guid id)
|
public static EmployeeType GetUserType(this UserManager userManager, Guid id)
|
||||||
{
|
{
|
||||||
return userManager.IsDocSpaceAdmin(id) ? EmployeeType.DocSpaceAdmin : userManager.IsUser(id) ? EmployeeType.User : EmployeeType.RoomAdmin;
|
if (userManager.GetUsers(id).Equals(Constants.LostUser))
|
||||||
|
{
|
||||||
|
return EmployeeType.User;
|
||||||
|
}
|
||||||
|
|
||||||
|
return userManager.IsDocSpaceAdmin(id) ? EmployeeType.DocSpaceAdmin :
|
||||||
|
userManager.IsUser(id) ? EmployeeType.User :
|
||||||
|
userManager.IsCollaborator(id) ? EmployeeType.Collaborator :
|
||||||
|
EmployeeType.RoomAdmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
private const string _extMobPhone = "extmobphone";
|
private const string _extMobPhone = "extmobphone";
|
||||||
@ -146,4 +170,4 @@ public static class UserExtensions
|
|||||||
|
|
||||||
ui.ContactsList = newContacts;
|
ui.ContactsList = newContacts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,10 +115,7 @@ public class BackupRepository : IBackupRepository
|
|||||||
public void DeleteBackupSchedule(int tenantId)
|
public void DeleteBackupSchedule(int tenantId)
|
||||||
{
|
{
|
||||||
using var backupContext = _dbContextFactory.CreateDbContext();
|
using var backupContext = _dbContextFactory.CreateDbContext();
|
||||||
var shedule = backupContext.Schedules.AsQueryable().Where(s => s.TenantId == tenantId).ToList();
|
backupContext.Schedules.Where(s => s.TenantId == tenantId).ExecuteDelete();
|
||||||
|
|
||||||
backupContext.Schedules.RemoveRange(shedule);
|
|
||||||
backupContext.SaveChanges();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BackupSchedule> GetBackupSchedules()
|
public List<BackupSchedule> GetBackupSchedules()
|
||||||
|
@ -40,7 +40,7 @@ public class Helpers
|
|||||||
ConfigurationConstants.CoreSystem.ID,
|
ConfigurationConstants.CoreSystem.ID,
|
||||||
ConfigurationConstants.Guest.ID,
|
ConfigurationConstants.Guest.ID,
|
||||||
UserConstants.LostUser.Id
|
UserConstants.LostUser.Id
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly Guid[] _systemGroups = new[]
|
private readonly Guid[] _systemGroups = new[]
|
||||||
{
|
{
|
||||||
@ -50,6 +50,7 @@ public class Helpers
|
|||||||
UserConstants.GroupEveryone.ID,
|
UserConstants.GroupEveryone.ID,
|
||||||
UserConstants.GroupUser.ID,
|
UserConstants.GroupUser.ID,
|
||||||
UserConstants.GroupManager.ID,
|
UserConstants.GroupManager.ID,
|
||||||
|
UserConstants.GroupCollaborator.ID,
|
||||||
new Guid("{EA942538-E68E-4907-9394-035336EE0BA8}"), //community product
|
new Guid("{EA942538-E68E-4907-9394-035336EE0BA8}"), //community product
|
||||||
new Guid("{1e044602-43b5-4d79-82f3-fd6208a11960}"), //projects product
|
new Guid("{1e044602-43b5-4d79-82f3-fd6208a11960}"), //projects product
|
||||||
new Guid("{6743007C-6F95-4d20-8C88-A8601CE5E76D}"), //crm product
|
new Guid("{6743007C-6F95-4d20-8C88-A8601CE5E76D}"), //crm product
|
||||||
@ -59,7 +60,7 @@ public class Helpers
|
|||||||
new Guid("{32D24CB5-7ECE-4606-9C94-19216BA42086}"), //calendar product
|
new Guid("{32D24CB5-7ECE-4606-9C94-19216BA42086}"), //calendar product
|
||||||
new Guid("{37620AE5-C40B-45ce-855A-39DD7D76A1FA}"), //birthdays product
|
new Guid("{37620AE5-C40B-45ce-855A-39DD7D76A1FA}"), //birthdays product
|
||||||
new Guid("{BF88953E-3C43-4850-A3FB-B1E43AD53A3E}") //talk product
|
new Guid("{BF88953E-3C43-4850-A3FB-B1E43AD53A3E}") //talk product
|
||||||
};
|
};
|
||||||
|
|
||||||
public Helpers(InstanceCrypto instanceCrypto)
|
public Helpers(InstanceCrypto instanceCrypto)
|
||||||
{
|
{
|
||||||
|
@ -117,14 +117,17 @@ public class CommonChunkedUploadSession : ICloneable
|
|||||||
switch (value.ValueKind)
|
switch (value.ValueKind)
|
||||||
{
|
{
|
||||||
case JsonValueKind.String:
|
case JsonValueKind.String:
|
||||||
newItems.Add(item.Key, item.Value.ToString());
|
newItems.Add(item.Key, item.Value.ToString());
|
||||||
break;
|
break;
|
||||||
case JsonValueKind.Number:
|
case JsonValueKind.Number:
|
||||||
newItems.Add(item.Key, Int32.Parse(item.Value.ToString()));
|
newItems.Add(item.Key, Int32.Parse(item.Value.ToString()));
|
||||||
break;
|
break;
|
||||||
case JsonValueKind.Array:
|
case JsonValueKind.Array:
|
||||||
newItems.Add(item.Key, value.EnumerateArray().Select(o => o.ToString()).ToList());
|
newItems.Add(item.Key, value.EnumerateArray().Select(o => o.ToString()).ToList());
|
||||||
break;
|
break;
|
||||||
|
case JsonValueKind.Object:
|
||||||
|
newItems.Add(item.Key, JsonSerializer.Deserialize<Dictionary<int, string>>(item.Value.ToString()));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
newItems.Add(item.Key, item.Value);
|
newItems.Add(item.Key, item.Value);
|
||||||
break;
|
break;
|
||||||
|
@ -63,13 +63,13 @@ public class BaseStorageSettingsListener
|
|||||||
|
|
||||||
var scopeClass = scope.ServiceProvider.GetService<BaseStorageSettingsListenerScope>();
|
var scopeClass = scope.ServiceProvider.GetService<BaseStorageSettingsListenerScope>();
|
||||||
var (storageSettingsHelper, settingsManager) = scopeClass;
|
var (storageSettingsHelper, settingsManager) = scopeClass;
|
||||||
var settings = settingsManager.LoadForTenant<StorageSettings>(i.TenantId);
|
var settings = settingsManager.Load<StorageSettings>(i.TenantId);
|
||||||
if (i.Name == settings.Module)
|
if (i.Name == settings.Module)
|
||||||
{
|
{
|
||||||
storageSettingsHelper.Clear(settings);
|
storageSettingsHelper.Clear(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
var cdnSettings = settingsManager.LoadForTenant<CdnStorageSettings>(i.TenantId);
|
var cdnSettings = settingsManager.Load<CdnStorageSettings>(i.TenantId);
|
||||||
if (i.Name == cdnSettings.Module)
|
if (i.Name == cdnSettings.Module)
|
||||||
{
|
{
|
||||||
storageSettingsHelper.Clear(cdnSettings);
|
storageSettingsHelper.Clear(cdnSettings);
|
||||||
|
@ -155,7 +155,7 @@ public class StorageFactory
|
|||||||
throw new InvalidOperationException("config section not found");
|
throw new InvalidOperationException("config section not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
var settings = _settingsManager.LoadForTenant<StorageSettings>(tenant.Value);
|
var settings = _settingsManager.Load<StorageSettings>(tenant.Value);
|
||||||
//TODO:GetStoreAndCache
|
//TODO:GetStoreAndCache
|
||||||
return GetDataStore(tenantPath, module, _storageSettingsHelper.DataStoreConsumer(settings), controller, region);
|
return GetDataStore(tenantPath, module, _storageSettingsHelper.DataStoreConsumer(settings), controller, region);
|
||||||
}
|
}
|
||||||
|
@ -89,8 +89,8 @@ public class S3ZipWriteOperator : IDataWriteOperator
|
|||||||
{
|
{
|
||||||
var fs = _fileStream;
|
var fs = _fileStream;
|
||||||
_fileStream = null;
|
_fileStream = null;
|
||||||
Upload(fs);
|
|
||||||
Computehash(fs, false);
|
Computehash(fs, false);
|
||||||
|
Upload(fs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ public class S3ZipWriteOperator : IDataWriteOperator
|
|||||||
stream.Position = 0;
|
stream.Position = 0;
|
||||||
var buffer = new byte[_sessionHolder.MaxChunkUploadSize];
|
var buffer = new byte[_sessionHolder.MaxChunkUploadSize];
|
||||||
int bytesRead;
|
int bytesRead;
|
||||||
while ((bytesRead = _fileStream.Read(buffer, 0, (int)_sessionHolder.MaxChunkUploadSize)) > 0)
|
while ((bytesRead = stream.Read(buffer, 0, (int)_sessionHolder.MaxChunkUploadSize)) > 0)
|
||||||
{
|
{
|
||||||
_sha.TransformBlock(buffer, 0, bytesRead, buffer, 0);
|
_sha.TransformBlock(buffer, 0, bytesRead, buffer, 0);
|
||||||
}
|
}
|
||||||
@ -134,12 +134,13 @@ public class S3ZipWriteOperator : IDataWriteOperator
|
|||||||
_tarOutputStream.Close();
|
_tarOutputStream.Close();
|
||||||
_tarOutputStream.Dispose();
|
_tarOutputStream.Dispose();
|
||||||
|
|
||||||
|
Computehash(_fileStream, true);
|
||||||
Upload(_fileStream);
|
Upload(_fileStream);
|
||||||
|
|
||||||
Task.WaitAll(_tasks.ToArray());
|
Task.WaitAll(_tasks.ToArray());
|
||||||
|
|
||||||
StoragePath = await _sessionHolder.FinalizeAsync(_chunkedUploadSession);
|
StoragePath = await _sessionHolder.FinalizeAsync(_chunkedUploadSession);
|
||||||
|
|
||||||
Computehash(_fileStream, true);
|
|
||||||
Hash = BitConverter.ToString(_sha.Hash).Replace("-", string.Empty);
|
Hash = BitConverter.ToString(_sha.Hash).Replace("-", string.Empty);
|
||||||
_sha.Dispose();
|
_sha.Dispose();
|
||||||
|
|
||||||
|
@ -154,11 +154,8 @@ public class FeedAggregateDataProvider
|
|||||||
using var feedDbContext = _dbContextFactory.CreateDbContext();
|
using var feedDbContext = _dbContextFactory.CreateDbContext();
|
||||||
using var tx = feedDbContext.Database.BeginTransaction(IsolationLevel.ReadUncommitted);
|
using var tx = feedDbContext.Database.BeginTransaction(IsolationLevel.ReadUncommitted);
|
||||||
|
|
||||||
var aggregates = feedDbContext.FeedAggregates.Where(r => r.AggregateDate <= fromTime);
|
feedDbContext.FeedAggregates.Where(r => r.AggregateDate <= fromTime).ExecuteDelete();
|
||||||
feedDbContext.FeedAggregates.RemoveRange(aggregates);
|
feedDbContext.FeedUsers.Where(r => feedDbContext.FeedAggregates.Where(r => r.AggregateDate <= fromTime).Any(a => a.Id == r.FeedId)).ExecuteDelete();
|
||||||
|
|
||||||
var users = feedDbContext.FeedUsers.Where(r => feedDbContext.FeedAggregates.Where(r => r.AggregateDate <= fromTime).Any(a => a.Id == r.FeedId));
|
|
||||||
feedDbContext.FeedUsers.RemoveRange(users);
|
|
||||||
|
|
||||||
tx.Commit();
|
tx.Commit();
|
||||||
});
|
});
|
||||||
@ -310,13 +307,8 @@ public class FeedAggregateDataProvider
|
|||||||
using var feedDbContext = _dbContextFactory.CreateDbContext();
|
using var feedDbContext = _dbContextFactory.CreateDbContext();
|
||||||
using var tx = feedDbContext.Database.BeginTransaction(IsolationLevel.ReadUncommitted);
|
using var tx = feedDbContext.Database.BeginTransaction(IsolationLevel.ReadUncommitted);
|
||||||
|
|
||||||
var aggregates = feedDbContext.FeedAggregates.Where(r => r.Id == id);
|
feedDbContext.FeedAggregates.Where(r => r.Id == id).ExecuteDelete();
|
||||||
feedDbContext.FeedAggregates.RemoveRange(aggregates);
|
feedDbContext.FeedUsers.Where(r => r.FeedId == id).ExecuteDelete();
|
||||||
|
|
||||||
var users = feedDbContext.FeedUsers.Where(r => r.FeedId == id);
|
|
||||||
feedDbContext.FeedUsers.RemoveRange(users);
|
|
||||||
|
|
||||||
feedDbContext.SaveChanges();
|
|
||||||
|
|
||||||
tx.Commit();
|
tx.Commit();
|
||||||
});
|
});
|
||||||
|
@ -57,16 +57,14 @@ public class IPRestrictionsRepository
|
|||||||
using var tenantDbContext = _dbContextManager.CreateDbContext();
|
using var tenantDbContext = _dbContextManager.CreateDbContext();
|
||||||
using var tx = tenantDbContext.Database.BeginTransaction();
|
using var tx = tenantDbContext.Database.BeginTransaction();
|
||||||
|
|
||||||
var restrictions = tenantDbContext.TenantIpRestrictions.Where(r => r.Tenant == tenant).ToList();
|
tenantDbContext.TenantIpRestrictions.Where(r => r.Tenant == tenant).ExecuteDelete();
|
||||||
tenantDbContext.TenantIpRestrictions.RemoveRange(restrictions);
|
|
||||||
tenantDbContext.SaveChanges();
|
|
||||||
|
|
||||||
var ipsList = ips.Select(r => new TenantIpRestrictions
|
var ipsList = ips.Select(r => new TenantIpRestrictions
|
||||||
{
|
{
|
||||||
Tenant = tenant,
|
Tenant = tenant,
|
||||||
Ip = r.Ip,
|
Ip = r.Ip,
|
||||||
ForAdmin = r.ForAdmin
|
ForAdmin = r.ForAdmin
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tenantDbContext.TenantIpRestrictions.AddRange(ipsList);
|
tenantDbContext.TenantIpRestrictions.AddRange(ipsList);
|
||||||
|
@ -69,7 +69,13 @@ public class DbWorker
|
|||||||
return objForCreate;
|
return objForCreate;
|
||||||
}
|
}
|
||||||
|
|
||||||
var toAdd = new WebhooksConfig { TenantId = Tenant, Uri = uri, SecretKey = secretKey };
|
var toAdd = new WebhooksConfig
|
||||||
|
{
|
||||||
|
TenantId = Tenant,
|
||||||
|
Uri = uri,
|
||||||
|
SecretKey = secretKey
|
||||||
|
};
|
||||||
|
|
||||||
toAdd = await webhooksDbContext.AddOrUpdateAsync(r => r.WebhooksConfigs, toAdd);
|
toAdd = await webhooksDbContext.AddOrUpdateAsync(r => r.WebhooksConfigs, toAdd);
|
||||||
await webhooksDbContext.SaveChangesAsync();
|
await webhooksDbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
@ -123,9 +123,9 @@ public class Startup
|
|||||||
|
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
app.UseEndpoints(endpoints =>
|
app.UseEndpoints(async endpoints =>
|
||||||
{
|
{
|
||||||
endpoints.MapCustom();
|
await endpoints.MapCustomAsync();
|
||||||
|
|
||||||
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
|
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
|
||||||
{
|
{
|
||||||
|
@ -144,19 +144,20 @@ public class Startup
|
|||||||
|
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
app.UseEndpoints(endpoints =>
|
app.UseEndpoints( async endpoints =>
|
||||||
{
|
{
|
||||||
endpoints.MapCustom();
|
await endpoints.MapCustomAsync();
|
||||||
|
|
||||||
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
|
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
|
||||||
{
|
{
|
||||||
Predicate = _ => true,
|
Predicate = _ => true,
|
||||||
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
|
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
|
||||||
});
|
});
|
||||||
|
|
||||||
endpoints.MapHealthChecks("/liveness", new HealthCheckOptions
|
endpoints.MapHealthChecks("/liveness", new HealthCheckOptions
|
||||||
{
|
{
|
||||||
Predicate = r => r.Name.Contains("self")
|
Predicate = r => r.Name.Contains("self")
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -57,10 +57,7 @@ try
|
|||||||
|
|
||||||
startup.ConfigureServices(builder.Services);
|
startup.ConfigureServices(builder.Services);
|
||||||
|
|
||||||
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
|
builder.Host.ConfigureContainer<ContainerBuilder>(startup.ConfigureContainer);
|
||||||
{
|
|
||||||
startup.ConfigureContainer(containerBuilder);
|
|
||||||
});
|
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
@ -57,10 +57,7 @@ try
|
|||||||
|
|
||||||
startup.ConfigureServices(builder.Services);
|
startup.ConfigureServices(builder.Services);
|
||||||
|
|
||||||
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
|
builder.Host.ConfigureContainer<ContainerBuilder>(startup.ConfigureContainer);
|
||||||
{
|
|
||||||
startup.ConfigureContainer(containerBuilder);
|
|
||||||
});
|
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ public class SearchSettingsHelper
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var settings = _settingsManager.LoadForTenant<SearchSettings>(tenantId);
|
var settings = _settingsManager.Load<SearchSettings>(tenantId);
|
||||||
|
|
||||||
return settings.IsEnabled(((ISearchItemDocument)_serviceProvider.GetService(t)).IndexName);
|
return settings.IsEnabled(((ISearchItemDocument)_serviceProvider.GetService(t)).IndexName);
|
||||||
}
|
}
|
||||||
|
@ -85,15 +85,11 @@ public class NotifyCleanerService : BackgroundService
|
|||||||
{
|
{
|
||||||
using var tx = dbContext.Database.BeginTransaction();
|
using var tx = dbContext.Database.BeginTransaction();
|
||||||
|
|
||||||
var info = dbContext.NotifyInfo.Where(r => r.ModifyDate < date && r.State == 4).ToList();
|
var infoCount = dbContext.NotifyInfo.Where(r => r.ModifyDate < date && r.State == 4).ExecuteDelete();
|
||||||
var queue = dbContext.NotifyQueue.Where(r => r.CreationDate < date).ToList();
|
var queueCount = dbContext.NotifyQueue.Where(r => r.CreationDate < date).ExecuteDelete();
|
||||||
dbContext.NotifyInfo.RemoveRange(info);
|
|
||||||
dbContext.NotifyQueue.RemoveRange(queue);
|
|
||||||
|
|
||||||
dbContext.SaveChanges();
|
|
||||||
tx.Commit();
|
tx.Commit();
|
||||||
|
|
||||||
_logger.InformationClearNotifyMessages(info.Count, queue.Count);
|
_logger.InformationClearNotifyMessages(infoCount, queueCount);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (ThreadAbortException)
|
catch (ThreadAbortException)
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
To begin the development, run `npm start` or `yarn start`.
|
To begin the development, run `npm start` or `yarn start`.
|
||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
To create a production bundle, use `npm run build` or `yarn build`.
|
||||||
-->
|
-->
|
||||||
|
<script src="/static/scripts/browserDetector.js"></script>
|
||||||
<script>
|
<script>
|
||||||
console.log("It's WEB CLIENT INIT");
|
console.log("It's WEB CLIENT INIT");
|
||||||
fetch("/static/scripts/config.json")
|
fetch("/static/scripts/config.json")
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
"ResetApplicationDescription": "Authenticator application configuration will be reset.",
|
"ResetApplicationDescription": "Authenticator application configuration will be reset.",
|
||||||
"ResetApplicationTitle": "Reset application configuration"
|
"ResetApplicationTitle": "Reset application configuration",
|
||||||
|
"SuccessResetApplication": "Application settings for authentication have been successfully reset"
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
"Remove": "Remove",
|
"Remove": "Remove",
|
||||||
"RoleCommentator": "Commentator",
|
"RoleCommentator": "Commentator",
|
||||||
"RoleCommentatorDescription": "Operations with existing files: viewing, commenting.",
|
"RoleCommentatorDescription": "Operations with existing files: viewing, commenting.",
|
||||||
|
"RoleCollaboratorDescription": "Collaborators can create and edit files in the room, but can't create rooms, manage users, or access settings.",
|
||||||
"RoleDocSpaceAdminDescription": "DocSpace admins can access DocSpace settings, manage and archive rooms, invite new users and assign roles below their level. All admins have access to the Personal section.",
|
"RoleDocSpaceAdminDescription": "DocSpace admins can access DocSpace settings, manage and archive rooms, invite new users and assign roles below their level. All admins have access to the Personal section.",
|
||||||
"RoleEditor": "Editor",
|
"RoleEditor": "Editor",
|
||||||
"RoleEditorDescription": "Operations with existing files: viewing, editing, form filling, reviewing, commenting.",
|
"RoleEditorDescription": "Operations with existing files: viewing, editing, form filling, reviewing, commenting.",
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
"BackToParentFolderButton": "Вернуться в папку на уровень выше",
|
"BackToParentFolderButton": "Вернуться в папку на уровень выше",
|
||||||
"ByAuthor": "Автор",
|
"ByAuthor": "Автор",
|
||||||
"ByCreation": "Создан",
|
"ByCreation": "Создан",
|
||||||
|
"ByErasure": "Стирание",
|
||||||
"ByLastModified": "Изменен",
|
"ByLastModified": "Изменен",
|
||||||
"ByOwner": "владелец",
|
"ByOwner": "владелец",
|
||||||
"CollaborationRooms": "Совместное редактирование",
|
"CollaborationRooms": "Совместное редактирование",
|
||||||
@ -22,6 +23,7 @@
|
|||||||
"CopyItems": "Скопировано элементов: <strong>{{qty}}</strong>",
|
"CopyItems": "Скопировано элементов: <strong>{{qty}}</strong>",
|
||||||
"CreateRoom": "Создание комнаты",
|
"CreateRoom": "Создание комнаты",
|
||||||
"CustomRooms": "Пользовательская",
|
"CustomRooms": "Пользовательская",
|
||||||
|
"DaysRemaining": "Дней осталось: {{daysRemaining}}",
|
||||||
"Document": "Документ",
|
"Document": "Документ",
|
||||||
"EditRoom": "Изменить комнату",
|
"EditRoom": "Изменить комнату",
|
||||||
"EmptyFile": "Пустой файл",
|
"EmptyFile": "Пустой файл",
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
"ResetApplicationDescription": "Настройки приложения для аутентификации будут сброшены.",
|
"ResetApplicationDescription": "Настройки приложения для аутентификации будут сброшены.",
|
||||||
"ResetApplicationTitle": "Сбросить настройки приложения"
|
"ResetApplicationTitle": "Сбросить настройки приложения",
|
||||||
|
"SuccessResetApplication": "Настройки приложения для аутентификации успешно сброшены"
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
"Remove": "Удалить",
|
"Remove": "Удалить",
|
||||||
"RoleCommentator": "Комментатор",
|
"RoleCommentator": "Комментатор",
|
||||||
"RoleCommentatorDescription": "Операции с существующими файлами: просмотр, комментирование.",
|
"RoleCommentatorDescription": "Операции с существующими файлами: просмотр, комментирование.",
|
||||||
|
"RoleCollaboratorDescription": "Сотрудники могут создавать и редактировать файлы в комнате, но не могут создавать комнаты, управлять пользователями или получать доступ к настройкам.",
|
||||||
"RoleDocSpaceAdminDescription": "Администраторы DocSpace могут получить доступ к настройкам DocSpace, управлять и архивировать комнаты, приглашать новых пользователей и назначать роли ниже своего уровня. Все администраторы имеют доступ к Личному разделу.",
|
"RoleDocSpaceAdminDescription": "Администраторы DocSpace могут получить доступ к настройкам DocSpace, управлять и архивировать комнаты, приглашать новых пользователей и назначать роли ниже своего уровня. Все администраторы имеют доступ к Личному разделу.",
|
||||||
"RoleEditor": "Редактор",
|
"RoleEditor": "Редактор",
|
||||||
"RoleEditorDescription": "Операции с существующими файлами: просмотр, редактирование, заполнение форм, рецензирование, комментирование.",
|
"RoleEditorDescription": "Операции с существующими файлами: просмотр, редактирование, заполнение форм, рецензирование, комментирование.",
|
||||||
|
@ -55,7 +55,7 @@ const withLoader = (WrappedComponent) => (Loader) => {
|
|||||||
|
|
||||||
return (!isEditor && firstLoad && !isGallery) ||
|
return (!isEditor && firstLoad && !isGallery) ||
|
||||||
!isLoaded ||
|
!isLoaded ||
|
||||||
(isMobile && inLoad) ||
|
(isMobile && inLoad && !firstLoad) ||
|
||||||
(isLoadingFilesFind && !Loader) ||
|
(isLoadingFilesFind && !Loader) ||
|
||||||
!tReady ||
|
!tReady ||
|
||||||
!isInit ? (
|
!isInit ? (
|
||||||
|
@ -517,7 +517,6 @@ const ShellWrapper = inject(({ auth, backup }) => {
|
|||||||
setSnackbarExist,
|
setSnackbarExist,
|
||||||
socketHelper,
|
socketHelper,
|
||||||
setTheme,
|
setTheme,
|
||||||
getWhiteLabelLogoUrls,
|
|
||||||
whiteLabelLogoUrls,
|
whiteLabelLogoUrls,
|
||||||
} = settingsStore;
|
} = settingsStore;
|
||||||
const isBase = settingsStore.theme.isBase;
|
const isBase = settingsStore.theme.isBase;
|
||||||
|
3
packages/client/src/bootstrap.js
vendored
3
packages/client/src/bootstrap.js
vendored
@ -2,7 +2,8 @@ import React from "react";
|
|||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
//import { registerSW } from "@docspace/common/sw/helper";
|
//import { registerSW } from "@docspace/common/sw/helper";
|
||||||
|
const root = document.getElementById("root");
|
||||||
|
|
||||||
ReactDOM.render(<App />, document.getElementById("root"));
|
if (root) ReactDOM.render(<App />, root);
|
||||||
|
|
||||||
//registerSW();
|
//registerSW();
|
||||||
|
@ -154,6 +154,7 @@ const Items = ({
|
|||||||
startUpload,
|
startUpload,
|
||||||
uploadEmptyFolders,
|
uploadEmptyFolders,
|
||||||
isVisitor,
|
isVisitor,
|
||||||
|
isCollaborator,
|
||||||
isAdmin,
|
isAdmin,
|
||||||
myId,
|
myId,
|
||||||
commonId,
|
commonId,
|
||||||
@ -169,6 +170,8 @@ const Items = ({
|
|||||||
|
|
||||||
onHide,
|
onHide,
|
||||||
firstLoad,
|
firstLoad,
|
||||||
|
deleteAction,
|
||||||
|
startDrag,
|
||||||
}) => {
|
}) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
data.forEach((elem) => {
|
data.forEach((elem) => {
|
||||||
@ -263,7 +266,12 @@ const Items = ({
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!draggableItems || draggableItems.find((x) => x.id === item.id))
|
if (
|
||||||
|
!draggableItems ||
|
||||||
|
draggableItems.find(
|
||||||
|
(x) => x.id === item.id && x.isFolder === item.isFolder
|
||||||
|
)
|
||||||
|
)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -278,7 +286,8 @@ const Items = ({
|
|||||||
(item.pathParts &&
|
(item.pathParts &&
|
||||||
(item.pathParts[0] === myId || item.pathParts[0] === commonId)) ||
|
(item.pathParts[0] === myId || item.pathParts[0] === commonId)) ||
|
||||||
item.rootFolderType === FolderType.USER ||
|
item.rootFolderType === FolderType.USER ||
|
||||||
item.rootFolderType === FolderType.COMMON
|
item.rootFolderType === FolderType.COMMON ||
|
||||||
|
(item.rootFolderType === FolderType.TRASH && startDrag)
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -306,6 +315,18 @@ const Items = ({
|
|||||||
[moveDragItems, t]
|
[moveDragItems, t]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const onRemove = React.useCallback(() => {
|
||||||
|
const translations = {
|
||||||
|
deleteOperation: t("Translations:DeleteOperation"),
|
||||||
|
deleteFromTrash: t("Translations:DeleteFromTrash"),
|
||||||
|
deleteSelectedElem: t("Translations:DeleteSelectedElem"),
|
||||||
|
FileRemoved: t("Files:FileRemoved"),
|
||||||
|
FolderRemoved: t("Files:FolderRemoved"),
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteAction(translations);
|
||||||
|
}, [deleteAction]);
|
||||||
|
|
||||||
const onEmptyTrashAction = () => {
|
const onEmptyTrashAction = () => {
|
||||||
isMobile && onHide();
|
isMobile && onHide();
|
||||||
setEmptyTrashDialogVisible(true);
|
setEmptyTrashDialogVisible(true);
|
||||||
@ -335,7 +356,7 @@ const Items = ({
|
|||||||
getEndOfBlock={getEndOfBlock}
|
getEndOfBlock={getEndOfBlock}
|
||||||
showText={showText}
|
showText={showText}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
onMoveTo={onMoveTo}
|
onMoveTo={isTrash ? onRemove : onMoveTo}
|
||||||
onBadgeClick={isTrash ? onEmptyTrashAction : onBadgeClick}
|
onBadgeClick={isTrash ? onEmptyTrashAction : onBadgeClick}
|
||||||
showDragItems={showDragItems}
|
showDragItems={showDragItems}
|
||||||
showBadge={showBadge}
|
showBadge={showBadge}
|
||||||
@ -347,7 +368,8 @@ const Items = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!firstLoad) items.splice(3, 0, <SettingsItem key="settings-item" />);
|
if (!firstLoad) items.splice(3, 0, <SettingsItem key="settings-item" />);
|
||||||
if (!isVisitor) items.splice(3, 0, <AccountsItem key="accounts-item" />);
|
if (!isVisitor && !isCollaborator)
|
||||||
|
items.splice(3, 0, <AccountsItem key="accounts-item" />);
|
||||||
|
|
||||||
if (!isVisitor) items.splice(3, 0, <CatalogDivider key="other-header" />);
|
if (!isVisitor) items.splice(3, 0, <CatalogDivider key="other-header" />);
|
||||||
else items.splice(2, 0, <CatalogDivider key="other-header" />);
|
else items.splice(2, 0, <CatalogDivider key="other-header" />);
|
||||||
@ -401,9 +423,9 @@ export default inject(
|
|||||||
selection,
|
selection,
|
||||||
dragging,
|
dragging,
|
||||||
setDragging,
|
setDragging,
|
||||||
setStartDrag,
|
|
||||||
trashIsEmpty,
|
trashIsEmpty,
|
||||||
firstLoad,
|
firstLoad,
|
||||||
|
startDrag,
|
||||||
} = filesStore;
|
} = filesStore;
|
||||||
|
|
||||||
const { startUpload } = uploadDataStore;
|
const { startUpload } = uploadDataStore;
|
||||||
@ -417,12 +439,17 @@ export default inject(
|
|||||||
} = treeFoldersStore;
|
} = treeFoldersStore;
|
||||||
|
|
||||||
const { id, pathParts, rootFolderType } = selectedFolderStore;
|
const { id, pathParts, rootFolderType } = selectedFolderStore;
|
||||||
const { moveDragItems, uploadEmptyFolders } = filesActionsStore;
|
const {
|
||||||
|
moveDragItems,
|
||||||
|
uploadEmptyFolders,
|
||||||
|
deleteAction,
|
||||||
|
} = filesActionsStore;
|
||||||
const { setEmptyTrashDialogVisible } = dialogsStore;
|
const { setEmptyTrashDialogVisible } = dialogsStore;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isAdmin: auth.isAdmin,
|
isAdmin: auth.isAdmin,
|
||||||
isVisitor: auth.userStore.user.isVisitor,
|
isVisitor: auth.userStore.user.isVisitor,
|
||||||
|
isCollaborator: auth.userStore.user.isCollaborator,
|
||||||
myId: myFolderId,
|
myId: myFolderId,
|
||||||
commonId: commonFolderId,
|
commonId: commonFolderId,
|
||||||
isPrivacy: isPrivacyFolder,
|
isPrivacy: isPrivacyFolder,
|
||||||
@ -435,14 +462,15 @@ export default inject(
|
|||||||
draggableItems: dragging ? selection : null,
|
draggableItems: dragging ? selection : null,
|
||||||
dragging,
|
dragging,
|
||||||
setDragging,
|
setDragging,
|
||||||
setStartDrag,
|
|
||||||
moveDragItems,
|
moveDragItems,
|
||||||
|
deleteAction,
|
||||||
startUpload,
|
startUpload,
|
||||||
uploadEmptyFolders,
|
uploadEmptyFolders,
|
||||||
setEmptyTrashDialogVisible,
|
setEmptyTrashDialogVisible,
|
||||||
trashIsEmpty,
|
trashIsEmpty,
|
||||||
rootFolderType,
|
rootFolderType,
|
||||||
firstLoad,
|
firstLoad,
|
||||||
|
startDrag,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
)(withTranslation(["Files", "Common", "Translations"])(observer(Items)));
|
)(withTranslation(["Files", "Common", "Translations"])(observer(Items)));
|
||||||
|
@ -50,10 +50,17 @@ const ArticleBodyContent = (props) => {
|
|||||||
|
|
||||||
const [disableBadgeClick, setDisableBadgeClick] = React.useState(false);
|
const [disableBadgeClick, setDisableBadgeClick] = React.useState(false);
|
||||||
|
|
||||||
|
let loadTimeout = null;
|
||||||
|
|
||||||
const campaigns = (localStorage.getItem("campaigns") || "")
|
const campaigns = (localStorage.getItem("campaigns") || "")
|
||||||
.split(",")
|
.split(",")
|
||||||
.filter((campaign) => campaign.length > 0);
|
.filter((campaign) => campaign.length > 0);
|
||||||
|
|
||||||
|
const cleanTimer = () => {
|
||||||
|
loadTimeout && clearTimeout(loadTimeout);
|
||||||
|
loadTimeout = null;
|
||||||
|
};
|
||||||
|
|
||||||
const onClick = React.useCallback(
|
const onClick = React.useCallback(
|
||||||
(folderId) => {
|
(folderId) => {
|
||||||
const {
|
const {
|
||||||
@ -72,7 +79,9 @@ const ArticleBodyContent = (props) => {
|
|||||||
const filesSection = window.location.pathname.indexOf("/filter") > 0;
|
const filesSection = window.location.pathname.indexOf("/filter") > 0;
|
||||||
|
|
||||||
if (filesSection) {
|
if (filesSection) {
|
||||||
setIsLoading(true);
|
loadTimeout = setTimeout(() => {
|
||||||
|
setIsLoading(true);
|
||||||
|
}, 200);
|
||||||
} else {
|
} else {
|
||||||
showLoader();
|
showLoader();
|
||||||
}
|
}
|
||||||
@ -86,54 +95,16 @@ const ArticleBodyContent = (props) => {
|
|||||||
? RoomSearchArea.Archive
|
? RoomSearchArea.Archive
|
||||||
: RoomSearchArea.Active;
|
: RoomSearchArea.Active;
|
||||||
|
|
||||||
fetchRooms(folderId, filter)
|
fetchRooms(folderId, filter).finally(() => {
|
||||||
.then(() => {
|
if (filesSection) {
|
||||||
const url = getCategoryUrl(
|
cleanTimer();
|
||||||
folderId === archiveFolderId
|
setIsLoading(false);
|
||||||
? CategoryType.Archive
|
} else {
|
||||||
: CategoryType.Shared
|
hideLoader();
|
||||||
);
|
}
|
||||||
|
});
|
||||||
const filterParamsStr = filter.toUrlParams();
|
|
||||||
|
|
||||||
history.push(
|
|
||||||
combineUrl(
|
|
||||||
window.DocSpaceConfig?.proxy?.url,
|
|
||||||
homepage,
|
|
||||||
`${url}?${filterParamsStr}`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
if (filesSection) {
|
|
||||||
setIsLoading(false);
|
|
||||||
} else {
|
|
||||||
hideLoader();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
fetchFiles(folderId, null, true, false)
|
fetchFiles(folderId, null, true, false)
|
||||||
.then(() => {
|
|
||||||
if (!filesSection) {
|
|
||||||
const filter = FilesFilter.getDefault();
|
|
||||||
|
|
||||||
filter.folder = folderId;
|
|
||||||
|
|
||||||
const filterParamsStr = filter.toUrlParams();
|
|
||||||
|
|
||||||
const url = getCategoryUrl(categoryType, filter.folder);
|
|
||||||
|
|
||||||
const pathname = `${url}?${filterParamsStr}`;
|
|
||||||
|
|
||||||
history.push(
|
|
||||||
combineUrl(
|
|
||||||
window.DocSpaceConfig?.proxy?.url,
|
|
||||||
config.homepage,
|
|
||||||
pathname
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => toastr.error(err))
|
.catch((err) => toastr.error(err))
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
if (filesSection) {
|
if (filesSection) {
|
||||||
|
@ -9,6 +9,7 @@ import ActionsPresentationReactSvgUrl from "PUBLIC_DIR/images/actions.presentati
|
|||||||
import CatalogFolderReactSvgUrl from "PUBLIC_DIR/images/catalog.folder.react.svg?url";
|
import CatalogFolderReactSvgUrl from "PUBLIC_DIR/images/catalog.folder.react.svg?url";
|
||||||
import PersonAdminReactSvgUrl from "PUBLIC_DIR/images/person.admin.react.svg?url";
|
import PersonAdminReactSvgUrl from "PUBLIC_DIR/images/person.admin.react.svg?url";
|
||||||
import PersonManagerReactSvgUrl from "PUBLIC_DIR/images/person.manager.react.svg?url";
|
import PersonManagerReactSvgUrl from "PUBLIC_DIR/images/person.manager.react.svg?url";
|
||||||
|
import PersonReactSvgUrl from "PUBLIC_DIR/images/person.react.svg?url";
|
||||||
import PersonUserReactSvgUrl from "PUBLIC_DIR/images/person.user.react.svg?url";
|
import PersonUserReactSvgUrl from "PUBLIC_DIR/images/person.user.react.svg?url";
|
||||||
import InviteAgainReactSvgUrl from "PUBLIC_DIR/images/invite.again.react.svg?url";
|
import InviteAgainReactSvgUrl from "PUBLIC_DIR/images/invite.again.react.svg?url";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
@ -29,7 +30,7 @@ import { Events, EmployeeType } from "@docspace/common/constants";
|
|||||||
import { getMainButtonItems } from "SRC_DIR/helpers/plugins";
|
import { getMainButtonItems } from "SRC_DIR/helpers/plugins";
|
||||||
|
|
||||||
import toastr from "@docspace/components/toast/toastr";
|
import toastr from "@docspace/components/toast/toastr";
|
||||||
import styled from "styled-components";
|
import styled, { css } from "styled-components";
|
||||||
import Button from "@docspace/components/button";
|
import Button from "@docspace/components/button";
|
||||||
|
|
||||||
import { resendInvitesAgain } from "@docspace/common/api/people";
|
import { resendInvitesAgain } from "@docspace/common/api/people";
|
||||||
@ -38,30 +39,36 @@ const StyledButton = styled(Button)`
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
opacity: 1;
|
opacity: ${(props) => (props.isDisabled ? 0.6 : 1)};
|
||||||
|
|
||||||
background-color: ${({ currentColorScheme }) =>
|
background-color: ${({ currentColorScheme }) =>
|
||||||
currentColorScheme.main.accent} !important;
|
currentColorScheme.main.accent} !important;
|
||||||
background: ${({ currentColorScheme }) => currentColorScheme.main.accent};
|
background: ${({ currentColorScheme }) => currentColorScheme.main.accent};
|
||||||
border: ${({ currentColorScheme }) => currentColorScheme.main.accent};
|
border: ${({ currentColorScheme }) => currentColorScheme.main.accent};
|
||||||
|
|
||||||
:hover {
|
${(props) =>
|
||||||
background-color: ${({ currentColorScheme }) =>
|
!props.isDisabled &&
|
||||||
currentColorScheme.main.accent};
|
css`
|
||||||
opacity: 0.85;
|
:hover {
|
||||||
background: ${({ currentColorScheme }) => currentColorScheme.main.accent};
|
background-color: ${({ currentColorScheme }) =>
|
||||||
border: ${({ currentColorScheme }) => currentColorScheme.main.accent};
|
currentColorScheme.main.accent};
|
||||||
}
|
opacity: 0.85;
|
||||||
|
background: ${({ currentColorScheme }) =>
|
||||||
|
currentColorScheme.main.accent};
|
||||||
|
border: ${({ currentColorScheme }) => currentColorScheme.main.accent};
|
||||||
|
}
|
||||||
|
|
||||||
:active {
|
:active {
|
||||||
background-color: ${({ currentColorScheme }) =>
|
background-color: ${({ currentColorScheme }) =>
|
||||||
currentColorScheme.main.accent};
|
currentColorScheme.main.accent};
|
||||||
background: ${({ currentColorScheme }) => currentColorScheme.main.accent};
|
background: ${({ currentColorScheme }) =>
|
||||||
border: ${({ currentColorScheme }) => currentColorScheme.main.accent};
|
currentColorScheme.main.accent};
|
||||||
opacity: 1;
|
border: ${({ currentColorScheme }) => currentColorScheme.main.accent};
|
||||||
filter: brightness(90%);
|
opacity: 1;
|
||||||
cursor: pointer;
|
filter: brightness(90%);
|
||||||
}
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
|
||||||
.button-content {
|
.button-content {
|
||||||
color: ${({ currentColorScheme }) => currentColorScheme.text.accent};
|
color: ${({ currentColorScheme }) => currentColorScheme.text.accent};
|
||||||
@ -113,6 +120,8 @@ const ArticleMainButtonContent = (props) => {
|
|||||||
setInvitePanelOptions,
|
setInvitePanelOptions,
|
||||||
|
|
||||||
mainButtonMobileVisible,
|
mainButtonMobileVisible,
|
||||||
|
|
||||||
|
security,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const isAccountsPage = selectedTreeNode[0] === "accounts";
|
const isAccountsPage = selectedTreeNode[0] === "accounts";
|
||||||
@ -297,6 +306,15 @@ const ArticleMainButtonContent = (props) => {
|
|||||||
action: EmployeeType.User,
|
action: EmployeeType.User,
|
||||||
key: "manager",
|
key: "manager",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "invite_room-collaborator",
|
||||||
|
className: "main-button_drop-down",
|
||||||
|
icon: PersonReactSvgUrl,
|
||||||
|
label: t("Common:Collaborator"),
|
||||||
|
onClick: onInvite,
|
||||||
|
action: EmployeeType.Collaborator,
|
||||||
|
key: "collaborator",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "invite_user",
|
id: "invite_user",
|
||||||
className: "main-button_drop-down",
|
className: "main-button_drop-down",
|
||||||
@ -429,26 +447,27 @@ const ArticleMainButtonContent = (props) => {
|
|||||||
? t("Common:Invite")
|
? t("Common:Invite")
|
||||||
: t("Common:Actions");
|
: t("Common:Actions");
|
||||||
|
|
||||||
const isDisabled =
|
const isDisabled = isAccountsPage ? !canInvite : !security?.Create;
|
||||||
((!canCreate || (!canCreateFiles && !isRoomsFolder)) && !canInvite) ||
|
|
||||||
isArchiveFolder;
|
|
||||||
const isProfile = history.location.pathname === "/accounts/view/@self";
|
const isProfile = history.location.pathname === "/accounts/view/@self";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isMobileArticle ? (
|
{isMobileArticle ? (
|
||||||
<>
|
<>
|
||||||
{!isArticleLoading && !isProfile && (canCreateFiles || canInvite) && (
|
{!isArticleLoading &&
|
||||||
<MobileView
|
!isProfile &&
|
||||||
t={t}
|
(security?.Create || canInvite) && (
|
||||||
titleProp={t("Upload")}
|
<MobileView
|
||||||
actionOptions={actions}
|
t={t}
|
||||||
buttonOptions={uploadActions}
|
titleProp={t("Upload")}
|
||||||
isRooms={isRoomsFolder}
|
actionOptions={actions}
|
||||||
mainButtonMobileVisible={mainButtonMobileVisible}
|
buttonOptions={uploadActions}
|
||||||
onMainButtonClick={onCreateRoom}
|
isRooms={isRoomsFolder}
|
||||||
/>
|
mainButtonMobileVisible={mainButtonMobileVisible}
|
||||||
)}
|
onMainButtonClick={onCreateRoom}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
) : isRoomsFolder ? (
|
) : isRoomsFolder ? (
|
||||||
<StyledButton
|
<StyledButton
|
||||||
@ -534,9 +553,11 @@ export default inject(
|
|||||||
|
|
||||||
const { enablePlugins, currentColorScheme } = auth.settingsStore;
|
const { enablePlugins, currentColorScheme } = auth.settingsStore;
|
||||||
|
|
||||||
|
const security = selectedFolderStore.security;
|
||||||
|
|
||||||
const currentFolderId = selectedFolderStore.id;
|
const currentFolderId = selectedFolderStore.id;
|
||||||
|
|
||||||
const { isAdmin, isOwner, isVisitor } = auth.userStore.user;
|
const { isAdmin, isOwner } = auth.userStore.user;
|
||||||
|
|
||||||
const { canCreateFiles } = accessRightsStore;
|
const { canCreateFiles } = accessRightsStore;
|
||||||
|
|
||||||
@ -572,9 +593,9 @@ export default inject(
|
|||||||
|
|
||||||
isAdmin,
|
isAdmin,
|
||||||
isOwner,
|
isOwner,
|
||||||
isVisitor,
|
|
||||||
|
|
||||||
mainButtonMobileVisible,
|
mainButtonMobileVisible,
|
||||||
|
security,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
)(
|
)(
|
||||||
|
@ -65,8 +65,10 @@ const RootFolderContainer = (props) => {
|
|||||||
isEmptyPage,
|
isEmptyPage,
|
||||||
setIsEmptyPage,
|
setIsEmptyPage,
|
||||||
isVisitor,
|
isVisitor,
|
||||||
|
isCollaborator,
|
||||||
sectionWidth,
|
sectionWidth,
|
||||||
setIsLoadedEmptyPage,
|
setIsLoadedEmptyPage,
|
||||||
|
security,
|
||||||
} = props;
|
} = props;
|
||||||
const personalDescription = t("EmptyFolderDecription");
|
const personalDescription = t("EmptyFolderDecription");
|
||||||
|
|
||||||
@ -77,12 +79,14 @@ const RootFolderContainer = (props) => {
|
|||||||
const favoritesDescription = t("FavoritesEmptyContainerDescription");
|
const favoritesDescription = t("FavoritesEmptyContainerDescription");
|
||||||
const recentDescription = t("RecentEmptyContainerDescription");
|
const recentDescription = t("RecentEmptyContainerDescription");
|
||||||
|
|
||||||
const roomsDescription = isVisitor
|
const roomsDescription =
|
||||||
? t("RoomEmptyContainerDescriptionUser")
|
isVisitor || isCollaborator
|
||||||
: t("RoomEmptyContainerDescription");
|
? t("RoomEmptyContainerDescriptionUser")
|
||||||
const archiveRoomsDescription = isVisitor
|
: t("RoomEmptyContainerDescription");
|
||||||
? t("ArchiveEmptyScreenUser")
|
const archiveRoomsDescription =
|
||||||
: t("ArchiveEmptyScreen");
|
isVisitor || isCollaborator
|
||||||
|
? t("ArchiveEmptyScreenUser")
|
||||||
|
: t("ArchiveEmptyScreen");
|
||||||
|
|
||||||
const privateRoomHeader = t("PrivateRoomHeader");
|
const privateRoomHeader = t("PrivateRoomHeader");
|
||||||
const privacyIcon = <img alt="" src={PrivacySvgUrl} />;
|
const privacyIcon = <img alt="" src={PrivacySvgUrl} />;
|
||||||
@ -201,7 +205,7 @@ const RootFolderContainer = (props) => {
|
|||||||
imageSrc: theme.isBase
|
imageSrc: theme.isBase
|
||||||
? EmptyScreenCorporateSvgUrl
|
? EmptyScreenCorporateSvgUrl
|
||||||
: EmptyScreenCorporateDarkSvgUrl,
|
: EmptyScreenCorporateDarkSvgUrl,
|
||||||
buttons: isVisitor ? null : roomsButtons,
|
buttons: !security?.Create ? null : roomsButtons,
|
||||||
};
|
};
|
||||||
case FolderType.Archive:
|
case FolderType.Archive:
|
||||||
return {
|
return {
|
||||||
@ -386,7 +390,7 @@ export default inject(
|
|||||||
setIsEmptyPage,
|
setIsEmptyPage,
|
||||||
setIsLoadedEmptyPage,
|
setIsLoadedEmptyPage,
|
||||||
} = filesStore;
|
} = filesStore;
|
||||||
const { title, rootFolderType } = selectedFolderStore;
|
const { title, rootFolderType, security } = selectedFolderStore;
|
||||||
const { isPrivacyFolder, myFolderId } = treeFoldersStore;
|
const { isPrivacyFolder, myFolderId } = treeFoldersStore;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -394,6 +398,7 @@ export default inject(
|
|||||||
isPrivacyFolder,
|
isPrivacyFolder,
|
||||||
isDesktop: isDesktopClient,
|
isDesktop: isDesktopClient,
|
||||||
isVisitor: auth.userStore.user.isVisitor,
|
isVisitor: auth.userStore.user.isVisitor,
|
||||||
|
isCollaborator: auth.userStore.user.isCollaborator,
|
||||||
isEncryptionSupport,
|
isEncryptionSupport,
|
||||||
organizationName,
|
organizationName,
|
||||||
privacyInstructions,
|
privacyInstructions,
|
||||||
@ -411,6 +416,7 @@ export default inject(
|
|||||||
isEmptyPage,
|
isEmptyPage,
|
||||||
setIsEmptyPage,
|
setIsEmptyPage,
|
||||||
setIsLoadedEmptyPage,
|
setIsLoadedEmptyPage,
|
||||||
|
security,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
)(withTranslation(["Files"])(observer(RootFolderContainer)));
|
)(withTranslation(["Files"])(observer(RootFolderContainer)));
|
||||||
|
@ -419,7 +419,7 @@ class TreeFolders extends React.Component {
|
|||||||
data: incomingDate,
|
data: incomingDate,
|
||||||
certainFolders,
|
certainFolders,
|
||||||
roomsFolderId,
|
roomsFolderId,
|
||||||
expandedPanelKeys,
|
expandedPanelKeys = [],
|
||||||
} = this.props;
|
} = this.props;
|
||||||
isExpand && this.setState({ isExpand: true });
|
isExpand && this.setState({ isExpand: true });
|
||||||
//console.log("load data...", treeNode);
|
//console.log("load data...", treeNode);
|
||||||
|
@ -15,6 +15,7 @@ const ChangeUserTypeEvent = ({
|
|||||||
peopleFilter,
|
peopleFilter,
|
||||||
updateUserType,
|
updateUserType,
|
||||||
getUsersList,
|
getUsersList,
|
||||||
|
onClose,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
toType,
|
toType,
|
||||||
@ -58,7 +59,7 @@ const ChangeUserTypeEvent = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onChangeUserType = () => {
|
const onChangeUserType = () => {
|
||||||
onClose();
|
onClosePanel();
|
||||||
updateUserType(toType, userIDs, peopleFilter, fromType)
|
updateUserType(toType, userIDs, peopleFilter, fromType)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
toastr.success(t("SuccessChangeUserType"));
|
toastr.success(t("SuccessChangeUserType"));
|
||||||
@ -83,14 +84,15 @@ const ChangeUserTypeEvent = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onClose = () => {
|
const onClosePanel = () => {
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
|
onClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCloseAction = async () => {
|
const onCloseAction = async () => {
|
||||||
await getUsersList(peopleFilter);
|
await getUsersList(peopleFilter);
|
||||||
abortCallback && abortCallback();
|
abortCallback && abortCallback();
|
||||||
onClose();
|
onClosePanel();
|
||||||
};
|
};
|
||||||
|
|
||||||
const getType = (type) => {
|
const getType = (type) => {
|
||||||
@ -99,6 +101,8 @@ const ChangeUserTypeEvent = ({
|
|||||||
return t("Common:DocSpaceAdmin");
|
return t("Common:DocSpaceAdmin");
|
||||||
case "manager":
|
case "manager":
|
||||||
return t("Common:RoomAdmin");
|
return t("Common:RoomAdmin");
|
||||||
|
case "collaborator":
|
||||||
|
return t("Common:Collaborator");
|
||||||
case "user":
|
case "user":
|
||||||
default:
|
default:
|
||||||
return t("Common:User");
|
return t("Common:User");
|
||||||
|
@ -48,7 +48,7 @@ const CreateEvent = ({
|
|||||||
|
|
||||||
setEventDialogVisible,
|
setEventDialogVisible,
|
||||||
eventDialogVisible,
|
eventDialogVisible,
|
||||||
createWithoutDialog,
|
keepNewFileName,
|
||||||
}) => {
|
}) => {
|
||||||
const [headerTitle, setHeaderTitle] = React.useState(null);
|
const [headerTitle, setHeaderTitle] = React.useState(null);
|
||||||
const [startValue, setStartValue] = React.useState("");
|
const [startValue, setStartValue] = React.useState("");
|
||||||
@ -77,7 +77,7 @@ const CreateEvent = ({
|
|||||||
|
|
||||||
if (!extension) return setEventDialogVisible(true);
|
if (!extension) return setEventDialogVisible(true);
|
||||||
|
|
||||||
if (!createWithoutDialog) {
|
if (!keepNewFileName) {
|
||||||
setEventDialogVisible(true);
|
setEventDialogVisible(true);
|
||||||
} else {
|
} else {
|
||||||
onSave(null, title || defaultName);
|
onSave(null, title || defaultName);
|
||||||
@ -289,6 +289,7 @@ export default inject(
|
|||||||
uploadDataStore,
|
uploadDataStore,
|
||||||
dialogsStore,
|
dialogsStore,
|
||||||
oformsStore,
|
oformsStore,
|
||||||
|
settingsStore,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
setIsLoading,
|
setIsLoading,
|
||||||
@ -321,7 +322,7 @@ export default inject(
|
|||||||
eventDialogVisible,
|
eventDialogVisible,
|
||||||
} = dialogsStore;
|
} = dialogsStore;
|
||||||
|
|
||||||
const { createWithoutDialog } = filesStore;
|
const { keepNewFileName } = settingsStore;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setEventDialogVisible,
|
setEventDialogVisible,
|
||||||
@ -352,7 +353,7 @@ export default inject(
|
|||||||
replaceFileStream,
|
replaceFileStream,
|
||||||
setEncryptionAccess,
|
setEncryptionAccess,
|
||||||
|
|
||||||
createWithoutDialog,
|
keepNewFileName,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
)(observer(CreateEvent));
|
)(observer(CreateEvent));
|
||||||
|
@ -22,9 +22,9 @@ const Dialog = ({
|
|||||||
onCancel,
|
onCancel,
|
||||||
onClose,
|
onClose,
|
||||||
isCreateDialog,
|
isCreateDialog,
|
||||||
createWithoutDialog,
|
|
||||||
setCreateWithoutDialog,
|
|
||||||
extension,
|
extension,
|
||||||
|
keepNewFileName,
|
||||||
|
setKeepNewFileName,
|
||||||
}) => {
|
}) => {
|
||||||
const [value, setValue] = useState("");
|
const [value, setValue] = useState("");
|
||||||
const [isDisabled, setIsDisabled] = useState(false);
|
const [isDisabled, setIsDisabled] = useState(false);
|
||||||
@ -32,8 +32,8 @@ const Dialog = ({
|
|||||||
const [isChanged, setIsChanged] = useState(false);
|
const [isChanged, setIsChanged] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
createWithoutDialog && isCreateDialog && setIsChecked(createWithoutDialog);
|
keepNewFileName && isCreateDialog && setIsChecked(keepNewFileName);
|
||||||
}, [isCreateDialog, createWithoutDialog]);
|
}, [isCreateDialog, keepNewFileName]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let input = document?.getElementById("create-text-input");
|
let input = document?.getElementById("create-text-input");
|
||||||
@ -80,7 +80,7 @@ const Dialog = ({
|
|||||||
const onSaveAction = useCallback(
|
const onSaveAction = useCallback(
|
||||||
(e) => {
|
(e) => {
|
||||||
setIsDisabled(true);
|
setIsDisabled(true);
|
||||||
isCreateDialog && setCreateWithoutDialog(isChecked);
|
isCreateDialog && setKeepNewFileName(isChecked);
|
||||||
onSave && onSave(e, value);
|
onSave && onSave(e, value);
|
||||||
},
|
},
|
||||||
[onSave, isCreateDialog, value, isChecked]
|
[onSave, isCreateDialog, value, isChecked]
|
||||||
@ -88,7 +88,7 @@ const Dialog = ({
|
|||||||
|
|
||||||
const onCancelAction = useCallback((e) => {
|
const onCancelAction = useCallback((e) => {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
setCreateWithoutDialog(false);
|
setKeepNewFileName(false);
|
||||||
}
|
}
|
||||||
onCancel && onCancel(e);
|
onCancel && onCancel(e);
|
||||||
}, []);
|
}, []);
|
||||||
@ -96,7 +96,7 @@ const Dialog = ({
|
|||||||
const onCloseAction = useCallback(
|
const onCloseAction = useCallback(
|
||||||
(e) => {
|
(e) => {
|
||||||
if (!isDisabled && isChecked) {
|
if (!isDisabled && isChecked) {
|
||||||
setCreateWithoutDialog(false);
|
setKeepNewFileName(false);
|
||||||
}
|
}
|
||||||
onClose && onClose(e);
|
onClose && onClose(e);
|
||||||
},
|
},
|
||||||
@ -171,9 +171,9 @@ const Dialog = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default inject(({ auth, filesStore }) => {
|
export default inject(({ auth, settingsStore }) => {
|
||||||
const { folderFormValidation } = auth.settingsStore;
|
const { folderFormValidation } = auth.settingsStore;
|
||||||
const { createWithoutDialog, setCreateWithoutDialog } = filesStore;
|
const { keepNewFileName, setKeepNewFileName } = settingsStore;
|
||||||
|
|
||||||
return { folderFormValidation, createWithoutDialog, setCreateWithoutDialog };
|
return { folderFormValidation, keepNewFileName, setKeepNewFileName };
|
||||||
})(observer(Dialog));
|
})(observer(Dialog));
|
||||||
|
@ -39,6 +39,8 @@ const Bar = (props) => {
|
|||||||
|
|
||||||
showRoomQuotaBar,
|
showRoomQuotaBar,
|
||||||
showStorageQuotaBar,
|
showStorageQuotaBar,
|
||||||
|
|
||||||
|
currentColorScheme,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const [barVisible, setBarVisible] = useState({
|
const [barVisible, setBarVisible] = useState({
|
||||||
@ -112,13 +114,7 @@ const Bar = (props) => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const sendActivationLinkAction = () => {
|
const sendActivationLinkAction = () => {
|
||||||
if (sendActivationLink) {
|
sendActivationLink && sendActivationLink(t);
|
||||||
sendActivationLink(t).finally(() => {
|
|
||||||
return onCloseActivationBar();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
onCloseActivationBar();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCloseActivationBar = () => {
|
const onCloseActivationBar = () => {
|
||||||
@ -183,6 +179,7 @@ const Bar = (props) => {
|
|||||||
|
|
||||||
return (isRoomQuota || isStorageQuota) && tReady ? (
|
return (isRoomQuota || isStorageQuota) && tReady ? (
|
||||||
<QuotasBar
|
<QuotasBar
|
||||||
|
currentColorScheme={currentColorScheme}
|
||||||
isRoomQuota={isRoomQuota}
|
isRoomQuota={isRoomQuota}
|
||||||
{...quotasValue}
|
{...quotasValue}
|
||||||
onClick={onClickQuota}
|
onClick={onClickQuota}
|
||||||
@ -191,6 +188,7 @@ const Bar = (props) => {
|
|||||||
/>
|
/>
|
||||||
) : withActivationBar && barVisible.confirmEmail && tReady ? (
|
) : withActivationBar && barVisible.confirmEmail && tReady ? (
|
||||||
<ConfirmEmailBar
|
<ConfirmEmailBar
|
||||||
|
currentColorScheme={currentColorScheme}
|
||||||
onLoad={onLoad}
|
onLoad={onLoad}
|
||||||
onClick={sendActivationLinkAction}
|
onClick={sendActivationLinkAction}
|
||||||
onClose={onCloseActivationBar}
|
onClose={onCloseActivationBar}
|
||||||
@ -221,6 +219,8 @@ export default inject(({ auth, profileActionsStore }) => {
|
|||||||
showStorageQuotaBar,
|
showStorageQuotaBar,
|
||||||
} = auth.currentQuotaStore;
|
} = auth.currentQuotaStore;
|
||||||
|
|
||||||
|
const { currentColorScheme } = auth.settingsStore;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isAdmin: user?.isAdmin,
|
isAdmin: user?.isAdmin,
|
||||||
withActivationBar,
|
withActivationBar,
|
||||||
@ -236,5 +236,7 @@ export default inject(({ auth, profileActionsStore }) => {
|
|||||||
|
|
||||||
showRoomQuotaBar,
|
showRoomQuotaBar,
|
||||||
showStorageQuotaBar,
|
showStorageQuotaBar,
|
||||||
|
|
||||||
|
currentColorScheme,
|
||||||
};
|
};
|
||||||
})(withTranslation(["Profile", "Common"])(withRouter(observer(Bar))));
|
})(withTranslation(["Profile", "Common"])(withRouter(observer(Bar))));
|
||||||
|
@ -11,10 +11,17 @@ const StyledLink = styled(Link)`
|
|||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
||||||
color: #316daa;
|
color: ${(props) => props.currentColorScheme.main.accent};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ConfirmEmailBar = ({ t, tReady, onClick, onClose, onLoad }) => {
|
const ConfirmEmailBar = ({
|
||||||
|
t,
|
||||||
|
tReady,
|
||||||
|
onClick,
|
||||||
|
onClose,
|
||||||
|
onLoad,
|
||||||
|
currentColorScheme,
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
tReady && (
|
tReady && (
|
||||||
<SnackBar
|
<SnackBar
|
||||||
@ -22,7 +29,12 @@ const ConfirmEmailBar = ({ t, tReady, onClick, onClose, onLoad }) => {
|
|||||||
text={
|
text={
|
||||||
<>
|
<>
|
||||||
{t("ConfirmEmailDescription")}{" "}
|
{t("ConfirmEmailDescription")}{" "}
|
||||||
<StyledLink onClick={onClick}>{t("RequestActivation")}</StyledLink>
|
<StyledLink
|
||||||
|
currentColorScheme={currentColorScheme}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
{t("RequestActivation")}
|
||||||
|
</StyledLink>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
isCampaigns={false}
|
isCampaigns={false}
|
||||||
|
@ -11,7 +11,7 @@ const StyledLink = styled(Link)`
|
|||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
||||||
color: #316daa;
|
color: ${(props) => props.currentColorScheme.main.accent};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const QuotasBar = ({
|
const QuotasBar = ({
|
||||||
@ -23,6 +23,7 @@ const QuotasBar = ({
|
|||||||
onClick,
|
onClick,
|
||||||
onClose,
|
onClose,
|
||||||
onLoad,
|
onLoad,
|
||||||
|
currentColorScheme,
|
||||||
}) => {
|
}) => {
|
||||||
const onClickAction = () => {
|
const onClickAction = () => {
|
||||||
onClick && onClick(isRoomQuota);
|
onClick && onClick(isRoomQuota);
|
||||||
@ -37,7 +38,10 @@ const QuotasBar = ({
|
|||||||
description: (
|
description: (
|
||||||
<Trans i18nKey="RoomQuotaDescription" t={t}>
|
<Trans i18nKey="RoomQuotaDescription" t={t}>
|
||||||
You can archived the unnecessary rooms or
|
You can archived the unnecessary rooms or
|
||||||
<StyledLink onClick={onClickAction}>
|
<StyledLink
|
||||||
|
currentColorScheme={currentColorScheme}
|
||||||
|
onClick={onClickAction}
|
||||||
|
>
|
||||||
{{ clickHere: t("ClickHere") }}
|
{{ clickHere: t("ClickHere") }}
|
||||||
</StyledLink>{" "}
|
</StyledLink>{" "}
|
||||||
to find a better pricing plan for your portal.
|
to find a better pricing plan for your portal.
|
||||||
@ -50,7 +54,10 @@ const QuotasBar = ({
|
|||||||
description: (
|
description: (
|
||||||
<Trans i18nKey="StorageQuotaDescription" t={t}>
|
<Trans i18nKey="StorageQuotaDescription" t={t}>
|
||||||
You can remove the unnecessary files or{" "}
|
You can remove the unnecessary files or{" "}
|
||||||
<StyledLink onClick={onClickAction}>
|
<StyledLink
|
||||||
|
currentColorScheme={currentColorScheme}
|
||||||
|
onClick={onClickAction}
|
||||||
|
>
|
||||||
{{ clickHere: t("ClickHere") }}
|
{{ clickHere: t("ClickHere") }}
|
||||||
</StyledLink>{" "}
|
</StyledLink>{" "}
|
||||||
to find a better pricing plan for your portal.
|
to find a better pricing plan for your portal.
|
||||||
|
@ -85,7 +85,18 @@ const PeopleSelector = ({
|
|||||||
}, [isLoading]);
|
}, [isLoading]);
|
||||||
|
|
||||||
const toListItem = (item) => {
|
const toListItem = (item) => {
|
||||||
const { id, email, avatar, icon, displayName, hasAvatar } = item;
|
const {
|
||||||
|
id,
|
||||||
|
email,
|
||||||
|
avatar,
|
||||||
|
icon,
|
||||||
|
displayName,
|
||||||
|
hasAvatar,
|
||||||
|
isOwner,
|
||||||
|
isAdmin,
|
||||||
|
isVisitor,
|
||||||
|
isCollaborator,
|
||||||
|
} = item;
|
||||||
|
|
||||||
const role = getUserRole(item);
|
const role = getUserRole(item);
|
||||||
|
|
||||||
@ -98,6 +109,10 @@ const PeopleSelector = ({
|
|||||||
icon,
|
icon,
|
||||||
label: displayName || email,
|
label: displayName || email,
|
||||||
role,
|
role,
|
||||||
|
isOwner,
|
||||||
|
isAdmin,
|
||||||
|
isVisitor,
|
||||||
|
isCollaborator,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,8 +79,6 @@ const AvatarEditorDialog = (props) => {
|
|||||||
const avatars = await createThumbnailsAvatar(profile.id, {
|
const avatars = await createThumbnailsAvatar(profile.id, {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: 192,
|
|
||||||
height: 192,
|
|
||||||
tmpFile: res.data,
|
tmpFile: res.data,
|
||||||
});
|
});
|
||||||
updateCreatedAvatar(avatars);
|
updateCreatedAvatar(avatars);
|
||||||
|
@ -14,10 +14,11 @@ class ResetApplicationDialogComponent extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resetApp = async () => {
|
resetApp = async () => {
|
||||||
const { resetTfaApp, id, onClose, history } = this.props;
|
const { t, resetTfaApp, id, onClose, history } = this.props;
|
||||||
onClose && onClose();
|
onClose && onClose();
|
||||||
try {
|
try {
|
||||||
const res = await resetTfaApp(id);
|
const res = await resetTfaApp(id);
|
||||||
|
toastr.success(t("SuccessResetApplication"));
|
||||||
if (res) history.push(res.replace(window.location.origin, ""));
|
if (res) history.push(res.replace(window.location.origin, ""));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toastr.error(e);
|
toastr.error(e);
|
||||||
|
@ -62,12 +62,19 @@ const AddUsersPanel = ({
|
|||||||
const currentItem = shareDataItems.find((x) => x.sharedTo.id === item.id);
|
const currentItem = shareDataItems.find((x) => x.sharedTo.id === item.id);
|
||||||
|
|
||||||
if (!currentItem) {
|
if (!currentItem) {
|
||||||
|
const currentAccess =
|
||||||
|
item.isOwner || item.isAdmin
|
||||||
|
? ShareAccessRights.RoomManager
|
||||||
|
: access.access;
|
||||||
|
|
||||||
const newItem = {
|
const newItem = {
|
||||||
access: access.access,
|
access: currentAccess,
|
||||||
email: item.email,
|
email: item.email,
|
||||||
id: item.id,
|
id: item.id,
|
||||||
displayName: item.label,
|
displayName: item.label,
|
||||||
avatar: item.avatar,
|
avatar: item.avatar,
|
||||||
|
isOwner: item.isOwner,
|
||||||
|
isAdmin: item.isAdmin,
|
||||||
};
|
};
|
||||||
items.push(newItem);
|
items.push(newItem);
|
||||||
}
|
}
|
||||||
|
@ -35,12 +35,15 @@ const InvitePanel = ({
|
|||||||
userLink,
|
userLink,
|
||||||
guestLink,
|
guestLink,
|
||||||
adminLink,
|
adminLink,
|
||||||
|
collaboratorLink,
|
||||||
defaultAccess,
|
defaultAccess,
|
||||||
inviteUsers,
|
inviteUsers,
|
||||||
setInfoPanelIsMobileHidden,
|
setInfoPanelIsMobileHidden,
|
||||||
reloadSelectionParentRoom,
|
reloadSelectionParentRoom,
|
||||||
setUpdateRoomMembers,
|
setUpdateRoomMembers,
|
||||||
roomsView,
|
roomsView,
|
||||||
|
getUsersList,
|
||||||
|
filter,
|
||||||
}) => {
|
}) => {
|
||||||
const [selectedRoom, setSelectedRoom] = useState(null);
|
const [selectedRoom, setSelectedRoom] = useState(null);
|
||||||
const [hasErrors, setHasErrors] = useState(false);
|
const [hasErrors, setHasErrors] = useState(false);
|
||||||
@ -85,7 +88,8 @@ const InvitePanel = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (roomId === -1) {
|
if (roomId === -1) {
|
||||||
if (!userLink || !guestLink || !adminLink) getPortalInviteLinks();
|
if (!userLink || !guestLink || !adminLink || !collaboratorLink)
|
||||||
|
getPortalInviteLinks();
|
||||||
|
|
||||||
setShareLinks([
|
setShareLinks([
|
||||||
{
|
{
|
||||||
@ -106,6 +110,12 @@ const InvitePanel = ({
|
|||||||
shareLink: adminLink,
|
shareLink: adminLink,
|
||||||
access: 3,
|
access: 3,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "collaborator",
|
||||||
|
title: "Collaborator",
|
||||||
|
shareLink: collaboratorLink,
|
||||||
|
access: 4,
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -113,7 +123,7 @@ const InvitePanel = ({
|
|||||||
|
|
||||||
selectRoom();
|
selectRoom();
|
||||||
getInfo();
|
getInfo();
|
||||||
}, [roomId, userLink, guestLink, adminLink]);
|
}, [roomId, userLink, guestLink, adminLink, collaboratorLink]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const hasErrors = inviteItems.some((item) => !!item.errors?.length);
|
const hasErrors = inviteItems.some((item) => !!item.errors?.length);
|
||||||
@ -178,6 +188,10 @@ const InvitePanel = ({
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
toastr.error(err);
|
toastr.error(err);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
} finally {
|
||||||
|
if (roomId === -1) {
|
||||||
|
await getUsersList(filter , false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -261,7 +275,8 @@ const InvitePanel = ({
|
|||||||
export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
|
export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
|
||||||
const { theme } = auth.settingsStore;
|
const { theme } = auth.settingsStore;
|
||||||
|
|
||||||
const { getUsersByQuery, inviteUsers } = peopleStore.usersStore;
|
const { getUsersByQuery, inviteUsers, getUsersList } = peopleStore.usersStore;
|
||||||
|
const { filter } = peopleStore.filterStore;
|
||||||
const {
|
const {
|
||||||
setIsMobileHidden: setInfoPanelIsMobileHidden,
|
setIsMobileHidden: setInfoPanelIsMobileHidden,
|
||||||
reloadSelectionParentRoom,
|
reloadSelectionParentRoom,
|
||||||
@ -275,6 +290,7 @@ export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
|
|||||||
userLink,
|
userLink,
|
||||||
guestLink,
|
guestLink,
|
||||||
adminLink,
|
adminLink,
|
||||||
|
collaboratorLink,
|
||||||
} = peopleStore.inviteLinksStore;
|
} = peopleStore.inviteLinksStore;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -308,11 +324,14 @@ export default inject(({ auth, peopleStore, filesStore, dialogsStore }) => {
|
|||||||
userLink,
|
userLink,
|
||||||
guestLink,
|
guestLink,
|
||||||
adminLink,
|
adminLink,
|
||||||
|
collaboratorLink,
|
||||||
inviteUsers,
|
inviteUsers,
|
||||||
setInfoPanelIsMobileHidden,
|
setInfoPanelIsMobileHidden,
|
||||||
reloadSelectionParentRoom,
|
reloadSelectionParentRoom,
|
||||||
setUpdateRoomMembers,
|
setUpdateRoomMembers,
|
||||||
roomsView,
|
roomsView,
|
||||||
|
getUsersList,
|
||||||
|
filter,
|
||||||
};
|
};
|
||||||
})(
|
})(
|
||||||
withTranslation([
|
withTranslation([
|
||||||
|
@ -16,6 +16,7 @@ import {
|
|||||||
StyledDeleteIcon,
|
StyledDeleteIcon,
|
||||||
StyledText,
|
StyledText,
|
||||||
} from "../StyledInvitePanel";
|
} from "../StyledInvitePanel";
|
||||||
|
import { filterUserRoleOptions } from "SRC_DIR/helpers/utils";
|
||||||
|
|
||||||
const Item = ({
|
const Item = ({
|
||||||
t,
|
t,
|
||||||
@ -38,7 +39,11 @@ const Item = ({
|
|||||||
|
|
||||||
const accesses = getAccessOptions(t, roomType, true, false, isOwner);
|
const accesses = getAccessOptions(t, roomType, true, false, isOwner);
|
||||||
|
|
||||||
const defaultAccess = accesses.find((option) => option.access === +access);
|
const filteredAccesses = filterUserRoleOptions(accesses, item, true);
|
||||||
|
|
||||||
|
const defaultAccess = filteredAccesses.find(
|
||||||
|
(option) => option.access === +access
|
||||||
|
);
|
||||||
|
|
||||||
const errorsInList = () => {
|
const errorsInList = () => {
|
||||||
const hasErrors = inviteItems.some((item) => !!item.errors?.length);
|
const hasErrors = inviteItems.some((item) => !!item.errors?.length);
|
||||||
@ -128,7 +133,7 @@ const Item = ({
|
|||||||
<StyledComboBox
|
<StyledComboBox
|
||||||
onSelect={selectItemAccess}
|
onSelect={selectItemAccess}
|
||||||
noBorder
|
noBorder
|
||||||
options={accesses}
|
options={filteredAccesses}
|
||||||
size="content"
|
size="content"
|
||||||
scaled={false}
|
scaled={false}
|
||||||
manualWidth="fit-content"
|
manualWidth="fit-content"
|
||||||
|
@ -31,6 +31,17 @@ export const getAccessOptions = (
|
|||||||
access:
|
access:
|
||||||
roomType === -1 ? EmployeeType.User : ShareAccessRights.RoomManager,
|
roomType === -1 ? EmployeeType.User : ShareAccessRights.RoomManager,
|
||||||
},
|
},
|
||||||
|
collaborator: {
|
||||||
|
key: "collaborator",
|
||||||
|
label: t("Common:Collaborator"),
|
||||||
|
description: t("Translations:RoleCollaboratorDescription"),
|
||||||
|
quota: t("Common:Paid"),
|
||||||
|
color: "#EDC409",
|
||||||
|
access:
|
||||||
|
roomType === -1
|
||||||
|
? EmployeeType.Collaborator
|
||||||
|
: ShareAccessRights.Collaborator,
|
||||||
|
},
|
||||||
user: {
|
user: {
|
||||||
key: "user",
|
key: "user",
|
||||||
label: t("Common:User"),
|
label: t("Common:User"),
|
||||||
@ -73,6 +84,7 @@ export const getAccessOptions = (
|
|||||||
case RoomsType.FillingFormsRoom:
|
case RoomsType.FillingFormsRoom:
|
||||||
options = [
|
options = [
|
||||||
accesses.roomAdmin,
|
accesses.roomAdmin,
|
||||||
|
accesses.collaborator,
|
||||||
{ key: "s1", isSeparator: withSeparator },
|
{ key: "s1", isSeparator: withSeparator },
|
||||||
accesses.formFiller,
|
accesses.formFiller,
|
||||||
accesses.viewer,
|
accesses.viewer,
|
||||||
@ -81,6 +93,7 @@ export const getAccessOptions = (
|
|||||||
case RoomsType.EditingRoom:
|
case RoomsType.EditingRoom:
|
||||||
options = [
|
options = [
|
||||||
accesses.roomAdmin,
|
accesses.roomAdmin,
|
||||||
|
accesses.collaborator,
|
||||||
{ key: "s1", isSeparator: withSeparator },
|
{ key: "s1", isSeparator: withSeparator },
|
||||||
accesses.editor,
|
accesses.editor,
|
||||||
accesses.viewer,
|
accesses.viewer,
|
||||||
@ -89,6 +102,7 @@ export const getAccessOptions = (
|
|||||||
case RoomsType.ReviewRoom:
|
case RoomsType.ReviewRoom:
|
||||||
options = [
|
options = [
|
||||||
accesses.roomAdmin,
|
accesses.roomAdmin,
|
||||||
|
accesses.collaborator,
|
||||||
{ key: "s1", isSeparator: withSeparator },
|
{ key: "s1", isSeparator: withSeparator },
|
||||||
accesses.reviewer,
|
accesses.reviewer,
|
||||||
accesses.commentator,
|
accesses.commentator,
|
||||||
@ -98,6 +112,7 @@ export const getAccessOptions = (
|
|||||||
case RoomsType.ReadOnlyRoom:
|
case RoomsType.ReadOnlyRoom:
|
||||||
options = [
|
options = [
|
||||||
accesses.roomAdmin,
|
accesses.roomAdmin,
|
||||||
|
accesses.collaborator,
|
||||||
{ key: "s1", isSeparator: withSeparator },
|
{ key: "s1", isSeparator: withSeparator },
|
||||||
accesses.viewer,
|
accesses.viewer,
|
||||||
];
|
];
|
||||||
@ -105,6 +120,7 @@ export const getAccessOptions = (
|
|||||||
case RoomsType.CustomRoom:
|
case RoomsType.CustomRoom:
|
||||||
options = [
|
options = [
|
||||||
accesses.roomAdmin,
|
accesses.roomAdmin,
|
||||||
|
accesses.collaborator,
|
||||||
{ key: "s1", isSeparator: withSeparator },
|
{ key: "s1", isSeparator: withSeparator },
|
||||||
accesses.editor,
|
accesses.editor,
|
||||||
accesses.formFiller,
|
accesses.formFiller,
|
||||||
@ -119,6 +135,7 @@ export const getAccessOptions = (
|
|||||||
options = [
|
options = [
|
||||||
...options,
|
...options,
|
||||||
accesses.roomAdmin,
|
accesses.roomAdmin,
|
||||||
|
accesses.collaborator,
|
||||||
{ key: "s1", isSeparator: withSeparator },
|
{ key: "s1", isSeparator: withSeparator },
|
||||||
accesses.user,
|
accesses.user,
|
||||||
];
|
];
|
||||||
|
@ -7,7 +7,6 @@ import toastr from "@docspace/components/toast/toastr";
|
|||||||
import SelectFolderDialog from "../SelectFolderDialog";
|
import SelectFolderDialog from "../SelectFolderDialog";
|
||||||
import SimpleFileInput from "../../SimpleFileInput";
|
import SimpleFileInput from "../../SimpleFileInput";
|
||||||
import { withTranslation } from "react-i18next";
|
import { withTranslation } from "react-i18next";
|
||||||
import SelectionPanel from "../SelectionPanel/SelectionPanelBody";
|
|
||||||
import { FolderType } from "@docspace/common/constants";
|
import { FolderType } from "@docspace/common/constants";
|
||||||
class SelectFolderInput extends React.PureComponent {
|
class SelectFolderInput extends React.PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -113,7 +112,7 @@ class SelectFolderInput extends React.PureComponent {
|
|||||||
onSelect && onSelect(folderId);
|
onSelect && onSelect(folderId);
|
||||||
};
|
};
|
||||||
onSetFolderInfo = (folderId) => {
|
onSetFolderInfo = (folderId) => {
|
||||||
const { setExpandedPanelKeys, setParentId } = this.props;
|
const { setExpandedPanelKeys, setParentId, clearLocalStorage } = this.props;
|
||||||
|
|
||||||
getFolder(folderId)
|
getFolder(folderId)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
@ -123,7 +122,10 @@ class SelectFolderInput extends React.PureComponent {
|
|||||||
setExpandedPanelKeys(pathParts);
|
setExpandedPanelKeys(pathParts);
|
||||||
setParentId(data.current.parentId);
|
setParentId(data.current.parentId);
|
||||||
})
|
})
|
||||||
.catch((e) => toastr.error(e));
|
.catch((e) => {
|
||||||
|
toastr.error(e);
|
||||||
|
clearLocalStorage();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -201,7 +203,9 @@ export default inject(
|
|||||||
treeFoldersStore,
|
treeFoldersStore,
|
||||||
selectFolderDialogStore,
|
selectFolderDialogStore,
|
||||||
selectedFolderStore,
|
selectedFolderStore,
|
||||||
|
backup,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { clearLocalStorage } = backup;
|
||||||
const { setFirstLoad } = filesStore;
|
const { setFirstLoad } = filesStore;
|
||||||
const { setExpandedPanelKeys } = treeFoldersStore;
|
const { setExpandedPanelKeys } = treeFoldersStore;
|
||||||
const {
|
const {
|
||||||
@ -220,6 +224,7 @@ export default inject(
|
|||||||
const { setParentId } = selectedFolderStore;
|
const { setParentId } = selectedFolderStore;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
clearLocalStorage,
|
||||||
setFirstLoad,
|
setFirstLoad,
|
||||||
setExpandedPanelKeys,
|
setExpandedPanelKeys,
|
||||||
setParentId,
|
setParentId,
|
||||||
|
@ -12,9 +12,6 @@ import ActionsUploadedFile from "./SubComponents/ActionsUploadedFile";
|
|||||||
import { isMobile } from "react-device-detect";
|
import { isMobile } from "react-device-detect";
|
||||||
import NoUserSelect from "@docspace/components/utils/commonStyles";
|
import NoUserSelect from "@docspace/components/utils/commonStyles";
|
||||||
import Button from "@docspace/components/button";
|
import Button from "@docspace/components/button";
|
||||||
import globalColors from "@docspace/components/utils/globalColors";
|
|
||||||
|
|
||||||
const buttonColor = globalColors.blueDisabled;
|
|
||||||
|
|
||||||
const StyledFileRow = styled(Row)`
|
const StyledFileRow = styled(Row)`
|
||||||
width: calc(100% - 16px);
|
width: calc(100% - 16px);
|
||||||
@ -145,11 +142,11 @@ class FileRow extends Component {
|
|||||||
onCancelCurrentUpload = (e) => {
|
onCancelCurrentUpload = (e) => {
|
||||||
//console.log("cancel upload ", e);
|
//console.log("cancel upload ", e);
|
||||||
const { id, action, fileId } = e.currentTarget.dataset;
|
const { id, action, fileId } = e.currentTarget.dataset;
|
||||||
const { cancelCurrentUpload, cancelCurrentFileConversion } = this.props;
|
const { t, cancelCurrentUpload, cancelCurrentFileConversion } = this.props;
|
||||||
|
|
||||||
return action === "convert"
|
return action === "convert"
|
||||||
? cancelCurrentFileConversion(fileId)
|
? cancelCurrentFileConversion(fileId)
|
||||||
: cancelCurrentUpload(id);
|
: cancelCurrentUpload(id, t);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMediaClick = (id) => {
|
onMediaClick = (id) => {
|
||||||
@ -228,8 +225,6 @@ class FileRow extends Component {
|
|||||||
t,
|
t,
|
||||||
item,
|
item,
|
||||||
uploaded,
|
uploaded,
|
||||||
//onMediaClick,
|
|
||||||
currentFileUploadProgress,
|
|
||||||
fileIcon,
|
fileIcon,
|
||||||
isMedia,
|
isMedia,
|
||||||
ext,
|
ext,
|
||||||
@ -314,7 +309,7 @@ class FileRow extends Component {
|
|||||||
data-id={item.uniqueId}
|
data-id={item.uniqueId}
|
||||||
onClick={this.onCancelCurrentUpload}
|
onClick={this.onCancelCurrentUpload}
|
||||||
>
|
>
|
||||||
<LoadingButton percent={currentFileUploadProgress} />
|
<LoadingButton item={item} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{showPasswordInput && (
|
{showPasswordInput && (
|
||||||
@ -365,7 +360,6 @@ export default inject(
|
|||||||
const { canViewedDocs, getIconSrc, isArchive } = settingsStore;
|
const { canViewedDocs, getIconSrc, isArchive } = settingsStore;
|
||||||
const {
|
const {
|
||||||
uploaded,
|
uploaded,
|
||||||
primaryProgressDataStore,
|
|
||||||
cancelCurrentUpload,
|
cancelCurrentUpload,
|
||||||
cancelCurrentFileConversion,
|
cancelCurrentFileConversion,
|
||||||
setUploadPanelVisible,
|
setUploadPanelVisible,
|
||||||
@ -379,7 +373,6 @@ export default inject(
|
|||||||
setMediaViewerData,
|
setMediaViewerData,
|
||||||
setCurrentItem,
|
setCurrentItem,
|
||||||
} = mediaViewerDataStore;
|
} = mediaViewerDataStore;
|
||||||
const { loadingFile: file } = primaryProgressDataStore;
|
|
||||||
|
|
||||||
const isMedia =
|
const isMedia =
|
||||||
item.fileInfo?.viewAccessability?.ImageView ||
|
item.fileInfo?.viewAccessability?.ImageView ||
|
||||||
@ -390,25 +383,16 @@ export default inject(
|
|||||||
|
|
||||||
const fileIcon = getIconSrc(ext, 24);
|
const fileIcon = getIconSrc(ext, 24);
|
||||||
|
|
||||||
const loadingFile = !file || !file.uniqueId ? null : file;
|
|
||||||
|
|
||||||
const currentFileUploadProgress =
|
|
||||||
file && loadingFile.uniqueId === item.uniqueId
|
|
||||||
? loadingFile.percent
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const downloadInCurrentTab = isArchive(ext) || !canViewedDocs(ext);
|
const downloadInCurrentTab = isArchive(ext) || !canViewedDocs(ext);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isPersonal: personal,
|
isPersonal: personal,
|
||||||
theme,
|
theme,
|
||||||
currentFileUploadProgress,
|
|
||||||
uploaded,
|
uploaded,
|
||||||
isMedia,
|
isMedia: !!isMedia,
|
||||||
fileIcon,
|
fileIcon,
|
||||||
ext,
|
ext,
|
||||||
name,
|
name,
|
||||||
loadingFile,
|
|
||||||
isMediaActive,
|
isMediaActive,
|
||||||
downloadInCurrentTab,
|
downloadInCurrentTab,
|
||||||
removeFileFromList,
|
removeFileFromList,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { inject, observer } from "mobx-react";
|
||||||
import {
|
import {
|
||||||
StyledCircle,
|
StyledCircle,
|
||||||
StyledCircleWrap,
|
|
||||||
StyledLoadingButton,
|
StyledLoadingButton,
|
||||||
} from "@docspace/common/components/StyledLoadingButton";
|
} from "@docspace/common/components/StyledLoadingButton";
|
||||||
|
|
||||||
@ -16,7 +16,6 @@ const LoadingButton = (props) => {
|
|||||||
onClick,
|
onClick,
|
||||||
isConversion,
|
isConversion,
|
||||||
inConversion,
|
inConversion,
|
||||||
...rest
|
|
||||||
} = props;
|
} = props;
|
||||||
const [isAnimation, setIsAnimation] = useState(true);
|
const [isAnimation, setIsAnimation] = useState(true);
|
||||||
|
|
||||||
@ -61,4 +60,22 @@ const LoadingButton = (props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LoadingButton;
|
export default inject(({ uploadDataStore }, { item }) => {
|
||||||
|
const { primaryProgressDataStore, isParallel } = uploadDataStore;
|
||||||
|
const { loadingFile: file } = primaryProgressDataStore;
|
||||||
|
|
||||||
|
const loadingFile = !file || !file.uniqueId ? null : file;
|
||||||
|
|
||||||
|
const currentFileUploadProgress =
|
||||||
|
file && loadingFile?.uniqueId === item?.uniqueId
|
||||||
|
? loadingFile.percent
|
||||||
|
: null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
percent: isParallel
|
||||||
|
? item?.percent
|
||||||
|
? item.percent
|
||||||
|
: null
|
||||||
|
: currentFileUploadProgress,
|
||||||
|
};
|
||||||
|
})(observer(LoadingButton));
|
||||||
|
@ -18,7 +18,7 @@ class ConfirmRoute extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { forUnauthorized, history, isAuthenticated } = this.props;
|
const { forUnauthorized, isAuthenticated } = this.props;
|
||||||
|
|
||||||
if (forUnauthorized && isAuthenticated) {
|
if (forUnauthorized && isAuthenticated) {
|
||||||
this.props.logout();
|
this.props.logout();
|
||||||
@ -42,18 +42,25 @@ class ConfirmRoute extends React.Component {
|
|||||||
.then((validationResult) => {
|
.then((validationResult) => {
|
||||||
switch (validationResult) {
|
switch (validationResult) {
|
||||||
case ValidationResult.Ok:
|
case ValidationResult.Ok:
|
||||||
const confirmHeader = `${confirmLinkData}&${search.slice(1)}`;
|
const confirmHeader = search.slice(1);
|
||||||
const linkData = {
|
const linkData = {
|
||||||
...confirmLinkData,
|
...confirmLinkData,
|
||||||
confirmHeader,
|
confirmHeader,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log("checkConfirmLink", {
|
||||||
|
confirmLinkData,
|
||||||
|
validationResult,
|
||||||
|
linkData,
|
||||||
|
});
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isLoaded: true,
|
isLoaded: true,
|
||||||
linkData,
|
linkData,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case ValidationResult.Invalid:
|
case ValidationResult.Invalid:
|
||||||
console.error("invlid link");
|
console.error("invlid link", { confirmLinkData, validationResult });
|
||||||
window.location.href = combineUrl(
|
window.location.href = combineUrl(
|
||||||
window.DocSpaceConfig?.proxy?.url,
|
window.DocSpaceConfig?.proxy?.url,
|
||||||
path,
|
path,
|
||||||
@ -61,7 +68,10 @@ class ConfirmRoute extends React.Component {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case ValidationResult.Expired:
|
case ValidationResult.Expired:
|
||||||
console.error("expired link");
|
console.error("expired link", {
|
||||||
|
confirmLinkData,
|
||||||
|
validationResult,
|
||||||
|
});
|
||||||
window.location.href = combineUrl(
|
window.location.href = combineUrl(
|
||||||
window.DocSpaceConfig?.proxy?.url,
|
window.DocSpaceConfig?.proxy?.url,
|
||||||
path,
|
path,
|
||||||
@ -69,7 +79,10 @@ class ConfirmRoute extends React.Component {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.error("unknown link");
|
console.error("unknown link", {
|
||||||
|
confirmLinkData,
|
||||||
|
validationResult,
|
||||||
|
});
|
||||||
window.location.href = combineUrl(
|
window.location.href = combineUrl(
|
||||||
window.DocSpaceConfig?.proxy?.url,
|
window.DocSpaceConfig?.proxy?.url,
|
||||||
path,
|
path,
|
||||||
@ -79,7 +92,7 @@ class ConfirmRoute extends React.Component {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error("FAILED checkConfirmLink", { error, confirmLinkData });
|
||||||
window.location.href = combineUrl(
|
window.location.href = combineUrl(
|
||||||
window.DocSpaceConfig?.proxy?.url,
|
window.DocSpaceConfig?.proxy?.url,
|
||||||
path,
|
path,
|
||||||
|
@ -51,6 +51,8 @@ export const CategoryType = Object.freeze({
|
|||||||
Favorite: 5,
|
Favorite: 5,
|
||||||
Recent: 6,
|
Recent: 6,
|
||||||
Trash: 7,
|
Trash: 7,
|
||||||
|
Settings: 8,
|
||||||
|
Accounts: 9,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,8 +40,9 @@ export const getAccessIcon = (access) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getTitleWithoutExst = (item, fromTemplate) => {
|
export const getTitleWithoutExst = (item, fromTemplate) => {
|
||||||
return item.fileExst && !fromTemplate
|
const titleWithoutExst = item.title.split(".").slice(0, -1).join(".");
|
||||||
? item.title.split(".").slice(0, -1).join(".")
|
return titleWithoutExst && item.fileExst && !fromTemplate
|
||||||
|
? titleWithoutExst
|
||||||
: item.title;
|
: item.title;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,26 +10,3 @@ export const thumbnailStatuses = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const ADS_TIMEOUT = 300000; // 5 min
|
export const ADS_TIMEOUT = 300000; // 5 min
|
||||||
|
|
||||||
export const FilterGroups = Object.freeze({
|
|
||||||
filterType: "filter-filterType",
|
|
||||||
filterAuthor: "filter-author",
|
|
||||||
filterFolders: "filter-folders",
|
|
||||||
filterContent: "filter-withContent",
|
|
||||||
roomFilterProviderType: "filter-provider-type",
|
|
||||||
roomFilterType: "filter-type",
|
|
||||||
roomFilterSubject: "filter-subject",
|
|
||||||
roomFilterOwner: "filter-owner",
|
|
||||||
roomFilterTags: "filter-tags",
|
|
||||||
roomFilterFolders: "filter-withSubfolders",
|
|
||||||
roomFilterContent: "filter-content",
|
|
||||||
});
|
|
||||||
|
|
||||||
export const FilterKeys = Object.freeze({
|
|
||||||
withSubfolders: "withSubfolders",
|
|
||||||
excludeSubfolders: "excludeSubfolders",
|
|
||||||
withContent: "withContent",
|
|
||||||
me: "me",
|
|
||||||
other: "other",
|
|
||||||
user: "user",
|
|
||||||
});
|
|
||||||
|
@ -2,7 +2,7 @@ import authStore from "@docspace/common/store/AuthStore";
|
|||||||
import { toCommunityHostname, getLanguage } from "@docspace/common/utils";
|
import { toCommunityHostname, getLanguage } from "@docspace/common/utils";
|
||||||
import history from "@docspace/common/history";
|
import history from "@docspace/common/history";
|
||||||
import { CategoryType } from "./constants";
|
import { CategoryType } from "./constants";
|
||||||
import { FolderType } from "@docspace/common/constants";
|
import { FolderType, ShareAccessRights } from "@docspace/common/constants";
|
||||||
import { translations } from "./autoGeneratedTranslations";
|
import { translations } from "./autoGeneratedTranslations";
|
||||||
|
|
||||||
export const setDocumentTitle = (subTitle = null) => {
|
export const setDocumentTitle = (subTitle = null) => {
|
||||||
@ -125,8 +125,12 @@ export const getCategoryType = (location) => {
|
|||||||
categoryType = CategoryType.Favorite;
|
categoryType = CategoryType.Favorite;
|
||||||
} else if (pathname.startsWith("/recent")) {
|
} else if (pathname.startsWith("/recent")) {
|
||||||
categoryType = CategoryType.Recent;
|
categoryType = CategoryType.Recent;
|
||||||
} else if (pathname.startsWith("/trash")) {
|
} else if (pathname.startsWith("/files/trash")) {
|
||||||
categoryType = CategoryType.Trash;
|
categoryType = CategoryType.Trash;
|
||||||
|
} else if (pathname.startsWith("/settings")) {
|
||||||
|
categoryType = CategoryType.Settings;
|
||||||
|
} else if (pathname.startsWith("/accounts/filter")) {
|
||||||
|
categoryType = CategoryType.Accounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
return categoryType;
|
return categoryType;
|
||||||
@ -186,3 +190,24 @@ export const getCategoryUrl = (categoryType, folderId = null) => {
|
|||||||
throw new Error("Unknown category type");
|
throw new Error("Unknown category type");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const filterUserRoleOptions = (
|
||||||
|
options,
|
||||||
|
currentUser,
|
||||||
|
withRemove = false
|
||||||
|
) => {
|
||||||
|
let newOptions = [...options];
|
||||||
|
|
||||||
|
if (currentUser?.isAdmin || currentUser?.isOwner) {
|
||||||
|
newOptions = newOptions.filter(
|
||||||
|
(o) =>
|
||||||
|
+o.access === ShareAccessRights.RoomManager ||
|
||||||
|
+o.access === ShareAccessRights.None ||
|
||||||
|
(withRemove && (o.key === "s2" || o.key === "remove"))
|
||||||
|
);
|
||||||
|
|
||||||
|
return newOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newOptions;
|
||||||
|
};
|
||||||
|
@ -20,6 +20,7 @@ const PeopleSection = React.memo(() => {
|
|||||||
<PrivateRoute exact path={["/accounts/view/@self"]} component={Profile} />
|
<PrivateRoute exact path={["/accounts/view/@self"]} component={Profile} />
|
||||||
<PrivateRoute
|
<PrivateRoute
|
||||||
exact
|
exact
|
||||||
|
withManager
|
||||||
path={["/accounts"]}
|
path={["/accounts"]}
|
||||||
component={HomeRedirectToFilter}
|
component={HomeRedirectToFilter}
|
||||||
/>
|
/>
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
SendInviteDialog,
|
SendInviteDialog,
|
||||||
DeleteUsersDialog,
|
DeleteUsersDialog,
|
||||||
ChangeNameDialog,
|
ChangeNameDialog,
|
||||||
|
ResetApplicationDialog,
|
||||||
} from "SRC_DIR/components/dialogs";
|
} from "SRC_DIR/components/dialogs";
|
||||||
|
|
||||||
const Dialogs = ({
|
const Dialogs = ({
|
||||||
@ -28,10 +29,12 @@ const Dialogs = ({
|
|||||||
disableDialogVisible,
|
disableDialogVisible,
|
||||||
sendInviteDialogVisible,
|
sendInviteDialogVisible,
|
||||||
deleteDialogVisible,
|
deleteDialogVisible,
|
||||||
|
resetAuthDialogVisible,
|
||||||
|
|
||||||
changeNameVisible,
|
changeNameVisible,
|
||||||
setChangeNameVisible,
|
setChangeNameVisible,
|
||||||
profile,
|
profile,
|
||||||
|
resetTfaApp,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -101,6 +104,15 @@ const Dialogs = ({
|
|||||||
fromList
|
fromList
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{resetAuthDialogVisible && (
|
||||||
|
<ResetApplicationDialog
|
||||||
|
visible={resetAuthDialogVisible}
|
||||||
|
onClose={closeDialogs}
|
||||||
|
resetTfaApp={resetTfaApp}
|
||||||
|
id={data}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -121,6 +133,7 @@ export default inject(({ auth, peopleStore }) => {
|
|||||||
disableDialogVisible,
|
disableDialogVisible,
|
||||||
sendInviteDialogVisible,
|
sendInviteDialogVisible,
|
||||||
deleteDialogVisible,
|
deleteDialogVisible,
|
||||||
|
resetAuthDialogVisible,
|
||||||
} = peopleStore.dialogStore;
|
} = peopleStore.dialogStore;
|
||||||
|
|
||||||
const { user: profile } = auth.userStore;
|
const { user: profile } = auth.userStore;
|
||||||
@ -130,6 +143,10 @@ export default inject(({ auth, peopleStore }) => {
|
|||||||
setChangeNameVisible,
|
setChangeNameVisible,
|
||||||
} = peopleStore.targetUserStore;
|
} = peopleStore.targetUserStore;
|
||||||
|
|
||||||
|
const { tfaStore } = auth;
|
||||||
|
|
||||||
|
const { unlinkApp: resetTfaApp } = tfaStore;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
changeEmail,
|
changeEmail,
|
||||||
changePassword,
|
changePassword,
|
||||||
@ -145,9 +162,12 @@ export default inject(({ auth, peopleStore }) => {
|
|||||||
disableDialogVisible,
|
disableDialogVisible,
|
||||||
sendInviteDialogVisible,
|
sendInviteDialogVisible,
|
||||||
deleteDialogVisible,
|
deleteDialogVisible,
|
||||||
|
resetAuthDialogVisible,
|
||||||
|
|
||||||
changeNameVisible,
|
changeNameVisible,
|
||||||
setChangeNameVisible,
|
setChangeNameVisible,
|
||||||
profile,
|
profile,
|
||||||
|
|
||||||
|
resetTfaApp,
|
||||||
};
|
};
|
||||||
})(observer(Dialogs));
|
})(observer(Dialogs));
|
||||||
|
@ -40,7 +40,14 @@ const UserContent = ({
|
|||||||
t,
|
t,
|
||||||
theme,
|
theme,
|
||||||
}) => {
|
}) => {
|
||||||
const { displayName, email, statusType, role, isVisitor } = item;
|
const {
|
||||||
|
displayName,
|
||||||
|
email,
|
||||||
|
statusType,
|
||||||
|
role,
|
||||||
|
isVisitor,
|
||||||
|
isCollaborator,
|
||||||
|
} = item;
|
||||||
|
|
||||||
const nameColor =
|
const nameColor =
|
||||||
statusType === "pending" || statusType === "disabled"
|
statusType === "pending" || statusType === "disabled"
|
||||||
@ -53,6 +60,8 @@ const UserContent = ({
|
|||||||
? t("Common:Owner")
|
? t("Common:Owner")
|
||||||
: role === "admin"
|
: role === "admin"
|
||||||
? t("Common:DocSpaceAdmin")
|
? t("Common:DocSpaceAdmin")
|
||||||
|
: isCollaborator
|
||||||
|
? t("Common:Collaborator")
|
||||||
: isVisitor
|
: isVisitor
|
||||||
? t("Common:User")
|
? t("Common:User")
|
||||||
: t("Common:RoomAdmin");
|
: t("Common:RoomAdmin");
|
||||||
|
@ -142,6 +142,7 @@ const PeopleTableRow = (props) => {
|
|||||||
|
|
||||||
role,
|
role,
|
||||||
isVisitor,
|
isVisitor,
|
||||||
|
isCollaborator,
|
||||||
} = item;
|
} = item;
|
||||||
|
|
||||||
const isPending = statusType === "pending" || statusType === "disabled";
|
const isPending = statusType === "pending" || statusType === "disabled";
|
||||||
@ -168,6 +169,12 @@ const PeopleTableRow = (props) => {
|
|||||||
label: t("Common:RoomAdmin"),
|
label: t("Common:RoomAdmin"),
|
||||||
action: "manager",
|
action: "manager",
|
||||||
};
|
};
|
||||||
|
const collaboratorOption = {
|
||||||
|
key: "collaborator",
|
||||||
|
title: t("Common:Collaborator"),
|
||||||
|
label: t("Common:Collaborator"),
|
||||||
|
action: "collaborator",
|
||||||
|
};
|
||||||
const userOption = {
|
const userOption = {
|
||||||
key: "user",
|
key: "user",
|
||||||
title: t("Common:User"),
|
title: t("Common:User"),
|
||||||
@ -179,10 +186,12 @@ const PeopleTableRow = (props) => {
|
|||||||
|
|
||||||
options.push(managerOption);
|
options.push(managerOption);
|
||||||
|
|
||||||
|
if (isCollaborator || isVisitor) options.push(collaboratorOption);
|
||||||
|
|
||||||
isVisitor && options.push(userOption);
|
isVisitor && options.push(userOption);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}, [t, isOwner, isVisitor]);
|
}, [t, isOwner, isVisitor, isCollaborator]);
|
||||||
|
|
||||||
const onAbort = () => {
|
const onAbort = () => {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@ -227,6 +236,8 @@ const PeopleTableRow = (props) => {
|
|||||||
return t("Common:DocSpaceAdmin");
|
return t("Common:DocSpaceAdmin");
|
||||||
case "manager":
|
case "manager":
|
||||||
return t("Common:RoomAdmin");
|
return t("Common:RoomAdmin");
|
||||||
|
case "collaborator":
|
||||||
|
return t("Common:Collaborator");
|
||||||
case "user":
|
case "user":
|
||||||
return t("Common:User");
|
return t("Common:User");
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,11 @@ import Loaders from "@docspace/common/components/Loaders";
|
|||||||
import { withLayoutSize } from "@docspace/common/utils";
|
import { withLayoutSize } from "@docspace/common/utils";
|
||||||
|
|
||||||
import withPeopleLoader from "SRC_DIR/HOCs/withPeopleLoader";
|
import withPeopleLoader from "SRC_DIR/HOCs/withPeopleLoader";
|
||||||
import { EmployeeType, PaymentsType } from "@docspace/common/constants";
|
import {
|
||||||
|
EmployeeType,
|
||||||
|
EmployeeStatus,
|
||||||
|
PaymentsType,
|
||||||
|
} from "@docspace/common/constants";
|
||||||
|
|
||||||
const getStatus = (filterValues) => {
|
const getStatus = (filterValues) => {
|
||||||
const employeeStatus = result(
|
const employeeStatus = result(
|
||||||
@ -69,7 +73,6 @@ const SectionFilterContent = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [selectedFilterValues, setSelectedFilterValues] = React.useState(null);
|
const [selectedFilterValues, setSelectedFilterValues] = React.useState(null);
|
||||||
|
|
||||||
//TODO: add new options from filter after update backend and fix manager from role
|
|
||||||
const onFilter = (data) => {
|
const onFilter = (data) => {
|
||||||
const status = getStatus(data);
|
const status = getStatus(data);
|
||||||
|
|
||||||
@ -80,8 +83,12 @@ const SectionFilterContent = ({
|
|||||||
const newFilter = filter.clone();
|
const newFilter = filter.clone();
|
||||||
|
|
||||||
if (status === 3) {
|
if (status === 3) {
|
||||||
newFilter.employeeStatus = 2;
|
newFilter.employeeStatus = EmployeeStatus.Disabled;
|
||||||
newFilter.activationStatus = null;
|
newFilter.activationStatus = null;
|
||||||
|
} else if (status === 2) {
|
||||||
|
console.log(status);
|
||||||
|
newFilter.employeeStatus = EmployeeStatus.Active;
|
||||||
|
newFilter.activationStatus = status;
|
||||||
} else {
|
} else {
|
||||||
newFilter.employeeStatus = null;
|
newFilter.employeeStatus = null;
|
||||||
newFilter.activationStatus = status;
|
newFilter.activationStatus = status;
|
||||||
@ -94,6 +101,7 @@ const SectionFilterContent = ({
|
|||||||
newFilter.group = group;
|
newFilter.group = group;
|
||||||
|
|
||||||
newFilter.payments = payments;
|
newFilter.payments = payments;
|
||||||
|
//console.log(newFilter);
|
||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
fetchPeople(newFilter, true).finally(() => setIsLoading(false));
|
fetchPeople(newFilter, true).finally(() => setIsLoading(false));
|
||||||
@ -123,7 +131,6 @@ const SectionFilterContent = ({
|
|||||||
fetchPeople(newFilter, true).finally(() => setIsLoading(false));
|
fetchPeople(newFilter, true).finally(() => setIsLoading(false));
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: change translation keys
|
|
||||||
const getData = async () => {
|
const getData = async () => {
|
||||||
const statusItems = [
|
const statusItems = [
|
||||||
{
|
{
|
||||||
@ -172,6 +179,12 @@ const SectionFilterContent = ({
|
|||||||
group: "filter-type",
|
group: "filter-type",
|
||||||
label: t("Common:RoomAdmin"),
|
label: t("Common:RoomAdmin"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "filter_type-room-admin",
|
||||||
|
key: EmployeeType.Collaborator,
|
||||||
|
group: "filter-type",
|
||||||
|
label: t("Common:Collaborator"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "filter_type-user",
|
id: "filter_type-user",
|
||||||
key: EmployeeType.Guest,
|
key: EmployeeType.Guest,
|
||||||
@ -312,6 +325,9 @@ const SectionFilterContent = ({
|
|||||||
case EmployeeType.User:
|
case EmployeeType.User:
|
||||||
label = t("Common:RoomAdmin");
|
label = t("Common:RoomAdmin");
|
||||||
break;
|
break;
|
||||||
|
case EmployeeType.Collaborator:
|
||||||
|
label = t("Common:Collaborator");
|
||||||
|
break;
|
||||||
case EmployeeType.Guest:
|
case EmployeeType.Guest:
|
||||||
label = t("Common:User");
|
label = t("Common:User");
|
||||||
break;
|
break;
|
||||||
|
@ -72,6 +72,7 @@ const StyledContainer = styled.div`
|
|||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
min-height: 33px;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -42,11 +42,20 @@ const PureHome = ({
|
|||||||
|
|
||||||
setSelectedNode,
|
setSelectedNode,
|
||||||
withPaging,
|
withPaging,
|
||||||
|
onClickBack,
|
||||||
}) => {
|
}) => {
|
||||||
const { location } = history;
|
const { location } = history;
|
||||||
const { pathname } = location;
|
const { pathname } = location;
|
||||||
//console.log("People Home render");
|
//console.log("People Home render");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("popstate", onClickBack);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("popstate", onClickBack);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (pathname.indexOf("/accounts/filter") > -1) {
|
if (pathname.indexOf("/accounts/filter") > -1) {
|
||||||
setSelectedNode(["accounts", "filter"]);
|
setSelectedNode(["accounts", "filter"]);
|
||||||
@ -95,6 +104,7 @@ const PureHome = ({
|
|||||||
<Section.SectionBody>
|
<Section.SectionBody>
|
||||||
<SectionBodyContent />
|
<SectionBodyContent />
|
||||||
</Section.SectionBody>
|
</Section.SectionBody>
|
||||||
|
|
||||||
<Section.InfoPanelHeader>
|
<Section.InfoPanelHeader>
|
||||||
<InfoPanelHeaderContent />
|
<InfoPanelHeaderContent />
|
||||||
</Section.InfoPanelHeader>
|
</Section.InfoPanelHeader>
|
||||||
@ -120,36 +130,45 @@ PureHome.propTypes = {
|
|||||||
|
|
||||||
const Home = withTranslation("People")(PureHome);
|
const Home = withTranslation("People")(PureHome);
|
||||||
|
|
||||||
export default inject(({ auth, peopleStore, treeFoldersStore }) => {
|
export default inject(
|
||||||
const { settingsStore } = auth;
|
({ auth, peopleStore, treeFoldersStore, filesActionsStore }) => {
|
||||||
const { showCatalog, withPaging } = settingsStore;
|
const { settingsStore } = auth;
|
||||||
const { usersStore, selectedGroupStore, loadingStore, viewAs } = peopleStore;
|
const { showCatalog, withPaging } = settingsStore;
|
||||||
const { getUsersList } = usersStore;
|
const {
|
||||||
const { selectedGroup } = selectedGroupStore;
|
usersStore,
|
||||||
const { setSelectedNode } = treeFoldersStore;
|
selectedGroupStore,
|
||||||
const {
|
loadingStore,
|
||||||
isLoading,
|
viewAs,
|
||||||
setIsLoading,
|
} = peopleStore;
|
||||||
setIsRefresh,
|
const { getUsersList } = usersStore;
|
||||||
firstLoad,
|
const { selectedGroup } = selectedGroupStore;
|
||||||
setFirstLoad,
|
const { setSelectedNode } = treeFoldersStore;
|
||||||
} = loadingStore;
|
const { onClickBack } = filesActionsStore;
|
||||||
|
const {
|
||||||
|
isLoading,
|
||||||
|
setIsLoading,
|
||||||
|
setIsRefresh,
|
||||||
|
firstLoad,
|
||||||
|
setFirstLoad,
|
||||||
|
} = loadingStore;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isAdmin: auth.isAdmin,
|
isAdmin: auth.isAdmin,
|
||||||
isLoading,
|
isLoading,
|
||||||
getUsersList,
|
getUsersList,
|
||||||
setIsLoading,
|
setIsLoading,
|
||||||
setIsRefresh,
|
setIsRefresh,
|
||||||
selectedGroup,
|
selectedGroup,
|
||||||
showCatalog,
|
showCatalog,
|
||||||
firstLoad,
|
firstLoad,
|
||||||
setFirstLoad,
|
setFirstLoad,
|
||||||
viewAs,
|
viewAs,
|
||||||
setSelectedNode,
|
setSelectedNode,
|
||||||
checkedMaintenance: auth.settingsStore.checkedMaintenance,
|
checkedMaintenance: auth.settingsStore.checkedMaintenance,
|
||||||
setMaintenanceExist: auth.settingsStore.setMaintenanceExist,
|
setMaintenanceExist: auth.settingsStore.setMaintenanceExist,
|
||||||
snackbarExist: auth.settingsStore.snackbarExist,
|
snackbarExist: auth.settingsStore.snackbarExist,
|
||||||
withPaging,
|
withPaging,
|
||||||
};
|
onClickBack,
|
||||||
})(observer(withRouter(Home)));
|
};
|
||||||
|
}
|
||||||
|
)(observer(withRouter(Home)));
|
||||||
|
@ -6,17 +6,18 @@ import Section from "@docspace/common/components/Section";
|
|||||||
import { combineUrl } from "@docspace/common/utils";
|
import { combineUrl } from "@docspace/common/utils";
|
||||||
import tryRedirectTo from "@docspace/common/utils/tryRedirectTo";
|
import tryRedirectTo from "@docspace/common/utils/tryRedirectTo";
|
||||||
import { inject, observer } from "mobx-react";
|
import { inject, observer } from "mobx-react";
|
||||||
|
import { EmployeeActivationStatus } from "@docspace/common/constants";
|
||||||
|
|
||||||
class ActivateEmail extends React.PureComponent {
|
class ActivateEmail extends React.PureComponent {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { logout, changeEmail, linkData } = this.props;
|
const { logout, updateEmailActivationStatus, linkData } = this.props;
|
||||||
const [email, uid, key] = [
|
const [email, uid, key] = [
|
||||||
linkData.email,
|
linkData.email,
|
||||||
linkData.uid,
|
linkData.uid,
|
||||||
linkData.confirmHeader,
|
linkData.confirmHeader,
|
||||||
];
|
];
|
||||||
logout().then(() =>
|
logout().then(() =>
|
||||||
changeEmail(uid, email, key)
|
updateEmailActivationStatus(EmployeeActivationStatus.Activated, uid, key)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
tryRedirectTo(
|
tryRedirectTo(
|
||||||
combineUrl(
|
combineUrl(
|
||||||
@ -70,6 +71,6 @@ export default inject(({ auth }) => {
|
|||||||
const { logout, userStore } = auth;
|
const { logout, userStore } = auth;
|
||||||
return {
|
return {
|
||||||
logout,
|
logout,
|
||||||
changeEmail: userStore.changeEmail,
|
updateEmailActivationStatus: userStore.updateEmailActivationStatus,
|
||||||
};
|
};
|
||||||
})(withRouter(observer(ActivateEmailForm)));
|
})(withRouter(observer(ActivateEmailForm)));
|
||||||
|
@ -91,6 +91,7 @@ const FilesSection = React.memo(() => {
|
|||||||
<PrivateRoute
|
<PrivateRoute
|
||||||
restricted
|
restricted
|
||||||
withManager
|
withManager
|
||||||
|
withCollaborator
|
||||||
path={[
|
path={[
|
||||||
"/rooms/personal",
|
"/rooms/personal",
|
||||||
"/rooms/personal/filter",
|
"/rooms/personal/filter",
|
||||||
@ -144,7 +145,6 @@ const FilesSection = React.memo(() => {
|
|||||||
<PrivateRoute
|
<PrivateRoute
|
||||||
exact
|
exact
|
||||||
restricted
|
restricted
|
||||||
withManager
|
|
||||||
path={"/settings/admin"}
|
path={"/settings/admin"}
|
||||||
component={Settings}
|
component={Settings}
|
||||||
/>
|
/>
|
||||||
|
@ -100,9 +100,8 @@ class Tile extends React.PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onShowTemplateInfo = () => {
|
onShowTemplateInfo = () => {
|
||||||
if (!this.props.isInfoPanelVisible) {
|
this.onSelectForm();
|
||||||
this.props.setIsInfoPanelVisible(true);
|
if (!this.props.isInfoPanelVisible) this.props.setIsInfoPanelVisible(true);
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
getOptions = () => ["create", "template-info"];
|
getOptions = () => ["create", "template-info"];
|
||||||
|
@ -7,6 +7,7 @@ import getCorrectDate from "@docspace/components/utils/getCorrectDate";
|
|||||||
import Link from "@docspace/components/link";
|
import Link from "@docspace/components/link";
|
||||||
import Text from "@docspace/components/text";
|
import Text from "@docspace/components/text";
|
||||||
import Tag from "@docspace/components/tag";
|
import Tag from "@docspace/components/tag";
|
||||||
|
import { decode } from "he";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
connectedCloudsTypeTitleTranslation as getProviderTranslation,
|
connectedCloudsTypeTitleTranslation as getProviderTranslation,
|
||||||
@ -227,8 +228,8 @@ class DetailsHelper {
|
|||||||
const onOpenUser = () => this.openUser(this.item.createdBy, this.history);
|
const onOpenUser = () => this.openUser(this.item.createdBy, this.history);
|
||||||
|
|
||||||
return this.personal || this.isVisitor
|
return this.personal || this.isVisitor
|
||||||
? text(decodeString(this.item.createdBy?.displayName))
|
? text(decode(this.item.createdBy?.displayName))
|
||||||
: link(decodeString(this.item.createdBy?.displayName), onOpenUser);
|
: link(decode(this.item.createdBy?.displayName), onOpenUser);
|
||||||
};
|
};
|
||||||
|
|
||||||
getItemLocation = () => {
|
getItemLocation = () => {
|
||||||
@ -279,8 +280,8 @@ class DetailsHelper {
|
|||||||
const onOpenUser = () => this.openUser(this.item.updatedBy, this.history);
|
const onOpenUser = () => this.openUser(this.item.updatedBy, this.history);
|
||||||
|
|
||||||
return this.personal || this.isVisitor
|
return this.personal || this.isVisitor
|
||||||
? text(decodeString(this.item.updatedBy?.displayName))
|
? text(decode(this.item.updatedBy?.displayName))
|
||||||
: link(decodeString(this.item.updatedBy?.displayName), onOpenUser);
|
: link(decode(this.item.updatedBy?.displayName), onOpenUser);
|
||||||
};
|
};
|
||||||
|
|
||||||
getItemCreationDate = () => {
|
getItemCreationDate = () => {
|
||||||
|
@ -21,6 +21,11 @@ class MembersHelper {
|
|||||||
label: this.t("Common:RoomAdmin"),
|
label: this.t("Common:RoomAdmin"),
|
||||||
access: ShareAccessRights.RoomManager,
|
access: ShareAccessRights.RoomManager,
|
||||||
},
|
},
|
||||||
|
collaborator: {
|
||||||
|
key: "collaborator",
|
||||||
|
label: this.t("Common:Collaborator"),
|
||||||
|
access: ShareAccessRights.Collaborator,
|
||||||
|
},
|
||||||
viewer: {
|
viewer: {
|
||||||
key: "viewer",
|
key: "viewer",
|
||||||
label: this.t("Translations:RoleViewer"),
|
label: this.t("Translations:RoleViewer"),
|
||||||
@ -69,6 +74,7 @@ class MembersHelper {
|
|||||||
case RoomsType.FillingFormsRoom:
|
case RoomsType.FillingFormsRoom:
|
||||||
return [
|
return [
|
||||||
options.roomAdmin,
|
options.roomAdmin,
|
||||||
|
options.collaborator,
|
||||||
options.formFiller,
|
options.formFiller,
|
||||||
options.viewer,
|
options.viewer,
|
||||||
...deleteOption,
|
...deleteOption,
|
||||||
@ -76,6 +82,7 @@ class MembersHelper {
|
|||||||
case RoomsType.EditingRoom:
|
case RoomsType.EditingRoom:
|
||||||
return [
|
return [
|
||||||
options.roomAdmin,
|
options.roomAdmin,
|
||||||
|
options.collaborator,
|
||||||
options.editor,
|
options.editor,
|
||||||
options.viewer,
|
options.viewer,
|
||||||
...deleteOption,
|
...deleteOption,
|
||||||
@ -83,16 +90,23 @@ class MembersHelper {
|
|||||||
case RoomsType.ReviewRoom:
|
case RoomsType.ReviewRoom:
|
||||||
return [
|
return [
|
||||||
options.roomAdmin,
|
options.roomAdmin,
|
||||||
|
options.collaborator,
|
||||||
options.reviewer,
|
options.reviewer,
|
||||||
options.commentator,
|
options.commentator,
|
||||||
options.viewer,
|
options.viewer,
|
||||||
...deleteOption,
|
...deleteOption,
|
||||||
];
|
];
|
||||||
case RoomsType.ReadOnlyRoom:
|
case RoomsType.ReadOnlyRoom:
|
||||||
return [options.roomAdmin, options.viewer, ...deleteOption];
|
return [
|
||||||
|
options.roomAdmin,
|
||||||
|
options.collaborator,
|
||||||
|
options.viewer,
|
||||||
|
...deleteOption,
|
||||||
|
];
|
||||||
case RoomsType.CustomRoom:
|
case RoomsType.CustomRoom:
|
||||||
return [
|
return [
|
||||||
options.roomAdmin,
|
options.roomAdmin,
|
||||||
|
options.collaborator,
|
||||||
options.editor,
|
options.editor,
|
||||||
options.formFiller,
|
options.formFiller,
|
||||||
options.reviewer,
|
options.reviewer,
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import styled, { css } from "styled-components";
|
import styled, { css } from "styled-components";
|
||||||
import { Base } from "@docspace/components/themes";
|
import { Base } from "@docspace/components/themes";
|
||||||
|
import { hugeMobile, tablet } from "@docspace/components/utils/device";
|
||||||
|
|
||||||
const StyledAccountsItemTitle = styled.div`
|
const StyledAccountsItemTitle = styled.div`
|
||||||
min-height: 104px;
|
min-height: 80px;
|
||||||
height: 104px;
|
height: 80px;
|
||||||
max-height: 104px;
|
max-height: 104px;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -11,8 +12,29 @@ const StyledAccountsItemTitle = styled.div`
|
|||||||
justify-content: start;
|
justify-content: start;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|
||||||
|
position: fixed;
|
||||||
|
margin-top: -80px;
|
||||||
|
margin-left: -20px;
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
padding: 24px 0 24px 20px;
|
||||||
|
background: ${(props) => props.theme.infoPanel.backgroundColor};
|
||||||
|
z-index: 100;
|
||||||
|
|
||||||
|
@media ${tablet} {
|
||||||
|
width: 440px;
|
||||||
|
padding: 24px 20px 24px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 549px) {
|
||||||
|
width: calc(100vw - 69px - 40px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media ${hugeMobile} {
|
||||||
|
width: calc(100vw - 32px);
|
||||||
|
padding: 24px 0 24px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
padding-top: 24px;
|
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@ const StyledInfoPanelBody = styled.div`
|
|||||||
${({ isAccounts }) =>
|
${({ isAccounts }) =>
|
||||||
isAccounts
|
isAccounts
|
||||||
? css`
|
? css`
|
||||||
padding: 0px 3px 0 20px;
|
padding: 80px 3px 0 20px;
|
||||||
@media ${hugeMobile} {
|
@media ${hugeMobile} {
|
||||||
padding: 0px 8px 0 16px;
|
padding: 80px 8px 0 16px;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
: css`
|
: css`
|
||||||
|
@ -28,7 +28,6 @@ const StyledNoItemContainer = styled.div`
|
|||||||
}
|
}
|
||||||
|
|
||||||
.no-accounts {
|
.no-accounts {
|
||||||
padding-top: 80px;
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@ import { ReactSVG } from "react-svg";
|
|||||||
import { Text } from "@docspace/components";
|
import { Text } from "@docspace/components";
|
||||||
import { StyledTitle } from "../../styles/common";
|
import { StyledTitle } from "../../styles/common";
|
||||||
|
|
||||||
const GalleryItemTitle = ({ selection, getIcon }) => {
|
const GalleryItemTitle = ({ gallerySelected, getIcon }) => {
|
||||||
return (
|
return (
|
||||||
<StyledTitle>
|
<StyledTitle>
|
||||||
<ReactSVG className="icon" src={getIcon(32, ".docxf")} />
|
<ReactSVG className="icon" src={getIcon(32, ".docxf")} />
|
||||||
<Text className="text">{selection?.attributes?.name_form}</Text>
|
<Text className="text">{gallerySelected?.attributes?.name_form}</Text>
|
||||||
</StyledTitle>
|
</StyledTitle>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user