foreman_resource_quota 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +51 -0
  4. data/Rakefile +49 -0
  5. data/app/controllers/concerns/foreman/controller/parameters/resource_quota.rb +28 -0
  6. data/app/controllers/foreman_resource_quota/api/v2/resource_quotas_controller.rb +96 -0
  7. data/app/controllers/foreman_resource_quota/application_controller.rb +9 -0
  8. data/app/controllers/foreman_resource_quota/resource_quotas_controller.rb +50 -0
  9. data/app/helpers/foreman_resource_quota/hosts_helper.rb +18 -0
  10. data/app/helpers/foreman_resource_quota/resource_quota_helper.rb +107 -0
  11. data/app/models/concerns/foreman_resource_quota/host_managed_extensions.rb +115 -0
  12. data/app/models/concerns/foreman_resource_quota/user_extensions.rb +15 -0
  13. data/app/models/concerns/foreman_resource_quota/usergroup_extensions.rb +14 -0
  14. data/app/models/foreman_resource_quota/resource_quota.rb +83 -0
  15. data/app/models/foreman_resource_quota/resource_quota_user.rb +10 -0
  16. data/app/models/foreman_resource_quota/resource_quota_usergroup.rb +10 -0
  17. data/app/services/foreman_resource_quota/resource_origin.rb +97 -0
  18. data/app/services/foreman_resource_quota/resource_origins/compute_attributes_origin.rb +64 -0
  19. data/app/services/foreman_resource_quota/resource_origins/compute_resource_origin.rb +82 -0
  20. data/app/services/foreman_resource_quota/resource_origins/facts_origin.rb +68 -0
  21. data/app/services/foreman_resource_quota/resource_origins/vm_attributes_origin.rb +40 -0
  22. data/app/views/foreman_resource_quota/api/v2/hosts/resource_quota.json.rabl +3 -0
  23. data/app/views/foreman_resource_quota/api/v2/resource_quotas/base.json.rabl +6 -0
  24. data/app/views/foreman_resource_quota/api/v2/resource_quotas/create.json.rabl +5 -0
  25. data/app/views/foreman_resource_quota/api/v2/resource_quotas/hosts.json.rabl +7 -0
  26. data/app/views/foreman_resource_quota/api/v2/resource_quotas/index.json.rabl +5 -0
  27. data/app/views/foreman_resource_quota/api/v2/resource_quotas/main.json.rabl +7 -0
  28. data/app/views/foreman_resource_quota/api/v2/resource_quotas/show.json.rabl +5 -0
  29. data/app/views/foreman_resource_quota/api/v2/resource_quotas/update.json.rabl +5 -0
  30. data/app/views/foreman_resource_quota/api/v2/resource_quotas/usergroups.json.rabl +7 -0
  31. data/app/views/foreman_resource_quota/api/v2/resource_quotas/users.json.rabl +7 -0
  32. data/app/views/foreman_resource_quota/api/v2/resource_quotas/utilization.json.rabl +7 -0
  33. data/app/views/foreman_resource_quota/api/v2/usergroups/resource_quota.json.rabl +3 -0
  34. data/app/views/foreman_resource_quota/api/v2/users/resource_quota.json.rabl +3 -0
  35. data/app/views/foreman_resource_quota/resource_quotas/_form.html.erb +21 -0
  36. data/app/views/foreman_resource_quota/resource_quotas/edit.html.erb +12 -0
  37. data/app/views/foreman_resource_quota/resource_quotas/index.html.erb +55 -0
  38. data/app/views/foreman_resource_quota/resource_quotas/new.html.erb +10 -0
  39. data/app/views/foreman_resource_quota/resource_quotas/welcome.html.erb +10 -0
  40. data/app/views/hosts/_form_quota_fields.html.erb +4 -0
  41. data/app/views/users/_form_quota_tab.html.erb +45 -0
  42. data/config/initializers/inflections.rb +5 -0
  43. data/config/routes.rb +43 -0
  44. data/db/migrate/20230306120001_create_resource_quotas.rb +31 -0
  45. data/lib/foreman_resource_quota/engine.rb +56 -0
  46. data/lib/foreman_resource_quota/exceptions.rb +11 -0
  47. data/lib/foreman_resource_quota/register.rb +106 -0
  48. data/lib/foreman_resource_quota/version.rb +5 -0
  49. data/lib/foreman_resource_quota.rb +6 -0
  50. data/lib/tasks/foreman_resource_quota_tasks.rake +50 -0
  51. data/locale/Makefile +60 -0
  52. data/locale/en/foreman_resource_quota.po +18 -0
  53. data/locale/foreman_resource_quota.pot +19 -0
  54. data/locale/gemspec.rb +4 -0
  55. data/package.json +44 -0
  56. data/webpack/api_helper.js +113 -0
  57. data/webpack/api_helper.test.js +96 -0
  58. data/webpack/components/CreateResourceQuotaModal.js +46 -0
  59. data/webpack/components/ResourceQuotaEmptyState/index.js +58 -0
  60. data/webpack/components/ResourceQuotaForm/ResourceQuotaForm.scss +1 -0
  61. data/webpack/components/ResourceQuotaForm/ResourceQuotaFormConstants.js +71 -0
  62. data/webpack/components/ResourceQuotaForm/components/Properties/Properties.scss +9 -0
  63. data/webpack/components/ResourceQuotaForm/components/Properties/StaticDetail.js +72 -0
  64. data/webpack/components/ResourceQuotaForm/components/Properties/StatusPropertiesLabel.js +71 -0
  65. data/webpack/components/ResourceQuotaForm/components/Properties/StatusPropertiesLabel.test.js +50 -0
  66. data/webpack/components/ResourceQuotaForm/components/Properties/TextInputField.js +131 -0
  67. data/webpack/components/ResourceQuotaForm/components/Properties/index.js +190 -0
  68. data/webpack/components/ResourceQuotaForm/components/QuotaState.js +157 -0
  69. data/webpack/components/ResourceQuotaForm/components/Resource/Resource.scss +13 -0
  70. data/webpack/components/ResourceQuotaForm/components/Resource/UnitInputField.js +224 -0
  71. data/webpack/components/ResourceQuotaForm/components/Resource/UtilizationProgress.js +151 -0
  72. data/webpack/components/ResourceQuotaForm/components/Resource/UtilizationProgress.scss +10 -0
  73. data/webpack/components/ResourceQuotaForm/components/Resource/index.js +239 -0
  74. data/webpack/components/ResourceQuotaForm/components/Resources.js +105 -0
  75. data/webpack/components/ResourceQuotaForm/components/Submit.js +72 -0
  76. data/webpack/components/ResourceQuotaForm/index.js +185 -0
  77. data/webpack/components/UpdateResourceQuotaModal.js +143 -0
  78. data/webpack/global_index.js +15 -0
  79. data/webpack/global_test_setup.js +11 -0
  80. data/webpack/helper.js +86 -0
  81. data/webpack/index.js +23 -0
  82. data/webpack/lib/ActionableDetail.js +115 -0
  83. data/webpack/lib/ActionableDetail.scss +4 -0
  84. data/webpack/lib/EditableSwitch.js +47 -0
  85. data/webpack/lib/EditableTextInput/EditableTextInput.js +206 -0
  86. data/webpack/lib/EditableTextInput/PencilEditButton.js +27 -0
  87. data/webpack/lib/EditableTextInput/__tests__/editableTextInput.test.js +193 -0
  88. data/webpack/lib/EditableTextInput/editableTextInput.scss +38 -0
  89. data/webpack/lib/EditableTextInput/index.js +4 -0
  90. data/webpack/lib/react-testing-lib-wrapper.js +80 -0
  91. data/webpack/test_setup.js +17 -0
  92. metadata +134 -0
@@ -0,0 +1,193 @@
1
+ /* Credits: https://github.com/Katello/katello/blob/631d5bb83dc5d87320ee9002a6de33809a281b3e/webpack/components/EditableTextInput/__tests__/editableTextInput.test.js */
2
+ import React from 'react';
3
+ import { head } from 'lodash';
4
+ import {
5
+ render,
6
+ patientlyWaitFor,
7
+ fireEvent,
8
+ } from '../../react-testing-lib-wrapper';
9
+ import EditableTextInput from '../EditableTextInput';
10
+
11
+ const actualValue = 'burger';
12
+ const attribute = 'favorite_food';
13
+ const defaultProps = {
14
+ onEdit: jest.fn(),
15
+ value: actualValue,
16
+ attribute,
17
+ };
18
+
19
+ test('Passed function is called after editing and clicking submit', async () => {
20
+ const mockEdit = jest.fn();
21
+ const { getByLabelText } = render(
22
+ <EditableTextInput {...defaultProps} onEdit={mockEdit} />
23
+ );
24
+
25
+ getByLabelText(`edit ${attribute}`).click();
26
+ fireEvent.change(getByLabelText(`${attribute} text input`), {
27
+ target: { value: actualValue },
28
+ });
29
+ getByLabelText(`submit ${attribute}`).click();
30
+ await patientlyWaitFor(() => expect(mockEdit.mock.calls).toHaveLength(1));
31
+ expect(mockEdit.mock.calls[0][0]).toBe(actualValue); // first arg
32
+ });
33
+
34
+ test('Passed function is called after editing and hitting enter', async () => {
35
+ const mockEdit = jest.fn();
36
+ const { getByLabelText } = render(
37
+ <EditableTextInput {...defaultProps} onEdit={mockEdit} />
38
+ );
39
+
40
+ getByLabelText(`edit ${attribute}`).click();
41
+ const textInputLabel = getByLabelText(`${attribute} text input`);
42
+ fireEvent.change(textInputLabel, {
43
+ target: { value: actualValue },
44
+ });
45
+ fireEvent.keyUp(textInputLabel, {
46
+ key: 'Enter',
47
+ code: 'Enter',
48
+ });
49
+ await patientlyWaitFor(() => expect(mockEdit.mock.calls).toHaveLength(1));
50
+ expect(head(mockEdit.mock.calls)).toContain(actualValue); // first arg
51
+ });
52
+
53
+ test('input is set back to original value after clearing', () => {
54
+ const value = 'Sandwich';
55
+ const { getByLabelText } = render(<EditableTextInput {...defaultProps} />);
56
+
57
+ // Show original value on load
58
+ expect(getByLabelText(`${attribute} text value`)).toHaveTextContent(
59
+ actualValue
60
+ );
61
+ getByLabelText(`edit ${attribute}`).click();
62
+ // Update text input
63
+ fireEvent.change(getByLabelText(`${attribute} text input`), {
64
+ target: { value },
65
+ });
66
+ expect(getByLabelText(`${attribute} text input`)).toHaveValue(value);
67
+ // Clear text
68
+ getByLabelText(`clear ${attribute}`).click();
69
+ // Original value is still showing even though it's been edited
70
+ expect(getByLabelText(`${attribute} text value`)).toHaveTextContent(
71
+ actualValue
72
+ );
73
+ });
74
+
75
+ test('shows a mask over the password when there is one', () => {
76
+ const { getByLabelText } = render(
77
+ <EditableTextInput
78
+ attribute={attribute}
79
+ onEdit={jest.fn()}
80
+ isPassword
81
+ hasPassword
82
+ />
83
+ );
84
+
85
+ expect(getByLabelText(`${attribute} text value`)).toHaveTextContent(
86
+ '••••••••'
87
+ );
88
+ });
89
+
90
+ test('shows a mask over the password after undoing changes', () => {
91
+ const { getByLabelText } = render(
92
+ <EditableTextInput
93
+ attribute={attribute}
94
+ onEdit={jest.fn()}
95
+ isPassword
96
+ hasPassword
97
+ />
98
+ );
99
+
100
+ getByLabelText(`edit ${attribute}`).click();
101
+ expect(getByLabelText(`${attribute} text input`)).toHaveTextContent('');
102
+
103
+ getByLabelText(`clear ${attribute}`).click();
104
+ expect(getByLabelText(`${attribute} text value`)).toHaveTextContent(
105
+ '••••••••'
106
+ );
107
+ });
108
+
109
+ test('shows a mask over the password after editing', async () => {
110
+ const newPassword = 'Pizza';
111
+ const { getByLabelText } = render(
112
+ <EditableTextInput
113
+ attribute={attribute}
114
+ onEdit={jest.fn()}
115
+ isPassword
116
+ hasPassword
117
+ />
118
+ );
119
+
120
+ getByLabelText(`edit ${attribute}`).click();
121
+ fireEvent.change(getByLabelText(`${attribute} text input`), {
122
+ target: { value: newPassword },
123
+ });
124
+ expect(getByLabelText(`${attribute} text input`)).toHaveValue(newPassword);
125
+ getByLabelText(`submit ${attribute}`).click();
126
+
127
+ await patientlyWaitFor(() =>
128
+ expect(getByLabelText(`${attribute} text value`)).toBeInTheDocument()
129
+ );
130
+ expect(getByLabelText(`${attribute} text value`)).toHaveTextContent(
131
+ '••••••••'
132
+ );
133
+ });
134
+
135
+ test('shows a placeholder after clearing the password', async () => {
136
+ const { getByLabelText } = render(
137
+ <EditableTextInput
138
+ attribute={attribute}
139
+ onEdit={jest.fn()}
140
+ isPassword
141
+ hasPassword
142
+ />
143
+ );
144
+
145
+ getByLabelText(`edit ${attribute}`).click();
146
+ getByLabelText(`submit ${attribute}`).click();
147
+
148
+ await patientlyWaitFor(() =>
149
+ expect(getByLabelText(`${attribute} text value`)).toBeInTheDocument()
150
+ );
151
+ expect(getByLabelText(`${attribute} text value`)).toHaveTextContent(
152
+ 'None provided'
153
+ );
154
+ });
155
+
156
+ test('can toggle showing the current password', async () => {
157
+ const { getByLabelText } = render(
158
+ <EditableTextInput
159
+ attribute={attribute}
160
+ onEdit={jest.fn()}
161
+ isPassword
162
+ hasPassword
163
+ />
164
+ );
165
+
166
+ getByLabelText(`edit ${attribute}`).click();
167
+
168
+ expect(getByLabelText(`show-password ${attribute}`)).toHaveAttribute(
169
+ 'disabled',
170
+ ''
171
+ );
172
+
173
+ const newPassword = 'New Password';
174
+ fireEvent.change(getByLabelText(`${attribute} text input`), {
175
+ target: { value: newPassword },
176
+ });
177
+ expect(getByLabelText(`${attribute} text input`)).toHaveAttribute(
178
+ 'type',
179
+ 'password'
180
+ );
181
+
182
+ getByLabelText(`show-password ${attribute}`).click();
183
+ expect(getByLabelText(`${attribute} text input`)).toHaveAttribute(
184
+ 'type',
185
+ 'text'
186
+ );
187
+
188
+ getByLabelText(`show-password ${attribute}`).click();
189
+ expect(getByLabelText(`${attribute} text input`)).toHaveAttribute(
190
+ 'type',
191
+ 'password'
192
+ );
193
+ });
@@ -0,0 +1,38 @@
1
+ /* Credits: https://github.com/Katello/katello/blob/631d5bb83dc5d87320ee9002a6de33809a281b3e/webpack/components/EditableTextInput/editableTextInput.scss */
2
+ @import '~@theforeman/vendor/scss/variables';
3
+
4
+ .foreman-limited-text {
5
+ max-width: 200px;
6
+ margin: auto 0px;
7
+ }
8
+
9
+ .foreman-limited-editable-text {
10
+ max-width: 300px;
11
+ margin: auto 0px;
12
+ }
13
+
14
+ // Edit icon isn't in line with text
15
+ .foreman-edit-icon {
16
+ padding-top: 2px;
17
+ }
18
+
19
+ .textInput-placeholder, .textArea-placeholder {
20
+ color: var(--pf-global--disabled-color--100);
21
+ }
22
+
23
+ textarea.pf-c-form-control {
24
+ width: 215px;
25
+ }
26
+
27
+ .pf-c-form-control:not(textarea) {
28
+ width: 215px;
29
+ }
30
+
31
+ p {
32
+ width: 215px;
33
+ }
34
+
35
+ p.textArea-placeholder, p.textArea-value {
36
+ width: 215px;
37
+ height: 50px;
38
+ }
@@ -0,0 +1,4 @@
1
+ /* Credits: https://github.com/Katello/katello/blob/631d5bb83dc5d87320ee9002a6de33809a281b3e/webpack/components/EditableTextInput/index.js */
2
+ import EditableTextInput from './EditableTextInput';
3
+
4
+ export default EditableTextInput;
@@ -0,0 +1,80 @@
1
+ /* Credits: https://github.com/Katello/katello/blob/631d5bb83dc5d87320ee9002a6de33809a281b3e/webpack/test-utils/react-testing-lib-wrapper.js#L4 */
2
+ // For react-testing-library helpers, overrides, and utilities
3
+ // All elements from react-testing-library can be imported from this wrapper.
4
+ // See https://testing-library.com/docs/react-testing-library/setup for more info
5
+ import React from 'react';
6
+ import thunk from 'redux-thunk';
7
+ import Immutable from 'seamless-immutable';
8
+ import { APIMiddleware, reducers as apiReducer } from 'foremanReact/redux/API';
9
+ import { reducers as fillReducers } from 'foremanReact/components/common/Fill';
10
+ import { reducers as foremanModalReducer } from 'foremanReact/components/ForemanModal';
11
+ import { STATUS } from 'foremanReact/constants';
12
+ import {
13
+ render,
14
+ waitFor,
15
+ waitForElementToBeRemoved,
16
+ } from '@testing-library/react';
17
+ import { createStore, applyMiddleware, combineReducers } from 'redux';
18
+ import { Provider } from 'react-redux';
19
+ import { MemoryRouter, BrowserRouter } from 'react-router-dom';
20
+
21
+ // r-t-lib's print limit for debug() is quite small, setting it to a much higher char max here.
22
+ // See https://github.com/testing-library/react-testing-library/issues/503 for more info.
23
+ process.env.DEBUG_PRINT_LIMIT = 99999;
24
+
25
+ // Renders testable component with redux and react-router according to Katello's usage
26
+ // This should be used when you want a fully connected component with Redux state and actions.
27
+ function renderWithRedux(
28
+ component,
29
+ {
30
+ apiNamespace, // namespace if using API middleware
31
+ initialApiState = { response: {}, status: STATUS.PENDING }, // Default state for API middleware
32
+ initialState = {}, // Override full state
33
+ routerParams = {},
34
+ } = {}
35
+ ) {
36
+ // Adding the reducer in the expected namespaced format
37
+ const combinedReducers = combineReducers({
38
+ ...apiReducer,
39
+ ...foremanModalReducer,
40
+ ...fillReducers,
41
+ });
42
+
43
+ // Namespacing the initial state as well
44
+ const initialFullState = Immutable({
45
+ API: {
46
+ [apiNamespace]: initialApiState,
47
+ },
48
+ extendable: {},
49
+ ...initialState,
50
+ });
51
+ const middlewares = applyMiddleware(thunk, APIMiddleware);
52
+ const store = createStore(combinedReducers, initialFullState, middlewares);
53
+ const connectedComponent = (
54
+ <Provider store={store}>
55
+ <MemoryRouter {...routerParams}>{component}</MemoryRouter>
56
+ </Provider>
57
+ );
58
+
59
+ return { ...render(connectedComponent), store };
60
+ }
61
+
62
+ // When you actually need to change browser history
63
+ const renderWithRouter = (ui, { route = '/' } = {}) => {
64
+ window.history.pushState({}, 'Test page', route);
65
+
66
+ return render(ui, { wrapper: BrowserRouter });
67
+ };
68
+
69
+ // When the tests run slower, they can hit the default waitFor timeout, which is 1000ms
70
+ // There doesn't seem to be a way to set it globally for r-t-lib, so using this wrapper function
71
+ const rtlTimeout = 5000;
72
+ export const patientlyWaitFor = waitForFunc =>
73
+ waitFor(waitForFunc, { timeout: rtlTimeout });
74
+ export const patientlyWaitForRemoval = waitForFunc =>
75
+ waitForElementToBeRemoved(waitForFunc, { timeout: rtlTimeout });
76
+
77
+ // re-export everything, so the library can be used from this wrapper.
78
+ export * from '@testing-library/react';
79
+
80
+ export { renderWithRedux, renderWithRouter };
@@ -0,0 +1,17 @@
1
+ import 'core-js/shim';
2
+ import 'regenerator-runtime/runtime';
3
+ import MutationObserver from '@sheerun/mutationobserver-shim';
4
+
5
+ import { configure } from 'enzyme';
6
+ import Adapter from 'enzyme-adapter-react-16';
7
+
8
+ configure({ adapter: new Adapter() });
9
+
10
+ // Mocking translation function
11
+ global.__ = text => text; // eslint-disable-line
12
+
13
+ // Mocking locales to prevent unnecessary fallback messages
14
+ window.locales = { en: { domain: 'app', locale_data: { app: { '': {} } } } };
15
+
16
+ // see https://github.com/testing-library/dom-testing-library/releases/tag/v7.0.0
17
+ window.MutationObserver = MutationObserver;
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: foreman_resource_quota
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Bastian Schmidt
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-04-17 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Foreman Plug-in to manage resource usage among users.
14
+ email:
15
+ - schmidt@atix.de
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - LICENSE
21
+ - README.md
22
+ - Rakefile
23
+ - app/controllers/concerns/foreman/controller/parameters/resource_quota.rb
24
+ - app/controllers/foreman_resource_quota/api/v2/resource_quotas_controller.rb
25
+ - app/controllers/foreman_resource_quota/application_controller.rb
26
+ - app/controllers/foreman_resource_quota/resource_quotas_controller.rb
27
+ - app/helpers/foreman_resource_quota/hosts_helper.rb
28
+ - app/helpers/foreman_resource_quota/resource_quota_helper.rb
29
+ - app/models/concerns/foreman_resource_quota/host_managed_extensions.rb
30
+ - app/models/concerns/foreman_resource_quota/user_extensions.rb
31
+ - app/models/concerns/foreman_resource_quota/usergroup_extensions.rb
32
+ - app/models/foreman_resource_quota/resource_quota.rb
33
+ - app/models/foreman_resource_quota/resource_quota_user.rb
34
+ - app/models/foreman_resource_quota/resource_quota_usergroup.rb
35
+ - app/services/foreman_resource_quota/resource_origin.rb
36
+ - app/services/foreman_resource_quota/resource_origins/compute_attributes_origin.rb
37
+ - app/services/foreman_resource_quota/resource_origins/compute_resource_origin.rb
38
+ - app/services/foreman_resource_quota/resource_origins/facts_origin.rb
39
+ - app/services/foreman_resource_quota/resource_origins/vm_attributes_origin.rb
40
+ - app/views/foreman_resource_quota/api/v2/hosts/resource_quota.json.rabl
41
+ - app/views/foreman_resource_quota/api/v2/resource_quotas/base.json.rabl
42
+ - app/views/foreman_resource_quota/api/v2/resource_quotas/create.json.rabl
43
+ - app/views/foreman_resource_quota/api/v2/resource_quotas/hosts.json.rabl
44
+ - app/views/foreman_resource_quota/api/v2/resource_quotas/index.json.rabl
45
+ - app/views/foreman_resource_quota/api/v2/resource_quotas/main.json.rabl
46
+ - app/views/foreman_resource_quota/api/v2/resource_quotas/show.json.rabl
47
+ - app/views/foreman_resource_quota/api/v2/resource_quotas/update.json.rabl
48
+ - app/views/foreman_resource_quota/api/v2/resource_quotas/usergroups.json.rabl
49
+ - app/views/foreman_resource_quota/api/v2/resource_quotas/users.json.rabl
50
+ - app/views/foreman_resource_quota/api/v2/resource_quotas/utilization.json.rabl
51
+ - app/views/foreman_resource_quota/api/v2/usergroups/resource_quota.json.rabl
52
+ - app/views/foreman_resource_quota/api/v2/users/resource_quota.json.rabl
53
+ - app/views/foreman_resource_quota/resource_quotas/_form.html.erb
54
+ - app/views/foreman_resource_quota/resource_quotas/edit.html.erb
55
+ - app/views/foreman_resource_quota/resource_quotas/index.html.erb
56
+ - app/views/foreman_resource_quota/resource_quotas/new.html.erb
57
+ - app/views/foreman_resource_quota/resource_quotas/welcome.html.erb
58
+ - app/views/hosts/_form_quota_fields.html.erb
59
+ - app/views/users/_form_quota_tab.html.erb
60
+ - config/initializers/inflections.rb
61
+ - config/routes.rb
62
+ - db/migrate/20230306120001_create_resource_quotas.rb
63
+ - lib/foreman_resource_quota.rb
64
+ - lib/foreman_resource_quota/engine.rb
65
+ - lib/foreman_resource_quota/exceptions.rb
66
+ - lib/foreman_resource_quota/register.rb
67
+ - lib/foreman_resource_quota/version.rb
68
+ - lib/tasks/foreman_resource_quota_tasks.rake
69
+ - locale/Makefile
70
+ - locale/en/foreman_resource_quota.po
71
+ - locale/foreman_resource_quota.pot
72
+ - locale/gemspec.rb
73
+ - package.json
74
+ - webpack/api_helper.js
75
+ - webpack/api_helper.test.js
76
+ - webpack/components/CreateResourceQuotaModal.js
77
+ - webpack/components/ResourceQuotaEmptyState/index.js
78
+ - webpack/components/ResourceQuotaForm/ResourceQuotaForm.scss
79
+ - webpack/components/ResourceQuotaForm/ResourceQuotaFormConstants.js
80
+ - webpack/components/ResourceQuotaForm/components/Properties/Properties.scss
81
+ - webpack/components/ResourceQuotaForm/components/Properties/StaticDetail.js
82
+ - webpack/components/ResourceQuotaForm/components/Properties/StatusPropertiesLabel.js
83
+ - webpack/components/ResourceQuotaForm/components/Properties/StatusPropertiesLabel.test.js
84
+ - webpack/components/ResourceQuotaForm/components/Properties/TextInputField.js
85
+ - webpack/components/ResourceQuotaForm/components/Properties/index.js
86
+ - webpack/components/ResourceQuotaForm/components/QuotaState.js
87
+ - webpack/components/ResourceQuotaForm/components/Resource/Resource.scss
88
+ - webpack/components/ResourceQuotaForm/components/Resource/UnitInputField.js
89
+ - webpack/components/ResourceQuotaForm/components/Resource/UtilizationProgress.js
90
+ - webpack/components/ResourceQuotaForm/components/Resource/UtilizationProgress.scss
91
+ - webpack/components/ResourceQuotaForm/components/Resource/index.js
92
+ - webpack/components/ResourceQuotaForm/components/Resources.js
93
+ - webpack/components/ResourceQuotaForm/components/Submit.js
94
+ - webpack/components/ResourceQuotaForm/index.js
95
+ - webpack/components/UpdateResourceQuotaModal.js
96
+ - webpack/global_index.js
97
+ - webpack/global_test_setup.js
98
+ - webpack/helper.js
99
+ - webpack/index.js
100
+ - webpack/lib/ActionableDetail.js
101
+ - webpack/lib/ActionableDetail.scss
102
+ - webpack/lib/EditableSwitch.js
103
+ - webpack/lib/EditableTextInput/EditableTextInput.js
104
+ - webpack/lib/EditableTextInput/PencilEditButton.js
105
+ - webpack/lib/EditableTextInput/__tests__/editableTextInput.test.js
106
+ - webpack/lib/EditableTextInput/editableTextInput.scss
107
+ - webpack/lib/EditableTextInput/index.js
108
+ - webpack/lib/react-testing-lib-wrapper.js
109
+ - webpack/test_setup.js
110
+ homepage: https://github.com/ATIX-AG/foreman_resource_quota
111
+ licenses:
112
+ - GPL-3.0
113
+ metadata:
114
+ is_foreman_plugin: 'true'
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubygems_version: 3.3.26
131
+ signing_key:
132
+ specification_version: 4
133
+ summary: Foreman Plug-in for resource quota
134
+ test_files: []