293 lines
10 KiB
C#
293 lines
10 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using PlotLine.Services;
|
|
using PlotLine.ViewModels;
|
|
|
|
namespace PlotLine.Controllers;
|
|
|
|
[Authorize]
|
|
public sealed class FloorPlansController(IFloorPlanService floorPlans) : Controller
|
|
{
|
|
public async Task<IActionResult> Index(int projectId)
|
|
{
|
|
var model = await floorPlans.ListAsync(projectId);
|
|
return model is null ? NotFound() : View(model);
|
|
}
|
|
|
|
public async Task<IActionResult> Edit(int id)
|
|
{
|
|
var model = await floorPlans.GetEditorAsync(id);
|
|
return model is null ? NotFound() : View(model);
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> Create(FloorPlanEditViewModel model)
|
|
{
|
|
if (!ModelState.IsValid)
|
|
{
|
|
return RedirectToAction(nameof(Index), new { projectId = model.ProjectID });
|
|
}
|
|
|
|
var floorPlanId = await floorPlans.SavePlanAsync(model);
|
|
return RedirectToAction(nameof(Edit), new { id = floorPlanId });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> SavePlan(FloorPlanEditViewModel model)
|
|
{
|
|
if (!ModelState.IsValid)
|
|
{
|
|
var editor = await floorPlans.GetEditorAsync(model.FloorPlanID);
|
|
if (editor is null)
|
|
{
|
|
return NotFound();
|
|
}
|
|
|
|
editor.FloorPlan = model;
|
|
return View("Edit", editor);
|
|
}
|
|
|
|
var floorPlanId = await floorPlans.SavePlanAsync(model);
|
|
TempData["FloorPlanMessage"] = "Floor plan saved.";
|
|
return RedirectToAction(nameof(Edit), new { id = floorPlanId });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> SaveLayout(FloorPlanEditorViewModel model)
|
|
{
|
|
var isAsyncSave = string.Equals(Request.Headers["X-Requested-With"], "XMLHttpRequest", StringComparison.OrdinalIgnoreCase);
|
|
try
|
|
{
|
|
await floorPlans.SaveLayoutAsync(model);
|
|
if (isAsyncSave)
|
|
{
|
|
return Json(new { ok = true, message = "Saved" });
|
|
}
|
|
|
|
TempData["FloorPlanMessage"] = "Layout saved.";
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
if (isAsyncSave)
|
|
{
|
|
Response.StatusCode = StatusCodes.Status400BadRequest;
|
|
return Json(new { ok = false, message = ex.Message });
|
|
}
|
|
|
|
TempData["FloorPlanError"] = ex.Message;
|
|
}
|
|
|
|
return RedirectToAction(nameof(Edit), new { id = model.FloorPlan.FloorPlanID });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> DeletePlan(int id, int projectId)
|
|
{
|
|
await floorPlans.DeletePlanAsync(id);
|
|
TempData["FloorPlanMessage"] = "Floor plan deleted.";
|
|
return RedirectToAction(nameof(Index), new { projectId });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> AddFloor(FloorPlanFloorEditViewModel model)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
await floorPlans.SaveFloorAsync(model);
|
|
TempData["FloorPlanMessage"] = "Floor added.";
|
|
}
|
|
|
|
return RedirectToAction(nameof(Edit), new { id = model.FloorPlanID });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> DeleteFloor(int floorPlanId, int floorPlanFloorId)
|
|
{
|
|
await floorPlans.DeleteFloorAsync(floorPlanFloorId);
|
|
TempData["FloorPlanMessage"] = "Floor deleted.";
|
|
return RedirectToAction(nameof(Edit), new { id = floorPlanId });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> UploadBackground(int floorPlanId, int floorPlanFloorId, IFormFile? backgroundImage)
|
|
{
|
|
if (backgroundImage is null)
|
|
{
|
|
TempData["FloorPlanError"] = "Choose a background image to upload.";
|
|
return RedirectToAction(nameof(Edit), new { id = floorPlanId });
|
|
}
|
|
|
|
var result = await floorPlans.UploadBackgroundAsync(floorPlanId, floorPlanFloorId, backgroundImage);
|
|
TempData[result.Succeeded ? "FloorPlanMessage" : "FloorPlanError"] = result.Succeeded
|
|
? "Background image uploaded."
|
|
: result.ErrorMessage ?? "Background image could not be uploaded.";
|
|
return RedirectToAction(nameof(Edit), new { id = floorPlanId });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> SaveBackgroundSettings(FloorPlanFloorBackgroundSettingsViewModel model)
|
|
{
|
|
var isAsyncSave = string.Equals(Request.Headers["X-Requested-With"], "XMLHttpRequest", StringComparison.OrdinalIgnoreCase);
|
|
try
|
|
{
|
|
await floorPlans.SaveBackgroundSettingsAsync(model);
|
|
if (isAsyncSave)
|
|
{
|
|
return Json(new { ok = true, message = "Saved" });
|
|
}
|
|
|
|
TempData["FloorPlanMessage"] = "Background settings saved.";
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
if (isAsyncSave)
|
|
{
|
|
Response.StatusCode = StatusCodes.Status400BadRequest;
|
|
return Json(new { ok = false, message = ex.Message });
|
|
}
|
|
|
|
TempData["FloorPlanError"] = ex.Message;
|
|
}
|
|
|
|
return RedirectToAction(nameof(Edit), new { id = model.FloorPlanID });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> ResetBackground(int floorPlanId, int floorPlanFloorId)
|
|
{
|
|
await floorPlans.ResetBackgroundAsync(floorPlanId, floorPlanFloorId);
|
|
TempData["FloorPlanMessage"] = "Background position reset.";
|
|
return RedirectToAction(nameof(Edit), new { id = floorPlanId });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> RemoveBackground(int floorPlanId, int floorPlanFloorId)
|
|
{
|
|
await floorPlans.RemoveBackgroundAsync(floorPlanId, floorPlanFloorId);
|
|
TempData["FloorPlanMessage"] = "Background image removed.";
|
|
return RedirectToAction(nameof(Edit), new { id = floorPlanId });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> SaveTransition(int floorPlanId, FloorPlanTransitionEditViewModel model)
|
|
{
|
|
try
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
await floorPlans.SaveTransitionAsync(floorPlanId, model);
|
|
TempData["FloorPlanMessage"] = model.FloorPlanTransitionID == 0 ? "Transition created." : "Transition updated.";
|
|
}
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
TempData["FloorPlanError"] = ex.Message;
|
|
}
|
|
|
|
return RedirectToAction(nameof(Edit), new { id = floorPlanId });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> DeleteTransition(int floorPlanId, int floorPlanTransitionId)
|
|
{
|
|
try
|
|
{
|
|
await floorPlans.DeleteTransitionAsync(floorPlanId, floorPlanTransitionId);
|
|
TempData["FloorPlanMessage"] = "Transition deleted.";
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
TempData["FloorPlanError"] = ex.Message;
|
|
}
|
|
|
|
return RedirectToAction(nameof(Edit), new { id = floorPlanId });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> AddBlock(int floorPlanId, FloorPlanBlockEditViewModel model)
|
|
{
|
|
var isAsyncSave = string.Equals(Request.Headers["X-Requested-With"], "XMLHttpRequest", StringComparison.OrdinalIgnoreCase);
|
|
try
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
var floorPlanBlockId = await floorPlans.SaveBlockAsync(model);
|
|
if (isAsyncSave)
|
|
{
|
|
var block = await floorPlans.GetBlockAsync(floorPlanBlockId);
|
|
if (block is null)
|
|
{
|
|
Response.StatusCode = StatusCodes.Status400BadRequest;
|
|
return Json(new { ok = false, message = "Block was saved but could not be loaded." });
|
|
}
|
|
|
|
return Json(new
|
|
{
|
|
ok = true,
|
|
message = "Saved",
|
|
block = new
|
|
{
|
|
block.FloorPlanBlockID,
|
|
block.FloorPlanFloorID,
|
|
block.LocationID,
|
|
block.LocationName,
|
|
block.LocationPath,
|
|
block.DisplayLabel,
|
|
block.X,
|
|
block.Y,
|
|
block.WidthCells,
|
|
block.HeightCells,
|
|
block.BlockType,
|
|
block.LabelOverride,
|
|
block.Notes
|
|
}
|
|
});
|
|
}
|
|
|
|
TempData["FloorPlanMessage"] = "Block added.";
|
|
return RedirectToAction(nameof(Edit), new { id = floorPlanId, selectedBlockId = floorPlanBlockId });
|
|
}
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
if (isAsyncSave)
|
|
{
|
|
Response.StatusCode = StatusCodes.Status400BadRequest;
|
|
return Json(new { ok = false, message = ex.Message });
|
|
}
|
|
|
|
TempData["FloorPlanError"] = ex.Message;
|
|
}
|
|
|
|
if (isAsyncSave)
|
|
{
|
|
Response.StatusCode = StatusCodes.Status400BadRequest;
|
|
return Json(new { ok = false, message = "Block could not be added." });
|
|
}
|
|
|
|
return RedirectToAction(nameof(Edit), new { id = floorPlanId });
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> DeleteBlock(int floorPlanId, int floorPlanBlockId)
|
|
{
|
|
await floorPlans.DeleteBlockAsync(floorPlanBlockId);
|
|
TempData["FloorPlanMessage"] = "Block deleted.";
|
|
return RedirectToAction(nameof(Edit), new { id = floorPlanId });
|
|
}
|
|
}
|