foreman_statistics 0.1.1 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/foreman_statistics/api/v2/statistics_controller.rb +9 -1
- data/app/controllers/foreman_statistics/api/v2/trends_controller.rb +8 -0
- data/app/jobs/foreman_statistics/trend_counter_job.rb +23 -0
- data/app/views/foreman_statistics/layouts/application_react.html.erb +1 -2
- data/app/views/foreman_statistics/trends/_empty_data.html.erb +0 -1
- data/app/views/foreman_statistics/trends/index.html.erb +3 -12
- data/app/views/foreman_statistics/trends/welcome.html.erb +1 -1
- data/db/migrate/20200605153005_migrate_core_types.rb +6 -2
- data/lib/foreman_statistics/engine.rb +7 -1
- data/lib/foreman_statistics/version.rb +1 -1
- data/lib/tasks/foreman_statistics_tasks.rake +3 -2
- data/locale/action_names.rb +5 -0
- data/locale/en/LC_MESSAGES/foreman_statistics.mo +0 -0
- data/locale/en/foreman_statistics.edit.po +258 -0
- data/locale/en/foreman_statistics.po +181 -2
- data/locale/en/foreman_statistics.po.time_stamp +0 -0
- data/locale/foreman_statistics.pot +265 -8
- data/locale/gemspec.rb +1 -1
- data/package.json +43 -0
- data/test/functional/foreman_statistics/api/v2/statistics_controller_test.rb +1 -1
- data/test/functional/foreman_statistics/api/v2/trends_controller_test.rb +1 -1
- data/test/functional/foreman_statistics/statistics_controller_test.rb +5 -7
- data/test/functional/foreman_statistics/trends_controller_test.rb +3 -3
- data/test/models/foreman_statistics/trend_counter_test.rb +1 -1
- data/test/models/foreman_statistics/trend_test.rb +1 -1
- data/test/{test_plugin_helper.rb → test_statistics_helper.rb} +0 -0
- data/test/unit/foreman_statistics/access_permissions_test.rb +1 -1
- data/test/unit/foreman_statistics/statistics_test.rb +1 -1
- data/test/unit/foreman_statistics_test.rb +1 -1
- data/test/unit/tasks/foreman_statistics_tasks_test.rb +1 -1
- data/webpack/__mocks__/foremanReact/API.js +7 -0
- data/webpack/__mocks__/foremanReact/common/HOC.js +24 -0
- data/webpack/__mocks__/foremanReact/common/I18n.js +3 -0
- data/webpack/__mocks__/foremanReact/common/helpers.js +1 -0
- data/webpack/__mocks__/foremanReact/common/urlHelpers.js +1 -0
- data/webpack/__mocks__/foremanReact/components/ChartBox/index.js +2 -0
- data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalActions.js +2 -0
- data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalHooks.js +10 -0
- data/webpack/__mocks__/foremanReact/components/ForemanModal/index.js +4 -0
- data/webpack/__mocks__/foremanReact/components/Layout/LayoutActions.js +2 -0
- data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +2 -0
- data/webpack/__mocks__/foremanReact/components/common/EmptyState.js +5 -0
- data/webpack/__mocks__/foremanReact/components/common/MessageBox.js +4 -0
- data/webpack/__mocks__/foremanReact/components/common/dates/LongDateTime.js +5 -0
- data/webpack/__mocks__/foremanReact/components/common/dates/RelativeDateTime.js +3 -0
- data/webpack/__mocks__/foremanReact/components/common/table.js +5 -0
- data/webpack/__mocks__/foremanReact/components/common/table/actionsHelpers/actionTypeCreator.js +7 -0
- data/webpack/__mocks__/foremanReact/constants.js +24 -0
- data/webpack/__mocks__/foremanReact/readme.md +11 -0
- data/webpack/__mocks__/foremanReact/redux/actions/toasts.js +8 -0
- data/webpack/__mocks__/foremanReact/routes/common/PageLayout/PageLayout.js +10 -0
- data/webpack/__mocks__/foremanReact/routes/common/PageLayout/components/ExportButton/ExportButton.js +5 -0
- data/webpack/__mocks__/foremanReact/routes/common/reducerHOC/withDataReducer.js +35 -0
- data/webpack/fills_index.js +15 -0
- data/webpack/index.js +21 -0
- data/webpack/src/Components/StatisticsChartsList/StatisticsChartsList.fixtures.js +19 -0
- data/webpack/src/Components/StatisticsChartsList/StatisticsChartsList.test.js +18 -0
- data/webpack/src/Components/StatisticsChartsList/StatisticsChartsListStyles.scss +28 -0
- data/webpack/src/Components/StatisticsChartsList/__snapshots__/StatisticsChartsList.test.js.snap +42 -0
- data/webpack/src/Components/StatisticsChartsList/index.js +32 -0
- data/webpack/src/ForemanStatistics.js +11 -0
- data/webpack/src/Router/StatisticsPage/Statistics/Statistics.js +27 -0
- data/webpack/src/Router/StatisticsPage/StatisticsPage.fixtures.js +11 -0
- data/webpack/src/Router/StatisticsPage/StatisticsPage.js +21 -0
- data/webpack/src/Router/StatisticsPage/StatisticsPageActions.js +43 -0
- data/webpack/src/Router/StatisticsPage/StatisticsPageSelectors.js +13 -0
- data/webpack/src/Router/StatisticsPage/__tests__/StatisticsPage.test.js +12 -0
- data/webpack/src/Router/StatisticsPage/__tests__/StatisticsPageActions.test.js +27 -0
- data/webpack/src/Router/StatisticsPage/__tests__/StatisticsPageSelectors.test.js +34 -0
- data/webpack/src/Router/StatisticsPage/__tests__/__snapshots__/StatisticsPage.test.js.snap +32 -0
- data/webpack/src/Router/StatisticsPage/__tests__/__snapshots__/StatisticsPageActions.test.js.snap +54 -0
- data/webpack/src/Router/StatisticsPage/__tests__/__snapshots__/StatisticsPageSelectors.test.js.snap +35 -0
- data/webpack/src/Router/StatisticsPage/constants.js +4 -0
- data/webpack/src/Router/StatisticsPage/index.js +36 -0
- data/webpack/src/Router/__snapshots__/routes.test.js.snap +47 -0
- data/webpack/src/Router/index.js +14 -0
- data/webpack/src/Router/routes.js +11 -0
- data/webpack/src/Router/routes.test.js +27 -0
- data/webpack/src/index.js +1 -0
- data/webpack/src/reducers.js +9 -0
- data/webpack/src/trends.js +7 -0
- data/webpack/src/trends.test.js +44 -0
- metadata +67 -9
data/locale/gemspec.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# Matches foreman_statistics.gemspec
|
2
|
-
_('
|
2
|
+
_('Statistics and Trends for Foreman gives users overview of their infrastructure.')
|
data/package.json
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
{
|
2
|
+
"name": "foreman_statistics",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "DESCRIPTION",
|
5
|
+
"main": "index.js",
|
6
|
+
"scripts": {
|
7
|
+
"lint": "tfm-lint --plugin -d /webpack",
|
8
|
+
"test": "tfm-test --plugin",
|
9
|
+
"test:watch": "tfm-test --plugin --watchAll",
|
10
|
+
"test:current": "tfm-test --plugin --watch",
|
11
|
+
"publish-coverage": "tfm-publish-coverage",
|
12
|
+
"stories": "tfm-stories --plugin",
|
13
|
+
"stories:build": "tfm-build-stories --plugin",
|
14
|
+
"create-react-component": "yo react-domain"
|
15
|
+
},
|
16
|
+
"repository": {
|
17
|
+
"type": "git",
|
18
|
+
"url": "git+https://github.com/theforeman/foreman_statistics.git"
|
19
|
+
},
|
20
|
+
"bugs": {
|
21
|
+
"url": "http://projects.theforeman.org/projects/foreman_statistics/issues"
|
22
|
+
},
|
23
|
+
"peerDependencies": {
|
24
|
+
"@theforeman/vendor": ">= 6.0.0"
|
25
|
+
},
|
26
|
+
"devDependencies": {
|
27
|
+
"@babel/core": "^7.7.0",
|
28
|
+
"@theforeman/builder": "^6.0.0",
|
29
|
+
"@theforeman/eslint-plugin-foreman": "^6.0.0",
|
30
|
+
"@theforeman/find-foreman": "^4.8.0",
|
31
|
+
"@theforeman/stories": "^7.0.0",
|
32
|
+
"@theforeman/test": "^8.0.0",
|
33
|
+
"@theforeman/vendor-dev": "^6.0.0",
|
34
|
+
"babel-eslint": "^10.0.3",
|
35
|
+
"eslint": "^6.7.2",
|
36
|
+
"prettier": "^1.19.1",
|
37
|
+
"stylelint-config-standard": "^18.0.0",
|
38
|
+
"stylelint": "^9.3.0"
|
39
|
+
},
|
40
|
+
"dependencies": {
|
41
|
+
"react-intl": "^2.8.0"
|
42
|
+
}
|
43
|
+
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require 'test_statistics_helper'
|
2
2
|
|
3
3
|
module ForemanStatistics
|
4
4
|
class StatisticsControllerTest < ActionController::TestCase
|
@@ -7,16 +7,14 @@ module ForemanStatistics
|
|
7
7
|
end
|
8
8
|
|
9
9
|
test 'user with viewer rights should succeed in viewing statistics' do
|
10
|
-
|
11
|
-
|
12
|
-
get :index, session: set_session_user
|
10
|
+
setup_user('view', 'statistics')
|
11
|
+
get :index, session: set_session_user(:one)
|
13
12
|
assert_response :success
|
14
13
|
end
|
15
14
|
|
16
15
|
test 'user with viewer rights should succeed in requesting statistics data via ajax' do
|
17
|
-
|
18
|
-
|
19
|
-
get :show, params: { :id => 'operatingsystem', :format => 'json' }, session: set_session_user
|
16
|
+
setup_user('view', 'statistics')
|
17
|
+
get :show, params: { :id => 'operatingsystem', :format => 'json' }, session: set_session_user(:one)
|
20
18
|
assert_response :success
|
21
19
|
end
|
22
20
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require 'test_statistics_helper'
|
2
2
|
|
3
3
|
module ForemanStatistics
|
4
4
|
class TrendsControllerTest < ActionController::TestCase
|
@@ -46,14 +46,14 @@ module ForemanStatistics
|
|
46
46
|
test 'should render correct per_page value' do
|
47
47
|
get :index, params: { per_page: entries_per_page + 1 }, session: set_session_user
|
48
48
|
assert_response :success
|
49
|
-
per_page_results = response.body.scan(/perPage
|
49
|
+
per_page_results = response.body.scan(/perPage":(\d+)/).first.first.to_i
|
50
50
|
assert_equal entries_per_page, per_page_results
|
51
51
|
end
|
52
52
|
|
53
53
|
test 'should render per page dropdown with correct values' do
|
54
54
|
get :index, params: { per_page: entries_per_page + 1 }, session: set_session_user
|
55
55
|
assert_response :success
|
56
|
-
assert_not_nil response.body['perPageOptions
|
56
|
+
assert_not_nil response.body['perPageOptions":[5,6,10,15,25,50]']
|
57
57
|
end
|
58
58
|
|
59
59
|
test 'sort links should include per page param' do
|
File without changes
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import React, { useEffect } from 'react';
|
2
|
+
|
3
|
+
export const callOnMount = callback => WrappedComponent => componentProps => {
|
4
|
+
// fires callback onMount, [] means don't listen to any props change
|
5
|
+
useEffect(() => {
|
6
|
+
callback(componentProps);
|
7
|
+
}, [componentProps]);
|
8
|
+
|
9
|
+
return <WrappedComponent {...componentProps} />;
|
10
|
+
};
|
11
|
+
|
12
|
+
export const withRenderHandler = ({
|
13
|
+
Component,
|
14
|
+
LoadingComponent = () => jest.fn(),
|
15
|
+
ErrorComponent = () => jest.fn(),
|
16
|
+
EmptyComponent = () => jest.fn(),
|
17
|
+
}) => componentProps => {
|
18
|
+
const { isLoading, hasData, hasError } = componentProps;
|
19
|
+
|
20
|
+
if (isLoading && !hasData) return <LoadingComponent {...componentProps} />;
|
21
|
+
if (hasError) return <ErrorComponent {...componentProps} />;
|
22
|
+
if (hasData) return <Component {...componentProps} />;
|
23
|
+
return <EmptyComponent {...componentProps} />;
|
24
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export const noop = Function.prototype;
|
@@ -0,0 +1 @@
|
|
1
|
+
export const getURIsearch = () => 'a=b';
|
@@ -0,0 +1,24 @@
|
|
1
|
+
export const STATUS = {
|
2
|
+
PENDING: 'PENDING',
|
3
|
+
RESOLVED: 'RESOLVED',
|
4
|
+
ERROR: 'ERROR',
|
5
|
+
};
|
6
|
+
|
7
|
+
export const getControllerSearchProps = (
|
8
|
+
controller,
|
9
|
+
id = 'searchBar',
|
10
|
+
canCreateBookmarks = true
|
11
|
+
) => ({
|
12
|
+
controller,
|
13
|
+
autocomplete: {
|
14
|
+
id,
|
15
|
+
searchQuery: '',
|
16
|
+
url: `${controller}/auto_complete_search`,
|
17
|
+
useKeyShortcuts: true,
|
18
|
+
},
|
19
|
+
bookmarks: {
|
20
|
+
url: '/api/bookmarks',
|
21
|
+
canCreateBookmarks,
|
22
|
+
documentationUrl: `4.1.5Searching`,
|
23
|
+
},
|
24
|
+
});
|
@@ -0,0 +1,11 @@
|
|
1
|
+
For testing components which have imported foreman-core components,
|
2
|
+
a mock file is required in this folder.
|
3
|
+
|
4
|
+
### Example: Mocking ForemanModal component
|
5
|
+
```js
|
6
|
+
// __mocks__/foremanReact/components/ForemanModal/index.js
|
7
|
+
const ForemanModal = () => jest.fn();
|
8
|
+
ForemanModal.Header = () => jest.fn();
|
9
|
+
ForemanModal.Footer = () => jest.fn();
|
10
|
+
export default ForemanModal;
|
11
|
+
```
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import Immutable from 'seamless-immutable';
|
2
|
+
|
3
|
+
const initialState = Immutable({
|
4
|
+
isLoading: true,
|
5
|
+
hasError: false,
|
6
|
+
hasData: false,
|
7
|
+
message: { type: 'empty', text: '' },
|
8
|
+
});
|
9
|
+
|
10
|
+
const withDataReducer = controller => (
|
11
|
+
state = initialState,
|
12
|
+
{ type, payload }
|
13
|
+
) => {
|
14
|
+
switch (type) {
|
15
|
+
case `${controller}_DATA_RESOLVED`:
|
16
|
+
return state.merge({ ...payload, isLoading: false });
|
17
|
+
|
18
|
+
case `${controller}_DATA_FAILED`:
|
19
|
+
return state.merge({ ...payload, isLoading: false, hasError: true });
|
20
|
+
|
21
|
+
case `${controller}_CLEAR_ERROR`:
|
22
|
+
return state.set('hasError', false);
|
23
|
+
|
24
|
+
case `${controller}_SHOW_LOADING`:
|
25
|
+
return state.set('isLoading', true);
|
26
|
+
|
27
|
+
case `${controller}_HIDE_LOADING`:
|
28
|
+
return state.set('isLoading', false);
|
29
|
+
|
30
|
+
default:
|
31
|
+
return state;
|
32
|
+
}
|
33
|
+
};
|
34
|
+
|
35
|
+
export default withDataReducer;
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// This example for extanding foreman-core's component via slot&fill
|
2
|
+
|
3
|
+
/*
|
4
|
+
import React from 'react';
|
5
|
+
import { addGlobalFill } from 'foremanReact/components/common/Fill/GlobalFill';
|
6
|
+
|
7
|
+
addGlobalFill('slotId', 'fillId', <SomeComponent key="some-key" />, 300);
|
8
|
+
|
9
|
+
addGlobalFill(
|
10
|
+
'slotId',
|
11
|
+
'fillId',
|
12
|
+
{ someProp: 'this is an override prop' },
|
13
|
+
300
|
14
|
+
);
|
15
|
+
*/
|
data/webpack/index.js
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
/* eslint import/no-unresolved: [2, { ignore: [foremanReact/*] }] */
|
2
|
+
/* eslint-disable import/no-extraneous-dependencies */
|
3
|
+
/* eslint-disable import/extensions */
|
4
|
+
import componentRegistry from 'foremanReact/components/componentRegistry';
|
5
|
+
import { registerReducer } from 'foremanReact/common/MountingService';
|
6
|
+
import reducers from './src/reducers';
|
7
|
+
import ForemanStatistics from './src/ForemanStatistics';
|
8
|
+
import * as trends from './src/trends';
|
9
|
+
|
10
|
+
Object.assign(window.tfm, { trends });
|
11
|
+
|
12
|
+
// register reducers
|
13
|
+
Object.entries(reducers).forEach(([key, reducer]) =>
|
14
|
+
registerReducer(key, reducer)
|
15
|
+
);
|
16
|
+
|
17
|
+
// register components for erb mounting
|
18
|
+
componentRegistry.register({
|
19
|
+
name: 'ForemanStatistics',
|
20
|
+
type: ForemanStatistics,
|
21
|
+
});
|
@@ -0,0 +1,19 @@
|
|
1
|
+
export const statisticsData = {
|
2
|
+
operatingsystem: {
|
3
|
+
id: 'operatingsystem',
|
4
|
+
title: 'OS Distribution',
|
5
|
+
url: 'statistics/operatingsystem',
|
6
|
+
search: '/hosts?search=os_title=~VAL~',
|
7
|
+
},
|
8
|
+
architecture: {
|
9
|
+
id: 'architecture',
|
10
|
+
title: 'Architecture Distribution',
|
11
|
+
url: 'statistics/architecture',
|
12
|
+
search: '/hosts?search=facts.architecture=~VAL~',
|
13
|
+
},
|
14
|
+
};
|
15
|
+
|
16
|
+
export const statisticsMeta = [
|
17
|
+
statisticsData.operatingsystem,
|
18
|
+
statisticsData.architecture,
|
19
|
+
];
|