just getting it her
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
[
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Nirvana",
|
||||
"title": "Nevermind",
|
||||
"releaseYear": "1991",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "The Beach Boys",
|
||||
"title": "Pet Sounds",
|
||||
"releaseYear": "1966",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Marvin Gaye",
|
||||
"title": "What's Going On",
|
||||
"releaseYear": "1971",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Jimi Hendrix Experience",
|
||||
"title": "Are You Experienced?",
|
||||
"releaseYear": "1967",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "U2",
|
||||
"title": "The Joshua Tree",
|
||||
"releaseYear": "1987",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "The Beatles",
|
||||
"title": "Abbey Road",
|
||||
"releaseYear": "1969",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Fleetwood Mac",
|
||||
"title": "Rumours",
|
||||
"releaseYear": "1977",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Elvis Presley",
|
||||
"title": "Sun Sessions",
|
||||
"releaseYear": "1976",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Michael Jackson",
|
||||
"title": "Thriller",
|
||||
"releaseYear": "1982",
|
||||
"genre": "Pop"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "The Rolling Stones",
|
||||
"title": "Exile on Main Street",
|
||||
"releaseYear": "1972",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Bruce Springsteen",
|
||||
"title": "Born to Run",
|
||||
"releaseYear": "1975",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "The Clash",
|
||||
"title": "London Calling",
|
||||
"releaseYear": "1980",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "The Eagles",
|
||||
"title": "Hotel California",
|
||||
"releaseYear": "1976",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Led Zeppelin",
|
||||
"title": "Led Zeppelin",
|
||||
"releaseYear": "1969",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Led Zeppelin",
|
||||
"title": "IV",
|
||||
"releaseYear": "1971",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Police",
|
||||
"title": "Synchronicity",
|
||||
"releaseYear": "1983",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "U2",
|
||||
"title": "Achtung Baby",
|
||||
"releaseYear": "1991",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "The Rolling Stones",
|
||||
"title": "Let it Bleed",
|
||||
"releaseYear": "1969",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "The Beatles",
|
||||
"title": "Rubber Soul",
|
||||
"releaseYear": "1965",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "The Ramones",
|
||||
"title": "The Ramones",
|
||||
"releaseYear": "1976",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Queen",
|
||||
"title": "A Night At The Opera",
|
||||
"releaseYear": "1975",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Boston",
|
||||
"title": "Don't Look Back",
|
||||
"releaseYear": "1978",
|
||||
"genre": "Rock"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "BB King",
|
||||
"title": "Singin' The Blues",
|
||||
"releaseYear": "1956",
|
||||
"genre": "Blues"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Albert King",
|
||||
"title": "Born Under A Bad Sign",
|
||||
"releaseYear": "1967",
|
||||
"genre": "Blues"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Muddy Waters",
|
||||
"title": "Folk Singer",
|
||||
"releaseYear": "1964",
|
||||
"genre": "Blues"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "The Fabulous Thunderbirds",
|
||||
"title": "Rock With Me",
|
||||
"releaseYear": "1979",
|
||||
"genre": "Blues"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Robert Johnson",
|
||||
"title": "King of the Delta Blues",
|
||||
"releaseYear": "1961",
|
||||
"genre": "Blues"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Stevie Ray Vaughan",
|
||||
"title": "Texas Flood",
|
||||
"releaseYear": "1983",
|
||||
"genre": "Blues"
|
||||
},
|
||||
{
|
||||
"_class": "org.cloudfoundry.samples.music.domain.Album",
|
||||
"artist": "Stevie Ray Vaughan",
|
||||
"title": "Couldn't Stand The Weather",
|
||||
"releaseYear": "1984",
|
||||
"genre": "Blues"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,52 @@
|
||||
spring:
|
||||
jpa:
|
||||
generate-ddl: true
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: "*"
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
|
||||
---
|
||||
spring:
|
||||
config:
|
||||
activate:
|
||||
on-profile: http2
|
||||
|
||||
server:
|
||||
http2:
|
||||
enabled: true
|
||||
|
||||
---
|
||||
spring:
|
||||
config:
|
||||
activate:
|
||||
on-profile: mysql
|
||||
datasource:
|
||||
url: "jdbc:mysql://localhost/music"
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username:
|
||||
password:
|
||||
jpa:
|
||||
properties:
|
||||
hibernate:
|
||||
dialect: org.hibernate.dialect.MySQL55Dialect
|
||||
|
||||
---
|
||||
spring:
|
||||
config:
|
||||
activate:
|
||||
on-profile: postgres
|
||||
datasource:
|
||||
url: "jdbc:postgresql://localhost/music"
|
||||
driver-class-name: org.postgresql.Driver
|
||||
username: postgres
|
||||
password:
|
||||
jpa:
|
||||
properties:
|
||||
hibernate:
|
||||
dialect: org.hibernate.dialect.ProgressDialect
|
||||
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,35 @@
|
||||
#body {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: white;
|
||||
border: 0;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.navbar .container {
|
||||
background-color: #008a00;
|
||||
background-image: -moz-linear-gradient(top, #008a00, #006b00);
|
||||
background-image: -ms-linear-gradient(top, #008a00, #006b00);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#008a00), to(#006b00));
|
||||
background-image: -webkit-linear-gradient(top, #008a00, #006b00);
|
||||
background-image: -o-linear-gradient(top, #008a00, #006b00);
|
||||
background-image: linear-gradient(top, #008a00, #006b00);
|
||||
}
|
||||
|
||||
.navbar .navbar-brand {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.navbar .navbar-brand:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.icon-white {
|
||||
color: white;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/* From https://github.com/sixfootsixdesigns/Bootstrap-3-Grid-Columns-Clearing */
|
||||
|
||||
/* clear first in row in ie 8 or lower */
|
||||
.multi-columns-row .first-in-row {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
/* clear the first in row for any block that has the class "multi-columns-row" */
|
||||
.multi-columns-row .col-xs-6:nth-child(2n + 3) { clear: left; }
|
||||
.multi-columns-row .col-xs-4:nth-child(3n + 4) { clear: left; }
|
||||
.multi-columns-row .col-xs-3:nth-child(4n + 5) { clear: left; }
|
||||
.multi-columns-row .col-xs-2:nth-child(6n + 7) { clear: left; }
|
||||
.multi-columns-row .col-xs-1:nth-child(12n + 13) { clear: left; }
|
||||
|
||||
@media (min-width: 768px) {
|
||||
/* reset previous grid */
|
||||
.multi-columns-row .col-xs-6:nth-child(2n + 3) { clear: none; }
|
||||
.multi-columns-row .col-xs-4:nth-child(3n + 4) { clear: none; }
|
||||
.multi-columns-row .col-xs-3:nth-child(4n + 5) { clear: none; }
|
||||
.multi-columns-row .col-xs-2:nth-child(6n + 7) { clear: none; }
|
||||
.multi-columns-row .col-xs-1:nth-child(12n + 13) { clear: none; }
|
||||
|
||||
/* clear first in row for small columns */
|
||||
.multi-columns-row .col-sm-6:nth-child(2n + 3) { clear: left; }
|
||||
.multi-columns-row .col-sm-4:nth-child(3n + 4) { clear: left; }
|
||||
.multi-columns-row .col-sm-3:nth-child(4n + 5) { clear: left; }
|
||||
.multi-columns-row .col-sm-2:nth-child(6n + 7) { clear: left; }
|
||||
.multi-columns-row .col-sm-1:nth-child(12n + 13) { clear: left; }
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
/* reset previous grid */
|
||||
.multi-columns-row .col-sm-6:nth-child(2n + 3) { clear: none; }
|
||||
.multi-columns-row .col-sm-4:nth-child(3n + 4) { clear: none; }
|
||||
.multi-columns-row .col-sm-3:nth-child(4n + 5) { clear: none; }
|
||||
.multi-columns-row .col-sm-2:nth-child(6n + 7) { clear: none; }
|
||||
.multi-columns-row .col-sm-1:nth-child(12n + 13) { clear: none; }
|
||||
|
||||
/* clear first in row for medium columns */
|
||||
.multi-columns-row .col-md-6:nth-child(2n + 3) { clear: left; }
|
||||
.multi-columns-row .col-md-4:nth-child(3n + 4) { clear: left; }
|
||||
.multi-columns-row .col-md-3:nth-child(4n + 5) { clear: left; }
|
||||
.multi-columns-row .col-md-2:nth-child(6n + 7) { clear: left; }
|
||||
.multi-columns-row .col-md-1:nth-child(12n + 13) { clear: left; }
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
/* reset previous grid */
|
||||
.multi-columns-row .col-md-6:nth-child(2n + 3) { clear: none; }
|
||||
.multi-columns-row .col-md-4:nth-child(3n + 4) { clear: none; }
|
||||
.multi-columns-row .col-md-3:nth-child(4n + 5) { clear: none; }
|
||||
.multi-columns-row .col-md-2:nth-child(6n + 7) { clear: none; }
|
||||
.multi-columns-row .col-md-1:nth-child(12n + 13) { clear: none; }
|
||||
|
||||
/* clear first in row for large columns */
|
||||
.multi-columns-row .col-lg-6:nth-child(2n + 3) { clear: left; }
|
||||
.multi-columns-row .col-lg-4:nth-child(3n + 4) { clear: left; }
|
||||
.multi-columns-row .col-lg-3:nth-child(4n + 5) { clear: left; }
|
||||
.multi-columns-row .col-lg-2:nth-child(6n + 7) { clear: left; }
|
||||
.multi-columns-row .col-lg-1:nth-child(12n + 13) { clear: left; }
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,47 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="en" ng-app="SpringMusic">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="description" content="Spring Music">
|
||||
<meta name="title" content="Spring Music">
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
<title>Spring Music</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="webjars/bootstrap/3.1.1/css/bootstrap.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/app.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/multi-columns-row.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div ng-include="'templates/header.html'"></div>
|
||||
</div>
|
||||
|
||||
<div id="body" class="row">
|
||||
<ng-view></ng-view>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div ng-include="'templates/footer.html'"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="webjars/jquery/2.1.0/jquery.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="webjars/angularjs/1.2.16/angular.js"></script>
|
||||
<script type="text/javascript" src="webjars/angularjs/1.2.16/angular-resource.js"></script>
|
||||
<script type="text/javascript" src="webjars/angularjs/1.2.16/angular-route.js"></script>
|
||||
<script type="text/javascript" src="webjars/angular-ui/0.4.0/angular-ui.js"></script>
|
||||
<script type="text/javascript" src="webjars/angular-ui-bootstrap/0.10.0/ui-bootstrap.js"></script>
|
||||
<script type="text/javascript" src="webjars/angular-ui-bootstrap/0.10.0/ui-bootstrap-tpls.js"></script>
|
||||
|
||||
<script type="text/javascript" src="webjars/bootstrap/3.1.1/js/bootstrap.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/app.js"></script>
|
||||
<script type="text/javascript" src="js/albums.js"></script>
|
||||
<script type="text/javascript" src="js/errors.js"></script>
|
||||
<script type="text/javascript" src="js/info.js"></script>
|
||||
<script type="text/javascript" src="js/status.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,199 @@
|
||||
angular.module('albums', ['ngResource', 'ui.bootstrap']).
|
||||
factory('Albums', function ($resource) {
|
||||
return $resource('albums');
|
||||
}).
|
||||
factory('Album', function ($resource) {
|
||||
return $resource('albums/:id', {id: '@id'});
|
||||
}).
|
||||
factory("EditorStatus", function () {
|
||||
var editorEnabled = {};
|
||||
|
||||
var enable = function (id, fieldName) {
|
||||
editorEnabled = { 'id': id, 'fieldName': fieldName };
|
||||
};
|
||||
|
||||
var disable = function () {
|
||||
editorEnabled = {};
|
||||
};
|
||||
|
||||
var isEnabled = function(id, fieldName) {
|
||||
return (editorEnabled['id'] == id && editorEnabled['fieldName'] == fieldName);
|
||||
};
|
||||
|
||||
return {
|
||||
isEnabled: isEnabled,
|
||||
enable: enable,
|
||||
disable: disable
|
||||
}
|
||||
});
|
||||
|
||||
function AlbumsController($scope, $modal, Albums, Album, Status) {
|
||||
function list() {
|
||||
$scope.albums = Albums.query();
|
||||
}
|
||||
|
||||
function clone (obj) {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
function saveAlbum(album) {
|
||||
Albums.save(album,
|
||||
function () {
|
||||
Status.success("Album saved");
|
||||
list();
|
||||
},
|
||||
function (result) {
|
||||
Status.error("Error saving album: " + result.status);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$scope.addAlbum = function () {
|
||||
var addModal = $modal.open({
|
||||
templateUrl: 'templates/albumForm.html',
|
||||
controller: AlbumModalController,
|
||||
resolve: {
|
||||
album: function () {
|
||||
return {};
|
||||
},
|
||||
action: function() {
|
||||
return 'add';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
addModal.result.then(function (album) {
|
||||
saveAlbum(album);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.updateAlbum = function (album) {
|
||||
var updateModal = $modal.open({
|
||||
templateUrl: 'templates/albumForm.html',
|
||||
controller: AlbumModalController,
|
||||
resolve: {
|
||||
album: function() {
|
||||
return clone(album);
|
||||
},
|
||||
action: function() {
|
||||
return 'update';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
updateModal.result.then(function (album) {
|
||||
saveAlbum(album);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.deleteAlbum = function (album) {
|
||||
Album.delete({id: album.id},
|
||||
function () {
|
||||
Status.success("Album deleted");
|
||||
list();
|
||||
},
|
||||
function (result) {
|
||||
Status.error("Error deleting album: " + result.status);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
$scope.setAlbumsView = function (viewName) {
|
||||
$scope.albumsView = "templates/" + viewName + ".html";
|
||||
};
|
||||
|
||||
$scope.init = function() {
|
||||
list();
|
||||
$scope.setAlbumsView("grid");
|
||||
$scope.sortField = "name";
|
||||
$scope.sortDescending = false;
|
||||
};
|
||||
}
|
||||
|
||||
function AlbumModalController($scope, $modalInstance, album, action) {
|
||||
$scope.albumAction = action;
|
||||
$scope.yearPattern = /^[1-2]\d{3}$/;
|
||||
$scope.album = album;
|
||||
|
||||
$scope.ok = function () {
|
||||
$modalInstance.close($scope.album);
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
};
|
||||
|
||||
function AlbumEditorController($scope, Albums, Status, EditorStatus) {
|
||||
$scope.enableEditor = function (album, fieldName) {
|
||||
$scope.newFieldValue = album[fieldName];
|
||||
EditorStatus.enable(album.id, fieldName);
|
||||
};
|
||||
|
||||
$scope.disableEditor = function () {
|
||||
EditorStatus.disable();
|
||||
};
|
||||
|
||||
$scope.isEditorEnabled = function (album, fieldName) {
|
||||
return EditorStatus.isEnabled(album.id, fieldName);
|
||||
};
|
||||
|
||||
$scope.save = function (album, fieldName) {
|
||||
if ($scope.newFieldValue === "") {
|
||||
return false;
|
||||
}
|
||||
|
||||
album[fieldName] = $scope.newFieldValue;
|
||||
|
||||
Albums.save({}, album,
|
||||
function () {
|
||||
Status.success("Album saved");
|
||||
list();
|
||||
},
|
||||
function (result) {
|
||||
Status.error("Error saving album: " + result.status);
|
||||
}
|
||||
);
|
||||
|
||||
$scope.disableEditor();
|
||||
};
|
||||
|
||||
$scope.disableEditor();
|
||||
}
|
||||
|
||||
angular.module('albums').
|
||||
directive('inPlaceEdit', function () {
|
||||
return {
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
replace: true,
|
||||
|
||||
scope: {
|
||||
ipeFieldName: '@fieldName',
|
||||
ipeInputType: '@inputType',
|
||||
ipeInputClass: '@inputClass',
|
||||
ipePattern: '@pattern',
|
||||
ipeModel: '=model'
|
||||
},
|
||||
|
||||
template:
|
||||
'<div>' +
|
||||
'<span ng-hide="isEditorEnabled(ipeModel, ipeFieldName)" ng-click="enableEditor(ipeModel, ipeFieldName)">' +
|
||||
'<span ng-transclude></span>' +
|
||||
'</span>' +
|
||||
'<span ng-show="isEditorEnabled(ipeModel, ipeFieldName)">' +
|
||||
'<div class="input-append">' +
|
||||
'<input type="{{ipeInputType}}" name="{{ipeFieldName}}" class="{{ipeInputClass}}" ' +
|
||||
'ng-required ng-pattern="{{ipePattern}}" ng-model="newFieldValue" ' +
|
||||
'ui-keyup="{enter: \'save(ipeModel, ipeFieldName)\', esc: \'disableEditor()\'}"/>' +
|
||||
'<div class="btn-group btn-group-xs" role="toolbar">' +
|
||||
'<button ng-click="save(ipeModel, ipeFieldName)" type="button" class="btn"><span class="glyphicon glyphicon-ok"></span></button>' +
|
||||
'<button ng-click="disableEditor()" type="button" class="btn"><span class="glyphicon glyphicon-remove"></span></button>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</span>' +
|
||||
'</div>',
|
||||
|
||||
controller: 'AlbumEditorController'
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
angular.module('SpringMusic', ['albums', 'errors', 'status', 'info', 'ngRoute', 'ui.directives']).
|
||||
config(function ($locationProvider, $routeProvider) {
|
||||
// $locationProvider.html5Mode(true);
|
||||
|
||||
$routeProvider.when('/errors', {
|
||||
controller: 'ErrorsController',
|
||||
templateUrl: 'templates/errors.html'
|
||||
});
|
||||
$routeProvider.otherwise({
|
||||
controller: 'AlbumsController',
|
||||
templateUrl: 'templates/albums.html'
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,37 @@
|
||||
angular.module('errors', ['ngResource']).
|
||||
factory('Errors', function ($resource) {
|
||||
return $resource('errors', {}, {
|
||||
kill: { url: 'errors/kill' },
|
||||
throw: { url: 'errors/throw' }
|
||||
});
|
||||
});
|
||||
|
||||
function ErrorsController($scope, Errors, Status) {
|
||||
$scope.kill = function() {
|
||||
Errors.kill({},
|
||||
function () {
|
||||
Status.error("The application should have been killed, but returned successfully instead.");
|
||||
},
|
||||
function (result) {
|
||||
if (result.status === 502)
|
||||
Status.error("An error occurred as expected, the application backend was killed: " + result.status);
|
||||
else
|
||||
Status.error("An unexpected error occurred: " + result.status);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
$scope.throwException = function() {
|
||||
Errors.throw({},
|
||||
function () {
|
||||
Status.error("An exception should have been thrown, but was not.");
|
||||
},
|
||||
function (result) {
|
||||
if (result.status === 500)
|
||||
Status.error("An error occurred as expected: " + result.status);
|
||||
else
|
||||
Status.error("An unexpected error occurred: " + result.status);
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
angular.module('info', ['ngResource']).
|
||||
factory('Info', function ($resource) {
|
||||
return $resource('appinfo');
|
||||
});
|
||||
|
||||
function InfoController($scope, Info) {
|
||||
$scope.info = Info.get();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
angular.module('status', []).
|
||||
factory("Status", function () {
|
||||
var status = null;
|
||||
|
||||
var success = function (message) {
|
||||
this.status = { isError: false, message: message };
|
||||
};
|
||||
|
||||
var error = function (message) {
|
||||
this.status = { isError: true, message: message };
|
||||
};
|
||||
|
||||
var clear = function () {
|
||||
this.status = null;
|
||||
};
|
||||
|
||||
return {
|
||||
status: status,
|
||||
success: success,
|
||||
error: error,
|
||||
clear: clear
|
||||
}
|
||||
});
|
||||
|
||||
function StatusController($scope, Status) {
|
||||
$scope.$watch(
|
||||
function () {
|
||||
return Status.status;
|
||||
},
|
||||
function (status) {
|
||||
$scope.status = status;
|
||||
},
|
||||
true);
|
||||
|
||||
$scope.clearStatus = function () {
|
||||
Status.clear();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<div class="modal-header">
|
||||
<h3 ng-show="albumAction === 'add'">Add an album</h3>
|
||||
<h3 ng-show="albumAction === 'update'">Edit an album</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form name="albumForm" role="form">
|
||||
<div class="form-group has-feedback" ng-class="{'has-warning': albumForm.title.$invalid, 'has-success': albumForm.title.$valid}">
|
||||
<label for="title">Album Title</label>
|
||||
<input type="text" class="form-control input-large" id="title" name="title" required ng-model="album.title">
|
||||
<span class="glyphicon form-control-feedback" ng-class="{'glyphicon-warning-sign': albumForm.title.$invalid, 'glyphicon-ok': albumForm.title.$valid}"></span>
|
||||
</div>
|
||||
<div class="form-group has-feedback" ng-class="{'has-warning': albumForm.artist.$invalid, 'has-success': albumForm.artist.$valid}">
|
||||
<label for="artist">Artist</label>
|
||||
<input type="text" class="form-control input-large" id="artist" name="artist" required ng-model="album.artist">
|
||||
<span class="glyphicon form-control-feedback" ng-class="{'glyphicon-warning-sign': albumForm.artist.$invalid, 'glyphicon-ok': albumForm.artist.$valid}"></span>
|
||||
</div>
|
||||
<div class="form-group has-feedback" ng-class="{'has-warning': albumForm.releaseYear.$invalid, 'has-success': albumForm.releaseYear.$valid}">
|
||||
<label for="releaseYear">Release Year</label>
|
||||
<input type="text" class="form-control input-small" id="releaseYear" name="releaseYear" required ng-model="album.releaseYear" ng-pattern=yearPattern>
|
||||
<span class="glyphicon form-control-feedback" ng-class="{'glyphicon-warning-sign': albumForm.releaseYear.$invalid, 'glyphicon-ok': albumForm.releaseYear.$valid}"></span>
|
||||
</div>
|
||||
<div class="form-group has-feedback" ng-class="{'has-warning': albumForm.genre.$invalid, 'has-success': albumForm.genre.$valid}">
|
||||
<label for="genre">Genre</label>
|
||||
<input type="text" class="form-control input-medium" id=genre name="genre" required ng-model="album.genre">
|
||||
<span class="glyphicon form-control-feedback" ng-class="{'glyphicon-warning-sign': albumForm.genre.$invalid, 'glyphicon-ok': albumForm.genre.$valid}"></span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary btn-md active" ng-disabled="albumForm.$invalid" ng-click="ok()" >OK</button>
|
||||
<button class="btn btn-warning btn-md active" ng-click="cancel()">Cancel</button>
|
||||
</div>
|
||||
@@ -0,0 +1,29 @@
|
||||
<div id="albums" ng-init="init()">
|
||||
<div class="page-header">
|
||||
<h1>Albums</h1>
|
||||
<div>
|
||||
<span> [ view as: </span>
|
||||
<a href="" ng-click="setAlbumsView('grid')"><span class="glyphicon glyphicon-th"></span></a>
|
||||
<a href="" ng-click="setAlbumsView('list')"><span class="glyphicon glyphicon-th-list"></span></a>
|
||||
<span> | sort by: </span>
|
||||
<a href="" ng-click="sortField='title'">title</a>
|
||||
<a href="" ng-click="sortField='artist'">artist</a>
|
||||
<a href="" ng-click="sortField='releaseYear'">year</a>
|
||||
<a href="" ng-click="sortField='genre'">genre</a>
|
||||
<a href="" ng-click="sortDescending=!sortDescending">
|
||||
<span class="glyphicon" ng-class="{'glyphicon-chevron-up' : !sortDescending, 'glyphicon-chevron-down' : sortDescending}"></span>
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="" ng-click="addAlbum()"><span class="glyphicon glyphicon-plus"></span>add an album</a>
|
||||
<span> ] </span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div ng-include src="'templates/status.html'"></div>
|
||||
</div>
|
||||
|
||||
<div class="row multi-columns-row">
|
||||
<div ng-include src="albumsView"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,22 @@
|
||||
<div id="errors" class="col-xs-12" ng-controller="ErrorsController">
|
||||
<div class="page-header">
|
||||
<h1>Force Errors</h1>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div ng-include src="'templates/status.html'"></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<form role="form">
|
||||
<div class="form-group">
|
||||
<h3>Kill this instance of the application</h3>
|
||||
<a ng-click="kill()" class="btn btn-primary btn-lg active" role="button">Kill</a>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<h3>Force an exception to be thrown from the application</h3>
|
||||
<a ng-click="throwException()" class="btn btn-primary btn-lg active" role="button">Throw Exception</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div id="footer" class="row">
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,31 @@
|
||||
<div class="col-xs-6 col-sm-3 col-md-3 col-lg-3" ng-repeat="album in albums | orderBy:sortField:sortDescending">
|
||||
<div class="thumbnail">
|
||||
<div class="caption">
|
||||
<h4>
|
||||
<in-place-edit field-name='title' input-type='text' input-class='input-medium' model=album>{{album.title}}</in-place-edit>
|
||||
</h4>
|
||||
|
||||
<h4>
|
||||
<in-place-edit field-name='artist' input-type='text' input-class='input-medium' model=album>{{album.artist}}</in-place-edit>
|
||||
</h4>
|
||||
|
||||
<h5>
|
||||
<in-place-edit field-name='releaseYear' input-type='text' input-class='input-small' model=album>{{album.releaseYear}}</in-place-edit>
|
||||
</h5>
|
||||
|
||||
<h5>
|
||||
<in-place-edit field-name='genre' input-type='text' input-class='input-small' model=album>{{album.genre}}</in-place-edit>
|
||||
</h5>
|
||||
|
||||
<div class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="glyphicon glyphicon-cog"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
|
||||
<li role="presentation"><a ng-click="updateAlbum(album)">edit</a></li>
|
||||
<li role="presentation"><a ng-click="deleteAlbum(album)">delete</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,24 @@
|
||||
<div id="header" ng-controller="InfoController" class="col-xs-12">
|
||||
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="#">Spring Music <span class="glyphicon glyphicon-music"></span></a>
|
||||
<ul class="navbar-nav">
|
||||
<!--<li></li>-->
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="glyphicon glyphicon-info-sign icon-white"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a><strong>Profiles:</strong> {{info.profiles.join()}}</a></li>
|
||||
<li><a><strong>Services:</strong> {{info.services.join()}}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
@@ -0,0 +1,38 @@
|
||||
<div class="col-xs-12">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Album Title</th>
|
||||
<th>Artist</th>
|
||||
<th>Year</th>
|
||||
<th>Genre</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="album in albums | orderBy:sortField:sortDescending">
|
||||
<td>
|
||||
<in-place-edit field-name='title' input-type='text' input-class='input-large' model=album>{{album.title}}</in-place-edit>
|
||||
</td>
|
||||
<td>
|
||||
<in-place-edit field-name='artist' input-type='artist' input-class='input-large' model=album>{{album.artist}}</in-place-edit>
|
||||
</td>
|
||||
<td>
|
||||
<in-place-edit field-name='releaseYear' input-type='text' input-class='input-small' model=album>{{album.releaseYear}}</in-place-edit>
|
||||
</td>
|
||||
<td>
|
||||
<in-place-edit field-name='genre' input-type='text' input-class='input-medium' model=album>{{album.genre}}</in-place-edit>
|
||||
</td>
|
||||
<td class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="glyphicon glyphicon-cog"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
|
||||
<li role="presentation"><a ng-click="updateAlbum(album)">edit</a></li>
|
||||
<li role="presentation"><a ng-click="deleteAlbum(album)">delete</a></li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -0,0 +1,8 @@
|
||||
<div class="col-xs-12" id="status" ng-controller="StatusController">
|
||||
<div id="alert" ng-show="status">
|
||||
<div class="alert" ng-class="{'alert-success': !status.isError, 'alert-danger': status.isError}">
|
||||
<button type="button" class="close" ng-click="clearStatus()"><span class="glyphicon glyphicon-remove-circle"></span></button>
|
||||
<p>{{status.message}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user