Migrated to bootstrap 3.0.x
This commit is contained in:
parent
a300db9845
commit
5dd9543b38
@ -112,6 +112,19 @@ var AccountController = function($scope, $http, $rootScope, $window) {
|
|||||||
|
|
||||||
// Reload accounts to update solds.
|
// Reload accounts to update solds.
|
||||||
$scope.loadAccounts();
|
$scope.loadAccounts();
|
||||||
|
}).error(function(data) {
|
||||||
|
if(data.error_type == 'validation') {
|
||||||
|
angular.forEach(data.errors, function(errors, field) {
|
||||||
|
// $scope.form[field].$setValidity('server', false);
|
||||||
|
//$scope.errors[field] = errors.join(', ');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$.pnotify({
|
||||||
|
type: "error",
|
||||||
|
title: "Save",
|
||||||
|
text: data.errors
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
var EntryController = function($scope, $http, $rootScope, $filter) {
|
var EntryController = function($scope, $http, $rootScope, $filter) {
|
||||||
// Entry store and selection
|
// Entry store and selection
|
||||||
$scope.entries = [];
|
$scope.entries = [];
|
||||||
|
$scope.categories = [];
|
||||||
|
$scope.chartValues = [];
|
||||||
|
$scope.pieChartValues = [];
|
||||||
$scope.selectedItem = null;
|
$scope.selectedItem = null;
|
||||||
|
|
||||||
$scope.account = null;
|
$scope.account = null;
|
||||||
@ -61,15 +64,24 @@ var EntryController = function($scope, $http, $rootScope, $filter) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$scope.chartValues = chartValues;
|
||||||
|
|
||||||
// Second pass: transform to an array readable by jqplot.
|
// Second pass: transform to an array readable by jqplot.
|
||||||
|
var pieChartValues = [];
|
||||||
angular.forEach(pieChartValuesTmp, function(value, key) {
|
angular.forEach(pieChartValuesTmp, function(value, key) {
|
||||||
pieChartValues.push([key, value]);
|
pieChartValues.push([key, value]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$scope.pieChartValues = pieChartValues;
|
||||||
|
|
||||||
|
//$scope.categories.length = 0;
|
||||||
|
//$scope.categories.concat(categories);
|
||||||
$scope.categories = categories;
|
$scope.categories = categories;
|
||||||
|
|
||||||
$scope.drawChart({account: $scope.account, entries: chartValues}, "#entries-chart-placeholder");
|
nv.addGraph($scope.drawChart);
|
||||||
$scope.drawPieChart(pieChartValues, "#expense-categories-chart-placeholder");
|
nv.addGraph($scope.drawPieChart);
|
||||||
|
//$scope.drawPieChart(pieChartValues, "#expense-categories-chart-placeholder");
|
||||||
|
//$scope.drawPieChart();
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.getAccountStatus = function(account, month) {
|
$scope.getAccountStatus = function(account, month) {
|
||||||
@ -200,17 +212,17 @@ var EntryController = function($scope, $http, $rootScope, $filter) {
|
|||||||
|
|
||||||
$scope.iconSaveClass = function(entry) {
|
$scope.iconSaveClass = function(entry) {
|
||||||
if(!$scope.isSaved(entry)) {
|
if(!$scope.isSaved(entry)) {
|
||||||
return "icon-plus";
|
return "fa fa-plus";
|
||||||
} else if ($scope.isEditing(entry)) {
|
} else if ($scope.isEditing(entry)) {
|
||||||
return "icon-ok";
|
return "fa fa-floppy-o";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.iconCancelClass = function(entry) {
|
$scope.iconCancelClass = function(entry) {
|
||||||
if($scope.isNew(entry)) {
|
if($scope.isNew(entry)) {
|
||||||
return "icon-remove";
|
return "fa fa-times";
|
||||||
} else if ($scope.isEditing(entry)) {
|
} else if ($scope.isEditing(entry)) {
|
||||||
return "icon-ban-circle";
|
return "fa fa-ban";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -330,13 +342,13 @@ var EntryController = function($scope, $http, $rootScope, $filter) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Function to draw the sold evolution chart.
|
// Function to draw the sold evolution chart.
|
||||||
$scope.drawChart = function(data, elementId) {
|
$scope.drawChart = function() {
|
||||||
// Clear previous chart
|
// Clear previous chart
|
||||||
//var element = angular.element(elementId);
|
var entries = $scope.chartValues;
|
||||||
//element.html("");
|
console.debug("drawChart", entries);
|
||||||
//element.css("height", "0px");
|
|
||||||
|
var width = 700;
|
||||||
var entries = data.entries;
|
var height = 300;
|
||||||
|
|
||||||
//if(entries && entries.length > 1) {
|
//if(entries && entries.length > 1) {
|
||||||
// Prepare for today vertical line.
|
// Prepare for today vertical line.
|
||||||
@ -346,27 +358,35 @@ var EntryController = function($scope, $http, $rootScope, $filter) {
|
|||||||
|
|
||||||
// Find first and last days to set limits of the x axis.
|
// Find first and last days to set limits of the x axis.
|
||||||
var day = 24 * 60 * 60 * 1000;
|
var day = 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
var firstDate = $filter('date')(new Date(Date.parse(entries[0][0]).valueOf() - day), 'yyyy-MM-dd');
|
var firstDate = $filter('date')(new Date(Date.parse(entries[0][0]).valueOf() - day), 'yyyy-MM-dd');
|
||||||
var lastDate = $filter('date')(new Date(Date.parse(entries[entries.length -1][0]).valueOf() + day), 'yyyy-MM-dd');
|
var lastDate = $filter('date')(new Date(Date.parse(entries[entries.length -1][0]).valueOf() + day), 'yyyy-MM-dd');
|
||||||
//var firstDate = new Date(Date.parse(entries[0][0]).valueOf() - day);
|
|
||||||
//var lastDate = new Date(Date.parse(entries[entries.length -1][0]).valueOf() + day);
|
var chart = nv.models.lineChart().options({
|
||||||
|
x: function(d) { return d3.time.format("%Y-%m-%d").parse(d[0]); },
|
||||||
// Plot chart, and store it in a window parameter for resize callback (need to be done better than it...)
|
y: function(d) { return new Number(d[1]); },
|
||||||
var chart = nv.models.lineChart()
|
transitionDuration: 250,
|
||||||
.x(function(d) { return d3.time.format("%Y-%m-%d").parse(d[0]); })
|
showXAxis: true,
|
||||||
.y(function(d) { return new Number(d[1]); });
|
showYAxis: true,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
});
|
||||||
|
|
||||||
chart.lines.interpolate("monotone");
|
chart.lines.interpolate("monotone");
|
||||||
|
|
||||||
chart.xAxis.axisLabel("Date").tickFormat(function(d) {
|
chart.xAxis
|
||||||
return d3.time.format("%Y-%m-%d")(new Date(d));
|
.axisLabel("Date")
|
||||||
});
|
.tickFormat(function(d) {
|
||||||
chart.xAxis.scale().range([firstDate, lastDate]);
|
return d3.time.format("%Y-%m-%d")(new Date(d));
|
||||||
|
});
|
||||||
|
//chart.xAxis.scale().range([firstDate, lastDate]);
|
||||||
|
|
||||||
chart.yAxis.axisLabel("Solde").tickFormat(d3.format('.02f'));
|
chart.yAxis
|
||||||
|
.axisLabel("Solde")
|
||||||
|
.tickFormat(d3.format('.02f'));
|
||||||
|
|
||||||
// FIXME add vertical line for today
|
// FIXME add vertical line for today
|
||||||
graph = d3.select(elementId + " svg").datum([
|
graph = d3.select("#entries-chart-placeholder").datum([
|
||||||
{ color: "orange", key: "Zero", values:[
|
{ color: "orange", key: "Zero", values:[
|
||||||
[firstDate, "0"],
|
[firstDate, "0"],
|
||||||
[lastDate, "0"]
|
[lastDate, "0"]
|
||||||
@ -376,23 +396,40 @@ var EntryController = function($scope, $http, $rootScope, $filter) {
|
|||||||
[lastDate, new Number($scope.account.authorized_overdraft)]
|
[lastDate, new Number($scope.account.authorized_overdraft)]
|
||||||
]},
|
]},
|
||||||
{ color: "darkblue", key: "Sold evolution", values: entries},
|
{ color: "darkblue", key: "Sold evolution", values: entries},
|
||||||
]).transition().duration(1200).call(chart);
|
])
|
||||||
|
.transition().duration(1200)
|
||||||
|
.attr("width", width)
|
||||||
|
.attr("height", height)
|
||||||
|
.call(chart);
|
||||||
|
|
||||||
nv.utils.windowResize(chart.update);
|
nv.utils.windowResize(chart.update);
|
||||||
|
|
||||||
|
return chart;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to draw the expense category pie chart.
|
// Function to draw the expense category pie chart.
|
||||||
$scope.drawPieChart = function(entries, elementId) {
|
$scope.drawPieChart = function() {
|
||||||
//if(entries && entries.length > 1) {
|
// FIXME retrieve width and height from DOM
|
||||||
|
var width = 300;
|
||||||
|
var height = 300;
|
||||||
|
|
||||||
var chart = nv.models.pieChart()
|
var chart = nv.models.pieChart()
|
||||||
.x(function(d) { return d[0]; })
|
.x(function(d) { console.debug(d); return d[0]; })
|
||||||
.y(function(d) { return d[1]; })
|
.y(function(d) { return d[1]; })
|
||||||
|
.width(width)
|
||||||
|
.height(height)
|
||||||
.showLabels(true);
|
.showLabels(true);
|
||||||
|
|
||||||
d3.select(elementId + " svg").datum([{key: "Expenses", values: entries}]).transition().duration(1200).call(chart);
|
d3.select("#expense-categories-chart-placeholder")
|
||||||
|
.datum($scope.pieChartValues)
|
||||||
|
.transition().duration(1200)
|
||||||
|
.attr('width', width)
|
||||||
|
.attr('height', height)
|
||||||
|
.call(chart);
|
||||||
|
|
||||||
nv.utils.windowResize(chart.update);
|
nv.utils.windowResize(chart.update);
|
||||||
//}
|
|
||||||
|
return chart
|
||||||
};
|
};
|
||||||
|
|
||||||
$rootScope.$on("monthsLoadedEvent", function(event, args){
|
$rootScope.$on("monthsLoadedEvent", function(event, args){
|
||||||
|
@ -62,17 +62,17 @@ var SchedulerController = function($scope, $http, $rootScope, $filter) {
|
|||||||
|
|
||||||
$scope.iconSaveClass = function(operation) {
|
$scope.iconSaveClass = function(operation) {
|
||||||
if($scope.isNew(operation)) {
|
if($scope.isNew(operation)) {
|
||||||
return "icon-plus";
|
return "fa fa-plus";
|
||||||
} else if ($scope.isEditing(operation)) {
|
} else if ($scope.isEditing(operation)) {
|
||||||
return "icon-ok";
|
return "fa fa-floppy-o";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.iconCancelClass = function(operation) {
|
$scope.iconCancelClass = function(operation) {
|
||||||
if($scope.isNew(operation)) {
|
if($scope.isNew(operation)) {
|
||||||
return "icon-remove";
|
return "fa fa-times";
|
||||||
} else if ($scope.isEditing(operation)) {
|
} else if ($scope.isEditing(operation)) {
|
||||||
return "icon-ban-circle";
|
return "fa fa-ban";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,18 +21,22 @@
|
|||||||
|
|
||||||
<!-- Dialog body -->
|
<!-- Dialog body -->
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal" role="form">
|
||||||
<div class="control-group">
|
<div class="form-group">
|
||||||
<!-- Account name field -->
|
<!-- Account name field -->
|
||||||
<label class="control-label" for="inputName">Nom du compte</label>
|
<label class="control-label" for="inputName">Nom du compte</label>
|
||||||
<div class="controls">
|
<input type="text" class="form-control" id="inputName" ng-model="account.name"/>
|
||||||
<input type="text" id="inputName" ng-model="account.name"></input>
|
|
||||||
|
<div class="errors" ng-show="form.inputName.$dirty && form.inputName.$invalid">
|
||||||
|
<span ng-show="form.inputName.$error.server">{{ errors.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Authorized overdraft field -->
|
<!-- Authorized overdraft field -->
|
||||||
<label class="control-label" for="inputAuthorizedOverdraft">Découvert authorisé</label>
|
<label class="control-label" for="inputAuthorizedOverdraft">Découvert authorisé</label>
|
||||||
<div class="controls">
|
<input type="text" class="form-control" id="inputAuthorizedOverdraft" ng-model="account.authorized_overdraft"/>
|
||||||
<input type="text" id="inputAuthorizedOverdraft" ng-model="account.authorized_overdraft"></input>
|
|
||||||
|
<div class="errors" ng-show="form.inputAuthorizedOverdraft.$dirty && form.inputAuthorizedOverdraft.$invalid">
|
||||||
|
<span ng-show="form.inputAuthorizedOverdraft.$error.server">{{ errors.authorized_overdraft }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
<!--
|
|
||||||
This file is part of Accountant.
|
|
||||||
|
|
||||||
Accountant is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Foobar is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with Accountant. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
-->
|
|
||||||
<!-- Dialog header with title -->
|
|
||||||
<div class="modal-header">
|
|
||||||
<h3>Supprimer l'entrée [[entry.label]]</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Dialog body -->
|
|
||||||
<div class="modal-body">
|
|
||||||
<p>Confirmez-vous la suppression de cette entrée ?</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Dialog footer with buttons -->
|
|
||||||
<div class="modal-footer">
|
|
||||||
<a href="#" class="btn btn-primary" ng-click="dismiss()">Non</a>
|
|
||||||
<a href="#" class="btn" ng-click="removeEntry(entry, this)">Oui</a>
|
|
||||||
</div>
|
|
||||||
|
|
656
frontend/static/third-party/nv.d3/nv.d3.css
vendored
656
frontend/static/third-party/nv.d3/nv.d3.css
vendored
@ -1,656 +0,0 @@
|
|||||||
|
|
||||||
/********************
|
|
||||||
* HTML CSS
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
.chartWrap {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/********************
|
|
||||||
* TOOLTIP CSS
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvtooltip {
|
|
||||||
position: absolute;
|
|
||||||
background-color: rgba(255,255,255,1);
|
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
z-index: 10000;
|
|
||||||
|
|
||||||
font-family: Arial;
|
|
||||||
font-size: 13px;
|
|
||||||
|
|
||||||
transition: opacity 500ms linear;
|
|
||||||
-moz-transition: opacity 500ms linear;
|
|
||||||
-webkit-transition: opacity 500ms linear;
|
|
||||||
|
|
||||||
transition-delay: 500ms;
|
|
||||||
-moz-transition-delay: 500ms;
|
|
||||||
-webkit-transition-delay: 500ms;
|
|
||||||
|
|
||||||
-moz-box-shadow: 4px 4px 8px rgba(0,0,0,.5);
|
|
||||||
-webkit-box-shadow: 4px 4px 8px rgba(0,0,0,.5);
|
|
||||||
box-shadow: 4px 4px 8px rgba(0,0,0,.5);
|
|
||||||
|
|
||||||
-moz-border-radius: 10px;
|
|
||||||
border-radius: 10px;
|
|
||||||
|
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvtooltip h3 {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvtooltip p {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvtooltip span {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 2px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvtooltip-pending-removal {
|
|
||||||
position: absolute;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/********************
|
|
||||||
* SVG CSS
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
svg {
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
/* Trying to get SVG to act like a greedy block in all browsers */
|
|
||||||
display: block;
|
|
||||||
width:100%;
|
|
||||||
height:100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
svg text {
|
|
||||||
font: normal 12px Arial;
|
|
||||||
}
|
|
||||||
|
|
||||||
svg .title {
|
|
||||||
font: bold 14px Arial;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-background {
|
|
||||||
fill: white;
|
|
||||||
fill-opacity: 0;
|
|
||||||
/*
|
|
||||||
pointer-events: none;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-noData {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Brush
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nv-brush .extent {
|
|
||||||
fill-opacity: .125;
|
|
||||||
shape-rendering: crispEdges;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Legend
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3 .nv-legend .nv-series {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-legend .disabled circle {
|
|
||||||
fill-opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Axes
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3 .nv-axis path {
|
|
||||||
fill: none;
|
|
||||||
stroke: #000;
|
|
||||||
stroke-opacity: .75;
|
|
||||||
shape-rendering: crispEdges;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-axis path.domain {
|
|
||||||
stroke-opacity: .75;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-axis.nv-x path.domain {
|
|
||||||
stroke-opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-axis line {
|
|
||||||
fill: none;
|
|
||||||
stroke: #000;
|
|
||||||
stroke-opacity: .25;
|
|
||||||
shape-rendering: crispEdges;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-axis line.zero {
|
|
||||||
stroke-opacity: .75;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-axis .nv-axisMaxMin text {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .x .nv-axis .nv-axisMaxMin text,
|
|
||||||
.nvd3 .x2 .nv-axis .nv-axisMaxMin text,
|
|
||||||
.nvd3 .x3 .nv-axis .nv-axisMaxMin text {
|
|
||||||
text-anchor: middle
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Brush
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nv-brush .resize path {
|
|
||||||
fill: #eee;
|
|
||||||
stroke: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Bars
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3 .nv-bars .negative rect {
|
|
||||||
zfill: brown;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-bars rect {
|
|
||||||
zfill: steelblue;
|
|
||||||
fill-opacity: .75;
|
|
||||||
|
|
||||||
transition: fill-opacity 250ms linear;
|
|
||||||
-moz-transition: fill-opacity 250ms linear;
|
|
||||||
-webkit-transition: fill-opacity 250ms linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-bars rect:hover {
|
|
||||||
fill-opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-bars .hover rect {
|
|
||||||
fill: lightblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-bars text {
|
|
||||||
fill: rgba(0,0,0,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-bars .hover text {
|
|
||||||
fill: rgba(0,0,0,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Bars
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3 .nv-multibar .nv-groups rect,
|
|
||||||
.nvd3 .nv-multibarHorizontal .nv-groups rect,
|
|
||||||
.nvd3 .nv-discretebar .nv-groups rect {
|
|
||||||
stroke-opacity: 0;
|
|
||||||
|
|
||||||
transition: fill-opacity 250ms linear;
|
|
||||||
-moz-transition: fill-opacity 250ms linear;
|
|
||||||
-webkit-transition: fill-opacity 250ms linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-multibar .nv-groups rect:hover,
|
|
||||||
.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,
|
|
||||||
.nvd3 .nv-discretebar .nv-groups rect:hover {
|
|
||||||
fill-opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-discretebar .nv-groups text,
|
|
||||||
.nvd3 .nv-multibarHorizontal .nv-groups text {
|
|
||||||
font-weight: bold;
|
|
||||||
fill: rgba(0,0,0,1);
|
|
||||||
stroke: rgba(0,0,0,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********
|
|
||||||
* Pie Chart
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3.nv-pie path {
|
|
||||||
stroke-opacity: 0;
|
|
||||||
|
|
||||||
transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
|
|
||||||
-moz-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
|
|
||||||
-webkit-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-pie .nv-slice text {
|
|
||||||
stroke: #000;
|
|
||||||
stroke-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-pie path {
|
|
||||||
stroke: #fff;
|
|
||||||
stroke-width: 1px;
|
|
||||||
stroke-opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-pie .hover path {
|
|
||||||
fill-opacity: .7;
|
|
||||||
/*
|
|
||||||
stroke-width: 6px;
|
|
||||||
stroke-opacity: 1;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-pie .nv-label rect {
|
|
||||||
fill-opacity: 0;
|
|
||||||
stroke-opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Lines
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3 .nv-groups path.nv-line {
|
|
||||||
fill: none;
|
|
||||||
stroke-width: 2.5px;
|
|
||||||
/*
|
|
||||||
stroke-linecap: round;
|
|
||||||
shape-rendering: geometricPrecision;
|
|
||||||
|
|
||||||
transition: stroke-width 250ms linear;
|
|
||||||
-moz-transition: stroke-width 250ms linear;
|
|
||||||
-webkit-transition: stroke-width 250ms linear;
|
|
||||||
|
|
||||||
transition-delay: 250ms
|
|
||||||
-moz-transition-delay: 250ms;
|
|
||||||
-webkit-transition-delay: 250ms;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-groups path.nv-area {
|
|
||||||
stroke: none;
|
|
||||||
/*
|
|
||||||
stroke-linecap: round;
|
|
||||||
shape-rendering: geometricPrecision;
|
|
||||||
|
|
||||||
stroke-width: 2.5px;
|
|
||||||
transition: stroke-width 250ms linear;
|
|
||||||
-moz-transition: stroke-width 250ms linear;
|
|
||||||
-webkit-transition: stroke-width 250ms linear;
|
|
||||||
|
|
||||||
transition-delay: 250ms
|
|
||||||
-moz-transition-delay: 250ms;
|
|
||||||
-webkit-transition-delay: 250ms;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-line.hover path {
|
|
||||||
stroke-width: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
.nvd3.scatter .groups .point {
|
|
||||||
fill-opacity: 0.1;
|
|
||||||
stroke-opacity: 0.1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point {
|
|
||||||
fill-opacity: 0;
|
|
||||||
stroke-opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point {
|
|
||||||
fill-opacity: .5 !important;
|
|
||||||
stroke-opacity: .5 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.nvd3 .nv-groups .nv-point {
|
|
||||||
transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
|
|
||||||
-moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
|
|
||||||
-webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-scatter .nv-groups .nv-point.hover,
|
|
||||||
.nvd3 .nv-groups .nv-point.hover {
|
|
||||||
stroke-width: 20px;
|
|
||||||
fill-opacity: .5 !important;
|
|
||||||
stroke-opacity: .5 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.nvd3 .nv-point-paths path {
|
|
||||||
stroke: #aaa;
|
|
||||||
stroke-opacity: 0;
|
|
||||||
fill: #eee;
|
|
||||||
fill-opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.nvd3 .nv-indexLine {
|
|
||||||
cursor: ew-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Distribution
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3 .nv-distribution {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Scatter
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* **Attempting to remove this for useVoronoi(false), need to see if it's required anywhere
|
|
||||||
.nvd3 .nv-groups .nv-point {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3 .nv-groups .nv-point.hover {
|
|
||||||
stroke-width: 20px;
|
|
||||||
stroke-opacity: .5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-scatter .nv-point.hover {
|
|
||||||
fill-opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
.nv-group.hover .nv-point {
|
|
||||||
fill-opacity: 1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Stacked Area
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3.nv-stackedarea path.nv-area {
|
|
||||||
fill-opacity: .7;
|
|
||||||
/*
|
|
||||||
stroke-opacity: .65;
|
|
||||||
fill-opacity: 1;
|
|
||||||
*/
|
|
||||||
stroke-opacity: 0;
|
|
||||||
|
|
||||||
transition: fill-opacity 250ms linear, stroke-opacity 250ms linear;
|
|
||||||
-moz-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear;
|
|
||||||
-webkit-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear;
|
|
||||||
|
|
||||||
/*
|
|
||||||
transition-delay: 500ms;
|
|
||||||
-moz-transition-delay: 500ms;
|
|
||||||
-webkit-transition-delay: 500ms;
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-stackedarea path.nv-area.hover {
|
|
||||||
fill-opacity: .9;
|
|
||||||
/*
|
|
||||||
stroke-opacity: .85;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
.d3stackedarea .groups path {
|
|
||||||
stroke-opacity: 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.nvd3.nv-stackedarea .nv-groups .nv-point {
|
|
||||||
stroke-opacity: 0;
|
|
||||||
fill-opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-stackedarea .nv-groups .nv-point.hover {
|
|
||||||
stroke-width: 20px;
|
|
||||||
stroke-opacity: .75;
|
|
||||||
fill-opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Line Plus Bar
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3.nv-linePlusBar .nv-bar rect {
|
|
||||||
fill-opacity: .75;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-linePlusBar .nv-bar rect:hover {
|
|
||||||
fill-opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Bullet
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3.nv-bullet { font: 10px sans-serif; }
|
|
||||||
.nvd3.nv-bullet .nv-measure { fill-opacity: .8; }
|
|
||||||
.nvd3.nv-bullet .nv-measure:hover { fill-opacity: 1; }
|
|
||||||
.nvd3.nv-bullet .nv-marker { stroke: #000; stroke-width: 2px; }
|
|
||||||
.nvd3.nv-bullet .nv-markerTriangle { stroke: #000; fill: #fff; stroke-width: 1.5px; }
|
|
||||||
.nvd3.nv-bullet .nv-tick line { stroke: #666; stroke-width: .5px; }
|
|
||||||
.nvd3.nv-bullet .nv-range.nv-s0 { fill: #eee; }
|
|
||||||
.nvd3.nv-bullet .nv-range.nv-s1 { fill: #ddd; }
|
|
||||||
.nvd3.nv-bullet .nv-range.nv-s2 { fill: #ccc; }
|
|
||||||
.nvd3.nv-bullet .nv-title { font-size: 14px; font-weight: bold; }
|
|
||||||
.nvd3.nv-bullet .nv-subtitle { fill: #999; }
|
|
||||||
|
|
||||||
|
|
||||||
.nvd3.nv-bullet .nv-range {
|
|
||||||
fill: #999;
|
|
||||||
fill-opacity: .4;
|
|
||||||
}
|
|
||||||
.nvd3.nv-bullet .nv-range:hover {
|
|
||||||
fill-opacity: .7;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Sparkline
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3.nv-sparkline path {
|
|
||||||
fill: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-sparklineplus g.nv-hoverValue {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-sparklineplus .nv-hoverValue line {
|
|
||||||
stroke: #333;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-sparklineplus,
|
|
||||||
.nvd3.nv-sparklineplus g {
|
|
||||||
pointer-events: all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-hoverArea {
|
|
||||||
fill-opacity: 0;
|
|
||||||
stroke-opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-sparklineplus .nv-xValue,
|
|
||||||
.nvd3.nv-sparklineplus .nv-yValue {
|
|
||||||
/*
|
|
||||||
stroke: #666;
|
|
||||||
*/
|
|
||||||
stroke-width: 0;
|
|
||||||
font-size: .9em;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-sparklineplus .nv-yValue {
|
|
||||||
stroke: #f66;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-sparklineplus .nv-maxValue {
|
|
||||||
stroke: #2ca02c;
|
|
||||||
fill: #2ca02c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-sparklineplus .nv-minValue {
|
|
||||||
stroke: #d62728;
|
|
||||||
fill: #d62728;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-sparklineplus .nv-currentValue {
|
|
||||||
/*
|
|
||||||
stroke: #444;
|
|
||||||
fill: #000;
|
|
||||||
*/
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* historical stock
|
|
||||||
*/
|
|
||||||
|
|
||||||
.nvd3.nv-ohlcBar .nv-ticks .nv-tick {
|
|
||||||
stroke-width: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover {
|
|
||||||
stroke-width: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive {
|
|
||||||
stroke: #2ca02c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative {
|
|
||||||
stroke: #d62728;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-historicalStockChart .nv-axis .nv-axislabel {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-historicalStockChart .nv-dragTarget {
|
|
||||||
fill-opacity: 0;
|
|
||||||
stroke: none;
|
|
||||||
cursor: move;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-brush .extent {
|
|
||||||
/*
|
|
||||||
cursor: ew-resize !important;
|
|
||||||
*/
|
|
||||||
fill-opacity: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3 .nv-brushBackground rect {
|
|
||||||
stroke: #000;
|
|
||||||
stroke-width: .4;
|
|
||||||
fill: #fff;
|
|
||||||
fill-opacity: .7;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********
|
|
||||||
* Indented Tree
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: the following 3 selectors are based on classes used in the example. I should either make them standard and leave them here, or move to a CSS file not included in the library
|
|
||||||
*/
|
|
||||||
.nvd3.nv-indentedtree .name {
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-indentedtree .clickable {
|
|
||||||
color: #08C;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-indentedtree span.clickable:hover {
|
|
||||||
color: #005580;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.nvd3.nv-indentedtree .nv-childrenCount {
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-indentedtree .nv-treeicon {
|
|
||||||
cursor: pointer;
|
|
||||||
/*
|
|
||||||
cursor: n-resize;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.nvd3.nv-indentedtree .nv-treeicon.nv-folded {
|
|
||||||
cursor: pointer;
|
|
||||||
/*
|
|
||||||
cursor: s-resize;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
11307
frontend/static/third-party/nv.d3/nv.d3.js
vendored
11307
frontend/static/third-party/nv.d3/nv.d3.js
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -16,25 +16,22 @@
|
|||||||
#}
|
#}
|
||||||
{% extends "layout.html" %}
|
{% extends "layout.html" %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
<div ng-controller="EntryController">
|
||||||
<!-- Chart row -->
|
<!-- Chart row -->
|
||||||
<div class="row-fluid">
|
<div class="row">
|
||||||
<!-- Sold evolution chart placeholder -->
|
<!-- Sold evolution chart placeholder -->
|
||||||
<div class="span7">
|
<div class="col-md-7">
|
||||||
<div id="entries-chart-placeholder">
|
<svg id="entries-chart-placeholder" style="stroke-width: 1px"/>
|
||||||
<svg style='height:300px'/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Expense category piechart -->
|
<!-- Expense category piechart -->
|
||||||
<div class="span3">
|
<div class="col-md-3">
|
||||||
<div id="expense-categories-chart-placeholder">
|
<svg id="expense-categories-chart-placeholder" style='height:300px'/>
|
||||||
<svg style='height:300px'/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Balance -->
|
<!-- Balance -->
|
||||||
<div class="span2" ng-controller="EntryController">
|
<div class="col-md-2">
|
||||||
<div class="row-fluid">
|
<div class="row">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<tr><td>Dépenses :</td><td>[[accountStatus.expenses]]</td></tr>
|
<tr><td>Dépenses :</td><td>[[accountStatus.expenses]]</td></tr>
|
||||||
<tr><td>Recettes :</td><td>[[accountStatus.revenues]]</td></tr>
|
<tr><td>Recettes :</td><td>[[accountStatus.revenues]]</td></tr>
|
||||||
@ -45,8 +42,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Row with entry table -->
|
<!-- Row with entry table -->
|
||||||
<div class="row-fluid">
|
<div class="row">
|
||||||
<table class="table table-striped table-condensed table-hover" ng-controller="EntryController">
|
<table class="table table-condensed table-hover">
|
||||||
<!-- Head of the table containing column headers and size -->
|
<!-- Head of the table containing column headers and size -->
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -55,7 +52,7 @@
|
|||||||
<th style="width: 50px">Montant</th>
|
<th style="width: 50px">Montant</th>
|
||||||
<th style="width: 50px">Solde</th>
|
<th style="width: 50px">Solde</th>
|
||||||
<th style="width: 100px">Catégorie</th>
|
<th style="width: 100px">Catégorie</th>
|
||||||
<th style="width: 60px">Actions</th>
|
<th style="width: 80px">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
@ -64,67 +61,102 @@
|
|||||||
<tr id="entry_[[entry.id]]" class="form-inline" ng-class="entryRowClass(entry)" ng-repeat="entry in entries">
|
<tr id="entry_[[entry.id]]" class="form-inline" ng-class="entryRowClass(entry)" ng-repeat="entry in entries">
|
||||||
<td>
|
<td>
|
||||||
<small>
|
<small>
|
||||||
<input ng-show="isEditing(entry)" type="text" class="input-small" ng-model="entry.operation_date" data-date-format="yyyy-mm-dd" bs-datepicker/>
|
<input ng-show="isEditing(entry)" type="text" class="form-control input-sm" ng-model="entry.operation_date" data-date-format="yyyy-mm-dd" bs-datepicker/>
|
||||||
<span ng-show="isDisplaying(entry)">[[entry.operation_date]]</span>
|
<span ng-show="isDisplaying(entry)">[[entry.operation_date]]</span>
|
||||||
</small>
|
</small>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<small>
|
<small>
|
||||||
<input ng-show="isEditing(entry)" type="text" class="input-xxlarge" ng-model="entry.label"/>
|
<input ng-show="isEditing(entry)" type="text" class="form-control input-sm" ng-model="entry.label"/>
|
||||||
<span ng-show="isDisplaying(entry)">[[entry.label]]</span>
|
<span ng-show="isDisplaying(entry)">[[entry.label]]</span>
|
||||||
</small>
|
</small>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<small>
|
<small>
|
||||||
<input ng-show="isEditing(entry)" type="text" class="input-mini" ng-model="entry.value"/>
|
<input ng-show="isEditing(entry)" type="text" class="form-control input-sm" ng-model="entry.value"/>
|
||||||
<span ng-show="isDisplaying(entry)">[[entry.value]]</span>
|
<span ng-show="isDisplaying(entry)">[[entry.value]]</span>
|
||||||
</small>
|
</small>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td ng-class="entryValueClass(entry.sold)">
|
<td ng-class="entryValueClass(entry.sold)">
|
||||||
<small>
|
<small>
|
||||||
[[entry.sold]]
|
[[entry.sold]]
|
||||||
</small>
|
</small>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<small>
|
<small>
|
||||||
<input ng-show="isEditing(entry)" type="text" class="input-small" ng-model="entry.category" bs-typeahead="categories"/>
|
<!--<input ng-show="isEditing(entry)" type="text" class="form-control input-sm" ng-model="entry.category" bs-typeahead="categories"/>-->
|
||||||
|
<input ng-show="isEditing(entry)" type="text" class="form-control input-sm" ng-model="entry.category"/>
|
||||||
<span ng-show="isDisplaying(entry)">[[entry.category]]</span>
|
<span ng-show="isDisplaying(entry)">[[entry.category]]</span>
|
||||||
</small>
|
</small>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<div class="btn-group" ng-show="isEditing(entry)">
|
<div class="btn-group" ng-show="isEditing(entry)">
|
||||||
<a class="btn btn-mini btn-success" ng-click="saveEntry(entry)" href="#" title="Save"><i ng-class="iconSaveClass(entry)"><span style="display: none">Save</span></i></a>
|
<button type="button" class="btn btn-xs btn-success" ng-click="saveEntry(entry)" title="Save">
|
||||||
<a class="btn btn-mini" ng-click="cancelEditEntry(entry)" href="#" title="Cancel"><i ng-class="iconCancelClass(entry)"><span style="display: none">Cancel</span></i></a>
|
<span ng-class="iconSaveClass(entry)"></span>
|
||||||
<a class="btn btn-mini" ng-click="pointEntry(entry)" ng-class="pointedEntryClass(entry)" href="#" title="point"><i class="icon-pencil"><span style="display: none">Point</span></i></a>
|
</button>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-xs btn-default" ng-click="cancelEditEntry(entry)" title="Cancel">
|
||||||
|
<span ng-class="iconCancelClass(entry)"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-xs btn-default" ng-click="pointEntry(entry)" ng-class="pointedEntryClass(entry)" title="point">
|
||||||
|
<span class="fa fa-check"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-group" ng-show="isDisplaying(entry) && isSaved(entry)">
|
<div class="btn-group" ng-show="isDisplaying(entry) && isSaved(entry)">
|
||||||
<a class="btn btn-mini" ng-click="editEntry(entry)" href="#" title="edit"><i class="icon-edit"><span style="display: none">Edit</span></i></a>
|
<button class="btn btn-xs btn-default" ng-click="editEntry(entry)" title="edit">
|
||||||
<a class="btn btn-mini" bs-modal="'{{ url_for('frontend.static', filename='templates/entry_remove.html') }}'" href="#" title="remove"><i class="icon-trash"><span style="display: none">Remove</span></i></a>
|
<span class="fa fa-pencil-square-o"></span>
|
||||||
<a class="btn btn-mini" ng-click="pointEntry(entry)" ng-class="pointedEntryClass(entry)" href="#" title="point"><i class="icon-pencil"><span style="display: none">Point</span></i></a>
|
</button>
|
||||||
|
|
||||||
|
<button class="btn btn-xs btn-default" data-toggle="modal" data-target="#remove_entry" title="remove">
|
||||||
|
<span class="fa fa-trash-o"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="btn btn-xs btn-default" ng-click="pointEntry(entry)" ng-class="pointedEntryClass(entry)" title="point">
|
||||||
|
<span class="fa fa-check"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-group" ng-show="isDisplaying(entry) && !isSaved(entry)">
|
<div class="btn-group" ng-show="isDisplaying(entry) && !isSaved(entry)">
|
||||||
<a class="btn btn-mini btn-success" ng-click="saveEntry(entry)" href="#" title="Save"><i ng-class="iconSaveClass(entry)"><span style="display: none">Save</span></i></a>
|
<button class="btn btn-xs btn-success" ng-click="saveEntry(entry)" title="Save">
|
||||||
<a class="btn btn-mini" ng-click="editEntry(entry)" href="#" title="edit"><i class="icon-edit"><span style="display: none">Edit</span></i></a>
|
<span ng-class="iconSaveClass(entry)"></span>
|
||||||
<a class="btn btn-mini" ng-click="pointEntry(entry)" ng-class="pointedEntryClass(entry)" href="#" title="point"><i class="icon-pencil"><span style="display: none">Point</span></i></a>
|
</button>
|
||||||
|
|
||||||
|
<button class="btn btn-xs btn-default" ng-click="editEntry(entry)" title="edit">
|
||||||
|
<span class="fa fa-pencil-square-o"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="btn btn-xs btn-default" ng-click="pointEntry(entry)" ng-class="pointedEntryClass(entry)" title="point">
|
||||||
|
<span class="fa fa-check"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% include "remove_entry.html" %}
|
||||||
|
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block footer %}
|
{% block footer %}
|
||||||
<!-- Navbar with the months of the selected account -->
|
<!-- Navbar with the months of the selected account -->
|
||||||
<div class="navbar navbar-fixed-bottom">
|
<div class="navbar navbar-default navbar-fixed-bottom" role="navigation" ng-controller="MonthController">
|
||||||
<div class="navbar-inner" ng-controller="MonthController">
|
<ul class="nav navbar-nav">
|
||||||
<ul class="nav">
|
<li ng-repeat="month in months" ng-class="monthClass(month)"><a href="#" ng-click="selectMonth(month)">[[month.year]]-[[month.month]]</a></li>
|
||||||
<li ng-repeat="month in months" ng-class="monthClass(month)"><a href="#" ng-click="selectMonth(month)">[[month.year]]-[[month.month]]</a></li>
|
</ul>
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
<!-- Custom Javascript library for entries -->
|
<!-- Custom Javascript library for entries -->
|
||||||
{% block js %}
|
{% block js %}
|
||||||
<script type="text/javascript" src="{{ url_for('frontend.static', filename='js/months.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('frontend.static', filename='js/months.js') }}"></script>
|
||||||
|
@ -20,14 +20,18 @@
|
|||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<title>Entries</title>
|
<title>Entries</title>
|
||||||
|
|
||||||
|
<!-- Awesome fonts -->
|
||||||
|
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
|
||||||
|
|
||||||
<!-- Bootstrap CSS -->
|
<!-- Bootstrap CSS -->
|
||||||
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
|
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap-theme.min.css" rel="stylesheet">
|
||||||
|
|
||||||
<!-- Bootstrap datepicker plugin CSS -->
|
<!-- Bootstrap datepicker plugin CSS -->
|
||||||
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.1.3/css/bootstrap-datepicker.min.css" rel="stylesheet">
|
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.1.3/css/bootstrap-datepicker.min.css" rel="stylesheet">
|
||||||
|
|
||||||
<!-- NVD3 CSS -->
|
<!-- NVD3 CSS -->
|
||||||
<link href="//cdnjs.cloudflare.com/ajax/libs/nvd3/1.0.0-beta/nv.d3.css" rel="stylesheet">
|
<link href="//cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.13-beta/nv.d3.css" rel="stylesheet">
|
||||||
|
|
||||||
<!-- Pines Notify JQuery plugin -->
|
<!-- Pines Notify JQuery plugin -->
|
||||||
<link href="{{ url_for('frontend.static', filename='third-party/pines-notify/jquery.pnotify.default.css') }}" rel="stylesheet">
|
<link href="{{ url_for('frontend.static', filename='third-party/pines-notify/jquery.pnotify.default.css') }}" rel="stylesheet">
|
||||||
@ -36,13 +40,14 @@
|
|||||||
<link href="{{ url_for('frontend.static', filename='css/main.css') }}" rel="stylesheet">
|
<link href="{{ url_for('frontend.static', filename='css/main.css') }}" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body style="padding-bottom:21px; padding-top: 40px">
|
<body style="padding-bottom: 50px; padding-top: 70px">
|
||||||
<div class="navbar navbar-fixed-top navbar-inverse">
|
<div class="navbar navbar-fixed-top navbar-inverse" role="navigation" ng-controller="AccountController">
|
||||||
<div class="navbar-inner" ng-controller="AccountController">
|
<div class="navbar-header">
|
||||||
<a class="brand" href="/"> Accountant</a>
|
<a class="navbar-brand" href="/"> Accountant</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Navbar with accounts and menu -->
|
<!-- Navbar with accounts and menu -->
|
||||||
<ul class="nav">
|
<ul class="nav navbar-nav">
|
||||||
<li class="{% if request.path == '/index.html' %}active{% endif %}"><a href="index.html">Opérations</a></li>
|
<li class="{% if request.path == '/index.html' %}active{% endif %}"><a href="index.html">Opérations</a></li>
|
||||||
<li class="{% if request.path == '/scheduler.html' %}active{% endif %}"><a href="scheduler.html">Planification</a></li>
|
<li class="{% if request.path == '/scheduler.html' %}active{% endif %}"><a href="scheduler.html">Planification</a></li>
|
||||||
|
|
||||||
@ -71,8 +76,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container">
|
||||||
<div class="row-fluid">
|
<div class="row">
|
||||||
{% block body %}{% endblock %}
|
{% block body %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -82,22 +87,20 @@
|
|||||||
<script type="text/javascript" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
|
<script type="text/javascript" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
|
||||||
|
|
||||||
<!-- Bootstrap Javascript library -->
|
<!-- Bootstrap Javascript library -->
|
||||||
<script type="text/javascript" src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
|
<script type="text/javascript" src="//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
|
||||||
|
|
||||||
<!-- Bootstrap datepicker module -->
|
<!-- Bootstrap datepicker module -->
|
||||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.0.2/js/bootstrap-datepicker.min.js"></script>
|
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.0.2/js/bootstrap-datepicker.min.js"></script>
|
||||||
|
|
||||||
<!-- Angular Javascript library -->
|
<!-- Angular Javascript library -->
|
||||||
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
|
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.min.js"></script>
|
||||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/0.7.4/angular-strap.js"></script>
|
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/0.7.4/angular-strap.js"></script>
|
||||||
|
|
||||||
<!-- D3 Plotting framework -->
|
<!-- D3 Plotting framework -->
|
||||||
<!--script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.2.2/d3.v3.js"></script-->
|
<script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script>
|
||||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/2.10.0/d3.v2.js"></script>
|
|
||||||
|
|
||||||
<!-- NVD3 framework -->
|
<!-- NVD3 framework -->
|
||||||
<!--script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/nvd3/1.0.0-beta/nv.d3.js"></script-->
|
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.13-beta/nv.d3.js"></script>
|
||||||
<script type="text/javascript" src="{{ url_for('frontend.static', filename='third-party/nv.d3/nv.d3.js') }}"></script>
|
|
||||||
|
|
||||||
<!-- Pines Notify JQuery plugin -->
|
<!-- Pines Notify JQuery plugin -->
|
||||||
<script type="text/javascript" src="{{ url_for('frontend.static', filename='third-party/pines-notify/jquery.pnotify.min.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('frontend.static', filename='third-party/pines-notify/jquery.pnotify.min.js') }}"></script>
|
||||||
@ -112,10 +115,16 @@ angular.module('$strap').config(function($interpolateProvider, $httpProvider) {
|
|||||||
|
|
||||||
$httpProvider.responseInterceptors.push(['$rootScope', '$q', function(scope, $q) {
|
$httpProvider.responseInterceptors.push(['$rootScope', '$q', function(scope, $q) {
|
||||||
function success(response) {
|
function success(response) {
|
||||||
|
console.debug(response)
|
||||||
|
if(response.data.ok == false) {
|
||||||
|
return $q.reject(response)
|
||||||
|
}
|
||||||
|
// TODO Intercept validation error.
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
function error(response) {
|
function error(response) {
|
||||||
|
// TODO Intercept Authentication Required error
|
||||||
$.pnotify({
|
$.pnotify({
|
||||||
type: "error",
|
type: "error",
|
||||||
title: response.data.title,
|
title: response.data.title,
|
||||||
|
39
frontend/templates/remove_entry.html
Normal file
39
frontend/templates/remove_entry.html
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<!--
|
||||||
|
This file is part of Accountant.
|
||||||
|
|
||||||
|
Accountant is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Foobar is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with Accountant. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
<div class="modal fade" id="remove_entry" role="dialog" aria-labeled-by="remove_entry_header" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<!-- Dialog header with title -->
|
||||||
|
<div class="modal-header">
|
||||||
|
<button class="close" ng-click="dismiss()" aria-hidden="true">×</button>
|
||||||
|
<h4 class="modal-title" id="remove_entry_header">Supprimer l'entrée [[entry.label]]</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Dialog body -->
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>Confirmez-vous la suppression de cette entrée ?</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Dialog footer with buttons -->
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button href="#" class="btn btn-primary" ng-click="dismiss()">Non</button>
|
||||||
|
<button href="#" class="btn btn-default" ng-click="removeEntry(entry, this)">Oui</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -17,15 +17,15 @@
|
|||||||
{% extends "layout.html" %}
|
{% extends "layout.html" %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<!-- Row with entry table -->
|
<!-- Row with entry table -->
|
||||||
<div class="row-fluid" ng-controller="SchedulerController">
|
<div class="row" ng-controller="SchedulerController">
|
||||||
<table class="table table-striped table-condensed table-hover">
|
<table class="table table-striped table-condensed table-hover">
|
||||||
<!-- Head of the table containing column headers and size -->
|
<!-- Head of the table containing column headers and size -->
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width: 100px">Date de début</th>
|
<th style="width: 120px">Date de début</th>
|
||||||
<th style="width: 100px">Date de fin</th>
|
<th style="width: 120px">Date de fin</th>
|
||||||
<th style="width: 50px">Jour</th>
|
<th style="width: 20px">Jour</th>
|
||||||
<th style="width: 50px">Fréq.</th>
|
<th style="width: 20px">Fréq.</th>
|
||||||
<th>Libellé de l'opération</th>
|
<th>Libellé de l'opération</th>
|
||||||
<th style="width: 50px">Montant</th>
|
<th style="width: 50px">Montant</th>
|
||||||
<th style="width: 100px">Catégorie</th>
|
<th style="width: 100px">Catégorie</th>
|
||||||
@ -37,41 +37,59 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr id="operation_[[operation.id]]" class="form-inline" ng-class="operationRowClass(operation.sold)" ng-repeat="operation in operations">
|
<tr id="operation_[[operation.id]]" class="form-inline" ng-class="operationRowClass(operation.sold)" ng-repeat="operation in operations">
|
||||||
<td>
|
<td>
|
||||||
<input ng-show="isEditing(operation)" type="text" class="input-small" ng-model="operation.start_date" data-date-format="yyyy-mm-dd" bs-datepicker/>
|
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.start_date" data-date-format="yyyy-mm-dd" bs-datepicker/>
|
||||||
<span ng-show="isDisplaying(operation)">[[operation.start_date]]</span>
|
<span ng-show="isDisplaying(operation)">[[operation.start_date]]</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<input ng-show="isEditing(operation)" type="text" class="input-small" ng-model="operation.stop_date" data-date-format="yyyy-mm-dd" bs-datepicker/>
|
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.stop_date" data-date-format="yyyy-mm-dd" bs-datepicker/>
|
||||||
<span ng-show="isDisplaying(operation)">[[operation.stop_date]]</span>
|
<span ng-show="isDisplaying(operation)">[[operation.stop_date]]</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<input ng-show="isEditing(operation)" type="text" class="input-mini" ng-model="operation.day"/>
|
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.day"/>
|
||||||
<span ng-show="isDisplaying(operation)">[[operation.day]]</span>
|
<span ng-show="isDisplaying(operation)">[[operation.day]]</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<input ng-show="isEditing(operation)" type="text" class="input-mini" ng-model="operation.frequency"/>
|
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.frequency"/>
|
||||||
<span ng-show="isDisplaying(operation)">[[operation.frequency]]</span>
|
<span ng-show="isDisplaying(operation)">[[operation.frequency]]</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<input ng-show="isEditing(operation)" type="text" class="input-xxlarge" ng-model="operation.label"/>
|
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.label"/>
|
||||||
<span ng-show="isDisplaying(operation)">[[operation.label]]</span>
|
<span ng-show="isDisplaying(operation)">[[operation.label]]</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<input ng-show="isEditing(operation)" type="text" class="input-mini" ng-model="operation.value"/>
|
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.value"/>
|
||||||
<span ng-show="isDisplaying(operation)">[[operation.value]]</span>
|
<span ng-show="isDisplaying(operation)">[[operation.value]]</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<input ng-show="isEditing(operation)" type="text" class="input-small" ng-model="operation.category" bs-typeahead="categories"/>
|
<input ng-show="isEditing(operation)" type="text" class="form-control input-sm" ng-model="operation.category" bs-typeahead="categories"/>
|
||||||
<span ng-show="isDisplaying(operation)">[[operation.category]]</span>
|
<span ng-show="isDisplaying(operation)">[[operation.category]]</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<div class="btn-group" ng-show="isEditing(operation)">
|
<div class="btn-group" ng-show="isEditing(operation)">
|
||||||
<a class="btn btn-mini btn-success" ng-click="saveOperation(operation)" href="#operation_[[operation.id]]" title="Save"><i ng-class="iconSaveClass(operation)"><span style="display: none">Save</span></i></a>
|
<button class="btn btn-xs btn-success" ng-click="saveOperation(operation)" title="Save">
|
||||||
<a class="btn btn-mini" ng-click="cancelEditOperation(operation)" href="#operation_[[operation.id]]" title="Cancel"><i ng-class="iconCancelClass(operation)"><span style="display: none">Cancel</span></i></a>
|
<span ng-class="iconSaveClass(operation)"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="btn btn-xs btn-default" ng-click="cancelEditOperation(operation)" title="Cancel">
|
||||||
|
<span ng-class="iconCancelClass(operation)"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-group" ng-show="isDisplaying(operation)">
|
<div class="btn-group" ng-show="isDisplaying(operation)">
|
||||||
<a class="btn btn-mini" ng-click="editOperation(operation)" href="#operation_[[operation.id]]" title="edit"><i class="icon-edit"><span style="display: none">Edit</span></i></a>
|
<button class="btn btn-xs btn-default" ng-click="editOperation(operation)" title="edit">
|
||||||
<a class="btn btn-mini" bs-modal="'{{ url_for('frontend.static', filename='templates/operation_remove.html') }}'" href="#operation_[[operation.id]]" title="remove"><i class="icon-trash"><span style="display: none">Remove</span></i></a>
|
<span class="fa fa-pencil-square-o"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="btn btn-xs btn-default" bs-modal="'{{ url_for('frontend.static', filename='templates/operation_remove.html') }}'" title="remove">
|
||||||
|
<span class="fa fa-trash-o"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
Loading…
Reference in New Issue
Block a user