diff --git a/samples/dotnet/UISampleApp/.dockerignore b/samples/dotnet/UISampleApp/.dockerignore new file mode 100644 index 0000000..3729ff0 --- /dev/null +++ b/samples/dotnet/UISampleApp/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/.gitignore b/samples/dotnet/UISampleApp/.gitignore new file mode 100644 index 0000000..1e9abf7 --- /dev/null +++ b/samples/dotnet/UISampleApp/.gitignore @@ -0,0 +1,329 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/Helpers/MockTenant.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/Helpers/MockTenant.cs new file mode 100644 index 0000000..71049d5 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/Helpers/MockTenant.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Security.Claims; + +namespace Rws.LC.UISampleApp.Test.Helpers +{ + public class MockTenant + { + private readonly string _fakeAccountId; + + public MockTenant() + { + _fakeAccountId = Guid.NewGuid().ToString(); + } + + public ClaimsPrincipal GetDefaultPrincipal() + { + List _claims = new List(); + + var defaultClaims = new[] + { + new Claim("aid", _fakeAccountId) + }; + + _claims.AddRange(defaultClaims); + + return CreatePrincipalWithClaims(_claims); + } + + private static ClaimsPrincipal CreatePrincipalWithClaims(IEnumerable claims) + { + var identity = new ClaimsIdentity(); + identity.AddClaims(claims); + + var principal = new ClaimsPrincipal(); + principal.AddIdentity(identity); + + return principal; + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/Rws.LC.UISampleApp.Test.csproj b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/Rws.LC.UISampleApp.Test.csproj new file mode 100644 index 0000000..5f9a922 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/Rws.LC.UISampleApp.Test.csproj @@ -0,0 +1,47 @@ + + + + net8.0 + false + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/StandardController/StandardControllerTests.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/StandardController/StandardControllerTests.cs new file mode 100644 index 0000000..ddeb46a --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/StandardController/StandardControllerTests.cs @@ -0,0 +1,272 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using NSubstitute; +using Rws.LC.UISampleApp.Helpers; +using Rws.LC.UISampleApp.Interfaces; +using Rws.LC.UISampleApp.Models; +using Rws.LC.UISampleApp.Test.Helpers; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Threading.Tasks; +using Xunit; + +namespace Rws.LC.UISampleApp.Test.StandardController +{ + public class StandardControllerTests + { + readonly IConfiguration _configuration; + readonly IDescriptorService _descriptorService; + readonly IAccountService _accountService; + readonly IHealthReporter _healthReporter; + + readonly MockTenant _mockTenant; + + public StandardControllerTests() + { + IConfiguration configuration = new ConfigurationBuilder() + .AddJsonFile("appsettings.test.json") + //.AddEnvironmentVariables() + .Build(); + + var startup = new Startup(configuration); + var services = new ServiceCollection(); + + startup.ConfigureServices(services); + services.AddSingleton(configuration); + + var serviceProvider = services.BuildServiceProvider(); + _configuration = serviceProvider.GetService(); + _descriptorService = serviceProvider.GetService(); + _accountService = serviceProvider.GetService(); + _healthReporter = serviceProvider.GetService(); + + _mockTenant = new MockTenant(); + } + + + [Fact] + public void GetDescriptor() + { + var standardController = BuildStandardController(new DefaultHttpContext()); + + var result = standardController.Descriptor(); + var descriptor = (result as OkObjectResult).Value as JsonNode; + + Assert.Equal(_configuration["baseUrl"], descriptor["baseUrl"].ToString()); + Assert.Equal("1.0.0", descriptor["version"].ToString()); + Assert.Equal("1.4", descriptor["descriptorVersion"].ToString()); + Assert.Single(descriptor["extensions"].AsArray()); + Assert.Equal("/v1/health", descriptor["standardEndpoints"]["health"].ToString()); + Assert.Equal("/v1/documentation", descriptor["standardEndpoints"]["documentation"].ToString()); + Assert.Equal("/v1/app-lifecycle", descriptor["standardEndpoints"]["appLifecycle"].ToString()); + Assert.Equal("/v1/configuration", descriptor["standardEndpoints"]["configuration"].ToString()); + Assert.Equal("/v1/configuration/validation", descriptor["standardEndpoints"]["configurationValidation"].ToString()); + Assert.Equal("/v1/privacyPolicy", descriptor["standardEndpoints"]["privacyPolicy"].ToString()); + Assert.Equal("/v1/termsAndConditions", descriptor["standardEndpoints"]["termsAndConditions"].ToString()); + Assert.Single(descriptor["configurations"].AsArray()); + } + + [Fact] + public void HealthCheck() + { + var standardController = BuildStandardController(new DefaultHttpContext()); + + var response = standardController.Health(); + + Assert.True(response is OkResult); + } + + [Fact] + public void GetDocumentation() + { + var standardController = BuildStandardController(new DefaultHttpContext()); + + var response = standardController.Documentation(); + + var result = response as RedirectResult; + Assert.Equal(_configuration["documentationUrl"], result.Url); + } + + [Fact] + public async Task AppLifecycleRegister() + { + using (var stream = new MemoryStream()) + { + var standardController = BuildStandardController(BuildRequestContext("RegisteredEventRequest.json", stream)); + + var response = await standardController.AppLifecycle().ConfigureAwait(false); + + Assert.True(response is OkResult); + } + } + + [Fact] + public async Task AppLifecycleUnregister() + { + using (var stream = new MemoryStream()) + { + var standardController = BuildStandardController(BuildRequestContext("UnregisteredEventRequest.json", stream)); + + var response = await standardController.AppLifecycle().ConfigureAwait(false); + + Assert.True(response is OkResult); + } + } + + [Fact] + public async Task AppLifecycleInstall() + { + using (var stream = new MemoryStream()) + { + var standardController = BuildStandardController(BuildRequestContext("InstalledEventRequest.json", stream)); + + var response = await standardController.AppLifecycle().ConfigureAwait(false); + + Assert.True(response is OkResult); + } + } + + [Fact] + public async Task AppLifecycleUninstall() + { + using (var stream = new MemoryStream()) + { + var standardController = BuildStandardController(BuildRequestContext("UninstalledEventRequest.json", stream)); + + var response = await standardController.AppLifecycle().ConfigureAwait(false); + + Assert.True(response is OkResult); + } + } + + [Fact] + public async Task SetConfigurationSettings() + { + // first install the app + using (var stream = new MemoryStream()) + { + var standardController = BuildStandardController(BuildRequestContext("InstalledEventRequest.json", stream)); + await standardController.AppLifecycle().ConfigureAwait(false); + } + // then set the configuration settings on the account install entity + using (var stream = new MemoryStream()) + { + var httpContext = new DefaultHttpContext(); + httpContext.User = _mockTenant.GetDefaultPrincipal(); + var standardController = BuildStandardController(httpContext); + + var configSettingsRequest = JsonSerializer.Deserialize>(File.ReadAllText("TestFiles\\ConfigurationRequest.json"), JsonSettings.Default()); + + var response = await standardController.SetConfigurationSettings(configSettingsRequest).ConfigureAwait(false); + + var configurationSettings = (response as OkObjectResult).Value as ConfigurationSettingsResult; + Assert.Equal(1, configurationSettings.ItemCount); + Assert.Single(configurationSettings.Items); + Assert.Equal("SAMPLE_CONFIG_ID", configurationSettings.Items.First().Id); + Assert.Equal("sampleConfigValue", configurationSettings.Items.First().Value.ToString()); + } + } + + [Fact] + public async Task GetConfigurationSettings() + { + // first install the app + using (var stream = new MemoryStream()) + { + var standardController = BuildStandardController(BuildRequestContext("InstalledEventRequest.json", stream)); + await standardController.AppLifecycle().ConfigureAwait(false); + } + // then set the configuration settings on the account install entity + using (var stream = new MemoryStream()) + { + var httpContext = new DefaultHttpContext(); + httpContext.User = _mockTenant.GetDefaultPrincipal(); + var standardController = BuildStandardController(httpContext); + + var configSettingsRequest = JsonSerializer.Deserialize>(File.ReadAllText("TestFiles\\ConfigurationRequest.json"), JsonSettings.Default()); + + await standardController.SetConfigurationSettings(configSettingsRequest).ConfigureAwait(false); + } + // prepare context user for the GET config settings request + var httpContext2 = new DefaultHttpContext(); + httpContext2.User = _mockTenant.GetDefaultPrincipal(); + var testedStandardController = BuildStandardController(httpContext2); + + var response = await testedStandardController.GetConfigurationSettings().ConfigureAwait(false); + + var configurationSettings = (response as OkObjectResult).Value as ConfigurationSettingsResult; + Assert.Equal(1, configurationSettings.ItemCount); + Assert.Single(configurationSettings.Items); + Assert.Equal("SAMPLE_CONFIG_ID", configurationSettings.Items.First().Id); + Assert.Equal("sampleConfigValue", configurationSettings.Items.First().Value.ToString()); + } + + [Fact] + public async Task ValidateConfigurationSettings() + { + // first install the app + using (var stream = new MemoryStream()) + { + var standardController = BuildStandardController(BuildRequestContext("InstalledEventRequest.json", stream)); + await standardController.AppLifecycle().ConfigureAwait(false); + } + // then set the configuration settings on the account install entity + using (var stream = new MemoryStream()) + { + var httpContext = new DefaultHttpContext(); + httpContext.User = _mockTenant.GetDefaultPrincipal(); + var standardController = BuildStandardController(httpContext); + + var configSettingsRequest = JsonSerializer.Deserialize>(File.ReadAllText("TestFiles\\ConfigurationRequest.json"), JsonSettings.Default()); + + await standardController.SetConfigurationSettings(configSettingsRequest).ConfigureAwait(false); + } + // prepare context user for the config validation request + var httpContext2 = new DefaultHttpContext(); + httpContext2.User = _mockTenant.GetDefaultPrincipal(); + var testedStandardController = BuildStandardController(httpContext2); + + var response = await testedStandardController.ValidateConfiguration().ConfigureAwait(false); + + Assert.True(response is OkResult); + } + + private Controllers.StandardController BuildStandardController(HttpContext httpContext) + { + var standardControllerLogger = Substitute.For>(); + + var controller = new Controllers.StandardController(_configuration, standardControllerLogger, _descriptorService, _accountService, _healthReporter) + { + ControllerContext = new ControllerContext + { + HttpContext = httpContext + } + }; + + return controller; + } + + private HttpContext BuildRequestContext(string requestFilePath, MemoryStream stream) + { + var httpContext = new DefaultHttpContext(); + + httpContext.User = _mockTenant.GetDefaultPrincipal(); + + var requestPayload = File.ReadAllText($"TestFiles\\{requestFilePath}"); + var payloadBytes = Encoding.UTF8.GetBytes(requestPayload); + stream.Write(payloadBytes, 0, payloadBytes.Length); + httpContext.Request.Body = stream; + httpContext.Request.Body.Position = 0; + httpContext.Request.ContentLength = stream.Length; + + return httpContext; + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/ConfigurationRequest.json b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/ConfigurationRequest.json new file mode 100644 index 0000000..523570a --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/ConfigurationRequest.json @@ -0,0 +1,6 @@ +[ + { + "id": "SAMPLE_CONFIG_ID", + "value": "sampleConfigValue" + } +] \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/InstalledEventRequest.json b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/InstalledEventRequest.json new file mode 100644 index 0000000..504c84d --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/InstalledEventRequest.json @@ -0,0 +1,4 @@ +{ + "id": "INSTALLED", + "timestamp": "2022-02-28T06:13:31.4037797Z" +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/RegisteredEventRequest.json b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/RegisteredEventRequest.json new file mode 100644 index 0000000..30189e3 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/RegisteredEventRequest.json @@ -0,0 +1,10 @@ +{ + "id": "REGISTERED", + "timestamp": "2022-02-28T06:13:31.4037797Z", + "data": { + "clientCredentials": { + "clientId": "someTestClientId", + "clientSecret": "someTestClientSecret" + } + } +} \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/UninstalledEventRequest.json b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/UninstalledEventRequest.json new file mode 100644 index 0000000..871d937 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/UninstalledEventRequest.json @@ -0,0 +1,4 @@ +{ + "id": "UNINSTALLED", + "timestamp": "2022-02-28T06:13:31.4037797Z" +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/UnregisteredEventRequest.json b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/UnregisteredEventRequest.json new file mode 100644 index 0000000..b5b5dd3 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/TestFiles/UnregisteredEventRequest.json @@ -0,0 +1,4 @@ +{ + "id": "UNREGISTERED", + "timestamp": "2022-02-28T06:13:31.4037797Z" +} \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/appsettings.test.json b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/appsettings.test.json new file mode 100644 index 0000000..e992e94 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.Test/appsettings.test.json @@ -0,0 +1,18 @@ +{ + "Logging": { + "LogLevel": { + //"Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + + "baseUrl": "https://test.base.url", + + "AllowedHosts": "*", + "documentationUrl": "docUrl", + "MongoDb": { + "Connection": "mongodb://localhost:27017", + "Name": "lc-ui-sample-app-tests" + } +} \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.sln b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.sln new file mode 100644 index 0000000..933d3da --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rws.LC.UISampleApp", "Rws.LC.UISampleApp\Rws.LC.UISampleApp.csproj", "{4EE985BB-5B32-4953-973F-0A60D394AA95}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rws.LC.UISampleApp.Test", "Rws.LC.UISampleApp.Test\Rws.LC.UISampleApp.Test.csproj", "{AABB4130-813D-4302-A2D3-A4AC9038B18B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4EE985BB-5B32-4953-973F-0A60D394AA95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4EE985BB-5B32-4953-973F-0A60D394AA95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4EE985BB-5B32-4953-973F-0A60D394AA95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4EE985BB-5B32-4953-973F-0A60D394AA95}.Release|Any CPU.Build.0 = Release|Any CPU + {AABB4130-813D-4302-A2D3-A4AC9038B18B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AABB4130-813D-4302-A2D3-A4AC9038B18B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AABB4130-813D-4302-A2D3-A4AC9038B18B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AABB4130-813D-4302-A2D3-A4AC9038B18B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {65F3101C-5779-4A0B-98BA-1DBE3B7374AF} + EndGlobalSection +EndGlobal diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Controllers/FilesController.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Controllers/FilesController.cs new file mode 100644 index 0000000..a047cac --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Controllers/FilesController.cs @@ -0,0 +1,54 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.StaticFiles; +using Microsoft.Extensions.Logging; +using Rws.LC.UISampleApp.Helpers; +using System.Threading; +using System.Threading.Tasks; + +namespace Rws.LC.UISampleApp.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class FilesController : ControllerBase + { + /// + /// The logger. + /// + private ILogger logger; + + public FilesController(ILogger logger) + { + this.logger = logger; + } + + /// + /// Gets the embedded script. + /// + /// + /// + /// The descriptor + [HttpGet("{*relativePath}")] + public async Task GetScript(string relativePath, CancellationToken cancellationToken = default) + { + // support path instead of filename directly + //if (relativePath?.IndexOfAny(Path.GetInvalidFileNameChars()) > 0) + //{ + // return NotFound($"Resource {relativePath} not found."); + //} + + string fileName = string.IsNullOrWhiteSpace(relativePath) ? "Script.js" : relativePath; + + byte[] fileStream = await StreamHelpers.GetData(fileName, cancellationToken).ConfigureAwait(true); + + if (fileStream == null) + { + return NotFound($"Resource {relativePath} not found."); + } + + string mimeType = string.Empty; + new FileExtensionContentTypeProvider().TryGetContentType(fileName, out mimeType); + + return File(fileStream, mimeType, fileName); + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Controllers/StandardController.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Controllers/StandardController.cs new file mode 100644 index 0000000..85fa90b --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Controllers/StandardController.cs @@ -0,0 +1,249 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Rws.LC.UISampleApp.Enums; +using Rws.LC.UISampleApp.Helpers; +using Rws.LC.UISampleApp.Infrastructure; +using Rws.LC.UISampleApp.Interfaces; +using Rws.LC.UISampleApp.Models; +using System.Collections.Generic; +using System.IO; +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Threading; +using System.Threading.Tasks; + +namespace Rws.LC.UISampleApp.Controllers +{ + [Route("v1")] + [ApiController] + public class StandardController : ControllerBase + { + /// + /// The configuration + /// + private readonly IConfiguration _configuration; + + /// + /// The logger. + /// + private readonly ILogger _logger; + + /// + /// The descriptor service. + /// + private readonly IDescriptorService _descriptorService; + + /// + /// The account service. + /// + private readonly IAccountService _accountService; + + /// + /// The health reporter. + /// + private readonly IHealthReporter _healthReporter; + + + /// + /// Initializes a new instance of the class. + /// + /// The configuration. + /// The logger. + /// The descriptor service. + /// The account service. + /// The health reporter. + public StandardController(IConfiguration configuration, + ILogger logger, + IDescriptorService descriptorService, + IAccountService accountService, + IHealthReporter healthReporter) + { + _configuration = configuration; + _logger = logger; + _descriptorService = descriptorService; + _accountService = accountService; + _healthReporter = healthReporter; + } + + /// + /// Gets the app descriptor. + /// + /// The descriptor + [HttpGet("descriptor")] + public IActionResult Descriptor() + { + // This endpoint provides the descriptor for the Language Cloud to inspect and register correctly. + // It can be implemented in any number of ways. The example implementation is to load the descriptor.json file + // Alternative implementation can be generating the descriptor based on config settings, environment variables, + // etc. + _logger.LogInformation("Entered Descriptor endpoint."); + + // Descriptor service will provide an object describing the descriptor. + JsonNode descriptor = _descriptorService.GetDescriptor(); + + // TODO: You might need to change the baseUrl in appsettings.json + descriptor["baseUrl"] = _configuration["baseUrl"]; + + return Ok(descriptor); + } + + /// + /// Gets the app health. + /// + /// 200 status code if it's healthy. + [HttpGet("health")] + public IActionResult Health() + { + // This is a health check endpoint. In most cases returning Ok is enough, but you might want to make checks + // to resources this service uses, like: DB, message queues, storage etc. + // Any response besides 200 Ok, will be considered as failure. As a suggestion use "return StatusCode(500);" + // when you need to signal that the service is having health issues. + + var isHealthy = _healthReporter.IsServiceHealthy(); + if (isHealthy) + { + return Ok(); + } + + return StatusCode(500); + } + + /// + /// This endpoint provides the documentation for the app. It can return the HTML page with the documentation + /// or redirect to a page. In this sample redirect is used with URL configured in appsettings.json + /// + [HttpGet("documentation")] + public IActionResult Documentation() + { + return Redirect(_configuration.GetValue("documentationUrl")); + } + + /// + /// Receive lifecycle events for the app. + /// + /// + [Authorize] + [HttpPost("app-lifecycle")] + public async Task AppLifecycle() + { + string payload; + using (StreamReader sr = new StreamReader(Request.Body)) + { + payload = await sr.ReadToEndAsync(); + } + + var tenantId = HttpContext.User?.GetTenantId(); + + var lifecycle = JsonSerializer.Deserialize(payload, JsonSettings.Default()); + switch (lifecycle.Id) + { + case AppLifecycleEventEnum.REGISTERED: + _logger.LogInformation($"App Registered in Language Cloud."); + // This is the event notifying that the App has been registered in Language Cloud + // no further details are available for that event + AppLifecycleEvent registeredEvent = JsonSerializer.Deserialize>(payload, JsonSettings.Default()); + await _accountService.SaveRegistrationInfo(registeredEvent.Data, CancellationToken.None).ConfigureAwait(true); + break; + case AppLifecycleEventEnum.INSTALLED: + _logger.LogInformation("App Installed Event Received for tenant id {TenantId}.", tenantId); + + await _accountService.SaveAccountInfo(tenantId, CancellationToken.None).ConfigureAwait(true); + break; + case AppLifecycleEventEnum.UNREGISTERED: + // This is the event notifying that the App has been unregistered/deleted from Language Cloud. + // No further details are available for that event. + _logger.LogInformation("App Unregistered Event Received."); + // All the tenant information should be removed. + await _accountService.RemoveAccounts(CancellationToken.None).ConfigureAwait(true); + // Remove the registration information + await _accountService.RemoveRegistrationInfo(CancellationToken.None).ConfigureAwait(true); + break; + + case AppLifecycleEventEnum.UNINSTALLED: + // This is the event notifying that the App has been uninstalled from a tenant account. + // No further details are available for that event. + _logger.LogInformation("App Uninstalled Event Received."); + await _accountService.RemoveAccountInfo(tenantId, CancellationToken.None).ConfigureAwait(true); + break; + } + + return Ok(); + } + + /// + /// Gets the configuration settings. + /// + /// The updated configuration settings. + [Authorize] + [HttpGet("configuration")] + public async Task GetConfigurationSettings() + { + // All configuration settings must be returned to the caller. + // Configurations that are secret will be returned with the value set to "*****", if they have a value. + + _logger.LogInformation("Retrieving the configuration settings."); + var tenantId = HttpContext.User?.GetTenantId(); + ConfigurationSettingsResult configurationSettingsResult = await _accountService.GetConfigurationSettings(tenantId, CancellationToken.None).ConfigureAwait(true); + + return Ok(configurationSettingsResult); + } + + /// + /// Sets or updates the configuration settings. + /// + /// The updated configuration settings. + [Authorize] + [HttpPost("configuration")] + public async Task SetConfigurationSettings(List configurationValues) + { + _logger.LogInformation("Setting the configuration settings."); + + var tenantId = HttpContext.User?.GetTenantId(); + + ConfigurationSettingsResult configurationSettingsResult = await _accountService.SaveOrUpdateConfigurationSettings(tenantId, configurationValues, CancellationToken.None).ConfigureAwait(true); + + return Ok(configurationSettingsResult); + } + + /// + /// Validates the configuration. + /// + /// + [Authorize] + [HttpPost("configuration/validation")] + public async Task ValidateConfiguration() + { + + _logger.LogInformation("Validating the configuration settings."); + + var tenantId = HttpContext.User?.GetTenantId(); + await _accountService.ValidateConfigurationSettings(tenantId, CancellationToken.None).ConfigureAwait(true); + + return Ok(); + } + + /// + /// This endpoint provides the privacy policy for the app. It can return the HTML page with the privacy policy + /// or redirect to a page. In this sample redirect is used the static file privacyPolicy.html. + /// + [HttpGet("privacyPolicy")] + public IActionResult PrivacyPolicy() + { + var html = System.IO.File.ReadAllText(@"./resources/privacyPolicy.html"); + return base.Content(html, "text/html"); + } + + /// + /// This endpoint provides the terms and conditions for the app. It can return the HTML page with the terms and conditions + /// or redirect to a page. In this sample redirect is used the static file termsAndCondition.html. + /// + [HttpGet("termsAndConditions")] + public IActionResult TermsANdConditions() + { + var html = System.IO.File.ReadAllText(@"./resources/termsAndConditions.html"); + return base.Content(html, "text/html"); + } + } +} \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/AppRegistrationRepository.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/AppRegistrationRepository.cs new file mode 100644 index 0000000..3c06d33 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/AppRegistrationRepository.cs @@ -0,0 +1,58 @@ +using MongoDB.Driver; +using Rws.LC.UISampleApp.DAL.Entities; +using Rws.LC.UISampleApp.Interfaces; +using System.Threading.Tasks; + +namespace Rws.LC.UISampleApp.DAL +{ + public class AppRegistrationRepository : IAppRegistrationRepository + { + /// + /// The registration status collection. + /// + private readonly IMongoCollection _appRegistration; + + /// + /// The database context. + /// + private readonly IDatabaseContext _databaseContext; + + /// + /// Initializes a new instance of the class. + /// + /// The database context. + public AppRegistrationRepository(IDatabaseContext databaseContext) + { + _databaseContext = databaseContext; + _appRegistration = _databaseContext.Mongo.GetCollection("AppRegistration"); + } + + /// + /// Saves the app registration entity. + /// + /// The app registration entity. + /// + public async Task SaveRegistrationInfo(AppRegistrationEntity entity) + { + await _appRegistration.InsertOneAsync(entity).ConfigureAwait(false); + } + + /// + /// Retrieves the app registration entity. + /// + /// The app registration entity + public async Task GetRegistrationInfo() + { + return await _appRegistration.Find(FilterDefinition.Empty).SingleOrDefaultAsync().ConfigureAwait(false); + } + + /// + /// Removes the app registration entity. + /// + /// + public async Task RemoveRegistrationInfo() + { + await _appRegistration.DeleteOneAsync(FilterDefinition.Empty).ConfigureAwait(false); + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/DatabaseContext.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/DatabaseContext.cs new file mode 100644 index 0000000..649e7c4 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/DatabaseContext.cs @@ -0,0 +1,36 @@ +using Microsoft.Extensions.Configuration; +using MongoDB.Bson; +using MongoDB.Driver; +using Rws.LC.UISampleApp.Interfaces; + +namespace Rws.LC.UISampleApp.DAL +{ + public class DatabaseContext : IDatabaseContext + { + /// + /// The Mongo Database. + /// + public IMongoDatabase Mongo { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The configuration. + public DatabaseContext(IConfiguration config) + { + var connectionString = config.GetValue("MongoDb:Connection"); + var connection = new MongoClient(connectionString); + Mongo = connection.GetDatabase(config.GetValue("MongoDb:Name")); + } + + /// + /// Checks if the Mongo Connection is healthy. + /// + /// True if it's healthy. + public bool IsConnectionHealthy() + { + bool isMongoLive = Mongo.RunCommandAsync((Command)"{ping:1}").Wait(1000); + return isMongoLive; + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/AccountInfoEntity.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/AccountInfoEntity.cs new file mode 100644 index 0000000..876f23b --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/AccountInfoEntity.cs @@ -0,0 +1,24 @@ +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using System.Collections.Generic; + +namespace Rws.LC.UISampleApp.DAL.Entities +{ + public class AccountInfoEntity + { + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public string Id { get; set; } + + /// + /// The tenant id. + /// + public string TenantId { get; set; } + + /// + /// The configuration values. + /// + public List ConfigurationValues { get; set; } + } +} + diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/AppRegistrationEntity.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/AppRegistrationEntity.cs new file mode 100644 index 0000000..09651de --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/AppRegistrationEntity.cs @@ -0,0 +1,18 @@ +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + +namespace Rws.LC.UISampleApp.DAL.Entities +{ + [BsonIgnoreExtraElements] + public class AppRegistrationEntity + { + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public string Id { get; set; } + + /// + /// The client credentials. + /// + public ClientCredentialsEntity ClientCredentials { get; set; } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/ClientCredentialsEntity.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/ClientCredentialsEntity.cs new file mode 100644 index 0000000..b399186 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/ClientCredentialsEntity.cs @@ -0,0 +1,15 @@ +namespace Rws.LC.UISampleApp.DAL.Entities +{ + public class ClientCredentialsEntity + { + /// + /// The client identifier. + /// + public string ClientId { get; set; } + + /// + /// The client secret. + /// + public string ClientSecret { get; set; } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/ConfigurationValueEntity.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/ConfigurationValueEntity.cs new file mode 100644 index 0000000..43d4ad7 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/ConfigurationValueEntity.cs @@ -0,0 +1,17 @@ +using System.Text.Json.Nodes; + +namespace Rws.LC.UISampleApp.DAL.Entities +{ + public class ConfigurationValueEntity + { + /// + /// The identifier. + /// + public string Id { get; set; } + + /// + /// The value object. + /// + public JsonNode Value { get; set; } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/Extensions/ModelExtensions.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/Extensions/ModelExtensions.cs new file mode 100644 index 0000000..8b9415e --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Entities/Extensions/ModelExtensions.cs @@ -0,0 +1,33 @@ +using Rws.LC.UISampleApp.Models; +using System.Collections.Generic; +using System.Linq; + +namespace Rws.LC.UISampleApp.DAL.Entities.Extensions +{ + public static class ModelExtensions + { + + public static List ToEntity(this List configurationValueModels) + { + return configurationValueModels.Select(config => config.ToEntity()).ToList(); + } + + public static ConfigurationValueEntity ToEntity(this ConfigurationValueModel configurationValueModel) + { + return new ConfigurationValueEntity + { + Id = configurationValueModel.Id, + Value = configurationValueModel.Value + }; + } + + public static ClientCredentialsEntity ToEntity(this ClientCredentials clientCredentials) + { + return new ClientCredentialsEntity + { + ClientId = clientCredentials.ClientId, + ClientSecret = clientCredentials.ClientSecret + }; + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/JsonNodeCustomSerializer.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/JsonNodeCustomSerializer.cs new file mode 100644 index 0000000..b9992d1 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/JsonNodeCustomSerializer.cs @@ -0,0 +1,21 @@ +using MongoDB.Bson.Serialization; +using MongoDB.Bson.Serialization.Serializers; +using System.Text.Json.Nodes; + +namespace Rws.LC.UISampleApp.DAL +{ + public class JsonNodeCustomSerializer : SerializerBase + { + public override JsonNode Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) + { + string stringValue = BsonSerializer.Deserialize(context.Reader); + + return JsonNode.Parse(stringValue); + } + public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, JsonNode value) + { + string stringValue = value.ToJsonString(); + BsonSerializer.Serialize(context.Writer, stringValue); + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/JsonNodeSerializerProvider.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/JsonNodeSerializerProvider.cs new file mode 100644 index 0000000..9240085 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/JsonNodeSerializerProvider.cs @@ -0,0 +1,14 @@ +using MongoDB.Bson.Serialization; +using System; +using System.Text.Json.Nodes; + +namespace Rws.LC.UISampleApp.DAL +{ + public class JsonNodeSerializerProvider : IBsonSerializationProvider + { + public IBsonSerializer GetSerializer(Type type) + { + return type == typeof(JsonNode) ? new JsonNodeCustomSerializer() : null; + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Repository.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Repository.cs new file mode 100644 index 0000000..f94492c --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/DAL/Repository.cs @@ -0,0 +1,94 @@ +using MongoDB.Driver; +using Rws.LC.UISampleApp.DAL.Entities; +using Rws.LC.UISampleApp.Interfaces; +using System.Linq; +using System.Threading.Tasks; + +namespace Rws.LC.UISampleApp.DAL +{ + public class Repository : IRepository + { + /// + /// The accounts info entity collection. + /// + private readonly IMongoCollection _accounts; + + /// + /// The database context. + /// + private readonly IDatabaseContext _databaseContext; + + /// + /// Initializes a new instance of the class. + /// + /// The database context. + public Repository(IDatabaseContext databaseContext) + { + _databaseContext = databaseContext; + _accounts = _databaseContext.Mongo.GetCollection("Accounts"); + } + + /// + /// Saves the account info entity. + /// + /// The account info entity. + /// + public async Task SaveAccount(AccountInfoEntity entity) + { + await _accounts.InsertOneAsync(entity).ConfigureAwait(false); + } + + /// + /// Gets the account info entity by tenant id. + /// + /// The tenant id. + /// The account info entity. + public async Task GetAccountInfoByTenantId(string tenantId) + { + var result = await _accounts.FindAsync(account => account.TenantId == tenantId).ConfigureAwait(false); + return result.SingleOrDefault(); + } + + /// + /// Removes the account by tenant id. + /// + /// The tenant id. + /// + public async Task RemoveAccount(string tenantId) + { + await _accounts.FindOneAndDeleteAsync(account => account.TenantId == tenantId).ConfigureAwait(false); + } + + /// + /// Removes all the accounts. + /// + /// + public async Task RemoveAccounts() + { + await _databaseContext.Mongo.DropCollectionAsync("Accounts").ConfigureAwait(false); + } + + /// + /// Saves or updates the configurations settings. + /// + /// The account info entity. + /// The updated account info entity. + public async Task SaveOrUpdateConfigurationSettings(AccountInfoEntity accountInfoEntity) + { + var filter = Builders.Filter + .Where(accountInfo => accountInfo.TenantId == accountInfoEntity.TenantId); + + var options = new FindOneAndUpdateOptions + { + ReturnDocument = ReturnDocument.After + }; + + var update = Builders.Update + .Set(account => account.TenantId, accountInfoEntity.TenantId) + .Set(account => account.ConfigurationValues, accountInfoEntity.ConfigurationValues); + + return await _accounts.FindOneAndUpdateAsync(filter, update, options); + } + + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Dockerfile b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Dockerfile new file mode 100644 index 0000000..282bce4 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Dockerfile @@ -0,0 +1,22 @@ +# This Dockerfile is used for debugging purposes to test how the App behaves when containerized. Run it under Linux docker. + +FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine AS base + +WORKDIR /app +EXPOSE 5000 + +FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build +WORKDIR /src +COPY ["Rws.LC.UISampleApp/Rws.LC.UISampleApp.csproj", "Rws.LC.UISampleApp/"] +RUN dotnet restore "Rws.LC.UISampleApp/Rws.LC.UISampleApp.csproj" +COPY . . +WORKDIR "/src/Rws.LC.UISampleApp" +RUN dotnet build "Rws.LC.UISampleApp.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Rws.LC.UISampleApp.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Rws.LC.UISampleApp.dll"] \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Enums/AppLifecycleEventEnum.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Enums/AppLifecycleEventEnum.cs new file mode 100644 index 0000000..1b3e6e5 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Enums/AppLifecycleEventEnum.cs @@ -0,0 +1,25 @@ +namespace Rws.LC.UISampleApp.Enums +{ + public enum AppLifecycleEventEnum + { + /// + /// App was registered in LanguageCloud. + /// + REGISTERED, + + /// + /// App was unregistered in LanguageCloud. + /// + UNREGISTERED, + + /// + /// App was installed on a tenant account. + /// + INSTALLED, + + /// + /// App was uninstalled on a tenant account. + /// + UNINSTALLED + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Enums/DataTypeEnum.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Enums/DataTypeEnum.cs new file mode 100644 index 0000000..66f8a40 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Enums/DataTypeEnum.cs @@ -0,0 +1,38 @@ +namespace Rws.LC.UISampleApp.Enums +{ + /// + /// The data types. + /// + public enum DataTypeEnum + { + /// + /// The string data type. + /// + @string, + + /// + /// The number data type. + /// + @number, + + /// + /// The integer data type. + /// + @integer, + + /// + /// The boolean data type. + /// + @boolean, + + /// + /// The date time data type. + /// + @datetime, + + /// + /// The secret data type. + /// + @secret + } +} \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/AccountValidationException.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/AccountValidationException.cs new file mode 100644 index 0000000..d8847f2 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/AccountValidationException.cs @@ -0,0 +1,22 @@ +using System; +using System.Net; + +namespace Rws.LC.UISampleApp.Exceptions +{ + public class AccountValidationException : AppException + { + public AccountValidationException(string message, Exception inner, params Details[] details) : base(message, inner) + { + ErrorCode = ErrorCodes.InvalidAccount; + StatusCode = HttpStatusCode.Unauthorized; + ExceptionDetails = details; + } + + public AccountValidationException(string message, params Details[] details) : base(message) + { + ErrorCode = ErrorCodes.InvalidAccount; + StatusCode = HttpStatusCode.Unauthorized; + ExceptionDetails = details; + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/AppException.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/AppException.cs new file mode 100644 index 0000000..d85150b --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/AppException.cs @@ -0,0 +1,62 @@ +using System; +using System.Net; + +namespace Rws.LC.UISampleApp.Exceptions +{ + public class AppException : Exception + { + public string ErrorCode { get; set; } + public HttpStatusCode StatusCode { get; set; } + public Details[] ExceptionDetails { get; set; } + + public AppException() + { + ErrorCode = ErrorCodes.InternalServerError; + StatusCode = HttpStatusCode.InternalServerError; + } + + public AppException(string message) + : base(message) + { + ErrorCode = ErrorCodes.InternalServerError; + StatusCode = HttpStatusCode.InternalServerError; + } + + public AppException(string message, Exception inner) + : base(message, inner) + { + ErrorCode = ErrorCodes.InternalServerError; + StatusCode = HttpStatusCode.InternalServerError; + } + + public AppException(HttpStatusCode statusCode, string errorCode, string message) + : base(message) + { + ErrorCode = errorCode; + StatusCode = statusCode; + } + + public AppException(HttpStatusCode statusCode, string errorCode, string message, Details[] details) + : base(message) + { + ErrorCode = errorCode; + StatusCode = statusCode; + ExceptionDetails = details; + } + + public AppException(HttpStatusCode statusCode, string errorCode, string message, Exception inner) + : base(message, inner) + { + ErrorCode = errorCode; + StatusCode = statusCode; + } + + public AppException(HttpStatusCode statusCode, string errorCode, string message, Details[] details, Exception inner) + : base(message, inner) + { + ErrorCode = errorCode; + StatusCode = statusCode; + ExceptionDetails = details; + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/AppValidationException.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/AppValidationException.cs new file mode 100644 index 0000000..9416b80 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/AppValidationException.cs @@ -0,0 +1,22 @@ +using System; +using System.Net; + +namespace Rws.LC.UISampleApp.Exceptions +{ + public class AppValidationException : AppException + { + public AppValidationException(string message, Exception inner, params Details[] details) : base(message, inner) + { + ErrorCode = ErrorCodes.InvalidValues; + StatusCode = HttpStatusCode.BadRequest; + ExceptionDetails = details; + } + + public AppValidationException(string message, params Details[] details) : base(message) + { + ErrorCode = ErrorCodes.InvalidValues; + StatusCode = HttpStatusCode.BadRequest; + ExceptionDetails = details; + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/ConfigurationValidationException.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/ConfigurationValidationException.cs new file mode 100644 index 0000000..fa6fcc2 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/ConfigurationValidationException.cs @@ -0,0 +1,14 @@ +using System.Net; + +namespace Rws.LC.UISampleApp.Exceptions +{ + public class ConfigurationValidationException : AppException + { + public ConfigurationValidationException(string message, Details[] details) : base(message) + { + ErrorCode = ErrorCodes.InvalidConfiguration; + StatusCode = HttpStatusCode.BadRequest; + ExceptionDetails = details; + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/Details.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/Details.cs new file mode 100644 index 0000000..cc6b5e7 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/Details.cs @@ -0,0 +1,9 @@ +namespace Rws.LC.UISampleApp.Exceptions +{ + public class Details + { + public string Name { get; set; } + public string Code { get; set; } + public string Value { get; set; } + } +} \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/DoubleRegistrationException.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/DoubleRegistrationException.cs new file mode 100644 index 0000000..dc2c534 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/DoubleRegistrationException.cs @@ -0,0 +1,13 @@ +using System.Net; + +namespace Rws.LC.UISampleApp.Exceptions +{ + public class DoubleRegistrationException : AppException + { + public DoubleRegistrationException() : base("The App has been already registered in Language Cloud") + { + ErrorCode = ErrorCodes.AlreadyRegistered; + StatusCode = HttpStatusCode.Conflict; + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/ErrorCodes.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/ErrorCodes.cs new file mode 100644 index 0000000..8739a08 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/ErrorCodes.cs @@ -0,0 +1,23 @@ +namespace Rws.LC.UISampleApp.Exceptions +{ + /// + /// The error codes as string constants. + /// + public static class ErrorCodes + { + public const string InvalidValues = "INVALID_VALUES"; + public const string InvalidType = "INVALID_TYPE"; + public const string InternalServerError = "INTERNAL_SERVER_ERROR"; + public const string InvalidAccount = "INVALID_ACCOUNT_ID"; + public const string AccountNotInstalled = "ACCOUNT_NOT_FOUND"; + public const string AccountAlreadyInstalled = "ACCOUNT_ALREADY_ACTIVATED"; + public const string InvalidInput = "INVALID_INPUT"; + public const string InternalError = "INTERNAL_ERROR"; + public const string InvalidConfiguration = "invalidConfiguration"; + public const string InvalidSetup = "invalidSetup"; + public const string InvalidValue = "invalidValue"; + public const string InvalidKey = "invalidKey"; + public const string NullValue = "nullValue"; + public const string AlreadyRegistered = "alreadyRegistered"; + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/ErrorMessages.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/ErrorMessages.cs new file mode 100644 index 0000000..b8c9240 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/ErrorMessages.cs @@ -0,0 +1,13 @@ +namespace Rws.LC.UISampleApp.Exceptions +{ + /// + /// The error codes as string constants. + /// + public static class ErrorMessages + { + public const string InvalidValueMessage = "Invalid value."; + public const string InvalidKeyMessage = "Invalid key."; + public const string InvalidSetupMessage = "Invalid setup."; + public const string NullValueMessage = "Value cannot be null."; + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/SetupValidationException.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/SetupValidationException.cs new file mode 100644 index 0000000..bf91ef3 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Exceptions/SetupValidationException.cs @@ -0,0 +1,14 @@ +using System.Net; + +namespace Rws.LC.UISampleApp.Exceptions +{ + public class SetupValidationException : AppException + { + public SetupValidationException(string message, Details[] details) : base(message) + { + ErrorCode = ErrorCodes.InvalidSetup; + StatusCode = HttpStatusCode.BadRequest; + ExceptionDetails = details; + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Helpers/Constants.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Helpers/Constants.cs new file mode 100644 index 0000000..9bdfe37 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Helpers/Constants.cs @@ -0,0 +1,11 @@ +namespace Rws.LC.UISampleApp.Helpers +{ + public class Constants + { + #region Headers + public const string ExtensionPointVersion = "X-LC-ExtensionPointVersion"; + public const string ExtensionId = "X-LC-ExtensionId"; + public const string AppVersion = "X-LC-AppVersion"; + #endregion + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Helpers/JsonSettings.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Helpers/JsonSettings.cs new file mode 100644 index 0000000..79ae09d --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Helpers/JsonSettings.cs @@ -0,0 +1,28 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Rws.LC.UISampleApp.Helpers +{ + /// + /// Helper class for Json Serializer Options + /// + public class JsonSettings + { + /// + /// Gets the default serializer options + /// + /// + public static JsonSerializerOptions Default() + { + var options = new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + options.Converters.Add(new JsonStringEnumConverter()); + + return options; + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Helpers/StreamHelpers.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Helpers/StreamHelpers.cs new file mode 100644 index 0000000..3f5f65c --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Helpers/StreamHelpers.cs @@ -0,0 +1,24 @@ +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace Rws.LC.UISampleApp.Helpers +{ + public static class StreamHelpers + { + /// + /// Returns a JSON stream + /// + /// The file name. + /// + internal static async Task GetData(string fileName, CancellationToken cancellationToken = default) + { + if (!File.Exists(Path.Combine("Resources", fileName))) + { + return null; + } + + return await File.ReadAllBytesAsync(Path.Combine("Resources", fileName), cancellationToken).ConfigureAwait(false); + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Infrastructure/ClaimsPrincipalExtensions.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Infrastructure/ClaimsPrincipalExtensions.cs new file mode 100644 index 0000000..16a6e51 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Infrastructure/ClaimsPrincipalExtensions.cs @@ -0,0 +1,12 @@ +using System.Security.Claims; + +namespace Rws.LC.UISampleApp.Infrastructure +{ + public static class ClaimsPrincipalExtensions + { + public static string GetTenantId(this ClaimsPrincipal principal) + { + return principal.FindFirstValue("aid"); + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IAccountService.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IAccountService.cs new file mode 100644 index 0000000..1c80e01 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IAccountService.cs @@ -0,0 +1,72 @@ +using Rws.LC.UISampleApp.Models; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Rws.LC.UISampleApp.Interfaces +{ + /// + /// Defines a service that allows creation and manipulation of account related data. + /// + public interface IAccountService + { + /// + /// Saves the registration information. + /// + /// The registered event information. + /// The cancellation token. + /// + Task SaveRegistrationInfo(RegisteredEvent registeredEvent, CancellationToken cancellationToken); + + /// + /// Removes the registration information. + /// + /// The cancellation token. + /// + Task RemoveRegistrationInfo(CancellationToken cancellationToken); + + /// + /// Saves the account information. + /// + /// The tenant identifier. + /// The cancellation token. + Task SaveAccountInfo(string tenantId, CancellationToken cancellationToken); + + /// + /// Removes the account information. + /// + /// The tenant id. + /// The cancellation token. + Task RemoveAccountInfo(string tenantId, CancellationToken cancellationToken); + + /// + /// Removes all the tenant related information. + /// + /// + Task RemoveAccounts(CancellationToken cancellationToken); + + /// + /// Saves or updates the configuration settings + /// + /// The tenant id. + /// The configuration values. + /// The cancellation token. + /// The updated configuration settings result. + Task SaveOrUpdateConfigurationSettings(string tenantId, List configurationValues, CancellationToken cancellationToken); + + /// + /// Gets the configuration settings. + /// + /// The tenant id. + /// The cancellation token. + /// The configuration settings result. + Task GetConfigurationSettings(string tenantId, CancellationToken cancellationToken); + + /// + /// Validates the configuration settings. + /// + /// The tenant id. + /// The cancellation token. + Task ValidateConfigurationSettings(string tenantId, CancellationToken cancellationToken); + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IAppRegistrationRepository.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IAppRegistrationRepository.cs new file mode 100644 index 0000000..8e479da --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IAppRegistrationRepository.cs @@ -0,0 +1,27 @@ +using Rws.LC.UISampleApp.DAL.Entities; +using System.Threading.Tasks; + +namespace Rws.LC.UISampleApp.Interfaces +{ + public interface IAppRegistrationRepository + { + /// + /// Saves the app registration entity. + /// + /// The app registration entity. + /// + Task SaveRegistrationInfo(AppRegistrationEntity entity); + + /// + /// Retrieves the app registration entity. + /// + /// The app registration entity + Task GetRegistrationInfo(); + + /// + /// Removes the app registration entity. + /// + /// + Task RemoveRegistrationInfo(); + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IDatabaseContext.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IDatabaseContext.cs new file mode 100644 index 0000000..7e19c59 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IDatabaseContext.cs @@ -0,0 +1,18 @@ +using MongoDB.Driver; + +namespace Rws.LC.UISampleApp.Interfaces +{ + public interface IDatabaseContext + { + /// + /// The Mongo Database. + /// + IMongoDatabase Mongo { get; } + + /// + /// Checks if the Mongo Connection is healthy. + /// + /// True if it's healthy. + bool IsConnectionHealthy(); + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IDescriptorService.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IDescriptorService.cs new file mode 100644 index 0000000..83fbafa --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IDescriptorService.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.Text.Json.Nodes; + +namespace Rws.LC.UISampleApp.Interfaces +{ + /// + /// Used to return the app descriptor + /// + public interface IDescriptorService + { + /// + /// Gets the descriptor. + /// + /// + JsonNode GetDescriptor(); + + /// + /// Gets the secret configurations ids. + /// + /// + List GetSecretConfigurations(); + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IHealthReporter.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IHealthReporter.cs new file mode 100644 index 0000000..8f428fc --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IHealthReporter.cs @@ -0,0 +1,14 @@ +namespace Rws.LC.UISampleApp.Interfaces +{ + /// + /// Used to check whether the service is healthy. + /// + public interface IHealthReporter + { + /// + /// Verifies if the database connection is healthy. + /// + /// True if the connection is healthy. + bool IsServiceHealthy(); + } +} \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IRepository.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IRepository.cs new file mode 100644 index 0000000..b51237e --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Interfaces/IRepository.cs @@ -0,0 +1,42 @@ +using Rws.LC.UISampleApp.DAL.Entities; +using System.Threading.Tasks; + +namespace Rws.LC.UISampleApp.Interfaces +{ + public interface IRepository + { + /// + /// Saves the account info entity. + /// + /// The account info entity. + /// + Task SaveAccount(AccountInfoEntity accountInfoEntity); + + /// + /// Gets the account info entity by tenant id. + /// + /// The tenant id. + /// The account info entity. + Task GetAccountInfoByTenantId(string tenantId); + + /// + /// Removes the account by tenant id. + /// + /// The tenant id. + /// + Task RemoveAccount(string tenantId); + + /// + /// Removes all the accounts. + /// + /// + Task RemoveAccounts(); + + /// + /// Saves or updates the configurations settings. + /// + /// The account info entity. + /// The updated account info entity. + Task SaveOrUpdateConfigurationSettings(AccountInfoEntity accountInfoEntity); + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/AppLifecycleEvent.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/AppLifecycleEvent.cs new file mode 100644 index 0000000..ec296e4 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/AppLifecycleEvent.cs @@ -0,0 +1,25 @@ +using Rws.LC.UISampleApp.Enums; + +namespace Rws.LC.UISampleApp.Models +{ + public class AppLifecycleEvent : AppLifecycleEvent where T : class + { + /// + /// The data object. + /// + public T Data { get; set; } + } + + public class AppLifecycleEvent + { + /// + /// The app lifecycle event id. + /// + public AppLifecycleEventEnum Id { get; set; } + + /// + /// The timestamp. + /// + public string Timestamp { get; set; } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/ClientCredentials.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/ClientCredentials.cs new file mode 100644 index 0000000..b83613e --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/ClientCredentials.cs @@ -0,0 +1,15 @@ +namespace Rws.LC.UISampleApp.Models +{ + public class ClientCredentials + { + /// + /// The client identifier. + /// + public string ClientId { get; set; } + + /// + /// The client secret. + /// + public string ClientSecret { get; set; } + } +} \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/ConfigurationSettingsResult.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/ConfigurationSettingsResult.cs new file mode 100644 index 0000000..ddcb8ba --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/ConfigurationSettingsResult.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; + +namespace Rws.LC.UISampleApp.Models +{ + public class ConfigurationSettingsResult + { + /// + /// Initializes an empty instance of the class. + /// Needed for deserialization in tests. + /// + public ConfigurationSettingsResult() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The list of configuration values. + public ConfigurationSettingsResult(List configurationValues) + { + Items = configurationValues; + ItemCount = configurationValues.Count; + } + + /// + /// The configuration values. + /// + public List Items { get; set; } + + /// + /// The item count. + /// + public int ItemCount { get; set; } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/ConfigurationValueModel.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/ConfigurationValueModel.cs new file mode 100644 index 0000000..e08a37e --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/ConfigurationValueModel.cs @@ -0,0 +1,17 @@ +using System.Text.Json.Nodes; + +namespace Rws.LC.UISampleApp.Models +{ + public class ConfigurationValueModel + { + /// + /// The identifier. + /// + public string Id { get; set; } + + /// + /// The value object. + /// + public JsonNode Value { get; set; } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/Extensions/EntityExtensions.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/Extensions/EntityExtensions.cs new file mode 100644 index 0000000..cf51634 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/Extensions/EntityExtensions.cs @@ -0,0 +1,23 @@ +using Rws.LC.UISampleApp.DAL.Entities; +using System.Collections.Generic; +using System.Linq; + +namespace Rws.LC.UISampleApp.Models.Extensions +{ + public static class EntityExtensions + { + public static List ToModel(this List configurationValueEntities) + { + return configurationValueEntities.Select(config => config.ToModel()).ToList(); + } + + private static ConfigurationValueModel ToModel(this ConfigurationValueEntity configurationValueEntity) + { + return new ConfigurationValueModel + { + Id = configurationValueEntity.Id, + Value = configurationValueEntity.Value + }; + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/RegisteredEvent.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/RegisteredEvent.cs new file mode 100644 index 0000000..fd1bd3e --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Models/RegisteredEvent.cs @@ -0,0 +1,10 @@ +namespace Rws.LC.UISampleApp.Models +{ + public class RegisteredEvent + { + /// + /// The client credentials. + /// + public ClientCredentials ClientCredentials { get; set; } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Program.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Program.cs new file mode 100644 index 0000000..819d1f5 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Program.cs @@ -0,0 +1,64 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Primitives; +using NLog.Web; +using NLog.Web.LayoutRenderers; +using System; +using System.Linq; + +namespace Rws.LC.UISampleApp +{ + public class Program + { + public static void Main(string[] args) + { + AspNetLayoutRendererBase.Register("TR_ID", (logEventInfo, httpContext, loggingConfiguration) => + { + StringValues traceValues; + if (httpContext == null) return null; + if (!httpContext.Request.Headers.TryGetValue("TR_ID", out traceValues)) return null; + return traceValues.FirstOrDefault(); + }); + + var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger(); + + System.Net.ServicePointManager.ServerCertificateValidationCallback += + (sender, certificate, chain, sslPolicyErrors) => + { + logger.Error($"SSL Policy Errors: {sslPolicyErrors}"); + return true; + }; + + try + { + logger.Debug("init main"); + CreateHostBuilder(args).Build().Run(); + } + catch (Exception exception) + { + //NLog: catch setup errors + logger.Error(exception, "Stopped program because of exception"); + throw; + } + finally + { + // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux) + NLog.LogManager.Shutdown(); + } + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }) + .ConfigureLogging(logging => + { + logging.ClearProviders(); + logging.SetMinimumLevel(LogLevel.Trace); + }) + .UseNLog(); + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Properties/launchSettings.json b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Properties/launchSettings.json new file mode 100644 index 0000000..eba9c81 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Properties/launchSettings.json @@ -0,0 +1,22 @@ +{ + "profiles": { + "Rws.LC.UISampleApp": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "v1/descriptor", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:5000" + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/v1/descriptor", + "environmentVariables": { + "ASPNETCORE_URLS": "http://+:80", + "LOG_LEVEL": "Debug" + } + } + } +} \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/.npmrc b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/.npmrc new file mode 100644 index 0000000..cb5c09f --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/.npmrc @@ -0,0 +1,5 @@ +@sdl:registry=https://nexus.sdl.com/repository/npm-internal/ +--init-author-name=SDL +--init-author-email=noreply@sdl.com +email=noreply@sdl.com +//nexus.sdl.com/repository/npm-internal/:_authToken=NpmToken. \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/dist/bundle.js b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/dist/bundle.js new file mode 100644 index 0000000..a0d3867 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/dist/bundle.js @@ -0,0 +1 @@ +(()=>{var e={462:function(e){var t;t=()=>(()=>{"use strict";var e={d:(t,n)=>{for(var o in n)e.o(n,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:n[o]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{trados:()=>ke});var n=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};const o="https://lc-api.sdl.com/public-api/v1".replace(/\/+$/,"");class i{constructor(e={}){this.configuration=e}set config(e){this.configuration=e}get basePath(){return null!=this.configuration.basePath?this.configuration.basePath:o}get fetchApi(){return this.configuration.fetchApi}get middleware(){return this.configuration.middleware||[]}get queryParamsStringify(){return this.configuration.queryParamsStringify||c}get username(){return this.configuration.username}get password(){return this.configuration.password}get apiKey(){const e=this.configuration.apiKey;if(e)return"function"==typeof e?e:()=>e}get accessToken(){const e=this.configuration.accessToken;if(e)return"function"==typeof e?e:()=>n(this,void 0,void 0,(function*(){return e}))}get headers(){return this.configuration.headers}get credentials(){return this.configuration.credentials}}const r=new i;class a{constructor(e=r){this.configuration=e,this.fetchApi=(e,t)=>n(this,void 0,void 0,(function*(){let n,o={url:e,init:t};for(const e of this.middleware)e.pre&&(o=(yield e.pre(Object.assign({fetch:this.fetchApi},o)))||o);try{n=yield(this.configuration.fetchApi||fetch)(o.url,o.init)}catch(e){for(const t of this.middleware)t.onError&&(n=(yield t.onError({fetch:this.fetchApi,url:o.url,init:o.init,error:e,response:n?n.clone():void 0}))||n);if(void 0===n)throw e instanceof Error?new u(e,"The request failed and the interceptors did not return an alternative response"):e}for(const e of this.middleware)e.post&&(n=(yield e.post({fetch:this.fetchApi,url:o.url,init:o.init,response:n.clone()}))||n);return n})),this.middleware=e.middleware}withMiddleware(...e){const t=this.clone();return t.middleware=t.middleware.concat(...e),t}withPreMiddleware(...e){const t=e.map((e=>({pre:e})));return this.withMiddleware(...t)}withPostMiddleware(...e){const t=e.map((e=>({post:e})));return this.withMiddleware(...t)}isJsonMime(e){return!!e&&a.jsonRegex.test(e)}request(e,t){return n(this,void 0,void 0,(function*(){const{url:n,init:o}=yield this.createFetchParams(e,t),i=yield this.fetchApi(n,o);if(i&&i.status>=200&&i.status<300)return i;throw new l(i,"Response returned an error code")}))}createFetchParams(e,t){return n(this,void 0,void 0,(function*(){let o=this.configuration.basePath+e.path;void 0!==e.query&&0!==Object.keys(e.query).length&&(o+="?"+this.configuration.queryParamsStringify(e.query));const i=Object.assign({},this.configuration.headers,e.headers);Object.keys(i).forEach((e=>void 0===i[e]?delete i[e]:{}));const r="function"==typeof t?t:()=>n(this,void 0,void 0,(function*(){return t})),a={method:e.method,headers:i,body:e.body,credentials:this.configuration.credentials},l=Object.assign(Object.assign({},a),yield r({init:a,context:e}));let u;var d;return d=l.body,u="undefined"!=typeof FormData&&d instanceof FormData||l.body instanceof URLSearchParams||function(e){return"undefined"!=typeof Blob&&e instanceof Blob}(l.body)?l.body:this.isJsonMime(i["Content-Type"])?JSON.stringify(l.body):l.body,{url:o,init:Object.assign(Object.assign({},l),{body:u})}}))}clone(){const e=new(0,this.constructor)(this.configuration);return e.middleware=this.middleware.slice(),e}}a.jsonRegex=new RegExp("^(:?application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(:?;.*)?$","i");class l extends Error{constructor(e,t){super(t),this.response=e,this.name="ResponseError"}}class u extends Error{constructor(e,t){super(t),this.cause=e,this.name="FetchError"}}class d extends Error{constructor(e,t){super(t),this.field=e,this.name="RequiredError"}}const s=",";function c(e,t=""){return Object.keys(e).map((n=>p(n,e[n],t))).filter((e=>e.length>0)).join("&")}function p(e,t,n=""){const o=n+(n.length?`[${e}]`:e);if(t instanceof Array){const e=t.map((e=>encodeURIComponent(String(e)))).join(`&${encodeURIComponent(o)}=`);return`${encodeURIComponent(o)}=${e}`}return t instanceof Set?p(e,Array.from(t),n):t instanceof Date?`${encodeURIComponent(o)}=${encodeURIComponent(t.toISOString())}`:t instanceof Object?c(t,o):`${encodeURIComponent(o)}=${encodeURIComponent(String(t))}`}function h(e){for(const t of e)if("multipart/form-data"===t.contentType)return!0;return!1}class w{constructor(e,t=(e=>e)){this.raw=e,this.transformer=t}value(){return n(this,void 0,void 0,(function*(){return this.transformer(yield this.raw.json())}))}}class f{constructor(e){this.raw=e}value(){return n(this,void 0,void 0,(function*(){}))}}class m{constructor(e){this.raw=e}value(){return n(this,void 0,void 0,(function*(){return yield this.raw.blob()}))}}var g=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class T extends a{listMyAccountsRaw(e,t){return g(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listMyAccounts().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listMyAccounts().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/accounts",method:"GET",headers:n,query:{}},t);return new w(o)}))}listMyAccounts(e,t){return g(this,void 0,void 0,(function*(){const n=yield this.listMyAccountsRaw(e,t);return yield n.value()}))}}var y=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class C extends a{getCustomFieldRaw(e,t){return y(this,void 0,void 0,(function*(){if(null==e.customFieldDefinitionId)throw new d("customFieldDefinitionId",'Required parameter "customFieldDefinitionId" was null or undefined when calling getCustomField().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getCustomField().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getCustomField().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/custom-field-definitions/{customFieldDefinitionId}".replace("{customFieldDefinitionId}",encodeURIComponent(String(e.customFieldDefinitionId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getCustomField(e,t){return y(this,void 0,void 0,(function*(){const n=yield this.getCustomFieldRaw(e,t);return yield n.value()}))}listCustomFieldsRaw(e,t){return y(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listCustomFields().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listCustomFields().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/custom-field-definitions",method:"GET",headers:o,query:n},t);return new w(i)}))}listCustomFields(e,t){return y(this,void 0,void 0,(function*(){const n=yield this.listCustomFieldsRaw(e,t);return yield n.value()}))}}var v=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class I extends a{createCustomerRaw(e,t){return v(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling createCustomer().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling createCustomer().');if(null==e.customerCreateRequest)throw new d("customerCreateRequest",'Required parameter "customerCreateRequest" was null or undefined when calling createCustomer().');const n={};null!=e.fields&&(n.fields=e.fields);const o={"Content-Type":"application/json"};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/customers",method:"POST",headers:o,query:n,body:e.customerCreateRequest},t);return new w(i)}))}createCustomer(e,t){return v(this,void 0,void 0,(function*(){const n=yield this.createCustomerRaw(e,t);return yield n.value()}))}deleteCustomerRaw(e,t){return v(this,void 0,void 0,(function*(){if(null==e.customerId)throw new d("customerId",'Required parameter "customerId" was null or undefined when calling deleteCustomer().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling deleteCustomer().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling deleteCustomer().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/customers/{customerId}".replace("{customerId}",encodeURIComponent(String(e.customerId))),method:"DELETE",headers:n,query:{}},t);return new f(o)}))}deleteCustomer(e,t){return v(this,void 0,void 0,(function*(){yield this.deleteCustomerRaw(e,t)}))}getCustomerRaw(e,t){return v(this,void 0,void 0,(function*(){if(null==e.customerId)throw new d("customerId",'Required parameter "customerId" was null or undefined when calling getCustomer().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getCustomer().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getCustomer().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/customers/{customerId}".replace("{customerId}",encodeURIComponent(String(e.customerId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getCustomer(e,t){return v(this,void 0,void 0,(function*(){const n=yield this.getCustomerRaw(e,t);return yield n.value()}))}listCustomersRaw(e,t){return v(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listCustomers().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listCustomers().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/customers",method:"GET",headers:o,query:n},t);return new w(i)}))}listCustomers(e,t){return v(this,void 0,void 0,(function*(){const n=yield this.listCustomersRaw(e,t);return yield n.value()}))}updateCustomerRaw(e,t){return v(this,void 0,void 0,(function*(){if(null==e.customerId)throw new d("customerId",'Required parameter "customerId" was null or undefined when calling updateCustomer().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling updateCustomer().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling updateCustomer().');if(null==e.customerUpdateRequest)throw new d("customerUpdateRequest",'Required parameter "customerUpdateRequest" was null or undefined when calling updateCustomer().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/customers/{customerId}".replace("{customerId}",encodeURIComponent(String(e.customerId))),method:"PUT",headers:n,query:{},body:e.customerUpdateRequest},t);return new f(o)}))}updateCustomer(e,t){return v(this,void 0,void 0,(function*(){yield this.updateCustomerRaw(e,t)}))}}var x=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class R extends a{pollUploadZipFileRaw(e,t){return x(this,void 0,void 0,(function*(){if(null==e.fileId)throw new d("fileId",'Required parameter "fileId" was null or undefined when calling pollUploadZipFile().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling pollUploadZipFile().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling pollUploadZipFile().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/files/{fileId}".replace("{fileId}",encodeURIComponent(String(e.fileId))),method:"GET",headers:n,query:{}},t);return new w(o)}))}pollUploadZipFile(e,t){return x(this,void 0,void 0,(function*(){const n=yield this.pollUploadZipFileRaw(e,t);return yield n.value()}))}uploadZipFileRaw(e,t){return x(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling uploadZipFile().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling uploadZipFile().');if(null==e.file)throw new d("file",'Required parameter "file" was null or undefined when calling uploadZipFile().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));let o,i=!1;i=h([{contentType:"multipart/form-data"}]),o=i?new FormData:new URLSearchParams,null!=e.file&&o.append("file",e.file);const r=yield this.request({path:"/files",method:"POST",headers:n,query:{},body:o},t);return new w(r)}))}uploadZipFile(e,t){return x(this,void 0,void 0,(function*(){const n=yield this.uploadZipFileRaw(e,t);return yield n.value()}))}}var L=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class q extends a{getFileProcessingConfigurationRaw(e,t){return L(this,void 0,void 0,(function*(){if(null==e.fileProcessingConfigurationId)throw new d("fileProcessingConfigurationId",'Required parameter "fileProcessingConfigurationId" was null or undefined when calling getFileProcessingConfiguration().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getFileProcessingConfiguration().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getFileProcessingConfiguration().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/file-processing-configurations/{fileProcessingConfigurationId}".replace("{fileProcessingConfigurationId}",encodeURIComponent(String(e.fileProcessingConfigurationId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getFileProcessingConfiguration(e,t){return L(this,void 0,void 0,(function*(){const n=yield this.getFileProcessingConfigurationRaw(e,t);return yield n.value()}))}getFileTypeSettingRaw(e,t){return L(this,void 0,void 0,(function*(){if(null==e.fileProcessingConfigurationId)throw new d("fileProcessingConfigurationId",'Required parameter "fileProcessingConfigurationId" was null or undefined when calling getFileTypeSetting().');if(null==e.fileTypeSettingId)throw new d("fileTypeSettingId",'Required parameter "fileTypeSettingId" was null or undefined when calling getFileTypeSetting().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getFileTypeSetting().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getFileTypeSetting().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/file-processing-configurations/{fileProcessingConfigurationId}/file-type-settings/{fileTypeSettingId}".replace("{fileProcessingConfigurationId}",encodeURIComponent(String(e.fileProcessingConfigurationId))).replace("{fileTypeSettingId}",encodeURIComponent(String(e.fileTypeSettingId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getFileTypeSetting(e,t){return L(this,void 0,void 0,(function*(){const n=yield this.getFileTypeSettingRaw(e,t);return yield n.value()}))}listFileProcessingConfigurationsRaw(e,t){return L(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listFileProcessingConfigurations().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listFileProcessingConfigurations().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/file-processing-configurations",method:"GET",headers:o,query:n},t);return new w(i)}))}listFileProcessingConfigurations(e,t){return L(this,void 0,void 0,(function*(){const n=yield this.listFileProcessingConfigurationsRaw(e,t);return yield n.value()}))}listFileTypeSettingsRaw(e,t){return L(this,void 0,void 0,(function*(){if(null==e.fileProcessingConfigurationId)throw new d("fileProcessingConfigurationId",'Required parameter "fileProcessingConfigurationId" was null or undefined when calling listFileTypeSettings().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listFileTypeSettings().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listFileTypeSettings().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/file-processing-configurations/{fileProcessingConfigurationId}/file-type-settings".replace("{fileProcessingConfigurationId}",encodeURIComponent(String(e.fileProcessingConfigurationId))),method:"GET",headers:o,query:n},t);return new w(i)}))}listFileTypeSettings(e,t){return L(this,void 0,void 0,(function*(){const n=yield this.listFileTypeSettingsRaw(e,t);return yield n.value()}))}}var z=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class j extends a{getFolderRaw(e,t){return z(this,void 0,void 0,(function*(){if(null==e.folderId)throw new d("folderId",'Required parameter "folderId" was null or undefined when calling getFolder().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getFolder().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getFolder().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/folders/{folderId}".replace("{folderId}",encodeURIComponent(String(e.folderId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getFolder(e,t){return z(this,void 0,void 0,(function*(){const n=yield this.getFolderRaw(e,t);return yield n.value()}))}getRootFolderRaw(e,t){return z(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getRootFolder().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getRootFolder().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/folders/root",method:"GET",headers:o,query:n},t);return new w(i)}))}getRootFolder(e,t){return z(this,void 0,void 0,(function*(){const n=yield this.getRootFolderRaw(e,t);return yield n.value()}))}listFoldersRaw(e,t){return z(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listFolders().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listFolders().');const n={};null!=e.name&&(n.name=e.name),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/folders",method:"GET",headers:o,query:n},t);return new w(i)}))}listFolders(e,t){return z(this,void 0,void 0,(function*(){const n=yield this.listFoldersRaw(e,t);return yield n.value()}))}}var b=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class S extends a{getGroupRaw(e,t){return b(this,void 0,void 0,(function*(){if(null==e.groupId)throw new d("groupId",'Required parameter "groupId" was null or undefined when calling getGroup().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getGroup().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getGroup().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/groups/{groupId}".replace("{groupId}",encodeURIComponent(String(e.groupId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getGroup(e,t){return b(this,void 0,void 0,(function*(){const n=yield this.getGroupRaw(e,t);return yield n.value()}))}listGroupsRaw(e,t){return b(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listGroups().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listGroups().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/groups",method:"GET",headers:o,query:n},t);return new w(i)}))}listGroups(e,t){return b(this,void 0,void 0,(function*(){const n=yield this.listGroupsRaw(e,t);return yield n.value()}))}}var k=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class F extends a{listLanguagesRaw(e,t){return k(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listLanguages().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listLanguages().');const n={};null!=e.languageCodes&&(n.languageCodes=e.languageCodes.join(s)),null!=e.type&&(n.type=e.type),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/languages",method:"GET",headers:o,query:n},t);return new w(i)}))}listLanguages(e,t){return k(this,void 0,void 0,(function*(){const n=yield this.listLanguagesRaw(e,t);return yield n.value()}))}}var E=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class P extends a{getLanguageProcessingRuleRaw(e,t){return E(this,void 0,void 0,(function*(){if(null==e.languageProcessingRuleId)throw new d("languageProcessingRuleId",'Required parameter "languageProcessingRuleId" was null or undefined when calling getLanguageProcessingRule().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getLanguageProcessingRule().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getLanguageProcessingRule().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/language-processing-rules/{languageProcessingRuleId}".replace("{languageProcessingRuleId}",encodeURIComponent(String(e.languageProcessingRuleId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getLanguageProcessingRule(e,t){return E(this,void 0,void 0,(function*(){const n=yield this.getLanguageProcessingRuleRaw(e,t);return yield n.value()}))}listLanguageProcessingRulesRaw(e,t){return E(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listLanguageProcessingRules().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listLanguageProcessingRules().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.sort&&(n.sort=e.sort),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/language-processing-rules",method:"GET",headers:o,query:n},t);return new w(i)}))}listLanguageProcessingRules(e,t){return E(this,void 0,void 0,(function*(){const n=yield this.listLanguageProcessingRulesRaw(e,t);return yield n.value()}))}}var A=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class U extends a{getPricingModelRaw(e,t){return A(this,void 0,void 0,(function*(){if(null==e.pricingModelId)throw new d("pricingModelId",'Required parameter "pricingModelId" was null or undefined when calling getPricingModel().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getPricingModel().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getPricingModel().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/pricing-models/{pricingModelId}".replace("{pricingModelId}",encodeURIComponent(String(e.pricingModelId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getPricingModel(e,t){return A(this,void 0,void 0,(function*(){const n=yield this.getPricingModelRaw(e,t);return yield n.value()}))}listPricingModelsRaw(e,t){return A(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listPricingModels().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listPricingModels().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/pricing-models",method:"GET",headers:o,query:n},t);return new w(i)}))}listPricingModels(e,t){return A(this,void 0,void 0,(function*(){const n=yield this.listPricingModelsRaw(e,t);return yield n.value()}))}}var M=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class G extends a{cancelProjectFileRaw(e,t){return M(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling cancelProjectFile().');if(null==e.fileId)throw new d("fileId",'Required parameter "fileId" was null or undefined when calling cancelProjectFile().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling cancelProjectFile().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling cancelProjectFile().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/projects/{projectId}/files/{fileId}/cancel".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{fileId}",encodeURIComponent(String(e.fileId))),method:"PUT",headers:n,query:{}},t);return new f(o)}))}cancelProjectFile(e,t){return M(this,void 0,void 0,(function*(){yield this.cancelProjectFileRaw(e,t)}))}completeProjectRaw(e,t){return M(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling completeProject().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling completeProject().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling completeProject().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/projects/{projectId}/complete".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"PUT",headers:n,query:{}},t);return new f(o)}))}completeProject(e,t){return M(this,void 0,void 0,(function*(){yield this.completeProjectRaw(e,t)}))}createProjectRaw(e,t){return M(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling createProject().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling createProject().');if(null==e.projectCreateRequest)throw new d("projectCreateRequest",'Required parameter "projectCreateRequest" was null or undefined when calling createProject().');const n={};null!=e.fields&&(n.fields=e.fields);const o={"Content-Type":"application/json"};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects",method:"POST",headers:o,query:n,body:e.projectCreateRequest},t);return new w(i)}))}createProject(e,t){return M(this,void 0,void 0,(function*(){const n=yield this.createProjectRaw(e,t);return yield n.value()}))}deleteProjectRaw(e,t){return M(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling deleteProject().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling deleteProject().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling deleteProject().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/projects/{projectId}".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"DELETE",headers:n,query:{}},t);return new f(o)}))}deleteProject(e,t){return M(this,void 0,void 0,(function*(){yield this.deleteProjectRaw(e,t)}))}getProjectRaw(e,t){return M(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling getProject().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getProject().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getProject().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getProject(e,t){return M(this,void 0,void 0,(function*(){const n=yield this.getProjectRaw(e,t);return yield n.value()}))}getProjectConfigurationRaw(e,t){return M(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling getProjectConfiguration().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getProjectConfiguration().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getProjectConfiguration().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/configuration".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getProjectConfiguration(e,t){return M(this,void 0,void 0,(function*(){const n=yield this.getProjectConfigurationRaw(e,t);return yield n.value()}))}listProjectTasksRaw(e,t){return M(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling listProjectTasks().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listProjectTasks().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listProjectTasks().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/tasks".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"GET",headers:o,query:n},t);return new w(i)}))}listProjectTasks(e,t){return M(this,void 0,void 0,(function*(){const n=yield this.listProjectTasksRaw(e,t);return yield n.value()}))}listProjectsRaw(e,t){return M(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listProjects().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listProjects().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields),null!=e.excludeOnline&&(n.excludeOnline=e.excludeOnline),null!=e.status&&(n.status=e.status),null!=e.createdFrom&&(n.createdFrom=e.createdFrom.toISOString()),null!=e.createdTo&&(n.createdTo=e.createdTo.toISOString()),null!=e.createdBy&&(n.createdBy=e.createdBy);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects",method:"GET",headers:o,query:n},t);return new w(i)}))}listProjects(e,t){return M(this,void 0,void 0,(function*(){const n=yield this.listProjectsRaw(e,t);return yield n.value()}))}startProjectRaw(e,t){return M(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling startProject().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling startProject().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling startProject().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/projects/{projectId}/start".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"PUT",headers:n,query:{}},t);return new f(o)}))}startProject(e,t){return M(this,void 0,void 0,(function*(){yield this.startProjectRaw(e,t)}))}updateCustomFieldRaw(e,t){return M(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling updateCustomField().');if(null==e.customFieldKey)throw new d("customFieldKey",'Required parameter "customFieldKey" was null or undefined when calling updateCustomField().');const n=yield this.request({path:"/projects/{projectId}/custom-fields/{customFieldKey}".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{customFieldKey}",encodeURIComponent(String(e.customFieldKey))),method:"PUT",headers:{"Content-Type":"application/json"},query:{},body:e.customFieldUpdateRequest},t);return new f(n)}))}updateCustomField(e,t){return M(this,void 0,void 0,(function*(){yield this.updateCustomFieldRaw(e,t)}))}updateProjectRaw(e,t){return M(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling updateProject().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling updateProject().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling updateProject().');if(null==e.projectUpdateRequest)throw new d("projectUpdateRequest",'Required parameter "projectUpdateRequest" was null or undefined when calling updateProject().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/projects/{projectId}".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"PUT",headers:n,query:{},body:e.projectUpdateRequest},t);return new f(o)}))}updateProject(e,t){return M(this,void 0,void 0,(function*(){yield this.updateProjectRaw(e,t)}))}updateProjectConfigurationRaw(e,t){return M(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling updateProjectConfiguration().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling updateProjectConfiguration().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling updateProjectConfiguration().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/projects/{projectId}/configuration".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"PUT",headers:n,query:{},body:e.projectConfigurationRequest},t);return new f(o)}))}updateProjectConfiguration(e,t){return M(this,void 0,void 0,(function*(){yield this.updateProjectConfigurationRaw(e,t)}))}}var V=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class X extends a{addProjectsToGroupRaw(e,t){return V(this,void 0,void 0,(function*(){if(null==e.projectGroupId)throw new d("projectGroupId",'Required parameter "projectGroupId" was null or undefined when calling addProjectsToGroup().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling addProjectsToGroup().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling addProjectsToGroup().');if(null==e.addProjectsToGroupRequest)throw new d("addProjectsToGroupRequest",'Required parameter "addProjectsToGroupRequest" was null or undefined when calling addProjectsToGroup().');const n={};null!=e.fields&&(n.fields=e.fields);const o={"Content-Type":"application/json"};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/project-groups/{projectGroupId}/projects".replace("{projectGroupId}",encodeURIComponent(String(e.projectGroupId))),method:"POST",headers:o,query:n,body:e.addProjectsToGroupRequest},t);return new w(i)}))}addProjectsToGroup(e,t){return V(this,void 0,void 0,(function*(){const n=yield this.addProjectsToGroupRaw(e,t);return yield n.value()}))}createProjectGroupRaw(e,t){return V(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling createProjectGroup().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling createProjectGroup().');if(null==e.projectGroupCreateRequest)throw new d("projectGroupCreateRequest",'Required parameter "projectGroupCreateRequest" was null or undefined when calling createProjectGroup().');const n={};null!=e.fields&&(n.fields=e.fields);const o={"Content-Type":"application/json"};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/project-groups",method:"POST",headers:o,query:n,body:e.projectGroupCreateRequest},t);return new w(i)}))}createProjectGroup(e,t){return V(this,void 0,void 0,(function*(){const n=yield this.createProjectGroupRaw(e,t);return yield n.value()}))}deleteProjectGroupRaw(e,t){return V(this,void 0,void 0,(function*(){if(null==e.projectGroupId)throw new d("projectGroupId",'Required parameter "projectGroupId" was null or undefined when calling deleteProjectGroup().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling deleteProjectGroup().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling deleteProjectGroup().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/project-groups/{projectGroupId}".replace("{projectGroupId}",encodeURIComponent(String(e.projectGroupId))),method:"DELETE",headers:n,query:{}},t);return new f(o)}))}deleteProjectGroup(e,t){return V(this,void 0,void 0,(function*(){yield this.deleteProjectGroupRaw(e,t)}))}getProjectGroupRaw(e,t){return V(this,void 0,void 0,(function*(){if(null==e.projectGroupId)throw new d("projectGroupId",'Required parameter "projectGroupId" was null or undefined when calling getProjectGroup().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getProjectGroup().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getProjectGroup().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/project-groups/{projectGroupId}".replace("{projectGroupId}",encodeURIComponent(String(e.projectGroupId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getProjectGroup(e,t){return V(this,void 0,void 0,(function*(){const n=yield this.getProjectGroupRaw(e,t);return yield n.value()}))}listProjectGroupsRaw(e,t){return V(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listProjectGroups().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listProjectGroups().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/project-groups",method:"GET",headers:o,query:n},t);return new w(i)}))}listProjectGroups(e,t){return V(this,void 0,void 0,(function*(){const n=yield this.listProjectGroupsRaw(e,t);return yield n.value()}))}removeProjectsFromGroupRaw(e,t){return V(this,void 0,void 0,(function*(){if(null==e.projectGroupId)throw new d("projectGroupId",'Required parameter "projectGroupId" was null or undefined when calling removeProjectsFromGroup().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling removeProjectsFromGroup().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling removeProjectsFromGroup().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/project-groups/{projectGroupId}/projects".replace("{projectGroupId}",encodeURIComponent(String(e.projectGroupId))),method:"DELETE",headers:n,query:{},body:e.removeProjectsFromGroupRequest},t);return new f(o)}))}removeProjectsFromGroup(e,t){return V(this,void 0,void 0,(function*(){yield this.removeProjectsFromGroupRaw(e,t)}))}updateProjectGroupRaw(e,t){return V(this,void 0,void 0,(function*(){if(null==e.projectGroupId)throw new d("projectGroupId",'Required parameter "projectGroupId" was null or undefined when calling updateProjectGroup().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling updateProjectGroup().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling updateProjectGroup().');if(null==e.projectGroupUpdateRequest)throw new d("projectGroupUpdateRequest",'Required parameter "projectGroupUpdateRequest" was null or undefined when calling updateProjectGroup().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/project-groups/{projectGroupId}".replace("{projectGroupId}",encodeURIComponent(String(e.projectGroupId))),method:"PUT",headers:n,query:{},body:e.projectGroupUpdateRequest},t);return new f(o)}))}updateProjectGroup(e,t){return V(this,void 0,void 0,(function*(){yield this.updateProjectGroupRaw(e,t)}))}}var O=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class D extends a{createProjectTemplateRaw(e,t){return O(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling createProjectTemplate().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling createProjectTemplate().');if(null==e.projectTemplateCreateRequest)throw new d("projectTemplateCreateRequest",'Required parameter "projectTemplateCreateRequest" was null or undefined when calling createProjectTemplate().');const n={};null!=e.fields&&(n.fields=e.fields);const o={"Content-Type":"application/json"};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/project-templates",method:"POST",headers:o,query:n,body:e.projectTemplateCreateRequest},t);return new w(i)}))}createProjectTemplate(e,t){return O(this,void 0,void 0,(function*(){const n=yield this.createProjectTemplateRaw(e,t);return yield n.value()}))}deleteProjectTemplateRaw(e,t){return O(this,void 0,void 0,(function*(){if(null==e.projectTemplateId)throw new d("projectTemplateId",'Required parameter "projectTemplateId" was null or undefined when calling deleteProjectTemplate().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling deleteProjectTemplate().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling deleteProjectTemplate().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/project-templates/{projectTemplateId}".replace("{projectTemplateId}",encodeURIComponent(String(e.projectTemplateId))),method:"DELETE",headers:n,query:{}},t);return new f(o)}))}deleteProjectTemplate(e,t){return O(this,void 0,void 0,(function*(){yield this.deleteProjectTemplateRaw(e,t)}))}getProjectTemplateRaw(e,t){return O(this,void 0,void 0,(function*(){if(null==e.projectTemplateId)throw new d("projectTemplateId",'Required parameter "projectTemplateId" was null or undefined when calling getProjectTemplate().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getProjectTemplate().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getProjectTemplate().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/project-templates/{projectTemplateId}".replace("{projectTemplateId}",encodeURIComponent(String(e.projectTemplateId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getProjectTemplate(e,t){return O(this,void 0,void 0,(function*(){const n=yield this.getProjectTemplateRaw(e,t);return yield n.value()}))}listProjectTemplatesRaw(e,t){return O(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listProjectTemplates().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listProjectTemplates().');const n={};null!=e.name&&(n.name=e.name),null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/project-templates",method:"GET",headers:o,query:n},t);return new w(i)}))}listProjectTemplates(e,t){return O(this,void 0,void 0,(function*(){const n=yield this.listProjectTemplatesRaw(e,t);return yield n.value()}))}updateProjectTemplateRaw(e,t){return O(this,void 0,void 0,(function*(){if(null==e.projectTemplateId)throw new d("projectTemplateId",'Required parameter "projectTemplateId" was null or undefined when calling updateProjectTemplate().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling updateProjectTemplate().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling updateProjectTemplate().');if(null==e.projectTemplateUpdateRequest)throw new d("projectTemplateUpdateRequest",'Required parameter "projectTemplateUpdateRequest" was null or undefined when calling updateProjectTemplate().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/project-templates/{projectTemplateId}".replace("{projectTemplateId}",encodeURIComponent(String(e.projectTemplateId))),method:"PUT",headers:n,query:{},body:e.projectTemplateUpdateRequest},t);return new f(o)}))}updateProjectTemplate(e,t){return O(this,void 0,void 0,(function*(){yield this.updateProjectTemplateRaw(e,t)}))}}var H=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class B extends a{getPublicKeyRaw(e,t){return H(this,void 0,void 0,(function*(){if(null==e.kid)throw new d("kid",'Required parameter "kid" was null or undefined when calling getPublicKey().');const n=yield this.request({path:"/.well-known/jwks.json/{kid}".replace("{kid}",encodeURIComponent(String(e.kid))),method:"GET",headers:{},query:{}},t);return new w(n)}))}getPublicKey(e,t){return H(this,void 0,void 0,(function*(){const n=yield this.getPublicKeyRaw(e,t);return yield n.value()}))}listPublicKeysRaw(e){return H(this,void 0,void 0,(function*(){const t=yield this.request({path:"/.well-known/jwks.json",method:"GET",headers:{},query:{}},e);return new w(t)}))}listPublicKeys(e){return H(this,void 0,void 0,(function*(){const t=yield this.listPublicKeysRaw(e);return yield t.value()}))}}var N=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class K extends a{downloadQuoteReportRaw(e,t){return N(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling downloadQuoteReport().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling downloadQuoteReport().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling downloadQuoteReport().');const n={};null!=e.format&&(n.format=e.format),null!=e.exportId&&(n.exportId=e.exportId);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/quote-report/download".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"GET",headers:o,query:n},t);return new m(i)}))}downloadQuoteReport(e,t){return N(this,void 0,void 0,(function*(){const n=yield this.downloadQuoteReportRaw(e,t);return yield n.value()}))}exportQuoteReportRaw(e,t){return N(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling exportQuoteReport().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling exportQuoteReport().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling exportQuoteReport().');const n={};null!=e.format&&(n.format=e.format),null!=e.languageId&&(n.languageId=e.languageId);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/quote-report/export".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"POST",headers:o,query:n},t);return new w(i)}))}exportQuoteReport(e,t){return N(this,void 0,void 0,(function*(){const n=yield this.exportQuoteReportRaw(e,t);return yield n.value()}))}pollQuoteReportExportRaw(e,t){return N(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling pollQuoteReportExport().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling pollQuoteReportExport().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling pollQuoteReportExport().');const n={};null!=e.format&&(n.format=e.format),null!=e.exportId&&(n.exportId=e.exportId);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/quote-report/export".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"GET",headers:o,query:n},t);return new w(i)}))}pollQuoteReportExport(e,t){return N(this,void 0,void 0,(function*(){const n=yield this.pollQuoteReportExportRaw(e,t);return yield n.value()}))}}var Q=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class W extends a{addSourceFileRaw(e,t){return Q(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling addSourceFile().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling addSourceFile().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling addSourceFile().');if(null==e.properties)throw new d("properties",'Required parameter "properties" was null or undefined when calling addSourceFile().');if(null==e.file)throw new d("file",'Required parameter "file" was null or undefined when calling addSourceFile().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));let o,i=!1;i=h([{contentType:"multipart/form-data"}]),o=i?new FormData:new URLSearchParams,null!=e.properties&&o.append("properties",new Blob([JSON.stringify(e.properties)],{type:"application/json"})),null!=e.file&&o.append("file",e.file);const r=yield this.request({path:"/projects/{projectId}/source-files".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"POST",headers:n,query:{},body:o},t);return new w(r)}))}addSourceFile(e,t){return Q(this,void 0,void 0,(function*(){const n=yield this.addSourceFileRaw(e,t);return yield n.value()}))}addSourceFileVersionRaw(e,t){return Q(this,void 0,void 0,(function*(){if(null==e.sourceFileId)throw new d("sourceFileId",'Required parameter "sourceFileId" was null or undefined when calling addSourceFileVersion().');if(null==e.taskId)throw new d("taskId",'Required parameter "taskId" was null or undefined when calling addSourceFileVersion().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling addSourceFileVersion().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling addSourceFileVersion().');if(null==e.properties)throw new d("properties",'Required parameter "properties" was null or undefined when calling addSourceFileVersion().');if(null==e.file)throw new d("file",'Required parameter "file" was null or undefined when calling addSourceFileVersion().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));let i,r=!1;r=h([{contentType:"multipart/form-data"}]),i=r?new FormData:new URLSearchParams,null!=e.properties&&i.append("properties",new Blob([JSON.stringify(e.properties)],{type:"application/json"})),null!=e.file&&i.append("file",e.file);const a=yield this.request({path:"/tasks/{taskId}/source-files/{sourceFileId}/versions".replace("{sourceFileId}",encodeURIComponent(String(e.sourceFileId))).replace("{taskId}",encodeURIComponent(String(e.taskId))),method:"POST",headers:o,query:n,body:i},t);return new w(a)}))}addSourceFileVersion(e,t){return Q(this,void 0,void 0,(function*(){const n=yield this.addSourceFileVersionRaw(e,t);return yield n.value()}))}addSourceFilesRaw(e,t){return Q(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling addSourceFiles().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling addSourceFiles().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling addSourceFiles().');if(null==e.sourceFileAttachmentRequest)throw new d("sourceFileAttachmentRequest",'Required parameter "sourceFileAttachmentRequest" was null or undefined when calling addSourceFiles().');const n={};null!=e.fields&&(n.fields=e.fields);const o={"Content-Type":"application/json"};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/source-files/attach-files".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"POST",headers:o,query:n,body:e.sourceFileAttachmentRequest},t);return new w(i)}))}addSourceFiles(e,t){return Q(this,void 0,void 0,(function*(){const n=yield this.addSourceFilesRaw(e,t);return yield n.value()}))}downloadSourceFileVersionRaw(e,t){return Q(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling downloadSourceFileVersion().');if(null==e.sourceFileId)throw new d("sourceFileId",'Required parameter "sourceFileId" was null or undefined when calling downloadSourceFileVersion().');if(null==e.fileVersionId)throw new d("fileVersionId",'Required parameter "fileVersionId" was null or undefined when calling downloadSourceFileVersion().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling downloadSourceFileVersion().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling downloadSourceFileVersion().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/projects/{projectId}/source-files/{sourceFileId}/versions/{fileVersionId}/download".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{sourceFileId}",encodeURIComponent(String(e.sourceFileId))).replace("{fileVersionId}",encodeURIComponent(String(e.fileVersionId))),method:"GET",headers:n,query:{}},t);return new m(o)}))}downloadSourceFileVersion(e,t){return Q(this,void 0,void 0,(function*(){const n=yield this.downloadSourceFileVersionRaw(e,t);return yield n.value()}))}getSourceFileRaw(e,t){return Q(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling getSourceFile().');if(null==e.sourceFileId)throw new d("sourceFileId",'Required parameter "sourceFileId" was null or undefined when calling getSourceFile().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getSourceFile().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getSourceFile().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/source-files/{sourceFileId}".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{sourceFileId}",encodeURIComponent(String(e.sourceFileId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getSourceFile(e,t){return Q(this,void 0,void 0,(function*(){const n=yield this.getSourceFileRaw(e,t);return yield n.value()}))}getSourceFilePropertiesRaw(e,t){return Q(this,void 0,void 0,(function*(){if(null==e.taskId)throw new d("taskId",'Required parameter "taskId" was null or undefined when calling getSourceFileProperties().');if(null==e.sourceFileId)throw new d("sourceFileId",'Required parameter "sourceFileId" was null or undefined when calling getSourceFileProperties().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getSourceFileProperties().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getSourceFileProperties().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/tasks/{taskId}/source-files/{sourceFileId}".replace("{taskId}",encodeURIComponent(String(e.taskId))).replace("{sourceFileId}",encodeURIComponent(String(e.sourceFileId))),method:"GET",headers:n,query:{}},t);return new w(o)}))}getSourceFileProperties(e,t){return Q(this,void 0,void 0,(function*(){const n=yield this.getSourceFilePropertiesRaw(e,t);return yield n.value()}))}listSourceFileVersionsRaw(e,t){return Q(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling listSourceFileVersions().');if(null==e.sourceFileId)throw new d("sourceFileId",'Required parameter "sourceFileId" was null or undefined when calling listSourceFileVersions().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listSourceFileVersions().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listSourceFileVersions().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/source-files/{sourceFileId}/versions".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{sourceFileId}",encodeURIComponent(String(e.sourceFileId))),method:"GET",headers:o,query:n},t);return new w(i)}))}listSourceFileVersions(e,t){return Q(this,void 0,void 0,(function*(){const n=yield this.listSourceFileVersionsRaw(e,t);return yield n.value()}))}listSourceFilesRaw(e,t){return Q(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling listSourceFiles().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listSourceFiles().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listSourceFiles().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/source-files".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"GET",headers:o,query:n},t);return new w(i)}))}listSourceFiles(e,t){return Q(this,void 0,void 0,(function*(){const n=yield this.listSourceFilesRaw(e,t);return yield n.value()}))}updateSourceFileRaw(e,t){return Q(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling updateSourceFile().');if(null==e.sourceFileId)throw new d("sourceFileId",'Required parameter "sourceFileId" was null or undefined when calling updateSourceFile().');const n=yield this.request({path:"/projects/{projectId}/source-files/{sourceFileId}".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{sourceFileId}",encodeURIComponent(String(e.sourceFileId))),method:"PUT",headers:{"Content-Type":"application/json"},query:{},body:e.sourceFileRenameRequest},t);return new f(n)}))}updateSourceFile(e,t){return Q(this,void 0,void 0,(function*(){yield this.updateSourceFileRaw(e,t)}))}updateSourceFilesRaw(e,t){return Q(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling updateSourceFiles().');const n=yield this.request({path:"/projects/{projectId}/source-files".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"PUT",headers:{"Content-Type":"application/json"},query:{},body:e.sourceFilesUpdateRequest},t);return new f(n)}))}updateSourceFiles(e,t){return Q(this,void 0,void 0,(function*(){yield this.updateSourceFilesRaw(e,t)}))}updateSourcePropertiesRaw(e,t){return Q(this,void 0,void 0,(function*(){if(null==e.taskId)throw new d("taskId",'Required parameter "taskId" was null or undefined when calling updateSourceProperties().');if(null==e.sourceFileId)throw new d("sourceFileId",'Required parameter "sourceFileId" was null or undefined when calling updateSourceProperties().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling updateSourceProperties().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling updateSourceProperties().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/tasks/{taskId}/source-files/{sourceFileId}".replace("{taskId}",encodeURIComponent(String(e.taskId))).replace("{sourceFileId}",encodeURIComponent(String(e.sourceFileId))),method:"PUT",headers:n,query:{},body:e.sourceFilePropertiesUpdateRequest},t);return new f(o)}))}updateSourceProperties(e,t){return Q(this,void 0,void 0,(function*(){yield this.updateSourcePropertiesRaw(e,t)}))}}var J=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class Z extends a{getTqaProfileRaw(e,t){return J(this,void 0,void 0,(function*(){if(null==e.profileId)throw new d("profileId",'Required parameter "profileId" was null or undefined when calling getTqaProfile().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getTqaProfile().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getTqaProfile().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/tqa-profiles/{profileId}".replace("{profileId}",encodeURIComponent(String(e.profileId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getTqaProfile(e,t){return J(this,void 0,void 0,(function*(){const n=yield this.getTqaProfileRaw(e,t);return yield n.value()}))}listTqaProfilesRaw(e,t){return J(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listTqaProfiles().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listTqaProfiles().');const n={};null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/tqa-profiles",method:"GET",headers:o,query:n},t);return new w(i)}))}listTqaProfiles(e,t){return J(this,void 0,void 0,(function*(){const n=yield this.listTqaProfilesRaw(e,t);return yield n.value()}))}}var _=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class $ extends a{addTargetFileVersionRaw(e,t){return _(this,void 0,void 0,(function*(){if(null==e.taskId)throw new d("taskId",'Required parameter "taskId" was null or undefined when calling addTargetFileVersion().');if(null==e.targetFileId)throw new d("targetFileId",'Required parameter "targetFileId" was null or undefined when calling addTargetFileVersion().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling addTargetFileVersion().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling addTargetFileVersion().');if(null==e.properties)throw new d("properties",'Required parameter "properties" was null or undefined when calling addTargetFileVersion().');if(null==e.file)throw new d("file",'Required parameter "file" was null or undefined when calling addTargetFileVersion().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));let i,r=!1;r=h([{contentType:"multipart/form-data"}]),i=r?new FormData:new URLSearchParams,null!=e.properties&&i.append("properties",new Blob([JSON.stringify(e.properties)],{type:"application/json"})),null!=e.file&&i.append("file",e.file);const a=yield this.request({path:"/tasks/{taskId}/target-files/{targetFileId}/versions".replace("{taskId}",encodeURIComponent(String(e.taskId))).replace("{targetFileId}",encodeURIComponent(String(e.targetFileId))),method:"POST",headers:o,query:n,body:i},t);return new w(a)}))}addTargetFileVersion(e,t){return _(this,void 0,void 0,(function*(){const n=yield this.addTargetFileVersionRaw(e,t);return yield n.value()}))}downloadExportedTargetFileVersionRaw(e,t){return _(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling downloadExportedTargetFileVersion().');if(null==e.targetFileId)throw new d("targetFileId",'Required parameter "targetFileId" was null or undefined when calling downloadExportedTargetFileVersion().');if(null==e.fileVersionId)throw new d("fileVersionId",'Required parameter "fileVersionId" was null or undefined when calling downloadExportedTargetFileVersion().');if(null==e.exportId)throw new d("exportId",'Required parameter "exportId" was null or undefined when calling downloadExportedTargetFileVersion().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling downloadExportedTargetFileVersion().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling downloadExportedTargetFileVersion().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/projects/{projectId}/target-files/{targetFileId}/versions/{fileVersionId}/exports/{exportId}/download".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{targetFileId}",encodeURIComponent(String(e.targetFileId))).replace("{fileVersionId}",encodeURIComponent(String(e.fileVersionId))).replace("{exportId}",encodeURIComponent(String(e.exportId))),method:"GET",headers:n,query:{}},t);return new m(o)}))}downloadExportedTargetFileVersion(e,t){return _(this,void 0,void 0,(function*(){const n=yield this.downloadExportedTargetFileVersionRaw(e,t);return yield n.value()}))}downloadFileVersionRaw(e,t){return _(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling downloadFileVersion().');if(null==e.targetFileId)throw new d("targetFileId",'Required parameter "targetFileId" was null or undefined when calling downloadFileVersion().');if(null==e.fileVersionId)throw new d("fileVersionId",'Required parameter "fileVersionId" was null or undefined when calling downloadFileVersion().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling downloadFileVersion().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling downloadFileVersion().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/projects/{projectId}/target-files/{targetFileId}/versions/{fileVersionId}/download".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{targetFileId}",encodeURIComponent(String(e.targetFileId))).replace("{fileVersionId}",encodeURIComponent(String(e.fileVersionId))),method:"GET",headers:n,query:{}},t);return new m(o)}))}downloadFileVersion(e,t){return _(this,void 0,void 0,(function*(){const n=yield this.downloadFileVersionRaw(e,t);return yield n.value()}))}exportTargetFileVersionRaw(e,t){return _(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling exportTargetFileVersion().');if(null==e.targetFileId)throw new d("targetFileId",'Required parameter "targetFileId" was null or undefined when calling exportTargetFileVersion().');if(null==e.fileVersionId)throw new d("fileVersionId",'Required parameter "fileVersionId" was null or undefined when calling exportTargetFileVersion().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling exportTargetFileVersion().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling exportTargetFileVersion().');const n={};null!=e.format&&(n.format=e.format);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/target-files/{targetFileId}/versions/{fileVersionId}/exports".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{targetFileId}",encodeURIComponent(String(e.targetFileId))).replace("{fileVersionId}",encodeURIComponent(String(e.fileVersionId))),method:"POST",headers:o,query:n},t);return new w(i)}))}exportTargetFileVersion(e,t){return _(this,void 0,void 0,(function*(){const n=yield this.exportTargetFileVersionRaw(e,t);return yield n.value()}))}getTargetFileRaw(e,t){return _(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling getTargetFile().');if(null==e.targetFileId)throw new d("targetFileId",'Required parameter "targetFileId" was null or undefined when calling getTargetFile().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getTargetFile().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getTargetFile().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/target-files/{targetFileId}".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{targetFileId}",encodeURIComponent(String(e.targetFileId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getTargetFile(e,t){return _(this,void 0,void 0,(function*(){const n=yield this.getTargetFileRaw(e,t);return yield n.value()}))}getTargetFileVersionRaw(e,t){return _(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling getTargetFileVersion().');if(null==e.targetFileId)throw new d("targetFileId",'Required parameter "targetFileId" was null or undefined when calling getTargetFileVersion().');if(null==e.fileVersionId)throw new d("fileVersionId",'Required parameter "fileVersionId" was null or undefined when calling getTargetFileVersion().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getTargetFileVersion().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getTargetFileVersion().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/target-files/{targetFileId}/versions/{fileVersionId}".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{targetFileId}",encodeURIComponent(String(e.targetFileId))).replace("{fileVersionId}",encodeURIComponent(String(e.fileVersionId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getTargetFileVersion(e,t){return _(this,void 0,void 0,(function*(){const n=yield this.getTargetFileVersionRaw(e,t);return yield n.value()}))}importTargetFileVersionRaw(e,t){return _(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling importTargetFileVersion().');if(null==e.targetFileId)throw new d("targetFileId",'Required parameter "targetFileId" was null or undefined when calling importTargetFileVersion().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling importTargetFileVersion().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling importTargetFileVersion().');if(null==e.file)throw new d("file",'Required parameter "file" was null or undefined when calling importTargetFileVersion().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));let o,i=!1;i=h([{contentType:"multipart/form-data"}]),o=i?new FormData:new URLSearchParams,null!=e.file&&o.append("file",e.file);const r=yield this.request({path:"/projects/{projectId}/target-files/{targetFileId}/versions/imports".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{targetFileId}",encodeURIComponent(String(e.targetFileId))),method:"POST",headers:n,query:{},body:o},t);return new w(r)}))}importTargetFileVersion(e,t){return _(this,void 0,void 0,(function*(){const n=yield this.importTargetFileVersionRaw(e,t);return yield n.value()}))}listTargetFileVersionsRaw(e,t){return _(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling listTargetFileVersions().');if(null==e.targetFileId)throw new d("targetFileId",'Required parameter "targetFileId" was null or undefined when calling listTargetFileVersions().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listTargetFileVersions().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listTargetFileVersions().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/target-files/{targetFileId}/versions".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{targetFileId}",encodeURIComponent(String(e.targetFileId))),method:"GET",headers:o,query:n},t);return new w(i)}))}listTargetFileVersions(e,t){return _(this,void 0,void 0,(function*(){const n=yield this.listTargetFileVersionsRaw(e,t);return yield n.value()}))}listTargetFilesRaw(e,t){return _(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling listTargetFiles().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listTargetFiles().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listTargetFiles().');const n={};null!=e.targetFileIds&&(n.targetFileIds=e.targetFileIds.join(s)),null!=e.sourceFileIds&&(n.sourceFileIds=e.sourceFileIds.join(s)),null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/projects/{projectId}/target-files".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"GET",headers:o,query:n},t);return new w(i)}))}listTargetFiles(e,t){return _(this,void 0,void 0,(function*(){const n=yield this.listTargetFilesRaw(e,t);return yield n.value()}))}pollTargetFileVersionExportRaw(e,t){return _(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling pollTargetFileVersionExport().');if(null==e.targetFileId)throw new d("targetFileId",'Required parameter "targetFileId" was null or undefined when calling pollTargetFileVersionExport().');if(null==e.fileVersionId)throw new d("fileVersionId",'Required parameter "fileVersionId" was null or undefined when calling pollTargetFileVersionExport().');if(null==e.exportId)throw new d("exportId",'Required parameter "exportId" was null or undefined when calling pollTargetFileVersionExport().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling pollTargetFileVersionExport().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling pollTargetFileVersionExport().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/projects/{projectId}/target-files/{targetFileId}/versions/{fileVersionId}/exports/{exportId}".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{targetFileId}",encodeURIComponent(String(e.targetFileId))).replace("{fileVersionId}",encodeURIComponent(String(e.fileVersionId))).replace("{exportId}",encodeURIComponent(String(e.exportId))),method:"GET",headers:n,query:{}},t);return new w(o)}))}pollTargetFileVersionExport(e,t){return _(this,void 0,void 0,(function*(){const n=yield this.pollTargetFileVersionExportRaw(e,t);return yield n.value()}))}pollTargetFileVersionImportRaw(e,t){return _(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling pollTargetFileVersionImport().');if(null==e.targetFileId)throw new d("targetFileId",'Required parameter "targetFileId" was null or undefined when calling pollTargetFileVersionImport().');if(null==e.importId)throw new d("importId",'Required parameter "importId" was null or undefined when calling pollTargetFileVersionImport().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling pollTargetFileVersionImport().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling pollTargetFileVersionImport().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/projects/{projectId}/target-files/{targetFileId}/versions/imports/{importId}".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{targetFileId}",encodeURIComponent(String(e.targetFileId))).replace("{importId}",encodeURIComponent(String(e.importId))),method:"GET",headers:n,query:{}},t);return new w(o)}))}pollTargetFileVersionImport(e,t){return _(this,void 0,void 0,(function*(){const n=yield this.pollTargetFileVersionImportRaw(e,t);return yield n.value()}))}updateTargetFileRaw(e,t){return _(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling updateTargetFile().');if(null==e.targetFileId)throw new d("targetFileId",'Required parameter "targetFileId" was null or undefined when calling updateTargetFile().');const n=yield this.request({path:"/projects/{projectId}/target-files/{targetFileId}".replace("{projectId}",encodeURIComponent(String(e.projectId))).replace("{targetFileId}",encodeURIComponent(String(e.targetFileId))),method:"PUT",headers:{"Content-Type":"application/json"},query:{},body:e.targetFileRenameRequest},t);return new f(n)}))}updateTargetFile(e,t){return _(this,void 0,void 0,(function*(){yield this.updateTargetFileRaw(e,t)}))}updateTargetFilesRaw(e,t){return _(this,void 0,void 0,(function*(){if(null==e.projectId)throw new d("projectId",'Required parameter "projectId" was null or undefined when calling updateTargetFiles().');const n=yield this.request({path:"/projects/{projectId}/target-files".replace("{projectId}",encodeURIComponent(String(e.projectId))),method:"PUT",headers:{"Content-Type":"application/json"},query:{},body:e.targetFilesUpdateRequest},t);return new f(n)}))}updateTargetFiles(e,t){return _(this,void 0,void 0,(function*(){yield this.updateTargetFilesRaw(e,t)}))}}var Y=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class ee extends a{acceptTaskRaw(e,t){return Y(this,void 0,void 0,(function*(){if(null==e.taskId)throw new d("taskId",'Required parameter "taskId" was null or undefined when calling acceptTask().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling acceptTask().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling acceptTask().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/tasks/{taskId}/accept".replace("{taskId}",encodeURIComponent(String(e.taskId))),method:"PUT",headers:n,query:{}},t);return new f(o)}))}acceptTask(e,t){return Y(this,void 0,void 0,(function*(){yield this.acceptTaskRaw(e,t)}))}assignTaskRaw(e,t){return Y(this,void 0,void 0,(function*(){if(null==e.taskId)throw new d("taskId",'Required parameter "taskId" was null or undefined when calling assignTask().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling assignTask().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling assignTask().');if(null==e.taskAssignRequest)throw new d("taskAssignRequest",'Required parameter "taskAssignRequest" was null or undefined when calling assignTask().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/tasks/{taskId}/assign".replace("{taskId}",encodeURIComponent(String(e.taskId))),method:"PUT",headers:n,query:{},body:e.taskAssignRequest},t);return new f(o)}))}assignTask(e,t){return Y(this,void 0,void 0,(function*(){yield this.assignTaskRaw(e,t)}))}completeTaskRaw(e,t){return Y(this,void 0,void 0,(function*(){if(null==e.taskId)throw new d("taskId",'Required parameter "taskId" was null or undefined when calling completeTask().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling completeTask().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling completeTask().');if(null==e.taskCompleteRequest)throw new d("taskCompleteRequest",'Required parameter "taskCompleteRequest" was null or undefined when calling completeTask().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/tasks/{taskId}/complete".replace("{taskId}",encodeURIComponent(String(e.taskId))),method:"PUT",headers:n,query:{},body:e.taskCompleteRequest},t);return new f(o)}))}completeTask(e,t){return Y(this,void 0,void 0,(function*(){yield this.completeTaskRaw(e,t)}))}getTaskRaw(e,t){return Y(this,void 0,void 0,(function*(){if(null==e.taskId)throw new d("taskId",'Required parameter "taskId" was null or undefined when calling getTask().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getTask().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getTask().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/tasks/{taskId}".replace("{taskId}",encodeURIComponent(String(e.taskId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getTask(e,t){return Y(this,void 0,void 0,(function*(){const n=yield this.getTaskRaw(e,t);return yield n.value()}))}listTasksAssignedToMeRaw(e,t){return Y(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listTasksAssignedToMe().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listTasksAssignedToMe().');const n={};null!=e.status&&(n.status=e.status),null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/tasks/assigned",method:"GET",headers:o,query:n},t);return new w(i)}))}listTasksAssignedToMe(e,t){return Y(this,void 0,void 0,(function*(){const n=yield this.listTasksAssignedToMeRaw(e,t);return yield n.value()}))}reclaimTaskRaw(e,t){return Y(this,void 0,void 0,(function*(){if(null==e.taskId)throw new d("taskId",'Required parameter "taskId" was null or undefined when calling reclaimTask().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling reclaimTask().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling reclaimTask().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/tasks/{taskId}/reclaim".replace("{taskId}",encodeURIComponent(String(e.taskId))),method:"PUT",headers:n,query:{}},t);return new f(o)}))}reclaimTask(e,t){return Y(this,void 0,void 0,(function*(){yield this.reclaimTaskRaw(e,t)}))}rejectTaskRaw(e,t){return Y(this,void 0,void 0,(function*(){if(null==e.taskId)throw new d("taskId",'Required parameter "taskId" was null or undefined when calling rejectTask().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling rejectTask().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling rejectTask().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/tasks/{taskId}/reject".replace("{taskId}",encodeURIComponent(String(e.taskId))),method:"PUT",headers:n,query:{}},t);return new f(o)}))}rejectTask(e,t){return Y(this,void 0,void 0,(function*(){yield this.rejectTaskRaw(e,t)}))}releaseTaskRaw(e,t){return Y(this,void 0,void 0,(function*(){if(null==e.taskId)throw new d("taskId",'Required parameter "taskId" was null or undefined when calling releaseTask().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling releaseTask().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling releaseTask().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/tasks/{taskId}/release".replace("{taskId}",encodeURIComponent(String(e.taskId))),method:"PUT",headers:n,query:{}},t);return new f(o)}))}releaseTask(e,t){return Y(this,void 0,void 0,(function*(){yield this.releaseTaskRaw(e,t)}))}}var te=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class ne extends a{getTaskTypeRaw(e,t){return te(this,void 0,void 0,(function*(){if(null==e.taskTypeId)throw new d("taskTypeId",'Required parameter "taskTypeId" was null or undefined when calling getTaskType().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getTaskType().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getTaskType().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/task-types/{taskTypeId}".replace("{taskTypeId}",encodeURIComponent(String(e.taskTypeId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getTaskType(e,t){return te(this,void 0,void 0,(function*(){const n=yield this.getTaskTypeRaw(e,t);return yield n.value()}))}listTaskTypesRaw(e,t){return te(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listTaskTypes().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listTaskTypes().');const n={};null!=e.key&&(n.key=e.key.join(s)),null!=e.automatic&&(n.automatic=e.automatic),null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/task-types",method:"GET",headers:o,query:n},t);return new w(i)}))}listTaskTypes(e,t){return te(this,void 0,void 0,(function*(){const n=yield this.listTaskTypesRaw(e,t);return yield n.value()}))}}var oe=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class ie extends a{createTermbaseRaw(e,t){return oe(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling createTermbase().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling createTermbase().');const n={};null!=e.fields&&(n.fields=e.fields);const o={"Content-Type":"application/json"};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/termbases",method:"POST",headers:o,query:n,body:e.termbaseCreateRequest},t);return new w(i)}))}createTermbase(e,t){return oe(this,void 0,void 0,(function*(){const n=yield this.createTermbaseRaw(e,t);return yield n.value()}))}createTermbaseEntryRaw(e,t){return oe(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling createTermbaseEntry().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling createTermbaseEntry().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling createTermbaseEntry().');const n={};null!=e.fields&&(n.fields=e.fields);const o={"Content-Type":"application/json"};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/termbases/{termbaseId}/entries".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))),method:"POST",headers:o,query:n,body:e.termbaseEntryCreateRequest},t);return new w(i)}))}createTermbaseEntry(e,t){return oe(this,void 0,void 0,(function*(){const n=yield this.createTermbaseEntryRaw(e,t);return yield n.value()}))}deleteTermbaseRaw(e,t){return oe(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling deleteTermbase().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling deleteTermbase().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling deleteTermbase().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/termbases/{termbaseId}".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))),method:"DELETE",headers:n,query:{}},t);return new f(o)}))}deleteTermbase(e,t){return oe(this,void 0,void 0,(function*(){yield this.deleteTermbaseRaw(e,t)}))}deleteTermbaseEntriesRaw(e,t){return oe(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling deleteTermbaseEntries().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling deleteTermbaseEntries().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling deleteTermbaseEntries().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/termbases/{termbaseId}/entries".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))),method:"DELETE",headers:n,query:{}},t);return new f(o)}))}deleteTermbaseEntries(e,t){return oe(this,void 0,void 0,(function*(){yield this.deleteTermbaseEntriesRaw(e,t)}))}deleteTermbaseEntryRaw(e,t){return oe(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling deleteTermbaseEntry().');if(null==e.entryId)throw new d("entryId",'Required parameter "entryId" was null or undefined when calling deleteTermbaseEntry().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling deleteTermbaseEntry().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling deleteTermbaseEntry().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/termbases/{termbaseId}/entries/{entryId}".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))).replace("{entryId}",encodeURIComponent(String(e.entryId))),method:"DELETE",headers:n,query:{}},t);return new f(o)}))}deleteTermbaseEntry(e,t){return oe(this,void 0,void 0,(function*(){yield this.deleteTermbaseEntryRaw(e,t)}))}getTermbaseRaw(e,t){return oe(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling getTermbase().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getTermbase().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getTermbase().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/termbases/{termbaseId}".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getTermbase(e,t){return oe(this,void 0,void 0,(function*(){const n=yield this.getTermbaseRaw(e,t);return yield n.value()}))}getTermbaseEntryRaw(e,t){return oe(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling getTermbaseEntry().');if(null==e.entryId)throw new d("entryId",'Required parameter "entryId" was null or undefined when calling getTermbaseEntry().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getTermbaseEntry().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getTermbaseEntry().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/termbases/{termbaseId}/entries/{entryId}".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))).replace("{entryId}",encodeURIComponent(String(e.entryId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getTermbaseEntry(e,t){return oe(this,void 0,void 0,(function*(){const n=yield this.getTermbaseEntryRaw(e,t);return yield n.value()}))}listTermbaseRaw(e,t){return oe(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listTermbase().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listTermbase().');const n={};null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.fields&&(n.fields=e.fields),null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/termbases",method:"GET",headers:o,query:n},t);return new w(i)}))}listTermbase(e,t){return oe(this,void 0,void 0,(function*(){const n=yield this.listTermbaseRaw(e,t);return yield n.value()}))}listTermbaseEntriesRaw(e,t){return oe(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling listTermbaseEntries().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listTermbaseEntries().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listTermbaseEntries().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.fields&&(n.fields=e.fields),null!=e.humanReadableIds&&(n.humanReadableIds=e.humanReadableIds);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/termbases/{termbaseId}/entries".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))),method:"GET",headers:o,query:n},t);return new w(i)}))}listTermbaseEntries(e,t){return oe(this,void 0,void 0,(function*(){const n=yield this.listTermbaseEntriesRaw(e,t);return yield n.value()}))}listTermbaseTermsRaw(e,t){return oe(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling listTermbaseTerms().');if(null==e.sourceLanguageCode)throw new d("sourceLanguageCode",'Required parameter "sourceLanguageCode" was null or undefined when calling listTermbaseTerms().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listTermbaseTerms().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listTermbaseTerms().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.search&&(n.search=e.search),null!=e.searchType&&(n.searchType=e.searchType),null!=e.targetLanguageCode&&(n.targetLanguageCode=e.targetLanguageCode);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/termbases/{termbaseId}/terms/{sourceLanguageCode}".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))).replace("{sourceLanguageCode}",encodeURIComponent(String(e.sourceLanguageCode))),method:"GET",headers:o,query:n},t);return new w(i)}))}listTermbaseTerms(e,t){return oe(this,void 0,void 0,(function*(){const n=yield this.listTermbaseTermsRaw(e,t);return yield n.value()}))}updateTermbaseRaw(e,t){return oe(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling updateTermbase().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling updateTermbase().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling updateTermbase().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/termbases/{termbaseId}".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))),method:"PUT",headers:n,query:{},body:e.termbaseUpdateRequest},t);return new f(o)}))}updateTermbase(e,t){return oe(this,void 0,void 0,(function*(){yield this.updateTermbaseRaw(e,t)}))}updateTermbaseEntryRaw(e,t){return oe(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling updateTermbaseEntry().');if(null==e.entryId)throw new d("entryId",'Required parameter "entryId" was null or undefined when calling updateTermbaseEntry().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling updateTermbaseEntry().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling updateTermbaseEntry().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/termbases/{termbaseId}/entries/{entryId}".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))).replace("{entryId}",encodeURIComponent(String(e.entryId))),method:"PUT",headers:n,query:{},body:e.termbaseEntryUpdateRequest},t);return new f(o)}))}updateTermbaseEntry(e,t){return oe(this,void 0,void 0,(function*(){yield this.updateTermbaseEntryRaw(e,t)}))}}var re=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class ae extends a{downloadExportedTermbaseRaw(e,t){return re(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling downloadExportedTermbase().');if(null==e.exportId)throw new d("exportId",'Required parameter "exportId" was null or undefined when calling downloadExportedTermbase().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling downloadExportedTermbase().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling downloadExportedTermbase().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/termbases/{termbaseId}/exports/{exportId}/download".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))).replace("{exportId}",encodeURIComponent(String(e.exportId))),method:"GET",headers:n,query:{}},t);return new m(o)}))}downloadExportedTermbase(e,t){return re(this,void 0,void 0,(function*(){const n=yield this.downloadExportedTermbaseRaw(e,t);return yield n.value()}))}downloadTermbaseDefinitionRaw(e,t){return re(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling downloadTermbaseDefinition().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling downloadTermbaseDefinition().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling downloadTermbaseDefinition().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/termbases/{termbaseId}/export-template".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))),method:"GET",headers:n,query:{}},t);return new m(o)}))}downloadTermbaseDefinition(e,t){return re(this,void 0,void 0,(function*(){const n=yield this.downloadTermbaseDefinitionRaw(e,t);return yield n.value()}))}exportTermbaseRaw(e,t){return re(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling exportTermbase().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling exportTermbase().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling exportTermbase().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/termbases/{termbaseId}/exports".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))),method:"POST",headers:n,query:{},body:e.exportTermbaseRequest},t);return new w(o)}))}exportTermbase(e,t){return re(this,void 0,void 0,(function*(){const n=yield this.exportTermbaseRaw(e,t);return yield n.value()}))}pollExportTermbaseRaw(e,t){return re(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling pollExportTermbase().');if(null==e.exportId)throw new d("exportId",'Required parameter "exportId" was null or undefined when calling pollExportTermbase().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling pollExportTermbase().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling pollExportTermbase().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/termbases/{termbaseId}/exports/{exportId}".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))).replace("{exportId}",encodeURIComponent(String(e.exportId))),method:"GET",headers:n,query:{}},t);return new w(o)}))}pollExportTermbase(e,t){return re(this,void 0,void 0,(function*(){const n=yield this.pollExportTermbaseRaw(e,t);return yield n.value()}))}}var le=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class ue extends a{downloadTermbaseImportLogRaw(e,t){return le(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling downloadTermbaseImportLog().');if(null==e.importId)throw new d("importId",'Required parameter "importId" was null or undefined when calling downloadTermbaseImportLog().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling downloadTermbaseImportLog().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling downloadTermbaseImportLog().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/termbases/{termbaseId}/imports/{importId}/logs".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))).replace("{importId}",encodeURIComponent(String(e.importId))),method:"GET",headers:n,query:{}},t);return new m(o)}))}downloadTermbaseImportLog(e,t){return le(this,void 0,void 0,(function*(){const n=yield this.downloadTermbaseImportLogRaw(e,t);return yield n.value()}))}getImportHistoryRaw(e,t){return le(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling getImportHistory().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getImportHistory().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getImportHistory().');const n={};null!=e.fields&&(n.fields=e.fields),null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/termbases/{termbaseId}/imports".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getImportHistory(e,t){return le(this,void 0,void 0,(function*(){const n=yield this.getImportHistoryRaw(e,t);return yield n.value()}))}importTermbaseRaw(e,t){return le(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling importTermbase().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling importTermbase().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling importTermbase().');if(null==e.file)throw new d("file",'Required parameter "file" was null or undefined when calling importTermbase().');const n={};null!=e.strictImport&&(n.strictImport=e.strictImport),null!=e.duplicateEntriesStrategy&&(n.duplicateEntriesStrategy=e.duplicateEntriesStrategy);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));let i,r=!1;r=h([{contentType:"multipart/form-data"}]),i=r?new FormData:new URLSearchParams,null!=e.file&&i.append("file",e.file);const a=yield this.request({path:"/termbases/{termbaseId}/imports".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))),method:"POST",headers:o,query:n,body:i},t);return new w(a)}))}importTermbase(e,t){return le(this,void 0,void 0,(function*(){const n=yield this.importTermbaseRaw(e,t);return yield n.value()}))}pollTermbaseImportRaw(e,t){return le(this,void 0,void 0,(function*(){if(null==e.termbaseId)throw new d("termbaseId",'Required parameter "termbaseId" was null or undefined when calling pollTermbaseImport().');if(null==e.importId)throw new d("importId",'Required parameter "importId" was null or undefined when calling pollTermbaseImport().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling pollTermbaseImport().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling pollTermbaseImport().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/termbases/{termbaseId}/imports/{importId}".replace("{termbaseId}",encodeURIComponent(String(e.termbaseId))).replace("{importId}",encodeURIComponent(String(e.importId))),method:"GET",headers:n,query:{}},t);return new w(o)}))}pollTermbaseImport(e,t){return le(this,void 0,void 0,(function*(){const n=yield this.pollTermbaseImportRaw(e,t);return yield n.value()}))}}var de=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class se extends a{convertTermbaseTemplateRaw(e,t){return de(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling convertTermbaseTemplate().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling convertTermbaseTemplate().');if(null==e.file)throw new d("file",'Required parameter "file" was null or undefined when calling convertTermbaseTemplate().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));let i,r=!1;r=h([{contentType:"multipart/form-data"}]),i=r?new FormData:new URLSearchParams,null!=e.file&&i.append("file",e.file);const a=yield this.request({path:"/termbase-templates/convert-xdt",method:"POST",headers:o,query:n,body:i},t);return new w(a)}))}convertTermbaseTemplate(e,t){return de(this,void 0,void 0,(function*(){const n=yield this.convertTermbaseTemplateRaw(e,t);return yield n.value()}))}createTermbaseTemplateRaw(e,t){return de(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling createTermbaseTemplate().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling createTermbaseTemplate().');const n={};null!=e.fields&&(n.fields=e.fields);const o={"Content-Type":"application/json"};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/termbase-templates",method:"POST",headers:o,query:n,body:e.termbaseTemplateCreateRequest},t);return new w(i)}))}createTermbaseTemplate(e,t){return de(this,void 0,void 0,(function*(){const n=yield this.createTermbaseTemplateRaw(e,t);return yield n.value()}))}deleteTermbaseTemplateRaw(e,t){return de(this,void 0,void 0,(function*(){if(null==e.termbaseTemplateId)throw new d("termbaseTemplateId",'Required parameter "termbaseTemplateId" was null or undefined when calling deleteTermbaseTemplate().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling deleteTermbaseTemplate().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling deleteTermbaseTemplate().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/termbase-templates/{termbaseTemplateId}".replace("{termbaseTemplateId}",encodeURIComponent(String(e.termbaseTemplateId))),method:"DELETE",headers:n,query:{}},t);return new f(o)}))}deleteTermbaseTemplate(e,t){return de(this,void 0,void 0,(function*(){yield this.deleteTermbaseTemplateRaw(e,t)}))}getTermbaseTemplateRaw(e,t){return de(this,void 0,void 0,(function*(){if(null==e.termbaseTemplateId)throw new d("termbaseTemplateId",'Required parameter "termbaseTemplateId" was null or undefined when calling getTermbaseTemplate().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getTermbaseTemplate().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getTermbaseTemplate().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/termbase-templates/{termbaseTemplateId}".replace("{termbaseTemplateId}",encodeURIComponent(String(e.termbaseTemplateId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getTermbaseTemplate(e,t){return de(this,void 0,void 0,(function*(){const n=yield this.getTermbaseTemplateRaw(e,t);return yield n.value()}))}listTermbaseTemplatesRaw(e,t){return de(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listTermbaseTemplates().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listTermbaseTemplates().');const n={};null!=e.location&&(n.location=e.location),null!=e.fields&&(n.fields=e.fields),null!=e.type&&(n.type=e.type),null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/termbase-templates",method:"GET",headers:o,query:n},t);return new w(i)}))}listTermbaseTemplates(e,t){return de(this,void 0,void 0,(function*(){const n=yield this.listTermbaseTemplatesRaw(e,t);return yield n.value()}))}updateTermbaseTemplateRaw(e,t){return de(this,void 0,void 0,(function*(){if(null==e.termbaseTemplateId)throw new d("termbaseTemplateId",'Required parameter "termbaseTemplateId" was null or undefined when calling updateTermbaseTemplate().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling updateTermbaseTemplate().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling updateTermbaseTemplate().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/termbase-templates/{termbaseTemplateId}".replace("{termbaseTemplateId}",encodeURIComponent(String(e.termbaseTemplateId))),method:"PUT",headers:n,query:{},body:e.termbaseTemplateUpdateRequest},t);return new f(o)}))}updateTermbaseTemplate(e,t){return de(this,void 0,void 0,(function*(){yield this.updateTermbaseTemplateRaw(e,t)}))}}var ce=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class pe extends a{getTranslationEngineRaw(e,t){return ce(this,void 0,void 0,(function*(){if(null==e.translationEngineId)throw new d("translationEngineId",'Required parameter "translationEngineId" was null or undefined when calling getTranslationEngine().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getTranslationEngine().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getTranslationEngine().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/translation-engines/{translationEngineId}".replace("{translationEngineId}",encodeURIComponent(String(e.translationEngineId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getTranslationEngine(e,t){return ce(this,void 0,void 0,(function*(){const n=yield this.getTranslationEngineRaw(e,t);return yield n.value()}))}listTranslationEnginesRaw(e,t){return ce(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listTranslationEngines().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listTranslationEngines().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/translation-engines",method:"GET",headers:o,query:n},t);return new w(i)}))}listTranslationEngines(e,t){return ce(this,void 0,void 0,(function*(){const n=yield this.listTranslationEnginesRaw(e,t);return yield n.value()}))}updateTranslationEngineRaw(e,t){return ce(this,void 0,void 0,(function*(){if(null==e.translationEngineId)throw new d("translationEngineId",'Required parameter "translationEngineId" was null or undefined when calling updateTranslationEngine().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling updateTranslationEngine().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling updateTranslationEngine().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/translation-engines/{translationEngineId}".replace("{translationEngineId}",encodeURIComponent(String(e.translationEngineId))),method:"PUT",headers:n,query:{},body:e.translationEngineUpdateRequest},t);return new f(o)}))}updateTranslationEngine(e,t){return ce(this,void 0,void 0,(function*(){yield this.updateTranslationEngineRaw(e,t)}))}}var he=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class we extends a{copyTranslationMemoryRaw(e,t){return he(this,void 0,void 0,(function*(){if(null==e.translationMemoryId)throw new d("translationMemoryId",'Required parameter "translationMemoryId" was null or undefined when calling copyTranslationMemory().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling copyTranslationMemory().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling copyTranslationMemory().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant)),null!=e.authorization&&(o.Authorization=String(e.authorization));const i=yield this.request({path:"/translation-memory/{translationMemoryId}/copy".replace("{translationMemoryId}",encodeURIComponent(String(e.translationMemoryId))),method:"POST",headers:o,query:n},t);return new w(i)}))}copyTranslationMemory(e,t){return he(this,void 0,void 0,(function*(){const n=yield this.copyTranslationMemoryRaw(e,t);return yield n.value()}))}createTranslationMemoryRaw(e,t){return he(this,void 0,void 0,(function*(){if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling createTranslationMemory().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling createTranslationMemory().');const n={};null!=e.fields&&(n.fields=e.fields);const o={"Content-Type":"application/json"};null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant)),null!=e.authorization&&(o.Authorization=String(e.authorization));const i=yield this.request({path:"/translation-memory",method:"POST",headers:o,query:n,body:e.translationMemoryCreateRequest},t);return new w(i)}))}createTranslationMemory(e,t){return he(this,void 0,void 0,(function*(){const n=yield this.createTranslationMemoryRaw(e,t);return yield n.value()}))}deleteTranslationMemoryRaw(e,t){return he(this,void 0,void 0,(function*(){if(null==e.translationMemoryId)throw new d("translationMemoryId",'Required parameter "translationMemoryId" was null or undefined when calling deleteTranslationMemory().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling deleteTranslationMemory().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling deleteTranslationMemory().');const n={};null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant)),null!=e.authorization&&(n.Authorization=String(e.authorization));const o=yield this.request({path:"/translation-memory/{translationMemoryId}".replace("{translationMemoryId}",encodeURIComponent(String(e.translationMemoryId))),method:"DELETE",headers:n,query:{}},t);return new f(o)}))}deleteTranslationMemory(e,t){return he(this,void 0,void 0,(function*(){yield this.deleteTranslationMemoryRaw(e,t)}))}getFieldTemplateRaw(e,t){return he(this,void 0,void 0,(function*(){if(null==e.fieldTemplateId)throw new d("fieldTemplateId",'Required parameter "fieldTemplateId" was null or undefined when calling getFieldTemplate().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getFieldTemplate().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getFieldTemplate().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/translation-memory/field-templates/{fieldTemplateId}".replace("{fieldTemplateId}",encodeURIComponent(String(e.fieldTemplateId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getFieldTemplate(e,t){return he(this,void 0,void 0,(function*(){const n=yield this.getFieldTemplateRaw(e,t);return yield n.value()}))}getTranslationMemoryRaw(e,t){return he(this,void 0,void 0,(function*(){if(null==e.translationMemoryId)throw new d("translationMemoryId",'Required parameter "translationMemoryId" was null or undefined when calling getTranslationMemory().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getTranslationMemory().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getTranslationMemory().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant)),null!=e.authorization&&(o.Authorization=String(e.authorization));const i=yield this.request({path:"/translation-memory/{translationMemoryId}".replace("{translationMemoryId}",encodeURIComponent(String(e.translationMemoryId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getTranslationMemory(e,t){return he(this,void 0,void 0,(function*(){const n=yield this.getTranslationMemoryRaw(e,t);return yield n.value()}))}listFieldTemplatesRaw(e,t){return he(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listFieldTemplates().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listFieldTemplates().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.sort&&(n.sort=e.sort),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/translation-memory/field-templates",method:"GET",headers:o,query:n},t);return new w(i)}))}listFieldTemplates(e,t){return he(this,void 0,void 0,(function*(){const n=yield this.listFieldTemplatesRaw(e,t);return yield n.value()}))}listTranslationMemoriesRaw(e,t){return he(this,void 0,void 0,(function*(){if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listTranslationMemories().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listTranslationMemories().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant)),null!=e.authorization&&(o.Authorization=String(e.authorization));const i=yield this.request({path:"/translation-memory",method:"GET",headers:o,query:n},t);return new w(i)}))}listTranslationMemories(e,t){return he(this,void 0,void 0,(function*(){const n=yield this.listTranslationMemoriesRaw(e,t);return yield n.value()}))}updateTranslationMemoryRaw(e,t){return he(this,void 0,void 0,(function*(){if(null==e.translationMemoryId)throw new d("translationMemoryId",'Required parameter "translationMemoryId" was null or undefined when calling updateTranslationMemory().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling updateTranslationMemory().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling updateTranslationMemory().');const n={"Content-Type":"application/json"};null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant)),null!=e.authorization&&(n.Authorization=String(e.authorization));const o=yield this.request({path:"/translation-memory/{translationMemoryId}".replace("{translationMemoryId}",encodeURIComponent(String(e.translationMemoryId))),method:"PUT",headers:n,query:{},body:e.translationMemoryUpdateRequest},t);return new f(o)}))}updateTranslationMemory(e,t){return he(this,void 0,void 0,(function*(){yield this.updateTranslationMemoryRaw(e,t)}))}}var fe=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))},me=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class ge extends a{getTMImportHistoryRaw(e,t){return me(this,void 0,void 0,(function*(){if(null==e.translationMemoryId)throw new d("translationMemoryId",'Required parameter "translationMemoryId" was null or undefined when calling getTMImportHistory().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getTMImportHistory().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getTMImportHistory().');const n={};null!=e.fields&&(n.fields=e.fields),null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/translation-memory/{translationMemoryId}/imports".replace("{translationMemoryId}",encodeURIComponent(String(e.translationMemoryId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getTMImportHistory(e,t){return me(this,void 0,void 0,(function*(){const n=yield this.getTMImportHistoryRaw(e,t);return yield n.value()}))}importTranslationMemoryRaw(e,t){return me(this,void 0,void 0,(function*(){if(null==e.translationMemoryId)throw new d("translationMemoryId",'Required parameter "translationMemoryId" was null or undefined when calling importTranslationMemory().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling importTranslationMemory().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling importTranslationMemory().');if(null==e.properties)throw new d("properties",'Required parameter "properties" was null or undefined when calling importTranslationMemory().');if(null==e.file)throw new d("file",'Required parameter "file" was null or undefined when calling importTranslationMemory().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));let o,i=!1;i=h([{contentType:"multipart/form-data"}]),o=i?new FormData:new URLSearchParams,null!=e.properties&&o.append("properties",new Blob([JSON.stringify(e.properties)],{type:"application/json"})),null!=e.file&&o.append("file",e.file);const r=yield this.request({path:"/translation-memory/{translationMemoryId}/imports".replace("{translationMemoryId}",encodeURIComponent(String(e.translationMemoryId))),method:"POST",headers:n,query:{},body:o},t);return new w(r)}))}importTranslationMemory(e,t){return me(this,void 0,void 0,(function*(){const n=yield this.importTranslationMemoryRaw(e,t);return yield n.value()}))}pollTMImportRaw(e,t){return me(this,void 0,void 0,(function*(){if(null==e.importId)throw new d("importId",'Required parameter "importId" was null or undefined when calling pollTMImport().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling pollTMImport().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling pollTMImport().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/translation-memory/imports/{importId}".replace("{importId}",encodeURIComponent(String(e.importId))),method:"GET",headers:n,query:{}},t);return new w(o)}))}pollTMImport(e,t){return me(this,void 0,void 0,(function*(){const n=yield this.pollTMImportRaw(e,t);return yield n.value()}))}}var Te=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class ye extends a{getMyUserRaw(e,t){return Te(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getMyUser().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getMyUser().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/users/me",method:"GET",headers:o,query:n},t);return new w(i)}))}getMyUser(e,t){return Te(this,void 0,void 0,(function*(){const n=yield this.getMyUserRaw(e,t);return yield n.value()}))}getUserRaw(e,t){return Te(this,void 0,void 0,(function*(){if(null==e.userId)throw new d("userId",'Required parameter "userId" was null or undefined when calling getUser().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getUser().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getUser().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/users/{userId}".replace("{userId}",encodeURIComponent(String(e.userId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getUser(e,t){return Te(this,void 0,void 0,(function*(){const n=yield this.getUserRaw(e,t);return yield n.value()}))}listUsersRaw(e,t){return Te(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listUsers().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listUsers().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/users",method:"GET",headers:o,query:n},t);return new w(i)}))}listUsers(e,t){return Te(this,void 0,void 0,(function*(){const n=yield this.listUsersRaw(e,t);return yield n.value()}))}}var Ce=function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function a(e){try{u(o.next(e))}catch(e){r(e)}}function l(e){try{u(o.throw(e))}catch(e){r(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,l)}u((o=o.apply(e,t||[])).next())}))};class ve extends a{getWorkflowRaw(e,t){return Ce(this,void 0,void 0,(function*(){if(null==e.workflowId)throw new d("workflowId",'Required parameter "workflowId" was null or undefined when calling getWorkflow().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling getWorkflow().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling getWorkflow().');const n={};null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/workflows/{workflowId}".replace("{workflowId}",encodeURIComponent(String(e.workflowId))),method:"GET",headers:o,query:n},t);return new w(i)}))}getWorkflow(e,t){return Ce(this,void 0,void 0,(function*(){const n=yield this.getWorkflowRaw(e,t);return yield n.value()}))}listWorkflowsRaw(e,t){return Ce(this,void 0,void 0,(function*(){if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling listWorkflows().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling listWorkflows().');const n={};null!=e.top&&(n.top=e.top),null!=e.skip&&(n.skip=e.skip),null!=e.location&&(n.location=e.location.join(s)),null!=e.locationStrategy&&(n.locationStrategy=e.locationStrategy),null!=e.sort&&(n.sort=e.sort),null!=e.fields&&(n.fields=e.fields);const o={};null!=e.authorization&&(o.Authorization=String(e.authorization)),null!=e.xLCTenant&&(o["X-LC-Tenant"]=String(e.xLCTenant));const i=yield this.request({path:"/workflows",method:"GET",headers:o,query:n},t);return new w(i)}))}listWorkflows(e,t){return Ce(this,void 0,void 0,(function*(){const n=yield this.listWorkflowsRaw(e,t);return yield n.value()}))}updateWorkflowRaw(e,t){return Ce(this,void 0,void 0,(function*(){if(null==e.workflowId)throw new d("workflowId",'Required parameter "workflowId" was null or undefined when calling updateWorkflow().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling updateWorkflow().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling updateWorkflow().');if(null==e.workflowUpdateRequest)throw new d("workflowUpdateRequest",'Required parameter "workflowUpdateRequest" was null or undefined when calling updateWorkflow().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/workflows/{workflowId}".replace("{workflowId}",encodeURIComponent(String(e.workflowId))),method:"PUT",headers:n,query:{},body:e.workflowUpdateRequest},t);return new f(o)}))}updateWorkflow(e,t){return Ce(this,void 0,void 0,(function*(){yield this.updateWorkflowRaw(e,t)}))}}const Ie={ENVIRONMENT:(()=>{const e=document.location.host.split("-")[0];switch(e){case"ci":case"qa":case"pte":case"uat":return e.toUpperCase();case"staging":return"STG";default:return"PROD"}})()||"CI",ENVIRONMENTS:{LOCAL:{apiUrl:"https://ci-lc-api.sdl.com/public-api/v1"},CI:{apiUrl:"https://ci-lc-api.sdl.com/public-api/v1"},QA:{apiUrl:"https://qa-lc-api.sdl.com/public-api/v1"},PTE:{apiUrl:"https://pte-lc-api.sdl.com/public-api/v1"},UAT:{apiUrl:"https://uat-lc-api.sdl.com/public-api/v1"},STG:{apiUrl:"https://staging-lc-api.sdl.com/public-api/v1"},PROD:{apiUrl:"https://lc-api.sdl.com/public-api/v1"}}};var xe;const Re=new i({basePath:Ie.ENVIRONMENTS[xe=xe||Ie.ENVIRONMENT].apiUrl}),Le={accountApi:()=>new T(Re),customFieldApi:()=>new C(Re),customerApi:()=>new I(Re),fileApi:()=>new R(Re),fileProcessingConfigurationApi:()=>new q(Re),folderApi:()=>new j(Re),groupApi:()=>new S(Re),languageApi:()=>new F(Re),languageProcessingApi:()=>new P(Re),pricingModelApi:()=>new U(Re),projectApi:()=>new G(Re),projectGroupApi:()=>new X(Re),projectTemplateApi:()=>new D(Re),publicKeysApi:()=>new B(Re),quoteApi:()=>new K(Re),sourceFileApi:()=>new W(Re),tqaProfileApi:()=>new Z(Re),targetFileApi:()=>new $(Re),taskApi:()=>new ee(Re),taskTypeApi:()=>new ne(Re),termbaseApi:()=>new ie(Re),termbaseExportApi:()=>new ae(Re),termbaseImportApi:()=>new ue(Re),termbaseTemplateApi:()=>new se(Re),translationEngineApi:()=>new pe(Re),translationMemoryApi:()=>new we(Re),translationMemoryExportApi:new class extends a{downloadExportedTranslationMemoryRaw(e,t){return fe(this,void 0,void 0,(function*(){if(null==e.exportId)throw new d("exportId",'Required parameter "exportId" was null or undefined when calling downloadExportedTranslationMemory().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling downloadExportedTranslationMemory().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling downloadExportedTranslationMemory().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/translation-memory/exports/{exportId}/download".replace("{exportId}",encodeURIComponent(String(e.exportId))),method:"GET",headers:n,query:{}},t);return new m(o)}))}downloadExportedTranslationMemory(e,t){return fe(this,void 0,void 0,(function*(){const n=yield this.downloadExportedTranslationMemoryRaw(e,t);return yield n.value()}))}exportTranslationMemoryRaw(e,t){return fe(this,void 0,void 0,(function*(){if(null==e.translationMemoryId)throw new d("translationMemoryId",'Required parameter "translationMemoryId" was null or undefined when calling exportTranslationMemory().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling exportTranslationMemory().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling exportTranslationMemory().');const n={"Content-Type":"application/json"};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/translation-memory/{translationMemoryId}/exports".replace("{translationMemoryId}",encodeURIComponent(String(e.translationMemoryId))),method:"POST",headers:n,query:{},body:e.translationMemoryExportRequest},t);return new w(o)}))}exportTranslationMemory(e,t){return fe(this,void 0,void 0,(function*(){const n=yield this.exportTranslationMemoryRaw(e,t);return yield n.value()}))}pollTranslationMemoryExportRaw(e,t){return fe(this,void 0,void 0,(function*(){if(null==e.exportId)throw new d("exportId",'Required parameter "exportId" was null or undefined when calling pollTranslationMemoryExport().');if(null==e.authorization)throw new d("authorization",'Required parameter "authorization" was null or undefined when calling pollTranslationMemoryExport().');if(null==e.xLCTenant)throw new d("xLCTenant",'Required parameter "xLCTenant" was null or undefined when calling pollTranslationMemoryExport().');const n={};null!=e.authorization&&(n.Authorization=String(e.authorization)),null!=e.xLCTenant&&(n["X-LC-Tenant"]=String(e.xLCTenant));const o=yield this.request({path:"/translation-memory/exports/{exportId}".replace("{exportId}",encodeURIComponent(String(e.exportId))),method:"GET",headers:n,query:{}},t);return new w(o)}))}pollTranslationMemoryExport(e,t){return fe(this,void 0,void 0,(function*(){const n=yield this.pollTranslationMemoryExportRaw(e,t);return yield n.value()}))}}(Re),translationMemoryImportApi:()=>new ge(Re),userApi:()=>new ye(Re),workflowApi:()=>new ve(Re)},qe={success:"success",fail:"fail",warning:"warning",info:"info"},ze={load:"load",route:"route"};let je;function be(e,t){const n=new CustomEvent(e,{detail:t});window.dispatchEvent(n)}function Se(){return je}const ke={apiClient:Le,onReady:function(e,t){be("register",{elements:e,callback:e=>{je=e,t()}})},getLocalData:function(e,t){return new Promise(((n,o)=>{be("getLocalData",Object.assign(Object.assign({context:e,selector:t},Se()),{resolve:n,reject:o}))}))},callApi:function(e){return new Promise(((t,n)=>{be("callApi",Object.assign(Object.assign(Object.assign({},e),Se()),{resolve:t,reject:n}))}))},callAddonApi:function(e){return new Promise(((t,n)=>{be("callAddonApi",Object.assign(Object.assign(Object.assign({},e),Se()),{resolve:t,reject:n}))}))},updateElement:function(e,t){return new Promise(((n,o)=>{be("updateElement",Object.assign(Object.assign({elementId:e,update:t},Se()),{resolve:n,reject:o}))}))},navigate:function(e,t){return new Promise(((n,o)=>{be("navigate",Object.assign(Object.assign({type:t||ze.route,path:e},Se()),{resolve:n,reject:o}))}))},showNotification:function(e,t,n){return new Promise(((o,i)=>{be("showNotification",Object.assign(Object.assign({context:t,type:n||qe.info,text:e},Se()),{resolve:o,reject:i}))}))},getRegistrationResult:Se,contexts:{projects:"projects",taskInbox:"task-inbox"},dataSelectors:{selectedProjects:"selectedProjects",selectedTasks:"selectedTasks",projectDashboard:"projectDashboard",projectFiles:"projectFiles",projectStages:"projectStages",projectTaskHistory:"projectTaskHistory"},notificationTypes:qe,navigationTypes:ze};return t})(),e.exports=t()}},t={};function n(o){var i=t[o];if(void 0!==i)return i.exports;var r=t[o]={exports:{}};return e[o].call(r.exports,r,r.exports,n),r.exports}(()=>{"use strict";var e=n(462),t=function(){return t=Object.assign||function(e){for(var t,n=1,o=arguments.length;n0&&i[i.length-1])||6!==l[0]&&2!==l[0])){a=0;continue}if(3===l[0]&&(!i||l[1]>i[0]&&l[1]".concat(t," content inserted on render.
This panel was added to column ").concat(!isNaN(t)&&t%2?"1":"2"," in Dashboard's main section."),n.appendChild(o)}},w=function(e){for(var t=document.getElementsByClassName("x-progress-text"),n=0;nTask description: ".concat(i||"no inputFiles"),o.appendChild(r)}else console.error("[UI Extensibility] [extension] No boxContentWrapper or taskPreview data")},x=0,R=function(e,t){d(e);var n=document.getElementById(e.domElementId);if(n){n.innerHTML="";var o=document.createElement("div");o.innerHTML="Custom panel ".concat(t," content inserted on render."),n.appendChild(o)}},L=[{elementId:"invoiceButton",icon:"x-fal fa-newspaper",text:"Create Invoice",location:"project-details-toolbar",type:"button",hidden:!0,actions:[{eventType:"onrender",eventHandler:l,payload:[]},{eventType:"onclick",eventHandler:function(t){d(t),e.trados.showNotification("Requesting LC UI Extensibility service to perform file download API call (LC Public API quote-report)",e.trados.contexts.projects,e.trados.notificationTypes.success),e.trados.callApi({url:"public-api/v1/projects/".concat(t.project.id,"/quote-report"),method:"GET",fileName:"invoice.pdf"}).then((function(t){e.trados.showNotification("Get project quote public API call completed successfully. Download will begin shortly.",e.trados.contexts.projects,e.trados.notificationTypes.success)})).catch((function(t){console.error("Get project quote call failed",t),e.trados.showNotification("Get project quote public API call failed.",e.trados.contexts.projects,e.trados.notificationTypes.fail)}))},payload:["project"]}]},{elementId:"invoiceButtonGeneratedApi",icon:"x-fal fa-newspaper",text:"Create Invoice (generated API)",location:"project-details-toolbar",type:"button",hidden:!0,actions:[{eventType:"onrender",eventHandler:l,payload:[]},{eventType:"onclick",eventHandler:function(n){return o(void 0,void 0,void 0,(function(){var r,a,l;return i(this,(function(u){switch(u.label){case 0:d(n),r=n.project.id,e.trados.showNotification("Requesting the export of the quote report (LC Public API ExportQuoteReport)",e.trados.contexts.projects),u.label=1;case 1:return u.trys.push([1,3,,4]),[4,e.trados.apiClient.quoteApi().exportQuoteReport(t({projectId:r},e.trados.getRegistrationResult()))];case 2:case 3:return u.sent(),[3,4];case 4:return a=0,l=setInterval((function(){return o(void 0,void 0,void 0,(function(){return i(this,(function(n){switch(n.label){case 0:return[4,e.trados.apiClient.quoteApi().pollQuoteReportExport(t({projectId:r},e.trados.getRegistrationResult())).then((function(n){a++,console.log("----pollResponse",n),"completed"===n.status?(clearInterval(l),l=null,e.trados.apiClient.quoteApi().downloadQuoteReport(t({projectId:r},e.trados.getRegistrationResult())).then((function(t){e.trados.showNotification("Download quote report completed successfully.
Preparing file. Download will begin shortly.",e.trados.contexts.projects,e.trados.notificationTypes.success),s("quoteReport.pdf",t)})).catch((function(t){console.log("Failed to download quote report.",t),e.trados.showNotification("Failed to download the quote report.",e.trados.contexts.projects,e.trados.notificationTypes.fail)}))):9===a&&(clearInterval(l),l=null,e.trados.showNotification("The export status was verified 10 times and it's not yet complete. We've given up checking.",e.trados.contexts.projects,e.trados.notificationTypes.fail))})).catch((function(t){console.log("Failed to poll quote report export status.",t),e.trados.showNotification("Failed to poll quote report export status.",e.trados.contexts.projects,e.trados.notificationTypes.fail)}))];case 1:return n.sent(),[2]}}))}))}),2e3),[2]}}))}))},payload:["project"]}]},{elementId:"openNewTabButtonLink",icon:"x-fal fa-external-link",text:"Open rws.com in New tab",location:"project-details-toolbar",type:"button",isLink:!0,href:"https://www.rws.com"},{elementId:"navigateButtonRoute",icon:"x-fal fa-clipboard",text:"View Project Template",location:"project-details-toolbar",type:"button",hidden:!0,actions:[{eventType:"onrender",eventHandler:function(t){d(t);var n=Boolean(t.project&&!t.project.id);e.trados.updateElement("navigateButtonRoute",{hidden:n})},payload:["project"]},{eventType:"onclick",eventHandler:function(t){var n;if(d(t),null===(n=t.project)||void 0===n?void 0:n.projectTemplate){var o=t.project.projectTemplate.id,i="resources/project-templates/".concat(o);e.trados.navigate(i,e.trados.navigationTypes.route)}},payload:["project"]}]},{elementId:"getLocalDataButton",icon:"x-fal fa-table",text:"Get Local Data",location:"project-details-toolbar",type:"button",actions:[{eventType:"onclick",eventHandler:function(t){d(t),t.project&&e.trados.getLocalData(e.trados.contexts.projects).then(c).catch((function(t){console.error("Failed to get local data",t),e.trados.showNotification("Failed to get local data.",e.trados.contexts.projects,e.trados.notificationTypes.fail)}))},payload:["selectedProjects","project","selectedFile","selectedFiles","selectedTaskHistoryTask","selectedStagesTasks","projectActiveTab"]}]},{elementId:"setProjectImportanceButton",icon:"x-fal fa-exclamation-circle",text:"Set Importance",location:"project-details-toolbar",type:"button",menu:[{text:"High",value:"high",icon:"x-fal fa-chevron-circle-up"},{text:"Medium",value:"medium",icon:"x-fal fa-dot-circle"},{text:"Low",value:"low",icon:"x-fal fa-chevron-circle-down"},{separator:!0},{text:"Unset importance",value:"none",icon:"x-fal fa-trash",disabled:!0}],actions:[{eventType:"onrender",eventHandler:function(t){d(t),r=t.project,t.project&&!a.find((function(e){return e.projectId===t.project.id}))&&(console.log("[UI Extensibility] [extension] Get project importance from add-on API"),e.trados.callAddonApi({url:"api/project-metadata/project-id/".concat(t.project.id),method:"GET"}).then((function(e){e&&e.responseData&&(e.responseData.errorCode?console.warn("Failed to get project metadata (importance).",e.responseData.errorCode,e.responseData.message):"string"!=typeof e.responseData&&u(e,!1))})).catch((function(t){console.error("Failed to get project metadata (importance)",t),e.trados.showNotification("Failed to get local data.",e.trados.contexts.projects,e.trados.notificationTypes.fail)})),a.push({projectId:t.project.id,pending:!0}))},payload:[]},{eventType:"onclick",eventHandler:function(t){if(d(t),t.project){var n=t.value;if(n){var o=a.find((function(e){return e.projectId===t.project.id&&!e.pending}));e.trados.updateElement("setProjectImportanceButton",{disabled:!0}),"none"===n&&o?e.trados.callAddonApi({url:"api/project-metadata/".concat(o.id),method:"DELETE"}).then((function(t){t.responseData&&r&&(p(t),e.trados.updateElement("setProjectImportanceButton",{icon:"x-fal fa-exclamation-circle",text:"Set Importance",disabled:!1,menuItems:[{index:4,disabled:!0}]}))})).catch((function(t){console.error("Failed to delete project metadata (importance)",t),e.trados.showNotification("Failed to delete project importance.",e.trados.contexts.projects,e.trados.notificationTypes.fail)})):e.trados.callAddonApi({url:"api/project-metadata".concat(o?"/"+o.id:""),method:o?"PUT":"POST",body:JSON.stringify({projectId:t.project.id,importance:n})}).then((function(e){u(e,!0)})).catch((function(t){console.error("Failed to set project metadata (importance)",t),e.trados.showNotification("Failed to set project importance.",e.trados.contexts.projects,e.trados.notificationTypes.fail)}))}}},payload:["project"]}]},{elementId:"extensionsHelper",text:"Extensions Helper",location:"project-details-tabpanel",type:"tab",actions:[{eventType:"onrender",eventHandler:function(t){d(t);var n=document.getElementById(t.domElementId);if(n){n.innerHTML="";var o=document.createElement("div");o.className="x-panel-header-title-light-framed",o.setAttribute("style","margin-bottom: 10px"),o.innerText="Available data",f=t.project,m=t.selectedProjects;var i={project:f,selectedProjects:m},r=document.createElement("a");r.setAttribute("style","margin-left: 10px; color: #434a65;"),r.innerHTML='',r.onclick=function(){SDL.common.utils.ClipboardCopy.copyToClipboard(JSON.stringify(i)),r.className.indexOf("fa-check")||(r.className="x-fa fa-check",setTimeout((function(){r.className="x-fa fa-copy"}),2e3))},o.appendChild(r),n.appendChild(o),n.style.position="relative";var a=document.createElement("style");a.innerHTML='\n.json-viewer {\n color: #000;\n margin: 0;\n padding-left: 20px;\n line-height: 20px;\n background-image: linear-gradient(\n 0deg,\n #fcfcfc 50%,\n #f3f3f3 50%,\n #f3f3f3 100%\n );\n background-size: 40px 40px;\n}\n.json-viewer ul {\n list-style-type: none;\n margin: 0;\n margin: 0 0 0 1px;\n border-left: 1px dotted #ccc;\n padding-left: 2em;\n}\n.json-viewer .hide {\n display: none;\n}\n.json-viewer .type-string {\n color: #0b7500;\n}\n.json-viewer .type-date {\n color: #cb7500;\n}\n.json-viewer .type-boolean {\n color: #1a01cc;\n font-weight: bold;\n}\n.json-viewer .type-number {\n color: #1a01cc;\n}\n.json-viewer .type-null,\n.json-viewer .type-undefined {\n color: #90a;\n}\n.json-viewer a.list-link {\n color: #000;\n text-decoration: none;\n position: relative;\n}\n.json-viewer a.list-link:before {\n color: #aaa;\n content: "▼";\n position: absolute;\n display: inline-block;\n width: 1em;\n left: -1em;\n}\n.json-viewer a.list-link.collapsed:before {\n content: "►";\n}\n.json-viewer a.list-link.empty:before {\n content: "";\n}\n.json-viewer .items-ph {\n color: #aaa;\n padding: 0 1em;\n}\n.json-viewer .items-ph:hover {\n text-decoration: underline;\n}\n.json-viewer .copy-links {\n display: none;\n}\n.json-viewer li:hover > a.list-link.collapsed ~ .copy-links.collapsed,\n.json-viewer li:hover > a.list-link:not(.collapsed) ~ .copy-links.expanded,\n.json-viewer li:hover > .copy-links.simple {\n display: inline;\n}',document.body.appendChild(a);var l=new(function(e){var t={}.toString,n=t.call(new Date);function o(){this._dom_container=e.createElement("pre"),this._dom_container.classList.add("json-viewer")}function i(t,n,o){var i=e.createElement("a");i.title=t,i.innerText="Copy path",i.setAttribute("style","margin-left: 10px"),i.onclick=function(){SDL.common.utils.ClipboardCopy.copyToClipboard(t)};var r=e.createElement("a"),a="object"==typeof n?JSON.stringify(n):n;r.title=a,r.innerText="Copy value",r.setAttribute("style","margin-left: 10px"),r.onclick=function(){SDL.common.utils.ClipboardCopy.copyToClipboard(a)};var l=e.createElement("span");return l.className="copy-links"+(o?" "+o:" simple"),l.appendChild(i),l.appendChild(r),l}function r(o,d,s,c,p,h){var w=t.call(d)===n,f=!w&&"object"==typeof d&&null!==d&&"toJSON"in d?d.toJSON():d;if("object"!=typeof f||null===f||w)o.appendChild(a(d,w));else{var m,g=s>=0&&p>=s,T=c>=0&&p>=c,y=Array.isArray(f),C=y?f:Object.keys(f);if(0===p){var v=l(C.length),I=u(y?"[":"{");C.length?(I.addEventListener("click",(function(){g||(I.classList.toggle("collapsed"),v.classList.toggle("hide"),o.querySelector("ul").classList.toggle("hide"))})),T&&(I.classList.add("collapsed"),v.classList.remove("hide"))):I.classList.add("empty"),I.appendChild(v),o.appendChild(I)}if(C.length&&!g){var x=C.length-1,R=e.createElement("ul");R.setAttribute("data-level",p.toString()),R.classList.add("type-"+(y?"array":"object")),C.forEach((function(o,w){var m=y?o:d[o],g=e.createElement("li");if("object"==typeof m){var T=-1,C=h+(h.length?".":"")+o;if(!m||m instanceof Date)g.appendChild(e.createTextNode(y?"":o+": ")),g.appendChild(a(m||null,!0));else{var v=Array.isArray(m),I=v?m.length:Object.keys(m).length;if(T=f.indexOf?f.indexOf(m):-1,C=h+(h.length?T>-1?"["+T+"]":"."+o:""+o),I){var L=("string"==typeof o?o+": ":"")+(v?"[":"{"),q=u(L),z=l(I);s>=0&&p+1>=s?g.appendChild(e.createTextNode(L)):(q.appendChild(z),g.appendChild(q)),r(g,m,s,c,p+1,C),g.appendChild(e.createTextNode(v?"]":"}"));var j=g.querySelector("ul"),b=function(){q.classList.toggle("collapsed"),z.classList.toggle("hide"),j.classList.toggle("hide")};q.addEventListener("click",b),c>=0&&p+1>=c&&b()}else g.appendChild(e.createTextNode(o+": "+(v?"[]":"{}")))}w1||0===e?"items":"item")}(t),n}function u(t){var n=e.createElement("a");return n.classList.add("list-link"),n.href="javascript:void(0)",n.innerHTML=t||"",n}return o.prototype.showJSON=function(e,t,n){var o="number"==typeof t?t:-1,i="number"==typeof n?n:-1;this._dom_container.innerHTML="",r(this._dom_container,e,o,i,0,"")},o.prototype.getContainer=function(){return this._dom_container},o}(document));n.appendChild(l.getContainer()),l.showJSON(i,null,1),console.log("[UI Extensibility] [extension] JSON data displayed");var u=document.createElement("div");u.className="x-panel-header-title-light-framed",u.setAttribute("style","margin: 40px 0 5px"),u.innerText="Dev Playground",n.appendChild(u);var s=document.createElement("form");s.autocomplete="off";var c=document.createElement("input");c.setAttribute("type","hidden"),c.setAttribute("autocomplete","false"),s.appendChild(c);var p=document.createElement("label");p.setAttribute("for","extension-notification-input"),p.setAttribute("autocomplete","false"),p.setAttribute("style","margin-bottom: 10px; font-weight: 700; display: inline-block; width: 120px;"),p.innerText="Notification text",s.appendChild(p);var h=document.createElement("input");h.setAttribute("id","extension-notification-input"),h.setAttribute("style","margin: 0 5px; border: 1px solid #9ba9b6; border-radius: 4px; padding: 5px 10px 4px; width: 475px;"),h.placeholder="Input notification text",s.appendChild(h),s.appendChild(document.createElement("br"));var w=document.createElement("label");w.setAttribute("for","extension-notification-select"),w.setAttribute("style","margin-bottom: 10px; font-weight: 700; display: inline-block; width: 120px;"),w.innerText="Notification type",s.appendChild(w);var g=document.createElement("select");g.setAttribute("id","extension-notification-select"),g.setAttribute("style","margin: 0 5px; border: 1px solid #9ba9b6; border-radius: 4px; padding: 5px 6px 4px; width: 475px;"),[["Information","info"],["Success","success"],["Warning","warning"],["Failure","fail"]].forEach((function(e){var t=document.createElement("option");t.textContent=e[0],t.value=e[1],g.appendChild(t)})),s.appendChild(g),s.appendChild(document.createElement("br"));var T=document.createElement("button");T.type="submit",T.innerText="Display notification",T.style="margin-top: 5px",T.className="x-btn x-btn-default-toolbar-medium",s.appendChild(T),s.addEventListener("submit",(function(t){var n=h.value,o=g.value;e.trados.showNotification(n,e.trados.contexts.projects,o),t.preventDefault()}));var y=document.createElement("div");y.style="white-space: pre; overflow: auto; margin-top: 10px; border: 1px solid #9ba9b6; border-radius: 4px; padding: 5px 10px 4px; width: 600px; height: 170px; ",s.appendChild(y);var C=function(){var e=h.value;y.innerText='trados.showNotification(\n "{text}",\n trados.contexts.projects,\n "{type}"\n});'.replace("{type}",g.value).replace("{text}",e)};h.addEventListener("input",(function(){C()})),g.addEventListener("change",(function(){C()})),C(),n.appendChild(s)}},payload:["project","selectedProjects"]}]},{elementId:"dashboardMain1Box",text:"Custom Panel 1",location:"project-details-dashboard-main",type:"panel",actions:[{eventType:"onrender",eventHandler:function(e){h(e,1)},payload:[]}]},{elementId:"dashboardMain2Box",text:"Custom Panel 2",location:"project-details-dashboard-main",type:"panel",actions:[{eventType:"onrender",eventHandler:function(e){h(e,2)},payload:[]}]},{elementId:"dashboardMain3Box",text:"Custom Panel 3",location:"project-details-dashboard-main",type:"panel",actions:[{eventType:"onrender",eventHandler:function(e){h(e,3)},payload:[]}]},{elementId:"dashboardSidebarBox",text:"Sidebar Box",location:"project-details-dashboard-sidebar",type:"sidebarBox",actions:[{eventType:"onrender",eventHandler:function(e){d(e);var t=document.getElementById(e.domElementId);if(t){t.innerHTML="";var n=document.createElement("div");n.innerHTML="Custom sidebar box content inserted on render.",t.appendChild(n)}},payload:[]}]},{elementId:"getLocalDashboardDataButton",icon:"x-fal fa-table",iconAlign:"right",text:"Get Local Data",location:"project-details-dashboard-toolbar",type:"button",actions:[{eventType:"onclick",eventHandler:function(t){d(t),e.trados.getLocalData(e.trados.contexts.projects,e.trados.dataSelectors.projectDashboard).then(c).catch((function(e){}))},payload:[]}]},{elementId:"increaseFontSizeButton",icon:"x-fal fa-font",iconAlign:"right",text:"Increase font size",location:"project-details-dashboard-toolbar",type:"button",actions:[{eventType:"onclick",eventHandler:function(e){d(e);for(var t=document.getElementsByTagName("table"),n=0;n")),n.appendChild(o)}},payload:["selectedTaskHistoryTask"]}]},{elementId:"highlightSelectedTaskButton",icon:"x-fal fa-folder-open",iconAlign:"right",text:"Highlight selected tasks",location:"project-details-task-history-toolbar",type:"button",actions:[{eventType:"onrender",eventHandler:function(t){d(t);var n=Boolean(t.selectedTaskHistoryTask);e.trados.updateElement("highlightSelectedTaskButton",{disabled:!n});for(var o=0,i=document.getElementsByClassName("x-grid-row");o times.");var o=e.task;console.log("[UI Extensibility] [extension] Task from event",o),t.appendChild(n),t.style.position="relative"}},payload:["task","taskActiveTab"]}]},{elementId:"taskSidebarBox",text:"Task Details Sidebar Box",location:"task-sidebar",type:"sidebarBox",actions:[{eventType:"onrender",eventHandler:function(e){d(e);var t=e.task;console.log("[UI Extensibility] [extension] Task data",t);var n=document.getElementById(e.domElementId);if(n){n.innerHTML="";var o=document.createElement("div");o.innerHTML="Custom sidebar box content inserted on render.
".concat(t?t.id:"No task id available."),n.appendChild(o)}},payload:[]}]},{elementId:"custom-btn-task-details-toolbar",icon:"x-fal fa-newspaper",text:"Custom task details toolbar button",location:"task-details-toolbar",type:"button",actions:[{eventType:"onrender",eventHandler:function(e){d(e);var t=document.getElementById(e.domElementId),n=e.task;t&&n&&console.log("RENDERED DETAILS TOOLBAR BUTTON")},payload:[]},{eventType:"onclick",eventHandler:function(e){d(e);var t=e.task;console.log("CLICKED DETAILS TOOLBAR BUTTON",t)},payload:["task","taskActiveTab"]}]},{elementId:"detailsMain1Box",text:"Custom Panel 1",location:"task-details-main",type:"panel",actions:[{eventType:"onrender",eventHandler:function(e){R(e,1)},payload:[]}]},{elementId:"detailsMain2Box",text:"Custom Panel 2",location:"task-details-main",type:"panel",actions:[{eventType:"onrender",eventHandler:function(e){R(e,2)},payload:[]}]},{elementId:"custom-btn-task-files-toolbar",icon:"x-fal fa-newspaper",text:"Custom button",location:"task-files-toolbar",type:"button",actions:[{eventType:"onrender",eventHandler:function(e){d(e);var t=document.getElementById(e.domElementId),n=e.task;t&&n&&console.log("RENDERED FILES TOOLBAR BUTTON")},payload:[]},{eventType:"onclick",eventHandler:function(e){d(e);var t=e.task,n=e.selectedFiles;console.log("CLICKED FILES TOOLBAR BUTTON",t,n)},payload:["task","taskActiveTab","selectedFiles"]}]}];e.trados.onReady(L,(function(){console.log("[UI Extensibility] [extension] Extension registered.")})),console.log("[UI Extensibility] [extension] Register request event published. External script loaded.")})()})(); \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/helpers.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/helpers.ts new file mode 100644 index 0000000..2974156 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/helpers.ts @@ -0,0 +1,84 @@ +import { ExtensibilityEventDetail } from "@sdl/extensibility-types/extensibility"; +import { + currentProject, + projectImportanceList +} from "./projectToolbarHandlers"; + +export const logExtensionData = (detail: ExtensibilityEventDetail) => { + console.log("[UI Extensibility] [extension] Custom event detail", detail); +}; + +// simple file download +// no longer used for initial "Create invoice" button; still used for "Get local data" button +export const download = (filename: string, data: string | Blob) => { + const element = document.createElement("a"); + if (typeof data === "string") { + element.href = "data:text/plain;charset=utf-8," + encodeURIComponent(data); + } else { + element.href = URL.createObjectURL(data); + } + element.setAttribute("download", filename); + element.style.display = "none"; + document.body.appendChild(element); + element.click(); + document.body.removeChild(element); +}; + +export const downloadData = (data: any) => { + const filename = "local-data.txt"; + console.log( + `[UI Extensibility] [extension] Download data as ${filename} file`, + data + ); + + setTimeout(() => { + download(filename, JSON.stringify(data)); + }, 1); +}; + +export const updateProjectImportanceList = (data?: any) => { + const currentProjectImportanceItem = projectImportanceList.find( + i => i.projectId === currentProject!.id + ); + if (currentProjectImportanceItem) { + if (data.responseData.importance) { + // update existing entry + currentProjectImportanceItem.importance = + data.responseData.importance.toLowerCase(); + if (currentProjectImportanceItem.pending) { + currentProjectImportanceItem.pending = false; + currentProjectImportanceItem.id = data.responseData.id; + } + } else { + // delete entry + projectImportanceList.splice( + projectImportanceList.indexOf(currentProjectImportanceItem), + 1 + ); + } + } else { + // add entry + projectImportanceList.push({ + id: data.responseData.id, + projectId: data.responseData.projectId, + importance: data.responseData.importance, + pending: false + }); + } +}; + +// a similar function exists in public-packages/extensibility/src/api/apiClient.ts but is intentionally not exported +// this helper function in the mock extension is used when calling add-on/app backend api directly, see api/project-metadata in projects-app/src/mocks/ui-extensibility/extensions/handlers/projectToolbarHandlers.ts +export const getEnvironmentUrlPartByHost = () => { + const hostEnv = document.location.host.split("-")[0]; + switch (hostEnv) { + case "ci": + case "qa": + case "pte": + case "uat": + case "staging": + return `${hostEnv}-`; + default: + return ""; // prod + } +}; \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectDashboardHandlers.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectDashboardHandlers.ts new file mode 100644 index 0000000..0903fce --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectDashboardHandlers.ts @@ -0,0 +1,74 @@ +import { trados } from "@sdl/extensibility"; // doesn't work until new extensibility public package published +//import { trados } from "../../../../../../../public-packages/extensibility/src/index"; // works +import { ExtensibilityEventDetail } from "@sdl/extensibility-types/extensibility"; +import { downloadData, logExtensionData } from "./helpers"; + +export const dashboardSidebarBoxRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + // extensionHelper is the elementId of the tab (in activated-extension.json config) + const boxContentWrapper = document.getElementById(detail.domElementId); + if (boxContentWrapper) { + boxContentWrapper.innerHTML = ""; + // create div + const div = document.createElement("div"); + div.innerHTML = `Custom sidebar box content inserted on render.`; + boxContentWrapper.appendChild(div); + } +}; + +export const getLocalDashboardDataButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + trados + .getLocalData( + trados.contexts.projects, + trados.dataSelectors.projectDashboard + ) + .then(downloadData) + .catch(_reason => { + debugger; // todo + }); +}; + +export const increaseFontSizeButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const panels = document.getElementsByTagName("table"); + for (let i = 0; i < panels.length; i++) { + panels[i].style.fontSize = "20px"; + } +}; + +export const backToDefaultFontSizeButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const panels = document.getElementsByTagName("table"); + for (let i = 0; i < panels.length; i++) { + panels[i].style.fontSize = "initial"; + } +}; + +export const dashboardMainPanelRendered = ( + detail: ExtensibilityEventDetail, + panelIndex: number +) => { + logExtensionData(detail); + + // extensionHelper is the elementId of the tab (in activated-extension.json config) + const panelContentWrapper = document.getElementById(detail.domElementId); + if (panelContentWrapper) { + // reset content for rerenders + panelContentWrapper.innerHTML = ""; // todo: fix multiple renders + // create div + const div = document.createElement("div"); + div.innerHTML = `Custom panel ${panelIndex} content inserted on render.
This panel was added to column ${ + !isNaN(panelIndex) && panelIndex % 2 ? "1" : "2" + } in Dashboard's main section.`; + panelContentWrapper.appendChild(div); + } +}; diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectFilesHandlers.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectFilesHandlers.ts new file mode 100644 index 0000000..836328a --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectFilesHandlers.ts @@ -0,0 +1,41 @@ +import { trados } from "@sdl/extensibility"; // doesn't work until new extensibility public package published +//import { trados } from "../../../../../../../public-packages/extensibility/src/index"; // works +import { ExtensibilityEventDetail } from "@sdl/extensibility-types/extensibility"; +import { downloadData, logExtensionData } from "./helpers"; + +const setProgressRowDisplayStyle = (displayStyle: string) => { + const progressTexts = document.getElementsByClassName("x-progress-text"); + for (let i = 0; i < progressTexts.length; i++) { + if (progressTexts[i].textContent === "0%") { + const expiredRow = progressTexts[i].closest("tr"); + if (expiredRow) { + //@ts-ignore + expiredRow.style.display = displayStyle; + } + } + } +}; + +export const getLocalFilesDataButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + trados + .getLocalData(trados.contexts.projects, trados.dataSelectors.projectFiles) + .then(downloadData) + .catch(_reason => { + debugger; // todo + }); +}; + +export const hideNotTranslatedFilesButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + setProgressRowDisplayStyle("none"); +}; + +export const showAllFilesButtonClicked = (detail: ExtensibilityEventDetail) => { + logExtensionData(detail); + setProgressRowDisplayStyle("table-row"); +}; diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectStagesHadlers.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectStagesHadlers.ts new file mode 100644 index 0000000..330a8f2 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectStagesHadlers.ts @@ -0,0 +1,42 @@ +import { trados } from "@sdl/extensibility"; // doesn't work until new extensibility public package published +//import { trados } from "../../../../../../../public-packages/extensibility/src/index"; // works +import { ExtensibilityEventDetail } from "@sdl/extensibility-types/extensibility"; +import { downloadData, logExtensionData } from "./helpers"; + +export const getLocalStagesDataButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + trados + .getLocalData(trados.contexts.projects, trados.dataSelectors.projectStages) + .then(downloadData) + .catch(_reason => { + debugger; // todo + }); +}; + +export const highlightPopulatedStagesButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const panels = document.getElementsByClassName("items-count"); + for (let i = 0; i < panels.length; i++) { + if (panels[i].textContent !== "0") { + //@ts-ignore + panels[i].style.background = "green"; + } + } +}; + +export const removeStagesHighlightsButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const panels = document.getElementsByClassName("items-count"); + for (let i = 0; i < panels.length; i++) { + if (panels[i].textContent !== "0") { + //@ts-ignore + panels[i].style.background = "#9ba9b6"; + } + } +}; diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectTabbarHandlers.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectTabbarHandlers.ts new file mode 100644 index 0000000..ab05060 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectTabbarHandlers.ts @@ -0,0 +1,618 @@ +import { trados } from "@sdl/extensibility"; // doesn't work until new extensibility public package published +//import { trados } from "../../../../../../../public-packages/extensibility/src/index"; // works +import { ExtensibilityEventDetail } from "@sdl/extensibility-types/extensibility"; +import { Project } from "@sdl/extensibility/lib/lc-public-api/models"; +import { logExtensionData } from "./helpers"; + +let project: Project | undefined = undefined; +let selectedProjects: Project[] | undefined = undefined; + +export const extensionsHelperTabRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + + // extensionHelper is the elementId of the tab (in activated-extension.json config) + const tabContentWrapper = document.getElementById(detail.domElementId); + if (tabContentWrapper) { + // reset content for rerenders + tabContentWrapper.innerHTML = ""; + + // create heading + const heading = document.createElement("div"); + heading.className = "x-panel-header-title-light-framed"; + heading.setAttribute("style", "margin-bottom: 10px"); + heading.innerText = "Available data"; + + //project and selectedProjects selectors set as event payload + project = detail.project; + selectedProjects = detail.selectedProjects; + // create all data object + const data = { + project: project, + selectedProjects: selectedProjects + }; + + // create copy to clipboard button + const copyBtn = document.createElement("a"); + + //copyBtn.className = "x-btn x-btn-default-toolbar-medium"; + copyBtn.setAttribute("style", "margin-left: 10px; color: #434a65;"); + copyBtn.innerHTML = ``; + copyBtn.onclick = () => { + // @ts-ignore + SDL.common.utils.ClipboardCopy.copyToClipboard(JSON.stringify(data)); + if (!copyBtn.className.indexOf("fa-check")) { + copyBtn.className = "x-fa fa-check"; + setTimeout(() => { + copyBtn.className = "x-fa fa-copy"; + }, 2000); + } + }; + + // add copy button to heading and heading to tab + heading.appendChild(copyBtn); + tabContentWrapper.appendChild(heading); + tabContentWrapper.style.position = "relative"; + + // json-viewer css + const jsonViewerStyle = document.createElement("style"); + //jsonViewerStyle.setAttribute("data-loaded-by-extension-id", key || ""); todo: may be helpful for debugging, but extension key is not exposed. should it be? + jsonViewerStyle.innerHTML = getJsonViewerCss(); + document.body.appendChild(jsonViewerStyle); + + // json-viewer js + // TODO: investigate importing JSONViewer to prevent including large code + // JSONViewer - by Roman Makudera 2016 (c) MIT licence. + var JSONViewer = (function (document) { + var Object_prototype_toString = {}.toString; + var DatePrototypeAsString = Object_prototype_toString.call(new Date()); + + /** @constructor */ + function JSONViewer() { + // @ts-ignore + this._dom_container = document.createElement("pre"); + // @ts-ignore + this._dom_container.classList.add("json-viewer"); + } + + /** + * Visualise JSON object. + * + * @param {Object|Array} json Input value + * @param {Number} [inputMaxLvl] Process only to max level, where 0..n, -1 unlimited + * @param {Number} [inputColAt] Collapse at level, where 0..n, -1 unlimited + */ + JSONViewer.prototype.showJSON = function ( + jsonValue: any, + inputMaxLvl: number, + inputColAt: number + ) { + // Process only to maxLvl, where 0..n, -1 unlimited + var maxLvl = typeof inputMaxLvl === "number" ? inputMaxLvl : -1; // max level + // Collapse at level colAt, where 0..n, -1 unlimited + var colAt = typeof inputColAt === "number" ? inputColAt : -1; // collapse at + this._dom_container.innerHTML = ""; + walkJSONTree(this._dom_container, jsonValue, maxLvl, colAt, 0, ""); + }; + /** + * Get container with pre object - this container is used for visualise JSON data. + * + * @return {Element} + */ + JSONViewer.prototype.getContainer = function () { + return this._dom_container; + }; + + function createCopyLinks( + path: string, + value: any, + extraContainerCssClass?: string + ) { + const copyPathBtn = document.createElement("a"); + copyPathBtn.title = path; + copyPathBtn.innerText = "Copy path"; + copyPathBtn.setAttribute("style", "margin-left: 10px"); + copyPathBtn.onclick = () => { + //debugger; + // @ts-ignore + SDL.common.utils.ClipboardCopy.copyToClipboard(path); + }; + const copyValueBtn = document.createElement("a"); + const stringValue = + typeof value === "object" ? JSON.stringify(value) : value; + copyValueBtn.title = stringValue; + copyValueBtn.innerText = "Copy value"; + copyValueBtn.setAttribute("style", "margin-left: 10px"); + copyValueBtn.onclick = () => { + //debugger; + // @ts-ignore + SDL.common.utils.ClipboardCopy.copyToClipboard(stringValue); + }; + const spanEl = document.createElement("span"); + spanEl.className = + "copy-links" + + (extraContainerCssClass ? " " + extraContainerCssClass : " simple"); + spanEl.appendChild(copyPathBtn); + spanEl.appendChild(copyValueBtn); + return spanEl; + } + + /** + * Recursive walk for input value. + * + * @param {Element} outputParent is the Element that will contain the new DOM + * @param {Object|Array} value Input value + * @param {Number} maxLvl Process only to max level, where 0..n, -1 unlimited + * @param {Number} colAt Collapse at level, where 0..n, -1 unlimited + * @param {Number} lvl Current level + * @param {String} path Current object path + */ + function walkJSONTree( + outputParent: any, + value: any, + maxLvl: number, + colAt: number, + lvl: number, + path: string + ) { + var isDate = + Object_prototype_toString.call(value) === DatePrototypeAsString; + var realValue = + !isDate && + typeof value === "object" && + value !== null && + "toJSON" in value + ? value.toJSON() + : value; + if (typeof realValue === "object" && realValue !== null && !isDate) { + var isMaxLvl = maxLvl >= 0 && lvl >= maxLvl; + var isCollapse = colAt >= 0 && lvl >= colAt; + var isArray = Array.isArray(realValue); + var items = isArray ? realValue : Object.keys(realValue); + if (lvl === 0) { + // root level + var rootCount = _createItemsCount(items.length); + // hide/show + var rootLink = _createLink(isArray ? "[" : "{"); + if (items.length) { + rootLink.addEventListener("click", function () { + if (isMaxLvl) return; + rootLink.classList.toggle("collapsed"); + rootCount.classList.toggle("hide"); + // main list + outputParent.querySelector("ul").classList.toggle("hide"); + }); + if (isCollapse) { + rootLink.classList.add("collapsed"); + rootCount.classList.remove("hide"); + } + } else { + rootLink.classList.add("empty"); + } + rootLink.appendChild(rootCount); + outputParent.appendChild(rootLink); // output the rootLink + } + if (items.length && !isMaxLvl) { + var len = items.length - 1; + var ulList = document.createElement("ul"); + ulList.setAttribute("data-level", lvl.toString()); + ulList.classList.add("type-" + (isArray ? "array" : "object")); + items.forEach(function (key: any, ind: number) { + var item = isArray ? key : value[key]; + var li = document.createElement("li"); + if (typeof item === "object") { + let index = -1; + let pathToCopy = path + (path.length ? "." : "") + key; + + // null && date + if (!item || item instanceof Date) { + li.appendChild( + document.createTextNode(isArray ? "" : key + ": ") + ); + li.appendChild(createSimpleViewOf(item ? item : null, true)); + } + // array & object + else { + var itemIsArray = Array.isArray(item); + var itemLen = itemIsArray + ? item.length + : Object.keys(item).length; + + index = realValue.indexOf ? realValue.indexOf(item) : -1; + pathToCopy = + path + + (path.length + ? index > -1 + ? "[" + index + "]" + : "." + key + : "" + key); + + // empty + if (!itemLen) { + li.appendChild( + document.createTextNode( + key + ": " + (itemIsArray ? "[]" : "{}") + ) + ); + } else { + // 1+ items + var itemTitle = + (typeof key === "string" ? key + ": " : "") + + (itemIsArray ? "[" : "{"); + var itemLink = _createLink(itemTitle); + var itemsCount = _createItemsCount(itemLen); + // maxLvl - only text, no link + if (maxLvl >= 0 && lvl + 1 >= maxLvl) { + li.appendChild(document.createTextNode(itemTitle)); + } else { + itemLink.appendChild(itemsCount); + li.appendChild(itemLink); + } + //debugger; + walkJSONTree(li, item, maxLvl, colAt, lvl + 1, pathToCopy); + li.appendChild( + document.createTextNode(itemIsArray ? "]" : "}") + ); + var list = li.querySelector("ul"); + var itemLinkCb = function () { + itemLink.classList.toggle("collapsed"); + itemsCount.classList.toggle("hide"); + list!.classList.toggle("hide"); + }; + // hide/show + itemLink.addEventListener("click", itemLinkCb); + // collapse lower level + if (colAt >= 0 && lvl + 1 >= colAt) { + itemLinkCb(); + } + } + } + // add comma to the end + if (ind < len) { + li.appendChild(document.createTextNode(",")); + } + + if (key === "lastModifiedAt") { + //debugger; + } + if ( + Object_prototype_toString.call(item) === DatePrototypeAsString + ) { + li.appendChild( + createCopyLinks(path + (path.length ? "." : "") + key, item) + ); + } else { + li.insertBefore( + createCopyLinks(pathToCopy, item, "expanded"), + li.children[1] + ); + li.appendChild( + createCopyLinks(pathToCopy, item, "collapsed") + ); + } + } + // simple values + else { + // object keys with key: + if (!isArray) { + li.appendChild(document.createTextNode(key + ": ")); + } + // recursive + walkJSONTree( + li, + item, + maxLvl, + colAt, + lvl + 1, + path + (path.length ? "." : "") + key + ); + // add comma to the end + if (ind < len) { + li.appendChild(document.createTextNode(",")); + } + li.appendChild( + createCopyLinks(path + (path.length ? "." : "") + key, item) + ); + } + + ulList.appendChild(li); + // @ts-ignore + }, this); + outputParent.appendChild(ulList); // output ulList + } else if (items.length && isMaxLvl) { + var itemsCount = _createItemsCount(items.length); + itemsCount.classList.remove("hide"); + outputParent.appendChild(itemsCount); // output itemsCount + } + if (lvl === 0) { + // empty root + if (!items.length) { + var itemsCount = _createItemsCount(0); + itemsCount.classList.remove("hide"); + outputParent.appendChild(itemsCount); // output itemsCount + } + // root cover + outputParent.appendChild( + document.createTextNode(isArray ? "]" : "}") + ); + // collapse + if (isCollapse) { + outputParent.querySelector("ul").classList.add("hide"); + } + } + } else { + // simple values + outputParent.appendChild(createSimpleViewOf(value, isDate)); + } + } + + /** + * Create simple value (no object|array). + * + * @param {Number|String|null|undefined|Date} value Input value + * @return {Element} + */ + function createSimpleViewOf(value: any, isDate: boolean) { + var spanEl = document.createElement("span"); + var type: any = typeof value; + var asText = "" + value; + if (type === "string") { + asText = '"' + value + '"'; + } else if (value === null) { + type = "null"; + //asText = "null"; + } else if (isDate) { + type = "date"; + asText = value.toLocaleString(); + } + spanEl.className = "type-" + type; + spanEl.textContent = asText; + return spanEl; + } + + /** + * Create items count element. + * + * @param {Number} count Items count + * @return {Element} + */ + function _createItemsCount(count: number) { + var itemsCount = document.createElement("span"); + itemsCount.className = "items-ph hide"; + itemsCount.innerHTML = _getItemsTitle(count); + return itemsCount; + } + + /** + * Create clickable link. + * + * @param {String} title Link title + * @return {Element} + */ + function _createLink(title: string) { + var linkEl = document.createElement("a"); + linkEl.classList.add("list-link"); + linkEl.href = "javascript:void(0)"; + linkEl.innerHTML = title || ""; + return linkEl; + } + + /** + * Get correct item|s title for count. + * + * @param {Number} count Items count + * @return {String} + */ + function _getItemsTitle(count: number) { + var itemsTxt = count > 1 || count === 0 ? "items" : "item"; + return count + " " + itemsTxt; + } + + return JSONViewer; + })(document); + + // @ts-ignore + var jsonViewer = new JSONViewer(); + tabContentWrapper.appendChild(jsonViewer.getContainer()); + jsonViewer.showJSON(data, null, 1); + console.log("[UI Extensibility] [extension] JSON data displayed"); + + // add playground + const playgroundHeading = document.createElement("div"); + playgroundHeading.className = "x-panel-header-title-light-framed"; + playgroundHeading.setAttribute("style", "margin: 40px 0 5px"); + playgroundHeading.innerText = "Dev Playground"; + tabContentWrapper.appendChild(playgroundHeading); + + const playgroundForm = document.createElement("form"); + playgroundForm.autocomplete = "off"; + const hidden = document.createElement("input"); + hidden.setAttribute("type", "hidden"); + hidden.setAttribute("autocomplete", "false"); + playgroundForm.appendChild(hidden); + + const label = document.createElement("label"); + label.setAttribute("for", "extension-notification-input"); + label.setAttribute("autocomplete", "false"); + label.setAttribute( + "style", + "margin-bottom: 10px; font-weight: 700; display: inline-block; width: 120px;" + ); + label.innerText = "Notification text"; + playgroundForm.appendChild(label); + + const input = document.createElement("input"); + input.setAttribute("id", "extension-notification-input"); + input.setAttribute( + "style", + "margin: 0 5px; border: 1px solid #9ba9b6; border-radius: 4px; padding: 5px 10px 4px; width: 475px;" + ); + input.placeholder = "Input notification text"; + playgroundForm.appendChild(input); + + playgroundForm.appendChild(document.createElement("br")); + + const typeLabel = document.createElement("label"); + typeLabel.setAttribute("for", "extension-notification-select"); + typeLabel.setAttribute( + "style", + "margin-bottom: 10px; font-weight: 700; display: inline-block; width: 120px;" + ); + typeLabel.innerText = "Notification type"; + playgroundForm.appendChild(typeLabel); + + const select = document.createElement("select"); + select.setAttribute("id", "extension-notification-select"); + select.setAttribute( + "style", + "margin: 0 5px; border: 1px solid #9ba9b6; border-radius: 4px; padding: 5px 6px 4px; width: 475px;" + ); + [ + ["Information", "info"], + ["Success", "success"], + ["Warning", "warning"], + ["Failure", "fail"] + ].forEach(type => { + const option = document.createElement("option"); + option.textContent = type[0]; + option.value = type[1]; + select.appendChild(option); + }); + playgroundForm.appendChild(select); + + playgroundForm.appendChild(document.createElement("br")); + + const button = document.createElement("button"); + button.type = "submit"; + button.innerText = "Display notification"; + // @ts-ignore + button.style = "margin-top: 5px"; + button.className = "x-btn x-btn-default-toolbar-medium"; + playgroundForm.appendChild(button); + + playgroundForm.addEventListener("submit", function (submitEvent) { + // sample input where eval was needed: "This is the " + projectDetails.name + " project." + //const text = input.value.indexOf('"') > -1 || input.value.indexOf("`") > -1 + // ? eval(input.value.replace(/projectDetails/g, "project")) + // : input.value; + const text = input.value; + const type = select.value as "info" | "success" | "warning" | "fail"; + trados.showNotification(text, trados.contexts.projects, type); + + submitEvent.preventDefault(); + }); + + const scriptText = `trados.showNotification( + "{text}", + trados.contexts.projects, + "{type}" +});`; + const code = document.createElement("div"); + // @ts-ignore + code.style = + "white-space: pre; overflow: auto; margin-top: 10px; border: 1px solid #9ba9b6; border-radius: 4px; padding: 5px 10px 4px; width: 600px; height: 170px; "; + playgroundForm.appendChild(code); + const updateCode = () => { + const text = input.value; + code.innerText = scriptText + .replace("{type}", select.value) + .replace("{text}", text); + /*.replace( + "{text}", + (text.indexOf('"') > -1 || text.indexOf("`") > -1 + ? text + : `"${text}"`) || '""' + ) + */ + }; + + input.addEventListener("input", () => { + updateCode(); + }); + select.addEventListener("change", () => { + updateCode(); + }); + updateCode(); + + tabContentWrapper.appendChild(playgroundForm); + } +}; + +const getJsonViewerCss = () => { + return ` +.json-viewer { + color: #000; + margin: 0; + padding-left: 20px; + line-height: 20px; + background-image: linear-gradient( + 0deg, + #fcfcfc 50%, + #f3f3f3 50%, + #f3f3f3 100% + ); + background-size: 40px 40px; +} +.json-viewer ul { + list-style-type: none; + margin: 0; + margin: 0 0 0 1px; + border-left: 1px dotted #ccc; + padding-left: 2em; +} +.json-viewer .hide { + display: none; +} +.json-viewer .type-string { + color: #0b7500; +} +.json-viewer .type-date { + color: #cb7500; +} +.json-viewer .type-boolean { + color: #1a01cc; + font-weight: bold; +} +.json-viewer .type-number { + color: #1a01cc; +} +.json-viewer .type-null, +.json-viewer .type-undefined { + color: #90a; +} +.json-viewer a.list-link { + color: #000; + text-decoration: none; + position: relative; +} +.json-viewer a.list-link:before { + color: #aaa; + content: "▼"; + position: absolute; + display: inline-block; + width: 1em; + left: -1em; +} +.json-viewer a.list-link.collapsed:before { + content: "►"; +} +.json-viewer a.list-link.empty:before { + content: ""; +} +.json-viewer .items-ph { + color: #aaa; + padding: 0 1em; +} +.json-viewer .items-ph:hover { + text-decoration: underline; +} +.json-viewer .copy-links { + display: none; +} +.json-viewer li:hover > a.list-link.collapsed ~ .copy-links.collapsed, +.json-viewer li:hover > a.list-link:not(.collapsed) ~ .copy-links.expanded, +.json-viewer li:hover > .copy-links.simple { + display: inline; +}`; +}; diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectTaskHistoryHandlers.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectTaskHistoryHandlers.ts new file mode 100644 index 0000000..a0d83ca --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectTaskHistoryHandlers.ts @@ -0,0 +1,96 @@ +import { trados } from "@sdl/extensibility"; // doesn't work until new extensibility public package published +//import { trados } from "../../../../../../../public-packages/extensibility/src/index"; // works +import { ExtensibilityEventDetail } from "@sdl/extensibility-types/extensibility"; +import { downloadData, logExtensionData } from "./helpers"; + +const setExpiredRowDisplayStyle = (displayStyle: string) => { + const statusText = document.getElementsByClassName("status file-failed"); + for (let i = 0; i < statusText.length; i++) { + const expiredRow = statusText[i].closest("tr"); + if (expiredRow) { + //@ts-ignore + expiredRow.style.display = displayStyle; + } + } +}; + +export const getLocalTaskHistoryDataButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + trados + .getLocalData( + trados.contexts.projects, + trados.dataSelectors.projectTaskHistory + ) + .then(downloadData) + .catch(_reason => { + debugger; // todo + }); +}; + +export const hideFailedTasksButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + setExpiredRowDisplayStyle("none"); +}; + +export const showAllTasksButtonClicked = (detail: ExtensibilityEventDetail) => { + logExtensionData(detail); + setExpiredRowDisplayStyle("table-row"); +}; + +export const highlightSelectedTaskButtonRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + //const isPreviewPanelOpen = detail.projectTaskHistory!.preview.show; + // todo: check if closing preview makes selectedTaskHistoryTask null + const isPreviewPanelOpen = Boolean(detail.selectedTaskHistoryTask); + + // update button availability + trados.updateElement("highlightSelectedTaskButton", { + disabled: !isPreviewPanelOpen + }); + const selectedTaskRows = document.getElementsByClassName("x-grid-row"); + //@ts-ignore + for (let selectedTaskRow of selectedTaskRows) { + //@ts-ignore + if (selectedTaskRow && selectedTaskRow.style) + //@ts-ignore + selectedTaskRow.style.backgroundColor = "initial"; + } +}; + +export const highlightSelectedTaskButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const selectedTaskRows = document.getElementsByClassName( + " x-grid-row x-grid-row-active" + ); + if (selectedTaskRows) { + //@ts-ignore + selectedTaskRows[0].style.backgroundColor = "#1d9570"; + } +}; + +// task history sidebar box +export const taskHistorySidebarBoxRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + // extensionHelper is the elementId of the tab (in activated-extension.json config) + const boxContentWrapper = document.getElementById(detail.domElementId); + if (boxContentWrapper) { + boxContentWrapper.innerHTML = ""; + // create div + const div = document.createElement("div"); + div.innerHTML = `Custom sidebar box content inserted on render.`; + if (detail.selectedTaskHistoryTask?.status) { + div.innerHTML += `
Status: ${detail.selectedTaskHistoryTask.status}`; + } + boxContentWrapper.appendChild(div); + } +}; diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectToolbarHandlers.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectToolbarHandlers.ts new file mode 100644 index 0000000..d7a7324 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectToolbarHandlers.ts @@ -0,0 +1,833 @@ +import { trados } from "@sdl/extensibility"; // doesn't work until new extensibility public package published +//import { trados } from "../../../../../../../public-packages/extensibility/src/index"; // works +import type { + Project, + TargetFile +} from "@sdl/extensibility/lib/lc-public-api/models"; +//import type { +// Project, +// TargetFile +//} from "../../../../../../../public-packages/extensibility/dist/lib/lc-public-api/models/index"; +import { ExtensibilityEventDetail } from "@sdl/extensibility-types/extensibility"; +import { ProjectImportance } from "../types"; +import { + download, + downloadData, + getEnvironmentUrlPartByHost, + logExtensionData, + updateProjectImportanceList +} from "./helpers"; + +export let currentProject: Project | undefined = undefined; +export let projectImportanceList: ProjectImportance[] = []; + +export const compareProjectApiToLocalDataButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const clickedSelector = detail.value; // extensibilityComponents sets value in menu item handler, so selector string + + if (clickedSelector) { + switch (clickedSelector) { + case "selectedProjects": + const selectedProjects = detail.selectedProjects; + if (selectedProjects?.length) { + // notification + trados.showNotification( + `Getting data via Public API for ${selectedProjects.length} selected project(s)`, + trados.contexts.projects, + trados.notificationTypes.info + ); + + // project api call for every selected project + Promise.all( + selectedProjects.map(p => + trados.apiClient.projectApi().getProject({ + projectId: p.id, + ...trados.getRegistrationResult(), + fields: + "name,description,dueBy,createdAt,status,statusHistory,languageDirections,customer,createdBy,location,projectTemplate,translationEngine,fileProcessingConfiguration,pricingModel,workflow,projectPlan,analytics,analysisStatistics,quote,customFields,tqaProfile,forceOnline,quoteTemplate,projectGroup,projectManagers" + }) + ) + ) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.projects, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(selectedProjects) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] At least one API call failed`, + e + ); + }); + } else { + // notification + trados.showNotification( + "No projects selected in projects list", + trados.contexts.projects, + trados.notificationTypes.warning + ); + } + break; + case "project": + const project = detail.project; + if (project) { + // notification + trados.showNotification( + "Getting data via Public API", + trados.contexts.projects, + trados.notificationTypes.info + ); + + // project details api call + trados.apiClient + .projectApi() + .getProject({ + projectId: project.id, + ...trados.getRegistrationResult(), + fields: + "name,description,dueBy,createdAt,status,statusHistory,languageDirections,customer,createdBy,location,projectTemplate,translationEngine,fileProcessingConfiguration,pricingModel,workflow,projectPlan,analytics,analysisStatistics,quote,customFields,tqaProfile,forceOnline,quoteTemplate,projectGroup,projectManagers" + }) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.projects, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(project) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] API call failed`, + e + ); + }); + } + break; + case "selectedFile": + const fileProject = detail.project; + const file = detail.selectedFile; // if file has status property, call targetFileApi instead of sourceFileApi + if (fileProject && file) { + // notification + trados.showNotification( + "Getting data via Public API", + trados.contexts.projects, + trados.notificationTypes.info + ); + + // file api call + const fileIsTargetFile = Boolean((file as TargetFile).status); + + if (fileIsTargetFile) { + // target file + trados.apiClient + .targetFileApi() + .getTargetFile({ + projectId: fileProject.id, + targetFileId: file.id, + ...trados.getRegistrationResult(), + fields: + "id,name,languageDirection,sourceFile,latestVersion,analysisStatistics,status" + }) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.projects, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(file) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] API call failed`, + e + ); + }); + } else { + // source file + trados.apiClient + .sourceFileApi() + .getSourceFile({ + projectId: fileProject.id, + sourceFileId: file.id, + ...trados.getRegistrationResult(), + fields: "id,name,role,language,versions,targetLanguages,path" + }) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.projects, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(file) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] API call failed`, + e + ); + }); + } + } else { + // notification + trados.showNotification( + "No file selected in project files tab", + trados.contexts.projects, + trados.notificationTypes.warning + ); + } + break; + case "selectedFiles": + const files = detail.selectedFiles; // if file has status property, call targetFileApi instead of sourceFileApi + const filesProject = detail.project; + if (filesProject && files?.length) { + // notification + trados.showNotification( + "Getting data via Public API", + trados.contexts.projects, + trados.notificationTypes.info + ); + + // file api call for every selected file + Promise.all( + files.map(f => { + const fileIsTargetFile = Boolean((f as TargetFile).status); + if (fileIsTargetFile) { + // target file + return trados.apiClient.targetFileApi().getTargetFile({ + projectId: filesProject.id, + targetFileId: f.id, + ...trados.getRegistrationResult(), + fields: + "id,name,languageDirection,sourceFile,latestVersion,analysisStatistics,status" + }); + } else { + // source file + return trados.apiClient.sourceFileApi().getSourceFile({ + projectId: filesProject.id, + sourceFileId: f.id, + ...trados.getRegistrationResult(), + fields: "id,name,role,language,versions,targetLanguages,path" + }); + } + }) + ) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.projects, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(files) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] At least one API call failed`, + e + ); + }); + } else { + // notification + trados.showNotification( + "No files selected in project files tab", + trados.contexts.projects, + trados.notificationTypes.warning + ); + } + break; + case "selectedTaskHistoryTask": + const taskHistoryTask = detail.selectedTaskHistoryTask; + if (taskHistoryTask) { + // notification + trados.showNotification( + "Getting data via Public API", + trados.contexts.projects, + trados.notificationTypes.info + ); + + // task api call + trados.apiClient + .taskApi() + .getTask({ + taskId: taskHistoryTask.id, + ...trados.getRegistrationResult(), + fields: + "id,status,taskType,input,inputFiles,owner,assignees,dueBy,createdAt,outcome,comment,project,failedTask,completedAt" + }) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.projects, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(taskHistoryTask) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] API call failed`, + e + ); + }); + } else { + // notification + trados.showNotification( + "No task selected in project task history tab", + trados.contexts.projects, + trados.notificationTypes.warning + ); + } + break; + case "selectedStagesTasks": + const stagesTasks = detail.selectedStagesTasks; + if (stagesTasks?.length) { + // notification + trados.showNotification( + `Getting data via Public API for ${stagesTasks.length} selected stages task(s)`, + trados.contexts.projects, + trados.notificationTypes.info + ); + + // task api call for every selected task in stages tab + Promise.all( + stagesTasks.map(t => + trados.apiClient.taskApi().getTask({ + taskId: t.id, + ...trados.getRegistrationResult(), + fields: + "id,status,taskType,input,inputFiles,owner,assignees,dueBy,createdAt,outcome,comment,project,failedTask,completedAt" + }) + ) + ) + .then(apiData => { + // notification + trados.showNotification( + "Getting data via Public API", + trados.contexts.projects, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(stagesTasks) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] At least one API call failed`, + e + ); + }); + } else { + // notification + trados.showNotification( + "No tasks selected in project stages tab", + trados.contexts.projects, + trados.notificationTypes.warning + ); + } + break; + case "projectActiveTab": + const activeTab = detail.projectActiveTab; + // notification only + trados.showNotification( + `The active tab in the project details view is ${activeTab}`, + trados.contexts.projects, + trados.notificationTypes.info + ); + break; + } + } +}; + +export const invoiceButtonRendered = (detail: ExtensibilityEventDetail) => { + logExtensionData(detail); + // update button visible state + const hidden = Boolean(detail.project && !detail.project.quote); + trados.updateElement("invoiceButton", { + hidden: hidden + }); + trados.updateElement("invoiceButtonGeneratedApi", { + hidden: hidden + }); +}; + +export const invoiceButtonClicked = (detail: ExtensibilityEventDetail) => { + logExtensionData(detail); + + // notifications + trados.showNotification( + "Requesting LC UI Extensibility service to perform file download API call (LC Public API quote-report)", + trados.contexts.projects, + trados.notificationTypes.success + ); + + // api calls - public api (pdf quote download) + trados + .callApi({ + url: `public-api/v1/projects/${detail.project!.id}/quote-report`, // LC Public API + method: "GET", + fileName: "invoice.pdf" // when fileName exists, FileDownloader will be used in extensibility service to make the LC Public API call + }) + .then(_data => { + trados.showNotification( + "Get project quote public API call completed successfully. Download will begin shortly.", + trados.contexts.projects, + trados.notificationTypes.success + ); + }) + .catch(reason => { + console.error("Get project quote call failed", reason); + trados.showNotification( + "Get project quote public API call failed.", + trados.contexts.projects, + trados.notificationTypes.fail + ); + }); + + // api calls - add-on backend api (testfile download) + // todo: uncomment and check when add-on management add-on back-end proxy endpoint will support file download. currently only json responses are supported. + /* + const testFileAddOnApiCallRequestEvent = new CustomEvent( + EventType.CallAddonApi, + { + detail: { + config: { + extensionId: extensionId, + context: "projects", + url: "api/files/test-file/testfile.txt", + method: "GET", + fileName: "testfile.txt", + callId: "getTestFileAddonApiCall" + } + } + } + ); + window.dispatchEvent(testFileAddOnApiCallRequestEvent); + + // response handler + // todo: uncomment and check when add-on management add-on back-end proxy endpoint will support file download. currently only json responses are supported. + /* + if (apiCallCompleteDetail.callId === "getTestFileAddonApiCall") { + publish("showNotification", { + context: "projects", + type: apiCallCompleteDetail.success + ? "success" + : "fail", + text: apiCallCompleteDetail.success + ? "Test file download from add-on API call completed successfully. Download will begin shortly." + : "Test file download from add-on API call failed." + }); + } + */ +}; + +// duplicated create invoice functionality to exemplify how it works with the +// generated TypeScript client alternative +export const invoiceButtonGeneratedApiClicked = async ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const projectId = detail.project!.id; + + // notifications + trados.showNotification( + "Requesting the export of the quote report (LC Public API ExportQuoteReport)", + trados.contexts.projects + ); + + /* remove try catch when https://jira.sdl.com/browse/LTLC-92923 fixed + const exportQuoteReport = await trados.apiClient.quoteApi.exportQuoteReport({ + projectId, + ...trados.getRegistrationResult() + }); + */ + try { + await trados.apiClient.quoteApi().exportQuoteReport({ + projectId, + ...trados.getRegistrationResult() + }); + } catch (error) { + // empty response instead of empty JSON response - https://jira.sdl.com/browse/LTLC-92923 + } + + //if (exportQuoteReport.id) { + let exportStatusChecks = 0; + let pollIntervalId: any = setInterval(async () => { + await trados.apiClient + .quoteApi() + .pollQuoteReportExport({ + projectId, + ...trados.getRegistrationResult() + }) + .then(pollResponse => { + exportStatusChecks++; + console.log("----pollResponse", pollResponse); + if (pollResponse.status === "completed") { + clearInterval(pollIntervalId); + pollIntervalId = null; + trados.apiClient + .quoteApi() + .downloadQuoteReport({ + projectId, + ...trados.getRegistrationResult() + }) + .then(blob => { + trados.showNotification( + "Download quote report completed successfully.
Preparing file. Download will begin shortly.", + trados.contexts.projects, + trados.notificationTypes.success + ); + + // for generated Public API, handle file download ourselves + download("quoteReport.pdf", blob); + }) + .catch(reason => { + console.log("Failed to download quote report.", reason); + trados.showNotification( + "Failed to download the quote report.", + trados.contexts.projects, + trados.notificationTypes.fail + ); + }); + } else { + if (exportStatusChecks === 9) { + clearInterval(pollIntervalId); + pollIntervalId = null; + trados.showNotification( + "The export status was verified 10 times and it's not yet complete. We've given up checking.", + trados.contexts.projects, + trados.notificationTypes.fail + ); + } + } + }) + .catch(reason => { + console.log("Failed to poll quote report export status.", reason); + trados.showNotification( + "Failed to poll quote report export status.", + trados.contexts.projects, + trados.notificationTypes.fail + ); + }); + }, 2000); // todo: 20000ms recommended interval, but isn't that too long a wait? + //} +}; + +// open in new tab +export const openNewTabButtonClicked = (detail: ExtensibilityEventDetail) => { + logExtensionData(detail); + const url = "https://www.rws.com"; + const windowName = "newTabFromLcUiExtension"; + window.open(url, windowName); +}; + +// navigate to project's template - set location and load new page +export const navigateButtonLoadRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + // update button visible state + const hidden = Boolean(detail.project && !detail.project.id); + trados.updateElement("navigateButtonLoad", { + hidden: hidden + }); +}; + +// navigate to project's template - set location and load new page +export const navigateButtonLoadClicked = (detail: ExtensibilityEventDetail) => { + logExtensionData(detail); + if (detail.project?.projectTemplate) { + // either use project set in the render handler + // or use custom event's detail: e.detail which is requested via the action's payload in activated-extensions json + const projectTemplateId = detail.project.projectTemplate.id; // can be null; button is hidden if no project template id + const destinationPath = `resources/project-templates/${projectTemplateId}`; + + // navigate to LC page event + trados.navigate(destinationPath, trados.navigationTypes.load); + } +}; + +// navigate to project's template - rely on router controller, no page load +export const navigateButtonRouteRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + // update button visible state + const hidden = Boolean(detail.project && !detail.project.id); + trados.updateElement("navigateButtonRoute", { + hidden: hidden + }); +}; + +// navigate to project's template - rely on router controller, no page load +export const navigateButtonRouteClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + if (detail.project?.projectTemplate) { + // either use project set in the render handler + // or use custom event's detail: e.detail which is requested via the action's payload in activated-extensions json + const projectTemplateId = detail.project.projectTemplate.id; // can be null; button is hidden if no project template id + const newPage = `resources/project-templates/${projectTemplateId}`; + + // navigate inside LC event + trados.navigate(newPage, trados.navigationTypes.route); + } +}; + +// get local data +export const getLocalDataButtonClicked = (detail: ExtensibilityEventDetail) => { + logExtensionData(detail); + if (detail.project) { + trados + .getLocalData(trados.contexts.projects) + .then(downloadData) + .catch(reason => { + console.error("Failed to get local data", reason); + trados.showNotification( + "Failed to get local data.", + trados.contexts.projects, + trados.notificationTypes.fail + ); + }); + } +}; + +// button rendered - setProjectImportanceButton +export const setProjectImportanceButtonRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + currentProject = detail.project; // used in index.ts apiCallComplete handler + + // should get project importance call be made now?!? + if ( + detail.project && + !projectImportanceList.find(i => i.projectId === detail.project!.id) + ) { + console.log( + "[UI Extensibility] [extension] Get project importance from add-on API" + ); + // call add-on API to get project importance + trados + .callAddonApi({ + url: `api/project-metadata/project-id/${detail.project.id}`, + method: "GET" + }) + .then(data => { + if (data && data.responseData) { + if (data.responseData.errorCode) { + console.warn( + "Failed to get project metadata (importance).", + data.responseData.errorCode, + data.responseData.message + ); + } else { + if (typeof data.responseData !== "string") { + setGetProjectImportanceApiResponseHandler(data, false); + } + } + } + }) + .catch(reason => { + console.error("Failed to get project metadata (importance)", reason); + trados.showNotification( + "Failed to get local data.", + trados.contexts.projects, + trados.notificationTypes.fail + ); + }); + + // add to projectImportanceList as pending + projectImportanceList.push({ + projectId: detail.project.id!, + pending: true + }); + } +}; + +// call add-on API - POST/PUT/DELETE +export const setProjectImportanceButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + if (detail.project) { + const importanceToSet = detail.value; // extensibilityComponents sets value in menu item handler, so high/medium/low + if (importanceToSet) { + const currentProjectImportance = projectImportanceList.find( + (i: ProjectImportance) => + i.projectId === detail.project!.id && !i.pending + ); + // update button disabled state + trados.updateElement("setProjectImportanceButton", { + disabled: true + }); + + const deleteProjectImportance = importanceToSet === "none"; + if (deleteProjectImportance && currentProjectImportance) { + trados + .callAddonApi({ + url: `api/project-metadata/${currentProjectImportance.id}`, + method: "DELETE" + }) + .then(data => { + if (data.responseData && currentProject) { + // remove from local projectImportanceList + updateProjectImportanceList(data); + + // update button text + trados.updateElement("setProjectImportanceButton", { + icon: "x-fal fa-exclamation-circle", + text: "Set Importance", + disabled: false, + menuItems: [ + { + index: 4, // unset importance + disabled: true + } + ] + }); + } + }) + .catch(reason => { + console.error( + "Failed to delete project metadata (importance)", + reason + ); + trados.showNotification( + "Failed to delete project importance.", + trados.contexts.projects, + trados.notificationTypes.fail + ); + }); + } else { + trados + .callAddonApi({ + url: `api/project-metadata${currentProjectImportance ? "/" + currentProjectImportance.id : "" + }`, + method: currentProjectImportance ? "PUT" : "POST", + body: JSON.stringify({ + projectId: detail.project.id, + importance: importanceToSet + }) + }) + .then(data => { + setGetProjectImportanceApiResponseHandler(data, true); + }) + .catch(reason => { + console.error( + "Failed to set project metadata (importance)", + reason + ); + trados.showNotification( + "Failed to set project importance.", + trados.contexts.projects, + trados.notificationTypes.fail + ); + }); + } + } else { + // main button was clicked, not High/Medium/Low menu items, so do nothing + } + } +}; + +export const setGetProjectImportanceApiResponseHandler = ( + data: any, + isSetResponsone: boolean +) => { + if (data.responseData && currentProject) { + // update/add to local projectImportanceList + updateProjectImportanceList(data); + const respImportance = data.responseData.importance; + + // update button text + trados.updateElement("setProjectImportanceButton", { + icon: + respImportance.toLowerCase() === "high" + ? "x-fal fa-chevron-circle-up" + : respImportance.toLowerCase() === "medium" + ? "x-fal fa-dot-circle" + : respImportance.toLowerCase() === "low" + ? "x-fal fa-chevron-circle-down" + : "x-fal fa-exclamation-circle", + text: respImportance, + disabled: isSetResponsone ? false : undefined, + menuItems: [ + { + index: 4, // unset importance + disabled: false + } + ] + }); + } +}; \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectsListToolbarHandlers.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectsListToolbarHandlers.ts new file mode 100644 index 0000000..c09cd80 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/projectsListToolbarHandlers.ts @@ -0,0 +1,42 @@ +import { trados } from "@sdl/extensibility"; // doesn't work until new extensibility public package published +//import { trados } from "../../../../../../../public-packages/extensibility/src/index"; // works +import { ExtensibilityEventDetail } from "@sdl/extensibility-types/extensibility"; +import { downloadData, logExtensionData } from "./helpers"; + +export const getLocalSelectedProjectsDataButtonRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const button = document.getElementById(detail.domElementId); + const selectedProjects = detail.selectedProjects; + if (button && selectedProjects) { + // update button disabled state + trados.updateElement("getLocalSelectedProjectsDataButton", { + disabled: selectedProjects.length === 0 + }); + } +}; + +export const getLocalSelectedProjectsDataButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const selectedProjects = detail.selectedProjects; + if (selectedProjects && selectedProjects.length) { + trados + .getLocalData( + trados.contexts.projects, + trados.dataSelectors.selectedProjects + ) + .then(downloadData) + .catch(_reason => { + debugger; // todo + }); + } else { + trados.showNotification( + "No selected projects", + trados.contexts.projects, + trados.notificationTypes.warning + ); + } +}; diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/taskDetailsHandlers.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/taskDetailsHandlers.ts new file mode 100644 index 0000000..24c1628 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/taskDetailsHandlers.ts @@ -0,0 +1,85 @@ +import { ExtensibilityEventDetail } from "@sdl/extensibility-types/extensibility"; +import { logExtensionData } from "./helpers"; + +// sidebar box (all tabs, not just Details tab) +export const taskDetailsSidebarBoxRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + + const task = detail.task; + console.log("[UI Extensibility] [extension] Task data", task); + + // extensionHelper is the elementId of the tab (in activated-extension.json config) + const boxContentWrapper = document.getElementById(detail.domElementId); + if (boxContentWrapper) { + // reset content for rerenders + boxContentWrapper.innerHTML = ""; + // create div + const div = document.createElement("div"); + div.innerHTML = `Custom sidebar box content inserted on render.
${ + task ? task.id : "No task id available." + }`; + boxContentWrapper.appendChild(div); + } +}; + +export const taskDetailsToolbarButtonRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const button = document.getElementById(detail.domElementId); + const task = detail.task; + if (button && task) { + console.log("RENDERED DETAILS TOOLBAR BUTTON"); + } +}; + +export const taskDetailsToolbarButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const task = detail.task; + console.log("CLICKED DETAILS TOOLBAR BUTTON", task); +}; + +// panel rendered +export const detailsMainBoxRendered = ( + detail: ExtensibilityEventDetail, + panelIndex: number +) => { + logExtensionData(detail); + + // extensionHelper is the elementId of the tab (in activated-extension.json config) + const panelContentWrapper = document.getElementById(detail.domElementId); + if (panelContentWrapper) { + // reset content for rerenders + panelContentWrapper.innerHTML = ""; + + // create div + const div = document.createElement("div"); + div.innerHTML = `Custom panel ${panelIndex} content inserted on render.`; + panelContentWrapper.appendChild(div); + } +}; + +// files tab +export const taskFilesToolbarButtonRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const button = document.getElementById(detail.domElementId); + const task = detail.task; + if (button && task) { + console.log("RENDERED FILES TOOLBAR BUTTON"); + } +}; + +export const taskFilesToolbarButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const task = detail.task; + const selectedFiles = detail.selectedFiles; + console.log("CLICKED FILES TOOLBAR BUTTON", task, selectedFiles); +}; diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/taskTabbarHandlers.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/taskTabbarHandlers.ts new file mode 100644 index 0000000..77d21ef --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/taskTabbarHandlers.ts @@ -0,0 +1,29 @@ +import { ExtensibilityEventDetail } from "@sdl/extensibility-types/extensibility"; +import { logExtensionData } from "./helpers"; + +let renderCount = 0; + +export const taskTabRendered = (detail: ExtensibilityEventDetail) => { + logExtensionData(detail); + renderCount++; + + // custom-tab is the elementId of the tab (in activated-extension.json config) + const tabContentWrapper = document.getElementById(detail.domElementId); + if (tabContentWrapper) { + // reset content for rerenders + tabContentWrapper.innerHTML = ""; + + // create heading + const heading = document.createElement("div"); + heading.className = "x-panel-header-title-light-framed"; + heading.setAttribute("style", "margin-bottom: 10px"); + heading.innerHTML = `Custom tab rendered ${renderCount} times.`; + + //task details selector set as event payload + const task = detail.task; + console.log("[UI Extensibility] [extension] Task from event", task); + // add heading to tab + tabContentWrapper.appendChild(heading); + tabContentWrapper.style.position = "relative"; + } +}; diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/taskToolbarHandlers.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/taskToolbarHandlers.ts new file mode 100644 index 0000000..acc5d4d --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/taskToolbarHandlers.ts @@ -0,0 +1,483 @@ +import { trados } from "@sdl/extensibility"; // doesn't work until new extensibility public package published +//import { trados } from "../../../../../../../public-packages/extensibility/src/index"; // works +import { ExtensibilityEventDetail } from "@sdl/extensibility-types/extensibility"; +import { download, logExtensionData } from "./helpers"; +import { TargetFile } from "@sdl/extensibility/lib/lc-public-api/models"; + +export const compareTaskApiToLocalDataButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const clickedSelector = detail.value; // extensibilityComponents sets value in menu item handler, so selector string + + if (clickedSelector) { + switch (clickedSelector) { + case "selectedNewTasks": + const newTasks = detail.selectedNewTasks; + if (newTasks?.length) { + // notification + trados.showNotification( + `Getting data via Public API for ${newTasks.length} selected new task(s)`, + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // task api call for every selected task + Promise.all( + newTasks.map(t => + trados.apiClient.taskApi().getTask({ + taskId: t.id, + ...trados.getRegistrationResult(), + fields: + "id,status,taskType,input,inputFiles,owner,assignees,dueBy,createdAt,outcome,comment,project,failedTask,completedAt" + }) + ) + ) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(newTasks) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] At least one API call failed`, + e + ); + }); + } else { + // notification + trados.showNotification( + "No tasks selected in inbox new tasks tab", + trados.contexts.taskInbox, + trados.notificationTypes.warning + ); + } + break; + case "selectedActiveTasks": + const activeTasks = detail.selectedActiveTasks; + if (activeTasks?.length) { + // notification + trados.showNotification( + `Getting data via Public API for ${activeTasks.length} selected new task(s)`, + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // task api call for every selected task + Promise.all( + activeTasks.map(t => + trados.apiClient.taskApi().getTask({ + taskId: t.id, + ...trados.getRegistrationResult(), + fields: + "id,status,taskType,input,inputFiles,owner,assignees,dueBy,createdAt,outcome,comment,project,failedTask,completedAt" + }) + ) + ) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(activeTasks) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] At least one API call failed`, + e + ); + }); + } else { + // notification + trados.showNotification( + "No tasks selected in inbox active tasks tab", + trados.contexts.taskInbox, + trados.notificationTypes.warning + ); + } + break; + case "selectedCompletedTasks": + const completedTasks = detail.selectedCompletedTasks; + if (completedTasks?.length) { + // notification + trados.showNotification( + `Getting data via Public API for ${completedTasks.length} selected new task(s)`, + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // task api call for every selected task + Promise.all( + completedTasks.map(t => + trados.apiClient.taskApi().getTask({ + taskId: t.id, + ...trados.getRegistrationResult(), + fields: + "id,status,taskType,input,inputFiles,owner,assignees,dueBy,createdAt,outcome,comment,project,failedTask,completedAt" + }) + ) + ) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(completedTasks) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] At least one API call failed`, + e + ); + }); + } else { + // notification + trados.showNotification( + "No tasks selected in inbox completed tasks tab", + trados.contexts.taskInbox, + trados.notificationTypes.warning + ); + } + break; + case "newTaskPreview": + const newTaskPreview = detail.newTaskPreview; + if (newTaskPreview) { + // notification + trados.showNotification( + "Getting data via Public API", + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // task api call + trados.apiClient + .taskApi() + .getTask({ + taskId: newTaskPreview.id, + ...trados.getRegistrationResult(), + fields: + "id,status,taskType,input,inputFiles,owner,assignees,dueBy,createdAt,outcome,comment,project,failedTask,completedAt" + }) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(newTaskPreview) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] API call failed`, + e + ); + }); + } else { + // notification + trados.showNotification( + "No new task preview", + trados.contexts.taskInbox, + trados.notificationTypes.warning + ); + } + break; + case "activeTaskPreview": + const activeTaskPreview = detail.activeTaskPreview; + if (activeTaskPreview) { + // notification + trados.showNotification( + "Getting data via Public API", + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // task api call + trados.apiClient + .taskApi() + .getTask({ + taskId: activeTaskPreview.id, + ...trados.getRegistrationResult(), + fields: + "id,status,taskType,input,inputFiles,owner,assignees,dueBy,createdAt,outcome,comment,project,failedTask,completedAt" + }) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(activeTaskPreview) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] API call failed`, + e + ); + }); + } else { + // notification + trados.showNotification( + "No active task preview", + trados.contexts.taskInbox, + trados.notificationTypes.warning + ); + } + break; + case "completedTaskPreview": + const completedTaskPreview = detail.completedTaskPreview; + if (completedTaskPreview) { + // notification + trados.showNotification( + "Getting data via Public API", + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // task api call + trados.apiClient + .taskApi() + .getTask({ + taskId: completedTaskPreview.id, + ...trados.getRegistrationResult(), + fields: + "id,status,taskType,input,inputFiles,owner,assignees,dueBy,createdAt,outcome,comment,project,failedTask,completedAt" + }) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(completedTaskPreview) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] API call failed`, + e + ); + }); + } else { + // notification + trados.showNotification( + "No completed task preview", + trados.contexts.taskInbox, + trados.notificationTypes.warning + ); + } + break; + case "task": + const task = detail.task; + if (task) { + // notification + trados.showNotification( + "Getting data via Public API", + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // task api call + trados.apiClient + .taskApi() + .getTask({ + taskId: task.id, + ...trados.getRegistrationResult(), + fields: + "id,status,taskType,input,inputFiles,owner,assignees,dueBy,createdAt,outcome,comment,project,failedTask,completedAt" + }) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(task) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] API call failed`, + e + ); + }); + } + break; + case "selectedFiles": + const files = detail.selectedFiles; // if file has status property, call targetFileApi instead of sourceFileApi + const taskProject = detail.task?.project; + if (taskProject && files?.length) { + // notification + trados.showNotification( + "Getting data via Public API", + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // file api call for every selected file + Promise.all( + files.map(f => { + const fileIsTargetFile = Boolean((f as TargetFile).status); // todo: detect source vs target from selector data (only id, name, status properties) + if (fileIsTargetFile) { + // target file + return trados.apiClient.targetFileApi().getTargetFile({ + projectId: taskProject.id, + targetFileId: f.id, + ...trados.getRegistrationResult(), + fields: + "id,name,languageDirection,sourceFile,latestVersion,analysisStatistics,status" + }); + } else { + // source file + return trados.apiClient.sourceFileApi().getSourceFile({ + projectId: taskProject.id, + sourceFileId: f.id, + ...trados.getRegistrationResult(), + fields: "id,name,role,language,versions,targetLanguages,path" + }); + } + }) + ) + .then(apiData => { + // notification + trados.showNotification( + "Downloading files for comparison", + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + + // download + download( + `compare-api-data-${clickedSelector}.json`, + JSON.stringify(apiData) + ); + download( + `compare-ui-data-${clickedSelector}.json`, + JSON.stringify(files) + ); + }) + .catch(e => { + console.error( + `[UI Extensibility] [extension] At least one API call failed`, + e + ); + }); + } else { + // notification + trados.showNotification( + "No files selected in task files tab", + trados.contexts.taskInbox, + trados.notificationTypes.warning + ); + } + break; + case "inboxActiveTab": + const inboxActiveTab = detail.inboxActiveTab; + // notification only + trados.showNotification( + `The active tab in the inbox view is ${inboxActiveTab}`, + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + break; + case "taskActiveTab": + const taskActiveTab = detail.taskActiveTab; + // notification only + trados.showNotification( + `The active tab in the task details view is ${taskActiveTab}`, + trados.contexts.taskInbox, + trados.notificationTypes.info + ); + break; + } + } +}; + +export const taskToolbarButtonRendered = (detail: ExtensibilityEventDetail) => { + logExtensionData(detail); + const button = document.getElementById(detail.domElementId); + const task = detail.task; + if (button) { + console.log("RENDERED TASK TOOLBAR BUTTON", task); + } +}; + +export const taskToolbarButtonClicked = (detail: ExtensibilityEventDetail) => { + logExtensionData(detail); + if (detail.task) { + const task = detail.task; + console.log("CLICKED TASK TOOLBAR BUTTON", task); + } +}; diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/tasksListPreviewHandlers.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/tasksListPreviewHandlers.ts new file mode 100644 index 0000000..3813525 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/tasksListPreviewHandlers.ts @@ -0,0 +1,49 @@ +import { ExtensibilityEventDetail } from "@sdl/extensibility-types/extensibility"; +import { Task } from "@sdl/extensibility/dist/lib/lc-public-api/models"; + +import { logExtensionData } from "./helpers"; + +let taskPreview: Task | undefined = undefined; + +export const taskSidebarBoxRendered = (detail: ExtensibilityEventDetail) => { + logExtensionData(detail); + const boxContentWrapper: HTMLElement | null = document.getElementById( + detail.domElementId + ); + taskPreview = + detail.newTaskPreview || + detail.activeTaskPreview || + detail.completedTaskPreview || + undefined; // reset previous taskPreview? + + console.log( + "[UI Extensibility] [extension] Update preview sidebar box", + boxContentWrapper, + taskPreview + ); + + if (boxContentWrapper && taskPreview) { + const filename = taskPreview.inputFiles?.length + ? taskPreview.inputFiles[0].sourceFile?.name + : ""; + + // version 1: create html element and add to DOM + boxContentWrapper.innerHTML = ""; + // create div + const div = document.createElement("div"); + div.innerHTML = `Custom sidebar box content inserted on render.
Task description: ${ + filename ? filename : "no inputFiles" + }`; + boxContentWrapper.appendChild(div); + /* + // version 2: don't create html element and add to DOM; just change innerHTML + boxContentWrapper.innerHTML = `Custom sidebar box content inserted on render.
Task description: ${ + filename ? filename : "no filename in metadata" + }`; + */ + } else { + console.error( + `[UI Extensibility] [extension] No boxContentWrapper or taskPreview data` + ); + } +}; diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/tasksListToolbarHandlers.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/tasksListToolbarHandlers.ts new file mode 100644 index 0000000..f376336 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/handlers/tasksListToolbarHandlers.ts @@ -0,0 +1,69 @@ +import { ExtensibilityEventDetail } from "@sdl/extensibility-types/extensibility"; +import { logExtensionData } from "./helpers"; + +let selectedNewTasks: undefined | any[] = undefined; +let selectedActiveTasks: undefined | any[] = undefined; +let selectedCompletedTasks: undefined | any[] = undefined; + +export const newTasksListToolbarButtonRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const button = document.getElementById(detail.domElementId); + selectedNewTasks = detail.selectedNewTasks; + if (button && selectedNewTasks) { + console.log("RENDERED NEW"); + } +}; + +export const newTasksListToolbarButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + if (detail.selectedNewTasks) { + selectedNewTasks = detail.selectedNewTasks; + console.log("CLICKED NEW", selectedNewTasks); + } +}; + +export const activeTasksListToolbarButtonRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const button = document.getElementById(detail.domElementId); + selectedActiveTasks = detail.selectedActiveTasks; + if (button && selectedActiveTasks) { + console.log("RENDERED ACTIVE"); + } +}; + +export const activeTasksListToolbarButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + if (detail.selectedActiveTasks) { + selectedActiveTasks = detail.selectedActiveTasks; + console.log("CLICKED ACTIVE", selectedActiveTasks); + } +}; + +export const completedTasksListToolbarButtonRendered = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + const button = document.getElementById(detail.domElementId); + selectedCompletedTasks = detail.selectedCompletedTasks; + if (button && selectedCompletedTasks) { + console.log("RENDERED COMPLETED"); + } +}; + +export const completedTasksListToolbarButtonClicked = ( + detail: ExtensibilityEventDetail +) => { + logExtensionData(detail); + if (detail.selectedCompletedTasks) { + selectedCompletedTasks = detail.selectedCompletedTasks; + console.log("CLICKED COMPLETED", selectedCompletedTasks); + } +}; diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/index.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/index.ts new file mode 100644 index 0000000..75b5527 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/index.ts @@ -0,0 +1,1322 @@ +/************************************************* + * this file is based on C:\SDL-Products\nimbus-ui\packages\projects\src\extensibility\PoCExtension.ts + * but wrapped into a self-invoked function + * + * the config is mocked in activated-extensions.json + * the extension script is mocked in the current file: run "tsc" from C:\SDL-Products\nimbus-ui\packages\projects-app\src\mocks\ui-extensibility to update the PoCExtension.js file + * the extension script is a self invoked function in this file that should be served by a separate website to simulate a third party resource: see https://confluence.sdl.com/display/LPD/UI+PoC+Add-on+-+Local+Setup for details + *************************************************/ +import { trados } from "@sdl/extensibility"; +import { + ExtensionElement, + ExtensibilityEventDetail, + ElementType +} from "@sdl/extensibility-types/extensibility"; + +// projects handlers +import { + backToDefaultFontSizeButtonClicked, + dashboardMainPanelRendered, + dashboardSidebarBoxRendered, + getLocalDashboardDataButtonClicked, + increaseFontSizeButtonClicked +} from "./handlers/projectDashboardHandlers"; +import { + getLocalFilesDataButtonClicked, + hideNotTranslatedFilesButtonClicked, + showAllFilesButtonClicked +} from "./handlers/projectFilesHandlers"; +import { + getLocalSelectedProjectsDataButtonRendered, + getLocalSelectedProjectsDataButtonClicked +} from "./handlers/projectsListToolbarHandlers"; +import { + getLocalStagesDataButtonClicked, + highlightPopulatedStagesButtonClicked, + removeStagesHighlightsButtonClicked +} from "./handlers/projectStagesHadlers"; +import { extensionsHelperTabRendered } from "./handlers/projectTabbarHandlers"; +import { + getLocalTaskHistoryDataButtonClicked, + hideFailedTasksButtonClicked, + highlightSelectedTaskButtonClicked, + highlightSelectedTaskButtonRendered, + showAllTasksButtonClicked, + taskHistorySidebarBoxRendered +} from "./handlers/projectTaskHistoryHandlers"; +import { + compareProjectApiToLocalDataButtonClicked, + getLocalDataButtonClicked, + invoiceButtonClicked, + invoiceButtonGeneratedApiClicked, + invoiceButtonRendered, + navigateButtonLoadClicked, + navigateButtonLoadRendered, + navigateButtonRouteClicked, + navigateButtonRouteRendered, + openNewTabButtonClicked, + setProjectImportanceButtonClicked, + setProjectImportanceButtonRendered +} from "./handlers/projectToolbarHandlers"; + +// task-inbox handlers +import { + activeTasksListToolbarButtonClicked, + activeTasksListToolbarButtonRendered, + completedTasksListToolbarButtonClicked, + completedTasksListToolbarButtonRendered, + newTasksListToolbarButtonClicked, + newTasksListToolbarButtonRendered +} from "./handlers/tasksListToolbarHandlers"; +import { taskSidebarBoxRendered } from "./handlers/tasksListPreviewHandlers"; +import { + compareTaskApiToLocalDataButtonClicked, + taskToolbarButtonClicked, + taskToolbarButtonRendered +} from "./handlers/taskToolbarHandlers"; +import { taskTabRendered } from "./handlers/taskTabbarHandlers"; +import { + detailsMainBoxRendered, + taskDetailsToolbarButtonClicked, + taskDetailsToolbarButtonRendered, + taskFilesToolbarButtonClicked, + taskFilesToolbarButtonRendered, + taskDetailsSidebarBoxRendered +} from "./handlers/taskDetailsHandlers"; + + +// extension elements: the JSON describing custom elements that will be added in the UI +const elements: ExtensionElement[] = [ + // projects elements + /* + { + elementId: "compareApiToLocalDataButton", + icon: "x-fal fa-copy", + text: "API vs Local data", + location: "project-details-toolbar", + type: "button", + hidden: false, + menu: [ + { + text: "selectedProjects", + value: "selectedProjects", + icon: "x-fal fa-copy" + }, + { + text: "project", + value: "project", + icon: "x-fal fa-copy" + }, + { + text: "selectedFile", + value: "selectedFile", + icon: "x-fal fa-copy" + }, + { + text: "selectedFiles", + value: "selectedFiles", + icon: "x-fal fa-copy" + }, + { + text: "selectedTaskHistoryTask", + value: "selectedTaskHistoryTask", + icon: "x-fal fa-copy" + }, + { + text: "selectedStagesTasks", + value: "selectedStagesTasks", + icon: "x-fal fa-copy" + }, + { separator: true }, + { + text: "projectActiveTab (notification only)", + value: "projectActiveTab", + icon: "x-fal fa-exclamation-circle" + } + ], + actions: [ + { + eventType: "onclick", + eventHandler: compareProjectApiToLocalDataButtonClicked, + payload: [ + "selectedProjects", + "project", + "selectedFile", + "selectedFiles", + "selectedTaskHistoryTask", + "selectedStagesTasks", + "projectActiveTab" + ] + } + ] + },*/ + { + elementId: "invoiceButton", + icon: "x-fal fa-newspaper", + text: "Create Invoice", + location: "project-details-toolbar", + type: "button", + hidden: true, + actions: [ + { + eventType: "onrender", + eventHandler: invoiceButtonRendered, + payload: [] + }, + { + eventType: "onclick", + eventHandler: invoiceButtonClicked, + payload: ["project"] + } + ] + }, + { + elementId: "invoiceButtonGeneratedApi", + icon: "x-fal fa-newspaper", + text: "Create Invoice (generated API)", + location: "project-details-toolbar", + type: "button", + hidden: true, + actions: [ + { + eventType: "onrender", + eventHandler: invoiceButtonRendered, + payload: [] + }, + { + eventType: "onclick", + eventHandler: invoiceButtonGeneratedApiClicked, + payload: ["project"] + } + ] + }, + /* + { + elementId: "openNewTabButton", + icon: "x-fal fa-external-link", + iconAlign: "right", + text: "Open rws.com in New tab", + location: "project-details-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: openNewTabButtonClicked, + payload: ["project"] + } + ] + },*/ + { + elementId: "openNewTabButtonLink", + icon: "x-fal fa-external-link", + text: "Open rws.com in New tab", + location: "project-details-toolbar", + type: "button", + isLink: true, + href: "https://www.rws.com" + }, + /* + { + elementId: "navigateButtonLoad", + icon: "x-fal fa-clipboard", + text: "View Project Template (page load)", + location: "project-details-toolbar", + type: "button", + hidden: true, + actions: [ + { + eventType: "onrender", + eventHandler: navigateButtonLoadRendered, + payload: ["project"] + }, + { + eventType: "onclick", + eventHandler: navigateButtonLoadClicked, + payload: ["project"] + } + ] + },*/ + { + elementId: "navigateButtonRoute", + icon: "x-fal fa-clipboard", + text: "View Project Template", // (route)", + location: "project-details-toolbar", + type: "button", + hidden: true, + actions: [ + { + eventType: "onrender", + eventHandler: navigateButtonRouteRendered, + payload: ["project"] + }, + { + eventType: "onclick", + eventHandler: navigateButtonRouteClicked, + payload: ["project"] + } + ] + }, + { + elementId: "getLocalDataButton", + icon: "x-fal fa-table", + text: "Get Local Data", + location: "project-details-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: getLocalDataButtonClicked, + //payload: ["project"] + payload: [ + "selectedProjects", + "project", + "selectedFile", + "selectedFiles", + "selectedTaskHistoryTask", + "selectedStagesTasks", + "projectActiveTab" + ] + } + ] + }, + { + elementId: "setProjectImportanceButton", + icon: "x-fal fa-exclamation-circle", + text: "Set Importance", + location: "project-details-toolbar", + type: "button", + menu: [ + { + text: "High", + value: "high", + icon: "x-fal fa-chevron-circle-up" + }, + { + text: "Medium", + value: "medium", + icon: "x-fal fa-dot-circle" + }, + { + text: "Low", + value: "low", + icon: "x-fal fa-chevron-circle-down" + }, + { separator: true }, + { + text: "Unset importance", + value: "none", + icon: "x-fal fa-trash", + disabled: true + } + ], + actions: [ + { + eventType: "onrender", + eventHandler: setProjectImportanceButtonRendered, + payload: [] + }, + { + eventType: "onclick", + eventHandler: setProjectImportanceButtonClicked, + payload: ["project"] + } + ] + }, + { + elementId: "extensionsHelper", + text: "Extensions Helper", + location: "project-details-tabpanel", + type: "tab", + actions: [ + { + eventType: "onrender", + eventHandler: extensionsHelperTabRendered, + payload: ["project", "selectedProjects"] + } + ] + }, + { + elementId: "dashboardMain1Box", + text: "Custom Panel 1", + location: "project-details-dashboard-main", + type: "panel", + actions: [ + { + eventType: "onrender", + eventHandler: (detail: ExtensibilityEventDetail) => { + dashboardMainPanelRendered(detail, 1); + }, + payload: [] + } + ] + }, + { + elementId: "dashboardMain2Box", + text: "Custom Panel 2", + location: "project-details-dashboard-main", + type: "panel", + actions: [ + { + eventType: "onrender", + eventHandler: (detail: ExtensibilityEventDetail) => { + dashboardMainPanelRendered(detail, 2); + }, + payload: [] + } + ] + }, + { + elementId: "dashboardMain3Box", + text: "Custom Panel 3", + location: "project-details-dashboard-main", + type: "panel", + actions: [ + { + eventType: "onrender", + eventHandler: (detail: ExtensibilityEventDetail) => { + dashboardMainPanelRendered(detail, 3); + }, + payload: [] + } + ] + }, + { + elementId: "dashboardSidebarBox", + text: "Sidebar Box", + location: "project-details-dashboard-sidebar", + type: "sidebarBox", + actions: [ + { + eventType: "onrender", + eventHandler: dashboardSidebarBoxRendered, + payload: [] + } + ] + }, + { + elementId: "getLocalDashboardDataButton", + icon: "x-fal fa-table", + iconAlign: "right", + text: "Get Local Data", + location: "project-details-dashboard-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: getLocalDashboardDataButtonClicked, + payload: [] + } + ] + }, + { + elementId: "increaseFontSizeButton", + icon: "x-fal fa-font", + iconAlign: "right", + text: "Increase font size", + location: "project-details-dashboard-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: increaseFontSizeButtonClicked, + payload: [] + } + ] + }, + { + elementId: "backToDefaultFontSizeButton", + icon: "x-fal fa-arrow-down", + iconAlign: "right", + text: "Back to default font size", + location: "project-details-dashboard-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: backToDefaultFontSizeButtonClicked, + payload: [] + } + ] + }, + { + elementId: "getLocalStagesDataButton", + icon: "x-fal fa-calendar", + iconAlign: "right", + text: "Get local data", + location: "project-details-stages-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: getLocalStagesDataButtonClicked, + payload: [] + } + ] + }, + { + elementId: "highlightPopulatedStagesButton", + icon: "x-fal fa-folder-open", + iconAlign: "right", + text: "Highlight populated stages", + location: "project-details-stages-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: highlightPopulatedStagesButtonClicked, + payload: [] + } + ] + }, + { + elementId: "removeStagesHighlightsButton", + icon: "x-fal fa-folder", + iconAlign: "right", + text: "Remove stages highlights", + location: "project-details-stages-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: removeStagesHighlightsButtonClicked, + payload: [] + } + ] + }, + { + elementId: "getLocalFilesDataButton", + icon: "x-fal fa-calendar", + iconAlign: "right", + text: "Get local data", + location: "project-details-files-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: getLocalFilesDataButtonClicked, + payload: [] + } + ] + }, + { + elementId: "hideNotTranslatedFilesButton", + icon: "x-fal fa-ban", + iconAlign: "right", + text: "Hide not translated files", + location: "project-details-files-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: hideNotTranslatedFilesButtonClicked, + payload: [] + } + ] + }, + { + elementId: "showAllFilesButton", + icon: "x-fal fa-bars", + iconAlign: "right", + text: "Show all files", + location: "project-details-files-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: showAllFilesButtonClicked, + payload: [] + } + ] + }, + { + elementId: "getLocalTaskHistoryDataButton", + icon: "x-fal fa-calendar", + iconAlign: "right", + text: "Get local data", + location: "project-details-task-history-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: getLocalTaskHistoryDataButtonClicked, + payload: [] + } + ] + }, + { + elementId: "hideFailedTasksButton", + icon: "x-fal fa-ban", + iconAlign: "right", + text: "Hide Failed tasks", + location: "project-details-task-history-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: hideFailedTasksButtonClicked, + payload: [] + } + ] + }, + { + elementId: "showAllButton", + icon: "x-fal fa-bars", + iconAlign: "right", + text: "Show all tasks", + location: "project-details-task-history-toolbar", + type: "button", + actions: [ + { + eventType: "onclick", + eventHandler: showAllTasksButtonClicked, + payload: [] + } + ] + }, + { + elementId: "taskHistorySidebarBox", + text: "Sidebar Box", + location: "project-details-task-history-sidebar", + type: "sidebarBox", + actions: [ + { + eventType: "onrender", + eventHandler: taskHistorySidebarBoxRendered, + payload: ["selectedTaskHistoryTask"] + } + ] + }, + { + elementId: "highlightSelectedTaskButton", + icon: "x-fal fa-folder-open", + iconAlign: "right", + text: "Highlight selected tasks", + location: "project-details-task-history-toolbar", + type: "button", + actions: [ + { + eventType: "onrender", + eventHandler: highlightSelectedTaskButtonRendered, + payload: ["selectedTaskHistoryTask"] + }, + { + eventType: "onclick", + eventHandler: highlightSelectedTaskButtonClicked, + payload: [] + } + ] + }, + { + elementId: "getLocalSelectedProjectsDataButton", + icon: "x-fal fa-table", + iconAlign: "right", + text: "Get selection data", + location: "projects-list-toolbar", + type: "button", + disabled: true, + actions: [ + { + eventType: "onrender", + eventHandler: getLocalSelectedProjectsDataButtonRendered, + payload: ["selectedProjects"] + }, + { + eventType: "onclick", + eventHandler: getLocalSelectedProjectsDataButtonClicked, + payload: ["selectedProjects"] + } + ] + }, + + // task-inbox elements + /* + { + elementId: "compareApiToLocalDataButton", + icon: "x-fal fa-copy", + text: "API vs Local data", + location: "task-toolbar", + type: "button", + hidden: false, + menu: [ + { + text: "selectedNewTasks", + value: "selectedNewTasks", + icon: "x-fal fa-copy" + }, + { + text: "selectedActiveTasks", + value: "selectedActiveTasks", + icon: "x-fal fa-copy" + }, + { + text: "selectedCompletedTasks", + value: "selectedCompletedTasks", + icon: "x-fal fa-copy" + }, + { + text: "newTaskPreview", + value: "newTaskPreview", + icon: "x-fal fa-copy" + }, + { + text: "activeTaskPreview", + value: "activeTaskPreview", + icon: "x-fal fa-copy" + }, + { + text: "completedTaskPreview", + value: "completedTaskPreview", + icon: "x-fal fa-copy" + }, + { + text: "task", + value: "task", + icon: "x-fal fa-copy" + }, + { + text: "selectedFiles", + value: "selectedFiles", + icon: "x-fal fa-copy" + }, + { separator: true }, + { + text: "inboxActiveTab (notification only)", + value: "inboxActiveTab", + icon: "x-fal fa-exclamation-circle" + }, + { + text: "taskActiveTab (notification only)", + value: "taskActiveTab", + icon: "x-fal fa-exclamation-circle" + } + ], + actions: [ + { + eventType: "onclick", + eventHandler: compareTaskApiToLocalDataButtonClicked, + payload: [ + "selectedNewTasks", + "selectedActiveTasks", + "selectedCompletedTasks", + "newTaskPreview", + "activeTaskPreview", + "completedTaskPreview", + "inboxActiveTab", + "task", + "selectedFiles", + "taskActiveTab" + ] + } + ] + },*/ + { + elementId: "custom-btn-new-tasks-list-toolbar", + icon: "x-fal fa-newspaper", + text: "New custom button", + location: "new-tasks-list-toolbar", + type: "button", + actions: [ + { + eventType: "onrender", + eventHandler: newTasksListToolbarButtonRendered, + payload: [] + }, + { + eventType: "onclick", + eventHandler: newTasksListToolbarButtonClicked, + payload: ["selectedNewTasks"] + } + ] + }, + { + elementId: "custom-btn-active-tasks-list-toolbar", + icon: "x-fal fa-newspaper", + text: "Active custom button", + location: "active-tasks-list-toolbar", + type: "button", + actions: [ + { + eventType: "onrender", + eventHandler: activeTasksListToolbarButtonRendered, + payload: [] + }, + { + eventType: "onclick", + eventHandler: activeTasksListToolbarButtonClicked, + payload: ["selectedActiveTasks"] + } + ] + }, + { + elementId: "custom-btn-completed-tasks-list-toolbar", + icon: "x-fal fa-newspaper", + text: "Completed custom button", + location: "completed-tasks-list-toolbar", + type: "button", + actions: [ + { + eventType: "onrender", + eventHandler: completedTasksListToolbarButtonRendered, + payload: [] + }, + { + eventType: "onclick", + eventHandler: completedTasksListToolbarButtonClicked, + payload: ["selectedCompletedTasks"] + } + ] + }, + { + elementId: "newTaskSidebarBox", + text: "New Sidebar Box", + location: "new-tasks-list-sidebar", + type: "sidebarBox", + actions: [ + { + eventType: "onrender", + eventHandler: taskSidebarBoxRendered, + payload: [] + } + ] + }, + { + elementId: "activeTaskSidebarBox", + text: "Active Sidebar Box", + location: "active-tasks-list-sidebar", + type: "sidebarBox", + actions: [ + { + eventType: "onrender", + eventHandler: taskSidebarBoxRendered, + payload: [] + } + ] + }, + { + elementId: "completedTaskSidebarBox", + text: "Completed Sidebar Box", + location: "completed-tasks-list-sidebar", + type: "sidebarBox", + actions: [ + { + eventType: "onrender", + eventHandler: taskSidebarBoxRendered, + payload: [] + } + ] + }, + { + elementId: "custom-btn-task-toolbar", + icon: "x-fal fa-newspaper", + text: "Custom button", + location: "task-toolbar", + type: "button", + actions: [ + { + eventType: "onrender", + eventHandler: taskToolbarButtonRendered, + payload: [] + }, + { + eventType: "onclick", + eventHandler: taskToolbarButtonClicked, + payload: ["task", "taskActiveTab"] + } + ] + }, + { + elementId: "custom-tab", + text: "Custom Tab", + location: "task-tabpanel", + type: "tab", + actions: [ + { + eventType: "onrender", + eventHandler: taskTabRendered, + payload: ["task", "taskActiveTab"] + } + ] + }, + { + elementId: "taskSidebarBox", + text: "Task Details Sidebar Box", + location: "task-sidebar", + type: "sidebarBox", + actions: [ + { + eventType: "onrender", + eventHandler: taskDetailsSidebarBoxRendered, + payload: [] + } + ] + }, + { + elementId: "custom-btn-task-details-toolbar", + icon: "x-fal fa-newspaper", + text: "Custom task details toolbar button", + location: "task-details-toolbar", + type: "button", + actions: [ + { + eventType: "onrender", + eventHandler: taskDetailsToolbarButtonRendered, + payload: [] + }, + { + eventType: "onclick", + eventHandler: taskDetailsToolbarButtonClicked, + payload: ["task", "taskActiveTab"] + } + ] + }, + { + elementId: "detailsMain1Box", + text: "Custom Panel 1", + location: "task-details-main", + type: "panel", + actions: [ + { + eventType: "onrender", + eventHandler: (detail: ExtensibilityEventDetail) => { + detailsMainBoxRendered(detail, 1); + }, + payload: [] + } + ] + }, + { + elementId: "detailsMain2Box", + text: "Custom Panel 2", + location: "task-details-main", + type: "panel", + actions: [ + { + eventType: "onrender", + eventHandler: (detail: ExtensibilityEventDetail) => { + detailsMainBoxRendered(detail, 2); + }, + payload: [] + } + ] + }, + { + elementId: "custom-btn-task-files-toolbar", + icon: "x-fal fa-newspaper", + text: "Custom button", + location: "task-files-toolbar", + type: "button", + actions: [ + { + eventType: "onrender", + eventHandler: taskFilesToolbarButtonRendered, + payload: [] + }, + { + eventType: "onclick", + eventHandler: taskFilesToolbarButtonClicked, + payload: ["task", "taskActiveTab", "selectedFiles"] + } + ] + } +]; + +/* +// extra buttons for LTLC-85181 +const allToolbarLocations = [ + // projects + "projects-list-toolbar", + "project-details-toolbar", + "project-details-dashboard-toolbar", + "project-details-stages-toolbar", + "project-details-files-toolbar", + "project-details-task-history-toolbar", + // task-inbox + "new-tasks-list-toolbar", + "active-tasks-list-toolbar", + "completed-tasks-list-toolbar", + "task-toolbar", + "task-details-toolbar", + "task-files-toolbar" +]; + +allToolbarLocations.forEach(l => + elements.push( + { + elementId: `${l}-cstm-btn-actions`, + icon: "x-fal fa-info-circle", + text: "Change Target button", + // @ts-ignore + location: l, + type: "button", + menu: [ + // toggle hidden + { + icon: "x-fal fa-angle-right", + text: "Hide", + value: "hide" + }, + { + icon: "x-fal fa-angle-right", + text: "Show", + value: "show" + }, + { + separator: true + }, + // toggle disabled + { + icon: "x-fal fa-angle-right", + text: "Disable", + value: "disable" + }, + { + icon: "x-fal fa-angle-right", + text: "Enable", + value: "enable" + }, + { + separator: true + }, + // toggle text + { + icon: "x-fal fa-angle-right", + text: "Make text uppercase", + value: "uppercase" + }, + { + icon: "x-fal fa-angle-right", + text: "Make text casing default", + value: "defaultcase" + }, + { + separator: true + }, + // toggle icon + { + icon: "x-fal fa-angle-right", + text: "Set star icon", + value: "staricon" + }, + { + icon: "x-fal fa-angle-right", + text: "Set info icon", + value: "infoicon" + }, + { + separator: true + }, + // toggle menu + { + icon: "x-fal fa-angle-right", + text: "Disable & make uppercase & set star icon for dropdown menu options", + value: "disablemenuoptions" + }, + { + icon: "x-fal fa-angle-right", + text: "Enable & make default case & set info icon for dropdown menu options", + value: "enablemenuoptions" + } + ], + actions: [ + { + eventType: "onclick", + eventHandler: (detail: ExtensibilityEventDetail) => { + switch (detail.value) { + case "hide": + trados.updateElement(`${l}-cstm-btn-target`, { hidden: true }); + break; + case "show": + trados.updateElement(`${l}-cstm-btn-target`, { hidden: false }); + break; + case "disable": + trados.updateElement(`${l}-cstm-btn-target`, { + disabled: true + }); + break; + case "enable": + trados.updateElement(`${l}-cstm-btn-target`, { + disabled: false + }); + break; + case "uppercase": + trados.updateElement(`${l}-cstm-btn-target`, { + text: "TARGET" + }); + break; + case "defaultcase": + trados.updateElement(`${l}-cstm-btn-target`, { + text: "Target" + }); + break; + case "staricon": + trados.updateElement(`${l}-cstm-btn-target`, { + icon: "x-fal fa-star" + }); + break; + case "infoicon": + trados.updateElement(`${l}-cstm-btn-target`, { + icon: "x-fal fa-info" + }); + break; + case "disablemenuoptions": + trados.updateElement(`${l}-cstm-btn-target`, { + menuItems: [ + { + index: 0, + disabled: true, + text: "MENU OPTION 1", + icon: "x-fal fa-star" + }, + { + index: 1, + disabled: true, + text: "MENU OPTION 2", + icon: "x-fal fa-star" + } + ] + }); + break; + case "enablemenuoptions": + trados.updateElement(`${l}-cstm-btn-target`, { + menuItems: [ + { + index: 0, + disabled: false, + text: "Menu option 1", + icon: "x-fal fa-angle-right" + }, + { + index: 1, + disabled: false, + text: "Menu option 2", + icon: "x-fal fa-angle-right" + } + ] + }); + break; + } + }, + payload: [] + } + ] + }, + { + elementId: `${l}-cstm-btn-target`, + icon: "x-fal fa-dot-circle", + text: "Target", + location: l, + type: "button", + menu: [ + { + text: "Menu option 1", + icon: "x-fal fa-angle-right" + }, + { + text: "Menu option 2", + icon: "x-fal fa-angle-right" + } + ] + }, + { + elementId: `${l}-cstm-btn1`, + icon: "x-fal fa-info-circle", + text: "`\"'~!@#$%^&*()_+-=:?/><;,.\\|ăîâșț", + location: l, + type: "button" + }, + { + elementId: `${l}-cstm-btn2`, + icon: "x-fal fa-info-circle", + text: "Long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long text", + location: l, + type: "button", + menu: [ + { + text: "Long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long text" + }, + { + text: "Some text" + }, + { + separator: true + }, + { + text: "`\"'~!@#$%^&*()_+-=:?/><;,.\\|ăîâșț" + } + ] + }, + { + elementId: `${l}-cstm-btn3`, + icon: "x-fal fa-info-circle", + text: "Long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long text", + location: l, + type: "button" + }, + { + elementId: `${l}-cstm-btn4`, + icon: "x-fal fa-info-circle", + text: "Long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long link", + location: l, + type: "button", + isLink: true, + href: "mailto:api.extensibility.team@rws.com" + } + ) +); + +// extra containers for LTLC-85185 +const renderCounter: any = {}; +const renderContent = ( + type: ElementType, + detail: ExtensibilityEventDetail, + elementId: string +) => { + renderCounter[elementId]++; + const container = document.getElementById(detail.domElementId); + if (container) { + // remove content for rerenders + container.innerHTML = ""; + const elem = document.createElement("div"); + const imgSize = type === "sidebarBox" ? "500x500" : "2000x2000"; + const imgWidthHight = type === "sidebarBox" ? "500" : "2000"; + elem.innerHTML = `

Custom element rendered ${renderCounter[elementId]} times.

`; + elem.innerHTML += "`\"'~!@#$%^&*()_+-=:?/><;,.\\|ăîâșț"; + elem.innerHTML += `

LongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaksLongTextWithNoBreaks

`; + elem.innerHTML += ``; + + if (type === "tab") { + elem.className = "x-panel-header-title-light-framed"; + elem.setAttribute("style", "margin-bottom: 10px"); + container.style.position = "relative"; + } + + // add new content + container.appendChild(elem); + } +}; + +const allPanelLocations = [ + // projects + "project-details-dashboard-main", + // task-inbox + "task-details-main" +]; + +allPanelLocations.forEach(l => { + renderCounter[`${l}-cstm-pnl`] = 0; + elements.push({ + elementId: `${l}-cstm-pnl`, + text: "Custom Panel", + // @ts-ignore + location: l, + type: "panel", + actions: [ + { + eventType: "onrender", + eventHandler: (detail: ExtensibilityEventDetail) => { + renderContent("panel", detail, `${l}-cstm-pnl`); + + trados.updateElement( + `${l}-cstm-pnl`, + // todo: when publishing new public package version, use "title" for containers instead of "text" + { + text: "(updated `\"'~!@#$%^&*()_+-=:?/><;,.\\|ăîâșț) Custom Panel with extra long long long long long long long long long long long long long long long long long long long long long long long long long long long long text" + } + //update: { hidden: true } + ); + }, + payload: [] + } + ] + }); +}); + +const allTabLocations = [ + // projects + "project-details-tabpanel", + // task-inbox + "task-tabpanel" +]; + +allTabLocations.forEach(l => { + renderCounter[`${l}-cstm-tab`] = 0; + elements.push({ + elementId: `${l}-cstm-tab`, + text: "Custom Tab", + // @ts-ignore + location: l, + type: "tab", + actions: [ + { + eventType: "onrender", + eventHandler: (detail: ExtensibilityEventDetail) => { + renderContent("tab", detail, `${l}-cstm-tab`); + + trados.updateElement( + `${l}-cstm-tab`, + // todo: when publishing new public package version, use "title" for containers instead of "text" + { + text: "(updated `\"'~!@#$%^&*()_+-=:?/><;,.\\|ăîâșț) Custom Tab with extra long long long long long long long long long long long long long long long long long long long long long long long long long long long long text" + } + //update: { hidden: true } + ); + }, + payload: [] + } + ] + }); +}); + +const allSidebarBoxLocations = [ + // projects + "project-details-dashboard-sidebar", + "project-details-task-history-sidebar", + // task-inbox + "new-tasks-list-sidebar", + "active-tasks-list-sidebar", + "completed-tasks-list-sidebar", + "task-sidebar" +]; + +allSidebarBoxLocations.forEach(l => { + renderCounter[`${l}-cstm-sb`] = 0; + elements.push({ + elementId: `${l}-cstm-sb`, + text: "Custom Sidebar Box", + // @ts-ignore + location: l, + type: "sidebarBox", + actions: [ + { + eventType: "onrender", + eventHandler: (detail: ExtensibilityEventDetail) => { + renderContent("sidebarBox", detail, `${l}-cstm-sb`); + + trados.updateElement( + `${l}-cstm-sb`, + // todo: when publishing new public package version, use "title" for containers instead of "text" + { + text: "(updated `\"'~!@#$%^&*()_+-=:?/><;,.\\|ăîâșț) Custom Sidebar Box with extra long long long long long long long long long long long long long text" + } + //update: { hidden: true } + ); + }, + payload: [] + } + ] + }); +}); +*/ + +// onReady function calls publish("register", configWithElementsAndEventHandlers) +// then, once registered, performs callback function passing extensionKey, tenant and token as registrationResult arg +trados.onReady(elements, () => { + // extension registered + // extensionKey retrieved for identification if events communication + // tenant & token available for API calls + console.log("[UI Extensibility] [extension] Extension registered."); +}); + +console.log( + "[UI Extensibility] [extension] Register request event published. External script loaded." +); diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/package.json b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/package.json new file mode 100644 index 0000000..959c064 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/package.json @@ -0,0 +1,23 @@ +{ + "name": "@sdl/frontend-extension", + "version": "1.0.0", + "description": "A frontend extension.", + "main": "index.js", + "sideEffects": false, + "scripts": { + "npm-auth": "npm config set @sdl:registry https://nexus.sdl.com/repository/npm-internal/", + "build-dev": "webpack --progress --mode=development", + "build": "webpack --progress --mode=production" + }, + "author": "SDL", + "license": "MIT", + "dependencies": { + "@sdl/extensibility": "^1.0.0", + "@sdl/extensibility-types": "^1.0.0" + }, + "devDependencies": { + "ts-loader": "9.5.1", + "webpack": "5.91.0", + "webpack-cli": "5.1.4" + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/tsconfig.json b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/tsconfig.json new file mode 100644 index 0000000..251ff03 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "module": "ES6", + "target": "ES5", + "lib": [ "dom", "ES2015" ], + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "types": [] + } +} \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/types.ts b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/types.ts new file mode 100644 index 0000000..b0660c7 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/types.ts @@ -0,0 +1,6 @@ +export type ProjectImportance = { + projectId: string; + pending: boolean; + importance?: "high" | "medium" | "low"; + id?: string; +}; diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/webpack.config.js b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/webpack.config.js new file mode 100644 index 0000000..b89d716 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/frontend/webpack.config.js @@ -0,0 +1,28 @@ +const path = require("path"); + +module.exports = { + entry: "./index.ts", + module: { + rules: [ + { + test: /\.tsx?$/, + use: [ + { + loader: "ts-loader", + options: { + transpileOnly: true, + }, + }, + ], + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: [".tsx", ".ts", ".js"], + }, + output: { + filename: "bundle.js", + path: path.resolve(__dirname, "dist"), + } +}; diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/privacyPolicy.html b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/privacyPolicy.html new file mode 100644 index 0000000..b371d30 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/privacyPolicy.html @@ -0,0 +1,18 @@ +

Privacy Policy for [YOUR SITE TITLE]

+

This is a mock-up content. Please replace it with your Privacy Policy.

+

If you require any more information or have any questions about our privacy policy, please feel free to contact us by email at [CONTACT@YOUREMAIL.COM].

+

At [YOUR SITE URL] we consider the privacy of our visitors to be extremely important. This privacy policy document describes the types of personal information is collected and recorded by [YOUR SITE URL] and how we use it.

+

Log Files
+

Cookies
+

Our Advertising Partners

+

Some of our advertising partners may use cookies on our site. Our advertising partners include …….

+
    +
  • [YOUR ADVERTISING PARTENER]
  • +
+

Third Party Privacy Policies
+

Children's Information
+

Consent
+ By using our website, you hereby consent to our privacy policy and agree to its terms. +

+

Update
This Privacy Policy was last updated on: [LAST UPDATE DATE]. Should we update, amend or make any changes to our privacy policy, those changes will be posted here.

+

\ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/termsAndConditions.html b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/termsAndConditions.html new file mode 100644 index 0000000..df7da8c --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Resources/termsAndConditions.html @@ -0,0 +1,31 @@ +

Terms and Conditions

+

This is a mock-up content. Please replace it with your Terms and Conditions.

+

Last updated: [LAST UPDATE DATE]

+

Please read these terms and conditions carefully before using Our Service.

+

Interpretation and Definitions

+

Interpretation

+

Definitions

+

For the purposes of these Terms and Conditions:

+
    +
  • +

    [USED TERM] [TERM DEFINITION]

    +
  • +
  • +

    [USED TERM] [TERM DEFINITION]

    +
  • +
+

Acknowledgment

+

YOUR ACKNOWLEDGMENT

+

Links to Other Websites

+

Termination

+

Limitation of Liability

+

Governing Law

+

For European Union (EU) Users

+

United States Legal Compliance

+

Translation Interpretation

+

Changes to These Terms and Conditions

+

Contact Us

+

If you have any questions about these Terms and Conditions, You can contact us:

+
    +
  • By visiting this page on our website: [YOUR SITE TITLE].
  • +
\ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Rws.LC.UISampleApp.csproj b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Rws.LC.UISampleApp.csproj new file mode 100644 index 0000000..e184302 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Rws.LC.UISampleApp.csproj @@ -0,0 +1,33 @@ + + + + net8.0 + Linux + + + + + Always + + + + + + + + + + + + + + + Always + + + Always + + + + + diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Services/AccountService.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Services/AccountService.cs new file mode 100644 index 0000000..7924649 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Services/AccountService.cs @@ -0,0 +1,245 @@ +using Rws.LC.UISampleApp.DAL.Entities; +using Rws.LC.UISampleApp.DAL.Entities.Extensions; +using Rws.LC.UISampleApp.Exceptions; +using Rws.LC.UISampleApp.Interfaces; +using Rws.LC.UISampleApp.Models; +using Rws.LC.UISampleApp.Models.Extensions; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Rws.LC.UISampleApp.Services +{ + /// + /// Defines a service that allows creation and manipulation of account related data. + /// + public class AccountService : IAccountService + { + public AccountService(IRepository repository, IAppRegistrationRepository appRegistrationRepository, IDescriptorService descriptorService) + { + _repository = repository; + _appRegistrationRepository = appRegistrationRepository; + _descriptorService = descriptorService; + } + + private IRepository _repository; + private readonly IAppRegistrationRepository _appRegistrationRepository; + private IDescriptorService _descriptorService; + + /// + /// The const string to be used for masking secrets. + /// + private const string SecretMask = "*****"; + + /// + public async Task SaveRegistrationInfo(RegisteredEvent registeredEvent, CancellationToken cancellationToken) + { + if (string.IsNullOrEmpty(registeredEvent.ClientCredentials?.ClientId)) + { + throw new AppValidationException($"Invalid {nameof(registeredEvent.ClientCredentials.ClientId)} provided.", new Details { Code = ErrorCodes.InvalidInput, Name = nameof(registeredEvent.ClientCredentials.ClientId), Value = null }); + } + + if (string.IsNullOrEmpty(registeredEvent.ClientCredentials?.ClientSecret)) + { + throw new AppValidationException($"Invalid {nameof(registeredEvent.ClientCredentials.ClientSecret)} provided.", new Details { Code = ErrorCodes.InvalidInput, Name = nameof(registeredEvent.ClientCredentials.ClientSecret), Value = null }); + } + + AppRegistrationEntity appRegistrationEntity = new AppRegistrationEntity() + { + ClientCredentials = registeredEvent.ClientCredentials.ToEntity() + }; + + var appRegistration = await _appRegistrationRepository.GetRegistrationInfo().ConfigureAwait(false); + if (appRegistration != null) + { + throw new DoubleRegistrationException(); + } + + await _appRegistrationRepository.SaveRegistrationInfo(appRegistrationEntity).ConfigureAwait(false); + } + + /// + public async Task RemoveRegistrationInfo(CancellationToken cancellationToken) + { + await _appRegistrationRepository.RemoveRegistrationInfo().ConfigureAwait(false); + } + + /// + public async Task SaveAccountInfo(string tenantId, CancellationToken cancellationToken) + { + if (string.IsNullOrEmpty(tenantId)) + { + throw new AppValidationException($"Invalid {nameof(tenantId)} provided.", new Details { Code = ErrorCodes.InvalidInput, Name = nameof(tenantId), Value = null }); + } + + AccountInfoEntity accountInfoEntity = new AccountInfoEntity() + { + TenantId = tenantId + }; + + var accountInfo = await _repository.GetAccountInfoByTenantId(tenantId).ConfigureAwait(false); + if (accountInfo != null) + { + return; + } + + await _repository.SaveAccount(accountInfoEntity).ConfigureAwait(false); + } + + /// + public async Task RemoveAccountInfo(string tenantId, CancellationToken cancellationToken) + { + await _repository.RemoveAccount(tenantId).ConfigureAwait(false); + } + + /// + public async Task RemoveAccounts(CancellationToken cancellationToken) + { + await _repository.RemoveAccounts().ConfigureAwait(false); + } + + /// + public async Task GetConfigurationSettings(string tenantId, CancellationToken cancellationToken) + { + var accountInfo = await _repository.GetAccountInfoByTenantId(tenantId).ConfigureAwait(false); + if (accountInfo == null) + { + throw new AccountValidationException($"Account {tenantId} is not installed!", new Details { Code = ErrorCodes.AccountNotInstalled, Name = nameof(tenantId), Value = tenantId }); + } + + if (accountInfo.ConfigurationValues == null) + { + return new ConfigurationSettingsResult(new List()); + } + + return MaskSecretConfigurations(accountInfo.ConfigurationValues); + } + + /// + public async Task SaveOrUpdateConfigurationSettings(string tenantId, List configurationValues, CancellationToken cancellationToken) + { + AccountInfoEntity accountInfo = await _repository.GetAccountInfoByTenantId(tenantId).ConfigureAwait(false); + if (accountInfo == null) + { + throw new AccountValidationException($"Account {tenantId} is not installed!", new Details { Code = ErrorCodes.AccountNotInstalled, Name = nameof(tenantId), Value = tenantId }); + } + + accountInfo = UpdateConfigurationsForAccount(accountInfo, configurationValues); + var updatedAccountInfoEntity = await _repository.SaveOrUpdateConfigurationSettings(accountInfo).ConfigureAwait(false); + + return MaskSecretConfigurations(updatedAccountInfoEntity.ConfigurationValues); + } + + /// + public async Task ValidateConfigurationSettings(string tenantId, CancellationToken cancellationToken) + { + var accountInfo = await _repository.GetAccountInfoByTenantId(tenantId).ConfigureAwait(false); + if (accountInfo == null) + { + throw new AccountValidationException($"Account {tenantId} is not installed!", new Details { Code = ErrorCodes.AccountNotInstalled, Name = nameof(tenantId), Value = tenantId }); + } + + var configurations = accountInfo.ConfigurationValues; + VerifyNoInvalidValues(configurations); + VerifyNoInvalidKeys(configurations); + VerifyNoNullValues(configurations); + VerifySetup(); + } + + /// + /// Updates the configurations for an account. + /// + /// The account information. + /// The configuration values. + /// The updated account info entity. + private AccountInfoEntity UpdateConfigurationsForAccount(AccountInfoEntity accountInfo, List configurationValues) + { + if (accountInfo.ConfigurationValues == null) + { + accountInfo.ConfigurationValues = configurationValues.ToEntity(); + } + else + { + foreach (var config in configurationValues) + { + var matchedItem = accountInfo.ConfigurationValues.FirstOrDefault(f => f.Id == config.Id); + if (matchedItem == null) + { + accountInfo.ConfigurationValues.Add(config.ToEntity()); + } + else + { + matchedItem.Value = config.Value; + } + } + } + + return accountInfo; + } + + + + /// + /// Masks the secret configuration values. + /// + /// A list of configurations + /// + private ConfigurationSettingsResult MaskSecretConfigurations(List configurations) + { + var secretConfigurationIds = _descriptorService.GetSecretConfigurations(); + + foreach (var config in configurations.Where(config => secretConfigurationIds.Contains(config.Id))) + { + if (config.Value != null) + { + config.Value = SecretMask; + } + } + + return new ConfigurationSettingsResult(configurations.ToModel()); + } + + private void VerifyNoInvalidValues(List configurations) + { + List
errorDetails = new List
(); + //Details errorDetail = new Details() { Name = "name", Code = ErrorCodes.InvalidValue, Value = "value" }; + //errorDetails.Add(errorDetail); + + if (errorDetails.Any()) + { + throw new ConfigurationValidationException(ErrorMessages.InvalidValueMessage, errorDetails.ToArray()); + } + } + + private void VerifyNoInvalidKeys(List configurations) + { + List
errorDetails = new List
(); + //Details errorDetail = new Details() { Name = "name", Code = ErrorCodes.InvalidKey, Value = "key" }; + //errorDetails.Add(errorDetail); + + if (errorDetails.Any()) + { + throw new ConfigurationValidationException(ErrorMessages.InvalidKeyMessage, errorDetails.ToArray()); + } + } + + private void VerifyNoNullValues(List configurations) + { + List
errorDetails = new List
(); + //Details errorDetail = new Details() { Name = "name", Code = ErrorCodes.NullValue, Value = null }; + //errorDetails.Add(errorDetail); + + if (errorDetails.Any()) + { + throw new ConfigurationValidationException(ErrorMessages.NullValueMessage, errorDetails.ToArray()); + } + } + + private void VerifySetup() + { + //how to send an error exemple: + //throw new SetupValidationException(ErrorMessages.InvalidSetupMessage, new Details[] { }); + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Services/DescriptorService.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Services/DescriptorService.cs new file mode 100644 index 0000000..049c39f --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Services/DescriptorService.cs @@ -0,0 +1,64 @@ +using Rws.LC.UISampleApp.Enums; +using Rws.LC.UISampleApp.Interfaces; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.Json.Nodes; + +namespace Rws.LC.UISampleApp.Services +{ + /// + /// Used to return the app descriptor + /// + public class DescriptorService : IDescriptorService + { + /// + /// Initializes a new instance of the class. + /// + public DescriptorService() + { + // Reading from the descriptor.json file, the descriptor for this app. + // Customize it to represent your app behavior. + string descriptorText = File.ReadAllText("descriptor.json"); + _appDescriptor = JsonNode.Parse(descriptorText); + } + + /// + /// The app descriptor. + /// + private readonly JsonNode _appDescriptor; + + /// + /// The secret data type. + /// + private const DataTypeEnum SecretDataType = DataTypeEnum.secret; + + /// + /// The secret mask const string. + /// + private const string SecretMask = "*****"; + + /// + /// Gets the descriptor. + /// + /// + public JsonNode GetDescriptor() + { + foreach (var configuration in _appDescriptor["configurations"].AsArray().Where(c => c["dataType"].ToString() == SecretDataType.ToString())) + { + configuration["defaultValue"] = SecretMask; + } + + return _appDescriptor; + } + + /// + /// Gets the secret configurations ids. + /// + /// + public List GetSecretConfigurations() + { + return _appDescriptor["configurations"].AsArray().Where(c => c["dataType"].ToString() == SecretDataType.ToString()).Select(s => s["id"].ToString()).ToList(); + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Services/HealthReporter.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Services/HealthReporter.cs new file mode 100644 index 0000000..f00eb20 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Services/HealthReporter.cs @@ -0,0 +1,46 @@ +using Rws.LC.UISampleApp.Interfaces; +using System; + +namespace Rws.LC.UISampleApp.Services +{ + /// + /// Used to check whether the service is healthy. + /// + public class HealthReporter : IHealthReporter + { + /// + /// The database context. + /// + private readonly IDatabaseContext _dbContext; + + /// + /// Initializes a new instance of the class. + /// + /// The database context. + public HealthReporter(IDatabaseContext databaseContext) + { + _dbContext = databaseContext; + } + + /// + /// Verifies if the database connection is healthy. + /// + /// True if the connection is healthy. + public bool IsServiceHealthy() + { + try + { + if (_dbContext.IsConnectionHealthy()) + { + return true; + } + + return false; + } + catch (Exception) + { + return false; + } + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Startup.cs b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Startup.cs new file mode 100644 index 0000000..8da1ce8 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/Startup.cs @@ -0,0 +1,151 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using MongoDB.Bson.Serialization; +using Rws.LanguageCloud.Authentication.Jws; +using Rws.LC.UISampleApp.DAL; +using Rws.LC.UISampleApp.Exceptions; +using Rws.LC.UISampleApp.Helpers; +using Rws.LC.UISampleApp.Interfaces; +using Rws.LC.UISampleApp.Services; +using System.Net; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Rws.LC.UISampleApp +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddControllers().AddJsonOptions(opts => + { + // only for system.text + opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); + opts.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; + opts.JsonSerializerOptions.PropertyNameCaseInsensitive = true; + opts.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; + }); + + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + + // this ensures that the services are started and stopped concurrently + services.Configure(options => + { + options.ServicesStartConcurrently = true; + options.ServicesStopConcurrently = true; + }); + + // Set CORS based on settings + var isCorsEnabled = Configuration.GetValue("Cors:Enable"); + + if (isCorsEnabled) + { + services.AddCors(); + } + + services.AddAuthentication(JwsDefaults.AuthenticationScheme) + .AddJws(options => + { + //that is not implemented yet: + //options.TokenValidationParameters.RequireSignedTokens = Configuration["ASPNETCORE_ENVIRONMENT"] != "Development"; + options.JwksUri = Configuration["Authorization:JwksUri"]; + options.TokenValidationParameters.ValidIssuer = Configuration["Authorization:Issuer"]; + options.TokenValidationParameters.ValidAudience = Configuration["baseUrl"]; + }); + + BsonSerializer.RegisterSerializationProvider(new JsonNodeSerializerProvider()); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + var isCorsEnabled = Configuration.GetValue("Cors:Enable"); + if (isCorsEnabled) + { + var allowOrigins = Configuration.GetValue("Cors:AllowOrigins"); + app.UseCors(options => options.WithOrigins(allowOrigins).AllowAnyHeader().AllowAnyMethod()); + } + + // This is required for intercepting the request body in validating the request signatures + app.Use(next => context => + { + context.Request.EnableBuffering(); + return next(context); + }); + + app.UseHttpsRedirection(); + + app.UseExceptionHandler(appError => + { + appError.Run(async context => + { + context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; + context.Response.ContentType = "application/json"; + + var contextFeature = context.Features.Get(); + if (contextFeature != null) + { + string message; + + if (contextFeature.Error is AppException) + { + var exception = (AppException)contextFeature.Error; + + context.Response.StatusCode = (int)exception.StatusCode; + message = JsonSerializer.Serialize(new + { + message = exception.Message, + errorCode = exception.ErrorCode, + details = exception.ExceptionDetails + }, JsonSettings.Default()); + } + else + { + message = JsonSerializer.Serialize(new + { + errorCode = ErrorCodes.InternalError, + message = contextFeature.Error.Message, + }, JsonSettings.Default()); + } + + await context.Response.WriteAsync(message).ConfigureAwait(false); + } + }); + }); + + app.UseRouting(); + + app.UseAuthentication(); + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/appsettings.Development.json b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/appsettings.Development.json new file mode 100644 index 0000000..3e2508b --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + //"Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/appsettings.json b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/appsettings.json new file mode 100644 index 0000000..ff5403c --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/appsettings.json @@ -0,0 +1,28 @@ +{ + "Logging": { + "LogLevel": { + //"Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + + "Authorization": { + "JwksUri": "https://lc-api.sdl.com/public-api/v1/.well-known/jwks.json", + "Issuer": "https://languagecloud.rws.com/" + }, + + "baseUrl": "TODO: replace with a proper URL", + + "Cors": { + "Enable": "true", + "AllowOrigins": "*" + }, + + "AllowedHosts": "*", + "documentationUrl": "docUrl", + "MongoDb": { + "Connection": "mongodb://localhost:27017", + "Name": "lc-ui-sample-app" + } +} \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/descriptor.json b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/descriptor.json new file mode 100644 index 0000000..50aa297 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/descriptor.json @@ -0,0 +1,45 @@ +{ + "name": "UI Sample App", + "version": "1.0.0", + "description": "Provides UI extensibility.", + "extensions": [ + { + "id": "SAMPLE_UI_EXTENSION_ID", + "extensionPointId": "lc.ui", + "name": "UI Extensibility App", + "description": "UI Extensibility in Inbox and Projects", + "extensionPointVersion": "1", + "configuration": { + "scriptPath": "/api/files/frontend/dist/bundle.js", + "endpoints": {} + } + } + ], + "standardEndpoints": { + "health": "/v1/health", + "documentation": "/v1/documentation", + "appLifecycle": "/v1/app-lifecycle", + "configuration": "/v1/configuration", + "configurationValidation": "/v1/configuration/validation", + "privacyPolicy": "/v1/privacyPolicy", + "termsAndConditions": "/v1/termsAndConditions" + }, + "configurations": [ + { + "name": "SAMPLE_CONFIG_NAME", + "id": "SAMPLE_CONFIG_ID", + "description": "SAMPLE_CONFIG_DESCRIPTION", + "optional": false, + "dataType": "string", + "defaultValue": "default config" + } + ], + "releaseNotes": "Initial plugin", + "minimumVersion": "1.0.0", + "vendor": { + "name": "SAMPLE_VENDOR_NAME", + "url": "SAMPLE_VENDOR_URL", + "email": "sample_vendor@email.com" + }, + "descriptorVersion": "1.4" +} \ No newline at end of file diff --git a/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/nlog.config b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/nlog.config new file mode 100644 index 0000000..5ed8d67 --- /dev/null +++ b/samples/dotnet/UISampleApp/Rws.LC.UISampleApp/nlog.config @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file