Compare commits
83 Commits
73eb270237
...
feat/envel
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
891f6368f1 | ||
|
|
e6011b6201 | ||
|
|
8b86114998 | ||
|
|
c20b115faf | ||
|
|
2c8ccd3e7c | ||
|
|
b1f771c320 | ||
|
|
425645a610 | ||
|
|
24e6ffc5ef | ||
|
|
1dd9ce6bbc | ||
|
|
e528fa6409 | ||
|
|
6440dd09d1 | ||
|
|
869493bd97 | ||
|
|
1cb9042736 | ||
|
|
c9410a1e2e | ||
|
|
c4f0ce7d4b | ||
|
|
dc83486032 | ||
|
|
2a64091c87 | ||
|
|
f65f749208 | ||
|
|
0b6ed00062 | ||
|
|
e87c976e19 | ||
|
|
f31ece3a59 | ||
|
|
cfd08602ab | ||
|
|
4b7152b272 | ||
|
|
5117a66c81 | ||
|
|
83794d4bbc | ||
|
|
76f74778b4 | ||
|
|
ded3425e31 | ||
|
|
738b379fe5 | ||
|
|
cf8b28441f | ||
|
|
0eb5897185 | ||
|
|
25cd1601a6 | ||
|
|
42e4d110ad | ||
|
|
2538f34892 | ||
|
|
3ce11f4cc7 | ||
|
|
f2cd34a79e | ||
|
|
5f923ad485 | ||
|
|
8f70f085d3 | ||
|
|
d6c09ed31a | ||
|
|
7d3ee1331d | ||
|
|
cd5b90a1e2 | ||
|
|
ac861f5fa0 | ||
|
|
c1d8f817bb | ||
|
|
da28a7332b | ||
|
|
bfd4e6a8ed | ||
|
|
b4e0e4b6b2 | ||
|
|
e37caf5c8f | ||
|
|
e95cf24af7 | ||
|
|
524a72caa0 | ||
|
|
1919c562cc | ||
|
|
62b54d6e75 | ||
|
|
efa9160c04 | ||
|
|
bc6955055a | ||
|
|
dc997d5ff2 | ||
|
|
a32f495038 | ||
|
|
210466883c | ||
|
|
728385b70a | ||
|
|
792aa0b922 | ||
|
|
6847b74095 | ||
|
|
54e86b421c | ||
|
|
370666cb0e | ||
|
|
e17f7df930 | ||
|
|
0e91df7acc | ||
|
|
ad26230da5 | ||
|
|
a103f34230 | ||
|
|
806bd3b248 | ||
|
|
c69c39fa44 | ||
|
|
b6badb44af | ||
|
|
b2195ce13f | ||
|
|
f3cb9b8510 | ||
|
|
8edfecb9dc | ||
|
|
c123d103bb | ||
|
|
b92d9da387 | ||
|
|
8841698aab | ||
|
|
6f140f16cd | ||
|
|
8bfd31997b | ||
|
|
4a1459d708 | ||
|
|
361bdeb2b2 | ||
|
|
9ce5af7cd0 | ||
|
|
84fa9e6e7c | ||
|
|
36916ed5c8 | ||
|
|
fb366d3e0b | ||
|
|
e82be8b6a5 | ||
|
|
07320af4ee |
@@ -0,0 +1,13 @@
|
|||||||
|
namespace EnvelopeGenerator.Application.Configurations
|
||||||
|
{
|
||||||
|
public class DispatcherConfig
|
||||||
|
{
|
||||||
|
public int SendingProfile { get; init; } = 1;
|
||||||
|
|
||||||
|
public string AddedWho { get; init; } = "DDEnvelopGenerator";
|
||||||
|
|
||||||
|
public int ReminderTypeId { get; init; } = 202377;
|
||||||
|
|
||||||
|
public string EmailAttmt1 { get; init; } = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace EnvelopeGenerator.Application.Configurations
|
||||||
|
{
|
||||||
|
public class MailConfig
|
||||||
|
{
|
||||||
|
public required Dictionary<string, string> Placeholders { get; init; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using DigitalData.Core.DTO;
|
using DigitalData.Core.DTO;
|
||||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
|
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
|
||||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||||
|
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
|
||||||
using EnvelopeGenerator.Common;
|
using EnvelopeGenerator.Common;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Contracts
|
namespace EnvelopeGenerator.Application.Contracts
|
||||||
@@ -8,6 +9,9 @@ namespace EnvelopeGenerator.Application.Contracts
|
|||||||
public interface IEnvelopeMailService : IEmailOutService
|
public interface IEnvelopeMailService : IEmailOutService
|
||||||
{
|
{
|
||||||
Task<DataResult<int>> SendAsync(EnvelopeReceiverDto envelopeReceiverDto, Constants.EmailTemplateType tempType);
|
Task<DataResult<int>> SendAsync(EnvelopeReceiverDto envelopeReceiverDto, Constants.EmailTemplateType tempType);
|
||||||
|
|
||||||
|
Task<DataResult<int>> SendAsync(EnvelopeReceiverReadOnlyDto dto);
|
||||||
|
|
||||||
Task<DataResult<int>> SendAccessCodeAsync(EnvelopeReceiverDto envelopeReceiverDto);
|
Task<DataResult<int>> SendAccessCodeAsync(EnvelopeReceiverDto envelopeReceiverDto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using DigitalData.Core.Abstractions.Application;
|
||||||
|
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
|
||||||
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.Contracts
|
||||||
|
{
|
||||||
|
public interface IEnvelopeReceiverReadOnlyService : ICRUDService<EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnlyDto, EnvelopeReceiverReadOnlyUpdateDto, EnvelopeReceiverReadOnly, long>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +1,18 @@
|
|||||||
using DigitalData.UserManager.Application.MappingProfiles;
|
using DigitalData.UserManager.Application.MappingProfiles;
|
||||||
using EnvelopeGenerator.Application.Contracts;
|
using EnvelopeGenerator.Application.Contracts;
|
||||||
using EnvelopeGenerator.Application.MappingProfiles;
|
using EnvelopeGenerator.Application.MappingProfiles;
|
||||||
|
using EnvelopeGenerator.Application.Configurations;
|
||||||
using EnvelopeGenerator.Application.Services;
|
using EnvelopeGenerator.Application.Services;
|
||||||
using EnvelopeGenerator.Infrastructure.Contracts;
|
using EnvelopeGenerator.Infrastructure.Contracts;
|
||||||
using EnvelopeGenerator.Infrastructure.Repositories;
|
using EnvelopeGenerator.Infrastructure.Repositories;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application
|
namespace EnvelopeGenerator.Application
|
||||||
{
|
{
|
||||||
public static class DIExtensions
|
public static class DIExtensions
|
||||||
{
|
{
|
||||||
public static IServiceCollection AddEnvelopeGenerator(this IServiceCollection services)
|
public static IServiceCollection AddEnvelopeGenerator(this IServiceCollection services, IConfiguration dispatcherConfigSection, IConfiguration mailConfigSection)
|
||||||
{
|
{
|
||||||
//Inject CRUD Service and repositoriesad
|
//Inject CRUD Service and repositoriesad
|
||||||
services.AddScoped<IConfigRepository, ConfigRepository>();
|
services.AddScoped<IConfigRepository, ConfigRepository>();
|
||||||
@@ -33,6 +30,7 @@ namespace EnvelopeGenerator.Application
|
|||||||
services.AddScoped<IEnvelopeTypeRepository, EnvelopeTypeRepository>();
|
services.AddScoped<IEnvelopeTypeRepository, EnvelopeTypeRepository>();
|
||||||
services.AddScoped<IReceiverRepository, ReceiverRepository>();
|
services.AddScoped<IReceiverRepository, ReceiverRepository>();
|
||||||
services.AddScoped<IUserReceiverRepository, UserReceiverRepository>();
|
services.AddScoped<IUserReceiverRepository, UserReceiverRepository>();
|
||||||
|
services.AddScoped<IEnvelopeReceiverReadOnlyRepository, EnvelopeReceiverReadOnlyRepository>();
|
||||||
services.AddScoped<IConfigService, ConfigService>();
|
services.AddScoped<IConfigService, ConfigService>();
|
||||||
services.AddScoped<IDocumentReceiverElementService, DocumentReceiverElementService>();
|
services.AddScoped<IDocumentReceiverElementService, DocumentReceiverElementService>();
|
||||||
services.AddScoped<IEnvelopeDocumentService, EnvelopeDocumentService>();
|
services.AddScoped<IEnvelopeDocumentService, EnvelopeDocumentService>();
|
||||||
@@ -46,12 +44,20 @@ namespace EnvelopeGenerator.Application
|
|||||||
services.AddScoped<IEnvelopeTypeService, EnvelopeTypeService>();
|
services.AddScoped<IEnvelopeTypeService, EnvelopeTypeService>();
|
||||||
services.AddScoped<IReceiverService, ReceiverService>();
|
services.AddScoped<IReceiverService, ReceiverService>();
|
||||||
services.AddScoped<IUserReceiverService, UserReceiverService>();
|
services.AddScoped<IUserReceiverService, UserReceiverService>();
|
||||||
|
services.AddScoped<IEnvelopeReceiverReadOnlyService, EnvelopeReceiverReadOnlyService>();
|
||||||
|
|
||||||
//Auto mapping profiles
|
//Auto mapping profiles
|
||||||
services.AddAutoMapper(typeof(BasicDtoMappingProfile).Assembly);
|
services.AddAutoMapper(typeof(BasicDtoMappingProfile).Assembly);
|
||||||
services.AddAutoMapper(typeof(UserMappingProfile).Assembly);
|
services.AddAutoMapper(typeof(UserMappingProfile).Assembly);
|
||||||
|
|
||||||
|
services.Configure<DispatcherConfig>(dispatcherConfigSection);
|
||||||
|
services.Configure<MailConfig>(mailConfigSection);
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddEnvelopeGenerator(this IServiceCollection services, IConfiguration config) => services.AddEnvelopeGenerator(
|
||||||
|
dispatcherConfigSection: config.GetSection("DispatcherConfig"),
|
||||||
|
mailConfigSection: config.GetSection("MailConfig"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
||||||
|
{
|
||||||
|
public record EnvelopeReceiverReadOnlyCreateDto(
|
||||||
|
DateTime DateValid)
|
||||||
|
{
|
||||||
|
[EmailAddress]
|
||||||
|
[Required]
|
||||||
|
public required string ReceiverMail { get; init; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public long? EnvelopeId { get; set; } = null;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public string? AddedWho { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public DateTime AddedWhen { get; } = DateTime.Now;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
||||||
|
{
|
||||||
|
public record EnvelopeReceiverReadOnlyDto(
|
||||||
|
long Id,
|
||||||
|
long EnvelopeId,
|
||||||
|
string ReceiverMail,
|
||||||
|
DateTime DateValid,
|
||||||
|
DateTime AddedWhen,
|
||||||
|
string AddedWho,
|
||||||
|
EnvelopeDto? Envelope = null,
|
||||||
|
string? ChangedWho = null,
|
||||||
|
DateTime? ChangedWhen = null,
|
||||||
|
ReceiverReadDto? Receiver = null);
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using DigitalData.Core.Abstractions;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
||||||
|
{
|
||||||
|
public record EnvelopeReceiverReadOnlyUpdateDto(
|
||||||
|
long Id,
|
||||||
|
DateTime DateValid,
|
||||||
|
string ChangedWho) : IUnique<long>
|
||||||
|
{
|
||||||
|
public DateTime ChangedWhen { get; } = DateTime.Now;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
namespace EnvelopeGenerator.Application
|
|
||||||
{
|
|
||||||
public class DispatcherConfig
|
|
||||||
{
|
|
||||||
public int SendingProfile { get; init; } = 1;
|
|
||||||
|
|
||||||
public string AddedWho { get; init; } = "DDEnvelopGenerator";
|
|
||||||
|
|
||||||
public int ReminderTypeId { get; init; } = 202377;
|
|
||||||
|
|
||||||
public string EmailAttmt1 { get; init; } = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\EnvelopeGenerator.Extensions\EnvelopeGenerator.Extensions.csproj" />
|
||||||
<ProjectReference Include="..\EnvelopeGenerator.Infrastructure\EnvelopeGenerator.Infrastructure.csproj" />
|
<ProjectReference Include="..\EnvelopeGenerator.Infrastructure\EnvelopeGenerator.Infrastructure.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using EnvelopeGenerator.Application.DTOs;
|
using EnvelopeGenerator.Application.DTOs;
|
||||||
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
|
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
|
||||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||||
|
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
|
||||||
using EnvelopeGenerator.Application.DTOs.Receiver;
|
using EnvelopeGenerator.Application.DTOs.Receiver;
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
|
|
||||||
@@ -28,6 +29,7 @@ namespace EnvelopeGenerator.Application.MappingProfiles
|
|||||||
CreateMap<Receiver, ReceiverCreateDto>();
|
CreateMap<Receiver, ReceiverCreateDto>();
|
||||||
CreateMap<Receiver, ReceiverUpdateDto>();
|
CreateMap<Receiver, ReceiverUpdateDto>();
|
||||||
CreateMap<UserReceiver, UserReceiverDto>();
|
CreateMap<UserReceiver, UserReceiverDto>();
|
||||||
|
CreateMap<EnvelopeReceiverReadOnly, EnvelopeReceiverReadOnlyDto>();
|
||||||
|
|
||||||
// DTO to Entity mappings
|
// DTO to Entity mappings
|
||||||
CreateMap<ConfigDto, Config>();
|
CreateMap<ConfigDto, Config>();
|
||||||
@@ -46,6 +48,8 @@ namespace EnvelopeGenerator.Application.MappingProfiles
|
|||||||
CreateMap<ReceiverUpdateDto, Receiver>();
|
CreateMap<ReceiverUpdateDto, Receiver>();
|
||||||
CreateMap<UserReceiverDto, UserReceiver>();
|
CreateMap<UserReceiverDto, UserReceiver>();
|
||||||
CreateMap<EnvelopeReceiverBase, EnvelopeReceiverBasicDto>();
|
CreateMap<EnvelopeReceiverBase, EnvelopeReceiverBasicDto>();
|
||||||
|
CreateMap<EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnly>();
|
||||||
|
CreateMap<EnvelopeReceiverReadOnlyUpdateDto, EnvelopeReceiverReadOnly>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,6 +177,9 @@
|
|||||||
<data name="LockedTitle" xml:space="preserve">
|
<data name="LockedTitle" xml:space="preserve">
|
||||||
<value>Dokument erfordert einen Zugriffscode</value>
|
<value>Dokument erfordert einen Zugriffscode</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ReadOnlyMessage" xml:space="preserve">
|
||||||
|
<value>Weitergeleitet von {0}. Gültig bis {1}.</value>
|
||||||
|
</data>
|
||||||
<data name="Reject" xml:space="preserve">
|
<data name="Reject" xml:space="preserve">
|
||||||
<value>Ablehnen</value>
|
<value>Ablehnen</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -177,6 +177,9 @@
|
|||||||
<data name="LockedTitle" xml:space="preserve">
|
<data name="LockedTitle" xml:space="preserve">
|
||||||
<value>Document requires an access code</value>
|
<value>Document requires an access code</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ReadOnlyMessage" xml:space="preserve">
|
||||||
|
<value>Forwarded by {0}. Valid until {1}.</value>
|
||||||
|
</data>
|
||||||
<data name="Reject" xml:space="preserve">
|
<data name="Reject" xml:space="preserve">
|
||||||
<value>Reject</value>
|
<value>Reject</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ using DigitalData.Core.DTO;
|
|||||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
|
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
|
||||||
using DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut;
|
using DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut;
|
||||||
using DigitalData.EmailProfilerDispatcher.Abstraction.Services;
|
using DigitalData.EmailProfilerDispatcher.Abstraction.Services;
|
||||||
using DigitalData.UserManager.Application;
|
|
||||||
using EnvelopeGenerator.Application.Contracts;
|
using EnvelopeGenerator.Application.Contracts;
|
||||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||||
using EnvelopeGenerator.Common;
|
using EnvelopeGenerator.Common;
|
||||||
using Microsoft.Extensions.Localization;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using static EnvelopeGenerator.Common.Constants;
|
using static EnvelopeGenerator.Common.Constants;
|
||||||
|
using EnvelopeGenerator.Extensions;
|
||||||
|
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
|
||||||
|
using EnvelopeGenerator.Application.Configurations;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Services
|
namespace EnvelopeGenerator.Application.Services
|
||||||
{
|
{
|
||||||
@@ -20,39 +21,50 @@ namespace EnvelopeGenerator.Application.Services
|
|||||||
private readonly IEnvelopeReceiverService _envRcvService;
|
private readonly IEnvelopeReceiverService _envRcvService;
|
||||||
private readonly DispatcherConfig _dConfig;
|
private readonly DispatcherConfig _dConfig;
|
||||||
private readonly IConfigService _configService;
|
private readonly IConfigService _configService;
|
||||||
|
private readonly Dictionary<string, string> _placeholders;
|
||||||
|
|
||||||
public EnvelopeMailService(IEmailOutRepository repository, IStringLocalizer<Resource> localizer, IMapper mapper, IEmailTemplateService tempService, IEnvelopeReceiverService envelopeReceiverService, IOptions<DispatcherConfig> dispatcherConfigOptions, IConfigService configService) : base(repository, mapper)
|
public EnvelopeMailService(IEmailOutRepository repository, IMapper mapper, IEmailTemplateService tempService, IEnvelopeReceiverService envelopeReceiverService, IOptions<DispatcherConfig> dispatcherConfigOptions, IConfigService configService, IOptions<MailConfig> mailConfig) : base(repository, mapper)
|
||||||
{
|
{
|
||||||
_tempService = tempService;
|
_tempService = tempService;
|
||||||
_envRcvService = envelopeReceiverService;
|
_envRcvService = envelopeReceiverService;
|
||||||
_dConfig = dispatcherConfigOptions.Value;
|
_dConfig = dispatcherConfigOptions.Value;
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
|
_placeholders = mailConfig.Value.Placeholders;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: create ioptions and implement TemplatePlaceHolderAttribute instead of this method
|
private async Task<Dictionary<string, string>> CreatePlaceholders(string? accessCode = null, EnvelopeReceiverDto? envelopeReceiverDto = null, EnvelopeReceiverReadOnlyDto? readOnlyDto = null)
|
||||||
private async Task<Dictionary<string, string>> CreatePlaceholders(string? accessCode = null, EnvelopeReceiverDto? envelopeReceiverDto = null)
|
|
||||||
{
|
{
|
||||||
Dictionary<string, string> placeholders = new() {
|
|
||||||
{ "[NAME_PORTAL]", "signFlow" },
|
|
||||||
{ "[SIGNATURE_TYPE]" , "signieren"},
|
|
||||||
{ "[REASON]", string.Empty } };
|
|
||||||
|
|
||||||
if (accessCode is not null)
|
if (accessCode is not null)
|
||||||
placeholders["[DOCUMENT_ACCESS_CODE]"] = accessCode;
|
_placeholders["[DOCUMENT_ACCESS_CODE]"] = accessCode;
|
||||||
|
|
||||||
if(envelopeReceiverDto is not null && envelopeReceiverDto.Envelope is not null && envelopeReceiverDto.Receiver is not null)
|
if(envelopeReceiverDto?.Envelope is not null && envelopeReceiverDto.Receiver is not null)
|
||||||
{
|
{
|
||||||
var erId = (envelopeReceiverDto.Envelope.Uuid, envelopeReceiverDto.Receiver.Signature).EncodeEnvelopeReceiverId();
|
var erId = (envelopeReceiverDto.Envelope.Uuid, envelopeReceiverDto.Receiver.Signature).EncodeEnvelopeReceiverId();
|
||||||
var sigHost = await _configService.ReadDefaultSignatureHost();
|
var sigHost = await _configService.ReadDefaultSignatureHost();
|
||||||
var linkToDoc = $"{sigHost}/envelope/{erId}";
|
var linkToDoc = $"{sigHost}/EnvelopeKey/{erId}";
|
||||||
placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
_placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
||||||
placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)];
|
_placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)] + "..";
|
||||||
}
|
}
|
||||||
|
|
||||||
return placeholders;
|
return _placeholders;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<DataResult<int>> SendAccessCodeAsync(EnvelopeReceiverDto dto) => await SendAsync(dto: dto, tempType: Constants.EmailTemplateType.DocumentAccessCodeReceived);
|
private async Task<Dictionary<string, string>> CreatePlaceholders(EnvelopeReceiverReadOnlyDto? readOnlyDto = null)
|
||||||
|
{
|
||||||
|
if (readOnlyDto?.Envelope is not null && readOnlyDto.Receiver is not null)
|
||||||
|
{
|
||||||
|
_placeholders["[NAME_RECEIVER]"] = await _envRcvService.ReadLastUsedReceiverNameByMail(readOnlyDto.AddedWho).ThenAsync(res => res, (msg, ntc) => string.Empty) ?? string.Empty;
|
||||||
|
var erReadOnlyId = (readOnlyDto.Id).EncodeEnvelopeReceiverId();
|
||||||
|
var sigHost = await _configService.ReadDefaultSignatureHost();
|
||||||
|
var linkToDoc = $"{sigHost}/EnvelopeKey/{erReadOnlyId}";
|
||||||
|
_placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc;
|
||||||
|
_placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)] + "..";
|
||||||
|
}
|
||||||
|
|
||||||
|
return _placeholders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<DataResult<int>> SendAccessCodeAsync(EnvelopeReceiverDto dto) => await SendAsync(dto: dto, tempType: Constants.EmailTemplateType.DocumentAccessCodeReceived);
|
||||||
|
|
||||||
public async Task<DataResult<int>> SendAsync(EnvelopeReceiverDto dto, Constants.EmailTemplateType tempType)
|
public async Task<DataResult<int>> SendAsync(EnvelopeReceiverDto dto, Constants.EmailTemplateType tempType)
|
||||||
{
|
{
|
||||||
@@ -92,8 +104,43 @@ namespace EnvelopeGenerator.Application.Services
|
|||||||
|
|
||||||
var placeholders = await CreatePlaceholders(accessCode: accessCode, envelopeReceiverDto: dto);
|
var placeholders = await CreatePlaceholders(accessCode: accessCode, envelopeReceiverDto: dto);
|
||||||
|
|
||||||
|
//TODO: remove the requirement to add the models using reflections
|
||||||
return await CreateWithTemplateAsync(createDto: mail,placeholders: placeholders,
|
return await CreateWithTemplateAsync(createDto: mail,placeholders: placeholders,
|
||||||
dto, dto.Envelope.User!, dto.Envelope);
|
dto, dto.Envelope.User!, dto.Envelope);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public async Task<DataResult<int>> SendAsync(EnvelopeReceiverReadOnlyDto dto)
|
||||||
|
{
|
||||||
|
var tempSerResult = await _tempService.ReadByNameAsync(Constants.EmailTemplateType.DocumentShared);
|
||||||
|
if (tempSerResult.IsFailed)
|
||||||
|
return tempSerResult.ToFail<int>().Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"The email cannot send because '{Constants.EmailTemplateType.DocumentShared}' template cannot found.");
|
||||||
|
var temp = tempSerResult.Data;
|
||||||
|
|
||||||
|
var mail = new EmailOutCreateDto()
|
||||||
|
{
|
||||||
|
EmailAddress = dto.ReceiverMail,
|
||||||
|
EmailSubj = temp.Subject,
|
||||||
|
EmailBody = temp.Body,
|
||||||
|
//TODO: remove int casting when all
|
||||||
|
ReferenceId = (int) dto.EnvelopeId, //REFERENCE_ID = ENVELOPE_ID
|
||||||
|
ReferenceString = dto.Envelope!.Uuid, //REFERENCE_STRING = ENVELOPE_UUID
|
||||||
|
//receiver_name = receiver.name,
|
||||||
|
//receiver_access_code = receiver.access_code,
|
||||||
|
//sender_adress = envelope.user.email,
|
||||||
|
//sender_name = envelope.user.full_name,
|
||||||
|
//envelope_title = envelope.title,
|
||||||
|
ReminderTypeId = _dConfig.ReminderTypeId,
|
||||||
|
SendingProfile = _dConfig.SendingProfile,
|
||||||
|
EntityId = null,
|
||||||
|
WfId = (int)EnvelopeStatus.EnvelopeShared,
|
||||||
|
WfReference = null,
|
||||||
|
AddedWho = _dConfig.AddedWho,
|
||||||
|
EmailAttmt1 = _dConfig.EmailAttmt1
|
||||||
|
};
|
||||||
|
|
||||||
|
var placeholders = await CreatePlaceholders(readOnlyDto: dto);
|
||||||
|
|
||||||
|
return await CreateWithTemplateAsync(createDto: mail, placeholders: placeholders, dto.Envelope);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using DigitalData.Core.Application;
|
||||||
|
using EnvelopeGenerator.Application.Contracts;
|
||||||
|
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
|
||||||
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
|
using EnvelopeGenerator.Infrastructure.Contracts;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.Services
|
||||||
|
{
|
||||||
|
public class EnvelopeReceiverReadOnlyService : CRUDService<IEnvelopeReceiverReadOnlyRepository, EnvelopeReceiverReadOnlyCreateDto, EnvelopeReceiverReadOnlyDto, EnvelopeReceiverReadOnlyUpdateDto, EnvelopeReceiverReadOnly, long>, IEnvelopeReceiverReadOnlyService
|
||||||
|
{
|
||||||
|
public EnvelopeReceiverReadOnlyService(IEnvelopeReceiverReadOnlyRepository repository, IMapper mapper) : base(repository, mapper)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ using EnvelopeGenerator.Domain.Entities;
|
|||||||
using EnvelopeGenerator.Infrastructure.Contracts;
|
using EnvelopeGenerator.Infrastructure.Contracts;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using EnvelopeGenerator.Extensions;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Services
|
namespace EnvelopeGenerator.Application.Services
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
Public Class Constants
|
Public Class Constants
|
||||||
|
|
||||||
#Region "Status Fields"
|
#Region "Status Fields"
|
||||||
|
'http://wiki.dd/xwiki13/bin/view/Anwendungen/Produkt-Handbuch/Sonstiges/SignFlow/Envelope%20Status/
|
||||||
Public Enum EnvelopeStatus
|
Public Enum EnvelopeStatus
|
||||||
Invalid = 0
|
Invalid = 0
|
||||||
EnvelopeCreated = 1001
|
EnvelopeCreated = 1001
|
||||||
@@ -19,6 +20,8 @@
|
|||||||
DocumentSigned = 2005
|
DocumentSigned = 2005
|
||||||
SignatureConfirmed = 2006
|
SignatureConfirmed = 2006
|
||||||
DocumentRejected = 2007
|
DocumentRejected = 2007
|
||||||
|
EnvelopeShared = 2008
|
||||||
|
EnvelopeViewed = 2009
|
||||||
MessageInvitationSent = 3001 ' Wird von Trigger verwendet
|
MessageInvitationSent = 3001 ' Wird von Trigger verwendet
|
||||||
MessageAccessCodeSent = 3002
|
MessageAccessCodeSent = 3002
|
||||||
MessageConfirmationSent = 3003
|
MessageConfirmationSent = 3003
|
||||||
@@ -94,6 +97,13 @@
|
|||||||
DocumentDeleted
|
DocumentDeleted
|
||||||
DocumentCompleted
|
DocumentCompleted
|
||||||
DocumentAccessCodeReceived
|
DocumentAccessCodeReceived
|
||||||
|
DocumentShared
|
||||||
|
End Enum
|
||||||
|
|
||||||
|
Public Enum EncodeType
|
||||||
|
EnvelopeReceiver
|
||||||
|
EnvelopeReceiverReadOnly
|
||||||
|
Undefined
|
||||||
End Enum
|
End Enum
|
||||||
|
|
||||||
#End Region
|
#End Region
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||||
<Deterministic>true</Deterministic>
|
<Deterministic>true</Deterministic>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
|
<NuGetPackageImportStamp>
|
||||||
|
</NuGetPackageImportStamp>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
@@ -75,8 +77,8 @@
|
|||||||
<Reference Include="DigitalData.Modules.Logging">
|
<Reference Include="DigitalData.Modules.Logging">
|
||||||
<HintPath>..\..\2_DLL Projekte\DDModules\Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath>
|
<HintPath>..\..\2_DLL Projekte\DDModules\Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="GdPicture.NET.14">
|
<Reference Include="GdPicture.NET.14, Version=14.2.89.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||||
<HintPath>D:\ProgramFiles\GdPicture.NET 14\Redist\GdPicture.NET (.NET Framework 4.5)\GdPicture.NET.14.dll</HintPath>
|
<HintPath>..\packages\GdPicture.14.2.89\lib\net462\GdPicture.NET.14.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
|
||||||
@@ -287,4 +289,11 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||||
|
<Import Project="..\packages\GdPicture.runtimes.windows.14.2.89\build\net462\GdPicture.runtimes.windows.targets" Condition="Exists('..\packages\GdPicture.runtimes.windows.14.2.89\build\net462\GdPicture.runtimes.windows.targets')" />
|
||||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ErrorText>Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".</ErrorText>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Condition="!Exists('..\packages\GdPicture.runtimes.windows.14.2.89\build\net462\GdPicture.runtimes.windows.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\GdPicture.runtimes.windows.14.2.89\build\net462\GdPicture.runtimes.windows.targets'))" />
|
||||||
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
|
|||||||
' indem Sie "*" wie unten gezeigt eingeben:
|
' indem Sie "*" wie unten gezeigt eingeben:
|
||||||
' <Assembly: AssemblyVersion("1.0.*")>
|
' <Assembly: AssemblyVersion("1.0.*")>
|
||||||
|
|
||||||
<Assembly: AssemblyVersion("1.9.2.0")>
|
<Assembly: AssemblyVersion("1.9.3.0")>
|
||||||
<Assembly: AssemblyFileVersion("1.9.2.0")>
|
<Assembly: AssemblyFileVersion("1.9.3.0")>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
|
<package id="GdPicture" version="14.2.89" targetFramework="net462" />
|
||||||
|
<package id="GdPicture.runtimes.windows" version="14.2.89" targetFramework="net462" />
|
||||||
<package id="Microsoft.Extensions.Logging.Abstractions" version="2.1.1" targetFramework="net462" />
|
<package id="Microsoft.Extensions.Logging.Abstractions" version="2.1.1" targetFramework="net462" />
|
||||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net462" />
|
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net462" />
|
||||||
<package id="Quartz" version="3.8.0" targetFramework="net462" />
|
<package id="Quartz" version="3.8.0" targetFramework="net462" />
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using DigitalData.Core.Abstractions;
|
||||||
|
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Domain.Entities
|
||||||
|
{
|
||||||
|
[Table("TBSIG_ENVELOPE_RECEIVER_READ_ONLY")]
|
||||||
|
public class EnvelopeReceiverReadOnly : IUnique<long>
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
[Column("GUID")]
|
||||||
|
public long Id { get; init; }
|
||||||
|
|
||||||
|
[Column("ENVELOPE_ID")]
|
||||||
|
[Required]
|
||||||
|
public long EnvelopeId { get; init; }
|
||||||
|
|
||||||
|
//TODO: remove NotMapped attribute when EnvelopeId data type is standardized
|
||||||
|
[NotMapped]
|
||||||
|
public Envelope? Envelope { get; set; }
|
||||||
|
|
||||||
|
[Column("RECEIVER_MAIL")]
|
||||||
|
[Required]
|
||||||
|
[StringLength(250)]
|
||||||
|
[TemplatePlaceholder("NAME_RECEIVER")]
|
||||||
|
public required string ReceiverMail { get; init; }
|
||||||
|
|
||||||
|
[Column("DATE_VALID")]
|
||||||
|
[Required]
|
||||||
|
public DateTime DateValid { get; init; }
|
||||||
|
|
||||||
|
[Column("ADDED_WHO")]
|
||||||
|
[Required]
|
||||||
|
[StringLength(100)]
|
||||||
|
public required string AddedWho { get; init; }
|
||||||
|
|
||||||
|
public Receiver? Receiver { get; init; }
|
||||||
|
|
||||||
|
[Column("ADDED_WHEN")]
|
||||||
|
[Required]
|
||||||
|
public DateTime AddedWhen { get; init; }
|
||||||
|
|
||||||
|
[Column("CHANGED_WHO")]
|
||||||
|
[StringLength(100)]
|
||||||
|
public string? ChangedWho { get; init; }
|
||||||
|
|
||||||
|
[Column("CHANGED_WHEN")]
|
||||||
|
public DateTime? ChangedWhen { get; init; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using System.Text;
|
||||||
using System.Text;
|
using static EnvelopeGenerator.Common.Constants;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application
|
namespace EnvelopeGenerator.Extensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
public static class DecodingExtensions
|
||||||
/// Provides extension methods for decoding and extracting information from an envelope receiver ID.
|
|
||||||
/// </summary>
|
|
||||||
public static class EnvelopeGeneratorExtensions
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validates whether a given string is a correctly formatted Base-64 encoded string.
|
/// Validates whether a given string is a correctly formatted Base-64 encoded string.
|
||||||
@@ -67,6 +64,40 @@ namespace EnvelopeGenerator.Application
|
|||||||
return input.IndexOf('=') == -1; // No padding allowed except at the end
|
return input.IndexOf('=') == -1; // No padding allowed except at the end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool TryDecode(this string encodedKey, out string[] decodedKeys)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] bytes = Convert.FromBase64String(encodedKey);
|
||||||
|
string decodedString = Encoding.UTF8.GetString(bytes);
|
||||||
|
decodedKeys = decodedString.Split(new string[] { "::" }, StringSplitOptions.None);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch(ArgumentNullException) { }
|
||||||
|
catch (FormatException) { }
|
||||||
|
catch(ArgumentException) { }
|
||||||
|
|
||||||
|
decodedKeys = Array.Empty<string>();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EncodeType GetEncodeType(this string[] decodedKeys) => decodedKeys.Length switch
|
||||||
|
{
|
||||||
|
2 => EncodeType.EnvelopeReceiver,
|
||||||
|
3 => long.TryParse(decodedKeys[1], out var _) ? EncodeType.EnvelopeReceiverReadOnly : EncodeType.Undefined,
|
||||||
|
_ => EncodeType.Undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static (string? EnvelopeUuid, string? ReceiverSignature) ParseEnvelopeReceiverId(this string[] decodedKeys)
|
||||||
|
=> decodedKeys.GetEncodeType() == EncodeType.EnvelopeReceiver
|
||||||
|
? (EnvelopeUuid: decodedKeys[0], ReceiverSignature: decodedKeys[1])
|
||||||
|
: throw new InvalidOperationException("Attempted to convert a decoded other than type EnvelopeReceiver to EnvelopeReceiver.");
|
||||||
|
|
||||||
|
public static long ParseReadOnlyId(this string[] decodedKeys)
|
||||||
|
=> decodedKeys.GetEncodeType() == EncodeType.EnvelopeReceiverReadOnly
|
||||||
|
? long.Parse(decodedKeys[1])
|
||||||
|
: throw new InvalidOperationException("Attempted to convert a decoded other than type EnvelopeReceiver to EnvelopeReceiver. ");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decodes the envelope receiver ID and extracts the envelope UUID and receiver signature.
|
/// Decodes the envelope receiver ID and extracts the envelope UUID and receiver signature.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -79,7 +110,7 @@ namespace EnvelopeGenerator.Application
|
|||||||
return (null, null);
|
return (null, null);
|
||||||
}
|
}
|
||||||
byte[] bytes = Convert.FromBase64String(envelopeReceiverId);
|
byte[] bytes = Convert.FromBase64String(envelopeReceiverId);
|
||||||
string decodedString = System.Text.Encoding.UTF8.GetString(bytes);
|
string decodedString = Encoding.UTF8.GetString(bytes);
|
||||||
string[] parts = decodedString.Split(new string[] { "::" }, StringSplitOptions.None);
|
string[] parts = decodedString.Split(new string[] { "::" }, StringSplitOptions.None);
|
||||||
|
|
||||||
if (parts.Length > 1)
|
if (parts.Length > 1)
|
||||||
@@ -88,6 +119,22 @@ namespace EnvelopeGenerator.Application
|
|||||||
return (string.Empty, string.Empty);
|
return (string.Empty, string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long? DecodeEnvelopeReceiverReadOnlyId(this string envelopeReceiverReadOnlyId)
|
||||||
|
{
|
||||||
|
if (!envelopeReceiverReadOnlyId.IsBase64String())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
byte[] bytes = Convert.FromBase64String(envelopeReceiverReadOnlyId);
|
||||||
|
string decodedString = System.Text.Encoding.UTF8.GetString(bytes);
|
||||||
|
string[] parts = decodedString.Split(new string[] { "::" }, StringSplitOptions.None);
|
||||||
|
|
||||||
|
if (parts.Length > 2)
|
||||||
|
return long.TryParse(parts[1], out long readOnlyId) ? readOnlyId : null;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the envelope UUID from the decoded envelope receiver ID.
|
/// Gets the envelope UUID from the decoded envelope receiver ID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -101,48 +148,5 @@ namespace EnvelopeGenerator.Application
|
|||||||
/// <param name="envelopeReceiverId">The base64 encoded string to decode.</param>
|
/// <param name="envelopeReceiverId">The base64 encoded string to decode.</param>
|
||||||
/// <returns>The receiver signature.</returns>
|
/// <returns>The receiver signature.</returns>
|
||||||
public static string? GetReceiverSignature(this string envelopeReceiverId) => envelopeReceiverId.DecodeEnvelopeReceiverId().ReceiverSignature;
|
public static string? GetReceiverSignature(this string envelopeReceiverId) => envelopeReceiverId.DecodeEnvelopeReceiverId().ReceiverSignature;
|
||||||
|
|
||||||
public static string EncodeEnvelopeReceiverId(this (string envelopeUuid, string receiverSignature) input)
|
|
||||||
{
|
|
||||||
string combinedString = $"{input.envelopeUuid}::{input.receiverSignature}";
|
|
||||||
byte[] bytes = Encoding.UTF8.GetBytes(combinedString);
|
|
||||||
string base64String = Convert.ToBase64String(bytes);
|
|
||||||
|
|
||||||
return base64String;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void LogEnvelopeError(this ILogger logger, string envelopeReceiverId, Exception? exception = null, string? message = null, params object?[] args)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder().AppendLine(envelopeReceiverId.DecodeEnvelopeReceiverId().ToTitle());
|
|
||||||
|
|
||||||
if (message is not null)
|
|
||||||
sb.AppendLine(message);
|
|
||||||
|
|
||||||
if(exception is null)
|
|
||||||
logger.Log(LogLevel.Error, sb.ToString(), args);
|
|
||||||
else
|
|
||||||
logger.Log(LogLevel.Error, exception, sb.AppendLine(exception.Message).ToString(), args);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void LogEnvelopeError(this ILogger logger, string? uuid, string? signature = null, Exception? exception = null, string? message = null, params object?[] args)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder($"Envelope Uuid: {uuid}");
|
|
||||||
|
|
||||||
if(signature is not null)
|
|
||||||
sb.AppendLine().Append($"Receiver Signature: {signature}");
|
|
||||||
|
|
||||||
if (message is not null)
|
|
||||||
sb.AppendLine().Append(message);
|
|
||||||
|
|
||||||
if (exception is null)
|
|
||||||
logger.Log(LogLevel.Error, sb.ToString(), args);
|
|
||||||
else
|
|
||||||
logger.Log(LogLevel.Error, exception, sb.ToString(), args);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ToTitle(this (string? UUID, string? Signature) envelopeReceiverTuple)
|
|
||||||
{
|
|
||||||
return $"UUID is {envelopeReceiverTuple.UUID} and signature is {envelopeReceiverTuple.Signature}";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
30
EnvelopeGenerator.Extensions/EncodingExtensions.cs
Normal file
30
EnvelopeGenerator.Extensions/EncodingExtensions.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Extensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extension methods for decoding and extracting information from an envelope receiver ID.
|
||||||
|
/// </summary>
|
||||||
|
public static class EncodingExtensions
|
||||||
|
{
|
||||||
|
public static string EncodeEnvelopeReceiverId(this long readOnlyId)
|
||||||
|
{
|
||||||
|
//The random number is used as a salt to increase security but it is not saved in the database.
|
||||||
|
string combinedString = $"{Random.Shared.Next()}::{readOnlyId}::{Random.Shared.Next()}";
|
||||||
|
byte[] bytes = Encoding.UTF8.GetBytes(combinedString);
|
||||||
|
string base64String = Convert.ToBase64String(bytes);
|
||||||
|
|
||||||
|
return base64String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string EncodeEnvelopeReceiverId(this (string envelopeUuid, string receiverSignature) input)
|
||||||
|
{
|
||||||
|
string combinedString = $"{input.envelopeUuid}::{input.receiverSignature}";
|
||||||
|
byte[] bytes = Encoding.UTF8.GetBytes(combinedString);
|
||||||
|
string base64String = Convert.ToBase64String(bytes);
|
||||||
|
|
||||||
|
return base64String;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="HtmlSanitizer" Version="8.0.865" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.19" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\EnvelopeGenerator.Common\EnvelopeGenerator.Common.vbproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
42
EnvelopeGenerator.Extensions/LoggerExtensions.cs
Normal file
42
EnvelopeGenerator.Extensions/LoggerExtensions.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Extensions
|
||||||
|
{
|
||||||
|
public static class LoggerExtensions
|
||||||
|
{
|
||||||
|
public static void LogEnvelopeError(this ILogger logger, string envelopeReceiverId, Exception? exception = null, string? message = null, params object?[] args)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder().AppendLine(envelopeReceiverId.DecodeEnvelopeReceiverId().ToTitle());
|
||||||
|
|
||||||
|
if (message is not null)
|
||||||
|
sb.AppendLine(message);
|
||||||
|
|
||||||
|
if (exception is null)
|
||||||
|
logger.Log(LogLevel.Error, sb.ToString(), args);
|
||||||
|
else
|
||||||
|
logger.Log(LogLevel.Error, exception, sb.AppendLine(exception.Message).ToString(), args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LogEnvelopeError(this ILogger logger, string? uuid, string? signature = null, Exception? exception = null, string? message = null, params object?[] args)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder($"Envelope Uuid: {uuid}");
|
||||||
|
|
||||||
|
if (signature is not null)
|
||||||
|
sb.AppendLine().Append($"Receiver Signature: {signature}");
|
||||||
|
|
||||||
|
if (message is not null)
|
||||||
|
sb.AppendLine().Append(message);
|
||||||
|
|
||||||
|
if (exception is null)
|
||||||
|
logger.Log(LogLevel.Error, sb.ToString(), args);
|
||||||
|
else
|
||||||
|
logger.Log(LogLevel.Error, exception, sb.ToString(), args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ToTitle(this (string? UUID, string? Signature) envelopeReceiverTuple)
|
||||||
|
{
|
||||||
|
return $"UUID is {envelopeReceiverTuple.UUID} and signature is {envelopeReceiverTuple.Signature}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
using System.Text.Encodings.Web;
|
using System.Text.Encodings.Web;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web
|
namespace EnvelopeGenerator.Extensions
|
||||||
{
|
{
|
||||||
public static class XSSExtensions
|
public static class XSSExtensions
|
||||||
{
|
{
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
<OptionCompare>Binary</OptionCompare>
|
<OptionCompare>Binary</OptionCompare>
|
||||||
<OptionStrict>Off</OptionStrict>
|
<OptionStrict>Off</OptionStrict>
|
||||||
<OptionInfer>On</OptionInfer>
|
<OptionInfer>On</OptionInfer>
|
||||||
|
<NuGetPackageImportStamp>
|
||||||
|
</NuGetPackageImportStamp>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
@@ -97,8 +99,8 @@
|
|||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\EnvelopeGenerator.Common\bin\Debug\EnvelopeGenerator.Common.dll</HintPath>
|
<HintPath>..\EnvelopeGenerator.Common\bin\Debug\EnvelopeGenerator.Common.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="GdPicture.NET.14">
|
<Reference Include="GdPicture.NET.14, Version=14.2.89.0, Culture=neutral, PublicKeyToken=f52a2e60ad468dbb, processorArchitecture=MSIL">
|
||||||
<HintPath>D:\ProgramFiles\GdPicture.NET 14\Redist\GdPicture.NET (.NET Framework 4.5)\GdPicture.NET.14.dll</HintPath>
|
<HintPath>..\packages\GdPicture.14.2.89\lib\net462\GdPicture.NET.14.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
|
||||||
@@ -269,6 +271,13 @@
|
|||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||||
|
<Import Project="..\packages\GdPicture.runtimes.windows.14.2.89\build\net462\GdPicture.runtimes.windows.targets" Condition="Exists('..\packages\GdPicture.runtimes.windows.14.2.89\build\net462\GdPicture.runtimes.windows.targets')" />
|
||||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ErrorText>Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".</ErrorText>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Condition="!Exists('..\packages\GdPicture.runtimes.windows.14.2.89\build\net462\GdPicture.runtimes.windows.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\GdPicture.runtimes.windows.14.2.89\build\net462\GdPicture.runtimes.windows.targets'))" />
|
||||||
|
</Target>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|||||||
@@ -68,4 +68,12 @@
|
|||||||
<!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->
|
<!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->
|
||||||
</sharedListeners>
|
</sharedListeners>
|
||||||
</system.diagnostics>
|
</system.diagnostics>
|
||||||
|
<runtime>
|
||||||
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="GdPicture.NET.14" publicKeyToken="f52a2e60ad468dbb" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-14.2.89.0" newVersion="14.2.89.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
</assemblyBinding>
|
||||||
|
</runtime>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
|
<package id="GdPicture" version="14.2.89" targetFramework="net462" />
|
||||||
|
<package id="GdPicture.runtimes.windows" version="14.2.89" targetFramework="net462" />
|
||||||
<package id="NLog" version="5.0.5" targetFramework="net462" />
|
<package id="NLog" version="5.0.5" targetFramework="net462" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using DigitalData.Core.Abstractions.Infrastructure;
|
||||||
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Infrastructure.Contracts
|
||||||
|
{
|
||||||
|
public interface IEnvelopeReceiverReadOnlyRepository : ICRUDRepository<EnvelopeReceiverReadOnly, long>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -51,6 +51,8 @@ namespace EnvelopeGenerator.Infrastructure
|
|||||||
|
|
||||||
public DbSet<EmailOut> EMailOuts { get; set; }
|
public DbSet<EmailOut> EMailOuts { get; set; }
|
||||||
|
|
||||||
|
public DbSet<EnvelopeReceiverReadOnly> EnvelopeReceiverReadOnlys { get; set; }
|
||||||
|
|
||||||
public EGDbContext(DbContextOptions<EGDbContext> options) : base(options)
|
public EGDbContext(DbContextOptions<EGDbContext> options) : base(options)
|
||||||
{
|
{
|
||||||
UserReceivers = Set<UserReceiver>();
|
UserReceivers = Set<UserReceiver>();
|
||||||
@@ -72,6 +74,7 @@ namespace EnvelopeGenerator.Infrastructure
|
|||||||
Users = Set<User>();
|
Users = Set<User>();
|
||||||
UserReps = Set<UserRep>();
|
UserReps = Set<UserRep>();
|
||||||
EMailOuts = Set<EmailOut>();
|
EMailOuts = Set<EmailOut>();
|
||||||
|
EnvelopeReceiverReadOnlys = Set<EnvelopeReceiverReadOnly>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
@@ -126,12 +129,19 @@ namespace EnvelopeGenerator.Infrastructure
|
|||||||
.HasForeignKey(eh => eh.UserReference)
|
.HasForeignKey(eh => eh.UserReference)
|
||||||
.HasPrincipalKey(e => e.Email);
|
.HasPrincipalKey(e => e.Email);
|
||||||
|
|
||||||
|
modelBuilder.Entity<EnvelopeReceiverReadOnly>()
|
||||||
|
.HasOne(erro => erro.Receiver)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey(erro => erro.AddedWho)
|
||||||
|
.HasPrincipalKey(r => r.EmailAddress);
|
||||||
|
|
||||||
// Configure entities to handle database triggers
|
// Configure entities to handle database triggers
|
||||||
modelBuilder.Entity<Envelope>().ToTable(tb => tb.HasTrigger("TBSIG_ENVELOPE_HISTORY_AFT_INS"));
|
modelBuilder.Entity<Envelope>().ToTable(tb => tb.HasTrigger("TBSIG_ENVELOPE_HISTORY_AFT_INS"));
|
||||||
modelBuilder.Entity<EnvelopeHistory>().ToTable(tb => tb.HasTrigger("TBSIG_ENVELOPE_HISTORY_AFT_INS"));
|
modelBuilder.Entity<EnvelopeHistory>().ToTable(tb => tb.HasTrigger("TBSIG_ENVELOPE_HISTORY_AFT_INS"));
|
||||||
modelBuilder.Entity<EmailOut>().ToTable(tb => tb.HasTrigger("TBEMLP_EMAIL_OUT_AFT_INS"));
|
modelBuilder.Entity<EmailOut>().ToTable(tb => tb.HasTrigger("TBEMLP_EMAIL_OUT_AFT_INS"));
|
||||||
modelBuilder.Entity<EmailOut>().ToTable(tb => tb.HasTrigger("TBEMLP_EMAIL_OUT_AFT_UPD"));
|
modelBuilder.Entity<EmailOut>().ToTable(tb => tb.HasTrigger("TBEMLP_EMAIL_OUT_AFT_UPD"));
|
||||||
|
modelBuilder.Entity<EnvelopeReceiverReadOnly>().ToTable(tb => tb.HasTrigger("TBSIG_ENVELOPE_RECEIVER_READ_ONLY_UPD"));
|
||||||
|
|
||||||
//configure model builder for user manager tables
|
//configure model builder for user manager tables
|
||||||
modelBuilder.ConfigureUserManager();
|
modelBuilder.ConfigureUserManager();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
using DigitalData.Core.Infrastructure;
|
||||||
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
|
using EnvelopeGenerator.Infrastructure.Contracts;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Infrastructure.Repositories
|
||||||
|
{
|
||||||
|
public class EnvelopeReceiverReadOnlyRepository : CRUDRepository<EnvelopeReceiverReadOnly, long, EGDbContext>, IEnvelopeReceiverReadOnlyRepository
|
||||||
|
{
|
||||||
|
private readonly IEnvelopeRepository _envRepo;
|
||||||
|
|
||||||
|
public EnvelopeReceiverReadOnlyRepository(EGDbContext dbContext, IEnvelopeRepository envelopeRepository) : base(dbContext, dbContext.EnvelopeReceiverReadOnlys)
|
||||||
|
{
|
||||||
|
_envRepo = envelopeRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IQueryable<EnvelopeReceiverReadOnly> ReadOnly()
|
||||||
|
{
|
||||||
|
return base.ReadOnly()
|
||||||
|
//TODO: add again when EnvelopeId data type is standardized
|
||||||
|
//.Include(erro => erro.Envelope)
|
||||||
|
.Include(erro => erro.Receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async override Task<IEnumerable<EnvelopeReceiverReadOnly>> ReadAllAsync()
|
||||||
|
{
|
||||||
|
var erros = await base.ReadAllAsync();
|
||||||
|
return await IncludeEnvelope(erros);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<EnvelopeReceiverReadOnly?> ReadByIdAsync(long id)
|
||||||
|
{
|
||||||
|
var erro = await _dbSet.AsNoTracking()
|
||||||
|
.Include(erro => erro.Receiver)
|
||||||
|
.Where(erro => erro.Id == id)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
return await IncludeEnvelope(erro);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Use IQueryable.Include instead of this when ID type is clarified.
|
||||||
|
[Obsolete("Use IQueryable.Include instead of this when ID type is clarified.")]
|
||||||
|
private async Task<EnvelopeReceiverReadOnly> IncludeEnvelope(EnvelopeReceiverReadOnly erro)
|
||||||
|
{
|
||||||
|
erro.Envelope = await _envRepo.ReadByIdAsync((int)erro.EnvelopeId);
|
||||||
|
return erro;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Use IQueryable.Include instead of this when ID type is clarified.
|
||||||
|
[Obsolete("Use IQueryable.Include instead of this when ID type is clarified.")]
|
||||||
|
private async Task<IEnumerable<EnvelopeReceiverReadOnly>> IncludeEnvelope(params EnvelopeReceiverReadOnly[] erros)
|
||||||
|
{
|
||||||
|
foreach (var erro in erros)
|
||||||
|
erro.Envelope = await _envRepo.ReadByIdAsync((int) erro.EnvelopeId);
|
||||||
|
|
||||||
|
return erros;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Use IQueryable.Include instead of this when ID type is clarified.
|
||||||
|
[Obsolete("Use IQueryable.Include instead of this when ID type is clarified.")]
|
||||||
|
private async Task<T> IncludeEnvelope<T>(T erros)
|
||||||
|
where T : IEnumerable<EnvelopeReceiverReadOnly>
|
||||||
|
{
|
||||||
|
foreach (var erro in erros)
|
||||||
|
erro.Envelope = await _envRepo.ReadByIdAsync((int)erro.EnvelopeId);
|
||||||
|
|
||||||
|
return erros;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,12 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
|
|
||||||
public static string? GetAuthEnvelopeTitle(this ControllerBase controller) => controller.User.FindFirstValue(EnvelopeClaimTypes.Title);
|
public static string? GetAuthEnvelopeTitle(this ControllerBase controller) => controller.User.FindFirstValue(EnvelopeClaimTypes.Title);
|
||||||
|
|
||||||
|
public static int? GetAuthEnvelopeId(this ControllerBase controller)
|
||||||
|
{
|
||||||
|
var env_id_str = controller.User.FindFirstValue(EnvelopeClaimTypes.Id);
|
||||||
|
return int.TryParse(env_id_str, out int env_id) ? env_id : null;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: integrate localizer for ready-to-use views
|
//TODO: integrate localizer for ready-to-use views
|
||||||
public static ViewResult ViewError(this Controller controller, ErrorViewModel errorViewModel) => controller.View("_Error", errorViewModel);
|
public static ViewResult ViewError(this Controller controller, ErrorViewModel errorViewModel) => controller.View("_Error", errorViewModel);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using EnvelopeGenerator.Web.Services;
|
|||||||
using EnvelopeGenerator.Application.Contracts;
|
using EnvelopeGenerator.Application.Contracts;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using EnvelopeGenerator.Application;
|
using EnvelopeGenerator.Application;
|
||||||
|
using EnvelopeGenerator.Extensions;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Controllers
|
namespace EnvelopeGenerator.Web.Controllers
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ using EnvelopeGenerator.Web.Services;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Text.Encodings.Web;
|
using System.Text.Encodings.Web;
|
||||||
using EnvelopeGenerator.Application.DTOs.EnvelopeHistory;
|
|
||||||
using static EnvelopeGenerator.Common.Constants;
|
using static EnvelopeGenerator.Common.Constants;
|
||||||
|
using EnvelopeGenerator.Extensions;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Controllers
|
namespace EnvelopeGenerator.Web.Controllers
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,14 +7,16 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using DigitalData.Core.API;
|
using DigitalData.Core.API;
|
||||||
using EnvelopeGenerator.Application;
|
using EnvelopeGenerator.Extensions;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
using DigitalData.Core.DTO;
|
using DigitalData.Core.DTO;
|
||||||
using Microsoft.AspNetCore.Localization;
|
using Microsoft.AspNetCore.Localization;
|
||||||
using System.Text.Encodings.Web;
|
|
||||||
using EnvelopeGenerator.Web.Models;
|
using EnvelopeGenerator.Web.Models;
|
||||||
using EnvelopeGenerator.Application.Resources;
|
using EnvelopeGenerator.Application.Resources;
|
||||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||||
|
using static EnvelopeGenerator.Common.Constants;
|
||||||
|
using Ganss.Xss;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Controllers
|
namespace EnvelopeGenerator.Web.Controllers
|
||||||
{
|
{
|
||||||
@@ -26,29 +28,41 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
private readonly IEnvelopeHistoryService _historyService;
|
private readonly IEnvelopeHistoryService _historyService;
|
||||||
private readonly IStringLocalizer<Resource> _localizer;
|
private readonly IStringLocalizer<Resource> _localizer;
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
private readonly UrlEncoder _urlEncoder;
|
private readonly HtmlSanitizer _sanitizer;
|
||||||
private readonly Cultures _cultures;
|
private readonly Cultures _cultures;
|
||||||
private readonly IEnvelopeMailService _mailService;
|
private readonly IEnvelopeMailService _mailService;
|
||||||
|
private readonly IEnvelopeReceiverReadOnlyService _readOnlyService;
|
||||||
public HomeController(EnvelopeOldService envelopeOldService, ILogger<HomeController> logger, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeHistoryService historyService, IStringLocalizer<Resource> localizer, IConfiguration configuration, UrlEncoder urlEncoder, Cultures cultures, IEnvelopeMailService envelopeMailService)
|
|
||||||
|
public HomeController(EnvelopeOldService envelopeOldService, ILogger<HomeController> logger, IEnvelopeReceiverService envelopeReceiverService, IEnvelopeHistoryService historyService, IStringLocalizer<Resource> localizer, IConfiguration configuration, HtmlSanitizer sanitizer, Cultures cultures, IEnvelopeMailService envelopeMailService, IEnvelopeReceiverReadOnlyService readOnlyService)
|
||||||
{
|
{
|
||||||
this.envelopeOldService = envelopeOldService;
|
this.envelopeOldService = envelopeOldService;
|
||||||
_envRcvService = envelopeReceiverService;
|
_envRcvService = envelopeReceiverService;
|
||||||
_historyService = historyService;
|
_historyService = historyService;
|
||||||
_localizer = localizer;
|
_localizer = localizer;
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
_urlEncoder = urlEncoder;
|
_sanitizer = sanitizer;
|
||||||
_cultures = cultures;
|
_cultures = cultures;
|
||||||
_mailService = envelopeMailService;
|
_mailService = envelopeMailService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
_readOnlyService = readOnlyService;
|
||||||
|
}
|
||||||
|
|
||||||
[HttpGet("EnvelopeKey/{envelopeReceiverId}")]
|
[HttpGet("EnvelopeKey/{envelopeReceiverId}")]
|
||||||
public async Task<IActionResult> SendAccessCode([FromRoute] string envelopeReceiverId)
|
public async Task<IActionResult> MainAsync([FromRoute] string envelopeReceiverId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
envelopeReceiverId = _urlEncoder.Encode(envelopeReceiverId);
|
envelopeReceiverId = _sanitizer.Sanitize(envelopeReceiverId);
|
||||||
|
|
||||||
|
if (!envelopeReceiverId.TryDecode(out var decoded))
|
||||||
|
{
|
||||||
|
Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||||||
|
return this.ViewDocumentNotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(decoded.GetEncodeType() == EncodeType.EnvelopeReceiverReadOnly)
|
||||||
|
return Redirect($"{envelopeReceiverId}/ReadOnly");
|
||||||
|
|
||||||
ViewData["EnvelopeKey"] = envelopeReceiverId;
|
ViewData["EnvelopeKey"] = envelopeReceiverId;
|
||||||
|
|
||||||
return await _envRcvService.ReadByEnvelopeReceiverIdAsync(envelopeReceiverId: envelopeReceiverId).ThenAsync<EnvelopeReceiverDto, IActionResult>(
|
return await _envRcvService.ReadByEnvelopeReceiverIdAsync(envelopeReceiverId: envelopeReceiverId).ThenAsync<EnvelopeReceiverDto, IActionResult>(
|
||||||
@@ -89,8 +103,8 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
culture = culture is not null ? _urlEncoder.Encode(culture) : null;
|
culture = culture is not null ? _sanitizer.Sanitize(culture) : null;
|
||||||
envelopeReceiverId = _urlEncoder.Encode(envelopeReceiverId);
|
envelopeReceiverId = _sanitizer.Sanitize(envelopeReceiverId);
|
||||||
|
|
||||||
if (UserLanguage is null && culture is null)
|
if (UserLanguage is null && culture is null)
|
||||||
{
|
{
|
||||||
@@ -125,7 +139,7 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
{
|
{
|
||||||
ViewData["UserCulture"] = _cultures[UserLanguage];
|
ViewData["UserCulture"] = _cultures[UserLanguage];
|
||||||
|
|
||||||
envelopeReceiverId = _urlEncoder.Encode(envelopeReceiverId);
|
envelopeReceiverId = _sanitizer.Sanitize(envelopeReceiverId);
|
||||||
(string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId();
|
(string? uuid, string? signature) = envelopeReceiverId.DecodeEnvelopeReceiverId();
|
||||||
|
|
||||||
if (uuid is null || signature is null)
|
if (uuid is null || signature is null)
|
||||||
@@ -185,14 +199,15 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
{
|
{
|
||||||
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, message: "No document was found.");
|
_logger.LogEnvelopeError(envelopeReceiverId: envelopeReceiverId, message: "No document was found.");
|
||||||
return this.ViewDocumentNotFound();
|
return this.ViewDocumentNotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var claims = new List<Claim> {
|
var claims = new List<Claim> {
|
||||||
new(ClaimTypes.NameIdentifier, uuid),
|
new(ClaimTypes.NameIdentifier, uuid),
|
||||||
new(ClaimTypes.Hash, signature),
|
new(ClaimTypes.Hash, signature),
|
||||||
new(ClaimTypes.Name, er.Name ?? string.Empty),
|
new(ClaimTypes.Name, er.Name ?? string.Empty),
|
||||||
new(ClaimTypes.Email, er.Receiver.EmailAddress),
|
new(ClaimTypes.Email, er.Receiver.EmailAddress),
|
||||||
new(EnvelopeClaimTypes.Title, er.Envelope.Title)
|
new(EnvelopeClaimTypes.Title, er.Envelope.Title),
|
||||||
|
new(EnvelopeClaimTypes.Id, er.Envelope.Id.ToString())
|
||||||
};
|
};
|
||||||
|
|
||||||
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||||
@@ -232,7 +247,7 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
envelopeReceiverId = _urlEncoder.Encode(envelopeReceiverId);
|
envelopeReceiverId = _sanitizer.Sanitize(envelopeReceiverId);
|
||||||
return await _envRcvService.IsExisting(envelopeReceiverId: envelopeReceiverId).ThenAsync(
|
return await _envRcvService.IsExisting(envelopeReceiverId: envelopeReceiverId).ThenAsync(
|
||||||
SuccessAsync: async isExisting =>
|
SuccessAsync: async isExisting =>
|
||||||
{
|
{
|
||||||
@@ -266,7 +281,7 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
envelopeReceiverId = _urlEncoder.Encode(envelopeReceiverId);
|
envelopeReceiverId = _sanitizer.Sanitize(envelopeReceiverId);
|
||||||
|
|
||||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||||
return await _envRcvService.ReadByEnvelopeReceiverIdAsync(envelopeReceiverId).ThenAsync(
|
return await _envRcvService.ReadByEnvelopeReceiverIdAsync(envelopeReceiverId).ThenAsync(
|
||||||
@@ -290,7 +305,81 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
return this.ViewInnerServiceError();
|
return this.ViewInnerServiceError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("EnvelopeKey/{readOnlyKey}/ReadOnly")]
|
||||||
|
public async Task<IActionResult> EnvelopeReceiverReadOnly([FromRoute] string readOnlyKey)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
readOnlyKey = _sanitizer.Sanitize(readOnlyKey);
|
||||||
|
|
||||||
|
// check if the readOnlyId is valid
|
||||||
|
if (!readOnlyKey.TryDecode(out var decodedKeys) || decodedKeys.GetEncodeType() != EncodeType.EnvelopeReceiverReadOnly)
|
||||||
|
{
|
||||||
|
Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||||||
|
return this.ViewDocumentNotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
var readOnlyId = decodedKeys.ParseReadOnlyId();
|
||||||
|
var erro_res = await _readOnlyService.ReadByIdAsync(readOnlyId);
|
||||||
|
if (erro_res.IsFailed)
|
||||||
|
{
|
||||||
|
_logger.LogNotice(erro_res.Notices);
|
||||||
|
return this.ViewInnerServiceError();
|
||||||
|
}
|
||||||
|
|
||||||
|
var erro = erro_res.Data;
|
||||||
|
|
||||||
|
if (DateTime.Now > erro.DateValid)
|
||||||
|
return View("EnvelopeExpired");
|
||||||
|
|
||||||
|
return await _envRcvService.ReadByUuidSignatureAsync(uuid: erro.Envelope!.Uuid, erro.Receiver!.Signature).ThenAsync(
|
||||||
|
SuccessAsync: async er =>
|
||||||
|
{
|
||||||
|
var envelopeKey = (er.Envelope!.Uuid, er.Receiver!.Signature).EncodeEnvelopeReceiverId();
|
||||||
|
|
||||||
|
EnvelopeResponse response = await envelopeOldService.LoadEnvelope(envelopeKey);
|
||||||
|
|
||||||
|
//TODO: implement multi-threading to history process (Task)
|
||||||
|
var hist_res = await _historyService.RecordAsync((int)erro.EnvelopeId, erro.AddedWho, EnvelopeStatus.EnvelopeViewed);
|
||||||
|
if (hist_res.IsFailed)
|
||||||
|
{
|
||||||
|
_logger.LogError(
|
||||||
|
"Although the envelope was sent as read-only, the EnvelopeShared hisotry could not be saved. ReadOnly-key: {readOnlyKey}\nEnvelope Receiver:\n{envelopeReceiver}",
|
||||||
|
readOnlyKey, JsonConvert.SerializeObject(er));
|
||||||
|
_logger.LogNotice(hist_res.Notices);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.Envelope.Documents.Count > 0)
|
||||||
|
{
|
||||||
|
var document = await envelopeOldService.GetDocument(response.Envelope.Documents[0].Id, envelopeKey);
|
||||||
|
byte[] bytes = await envelopeOldService.GetDocumentContents(document);
|
||||||
|
ViewData["EnvelopeKey"] = envelopeKey;
|
||||||
|
ViewData["DocumentBytes"] = bytes;
|
||||||
|
ViewData["IsReadOnly"] = true;
|
||||||
|
ViewData["ReadOnly"] = erro;
|
||||||
|
ViewData["PSPDFKitLicenseKey"] = _configuration["PSPDFKitLicenseKey"];
|
||||||
|
return View("ShowEnvelope", er);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogEnvelopeError(envelopeReceiverId: envelopeKey, message: "No document was found.");
|
||||||
|
return this.ViewDocumentNotFound();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Fail: (messages, notices) =>
|
||||||
|
{
|
||||||
|
_logger.LogNotice(notices);
|
||||||
|
return this.ViewEnvelopeNotFound();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "An unexpected error occurred while displaying a read-only envelope. Read-only key is {readOnlyKey}. {message}", readOnlyKey, ex.Message);
|
||||||
|
return this.ViewInnerServiceError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[HttpGet("IsAuthenticated")]
|
[HttpGet("IsAuthenticated")]
|
||||||
public IActionResult IsAuthenticated()
|
public IActionResult IsAuthenticated()
|
||||||
@@ -305,7 +394,7 @@ namespace EnvelopeGenerator.Web.Controllers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
language = _urlEncoder.Encode(language);
|
language = _sanitizer.Sanitize(language);
|
||||||
if (!_cultures.Languages.Contains(language))
|
if (!_cultures.Languages.Contains(language))
|
||||||
return BadRequest();
|
return BadRequest();
|
||||||
|
|
||||||
|
|||||||
102
EnvelopeGenerator.Web/Controllers/ReadOnlyController.cs
Normal file
102
EnvelopeGenerator.Web/Controllers/ReadOnlyController.cs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
using DigitalData.Core.DTO;
|
||||||
|
using EnvelopeGenerator.Application.Contracts;
|
||||||
|
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly;
|
||||||
|
using EnvelopeGenerator.Extensions;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Web.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class ReadOnlyController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ILogger<ReadOnlyController> _logger;
|
||||||
|
|
||||||
|
private readonly IEnvelopeReceiverReadOnlyService _erroService;
|
||||||
|
|
||||||
|
private readonly IEnvelopeMailService _mailService;
|
||||||
|
|
||||||
|
private readonly IEnvelopeHistoryService _histService;
|
||||||
|
|
||||||
|
public ReadOnlyController(ILogger<ReadOnlyController> logger, IEnvelopeReceiverReadOnlyService erroService, IEnvelopeMailService mailService, IEnvelopeHistoryService histService)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_erroService = erroService;
|
||||||
|
_mailService = mailService;
|
||||||
|
_histService = histService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Authorize]
|
||||||
|
public async Task<IActionResult> CreateAsync([FromBody] EnvelopeReceiverReadOnlyCreateDto createDto)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//set AddedWho
|
||||||
|
var authReceiverMail = this.GetAuthReceiverMail();
|
||||||
|
if (authReceiverMail is null)
|
||||||
|
{
|
||||||
|
_logger.LogError("Email clam is not found in envelope-receiver-read-only creation process. Create DTO is:\n {dto}", JsonConvert.SerializeObject(createDto));
|
||||||
|
return Unauthorized();
|
||||||
|
}
|
||||||
|
|
||||||
|
var envelopeId = this.GetAuthEnvelopeId();
|
||||||
|
if (envelopeId is null)
|
||||||
|
{
|
||||||
|
_logger.LogError("Envelope Id clam is not found in envelope-receiver-read-only creation process. Create DTO is:\n {dto}", JsonConvert.SerializeObject(createDto));
|
||||||
|
return Unauthorized();
|
||||||
|
}
|
||||||
|
|
||||||
|
createDto.AddedWho = authReceiverMail;
|
||||||
|
createDto.EnvelopeId = envelopeId;
|
||||||
|
|
||||||
|
// create entity
|
||||||
|
var creation_res = await _erroService.CreateAsync(createDto: createDto);
|
||||||
|
|
||||||
|
if (creation_res.IsFailed)
|
||||||
|
{
|
||||||
|
_logger.LogNotice(creation_res);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
}
|
||||||
|
|
||||||
|
//read new entity
|
||||||
|
var read_res = await _erroService.ReadByIdAsync(creation_res.Data);
|
||||||
|
if (read_res.IsFailed)
|
||||||
|
{
|
||||||
|
_logger.LogNotice(creation_res);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
}
|
||||||
|
|
||||||
|
var new_erro = read_res.Data;
|
||||||
|
|
||||||
|
//send email two receiver
|
||||||
|
return await _mailService.SendAsync(new_erro).ThenAsync<int, IActionResult>(SuccessAsync: async res =>
|
||||||
|
{
|
||||||
|
//TODO: implement multi-threading to history process (Task)
|
||||||
|
//TODO: remove casting after change the id type
|
||||||
|
var hist_res = await _histService.RecordAsync((int)createDto.EnvelopeId, createDto.AddedWho, Common.Constants.EnvelopeStatus.EnvelopeShared);
|
||||||
|
if (hist_res.IsFailed)
|
||||||
|
{
|
||||||
|
_logger.LogError("Although the envelope was sent as read-only, the EnvelopeShared hisotry could not be saved. Create DTO:\n{createDto}", JsonConvert.SerializeObject(createDto));
|
||||||
|
_logger.LogNotice(hist_res.Notices);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
},
|
||||||
|
|
||||||
|
Fail: (msg, ntc) =>
|
||||||
|
{
|
||||||
|
_logger.LogNotice(ntc);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "{Message}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using EnvelopeGenerator.Application;
|
using EnvelopeGenerator.Application.Contracts;
|
||||||
using EnvelopeGenerator.Application.Contracts;
|
|
||||||
using EnvelopeGenerator.Application.DTOs;
|
using EnvelopeGenerator.Application.DTOs;
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using EnvelopeGenerator.Extensions;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Web.Controllers.Test
|
namespace EnvelopeGenerator.Web.Controllers.Test
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using DigitalData.Core.API;
|
using DigitalData.Core.API;
|
||||||
using DigitalData.Core.DTO;
|
using DigitalData.Core.DTO;
|
||||||
using EnvelopeGenerator.Application.Contracts;
|
using EnvelopeGenerator.Application.Contracts;
|
||||||
using EnvelopeGenerator.Application;
|
using EnvelopeGenerator.Extensions;
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver;
|
||||||
@@ -40,13 +40,27 @@ namespace EnvelopeGenerator.Web.Controllers.Test
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("decode")]
|
[HttpGet("decode")]
|
||||||
public IActionResult DecodeEnvelopeReceiverId(string envelopeReceiverId)
|
public IActionResult DecodeEnvelopeReceiverId(string envelopeReceiverId, bool isReadOnly = false)
|
||||||
{
|
{
|
||||||
var decoded = envelopeReceiverId.DecodeEnvelopeReceiverId();
|
if (isReadOnly)
|
||||||
return Ok(new { uuid = decoded.EnvelopeUuid, signature = decoded.ReceiverSignature });
|
{
|
||||||
|
var readOnlyId = envelopeReceiverId.DecodeEnvelopeReceiverReadOnlyId();
|
||||||
|
return Ok(new { readOnlyId });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var (EnvelopeUuid, ReceiverSignature) = envelopeReceiverId.DecodeEnvelopeReceiverId();
|
||||||
|
return Ok(new { uuid = EnvelopeUuid, signature = ReceiverSignature });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("encode")]
|
[HttpGet("encode")]
|
||||||
public IActionResult EncodeEnvelopeReceiverId(string uuid, string signature) => Ok((uuid, signature).EncodeEnvelopeReceiverId());
|
public IActionResult EncodeEnvelopeReceiverId(string? uuid = null, string? signature = null, long? readOnlyId = null)
|
||||||
|
{
|
||||||
|
if(readOnlyId is long readOnlyId_long)
|
||||||
|
return Ok(readOnlyId_long.EncodeEnvelopeReceiverId());
|
||||||
|
else
|
||||||
|
return Ok((uuid ?? string.Empty, signature ?? string.Empty).EncodeEnvelopeReceiverId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,5 +9,10 @@
|
|||||||
/// Claim type for the title of an envelope.
|
/// Claim type for the title of an envelope.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly string Title = $"Envelope{nameof(Title)}";
|
public static readonly string Title = $"Envelope{nameof(Title)}";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Claim type for the ID of an envelope.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly string Id = $"Envelope{nameof(Id)}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<PackageId>EnvelopeGenerator.Web</PackageId>
|
<PackageId>EnvelopeGenerator.Web</PackageId>
|
||||||
<Version>2.0.0.0</Version>
|
<Version>2.1.1.0</Version>
|
||||||
<Authors>Digital Data GmbH</Authors>
|
<Authors>Digital Data GmbH</Authors>
|
||||||
<Company>Digital Data GmbH</Company>
|
<Company>Digital Data GmbH</Company>
|
||||||
<Product>EnvelopeGenerator.Web</Product>
|
<Product>EnvelopeGenerator.Web</Product>
|
||||||
@@ -13,8 +13,9 @@
|
|||||||
<PackageTags>digital data envelope generator web</PackageTags>
|
<PackageTags>digital data envelope generator web</PackageTags>
|
||||||
<Description>EnvelopeGenerator.Web is an ASP.NET MVC application developed to manage signing processes. It uses Entity Framework Core (EF Core) for database operations. The user interface for signing processes is developed with Razor View Engine (.cshtml files) and JavaScript under wwwroot, integrated with PSPDFKit. This integration allows users to view and sign documents seamlessly.</Description>
|
<Description>EnvelopeGenerator.Web is an ASP.NET MVC application developed to manage signing processes. It uses Entity Framework Core (EF Core) for database operations. The user interface for signing processes is developed with Razor View Engine (.cshtml files) and JavaScript under wwwroot, integrated with PSPDFKit. This integration allows users to view and sign documents seamlessly.</Description>
|
||||||
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
||||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
<AssemblyVersion>2.1.1.0</AssemblyVersion>
|
||||||
<FileVersion>2.0.0.0</FileVersion>
|
<FileVersion>2.1.1.0</FileVersion>
|
||||||
|
<Copyright>Copyright © 2024 Digital Data GmbH. All rights reserved.</Copyright>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -70,6 +71,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\EnvelopeGenerator.Application\EnvelopeGenerator.Application.csproj" />
|
<ProjectReference Include="..\EnvelopeGenerator.Application\EnvelopeGenerator.Application.csproj" />
|
||||||
<ProjectReference Include="..\EnvelopeGenerator.Common\EnvelopeGenerator.Common.vbproj" />
|
<ProjectReference Include="..\EnvelopeGenerator.Common\EnvelopeGenerator.Common.vbproj" />
|
||||||
|
<ProjectReference Include="..\EnvelopeGenerator.Extensions\EnvelopeGenerator.Extensions.csproj" />
|
||||||
<ProjectReference Include="..\EnvelopeGenerator.Infrastructure\EnvelopeGenerator.Infrastructure.csproj" />
|
<ProjectReference Include="..\EnvelopeGenerator.Infrastructure\EnvelopeGenerator.Infrastructure.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ try
|
|||||||
builder.Services.AddDbContext<EGDbContext>(options => options.UseSqlServer(connStr));
|
builder.Services.AddDbContext<EGDbContext>(options => options.UseSqlServer(connStr));
|
||||||
|
|
||||||
// Add envelope generator services
|
// Add envelope generator services
|
||||||
builder.Services.AddEnvelopeGenerator();
|
builder.Services.AddEnvelopeGenerator(config);
|
||||||
|
|
||||||
builder.Services.Configure<CookiePolicyOptions>(options =>
|
builder.Services.Configure<CookiePolicyOptions>(options =>
|
||||||
{
|
{
|
||||||
@@ -157,8 +157,6 @@ try
|
|||||||
|
|
||||||
builder.Services.AddMemoryCache();
|
builder.Services.AddMemoryCache();
|
||||||
|
|
||||||
builder.ConfigureBySection<DispatcherConfig>();
|
|
||||||
|
|
||||||
builder.ConfigureBySection<Logo>();
|
builder.ConfigureBySection<Logo>();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|||||||
24
EnvelopeGenerator.Web/Views/Home/EnvelopeExpired.cshtml
Normal file
24
EnvelopeGenerator.Web/Views/Home/EnvelopeExpired.cshtml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "Abgelaufen";
|
||||||
|
}
|
||||||
|
<div class="page container p-5">
|
||||||
|
<header class="text-center">
|
||||||
|
<div class="icon expired">
|
||||||
|
<svg width="72" height="72" viewBox="0 0 48 48" version="1" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 48 48">
|
||||||
|
<circle fill="#00ACC1" cx="17" cy="17" r="14" />
|
||||||
|
<circle fill="#eee" cx="17" cy="17" r="11" />
|
||||||
|
<rect x="16" y="8" width="2" height="9" />
|
||||||
|
<rect x="18.2" y="16" transform="matrix(-.707 .707 -.707 -.707 46.834 19.399)" width="2.4" height="6.8" />
|
||||||
|
<circle cx="17" cy="17" r="2" />
|
||||||
|
<circle fill="#00ACC1" cx="17" cy="17" r="1" />
|
||||||
|
<path fill="#FFC107" d="M11.9,42l14.4-24.1c0.8-1.3,2.7-1.3,3.4,0L44.1,42c0.8,1.3-0.2,3-1.7,3H13.6C12.1,45,11.1,43.3,11.9,42z" />
|
||||||
|
<path fill="#263238" d="M26.4,39.9c0-0.2,0-0.4,0.1-0.6s0.2-0.3,0.3-0.5s0.3-0.2,0.5-0.3s0.4-0.1,0.6-0.1s0.5,0,0.7,0.1 s0.4,0.2,0.5,0.3s0.2,0.3,0.3,0.5s0.1,0.4,0.1,0.6s0,0.4-0.1,0.6s-0.2,0.3-0.3,0.5s-0.3,0.2-0.5,0.3s-0.4,0.1-0.7,0.1 s-0.5,0-0.6-0.1s-0.4-0.2-0.5-0.3s-0.2-0.3-0.3-0.5S26.4,40.1,26.4,39.9z M29.2,36.8h-2.3L26.5,27h3L29.2,36.8z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h1>Abgelaufen!</h1>
|
||||||
|
</header>
|
||||||
|
<section class="text-center">
|
||||||
|
<p>Der Zeitraum für die gemeinsame Nutzung von Dokumenten ist abgelaufen.</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<footer class="container" id="page-footer">© SignFlow 2023-2024 <a href="https://digitaldata.works">Digital Data GmbH</a></footer>
|
||||||
@@ -23,45 +23,46 @@
|
|||||||
<section class="text-center">
|
<section class="text-center">
|
||||||
<p>@_localizer[WebKey.LockedBody]</p>
|
<p>@_localizer[WebKey.LockedBody]</p>
|
||||||
</section>
|
</section>
|
||||||
<div class="row m-0 p-0 justify-content-center">
|
<div class="row m-0 p-0">
|
||||||
<div class="col-8 pe-0">
|
<div class="access-code-panel justify-content-center align-items-center p-0 m-0">
|
||||||
<form id="form-access-code" class="form" method="post">
|
<form id="form-access-code" class="form form-floating mb-0" method="post">
|
||||||
<div class="input">
|
<div class="form-floating access-code-form-floating">
|
||||||
<label class="visually-hidden" for="access_code">@_localizer[WebKey.LockedTitle]</label>
|
|
||||||
<input type="password" id="access_code" class="form-control" name="access_code" placeholder="@_localizer[WebKey.LockedAccessCode]" required="required">
|
<input type="password" id="access_code" class="form-control" name="access_code" placeholder="@_localizer[WebKey.LockedAccessCode]" required="required">
|
||||||
<div id="access-code-error-message" class="text-danger" style="height: 20px;">
|
<label for="access_code">@_localizer[WebKey.LockedAccessCode]</label>
|
||||||
@if (ViewData["ErrorMessage"] is string errMsg)
|
<button type="submit" class="btn btn-primary">
|
||||||
{
|
<span class="material-symbols-outlined">
|
||||||
@_sanitizer.Sanitize(errMsg)
|
login
|
||||||
}
|
</span>
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="button">
|
<div class="dropdown flag-dropdown">
|
||||||
<button type="submit" class="btn btn-primary">@_localizer[WebKey.LocakedOpen]</button>
|
<button class="btn btn-outline-secondary dropdown-toggle" type="button" id="langDropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
<span class="fi @userCulture?.FIClass.TrySanitize(_sanitizer) me-2" id="selectedFlag"></span><span id="selectedLanguage"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="langDropdownMenuButton">
|
||||||
|
@foreach (var culture in _cultures)
|
||||||
|
{
|
||||||
|
var lang = culture.Language;
|
||||||
|
var info = culture.Info;
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" data-language="@lang.TrySanitize(_sanitizer)" data-flag="@_cultures[lang]?.FIClass.TrySanitize(_sanitizer)">
|
||||||
|
<span class="fi @_cultures[lang]?.FIClass.TrySanitize(_sanitizer) me-2"></span>@info?.Parent.NativeName
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4 mb-3 d-flex justify-content-center align-items-center">
|
|
||||||
<div class="dropdown">
|
|
||||||
<button class="btn btn-outline-secondary dropdown-toggle" type="button" id="langDropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
<span class="fi @userCulture?.FIClass.TrySanitize(_sanitizer) me-2" id="selectedFlag"></span><span id="selectedLanguage"></span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu" aria-labelledby="langDropdownMenuButton">
|
|
||||||
@foreach(var culture in _cultures)
|
|
||||||
{
|
|
||||||
var lang = culture.Language;
|
|
||||||
var info = culture.Info;
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" data-language="@lang.TrySanitize(_sanitizer)" data-flag="@_cultures[lang]?.FIClass.TrySanitize(_sanitizer)">
|
|
||||||
<span class="fi @_cultures[lang]?.FIClass.TrySanitize(_sanitizer) me-2"></span>@info?.Parent.NativeName
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<section class="text-center">
|
@if (ViewData["ErrorMessage"] is string errMsg)
|
||||||
|
{
|
||||||
|
<div id="access-code-error-message" class="alert alert-danger row" role="alert">
|
||||||
|
@_sanitizer.Sanitize(errMsg)
|
||||||
|
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<section class="no-receiver-explanation text-center">
|
||||||
<details>
|
<details>
|
||||||
<summary>@_localizer[WebKey.LockedFooterTitle]</summary>
|
<summary>@_localizer[WebKey.LockedFooterTitle]</summary>
|
||||||
<p>@_localizer[WebKey.LockedFooterBody]</p>
|
<p>@_localizer[WebKey.LockedFooterBody]</p>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
@using DigitalData.Core.DTO;
|
@using DigitalData.Core.DTO;
|
||||||
@using EnvelopeGenerator.Application.DTOs;
|
@using EnvelopeGenerator.Application.DTOs;
|
||||||
@using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
|
@using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver
|
||||||
|
@using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly
|
||||||
@using Newtonsoft.Json
|
@using Newtonsoft.Json
|
||||||
@using Newtonsoft.Json.Serialization
|
@using Newtonsoft.Json.Serialization
|
||||||
@model EnvelopeReceiverDto;
|
@model EnvelopeReceiverDto;
|
||||||
@@ -15,79 +16,182 @@
|
|||||||
@{
|
@{
|
||||||
var userCulture = ViewData["UserCulture"] as Culture;
|
var userCulture = ViewData["UserCulture"] as Culture;
|
||||||
var envelope = Model.Envelope;
|
var envelope = Model.Envelope;
|
||||||
|
var receiver_name = Model.Name;
|
||||||
var document = Model.Envelope?.Documents?.FirstOrDefault();
|
var document = Model.Envelope?.Documents?.FirstOrDefault();
|
||||||
var sender = Model.Envelope?.User;
|
var sender = Model.Envelope?.User;
|
||||||
var pages = document?.Elements?.Select(e => e.Page) ?? Array.Empty<int>();
|
var pages = document?.Elements?.Select(e => e.Page) ?? Array.Empty<int>();
|
||||||
|
int? signatureCount = document?.Elements?.Count();
|
||||||
var stPageIndexes = string.Join(pages.Count() > 1 ? ", " : "", pages.Take(pages.Count() - 1))
|
var stPageIndexes = string.Join(pages.Count() > 1 ? ", " : "", pages.Take(pages.Count() - 1))
|
||||||
+ (pages.Count() > 1 ? $" {_localizer[WebKey.and].TrySanitize(_sanitizer)} " : "") + pages.LastOrDefault();
|
+ (pages.Count() > 1 ? $" {_localizer[WebKey.and].TrySanitize(_sanitizer)} " : "") + pages.LastOrDefault();
|
||||||
|
var isReadOnly = false;
|
||||||
|
if (ViewData["IsReadOnly"] is bool isReadOnly_bool)
|
||||||
|
isReadOnly = isReadOnly_bool;
|
||||||
}
|
}
|
||||||
<div class="d-flex flex-column min-vh-100">
|
<div class="envelope-view">
|
||||||
<nav class="navbar navbar-light bg-light">
|
@if (!isReadOnly)
|
||||||
<div class="container">
|
{
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarToggleExternalContent" aria-controls="navbarToggleExternalContent" aria-expanded="false" aria-label="Toggle navigation">
|
|
||||||
<span class="material-symbols-outlined">
|
|
||||||
more_vert
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<div class="envelope-message">
|
|
||||||
<span class="icon material-symbols-outlined">history_edu</span>
|
|
||||||
<span class="message navbar-brand">@($"{_localizer[WebKey.Hello]} {Model.Name}, {@envelope?.Message}".TrySanitize(_sanitizer))</span>
|
|
||||||
</div>
|
|
||||||
<div class="logo">
|
|
||||||
<img class="@logo.ShowPageClass" src="@logo.Src" alt="logo">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<div class="collapse show bg-light " id="navbarToggleExternalContent" data-bs-theme="light">
|
|
||||||
<div class="card sender-card p-1 mb-3">
|
|
||||||
<div class="row g-0">
|
|
||||||
<div class="col p-0 m-0">
|
|
||||||
<div class="card-body p-0 m-0 ms-4">
|
|
||||||
<h5 class="card-title p-0 m-0">
|
|
||||||
<span class="signature-process-title">@($"{_localizer[WebKey.SigningProcessTitle]}: ".TrySanitize(_sanitizer))</span>
|
|
||||||
<span class="signature-process-name">@($"{envelope?.Title}".TrySanitize(_sanitizer))</span>
|
|
||||||
</h5>
|
|
||||||
<p class="card-text p-0 m-0">@Html.Raw(string.Format(_localizer[WebKey.EnvelopeInfo1], pages.Count(), stPageIndexes).TrySanitize(_hlSanitizer))</p>
|
|
||||||
<p class="card-text p-0 m-0">
|
|
||||||
<small class="text-body-secondary">
|
|
||||||
@Html.Raw(string.Format(_localizer[WebKey.EnvelopeInfo2], /* sanitize separately but don't sanitize the URI */
|
|
||||||
envelope?.AddedWhen.ToString(userCulture?.Info?.DateTimeFormat).TrySanitize(_sanitizer),
|
|
||||||
$"{sender?.Prename} {sender?.Name}".TrySanitize(_sanitizer),
|
|
||||||
sender?.Email.TrySanitize(_sanitizer),
|
|
||||||
envelope?.Title.TrySanitize(_sanitizer),
|
|
||||||
sender?.Prename.TrySanitize(_sanitizer),
|
|
||||||
sender?.Name.TrySanitize(_sanitizer),
|
|
||||||
sender?.Email.TrySanitize(_sanitizer)))
|
|
||||||
</small>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="flex-action-panel" class="btn-group btn_group position-fixed bottom-0 end-0 d-flex align-items-center" role="group" aria-label="Basic mixed styles example">
|
<div id="flex-action-panel" class="btn-group btn_group position-fixed bottom-0 end-0 d-flex align-items-center" role="group" aria-label="Basic mixed styles example">
|
||||||
<button class="btn_complete btn btn-primary" type="button">
|
<button class="btn_complete btn btn-primary btn-desktop" type="button">
|
||||||
<svg class="icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 16">
|
<svg class="icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 16">
|
||||||
<path d="m10.036 8.278 9.258-7.79A1.979 1.979 0 0 0 18 0H2A1.987 1.987 0 0 0 .641.541l9.395 7.737Z" />
|
<path d="m10.036 8.278 9.258-7.79A1.979 1.979 0 0 0 18 0H2A1.987 1.987 0 0 0 .641.541l9.395 7.737Z" />
|
||||||
<path d="M11.241 9.817c-.36.275-.801.425-1.255.427-.428 0-.845-.138-1.187-.395L0 2.6V14a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V2.5l-8.759 7.317Z" />
|
<path d="M11.241 9.817c-.36.275-.801.425-1.255.427-.428 0-.845-.138-1.187-.395L0 2.6V14a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V2.5l-8.759 7.317Z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>@_localizer[WebKey.Complete]</span>
|
<span>@_localizer[WebKey.Complete]</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn_reject btn btn-danger" type="button">
|
<button class="btn_reject btn btn-danger btn-desktop" type="button">
|
||||||
<svg width="25px" height="25px" viewBox="43.5 43.5 512 512" version="1.1" fill="currentColor" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
<svg width="25px" height="25px" viewBox="43.5 43.5 512 512" version="1.1" fill="currentColor" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<path class="st0" d="M263.24,43.5c-117.36,0-212.5,95.14-212.5,212.5s95.14,212.5,212.5,212.5s212.5-95.14,212.5-212.5 S380.6,43.5,263.24,43.5z M367.83,298.36c17.18,17.18,17.18,45.04,0,62.23v0c-17.18,17.18-45.04,17.18-62.23,0l-42.36-42.36 l-42.36,42.36c-17.18,17.18-45.04,17.18-62.23,0v0c-17.18-17.18-17.18-45.04,0-62.23L201.01,256l-42.36-42.36 c-17.18-17.18-17.18-45.04,0-62.23v0c17.18-17.18,45.04-17.18,62.23,0l42.36,42.36l42.36-42.36c17.18-17.18,45.04-17.18,62.23,0v0 c17.18,17.18,17.18,45.04,0,62.23L325.46,256L367.83,298.36z" />
|
<path class="st0" d="M263.24,43.5c-117.36,0-212.5,95.14-212.5,212.5s95.14,212.5,212.5,212.5s212.5-95.14,212.5-212.5 S380.6,43.5,263.24,43.5z M367.83,298.36c17.18,17.18,17.18,45.04,0,62.23v0c-17.18,17.18-45.04,17.18-62.23,0l-42.36-42.36 l-42.36,42.36c-17.18,17.18-45.04,17.18-62.23,0v0c-17.18-17.18-17.18-45.04,0-62.23L201.01,256l-42.36-42.36 c-17.18-17.18-17.18-45.04,0-62.23v0c17.18-17.18,45.04-17.18,62.23,0l42.36,42.36l42.36-42.36c17.18-17.18,45.04-17.18,62.23,0v0 c17.18,17.18,17.18,45.04,0,62.23L325.46,256L367.83,298.36z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>@_localizer[WebKey.Reject]</span>
|
<span>@_localizer[WebKey.Reject]</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn_refresh btn btn-secondary" type="button">
|
<button class="btn_refresh btn btn-secondary btn-desktop" type="button">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
|
||||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z" />
|
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z" />
|
||||||
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z" />
|
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div id='app' class="flex-grow-1"></div>
|
}
|
||||||
|
<div class="dd-cards-container">
|
||||||
|
<div class="dd-card">
|
||||||
|
<div class="dd-card-preview">
|
||||||
|
<img src="~/img/sign_flow_horizontal.svg" class="app-logo">
|
||||||
|
@if (!isReadOnly)
|
||||||
|
{
|
||||||
|
<div class="progress-container">
|
||||||
|
<div id="signed-count-bar" class="progress"></div>
|
||||||
|
<span class="progress-text">
|
||||||
|
<span id="signed-count">0</span>/<span id="signature-count">@signatureCount</span> Unterschriften
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="dd-card-info">
|
||||||
|
<div class="logo">
|
||||||
|
<img class="@logo.ShowPageClass" src="@logo.Src" alt="logo">
|
||||||
|
</div>
|
||||||
|
<h2>@($"{envelope?.Title}".TrySanitize(_sanitizer))</h2>
|
||||||
|
@if (isReadOnly)
|
||||||
|
{
|
||||||
|
var dateTimeSt = string.Empty;
|
||||||
|
if (ViewData["ReadOnly"] is EnvelopeReceiverReadOnlyDto readOnly)
|
||||||
|
dateTimeSt = readOnly.DateValid.ToLongDateString();
|
||||||
|
<h6>@string.Format(_localizer["ReadOnlyMessage"], receiver_name, dateTimeSt)</h6>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<h6>@($"{@envelope?.Message}".TrySanitize(_sanitizer))</h6>
|
||||||
|
}
|
||||||
|
<p>
|
||||||
|
<small class="text-body-secondary">
|
||||||
|
@Html.Raw(string.Format(_localizer[WebKey.EnvelopeInfo2], /* sanitize separately but don't sanitize the URI */
|
||||||
|
envelope?.AddedWhen.ToString(userCulture?.Info?.DateTimeFormat).TrySanitize(_sanitizer),
|
||||||
|
$"{sender?.Prename} {sender?.Name}".TrySanitize(_sanitizer),
|
||||||
|
sender?.Email.TrySanitize(_sanitizer),
|
||||||
|
envelope?.Title.TrySanitize(_sanitizer),
|
||||||
|
sender?.Prename.TrySanitize(_sanitizer),
|
||||||
|
sender?.Name.TrySanitize(_sanitizer),
|
||||||
|
sender?.Email.TrySanitize(_sanitizer)))
|
||||||
|
</small>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if (!isReadOnly)
|
||||||
|
{
|
||||||
|
<div class="modal fade" id="shareBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="shareBackdropLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<small class="modal-title text-body-secondary" id="shareBackdropLabel">Geben Sie hier den Empfänger ein, mit welchem Sie das Dokument teilen wollen:</small>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<span class="input-group-text">E-Mail</span>
|
||||||
|
<input type="text" class="form-control email-input" placeholder="user@mail.com" id="readonly-receiver-mail" aria-label="">
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-text">Gültig bis</span>
|
||||||
|
<input type="date" name="expiration" class="form-control" lang="de" id="readonly-date-valid" onkeydown="return false;" onclick="this.showPicker()"
|
||||||
|
min="@DateTime.Today.AddDays(1).ToString("yyyy-MM-dd")"
|
||||||
|
max="@DateTime.Today.AddDays(90).ToString("yyyy-MM-dd")"
|
||||||
|
value="@DateTime.Today.AddDays(7).ToString("yyyy-MM-dd")">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-primary" id="readonly-send">
|
||||||
|
<span class="material-symbols-outlined">
|
||||||
|
send
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div id='app'></div>
|
||||||
</div>
|
</div>
|
||||||
|
@if (!isReadOnly)
|
||||||
|
{
|
||||||
|
<script nonce="@nonce">
|
||||||
|
document.getElementById('readonly-send').addEventListener('click', async () => {
|
||||||
|
const receiverMail = document.getElementById('readonly-receiver-mail');
|
||||||
|
const dateValid = document.getElementById('readonly-date-valid');
|
||||||
|
|
||||||
|
const receiverMail_value = receiverMail.value;
|
||||||
|
const dateValid_value = dateValid.value;
|
||||||
|
|
||||||
|
//check email
|
||||||
|
if (!receiverMail_value || receiverMail.classList.contains('is-invalid')) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Falsche Email",
|
||||||
|
text: "Die E-Mail-Adresse ist ungültig. Bitte verwenden Sie das richtige Format, z. B.: user@mail.com."
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check the date
|
||||||
|
const tomorrow = new Date(Date.now() + 86400000);
|
||||||
|
if (new Date(dateValid_value) < tomorrow) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Falsches Datum",
|
||||||
|
text: "Die Verteilung der Umschläge sollte mindestens einen Tag dauern."
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shareEnvelope(receiverMail_value, dateValid_value)
|
||||||
|
.then(res => {
|
||||||
|
if (res.ok) {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Gesendet",
|
||||||
|
icon: "success"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: `Fehler ${res.status}`,
|
||||||
|
text: "Der Vorgang ist fehlgeschlagen. Bitte wenden Sie sich an das IT-Team."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Unerwarteter Fehler",
|
||||||
|
text: "Der Vorgang ist fehlgeschlagen. Bitte wenden Sie sich an das IT-Team."
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
receiverMail.value = '';
|
||||||
|
dateValid.valueAsDate = new Date(new Date().setDate(new Date().getDate() + 8));
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
}
|
||||||
<script nonce="@nonce">
|
<script nonce="@nonce">
|
||||||
const collapseNav = () => {
|
const collapseNav = () => {
|
||||||
document.addEventListener('click', function (event) {
|
document.addEventListener('click', function (event) {
|
||||||
|
|||||||
@@ -3,9 +3,13 @@
|
|||||||
@using Newtonsoft.Json.Serialization
|
@using Newtonsoft.Json.Serialization
|
||||||
@{
|
@{
|
||||||
var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string;
|
var nonce = _accessor.HttpContext?.Items["csp-nonce"] as string;
|
||||||
|
|
||||||
|
var isReadOnly = false;
|
||||||
|
if (ViewData["IsReadOnly"] is bool isReadOnly_bool)
|
||||||
|
isReadOnly = isReadOnly_bool;
|
||||||
}
|
}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="de">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||||
@@ -14,10 +18,10 @@
|
|||||||
<link rel="stylesheet" href="~/lib/sweetalert2/sweetalert2.min.css" />
|
<link rel="stylesheet" href="~/lib/sweetalert2/sweetalert2.min.css" />
|
||||||
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
|
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
|
||||||
<link rel="stylesheet" href="~/css/logo.min.css" asp-append-version="true" />
|
<link rel="stylesheet" href="~/css/logo.min.css" asp-append-version="true" />
|
||||||
|
<link rel="stylesheet" href="~/css/card.min.css" asp-append-version="true" />
|
||||||
<link rel="stylesheet" href="~/EnvelopeGenerator.Web.styles.css" asp-append-version="true" />
|
<link rel="stylesheet" href="~/EnvelopeGenerator.Web.styles.css" asp-append-version="true" />
|
||||||
<link rel="stylesheet" href="~/lib/flag-icons-main/css/flag-icons.min.css" asp-append-version="true" />
|
<link rel="stylesheet" href="~/lib/flag-icons-main/css/flag-icons.min.css" asp-append-version="true" />
|
||||||
<link rel="stylesheet" href="~/lib/alertifyjs/css/alertify.min.css" />
|
<link rel="stylesheet" href="~/lib/alertifyjs/css/alertify.min.css" />
|
||||||
<link rel="stylesheet" href="~/lib/alertifyjs/css/themes/default.min.css" />
|
|
||||||
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
|
||||||
</head>
|
</head>
|
||||||
@@ -27,10 +31,19 @@
|
|||||||
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24
|
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<script nonce="@nonce">
|
||||||
@if (ViewData["EnvelopeKey"] is string envelopeKey)
|
@if (ViewData["EnvelopeKey"] is string envelopeKey)
|
||||||
{
|
{
|
||||||
<script nonce="@nonce">const ENV_KEY = "@envelopeKey.TrySanitize(_sanitizer)"</script>
|
@: const ENV_KEY = "@envelopeKey.TrySanitize(_sanitizer)"
|
||||||
}
|
}
|
||||||
|
const IS_READONLY = @isReadOnly.ToString().ToLower();
|
||||||
|
|
||||||
|
const DEVICE_TYPE = window.innerWidth <= 768 ? 'mobile' : window.innerWidth <= 1024 ? 'tablet' : 'desktop';
|
||||||
|
|
||||||
|
const IS_DESKTOP = DEVICE_TYPE == 'desktop'
|
||||||
|
</script>
|
||||||
|
|
||||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||||
<script src="~/lib/popper/dist/umd/popper.min.js"></script>
|
<script src="~/lib/popper/dist/umd/popper.min.js"></script>
|
||||||
<script src="~/lib/bootstrap/dist/js/bootstrap.min.js"></script>
|
<script src="~/lib/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||||
@@ -41,7 +54,6 @@
|
|||||||
<script src="~/js/network.min.js" asp-append-version="true"></script>
|
<script src="~/js/network.min.js" asp-append-version="true"></script>
|
||||||
<script src="~/js/app.min.js" asp-append-version="true"></script>
|
<script src="~/js/app.min.js" asp-append-version="true"></script>
|
||||||
<script src="~/lib/pspdfkit/dist-2024.3.2/pspdfkit.js"></script>
|
<script src="~/lib/pspdfkit/dist-2024.3.2/pspdfkit.js"></script>
|
||||||
<script src="~/lib/bootstrap-cookie-consent-settings-main/bootstrap-cookie-consent-settings.js" asp-append-version="true"></script>
|
|
||||||
<script src="~/js/util.min.js" asp-append-version="true"></script>
|
<script src="~/js/util.min.js" asp-append-version="true"></script>
|
||||||
<script src="~/js/api-service.min.js" asp-append-version="true"></script>
|
<script src="~/js/api-service.min.js" asp-append-version="true"></script>
|
||||||
@await RenderSectionAsync("Scripts", required: false)
|
@await RenderSectionAsync("Scripts", required: false)
|
||||||
@@ -61,6 +73,9 @@
|
|||||||
</main>
|
</main>
|
||||||
<script src="~/js/event-binder.min.js" asp-append-version="true"></script>
|
<script src="~/js/event-binder.min.js" asp-append-version="true"></script>
|
||||||
@Html.AntiForgeryToken()
|
@Html.AntiForgeryToken()
|
||||||
<footer>© SignFlow 2023-2024 <a href="https://digitaldata.works">Digital Data GmbH</a></footer>
|
<footer>
|
||||||
|
<span>© SignFlow 2023-2024 <a href="https://digitaldata.works">Digital Data GmbH</a></span>
|
||||||
|
<a href="/privacy-policy.de-DE.html">Datenschutz</a>
|
||||||
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
@using EnvelopeGenerator.Web
|
@using EnvelopeGenerator.Web
|
||||||
@using EnvelopeGenerator.Web.Models
|
@using EnvelopeGenerator.Web.Models
|
||||||
@using EnvelopeGenerator.Web.Sanitizers
|
@using EnvelopeGenerator.Web.Sanitizers
|
||||||
|
@using EnvelopeGenerator.Extensions
|
||||||
@using Microsoft.Extensions.Localization
|
@using Microsoft.Extensions.Localization
|
||||||
@using EnvelopeGenerator.Application.Resources
|
@using EnvelopeGenerator.Application.Resources
|
||||||
@using Microsoft.Extensions.Options
|
@using Microsoft.Extensions.Options
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
},
|
},
|
||||||
"AdminPassword": "dd",
|
"AdminPassword": "dd",
|
||||||
"PSPDFKitLicenseKey": "SXCtGGY9XA-31OGUXQK-r7c6AkdLGPm2ljuyDr1qu0kkhLvydg-Do-fxpNUF4Rq3fS_xAnZRNFRHbXpE6sQ2BMcCSVTcXVJO6tPviexjpiT-HnrDEySlUERJnnvh-tmeOWprxS6BySPnSILkmaVQtUfOIUS-cUbvvEYHTvQBKbSF8di4XHQFyfv49ihr51axm3NVV3AXwh2EiKL5C5XdqBZ4sQ4O7vXBjM2zvxdPxlxdcNYmiU83uAzw7B83O_jubPzya4CdUHh_YH7Nlp2gP56MeG1Sw2JhMtfG3Rj14Sg4ctaeL9p6AEWca5dDjJ2li5tFIV2fQSsw6A_cowLu0gtMm5i8IfJXeIcQbMC2-0wGv1oe9hZYJvFMdzhTM_FiejM0agemxt3lJyzuyP8zbBSOgp7Si6A85krLWPZptyZBTG7pp7IHboUHfPMxCXqi-zMsqewOJtQBE2mjntU-lPryKnssOpMPfswwQX7QSkJYV5EMqNmEhQX6mEkp2wcqFzMC7bJQew1aO4pOpvChUaMvb1vgRek0HxLag0nwQYX2YrYGh7F_xXJs-8HNwJe8H0-eW4x4faayCgM5rB5772CCCsD9ThZcvXFrjNHHLGJ8WuBUFm6LArvSfFQdii_7j-_sqHMpeKZt26NFgivj1A==",
|
"PSPDFKitLicenseKey": "SXCtGGY9XA-31OGUXQK-r7c6AkdLGPm2ljuyDr1qu0kkhLvydg-Do-fxpNUF4Rq3fS_xAnZRNFRHbXpE6sQ2BMcCSVTcXVJO6tPviexjpiT-HnrDEySlUERJnnvh-tmeOWprxS6BySPnSILkmaVQtUfOIUS-cUbvvEYHTvQBKbSF8di4XHQFyfv49ihr51axm3NVV3AXwh2EiKL5C5XdqBZ4sQ4O7vXBjM2zvxdPxlxdcNYmiU83uAzw7B83O_jubPzya4CdUHh_YH7Nlp2gP56MeG1Sw2JhMtfG3Rj14Sg4ctaeL9p6AEWca5dDjJ2li5tFIV2fQSsw6A_cowLu0gtMm5i8IfJXeIcQbMC2-0wGv1oe9hZYJvFMdzhTM_FiejM0agemxt3lJyzuyP8zbBSOgp7Si6A85krLWPZptyZBTG7pp7IHboUHfPMxCXqi-zMsqewOJtQBE2mjntU-lPryKnssOpMPfswwQX7QSkJYV5EMqNmEhQX6mEkp2wcqFzMC7bJQew1aO4pOpvChUaMvb1vgRek0HxLag0nwQYX2YrYGh7F_xXJs-8HNwJe8H0-eW4x4faayCgM5rB5772CCCsD9ThZcvXFrjNHHLGJ8WuBUFm6LArvSfFQdii_7j-_sqHMpeKZt26NFgivj1A==",
|
||||||
"UseCSPInDev": true,
|
"UseCSPInDev": false,
|
||||||
"Content-Security-Policy": [ // The first format parameter {0} will be replaced by the nonce value.
|
"Content-Security-Policy": [ // The first format parameter {0} will be replaced by the nonce value.
|
||||||
"default-src 'self'",
|
"default-src 'self'",
|
||||||
"script-src 'self' 'nonce-{0}' 'unsafe-eval'",
|
"script-src 'self' 'nonce-{0}' 'unsafe-eval'",
|
||||||
@@ -135,5 +135,12 @@
|
|||||||
"Src": "/img/digital_data.svg",
|
"Src": "/img/digital_data.svg",
|
||||||
"ShowPageClass": "dd-show-logo",
|
"ShowPageClass": "dd-show-logo",
|
||||||
"LockedPageClass": "dd-locked-logo"
|
"LockedPageClass": "dd-locked-logo"
|
||||||
|
},
|
||||||
|
"MailConfig": {
|
||||||
|
"Placeholders": {
|
||||||
|
"[NAME_PORTAL]": "signFlow",
|
||||||
|
"[SIGNATURE_TYPE]": "signieren",
|
||||||
|
"[REASON]": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,5 +76,11 @@
|
|||||||
"inputFiles": [
|
"inputFiles": [
|
||||||
"wwwroot/css/privacy-policy.css"
|
"wwwroot/css/privacy-policy.css"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"outputFileName": "wwwroot/css/card.min.css",
|
||||||
|
"inputFiles": [
|
||||||
|
"wwwroot/css/card.css"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
126
EnvelopeGenerator.Web/wwwroot/css/card.css
Normal file
126
EnvelopeGenerator.Web/wwwroot/css/card.css
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css?family=Muli&display=swap');
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dd-cards-container {
|
||||||
|
font-family: 'Muli', sans-serif;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.dd-card {
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dd-card h6 {
|
||||||
|
opacity: 0.6;
|
||||||
|
margin: 0;
|
||||||
|
letter-spacing: 0.0625rem;
|
||||||
|
font-size: clamp(0.6rem, 1.33vw, 0.8rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dd-card h2 {
|
||||||
|
letter-spacing: 0.0625rem;
|
||||||
|
margin: 0;
|
||||||
|
font-size: clamp(1rem, 2.67vw, 1.67rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uppercase {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dd-card-preview {
|
||||||
|
background-color: #2A265F;
|
||||||
|
color: #fff;
|
||||||
|
padding: 0.1rem 1rem 1rem 1rem;
|
||||||
|
margin:0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dd-card-preview a {
|
||||||
|
color: #fff;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dd-card-preview button {
|
||||||
|
border-width: 0;
|
||||||
|
align-items: center;
|
||||||
|
background-color: transparent;
|
||||||
|
color: white;
|
||||||
|
margin: 15% 0 0 0;
|
||||||
|
transition: color 0.25s ease;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.dd-card-preview button:hover {
|
||||||
|
color: #bebebe;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dd-card-preview span {
|
||||||
|
}
|
||||||
|
|
||||||
|
.dd-card-info {
|
||||||
|
padding: clamp(0.55rem, 2vw, .875rem) 0 0 clamp(0.55rem, 2.5vw, 1.7rem);
|
||||||
|
margin: 0;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dd-card-info p, .dd-card-info a, .dd-card-info small, .dd-card-info span {
|
||||||
|
opacity: 0.65;
|
||||||
|
font-size: clamp(0.55rem, 1.23vw, 0.75rem);
|
||||||
|
margin: clamp(0.55rem, 2vw, .875rem) 0 clamp(0.55rem, 2vw, .875rem) 0;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-logo {
|
||||||
|
width: clamp(4rem, 10vw, 5rem);
|
||||||
|
margin: 1rem 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-container {
|
||||||
|
text-align: right;
|
||||||
|
width: 100%;
|
||||||
|
margin: clamp(0.8rem, 2vw, 1rem) 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
background-color: #ddd;
|
||||||
|
border-radius: 0.1875rem;
|
||||||
|
height: clamp(0.25rem, 1vw, 0.3125rem);
|
||||||
|
width: clamp(6rem, 20vw, 10rem);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress::after {
|
||||||
|
background-color: #2A265F;
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: clamp(0.25rem, 1vw, 0.3125rem);
|
||||||
|
width: var(--progress-width, 1%);
|
||||||
|
transition: width 1s ease;
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-text {
|
||||||
|
font-size: clamp(0.5rem, 1.5vw, 0.625rem);
|
||||||
|
opacity: 0.6;
|
||||||
|
letter-spacing: clamp(0.05rem, 0.5vw, 0.0625rem);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
1
EnvelopeGenerator.Web/wwwroot/css/card.min.css
vendored
Normal file
1
EnvelopeGenerator.Web/wwwroot/css/card.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css?family=Muli&display=swap');*{box-sizing:border-box}.dd-cards-container{font-family:'Muli',sans-serif;display:flex;align-items:center;justify-content:center;flex-direction:column}.dd-card{background-color:#fff;display:flex;max-width:100%;margin:0;overflow:hidden;width:100%}.dd-card h6{opacity:.6;margin:0;letter-spacing:.0625rem;font-size:clamp(.6rem,1.33vw,.8rem)}.dd-card h2{letter-spacing:.0625rem;margin:0;font-size:clamp(1rem,2.67vw,1.67rem)}.uppercase{text-transform:uppercase}.dd-card-preview{background-color:#2a265f;color:#fff;padding:.1rem 1rem 1rem 1rem;margin:0;display:flex;flex-direction:column;justify-content:center;align-items:center}.dd-card-preview a{color:#fff;opacity:.6}.dd-card-preview button{border-width:0;align-items:center;background-color:transparent;color:#fff;margin:15% 0 0 0;transition:color .25s ease}.dd-card-preview button:hover{color:#bebebe}.dd-card-info{padding:clamp(.55rem,2vw,.875rem) 0 0 clamp(.55rem,2.5vw,1.7rem);margin:0;position:relative;width:100%}.dd-card-info p,.dd-card-info a,.dd-card-info small,.dd-card-info span{opacity:.65;font-size:clamp(.55rem,1.23vw,.75rem);margin:clamp(.55rem,2vw,.875rem) 0 clamp(.55rem,2vw,.875rem) 0;text-decoration:none;padding:0}.app-logo{width:clamp(4rem,10vw,5rem);margin:1rem 0 0 0}.progress-container{text-align:right;width:100%;margin:clamp(.8rem,2vw,1rem) 0 0 0}.progress{background-color:#ddd;border-radius:.1875rem;height:clamp(.25rem,1vw,.3125rem);width:clamp(6rem,20vw,10rem);position:relative}.progress::after{background-color:#2a265f;content:'';position:absolute;top:0;left:0;height:clamp(.25rem,1vw,.3125rem);width:var(--progress-width,1%);transition:width 1s ease;opacity:.85}.progress-text{font-size:clamp(.5rem,1.5vw,.625rem);opacity:.6;letter-spacing:clamp(.05rem,.5vw,.0625rem);text-align:left}
|
||||||
@@ -5,6 +5,11 @@
|
|||||||
|
|
||||||
.dd-show-logo {
|
.dd-show-logo {
|
||||||
width: 9rem;
|
width: 9rem;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
margin: 0 2rem 0 0;
|
||||||
|
padding: 0;
|
||||||
|
top:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cursor-locked-logo {
|
.cursor-locked-logo {
|
||||||
@@ -19,6 +24,7 @@
|
|||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
.dd-show-logo {
|
.dd-show-logo {
|
||||||
width: 5rem;
|
width: 5rem;
|
||||||
|
margin-right: 0rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cursor-show-logo {
|
.cursor-show-logo {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
.dd-locked-logo{width:13rem;padding-top:1rem}.dd-show-logo{width:9rem}.cursor-locked-logo{width:9rem;padding-top:1rem}.cursor-show-logo{width:6rem}@media(max-width:767px){.dd-show-logo{width:5rem}.cursor-show-logo{width:3rem}}
|
.dd-locked-logo{width:13rem;padding-top:1rem}.dd-show-logo{width:9rem;position:absolute;right:0;margin:0 2rem 0 0;padding:0;top:0}.cursor-locked-logo{width:9rem;padding-top:1rem}.cursor-show-logo{width:6rem}@media(max-width:767px){.dd-show-logo{width:5rem;margin-right:0}.cursor-show-logo{width:3rem}}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
margin: 1.25rem;
|
margin: 1.25rem;
|
||||||
background-color: #f4f4f4;
|
background-color: #f4f4f4;
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
body{font-family:Arial,sans-serif;line-height:1.6;margin:1.25rem;background-color:#f4f4f4}header{text-align:center;margin:0 10rem 3rem 10rem;box-shadow:0 .25rem .5rem rgba(0,0,0,.1)}h1{color:#333}h2{color:#0056b3}section{background-color:#fff;padding:1.25rem;border-radius:.5rem;box-shadow:0 .25rem .5rem rgba(0,0,0,.1);margin:0 10rem 3rem 10rem}ul{list-style:disc inside}a{color:#0056b3;text-decoration:none}a:hover{text-decoration:underline}
|
body{font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.6;margin:1.25rem;background-color:#f4f4f4}header{text-align:center;margin:0 10rem 3rem 10rem;box-shadow:0 .25rem .5rem rgba(0,0,0,.1)}h1{color:#333}h2{color:#0056b3}section{background-color:#fff;padding:1.25rem;border-radius:.5rem;box-shadow:0 .25rem .5rem rgba(0,0,0,.1);margin:0 10rem 3rem 10rem}ul{list-style:disc inside}a{color:#0056b3;text-decoration:none}a:hover{text-decoration:underline}
|
||||||
@@ -4,22 +4,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Toolbar Buttons */
|
/* Toolbar Buttons */
|
||||||
#app {
|
|
||||||
background: gray;
|
|
||||||
width: 100vw;
|
|
||||||
height: 80vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-toggler {
|
.navbar-toggler {
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.material-symbols-outlined {
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-group {
|
.btn-group {
|
||||||
margin-right: 10vw;
|
margin-right: 10vw;
|
||||||
margin-bottom: 10vh;
|
margin-bottom: 10vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.btn_refresh, .btn_reject, .btn_complete {
|
.btn_refresh, .btn_reject, .btn_complete {
|
||||||
height:2.5rem;
|
height:2.5rem;
|
||||||
}
|
}
|
||||||
@@ -33,44 +31,94 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.button-finish {
|
.button-finish {
|
||||||
transition: background-color linear 300ms;
|
color: #fff;
|
||||||
background-color: #059669; /* emerald-600 */
|
background-color: #0d6efd;
|
||||||
color: white;
|
border-color: #0d6efd;
|
||||||
border-left: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-finish:hover, .button-finish:focus, .button-finish:active {
|
.button-finish:hover {
|
||||||
background-color: #10b981; /* emerald-500 */
|
color: #fff;
|
||||||
color: white;
|
background-color: #0b5ed7;
|
||||||
|
border-color: #0a58ca;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-finish:focus {
|
||||||
|
box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-finish:active {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #0a58ca;
|
||||||
|
border-color: #0a53be;
|
||||||
|
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-finish:disabled {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #0d6efd;
|
||||||
|
border-color: #0d6efd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-reject {
|
.button-reject {
|
||||||
transition: background-color linear 300ms;
|
color: #fff;
|
||||||
background-color: #d97706; /* amber-600 */
|
background-color: #dc3545;
|
||||||
color: white;
|
border-color: #dc3545;
|
||||||
border-left: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-reject:hover, .button-reject:focus, .button-reject:active {
|
.button-reject:hover {
|
||||||
background-color: #f59e0b; /* amber-500 */
|
color: #fff;
|
||||||
color: white;
|
background-color: #bb2d3b;
|
||||||
|
border-color: #b02a37;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-reject:focus {
|
||||||
|
box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-reject:active {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #b02a37;
|
||||||
|
border-color: #a52834;
|
||||||
|
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-reject:disabled {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #dc3545;
|
||||||
|
border-color: #dc3545;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-reset {
|
.button-reset {
|
||||||
transition: background-color linear 300ms;
|
color: #fff;
|
||||||
background-color: #2563eb; /* blue-600 */
|
background-color: #6c757d;
|
||||||
color: white;
|
border-color: #6c757d;
|
||||||
border-left: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-reset:hover, .button-reset:focus, .button-reset:active {
|
.button-reset:hover {
|
||||||
background-color: #3b82f6; /* blue-500 */
|
color: #fff;
|
||||||
color: white;
|
background-color: #5c636a;
|
||||||
|
border-color: #565e64;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-reset:focus {
|
||||||
|
box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-reset:active {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #565e64;
|
||||||
|
border-color: #51585e;
|
||||||
|
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-reset:disabled {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #6c757d;
|
||||||
|
border-color: #6c757d;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: #bbb;
|
background: #f8fcfc;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
@@ -78,16 +126,53 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
flex: 1;
|
display:flex;
|
||||||
|
margin: 0 0 0.5vh 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.envelope-view {
|
||||||
|
display: flex; /* d-flex */
|
||||||
|
flex-direction: column; /* flex-column */
|
||||||
|
width: 100vw;
|
||||||
|
height: 95.9vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
background: gray;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100%;
|
||||||
|
flex-grow: 1;
|
||||||
|
border-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
background: #333;
|
height: 4vh;
|
||||||
color: white;
|
min-height: 1.5rem;
|
||||||
text-align: center;
|
background-color: #001F61;
|
||||||
padding: 10px 0;
|
border-radius: 10px 10px 0 0;
|
||||||
|
color: #fff;
|
||||||
|
font-family: 'Muli';
|
||||||
|
padding: 0.5vh 0;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 998;
|
||||||
|
border-width: 0;
|
||||||
|
font-size: clamp(0.75rem, 1.5vw, 1rem);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
footer * {
|
||||||
|
margin-left: clamp(0.5rem, 2vw, 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
footer a {
|
||||||
|
color: #FF7500;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
margin-top: 3rem;
|
margin-top: 3rem;
|
||||||
@@ -129,6 +214,11 @@ footer {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page header .icon.expired {
|
||||||
|
background-color: rgba(228, 216, 213, 0.5);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
.page .form {
|
.page .form {
|
||||||
max-width: 30rem;
|
max-width: 30rem;
|
||||||
margin: 2rem auto;
|
margin: 2rem auto;
|
||||||
@@ -281,13 +371,44 @@ footer#page-footer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#form-access-code {
|
#form-access-code {
|
||||||
margin-left: 5rem;
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
|
||||||
|
.access-code-form-floating {
|
||||||
|
display: flex;
|
||||||
|
justify-content: start;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.access-code-form-floating button {
|
||||||
|
align-content: center;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.access-code-form-floating input {
|
||||||
|
align-content: center;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-right-width: 0;
|
||||||
|
width: 7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#access-code-error-message {
|
||||||
|
justify-content: center;
|
||||||
|
align-content: center;
|
||||||
|
margin: 1.5rem 7rem 0 7rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flag-dropdown button {
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-1 {
|
.header-1 {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin-top:0;
|
margin-top: 0;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,6 +419,30 @@ footer#page-footer {
|
|||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-receiver-explanation {
|
||||||
|
padding: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ajs-message.ajs-custom {
|
||||||
|
margin: 0rem 0rem 0rem 0rem;
|
||||||
|
padding: 0rem 0rem 0rem 0rem;
|
||||||
|
width:50rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ajs-message.ajs-custom .alert {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ajs-message.ajs-custom span {
|
||||||
|
margin: 0 1rem 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ajs-message.ajs-custom p {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* styles for mobile responsiveness */
|
/* styles for mobile responsiveness */
|
||||||
@media (max-height: 850px) {
|
@media (max-height: 850px) {
|
||||||
.navbar .container {
|
.navbar .container {
|
||||||
@@ -406,6 +551,12 @@ footer#page-footer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
#flex-action-panel, .btn-desktop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-height: 600px) {
|
@media (max-height: 600px) {
|
||||||
.collapse {
|
.collapse {
|
||||||
height: 4rem;
|
height: 4rem;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
41
EnvelopeGenerator.Web/wwwroot/img/sign_flow.svg
Normal file
41
EnvelopeGenerator.Web/wwwroot/img/sign_flow.svg
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 256">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
.cls-1 {
|
||||||
|
fill: #ffd631;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-1, .cls-2, .cls-3, .cls-4 {
|
||||||
|
stroke-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-2 {
|
||||||
|
fill: #a52431;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-3 {
|
||||||
|
fill: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-4 {
|
||||||
|
fill: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-5 {
|
||||||
|
clip-path: url(#clippath);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<clipPath id="clippath">
|
||||||
|
<rect class="cls-3" x="0" width="256" height="256"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
<g class="cls-5">
|
||||||
|
<rect class="cls-2" x="0" width="256" height="256" rx="48.67" ry="48.67"/>
|
||||||
|
</g>
|
||||||
|
<path class="cls-1" d="M153.29,63.22l-20.08,28.03h-10.42l-20.08-28.03,8.74-5.57h33.09l8.74,5.57ZM89.25,71.8l19.69,27.49-11.88,14.56-14.5-37.78,6.69-4.26ZM104.33,128.96l17.33-21.24h12.67l17.33,21.24-23.67,19.17-23.67-19.17ZM158.94,113.85l-11.88-14.56,19.69-27.49,6.69,4.26-14.5,37.78ZM149.16,42.03v-.03h-42.32v.03s-43.57,27.76-43.57,27.76l.28.44,25.76,67.11,38.62,30.89.06.07h.01s.01,0,.01,0l.05-.07,38.62-30.89,25.76-67.11.28-.44-43.57-27.76Z"/>
|
||||||
|
<path class="cls-1" d="M191.6,222.14h5.32l4.9-17.08,4.83,17.08h5.35l5.39-24.5h-5.04l-3.33,16.56-4.76-16.56h-4.79l-4.76,16.56-3.33-16.56h-5.21l5.43,24.5ZM171.79,217.87c-4.38,0-7.74-3.47-7.74-7.98s3.36-7.98,7.74-7.98,7.77,3.43,7.77,7.98-3.36,7.98-7.77,7.98M171.79,222.52c7.28,0,12.95-5.56,12.95-12.64s-5.67-12.63-12.95-12.63-12.95,5.56-12.95,12.63,5.71,12.64,12.95,12.64M139.3,222.14h18.48v-4.48h-13.4v-20.02h-5.07v24.5ZM115.9,222.14h5.07v-10.04h9.21v-4.27h-9.21v-5.78h13.86v-4.41h-18.93v24.5Z"/>
|
||||||
|
<path class="cls-4" d="M92.79,222.14h4.8v-12.63c.84-1.16,2.13-1.82,3.74-1.82,2.31,0,3.78,1.51,3.78,3.85v10.6h4.79v-11.31c0-4.31-2.97-7.28-7.21-7.28-2,0-3.75.63-5.11,1.82v-1.47h-4.8v18.24ZM78.07,218.18c-2.97,0-5.25-2.31-5.25-5.29s2.31-5.18,5.28-5.18c1.68,0,3.19.63,4.24,1.65v7.14c-1.05,1.08-2.52,1.68-4.27,1.68M78.1,229.63c5.85,0,9.03-2.69,9.03-7.52v-18.2h-4.72v1.19c-1.44-.94-3.15-1.47-4.94-1.47-5.25,0-9.38,4.09-9.38,9.27s4.1,9.35,9.24,9.35c1.82,0,3.54-.59,5-1.65v1.44c0,2.41-1.47,3.64-4.34,3.64-1.93,0-3.82-.45-5.81-1.44l-1.68,3.71c2.13,1.08,4.79,1.68,7.59,1.68M58.75,222.14h4.8v-18.24h-4.8v18.24ZM61.13,201.73c1.51,0,2.73-1.26,2.73-2.73s-1.22-2.73-2.73-2.73-2.73,1.23-2.73,2.73,1.22,2.73,2.73,2.73M46.42,222.49c4.58,0,7.98-2.55,7.98-6.02,0-2.84-2-4.69-5.57-5.22l-3.5-.53c-1.78-.24-2.49-.74-2.49-1.75s1.16-1.78,2.87-1.78c1.85,0,3.64.56,5.63,1.78l2.31-3.12c-2.28-1.5-4.83-2.27-7.49-2.27-4.65,0-7.59,2.27-7.59,5.77,0,2.94,1.92,4.8,5.53,5.32l3.5.52c1.58.24,2.27.77,2.27,1.72,0,1.19-1.4,1.96-3.53,1.96-1.92,0-3.78-.66-5.91-2.1l-2.38,3.19c2.06,1.64,5.04,2.52,8.37,2.52"/>
|
||||||
|
<rect class="cls-3" x="0" width="256" height="256"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1,5 @@
|
|||||||
|
<svg width="199" height="95" viewBox="0 0 199 95" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M67.515 15.8772L52.455 36.8498H44.64L29.58 15.8772L36.135 11.7096H60.9525L67.5075 15.8772H67.515ZM19.485 22.2969L34.2525 42.8654L25.3425 53.7595L14.4675 25.4918L19.485 22.3044V22.2969ZM30.795 65.0651L43.7925 49.1729H53.295L66.2925 65.0651L48.54 79.4084L30.7875 65.0651H30.795ZM71.7525 53.7595L62.8425 42.8654L77.61 22.2969L82.6275 25.4843L71.7525 53.752V53.7595ZM64.4175 0.0224456V0H32.6775V0.0224456L0 20.793L0.209999 21.1222L19.53 71.3352L48.495 94.4476L48.54 94.5H48.5475H48.555L48.5925 94.4476L77.5575 71.3352L96.8775 21.1222L97.0875 20.793L64.41 0.0224456H64.4175Z" fill="#FFD631"/>
|
||||||
|
<path d="M180.74 34.5908H185.54V22.0971C186.38 20.9496 187.67 20.2968 189.28 20.2968C191.59 20.2968 193.06 21.7905 193.06 24.1052V34.5908H197.85V23.4029C197.85 19.1394 194.88 16.2014 190.64 16.2014C188.64 16.2014 186.89 16.8246 185.53 18.0018V16.5477H180.73V34.5908H180.74ZM166.02 30.6735C163.05 30.6735 160.77 28.3885 160.77 25.4406C160.77 22.4928 163.08 20.3165 166.05 20.3165C167.73 20.3165 169.24 20.9397 170.29 21.9487V29.0117C169.24 30.08 167.77 30.6735 166.02 30.6735ZM166.05 42C171.9 42 175.08 39.339 175.08 34.5611V16.5576H170.36V17.7347C168.92 16.8049 167.21 16.2806 165.42 16.2806C160.17 16.2806 156.04 20.3264 156.04 25.4505C156.04 30.5746 160.14 34.6996 165.28 34.6996C167.1 34.6996 168.82 34.116 170.28 33.0674V34.4919C170.28 36.8759 168.81 38.0926 165.94 38.0926C164.01 38.0926 162.12 37.6475 160.13 36.6682L158.45 40.3381C160.58 41.4065 163.24 42 166.04 42M146.7 34.5908H151.5V16.5477H146.7V34.5908ZM149.08 14.4011C150.59 14.4011 151.81 13.1547 151.81 11.7005C151.81 10.2464 150.59 9 149.08 9C147.57 9 146.35 10.2167 146.35 11.7005C146.35 13.1843 147.57 14.4011 149.08 14.4011ZM134.37 34.9371C138.95 34.9371 142.35 32.4146 142.35 28.982C142.35 26.1727 140.35 24.3426 136.78 23.8183L133.28 23.2941C131.5 23.0567 130.79 22.562 130.79 21.5629C130.79 20.5638 131.95 19.8022 133.66 19.8022C135.51 19.8022 137.3 20.3561 139.29 21.5629L141.6 18.4766C139.32 16.9928 136.77 16.2311 134.11 16.2311C129.46 16.2311 126.52 18.4766 126.52 21.9389C126.52 24.8471 128.44 26.687 132.05 27.2014L135.55 27.7158C137.13 27.9532 137.82 28.4775 137.82 29.4173C137.82 30.5944 136.42 31.3561 134.29 31.3561C132.37 31.3561 130.51 30.7032 128.38 29.2788L126 32.4344C128.06 34.0567 131.04 34.9271 134.37 34.9271" fill="white"/>
|
||||||
|
<path d="M172.7 84.6241H178.02L182.92 67.7265L187.75 84.6241H193.1L198.49 60.3858H193.45L190.12 76.7689L185.36 60.3858H180.57L175.81 76.7689L172.48 60.3858H167.27L172.7 84.6241ZM152.89 80.3997C148.51 80.3997 145.15 76.9668 145.15 72.5049C145.15 68.0431 148.51 64.6102 152.89 64.6102C157.27 64.6102 160.66 68.0036 160.66 72.5049C160.66 77.0063 157.3 80.3997 152.89 80.3997ZM152.89 85C160.17 85 165.84 79.4994 165.84 72.4951C165.84 65.4907 160.17 60 152.89 60C145.61 60 139.94 65.5006 139.94 72.4951C139.94 79.4895 145.65 85 152.89 85ZM120.4 84.6241H138.88V80.1919H125.48V60.3858H120.41V84.6241H120.4ZM97 84.6241H102.07V74.6913H111.28V70.467H102.07V64.7487H115.93V60.3858H97V84.6241Z" fill="#FFD631"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -253,6 +253,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async createAnnotationFrameBlob(receiverName, receiverSignature, timestamp, width, height) {
|
static async createAnnotationFrameBlob(receiverName, receiverSignature, timestamp, width, height) {
|
||||||
|
Comp.SignatureProgress.SignedCount += 1;
|
||||||
const canvas = document.createElement('canvas')
|
const canvas = document.createElement('canvas')
|
||||||
const scale = 4
|
const scale = 4
|
||||||
const fontSize = 10
|
const fontSize = 10
|
||||||
|
|||||||
@@ -1,25 +1,29 @@
|
|||||||
class Content {
|
class Content {
|
||||||
static get JSON () {
|
static get JSON() {
|
||||||
return 'application/json';
|
return 'application/json';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class API {
|
class API {
|
||||||
static get REJECT_URL () {
|
static get REJECT_URL() {
|
||||||
return `/api/envelope/reject`;
|
return `/api/envelope/reject`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get REJECT_REDIR_URL(){
|
static get REJECT_REDIR_URL() {
|
||||||
return `/envelopekey/${API.ENV_KEY}/rejected`;
|
return `/envelopekey/${API.ENV_KEY}/rejected`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get SHARE_URL() {
|
||||||
|
return `/api/readonly`
|
||||||
|
}
|
||||||
|
|
||||||
static __XSRF_TOKEN
|
static __XSRF_TOKEN
|
||||||
static get XSRF_TOKEN() {
|
static get XSRF_TOKEN() {
|
||||||
API.__XSRF_TOKEN ??= document.getElementsByName('__RequestVerificationToken')[0].value;
|
API.__XSRF_TOKEN ??= document.getElementsByName('__RequestVerificationToken')[0].value;
|
||||||
return API.__XSRF_TOKEN;
|
return API.__XSRF_TOKEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get ENV_KEY(){
|
static get ENV_KEY() {
|
||||||
return ENV_KEY ?? document.querySelector('meta[name="env-key"]').getAttribute('content');
|
return ENV_KEY ?? document.querySelector('meta[name="env-key"]').getAttribute('content');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,20 +32,20 @@ const submitForm = async form => await fetch(form.action, {
|
|||||||
method: form.method,
|
method: form.method,
|
||||||
body: new FormData(form),
|
body: new FormData(form),
|
||||||
headers: {
|
headers: {
|
||||||
"X-Requested-With": "XMLHttpRequest"
|
"X-Requested-With": "XMLHttpRequest"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const createRequest = async (method, url, body, contentType) => {
|
const createRequest = async (method, url, body, contentType) => {
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
method: method,
|
method: method,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': contentType,
|
'Content-Type': contentType,
|
||||||
'X-XSRF-TOKEN': API.XSRF_TOKEN
|
'X-XSRF-TOKEN': API.XSRF_TOKEN
|
||||||
},
|
},
|
||||||
body: JSON.stringify(body)
|
body: JSON.stringify(body)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const createPost = (url, body, contentType) => createRequest('POST', url, body, contentType);
|
const createPost = (url, body, contentType) => createRequest('POST', url, body, contentType);
|
||||||
@@ -50,4 +54,6 @@ const rejectEnvelope = (reason) => createPost(API.REJECT_URL, reason, Content.JS
|
|||||||
|
|
||||||
const redirect = (url) => window.location.href = url;
|
const redirect = (url) => window.location.href = url;
|
||||||
|
|
||||||
const redirRejected = () => redirect(API.REJECT_REDIR_URL);
|
const redirRejected = () => redirect(API.REJECT_REDIR_URL);
|
||||||
|
|
||||||
|
const shareEnvelope = (receiverMail, dateValid) => createPost(API.SHARE_URL, { receiverMail: receiverMail, dateValid: dateValid }, Content.JSON);
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
class Content{static get JSON(){return"application/json"}}class API{static get REJECT_URL(){return`/api/envelope/reject`}static get REJECT_REDIR_URL(){return`/envelopekey/${API.ENV_KEY}/rejected`}static __XSRF_TOKEN
|
class Content{static get JSON(){return"application/json"}}class API{static get REJECT_URL(){return`/api/envelope/reject`}static get REJECT_REDIR_URL(){return`/envelopekey/${API.ENV_KEY}/rejected`}static get SHARE_URL(){return`/api/readonly`}static __XSRF_TOKEN
|
||||||
static get XSRF_TOKEN(){return API.__XSRF_TOKEN??=document.getElementsByName("__RequestVerificationToken")[0].value,API.__XSRF_TOKEN}static get ENV_KEY(){return ENV_KEY??document.querySelector('meta[name="env-key"]').getAttribute("content")}}const submitForm=async n=>await fetch(n.action,{method:n.method,body:new FormData(n),headers:{"X-Requested-With":"XMLHttpRequest"}}),createRequest=async(n,t,i,r)=>fetch(t,{credentials:"include",method:n,headers:{"Content-Type":r,"X-XSRF-TOKEN":API.XSRF_TOKEN},body:JSON.stringify(i)}),createPost=(n,t,i)=>createRequest("POST",n,t,i),rejectEnvelope=n=>createPost(API.REJECT_URL,n,Content.JSON),redirect=n=>window.location.href=n,redirRejected=()=>redirect(API.REJECT_REDIR_URL);
|
static get XSRF_TOKEN(){return API.__XSRF_TOKEN??=document.getElementsByName("__RequestVerificationToken")[0].value,API.__XSRF_TOKEN}static get ENV_KEY(){return ENV_KEY??document.querySelector('meta[name="env-key"]').getAttribute("content")}}const submitForm=async n=>await fetch(n.action,{method:n.method,body:new FormData(n),headers:{"X-Requested-With":"XMLHttpRequest"}}),createRequest=async(n,t,i,r)=>fetch(t,{credentials:"include",method:n,headers:{"Content-Type":r,"X-XSRF-TOKEN":API.XSRF_TOKEN},body:JSON.stringify(i)}),createPost=(n,t,i)=>createRequest("POST",n,t,i),rejectEnvelope=n=>createPost(API.REJECT_URL,n,Content.JSON),redirect=n=>window.location.href=n,redirRejected=()=>redirect(API.REJECT_REDIR_URL),shareEnvelope=(n,t)=>createPost(API.SHARE_URL,{receiverMail:n,dateValid:t},Content.JSON);
|
||||||
@@ -48,7 +48,7 @@ class App {
|
|||||||
|
|
||||||
// Load PSPDFKit
|
// Load PSPDFKit
|
||||||
this.Instance = await UI.loadPSPDFKit(arrayBuffer, this.container, this.licenseKey, this.locale)
|
this.Instance = await UI.loadPSPDFKit(arrayBuffer, this.container, this.licenseKey, this.locale)
|
||||||
UI.configurePSPDFKit(this.Instance, this.handleClick.bind(this))
|
UI.addToolbarItems(this.Instance, this.handleClick.bind(this))
|
||||||
|
|
||||||
this.Instance.addEventListener(
|
this.Instance.addEventListener(
|
||||||
'annotations.load',
|
'annotations.load',
|
||||||
@@ -87,6 +87,7 @@ class App {
|
|||||||
//add click events of external buttons
|
//add click events of external buttons
|
||||||
[...document.getElementsByClassName('btn_refresh')].forEach(btn => btn.addEventListener('click', _ => this.handleClick('RESET')));
|
[...document.getElementsByClassName('btn_refresh')].forEach(btn => btn.addEventListener('click', _ => this.handleClick('RESET')));
|
||||||
[...document.getElementsByClassName('btn_complete')].forEach(btn => btn.addEventListener('click', _ => this.handleClick('FINISH')));
|
[...document.getElementsByClassName('btn_complete')].forEach(btn => btn.addEventListener('click', _ => this.handleClick('FINISH')));
|
||||||
|
[...document.getElementsByClassName('btn_reject')].forEach(btn => btn.addEventListener('click', _ => this.handleClick('REJECT')));
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAnnotationsLoad(loadedAnnotations) {
|
handleAnnotationsLoad(loadedAnnotations) {
|
||||||
@@ -141,7 +142,7 @@ class App {
|
|||||||
switch (eventType) {
|
switch (eventType) {
|
||||||
case 'RESET':
|
case 'RESET':
|
||||||
result = await this.handleReset(null)
|
result = await this.handleReset(null)
|
||||||
|
Comp.SignatureProgress.SignedCount = 0;
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Erfolg',
|
title: 'Erfolg',
|
||||||
@@ -149,8 +150,7 @@ class App {
|
|||||||
icon: 'info',
|
icon: 'info',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
break
|
|
||||||
|
|
||||||
case 'FINISH':
|
case 'FINISH':
|
||||||
result = await this.handleFinish(null)
|
result = await this.handleFinish(null)
|
||||||
@@ -159,23 +159,70 @@ class App {
|
|||||||
// Redirect to success page after saving to database
|
// Redirect to success page after saving to database
|
||||||
window.location.href = `/EnvelopeKey/${this.envelopeKey}/Success`
|
window.location.href = `/EnvelopeKey/${this.envelopeKey}/Success`
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
break
|
|
||||||
|
|
||||||
case 'REJECT':
|
case 'REJECT':
|
||||||
alert('Dokument abgelent!')
|
Swal.fire({
|
||||||
|
title: localized.rejection,
|
||||||
|
html: `<div class="text-start fs-6 p-0 m-0">${localized.rejectionReasonQ}</div>`,
|
||||||
|
icon: "question",
|
||||||
|
input: "text",
|
||||||
|
inputAttributes: {
|
||||||
|
autocapitalize: "off"
|
||||||
|
},
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: "#3085d6",
|
||||||
|
cancelButtonColor: "#d33",
|
||||||
|
confirmButtonText: localized.complete,
|
||||||
|
cancelButtonText: localized.back,
|
||||||
|
showLoaderOnConfirm: true,
|
||||||
|
preConfirm: async (reason) => {
|
||||||
|
try {
|
||||||
|
var res = await rejectEnvelope(reason);
|
||||||
|
return res;
|
||||||
|
} catch (error) {
|
||||||
|
Swal.showValidationMessage(`
|
||||||
|
Request failed: ${error}
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
allowOutsideClick: () => !Swal.isLoading()
|
||||||
|
}).then((result) => {
|
||||||
|
if (!result.isConfirmed)
|
||||||
|
return;
|
||||||
|
const res = result.value;
|
||||||
|
if (res.ok) {
|
||||||
|
redirRejected()
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Swal.showValidationMessage(`Request failed: ${res.message}`);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'COPY_URL':
|
||||||
|
const url = window.location.href;
|
||||||
|
navigator.clipboard.writeText(url).then(function () {
|
||||||
|
bsNotify('Kopiert', { alert_type: 'success', delay: 4, icon_name: 'check_circle' });
|
||||||
|
}).catch(function (err) {
|
||||||
|
bsNotify('Unerwarteter Fehler', { alert_type: 'danger', delay: 4, icon_name: 'error' });
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'SHARE':
|
||||||
|
// Show the modal
|
||||||
|
Comp.ShareBackdrop.show();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleFinish(event) {
|
async handleFinish(event) {
|
||||||
const iJSON = await this.Instance.exportInstantJSON()
|
const iJSON = await this.Instance.exportInstantJSON()
|
||||||
const iFormFieldValues = await iJSON.formFieldValues;
|
const iFormFieldValues = await iJSON.formFieldValues;
|
||||||
|
|
||||||
//check required
|
//check required
|
||||||
const iReqFields = iFormFieldValues.filter(f => Annotation.isFieldRequired(f))
|
const iReqFields = iFormFieldValues.filter(f => Annotation.isFieldRequired(f))
|
||||||
const hasEmptyReq = iReqFields.some(f => (f.value === undefined || f.value === null || f.value === ""))
|
const hasEmptyReq = iReqFields.some(f => (f.value === undefined || f.value === null || f.value === ""))
|
||||||
|
|
||||||
if (hasEmptyReq){
|
if (hasEmptyReq) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Warnung',
|
title: 'Warnung',
|
||||||
text: 'Bitte füllen Sie alle Standortinformationen vollständig aus!',
|
text: 'Bitte füllen Sie alle Standortinformationen vollständig aus!',
|
||||||
@@ -187,8 +234,8 @@ class App {
|
|||||||
//check city
|
//check city
|
||||||
const city_regex = new RegExp("^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$")
|
const city_regex = new RegExp("^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$")
|
||||||
const iCityFields = iFormFieldValues.filter(f => Annotation.isCityField(f))
|
const iCityFields = iFormFieldValues.filter(f => Annotation.isCityField(f))
|
||||||
for(var f of iCityFields)
|
for (var f of iCityFields)
|
||||||
if(!city_regex.test(f.value)){
|
if (!city_regex.test(f.value)) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Warnung',
|
title: 'Warnung',
|
||||||
text: `Bitte überprüfen Sie die eingegebene Ortsangabe "${f.value}" auf korrekte Formatierung. Beispiele für richtige Formate sind: München, Île-de-France, Sauðárkrókur, San Francisco, St. Catharines usw.`,
|
text: `Bitte überprüfen Sie die eingegebene Ortsangabe "${f.value}" auf korrekte Formatierung. Beispiele für richtige Formate sind: München, Île-de-France, Sauðárkrókur, San Francisco, St. Catharines usw.`,
|
||||||
|
|||||||
4
EnvelopeGenerator.Web/wwwroot/js/app.min.js
vendored
4
EnvelopeGenerator.Web/wwwroot/js/app.min.js
vendored
@@ -1 +1,3 @@
|
|||||||
const ActionType={Created:0,Saved:1,Sent:2,EmailSent:3,Delivered:4,Seen:5,Signed:6,Rejected:7};class App{constructor(n,t,i,r,u,f){this.container=f??`#${this.constructor.name.toLowerCase()}`;this.envelopeKey=n;this.Network=new Network;this.Instance=null;this.currentDocument=null;this.currentReceiver=null;this.signatureCount=0;this.envelopeReceiver=t;this.documentBytes=i;this.licenseKey=r;this.locale=u}async init(){this.currentDocument=this.envelopeReceiver.envelope.documents[0];this.currentReceiver=this.envelopeReceiver.receiver;const n=this.documentBytes;if(n.fatal||n.error)return Swal.fire({title:"Fehler",text:"Dokument konnte nicht geladen werden!",icon:"error"});const t=this.documentBytes;this.Instance=await UI.loadPSPDFKit(t,this.container,this.licenseKey,this.locale);UI.configurePSPDFKit(this.Instance,this.handleClick.bind(this));this.Instance.addEventListener("annotations.load",this.handleAnnotationsLoad.bind(this));this.Instance.addEventListener("annotations.change",this.handleAnnotationsChange.bind(this));this.Instance.addEventListener("annotations.create",this.handleAnnotationsCreate.bind(this));this.Instance.addEventListener("annotations.willChange",()=>{Comp.ActPanel.Toggle()});try{this.signatureCount=this.currentDocument.elements.length;await Annotation.createAnnotations(this.currentDocument,this.Instance);const n=await this.Network.openDocument(this.envelopeKey);if(n.fatal||n.error)return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht geöffnet werden!",icon:"error"})}catch(i){}[...document.getElementsByClassName("btn_refresh")].forEach(n=>n.addEventListener("click",()=>this.handleClick("RESET")));[...document.getElementsByClassName("btn_complete")].forEach(n=>n.addEventListener("click",()=>this.handleClick("FINISH")))}handleAnnotationsLoad(n){n.toJS()}handleAnnotationsChange(){}async handleAnnotationsCreate(n){const t=n.toJS()[0],i=!!t.formFieldName,r=!!t.isSignature;if(i===!1&&r===!0){const r=t.boundingBox.left-20,u=t.boundingBox.top-20,n=150,i=75,f=new Date,e=await Annotation.createAnnotationFrameBlob(this.envelopeReceiver.name,this.currentReceiver.signature,f,n,i),o=await fetch(e),s=await o.blob(),h=await this.Instance.createAttachment(s),c=Annotation.createImageAnnotation(new PSPDFKit.Geometry.Rect({left:r,top:u,width:n,height:i}),t.pageIndex,h);this.Instance.create(c)}}async handleClick(n){let t=!1;switch(n){case"RESET":t=await this.handleReset(null);t.isConfirmed&&Swal.fire({title:"Erfolg",text:"Dokument wurde zurückgesetzt",icon:"info"});break;case"FINISH":t=await this.handleFinish(null);t==!0&&(window.location.href=`/EnvelopeKey/${this.envelopeKey}/Success`);break;case"REJECT":alert("Dokument abgelent!")}}async handleFinish(){const n=await this.Instance.exportInstantJSON(),t=await n.formFieldValues,r=t.filter(n=>Annotation.isFieldRequired(n)),u=r.some(n=>n.value===undefined||n.value===null||n.value==="");if(u)return Swal.fire({title:"Warnung",text:"Bitte füllen Sie alle Standortinformationen vollständig aus!",icon:"warning"}),!1;const f=new RegExp("^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$"),e=t.filter(n=>Annotation.isCityField(n));for(var i of e)if(!f.test(i.value))return Swal.fire({title:"Warnung",text:`Bitte überprüfen Sie die eingegebene Ortsangabe "${i.value}" auf korrekte Formatierung. Beispiele für richtige Formate sind: München, Île-de-France, Sauðárkrókur, San Francisco, St. Catharines usw.`,icon:"warning"}),!1;const o=await this.validateAnnotations(this.signatureCount);return o===!1?(Swal.fire({title:"Warnung",text:"Es wurden nicht alle Signaturfelder ausgefüllt!",icon:"warning"}),!1):Swal.fire({title:localized.confirmation,html:`<div class="text-start fs-6 p-0 m-0">${localized.sigAgree}</div>`,icon:"question",showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.finalize,cancelButtonText:localized.back}).then(async t=>{if(t.isConfirmed){try{await this.Instance.save()}catch(i){return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1}try{const i=await n,t=await this.Network.postEnvelope(this.envelopeKey,this.currentDocument.id,i);return t.fatal?(Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1):t.error?(Swal.fire({title:"Warnung",text:"Umschlag ist nicht mehr verfügbar.",icon:"warning"}),!1):!0}catch(i){return!1}}else return!1})}async validateAnnotations(n){const t=await Annotation.getAnnotations(this.Instance),i=t.map(n=>n.toJS()).filter(n=>n.isSignature);return n>i.length?!1:!0}async handleReset(){const n=await Swal.fire({title:"Sind sie sicher?",text:"Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?",icon:"question",showCancelButton:!0});if(n.isConfirmed){const n=await Annotation.deleteAnnotations(this.Instance)}return n}}
|
const ActionType={Created:0,Saved:1,Sent:2,EmailSent:3,Delivered:4,Seen:5,Signed:6,Rejected:7};class App{constructor(n,t,i,r,u,f){this.container=f??`#${this.constructor.name.toLowerCase()}`;this.envelopeKey=n;this.Network=new Network;this.Instance=null;this.currentDocument=null;this.currentReceiver=null;this.signatureCount=0;this.envelopeReceiver=t;this.documentBytes=i;this.licenseKey=r;this.locale=u}async init(){this.currentDocument=this.envelopeReceiver.envelope.documents[0];this.currentReceiver=this.envelopeReceiver.receiver;const n=this.documentBytes;if(n.fatal||n.error)return Swal.fire({title:"Fehler",text:"Dokument konnte nicht geladen werden!",icon:"error"});const t=this.documentBytes;this.Instance=await UI.loadPSPDFKit(t,this.container,this.licenseKey,this.locale);UI.addToolbarItems(this.Instance,this.handleClick.bind(this));this.Instance.addEventListener("annotations.load",this.handleAnnotationsLoad.bind(this));this.Instance.addEventListener("annotations.change",this.handleAnnotationsChange.bind(this));this.Instance.addEventListener("annotations.create",this.handleAnnotationsCreate.bind(this));this.Instance.addEventListener("annotations.willChange",()=>{Comp.ActPanel.Toggle()});try{this.signatureCount=this.currentDocument.elements.length;await Annotation.createAnnotations(this.currentDocument,this.Instance);const n=await this.Network.openDocument(this.envelopeKey);if(n.fatal||n.error)return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht geöffnet werden!",icon:"error"})}catch(i){}[...document.getElementsByClassName("btn_refresh")].forEach(n=>n.addEventListener("click",()=>this.handleClick("RESET")));[...document.getElementsByClassName("btn_complete")].forEach(n=>n.addEventListener("click",()=>this.handleClick("FINISH")));[...document.getElementsByClassName("btn_reject")].forEach(n=>n.addEventListener("click",()=>this.handleClick("REJECT")))}handleAnnotationsLoad(n){n.toJS()}handleAnnotationsChange(){}async handleAnnotationsCreate(n){const t=n.toJS()[0],i=!!t.formFieldName,r=!!t.isSignature;if(i===!1&&r===!0){const r=t.boundingBox.left-20,u=t.boundingBox.top-20,n=150,i=75,f=new Date,e=await Annotation.createAnnotationFrameBlob(this.envelopeReceiver.name,this.currentReceiver.signature,f,n,i),o=await fetch(e),s=await o.blob(),h=await this.Instance.createAttachment(s),c=Annotation.createImageAnnotation(new PSPDFKit.Geometry.Rect({left:r,top:u,width:n,height:i}),t.pageIndex,h);this.Instance.create(c)}}async handleClick(n){let t=!1;switch(n){case"RESET":t=await this.handleReset(null);Comp.SignatureProgress.SignedCount=0;t.isConfirmed&&Swal.fire({title:"Erfolg",text:"Dokument wurde zurückgesetzt",icon:"info"});break;case"FINISH":t=await this.handleFinish(null);t==!0&&(window.location.href=`/EnvelopeKey/${this.envelopeKey}/Success`);break;case"REJECT":Swal.fire({title:localized.rejection,html:`<div class="text-start fs-6 p-0 m-0">${localized.rejectionReasonQ}</div>`,icon:"question",input:"text",inputAttributes:{autocapitalize:"off"},showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.complete,cancelButtonText:localized.back,showLoaderOnConfirm:!0,preConfirm:async n=>{try{return await rejectEnvelope(n)}catch(t){Swal.showValidationMessage(`
|
||||||
|
Request failed: ${t}
|
||||||
|
`)}},allowOutsideClick:()=>!Swal.isLoading()}).then(n=>{if(n.isConfirmed){const t=n.value;t.ok?redirRejected():Swal.showValidationMessage(`Request failed: ${t.message}`)}});break;case"COPY_URL":const n=window.location.href;navigator.clipboard.writeText(n).then(function(){bsNotify("Kopiert",{alert_type:"success",delay:4,icon_name:"check_circle"})}).catch(function(){bsNotify("Unerwarteter Fehler",{alert_type:"danger",delay:4,icon_name:"error"})});break;case"SHARE":Comp.ShareBackdrop.show()}}async handleFinish(){const n=await this.Instance.exportInstantJSON(),t=await n.formFieldValues,r=t.filter(n=>Annotation.isFieldRequired(n)),u=r.some(n=>n.value===undefined||n.value===null||n.value==="");if(u)return Swal.fire({title:"Warnung",text:"Bitte füllen Sie alle Standortinformationen vollständig aus!",icon:"warning"}),!1;const f=new RegExp("^[a-zA-Z\\u0080-\\u024F]+(?:([\\ \\-\\']|(\\.\\ ))[a-zA-Z\\u0080-\\u024F]+)*$"),e=t.filter(n=>Annotation.isCityField(n));for(var i of e)if(!f.test(i.value))return Swal.fire({title:"Warnung",text:`Bitte überprüfen Sie die eingegebene Ortsangabe "${i.value}" auf korrekte Formatierung. Beispiele für richtige Formate sind: München, Île-de-France, Sauðárkrókur, San Francisco, St. Catharines usw.`,icon:"warning"}),!1;const o=await this.validateAnnotations(this.signatureCount);return o===!1?(Swal.fire({title:"Warnung",text:"Es wurden nicht alle Signaturfelder ausgefüllt!",icon:"warning"}),!1):Swal.fire({title:localized.confirmation,html:`<div class="text-start fs-6 p-0 m-0">${localized.sigAgree}</div>`,icon:"question",showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.finalize,cancelButtonText:localized.back}).then(async t=>{if(t.isConfirmed){try{await this.Instance.save()}catch(i){return Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1}try{const i=await n,t=await this.Network.postEnvelope(this.envelopeKey,this.currentDocument.id,i);return t.fatal?(Swal.fire({title:"Fehler",text:"Umschlag konnte nicht signiert werden!",icon:"error"}),!1):t.error?(Swal.fire({title:"Warnung",text:"Umschlag ist nicht mehr verfügbar.",icon:"warning"}),!1):!0}catch(i){return!1}}else return!1})}async validateAnnotations(n){const t=await Annotation.getAnnotations(this.Instance),i=t.map(n=>n.toJS()).filter(n=>n.isSignature);return n>i.length?!1:!0}async handleReset(){const n=await Swal.fire({title:"Sind sie sicher?",text:"Wollen Sie das Dokument und alle erstellten Signaturen zurücksetzen?",icon:"question",showCancelButton:!0});if(n.isConfirmed){const n=await Annotation.deleteAnnotations(this.Instance)}return n}}
|
||||||
@@ -1,40 +1,17 @@
|
|||||||
$('.btn_reject').click(_ =>
|
document.querySelectorAll('.email-input').forEach(input => {
|
||||||
Swal.fire({
|
input.addEventListener('input', function () {
|
||||||
title: localized.rejection,
|
if (/^\S+@\S+\.\S+$/.test(this.value)) {
|
||||||
html: `<div class="text-start fs-6 p-0 m-0">${localized.rejectionReasonQ}</div>`,
|
this.classList.remove('is-invalid');
|
||||||
icon: "question",
|
} else {
|
||||||
input: "text",
|
this.classList.add('is-invalid');
|
||||||
inputAttributes: {
|
|
||||||
autocapitalize: "off"
|
|
||||||
},
|
|
||||||
showCancelButton: true,
|
|
||||||
confirmButtonColor: "#3085d6",
|
|
||||||
cancelButtonColor: "#d33",
|
|
||||||
confirmButtonText: localized.complete,
|
|
||||||
cancelButtonText: localized.back,
|
|
||||||
showLoaderOnConfirm: true,
|
|
||||||
preConfirm: async (reason) => {
|
|
||||||
try {
|
|
||||||
var res = await rejectEnvelope(reason);
|
|
||||||
return res;
|
|
||||||
} catch (error) {
|
|
||||||
Swal.showValidationMessage(`
|
|
||||||
Request failed: ${error}
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
allowOutsideClick: () => !Swal.isLoading()
|
|
||||||
}).then((result) => {
|
|
||||||
if (!result.isConfirmed)
|
|
||||||
return;
|
|
||||||
const res = result.value;
|
|
||||||
if (res.ok) {
|
|
||||||
redirRejected()
|
|
||||||
}
|
}
|
||||||
else
|
});
|
||||||
Swal.showValidationMessage(`Request failed: ${res.message}`);
|
});
|
||||||
}));
|
|
||||||
|
|
||||||
|
const bsNotify = (message, options) => alertify.notify(
|
||||||
|
`<div class="alert ${options.alert_type ? 'alert-' + options.alert_type : ''}" role="alert"><span class="material-symbols-outlined">${options?.icon_name ?? ''}</span><p>${message}</p></div>`,
|
||||||
|
'custom',
|
||||||
|
options?.delay ?? 5);
|
||||||
|
|
||||||
class Comp {
|
class Comp {
|
||||||
static ActPanel = class {
|
static ActPanel = class {
|
||||||
@@ -64,4 +41,42 @@ class Comp {
|
|||||||
Comp.ActPanel.Display = Comp.ActPanel.IsHided ? '' : 'none'
|
Comp.ActPanel.Display = Comp.ActPanel.IsHided ? '' : 'none'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SignatureProgress = class {
|
||||||
|
static __SignatureCount;
|
||||||
|
static get SignatureCount() {
|
||||||
|
this.__SignatureCount = parseInt(document.getElementById("signature-count").innerText);
|
||||||
|
return this.__SignatureCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __SignedCountSpan;
|
||||||
|
static get SignedCountSpan() {
|
||||||
|
this.__SignedCountSpan ??= document.getElementById("signed-count");
|
||||||
|
return Comp.SignatureProgress.__SignedCountSpan;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __signedCount = 0;
|
||||||
|
static get SignedCount() {
|
||||||
|
return this.__signedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static set SignedCount(value) {
|
||||||
|
this.__signedCount = value;
|
||||||
|
const width = (value / this.SignatureCount) * 100;
|
||||||
|
this.SignedCountBar.style.setProperty('--progress-width', width + '%');
|
||||||
|
this.SignedCountSpan.innerText = value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
static __SignedCountBar;
|
||||||
|
static get SignedCountBar() {
|
||||||
|
this.__SignedCountBar ??= document.getElementById("signed-count-bar");
|
||||||
|
return this.__SignedCountBar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static __ShareBackdrop;
|
||||||
|
static get ShareBackdrop() {
|
||||||
|
Comp.__ShareBackdrop ??= new bootstrap.Modal(document.getElementById('shareBackdrop'));
|
||||||
|
return this.__ShareBackdrop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1 @@
|
|||||||
$(".btn_reject").click(()=>Swal.fire({title:localized.rejection,html:`<div class="text-start fs-6 p-0 m-0">${localized.rejectionReasonQ}</div>`,icon:"question",input:"text",inputAttributes:{autocapitalize:"off"},showCancelButton:!0,confirmButtonColor:"#3085d6",cancelButtonColor:"#d33",confirmButtonText:localized.complete,cancelButtonText:localized.back,showLoaderOnConfirm:!0,preConfirm:async n=>{try{return await rejectEnvelope(n)}catch(t){Swal.showValidationMessage(`
|
document.querySelectorAll(".email-input").forEach(n=>{n.addEventListener("input",function(){/^\S+@\S+\.\S+$/.test(this.value)?this.classList.remove("is-invalid"):this.classList.add("is-invalid")})});const bsNotify=(n,t)=>alertify.notify(`<div class="alert ${t.alert_type?"alert-"+t.alert_type:""}" role="alert"><span class="material-symbols-outlined">${t?.icon_name??""}</span><p>${n}</p></div>`,"custom",t?.delay??5);class Comp{static ActPanel=class{static __Root;static get Root(){Comp.ActPanel.__Root??=document.getElementById("flex-action-panel");return Comp.ActPanel.__Root}static get Elements(){return[...Comp.ActPanel.Root.children]}static get IsHided(){return Comp.ActPanel.Root.style.display=="none"}static set Display(n){Comp.ActPanel.Root.style.display=n;Comp.ActPanel.Elements.forEach(t=>t.style.display=n)}static Toggle(){Comp.ActPanel.Display=Comp.ActPanel.IsHided?"":"none"}};static SignatureProgress=class{static __SignatureCount;static get SignatureCount(){this.__SignatureCount=parseInt(document.getElementById("signature-count").innerText);return this.__SignatureCount}static __SignedCountSpan;static get SignedCountSpan(){this.__SignedCountSpan??=document.getElementById("signed-count");return Comp.SignatureProgress.__SignedCountSpan}static __signedCount=0;static get SignedCount(){return this.__signedCount}static set SignedCount(n){this.__signedCount=n;const t=(n/this.SignatureCount)*100;this.SignedCountBar.style.setProperty("--progress-width",t+"%");this.SignedCountSpan.innerText=n.toString()}static __SignedCountBar;static get SignedCountBar(){this.__SignedCountBar??=document.getElementById("signed-count-bar");return this.__SignedCountBar}};static __ShareBackdrop;static get ShareBackdrop(){return Comp.__ShareBackdrop??=new bootstrap.Modal(document.getElementById("shareBackdrop")),this.__ShareBackdrop}}
|
||||||
Request failed: ${t}
|
|
||||||
`)}},allowOutsideClick:()=>!Swal.isLoading()}).then(n=>{if(n.isConfirmed){const t=n.value;t.ok?redirRejected():Swal.showValidationMessage(`Request failed: ${t.message}`)}}));class Comp{static ActPanel=class{static __Root;static get Root(){Comp.ActPanel.__Root??=document.getElementById("flex-action-panel");return Comp.ActPanel.__Root}static get Elements(){return[...Comp.ActPanel.Root.children]}static get IsHided(){return Comp.ActPanel.Root.style.display=="none"}static set Display(n){Comp.ActPanel.Root.style.display=n;Comp.ActPanel.Elements.forEach(t=>t.style.display=n)}static Toggle(){Comp.ActPanel.Display=Comp.ActPanel.IsHided?"":"none"}};}
|
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
'zoom-mode',
|
'zoom-mode',
|
||||||
'spacer',
|
'spacer',
|
||||||
'search',
|
'search',
|
||||||
|
'export-pdf'
|
||||||
]
|
]
|
||||||
|
|
||||||
// Load the PSPDFKit UI by setting a target element as the container to render in
|
// Load the PSPDFKit UI by setting a target element as the container to render in
|
||||||
@@ -49,8 +50,17 @@
|
|||||||
return UI.Instance;
|
return UI.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
static configurePSPDFKit(instance, handler) {
|
static addToolbarItems(instance, handler) {
|
||||||
const toolbarItems = UI.getToolbarItems(instance, handler)
|
var toolbarItems = instance.toolbarItems.filter((item) => UI.allowedToolbarItems.includes(item.type));
|
||||||
|
|
||||||
|
if (IS_READONLY)
|
||||||
|
toolbarItems = toolbarItems.concat(UI.getReadOnlyItems(handler));
|
||||||
|
else
|
||||||
|
toolbarItems = toolbarItems.concat(UI.getWritableItems(handler));
|
||||||
|
|
||||||
|
if (!IS_DESKTOP && !IS_READONLY)
|
||||||
|
toolbarItems = toolbarItems.concat(UI.getMobileWritableItems(handler));
|
||||||
|
|
||||||
instance.setToolbarItems(toolbarItems)
|
instance.setToolbarItems(toolbarItems)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,12 +69,6 @@
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
static getToolbarItems(instance, handler) {
|
|
||||||
const customItems = UI.getCustomItems(handler)
|
|
||||||
const defaultItems = UI.getDefaultItems(instance.toolbarItems)
|
|
||||||
return defaultItems.concat(customItems)
|
|
||||||
}
|
|
||||||
|
|
||||||
static createElementFromHTML(html) {
|
static createElementFromHTML(html) {
|
||||||
const el = document.createElement('div')
|
const el = document.createElement('div')
|
||||||
el.innerHTML = html.trim()
|
el.innerHTML = html.trim()
|
||||||
@@ -72,21 +76,54 @@
|
|||||||
return el.firstChild
|
return el.firstChild
|
||||||
}
|
}
|
||||||
|
|
||||||
static getCustomItems = function (callback) {
|
static getWritableItems = function (callback) {
|
||||||
return []
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
id: 'button-reset',
|
id: 'button-share',
|
||||||
className: 'button-reset',
|
className: 'button-share',
|
||||||
title: 'Zurücksetzen',
|
title: 'Teilen',
|
||||||
onPress() {
|
onPress() {
|
||||||
callback('RESET')
|
callback('SHARE')
|
||||||
},
|
},
|
||||||
icon: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
|
icon: `<svg width="30" height="30" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z"/>
|
<path d="M20 13V17.5C20 20.5577 16 20.5 12 20.5C8 20.5 4 20.5577 4 17.5V13M12 3L12 15M12 3L16 7M12 3L8 7" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z"/>
|
</svg>`,
|
||||||
</svg>`,
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static getReadOnlyItems = function (callback) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'custom',
|
||||||
|
id: 'button-copy-url',
|
||||||
|
className: 'button-copy-url',
|
||||||
|
title: 'Teilen',
|
||||||
|
onPress() {
|
||||||
|
callback('COPY_URL')
|
||||||
|
},
|
||||||
|
icon: `<svg viewBox="4 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M15 3H9C6.79086 3 5 4.79086 5 7V15" stroke="#222222"/>
|
||||||
|
<path d="M8.5 11.5C8.5 10.3156 8.50074 9.46912 8.57435 8.81625C8.64681 8.17346 8.78457 7.78051 9.01662 7.4781C9.14962 7.30477 9.30477 7.14962 9.4781 7.01662C9.78051 6.78457 10.1735 6.64681 10.8163 6.57435C11.4691 6.50074 12.3156 6.5 13.5 6.5C14.6844 6.5 15.5309 6.50074 16.1837 6.57435C16.8265 6.64681 17.2195 6.78457 17.5219 7.01662C17.6952 7.14962 17.8504 7.30477 17.9834 7.4781C18.2154 7.78051 18.3532 8.17346 18.4257 8.81625C18.4993 9.46912 18.5 10.3156 18.5 11.5V15.5C18.5 16.6844 18.4993 17.5309 18.4257 18.1837C18.3532 18.8265 18.2154 19.2195 17.9834 19.5219C17.8504 19.6952 17.6952 19.8504 17.5219 19.9834C17.2195 20.2154 16.8265 20.3532 16.1837 20.4257C15.5309 20.4993 14.6844 20.5 13.5 20.5C12.3156 20.5 11.4691 20.4993 10.8163 20.4257C10.1735 20.3532 9.78051 20.2154 9.4781 19.9834C9.30477 19.8504 9.14962 19.6952 9.01662 19.5219C8.78457 19.2195 8.64681 18.8265 8.57435 18.1837C8.50074 17.5309 8.5 16.6844 8.5 15.5V11.5Z" stroke="#222222"/>
|
||||||
|
</svg>`,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static getMobileWritableItems = function (callback) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'custom',
|
||||||
|
id: 'button-finish',
|
||||||
|
className: 'button-finish',
|
||||||
|
onPress() {
|
||||||
|
callback('FINISH')
|
||||||
|
},
|
||||||
|
icon: `<svg class="icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="-4 -4 26 26">
|
||||||
|
<path d="m10.036 8.278 9.258-7.79A1.979 1.979 0 0 0 18 0H2A1.987 1.987 0 0 0 .641.541l9.395 7.737Z" />
|
||||||
|
<path d="M11.241 9.817c-.36.275-.801.425-1.255.427-.428 0-.845-.138-1.187-.395L0 2.6V14a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V2.5l-8.759 7.317Z" />
|
||||||
|
</svg>`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
@@ -96,24 +133,24 @@
|
|||||||
onPress() {
|
onPress() {
|
||||||
callback('REJECT')
|
callback('REJECT')
|
||||||
},
|
},
|
||||||
icon: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-hand-thumbs-down" viewBox="0 0 16 16">
|
icon: `<svg width="25px" height="25px" viewBox="43.5 43.5 512 512" version="1.1" fill="currentColor" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<path d="M8.864 15.674c-.956.24-1.843-.484-1.908-1.42-.072-1.05-.23-2.015-.428-2.59-.125-.36-.479-1.012-1.04-1.638-.557-.624-1.282-1.179-2.131-1.41C2.685 8.432 2 7.85 2 7V3c0-.845.682-1.464 1.448-1.546 1.07-.113 1.564-.415 2.068-.723l.048-.029c.272-.166.578-.349.97-.484C6.931.08 7.395 0 8 0h3.5c.937 0 1.599.478 1.934 1.064.164.287.254.607.254.913 0 .152-.023.312-.077.464.201.262.38.577.488.9.11.33.172.762.004 1.15.069.13.12.268.159.403.077.27.113.567.113.856 0 .289-.036.586-.113.856-.035.12-.08.244-.138.363.394.571.418 1.2.234 1.733-.206.592-.682 1.1-1.2 1.272-.847.283-1.803.276-2.516.211a9.877 9.877 0 0 1-.443-.05 9.364 9.364 0 0 1-.062 4.51c-.138.508-.55.848-1.012.964zM11.5 1H8c-.51 0-.863.068-1.14.163-.281.097-.506.229-.776.393l-.04.025c-.555.338-1.198.73-2.49.868-.333.035-.554.29-.554.55V7c0 .255.226.543.62.65 1.095.3 1.977.997 2.614 1.709.635.71 1.064 1.475 1.238 1.977.243.7.407 1.768.482 2.85.025.362.36.595.667.518l.262-.065c.16-.04.258-.144.288-.255a8.34 8.34 0 0 0-.145-4.726.5.5 0 0 1 .595-.643h.003l.014.004.058.013a8.912 8.912 0 0 0 1.036.157c.663.06 1.457.054 2.11-.163.175-.059.45-.301.57-.651.107-.308.087-.67-.266-1.021L12.793 7l.353-.354c.043-.042.105-.14.154-.315.048-.167.075-.37.075-.581 0-.211-.027-.414-.075-.581-.05-.174-.111-.273-.154-.315l-.353-.354.353-.354c.047-.047.109-.176.005-.488a2.224 2.224 0 0 0-.505-.804l-.353-.354.353-.354c.006-.005.041-.05.041-.17a.866.866 0 0 0-.121-.415C12.4 1.272 12.063 1 11.5 1"/>
|
<path class="st0" d="M263.24,43.5c-117.36,0-212.5,95.14-212.5,212.5s95.14,212.5,212.5,212.5s212.5-95.14,212.5-212.5 S380.6,43.5,263.24,43.5z M367.83,298.36c17.18,17.18,17.18,45.04,0,62.23v0c-17.18,17.18-45.04,17.18-62.23,0l-42.36-42.36 l-42.36,42.36c-17.18,17.18-45.04,17.18-62.23,0v0c-17.18-17.18-17.18-45.04,0-62.23L201.01,256l-42.36-42.36 c-17.18-17.18-17.18-45.04,0-62.23v0c17.18-17.18,45.04-17.18,62.23,0l42.36,42.36l42.36-42.36c17.18-17.18,45.04-17.18,62.23,0v0 c17.18,17.18,17.18,45.04,0,62.23L325.46,256L367.83,298.36z" />
|
||||||
</svg>`,
|
</svg>`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
id: 'button-finish',
|
id: 'button-reset',
|
||||||
className: 'button-finish',
|
className: 'button-reset',
|
||||||
title: 'Abschließen',
|
title: 'Zurücksetzen',
|
||||||
onPress() {
|
onPress() {
|
||||||
callback('FINISH')
|
callback('RESET')
|
||||||
},
|
},
|
||||||
},
|
icon: `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="-1 -1 16 16">
|
||||||
]
|
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z"/>
|
||||||
}
|
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z"/>
|
||||||
|
</svg>`,
|
||||||
static getDefaultItems(items) {
|
}
|
||||||
return items.filter((item) => UI.allowedToolbarItems.includes(item.type))
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
static getPresets() {
|
static getPresets() {
|
||||||
|
|||||||
22
EnvelopeGenerator.Web/wwwroot/js/ui.min.js
vendored
22
EnvelopeGenerator.Web/wwwroot/js/ui.min.js
vendored
@@ -1,7 +1,15 @@
|
|||||||
class UI{static allowedToolbarItems=["sidebar-thumbnails","sidebar-document-ouline","sidebar-bookmarks","pager","pan","zoom-out","zoom-in","zoom-mode","spacer","search",];static Instance
|
class UI{static allowedToolbarItems=["sidebar-thumbnails","sidebar-document-ouline","sidebar-bookmarks","pager","pan","zoom-out","zoom-in","zoom-mode","spacer","search","export-pdf"];static Instance
|
||||||
static loadPSPDFKit(n,t,i,r){return UI.Instance=PSPDFKit.load({inlineWorkers:!1,locale:r,licenseKey:i,styleSheets:["/css/site.css"],container:t,document:n,annotationPresets:UI.getPresets(),electronicSignatures:{creationModes:["DRAW","TYPE","IMAGE"]},initialViewState:new PSPDFKit.ViewState({sidebarMode:PSPDFKit.SidebarMode.THUMBNAILS}),isEditableAnnotation:function(n){return n.isSignature||n.description=="FRAME"?!1:!0},customRenderers:{Annotation:UI.annotationRenderer}}),UI.Instance}static configurePSPDFKit(n,t){const i=UI.getToolbarItems(n,t);n.setToolbarItems(i)}static annotationRenderer(){return null}static getToolbarItems(n,t){const i=UI.getCustomItems(t),r=UI.getDefaultItems(n.toolbarItems);return r.concat(i)}static createElementFromHTML(n){const t=document.createElement("div");return t.innerHTML=n.trim(),t.firstChild}static getCustomItems=function(n){return[];return[{type:"custom",id:"button-reset",className:"button-reset",title:"Zurücksetzen",onPress(){n("RESET")},icon:`<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
|
static loadPSPDFKit(n,t,i,r){return UI.Instance=PSPDFKit.load({inlineWorkers:!1,locale:r,licenseKey:i,styleSheets:["/css/site.css"],container:t,document:n,annotationPresets:UI.getPresets(),electronicSignatures:{creationModes:["DRAW","TYPE","IMAGE"]},initialViewState:new PSPDFKit.ViewState({sidebarMode:PSPDFKit.SidebarMode.THUMBNAILS}),isEditableAnnotation:function(n){return n.isSignature||n.description=="FRAME"?!1:!0},customRenderers:{Annotation:UI.annotationRenderer}}),UI.Instance}static addToolbarItems(n,t){var i=n.toolbarItems.filter(n=>UI.allowedToolbarItems.includes(n.type));i=IS_READONLY?i.concat(UI.getReadOnlyItems(t)):i.concat(UI.getWritableItems(t));IS_DESKTOP||IS_READONLY||(i=i.concat(UI.getMobileWritableItems(t)));n.setToolbarItems(i)}static annotationRenderer(){return null}static createElementFromHTML(n){const t=document.createElement("div");return t.innerHTML=n.trim(),t.firstChild}static getWritableItems=function(n){return[{type:"custom",id:"button-share",className:"button-share",title:"Teilen",onPress(){n("SHARE")},icon:`<svg width="30" height="30" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z"/>
|
<path d="M20 13V17.5C20 20.5577 16 20.5 12 20.5C8 20.5 4 20.5577 4 17.5V13M12 3L12 15M12 3L16 7M12 3L8 7" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z"/>
|
</svg>`}]};static getReadOnlyItems=function(n){return[{type:"custom",id:"button-copy-url",className:"button-copy-url",title:"Teilen",onPress(){n("COPY_URL")},icon:`<svg viewBox="4 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
</svg>`},{type:"custom",id:"button-reject",className:"button-reject",title:"Ablehnen",onPress(){n("REJECT")},icon:`<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-hand-thumbs-down" viewBox="0 0 16 16">
|
<path d="M15 3H9C6.79086 3 5 4.79086 5 7V15" stroke="#222222"/>
|
||||||
<path d="M8.864 15.674c-.956.24-1.843-.484-1.908-1.42-.072-1.05-.23-2.015-.428-2.59-.125-.36-.479-1.012-1.04-1.638-.557-.624-1.282-1.179-2.131-1.41C2.685 8.432 2 7.85 2 7V3c0-.845.682-1.464 1.448-1.546 1.07-.113 1.564-.415 2.068-.723l.048-.029c.272-.166.578-.349.97-.484C6.931.08 7.395 0 8 0h3.5c.937 0 1.599.478 1.934 1.064.164.287.254.607.254.913 0 .152-.023.312-.077.464.201.262.38.577.488.9.11.33.172.762.004 1.15.069.13.12.268.159.403.077.27.113.567.113.856 0 .289-.036.586-.113.856-.035.12-.08.244-.138.363.394.571.418 1.2.234 1.733-.206.592-.682 1.1-1.2 1.272-.847.283-1.803.276-2.516.211a9.877 9.877 0 0 1-.443-.05 9.364 9.364 0 0 1-.062 4.51c-.138.508-.55.848-1.012.964zM11.5 1H8c-.51 0-.863.068-1.14.163-.281.097-.506.229-.776.393l-.04.025c-.555.338-1.198.73-2.49.868-.333.035-.554.29-.554.55V7c0 .255.226.543.62.65 1.095.3 1.977.997 2.614 1.709.635.71 1.064 1.475 1.238 1.977.243.7.407 1.768.482 2.85.025.362.36.595.667.518l.262-.065c.16-.04.258-.144.288-.255a8.34 8.34 0 0 0-.145-4.726.5.5 0 0 1 .595-.643h.003l.014.004.058.013a8.912 8.912 0 0 0 1.036.157c.663.06 1.457.054 2.11-.163.175-.059.45-.301.57-.651.107-.308.087-.67-.266-1.021L12.793 7l.353-.354c.043-.042.105-.14.154-.315.048-.167.075-.37.075-.581 0-.211-.027-.414-.075-.581-.05-.174-.111-.273-.154-.315l-.353-.354.353-.354c.047-.047.109-.176.005-.488a2.224 2.224 0 0 0-.505-.804l-.353-.354.353-.354c.006-.005.041-.05.041-.17a.866.866 0 0 0-.121-.415C12.4 1.272 12.063 1 11.5 1"/>
|
<path d="M8.5 11.5C8.5 10.3156 8.50074 9.46912 8.57435 8.81625C8.64681 8.17346 8.78457 7.78051 9.01662 7.4781C9.14962 7.30477 9.30477 7.14962 9.4781 7.01662C9.78051 6.78457 10.1735 6.64681 10.8163 6.57435C11.4691 6.50074 12.3156 6.5 13.5 6.5C14.6844 6.5 15.5309 6.50074 16.1837 6.57435C16.8265 6.64681 17.2195 6.78457 17.5219 7.01662C17.6952 7.14962 17.8504 7.30477 17.9834 7.4781C18.2154 7.78051 18.3532 8.17346 18.4257 8.81625C18.4993 9.46912 18.5 10.3156 18.5 11.5V15.5C18.5 16.6844 18.4993 17.5309 18.4257 18.1837C18.3532 18.8265 18.2154 19.2195 17.9834 19.5219C17.8504 19.6952 17.6952 19.8504 17.5219 19.9834C17.2195 20.2154 16.8265 20.3532 16.1837 20.4257C15.5309 20.4993 14.6844 20.5 13.5 20.5C12.3156 20.5 11.4691 20.4993 10.8163 20.4257C10.1735 20.3532 9.78051 20.2154 9.4781 19.9834C9.30477 19.8504 9.14962 19.6952 9.01662 19.5219C8.78457 19.2195 8.64681 18.8265 8.57435 18.1837C8.50074 17.5309 8.5 16.6844 8.5 15.5V11.5Z" stroke="#222222"/>
|
||||||
</svg>`},{type:"custom",id:"button-finish",className:"button-finish",title:"Abschließen",onPress(){n("FINISH")}},]};static getDefaultItems(n){return n.filter(n=>UI.allowedToolbarItems.includes(n.type))}static getPresets(){const n=PSPDFKit.defaultAnnotationPresets;return n.ink={lineWidth:10},n.widget={readOnly:!0},n}}
|
</svg>`}]};static getMobileWritableItems=function(n){return[{type:"custom",id:"button-finish",className:"button-finish",onPress(){n("FINISH")},icon:`<svg class="icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="-4 -4 26 26">
|
||||||
|
<path d="m10.036 8.278 9.258-7.79A1.979 1.979 0 0 0 18 0H2A1.987 1.987 0 0 0 .641.541l9.395 7.737Z" />
|
||||||
|
<path d="M11.241 9.817c-.36.275-.801.425-1.255.427-.428 0-.845-.138-1.187-.395L0 2.6V14a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V2.5l-8.759 7.317Z" />
|
||||||
|
</svg>`},{type:"custom",id:"button-reject",className:"button-reject",title:"Ablehnen",onPress(){n("REJECT")},icon:`<svg width="25px" height="25px" viewBox="43.5 43.5 512 512" version="1.1" fill="currentColor" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<path class="st0" d="M263.24,43.5c-117.36,0-212.5,95.14-212.5,212.5s95.14,212.5,212.5,212.5s212.5-95.14,212.5-212.5 S380.6,43.5,263.24,43.5z M367.83,298.36c17.18,17.18,17.18,45.04,0,62.23v0c-17.18,17.18-45.04,17.18-62.23,0l-42.36-42.36 l-42.36,42.36c-17.18,17.18-45.04,17.18-62.23,0v0c-17.18-17.18-17.18-45.04,0-62.23L201.01,256l-42.36-42.36 c-17.18-17.18-17.18-45.04,0-62.23v0c17.18-17.18,45.04-17.18,62.23,0l42.36,42.36l42.36-42.36c17.18-17.18,45.04-17.18,62.23,0v0 c17.18,17.18,17.18,45.04,0,62.23L325.46,256L367.83,298.36z" />
|
||||||
|
</svg>`},{type:"custom",id:"button-reset",className:"button-reset",title:"Zurücksetzen",onPress(){n("RESET")},icon:`<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="-1 -1 16 16">
|
||||||
|
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2v1z"/>
|
||||||
|
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466z"/>
|
||||||
|
</svg>`}]};static getPresets(){const n=PSPDFKit.defaultAnnotationPresets;return n.ink={lineWidth:10},n.widget={readOnly:!0},n}}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
7751
EnvelopeGenerator.Web/wwwroot/lib/MDB/js/mdb.es.min.js
vendored
7751
EnvelopeGenerator.Web/wwwroot/lib/MDB/js/mdb.es.min.js
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,435 +0,0 @@
|
|||||||
import EventHandler from '../../mdb/dom/event-handler';
|
|
||||||
import SelectorEngine from '../../mdb/dom/selector-engine';
|
|
||||||
import Manipulator from '../../mdb/dom/manipulator';
|
|
||||||
import {
|
|
||||||
isDisabled,
|
|
||||||
getElementFromSelector,
|
|
||||||
isVisible,
|
|
||||||
getSelectorFromElement,
|
|
||||||
} from '../../mdb/util';
|
|
||||||
import { enableDismissTrigger } from '../../bootstrap/mdb-prefix/util/component-functions';
|
|
||||||
|
|
||||||
const alertCallback = (component, initSelector) => {
|
|
||||||
const Alert = component;
|
|
||||||
|
|
||||||
enableDismissTrigger(Alert, 'close');
|
|
||||||
|
|
||||||
// MDB init
|
|
||||||
SelectorEngine.find(initSelector).forEach((element) => {
|
|
||||||
return Alert.getOrCreateInstance(element);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const buttonCallback = (component, initSelector) => {
|
|
||||||
const Button = component;
|
|
||||||
const EVENT_CLICK_DATA_API = `click.bs.${component.name}.data-api`;
|
|
||||||
|
|
||||||
// BS init
|
|
||||||
EventHandler.on(document, EVENT_CLICK_DATA_API, initSelector, (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const button = event.target.closest(initSelector);
|
|
||||||
const data = Button.getOrCreateInstance(button);
|
|
||||||
|
|
||||||
data.toggle();
|
|
||||||
});
|
|
||||||
|
|
||||||
// MDB init
|
|
||||||
SelectorEngine.find(initSelector).forEach((element) => {
|
|
||||||
return Button.getOrCreateInstance(element);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const carouselCallback = (component, initSelector) => {
|
|
||||||
const EVENT_CLICK_DATA_API = `click.bs.${component.name}.data-api`;
|
|
||||||
const SELECTOR_DATA_SLIDE = '[data-mdb-slide], [data-mdb-slide-to]';
|
|
||||||
const CLASS_NAME_CAROUSEL = 'carousel';
|
|
||||||
const Carousel = component;
|
|
||||||
const EVENT_LOAD_DATA_API = `load.bs.${component.name}.data-api`;
|
|
||||||
const SELECTOR_DATA_RIDE = initSelector;
|
|
||||||
|
|
||||||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, function (event) {
|
|
||||||
const target = getElementFromSelector(this);
|
|
||||||
|
|
||||||
if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const carousel = Carousel.getOrCreateInstance(target);
|
|
||||||
const slideIndex = this.getAttribute('data-mdb-slide-to');
|
|
||||||
|
|
||||||
if (slideIndex) {
|
|
||||||
carousel.to(slideIndex);
|
|
||||||
carousel._maybeEnableCycle();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Manipulator.getDataAttribute(this, 'slide') === 'next') {
|
|
||||||
carousel.next();
|
|
||||||
carousel._maybeEnableCycle();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
carousel.prev();
|
|
||||||
carousel._maybeEnableCycle();
|
|
||||||
});
|
|
||||||
|
|
||||||
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
|
||||||
const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);
|
|
||||||
|
|
||||||
carousels.forEach((carousel) => {
|
|
||||||
Carousel.getOrCreateInstance(carousel);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const collapseCallback = (component, initSelector) => {
|
|
||||||
const EVENT_CLICK_DATA_API = `click.bs.${component.name}.data-api`;
|
|
||||||
const SELECTOR_DATA_TOGGLE = initSelector;
|
|
||||||
const Collapse = component;
|
|
||||||
|
|
||||||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
|
||||||
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
|
|
||||||
if (
|
|
||||||
event.target.tagName === 'A' ||
|
|
||||||
(event.delegateTarget && event.delegateTarget.tagName === 'A')
|
|
||||||
) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
const selector = getSelectorFromElement(this);
|
|
||||||
const selectorElements = SelectorEngine.find(selector);
|
|
||||||
|
|
||||||
selectorElements.forEach((element) => {
|
|
||||||
Collapse.getOrCreateInstance(element, { toggle: false }).toggle();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
SelectorEngine.find(SELECTOR_DATA_TOGGLE).forEach((el) => {
|
|
||||||
const selector = getSelectorFromElement(el);
|
|
||||||
const selectorElements = SelectorEngine.find(selector);
|
|
||||||
|
|
||||||
selectorElements.forEach((element) => {
|
|
||||||
Collapse.getOrCreateInstance(element, { toggle: false });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const dropdownCallback = (component, initSelector) => {
|
|
||||||
const EVENT_CLICK_DATA_API = `click.bs.${component.name}.data-api`;
|
|
||||||
const EVENT_KEYDOWN_DATA_API = `keydown.bs.${component.name}.data-api`;
|
|
||||||
const EVENT_KEYUP_DATA_API = `keyup.bs.${component.name}.data-api`;
|
|
||||||
const SELECTOR_MENU = '.dropdown-menu';
|
|
||||||
const SELECTOR_DATA_TOGGLE = `[data-mdb-${component.NAME}-initialized]`;
|
|
||||||
const Dropdown = component;
|
|
||||||
|
|
||||||
EventHandler.on(
|
|
||||||
document,
|
|
||||||
EVENT_KEYDOWN_DATA_API,
|
|
||||||
SELECTOR_DATA_TOGGLE,
|
|
||||||
Dropdown.dataApiKeydownHandler
|
|
||||||
);
|
|
||||||
EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);
|
|
||||||
EventHandler.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus);
|
|
||||||
EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
|
|
||||||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
Dropdown.getOrCreateInstance(this).toggle();
|
|
||||||
});
|
|
||||||
|
|
||||||
SelectorEngine.find(initSelector).forEach((el) => {
|
|
||||||
Dropdown.getOrCreateInstance(el);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const inputCallback = (component, initSelector) => {
|
|
||||||
const SELECTOR_DATA_INIT = initSelector;
|
|
||||||
const SELECTOR_OUTLINE_INPUT = `${SELECTOR_DATA_INIT} input`;
|
|
||||||
const SELECTOR_OUTLINE_TEXTAREA = `${SELECTOR_DATA_INIT} textarea`;
|
|
||||||
const Input = component;
|
|
||||||
|
|
||||||
EventHandler.on(document, 'focus', SELECTOR_OUTLINE_INPUT, Input.activate(new Input()));
|
|
||||||
EventHandler.on(document, 'input', SELECTOR_OUTLINE_INPUT, Input.activate(new Input()));
|
|
||||||
EventHandler.on(document, 'blur', SELECTOR_OUTLINE_INPUT, Input.deactivate(new Input()));
|
|
||||||
|
|
||||||
EventHandler.on(document, 'focus', SELECTOR_OUTLINE_TEXTAREA, Input.activate(new Input()));
|
|
||||||
EventHandler.on(document, 'input', SELECTOR_OUTLINE_TEXTAREA, Input.activate(new Input()));
|
|
||||||
EventHandler.on(document, 'blur', SELECTOR_OUTLINE_TEXTAREA, Input.deactivate(new Input()));
|
|
||||||
|
|
||||||
EventHandler.on(window, 'shown.bs.modal', (e) => {
|
|
||||||
SelectorEngine.find(SELECTOR_OUTLINE_INPUT, e.target).forEach((element) => {
|
|
||||||
const instance = Input.getInstance(element.parentNode);
|
|
||||||
if (!instance) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
instance.update();
|
|
||||||
});
|
|
||||||
SelectorEngine.find(SELECTOR_OUTLINE_TEXTAREA, e.target).forEach((element) => {
|
|
||||||
const instance = Input.getInstance(element.parentNode);
|
|
||||||
if (!instance) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
instance.update();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
EventHandler.on(window, 'shown.bs.dropdown', (e) => {
|
|
||||||
const target = e.target.parentNode.querySelector('.dropdown-menu');
|
|
||||||
if (target) {
|
|
||||||
SelectorEngine.find(SELECTOR_OUTLINE_INPUT, target).forEach((element) => {
|
|
||||||
const instance = Input.getInstance(element.parentNode);
|
|
||||||
if (!instance) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
instance.update();
|
|
||||||
});
|
|
||||||
SelectorEngine.find(SELECTOR_OUTLINE_TEXTAREA, target).forEach((element) => {
|
|
||||||
const instance = Input.getInstance(element.parentNode);
|
|
||||||
if (!instance) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
instance.update();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
EventHandler.on(window, 'shown.bs.tab', (e) => {
|
|
||||||
let targetId;
|
|
||||||
|
|
||||||
if (e.target.href) {
|
|
||||||
targetId = e.target.href.split('#')[1];
|
|
||||||
} else {
|
|
||||||
targetId = Manipulator.getDataAttribute(e.target, 'target').split('#')[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
const target = SelectorEngine.findOne(`#${targetId}`);
|
|
||||||
SelectorEngine.find(SELECTOR_OUTLINE_INPUT, target).forEach((element) => {
|
|
||||||
const instance = Input.getInstance(element.parentNode);
|
|
||||||
if (!instance) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
instance.update();
|
|
||||||
});
|
|
||||||
SelectorEngine.find(SELECTOR_OUTLINE_TEXTAREA, target).forEach((element) => {
|
|
||||||
const instance = Input.getInstance(element.parentNode);
|
|
||||||
if (!instance) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
instance.update();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// auto-init
|
|
||||||
SelectorEngine.find(SELECTOR_DATA_INIT).map((element) => new Input(element));
|
|
||||||
|
|
||||||
// form reset handler
|
|
||||||
EventHandler.on(window, 'reset', (e) => {
|
|
||||||
SelectorEngine.find(SELECTOR_OUTLINE_INPUT, e.target).forEach((element) => {
|
|
||||||
const instance = Input.getInstance(element.parentNode);
|
|
||||||
if (!instance) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
instance.forceInactive();
|
|
||||||
});
|
|
||||||
SelectorEngine.find(SELECTOR_OUTLINE_TEXTAREA, e.target).forEach((element) => {
|
|
||||||
const instance = Input.getInstance(element.parentNode);
|
|
||||||
if (!instance) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
instance.forceInactive();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// auto-fill
|
|
||||||
EventHandler.on(window, 'onautocomplete', (e) => {
|
|
||||||
const instance = Input.getInstance(e.target.parentNode);
|
|
||||||
if (!instance || !e.cancelable) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
instance.forceActive();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const modalCallback = (component, initSelector) => {
|
|
||||||
const EVENT_CLICK_DATA_API = `click.bs.${component.name}.data-api`;
|
|
||||||
const OPEN_SELECTOR = '.modal.show';
|
|
||||||
const Modal = component;
|
|
||||||
const EVENT_SHOW = `show.bs.${component.name}`;
|
|
||||||
const EVENT_HIDDEN = `hidden.bs.${component.name}`;
|
|
||||||
|
|
||||||
EventHandler.on(document, EVENT_CLICK_DATA_API, initSelector, function (event) {
|
|
||||||
const target = getElementFromSelector(this);
|
|
||||||
|
|
||||||
if (['A', 'AREA'].includes(this.tagName)) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
EventHandler.one(target, EVENT_SHOW, (showEvent) => {
|
|
||||||
if (showEvent.defaultPrevented) {
|
|
||||||
// only register focus restorer if modal will actually get shown
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
EventHandler.one(target, EVENT_HIDDEN, () => {
|
|
||||||
if (isVisible(this)) {
|
|
||||||
this.focus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// avoid conflict when clicking modal toggler while another one is open
|
|
||||||
const alreadyOpenedModals = SelectorEngine.find(OPEN_SELECTOR);
|
|
||||||
alreadyOpenedModals.forEach((modal) => {
|
|
||||||
if (!modal.classList.contains('modal-non-invasive-show')) {
|
|
||||||
Modal.getInstance(modal).hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = Modal.getOrCreateInstance(target);
|
|
||||||
|
|
||||||
data.toggle(this);
|
|
||||||
});
|
|
||||||
|
|
||||||
enableDismissTrigger(Modal);
|
|
||||||
|
|
||||||
SelectorEngine.find(initSelector).forEach((el) => {
|
|
||||||
const selector = getSelectorFromElement(el);
|
|
||||||
const selectorElement = SelectorEngine.findOne(selector);
|
|
||||||
|
|
||||||
Modal.getOrCreateInstance(selectorElement);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const popoverCallback = (component, initSelector) => {
|
|
||||||
const Popover = component;
|
|
||||||
const SELECTOR_DATA_TOGGLE = initSelector;
|
|
||||||
|
|
||||||
SelectorEngine.find(SELECTOR_DATA_TOGGLE).forEach((el) => {
|
|
||||||
Popover.getOrCreateInstance(el);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const offcanvasCallback = (component, initSelector) => {
|
|
||||||
const EVENT_CLICK_DATA_API = `click.bs.${component.name}.data-api`;
|
|
||||||
const OPEN_SELECTOR = '.offcanvas.show';
|
|
||||||
const Offcanvas = component;
|
|
||||||
const EVENT_HIDDEN = `hidden.bs.${component.name}`;
|
|
||||||
const EVENT_LOAD_DATA_API = `load.bs.${component.name}.data-api`;
|
|
||||||
const EVENT_RESIZE = `resize.bs.${component.name}`;
|
|
||||||
|
|
||||||
EventHandler.on(document, EVENT_CLICK_DATA_API, initSelector, function (event) {
|
|
||||||
const target = getElementFromSelector(this);
|
|
||||||
|
|
||||||
if (['A', 'AREA'].includes(this.tagName)) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDisabled(this)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
EventHandler.one(target, EVENT_HIDDEN, () => {
|
|
||||||
// focus on trigger when it is closed
|
|
||||||
if (isVisible(this)) {
|
|
||||||
this.focus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// avoid conflict when clicking a toggler of an offcanvas, while another is open
|
|
||||||
const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);
|
|
||||||
if (alreadyOpen && alreadyOpen !== target) {
|
|
||||||
Offcanvas.getInstance(alreadyOpen).hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = Offcanvas.getOrCreateInstance(target);
|
|
||||||
data.toggle(this);
|
|
||||||
});
|
|
||||||
|
|
||||||
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
|
||||||
SelectorEngine.find(OPEN_SELECTOR).forEach((selector) => {
|
|
||||||
Offcanvas.getOrCreateInstance(selector).show();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
EventHandler.on(window, EVENT_RESIZE, () => {
|
|
||||||
SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]').forEach((element) => {
|
|
||||||
if (getComputedStyle(element).position !== 'fixed') {
|
|
||||||
Offcanvas.getOrCreateInstance(element).hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
enableDismissTrigger(Offcanvas);
|
|
||||||
};
|
|
||||||
|
|
||||||
const scrollspyCallback = (component, initSelector) => {
|
|
||||||
const EVENT_LOAD_DATA_API = `load.bs.${component.name}.data-api`;
|
|
||||||
const ScrollSpy = component;
|
|
||||||
|
|
||||||
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
|
||||||
SelectorEngine.find(initSelector).forEach((el) => {
|
|
||||||
ScrollSpy.getOrCreateInstance(el);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const tabCallback = (component, initSelector) => {
|
|
||||||
const EVENT_LOAD_DATA_API = `load.bs.${component.name}.data-api`;
|
|
||||||
const EVENT_CLICK_DATA_API = `click.bs.${component.name}.data-api`;
|
|
||||||
const CLASS_NAME_ACTIVE = 'active';
|
|
||||||
const SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-mdb-tab-init], .${CLASS_NAME_ACTIVE}[data-mdb-pill-init], .${CLASS_NAME_ACTIVE}[data-mdb-toggle="list"]`;
|
|
||||||
const Tab = component;
|
|
||||||
|
|
||||||
EventHandler.on(document, EVENT_CLICK_DATA_API, initSelector, function (event) {
|
|
||||||
if (['A', 'AREA'].includes(this.tagName)) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDisabled(this)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tab.getOrCreateInstance(this).show();
|
|
||||||
});
|
|
||||||
|
|
||||||
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
|
||||||
SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE).forEach((element) => {
|
|
||||||
Tab.getOrCreateInstance(element);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const toastCallback = (component, initSelector) => {
|
|
||||||
const Toast = component;
|
|
||||||
|
|
||||||
enableDismissTrigger(Toast);
|
|
||||||
|
|
||||||
// MDB init
|
|
||||||
SelectorEngine.find(initSelector).forEach((element) => {
|
|
||||||
return Toast.getOrCreateInstance(element);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const rippleCallback = (component, initSelector) => {
|
|
||||||
const Ripple = component;
|
|
||||||
|
|
||||||
EventHandler.one(document, 'mousedown', initSelector, Ripple.autoInitial(new Ripple()));
|
|
||||||
};
|
|
||||||
|
|
||||||
export {
|
|
||||||
alertCallback,
|
|
||||||
buttonCallback,
|
|
||||||
carouselCallback,
|
|
||||||
collapseCallback,
|
|
||||||
dropdownCallback,
|
|
||||||
inputCallback,
|
|
||||||
modalCallback,
|
|
||||||
offcanvasCallback,
|
|
||||||
tabCallback,
|
|
||||||
toastCallback,
|
|
||||||
popoverCallback,
|
|
||||||
rippleCallback,
|
|
||||||
scrollspyCallback,
|
|
||||||
};
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import defaultInitSelectors from './initSelectors/free';
|
|
||||||
import { InitMDB } from './init';
|
|
||||||
|
|
||||||
const initMDBInstance = new InitMDB(defaultInitSelectors);
|
|
||||||
const initMDB = initMDBInstance.initMDB;
|
|
||||||
|
|
||||||
export default initMDB;
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
import SelectorEngine from '../mdb/dom/selector-engine';
|
|
||||||
import { defineJQueryPlugin } from '../mdb/util/index';
|
|
||||||
|
|
||||||
const mapComponentsData = (() => {
|
|
||||||
const componentsData = [];
|
|
||||||
return {
|
|
||||||
set(componentName) {
|
|
||||||
componentsData.push(componentName);
|
|
||||||
},
|
|
||||||
get(componentName) {
|
|
||||||
return componentsData.includes(componentName);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
export const InitializedComponents = {
|
|
||||||
set(componentName) {
|
|
||||||
mapComponentsData.set(componentName);
|
|
||||||
},
|
|
||||||
get(componentName) {
|
|
||||||
return mapComponentsData.get(componentName);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const isInitialized = (componentName) => {
|
|
||||||
return InitializedComponents.get(componentName);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const bindCallbackEventsIfNeeded = (component) => {
|
|
||||||
if (!isInitialized(component.NAME)) {
|
|
||||||
const manualInit = true;
|
|
||||||
initComponent(component, manualInit);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const initComponent = (component, manualInit = false) => {
|
|
||||||
if (!component || InitializedComponents.get(component.NAME)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializedComponents.set(component.NAME);
|
|
||||||
|
|
||||||
const thisComponent = _defaultInitSelectors[component.NAME] || null;
|
|
||||||
const isToggler = thisComponent?.isToggler || false;
|
|
||||||
|
|
||||||
defineJQueryPlugin(component);
|
|
||||||
if (thisComponent?.advanced) {
|
|
||||||
thisComponent.advanced(component, thisComponent?.selector);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isToggler) {
|
|
||||||
thisComponent.callback(component, thisComponent?.selector);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (manualInit) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SelectorEngine.find(thisComponent?.selector).forEach((element) => {
|
|
||||||
let instance = component.getInstance(element);
|
|
||||||
if (!instance) {
|
|
||||||
instance = new component(element); // eslint-disable-line
|
|
||||||
if (thisComponent?.onInit) {
|
|
||||||
instance[thisComponent.onInit]();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
let _defaultInitSelectors;
|
|
||||||
export class InitMDB {
|
|
||||||
constructor(defaultInitSelectors) {
|
|
||||||
_defaultInitSelectors = defaultInitSelectors;
|
|
||||||
}
|
|
||||||
|
|
||||||
init = (components) => {
|
|
||||||
components.forEach((component) => initComponent(component));
|
|
||||||
};
|
|
||||||
|
|
||||||
initMDB = (components, checkOtherImports = false) => {
|
|
||||||
const componentList = Object.keys(_defaultInitSelectors).map((element) => {
|
|
||||||
const requireAutoInit = Boolean(
|
|
||||||
document.querySelector(_defaultInitSelectors[element].selector)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (requireAutoInit) {
|
|
||||||
const component = components[_defaultInitSelectors[element].name];
|
|
||||||
if (!component && !InitializedComponents.get(element) && checkOtherImports) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.warn(
|
|
||||||
`Please import ${_defaultInitSelectors[element].name} from "MDB" package and add it to a object parameter inside "initMDB" function`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return component;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.init(componentList);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
import {
|
|
||||||
alertCallback,
|
|
||||||
dropdownCallback,
|
|
||||||
offcanvasCallback,
|
|
||||||
tabCallback,
|
|
||||||
buttonCallback,
|
|
||||||
modalCallback,
|
|
||||||
rippleCallback,
|
|
||||||
collapseCallback,
|
|
||||||
carouselCallback,
|
|
||||||
scrollspyCallback,
|
|
||||||
toastCallback,
|
|
||||||
inputCallback,
|
|
||||||
} from '../callbacks/free';
|
|
||||||
|
|
||||||
const defaultInitSelectors = {
|
|
||||||
// Bootstrap Components
|
|
||||||
alert: {
|
|
||||||
name: 'Alert',
|
|
||||||
selector: '[data-mdb-alert-init]',
|
|
||||||
isToggler: true,
|
|
||||||
callback: alertCallback,
|
|
||||||
},
|
|
||||||
button: {
|
|
||||||
name: 'Button',
|
|
||||||
selector: '[data-mdb-button-init]',
|
|
||||||
isToggler: true,
|
|
||||||
callback: buttonCallback,
|
|
||||||
},
|
|
||||||
carousel: {
|
|
||||||
name: 'Carousel',
|
|
||||||
selector: '[data-mdb-carousel-init]',
|
|
||||||
isToggler: true,
|
|
||||||
callback: carouselCallback,
|
|
||||||
},
|
|
||||||
collapse: {
|
|
||||||
name: 'Collapse',
|
|
||||||
selector: '[data-mdb-collapse-init]',
|
|
||||||
isToggler: true,
|
|
||||||
callback: collapseCallback,
|
|
||||||
},
|
|
||||||
dropdown: {
|
|
||||||
name: 'Dropdown',
|
|
||||||
selector: '[data-mdb-dropdown-init]',
|
|
||||||
isToggler: true,
|
|
||||||
callback: dropdownCallback,
|
|
||||||
},
|
|
||||||
modal: {
|
|
||||||
name: 'Modal',
|
|
||||||
selector: '[data-mdb-modal-init]',
|
|
||||||
isToggler: true,
|
|
||||||
callback: modalCallback,
|
|
||||||
},
|
|
||||||
offcanvas: {
|
|
||||||
name: 'Offcanvas',
|
|
||||||
selector: '[data-mdb-offcanvas-init]',
|
|
||||||
isToggler: true,
|
|
||||||
callback: offcanvasCallback,
|
|
||||||
},
|
|
||||||
scrollspy: {
|
|
||||||
name: 'ScrollSpy',
|
|
||||||
selector: '[data-mdb-scrollspy-init]',
|
|
||||||
isToggler: true,
|
|
||||||
callback: scrollspyCallback,
|
|
||||||
},
|
|
||||||
tab: {
|
|
||||||
name: 'Tab',
|
|
||||||
selector: '[data-mdb-tab-init], [data-mdb-pill-init], [data-mdb-list-init]',
|
|
||||||
isToggler: true,
|
|
||||||
callback: tabCallback,
|
|
||||||
},
|
|
||||||
toast: {
|
|
||||||
name: 'Toast',
|
|
||||||
selector: '[data-mdb-toast-init]',
|
|
||||||
isToggler: true,
|
|
||||||
callback: toastCallback,
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
name: 'Tooltip',
|
|
||||||
selector: '[data-mdb-tooltip-init]',
|
|
||||||
isToggler: false,
|
|
||||||
},
|
|
||||||
input: {
|
|
||||||
name: 'Input',
|
|
||||||
selector: '[data-mdb-input-init]',
|
|
||||||
isToggler: true,
|
|
||||||
callback: inputCallback,
|
|
||||||
},
|
|
||||||
range: {
|
|
||||||
name: 'Range',
|
|
||||||
selector: '[data-mdb-range-init]',
|
|
||||||
isToggler: false,
|
|
||||||
},
|
|
||||||
ripple: {
|
|
||||||
name: 'Ripple',
|
|
||||||
selector: '[data-mdb-ripple-init]',
|
|
||||||
isToggler: true,
|
|
||||||
callback: rippleCallback,
|
|
||||||
},
|
|
||||||
popover: {
|
|
||||||
name: 'Popover',
|
|
||||||
selector: '[data-mdb-popover-init]',
|
|
||||||
isToggler: false,
|
|
||||||
callback: rippleCallback,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default defaultInitSelectors;
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap alert.js v5.3.2 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
*/
|
|
||||||
(function (global, factory) {
|
|
||||||
typeof exports === 'object' && typeof module !== 'undefined'
|
|
||||||
? (module.exports = factory(
|
|
||||||
require('./base-component.js'),
|
|
||||||
require('./dom/event-handler.js'),
|
|
||||||
require('./util/component-functions.js'),
|
|
||||||
require('./util/index.js')
|
|
||||||
))
|
|
||||||
: typeof define === 'function' && define.amd
|
|
||||||
? define(
|
|
||||||
['./base-component', './dom/event-handler', './util/component-functions', './util/index'],
|
|
||||||
factory
|
|
||||||
)
|
|
||||||
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
|
|
||||||
(global.Alert = factory(
|
|
||||||
global.BaseComponent,
|
|
||||||
global.EventHandler,
|
|
||||||
global.ComponentFunctions,
|
|
||||||
global.Index
|
|
||||||
)));
|
|
||||||
})(this, function (BaseComponent, EventHandler, componentFunctions_js, index_js) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap alert.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'alert';
|
|
||||||
const DATA_KEY = 'bs.alert';
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`;
|
|
||||||
const EVENT_CLOSE = `close${EVENT_KEY}`;
|
|
||||||
const EVENT_CLOSED = `closed${EVENT_KEY}`;
|
|
||||||
const CLASS_NAME_FADE = 'fade';
|
|
||||||
const CLASS_NAME_SHOW = 'show';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class definition
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Alert extends BaseComponent {
|
|
||||||
// Getters
|
|
||||||
static get NAME() {
|
|
||||||
return NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
close() {
|
|
||||||
const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);
|
|
||||||
if (closeEvent.defaultPrevented) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._element.classList.remove(CLASS_NAME_SHOW);
|
|
||||||
const isAnimated = this._element.classList.contains(CLASS_NAME_FADE);
|
|
||||||
this._queueCallback(() => this._destroyElement(), this._element, isAnimated);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private
|
|
||||||
_destroyElement() {
|
|
||||||
this._element.remove();
|
|
||||||
EventHandler.trigger(this._element, EVENT_CLOSED);
|
|
||||||
this.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
static jQueryInterface(config) {
|
|
||||||
return this.each(function () {
|
|
||||||
const data = Alert.getOrCreateInstance(this);
|
|
||||||
if (typeof config !== 'string') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
|
||||||
throw new TypeError(`No method named "${config}"`);
|
|
||||||
}
|
|
||||||
data[config](this);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data API implementation
|
|
||||||
*/
|
|
||||||
|
|
||||||
componentFunctions_js.enableDismissTrigger(Alert, 'close');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* jQuery
|
|
||||||
*/
|
|
||||||
|
|
||||||
index_js.defineJQueryPlugin(Alert);
|
|
||||||
|
|
||||||
return Alert;
|
|
||||||
});
|
|
||||||
//# sourceMappingURL=alert.js.map
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"alert.js","sources":["../src/alert.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\nimport { defineJQueryPlugin } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'alert'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n close() {\n const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE)\n\n if (closeEvent.defaultPrevented) {\n return\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n\n const isAnimated = this._element.classList.contains(CLASS_NAME_FADE)\n this._queueCallback(() => this._destroyElement(), this._element, isAnimated)\n }\n\n // Private\n _destroyElement() {\n this._element.remove()\n EventHandler.trigger(this._element, EVENT_CLOSED)\n this.dispose()\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Alert.getOrCreateInstance(this)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Alert, 'close')\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Alert)\n\nexport default Alert\n"],"names":["NAME","DATA_KEY","EVENT_KEY","EVENT_CLOSE","EVENT_CLOSED","CLASS_NAME_FADE","CLASS_NAME_SHOW","Alert","BaseComponent","close","closeEvent","EventHandler","trigger","_element","defaultPrevented","classList","remove","isAnimated","contains","_queueCallback","_destroyElement","dispose","jQueryInterface","config","each","data","getOrCreateInstance","undefined","startsWith","TypeError","enableDismissTrigger","defineJQueryPlugin"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAOA;EACA;EACA;;EAEA,MAAMA,IAAI,GAAG,OAAO,CAAA;EACpB,MAAMC,QAAQ,GAAG,UAAU,CAAA;EAC3B,MAAMC,SAAS,GAAI,CAAGD,CAAAA,EAAAA,QAAS,CAAC,CAAA,CAAA;EAEhC,MAAME,WAAW,GAAI,CAAOD,KAAAA,EAAAA,SAAU,CAAC,CAAA,CAAA;EACvC,MAAME,YAAY,GAAI,CAAQF,MAAAA,EAAAA,SAAU,CAAC,CAAA,CAAA;EACzC,MAAMG,eAAe,GAAG,MAAM,CAAA;EAC9B,MAAMC,eAAe,GAAG,MAAM,CAAA;;EAE9B;EACA;EACA;;EAEA,MAAMC,KAAK,SAASC,aAAa,CAAC;EAChC;IACA,WAAWR,IAAIA,GAAG;EAChB,IAAA,OAAOA,IAAI,CAAA;EACb,GAAA;;EAEA;EACAS,EAAAA,KAAKA,GAAG;MACN,MAAMC,UAAU,GAAGC,YAAY,CAACC,OAAO,CAAC,IAAI,CAACC,QAAQ,EAAEV,WAAW,CAAC,CAAA;MAEnE,IAAIO,UAAU,CAACI,gBAAgB,EAAE;EAC/B,MAAA,OAAA;EACF,KAAA;MAEA,IAAI,CAACD,QAAQ,CAACE,SAAS,CAACC,MAAM,CAACV,eAAe,CAAC,CAAA;MAE/C,MAAMW,UAAU,GAAG,IAAI,CAACJ,QAAQ,CAACE,SAAS,CAACG,QAAQ,CAACb,eAAe,CAAC,CAAA;EACpE,IAAA,IAAI,CAACc,cAAc,CAAC,MAAM,IAAI,CAACC,eAAe,EAAE,EAAE,IAAI,CAACP,QAAQ,EAAEI,UAAU,CAAC,CAAA;EAC9E,GAAA;;EAEA;EACAG,EAAAA,eAAeA,GAAG;EAChB,IAAA,IAAI,CAACP,QAAQ,CAACG,MAAM,EAAE,CAAA;MACtBL,YAAY,CAACC,OAAO,CAAC,IAAI,CAACC,QAAQ,EAAET,YAAY,CAAC,CAAA;MACjD,IAAI,CAACiB,OAAO,EAAE,CAAA;EAChB,GAAA;;EAEA;IACA,OAAOC,eAAeA,CAACC,MAAM,EAAE;EAC7B,IAAA,OAAO,IAAI,CAACC,IAAI,CAAC,YAAY;EAC3B,MAAA,MAAMC,IAAI,GAAGlB,KAAK,CAACmB,mBAAmB,CAAC,IAAI,CAAC,CAAA;EAE5C,MAAA,IAAI,OAAOH,MAAM,KAAK,QAAQ,EAAE;EAC9B,QAAA,OAAA;EACF,OAAA;EAEA,MAAA,IAAIE,IAAI,CAACF,MAAM,CAAC,KAAKI,SAAS,IAAIJ,MAAM,CAACK,UAAU,CAAC,GAAG,CAAC,IAAIL,MAAM,KAAK,aAAa,EAAE;EACpF,QAAA,MAAM,IAAIM,SAAS,CAAE,CAAmBN,iBAAAA,EAAAA,MAAO,GAAE,CAAC,CAAA;EACpD,OAAA;EAEAE,MAAAA,IAAI,CAACF,MAAM,CAAC,CAAC,IAAI,CAAC,CAAA;EACpB,KAAC,CAAC,CAAA;EACJ,GAAA;EACF,CAAA;;EAEA;EACA;EACA;;AAEAO,4CAAoB,CAACvB,KAAK,EAAE,OAAO,CAAC,CAAA;;EAEpC;EACA;EACA;;AAEAwB,6BAAkB,CAACxB,KAAK,CAAC;;;;;;;;"}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap base-component.js v5.3.2 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
*/
|
|
||||||
(function (global, factory) {
|
|
||||||
typeof exports === 'object' && typeof module !== 'undefined'
|
|
||||||
? (module.exports = factory(
|
|
||||||
require('./dom/data.js'),
|
|
||||||
require('./dom/event-handler.js'),
|
|
||||||
require('./util/config.js'),
|
|
||||||
require('./util/index.js')
|
|
||||||
))
|
|
||||||
: typeof define === 'function' && define.amd
|
|
||||||
? define(['./dom/data', './dom/event-handler', './util/config', './util/index'], factory)
|
|
||||||
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
|
|
||||||
(global.BaseComponent = factory(
|
|
||||||
global.Data,
|
|
||||||
global.EventHandler,
|
|
||||||
global.Config,
|
|
||||||
global.Index
|
|
||||||
)));
|
|
||||||
})(this, function (Data, EventHandler, Config, index_js) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap base-component.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
|
|
||||||
const VERSION = '5.3.2';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class definition
|
|
||||||
*/
|
|
||||||
|
|
||||||
class BaseComponent extends Config {
|
|
||||||
constructor(element, config) {
|
|
||||||
super();
|
|
||||||
element = index_js.getElement(element);
|
|
||||||
if (!element) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._element = element;
|
|
||||||
this._config = this._getConfig(config);
|
|
||||||
Data.set(this._element, this.constructor.DATA_KEY, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
dispose() {
|
|
||||||
Data.remove(this._element, this.constructor.DATA_KEY);
|
|
||||||
EventHandler.off(this._element, this.constructor.EVENT_KEY);
|
|
||||||
for (const propertyName of Object.getOwnPropertyNames(this)) {
|
|
||||||
this[propertyName] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_queueCallback(callback, element, isAnimated = true) {
|
|
||||||
index_js.executeAfterTransition(callback, element, isAnimated);
|
|
||||||
}
|
|
||||||
_getConfig(config) {
|
|
||||||
config = this._mergeConfigObj(config, this._element);
|
|
||||||
config = this._configAfterMerge(config);
|
|
||||||
this._typeCheckConfig(config);
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
static getInstance(element) {
|
|
||||||
return Data.get(index_js.getElement(element), this.DATA_KEY);
|
|
||||||
}
|
|
||||||
static getOrCreateInstance(element, config = {}) {
|
|
||||||
return (
|
|
||||||
this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
static get VERSION() {
|
|
||||||
return VERSION;
|
|
||||||
}
|
|
||||||
static get DATA_KEY() {
|
|
||||||
return `bs.${this.NAME}`;
|
|
||||||
}
|
|
||||||
static get EVENT_KEY() {
|
|
||||||
return `.${this.DATA_KEY}`;
|
|
||||||
}
|
|
||||||
static eventName(name) {
|
|
||||||
return `${name}${this.EVENT_KEY}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return BaseComponent;
|
|
||||||
});
|
|
||||||
//# sourceMappingURL=base-component.js.map
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"base-component.js","sources":["../src/base-component.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Data from './dom/data.js'\nimport EventHandler from './dom/event-handler.js'\nimport Config from './util/config.js'\nimport { executeAfterTransition, getElement } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst VERSION = '5.3.2'\n\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n constructor(element, config) {\n super()\n\n element = getElement(element)\n if (!element) {\n return\n }\n\n this._element = element\n this._config = this._getConfig(config)\n\n Data.set(this._element, this.constructor.DATA_KEY, this)\n }\n\n // Public\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY)\n EventHandler.off(this._element, this.constructor.EVENT_KEY)\n\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null\n }\n }\n\n _queueCallback(callback, element, isAnimated = true) {\n executeAfterTransition(callback, element, isAnimated)\n }\n\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n // Static\n static getInstance(element) {\n return Data.get(getElement(element), this.DATA_KEY)\n }\n\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)\n }\n\n static get VERSION() {\n return VERSION\n }\n\n static get DATA_KEY() {\n return `bs.${this.NAME}`\n }\n\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`\n }\n\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`\n }\n}\n\nexport default BaseComponent\n"],"names":["VERSION","BaseComponent","Config","constructor","element","config","getElement","_element","_config","_getConfig","Data","set","DATA_KEY","dispose","remove","EventHandler","off","EVENT_KEY","propertyName","Object","getOwnPropertyNames","_queueCallback","callback","isAnimated","executeAfterTransition","_mergeConfigObj","_configAfterMerge","_typeCheckConfig","getInstance","get","getOrCreateInstance","NAME","eventName","name"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAOA;EACA;EACA;;EAEA,MAAMA,OAAO,GAAG,OAAO,CAAA;;EAEvB;EACA;EACA;;EAEA,MAAMC,aAAa,SAASC,MAAM,CAAC;EACjCC,EAAAA,WAAWA,CAACC,OAAO,EAAEC,MAAM,EAAE;EAC3B,IAAA,KAAK,EAAE,CAAA;EAEPD,IAAAA,OAAO,GAAGE,mBAAU,CAACF,OAAO,CAAC,CAAA;MAC7B,IAAI,CAACA,OAAO,EAAE;EACZ,MAAA,OAAA;EACF,KAAA;MAEA,IAAI,CAACG,QAAQ,GAAGH,OAAO,CAAA;MACvB,IAAI,CAACI,OAAO,GAAG,IAAI,CAACC,UAAU,CAACJ,MAAM,CAAC,CAAA;EAEtCK,IAAAA,IAAI,CAACC,GAAG,CAAC,IAAI,CAACJ,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACS,QAAQ,EAAE,IAAI,CAAC,CAAA;EAC1D,GAAA;;EAEA;EACAC,EAAAA,OAAOA,GAAG;EACRH,IAAAA,IAAI,CAACI,MAAM,CAAC,IAAI,CAACP,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACS,QAAQ,CAAC,CAAA;EACrDG,IAAAA,YAAY,CAACC,GAAG,CAAC,IAAI,CAACT,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACc,SAAS,CAAC,CAAA;MAE3D,KAAK,MAAMC,YAAY,IAAIC,MAAM,CAACC,mBAAmB,CAAC,IAAI,CAAC,EAAE;EAC3D,MAAA,IAAI,CAACF,YAAY,CAAC,GAAG,IAAI,CAAA;EAC3B,KAAA;EACF,GAAA;IAEAG,cAAcA,CAACC,QAAQ,EAAElB,OAAO,EAAEmB,UAAU,GAAG,IAAI,EAAE;EACnDC,IAAAA,+BAAsB,CAACF,QAAQ,EAAElB,OAAO,EAAEmB,UAAU,CAAC,CAAA;EACvD,GAAA;IAEAd,UAAUA,CAACJ,MAAM,EAAE;MACjBA,MAAM,GAAG,IAAI,CAACoB,eAAe,CAACpB,MAAM,EAAE,IAAI,CAACE,QAAQ,CAAC,CAAA;EACpDF,IAAAA,MAAM,GAAG,IAAI,CAACqB,iBAAiB,CAACrB,MAAM,CAAC,CAAA;EACvC,IAAA,IAAI,CAACsB,gBAAgB,CAACtB,MAAM,CAAC,CAAA;EAC7B,IAAA,OAAOA,MAAM,CAAA;EACf,GAAA;;EAEA;IACA,OAAOuB,WAAWA,CAACxB,OAAO,EAAE;EAC1B,IAAA,OAAOM,IAAI,CAACmB,GAAG,CAACvB,mBAAU,CAACF,OAAO,CAAC,EAAE,IAAI,CAACQ,QAAQ,CAAC,CAAA;EACrD,GAAA;IAEA,OAAOkB,mBAAmBA,CAAC1B,OAAO,EAAEC,MAAM,GAAG,EAAE,EAAE;MAC/C,OAAO,IAAI,CAACuB,WAAW,CAACxB,OAAO,CAAC,IAAI,IAAI,IAAI,CAACA,OAAO,EAAE,OAAOC,MAAM,KAAK,QAAQ,GAAGA,MAAM,GAAG,IAAI,CAAC,CAAA;EACnG,GAAA;IAEA,WAAWL,OAAOA,GAAG;EACnB,IAAA,OAAOA,OAAO,CAAA;EAChB,GAAA;IAEA,WAAWY,QAAQA,GAAG;EACpB,IAAA,OAAQ,CAAK,GAAA,EAAA,IAAI,CAACmB,IAAK,CAAC,CAAA,CAAA;EAC1B,GAAA;IAEA,WAAWd,SAASA,GAAG;EACrB,IAAA,OAAQ,CAAG,CAAA,EAAA,IAAI,CAACL,QAAS,CAAC,CAAA,CAAA;EAC5B,GAAA;IAEA,OAAOoB,SAASA,CAACC,IAAI,EAAE;EACrB,IAAA,OAAQ,GAAEA,IAAK,CAAA,EAAE,IAAI,CAAChB,SAAU,CAAC,CAAA,CAAA;EACnC,GAAA;EACF;;;;;;;;"}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap button.js v5.3.2 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
*/
|
|
||||||
(function (global, factory) {
|
|
||||||
typeof exports === 'object' && typeof module !== 'undefined'
|
|
||||||
? (module.exports = factory(
|
|
||||||
require('./base-component.js'),
|
|
||||||
require('./dom/event-handler.js'),
|
|
||||||
require('./util/index.js')
|
|
||||||
))
|
|
||||||
: typeof define === 'function' && define.amd
|
|
||||||
? define(['./base-component', './dom/event-handler', './util/index'], factory)
|
|
||||||
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
|
|
||||||
(global.Button = factory(global.BaseComponent, global.EventHandler, global.Index)));
|
|
||||||
})(this, function (BaseComponent, EventHandler, index_js) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap button.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'button';
|
|
||||||
const DATA_KEY = 'bs.button';
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`;
|
|
||||||
const DATA_API_KEY = '.data-api';
|
|
||||||
const CLASS_NAME_ACTIVE = 'active';
|
|
||||||
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="button"]';
|
|
||||||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class definition
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Button extends BaseComponent {
|
|
||||||
// Getters
|
|
||||||
static get NAME() {
|
|
||||||
return NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
toggle() {
|
|
||||||
// Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
|
|
||||||
this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
static jQueryInterface(config) {
|
|
||||||
return this.each(function () {
|
|
||||||
const data = Button.getOrCreateInstance(this);
|
|
||||||
if (config === 'toggle') {
|
|
||||||
data[config]();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data API implementation
|
|
||||||
*/
|
|
||||||
|
|
||||||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
const button = event.target.closest(SELECTOR_DATA_TOGGLE);
|
|
||||||
const data = Button.getOrCreateInstance(button);
|
|
||||||
data.toggle();
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* jQuery
|
|
||||||
*/
|
|
||||||
|
|
||||||
index_js.defineJQueryPlugin(Button);
|
|
||||||
|
|
||||||
return Button;
|
|
||||||
});
|
|
||||||
//# sourceMappingURL=button.js.map
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"button.js","sources":["../src/button.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport { defineJQueryPlugin } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'button'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"button\"]'\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE))\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Button.getOrCreateInstance(this)\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {\n event.preventDefault()\n\n const button = event.target.closest(SELECTOR_DATA_TOGGLE)\n const data = Button.getOrCreateInstance(button)\n\n data.toggle()\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Button)\n\nexport default Button\n"],"names":["NAME","DATA_KEY","EVENT_KEY","DATA_API_KEY","CLASS_NAME_ACTIVE","SELECTOR_DATA_TOGGLE","EVENT_CLICK_DATA_API","Button","BaseComponent","toggle","_element","setAttribute","classList","jQueryInterface","config","each","data","getOrCreateInstance","EventHandler","on","document","event","preventDefault","button","target","closest","defineJQueryPlugin"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAMA;EACA;EACA;;EAEA,MAAMA,IAAI,GAAG,QAAQ,CAAA;EACrB,MAAMC,QAAQ,GAAG,WAAW,CAAA;EAC5B,MAAMC,SAAS,GAAI,CAAGD,CAAAA,EAAAA,QAAS,CAAC,CAAA,CAAA;EAChC,MAAME,YAAY,GAAG,WAAW,CAAA;EAEhC,MAAMC,iBAAiB,GAAG,QAAQ,CAAA;EAClC,MAAMC,oBAAoB,GAAG,2BAA2B,CAAA;EACxD,MAAMC,oBAAoB,GAAI,CAAA,KAAA,EAAOJ,SAAU,CAAA,EAAEC,YAAa,CAAC,CAAA,CAAA;;EAE/D;EACA;EACA;;EAEA,MAAMI,MAAM,SAASC,aAAa,CAAC;EACjC;IACA,WAAWR,IAAIA,GAAG;EAChB,IAAA,OAAOA,IAAI,CAAA;EACb,GAAA;;EAEA;EACAS,EAAAA,MAAMA,GAAG;EACP;EACA,IAAA,IAAI,CAACC,QAAQ,CAACC,YAAY,CAAC,cAAc,EAAE,IAAI,CAACD,QAAQ,CAACE,SAAS,CAACH,MAAM,CAACL,iBAAiB,CAAC,CAAC,CAAA;EAC/F,GAAA;;EAEA;IACA,OAAOS,eAAeA,CAACC,MAAM,EAAE;EAC7B,IAAA,OAAO,IAAI,CAACC,IAAI,CAAC,YAAY;EAC3B,MAAA,MAAMC,IAAI,GAAGT,MAAM,CAACU,mBAAmB,CAAC,IAAI,CAAC,CAAA;QAE7C,IAAIH,MAAM,KAAK,QAAQ,EAAE;EACvBE,QAAAA,IAAI,CAACF,MAAM,CAAC,EAAE,CAAA;EAChB,OAAA;EACF,KAAC,CAAC,CAAA;EACJ,GAAA;EACF,CAAA;;EAEA;EACA;EACA;;EAEAI,YAAY,CAACC,EAAE,CAACC,QAAQ,EAAEd,oBAAoB,EAAED,oBAAoB,EAAEgB,KAAK,IAAI;IAC7EA,KAAK,CAACC,cAAc,EAAE,CAAA;IAEtB,MAAMC,MAAM,GAAGF,KAAK,CAACG,MAAM,CAACC,OAAO,CAACpB,oBAAoB,CAAC,CAAA;EACzD,EAAA,MAAMW,IAAI,GAAGT,MAAM,CAACU,mBAAmB,CAACM,MAAM,CAAC,CAAA;IAE/CP,IAAI,CAACP,MAAM,EAAE,CAAA;EACf,CAAC,CAAC,CAAA;;EAEF;EACA;EACA;;AAEAiB,6BAAkB,CAACnB,MAAM,CAAC;;;;;;;;"}
|
|
||||||
@@ -1,422 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap carousel.js v5.3.2 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
*/
|
|
||||||
(function (global, factory) {
|
|
||||||
typeof exports === 'object' && typeof module !== 'undefined'
|
|
||||||
? (module.exports = factory(
|
|
||||||
require('./base-component.js'),
|
|
||||||
require('./dom/event-handler.js'),
|
|
||||||
require('./dom/manipulator.js'),
|
|
||||||
require('./dom/selector-engine.js'),
|
|
||||||
require('./util/index.js'),
|
|
||||||
require('./util/swipe.js')
|
|
||||||
))
|
|
||||||
: typeof define === 'function' && define.amd
|
|
||||||
? define(
|
|
||||||
[
|
|
||||||
'./base-component',
|
|
||||||
'./dom/event-handler',
|
|
||||||
'./dom/manipulator',
|
|
||||||
'./dom/selector-engine',
|
|
||||||
'./util/index',
|
|
||||||
'./util/swipe',
|
|
||||||
],
|
|
||||||
factory
|
|
||||||
)
|
|
||||||
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
|
|
||||||
(global.Carousel = factory(
|
|
||||||
global.BaseComponent,
|
|
||||||
global.EventHandler,
|
|
||||||
global.Manipulator,
|
|
||||||
global.SelectorEngine,
|
|
||||||
global.Index,
|
|
||||||
global.Swipe
|
|
||||||
)));
|
|
||||||
})(this, function (BaseComponent, EventHandler, Manipulator, SelectorEngine, index_js, Swipe) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap carousel.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'carousel';
|
|
||||||
const DATA_KEY = 'bs.carousel';
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`;
|
|
||||||
const DATA_API_KEY = '.data-api';
|
|
||||||
const ARROW_LEFT_KEY = 'ArrowLeft';
|
|
||||||
const ARROW_RIGHT_KEY = 'ArrowRight';
|
|
||||||
const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
|
|
||||||
|
|
||||||
const ORDER_NEXT = 'next';
|
|
||||||
const ORDER_PREV = 'prev';
|
|
||||||
const DIRECTION_LEFT = 'left';
|
|
||||||
const DIRECTION_RIGHT = 'right';
|
|
||||||
const EVENT_SLIDE = `slide${EVENT_KEY}`;
|
|
||||||
const EVENT_SLID = `slid${EVENT_KEY}`;
|
|
||||||
const EVENT_KEYDOWN = `keydown${EVENT_KEY}`;
|
|
||||||
const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`;
|
|
||||||
const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`;
|
|
||||||
const EVENT_DRAG_START = `dragstart${EVENT_KEY}`;
|
|
||||||
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`;
|
|
||||||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
|
|
||||||
const CLASS_NAME_CAROUSEL = 'carousel';
|
|
||||||
const CLASS_NAME_ACTIVE = 'active';
|
|
||||||
const CLASS_NAME_SLIDE = 'slide';
|
|
||||||
const CLASS_NAME_END = 'carousel-item-end';
|
|
||||||
const CLASS_NAME_START = 'carousel-item-start';
|
|
||||||
const CLASS_NAME_NEXT = 'carousel-item-next';
|
|
||||||
const CLASS_NAME_PREV = 'carousel-item-prev';
|
|
||||||
const SELECTOR_ACTIVE = '.active';
|
|
||||||
const SELECTOR_ITEM = '.carousel-item';
|
|
||||||
const SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM;
|
|
||||||
const SELECTOR_ITEM_IMG = '.carousel-item img';
|
|
||||||
const SELECTOR_INDICATORS = '.carousel-indicators';
|
|
||||||
const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';
|
|
||||||
const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]';
|
|
||||||
const KEY_TO_DIRECTION = {
|
|
||||||
[ARROW_LEFT_KEY]: DIRECTION_RIGHT,
|
|
||||||
[ARROW_RIGHT_KEY]: DIRECTION_LEFT,
|
|
||||||
};
|
|
||||||
const Default = {
|
|
||||||
interval: 5000,
|
|
||||||
keyboard: true,
|
|
||||||
pause: 'hover',
|
|
||||||
ride: false,
|
|
||||||
touch: true,
|
|
||||||
wrap: true,
|
|
||||||
};
|
|
||||||
const DefaultType = {
|
|
||||||
interval: '(number|boolean)',
|
|
||||||
// TODO:v6 remove boolean support
|
|
||||||
keyboard: 'boolean',
|
|
||||||
pause: '(string|boolean)',
|
|
||||||
ride: '(boolean|string)',
|
|
||||||
touch: 'boolean',
|
|
||||||
wrap: 'boolean',
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class definition
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Carousel extends BaseComponent {
|
|
||||||
constructor(element, config) {
|
|
||||||
super(element, config);
|
|
||||||
this._interval = null;
|
|
||||||
this._activeElement = null;
|
|
||||||
this._isSliding = false;
|
|
||||||
this.touchTimeout = null;
|
|
||||||
this._swipeHelper = null;
|
|
||||||
this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);
|
|
||||||
this._addEventListeners();
|
|
||||||
if (this._config.ride === CLASS_NAME_CAROUSEL) {
|
|
||||||
this.cycle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
static get Default() {
|
|
||||||
return Default;
|
|
||||||
}
|
|
||||||
static get DefaultType() {
|
|
||||||
return DefaultType;
|
|
||||||
}
|
|
||||||
static get NAME() {
|
|
||||||
return NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
next() {
|
|
||||||
this._slide(ORDER_NEXT);
|
|
||||||
}
|
|
||||||
nextWhenVisible() {
|
|
||||||
// FIXME TODO use `document.visibilityState`
|
|
||||||
// Don't call next when the page isn't visible
|
|
||||||
// or the carousel or its parent isn't visible
|
|
||||||
if (!document.hidden && index_js.isVisible(this._element)) {
|
|
||||||
this.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prev() {
|
|
||||||
this._slide(ORDER_PREV);
|
|
||||||
}
|
|
||||||
pause() {
|
|
||||||
if (this._isSliding) {
|
|
||||||
index_js.triggerTransitionEnd(this._element);
|
|
||||||
}
|
|
||||||
this._clearInterval();
|
|
||||||
}
|
|
||||||
cycle() {
|
|
||||||
this._clearInterval();
|
|
||||||
this._updateInterval();
|
|
||||||
this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval);
|
|
||||||
}
|
|
||||||
_maybeEnableCycle() {
|
|
||||||
if (!this._config.ride) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this._isSliding) {
|
|
||||||
EventHandler.one(this._element, EVENT_SLID, () => this.cycle());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.cycle();
|
|
||||||
}
|
|
||||||
to(index) {
|
|
||||||
const items = this._getItems();
|
|
||||||
if (index > items.length - 1 || index < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this._isSliding) {
|
|
||||||
EventHandler.one(this._element, EVENT_SLID, () => this.to(index));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const activeIndex = this._getItemIndex(this._getActive());
|
|
||||||
if (activeIndex === index) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;
|
|
||||||
this._slide(order, items[index]);
|
|
||||||
}
|
|
||||||
dispose() {
|
|
||||||
if (this._swipeHelper) {
|
|
||||||
this._swipeHelper.dispose();
|
|
||||||
}
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private
|
|
||||||
_configAfterMerge(config) {
|
|
||||||
config.defaultInterval = config.interval;
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
_addEventListeners() {
|
|
||||||
if (this._config.keyboard) {
|
|
||||||
EventHandler.on(this._element, EVENT_KEYDOWN, (event) => this._keydown(event));
|
|
||||||
}
|
|
||||||
if (this._config.pause === 'hover') {
|
|
||||||
EventHandler.on(this._element, EVENT_MOUSEENTER, () => this.pause());
|
|
||||||
EventHandler.on(this._element, EVENT_MOUSELEAVE, () => this._maybeEnableCycle());
|
|
||||||
}
|
|
||||||
if (this._config.touch && Swipe.isSupported()) {
|
|
||||||
this._addTouchEventListeners();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_addTouchEventListeners() {
|
|
||||||
for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {
|
|
||||||
EventHandler.on(img, EVENT_DRAG_START, (event) => event.preventDefault());
|
|
||||||
}
|
|
||||||
const endCallBack = () => {
|
|
||||||
if (this._config.pause !== 'hover') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it's a touch-enabled device, mouseenter/leave are fired as
|
|
||||||
// part of the mouse compatibility events on first tap - the carousel
|
|
||||||
// would stop cycling until user tapped out of it;
|
|
||||||
// here, we listen for touchend, explicitly pause the carousel
|
|
||||||
// (as if it's the second time we tap on it, mouseenter compat event
|
|
||||||
// is NOT fired) and after a timeout (to allow for mouse compatibility
|
|
||||||
// events to fire) we explicitly restart cycling
|
|
||||||
|
|
||||||
this.pause();
|
|
||||||
if (this.touchTimeout) {
|
|
||||||
clearTimeout(this.touchTimeout);
|
|
||||||
}
|
|
||||||
this.touchTimeout = setTimeout(
|
|
||||||
() => this._maybeEnableCycle(),
|
|
||||||
TOUCHEVENT_COMPAT_WAIT + this._config.interval
|
|
||||||
);
|
|
||||||
};
|
|
||||||
const swipeConfig = {
|
|
||||||
leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),
|
|
||||||
rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),
|
|
||||||
endCallback: endCallBack,
|
|
||||||
};
|
|
||||||
this._swipeHelper = new Swipe(this._element, swipeConfig);
|
|
||||||
}
|
|
||||||
_keydown(event) {
|
|
||||||
if (/input|textarea/i.test(event.target.tagName)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const direction = KEY_TO_DIRECTION[event.key];
|
|
||||||
if (direction) {
|
|
||||||
event.preventDefault();
|
|
||||||
this._slide(this._directionToOrder(direction));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_getItemIndex(element) {
|
|
||||||
return this._getItems().indexOf(element);
|
|
||||||
}
|
|
||||||
_setActiveIndicatorElement(index) {
|
|
||||||
if (!this._indicatorsElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement);
|
|
||||||
activeIndicator.classList.remove(CLASS_NAME_ACTIVE);
|
|
||||||
activeIndicator.removeAttribute('aria-current');
|
|
||||||
const newActiveIndicator = SelectorEngine.findOne(
|
|
||||||
`[data-bs-slide-to="${index}"]`,
|
|
||||||
this._indicatorsElement
|
|
||||||
);
|
|
||||||
if (newActiveIndicator) {
|
|
||||||
newActiveIndicator.classList.add(CLASS_NAME_ACTIVE);
|
|
||||||
newActiveIndicator.setAttribute('aria-current', 'true');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_updateInterval() {
|
|
||||||
const element = this._activeElement || this._getActive();
|
|
||||||
if (!element) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);
|
|
||||||
this._config.interval = elementInterval || this._config.defaultInterval;
|
|
||||||
}
|
|
||||||
_slide(order, element = null) {
|
|
||||||
if (this._isSliding) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const activeElement = this._getActive();
|
|
||||||
const isNext = order === ORDER_NEXT;
|
|
||||||
const nextElement =
|
|
||||||
element ||
|
|
||||||
index_js.getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap);
|
|
||||||
if (nextElement === activeElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const nextElementIndex = this._getItemIndex(nextElement);
|
|
||||||
const triggerEvent = (eventName) => {
|
|
||||||
return EventHandler.trigger(this._element, eventName, {
|
|
||||||
relatedTarget: nextElement,
|
|
||||||
direction: this._orderToDirection(order),
|
|
||||||
from: this._getItemIndex(activeElement),
|
|
||||||
to: nextElementIndex,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const slideEvent = triggerEvent(EVENT_SLIDE);
|
|
||||||
if (slideEvent.defaultPrevented) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!activeElement || !nextElement) {
|
|
||||||
// Some weirdness is happening, so we bail
|
|
||||||
// TODO: change tests that use empty divs to avoid this check
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const isCycling = Boolean(this._interval);
|
|
||||||
this.pause();
|
|
||||||
this._isSliding = true;
|
|
||||||
this._setActiveIndicatorElement(nextElementIndex);
|
|
||||||
this._activeElement = nextElement;
|
|
||||||
const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;
|
|
||||||
const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;
|
|
||||||
nextElement.classList.add(orderClassName);
|
|
||||||
index_js.reflow(nextElement);
|
|
||||||
activeElement.classList.add(directionalClassName);
|
|
||||||
nextElement.classList.add(directionalClassName);
|
|
||||||
const completeCallBack = () => {
|
|
||||||
nextElement.classList.remove(directionalClassName, orderClassName);
|
|
||||||
nextElement.classList.add(CLASS_NAME_ACTIVE);
|
|
||||||
activeElement.classList.remove(CLASS_NAME_ACTIVE, orderClassName, directionalClassName);
|
|
||||||
this._isSliding = false;
|
|
||||||
triggerEvent(EVENT_SLID);
|
|
||||||
};
|
|
||||||
this._queueCallback(completeCallBack, activeElement, this._isAnimated());
|
|
||||||
if (isCycling) {
|
|
||||||
this.cycle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_isAnimated() {
|
|
||||||
return this._element.classList.contains(CLASS_NAME_SLIDE);
|
|
||||||
}
|
|
||||||
_getActive() {
|
|
||||||
return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);
|
|
||||||
}
|
|
||||||
_getItems() {
|
|
||||||
return SelectorEngine.find(SELECTOR_ITEM, this._element);
|
|
||||||
}
|
|
||||||
_clearInterval() {
|
|
||||||
if (this._interval) {
|
|
||||||
clearInterval(this._interval);
|
|
||||||
this._interval = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_directionToOrder(direction) {
|
|
||||||
if (index_js.isRTL()) {
|
|
||||||
return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;
|
|
||||||
}
|
|
||||||
return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;
|
|
||||||
}
|
|
||||||
_orderToDirection(order) {
|
|
||||||
if (index_js.isRTL()) {
|
|
||||||
return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;
|
|
||||||
}
|
|
||||||
return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
static jQueryInterface(config) {
|
|
||||||
return this.each(function () {
|
|
||||||
const data = Carousel.getOrCreateInstance(this, config);
|
|
||||||
if (typeof config === 'number') {
|
|
||||||
data.to(config);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeof config === 'string') {
|
|
||||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
|
||||||
throw new TypeError(`No method named "${config}"`);
|
|
||||||
}
|
|
||||||
data[config]();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data API implementation
|
|
||||||
*/
|
|
||||||
|
|
||||||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, function (event) {
|
|
||||||
const target = SelectorEngine.getElementFromSelector(this);
|
|
||||||
if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
const carousel = Carousel.getOrCreateInstance(target);
|
|
||||||
const slideIndex = this.getAttribute('data-bs-slide-to');
|
|
||||||
if (slideIndex) {
|
|
||||||
carousel.to(slideIndex);
|
|
||||||
carousel._maybeEnableCycle();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Manipulator.getDataAttribute(this, 'slide') === 'next') {
|
|
||||||
carousel.next();
|
|
||||||
carousel._maybeEnableCycle();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
carousel.prev();
|
|
||||||
carousel._maybeEnableCycle();
|
|
||||||
});
|
|
||||||
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
|
||||||
const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);
|
|
||||||
for (const carousel of carousels) {
|
|
||||||
Carousel.getOrCreateInstance(carousel);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* jQuery
|
|
||||||
*/
|
|
||||||
|
|
||||||
index_js.defineJQueryPlugin(Carousel);
|
|
||||||
|
|
||||||
return Carousel;
|
|
||||||
});
|
|
||||||
//# sourceMappingURL=carousel.js.map
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,275 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap collapse.js v5.3.2 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
*/
|
|
||||||
(function (global, factory) {
|
|
||||||
typeof exports === 'object' && typeof module !== 'undefined'
|
|
||||||
? (module.exports = factory(
|
|
||||||
require('./base-component.js'),
|
|
||||||
require('./dom/event-handler.js'),
|
|
||||||
require('./dom/selector-engine.js'),
|
|
||||||
require('./util/index.js')
|
|
||||||
))
|
|
||||||
: typeof define === 'function' && define.amd
|
|
||||||
? define(
|
|
||||||
['./base-component', './dom/event-handler', './dom/selector-engine', './util/index'],
|
|
||||||
factory
|
|
||||||
)
|
|
||||||
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
|
|
||||||
(global.Collapse = factory(
|
|
||||||
global.BaseComponent,
|
|
||||||
global.EventHandler,
|
|
||||||
global.SelectorEngine,
|
|
||||||
global.Index
|
|
||||||
)));
|
|
||||||
})(this, function (BaseComponent, EventHandler, SelectorEngine, index_js) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap collapse.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NAME = 'collapse';
|
|
||||||
const DATA_KEY = 'bs.collapse';
|
|
||||||
const EVENT_KEY = `.${DATA_KEY}`;
|
|
||||||
const DATA_API_KEY = '.data-api';
|
|
||||||
const EVENT_SHOW = `show${EVENT_KEY}`;
|
|
||||||
const EVENT_SHOWN = `shown${EVENT_KEY}`;
|
|
||||||
const EVENT_HIDE = `hide${EVENT_KEY}`;
|
|
||||||
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
|
|
||||||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
|
|
||||||
const CLASS_NAME_SHOW = 'show';
|
|
||||||
const CLASS_NAME_COLLAPSE = 'collapse';
|
|
||||||
const CLASS_NAME_COLLAPSING = 'collapsing';
|
|
||||||
const CLASS_NAME_COLLAPSED = 'collapsed';
|
|
||||||
const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;
|
|
||||||
const CLASS_NAME_HORIZONTAL = 'collapse-horizontal';
|
|
||||||
const WIDTH = 'width';
|
|
||||||
const HEIGHT = 'height';
|
|
||||||
const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';
|
|
||||||
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="collapse"]';
|
|
||||||
const Default = {
|
|
||||||
parent: null,
|
|
||||||
toggle: true,
|
|
||||||
};
|
|
||||||
const DefaultType = {
|
|
||||||
parent: '(null|element)',
|
|
||||||
toggle: 'boolean',
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class definition
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Collapse extends BaseComponent {
|
|
||||||
constructor(element, config) {
|
|
||||||
super(element, config);
|
|
||||||
this._isTransitioning = false;
|
|
||||||
this._triggerArray = [];
|
|
||||||
const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE);
|
|
||||||
for (const elem of toggleList) {
|
|
||||||
const selector = SelectorEngine.getSelectorFromElement(elem);
|
|
||||||
const filterElement = SelectorEngine.find(selector).filter(
|
|
||||||
(foundElement) => foundElement === this._element
|
|
||||||
);
|
|
||||||
if (selector !== null && filterElement.length) {
|
|
||||||
this._triggerArray.push(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._initializeChildren();
|
|
||||||
if (!this._config.parent) {
|
|
||||||
this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());
|
|
||||||
}
|
|
||||||
if (this._config.toggle) {
|
|
||||||
this.toggle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getters
|
|
||||||
static get Default() {
|
|
||||||
return Default;
|
|
||||||
}
|
|
||||||
static get DefaultType() {
|
|
||||||
return DefaultType;
|
|
||||||
}
|
|
||||||
static get NAME() {
|
|
||||||
return NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public
|
|
||||||
toggle() {
|
|
||||||
if (this._isShown()) {
|
|
||||||
this.hide();
|
|
||||||
} else {
|
|
||||||
this.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
show() {
|
|
||||||
if (this._isTransitioning || this._isShown()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let activeChildren = [];
|
|
||||||
|
|
||||||
// find active children
|
|
||||||
if (this._config.parent) {
|
|
||||||
activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES)
|
|
||||||
.filter((element) => element !== this._element)
|
|
||||||
.map((element) =>
|
|
||||||
Collapse.getOrCreateInstance(element, {
|
|
||||||
toggle: false,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (activeChildren.length && activeChildren[0]._isTransitioning) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const startEvent = EventHandler.trigger(this._element, EVENT_SHOW);
|
|
||||||
if (startEvent.defaultPrevented) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (const activeInstance of activeChildren) {
|
|
||||||
activeInstance.hide();
|
|
||||||
}
|
|
||||||
const dimension = this._getDimension();
|
|
||||||
this._element.classList.remove(CLASS_NAME_COLLAPSE);
|
|
||||||
this._element.classList.add(CLASS_NAME_COLLAPSING);
|
|
||||||
this._element.style[dimension] = 0;
|
|
||||||
this._addAriaAndCollapsedClass(this._triggerArray, true);
|
|
||||||
this._isTransitioning = true;
|
|
||||||
const complete = () => {
|
|
||||||
this._isTransitioning = false;
|
|
||||||
this._element.classList.remove(CLASS_NAME_COLLAPSING);
|
|
||||||
this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW);
|
|
||||||
this._element.style[dimension] = '';
|
|
||||||
EventHandler.trigger(this._element, EVENT_SHOWN);
|
|
||||||
};
|
|
||||||
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
|
|
||||||
const scrollSize = `scroll${capitalizedDimension}`;
|
|
||||||
this._queueCallback(complete, this._element, true);
|
|
||||||
this._element.style[dimension] = `${this._element[scrollSize]}px`;
|
|
||||||
}
|
|
||||||
hide() {
|
|
||||||
if (this._isTransitioning || !this._isShown()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const startEvent = EventHandler.trigger(this._element, EVENT_HIDE);
|
|
||||||
if (startEvent.defaultPrevented) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const dimension = this._getDimension();
|
|
||||||
this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;
|
|
||||||
index_js.reflow(this._element);
|
|
||||||
this._element.classList.add(CLASS_NAME_COLLAPSING);
|
|
||||||
this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW);
|
|
||||||
for (const trigger of this._triggerArray) {
|
|
||||||
const element = SelectorEngine.getElementFromSelector(trigger);
|
|
||||||
if (element && !this._isShown(element)) {
|
|
||||||
this._addAriaAndCollapsedClass([trigger], false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._isTransitioning = true;
|
|
||||||
const complete = () => {
|
|
||||||
this._isTransitioning = false;
|
|
||||||
this._element.classList.remove(CLASS_NAME_COLLAPSING);
|
|
||||||
this._element.classList.add(CLASS_NAME_COLLAPSE);
|
|
||||||
EventHandler.trigger(this._element, EVENT_HIDDEN);
|
|
||||||
};
|
|
||||||
this._element.style[dimension] = '';
|
|
||||||
this._queueCallback(complete, this._element, true);
|
|
||||||
}
|
|
||||||
_isShown(element = this._element) {
|
|
||||||
return element.classList.contains(CLASS_NAME_SHOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private
|
|
||||||
_configAfterMerge(config) {
|
|
||||||
config.toggle = Boolean(config.toggle); // Coerce string values
|
|
||||||
config.parent = index_js.getElement(config.parent);
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
_getDimension() {
|
|
||||||
return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;
|
|
||||||
}
|
|
||||||
_initializeChildren() {
|
|
||||||
if (!this._config.parent) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE);
|
|
||||||
for (const element of children) {
|
|
||||||
const selected = SelectorEngine.getElementFromSelector(element);
|
|
||||||
if (selected) {
|
|
||||||
this._addAriaAndCollapsedClass([element], this._isShown(selected));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_getFirstLevelChildren(selector) {
|
|
||||||
const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);
|
|
||||||
// remove children if greater depth
|
|
||||||
return SelectorEngine.find(selector, this._config.parent).filter(
|
|
||||||
(element) => !children.includes(element)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_addAriaAndCollapsedClass(triggerArray, isOpen) {
|
|
||||||
if (!triggerArray.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (const element of triggerArray) {
|
|
||||||
element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen);
|
|
||||||
element.setAttribute('aria-expanded', isOpen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
static jQueryInterface(config) {
|
|
||||||
const _config = {};
|
|
||||||
if (typeof config === 'string' && /show|hide/.test(config)) {
|
|
||||||
_config.toggle = false;
|
|
||||||
}
|
|
||||||
return this.each(function () {
|
|
||||||
const data = Collapse.getOrCreateInstance(this, _config);
|
|
||||||
if (typeof config === 'string') {
|
|
||||||
if (typeof data[config] === 'undefined') {
|
|
||||||
throw new TypeError(`No method named "${config}"`);
|
|
||||||
}
|
|
||||||
data[config]();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data API implementation
|
|
||||||
*/
|
|
||||||
|
|
||||||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
|
||||||
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
|
|
||||||
if (
|
|
||||||
event.target.tagName === 'A' ||
|
|
||||||
(event.delegateTarget && event.delegateTarget.tagName === 'A')
|
|
||||||
) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {
|
|
||||||
Collapse.getOrCreateInstance(element, {
|
|
||||||
toggle: false,
|
|
||||||
}).toggle();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* jQuery
|
|
||||||
*/
|
|
||||||
|
|
||||||
index_js.defineJQueryPlugin(Collapse);
|
|
||||||
|
|
||||||
return Collapse;
|
|
||||||
});
|
|
||||||
//# sourceMappingURL=collapse.js.map
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,70 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap data.js v5.3.2 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
*/
|
|
||||||
(function (global, factory) {
|
|
||||||
typeof exports === 'object' && typeof module !== 'undefined'
|
|
||||||
? (module.exports = factory())
|
|
||||||
: typeof define === 'function' && define.amd
|
|
||||||
? define(factory)
|
|
||||||
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
|
|
||||||
(global.Data = factory()));
|
|
||||||
})(this, function () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap dom/data.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
|
|
||||||
const elementMap = new Map();
|
|
||||||
const data = {
|
|
||||||
set(element, key, instance) {
|
|
||||||
if (!elementMap.has(element)) {
|
|
||||||
elementMap.set(element, new Map());
|
|
||||||
}
|
|
||||||
const instanceMap = elementMap.get(element);
|
|
||||||
|
|
||||||
// make it clear we only want one instance per element
|
|
||||||
// can be removed later when multiple key/instances are fine to be used
|
|
||||||
if (!instanceMap.has(key) && instanceMap.size !== 0) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(
|
|
||||||
`Bootstrap doesn't allow more than one instance per element. Bound instance: ${
|
|
||||||
Array.from(instanceMap.keys())[0]
|
|
||||||
}.`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
instanceMap.set(key, instance);
|
|
||||||
},
|
|
||||||
get(element, key) {
|
|
||||||
if (elementMap.has(element)) {
|
|
||||||
return elementMap.get(element).get(key) || null;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
remove(element, key) {
|
|
||||||
if (!elementMap.has(element)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const instanceMap = elementMap.get(element);
|
|
||||||
instanceMap.delete(key);
|
|
||||||
|
|
||||||
// free up element references if there are no instances left for an element
|
|
||||||
if (instanceMap.size === 0) {
|
|
||||||
elementMap.delete(element);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
});
|
|
||||||
//# sourceMappingURL=data.js.map
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"data.js","sources":["../../src/dom/data.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * Constants\n */\n\nconst elementMap = new Map()\n\nexport default {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map())\n }\n\n const instanceMap = elementMap.get(element)\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`)\n return\n }\n\n instanceMap.set(key, instance)\n },\n\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null\n }\n\n return null\n },\n\n remove(element, key) {\n if (!elementMap.has(element)) {\n return\n }\n\n const instanceMap = elementMap.get(element)\n\n instanceMap.delete(key)\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element)\n }\n }\n}\n"],"names":["elementMap","Map","set","element","key","instance","has","instanceMap","get","size","console","error","Array","from","keys","remove","delete"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;;EAEA,MAAMA,UAAU,GAAG,IAAIC,GAAG,EAAE,CAAA;AAE5B,eAAe;EACbC,EAAAA,GAAGA,CAACC,OAAO,EAAEC,GAAG,EAAEC,QAAQ,EAAE;EAC1B,IAAA,IAAI,CAACL,UAAU,CAACM,GAAG,CAACH,OAAO,CAAC,EAAE;QAC5BH,UAAU,CAACE,GAAG,CAACC,OAAO,EAAE,IAAIF,GAAG,EAAE,CAAC,CAAA;EACpC,KAAA;EAEA,IAAA,MAAMM,WAAW,GAAGP,UAAU,CAACQ,GAAG,CAACL,OAAO,CAAC,CAAA;;EAE3C;EACA;EACA,IAAA,IAAI,CAACI,WAAW,CAACD,GAAG,CAACF,GAAG,CAAC,IAAIG,WAAW,CAACE,IAAI,KAAK,CAAC,EAAE;EACnD;EACAC,MAAAA,OAAO,CAACC,KAAK,CAAE,+EAA8EC,KAAK,CAACC,IAAI,CAACN,WAAW,CAACO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAE,GAAE,CAAC,CAAA;EAClI,MAAA,OAAA;EACF,KAAA;EAEAP,IAAAA,WAAW,CAACL,GAAG,CAACE,GAAG,EAAEC,QAAQ,CAAC,CAAA;KAC/B;EAEDG,EAAAA,GAAGA,CAACL,OAAO,EAAEC,GAAG,EAAE;EAChB,IAAA,IAAIJ,UAAU,CAACM,GAAG,CAACH,OAAO,CAAC,EAAE;EAC3B,MAAA,OAAOH,UAAU,CAACQ,GAAG,CAACL,OAAO,CAAC,CAACK,GAAG,CAACJ,GAAG,CAAC,IAAI,IAAI,CAAA;EACjD,KAAA;EAEA,IAAA,OAAO,IAAI,CAAA;KACZ;EAEDW,EAAAA,MAAMA,CAACZ,OAAO,EAAEC,GAAG,EAAE;EACnB,IAAA,IAAI,CAACJ,UAAU,CAACM,GAAG,CAACH,OAAO,CAAC,EAAE;EAC5B,MAAA,OAAA;EACF,KAAA;EAEA,IAAA,MAAMI,WAAW,GAAGP,UAAU,CAACQ,GAAG,CAACL,OAAO,CAAC,CAAA;EAE3CI,IAAAA,WAAW,CAACS,MAAM,CAACZ,GAAG,CAAC,CAAA;;EAEvB;EACA,IAAA,IAAIG,WAAW,CAACE,IAAI,KAAK,CAAC,EAAE;EAC1BT,MAAAA,UAAU,CAACgB,MAAM,CAACb,OAAO,CAAC,CAAA;EAC5B,KAAA;EACF,GAAA;EACF,CAAC;;;;;;;;"}
|
|
||||||
@@ -1,303 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap event-handler.js v5.3.2 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
*/
|
|
||||||
(function (global, factory) {
|
|
||||||
typeof exports === 'object' && typeof module !== 'undefined'
|
|
||||||
? (module.exports = factory(require('../util/index.js')))
|
|
||||||
: typeof define === 'function' && define.amd
|
|
||||||
? define(['../util/index'], factory)
|
|
||||||
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
|
|
||||||
(global.EventHandler = factory(global.Index)));
|
|
||||||
})(this, function (index_js) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap dom/event-handler.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constants
|
|
||||||
*/
|
|
||||||
|
|
||||||
const namespaceRegex = /[^.]*(?=\..*)\.|.*/;
|
|
||||||
const stripNameRegex = /\..*/;
|
|
||||||
const stripUidRegex = /::\d+$/;
|
|
||||||
const eventRegistry = {}; // Events storage
|
|
||||||
let uidEvent = 1;
|
|
||||||
const customEvents = {
|
|
||||||
mouseenter: 'mouseover',
|
|
||||||
mouseleave: 'mouseout',
|
|
||||||
};
|
|
||||||
const nativeEvents = new Set([
|
|
||||||
'click',
|
|
||||||
'dblclick',
|
|
||||||
'mouseup',
|
|
||||||
'mousedown',
|
|
||||||
'contextmenu',
|
|
||||||
'mousewheel',
|
|
||||||
'DOMMouseScroll',
|
|
||||||
'mouseover',
|
|
||||||
'mouseout',
|
|
||||||
'mousemove',
|
|
||||||
'selectstart',
|
|
||||||
'selectend',
|
|
||||||
'keydown',
|
|
||||||
'keypress',
|
|
||||||
'keyup',
|
|
||||||
'orientationchange',
|
|
||||||
'touchstart',
|
|
||||||
'touchmove',
|
|
||||||
'touchend',
|
|
||||||
'touchcancel',
|
|
||||||
'pointerdown',
|
|
||||||
'pointermove',
|
|
||||||
'pointerup',
|
|
||||||
'pointerleave',
|
|
||||||
'pointercancel',
|
|
||||||
'gesturestart',
|
|
||||||
'gesturechange',
|
|
||||||
'gestureend',
|
|
||||||
'focus',
|
|
||||||
'blur',
|
|
||||||
'change',
|
|
||||||
'reset',
|
|
||||||
'select',
|
|
||||||
'submit',
|
|
||||||
'focusin',
|
|
||||||
'focusout',
|
|
||||||
'load',
|
|
||||||
'unload',
|
|
||||||
'beforeunload',
|
|
||||||
'resize',
|
|
||||||
'move',
|
|
||||||
'DOMContentLoaded',
|
|
||||||
'readystatechange',
|
|
||||||
'error',
|
|
||||||
'abort',
|
|
||||||
'scroll',
|
|
||||||
]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private methods
|
|
||||||
*/
|
|
||||||
|
|
||||||
function makeEventUid(element, uid) {
|
|
||||||
return (uid && `${uid}::${uidEvent++}`) || element.uidEvent || uidEvent++;
|
|
||||||
}
|
|
||||||
function getElementEvents(element) {
|
|
||||||
const uid = makeEventUid(element);
|
|
||||||
element.uidEvent = uid;
|
|
||||||
eventRegistry[uid] = eventRegistry[uid] || {};
|
|
||||||
return eventRegistry[uid];
|
|
||||||
}
|
|
||||||
function bootstrapHandler(element, fn) {
|
|
||||||
return function handler(event) {
|
|
||||||
hydrateObj(event, {
|
|
||||||
delegateTarget: element,
|
|
||||||
});
|
|
||||||
if (handler.oneOff) {
|
|
||||||
EventHandler.off(element, event.type, fn);
|
|
||||||
}
|
|
||||||
return fn.apply(element, [event]);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function bootstrapDelegationHandler(element, selector, fn) {
|
|
||||||
return function handler(event) {
|
|
||||||
const domElements = element.querySelectorAll(selector);
|
|
||||||
for (let { target } = event; target && target !== this; target = target.parentNode) {
|
|
||||||
for (const domElement of domElements) {
|
|
||||||
if (domElement !== target) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
hydrateObj(event, {
|
|
||||||
delegateTarget: target,
|
|
||||||
});
|
|
||||||
if (handler.oneOff) {
|
|
||||||
EventHandler.off(element, event.type, selector, fn);
|
|
||||||
}
|
|
||||||
return fn.apply(target, [event]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function findHandler(events, callable, delegationSelector = null) {
|
|
||||||
return Object.values(events).find(
|
|
||||||
(event) => event.callable === callable && event.delegationSelector === delegationSelector
|
|
||||||
);
|
|
||||||
}
|
|
||||||
function normalizeParameters(originalTypeEvent, handler, delegationFunction) {
|
|
||||||
const isDelegated = typeof handler === 'string';
|
|
||||||
// TODO: tooltip passes `false` instead of selector, so we need to check
|
|
||||||
const callable = isDelegated ? delegationFunction : handler || delegationFunction;
|
|
||||||
let typeEvent = getTypeEvent(originalTypeEvent);
|
|
||||||
if (!nativeEvents.has(typeEvent)) {
|
|
||||||
typeEvent = originalTypeEvent;
|
|
||||||
}
|
|
||||||
return [isDelegated, callable, typeEvent];
|
|
||||||
}
|
|
||||||
function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {
|
|
||||||
if (typeof originalTypeEvent !== 'string' || !element) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let [isDelegated, callable, typeEvent] = normalizeParameters(
|
|
||||||
originalTypeEvent,
|
|
||||||
handler,
|
|
||||||
delegationFunction
|
|
||||||
);
|
|
||||||
|
|
||||||
// in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
|
|
||||||
// this prevents the handler from being dispatched the same way as mouseover or mouseout does
|
|
||||||
if (originalTypeEvent in customEvents) {
|
|
||||||
const wrapFunction = (fn) => {
|
|
||||||
return function (event) {
|
|
||||||
if (
|
|
||||||
!event.relatedTarget ||
|
|
||||||
(event.relatedTarget !== event.delegateTarget &&
|
|
||||||
!event.delegateTarget.contains(event.relatedTarget))
|
|
||||||
) {
|
|
||||||
return fn.call(this, event);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
callable = wrapFunction(callable);
|
|
||||||
}
|
|
||||||
const events = getElementEvents(element);
|
|
||||||
const handlers = events[typeEvent] || (events[typeEvent] = {});
|
|
||||||
const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null);
|
|
||||||
if (previousFunction) {
|
|
||||||
previousFunction.oneOff = previousFunction.oneOff && oneOff;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''));
|
|
||||||
const fn = isDelegated
|
|
||||||
? bootstrapDelegationHandler(element, handler, callable)
|
|
||||||
: bootstrapHandler(element, callable);
|
|
||||||
fn.delegationSelector = isDelegated ? handler : null;
|
|
||||||
fn.callable = callable;
|
|
||||||
fn.oneOff = oneOff;
|
|
||||||
fn.uidEvent = uid;
|
|
||||||
handlers[uid] = fn;
|
|
||||||
element.addEventListener(typeEvent, fn, isDelegated);
|
|
||||||
}
|
|
||||||
function removeHandler(element, events, typeEvent, handler, delegationSelector) {
|
|
||||||
const fn = findHandler(events[typeEvent], handler, delegationSelector);
|
|
||||||
if (!fn) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));
|
|
||||||
delete events[typeEvent][fn.uidEvent];
|
|
||||||
}
|
|
||||||
function removeNamespacedHandlers(element, events, typeEvent, namespace) {
|
|
||||||
const storeElementEvent = events[typeEvent] || {};
|
|
||||||
for (const [handlerKey, event] of Object.entries(storeElementEvent)) {
|
|
||||||
if (handlerKey.includes(namespace)) {
|
|
||||||
removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function getTypeEvent(event) {
|
|
||||||
// allow to get the native events from namespaced events ('click.bs.button' --> 'click')
|
|
||||||
event = event.replace(stripNameRegex, '');
|
|
||||||
return customEvents[event] || event;
|
|
||||||
}
|
|
||||||
const EventHandler = {
|
|
||||||
on(element, event, handler, delegationFunction) {
|
|
||||||
addHandler(element, event, handler, delegationFunction, false);
|
|
||||||
},
|
|
||||||
one(element, event, handler, delegationFunction) {
|
|
||||||
addHandler(element, event, handler, delegationFunction, true);
|
|
||||||
},
|
|
||||||
off(element, originalTypeEvent, handler, delegationFunction) {
|
|
||||||
if (typeof originalTypeEvent !== 'string' || !element) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const [isDelegated, callable, typeEvent] = normalizeParameters(
|
|
||||||
originalTypeEvent,
|
|
||||||
handler,
|
|
||||||
delegationFunction
|
|
||||||
);
|
|
||||||
const inNamespace = typeEvent !== originalTypeEvent;
|
|
||||||
const events = getElementEvents(element);
|
|
||||||
const storeElementEvent = events[typeEvent] || {};
|
|
||||||
const isNamespace = originalTypeEvent.startsWith('.');
|
|
||||||
if (typeof callable !== 'undefined') {
|
|
||||||
// Simplest case: handler is passed, remove that listener ONLY.
|
|
||||||
if (!Object.keys(storeElementEvent).length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isNamespace) {
|
|
||||||
for (const elementEvent of Object.keys(events)) {
|
|
||||||
removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {
|
|
||||||
const handlerKey = keyHandlers.replace(stripUidRegex, '');
|
|
||||||
if (!inNamespace || originalTypeEvent.includes(handlerKey)) {
|
|
||||||
removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
trigger(element, event, args) {
|
|
||||||
if (typeof event !== 'string' || !element) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const $ = index_js.getjQuery();
|
|
||||||
const typeEvent = getTypeEvent(event);
|
|
||||||
const inNamespace = event !== typeEvent;
|
|
||||||
let jQueryEvent = null;
|
|
||||||
let bubbles = true;
|
|
||||||
let nativeDispatch = true;
|
|
||||||
let defaultPrevented = false;
|
|
||||||
if (inNamespace && $) {
|
|
||||||
jQueryEvent = $.Event(event, args);
|
|
||||||
$(element).trigger(jQueryEvent);
|
|
||||||
bubbles = !jQueryEvent.isPropagationStopped();
|
|
||||||
nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();
|
|
||||||
defaultPrevented = jQueryEvent.isDefaultPrevented();
|
|
||||||
}
|
|
||||||
const evt = hydrateObj(
|
|
||||||
new Event(event, {
|
|
||||||
bubbles,
|
|
||||||
cancelable: true,
|
|
||||||
}),
|
|
||||||
args
|
|
||||||
);
|
|
||||||
if (defaultPrevented) {
|
|
||||||
evt.preventDefault();
|
|
||||||
}
|
|
||||||
if (nativeDispatch) {
|
|
||||||
element.dispatchEvent(evt);
|
|
||||||
}
|
|
||||||
if (evt.defaultPrevented && jQueryEvent) {
|
|
||||||
jQueryEvent.preventDefault();
|
|
||||||
}
|
|
||||||
return evt;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
function hydrateObj(obj, meta = {}) {
|
|
||||||
for (const [key, value] of Object.entries(meta)) {
|
|
||||||
try {
|
|
||||||
obj[key] = value;
|
|
||||||
} catch (_unused) {
|
|
||||||
Object.defineProperty(obj, key, {
|
|
||||||
configurable: true,
|
|
||||||
get() {
|
|
||||||
return value;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EventHandler;
|
|
||||||
});
|
|
||||||
//# sourceMappingURL=event-handler.js.map
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,77 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap manipulator.js v5.3.2 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
*/
|
|
||||||
(function (global, factory) {
|
|
||||||
typeof exports === 'object' && typeof module !== 'undefined'
|
|
||||||
? (module.exports = factory())
|
|
||||||
: typeof define === 'function' && define.amd
|
|
||||||
? define(factory)
|
|
||||||
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
|
|
||||||
(global.Manipulator = factory()));
|
|
||||||
})(this, function () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap dom/manipulator.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
function normalizeData(value) {
|
|
||||||
if (value === 'true') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (value === 'false') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (value === Number(value).toString()) {
|
|
||||||
return Number(value);
|
|
||||||
}
|
|
||||||
if (value === '' || value === 'null') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (typeof value !== 'string') {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return JSON.parse(decodeURIComponent(value));
|
|
||||||
} catch (_unused) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function normalizeDataKey(key) {
|
|
||||||
return key.replace(/[A-Z]/g, (chr) => `-${chr.toLowerCase()}`);
|
|
||||||
}
|
|
||||||
const Manipulator = {
|
|
||||||
setDataAttribute(element, key, value) {
|
|
||||||
element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);
|
|
||||||
},
|
|
||||||
removeDataAttribute(element, key) {
|
|
||||||
element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);
|
|
||||||
},
|
|
||||||
getDataAttributes(element) {
|
|
||||||
if (!element) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
const attributes = {};
|
|
||||||
const bsKeys = Object.keys(element.dataset).filter(
|
|
||||||
(key) => key.startsWith('bs') && !key.startsWith('bsConfig')
|
|
||||||
);
|
|
||||||
for (const key of bsKeys) {
|
|
||||||
let pureKey = key.replace(/^bs/, '');
|
|
||||||
pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);
|
|
||||||
attributes[pureKey] = normalizeData(element.dataset[key]);
|
|
||||||
}
|
|
||||||
return attributes;
|
|
||||||
},
|
|
||||||
getDataAttribute(element, key) {
|
|
||||||
return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return Manipulator;
|
|
||||||
});
|
|
||||||
//# sourceMappingURL=manipulator.js.map
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"manipulator.js","sources":["../../src/dom/manipulator.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nfunction normalizeData(value) {\n if (value === 'true') {\n return true\n }\n\n if (value === 'false') {\n return false\n }\n\n if (value === Number(value).toString()) {\n return Number(value)\n }\n\n if (value === '' || value === 'null') {\n return null\n }\n\n if (typeof value !== 'string') {\n return value\n }\n\n try {\n return JSON.parse(decodeURIComponent(value))\n } catch {\n return value\n }\n}\n\nfunction normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`)\n}\n\nconst Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value)\n },\n\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`)\n },\n\n getDataAttributes(element) {\n if (!element) {\n return {}\n }\n\n const attributes = {}\n const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'))\n\n for (const key of bsKeys) {\n let pureKey = key.replace(/^bs/, '')\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length)\n attributes[pureKey] = normalizeData(element.dataset[key])\n }\n\n return attributes\n },\n\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`))\n }\n}\n\nexport default Manipulator\n"],"names":["normalizeData","value","Number","toString","JSON","parse","decodeURIComponent","_unused","normalizeDataKey","key","replace","chr","toLowerCase","Manipulator","setDataAttribute","element","setAttribute","removeDataAttribute","removeAttribute","getDataAttributes","attributes","bsKeys","Object","keys","dataset","filter","startsWith","pureKey","charAt","slice","length","getDataAttribute","getAttribute"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;EAEA,SAASA,aAAaA,CAACC,KAAK,EAAE;IAC5B,IAAIA,KAAK,KAAK,MAAM,EAAE;EACpB,IAAA,OAAO,IAAI,CAAA;EACb,GAAA;IAEA,IAAIA,KAAK,KAAK,OAAO,EAAE;EACrB,IAAA,OAAO,KAAK,CAAA;EACd,GAAA;IAEA,IAAIA,KAAK,KAAKC,MAAM,CAACD,KAAK,CAAC,CAACE,QAAQ,EAAE,EAAE;MACtC,OAAOD,MAAM,CAACD,KAAK,CAAC,CAAA;EACtB,GAAA;EAEA,EAAA,IAAIA,KAAK,KAAK,EAAE,IAAIA,KAAK,KAAK,MAAM,EAAE;EACpC,IAAA,OAAO,IAAI,CAAA;EACb,GAAA;EAEA,EAAA,IAAI,OAAOA,KAAK,KAAK,QAAQ,EAAE;EAC7B,IAAA,OAAOA,KAAK,CAAA;EACd,GAAA;IAEA,IAAI;MACF,OAAOG,IAAI,CAACC,KAAK,CAACC,kBAAkB,CAACL,KAAK,CAAC,CAAC,CAAA;KAC7C,CAAC,OAAAM,OAAA,EAAM;EACN,IAAA,OAAON,KAAK,CAAA;EACd,GAAA;EACF,CAAA;EAEA,SAASO,gBAAgBA,CAACC,GAAG,EAAE;EAC7B,EAAA,OAAOA,GAAG,CAACC,OAAO,CAAC,QAAQ,EAAEC,GAAG,IAAK,CAAA,CAAA,EAAGA,GAAG,CAACC,WAAW,EAAG,EAAC,CAAC,CAAA;EAC9D,CAAA;AAEA,QAAMC,WAAW,GAAG;EAClBC,EAAAA,gBAAgBA,CAACC,OAAO,EAAEN,GAAG,EAAER,KAAK,EAAE;MACpCc,OAAO,CAACC,YAAY,CAAE,CAAUR,QAAAA,EAAAA,gBAAgB,CAACC,GAAG,CAAE,CAAA,CAAC,EAAER,KAAK,CAAC,CAAA;KAChE;EAEDgB,EAAAA,mBAAmBA,CAACF,OAAO,EAAEN,GAAG,EAAE;MAChCM,OAAO,CAACG,eAAe,CAAE,CAAA,QAAA,EAAUV,gBAAgB,CAACC,GAAG,CAAE,CAAA,CAAC,CAAC,CAAA;KAC5D;IAEDU,iBAAiBA,CAACJ,OAAO,EAAE;MACzB,IAAI,CAACA,OAAO,EAAE;EACZ,MAAA,OAAO,EAAE,CAAA;EACX,KAAA;MAEA,MAAMK,UAAU,GAAG,EAAE,CAAA;EACrB,IAAA,MAAMC,MAAM,GAAGC,MAAM,CAACC,IAAI,CAACR,OAAO,CAACS,OAAO,CAAC,CAACC,MAAM,CAAChB,GAAG,IAAIA,GAAG,CAACiB,UAAU,CAAC,IAAI,CAAC,IAAI,CAACjB,GAAG,CAACiB,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;EAE9G,IAAA,KAAK,MAAMjB,GAAG,IAAIY,MAAM,EAAE;QACxB,IAAIM,OAAO,GAAGlB,GAAG,CAACC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;QACpCiB,OAAO,GAAGA,OAAO,CAACC,MAAM,CAAC,CAAC,CAAC,CAAChB,WAAW,EAAE,GAAGe,OAAO,CAACE,KAAK,CAAC,CAAC,EAAEF,OAAO,CAACG,MAAM,CAAC,CAAA;EAC5EV,MAAAA,UAAU,CAACO,OAAO,CAAC,GAAG3B,aAAa,CAACe,OAAO,CAACS,OAAO,CAACf,GAAG,CAAC,CAAC,CAAA;EAC3D,KAAA;EAEA,IAAA,OAAOW,UAAU,CAAA;KAClB;EAEDW,EAAAA,gBAAgBA,CAAChB,OAAO,EAAEN,GAAG,EAAE;EAC7B,IAAA,OAAOT,aAAa,CAACe,OAAO,CAACiB,YAAY,CAAE,CAAUxB,QAAAA,EAAAA,gBAAgB,CAACC,GAAG,CAAE,CAAA,CAAC,CAAC,CAAC,CAAA;EAChF,GAAA;EACF;;;;;;;;"}
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap selector-engine.js v5.3.2 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
*/
|
|
||||||
(function (global, factory) {
|
|
||||||
typeof exports === 'object' && typeof module !== 'undefined'
|
|
||||||
? (module.exports = factory(require('../util/index.js')))
|
|
||||||
: typeof define === 'function' && define.amd
|
|
||||||
? define(['../util/index'], factory)
|
|
||||||
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
|
|
||||||
(global.SelectorEngine = factory(global.Index)));
|
|
||||||
})(this, function (index_js) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
* Bootstrap dom/selector-engine.js
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
const getSelector = (element) => {
|
|
||||||
let selector = element.getAttribute('data-bs-target');
|
|
||||||
if (!selector || selector === '#') {
|
|
||||||
let hrefAttribute = element.getAttribute('href');
|
|
||||||
|
|
||||||
// The only valid content that could double as a selector are IDs or classes,
|
|
||||||
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
|
||||||
// `document.querySelector` will rightfully complain it is invalid.
|
|
||||||
// See https://github.com/twbs/bootstrap/issues/32273
|
|
||||||
if (!hrefAttribute || (!hrefAttribute.includes('#') && !hrefAttribute.startsWith('.'))) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just in case some CMS puts out a full URL with the anchor appended
|
|
||||||
if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {
|
|
||||||
hrefAttribute = `#${hrefAttribute.split('#')[1]}`;
|
|
||||||
}
|
|
||||||
selector =
|
|
||||||
hrefAttribute && hrefAttribute !== '#'
|
|
||||||
? index_js.parseSelector(hrefAttribute.trim())
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
return selector;
|
|
||||||
};
|
|
||||||
const SelectorEngine = {
|
|
||||||
find(selector, element = document.documentElement) {
|
|
||||||
return [].concat(...Element.prototype.querySelectorAll.call(element, selector));
|
|
||||||
},
|
|
||||||
findOne(selector, element = document.documentElement) {
|
|
||||||
return Element.prototype.querySelector.call(element, selector);
|
|
||||||
},
|
|
||||||
children(element, selector) {
|
|
||||||
return [].concat(...element.children).filter((child) => child.matches(selector));
|
|
||||||
},
|
|
||||||
parents(element, selector) {
|
|
||||||
const parents = [];
|
|
||||||
let ancestor = element.parentNode.closest(selector);
|
|
||||||
while (ancestor) {
|
|
||||||
parents.push(ancestor);
|
|
||||||
ancestor = ancestor.parentNode.closest(selector);
|
|
||||||
}
|
|
||||||
return parents;
|
|
||||||
},
|
|
||||||
prev(element, selector) {
|
|
||||||
let previous = element.previousElementSibling;
|
|
||||||
while (previous) {
|
|
||||||
if (previous.matches(selector)) {
|
|
||||||
return [previous];
|
|
||||||
}
|
|
||||||
previous = previous.previousElementSibling;
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
},
|
|
||||||
// TODO: this is now unused; remove later along with prev()
|
|
||||||
next(element, selector) {
|
|
||||||
let next = element.nextElementSibling;
|
|
||||||
while (next) {
|
|
||||||
if (next.matches(selector)) {
|
|
||||||
return [next];
|
|
||||||
}
|
|
||||||
next = next.nextElementSibling;
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
},
|
|
||||||
focusableChildren(element) {
|
|
||||||
const focusables = [
|
|
||||||
'a',
|
|
||||||
'button',
|
|
||||||
'input',
|
|
||||||
'textarea',
|
|
||||||
'select',
|
|
||||||
'details',
|
|
||||||
'[tabindex]',
|
|
||||||
'[contenteditable="true"]',
|
|
||||||
]
|
|
||||||
.map((selector) => `${selector}:not([tabindex^="-"])`)
|
|
||||||
.join(',');
|
|
||||||
return this.find(focusables, element).filter(
|
|
||||||
(el) => !index_js.isDisabled(el) && index_js.isVisible(el)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
getSelectorFromElement(element) {
|
|
||||||
const selector = getSelector(element);
|
|
||||||
if (selector) {
|
|
||||||
return SelectorEngine.findOne(selector) ? selector : null;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
getElementFromSelector(element) {
|
|
||||||
const selector = getSelector(element);
|
|
||||||
return selector ? SelectorEngine.findOne(selector) : null;
|
|
||||||
},
|
|
||||||
getMultipleElementsFromSelector(element) {
|
|
||||||
const selector = getSelector(element);
|
|
||||||
return selector ? SelectorEngine.find(selector) : [];
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return SelectorEngine;
|
|
||||||
});
|
|
||||||
//# sourceMappingURL=selector-engine.js.map
|
|
||||||
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user