Merge branch 'release/rc-v1.2.0' of github.com:ONLYOFFICE/DocSpace into release/rc-v1.2.0
This commit is contained in:
commit
748e454224
@ -135,7 +135,7 @@ public class SecurityContext
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (tenant != _tenantManager.GetCurrentTenant().Id)
|
||||
{
|
||||
return false;
|
||||
@ -161,9 +161,9 @@ public class SecurityContext
|
||||
return false;
|
||||
}
|
||||
|
||||
var loginEventById = await _dbLoginEventsManager.GetById(loginEventId);
|
||||
|
||||
if (loginEventById == null)
|
||||
var loginEventById = await _dbLoginEventsManager.GetById(loginEventId);
|
||||
|
||||
if (loginEventById == null || !loginEventById.Active)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ public static class DbQuotaExtension
|
||||
Tenant = -1,
|
||||
Name = "trial",
|
||||
Description = null,
|
||||
Features = "trial,audit,ldap,sso,whitelabel,thirdparty,restore,total_size:107374182400,file_size:100,manager:1",
|
||||
Features = "trial,audit,ldap,sso,whitelabel,thirdparty,audit,restore,total_size:107374182400,file_size:100,manager:1",
|
||||
Price = 0,
|
||||
ProductId = null,
|
||||
Visible = false
|
||||
@ -69,7 +69,7 @@ public static class DbQuotaExtension
|
||||
Tenant = -2,
|
||||
Name = "admin",
|
||||
Description = null,
|
||||
Features = "audit,ldap,sso,whitelabel,thirdparty,restore,total_size:107374182400,file_size:1024,manager:1",
|
||||
Features = "audit,ldap,sso,whitelabel,thirdparty,audit,restore,total_size:107374182400,file_size:1024,manager:1",
|
||||
Price = 30,
|
||||
ProductId = "1002",
|
||||
Visible = true
|
||||
@ -79,7 +79,7 @@ public static class DbQuotaExtension
|
||||
Tenant = -3,
|
||||
Name = "startup",
|
||||
Description = null,
|
||||
Features = "free,thirdparty,total_size:2147483648,manager:1,room:12,usersInRoom:3",
|
||||
Features = "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3",
|
||||
Price = 0,
|
||||
ProductId = null,
|
||||
Visible = false
|
||||
|
@ -149,7 +149,7 @@ public abstract class BaseStorage : IDataStore
|
||||
|
||||
public abstract Task<Stream> GetReadStreamAsync(string domain, string path);
|
||||
|
||||
public abstract Task<Stream> GetReadStreamAsync(string domain, string path, int offset);
|
||||
public abstract Task<Stream> GetReadStreamAsync(string domain, string path, long offset);
|
||||
|
||||
public abstract Task<Uri> SaveAsync(string domain, string path, Stream stream);
|
||||
public abstract Task<Uri> SaveAsync(string domain, string path, Stream stream, ACL acl);
|
||||
|
@ -110,7 +110,7 @@ public class DiscDataStore : BaseStorage
|
||||
throw new FileNotFoundException("File not found", Path.GetFullPath(target));
|
||||
}
|
||||
|
||||
public override Task<Stream> GetReadStreamAsync(string domain, string path, int offset)
|
||||
public override Task<Stream> GetReadStreamAsync(string domain, string path, long offset)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(path);
|
||||
|
||||
@ -123,6 +123,10 @@ public class DiscDataStore : BaseStorage
|
||||
{
|
||||
stream.Seek(offset, SeekOrigin.Begin);
|
||||
}
|
||||
else if (0 < offset)
|
||||
{
|
||||
throw new InvalidOperationException("Seek stream is not impossible");
|
||||
}
|
||||
|
||||
return Task.FromResult(stream);
|
||||
}
|
||||
@ -130,7 +134,6 @@ public class DiscDataStore : BaseStorage
|
||||
throw new FileNotFoundException("File not found", Path.GetFullPath(target));
|
||||
}
|
||||
|
||||
|
||||
public override Task<Uri> SaveAsync(string domain, string path, Stream stream, string contentType, string contentDisposition)
|
||||
{
|
||||
return SaveAsync(domain, path, stream);
|
||||
|
@ -142,7 +142,7 @@ public class GoogleCloudStorage : BaseStorage
|
||||
return GetReadStreamAsync(domain, path, 0);
|
||||
}
|
||||
|
||||
public override async Task<Stream> GetReadStreamAsync(string domain, string path, int offset)
|
||||
public override async Task<Stream> GetReadStreamAsync(string domain, string path, long offset)
|
||||
{
|
||||
var tempStream = _tempStream.Create();
|
||||
|
||||
|
@ -91,7 +91,7 @@ public interface IDataStore
|
||||
///<param name="domain"></param>
|
||||
///<param name="path"></param>
|
||||
///<returns></returns>
|
||||
Task<Stream> GetReadStreamAsync(string domain, string path, int offset);
|
||||
Task<Stream> GetReadStreamAsync(string domain, string path, long offset);
|
||||
|
||||
///<summary>
|
||||
/// Saves the contents of the stream in the repository.
|
||||
|
@ -162,7 +162,7 @@ public class RackspaceCloudStorage : BaseStorage
|
||||
return GetReadStreamAsync(domain, path, 0);
|
||||
}
|
||||
|
||||
public override Task<Stream> GetReadStreamAsync(string domain, string path, int offset)
|
||||
public override Task<Stream> GetReadStreamAsync(string domain, string path, long offset)
|
||||
{
|
||||
return GetReadStreamAsync(domain, path, offset);
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ public class S3Storage : BaseStorage
|
||||
return GetReadStreamAsync(domain, path, 0);
|
||||
}
|
||||
|
||||
public override async Task<Stream> GetReadStreamAsync(string domain, string path, int offset)
|
||||
public override async Task<Stream> GetReadStreamAsync(string domain, string path, long offset)
|
||||
{
|
||||
var request = new GetObjectRequest
|
||||
{
|
||||
|
@ -24,6 +24,13 @@
|
||||
// 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
|
||||
|
||||
using System.IO;
|
||||
|
||||
using ASC.Common.Web;
|
||||
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace ASC.Data.Storage.DiscStorage;
|
||||
|
||||
public class StorageHandler
|
||||
@ -86,8 +93,9 @@ public class StorageHandler
|
||||
var headers = header.Length > 0 ? header.Split('&').Select(HttpUtility.UrlDecode) : Array.Empty<string>();
|
||||
|
||||
const int bigSize = 5 * 1024 * 1024;
|
||||
var fileSize = await storage.GetFileSizeAsync(_domain, path);
|
||||
|
||||
if (storage.IsSupportInternalUri && bigSize < await storage.GetFileSizeAsync(_domain, path))
|
||||
if (storage.IsSupportInternalUri && bigSize < fileSize)
|
||||
{
|
||||
var uri = await storage.GetInternalUriAsync(_domain, path, TimeSpan.FromMinutes(15), headers);
|
||||
|
||||
@ -134,7 +142,7 @@ public class StorageHandler
|
||||
|
||||
context.Response.Headers[toCopy] = h.Substring(toCopy.Length + 1);
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
context.Response.ContentType = MimeMapping.GetMimeMapping(path);
|
||||
@ -149,8 +157,18 @@ public class StorageHandler
|
||||
context.Response.Headers["Content-Encoding"] = encoding;
|
||||
}
|
||||
|
||||
using (var stream = await storage.GetReadStreamAsync(_domain, path))
|
||||
{
|
||||
|
||||
long offset = 0;
|
||||
var length = ProcessRangeHeader(context, fileSize, ref offset);
|
||||
|
||||
context.Response.Headers["Connection"] = "Keep-Alive";
|
||||
context.Response.Headers["Content-Length"] = length.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
using (var stream = await storage.GetReadStreamAsync(_domain, path, offset))
|
||||
{
|
||||
var responseBufferingFeature = context.Features.Get<IHttpResponseBodyFeature>();
|
||||
responseBufferingFeature?.DisableBuffering();
|
||||
|
||||
await stream.CopyToAsync(context.Response.Body);
|
||||
}
|
||||
|
||||
@ -158,6 +176,38 @@ public class StorageHandler
|
||||
await context.Response.CompleteAsync();
|
||||
}
|
||||
|
||||
private long ProcessRangeHeader(HttpContext context, long fullLength, ref long offset)
|
||||
{
|
||||
if (context == null) throw new ArgumentNullException();
|
||||
if (context.Request.Headers["Range"] == StringValues.Empty) return fullLength;
|
||||
|
||||
long endOffset = -1;
|
||||
|
||||
var range = context.Request.Headers["Range"][0].Split(new[] { '=', '-' });
|
||||
offset = Convert.ToInt64(range[1]);
|
||||
if (range.Count() > 2 && !string.IsNullOrEmpty(range[2]))
|
||||
{
|
||||
endOffset = Convert.ToInt64(range[2]);
|
||||
}
|
||||
if (endOffset < 0 || endOffset >= fullLength)
|
||||
{
|
||||
endOffset = fullLength - 1;
|
||||
}
|
||||
|
||||
var length = endOffset - offset + 1;
|
||||
|
||||
if (length <= 0) throw new HttpException(HttpStatusCode.BadRequest, "Wrong Range header");
|
||||
|
||||
if (length < fullLength)
|
||||
{
|
||||
context.Response.StatusCode = (int)HttpStatusCode.PartialContent;
|
||||
}
|
||||
context.Response.Headers["Accept-Ranges"] = "bytes";
|
||||
context.Response.Headers["Content-Range"] = string.Format(" bytes {0}-{1}/{2}", offset, endOffset, fullLength);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
private string GetRouteValue(string name, HttpContext context)
|
||||
{
|
||||
return (context.GetRouteValue(name) ?? "").ToString();
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
global using System.Data;
|
||||
global using System.Data.Common;
|
||||
global using System.Text.RegularExpressions;
|
||||
global using System.Xml.Linq;
|
||||
|
||||
global using ASC.Api.Core;
|
||||
@ -33,9 +34,8 @@ global using ASC.Api.Core.Core;
|
||||
global using ASC.Api.Core.Extensions;
|
||||
global using ASC.Common;
|
||||
global using ASC.Common.Logging;
|
||||
global using ASC.Common.Utils;
|
||||
global using ASC.Core.Common.EF;
|
||||
global using ASC.Core.Common.EF.Context;
|
||||
global using ASC.Core.Common.EF.Context;
|
||||
global using ASC.Core.Common.Hosting;
|
||||
global using ASC.Core.Tenants;
|
||||
global using ASC.Core.Users;
|
||||
@ -47,7 +47,6 @@ global using ASC.Data.Backup.Tasks;
|
||||
global using ASC.Data.Backup.Tasks.Data;
|
||||
global using ASC.Data.Backup.Tasks.Modules;
|
||||
global using ASC.Data.Storage;
|
||||
global using ASC.Data.Storage.DiscStorage;
|
||||
global using ASC.EventBus.Abstractions;
|
||||
global using ASC.EventBus.Events;
|
||||
global using ASC.EventBus.Extensions.Logger;
|
||||
@ -61,5 +60,8 @@ global using ASC.Webhooks.Core.EF.Context;
|
||||
|
||||
global using Autofac.Extensions.DependencyInjection;
|
||||
|
||||
global using AutoMapper;
|
||||
global using AutoMapper.QueryableExtensions;
|
||||
|
||||
global using Microsoft.EntityFrameworkCore;
|
||||
global using Microsoft.Extensions.Hosting.WindowsServices;
|
||||
|
@ -23,8 +23,6 @@
|
||||
// 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
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ASC.Migration.PersonalToDocspace.Creator;
|
||||
|
||||
@ -37,6 +35,7 @@ public class MigrationCreator
|
||||
private readonly StorageFactory _storageFactory;
|
||||
private readonly StorageFactoryConfig _storageFactoryConfig;
|
||||
private readonly ModuleProvider _moduleProvider;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
private List<IModuleSpecifics> _modules;
|
||||
private string _pathToSave;
|
||||
@ -72,7 +71,8 @@ public class MigrationCreator
|
||||
DbFactory dbFactory,
|
||||
StorageFactory storageFactory,
|
||||
StorageFactoryConfig storageFactoryConfig,
|
||||
ModuleProvider moduleProvider)
|
||||
ModuleProvider moduleProvider,
|
||||
IMapper mapper)
|
||||
{
|
||||
_tenantDomainValidator = tenantDomainValidator;
|
||||
_tempStream = tempStream;
|
||||
@ -80,13 +80,15 @@ public class MigrationCreator
|
||||
_storageFactory = storageFactory;
|
||||
_storageFactoryConfig = storageFactoryConfig;
|
||||
_moduleProvider = moduleProvider;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public string Create(string fromAlias, string userName, string mail, string toRegion, string toAlias)
|
||||
{
|
||||
Init(fromAlias, userName, mail, toRegion, toAlias);
|
||||
|
||||
var id = GetUserId();
|
||||
var id = GetUserId();
|
||||
CheckCountManager();
|
||||
var fileName = _userName + ".tar.gz";
|
||||
var path = Path.Combine(_pathToSave, fileName);
|
||||
using (var writer = new ZipWriteOperator(_tempStream, path))
|
||||
@ -169,7 +171,31 @@ public class MigrationCreator
|
||||
{
|
||||
throw new ArgumentException("username was not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckCountManager()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_toAlias)) {
|
||||
using var dbContextTenant = _dbFactory.CreateDbContext<TenantDbContext>(_toRegion);
|
||||
var tenant = dbContextTenant.Tenants.SingleOrDefault(t => t.Alias == _toAlias);
|
||||
|
||||
using var coreDbContext = _dbFactory.CreateDbContext<CoreDbContext>(_toRegion);
|
||||
var qouta = coreDbContext.Quotas
|
||||
.Where(r => r.Tenant == tenant.Id)
|
||||
.ProjectTo<TenantQuota>(_mapper.ConfigurationProvider)
|
||||
.SingleOrDefault();
|
||||
|
||||
using var userDbContextToregion = _dbFactory.CreateDbContext<UserDbContext>(_toRegion);
|
||||
var usersCount = userDbContextToregion.Users
|
||||
.Join(userDbContextToregion.UserGroups, u => u.Id, ug => ug.Userid, (u, ug) => new {u, ug})
|
||||
.Where(q=> q.u.Tenant == tenant.Id && q.ug.UserGroupId == Common.Security.Authorizing.Constants.DocSpaceAdmin.ID).Count();
|
||||
if (usersCount > qouta.CountRoomAdmin)
|
||||
{
|
||||
throw new ArgumentException("user count exceed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DoMigrationDb(Guid id, IDataWriteOperator writer)
|
||||
{
|
||||
@ -239,6 +265,11 @@ public class MigrationCreator
|
||||
ChangeName(data);
|
||||
}
|
||||
|
||||
if (data.TableName == "files_bunch_objects")
|
||||
{
|
||||
ClearCommonBunch(data);
|
||||
}
|
||||
|
||||
WriteEnrty(data, writer, module);
|
||||
}
|
||||
}
|
||||
@ -319,7 +350,19 @@ public class MigrationCreator
|
||||
{
|
||||
data.Rows[0]["name"] = "";
|
||||
}
|
||||
|
||||
|
||||
private void ClearCommonBunch(DataTable data)
|
||||
{
|
||||
for(var i = 0; i < data.Rows.Count; i++)
|
||||
{
|
||||
if (data.Rows[i]["right_node"].ToString().EndsWith('/'))
|
||||
{
|
||||
data.Rows.RemoveAt(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DoMigrationStorage(Guid id, IDataWriteOperator writer)
|
||||
{
|
||||
Console.WriteLine($"start backup storage");
|
||||
|
@ -72,7 +72,7 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
new
|
||||
{
|
||||
Tenant = -1,
|
||||
Features = "trial,audit,ldap,sso,whitelabel,restore,thirdparty,total_size:107374182400,file_size:100,manager:1",
|
||||
Features = "trial,audit,ldap,sso,whitelabel,restore,thirdparty,audit,total_size:107374182400,file_size:100,manager:1",
|
||||
Name = "trial",
|
||||
Price = 0m,
|
||||
Visible = false
|
||||
@ -80,7 +80,7 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
new
|
||||
{
|
||||
Tenant = -2,
|
||||
Features = "audit,ldap,sso,whitelabel,restore,thirdparty,total_size:107374182400,file_size:1024,manager:1",
|
||||
Features = "audit,ldap,sso,whitelabel,restore,thirdparty,audit,total_size:107374182400,file_size:1024,manager:1",
|
||||
Name = "admin",
|
||||
Price = 30m,
|
||||
ProductId = "1002",
|
||||
@ -89,7 +89,7 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
new
|
||||
{
|
||||
Tenant = -3,
|
||||
Features = "free,thirdparty,total_size:2147483648,manager:1,room:12,usersInRoom:3",
|
||||
Features = "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3",
|
||||
Name = "startup",
|
||||
Price = 0m,
|
||||
Visible = false
|
||||
|
@ -118,17 +118,17 @@ public partial class CoreDbContextMigrate : Migration
|
||||
migrationBuilder.InsertData(
|
||||
table: "tenants_quota",
|
||||
columns: new[] { "tenant", "description", "features", "name", "product_id" },
|
||||
values: new object[] { -3, null, "free,thirdparty,total_size:2147483648,manager:1,room:12,usersInRoom:3", "startup", null });
|
||||
values: new object[] { -3, null, "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3", "startup", null });
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "tenants_quota",
|
||||
columns: new[] { "tenant", "description", "features", "name", "price", "product_id", "visible" },
|
||||
values: new object[] { -2, null, "audit,ldap,sso,whitelabel,restore,thirdparty,total_size:107374182400,file_size:1024,manager:1", "admin", 30m, "1002", true });
|
||||
values: new object[] { -2, null, "audit,ldap,sso,whitelabel,restore,thirdparty,audit,total_size:107374182400,file_size:1024,manager:1", "admin", 30m, "1002", true });
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "tenants_quota",
|
||||
columns: new[] { "tenant", "description", "features", "name", "product_id" },
|
||||
values: new object[] { -1, null, "trial,audit,ldap,sso,whitelabel,restore,thirdparty,total_size:107374182400,file_size:100,manager:1", "trial", null });
|
||||
values: new object[] { -1, null, "trial,audit,ldap,sso,whitelabel,restore,thirdparty,audit,total_size:107374182400,file_size:100,manager:1", "trial", null });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "last_modified",
|
||||
|
@ -70,7 +70,7 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
new
|
||||
{
|
||||
Tenant = -1,
|
||||
Features = "trial,audit,ldap,sso,whitelabel,restore,thirdparty,total_size:107374182400,file_size:100,manager:1",
|
||||
Features = "trial,audit,ldap,sso,whitelabel,restore,thirdparty,audit,total_size:107374182400,file_size:100,manager:1",
|
||||
Name = "trial",
|
||||
Price = 0m,
|
||||
Visible = false
|
||||
@ -78,7 +78,7 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
new
|
||||
{
|
||||
Tenant = -2,
|
||||
Features = "audit,ldap,sso,whitelabel,restore,thirdparty,total_size:107374182400,file_size:1024,manager:1",
|
||||
Features = "audit,ldap,sso,whitelabel,restore,thirdparty,audit,total_size:107374182400,file_size:1024,manager:1",
|
||||
Name = "admin",
|
||||
Price = 30m,
|
||||
ProductId = "1002",
|
||||
@ -87,7 +87,7 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
new
|
||||
{
|
||||
Tenant = -3,
|
||||
Features = "free,thirdparty,total_size:2147483648,manager:1,room:12,usersInRoom:3",
|
||||
Features = "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3",
|
||||
Name = "startup",
|
||||
Price = 0m,
|
||||
Visible = false
|
||||
|
@ -67,7 +67,7 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
new
|
||||
{
|
||||
Tenant = -1,
|
||||
Features = "trial,audit,ldap,sso,whitelabel,restore,thirdparty,total_size:107374182400,file_size:100,manager:1",
|
||||
Features = "trial,audit,ldap,sso,whitelabel,restore,thirdparty,audit,total_size:107374182400,file_size:100,manager:1",
|
||||
Name = "trial",
|
||||
Price = 0m,
|
||||
Visible = false
|
||||
@ -75,7 +75,7 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
new
|
||||
{
|
||||
Tenant = -2,
|
||||
Features = "audit,ldap,sso,whitelabel,restore,thirdparty,total_size:107374182400,file_size:1024,manager:1",
|
||||
Features = "audit,ldap,sso,whitelabel,restore,thirdparty,audit,total_size:107374182400,file_size:1024,manager:1",
|
||||
Name = "admin",
|
||||
Price = 30m,
|
||||
ProductId = "1002",
|
||||
@ -84,7 +84,7 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
new
|
||||
{
|
||||
Tenant = -3,
|
||||
Features = "free,thirdparty,total_size:2147483648,manager:1,room:12,usersInRoom:3",
|
||||
Features = "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3",
|
||||
Name = "startup",
|
||||
Price = 0m,
|
||||
Visible = false
|
||||
|
@ -111,19 +111,19 @@ public partial class CoreDbContextMigrate : Migration
|
||||
schema: "onlyoffice",
|
||||
table: "tenants_quota",
|
||||
columns: new[] { "tenant", "description", "features", "name", "visible" },
|
||||
values: new object[] { -3, null, "free,thirdparty,total_size:2147483648,manager:1,room:12,usersInRoom:3", "startup", false });
|
||||
values: new object[] { -3, null, "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3", "startup", false });
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
schema: "onlyoffice",
|
||||
table: "tenants_quota",
|
||||
columns: new[] { "tenant", "description", "features", "name", "price", "product_id", "visible" },
|
||||
values: new object[] { -2, null, "audit,ldap,sso,whitelabel,restore,thirdparty,total_size:107374182400,file_size:1024,manager:1", "admin", 30m, "1002", true });
|
||||
values: new object[] { -2, null, "audit,ldap,sso,whitelabel,restore,thirdparty,audit,total_size:107374182400,file_size:1024,manager:1", "admin", 30m, "1002", true });
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
schema: "onlyoffice",
|
||||
table: "tenants_quota",
|
||||
columns: new[] { "tenant", "description", "features", "name", "visible" },
|
||||
values: new object[] { -1, null, "trial,audit,ldap,sso,whitelabel,restore,thirdparty,total_size:107374182400,file_size:100,manager:1", "trial", false });
|
||||
values: new object[] { -1, null, "trial,audit,ldap,sso,whitelabel,restore,thirdparty,audit,total_size:107374182400,file_size:100,manager:1", "trial", false });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "last_modified_tenants_quotarow",
|
||||
|
@ -65,7 +65,7 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
new
|
||||
{
|
||||
Tenant = -1,
|
||||
Features = "trial,audit,ldap,sso,whitelabel,restore,thirdparty,total_size:107374182400,file_size:100,manager:1",
|
||||
Features = "trial,audit,ldap,sso,whitelabel,restore,thirdparty,audit,total_size:107374182400,file_size:100,manager:1",
|
||||
Name = "trial",
|
||||
Price = 0m,
|
||||
Visible = false
|
||||
@ -73,7 +73,7 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
new
|
||||
{
|
||||
Tenant = -2,
|
||||
Features = "audit,ldap,sso,whitelabel,restore,thirdparty,total_size:107374182400,file_size:1024,manager:1",
|
||||
Features = "audit,ldap,sso,whitelabel,restore,thirdparty,audit,total_size:107374182400,file_size:1024,manager:1",
|
||||
Name = "admin",
|
||||
Price = 30m,
|
||||
ProductId = "1002",
|
||||
@ -82,7 +82,7 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
new
|
||||
{
|
||||
Tenant = -3,
|
||||
Features = "free,thirdparty,total_size:2147483648,manager:1,room:12,usersInRoom:3",
|
||||
Features = "free,thirdparty,audit,total_size:2147483648,manager:1,room:12,usersInRoom:3",
|
||||
Name = "startup",
|
||||
Price = 0m,
|
||||
Visible = false
|
||||
|
@ -73,7 +73,7 @@
|
||||
"PortalAccessSubTitle": "Bu bölmə sizə istifadəçiləri portala təhlükəsiz və rahat giriş imkanı ilə təmin etmək imkanı verir",
|
||||
"PortalNameEmpty": "Hesab adı boşdur",
|
||||
"PortalNameIncorrect": "Yanlış hesab adı",
|
||||
"PortalNameLength": "Hesab adı ən az 6, ən çox 50 işarədən ibarət ola bilər",
|
||||
"PortalNameLength": "Hesab adı ən az 3, ən çox 50 işarədən ibarət ola bilər",
|
||||
"PortalRenaming": "Portalın Adının dəyişdirilməsi",
|
||||
"PortalRenamingDescription": "Burada portal ünvanınızı dəyişə bilərsiniz.",
|
||||
"PortalRenamingLabelText": "Yeni portal adı",
|
||||
|
@ -72,7 +72,7 @@
|
||||
"PortalAccessSubTitle": "Този раздел Ви позволява да предоставите на потребителите безопасни и удобни начини за достъп до портала.",
|
||||
"PortalNameEmpty": "Името на профила е празно",
|
||||
"PortalNameIncorrect": "Неправилно име на профила",
|
||||
"PortalNameLength": "Името на профила трябва да бъде дълго между 6 и 50 знака",
|
||||
"PortalNameLength": "Името на профила трябва да бъде дълго между 3 и 50 знака",
|
||||
"PortalRenaming": "Преименуване на портала",
|
||||
"PortalRenamingDescription": "Тук можете да промените адреса на вашия портал.",
|
||||
"PortalRenamingLabelText": "Ново име на портала",
|
||||
|
@ -71,7 +71,7 @@
|
||||
"PortalAccessSubTitle": "Tato sekce umožňuje poskytnout uživatelům bezpečný a pohodlný způsob přístupu k portálu.",
|
||||
"PortalNameEmpty": "Název účtu je prázdný",
|
||||
"PortalNameIncorrect": "Nesprávný název účtu",
|
||||
"PortalNameLength": "Název účtu musí mít délku od 6 do 50 znaků",
|
||||
"PortalNameLength": "Název účtu musí mít délku od 3 do 50 znaků",
|
||||
"PortalRenaming": "Přejmenování portálu",
|
||||
"PortalRenamingDescription": "Zde můžete změnit Vaši adresu portálu.",
|
||||
"PortalRenamingLabelText": "Nový název portálu",
|
||||
|
@ -73,7 +73,7 @@
|
||||
"PortalAccessSubTitle": "In diesem Bereich können Sie den Benutzern einen sicheren und nahtlosen Zugang zum Portal gewähren.",
|
||||
"PortalNameEmpty": "Der Kontoname ist leer",
|
||||
"PortalNameIncorrect": "Inkorrekter Kontoname",
|
||||
"PortalNameLength": "Der Kontoname muss zwischen 6 und 50 Zeichen lang sein",
|
||||
"PortalNameLength": "Der Kontoname muss zwischen 3 und 50 Zeichen lang sein",
|
||||
"PortalRenaming": "Portalumbenennung",
|
||||
"PortalRenamingDescription": "Hier können Sie Ihre Portaladresse ändern.",
|
||||
"PortalRenamingLabelText": "Neuer Portalname",
|
||||
|
@ -68,7 +68,7 @@
|
||||
"PortalAccessSubTitle": "Αυτή η ενότητα σάς επιτρέπει να παρέχετε στους χρήστες ασφαλείς και βολικούς τρόπους πρόσβασης στην πύλη.",
|
||||
"PortalNameEmpty": "Το όνομα λογαριασμού είναι κενό",
|
||||
"PortalNameIncorrect": "Λανθασμένο όνομα λογαριασμού",
|
||||
"PortalNameLength": "Το όνομα του λογαριασμού πρέπει να έχει μήκος μεταξύ 6 και 50 χαρακτήρων",
|
||||
"PortalNameLength": "Το όνομα του λογαριασμού πρέπει να έχει μήκος μεταξύ 3 και 50 χαρακτήρων",
|
||||
"PortalRenaming": "Μετονομασία πύλης",
|
||||
"PortalRenamingDescription": "Εδώ μπορείτε να αλλάξετε τη διεύθυνση της πύλης σας.",
|
||||
"PortalRenamingLabelText": "Νέο όνομα πύλης",
|
||||
|
@ -136,7 +136,7 @@
|
||||
"PortalIntegration": "Space integration",
|
||||
"PortalNameEmpty": "Account name is empty",
|
||||
"PortalNameIncorrect": "Incorrect account name",
|
||||
"PortalNameLength": "The account name must be between 6 and 50 characters long",
|
||||
"PortalNameLength": "The account name must be between 3 and 50 characters long",
|
||||
"PortalRenaming": "Space Renaming",
|
||||
"PortalRenamingDescription": "Here you can change your space address.",
|
||||
"PortalRenamingLabelText": "New space name",
|
||||
|
@ -28,6 +28,7 @@
|
||||
"Folders": "Folders",
|
||||
"FormTemplates": "Form templates",
|
||||
"LinkCopySuccess": "Link has been copied to the clipboard",
|
||||
"LinkValidTime": "This link is valid for {{days_count}} days only",
|
||||
"MediaLoadError": "Media file could not be loaded",
|
||||
"MobileAndroid": "Get ONLYOFFICE Documents on Google Play",
|
||||
"MobileIos": "Download ONLYOFFICE Documents on the App Store",
|
||||
|
@ -73,7 +73,7 @@
|
||||
"PortalAccessSubTitle": "Esta sección le permite ofrecer a los usuarios formas seguras y cómodas de acceder al portal.",
|
||||
"PortalNameEmpty": "Nombre de cuenta está vacío",
|
||||
"PortalNameIncorrect": "Nombre de cuenta incorrecto",
|
||||
"PortalNameLength": "El nombre de cuenta debe tener entre 6 y 50 caracteres de longitud",
|
||||
"PortalNameLength": "El nombre de cuenta debe tener entre 3 y 50 caracteres de longitud",
|
||||
"PortalRenaming": "Cambio del nombre de portal",
|
||||
"PortalRenamingDescription": "Puede cambiar la dirección de su portal aquí.",
|
||||
"PortalRenamingLabelText": "Nombre de portal nuevo",
|
||||
|
@ -71,7 +71,7 @@
|
||||
"PortalAccessSubTitle": "Tämän osan avulla voit tarjota käyttäjille turvallisia ja käteviä tapoja käyttää portaalia.",
|
||||
"PortalNameEmpty": "Tilin nimi on tyhjä",
|
||||
"PortalNameIncorrect": "Virheellinen tilin nimi",
|
||||
"PortalNameLength": "Tilin nimen on oltava 6-50 merkkiä pitkä",
|
||||
"PortalNameLength": "Tilin nimen on oltava 3-50 merkkiä pitkä",
|
||||
"PortalRenaming": "Portaalin uudelleennimeäminen",
|
||||
"PortalRenamingDescription": "Tässä voit vaihtaa portaalisi osoitteen.",
|
||||
"PortalRenamingLabelText": "Uusi portaalin nimi",
|
||||
|
@ -73,7 +73,7 @@
|
||||
"PortalAccessSubTitle": "Cette section vous permet de fournir aux utilisateurs des moyens sûrs et pratiques d'accéder au portail.",
|
||||
"PortalNameEmpty": "Nom de compte est vide",
|
||||
"PortalNameIncorrect": "Nom de compte incorrect",
|
||||
"PortalNameLength": "Le nom du compte doit comporter entre 6 et 50 caractères",
|
||||
"PortalNameLength": "Le nom du compte doit comporter entre 3 et 50 caractères",
|
||||
"PortalRenaming": "Changement de nom du portail",
|
||||
"PortalRenamingDescription": "Ici vous pouvez changer l'adresse du portail.",
|
||||
"PortalRenamingLabelText": "Nouveau nom du portail",
|
||||
|
@ -68,7 +68,7 @@
|
||||
"PortalAccessSubTitle": "Այս բաժինը թույլ է տալիս օգտվողներին տրամադրել կայքէջ մուտք գործելու անվտանգ և հարմար եղանակներ:",
|
||||
"PortalNameEmpty": "Հաշվի անունը դատարկ է",
|
||||
"PortalNameIncorrect": "Հաշվի սխալ անուն",
|
||||
"PortalNameLength": "Հաշվի անունը պետք է լինի 6-ից 50 նիշ",
|
||||
"PortalNameLength": "Հաշվի անունը պետք է լինի 3-ից 50 նիշ",
|
||||
"PortalRenaming": "Կայքէջի վերանվանում",
|
||||
"PortalRenamingDescription": "Այստեղ Դուք կարող եք փոխել Ձեր կայքէջի հասցեն:",
|
||||
"PortalRenamingLabelText": "Նոր կայքէջի անուն",
|
||||
|
@ -73,7 +73,7 @@
|
||||
"PortalAccessSubTitle": "Questa sezione consente di fornire agli utenti modi sicuri e convenienti per accedere al portale.",
|
||||
"PortalNameEmpty": "Nome account vuoto",
|
||||
"PortalNameIncorrect": "Nome account errato",
|
||||
"PortalNameLength": "Il nome dell'account deve contenere da 6 a 50 caratteri",
|
||||
"PortalNameLength": "Il nome dell'account deve contenere da 3 a 50 caratteri",
|
||||
"PortalRenaming": "Ridenominazione del portale",
|
||||
"PortalRenamingDescription": "Qui tu puoi cambiare il tuo indirizzo portale.",
|
||||
"PortalRenamingLabelText": "Nome del portale nuovo",
|
||||
|
@ -72,7 +72,7 @@
|
||||
"PortalAccessSubTitle": "このセクションでは、ユーザーがポータルにアクセスするための安全で便利な方法を提供することができます。",
|
||||
"PortalNameEmpty": "アカウント名が空です。",
|
||||
"PortalNameIncorrect": "アカウント名が無効です。",
|
||||
"PortalNameLength": "アカウント名は6~50文字がある必要です。",
|
||||
"PortalNameLength": "アカウント名は3~50文字がある必要です。",
|
||||
"PortalRenaming": "ポータル改名",
|
||||
"PortalRenamingDescription": "ここではポータルアドレスを変更できます。",
|
||||
"PortalRenamingLabelText": "新のポータル名",
|
||||
|
@ -68,7 +68,7 @@
|
||||
"PortalAccessSubTitle": "이 섹션에서는 사용자에게 안전하고 편리한 포털 액세스 방법을 제공할 수 있습니다.",
|
||||
"PortalNameEmpty": "계정 이름이 비어 있습니다",
|
||||
"PortalNameIncorrect": "계정 이름이 잘못되었습니다",
|
||||
"PortalNameLength": "계정 이름은 6~50글자여야 합니다",
|
||||
"PortalNameLength": "계정 이름은 3~50글자여야 합니다",
|
||||
"PortalRenaming": "포털 이름 변경",
|
||||
"PortalRenamingDescription": "여기에서 포털 주소를 변경할 수 있습니다.",
|
||||
"PortalRenamingLabelText": "새 포털 이름",
|
||||
|
@ -66,7 +66,7 @@
|
||||
"PortalAccessSubTitle": "ພາກນີ້ຊ່ວຍໃຫ້ທ່ານສາມາດໃຫ້ຜູ້ໃຊ້ມີວິທີທີ່ປອດໄພແລະສະດວກໃນການເຂົ້າເຖິງປະຕູ. ",
|
||||
"PortalNameEmpty": "ບັນຊີ ຊື່ ແມ່ນ ເປົ່າ",
|
||||
"PortalNameIncorrect": "ບໍ່ຖືກຕ້ອງ ບັນຊີ ຊື່ ",
|
||||
"PortalNameLength": "ຊື່ບັນຊີຕ້ອງມີຄວາມຍາວລະຫວ່າງ 6 ຫາ 50 ຕົວອັກສອນ",
|
||||
"PortalNameLength": "ຊື່ບັນຊີຕ້ອງມີຄວາມຍາວລະຫວ່າງ 3 ຫາ 50 ຕົວອັກສອນ",
|
||||
"PortalRenaming": "ປະຕູ ການ ປ່ຽນຊື່ ",
|
||||
"PortalRenamingDescription": "ທີ່ນີ້ທ່ານສາມາດປ່ຽນທີ່ຢູ່ປະຕູຂອງເຈົ້າໄດ້.",
|
||||
"PortalRenamingLabelText": "ໃໝ່ ປະຕູ ຊື່ ",
|
||||
|
@ -71,7 +71,7 @@
|
||||
"PortalAccessSubTitle": "Šī sadaļa ļauj lietotājiem nodrošināt drošus un ērtus veidus, kā piekļūt portālam.",
|
||||
"PortalNameEmpty": "Konta nosaukums ir tukšs",
|
||||
"PortalNameIncorrect": "Nepareizs konta nosaukums",
|
||||
"PortalNameLength": "Konta nosaukumam ir jābūt no 6 līdz 50 rakstzīmēm garam",
|
||||
"PortalNameLength": "Konta nosaukumam ir jābūt no 3 līdz 50 rakstzīmēm garam",
|
||||
"PortalRenaming": "Portāla pārdēvēšana",
|
||||
"PortalRenamingDescription": "Šeit jūs varat mainīt savu portāla adresi.",
|
||||
"PortalRenamingLabelText": "Jauns portāla nosaukums",
|
||||
|
@ -71,7 +71,7 @@
|
||||
"PortalAccessSubTitle": "In dit gedeelte kunt u gebruikers veilige en handige manieren bieden om toegang te krijgen tot het portaal.",
|
||||
"PortalNameEmpty": "Accountnaam is leeg",
|
||||
"PortalNameIncorrect": "Onjuiste accountnaam",
|
||||
"PortalNameLength": "De naam van de account moet tussen 6 en 50 tekens lang zijn",
|
||||
"PortalNameLength": "De naam van de account moet tussen 3 en 50 tekens lang zijn",
|
||||
"PortalRenaming": "Hernoemen Portaal",
|
||||
"PortalRenamingDescription": "Hier kunt u uw portaaladres veranderen.",
|
||||
"PortalRenamingLabelText": "Nieuwe portaalnaam",
|
||||
|
@ -71,7 +71,7 @@
|
||||
"PortalAccessSubTitle": "Dana sekcja umożliwia zapewnienie użytkownikom bezpiecznych i wygodnych metod dostępu do portalu.",
|
||||
"PortalNameEmpty": "Nazwa konta jest pusta",
|
||||
"PortalNameIncorrect": "Nieprawidłowa nazwa konta",
|
||||
"PortalNameLength": "Nazwa konta musi zawierać od 6 do 50 znaków",
|
||||
"PortalNameLength": "Nazwa konta musi zawierać od 3 do 50 znaków",
|
||||
"PortalRenaming": "Zmiana nazwy portalu",
|
||||
"PortalRenamingDescription": "Tutaj możesz zmienić adres portalu.",
|
||||
"PortalRenamingLabelText": "Nowa nazwa portalu",
|
||||
|
@ -73,7 +73,7 @@
|
||||
"PortalAccessSubTitle": "Esta seção permite que você forneça aos usuários formas seguras e convenientes de acessar o portal.",
|
||||
"PortalNameEmpty": "Nome da conta está vazio",
|
||||
"PortalNameIncorrect": "Nome da conta incorreto",
|
||||
"PortalNameLength": "O nome da conta deve ter entre 6 e 50 caracteres",
|
||||
"PortalNameLength": "O nome da conta deve ter entre 3 e 50 caracteres",
|
||||
"PortalRenaming": "Renomear portal",
|
||||
"PortalRenamingDescription": "Aqui, você pode alterar o endereço do seu portal.",
|
||||
"PortalRenamingLabelText": "Nome do novo portal",
|
||||
|
@ -68,7 +68,7 @@
|
||||
"PortalAccessSubTitle": "Esta secção permite-lhe fornecer aos utilizadores formas seguras e convenientes de aceder ao portal.",
|
||||
"PortalNameEmpty": "Não colocou um nome para a conta",
|
||||
"PortalNameIncorrect": "Nome de conta incorreto",
|
||||
"PortalNameLength": "O nome da conta tem de ter entre 6 e 50 caracteres",
|
||||
"PortalNameLength": "O nome da conta tem de ter entre 3 e 50 caracteres",
|
||||
"PortalRenaming": "Renomeação do Portal",
|
||||
"PortalRenamingDescription": "Aqui pode mudar o endereço do seu portal.",
|
||||
"PortalRenamingLabelText": "Novo nome de portal",
|
||||
|
@ -68,7 +68,7 @@
|
||||
"PortalAccessSubTitle": "Această secțiune va permite să le oferă utilizatorilor accesul sigur și convenabil la portal.",
|
||||
"PortalNameEmpty": "Denumirea contului este necompletată",
|
||||
"PortalNameIncorrect": "Denumirea contului incorectă",
|
||||
"PortalNameLength": "Denumirea contului trebuie să conțină de la 6 până la 50 de caractere",
|
||||
"PortalNameLength": "Denumirea contului trebuie să conțină de la 3 până la 50 de caractere",
|
||||
"PortalRenaming": "Redenumirea portalului",
|
||||
"PortalRenamingDescription": "Aici puteți schimba adresa de portal dvs.",
|
||||
"PortalRenamingLabelText": "O nouă denumire de portal",
|
||||
|
@ -136,7 +136,7 @@
|
||||
"PortalIntegration": "Интеграция с порталом",
|
||||
"PortalNameEmpty": "Поле имя аккаунта не заполнено",
|
||||
"PortalNameIncorrect": "Неверное имя портала",
|
||||
"PortalNameLength": "Имя учетной записи должно быть от 6 до 50 символов",
|
||||
"PortalNameLength": "Имя учетной записи должно быть от 3 до 50 символов",
|
||||
"PortalRenaming": "Изменение имени портала",
|
||||
"PortalRenamingDescription": "Здесь вы можете изменить адрес портала.",
|
||||
"PortalRenamingLabelText": "Новое имя портала",
|
||||
|
@ -28,6 +28,7 @@
|
||||
"Folders": "Папки",
|
||||
"FormTemplates": "Шаблоны форм",
|
||||
"LinkCopySuccess": "Ссылка скопирована в буфер обмена",
|
||||
"LinkValidTime": "Эта ссылка действительна только {{days_count}} дней",
|
||||
"MediaLoadError": "Медиа файл не может быть загружен",
|
||||
"MobileAndroid": "Скачать ONLYOFFICE Документы в Google Play",
|
||||
"MobileIos": "Скачать ONLYOFFICE Документы в App Store",
|
||||
|
@ -71,7 +71,7 @@
|
||||
"PortalAccessSubTitle": "Tu môžete vytvoriť pre používateľov bezpečné a pohodlné spôsoby prístupu na portál.",
|
||||
"PortalNameEmpty": "Názov účtu je prázdny",
|
||||
"PortalNameIncorrect": "Nesprávny názov účtu",
|
||||
"PortalNameLength": "Názov účtu musí mať 6 až 50 znakov",
|
||||
"PortalNameLength": "Názov účtu musí mať 3 až 50 znakov",
|
||||
"PortalRenaming": "Premenovanie portálu",
|
||||
"PortalRenamingDescription": "Tu môžete zmeniť adresu portálu.",
|
||||
"PortalRenamingLabelText": "Nový názov portálu",
|
||||
|
@ -71,7 +71,7 @@
|
||||
"PortalAccessSubTitle": "Ta razdelek omogoča uporabnikom varne in udobne načine za dostop do portala.",
|
||||
"PortalNameEmpty": "Ime računa je prazno",
|
||||
"PortalNameIncorrect": "Napačno ime računa",
|
||||
"PortalNameLength": "Ime računa mora imeti dolžino od 6 do 50 znakov",
|
||||
"PortalNameLength": "Ime računa mora imeti dolžino od 3 do 50 znakov",
|
||||
"PortalRenaming": "Preimenovanje portala",
|
||||
"PortalRenamingDescription": "Tukaj lahko spremenite naslov vašega portala.",
|
||||
"PortalRenamingLabelText": "Novo ime portala",
|
||||
|
@ -71,7 +71,7 @@
|
||||
"PortalAccessSubTitle": "Bu bölüm, kullanıcılara portala erişmeleri için güvenli ve uygun yollar sağlamanıza olanak tanır.",
|
||||
"PortalNameEmpty": "Hesap adı boş",
|
||||
"PortalNameIncorrect": "Yanlış hesap adı",
|
||||
"PortalNameLength": "Hesap adı 6 ila 50 karakter uzunluğunda olmalıdır",
|
||||
"PortalNameLength": "Hesap adı 3 ila 50 karakter uzunluğunda olmalıdır",
|
||||
"PortalRenaming": "Portal Yeniden Adlandırma",
|
||||
"PortalRenamingDescription": "Buradan portal adresinizi değiştirebilirsiniz.",
|
||||
"PortalRenamingLabelText": "Yeni portal adı",
|
||||
|
@ -71,7 +71,7 @@
|
||||
"PortalAccessSubTitle": "У цьому розділі можна надати користувачам безпечні та зручні способи доступу до порталу.",
|
||||
"PortalNameEmpty": "Ім'я облікового запису порожнє",
|
||||
"PortalNameIncorrect": "Неправильне ім'я облікового запису",
|
||||
"PortalNameLength": "Довжина імені облікового запису має бути від 6 до 50 символів",
|
||||
"PortalNameLength": "Довжина імені облікового запису має бути від 3 до 50 символів",
|
||||
"PortalRenaming": "Перейменування порталу",
|
||||
"PortalRenamingDescription": "Тут ви можете змінити адресу вашого порталу.",
|
||||
"PortalRenamingLabelText": "Нове ім'я порталу",
|
||||
|
@ -71,7 +71,7 @@
|
||||
"PortalAccessSubTitle": "Phần này cho phép bạn cung cấp cho người dùng những cách an toàn và thuận tiện để truy cập cổng thông tin.",
|
||||
"PortalNameEmpty": "Tên tài khoản trống",
|
||||
"PortalNameIncorrect": "Tên tài khoản không chính xác",
|
||||
"PortalNameLength": "Tên tài khoản phải dài từ 6 đến 50 ký tự",
|
||||
"PortalNameLength": "Tên tài khoản phải dài từ 3 đến 50 ký tự",
|
||||
"PortalRenaming": "Đang đổi tên cổng",
|
||||
"PortalRenamingDescription": "Ở đây bạn có thể thay đổi địa chỉ cổng thông tin của bạn.",
|
||||
"PortalRenamingLabelText": "Tên cổng thông tin mới",
|
||||
|
@ -73,7 +73,7 @@
|
||||
"PortalAccessSubTitle": "这一部分允许您为用户提供安全又方便的方式来访问门户网站。",
|
||||
"PortalNameEmpty": "账户名称为空",
|
||||
"PortalNameIncorrect": "账户名称不正确",
|
||||
"PortalNameLength": "账户名称的长度必须在6至50个字符之间",
|
||||
"PortalNameLength": "账户名称的长度必须在3至50个字符之间",
|
||||
"PortalRenaming": "门户重命名",
|
||||
"PortalRenamingDescription": "在此处,您可以更改您的门户地址。",
|
||||
"PortalRenamingLabelText": "新门户名称",
|
||||
|
@ -27,6 +27,7 @@ const ConvertDialogComponent = (props) => {
|
||||
isRecentFolder,
|
||||
isFavoritesFolder,
|
||||
isShareFolder,
|
||||
setIsConvertSingleFile,
|
||||
} = props;
|
||||
|
||||
let rootFolderTitle = "";
|
||||
@ -50,6 +51,7 @@ const ConvertDialogComponent = (props) => {
|
||||
onClose();
|
||||
|
||||
if (convertSingleFile) {
|
||||
setIsConvertSingleFile(true);
|
||||
const item = {
|
||||
fileId: convertItem.id,
|
||||
toFolderId: folderId,
|
||||
@ -160,7 +162,11 @@ export default inject(
|
||||
isFavoritesFolder,
|
||||
isShareFolder,
|
||||
} = treeFoldersStore;
|
||||
const { convertUploadedFiles, convertFile } = uploadDataStore;
|
||||
const {
|
||||
convertUploadedFiles,
|
||||
convertFile,
|
||||
setIsConvertSingleFile,
|
||||
} = uploadDataStore;
|
||||
const {
|
||||
storeOriginalFiles,
|
||||
setStoreOriginal,
|
||||
@ -187,6 +193,7 @@ export default inject(
|
||||
isRecentFolder,
|
||||
isFavoritesFolder,
|
||||
isShareFolder,
|
||||
setIsConvertSingleFile,
|
||||
};
|
||||
}
|
||||
)(withRouter(observer(ConvertDialog)));
|
||||
|
@ -72,7 +72,12 @@ const ExternalLinks = ({
|
||||
|
||||
const copyLink = (link) => {
|
||||
if (link) {
|
||||
toastr.success(t("Translations:LinkCopySuccess"));
|
||||
toastr.success(
|
||||
`${t("Translations:LinkCopySuccess")}. ${t(
|
||||
"Translations:LinkValidTime",
|
||||
{ days_count: 7 }
|
||||
)}`
|
||||
);
|
||||
copy(link);
|
||||
}
|
||||
};
|
||||
|
@ -196,7 +196,7 @@ const InviteInput = ({
|
||||
};
|
||||
|
||||
const closeInviteInputPanel = (e) => {
|
||||
if (e?.target.tagName.toUpperCase() == "INPUT") return;
|
||||
// if (e?.target.tagName.toUpperCase() == "INPUT") return;
|
||||
|
||||
setSearchPanelVisible(false);
|
||||
};
|
||||
|
@ -17,7 +17,6 @@ const StyledModalDialog = styled(ModalDialog)`
|
||||
}
|
||||
`;
|
||||
const SelectFolderDialogAsideView = ({
|
||||
theme,
|
||||
t,
|
||||
isPanelVisible,
|
||||
onClose,
|
||||
@ -41,7 +40,6 @@ const SelectFolderDialogAsideView = ({
|
||||
const isLoaded = folderId && resultingFolderTree;
|
||||
return (
|
||||
<StyledModalDialog
|
||||
theme={theme}
|
||||
visible={isPanelVisible}
|
||||
onClose={onClose}
|
||||
withoutBodyScroll
|
||||
@ -49,11 +47,10 @@ const SelectFolderDialogAsideView = ({
|
||||
displayType="aside"
|
||||
isDoubleFooterLine
|
||||
>
|
||||
<ModalDialog.Header theme={theme}>
|
||||
<ModalDialog.Header>
|
||||
<StyledAsideHeader>
|
||||
{withFileSelectDialog && (
|
||||
<IconButton
|
||||
theme={theme}
|
||||
className="selection-panel_aside-header-icon"
|
||||
size="16"
|
||||
iconName="/static/images/arrow.path.react.svg"
|
||||
@ -63,8 +60,8 @@ const SelectFolderDialogAsideView = ({
|
||||
{dialogName}
|
||||
</StyledAsideHeader>
|
||||
</ModalDialog.Header>
|
||||
<ModalDialog.Body theme={theme}>
|
||||
<StyledAsideBody theme={theme} header={!!header} footer={!!footer}>
|
||||
<ModalDialog.Body>
|
||||
<StyledAsideBody header={!!header} footer={!!footer}>
|
||||
<div className="selection-panel_aside-body">
|
||||
<div className="selection-panel_aside-header">
|
||||
<div>{header}</div>
|
||||
@ -86,7 +83,6 @@ const SelectFolderDialogAsideView = ({
|
||||
<FolderTreeBody
|
||||
selectionFiles={selectionFiles}
|
||||
parentId={parentId}
|
||||
theme={theme}
|
||||
folderTree={resultingFolderTree}
|
||||
onSelect={onSelectFolder}
|
||||
withoutProvider={withoutProvider}
|
||||
@ -109,7 +105,6 @@ const SelectFolderDialogAsideView = ({
|
||||
{footer}
|
||||
<div>
|
||||
<Button
|
||||
theme={theme}
|
||||
className="select-folder-dialog-buttons-save"
|
||||
primary
|
||||
scale
|
||||
|
@ -191,7 +191,6 @@ class SelectFolderDialog extends React.Component {
|
||||
render() {
|
||||
const {
|
||||
t,
|
||||
theme,
|
||||
isPanelVisible,
|
||||
zIndex,
|
||||
withoutProvider,
|
||||
@ -236,7 +235,6 @@ class SelectFolderDialog extends React.Component {
|
||||
return displayType === "aside" ? (
|
||||
<SelectFolderDialogAsideView
|
||||
selectionFiles={selectionFiles}
|
||||
theme={theme}
|
||||
t={t}
|
||||
isPanelVisible={isPanelVisible}
|
||||
zIndex={zIndex}
|
||||
@ -265,7 +263,6 @@ class SelectFolderDialog extends React.Component {
|
||||
<SelectionPanel
|
||||
selectionFiles={selectionFiles}
|
||||
t={t}
|
||||
theme={theme}
|
||||
isPanelVisible={isPanelVisible}
|
||||
onClose={this.onClose}
|
||||
withoutProvider={withoutProvider}
|
||||
@ -321,7 +318,6 @@ export default inject(
|
||||
selectedFolderStore,
|
||||
selectFolderDialogStore,
|
||||
filesStore,
|
||||
auth,
|
||||
filesActionsStore,
|
||||
},
|
||||
{ selectedId }
|
||||
@ -347,12 +343,9 @@ export default inject(
|
||||
securityItem,
|
||||
} = selectFolderDialogStore;
|
||||
|
||||
const { settingsStore } = auth;
|
||||
const { theme } = settingsStore;
|
||||
const selectedFolderId = selectedId ? selectedId : id;
|
||||
|
||||
return {
|
||||
theme: theme,
|
||||
storeFolderId: selectedFolderId,
|
||||
providerKey,
|
||||
folderTitle,
|
||||
|
@ -22,7 +22,6 @@ const FilesListBody = ({
|
||||
displayType,
|
||||
folderId,
|
||||
fileId,
|
||||
theme,
|
||||
page,
|
||||
folderSelection,
|
||||
getIcon,
|
||||
@ -92,13 +91,8 @@ const FilesListBody = ({
|
||||
return (
|
||||
<div style={style}>
|
||||
<StyledItemsLoader key="loader">
|
||||
<Loader
|
||||
theme={theme}
|
||||
type="oval"
|
||||
size="16px"
|
||||
className="panel-loader"
|
||||
/>
|
||||
<Text theme={theme} as="span">
|
||||
<Loader type="oval" size="16px" className="panel-loader" />
|
||||
<Text as="span">
|
||||
{t("Common:LoadingProcessing")} {t("Common:LoadingDescription")}
|
||||
</Text>
|
||||
</StyledItemsLoader>
|
||||
@ -145,7 +139,6 @@ const FilesListBody = ({
|
||||
return (
|
||||
<div style={style}>
|
||||
<FilesListRow
|
||||
theme={theme}
|
||||
displayType={displayType}
|
||||
index={index}
|
||||
onSelectFile={onSelectFile}
|
||||
@ -169,7 +162,6 @@ const FilesListBody = ({
|
||||
<AutoSizer>
|
||||
{({ width, height }) => (
|
||||
<InfiniteLoader
|
||||
theme={theme}
|
||||
ref={filesListRef}
|
||||
isItemLoaded={isItemLoaded}
|
||||
itemCount={itemCount}
|
||||
@ -177,7 +169,6 @@ const FilesListBody = ({
|
||||
>
|
||||
{({ onItemsRendered, ref }) => (
|
||||
<List
|
||||
theme={theme}
|
||||
height={maxHeight}
|
||||
itemCount={itemCount}
|
||||
itemSize={48}
|
||||
@ -196,7 +187,6 @@ const FilesListBody = ({
|
||||
{!hasNextPage && itemCount === 0 && (
|
||||
<div className="select-file-dialog_empty-container">
|
||||
<EmptyContainer
|
||||
theme={theme}
|
||||
headerText={t("Files:EmptyFolderHeader")}
|
||||
imageSrc="/static/images/empty.screen.react.svg"
|
||||
/>
|
||||
|
@ -8,7 +8,6 @@ const FilesListRow = ({
|
||||
index,
|
||||
onSelectFile,
|
||||
isChecked,
|
||||
theme,
|
||||
folderSelection,
|
||||
icon,
|
||||
item,
|
||||
@ -22,7 +21,6 @@ const FilesListRow = ({
|
||||
return (
|
||||
<StyledRow
|
||||
displayType={displayType}
|
||||
theme={theme}
|
||||
isChecked={isChecked}
|
||||
folderSelection={folderSelection}
|
||||
onClick={onFileClick}
|
||||
@ -36,7 +34,6 @@ const FilesListRow = ({
|
||||
<div className="selection-panel_checkbox">
|
||||
{!folderSelection && (
|
||||
<RadioButton
|
||||
//theme={theme}
|
||||
fontSize="13px"
|
||||
fontWeight="400"
|
||||
name={`${index}`}
|
||||
|
@ -113,7 +113,6 @@ class FilesListWrapper extends React.Component {
|
||||
render() {
|
||||
const {
|
||||
t,
|
||||
theme,
|
||||
onSelectFile,
|
||||
folderSelection = false,
|
||||
fileId,
|
||||
@ -124,7 +123,6 @@ class FilesListWrapper extends React.Component {
|
||||
|
||||
return (
|
||||
<FilesListBody
|
||||
theme={theme}
|
||||
files={files}
|
||||
onSelectFile={onSelectFile}
|
||||
hasNextPage={hasNextPage}
|
||||
@ -150,11 +148,7 @@ export default inject(
|
||||
setProviderKey,
|
||||
} = selectFolderDialogStore;
|
||||
|
||||
const { settingsStore } = auth;
|
||||
const { theme } = settingsStore;
|
||||
|
||||
return {
|
||||
theme: theme,
|
||||
storeFolderId: id,
|
||||
setResultingFolderId,
|
||||
setFolderTitle,
|
||||
|
@ -29,7 +29,6 @@ const SelectionPanelBody = ({
|
||||
filesListTitle,
|
||||
dialogName,
|
||||
primaryButtonName,
|
||||
theme,
|
||||
isLoading,
|
||||
onButtonClick,
|
||||
folderId,
|
||||
@ -53,7 +52,6 @@ const SelectionPanelBody = ({
|
||||
const isLoaded = folderId && resultingFolderTree;
|
||||
return (
|
||||
<StyledModalDialog
|
||||
theme={theme}
|
||||
visible={isPanelVisible}
|
||||
onClose={onClose}
|
||||
displayType="modal"
|
||||
@ -62,10 +60,10 @@ const SelectionPanelBody = ({
|
||||
isDoubleFooterLine
|
||||
autoMaxWidth
|
||||
>
|
||||
<ModalDialog.Header theme={theme} className={"select-panel-modal-header"}>
|
||||
<ModalDialog.Header className={"select-panel-modal-header"}>
|
||||
{dialogName}
|
||||
</ModalDialog.Header>
|
||||
<ModalDialog.Body theme={theme} className="select-file_body-modal-dialog">
|
||||
<ModalDialog.Body className="select-file_body-modal-dialog">
|
||||
<StyledBody header={!!header} footer={!!footer}>
|
||||
<div className="selection-panel_body">
|
||||
<div className="selection-panel_tree-body">
|
||||
@ -90,7 +88,6 @@ const SelectionPanelBody = ({
|
||||
{isLoaded ? (
|
||||
<FolderTreeBody
|
||||
selectionFiles={selectionFiles}
|
||||
theme={theme}
|
||||
folderTree={resultingFolderTree}
|
||||
onSelect={onSelectFolder}
|
||||
withoutProvider={withoutProvider}
|
||||
@ -111,11 +108,7 @@ const SelectionPanelBody = ({
|
||||
<div className="selection-panel_files-header">
|
||||
{header}
|
||||
|
||||
<Text
|
||||
color="#A3A9AE"
|
||||
theme={theme}
|
||||
className="selection-panel_title"
|
||||
>
|
||||
<Text color="#A3A9AE" className="selection-panel_title">
|
||||
{folderSelection
|
||||
? t("FolderContents", { folderTitle })
|
||||
: filesListTitle}
|
||||
@ -123,7 +116,6 @@ const SelectionPanelBody = ({
|
||||
</div>
|
||||
|
||||
<FilesListWrapper
|
||||
theme={theme}
|
||||
onSelectFile={onSelectFile}
|
||||
folderId={folderId}
|
||||
displayType={"modal"}
|
||||
@ -143,7 +135,6 @@ const SelectionPanelBody = ({
|
||||
<div>
|
||||
<Button
|
||||
id="select-file-modal-submit"
|
||||
theme={theme}
|
||||
className="select-file-modal-dialog-buttons-save"
|
||||
primary
|
||||
size="normal"
|
||||
@ -158,7 +149,6 @@ const SelectionPanelBody = ({
|
||||
/>
|
||||
<Button
|
||||
id="select-file-modal-cancel"
|
||||
theme={theme}
|
||||
className="modal-dialog-button"
|
||||
size="normal"
|
||||
label={t("Common:CancelButton")}
|
||||
|
@ -113,6 +113,9 @@ const StyledFileRow = styled(Row)`
|
||||
css`
|
||||
cursor: default;
|
||||
`}
|
||||
:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
`;
|
||||
class FileRow extends Component {
|
||||
|
@ -180,7 +180,7 @@ const PortalRenaming = (props) => {
|
||||
setErrorValue(t("PortalNameEmpty"));
|
||||
saveToSessionStorage("errorValue", t("PortalNameEmpty"));
|
||||
break;
|
||||
case value.length < 6 || value.length > 50:
|
||||
case value.length < 3 || value.length > 50:
|
||||
setErrorValue(t("PortalNameLength"));
|
||||
saveToSessionStorage("errorValue", t("PortalNameLength"));
|
||||
break;
|
||||
|
@ -967,6 +967,7 @@ class FilesActionStore {
|
||||
|
||||
switch (action) {
|
||||
case "archive":
|
||||
this.setGroupMenuBlocked(true);
|
||||
return moveToFolder(archiveRoomsId, items)
|
||||
.then(async (res) => {
|
||||
const lastResult = res && res[res.length - 1];
|
||||
@ -1022,8 +1023,12 @@ class FilesActionStore {
|
||||
setTimeout(() => clearSecondaryProgressData(), TIMEOUT);
|
||||
return toastr.error(err.message ? err.message : err);
|
||||
})
|
||||
.finally(() => clearActiveOperations(null, items));
|
||||
.finally(() => {
|
||||
clearActiveOperations(null, items);
|
||||
this.setGroupMenuBlocked(false);
|
||||
});
|
||||
case "unarchive":
|
||||
this.setGroupMenuBlocked(true);
|
||||
return moveToFolder(myRoomsId, items)
|
||||
.then(async (res) => {
|
||||
const lastResult = res && res[res.length - 1];
|
||||
@ -1062,7 +1067,10 @@ class FilesActionStore {
|
||||
setTimeout(() => clearSecondaryProgressData(), TIMEOUT);
|
||||
return toastr.error(err.message ? err.message : err);
|
||||
})
|
||||
.finally(() => clearActiveOperations(null, items));
|
||||
.finally(() => {
|
||||
clearActiveOperations(null, items);
|
||||
this.setGroupMenuBlocked(false);
|
||||
});
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@ -1894,7 +1902,7 @@ class FilesActionStore {
|
||||
)
|
||||
: null;
|
||||
|
||||
return openDocEditor(id, providerKey, tab);
|
||||
return openDocEditor(id, providerKey, tab, null, !canWebEdit);
|
||||
}
|
||||
|
||||
if (isMediaOrImage) {
|
||||
|
@ -16,6 +16,11 @@ import {
|
||||
fileCopyAs,
|
||||
} from "@docspace/common/api/files";
|
||||
import toastr from "@docspace/components/toast/toastr";
|
||||
import { isMobile } from "react-device-detect";
|
||||
import {
|
||||
isMobile as isMobileUtils,
|
||||
isTablet as isTabletUtils,
|
||||
} from "@docspace/components/utils/device";
|
||||
class UploadDataStore {
|
||||
authStore;
|
||||
treeFoldersStore;
|
||||
@ -45,6 +50,8 @@ class UploadDataStore {
|
||||
isUploading = false;
|
||||
isUploadingAndConversion = false;
|
||||
|
||||
isConvertSingleFile = false;
|
||||
|
||||
constructor(
|
||||
authStore,
|
||||
treeFoldersStore,
|
||||
@ -83,6 +90,10 @@ class UploadDataStore {
|
||||
}
|
||||
};
|
||||
|
||||
setIsConvertSingleFile = (isConvertSingleFile) => {
|
||||
this.isConvertSingleFile = isConvertSingleFile;
|
||||
};
|
||||
|
||||
updateUploadedFile = (id, info) => {
|
||||
const files = this.files.map((file) =>
|
||||
file.fileId === id ? { ...file, fileInfo: info } : file
|
||||
@ -230,10 +241,12 @@ class UploadDataStore {
|
||||
const secondConvertingWithPassword = file.hasOwnProperty("password");
|
||||
const conversionPositionIndex = file.hasOwnProperty("index");
|
||||
|
||||
const alreadyConverting = this.files.some(
|
||||
let alreadyConverting = this.files.some(
|
||||
(item) => item.fileId === file.fileId
|
||||
);
|
||||
|
||||
if (this.isConvertSingleFile) alreadyConverting = false;
|
||||
|
||||
if (this.converted && !alreadyConverting) {
|
||||
this.filesToConversion = [];
|
||||
this.convertFilesSize = 0;
|
||||
@ -261,6 +274,8 @@ class UploadDataStore {
|
||||
this.uploadedFilesHistory.push(file);
|
||||
}
|
||||
}
|
||||
|
||||
this.setIsConvertSingleFile(false);
|
||||
};
|
||||
|
||||
getNewPercent = (uploadedSize, indexOfFile) => {
|
||||
@ -396,7 +411,16 @@ class UploadDataStore {
|
||||
}
|
||||
|
||||
const percent = this.getConversationPercent(index + 1);
|
||||
this.setConversionPercent(percent);
|
||||
const numberFiles = this.files.filter((f) => f.needConvert).length;
|
||||
|
||||
if (
|
||||
numberFiles === 1 &&
|
||||
!(isMobile || isMobileUtils() || isTabletUtils())
|
||||
) {
|
||||
this.setConversionPercent(progress);
|
||||
} else {
|
||||
this.setConversionPercent(percent);
|
||||
}
|
||||
}
|
||||
|
||||
if (progress === 100) {
|
||||
|
@ -366,7 +366,7 @@ internal class FileDao : AbstractDao, IFileDao<int>
|
||||
|
||||
public Task<Stream> GetFileStreamAsync(File<int> file, long offset)
|
||||
{
|
||||
return _globalStore.GetStore().GetReadStreamAsync(string.Empty, GetUniqFilePath(file), (int)offset);
|
||||
return _globalStore.GetStore().GetReadStreamAsync(string.Empty, GetUniqFilePath(file), offset);
|
||||
}
|
||||
|
||||
public Task<Uri> GetPreSignedUriAsync(File<int> file, TimeSpan expires)
|
||||
|
@ -79,7 +79,6 @@ public class FileHandlerService
|
||||
private readonly SocketManager _socketManager;
|
||||
private readonly ILogger<FileHandlerService> _logger;
|
||||
private readonly IHttpClientFactory _clientFactory;
|
||||
private readonly RoomLogoManager _roomLogoManager;
|
||||
|
||||
public FileHandlerService(
|
||||
FilesLinkUtility filesLinkUtility,
|
||||
@ -110,8 +109,7 @@ public class FileHandlerService
|
||||
CompressToArchive compressToArchive,
|
||||
InstanceCrypto instanceCrypto,
|
||||
IHttpClientFactory clientFactory,
|
||||
ThumbnailSettings thumbnailSettings,
|
||||
RoomLogoManager roomLogoManager)
|
||||
ThumbnailSettings thumbnailSettings)
|
||||
{
|
||||
_filesLinkUtility = filesLinkUtility;
|
||||
_tenantExtra = tenantExtra;
|
||||
@ -142,7 +140,6 @@ public class FileHandlerService
|
||||
_logger = logger;
|
||||
_clientFactory = clientFactory;
|
||||
_thumbnailSettings = thumbnailSettings;
|
||||
_roomLogoManager = roomLogoManager;
|
||||
}
|
||||
|
||||
public Task Invoke(HttpContext context)
|
||||
@ -422,7 +419,7 @@ public class FileHandlerService
|
||||
var fullLength = await store.GetFileSizeAsync(string.Empty, mp4Path);
|
||||
|
||||
length = ProcessRangeHeader(context, fullLength, ref offset);
|
||||
fileStream = await store.GetReadStreamAsync(string.Empty, mp4Path, (int)offset);
|
||||
fileStream = await store.GetReadStreamAsync(string.Empty, mp4Path, offset);
|
||||
|
||||
title = FileUtility.ReplaceFileExtension(title, ".mp4");
|
||||
}
|
||||
@ -1064,7 +1061,7 @@ public class FileHandlerService
|
||||
|
||||
if (file.ThumbnailStatus != Thumbnail.Created)
|
||||
{
|
||||
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||
context.Response.StatusCode = (int)HttpStatusCode.NoContent;
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user