Merge pull request #1 from deBankeGroup/dashboard

Dashboard work
pull/365/head
callumwhite20 2017-11-28 08:24:14 +00:00 committed by GitHub
commit 569a53df27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 9722 additions and 1303 deletions

View File

@ -100,6 +100,11 @@
"fonts/fontawesome-webfont.woff",
"fonts/fontawesome-webfont.woff2"
]
},
"angular-smart-table" : {
"main": [
"dist/smart-table.js"
]
}
}
}

8921
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,39 @@
<div class="row">
<div class="col-md-4" ng-controller="chartJs1DCtrl">
<div ba-panel ba-panel-title="Pie" ba-panel-class="with-scroll ">
<div class="chartjs-canvas-holder-first-row">
<div class="col-md-6" ng-controller="chartJs1DCtrl">
<div ba-panel ba-panel-title="Current Sprint" ba-panel-class="with-scroll ">
<div class="row">
<div class="col-md-6">
<canvas id="doughnut" chart-options="options" class="chart chart-doughnut"
chart-data="data" chart-labels="labels" chart-click="changeData">
</canvas>
</div>
<div class="col-md-6">
<canvas id="pie" class="chart chart-pie"
chart-options="options" chart-data="data" chart-labels="labels"
chart-click="changeData">
</canvas>
</div>
</div>
</div>
<div class="col-md-4" ng-controller="chartJs1DCtrl">
</div>
<!-- <div class="col-md-4" ng-controller="chartJs1DCtrl">
<div ba-panel ba-panel-title="Doughnut" ba-panel-class="with-scroll ">
</div>
</div> -->
<div class="col-md-3" ng-controller="chartJs1DCtrl">
<div ba-panel ba-panel-title="Polar" ba-panel-class="with-scroll ">
<div class="chartjs-canvas-holder-first-row">
<canvas id="doughnut" chart-options="options" class="chart chart-doughnut"
chart-data="data" chart-labels="labels" chart-click="changeData">
<canvas id="polar-area" class="chart chart-polar-area"
chart-data="data" chart-options="options" chart-labels="labels"
chart-click="changeData">
</canvas>
</div>
</div>
</div>
<div class="col-md-4" ng-controller="chartJs1DCtrl">
<div class="col-md-3" ng-controller="chartJs1DCtrl">
<div ba-panel ba-panel-title="Polar" ba-panel-class="with-scroll ">
<div class="chartjs-canvas-holder-first-row">
<canvas id="polar-area" class="chart chart-polar-area"
@ -29,7 +44,7 @@
</div>
</div>
</div>
<!--
<div class="row ">
<div class="col-md-6" ng-controller="chartJsWaveCtrl">
<div ba-panel ba-panel-title="Animated Radar" ba-panel-class="col-eq-height">
@ -76,6 +91,6 @@
</div>
</div>
</div>
</div>
</div> -->

View File

@ -9,9 +9,13 @@
.controller('chartJs1DCtrl', chartJs1DCtrl);
/** @ngInject */
function chartJs1DCtrl($scope, baConfig) {
function chartJs1DCtrl($scope, baConfig, $http) {
var layoutColors = baConfig.colors;
var headers = {
'Authorization': 'Basic cmljaGFyZG1vaGFtbWVkMTpzanZKRnozTk5DektuU041alJ5SA=='
};
$scope.labels =["Sleeping", "Designing", "Coding", "Cycling"];
$scope.data = [20, 40, 5, 35];
$scope.options = {
@ -37,6 +41,18 @@
for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x){}
return o;
}
function returnSessionsFromBrowserstackPromise(buildId){
$http.get('https://www.browserstack.com/automate/builds/' + buildId + '/sessions.json', {
headers: {'Authorization': 'Basic cmljaGFyZG1vaGFtbWVkMTpzanZKRnozTk5DektuU041alJ5SA=='}
}).then(function(response){
console.log('response', response);
});
}
returnSessionsFromBrowserstackPromise('2f7a6dca052a67852693cd3bdef03356255e0745');
}
})();

BIN
src/app/pages/dashboard/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -1,129 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.controller('BlurFeedCtrl', BlurFeedCtrl);
/** @ngInject */
function BlurFeedCtrl($scope) {
$scope.feed = [
{
type: 'text-message',
author: 'Kostya',
surname: 'Danovsky',
header: 'Posted new message',
text: 'Guys, check this out: \nA police officer found a perfect hiding place for watching for speeding motorists. One day, the officer was amazed when everyone was under the speed limit, so he investigated and found the problem. A 10 years old boy was standing on the side of the road with a huge hand painted sign which said "Radar Trap Ahead." A little more investigative work led the officer to the boy\'s accomplice: another boy about 100 yards beyond the radar trap with a sign reading "TIPS" and a bucket at his feet full of change.',
time: 'Today 11:55 pm',
ago: '25 minutes ago',
expanded: false,
}, {
type: 'video-message',
author: 'Andrey',
surname: 'Hrabouski',
header: 'Added new video',
text: '"Vader and Me"',
preview: 'app/feed/vader-and-me-preview.png',
link: 'https://www.youtube.com/watch?v=IfcpzBbbamk',
time: 'Today 9:30 pm',
ago: '3 hrs ago',
expanded: false,
}, {
type: 'image-message',
author: 'Vlad',
surname: 'Lugovsky',
header: 'Added new image',
text: '"My little kitten"',
preview: 'app/feed/my-little-kitten.png',
link: 'http://api.ning.com/files/DtcI2O2Ry7A7VhVxeiWfGU9WkHcMy4WSTWZ79oxJq*h0iXvVGndfD7CIYy-Ax-UAFCBCdqXI4GCBw3FOLKTTjQc*2cmpdOXJ/1082127884.jpeg',
time: 'Today 2:20 pm',
ago: '10 hrs ago',
expanded: false,
}, {
type: 'text-message',
author: 'Nasta',
surname: 'Linnie',
header: 'Posted new message',
text: 'Haha lol',
time: '11.11.2015',
ago: '2 days ago',
expanded: false,
}, {
type: 'geo-message',
author: 'Nick',
surname: 'Cat',
header: 'Posted location',
text: '"New York, USA"',
preview: 'app/feed/new-york-location.png',
link: 'https://www.google.by/maps/place/New+York,+NY,+USA/@40.7201111,-73.9893872,14z',
time: '11.11.2015',
ago: '2 days ago',
expanded: false,
}, {
type: 'text-message',
author: 'Vlad',
surname: 'Lugovsky',
header: 'Posted new message',
text: "First snake: I hope I'm not poisonous. Second snake: Why? First snake: Because I bit my lip!",
time: '12.11.2015',
ago: '3 days ago',
expanded: false,
}, {
type: 'text-message',
author: 'Andrey',
surname: 'Hrabouski',
header: 'Posted new message',
text: 'How do you smuggle an elephant across the border? Put a slice of bread on each side, and call him "lunch".',
time: '14.11.2015',
ago: '5 days ago',
expanded: false,
}, {
type: 'text-message',
author: 'Nasta',
surname: 'Linnie',
header: 'Posted new message',
text: 'When your hammer is C++, everything begins to look like a thumb.',
time: '14.11.2015',
ago: '5 days ago',
expanded: false,
}, {
type: 'text-message',
author: 'Alexander',
surname: 'Demeshko',
header: 'Posted new message',
text: '“I mean, they say you die twice. One time when you stop breathing and a second time, a bit later on, when somebody says your name for the last time." ©',
time: '15.11.2015',
ago: '6 days ago',
expanded: false,
}, {
type: 'image-message',
author: 'Nick',
surname: 'Cat',
header: 'Posted photo',
text: '"Protein Heroes"',
preview: 'app/feed/genom.png',
link: 'https://dribbble.com/shots/2504810-Protein-Heroes',
time: '16.11.2015',
ago: '7 days ago',
expanded: false,
},
{
type: 'text-message',
author: 'Kostya',
surname: 'Danovsky',
header: 'Posted new message',
text: 'Why did the CoffeeScript developer keep getting lost? Because he couldn\'t find his source without a map',
time: '18.11.2015',
ago: '9 days ago',
expanded: false,
}
];
$scope.expandMessage = function(message){
message.expanded = !message.expanded;
}
}
})();

View File

@ -1,19 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.directive('blurFeed', blurFeed);
/** @ngInject */
function blurFeed() {
return {
restrict: 'E',
controller: 'BlurFeedCtrl',
templateUrl: 'app/pages/dashboard/blurFeed/blurFeed.html'
};
}
})();

View File

@ -1,33 +0,0 @@
<div class="feed-messages-container" track-width="smallContainerWidth" min-width="360">
<div class="feed-message" ng-repeat="message in feed" ng-click="expandMessage(message)">
<div class="message-icon" ng-if="message.type == 'text-message'">
<img class="photo-icon" ng-src="{{::( message.author | profilePicture )}}">
</div>
<div class="message-icon" ng-if="message.type != 'text-message'">
<img class="photo-icon" ng-src="{{::( message.author | profilePicture )}}">
<span class="sub-photo-icon" ng-class="::message.type"></span>
</div>
<div class="text-block text-message">
<div class="message-header">
<span class="author">{{ ::message.author }} {{ ::message.surname}}</span>
</div>
<div class="message-content line-clamp" ng-class="{'line-clamp-2' : !message.expanded}">
<span ng-if="message.preview">{{message.header}} </span>{{::message.text}}
</div>
<div class="preview" ng-show="message.expanded" ng-if="message.preview">
<a href="{{::message.link}}" target="_blank">
<img ng-src="{{ ::( message.preview | appImage )}}">
</a>
</div>
<div ng-show="message.expanded" class="message-time">
<div class="post-time">
{{::message.time}}
</div>
<div class="ago-time">
{{::message.ago}}
</div>
</div>
</div>
</div>
</div>

View File

@ -1,15 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.service('dashboardCalendar', dashboardCalendar);
/** @ngInject */
function dashboardCalendar() {
}
})();

View File

@ -0,0 +1,202 @@
/**
* @author a.demeshko
* created on 12/16/15
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.controller('chartJs1DCtrl', chartJs1DCtrl);
/** @ngInject */
function chartJs1DCtrl($scope, baConfig, $http, $interval) {
var layoutColors = baConfig.colors;
var stories = [];
var complete = 0;
var inProgress = 0;
var toDo = 0;
var frontEnd = 0;
var backEnd = 0;
var devOps = 0;
$scope.progressLabels = ["Complete", "In progress", "To do"];
$scope.progressData = [complete, inProgress, toDo];
$scope.progressColors = ['#0BD680', '#FFC93C', '#DBDBDB'];
$scope.teamLabels = ["Front end", "Back end", "Devops"];
$scope.teamData = [frontEnd, backEnd, devOps];
$scope.teamColors = ['#0BD680', '#626EEF', '#FFC93C'];
$scope.options = {
elements: {
arc: {
borderWidth: 0
}
},
legend: {
display: true,
position: 'bottom',
labels: {
fontColor: layoutColors.defaultText
}
}
};
function getPivotalStories() {
var projectId = '1993279';
var version = 'v0.98';
var queryParams = [
'token=dbd3bfeb53beb6097fe299ab189e50b8',
'limit=200',
'filter=label:"' + version + '" (label:"approved" OR label:"no approval required")'
];
var url = 'https://www.pivotaltracker.com/services/v5/projects/' + projectId + '/stories';
$http({
method: 'GET',
url: url + '?' + queryParams.join('&')
}).then(function (response) {
stories = response.data;
complete = 0;
inProgress = 0;
toDo = 0;
frontEnd = 0;
backEnd = 0;
devOps = 0;
stories.forEach(function (story) {
if (story.current_state === 'accepted' && story.estimate >= 0) {
complete += story.estimate;
} else if (story.current_state === 'unstarted' && story.estimate >= 0) {
toDo += story.estimate;
} else if (story.estimate >= 0) {
inProgress += story.estimate;
}
story.labels.forEach(function (label) {
if (label.name === 'back end' && story.estimate >= 0) {
backEnd += story.estimate;
} else if (label.name === 'front end' && story.estimate >= 0) {
frontEnd += story.estimate;
} else if (label.name === 'devops' && story.estimate >= 0) {
devOps += story.estimate;
}
});
});
$scope.progressData = [complete, inProgress, toDo];
$scope.teamData = [frontEnd, backEnd, devOps];
});
}
function getBrowserStackData() {
var queryParams1 = [
'type=builds'
];
var queryParams2 = [
'type=buildSessions'
];
$http({
method: 'GET',
url: 'http://localhost:3001/browserstack_php.php' + '?' + queryParams1.join('&')
}).then(function (data) {
queryParams2.push('buildId=' + data.data.results[0].automation_build.hashed_id);
$http({
method: 'GET',
url: 'http://localhost:3001/browserstack_php.php' + '?' + queryParams2.join('&')
}).then(function (response) {
$scope.behatResults = {
failed: 0,
passed: 0,
windows: {
chrome: {
name: 'Chrome',
passed: 0,
failed: 0,
percentage: 0
},
firefox: {
name: 'Firefox',
passed: 0,
failed: 0,
percentage: 0
},
ie: {
name: 'Internet Explorer',
passed: 0,
failed: 0,
percentage: 0
},
edge: {
name: 'Microsoft Edge',
passed: 0,
failed: 0,
percentage: 0
}
},
mac: {
chrome: {
name: 'Chrome',
passed: 0,
failed: 0,
percentage: 0
},
firefox: {
name: 'Firefox',
passed: 0,
failed: 0,
percentage: 0
},
safari: {
name: 'Safari',
passed: 0,
failed: 0,
percentage: 0
}
}
};
function calcPercentage(browser) {
$scope.behatResults.windows[browser].percentage = (($scope.behatResults.windows[browser].passed / ($scope.behatResults.windows[browser].passed + $scope.behatResults.windows[browser].failed)) * 100).toFixed(2);
}
function browserTestLog(test, status) {
if (test.os === 'Windows') {
$scope.behatResults.windows[test.browser][status] += 1;
calcPercentage(test.browser);
}
}
response.data.results.forEach(function (test) {
var session = test.automation_session;
if (session.status === 'passed') {
$scope.behatResults.passed += 1;
browserTestLog(session, 'passed')
} else if (session.status === 'failed') {
$scope.behatResults.failed += 1;
browserTestLog(session, 'failed')
}
});
});
});
}
$interval(getPivotalStories, 120000);
$interval(getBrowserStackData, 300000);
getPivotalStories();
getBrowserStackData();
}
})();

View File

@ -0,0 +1,32 @@
/**
* @author a.demeshko
* created on 12/16/15
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.controller('chartJs2DCtrl', chartJs2DCtrl);
/** @ngInject */
function chartJs2DCtrl($scope) {
$scope.labels =["May", "Jun", "Jul", "Aug", "Sep"];
$scope.data = [
[65, 59, 90, 81, 56],
[28, 48, 40, 19, 88]
];
$scope.series = ['Product A', 'Product B'];
$scope.changeData = function () {
$scope.data[0] = shuffle($scope.data[0]);
$scope.data[1] = shuffle($scope.data[1]);
};
function shuffle(o){
for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x){}
return o;
}
}
})();

View File

@ -0,0 +1,86 @@
/**
* @author a.demeshko
* created on 12/16/15
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.controller('chartJs3DCtrl', chartJs3DCtrl);
/** @ngInject */
function chartJs3DCtrl($scope, $http, $filter, $interval) {
var users;
var stories;
$scope.workInProgress = [];
function compare(a, b) {
if (a.owners[0].name < b.owners[0].name)
return -1;
if (a.owners[0].name > b.owners[0].name)
return 1;
return 0;
}
function getPivotalStories() {
var projectId = '1993279';
var version = 'v0.98';
var queryParams = [
'token=dbd3bfeb53beb6097fe299ab189e50b8',
'limit=200',
'filter=label:"' + version + '" state:started (label:"approved" OR label:"no approval required")'
];
var url = 'https://www.pivotaltracker.com/services/v5/projects/' + projectId + '/stories';
return $http({
method: 'GET',
url: url + '?' + queryParams.join('&')
});
}
function getPivotalUsers() {
var projectId = '1993279';
var auth = '?token=dbd3bfeb53beb6097fe299ab189e50b8';
var url = 'https://www.pivotaltracker.com/services/v5/projects/' + projectId + '/memberships';
$http({
method: 'GET',
url: url + auth
}).then(function (response) {
getPivotalStories().then(function (data) {
$scope.workInProgress = [];
users = {};
stories = data.data;
response.data.forEach(function (user) {
var items = $filter('filter')(stories, {owned_by_id: user.person.id});
users[user.person.id] = user.person;
});
stories.forEach(function (story, index) {
story.owners = [];
story.owner_ids.forEach(function (ownerId) {
story.owners.push(users[ownerId]);
});
$scope.workInProgress.push(story);
$scope.workInProgress.sort(compare);
});
});
});
}
$interval(getPivotalUsers, 120000);
getPivotalUsers();
}
})();

View File

@ -0,0 +1,29 @@
/**
* @author a.demeshko
* created on 12/16/15
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.controller('chartJsWaveCtrl', chartJsWaveCtrl);
/** @ngInject */
function chartJsWaveCtrl($scope, $interval, stopableInterval) {
$scope.labels =["Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
$scope.data = [1, 9, 3, 4, 5, 6, 7, 8, 2].map(function(e){
return Math.sin(e) * 25 +25;
});
stopableInterval.start($interval, function(){
var tempArray = [];
var lastElement = $scope.data[$scope.data.length-1];
for(var i = $scope.data.length-1; i > 0; i--){
tempArray[i] = $scope.data[i-1];
}
tempArray[0] = lastElement;
$scope.data = tempArray;
}, 400)
}
})();

View File

@ -1,63 +1,77 @@
<dashboard-pie-chart></dashboard-pie-chart>
<div class="row">
<div class="col-lg-6 col-md-12 col-sm-12"
ba-panel
ba-panel-title="Acquisition Channels"
ba-panel-class="medium-panel traffic-panel">
<traffic-chart></traffic-chart>
</div>
<div class="col-lg-6 col-md-12 col-sm-12"
ba-panel
ba-panel-title="Users by Country"
ba-panel-class="medium-panel">
<dashboard-map></dashboard-map>
</div>
</div>
<div class="row">
<div class="col-xlg-9 col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div class="col-md-8" ng-controller="chartJs1DCtrl">
<div ba-panel ba-panel-title="Current Sprint" ba-panel-class="with-scroll ">
<div class="row">
<div class="col-xlg-8 col-lg-12 col-md-12 col-sm-7 col-xs-12"
ba-panel
ba-panel-title="Revenue"
ba-panel-class="medium-panel">
<dashboard-line-chart></dashboard-line-chart>
<div class="col-md-6">
<canvas id="doughnut" chart-options="options" class="chart chart-doughnut"
chart-data="progressData" chart-labels="progressLabels" chart-colors="progressColors" chart-click="changeData">
</canvas>
</div>
<div class="col-xlg-4 col-lg-12 col-md-12 col-sm-5 col-xs-12"
ba-panel
ba-panel-class="popular-app medium-panel">
<popular-app></popular-app>
<div class="col-md-6">
<canvas id="pie" class="chart chart-pie"
chart-options="options" chart-data="teamData" chart-labels="teamLabels"
chart-click="changeData" chart-colors="teamColors">
</canvas>
</div>
</div>
</div>
<div class="col-xlg-3 col-lg-6 col-md-6 col-sm-12 col-xs-12"
ba-panel
ba-panel-title="Feed"
ba-panel-class="large-panel with-scroll feed-panel">
<blur-feed></blur-feed>
<div ba-panel ba-panel-title="Behat results" ba-panel-class="with-scroll">
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-5">
<div class="behat-box failed" data-ng-class="{'no-results': behatResults.failed === 0}">
<p>Failed</p>
<h1>{{behatResults.failed}}</h1>
</div>
</div>
<div class="col-md-5">
<div class="behat-box passed" data-ng-class="{'no-results': behatResults.passed === 0}">
<p>Passed</p>
<h1>{{behatResults.passed}}</h1>
</div>
</div>
<div class="col-md-1"></div>
</div>
<hr style="margin: 30px 8%;"/>
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-5">
<h4>Windows</h4>
<div class="browser-row" data-ng-repeat="(browser, results) in behatResults.windows" data-ng-class="results.percentage === 100 ? 'passed' : results.percentage === 0 ? 'no-results' : 'failed'">
<ul>
<li>
<span>{{results.name}}</span><span style="float: right;">{{results.percentage}}%</span>
</li>
</ul>
</div>
</div>
<div class="col-md-5">
<h4>Mac</h4>
<div class="browser-row" data-ng-repeat="(browser, results) in behatResults.mac" data-ng-class="results.percentage === 100 ? 'passed' : results.percentage === 0 ? 'no-results' : 'failed'">
<ul>
<li>
<span>{{results.name}}</span><span style="float: right;">{{results.percentage}}%</span>
</li>
</ul>
</div>
</div>
<div class="col-md-1"></div>
</div>
</div>
</div>
<div class="col-md-4" ng-controller="chartJs3DCtrl">
<div ba-panel ba-panel-title="Work in progress" ba-panel-class="with-scroll ">
<div class="item" data-ng-repeat="story in workInProgress track by $index" style="border-bottom: 1px solid #E6EAEE; margin-bottom: 6px;">
<div style="font-weight: 600;"><span data-ng-repeat="owner in story.owners" class="list-of-words">{{owner.name}}</span> <span style="float: right;">#{{story.id}}</span></div>
<p style="padding-top: 3px;">{{story.name}}</p>
</div>
</div>
</div>
</div>
<div class="row shift-up">
<div class="col-xlg-3 col-lg-6 col-md-6 col-xs-12"
ba-panel
ba-panel-title="To Do List"
ba-panel-class="xmedium-panel feed-comply-panel with-scroll todo-panel">
<dashboard-todo></dashboard-todo>
</div>
<div class="col-xlg-6 col-lg-6 col-md-6 col-xs-12"
ba-panel
ba-panel-title="Calendar"
ba-panel-class="xmedium-panel feed-comply-panel with-scroll calendar-panel">
<dashboard-calendar></dashboard-calendar>
</div>
</div>
<!--<div class="row">
<div class="col-lg-4 col-sm-6 col-xs-12">
<div ba-panel ba-panel-title="Weather" ba-panel-class="medium-panel with-scroll">
<blur-weather forecast="5"></blur-weather>
</div>
</div>
</div>-->

View File

@ -6,7 +6,7 @@
'use strict';
angular.module('BlurAdmin.pages.dashboard', [])
.config(routeConfig);
.config(routeConfig).config(chartJsConfig);
/** @ngInject */
function routeConfig($stateProvider) {
@ -22,4 +22,52 @@
});
}
function chartJsConfig(ChartJsProvider, baConfigProvider) {
var layoutColors = baConfigProvider.colors;
// Configure all charts
ChartJsProvider.setOptions({
chartColors: [
layoutColors.primary, layoutColors.danger, layoutColors.warning, layoutColors.success, layoutColors.info, layoutColors.default, layoutColors.primaryDark, layoutColors.successDark, layoutColors.warningLight, layoutColors.successLight, layoutColors.primaryLight],
responsive: true,
maintainAspectRatio: false,
animation: {
duration: 2500
},
scale: {
gridLines: {
color: layoutColors.border
},
scaleLabel: {
fontColor: layoutColors.defaultText
},
ticks: {
fontColor: layoutColors.defaultText,
showLabelBackdrop: false
}
}
});
// Configure all line charts
ChartJsProvider.setOptions('Line', {
datasetFill: false
});
// Configure all radar charts
ChartJsProvider.setOptions('radar', {
scale: {
pointLabels: {
fontColor: layoutColors.defaultText
},
ticks: {
maxTicksLimit: 5,
display: false
}
}
});
// Configure all bar charts
ChartJsProvider.setOptions('bar', {
tooltips: {
enabled: false
}
});
}
})();

View File

@ -1,64 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.controller('DashboardCalendarCtrl', DashboardCalendarCtrl);
/** @ngInject */
function DashboardCalendarCtrl(baConfig) {
var dashboardColors = baConfig.colors.dashboard;
var $element = $('#calendar').fullCalendar({
//height: 335,
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultDate: '2016-03-08',
selectable: true,
selectHelper: true,
select: function (start, end) {
var title = prompt('Event Title:');
var eventData;
if (title) {
eventData = {
title: title,
start: start,
end: end
};
$element.fullCalendar('renderEvent', eventData, true); // stick? = true
}
$element.fullCalendar('unselect');
},
editable: true,
eventLimit: true, // allow "more" link when too many events
events: [
{
title: 'All Day Event',
start: '2016-03-01',
color: dashboardColors.silverTree
},
{
title: 'Long Event',
start: '2016-03-07',
end: '2016-03-10',
color: dashboardColors.blueStone
},
{
title: 'Dinner',
start: '2016-03-14T20:00:00',
color: dashboardColors.surfieGreen
},
{
title: 'Birthday Party',
start: '2016-04-01T07:00:00',
color: dashboardColors.gossipDark
}
]
});
}
})();

View File

@ -1,19 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.directive('dashboardCalendar', dashboardCalendar);
/** @ngInject */
function dashboardCalendar() {
return {
restrict: 'E',
controller: 'DashboardCalendarCtrl',
templateUrl: 'app/pages/dashboard/dashboardCalendar/dashboardCalendar.html'
};
}
})();

View File

@ -1 +0,0 @@
<div id='calendar' class="blurCalendar"></div>

View File

@ -1,126 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.controller('DashboardLineChartCtrl', DashboardLineChartCtrl);
/** @ngInject */
function DashboardLineChartCtrl(baConfig, layoutPaths, baUtil) {
var layoutColors = baConfig.colors;
var graphColor = baConfig.theme.blur ? '#000000' : layoutColors.primary;
var chartData = [
{ date: new Date(2012, 11), value: 0, value0: 0 },
{ date: new Date(2013, 0), value: 15000, value0: 19000},
{ date: new Date(2013, 1), value: 30000, value0: 20000},
{ date: new Date(2013, 2), value: 25000, value0: 22000},
{ date: new Date(2013, 3), value: 21000, value0: 25000},
{ date: new Date(2013, 4), value: 24000, value0: 29000},
{ date: new Date(2013, 5), value: 31000, value0: 26000},
{ date: new Date(2013, 6), value: 40000, value0: 25000},
{ date: new Date(2013, 7), value: 37000, value0: 20000},
{ date: new Date(2013, 8), value: 18000, value0: 22000},
{ date: new Date(2013, 9), value: 5000, value0: 26000},
{ date: new Date(2013, 10), value: 40000, value0: 30000},
{ date: new Date(2013, 11), value: 20000, value0: 25000},
{ date: new Date(2014, 0), value: 5000, value0: 13000},
{ date: new Date(2014, 1), value: 3000, value0: 13000},
{ date: new Date(2014, 2), value: 1800, value0: 13000},
{ date: new Date(2014, 3), value: 10400, value0: 13000},
{ date: new Date(2014, 4), value: 25500, value0: 13000},
{ date: new Date(2014, 5), value: 2100, value0: 13000},
{ date: new Date(2014, 6), value: 6500, value0: 13000},
{ date: new Date(2014, 7), value: 1100, value0: 13000},
{ date: new Date(2014, 8), value: 17200, value0: 13000},
{ date: new Date(2014, 9), value: 26900, value0: 13000},
{ date: new Date(2014, 10), value: 14100, value0: 13000},
{ date: new Date(2014, 11), value: 35300, value0: 13000},
{ date: new Date(2015, 0), value: 54800, value0: 13000},
{ date: new Date(2015, 1), value: 49800, value0: 13000}
];
var chart = AmCharts.makeChart('amchart', {
type: 'serial',
theme: 'blur',
marginTop: 15,
marginRight: 15,
dataProvider: chartData,
categoryField: 'date',
categoryAxis: {
parseDates: true,
gridAlpha: 0,
color: layoutColors.defaultText,
axisColor: layoutColors.defaultText
},
valueAxes: [
{
minVerticalGap: 50,
gridAlpha: 0,
color: layoutColors.defaultText,
axisColor: layoutColors.defaultText
}
],
graphs: [
{
id: 'g0',
bullet: 'none',
useLineColorForBulletBorder: true,
lineColor: baUtil.hexToRGB(graphColor, 0.3),
lineThickness: 1,
negativeLineColor: layoutColors.danger,
type: 'smoothedLine',
valueField: 'value0',
fillAlphas: 1,
fillColorsField: 'lineColor'
},
{
id: 'g1',
bullet: 'none',
useLineColorForBulletBorder: true,
lineColor: baUtil.hexToRGB(graphColor, 0.5),
lineThickness: 1,
negativeLineColor: layoutColors.danger,
type: 'smoothedLine',
valueField: 'value',
fillAlphas: 1,
fillColorsField: 'lineColor'
}
],
chartCursor: {
categoryBalloonDateFormat: 'MM YYYY',
categoryBalloonColor: '#4285F4',
categoryBalloonAlpha: 0.7,
cursorAlpha: 0,
valueLineEnabled: true,
valueLineBalloonEnabled: true,
valueLineAlpha: 0.5
},
dataDateFormat: 'MM YYYY',
export: {
enabled: true
},
creditsPosition: 'bottom-right',
zoomOutButton: {
backgroundColor: '#fff',
backgroundAlpha: 0
},
zoomOutText: '',
pathToImages: layoutPaths.images.amChart
});
function zoomChart() {
chart.zoomToDates(new Date(2013, 3), new Date(2014, 0));
}
chart.addListener('rendered', zoomChart);
zoomChart();
if (chart.zoomChart) {
chart.zoomChart();
}
}
})();

View File

@ -1,19 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.directive('dashboardLineChart', dashboardLineChart);
/** @ngInject */
function dashboardLineChart() {
return {
restrict: 'E',
controller: 'DashboardLineChartCtrl',
templateUrl: 'app/pages/dashboard/dashboardLineChart/dashboardLineChart.html'
};
}
})();

View File

@ -1 +0,0 @@
<div id="amchart"></div>

View File

@ -1,104 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.controller('DashboardMapCtrl', DashboardMapCtrl);
/** @ngInject */
function DashboardMapCtrl(baConfig, layoutPaths) {
var layoutColors = baConfig.colors;
var map = AmCharts.makeChart('amChartMap', {
type: 'map',
theme: 'blur',
zoomControl: { zoomControlEnabled: false, panControlEnabled: false },
dataProvider: {
map: 'worldLow',
zoomLevel: 3.5,
zoomLongitude: 10,
zoomLatitude: 52,
areas: [
{ title: 'Austria', id: 'AT', color: layoutColors.primary, customData: '1 244', groupId: '1'},
{ title: 'Ireland', id: 'IE', color: layoutColors.primary, customData: '1 342', groupId: '1'},
{ title: 'Denmark', id: 'DK', color: layoutColors.primary, customData: '1 973', groupId: '1'},
{ title: 'Finland', id: 'FI', color: layoutColors.primary, customData: '1 573', groupId: '1'},
{ title: 'Sweden', id: 'SE', color: layoutColors.primary, customData: '1 084', groupId: '1'},
{ title: 'Great Britain', id: 'GB', color: layoutColors.primary, customData: '1 452', groupId: '1'},
{ title: 'Italy', id: 'IT', color: layoutColors.primary, customData: '1 321', groupId: '1'},
{ title: 'France', id: 'FR', color: layoutColors.primary, customData: '1 112', groupId: '1'},
{ title: 'Spain', id: 'ES', color: layoutColors.primary, customData: '1 865', groupId: '1'},
{ title: 'Greece', id: 'GR', color: layoutColors.primary, customData: '1 453', groupId: '1'},
{ title: 'Germany', id: 'DE', color: layoutColors.primary, customData: '1 957', groupId: '1'},
{ title: 'Belgium', id: 'BE', color: layoutColors.primary, customData: '1 011', groupId: '1'},
{ title: 'Luxembourg', id: 'LU', color: layoutColors.primary, customData: '1 011', groupId: '1'},
{ title: 'Netherlands', id: 'NL', color: layoutColors.primary, customData: '1 213', groupId: '1'},
{ title: 'Portugal', id: 'PT', color: layoutColors.primary, customData: '1 291', groupId: '1'},
{ title: 'Lithuania', id: 'LT', color: layoutColors.successLight, customData: '567', groupId: '2'},
{ title: 'Latvia', id: 'LV', color: layoutColors.successLight, customData: '589', groupId: '2'},
{ title: 'Czech Republic ', id: 'CZ', color: layoutColors.successLight, customData: '785', groupId: '2'},
{ title: 'Slovakia', id: 'SK', color: layoutColors.successLight, customData: '965', groupId: '2'},
{ title: 'Estonia', id: 'EE', color: layoutColors.successLight, customData: '685', groupId: '2'},
{ title: 'Hungary', id: 'HU', color: layoutColors.successLight, customData: '854', groupId: '2'},
{ title: 'Cyprus', id: 'CY', color: layoutColors.successLight, customData: '754', groupId: '2'},
{ title: 'Malta', id: 'MT', color: layoutColors.successLight, customData: '867', groupId: '2'},
{ title: 'Poland', id: 'PL', color: layoutColors.successLight, customData: '759', groupId: '2'},
{ title: 'Romania', id: 'RO', color: layoutColors.success, customData: '302', groupId: '3'},
{ title: 'Bulgaria', id: 'BG', color: layoutColors.success, customData: '102', groupId: '3'},
{ title: 'Slovenia', id: 'SI', color: layoutColors.danger, customData: '23', groupId: '4'},
{ title: 'Croatia', id: 'HR', color: layoutColors.danger, customData: '96', groupId: '4'}
]
},
areasSettings: {
rollOverOutlineColor: layoutColors.border,
rollOverColor: layoutColors.primaryDark,
alpha: 0.8,
unlistedAreasAlpha: 0.2,
unlistedAreasColor: layoutColors.defaultText,
balloonText: '[[title]]: [[customData]] users'
},
legend: {
width: '100%',
marginRight: 27,
marginLeft: 27,
equalWidths: false,
backgroundAlpha: 0.3,
backgroundColor: layoutColors.border,
borderColor: layoutColors.border,
borderAlpha: 1,
top: 362,
left: 0,
horizontalGap: 10,
data: [
{
title: 'over 1 000 users',
color: layoutColors.primary
},
{
title: '500 - 1 000 users',
color: layoutColors.successLight
},
{
title: '100 - 500 users',
color: layoutColors.success
},
{
title: '0 - 100 users',
color: layoutColors.danger
}
]
},
export: {
enabled: true
},
creditsPosition: 'bottom-right',
pathToImages: layoutPaths.images.amChart
});
}
})();

View File

@ -1,19 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.directive('dashboardMap', dashboardMap);
/** @ngInject */
function dashboardMap() {
return {
restrict: 'E',
controller: 'DashboardMapCtrl',
templateUrl: 'app/pages/dashboard/dashboardMap/dashboardMap.html'
};
}
})();

View File

@ -1 +0,0 @@
<div id="amChartMap"></div>

View File

@ -1,75 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.controller('DashboardPieChartCtrl', DashboardPieChartCtrl);
/** @ngInject */
function DashboardPieChartCtrl($scope, $timeout, baConfig, baUtil) {
var pieColor = baUtil.hexToRGB(baConfig.colors.defaultText, 0.2);
$scope.charts = [{
color: pieColor,
description: 'New Visits',
stats: '57,820',
icon: 'person',
}, {
color: pieColor,
description: 'Purchases',
stats: '$ 89,745',
icon: 'money',
}, {
color: pieColor,
description: 'Active Users',
stats: '178,391',
icon: 'face',
}, {
color: pieColor,
description: 'Returned',
stats: '32,592',
icon: 'refresh',
}
];
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
function loadPieCharts() {
$('.chart').each(function () {
var chart = $(this);
chart.easyPieChart({
easing: 'easeOutBounce',
onStep: function (from, to, percent) {
$(this.el).find('.percent').text(Math.round(percent));
},
barColor: chart.attr('rel'),
trackColor: 'rgba(0,0,0,0)',
size: 84,
scaleLength: 0,
animation: 2000,
lineWidth: 9,
lineCap: 'round',
});
});
$('.refresh-data').on('click', function () {
updatePieCharts();
});
}
function updatePieCharts() {
$('.pie-charts .chart').each(function(index, chart) {
$(chart).data('easyPieChart').update(getRandomArbitrary(55, 90));
});
}
$timeout(function () {
loadPieCharts();
updatePieCharts();
}, 1000);
}
})();

View File

@ -1,19 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.directive('dashboardPieChart', dashboardPieChart);
/** @ngInject */
function dashboardPieChart() {
return {
restrict: 'E',
controller: 'DashboardPieChartCtrl',
templateUrl: 'app/pages/dashboard/dashboardPieChart/dashboardPieChart.html'
};
}
})();

View File

@ -1,14 +0,0 @@
<div class="row pie-charts">
<div class="pie-chart-item-container" ng-repeat="chart in charts">
<div ba-panel>
<div class="pie-chart-item">
<div class="chart" rel="{{ ::chart.color }}" data-percent="60"> <span class="percent"></span> </div>
<div class="description">
<div>{{ ::chart.description }}</div>
<div class="description-stats">{{ ::chart.stats }}</div>
</div>
<i class="chart-icon i-{{ ::chart.icon }}"></i>
</div>
</div>
</div>
</div>

View File

@ -1,55 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.controller('DashboardTodoCtrl', DashboardTodoCtrl);
/** @ngInject */
function DashboardTodoCtrl($scope, baConfig) {
$scope.transparent = baConfig.theme.blur;
var dashboardColors = baConfig.colors.dashboard;
var colors = [];
for (var key in dashboardColors) {
colors.push(dashboardColors[key]);
}
function getRandomColor() {
var i = Math.floor(Math.random() * (colors.length - 1));
return colors[i];
}
$scope.todoList = [
{ text: 'Check me out' },
{ text: 'Lorem ipsum dolor sit amet, possit denique oportere at his, etiam corpora deseruisse te pro' },
{ text: 'Ex has semper alterum, expetenda dignissim' },
{ text: 'Vim an eius ocurreret abhorreant, id nam aeque persius ornatus.' },
{ text: 'Simul erroribus ad usu' },
{ text: 'Ei cum solet appareat, ex est graeci mediocritatem' },
{ text: 'Get in touch with akveo team' },
{ text: 'Write email to business cat' },
{ text: 'Have fun with blur admin' },
{ text: 'What do you think?' },
];
$scope.todoList.forEach(function(item) {
item.color = getRandomColor();
});
$scope.newTodoText = '';
$scope.addToDoItem = function (event, clickPlus) {
if (clickPlus || event.which === 13) {
$scope.todoList.unshift({
text: $scope.newTodoText,
color: getRandomColor(),
});
$scope.newTodoText = '';
}
};
}
})();

View File

@ -1,19 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.directive('dashboardTodo', dashboardTodo);
/** @ngInject */
function dashboardTodo() {
return {
restrict: 'EA',
controller: 'DashboardTodoCtrl',
templateUrl: 'app/pages/dashboard/dashboardTodo/dashboardTodo.html'
};
}
})();

View File

@ -1,18 +0,0 @@
<div class="task-todo-container" ng-class="{'transparent': transparent}">
<input type="text" value="" class="form-control task-todo" placeholder="Task to do.." ng-keyup="addToDoItem($event)" ng-model="newTodoText"/>
<i ng-click="addToDoItem('',true)" class="add-item-icon ion-plus-round"></i>
<div class="box-shadow-border"></div>
<ul class="todo-list" ui-sortable ng-model="todoList">
<li ng-repeat="item in todoList" ng-if="!item.deleted" ng-init="activeItem=false"
ng-class="{checked: isChecked, active: activeItem}"
ng-mouseenter="activeItem=true" ng-mouseleave="activeItem=false">
<div class="blur-container"><div class="blur-box"></div></div>
<i class="mark" style="background-color: {{::item.color}}"></i>
<label class="todo-checkbox custom-checkbox custom-input-success">
<input type="checkbox" ng-model="isChecked">
<span class="cut-with-dots">{{ item.text }}</span>
</label>
<i class="remove-todo ion-ios-close-empty" ng-click="item.deleted = true"></i>
</li>
</ul>
</div>

View File

@ -1,15 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.service('dashboardPieChart', dashboardPieChart);
/** @ngInject */
function dashboardPieChart() {
}
})();

View File

@ -1,18 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.directive('popularApp', popularApp);
/** @ngInject */
function popularApp() {
return {
restrict: 'E',
templateUrl: 'app/pages/dashboard/popularApp/popularApp.html'
};
}
})();

View File

@ -1,28 +0,0 @@
<div class="popular-app-img-container">
<div class="popular-app-img">
<img ng-src="{{::( 'app/my-app-logo.png' | appImage )}}"/>
<span class="logo-text">Super&nbspApp</span>
</div>
</div>
<div class="popular-app-cost row">
<div class="col-xs-9">
Most Popular App
</div>
<div class="col-xs-3 text-right">
175$
</div>
</div>
<div class="popular-app-info row">
<div class="col-xs-4 text-left">
<div class="info-label">Total Visits</div>
<div>47,512</div>
</div>
<div class="col-xs-4 text-center">
<div class="info-label">New Visits</div>
<div>9,217</div>
</div>
<div class="col-xs-4 text-right">
<div class="info-label">Sales</div>
<div>2,928</div>
</div>
</div>

View File

@ -1,61 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.controller('TrafficChartCtrl', TrafficChartCtrl);
/** @ngInject */
function TrafficChartCtrl($scope, baConfig, colorHelper) {
$scope.transparent = baConfig.theme.blur;
var dashboardColors = baConfig.colors.dashboard;
$scope.doughnutData = {
labels: [
'Other',
'Search engines',
'Referral Traffic',
'Direct Traffic',
'Ad Campaigns'
],
datasets: [
{
data: [2000, 1500, 1000, 1200, 400],
backgroundColor: [
dashboardColors.white,
dashboardColors.blueStone,
dashboardColors.surfieGreen,
dashboardColors.silverTree,
dashboardColors.gossip
],
hoverBackgroundColor: [
colorHelper.shade(dashboardColors.white, 15),
colorHelper.shade(dashboardColors.blueStone, 15),
colorHelper.shade(dashboardColors.surfieGreen, 15),
colorHelper.shade(dashboardColors.silverTree, 15),
colorHelper.shade(dashboardColors.gossip, 15)
],
percentage: [87, 22, 70, 38, 17]
}]
};
var ctx = document.getElementById('chart-area').getContext('2d');
window.myDoughnut = new Chart(ctx, {
type: 'doughnut',
data: $scope.doughnutData,
options: {
cutoutPercentage: 64,
responsive: true,
elements: {
arc: {
borderWidth: 0
}
}
}
});
}
})();

View File

@ -1,19 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.directive('trafficChart', trafficChart);
/** @ngInject */
function trafficChart() {
return {
restrict: 'E',
controller: 'TrafficChartCtrl',
templateUrl: 'app/pages/dashboard/trafficChart/trafficChart.html'
};
}
})();

View File

@ -1,29 +0,0 @@
<div class="channels-block" ng-class="{'transparent': transparent}">
<div class="chart-bg"></div>
<div class="traffic-chart" id="trafficChart">
<div class="canvas-holder">
<canvas id="chart-area" width="280" height="280"></canvas>
<div class="traffic-text">
1,900,128
<span>Views Total</span>
</div>
</div>
</div>
<div class="channels-info">
<div>
<div class="channels-info-item" ng-repeat="label in doughnutData.labels"
ng-init="i = $index; data = doughnutData.datasets[0]">
<div class="legend-color" style="background-color: {{::data.backgroundColor[i]}}"></div>
<p>{{::label}}<span class="channel-number">+{{data.percentage[i]}}%</span></p>
<div class="progress progress-sm channel-progress">
<div class="progress-bar " role="progressbar"
aria-valuenow="{{data.percentage[i]}}" aria-valuemin="0" aria-valuemax="100"
style="width: {{item.percentage}}%">
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,144 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.controller('WeatherCtrl', WeatherCtrl);
/** @ngInject */
function WeatherCtrl($scope, $http, $timeout, $element) {
var url = 'http://api.openweathermap.org/data/2.5/forecast';
var method = 'GET';
var key = '2de143494c0b295cca9337e1e96b00e0';
var middleOfTheDay = 15;
$scope.units = 'metric';
$scope.weatherIcons = {
'01d': 'ion-ios-sunny-outline',
'02d': 'ion-ios-partlysunny-outline',
'03d': 'ion-ios-cloud-outline',
'04d': 'ion-ios-cloud',
'09d': 'ion-ios-rainy',
'10d': 'ion-ios-rainy-outline',
'11d': 'ion-ios-thunderstorm-outline',
'13d': 'ion-ios-snowy',
'50d': 'ion-ios-cloudy-outline',
'01n': 'ion-ios-cloudy-night-outline',
'02n': 'ion-ios-cloudy-night',
'03n': 'ion-ios-cloud-outline',
'04n': 'ion-ios-cloud',
'09n': 'ion-ios-rainy',
'10n': 'ion-ios-rainy-outline',
'11n': 'ion-ios-thunderstorm',
'13n': 'ion-ios-snowy',
'50n': 'ion-ios-cloudy-outline'
};
$scope.weather = {};
$scope.switchUnits = function (name) {
$scope.units = name;
$scope.updateWeather();
};
$scope.switchDay = function (day) {
$scope.weather.current = day;
makeChart($scope.weather.days[$scope.weather.current].timeTemp)
};
$scope.updateWeather = function () {
$http({
method: method, url: url, params: {
appid: key,
lat: $scope.geoData.geoplugin_latitude,
lon: $scope.geoData.geoplugin_longitude,
units: $scope.units
}
}).then(function success(response) {
saveWeatherData(response.data);
makeChart($scope.weather.days[$scope.weather.current].timeTemp)
}, function error() {
console.log("WEATHER FAILED")
});
};
function updateGeoData() {
$http.jsonp('http://www.geoplugin.net/json.gp?jsoncallback=JSON_CALLBACK').then(function success(response) {
$scope.geoData = response.data;
$scope.updateWeather();
}, function error() {
console.log("GEO FAILED")
});
}
function makeChart(data) {
AmCharts.makeChart('tempChart', {
type: 'serial',
theme: 'blur',
handDrawn: true,
categoryField: 'time',
dataProvider: data,
valueAxes: [
{
axisAlpha: 0.3,
gridAlpha: 0
}
],
graphs: [
{
bullet: 'square',
fillAlphas: 0.3,
fillColorsField: 'lineColor',
legendValueText: '[[value]]',
lineColorField: 'lineColor',
title: 'Temp',
valueField: 'temp'
}
],
categoryAxis: {
gridAlpha: 0,
axisAlpha: 0.3
}
}).write('tempChart');
}
function saveWeatherData(data) {
var firstItem = data.list[0];
var weather = {
days: [{
date: new Date(),
timeTemp: [],
main: firstItem.weather[0].main,
description: firstItem.weather[0].description,
icon: firstItem.weather[0].icon,
temp: firstItem.main.temp
}], current: 0
};
data.list.forEach(function (item, i) {
var itemDate = new Date(item.dt_txt);
if (itemDate.getDate() !== weather.days[weather.days.length - 1].date.getDate()) {
weather.days.push({date: itemDate, timeTemp: []});
}
var lastItem = weather.days[weather.days.length - 1];
lastItem.timeTemp.push({
time: itemDate.getHours(),
temp: item.main.temp
});
if ((weather.days.length > 1 && itemDate.getHours() == middleOfTheDay) || i == data.list.length - 1) {
lastItem.main = item.weather[0].main;
lastItem.description = item.weather[0].description;
lastItem.icon = item.weather[0].icon;
lastItem.temp = item.main.temp;
lastItem.date.setHours(i == data.list.length - 1 ? 0 : middleOfTheDay);
lastItem.date.setMinutes(0);
}
});
console.log(weather.days[weather.current].date);
weather.days = weather.days.slice(0, $element.attr('forecast') || 5);
$scope.weather = weather;
}
updateGeoData();
}
})();

View File

@ -1,19 +0,0 @@
/**
* @author v.lugovksy
* created on 16.12.2015
*/
(function () {
'use strict';
angular.module('BlurAdmin.pages.dashboard')
.directive('weather', weather);
/** @ngInject */
function weather() {
return {
restrict: 'EA',
controller: 'WeatherCtrl',
templateUrl: 'app/pages/dashboard/weather/weather.html'
};
}
})();

View File

@ -1,45 +0,0 @@
<div class="weather-wrapper">
<div class="weather-main-info">
<h5 class="city-date font-x1dot5">
<div>
{{geoData.geoplugin_city}} - {{geoData.geoplugin_countryName | uppercase}}
</div>
<div>
{{ weather.days[weather.current].date | date : 'EEEE h:mm'}}
</div>
</h5>
<div class="weather-description font-x1dot5">
<i class="font-x3 {{weatherIcons[weather.days[weather.current].icon]}}"></i>
<div class="weather-info">{{weather.days[weather.current].main}} -
{{weather.days[weather.current].description}}
</div>
</div>
<div class="weather-temp font-x1dot5">
<i class="font-x2 ion-thermometer"></i>
<div class="weather-info" ng-switch on="units">
<span ng-switch-when="metric">{{weather.days[weather.current].temp}} °C | <a
ng-click="switchUnits('imperial')" href>°F</a></span>
<span ng-switch-when="imperial">{{weather.days[weather.current].temp}} °F | <a
ng-click="switchUnits('metric')" href>°C</a></span>
</div>
</div>
</div>
<div id="tempChart" class="temp-by-time"></div>
<div class="select-day">
<div class="day" ng-repeat="day in weather.days" ng-click="switchDay($index)">
<div>
<span class="font-x1dot25">{{day.temp}}</span>
</div>
<div>
<i class="weatherIcon font-x2 {{weatherIcons[day.icon]}}"></i></td>
<span class="select-day-info">{{day.main}}</span>
</div>
<div>
<span>{{day.date | date : 'EEE'}}</span>
</div>
</div>
</div>
</div>
</div>

View File

@ -7,15 +7,7 @@
angular.module('BlurAdmin.pages', [
'ui.router',
'BlurAdmin.pages.dashboard',
'BlurAdmin.pages.ui',
'BlurAdmin.pages.components',
'BlurAdmin.pages.form',
'BlurAdmin.pages.tables',
'BlurAdmin.pages.charts',
'BlurAdmin.pages.maps',
'BlurAdmin.pages.profile',
'BlurAdmin.pages.dashboard'
])
.config(routeConfig);
@ -23,40 +15,40 @@
function routeConfig($urlRouterProvider, baSidebarServiceProvider) {
$urlRouterProvider.otherwise('/dashboard');
baSidebarServiceProvider.addStaticItem({
title: 'Pages',
icon: 'ion-document',
subMenu: [{
title: 'Sign In',
fixedHref: 'auth.html',
blank: true
}, {
title: 'Sign Up',
fixedHref: 'reg.html',
blank: true
}, {
title: 'User Profile',
stateRef: 'profile'
}, {
title: '404 Page',
fixedHref: '404.html',
blank: true
}]
});
baSidebarServiceProvider.addStaticItem({
title: 'Menu Level 1',
icon: 'ion-ios-more',
subMenu: [{
title: 'Menu Level 1.1',
disabled: true
}, {
title: 'Menu Level 1.2',
subMenu: [{
title: 'Menu Level 1.2.1',
disabled: true
}]
}]
});
// baSidebarServiceProvider.addStaticItem({
// title: 'Pages',
// icon: 'ion-document',
// subMenu: [{
// title: 'Sign In',
// fixedHref: 'auth.html',
// blank: true
// }, {
// title: 'Sign Up',
// fixedHref: 'reg.html',
// blank: true
// }, {
// title: 'User Profile',
// stateRef: 'profile'
// }, {
// title: '404 Page',
// fixedHref: '404.html',
// blank: true
// }]
// });
// baSidebarServiceProvider.addStaticItem({
// title: 'Menu Level 1',
// icon: 'ion-ios-more',
// subMenu: [{
// title: 'Menu Level 1.1',
// disabled: true
// }, {
// title: 'Menu Level 1.2',
// subMenu: [{
// title: 'Menu Level 1.2.1',
// disabled: true
// }]
// }]
// });
}
})();

View File

@ -1,9 +1 @@
<div class="content-top clearfix">
<h1 class="al-title">{{ activePageTitle }}</h1>
<ul class="breadcrumb al-breadcrumb">
<li>
<a href="#/dashboard">Home</a></li>
<li>{{ activePageTitle }}</li>
</ul>
</div>
<h1 class="al-title" style="color: white;">{{ activePageTitle }}</h1>

View File

@ -1,24 +1,13 @@
<div class="page-top clearfix" scroll-position="scrolled" max-height="50" ng-class="{'scrolled': scrolled}">
<a href="#/dashboard" class="al-logo clearfix"><span>Blur</span>Admin</a>
<a href="#/dashboard" class="al-logo clearfix">
<span class="inverted icon icon-ip-centrum">
<span class="path1"></span>
<span class="path2"></span>
</span>
</a>
<a href class="collapse-menu-link ion-navicon" ba-sidebar-toggle-menu></a>
<div class="search">
<i class="ion-ios-search-strong" ng-click="startSearch()"></i>
<input id="searchInput" type="text" placeholder="Search for...">
</div>
<div class="user-profile clearfix">
<div class="al-user-profile" uib-dropdown>
<a uib-dropdown-toggle class="profile-toggle-link">
<img ng-src="{{::( 'Nasta' | profilePicture )}}">
</a>
<ul class="top-dropdown-menu profile-dropdown" uib-dropdown-menu>
<li><i class="dropdown-arr"></i></li>
<li><a href="#/profile"><i class="fa fa-user"></i>Profile</a></li>
<li><a href><i class="fa fa-cog"></i>Settings</a></li>
<li><a href class="signout"><i class="fa fa-power-off"></i>Sign out</a></li>
</ul>
</div>
<msg-center></msg-center>
<content-top></content-top>
</div>
</div>

160
src/browserstack_php.php Normal file
View File

@ -0,0 +1,160 @@
<?php
class HTTP_Request_Helper {
public static function request($method, $request_url, $data = NULL, $headers = array(), $followRedirected = FALSE)
{
$returnValue = FALSE;
if ($cURL = curl_init()) {
curl_setopt($cURL, CURLOPT_CUSTOMREQUEST, mb_strtoupper($method));
curl_setopt($cURL, CURLOPT_HEADER, TRUE);
curl_setopt($cURL, CURLOPT_HTTPHEADER, $headers);
curl_setopt($cURL, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($cURL, CURLOPT_TIMEOUT, 60);
curl_setopt($cURL, CURLOPT_CONNECTTIMEOUT, 10);
if (in_array(mb_strtoupper($method), array('PATCH', 'POST', 'PUT')) && !empty($data)) {
curl_setopt($cURL, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($cURL, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($cURL, CURLOPT_URL, $request_url);
if ($followRedirected) {
curl_setopt($cURL, CURLOPT_FOLLOWLOCATION, TRUE);
} else {
curl_setopt($cURL, CURLOPT_FOLLOWLOCATION, FALSE);
}
if (defined('DISABLE_SSL_SECURITY_FOR_TESTING') && DISABLE_SSL_SECURITY_FOR_TESTING) {
curl_setopt($cURL, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($cURL, CURLOPT_SSL_VERIFYPEER, FALSE);
}
if ($response = curl_exec($cURL)) {
list($responseHeaders, $responseBody) = explode("\r\n\r\n", $response, 2);
$returnValue['status'] = curl_getinfo($cURL, CURLINFO_HTTP_CODE);
$tmpHeaders = explode("\r\n", $responseHeaders);
$returnValue['headers'] = array();
foreach ($tmpHeaders AS $str) {
if (!preg_match('/^HTTP\\//u', $str)) {
list($Key, $value) = explode(': ', $str, 2);
$returnValue['headers'][$Key] = $value;
}
}
$returnValue['body'] = $responseBody;
}
curl_close($cURL);
}
return $returnValue;
}
}
class BrowserStackAPI_Helper
{
protected $apiRoot = 'https://www.browserstack.com/';
protected $token = NULL;
public function setAccessToken($token) {
$this->token = $token;
}
public function get($request_uri, $data = NULL, $headers = array(), $parse_body = TRUE)
{
return self::request('GET', $request_uri, $data, $headers, $parse_body);
}
private function request($method, $request_uri, $data = NULL, $headers = array(), $parse_body = TRUE)
{
if (NULL !== $this->token) {
$headers[] = 'Authorization: Basic ' . $this->token;
}
// Force to JSON for now - ideally this needs to look at the current Output::$outputFormat to ensure returned data is consistent
$headers[] = 'Accept: application/json';
return self::makeRequest($method, $request_uri, $data, $headers, $parse_body);
}
private function makeRequest($method, $request_uri, $data = NULL, $headers = array(), $parse_body = TRUE)
{
$returnValue = FALSE;
$request_url = $this->apiRoot . ltrim($request_uri, '/');
$response = HTTP_Request_Helper::request($method, $request_url, $data, $headers);
if (FALSE !== $response) {
$returnValue = array();
$returnValue['status'] = $response['status'];
$returnValue['headers'] = $response['headers'];
$returnValue['body'] = json_decode($response['body'], TRUE);
} else {
$returnValue = array();
$returnValue['status'] = 504;
$returnValue['headers'] = array();
$returnValue['body'] = '';
}
return $returnValue;
}
}
class BrowserStackClient extends BrowserStackAPI_Helper
{
public function __construct($username, $password)
{
$token = $this->generateToken($username, $password);
$this->setAccessToken($token);
}
public function buildSessions($buildId)
{
return $this->get('automate/builds/' . $buildId . '/sessions.json');
}
public function builds()
{
return $this->get('automate/builds.json');
}
private function generateToken($user, $password)
{
return base64_encode($user . ':' . $password);
}
}
$user = 'danneh1';
$password = '5gXqwjkDjBtTiLVmvsLV';
$browserStackClient = new BrowserStackClient($user, $password);
$buildId = '7ecd9b26fd193d25102ef8e45acad32b02127615';
if ($_GET['type'] == 'builds') {
$response = $browserStackClient->builds();
if (isset($response['body']) && is_array($response['body'])) {
echo json_encode(['results' => $response['body']]);
} else {
echo json_encode(['errors' => ['No results found for builds.']]);
}
} else if (isset($_GET['type']) && $_GET['type'] == 'buildSessions' && isset($_GET['buildId'])) {
$buildId = $_GET['buildId'];
$response = $browserStackClient->buildSessions($buildId);
if (isset($response['body']) && is_array($response['body'])) {
echo json_encode(['results' => $response['body']]);
} else {
if (!$buildId) {
echo json_encode(['errors' => ['GET parameter of buildId is required for buildSessions query.']]);
} else {
echo json_encode(['errors' => ['No results found for build sessions.']]);
}
}
} else {
echo json_encode(['errors' => ['GET parameter of builds of buildSessions is required.']]);
}
?>

View File

@ -6,7 +6,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Blur Admin</title>
<link href='https://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900italic,900&subset=latin,greek,greek-ext,vietnamese,cyrillic-ext,latin-ext,cyrillic' rel='stylesheet' type='text/css'>
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i" rel="stylesheet">
<link rel="stylesheet" href="https://s3.amazonaws.com/icomoon.io/68294/IPCentrum-Application/style.css?5au8gz" />
<link rel="icon" type="image/png" sizes="16x16" href="assets/img/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="assets/img/favicon-32x32.png">
@ -32,26 +33,10 @@
<page-top></page-top>
<div class="al-main">
<div class="al-content">
<content-top></content-top>
<div class="al-content" style="padding-top: 24px;">
<div ui-view autoscroll="true" autoscroll-body-top></div>
</div>
</div>
<footer class="al-footer clearfix">
<div class="al-footer-right">Created with <i class="ion-heart"></i></div>
<div class="al-footer-main clearfix">
<div class="al-copy">Blur Admin 2016</div>
<ul class="al-share clearfix">
<li><i class="socicon socicon-facebook"></i></li>
<li><i class="socicon socicon-twitter"></i></li>
<li><i class="socicon socicon-google"></i></li>
<li><i class="socicon socicon-github"></i></li>
</ul>
</div>
</footer>
<back-top></back-top>
</main>
<div id="preloader" ng-show="!$pageFinishedLoading">

View File

@ -21,3 +21,60 @@
.blurCalendar{
height: 475px;
}
.list-of-words:not(:nth-last-child(2)):after {
content: ", ";
}
.behat-box {
border-radius: 8px;
padding: 24px 48px;
box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.25);
&.passed:not(.no-results) {
background: #0BD680;
}
&.failed:not(.no-results) {
background: #FF004E;
color: white;
}
&.no-results {
background: #DBDBDB;
opacity: 0.4;
}
p {
margin-bottom: 24px;
}
h1 {
text-align: right;
margin-bottom: 0px;
}
}
.browser-row {
padding: 6px;
border-radius: 4px;
margin-bottom: 3px;
&.passed {
background: rgba(11, 214, 128, 0.12);
}
&.failed {
background: rgba(255, 0, 78, 0.12);
}
&.no-results {
background: #DBDBDB;
opacity: 0.4;
}
> ul {
margin-bottom: 0;
padding-left: 24px;
}
}

View File

@ -70,7 +70,7 @@ a {
.al-main {
margin-left: $left-space;
padding: 66px 0 34px 0;
padding-top: 66px;
min-height: 500px;
}

View File

@ -6,7 +6,7 @@ $panel-heading-font-size: 16px;
color: $default-text;
background-color: $default;
border: none;
border-radius: 5px;
border-radius: 8px;
position: relative;
margin-bottom: 24px;
box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.25);

View File

@ -11,7 +11,6 @@ h1.al-title {
margin: 0;
padding: 0;
font-size: 24px;
text-transform: uppercase;
opacity: 0.9;
}

View File

@ -14,17 +14,22 @@
}
a.al-logo {
color: $sidebar-text;
color: white;
display: block;
font-size: 24px;
font-size: 28px;
font-family: $font-family;
white-space: nowrap;
float: left;
outline: none !important;
line-height: 60px;
position: relative;
right: 18px;
top: 3px;
span {
color: $primary;
.path2:before {
color: white;
position: relative;
right: 14px;
}
}

View File

@ -1,4 +1,4 @@
$font-family: 'Roboto', sans-serif;
$font-family: 'Source Sans Pro', sans-serif;
$activelink: $primary;
$hoverlink: $primary-dark;

View File

@ -11,7 +11,7 @@ $border-light: tint($border, 15%);
$input-border: shade($border, 5%);
$input-background: #ffffff;
$sidebar: #1C2B36;
$sidebar: #273142;
$sidebar-text: #ffffff;
$dropdown-text: #7d7d7d;
$bootstrap-panel-text: #7d7d7d;