Merge branch 'master' into database_fixes

This commit is contained in:
2020-02-09 21:44:52 +00:00
committed by GitHub
38 changed files with 25757 additions and 261 deletions

1
.gitignore vendored
View File

@@ -448,3 +448,4 @@ cicm_web/wwwroot/assets/**/*.png
cicm_web/wwwroot/assets/**/*.tif cicm_web/wwwroot/assets/**/*.tif
cicm_web/wwwroot/assets/**/*.jpg cicm_web/wwwroot/assets/**/*.jpg
cicm_web/wwwroot/assets/**/*.tiff cicm_web/wwwroot/assets/**/*.tiff
cicm_web/wwwroot/assets/**/*.webp

BIN
CLA.pdf Normal file

Binary file not shown.

1
CODEOWNERS Normal file
View File

@@ -0,0 +1 @@
* @claunia

36
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,36 @@
# Contributing
## Commit signature
For security reason we require all commits to be cryptographically signed.
This section explains how to setup the development environment for that purpose.
### Visual Studio and Visual Studio Code for Windows
You need to install Git for Windows. It is available as a component of Visual Studio, or separately in https://gitforwindows.org.
You also need to install Gpg4win from https://www.gpg4win.org. Ensure to select the Kleopatra component.
Once you have them installed, open Kleopatra and generate a new key pair, of OpenPGP type, following the instructions [here](https://www.gpg4win.org/doc/en/gpg4win-compendium_12.html).
Save aside the fingerprint, you'll need it later.
Now go to environment variables (in the properties of your computer) and add this to the path:
`C:\Program Files\Git\usr\bin`
Finally, open Git Bash, and write the following commands if you want all git commits to be signed:
```bash
git config --global commit.gpgsign true
git config --global user.signingkey <FINGERPRINT>
git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"
```
or if you want the options to apply only for this project
```bash
cd /DRIVE/PATH_TO_PROJECT
git config commit.gpgsign true
git config user.signingkey FINGERPRINT
git config gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"
```
replacing `FINGERPRINT` with the fingerprint you saved from the key generation, `DRIVE` with the drive letter and `PATH_TO_PROJECT` using `/` as path separator.
Once this is done, every time you commit in VS / VSCode, a message box titled `pinentry-qt` will ask for the passphrase you set up earlier and sign the commit with your key.
For GitHub to recognize your signature you need to follow the steps [here](https://help.github.com/en/github/authenticating-to-github/adding-a-new-gpg-key-to-your-github-account).

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace Cicm.Database.Migrations
{
public partial class FixDocumentCompanyOneToOne : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey("FK_companies_DocumentCompanies_DocumentCompanyId", "companies");
migrationBuilder.DropIndex("IX_companies_DocumentCompanyId", "companies");
migrationBuilder.AlterColumn<int>("CompanyId", "DocumentCompanies", nullable: true, oldClrType: typeof(int),
oldNullable: true);
migrationBuilder.AddForeignKey("FK_DocumentCompanies_companies_CompanyId", "DocumentCompanies", "CompanyId",
"companies", principalColumn: "id", onDelete: ReferentialAction.SetNull);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey("FK_DocumentCompanies_companies_CompanyId", "DocumentCompanies");
migrationBuilder.AlterColumn<int>("CompanyId", "DocumentCompanies", nullable: true, oldClrType: typeof(int),
oldNullable: true);
migrationBuilder.CreateIndex("IX_companies_DocumentCompanyId", "companies", "DocumentCompanyId",
unique: true);
migrationBuilder.AddForeignKey("FK_companies_DocumentCompanies_DocumentCompanyId", "companies",
"DocumentCompanyId", "DocumentCompanies", principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace Cicm.Database.Migrations
{
public partial class AddDisplayNameAndAliasToPerson : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>("Alias", "People", nullable: true);
migrationBuilder.AddColumn<string>("DisplayName", "People", nullable: true);
migrationBuilder.CreateIndex("IX_People_Alias", "People", "Alias");
migrationBuilder.CreateIndex("IX_People_DisplayName", "People", "DisplayName");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex("IX_People_Alias", "People");
migrationBuilder.DropIndex("IX_People_DisplayName", "People");
migrationBuilder.DropColumn("Alias", "People");
migrationBuilder.DropColumn("DisplayName", "People");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace Cicm.Database.Migrations
{
public partial class AddDisplayNameAndAliasToDocumentPerson : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>("Alias", "DocumentPeople", nullable: true);
migrationBuilder.AddColumn<string>("DisplayName", "DocumentPeople", nullable: true);
migrationBuilder.CreateIndex("IX_DocumentPeople_Alias", "DocumentPeople", "Alias");
migrationBuilder.CreateIndex("IX_DocumentPeople_DisplayName", "DocumentPeople", "DisplayName");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex("IX_DocumentPeople_Alias", "DocumentPeople");
migrationBuilder.DropIndex("IX_DocumentPeople_DisplayName", "DocumentPeople");
migrationBuilder.DropColumn("Alias", "DocumentPeople");
migrationBuilder.DropColumn("DisplayName", "DocumentPeople");
}
}
}

View File

@@ -285,8 +285,6 @@ namespace Cicm.Database.Migrations
b.HasIndex("CountryId").HasName("idx_companies_country"); b.HasIndex("CountryId").HasName("idx_companies_country");
b.HasIndex("DocumentCompanyId").IsUnique();
b.HasIndex("Facebook").HasName("idx_companies_facebook"); b.HasIndex("Facebook").HasName("idx_companies_facebook");
b.HasIndex("Founded").HasName("idx_companies_founded"); b.HasIndex("Founded").HasName("idx_companies_founded");
@@ -400,6 +398,10 @@ namespace Cicm.Database.Migrations
{ {
b.Property<int>("Id").ValueGeneratedOnAdd(); b.Property<int>("Id").ValueGeneratedOnAdd();
b.Property<string>("Alias");
b.Property<string>("DisplayName");
b.Property<string>("Name").IsRequired(); b.Property<string>("Name").IsRequired();
b.Property<int?>("PersonId"); b.Property<int?>("PersonId");
@@ -408,6 +410,10 @@ namespace Cicm.Database.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("Alias");
b.HasIndex("DisplayName");
b.HasIndex("Name"); b.HasIndex("Name");
b.HasIndex("PersonId").IsUnique(); b.HasIndex("PersonId").IsUnique();
@@ -4960,12 +4966,16 @@ namespace Cicm.Database.Migrations
{ {
b.Property<int>("Id").ValueGeneratedOnAdd(); b.Property<int>("Id").ValueGeneratedOnAdd();
b.Property<string>("Alias");
b.Property<DateTime>("BirthDate"); b.Property<DateTime>("BirthDate");
b.Property<short?>("CountryOfBirthId"); b.Property<short?>("CountryOfBirthId");
b.Property<DateTime?>("DeathDate"); b.Property<DateTime?>("DeathDate");
b.Property<string>("DisplayName");
b.Property<int?>("DocumentPersonId"); b.Property<int?>("DocumentPersonId");
b.Property<string>("Facebook"); b.Property<string>("Facebook");
@@ -4982,12 +4992,16 @@ namespace Cicm.Database.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("Alias");
b.HasIndex("BirthDate"); b.HasIndex("BirthDate");
b.HasIndex("CountryOfBirthId"); b.HasIndex("CountryOfBirthId");
b.HasIndex("DeathDate"); b.HasIndex("DeathDate");
b.HasIndex("DisplayName");
b.HasIndex("Facebook"); b.HasIndex("Facebook");
b.HasIndex("Name"); b.HasIndex("Name");
@@ -5634,9 +5648,6 @@ namespace Cicm.Database.Migrations
b.HasOne("Cicm.Database.Models.Iso31661Numeric", "Country").WithMany("Companies") b.HasOne("Cicm.Database.Models.Iso31661Numeric", "Country").WithMany("Companies")
.HasForeignKey("CountryId").HasConstraintName("fk_companies_country"); .HasForeignKey("CountryId").HasConstraintName("fk_companies_country");
b.HasOne("Cicm.Database.Models.DocumentCompany", "DocumentCompany").WithOne("Company")
.HasForeignKey("Cicm.Database.Models.Company", "DocumentCompanyId").OnDelete(DeleteBehavior.SetNull);
b.HasOne("Cicm.Database.Models.Company", "SoldTo").WithMany("InverseSoldToNavigation") b.HasOne("Cicm.Database.Models.Company", "SoldTo").WithMany("InverseSoldToNavigation")
.HasForeignKey("SoldToId").HasConstraintName("fk_companies_sold_to"); .HasForeignKey("SoldToId").HasConstraintName("fk_companies_sold_to");
}); });
@@ -5662,6 +5673,14 @@ namespace Cicm.Database.Migrations
.HasForeignKey("CountryId"); .HasForeignKey("CountryId");
}); });
modelBuilder.Entity("Cicm.Database.Models.DocumentCompany",
b =>
{
b.HasOne("Cicm.Database.Models.Company", "Company").WithOne("DocumentCompany")
.HasForeignKey("Cicm.Database.Models.DocumentCompany", "CompanyId")
.OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("Cicm.Database.Models.DocumentPerson", modelBuilder.Entity("Cicm.Database.Models.DocumentPerson",
b => b =>
{ {

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace Cicm.Database.Models namespace Cicm.Database.Models
@@ -9,6 +10,7 @@ namespace Cicm.Database.Models
public string Name { get; set; } public string Name { get; set; }
public int? CompanyId { get; set; } public int? CompanyId { get; set; }
[DisplayName("Linked company")]
public virtual Company Company { get; set; } public virtual Company Company { get; set; }
public virtual ICollection<CompaniesByDocument> Documents { get; set; } public virtual ICollection<CompaniesByDocument> Documents { get; set; }
public virtual ICollection<CompaniesByBook> Books { get; set; } public virtual ICollection<CompaniesByBook> Books { get; set; }

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
@@ -11,13 +12,18 @@ namespace Cicm.Database.Models
[Required] [Required]
public string Surname { get; set; } public string Surname { get; set; }
public int? PersonId { get; set; } public int? PersonId { get; set; }
public string Alias { get; set; }
[DisplayName("Name to be displayed")]
public string DisplayName { get; set; }
[NotMapped]
[DisplayName("Name")]
public string FullName => DisplayName ?? Alias ?? $"{Name} {Surname}";
[DisplayName("Linked person")]
public virtual Person Person { get; set; } public virtual Person Person { get; set; }
public virtual ICollection<PeopleByDocument> Documents { get; set; } public virtual ICollection<PeopleByDocument> Documents { get; set; }
public virtual ICollection<PeopleByBook> Books { get; set; } public virtual ICollection<PeopleByBook> Books { get; set; }
public virtual ICollection<PeopleByMagazine> Magazines { get; set; } public virtual ICollection<PeopleByMagazine> Magazines { get; set; }
[NotMapped]
public string FullName => $"{Name} {Surname}";
} }
} }

View File

@@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.AspNetCore.Mvc;
namespace Cicm.Database.Models namespace Cicm.Database.Models
{ {
@@ -11,17 +13,28 @@ namespace Cicm.Database.Models
public string Name { get; set; } public string Name { get; set; }
[Required] [Required]
public string Surname { get; set; } public string Surname { get; set; }
[DisplayName("Country of birth")]
public virtual Iso31661Numeric CountryOfBirth { get; set; } public virtual Iso31661Numeric CountryOfBirth { get; set; }
[DisplayName("Birth date")]
[DataType(DataType.Date)]
public DateTime BirthDate { get; set; } public DateTime BirthDate { get; set; }
[DisplayName("Date of death")]
[DataType(DataType.Date)]
public DateTime? DeathDate { get; set; } public DateTime? DeathDate { get; set; }
[Url]
public string Webpage { get; set; } public string Webpage { get; set; }
[Remote("VerifyTwitter", "People", "Admin")]
public string Twitter { get; set; } public string Twitter { get; set; }
public string Facebook { get; set; } public string Facebook { get; set; }
public Guid Photo { get; set; } public Guid Photo { get; set; }
public int? DocumentPersonId { get; set; } public int? DocumentPersonId { get; set; }
public string Alias { get; set; }
[DisplayName("Name to be displayed")]
public string DisplayName { get; set; }
[NotMapped] [NotMapped]
public string FullName => $"{Name} {Surname}"; [DisplayName("Name")]
public string FullName => DisplayName ?? Alias ?? $"{Name} {Surname}";
public short? CountryOfBirthId { get; set; } public short? CountryOfBirthId { get; set; }
public virtual ICollection<PeopleByCompany> Companies { get; set; } public virtual ICollection<PeopleByCompany> Companies { get; set; }

View File

@@ -388,9 +388,6 @@ namespace Cicm.Database.Models
entity.HasIndex(e => e.Name); entity.HasIndex(e => e.Name);
entity.HasIndex(e => e.CompanyId).IsUnique(); entity.HasIndex(e => e.CompanyId).IsUnique();
entity.HasOne(d => d.Company).WithOne(p => p.DocumentCompany)
.HasForeignKey<Company>(d => d.DocumentCompanyId).OnDelete(DeleteBehavior.SetNull);
}); });
modelBuilder.Entity<DocumentPerson>(entity => modelBuilder.Entity<DocumentPerson>(entity =>
@@ -401,6 +398,10 @@ namespace Cicm.Database.Models
entity.HasIndex(e => e.PersonId).IsUnique(); entity.HasIndex(e => e.PersonId).IsUnique();
entity.HasIndex(e => e.Alias);
entity.HasIndex(e => e.DisplayName);
entity.HasOne(d => d.Person).WithOne(p => p.DocumentPerson) entity.HasOne(d => d.Person).WithOne(p => p.DocumentPerson)
.HasForeignKey<Person>(d => d.DocumentPersonId).OnDelete(DeleteBehavior.SetNull); .HasForeignKey<Person>(d => d.DocumentPersonId).OnDelete(DeleteBehavior.SetNull);
}); });
@@ -1079,6 +1080,10 @@ namespace Cicm.Database.Models
entity.HasIndex(e => e.Photo); entity.HasIndex(e => e.Photo);
entity.HasIndex(e => e.Alias);
entity.HasIndex(e => e.DisplayName);
entity.HasOne(d => d.CountryOfBirth).WithMany(p => p.People).HasForeignKey(d => d.CountryOfBirthId); entity.HasOne(d => d.CountryOfBirth).WithMany(p => p.People).HasForeignKey(d => d.CountryOfBirthId);
entity.HasOne(d => d.DocumentPerson).WithOne(p => p.Person) entity.HasOne(d => d.DocumentPerson).WithOne(p => p.Person)

7
README.md Normal file
View File

@@ -0,0 +1,7 @@
# Canary Islands Computer Museum Website
Welcome to the Canary Islands Computer Museum Website repository.
This repository contains the CICM Website software.
For contributing please read [here.](CONTRIBUTING.md)

View File

@@ -1,7 +1,7 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Cicm.Database.Models; using Cicm.Database.Models;
using cicm_web.Models; using cicm_web.Areas.Admin.Models;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Rendering;
@@ -23,8 +23,14 @@ namespace cicm_web.Areas.Admin.Controllers
// GET: DocumentCompanies // GET: DocumentCompanies
public async Task<IActionResult> Index() public async Task<IActionResult> Index()
{ {
return View(await _context.DocumentCompanies.Select(d => new CompanyViewModel {Id = d.Id, Name = d.Name}) return View(await _context.DocumentCompanies.OrderBy(c => c.Name)
.ToListAsync()); .Select(d => new DocumentCompanyViewModel
{
Id = d.Id,
Name = d.Name,
Company = d.Company.Name,
CompanyId = d.CompanyId
}).ToListAsync());
} }
// GET: DocumentCompanies/Details/5 // GET: DocumentCompanies/Details/5
@@ -32,7 +38,15 @@ namespace cicm_web.Areas.Admin.Controllers
{ {
if(id == null) return NotFound(); if(id == null) return NotFound();
DocumentCompany documentCompany = await _context.DocumentCompanies.FirstOrDefaultAsync(m => m.Id == id); DocumentCompanyViewModel documentCompany =
await _context.DocumentCompanies
.Select(d => new DocumentCompanyViewModel
{
Id = d.Id,
Name = d.Name,
Company = d.Company.Name,
CompanyId = d.CompanyId
}).FirstOrDefaultAsync(m => m.Id == id);
if(documentCompany == null) return NotFound(); if(documentCompany == null) return NotFound();
return View(documentCompany); return View(documentCompany);
@@ -66,8 +80,13 @@ namespace cicm_web.Areas.Admin.Controllers
if(id == null) return NotFound(); if(id == null) return NotFound();
DocumentCompany documentCompany = await _context.DocumentCompanies.FindAsync(id); DocumentCompany documentCompany = await _context.DocumentCompanies.FindAsync(id);
if(documentCompany == null) return NotFound(); if(documentCompany == null) return NotFound();
ViewData["CompanyId"] =
new SelectList(_context.Companies.OrderBy(c => c.Name).Select(c => new {c.Id, c.Name}), "Id", "Name",
documentCompany.CompanyId);
return View(documentCompany); return View(documentCompany);
} }
@@ -97,6 +116,10 @@ namespace cicm_web.Areas.Admin.Controllers
return RedirectToAction(nameof(Index)); return RedirectToAction(nameof(Index));
} }
ViewData["CompanyId"] =
new SelectList(_context.Companies.OrderBy(c => c.Name).Select(c => new {c.Id, c.Name}), "Id", "Name",
documentCompany.CompanyId);
return View(documentCompany); return View(documentCompany);
} }
@@ -105,7 +128,15 @@ namespace cicm_web.Areas.Admin.Controllers
{ {
if(id == null) return NotFound(); if(id == null) return NotFound();
DocumentCompany documentCompany = await _context.DocumentCompanies.FirstOrDefaultAsync(m => m.Id == id); DocumentCompanyViewModel documentCompany =
await _context.DocumentCompanies
.Select(d => new DocumentCompanyViewModel
{
Id = d.Id,
Name = d.Name,
Company = d.Company.Name,
CompanyId = d.CompanyId
}).FirstOrDefaultAsync(m => m.Id == id);
if(documentCompany == null) return NotFound(); if(documentCompany == null) return NotFound();
return View(documentCompany); return View(documentCompany);

View File

@@ -0,0 +1,149 @@
using System.Linq;
using System.Threading.Tasks;
using Cicm.Database.Models;
using cicm_web.Areas.Admin.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
namespace cicm_web.Areas.Admin.Controllers
{
[Area("Admin")]
[Authorize]
public class DocumentPeopleController : Controller
{
readonly cicmContext _context;
public DocumentPeopleController(cicmContext context)
{
_context = context;
}
// GET: DocumentPeople
public async Task<IActionResult> Index()
{
return View(await _context.DocumentPeople.OrderBy(d => d.FullName)
.Select(d => new DocumentPersonViewModel
{
Id = d.Id,
Name = d.FullName,
Person = d.Person.FullName,
PersonId = d.PersonId
}).ToListAsync());
}
// GET: DocumentPeople/Details/5
public async Task<IActionResult> Details(int? id)
{
if(id == null) return NotFound();
DocumentPerson documentPerson = await _context.DocumentPeople.FirstOrDefaultAsync(m => m.Id == id);
if(documentPerson == null) return NotFound();
return View(documentPerson);
}
// GET: DocumentPeople/Create
public IActionResult Create()
{
ViewData["PersonId"] =
new SelectList(_context.People.OrderBy(c => c.FullName).Select(c => new {c.Id, Name = c.FullName}),
"Id", "Name");
return View();
}
// POST: DocumentPeople/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Name,Surname,Alias,DisplayName,PersonId,Id")]
DocumentPerson documentPerson)
{
if(!ModelState.IsValid) return View(documentPerson);
_context.Add(documentPerson);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
// GET: DocumentPeople/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if(id == null) return NotFound();
DocumentPerson documentPerson = await _context.DocumentPeople.FindAsync(id);
if(documentPerson == null) return NotFound();
ViewData["PersonId"] =
new SelectList(_context.People.OrderBy(c => c.FullName).Select(c => new {c.Id, Name = c.FullName}),
"Id", "Name", documentPerson.PersonId);
return View(documentPerson);
}
// POST: DocumentPeople/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Name,Surname,Alias,DisplayName,PersonId,Id")]
DocumentPerson documentPerson)
{
if(id != documentPerson.Id) return NotFound();
if(ModelState.IsValid)
{
try
{
_context.Update(documentPerson);
await _context.SaveChangesAsync();
}
catch(DbUpdateConcurrencyException)
{
if(!DocumentPersonExists(documentPerson.Id)) return NotFound();
throw;
}
return RedirectToAction(nameof(Index));
}
ViewData["PersonId"] =
new SelectList(_context.People.OrderBy(c => c.FullName).Select(c => new {c.Id, Name = c.FullName}),
"Id", "Name", documentPerson.PersonId);
return View(documentPerson);
}
// GET: DocumentPeople/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if(id == null) return NotFound();
DocumentPerson documentPerson = await _context.DocumentPeople.FirstOrDefaultAsync(m => m.Id == id);
if(documentPerson == null) return NotFound();
return View(documentPerson);
}
// POST: DocumentPeople/Delete/5
[HttpPost]
[ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
DocumentPerson documentPerson = await _context.DocumentPeople.FindAsync(id);
_context.DocumentPeople.Remove(documentPerson);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
bool DocumentPersonExists(int id)
{
return _context.DocumentPeople.Any(e => e.Id == id);
}
}
}

View File

@@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query;
namespace cicm_web.Areas.Admin.Controllers namespace cicm_web.Areas.Admin.Controllers
{ {
@@ -12,7 +13,7 @@ namespace cicm_web.Areas.Admin.Controllers
[Authorize] [Authorize]
public class PeopleController : Controller public class PeopleController : Controller
{ {
private readonly cicmContext _context; readonly cicmContext _context;
public PeopleController(cicmContext context) public PeopleController(cicmContext context)
{ {
@@ -22,25 +23,17 @@ namespace cicm_web.Areas.Admin.Controllers
// GET: People // GET: People
public async Task<IActionResult> Index() public async Task<IActionResult> Index()
{ {
var cicmContext = _context.People.Include(p => p.CountryOfBirth); IIncludableQueryable<Person, Iso31661Numeric> cicmContext = _context.People.Include(p => p.CountryOfBirth);
return View(await cicmContext.ToListAsync()); return View(await cicmContext.OrderBy(p => p.FullName).ToListAsync());
} }
// GET: People/Details/5 // GET: People/Details/5
public async Task<IActionResult> Details(int? id) public async Task<IActionResult> Details(int? id)
{ {
if (id == null) if(id == null) return NotFound();
{
return NotFound();
}
var person = await _context.People Person person = await _context.People.Include(p => p.CountryOfBirth).FirstOrDefaultAsync(m => m.Id == id);
.Include(p => p.CountryOfBirth) if(person == null) return NotFound();
.FirstOrDefaultAsync(m => m.Id == id);
if (person == null)
{
return NotFound();
}
return View(person); return View(person);
} }
@@ -57,7 +50,10 @@ namespace cicm_web.Areas.Admin.Controllers
// more details see http://go.microsoft.com/fwlink/?LinkId=317598. // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost] [HttpPost]
[ValidateAntiForgeryToken] [ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Name,Surname,BirthDate,DeathDate,Webpage,Twitter,Facebook,Photo,CountryOfBirthId,Id")] Person person) public async Task<IActionResult> Create(
[Bind(
"Name,Surname,BirthDate,DeathDate,Webpage,Twitter,Facebook,Photo,CountryOfBirthId,Id,Alias,DisplayName")]
Person person)
{ {
if(ModelState.IsValid) if(ModelState.IsValid)
{ {
@@ -65,24 +61,22 @@ namespace cicm_web.Areas.Admin.Controllers
await _context.SaveChangesAsync(); await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index)); return RedirectToAction(nameof(Index));
} }
ViewData["CountryOfBirthId"] = new SelectList(_context.Iso31661Numeric, "Id", "Name", person.CountryOfBirthId);
ViewData["CountryOfBirthId"] =
new SelectList(_context.Iso31661Numeric, "Id", "Name", person.CountryOfBirthId);
return View(person); return View(person);
} }
// GET: People/Edit/5 // GET: People/Edit/5
public async Task<IActionResult> Edit(int? id) public async Task<IActionResult> Edit(int? id)
{ {
if (id == null) if(id == null) return NotFound();
{
return NotFound();
}
var person = await _context.People.FindAsync(id); Person person = await _context.People.FindAsync(id);
if (person == null) if(person == null) return NotFound();
{
return NotFound(); ViewData["CountryOfBirthId"] =
} new SelectList(_context.Iso31661Numeric, "Id", "Name", person.CountryOfBirthId);
ViewData["CountryOfBirthId"] = new SelectList(_context.Iso31661Numeric, "Id", "Name", person.CountryOfBirthId);
return View(person); return View(person);
} }
@@ -91,12 +85,12 @@ namespace cicm_web.Areas.Admin.Controllers
// more details see http://go.microsoft.com/fwlink/?LinkId=317598. // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost] [HttpPost]
[ValidateAntiForgeryToken] [ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Name,Surname,BirthDate,DeathDate,Webpage,Twitter,Facebook,Photo,CountryOfBirthId,Id")] Person person) public async Task<IActionResult> Edit(
int id, [Bind(
"Name,Surname,BirthDate,DeathDate,Webpage,Twitter,Facebook,Photo,CountryOfBirthId,Id,Alias,DisplayName")]
Person person)
{ {
if (id != person.Id) if(id != person.Id) return NotFound();
{
return NotFound();
}
if(ModelState.IsValid) if(ModelState.IsValid)
{ {
@@ -107,54 +101,49 @@ namespace cicm_web.Areas.Admin.Controllers
} }
catch(DbUpdateConcurrencyException) catch(DbUpdateConcurrencyException)
{ {
if (!PersonExists(person.Id)) if(!PersonExists(person.Id)) return NotFound();
{
return NotFound();
}
else
{
throw; throw;
} }
}
return RedirectToAction(nameof(Index)); return RedirectToAction(nameof(Index));
} }
ViewData["CountryOfBirthId"] = new SelectList(_context.Iso31661Numeric, "Id", "Name", person.CountryOfBirthId);
ViewData["CountryOfBirthId"] =
new SelectList(_context.Iso31661Numeric, "Id", "Name", person.CountryOfBirthId);
return View(person); return View(person);
} }
// GET: People/Delete/5 // GET: People/Delete/5
public async Task<IActionResult> Delete(int? id) public async Task<IActionResult> Delete(int? id)
{ {
if (id == null) if(id == null) return NotFound();
{
return NotFound();
}
var person = await _context.People Person person = await _context.People.Include(p => p.CountryOfBirth).FirstOrDefaultAsync(m => m.Id == id);
.Include(p => p.CountryOfBirth) if(person == null) return NotFound();
.FirstOrDefaultAsync(m => m.Id == id);
if (person == null)
{
return NotFound();
}
return View(person); return View(person);
} }
// POST: People/Delete/5 // POST: People/Delete/5
[HttpPost, ActionName("Delete")] [HttpPost]
[ActionName("Delete")]
[ValidateAntiForgeryToken] [ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id) public async Task<IActionResult> DeleteConfirmed(int id)
{ {
var person = await _context.People.FindAsync(id); Person person = await _context.People.FindAsync(id);
_context.People.Remove(person); _context.People.Remove(person);
await _context.SaveChangesAsync(); await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index)); return RedirectToAction(nameof(Index));
} }
private bool PersonExists(int id) bool PersonExists(int id)
{ {
return _context.People.Any(e => e.Id == id); return _context.People.Any(e => e.Id == id);
} }
[AcceptVerbs("Get", "Post")]
public IActionResult VerifyTwitter(string twitter) =>
twitter?.Length > 0 && twitter[0] == '@' ? Json(true) : Json("Invalid twitter handle.");
} }
} }

View File

@@ -0,0 +1,12 @@
using System.ComponentModel;
namespace cicm_web.Areas.Admin.Models
{
public class DocumentCompanyViewModel : BaseViewModel<int>
{
public string Name { get; set; }
[DisplayName("Linked company")]
public string Company { get; set; }
public int? CompanyId { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
using System.ComponentModel;
namespace cicm_web.Areas.Admin.Models
{
public class DocumentPersonViewModel : BaseViewModel<int>
{
public string Name { get; set; }
[DisplayName("Linked person")]
public string Person { get; set; }
public int? PersonId { get; set; }
}
}

View File

@@ -31,6 +31,10 @@
<select asp-for="CompanyId" <select asp-for="CompanyId"
class="form-control" class="form-control"
asp-items="ViewBag.CompanyId"> asp-items="ViewBag.CompanyId">
<option selected
value="">
None or unknown
</option>
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@@ -1,4 +1,4 @@
@model Cicm.Database.Models.DocumentCompany @model cicm_web.Areas.Admin.Models.DocumentCompanyViewModel
@{ @{
ViewData["Title"] = "Delete"; ViewData["Title"] = "Delete";
@@ -8,7 +8,7 @@
<h3>Are you sure you want to delete this?</h3> <h3>Are you sure you want to delete this?</h3>
<div> <div>
<h4>DocumentCompany</h4> <h4>Document company</h4>
<hr /> <hr />
<dl class="row"> <dl class="row">
<dt class="col-sm-2"> <dt class="col-sm-2">
@@ -18,10 +18,13 @@
@Html.DisplayFor(model => model.Name) @Html.DisplayFor(model => model.Name)
</dd> </dd>
<dt class="col-sm-2"> <dt class="col-sm-2">
@Html.DisplayNameFor(model => model.CompanyId) @Html.DisplayNameFor(model => model.Company)
</dt> </dt>
<dd class="col-sm-10"> <dd class="col-sm-10">
@Html.DisplayFor(model => model.CompanyId) <a asp-action="Details"
asp-route-id="@Model.CompanyId"
asp-controller="Companies">
@Html.DisplayFor(modelItem => Model.Company)</a>
</dd> </dd>
</dl> </dl>
@@ -30,7 +33,10 @@
asp-for="Id" /> asp-for="Id" />
<input class="btn btn-danger" <input class="btn btn-danger"
type="submit" type="submit"
value="Delete" /> | value="Delete" />
<a asp-action="Index">Back to List</a> <a asp-action="Index"
class="btn btn-secondary">
Back to List
</a>
</form> </form>
</div> </div>

View File

@@ -1,4 +1,4 @@
@model Cicm.Database.Models.DocumentCompany @model cicm_web.Areas.Admin.Models.DocumentCompanyViewModel
@{ @{
ViewData["Title"] = "Details"; ViewData["Title"] = "Details";
@@ -7,7 +7,7 @@
<h1>Details</h1> <h1>Details</h1>
<div> <div>
<h4>DocumentCompany</h4> <h4>Document company</h4>
<hr /> <hr />
<dl class="row"> <dl class="row">
<dt class="col-sm-2"> <dt class="col-sm-2">
@@ -17,17 +17,24 @@
@Html.DisplayFor(model => model.Name) @Html.DisplayFor(model => model.Name)
</dd> </dd>
<dt class="col-sm-2"> <dt class="col-sm-2">
@Html.DisplayNameFor(model => model.CompanyId) @Html.DisplayNameFor(model => model.Company)
</dt> </dt>
<dd class="col-sm-10"> <dd class="col-sm-10">
@Html.DisplayFor(model => model.CompanyId) <a asp-action="Details"
asp-route-id="@Model.CompanyId"
asp-controller="Companies">
@Html.DisplayFor(modelItem => Model.Company)</a>
</dd> </dd>
</dl> </dl>
</div> </div>
<div> <div>
<a asp-action="Edit" <a asp-action="Edit"
asp-route-id="@Model.Id"> asp-route-id="@Model.Id"
class="btn btn-primary">
Edit Edit
</a> | </a>
<a asp-action="Index">Back to List</a> <a asp-action="Index"
class="btn btn-secondary">
Back to List
</a>
</div> </div>

View File

@@ -6,7 +6,7 @@
<h1>Edit</h1> <h1>Edit</h1>
<h4>DocumentCompany</h4> <h4>Document company</h4>
<hr /> <hr />
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
@@ -25,14 +25,17 @@
</span> </span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="CompanyId" <label asp-for="Company"
class="control-label"> class="control-label">
</label> </label>
<input asp-for="CompanyId" <select asp-for="CompanyId"
class="form-control" /> class="form-control"
<span asp-validation-for="CompanyId" asp-items="ViewBag.CompanyId">
class="text-danger"> <option selected
</span> value="">
None or unknown
</option>
</select>
</div> </div>
<input type="hidden" <input type="hidden"
asp-for="Id" /> asp-for="Id" />
@@ -40,11 +43,12 @@
<input class="btn btn-primary" <input class="btn btn-primary"
type="submit" type="submit"
value="Save" /> value="Save" />
<a asp-action="Index" class="btn btn-secondary">Back to List</a>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
<div> @section Scripts {
<a asp-action="Index">Back to List</a> @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
</div> }

View File

@@ -1,4 +1,5 @@
@model IEnumerable<CompanyViewModel> @using cicm_web.Areas.Admin.Models
@model IEnumerable<cicm_web.Areas.Admin.Models.DocumentCompanyViewModel>
@{ @{
ViewData["Title"] = "Index"; ViewData["Title"] = "Index";
@@ -18,16 +19,25 @@
<th> <th>
@Html.DisplayNameFor(model => model.Name) @Html.DisplayNameFor(model => model.Name)
</th> </th>
<th>
@Html.DisplayNameFor(model => model.Company)
</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@foreach(CompanyViewModel item in Model) @foreach(DocumentCompanyViewModel item in Model)
{ {
<tr> <tr>
<td> <td>
@Html.DisplayFor(modelItem => item.Name) @Html.DisplayFor(modelItem => item.Name)
</td> </td>
<td>
<a asp-action="Details"
asp-route-id="@item.CompanyId"
asp-controller="Companies">
@Html.DisplayFor(modelItem => item.Company)</a>
</td>
<td> <td>
<a asp-action="Details" <a asp-action="Details"
class="btn btn-primary" class="btn btn-primary"

View File

@@ -0,0 +1,85 @@
@model Cicm.Database.Models.DocumentPerson
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Document person</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly"
class="text-danger">
</div>
<div class="form-group">
<label asp-for="Name"
class="control-label">
</label>
<input asp-for="Name"
class="form-control" />
<span asp-validation-for="Name"
class="text-danger">
</span>
</div>
<div class="form-group">
<label asp-for="Surname"
class="control-label">
</label>
<input asp-for="Surname"
class="form-control" />
<span asp-validation-for="Surname"
class="text-danger">
</span>
</div>
<div class="form-group">
<label asp-for="Alias"
class="control-label">
</label>
<input asp-for="Alias"
class="form-control" />
<span asp-validation-for="Alias"
class="text-danger">
</span>
</div>
<div class="form-group">
<label asp-for="DisplayName"
class="control-label">
</label>
<input asp-for="DisplayName"
class="form-control" />
<span asp-validation-for="DisplayName"
class="text-danger">
</span>
</div>
<div class="form-group">
<label asp-for="Person"
class="control-label">
</label>
<select asp-for="PersonId"
class="form-control"
asp-items="ViewBag.PersonId">
<option selected
value="">
None or unknown
</option>
</select>
</div>
<div class="form-group">
<input class="btn btn-primary"
type="submit"
value="Create" />
<a asp-action="Index"
class="btn btn-secondary">
Back to List
</a>
</div>
</form>
</div>
</div>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

View File

@@ -0,0 +1,60 @@
@model Cicm.Database.Models.DocumentPerson
@{
ViewData["Title"] = "Delete";
}
<h1>Delete</h1>
<h3>Are you sure you want to delete this?</h3>
<div>
<h4>Document person</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Name)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Name)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Surname)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Surname)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Alias)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Alias)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.DisplayName)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.DisplayName)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Person)
</dt>
<dd class="col-sm-10">
<a asp-action="Details"
asp-route-id="@Model.PersonId"
asp-controller="People">
@Html.DisplayFor(modelItem => Model.Person.FullName)</a>
</dd>
</dl>
<form asp-action="Delete">
<input type="hidden"
asp-for="Id" />
<input class="btn btn-danger"
type="submit"
value="Delete" />
<a asp-action="Index"
class="btn btn-secondary">
Back to List
</a>
</form>
</div>

View File

@@ -0,0 +1,58 @@
@model Cicm.Database.Models.DocumentPerson
@{
ViewData["Title"] = "Details";
}
<h1>Details</h1>
<div>
<h4>Document person</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Name)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Name)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Surname)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Surname)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Alias)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Alias)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.DisplayName)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.DisplayName)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Person)
</dt>
<dd class="col-sm-10">
<a asp-action="Details"
asp-route-id="@Model.PersonId"
asp-controller="People">
@Html.DisplayFor(modelItem => Model.Person.FullName)</a>
</dd>
</dl>
</div>
<div>
<a asp-action="Edit"
asp-route-id="@Model.Id"
class="btn btn-primary">
Edit
</a>
<a asp-action="Index"
class="btn btn-secondary">
Back to List
</a>
</div>

View File

@@ -0,0 +1,87 @@
@model Cicm.Database.Models.DocumentPerson
@{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>Document person</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly"
class="text-danger">
</div>
<div class="form-group">
<label asp-for="Name"
class="control-label">
</label>
<input asp-for="Name"
class="form-control" />
<span asp-validation-for="Name"
class="text-danger">
</span>
</div>
<div class="form-group">
<label asp-for="Surname"
class="control-label">
</label>
<input asp-for="Surname"
class="form-control" />
<span asp-validation-for="Surname"
class="text-danger">
</span>
</div>
<div class="form-group">
<label asp-for="Alias"
class="control-label">
</label>
<input asp-for="Alias"
class="form-control" />
<span asp-validation-for="Alias"
class="text-danger">
</span>
</div>
<div class="form-group">
<label asp-for="DisplayName"
class="control-label">
</label>
<input asp-for="DisplayName"
class="form-control" />
<span asp-validation-for="DisplayName"
class="text-danger">
</span>
</div>
<div class="form-group">
<label asp-for="Person"
class="control-label">
</label>
<select asp-for="PersonId"
class="form-control"
asp-items="ViewBag.PersonId">
<option selected
value="">
None or unknown
</option>
</select>
</div>
<input type="hidden"
asp-for="Id" />
<div class="form-group">
<input class="btn btn-primary"
type="submit"
value="Save" />
<a asp-action="Index"
class="btn btn-secondary">
Back to List
</a>
</div>
</form>
</div>
</div>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

View File

@@ -0,0 +1,61 @@
@using cicm_web.Areas.Admin.Models
@model IEnumerable<cicm_web.Areas.Admin.Models.DocumentPersonViewModel>
@{
ViewData["Title"] = "Index";
}
<h1>Document people</h1>
<p>
<a asp-action="Create"
class="btn btn-primary">
Create New
</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Person)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach(DocumentPersonViewModel item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
<a asp-action="Details"
asp-route-id="@item.PersonId"
asp-controller="People">
@Html.DisplayFor(modelItem => item.Person)</a>
</td>
<td>
<a asp-action="Details"
class="btn btn-primary"
asp-route-id="@item.Id">
Details
</a>
<a asp-action="Edit"
class="btn btn-secondary"
asp-route-id="@item.Id">
Edit
</a>
<a asp-action="Delete"
class="btn btn-danger"
asp-route-id="@item.Id">
Delete
</a>
</td>
</tr>
}
</tbody>
</table>

View File

@@ -67,6 +67,7 @@
<div class="content"> <div class="content">
<h3>Administrative pages for documents</h3> <h3>Administrative pages for documents</h3>
<a asp-controller="DocumentCompanies">Document companies</a><br /> <a asp-controller="DocumentCompanies">Document companies</a><br />
<a asp-controller="DocumentPeople">Document people</a><br />
</div> </div>
<div class="content"> <div class="content">

View File

@@ -11,59 +11,121 @@
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
<form asp-action="Create"> <form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div> <div asp-validation-summary="ModelOnly"
<div class="form-group"> class="text-danger">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="Surname" class="control-label"></label> <label asp-for="Name"
<input asp-for="Surname" class="form-control" /> class="control-label">
<span asp-validation-for="Surname" class="text-danger"></span> </label>
<input asp-for="Name"
class="form-control" />
<span asp-validation-for="Name"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="BirthDate" class="control-label"></label> <label asp-for="Alias"
<input asp-for="BirthDate" class="form-control" /> class="control-label">
<span asp-validation-for="BirthDate" class="text-danger"></span> </label>
<input asp-for="Alias"
class="form-control" />
<span asp-validation-for="Alias"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="DeathDate" class="control-label"></label> <label asp-for="DisplayName"
<input asp-for="DeathDate" class="form-control" /> class="control-label">
<span asp-validation-for="DeathDate" class="text-danger"></span> </label>
<input asp-for="DisplayName"
class="form-control" />
<span asp-validation-for="DisplayName"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="Webpage" class="control-label"></label> <label asp-for="Surname"
<input asp-for="Webpage" class="form-control" /> class="control-label">
<span asp-validation-for="Webpage" class="text-danger"></span> </label>
<input asp-for="Surname"
class="form-control" />
<span asp-validation-for="Surname"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="Twitter" class="control-label"></label> <label asp-for="BirthDate"
<input asp-for="Twitter" class="form-control" /> class="control-label">
<span asp-validation-for="Twitter" class="text-danger"></span> </label>
<input asp-for="BirthDate"
class="form-control" />
<span asp-validation-for="BirthDate"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="Facebook" class="control-label"></label> <label asp-for="DeathDate"
<input asp-for="Facebook" class="form-control" /> class="control-label">
<span asp-validation-for="Facebook" class="text-danger"></span> </label>
<input asp-for="DeathDate"
class="form-control" />
<span asp-validation-for="DeathDate"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="Photo" class="control-label"></label> <label asp-for="Webpage"
<input asp-for="Photo" class="form-control" /> class="control-label">
<span asp-validation-for="Photo" class="text-danger"></span> </label>
<input asp-for="Webpage"
class="form-control" />
<span asp-validation-for="Webpage"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="CountryOfBirthId" class="control-label"></label> <label asp-for="Twitter"
<select asp-for="CountryOfBirthId" class ="form-control" asp-items="ViewBag.CountryOfBirthId"></select> class="control-label">
</label>
<input asp-for="Twitter"
class="form-control" />
<span asp-validation-for="Twitter"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" /> <label asp-for="Facebook"
class="control-label">
</label>
<input asp-for="Facebook"
class="form-control" />
<span asp-validation-for="Facebook"
class="text-danger">
</span>
</div>
<div class="form-group">
<label asp-for="CountryOfBirth"
class="control-label">
</label>
<select asp-for="CountryOfBirthId"
class="form-control"
asp-items="ViewBag.CountryOfBirthId">
</select>
</div>
<div class="form-group">
<input class="btn btn-primary"
type="submit"
value="Create" />
<a asp-action="Index"
class="btn btn-secondary">
Back to List
</a>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
<div> @section Scripts {
<a asp-action="Index">Back to List</a> @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
</div> }

View File

@@ -23,12 +23,24 @@
<dd class="col-sm-10"> <dd class="col-sm-10">
@Html.DisplayFor(model => model.Surname) @Html.DisplayFor(model => model.Surname)
</dd> </dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Alias)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Alias)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.DisplayName)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.DisplayName)
</dd>
<dt class="col-sm-2"> <dt class="col-sm-2">
@Html.DisplayNameFor(model => model.CountryOfBirth) @Html.DisplayNameFor(model => model.CountryOfBirth)
</dt> </dt>
<dd class="col-sm-10"> <dd class="col-sm-10">
@Html.DisplayFor(model => model.CountryOfBirth.Name) @Html.DisplayFor(model => model.CountryOfBirth.Name)
</dd class> </dd>
<dt class="col-sm-2"> <dt class="col-sm-2">
@Html.DisplayNameFor(model => model.BirthDate) @Html.DisplayNameFor(model => model.BirthDate)
</dt> </dt>
@@ -51,25 +63,31 @@
@Html.DisplayNameFor(model => model.Twitter) @Html.DisplayNameFor(model => model.Twitter)
</dt> </dt>
<dd class="col-sm-10"> <dd class="col-sm-10">
@Html.DisplayFor(model => model.Twitter) @if(Model.Twitter != null)
{
<a href="https://twitter.com/@Html.DisplayFor(model => model.Twitter)">@Html.DisplayFor(model => model.Twitter)</a>
}
</dd> </dd>
<dt class="col-sm-2"> <dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Facebook) @Html.DisplayNameFor(model => model.Facebook)
</dt> </dt>
<dd class="col-sm-10"> <dd class="col-sm-10">
@Html.DisplayFor(model => model.Facebook) @if(Model.Facebook != null)
</dd> {
<dt class = "col-sm-2"> <a href="https://www.facebook.com/@Html.DisplayFor(model => model.Facebook)">@Html.DisplayFor(model => model.Facebook)</a>
@Html.DisplayNameFor(model => model.Photo) }
</dt>
<dd class = "col-sm-10">
@Html.DisplayFor(model => model.Photo)
</dd> </dd>
</dl> </dl>
<form asp-action="Delete"> <form asp-action="Delete">
<input type="hidden" asp-for="Id" /> <input type="hidden"
<input type="submit" value="Delete" class="btn btn-danger" /> | asp-for="Id" />
<a asp-action="Index">Back to List</a> <input class="btn btn-danger"
type="submit"
value="Delete" />
<a asp-action="Index"
class="btn btn-secondary">
Back to List
</a>
</form> </form>
</div> </div>

View File

@@ -22,6 +22,18 @@
<dd class="col-sm-10"> <dd class="col-sm-10">
@Html.DisplayFor(model => model.Surname) @Html.DisplayFor(model => model.Surname)
</dd> </dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Alias)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Alias)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.DisplayName)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.DisplayName)
</dd>
<dt class="col-sm-2"> <dt class="col-sm-2">
@Html.DisplayNameFor(model => model.CountryOfBirth) @Html.DisplayNameFor(model => model.CountryOfBirth)
</dt> </dt>
@@ -50,23 +62,30 @@
@Html.DisplayNameFor(model => model.Twitter) @Html.DisplayNameFor(model => model.Twitter)
</dt> </dt>
<dd class="col-sm-10"> <dd class="col-sm-10">
@Html.DisplayFor(model => model.Twitter) @if(Model.Twitter != null)
{
<a href="https://twitter.com/@Html.DisplayFor(model => model.Twitter)">@Html.DisplayFor(model => model.Twitter)</a>
}
</dd> </dd>
<dt class="col-sm-2"> <dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Facebook) @Html.DisplayNameFor(model => model.Facebook)
</dt> </dt>
<dd class="col-sm-10"> <dd class="col-sm-10">
@Html.DisplayFor(model => model.Facebook) @if(Model.Facebook != null)
</dd> {
<dt class = "col-sm-2"> <a href="https://www.facebook.com/@Html.DisplayFor(model => model.Facebook)">@Html.DisplayFor(model => model.Facebook)</a>
@Html.DisplayNameFor(model => model.Photo) }
</dt>
<dd class = "col-sm-10">
@Html.DisplayFor(model => model.Photo)
</dd> </dd>
</dl> </dl>
</div> </div>
<div> <div>
<a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> | <a asp-action="Edit"
<a asp-action="Index">Back to List</a> asp-route-id="@Model.Id"
class="btn btn-primary">
Edit
</a>
<a asp-action="Index"
class="btn btn-secondary">
Back to List
</a>
</div> </div>

View File

@@ -11,61 +11,123 @@
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
<form asp-action="Edit"> <form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div> <div asp-validation-summary="ModelOnly"
<div class="form-group"> class="text-danger">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="Surname" class="control-label"></label> <label asp-for="Name"
<input asp-for="Surname" class="form-control" /> class="control-label">
<span asp-validation-for="Surname" class="text-danger"></span> </label>
<input asp-for="Name"
class="form-control" />
<span asp-validation-for="Name"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="BirthDate" class="control-label"></label> <label asp-for="Surname"
<input asp-for="BirthDate" class="form-control" /> class="control-label">
<span asp-validation-for="BirthDate" class="text-danger"></span> </label>
<input asp-for="Surname"
class="form-control" />
<span asp-validation-for="Surname"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="DeathDate" class="control-label"></label> <label asp-for="Alias"
<input asp-for="DeathDate" class="form-control" /> class="control-label">
<span asp-validation-for="DeathDate" class="text-danger"></span> </label>
<input asp-for="Alias"
class="form-control" />
<span asp-validation-for="Alias"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="Webpage" class="control-label"></label> <label asp-for="DisplayName"
<input asp-for="Webpage" class="form-control" /> class="control-label">
<span asp-validation-for="Webpage" class="text-danger"></span> </label>
<input asp-for="DisplayName"
class="form-control" />
<span asp-validation-for="DisplayName"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="Twitter" class="control-label"></label> <label asp-for="BirthDate"
<input asp-for="Twitter" class="form-control" /> class="control-label">
<span asp-validation-for="Twitter" class="text-danger"></span> </label>
<input asp-for="BirthDate"
class="form-control" />
<span asp-validation-for="BirthDate"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="Facebook" class="control-label"></label> <label asp-for="DeathDate"
<input asp-for="Facebook" class="form-control" /> class="control-label">
<span asp-validation-for="Facebook" class="text-danger"></span> </label>
<input asp-for="DeathDate"
class="form-control" />
<span asp-validation-for="DeathDate"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="Photo" class="control-label"></label> <label asp-for="Webpage"
<input asp-for="Photo" class="form-control" /> class="control-label">
<span asp-validation-for="Photo" class="text-danger"></span> </label>
<input asp-for="Webpage"
class="form-control" />
<span asp-validation-for="Webpage"
class="text-danger">
</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="CountryOfBirthId" class="control-label"></label> <label asp-for="Twitter"
<select asp-for="CountryOfBirthId" class="form-control" asp-items="ViewBag.CountryOfBirthId"></select> class="control-label">
<span asp-validation-for="CountryOfBirthId" class="text-danger"></span> </label>
<input asp-for="Twitter"
class="form-control" />
<span asp-validation-for="Twitter"
class="text-danger">
</span>
</div> </div>
<input type="hidden" asp-for="Id" />
<div class="form-group"> <div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" /> <label asp-for="Facebook"
class="control-label">
</label>
<input asp-for="Facebook"
class="form-control" />
<span asp-validation-for="Facebook"
class="text-danger">
</span>
</div>
<div class="form-group">
<label asp-for="CountryOfBirth"
class="control-label">
</label>
<select asp-for="CountryOfBirthId"
class="form-control"
asp-items="ViewBag.CountryOfBirthId">
</select>
</div>
<input type="hidden"
asp-for="Id" />
<div class="form-group">
<input class="btn btn-primary"
type="submit"
value="Save" />
<a asp-action="Index"
class="btn btn-secondary">
Back to List
</a>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
<div> @section Scripts {
<a asp-action="Index">Back to List</a> @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
</div> }

View File

@@ -1,22 +1,19 @@
@model IEnumerable<Cicm.Database.Models.Person> @model IEnumerable<Cicm.Database.Models.Person>
@{ @{
ViewData["Title"] = "Index"; ViewData["Title"] = "People";
} }
<h1>Index</h1> <h1>People</h1>
<p> <p>
<a asp-action="Create">Create New</a> <a asp-action="Create" class="btn btn-primary">Create New</a>
</p> </p>
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
<th> <th>
@Html.DisplayNameFor(model => model.Name) @Html.DisplayNameFor(model => model.FullName)
</th>
<th>
@Html.DisplayNameFor(model => model.Surname)
</th> </th>
<th> <th>
@Html.DisplayNameFor(model => model.CountryOfBirth) @Html.DisplayNameFor(model => model.CountryOfBirth)
@@ -36,9 +33,6 @@
<th> <th>
@Html.DisplayNameFor(model => model.Facebook) @Html.DisplayNameFor(model => model.Facebook)
</th> </th>
<th>
@Html.DisplayNameFor(model => model.Photo)
</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
@@ -46,10 +40,7 @@
@foreach (var item in Model) { @foreach (var item in Model) {
<tr> <tr>
<td> <td>
@Html.DisplayFor(modelItem => item.Name) @Html.DisplayFor(modelItem => item.FullName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Surname)
</td> </td>
<td> <td>
@Html.DisplayFor(modelItem => item.CountryOfBirth.Name) @Html.DisplayFor(modelItem => item.CountryOfBirth.Name)
@@ -64,18 +55,21 @@
@Html.DisplayFor(modelItem => item.Webpage) @Html.DisplayFor(modelItem => item.Webpage)
</td> </td>
<td> <td>
@Html.DisplayFor(modelItem => item.Twitter) @if(item.Twitter != null)
{
<a href="https://twitter.com/@Html.DisplayFor(modelItem => item.Twitter)">@Html.DisplayFor(modelItem => item.Twitter)</a>
}
</td> </td>
<td> <td>
@Html.DisplayFor(modelItem => item.Facebook) @if(item.Facebook != null)
{
<a href="https://www.facebook.com/@Html.DisplayFor(modelItem => item.Facebook)">@Html.DisplayFor(modelItem => item.Facebook)</a>
}
</td> </td>
<td> <td>
@Html.DisplayFor(modelItem => item.Photo) <a asp-action="Details" asp-route-id="@item.Id" class="btn btn-primary">Details</a>
</td> <a asp-action="Edit" asp-route-id="@item.Id" class="btn btn-secondary">Edit</a>
<td> <a asp-action="Delete" asp-route-id="@item.Id" class="btn btn-danger">Delete</a>
<a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-action="Details" asp-route-id="@item.Id">Details</a> |
<a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
</td> </td>
</tr> </tr>
} }

View File

@@ -2,7 +2,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp2.2</TargetFramework>
<Version>3.0.99.846</Version> <Version>3.0.99.883</Version>
<Company>Canary Islands Computer Museum</Company> <Company>Canary Islands Computer Museum</Company>
<Copyright>Copyright © 2003-2018 Natalia Portillo</Copyright> <Copyright>Copyright © 2003-2018 Natalia Portillo</Copyright>
<Product>Canary Islands Computer Museum Website</Product> <Product>Canary Islands Computer Museum Website</Product>