Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 85944da9ed | |||
| a598c6793a | |||
| bf30e006c3 | |||
| e799fdf10a | |||
| 34ce093ca9 | |||
| c1d39b73e9 | |||
| 567b966157 | |||
| e076bc3f6b | |||
| fd027e424f | |||
| 3bd8ee233b | |||
| bb9e9ce7d5 | |||
| a5f5a55e34 | |||
| 2ecc7338e6 | |||
| 66c069fb35 | |||
| 361d4338a6 | |||
| 9a964330e3 | |||
| 0e65410340 | |||
| b0e5d54061 | |||
| 9c979582d4 | |||
| 11cae94995 | |||
| 05ca047b5c | |||
| cd533c190b | |||
| efd84437b5 | |||
| 1c36305304 | |||
| f1f1e784da | |||
| 512d25f513 | |||
| f1628818f3 | |||
| b57d20420b | |||
| cbf97a2eb6 | |||
| 284f7ff241 | |||
| 888c7398f7 | |||
| 4926cb4715 | |||
| e2c7615826 | |||
| dc8ce10b51 | |||
| ffb4c9872d | |||
| a415d175d9 | |||
| 60b069cd28 | |||
| 7a63caa377 | |||
| df970e0a69 | |||
| c5c40f67cd | |||
| f8d2212ff3 | |||
| 38bcffe135 | |||
| 02e7224736 | |||
| 820ae5ce11 | |||
| 1f645b3aa2 | |||
| 9ff00ce0b6 | |||
| 586d281736 | |||
| 9441ee0e66 | |||
| be61e174c0 | |||
| 46f70964f0 | |||
| c337bbb7da | |||
| c007abe4a5 | |||
| 74ffe5983b | |||
| a6642512c3 | |||
| f5389907f0 | |||
| 37ca1d9a70 | |||
| a52199d4e3 |
+3
-1
@@ -118,7 +118,9 @@ installer:
|
||||
# - *nuget-fix
|
||||
# - dotnet restore
|
||||
script:
|
||||
- dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release GWMS.UI/GWMS.UI.csproj -o:publish
|
||||
# - dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release GWMS.UI/GWMS.UI.csproj -o:publish
|
||||
# pubblico solo installer Linux x64: https://docs.microsoft.com/en-us/dotnet/core/deploying/
|
||||
- dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release GWMS.UI/GWMS.UI.csproj -o:publish -r linux-x64 --self-contained false
|
||||
# qui il deploy su nexus...
|
||||
- *hashBuild
|
||||
- *nexusUpload
|
||||
|
||||
@@ -469,6 +469,7 @@ namespace GWMS.Data.Controllers
|
||||
.Where(x => x.FluxType == "Level" && x.PlantId == PlantId)
|
||||
.OrderByDescending(x => x.DtEvent)
|
||||
.Take(maxRecords)
|
||||
.OrderBy(x => x.DtEvent)
|
||||
.ToList();
|
||||
|
||||
var rawMainPressData = dbCtxMult
|
||||
@@ -476,6 +477,7 @@ namespace GWMS.Data.Controllers
|
||||
.Where(x => x.FluxType == "MainPress" && x.PlantId == PlantId)
|
||||
.OrderByDescending(x => x.DtEvent)
|
||||
.Take(maxRecords)
|
||||
.OrderBy(x => x.DtEvent)
|
||||
.ToList();
|
||||
|
||||
var rawBHPressData = dbCtxMult
|
||||
@@ -483,6 +485,7 @@ namespace GWMS.Data.Controllers
|
||||
.Where(x => x.FluxType == "PressBH" && x.PlantId == PlantId)
|
||||
.OrderByDescending(x => x.DtEvent)
|
||||
.Take(maxRecords)
|
||||
.OrderBy(x => x.DtEvent)
|
||||
.ToList();
|
||||
|
||||
var rawBLPressData = dbCtxMult
|
||||
@@ -490,6 +493,7 @@ namespace GWMS.Data.Controllers
|
||||
.Where(x => x.FluxType == "PressBL" && x.PlantId == PlantId)
|
||||
.OrderByDescending(x => x.DtEvent)
|
||||
.Take(maxRecords)
|
||||
.OrderBy(x => x.DtEvent)
|
||||
.ToList();
|
||||
|
||||
var rawOrderData = dbCtxMult
|
||||
@@ -497,6 +501,7 @@ namespace GWMS.Data.Controllers
|
||||
.Where(x => x.PlantId == PlantId && x.ExecutionQty == 0)
|
||||
.OrderByDescending(x => x.DtOrder)
|
||||
.Take(maxRecords)
|
||||
.OrderBy(x => x.DtOrder)
|
||||
.ToList();
|
||||
|
||||
LevelTS = rawLevelData
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using GWMS.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace GWMS.User.Migrations
|
||||
{
|
||||
[DbContext(typeof(UserIdentityDbContext))]
|
||||
[Migration("20210826102940_AddTransporterRule")]
|
||||
partial class AddTransporterRule
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64)
|
||||
.HasAnnotation("ProductVersion", "5.0.7");
|
||||
|
||||
modelBuilder.Entity("GWMS.Data.DatabaseModels.TableCount", b =>
|
||||
{
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("TableName")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.ToTable("DbSetCounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("varchar(256)");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("varchar(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles");
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = "339a7ac3-4fcd-4baa-bd19-a6a09d1b7c5d",
|
||||
ConcurrencyStamp = "3caf0732-df97-4b81-ba2c-9fb51e34532a",
|
||||
Name = "Undef",
|
||||
NormalizedName = "UNDEF"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = "47c8d4fb-6925-4ef0-a830-5df33e705d7a",
|
||||
ConcurrencyStamp = "9671ece6-f70a-4ca6-88db-64562e007c72",
|
||||
Name = "ExtUser",
|
||||
NormalizedName = "EXTUSER"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = "2d87821f-5c6d-4d9e-98d7-7ae801030100",
|
||||
ConcurrencyStamp = "9ee56f2f-558f-4579-9ad7-4a6150e3d822",
|
||||
Name = "ExtTransp",
|
||||
NormalizedName = "EXTTRANSP"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = "db1d1ac5-905d-46a5-bcf4-ef8a5f3f715c",
|
||||
ConcurrencyStamp = "3244e9d3-ab0e-45ae-97b6-c8c74f57cf64",
|
||||
Name = "User",
|
||||
NormalizedName = "USER"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = "7e3dc53b-c152-440f-a49d-6c3a2f6bf6eb",
|
||||
ConcurrencyStamp = "a0a109e5-ab8e-4e20-9aa8-eba3c429fd12",
|
||||
Name = "Admin",
|
||||
NormalizedName = "ADMIN"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = "2fcd8455-143a-4ebc-b41c-e9bdf6a0315b",
|
||||
ConcurrencyStamp = "549b8a8d-ba83-4b79-be88-fde0bd4cc60f",
|
||||
Name = "SuperAdmin",
|
||||
NormalizedName = "SUPERADMIN"
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("varchar(256)");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("varchar(256)");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("varchar(256)");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("varchar(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasDatabaseName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("varchar(128)");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("varchar(128)");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("varchar(128)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("varchar(128)");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace GWMS.User.Migrations
|
||||
{
|
||||
public partial class AddTransporterRule : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DeleteData(
|
||||
table: "AspNetRoles",
|
||||
keyColumn: "Id",
|
||||
keyValue: "00e6b3ed-dd0e-4cd5-8d3d-f88d8ae5e145");
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "AspNetRoles",
|
||||
keyColumn: "Id",
|
||||
keyValue: "5287113c-6493-4419-bbc9-2cb2f6455006");
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "AspNetRoles",
|
||||
keyColumn: "Id",
|
||||
keyValue: "5b928219-a530-49c6-be33-f65253865a98");
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "AspNetRoles",
|
||||
keyColumn: "Id",
|
||||
keyValue: "e9befc87-9732-4c21-b91e-7aea6a289d35");
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "AspNetRoles",
|
||||
keyColumn: "Id",
|
||||
keyValue: "f27a0416-02cc-4e4c-8983-29cb51eb4f9a");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DbSetCounts",
|
||||
columns: table => new
|
||||
{
|
||||
Count = table.Column<int>(type: "int", nullable: false),
|
||||
TableName = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "AspNetRoles",
|
||||
columns: new[] { "Id", "ConcurrencyStamp", "Name", "NormalizedName" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ "339a7ac3-4fcd-4baa-bd19-a6a09d1b7c5d", "3caf0732-df97-4b81-ba2c-9fb51e34532a", "Undef", "UNDEF" },
|
||||
{ "47c8d4fb-6925-4ef0-a830-5df33e705d7a", "9671ece6-f70a-4ca6-88db-64562e007c72", "ExtUser", "EXTUSER" },
|
||||
{ "2d87821f-5c6d-4d9e-98d7-7ae801030100", "9ee56f2f-558f-4579-9ad7-4a6150e3d822", "ExtTransp", "EXTTRANSP" },
|
||||
{ "db1d1ac5-905d-46a5-bcf4-ef8a5f3f715c", "3244e9d3-ab0e-45ae-97b6-c8c74f57cf64", "User", "USER" },
|
||||
{ "7e3dc53b-c152-440f-a49d-6c3a2f6bf6eb", "a0a109e5-ab8e-4e20-9aa8-eba3c429fd12", "Admin", "ADMIN" },
|
||||
{ "2fcd8455-143a-4ebc-b41c-e9bdf6a0315b", "549b8a8d-ba83-4b79-be88-fde0bd4cc60f", "SuperAdmin", "SUPERADMIN" }
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "DbSetCounts");
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "AspNetRoles",
|
||||
keyColumn: "Id",
|
||||
keyValue: "2d87821f-5c6d-4d9e-98d7-7ae801030100");
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "AspNetRoles",
|
||||
keyColumn: "Id",
|
||||
keyValue: "2fcd8455-143a-4ebc-b41c-e9bdf6a0315b");
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "AspNetRoles",
|
||||
keyColumn: "Id",
|
||||
keyValue: "339a7ac3-4fcd-4baa-bd19-a6a09d1b7c5d");
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "AspNetRoles",
|
||||
keyColumn: "Id",
|
||||
keyValue: "47c8d4fb-6925-4ef0-a830-5df33e705d7a");
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "AspNetRoles",
|
||||
keyColumn: "Id",
|
||||
keyValue: "7e3dc53b-c152-440f-a49d-6c3a2f6bf6eb");
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "AspNetRoles",
|
||||
keyColumn: "Id",
|
||||
keyValue: "db1d1ac5-905d-46a5-bcf4-ef8a5f3f715c");
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "AspNetRoles",
|
||||
columns: new[] { "Id", "ConcurrencyStamp", "Name", "NormalizedName" },
|
||||
values: new object[,]
|
||||
{
|
||||
{ "5287113c-6493-4419-bbc9-2cb2f6455006", "00059b0a-3e8c-406e-a578-2ae40c52435a", "Undef", "UNDEF" },
|
||||
{ "f27a0416-02cc-4e4c-8983-29cb51eb4f9a", "b58874fc-02b5-4efa-b4d5-61bfda8b7c67", "ExtUser", "EXTUSER" },
|
||||
{ "00e6b3ed-dd0e-4cd5-8d3d-f88d8ae5e145", "cd1f0ba9-9f42-42f3-8271-1627ef55d36f", "User", "USER" },
|
||||
{ "5b928219-a530-49c6-be33-f65253865a98", "6de09bee-9a83-416a-90c4-27bb643519f6", "Admin", "ADMIN" },
|
||||
{ "e9befc87-9732-4c21-b91e-7aea6a289d35", "f2bf6c1c-4043-4344-8b68-c8b2122ab88f", "SuperAdmin", "SUPERADMIN" }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,18 @@ namespace GWMS.User.Migrations
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64)
|
||||
.HasAnnotation("ProductVersion", "5.0.8");
|
||||
.HasAnnotation("ProductVersion", "5.0.7");
|
||||
|
||||
modelBuilder.Entity("GWMS.Data.DatabaseModels.TableCount", b =>
|
||||
{
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("TableName")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.ToTable("DbSetCounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
@@ -45,36 +56,43 @@ namespace GWMS.User.Migrations
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = "5287113c-6493-4419-bbc9-2cb2f6455006",
|
||||
ConcurrencyStamp = "00059b0a-3e8c-406e-a578-2ae40c52435a",
|
||||
Id = "339a7ac3-4fcd-4baa-bd19-a6a09d1b7c5d",
|
||||
ConcurrencyStamp = "3caf0732-df97-4b81-ba2c-9fb51e34532a",
|
||||
Name = "Undef",
|
||||
NormalizedName = "UNDEF"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = "f27a0416-02cc-4e4c-8983-29cb51eb4f9a",
|
||||
ConcurrencyStamp = "b58874fc-02b5-4efa-b4d5-61bfda8b7c67",
|
||||
Id = "47c8d4fb-6925-4ef0-a830-5df33e705d7a",
|
||||
ConcurrencyStamp = "9671ece6-f70a-4ca6-88db-64562e007c72",
|
||||
Name = "ExtUser",
|
||||
NormalizedName = "EXTUSER"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = "00e6b3ed-dd0e-4cd5-8d3d-f88d8ae5e145",
|
||||
ConcurrencyStamp = "cd1f0ba9-9f42-42f3-8271-1627ef55d36f",
|
||||
Id = "2d87821f-5c6d-4d9e-98d7-7ae801030100",
|
||||
ConcurrencyStamp = "9ee56f2f-558f-4579-9ad7-4a6150e3d822",
|
||||
Name = "ExtTransp",
|
||||
NormalizedName = "EXTTRANSP"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = "db1d1ac5-905d-46a5-bcf4-ef8a5f3f715c",
|
||||
ConcurrencyStamp = "3244e9d3-ab0e-45ae-97b6-c8c74f57cf64",
|
||||
Name = "User",
|
||||
NormalizedName = "USER"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = "5b928219-a530-49c6-be33-f65253865a98",
|
||||
ConcurrencyStamp = "6de09bee-9a83-416a-90c4-27bb643519f6",
|
||||
Id = "7e3dc53b-c152-440f-a49d-6c3a2f6bf6eb",
|
||||
ConcurrencyStamp = "a0a109e5-ab8e-4e20-9aa8-eba3c429fd12",
|
||||
Name = "Admin",
|
||||
NormalizedName = "ADMIN"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = "e9befc87-9732-4c21-b91e-7aea6a289d35",
|
||||
ConcurrencyStamp = "f2bf6c1c-4043-4344-8b68-c8b2122ab88f",
|
||||
Id = "2fcd8455-143a-4ebc-b41c-e9bdf6a0315b",
|
||||
ConcurrencyStamp = "549b8a8d-ba83-4b79-be88-fde0bd4cc60f",
|
||||
Name = "SuperAdmin",
|
||||
NormalizedName = "SUPERADMIN"
|
||||
});
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace GWMS.Data
|
||||
builder.HasData(
|
||||
new IdentityRole { Name = "Undef", NormalizedName = "UNDEF" },
|
||||
new IdentityRole { Name = "ExtUser", NormalizedName = "EXTUSER" },
|
||||
new IdentityRole { Name = "ExtTransp", NormalizedName = "EXTTRANSP" },
|
||||
new IdentityRole { Name = "User", NormalizedName = "USER" },
|
||||
new IdentityRole { Name = "Admin", NormalizedName = "ADMIN" },
|
||||
new IdentityRole { Name = "SuperAdmin", NormalizedName = "SUPERADMIN" }
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
@page
|
||||
@model ConfirmEmailModel
|
||||
@{
|
||||
ViewData["Title"] = "Confirm email";
|
||||
ViewData["Title"] = "Conferma Effettuata";
|
||||
}
|
||||
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
<div class="card">
|
||||
<div class="card-header"><h1>@ViewData["Title"]</h1></div>
|
||||
<div class="card-body">
|
||||
<div class="alert alert-success">
|
||||
<p>L'email è stata confermata! ora puoi effettuare il login all'applicazione</p>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<a title="LogIn" href="Identity/Account/LogIn" class="btn btn-sm btn-success btn-block"><i class="fas fa-sign-in-alt"></i> Login Page</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,26 +1,30 @@
|
||||
@page
|
||||
@model ForgotPasswordModel
|
||||
@{
|
||||
ViewData["Title"] = "Forgot your password?";
|
||||
ViewData["Title"] = "Password dimenticata?";
|
||||
}
|
||||
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
<h4>Enter your email.</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form method="post">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Email"></label>
|
||||
<input asp-for="Input.Email" class="form-control" />
|
||||
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||
<div class="card">
|
||||
<div class="card-header"><h1>@ViewData["Title"]</h1></div>
|
||||
<div class="card-body">
|
||||
<h4>Inserire l'account email registrato</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form method="post">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Email"></label>
|
||||
<input asp-for="Input.Email" class="form-control" />
|
||||
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-block"><i class="fas fa-envelope"></i> Inoltra richiesta reset password</button>
|
||||
</form>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,21 @@
|
||||
@page
|
||||
@model ForgotPasswordConfirmation
|
||||
@{
|
||||
ViewData["Title"] = "Forgot password confirmation";
|
||||
ViewData["Title"] = "Password dimenticata";
|
||||
}
|
||||
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
<p>
|
||||
Please check your email to reset your password.
|
||||
</p>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header"><h1>@ViewData["Title"]</h1></div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<p>
|
||||
Prego verificare l'account email per le istruzioni relative alla reimpostazione della password.
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<a title="LogIn" href="Identity/Account/LogIn" class="btn btn-primary btn-block"><i class="fas fa-sign-in-alt"></i> Login Page</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -4,18 +4,37 @@
|
||||
ViewData["Title"] = "Log out";
|
||||
}
|
||||
|
||||
<header>
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
@{
|
||||
if (User.Identity.IsAuthenticated)
|
||||
{
|
||||
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post">
|
||||
<button type="submit" class="nav-link btn btn-warning">Click here to Logout</button>
|
||||
</form>
|
||||
<div class="card">
|
||||
<div class="card-header"><h1>@ViewData["Title"]</h1></div>
|
||||
<div class="card-body">
|
||||
@{
|
||||
if (User.Identity.IsAuthenticated)
|
||||
{
|
||||
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<p>Premendo sul pulsante effettuerai il logout dal sistema.</p>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<button type="submit" class="nav-link btn btn-warning"><i class="fas fa-sign-out-alt"></i> Clicca per Logout</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<p>Disconnesisone effettuata.</p>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<a title="Home" href="~/" class="btn btn-sm btn-primary btn-block"><i class="fas fa-home"></i> Home Page</a>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<a title="LogIn" href="Identity/Account/LogIn" class="btn btn-sm btn-success btn-block"><i class="fas fa-sign-in-alt"></i> Login Page</a>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>You have successfully logged out of the application.</p>
|
||||
}
|
||||
}
|
||||
</header>
|
||||
</div>
|
||||
</div>
|
||||
@@ -4,82 +4,87 @@
|
||||
@{
|
||||
ViewData["Title"] = "Log in";
|
||||
}
|
||||
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<section>
|
||||
<form id="account" method="post">
|
||||
<h4>Use a local account to log in.</h4>
|
||||
<hr />
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Email"></label>
|
||||
<input asp-for="Input.Email" class="form-control" />
|
||||
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Password"></label>
|
||||
<input asp-for="Input.Password" class="form-control" />
|
||||
<span asp-validation-for="Input.Password" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label asp-for="Input.RememberMe">
|
||||
<input asp-for="Input.RememberMe" />
|
||||
@Html.DisplayNameFor(m => m.Input.RememberMe)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary">Log in</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<p>
|
||||
<a id="forgot-password" asp-page="./ForgotPassword">Forgot your password?</a>
|
||||
</p>
|
||||
<p>
|
||||
<a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
|
||||
</p>
|
||||
<p>
|
||||
<a id="resend-confirmation" asp-page="./ResendEmailConfirmation">Resend email confirmation</a>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
@*<div class="col-md-6 col-md-offset-2">
|
||||
<section>
|
||||
<h4>Use another service to log in.</h4>
|
||||
<hr />
|
||||
@{
|
||||
if ((Model.ExternalLogins?.Count ?? 0) == 0)
|
||||
{
|
||||
<div>
|
||||
<p>
|
||||
There are no external authentication services configured. See <a href="https://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
|
||||
for details on setting up this ASP.NET application to support logging in via external services.
|
||||
</p>
|
||||
<div class="card">
|
||||
<div class="card-header"><h1>@ViewData["Title"]</h1></div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<section>
|
||||
<form id="account" method="post">
|
||||
<h4>Effettuare login con l'account registrato.</h4>
|
||||
<hr />
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Email"></label>
|
||||
<input asp-for="Input.Email" class="form-control" />
|
||||
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
|
||||
<div>
|
||||
<p>
|
||||
@foreach (var provider in Model.ExternalLogins)
|
||||
{
|
||||
<button type="submit" class="btn btn-primary" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
|
||||
}
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Password"></label>
|
||||
<input asp-for="Input.Password" class="form-control" />
|
||||
<span asp-validation-for="Input.Password" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label asp-for="Input.RememberMe">
|
||||
<input asp-for="Input.RememberMe" />
|
||||
@Html.DisplayNameFor(m => m.Input.RememberMe)
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
</section>
|
||||
</div>*@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="col">
|
||||
<button type="submit" class="btn btn-block btn-primary"><i class="fas fa-sign-in-alt"></i> Log in</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a asp-page="./Register" class="btn btn-block btn-outline-primary" asp-route-returnUrl="@Model.ReturnUrl"><i class="fas fa-edit"></i> Registra account</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mt-2">
|
||||
<div class="col">
|
||||
<a id="forgot-password" class="btn btn-block btn-outline-info" asp-page="./ForgotPassword"><i class="far fa-life-ring"></i> Password dimenticata?</a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a id="resend-confirmation" class="btn btn-block btn-outline-dark" asp-page="./ResendEmailConfirmation"><i class="far fa-envelope"></i> (Re)Invia email conferma</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
@*<div class="col-md-6 col-md-offset-2">
|
||||
<section>
|
||||
<h4>Use another service to log in.</h4>
|
||||
<hr />
|
||||
@{
|
||||
if ((Model.ExternalLogins?.Count ?? 0) == 0)
|
||||
{
|
||||
<div>
|
||||
<p>
|
||||
There are no external authentication services configured. See <a href="https://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
|
||||
for details on setting up this ASP.NET application to support logging in via external services.
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
|
||||
<div>
|
||||
<p>
|
||||
@foreach (var provider in Model.ExternalLogins)
|
||||
{
|
||||
<button type="submit" class="btn btn-primary" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
</section>
|
||||
</div>*@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
}
|
||||
@@ -81,16 +81,18 @@ namespace GWMS.UI.Areas.Identity.Pages.Account
|
||||
// verifico ruoli...
|
||||
if (user != null)
|
||||
{
|
||||
bool needCreate = true;
|
||||
// Gestione salvataggio ruoli... SE VARIATO...
|
||||
var UserRoles = await _userManager.GetRolesAsync(user);
|
||||
if (UserRoles != null && UserRoles.Count > 0)
|
||||
{
|
||||
var oldRole = UserRoles.Where(x => x == ADMIN_ROLE).FirstOrDefault();
|
||||
if (oldRole == null)
|
||||
{
|
||||
// aggiungo a ruolo admin
|
||||
await _userManager.AddToRoleAsync(user, ADMIN_ROLE);
|
||||
}
|
||||
needCreate = (oldRole == null);
|
||||
}
|
||||
if (needCreate)
|
||||
{
|
||||
// aggiungo a ruolo admin
|
||||
await _userManager.AddToRoleAsync(user, ADMIN_ROLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,7 +103,7 @@ namespace GWMS.UI.Areas.Identity.Pages.Account
|
||||
|
||||
public async Task OnGetAsync(string returnUrl = null)
|
||||
{
|
||||
CheckSuperAdmin();
|
||||
await CheckSuperAdmin();
|
||||
if (!string.IsNullOrEmpty(ErrorMessage))
|
||||
{
|
||||
ModelState.AddModelError(string.Empty, ErrorMessage);
|
||||
|
||||
@@ -1,67 +1,70 @@
|
||||
@page
|
||||
@model RegisterModel
|
||||
@{
|
||||
ViewData["Title"] = "Register";
|
||||
ViewData["Title"] = "Registrazione";
|
||||
}
|
||||
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form asp-route-returnUrl="@Model.ReturnUrl" method="post">
|
||||
<h4>Create a new account.</h4>
|
||||
<hr />
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Email"></label>
|
||||
<input asp-for="Input.Email" class="form-control" />
|
||||
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Password"></label>
|
||||
<input asp-for="Input.Password" class="form-control" />
|
||||
<span asp-validation-for="Input.Password" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.ConfirmPassword"></label>
|
||||
<input asp-for="Input.ConfirmPassword" class="form-control" />
|
||||
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Register</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-md-6 col-md-offset-2">
|
||||
<section>
|
||||
<h4>Use another service to register.</h4>
|
||||
<hr />
|
||||
@{
|
||||
if ((Model.ExternalLogins?.Count ?? 0) == 0)
|
||||
{
|
||||
<div>
|
||||
<p>
|
||||
There are no external authentication services configured. See <a href="https://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
|
||||
for details on setting up this ASP.NET application to support logging in via external services.
|
||||
</p>
|
||||
<div class="card">
|
||||
<div class="card-header"><h1>@ViewData["Title"]</h1></div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form asp-route-returnUrl="@Model.ReturnUrl" method="post">
|
||||
<h4>Creazione nuovo account.</h4>
|
||||
<hr />
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Email"></label>
|
||||
<input asp-for="Input.Email" class="form-control" />
|
||||
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
|
||||
<div>
|
||||
<p>
|
||||
@foreach (var provider in Model.ExternalLogins)
|
||||
{
|
||||
<button type="submit" class="btn btn-primary" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
</section>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Password"></label>
|
||||
<input asp-for="Input.Password" class="form-control" />
|
||||
<span asp-validation-for="Input.Password" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.ConfirmPassword"></label>
|
||||
<input asp-for="Input.ConfirmPassword" class="form-control" />
|
||||
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success btn-block"><i class="far fa-save"></i> Registra Account</button>
|
||||
</form>
|
||||
</div>
|
||||
@*<div class="col-md-6 col-md-offset-2">
|
||||
<section>
|
||||
<h4>Use another service to register.</h4>
|
||||
<hr />
|
||||
@{
|
||||
if ((Model.ExternalLogins?.Count ?? 0) == 0)
|
||||
{
|
||||
<div>
|
||||
<p>
|
||||
There are no external authentication services configured. See <a href="https://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
|
||||
for details on setting up this ASP.NET application to support logging in via external services.
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
|
||||
<div>
|
||||
<p>
|
||||
@foreach (var provider in Model.ExternalLogins)
|
||||
{
|
||||
<button type="submit" class="btn btn-primary" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
}
|
||||
</section>
|
||||
</div>*@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
}
|
||||
}
|
||||
@@ -83,8 +83,8 @@ namespace GWMS.UI.Areas.Identity.Pages.Account
|
||||
values: new { area = "Identity", userId = user.Id, code = code, returnUrl = returnUrl },
|
||||
protocol: Request.Scheme);
|
||||
|
||||
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
|
||||
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
|
||||
await _emailSender.SendEmailAsync(Input.Email, "GWMS: Richiesta conferma email",
|
||||
$"Prego cliccare sul <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>seguente link</a> per confermare l'account registrato con questa email.");
|
||||
|
||||
if (_userManager.Options.SignIn.RequireConfirmedAccount)
|
||||
{
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
@page
|
||||
@model RegisterConfirmationModel
|
||||
@{
|
||||
ViewData["Title"] = "Register confirmation";
|
||||
ViewData["Title"] = "Conferma richiesta";
|
||||
}
|
||||
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
@{
|
||||
if (@Model.DisplayConfirmAccountLink)
|
||||
{
|
||||
<p>
|
||||
This app does not currently have a real email sender registered, see <a href="https://aka.ms/aspaccountconf">these docs</a> for how to configure a real email sender.
|
||||
Normally this would be emailed: <a id="confirm-link" href="@Model.EmailConfirmationUrl">Click here to confirm your account</a>
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p>
|
||||
Please check your email to confirm your account.
|
||||
</p>
|
||||
}
|
||||
}
|
||||
<div class="card">
|
||||
<div class="card-header"><h1>@ViewData["Title"]</h1></div>
|
||||
<div class="card-body">
|
||||
<div class="alert alert-warning">
|
||||
<h4>Account creato!</h4>
|
||||
<p>Ora è necessario effettuare la verifica dell'email registrata</p>
|
||||
</div>
|
||||
<b>Prego verifica la posta ricevuta all'account registrato per effettuare la conferma.</b>
|
||||
<p>Riceverai un email da steamwarebot at gmail.com con un link da cliccare per completare la registrazione. Dopo la conferma potrai effettuare il login all'applicazione.</p>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<a title="LogIn" href="Identity/Account/LogIn" class="btn btn-sm btn-success btn-block"><i class="fas fa-sign-in-alt"></i> Login Page</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -31,7 +31,6 @@ namespace GWMS.UI.Areas.Identity.Pages.Account
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public bool DisplayConfirmAccountLink { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string EmailConfirmationUrl { get; set; }
|
||||
|
||||
@@ -53,19 +52,6 @@ namespace GWMS.UI.Areas.Identity.Pages.Account
|
||||
}
|
||||
|
||||
Email = email;
|
||||
// Once you add a real email sender, you should remove this code that lets you confirm the account
|
||||
DisplayConfirmAccountLink = false;
|
||||
if (DisplayConfirmAccountLink)
|
||||
{
|
||||
var userId = await _userManager.GetUserIdAsync(user);
|
||||
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
||||
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
|
||||
EmailConfirmationUrl = Url.Page(
|
||||
"/Account/ConfirmEmail",
|
||||
pageHandler: null,
|
||||
values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
|
||||
protocol: Request.Scheme);
|
||||
}
|
||||
|
||||
return Page();
|
||||
}
|
||||
|
||||
@@ -1,26 +1,30 @@
|
||||
@page
|
||||
@model ResendEmailConfirmationModel
|
||||
@{
|
||||
ViewData["Title"] = "Resend email confirmation";
|
||||
ViewData["Title"] = "Reinvia email di conferma";
|
||||
}
|
||||
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
<h4>Enter your email.</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form method="post">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Email"></label>
|
||||
<input asp-for="Input.Email" class="form-control" />
|
||||
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||
<div class="card">
|
||||
<div class="card-header"><h1>@ViewData["Title"]</h1></div>
|
||||
<div class="card-body">
|
||||
<h4>Inserire l'account email registrato.</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form method="post">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Email"></label>
|
||||
<input asp-for="Input.Email" class="form-control" />
|
||||
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-block"><i class="fas fa-envelope"></i> Invia nuovamente email</button>
|
||||
</form>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Resend</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,41 @@
|
||||
@page
|
||||
@model ResetPasswordModel
|
||||
@{
|
||||
ViewData["Title"] = "Reset password";
|
||||
ViewData["Title"] = "Reset Password";
|
||||
}
|
||||
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
<h4>Reset your password.</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form method="post">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<input asp-for="Input.Code" type="hidden" />
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Email"></label>
|
||||
<input asp-for="Input.Email" class="form-control" />
|
||||
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||
<div class="card">
|
||||
<div class="card-header"><h1>@ViewData["Title"]</h1></div>
|
||||
<div class="card-body">
|
||||
<h4>Reset password.</h4>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<form method="post">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<input asp-for="Input.Code" type="hidden" />
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Email"></label>
|
||||
<input asp-for="Input.Email" class="form-control" />
|
||||
<span asp-validation-for="Input.Email" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Password"></label>
|
||||
<input asp-for="Input.Password" class="form-control" />
|
||||
<span asp-validation-for="Input.Password" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.ConfirmPassword"></label>
|
||||
<input asp-for="Input.ConfirmPassword" class="form-control" />
|
||||
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-block"><i class="fas fa-envelope"></i> Reset Password</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.Password"></label>
|
||||
<input asp-for="Input.Password" class="form-control" />
|
||||
<span asp-validation-for="Input.Password" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Input.ConfirmPassword"></label>
|
||||
<input asp-for="Input.ConfirmPassword" class="form-control" />
|
||||
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Reset</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<partial name="_ValidationScriptsPartial" />
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="row px-1 text-light">
|
||||
<div class="form-row text-light">
|
||||
<div class="col-5 pr-0 text-left">
|
||||
GWMS <span class="small">v.@version</span>
|
||||
</div>
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
@inject MessageService AppMessages
|
||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||
|
||||
<div class="row pt-3">
|
||||
<div class="col-6 col-md-5 col-lg-4 col-xl-3 px-0 text-truncate">
|
||||
<div class="form-row pt-3">
|
||||
<div class="col-7 col-md-6 col-lg-4 col-xl-3">
|
||||
<LoginDisplay></LoginDisplay>
|
||||
</div>
|
||||
<div class="col-12 col-md-2 col-lg-4 col-xl-6 d-none d-lg-block text-center h4 px-1 text-truncate">
|
||||
<div class="col-12 col-lg-4 col-xl-6 d-none d-lg-block text-center h4 text-truncate">
|
||||
<span class="@PageIcon" aria-hidden="true"></span> @PageName
|
||||
</div>
|
||||
<div class="col-6 col-md-5 col-lg-4 col-xl-3 text-right pl-0">
|
||||
<div class="col-5 col-md-6 col-lg-4 col-xl-3 text-right">
|
||||
@if (ShowSearch)
|
||||
{
|
||||
<SearchMod></SearchMod>
|
||||
|
||||
@@ -4,26 +4,28 @@
|
||||
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
<div class="input-group">
|
||||
<div class="input-group text-truncate">
|
||||
<div class="input-group-prepend">
|
||||
<a title="LogOut" href="Identity/Account/LogOut" class="btn btn-sm btn-danger ml-3"><i class="fas fa-sign-out-alt"></i></a>
|
||||
<a title="LogOut" href="Identity/Account/LogOut" class="btn btn-sm btn-danger"><i class="fas fa-sign-out-alt"></i></a>
|
||||
</div>
|
||||
<a title="Manage" href="Identity/Account/Manage" class="btn btn-sm btn-outline-dark mx-0 px-1">
|
||||
<i class="fas fa-user-alt"></i> @userName
|
||||
<a title="Gestione account @userName" href="Identity/Account/Manage" class="btn btn-sm btn-outline-dark mx-0 px-1">
|
||||
<div class="d-none d-sm-block">
|
||||
<i class="fas fa-user-alt"></i> @StringLim(userName, 30)
|
||||
</div>
|
||||
<div class="d-block d-sm-none">
|
||||
<i class="fas fa-user-alt"></i> @StringLim(userName, 15)
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</Authorized>
|
||||
<NotAuthorized>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<a title="LogIn" href="Identity/Account/LogIn" class="btn btn-sm btn-success ml-3"><i class="fas fa-sign-in-alt"></i></a>
|
||||
<a title="LogIn" href="Identity/Account/LogIn" class="btn btn-sm btn-success"><i class="fas fa-sign-in-alt"></i></a>
|
||||
</div>
|
||||
<div class="form-control form-control-sm">
|
||||
<i class="fas fa-user-alt"></i> @userName
|
||||
</div>
|
||||
<div class="input-group-append">
|
||||
<a title="Register" href="Identity/Account/Register" class="btn btn-sm btn-primary ml-0"><i class="fas fa-edit"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
@@ -51,4 +53,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
protected string StringLim(string original, int maxLen)
|
||||
{
|
||||
return original.Length <= maxLen ? original : $"{original.Substring(0, maxLen - 3)}...";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,7 +20,8 @@
|
||||
<DataAnnotationsValidator />
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-1">
|
||||
<img src="@getImgUrl(_currItem.OrderCode)" class="img-fluid" width="85" />
|
||||
<div id="qrCodeImg"></div>
|
||||
@*<img src="@getImgUrl(_currItem.OrderCode)" class="img-fluid" width="85" />*@
|
||||
</div>
|
||||
<div class="col-12 col-lg-9 align-items-center">
|
||||
<div class="row">
|
||||
@@ -266,6 +267,20 @@
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await ReloadAllData();
|
||||
await JSRuntime.InvokeVoidAsync("displayQr", "qrCodeImg", rawCode);
|
||||
}
|
||||
|
||||
protected string rawCode
|
||||
{
|
||||
get
|
||||
{
|
||||
string answ = "";
|
||||
if (_currItem != null)
|
||||
{
|
||||
answ = _currItem.OrderCode;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task ReloadAllData()
|
||||
@@ -290,17 +305,17 @@
|
||||
return q[parmName] ?? "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce URL immagine QRCode
|
||||
/// </summary>
|
||||
/// <param name="QrValue">Parametro da renderizzare con QRCode</param>
|
||||
/// <returns></returns>
|
||||
protected string getImgUrl(object QrValue)
|
||||
{
|
||||
string baseUrl = $"{Configuration["ZCodeUrl"]}/HOME/QR_site/JSON?val=";
|
||||
string payload = "{'baseUrl':'{0}','parameters':['" + $"{QrValue}" + "']}";
|
||||
string answ = $"{baseUrl}{payload}";
|
||||
return answ;
|
||||
}
|
||||
///// <summary>
|
||||
///// Restituisce URL immagine QRCode
|
||||
///// </summary>
|
||||
///// <param name="QrValue">Parametro da renderizzare con QRCode</param>
|
||||
///// <returns></returns>
|
||||
//protected string getImgUrl(object QrValue)
|
||||
//{
|
||||
// string baseUrl = $"{Configuration["ZCodeUrl"]}/HOME/QR_site/JSON?val=";
|
||||
// string payload = "{'baseUrl':'{0}','parameters':['" + $"{QrValue}" + "']}";
|
||||
// string answ = $"{baseUrl}{payload}";
|
||||
// return answ;
|
||||
//}
|
||||
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
@inject MessageService AppMService
|
||||
@inject GWMSDataService DataService
|
||||
@inject IConfiguration Configuration
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header bg-info text-light">
|
||||
@@ -17,10 +18,11 @@
|
||||
<EditForm Model="@_currItem">
|
||||
<DataAnnotationsValidator />
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-2">
|
||||
<img src="@getImgUrl(_currItem.OrderCode)" class="img-fluid" width="85" />
|
||||
<div class="col-12 col-lg-1">
|
||||
<div id="qrCodeImg"></div>
|
||||
@*<img src="@getImgUrl(_currItem.OrderCode)" class="img-fluid" width="85" />*@
|
||||
</div>
|
||||
<div class="col-12 col-lg-8 align-items-center">
|
||||
<div class="col-12 col-lg-9 align-items-center">
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
@@ -138,6 +140,20 @@
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await ReloadAllData();
|
||||
await JSRuntime.InvokeVoidAsync("displayQr", "qrCodeImg", rawCode);
|
||||
}
|
||||
|
||||
protected string rawCode
|
||||
{
|
||||
get
|
||||
{
|
||||
string answ = "";
|
||||
if (_currItem != null)
|
||||
{
|
||||
answ = _currItem.OrderCode;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task ReloadAllData()
|
||||
@@ -145,17 +161,17 @@
|
||||
transpList = await DataService.TransportersGetAll();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce URL immagine QRCode
|
||||
/// </summary>
|
||||
/// <param name="QrValue">Parametro da renderizzare con QRCode</param>
|
||||
/// <returns></returns>
|
||||
protected string getImgUrl(object QrValue)
|
||||
{
|
||||
string baseUrl = $"{Configuration["ZCodeUrl"]}/HOME/QR_site/JSON?val=";
|
||||
string payload = "{'baseUrl':'{0}','parameters':['" + $"{QrValue}" + "']}";
|
||||
string answ = $"{baseUrl}{payload}";
|
||||
return answ;
|
||||
}
|
||||
///// <summary>
|
||||
///// Restituisce URL immagine QRCode
|
||||
///// </summary>
|
||||
///// <param name="QrValue">Parametro da renderizzare con QRCode</param>
|
||||
///// <returns></returns>
|
||||
//protected string getImgUrl(object QrValue)
|
||||
//{
|
||||
// string baseUrl = $"{Configuration["ZCodeUrl"]}/HOME/QR_site/JSON?val=";
|
||||
// string payload = "{'baseUrl':'{0}','parameters':['" + $"{QrValue}" + "']}";
|
||||
// string answ = $"{baseUrl}{payload}";
|
||||
// return answ;
|
||||
//}
|
||||
|
||||
}
|
||||
@@ -4,63 +4,67 @@
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using GWMS.UI.Data
|
||||
@using Microsoft.Extensions.Configuration
|
||||
@using Microsoft.JSInterop
|
||||
|
||||
@inject MessageService AppMService
|
||||
@inject GWMSDataService DataService
|
||||
@inject IConfiguration Configuration
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
<div class="card">
|
||||
@*<div class="card-header bg-info text-light">
|
||||
<b>Modifica</b>
|
||||
</div>*@
|
||||
<div class="card-body small p-1">
|
||||
<EditForm Model="@_currItem">
|
||||
<DataAnnotationsValidator />
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-2">
|
||||
<img src="@getImgUrl(_currItem.OrderCode)" class="img-fluid" />
|
||||
</div>
|
||||
<div class="col-12 col-lg-8 align-items-center">
|
||||
<div class="row small">
|
||||
<div class="col-12">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" style="width: 3em;">
|
||||
<span class="fas fa-truck" aria-hidden="true"></span>
|
||||
</span>
|
||||
@if (_currItem != null)
|
||||
{
|
||||
<EditForm Model="@_currItem">
|
||||
<DataAnnotationsValidator />
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-2 text-center">
|
||||
<div id="qrCodeImg"></div>
|
||||
@_currItem.OrderCode
|
||||
@*<img src="@getImgUrl(_currItem.OrderCode)" class="img-fluid" />*@
|
||||
</div>
|
||||
@*<div class="col-12 col-lg-8 align-items-center">
|
||||
<div class="row small">
|
||||
<div class="col-12">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" style="width: 3em;">
|
||||
<span class="fas fa-truck" aria-hidden="true"></span>
|
||||
</span>
|
||||
</div>
|
||||
<DateEdit @bind-Date="_currItem.DtETA" InputMode="DateInputMode.DateTime" class="form-control" title="ETA (previsione consegna)" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" style="width: 3em;">
|
||||
<span class="fas fa-comment-alt" aria-hidden="true"></span>
|
||||
</span>
|
||||
</div>
|
||||
<InputText id="OrderDesc" @bind-Value="_currItem.OrderDesc" class="form-control" title="Note Ordine (opzionali)" />
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">
|
||||
Note
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<DateEdit @bind-Date="_currItem.DtETA" InputMode="DateInputMode.DateTime" class="form-control" title="ETA (previsione consegna)" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" style="width: 3em;">
|
||||
<span class="fas fa-comment-alt" aria-hidden="true"></span>
|
||||
</span>
|
||||
</div>
|
||||
<InputText id="OrderDesc" @bind-Value="_currItem.OrderDesc" class="form-control" title="Note Ordine (opzionali)" />
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">
|
||||
Note
|
||||
</span>
|
||||
</div>
|
||||
</div>*@
|
||||
<div class="col-12 col-lg-2">
|
||||
<div class="row">
|
||||
@*<div class="col">
|
||||
<button type="button" class="btn btn-sm btn-success btn-block" value="Save" @onclick="saveUpdate">Save <i class="far fa-save"></i></button>
|
||||
</div>*@
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-sm btn-warning btn-block" value="Cancel" @onclick="cancelUpdate">Cancel <i class="fas fa-ban"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-2">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<button type="button" class="btn btn-sm btn-success btn-block" value="Save" @onclick="saveUpdate">Save <i class="far fa-save"></i></button>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<button type="button" class="btn btn-sm btn-warning btn-block" value="Cancel" @onclick="cancelUpdate">Cancel <i class="fas fa-ban"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</EditForm>
|
||||
</EditForm>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -76,7 +80,7 @@
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currItem = null;
|
||||
return _currItem;
|
||||
}
|
||||
set
|
||||
{
|
||||
@@ -84,6 +88,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
public async void refreshQr()
|
||||
{
|
||||
await JSRuntime.InvokeVoidAsync("refreshQr", rawCode);
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<int> DataReset { get; set; }
|
||||
[Parameter]
|
||||
@@ -122,9 +131,23 @@
|
||||
await DataReset.InvokeAsync(0);
|
||||
}
|
||||
|
||||
protected string rawCode
|
||||
{
|
||||
get
|
||||
{
|
||||
string answ = "";
|
||||
if (_currItem != null)
|
||||
{
|
||||
answ = _currItem.OrderCode;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await ReloadAllData();
|
||||
await JSRuntime.InvokeVoidAsync("displayQr", "qrCodeImg", rawCode);
|
||||
}
|
||||
|
||||
protected async Task ReloadAllData()
|
||||
@@ -132,17 +155,17 @@
|
||||
transpList = await DataService.TransportersGetAll();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce URL immagine QRCode
|
||||
/// </summary>
|
||||
/// <param name="QrValue">Parametro da renderizzare con QRCode</param>
|
||||
/// <returns></returns>
|
||||
protected string getImgUrl(object QrValue)
|
||||
{
|
||||
string baseUrl = $"{Configuration["ZCodeUrl"]}/HOME/QR_site/JSON?val=";
|
||||
string payload = "{'baseUrl':'{0}','parameters':['" + $"{QrValue}" + "']}";
|
||||
string answ = $"{baseUrl}{payload}";
|
||||
return answ;
|
||||
}
|
||||
///// <summary>
|
||||
///// Restituisce URL immagine QRCode
|
||||
///// </summary>
|
||||
///// <param name="QrValue">Parametro da renderizzare con QRCode</param>
|
||||
///// <returns></returns>
|
||||
//protected string getImgUrl(object QrValue)
|
||||
//{
|
||||
// string baseUrl = $"{Configuration["ZCodeUrl"]}/HOME/QR_site/JSON?val=";
|
||||
// string payload = "{'baseUrl':'{0}','parameters':['" + $"{QrValue}" + "']}";
|
||||
// string answ = $"{baseUrl}{payload}";
|
||||
// return answ;
|
||||
//}
|
||||
|
||||
}
|
||||
@@ -49,25 +49,28 @@
|
||||
<li class="list-group-item active d-flex justify-content-between align-items-center">SERBATOIO Principale</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div class="row">
|
||||
<div class="col-12 px-0">
|
||||
<LineChart @ref="LevelVal" TItem="double" OptionsObject="lineChartOptions" />
|
||||
@*<div class="col-4 small">
|
||||
@currItem.LevelAct.ToString("N0")
|
||||
</div>*@
|
||||
<div class="col-12 text-center small">
|
||||
<span><i class="fas fa-database"></i> Livello: </span> <span style="font-size:1.2em;"><b>@currItem.LevelRatio</b> <sub>%</sub></span> <span>(@currItem.LevelAct.ToString("N0")/@currItem.LevelMax.ToString("N0"))</span>
|
||||
</div>
|
||||
<div class="col-6 small">
|
||||
@currItem.LevelAct.ToString("N0")
|
||||
</div>
|
||||
<div class="col-6 text-right small">
|
||||
@currItem.LevelMax.ToString("N0")
|
||||
</div>
|
||||
<div class="col-12">
|
||||
@*<div class="col-4 text-right small">
|
||||
@currItem.LevelMax.ToString("N0")
|
||||
</div>*@
|
||||
<div class="col-12 small">
|
||||
<Progress>
|
||||
<ProgressBar Value="@currItem.LevelRatio" Striped="false" Animated="false" />
|
||||
</Progress>
|
||||
</div>
|
||||
<div class="col-12 px-0 mt-2">
|
||||
<LineChart @ref="LevelVal" TItem="double" OptionsObject="lineChartOptions" />
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<span><i class="fas fa-database"></i> Livello</span> <span style="font-size:1.2em;"><b>@currItem.LevelRatio</b> <sub>%</sub></span>
|
||||
</li>
|
||||
@*<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<span><i class="fas fa-database"></i> Livello</span> <span style="font-size:1.2em;"><b>@currItem.LevelRatio</b> <sub>%</sub></span>
|
||||
</li>*@
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<span><i class="fas fa-compress-arrows-alt"></i> Pressione</span> <span style="font-size:1.2em;"><b>@currItem.PressAct["Main"].ToString("N1")</b> <span class="small"> <sub>bar</sub></span></span>
|
||||
</li>
|
||||
|
||||
@@ -7,6 +7,7 @@ using GWMS.Data.DTO;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Blazorise.Charts;
|
||||
using System.Threading;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace GWMS.UI.Components
|
||||
{
|
||||
@@ -24,23 +25,25 @@ namespace GWMS.UI.Components
|
||||
{
|
||||
XAxes = new object[]
|
||||
{
|
||||
new {
|
||||
Display = true,
|
||||
//type = "timeseries",
|
||||
//type = "time",
|
||||
//Time = new {
|
||||
// unit="day"
|
||||
//}
|
||||
}
|
||||
},
|
||||
new {
|
||||
display = true,
|
||||
//type = "timeseries",
|
||||
//type = "time",
|
||||
//Time = new {
|
||||
// unit="day"
|
||||
//}
|
||||
}
|
||||
},
|
||||
YAxes = new object[]
|
||||
{
|
||||
new {
|
||||
Display = true,
|
||||
ticks= new {
|
||||
suggestedMin = 0,
|
||||
suggestedMax = 10000
|
||||
}
|
||||
display = true,
|
||||
position = "right",
|
||||
//text = "Kg",
|
||||
ticks = new {
|
||||
suggestedMin = 0,
|
||||
suggestedMax = 10000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -54,8 +57,14 @@ namespace GWMS.UI.Components
|
||||
Mode = "nearest",
|
||||
Intersect = false
|
||||
},
|
||||
Animation = false,
|
||||
AspectRatio = 2
|
||||
Animation = true,
|
||||
Responsive = true,
|
||||
AspectRatio = 2,
|
||||
type = "line",
|
||||
Legend = new
|
||||
{
|
||||
display = false
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -67,6 +76,9 @@ namespace GWMS.UI.Components
|
||||
|
||||
#region Private Properties
|
||||
|
||||
[Inject]
|
||||
private IConfiguration Configuration { get; set; }
|
||||
|
||||
[Inject]
|
||||
private NavigationManager NavManager { get; set; }
|
||||
|
||||
@@ -119,7 +131,9 @@ namespace GWMS.UI.Components
|
||||
var dataReload = Task.Run(async () =>
|
||||
{
|
||||
// aggiunta delay o non riesce a disegnare
|
||||
Thread.Sleep(50);
|
||||
int ChartWaitDelay = 150;
|
||||
int.TryParse(Configuration["ChartWaitDelay"], out ChartWaitDelay);
|
||||
Thread.Sleep(ChartWaitDelay);
|
||||
await HandleRedraw();
|
||||
});
|
||||
}
|
||||
@@ -134,12 +148,15 @@ namespace GWMS.UI.Components
|
||||
{
|
||||
int answ = 1;
|
||||
int numCount = _currItem.LevelTS.Count;
|
||||
// passo a 2h se > 5 gg
|
||||
if (numCount > 120)
|
||||
// passo a 2h se > 3 gg
|
||||
if (numCount > 72)
|
||||
answ = 2;
|
||||
// passo a 3h se > 10 gg
|
||||
else if (numCount > 240)
|
||||
// passo a 3h se > 5 gg
|
||||
else if (numCount > 120)
|
||||
answ = 3;
|
||||
// passo a 4h se > 10 gg
|
||||
else if (numCount > 240)
|
||||
answ = 4;
|
||||
redFact = answ;
|
||||
}
|
||||
|
||||
|
||||
+29
-16
@@ -2,13 +2,26 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<Version>1.0.2108.2516</Version>
|
||||
<Version>1.0.2108.2713</Version>
|
||||
<UserSecretsId>95c9f021-52d1-4390-a670-5810b7b777b0</UserSecretsId>
|
||||
<EnableNETAnalyzers>true</EnableNETAnalyzers>
|
||||
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
|
||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="QuartzHostedService.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="bundleconfig.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS02.pubxml" />
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IISProfile.pubxml" />
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IISProfileLinux.pubxml" />
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\IISProfileWin.pubxml" />
|
||||
<_WebToolingArtifacts Remove="Properties\PublishProfiles\W2019-IIS-DEV.pubxml" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -25,31 +38,31 @@
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="5.0.1" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.Uris" Version="5.0.1" />
|
||||
<PackageReference Include="BlazorBarcodeScanner.ZXing.JS" Version="0.2.4" />
|
||||
<PackageReference Include="Blazorise" Version="0.9.3.7" />
|
||||
<PackageReference Include="Blazorise.Bootstrap" Version="0.9.3.7" />
|
||||
<PackageReference Include="Blazorise.Charts" Version="0.9.3.7" />
|
||||
<PackageReference Include="Blazorise.Components" Version="0.9.3.7" />
|
||||
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="0.9.3.7" />
|
||||
<PackageReference Include="ElmahCore" Version="2.0.6" />
|
||||
<PackageReference Include="ElmahCore.Common" Version="2.0.6" />
|
||||
<PackageReference Include="ElmahCore.Sql" Version="2.0.6" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="5.0.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="5.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.7">
|
||||
<PackageReference Include="Blazorise" Version="0.9.4.3" />
|
||||
<PackageReference Include="Blazorise.Bootstrap" Version="0.9.4.3" />
|
||||
<PackageReference Include="Blazorise.Charts" Version="0.9.4.3" />
|
||||
<PackageReference Include="Blazorise.Components" Version="0.9.4.3" />
|
||||
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="0.9.4.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="5.0.9" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.9" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="5.0.9" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.9">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="5.0.1" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.12.0" />
|
||||
<PackageReference Include="Quartz" Version="3.3.2" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" ExcludeAssets="All" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.13.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Services\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="bundleconfig.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Pages\Transporters - Copy - Copy.razor.cs">
|
||||
<DependentUpon>Transporters - Copy.razor.cs</DependentUpon>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using BlazorBarcodeScanner.ZXing.JS;
|
||||
using GWMS.Data.DatabaseModels;
|
||||
using GWMS.Data.DTO;
|
||||
using GWMS.UI.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.JSInterop;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,6 +12,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace GWMS.UI.Pages
|
||||
{
|
||||
[Authorize(Roles = "SuperAdmin, Admin, User")]
|
||||
public partial class GasStation : ComponentBase, IDisposable
|
||||
{
|
||||
#region Private Fields
|
||||
@@ -19,8 +21,19 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// Valore PlantId filtrato da claim
|
||||
/// </summary>
|
||||
protected int ClaimPlantId = -1;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private bool isLoading { get; set; } = false;
|
||||
|
||||
private int SelPlantId
|
||||
{
|
||||
get
|
||||
@@ -47,6 +60,9 @@ namespace GWMS.UI.Pages
|
||||
|
||||
protected string _plantCode { get; set; } = "";
|
||||
|
||||
[Inject]
|
||||
protected AuthenticationStateProvider AuthenticationStateProvider { get; set; }
|
||||
|
||||
[Inject]
|
||||
protected GWMSDataService DataService { get; set; }
|
||||
|
||||
@@ -97,12 +113,59 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Recupero Claims dell'utente...
|
||||
///
|
||||
/// https://docs.microsoft.com/it-it/aspnet/core/blazor/security/?view=aspnetcore-5.0
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task GetClaimsData()
|
||||
{
|
||||
// recupero auth
|
||||
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||
var user = authState.User;
|
||||
// se autenticato --> controllo i claims
|
||||
if (user.Identity.IsAuthenticated)
|
||||
{
|
||||
// cerco il claim PlantId...
|
||||
var plantClaim = user.FindFirst(c => c.Type == "PlantId")?.Value;
|
||||
int.TryParse(plantClaim, out ClaimPlantId);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClaimPlantId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void LocalReceivedBarcodeText(BarcodeReceivedEventArgs args)
|
||||
{
|
||||
// rimando a pagina con codice ordine....
|
||||
NavManager.NavigateTo($"GasStation/{args.BarcodeText}");
|
||||
}
|
||||
|
||||
private async Task reloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
PlantsList = null;
|
||||
await GetClaimsData();
|
||||
// se ho un plantId valido --> altrimenti non abilitato
|
||||
if (ClaimPlantId == 0)
|
||||
{
|
||||
PlantsList = await DataService.PlantsGetAll();
|
||||
}
|
||||
else if (ClaimPlantId > 0)
|
||||
{
|
||||
var rawData = await DataService.PlantsGetAll();
|
||||
PlantsList = rawData.Where(x => x.PlantId == ClaimPlantId).ToList();
|
||||
SelPlantId = ClaimPlantId;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlantsList = new List<PlantDTO>();
|
||||
}
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
|
||||
#region Protected Methods
|
||||
@@ -112,7 +175,7 @@ namespace GWMS.UI.Pages
|
||||
MessageService.ShowSearch = false;
|
||||
MessageService.PageName = "Stazione";
|
||||
MessageService.PageIcon = "fas fa-gas-pump pr-2";
|
||||
PlantsList = await DataService.PlantsGetAll();
|
||||
await reloadData();
|
||||
}
|
||||
|
||||
protected void ResetData()
|
||||
|
||||
@@ -132,7 +132,20 @@
|
||||
@foreach (var record in ListRecords)
|
||||
{
|
||||
<tr class="@checkSelect(@record.OrderId)">
|
||||
<td class="text-nowrap"><button class="btn btn-sm btn-info" @onclick="() => Edit(record)"><span class="oi oi-pencil"></span></button></td>
|
||||
<td class="text-nowrap">
|
||||
@if (currRecord == null)
|
||||
{
|
||||
<button class="btn btn-sm btn-info" @onclick="() => Edit(record)">
|
||||
<span class="oi oi-pencil"></span>
|
||||
</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-secondary disabled">
|
||||
<i class="oi oi-pencil"></i>
|
||||
</button>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
<div>@record.Plant.PlantCode</div>
|
||||
<div class="small">@record.Plant.PlantDesc</div>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using GWMS.Data.DatabaseModels;
|
||||
using GWMS.Data.DTO;
|
||||
using GWMS.UI.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.JSInterop;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -10,6 +12,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace GWMS.UI.Pages
|
||||
{
|
||||
[Authorize(Roles = "SuperAdmin, Admin, User")]
|
||||
public partial class Orders : ComponentBase, IDisposable
|
||||
{
|
||||
#region Private Fields
|
||||
@@ -23,6 +26,15 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// Valore PlantId filtrato da claim
|
||||
/// </summary>
|
||||
protected int ClaimPlantId = -1;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private int _currPage { get; set; } = 1;
|
||||
@@ -134,6 +146,9 @@ namespace GWMS.UI.Pages
|
||||
[Inject]
|
||||
protected MessageService AppMService { get; set; }
|
||||
|
||||
[Inject]
|
||||
protected AuthenticationStateProvider AuthenticationStateProvider { get; set; }
|
||||
|
||||
[Inject]
|
||||
protected GWMSDataService DataService { get; set; }
|
||||
|
||||
@@ -218,6 +233,30 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Recupero Claims dell'utente...
|
||||
///
|
||||
/// https://docs.microsoft.com/it-it/aspnet/core/blazor/security/?view=aspnetcore-5.0
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task GetClaimsData()
|
||||
{
|
||||
// recupero auth
|
||||
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||
var user = authState.User;
|
||||
// se autenticato --> controllo i claims
|
||||
if (user.Identity.IsAuthenticated)
|
||||
{
|
||||
// cerco il claim PlantId...
|
||||
var plantClaim = user.FindFirst(c => c.Type == "PlantId")?.Value;
|
||||
int.TryParse(plantClaim, out ClaimPlantId);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClaimPlantId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDateEndChanged(DateTime? date)
|
||||
{
|
||||
DateEnd = (DateTime)date;
|
||||
@@ -298,8 +337,28 @@ namespace GWMS.UI.Pages
|
||||
|
||||
protected async Task ReloadAllData()
|
||||
{
|
||||
PlantsList = await DataService.PlantsGetAll();
|
||||
isLoading = true;
|
||||
//PlantsList = await DataService.PlantsGetAll();
|
||||
SuppliersList = await DataService.SuppliersGetAll();
|
||||
PlantsList = null;
|
||||
await GetClaimsData();
|
||||
// se ho un plantId valido --> altrimenti non abilitato
|
||||
if (ClaimPlantId == 0)
|
||||
{
|
||||
PlantsList = await DataService.PlantsGetAll();
|
||||
}
|
||||
else if (ClaimPlantId > 0)
|
||||
{
|
||||
var rawData = await DataService.PlantsGetAll();
|
||||
PlantsList = rawData.Where(x => x.PlantId == ClaimPlantId).ToList();
|
||||
SelPlantId = ClaimPlantId;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlantsList = new List<PlantDTO>();
|
||||
}
|
||||
isLoading = false;
|
||||
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
@using GWMS.UI.Components
|
||||
|
||||
<div class="row">
|
||||
|
||||
@if (ListRecords == null)
|
||||
{
|
||||
<div class="col-12">
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using GWMS.Data.DTO;
|
||||
using GWMS.UI.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.JSInterop;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using GWMS.Data.DTO;
|
||||
|
||||
namespace GWMS.UI.Pages
|
||||
{
|
||||
[Authorize(Roles = "SuperAdmin, Admin, User")]
|
||||
public partial class PlantStatus : ComponentBase, IDisposable
|
||||
{
|
||||
#region Private Fields
|
||||
@@ -19,6 +24,15 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// Valore PlantId filtrato da claim
|
||||
/// </summary>
|
||||
protected int ClaimPlantId = -1;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private bool isLoading { get; set; } = false;
|
||||
@@ -29,6 +43,9 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected AuthenticationStateProvider AuthenticationStateProvider { get; set; }
|
||||
|
||||
[Inject]
|
||||
protected GWMSDataService DataService { get; set; }
|
||||
|
||||
@@ -58,10 +75,49 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Recupero Claims dell'utente...
|
||||
///
|
||||
/// https://docs.microsoft.com/it-it/aspnet/core/blazor/security/?view=aspnetcore-5.0
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task GetClaimsData()
|
||||
{
|
||||
// recupero auth
|
||||
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||
var user = authState.User;
|
||||
// se autenticato --> controllo i claims
|
||||
if (user.Identity.IsAuthenticated)
|
||||
{
|
||||
// cerco il claim PlantId...
|
||||
var plantClaim = user.FindFirst(c => c.Type == "PlantId")?.Value;
|
||||
int.TryParse(plantClaim, out ClaimPlantId);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClaimPlantId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task reloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
ListRecords = await DataService.PlantsGetAll();
|
||||
ListRecords = null;
|
||||
await GetClaimsData();
|
||||
// se ho un plantId valido --> altrimenti non abilitato
|
||||
if (ClaimPlantId == 0)
|
||||
{
|
||||
ListRecords = await DataService.PlantsGetAll();
|
||||
}
|
||||
else if (ClaimPlantId > 0)
|
||||
{
|
||||
var rawData = await DataService.PlantsGetAll();
|
||||
ListRecords = rawData.Where(x => x.PlantId == ClaimPlantId).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
ListRecords = new List<PlantDTO>();
|
||||
}
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,13 +12,19 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@*<meta name="viewport" content="width=device-width, initial-scale=1.0" />*@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<title>GWMS User Management</title>
|
||||
<title>GWMS.UI User Management</title>
|
||||
<base href="~/" />
|
||||
<link rel="stylesheet" href="~/Identity/lib/bootstrap/dist/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="font-awesome/css/fontawesome.min.css" />
|
||||
<link href="_content/Blazorise/blazorise.css" rel="stylesheet" />
|
||||
<link href="_content/Blazorise.Bootstrap/blazorise.bootstrap.css" rel="stylesheet" />
|
||||
<link href="css/site.css" rel="stylesheet" />
|
||||
<link href="GWMS.UI.styles.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="~/Identity/css/site.css" />
|
||||
<link rel="stylesheet" href="~/css/site.css" />
|
||||
|
||||
@*<link rel="stylesheet" href="~/Identity/lib/bootstrap/dist/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="~/css/site.css" />*@
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
@@ -55,13 +61,14 @@
|
||||
</div>
|
||||
<footer class="footer border-top text-muted fixed-bottom bottom-row bg-dark py-0 my-0">
|
||||
<div class="container py-1">
|
||||
© 2021 - GWMS User Management- <a asp-area="" asp-page="Privacy">Privacy</a>
|
||||
© 2021+ | GWMS.UI User Management
|
||||
</div>
|
||||
<CmpFooter></CmpFooter>
|
||||
</footer>
|
||||
<script src="~/Identity/lib/jquery/dist/jquery.min.js"></script>
|
||||
<script src="~/Identity/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="~/Identity/js/site.js" asp-append-version="true"></script>
|
||||
<script src="font-awesome/js/all.js"></script>
|
||||
@RenderSection("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
||||
@@ -105,7 +105,20 @@
|
||||
@foreach (var record in ListRecords)
|
||||
{
|
||||
<tr class="@checkSelect(@record.OrderId)">
|
||||
<td class="text-nowrap"><button class="btn btn-sm btn-info" @onclick="() => Edit(record)"><span class="oi oi-pencil"></span></button></td>
|
||||
<td class="text-nowrap">
|
||||
@if (currRecord == null)
|
||||
{
|
||||
<button class="btn btn-sm btn-info" @onclick="() => Edit(record)">
|
||||
<span class="oi oi-pencil"></span>
|
||||
</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-secondary disabled">
|
||||
<i class="oi oi-pencil"></i>
|
||||
</button>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
<div>@record.Plant.PlantCode</div>
|
||||
<div class="small">@record.Plant.PlantDesc</div>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using GWMS.Data.DatabaseModels;
|
||||
using GWMS.Data.DTO;
|
||||
using GWMS.UI.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.JSInterop;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -10,6 +12,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace GWMS.UI.Pages
|
||||
{
|
||||
[Authorize(Roles = "SuperAdmin, Admin, ExtUser")]
|
||||
public partial class Suppliers : ComponentBase, IDisposable
|
||||
{
|
||||
#region Private Fields
|
||||
@@ -23,6 +26,15 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
/// <summary>
|
||||
/// Valore SupplierId filtrato da claim
|
||||
/// </summary>
|
||||
protected int ClaimSupplierId = -1;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private int _currPage { get; set; } = 1;
|
||||
@@ -109,6 +121,9 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected AuthenticationStateProvider AuthenticationStateProvider { get; set; }
|
||||
|
||||
[Inject]
|
||||
protected GWMSDataService DataService { get; set; }
|
||||
|
||||
@@ -165,16 +180,6 @@ namespace GWMS.UI.Pages
|
||||
[Inject]
|
||||
protected NavigationManager NavManager { get; set; }
|
||||
|
||||
protected int SupplierIdFilt
|
||||
{
|
||||
get
|
||||
{
|
||||
int answ = 0;
|
||||
int.TryParse(SupplierIdReq, out answ);
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
protected int totalCount
|
||||
{
|
||||
get
|
||||
@@ -199,6 +204,30 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Recupero Claims dell'utente...
|
||||
///
|
||||
/// https://docs.microsoft.com/it-it/aspnet/core/blazor/security/?view=aspnetcore-5.0
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task GetClaimsData()
|
||||
{
|
||||
// recupero auth
|
||||
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||
var user = authState.User;
|
||||
// se autenticato --> controllo i claims
|
||||
if (user.Identity.IsAuthenticated)
|
||||
{
|
||||
// cerco il claim PlantId...
|
||||
var supplierClaim = user.FindFirst(c => c.Type == "SupplierId")?.Value;
|
||||
int.TryParse(supplierClaim, out ClaimSupplierId);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClaimSupplierId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDateEndChanged(DateTime? date)
|
||||
{
|
||||
DateEnd = (DateTime)date;
|
||||
@@ -247,9 +276,26 @@ namespace GWMS.UI.Pages
|
||||
|
||||
protected async Task ReloadAllData()
|
||||
{
|
||||
isLoading = true;
|
||||
SuppliersList = null;
|
||||
await GetClaimsData();
|
||||
PlantsList = await DataService.PlantsGetAll();
|
||||
var suppliersAll = await DataService.SuppliersGetAll();
|
||||
SuppliersList = suppliersAll.Where(x => x.SupplierId == SupplierIdFilt || SupplierIdFilt == 0).ToList();
|
||||
// se ho un plantId valido --> altrimenti non abilitato
|
||||
if (ClaimSupplierId == 0)
|
||||
{
|
||||
SuppliersList = await DataService.SuppliersGetAll();
|
||||
}
|
||||
else if (ClaimSupplierId > 0)
|
||||
{
|
||||
var rawData = await DataService.SuppliersGetAll();
|
||||
SuppliersList = rawData.Where(x => x.SupplierId == ClaimSupplierId).ToList();
|
||||
SelSupplierId = ClaimSupplierId;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlantsList = new List<PlantDTO>();
|
||||
}
|
||||
isLoading = false;
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,18 +8,15 @@
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="row">
|
||||
<div class="col-6 pr-0 col-lg-8 h3">
|
||||
<div class="col-6 pr-0 col-lg-8 h3 mb-0">
|
||||
Consegne
|
||||
</div>
|
||||
<div class="col-6 col-lg-4">
|
||||
<div class="row">
|
||||
<div class="col-6 px-1">
|
||||
<div class="col-6">
|
||||
<button class="btn btn-sm btn-block btn-secondary" @onclick="() => ToggleFiltPeriod()"><i class="far fa-calendar-alt"></i> <i class="@icnFiltTime"></i></button>
|
||||
</div>
|
||||
@*<div class="col-4 px-1">
|
||||
<button class="btn btn-sm btn-block btn-secondary" @onclick="() => ToggleFiltTransp()"><i class="fas fa-truck-moving"></i> <i class="@icnFiltTran"></i></button>
|
||||
</div>*@
|
||||
<div class="col-6 px-1">
|
||||
<div class="col-6">
|
||||
<button class="btn btn-sm btn-block btn-secondary" @onclick="() => ToggleFiltDest()"><i class="fas fa-gas-pump"></i> <i class="@icnFiltDest"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -90,7 +87,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-1">
|
||||
<div class="card-body">
|
||||
@if (currRecord != null)
|
||||
{
|
||||
<OrderTranspEditor currItem="@currRecord" DataReset="ResetData" DataUpdated="UpdateData" SupplierId="@currRecord.SupplierId"></OrderTranspEditor>
|
||||
@@ -107,6 +104,7 @@
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@*<div id="qrCodeImg"></div>*@
|
||||
<table class="table table-sm table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -119,7 +117,20 @@
|
||||
@foreach (var record in ListRecords)
|
||||
{
|
||||
<tr class="@checkSelect(@record.OrderId)">
|
||||
<td class="text-nowrap"><button class="btn btn-sm btn-info" @onclick="() => Edit(record)"><span class="oi oi-magnifying-glass"></span></button></td>
|
||||
<td class="text-nowrap">
|
||||
@if (currRecord == null)
|
||||
{
|
||||
<button class="btn btn-sm btn-info" @onclick="() => Edit(record)">
|
||||
<i class="oi oi-magnifying-glass"></i>
|
||||
</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-sm btn-secondary disabled">
|
||||
<i class="oi oi-magnifying-glass"></i>
|
||||
</button>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
<div><b>@record.Plant.PlantCode</b> | @record.Plant.PlantDesc</div>
|
||||
<div class="small"><span class="fas fa-comment-alt" aria-hidden="true"></span> @record.OrderDesc</div>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using GWMS.Data.DatabaseModels;
|
||||
using GWMS.Data.DTO;
|
||||
using GWMS.UI.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.JSInterop;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -10,6 +12,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace GWMS.UI.Pages
|
||||
{
|
||||
[Authorize(Roles = "SuperAdmin, Admin, ExtTransp")]
|
||||
public partial class Transporters : ComponentBase, IDisposable
|
||||
{
|
||||
#region Private Fields
|
||||
@@ -24,6 +27,14 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
/// Valore TransporterId filtrato da claim
|
||||
/// </summary>
|
||||
protected int ClaimTransporterId = -1;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private int _currPage { get; set; } = 1;
|
||||
@@ -134,6 +145,9 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected AuthenticationStateProvider AuthenticationStateProvider { get; set; }
|
||||
|
||||
[Inject]
|
||||
protected GWMSDataService DataService { get; set; }
|
||||
|
||||
@@ -193,6 +207,7 @@ namespace GWMS.UI.Pages
|
||||
protected bool showFiltDest { get; set; } = false;
|
||||
|
||||
protected bool showFiltTime { get; set; } = false;
|
||||
|
||||
protected bool showFiltTrasp { get; set; } = false;
|
||||
|
||||
protected int totalCount
|
||||
@@ -212,6 +227,30 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Recupero Claims dell'utente...
|
||||
///
|
||||
/// https://docs.microsoft.com/it-it/aspnet/core/blazor/security/?view=aspnetcore-5.0
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task GetClaimsData()
|
||||
{
|
||||
// recupero auth
|
||||
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||
var user = authState.User;
|
||||
// se autenticato --> controllo i claims
|
||||
if (user.Identity.IsAuthenticated)
|
||||
{
|
||||
// cerco il claim PlantId...
|
||||
var supplierClaim = user.FindFirst(c => c.Type == "TransporterId")?.Value;
|
||||
int.TryParse(supplierClaim, out ClaimTransporterId);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClaimTransporterId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDateEndChanged(DateTime? date)
|
||||
{
|
||||
currRecord = null;
|
||||
@@ -265,8 +304,27 @@ namespace GWMS.UI.Pages
|
||||
|
||||
protected async Task ReloadAllData()
|
||||
{
|
||||
isLoading = true;
|
||||
PlantsList = await DataService.PlantsGetAll();
|
||||
TransportersList = await DataService.TransportersGetAll();
|
||||
TransportersList = null;
|
||||
await GetClaimsData();
|
||||
// se ho un plantId valido --> altrimenti non abilitato
|
||||
if (ClaimTransporterId == 0)
|
||||
{
|
||||
TransportersList = await DataService.TransportersGetAll();
|
||||
}
|
||||
else if (ClaimTransporterId > 0)
|
||||
{
|
||||
var rawData = await DataService.TransportersGetAll();
|
||||
TransportersList = rawData.Where(x => x.TransporterId == ClaimTransporterId).ToList();
|
||||
SelTranspId = ClaimTransporterId;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlantsList = new List<PlantDTO>();
|
||||
}
|
||||
isLoading = false;
|
||||
|
||||
await ReloadData();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@page "/UserAdmin"
|
||||
|
||||
@using GWMS.UI.Pages
|
||||
@using GWMS.UI.Components
|
||||
|
||||
@if (ShowPopup)
|
||||
{
|
||||
@@ -168,6 +169,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="card-footer p-1">
|
||||
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -27,10 +27,15 @@ namespace GWMS.UI.Pages
|
||||
/// </summary>
|
||||
private IdentityUser objUser = new IdentityUser();
|
||||
|
||||
/// <summary>
|
||||
/// Collezione utenti
|
||||
/// </summary>
|
||||
private List<IdentityUser> RawList = new List<IdentityUser>();
|
||||
|
||||
/// <summary>
|
||||
/// Elenco ROLES da mostrare in dropdown durante editing (1 solo? usare DB?!?)
|
||||
/// </summary>
|
||||
private List<string> RolesList = new List<string>() { "Undef", "ExtUser", "User", "Admin", "SuperAdmin" };
|
||||
private List<string> RolesList = new List<string>() { "Undef", "ExtTransp", "ExtUser", "User", "Admin", "SuperAdmin" };
|
||||
|
||||
// To enable showing the Popup
|
||||
private bool ShowPopup = false;
|
||||
@@ -55,6 +60,10 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private int _currPage { get; set; } = 1;
|
||||
|
||||
private int _numRecord { get; set; } = 10;
|
||||
|
||||
[CascadingParameter]
|
||||
private Task<AuthenticationState> authenticationStateTask { get; set; }
|
||||
|
||||
@@ -78,6 +87,39 @@ namespace GWMS.UI.Pages
|
||||
/// </summary>
|
||||
private string CurrentUserRole { get; set; } = "User";
|
||||
|
||||
private int currPage
|
||||
{
|
||||
get => _currPage;
|
||||
set
|
||||
{
|
||||
if (_currPage != value)
|
||||
{
|
||||
_currPage = value;
|
||||
var pUpd = Task.Run(async () => await ReloadData());
|
||||
pUpd.Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool isLoading { get; set; } = false;
|
||||
|
||||
[Inject]
|
||||
private MessageService MessageService { get; set; }
|
||||
|
||||
private int numRecord
|
||||
{
|
||||
get => _numRecord;
|
||||
set
|
||||
{
|
||||
if (_numRecord != value)
|
||||
{
|
||||
_numRecord = value;
|
||||
var pUpd = Task.Run(async () => await ReloadData());
|
||||
pUpd.Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Protected Properties
|
||||
@@ -97,8 +139,33 @@ namespace GWMS.UI.Pages
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; }
|
||||
|
||||
protected int totalCount
|
||||
{
|
||||
get
|
||||
{
|
||||
int answ = 0;
|
||||
if (RawList != null)
|
||||
{
|
||||
answ = RawList.Count;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public string searchVal
|
||||
{
|
||||
get
|
||||
{
|
||||
return MessageService.SearchVal;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void AddNewUser()
|
||||
@@ -220,6 +287,13 @@ namespace GWMS.UI.Pages
|
||||
ShowPopup = true;
|
||||
}
|
||||
|
||||
private async Task ReloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
await GetUsers();
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
private async Task SaveUser()
|
||||
{
|
||||
try
|
||||
@@ -353,11 +427,22 @@ namespace GWMS.UI.Pages
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected void ForceReload(int newNum)
|
||||
{
|
||||
numRecord = newNum;
|
||||
}
|
||||
|
||||
protected void ForceReloadPage(int newNum)
|
||||
{
|
||||
currPage = newNum;
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
AppMService.ShowSearch = true;
|
||||
AppMService.PageName = "Gestione Utenti";
|
||||
AppMService.PageIcon = "fas fa-users pr-2";
|
||||
AppMService.EA_SearchUpdated += OnSeachUpdated;
|
||||
// lettura dati
|
||||
await GetUsers();
|
||||
await CheckSuperAdmin();
|
||||
@@ -374,6 +459,7 @@ namespace GWMS.UI.Pages
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
AppMService.EA_SearchUpdated -= OnSeachUpdated;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -386,7 +472,16 @@ namespace GWMS.UI.Pages
|
||||
// Collection to hold users
|
||||
UsersList = new List<UserData>();
|
||||
// get users from _UserManager
|
||||
var user = _UserManager.Users.Select(x => new IdentityUser
|
||||
var allData = _UserManager.Users.ToList();
|
||||
if (!string.IsNullOrEmpty(searchVal))
|
||||
{
|
||||
RawList = allData.Where(x => x.NormalizedEmail.Contains(searchVal.ToUpper()) || x.NormalizedUserName.Contains(searchVal.ToUpper())).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
RawList = allData;
|
||||
}
|
||||
var user = RawList.Skip(numRecord * (currPage - 1)).Take(numRecord).Select(x => new IdentityUser
|
||||
{
|
||||
Id = x.Id,
|
||||
UserName = x.UserName,
|
||||
@@ -411,6 +506,15 @@ namespace GWMS.UI.Pages
|
||||
}
|
||||
}
|
||||
|
||||
public async void OnSeachUpdated()
|
||||
{
|
||||
await GetUsers();
|
||||
await InvokeAsync(() =>
|
||||
{
|
||||
StateHasChanged();
|
||||
});
|
||||
}
|
||||
|
||||
public string ShowClaims(List<System.Security.Claims.Claim> ClaimList)
|
||||
{
|
||||
string answ = string.Join(",", ClaimList);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using GWMS.Data.DatabaseModels;
|
||||
using GWMS.Data.DTO;
|
||||
using GWMS.UI.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using System;
|
||||
@@ -11,6 +12,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace GWMS.UI.Pages
|
||||
{
|
||||
[Authorize(Roles = "SuperAdmin, Admin, User")]
|
||||
public partial class UserManager : ComponentBase, IDisposable
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using GWMS.Data.DatabaseModels;
|
||||
using GWMS.Data.DTO;
|
||||
using GWMS.UI.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using System;
|
||||
@@ -11,6 +12,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace GWMS.UI.Pages
|
||||
{
|
||||
[Authorize(Roles = "SuperAdmin, Admin")]
|
||||
public partial class WeekPlan : ComponentBase
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
+30
-12
@@ -13,17 +13,13 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
@*<meta name="viewport" content="width=device-width, initial-scale=1.0" />*@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<title>GWMS.UI</title>
|
||||
<base href="~/" />
|
||||
@*<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />*@
|
||||
|
||||
<!-- inside of head section -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
|
||||
<!--<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css"> -->
|
||||
|
||||
<link rel="stylesheet" href="font-awesome/css/fontawesome.css" />
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="font-awesome/css/fontawesome.min.css" />
|
||||
<link rel="stylesheet" href="Chart.js/Chart.min.css" />
|
||||
<link href="_content/Blazorise/blazorise.css" rel="stylesheet" />
|
||||
<link href="_content/Blazorise.Bootstrap/blazorise.bootstrap.css" rel="stylesheet" />
|
||||
|
||||
@@ -46,10 +42,10 @@
|
||||
</div>
|
||||
|
||||
<!-- inside of body section and after the div/app tag -->
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js" integrity="sha384-+YQ4JLhjyBLPDQt//I+STsc9iw4uQqACwlvpslubQzn4u2UU2UFM80nGisd026JF" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
|
||||
<script src="jquery/jquery.min.js"></script>
|
||||
<script src="Chart.js/Chart.min.js"></script>
|
||||
<script src="popper.js/umd/popper.min.js"></script>
|
||||
<script src="bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<script src="_content/Blazorise/blazorise.js"></script>
|
||||
<script src="_content/Blazorise.Bootstrap/blazorise.bootstrap.js"></script>
|
||||
@@ -58,7 +54,29 @@
|
||||
<script src="_content/BlazorBarcodeScanner.ZXing.JS/zxingjs.index.min.js"></script>
|
||||
<script src="_content/BlazorBarcodeScanner.ZXing.JS/BlazorBarcodeScanner.js"></script>
|
||||
|
||||
<script src="font-awesome/js/all.js"></script>
|
||||
<script src="font-awesome/js/all.min.js"></script>
|
||||
<script src="_framework/blazor.server.js"></script>
|
||||
|
||||
<script type="text/javascript" src="~/lib/qrcode.js"></script>
|
||||
<script type="text/javascript">
|
||||
// gestione qrcode... da https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity-enable-qrcodes?view=aspnetcore-5.0
|
||||
//var qrcode = new QRCode("qrCodeImg");
|
||||
function displayQr(elementName, rawData) {
|
||||
try {
|
||||
if (elementName != "" && rawData != "") {
|
||||
//qrcode = new QRCode(document.getElementById(elementName));
|
||||
new QRCode(document.getElementById(elementName),
|
||||
{
|
||||
text: rawData,
|
||||
width: 400,
|
||||
height: 400
|
||||
});
|
||||
//qrcode.makeCode(rawData);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
|
||||
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<TimeStampOfAssociatedLegacyPublishXmlFile />
|
||||
<EncryptedPassword>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAxNUOeyL5oUSNi/ISzvJtLgAAAAACAAAAAAADZgAAwAAAABAAAAD+ZfytfJJzf+XzD0ShcSagAAAAAASAAACgAAAAEAAAAAhSlOT4SIk7WdUrN1YS1qMYAAAAGI+89iBgQqaMJeEi4KxlVpTh9PMYTidkFAAAAO7so25722o8lxnn313D6J0eV2MV</EncryptedPassword>
|
||||
<History>False|2021-06-23T12:54:39.3412623Z;</History>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
|
||||
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<TimeStampOfAssociatedLegacyPublishXmlFile />
|
||||
<EncryptedPassword>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAxNUOeyL5oUSNi/ISzvJtLgAAAAACAAAAAAADZgAAwAAAABAAAAAwZbVLPZ+eVCZgVc7GoE8CAAAAAASAAACgAAAAEAAAAEmDwlS8G30J/kR5K+eX8B4YAAAAZ14uy/TVGN4ui4QHWpgdmwaMob7VeTSiFAAAAC/61bXCe/Mgyo7S2QBvJRJ2GUiZ</EncryptedPassword>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
|
||||
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<History>True|2021-06-23T13:11:40.1591388Z;</History>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
|
||||
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<WebPublishMethod>Package</WebPublishMethod>
|
||||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||
<SiteUrlToLaunchAfterPublish />
|
||||
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
|
||||
<ExcludeApp_Data>False</ExcludeApp_Data>
|
||||
<ProjectGuid>5f0dbab0-122f-4a81-be73-161bbefeef59</ProjectGuid>
|
||||
<DesktopBuildPackageLocation>bin\publish\GWMS.UI.zip</DesktopBuildPackageLocation>
|
||||
<PackageAsSingleFile>true</PackageAsSingleFile>
|
||||
<DeployIisAppPath>Default Web Site/GWMS</DeployIisAppPath>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<SelfContained>false</SelfContained>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
|
||||
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
</Project>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
|
||||
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<WebPublishMethod>Package</WebPublishMethod>
|
||||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||
<SiteUrlToLaunchAfterPublish />
|
||||
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
|
||||
<ExcludeApp_Data>False</ExcludeApp_Data>
|
||||
<ProjectGuid>5f0dbab0-122f-4a81-be73-161bbefeef59</ProjectGuid>
|
||||
<DesktopBuildPackageLocation>bin\publish\GWMS.UI.zip</DesktopBuildPackageLocation>
|
||||
<PackageAsSingleFile>true</PackageAsSingleFile>
|
||||
<DeployIisAppPath>Default Web Site/GWMS</DeployIisAppPath>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<SelfContained>false</SelfContained>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
|
||||
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
</Project>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
|
||||
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<TimeStampOfAssociatedLegacyPublishXmlFile />
|
||||
<EncryptedPassword>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAxNUOeyL5oUSNi/ISzvJtLgAAAAACAAAAAAADZgAAwAAAABAAAADTQmYF8PrkLa4Xb9E/zxuXAAAAAASAAACgAAAAEAAAADLKIlcnZuaCFkaVmfe382YYAAAADxGWDujdGKLnZ+ycw0Vb2K2g5K0dRHB8FAAAAHB9B2k06W3L+M48vPfUvedJRpJX</EncryptedPassword>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,42 +0,0 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Quartz;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GWMS.UI
|
||||
{
|
||||
public class QuartzHostedService : IHostedService
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
private readonly IScheduler _scheduler;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Public Constructors
|
||||
|
||||
public QuartzHostedService(IScheduler scheduler)
|
||||
{
|
||||
_scheduler = scheduler;
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await _scheduler?.Start(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await _scheduler?.Shutdown(cancellationToken);
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
@@ -11,11 +11,11 @@
|
||||
</div>
|
||||
|
||||
<CascadingValue Name="ShowSearch" Value=@ShowSearch>
|
||||
<div class="main">
|
||||
<div class="top-row px-0">
|
||||
<div class="main mr-1">
|
||||
<div class="top-row">
|
||||
<CmpTop></CmpTop>
|
||||
</div>
|
||||
<div class="content pt-1 pt-lg-2 px-2 mb-5">
|
||||
<div class="content pt-1 pt-lg-2 mb-5">
|
||||
@Body
|
||||
</div>
|
||||
<div class="fixed-bottom bottom-row">
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
height: 3.5rem;
|
||||
align-items: center;
|
||||
/*justify-content: space-evenly;
|
||||
display: flex;*/
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row .btn-link {
|
||||
@@ -34,37 +34,10 @@
|
||||
.bottom-row {
|
||||
color: #dedede;
|
||||
background-color: #000000;
|
||||
/*border-bottom: 1px solid #313131;*/
|
||||
/*justify-content: flex-end;*/
|
||||
height: 2rem;
|
||||
/*display: flex;*/
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bottom-row ::deep a, .top-row .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
||||
.bottom-row a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
/*
|
||||
@media (max-width: 640.98px) {
|
||||
.top-row:not(.auth) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.top-row.auth {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-row a, .top-row .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.page {
|
||||
flex-direction: row;
|
||||
|
||||
@@ -35,49 +35,74 @@
|
||||
<span class="@hideText">Home</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
<AuthorizeView>
|
||||
<NotAuthorized>
|
||||
<li class="nav-item px-3" title="Login">
|
||||
<NavLink class="nav-link" href="Identity/Account/LogIn">
|
||||
<i class="fas fa-2x fa-user-alt pr-2"></i>Non Autenticato
|
||||
</NavLink>
|
||||
</li>
|
||||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
<AuthorizeView Roles="SuperAdmin, Admin, User">
|
||||
<Authorized>
|
||||
<li class="nav-item px-3" title="Stato Impianti">
|
||||
<NavLink class="nav-link" href="PlantStatus">
|
||||
<i class="fas fa-2x fa-tachometer-alt pr-2"></i>
|
||||
<span class="@hideText">Stato Impianti</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item px-3" title="Storico Ordini">
|
||||
<NavLink class="nav-link" href="Orders">
|
||||
<i class="fas fa-2x fa-file-invoice pr-2" aria-hidden="true"></i>
|
||||
<span class="@hideText">Storico Ordini</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item px-3" title="Scheda Stazione">
|
||||
<NavLink class="nav-link" href="GasStation">
|
||||
<i class="fas fa-2x fa-gas-pump pr-2" aria-hidden="true"></i>
|
||||
<span class="@hideText">Scheda Stazione</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
</Authorized>
|
||||
</AuthorizeView>
|
||||
<AuthorizeView Roles="SuperAdmin, Admin, ExtUser">
|
||||
<Authorized>
|
||||
<li class="nav-item px-3" title="Scheda Fornitore">
|
||||
<NavLink class="nav-link" href="Suppliers">
|
||||
<i class="fas fa-2x fa-industry pr-2" aria-hidden="true"></i>
|
||||
<span class="@hideText">Scheda Fornitore</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
</Authorized>
|
||||
</AuthorizeView>
|
||||
<AuthorizeView Roles="SuperAdmin, Admin, ExtTransp">
|
||||
<Authorized>
|
||||
<li class="nav-item px-3" title="Scheda Trasportatore">
|
||||
<NavLink class="nav-link" href="Transporters">
|
||||
<i class="fas fa-2x fa-truck-moving pr-2" aria-hidden="true"></i>
|
||||
<span class="@hideText">Scheda Trasportatore</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
</Authorized>
|
||||
</AuthorizeView>
|
||||
<AuthorizeView Roles="SuperAdmin, Admin">
|
||||
<Authorized>
|
||||
<li class="nav-item px-3" title="Planner Consegne">
|
||||
<NavLink class="nav-link" href="WeekPlan">
|
||||
<i class="fas fa-2x fa-calendar pr-2" aria-hidden="true"></i>
|
||||
<span class="@hideText">Planner Consegne</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item px-3" title="Admin Utenti">
|
||||
<NavLink class="nav-link" href="UserAdmin">
|
||||
<i class="fas fa-2x fa-users pr-2" aria-hidden="true"></i>
|
||||
<span class="@hideText">Admin Utenti</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
</Authorized>
|
||||
</AuthorizeView>
|
||||
|
||||
<li class="nav-item px-3" title="Stato Impianti">
|
||||
<NavLink class="nav-link" href="PlantStatus">
|
||||
<i class="fas fa-2x fa-tachometer-alt pr-2"></i>
|
||||
<span class="@hideText">Stato Impianti</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item px-3" title="Storico Ordini">
|
||||
<NavLink class="nav-link" href="Orders">
|
||||
<i class="fas fa-2x fa-file-invoice pr-2" aria-hidden="true"></i>
|
||||
<span class="@hideText">Storico Ordini</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item px-3" title="Scheda Fornitore">
|
||||
<NavLink class="nav-link" href="Suppliers">
|
||||
<i class="fas fa-2x fa-industry pr-2" aria-hidden="true"></i>
|
||||
<span class="@hideText">Scheda Fornitore</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item px-3" title="Scheda Trasportatore">
|
||||
<NavLink class="nav-link" href="Transporters">
|
||||
<i class="fas fa-2x fa-truck-moving pr-2" aria-hidden="true"></i>
|
||||
<span class="@hideText">Scheda Trasportatore</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item px-3" title="Scheda Stazione">
|
||||
<NavLink class="nav-link" href="GasStation">
|
||||
<i class="fas fa-2x fa-gas-pump pr-2" aria-hidden="true"></i>
|
||||
<span class="@hideText">Scheda Stazione</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item px-3" title="Planner Consegne">
|
||||
<NavLink class="nav-link" href="WeekPlan">
|
||||
<i class="fas fa-2x fa-calendar pr-2" aria-hidden="true"></i>
|
||||
<span class="@hideText">Planner Consegne</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
<li class="nav-item px-3" title="Utenti">
|
||||
<NavLink class="nav-link" href="UserAdmin">
|
||||
<i class="fas fa-2x fa-users pr-2" aria-hidden="true"></i>
|
||||
<span class="@hideText">Admin Utenti</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
@*<li class="nav-item px-3" title="Utenti">
|
||||
<NavLink class="nav-link" href="UserManager">
|
||||
<i class="fas fa-2x fa-users pr-2" aria-hidden="true"></i>
|
||||
|
||||
+9
-12
@@ -1,7 +1,6 @@
|
||||
using Blazorise;
|
||||
using Blazorise.Bootstrap;
|
||||
using Blazorise.Icons.FontAwesome;
|
||||
using ElmahCore.Mvc;
|
||||
using GWMS.Data;
|
||||
using GWMS.UI.Areas.Identity;
|
||||
using GWMS.UI.Data;
|
||||
@@ -23,8 +22,6 @@ using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Quartz;
|
||||
using Quartz.Impl;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -79,9 +76,9 @@ namespace GWMS.UI
|
||||
});
|
||||
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("it-IT");
|
||||
|
||||
// Registrazione Elmah:
|
||||
// https://github.com/ElmahCore/ElmahCore
|
||||
app.UseElmah();
|
||||
//// Registrazione Elmah:
|
||||
//// https://github.com/ElmahCore/ElmahCore
|
||||
//app.UseElmah();
|
||||
|
||||
// fix forwarders
|
||||
app.UseForwardedHeaders(new ForwardedHeadersOptions
|
||||
@@ -132,18 +129,18 @@ namespace GWMS.UI
|
||||
string connStringDB = DbConfig.CONNECTION_STRING;
|
||||
string connStringRedis = Configuration.GetConnectionString("Redis");
|
||||
string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":"));
|
||||
var qrCodeUri = new Uri(Configuration["ZCodeUrl"]);
|
||||
string qrCodeAddr = qrCodeUri.Host;
|
||||
//var qrCodeUri = new Uri(Configuration["ZCodeUrl"]);
|
||||
//string qrCodeAddr = qrCodeUri.Host;
|
||||
|
||||
// healthchecks
|
||||
services.AddHealthChecks()
|
||||
.AddMySql(connStringDB, "MySql instance")
|
||||
.AddAsyncCheck($"DB PING ({dbServerAddr})", () => Health.Checks.PingCheck(dbServerAddr))
|
||||
.AddAsyncCheck($"Redis PING ({redisSrvAddr})", () => Health.Checks.PingCheck(redisSrvAddr))
|
||||
.AddAsyncCheck($"QrCode PING ({qrCodeAddr})", () => Health.Checks.PingCheck(qrCodeAddr))
|
||||
//.AddAsyncCheck($"QrCode PING ({qrCodeAddr})", () => Health.Checks.PingCheck(qrCodeAddr))
|
||||
.AddProcessAllocatedMemoryHealthCheck(512, "Max Process memory (<512MB)", failureStatus: HealthStatus.Degraded) // 512 MB max allocated memory
|
||||
.AddRedis(Configuration.GetConnectionString("Redis"), "Redis", failureStatus: HealthStatus.Degraded)
|
||||
.AddUrlGroup(new Uri(Configuration["ZCodeUrl"]), name: $"QrCode Gen ({Configuration["ZCodeUrl"]})", failureStatus: HealthStatus.Degraded)
|
||||
//.AddUrlGroup(new Uri(Configuration["ZCodeUrl"]), name: $"QrCode Gen ({Configuration["ZCodeUrl"]})", failureStatus: HealthStatus.Degraded)
|
||||
.AddAsyncCheck($"MySql Root User", () => Health.Checks.DbUserRoot("MySql"))
|
||||
.AddAsyncCheck($"MySql App Users", () => Health.Checks.DbUserApp(DbConfig.DATABASE_NAME))
|
||||
.AddAsyncCheck($"MySql Identity", () => Health.Checks.DbIdentity(DbConfig.DATABASE_NAME))
|
||||
@@ -218,8 +215,8 @@ namespace GWMS.UI
|
||||
.AddBootstrapProviders()
|
||||
.AddFontAwesomeIcons();
|
||||
|
||||
// Elmah
|
||||
services.AddElmah();
|
||||
//// Elmah
|
||||
//services.AddElmah();
|
||||
//string elmaConn = "Data Source=SQL2016DEV;Initial Catalog=Elmah;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=SHERPA.BBM;";
|
||||
//services.AddElmah<SqlErrorLog>(options =>
|
||||
//{
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
"IntervalMin": 60,
|
||||
"MaxLogRecord": 360,
|
||||
"ZCodeUrl": "https://qrcode.steamware.net/",
|
||||
"ChartWaitDelay": 10,
|
||||
"logo": "img/LogoPizzaferri.jpg",
|
||||
"ExternalProviders": {
|
||||
"MailKit": {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[
|
||||
{
|
||||
"outputFileName": "wwwroot/bootstrap/css/bootstrap.min.css",
|
||||
"inputFiles": [
|
||||
"wwwroot/bootstrap/css/bootstrap.css"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"defaultProvider": "cdnjs",
|
||||
"libraries": [
|
||||
{
|
||||
"library": "font-awesome@5.15.4",
|
||||
"destination": "wwwroot/font-awesome/"
|
||||
},
|
||||
{
|
||||
"library": "bootstrap@4.6.0",
|
||||
"destination": "wwwroot/bootstrap/"
|
||||
},
|
||||
{
|
||||
"library": "Chart.js@2.8.0",
|
||||
"destination": "wwwroot/Chart.js/"
|
||||
},
|
||||
{
|
||||
"library": "popper.js@1.16.1",
|
||||
"destination": "wwwroot/popper.js/"
|
||||
},
|
||||
{
|
||||
"library": "jquery@3.5.1",
|
||||
"destination": "wwwroot/jquery/"
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* DOM element rendering detection
|
||||
* https://davidwalsh.name/detect-node-insertion
|
||||
*/
|
||||
@keyframes chartjs-render-animation {
|
||||
from { opacity: 0.99; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.chartjs-render-monitor {
|
||||
animation: chartjs-render-animation 0.001s;
|
||||
}
|
||||
|
||||
/*
|
||||
* DOM element resizing detection
|
||||
* https://github.com/marcj/css-element-queries
|
||||
*/
|
||||
.chartjs-size-monitor,
|
||||
.chartjs-size-monitor-expand,
|
||||
.chartjs-size-monitor-shrink {
|
||||
position: absolute;
|
||||
direction: ltr;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.chartjs-size-monitor-expand > div {
|
||||
position: absolute;
|
||||
width: 1000000px;
|
||||
height: 1000000px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.chartjs-size-monitor-shrink > div {
|
||||
position: absolute;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
Vendored
+14680
File diff suppressed because it is too large
Load Diff
+1
@@ -0,0 +1 @@
|
||||
@keyframes chartjs-render-animation{from{opacity:.99}to{opacity:1}}.chartjs-render-monitor{animation:chartjs-render-animation 1ms}.chartjs-size-monitor,.chartjs-size-monitor-expand,.chartjs-size-monitor-shrink{position:absolute;direction:ltr;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1}.chartjs-size-monitor-expand>div{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}
|
||||
+7
File diff suppressed because one or more lines are too long
+3872
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
+325
@@ -0,0 +1,325 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v4.6.0 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
line-height: 1.15;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: #212529;
|
||||
text-align: left;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
[tabindex="-1"]:focus:not(:focus-visible) {
|
||||
outline: 0 !important;
|
||||
}
|
||||
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title],
|
||||
abbr[data-original-title] {
|
||||
text-decoration: underline;
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
border-bottom: 0;
|
||||
-webkit-text-decoration-skip-ink: none;
|
||||
text-decoration-skip-ink: none;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: .5rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #0056b3;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:not([href]):not([class]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:not([href]):not([class]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
-ms-overflow-style: scrollbar;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
svg {
|
||||
overflow: hidden;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
color: #6c757d;
|
||||
text-align: left;
|
||||
caption-side: bottom;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
text-align: -webkit-match-parent;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
[role="button"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
button,
|
||||
[type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
button:not(:disabled),
|
||||
[type="button"]:not(:disabled),
|
||||
[type="reset"]:not(:disabled),
|
||||
[type="submit"]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
input[type="radio"],
|
||||
input[type="checkbox"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: .5rem;
|
||||
font-size: 1.5rem;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type="search"] {
|
||||
outline-offset: -2px;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v4.6.0 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
|
||||
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
|
||||
File diff suppressed because one or more lines are too long
+10298
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
+7045
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
+4432
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
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// Base styles
|
||||
//
|
||||
|
||||
.alert {
|
||||
position: relative;
|
||||
padding: $alert-padding-y $alert-padding-x;
|
||||
margin-bottom: $alert-margin-bottom;
|
||||
border: $alert-border-width solid transparent;
|
||||
@include border-radius($alert-border-radius);
|
||||
}
|
||||
|
||||
// Headings for larger alerts
|
||||
.alert-heading {
|
||||
// Specified to prevent conflicts of changing $headings-color
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
// Provide class for links that match alerts
|
||||
.alert-link {
|
||||
font-weight: $alert-link-font-weight;
|
||||
}
|
||||
|
||||
|
||||
// Dismissible alerts
|
||||
//
|
||||
// Expand the right padding and account for the close button's positioning.
|
||||
|
||||
.alert-dismissible {
|
||||
padding-right: $close-font-size + $alert-padding-x * 2;
|
||||
|
||||
// Adjust close link position
|
||||
.close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 2;
|
||||
padding: $alert-padding-y $alert-padding-x;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Alternate styles
|
||||
//
|
||||
// Generate contextual modifier classes for colorizing the alert.
|
||||
|
||||
@each $color, $value in $theme-colors {
|
||||
.alert-#{$color} {
|
||||
@include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// Base class
|
||||
//
|
||||
// Requires one of the contextual, color modifier classes for `color` and
|
||||
// `background-color`.
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: $badge-padding-y $badge-padding-x;
|
||||
@include font-size($badge-font-size);
|
||||
font-weight: $badge-font-weight;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
@include border-radius($badge-border-radius);
|
||||
@include transition($badge-transition);
|
||||
|
||||
@at-root a#{&} {
|
||||
@include hover-focus() {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Empty badges collapse automatically
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Quick fix for badges in buttons
|
||||
.btn .badge {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
// Pill badges
|
||||
//
|
||||
// Make them extra rounded with a modifier to replace v3's badges.
|
||||
|
||||
.badge-pill {
|
||||
padding-right: $badge-pill-padding-x;
|
||||
padding-left: $badge-pill-padding-x;
|
||||
@include border-radius($badge-pill-border-radius);
|
||||
}
|
||||
|
||||
// Colors
|
||||
//
|
||||
// Contextual variations (linked badges get darker on :hover).
|
||||
|
||||
@each $color, $value in $theme-colors {
|
||||
.badge-#{$color} {
|
||||
@include badge-variant($value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
.breadcrumb {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: $breadcrumb-padding-y $breadcrumb-padding-x;
|
||||
margin-bottom: $breadcrumb-margin-bottom;
|
||||
@include font-size($breadcrumb-font-size);
|
||||
list-style: none;
|
||||
background-color: $breadcrumb-bg;
|
||||
@include border-radius($breadcrumb-border-radius);
|
||||
}
|
||||
|
||||
.breadcrumb-item {
|
||||
// The separator between breadcrumbs (by default, a forward-slash: "/")
|
||||
+ .breadcrumb-item {
|
||||
padding-left: $breadcrumb-item-padding;
|
||||
|
||||
&::before {
|
||||
float: left; // Suppress inline spacings and underlining of the separator
|
||||
padding-right: $breadcrumb-item-padding;
|
||||
color: $breadcrumb-divider-color;
|
||||
content: escape-svg($breadcrumb-divider);
|
||||
}
|
||||
}
|
||||
|
||||
// IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built
|
||||
// without `<ul>`s. The `::before` pseudo-element generates an element
|
||||
// *within* the .breadcrumb-item and thereby inherits the `text-decoration`.
|
||||
//
|
||||
// To trick IE into suppressing the underline, we give the pseudo-element an
|
||||
// underline and then immediately remove it.
|
||||
+ .breadcrumb-item:hover::before {
|
||||
text-decoration: underline;
|
||||
}
|
||||
// stylelint-disable-next-line no-duplicate-selectors
|
||||
+ .breadcrumb-item:hover::before {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $breadcrumb-active-color;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
|
||||
// Make the div behave like a button
|
||||
.btn-group,
|
||||
.btn-group-vertical {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
vertical-align: middle; // match .btn alignment given font-size hack above
|
||||
|
||||
> .btn {
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
|
||||
// Bring the hover, focused, and "active" buttons to the front to overlay
|
||||
// the borders properly
|
||||
@include hover() {
|
||||
z-index: 1;
|
||||
}
|
||||
&:focus,
|
||||
&:active,
|
||||
&.active {
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Optional: Group multiple button groups together for a toolbar
|
||||
.btn-toolbar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
|
||||
.input-group {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
// Prevent double borders when buttons are next to each other
|
||||
> .btn:not(:first-child),
|
||||
> .btn-group:not(:first-child) {
|
||||
margin-left: -$btn-border-width;
|
||||
}
|
||||
|
||||
// Reset rounded corners
|
||||
> .btn:not(:last-child):not(.dropdown-toggle),
|
||||
> .btn-group:not(:last-child) > .btn {
|
||||
@include border-right-radius(0);
|
||||
}
|
||||
|
||||
> .btn:not(:first-child),
|
||||
> .btn-group:not(:first-child) > .btn {
|
||||
@include border-left-radius(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Sizing
|
||||
//
|
||||
// Remix the default button sizing classes into new ones for easier manipulation.
|
||||
|
||||
.btn-group-sm > .btn { @extend .btn-sm; }
|
||||
.btn-group-lg > .btn { @extend .btn-lg; }
|
||||
|
||||
|
||||
//
|
||||
// Split button dropdowns
|
||||
//
|
||||
|
||||
.dropdown-toggle-split {
|
||||
padding-right: $btn-padding-x * .75;
|
||||
padding-left: $btn-padding-x * .75;
|
||||
|
||||
&::after,
|
||||
.dropup &::after,
|
||||
.dropright &::after {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.dropleft &::before {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-sm + .dropdown-toggle-split {
|
||||
padding-right: $btn-padding-x-sm * .75;
|
||||
padding-left: $btn-padding-x-sm * .75;
|
||||
}
|
||||
|
||||
.btn-lg + .dropdown-toggle-split {
|
||||
padding-right: $btn-padding-x-lg * .75;
|
||||
padding-left: $btn-padding-x-lg * .75;
|
||||
}
|
||||
|
||||
|
||||
// The clickable button for toggling the menu
|
||||
// Set the same inset shadow as the :active state
|
||||
.btn-group.show .dropdown-toggle {
|
||||
@include box-shadow($btn-active-box-shadow);
|
||||
|
||||
// Show no shadow for `.btn-link` since it has no other button styles.
|
||||
&.btn-link {
|
||||
@include box-shadow(none);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Vertical button groups
|
||||
//
|
||||
|
||||
.btn-group-vertical {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
|
||||
> .btn,
|
||||
> .btn-group {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
> .btn:not(:first-child),
|
||||
> .btn-group:not(:first-child) {
|
||||
margin-top: -$btn-border-width;
|
||||
}
|
||||
|
||||
// Reset rounded corners
|
||||
> .btn:not(:last-child):not(.dropdown-toggle),
|
||||
> .btn-group:not(:last-child) > .btn {
|
||||
@include border-bottom-radius(0);
|
||||
}
|
||||
|
||||
> .btn:not(:first-child),
|
||||
> .btn-group:not(:first-child) > .btn {
|
||||
@include border-top-radius(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Checkbox and radio options
|
||||
//
|
||||
// In order to support the browser's form validation feedback, powered by the
|
||||
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
|
||||
// `display: none;` or `visibility: hidden;` as that also hides the popover.
|
||||
// Simply visually hiding the inputs via `opacity` would leave them clickable in
|
||||
// certain cases which is prevented by using `clip` and `pointer-events`.
|
||||
// This way, we ensure a DOM element is visible to position the popover from.
|
||||
//
|
||||
// See https://github.com/twbs/bootstrap/pull/12794 and
|
||||
// https://github.com/twbs/bootstrap/pull/14559 for more information.
|
||||
|
||||
.btn-group-toggle {
|
||||
> .btn,
|
||||
> .btn-group > .btn {
|
||||
margin-bottom: 0; // Override default `<label>` value
|
||||
|
||||
input[type="radio"],
|
||||
input[type="checkbox"] {
|
||||
position: absolute;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
|
||||
//
|
||||
// Base styles
|
||||
//
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
font-family: $btn-font-family;
|
||||
font-weight: $btn-font-weight;
|
||||
color: $body-color;
|
||||
text-align: center;
|
||||
text-decoration: if($link-decoration == none, null, none);
|
||||
white-space: $btn-white-space;
|
||||
vertical-align: middle;
|
||||
user-select: none;
|
||||
background-color: transparent;
|
||||
border: $btn-border-width solid transparent;
|
||||
@include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);
|
||||
@include transition($btn-transition);
|
||||
|
||||
@include hover() {
|
||||
color: $body-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&.focus {
|
||||
outline: 0;
|
||||
box-shadow: $btn-focus-box-shadow;
|
||||
}
|
||||
|
||||
// Disabled comes first so active can properly restyle
|
||||
&.disabled,
|
||||
&:disabled {
|
||||
opacity: $btn-disabled-opacity;
|
||||
@include box-shadow(none);
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled) {
|
||||
cursor: if($enable-pointer-cursor-for-buttons, pointer, null);
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
@include box-shadow($btn-active-box-shadow);
|
||||
|
||||
&:focus {
|
||||
@include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Future-proof disabling of clicks on `<a>` elements
|
||||
a.btn.disabled,
|
||||
fieldset:disabled a.btn {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Alternate buttons
|
||||
//
|
||||
|
||||
@each $color, $value in $theme-colors {
|
||||
.btn-#{$color} {
|
||||
@include button-variant($value, $value);
|
||||
}
|
||||
}
|
||||
|
||||
@each $color, $value in $theme-colors {
|
||||
.btn-outline-#{$color} {
|
||||
@include button-outline-variant($value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Link buttons
|
||||
//
|
||||
|
||||
// Make a button look and behave like a link
|
||||
.btn-link {
|
||||
font-weight: $font-weight-normal;
|
||||
color: $link-color;
|
||||
text-decoration: $link-decoration;
|
||||
|
||||
@include hover() {
|
||||
color: $link-hover-color;
|
||||
text-decoration: $link-hover-decoration;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&.focus {
|
||||
text-decoration: $link-hover-decoration;
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&.disabled {
|
||||
color: $btn-link-disabled-color;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// No need for an active state here
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Button Sizes
|
||||
//
|
||||
|
||||
.btn-lg {
|
||||
@include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
@include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Block button
|
||||
//
|
||||
|
||||
.btn-block {
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
||||
// Vertically space out multiple block buttons
|
||||
+ .btn-block {
|
||||
margin-top: $btn-block-spacing-y;
|
||||
}
|
||||
}
|
||||
|
||||
// Specificity overrides
|
||||
input[type="submit"],
|
||||
input[type="reset"],
|
||||
input[type="button"] {
|
||||
&.btn-block {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
//
|
||||
// Base styles
|
||||
//
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
|
||||
height: $card-height;
|
||||
word-wrap: break-word;
|
||||
background-color: $card-bg;
|
||||
background-clip: border-box;
|
||||
border: $card-border-width solid $card-border-color;
|
||||
@include border-radius($card-border-radius);
|
||||
|
||||
> hr {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
> .list-group {
|
||||
border-top: inherit;
|
||||
border-bottom: inherit;
|
||||
|
||||
&:first-child {
|
||||
border-top-width: 0;
|
||||
@include border-top-radius($card-inner-border-radius);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom-width: 0;
|
||||
@include border-bottom-radius($card-inner-border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
// Due to specificity of the above selector (`.card > .list-group`), we must
|
||||
// use a child selector here to prevent double borders.
|
||||
> .card-header + .list-group,
|
||||
> .list-group + .card-footer {
|
||||
border-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.card-body {
|
||||
// Enable `flex-grow: 1` for decks and groups so that card blocks take up
|
||||
// as much space as possible, ensuring footers are aligned to the bottom.
|
||||
flex: 1 1 auto;
|
||||
// Workaround for the image size bug in IE
|
||||
// See: https://github.com/twbs/bootstrap/pull/28855
|
||||
min-height: 1px;
|
||||
padding: $card-spacer-x;
|
||||
color: $card-color;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
margin-bottom: $card-spacer-y;
|
||||
}
|
||||
|
||||
.card-subtitle {
|
||||
margin-top: -$card-spacer-y / 2;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.card-text:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.card-link {
|
||||
@include hover() {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
+ .card-link {
|
||||
margin-left: $card-spacer-x;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Optional textual caps
|
||||
//
|
||||
|
||||
.card-header {
|
||||
padding: $card-spacer-y $card-spacer-x;
|
||||
margin-bottom: 0; // Removes the default margin-bottom of <hN>
|
||||
color: $card-cap-color;
|
||||
background-color: $card-cap-bg;
|
||||
border-bottom: $card-border-width solid $card-border-color;
|
||||
|
||||
&:first-child {
|
||||
@include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);
|
||||
}
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
padding: $card-spacer-y $card-spacer-x;
|
||||
color: $card-cap-color;
|
||||
background-color: $card-cap-bg;
|
||||
border-top: $card-border-width solid $card-border-color;
|
||||
|
||||
&:last-child {
|
||||
@include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Header navs
|
||||
//
|
||||
|
||||
.card-header-tabs {
|
||||
margin-right: -$card-spacer-x / 2;
|
||||
margin-bottom: -$card-spacer-y;
|
||||
margin-left: -$card-spacer-x / 2;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.card-header-pills {
|
||||
margin-right: -$card-spacer-x / 2;
|
||||
margin-left: -$card-spacer-x / 2;
|
||||
}
|
||||
|
||||
// Card image
|
||||
.card-img-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: $card-img-overlay-padding;
|
||||
@include border-radius($card-inner-border-radius);
|
||||
}
|
||||
|
||||
.card-img,
|
||||
.card-img-top,
|
||||
.card-img-bottom {
|
||||
flex-shrink: 0; // For IE: https://github.com/twbs/bootstrap/issues/29396
|
||||
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
|
||||
}
|
||||
|
||||
.card-img,
|
||||
.card-img-top {
|
||||
@include border-top-radius($card-inner-border-radius);
|
||||
}
|
||||
|
||||
.card-img,
|
||||
.card-img-bottom {
|
||||
@include border-bottom-radius($card-inner-border-radius);
|
||||
}
|
||||
|
||||
|
||||
// Card deck
|
||||
|
||||
.card-deck {
|
||||
.card {
|
||||
margin-bottom: $card-deck-margin;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
margin-right: -$card-deck-margin;
|
||||
margin-left: -$card-deck-margin;
|
||||
|
||||
.card {
|
||||
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
|
||||
flex: 1 0 0%;
|
||||
margin-right: $card-deck-margin;
|
||||
margin-bottom: 0; // Override the default
|
||||
margin-left: $card-deck-margin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Card groups
|
||||
//
|
||||
|
||||
.card-group {
|
||||
// The child selector allows nested `.card` within `.card-group`
|
||||
// to display properly.
|
||||
> .card {
|
||||
margin-bottom: $card-group-margin;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
// The child selector allows nested `.card` within `.card-group`
|
||||
// to display properly.
|
||||
> .card {
|
||||
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
|
||||
flex: 1 0 0%;
|
||||
margin-bottom: 0;
|
||||
|
||||
+ .card {
|
||||
margin-left: 0;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
// Handle rounded corners
|
||||
@if $enable-rounded {
|
||||
&:not(:last-child) {
|
||||
@include border-right-radius(0);
|
||||
|
||||
.card-img-top,
|
||||
.card-header {
|
||||
// stylelint-disable-next-line property-disallowed-list
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
.card-img-bottom,
|
||||
.card-footer {
|
||||
// stylelint-disable-next-line property-disallowed-list
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
@include border-left-radius(0);
|
||||
|
||||
.card-img-top,
|
||||
.card-header {
|
||||
// stylelint-disable-next-line property-disallowed-list
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
.card-img-bottom,
|
||||
.card-footer {
|
||||
// stylelint-disable-next-line property-disallowed-list
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Columns
|
||||
//
|
||||
|
||||
.card-columns {
|
||||
.card {
|
||||
margin-bottom: $card-columns-margin;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
column-count: $card-columns-count;
|
||||
column-gap: $card-columns-gap;
|
||||
orphans: 1;
|
||||
widows: 1;
|
||||
|
||||
.card {
|
||||
display: inline-block; // Don't let them vertically span multiple columns
|
||||
width: 100%; // Don't let their width change
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Accordion
|
||||
//
|
||||
|
||||
.accordion {
|
||||
overflow-anchor: none;
|
||||
|
||||
> .card {
|
||||
overflow: hidden;
|
||||
|
||||
&:not(:last-of-type) {
|
||||
border-bottom: 0;
|
||||
@include border-bottom-radius(0);
|
||||
}
|
||||
|
||||
&:not(:first-of-type) {
|
||||
@include border-top-radius(0);
|
||||
}
|
||||
|
||||
> .card-header {
|
||||
@include border-radius(0);
|
||||
margin-bottom: -$card-border-width;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
// Notes on the classes:
|
||||
//
|
||||
// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)
|
||||
// even when their scroll action started on a carousel, but for compatibility (with Firefox)
|
||||
// we're preventing all actions instead
|
||||
// 2. The .carousel-item-left and .carousel-item-right is used to indicate where
|
||||
// the active slide is heading.
|
||||
// 3. .active.carousel-item is the current slide.
|
||||
// 4. .active.carousel-item-left and .active.carousel-item-right is the current
|
||||
// slide in its in-transition state. Only one of these occurs at a time.
|
||||
// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right
|
||||
// is the upcoming slide in transition.
|
||||
|
||||
.carousel {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.carousel.pointer-event {
|
||||
touch-action: pan-y;
|
||||
}
|
||||
|
||||
.carousel-inner {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
@include clearfix();
|
||||
}
|
||||
|
||||
.carousel-item {
|
||||
position: relative;
|
||||
display: none;
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin-right: -100%;
|
||||
backface-visibility: hidden;
|
||||
@include transition($carousel-transition);
|
||||
}
|
||||
|
||||
.carousel-item.active,
|
||||
.carousel-item-next,
|
||||
.carousel-item-prev {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.carousel-item-next:not(.carousel-item-left),
|
||||
.active.carousel-item-right {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
.carousel-item-prev:not(.carousel-item-right),
|
||||
.active.carousel-item-left {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Alternate transitions
|
||||
//
|
||||
|
||||
.carousel-fade {
|
||||
.carousel-item {
|
||||
opacity: 0;
|
||||
transition-property: opacity;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.carousel-item.active,
|
||||
.carousel-item-next.carousel-item-left,
|
||||
.carousel-item-prev.carousel-item-right {
|
||||
z-index: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.active.carousel-item-left,
|
||||
.active.carousel-item-right {
|
||||
z-index: 0;
|
||||
opacity: 0;
|
||||
@include transition(opacity 0s $carousel-transition-duration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Left/right controls for nav
|
||||
//
|
||||
|
||||
.carousel-control-prev,
|
||||
.carousel-control-next {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 1;
|
||||
// Use flex for alignment (1-3)
|
||||
display: flex; // 1. allow flex styles
|
||||
align-items: center; // 2. vertically center contents
|
||||
justify-content: center; // 3. horizontally center contents
|
||||
width: $carousel-control-width;
|
||||
color: $carousel-control-color;
|
||||
text-align: center;
|
||||
opacity: $carousel-control-opacity;
|
||||
@include transition($carousel-control-transition);
|
||||
|
||||
// Hover/focus state
|
||||
@include hover-focus() {
|
||||
color: $carousel-control-color;
|
||||
text-decoration: none;
|
||||
outline: 0;
|
||||
opacity: $carousel-control-hover-opacity;
|
||||
}
|
||||
}
|
||||
.carousel-control-prev {
|
||||
left: 0;
|
||||
@if $enable-gradients {
|
||||
background-image: linear-gradient(90deg, rgba($black, .25), rgba($black, .001));
|
||||
}
|
||||
}
|
||||
.carousel-control-next {
|
||||
right: 0;
|
||||
@if $enable-gradients {
|
||||
background-image: linear-gradient(270deg, rgba($black, .25), rgba($black, .001));
|
||||
}
|
||||
}
|
||||
|
||||
// Icons for within
|
||||
.carousel-control-prev-icon,
|
||||
.carousel-control-next-icon {
|
||||
display: inline-block;
|
||||
width: $carousel-control-icon-width;
|
||||
height: $carousel-control-icon-width;
|
||||
background: 50% / 100% 100% no-repeat;
|
||||
}
|
||||
.carousel-control-prev-icon {
|
||||
background-image: escape-svg($carousel-control-prev-icon-bg);
|
||||
}
|
||||
.carousel-control-next-icon {
|
||||
background-image: escape-svg($carousel-control-next-icon-bg);
|
||||
}
|
||||
|
||||
|
||||
// Optional indicator pips
|
||||
//
|
||||
// Add an ordered list with the following class and add a list item for each
|
||||
// slide your carousel holds.
|
||||
|
||||
.carousel-indicators {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 15;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding-left: 0; // override <ol> default
|
||||
// Use the .carousel-control's width as margin so we don't overlay those
|
||||
margin-right: $carousel-control-width;
|
||||
margin-left: $carousel-control-width;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
box-sizing: content-box;
|
||||
flex: 0 1 auto;
|
||||
width: $carousel-indicator-width;
|
||||
height: $carousel-indicator-height;
|
||||
margin-right: $carousel-indicator-spacer;
|
||||
margin-left: $carousel-indicator-spacer;
|
||||
text-indent: -999px;
|
||||
cursor: pointer;
|
||||
background-color: $carousel-indicator-active-bg;
|
||||
background-clip: padding-box;
|
||||
// Use transparent borders to increase the hit area by 10px on top and bottom.
|
||||
border-top: $carousel-indicator-hit-area-height solid transparent;
|
||||
border-bottom: $carousel-indicator-hit-area-height solid transparent;
|
||||
opacity: .5;
|
||||
@include transition($carousel-indicator-transition);
|
||||
}
|
||||
|
||||
.active {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Optional captions
|
||||
//
|
||||
//
|
||||
|
||||
.carousel-caption {
|
||||
position: absolute;
|
||||
right: (100% - $carousel-caption-width) / 2;
|
||||
bottom: 20px;
|
||||
left: (100% - $carousel-caption-width) / 2;
|
||||
z-index: 10;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
color: $carousel-caption-color;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
.close {
|
||||
float: right;
|
||||
@include font-size($close-font-size);
|
||||
font-weight: $close-font-weight;
|
||||
line-height: 1;
|
||||
color: $close-color;
|
||||
text-shadow: $close-text-shadow;
|
||||
opacity: .5;
|
||||
|
||||
// Override <a>'s hover style
|
||||
@include hover() {
|
||||
color: $close-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled) {
|
||||
@include hover-focus() {
|
||||
opacity: .75;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Additional properties for button version
|
||||
// iOS requires the button element instead of an anchor tag.
|
||||
// If you want the anchor version, it requires `href="#"`.
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
|
||||
|
||||
// stylelint-disable-next-line selector-no-qualifying-type
|
||||
button.close {
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
// Future-proof disabling of clicks on `<a>` elements
|
||||
|
||||
// stylelint-disable-next-line selector-no-qualifying-type
|
||||
a.close.disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Inline code
|
||||
code {
|
||||
@include font-size($code-font-size);
|
||||
color: $code-color;
|
||||
word-wrap: break-word;
|
||||
|
||||
// Streamline the style when inside anchors to avoid broken underline and more
|
||||
a > & {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
// User input typically entered via keyboard
|
||||
kbd {
|
||||
padding: $kbd-padding-y $kbd-padding-x;
|
||||
@include font-size($kbd-font-size);
|
||||
color: $kbd-color;
|
||||
background-color: $kbd-bg;
|
||||
@include border-radius($border-radius-sm);
|
||||
@include box-shadow($kbd-box-shadow);
|
||||
|
||||
kbd {
|
||||
padding: 0;
|
||||
@include font-size(100%);
|
||||
font-weight: $nested-kbd-font-weight;
|
||||
@include box-shadow(none);
|
||||
}
|
||||
}
|
||||
|
||||
// Blocks of code
|
||||
pre {
|
||||
display: block;
|
||||
@include font-size($code-font-size);
|
||||
color: $pre-color;
|
||||
|
||||
// Account for some code outputs that place code tags in pre tags
|
||||
code {
|
||||
@include font-size(inherit);
|
||||
color: inherit;
|
||||
word-break: normal;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable scrollable blocks of code
|
||||
.pre-scrollable {
|
||||
max-height: $pre-scrollable-max-height;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
@@ -0,0 +1,526 @@
|
||||
// Embedded icons from Open Iconic.
|
||||
// Released under MIT and copyright 2014 Waybury.
|
||||
// https://useiconic.com/open
|
||||
|
||||
|
||||
// Checkboxes and radios
|
||||
//
|
||||
// Base class takes care of all the key behavioral aspects.
|
||||
|
||||
.custom-control {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: block;
|
||||
min-height: $font-size-base * $line-height-base;
|
||||
padding-left: $custom-control-gutter + $custom-control-indicator-size;
|
||||
color-adjust: exact; // Keep themed appearance for print
|
||||
}
|
||||
|
||||
.custom-control-inline {
|
||||
display: inline-flex;
|
||||
margin-right: $custom-control-spacer-x;
|
||||
}
|
||||
|
||||
.custom-control-input {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
z-index: -1; // Put the input behind the label so it doesn't overlay text
|
||||
width: $custom-control-indicator-size;
|
||||
height: ($font-size-base * $line-height-base + $custom-control-indicator-size) / 2;
|
||||
opacity: 0;
|
||||
|
||||
&:checked ~ .custom-control-label::before {
|
||||
color: $custom-control-indicator-checked-color;
|
||||
border-color: $custom-control-indicator-checked-border-color;
|
||||
@include gradient-bg($custom-control-indicator-checked-bg);
|
||||
@include box-shadow($custom-control-indicator-checked-box-shadow);
|
||||
}
|
||||
|
||||
&:focus ~ .custom-control-label::before {
|
||||
// the mixin is not used here to make sure there is feedback
|
||||
@if $enable-shadows {
|
||||
box-shadow: $input-box-shadow, $custom-control-indicator-focus-box-shadow;
|
||||
} @else {
|
||||
box-shadow: $custom-control-indicator-focus-box-shadow;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus:not(:checked) ~ .custom-control-label::before {
|
||||
border-color: $custom-control-indicator-focus-border-color;
|
||||
}
|
||||
|
||||
&:not(:disabled):active ~ .custom-control-label::before {
|
||||
color: $custom-control-indicator-active-color;
|
||||
background-color: $custom-control-indicator-active-bg;
|
||||
border-color: $custom-control-indicator-active-border-color;
|
||||
@include box-shadow($custom-control-indicator-active-box-shadow);
|
||||
}
|
||||
|
||||
// Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
|
||||
&[disabled],
|
||||
&:disabled {
|
||||
~ .custom-control-label {
|
||||
color: $custom-control-label-disabled-color;
|
||||
|
||||
&::before {
|
||||
background-color: $custom-control-indicator-disabled-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Custom control indicators
|
||||
//
|
||||
// Build the custom controls out of pseudo-elements.
|
||||
|
||||
.custom-control-label {
|
||||
position: relative;
|
||||
margin-bottom: 0;
|
||||
color: $custom-control-label-color;
|
||||
vertical-align: top;
|
||||
cursor: $custom-control-cursor;
|
||||
|
||||
// Background-color and (when enabled) gradient
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
|
||||
left: -($custom-control-gutter + $custom-control-indicator-size);
|
||||
display: block;
|
||||
width: $custom-control-indicator-size;
|
||||
height: $custom-control-indicator-size;
|
||||
pointer-events: none;
|
||||
content: "";
|
||||
background-color: $custom-control-indicator-bg;
|
||||
border: $custom-control-indicator-border-color solid $custom-control-indicator-border-width;
|
||||
@include box-shadow($custom-control-indicator-box-shadow);
|
||||
}
|
||||
|
||||
// Foreground (icon)
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
|
||||
left: -($custom-control-gutter + $custom-control-indicator-size);
|
||||
display: block;
|
||||
width: $custom-control-indicator-size;
|
||||
height: $custom-control-indicator-size;
|
||||
content: "";
|
||||
background: 50% / #{$custom-control-indicator-bg-size} no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Checkboxes
|
||||
//
|
||||
// Tweak just a few things for checkboxes.
|
||||
|
||||
.custom-checkbox {
|
||||
.custom-control-label::before {
|
||||
@include border-radius($custom-checkbox-indicator-border-radius);
|
||||
}
|
||||
|
||||
.custom-control-input:checked ~ .custom-control-label {
|
||||
&::after {
|
||||
background-image: escape-svg($custom-checkbox-indicator-icon-checked);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-control-input:indeterminate ~ .custom-control-label {
|
||||
&::before {
|
||||
border-color: $custom-checkbox-indicator-indeterminate-border-color;
|
||||
@include gradient-bg($custom-checkbox-indicator-indeterminate-bg);
|
||||
@include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);
|
||||
}
|
||||
&::after {
|
||||
background-image: escape-svg($custom-checkbox-indicator-icon-indeterminate);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-control-input:disabled {
|
||||
&:checked ~ .custom-control-label::before {
|
||||
@include gradient-bg($custom-control-indicator-checked-disabled-bg);
|
||||
}
|
||||
&:indeterminate ~ .custom-control-label::before {
|
||||
@include gradient-bg($custom-control-indicator-checked-disabled-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Radios
|
||||
//
|
||||
// Tweak just a few things for radios.
|
||||
|
||||
.custom-radio {
|
||||
.custom-control-label::before {
|
||||
// stylelint-disable-next-line property-disallowed-list
|
||||
border-radius: $custom-radio-indicator-border-radius;
|
||||
}
|
||||
|
||||
.custom-control-input:checked ~ .custom-control-label {
|
||||
&::after {
|
||||
background-image: escape-svg($custom-radio-indicator-icon-checked);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-control-input:disabled {
|
||||
&:checked ~ .custom-control-label::before {
|
||||
@include gradient-bg($custom-control-indicator-checked-disabled-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// switches
|
||||
//
|
||||
// Tweak a few things for switches
|
||||
|
||||
.custom-switch {
|
||||
padding-left: $custom-switch-width + $custom-control-gutter;
|
||||
|
||||
.custom-control-label {
|
||||
&::before {
|
||||
left: -($custom-switch-width + $custom-control-gutter);
|
||||
width: $custom-switch-width;
|
||||
pointer-events: all;
|
||||
// stylelint-disable-next-line property-disallowed-list
|
||||
border-radius: $custom-switch-indicator-border-radius;
|
||||
}
|
||||
|
||||
&::after {
|
||||
top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2, $custom-control-indicator-border-width * 2);
|
||||
left: add(-($custom-switch-width + $custom-control-gutter), $custom-control-indicator-border-width * 2);
|
||||
width: $custom-switch-indicator-size;
|
||||
height: $custom-switch-indicator-size;
|
||||
background-color: $custom-control-indicator-border-color;
|
||||
// stylelint-disable-next-line property-disallowed-list
|
||||
border-radius: $custom-switch-indicator-border-radius;
|
||||
@include transition(transform .15s ease-in-out, $custom-forms-transition);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-control-input:checked ~ .custom-control-label {
|
||||
&::after {
|
||||
background-color: $custom-control-indicator-bg;
|
||||
transform: translateX($custom-switch-width - $custom-control-indicator-size);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-control-input:disabled {
|
||||
&:checked ~ .custom-control-label::before {
|
||||
@include gradient-bg($custom-control-indicator-checked-disabled-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Select
|
||||
//
|
||||
// Replaces the browser default select with a custom one, mostly pulled from
|
||||
// https://primer.github.io/.
|
||||
//
|
||||
|
||||
.custom-select {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: $custom-select-height;
|
||||
padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;
|
||||
font-family: $custom-select-font-family;
|
||||
@include font-size($custom-select-font-size);
|
||||
font-weight: $custom-select-font-weight;
|
||||
line-height: $custom-select-line-height;
|
||||
color: $custom-select-color;
|
||||
vertical-align: middle;
|
||||
background: $custom-select-bg $custom-select-background;
|
||||
border: $custom-select-border-width solid $custom-select-border-color;
|
||||
@include border-radius($custom-select-border-radius, 0);
|
||||
@include box-shadow($custom-select-box-shadow);
|
||||
appearance: none;
|
||||
|
||||
&:focus {
|
||||
border-color: $custom-select-focus-border-color;
|
||||
outline: 0;
|
||||
@if $enable-shadows {
|
||||
@include box-shadow($custom-select-box-shadow, $custom-select-focus-box-shadow);
|
||||
} @else {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
box-shadow: $custom-select-focus-box-shadow;
|
||||
}
|
||||
|
||||
&::-ms-value {
|
||||
// For visual consistency with other platforms/browsers,
|
||||
// suppress the default white text on blue background highlight given to
|
||||
// the selected option text when the (still closed) <select> receives focus
|
||||
// in IE and (under certain conditions) Edge.
|
||||
// See https://github.com/twbs/bootstrap/issues/19398.
|
||||
color: $input-color;
|
||||
background-color: $input-bg;
|
||||
}
|
||||
}
|
||||
|
||||
&[multiple],
|
||||
&[size]:not([size="1"]) {
|
||||
height: auto;
|
||||
padding-right: $custom-select-padding-x;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: $custom-select-disabled-color;
|
||||
background-color: $custom-select-disabled-bg;
|
||||
}
|
||||
|
||||
// Hides the default caret in IE11
|
||||
&::-ms-expand {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Remove outline from select box in FF
|
||||
&:-moz-focusring {
|
||||
color: transparent;
|
||||
text-shadow: 0 0 0 $custom-select-color;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-select-sm {
|
||||
height: $custom-select-height-sm;
|
||||
padding-top: $custom-select-padding-y-sm;
|
||||
padding-bottom: $custom-select-padding-y-sm;
|
||||
padding-left: $custom-select-padding-x-sm;
|
||||
@include font-size($custom-select-font-size-sm);
|
||||
}
|
||||
|
||||
.custom-select-lg {
|
||||
height: $custom-select-height-lg;
|
||||
padding-top: $custom-select-padding-y-lg;
|
||||
padding-bottom: $custom-select-padding-y-lg;
|
||||
padding-left: $custom-select-padding-x-lg;
|
||||
@include font-size($custom-select-font-size-lg);
|
||||
}
|
||||
|
||||
|
||||
// File
|
||||
//
|
||||
// Custom file input.
|
||||
|
||||
.custom-file {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: $custom-file-height;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.custom-file-input {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
height: $custom-file-height;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
|
||||
&:focus ~ .custom-file-label {
|
||||
border-color: $custom-file-focus-border-color;
|
||||
box-shadow: $custom-file-focus-box-shadow;
|
||||
}
|
||||
|
||||
// Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
|
||||
&[disabled] ~ .custom-file-label,
|
||||
&:disabled ~ .custom-file-label {
|
||||
background-color: $custom-file-disabled-bg;
|
||||
}
|
||||
|
||||
@each $lang, $value in $custom-file-text {
|
||||
&:lang(#{$lang}) ~ .custom-file-label::after {
|
||||
content: $value;
|
||||
}
|
||||
}
|
||||
|
||||
~ .custom-file-label[data-browse]::after {
|
||||
content: attr(data-browse);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-file-label {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
height: $custom-file-height;
|
||||
padding: $custom-file-padding-y $custom-file-padding-x;
|
||||
overflow: hidden;
|
||||
font-family: $custom-file-font-family;
|
||||
font-weight: $custom-file-font-weight;
|
||||
line-height: $custom-file-line-height;
|
||||
color: $custom-file-color;
|
||||
background-color: $custom-file-bg;
|
||||
border: $custom-file-border-width solid $custom-file-border-color;
|
||||
@include border-radius($custom-file-border-radius);
|
||||
@include box-shadow($custom-file-box-shadow);
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 3;
|
||||
display: block;
|
||||
height: $custom-file-height-inner;
|
||||
padding: $custom-file-padding-y $custom-file-padding-x;
|
||||
line-height: $custom-file-line-height;
|
||||
color: $custom-file-button-color;
|
||||
content: "Browse";
|
||||
@include gradient-bg($custom-file-button-bg);
|
||||
border-left: inherit;
|
||||
@include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Range
|
||||
//
|
||||
// Style range inputs the same across browsers. Vendor-specific rules for pseudo
|
||||
// elements cannot be mixed. As such, there are no shared styles for focus or
|
||||
// active states on prefixed selectors.
|
||||
|
||||
.custom-range {
|
||||
width: 100%;
|
||||
height: add($custom-range-thumb-height, $custom-range-thumb-focus-box-shadow-width * 2);
|
||||
padding: 0; // Need to reset padding
|
||||
background-color: transparent;
|
||||
appearance: none;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
|
||||
// Pseudo-elements must be split across multiple rulesets to have an effect.
|
||||
// No box-shadow() mixin for focus accessibility.
|
||||
&::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
|
||||
&::-moz-range-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
|
||||
&::-ms-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
|
||||
}
|
||||
|
||||
&::-moz-focus-outer {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
&::-webkit-slider-thumb {
|
||||
width: $custom-range-thumb-width;
|
||||
height: $custom-range-thumb-height;
|
||||
margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific
|
||||
@include gradient-bg($custom-range-thumb-bg);
|
||||
border: $custom-range-thumb-border;
|
||||
@include border-radius($custom-range-thumb-border-radius);
|
||||
@include box-shadow($custom-range-thumb-box-shadow);
|
||||
@include transition($custom-forms-transition);
|
||||
appearance: none;
|
||||
|
||||
&:active {
|
||||
@include gradient-bg($custom-range-thumb-active-bg);
|
||||
}
|
||||
}
|
||||
|
||||
&::-webkit-slider-runnable-track {
|
||||
width: $custom-range-track-width;
|
||||
height: $custom-range-track-height;
|
||||
color: transparent; // Why?
|
||||
cursor: $custom-range-track-cursor;
|
||||
background-color: $custom-range-track-bg;
|
||||
border-color: transparent;
|
||||
@include border-radius($custom-range-track-border-radius);
|
||||
@include box-shadow($custom-range-track-box-shadow);
|
||||
}
|
||||
|
||||
&::-moz-range-thumb {
|
||||
width: $custom-range-thumb-width;
|
||||
height: $custom-range-thumb-height;
|
||||
@include gradient-bg($custom-range-thumb-bg);
|
||||
border: $custom-range-thumb-border;
|
||||
@include border-radius($custom-range-thumb-border-radius);
|
||||
@include box-shadow($custom-range-thumb-box-shadow);
|
||||
@include transition($custom-forms-transition);
|
||||
appearance: none;
|
||||
|
||||
&:active {
|
||||
@include gradient-bg($custom-range-thumb-active-bg);
|
||||
}
|
||||
}
|
||||
|
||||
&::-moz-range-track {
|
||||
width: $custom-range-track-width;
|
||||
height: $custom-range-track-height;
|
||||
color: transparent;
|
||||
cursor: $custom-range-track-cursor;
|
||||
background-color: $custom-range-track-bg;
|
||||
border-color: transparent; // Firefox specific?
|
||||
@include border-radius($custom-range-track-border-radius);
|
||||
@include box-shadow($custom-range-track-box-shadow);
|
||||
}
|
||||
|
||||
&::-ms-thumb {
|
||||
width: $custom-range-thumb-width;
|
||||
height: $custom-range-thumb-height;
|
||||
margin-top: 0; // Edge specific
|
||||
margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
|
||||
margin-left: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
|
||||
@include gradient-bg($custom-range-thumb-bg);
|
||||
border: $custom-range-thumb-border;
|
||||
@include border-radius($custom-range-thumb-border-radius);
|
||||
@include box-shadow($custom-range-thumb-box-shadow);
|
||||
@include transition($custom-forms-transition);
|
||||
appearance: none;
|
||||
|
||||
&:active {
|
||||
@include gradient-bg($custom-range-thumb-active-bg);
|
||||
}
|
||||
}
|
||||
|
||||
&::-ms-track {
|
||||
width: $custom-range-track-width;
|
||||
height: $custom-range-track-height;
|
||||
color: transparent;
|
||||
cursor: $custom-range-track-cursor;
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
border-width: $custom-range-thumb-height / 2;
|
||||
@include box-shadow($custom-range-track-box-shadow);
|
||||
}
|
||||
|
||||
&::-ms-fill-lower {
|
||||
background-color: $custom-range-track-bg;
|
||||
@include border-radius($custom-range-track-border-radius);
|
||||
}
|
||||
|
||||
&::-ms-fill-upper {
|
||||
margin-right: 15px; // arbitrary?
|
||||
background-color: $custom-range-track-bg;
|
||||
@include border-radius($custom-range-track-border-radius);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
&::-webkit-slider-thumb {
|
||||
background-color: $custom-range-thumb-disabled-bg;
|
||||
}
|
||||
|
||||
&::-webkit-slider-runnable-track {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&::-moz-range-thumb {
|
||||
background-color: $custom-range-thumb-disabled-bg;
|
||||
}
|
||||
|
||||
&::-moz-range-track {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&::-ms-thumb {
|
||||
background-color: $custom-range-thumb-disabled-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.custom-control-label::before,
|
||||
.custom-file-label,
|
||||
.custom-select {
|
||||
@include transition($custom-forms-transition);
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
// The dropdown wrapper (`<div>`)
|
||||
.dropup,
|
||||
.dropright,
|
||||
.dropdown,
|
||||
.dropleft {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
white-space: nowrap;
|
||||
|
||||
// Generate the caret automatically
|
||||
@include caret();
|
||||
}
|
||||
|
||||
// The dropdown menu
|
||||
.dropdown-menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
z-index: $zindex-dropdown;
|
||||
display: none; // none by default, but block on "open" of the menu
|
||||
float: left;
|
||||
min-width: $dropdown-min-width;
|
||||
padding: $dropdown-padding-y $dropdown-padding-x;
|
||||
margin: $dropdown-spacer 0 0; // override default ul
|
||||
@include font-size($dropdown-font-size);
|
||||
color: $dropdown-color;
|
||||
text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
|
||||
list-style: none;
|
||||
background-color: $dropdown-bg;
|
||||
background-clip: padding-box;
|
||||
border: $dropdown-border-width solid $dropdown-border-color;
|
||||
@include border-radius($dropdown-border-radius);
|
||||
@include box-shadow($dropdown-box-shadow);
|
||||
}
|
||||
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
@include media-breakpoint-up($breakpoint) {
|
||||
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
|
||||
|
||||
.dropdown-menu#{$infix}-left {
|
||||
right: auto;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.dropdown-menu#{$infix}-right {
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow for dropdowns to go bottom up (aka, dropup-menu)
|
||||
// Just add .dropup after the standard .dropdown class and you're set.
|
||||
.dropup {
|
||||
.dropdown-menu {
|
||||
top: auto;
|
||||
bottom: 100%;
|
||||
margin-top: 0;
|
||||
margin-bottom: $dropdown-spacer;
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
@include caret(up);
|
||||
}
|
||||
}
|
||||
|
||||
.dropright {
|
||||
.dropdown-menu {
|
||||
top: 0;
|
||||
right: auto;
|
||||
left: 100%;
|
||||
margin-top: 0;
|
||||
margin-left: $dropdown-spacer;
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
@include caret(right);
|
||||
&::after {
|
||||
vertical-align: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropleft {
|
||||
.dropdown-menu {
|
||||
top: 0;
|
||||
right: 100%;
|
||||
left: auto;
|
||||
margin-top: 0;
|
||||
margin-right: $dropdown-spacer;
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
@include caret(left);
|
||||
&::before {
|
||||
vertical-align: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When Popper is enabled, reset the basic dropdown position
|
||||
// stylelint-disable-next-line no-duplicate-selectors
|
||||
.dropdown-menu {
|
||||
&[x-placement^="top"],
|
||||
&[x-placement^="right"],
|
||||
&[x-placement^="bottom"],
|
||||
&[x-placement^="left"] {
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// Dividers (basically an `<hr>`) within the dropdown
|
||||
.dropdown-divider {
|
||||
@include nav-divider($dropdown-divider-bg, $dropdown-divider-margin-y, true);
|
||||
}
|
||||
|
||||
// Links, buttons, and more within the dropdown menu
|
||||
//
|
||||
// `<button>`-specific styles are denoted with `// For <button>s`
|
||||
.dropdown-item {
|
||||
display: block;
|
||||
width: 100%; // For `<button>`s
|
||||
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
|
||||
clear: both;
|
||||
font-weight: $font-weight-normal;
|
||||
color: $dropdown-link-color;
|
||||
text-align: inherit; // For `<button>`s
|
||||
text-decoration: if($link-decoration == none, null, none);
|
||||
white-space: nowrap; // prevent links from randomly breaking onto new lines
|
||||
background-color: transparent; // For `<button>`s
|
||||
border: 0; // For `<button>`s
|
||||
|
||||
// Prevent dropdown overflow if there's no padding
|
||||
// See https://github.com/twbs/bootstrap/pull/27703
|
||||
@if $dropdown-padding-y == 0 {
|
||||
&:first-child {
|
||||
@include border-top-radius($dropdown-inner-border-radius);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
@include border-bottom-radius($dropdown-inner-border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
@include hover-focus() {
|
||||
color: $dropdown-link-hover-color;
|
||||
text-decoration: none;
|
||||
@include gradient-bg($dropdown-link-hover-bg);
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:active {
|
||||
color: $dropdown-link-active-color;
|
||||
text-decoration: none;
|
||||
@include gradient-bg($dropdown-link-active-bg);
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&:disabled {
|
||||
color: $dropdown-link-disabled-color;
|
||||
pointer-events: none;
|
||||
background-color: transparent;
|
||||
// Remove CSS gradients if they're enabled
|
||||
@if $enable-gradients {
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
// Dropdown section headers
|
||||
.dropdown-header {
|
||||
display: block;
|
||||
padding: $dropdown-header-padding;
|
||||
margin-bottom: 0; // for use with heading elements
|
||||
@include font-size($font-size-sm);
|
||||
color: $dropdown-header-color;
|
||||
white-space: nowrap; // as with > li > a
|
||||
}
|
||||
|
||||
// Dropdown text
|
||||
.dropdown-item-text {
|
||||
display: block;
|
||||
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
|
||||
color: $dropdown-link-color;
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
|
||||
//
|
||||
// Textual form controls
|
||||
//
|
||||
|
||||
.form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: $input-height;
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
font-family: $input-font-family;
|
||||
@include font-size($input-font-size);
|
||||
font-weight: $input-font-weight;
|
||||
line-height: $input-line-height;
|
||||
color: $input-color;
|
||||
background-color: $input-bg;
|
||||
background-clip: padding-box;
|
||||
border: $input-border-width solid $input-border-color;
|
||||
|
||||
// Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
|
||||
@include border-radius($input-border-radius, 0);
|
||||
|
||||
@include box-shadow($input-box-shadow);
|
||||
@include transition($input-transition);
|
||||
|
||||
// Unstyle the caret on `<select>`s in IE10+.
|
||||
&::-ms-expand {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
// Remove select outline from select box in FF
|
||||
&:-moz-focusring {
|
||||
color: transparent;
|
||||
text-shadow: 0 0 0 $input-color;
|
||||
}
|
||||
|
||||
// Customize the `:focus` state to imitate native WebKit styles.
|
||||
@include form-control-focus($ignore-warning: true);
|
||||
|
||||
// Placeholder
|
||||
&::placeholder {
|
||||
color: $input-placeholder-color;
|
||||
// Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
// Disabled and read-only inputs
|
||||
//
|
||||
// HTML5 says that controls under a fieldset > legend:first-child won't be
|
||||
// disabled if the fieldset is disabled. Due to implementation difficulty, we
|
||||
// don't honor that edge case; we style them as disabled anyway.
|
||||
&:disabled,
|
||||
&[readonly] {
|
||||
background-color: $input-disabled-bg;
|
||||
// iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="date"],
|
||||
input[type="time"],
|
||||
input[type="datetime-local"],
|
||||
input[type="month"] {
|
||||
&.form-control {
|
||||
appearance: none; // Fix appearance for date inputs in Safari
|
||||
}
|
||||
}
|
||||
|
||||
select.form-control {
|
||||
&:focus::-ms-value {
|
||||
// Suppress the nested default white text on blue background highlight given to
|
||||
// the selected option text when the (still closed) <select> receives focus
|
||||
// in IE and (under certain conditions) Edge, as it looks bad and cannot be made to
|
||||
// match the appearance of the native widget.
|
||||
// See https://github.com/twbs/bootstrap/issues/19398.
|
||||
color: $input-color;
|
||||
background-color: $input-bg;
|
||||
}
|
||||
}
|
||||
|
||||
// Make file inputs better match text inputs by forcing them to new lines.
|
||||
.form-control-file,
|
||||
.form-control-range {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Labels
|
||||
//
|
||||
|
||||
// For use with horizontal and inline forms, when you need the label (or legend)
|
||||
// text to align with the form controls.
|
||||
.col-form-label {
|
||||
padding-top: add($input-padding-y, $input-border-width);
|
||||
padding-bottom: add($input-padding-y, $input-border-width);
|
||||
margin-bottom: 0; // Override the `<label>/<legend>` default
|
||||
@include font-size(inherit); // Override the `<legend>` default
|
||||
line-height: $input-line-height;
|
||||
}
|
||||
|
||||
.col-form-label-lg {
|
||||
padding-top: add($input-padding-y-lg, $input-border-width);
|
||||
padding-bottom: add($input-padding-y-lg, $input-border-width);
|
||||
@include font-size($input-font-size-lg);
|
||||
line-height: $input-line-height-lg;
|
||||
}
|
||||
|
||||
.col-form-label-sm {
|
||||
padding-top: add($input-padding-y-sm, $input-border-width);
|
||||
padding-bottom: add($input-padding-y-sm, $input-border-width);
|
||||
@include font-size($input-font-size-sm);
|
||||
line-height: $input-line-height-sm;
|
||||
}
|
||||
|
||||
|
||||
// Readonly controls as plain text
|
||||
//
|
||||
// Apply class to a readonly input to make it appear like regular plain
|
||||
// text (without any border, background color, focus indicator)
|
||||
|
||||
.form-control-plaintext {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: $input-padding-y 0;
|
||||
margin-bottom: 0; // match inputs if this class comes on inputs with default margins
|
||||
@include font-size($input-font-size);
|
||||
line-height: $input-line-height;
|
||||
color: $input-plaintext-color;
|
||||
background-color: transparent;
|
||||
border: solid transparent;
|
||||
border-width: $input-border-width 0;
|
||||
|
||||
&.form-control-sm,
|
||||
&.form-control-lg {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Form control sizing
|
||||
//
|
||||
// Build on `.form-control` with modifier classes to decrease or increase the
|
||||
// height and font-size of form controls.
|
||||
//
|
||||
// Repeated in `_input_group.scss` to avoid Sass extend issues.
|
||||
|
||||
.form-control-sm {
|
||||
height: $input-height-sm;
|
||||
padding: $input-padding-y-sm $input-padding-x-sm;
|
||||
@include font-size($input-font-size-sm);
|
||||
line-height: $input-line-height-sm;
|
||||
@include border-radius($input-border-radius-sm);
|
||||
}
|
||||
|
||||
.form-control-lg {
|
||||
height: $input-height-lg;
|
||||
padding: $input-padding-y-lg $input-padding-x-lg;
|
||||
@include font-size($input-font-size-lg);
|
||||
line-height: $input-line-height-lg;
|
||||
@include border-radius($input-border-radius-lg);
|
||||
}
|
||||
|
||||
// stylelint-disable-next-line no-duplicate-selectors
|
||||
select.form-control {
|
||||
&[size],
|
||||
&[multiple] {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
textarea.form-control {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
// Form groups
|
||||
//
|
||||
// Designed to help with the organization and spacing of vertical forms. For
|
||||
// horizontal forms, use the predefined grid classes.
|
||||
|
||||
.form-group {
|
||||
margin-bottom: $form-group-margin-bottom;
|
||||
}
|
||||
|
||||
.form-text {
|
||||
display: block;
|
||||
margin-top: $form-text-margin-top;
|
||||
}
|
||||
|
||||
|
||||
// Form grid
|
||||
//
|
||||
// Special replacement for our grid system's `.row` for tighter form layouts.
|
||||
|
||||
.form-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-right: -$form-grid-gutter-width / 2;
|
||||
margin-left: -$form-grid-gutter-width / 2;
|
||||
|
||||
> .col,
|
||||
> [class*="col-"] {
|
||||
padding-right: $form-grid-gutter-width / 2;
|
||||
padding-left: $form-grid-gutter-width / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Checkboxes and radios
|
||||
//
|
||||
// Indent the labels to position radios/checkboxes as hanging controls.
|
||||
|
||||
.form-check {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding-left: $form-check-input-gutter;
|
||||
}
|
||||
|
||||
.form-check-input {
|
||||
position: absolute;
|
||||
margin-top: $form-check-input-margin-y;
|
||||
margin-left: -$form-check-input-gutter;
|
||||
|
||||
// Use [disabled] and :disabled for workaround https://github.com/twbs/bootstrap/issues/28247
|
||||
&[disabled] ~ .form-check-label,
|
||||
&:disabled ~ .form-check-label {
|
||||
color: $text-muted;
|
||||
}
|
||||
}
|
||||
|
||||
.form-check-label {
|
||||
margin-bottom: 0; // Override default `<label>` bottom margin
|
||||
}
|
||||
|
||||
.form-check-inline {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding-left: 0; // Override base .form-check
|
||||
margin-right: $form-check-inline-margin-x;
|
||||
|
||||
// Undo .form-check-input defaults and add some `margin-right`.
|
||||
.form-check-input {
|
||||
position: static;
|
||||
margin-top: 0;
|
||||
margin-right: $form-check-inline-input-margin-x;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Form validation
|
||||
//
|
||||
// Provide feedback to users when form field values are valid or invalid. Works
|
||||
// primarily for client-side validation via scoped `:invalid` and `:valid`
|
||||
// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for
|
||||
// server side validation.
|
||||
|
||||
@each $state, $data in $form-validation-states {
|
||||
@include form-validation-state($state, map-get($data, color), map-get($data, icon));
|
||||
}
|
||||
|
||||
// Inline forms
|
||||
//
|
||||
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
|
||||
// forms begin stacked on extra small (mobile) devices and then go inline when
|
||||
// viewports reach <768px.
|
||||
//
|
||||
// Requires wrapping inputs and labels with `.form-group` for proper display of
|
||||
// default HTML form controls and our custom form controls (e.g., input groups).
|
||||
|
||||
.form-inline {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)
|
||||
|
||||
// Because we use flex, the initial sizing of checkboxes is collapsed and
|
||||
// doesn't occupy the full-width (which is what we want for xs grid tier),
|
||||
// so we force that here.
|
||||
.form-check {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// Kick in the inline
|
||||
@include media-breakpoint-up(sm) {
|
||||
label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
// Inline-block all the things for "inline"
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
flex-flow: row wrap;
|
||||
align-items: center;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
// Allow folks to *not* use `.form-group`
|
||||
.form-control {
|
||||
display: inline-block;
|
||||
width: auto; // Prevent labels from stacking above inputs in `.form-group`
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
// Make static controls behave like regular ones
|
||||
.form-control-plaintext {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.input-group,
|
||||
.custom-select {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
// Remove default margin on radios/checkboxes that were used for stacking, and
|
||||
// then undo the floating of radios and checkboxes to match.
|
||||
.form-check {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: auto;
|
||||
padding-left: 0;
|
||||
}
|
||||
.form-check-input {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
margin-top: 0;
|
||||
margin-right: $form-check-input-margin-x;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.custom-control {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.custom-control-label {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
// Bootstrap functions
|
||||
//
|
||||
// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.
|
||||
|
||||
// Ascending
|
||||
// Used to evaluate Sass maps like our grid breakpoints.
|
||||
@mixin _assert-ascending($map, $map-name) {
|
||||
$prev-key: null;
|
||||
$prev-num: null;
|
||||
@each $key, $num in $map {
|
||||
@if $prev-num == null or unit($num) == "%" or unit($prev-num) == "%" {
|
||||
// Do nothing
|
||||
} @else if not comparable($prev-num, $num) {
|
||||
@warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
|
||||
} @else if $prev-num >= $num {
|
||||
@warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
|
||||
}
|
||||
$prev-key: $key;
|
||||
$prev-num: $num;
|
||||
}
|
||||
}
|
||||
|
||||
// Starts at zero
|
||||
// Used to ensure the min-width of the lowest breakpoint starts at 0.
|
||||
@mixin _assert-starts-at-zero($map, $map-name: "$grid-breakpoints") {
|
||||
@if length($map) > 0 {
|
||||
$values: map-values($map);
|
||||
$first-value: nth($values, 1);
|
||||
@if $first-value != 0 {
|
||||
@warn "First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace `$search` with `$replace` in `$string`
|
||||
// Used on our SVG icon backgrounds for custom forms.
|
||||
//
|
||||
// @author Hugo Giraudel
|
||||
// @param {String} $string - Initial string
|
||||
// @param {String} $search - Substring to replace
|
||||
// @param {String} $replace ('') - New value
|
||||
// @return {String} - Updated string
|
||||
@function str-replace($string, $search, $replace: "") {
|
||||
$index: str-index($string, $search);
|
||||
|
||||
@if $index {
|
||||
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
|
||||
}
|
||||
|
||||
@return $string;
|
||||
}
|
||||
|
||||
// See https://codepen.io/kevinweber/pen/dXWoRw
|
||||
//
|
||||
// Requires the use of quotes around data URIs.
|
||||
|
||||
@function escape-svg($string) {
|
||||
@if str-index($string, "data:image/svg+xml") {
|
||||
@each $char, $encoded in $escaped-characters {
|
||||
// Do not escape the url brackets
|
||||
@if str-index($string, "url(") == 1 {
|
||||
$string: url("#{str-replace(str-slice($string, 6, -3), $char, $encoded)}");
|
||||
} @else {
|
||||
$string: str-replace($string, $char, $encoded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@return $string;
|
||||
}
|
||||
|
||||
// Color contrast
|
||||
@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) {
|
||||
$r: red($color);
|
||||
$g: green($color);
|
||||
$b: blue($color);
|
||||
|
||||
$yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
|
||||
|
||||
@if ($yiq >= $yiq-contrasted-threshold) {
|
||||
@return $dark;
|
||||
} @else {
|
||||
@return $light;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve color Sass maps
|
||||
@function color($key: "blue") {
|
||||
@return map-get($colors, $key);
|
||||
}
|
||||
|
||||
@function theme-color($key: "primary") {
|
||||
@return map-get($theme-colors, $key);
|
||||
}
|
||||
|
||||
@function gray($key: "100") {
|
||||
@return map-get($grays, $key);
|
||||
}
|
||||
|
||||
// Request a theme color level
|
||||
@function theme-color-level($color-name: "primary", $level: 0) {
|
||||
$color: theme-color($color-name);
|
||||
$color-base: if($level > 0, $black, $white);
|
||||
$level: abs($level);
|
||||
|
||||
@return mix($color-base, $color, $level * $theme-color-interval);
|
||||
}
|
||||
|
||||
// Return valid calc
|
||||
@function add($value1, $value2, $return-calc: true) {
|
||||
@if $value1 == null {
|
||||
@return $value2;
|
||||
}
|
||||
|
||||
@if $value2 == null {
|
||||
@return $value1;
|
||||
}
|
||||
|
||||
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
|
||||
@return $value1 + $value2;
|
||||
}
|
||||
|
||||
@return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(" + ") + $value2);
|
||||
}
|
||||
|
||||
@function subtract($value1, $value2, $return-calc: true) {
|
||||
@if $value1 == null and $value2 == null {
|
||||
@return null;
|
||||
}
|
||||
|
||||
@if $value1 == null {
|
||||
@return -$value2;
|
||||
}
|
||||
|
||||
@if $value2 == null {
|
||||
@return $value1;
|
||||
}
|
||||
|
||||
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
|
||||
@return $value1 - $value2;
|
||||
}
|
||||
|
||||
@return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(" - ") + $value2);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// Container widths
|
||||
//
|
||||
// Set the container width, and override it for fixed navbars in media queries.
|
||||
|
||||
@if $enable-grid-classes {
|
||||
// Single container class with breakpoint max-widths
|
||||
.container,
|
||||
// 100% wide container at all breakpoints
|
||||
.container-fluid {
|
||||
@include make-container();
|
||||
}
|
||||
|
||||
// Responsive containers that are 100% wide until a breakpoint
|
||||
@each $breakpoint, $container-max-width in $container-max-widths {
|
||||
.container-#{$breakpoint} {
|
||||
@extend .container-fluid;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up($breakpoint, $grid-breakpoints) {
|
||||
%responsive-container-#{$breakpoint} {
|
||||
max-width: $container-max-width;
|
||||
}
|
||||
|
||||
// Extend each breakpoint which is smaller or equal to the current breakpoint
|
||||
$extend-breakpoint: true;
|
||||
|
||||
@each $name, $width in $grid-breakpoints {
|
||||
@if ($extend-breakpoint) {
|
||||
.container#{breakpoint-infix($name, $grid-breakpoints)} {
|
||||
@extend %responsive-container-#{$breakpoint};
|
||||
}
|
||||
|
||||
// Once the current breakpoint is reached, stop extending
|
||||
@if ($breakpoint == $name) {
|
||||
$extend-breakpoint: false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Row
|
||||
//
|
||||
// Rows contain your columns.
|
||||
|
||||
@if $enable-grid-classes {
|
||||
.row {
|
||||
@include make-row();
|
||||
}
|
||||
|
||||
// Remove the negative margin from default .row, then the horizontal padding
|
||||
// from all immediate children columns (to prevent runaway style inheritance).
|
||||
.no-gutters {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
|
||||
> .col,
|
||||
> [class*="col-"] {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Columns
|
||||
//
|
||||
// Common styles for small and large grid columns
|
||||
|
||||
@if $enable-grid-classes {
|
||||
@include make-grid-columns();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Responsive images (ensure images don't scale beyond their parents)
|
||||
//
|
||||
// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.
|
||||
// We previously tried the "images are responsive by default" approach in Bootstrap v2,
|
||||
// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)
|
||||
// which weren't expecting the images within themselves to be involuntarily resized.
|
||||
// See also https://github.com/twbs/bootstrap/issues/18178
|
||||
.img-fluid {
|
||||
@include img-fluid();
|
||||
}
|
||||
|
||||
|
||||
// Image thumbnails
|
||||
.img-thumbnail {
|
||||
padding: $thumbnail-padding;
|
||||
background-color: $thumbnail-bg;
|
||||
border: $thumbnail-border-width solid $thumbnail-border-color;
|
||||
@include border-radius($thumbnail-border-radius);
|
||||
@include box-shadow($thumbnail-box-shadow);
|
||||
|
||||
// Keep them at most 100% wide
|
||||
@include img-fluid();
|
||||
}
|
||||
|
||||
//
|
||||
// Figures
|
||||
//
|
||||
|
||||
.figure {
|
||||
// Ensures the caption's text aligns with the image.
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.figure-img {
|
||||
margin-bottom: $spacer / 2;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.figure-caption {
|
||||
@include font-size($figure-caption-font-size);
|
||||
color: $figure-caption-color;
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
|
||||
//
|
||||
// Base styles
|
||||
//
|
||||
|
||||
.input-group {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-wrap: wrap; // For form validation feedback
|
||||
align-items: stretch;
|
||||
width: 100%;
|
||||
|
||||
> .form-control,
|
||||
> .form-control-plaintext,
|
||||
> .custom-select,
|
||||
> .custom-file {
|
||||
position: relative; // For focus state's z-index
|
||||
flex: 1 1 auto;
|
||||
width: 1%;
|
||||
min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size
|
||||
margin-bottom: 0;
|
||||
|
||||
+ .form-control,
|
||||
+ .custom-select,
|
||||
+ .custom-file {
|
||||
margin-left: -$input-border-width;
|
||||
}
|
||||
}
|
||||
|
||||
// Bring the "active" form control to the top of surrounding elements
|
||||
> .form-control:focus,
|
||||
> .custom-select:focus,
|
||||
> .custom-file .custom-file-input:focus ~ .custom-file-label {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
// Bring the custom file input above the label
|
||||
> .custom-file .custom-file-input:focus {
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
> .form-control,
|
||||
> .custom-select {
|
||||
&:not(:first-child) { @include border-left-radius(0); }
|
||||
}
|
||||
|
||||
// Custom file inputs have more complex markup, thus requiring different
|
||||
// border-radius overrides.
|
||||
> .custom-file {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:not(:last-child) .custom-file-label,
|
||||
&:not(:first-child) .custom-file-label { @include border-left-radius(0); }
|
||||
}
|
||||
|
||||
&:not(.has-validation) {
|
||||
> .form-control:not(:last-child),
|
||||
> .custom-select:not(:last-child),
|
||||
> .custom-file:not(:last-child) .custom-file-label::after {
|
||||
@include border-right-radius(0);
|
||||
}
|
||||
}
|
||||
|
||||
&.has-validation {
|
||||
> .form-control:nth-last-child(n + 3),
|
||||
> .custom-select:nth-last-child(n + 3),
|
||||
> .custom-file:nth-last-child(n + 3) .custom-file-label::after {
|
||||
@include border-right-radius(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Prepend and append
|
||||
//
|
||||
// While it requires one extra layer of HTML for each, dedicated prepend and
|
||||
// append elements allow us to 1) be less clever, 2) simplify our selectors, and
|
||||
// 3) support HTML5 form validation.
|
||||
|
||||
.input-group-prepend,
|
||||
.input-group-append {
|
||||
display: flex;
|
||||
|
||||
// Ensure buttons are always above inputs for more visually pleasing borders.
|
||||
// This isn't needed for `.input-group-text` since it shares the same border-color
|
||||
// as our inputs.
|
||||
.btn {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
&:focus {
|
||||
z-index: 3;
|
||||
}
|
||||
}
|
||||
|
||||
.btn + .btn,
|
||||
.btn + .input-group-text,
|
||||
.input-group-text + .input-group-text,
|
||||
.input-group-text + .btn {
|
||||
margin-left: -$input-border-width;
|
||||
}
|
||||
}
|
||||
|
||||
.input-group-prepend { margin-right: -$input-border-width; }
|
||||
.input-group-append { margin-left: -$input-border-width; }
|
||||
|
||||
|
||||
// Textual addons
|
||||
//
|
||||
// Serves as a catch-all element for any text or radio/checkbox input you wish
|
||||
// to prepend or append to an input.
|
||||
|
||||
.input-group-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom
|
||||
@include font-size($input-font-size); // Match inputs
|
||||
font-weight: $font-weight-normal;
|
||||
line-height: $input-line-height;
|
||||
color: $input-group-addon-color;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
background-color: $input-group-addon-bg;
|
||||
border: $input-border-width solid $input-group-addon-border-color;
|
||||
@include border-radius($input-border-radius);
|
||||
|
||||
// Nuke default margins from checkboxes and radios to vertically center within.
|
||||
input[type="radio"],
|
||||
input[type="checkbox"] {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sizing
|
||||
//
|
||||
// Remix the default form control sizing classes into new ones for easier
|
||||
// manipulation.
|
||||
|
||||
.input-group-lg > .form-control:not(textarea),
|
||||
.input-group-lg > .custom-select {
|
||||
height: $input-height-lg;
|
||||
}
|
||||
|
||||
.input-group-lg > .form-control,
|
||||
.input-group-lg > .custom-select,
|
||||
.input-group-lg > .input-group-prepend > .input-group-text,
|
||||
.input-group-lg > .input-group-append > .input-group-text,
|
||||
.input-group-lg > .input-group-prepend > .btn,
|
||||
.input-group-lg > .input-group-append > .btn {
|
||||
padding: $input-padding-y-lg $input-padding-x-lg;
|
||||
@include font-size($input-font-size-lg);
|
||||
line-height: $input-line-height-lg;
|
||||
@include border-radius($input-border-radius-lg);
|
||||
}
|
||||
|
||||
.input-group-sm > .form-control:not(textarea),
|
||||
.input-group-sm > .custom-select {
|
||||
height: $input-height-sm;
|
||||
}
|
||||
|
||||
.input-group-sm > .form-control,
|
||||
.input-group-sm > .custom-select,
|
||||
.input-group-sm > .input-group-prepend > .input-group-text,
|
||||
.input-group-sm > .input-group-append > .input-group-text,
|
||||
.input-group-sm > .input-group-prepend > .btn,
|
||||
.input-group-sm > .input-group-append > .btn {
|
||||
padding: $input-padding-y-sm $input-padding-x-sm;
|
||||
@include font-size($input-font-size-sm);
|
||||
line-height: $input-line-height-sm;
|
||||
@include border-radius($input-border-radius-sm);
|
||||
}
|
||||
|
||||
.input-group-lg > .custom-select,
|
||||
.input-group-sm > .custom-select {
|
||||
padding-right: $custom-select-padding-x + $custom-select-indicator-padding;
|
||||
}
|
||||
|
||||
|
||||
// Prepend and append rounded corners
|
||||
//
|
||||
// These rulesets must come after the sizing ones to properly override sm and lg
|
||||
// border-radius values when extending. They're more specific than we'd like
|
||||
// with the `.input-group >` part, but without it, we cannot override the sizing.
|
||||
|
||||
|
||||
.input-group > .input-group-prepend > .btn,
|
||||
.input-group > .input-group-prepend > .input-group-text,
|
||||
.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .btn,
|
||||
.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .input-group-text,
|
||||
.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .btn,
|
||||
.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .input-group-text,
|
||||
.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
|
||||
.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {
|
||||
@include border-right-radius(0);
|
||||
}
|
||||
|
||||
.input-group > .input-group-append > .btn,
|
||||
.input-group > .input-group-append > .input-group-text,
|
||||
.input-group > .input-group-prepend:not(:first-child) > .btn,
|
||||
.input-group > .input-group-prepend:not(:first-child) > .input-group-text,
|
||||
.input-group > .input-group-prepend:first-child > .btn:not(:first-child),
|
||||
.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {
|
||||
@include border-left-radius(0);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user