This commit is contained in:
@@ -197,5 +197,72 @@ namespace Aberwyn.Controllers
|
||||
return RedirectToAction("Categories");
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("/meal/lab")]
|
||||
public IActionResult Lab(int? id)
|
||||
{
|
||||
if (id.HasValue)
|
||||
{
|
||||
var entry = _menuService.GetRecipeLabEntryById(id.Value);
|
||||
if (entry == null) return NotFound();
|
||||
|
||||
return View("Lab", entry);
|
||||
}
|
||||
|
||||
// Skapa ett tomt labb-entry för formulär
|
||||
var newEntry = new RecipeLabEntry
|
||||
{
|
||||
Title = "",
|
||||
Inspiration = "",
|
||||
Notes = "",
|
||||
Tags = ""
|
||||
};
|
||||
|
||||
return View("Lab", newEntry);
|
||||
}
|
||||
[HttpPost("/meal/lab/create")]
|
||||
public IActionResult CreateLabEntry(RecipeLabEntry entry)
|
||||
{
|
||||
entry.CreatedAt = DateTime.Now;
|
||||
_menuService.AddLabEntry(entry);
|
||||
|
||||
return RedirectToAction("Lab", new { id = entry.Id });
|
||||
}
|
||||
|
||||
[HttpPost("/meal/lab/save-ingredients")]
|
||||
public IActionResult SaveLabIngredients(int RecipeLabEntryId, List<LabIngredient> Ingredients)
|
||||
{
|
||||
_menuService.SaveIngredientsForLabEntry(RecipeLabEntryId, Ingredients);
|
||||
return RedirectToAction("Lab", new { id = RecipeLabEntryId });
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("/meal/lab/addversion")]
|
||||
public IActionResult AddLabVersion(RecipeLabVersion version)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
return RedirectToAction("Lab", new { id = version.RecipeLabEntryId });
|
||||
|
||||
var entry = _menuService.GetRecipeLabEntryById(version.RecipeLabEntryId);
|
||||
if (entry == null) return NotFound();
|
||||
|
||||
version.CreatedAt = DateTime.Now;
|
||||
|
||||
// Kopiera nuvarande ingredienser
|
||||
var copiedIngredients = entry.Ingredients
|
||||
.Select(i => new LabVersionIngredient
|
||||
{
|
||||
Quantity = i.Quantity,
|
||||
Item = i.Item
|
||||
})
|
||||
.ToList();
|
||||
|
||||
_menuService.SaveLabVersionWithIngredients(version, copiedIngredients);
|
||||
|
||||
return RedirectToAction("Lab", new { id = version.RecipeLabEntryId });
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,6 +47,11 @@ namespace Aberwyn.Data
|
||||
public DbSet<UserPreferences> UserPreferences { get; set; }
|
||||
public DbSet<StoredPushSubscription> PushSubscriptions { get; set; }
|
||||
public DbSet<MealCategory> MealCategories { get; set; }
|
||||
public DbSet<RecipeLabEntry> RecipeLabEntries { get; set; }
|
||||
public DbSet<RecipeLabVersion> RecipeLabVersions { get; set; }
|
||||
public DbSet<LabIngredient> LabIngredients { get; set; }
|
||||
public DbSet<LabVersionIngredient> LabVersionIngredients { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,7 +466,7 @@ public List<WeeklyMenu> GetWeeklyMenu(int weekNumber, int year)
|
||||
}
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
#region Lab
|
||||
public void DeleteCategory(int id)
|
||||
{
|
||||
var cat = _context.MealCategories.Find(id);
|
||||
@@ -476,6 +476,53 @@ public List<WeeklyMenu> GetWeeklyMenu(int weekNumber, int year)
|
||||
_context.SaveChanges();
|
||||
}
|
||||
}
|
||||
public RecipeLabEntry? GetRecipeLabEntryById(int id)
|
||||
{
|
||||
return _context.RecipeLabEntries
|
||||
.Include(e => e.Versions)
|
||||
.FirstOrDefault(e => e.Id == id);
|
||||
}
|
||||
|
||||
public void AddVersionToLabEntry(RecipeLabVersion version)
|
||||
{
|
||||
_context.RecipeLabVersions.Add(version);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
public void AddLabEntry(RecipeLabEntry entry)
|
||||
{
|
||||
_context.RecipeLabEntries.Add(entry);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
public void SaveLabVersionWithIngredients(RecipeLabVersion version, List<LabVersionIngredient> ingredients)
|
||||
{
|
||||
_context.RecipeLabVersions.Add(version);
|
||||
_context.SaveChanges(); // så vi får ett ID
|
||||
|
||||
foreach (var ing in ingredients)
|
||||
{
|
||||
ing.RecipeLabVersionId = version.Id;
|
||||
}
|
||||
|
||||
_context.LabVersionIngredients.AddRange(ingredients);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
public void SaveIngredientsForLabEntry(int labEntryId, List<LabIngredient> ingredients)
|
||||
{
|
||||
var existing = _context.LabIngredients
|
||||
.Where(i => i.RecipeLabEntryId == labEntryId)
|
||||
.ToList();
|
||||
|
||||
_context.LabIngredients.RemoveRange(existing);
|
||||
|
||||
foreach (var ing in ingredients)
|
||||
ing.RecipeLabEntryId = labEntryId;
|
||||
|
||||
_context.LabIngredients.AddRange(ingredients);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
949
Aberwyn/Migrations/20250630123620_AddRecipeLab.Designer.cs
generated
Normal file
949
Aberwyn/Migrations/20250630123620_AddRecipeLab.Designer.cs
generated
Normal file
@@ -0,0 +1,949 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Aberwyn.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20250630123620_AddRecipeLab")]
|
||||
partial class AddRecipeLab
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.36")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", 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", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.AppSetting", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Key")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("AppSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("BudgetCategoryDefinitionId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("BudgetPeriodId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Color")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("Order")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BudgetCategoryDefinitionId");
|
||||
|
||||
b.HasIndex("BudgetPeriodId");
|
||||
|
||||
b.ToTable("BudgetCategories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.BudgetCategoryDefinition", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Color")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BudgetCategoryDefinitions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<decimal>("Amount")
|
||||
.HasColumnType("decimal(65,30)");
|
||||
|
||||
b.Property<int>("BudgetCategoryId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("BudgetItemDefinitionId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("IncludeInSummary")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("IsExpense")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("Order")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("PaymentStatus")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BudgetCategoryId");
|
||||
|
||||
b.HasIndex("BudgetItemDefinitionId");
|
||||
|
||||
b.ToTable("BudgetItems");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.BudgetItemDefinition", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("DefaultCategory")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("DefaultPaymentStatus")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("IncludeInSummary")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("IsExpense")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BudgetItemDefinitions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Month")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Order")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Year")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BudgetPeriods");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.Ingredient", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Item")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("MealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Quantity")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MealId");
|
||||
|
||||
b.ToTable("Ingredients");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.Meal", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("CarbType")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<byte[]>("ImageData")
|
||||
.HasColumnType("longblob");
|
||||
|
||||
b.Property<string>("ImageMimeType")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("ImageUrl")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Instructions")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("IsAvailable")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("IsPublished")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<int?>("MealCategoryId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("ProteinType")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("RecipeUrl")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<byte[]>("ThumbnailData")
|
||||
.HasColumnType("longblob");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MealCategoryId");
|
||||
|
||||
b.ToTable("Meals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.MealCategory", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Color")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("DisplayOrder")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Icon")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("MealCategories");
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = 1,
|
||||
Color = "#f97316",
|
||||
DisplayOrder = 1,
|
||||
Icon = "🍕",
|
||||
IsActive = true,
|
||||
Name = "Pizza",
|
||||
Slug = "pizza"
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.PizzaOrder", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("CustomerName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("IngredientsJson")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("OrderedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("PizzaName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PizzaOrders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.PushSubscriber", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Auth")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Endpoint")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("P256DH")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("PizzaOrderId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PizzaOrderId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("PushSubscribers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.RecipeLabEntry", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("BaseMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Category")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Inspiration")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("Rating")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Tags")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("TestedBy")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BaseMealId");
|
||||
|
||||
b.ToTable("RecipeLabEntries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.RecipeLabVersion", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Ingredients")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Instructions")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("RecipeLabEntryId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ResultNotes")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("VersionLabel")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RecipeLabEntryId");
|
||||
|
||||
b.ToTable("RecipeLabVersions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.StoredPushSubscription", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Auth")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Endpoint")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("P256DH")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("PushSubscriptions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.TodoTask", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("AssignedTo")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("IsArchived")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<int>("Priority")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Tags")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("TodoTasks");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.UserPreferences", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<bool>("NotifyBudget")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("NotifyMenu")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("NotifyPizza")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.HasKey("UserId");
|
||||
|
||||
b.ToTable("UserPreferences");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.WeeklyMenu", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("BreakfastMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Cook")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<int>("DayOfWeek")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("DinnerMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("LunchMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("WeekNumber")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Year")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("WeeklyMenu", (string)null);
|
||||
});
|
||||
|
||||
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", (string)null);
|
||||
});
|
||||
|
||||
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", (string)null);
|
||||
});
|
||||
|
||||
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", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins", (string)null);
|
||||
});
|
||||
|
||||
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", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.BudgetCategoryDefinition", "Definition")
|
||||
.WithMany()
|
||||
.HasForeignKey("BudgetCategoryDefinitionId");
|
||||
|
||||
b.HasOne("Aberwyn.Models.BudgetPeriod", "BudgetPeriod")
|
||||
.WithMany("Categories")
|
||||
.HasForeignKey("BudgetPeriodId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("BudgetPeriod");
|
||||
|
||||
b.Navigation("Definition");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.BudgetItem", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.BudgetCategory", null)
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("BudgetCategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Aberwyn.Models.BudgetItemDefinition", "BudgetItemDefinition")
|
||||
.WithMany()
|
||||
.HasForeignKey("BudgetItemDefinitionId");
|
||||
|
||||
b.Navigation("BudgetItemDefinition");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.Ingredient", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.Meal", null)
|
||||
.WithMany("Ingredients")
|
||||
.HasForeignKey("MealId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.Meal", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.MealCategory", "Category")
|
||||
.WithMany("Meals")
|
||||
.HasForeignKey("MealCategoryId");
|
||||
|
||||
b.Navigation("Category");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.PushSubscriber", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.PizzaOrder", "PizzaOrder")
|
||||
.WithMany()
|
||||
.HasForeignKey("PizzaOrderId");
|
||||
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("PizzaOrder");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.RecipeLabEntry", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.Meal", "BaseMeal")
|
||||
.WithMany()
|
||||
.HasForeignKey("BaseMealId");
|
||||
|
||||
b.Navigation("BaseMeal");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.RecipeLabVersion", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.RecipeLabEntry", "Entry")
|
||||
.WithMany("Versions")
|
||||
.HasForeignKey("RecipeLabEntryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Entry");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.StoredPushSubscription", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.UserPreferences", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", "User")
|
||||
.WithOne("Preferences")
|
||||
.HasForeignKey("Aberwyn.Models.UserPreferences", "UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
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("Aberwyn.Models.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", 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("Aberwyn.Models.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.ApplicationUser", b =>
|
||||
{
|
||||
b.Navigation("Preferences")
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.BudgetCategory", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.BudgetPeriod", b =>
|
||||
{
|
||||
b.Navigation("Categories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.Meal", b =>
|
||||
{
|
||||
b.Navigation("Ingredients");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.MealCategory", b =>
|
||||
{
|
||||
b.Navigation("Meals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.RecipeLabEntry", b =>
|
||||
{
|
||||
b.Navigation("Versions");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
95
Aberwyn/Migrations/20250630123620_AddRecipeLab.cs
Normal file
95
Aberwyn/Migrations/20250630123620_AddRecipeLab.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
public partial class AddRecipeLab : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "RecipeLabEntries",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Title = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Category = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Inspiration = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
BaseMealId = table.Column<int>(type: "int", nullable: true),
|
||||
Notes = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Rating = table.Column<int>(type: "int", nullable: true),
|
||||
TestedBy = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Tags = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_RecipeLabEntries", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_RecipeLabEntries_Meals_BaseMealId",
|
||||
column: x => x.BaseMealId,
|
||||
principalTable: "Meals",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "RecipeLabVersions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
RecipeLabEntryId = table.Column<int>(type: "int", nullable: false),
|
||||
VersionLabel = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Ingredients = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Instructions = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ResultNotes = table.Column<string>(type: "longtext", nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_RecipeLabVersions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_RecipeLabVersions_RecipeLabEntries_RecipeLabEntryId",
|
||||
column: x => x.RecipeLabEntryId,
|
||||
principalTable: "RecipeLabEntries",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_RecipeLabEntries_BaseMealId",
|
||||
table: "RecipeLabEntries",
|
||||
column: "BaseMealId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_RecipeLabVersions_RecipeLabEntryId",
|
||||
table: "RecipeLabVersions",
|
||||
column: "RecipeLabEntryId");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "RecipeLabVersions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "RecipeLabEntries");
|
||||
}
|
||||
}
|
||||
}
|
||||
1026
Aberwyn/Migrations/20250630133813_AddLabIngredientModel.Designer.cs
generated
Normal file
1026
Aberwyn/Migrations/20250630133813_AddLabIngredientModel.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
80
Aberwyn/Migrations/20250630133813_AddLabIngredientModel.cs
Normal file
80
Aberwyn/Migrations/20250630133813_AddLabIngredientModel.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
public partial class AddLabIngredientModel : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "LabIngredients",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
RecipeLabEntryId = table.Column<int>(type: "int", nullable: false),
|
||||
Quantity = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Item = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_LabIngredients", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_LabIngredients_RecipeLabEntries_RecipeLabEntryId",
|
||||
column: x => x.RecipeLabEntryId,
|
||||
principalTable: "RecipeLabEntries",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "LabVersionIngredients",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
RecipeLabVersionId = table.Column<int>(type: "int", nullable: false),
|
||||
Quantity = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Item = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_LabVersionIngredients", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_LabVersionIngredients_RecipeLabVersions_RecipeLabVersionId",
|
||||
column: x => x.RecipeLabVersionId,
|
||||
principalTable: "RecipeLabVersions",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_LabIngredients_RecipeLabEntryId",
|
||||
table: "LabIngredients",
|
||||
column: "RecipeLabEntryId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_LabVersionIngredients_RecipeLabVersionId",
|
||||
table: "LabVersionIngredients",
|
||||
column: "RecipeLabVersionId");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "LabIngredients");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "LabVersionIngredients");
|
||||
}
|
||||
}
|
||||
}
|
||||
1023
Aberwyn/Migrations/20250630141059_AddRecipeLabModels.Designer.cs
generated
Normal file
1023
Aberwyn/Migrations/20250630141059_AddRecipeLabModels.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
26
Aberwyn/Migrations/20250630141059_AddRecipeLabModels.cs
Normal file
26
Aberwyn/Migrations/20250630141059_AddRecipeLabModels.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aberwyn.Migrations
|
||||
{
|
||||
public partial class AddRecipeLabModels : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Ingredients",
|
||||
table: "RecipeLabVersions");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Ingredients",
|
||||
table: "RecipeLabVersions",
|
||||
type: "longtext",
|
||||
nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,6 +264,54 @@ namespace Aberwyn.Migrations
|
||||
b.ToTable("Ingredients");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.LabIngredient", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Item")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Quantity")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("RecipeLabEntryId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RecipeLabEntryId");
|
||||
|
||||
b.ToTable("LabIngredients");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.LabVersionIngredient", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Item")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Quantity")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("RecipeLabVersionId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RecipeLabVersionId");
|
||||
|
||||
b.ToTable("LabVersionIngredients");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.Meal", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -428,6 +476,76 @@ namespace Aberwyn.Migrations
|
||||
b.ToTable("PushSubscribers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.RecipeLabEntry", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("BaseMealId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Category")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Inspiration")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("Rating")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Tags")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("TestedBy")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BaseMealId");
|
||||
|
||||
b.ToTable("RecipeLabEntries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.RecipeLabVersion", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Instructions")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("RecipeLabEntryId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ResultNotes")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("VersionLabel")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RecipeLabEntryId");
|
||||
|
||||
b.ToTable("RecipeLabVersions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.StoredPushSubscription", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -719,6 +837,28 @@ namespace Aberwyn.Migrations
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.LabIngredient", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.RecipeLabEntry", "Entry")
|
||||
.WithMany("Ingredients")
|
||||
.HasForeignKey("RecipeLabEntryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Entry");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.LabVersionIngredient", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.RecipeLabVersion", "Version")
|
||||
.WithMany("Ingredients")
|
||||
.HasForeignKey("RecipeLabVersionId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Version");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.Meal", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.MealCategory", "Category")
|
||||
@@ -745,6 +885,26 @@ namespace Aberwyn.Migrations
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.RecipeLabEntry", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.Meal", "BaseMeal")
|
||||
.WithMany()
|
||||
.HasForeignKey("BaseMealId");
|
||||
|
||||
b.Navigation("BaseMeal");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.RecipeLabVersion", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.RecipeLabEntry", "Entry")
|
||||
.WithMany("Versions")
|
||||
.HasForeignKey("RecipeLabEntryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Entry");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.StoredPushSubscription", b =>
|
||||
{
|
||||
b.HasOne("Aberwyn.Models.ApplicationUser", "User")
|
||||
@@ -843,6 +1003,18 @@ namespace Aberwyn.Migrations
|
||||
{
|
||||
b.Navigation("Meals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.RecipeLabEntry", b =>
|
||||
{
|
||||
b.Navigation("Ingredients");
|
||||
|
||||
b.Navigation("Versions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aberwyn.Models.RecipeLabVersion", b =>
|
||||
{
|
||||
b.Navigation("Ingredients");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
|
||||
81
Aberwyn/Models/RecipeLab.cs
Normal file
81
Aberwyn/Models/RecipeLab.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Aberwyn.Models
|
||||
{
|
||||
public class RecipeLabEntry
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Title { get; set; }
|
||||
|
||||
public string? Category { get; set; }
|
||||
public string? Inspiration { get; set; }
|
||||
|
||||
public int? BaseMealId { get; set; }
|
||||
|
||||
[ForeignKey("BaseMealId")]
|
||||
public Meal? BaseMeal { get; set; }
|
||||
|
||||
public string? Notes { get; set; }
|
||||
public int? Rating { get; set; }
|
||||
public string? TestedBy { get; set; }
|
||||
public string? Tags { get; set; } // "vego,snabbt"
|
||||
public DateTime CreatedAt { get; set; } = DateTime.Now;
|
||||
public List<LabIngredient> Ingredients { get; set; } = new();
|
||||
|
||||
|
||||
public List<RecipeLabVersion> Versions { get; set; } = new();
|
||||
}
|
||||
public class RecipeLabVersion
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
public int RecipeLabEntryId { get; set; }
|
||||
|
||||
[ForeignKey("RecipeLabEntryId")]
|
||||
public RecipeLabEntry Entry { get; set; }
|
||||
|
||||
public string VersionLabel { get; set; } = "v1";
|
||||
|
||||
public List<LabVersionIngredient> Ingredients { get; set; } = new();
|
||||
|
||||
public string? Instructions { get; set; }
|
||||
public string? ResultNotes { get; set; }
|
||||
public DateTime CreatedAt { get; set; } = DateTime.Now;
|
||||
}
|
||||
|
||||
|
||||
public class LabIngredient
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
public int RecipeLabEntryId { get; set; }
|
||||
|
||||
[ForeignKey("RecipeLabEntryId")]
|
||||
public RecipeLabEntry Entry { get; set; }
|
||||
|
||||
public string Quantity { get; set; } = "";
|
||||
public string Item { get; set; } = "";
|
||||
}
|
||||
public class LabVersionIngredient
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public int RecipeLabVersionId { get; set; }
|
||||
|
||||
[ForeignKey("RecipeLabVersionId")]
|
||||
public RecipeLabVersion Version { get; set; }
|
||||
|
||||
public string Quantity { get; set; } = "";
|
||||
public string Item { get; set; } = "";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
99
Aberwyn/Views/Meal/Lab.cshtml
Normal file
99
Aberwyn/Views/Meal/Lab.cshtml
Normal file
@@ -0,0 +1,99 @@
|
||||
@model Aberwyn.Models.RecipeLabEntry
|
||||
@{
|
||||
ViewData["Title"] = "Matlabb";
|
||||
}
|
||||
|
||||
<h1>Matlabb: @Model.Title</h1>
|
||||
|
||||
<form asp-action="CreateLabEntry" method="post">
|
||||
<input type="hidden" asp-for="Id" />
|
||||
|
||||
<div>
|
||||
<label>Titel</label>
|
||||
<input asp-for="Title" class="form-control" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Kategori</label>
|
||||
<input asp-for="Category" class="form-control" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Inspiration</label>
|
||||
<input asp-for="Inspiration" class="form-control" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Anteckningar</label>
|
||||
<textarea asp-for="Notes" class="form-control"></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label>Taggar</label>
|
||||
<input asp-for="Tags" class="form-control" />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mt-2">Spara info</button>
|
||||
</form>
|
||||
|
||||
<hr />
|
||||
|
||||
<h3>Ingredienser</h3>
|
||||
<form asp-action="SaveLabIngredients" method="post">
|
||||
<input type="hidden" name="RecipeLabEntryId" value="@Model.Id" />
|
||||
|
||||
<div id="ingredient-list">
|
||||
@for (int i = 0; i < Model.Ingredients.Count; i++)
|
||||
{
|
||||
<div class="d-flex mb-2">
|
||||
<input type="text" name="Ingredients[@i].Quantity" value="@Model.Ingredients[i].Quantity" class="form-control me-1" placeholder="Mängd" />
|
||||
<input type="text" name="Ingredients[@i].Item" value="@Model.Ingredients[i].Item" class="form-control me-1" placeholder="Ingrediens" />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success">Spara ingredienser</button>
|
||||
</form>
|
||||
|
||||
<hr />
|
||||
<h3>Versioner</h3>
|
||||
<form asp-action="AddLabVersion" method="post">
|
||||
<input type="hidden" name="RecipeLabEntryId" value="@Model.Id" />
|
||||
|
||||
<div class="mb-2">
|
||||
<label>Versionsnamn</label>
|
||||
<input type="text" name="VersionLabel" value="v@(@Model.Versions.Count + 1)" class="form-control" />
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-secondary">Skapa version från nuvarande ingredienser</button>
|
||||
</form>
|
||||
|
||||
@if (Model.Versions.Any())
|
||||
{
|
||||
<div class="mt-4">
|
||||
@foreach (var version in Model.Versions)
|
||||
{
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<strong>@version.VersionLabel</strong> <span class="text-muted">(@version.CreatedAt.ToShortDateString())</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h5>Ingredienser</h5>
|
||||
@if (version.Ingredients != null && version.Ingredients.Any())
|
||||
{
|
||||
<ul>
|
||||
@foreach (var ing in version.Ingredients)
|
||||
{
|
||||
<li>@ing.Quantity @ing.Item</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
else
|
||||
{
|
||||
<em>Inga ingredienser kopplade.</em>
|
||||
}
|
||||
|
||||
<h5 class="mt-3">Instruktioner</h5>
|
||||
<p>@version.Instructions</p>
|
||||
|
||||
<h5 class="mt-3">Kommentar</h5>
|
||||
<p>@version.ResultNotes</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
Reference in New Issue
Block a user