just getting it her
This commit is contained in:
205
bin/main/albums.json
Normal file
205
bin/main/albums.json
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
52
bin/main/application.yml
Normal file
52
bin/main/application.yml
Normal file
@@ -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
|
||||
BIN
bin/main/org/cloudfoundry/samples/music/Application.class
Normal file
BIN
bin/main/org/cloudfoundry/samples/music/Application.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
bin/main/org/cloudfoundry/samples/music/domain/Album.class
Normal file
BIN
bin/main/org/cloudfoundry/samples/music/domain/Album.class
Normal file
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.
Binary file not shown.
Binary file not shown.
BIN
bin/main/org/cloudfoundry/samples/music/web/InfoController.class
Normal file
BIN
bin/main/org/cloudfoundry/samples/music/web/InfoController.class
Normal file
Binary file not shown.
35
bin/main/static/css/app.css
Normal file
35
bin/main/static/css/app.css
Normal file
@@ -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;
|
||||
}
|
||||
59
bin/main/static/css/multi-columns-row.css
Normal file
59
bin/main/static/css/multi-columns-row.css
Normal file
@@ -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; }
|
||||
}
|
||||
BIN
bin/main/static/img/glyphicons-halflings-white.png
Normal file
BIN
bin/main/static/img/glyphicons-halflings-white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
BIN
bin/main/static/img/glyphicons-halflings.png
Normal file
BIN
bin/main/static/img/glyphicons-halflings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
47
bin/main/static/index.html
Normal file
47
bin/main/static/index.html
Normal file
@@ -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>
|
||||
199
bin/main/static/js/albums.js
Normal file
199
bin/main/static/js/albums.js
Normal file
@@ -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'
|
||||
};
|
||||
});
|
||||
14
bin/main/static/js/app.js
Normal file
14
bin/main/static/js/app.js
Normal file
@@ -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'
|
||||
});
|
||||
}
|
||||
);
|
||||
37
bin/main/static/js/errors.js
Normal file
37
bin/main/static/js/errors.js
Normal file
@@ -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);
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
8
bin/main/static/js/info.js
Normal file
8
bin/main/static/js/info.js
Normal file
@@ -0,0 +1,8 @@
|
||||
angular.module('info', ['ngResource']).
|
||||
factory('Info', function ($resource) {
|
||||
return $resource('appinfo');
|
||||
});
|
||||
|
||||
function InfoController($scope, Info) {
|
||||
$scope.info = Info.get();
|
||||
}
|
||||
38
bin/main/static/js/status.js
Normal file
38
bin/main/static/js/status.js
Normal file
@@ -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();
|
||||
};
|
||||
}
|
||||
32
bin/main/static/templates/albumForm.html
Normal file
32
bin/main/static/templates/albumForm.html
Normal file
@@ -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>
|
||||
29
bin/main/static/templates/albums.html
Normal file
29
bin/main/static/templates/albums.html
Normal file
@@ -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>
|
||||
22
bin/main/static/templates/errors.html
Normal file
22
bin/main/static/templates/errors.html
Normal file
@@ -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>
|
||||
3
bin/main/static/templates/footer.html
Normal file
3
bin/main/static/templates/footer.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<div id="footer" class="row">
|
||||
|
||||
</div>
|
||||
31
bin/main/static/templates/grid.html
Normal file
31
bin/main/static/templates/grid.html
Normal file
@@ -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>
|
||||
24
bin/main/static/templates/header.html
Normal file
24
bin/main/static/templates/header.html
Normal file
@@ -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>
|
||||
38
bin/main/static/templates/list.html
Normal file
38
bin/main/static/templates/list.html
Normal file
@@ -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>
|
||||
8
bin/main/static/templates/status.html
Normal file
8
bin/main/static/templates/status.html
Normal file
@@ -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