@fleetbase/ember-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +9 -0
- package/README.md +32 -0
- package/addon/adapters/application.js +155 -0
- package/addon/adapters/user.js +19 -0
- package/addon/authenticators/fleetbase.js +72 -0
- package/addon/decorators/fetch-from.js +55 -0
- package/addon/decorators/from-store.js +56 -0
- package/addon/decorators/is-equal.js +15 -0
- package/addon/exports/host-services.js +18 -0
- package/addon/exports/services.js +18 -0
- package/addon/initializers/local-storage-adapter.js +21 -0
- package/addon/serializers/application.js +87 -0
- package/addon/services/app-cache.js +59 -0
- package/addon/services/crud.js +226 -0
- package/addon/services/current-user.js +259 -0
- package/addon/services/fetch.js +648 -0
- package/addon/services/filters.js +183 -0
- package/addon/services/loader.js +136 -0
- package/addon/services/notifications.js +32 -0
- package/addon/services/session.js +221 -0
- package/addon/services/theme.js +200 -0
- package/addon/services/url-search-params.js +92 -0
- package/addon/transforms/array.js +29 -0
- package/addon/transforms/object.js +11 -0
- package/addon/transforms/raw.js +11 -0
- package/addon/utils/api-url.js +11 -0
- package/addon/utils/apply-column-filters.js +3 -0
- package/addon/utils/auto-serialize.js +100 -0
- package/addon/utils/calculate-percentage.js +3 -0
- package/addon/utils/close-sidebar.js +7 -0
- package/addon/utils/console-url.js +56 -0
- package/addon/utils/copy-to-clipboard.js +35 -0
- package/addon/utils/corslite.js +95 -0
- package/addon/utils/download.js +157 -0
- package/addon/utils/env.js +3 -0
- package/addon/utils/extract-coordinates.js +35 -0
- package/addon/utils/extract-latitude.js +28 -0
- package/addon/utils/extract-longitude.js +28 -0
- package/addon/utils/find-closest-waypoint.js +20 -0
- package/addon/utils/first.js +10 -0
- package/addon/utils/frontend-url.js +30 -0
- package/addon/utils/generate-slug.js +11 -0
- package/addon/utils/generate-uuid.js +3 -0
- package/addon/utils/get-length-units.js +44 -0
- package/addon/utils/get-meta-field-types.js +3 -0
- package/addon/utils/get-mime-type.js +25 -0
- package/addon/utils/get-model-name.js +45 -0
- package/addon/utils/get-permission-action.js +47 -0
- package/addon/utils/get-permission-resource.js +16 -0
- package/addon/utils/get-pod-methods.js +7 -0
- package/addon/utils/get-routing-host.js +44 -0
- package/addon/utils/get-service-name.js +21 -0
- package/addon/utils/get-user-options.js +21 -0
- package/addon/utils/get-weight-units.js +32 -0
- package/addon/utils/get-with-default.js +6 -0
- package/addon/utils/group-api-events.js +20 -0
- package/addon/utils/group-by.js +26 -0
- package/addon/utils/has-extension.js +11 -0
- package/addon/utils/has-json-structure.js +10 -0
- package/addon/utils/hason-structure.js +3 -0
- package/addon/utils/haversine.js +59 -0
- package/addon/utils/humanize.js +16 -0
- package/addon/utils/is-electron.js +18 -0
- package/addon/utils/is-email.js +5 -0
- package/addon/utils/is-function.js +3 -0
- package/addon/utils/is-image-file.js +3 -0
- package/addon/utils/is-iterable.js +7 -0
- package/addon/utils/is-json.js +9 -0
- package/addon/utils/is-latitude.js +3 -0
- package/addon/utils/is-letter.js +3 -0
- package/addon/utils/is-longitude.js +3 -0
- package/addon/utils/is-model.js +6 -0
- package/addon/utils/is-not-empty.js +5 -0
- package/addon/utils/is-not-model.js +5 -0
- package/addon/utils/is-numeric.js +3 -0
- package/addon/utils/is-object.js +3 -0
- package/addon/utils/is-proxy.js +5 -0
- package/addon/utils/is-relation-missing.js +21 -0
- package/addon/utils/is-valid-coordinates.js +38 -0
- package/addon/utils/is-video-file.js +3 -0
- package/addon/utils/is-waypoint-record.js +5 -0
- package/addon/utils/ison.js +3 -0
- package/addon/utils/isset.js +10 -0
- package/addon/utils/last.js +23 -0
- package/addon/utils/lazy-load-script.js +25 -0
- package/addon/utils/leaflet-icon.js +13 -0
- package/addon/utils/leaflet-points-from-coordinates.js +3 -0
- package/addon/utils/load-engines.js +37 -0
- package/addon/utils/load-extensions.js +8 -0
- package/addon/utils/macros/group-by.js +28 -0
- package/addon/utils/make-dataset.js +57 -0
- package/addon/utils/map-engines.js +30 -0
- package/addon/utils/mock-response.js +15 -0
- package/addon/utils/numbers-only.js +11 -0
- package/addon/utils/past-tense.js +40 -0
- package/addon/utils/path-to-route.js +10 -0
- package/addon/utils/polyline.js +161 -0
- package/addon/utils/range.js +19 -0
- package/addon/utils/refresh-route.js +3 -0
- package/addon/utils/replace-table-row.js +17 -0
- package/addon/utils/reverse-point.js +3 -0
- package/addon/utils/serialize/normalize-polymorphic-type-within-hash.js +27 -0
- package/addon/utils/serialize/normalize-polymorphic-type.js +13 -0
- package/addon/utils/serialize/normalize-relations-with-hash.js +32 -0
- package/addon/utils/set-column-filter-options.js +3 -0
- package/addon/utils/strip-html.js +3 -0
- package/addon/utils/to-leaflet-bounds.js +6 -0
- package/addon/utils/to-model.js +18 -0
- package/addon/utils/waypoint-label.js +3 -0
- package/addon/utils/with-default-value.js +5 -0
- package/addon/utils/words.js +5 -0
- package/app/adapters/user.js +1 -0
- package/app/authenticators/fleetbase.js +1 -0
- package/app/decorators/fetch-from.js +1 -0
- package/app/decorators/from-store.js +1 -0
- package/app/decorators/is-equal.js +1 -0
- package/app/exports/host-services.js +1 -0
- package/app/exports/services.js +1 -0
- package/app/initializers/local-storage-adapter.js +1 -0
- package/app/serializers/application.js +1 -0
- package/app/services/app-cache.js +1 -0
- package/app/services/crud.js +1 -0
- package/app/services/current-user.js +1 -0
- package/app/services/fetch.js +1 -0
- package/app/services/filters.js +1 -0
- package/app/services/loader.js +1 -0
- package/app/services/notifications.js +1 -0
- package/app/services/session.js +1 -0
- package/app/services/theme.js +1 -0
- package/app/services/url-search-params.js +1 -0
- package/app/storages/local-cache.js +12 -0
- package/app/storages/user-options.js +12 -0
- package/app/transforms/array.js +1 -0
- package/app/transforms/object.js +1 -0
- package/app/transforms/raw.js +1 -0
- package/app/utils/api-url.js +1 -0
- package/app/utils/apply-column-filters.js +1 -0
- package/app/utils/auto-serialize.js +1 -0
- package/app/utils/calculate-percentage.js +1 -0
- package/app/utils/close-sidebar.js +1 -0
- package/app/utils/console-url.js +1 -0
- package/app/utils/copy-to-clipboard.js +1 -0
- package/app/utils/corslite.js +1 -0
- package/app/utils/download.js +1 -0
- package/app/utils/env.js +1 -0
- package/app/utils/extract-coordinates.js +1 -0
- package/app/utils/extract-latitude.js +1 -0
- package/app/utils/extract-longitude.js +1 -0
- package/app/utils/find-closest-waypoint.js +1 -0
- package/app/utils/first.js +1 -0
- package/app/utils/frontend-url.js +1 -0
- package/app/utils/generate-slug.js +1 -0
- package/app/utils/generate-uuid.js +1 -0
- package/app/utils/get-length-units.js +1 -0
- package/app/utils/get-meta-field-types.js +1 -0
- package/app/utils/get-mime-type.js +1 -0
- package/app/utils/get-model-name.js +1 -0
- package/app/utils/get-permission-action.js +1 -0
- package/app/utils/get-permission-resource.js +1 -0
- package/app/utils/get-pod-methods.js +1 -0
- package/app/utils/get-routing-host.js +1 -0
- package/app/utils/get-service-name.js +1 -0
- package/app/utils/get-user-options.js +1 -0
- package/app/utils/get-weight-units.js +1 -0
- package/app/utils/get-with-default.js +1 -0
- package/app/utils/group-api-events.js +1 -0
- package/app/utils/group-by.js +1 -0
- package/app/utils/has-extension.js +1 -0
- package/app/utils/has-json-structure.js +1 -0
- package/app/utils/hason-structure.js +1 -0
- package/app/utils/haversine.js +1 -0
- package/app/utils/humanize.js +1 -0
- package/app/utils/is-electron.js +1 -0
- package/app/utils/is-email.js +1 -0
- package/app/utils/is-function.js +1 -0
- package/app/utils/is-image-file.js +1 -0
- package/app/utils/is-iterable.js +1 -0
- package/app/utils/is-latitude.js +1 -0
- package/app/utils/is-letter.js +1 -0
- package/app/utils/is-longitude.js +1 -0
- package/app/utils/is-model.js +1 -0
- package/app/utils/is-not-empty.js +1 -0
- package/app/utils/is-not-model.js +1 -0
- package/app/utils/is-numeric.js +1 -0
- package/app/utils/is-object.js +1 -0
- package/app/utils/is-proxy.js +1 -0
- package/app/utils/is-relation-missing.js +1 -0
- package/app/utils/is-valid-coordinates.js +1 -0
- package/app/utils/is-video-file.js +1 -0
- package/app/utils/is-waypoint-record.js +1 -0
- package/app/utils/ison.js +1 -0
- package/app/utils/isset.js +1 -0
- package/app/utils/last.js +1 -0
- package/app/utils/lazy-load-script.js +1 -0
- package/app/utils/leaflet-icon.js +1 -0
- package/app/utils/leaflet-points-from-coordinates.js +1 -0
- package/app/utils/load-engines.js +1 -0
- package/app/utils/load-extensions.js +1 -0
- package/app/utils/macros/group-by.js +1 -0
- package/app/utils/make-dataset.js +1 -0
- package/app/utils/map-engines.js +1 -0
- package/app/utils/mock-response.js +1 -0
- package/app/utils/numbers-only.js +1 -0
- package/app/utils/past-tense.js +1 -0
- package/app/utils/path-to-route.js +1 -0
- package/app/utils/polyline.js +1 -0
- package/app/utils/range.js +1 -0
- package/app/utils/refresh-route.js +1 -0
- package/app/utils/replace-table-row.js +1 -0
- package/app/utils/reverse-point.js +1 -0
- package/app/utils/serialize/normalize-polymorphic-type-within-hash.js +1 -0
- package/app/utils/serialize/normalize-polymorphic-type.js +1 -0
- package/app/utils/serialize/normalize-relations-with-hash.js +1 -0
- package/app/utils/set-column-filter-options.js +1 -0
- package/app/utils/strip-html.js +1 -0
- package/app/utils/to-leaflet-bounds.js +1 -0
- package/app/utils/to-model.js +1 -0
- package/app/utils/waypoint-label.js +1 -0
- package/app/utils/with-default-value.js +1 -0
- package/app/utils/words.js +1 -0
- package/config/environment.js +5 -0
- package/index.js +26 -0
- package/package.json +117 -0
- package/pnpm-lock.yaml +12750 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import Service from '@ember/service';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { inject as service } from '@ember/service';
|
|
4
|
+
import { dasherize } from '@ember/string';
|
|
5
|
+
import { isArray } from '@ember/array';
|
|
6
|
+
import { getOwner } from '@ember/application';
|
|
7
|
+
import closeSidebar from '@fleetbase/ember-ui/utils/close-sidebar';
|
|
8
|
+
|
|
9
|
+
export default class ThemeService extends Service {
|
|
10
|
+
/**
|
|
11
|
+
* Lookup the correct router for the engine and or console.
|
|
12
|
+
*
|
|
13
|
+
* @readonly
|
|
14
|
+
* @memberof ThemeService
|
|
15
|
+
*/
|
|
16
|
+
get router() {
|
|
17
|
+
const owner = getOwner(this);
|
|
18
|
+
const router = owner.lookup('service:router');
|
|
19
|
+
|
|
20
|
+
return router;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Inject the current user service
|
|
25
|
+
*
|
|
26
|
+
* @var {Service}
|
|
27
|
+
*/
|
|
28
|
+
@service currentUser;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The current active theme, uses the system preffered mode to set default
|
|
32
|
+
* refers to the theme in headData service
|
|
33
|
+
*
|
|
34
|
+
* @var {String}
|
|
35
|
+
*/
|
|
36
|
+
get activeTheme() {
|
|
37
|
+
const userSetTheme = this.currentUser.getOption(`theme`);
|
|
38
|
+
|
|
39
|
+
if (userSetTheme) {
|
|
40
|
+
return userSetTheme;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
44
|
+
return 'dark';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// default to dark theme
|
|
48
|
+
return 'dark';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Set the activeTheme in the headData service
|
|
53
|
+
*/
|
|
54
|
+
set activeTheme(theme) {
|
|
55
|
+
document.body.dataset.theme = theme;
|
|
56
|
+
this.currentTheme = theme;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Current theme, defaults to light, active theme represents the theme set by user OS
|
|
61
|
+
*
|
|
62
|
+
* @var {String}
|
|
63
|
+
*/
|
|
64
|
+
@tracked currentTheme = 'dark';
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The current route name as style class
|
|
68
|
+
*
|
|
69
|
+
* @var {String}
|
|
70
|
+
*/
|
|
71
|
+
get routeClassName() {
|
|
72
|
+
return dasherize(typeof this.router.currentRouteName === 'string' ? this.router.currentRouteName.replace(/\./g, ' ') : 'fleetbase-console');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The current route
|
|
77
|
+
*
|
|
78
|
+
* @var {Route}
|
|
79
|
+
*/
|
|
80
|
+
get currentRoute() {
|
|
81
|
+
return getOwner(this).lookup(`route:${this.router.currentRouteName}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The current route
|
|
86
|
+
*
|
|
87
|
+
* @var {Route}
|
|
88
|
+
*/
|
|
89
|
+
get currentRouteBodyClasses() {
|
|
90
|
+
if (this.currentRoute && this.currentRoute.bodyClassNames && isArray(this.currentRoute.bodyClassNames)) {
|
|
91
|
+
return this.currentRoute.bodyClassNames;
|
|
92
|
+
}
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Hook for handling when route does change
|
|
98
|
+
*
|
|
99
|
+
* @void
|
|
100
|
+
*/
|
|
101
|
+
routeDidChange() {
|
|
102
|
+
this.setRoutebodyClassNames(this.currentRouteBodyClasses);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Hook for handling when route does change
|
|
107
|
+
*
|
|
108
|
+
* @void
|
|
109
|
+
*/
|
|
110
|
+
routeWillChange() {
|
|
111
|
+
closeSidebar();
|
|
112
|
+
this.removeRoutebodyClassNames(this.currentRouteBodyClasses);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Initialize theme configurations
|
|
117
|
+
*
|
|
118
|
+
* @void
|
|
119
|
+
*/
|
|
120
|
+
initialize(options = {}) {
|
|
121
|
+
this.setTheme(this.activeTheme);
|
|
122
|
+
this.setEnvironment();
|
|
123
|
+
this.resetScroll();
|
|
124
|
+
this.setRoutebodyClassNames(options.bodyClassNames && isArray(options.bodyClassNames) ? options.bodyClassNames : []);
|
|
125
|
+
// on every subsequent transition set the body class
|
|
126
|
+
this.router.on('routeDidChange', this.routeDidChange.bind(this));
|
|
127
|
+
// remove route class as exiting
|
|
128
|
+
this.router.on('routeWillChange', this.routeWillChange.bind(this));
|
|
129
|
+
// remove console-loader
|
|
130
|
+
const consoleLoader = document.getElementById(`console-loader`);
|
|
131
|
+
if (consoleLoader) {
|
|
132
|
+
consoleLoader.remove();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Resets window scroll
|
|
138
|
+
*
|
|
139
|
+
* @void
|
|
140
|
+
*/
|
|
141
|
+
resetScroll() {
|
|
142
|
+
window.scrollTo(0, 0);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Appends the current route name to body
|
|
147
|
+
*
|
|
148
|
+
* @void
|
|
149
|
+
*/
|
|
150
|
+
setRoutebodyClassNames(classes = []) {
|
|
151
|
+
document.body.classList.add(...[this.routeClassName, `${this.currentTheme}-theme`, ...classes]);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Remove thes current route name from body
|
|
156
|
+
*
|
|
157
|
+
* @void
|
|
158
|
+
*/
|
|
159
|
+
removeRoutebodyClassNames(classes = []) {
|
|
160
|
+
document.body.classList.remove(...[this.routeClassName, `${this.currentTheme}-theme`, ...classes]);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Toggle the activeTheme between light and dark, and returns the toggled them
|
|
165
|
+
*
|
|
166
|
+
* @return string
|
|
167
|
+
*/
|
|
168
|
+
toggleTheme() {
|
|
169
|
+
const nextTheme = this.currentTheme === 'light' ? 'dark' : 'light';
|
|
170
|
+
this.setTheme(nextTheme);
|
|
171
|
+
return nextTheme;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Set the theme to the headData
|
|
176
|
+
*
|
|
177
|
+
* @void
|
|
178
|
+
*/
|
|
179
|
+
setTheme(theme = 'light') {
|
|
180
|
+
document.body.classList.remove(`${this.currentTheme}-theme`);
|
|
181
|
+
document.body.classList.add(`${theme}-theme`);
|
|
182
|
+
this.currentUser.setOption(`theme`, theme);
|
|
183
|
+
this.activeTheme = theme;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Set the theme to the headData
|
|
188
|
+
*
|
|
189
|
+
* @void
|
|
190
|
+
*/
|
|
191
|
+
setEnvironment() {
|
|
192
|
+
const isSandbox = this.currentUser.getOption('sandbox') || false;
|
|
193
|
+
|
|
194
|
+
if (isSandbox) {
|
|
195
|
+
document.body.classList.add('sandbox-console');
|
|
196
|
+
} else {
|
|
197
|
+
document.body.classList.remove('sandbox-console');
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import Service from '@ember/service';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import hasJsonStructure from '../utils/has-json-structure';
|
|
4
|
+
|
|
5
|
+
export default class UrlSearchParamsService extends Service {
|
|
6
|
+
/**
|
|
7
|
+
* The active URL params
|
|
8
|
+
*
|
|
9
|
+
* @var {Array}
|
|
10
|
+
*/
|
|
11
|
+
@tracked urlParams;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Update the URL params
|
|
15
|
+
*
|
|
16
|
+
* @void
|
|
17
|
+
*/
|
|
18
|
+
setSearchParams() {
|
|
19
|
+
this.urlParams = new URLSearchParams(window.location.search);
|
|
20
|
+
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get a param
|
|
26
|
+
*
|
|
27
|
+
* @param {String} key the url param
|
|
28
|
+
* @return mixed
|
|
29
|
+
*/
|
|
30
|
+
getParam(key) {
|
|
31
|
+
this.setSearchParams();
|
|
32
|
+
|
|
33
|
+
let value = this.urlParams.get(key);
|
|
34
|
+
|
|
35
|
+
if (hasJsonStructure(value)) {
|
|
36
|
+
value = JSON.parse(value);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get a param
|
|
44
|
+
*
|
|
45
|
+
* @param {String} key the url param
|
|
46
|
+
* @return mixed
|
|
47
|
+
*/
|
|
48
|
+
get(key) {
|
|
49
|
+
return this.getParam(key);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Determines if a queryParam exists
|
|
54
|
+
*
|
|
55
|
+
* @param {String} key the url param
|
|
56
|
+
* @var {Boolean}
|
|
57
|
+
*/
|
|
58
|
+
exists(key) {
|
|
59
|
+
this.setSearchParams();
|
|
60
|
+
|
|
61
|
+
return this.urlParams.has(key);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Remove a queryparam
|
|
66
|
+
*
|
|
67
|
+
* @param {String} key the url param
|
|
68
|
+
* @void
|
|
69
|
+
*/
|
|
70
|
+
remove(key) {
|
|
71
|
+
this.setSearchParams();
|
|
72
|
+
|
|
73
|
+
return this.urlParams.delete(key);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Returns object of all params
|
|
78
|
+
*
|
|
79
|
+
* @return {Array}
|
|
80
|
+
*/
|
|
81
|
+
all() {
|
|
82
|
+
this.setSearchParams();
|
|
83
|
+
|
|
84
|
+
const all = {};
|
|
85
|
+
|
|
86
|
+
for (let key of this.urlParams.keys()) {
|
|
87
|
+
all[key] = this.getParam(key);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return all;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import Transform from '@ember-data/serializer/transform';
|
|
2
|
+
import isIterable from '../utils/is-iterable';
|
|
3
|
+
import { isArray } from '@ember/array';
|
|
4
|
+
|
|
5
|
+
export default class ArrayTransform extends Transform {
|
|
6
|
+
deserialize(serialized) {
|
|
7
|
+
if (isArray(serialized)) {
|
|
8
|
+
return serialized;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (!isIterable(serialized)) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return Array.from(serialized);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
serialize(deserialized) {
|
|
19
|
+
if (isArray(deserialized)) {
|
|
20
|
+
return deserialized;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (!isIterable(deserialized)) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return Array.from(deserialized);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Transform from '@ember-data/serializer/transform';
|
|
2
|
+
|
|
3
|
+
export default class ObjectTransform extends Transform {
|
|
4
|
+
deserialize(serialized) {
|
|
5
|
+
return Object.assign({}, serialized);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
serialize(deserialized) {
|
|
9
|
+
return Object.assign({}, deserialized);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import consoleUrl from './console-url';
|
|
2
|
+
import config from '@fleetbase/console/config/environment';
|
|
3
|
+
import { get } from '@ember/object';
|
|
4
|
+
|
|
5
|
+
export default function apiUrl(path, queryParams = {}, subdomain = null, host = null) {
|
|
6
|
+
if (host === null) {
|
|
7
|
+
host = `${get(config, 'API.host')}/${get(config, 'API.namespace')}`;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return consoleUrl(path, queryParams, subdomain, host);
|
|
11
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import Model from '@ember-data/model';
|
|
2
|
+
import { isArray } from '@ember/array';
|
|
3
|
+
import { get } from '@ember/object';
|
|
4
|
+
import { isEmpty, tryInvoke } from '@ember/utils';
|
|
5
|
+
|
|
6
|
+
const _isEmpty = (value) => {
|
|
7
|
+
let empty = isEmpty(value);
|
|
8
|
+
|
|
9
|
+
if (empty) {
|
|
10
|
+
return empty;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// edge case for empty object {}
|
|
14
|
+
if (typeof value === 'object' && Object.values(value).length === 0) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return empty;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const invoke = (context, method, ...params) => {
|
|
22
|
+
if (typeof context.method === 'function') {
|
|
23
|
+
return context.method(...params);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return null;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const serialize = (model) => {
|
|
30
|
+
let serializerMethods = ['toJSON', 'toJson', 'serialize'];
|
|
31
|
+
|
|
32
|
+
for (let i = 0; i < serializerMethods.length; i++) {
|
|
33
|
+
const serializer = serializerMethods.objectAt(i);
|
|
34
|
+
const serialized = invoke(model, serializer);
|
|
35
|
+
|
|
36
|
+
if (!_isEmpty(serialized)) {
|
|
37
|
+
return serialized;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return autoSerialize(model);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default function autoSerialize(model, except = []) {
|
|
45
|
+
if (isArray(model)) {
|
|
46
|
+
return model.map((record) => autoSerialize(record, except));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!(model instanceof Model)) {
|
|
50
|
+
return {};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// hacky patch
|
|
54
|
+
const modelName = get(model, '_internalModel.modelName');
|
|
55
|
+
|
|
56
|
+
if (modelName === 'fleet') {
|
|
57
|
+
except.push('drivers');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (modelName === 'zone') {
|
|
61
|
+
except.push('service_area');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const serialized = {};
|
|
65
|
+
|
|
66
|
+
// set uuid from id
|
|
67
|
+
serialized.id = model.id;
|
|
68
|
+
serialized.uuid = model.id;
|
|
69
|
+
|
|
70
|
+
// serialize attributes
|
|
71
|
+
model.eachAttribute((attr) => {
|
|
72
|
+
if (except.includes(attr)) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
serialized[attr] = model[attr];
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// serialize relationships
|
|
80
|
+
model.eachRelationship((attr, descriptor) => {
|
|
81
|
+
const { kind } = descriptor;
|
|
82
|
+
|
|
83
|
+
if (except.includes(attr)) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (_isEmpty(model.get(attr))) {
|
|
88
|
+
serialized[attr] = null;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (kind === 'hasMany') {
|
|
93
|
+
serialized[attr] = model[attr].toArray().map((instance) => serialize(instance));
|
|
94
|
+
} else {
|
|
95
|
+
serialized[attr] = serialize(model[attr]);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return serialized;
|
|
100
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import config from '@fleetbase/console/config/environment';
|
|
2
|
+
import { isBlank } from '@ember/utils';
|
|
3
|
+
|
|
4
|
+
const isDevelopment = ['local', 'development'].includes(config.environment);
|
|
5
|
+
const isProduction = ['production'].includes(config.environment);
|
|
6
|
+
|
|
7
|
+
function queryString(params) {
|
|
8
|
+
return Object.keys(params)
|
|
9
|
+
.map((key) => `${key}=${params[key]}`)
|
|
10
|
+
.join('&');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function extractHostAndPort(url) {
|
|
14
|
+
try {
|
|
15
|
+
const parsedUrl = new URL(url);
|
|
16
|
+
const host = parsedUrl.hostname;
|
|
17
|
+
const port = parsedUrl.port;
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
host: host,
|
|
21
|
+
port: port || null,
|
|
22
|
+
};
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error('Invalid URL:', error);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default function consoleUrl(path = '', queryParams = {}, subdomain = 'console', host = 'fleetbase.io') {
|
|
30
|
+
let parsedHost = extractHostAndPort(host);
|
|
31
|
+
let url = isDevelopment ? 'http://' : 'https://';
|
|
32
|
+
|
|
33
|
+
if (subdomain) {
|
|
34
|
+
url += subdomain + '.';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let urlParams = !isBlank(queryParams) ? queryString(queryParams) : '';
|
|
38
|
+
|
|
39
|
+
if (!isProduction && !isDevelopment) {
|
|
40
|
+
url += `${config.environment}.`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
url += parsedHost.host;
|
|
44
|
+
|
|
45
|
+
if (parsedHost.port) {
|
|
46
|
+
url += `:${parsedHost.port}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
url += `/${path}`;
|
|
50
|
+
|
|
51
|
+
if (urlParams) {
|
|
52
|
+
url += `?${urlParams}`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return url;
|
|
56
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export default function copyToClipboard(value) {
|
|
2
|
+
const fallbackCopyToClipboard = (value) => {
|
|
3
|
+
return new Promise((resolve, reject) => {
|
|
4
|
+
const textArea = document.createElement('textarea');
|
|
5
|
+
textArea.value = value;
|
|
6
|
+
|
|
7
|
+
// Avoid scrolling to bottom
|
|
8
|
+
textArea.style.top = '0';
|
|
9
|
+
textArea.style.left = '0';
|
|
10
|
+
textArea.style.position = 'fixed';
|
|
11
|
+
|
|
12
|
+
document.body.appendChild(textArea);
|
|
13
|
+
textArea.focus();
|
|
14
|
+
textArea.select();
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
document.execCommand('copy');
|
|
18
|
+
resolve(value);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
reject(new Error(error));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
document.body.removeChild(textArea);
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const _copyToClipboard = (value) => {
|
|
28
|
+
if (!navigator.clipboard) {
|
|
29
|
+
return fallbackCopyToClipboard(value);
|
|
30
|
+
}
|
|
31
|
+
return navigator.clipboard.writeText(value);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return _copyToClipboard(value);
|
|
35
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
function corslite(url, callback, cors) {
|
|
2
|
+
var sent = false;
|
|
3
|
+
|
|
4
|
+
if (typeof window.XMLHttpRequest === 'undefined') {
|
|
5
|
+
return callback(Error('Browser not supported'));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (typeof cors === 'undefined') {
|
|
9
|
+
var m = url.match(/^\s*https?:\/\/[^\/]*/);
|
|
10
|
+
cors = m && m[0] !== location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
var x = new window.XMLHttpRequest();
|
|
14
|
+
|
|
15
|
+
function isSuccessful(status) {
|
|
16
|
+
return (status >= 200 && status < 300) || status === 304;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (cors && !('withCredentials' in x)) {
|
|
20
|
+
// IE8-9
|
|
21
|
+
x = new window.XDomainRequest();
|
|
22
|
+
|
|
23
|
+
// Ensure callback is never called synchronously, i.e., before
|
|
24
|
+
// x.send() returns (this has been observed in the wild).
|
|
25
|
+
// See https://github.com/mapbox/mapbox.js/issues/472
|
|
26
|
+
var original = callback;
|
|
27
|
+
callback = function () {
|
|
28
|
+
if (sent) {
|
|
29
|
+
original.apply(this, arguments);
|
|
30
|
+
} else {
|
|
31
|
+
var that = this,
|
|
32
|
+
args = arguments;
|
|
33
|
+
setTimeout(function () {
|
|
34
|
+
original.apply(that, args);
|
|
35
|
+
}, 0);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function loaded() {
|
|
41
|
+
if (
|
|
42
|
+
// XDomainRequest
|
|
43
|
+
x.status === undefined ||
|
|
44
|
+
// modern browsers
|
|
45
|
+
isSuccessful(x.status)
|
|
46
|
+
)
|
|
47
|
+
callback.call(x, null, x);
|
|
48
|
+
else callback.call(x, x, null);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Both `onreadystatechange` and `onload` can fire. `onreadystatechange`
|
|
52
|
+
// has [been supported for longer](http://stackoverflow.com/a/9181508/229001).
|
|
53
|
+
if ('onload' in x) {
|
|
54
|
+
x.onload = loaded;
|
|
55
|
+
} else {
|
|
56
|
+
x.onreadystatechange = function readystate() {
|
|
57
|
+
if (x.readyState === 4) {
|
|
58
|
+
loaded();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Call the callback with the XMLHttpRequest object as an error and prevent
|
|
64
|
+
// it from ever being called again by reassigning it to `noop`
|
|
65
|
+
x.onerror = function error(evt) {
|
|
66
|
+
// XDomainRequest provides no evt parameter
|
|
67
|
+
callback.call(this, evt || true, null);
|
|
68
|
+
callback = function () {};
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// IE9 must have onprogress be set to a unique function.
|
|
72
|
+
x.onprogress = function () {};
|
|
73
|
+
|
|
74
|
+
x.ontimeout = function (evt) {
|
|
75
|
+
callback.call(this, evt, null);
|
|
76
|
+
callback = function () {};
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
x.onabort = function (evt) {
|
|
80
|
+
callback.call(this, evt, null);
|
|
81
|
+
callback = function () {};
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// GET is the only supported HTTP Verb by XDomainRequest and is the
|
|
85
|
+
// only one supported here.
|
|
86
|
+
x.open('GET', url, true);
|
|
87
|
+
|
|
88
|
+
// Send the request. Sending data is not supported.
|
|
89
|
+
x.send(null);
|
|
90
|
+
sent = true;
|
|
91
|
+
|
|
92
|
+
return x;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export default corslite;
|