mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-22 17:47:53 +00:00
Beginning React+Redux "Music Store" sample
This commit is contained in:
3
samples/react/MusicStore/.babelrc
Normal file
3
samples/react/MusicStore/.babelrc
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"presets": ["es2015", "react"]
|
||||||
|
}
|
||||||
3
samples/react/MusicStore/.gitignore
vendored
Normal file
3
samples/react/MusicStore/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
music-db.sqlite
|
||||||
|
/wwwroot/dist/
|
||||||
|
/node_modules/
|
||||||
206
samples/react/MusicStore/Apis/AlbumsApiController.cs
Normal file
206
samples/react/MusicStore/Apis/AlbumsApiController.cs
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Authorization;
|
||||||
|
using Microsoft.AspNet.Mvc;
|
||||||
|
using Microsoft.Data.Entity;
|
||||||
|
using AutoMapper;
|
||||||
|
using MusicStore.Models;
|
||||||
|
using MusicStore.Infrastructure;
|
||||||
|
|
||||||
|
namespace MusicStore.Apis
|
||||||
|
{
|
||||||
|
[Route("api/albums")]
|
||||||
|
public class AlbumsApiController : Controller
|
||||||
|
{
|
||||||
|
private readonly MusicStoreContext _storeContext;
|
||||||
|
|
||||||
|
public AlbumsApiController(MusicStoreContext storeContext)
|
||||||
|
{
|
||||||
|
_storeContext = storeContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[NoCache]
|
||||||
|
public async Task<ActionResult> Paged(int page = 1, int pageSize = 50, string sortBy = null)
|
||||||
|
{
|
||||||
|
await _storeContext.Genres.LoadAsync();
|
||||||
|
await _storeContext.Artists.LoadAsync();
|
||||||
|
|
||||||
|
var albums = await _storeContext.Albums
|
||||||
|
// .Include(a => a.Genre)
|
||||||
|
// .Include(a => a.Artist)
|
||||||
|
.ToPagedListAsync(page, pageSize, sortBy,
|
||||||
|
a => a.Title, // sortExpression
|
||||||
|
SortDirection.Ascending, // defaultSortDirection
|
||||||
|
a => Mapper.Map(a, new AlbumResultDto())); // selector
|
||||||
|
|
||||||
|
return Json(albums);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("all")]
|
||||||
|
[NoCache]
|
||||||
|
public async Task<ActionResult> All()
|
||||||
|
{
|
||||||
|
var albums = await _storeContext.Albums
|
||||||
|
//.Include(a => a.Genre)
|
||||||
|
//.Include(a => a.Artist)
|
||||||
|
.OrderBy(a => a.Title)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Json(albums.Select(a => Mapper.Map(a, new AlbumResultDto())));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("mostPopular")]
|
||||||
|
[NoCache]
|
||||||
|
public async Task<ActionResult> MostPopular(int count = 6)
|
||||||
|
{
|
||||||
|
count = count > 0 && count < 20 ? count : 6;
|
||||||
|
var albums = await _storeContext.Albums
|
||||||
|
.OrderByDescending(a => a.OrderDetails.Count())
|
||||||
|
.Take(count)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
// TODO: Move the .Select() to end of albums query when EF supports it
|
||||||
|
return Json(albums.Select(a => Mapper.Map(a, new AlbumResultDto())));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{albumId:int}")]
|
||||||
|
[NoCache]
|
||||||
|
public async Task<ActionResult> Details(int albumId)
|
||||||
|
{
|
||||||
|
await _storeContext.Genres.LoadAsync();
|
||||||
|
await _storeContext.Artists.LoadAsync();
|
||||||
|
|
||||||
|
var album = await _storeContext.Albums
|
||||||
|
//.Include(a => a.Artist)
|
||||||
|
//.Include(a => a.Genre)
|
||||||
|
.Where(a => a.AlbumId == albumId)
|
||||||
|
.SingleOrDefaultAsync();
|
||||||
|
|
||||||
|
var albumResult = Mapper.Map(album, new AlbumResultDto());
|
||||||
|
|
||||||
|
// TODO: Get these from the related entities when EF supports that again, i.e. when .Include() works
|
||||||
|
//album.Artist.Name = (await _storeContext.Artists.SingleOrDefaultAsync(a => a.ArtistId == album.ArtistId)).Name;
|
||||||
|
//album.Genre.Name = (await _storeContext.Genres.SingleOrDefaultAsync(g => g.GenreId == album.GenreId)).Name;
|
||||||
|
|
||||||
|
// TODO: Add null checking and return 404 in that case
|
||||||
|
|
||||||
|
return Json(albumResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Authorize("app-ManageStore")]
|
||||||
|
public async Task<ActionResult> CreateAlbum([FromBody]AlbumChangeDto album)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
// Return the model errors
|
||||||
|
return HttpBadRequest(ModelState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the changes to the DB
|
||||||
|
var dbAlbum = new Album();
|
||||||
|
_storeContext.Albums.Add(Mapper.Map(album, dbAlbum));
|
||||||
|
await _storeContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
// TODO: Handle missing record, key violations, concurrency issues, etc.
|
||||||
|
|
||||||
|
return new ObjectResult(new {
|
||||||
|
Data = dbAlbum.AlbumId,
|
||||||
|
Message = "Album created successfully."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("{albumId:int}/update")]
|
||||||
|
public async Task<ActionResult> UpdateAlbum(int albumId, [FromBody] AlbumChangeDto album)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
// Return the model errors
|
||||||
|
return HttpBadRequest(ModelState);
|
||||||
|
}
|
||||||
|
|
||||||
|
var dbAlbum = await _storeContext.Albums.SingleOrDefaultAsync(a => a.AlbumId == albumId);
|
||||||
|
|
||||||
|
if (dbAlbum == null)
|
||||||
|
{
|
||||||
|
return new ObjectResult(new {
|
||||||
|
Message = string.Format("The album with ID {0} was not found.", albumId)
|
||||||
|
}) { StatusCode = 404 };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the changes to the DB
|
||||||
|
Mapper.Map(album, dbAlbum);
|
||||||
|
await _storeContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
// TODO: Handle missing record, key violations, concurrency issues, etc.
|
||||||
|
|
||||||
|
return new ObjectResult (new {
|
||||||
|
Message = "Album updated successfully."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{albumId:int}")]
|
||||||
|
[Authorize("app-ManageStore")]
|
||||||
|
public async Task<ActionResult> DeleteAlbum(int albumId)
|
||||||
|
{
|
||||||
|
var album = await _storeContext.Albums.SingleOrDefaultAsync(a => a.AlbumId == albumId);
|
||||||
|
//var album = _storeContext.Albums.SingleOrDefault(a => a.AlbumId == albumId);
|
||||||
|
|
||||||
|
if (album != null)
|
||||||
|
{
|
||||||
|
_storeContext.Albums.Remove(album);
|
||||||
|
|
||||||
|
// Save the changes to the DB
|
||||||
|
await _storeContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
// TODO: Handle missing record, key violations, concurrency issues, etc.
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ObjectResult (new {
|
||||||
|
Message = "Album deleted successfully."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ModelMetadataType(typeof(Album))]
|
||||||
|
public class AlbumChangeDto
|
||||||
|
{
|
||||||
|
public int GenreId { get; set; }
|
||||||
|
|
||||||
|
public int ArtistId { get; set; }
|
||||||
|
|
||||||
|
public string Title { get; set; }
|
||||||
|
|
||||||
|
public decimal Price { get; set; }
|
||||||
|
|
||||||
|
public string AlbumArtUrl { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AlbumResultDto : AlbumChangeDto
|
||||||
|
{
|
||||||
|
public AlbumResultDto()
|
||||||
|
{
|
||||||
|
Artist = new ArtistResultDto();
|
||||||
|
Genre = new GenreResultDto();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int AlbumId { get; set; }
|
||||||
|
|
||||||
|
public ArtistResultDto Artist { get; private set; }
|
||||||
|
|
||||||
|
public GenreResultDto Genre { get; private set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ArtistResultDto
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GenreResultDto
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
30
samples/react/MusicStore/Apis/ArtistsApiController.cs
Normal file
30
samples/react/MusicStore/Apis/ArtistsApiController.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Mvc;
|
||||||
|
using Microsoft.Data.Entity;
|
||||||
|
using MusicStore.Models;
|
||||||
|
|
||||||
|
namespace MusicStore.Apis
|
||||||
|
{
|
||||||
|
[Route("api/artists")]
|
||||||
|
public class ArtistsApiController : Controller
|
||||||
|
{
|
||||||
|
private readonly MusicStoreContext _storeContext;
|
||||||
|
|
||||||
|
public ArtistsApiController(MusicStoreContext storeContext)
|
||||||
|
{
|
||||||
|
_storeContext = storeContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("lookup")]
|
||||||
|
public async Task<ActionResult> Lookup()
|
||||||
|
{
|
||||||
|
var artists = await _storeContext.Artists
|
||||||
|
.OrderBy(a => a.Name)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Json(artists);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
70
samples/react/MusicStore/Apis/GenresApiController.cs
Normal file
70
samples/react/MusicStore/Apis/GenresApiController.cs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Mvc;
|
||||||
|
using Microsoft.Data.Entity;
|
||||||
|
using MusicStore.Models;
|
||||||
|
using MusicStore.Infrastructure;
|
||||||
|
|
||||||
|
namespace MusicStore.Apis
|
||||||
|
{
|
||||||
|
[Route("api/genres")]
|
||||||
|
public class GenresApiController : Controller
|
||||||
|
{
|
||||||
|
private readonly MusicStoreContext _storeContext;
|
||||||
|
|
||||||
|
public GenresApiController(MusicStoreContext storeContext)
|
||||||
|
{
|
||||||
|
_storeContext = storeContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<ActionResult> GenreList()
|
||||||
|
{
|
||||||
|
var genres = await _storeContext.Genres
|
||||||
|
//.Include(g => g.Albums)
|
||||||
|
.OrderBy(g => g.Name)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Json(genres);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("genre-lookup")]
|
||||||
|
public async Task<ActionResult> Lookup()
|
||||||
|
{
|
||||||
|
var genres = await _storeContext.Genres
|
||||||
|
.Select(g => new { g.GenreId, g.Name })
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Json(genres);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("menu")]
|
||||||
|
public async Task<ActionResult> GenreMenuList(int count = 9)
|
||||||
|
{
|
||||||
|
count = count > 0 && count < 20 ? count : 9;
|
||||||
|
|
||||||
|
var genres = await _storeContext.Genres
|
||||||
|
.OrderByDescending(g =>
|
||||||
|
g.Albums.Sum(a =>
|
||||||
|
a.OrderDetails.Sum(od => od.Quantity)))
|
||||||
|
.Take(count)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Json(genres);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{genreId:int}/albums")]
|
||||||
|
[NoCache]
|
||||||
|
public async Task<ActionResult> GenreAlbums(int genreId)
|
||||||
|
{
|
||||||
|
var albums = await _storeContext.Albums
|
||||||
|
.Where(a => a.GenreId == genreId)
|
||||||
|
//.Include(a => a.Genre)
|
||||||
|
//.Include(a => a.Artist)
|
||||||
|
//.OrderBy(a => a.Genre.Name)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Json(albums);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
63
samples/react/MusicStore/Apis/Models/AccountViewModels.cs
Normal file
63
samples/react/MusicStore/Apis/Models/AccountViewModels.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace MusicStore.Models
|
||||||
|
{
|
||||||
|
public class ExternalLoginConfirmationViewModel
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[Display(Name = "User name")]
|
||||||
|
public string UserName { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ManageUserViewModel
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "Current password")]
|
||||||
|
public string OldPassword { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "New password")]
|
||||||
|
public string NewPassword { get; set; }
|
||||||
|
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "Confirm new password")]
|
||||||
|
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
|
||||||
|
public string ConfirmPassword { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LoginViewModel
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[Display(Name = "User name")]
|
||||||
|
public string UserName { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "Password")]
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
[Display(Name = "Remember me?")]
|
||||||
|
public bool RememberMe { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RegisterViewModel
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[Display(Name = "User name")]
|
||||||
|
public string UserName { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "Password")]
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "Confirm password")]
|
||||||
|
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
|
||||||
|
public string ConfirmPassword { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
40
samples/react/MusicStore/Apis/Models/Album.cs
Normal file
40
samples/react/MusicStore/Apis/Models/Album.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace MusicStore.Models
|
||||||
|
{
|
||||||
|
public class Album
|
||||||
|
{
|
||||||
|
public Album()
|
||||||
|
{
|
||||||
|
// TODO: Temporary hack to populate the orderdetails until EF does this automatically.
|
||||||
|
OrderDetails = new List<OrderDetail>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ScaffoldColumn(false)]
|
||||||
|
public int AlbumId { get; set; }
|
||||||
|
|
||||||
|
public int GenreId { get; set; }
|
||||||
|
|
||||||
|
public int ArtistId { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[StringLength(160, MinimumLength = 2)]
|
||||||
|
public string Title { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[RangeAttribute(typeof(double), "0.01", "100")] // Long-form constructor to work around https://github.com/dotnet/coreclr/issues/2172
|
||||||
|
[DataType(DataType.Currency)]
|
||||||
|
public decimal Price { get; set; }
|
||||||
|
|
||||||
|
[Display(Name = "Album Art URL")]
|
||||||
|
[StringLength(1024)]
|
||||||
|
public string AlbumArtUrl { get; set; }
|
||||||
|
|
||||||
|
public virtual Genre Genre { get; set; }
|
||||||
|
|
||||||
|
public virtual Artist Artist { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<OrderDetail> OrderDetails { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
12
samples/react/MusicStore/Apis/Models/Artist.cs
Normal file
12
samples/react/MusicStore/Apis/Models/Artist.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace MusicStore.Models
|
||||||
|
{
|
||||||
|
public class Artist
|
||||||
|
{
|
||||||
|
public int ArtistId { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
21
samples/react/MusicStore/Apis/Models/CartItem.cs
Normal file
21
samples/react/MusicStore/Apis/Models/CartItem.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace MusicStore.Models
|
||||||
|
{
|
||||||
|
public class CartItem
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public int CartItemId { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string CartId { get; set; }
|
||||||
|
public int AlbumId { get; set; }
|
||||||
|
public int Count { get; set; }
|
||||||
|
|
||||||
|
[DataType(DataType.DateTime)]
|
||||||
|
public DateTime DateCreated { get; set; }
|
||||||
|
|
||||||
|
public virtual Album Album { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
24
samples/react/MusicStore/Apis/Models/Genre.cs
Normal file
24
samples/react/MusicStore/Apis/Models/Genre.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace MusicStore.Models
|
||||||
|
{
|
||||||
|
public class Genre
|
||||||
|
{
|
||||||
|
public Genre()
|
||||||
|
{
|
||||||
|
Albums = new List<Album>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GenreId { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<Album> Albums { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
34
samples/react/MusicStore/Apis/Models/MusicStoreContext.cs
Normal file
34
samples/react/MusicStore/Apis/Models/MusicStoreContext.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
using Microsoft.AspNet.Identity.EntityFramework;
|
||||||
|
using Microsoft.Data.Entity;
|
||||||
|
|
||||||
|
namespace MusicStore.Models
|
||||||
|
{
|
||||||
|
public class ApplicationUser : IdentityUser { }
|
||||||
|
|
||||||
|
public class MusicStoreContext : IdentityDbContext<ApplicationUser>
|
||||||
|
{
|
||||||
|
public MusicStoreContext()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbSet<Album> Albums { get; set; }
|
||||||
|
public DbSet<Artist> Artists { get; set; }
|
||||||
|
public DbSet<Order> Orders { get; set; }
|
||||||
|
public DbSet<Genre> Genres { get; set; }
|
||||||
|
public DbSet<CartItem> CartItems { get; set; }
|
||||||
|
public DbSet<OrderDetail> OrderDetails { get; set; }
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder builder)
|
||||||
|
{
|
||||||
|
// Configure pluralization
|
||||||
|
builder.Entity<Album>().ToTable("Albums");
|
||||||
|
builder.Entity<Artist>().ToTable("Artists");
|
||||||
|
builder.Entity<Order>().ToTable("Orders");
|
||||||
|
builder.Entity<Genre>().ToTable("Genres");
|
||||||
|
builder.Entity<CartItem>().ToTable("CartItems");
|
||||||
|
builder.Entity<OrderDetail>().ToTable("OrderDetails");
|
||||||
|
|
||||||
|
base.OnModelCreating(builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
73
samples/react/MusicStore/Apis/Models/Order.cs
Normal file
73
samples/react/MusicStore/Apis/Models/Order.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace MusicStore.Models
|
||||||
|
{
|
||||||
|
//[Bind(Include = "FirstName,LastName,Address,City,State,PostalCode,Country,Phone,Email")]
|
||||||
|
public class Order
|
||||||
|
{
|
||||||
|
public Order()
|
||||||
|
{
|
||||||
|
OrderDetails = new List<OrderDetail>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ScaffoldColumn(false)]
|
||||||
|
public int OrderId { get; set; }
|
||||||
|
|
||||||
|
[ScaffoldColumn(false)]
|
||||||
|
public DateTime OrderDate { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[ScaffoldColumn(false)]
|
||||||
|
public string Username { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[Display(Name = "First Name")]
|
||||||
|
[StringLength(160)]
|
||||||
|
public string FirstName { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[Display(Name = "Last Name")]
|
||||||
|
[StringLength(160)]
|
||||||
|
public string LastName { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[StringLength(70, MinimumLength = 3)]
|
||||||
|
public string Address { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[StringLength(40)]
|
||||||
|
public string City { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[StringLength(40)]
|
||||||
|
public string State { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[Display(Name = "Postal Code")]
|
||||||
|
[StringLength(10, MinimumLength = 5)]
|
||||||
|
public string PostalCode { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[StringLength(40)]
|
||||||
|
public string Country { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[StringLength(24)]
|
||||||
|
[DataType(DataType.PhoneNumber)]
|
||||||
|
public string Phone { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[Display(Name = "Email Address")]
|
||||||
|
[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}",
|
||||||
|
ErrorMessage = "Email is not valid.")]
|
||||||
|
[DataType(DataType.EmailAddress)]
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
|
[ScaffoldColumn(false)]
|
||||||
|
public decimal Total { get; set; }
|
||||||
|
|
||||||
|
public ICollection<OrderDetail> OrderDetails { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
14
samples/react/MusicStore/Apis/Models/OrderDetail.cs
Normal file
14
samples/react/MusicStore/Apis/Models/OrderDetail.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
namespace MusicStore.Models
|
||||||
|
{
|
||||||
|
public class OrderDetail
|
||||||
|
{
|
||||||
|
public int OrderDetailId { get; set; }
|
||||||
|
public int OrderId { get; set; }
|
||||||
|
public int AlbumId { get; set; }
|
||||||
|
public int Quantity { get; set; }
|
||||||
|
public decimal UnitPrice { get; set; }
|
||||||
|
|
||||||
|
public virtual Album Album { get; set; }
|
||||||
|
public virtual Order Order { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
915
samples/react/MusicStore/Apis/Models/SampleData.cs
Normal file
915
samples/react/MusicStore/Apis/Models/SampleData.cs
Normal file
@@ -0,0 +1,915 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Identity;
|
||||||
|
using Microsoft.AspNet.Identity.EntityFramework;
|
||||||
|
using Microsoft.Data.Entity;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.OptionsModel;
|
||||||
|
|
||||||
|
namespace MusicStore.Models
|
||||||
|
{
|
||||||
|
public static class SampleData
|
||||||
|
{
|
||||||
|
const string imgUrl = "/images/placeholder.png";
|
||||||
|
|
||||||
|
public static async Task InitializeMusicStoreDatabaseAsync(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
using (var db = serviceProvider.GetService<MusicStoreContext>())
|
||||||
|
{
|
||||||
|
if (await db.Database.EnsureCreatedAsync())
|
||||||
|
{
|
||||||
|
await InsertTestData(serviceProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task InsertTestData(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
var albums = GetAlbums(imgUrl, Genres, Artists);
|
||||||
|
await AddOrUpdateAsync(serviceProvider, g => g.GenreId, Genres.Select(genre => genre.Value));
|
||||||
|
await AddOrUpdateAsync(serviceProvider, a => a.ArtistId, Artists.Select(artist => artist.Value));
|
||||||
|
await AddOrUpdateAsync(serviceProvider, a => a.AlbumId, albums);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO [EF] This may be replaced by a first class mechanism in EF
|
||||||
|
private static async Task AddOrUpdateAsync<TEntity>(
|
||||||
|
IServiceProvider serviceProvider,
|
||||||
|
Func<TEntity, object> propertyToMatch, IEnumerable<TEntity> entities)
|
||||||
|
where TEntity : class
|
||||||
|
{
|
||||||
|
// Query in a separate context so that we can attach existing entities as modified
|
||||||
|
List<TEntity> existingData;
|
||||||
|
|
||||||
|
using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
|
||||||
|
using (var db = scope.ServiceProvider.GetService<MusicStoreContext>())
|
||||||
|
{
|
||||||
|
existingData = db.Set<TEntity>().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
|
||||||
|
using (var db = scope.ServiceProvider.GetService<MusicStoreContext>())
|
||||||
|
{
|
||||||
|
foreach (var item in entities)
|
||||||
|
{
|
||||||
|
db.Entry(item).State = existingData.Any(g => propertyToMatch(g).Equals(propertyToMatch(item)))
|
||||||
|
? EntityState.Modified
|
||||||
|
: EntityState.Added;
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Album[] GetAlbums(string imgUrl, Dictionary<string, Genre> genres, Dictionary<string, Artist> artists)
|
||||||
|
{
|
||||||
|
var albums = new Album[]
|
||||||
|
{
|
||||||
|
new Album { Title = "The Best Of The Men At Work", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Men At Work"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "...And Justice For All", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "עד גבול האור", Genre = genres["World"], Price = 8.99M, Artist = artists["אריק אינשטיין"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Black Light Syndrome", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Terry Bozzio, Tony Levin & Steve Stevens"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "10,000 Days", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "11i", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Supreme Beings of Leisure"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "1960", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Soul-Junk"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "4x4=12 ", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["deadmau5"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "A Copland Celebration, Vol. I", Genre = genres["Classical"], Price = 8.99M, Artist = artists["London Symphony Orchestra"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "A Lively Mind", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Paul Oakenfold"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "A Matter of Life and Death", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "A Real Dead One", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "A Real Live One", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "A Rush of Blood to the Head", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Coldplay"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "A Soprano Inspired", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Britten Sinfonia, Ivor Bolton & Lesley Garrett"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "A Winter Symphony", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Abbey Road", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Beatles"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Ace Of Spades", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Motörhead"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Achtung Baby", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Acústico MTV", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Os Paralamas Do Sucesso"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Adams, John: The Chairman Dances", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Edo de Waart & San Francisco Symphony"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Adrenaline", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deftones"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Ænima", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Afrociberdelia", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Chico Science & Nação Zumbi"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "After the Goldrush", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Neil Young"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Airdrawn Dagger", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Sasha"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Album Title Goes Here", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["deadmau5"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Alcohol Fueled Brewtality Live! [Disc 1]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Label Society"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Alcohol Fueled Brewtality Live! [Disc 2]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Label Society"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Alive 2007", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Daft Punk"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "All I Ask of You", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Amen (So Be It)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Paddy Casey"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Animal Vehicle", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Axis of Awesome"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Ao Vivo [IMPORT]", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Zeca Pagodinho"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Apocalyptic Love", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Slash"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Appetite for Destruction", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Are You Experienced?", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Jimi Hendrix"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Arquivo II", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Os Paralamas Do Sucesso"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Arquivo Os Paralamas Do Sucesso", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Os Paralamas Do Sucesso"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "A-Sides", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Soundgarden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Audioslave", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Audioslave"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Automatic for the People", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["R.E.M."], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Axé Bahia 2001", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Various Artists"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Babel", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Mumford & Sons"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Bach: Goldberg Variations", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Wilhelm Kempff"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Bach: The Brandenburg Concertos", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Orchestra of The Age of Enlightenment"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Bach: The Cello Suites", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Yo-Yo Ma"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Bach: Toccata & Fugue in D Minor", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Ton Koopman"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Bad Motorfinger", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Soundgarden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Balls to the Wall", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Accept"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Banadeek Ta'ala", Genre = genres["World"], Price = 8.99M, Artist = artists["Amr Diab"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Barbie Girl", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Aqua"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Bark at the Moon (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Bartok: Violin & Viola Concertos", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Yehudi Menuhin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Barulhinho Bom", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Marisa Monte"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "BBC Sessions [Disc 1] [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "BBC Sessions [Disc 2] [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Be Here Now", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Oasis"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Bedrock 11 Compiled & Mixed", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["John Digweed"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Berlioz: Symphonie Fantastique", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Michael Tilson Thomas"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Beyond Good And Evil", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Cult"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Big Bad Wolf ", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Armand Van Helden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Big Ones", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Aerosmith"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Black Album", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Black Sabbath Vol. 4 (Remaster)", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Sabbath"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Black Sabbath", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Black Sabbath"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Black", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Blackwater Park", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Opeth"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Blizzard of Ozz", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Blood", Genre = genres["Rock"], Price = 8.99M, Artist = artists["In This Moment"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Blue Moods", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Incognito"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Blue", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Weezer"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Bongo Fury", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Frank Zappa & Captain Beefheart"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Boys & Girls", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alabama Shakes"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Brave New World", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "B-Sides 1980-1990", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Bunkka", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Paul Oakenfold"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "By The Way", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Red Hot Chili Peppers"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Cake: B-Sides and Rarities", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Cake"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Californication", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Red Hot Chili Peppers"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Carmina Burana", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Boston Symphony Orchestra & Seiji Ozawa"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Carried to Dust (Bonus Track Version)", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Calexico"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Carry On", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Chris Cornell"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Cássia Eller - Sem Limite [Disc 1]", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Cássia Eller"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Chemical Wedding", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Bruce Dickinson"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Chill: Brazil (Disc 1)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Marcos Valle"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Chill: Brazil (Disc 2)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Antônio Carlos Jobim"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Chocolate Starfish And The Hot Dog Flavored Water", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Limp Bizkit"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Chronicle, Vol. 1", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Creedence Clearwater Revival"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Chronicle, Vol. 2", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Creedence Clearwater Revival"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Ciao, Baby", Genre = genres["Rock"], Price = 8.99M, Artist = artists["TheStart"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Cidade Negra - Hits", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Cidade Negra"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Classic Munkle: Turbo Edition", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Munkle"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Classics: The Best of Sarah Brightman", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Coda", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Come Away With Me", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Norah Jones"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Come Taste The Band", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Comfort Eagle", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Cake"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Common Reaction", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Uh Huh Her "], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Compositores", Genre = genres["Rock"], Price = 8.99M, Artist = artists["O Terço"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Contraband", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Velvet Revolver"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Core", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Stone Temple Pilots"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Cornerstone", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Styx"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Cosmicolor", Genre = genres["Rap"], Price = 8.99M, Artist = artists["M-Flo"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Cross", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Justice"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Culture of Fear", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Thievery Corporation"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Da Lama Ao Caos", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Chico Science & Nação Zumbi"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Dakshina", Genre = genres["World"], Price = 8.99M, Artist = artists["Deva Premal"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Dark Side of the Moon", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Death Magnetic", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Deep End of Down", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Above the Fold"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Deep Purple In Rock", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Deixa Entrar", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Falamansa"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Deja Vu", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Crosby, Stills, Nash, and Young"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Di Korpu Ku Alma", Genre = genres["World"], Price = 8.99M, Artist = artists["Lura"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Diary of a Madman (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Diary of a Madman", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Dirt", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alice in Chains"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Diver Down", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Djavan Ao Vivo - Vol. 02", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Djavan"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Djavan Ao Vivo - Vol. 1", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Djavan"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Drum'n'bass for Papa", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Plug"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Duluth", Genre = genres["Country"], Price = 8.99M, Artist = artists["Trampled By Turtles"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Dummy", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Portishead"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Duos II", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Luciana Souza/Romero Lubambo"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Earl Scruggs and Friends", Genre = genres["Country"], Price = 8.99M, Artist = artists["Earl Scruggs"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Eden", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "El Camino", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Black Keys"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Elegant Gypsy", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Al di Meola"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Elements Of Life", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Tiësto"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Elis Regina-Minha História", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Elis Regina"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Emergency On Planet Earth", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Jamiroquai"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Emotion", Genre = genres["World"], Price = 8.99M, Artist = artists["Papa Wemba"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "English Renaissance", Genre = genres["Classical"], Price = 8.99M, Artist = artists["The King's Singers"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Every Kind of Light", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Posies"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Faceless", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Godsmack"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Facelift", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alice in Chains"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Fair Warning", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Fear of a Black Planet", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Public Enemy"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Fear Of The Dark", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Feels Like Home", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Norah Jones"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Fireball", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Fly", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "For Those About To Rock We Salute You", Genre = genres["Rock"], Price = 8.99M, Artist = artists["AC/DC"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Four", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Blues Traveler"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Frank", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Amy Winehouse"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Further Down the Spiral", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Nine Inch Nails"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Garage Inc. (Disc 1)", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Garage Inc. (Disc 2)", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Garbage", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Garbage"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Good News For People Who Love Bad News", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Modest Mouse"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Gordon", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Barenaked Ladies"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Górecki: Symphony No. 3", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Adrian Leaper & Doreen de Feis"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Greatest Hits I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Greatest Hits II", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Greatest Hits", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Duck Sauce"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Greatest Hits", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Lenny Kravitz"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Greatest Hits", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Lenny Kravitz"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Greatest Kiss", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Kiss"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Greetings from Michigan", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Sufjan Stevens"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Group Therapy", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Above & Beyond"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Handel: The Messiah (Highlights)", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Scholars Baroque Ensemble"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Haydn: Symphonies 99 - 104", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Royal Philharmonic Orchestra"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Heart of the Night", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Spyro Gyra"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Heart On", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Eagles of Death Metal"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Holy Diver", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Dio"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Homework", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Daft Punk"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Hot Rocks, 1964-1971 (Disc 1)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Rolling Stones"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Houses Of The Holy", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "How To Dismantle An Atomic Bomb", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Human", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Projected"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Hunky Dory", Genre = genres["Rock"], Price = 8.99M, Artist = artists["David Bowie"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Hymns", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Projected"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Hysteria", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Def Leppard"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "In Absentia", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Porcupine Tree"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "In Between", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Paul Van Dyk"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "In Rainbows", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Radiohead"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "In Step", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Stevie Ray Vaughan & Double Trouble"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "In the court of the Crimson King", Genre = genres["Rock"], Price = 8.99M, Artist = artists["King Crimson"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "In Through The Out Door", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "In Your Honor [Disc 1]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Foo Fighters"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "In Your Honor [Disc 2]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Foo Fighters"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Indestructible", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Rancid"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Infinity", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Journey"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Into The Light", Genre = genres["Rock"], Price = 8.99M, Artist = artists["David Coverdale"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Introspective", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Pet Shop Boys"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Iron Maiden", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "ISAM", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Amon Tobin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "IV", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Jagged Little Pill", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Alanis Morissette"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Jagged Little Pill", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Alanis Morissette"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Jorge Ben Jor 25 Anos", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Jorge Ben"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Jota Quest-1995", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Jota Quest"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Kick", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["INXS"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Kill 'Em All", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Kind of Blue", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "King For A Day Fool For A Lifetime", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Faith No More"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Kiss", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Carly Rae Jepsen"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Last Call", Genre = genres["Country"], Price = 8.99M, Artist = artists["Cayouche"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Le Freak", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Chic"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Le Tigre", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Le Tigre"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Led Zeppelin I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Led Zeppelin II", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Led Zeppelin III", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Let There Be Rock", Genre = genres["Rock"], Price = 8.99M, Artist = artists["AC/DC"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Little Earthquakes", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Tori Amos"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Live [Disc 1]", Genre = genres["Blues"], Price = 8.99M, Artist = artists["The Black Crowes"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Live [Disc 2]", Genre = genres["Blues"], Price = 8.99M, Artist = artists["The Black Crowes"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Live After Death", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Live At Donington 1992 (Disc 1)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Live At Donington 1992 (Disc 2)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Live on Earth", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["The Cat Empire"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Live On Two Legs [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Living After Midnight", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Judas Priest"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Living", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Paddy Casey"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Load", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Love Changes Everything", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "MacArthur Park Suite", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Donna Summer"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Machine Head", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Magical Mystery Tour", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Beatles"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Mais Do Mesmo", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Legião Urbana"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Maquinarama", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Skank"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Marasim", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Jagjit Singh"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Mascagni: Cavalleria Rusticana", Genre = genres["Classical"], Price = 8.99M, Artist = artists["James Levine"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Master of Puppets", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Mechanics & Mathematics", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Venus Hum"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Mental Jewelry", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Live"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Metallics", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "meteora", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Linkin Park"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Meus Momentos", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Gonzaguinha"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Mezmerize", Genre = genres["Metal"], Price = 8.99M, Artist = artists["System Of A Down"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Mezzanine", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Massive Attack"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Miles Ahead", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Milton Nascimento Ao Vivo", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Milton Nascimento"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Minas", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Milton Nascimento"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Minha Historia", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Chico Buarque"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Misplaced Childhood", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Marillion"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "MK III The Final Concerts [Disc 1]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Morning Dance", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Spyro Gyra"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Motley Crue Greatest Hits", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Mötley Crüe"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Moving Pictures", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Rush"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Mozart: Chamber Music", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Nash Ensemble"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Mozart: Symphonies Nos. 40 & 41", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Berliner Philharmoniker"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Murder Ballads", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Nick Cave and the Bad Seeds"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Music For The Jilted Generation", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["The Prodigy"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "My Generation - The Very Best Of The Who", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Who"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "My Name is Skrillex", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Skrillex"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Na Pista", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Cláudio Zoli"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Nevermind", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Nirvana"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "New Adventures In Hi-Fi", Genre = genres["Rock"], Price = 8.99M, Artist = artists["R.E.M."], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "New Divide", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Linkin Park"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "New York Dolls", Genre = genres["Punk"], Price = 8.99M, Artist = artists["New York Dolls"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "News Of The World", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Nielsen: The Six Symphonies", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Göteborgs Symfoniker & Neeme Järvi"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Night At The Opera", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Queen"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Night Castle", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Trans-Siberian Orchestra"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Nkolo", Genre = genres["World"], Price = 8.99M, Artist = artists["Lokua Kanza"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "No More Tears (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "No Prayer For The Dying", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "No Security", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Rolling Stones"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "O Brother, Where Art Thou?", Genre = genres["Country"], Price = 8.99M, Artist = artists["Alison Krauss"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "O Samba Poconé", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Skank"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "O(+>", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Prince"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Oceania", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Smashing Pumpkins"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Off the Deep End", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Weird Al"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "OK Computer", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Radiohead"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Olodum", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Olodum"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "One Love", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["David Guetta"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Operation: Mindcrime", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Queensrÿche"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Opiate", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Outbreak", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Dennis Chambers"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Pachelbel: Canon & Gigue", Genre = genres["Classical"], Price = 8.99M, Artist = artists["English Concert & Trevor Pinnock"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Paid in Full", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Eric B. and Rakim"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Para Siempre", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Vicente Fernandez"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Pause", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Four Tet"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Peace Sells... but Who's Buying", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Megadeth"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Physical Graffiti [Disc 1]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Physical Graffiti [Disc 2]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Physical Graffiti", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Piece Of Mind", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Pinkerton", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Weezer"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Plays Metallica By Four Cellos", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Apocalyptica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Pop", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Powerslave", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Prenda Minha", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Caetano Veloso"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Presence", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Pretty Hate Machine", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Nine Inch Nails"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Prisoner", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Jezabels"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Privateering", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Mark Knopfler"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Prokofiev: Romeo & Juliet", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Michael Tilson Thomas"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Prokofiev: Symphony No.1", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sergei Prokofiev & Yuri Temirkanov"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "PSY's Best 6th Part 1", Genre = genres["Pop"], Price = 8.99M, Artist = artists["PSY"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Purcell: The Fairy Queen", Genre = genres["Classical"], Price = 8.99M, Artist = artists["London Classical Players"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Purpendicular", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Purple", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Stone Temple Pilots"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Quanta Gente Veio Ver (Live)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Gilberto Gil"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Quanta Gente Veio ver--Bônus De Carnaval", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Gilberto Gil"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Quiet Songs", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Aisha Duo"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Raices", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Los Tigres del Norte"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Raising Hell", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Run DMC"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Raoul and the Kings of Spain ", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tears For Fears"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Rattle And Hum", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Raul Seixas", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Raul Seixas"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Recovery [Explicit]", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Eminem"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Reign In Blood", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Slayer"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Relayed", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Yes"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "ReLoad", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Respighi:Pines of Rome", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Eugene Ormandy"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Restless and Wild", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Accept"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Retrospective I (1974-1980)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Rush"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Revelations", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Audioslave"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Revolver", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Beatles"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Ride the Lighting ", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Ride The Lightning", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Ring My Bell", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Anita Ward"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Riot Act", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Rise of the Phoenix", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Before the Dawn"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Rock In Rio [CD1]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Rock In Rio [CD2]", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Rock In Rio [CD2]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Roda De Funk", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Funk Como Le Gusta"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Room for Squares", Genre = genres["Pop"], Price = 8.99M, Artist = artists["John Mayer"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Root Down", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Jimmy Smith"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Rounds", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Four Tet"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Rubber Factory", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Black Keys"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Rust in Peace", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Megadeth"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Sambas De Enredo 2001", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Various Artists"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Santana - As Years Go By", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Santana"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Santana Live", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Santana"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Saturday Night Fever", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Bee Gees"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Scary Monsters and Nice Sprites", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Skrillex"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Scheherazade", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Chicago Symphony Orchestra & Fritz Reiner"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "SCRIABIN: Vers la flamme", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Christopher O'Riley"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Second Coming", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Stone Roses"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Serie Sem Limite (Disc 1)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Tim Maia"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Serie Sem Limite (Disc 2)", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Tim Maia"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Serious About Men", Genre = genres["Rap"], Price = 8.99M, Artist = artists["The Rubberbandits"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Seventh Son of a Seventh Son", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Short Bus", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Filter"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Sibelius: Finlandia", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Berliner Philharmoniker"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Singles Collection", Genre = genres["Rock"], Price = 8.99M, Artist = artists["David Bowie"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Six Degrees of Inner Turbulence", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Dream Theater"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Slave To The Empire", Genre = genres["Metal"], Price = 8.99M, Artist = artists["T&N"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Slaves And Masters", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Slouching Towards Bethlehem", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Robert James"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Smash", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Offspring"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Something Special", Genre = genres["Country"], Price = 8.99M, Artist = artists["Dolly Parton"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Somewhere in Time", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Song(s) You Know By Heart", Genre = genres["Country"], Price = 8.99M, Artist = artists["Jimmy Buffett"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Sound of Music", Genre = genres["Punk"], Price = 8.99M, Artist = artists["Adicts"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "South American Getaway", Genre = genres["Classical"], Price = 8.99M, Artist = artists["The 12 Cellists of The Berlin Philharmonic"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Sozinho Remix Ao Vivo", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Caetano Veloso"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Speak of the Devil", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Spiritual State", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Nujabes"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "St. Anger", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Metallica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Still Life", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Opeth"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Stop Making Sense", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Talking Heads"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Stormbringer", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Stranger than Fiction", Genre = genres["Punk"], Price = 8.99M, Artist = artists["Bad Religion"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Strauss: Waltzes", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Eugene Ormandy"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Supermodified", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Amon Tobin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Supernatural", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Santana"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Surfing with the Alien (Remastered)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Joe Satriani"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Switched-On Bach", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Wendy Carlos"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Symphony", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Szymanowski: Piano Works, Vol. 1", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Martin Roscoe"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Tchaikovsky: The Nutcracker", Genre = genres["Classical"], Price = 8.99M, Artist = artists["London Symphony Orchestra"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Ted Nugent", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Ted Nugent"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Teflon Don", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Rick Ross"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Tell Another Joke at the Ol' Choppin' Block", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Danielson Famile"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Temple of the Dog", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Temple of the Dog"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Ten", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Texas Flood", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Stevie Ray Vaughan"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Battle Rages On", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Beast Live", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Paul D'Ianno"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Best Of 1980-1990", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Best of 1990–2000", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Best of Beethoven", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Nicolaus Esterhazy Sinfonia"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Best Of Billy Cobham", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Billy Cobham"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Best of Ed Motta", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Ed Motta"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Best Of Van Halen, Vol. I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Bridge", Genre = genres["R&B"], Price = 8.99M, Artist = artists["Melanie Fiona"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Cage", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tygers of Pan Tang"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Chicago Transit Authority", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Chicago "], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Chronic", Genre = genres["Rap"], Price = 8.99M, Artist = artists["Dr. Dre"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Colour And The Shape", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Foo Fighters"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Crane Wife", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["The Decemberists"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Cream Of Clapton", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Eric Clapton"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Cure", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Cure"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Dark Side Of The Moon", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Divine Conspiracy", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Epica"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Doors", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Doors"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Dream of the Blue Turtles", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Sting"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Essential Miles Davis [Disc 1]", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Essential Miles Davis [Disc 2]", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Miles Davis"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Final Concerts (Disc 2)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deep Purple"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Final Frontier", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Head and the Heart", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Head and the Heart"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Joshua Tree", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Last Night of the Proms", Genre = genres["Classical"], Price = 8.99M, Artist = artists["BBC Concert Orchestra"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Lumineers", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Lumineers"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Number of The Beast", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Number of The Beast", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Police Greatest Hits", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Police"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Song Remains The Same (Disc 1)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Song Remains The Same (Disc 2)", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Southern Harmony and Musical Companion", Genre = genres["Blues"], Price = 8.99M, Artist = artists["The Black Crowes"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Spade", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Butch Walker & The Black Widows"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Stone Roses", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Stone Roses"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Suburbs", Genre = genres["Indie"], Price = 8.99M, Artist = artists["Arcade Fire"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Three Tenors Disc1/Disc2", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Carreras, Pavarotti, Domingo"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Trees They Grow So High", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The Wall", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "The X Factor", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Them Crooked Vultures", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Them Crooked Vultures"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "This Is Happening", Genre = genres["Rock"], Price = 8.99M, Artist = artists["LCD Soundsystem"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Thunder, Lightning, Strike", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Go! Team"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Time to Say Goodbye", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sarah Brightman"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Time, Love & Tenderness", Genre = genres["Pop"], Price = 8.99M, Artist = artists["Michael Bolton"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Tomorrow Starts Today", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Mobile"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Tribute", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Ozzy Osbourne"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Tuesday Night Music Club", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Sheryl Crow"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Umoja", Genre = genres["Rock"], Price = 8.99M, Artist = artists["BLØF"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Under the Pink", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Tori Amos"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Undertow", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Tool"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Un-Led-Ed", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Dread Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Unplugged [Live]", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Kiss"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Unplugged", Genre = genres["Blues"], Price = 8.99M, Artist = artists["Eric Clapton"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Unplugged", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Eric Clapton"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Untrue", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Burial"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Use Your Illusion I", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Use Your Illusion II", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Use Your Illusion II", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Guns N' Roses"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Van Halen III", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Van Halen", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Van Halen"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Version 2.0", Genre = genres["Alternative"], Price = 8.99M, Artist = artists["Garbage"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Vinicius De Moraes", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Vinícius De Moraes"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Virtual XI", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Iron Maiden"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Voodoo Lounge", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Rolling Stones"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Vozes do MPB", Genre = genres["Latin"], Price = 8.99M, Artist = artists["Various Artists"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Vs.", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pearl Jam"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Wagner: Favourite Overtures", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Sir Georg Solti & Wiener Philharmoniker"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Walking Into Clarksdale", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Page & Plant"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Wapi Yo", Genre = genres["World"], Price = 8.99M, Artist = artists["Lokua Kanza"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "War", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Warner 25 Anos", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Antônio Carlos Jobim"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Wasteland R&Btheque", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Raunchy"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Watermark", Genre = genres["Electronic"], Price = 8.99M, Artist = artists["Enya"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "We Were Exploding Anyway", Genre = genres["Rock"], Price = 8.99M, Artist = artists["65daysofstatic"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Weill: The Seven Deadly Sins", Genre = genres["Classical"], Price = 8.99M, Artist = artists["Orchestre de l'Opéra de Lyon"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "White Pony", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Deftones"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Who's Next", Genre = genres["Rock"], Price = 8.99M, Artist = artists["The Who"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Wish You Were Here", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Pink Floyd"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "With Oden on Our Side", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Amon Amarth"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Worlds", Genre = genres["Jazz"], Price = 8.99M, Artist = artists["Aaron Goldberg"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Worship Music", Genre = genres["Metal"], Price = 8.99M, Artist = artists["Anthrax"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "X&Y", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Coldplay"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Xinti", Genre = genres["World"], Price = 8.99M, Artist = artists["Sara Tavares"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Yano", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Yano"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Yesterday Once More Disc 1/Disc 2", Genre = genres["Pop"], Price = 8.99M, Artist = artists["The Carpenters"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Zooropa", Genre = genres["Rock"], Price = 8.99M, Artist = artists["U2"], AlbumArtUrl = imgUrl },
|
||||||
|
new Album { Title = "Zoso", Genre = genres["Rock"], Price = 8.99M, Artist = artists["Led Zeppelin"], AlbumArtUrl = imgUrl },
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var album in albums)
|
||||||
|
{
|
||||||
|
album.ArtistId = album.Artist.ArtistId;
|
||||||
|
album.GenreId = album.Genre.GenreId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return albums;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Dictionary<string, Artist> artists;
|
||||||
|
public static Dictionary<string, Artist> Artists
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (artists == null)
|
||||||
|
{
|
||||||
|
var artistsList = new Artist[]
|
||||||
|
{
|
||||||
|
new Artist { Name = "65daysofstatic" },
|
||||||
|
new Artist { Name = "Aaron Goldberg" },
|
||||||
|
new Artist { Name = "Above & Beyond" },
|
||||||
|
new Artist { Name = "Above the Fold" },
|
||||||
|
new Artist { Name = "AC/DC" },
|
||||||
|
new Artist { Name = "Accept" },
|
||||||
|
new Artist { Name = "Adicts" },
|
||||||
|
new Artist { Name = "Adrian Leaper & Doreen de Feis" },
|
||||||
|
new Artist { Name = "Aerosmith" },
|
||||||
|
new Artist { Name = "Aisha Duo" },
|
||||||
|
new Artist { Name = "Al di Meola" },
|
||||||
|
new Artist { Name = "Alabama Shakes" },
|
||||||
|
new Artist { Name = "Alanis Morissette" },
|
||||||
|
new Artist { Name = "Alberto Turco & Nova Schola Gregoriana" },
|
||||||
|
new Artist { Name = "Alice in Chains" },
|
||||||
|
new Artist { Name = "Alison Krauss" },
|
||||||
|
new Artist { Name = "Amon Amarth" },
|
||||||
|
new Artist { Name = "Amon Tobin" },
|
||||||
|
new Artist { Name = "Amr Diab" },
|
||||||
|
new Artist { Name = "Amy Winehouse" },
|
||||||
|
new Artist { Name = "Anita Ward" },
|
||||||
|
new Artist { Name = "Anthrax" },
|
||||||
|
new Artist { Name = "Antônio Carlos Jobim" },
|
||||||
|
new Artist { Name = "Apocalyptica" },
|
||||||
|
new Artist { Name = "Aqua" },
|
||||||
|
new Artist { Name = "Armand Van Helden" },
|
||||||
|
new Artist { Name = "Arcade Fire" },
|
||||||
|
new Artist { Name = "Audioslave" },
|
||||||
|
new Artist { Name = "Bad Religion" },
|
||||||
|
new Artist { Name = "Barenaked Ladies" },
|
||||||
|
new Artist { Name = "BBC Concert Orchestra" },
|
||||||
|
new Artist { Name = "Bee Gees" },
|
||||||
|
new Artist { Name = "Before the Dawn" },
|
||||||
|
new Artist { Name = "Berliner Philharmoniker" },
|
||||||
|
new Artist { Name = "Billy Cobham" },
|
||||||
|
new Artist { Name = "Black Label Society" },
|
||||||
|
new Artist { Name = "Black Sabbath" },
|
||||||
|
new Artist { Name = "BLØF" },
|
||||||
|
new Artist { Name = "Blues Traveler" },
|
||||||
|
new Artist { Name = "Boston Symphony Orchestra & Seiji Ozawa" },
|
||||||
|
new Artist { Name = "Britten Sinfonia, Ivor Bolton & Lesley Garrett" },
|
||||||
|
new Artist { Name = "Bruce Dickinson" },
|
||||||
|
new Artist { Name = "Buddy Guy" },
|
||||||
|
new Artist { Name = "Burial" },
|
||||||
|
new Artist { Name = "Butch Walker & The Black Widows" },
|
||||||
|
new Artist { Name = "Caetano Veloso" },
|
||||||
|
new Artist { Name = "Cake" },
|
||||||
|
new Artist { Name = "Calexico" },
|
||||||
|
new Artist { Name = "Carly Rae Jepsen" },
|
||||||
|
new Artist { Name = "Carreras, Pavarotti, Domingo" },
|
||||||
|
new Artist { Name = "Cássia Eller" },
|
||||||
|
new Artist { Name = "Cayouche" },
|
||||||
|
new Artist { Name = "Chic" },
|
||||||
|
new Artist { Name = "Chicago " },
|
||||||
|
new Artist { Name = "Chicago Symphony Orchestra & Fritz Reiner" },
|
||||||
|
new Artist { Name = "Chico Buarque" },
|
||||||
|
new Artist { Name = "Chico Science & Nação Zumbi" },
|
||||||
|
new Artist { Name = "Choir Of Westminster Abbey & Simon Preston" },
|
||||||
|
new Artist { Name = "Chris Cornell" },
|
||||||
|
new Artist { Name = "Christopher O'Riley" },
|
||||||
|
new Artist { Name = "Cidade Negra" },
|
||||||
|
new Artist { Name = "Cláudio Zoli" },
|
||||||
|
new Artist { Name = "Coldplay" },
|
||||||
|
new Artist { Name = "Creedence Clearwater Revival" },
|
||||||
|
new Artist { Name = "Crosby, Stills, Nash, and Young" },
|
||||||
|
new Artist { Name = "Daft Punk" },
|
||||||
|
new Artist { Name = "Danielson Famile" },
|
||||||
|
new Artist { Name = "David Bowie" },
|
||||||
|
new Artist { Name = "David Coverdale" },
|
||||||
|
new Artist { Name = "David Guetta" },
|
||||||
|
new Artist { Name = "deadmau5" },
|
||||||
|
new Artist { Name = "Deep Purple" },
|
||||||
|
new Artist { Name = "Def Leppard" },
|
||||||
|
new Artist { Name = "Deftones" },
|
||||||
|
new Artist { Name = "Dennis Chambers" },
|
||||||
|
new Artist { Name = "Deva Premal" },
|
||||||
|
new Artist { Name = "Dio" },
|
||||||
|
new Artist { Name = "Djavan" },
|
||||||
|
new Artist { Name = "Dolly Parton" },
|
||||||
|
new Artist { Name = "Donna Summer" },
|
||||||
|
new Artist { Name = "Dr. Dre" },
|
||||||
|
new Artist { Name = "Dread Zeppelin" },
|
||||||
|
new Artist { Name = "Dream Theater" },
|
||||||
|
new Artist { Name = "Duck Sauce" },
|
||||||
|
new Artist { Name = "Earl Scruggs" },
|
||||||
|
new Artist { Name = "Ed Motta" },
|
||||||
|
new Artist { Name = "Edo de Waart & San Francisco Symphony" },
|
||||||
|
new Artist { Name = "Elis Regina" },
|
||||||
|
new Artist { Name = "Eminem" },
|
||||||
|
new Artist { Name = "English Concert & Trevor Pinnock" },
|
||||||
|
new Artist { Name = "Enya" },
|
||||||
|
new Artist { Name = "Epica" },
|
||||||
|
new Artist { Name = "Eric B. and Rakim" },
|
||||||
|
new Artist { Name = "Eric Clapton" },
|
||||||
|
new Artist { Name = "Eugene Ormandy" },
|
||||||
|
new Artist { Name = "Faith No More" },
|
||||||
|
new Artist { Name = "Falamansa" },
|
||||||
|
new Artist { Name = "Filter" },
|
||||||
|
new Artist { Name = "Foo Fighters" },
|
||||||
|
new Artist { Name = "Four Tet" },
|
||||||
|
new Artist { Name = "Frank Zappa & Captain Beefheart" },
|
||||||
|
new Artist { Name = "Fretwork" },
|
||||||
|
new Artist { Name = "Funk Como Le Gusta" },
|
||||||
|
new Artist { Name = "Garbage" },
|
||||||
|
new Artist { Name = "Gerald Moore" },
|
||||||
|
new Artist { Name = "Gilberto Gil" },
|
||||||
|
new Artist { Name = "Godsmack" },
|
||||||
|
new Artist { Name = "Gonzaguinha" },
|
||||||
|
new Artist { Name = "Göteborgs Symfoniker & Neeme Järvi" },
|
||||||
|
new Artist { Name = "Guns N' Roses" },
|
||||||
|
new Artist { Name = "Gustav Mahler" },
|
||||||
|
new Artist { Name = "In This Moment" },
|
||||||
|
new Artist { Name = "Incognito" },
|
||||||
|
new Artist { Name = "INXS" },
|
||||||
|
new Artist { Name = "Iron Maiden" },
|
||||||
|
new Artist { Name = "Jagjit Singh" },
|
||||||
|
new Artist { Name = "James Levine" },
|
||||||
|
new Artist { Name = "Jamiroquai" },
|
||||||
|
new Artist { Name = "Jimi Hendrix" },
|
||||||
|
new Artist { Name = "Jimmy Buffett" },
|
||||||
|
new Artist { Name = "Jimmy Smith" },
|
||||||
|
new Artist { Name = "Joe Satriani" },
|
||||||
|
new Artist { Name = "John Digweed" },
|
||||||
|
new Artist { Name = "John Mayer" },
|
||||||
|
new Artist { Name = "Jorge Ben" },
|
||||||
|
new Artist { Name = "Jota Quest" },
|
||||||
|
new Artist { Name = "Journey" },
|
||||||
|
new Artist { Name = "Judas Priest" },
|
||||||
|
new Artist { Name = "Julian Bream" },
|
||||||
|
new Artist { Name = "Justice" },
|
||||||
|
new Artist { Name = "Orchestre de l'Opéra de Lyon" },
|
||||||
|
new Artist { Name = "King Crimson" },
|
||||||
|
new Artist { Name = "Kiss" },
|
||||||
|
new Artist { Name = "LCD Soundsystem" },
|
||||||
|
new Artist { Name = "Le Tigre" },
|
||||||
|
new Artist { Name = "Led Zeppelin" },
|
||||||
|
new Artist { Name = "Legião Urbana" },
|
||||||
|
new Artist { Name = "Lenny Kravitz" },
|
||||||
|
new Artist { Name = "Les Arts Florissants & William Christie" },
|
||||||
|
new Artist { Name = "Limp Bizkit" },
|
||||||
|
new Artist { Name = "Linkin Park" },
|
||||||
|
new Artist { Name = "Live" },
|
||||||
|
new Artist { Name = "Lokua Kanza" },
|
||||||
|
new Artist { Name = "London Symphony Orchestra" },
|
||||||
|
new Artist { Name = "Los Tigres del Norte" },
|
||||||
|
new Artist { Name = "Luciana Souza/Romero Lubambo" },
|
||||||
|
new Artist { Name = "Lulu Santos" },
|
||||||
|
new Artist { Name = "Lura" },
|
||||||
|
new Artist { Name = "Marcos Valle" },
|
||||||
|
new Artist { Name = "Marillion" },
|
||||||
|
new Artist { Name = "Marisa Monte" },
|
||||||
|
new Artist { Name = "Mark Knopfler" },
|
||||||
|
new Artist { Name = "Martin Roscoe" },
|
||||||
|
new Artist { Name = "Massive Attack" },
|
||||||
|
new Artist { Name = "Maurizio Pollini" },
|
||||||
|
new Artist { Name = "Megadeth" },
|
||||||
|
new Artist { Name = "Mela Tenenbaum, Pro Musica Prague & Richard Kapp" },
|
||||||
|
new Artist { Name = "Melanie Fiona" },
|
||||||
|
new Artist { Name = "Men At Work" },
|
||||||
|
new Artist { Name = "Metallica" },
|
||||||
|
new Artist { Name = "M-Flo" },
|
||||||
|
new Artist { Name = "Michael Bolton" },
|
||||||
|
new Artist { Name = "Michael Tilson Thomas" },
|
||||||
|
new Artist { Name = "Miles Davis" },
|
||||||
|
new Artist { Name = "Milton Nascimento" },
|
||||||
|
new Artist { Name = "Mobile" },
|
||||||
|
new Artist { Name = "Modest Mouse" },
|
||||||
|
new Artist { Name = "Mötley Crüe" },
|
||||||
|
new Artist { Name = "Motörhead" },
|
||||||
|
new Artist { Name = "Mumford & Sons" },
|
||||||
|
new Artist { Name = "Munkle" },
|
||||||
|
new Artist { Name = "Nash Ensemble" },
|
||||||
|
new Artist { Name = "Neil Young" },
|
||||||
|
new Artist { Name = "New York Dolls" },
|
||||||
|
new Artist { Name = "Nick Cave and the Bad Seeds" },
|
||||||
|
new Artist { Name = "Nicolaus Esterhazy Sinfonia" },
|
||||||
|
new Artist { Name = "Nine Inch Nails" },
|
||||||
|
new Artist { Name = "Nirvana" },
|
||||||
|
new Artist { Name = "Norah Jones" },
|
||||||
|
new Artist { Name = "Nujabes" },
|
||||||
|
new Artist { Name = "O Terço" },
|
||||||
|
new Artist { Name = "Oasis" },
|
||||||
|
new Artist { Name = "Olodum" },
|
||||||
|
new Artist { Name = "Opeth" },
|
||||||
|
new Artist { Name = "Orchestra of The Age of Enlightenment" },
|
||||||
|
new Artist { Name = "Os Paralamas Do Sucesso" },
|
||||||
|
new Artist { Name = "Ozzy Osbourne" },
|
||||||
|
new Artist { Name = "Paddy Casey" },
|
||||||
|
new Artist { Name = "Page & Plant" },
|
||||||
|
new Artist { Name = "Papa Wemba" },
|
||||||
|
new Artist { Name = "Paul D'Ianno" },
|
||||||
|
new Artist { Name = "Paul Oakenfold" },
|
||||||
|
new Artist { Name = "Paul Van Dyk" },
|
||||||
|
new Artist { Name = "Pearl Jam" },
|
||||||
|
new Artist { Name = "Pet Shop Boys" },
|
||||||
|
new Artist { Name = "Pink Floyd" },
|
||||||
|
new Artist { Name = "Plug" },
|
||||||
|
new Artist { Name = "Porcupine Tree" },
|
||||||
|
new Artist { Name = "Portishead" },
|
||||||
|
new Artist { Name = "Prince" },
|
||||||
|
new Artist { Name = "Projected" },
|
||||||
|
new Artist { Name = "PSY" },
|
||||||
|
new Artist { Name = "Public Enemy" },
|
||||||
|
new Artist { Name = "Queen" },
|
||||||
|
new Artist { Name = "Queensrÿche" },
|
||||||
|
new Artist { Name = "R.E.M." },
|
||||||
|
new Artist { Name = "Radiohead" },
|
||||||
|
new Artist { Name = "Rancid" },
|
||||||
|
new Artist { Name = "Raul Seixas" },
|
||||||
|
new Artist { Name = "Raunchy" },
|
||||||
|
new Artist { Name = "Red Hot Chili Peppers" },
|
||||||
|
new Artist { Name = "Rick Ross" },
|
||||||
|
new Artist { Name = "Robert James" },
|
||||||
|
new Artist { Name = "London Classical Players" },
|
||||||
|
new Artist { Name = "Royal Philharmonic Orchestra" },
|
||||||
|
new Artist { Name = "Run DMC" },
|
||||||
|
new Artist { Name = "Rush" },
|
||||||
|
new Artist { Name = "Santana" },
|
||||||
|
new Artist { Name = "Sara Tavares" },
|
||||||
|
new Artist { Name = "Sarah Brightman" },
|
||||||
|
new Artist { Name = "Sasha" },
|
||||||
|
new Artist { Name = "Scholars Baroque Ensemble" },
|
||||||
|
new Artist { Name = "Scorpions" },
|
||||||
|
new Artist { Name = "Sergei Prokofiev & Yuri Temirkanov" },
|
||||||
|
new Artist { Name = "Sheryl Crow" },
|
||||||
|
new Artist { Name = "Sir Georg Solti & Wiener Philharmoniker" },
|
||||||
|
new Artist { Name = "Skank" },
|
||||||
|
new Artist { Name = "Skrillex" },
|
||||||
|
new Artist { Name = "Slash" },
|
||||||
|
new Artist { Name = "Slayer" },
|
||||||
|
new Artist { Name = "Soul-Junk" },
|
||||||
|
new Artist { Name = "Soundgarden" },
|
||||||
|
new Artist { Name = "Spyro Gyra" },
|
||||||
|
new Artist { Name = "Stevie Ray Vaughan & Double Trouble" },
|
||||||
|
new Artist { Name = "Stevie Ray Vaughan" },
|
||||||
|
new Artist { Name = "Sting" },
|
||||||
|
new Artist { Name = "Stone Temple Pilots" },
|
||||||
|
new Artist { Name = "Styx" },
|
||||||
|
new Artist { Name = "Sufjan Stevens" },
|
||||||
|
new Artist { Name = "Supreme Beings of Leisure" },
|
||||||
|
new Artist { Name = "System Of A Down" },
|
||||||
|
new Artist { Name = "T&N" },
|
||||||
|
new Artist { Name = "Talking Heads" },
|
||||||
|
new Artist { Name = "Tears For Fears" },
|
||||||
|
new Artist { Name = "Ted Nugent" },
|
||||||
|
new Artist { Name = "Temple of the Dog" },
|
||||||
|
new Artist { Name = "Terry Bozzio, Tony Levin & Steve Stevens" },
|
||||||
|
new Artist { Name = "The 12 Cellists of The Berlin Philharmonic" },
|
||||||
|
new Artist { Name = "The Axis of Awesome" },
|
||||||
|
new Artist { Name = "The Beatles" },
|
||||||
|
new Artist { Name = "The Black Crowes" },
|
||||||
|
new Artist { Name = "The Black Keys" },
|
||||||
|
new Artist { Name = "The Carpenters" },
|
||||||
|
new Artist { Name = "The Cat Empire" },
|
||||||
|
new Artist { Name = "The Cult" },
|
||||||
|
new Artist { Name = "The Cure" },
|
||||||
|
new Artist { Name = "The Decemberists" },
|
||||||
|
new Artist { Name = "The Doors" },
|
||||||
|
new Artist { Name = "The Eagles of Death Metal" },
|
||||||
|
new Artist { Name = "The Go! Team" },
|
||||||
|
new Artist { Name = "The Head and the Heart" },
|
||||||
|
new Artist { Name = "The Jezabels" },
|
||||||
|
new Artist { Name = "The King's Singers" },
|
||||||
|
new Artist { Name = "The Lumineers" },
|
||||||
|
new Artist { Name = "The Offspring" },
|
||||||
|
new Artist { Name = "The Police" },
|
||||||
|
new Artist { Name = "The Posies" },
|
||||||
|
new Artist { Name = "The Prodigy" },
|
||||||
|
new Artist { Name = "The Rolling Stones" },
|
||||||
|
new Artist { Name = "The Rubberbandits" },
|
||||||
|
new Artist { Name = "The Smashing Pumpkins" },
|
||||||
|
new Artist { Name = "The Stone Roses" },
|
||||||
|
new Artist { Name = "The Who" },
|
||||||
|
new Artist { Name = "Them Crooked Vultures" },
|
||||||
|
new Artist { Name = "TheStart" },
|
||||||
|
new Artist { Name = "Thievery Corporation" },
|
||||||
|
new Artist { Name = "Tiësto" },
|
||||||
|
new Artist { Name = "Tim Maia" },
|
||||||
|
new Artist { Name = "Ton Koopman" },
|
||||||
|
new Artist { Name = "Tool" },
|
||||||
|
new Artist { Name = "Tori Amos" },
|
||||||
|
new Artist { Name = "Trampled By Turtles" },
|
||||||
|
new Artist { Name = "Trans-Siberian Orchestra" },
|
||||||
|
new Artist { Name = "Tygers of Pan Tang" },
|
||||||
|
new Artist { Name = "U2" },
|
||||||
|
new Artist { Name = "UB40" },
|
||||||
|
new Artist { Name = "Uh Huh Her " },
|
||||||
|
new Artist { Name = "Van Halen" },
|
||||||
|
new Artist { Name = "Various Artists" },
|
||||||
|
new Artist { Name = "Velvet Revolver" },
|
||||||
|
new Artist { Name = "Venus Hum" },
|
||||||
|
new Artist { Name = "Vicente Fernandez" },
|
||||||
|
new Artist { Name = "Vinícius De Moraes" },
|
||||||
|
new Artist { Name = "Weezer" },
|
||||||
|
new Artist { Name = "Weird Al" },
|
||||||
|
new Artist { Name = "Wendy Carlos" },
|
||||||
|
new Artist { Name = "Wilhelm Kempff" },
|
||||||
|
new Artist { Name = "Yano" },
|
||||||
|
new Artist { Name = "Yehudi Menuhin" },
|
||||||
|
new Artist { Name = "Yes" },
|
||||||
|
new Artist { Name = "Yo-Yo Ma" },
|
||||||
|
new Artist { Name = "Zeca Pagodinho" },
|
||||||
|
new Artist { Name = "אריק אינשטיין"}
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO [EF] Swap to store generated keys when available
|
||||||
|
int artistId = 1;
|
||||||
|
artists = new Dictionary<string, Artist>();
|
||||||
|
foreach (Artist artist in artistsList)
|
||||||
|
{
|
||||||
|
artist.ArtistId = artistId++;
|
||||||
|
artists.Add(artist.Name, artist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return artists;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Dictionary<string, Genre> genres;
|
||||||
|
public static Dictionary<string, Genre> Genres
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (genres == null)
|
||||||
|
{
|
||||||
|
var genresList = new Genre[]
|
||||||
|
{
|
||||||
|
new Genre { Name = "Pop" },
|
||||||
|
new Genre { Name = "Rock" },
|
||||||
|
new Genre { Name = "Jazz" },
|
||||||
|
new Genre { Name = "Metal" },
|
||||||
|
new Genre { Name = "Electronic" },
|
||||||
|
new Genre { Name = "Blues" },
|
||||||
|
new Genre { Name = "Latin" },
|
||||||
|
new Genre { Name = "Rap" },
|
||||||
|
new Genre { Name = "Classical" },
|
||||||
|
new Genre { Name = "Alternative" },
|
||||||
|
new Genre { Name = "Country" },
|
||||||
|
new Genre { Name = "R&B" },
|
||||||
|
new Genre { Name = "Indie" },
|
||||||
|
new Genre { Name = "Punk" },
|
||||||
|
new Genre { Name = "World" }
|
||||||
|
};
|
||||||
|
|
||||||
|
genres = new Dictionary<string, Genre>();
|
||||||
|
// TODO [EF] Swap to store generated keys when available
|
||||||
|
int genreId = 1;
|
||||||
|
foreach (Genre genre in genresList)
|
||||||
|
{
|
||||||
|
genre.GenreId = genreId++;
|
||||||
|
|
||||||
|
// TODO [EF] Remove when null values are supported by update pipeline
|
||||||
|
genre.Description = genre.Name + " is great music (if you like it).";
|
||||||
|
|
||||||
|
genres.Add(genre.Name, genre);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return genres;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
207
samples/react/MusicStore/Apis/Models/ShoppingCart.cs
Normal file
207
samples/react/MusicStore/Apis/Models/ShoppingCart.cs
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.Data.Entity;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace MusicStore.Models
|
||||||
|
{
|
||||||
|
public partial class ShoppingCart
|
||||||
|
{
|
||||||
|
MusicStoreContext _db;
|
||||||
|
string ShoppingCartId { get; set; }
|
||||||
|
|
||||||
|
public ShoppingCart(MusicStoreContext db)
|
||||||
|
{
|
||||||
|
_db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ShoppingCart GetCart(MusicStoreContext db, HttpContext context)
|
||||||
|
{
|
||||||
|
var cart = new ShoppingCart(db);
|
||||||
|
cart.ShoppingCartId = cart.GetCartId(context);
|
||||||
|
return cart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddToCart(Album album)
|
||||||
|
{
|
||||||
|
// Get the matching cart and album instances
|
||||||
|
var cartItem = _db.CartItems.SingleOrDefault(
|
||||||
|
c => c.CartId == ShoppingCartId
|
||||||
|
&& c.AlbumId == album.AlbumId);
|
||||||
|
|
||||||
|
if (cartItem == null)
|
||||||
|
{
|
||||||
|
// TODO [EF] Swap to store generated key once we support identity pattern
|
||||||
|
var nextCartItemId = _db.CartItems.Any()
|
||||||
|
? _db.CartItems.Max(c => c.CartItemId) + 1
|
||||||
|
: 1;
|
||||||
|
|
||||||
|
// Create a new cart item if no cart item exists
|
||||||
|
cartItem = new CartItem
|
||||||
|
{
|
||||||
|
CartItemId = nextCartItemId,
|
||||||
|
AlbumId = album.AlbumId,
|
||||||
|
CartId = ShoppingCartId,
|
||||||
|
Count = 1,
|
||||||
|
DateCreated = DateTime.Now
|
||||||
|
};
|
||||||
|
|
||||||
|
_db.CartItems.Add(cartItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the item does exist in the cart, then add one to the quantity
|
||||||
|
cartItem.Count++;
|
||||||
|
|
||||||
|
// TODO [EF] Remove this line once change detection is available
|
||||||
|
_db.Update(cartItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int RemoveFromCart(int id)
|
||||||
|
{
|
||||||
|
// Get the cart
|
||||||
|
var cartItem = _db.CartItems.Single(
|
||||||
|
cart => cart.CartId == ShoppingCartId
|
||||||
|
&& cart.CartItemId == id);
|
||||||
|
|
||||||
|
int itemCount = 0;
|
||||||
|
|
||||||
|
if (cartItem != null)
|
||||||
|
{
|
||||||
|
if (cartItem.Count > 1)
|
||||||
|
{
|
||||||
|
cartItem.Count--;
|
||||||
|
|
||||||
|
// TODO [EF] Remove this line once change detection is available
|
||||||
|
_db.Update(cartItem);
|
||||||
|
|
||||||
|
itemCount = cartItem.Count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_db.CartItems.Remove(cartItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EmptyCart()
|
||||||
|
{
|
||||||
|
var cartItems = _db.CartItems.Where(cart => cart.CartId == ShoppingCartId);
|
||||||
|
|
||||||
|
foreach (var cartItem in cartItems)
|
||||||
|
{
|
||||||
|
_db.Remove(cartItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CartItem> GetCartItems()
|
||||||
|
{
|
||||||
|
var cartItems = _db.CartItems.Where(cart => cart.CartId == ShoppingCartId).ToList();
|
||||||
|
//TODO: Auto population of the related album data not available until EF feature is lighted up.
|
||||||
|
foreach (var cartItem in cartItems)
|
||||||
|
{
|
||||||
|
cartItem.Album = _db.Albums.Single(a => a.AlbumId == cartItem.AlbumId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cartItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetCount()
|
||||||
|
{
|
||||||
|
// Get the count of each item in the cart and sum them up
|
||||||
|
int? count = (from cartItems in _db.CartItems
|
||||||
|
where cartItems.CartId == ShoppingCartId
|
||||||
|
select (int?)cartItems.Count).Sum();
|
||||||
|
|
||||||
|
// Return 0 if all entries are null
|
||||||
|
return count ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public decimal GetTotal()
|
||||||
|
{
|
||||||
|
// Multiply album price by count of that album to get
|
||||||
|
// the current price for each of those albums in the cart
|
||||||
|
// sum all album price totals to get the cart total
|
||||||
|
|
||||||
|
// TODO Collapse to a single query once EF supports querying related data
|
||||||
|
decimal total = 0;
|
||||||
|
foreach (var item in _db.CartItems.Where(c => c.CartId == ShoppingCartId))
|
||||||
|
{
|
||||||
|
var album = _db.Albums.Single(a => a.AlbumId == item.AlbumId);
|
||||||
|
total += item.Count * album.Price;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CreateOrder(Order order)
|
||||||
|
{
|
||||||
|
decimal orderTotal = 0;
|
||||||
|
|
||||||
|
var cartItems = GetCartItems();
|
||||||
|
|
||||||
|
// TODO [EF] Swap to store generated identity key when supported
|
||||||
|
var nextId = _db.OrderDetails.Any()
|
||||||
|
? _db.OrderDetails.Max(o => o.OrderDetailId) + 1
|
||||||
|
: 1;
|
||||||
|
|
||||||
|
// Iterate over the items in the cart, adding the order details for each
|
||||||
|
foreach (var item in cartItems)
|
||||||
|
{
|
||||||
|
//var album = _db.Albums.Find(item.AlbumId);
|
||||||
|
var album = _db.Albums.Single(a => a.AlbumId == item.AlbumId);
|
||||||
|
|
||||||
|
var orderDetail = new OrderDetail
|
||||||
|
{
|
||||||
|
OrderDetailId = nextId,
|
||||||
|
AlbumId = item.AlbumId,
|
||||||
|
OrderId = order.OrderId,
|
||||||
|
UnitPrice = album.Price,
|
||||||
|
Quantity = item.Count,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the order total of the shopping cart
|
||||||
|
orderTotal += (item.Count * album.Price);
|
||||||
|
|
||||||
|
_db.OrderDetails.Add(orderDetail);
|
||||||
|
|
||||||
|
nextId++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the order's total to the orderTotal count
|
||||||
|
order.Total = orderTotal;
|
||||||
|
|
||||||
|
// Empty the shopping cart
|
||||||
|
EmptyCart();
|
||||||
|
|
||||||
|
// Return the OrderId as the confirmation number
|
||||||
|
return order.OrderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're using HttpContextBase to allow access to cookies.
|
||||||
|
public string GetCartId(HttpContext context)
|
||||||
|
{
|
||||||
|
var sessionCookie = context.Request.Cookies["Session"];
|
||||||
|
string cartId = null;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(sessionCookie))
|
||||||
|
{
|
||||||
|
//A GUID to hold the cartId.
|
||||||
|
cartId = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
// Send cart Id as a cookie to the client.
|
||||||
|
context.Response.Cookies.Append("Session", cartId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cartId = sessionCookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cartId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
samples/react/MusicStore/Controllers/HomeController.cs
Executable file
16
samples/react/MusicStore/Controllers/HomeController.cs
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Mvc;
|
||||||
|
|
||||||
|
namespace MusicStore.Controllers
|
||||||
|
{
|
||||||
|
public class HomeController : Controller
|
||||||
|
{
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
samples/react/MusicStore/Infrastructure/NoCacheAttribute.cs
Normal file
19
samples/react/MusicStore/Infrastructure/NoCacheAttribute.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Microsoft.AspNet.Mvc;
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNet.Mvc.Filters;
|
||||||
|
|
||||||
|
namespace MusicStore.Infrastructure
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||||
|
public sealed class NoCacheAttribute : ActionFilterAttribute
|
||||||
|
{
|
||||||
|
public override void OnResultExecuting(ResultExecutingContext context)
|
||||||
|
{
|
||||||
|
context.HttpContext.Response.Headers["Cache-Control"] = "no-cache, no-store, max-age=0";
|
||||||
|
context.HttpContext.Response.Headers["Pragma"] = "no-cache";
|
||||||
|
context.HttpContext.Response.Headers["Expires"] = "-1";
|
||||||
|
|
||||||
|
base.OnResultExecuting(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
150
samples/react/MusicStore/Infrastructure/PagedList.cs
Normal file
150
samples/react/MusicStore/Infrastructure/PagedList.cs
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
using Microsoft.Data.Entity;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MusicStore.Infrastructure
|
||||||
|
{
|
||||||
|
public interface IPagedList<T>
|
||||||
|
{
|
||||||
|
IEnumerable<T> Data { get; }
|
||||||
|
|
||||||
|
int Page { get; }
|
||||||
|
|
||||||
|
int PageSize { get; }
|
||||||
|
|
||||||
|
int TotalCount { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class PagedList<T> : IPagedList<T>
|
||||||
|
{
|
||||||
|
public PagedList(IEnumerable<T> data, int page, int pageSize, int totalCount)
|
||||||
|
{
|
||||||
|
Data = data;
|
||||||
|
Page = page;
|
||||||
|
PageSize = pageSize;
|
||||||
|
TotalCount = totalCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<T> Data { get; private set; }
|
||||||
|
|
||||||
|
public int Page { get; private set; }
|
||||||
|
|
||||||
|
public int PageSize { get; private set; }
|
||||||
|
|
||||||
|
public int TotalCount { get; private set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PagedListExtensions
|
||||||
|
{
|
||||||
|
public static IPagedList<T> ToPagedList<T>(this IQueryable<T> query, int page, int pageSize)
|
||||||
|
{
|
||||||
|
if (query == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("query");
|
||||||
|
}
|
||||||
|
|
||||||
|
var pagingConfig = new PagingConfig(page, pageSize);
|
||||||
|
var skipCount = ValidatePagePropertiesAndGetSkipCount(pagingConfig);
|
||||||
|
|
||||||
|
var data = query
|
||||||
|
.Skip(skipCount)
|
||||||
|
.Take(pagingConfig.PageSize)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (skipCount > 0 && data.Count == 0)
|
||||||
|
{
|
||||||
|
// Requested page has no records, just return the first page
|
||||||
|
pagingConfig.Page = 1;
|
||||||
|
data = query
|
||||||
|
.Take(pagingConfig.PageSize)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PagedList<T>(data, pagingConfig.Page, pagingConfig.PageSize, query.Count());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Task<IPagedList<TModel>> ToPagedListAsync<TModel, TProperty>(this IQueryable<TModel> query, int page, int pageSize, string sortExpression, Expression<Func<TModel, TProperty>> defaultSortExpression, SortDirection defaultSortDirection = SortDirection.Ascending)
|
||||||
|
where TModel : class
|
||||||
|
{
|
||||||
|
return ToPagedListAsync<TModel, TProperty, TModel>(query, page, pageSize, sortExpression, defaultSortExpression, defaultSortDirection, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<IPagedList<TResult>> ToPagedListAsync<TModel, TProperty, TResult>(this IQueryable<TModel> query, int page, int pageSize, string sortExpression, Expression<Func<TModel, TProperty>> defaultSortExpression, SortDirection defaultSortDirection, Func<TModel, TResult> selector)
|
||||||
|
where TModel : class
|
||||||
|
where TResult : class
|
||||||
|
{
|
||||||
|
if (query == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("query");
|
||||||
|
}
|
||||||
|
|
||||||
|
var pagingConfig = new PagingConfig(page, pageSize);
|
||||||
|
var skipCount = ValidatePagePropertiesAndGetSkipCount(pagingConfig);
|
||||||
|
var dataQuery = query;
|
||||||
|
|
||||||
|
if (defaultSortExpression != null)
|
||||||
|
{
|
||||||
|
dataQuery = dataQuery
|
||||||
|
.SortBy(sortExpression, defaultSortExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = await dataQuery
|
||||||
|
.Skip(skipCount)
|
||||||
|
.Take(pagingConfig.PageSize)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
if (skipCount > 0 && data.Count == 0)
|
||||||
|
{
|
||||||
|
// Requested page has no records, just return the first page
|
||||||
|
pagingConfig.Page = 1;
|
||||||
|
data = await dataQuery
|
||||||
|
.Take(pagingConfig.PageSize)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
var count = await query.CountAsync();
|
||||||
|
|
||||||
|
var resultData = selector != null
|
||||||
|
? data.Select(selector)
|
||||||
|
: data.Cast<TResult>();
|
||||||
|
|
||||||
|
return new PagedList<TResult>(resultData, pagingConfig.Page, pagingConfig.PageSize, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int ValidatePagePropertiesAndGetSkipCount(PagingConfig pagingConfig)
|
||||||
|
{
|
||||||
|
if (pagingConfig.Page < 1)
|
||||||
|
{
|
||||||
|
pagingConfig.Page = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pagingConfig.PageSize < 10)
|
||||||
|
{
|
||||||
|
pagingConfig.PageSize = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pagingConfig.PageSize > 100)
|
||||||
|
{
|
||||||
|
pagingConfig.PageSize = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pagingConfig.PageSize * (pagingConfig.Page - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class PagingConfig
|
||||||
|
{
|
||||||
|
public PagingConfig(int page, int pageSize)
|
||||||
|
{
|
||||||
|
Page = page;
|
||||||
|
PageSize = pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Page { get; set; }
|
||||||
|
|
||||||
|
public int PageSize { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
samples/react/MusicStore/Infrastructure/SortDirection.cs
Normal file
13
samples/react/MusicStore/Infrastructure/SortDirection.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MusicStore.Infrastructure
|
||||||
|
{
|
||||||
|
public enum SortDirection
|
||||||
|
{
|
||||||
|
Ascending,
|
||||||
|
Descending
|
||||||
|
}
|
||||||
|
}
|
||||||
87
samples/react/MusicStore/Infrastructure/SortExpression.cs
Normal file
87
samples/react/MusicStore/Infrastructure/SortExpression.cs
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Mvc.ViewFeatures;
|
||||||
|
|
||||||
|
namespace MusicStore.Infrastructure
|
||||||
|
{
|
||||||
|
public static class SortExpression
|
||||||
|
{
|
||||||
|
private const string SORT_DIRECTION_DESC = " DESC";
|
||||||
|
|
||||||
|
public static IQueryable<TModel> SortBy<TModel, TProperty>(this IQueryable<TModel> query, string sortExpression, Expression<Func<TModel, TProperty>> defaultSortExpression, SortDirection defaultSortDirection = SortDirection.Ascending) where TModel : class
|
||||||
|
{
|
||||||
|
return SortBy(query, sortExpression ?? Create(defaultSortExpression, defaultSortDirection));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Create<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression, SortDirection sortDirection = SortDirection.Ascending) where TModel : class
|
||||||
|
{
|
||||||
|
var expressionText = ExpressionHelper.GetExpressionText(expression);
|
||||||
|
// TODO: Validate the expression depth, etc.
|
||||||
|
|
||||||
|
var sortExpression = expressionText;
|
||||||
|
|
||||||
|
if (sortDirection == SortDirection.Descending)
|
||||||
|
{
|
||||||
|
sortExpression += SORT_DIRECTION_DESC;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sortExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IQueryable<T> SortBy<T>(this IQueryable<T> source, string sortExpression) where T : class
|
||||||
|
{
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("source");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (String.IsNullOrWhiteSpace(sortExpression))
|
||||||
|
{
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
sortExpression = sortExpression.Trim();
|
||||||
|
var isDescending = false;
|
||||||
|
|
||||||
|
// DataSource control passes the sort parameter with a direction
|
||||||
|
// if the direction is descending
|
||||||
|
if (sortExpression.EndsWith(SORT_DIRECTION_DESC, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
isDescending = true;
|
||||||
|
var descIndex = sortExpression.Length - SORT_DIRECTION_DESC.Length;
|
||||||
|
sortExpression = sortExpression.Substring(0, descIndex).Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(sortExpression))
|
||||||
|
{
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParameterExpression parameter = Expression.Parameter(source.ElementType, String.Empty);
|
||||||
|
|
||||||
|
// Build up the property expression, e.g.: (m => m.Foo.Bar)
|
||||||
|
var sortExpressionParts = sortExpression.Split('.');
|
||||||
|
Expression propertyExpression = parameter;
|
||||||
|
foreach (var property in sortExpressionParts)
|
||||||
|
{
|
||||||
|
propertyExpression = Expression.Property(propertyExpression, property);
|
||||||
|
}
|
||||||
|
|
||||||
|
LambdaExpression lambda = Expression.Lambda(propertyExpression, parameter);
|
||||||
|
|
||||||
|
var methodName = (isDescending) ? "OrderByDescending" : "OrderBy";
|
||||||
|
|
||||||
|
Expression methodCallExpression = Expression.Call(
|
||||||
|
typeof(Queryable),
|
||||||
|
methodName,
|
||||||
|
new[] { source.ElementType, propertyExpression.Type },
|
||||||
|
source.Expression,
|
||||||
|
Expression.Quote(lambda));
|
||||||
|
|
||||||
|
return (IQueryable<T>)source.Provider.CreateQuery(methodCallExpression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
62
samples/react/MusicStore/ReactApp/TypedRedux.ts
Normal file
62
samples/react/MusicStore/ReactApp/TypedRedux.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
// Credits for the type detection trick: http://www.bluewire-technologies.com/2015/redux-actions-for-typescript/
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Dispatch } from 'redux';
|
||||||
|
import { connect as nativeConnect, ElementClass } from 'react-redux';
|
||||||
|
|
||||||
|
interface ActionClass<T extends Action> {
|
||||||
|
prototype: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function typeName(name: string) {
|
||||||
|
return function<T extends Action>(actionClass: ActionClass<T>) {
|
||||||
|
// Although we could determine the type name using actionClass.prototype.constructor.name,
|
||||||
|
// it's dangerous to do that because minifiers may interfere with it, and then serialized state
|
||||||
|
// might not have the expected meaning after a recompile. So we explicitly ask for a name string.
|
||||||
|
actionClass.prototype.type = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isActionType<T extends Action>(action: Action, actionClass: ActionClass<T>): action is T {
|
||||||
|
return action.type == actionClass.prototype.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
export abstract class Action {
|
||||||
|
type: string;
|
||||||
|
constructor() {
|
||||||
|
// Make it an own-property (not a prototype property) so that it's included when JSON-serializing
|
||||||
|
this.type = this.type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Reducer<TState> extends Function {
|
||||||
|
(state: TState, action: Action): TState;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ActionCreatorGeneric<TState> extends Function {
|
||||||
|
(dispatch: Dispatch, getState: () => TState): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ClassDecoratorWithProps<TProps> extends Function {
|
||||||
|
<T extends (typeof ElementClass)>(component: T): T;
|
||||||
|
props: TProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReactComponentClass<T, S> = new(props: T) => React.Component<T, S>;
|
||||||
|
class ComponentBuilder<TOwnProps, TActions, TExternalProps> {
|
||||||
|
constructor(private stateToProps: (appState: any) => TOwnProps, private actionCreators: TActions) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public withExternalProps<TAddExternalProps>() {
|
||||||
|
return this as any as ComponentBuilder<TOwnProps, TActions, TAddExternalProps>;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get allProps(): TOwnProps & TActions & TExternalProps { return null; }
|
||||||
|
|
||||||
|
public connect<TState>(componentClass: ReactComponentClass<TOwnProps & TActions & TExternalProps, TState>): ReactComponentClass<TExternalProps, TState> {
|
||||||
|
return nativeConnect(this.stateToProps, this.actionCreators as any)(componentClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function provide<TOwnProps, TActions>(stateToProps: (appState: any) => TOwnProps, actionCreators: TActions) {
|
||||||
|
return new ComponentBuilder<TOwnProps, TActions, {}>(stateToProps, actionCreators);
|
||||||
|
}
|
||||||
19
samples/react/MusicStore/ReactApp/boot.tsx
Normal file
19
samples/react/MusicStore/ReactApp/boot.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import * as ReactDOM from 'react-dom';
|
||||||
|
import { browserHistory } from 'react-router';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
React; // Need this reference otherwise TypeScript doesn't think we're using it and ignores the import
|
||||||
|
|
||||||
|
import './styles/styles.css';
|
||||||
|
import 'bootstrap/dist/css/bootstrap.css';
|
||||||
|
import configureStore from './configureStore';
|
||||||
|
import { App } from './components/App';
|
||||||
|
|
||||||
|
const store = configureStore(browserHistory);
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Provider store={ store }>
|
||||||
|
<App history={ browserHistory } />
|
||||||
|
</Provider>,
|
||||||
|
document.getElementById('react-app')
|
||||||
|
);
|
||||||
37
samples/react/MusicStore/ReactApp/components/App.tsx
Normal file
37
samples/react/MusicStore/ReactApp/components/App.tsx
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Router, Route, HistoryBase } from 'react-router';
|
||||||
|
import NavMenu from './NavMenu';
|
||||||
|
import Home from './public/Home';
|
||||||
|
import Genres from './public/Genres';
|
||||||
|
import GenreDetails from './public/GenreDetails';
|
||||||
|
import AlbumDetails from './public/AlbumDetails';
|
||||||
|
|
||||||
|
export interface AppProps {
|
||||||
|
history: HistoryBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class App extends React.Component<AppProps, void> {
|
||||||
|
public render() {
|
||||||
|
return (
|
||||||
|
<Router history={ this.props.history }>
|
||||||
|
<Route component={ Layout }>
|
||||||
|
<Route path="/" components={{ body: Home }} />
|
||||||
|
<Route path="/genres" components={{ body: Genres }} />
|
||||||
|
<Route path="/genre/:genreId" components={{ body: GenreDetails }} />
|
||||||
|
<Route path="/album/:albumId" components={{ body: AlbumDetails }} />
|
||||||
|
</Route>
|
||||||
|
</Router>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Layout extends React.Component<{ body: React.ReactElement<any> }, void> {
|
||||||
|
public render() {
|
||||||
|
return <div>
|
||||||
|
<NavMenu />
|
||||||
|
<div className="container">
|
||||||
|
{ this.props.body }
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
49
samples/react/MusicStore/ReactApp/components/NavMenu.tsx
Normal file
49
samples/react/MusicStore/ReactApp/components/NavMenu.tsx
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Navbar, Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
|
||||||
|
import { Link } from 'react-router';
|
||||||
|
import { LinkContainer } from 'react-router-bootstrap';
|
||||||
|
import { provide } from '../TypedRedux';
|
||||||
|
import { ApplicationState } from '../store';
|
||||||
|
import * as GenreList from '../store/GenreList';
|
||||||
|
|
||||||
|
class NavMenu extends React.Component<NavMenuProps, void> {
|
||||||
|
componentWillMount() {
|
||||||
|
this.props.requestGenresList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
var genres = this.props.genres.slice(0, 5);
|
||||||
|
return (
|
||||||
|
<Navbar inverse fixedTop>
|
||||||
|
<Navbar.Header>
|
||||||
|
<Navbar.Brand><Link to={ '/' }>Music Store</Link></Navbar.Brand>
|
||||||
|
</Navbar.Header>
|
||||||
|
<Navbar.Collapse>
|
||||||
|
<Nav>
|
||||||
|
<LinkContainer to={ '/' }><NavItem>Home</NavItem></LinkContainer>
|
||||||
|
<NavDropdown id="menu-dropdown" title="Store">
|
||||||
|
{genres.map(genre =>
|
||||||
|
<LinkContainer key={ genre.GenreId } to={ `/genre/${ genre.GenreId }` }>
|
||||||
|
<MenuItem>{ genre.Name }</MenuItem>
|
||||||
|
</LinkContainer>
|
||||||
|
)}
|
||||||
|
<MenuItem divider />
|
||||||
|
<LinkContainer to={ '/genres' }><MenuItem>More…</MenuItem></LinkContainer>
|
||||||
|
</NavDropdown>
|
||||||
|
</Nav>
|
||||||
|
<Nav pullRight>
|
||||||
|
<NavItem href="#">Admin</NavItem>
|
||||||
|
</Nav>
|
||||||
|
</Navbar.Collapse>
|
||||||
|
</Navbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selects which part of global state maps to this component, and defines a type for the resulting props
|
||||||
|
const provider = provide(
|
||||||
|
(state: ApplicationState) => state.genreList,
|
||||||
|
GenreList.actionCreators
|
||||||
|
);
|
||||||
|
type NavMenuProps = typeof provider.allProps;
|
||||||
|
export default provider.connect(NavMenu);
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Link } from 'react-router';
|
||||||
|
import { provide } from '../../TypedRedux';
|
||||||
|
import { ApplicationState } from '../../store';
|
||||||
|
import * as AlbumDetailsState from '../../store/AlbumDetails';
|
||||||
|
|
||||||
|
interface RouteParams {
|
||||||
|
albumId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AlbumDetails extends React.Component<AlbumDetailsProps, void> {
|
||||||
|
componentWillMount() {
|
||||||
|
this.props.requestAlbumDetails(this.props.params.albumId);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps: AlbumDetailsProps) {
|
||||||
|
if (nextProps.params.albumId !== this.props.params.albumId) {
|
||||||
|
nextProps.requestAlbumDetails(nextProps.params.albumId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
if (this.props.isLoaded) {
|
||||||
|
const albumData = this.props.album;
|
||||||
|
return <div>
|
||||||
|
<h2>{ albumData.Title }</h2>
|
||||||
|
|
||||||
|
<p><img alt={ albumData.Title } src={ albumData.AlbumArtUrl } /></p>
|
||||||
|
|
||||||
|
<div id="album-details">
|
||||||
|
<p>
|
||||||
|
<em>Genre:</em>
|
||||||
|
{ albumData.Genre.Name }
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<em>Artist:</em>
|
||||||
|
{ albumData.Artist.Name }
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<em>Price:</em>
|
||||||
|
${ albumData.Price.toFixed(2) }
|
||||||
|
</p>
|
||||||
|
<p className="button">
|
||||||
|
Add to cart
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
} else {
|
||||||
|
return <p>Loading...</p>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selects which part of global state maps to this component, and defines a type for the resulting props
|
||||||
|
const provider = provide(
|
||||||
|
(state: ApplicationState) => state.albumDetails,
|
||||||
|
AlbumDetailsState.actionCreators
|
||||||
|
).withExternalProps<{ params: RouteParams }>();
|
||||||
|
type AlbumDetailsProps = typeof provider.allProps;
|
||||||
|
export default provider.connect(AlbumDetails);
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Link } from 'react-router';
|
||||||
|
import { Album } from '../../store/FeaturedAlbums';
|
||||||
|
|
||||||
|
export class AlbumTile extends React.Component<{ album: Album, key?: any }, void> {
|
||||||
|
public render() {
|
||||||
|
const { album } = this.props;
|
||||||
|
return (
|
||||||
|
<li className="col-lg-2 col-md-2 col-sm-2 col-xs-4 container">
|
||||||
|
<Link to={ '/album/' + album.AlbumId }>
|
||||||
|
<img alt={ album.Title } src={ album.AlbumArtUrl } />
|
||||||
|
<h4>{ album.Title }</h4>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Link } from 'react-router';
|
||||||
|
import { provide } from '../../TypedRedux';
|
||||||
|
import { ApplicationState } from '../../store';
|
||||||
|
import * as GenreDetailsStore from '../../store/GenreDetails';
|
||||||
|
import { AlbumTile } from './AlbumTile';
|
||||||
|
|
||||||
|
interface RouteParams {
|
||||||
|
genreId: number
|
||||||
|
}
|
||||||
|
|
||||||
|
class GenreDetails extends React.Component<GenreDetailsProps, void> {
|
||||||
|
componentWillMount() {
|
||||||
|
this.props.requestGenreDetails(this.props.params.genreId);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps: GenreDetailsProps) {
|
||||||
|
if (nextProps.params.genreId !== this.props.params.genreId) {
|
||||||
|
nextProps.requestGenreDetails(nextProps.params.genreId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
if (this.props.isLoaded) {
|
||||||
|
let albums = this.props.albums;
|
||||||
|
return <div>
|
||||||
|
<h3>Albums</h3>
|
||||||
|
|
||||||
|
<ul className="list-unstyled">
|
||||||
|
{albums.map(album =>
|
||||||
|
<AlbumTile key={ album.AlbumId } album={ album } />
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</div>;
|
||||||
|
} else {
|
||||||
|
return <p>Loading...</p>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selects which part of global state maps to this component, and defines a type for the resulting props
|
||||||
|
const provider = provide(
|
||||||
|
(state: ApplicationState) => state.genreDetails,
|
||||||
|
GenreDetailsStore.actionCreators
|
||||||
|
).withExternalProps<{ params: RouteParams }>();
|
||||||
|
|
||||||
|
type GenreDetailsProps = typeof provider.allProps;
|
||||||
|
export default provider.connect(GenreDetails);
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Link } from 'react-router';
|
||||||
|
import { provide } from '../../TypedRedux';
|
||||||
|
import { ApplicationState } from '../../store';
|
||||||
|
import * as GenreList from '../../store/GenreList';
|
||||||
|
|
||||||
|
class Genres extends React.Component<GenresProps, void> {
|
||||||
|
componentWillMount() {
|
||||||
|
if (!this.props.genres.length) {
|
||||||
|
this.props.requestGenresList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
let { genres } = this.props;
|
||||||
|
|
||||||
|
return <div>
|
||||||
|
<h3>Browse Genres</h3>
|
||||||
|
|
||||||
|
<p>Select from { genres.length || '...' } genres:</p>
|
||||||
|
|
||||||
|
<ul className="list-group">
|
||||||
|
{genres.map(genre =>
|
||||||
|
<li key={ genre.GenreId } className="list-group-item">
|
||||||
|
<Link to={ '/genre/' + genre.GenreId }>
|
||||||
|
{ genre.Name }
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selects which part of global state maps to this component, and defines a type for the resulting props
|
||||||
|
const provider = provide(
|
||||||
|
(state: ApplicationState) => state.genreList,
|
||||||
|
GenreList.actionCreators
|
||||||
|
);
|
||||||
|
type GenresProps = typeof provider.allProps;
|
||||||
|
export default provider.connect(Genres);
|
||||||
37
samples/react/MusicStore/ReactApp/components/public/Home.tsx
Normal file
37
samples/react/MusicStore/ReactApp/components/public/Home.tsx
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Link } from 'react-router';
|
||||||
|
import { provide } from '../../TypedRedux';
|
||||||
|
import { ApplicationState } from '../../store';
|
||||||
|
import { actionCreators } from '../../store/FeaturedAlbums';
|
||||||
|
import { AlbumTile } from './AlbumTile';
|
||||||
|
|
||||||
|
class Home extends React.Component<HomeProps, void> {
|
||||||
|
componentWillMount() {
|
||||||
|
if (!this.props.albums.length) {
|
||||||
|
this.props.requestFeaturedAlbums();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
let { albums } = this.props;
|
||||||
|
return <div>
|
||||||
|
<div className="jumbotron">
|
||||||
|
<h1>MVC Music Store</h1>
|
||||||
|
<img src="/Images/home-showcase.png" />
|
||||||
|
</div>
|
||||||
|
<ul className="row list-unstyled" id="album-list">
|
||||||
|
{albums.map(album =>
|
||||||
|
<AlbumTile key={ album.AlbumId } album={ album } />
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selects which part of global state maps to this component, and defines a type for the resulting props
|
||||||
|
const provider = provide(
|
||||||
|
(state: ApplicationState) => state.featuredAlbums,
|
||||||
|
actionCreators
|
||||||
|
);
|
||||||
|
type HomeProps = typeof provider.allProps;
|
||||||
|
export default provider.connect(Home);
|
||||||
39
samples/react/MusicStore/ReactApp/configureStore.ts
Normal file
39
samples/react/MusicStore/ReactApp/configureStore.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
|
||||||
|
import * as thunkModule from 'redux-thunk';
|
||||||
|
import { syncHistory, routeReducer } from 'react-router-redux';
|
||||||
|
import * as Store from './store';
|
||||||
|
|
||||||
|
export default function configureStore(history: HistoryModule.History, initialState?: Store.ApplicationState) {
|
||||||
|
// Build middleware
|
||||||
|
const thunk = (thunkModule as any).default; // Workaround for TypeScript not importing thunk module as expected
|
||||||
|
const reduxRouterMiddleware = syncHistory(history);
|
||||||
|
const middlewares = [thunk, reduxRouterMiddleware];
|
||||||
|
const devToolsExtension = (window as any).devToolsExtension; // If devTools is installed, connect to it
|
||||||
|
|
||||||
|
const finalCreateStore = compose(
|
||||||
|
applyMiddleware(...middlewares),
|
||||||
|
devToolsExtension ? devToolsExtension() : f => f
|
||||||
|
)(createStore)
|
||||||
|
|
||||||
|
// Combine all reducers
|
||||||
|
const allReducers = buildRootReducer(Store.reducers);
|
||||||
|
|
||||||
|
const store = finalCreateStore(allReducers, initialState) as Redux.Store;
|
||||||
|
|
||||||
|
// Required for replaying actions from devtools to work
|
||||||
|
reduxRouterMiddleware.listenForReplays(store);
|
||||||
|
|
||||||
|
// Enable Webpack hot module replacement for reducers
|
||||||
|
if (module.hot) {
|
||||||
|
module.hot.accept('./store', () => {
|
||||||
|
const nextRootReducer = require<typeof Store>('./store');
|
||||||
|
store.replaceReducer(buildRootReducer(nextRootReducer.reducers));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildRootReducer(allReducers) {
|
||||||
|
return combineReducers(Object.assign({}, allReducers, { routing: routeReducer })) as Redux.Reducer;
|
||||||
|
}
|
||||||
3
samples/react/MusicStore/ReactApp/isomorphic-fetch.d.ts
vendored
Normal file
3
samples/react/MusicStore/ReactApp/isomorphic-fetch.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
declare module 'isomorphic-fetch' {
|
||||||
|
export default function fetch(url: string): Promise<any>;
|
||||||
|
}
|
||||||
72
samples/react/MusicStore/ReactApp/store/AlbumDetails.ts
Normal file
72
samples/react/MusicStore/ReactApp/store/AlbumDetails.ts
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import fetch from 'isomorphic-fetch';
|
||||||
|
import { typeName, isActionType, Action, Reducer } from '../TypedRedux';
|
||||||
|
import { ActionCreator } from './';
|
||||||
|
import { Genre } from './GenreList';
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// STATE - This defines the type of data maintained in the Redux store.
|
||||||
|
|
||||||
|
export interface AlbumDetailsState {
|
||||||
|
isLoaded: boolean;
|
||||||
|
album: AlbumDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AlbumDetails {
|
||||||
|
AlbumId: string;
|
||||||
|
Title: string;
|
||||||
|
AlbumArtUrl: string;
|
||||||
|
Genre: Genre;
|
||||||
|
Artist: Artist;
|
||||||
|
Price: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Artist {
|
||||||
|
Name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// ACTIONS - These are serializable (hence replayable) descriptions of state transitions.
|
||||||
|
// They do not themselves have any side-effects; they just describe something that is going to happen.
|
||||||
|
// Use @typeName and isActionType for type detection that works even after serialization/deserialization.
|
||||||
|
|
||||||
|
@typeName("REQUEST_ALBUM_DETAILS")
|
||||||
|
class RequestAlbumDetails extends Action {
|
||||||
|
constructor(public albumId: number) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@typeName("RECEIVE_ALBUM_DETAILS")
|
||||||
|
class ReceiveAlbumDetails extends Action {
|
||||||
|
constructor(public album: AlbumDetails) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------
|
||||||
|
// ACTION CREATORS - These are functions exposed to UI components that will trigger a state transition.
|
||||||
|
// They don't directly mutate state, but they can have external side-effects (such as loading data).
|
||||||
|
|
||||||
|
export const actionCreators = {
|
||||||
|
requestAlbumDetails: (albumId: number): ActionCreator => (dispatch, getState) => {
|
||||||
|
fetch(`/api/albums/${ albumId }`)
|
||||||
|
.then(results => results.json())
|
||||||
|
.then(album => dispatch(new ReceiveAlbumDetails(album)));
|
||||||
|
|
||||||
|
dispatch(new RequestAlbumDetails(albumId));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------
|
||||||
|
// REDUCER - For a given state and action, returns the new state. To support time travel, this must not mutate the old state.
|
||||||
|
// For unrecognized actions, must return the existing state (or default initial state if none was supplied).
|
||||||
|
const unloadedState: AlbumDetailsState = { isLoaded: false, album: null };
|
||||||
|
export const reducer: Reducer<AlbumDetailsState> = (state, action) => {
|
||||||
|
if (isActionType(action, RequestAlbumDetails)) {
|
||||||
|
return unloadedState;
|
||||||
|
} else if (isActionType(action, ReceiveAlbumDetails)) {
|
||||||
|
return { isLoaded: true, album: action.album };
|
||||||
|
} else {
|
||||||
|
return state || unloadedState;
|
||||||
|
}
|
||||||
|
};
|
||||||
58
samples/react/MusicStore/ReactApp/store/FeaturedAlbums.ts
Normal file
58
samples/react/MusicStore/ReactApp/store/FeaturedAlbums.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import fetch from 'isomorphic-fetch';
|
||||||
|
import { typeName, isActionType, Action, Reducer } from '../TypedRedux';
|
||||||
|
import { ActionCreator } from './';
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// STATE - This defines the type of data maintained in the Redux store.
|
||||||
|
|
||||||
|
export interface FeaturedAlbumsState {
|
||||||
|
albums: Album[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Album {
|
||||||
|
AlbumId: number;
|
||||||
|
Title: string;
|
||||||
|
AlbumArtUrl: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// ACTIONS - These are serializable (hence replayable) descriptions of state transitions.
|
||||||
|
// They do not themselves have any side-effects; they just describe something that is going to happen.
|
||||||
|
// Use @typeName and isActionType for type detection that works even after serialization/deserialization.
|
||||||
|
|
||||||
|
@typeName("REQUEST_FEATURED_ALBUMS")
|
||||||
|
class RequestFeaturedAlbums extends Action {
|
||||||
|
}
|
||||||
|
|
||||||
|
@typeName("RECEIVE_FEATURED_ALBUMS")
|
||||||
|
class ReceiveFeaturedAlbums extends Action {
|
||||||
|
constructor(public albums: Album[]) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------
|
||||||
|
// ACTION CREATORS - These are functions exposed to UI components that will trigger a state transition.
|
||||||
|
// They don't directly mutate state, but they can have external side-effects (such as loading data).
|
||||||
|
|
||||||
|
export const actionCreators = {
|
||||||
|
requestFeaturedAlbums: (): ActionCreator => (dispatch, getState) => {
|
||||||
|
fetch('/api/albums/mostPopular')
|
||||||
|
.then(results => results.json())
|
||||||
|
.then(albums => dispatch(new ReceiveFeaturedAlbums(albums)));
|
||||||
|
|
||||||
|
return dispatch(new RequestFeaturedAlbums());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------
|
||||||
|
// REDUCER - For a given state and action, returns the new state. To support time travel, this must not mutate the old state.
|
||||||
|
// For unrecognized actions, must return the existing state (or default initial state if none was supplied).
|
||||||
|
|
||||||
|
export const reducer: Reducer<FeaturedAlbumsState> = (state, action) => {
|
||||||
|
if (isActionType(action, ReceiveFeaturedAlbums)) {
|
||||||
|
return { albums: action.albums };
|
||||||
|
} else {
|
||||||
|
return state || { albums: [] };
|
||||||
|
}
|
||||||
|
};
|
||||||
59
samples/react/MusicStore/ReactApp/store/GenreDetails.ts
Normal file
59
samples/react/MusicStore/ReactApp/store/GenreDetails.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import fetch from 'isomorphic-fetch';
|
||||||
|
import { typeName, isActionType, Action, Reducer } from '../TypedRedux';
|
||||||
|
import { ActionCreator } from './';
|
||||||
|
import { Album } from './FeaturedAlbums';
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// STATE - This defines the type of data maintained in the Redux store.
|
||||||
|
|
||||||
|
export interface GenreDetailsState {
|
||||||
|
isLoaded: boolean;
|
||||||
|
albums: Album[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// ACTIONS - These are serializable (hence replayable) descriptions of state transitions.
|
||||||
|
// They do not themselves have any side-effects; they just describe something that is going to happen.
|
||||||
|
// Use @typeName and isActionType for type detection that works even after serialization/deserialization.
|
||||||
|
|
||||||
|
@typeName("REQUEST_GENRE_DETAILS")
|
||||||
|
class RequestGenreDetails extends Action {
|
||||||
|
constructor(public genreId: number) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@typeName("RECEIVE_GENRE_DETAILS")
|
||||||
|
class ReceiveGenreDetails extends Action {
|
||||||
|
constructor(public albums: Album[]) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------
|
||||||
|
// ACTION CREATORS - These are functions exposed to UI components that will trigger a state transition.
|
||||||
|
// They don't directly mutate state, but they can have external side-effects (such as loading data).
|
||||||
|
|
||||||
|
export const actionCreators = {
|
||||||
|
requestGenreDetails: (genreId: number): ActionCreator => (dispatch, getState) => {
|
||||||
|
fetch(`/api/genres/${ genreId }/albums`)
|
||||||
|
.then(results => results.json())
|
||||||
|
.then(albums => dispatch(new ReceiveGenreDetails(albums)));
|
||||||
|
|
||||||
|
dispatch(new RequestGenreDetails(genreId));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------
|
||||||
|
// REDUCER - For a given state and action, returns the new state. To support time travel, this must not mutate the old state.
|
||||||
|
// For unrecognized actions, must return the existing state (or default initial state if none was supplied).
|
||||||
|
const unloadedState: GenreDetailsState = { isLoaded: false, albums: [] };
|
||||||
|
export const reducer: Reducer<GenreDetailsState> = (state, action) => {
|
||||||
|
if (isActionType(action, RequestGenreDetails)) {
|
||||||
|
return unloadedState;
|
||||||
|
} else if (isActionType(action, ReceiveGenreDetails)) {
|
||||||
|
return { isLoaded: true, albums: action.albums };
|
||||||
|
} else {
|
||||||
|
return state || unloadedState;
|
||||||
|
}
|
||||||
|
};
|
||||||
51
samples/react/MusicStore/ReactApp/store/GenreList.ts
Normal file
51
samples/react/MusicStore/ReactApp/store/GenreList.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import fetch from 'isomorphic-fetch';
|
||||||
|
import { typeName, isActionType, Action, Reducer } from '../TypedRedux';
|
||||||
|
import { ActionCreator } from './';
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// STATE - This defines the type of data maintained in the Redux store.
|
||||||
|
|
||||||
|
export interface GenresListState {
|
||||||
|
genres: Genre[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Genre {
|
||||||
|
GenreId: string;
|
||||||
|
Name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// ACTIONS - These are serializable (hence replayable) descriptions of state transitions.
|
||||||
|
// They do not themselves have any side-effects; they just describe something that is going to happen.
|
||||||
|
// Use @typeName and isActionType for type detection that works even after serialization/deserialization.
|
||||||
|
|
||||||
|
@typeName("RECEIVE_GENRES_LIST")
|
||||||
|
class ReceiveGenresList extends Action {
|
||||||
|
constructor(public genres: Genre[]) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------
|
||||||
|
// ACTION CREATORS - These are functions exposed to UI components that will trigger a state transition.
|
||||||
|
// They don't directly mutate state, but they can have external side-effects (such as loading data).
|
||||||
|
|
||||||
|
export const actionCreators = {
|
||||||
|
requestGenresList: (): ActionCreator => (dispatch, getState) => {
|
||||||
|
fetch('/api/genres')
|
||||||
|
.then(results => results.json())
|
||||||
|
.then(genres => dispatch(new ReceiveGenresList(genres)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------
|
||||||
|
// REDUCER - For a given state and action, returns the new state. To support time travel, this must not mutate the old state.
|
||||||
|
// For unrecognized actions, must return the existing state (or default initial state if none was supplied).
|
||||||
|
|
||||||
|
export const reducer: Reducer<GenresListState> = (state, action) => {
|
||||||
|
if (isActionType(action, ReceiveGenresList)) {
|
||||||
|
return { genres: action.genres };
|
||||||
|
} else {
|
||||||
|
return state || { genres: [] };
|
||||||
|
}
|
||||||
|
};
|
||||||
27
samples/react/MusicStore/ReactApp/store/index.ts
Normal file
27
samples/react/MusicStore/ReactApp/store/index.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { ActionCreatorGeneric } from '../TypedRedux';
|
||||||
|
import * as FeaturedAlbums from './FeaturedAlbums';
|
||||||
|
import * as GenreList from './GenreList';
|
||||||
|
import * as GenreDetails from './GenreDetails';
|
||||||
|
import * as AlbumDetails from './AlbumDetails';
|
||||||
|
|
||||||
|
// The top-level state object
|
||||||
|
export interface ApplicationState {
|
||||||
|
featuredAlbums: FeaturedAlbums.FeaturedAlbumsState;
|
||||||
|
genreList: GenreList.GenresListState,
|
||||||
|
genreDetails: GenreDetails.GenreDetailsState,
|
||||||
|
albumDetails: AlbumDetails.AlbumDetailsState
|
||||||
|
}
|
||||||
|
|
||||||
|
// Whenever an action is dispatched, Redux will update each top-level application state property using
|
||||||
|
// the reducer with the matching name. It's important that the names match exactly, and that the reducer
|
||||||
|
// acts on the corresponding ApplicationState property type.
|
||||||
|
export const reducers = {
|
||||||
|
featuredAlbums: FeaturedAlbums.reducer,
|
||||||
|
genreList: GenreList.reducer,
|
||||||
|
genreDetails: GenreDetails.reducer,
|
||||||
|
albumDetails: AlbumDetails.reducer
|
||||||
|
};
|
||||||
|
|
||||||
|
// This type can be used as a hint on action creators so that its 'dispatch' and 'getState' params are
|
||||||
|
// correctly typed to match your store.
|
||||||
|
export type ActionCreator = ActionCreatorGeneric<ApplicationState>;
|
||||||
3
samples/react/MusicStore/ReactApp/styles/styles.css
Normal file
3
samples/react/MusicStore/ReactApp/styles/styles.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
body {
|
||||||
|
padding-top: 50px;
|
||||||
|
}
|
||||||
13
samples/react/MusicStore/SiteSettings.cs
Normal file
13
samples/react/MusicStore/SiteSettings.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MusicStore
|
||||||
|
{
|
||||||
|
public class SiteSettings
|
||||||
|
{
|
||||||
|
public string DefaultAdminUsername { get; set; }
|
||||||
|
public string DefaultAdminPassword { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
122
samples/react/MusicStore/Startup.cs
Executable file
122
samples/react/MusicStore/Startup.cs
Executable file
@@ -0,0 +1,122 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AutoMapper;
|
||||||
|
using Microsoft.AspNet.Authorization;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.AspNet.Hosting;
|
||||||
|
using Microsoft.AspNet.Identity.EntityFramework;
|
||||||
|
using Microsoft.AspNet.SpaServices;
|
||||||
|
using Microsoft.Data.Entity;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using MusicStore.Apis;
|
||||||
|
using MusicStore.Models;
|
||||||
|
|
||||||
|
namespace MusicStore
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public Startup(IHostingEnvironment env)
|
||||||
|
{
|
||||||
|
// Set up configuration sources.
|
||||||
|
var builder = new ConfigurationBuilder()
|
||||||
|
.AddJsonFile("appsettings.json")
|
||||||
|
.AddEnvironmentVariables();
|
||||||
|
Configuration = builder.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IConfigurationRoot Configuration { get; set; }
|
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to add services to the container.
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.Configure<SiteSettings>(settings =>
|
||||||
|
{
|
||||||
|
settings.DefaultAdminUsername = Configuration["DefaultAdminUsername"];
|
||||||
|
settings.DefaultAdminPassword = Configuration["DefaultAdminPassword"];
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add MVC services to the services container.
|
||||||
|
services.AddMvc();
|
||||||
|
|
||||||
|
// Uncomment the following line to add Web API services which makes it easier to port Web API 2 controllers.
|
||||||
|
// You will also need to add the Microsoft.AspNet.Mvc.WebApiCompatShim package to the 'dependencies' section of project.json.
|
||||||
|
// services.AddWebApiConventions();
|
||||||
|
|
||||||
|
// Add EF services to the service container
|
||||||
|
services.AddEntityFramework()
|
||||||
|
.AddSqlite()
|
||||||
|
.AddDbContext<MusicStoreContext>(options => {
|
||||||
|
options.UseSqlite(Configuration["DbConnectionString"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add Identity services to the services container
|
||||||
|
services.AddIdentity<ApplicationUser, IdentityRole>()
|
||||||
|
.AddEntityFrameworkStores<MusicStoreContext>()
|
||||||
|
.AddDefaultTokenProviders();
|
||||||
|
|
||||||
|
// Uncomment the following line to add Web API services which makes it easier to port Web API 2 controllers.
|
||||||
|
// You will also need to add the Microsoft.AspNet.Mvc.WebApiCompatShim package to the 'dependencies' section of project.json.
|
||||||
|
// services.AddWebApiConventions();
|
||||||
|
|
||||||
|
// Configure Auth
|
||||||
|
services.Configure<AuthorizationOptions>(options =>
|
||||||
|
{
|
||||||
|
options.AddPolicy("app-ManageStore", new AuthorizationPolicyBuilder().RequireClaim("app-ManageStore", "Allowed").Build());
|
||||||
|
});
|
||||||
|
|
||||||
|
Mapper.CreateMap<AlbumChangeDto, Album>();
|
||||||
|
Mapper.CreateMap<Album, AlbumChangeDto>();
|
||||||
|
Mapper.CreateMap<Album, AlbumResultDto>();
|
||||||
|
Mapper.CreateMap<AlbumResultDto, Album>();
|
||||||
|
Mapper.CreateMap<Artist, ArtistResultDto>();
|
||||||
|
Mapper.CreateMap<ArtistResultDto, Artist>();
|
||||||
|
Mapper.CreateMap<Genre, GenreResultDto>();
|
||||||
|
Mapper.CreateMap<GenreResultDto, Genre>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||||
|
{
|
||||||
|
loggerFactory.AddConsole(LogLevel.Warning);
|
||||||
|
|
||||||
|
// Initialize the sample data
|
||||||
|
SampleData.InitializeMusicStoreDatabaseAsync(app.ApplicationServices).Wait();
|
||||||
|
|
||||||
|
if (env.IsDevelopment()) {
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
} else {
|
||||||
|
app.UseExceptionHandler("/Home/Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseIISPlatformHandler();
|
||||||
|
|
||||||
|
// In dev mode, the JS/TS/etc is compiled and served dynamically and supports hot replacement.
|
||||||
|
// In production, we assume you've used webpack to emit the prebuilt content to disk.
|
||||||
|
if (env.IsDevelopment()) {
|
||||||
|
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions {
|
||||||
|
HotModuleReplacement = true,
|
||||||
|
ReactHotModuleReplacement = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseStaticFiles();
|
||||||
|
|
||||||
|
app.UseMvc(routes => {
|
||||||
|
routes.MapRoute(
|
||||||
|
name: "default",
|
||||||
|
template: "{controller=Home}/{action=Index}/{id?}");
|
||||||
|
|
||||||
|
routes.MapSpaFallbackRoute(
|
||||||
|
name: "spa-fallback",
|
||||||
|
defaults: new { controller = "Home", action = "Index" });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entry point for the application.
|
||||||
|
public static void Main(string[] args) => Microsoft.AspNet.Hosting.WebApplication.Run<Startup>(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
samples/react/MusicStore/Views/Home/Index.cshtml
Executable file
10
samples/react/MusicStore/Views/Home/Index.cshtml
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "Home Page";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div id="react-app">Loading...</div>
|
||||||
|
|
||||||
|
@section scripts {
|
||||||
|
<script src="/dist/vendor.bundle.js"></script>
|
||||||
|
<script src="/dist/main.js"></script>
|
||||||
|
}
|
||||||
6
samples/react/MusicStore/Views/Shared/Error.cshtml
Executable file
6
samples/react/MusicStore/Views/Shared/Error.cshtml
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "Error";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1 class="text-danger">Error.</h1>
|
||||||
|
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||||
11
samples/react/MusicStore/Views/Shared/_Layout.cshtml
Executable file
11
samples/react/MusicStore/Views/Shared/_Layout.cshtml
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>@ViewData["Title"]</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
@RenderBody()
|
||||||
|
@RenderSection("scripts", required: false)
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
2
samples/react/MusicStore/Views/_ViewImports.cshtml
Executable file
2
samples/react/MusicStore/Views/_ViewImports.cshtml
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
@using MusicStore
|
||||||
|
@addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers"
|
||||||
3
samples/react/MusicStore/Views/_ViewStart.cshtml
Executable file
3
samples/react/MusicStore/Views/_ViewStart.cshtml
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
@{
|
||||||
|
Layout = "_Layout";
|
||||||
|
}
|
||||||
11
samples/react/MusicStore/appsettings.json
Executable file
11
samples/react/MusicStore/appsettings.json
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"DbConnectionString": "Data Source=music-db.sqlite",
|
||||||
|
"Logging": {
|
||||||
|
"IncludeScopes": false,
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Warning",
|
||||||
|
"System": "Information",
|
||||||
|
"Microsoft": "Information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
34
samples/react/MusicStore/package.json
Normal file
34
samples/react/MusicStore/package.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "MusicStore",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-loader": "^6.2.1",
|
||||||
|
"babel-plugin-react-transform": "^2.0.0",
|
||||||
|
"babel-preset-es2015": "^6.3.13",
|
||||||
|
"babel-preset-react": "^6.3.13",
|
||||||
|
"css-loader": "^0.23.1",
|
||||||
|
"express": "^4.13.4",
|
||||||
|
"file-loader": "^0.8.5",
|
||||||
|
"react-transform-hmr": "^1.0.2",
|
||||||
|
"style-loader": "^0.13.0",
|
||||||
|
"ts-loader": "^0.8.0",
|
||||||
|
"typescript": "^1.7.5",
|
||||||
|
"url-loader": "^0.5.7",
|
||||||
|
"webpack": "^1.12.12",
|
||||||
|
"webpack-dev-middleware": "^1.5.1",
|
||||||
|
"webpack-hot-middleware": "^2.6.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"bootstrap": "^3.3.6",
|
||||||
|
"isomorphic-fetch": "^2.2.1",
|
||||||
|
"react": "^0.14.7",
|
||||||
|
"react-bootstrap": "^0.28.2",
|
||||||
|
"react-dom": "^0.14.7",
|
||||||
|
"react-redux": "^4.2.1",
|
||||||
|
"react-router": "^2.0.0-rc5",
|
||||||
|
"react-router-bootstrap": "^0.20.1",
|
||||||
|
"react-router-redux": "^2.1.0",
|
||||||
|
"redux": "^3.2.1",
|
||||||
|
"redux-thunk": "^1.0.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
53
samples/react/MusicStore/project.json
Executable file
53
samples/react/MusicStore/project.json
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
"compilationOptions": {
|
||||||
|
"emitEntryPoint": true
|
||||||
|
},
|
||||||
|
"tooling": {
|
||||||
|
"defaultNamespace": "MusicStore"
|
||||||
|
},
|
||||||
|
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final",
|
||||||
|
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
|
||||||
|
"Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
|
||||||
|
"Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",
|
||||||
|
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
|
||||||
|
"Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
|
||||||
|
"Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final",
|
||||||
|
"Microsoft.Extensions.Configuration.FileProviderExtensions" : "1.0.0-rc1-final",
|
||||||
|
"Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final",
|
||||||
|
"Microsoft.Extensions.Logging": "1.0.0-rc1-final",
|
||||||
|
"Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final",
|
||||||
|
"Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final",
|
||||||
|
"Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-*",
|
||||||
|
"Microsoft.AspNet.ReactServices": "1.0.0-alpha7",
|
||||||
|
"EntityFramework.SQLite": "7.0.0-rc1-*",
|
||||||
|
"AutoMapper": "4.1.1"
|
||||||
|
},
|
||||||
|
|
||||||
|
"commands": {
|
||||||
|
"web": "Microsoft.AspNet.Server.Kestrel"
|
||||||
|
},
|
||||||
|
|
||||||
|
"frameworks": {
|
||||||
|
"dnx451": {},
|
||||||
|
"dnxcore50": {}
|
||||||
|
},
|
||||||
|
|
||||||
|
"exclude": [
|
||||||
|
"wwwroot",
|
||||||
|
"node_modules"
|
||||||
|
],
|
||||||
|
"publishExclude": [
|
||||||
|
"node_modules",
|
||||||
|
"**.xproj",
|
||||||
|
"**.user",
|
||||||
|
"**.vspscc"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"prepublish": [
|
||||||
|
"npm install"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
12
samples/react/MusicStore/tsconfig.json
Normal file
12
samples/react/MusicStore/tsconfig.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"target": "es6",
|
||||||
|
"jsx": "preserve",
|
||||||
|
"sourceMap": true,
|
||||||
|
"experimentalDecorators": true
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
|
}
|
||||||
42
samples/react/MusicStore/tsd.json
Normal file
42
samples/react/MusicStore/tsd.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"version": "v4",
|
||||||
|
"repo": "borisyankov/DefinitelyTyped",
|
||||||
|
"ref": "master",
|
||||||
|
"path": "typings",
|
||||||
|
"bundle": "typings/tsd.d.ts",
|
||||||
|
"installed": {
|
||||||
|
"react/react.d.ts": {
|
||||||
|
"commit": "e69fe60f2d6377ea4fae539493997b098f52cad1"
|
||||||
|
},
|
||||||
|
"react/react-dom.d.ts": {
|
||||||
|
"commit": "86dbea8fc37d9473fee465da4f0a21bea4f8cbd9"
|
||||||
|
},
|
||||||
|
"redux/redux.d.ts": {
|
||||||
|
"commit": "e69fe60f2d6377ea4fae539493997b098f52cad1"
|
||||||
|
},
|
||||||
|
"webpack/webpack-env.d.ts": {
|
||||||
|
"commit": "717a5fdb079f8dd7c19f1b22f7f656dd990f0ccf"
|
||||||
|
},
|
||||||
|
"react-redux/react-redux.d.ts": {
|
||||||
|
"commit": "717a5fdb079f8dd7c19f1b22f7f656dd990f0ccf"
|
||||||
|
},
|
||||||
|
"react-bootstrap/react-bootstrap.d.ts": {
|
||||||
|
"commit": "e69fe60f2d6377ea4fae539493997b098f52cad1"
|
||||||
|
},
|
||||||
|
"react-router/react-router.d.ts": {
|
||||||
|
"commit": "e69fe60f2d6377ea4fae539493997b098f52cad1"
|
||||||
|
},
|
||||||
|
"react-router/history.d.ts": {
|
||||||
|
"commit": "e69fe60f2d6377ea4fae539493997b098f52cad1"
|
||||||
|
},
|
||||||
|
"react-router-bootstrap/react-router-bootstrap.d.ts": {
|
||||||
|
"commit": "e69fe60f2d6377ea4fae539493997b098f52cad1"
|
||||||
|
},
|
||||||
|
"react-router-redux/react-router-redux.d.ts": {
|
||||||
|
"commit": "e69fe60f2d6377ea4fae539493997b098f52cad1"
|
||||||
|
},
|
||||||
|
"redux-thunk/redux-thunk.d.ts": {
|
||||||
|
"commit": "e69fe60f2d6377ea4fae539493997b098f52cad1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
976
samples/react/MusicStore/typings/react-bootstrap/react-bootstrap.d.ts
vendored
Normal file
976
samples/react/MusicStore/typings/react-bootstrap/react-bootstrap.d.ts
vendored
Normal file
@@ -0,0 +1,976 @@
|
|||||||
|
// Type definitions for react-bootstrap
|
||||||
|
// Project: https://github.com/react-bootstrap/react-bootstrap
|
||||||
|
// Definitions by: Walker Burgin <https://github.com/walkerburgin>
|
||||||
|
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||||
|
|
||||||
|
///<reference path="../react/react.d.ts"/>
|
||||||
|
|
||||||
|
declare module "react-bootstrap" {
|
||||||
|
// Import React
|
||||||
|
import React = require("react");
|
||||||
|
|
||||||
|
|
||||||
|
// <Button />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ButtonProps extends React.Props<ButtonClass>{
|
||||||
|
|
||||||
|
// Optional
|
||||||
|
active?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
block?: boolean;
|
||||||
|
bsStyle?: string;
|
||||||
|
bsSize?: string;
|
||||||
|
className?: string;
|
||||||
|
navItem?: boolean;
|
||||||
|
navDropdown?: boolean;
|
||||||
|
componentClass?: string;
|
||||||
|
href?: string;
|
||||||
|
onClick?: Function; // Add more specific type
|
||||||
|
target?: string;
|
||||||
|
type?: string;
|
||||||
|
}
|
||||||
|
interface Button extends React.ReactElement<ButtonProps> { }
|
||||||
|
interface ButtonClass extends React.ComponentClass<ButtonProps> { }
|
||||||
|
var Button: ButtonClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <ButtonToolbar />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ButtonToolbarProps extends React.Props<ButtonToolbarClass> {
|
||||||
|
|
||||||
|
// Optional
|
||||||
|
block?: boolean;
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
justified?: boolean;
|
||||||
|
vertical?: boolean;
|
||||||
|
}
|
||||||
|
interface ButtonToolbar extends React.ReactElement<ButtonToolbarProps> { }
|
||||||
|
interface ButtonToolbarClass extends React.ComponentClass<ButtonToolbarProps> { }
|
||||||
|
var ButtonToolbar: ButtonToolbarClass;
|
||||||
|
|
||||||
|
// <ButtonGroup />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ButtonGroupProps extends React.Props<ButtonGroupClass> {
|
||||||
|
// Optional
|
||||||
|
block?: boolean;
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
justified?: boolean;
|
||||||
|
vertical?: boolean;
|
||||||
|
}
|
||||||
|
interface ButtonGroup extends React.ReactElement<ButtonGroupProps> { }
|
||||||
|
interface ButtonGroupClass extends React.ComponentClass<ButtonGroupProps> { }
|
||||||
|
var ButtonGroup: ButtonGroupClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <DropdownButton />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface DropdownButtonProps extends React.Props<DropdownButtonClass> {
|
||||||
|
bsStyle?: string;
|
||||||
|
bsSize?: string;
|
||||||
|
buttonClassName?: string;
|
||||||
|
className?: string;
|
||||||
|
dropup?: boolean;
|
||||||
|
href?: string;
|
||||||
|
id?: string | number;
|
||||||
|
navItem?: boolean;
|
||||||
|
noCaret?: boolean;
|
||||||
|
onClick?: Function; // TODO: Add more specifc type
|
||||||
|
onSelect?: Function; // TODO: Add more specific type
|
||||||
|
pullRight?: boolean;
|
||||||
|
title?: any; // TODO: Add more specific type
|
||||||
|
}
|
||||||
|
interface DropdownButton extends React.ReactElement<DropdownButtonProps> { }
|
||||||
|
interface DropdownButtonClass extends React.ComponentClass<DropdownButtonProps> { }
|
||||||
|
var DropdownButton: DropdownButtonClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <SplitButton />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface SplitButtonProps extends React.Props<SplitButtonClass>{
|
||||||
|
bsStyle?: string;
|
||||||
|
bsSize?: string;
|
||||||
|
className?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
dropdownTitle?: any; // TODO: Add more specific type
|
||||||
|
dropup?: boolean;
|
||||||
|
href?: string;
|
||||||
|
id?: string;
|
||||||
|
onClick?: Function; // TODO: Add more specific type
|
||||||
|
onSelect?: Function; // TODO: Add more specific type
|
||||||
|
pullRight?: boolean;
|
||||||
|
target?: string;
|
||||||
|
title?: any; // TODO: Add more specific type
|
||||||
|
}
|
||||||
|
interface SplitButton extends React.ReactElement<SplitButtonProps> { }
|
||||||
|
interface SplitButtonClass extends React.ComponentClass<SplitButtonProps> { }
|
||||||
|
var SplitButton: SplitButtonClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <MenuItem />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface MenuItemProps extends React.Props<MenuItemClass> {
|
||||||
|
active?: boolean;
|
||||||
|
className?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
divider?: boolean;
|
||||||
|
eventKey?: any;
|
||||||
|
header?: boolean;
|
||||||
|
href?: string;
|
||||||
|
onClick?: Function;
|
||||||
|
onKeyDown?: Function;
|
||||||
|
onSelect?: Function;
|
||||||
|
target?: string;
|
||||||
|
title?: string;
|
||||||
|
}
|
||||||
|
interface MenuItem extends React.ReactElement<MenuItemProps> { }
|
||||||
|
interface MenuItemClass extends React.ComponentClass<MenuItemProps> { }
|
||||||
|
var MenuItem: MenuItemClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Panel />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface PanelProps extends React.Props<PanelClass> {
|
||||||
|
className?: string;
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
collapsible?: boolean;
|
||||||
|
defaultExpanded?: boolean;
|
||||||
|
eventKey?: any;
|
||||||
|
expanded?: boolean;
|
||||||
|
footer?: any; // TODO: Add more specific type
|
||||||
|
header?: any; // TODO: Add more specific type
|
||||||
|
id?: string;
|
||||||
|
onSelect?: Function; // TODO: Add more specific type
|
||||||
|
onClick?: Function; // TODO: Add more specific type
|
||||||
|
}
|
||||||
|
interface Panel extends React.ReactElement<PanelProps> { }
|
||||||
|
interface PanelClass extends React.ComponentClass<PanelProps> { }
|
||||||
|
var Panel: PanelClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Accordion />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface AccordionProps extends React.Props<AccordionClass> {
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
collapsible?: boolean;
|
||||||
|
defaultExpanded?: boolean;
|
||||||
|
eventKey?: any;
|
||||||
|
expanded?: boolean;
|
||||||
|
footer?: any; // TODO: Add more specific type
|
||||||
|
header?: any; // TODO: Add more specific type
|
||||||
|
id?: string;
|
||||||
|
onSelect?: Function; // TODO: Add more specific type
|
||||||
|
}
|
||||||
|
interface Accordion extends React.ReactElement<AccordionProps> { }
|
||||||
|
interface AccordionClass extends React.ComponentClass<AccordionProps> { }
|
||||||
|
var Accordion: AccordionClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <PanelGroup />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface PanelGroupProps extends React.Props<PanelGroupClass> {
|
||||||
|
accordion?: boolean;
|
||||||
|
activeKey?: any;
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
defaultActiveKey?: any;
|
||||||
|
onSelect?: Function;
|
||||||
|
}
|
||||||
|
interface PanelGroup extends React.ReactElement<PanelGroupProps> { }
|
||||||
|
interface PanelGroupClass extends React.ComponentClass<PanelGroupProps> { }
|
||||||
|
var PanelGroup: PanelGroupClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Modal.Dialog />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ModalDialogProps extends React.Props<ModalDialogClass> {
|
||||||
|
// TODO: Add more specific type
|
||||||
|
}
|
||||||
|
interface ModalDialog extends React.ReactElement<ModalDialogProps> { }
|
||||||
|
interface ModalDialogClass extends React.ComponentClass<ModalHeaderProps> { }
|
||||||
|
|
||||||
|
|
||||||
|
// <Modal.Header />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ModalHeaderProps extends React.Props<ModalHeaderClass> {
|
||||||
|
className?: string;
|
||||||
|
closeButton?: boolean;
|
||||||
|
modalClassName?: string;
|
||||||
|
onHide?: Function;
|
||||||
|
// undefined?: string;
|
||||||
|
}
|
||||||
|
interface ModalHeader extends React.ReactElement<ModalHeaderProps> { }
|
||||||
|
interface ModalHeaderClass extends React.ComponentClass<ModalHeaderProps> { }
|
||||||
|
|
||||||
|
|
||||||
|
// <Modal.Title/>
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ModalTitleProps extends React.Props<ModalTitleClass> {
|
||||||
|
className?: string;
|
||||||
|
modalClassName?: string;
|
||||||
|
}
|
||||||
|
interface ModalTitle extends React.ReactElement<ModalTitleProps> { }
|
||||||
|
interface ModalTitleClass extends React.ComponentClass<ModalTitleProps> { }
|
||||||
|
|
||||||
|
|
||||||
|
// <Modal.Body />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ModalBodyProps extends React.Props<ModalBodyClass> {
|
||||||
|
className?: string;
|
||||||
|
modalClassName?: string;
|
||||||
|
}
|
||||||
|
interface ModalBody extends React.ReactElement<ModalBodyProps> { }
|
||||||
|
interface ModalBodyClass extends React.ComponentClass<ModalBodyProps> { }
|
||||||
|
|
||||||
|
|
||||||
|
// <Modal.Footer />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ModalFooterProps extends React.Props<ModalFooterClass> {
|
||||||
|
className?: string;
|
||||||
|
modalClassName?: string;
|
||||||
|
}
|
||||||
|
interface ModalFooter extends React.ReactElement<ModalFooterProps> { }
|
||||||
|
interface ModalFooterClass extends React.ComponentClass<ModalFooterProps> { }
|
||||||
|
|
||||||
|
|
||||||
|
// <Modal />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ModalProps extends React.Props<ModalClass> {
|
||||||
|
// Required
|
||||||
|
onHide: Function;
|
||||||
|
|
||||||
|
// Optional
|
||||||
|
animation?: boolean;
|
||||||
|
autoFocus?: boolean;
|
||||||
|
backdrop?: boolean|string;
|
||||||
|
bsSize?: string;
|
||||||
|
container?: any; // TODO: Add more specific type
|
||||||
|
dialogClassName?: string;
|
||||||
|
dialogComponent?: any; // TODO: Add more specific type
|
||||||
|
enforceFocus?: boolean;
|
||||||
|
keyboard?: boolean;
|
||||||
|
show?: boolean;
|
||||||
|
}
|
||||||
|
interface Modal extends React.ReactElement<ModalProps> { }
|
||||||
|
interface ModalClass extends React.ComponentClass<ModalProps> {
|
||||||
|
Header: ModalHeaderClass;
|
||||||
|
Title: ModalTitleClass;
|
||||||
|
Body: ModalBodyClass;
|
||||||
|
Footer: ModalFooterClass;
|
||||||
|
Dialog: ModalDialogClass;
|
||||||
|
}
|
||||||
|
var Modal: ModalClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <OverlayTrigger />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface OverlayTriggerProps extends React.Props<OverlayTriggerClass> {
|
||||||
|
// Required
|
||||||
|
overlay: any; // TODO: Add more specific type
|
||||||
|
|
||||||
|
// Optional
|
||||||
|
animation?: any; // TODO: Add more specific type
|
||||||
|
container?: any; // TODO: Add more specific type
|
||||||
|
containerPadding?: number;
|
||||||
|
defaultOverlayShown?: boolean;
|
||||||
|
delay?: number;
|
||||||
|
delayHide?: number;
|
||||||
|
delayShow?: number;
|
||||||
|
onEnter?: Function;
|
||||||
|
onEntered?: Function;
|
||||||
|
onEntering?: Function;
|
||||||
|
onExit?: Function;
|
||||||
|
onExited?: Function;
|
||||||
|
onExiting?: Function;
|
||||||
|
placement?: string;
|
||||||
|
rootClose?: boolean;
|
||||||
|
trigger?: string;
|
||||||
|
}
|
||||||
|
interface OverlayTrigger extends React.ReactElement<OverlayTriggerProps> { }
|
||||||
|
interface OverlayTriggerClass extends React.ComponentClass<OverlayTriggerProps> { }
|
||||||
|
var OverlayTrigger: OverlayTriggerClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Tooltip />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface TooltipProps extends React.Props<TooltipClass> {
|
||||||
|
// Optional
|
||||||
|
arrowOffsetLeft?: number | string;
|
||||||
|
arrowOffsetTop?: number | string;
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
id?: string;
|
||||||
|
placement?: string;
|
||||||
|
positionLeft?: number;
|
||||||
|
positionTop?: number;
|
||||||
|
title?: any; // TODO: Add more specific type
|
||||||
|
}
|
||||||
|
interface Tooltip extends React.ReactElement<TooltipProps> { }
|
||||||
|
interface TooltipClass extends React.ComponentClass<TooltipProps> { }
|
||||||
|
var Tooltip: TooltipClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Popover/>
|
||||||
|
// ----------------------------------------
|
||||||
|
interface PopoverProps extends React.Props<PopoverClass> {
|
||||||
|
// Optional
|
||||||
|
arrowOffsetLeft?: number | string;
|
||||||
|
arrowOffsetTop?: number | string;
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
id?: string;
|
||||||
|
placement?: string;
|
||||||
|
positionLeft?: number;
|
||||||
|
positionTop?: number;
|
||||||
|
title?: any; // TODO: Add more specific type
|
||||||
|
}
|
||||||
|
interface Popover extends React.ReactElement<PopoverProps> { }
|
||||||
|
interface PopoverClass extends React.ComponentClass<PopoverProps> { }
|
||||||
|
var Popover: PopoverClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Overlay />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface OverlayProps extends React.Props<OverlayClass> {
|
||||||
|
// Optional
|
||||||
|
animation?: any; // TODO: Add more specific type
|
||||||
|
container?: any; // TODO: Add more specific type
|
||||||
|
containerPadding?: number; // TODO: Add more specific type
|
||||||
|
onEnter?: Function;
|
||||||
|
onEntered?: Function;
|
||||||
|
onEntering?: Function;
|
||||||
|
onExit?: Function;
|
||||||
|
onExited?: Function;
|
||||||
|
onExiting?: Function;
|
||||||
|
onHide?: Function;
|
||||||
|
placement?: string;
|
||||||
|
rootClose?: boolean;
|
||||||
|
show?: boolean;
|
||||||
|
target?: Function;
|
||||||
|
}
|
||||||
|
interface Overlay extends React.ReactElement<OverlayProps> { }
|
||||||
|
interface OverlayClass extends React.ComponentClass<OverlayProps> { }
|
||||||
|
var Overlay: OverlayClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <ProgressBar />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ProgressBarProps extends React.Props<ProgressBarClass> {
|
||||||
|
// Optional
|
||||||
|
active?: boolean;
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
interpolatedClass?: any; // TODO: Add more specific type
|
||||||
|
label?: any; // TODO: Add more specific type
|
||||||
|
max?: number;
|
||||||
|
min?: number;
|
||||||
|
now?: number;
|
||||||
|
srOnly?: boolean;
|
||||||
|
striped?: boolean;
|
||||||
|
}
|
||||||
|
interface ProgressBar extends React.ReactElement<ProgressBarProps> { }
|
||||||
|
interface ProgressBarClass extends React.ComponentClass<ProgressBarProps> { }
|
||||||
|
var ProgressBar: ProgressBarClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Nav />
|
||||||
|
// ----------------------------------------
|
||||||
|
// TODO: This one turned into a union of two different types
|
||||||
|
interface NavProps extends React.Props<NavClass> {
|
||||||
|
// Optional
|
||||||
|
activeHref?: string;
|
||||||
|
activeKey?: any;
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
collapsible?: boolean;
|
||||||
|
eventKey?: any;
|
||||||
|
expanded?: boolean;
|
||||||
|
id?: string;
|
||||||
|
justified?: boolean;
|
||||||
|
navbar?: boolean;
|
||||||
|
onSelect?: Function;
|
||||||
|
pullRight?: boolean;
|
||||||
|
right?: boolean;
|
||||||
|
stacked?: boolean;
|
||||||
|
ulClassName?: string;
|
||||||
|
ulId?: string;
|
||||||
|
}
|
||||||
|
interface Nav extends React.ReactElement<NavProps> { }
|
||||||
|
interface NavClass extends React.ComponentClass<NavProps> { }
|
||||||
|
var Nav: NavClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <NavItem />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface NavItemProps extends React.Props<NavItemClass> {
|
||||||
|
active?: boolean;
|
||||||
|
brand?: any; // TODO: Add more specific type
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
componentClass?: any; // TODO: Add more specific type
|
||||||
|
defaultNavExpanded?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
eventKey?: any;
|
||||||
|
fixedBottom?: boolean;
|
||||||
|
fixedTop?: boolean;
|
||||||
|
fluid?: boolean;
|
||||||
|
href?: string;
|
||||||
|
inverse?: boolean;
|
||||||
|
linkId?: string;
|
||||||
|
navExpanded?: boolean;
|
||||||
|
onClick?: Function;
|
||||||
|
onSelect?: Function;
|
||||||
|
onToggle?: Function;
|
||||||
|
role?: string;
|
||||||
|
staticTop?: boolean;
|
||||||
|
target?: string;
|
||||||
|
title?: string;
|
||||||
|
toggleButton?: any; // TODO: Add more specific type
|
||||||
|
toggleNavKey?: string | number;
|
||||||
|
}
|
||||||
|
interface NavItem extends React.ReactElement<NavItemProps> { }
|
||||||
|
interface NavItemClass extends React.ComponentClass<NavItemProps> { }
|
||||||
|
var NavItem: NavItemClass;
|
||||||
|
|
||||||
|
// <Navbar.Brand />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface NavbarBrandProps extends React.Props<NavbarBrandClass> {
|
||||||
|
}
|
||||||
|
interface NavbarBrand extends React.ReactElement<NavbarBrandProps> { }
|
||||||
|
interface NavbarBrandClass extends React.ComponentClass<NavbarBrandProps> { }
|
||||||
|
|
||||||
|
// <Navbar.Collapse />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface NavbarCollapseProps extends React.Props<NavbarCollapseClass> {
|
||||||
|
}
|
||||||
|
interface NavbarCollapse extends React.ReactElement<NavbarCollapseProps> { }
|
||||||
|
interface NavbarCollapseClass extends React.ComponentClass<NavbarCollapseProps> { }
|
||||||
|
|
||||||
|
// <Navbar.Header />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface NavbarHeaderProps extends React.Props<NavbarHeaderClass> {
|
||||||
|
}
|
||||||
|
interface NavbarHeader extends React.ReactElement<NavbarHeaderProps> { }
|
||||||
|
interface NavbarHeaderClass extends React.ComponentClass<NavbarHeaderProps> { }
|
||||||
|
|
||||||
|
// <Navbar.Toggle />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface NavbarToggleProps extends React.Props<NavbarToggleClass> {
|
||||||
|
}
|
||||||
|
interface NavbarToggle extends React.ReactElement<NavbarToggleProps> { }
|
||||||
|
interface NavbarToggleClass extends React.ComponentClass<NavbarToggleProps> { }
|
||||||
|
|
||||||
|
// <Navbar />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface NavbarProps extends React.Props<NavbarClass> {
|
||||||
|
brand?: any; // TODO: Add more specific type
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
componentClass?: any; // TODO: Add more specific type
|
||||||
|
defaultNavExpanded?: boolean;
|
||||||
|
fixedBottom?: boolean;
|
||||||
|
fixedTop?: boolean;
|
||||||
|
fluid?: boolean;
|
||||||
|
inverse?: boolean;
|
||||||
|
navExpanded?: boolean;
|
||||||
|
onToggle?: Function;
|
||||||
|
role?: string;
|
||||||
|
staticTop?: boolean;
|
||||||
|
toggleButton?: any; // TODO: Add more specific type
|
||||||
|
toggleNavKey?: string | number;
|
||||||
|
}
|
||||||
|
interface Navbar extends React.ReactElement<NavbarProps> { }
|
||||||
|
interface NavbarClass extends React.ComponentClass<NavbarProps> {
|
||||||
|
Brand: NavbarBrandClass;
|
||||||
|
Collapse: NavbarCollapseClass;
|
||||||
|
Header: NavbarHeaderClass;
|
||||||
|
Toggle: NavbarToggleClass;
|
||||||
|
}
|
||||||
|
var Navbar: NavbarClass;
|
||||||
|
|
||||||
|
// <NavBrand />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface NavBrandProps {
|
||||||
|
|
||||||
|
}
|
||||||
|
interface NavBrand extends React.ReactElement<NavbarProps> { }
|
||||||
|
interface NavBrandClass extends React.ComponentClass<NavbarProps> { }
|
||||||
|
var NavBrand: NavBrandClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <NavDropdown />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface NavDropdownProps extends React.Props<NavDropdownClass> {
|
||||||
|
className?: string;
|
||||||
|
eventKey?: any;
|
||||||
|
title?: string;
|
||||||
|
id?: string;
|
||||||
|
}
|
||||||
|
interface NavDropdown extends React.ReactElement<NavDropdownProps> { }
|
||||||
|
interface NavDropdownClass extends React.ComponentClass<NavDropdownProps> { }
|
||||||
|
var NavDropdown: NavDropdownClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Tabs />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface TabsProps extends React.Props<TabsClass> {
|
||||||
|
activeKey?: any;
|
||||||
|
animation?: boolean;
|
||||||
|
bsStyle?: string;
|
||||||
|
defaultActiveKey?: any;
|
||||||
|
id?: string | number;
|
||||||
|
onSelect?: Function;
|
||||||
|
paneWidth?: any; // TODO: Add more specific type
|
||||||
|
position?: string;
|
||||||
|
tabWidth?: any; // TODO: Add more specific type
|
||||||
|
}
|
||||||
|
interface Tabs extends React.ReactElement<TabsProps> { }
|
||||||
|
interface TabsClass extends React.ComponentClass<TabsProps> { }
|
||||||
|
var Tabs: TabsClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Tab />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface TabProps extends React.Props<TabClass> {
|
||||||
|
animation?: boolean;
|
||||||
|
className?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
eventKey?: any; // TODO: Add more specific type
|
||||||
|
title?: any; // TODO: Add more specific type
|
||||||
|
}
|
||||||
|
interface Tab extends React.ReactElement<TabProps> { }
|
||||||
|
interface TabClass extends React.ComponentClass<TabProps> { }
|
||||||
|
var Tab: TabClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Pager />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface PagerProps extends React.Props<PagerClass> {
|
||||||
|
className?: string;
|
||||||
|
onSelect?: Function;
|
||||||
|
}
|
||||||
|
interface Pager extends React.ReactElement<PagerProps> { }
|
||||||
|
interface PagerClass extends React.ComponentClass<PagerProps> { }
|
||||||
|
var Pager: PagerClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <PageItem />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface PageItemProps extends React.Props<PageItemClass> {
|
||||||
|
className?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
eventKey?: any;
|
||||||
|
href?: string;
|
||||||
|
next?: boolean;
|
||||||
|
onSelect?: Function;
|
||||||
|
previous?: boolean;
|
||||||
|
target?: string;
|
||||||
|
title?: string;
|
||||||
|
}
|
||||||
|
interface PageItem extends React.ReactElement<PageItemProps> { }
|
||||||
|
interface PageItemClass extends React.ComponentClass<PageItemProps> { }
|
||||||
|
var PageItem: PageItemClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Pagination />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface PaginationProps extends React.Props<PaginationClass> {
|
||||||
|
activePage?: number;
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
buttonComponentClass?: any; // TODO: Add more specific type
|
||||||
|
className?: string;
|
||||||
|
ellipsis?: boolean;
|
||||||
|
first?: boolean;
|
||||||
|
items?: number;
|
||||||
|
last?: boolean;
|
||||||
|
maxButtons?: number;
|
||||||
|
next?: boolean;
|
||||||
|
onSelect?: Function;
|
||||||
|
prev?: boolean;
|
||||||
|
}
|
||||||
|
interface Pagination extends React.ReactElement<PaginationProps> { }
|
||||||
|
interface PaginationClass extends React.ComponentClass<PaginationProps> { }
|
||||||
|
var Pagination: PaginationClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Alert />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface AlertProps extends React.Props<AlertClass> {
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
closeLabel?: string;
|
||||||
|
dismissAfter?: number;
|
||||||
|
onDismiss?: Function;
|
||||||
|
}
|
||||||
|
interface Alert extends React.ReactElement<AlertProps> { }
|
||||||
|
interface AlertClass extends React.ComponentClass<AlertProps> { }
|
||||||
|
var Alert: AlertClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Carousel />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface CarouselProps extends React.Props<CarouselClass> {
|
||||||
|
activeIndex?: number;
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
controls?: boolean;
|
||||||
|
defaultActiveIndex?: number;
|
||||||
|
direction?: string;
|
||||||
|
indicators?: boolean;
|
||||||
|
interval?: number;
|
||||||
|
nextIcon?: any; // TODO: Add more specific type
|
||||||
|
onSelect?: Function;
|
||||||
|
onSlideEnd?: Function;
|
||||||
|
pauseOnHover?: boolean;
|
||||||
|
prevIcon?: any; // TODO: Add more specific type
|
||||||
|
slide?: boolean;
|
||||||
|
wrap?: boolean;
|
||||||
|
}
|
||||||
|
interface Carousel extends React.ReactElement<CarouselProps> { }
|
||||||
|
interface CarouselClass extends React.ComponentClass<CarouselProps> { }
|
||||||
|
var Carousel: CarouselClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <CarouselItem />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface CarouselItemProps extends React.Props<CarouselItemClass> {
|
||||||
|
active?: boolean;
|
||||||
|
animtateIn?: boolean;
|
||||||
|
animateOut?: boolean;
|
||||||
|
caption?: any; // TODO: Add more specific type
|
||||||
|
className?: string;
|
||||||
|
direction?: string;
|
||||||
|
index?: number;
|
||||||
|
onAnimateOutEnd?: Function;
|
||||||
|
}
|
||||||
|
interface CarouselItem extends React.ReactElement<CarouselItemProps> { }
|
||||||
|
interface CarouselItemClass extends React.ComponentClass<CarouselItemProps> { }
|
||||||
|
var CarouselItem: CarouselItemClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Grid />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface GridProps extends React.Props<GridClass> {
|
||||||
|
className?: string;
|
||||||
|
componentClass?: any; // TODO: Add more specific type
|
||||||
|
fluid?: boolean;
|
||||||
|
}
|
||||||
|
interface Grid extends React.ReactElement<GridProps> { }
|
||||||
|
interface GridClass extends React.ComponentClass<GridProps> { }
|
||||||
|
var Grid: GridClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Row />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface RowProps extends React.Props<RowClass> {
|
||||||
|
className?: string;
|
||||||
|
componentClass?: any; // TODO: Add more specific type
|
||||||
|
}
|
||||||
|
interface Row extends React.ReactElement<RowProps> { }
|
||||||
|
interface RowClass extends React.ComponentClass<RowProps> { }
|
||||||
|
var Row: RowClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Col />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ColProps extends React.Props<ColClass> {
|
||||||
|
className?: string;
|
||||||
|
componentClass?: any; // TODO: Add more specific type
|
||||||
|
lg?: number;
|
||||||
|
lgOffset?: number;
|
||||||
|
lgPull?: number;
|
||||||
|
lgPush?: number;
|
||||||
|
md?: number;
|
||||||
|
mdOffset?: number;
|
||||||
|
mdPull?: number;
|
||||||
|
mdPush?: number;
|
||||||
|
sm?: number;
|
||||||
|
smOffset?: number;
|
||||||
|
smPull?: number;
|
||||||
|
smPush?: number;
|
||||||
|
xs?: number;
|
||||||
|
xsOffset?: number;
|
||||||
|
xsPull?: number;
|
||||||
|
xsPush?: number;
|
||||||
|
}
|
||||||
|
interface Col extends React.ReactElement<ColProps> { }
|
||||||
|
interface ColClass extends React.ComponentClass<ColProps> { }
|
||||||
|
var Col: ColClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Thumbnail />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ThumbnailProps extends React.Props<ThumbnailClass> {
|
||||||
|
alt?: string;
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
href?: string;
|
||||||
|
src?: string;
|
||||||
|
}
|
||||||
|
interface Thumbnail extends React.ReactElement<ThumbnailProps> { }
|
||||||
|
interface ThumbnailClass extends React.ComponentClass<ThumbnailProps> { }
|
||||||
|
var Thumbnail: ThumbnailClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <ListGroup />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ListGroupProps extends React.Props<ListGroupClass> {
|
||||||
|
className?: string;
|
||||||
|
id?: string | number;
|
||||||
|
fill?: boolean; // TODO: Add more specific type
|
||||||
|
}
|
||||||
|
interface ListGroup extends React.ReactElement<ListGroupProps> { }
|
||||||
|
interface ListGroupClass extends React.ComponentClass<ListGroupProps> { }
|
||||||
|
var ListGroup: ListGroupClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <ListGroupItem />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ListGroupItemProps extends React.Props<ListGroupItemClass> {
|
||||||
|
active?: any;
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
disabled?: any;
|
||||||
|
eventKey?: any;
|
||||||
|
header?: any; // TODO: Add more specific type
|
||||||
|
href?: string;
|
||||||
|
key?: any; // TODO: Add more specific type
|
||||||
|
listItem?: boolean;
|
||||||
|
onClick?: Function; // TODO: Add more specific type
|
||||||
|
target?: string;
|
||||||
|
}
|
||||||
|
interface ListGroupItem extends React.ReactElement<ListGroupItemProps> { }
|
||||||
|
interface ListGroupItemClass extends React.ComponentClass<ListGroupItemProps> { }
|
||||||
|
var ListGroupItem: ListGroupItemClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Label />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface LabelProps extends React.Props<LabelClass> {
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
interface Label extends React.ReactElement<LabelProps> { }
|
||||||
|
interface LabelClass extends React.ComponentClass<LabelProps> { }
|
||||||
|
var Label: LabelClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Badge />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface BadgeProps extends React.Props<BadgeClass> {
|
||||||
|
className?: string;
|
||||||
|
pullRight?: boolean;
|
||||||
|
}
|
||||||
|
interface Badge extends React.ReactElement<BadgeProps> { }
|
||||||
|
interface BadgeClass extends React.ComponentClass<BadgeProps> { }
|
||||||
|
var Badge: BadgeClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Jumbotron />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface JumbotronProps extends React.Props<JumbotronClass> {
|
||||||
|
className?: string;
|
||||||
|
componentClass?: any; // TODO: Add more specific type
|
||||||
|
}
|
||||||
|
interface Jumbotron extends React.ReactElement<JumbotronProps> { }
|
||||||
|
interface JumbotronClass extends React.ComponentClass<JumbotronProps> { }
|
||||||
|
var Jumbotron: JumbotronClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <PageHeader />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface PageHeaderProps extends React.Props<PageHeaderClass> {
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
interface PageHeader extends React.ReactElement<PageHeaderProps> { }
|
||||||
|
interface PageHeaderClass extends React.ComponentClass<PageHeaderProps> { }
|
||||||
|
var PageHeader: PageHeaderClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Well />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface WellProps extends React.Props<WellClass> {
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
interface Well extends React.ReactElement<WellProps> { }
|
||||||
|
interface WellClass extends React.ComponentClass<WellProps> { }
|
||||||
|
var Well: WellClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Glyphicon />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface GlyphiconProps extends React.Props<GlyphiconClass> {
|
||||||
|
className?: string;
|
||||||
|
// Required
|
||||||
|
glyph: string;
|
||||||
|
}
|
||||||
|
interface Glyphicon extends React.ReactElement<GlyphiconProps> { }
|
||||||
|
interface GlyphiconClass extends React.ComponentClass<GlyphiconProps> { }
|
||||||
|
var Glyphicon: GlyphiconClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Table />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface TableProps extends React.Props<TableClass> {
|
||||||
|
bordered?: boolean;
|
||||||
|
className?: string;
|
||||||
|
condensed?: boolean;
|
||||||
|
hover?: boolean;
|
||||||
|
responsive?: boolean;
|
||||||
|
striped?: boolean;
|
||||||
|
}
|
||||||
|
interface Table extends React.ReactElement<TableProps> { }
|
||||||
|
interface TableClass extends React.ComponentClass<TableProps> { }
|
||||||
|
var Table: TableClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Input />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface InputProps extends React.Props<InputClass> {
|
||||||
|
defaultValue?:string;
|
||||||
|
addonAfter?: any; // TODO: Add more specific type
|
||||||
|
addonBefore?: any; // TODO: Add more specific type
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
buttonAfter?: any; // TODO: Add more specific type
|
||||||
|
buttonBefore?: any; // TODO: Add more specific type
|
||||||
|
className?: string;
|
||||||
|
checked?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
feedbackIcon?: any; // TODO: Add more specific type
|
||||||
|
groupClassName?: string;
|
||||||
|
hasFeedback?: boolean;
|
||||||
|
help?: any; // TODO: Add more specific type
|
||||||
|
id?: string | number;
|
||||||
|
label?: any; // TODO: Add more specific type
|
||||||
|
labelClassName?: string;
|
||||||
|
multiple?: boolean;
|
||||||
|
placeholder?: string;
|
||||||
|
readOnly?: boolean;
|
||||||
|
type?: string;
|
||||||
|
onChange?: Function; // TODO: Add more specific type
|
||||||
|
onKeyDown?: Function; // TODO: Add more specific type
|
||||||
|
onKeyUp?: Function; // TODO: Add more specific type
|
||||||
|
onKeyPress?: Function; // TODO: Add more specific type
|
||||||
|
value?: any; // TODO: Add more specific type
|
||||||
|
wrapperClassName?: string;
|
||||||
|
}
|
||||||
|
interface Input extends React.ReactElement<InputProps> { }
|
||||||
|
interface InputClass extends React.ComponentClass<InputProps> { }
|
||||||
|
var Input: InputClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <ButtonInput />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface ButtonInputProps extends React.Props<ButtonInputClass> {
|
||||||
|
addonAfter?: any; // TODO: Add more specific type
|
||||||
|
addonBefore?: any; // TODO: Add more specific type
|
||||||
|
bsSize?: string;
|
||||||
|
bsStyle?: string;
|
||||||
|
buttonAfter?: any; // TODO: Add more specific type
|
||||||
|
buttonBefore?: any; // TODO: Add more specific type
|
||||||
|
className?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
feedbackIcon?: any; // TODO: Add more specific type
|
||||||
|
groupClassName?: string;
|
||||||
|
hasFeedback?: boolean;
|
||||||
|
help?: any; // TODO: Add more specific type
|
||||||
|
id?: string | number;
|
||||||
|
label?: any; // TODO: Add more specific type
|
||||||
|
labelClassName?: string;
|
||||||
|
multiple?: boolean;
|
||||||
|
onClick?: Function; // TODO: Add more specific type
|
||||||
|
type?: string;
|
||||||
|
value?: any; // TODO: Add more specific type
|
||||||
|
wrapperClassName?: string;
|
||||||
|
}
|
||||||
|
interface ButtonInput extends React.ReactElement<ButtonInputProps> { }
|
||||||
|
interface ButtonInputClass extends React.ComponentClass<ButtonInputProps> { }
|
||||||
|
var ButtonInput: ButtonInputClass;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: FormControls.Static
|
||||||
|
|
||||||
|
|
||||||
|
// <Portal />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface PortalProps extends React.Props<PortalClass> {
|
||||||
|
dimension?: string | Function;
|
||||||
|
getDimensionValue?: Function;
|
||||||
|
in?: boolean;
|
||||||
|
onEnter?: Function;
|
||||||
|
onEntered?: Function;
|
||||||
|
onEntering?: Function;
|
||||||
|
onExit?: Function;
|
||||||
|
onExited?: Function;
|
||||||
|
onExiting?: Function;
|
||||||
|
role?: string;
|
||||||
|
timeout?: number;
|
||||||
|
transitionAppear?: boolean;
|
||||||
|
unmountOnExit?: boolean;
|
||||||
|
}
|
||||||
|
interface Portal extends React.ReactElement<PortalProps> { }
|
||||||
|
interface PortalClass extends React.ComponentClass<PortalProps> { }
|
||||||
|
var Portal: PortalClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Position />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface PositionProps extends React.Props<PositionClass> {
|
||||||
|
dimension?: string | Function;
|
||||||
|
getDimensionValue?: Function;
|
||||||
|
in?: boolean;
|
||||||
|
onEnter?: Function;
|
||||||
|
onEntered?: Function;
|
||||||
|
onEntering?: Function;
|
||||||
|
onExit?: Function;
|
||||||
|
onExited?: Function;
|
||||||
|
onExiting?: Function;
|
||||||
|
role?: string;
|
||||||
|
timeout?: number;
|
||||||
|
transitionAppear?: boolean;
|
||||||
|
unmountOnExit?: boolean;
|
||||||
|
}
|
||||||
|
interface Position extends React.ReactElement<PositionProps> { }
|
||||||
|
interface PositionClass extends React.ComponentClass<PositionProps> { }
|
||||||
|
var Position: PositionClass;
|
||||||
|
|
||||||
|
|
||||||
|
// <Fade />
|
||||||
|
// ----------------------------------------
|
||||||
|
interface FadeProps extends React.Props<FadeClass> {
|
||||||
|
in?: boolean;
|
||||||
|
onEnter?: Function;
|
||||||
|
onEntered?: Function;
|
||||||
|
onEntering?: Function;
|
||||||
|
onExit?: Function;
|
||||||
|
onExited?: Function;
|
||||||
|
onExiting?: Function;
|
||||||
|
timeout?: number;
|
||||||
|
transitionAppear?: boolean;
|
||||||
|
unmountOnExit?: boolean;
|
||||||
|
}
|
||||||
|
interface Fade extends React.ReactElement<FadeProps> { }
|
||||||
|
interface FadeClass extends React.ComponentClass<FadeProps> { }
|
||||||
|
var Fade: FadeClass;
|
||||||
|
}
|
||||||
69
samples/react/MusicStore/typings/react-redux/react-redux.d.ts
vendored
Normal file
69
samples/react/MusicStore/typings/react-redux/react-redux.d.ts
vendored
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
// Type definitions for react-redux 2.1.2
|
||||||
|
// Project: https://github.com/rackt/react-redux
|
||||||
|
// Definitions by: Qubo <https://github.com/tkqubo>
|
||||||
|
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||||
|
|
||||||
|
/// <reference path="../react/react.d.ts" />
|
||||||
|
/// <reference path="../redux/redux.d.ts" />
|
||||||
|
|
||||||
|
declare module "react-redux" {
|
||||||
|
import { Component } from 'react';
|
||||||
|
import { Store, Dispatch, ActionCreator } from 'redux';
|
||||||
|
|
||||||
|
export class ElementClass extends Component<any, any> { }
|
||||||
|
export interface ClassDecorator {
|
||||||
|
<T extends (typeof ElementClass)>(component: T): T
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects a React component to a Redux store.
|
||||||
|
* @param mapStateToProps
|
||||||
|
* @param mapDispatchToProps
|
||||||
|
* @param mergeProps
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
export function connect(mapStateToProps?: MapStateToProps,
|
||||||
|
mapDispatchToProps?: MapDispatchToPropsFunction|MapDispatchToPropsObject,
|
||||||
|
mergeProps?: MergeProps,
|
||||||
|
options?: Options): ClassDecorator;
|
||||||
|
|
||||||
|
interface MapStateToProps {
|
||||||
|
(state: any, ownProps?: any): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MapDispatchToPropsFunction {
|
||||||
|
(dispatch: Dispatch, ownProps?: any): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MapDispatchToPropsObject {
|
||||||
|
[name: string]: ActionCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MergeProps {
|
||||||
|
(stateProps: any, dispatchProps: any, ownProps: any): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Options {
|
||||||
|
/**
|
||||||
|
* If true, implements shouldComponentUpdate and shallowly compares the result of mergeProps,
|
||||||
|
* preventing unnecessary updates, assuming that the component is a “pure” component
|
||||||
|
* and does not rely on any input or state other than its props and the selected Redux store’s state.
|
||||||
|
* Defaults to true.
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
pure: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Property {
|
||||||
|
/**
|
||||||
|
* The single Redux store in your application.
|
||||||
|
*/
|
||||||
|
store?: Store;
|
||||||
|
children?: Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the Redux store available to the connect() calls in the component hierarchy below.
|
||||||
|
*/
|
||||||
|
export class Provider extends Component<Property, {}> { }
|
||||||
|
}
|
||||||
46
samples/react/MusicStore/typings/react-router-bootstrap/react-router-bootstrap.d.ts
vendored
Normal file
46
samples/react/MusicStore/typings/react-router-bootstrap/react-router-bootstrap.d.ts
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
// Type definitions for react-router-bootstrap
|
||||||
|
// Project: https://github.com/react-bootstrap/react-router-bootstrap
|
||||||
|
// Definitions by: Vincent Lesierse <https://github.com/vlesierse>
|
||||||
|
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||||
|
|
||||||
|
///<reference path="../react/react.d.ts"/>
|
||||||
|
///<reference path="../react-router/react-router.d.ts"/>
|
||||||
|
|
||||||
|
declare namespace ReactRouterBootstrap {
|
||||||
|
// Import React
|
||||||
|
import React = __React;
|
||||||
|
|
||||||
|
interface LinkContainerProps extends ReactRouter.LinkProps {
|
||||||
|
disabled?: boolean
|
||||||
|
}
|
||||||
|
interface LinkContainer extends React.ComponentClass<LinkContainerProps> {}
|
||||||
|
interface LinkContainerElement extends React.ReactElement<LinkContainerProps> {}
|
||||||
|
const LinkContainer: LinkContainer
|
||||||
|
|
||||||
|
const IndexLinkContainer: LinkContainer
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "react-router-bootstrap/lib/LinkContainer" {
|
||||||
|
|
||||||
|
export default ReactRouterBootstrap.LinkContainer
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "react-router-bootstrap/lib/IndexLinkContainer" {
|
||||||
|
|
||||||
|
export default ReactRouterBootstrap.IndexLinkContainer
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "react-router-bootstrap" {
|
||||||
|
|
||||||
|
import LinkContainer from "react-router-bootstrap/lib/LinkContainer"
|
||||||
|
|
||||||
|
import IndexLinkContainer from "react-router-bootstrap/lib/IndexLinkContainer"
|
||||||
|
|
||||||
|
export {
|
||||||
|
LinkContainer,
|
||||||
|
IndexLinkContainer
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
48
samples/react/MusicStore/typings/react-router-redux/react-router-redux.d.ts
vendored
Normal file
48
samples/react/MusicStore/typings/react-router-redux/react-router-redux.d.ts
vendored
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
// Type definitions for react-router-redux v2.1.0
|
||||||
|
// Project: https://github.com/rackt/react-router-redux
|
||||||
|
// Definitions by: Isman Usoh <http://github.com/isman-usoh>, Noah Shipley <https://github.com/noah79>, Dimitri Rosenberg <https://github.com/rosendi>
|
||||||
|
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||||
|
|
||||||
|
/// <reference path="../redux/redux.d.ts" />
|
||||||
|
/// <reference path="../react-router/react-router.d.ts"/>
|
||||||
|
|
||||||
|
declare namespace ReactRouterRedux {
|
||||||
|
import R = Redux;
|
||||||
|
import H = HistoryModule;
|
||||||
|
|
||||||
|
const TRANSITION: string;
|
||||||
|
const UPDATE_LOCATION: string;
|
||||||
|
|
||||||
|
const push: PushAction;
|
||||||
|
const replace: ReplaceAction;
|
||||||
|
const go: GoAction;
|
||||||
|
const goBack: GoForwardAction;
|
||||||
|
const goForward: GoBackAction;
|
||||||
|
const routeActions: RouteActions;
|
||||||
|
|
||||||
|
type LocationDescriptor = H.Location | H.Path;
|
||||||
|
type PushAction = (nextLocation: LocationDescriptor) => void;
|
||||||
|
type ReplaceAction = (nextLocation: LocationDescriptor) => void;
|
||||||
|
type GoAction = (n: number) => void;
|
||||||
|
type GoForwardAction = () => void;
|
||||||
|
type GoBackAction = () => void;
|
||||||
|
|
||||||
|
interface RouteActions {
|
||||||
|
push: PushAction;
|
||||||
|
replace: ReplaceAction;
|
||||||
|
go: GoAction;
|
||||||
|
goForward: GoForwardAction;
|
||||||
|
goBack: GoBackAction;
|
||||||
|
}
|
||||||
|
interface HistoryMiddleware extends R.Middleware {
|
||||||
|
listenForReplays(store: R.Store, selectLocationState?: Function): void;
|
||||||
|
unsubscribe(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function routeReducer(state?: any, options?: any): R.Reducer;
|
||||||
|
function syncHistory(history: H.History): HistoryMiddleware;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "react-router-redux" {
|
||||||
|
export = ReactRouterRedux;
|
||||||
|
}
|
||||||
192
samples/react/MusicStore/typings/react-router/history.d.ts
vendored
Normal file
192
samples/react/MusicStore/typings/react-router/history.d.ts
vendored
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
// Type definitions for history v1.13.1
|
||||||
|
// Project: https://github.com/rackt/history
|
||||||
|
// Definitions by: Sergey Buturlakin <http://github.com/sergey-buturlakin>
|
||||||
|
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||||
|
|
||||||
|
|
||||||
|
declare namespace HistoryModule {
|
||||||
|
|
||||||
|
// types based on https://github.com/rackt/history/blob/master/docs/Terms.md
|
||||||
|
|
||||||
|
type Action = string
|
||||||
|
|
||||||
|
type BeforeUnloadHook = () => string | boolean
|
||||||
|
|
||||||
|
type CreateHistory<T> = (options?: HistoryOptions) => T
|
||||||
|
|
||||||
|
type CreateHistoryEnhancer<T, E> = (createHistory: CreateHistory<T>) => CreateHistory<T & E>
|
||||||
|
|
||||||
|
interface History {
|
||||||
|
listenBefore(hook: TransitionHook): Function
|
||||||
|
listen(listener: LocationListener): Function
|
||||||
|
transitionTo(location: Location): void
|
||||||
|
pushState(state: LocationState, path: Path): void
|
||||||
|
replaceState(state: LocationState, path: Path): void
|
||||||
|
push(path: Path): void
|
||||||
|
replace(path: Path): void
|
||||||
|
go(n: number): void
|
||||||
|
goBack(): void
|
||||||
|
goForward(): void
|
||||||
|
createKey(): LocationKey
|
||||||
|
createPath(path: Path): Path
|
||||||
|
createHref(path: Path): Href
|
||||||
|
createLocation(path?: Path, state?: LocationState, action?: Action, key?: LocationKey): Location
|
||||||
|
|
||||||
|
/** @deprecated use location.key to save state instead */
|
||||||
|
setState(state: LocationState): void
|
||||||
|
/** @deprecated use listenBefore instead */
|
||||||
|
registerTransitionHook(hook: TransitionHook): void
|
||||||
|
/** @deprecated use the callback returned from listenBefore instead */
|
||||||
|
unregisterTransitionHook(hook: TransitionHook): void
|
||||||
|
}
|
||||||
|
|
||||||
|
type HistoryOptions = Object
|
||||||
|
|
||||||
|
type Href = string
|
||||||
|
|
||||||
|
type Location = {
|
||||||
|
pathname: Pathname
|
||||||
|
search: QueryString
|
||||||
|
query: Query
|
||||||
|
state: LocationState
|
||||||
|
action: Action
|
||||||
|
key: LocationKey
|
||||||
|
}
|
||||||
|
|
||||||
|
type LocationKey = string
|
||||||
|
|
||||||
|
type LocationListener = (location: Location) => void
|
||||||
|
|
||||||
|
type LocationState = Object
|
||||||
|
|
||||||
|
type Path = string // Pathname + QueryString
|
||||||
|
|
||||||
|
type Pathname = string
|
||||||
|
|
||||||
|
type Query = Object
|
||||||
|
|
||||||
|
type QueryString = string
|
||||||
|
|
||||||
|
type TransitionHook = (location: Location, callback: Function) => any
|
||||||
|
|
||||||
|
|
||||||
|
interface HistoryBeforeUnload {
|
||||||
|
listenBeforeUnload(hook: BeforeUnloadHook): Function
|
||||||
|
}
|
||||||
|
|
||||||
|
interface HistoryQueries {
|
||||||
|
pushState(state: LocationState, pathname: Pathname | Path, query?: Query): void
|
||||||
|
replaceState(state: LocationState, pathname: Pathname | Path, query?: Query): void
|
||||||
|
createPath(path: Path, query?: Query): Path
|
||||||
|
createHref(path: Path, query?: Query): Href
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Global usage, without modules, needs the small trick, because lib.d.ts
|
||||||
|
// already has `history` and `History` global definitions:
|
||||||
|
// var createHistory = ((window as any).History as HistoryModule.Module).createHistory;
|
||||||
|
interface Module {
|
||||||
|
createHistory: CreateHistory<History>
|
||||||
|
createHashHistory: CreateHistory<History>
|
||||||
|
createMemoryHistory: CreateHistory<History>
|
||||||
|
createLocation(path?: Path, state?: LocationState, action?: Action, key?: LocationKey): Location
|
||||||
|
useBasename<T>(createHistory: CreateHistory<T>): CreateHistory<T>
|
||||||
|
useBeforeUnload<T>(createHistory: CreateHistory<T>): CreateHistory<T & HistoryBeforeUnload>
|
||||||
|
useQueries<T>(createHistory: CreateHistory<T>): CreateHistory<T & HistoryQueries>
|
||||||
|
actions: {
|
||||||
|
PUSH: string
|
||||||
|
REPLACE: string
|
||||||
|
POP: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "history/lib/createBrowserHistory" {
|
||||||
|
|
||||||
|
export default function createBrowserHistory(options?: HistoryModule.HistoryOptions): HistoryModule.History
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "history/lib/createHashHistory" {
|
||||||
|
|
||||||
|
export default function createHashHistory(options?: HistoryModule.HistoryOptions): HistoryModule.History
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "history/lib/createMemoryHistory" {
|
||||||
|
|
||||||
|
export default function createMemoryHistory(options?: HistoryModule.HistoryOptions): HistoryModule.History
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "history/lib/createLocation" {
|
||||||
|
|
||||||
|
export default function createLocation(path?: HistoryModule.Path, state?: HistoryModule.LocationState, action?: HistoryModule.Action, key?: HistoryModule.LocationKey): HistoryModule.Location
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "history/lib/useBasename" {
|
||||||
|
|
||||||
|
export default function useBasename<T>(createHistory: HistoryModule.CreateHistory<T>): HistoryModule.CreateHistory<T>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "history/lib/useBeforeUnload" {
|
||||||
|
|
||||||
|
export default function useBeforeUnload<T>(createHistory: HistoryModule.CreateHistory<T>): HistoryModule.CreateHistory<T & HistoryModule.HistoryBeforeUnload>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "history/lib/useQueries" {
|
||||||
|
|
||||||
|
export default function useQueries<T>(createHistory: HistoryModule.CreateHistory<T>): HistoryModule.CreateHistory<T & HistoryModule.HistoryQueries>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "history/lib/actions" {
|
||||||
|
|
||||||
|
export const PUSH: string
|
||||||
|
|
||||||
|
export const REPLACE: string
|
||||||
|
|
||||||
|
export const POP: string
|
||||||
|
|
||||||
|
export default {
|
||||||
|
PUSH,
|
||||||
|
REPLACE,
|
||||||
|
POP
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "history" {
|
||||||
|
|
||||||
|
export { default as createHistory } from "history/lib/createBrowserHistory"
|
||||||
|
|
||||||
|
export { default as createHashHistory } from "history/lib/createHashHistory"
|
||||||
|
|
||||||
|
export { default as createMemoryHistory } from "history/lib/createMemoryHistory"
|
||||||
|
|
||||||
|
export { default as createLocation } from "history/lib/createLocation"
|
||||||
|
|
||||||
|
export { default as useBasename } from "history/lib/useBasename"
|
||||||
|
|
||||||
|
export { default as useBeforeUnload } from "history/lib/useBeforeUnload"
|
||||||
|
|
||||||
|
export { default as useQueries } from "history/lib/useQueries"
|
||||||
|
|
||||||
|
import * as Actions from "history/lib/actions"
|
||||||
|
|
||||||
|
export { Actions }
|
||||||
|
|
||||||
|
}
|
||||||
474
samples/react/MusicStore/typings/react-router/react-router.d.ts
vendored
Normal file
474
samples/react/MusicStore/typings/react-router/react-router.d.ts
vendored
Normal file
@@ -0,0 +1,474 @@
|
|||||||
|
// Type definitions for react-router v2.0.0-rc5
|
||||||
|
// Project: https://github.com/rackt/react-router
|
||||||
|
// Definitions by: Sergey Buturlakin <http://github.com/sergey-buturlakin>, Yuichi Murata <https://github.com/mrk21>, Václav Ostrožlík <https://github.com/vasek17>
|
||||||
|
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||||
|
|
||||||
|
|
||||||
|
/// <reference path="../react/react.d.ts" />
|
||||||
|
/// <reference path="./history.d.ts"/>
|
||||||
|
|
||||||
|
|
||||||
|
declare namespace ReactRouter {
|
||||||
|
|
||||||
|
import React = __React
|
||||||
|
|
||||||
|
import H = HistoryModule
|
||||||
|
|
||||||
|
// types based on https://github.com/rackt/react-router/blob/master/docs/Glossary.md
|
||||||
|
|
||||||
|
type Component = React.ReactType
|
||||||
|
|
||||||
|
type EnterHook = (nextState: RouterState, replaceState: RedirectFunction, callback?: Function) => any
|
||||||
|
|
||||||
|
type LeaveHook = () => any
|
||||||
|
|
||||||
|
type Params = Object
|
||||||
|
|
||||||
|
type ParseQueryString = (queryString: H.QueryString) => H.Query
|
||||||
|
|
||||||
|
type RedirectFunction = (state: H.LocationState, pathname: H.Pathname | H.Path, query?: H.Query) => void
|
||||||
|
|
||||||
|
type RouteComponent = Component
|
||||||
|
|
||||||
|
// use the following interface in an app code to get access to route param values, history, location...
|
||||||
|
// interface MyComponentProps extends ReactRouter.RouteComponentProps<{}, { id: number }> {}
|
||||||
|
// somewhere in MyComponent
|
||||||
|
// ...
|
||||||
|
// let id = this.props.routeParams.id
|
||||||
|
// ...
|
||||||
|
// this.props.history. ...
|
||||||
|
// ...
|
||||||
|
interface RouteComponentProps<P, R> {
|
||||||
|
history?: History
|
||||||
|
location?: H.Location
|
||||||
|
params?: P
|
||||||
|
route?: PlainRoute
|
||||||
|
routeParams?: R
|
||||||
|
routes?: PlainRoute[]
|
||||||
|
children?: React.ReactElement<any>
|
||||||
|
}
|
||||||
|
|
||||||
|
type RouteComponents = { [key: string]: RouteComponent }
|
||||||
|
|
||||||
|
type RouteConfig = React.ReactNode | PlainRoute | PlainRoute[]
|
||||||
|
|
||||||
|
type RouteHook = (nextLocation?: H.Location) => any
|
||||||
|
|
||||||
|
type RoutePattern = string
|
||||||
|
|
||||||
|
type StringifyQuery = (queryObject: H.Query) => H.QueryString
|
||||||
|
|
||||||
|
type RouterListener = (error: Error, nextState: RouterState) => void
|
||||||
|
|
||||||
|
interface RouterState {
|
||||||
|
location: H.Location
|
||||||
|
routes: PlainRoute[]
|
||||||
|
params: Params
|
||||||
|
components: RouteComponent[]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface HistoryBase extends H.History {
|
||||||
|
routes: PlainRoute[]
|
||||||
|
parseQueryString?: ParseQueryString
|
||||||
|
stringifyQuery?: StringifyQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
type History = HistoryBase & H.HistoryQueries & HistoryRoutes
|
||||||
|
const browserHistory: History;
|
||||||
|
const hashHistory: History;
|
||||||
|
|
||||||
|
/* components */
|
||||||
|
|
||||||
|
interface RouterProps extends React.Props<Router> {
|
||||||
|
history?: H.History
|
||||||
|
routes?: RouteConfig // alias for children
|
||||||
|
createElement?: (component: RouteComponent, props: Object) => any
|
||||||
|
onError?: (error: any) => any
|
||||||
|
onUpdate?: () => any
|
||||||
|
parseQueryString?: ParseQueryString
|
||||||
|
stringifyQuery?: StringifyQuery
|
||||||
|
}
|
||||||
|
interface Router extends React.ComponentClass<RouterProps> {}
|
||||||
|
interface RouterElement extends React.ReactElement<RouterProps> {}
|
||||||
|
const Router: Router
|
||||||
|
|
||||||
|
|
||||||
|
interface LinkProps extends React.HTMLAttributes, React.Props<Link> {
|
||||||
|
activeStyle?: React.CSSProperties
|
||||||
|
activeClassName?: string
|
||||||
|
onlyActiveOnIndex?: boolean
|
||||||
|
to: RoutePattern
|
||||||
|
query?: H.Query
|
||||||
|
state?: H.LocationState
|
||||||
|
}
|
||||||
|
interface Link extends React.ComponentClass<LinkProps> {}
|
||||||
|
interface LinkElement extends React.ReactElement<LinkProps> {}
|
||||||
|
const Link: Link
|
||||||
|
|
||||||
|
|
||||||
|
const IndexLink: Link
|
||||||
|
|
||||||
|
|
||||||
|
interface RouterContextProps extends React.Props<RouterContext> {
|
||||||
|
history?: H.History
|
||||||
|
router: Router
|
||||||
|
createElement: (component: RouteComponent, props: Object) => any
|
||||||
|
location: H.Location
|
||||||
|
routes: RouteConfig
|
||||||
|
params: Params
|
||||||
|
components?: RouteComponent[]
|
||||||
|
}
|
||||||
|
interface RouterContext extends React.ComponentClass<RouterContextProps> {}
|
||||||
|
interface RouterContextElement extends React.ReactElement<RouterContextProps> {
|
||||||
|
history?: H.History
|
||||||
|
location: H.Location
|
||||||
|
router?: Router
|
||||||
|
}
|
||||||
|
const RouterContext: RouterContext
|
||||||
|
|
||||||
|
|
||||||
|
/* components (configuration) */
|
||||||
|
|
||||||
|
interface RouteProps extends React.Props<Route> {
|
||||||
|
path?: RoutePattern
|
||||||
|
component?: RouteComponent
|
||||||
|
components?: RouteComponents
|
||||||
|
getComponent?: (location: H.Location, cb: (error: any, component?: RouteComponent) => void) => void
|
||||||
|
getComponents?: (location: H.Location, cb: (error: any, components?: RouteComponents) => void) => void
|
||||||
|
onEnter?: EnterHook
|
||||||
|
onLeave?: LeaveHook
|
||||||
|
getIndexRoute?: (location: H.Location, cb: (error: any, indexRoute: RouteConfig) => void) => void
|
||||||
|
getChildRoutes?: (location: H.Location, cb: (error: any, childRoutes: RouteConfig) => void) => void
|
||||||
|
}
|
||||||
|
interface Route extends React.ComponentClass<RouteProps> {}
|
||||||
|
interface RouteElement extends React.ReactElement<RouteProps> {}
|
||||||
|
const Route: Route
|
||||||
|
|
||||||
|
|
||||||
|
interface PlainRoute {
|
||||||
|
path?: RoutePattern
|
||||||
|
component?: RouteComponent
|
||||||
|
components?: RouteComponents
|
||||||
|
getComponent?: (location: H.Location, cb: (error: any, component?: RouteComponent) => void) => void
|
||||||
|
getComponents?: (location: H.Location, cb: (error: any, components?: RouteComponents) => void) => void
|
||||||
|
onEnter?: EnterHook
|
||||||
|
onLeave?: LeaveHook
|
||||||
|
indexRoute?: PlainRoute
|
||||||
|
getIndexRoute?: (location: H.Location, cb: (error: any, indexRoute: RouteConfig) => void) => void
|
||||||
|
childRoutes?: PlainRoute[]
|
||||||
|
getChildRoutes?: (location: H.Location, cb: (error: any, childRoutes: RouteConfig) => void) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface RedirectProps extends React.Props<Redirect> {
|
||||||
|
path?: RoutePattern
|
||||||
|
from?: RoutePattern // alias for path
|
||||||
|
to: RoutePattern
|
||||||
|
query?: H.Query
|
||||||
|
state?: H.LocationState
|
||||||
|
}
|
||||||
|
interface Redirect extends React.ComponentClass<RedirectProps> {}
|
||||||
|
interface RedirectElement extends React.ReactElement<RedirectProps> {}
|
||||||
|
const Redirect: Redirect
|
||||||
|
|
||||||
|
|
||||||
|
interface IndexRouteProps extends React.Props<IndexRoute> {
|
||||||
|
component?: RouteComponent
|
||||||
|
components?: RouteComponents
|
||||||
|
getComponent?: (location: H.Location, cb: (error: any, component?: RouteComponent) => void) => void
|
||||||
|
getComponents?: (location: H.Location, cb: (error: any, components?: RouteComponents) => void) => void
|
||||||
|
onEnter?: EnterHook
|
||||||
|
onLeave?: LeaveHook
|
||||||
|
}
|
||||||
|
interface IndexRoute extends React.ComponentClass<IndexRouteProps> {}
|
||||||
|
interface IndexRouteElement extends React.ReactElement<IndexRouteProps> {}
|
||||||
|
const IndexRoute: IndexRoute
|
||||||
|
|
||||||
|
|
||||||
|
interface IndexRedirectProps extends React.Props<IndexRedirect> {
|
||||||
|
to: RoutePattern
|
||||||
|
query?: H.Query
|
||||||
|
state?: H.LocationState
|
||||||
|
}
|
||||||
|
interface IndexRedirect extends React.ComponentClass<IndexRedirectProps> {}
|
||||||
|
interface IndexRedirectElement extends React.ReactElement<IndexRedirectProps> {}
|
||||||
|
const IndexRedirect: IndexRedirect
|
||||||
|
|
||||||
|
|
||||||
|
/* mixins */
|
||||||
|
|
||||||
|
interface HistoryMixin {
|
||||||
|
history: History
|
||||||
|
}
|
||||||
|
const History: React.Mixin<any, any>
|
||||||
|
|
||||||
|
|
||||||
|
interface LifecycleMixin {
|
||||||
|
routerWillLeave(nextLocation: H.Location): string | boolean
|
||||||
|
}
|
||||||
|
const Lifecycle: React.Mixin<any, any>
|
||||||
|
|
||||||
|
|
||||||
|
const RouteContext: React.Mixin<any, any>
|
||||||
|
|
||||||
|
|
||||||
|
/* utils */
|
||||||
|
|
||||||
|
interface HistoryRoutes {
|
||||||
|
listen(listener: RouterListener): Function
|
||||||
|
listenBeforeLeavingRoute(route: PlainRoute, hook: RouteHook): void
|
||||||
|
match(location: H.Location, callback: (error: any, nextState: RouterState, nextLocation: H.Location) => void): void
|
||||||
|
isActive(pathname: H.Pathname, query?: H.Query, indexOnly?: boolean): boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
function useRoutes<T>(createHistory: HistoryModule.CreateHistory<T>): HistoryModule.CreateHistory<T & HistoryRoutes>
|
||||||
|
|
||||||
|
|
||||||
|
function createRoutes(routes: RouteConfig): PlainRoute[]
|
||||||
|
|
||||||
|
|
||||||
|
interface MatchArgs {
|
||||||
|
routes?: RouteConfig
|
||||||
|
history?: H.History
|
||||||
|
location?: H.Location
|
||||||
|
parseQueryString?: ParseQueryString
|
||||||
|
stringifyQuery?: StringifyQuery
|
||||||
|
}
|
||||||
|
interface MatchState extends RouterState {
|
||||||
|
history: History
|
||||||
|
}
|
||||||
|
function match(args: MatchArgs, cb: (error: any, nextLocation: H.Location, nextState: MatchState) => void): void
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router/lib/Router" {
|
||||||
|
|
||||||
|
export default ReactRouter.Router
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router/lib/Link" {
|
||||||
|
|
||||||
|
export default ReactRouter.Link
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router/lib/IndexLink" {
|
||||||
|
|
||||||
|
export default ReactRouter.IndexLink
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router/lib/IndexRedirect" {
|
||||||
|
|
||||||
|
export default ReactRouter.IndexRedirect
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router/lib/IndexRoute" {
|
||||||
|
|
||||||
|
export default ReactRouter.IndexRoute
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router/lib/Redirect" {
|
||||||
|
|
||||||
|
export default ReactRouter.Redirect
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router/lib/Route" {
|
||||||
|
|
||||||
|
export default ReactRouter.Route
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router/lib/History" {
|
||||||
|
|
||||||
|
export default ReactRouter.History
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router/lib/Lifecycle" {
|
||||||
|
|
||||||
|
export default ReactRouter.Lifecycle
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router/lib/RouteContext" {
|
||||||
|
|
||||||
|
export default ReactRouter.RouteContext
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router/lib/useRoutes" {
|
||||||
|
|
||||||
|
export default ReactRouter.useRoutes
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "react-router/lib/PatternUtils" {
|
||||||
|
|
||||||
|
export function formatPattern(pattern: string, params: {}): string;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "react-router/lib/RouteUtils" {
|
||||||
|
|
||||||
|
type E = __React.ReactElement<any>
|
||||||
|
|
||||||
|
export function isReactChildren(object: E | E[]): boolean
|
||||||
|
|
||||||
|
export function createRouteFromReactElement(element: E): ReactRouter.PlainRoute
|
||||||
|
|
||||||
|
export function createRoutesFromReactChildren(children: E | E[], parentRoute: ReactRouter.PlainRoute): ReactRouter.PlainRoute[]
|
||||||
|
|
||||||
|
export import createRoutes = ReactRouter.createRoutes
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router/lib/RouterContext" {
|
||||||
|
|
||||||
|
export default ReactRouter.RouterContext
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router/lib/PropTypes" {
|
||||||
|
|
||||||
|
import React = __React
|
||||||
|
|
||||||
|
export function falsy(props: any, propName: string, componentName: string): Error;
|
||||||
|
|
||||||
|
export const history: React.Requireable<any>
|
||||||
|
|
||||||
|
export const location: React.Requireable<any>
|
||||||
|
|
||||||
|
export const component: React.Requireable<any>
|
||||||
|
|
||||||
|
export const components: React.Requireable<any>
|
||||||
|
|
||||||
|
export const route: React.Requireable<any>
|
||||||
|
|
||||||
|
export const routes: React.Requireable<any>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
falsy,
|
||||||
|
history,
|
||||||
|
location,
|
||||||
|
component,
|
||||||
|
components,
|
||||||
|
route
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "react-router/lib/browserHistory" {
|
||||||
|
export default ReactRouter.browserHistory;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "react-router/lib/hashHistory" {
|
||||||
|
export default ReactRouter.hashHistory;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "react-router/lib/match" {
|
||||||
|
|
||||||
|
export default ReactRouter.match
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "react-router" {
|
||||||
|
|
||||||
|
import Router from "react-router/lib/Router"
|
||||||
|
|
||||||
|
import Link from "react-router/lib/Link"
|
||||||
|
|
||||||
|
import IndexLink from "react-router/lib/IndexLink"
|
||||||
|
|
||||||
|
import IndexRedirect from "react-router/lib/IndexRedirect"
|
||||||
|
|
||||||
|
import IndexRoute from "react-router/lib/IndexRoute"
|
||||||
|
|
||||||
|
import Redirect from "react-router/lib/Redirect"
|
||||||
|
|
||||||
|
import Route from "react-router/lib/Route"
|
||||||
|
|
||||||
|
import History from "react-router/lib/History"
|
||||||
|
|
||||||
|
import Lifecycle from "react-router/lib/Lifecycle"
|
||||||
|
|
||||||
|
import RouteContext from "react-router/lib/RouteContext"
|
||||||
|
|
||||||
|
import browserHistory from "react-router/lib/browserHistory"
|
||||||
|
|
||||||
|
import hashHistory from "react-router/lib/hashHistory"
|
||||||
|
|
||||||
|
import useRoutes from "react-router/lib/useRoutes"
|
||||||
|
|
||||||
|
import { createRoutes } from "react-router/lib/RouteUtils"
|
||||||
|
|
||||||
|
import { formatPattern } from "react-router/lib/PatternUtils"
|
||||||
|
|
||||||
|
import RouterContext from "react-router/lib/RouterContext"
|
||||||
|
|
||||||
|
import PropTypes from "react-router/lib/PropTypes"
|
||||||
|
|
||||||
|
import match from "react-router/lib/match"
|
||||||
|
|
||||||
|
// PlainRoute is defined in the API documented at:
|
||||||
|
// https://github.com/rackt/react-router/blob/master/docs/API.md
|
||||||
|
// but not included in any of the .../lib modules above.
|
||||||
|
export type PlainRoute = ReactRouter.PlainRoute
|
||||||
|
|
||||||
|
// The following definitions are also very useful to export
|
||||||
|
// because by using these types lots of potential type errors
|
||||||
|
// can be exposed:
|
||||||
|
export type EnterHook = ReactRouter.EnterHook
|
||||||
|
export type LeaveHook = ReactRouter.LeaveHook
|
||||||
|
export type ParseQueryString = ReactRouter.ParseQueryString
|
||||||
|
export type RedirectFunction = ReactRouter.RedirectFunction
|
||||||
|
export type RouteComponentProps<P,R> = ReactRouter.RouteComponentProps<P,R>;
|
||||||
|
export type RouteHook = ReactRouter.RouteHook
|
||||||
|
export type StringifyQuery = ReactRouter.StringifyQuery
|
||||||
|
export type RouterListener = ReactRouter.RouterListener
|
||||||
|
export type RouterState = ReactRouter.RouterState
|
||||||
|
export type HistoryBase = ReactRouter.HistoryBase
|
||||||
|
|
||||||
|
export {
|
||||||
|
Router,
|
||||||
|
Link,
|
||||||
|
IndexLink,
|
||||||
|
IndexRedirect,
|
||||||
|
IndexRoute,
|
||||||
|
Redirect,
|
||||||
|
Route,
|
||||||
|
History,
|
||||||
|
browserHistory,
|
||||||
|
hashHistory,
|
||||||
|
Lifecycle,
|
||||||
|
RouteContext,
|
||||||
|
useRoutes,
|
||||||
|
createRoutes,
|
||||||
|
formatPattern,
|
||||||
|
RouterContext,
|
||||||
|
PropTypes,
|
||||||
|
match
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Router
|
||||||
|
|
||||||
|
}
|
||||||
66
samples/react/MusicStore/typings/react/react-dom.d.ts
vendored
Normal file
66
samples/react/MusicStore/typings/react/react-dom.d.ts
vendored
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
// Type definitions for React v0.14 (react-dom)
|
||||||
|
// Project: http://facebook.github.io/react/
|
||||||
|
// Definitions by: Asana <https://asana.com>, AssureSign <http://www.assuresign.com>, Microsoft <https://microsoft.com>
|
||||||
|
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||||
|
|
||||||
|
/// <reference path="react.d.ts" />
|
||||||
|
|
||||||
|
declare namespace __React {
|
||||||
|
namespace __DOM {
|
||||||
|
function findDOMNode<E extends Element>(instance: ReactInstance): E;
|
||||||
|
function findDOMNode(instance: ReactInstance): Element;
|
||||||
|
|
||||||
|
function render<P>(
|
||||||
|
element: DOMElement<P>,
|
||||||
|
container: Element,
|
||||||
|
callback?: (element: Element) => any): Element;
|
||||||
|
function render<P, S>(
|
||||||
|
element: ClassicElement<P>,
|
||||||
|
container: Element,
|
||||||
|
callback?: (component: ClassicComponent<P, S>) => any): ClassicComponent<P, S>;
|
||||||
|
function render<P, S>(
|
||||||
|
element: ReactElement<P>,
|
||||||
|
container: Element,
|
||||||
|
callback?: (component: Component<P, S>) => any): Component<P, S>;
|
||||||
|
|
||||||
|
function unmountComponentAtNode(container: Element): boolean;
|
||||||
|
|
||||||
|
var version: string;
|
||||||
|
|
||||||
|
function unstable_batchedUpdates<A, B>(callback: (a: A, b: B) => any, a: A, b: B): void;
|
||||||
|
function unstable_batchedUpdates<A>(callback: (a: A) => any, a: A): void;
|
||||||
|
function unstable_batchedUpdates(callback: () => any): void;
|
||||||
|
|
||||||
|
function unstable_renderSubtreeIntoContainer<P>(
|
||||||
|
parentComponent: Component<any, any>,
|
||||||
|
nextElement: DOMElement<P>,
|
||||||
|
container: Element,
|
||||||
|
callback?: (element: Element) => any): Element;
|
||||||
|
function unstable_renderSubtreeIntoContainer<P, S>(
|
||||||
|
parentComponent: Component<any, any>,
|
||||||
|
nextElement: ClassicElement<P>,
|
||||||
|
container: Element,
|
||||||
|
callback?: (component: ClassicComponent<P, S>) => any): ClassicComponent<P, S>;
|
||||||
|
function unstable_renderSubtreeIntoContainer<P, S>(
|
||||||
|
parentComponent: Component<any, any>,
|
||||||
|
nextElement: ReactElement<P>,
|
||||||
|
container: Element,
|
||||||
|
callback?: (component: Component<P, S>) => any): Component<P, S>;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace __DOMServer {
|
||||||
|
function renderToString(element: ReactElement<any>): string;
|
||||||
|
function renderToStaticMarkup(element: ReactElement<any>): string;
|
||||||
|
var version: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "react-dom" {
|
||||||
|
import DOM = __React.__DOM;
|
||||||
|
export = DOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "react-dom/server" {
|
||||||
|
import DOMServer = __React.__DOMServer;
|
||||||
|
export = DOMServer;
|
||||||
|
}
|
||||||
2274
samples/react/MusicStore/typings/react/react.d.ts
vendored
Normal file
2274
samples/react/MusicStore/typings/react/react.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
18
samples/react/MusicStore/typings/redux-thunk/redux-thunk.d.ts
vendored
Normal file
18
samples/react/MusicStore/typings/redux-thunk/redux-thunk.d.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// Type definitions for redux-thunk
|
||||||
|
// Project: https://github.com/gaearon/redux-thunk
|
||||||
|
// Definitions by: Qubo <https://github.com/tkqubo>
|
||||||
|
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||||
|
|
||||||
|
/// <reference path="../redux/redux.d.ts" />
|
||||||
|
|
||||||
|
declare module ReduxThunk {
|
||||||
|
export interface Thunk extends Redux.Middleware {}
|
||||||
|
export interface ThunkInterface {
|
||||||
|
<T>(dispatch: Redux.Dispatch, getState?: () => T): any;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "redux-thunk" {
|
||||||
|
var thunk: ReduxThunk.Thunk;
|
||||||
|
export = thunk;
|
||||||
|
}
|
||||||
52
samples/react/MusicStore/typings/redux/redux.d.ts
vendored
Normal file
52
samples/react/MusicStore/typings/redux/redux.d.ts
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
// Type definitions for Redux v1.0.0
|
||||||
|
// Project: https://github.com/rackt/redux
|
||||||
|
// Definitions by: William Buchwalter <https://github.com/wbuchwalter/>, Vincent Prouillet <https://github.com/Keats/>
|
||||||
|
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||||
|
|
||||||
|
declare module Redux {
|
||||||
|
|
||||||
|
interface ActionCreator extends Function {
|
||||||
|
(...args: any[]): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Reducer extends Function {
|
||||||
|
(state: any, action: any): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Dispatch extends Function {
|
||||||
|
(action: any): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StoreMethods {
|
||||||
|
dispatch: Dispatch;
|
||||||
|
getState(): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface MiddlewareArg {
|
||||||
|
dispatch: Dispatch;
|
||||||
|
getState: Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Middleware extends Function {
|
||||||
|
(obj: MiddlewareArg): Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Store {
|
||||||
|
getReducer(): Reducer;
|
||||||
|
replaceReducer(nextReducer: Reducer): void;
|
||||||
|
dispatch(action: any): any;
|
||||||
|
getState(): any;
|
||||||
|
subscribe(listener: Function): Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createStore(reducer: Reducer, initialState?: any): Store;
|
||||||
|
function bindActionCreators<T>(actionCreators: T, dispatch: Dispatch): T;
|
||||||
|
function combineReducers(reducers: any): Reducer;
|
||||||
|
function applyMiddleware(...middlewares: Middleware[]): Function;
|
||||||
|
function compose<T extends Function>(...functions: Function[]): T;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "redux" {
|
||||||
|
export = Redux;
|
||||||
|
}
|
||||||
11
samples/react/MusicStore/typings/tsd.d.ts
vendored
Normal file
11
samples/react/MusicStore/typings/tsd.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/// <reference path="react-redux/react-redux.d.ts" />
|
||||||
|
/// <reference path="react/react-dom.d.ts" />
|
||||||
|
/// <reference path="react/react.d.ts" />
|
||||||
|
/// <reference path="redux/redux.d.ts" />
|
||||||
|
/// <reference path="webpack/webpack-env.d.ts" />
|
||||||
|
/// <reference path="react-bootstrap/react-bootstrap.d.ts" />
|
||||||
|
/// <reference path="react-router/history.d.ts" />
|
||||||
|
/// <reference path="react-router/react-router.d.ts" />
|
||||||
|
/// <reference path="react-router-bootstrap/react-router-bootstrap.d.ts" />
|
||||||
|
/// <reference path="react-router-redux/react-router-redux.d.ts" />
|
||||||
|
/// <reference path="redux-thunk/redux-thunk.d.ts" />
|
||||||
232
samples/react/MusicStore/typings/webpack/webpack-env.d.ts
vendored
Normal file
232
samples/react/MusicStore/typings/webpack/webpack-env.d.ts
vendored
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
// Type definitions for webpack 1.12.2 (module API)
|
||||||
|
// Project: https://github.com/webpack/webpack
|
||||||
|
// Definitions by: use-strict <https://github.com/use-strict>
|
||||||
|
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Webpack module API - variables and global functions available inside modules
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare namespace __WebpackModuleApi {
|
||||||
|
interface RequireContext {
|
||||||
|
keys(): string[];
|
||||||
|
<T>(id: string): T;
|
||||||
|
resolve(id: string): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RequireFunction {
|
||||||
|
/**
|
||||||
|
* Returns the exports from a dependency. The call is sync. No request to the server is fired. The compiler ensures that the dependency is available.
|
||||||
|
*/
|
||||||
|
<T>(path: string): T;
|
||||||
|
/**
|
||||||
|
* Behaves similar to require.ensure, but the callback is called with the exports of each dependency in the paths array. There is no option to provide a chunk name.
|
||||||
|
*/
|
||||||
|
(paths: string[], callback: (...modules: any[]) => void): void;
|
||||||
|
/**
|
||||||
|
* Download additional dependencies on demand. The paths array lists modules that should be available. When they are, callback is called. If the callback is a function expression, dependencies in that source part are extracted and also loaded on demand. A single request is fired to the server, except if all modules are already available.
|
||||||
|
*
|
||||||
|
* This creates a chunk. The chunk can be named. If a chunk with this name already exists, the dependencies are merged into that chunk and that chunk is used.
|
||||||
|
*/
|
||||||
|
ensure: (paths: string[], callback: (require: <T>(path: string) => T) => void, chunkName?: string) => void;
|
||||||
|
context: (path: string, deep?: boolean, filter?: RegExp) => RequireContext;
|
||||||
|
/**
|
||||||
|
* Returns the module id of a dependency. The call is sync. No request to the server is fired. The compiler ensures that the dependency is available.
|
||||||
|
*
|
||||||
|
* The module id is a number in webpack (in contrast to node.js where it is a string, the filename).
|
||||||
|
*/
|
||||||
|
resolve(path: string): number;
|
||||||
|
/**
|
||||||
|
* Like require.resolve, but doesn’t include the module into the bundle. It’s a weak dependency.
|
||||||
|
*/
|
||||||
|
resolveWeak(path: string): number;
|
||||||
|
/**
|
||||||
|
* Ensures that the dependency is available, but don’t execute it. This can be use for optimizing the position of a module in the chunks.
|
||||||
|
*/
|
||||||
|
include(path: string): void;
|
||||||
|
/**
|
||||||
|
* Multiple requires to the same module result in only one module execution and only one export. Therefore a cache in the runtime exists. Removing values from this cache cause new module execution and a new export. This is only needed in rare cases (for compatibility!).
|
||||||
|
*/
|
||||||
|
cache: {
|
||||||
|
[id: string]: any;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Module {
|
||||||
|
exports: any;
|
||||||
|
require(id: string): any;
|
||||||
|
id: string;
|
||||||
|
filename: string;
|
||||||
|
loaded: boolean;
|
||||||
|
parent: any;
|
||||||
|
children: any[];
|
||||||
|
hot: Hot;
|
||||||
|
}
|
||||||
|
type ModuleId = string|number;
|
||||||
|
|
||||||
|
interface Hot {
|
||||||
|
/**
|
||||||
|
* Accept code updates for the specified dependencies. The callback is called when dependencies were replaced.
|
||||||
|
* @param dependencies
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
accept(dependencies: string[], callback: (updatedDependencies: ModuleId[]) => void): void;
|
||||||
|
/**
|
||||||
|
* Accept code updates for the specified dependencies. The callback is called when dependencies were replaced.
|
||||||
|
* @param dependency
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
accept(dependency: string, callback: () => void): void;
|
||||||
|
/**
|
||||||
|
* Accept code updates for this module without notification of parents.
|
||||||
|
* This should only be used if the module doesn’t export anything.
|
||||||
|
* The errHandler can be used to handle errors that occur while loading the updated module.
|
||||||
|
* @param errHandler
|
||||||
|
*/
|
||||||
|
accept(errHandler?: (err: Error) => void): void;
|
||||||
|
/**
|
||||||
|
* Do not accept updates for the specified dependencies. If any dependencies is updated, the code update fails with code "decline".
|
||||||
|
*/
|
||||||
|
decline(dependencies: string[]): void;
|
||||||
|
/**
|
||||||
|
* Do not accept updates for the specified dependencies. If any dependencies is updated, the code update fails with code "decline".
|
||||||
|
*/
|
||||||
|
decline(dependency: string): void;
|
||||||
|
/**
|
||||||
|
* Flag the current module as not update-able. If updated the update code would fail with code "decline".
|
||||||
|
*/
|
||||||
|
decline(): void;
|
||||||
|
/**
|
||||||
|
* Add a one time handler, which is executed when the current module code is replaced.
|
||||||
|
* Here you should destroy/remove any persistent resource you have claimed/created.
|
||||||
|
* If you want to transfer state to the new module, add it to data object.
|
||||||
|
* The data will be available at module.hot.data on the new module.
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
dispose<T>(callback: (data: T) => void): void;
|
||||||
|
/**
|
||||||
|
* Add a one time handler, which is executed when the current module code is replaced.
|
||||||
|
* Here you should destroy/remove any persistent resource you have claimed/created.
|
||||||
|
* If you want to transfer state to the new module, add it to data object.
|
||||||
|
* The data will be available at module.hot.data on the new module.
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
addDisposeHandler<T>(callback: (data: T) => void): void;
|
||||||
|
/**
|
||||||
|
* Remove a handler.
|
||||||
|
* This can useful to add a temporary dispose handler. You could i. e. replace code while in the middle of a multi-step async function.
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
removeDisposeHandler<T>(callback: (data: T) => void): void;
|
||||||
|
/**
|
||||||
|
* Throws an exceptions if status() is not idle.
|
||||||
|
* Check all currently loaded modules for updates and apply updates if found.
|
||||||
|
* If no update was found, the callback is called with null.
|
||||||
|
* If autoApply is truthy the callback will be called with all modules that were disposed.
|
||||||
|
* apply() is automatically called with autoApply as options parameter.
|
||||||
|
* If autoApply is not set the callback will be called with all modules that will be disposed on apply().
|
||||||
|
* @param autoApply
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
check(autoApply: boolean, callback: (err: Error, outdatedModules: ModuleId[]) => void): void;
|
||||||
|
/**
|
||||||
|
* Throws an exceptions if status() is not idle.
|
||||||
|
* Check all currently loaded modules for updates and apply updates if found.
|
||||||
|
* If no update was found, the callback is called with null.
|
||||||
|
* The callback will be called with all modules that will be disposed on apply().
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
check(callback: (err: Error, outdatedModules: ModuleId[]) => void): void;
|
||||||
|
/**
|
||||||
|
* If status() != "ready" it throws an error.
|
||||||
|
* Continue the update process.
|
||||||
|
* @param options
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
apply(options: AcceptOptions, callback: (err: Error, outdatedModules: ModuleId[]) => void): void;
|
||||||
|
/**
|
||||||
|
* If status() != "ready" it throws an error.
|
||||||
|
* Continue the update process.
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
apply(callback: (err: Error, outdatedModules: ModuleId[]) => void): void;
|
||||||
|
/**
|
||||||
|
* Return one of idle, check, watch, watch-delay, prepare, ready, dispose, apply, abort or fail.
|
||||||
|
*/
|
||||||
|
status(): string;
|
||||||
|
/** Register a callback on status change. */
|
||||||
|
status(callback: (status: string) => void): void;
|
||||||
|
/** Register a callback on status change. */
|
||||||
|
addStatusHandler(callback: (status: string) => void): void;
|
||||||
|
/**
|
||||||
|
* Remove a registered status change handler.
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
removeStatusHandler(callback: (status: string) => void): void;
|
||||||
|
|
||||||
|
active: boolean;
|
||||||
|
data: {};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AcceptOptions {
|
||||||
|
/**
|
||||||
|
* If true the update process continues even if some modules are not accepted (and would bubble to the entry point).
|
||||||
|
*/
|
||||||
|
ignoreUnaccepted?: boolean;
|
||||||
|
/**
|
||||||
|
* Indicates that apply() is automatically called by check function
|
||||||
|
*/
|
||||||
|
autoApply?: boolean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare var require: __WebpackModuleApi.RequireFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resource query of the current module.
|
||||||
|
*
|
||||||
|
* e.g. __resourceQuery === "?test" // Inside "file.js?test"
|
||||||
|
*/
|
||||||
|
declare var __resourceQuery: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Equals the config options output.publicPath.
|
||||||
|
*/
|
||||||
|
declare var __webpack_public_path__: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The raw require function. This expression isn’t parsed by the Parser for dependencies.
|
||||||
|
*/
|
||||||
|
declare var __webpack_require__: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The internal chunk loading function
|
||||||
|
*
|
||||||
|
* @param chunkId The id for the chunk to load.
|
||||||
|
* @param callback A callback function called once the chunk is loaded.
|
||||||
|
*/
|
||||||
|
declare var __webpack_chunk_load__: (chunkId: any, callback: (require: (id: string) => any) => void) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access to the internal object of all modules.
|
||||||
|
*/
|
||||||
|
declare var __webpack_modules__: any[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access to the hash of the compilation.
|
||||||
|
*
|
||||||
|
* Only available with the HotModuleReplacementPlugin or the ExtendedAPIPlugin
|
||||||
|
*/
|
||||||
|
declare var __webpack_hash__: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a require function that is not parsed by webpack. Can be used to do cool stuff with a global require function if available.
|
||||||
|
*/
|
||||||
|
declare var __non_webpack_require__: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Equals the config option debug
|
||||||
|
*/
|
||||||
|
declare var DEBUG: boolean;
|
||||||
|
|
||||||
|
declare var module: __WebpackModuleApi.Module;
|
||||||
30
samples/react/MusicStore/webpack.config.js
Normal file
30
samples/react/MusicStore/webpack.config.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
var path = require('path');
|
||||||
|
var webpack = require('webpack');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
devtool: 'inline-source-map',
|
||||||
|
resolve: {
|
||||||
|
extensions: [ '', '.js', '.jsx', '.ts', '.tsx' ]
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
loaders: [
|
||||||
|
{ test: /\.ts(x?)$/, include: /ReactApp/, exclude: /node_modules/, loader: 'babel-loader' },
|
||||||
|
{ test: /\.ts(x?)$/, include: /ReactApp/, exclude: /node_modules/, loader: 'ts-loader' },
|
||||||
|
{ test: /\.css$/, loader: "style-loader!css-loader" },
|
||||||
|
{ test: /\.(png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
entry: {
|
||||||
|
main: ['./ReactApp/boot.tsx'],
|
||||||
|
vendor: ['react']
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
path: path.join(__dirname, 'wwwroot', 'dist'),
|
||||||
|
filename: '[name].js',
|
||||||
|
publicPath: '/dist/'
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.optimize.OccurenceOrderPlugin(),
|
||||||
|
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js') // Moves vendor content out of other bundles
|
||||||
|
]
|
||||||
|
};
|
||||||
BIN
samples/react/MusicStore/wwwroot/favicon.ico
Executable file
BIN
samples/react/MusicStore/wwwroot/favicon.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
BIN
samples/react/MusicStore/wwwroot/images/home-showcase.png
Normal file
BIN
samples/react/MusicStore/wwwroot/images/home-showcase.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 248 KiB |
BIN
samples/react/MusicStore/wwwroot/images/logo.png
Normal file
BIN
samples/react/MusicStore/wwwroot/images/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
BIN
samples/react/MusicStore/wwwroot/images/placeholder.png
Normal file
BIN
samples/react/MusicStore/wwwroot/images/placeholder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
9
samples/react/MusicStore/wwwroot/web.config
Normal file
9
samples/react/MusicStore/wwwroot/web.config
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<system.webServer>
|
||||||
|
<handlers>
|
||||||
|
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
|
||||||
|
</handlers>
|
||||||
|
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false"/>
|
||||||
|
</system.webServer>
|
||||||
|
</configuration>
|
||||||
@@ -20,8 +20,7 @@ module.exports = {
|
|||||||
if (enableHotModuleReplacement) {
|
if (enableHotModuleReplacement) {
|
||||||
webpackConfig.entry.main.unshift('webpack-hot-middleware/client');
|
webpackConfig.entry.main.unshift('webpack-hot-middleware/client');
|
||||||
webpackConfig.plugins.push(
|
webpackConfig.plugins.push(
|
||||||
new webpack.HotModuleReplacementPlugin(),
|
new webpack.HotModuleReplacementPlugin()
|
||||||
new webpack.NoErrorsPlugin()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (enableReactHotModuleReplacement) {
|
if (enableReactHotModuleReplacement) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.NodeServices;
|
using Microsoft.AspNet.NodeServices;
|
||||||
using Microsoft.AspNet.Proxy;
|
using Microsoft.AspNet.Proxy;
|
||||||
using Microsoft.AspNet.SpaServices;
|
using Microsoft.AspNet.SpaServices;
|
||||||
@@ -52,11 +53,15 @@ namespace Microsoft.AspNet.Builder
|
|||||||
Port = devServerInfo.Port.ToString()
|
Port = devServerInfo.Port.ToString()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// While it would be nice to proxy the /__webpack_hmr requests too, these return an EventStream,
|
||||||
|
// and the Microsoft.Aspnet.Proxy code doesn't handle that entirely - it throws an exception after
|
||||||
|
// a while. So, just serve a 302 for those.
|
||||||
appBuilder.Map(WebpackHotMiddlewareEndpoint, builder => {
|
appBuilder.Map(WebpackHotMiddlewareEndpoint, builder => {
|
||||||
builder.RunProxy(new ProxyOptions {
|
builder.Use(next => async ctx => {
|
||||||
Host = WebpackDevMiddlewareHostname,
|
ctx.Response.Redirect($"http://localhost:{ devServerInfo.Port.ToString() }{ WebpackHotMiddlewareEndpoint }");
|
||||||
Port = devServerInfo.Port.ToString()
|
await Task.Yield();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user