Merge branch 'develop' into feature/thumbnails

# Conflicts:
#	products/ASC.Files/Client/src/pages/Home/Section/Filter/index.js
#	yarn.lock
This commit is contained in:
Artem Tarasov 2021-05-11 10:30:19 +03:00
commit 58a41faa4a
166 changed files with 3377 additions and 2416 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.7",
"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

@ -12,7 +12,7 @@ export function openEdit(fileId, version, doc) {
}
if (doc) {
params.push(`version=${version}`);
params.push(`doc=${doc}`);
}
const paramsString = params.length > 0 ? `?${params.join("&")}` : "";
@ -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);
}

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,

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

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

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.2",
"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

@ -8,7 +8,7 @@ import UserStore from "./UserStore";
import { logout as logoutDesktop, desktopConstants } from "../desktop";
import { combineUrl, isAdmin } from "../utils";
import isEmpty from "lodash/isEmpty";
import { AppServerConfig } from "../constants";
import { AppServerConfig, LANGUAGE } from "../constants";
const { proxyURL } = AppServerConfig;
class AuthStore {
@ -43,7 +43,14 @@ class AuthStore {
return Promise.all(requests);
};
setLanguage() {
if (this.userStore.user.cultureName) {
localStorage.getItem(LANGUAGE) !== this.userStore.user.cultureName &&
localStorage.setItem(LANGUAGE, this.userStore.user.cultureName);
} else {
localStorage.setItem(LANGUAGE, this.settingsStore.culture || "en-US");
}
}
get isLoaded() {
let success = false;
if (this.isAuthenticated) {
@ -51,6 +58,8 @@ class AuthStore {
this.userStore.isLoaded &&
this.moduleStore.isLoaded &&
this.settingsStore.isLoaded;
success && this.setLanguage();
} else {
success = this.settingsStore.isLoaded;
}

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

@ -1,6 +1,5 @@
import { action, makeObservable, observable } from "mobx";
import api from "../api";
import { LANGUAGE } from "../constants";
class UserStore {
user = null;
@ -21,9 +20,7 @@ class UserStore {
getCurrentUser = async () => {
const user = await api.people.getUser();
user.cultureName &&
localStorage.getItem(LANGUAGE) !== user.cultureName &&
localStorage.setItem(LANGUAGE, user.cultureName);
this.setUser(user);
};

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

@ -15,6 +15,7 @@ const StyledLabel = styled.label`
.checkbox {
margin-right: 12px;
overflow: visible;
}
/* ${(props) =>

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.2",
"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.7",
"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.7",
"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

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

View File

@ -81,6 +81,7 @@ const PureTreeSettings = ({
history,
setIsLoading,
t,
isVisitor,
}) => {
const { setting } = match.params;
@ -168,7 +169,7 @@ const PureTreeSettings = ({
title={t("TreeSettingsAdminSettings")}
/>
) : null}
{enableThirdParty ? (
{enableThirdParty && !isVisitor ? (
<TreeNode
selectable={true}
className="settings-node"
@ -226,6 +227,7 @@ export default inject(
return {
isAdmin: auth.isAdmin,
isVisitor: auth.userStore.user.isVisitor,
isLoading,
selectedTreeNode,
enableThirdParty,

View File

@ -85,6 +85,7 @@ class ArticleBodyContent extends React.Component {
onTreeDrop,
selectedTreeNode,
enableThirdParty,
isVisitor,
} = this.props;
return isEmpty(treeFolders) ? (
@ -99,7 +100,7 @@ class ArticleBodyContent extends React.Component {
onTreeDrop={onTreeDrop}
/>
<TreeSettings />
{enableThirdParty && <ThirdPartyList />}
{enableThirdParty && !isVisitor && <ThirdPartyList />}
</>
);
}
@ -107,6 +108,7 @@ class ArticleBodyContent extends React.Component {
export default inject(
({
auth,
filesStore,
treeFoldersStore,
selectedFolderStore,
@ -115,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;
@ -129,6 +135,7 @@ export default inject(
selectedTreeNode,
filter,
enableThirdParty: settingsStore.enableThirdParty,
isVisitor: auth.userStore.user.isVisitor,
setIsLoading,
fetchFiles,

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 && (
@ -48,7 +52,7 @@ const Badges = ({
hoverColor="#3B72A7"
/>
)}
{locked && (
{locked && accessToEdit && (
<StyledFileActionsLockedIcon
className="badge lock-file icons-group"
size="small"
@ -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,7 +31,15 @@ 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
@ -105,13 +113,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 +163,6 @@ const PureConnectDialogContainer = (props) => {
})
.catch((err) => {
toastr.error(err);
onClose();
setIsLoading(false);
});
}, [
@ -234,6 +241,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

@ -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,
});
}
}
@ -427,6 +414,9 @@ class DownloadDialogComponent extends React.Component {
indeterminateOtherTitle,
} = this.state;
console.log("this.props", this.props);
console.log("this.state", this.state);
const otherLength = other.length;
const showOther = otherLength > 1;
@ -440,140 +430,130 @@ class DownloadDialogComponent extends React.Component {
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

@ -77,14 +77,10 @@ class SharingPanelComponent extends React.Component {
};
updateRowData = (newRowData) => {
const { setFile, setFolder } = this.props;
const { getFileInfo, getFolderInfo } = this.props;
for (let item of newRowData) {
if (!item.fileExst) {
setFolder(item);
} else {
setFile(item);
}
!item.fileExst ? getFolderInfo(item.id) : getFileInfo(item.id);
}
};
@ -172,8 +168,8 @@ class SharingPanelComponent extends React.Component {
ownerId
)
.then((res) => {
if (ownerId) {
this.updateRowData(res[0]);
if (!ownerId) {
this.updateRowData(selection);
}
if (isPrivacy && isDesktop) {
if (share.length === 0) return Promise.resolve();
@ -610,6 +606,8 @@ const SharingPanel = inject(
getShareUsers,
setShareFiles,
setIsLoading,
getFileInfo,
getFolderInfo,
isLoading,
} = filesStore;
const { isPrivacyFolder } = treeFoldersStore;
@ -644,6 +642,8 @@ const SharingPanel = inject(
setFolder,
getShareUsers,
setShareFiles,
getFileInfo,
getFolderInfo,
};
}
)(observer(withTranslation("SharingPanel")(SharingPanelComponent)));

View File

@ -13,11 +13,12 @@ const FilesMediaViewer = (props) => {
playlist,
visible,
currentMediaFileId,
deleteFileAction,
deleteItemAction,
setMediaViewerData,
mediaViewerMediaFormats,
mediaViewerImageFormats,
location,
setRemoveMediaItem,
} = props;
useEffect(() => {
@ -60,7 +61,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, file.folderId, translations, true);
}
}
};
@ -95,7 +99,13 @@ const FilesMediaViewer = (props) => {
};
export default inject(
({ filesStore, mediaViewerDataStore, filesActionsStore, formatsStore }) => {
({
filesStore,
mediaViewerDataStore,
filesActionsStore,
formatsStore,
dialogsStore,
}) => {
const { files } = filesStore;
const {
visible,
@ -103,7 +113,7 @@ export default inject(
setMediaViewerData,
playlist,
} = mediaViewerDataStore;
const { deleteFileAction } = filesActionsStore;
const { deleteItemAction } = filesActionsStore;
const { media, images } = formatsStore.mediaViewersFormatsStore;
return {
@ -111,10 +121,11 @@ export default inject(
playlist,
visible: playlist.length > 0 && visible,
currentMediaFileId,
deleteFileAction,
deleteItemAction,
setMediaViewerData,
mediaViewerImageFormats: images,
mediaViewerMediaFormats: media,
setRemoveMediaItem: dialogsStore.setRemoveMediaItem,
};
}
)(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

@ -262,19 +262,11 @@ class SectionFilterContent extends React.Component {
render() {
//console.log("Filter render");
const selectedFilterData = this.getSelectedFilterData();
const {
t,
firstLoad,
sectionWidth,
tReady,
isAnyItems,
filterSearch,
viewAs,
} = this.props;
const { t, sectionWidth, tReady, isFiltered, viewAs } = this.props;
const filterColumnCount =
window.innerWidth < 500 ? {} : { filterColumnCount: 3 };
return !isAnyItems && !filterSearch ? null : !tReady ? (
return !isFiltered ? null : !tReady ? (
<Loaders.Filter />
) : (
<FilterInput
@ -299,7 +291,6 @@ class SectionFilterContent extends React.Component {
export default inject(({ auth, filesStore, selectedFolderStore }) => {
const {
firstLoad,
fetchFiles,
filter,
setIsLoading,
@ -311,24 +302,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

@ -323,6 +323,7 @@ class SectionHeaderContent extends React.Component {
isOnlyFoldersSelected,
isFavoritesFolder,
isRecentFolder,
isShareFolder,
} = this.props;
let menu = [
@ -438,6 +439,10 @@ class SectionHeaderContent extends React.Component {
menu.splice(4, 1);
}
if (isShareFolder) {
menu.splice(4, 1);
}
return menu;
};
@ -591,6 +596,7 @@ export default inject(
isPrivacyFolder,
isFavoritesFolder,
isRecentFolder,
isShareFolder,
} = treeFoldersStore;
const { setAction } = fileActionStore;
const {
@ -614,6 +620,7 @@ export default inject(
isPrivacy: isPrivacyFolder,
isFavoritesFolder,
isRecentFolder,
isShareFolder,
filter,
canCreate,
selectionCount: selection.length,

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(() => {
@ -366,6 +373,7 @@ export default inject(
viewAs,
uploaded,
isRecycleBinFolder,
isVisitor: auth.userStore.user.isVisitor,
primaryProgressDataVisible,
primaryProgressDataPercent,

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

@ -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

@ -71,17 +71,18 @@ class FilesActionStore {
}
if (folderIds.length || fileIds.length) {
setSecondaryProgressBarData({
icon: "trash",
visible: true,
label: translations.deleteOperation,
percent: 0,
alert: false,
});
return removeFiles(folderIds, fileIds, deleteAfter, immediately)
.then((res) => {
const id = res[0] && res[0].id ? res[0].id : null;
const currentProcess = res.find((x) => x.id === id);
setSecondaryProgressBarData({
icon: "trash",
visible: true,
label: translations.deleteOperation,
percent: currentProcess.progress,
alert: false,
});
this.loopDeleteOperation(id, translations);
})
.catch((err) => {
@ -267,25 +268,41 @@ 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
? deleteFileAction(itemId, currentFolderId, translations)
: 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,
});
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,
@ -300,19 +317,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";
@ -123,6 +124,7 @@ class FilesStore {
if (this.isInit) return;
const { isAuthenticated } = this.authStore;
const {
getPortalCultures,
isDesktopClient,
@ -370,10 +372,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;
@ -384,13 +386,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) {
@ -498,12 +505,7 @@ class FilesStore {
]);
}
if (
isCommonFolder ||
isFavoritesFolder ||
isPrivacyFolder ||
isRecentFolder
) {
if (isFavoritesFolder || isPrivacyFolder || isRecentFolder) {
fileOptions = this.removeOptions(fileOptions, [
"copy",
"move-to",
@ -547,6 +549,7 @@ class FilesStore {
"rename",
"block-unblock-version",
"copy",
"sharing-settings",
]);
}
@ -575,7 +578,7 @@ class FilesStore {
]);
}
if (isCommonFolder)
if (isCommonFolder) {
if (!this.userAccess) {
fileOptions = this.removeOptions(fileOptions, [
"owner-change",
@ -587,6 +590,7 @@ class FilesStore {
fileOptions = this.removeOptions(fileOptions, ["separator2"]);
}
}
}
if (withoutShare) {
fileOptions = this.removeOptions(fileOptions, [
@ -605,6 +609,10 @@ class FilesStore {
fileOptions = this.removeOptions(fileOptions, ["separator2"]);
}
if (isShareFolder) {
fileOptions = this.removeOptions(fileOptions, ["move-to", "delete"]);
}
return fileOptions;
} else {
let folderOptions = [
@ -631,6 +639,13 @@ class FilesStore {
folderOptions = this.removeOptions(folderOptions, ["copy"]);
}
if (isShareFolder) {
folderOptions = this.removeOptions(folderOptions, [
"move-to",
"delete",
]);
}
if (isRecycleBinFolder) {
folderOptions = this.removeOptions(folderOptions, [
"open",
@ -686,6 +701,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"]);
@ -700,10 +723,7 @@ class FilesStore {
]);
}
folderOptions = this.removeOptions(folderOptions, [
"remove",
"move-to",
]);
folderOptions = this.removeOptions(folderOptions, ["remove"]);
if (!item) {
//For damaged items
@ -1025,10 +1045,6 @@ class FilesStore {
} = this.formatsStore.iconFormatsStore;
const { canWebEdit } = this.formatsStore.docserviceStore;
const formatKeys = Object.freeze({
OriginalFormat: 0,
});
let sortedFiles = {
documents: [],
spreadsheets: [],
@ -1038,7 +1054,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 +1096,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)
);
}
@ -1231,6 +1246,11 @@ class FilesStore {
this.setFile(fileInfo);
};
getFolderInfo = async (id) => {
const folderInfo = await api.files.getFolderInfo(id);
this.setFolder(folderInfo);
};
openDocEditor = (id, providerKey = null, tab = null, url = null) => {
if (providerKey) {
tab

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

@ -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;

View File

@ -367,7 +367,9 @@ namespace ASC.Files.Thirdparty
{
Id = id,
Title = customerTitle,
Token = EncryptPassword(authData.Token),
Token = EncryptPassword(authData.Token),
Url = authData.Url,
UserName = authData.Login,
Password = EncryptPassword(authData.Password),
UserId = owner,
FolderType = type,
@ -390,10 +392,11 @@ namespace ASC.Files.Thirdparty
var createOn = TenantUtil.DateTimeFromUtc(input.CreateOn);
var authData = new AuthData(input.Url, input.UserName, DecryptPassword(input.Password), token);
if (string.IsNullOrEmpty(token)) throw new ArgumentException("Token can't be null");
if (key == ProviderTypes.Box)
{
{
if (string.IsNullOrEmpty(token))
throw new ArgumentException("Token can't be null");
var box = ServiceProvider.GetService<BoxProviderInfo>();
box.ID = id;
box.CustomerTitle = providerTitle;
@ -406,7 +409,10 @@ namespace ASC.Files.Thirdparty
}
if (key == ProviderTypes.DropboxV2)
{
{
if (string.IsNullOrEmpty(token))
throw new ArgumentException("Token can't be null");
var drop = ServiceProvider.GetService<DropboxProviderInfo>();
drop.ID = id;
drop.CustomerTitle = providerTitle;
@ -436,7 +442,10 @@ namespace ASC.Files.Thirdparty
}
if (key == ProviderTypes.GoogleDrive)
{
{
if (string.IsNullOrEmpty(token))
throw new ArgumentException("Token can't be null");
var gd = ServiceProvider.GetService<GoogleDriveProviderInfo>();
gd.ID = id;
gd.CustomerTitle = providerTitle;
@ -450,7 +459,10 @@ namespace ASC.Files.Thirdparty
}
if (key == ProviderTypes.OneDrive)
{
{
if (string.IsNullOrEmpty(token))
throw new ArgumentException("Token can't be null");
var od = ServiceProvider.GetService<OneDriveProviderInfo>();
od.ID = id;
od.CustomerTitle = providerTitle;

View File

@ -485,8 +485,7 @@ namespace ASC.Web.Files.Services.DocumentService
}
var folderDao = DaoFactory.GetFolderDao<int>();
var fileDao = DaoFactory.GetFileDao<int>();
var files = entryManager.GetRecent(folderDao, fileDao, filter, false, Guid.Empty, string.Empty, false);
var files = entryManager.GetRecent(filter, false, Guid.Empty, string.Empty, false).Cast<File<int>>();
var listRecent = from file in files
where !Equals(_configuration.Document.Info.File.ID, file.ID)

View File

@ -358,9 +358,9 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
protected void ProgressStep(TId folderId = default, TId fileId = default)
{
if (folderId.Equals(default(TId)) && fileId.Equals(default(TId))
|| !folderId.Equals(default(TId)) && Folders.Contains(folderId)
|| !fileId.Equals(default(TId)) && Files.Contains(fileId))
if (Equals(folderId, default(TId)) && Equals(fileId, default(TId))
|| !Equals(folderId, default(TId)) && Folders.Contains(folderId)
|| !Equals(fileId, default(TId)) && Files.Contains(fileId))
{
processed++;
PublishTaskInfo();

View File

@ -384,9 +384,7 @@ namespace ASC.Web.Files.Utils
}
else if (parent.FolderType == FolderType.Recent)
{
var folderDao = DaoFactory.GetFolderDao<T>();
var fileDao = DaoFactory.GetFileDao<T>();
var files = GetRecent(folderDao, fileDao, filter, subjectGroup, subjectId, searchText, searchInContent);
var files = GetRecent(filter, subjectGroup, subjectId, searchText, searchInContent);
entries = entries.Concat(files);
CalculateTotal();
@ -396,7 +394,7 @@ namespace ASC.Web.Files.Utils
var fileDao = DaoFactory.GetFileDao<T>();
var folderDao = DaoFactory.GetFolderDao<T>();
GetFavorites(folderDao, fileDao, filter, subjectGroup, subjectId, searchText, searchInContent, out var folders, out var files);
var (files, folders) = GetFavorites(filter, subjectGroup, subjectId, searchText, searchInContent);
entries = entries.Concat(folders);
entries = entries.Concat(files);
@ -473,7 +471,7 @@ namespace ASC.Web.Files.Utils
if (0 < count) entries = entries.Take(count);
}
SetFileStatus(entries.OfType<File<T>>().Where(r => r != null && r.ID != null && r.FileEntryType == FileEntryType.File).ToList());
SetFileStatus(entries.Where(r => r != null && r.FileEntryType == FileEntryType.File).ToList());
return entries;
void CalculateTotal()
@ -545,53 +543,101 @@ namespace ASC.Web.Files.Utils
return folderList;
}
public IEnumerable<File<T>> GetRecent<T>(IFolderDao<T> folderDao, IFileDao<T> fileDao, FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent)
public IEnumerable<FileEntry> GetRecent(FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent)
{
var tagDao = DaoFactory.GetTagDao<T>();
var tagDao = DaoFactory.GetTagDao<int>();
var tags = tagDao.GetTags(AuthContext.CurrentAccount.ID, TagType.Recent).ToList();
var fileIds = tags.Where(tag => tag.EntryType == FileEntryType.File).Select(tag => (T)Convert.ChangeType(tag.EntryId, typeof(T))).ToArray();
var files = fileDao.GetFilesFiltered(fileIds, filter, subjectGroup, subjectId, searchText, searchInContent);
files = files.Where(file => file.RootFolderType != FolderType.TRASH).ToList();
var fileIds = tags.Where(tag => tag.EntryType == FileEntryType.File).ToList();
files = FileSecurity.FilterRead(files).ToList();
List<FileEntry> files = GetRecentByIds(fileIds.Where(r => r.EntryId is int).Select(r=> (int)r.EntryId), filter, subjectGroup, subjectId, searchText, searchInContent).ToList();
files.AddRange(GetRecentByIds(fileIds.Where(r => r.EntryId is string).Select(r => (string)r.EntryId), filter, subjectGroup, subjectId, searchText, searchInContent));
CheckFolderId(folderDao, files);
var listFileIds = fileIds.Select(tag => tag.EntryId).ToList();
var listFileIds = fileIds.ToList();
files = files.OrderBy(file => listFileIds.IndexOf(file.ID)).ToList();
files = files.OrderBy(file =>
{
var fileId = "";
if (file is File<int> fileInt)
{
fileId = fileInt.ID.ToString();
}
else if (file is File<string> fileString)
{
fileId = fileString.ID;
}
return listFileIds.IndexOf(fileId);
}).ToList();
return files;
}
public void GetFavorites<T>(IFolderDao<T> folderDao, IFileDao<T> fileDao, FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent, out IEnumerable<Folder<T>> folders, out IEnumerable<File<T>> files)
{
folders = new List<Folder<T>>();
files = new List<File<T>>();
var fileSecurity = FileSecurity;
var tagDao = DaoFactory.GetTagDao<T>();
var tags = tagDao.GetTags(AuthContext.CurrentAccount.ID, TagType.Favorite);
if (filter == FilterType.None || filter == FilterType.FoldersOnly)
IEnumerable<FileEntry> GetRecentByIds<T>(IEnumerable<T> fileIds, FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent)
{
var folderIds = tags.Where(tag => tag.EntryType == FileEntryType.Folder).Select(tag => (T)Convert.ChangeType(tag.EntryId, typeof(T))).ToList();
folders = folderDao.GetFolders(folderIds, filter, subjectGroup, subjectId, searchText, false, false);
folders = folders.Where(folder => folder.RootFolderType != FolderType.TRASH).ToList();
folders = fileSecurity.FilterRead(folders).ToList();
CheckFolderId(folderDao, folders);
}
if (filter != FilterType.FoldersOnly)
{
var fileIds = tags.Where(tag => tag.EntryType == FileEntryType.File).Select(tag => (T)Convert.ChangeType(tag.EntryId, typeof(T))).ToArray();
files = fileDao.GetFilesFiltered(fileIds, filter, subjectGroup, subjectId, searchText, searchInContent);
var folderDao = DaoFactory.GetFolderDao<T>();
var fileDao = DaoFactory.GetFileDao<T>();
var files = fileDao.GetFilesFiltered(fileIds, filter, subjectGroup, subjectId, searchText, searchInContent);
files = files.Where(file => file.RootFolderType != FolderType.TRASH).ToList();
files = fileSecurity.FilterRead(files).ToList();
files = FileSecurity.FilterRead(files).ToList();
CheckFolderId(folderDao, folders);
CheckFolderId(folderDao, files);
return files;
}
}
public (IEnumerable<FileEntry>, IEnumerable<FileEntry>) GetFavorites(FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent)
{
var fileSecurity = FileSecurity;
var tagDao = DaoFactory.GetTagDao<int>();
var tags = tagDao.GetTags(AuthContext.CurrentAccount.ID, TagType.Favorite);
var fileIds = tags.Where(tag => tag.EntryType == FileEntryType.File).ToList();
var folderIds = tags.Where(tag => tag.EntryType == FileEntryType.Folder).ToList();
var (filesInt, foldersInt) = GetFavoritesById(fileIds.Where(r => r.EntryId is int).Select(r => (int)r.EntryId), folderIds.Where(r => r.EntryId is int).Select(r => (int)r.EntryId), filter, subjectGroup, subjectId, searchText, searchInContent);
var (filesString, foldersString) = GetFavoritesById(fileIds.Where(r => r.EntryId is string).Select(r => (string)r.EntryId), folderIds.Where(r => r.EntryId is string).Select(r => (string)r.EntryId), filter, subjectGroup, subjectId, searchText, searchInContent);
var files = new List<FileEntry>();
files.AddRange(filesInt);
files.AddRange(filesString);
var folders = new List<FileEntry>();
folders.AddRange(foldersInt);
folders.AddRange(foldersString);
return (files, folders);
(IEnumerable<FileEntry>, IEnumerable<FileEntry>) GetFavoritesById<T>(IEnumerable<T> fileIds, IEnumerable<T> folderIds, FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent)
{
var folderDao = DaoFactory.GetFolderDao<T>();
var fileDao = DaoFactory.GetFileDao<T>();
var folders = new List<Folder<T>>();
var files = new List<File<T>>();
var fileSecurity = FileSecurity;
if (filter == FilterType.None || filter == FilterType.FoldersOnly)
{
folders = folderDao.GetFolders(folderIds, filter, subjectGroup, subjectId, searchText, false, false);
folders = folders.Where(folder => folder.RootFolderType != FolderType.TRASH).ToList();
folders = fileSecurity.FilterRead(folders).ToList();
CheckFolderId(folderDao, folders);
}
if (filter != FilterType.FoldersOnly)
{
files = fileDao.GetFilesFiltered(fileIds, filter, subjectGroup, subjectId, searchText, searchInContent);
files = files.Where(file => file.RootFolderType != FolderType.TRASH).ToList();
files = fileSecurity.FilterRead(files).ToList();
CheckFolderId(folderDao, folders);
}
return (files, folders);
}
}
@ -778,6 +824,12 @@ namespace ASC.Web.Files.Utils
SetFileStatus(new List<File<T>>(1) { file });
}
public void SetFileStatus(IEnumerable<FileEntry> files)
{
SetFileStatus(files.OfType<File<int>>().Where(r=> r.ID != 0));
SetFileStatus(files.OfType<File<string>>().Where(r=> !string.IsNullOrEmpty(r.ID)));
}
public void SetFileStatus<T>(IEnumerable<File<T>> files)
{
var tagDao = DaoFactory.GetTagDao<T>();

View File

@ -29,6 +29,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" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\ASC.Api.Core\ASC.Api.Core.csproj" />

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