forked from getredash/redash
/
index.js
134 lines (115 loc) · 3.62 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// This polyfill is needed to support PhantomJS which we use to generate PNGs from embeds.
import 'core-js/fn/typed/array-buffer';
import * as Pace from 'pace-progress';
import debug from 'debug';
import angular from 'angular';
import ngSanitize from 'angular-sanitize';
import ngRoute from 'angular-route';
import ngResource from 'angular-resource';
import uiBootstrap from 'angular-ui-bootstrap';
import uiSelect from 'ui-select';
import ngMessages from 'angular-messages';
import toastr from 'angular-toastr';
import ngUpload from 'angular-base64-upload';
import vsRepeat from 'angular-vs-repeat';
import 'angular-moment';
import 'brace';
import 'angular-ui-ace';
import 'angular-resizable';
import { each, isFunction } from 'underscore';
import '@/lib/sortable';
import * as filters from '@/filters';
import registerDirectives from '@/directives';
import markdownFilter from '@/filters/markdown';
import dateTimeFilter from '@/filters/datetime';
import dashboardGridOptions from './dashboard-grid-options';
const logger = debug('redash:config');
Pace.options.shouldHandlePushState = (prevUrl, newUrl) => {
// Show pace progress bar only if URL path changed; when query params
// or hash changed - ignore that history event
const [prevPrefix] = prevUrl.split('?');
const [newPrefix] = newUrl.split('?');
return prevPrefix !== newPrefix;
};
const requirements = [
ngRoute,
ngResource,
ngSanitize,
uiBootstrap,
ngMessages,
uiSelect,
'angularMoment',
toastr,
'ui.ace',
ngUpload,
'angularResizable',
vsRepeat,
'ui.sortable',
];
const ngModule = angular.module('app', requirements);
dashboardGridOptions(ngModule);
function registerAll(context) {
const modules = context
.keys()
.map(context)
.map(module => module.default);
return modules.filter(isFunction).map(f => f(ngModule));
}
function requireImages() {
// client/app/assets/images/<path> => /images/<path>
const ctx = require.context('@/assets/images/', true, /\.(png|jpe?g|gif|svg)$/);
ctx.keys().forEach(ctx);
}
function registerComponents() {
// We repeat this code in other register functions, because if we don't use a literal for the path
// Webpack won't be able to statcily analyze our imports.
const context = require.context('@/components', true, /^((?![\\/]test[\\/]).)*\.js$/);
registerAll(context);
}
function registerServices() {
const context = require.context('@/services', true, /^((?![\\/]test[\\/]).)*\.js$/);
registerAll(context);
}
function registerVisualizations() {
const context = require.context('@/visualizations', true, /^((?![\\/]test[\\/]).)*\.js$/);
registerAll(context);
}
function registerPages() {
const context = require.context('@/pages', true, /^((?![\\/]test[\\/]).)*\.js$/);
const routesCollection = registerAll(context);
routesCollection.forEach((routes) => {
ngModule.config(($routeProvider) => {
each(routes, (route, path) => {
logger('Registering route: %s', path);
route.authenticated = true;
$routeProvider.when(path, route);
});
});
});
ngModule.config(($routeProvider) => {
$routeProvider.otherwise({
resolve: {
// Ugly hack to show 404 when hitting an unknown route.
error: () => {
const error = { status: 404 };
throw error;
},
},
});
});
}
function registerFilters() {
each(filters, (filter, name) => {
ngModule.filter(name, () => filter);
});
}
requireImages();
registerDirectives(ngModule);
registerServices();
registerFilters();
markdownFilter(ngModule);
dateTimeFilter(ngModule);
registerComponents();
registerPages();
registerVisualizations(ngModule);
export default ngModule;