Merge branch 'develop' into feature/translations

This commit is contained in:
Alexey Safronov 2021-05-14 12:07:48 +03:00
commit 85bd971735
168 changed files with 3691 additions and 2723 deletions

1
.gitignore vendored
View File

@ -14,3 +14,4 @@ Data/
Logs/
**/.DS_Store
.eslintcache
build/deploy/

View File

@ -3,12 +3,8 @@
<solution>
<add key="disableSourceControlIntegration" value="true" />
</solution>
<config>
<add key="repositorypath" value="$\..\..\packages" />
</config>
<packageSources>
<add key="Pomelo" value="https://pkgs.dev.azure.com/pomelo-efcore/Pomelo.EntityFrameworkCore.MySql/_packaging/pomelo-efcore-public/nuget/v3/index.json" />
<add key="Custom NuGet Server" value="packages" />
<add key="Custom NuGet Server" value=".nuget\packages" />
<add key="NuGet official package source" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<packageRestore>

16
build/Jenkinsfile vendored
View File

@ -6,14 +6,14 @@ pipeline {
stage('Unix') {
agent { label 'net-core' }
stages {
stage('Backend') {
stage('Frontend') {
steps {
sh 'yarn install && yarn build'
}
}
stage('Frontend') {
stage('Backend') {
steps {
sh 'dotnet build ASC.Web.sln --configfile .nuget/NuGet.Config'
sh 'dotnet build ASC.Web.sln'
}
}
}
@ -21,14 +21,14 @@ pipeline {
stage('Windows') {
agent { label 'win-core' }
stages {
stage('Backend') {
stage('Frontend') {
steps {
bat 'yarn install && yarn build'
}
}
stage('Frontend') {
stage('Backend') {
steps {
bat 'dotnet build ASC.Web.sln --configfile .nuget\\NuGet.Config'
bat 'dotnet build ASC.Web.sln'
}
}
}
@ -62,7 +62,7 @@ pipeline {
}
stage('Files') {
steps {
sh "dotnet build ASC.Web.sln --configfile .nuget/NuGet.Config && cd ${env.WORKSPACE}/products/ASC.Files/Tests/ && dotnet test ASC.Files.Tests.csproj -r linux-x64 -l \"console;verbosity=detailed\""
sh "dotnet build ASC.Web.sln && cd ${env.WORKSPACE}/products/ASC.Files/Tests/ && dotnet test ASC.Files.Tests.csproj -r linux-x64 -l \"console;verbosity=detailed\""
}
}
}
@ -90,7 +90,7 @@ pipeline {
}
stage('Files') {
steps {
bat "dotnet build ASC.Web.sln --configfile .nuget\\NuGet.Config && cd ${env.WORKSPACE}\\products\\ASC.Files\\Tests\\ && dotnet test ASC.Files.Tests.csproj"
bat "dotnet build ASC.Web.sln && cd ${env.WORKSPACE}\\products\\ASC.Files\\Tests\\ && dotnet test ASC.Files.Tests.csproj"
}
}
}

View File

@ -42,7 +42,7 @@ done
echo "== BACK-END-BUILD =="
cd ${SRC_PATH}
dotnet restore ASC.Web.sln --configfile .nuget/NuGet.Config ${ARGS}
dotnet restore ASC.Web.sln${ARGS}
dotnet build ASC.Web.sln ${ARGS}
echo "== Build ASC.Thumbnails =="

View File

@ -140,7 +140,7 @@ RUN cd /app/onlyoffice/src/ && \
cp -f config/nginx/onlyoffice*.conf /etc/nginx/conf.d/ && \
mkdir -p /etc/nginx/includes/ && cp -f config/nginx/includes/onlyoffice*.conf /etc/nginx/includes/ && \
sed -e 's/#//' -i /etc/nginx/conf.d/onlyoffice.conf && \
dotnet restore ASC.Web.sln --configfile .nuget/NuGet.Config && \
dotnet restore ASC.Web.sln && \
dotnet build -r linux-x64 ASC.Web.sln && \
cd products/ASC.People/Server && \
dotnet -d publish --no-build --self-contained -r linux-x64 -o /var/www/products/ASC.People/server && \

View File

@ -44,7 +44,18 @@ RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
cd ${SRC_PATH}/build/install/common/ && \
bash build-frontend.sh -sp ${SRC_PATH} && \
bash build-backend.sh -sp ${SRC_PATH} -ar "--disable-parallel" && \
bash publish-backend.sh -sp ${SRC_PATH} -bp ${BUILD_PATH} -ar "--disable-parallel"
bash publish-backend.sh -sp ${SRC_PATH} -bp ${BUILD_PATH} -ar "--disable-parallel" && \
rm -rf ${SRC_PATH}/common/* && \
rm -rf ${SRC_PATH}/web/ASC.Web.Core/* && \
rm -rf ${SRC_PATH}/web/ASC.Web.Studio/* && \
rm -rf ${SRC_PATH}/products/ASC.Calendar/Server/* && \
rm -rf ${SRC_PATH}/products/ASC.CRM/Server/* && \
rm -rf ${SRC_PATH}/products/ASC.Files/Server/* && \
rm -rf ${SRC_PATH}/products/ASC.Files/Service/* && \
rm -rf ${SRC_PATH}/products/ASC.Mail/Server/* && \
rm -rf ${SRC_PATH}/products/ASC.People/Server/* && \
rm -rf ${SRC_PATH}/products/ASC.Projects/Server/*
COPY config/mysql/conf.d/mysql.cnf /etc/mysql/conf.d/mysql.cnf

View File

@ -48,7 +48,7 @@ npm i && cd ../../../)
npm run-script build --prefix products/ASC.People/Client
cd %{_builddir}/AppServer-%GIT_BRANCH/
dotnet restore ASC.Web.sln --configfile .nuget/NuGet.Config
dotnet restore ASC.Web.sln
dotnet build -r linux-x64 ASC.Web.sln
cd products/ASC.People/Server
dotnet -d publish --no-build --self-contained -r linux-x64 -o %{_builddir}%{_var}/www/appserver/products/ASC.People/server

View File

@ -1,10 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<ApplicationIcon />
<OutputType>Library</OutputType>
<StartupObject />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">

View File

@ -60,7 +60,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.5" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.2" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="5.0.0-alpha.2" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="5.0.2" />
<PackageReference Include="Telegram.Bot" Version="15.7.1" />
</ItemGroup>

View File

@ -1,10 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<ApplicationIcon />
<OutputType>Library</OutputType>
<StartupObject />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">

View File

@ -1,10 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<ApplicationIcon />
<OutputType>Library</OutputType>
<StartupObject />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">

View File

@ -1,10 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<ApplicationIcon />
<OutputType>Library</OutputType>
<StartupObject />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ProductVersion>9.0.30729</ProductVersion>
<TargetFramework>net5.0</TargetFramework>
@ -6,9 +6,6 @@
<Company>Ascensio System SIA</Company>
<Product>ASC.Notify.Textile</Product>
<Copyright>(c) Ascensio System SIA. All rights reserved</Copyright>
<ApplicationIcon />
<OutputType>Library</OutputType>
<StartupObject />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>full</DebugType>

View File

@ -14,6 +14,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Core" Version="5.2.7" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
</ItemGroup>
<ItemGroup>

View File

@ -24,8 +24,11 @@
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using ASC.Common.Utils;
@ -39,18 +42,40 @@ namespace ASC.ApiSystem
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
public async static Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.UseWindowsService()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
var builder = webBuilder.UseStartup<Startup>();
builder.ConfigureKestrel((hostingContext, serverOptions) =>
{
var kestrelConfig = hostingContext.Configuration.GetSection("Kestrel");
if (!kestrelConfig.Exists()) return;
var unixSocket = kestrelConfig.GetValue<string>("ListenUnixSocket");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
if (!String.IsNullOrWhiteSpace(unixSocket))
{
unixSocket = String.Format(unixSocket, hostingContext.HostingEnvironment.ApplicationName.Replace("ASC.", "").Replace(".", ""));
serverOptions.ListenUnixSocket(unixSocket);
}
}
});
})
.ConfigureAppConfiguration((hostingContext, config) =>
{
@ -76,6 +101,5 @@ namespace ASC.ApiSystem
});
});
}
}
}

View File

@ -1,10 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<ApplicationIcon />
<OutputType>Library</OutputType>
<StartupObject />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">

View File

@ -23,6 +23,8 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
<PackageReference Include="SharpCompress" Version="0.26.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,5 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using ASC.Common.Utils;
@ -13,14 +15,41 @@ using Microsoft.Extensions.Hosting;
namespace ASC.Data.Backup
{
public class Program
{
public static async Task Main(string[] args)
{
await Host.CreateDefaultBuilder(args)
{
public async static Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.UseWindowsService()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
var builder = webBuilder.UseStartup<Startup>();
builder.ConfigureKestrel((hostingContext, serverOptions) =>
{
var kestrelConfig = hostingContext.Configuration.GetSection("Kestrel");
if (!kestrelConfig.Exists()) return;
var unixSocket = kestrelConfig.GetValue<string>("ListenUnixSocket");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
if (!String.IsNullOrWhiteSpace(unixSocket))
{
unixSocket = String.Format(unixSocket, hostingContext.HostingEnvironment.ApplicationName.Replace("ASC.", "").Replace(".", ""));
serverOptions.ListenUnixSocket(unixSocket);
}
}
});
})
.ConfigureAppConfiguration((hostContext, config) =>
{
@ -46,10 +75,7 @@ namespace ASC.Data.Backup
{"pathToConf", path }
}
);
})
.UseConsoleLifetime()
.Build()
.RunAsync();
}
});
}
}

View File

@ -22,6 +22,8 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
<PackageReference Include="SharpCompress" Version="0.26.0" />
</ItemGroup>

View File

@ -22,8 +22,10 @@
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using ASC.Common.Utils;
@ -38,13 +40,40 @@ namespace ASC.Data.Storage.Encryption
{
public class Program
{
public static async Task Main(string[] args)
{
await Host.CreateDefaultBuilder(args)
public async static Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.UseWindowsService()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
var builder = webBuilder.UseStartup<Startup>();
builder.ConfigureKestrel((hostingContext, serverOptions) =>
{
var kestrelConfig = hostingContext.Configuration.GetSection("Kestrel");
if (!kestrelConfig.Exists()) return;
var unixSocket = kestrelConfig.GetValue<string>("ListenUnixSocket");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
if (!String.IsNullOrWhiteSpace(unixSocket))
{
unixSocket = String.Format(unixSocket, hostingContext.HostingEnvironment.ApplicationName.Replace("ASC.", "").Replace(".", ""));
serverOptions.ListenUnixSocket(unixSocket);
}
}
});
})
.ConfigureAppConfiguration((hostContext, config) =>
{
@ -69,10 +98,6 @@ namespace ASC.Data.Storage.Encryption
.AddJsonFile("kafka.json")
.AddJsonFile($"kafka.{env}.json", true)
.AddEnvironmentVariables();
})
.UseConsoleLifetime()
.Build()
.RunAsync();
}
});
}
}

View File

@ -4,6 +4,11 @@
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />

View File

@ -19,9 +19,17 @@ namespace ASC.Data.Storage.Migration
{
public class Program
{
public static async Task Main(string[] args)
{
await Host.CreateDefaultBuilder(args)
public async static Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.UseWindowsService()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureAppConfiguration((hostContext, config) =>
{
@ -64,10 +72,6 @@ namespace ASC.Data.Storage.Migration
.ConfigureContainer<ContainerBuilder>((context, builder) =>
{
builder.Register(context.Configuration);
})
.UseConsoleLifetime()
.Build()
.RunAsync();
}
});
}
}

View File

@ -13,7 +13,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
</ItemGroup>
<ItemGroup>

View File

@ -21,9 +21,17 @@ namespace ASC.Notify
{
public class Program
{
public static async Task Main(string[] args)
public async static Task Main(string[] args)
{
var host = Host.CreateDefaultBuilder(args)
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.UseWindowsService()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureAppConfiguration((hostContext, config) =>
{
@ -73,18 +81,6 @@ namespace ASC.Notify
.ConfigureContainer<ContainerBuilder>((context, builder) =>
{
builder.Register(context.Configuration);
})
.UseConsoleLifetime()
.Build();
using (host)
{
// Start the host
await host.StartAsync();
// Wait for the host to shutdown
await host.WaitForShutdownAsync();
}
}
});
}
}

View File

@ -16,6 +16,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
<PackageReference Include="WebSocketSharp" Version="1.0.3-rc11" />
</ItemGroup>

View File

@ -46,9 +46,17 @@ namespace ASC.Socket.IO.Svc
{
public class Program
{
public static async Task Main(string[] args)
{
var host = Host.CreateDefaultBuilder(args)
public async static Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.UseWindowsService()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureAppConfiguration((hostContext, config) =>
{
@ -90,18 +98,7 @@ namespace ASC.Socket.IO.Svc
.ConfigureContainer<ContainerBuilder>((context, builder) =>
{
builder.Register(context.Configuration, false, false);
})
.UseConsoleLifetime()
.Build();
using (host)
{
// Start the host
await host.StartAsync();
// Wait for the host to shutdown
await host.WaitForShutdownAsync();
}
}
}
}
});
}
}

View File

@ -10,6 +10,11 @@
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\web\ASC.Web.Core\ASC.Web.Core.csproj" />
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />

View File

@ -22,9 +22,17 @@ namespace ASC.Studio.Notify
{
public class Program
{
public static async Task Main(string[] args)
public async static Task Main(string[] args)
{
var host = Host.CreateDefaultBuilder(args)
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.UseWindowsService()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureAppConfiguration((hostContext, config) =>
{
@ -67,18 +75,6 @@ namespace ASC.Studio.Notify
.ConfigureContainer<ContainerBuilder>((context, builder) =>
{
builder.Register(context.Configuration);
})
.UseConsoleLifetime()
.Build();
using (host)
{
// Start the host
await host.StartAsync();
// Wait for the host to shutdown
await host.WaitForShutdownAsync();
}
}
});
}
}

View File

@ -13,7 +13,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
<PackageReference Include="Telegram.Bot" Version="15.7.1" />
</ItemGroup>

View File

@ -22,8 +22,10 @@
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using ASC.Common.Utils;
@ -38,13 +40,40 @@ namespace ASC.TelegramService
{
public class Program
{
public static async Task Main(string[] args)
{
await Host.CreateDefaultBuilder(args)
public async static Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.UseWindowsService()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
var builder = webBuilder.UseStartup<Startup>();
builder.ConfigureKestrel((hostingContext, serverOptions) =>
{
var kestrelConfig = hostingContext.Configuration.GetSection("Kestrel");
if (!kestrelConfig.Exists()) return;
var unixSocket = kestrelConfig.GetValue<string>("ListenUnixSocket");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
if (!String.IsNullOrWhiteSpace(unixSocket))
{
unixSocket = String.Format(unixSocket, hostingContext.HostingEnvironment.ApplicationName.Replace("ASC.", "").Replace(".", ""));
serverOptions.ListenUnixSocket(unixSocket);
}
}
});
})
.ConfigureAppConfiguration((hostContext, config) =>
{
@ -69,10 +98,6 @@ namespace ASC.TelegramService
.AddJsonFile("kafka.json")
.AddJsonFile($"kafka.{env}.json", true)
.AddEnvironmentVariables();
})
.UseConsoleLifetime()
.Build()
.RunAsync();
}
});
}
}

View File

@ -21,5 +21,10 @@
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
</ItemGroup>
</Project>

View File

@ -26,6 +26,7 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using ASC.Common;
@ -45,11 +46,19 @@ using Microsoft.Extensions.Hosting;
namespace ASC.Thumbnails.Svc
{
public class Program
{
public static async Task Main(string[] args)
{
var host = Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
{
public async static Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.UseWindowsService()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureAppConfiguration((hostContext, config) =>
{
var buided = config.Build();
@ -89,18 +98,6 @@ namespace ASC.Thumbnails.Svc
.ConfigureContainer<ContainerBuilder>((context, builder) =>
{
builder.Register(context.Configuration, false, false);
})
.UseConsoleLifetime()
.Build();
using (host)
{
// Start the host
await host.StartAsync();
// Wait for the host to shutdown
await host.WaitForShutdownAsync();
}
}
});
}
}

View File

@ -13,7 +13,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
</ItemGroup>
<ItemGroup>

View File

@ -44,59 +44,60 @@ using Microsoft.Extensions.Hosting;
namespace ASC.UrlShortener.Svc
{
public class Program
{
public static async Task Main(string[] args)
{
var host = Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureAppConfiguration((hostContext, config) =>
{
var buided = config.Build();
var path = buided["pathToConf"];
if (!Path.IsPathRooted(path))
{
path = Path.GetFullPath(CrossPlatform.PathCombine(hostContext.HostingEnvironment.ContentRootPath, path));
}
config.SetBasePath(path);
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
config
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env}.json", true)
.AddJsonFile($"urlshortener.{env}.json", true)
.AddJsonFile("storage.json")
.AddJsonFile("kafka.json")
.AddJsonFile($"kafka.{env}.json", true)
.AddEnvironmentVariables()
.AddCommandLine(args)
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
);
})
.ConfigureServices((hostContext, services) =>
{
services.AddMemoryCache();
var diHelper = new DIHelper(services);
LogNLogExtension.ConfigureLog(diHelper, "ASC.UrlShortener.Svc");
services.AddHostedService<UrlShortenerServiceLauncher>();
diHelper.TryAdd<UrlShortenerServiceLauncher>();
})
.ConfigureContainer<ContainerBuilder>((context, builder) =>
{
builder.Register(context.Configuration, false, false);
})
.UseConsoleLifetime()
.Build();
using (host)
{
// Start the host
await host.StartAsync();
// Wait for the host to shutdown
await host.WaitForShutdownAsync();
}
}
{
public async static Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.UseWindowsService()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureAppConfiguration((hostContext, config) =>
{
var buided = config.Build();
var path = buided["pathToConf"];
if (!Path.IsPathRooted(path))
{
path = Path.GetFullPath(CrossPlatform.PathCombine(hostContext.HostingEnvironment.ContentRootPath, path));
}
config.SetBasePath(path);
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
config.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env}.json", true)
.AddJsonFile($"urlshortener.{env}.json", true)
.AddJsonFile("storage.json")
.AddJsonFile("kafka.json")
.AddJsonFile($"kafka.{env}.json", true)
.AddEnvironmentVariables()
.AddCommandLine(args)
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
);
})
.ConfigureServices((hostContext, services) =>
{
services.AddMemoryCache();
var diHelper = new DIHelper(services);
LogNLogExtension.ConfigureLog(diHelper, "ASC.UrlShortener.Svc");
services.AddHostedService<UrlShortenerServiceLauncher>();
diHelper.TryAdd<UrlShortenerServiceLauncher>();
})
.ConfigureContainer<ContainerBuilder>((context, builder) =>
{
builder.Register(context.Configuration, false, false);
});
}
}

View File

@ -4,6 +4,12 @@
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
},
"EventLog": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
}
},
"AllowedHosts": "*",

View File

@ -1,5 +1,5 @@
{
"version": "0.1.8",
"version": "0.1.9",
"npmClient": "yarn",
"packages": [
"packages/asc-web-components",

View File

@ -1,6 +1,7 @@
{
"name": "appserver",
"private": true,
"version": "0.1.9",
"workspaces": [
"packages/asc-web-components",
"packages/asc-web-common",
@ -16,14 +17,16 @@
],
"scripts": {
"wipe": "rimraf node_modules yarn.lock web/**/node_modules products/**/node_modules",
"build": "yarn workspaces run build",
"build": "concurrently \"wsrun --parallel build\"",
"start": "concurrently \"wsrun --parallel start\"",
"start-prod": "concurrently \"wsrun --parallel start-prod\"",
"serve": "concurrently \"wsrun --parallel serve\"",
"test": "yarn workspace @appserver/components test",
"clean": "concurrently \"wsrun --parallel clean\"",
"storybook": "yarn workspace @appserver/components storybook",
"storybook-build": "yarn workspace @appserver/components run storybook-build"
"storybook-build": "yarn workspace @appserver/components run storybook-build",
"bump": "lerna version --no-push --no-git-tag-version",
"deploy": "rimraf build/deploy && concurrently \"wsrun --parallel deploy\""
},
"devDependencies": {
"lerna": "^3.22.1",

View File

@ -638,8 +638,7 @@ export function getSettingsFiles() {
}
export function markAsFavorite(ids) {
let items = ids.map((id) => +id);
const data = { fileIds: items };
const data = { fileIds: ids };
const options = {
method: "post",
url: "/files/favorites",
@ -650,8 +649,7 @@ export function markAsFavorite(ids) {
}
export function removeFromFavorite(ids) {
let items = ids.map((id) => +id);
const data = { fileIds: items };
const data = { fileIds: ids };
const options = {
method: "delete",
url: "/files/favorites",

View File

@ -1,4 +1,4 @@
import styled from "styled-components";
import styled, { keyframes, css } from "styled-components";
const backgroundColor = "none";
const color = "#2DA7DB";
@ -11,6 +11,15 @@ const StyledCircleWrap = styled.div`
cursor: pointer;
`;
const rotate360 = keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
`;
const StyledCircle = styled.div`
.circle__mask,
.circle__fill {
@ -20,14 +29,24 @@ const StyledCircle = styled.div`
border-radius: 50%;
}
.circle__mask {
clip: rect(0px, 54px, 54px, 27px);
}
${(props) =>
props.percent > 0
? css`
.circle__mask {
clip: rect(0px, 54px, 54px, 27px);
}
.circle__fill {
animation: fill-rotate ease-in-out none;
transform: rotate(${(props) => props.percent * 1.8}deg);
}
.circle__fill {
animation: fill-rotate ease-in-out none;
transform: rotate(${(props) => props.percent * 1.8}deg);
}
`
: css`
.circle__fill {
animation: ${rotate360} 2s linear infinite;
transform: translate(0);
}
`}
.circle__mask .circle__fill {
clip: rect(0px, 27px, 54px, 0px);

View File

@ -15,7 +15,7 @@ import CrossIcon from "../../../../public/images/cross.react.svg";
import commonIconsStyles from "@appserver/components/utils/common-icons-style";
const StyledVideoViewer = styled(VideoViewer)`
z-index: 4001;
z-index: 301;
`;
const mediaTypes = Object.freeze({
audio: 1,
@ -181,12 +181,14 @@ class MediaViewer extends React.Component {
}
componentWillUnmount() {
this.hammer.off("swipeleft", this.nextMedia);
this.hammer.off("swiperight", this.prevMedia);
this.hammer.off("pinchout", this.prevMedia);
this.hammer.off("pinchin", this.prevMedia);
this.hammer.off("pinchend", this.prevMedia);
this.hammer.off("doubletap", this.prevMedia);
if (this.hammer) {
this.hammer.off("swipeleft", this.nextMedia);
this.hammer.off("swiperight", this.prevMedia);
this.hammer.off("pinchout", this.prevMedia);
this.hammer.off("pinchin", this.prevMedia);
this.hammer.off("pinchend", this.prevMedia);
this.hammer.off("doubletap", this.prevMedia);
}
document.removeEventListener("keydown", this.onKeydown, false);
document.removeEventListener("keyup", this.onKeyup, false);
}
@ -434,13 +436,14 @@ class MediaViewer extends React.Component {
onClick={this.props.onClose && this.props.onClose}
className="mediaPlayerClose"
>
<CrossIcon size="medium" isfill={true} color="#fff" />
<CrossIcon size="medium" /* isfill={true} */ color="#fff" />
</ControlBtn>
</div>
</div>
{canOpen &&
(isImage ? (
<ImageViewer
userAccess={this.props.userAccess}
visible={this.state.visible}
onClose={this.onClose}
images={[{ src: url, alt: "" }]}

View File

@ -6,7 +6,7 @@ const StyledMediaViewer = styled.div`
overflow: hidden;
.videoViewerOverlay {
position: fixed;
z-index: 4000;
z-index: 300;
top: 0;
left: 0;
width: 100%;
@ -15,7 +15,7 @@ const StyledMediaViewer = styled.div`
opacity: 0.5;
}
.mediaViewerToolbox {
z-index: 4001;
z-index: 301;
padding-top: 14px;
padding-bottom: 14px;
height: 20px;
@ -31,7 +31,7 @@ const StyledMediaViewer = styled.div`
right: 0;
bottom: 5px;
margin-right: 10px;
z-index: 4005;
z-index: 305;
}
.deleteBtnContainer,
.downloadBtnContainer {
@ -41,7 +41,7 @@ const StyledMediaViewer = styled.div`
line-height: 19px;
}
.details {
z-index: 4002;
z-index: 302;
padding-top: 14px;
padding-bottom: 14px;
height: 20px;

View File

@ -38,11 +38,11 @@ const StyledMediaDownloadIcon = styled(MediaDownloadIcon)`
const StyledViewer = styled(Viewer)`
.react-viewer-footer {
bottom: 5px !important;
z-index: 4001 !important;
z-index: 301 !important;
overflow: visible;
}
.react-viewer-canvas {
z-index: 4000 !important;
z-index: 300 !important;
margin-top: 50px;
}
.react-viewer-navbar,
@ -217,7 +217,14 @@ class ImageViewer extends React.Component {
}
render() {
const { className, visible, images, inactive, onClose } = this.props;
const {
className,
visible,
images,
inactive,
onClose,
userAccess,
} = this.props;
customToolbar.forEach((button) => {
switch (button.key) {
@ -237,6 +244,11 @@ class ImageViewer extends React.Component {
break;
}
});
const toolbars = userAccess
? customToolbar
: customToolbar.filter((x) => x.key !== "delete");
return (
<div className={className}>
<StyledViewer
@ -244,9 +256,7 @@ class ImageViewer extends React.Component {
visible={visible}
zoomSpeed={0.1}
onMaskClick={onClose}
customToolbar={(toolbars) => {
return customToolbar;
}}
customToolbar={() => toolbars}
images={images}
disableKeyboardSupport={true}
/>

View File

@ -4,7 +4,7 @@ import styled from "styled-components";
const ScrollButton = styled.div`
cursor: ${(props) => (props.inactive ? "default" : "pointer")};
opacity: ${(props) => (props.inactive ? "0.2" : "1")};
z-index: 4005;
z-index: 305;
position: fixed;
top: calc(50% - 20px);

View File

@ -19,7 +19,7 @@ const StyledControls = styled.div`
height: ${(props) => props.height}px;
display: block;
position: fixed;
z-index: 4001;
z-index: 301;
${(props) => !props.isVideo && "background-color: rgba(11,11,11,0.7);"}
top: calc(50% + ${(props) => props.top}px);
left: ${(props) => props.left}px;
@ -174,13 +174,13 @@ const StyledVideoViewer = styled.div`
height: ${(props) => props.height}px;
left: ${(props) => props.left}px;
top: calc(50% - ${(props) => props.top / 2}px);
z-index: 4001;
z-index: 301;
position: fixed;
padding-bottom: 40px;
background-color: rgba(11, 11, 11, 0.7);
video {
z-index: 4000;
z-index: 300;
}
}
`;

View File

@ -264,15 +264,9 @@ class PageLayout extends React.Component {
isArticleAvailable,
isBackdropAvailable = isArticleAvailable;
return (
<>
<StyledSelectableGroup
enableDeselect
resetOnStart
allowClickWithoutSelected={false}
duringSelection={this.duringSelection}
ignoreList={[".not-selectable", "draggable"]}
>
const renderPageLayout = () => {
return (
<>
{isBackdropAvailable && (
<Backdrop
zIndex={400}
@ -432,6 +426,22 @@ class PageLayout extends React.Component {
)}
</ReactResizeDetector>
)}
</>
);
};
return isMobile || !uploadFiles ? (
renderPageLayout()
) : (
<>
<StyledSelectableGroup
enableDeselect
resetOnStart
allowClickWithoutSelected={false}
duringSelection={this.duringSelection}
ignoreList={[".not-selectable", "draggable"]}
>
{renderPageLayout()}
</StyledSelectableGroup>
{uploadFiles && <SelectedFrame />}
</>

View File

@ -111,7 +111,7 @@ class SectionBody extends React.Component {
const focusProps = autoFocus
? {
ref: this.focusRef,
tabIndex: 1,
tabIndex: -1,
}
: {};

View File

@ -41,7 +41,7 @@ const SectionToggler = React.memo((props) => {
const { visible, onClick } = props;
return (
<StyledSectionToggler visible={visible}>
<StyledSectionToggler className="not-selectable" visible={visible}>
<div onClick={onClick}>
<CatalogButtonIcon style={iconStyle} />
</div>

View File

@ -163,3 +163,27 @@ export const LoaderStyle = {
import config from "./AppServerConfig";
export const AppServerConfig = config;
/**
* Enum for Tenant trusted domains on registration.
* @readonly
*/
export const TenantTrustedDomainsType = Object.freeze({
None: 0,
Custom: 1,
All: 2,
});
export const FilesFormats = Object.freeze({
OriginalFormat: 0,
TxtFormat: 1,
DocxFormat: 2,
OdtFormat: 3,
OdsFormat: 4,
OdpFormat: 5,
PdfFormat: 6,
RtfFormat: 7,
XlsxFormat: 8,
PptxFormat: 9,
CustomFormat: 10,
});

View File

@ -1,12 +1,13 @@
{
"name": "@appserver/common",
"version": "0.0.3",
"version": "0.1.9",
"private": true,
"scripts": {
"build": "echo 'skip it'",
"start": "echo 'skip it'",
"start-prod": "echo 'skip it'",
"clean": "echo 'skip it'"
"clean": "echo 'skip it'",
"deploy": "echo 'skip it'"
},
"api": {
"url": "/api/2.0",

View File

@ -13,7 +13,8 @@ class SettingsStore {
culture = "en-US";
cultures = [];
trustedDomains = [];
trustedDomainsType = 1;
trustedDomainsType = 0;
trustedDomains = [];
timezone = "UTC";
timezones = [];
utcOffset = "00:00:00";

View File

@ -133,7 +133,7 @@ export function isAdmin(currentUser, currentProductId) {
productName = "people";
break;
case "e67be73d-f9ae-4ce1-8fec-1880cb518cb4":
productName = "documents";
productName = "files";
break;
default:
break;
@ -147,21 +147,6 @@ export function isAdmin(currentUser, currentProductId) {
return currentUser.isAdmin || currentUser.isOwner || isProductAdmin;
}
// export function combineUrl(host = "", ...params) {
// let url = host.replace(/\/+$/, "");
// params.forEach((part) => {
// const newPart = part.trim().replace(/^\/+/, "");
// url += newPart
// ? url.length > 0 && url[url.length - 1] === "/"
// ? newPart
// : `/${newPart}`
// : "";
// });
// return url;
// }
import combineUrlFunc from "./combineUrl";
export const combineUrl = combineUrlFunc;
@ -213,3 +198,29 @@ export function clickBackdrop() {
elms[0].click();
}
}
export function objectToGetParams(object) {
const params = Object.entries(object)
.filter(([, value]) => value !== undefined && value !== null)
.map(
([key, value]) =>
`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`
);
return params.length > 0 ? `?${params.join("&")}` : "";
}
export function toCommunityHostname(hostname) {
let communityHostname;
try {
communityHostname =
hostname.indexOf("m.") > -1
? hostname.substring(2, hostname.length)
: hostname;
} catch (e) {
console.error(e);
communityHostname = hostname;
}
return communityHostname;
}

View File

@ -164,7 +164,7 @@ class IconButton extends React.PureComponent {
})} */}
<ReactSVG
className="icon-button_svg"
className="icon-button_svg not-selectable"
src={this.state.currentIconName}
/>
</StyledOuter>

View File

@ -14,6 +14,8 @@ import {
Dialog,
BodyBox,
} from "./styled-modal-dialog";
import Portal from "../portal";
function Header() {
return null;
}
@ -127,62 +129,72 @@ class ModalDialog extends React.Component {
}
});
return this.state.displayType === "modal" ? (
<Backdrop
visible={visible}
zIndex={zIndex}
withBackground={true}
isModalDialog
>
<Dialog className={`${className} not-selectable`} id={id} style={style}>
<Content contentHeight={contentHeight} contentWidth={contentWidth}>
<StyledHeader>
<Heading className="heading" size="medium" truncate={true}>
{header ? header.props.children : null}
</Heading>
<CloseButton onClick={onClose}></CloseButton>
</StyledHeader>
<BodyBox paddingProp={bodyPadding}>
{body ? body.props.children : null}
</BodyBox>
<Box>{footer ? footer.props.children : null}</Box>
</Content>
</Dialog>
</Backdrop>
) : (
<Box className={className} id={id} style={style}>
const renderModal = () => {
return this.state.displayType === "modal" ? (
<Backdrop
visible={visible}
onClick={onClose}
zIndex={zIndex}
isAside={true}
/>
<Aside
visible={visible}
scale={scale}
zIndex={zIndex}
className="modal-dialog-aside not-selectable"
withBackground={true}
isModalDialog
>
<Content contentHeight={contentHeight} contentWidth={contentWidth}>
<StyledHeader className="modal-dialog-aside-header">
<Heading className="heading" size="medium" truncate={true}>
{header ? header.props.children : null}
</Heading>
{scale ? <CloseButton onClick={onClose}></CloseButton> : ""}
</StyledHeader>
<BodyBox
className="modal-dialog-aside-body"
paddingProp={bodyPadding}
>
{body ? body.props.children : null}
</BodyBox>
<Box className="modal-dialog-aside-footer">
{footer ? footer.props.children : null}
</Box>
</Content>
</Aside>
</Box>
);
<Dialog
className={`${className} not-selectable`}
id={id}
style={style}
>
<Content contentHeight={contentHeight} contentWidth={contentWidth}>
<StyledHeader>
<Heading className="heading" size="medium" truncate={true}>
{header ? header.props.children : null}
</Heading>
<CloseButton onClick={onClose}></CloseButton>
</StyledHeader>
<BodyBox paddingProp={bodyPadding}>
{body ? body.props.children : null}
</BodyBox>
<Box>{footer ? footer.props.children : null}</Box>
</Content>
</Dialog>
</Backdrop>
) : (
<Box className={className} id={id} style={style}>
<Backdrop
visible={visible}
onClick={onClose}
zIndex={zIndex}
isAside={true}
/>
<Aside
visible={visible}
scale={scale}
zIndex={zIndex}
className="modal-dialog-aside not-selectable"
>
<Content contentHeight={contentHeight} contentWidth={contentWidth}>
<StyledHeader className="modal-dialog-aside-header">
<Heading className="heading" size="medium" truncate={true}>
{header ? header.props.children : null}
</Heading>
{scale ? <CloseButton onClick={onClose}></CloseButton> : ""}
</StyledHeader>
<BodyBox
className="modal-dialog-aside-body"
paddingProp={bodyPadding}
>
{body ? body.props.children : null}
</BodyBox>
<Box className="modal-dialog-aside-footer">
{footer ? footer.props.children : null}
</Box>
</Content>
</Aside>
</Box>
);
};
const modalDialog = renderModal();
return <Portal element={modalDialog} />;
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/components",
"version": "0.0.3",
"version": "0.1.9",
"private": true,
"scripts": {
"build": "echo 'skip it'",
@ -12,7 +12,8 @@
"storybook": "start-storybook -p 8082 -s public",
"storybook-build": "build-storybook",
"storybook-serve": "serve storybook-static -p 8082",
"clean": "echo 'skip it'"
"clean": "echo 'skip it'",
"deploy": "echo 'skip it'"
},
"devDependencies": {
"@babel/cli": "^7.12.10",
@ -69,8 +70,7 @@
"email-addresses": "^3.1.0",
"fast-deep-equal": "^3.1.3",
"html-to-react": "^1.4.5",
"lodash": "4.17.19",
"lodash-es": "4.17.15",
"lodash": "4.17.21",
"moment": "^2.29.1",
"prop-types": "^15.7.2",
"punycode": "^2.1.1",

View File

@ -423,6 +423,7 @@ class PasswordInput extends React.Component {
simpleView,
hideNewPasswordButton,
isDisabled,
showCopyLink,
} = this.props;
const { copyLabel, disableCopyAction } = this.state;
@ -461,18 +462,20 @@ class PasswordInput extends React.Component {
) : null}
</div>
{this.renderTextTooltip()}
<CopyLink>
<Link
type="action"
isHovered={true}
fontSize="13px"
className="password-input_link"
isSemitransparent={disableCopyAction}
onClick={this.copyToClipboard.bind(this, emailInputName)}
>
{copyLabel}
</Link>
</CopyLink>
{showCopyLink && (
<CopyLink>
<Link
type="action"
isHovered={true}
fontSize="13px"
className="password-input_link"
isSemitransparent={disableCopyAction}
onClick={this.copyToClipboard.bind(this, emailInputName)}
>
{copyLabel}
</Link>
</CopyLink>
)}
</>
)}
</StyledInput>
@ -549,6 +552,8 @@ PasswordInput.propTypes = {
tooltipOffsetLeft: PropTypes.number,
/** Set simple view of password input (without tooltips, password progress bar and several additional buttons (copy and generate password) */
simpleView: PropTypes.bool,
/** Sets the link to copy the password visible */
showCopyLink: PropTypes.bool,
};
PasswordInput.defaultProps = {
@ -579,6 +584,7 @@ PasswordInput.defaultProps = {
digits: false,
specSymbols: false,
},
showCopyLink: true,
};
export default PasswordInput;

View File

@ -1,7 +1,6 @@
{
"name": "@appserver/crm",
"version": "0.1.8",
"private": "true",
"version": "0.1.9",
"homepage": "/products/crm",
"title": "ONLYOFFICE",
"id": "6743007c-6f95-4d20-8c88-a8601ce5e76d",
@ -9,8 +8,9 @@
"start": "webpack-cli serve",
"start-prod": "webpack --mode production && serve dist -p 5014",
"build": "webpack --mode production",
"deploy": "mkdirp ../../../build/deploy/products/ASC.CRM/client && cp -r -u dist/* ../../../build/deploy/products/ASC.CRM/client",
"serve": "serve dist -p 5014",
"clean": "rm -rf dist"
"clean": "rimraf dist"
},
"devDependencies": {
"@babel/core": "^7.12.10",
@ -26,9 +26,12 @@
"css-loader": "^3.6.0",
"html-webpack-plugin": "4.5.0",
"json-loader": "^0.5.7",
"mkdirp": "^1.0.4",
"rimraf": "^3.0.2",
"serve": "11.3.2",
"source-map-loader": "^1.1.2",
"style-loader": "1.2.1",
"terser-webpack-plugin": "^5.1.1",
"webpack": "5.14.0",
"webpack-cli": "4.5.0",
"webpack-dev-server": "3.11.2",
@ -38,14 +41,14 @@
"@babel/runtime": "^7.12.5",
"attr-accept": "^2.2.2",
"axios": "^0.21.0",
"copy-to-clipboard": "^3.2.0",
"email-addresses": "^3.1.0",
"fast-deep-equal": "^3.1.3",
"i18next": "^19.8.4",
"i18next-http-backend": "^1.1.0",
"mobx": "^6.1.1",
"mobx-react": "^7.1.0",
"moment": "^2.29.1",
"copy-to-clipboard": "^3.2.0",
"fast-deep-equal": "^3.1.3",
"prop-types": "^15.7.2",
"rc-tree": "^2.1.4",
"re-resizable": "^6.9.0",
@ -56,8 +59,8 @@
"react-device-detect": "^1.14.0",
"react-dom": "^17.0.1",
"react-dropzone": "^11.2.4",
"react-i18next": "^11.7.3",
"react-hammerjs": "^1.0.1",
"react-i18next": "^11.7.3",
"react-onclickoutside": "^6.9.0",
"react-player": "^1.15.3",
"react-resize-detector": "^5.2.0",
@ -75,8 +78,8 @@
"resize-image": "^0.1.0",
"sass": "^1.29.0",
"sass-loader": "^10.1.0",
"sjcl": "^1.0.8",
"screenfull": "^5.1.0",
"sjcl": "^1.0.8",
"styled-components": "^5.2.1",
"workbox-window": "^6.1.1"
}

View File

@ -19,7 +19,7 @@ import { setDocumentTitle } from "../../helpers/utils";
import { inject } from "mobx-react";
import i18n from "../../i18n";
import { I18nextProvider } from "react-i18next";
import { combineUrl, deleteCookie } from "@appserver/common/utils";
import { toCommunityHostname, deleteCookie } from "@appserver/common/utils";
const commonStyles = `
.link-box {
@ -121,12 +121,11 @@ const Body = ({ modules, match, isLoaded, setCurrentProductId, t, tReady }) => {
const { error } = match.params;
const { pathname, protocol, hostname } = window.location;
const currentModule = modules.find((m) => m.link === pathname);
const { id, title, imageUrl, link, originUrl, helpUrl } = currentModule;
const url = originUrl ? originUrl : link;
const webLink = combineUrl(
protocol + "//" + hostname,
`${url}?desktop_view=true`
);
const { id, title, imageUrl, /*link, originUrl,*/ helpUrl } = currentModule;
//const url = originUrl ? originUrl : link;
const communityHostname = toCommunityHostname(hostname);
const webLink = `${protocol}//${communityHostname}/Products/CRM/?desktop_view=true`;
const appLink = isIOS
? id === "2A923037-8B2D-487b-9A22-5AC0918ACF3F"
? "message:"

View File

@ -4,6 +4,11 @@
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\ASC.Api.Core\ASC.Api.Core.csproj" />
</ItemGroup>

View File

@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using ASC.Common.DependencyInjection;
using ASC.Common.Utils;
@ -15,18 +18,40 @@ namespace ASC.CRM
{
public class Program
{
public static void Main(string[] args)
public async static Task Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.UseWindowsService()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
var builder = webBuilder.UseStartup<Startup>();
builder.ConfigureKestrel((hostingContext, serverOptions) =>
{
var kestrelConfig = hostingContext.Configuration.GetSection("Kestrel");
if (!kestrelConfig.Exists()) return;
var unixSocket = kestrelConfig.GetValue<string>("ListenUnixSocket");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
if (!String.IsNullOrWhiteSpace(unixSocket))
{
unixSocket = String.Format(unixSocket, hostingContext.HostingEnvironment.ApplicationName.Replace("ASC.", "").Replace(".", ""));
serverOptions.ListenUnixSocket(unixSocket);
}
}
});
})
.ConfigureAppConfiguration((hostingContext, config) =>
{
@ -54,25 +79,6 @@ namespace ASC.CRM
.ConfigureContainer<ContainerBuilder>((context, builder) =>
{
builder.Register(context.Configuration, true, false);
});
//if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "crm_common"))
//{
// FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", new FileSecurityProvider());
//}
////Register prodjects' calendar events
//CalendarManager.Instance.RegistryCalendarProvider(userid =>
//{
// if (WebItemSecurity.IsAvailableForUser(WebItemManager.CRMProductID, userid))
// {
// return new List<BaseCalendar> { new CRMCalendar(userid) };
// }
// return new List<BaseCalendar>();
//});
}
});//if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "crm_common"))//{// FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", new FileSecurityProvider());//}////Register prodjects' calendar events//CalendarManager.Instance.RegistryCalendarProvider(userid =>//{// if (WebItemSecurity.IsAvailableForUser(WebItemManager.CRMProductID, userid))// {// return new List<BaseCalendar> { new CRMCalendar(userid) };// }// return new List<BaseCalendar>();//});
}
}

View File

@ -1,7 +1,6 @@
{
"name": "@appserver/calendar",
"version": "0.1.3",
"private": "true",
"version": "0.1.9",
"homepage": "/products/calendar",
"id": "32d24cb5-7ece-4606-9c94-19216ba42086",
"title": "ONLYOFFICE",
@ -9,8 +8,9 @@
"start": "webpack-cli serve",
"start-prod": "webpack --mode production && serve dist -p 5017",
"build": "webpack --mode production",
"deploy": "mkdirp ../../../build/deploy/products/ASC.Calendar/client && cp -r -u dist/* ../../../build/deploy/products/ASC.Calendar/client",
"serve": "serve dist -p 5017",
"clean": "rm -rf dist"
"clean": "rimraf dist"
},
"devDependencies": {
"@babel/core": "^7.12.10",
@ -26,9 +26,12 @@
"css-loader": "^3.6.0",
"html-webpack-plugin": "4.5.0",
"json-loader": "^0.5.7",
"mkdirp": "^1.0.4",
"rimraf": "^3.0.2",
"serve": "11.3.2",
"source-map-loader": "^1.1.2",
"style-loader": "1.2.1",
"terser-webpack-plugin": "^5.1.1",
"webpack": "5.14.0",
"webpack-cli": "4.5.0",
"webpack-dev-server": "3.11.2",
@ -38,14 +41,14 @@
"@babel/runtime": "^7.12.5",
"attr-accept": "^2.2.2",
"axios": "^0.21.0",
"copy-to-clipboard": "^3.2.0",
"email-addresses": "^3.1.0",
"fast-deep-equal": "^3.1.3",
"i18next": "^19.8.4",
"i18next-http-backend": "^1.1.0",
"mobx": "^6.1.1",
"mobx-react": "^7.1.0",
"moment": "^2.29.1",
"copy-to-clipboard": "^3.2.0",
"fast-deep-equal": "^3.1.3",
"prop-types": "^15.7.2",
"rc-tree": "^2.1.4",
"re-resizable": "^6.9.0",
@ -56,8 +59,8 @@
"react-device-detect": "^1.14.0",
"react-dom": "^17.0.1",
"react-dropzone": "^11.2.4",
"react-i18next": "^11.7.3",
"react-hammerjs": "^1.0.1",
"react-i18next": "^11.7.3",
"react-onclickoutside": "^6.9.0",
"react-player": "^1.15.3",
"react-resize-detector": "^5.2.0",
@ -75,8 +78,8 @@
"resize-image": "^0.1.0",
"sass": "^1.29.0",
"sass-loader": "^10.1.0",
"sjcl": "^1.0.8",
"screenfull": "^5.1.0",
"sjcl": "^1.0.8",
"styled-components": "^5.2.1",
"workbox-window": "^6.1.1"
}

View File

@ -19,7 +19,7 @@ import { setDocumentTitle } from "../../helpers/utils";
import { inject } from "mobx-react";
import i18n from "../../i18n";
import { I18nextProvider } from "react-i18next";
import { combineUrl, deleteCookie } from "@appserver/common/utils";
import { toCommunityHostname, deleteCookie } from "@appserver/common/utils";
const commonStyles = `
.link-box {
@ -121,12 +121,10 @@ const Body = ({ modules, match, isLoaded, setCurrentProductId, t, tReady }) => {
const { error } = match.params;
const { pathname, protocol, hostname } = window.location;
const currentModule = modules.find((m) => m.link === pathname);
const { id, title, imageUrl, link, originUrl, helpUrl } = currentModule;
const url = originUrl ? originUrl : link;
const webLink = combineUrl(
protocol + "//" + hostname,
`${url}?desktop_view=true`
);
const { id, title, imageUrl, /*link, originUrl,*/ helpUrl } = currentModule;
//const url = originUrl ? originUrl : link;
const communityHostname = toCommunityHostname(hostname);
const webLink = `${protocol}//${communityHostname}/addons/calendar/?desktop_view=true`;
const appLink = isIOS
? id === "2A923037-8B2D-487b-9A22-5AC0918ACF3F"
? "message:"

View File

@ -5,6 +5,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.9" />
</ItemGroup>

View File

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Autofac.Extensions.DependencyInjection;
@ -12,19 +13,23 @@ namespace ASC.Calendar
{
public class Program
{
public static void Main(string[] args)
public async static Task Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSystemd()
.UseWindowsService()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureAppConfiguration((hostingContext, config) =>
.ConfigureAppConfiguration((hostingContext, config) =>
{
var buided = config.Build();
var path = buided["pathToConf"];

View File

@ -1,31 +1,29 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:5023",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"Kestrel WebServer": {
"commandName": "Project",
"launchBrowser": false,
"launchUrl": "http://localhost:5023/api/2.0/calendar/info",
"environmentVariables": {
"$STORAGE_ROOT": "../../../Data",
"log__dir": "../../../Logs",
"log__name": "calendar",
"ASPNETCORE_URLS": "http://localhost:5023",
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"ASC.Calendar": {
"commandName": "Project",
"WSL 2 : Ubuntu 20.04": {
"commandName": "WSL2",
"launchBrowser": false,
"launchUrl": "http://localhost:5023/api/2.0/calendar/info",
"environmentVariables": {
"$STORAGE_ROOT": "../../../Data",
"log__dir": "../../../Logs",
"log__name": "calendar",
"ASPNETCORE_URLS": "http://localhost:5023",
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:5023"
"distributionName": "Ubuntu-20.04"
}
}
}

View File

@ -1,7 +1,6 @@
{
"name": "@appserver/files",
"version": "0.1.8",
"private": "true",
"version": "0.1.9",
"homepage": "/products/files",
"id": "e67be73d-f9ae-4ce1-8fec-1880cb518cb4",
"title": "ONLYOFFICE",
@ -9,8 +8,9 @@
"start": "webpack-cli serve",
"start-prod": "webpack --mode production && serve dist -p 5008",
"build": "webpack --mode production",
"deploy": "mkdirp ../../../build/deploy/products/ASC.Files/client && cp -r -u dist/* ../../../build/deploy/products/ASC.Files/client",
"serve": "serve dist -p 5008",
"clean": "rm -rf dist"
"clean": "rimraf dist"
},
"devDependencies": {
"@babel/core": "^7.12.10",
@ -28,11 +28,14 @@
"interpolate-html-plugin": "^4.0.0",
"json-loader": "^0.5.7",
"mini-css-extract-plugin": "^1.3.9",
"mkdirp": "^1.0.4",
"rimraf": "^3.0.2",
"sass": "^1.29.0",
"sass-loader": "^10.1.0",
"serve": "11.3.2",
"source-map-loader": "^1.1.2",
"style-loader": "1.2.1",
"terser-webpack-plugin": "^5.1.1",
"webpack": "5.14.0",
"webpack-cli": "4.5.0",
"webpack-dev-server": "3.11.2",

View File

@ -83,7 +83,7 @@ export default function withContextOptions(WrappedComponent) {
onClickLinkForPortal = () => {
const { item, homepage, t } = this.props;
const { fileExst, canOpenPlayer, webUrl } = item;
const { fileExst, canOpenPlayer, webUrl, id } = item;
const isFile = !!fileExst;
copy(
@ -151,11 +151,8 @@ export default function withContextOptions(WrappedComponent) {
item,
setRemoveItem,
setDeleteThirdPartyDialogVisible,
confirmDelete,
setDeleteDialogVisible,
t,
deleteFileAction,
deleteFolderAction,
deleteItemAction,
isThirdPartyFolder,
} = this.props;
const { id, title, fileExst, contentLength, folderId, parentId } = item;
@ -167,21 +164,13 @@ export default function withContextOptions(WrappedComponent) {
return;
}
if (confirmDelete) {
setDeleteDialogVisible(true);
} else {
const translations = {
deleteOperation: t("DeleteOperation"),
};
const translations = {
deleteOperation: t("DeleteOperation"),
successRemoveFile: t("FileRemoved"),
successRemoveFolder: t("FolderRemoved"),
};
fileExst || contentLength
? deleteFileAction(id, folderId, translations)
.then(() => toastr.success(t("FileRemoved")))
.catch((err) => toastr.error(err))
: deleteFolderAction(id, parentId, translations)
.then(() => toastr.success(t("FolderRemoved")))
.catch((err) => toastr.error(err));
}
deleteItemAction(id, folderId, translations, fileExst || contentLength);
};
onClickShare = () => {
@ -426,7 +415,6 @@ export default function withContextOptions(WrappedComponent) {
auth,
versionHistoryStore,
mediaViewerDataStore,
settingsStore,
selectedFolderStore,
dialogsStore,
treeFoldersStore,
@ -442,9 +430,8 @@ export default function withContextOptions(WrappedComponent) {
downloadAction,
duplicateAction,
setThirdpartyInfo,
deleteFileAction,
deleteFolderAction,
onSelectItem,
deleteItemAction,
} = filesActionsStore;
const {
setChangeOwnerPanelVisible,
@ -453,7 +440,6 @@ export default function withContextOptions(WrappedComponent) {
setDownloadDialogVisible,
setRemoveItem,
setDeleteThirdPartyDialogVisible,
setDeleteDialogVisible,
setSharingPanelVisible,
} = dialogsStore;
const { isTabletView } = auth.settingsStore;
@ -486,10 +472,7 @@ export default function withContextOptions(WrappedComponent) {
setMediaViewerData,
setRemoveItem,
setDeleteThirdPartyDialogVisible,
confirmDelete: settingsStore.confirmDelete,
setDeleteDialogVisible,
deleteFileAction,
deleteFolderAction,
deleteItemAction,
isThirdPartyFolder,
onSelectItem,
setSharingPanelVisible,

View File

@ -70,6 +70,7 @@ export default function withFileActions(WrappedFileItem) {
onDropZoneUpload = (files, uploadToFolder) => {
const {
t,
selectedFolderId,
dragging,
setDragging,

View File

@ -80,6 +80,7 @@ const ServiceItem = (props) => {
const dataProps = {
"data-link": capabilityLink,
"data-title": capabilityName,
"data-key": capabilityName,
};
return (

View File

@ -473,7 +473,6 @@ export default inject(
({ auth, filesStore, treeFoldersStore, selectedFolderStore }) => {
const {
filter,
setFilter,
selection,
setIsLoading,
dragging,
@ -509,7 +508,6 @@ export default inject(
setDragging,
setIsLoading,
setTreeFolders,
setFilter,
setExpandedKeys,
setExpandedPanelKeys,
};

View File

@ -117,10 +117,14 @@ export default inject(
}) => {
const { fetchFiles, filter, setIsLoading } = filesStore;
const { treeFolders, setSelectedNode, setTreeFolders } = treeFoldersStore;
const selectedNode = treeFoldersStore.selectedTreeNode;
const selectedTreeNode =
treeFoldersStore.selectedTreeNode.length > 0 &&
treeFoldersStore.selectedTreeNode[0] !== "@my"
? treeFoldersStore.selectedTreeNode
selectedNode.length > 0 &&
selectedNode[0] !== "@my" &&
selectedNode[0] !== "@common"
? selectedNode
: [selectedFolderStore.id + ""];
const { setNewFilesPanelVisible, setNewFilesIds } = dialogsStore;

View File

@ -24,6 +24,10 @@ const Badges = ({
}) => {
const { id, locked, fileStatus, versionGroup, title, fileExst } = item;
const isFavorite = fileStatus === 32;
const isEditing = fileStatus === 1;
const isNewWithFav = fileStatus === 34;
return fileExst ? (
<div className="badges additional-badges">
{/* TODO: Uncomment after fix conversation {canConvert && !isTrashFolder && (
@ -57,7 +61,7 @@ const Badges = ({
onClick={onClickLock}
/>
)}
{fileStatus === 32 && !isTrashFolder && (
{(isFavorite || isNewWithFav) && !isTrashFolder && (
<StyledFavoriteIcon
className="favorite icons-group"
size="small"
@ -67,7 +71,7 @@ const Badges = ({
onClick={onClickFavorite}
/>
)}
{fileStatus === 1 && (
{isEditing && (
<StyledFileActionsConvertEditDocIcon className="badge" size="small" />
)}
{versionGroup > 1 && (
@ -85,7 +89,7 @@ const Badges = ({
data-id={id}
/>
)}
{showNew && (
{(showNew || isNewWithFav) && (
<Badge
className="badge-version icons-group"
backgroundColor="#ED7309"

View File

@ -110,52 +110,50 @@ const ConflictResolveDialog = (props) => {
const file = items[0].title;
return (
<ModalDialogContainer>
<ModalDialog visible={visible} onClose={onClose}>
<ModalDialog.Header>{t("ConflictResolveTitle")}</ModalDialog.Header>
<ModalDialog.Body>
<Text className="conflict-resolve-dialog-text">
{singleFile
? t("ConflictResolveDescription", { file, folder: folderTitle })
: t("ConflictResolveDescriptionFiles", {
filesCount,
folder: folderTitle,
})}
</Text>
<Text className="conflict-resolve-dialog-text">
{t("ConflictResolveSelectAction")}
</Text>
<RadioButtonGroup
className="conflict-resolve-radio-button"
orientation="vertical"
fontSize="13px"
fontWeight="400"
name="group"
onClick={onSelectResolveType}
options={radioOptions}
selected="overwrite"
/>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
className="button-dialog-accept"
key="OkButton"
label={t("OKButton")}
size="medium"
primary
onClick={onAcceptType}
//isLoading={isLoading}
/>
<Button
className="button-dialog"
key="CancelButton"
label={t("CancelButton")}
size="medium"
onClick={onClose}
//isLoading={isLoading}
/>
</ModalDialog.Footer>
</ModalDialog>
<ModalDialogContainer visible={visible} onClose={onClose}>
<ModalDialog.Header>{t("ConflictResolveTitle")}</ModalDialog.Header>
<ModalDialog.Body>
<Text className="conflict-resolve-dialog-text">
{singleFile
? t("ConflictResolveDescription", { file, folder: folderTitle })
: t("ConflictResolveDescriptionFiles", {
filesCount,
folder: folderTitle,
})}
</Text>
<Text className="conflict-resolve-dialog-text">
{t("ConflictResolveSelectAction")}
</Text>
<RadioButtonGroup
className="conflict-resolve-radio-button"
orientation="vertical"
fontSize="13px"
fontWeight="400"
name="group"
onClick={onSelectResolveType}
options={radioOptions}
selected="overwrite"
/>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
className="button-dialog-accept"
key="OkButton"
label={t("OKButton")}
size="medium"
primary
onClick={onAcceptType}
//isLoading={isLoading}
/>
<Button
className="button-dialog"
key="CancelButton"
label={t("CancelButton")}
size="medium"
onClick={onClose}
//isLoading={isLoading}
/>
</ModalDialog.Footer>
</ModalDialogContainer>
);
};

View File

@ -31,11 +31,17 @@ const PureConnectDialogContainer = (props) => {
openConnectWindow,
setConnectDialogVisible,
} = props;
const { corporate, title, link, token, provider_id, provider_key } = item;
const {
corporate,
title,
link,
token,
provider_id,
provider_key,
key,
} = item;
const provider = providers.find(
(el) => el.provider_key === item.provider_key
);
const provider = providers.find((el) => el.provider_id === item.provider_id);
const folderTitle = provider ? provider.customer_title : title;
const [urlValue, setUrlValue] = useState("");
@ -105,13 +111,13 @@ const PureConnectDialogContainer = (props) => {
setIsLoading(true);
saveThirdParty(
null,
null,
null,
urlValue,
loginValue,
passwordValue,
oAuthToken,
isCorporate,
customerTitle,
provider_key,
provider_key || key,
provider_id
)
.then((folderData) => {
@ -155,7 +161,6 @@ const PureConnectDialogContainer = (props) => {
})
.catch((err) => {
toastr.error(err);
onClose();
setIsLoading(false);
});
}, [
@ -234,6 +239,7 @@ const PureConnectDialogContainer = (props) => {
errorMessage={t("RequiredFieldMessage")}
>
<TextInput
isAutoFocussed={true}
hasError={!isUrlValid}
isDisabled={isLoading}
tabIndex={1}

View File

@ -31,53 +31,51 @@ class ConvertDialogComponent extends React.Component {
const { saveOriginalFormat, hideMessage } = this.state;
return (
<ModalDialogContainer>
<ModalDialog visible={visible} onClose={this.onClose}>
<ModalDialog.Header>{t("ConversionTitle")}</ModalDialog.Header>
<ModalDialog.Body>
<div className="convert_dialog_content">
<img
className="convert_dialog_image"
src="images/convert_alert.png"
alt="convert alert"
<ModalDialogContainer visible={visible} onClose={this.onClose}>
<ModalDialog.Header>{t("ConversionTitle")}</ModalDialog.Header>
<ModalDialog.Body>
<div className="convert_dialog_content">
<img
className="convert_dialog_image"
src="images/convert_alert.png"
alt="convert alert"
/>
<div className="convert_dialog-content">
<Text>{t("ConversionMessage")}</Text>
<Checkbox
className="convert_dialog_checkbox"
label={t("SaveOriginalFormatMessage")}
isChecked={saveOriginalFormat}
onChange={this.onChangeFormat}
/>
<div className="convert_dialog-content">
<Text>{t("ConversionMessage")}</Text>
<Checkbox
className="convert_dialog_checkbox"
label={t("SaveOriginalFormatMessage")}
isChecked={saveOriginalFormat}
onChange={this.onChangeFormat}
/>
<Checkbox
className="convert_dialog_checkbox"
label={t("HideMessage")}
isChecked={hideMessage}
onChange={this.onChangeMessageVisible}
/>
</div>
</div>
</ModalDialog.Body>
<ModalDialog.Footer>
<div className="convert_dialog_footer">
<Button
className="convert_dialog_button-accept"
key="ContinueButton"
label={t("ContinueButton")}
size="medium"
primary
onClick={this.onConvert}
/>
<Button
className="convert_dialog_button"
key="CloseButton"
label={t("CloseButton")}
size="medium"
onClick={this.onClose}
<Checkbox
className="convert_dialog_checkbox"
label={t("HideMessage")}
isChecked={hideMessage}
onChange={this.onChangeMessageVisible}
/>
</div>
</ModalDialog.Footer>
</ModalDialog>
</div>
</ModalDialog.Body>
<ModalDialog.Footer>
<div className="convert_dialog_footer">
<Button
className="convert_dialog_button-accept"
key="ContinueButton"
label={t("ContinueButton")}
size="medium"
primary
onClick={this.onConvert}
/>
<Button
className="convert_dialog_button"
key="CloseButton"
label={t("CloseButton")}
size="medium"
onClick={this.onClose}
/>
</div>
</ModalDialog.Footer>
</ModalDialogContainer>
);
}

View File

@ -77,7 +77,10 @@ class DeleteDialogComponent extends React.Component {
}
};
onClose = () => this.props.setDeleteDialogVisible(false);
onClose = () => {
this.props.setRemoveMediaItem(null);
this.props.setDeleteDialogVisible(false);
};
render() {
const { visible, t, isLoading } = this.props;
@ -112,69 +115,67 @@ class DeleteDialogComponent extends React.Component {
const height = filesHeight + foldersHeight;
return (
<ModalDialogContainer>
<ModalDialog visible={visible} onClose={this.onClose}>
<ModalDialog.Header>{title}</ModalDialog.Header>
<ModalDialog.Body>
<div className="modal-dialog-content">
<Text className="delete_dialog-header-text">{noteText}</Text>
<Scrollbar style={{ height, maxHeight: 330 }} stype="mediumBlack">
{foldersList.length > 0 && (
<Text isBold className="delete_dialog-text">
{t("FoldersModule")}:
</Text>
)}
{foldersList.map((item, index) => (
<Checkbox
truncate
className="modal-dialog-checkbox"
value={`${item.fileExst}/${item.id}`}
onChange={this.onChange}
key={`checkbox_${index}`}
isChecked={item.checked}
label={item.title}
/>
))}
<ModalDialogContainer visible={visible} onClose={this.onClose}>
<ModalDialog.Header>{title}</ModalDialog.Header>
<ModalDialog.Body>
<div className="modal-dialog-content">
<Text className="delete_dialog-header-text">{noteText}</Text>
<Scrollbar style={{ height, maxHeight: 330 }} stype="mediumBlack">
{foldersList.length > 0 && (
<Text isBold className="delete_dialog-text">
{t("FoldersModule")}:
</Text>
)}
{foldersList.map((item, index) => (
<Checkbox
truncate
className="modal-dialog-checkbox"
value={`${item.fileExst}/${item.id}`}
onChange={this.onChange}
key={`checkbox_${index}`}
isChecked={item.checked}
label={item.title}
/>
))}
{filesList.length > 0 && (
<Text isBold className="delete_dialog-text">
{t("FilesModule")}:
</Text>
)}
{filesList.map((item, index) => (
<Checkbox
truncate
className="modal-dialog-checkbox"
value={`${item.fileExst}/${item.id}`}
onChange={this.onChange}
key={`checkbox_${index}`}
isChecked={item.checked}
label={item.title}
/>
))}
</Scrollbar>
</div>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
className="button-dialog-accept"
key="OkButton"
label={t("MoveToTrashButton")}
size="medium"
primary
onClick={this.onDelete}
isLoading={isLoading}
/>
<Button
className="button-dialog"
key="CancelButton"
label={t("CancelButton")}
size="medium"
onClick={this.onClose}
isLoading={isLoading}
/>
</ModalDialog.Footer>
</ModalDialog>
{filesList.length > 0 && (
<Text isBold className="delete_dialog-text">
{t("FilesModule")}:
</Text>
)}
{filesList.map((item, index) => (
<Checkbox
truncate
className="modal-dialog-checkbox"
value={`${item.fileExst}/${item.id}`}
onChange={this.onChange}
key={`checkbox_${index}`}
isChecked={item.checked}
label={item.title}
/>
))}
</Scrollbar>
</div>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
className="button-dialog-accept"
key="OkButton"
label={t("MoveToTrashButton")}
size="medium"
primary
onClick={this.onDelete}
isLoading={isLoading}
/>
<Button
className="button-dialog"
key="CancelButton"
label={t("CancelButton")}
size="medium"
onClick={this.onClose}
isLoading={isLoading}
/>
</ModalDialog.Footer>
</ModalDialogContainer>
);
}
@ -210,11 +211,13 @@ export default inject(
const {
deleteDialogVisible: visible,
setDeleteDialogVisible,
removeMediaItem,
setRemoveMediaItem,
} = dialogsStore;
return {
currentFolderId: selectedFolderStore.id,
selection,
selection: removeMediaItem ? [removeMediaItem] : selection,
isLoading,
treeFolders,
isRecycleBinFolder,
@ -229,6 +232,8 @@ export default inject(
clearSecondaryProgressData,
setDeleteDialogVisible,
deleteAction,
setRemoveMediaItem,
};
}
)(withRouter(observer(DeleteDialog)));

View File

@ -1,4 +1,4 @@
import React from "react";
import React, { useState } from "react";
import { withRouter } from "react-router";
import ModalDialog from "@appserver/components/modal-dialog";
import Button from "@appserver/components/button";
@ -8,35 +8,41 @@ import toastr from "studio/toastr";
import { loopTreeFolders } from "../../../helpers/files-helpers";
import { inject, observer } from "mobx-react";
class DeleteThirdPartyDialogComponent extends React.Component {
updateTree = (path, folders) => {
const { t, treeFolders, removeItem, setTreeFolders } = this.props;
const DeleteThirdPartyDialog = (props) => {
const {
t,
myId,
visible,
commonId,
providers,
removeItem,
fetchFiles,
treeFolders,
setTreeFolders,
currentFolderId,
deleteThirdParty,
setThirdPartyProviders,
setDeleteThirdPartyDialogVisible,
} = props;
const [isLoading, setIsLoading] = useState(false);
const updateTree = (path, folders) => {
const newTreeFolders = treeFolders;
loopTreeFolders(path, newTreeFolders, folders, null);
setTreeFolders(newTreeFolders);
toastr.success(t("SuccessDeleteThirdParty", { service: removeItem.title }));
};
onClose = () => this.props.setDeleteThirdPartyDialogVisible(false);
onDeleteThirdParty = () => {
const {
setThirdPartyProviders,
removeItem,
providers,
fetchFiles,
currentFolderId,
commonId,
myId,
deleteThirdParty,
} = this.props;
const onClose = () => setDeleteThirdPartyDialogVisible(false);
const onDeleteThirdParty = () => {
const providerItem = providers.find((x) => x.provider_id === removeItem.id);
const newProviders = providers.filter(
(x) => x.provider_id !== removeItem.id
);
setIsLoading(true);
deleteThirdParty(+removeItem.id)
.then(() => {
setThirdPartyProviders(newProviders);
@ -44,45 +50,41 @@ class DeleteThirdPartyDialogComponent extends React.Component {
fetchFiles(currentFolderId).then((data) => {
const path = data.selectedFolder.pathParts;
const folders = data.selectedFolder.folders;
this.updateTree(path, folders);
updateTree(path, folders);
});
} else {
const folderId = providerItem.corporate ? commonId : myId;
getFolder(folderId).then((data) => {
const path = [folderId];
this.updateTree(path, data.folders);
updateTree(path, data.folders);
});
}
})
.catch((err) => toastr.error(err))
.finally(() => this.onClose());
.finally(() => {
onClose();
setIsLoading(false);
});
};
render() {
const { visible, t, removeItem } = this.props;
return (
<ModalDialog visible={visible} zIndex={310} onClose={this.onClose}>
<ModalDialog.Header>{t("DeleteThirdParty")}</ModalDialog.Header>
<ModalDialog.Body>
{t("DeleteThirdPartyAlert", { service: removeItem.title })}
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
label={t("OKButton")}
size="big"
primary
onClick={this.onDeleteThirdParty}
/>
</ModalDialog.Footer>
</ModalDialog>
);
}
}
const DeleteThirdPartyDialog = withTranslation("DeleteThirdPartyDialog")(
DeleteThirdPartyDialogComponent
);
return (
<ModalDialog visible={visible} zIndex={310} onClose={onClose}>
<ModalDialog.Header>{t("DeleteThirdParty")}</ModalDialog.Header>
<ModalDialog.Body>
{t("DeleteThirdPartyAlert", { service: removeItem.title })}
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
isLoading={isLoading}
label={t("OKButton")}
size="big"
primary
onClick={onDeleteThirdParty}
/>
</ModalDialog.Footer>
</ModalDialog>
);
};
export default inject(
({
@ -128,4 +130,8 @@ export default inject(
setDeleteThirdPartyDialogVisible,
};
}
)(withRouter(observer(DeleteThirdPartyDialog)));
)(
withRouter(
withTranslation("DeleteThirdPartyDialog")(observer(DeleteThirdPartyDialog))
)
);

View File

@ -5,6 +5,7 @@ import RowContainer from "@appserver/components/row-container";
import Text from "@appserver/components/text";
import LinkWithDropdown from "@appserver/components/link-with-dropdown";
import styled from "styled-components";
import { FilesFormats } from "@appserver/common/constants";
const StyledDownloadContent = styled.div`
.row_content,
@ -19,7 +20,6 @@ const DownloadContent = (props) => {
checkedTitle,
indeterminateTitle,
items,
formatKeys,
onSelectFormat,
onRowSelect,
getItemIcon,
@ -35,7 +35,7 @@ const DownloadContent = (props) => {
label: t("OriginalFormat"),
onClick: onSelectFormat.bind(
this,
formatKeys.OriginalFormat,
FilesFormats.OriginalFormat,
item,
"document"
),
@ -45,7 +45,7 @@ const DownloadContent = (props) => {
label: ".txt",
onClick: onSelectFormat.bind(
this,
formatKeys.TxtFormat,
FilesFormats.TxtFormat,
item,
"document"
),
@ -55,7 +55,7 @@ const DownloadContent = (props) => {
label: ".docx",
onClick: onSelectFormat.bind(
this,
formatKeys.DocxFormat,
FilesFormats.DocxFormat,
item,
"document"
),
@ -65,7 +65,7 @@ const DownloadContent = (props) => {
label: ".odt",
onClick: onSelectFormat.bind(
this,
formatKeys.OdtFormat,
FilesFormats.OdtFormat,
item,
"document"
),
@ -75,7 +75,7 @@ const DownloadContent = (props) => {
label: ".pdf",
onClick: onSelectFormat.bind(
this,
formatKeys.PdfFormat,
FilesFormats.PdfFormat,
item,
"document"
),
@ -85,7 +85,7 @@ const DownloadContent = (props) => {
label: ".rtf",
onClick: onSelectFormat.bind(
this,
formatKeys.RtfFormat,
FilesFormats.RtfFormat,
item,
"document"
),
@ -95,7 +95,7 @@ const DownloadContent = (props) => {
label: t("CustomFormat"),
onClick: onSelectFormat.bind(
this,
formatKeys.CustomFormat,
FilesFormats.CustomFormat,
item,
"document"
),
@ -108,7 +108,7 @@ const DownloadContent = (props) => {
label: t("OriginalFormat"),
onClick: onSelectFormat.bind(
this,
formatKeys.OriginalFormat,
FilesFormats.OriginalFormat,
item,
"presentation"
),
@ -118,7 +118,7 @@ const DownloadContent = (props) => {
label: ".odp",
onClick: onSelectFormat.bind(
this,
formatKeys.OdpFormat,
FilesFormats.OdpFormat,
item,
"presentation"
),
@ -128,7 +128,7 @@ const DownloadContent = (props) => {
label: ".pdf",
onClick: onSelectFormat.bind(
this,
formatKeys.PdfFormat,
FilesFormats.PdfFormat,
item,
"presentation"
),
@ -138,7 +138,7 @@ const DownloadContent = (props) => {
label: ".pptx",
onClick: onSelectFormat.bind(
this,
formatKeys.PptxFormat,
FilesFormats.PptxFormat,
item,
"presentation"
),
@ -148,7 +148,7 @@ const DownloadContent = (props) => {
label: t("CustomFormat"),
onClick: onSelectFormat.bind(
this,
formatKeys.CustomFormat,
FilesFormats.CustomFormat,
item,
"presentation"
),
@ -161,7 +161,7 @@ const DownloadContent = (props) => {
label: t("OriginalFormat"),
onClick: onSelectFormat.bind(
this,
formatKeys.OriginalFormat,
FilesFormats.OriginalFormat,
item,
"spreadsheet"
),
@ -171,7 +171,7 @@ const DownloadContent = (props) => {
label: ".odp",
onClick: onSelectFormat.bind(
this,
formatKeys.OdsFormat,
FilesFormats.OdsFormat,
item,
"spreadsheet"
),
@ -181,7 +181,7 @@ const DownloadContent = (props) => {
label: ".pdf",
onClick: onSelectFormat.bind(
this,
formatKeys.PdfFormat,
FilesFormats.PdfFormat,
item,
"spreadsheet"
),
@ -191,7 +191,7 @@ const DownloadContent = (props) => {
label: ".xlsx",
onClick: onSelectFormat.bind(
this,
formatKeys.XlsxFormat,
FilesFormats.XlsxFormat,
item,
"spreadsheet"
),
@ -201,7 +201,7 @@ const DownloadContent = (props) => {
label: t("CustomFormat"),
onClick: onSelectFormat.bind(
this,
formatKeys.CustomFormat,
FilesFormats.CustomFormat,
item,
"spreadsheet"
),
@ -256,18 +256,22 @@ const DownloadContent = (props) => {
</Text>
<></>
<Text fontSize="12px" containerWidth="auto">
{t("ConvertInto")}
{(checkedTitle || indeterminateTitle) && t("ConvertInto")}
</Text>
<LinkWithDropdown
containerWidth="auto"
data={formats}
directionX="left"
directionY="bottom"
dropdownType="appearDashedAfterHover"
fontSize="12px"
>
{documentsTitle}
</LinkWithDropdown>
{checkedTitle || indeterminateTitle ? (
<LinkWithDropdown
containerWidth="auto"
data={formats}
directionX="left"
directionY="bottom"
dropdownType="appearDashedAfterHover"
fontSize="12px"
>
{documentsTitle}
</LinkWithDropdown>
) : (
<></>
)}
</RowContent>
</Row>
)}
@ -297,19 +301,26 @@ const DownloadContent = (props) => {
{file.title}
</Text>
<></>
<Text fontSize="12px" containerWidth="auto">
{file.checked && t("ConvertInto")}
</Text>
<LinkWithDropdown
dropdownType="appearDashedAfterHover"
containerWidth="auto"
data={dropdownItems}
directionX="left"
directionY="bottom"
fontSize="12px"
>
{format}
</LinkWithDropdown>
{file.checked && (
<Text fontSize="12px" containerWidth="auto">
{t("ConvertInto")}
</Text>
)}
{file.checked ? (
<LinkWithDropdown
dropdownType="appearDashedAfterHover"
containerWidth="auto"
data={dropdownItems}
directionX="left"
directionY="bottom"
fontSize="12px"
>
{format}
</LinkWithDropdown>
) : (
<></>
)}
</RowContent>
</Row>
);

View File

@ -13,20 +13,7 @@ import { downloadFormatFiles } from "@appserver/common/api/files";
import { TIMEOUT } from "../../../helpers/constants";
import DownloadContent from "./DownloadContent";
import { inject, observer } from "mobx-react";
const formatKeys = Object.freeze({
OriginalFormat: 0,
TxtFormat: 1,
DocxFormat: 2,
OdtFormat: 3,
OdsFormat: 4,
OdpFormat: 5,
PdfFormat: 6,
RtfFormat: 7,
XlsxFormat: 8,
PptxFormat: 9,
CustomFormat: 10,
});
import { FilesFormats } from "@appserver/common/constants";
class DownloadDialogComponent extends React.Component {
constructor(props) {
@ -39,9 +26,9 @@ class DownloadDialogComponent extends React.Component {
presentations: sortedFiles.presentations,
other: sortedFiles.other,
documentsTitleFormat: formatKeys.OriginalFormat,
spreadsheetsTitleFormat: formatKeys.OriginalFormat,
presentationsTitleFormat: formatKeys.OriginalFormat,
documentsTitleFormat: FilesFormats.OriginalFormat,
spreadsheetsTitleFormat: FilesFormats.OriginalFormat,
presentationsTitleFormat: FilesFormats.OriginalFormat,
checkedDocTitle: true,
checkedSpreadsheetTitle: true,
@ -192,8 +179,8 @@ class DownloadDialogComponent extends React.Component {
if (!file) {
for (let file of newDocuments) {
file.format =
format === formatKeys.CustomFormat || file.fileExst === format
? formatKeys.OriginalFormat
format === FilesFormats.CustomFormat || file.fileExst === format
? FilesFormats.OriginalFormat
: format;
}
this.setState({
@ -207,7 +194,7 @@ class DownloadDialogComponent extends React.Component {
newDoc.format = format;
this.setState({
documents: newDocuments,
documentsTitleFormat: formatKeys.CustomFormat,
documentsTitleFormat: FilesFormats.CustomFormat,
});
}
}
@ -216,8 +203,8 @@ class DownloadDialogComponent extends React.Component {
if (!file) {
for (let file of newSpreadsheets) {
file.format =
format === formatKeys.CustomFormat || file.fileExst === format
? formatKeys.OriginalFormat
format === FilesFormats.CustomFormat || file.fileExst === format
? FilesFormats.OriginalFormat
: format;
}
this.setState({
@ -231,7 +218,7 @@ class DownloadDialogComponent extends React.Component {
newSpreadsheet.format = format;
this.setState({
spreadsheets: newSpreadsheets,
spreadsheetsTitleFormat: formatKeys.CustomFormat,
spreadsheetsTitleFormat: FilesFormats.CustomFormat,
});
}
}
@ -240,8 +227,8 @@ class DownloadDialogComponent extends React.Component {
if (!file) {
for (let file of newPresentations) {
file.format =
format === formatKeys.CustomFormat || file.fileExst === format
? formatKeys.OriginalFormat
format === FilesFormats.CustomFormat || file.fileExst === format
? FilesFormats.OriginalFormat
: format;
}
this.setState({
@ -255,7 +242,7 @@ class DownloadDialogComponent extends React.Component {
newPresentation.format = format;
this.setState({
presentations: newPresentations,
presentationsTitleFormat: formatKeys.CustomFormat,
presentationsTitleFormat: FilesFormats.CustomFormat,
});
}
}
@ -428,7 +415,6 @@ class DownloadDialogComponent extends React.Component {
} = this.state;
const otherLength = other.length;
const showOther = otherLength > 1;
const minHeight = otherLength > 2 ? 110 : otherLength * 50;
@ -436,144 +422,134 @@ class DownloadDialogComponent extends React.Component {
documents.filter((f) => f.checked).length +
spreadsheets.filter((f) => f.checked).length +
presentations.filter((f) => f.checked).length +
other.filter((f) => f.checked).length ===
other.filter((f) => f.checked).length <=
1;
return (
<ModalDialogContainer>
<ModalDialog visible={visible} onClose={this.onClose}>
<ModalDialog.Header>{t("DownloadAs")}</ModalDialog.Header>
<ModalDialog.Body>
<Text>{t("ChooseFormatText")}</Text>
{documents.length > 0 && (
<DownloadContent
t={t}
checkedTitle={checkedDocTitle}
indeterminateTitle={indeterminateDocTitle}
items={documents}
formatKeys={formatKeys}
onSelectFormat={this.onSelectFormat}
onRowSelect={this.onRowSelect}
getItemIcon={this.getItemIcon}
getTitleLabel={this.getTitleLabel}
titleFormat={documentsTitleFormat}
type="document"
/>
)}
<ModalDialogContainer visible={visible} onClose={this.onClose}>
<ModalDialog.Header>{t("DownloadAs")}</ModalDialog.Header>
<ModalDialog.Body>
<Text>{t("ChooseFormatText")}</Text>
{documents.length > 0 && (
<DownloadContent
t={t}
checkedTitle={checkedDocTitle}
indeterminateTitle={indeterminateDocTitle}
items={documents}
onSelectFormat={this.onSelectFormat}
onRowSelect={this.onRowSelect}
getItemIcon={this.getItemIcon}
getTitleLabel={this.getTitleLabel}
titleFormat={documentsTitleFormat}
type="document"
/>
)}
{spreadsheets.length > 0 && (
<DownloadContent
t={t}
checkedTitle={checkedSpreadsheetTitle}
indeterminateTitle={indeterminateSpreadsheetTitle}
items={spreadsheets}
formatKeys={formatKeys}
onSelectFormat={this.onSelectFormat}
onRowSelect={this.onRowSelect}
getItemIcon={this.getItemIcon}
getTitleLabel={this.getTitleLabel}
titleFormat={spreadsheetsTitleFormat}
type="spreadsheet"
/>
)}
{spreadsheets.length > 0 && (
<DownloadContent
t={t}
checkedTitle={checkedSpreadsheetTitle}
indeterminateTitle={indeterminateSpreadsheetTitle}
items={spreadsheets}
onSelectFormat={this.onSelectFormat}
onRowSelect={this.onRowSelect}
getItemIcon={this.getItemIcon}
getTitleLabel={this.getTitleLabel}
titleFormat={spreadsheetsTitleFormat}
type="spreadsheet"
/>
)}
{presentations.length > 0 && (
<DownloadContent
t={t}
checkedTitle={checkedPresentationTitle}
indeterminateTitle={indeterminatePresentationTitle}
items={presentations}
formatKeys={formatKeys}
onSelectFormat={this.onSelectFormat}
onRowSelect={this.onRowSelect}
getItemIcon={this.getItemIcon}
getTitleLabel={this.getTitleLabel}
titleFormat={presentationsTitleFormat}
type="presentation"
/>
)}
{presentations.length > 0 && (
<DownloadContent
t={t}
checkedTitle={checkedPresentationTitle}
indeterminateTitle={indeterminatePresentationTitle}
items={presentations}
onSelectFormat={this.onSelectFormat}
onRowSelect={this.onRowSelect}
getItemIcon={this.getItemIcon}
getTitleLabel={this.getTitleLabel}
titleFormat={presentationsTitleFormat}
type="presentation"
/>
)}
{otherLength > 0 && (
<>
{showOther && (
<Row
key="title2"
onSelect={this.onRowSelect.bind(this, "All", "other")}
checked={checkedOtherTitle}
indeterminate={indeterminateOtherTitle}
>
<RowContent>
<Text
truncate
type="page"
title={"Other"}
fontSize="14px"
>
{t("Other")}
</Text>
<></>
</RowContent>
</Row>
)}
<RowContainer
useReactWindow
style={{ minHeight: minHeight, padding: "8px 0" }}
itemHeight={50}
{otherLength > 0 && (
<>
{showOther && (
<Row
key="title2"
onSelect={this.onRowSelect.bind(this, "All", "other")}
checked={checkedOtherTitle}
indeterminate={indeterminateOtherTitle}
>
{other.map((folder) => {
const element = this.getItemIcon(folder);
return (
<Row
key={folder.id}
onSelect={this.onRowSelect.bind(this, folder, "other")}
checked={folder.checked}
element={element}
>
<RowContent>
<Text
truncate
type="page"
title={folder.title}
fontSize="14px"
>
{folder.title}
</Text>
<></>
<Text fontSize="12px" containerWidth="auto">
{folder.fileExst && t("OriginalFormat")}
</Text>
</RowContent>
</Row>
);
})}
</RowContainer>
</>
)}
<RowContent>
<Text truncate type="page" title={"Other"} fontSize="14px">
{t("Other")}
</Text>
<></>
</RowContent>
</Row>
)}
{!isSingleFile && <Text>{t("ConvertToZip")}</Text>}
<Text>{t("ConvertMessage")}</Text>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
className="button-dialog-accept"
key="DownloadButton"
label={t("DownloadButton")}
size="medium"
primary
onClick={this.onDownload}
//isLoading={isLoading}
/>
<Button
className="button-dialog"
key="CancelButton"
label={t("CancelButton")}
size="medium"
onClick={this.onClose}
//isLoading={isLoading}
/>
</ModalDialog.Footer>
</ModalDialog>
<RowContainer
useReactWindow
style={{ minHeight: minHeight, padding: "8px 0" }}
itemHeight={50}
>
{other.map((folder) => {
const element = this.getItemIcon(folder);
return (
<Row
key={folder.id}
onSelect={this.onRowSelect.bind(this, folder, "other")}
checked={folder.checked}
element={element}
>
<RowContent>
<Text
truncate
type="page"
title={folder.title}
fontSize="14px"
>
{folder.title}
</Text>
<></>
<Text fontSize="12px" containerWidth="auto">
{folder.fileExst && t("OriginalFormat")}
</Text>
</RowContent>
</Row>
);
})}
</RowContainer>
</>
)}
{!isSingleFile && <Text>{t("ConvertToZip")}</Text>}
<Text>{t("ConvertMessage")}</Text>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
className="button-dialog-accept"
key="DownloadButton"
label={t("DownloadButton")}
size="medium"
primary
onClick={this.onDownload}
//isLoading={isLoading}
/>
<Button
className="button-dialog"
key="CancelButton"
label={t("CancelButton")}
size="medium"
onClick={this.onClose}
//isLoading={isLoading}
/>
</ModalDialog.Footer>
</ModalDialogContainer>
);
}

View File

@ -115,31 +115,29 @@ const EmptyTrashDialogComponent = (props) => {
]);
return (
<ModalDialogContainer>
<ModalDialog visible={visible} onClose={onClose}>
<ModalDialog.Header>{t("DeleteForeverTitle")}</ModalDialog.Header>
<ModalDialog.Body>
<Text>{t("DeleteForeverNote")}</Text>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
key="OkButton"
label={t("DeleteForeverButton")}
size="medium"
primary
onClick={onEmptyTrash}
isLoading={isLoading}
/>
<Button
className="button-dialog"
key="CancelButton"
label={t("CancelButton")}
size="medium"
onClick={onClose}
isLoading={isLoading}
/>
</ModalDialog.Footer>
</ModalDialog>
<ModalDialogContainer visible={visible} onClose={onClose}>
<ModalDialog.Header>{t("DeleteForeverTitle")}</ModalDialog.Header>
<ModalDialog.Body>
<Text>{t("DeleteForeverNote")}</Text>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
key="OkButton"
label={t("DeleteForeverButton")}
size="medium"
primary
onClick={onEmptyTrash}
isLoading={isLoading}
/>
<Button
className="button-dialog"
key="CancelButton"
label={t("CancelButton")}
size="medium"
onClick={onClose}
isLoading={isLoading}
/>
</ModalDialog.Footer>
</ModalDialogContainer>
);
};

View File

@ -1,7 +1,8 @@
import styled from "styled-components";
import { tablet } from "@appserver/components/utils/device";
import ModalDialog from "@appserver/components/modal-dialog";
const ModalDialogContainer = styled.div`
const ModalDialogContainer = styled(ModalDialog)`
.flex {
display: flex;
justify-content: space-between;

View File

@ -52,6 +52,7 @@ const ServiceItem = (props) => {
const dataProps = {
"data-link": capabilityLink,
"data-title": capabilityName,
"data-key": capabilityName,
};
return <img {...dataProps} {...rest} alt="" />;
@ -222,6 +223,7 @@ const ThirdPartyDialog = (props) => {
onClick={onShowService}
className="service-item service-text"
data-title={webDavConnectItem[0]}
data-key={webDavConnectItem[0]}
>
{t("ConnextOtherAccount")}
</Text>

View File

@ -10,6 +10,7 @@ import AccessComboBox from "./AccessComboBox";
//import equal from "fast-deep-equal/react";
import { getAccessIcon } from "../../../helpers/files-helpers";
import { ReactSVG } from "react-svg";
import { objectToGetParams } from "@appserver/common/utils";
class SharingRow extends React.Component {
constructor(props) {
@ -49,19 +50,42 @@ class SharingRow extends React.Component {
const subject = t("ShareEmailSubject", { itemName });
const body = t("ShareEmailBody", { itemName, shareLink });
window.open(`mailto:?subject=${subject}&body=${body}`);
const mailtoLink =
"mailto:" +
objectToGetParams({
subject,
body,
});
window.open(mailtoLink);
};
onShareTwitter = () => {
const encodedLink = encodeURIComponent(this.props.item.sharedTo.shareLink);
window.open(`https://twitter.com/intent/tweet?text=${encodedLink}`);
const { item } = this.props;
const { shareLink } = item.sharedTo;
const twitterLink =
"https://twitter.com/intent/tweet" +
objectToGetParams({
text: shareLink,
});
window.open(twitterLink);
};
onShareFacebook = () => {
window.open(
`https://www.facebook.com/sharer/sharer.php?u=${this.props.item.sharedTo.shareLink}`
);
};
// onShareFacebook = () => {
// const { item, selection } = this.props;
// const { shareLink } = item.sharedTo;
// const facebookLink =
// "https://www.facebook.com/sharer/sharer.php" +
// objectToGetParams({
// u: shareLink,
// t: selection.title ? selection.title : selection[0].title,
// });
// window.open(facebookLink);
// };
render() {
//console.log("SharingRow render");
@ -120,11 +144,11 @@ class SharingRow extends React.Component {
label: `${t("ShareVia")} e-mail`,
onClick: this.onShareEmail,
},
{
key: "linkItem_3",
label: `${t("ShareVia")} Facebook`,
onClick: this.onShareFacebook,
},
// {
// key: "linkItem_3",
// label: `${t("ShareVia")} Facebook`,
// onClick: this.onShareFacebook,
// },
{
key: "linkItem_4",
label: `${t("ShareVia")} Twitter`,

View File

@ -13,11 +13,14 @@ const FilesMediaViewer = (props) => {
playlist,
visible,
currentMediaFileId,
deleteFileAction,
deleteItemAction,
setMediaViewerData,
mediaViewerMediaFormats,
mediaViewerImageFormats,
location,
setRemoveMediaItem,
selectedFolderId,
userAccess,
} = props;
useEffect(() => {
@ -60,7 +63,10 @@ const FilesMediaViewer = (props) => {
if (files.length > 0) {
let file = files.find((file) => file.id === id);
if (file) deleteFileAction(file.id, file.folderId, translations);
if (file) {
setRemoveMediaItem(file);
deleteItemAction(file.id, selectedFolderId, translations, true);
}
}
};
@ -77,6 +83,7 @@ const FilesMediaViewer = (props) => {
return (
visible && (
<MediaViewer
userAccess={userAccess}
currentFileId={currentMediaFileId}
allowConvert={true} //TODO:
canDelete={canDelete} //TODO:
@ -95,26 +102,36 @@ const FilesMediaViewer = (props) => {
};
export default inject(
({ filesStore, mediaViewerDataStore, filesActionsStore, formatsStore }) => {
const { files } = filesStore;
({
filesStore,
mediaViewerDataStore,
filesActionsStore,
formatsStore,
dialogsStore,
selectedFolderStore,
}) => {
const { files, userAccess } = filesStore;
const {
visible,
id: currentMediaFileId,
setMediaViewerData,
playlist,
} = mediaViewerDataStore;
const { deleteFileAction } = filesActionsStore;
const { deleteItemAction } = filesActionsStore;
const { media, images } = formatsStore.mediaViewersFormatsStore;
return {
files,
playlist,
userAccess,
visible: playlist.length > 0 && visible,
currentMediaFileId,
deleteFileAction,
deleteItemAction,
setMediaViewerData,
mediaViewerImageFormats: images,
mediaViewerMediaFormats: media,
setRemoveMediaItem: dialogsStore.setRemoveMediaItem,
selectedFolderId: selectedFolderStore.id,
};
}
)(withRouter(withTranslation("Home")(observer(FilesMediaViewer))));

View File

@ -103,5 +103,5 @@ const SimpleFilesRow = createSelectable((props) => {
});
export default withTranslation("Home")(
withFileActions(withContextOptions(withRouter(SimpleFilesRow)))
withFileActions(withRouter(withContextOptions(SimpleFilesRow)))
);

View File

@ -261,18 +261,11 @@ class SectionFilterContent extends React.Component {
render() {
//console.log("Filter render");
const selectedFilterData = this.getSelectedFilterData();
const {
t,
firstLoad,
sectionWidth,
tReady,
isAnyItems,
filterSearch,
} = this.props;
const { t, sectionWidth, tReady, isFiltered } = this.props;
const filterColumnCount =
window.innerWidth < 500 ? {} : { filterColumnCount: 3 };
return !isAnyItems && !filterSearch ? null : !tReady ? (
return !isFiltered ? null : !tReady ? (
<Loaders.Filter />
) : (
<FilterInput
@ -297,7 +290,6 @@ class SectionFilterContent extends React.Component {
export default inject(({ auth, filesStore, selectedFolderStore }) => {
const {
firstLoad,
fetchFiles,
filter,
setIsLoading,
@ -309,24 +301,22 @@ export default inject(({ auth, filesStore, selectedFolderStore }) => {
const { user } = auth.userStore;
const { customNames, culture } = auth.settingsStore;
const isAnyItems = !!files.length || !!folders.length;
const filterSearch = filter.search;
const { search, filterType } = filter;
const isFiltered = !!files.length || !!folders.length || search || filterType;
return {
customNames,
user,
firstLoad,
selectedFolderId: selectedFolderStore.id,
selectedItem: filter.selectedItem,
filter,
viewAs,
isFiltered,
setIsLoading,
fetchFiles,
setViewAs,
isAnyItems,
filterSearch,
};
})(
withRouter(

View File

@ -402,7 +402,6 @@ class SectionHeaderContent extends React.Component {
disabled:
isFavoritesFolder ||
isRecentFolder ||
isShareFolder ||
!isAccessedSelected ||
!selectionCount ||
isThirdPartySelection,
@ -440,6 +439,10 @@ class SectionHeaderContent extends React.Component {
menu.splice(4, 1);
}
if (isShareFolder) {
menu.splice(4, 1);
}
return menu;
};

View File

@ -30,7 +30,13 @@ import config from "../../../package.json";
class PureHome extends React.Component {
componentDidMount() {
const { fetchFiles, homepage, setIsLoading, setFirstLoad } = this.props;
const {
fetchFiles,
homepage,
setIsLoading,
setFirstLoad,
isVisitor,
} = this.props;
const reg = new RegExp(`${homepage}((/?)$|/filter)`, "gm"); //TODO: Always find?
const match = window.location.pathname.match(reg);
@ -41,6 +47,7 @@ class PureHome extends React.Component {
if (!filterObj) {
filterObj = FilesFilter.getDefault();
if (isVisitor) filterObj.folder = "@common";
const folderId = filterObj.folder;
setIsLoading(true);
fetchFiles(folderId, filterObj).finally(() => {
@ -364,6 +371,7 @@ export default inject(
viewAs,
uploaded,
isRecycleBinFolder,
isVisitor: auth.userStore.user.isVisitor,
primaryProgressDataVisible,
primaryProgressDataPercent,

View File

@ -89,21 +89,21 @@ class ConnectClouds extends React.Component {
onChangeThirdPartyInfo = (e) => {
const { dataset } = (e.originalEvent || e).currentTarget;
const { provider_key } = dataset;
const { provider_id } = dataset;
const capabilitiesItem = this.props.capabilities.find(
(x) => x[0] === provider_key
(x) => x[0] === provider_id
);
const providerItem = this.props.providers.find(
(x) => x.provider_key === provider_key
(x) => x.provider_id === provider_id
);
const { corporate, provider_id, customer_title } = providerItem;
const { corporate, customer_title, provider_key } = providerItem;
const item = {
title: capabilitiesItem ? capabilitiesItem[0] : customer_title,
link: capabilitiesItem ? capabilitiesItem[1] : " ",
corporate: corporate,
provider_id: provider_id,
provider_key: provider_key,
corporate,
provider_id,
provider_key,
};
this.props.setConnectItem(item);
@ -176,7 +176,7 @@ class ConnectClouds extends React.Component {
return [
{
key: `${index}_change`,
"data-provider_key": item.provider_key,
"data-provider_id": item.provider_id,
label: t("ThirdPartyInfo"),
onClick: this.onChangeThirdPartyInfo,
},

View File

@ -51,6 +51,7 @@ const SectionBodyContent = ({
myFolderId,
commonFolderId,
t,
isVisitor,
}) => {
const onChangeStoreForceSave = () => {
setStoreForceSave(!storeForceSave, "storeForceSave");
@ -134,42 +135,51 @@ const SectionBodyContent = ({
onChange={onChangeDeleteConfirm}
isChecked={confirmDelete}
/>
<ToggleButton
isDisabled={true}
className="toggle-btn"
label={t("DisplayRecent")}
onChange={(e) => console.log(e)}
isChecked={false}
/>
<ToggleButton
isDisabled={true}
className="toggle-btn"
label={t("DisplayFavorites")}
onChange={(e) => console.log(e)}
isChecked={false}
/>
<ToggleButton
isDisabled={true}
className="toggle-btn"
label={t("DisplayTemplates")}
onChange={(e) => console.log(e)}
isChecked={false}
/>
<Heading className="heading" level={2} size="small">
{t("StoringFileVersion")}
</Heading>
<ToggleButton
className="toggle-btn"
label={t("UpdateOrCreate")}
onChange={onChangeUpdateIfExist}
isChecked={updateIfExist}
/>
<ToggleButton
className="toggle-btn"
label={t("KeepIntermediateVersion")}
onChange={onChangeForceSave}
isChecked={forceSave}
/>
{!isVisitor && (
<>
<ToggleButton
isDisabled={true}
className="toggle-btn"
label={t("DisplayRecent")}
onChange={(e) => console.log(e)}
isChecked={false}
/>
<ToggleButton
isDisabled={true}
className="toggle-btn"
label={t("DisplayFavorites")}
onChange={(e) => console.log(e)}
isChecked={false}
/>
<ToggleButton
isDisabled={true}
className="toggle-btn"
label={t("DisplayTemplates")}
onChange={(e) => console.log(e)}
isChecked={false}
/>
</>
)}
{!isVisitor && (
<>
<Heading className="heading" level={2} size="small">
{t("StoringFileVersion")}
</Heading>
<ToggleButton
className="toggle-btn"
label={t("UpdateOrCreate")}
onChange={onChangeUpdateIfExist}
isChecked={updateIfExist}
/>
<ToggleButton
className="toggle-btn"
label={t("KeepIntermediateVersion")}
onChange={onChangeForceSave}
isChecked={forceSave}
/>
</>
)}
</StyledSettings>
);
};
@ -240,6 +250,7 @@ export default inject(
treeFolders,
myFolderId,
commonFolderId,
isVisitor: auth.userStore.user.isVisitor,
setUpdateIfExist,
setStoreOriginal,

View File

@ -13,6 +13,7 @@ import StyledVersionRow from "./StyledVersionRow";
import ExternalLinkIcon from "../../../../../public/images/external.link.react.svg";
import commonIconsStyles from "@appserver/components/utils/common-icons-style";
import { inject, observer } from "mobx-react";
import toastr from "studio/toastr";
const StyledExternalLinkIcon = styled(ExternalLinkIcon)`
${commonIconsStyles}

View File

@ -87,7 +87,7 @@ VersionHistory.propTypes = {
};
export default inject(({ auth, filesStore, versionHistoryStore }) => {
const { filter, setFilesFilter, isLoading } = filesStore;
const { filter, isLoading } = filesStore;
const { setIsVerHistoryPanel, versions } = versionHistoryStore;
return {
@ -96,7 +96,6 @@ export default inject(({ auth, filesStore, versionHistoryStore }) => {
filter,
versions,
setFilesFilter,
setIsVerHistoryPanel,
};
})(withRouter(observer(VersionHistory)));

View File

@ -21,6 +21,7 @@ class DialogsStore {
newFilesIds = null;
conflictResolveDialogData = null;
conflictResolveDialogItems = null;
removeMediaItem = null;
constructor() {
makeAutoObservable(this);
@ -104,6 +105,10 @@ class DialogsStore {
setConflictResolveDialogItems = (items) => {
this.conflictResolveDialogItems = items;
};
setRemoveMediaItem = (removeMediaItem) => {
this.removeMediaItem = removeMediaItem;
};
}
export default new DialogsStore();

View File

@ -24,6 +24,7 @@ class FilesActionStore {
selectedFolderStore;
settingsStore;
dialogsStore;
mediaViewerDataStore;
constructor(
authStore,
@ -32,7 +33,8 @@ class FilesActionStore {
filesStore,
selectedFolderStore,
settingsStore,
dialogsStore
dialogsStore,
mediaViewerDataStore
) {
makeAutoObservable(this);
this.authStore = authStore;
@ -42,8 +44,16 @@ class FilesActionStore {
this.selectedFolderStore = selectedFolderStore;
this.settingsStore = settingsStore;
this.dialogsStore = dialogsStore;
this.mediaViewerDataStore = mediaViewerDataStore;
}
isMediaOpen = () => {
const { visible, setMediaViewerData, playlist } = this.mediaViewerDataStore;
if (visible && playlist.length === 1) {
setMediaViewerData({ visible: false, id: null });
}
};
deleteAction = (translations, newSelection = null) => {
const { isRecycleBinFolder, isPrivacyFolder } = this.treeFoldersStore;
@ -71,6 +81,7 @@ class FilesActionStore {
}
if (folderIds.length || fileIds.length) {
this.isMediaOpen();
return removeFiles(folderIds, fileIds, deleteAfter, immediately)
.then((res) => {
const id = res[0] && res[0].id ? res[0].id : null;
@ -268,25 +279,42 @@ class FilesActionStore {
setSelection([item]);
};
deleteItemAction = (itemId, currentFolderId, translations, isFile) => {
const {
setSecondaryProgressBarData,
} = this.uploadDataStore.secondaryProgressDataStore;
if (this.settingsStore.confirmDelete) {
this.dialogsStore.setDeleteDialogVisible(true);
} else {
setSecondaryProgressBarData({
icon: "trash",
visible: true,
percent: 0,
label: translations.deleteOperation,
alert: false,
});
isFile
? this.deleteFileAction(itemId, currentFolderId, translations)
: this.deleteFolderAction(itemId, currentFolderId, translations);
}
};
deleteFileAction = (fileId, currentFolderId, translations) => {
const {
setSecondaryProgressBarData,
clearSecondaryProgressData,
} = this.uploadDataStore.secondaryProgressDataStore;
setSecondaryProgressBarData({
icon: "trash",
visible: true,
percent: 0,
label: translations.deleteOperation,
alert: false,
});
this.isMediaOpen();
return deleteFile(fileId)
.then((res) => {
const id = res[0] && res[0].id ? res[0].id : null;
this.loopDeleteProgress(id, currentFolderId, false, translations);
})
.then(() => toastr.success(translations.successRemoveFile))
.catch((err) => {
toastr.error(err);
setSecondaryProgressBarData({
visible: true,
alert: true,
@ -301,19 +329,14 @@ class FilesActionStore {
clearSecondaryProgressData,
} = this.uploadDataStore.secondaryProgressDataStore;
setSecondaryProgressBarData({
icon: "trash",
visible: true,
percent: 0,
label: translations.deleteOperation,
alert: false,
});
return deleteFolder(folderId, currentFolderId)
.then((res) => {
const id = res[0] && res[0].id ? res[0].id : null;
this.loopDeleteProgress(id, currentFolderId, true, translations);
})
.then(() => toastr.success(translations.successRemoveFolder))
.catch((err) => {
toastr.error(err);
setSecondaryProgressBarData({
visible: true,
alert: true,

View File

@ -6,6 +6,7 @@ import {
FileType,
FileAction,
AppServerConfig,
FilesFormats,
} from "@appserver/common/constants";
import history from "@appserver/common/history";
import { createTreeFolders } from "../helpers/files-helpers";
@ -122,6 +123,7 @@ class FilesStore {
if (this.isInit) return;
const { isAuthenticated } = this.authStore;
const {
getPortalCultures,
isDesktopClient,
@ -369,10 +371,10 @@ class FilesStore {
const isVisitor =
(this.userStore.user && this.userStore.user.isVisitor) || false;
const isFile = !!item.fileExst || item.contentLength;
const isFavorite = item.fileStatus === 32;
const isFavorite = item.fileStatus === 32 || item.fileStatus === 34;
const isFullAccess = item.access < 2;
const withoutShare = false; //TODO: need this prop
const isThirdPartyItem = item.providerKey;
const isThirdPartyItem = !!item.providerKey;
const hasNew = item.new > 0;
const canConvert = false; //TODO: fix of added convert check;
const isEncrypted = item.encrypted;
@ -383,13 +385,18 @@ class FilesStore {
isRecycleBinFolder,
isPrivacyFolder,
isRecentFolder,
isShareFolder,
isCommonFolder,
isCommon,
isShare,
isFavoritesFolder,
isThirdPartyFolder,
isMyFolder,
} = this.treeFoldersStore;
const { isRootFolder } = this.selectedFolderStore;
const isThirdPartyFolder = item.providerKey && isRootFolder;
const isShareFolder = isShare(item.rootFolderType);
const isCommonFolder = isCommon(item.rootFolderType);
const { isDesktopClient } = this.settingsStore;
if (isFile) {
@ -497,12 +504,7 @@ class FilesStore {
]);
}
if (
isCommonFolder ||
isFavoritesFolder ||
isPrivacyFolder ||
isRecentFolder
) {
if (isFavoritesFolder || isPrivacyFolder || isRecentFolder) {
fileOptions = this.removeOptions(fileOptions, [
"copy",
"move-to",
@ -546,6 +548,7 @@ class FilesStore {
"rename",
"block-unblock-version",
"copy",
"sharing-settings",
]);
}
@ -606,7 +609,7 @@ class FilesStore {
}
if (isShareFolder) {
fileOptions = this.removeOptions(fileOptions, ["move-to"]);
fileOptions = this.removeOptions(fileOptions, ["move-to", "delete"]);
}
return fileOptions;
@ -636,7 +639,10 @@ class FilesStore {
}
if (isShareFolder) {
folderOptions = this.removeOptions(folderOptions, ["move-to"]);
folderOptions = this.removeOptions(folderOptions, [
"move-to",
"delete",
]);
}
if (isRecycleBinFolder) {
@ -694,6 +700,14 @@ class FilesStore {
folderOptions = this.removeOptions(folderOptions, ["unsubscribe"]);
}
if (isThirdPartyFolder) {
folderOptions = this.removeOptions(folderOptions, ["move-to"]);
} else {
folderOptions = this.removeOptions(folderOptions, [
"change-thirdparty-info",
]);
}
if (isThirdPartyItem) {
folderOptions = this.removeOptions(folderOptions, ["owner-change"]);
@ -708,10 +722,7 @@ class FilesStore {
]);
}
folderOptions = this.removeOptions(folderOptions, [
"remove",
"move-to",
]);
folderOptions = this.removeOptions(folderOptions, ["remove"]);
if (!item) {
//For damaged items
@ -1025,10 +1036,6 @@ class FilesStore {
} = this.formatsStore.iconFormatsStore;
const { canWebEdit } = this.formatsStore.docserviceStore;
const formatKeys = Object.freeze({
OriginalFormat: 0,
});
let sortedFiles = {
documents: [],
spreadsheets: [],
@ -1038,7 +1045,7 @@ class FilesStore {
for (let item of this.selection) {
item.checked = true;
item.format = formatKeys.OriginalFormat;
item.format = FilesFormats.OriginalFormat;
if (item.fileExst) {
if (isSpreadsheet(item.fileExst)) {
@ -1080,9 +1087,8 @@ class FilesStore {
get isAccessedSelected() {
return (
(this.selection.length &&
this.selection.every((x) => x.access === 1 || x.access === 0)) ||
(this.authStore.isAdmin && this.selection.length)
this.selection.length &&
this.selection.every((x) => x.access === 1 || x.access === 0)
);
}

View File

@ -27,16 +27,29 @@ class SelectedFolderStore {
return this.pathParts && this.pathParts.length <= 1;
}
toDefault = () => {
this.folders = null;
this.parentId = null;
this.filesCount = null;
this.foldersCount = null;
this.isShareable = null;
this.new = null;
this.id = null;
this.title = null;
this.access = null;
this.shared = null;
this.created = null;
this.createdBy = null;
this.updated = null;
this.updatedBy = null;
this.rootFolderType = null;
this.pathParts = null;
this.providerItem = null;
};
setSelectedFolder = (selectedFolder) => {
if (!selectedFolder) {
const newStore = new SelectedFolderStore();
const selectedFolderItems = Object.keys(newStore);
for (let key of selectedFolderItems) {
if (key in this) {
this[key] = newStore[key];
}
}
this.toDefault();
} else {
const selectedFolderItems = Object.keys(selectedFolder);

View File

@ -48,6 +48,9 @@ class TreeFoldersStore {
if (rootItem) rootItem.newItems -= count;
};
isCommon = (commonType) => commonType === FolderType.COMMON;
isShare = (shareType) => shareType === FolderType.SHARE;
get myFolder() {
return this.treeFolders.find((x) => x.rootFolderName === "@my");
}

View File

@ -34,6 +34,7 @@ const filesStore = new FilesStore(
treeFoldersStore,
formatsStore
);
const mediaViewerDataStore = new MediaViewerDataStore(filesStore);
const settingsStore = new SettingsStore(thirdPartyStore);
const secondaryProgressDataStore = new SecondaryProgressDataStore();
const primaryProgressDataStore = new PrimaryProgressDataStore();
@ -52,10 +53,10 @@ const filesActionsStore = new FilesActionsStore(
filesStore,
selectedFolderStore,
settingsStore,
dialogsStore
dialogsStore,
mediaViewerDataStore
);
const mediaViewerDataStore = new MediaViewerDataStore(filesStore);
const versionHistoryStore = new VersionHistoryStore(filesStore);
const stores = {
filesStore,

View File

@ -271,7 +271,7 @@ namespace ASC.Files.Core.Data
}
}
return (checkShare ? FromQueryWithShared(q) : FromQuery(q)).Select(ToFolder).ToList();
return (checkShare ? FromQueryWithShared(q) : FromQuery(q)).Select(ToFolder).Distinct().ToList();
}
public List<Folder<int>> GetParentFolders(int folderId)

View File

@ -382,7 +382,7 @@ namespace ASC.Web.Files.Services.WCFService
}
}
EntryManager.SetFileStatus(entries.OfType<File<TId>>().Where(r => r.ID != null).ToList());
EntryManager.SetFileStatus(entries);
return new ItemList<FileEntry>(entries);
}
@ -1225,7 +1225,7 @@ namespace ASC.Web.Files.Services.WCFService
}
catch (Exception e)
{
throw GenerateException(e);
throw GenerateException(e.InnerException ?? e);
}
}
else

View File

@ -37,9 +37,8 @@ using ASC.Files.Core;
using ASC.Files.Core.EF;
using ASC.Web.Core.Files;
using ASC.Web.Files.Classes;
using ASC.Web.Studio.Core;
using Microsoft.Extensions.DependencyInjection;
using ASC.Web.Studio.Core;
using Microsoft.Extensions.Options;
using Microsoft.OneDrive.Sdk;
@ -171,7 +170,7 @@ namespace ASC.Files.Thirdparty.OneDrive
if (onedriveFile.File == null) return null;
var file = ServiceProvider.GetService<File<string>>();
var file = GetFile();
file.ID = MakeId(onedriveFile.Id);
file.ContentLength = onedriveFile.Size.HasValue ? (long)onedriveFile.Size : 0;

Some files were not shown because too many files have changed in this diff Show More