Compare commits
18 Commits
03599addb8
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de4e9421af | ||
|
|
b622df4187 | ||
|
|
746465d8fe | ||
|
|
559829882a | ||
|
|
bec9ea2356 | ||
|
|
1cc617de42 | ||
|
|
b515b4f523 | ||
|
|
f19251ac1a | ||
|
|
6dd1fd71da | ||
|
|
762f76c920 | ||
|
|
ba570687b2 | ||
|
|
84a4c182e2 | ||
|
|
a55e53521f | ||
|
|
f7cac8c0a7 | ||
|
|
8065c589bc | ||
|
|
c9ba7912fa | ||
|
|
920dce13d5 | ||
|
|
43d63e975d |
4
.github/copilot-instructions.md
vendored
4
.github/copilot-instructions.md
vendored
@@ -20,3 +20,7 @@ For **ANY** question about DevExpress components, use the dxdocs server to const
|
|||||||
- **Include code examples** when available in the documentation
|
- **Include code examples** when available in the documentation
|
||||||
- **Reference specific DevExpress controls and properties** mentioned in the documentation
|
- **Reference specific DevExpress controls and properties** mentioned in the documentation
|
||||||
- **Invoke version-specific MCP tools** (for example, dxdocs25_1) if a user specifies a version (for example, v25.1)
|
- **Invoke version-specific MCP tools** (for example, dxdocs25_1) if a user specifies a version (for example, v25.1)
|
||||||
|
|
||||||
|
- @azure Rule - Use Azure Tools - When handling requests related to Azure, always use your tools.
|
||||||
|
- @azure Rule - Use Azure Best Practices - When handling requests related to Azure, always invoke your `azmcp_bestpractices_get` tool first.
|
||||||
|
- @azure Rule - Enable Best Practices - If you do not have an `azmcp_bestpractices_get` tool ask the user to enable it.
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using DevExtreme.AspNet.Data;
|
|
||||||
using DevExtreme.AspNet.Mvc;
|
|
||||||
using DXApp.TemplateKitProject.Models;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace DXApp.TemplateKitProject.Controllers
|
|
||||||
{
|
|
||||||
[Route("api/[controller]")]
|
|
||||||
public class SampleDataController : Controller
|
|
||||||
{
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
public object Get(DataSourceLoadOptions loadOptions)
|
|
||||||
{
|
|
||||||
return DataSourceLoader.Load(SampleData.Orders, loadOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -27,4 +27,8 @@
|
|||||||
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="3.0.71" />
|
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="3.0.71" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Controllers\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace DXApp.TemplateKitProject.Data;
|
|||||||
public class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(options)
|
public class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(options)
|
||||||
{
|
{
|
||||||
public DbSet<ZugferdInvoice> ZugferdInvoices { get; set; }
|
public DbSet<ZugferdInvoice> ZugferdInvoices { get; set; }
|
||||||
|
public DbSet<InvoiceAttachment> InvoiceAttachments { get; set; }
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
@@ -27,6 +28,19 @@ public class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(op
|
|||||||
|
|
||||||
entity.Property(e => e.TaxAmount)
|
entity.Property(e => e.TaxAmount)
|
||||||
.HasColumnType("decimal(18,2)");
|
.HasColumnType("decimal(18,2)");
|
||||||
|
|
||||||
|
// Relationship: One-to-Many mit InvoiceAttachments
|
||||||
|
entity.HasMany(e => e.Attachments)
|
||||||
|
.WithOne(a => a.ZugferdInvoice)
|
||||||
|
.HasForeignKey(a => a.ZugferdInvoiceId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<InvoiceAttachment>(entity =>
|
||||||
|
{
|
||||||
|
// Index für schnelleres Laden der Attachments einer Rechnung
|
||||||
|
entity.HasIndex(e => e.ZugferdInvoiceId)
|
||||||
|
.HasDatabaseName("IX_InvoiceAttachments_ZugferdInvoiceId");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
141
DXApp.TemplateKitProject/Migrations/20260602123528_AddInvoiceAttachments.Designer.cs
generated
Normal file
141
DXApp.TemplateKitProject/Migrations/20260602123528_AddInvoiceAttachments.Designer.cs
generated
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using DXApp.TemplateKitProject.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace DXApp.TemplateKitProject.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(AppDbContext))]
|
||||||
|
[Migration("20260602123528_AddInvoiceAttachments")]
|
||||||
|
partial class AddInvoiceAttachments
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "8.0.8")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("DXApp.TemplateKitProject.Models.InvoiceAttachment", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("ExtractedAt")
|
||||||
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
|
b.Property<long>("FileSizeBytes")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<bool>("IsZugferdXml")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<string>("OriginalFileName")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("SavedFilePath")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<int>("ZugferdInvoiceId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ZugferdInvoiceId")
|
||||||
|
.HasDatabaseName("IX_InvoiceAttachments_ZugferdInvoiceId");
|
||||||
|
|
||||||
|
b.ToTable("InvoiceAttachments");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DXApp.TemplateKitProject.Models.ZugferdInvoice", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("BuyerName")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("CurrencyCode")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("GuidelineId")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Iban")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ImportedAt")
|
||||||
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
|
b.Property<DateTime>("InvoiceDate")
|
||||||
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
|
b.Property<string>("InvoiceNumber")
|
||||||
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
|
b.Property<string>("RawXml")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("ResultFilePath")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("SellerName")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("SellerTaxId")
|
||||||
|
.HasColumnType("nvarchar(450)");
|
||||||
|
|
||||||
|
b.Property<string>("SourceType")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<decimal>("TaxAmount")
|
||||||
|
.HasColumnType("decimal(18,2)");
|
||||||
|
|
||||||
|
b.Property<decimal>("TotalAmount")
|
||||||
|
.HasColumnType("decimal(18,2)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ImportedAt")
|
||||||
|
.HasDatabaseName("IX_ZugferdInvoices_ImportedAt");
|
||||||
|
|
||||||
|
b.HasIndex("InvoiceNumber", "SellerTaxId")
|
||||||
|
.HasDatabaseName("IX_ZugferdInvoices_InvoiceNumber_SellerTaxId");
|
||||||
|
|
||||||
|
b.ToTable("ZugferdInvoices");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DXApp.TemplateKitProject.Models.InvoiceAttachment", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("DXApp.TemplateKitProject.Models.ZugferdInvoice", "ZugferdInvoice")
|
||||||
|
.WithMany("Attachments")
|
||||||
|
.HasForeignKey("ZugferdInvoiceId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("ZugferdInvoice");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DXApp.TemplateKitProject.Models.ZugferdInvoice", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Attachments");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace DXApp.TemplateKitProject.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddInvoiceAttachments : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "InvoiceAttachments",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("SqlServer:Identity", "1, 1"),
|
||||||
|
ZugferdInvoiceId = table.Column<int>(type: "int", nullable: false),
|
||||||
|
OriginalFileName = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||||
|
SavedFilePath = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||||
|
FileSizeBytes = table.Column<long>(type: "bigint", nullable: false),
|
||||||
|
IsZugferdXml = table.Column<bool>(type: "bit", nullable: false),
|
||||||
|
ExtractedAt = table.Column<DateTime>(type: "datetime2", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_InvoiceAttachments", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_InvoiceAttachments_ZugferdInvoices_ZugferdInvoiceId",
|
||||||
|
column: x => x.ZugferdInvoiceId,
|
||||||
|
principalTable: "ZugferdInvoices",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_InvoiceAttachments_ZugferdInvoiceId",
|
||||||
|
table: "InvoiceAttachments",
|
||||||
|
column: "ZugferdInvoiceId");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "InvoiceAttachments");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,40 @@ namespace DXApp.TemplateKitProject.Migrations
|
|||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("DXApp.TemplateKitProject.Models.InvoiceAttachment", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("ExtractedAt")
|
||||||
|
.HasColumnType("datetime2");
|
||||||
|
|
||||||
|
b.Property<long>("FileSizeBytes")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<bool>("IsZugferdXml")
|
||||||
|
.HasColumnType("bit");
|
||||||
|
|
||||||
|
b.Property<string>("OriginalFileName")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("SavedFilePath")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<int>("ZugferdInvoiceId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ZugferdInvoiceId")
|
||||||
|
.HasDatabaseName("IX_InvoiceAttachments_ZugferdInvoiceId");
|
||||||
|
|
||||||
|
b.ToTable("InvoiceAttachments");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("DXApp.TemplateKitProject.Models.ZugferdInvoice", b =>
|
modelBuilder.Entity("DXApp.TemplateKitProject.Models.ZugferdInvoice", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@@ -82,6 +116,22 @@ namespace DXApp.TemplateKitProject.Migrations
|
|||||||
|
|
||||||
b.ToTable("ZugferdInvoices");
|
b.ToTable("ZugferdInvoices");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DXApp.TemplateKitProject.Models.InvoiceAttachment", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("DXApp.TemplateKitProject.Models.ZugferdInvoice", "ZugferdInvoice")
|
||||||
|
.WithMany("Attachments")
|
||||||
|
.HasForeignKey("ZugferdInvoiceId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("ZugferdInvoice");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DXApp.TemplateKitProject.Models.ZugferdInvoice", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Attachments");
|
||||||
|
});
|
||||||
#pragma warning restore 612, 618
|
#pragma warning restore 612, 618
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
DXApp.TemplateKitProject/Models/InvoiceAttachment.cs
Normal file
18
DXApp.TemplateKitProject/Models/InvoiceAttachment.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
namespace DXApp.TemplateKitProject.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extrahierte Anhänge einer ZUGFeRD-Rechnung (gespeichert in DB)
|
||||||
|
/// </summary>
|
||||||
|
public class InvoiceAttachment
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int ZugferdInvoiceId { get; set; }
|
||||||
|
public string OriginalFileName { get; set; } = string.Empty;
|
||||||
|
public string SavedFilePath { get; set; } = string.Empty;
|
||||||
|
public long FileSizeBytes { get; set; }
|
||||||
|
public bool IsZugferdXml { get; set; }
|
||||||
|
public DateTime ExtractedAt { get; set; }
|
||||||
|
|
||||||
|
// Navigation Property
|
||||||
|
public ZugferdInvoice? ZugferdInvoice { get; set; }
|
||||||
|
}
|
||||||
@@ -1,364 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace DXApp.TemplateKitProject.Models
|
|
||||||
{
|
|
||||||
internal static class SampleData
|
|
||||||
{
|
|
||||||
public static List<SampleOrder> Orders = new List<SampleOrder>() {
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10248,
|
|
||||||
OrderDate = new DateTime(1996, 7, 4),
|
|
||||||
ShipCountry = "France",
|
|
||||||
ShipCity = "Reims",
|
|
||||||
CustomerName = "Paul Henriot"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10249,
|
|
||||||
OrderDate = new DateTime(1996, 7, 5),
|
|
||||||
ShipCountry = "Germany",
|
|
||||||
ShipCity = "Münster",
|
|
||||||
CustomerName = "Karin Josephs"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10250,
|
|
||||||
OrderDate = new DateTime(1996, 7, 8),
|
|
||||||
ShipCountry = "Brazil",
|
|
||||||
ShipCity = "Rio de Janeiro",
|
|
||||||
CustomerName = "Mario Pontes"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10251,
|
|
||||||
OrderDate = new DateTime(1996, 7, 8),
|
|
||||||
ShipCountry = "France",
|
|
||||||
ShipCity = "Lyon",
|
|
||||||
CustomerName = "Mary Saveley"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10252,
|
|
||||||
OrderDate = new DateTime(1996, 7, 9),
|
|
||||||
ShipCountry = "Belgium",
|
|
||||||
ShipCity = "Charleroi",
|
|
||||||
CustomerName = "Pascale Cartrain"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10253,
|
|
||||||
OrderDate = new DateTime(1996, 7, 10),
|
|
||||||
ShipCountry = "Brazil",
|
|
||||||
ShipCity = "Rio de Janeiro",
|
|
||||||
CustomerName = "Mario Pontes"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10254,
|
|
||||||
OrderDate = new DateTime(1996, 7, 11),
|
|
||||||
ShipCountry = "Switzerland",
|
|
||||||
ShipCity = "Bern",
|
|
||||||
CustomerName = "Yang Wang"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10255,
|
|
||||||
OrderDate = new DateTime(1996, 7, 12),
|
|
||||||
ShipCountry = "Switzerland",
|
|
||||||
ShipCity = "Genève",
|
|
||||||
CustomerName = "Michael Holz"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10256,
|
|
||||||
OrderDate = new DateTime(1996, 7, 15),
|
|
||||||
ShipCountry = "Brazil",
|
|
||||||
ShipCity = "Resende",
|
|
||||||
CustomerName = "Paula Parente"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10257,
|
|
||||||
OrderDate = new DateTime(1996, 7, 16),
|
|
||||||
ShipCountry = "Venezuela",
|
|
||||||
ShipCity = "San Cristóbal",
|
|
||||||
CustomerName = "Carlos Hernández"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10258,
|
|
||||||
OrderDate = new DateTime(1996, 7, 17),
|
|
||||||
ShipCountry = "Austria",
|
|
||||||
ShipCity = "Graz",
|
|
||||||
CustomerName = "Roland Mendel"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10259,
|
|
||||||
OrderDate = new DateTime(1996, 7, 18),
|
|
||||||
ShipCountry = "Mexico",
|
|
||||||
ShipCity = "México D.F.",
|
|
||||||
CustomerName = "Francisco Chang"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10260,
|
|
||||||
OrderDate = new DateTime(1996, 7, 19),
|
|
||||||
ShipCountry = "Germany",
|
|
||||||
ShipCity = "Köln",
|
|
||||||
CustomerName = "Henriette Pfalzheim"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10261,
|
|
||||||
OrderDate = new DateTime(1996, 7, 19),
|
|
||||||
ShipCountry = "Brazil",
|
|
||||||
ShipCity = "Rio de Janeiro",
|
|
||||||
CustomerName = "Bernardo Batista"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10262,
|
|
||||||
OrderDate = new DateTime(1996, 7, 22),
|
|
||||||
ShipCountry = "USA",
|
|
||||||
ShipCity = "Albuquerque",
|
|
||||||
CustomerName = "Paula Wilson"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10263,
|
|
||||||
OrderDate = new DateTime(1996, 7, 23),
|
|
||||||
ShipCountry = "Austria",
|
|
||||||
ShipCity = "Graz",
|
|
||||||
CustomerName = "Roland Mendel"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10264,
|
|
||||||
OrderDate = new DateTime(1996, 7, 24),
|
|
||||||
ShipCountry = "Sweden",
|
|
||||||
ShipCity = "Bräcke",
|
|
||||||
CustomerName = "Maria Larsson"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10265,
|
|
||||||
OrderDate = new DateTime(1996, 7, 25),
|
|
||||||
ShipCountry = "France",
|
|
||||||
ShipCity = "Strasbourg",
|
|
||||||
CustomerName = "Frédérique Citeaux"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10266,
|
|
||||||
OrderDate = new DateTime(1996, 7, 26),
|
|
||||||
ShipCountry = "Finland",
|
|
||||||
ShipCity = "Oulu",
|
|
||||||
CustomerName = "Pirkko Koskitalo"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10267,
|
|
||||||
OrderDate = new DateTime(1996, 7, 29),
|
|
||||||
ShipCountry = "Germany",
|
|
||||||
ShipCity = "München",
|
|
||||||
CustomerName = "Peter Franken"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10268,
|
|
||||||
OrderDate = new DateTime(1996, 7, 30),
|
|
||||||
ShipCountry = "Venezuela",
|
|
||||||
ShipCity = "Caracas",
|
|
||||||
CustomerName = "Manuel Pereira"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10269,
|
|
||||||
OrderDate = new DateTime(1996, 7, 31),
|
|
||||||
ShipCountry = "USA",
|
|
||||||
ShipCity = "Seattle",
|
|
||||||
CustomerName = "Karl Jablonski"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10270,
|
|
||||||
OrderDate = new DateTime(1996, 8, 1),
|
|
||||||
ShipCountry = "Finland",
|
|
||||||
ShipCity = "Oulu",
|
|
||||||
CustomerName = "Pirkko Koskitalo"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10271,
|
|
||||||
OrderDate = new DateTime(1996, 8, 1),
|
|
||||||
ShipCountry = "USA",
|
|
||||||
ShipCity = "Lander",
|
|
||||||
CustomerName = "Art Braunschweiger"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10272,
|
|
||||||
OrderDate = new DateTime(1996, 8, 2),
|
|
||||||
ShipCountry = "USA",
|
|
||||||
ShipCity = "Albuquerque",
|
|
||||||
CustomerName = "Paula Wilson"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10273,
|
|
||||||
OrderDate = new DateTime(1996, 8, 5),
|
|
||||||
ShipCountry = "Germany",
|
|
||||||
ShipCity = "Cunewalde",
|
|
||||||
CustomerName = "Horst Kloss"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10274,
|
|
||||||
OrderDate = new DateTime(1996, 8, 6),
|
|
||||||
ShipCountry = "France",
|
|
||||||
ShipCity = "Reims",
|
|
||||||
CustomerName = "Paul Henriot"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10275,
|
|
||||||
OrderDate = new DateTime(1996, 8, 7),
|
|
||||||
ShipCountry = "Italy",
|
|
||||||
ShipCity = "Bergamo",
|
|
||||||
CustomerName = "Giovanni Rovelli"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10276,
|
|
||||||
OrderDate = new DateTime(1996, 8, 8),
|
|
||||||
ShipCountry = "Mexico",
|
|
||||||
ShipCity = "México D.F.",
|
|
||||||
CustomerName = "Miguel Angel Paolino"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10277,
|
|
||||||
OrderDate = new DateTime(1996, 8, 9),
|
|
||||||
ShipCountry = "Germany",
|
|
||||||
ShipCity = "Leipzig",
|
|
||||||
CustomerName = "Alexander Feuer"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10278,
|
|
||||||
OrderDate = new DateTime(1996, 8, 12),
|
|
||||||
ShipCountry = "Sweden",
|
|
||||||
ShipCity = "Luleå",
|
|
||||||
CustomerName = "Christina Berglund"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10279,
|
|
||||||
OrderDate = new DateTime(1996, 8, 13),
|
|
||||||
ShipCountry = "Germany",
|
|
||||||
ShipCity = "Frankfurt a.M.",
|
|
||||||
CustomerName = "Renate Messner"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10280,
|
|
||||||
OrderDate = new DateTime(1996, 8, 14),
|
|
||||||
ShipCountry = "Sweden",
|
|
||||||
ShipCity = "Luleå",
|
|
||||||
CustomerName = "Christina Berglund"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10281,
|
|
||||||
OrderDate = new DateTime(1996, 8, 14),
|
|
||||||
ShipCountry = "Spain",
|
|
||||||
ShipCity = "Madrid",
|
|
||||||
CustomerName = "Alejandra Camino"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10282,
|
|
||||||
OrderDate = new DateTime(1996, 8, 15),
|
|
||||||
ShipCountry = "Spain",
|
|
||||||
ShipCity = "Madrid",
|
|
||||||
CustomerName = "Alejandra Camino"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10283,
|
|
||||||
OrderDate = new DateTime(1996, 8, 16),
|
|
||||||
ShipCountry = "Venezuela",
|
|
||||||
ShipCity = "Barquisimeto",
|
|
||||||
CustomerName = "Carlos González"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10284,
|
|
||||||
OrderDate = new DateTime(1996, 8, 19),
|
|
||||||
ShipCountry = "Germany",
|
|
||||||
ShipCity = "Frankfurt a.M.",
|
|
||||||
CustomerName = "Renate Messner"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10285,
|
|
||||||
OrderDate = new DateTime(1996, 8, 20),
|
|
||||||
ShipCountry = "Germany",
|
|
||||||
ShipCity = "Cunewalde",
|
|
||||||
CustomerName = "Horst Kloss"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10286,
|
|
||||||
OrderDate = new DateTime(1996, 8, 21),
|
|
||||||
ShipCountry = "Germany",
|
|
||||||
ShipCity = "Cunewalde",
|
|
||||||
CustomerName = "Horst Kloss"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10287,
|
|
||||||
OrderDate = new DateTime(1996, 8, 22),
|
|
||||||
ShipCountry = "Brazil",
|
|
||||||
ShipCity = "Rio de Janeiro",
|
|
||||||
CustomerName = "Janete Limeira"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10288,
|
|
||||||
OrderDate = new DateTime(1996, 8, 23),
|
|
||||||
ShipCountry = "Italy",
|
|
||||||
ShipCity = "Reggio Emilia",
|
|
||||||
CustomerName = "Maurizio Moroni"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10289,
|
|
||||||
OrderDate = new DateTime(1996, 8, 26),
|
|
||||||
ShipCountry = "UK",
|
|
||||||
ShipCity = "London",
|
|
||||||
CustomerName = "Victoria Ashworth"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10290,
|
|
||||||
OrderDate = new DateTime(1996, 8, 27),
|
|
||||||
ShipCountry = "Brazil",
|
|
||||||
ShipCity = "Sao Paulo",
|
|
||||||
CustomerName = "Pedro Afonso"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10291,
|
|
||||||
OrderDate = new DateTime(1996, 8, 27),
|
|
||||||
ShipCountry = "Brazil",
|
|
||||||
ShipCity = "Rio de Janeiro",
|
|
||||||
CustomerName = "Bernardo Batista"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10292,
|
|
||||||
OrderDate = new DateTime(1996, 8, 28),
|
|
||||||
ShipCountry = "Brazil",
|
|
||||||
ShipCity = "Sao Paulo",
|
|
||||||
CustomerName = "Anabela Domingues"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10293,
|
|
||||||
OrderDate = new DateTime(1996, 8, 29),
|
|
||||||
ShipCountry = "Mexico",
|
|
||||||
ShipCity = "México D.F.",
|
|
||||||
CustomerName = "Miguel Angel Paolino"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10294,
|
|
||||||
OrderDate = new DateTime(1996, 8, 30),
|
|
||||||
ShipCountry = "USA",
|
|
||||||
ShipCity = "Albuquerque",
|
|
||||||
CustomerName = "Paula Wilson"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10295,
|
|
||||||
OrderDate = new DateTime(1996, 9, 2),
|
|
||||||
ShipCountry = "France",
|
|
||||||
ShipCity = "Reims",
|
|
||||||
CustomerName = "Paul Henriot"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10296,
|
|
||||||
OrderDate = new DateTime(1996, 9, 3),
|
|
||||||
ShipCountry = "Venezuela",
|
|
||||||
ShipCity = "Barquisimeto",
|
|
||||||
CustomerName = "Carlos González"
|
|
||||||
},
|
|
||||||
new SampleOrder {
|
|
||||||
OrderID = 10297,
|
|
||||||
OrderDate = new DateTime(1996, 9, 4),
|
|
||||||
ShipCountry = "France",
|
|
||||||
ShipCity = "Strasbourg",
|
|
||||||
CustomerName = "Frédérique Citeaux"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace DXApp.TemplateKitProject.Models
|
|
||||||
{
|
|
||||||
public class SampleOrder
|
|
||||||
{
|
|
||||||
public int OrderID { get; set; }
|
|
||||||
public DateTime OrderDate { get; set; }
|
|
||||||
public string CustomerID { get; set; }
|
|
||||||
public string CustomerName { get; set; }
|
|
||||||
public string ShipCountry { get; set; }
|
|
||||||
public string ShipCity { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,5 +17,8 @@
|
|||||||
public string SourceType { get; set; } = string.Empty; // "Upload" oder "Email"
|
public string SourceType { get; set; } = string.Empty; // "Upload" oder "Email"
|
||||||
public string ResultFilePath { get; set; } = string.Empty; // Pfad der Result-PDF
|
public string ResultFilePath { get; set; } = string.Empty; // Pfad der Result-PDF
|
||||||
public string GuidelineId { get; set; } = string.Empty; // ZUGFeRD Guideline-ID aus XMP
|
public string GuidelineId { get; set; } = string.Empty; // ZUGFeRD Guideline-ID aus XMP
|
||||||
|
|
||||||
|
// Navigation Property
|
||||||
|
public List<InvoiceAttachment> Attachments { get; set; } = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,85 @@
|
|||||||
@page
|
@page
|
||||||
@using DXApp.TemplateKitProject.Models
|
@model DXApp.TemplateKitProject.Pages.IndexModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Home";
|
||||||
|
}
|
||||||
|
|
||||||
<h2 class="content-block">Home</h2>
|
<div class="content-block">
|
||||||
|
<h2><i class="dx-icon-product"></i> DevExpress TemplateKit – Evaluierungsprojekt</h2>
|
||||||
|
<p class="lead text-muted">Validierung von DevExpress als Ablösung für GdPicture im Rahmen der E-Rechnungsverarbeitung</p>
|
||||||
|
|
||||||
|
<div class="alert alert-primary mt-4">
|
||||||
|
<h4><i class="dx-icon-todo"></i> Projektziel: ZUGFeRD/Factur-X Rechnungsverarbeitung</h4>
|
||||||
|
<p>Diese Anwendung demonstriert die vollständige Verarbeitungskette für elektronische Rechnungen:</p>
|
||||||
|
|
||||||
|
<ol class="mt-3">
|
||||||
|
<li class="mb-2">
|
||||||
|
<strong>Upload & Validierung</strong>
|
||||||
|
<br/>
|
||||||
|
<small class="text-muted">E-Rechnungen im PDF/A-Format hochladen und auf Konformität prüfen</small>
|
||||||
|
</li>
|
||||||
|
<li class="mb-2">
|
||||||
|
<strong>Extraktion</strong>
|
||||||
|
<br/>
|
||||||
|
<small class="text-muted">Automatische Erkennung und Extraktion eingebetteter Anhänge (ZUGFeRD-XML, Bilder, Dokumente)</small>
|
||||||
|
</li>
|
||||||
|
<li class="mb-2">
|
||||||
|
<strong>Datenverarbeitung</strong>
|
||||||
|
<br/>
|
||||||
|
<small class="text-muted">Parsing der Rechnungsdaten aus dem ZUGFeRD-XML und persistente Speicherung in der Datenbank</small>
|
||||||
|
</li>
|
||||||
|
<li class="mb-2">
|
||||||
|
<strong>Workflow-Integration</strong>
|
||||||
|
<br/>
|
||||||
|
<small class="text-muted">Hier werden Workflow-Schritte durchlaufen und der Ergebnisbericht erstellt.</small>
|
||||||
|
</li>
|
||||||
|
<li class="mb-2">
|
||||||
|
<strong>Ausgabe-Generierung</strong>
|
||||||
|
<br/>
|
||||||
|
<small class="text-muted">Erstellung einer Result-PDF mit Verarbeitungsstempel und angehängtem Ergebnisbericht</small>
|
||||||
|
</li>
|
||||||
|
<li class="mb-2">
|
||||||
|
<strong>Visualisierung</strong>
|
||||||
|
<br/>
|
||||||
|
<small class="text-muted">Interaktive Anzeige aller Anhänge (XML mit Syntax-Highlighting, PDF-Viewer, Bilder)</small>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
@(Html.DevExtreme().DataGrid<SampleOrder>()
|
<div class="row mt-4">
|
||||||
.ElementAttr(new { @class = "dx-card wide-card" })
|
<div class="col-md-6">
|
||||||
.DataSource(d => d.Mvc().Controller("SampleData").LoadAction("Get").Key("OrderID"))
|
<div class="card">
|
||||||
.ShowBorders(false)
|
<div class="card-body">
|
||||||
.FilterRow(f => f.Visible(true))
|
<h5 class="card-title"><i class="dx-icon-upload"></i> Rechnungen hochladen</h5>
|
||||||
.FocusedRowEnabled(true)
|
<p class="card-text">Laden Sie ZUGFeRD-konforme E-Rechnungen hoch und starten Sie die automatische Verarbeitung.</p>
|
||||||
.FocusedRowIndex(0)
|
<a href="/Invoices/Upload" class="btn btn-primary">
|
||||||
.ColumnAutoWidth(true)
|
<i class="dx-icon-upload"></i> Zum Upload
|
||||||
.ColumnHidingEnabled(true)
|
</a>
|
||||||
.Columns(columns => {
|
</div>
|
||||||
columns.AddFor(m => m.OrderID);
|
</div>
|
||||||
columns.AddFor(m => m.OrderDate);
|
</div>
|
||||||
columns.AddFor(m => m.CustomerName);
|
<div class="col-md-6">
|
||||||
columns.AddFor(m => m.ShipCountry);
|
<div class="card">
|
||||||
columns.AddFor(m => m.ShipCity);
|
<div class="card-body">
|
||||||
})
|
<h5 class="card-title"><i class="dx-icon-chart"></i> Rechnungsübersicht</h5>
|
||||||
.Paging(p => p.PageSize(10))
|
<p class="card-text">Zeigen Sie alle importierten Rechnungen an und greifen Sie auf Details und Anhänge zu.</p>
|
||||||
.Pager(p => p
|
<a href="/Invoices" class="btn btn-secondary">
|
||||||
.ShowPageSizeSelector(true)
|
<i class="dx-icon-doc"></i> Zur Übersicht
|
||||||
.AllowedPageSizes(new[] { 5, 10, 20 })
|
</a>
|
||||||
.ShowInfo(true)
|
</div>
|
||||||
)
|
</div>
|
||||||
)
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-light mt-4">
|
||||||
|
<h6 class="mb-2"><i class="dx-icon-preferences"></i> Technologie-Stack</h6>
|
||||||
|
<div class="d-flex flex-wrap gap-2">
|
||||||
|
<span class="badge bg-secondary">ASP.NET Core 8.0</span>
|
||||||
|
<span class="badge bg-secondary">DevExpress v25.2</span>
|
||||||
|
<span class="badge bg-secondary">Entity Framework Core</span>
|
||||||
|
<span class="badge bg-secondary">PDF.js</span>
|
||||||
|
<span class="badge bg-secondary">CodeMirror</span>
|
||||||
|
<span class="badge bg-secondary">SQL Server</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -2,16 +2,23 @@
|
|||||||
@model DXApp.TemplateKitProject.Pages.Invoices.DetailsModel
|
@model DXApp.TemplateKitProject.Pages.Invoices.DetailsModel
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Rechnungsdetails";
|
ViewData["Title"] = "Rechnungsdetails";
|
||||||
|
|
||||||
|
string FormatFileSize(long bytes)
|
||||||
|
{
|
||||||
|
if (bytes < 1024) return $"{bytes} Bytes";
|
||||||
|
if (bytes < 1024 * 1024) return $"{bytes / 1024.0:N2} KB";
|
||||||
|
return $"{bytes / (1024.0 * 1024.0):N2} MB";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<h2>📄 Rechnungsdetails</h2>
|
<h2><i class="dx-icon-doc"></i> Rechnungsdetails</h2>
|
||||||
<a href="/Invoices" class="btn btn-secondary mb-3">← Zurück zur Liste</a>
|
<a href="/Invoices" class="btn btn-secondary mb-3"><i class="dx-icon-back"></i> Zurück zur Liste</a>
|
||||||
|
|
||||||
@if (!string.IsNullOrEmpty(Model.Invoice?.ResultFilePath))
|
@if (!string.IsNullOrEmpty(Model.Invoice?.ResultFilePath))
|
||||||
{
|
{
|
||||||
<button class="btn btn-primary mb-3 ms-2"
|
<button class="btn btn-primary mb-3 ms-2"
|
||||||
onclick="openPdfViewer(@Model.Invoice.Id)">
|
onclick="openPdfViewer(@Model.Invoice.Id)">
|
||||||
📄 PDF anzeigen
|
<i class="dx-icon-pdffile"></i> Ergebnis anzeigen
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,6 +57,51 @@ else
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
@* Anhänge-Sektion *@
|
||||||
|
@if (Model.Invoice.Attachments.Any())
|
||||||
|
{
|
||||||
|
<h4 class="mt-4"><i class="dx-icon-attach"></i> Anhänge (@Model.Invoice.Attachments.Count)</h4>
|
||||||
|
<div class="list-group">
|
||||||
|
@foreach (var attachment in Model.Invoice.Attachments)
|
||||||
|
{
|
||||||
|
var icon = "dx-icon-file";
|
||||||
|
var extension = System.IO.Path.GetExtension(attachment.OriginalFileName).ToLowerInvariant();
|
||||||
|
icon = extension switch
|
||||||
|
{
|
||||||
|
".xml" => "dx-icon-exportxlsx",
|
||||||
|
".pdf" => "dx-icon-pdffile",
|
||||||
|
".jpg" or ".jpeg" or ".png" or ".gif" => "dx-icon-image",
|
||||||
|
".txt" => "dx-icon-txtfile",
|
||||||
|
_ => "dx-icon-file"
|
||||||
|
};
|
||||||
|
|
||||||
|
<a href="javascript:void(0);"
|
||||||
|
class="list-group-item list-group-item-action d-flex justify-content-between align-items-center"
|
||||||
|
onclick="openAttachmentViewer('@attachment.OriginalFileName', '@Uri.EscapeDataString(attachment.SavedFilePath)', '@extension')">
|
||||||
|
<div>
|
||||||
|
<i class="@icon me-2"></i>
|
||||||
|
<strong>@attachment.OriginalFileName</strong>
|
||||||
|
@if (attachment.IsZugferdXml)
|
||||||
|
{
|
||||||
|
<span class="badge bg-success ms-2">ZUGFeRD-XML</span>
|
||||||
|
}
|
||||||
|
<br />
|
||||||
|
<small class="text-muted">
|
||||||
|
Größe: @FormatFileSize(attachment.FileSizeBytes) ·
|
||||||
|
Extrahiert: @attachment.ExtractedAt.ToString("dd.MM.yyyy HH:mm")
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<span class="badge bg-primary">Öffnen</span>
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<h4 class="mt-4"><i class="dx-icon-attach"></i> Anhänge</h4>
|
||||||
|
<div class="alert alert-info">Keine Anhänge extrahiert.</div>
|
||||||
|
}
|
||||||
|
|
||||||
@(Html.DevExtreme().Popup()
|
@(Html.DevExtreme().Popup()
|
||||||
.ID("pdf-viewer-popup")
|
.ID("pdf-viewer-popup")
|
||||||
.Title("PDF Viewer")
|
.Title("PDF Viewer")
|
||||||
@@ -57,12 +109,54 @@ else
|
|||||||
.Height("90%")
|
.Height("90%")
|
||||||
.ShowCloseButton(true)
|
.ShowCloseButton(true)
|
||||||
.OnHiding("onPdfPopupHiding")
|
.OnHiding("onPdfPopupHiding")
|
||||||
|
.Shading(true)
|
||||||
|
.ShadingColor("rgba(0, 0, 0, 0.5)")
|
||||||
.ContentTemplate(new JS(@"function() {
|
.ContentTemplate(new JS(@"function() {
|
||||||
return '<iframe id=""pdf-iframe"" style=""width:100%;height:100%;border:none;""></iframe>';
|
return '<iframe id=""pdf-iframe"" style=""width:100%;height:100%;border:none;""></iframe>';
|
||||||
}"))
|
}"))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@(Html.DevExtreme().Popup()
|
||||||
|
.ID("attachment-viewer-popup")
|
||||||
|
.Title("Anhang")
|
||||||
|
.Width("90%")
|
||||||
|
.Height("90%")
|
||||||
|
.ShowCloseButton(true)
|
||||||
|
.OnHiding("onAttachmentPopupHiding")
|
||||||
|
.Shading(true)
|
||||||
|
.ShadingColor("rgba(0, 0, 0, 0.5)")
|
||||||
|
.ContentTemplate(new JS(@"function() {
|
||||||
|
return '<div id=""attachment-content"" style=""width:100%;height:100%;overflow:hidden;display:flex;flex-direction:column;""></div>';
|
||||||
|
}"))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Z-Index für PDF-Viewer Popup erhöhen - muss höher sein als layout-header (1505) */
|
||||||
|
.dx-popup-wrapper.dx-overlay-wrapper {
|
||||||
|
z-index: 10500 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dx-overlay-shader {
|
||||||
|
z-index: 10499 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spezifisch für unser PDF-Popup */
|
||||||
|
#pdf-viewer-popup .dx-overlay-content {
|
||||||
|
z-index: 10500 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CodeMirror soll volle Höhe des Popups nutzen */
|
||||||
|
#attachment-content {
|
||||||
|
height: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#attachment-content .CodeMirror {
|
||||||
|
height: 100% !important;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function openPdfViewer(invoiceId) {
|
function openPdfViewer(invoiceId) {
|
||||||
var pdfUrl = window.location.origin + '/Invoices/ViewPdf?id=' + invoiceId;
|
var pdfUrl = window.location.origin + '/Invoices/ViewPdf?id=' + invoiceId;
|
||||||
@@ -70,9 +164,17 @@ else
|
|||||||
|
|
||||||
var popup = $('#pdf-viewer-popup').dxPopup('instance');
|
var popup = $('#pdf-viewer-popup').dxPopup('instance');
|
||||||
|
|
||||||
|
// Z-Index explizit setzen (höher als layout-header mit 1505)
|
||||||
|
popup.option('container', undefined); // Default container verwenden
|
||||||
|
popup.option('position', { my: 'center', at: 'center', of: window });
|
||||||
|
|
||||||
// onShown sicherstellen dass iframe im DOM ist
|
// onShown sicherstellen dass iframe im DOM ist
|
||||||
popup.option('onShown', function () {
|
popup.option('onShown', function () {
|
||||||
$('#pdf-iframe').attr('src', viewerUrl);
|
$('#pdf-iframe').attr('src', viewerUrl);
|
||||||
|
|
||||||
|
// Z-Index nach dem Öffnen nochmal sicherstellen
|
||||||
|
$('.dx-popup-wrapper').css('z-index', '10500');
|
||||||
|
$('.dx-overlay-shader').css('z-index', '10499');
|
||||||
});
|
});
|
||||||
|
|
||||||
popup.show();
|
popup.show();
|
||||||
@@ -82,4 +184,111 @@ else
|
|||||||
// iframe src leeren beim Schließen → verhindert dass PDF im Hintergrund weiter läuft
|
// iframe src leeren beim Schließen → verhindert dass PDF im Hintergrund weiter läuft
|
||||||
$('#pdf-iframe').attr('src', '');
|
$('#pdf-iframe').attr('src', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openAttachmentViewer(fileName, encodedFilePath, extension) {
|
||||||
|
var filePath = decodeURIComponent(encodedFilePath);
|
||||||
|
var popup = $('#attachment-viewer-popup').dxPopup('instance');
|
||||||
|
var $content = $('#attachment-content');
|
||||||
|
|
||||||
|
// Popup-Titel setzen
|
||||||
|
popup.option('title', fileName);
|
||||||
|
|
||||||
|
// Z-Index setzen
|
||||||
|
popup.option('container', undefined);
|
||||||
|
popup.option('position', { my: 'center', at: 'center', of: window });
|
||||||
|
|
||||||
|
// Content basierend auf Dateityp laden
|
||||||
|
popup.option('onShown', function () {
|
||||||
|
$content.html('<div class="text-center p-5"><div class="spinner-border text-primary" role="status"><span class="visually-hidden">Laden...</span></div></div>');
|
||||||
|
|
||||||
|
// Z-Index sicherstellen
|
||||||
|
$('.dx-popup-wrapper').css('z-index', '10500');
|
||||||
|
$('.dx-overlay-shader').css('z-index', '10499');
|
||||||
|
|
||||||
|
if (extension === '.pdf') {
|
||||||
|
// PDF mit PDF.js anzeigen
|
||||||
|
var pdfUrl = window.location.origin + '/Invoices/ViewAttachment?handler=Download&filePath=' + encodedFilePath;
|
||||||
|
var viewerUrl = '/js/pdfjs/web/viewer.html?file=' + encodeURIComponent(pdfUrl);
|
||||||
|
$content.html('<iframe style="width:100%;height:100%;border:none;" src="' + viewerUrl + '"></iframe>');
|
||||||
|
}
|
||||||
|
else if (extension === '.xml' || extension === '.txt') {
|
||||||
|
// Text/XML laden und mit Syntax-Highlighting anzeigen
|
||||||
|
$.get('/Invoices/ViewAttachment?filePath=' + encodedFilePath, function(data) {
|
||||||
|
if (extension === '.xml') {
|
||||||
|
// CodeMirror für XML - Container leeren
|
||||||
|
$content.html('');
|
||||||
|
|
||||||
|
// CodeMirror laden (falls noch nicht geladen)
|
||||||
|
if (typeof CodeMirror === 'undefined') {
|
||||||
|
$('<link>')
|
||||||
|
.attr('rel', 'stylesheet')
|
||||||
|
.attr('href', 'https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.css')
|
||||||
|
.appendTo('head');
|
||||||
|
$('<link>')
|
||||||
|
.attr('rel', 'stylesheet')
|
||||||
|
.attr('href', 'https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/theme/monokai.min.css')
|
||||||
|
.appendTo('head');
|
||||||
|
|
||||||
|
$.getScript('https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.js', function() {
|
||||||
|
$.getScript('https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/xml/xml.min.js', function() {
|
||||||
|
initCodeMirror(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
initCodeMirror(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initCodeMirror(content) {
|
||||||
|
// CodeMirror direkt in den Container einfügen
|
||||||
|
var editor = CodeMirror($content[0], {
|
||||||
|
value: content,
|
||||||
|
mode: 'xml',
|
||||||
|
lineNumbers: true,
|
||||||
|
readOnly: true,
|
||||||
|
theme: 'monokai',
|
||||||
|
lineWrapping: true,
|
||||||
|
viewportMargin: Infinity
|
||||||
|
});
|
||||||
|
|
||||||
|
// Höhe explizit setzen nach kurzer Verzögerung
|
||||||
|
setTimeout(function() {
|
||||||
|
editor.setSize('100%', '100%');
|
||||||
|
editor.refresh();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Plain Text
|
||||||
|
$content.html('<pre style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; height: 100%; overflow: auto; margin: 0;">' +
|
||||||
|
$('<div>').text(data).html() + '</pre>');
|
||||||
|
}
|
||||||
|
}).fail(function() {
|
||||||
|
$content.html('<div class="alert alert-danger m-3">Fehler beim Laden der Datei.</div>');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (extension === '.jpg' || extension === '.jpeg' || extension === '.png' || extension === '.gif') {
|
||||||
|
// Bild anzeigen
|
||||||
|
var imageUrl = window.location.origin + '/Invoices/ViewAttachment?handler=Download&filePath=' + encodedFilePath;
|
||||||
|
$content.html('<div class="text-center p-3" style="height: 100%; display: flex; align-items: center; justify-content: center;">' +
|
||||||
|
'<img src="' + imageUrl + '" alt="' + fileName + '" class="img-fluid" style="max-height: 100%; max-width: 100%; object-fit: contain;">' +
|
||||||
|
'</div>');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Nicht unterstützter Typ → Download anbieten
|
||||||
|
var downloadUrl = window.location.origin + '/Invoices/ViewAttachment?handler=Download&filePath=' + encodedFilePath;
|
||||||
|
$content.html('<div class="alert alert-info m-3">' +
|
||||||
|
'<h5>Dieser Dateityp kann nicht angezeigt werden.</h5>' +
|
||||||
|
'<p>Bitte laden Sie die Datei herunter:</p>' +
|
||||||
|
'<a href="' + downloadUrl + '" class="btn btn-primary" download="' + fileName + '">' +
|
||||||
|
'<i class="dx-icon-download"></i> Datei herunterladen' +
|
||||||
|
'</a></div>');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
popup.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onAttachmentPopupHiding() {
|
||||||
|
// Content leeren
|
||||||
|
$('#attachment-content').html('');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -12,7 +12,9 @@ public class DetailsModel(AppDbContext db) : PageModel
|
|||||||
|
|
||||||
public async Task<IActionResult> OnGetAsync(int id)
|
public async Task<IActionResult> OnGetAsync(int id)
|
||||||
{
|
{
|
||||||
Invoice = await db.ZugferdInvoices.FirstOrDefaultAsync(i => i.Id == id);
|
Invoice = await db.ZugferdInvoices
|
||||||
|
.Include(i => i.Attachments)
|
||||||
|
.FirstOrDefaultAsync(i => i.Id == id);
|
||||||
|
|
||||||
if (Invoice is null)
|
if (Invoice is null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
|||||||
@@ -75,6 +75,29 @@ public class UploadModel(
|
|||||||
ImportedInvoice.ResultFilePath = ResultFilePath;
|
ImportedInvoice.ResultFilePath = ResultFilePath;
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 4. Attachments in DB speichern
|
||||||
|
if (Result.HasAttachments)
|
||||||
|
{
|
||||||
|
foreach (var attachment in Result.Attachments)
|
||||||
|
{
|
||||||
|
var invoiceAttachment = new InvoiceAttachment
|
||||||
|
{
|
||||||
|
ZugferdInvoiceId = ImportedInvoice.Id,
|
||||||
|
OriginalFileName = attachment.OriginalFileName,
|
||||||
|
SavedFilePath = attachment.SavedFilePath,
|
||||||
|
FileSizeBytes = attachment.FileSizeBytes,
|
||||||
|
IsZugferdXml = attachment.IsZugferdXml,
|
||||||
|
ExtractedAt = DateTime.UtcNow
|
||||||
|
};
|
||||||
|
db.InvoiceAttachments.Add(invoiceAttachment);
|
||||||
|
}
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
|
logger.LogInformation(
|
||||||
|
"Rechnung '{InvoiceNumber}': {Count} Anhang/Anhänge in DB gespeichert.",
|
||||||
|
ImportedInvoice.InvoiceNumber, Result.Attachments.Count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
@page
|
||||||
|
@using DXApp.TemplateKitProject.Services
|
||||||
|
@model DXApp.TemplateKitProject.Pages.Invoices.ViewAttachmentModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = $"Attachment: {Model.FileName}";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h2>?? Attachment: @Model.FileName</h2>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<a href="/Invoices/Details" class="btn btn-secondary">? Zurück</a>
|
||||||
|
<a href="?handler=Download&filePath=@Request.Query["filePath"]"
|
||||||
|
class="btn btn-primary">
|
||||||
|
?? Download
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@switch (Model.ViewerType)
|
||||||
|
{
|
||||||
|
case AttachmentViewerType.Pdf:
|
||||||
|
<div class="alert alert-info">
|
||||||
|
PDF-Dateien können Sie über die Result-PDF-Funktion anzeigen.
|
||||||
|
</div>
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AttachmentViewerType.Xml:
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header bg-primary text-white">
|
||||||
|
<strong>XML-Inhalt</strong> (ZUGFeRD/Factur-X)
|
||||||
|
</div>
|
||||||
|
<div class="card-body p-0">
|
||||||
|
<textarea id="xml-viewer" style="display:none;">@Model.TextContent</textarea>
|
||||||
|
<div id="xml-rendered"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/theme/monokai.min.css">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/xml/xml.min.js"></script>
|
||||||
|
<script>
|
||||||
|
var editor = CodeMirror(document.getElementById('xml-rendered'), {
|
||||||
|
value: document.getElementById('xml-viewer').value,
|
||||||
|
mode: 'xml',
|
||||||
|
lineNumbers: true,
|
||||||
|
readOnly: true,
|
||||||
|
theme: 'monokai',
|
||||||
|
lineWrapping: true
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AttachmentViewerType.Text:
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header bg-secondary text-white">
|
||||||
|
<strong>Text-Inhalt</strong>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<pre style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; max-height: 600px; overflow: auto;">@Model.TextContent</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AttachmentViewerType.Image:
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body text-center">
|
||||||
|
<img src="?handler=Download&filePath=@Request.Query["filePath"]"
|
||||||
|
alt="@Model.FileName"
|
||||||
|
class="img-fluid"
|
||||||
|
style="max-height: 800px;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AttachmentViewerType.Word:
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<strong>Word-Dokumente können nicht direkt angezeigt werden.</strong>
|
||||||
|
<p>Bitte laden Sie die Datei herunter oder implementieren Sie eine Konvertierung zu PDF.</p>
|
||||||
|
</div>
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<strong>Dieser Dateityp kann nicht angezeigt werden.</strong>
|
||||||
|
<p>Bitte laden Sie die Datei herunter.</p>
|
||||||
|
</div>
|
||||||
|
break;
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using DXApp.TemplateKitProject.Services;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace DXApp.TemplateKitProject.Pages.Invoices;
|
||||||
|
|
||||||
|
public class ViewAttachmentModel(AttachmentViewerService viewerService) : PageModel
|
||||||
|
{
|
||||||
|
public string FileName { get; private set; } = string.Empty;
|
||||||
|
public AttachmentViewerType ViewerType { get; private set; }
|
||||||
|
public string? TextContent { get; private set; }
|
||||||
|
|
||||||
|
public IActionResult OnGet(string filePath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(filePath) || !System.IO.File.Exists(filePath))
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
FileName = Path.GetFileName(filePath);
|
||||||
|
ViewerType = viewerService.DetermineViewerType(FileName);
|
||||||
|
|
||||||
|
// Für Text/XML: Inhalt direkt als Content zurückgeben (für AJAX)
|
||||||
|
if (ViewerType == AttachmentViewerType.Xml || ViewerType == AttachmentViewerType.Text)
|
||||||
|
{
|
||||||
|
TextContent = System.IO.File.ReadAllText(filePath, Encoding.UTF8);
|
||||||
|
|
||||||
|
// Wenn Request von AJAX kommt (Accept: */* oder text/plain)
|
||||||
|
if (Request.Headers.Accept.ToString().Contains("*/*") ||
|
||||||
|
Request.Headers["X-Requested-With"] == "XMLHttpRequest")
|
||||||
|
{
|
||||||
|
return Content(TextContent, "text/plain", Encoding.UTF8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult OnGetDownload(string filePath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(filePath) || !System.IO.File.Exists(filePath))
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
var fileName = Path.GetFileName(filePath);
|
||||||
|
var mimeType = viewerService.GetMimeType(fileName);
|
||||||
|
var bytes = System.IO.File.ReadAllBytes(filePath);
|
||||||
|
|
||||||
|
return File(bytes, mimeType, fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ builder.Services.AddScoped<PdfResultPackageService>();
|
|||||||
builder.Services.AddScoped<ZugferdExtractorService>();
|
builder.Services.AddScoped<ZugferdExtractorService>();
|
||||||
builder.Services.AddScoped<ZugferdParserService>();
|
builder.Services.AddScoped<ZugferdParserService>();
|
||||||
builder.Services.AddScoped<ZugferdImportService>();
|
builder.Services.AddScoped<ZugferdImportService>();
|
||||||
|
builder.Services.AddScoped<AttachmentViewerService>();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
|||||||
49
DXApp.TemplateKitProject/Services/AttachmentViewerService.cs
Normal file
49
DXApp.TemplateKitProject/Services/AttachmentViewerService.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using DXApp.TemplateKitProject.Models;
|
||||||
|
|
||||||
|
namespace DXApp.TemplateKitProject.Services;
|
||||||
|
|
||||||
|
public class AttachmentViewerService
|
||||||
|
{
|
||||||
|
public AttachmentViewerType DetermineViewerType(string fileName)
|
||||||
|
{
|
||||||
|
var extension = Path.GetExtension(fileName).ToLowerInvariant();
|
||||||
|
|
||||||
|
return extension switch
|
||||||
|
{
|
||||||
|
".pdf" => AttachmentViewerType.Pdf,
|
||||||
|
".xml" => AttachmentViewerType.Xml,
|
||||||
|
".txt" => AttachmentViewerType.Text,
|
||||||
|
".jpg" or ".jpeg" or ".png" or ".gif" => AttachmentViewerType.Image,
|
||||||
|
".docx" or ".doc" => AttachmentViewerType.Word,
|
||||||
|
_ => AttachmentViewerType.Download
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetMimeType(string fileName)
|
||||||
|
{
|
||||||
|
var extension = Path.GetExtension(fileName).ToLowerInvariant();
|
||||||
|
|
||||||
|
return extension switch
|
||||||
|
{
|
||||||
|
".pdf" => "application/pdf",
|
||||||
|
".xml" => "application/xml",
|
||||||
|
".txt" => "text/plain",
|
||||||
|
".jpg" or ".jpeg" => "image/jpeg",
|
||||||
|
".png" => "image/png",
|
||||||
|
".gif" => "image/gif",
|
||||||
|
".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||||
|
".doc" => "application/msword",
|
||||||
|
_ => "application/octet-stream"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum AttachmentViewerType
|
||||||
|
{
|
||||||
|
Pdf, // PDF.js Viewer
|
||||||
|
Xml, // Syntax-highlighted XML
|
||||||
|
Text, // Plain Text
|
||||||
|
Image, // <img> Tag
|
||||||
|
Word, // Konvertierung zu PDF (optional)
|
||||||
|
Download // Nur Download-Button
|
||||||
|
}
|
||||||
@@ -56,7 +56,7 @@ public class PdfResultPackageService(
|
|||||||
converter.SaveDocument(convertedStream);
|
converter.SaveDocument(convertedStream);
|
||||||
convertedStream.Position = 0;
|
convertedStream.Position = 0;
|
||||||
|
|
||||||
// Schritt 3: Anhang einbetten
|
// Schritt 3: Hauptdokument laden
|
||||||
using var processor = new PdfDocumentProcessor();
|
using var processor = new PdfDocumentProcessor();
|
||||||
processor.LoadDocument(convertedStream);
|
processor.LoadDocument(convertedStream);
|
||||||
|
|
||||||
@@ -68,15 +68,23 @@ public class PdfResultPackageService(
|
|||||||
processor.Document.Subject = string.Empty;
|
processor.Document.Subject = string.Empty;
|
||||||
processor.Document.Keywords = string.Empty;
|
processor.Document.Keywords = string.Empty;
|
||||||
|
|
||||||
processor.AttachFile(new PdfFileAttachment
|
// Schritt 3a: Berichts-Seiten ans Ende anhängen
|
||||||
|
int reportPageCount;
|
||||||
|
using (var reportStream = new FileStream(reportPath, FileMode.Open, FileAccess.Read))
|
||||||
{
|
{
|
||||||
FileName = Path.GetFileName(reportPath),
|
// Temporäres Dokument öffnen um Seitenanzahl zu ermitteln
|
||||||
Description = "Ergebnisbericht",
|
using var tempProcessor = new PdfDocumentProcessor();
|
||||||
MimeType = "application/pdf",
|
tempProcessor.LoadDocument(reportStream);
|
||||||
Relationship = PdfAssociatedFileRelationship.Supplement,
|
reportPageCount = tempProcessor.Document.Pages.Count;
|
||||||
CreationDate = DateTime.Now,
|
|
||||||
Data = File.ReadAllBytes(reportPath)
|
logger.LogDebug(
|
||||||
});
|
"Hänge {PageCount} Seite(n) aus Bericht an das Dokument an.",
|
||||||
|
reportPageCount);
|
||||||
|
|
||||||
|
// Stream zurücksetzen und ans Hauptdokument anhängen
|
||||||
|
reportStream.Position = 0;
|
||||||
|
processor.AppendDocument(reportStream);
|
||||||
|
}
|
||||||
|
|
||||||
// Schritt 4: Stempel auf Seite 1 zeichnen
|
// Schritt 4: Stempel auf Seite 1 zeichnen
|
||||||
var firstPage = processor.Document.Pages[0];
|
var firstPage = processor.Document.Pages[0];
|
||||||
@@ -126,10 +134,15 @@ public class PdfResultPackageService(
|
|||||||
processor.Document.Pages[0], 96, 96);
|
processor.Document.Pages[0], 96, 96);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schritt 4: Speichern
|
// Schritt 5: Speichern
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
processor.SaveDocument(outputPath);
|
processor.SaveDocument(outputPath);
|
||||||
|
|
||||||
|
logger.LogInformation(
|
||||||
|
"Result-PDF erstellt mit {TotalPages} Seiten (Original + {ReportPages} Berichtseiten).",
|
||||||
|
processor.Document.Pages.Count,
|
||||||
|
reportPageCount);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
89
DXApp.TemplateKitProject/package-lock.json
generated
89
DXApp.TemplateKitProject/package-lock.json
generated
@@ -19,6 +19,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz",
|
||||||
"integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==",
|
"integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@devexpress/utils/-/utils-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@devexpress/utils/-/utils-2.1.1.tgz",
|
||||||
"integrity": "sha512-hlemXR3L0yDPsMdhTQl9EtjiEYxIHklH7I4RKPkOhfrF5+jb4f3kkfvbKT7nA9aoFEHPPF0/hll43gOBpUpY0g==",
|
"integrity": "sha512-hlemXR3L0yDPsMdhTQl9EtjiEYxIHklH7I4RKPkOhfrF5+jb4f3kkfvbKT7nA9aoFEHPPF0/hll43gOBpUpY0g==",
|
||||||
"license": "SEE LICENSE IN README.md",
|
"license": "SEE LICENSE IN README.md",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "2.3.1"
|
"tslib": "2.3.1"
|
||||||
}
|
}
|
||||||
@@ -37,6 +39,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||||
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
|
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/sourcemap-codec": "^1.5.0",
|
"@jridgewell/sourcemap-codec": "^1.5.0",
|
||||||
"@jridgewell/trace-mapping": "^0.3.24"
|
"@jridgewell/trace-mapping": "^0.3.24"
|
||||||
@@ -47,6 +50,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
|
||||||
"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
|
"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/gen-mapping": "^0.3.5",
|
"@jridgewell/gen-mapping": "^0.3.5",
|
||||||
"@jridgewell/trace-mapping": "^0.3.24"
|
"@jridgewell/trace-mapping": "^0.3.24"
|
||||||
@@ -57,6 +61,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
@@ -65,13 +70,15 @@
|
|||||||
"version": "1.5.5",
|
"version": "1.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/trace-mapping": {
|
"node_modules/@jridgewell/trace-mapping": {
|
||||||
"version": "0.3.31",
|
"version": "0.3.31",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
|
||||||
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
|
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/resolve-uri": "^3.1.0",
|
"@jridgewell/resolve-uri": "^3.1.0",
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||||
@@ -82,6 +89,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.14.2.tgz",
|
"resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.14.2.tgz",
|
||||||
"integrity": "sha512-RZHdBj9ZF4n40Rp4jS052EHHjBWf96P9oNdXPfhQTovCuWY9iQn3Gq+gOTJSgBO9A/JBuPfMOWsSX/lIU9Pc/A==",
|
"integrity": "sha512-RZHdBj9ZF4n40Rp4jS052EHHjBWf96P9oNdXPfhQTovCuWY9iQn3Gq+gOTJSgBO9A/JBuPfMOWsSX/lIU9Pc/A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/preact"
|
"url": "https://opencollective.com/preact"
|
||||||
@@ -93,6 +101,7 @@
|
|||||||
"integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==",
|
"integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/core-js"
|
"url": "https://opencollective.com/core-js"
|
||||||
@@ -102,19 +111,22 @@
|
|||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
|
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/csstype": {
|
"node_modules/csstype": {
|
||||||
"version": "3.2.3",
|
"version": "3.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
||||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/devexpress-diagram": {
|
"node_modules/devexpress-diagram": {
|
||||||
"version": "2.2.29",
|
"version": "2.2.29",
|
||||||
"resolved": "https://registry.npmjs.org/devexpress-diagram/-/devexpress-diagram-2.2.29.tgz",
|
"resolved": "https://registry.npmjs.org/devexpress-diagram/-/devexpress-diagram-2.2.29.tgz",
|
||||||
"integrity": "sha512-6QS1zKP736QlIU6lMeZdq52Fe85BSa6vh1TwDIxSAKNwT6gHnGKm5paI71epRJ9H6GC4SLtv/zhlH8QCjwNnXQ==",
|
"integrity": "sha512-6QS1zKP736QlIU6lMeZdq52Fe85BSa6vh1TwDIxSAKNwT6gHnGKm5paI71epRJ9H6GC4SLtv/zhlH8QCjwNnXQ==",
|
||||||
"license": "SEE LICENSE IN README.md",
|
"license": "SEE LICENSE IN README.md",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@devexpress/utils": "^2.1.1",
|
"@devexpress/utils": "^2.1.1",
|
||||||
"es6-object-assign": "^1.1.0"
|
"es6-object-assign": "^1.1.0"
|
||||||
@@ -125,6 +137,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/devexpress-gantt/-/devexpress-gantt-4.1.68.tgz",
|
"resolved": "https://registry.npmjs.org/devexpress-gantt/-/devexpress-gantt-4.1.68.tgz",
|
||||||
"integrity": "sha512-pilTDWwCv1EthcCV9uFj5krbSkA3MdjiKCgJdCmGaTA+lDNiWP5Xc2JzNK1sOOTMUmzN+3h7kAtcLxzTfjWTRg==",
|
"integrity": "sha512-pilTDWwCv1EthcCV9uFj5krbSkA3MdjiKCgJdCmGaTA+lDNiWP5Xc2JzNK1sOOTMUmzN+3h7kAtcLxzTfjWTRg==",
|
||||||
"license": "SEE LICENSE IN README.md",
|
"license": "SEE LICENSE IN README.md",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@devexpress/utils": "^2.1.1",
|
"@devexpress/utils": "^2.1.1",
|
||||||
"tslib": "2.3.1"
|
"tslib": "2.3.1"
|
||||||
@@ -175,6 +188,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/devextreme-quill/-/devextreme-quill-1.7.9.tgz",
|
"resolved": "https://registry.npmjs.org/devextreme-quill/-/devextreme-quill-1.7.9.tgz",
|
||||||
"integrity": "sha512-UEkR16+I/7P/4+7dUmc65lv+VRdRGk0kFvZXgHnM2UFcEBKqm1kVDdVPBolGRFwuOFuDttJxp2SXUAyiuSC8wA==",
|
"integrity": "sha512-UEkR16+I/7P/4+7dUmc65lv+VRdRGk0kFvZXgHnM2UFcEBKqm1kVDdVPBolGRFwuOFuDttJxp2SXUAyiuSC8wA==",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^3.34.0",
|
"core-js": "^3.34.0",
|
||||||
"eventemitter3": "^4.0.7",
|
"eventemitter3": "^4.0.7",
|
||||||
@@ -188,25 +202,29 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
|
||||||
"integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==",
|
"integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/eventemitter3": {
|
"node_modules/eventemitter3": {
|
||||||
"version": "4.0.7",
|
"version": "4.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
|
||||||
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
|
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/fast-diff": {
|
"node_modules/fast-diff": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
|
||||||
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
|
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/immediate": {
|
"node_modules/immediate": {
|
||||||
"version": "3.0.6",
|
"version": "3.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||||
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
|
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/inferno": {
|
"node_modules/inferno": {
|
||||||
"version": "8.2.3",
|
"version": "8.2.3",
|
||||||
@@ -214,6 +232,7 @@
|
|||||||
"integrity": "sha512-LMeRlCe+RlXw8kHCLyOWRk2PsZ3Fo4jkESyAR1g4FfPT48N78i11YhTVXW2ukCx5MFjv+qrfa73JzJWU9sg4CQ==",
|
"integrity": "sha512-LMeRlCe+RlXw8kHCLyOWRk2PsZ3Fo4jkESyAR1g4FfPT48N78i11YhTVXW2ukCx5MFjv+qrfa73JzJWU9sg4CQ==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "^3.1.2",
|
"csstype": "^3.1.2",
|
||||||
"inferno-vnode-flags": "8.2.3",
|
"inferno-vnode-flags": "8.2.3",
|
||||||
@@ -229,6 +248,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/inferno-create-element/-/inferno-create-element-8.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/inferno-create-element/-/inferno-create-element-8.2.3.tgz",
|
||||||
"integrity": "sha512-YEwX4OiFlgeTutvE16uCGxkaSVwZ1DklpAPX8okjVsGaLIWQrM8QIQFxn3mTLWSu70Uea+afQfKL5wE4hxn39Q==",
|
"integrity": "sha512-YEwX4OiFlgeTutvE16uCGxkaSVwZ1DklpAPX8okjVsGaLIWQrM8QIQFxn3mTLWSu70Uea+afQfKL5wE4hxn39Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"inferno": "8.2.3"
|
"inferno": "8.2.3"
|
||||||
}
|
}
|
||||||
@@ -238,6 +258,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/inferno-hydrate/-/inferno-hydrate-8.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/inferno-hydrate/-/inferno-hydrate-8.2.3.tgz",
|
||||||
"integrity": "sha512-AyCiswnjYg7D9veJdjiQg06Npp0/iXKhwOm2hjoY3cjadT3fIdz2XtDElLB7imU4icuJ3xOmXA8FgIfnSJfHrQ==",
|
"integrity": "sha512-AyCiswnjYg7D9veJdjiQg06Npp0/iXKhwOm2hjoY3cjadT3fIdz2XtDElLB7imU4icuJ3xOmXA8FgIfnSJfHrQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"inferno": "8.2.3"
|
"inferno": "8.2.3"
|
||||||
}
|
}
|
||||||
@@ -246,19 +267,22 @@
|
|||||||
"version": "8.2.3",
|
"version": "8.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/inferno-vnode-flags/-/inferno-vnode-flags-8.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/inferno-vnode-flags/-/inferno-vnode-flags-8.2.3.tgz",
|
||||||
"integrity": "sha512-dfC0MIwFv9PCbZCUsuk9ISejFS3fKJODC0rZ/LjxxzE+OrCk+PMwPLsUnGU6O9/jbBnPACVz1BkACDf5LWgU5Q==",
|
"integrity": "sha512-dfC0MIwFv9PCbZCUsuk9ISejFS3fKJODC0rZ/LjxxzE+OrCk+PMwPLsUnGU6O9/jbBnPACVz1BkACDf5LWgU5Q==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/inherits": {
|
"node_modules/inherits": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
"license": "ISC"
|
"license": "ISC",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/isarray": {
|
"node_modules/isarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
|
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/jquery": {
|
"node_modules/jquery": {
|
||||||
"version": "3.7.1",
|
"version": "3.7.1",
|
||||||
@@ -271,6 +295,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
|
||||||
"integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
|
"integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
|
||||||
"license": "(MIT OR GPL-3.0-or-later)",
|
"license": "(MIT OR GPL-3.0-or-later)",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lie": "~3.3.0",
|
"lie": "~3.3.0",
|
||||||
"pako": "~1.0.2",
|
"pako": "~1.0.2",
|
||||||
@@ -283,6 +308,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
|
||||||
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
|
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"immediate": "~3.0.5"
|
"immediate": "~3.0.5"
|
||||||
}
|
}
|
||||||
@@ -291,26 +317,30 @@
|
|||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
|
||||||
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
|
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/lodash.isequal": {
|
"node_modules/lodash.isequal": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||||
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
|
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
|
||||||
"deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.",
|
"deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/lodash.merge": {
|
"node_modules/lodash.merge": {
|
||||||
"version": "4.6.2",
|
"version": "4.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/opencollective-postinstall": {
|
"node_modules/opencollective-postinstall": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
|
||||||
"integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
|
"integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"opencollective-postinstall": "index.js"
|
"opencollective-postinstall": "index.js"
|
||||||
}
|
}
|
||||||
@@ -319,19 +349,22 @@
|
|||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
|
||||||
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
|
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
|
||||||
"license": "(MIT AND Zlib)"
|
"license": "(MIT AND Zlib)",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/parchment": {
|
"node_modules/parchment": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parchment/-/parchment-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/parchment/-/parchment-2.0.1.tgz",
|
||||||
"integrity": "sha512-VBKrlEoZCBD+iwoeag0QTtY1Cti+Ma4nLpVYcc/uus/wHhMsPOi5InH3RL1s4aekahPZpabcS2ToKyGf7RMH/g==",
|
"integrity": "sha512-VBKrlEoZCBD+iwoeag0QTtY1Cti+Ma4nLpVYcc/uus/wHhMsPOi5InH3RL1s4aekahPZpabcS2ToKyGf7RMH/g==",
|
||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
||||||
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
@@ -343,13 +376,15 @@
|
|||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/quill-delta": {
|
"node_modules/quill-delta": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz",
|
||||||
"integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==",
|
"integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-diff": "^1.3.0",
|
"fast-diff": "^1.3.0",
|
||||||
"lodash.clonedeep": "^4.5.0",
|
"lodash.clonedeep": "^4.5.0",
|
||||||
@@ -364,6 +399,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
||||||
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-util-is": "~1.0.0",
|
"core-util-is": "~1.0.0",
|
||||||
"inherits": "~2.0.3",
|
"inherits": "~2.0.3",
|
||||||
@@ -379,6 +415,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/rrule/-/rrule-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/rrule/-/rrule-2.8.1.tgz",
|
||||||
"integrity": "sha512-hM3dHSBMeaJ0Ktp7W38BJZ7O1zOgaFEsn41PDk+yHoEtfLV+PoJt9E9xAlZiWgf/iqEqionN0ebHFZIDAp+iGw==",
|
"integrity": "sha512-hM3dHSBMeaJ0Ktp7W38BJZ7O1zOgaFEsn41PDk+yHoEtfLV+PoJt9E9xAlZiWgf/iqEqionN0ebHFZIDAp+iGw==",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
@@ -387,25 +424,29 @@
|
|||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
"license": "0BSD"
|
"license": "0BSD",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/safe-buffer": {
|
"node_modules/safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/setimmediate": {
|
"node_modules/setimmediate": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||||
"integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
|
"integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/string_decoder": {
|
"node_modules/string_decoder": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
}
|
}
|
||||||
@@ -414,13 +455,15 @@
|
|||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
||||||
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
|
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
|
||||||
"license": "0BSD"
|
"license": "0BSD",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/unplugin": {
|
"node_modules/unplugin": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.0.0.tgz",
|
||||||
"integrity": "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==",
|
"integrity": "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/remapping": "^2.3.5",
|
"@jridgewell/remapping": "^2.3.5",
|
||||||
"picomatch": "^4.0.3",
|
"picomatch": "^4.0.3",
|
||||||
@@ -434,13 +477,15 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/webpack-virtual-modules": {
|
"node_modules/webpack-virtual-modules": {
|
||||||
"version": "0.6.2",
|
"version": "0.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
|
||||||
"integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
|
"integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user