Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 0b27c108

Přidáno uživatelem Jan Kohlíček před asi 7 roky(ů)

refs #6777: Komunikace s REST API, přispůsobení REST API, vyhledávání lokalit, možnost schovat graf, ošetření expirace tokenu, přidání loading screenu, generování tokenu do stránky

Zobrazit rozdíly:

.idea/php.xml
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project version="4">
3
  <component name="PhpIncludePathManager">
4
    <include_path>
5
      <path value="$PROJECT_DIR$/backend/vendor/psr/log" />
6
      <path value="$PROJECT_DIR$/backend/vendor/sebastian/comparator" />
7
      <path value="$PROJECT_DIR$/backend/vendor/sebastian/global-state" />
8
      <path value="$PROJECT_DIR$/backend/vendor/sebastian/exporter" />
9
      <path value="$PROJECT_DIR$/backend/vendor/sebastian/environment" />
10
      <path value="$PROJECT_DIR$/backend/vendor/doctrine/inflector" />
11
      <path value="$PROJECT_DIR$/backend/vendor/sebastian/diff" />
12
      <path value="$PROJECT_DIR$/backend/vendor/doctrine/instantiator" />
13
      <path value="$PROJECT_DIR$/backend/vendor/sebastian/recursion-context" />
14
      <path value="$PROJECT_DIR$/backend/vendor/sebastian/version" />
15
      <path value="$PROJECT_DIR$/backend/vendor/symfony/process" />
16
      <path value="$PROJECT_DIR$/backend/vendor/phpdocumentor/reflection-docblock" />
17
      <path value="$PROJECT_DIR$/backend/vendor/symfony/console" />
18
      <path value="$PROJECT_DIR$/backend/vendor/symfony/polyfill-php56" />
19
      <path value="$PROJECT_DIR$/backend/vendor/phpdocumentor/reflection-common" />
20
      <path value="$PROJECT_DIR$/backend/vendor/symfony/debug" />
21
      <path value="$PROJECT_DIR$/backend/vendor/phpdocumentor/type-resolver" />
22
      <path value="$PROJECT_DIR$/backend/vendor/symfony/http-kernel" />
23
      <path value="$PROJECT_DIR$/backend/vendor/nikic/fast-route" />
24
      <path value="$PROJECT_DIR$/backend/vendor/symfony/polyfill-util" />
25
      <path value="$PROJECT_DIR$/backend/vendor/symfony/event-dispatcher" />
26
      <path value="$PROJECT_DIR$/backend/vendor/symfony/finder" />
27
      <path value="$PROJECT_DIR$/backend/vendor/symfony/polyfill-mbstring" />
28
      <path value="$PROJECT_DIR$/backend/vendor/symfony/translation" />
29
      <path value="$PROJECT_DIR$/backend/vendor/symfony/yaml" />
30
      <path value="$PROJECT_DIR$/backend/vendor/symfony/http-foundation" />
31
      <path value="$PROJECT_DIR$/backend/vendor/phpunit/php-timer" />
32
      <path value="$PROJECT_DIR$/backend/vendor/phpunit/php-file-iterator" />
33
      <path value="$PROJECT_DIR$/backend/vendor/phpunit/php-token-stream" />
34
      <path value="$PROJECT_DIR$/backend/vendor/webmozart/assert" />
35
      <path value="$PROJECT_DIR$/backend/vendor/phpunit/php-text-template" />
36
      <path value="$PROJECT_DIR$/backend/vendor/phpunit/php-code-coverage" />
37
      <path value="$PROJECT_DIR$/backend/vendor/vlucas/phpdotenv" />
38
      <path value="$PROJECT_DIR$/backend/vendor/phpunit/phpunit-mock-objects" />
39
      <path value="$PROJECT_DIR$/backend/vendor/phpunit/phpunit" />
40
      <path value="$PROJECT_DIR$/backend/vendor/fzaninotto/faker" />
41
      <path value="$PROJECT_DIR$/backend/vendor/phpspec/prophecy" />
42
      <path value="$PROJECT_DIR$/backend/vendor/laravel/lumen-framework" />
43
      <path value="$PROJECT_DIR$/backend/vendor/mtdowling/cron-expression" />
44
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/container" />
45
      <path value="$PROJECT_DIR$/backend/vendor/nesbot/carbon" />
46
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/console" />
47
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/bus" />
48
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/pagination" />
49
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/cache" />
50
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/session" />
51
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/auth" />
52
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/contracts" />
53
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/hashing" />
54
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/broadcasting" />
55
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/filesystem" />
56
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/database" />
57
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/pipeline" />
58
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/encryption" />
59
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/view" />
60
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/http" />
61
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/translation" />
62
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/support" />
63
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/config" />
64
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/queue" />
65
      <path value="$PROJECT_DIR$/backend/vendor/paragonie/random_compat" />
66
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/events" />
67
      <path value="$PROJECT_DIR$/backend/vendor/monolog/monolog" />
68
      <path value="$PROJECT_DIR$/backend/vendor/illuminate/validation" />
69
      <path value="$PROJECT_DIR$/backend/vendor/composer" />
70
      <path value="$PROJECT_DIR$/backend/vendor/firebase/php-jwt" />
71
    </include_path>
72
  </component>
73
  <component name="PhpProjectSharedConfiguration" php_language_level="5.5.0" />
74
  <component name="PhpUnit">
75
    <phpunit_settings>
76
      <PhpUnitSettings load_method="CUSTOM_LOADER" custom_loader_path="$PROJECT_DIR$/backend/vendor/autoload.php" />
77
    </phpunit_settings>
78
  </component>
79
</project>
backend/app/Http/Controllers/DeviceController.php
27 27
        }
28 28

  
29 29
        $device = Zarizeni::findByAddressJoinAddress($address);
30
        if ($device == null || count($device) == 0) {
31
            return response('Not found.', 404);
32
        }
33 30

  
34 31
        return $device;
35 32
    }
......
74 71

  
75 72
        $device = Zarizeni::findByIdJoinAddress($id);
76 73
        if ($device != null) {
77
            $device[0]->traffic = Zaznam::findByDevice($id, $dateFrom, $dateTo, $timeFrom, $timeTo, $direction);
78
        } else if ($device == null || count($device) == 0) {
74
            $device->traffic = Zaznam::findByDevice($id, $dateFrom, $dateTo, $timeFrom, $timeTo, $direction);
75
            return json_encode($device);
76
        } else {
79 77
            return response('Not found.', 404);
80 78
        }
81

  
82
        return $device;
83 79
    }
84 80

  
85 81
    public function getAll() {
backend/app/Http/Controllers/VehicleController.php
18 18
     * Vrati vsechny typy vozidel.
19 19
     */
20 20
    public function getAll() {
21
        $vehicles = Vozidlo::all();
21
        $vehicles = Vozidlo::from('vozidlo')->select('vozidlo.id', 'vozidlo.nazev as name')->get();
22 22

  
23 23
        if ($vehicles == null || count($vehicles) == 0) {
24 24
            return response('Not found.', 404);
backend/app/Model/Zarizeni.php
78 78
            ->select('zarizeni.id as id', 'zarizeni.smer_popis as name', 'ulice.nazev as street', 'ulice.id as street_id', 'mesto.nazev as town', 'mesto.id as town_id')
79 79
            ->where('zarizeni.id', '=', $id)
80 80
            ->orderBy('zarizeni.id')
81
            ->get();
81
            ->first();
82 82
    }
83 83

  
84 84
    /**
backend/lib/generateToken.php
1
<?php
2

  
3
require_once __DIR__ . '/../vendor/autoload.php';
4

  
5
try {
6
    (new Dotenv\Dotenv(__DIR__ . '/../'))->load();
7
} catch (Dotenv\Exception\InvalidPathException $e) {
8
    //
9
}
10

  
11
use Illuminate\Http\Request;
12
use \Firebase\JWT\JWT;
13

  
14
function generateToken() {
15
    $request = Request::createFromGlobals();
16
    // parametry jwt
17
    $key = env('JWT_SECRET', '');
18
    $iss = env('JWT_ISS', 'aswi-doprava');
19

  
20
    $duration = env('JWT_DURATION', 1800);
21
    $iat = time();
22
    $exp = $iat + $duration;
23

  
24
    // generovani tokenu
25
    $token = array(
26
        'iss' => $iss,
27
        'iat' => $iat,
28
        'exp' => $exp,
29
        'ipaddr' => $request->ip(),
30
        'user-agent' => $request->header('User-Agent')
31
    );
32

  
33
    $jwt = JWT::encode($token, $key, 'HS256');
34

  
35
    return $jwt;
36
}
frontend/app.js
1
var app = angular.module('pvpk', ['ngRoute', 'ngResource']);
1 2

  
2
//var app = angular.module('PVPK', []);
3

  
4

  
5
// app.controller('myController', function($scope, $http, $window) {
6
//     $scope.render = function() {
7
//         var url = 'http://www.recipepuppy.com/api/';
8
//
9
//         var c = $window.angular.callbacks.counter.toString(36);
10
//         $window['angularcallbacks' + c] = function (data) {
11
//             $window.angular.callbacks['_' + c](data);
12
//             delete $window['angularcallbacks' + c];
13
//         };
14
//
15
//         $http.jsonp('http://www.recipepuppy.com/api/?i=onions,garlic&q=omelet&p=1&callback=JSON_CALLBACK').then(function(response) {
16
//             $scope.records = response.data.results;
17
//         });
18
//     };
19
//
20
//     $scope.render();
21
// });
3
app.constant('config', {
4
    APP_NAME: 'PVPK',
5
    APP_VERSION: 1.0,
6
    API_URL: API_URL,
7
    API_TOKEN: API_TOKEN
8
});
9

  
10

  
11
// app.config(function($stateProvider, $locationProvider) {
12
//     // $stateProvider
13
//     // .state('report',{
14
//     //     views: {
15
//     //         'search': {
16
//     //             templateUrl: 'report-filters.html',
17
//     //             controller: searchController
18
//     //         },
19
//     //         'graph': {
20
//     //             templateUrl: 'report-table.html',
21
//     //             controller: graphController
22
//     //         },
23
//     //         'map': {
24
//     //             templateUrl: 'report-graph.html',
25
//     //             controller: mapController
26
//     //         }
27
//     //     }
28
//     // });
29
//    $locationProvider.html5Mode(true);
30
// });
31

  
32
app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
33

  
34
}]);
35

  
36

  
37
app.controller('mainController', function ($rootScope, $scope, $http, $window) {
38

  
39
    this.$onInit = function () {
40
        $scope.showLoadingScreen = false;
41
    };
42

  
43
    $rootScope.handleErrorResponse = function (response) {
44
        switch (response.status) {
45
            case 400:
46
                console.log('API ERROR 400');
47
                break;
48
            case 401:
49
                jQuery('#modalExpiredToken').modal('show');
50
                break;
51
            case 404:
52
                console.log('API ERROR 404');
53
                break;
54
            case 500:
55
                console.log('API ERROR 500');
56
                break;
57
            default:
58
        }
59
    };
60

  
61
    $scope.reloadApp = function () {
62
        $window.location.reload();
63
    }
64
});
65

  
66

  
67
app.controller('searchController', function ($rootScope, $scope, $location, config, Device) {
68

  
69
    this.$onInit = function () {
70
        var fromTime = new Date();
71
        fromTime.setHours(7, 0, 0, 0);
72

  
73
        var toTime = new Date();
74
        toTime.setHours(16, 0, 0, 0);
75

  
76
        var toDate = new Date();
77
        var fromDate = new Date(toDate.getTime() - (30 * 24 * 60 * 60 * 1000));
78

  
79
        var params = $location.search();
80

  
81
        $scope.search = {
82
            location: params.location,
83
            fromDate: params.fromDate == null ? fromDate : new Date(parseInt(params.fromDate)),
84
            toDate: params.toDate == null ? toDate : new Date(parseInt(params.toDate)),
85
            fromTime: params.fromTime == null ? fromTime : new Date(parseInt(params.fromTime)),
86
            toTime: params.toTime == null ? toTime : new Date(parseInt(params.toTime)),
87
            direction: params.direction == null ? true : !!+params.direction
88
        };
89

  
90
        $scope.locations = [];
91
        $scope.showLocationsLoading = false;
92

  
93
        if (params.location!=null && params.location.length > 2) {
94
            $scope.searchLocations(false);
95
        }
96
    };
97

  
98

  
99
    $scope.searchLocations = function (saveToUrl) {
100
        $scope.showLocationsLoading = true;
101

  
102
        if (saveToUrl)
103
            $location.search({
104
                location: $scope.search.location,
105
                fromDate: $scope.search.fromDate.getTime(),
106
                toDate: $scope.search.toDate.getTime(),
107
                fromTime: $scope.search.fromTime.getTime(),
108
                toTime: $scope.search.toTime.getTime(),
109
                direction: $scope.search.direction ? 1 : 0
110
            });
111

  
112
        Device({jwt: config.API_TOKEN}).query({
113
            address: $scope.search.location,
114
            showDirection: $scope.search.direction ? 1 : 0
115
        }, function (data) {
116
            $scope.locations = data;
117
            $scope.showLocationsLoading = false;
118

  
119
            var params = $location.search();
120
            if(!saveToUrl && jQuery.grep($scope.locations, function(e){ return e.id === params.deviceId; }).length>0){
121
                $scope.selectDevice(params.deviceId);
122
            }
123

  
124
        }, function (response) {
125
            $scope.showLocationsLoading = false;
126
            console.log('Error api all Devices');
127
            $rootScope.handleErrorResponse(response);
128
        });
129
    };
130

  
131
    $scope.selectDevice = function (id) {
132
        $scope.deviceId = id;
133

  
134
        var searchObject = $location.search();
135
        searchObject.deviceId = id;
136
        $location.search(searchObject);
137

  
138
        Device({jwt: config.API_TOKEN}).get({
139
            id: id
140
            // dateFrom: $scope.search.fromDate.getTime(),
141
            // dateTo: $scope.search.toDate.getTime(),
142
            // timeFrom: $scope.search.fromTime.getTime(),
143
            // timeTo: $scope.search.toTime.getTime(),
144
            // direction: $scope.search.direction ? 1 : 0
145
        }, function (data) {
146
            $rootScope.$emit('renderGraph', data);
147
        }, function (response) {
148
            console.log('Error api get Devices');
149
            $rootScope.handleErrorResponse(response);
150
        });
151
    };
152

  
153
});
154

  
155

  
156
app.controller('graphController', function ($rootScope, $scope, config, Vehicle) {
157

  
158
    this.$onInit = function () {
159
        $rootScope.graphShow = false;
160
        $scope.vehicles = [];
161
    };
162

  
163
    $rootScope.$on("renderGraph", function (event, args) {
164
        $rootScope.graphShow = true;
165

  
166
        Vehicle({jwt: config.API_TOKEN}).query(null, function (data) {
167
            $scope.vehicles = data;
168

  
169
        }, function (response) {
170
            $rootScope.graphShow = false;
171
            console.log('Error api all Vehicles');
172
            $rootScope.handleErrorResponse(response);
173
        });
174
    });
175

  
176
});
177

  
178
app.controller('mapController', function ($scope) {
179

  
180
    this.$onInit = function () {
181

  
182
    };
183

  
184
});
185

  
186

  
187
app.factory("Device", function ($resource, config) {
188
    return function (headers) {
189
        return $resource(config.API_URL + "/devices/:id", {id: '@id'}, {
190
            'get': {
191
                url: config.API_URL + '/devices/:id',
192
                method: 'GET',
193
                headers: headers || {}
194
            },
195
            'query': {
196
                url: config.API_URL + '/devices',
197
                method: 'GET',
198
                isArray: true,
199
                headers: headers || {}
200
            }
201
        });
202
    };
203
});
204

  
205
app.factory("Vehicle", function ($resource, config) {
206
    return function (headers) {
207
        return $resource(config.API_URL + "/vehicles", null, {
208
            'query': {
209
                url: config.API_URL + '/vehicles',
210
                method: 'GET',
211
                isArray: true,
212
                headers: headers || {}
213
            }
214
        });
215
    };
216
});
frontend/assets/css/main.css
26 26
    font-weight: bold;
27 27
}
28 28

  
29
#search footer {
30
    position: absolute;
31
    right: 0;
32
    bottom: 0;
33
    left: 0;
34
    font-size: 0.8rem;
29
.searchWrapper{
30
    min-height: calc(100% - 40px);
31
    float: left;
35 32
}
36 33

  
37 34
#graph {
......
48 45
}
49 46

  
50 47

  
48
/* LOADING */
49
.loading {
50
    border: 6px solid white; /* Light grey */
51
    border-top: 6px solid #007bff; /* Blue */
52
    border-radius: 50%;
53
    width: 50px;
54
    height: 50px;
55
    animation: spin 2s linear infinite;
56
    margin: 0 auto;
57
}
58

  
59
@keyframes spin {
60
    0% { transform: rotate(0deg); }
61
    100% { transform: rotate(360deg); }
62
}
63

  
64

  
65
#loadingScreen{
66
    position: fixed;
67
    width: 100%;
68
    height: 100%;
69
    z-index: 1000;
70
    top: 0;
71
    left: 0;
72
    right: 0;
73
    bottom: 0;
74
    background-color: #CFD8DC;
75
}
76

  
77
#loadingScreen .loading{
78
    border: 12px solid white; /* Light grey */
79
    border-top: 12px solid #007bff; /* Blue */
80
    border-radius: 50%;
81
    width: 100px;
82
    height: 100px;
83
    animation: spin 2s linear infinite;
84
    margin: auto auto;
85
    position: fixed;
86
    top: 0;
87
    bottom: 0;
88
    left: 0;
89
    right: 0;
90
}
91

  
92

  
93

  
94

  
95

  
96

  
97

  
98

  
51 99

  
frontend/assets/css/normalize.css
1
/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */
2

  
3
/* Document
4
   ========================================================================== */
5

  
6
/**
7
 * 1. Correct the line height in all browsers.
8
 * 2. Prevent adjustments of font size after orientation changes in
9
 *    IE on Windows Phone and in iOS.
10
 */
11

  
12
html {
13
  line-height: 1.15; /* 1 */
14
  -ms-text-size-adjust: 100%; /* 2 */
15
  -webkit-text-size-adjust: 100%; /* 2 */
16
}
17

  
18
/* Sections
19
   ========================================================================== */
20

  
21
/**
22
 * Remove the margin in all browsers (opinionated).
23
 */
24

  
25
body {
26
  margin: 0;
27
}
28

  
29
/**
30
 * Add the correct display in IE 9-.
31
 */
32

  
33
article,
34
aside,
35
footer,
36
header,
37
nav,
38
section {
39
  display: block;
40
}
41

  
42
/**
43
 * Correct the font size and margin on `h1` elements within `section` and
44
 * `article` contexts in Chrome, Firefox, and Safari.
45
 */
46

  
47
h1 {
48
  font-size: 2em;
49
  margin: 0.67em 0;
50
}
51

  
52
/* Grouping content
53
   ========================================================================== */
54

  
55
/**
56
 * Add the correct display in IE 9-.
57
 * 1. Add the correct display in IE.
58
 */
59

  
60
figcaption,
61
figure,
62
main { /* 1 */
63
  display: block;
64
}
65

  
66
/**
67
 * Add the correct margin in IE 8.
68
 */
69

  
70
figure {
71
  margin: 1em 40px;
72
}
73

  
74
/**
75
 * 1. Add the correct box sizing in Firefox.
76
 * 2. Show the overflow in Edge and IE.
77
 */
78

  
79
hr {
80
  box-sizing: content-box; /* 1 */
81
  height: 0; /* 1 */
82
  overflow: visible; /* 2 */
83
}
84

  
85
/**
86
 * 1. Correct the inheritance and scaling of font size in all browsers.
87
 * 2. Correct the odd `em` font sizing in all browsers.
88
 */
89

  
90
pre {
91
  font-family: monospace, monospace; /* 1 */
92
  font-size: 1em; /* 2 */
93
}
94

  
95
/* Text-level semantics
96
   ========================================================================== */
97

  
98
/**
99
 * 1. Remove the gray background on active links in IE 10.
100
 * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
101
 */
102

  
103
a {
104
  background-color: transparent; /* 1 */
105
  -webkit-text-decoration-skip: objects; /* 2 */
106
}
107

  
108
/**
109
 * 1. Remove the bottom border in Chrome 57- and Firefox 39-.
110
 * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
111
 */
112

  
113
abbr[title] {
114
  border-bottom: none; /* 1 */
115
  text-decoration: underline; /* 2 */
116
  text-decoration: underline dotted; /* 2 */
117
}
118

  
119
/**
120
 * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
121
 */
122

  
123
b,
124
strong {
125
  font-weight: inherit;
126
}
127

  
128
/**
129
 * Add the correct font weight in Chrome, Edge, and Safari.
130
 */
131

  
132
b,
133
strong {
134
  font-weight: bolder;
135
}
136

  
137
/**
138
 * 1. Correct the inheritance and scaling of font size in all browsers.
139
 * 2. Correct the odd `em` font sizing in all browsers.
140
 */
141

  
142
code,
143
kbd,
144
samp {
145
  font-family: monospace, monospace; /* 1 */
146
  font-size: 1em; /* 2 */
147
}
148

  
149
/**
150
 * Add the correct font style in Android 4.3-.
151
 */
152

  
153
dfn {
154
  font-style: italic;
155
}
156

  
157
/**
158
 * Add the correct background and color in IE 9-.
159
 */
160

  
161
mark {
162
  background-color: #ff0;
163
  color: #000;
164
}
165

  
166
/**
167
 * Add the correct font size in all browsers.
168
 */
169

  
170
small {
171
  font-size: 80%;
172
}
173

  
174
/**
175
 * Prevent `sub` and `sup` elements from affecting the line height in
176
 * all browsers.
177
 */
178

  
179
sub,
180
sup {
181
  font-size: 75%;
182
  line-height: 0;
183
  position: relative;
184
  vertical-align: baseline;
185
}
186

  
187
sub {
188
  bottom: -0.25em;
189
}
190

  
191
sup {
192
  top: -0.5em;
193
}
194

  
195
/* Embedded content
196
   ========================================================================== */
197

  
198
/**
199
 * Add the correct display in IE 9-.
200
 */
201

  
202
audio,
203
video {
204
  display: inline-block;
205
}
206

  
207
/**
208
 * Add the correct display in iOS 4-7.
209
 */
210

  
211
audio:not([controls]) {
212
  display: none;
213
  height: 0;
214
}
215

  
216
/**
217
 * Remove the border on images inside links in IE 10-.
218
 */
219

  
220
img {
221
  border-style: none;
222
}
223

  
224
/**
225
 * Hide the overflow in IE.
226
 */
227

  
228
svg:not(:root) {
229
  overflow: hidden;
230
}
231

  
232
/* Forms
233
   ========================================================================== */
234

  
235
/**
236
 * 1. Change the font styles in all browsers (opinionated).
237
 * 2. Remove the margin in Firefox and Safari.
238
 */
239

  
240
button,
241
input,
242
optgroup,
243
select,
244
textarea {
245
  font-family: sans-serif; /* 1 */
246
  font-size: 100%; /* 1 */
247
  line-height: 1.15; /* 1 */
248
  margin: 0; /* 2 */
249
}
250

  
251
/**
252
 * Show the overflow in IE.
253
 * 1. Show the overflow in Edge.
254
 */
255

  
256
button,
257
input { /* 1 */
258
  overflow: visible;
259
}
260

  
261
/**
262
 * Remove the inheritance of text transform in Edge, Firefox, and IE.
263
 * 1. Remove the inheritance of text transform in Firefox.
264
 */
265

  
266
button,
267
select { /* 1 */
268
  text-transform: none;
269
}
270

  
271
/**
272
 * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
273
 *    controls in Android 4.
274
 * 2. Correct the inability to style clickable types in iOS and Safari.
275
 */
276

  
277
button,
278
html [type="button"], /* 1 */
279
[type="reset"],
280
[type="submit"] {
281
  -webkit-appearance: button; /* 2 */
282
}
283

  
284
/**
285
 * Remove the inner border and padding in Firefox.
286
 */
287

  
288
button::-moz-focus-inner,
289
[type="button"]::-moz-focus-inner,
290
[type="reset"]::-moz-focus-inner,
291
[type="submit"]::-moz-focus-inner {
292
  border-style: none;
293
  padding: 0;
294
}
295

  
296
/**
297
 * Restore the focus styles unset by the previous rule.
298
 */
299

  
300
button:-moz-focusring,
301
[type="button"]:-moz-focusring,
302
[type="reset"]:-moz-focusring,
303
[type="submit"]:-moz-focusring {
304
  outline: 1px dotted ButtonText;
305
}
306

  
307
/**
308
 * Correct the padding in Firefox.
309
 */
310

  
311
fieldset {
312
  padding: 0.35em 0.75em 0.625em;
313
}
314

  
315
/**
316
 * 1. Correct the text wrapping in Edge and IE.
317
 * 2. Correct the color inheritance from `fieldset` elements in IE.
318
 * 3. Remove the padding so developers are not caught out when they zero out
319
 *    `fieldset` elements in all browsers.
320
 */
321

  
322
legend {
323
  box-sizing: border-box; /* 1 */
324
  color: inherit; /* 2 */
325
  display: table; /* 1 */
326
  max-width: 100%; /* 1 */
327
  padding: 0; /* 3 */
328
  white-space: normal; /* 1 */
329
}
330

  
331
/**
332
 * 1. Add the correct display in IE 9-.
333
 * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
334
 */
335

  
336
progress {
337
  display: inline-block; /* 1 */
338
  vertical-align: baseline; /* 2 */
339
}
340

  
341
/**
342
 * Remove the default vertical scrollbar in IE.
343
 */
344

  
345
textarea {
346
  overflow: auto;
347
}
348

  
349
/**
350
 * 1. Add the correct box sizing in IE 10-.
351
 * 2. Remove the padding in IE 10-.
352
 */
353

  
354
[type="checkbox"],
355
[type="radio"] {
356
  box-sizing: border-box; /* 1 */
357
  padding: 0; /* 2 */
358
}
359

  
360
/**
361
 * Correct the cursor style of increment and decrement buttons in Chrome.
362
 */
363

  
364
[type="number"]::-webkit-inner-spin-button,
365
[type="number"]::-webkit-outer-spin-button {
366
  height: auto;
367
}
368

  
369
/**
370
 * 1. Correct the odd appearance in Chrome and Safari.
371
 * 2. Correct the outline style in Safari.
372
 */
373

  
374
[type="search"] {
375
  -webkit-appearance: textfield; /* 1 */
376
  outline-offset: -2px; /* 2 */
377
}
378

  
379
/**
380
 * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
381
 */
382

  
383
[type="search"]::-webkit-search-cancel-button,
384
[type="search"]::-webkit-search-decoration {
385
  -webkit-appearance: none;
386
}
387

  
388
/**
389
 * 1. Correct the inability to style clickable types in iOS and Safari.
390
 * 2. Change font properties to `inherit` in Safari.
391
 */
392

  
393
::-webkit-file-upload-button {
394
  -webkit-appearance: button; /* 1 */
395
  font: inherit; /* 2 */
396
}
397

  
398
/* Interactive
399
   ========================================================================== */
400

  
401
/*
402
 * Add the correct display in IE 9-.
403
 * 1. Add the correct display in Edge, IE, and Firefox.
404
 */
405

  
406
details, /* 1 */
407
menu {
408
  display: block;
409
}
410

  
411
/*
412
 * Add the correct display in all browsers.
413
 */
414

  
415
summary {
416
  display: list-item;
417
}
418

  
419
/* Scripting
420
   ========================================================================== */
421

  
422
/**
423
 * Add the correct display in IE 9-.
424
 */
425

  
426
canvas {
427
  display: inline-block;
428
}
429

  
430
/**
431
 * Add the correct display in IE.
432
 */
433

  
434
template {
435
  display: none;
436
}
437

  
438
/* Hidden
439
   ========================================================================== */
440

  
441
/**
442
 * Add the correct display in IE 10-.
443
 */
444

  
445
[hidden] {
446
  display: none;
447
}
frontend/index.html
1
<!doctype html>
2
<html ng-app="PVPK" class="no-js" lang="cs">
3
<head>
4
    <meta charset="utf-8">
5
    <title>Průjezd vozidel - Plzeňský kraj</title>
6
    <meta http-equiv="x-ua-compatible" content="ie=edge">
7

  
8
    <meta name="description" content="Zobrazení dat o průjezdu vozidel pro Plzeňský kraj">
9
    <meta name="viewport" content="width=device-width, initial-scale=1">
10

  
11
    <link rel="apple-touch-icon" href="./assets/img/favicon.png">
12
    <link rel="icon" href="./assets/img/favicon.png">
13

  
14
    <script>
15
        document.documentElement.className = document.documentElement.className.replace("no-js", "js");
16
    </script>
17

  
18
    <link rel="stylesheet" href="./assets/css/normalize.css">
19
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"
20
          integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
21
    <link rel="stylesheet" media="screen" href="./assets/css/main.css">
22

  
23

  
24
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
25
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-route.min.js"></script>
26
    <script src="./app.js"></script>
27

  
28
</head>
29
<body>
30
<!--[if lte IE 9]>
31
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="https://browsehappy.com/">upgrade
32
    your browser</a> to improve your experience and security.</p>
33
<![endif]-->
34

  
35
<div class="container-fluid h-100">
36
    <div class="row h-100">
37
        <!--search section-->
38
        <section class="search col-12 col-sm-6 col-lg-3" id="search">
39

  
40
            <header class="mt-2">
41

  
42
                <h1>
43
                    <img src="./assets/img/favicon.png" alt="logo"> Průjezd vozidel
44
                    <small class="text-muted">Plzeňský kraj</small>
45
                </h1>
46

  
47
            </header>
48

  
49
            <div class="mb-4 mt-4">
50
                <h4></h4>
51
                <form method="get">
52

  
53
                    <div class="form-group">
54
                        <label for="searchLocation" class="h5">Hledání - lokalit</label>
55

  
56
                        <input type="search" id="searchLocation" name="location"
57
                               class="form-control form-control-sm"
58
                               placeholder="Město, ulice, psč, ...">
59
                    </div>
60

  
61
                    <div class="form-row">
62

  
63
                        <div class="form-group col">
64
                            <label for="searchFromDate">Období</label>
65

  
66
                            <input type="date" id="searchFromDate" name="fromDate"
67
                                   class="form-control form-control-sm"
68
                                   value="2018-04-01">
69
                        </div>
70

  
71
                        <div class="form-group col">
72
                            <label for="searchToDate" class="invisible">Období</label>
73
                            <input type="date" id="searchToDate" name="toDateTime"
74
                                   class="form-control form-control-sm"
75
                                   value="2018-04-30">
76
                        </div>
77

  
78

  
79
                    </div>
80

  
81
                    <div class="form-row">
82

  
83
                        <div class="form-group col">
84
                            <label for="searchFromTime">Časové rozmezí dne</label>
85
                            <input type="time" id="searchFromTime" class="form-control form-control-sm"
86
                                   value="06:00">
87
                        </div>
88

  
89
                        <div class="form-group col">
90
                            <label for="searchToTime" class="invisible">Časové rozmezí dne</label>
91
                            <input type="time" id="searchToTime" class="form-control form-control-sm" value="20:00">
92
                        </div>
93

  
94

  
95
                    </div>
96

  
97
                    <div class="form-group">
98
                        <label for="searchVehicle">Vozidla</label>
99
                        <select id="searchVehicle" class="custom-select custom-select-sm">
100
                            <option value="all" selected>Všechna vozidla</option>
101
                        </select>
102
                    </div>
103
                    <div class="custom-control custom-checkbox mb-3">
104
                        <input type="checkbox" id="searchDirection" name="searchDirection"
105
                               class="custom-control-input"
106
                               checked>
107
                        <label for="searchDirection" class="custom-control-label">Rozlišovat směr</label>
108
                    </div>
109

  
110
                    <input type="submit" value="Vyhledat" class="btn btn-primary btn-block">
111

  
112
                </form>
113

  
114

  
115
                <div class="result-locations mb-5 mt-5">
116
                    <h5>Lokality</h5>
117

  
118

  
119
                    <div class="list-group">
120
                        <a href="#"
121
                           class="list-group-item list-group-item-action flex-column align-items-start active">
122
                            <div class="d-flex w-100 justify-content-between">
123
                                <h6 class="mb-1">Nýrsko, směr od Ž.Rudy</h6>
124
                                <small>malé info</small>
125
                            </div>
126
                            <small>
127
                                <address>U Banky, Nýrsko</address>
128
                            </small>
129
                        </a>
130
                        <a href="#" class="list-group-item list-group-item-action flex-column align-items-start">
131
                            <div class="d-flex w-100 justify-content-between">
132
                                <h6 class="mb-1">Domažlice, směr od Klatov</h6>
133
                                <small class="text-muted">malé info</small>
134
                            </div>
135
                            <small>
136
                                <address>Masarykova, Domažlice</address>
137
                            </small>
138
                        </a>
139
                        <a href="#" class="list-group-item list-group-item-action flex-column align-items-start">
140
                            <div class="d-flex w-100 justify-content-between">
141
                                <h6 class="mb-1">Hostouň, směr od Bělé</h6>
142
                                <small class="text-muted">malé info</small>
143
                            </div>
144
                            <small class="text-muted">
145
                                <address>Petra Bezruče, Hostouň</address>
146
                            </small>
147
                        </a>
148
                    </div>
149

  
150
                </div>
151

  
152

  
153
            </div>
154

  
155
            <footer class="text-center mb-2 mt-2">
156
                2018 © FAV, ZČU
157
            </footer>
158
        </section>
159

  
160
        <!--graph section-->
161
        <section class="graph col-12 col-sm-6 col-lg-3" id="graph">
162

  
163
            <header class="mt-2">
164

  
165
                <h4>Grafy
166
                    <button type="button" class="close" aria-label="Close">
167
                        <span aria-hidden="true">&times;</span>
168
                    </button>
169
                </h4>
170
            </header>
171

  
172

  
173
            <script src="assets/libs/Chart.min.js"></script>
174
            <canvas id="myChart" width="100%" height="60"></canvas>
175
            <script>
176
                var ctx = document.getElementById("myChart").getContext('2d');
177
                var myChart = new Chart(ctx, {
178
                    type: 'bar',
179
                    data: {
180
                        labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
181
                        datasets: [{
182
                            label: '# of Votes',
183
                            data: [12, 19, 3, 5, 2, 3],
184
                            backgroundColor: [
185
                                'rgba(255, 99, 132, 0.2)',
186
                                'rgba(54, 162, 235, 0.2)',
187
                                'rgba(255, 206, 86, 0.2)',
188
                                'rgba(75, 192, 192, 0.2)',
189
                                'rgba(153, 102, 255, 0.2)',
190
                                'rgba(255, 159, 64, 0.2)'
191
                            ],
192
                            borderColor: [
193
                                'rgba(255,99,132,1)',
194
                                'rgba(54, 162, 235, 1)',
195
                                'rgba(255, 206, 86, 1)',
196
                                'rgba(75, 192, 192, 1)',
197
                                'rgba(153, 102, 255, 1)',
198
                                'rgba(255, 159, 64, 1)'
199
                            ],
200
                            borderWidth: 1
201
                        }]
202
                    },
203
                    options: {
204
                        scales: {
205
                            yAxes: [{
206
                                ticks: {
207
                                    beginAtZero: true
208
                                }
209
                            }]
210
                        }
211
                    }
212
                });
213
            </script>
214

  
215
        </section>
216

  
217
        <!--map section-->
218
        <section class="map col-12 col-sm-12 col-lg-6" id="map">
219

  
220
            <iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d1326226.1771813703!2d11.996870042985256!3d49.51688547407959!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x470abf4bb3db6569%3A0x100af0f6614a850!2zUGx6ZcWIc2vDvSBrcmFq!5e0!3m2!1scs!2scz!4v1523814169200"
221
                    width="100%" height="100%" frameborder="0" style="border:0" allowfullscreen></iframe>
222
        </section>
223
    </div>
224
</div>
225

  
226

  
227
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
228
        integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
229
        crossorigin="anonymous"></script>
230
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"
231
        integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm"
232
        crossorigin="anonymous"></script>
233

  
234

  
235
</body>
236
</html>
frontend/index.php
1
<!doctype html>
2
<html ng-app="pvpk" class="no-js" lang="cs">
3
<head>
4
    <meta charset="utf-8">
5
    <title>Průjezd vozidel - Plzeňský kraj</title>
6
    <meta http-equiv="x-ua-compatible" content="ie=edge">
7

  
8
    <meta name="description" content="Zobrazení dat o průjezdu vozidel pro Plzeňský kraj">
9
    <meta name="viewport" content="width=device-width, initial-scale=1">
10

  
11
    <link rel="apple-touch-icon" href="./assets/img/favicon.png">
12
    <link rel="icon" href="./assets/img/favicon.png">
13

  
14
    <script>
15
        document.documentElement.className = document.documentElement.className.replace("no-js", "js");
16
    </script>
17

  
18
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"
19
          integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
20
    <link rel="stylesheet" media="screen" href="./assets/css/main.css">
21

  
22

  
23
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
24
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-route.min.js"></script>
25
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-resource.min.js"></script>
26

  
27
    <script>
28
        <?php
29
        /* JEN PRO TESTOVANI, POZDEJI SE ODSTRANIT, A NAHRADIT NASDILENOU KNIHOVNOU */
30
        $base_url = 'http://localhost/pvpk/backend/public/api/v1';
31

  
32
        include_once '../backend/lib/generateToken.php';
33
        $token = generateToken();
34
        ?>
35
        var API_URL = '<?=$base_url ?>';
36
        var API_TOKEN = '<?=$token ?>';
37
    </script>
38

  
39
    <script src="./app.js"></script>
40

  
41

  
42
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
43
</head>
44
<body ng-controller="mainController" class="container-fluid">
45

  
46

  
47

  
48

  
49
<div id="loadingScreen" ng-show="showLoadingScreen">
50
    <div class="loading"></div>
51
</div>
52
<div class="row h-100">
53

  
54
    <section class="search col-12 col-sm-6 col-lg-3" id="search" ng-controller="searchController">
55

  
56
        <div class="w-100 searchWrapper">
57
            <header class="mt-2">
58
                <h1>
59
                    <img src="./assets/img/favicon.png" alt="logo"> Průjezd vozidel
60
                    <small class="text-muted">Plzeňský kraj</small>
61
                </h1>
62
            </header>
63

  
64
            <form class="mb-4 mt-4">
65
                <div class="form-group">
66
                    <label for="searchLocation" class="h5">Hledání - lokalit</label>
67
                    <input type="search" id="searchLocation" name="location"
68
                           class="form-control form-control-sm" placeholder="Město, ulice, ..."
69
                           ng-model="search.location" required maxlength="255" autocomplete="off"
70
                           ng-change="search.location.length>2 && searchLocations(true)">
71
                </div>
72

  
73
                <div class="custom-control custom-checkbox mb-3">
74
                    <!-- ng-true-value="ofCourse" ng-false-value="iWish"  -->
75
                    <input type="checkbox" id="searchDirection" name="searchDirection" class="custom-control-input"
76
                           checked ng-model="search.direction" required ng-change="searchLocations()">
77
                    <label for="searchDirection" class="custom-control-label">Rozlišovat směr</label>
78
                </div>
79

  
80
                <div class="form-row">
81
                    <div class="form-group col">
82
                        <label for="searchFromDate">Období</label>
83
                        <input type="date" id="searchFromDate" name="fromDate"
84
                               class="form-control form-control-sm" ng-model="search.fromDate" required
85
                               ng-class="{ 'is-invalid': search.fromDate>search.toDate}">
86
                        <div class="invalid-feedback">
87
                            Tento datum musí být menší.
88
                        </div>
89
                    </div>
90

  
91
                    <div class="form-group col">
92
                        <label for="searchToDate" class="invisible">Období</label>
93
                        <input type="date" id="searchToDate" name="toDateTime"
94
                               class="form-control form-control-sm" ng-model="search.toDate" required
95
                               ng-class="{ 'is-invalid': search.fromDate>search.toDate}">
96
                        <div class="invalid-feedback">
97
                            Tento datum musí být vetší.
98
                        </div>
99
                    </div>
100
                </div>
101

  
102
                <div class="form-row">
103
                    <div class="form-group col">
104
                        <label for="searchFromTime">Časové rozmezí dne</label>
105
                        <input type="time" id="searchFromTime" class="form-control form-control-sm"
106
                               ng-model="search.fromTime" required
107
                               ng-class="{'is-invalid': search.fromTime>search.toTime}">
108
                        <div class="invalid-feedback">
109
                            Tento čas musí být menší.
110
                        </div>
111
                    </div>
112

  
113
                    <div class="form-group col">
114
                        <label for="searchToTime" class="invisible">Časové rozmezí dne</label>
115
                        <input type="time" id="searchToTime" class="form-control form-control-sm"
116
                               ng-model="search.toTime" required
117
                               ng-class="{'is-invalid': search.fromTime>search.toTime}">
118
                        <div class="invalid-feedback">
119
                            Tento čas musí být vetší.
120
                        </div>
121
                    </div>
122
                </div>
123

  
124
                <!--<input type="submit" value="Vyhledat" class="btn btn-primary btn-block"-->
125
                <!--ng-disabled="search.fromDate>search.toDate || search.fromTime>search.toTime">-->
126
            </form>
127

  
128

  
129
            <div class="result-locations mb-5 mt-5">
130
                <h5>Lokality</h5>
131

  
132
                <div class="list-group" ng-show="locations.length>0 && !showLocationsLoading">
133
                    <!-- class = active -->
134
                    <a href="" id="location-{{location.id}}"
135
                       class="list-group-item list-group-item-action flex-column align-items-start"
136
                       ng-repeat="location in locations"
137
                       ng-click="selectDevice(location.id)"
138
                       ng-class="{'active': deviceId == location.id}">
139

  
140
                        <div class="d-flex w-100 justify-content-between">
141
                            <h6 class="mb-1">{{location.name}}</h6>
142
                            <small ng-show="search.direction">{{location.direction ==1 ? 'po směru': 'proti směru' }}
143
                            </small>
144
                        </div>
145
                        <small>
146
                            <address>{{location.street}}, {{location.town}}</address>
147
                        </small>
148
                    </a>
149
                </div>
150

  
151
                <div ng-show="locations.length==0 && !showLocationsLoading">
152
                    <small class="form-text text-muted text-center">Žádná lokalita</small>
153
                </div>
154

  
155
                <div class="loading" ng-show="showLocationsLoading"></div>
156

  
157
            </div>
158

  
159
        </div>
160
        <footer class="text-center mb-2 mt-2 w-100">
161
            <small class="text-muted">2018 © FAV, ZČU</small>
162
        </footer>
163
    </section>
164

  
165

  
166
    <!--graph section-->
167
    <section class="graph col-12 col-sm-6 col-lg-3" id="graph" ng-show="$root.graphShow"
168
             ng-controller="graphController">
169

  
170
        <header class="mt-2">
171

  
172
            <h4>Grafy
173
                <button type="button" class="close" aria-label="Close" ng-click="$root.graphShow = !$root.graphShow">
174
                    <span aria-hidden="true">&times;</span>
175
                </button>
176
            </h4>
177
        </header>
178

  
179
        <form>
180
            <div class="form-group">
181
                <label for="searchVehicle">Vozidla</label>
182
                <select id="searchVehicle" class="custom-select custom-select-sm" ng-model="search.vehicle">
183
                    <option value="">Všechna vozidla</option>
184
                    <option ng-repeat="vehicle in vehicles" value="{{vehicle.id}}">{{vehicle.name}}</option>
185
                </select>
186
            </div>
187

  
188
        </form>
189

  
190
        <div class="loading"></div>
191

  
192
        <!--<canvas id="myChart" width="100%" height="60"></canvas>-->
193
        <!--<script>-->
194
        <!--var ctx = document.getElementById("myChart").getContext('2d');-->
195
        <!--var myChart = new Chart(ctx, {-->
196
        <!--type: 'bar',-->
197
        <!--data: {-->
198
        <!--labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],-->
199
        <!--datasets: [{-->
200
        <!--label: '# of Votes',-->
201
        <!--data: [12, 19, 3, 5, 2, 3],-->
202
        <!--backgroundColor: [-->
203
        <!--'rgba(255, 99, 132, 0.2)',-->
204
        <!--'rgba(54, 162, 235, 0.2)',-->
205
        <!--'rgba(255, 206, 86, 0.2)',-->
206
        <!--'rgba(75, 192, 192, 0.2)',-->
207
        <!--'rgba(153, 102, 255, 0.2)',-->
208
        <!--'rgba(255, 159, 64, 0.2)'-->
209
        <!--],-->
210
        <!--borderColor: [-->
211
        <!--'rgba(255,99,132,1)',-->
212
        <!--'rgba(54, 162, 235, 1)',-->
213
        <!--'rgba(255, 206, 86, 1)',-->
214
        <!--'rgba(75, 192, 192, 1)',-->
215
        <!--'rgba(153, 102, 255, 1)',-->
216
        <!--'rgba(255, 159, 64, 1)'-->
217
        <!--],-->
218
        <!--borderWidth: 1-->
219
        <!--}]-->
220
        <!--},-->
221
        <!--options: {-->
222
        <!--scales: {-->
223
        <!--yAxes: [{-->
224
        <!--ticks: {-->
225
        <!--beginAtZero: true-->
226
        <!--}-->
227
        <!--}]-->
228
        <!--}-->
229
        <!--}-->
230
        <!--});-->
231
        <!--</script>-->
232

  
233
    </section>
234

  
235

  
236
    <!--map section-->
237
    <!-- ng-class="textType" -->
238
    <section class="map col-12 col-sm-12" id="map"
239
             ng-class="{ 'col-lg-9': !$root.graphShow, 'col-lg-6': $root.graphShow }" ng-controller="mapController">
240

  
241
        <iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d1326226.1771813703!2d11.996870042985256!3d49.51688547407959!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x470abf4bb3db6569%3A0x100af0f6614a850!2zUGx6ZcWIc2vDvSBrcmFq!5e0!3m2!1scs!2scz!4v1523814169200"
242
                width="100%" height="100%" frameborder="0" style="border:0" allowfullscreen></iframe>
243
    </section>
244

  
245

  
246
</div>
247

  
248
<div class="modal fade" id="modalExpiredToken" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
249
     aria-hidden="true">
250
    <div class="modal-dialog" role="document">
251
        <div class="modal-content">
252
            <div class="modal-header">
253
                <h5 class="modal-title" id="exampleModalLabel">Platnost webové aplikace vypršela</h5>
254
            </div>
255
            <div class="modal-body">
256
                <p>Pro obnovení platnosti stačí stisknout tlačítko <strong>Obnovit</strong>.</p>
257
            </div>
258
            <div class="modal-footer">
259
                <button type="button" class="btn btn-primary" ng-click="reloadApp()">Obnovit</button>
260
            </div>
261
        </div>
262
    </div>
263
</div>
264

  
265

  
266
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
267
        integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
268
        crossorigin="anonymous"></script>
269
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"
270
        integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm"
271
        crossorigin="anonymous"></script>
272

  
273

  
274
</body>
275
</html>

Také k dispozici: Unified diff