foreman_templates 9.0.2 → 9.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/template_controller.rb +3 -3
  3. data/app/controllers/ui_template_syncs_controller.rb +8 -2
  4. data/app/services/foreman_templates/template_exporter.rb +1 -1
  5. data/app/services/foreman_templates/template_importer.rb +1 -1
  6. data/app/views/template_sync_settings/show.json.rabl +2 -2
  7. data/app/views/ui_template_syncs/template_attrs.json.rabl +1 -1
  8. data/db/migrate/20211122154929_templates_settings_category_to_dsl.rb +5 -0
  9. data/lib/foreman_templates/engine.rb +76 -10
  10. data/lib/foreman_templates/version.rb +1 -1
  11. data/lib/foreman_templates.rb +15 -0
  12. data/lib/tasks/foreman_templates_tasks.rake +10 -9
  13. data/package.json +10 -36
  14. data/webpack/__mocks__/foremanReact/Root/Context/ForemanContext.js +2 -0
  15. data/webpack/__mocks__/foremanReact/common/I18n.js +1 -0
  16. data/webpack/__mocks__/foremanReact/components/Pagination/index.js +2 -0
  17. data/webpack/__tests__/helpers.test.js +1 -1
  18. data/webpack/components/NewTemplateSync/NewTemplateSync.js +2 -1
  19. data/webpack/components/NewTemplateSync/__tests__/NewTemplateSync.test.js +1 -1
  20. data/webpack/components/NewTemplateSync/__tests__/NewTemplateSyncReducer.test.js +1 -1
  21. data/webpack/components/NewTemplateSync/__tests__/NewTemplateSyncSelectors.test.js +1 -1
  22. data/webpack/components/NewTemplateSync/components/ButtonTooltip.js +8 -14
  23. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncForm.js +95 -140
  24. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncFormHelpers.js +43 -0
  25. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/NewTemplateSyncFormSelectors.test.js +1 -1
  26. data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/index.js +0 -4
  27. data/webpack/components/NewTemplateSync/components/__tests__/SyncSettingField.test.js +1 -1
  28. data/webpack/components/NewTemplateSync/components/__tests__/SyncSettingFields.test.js +1 -1
  29. data/webpack/components/NewTemplateSync/components/__tests__/SyncTypeRadios.test.js +1 -1
  30. data/webpack/components/NewTemplateSync/components/__tests__/TextButtonField.test.js +1 -1
  31. data/webpack/components/PageNotFound.js +1 -0
  32. data/webpack/components/PermissionDenied.js +1 -0
  33. data/webpack/components/TemplateSyncResult/TemplateSyncResultHelpers.js +2 -2
  34. data/webpack/components/TemplateSyncResult/TemplateSyncResultReducer.js +1 -1
  35. data/webpack/components/TemplateSyncResult/__tests__/TemplateSyncResult.test.js +1 -1
  36. data/webpack/components/TemplateSyncResult/__tests__/TemplateSyncResultReducer.test.js +1 -1
  37. data/webpack/components/TemplateSyncResult/__tests__/__snapshots__/TemplateSyncResultReducer.test.js.snap +2 -2
  38. data/webpack/components/TemplateSyncResult/components/FinishedSyncResult.js +3 -2
  39. data/webpack/components/TemplateSyncResult/components/SyncResultList.js +11 -6
  40. data/webpack/components/TemplateSyncResult/components/SyncedTemplate/InfoItem.js +4 -8
  41. data/webpack/components/TemplateSyncResult/components/SyncedTemplate/StringInfoItem.js +1 -0
  42. data/webpack/components/TemplateSyncResult/components/SyncedTemplate/helpers.test.js +1 -1
  43. data/webpack/components/TemplateSyncResult/components/__tests__/SyncResultList.test.js +2 -2
  44. data/webpack/components/TemplateSyncResult/components/__tests__/SyncedTemplate.test.js +1 -1
  45. data/webpack/components/TemplateSyncResult/components/__tests__/__snapshots__/SyncResultList.test.js.snap +3 -9
  46. data/webpack/testSetup.js +1 -1
  47. metadata +7 -4
  48. data/app/models/setting/template_sync.rb +0 -115
  49. data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f43c3bbc33be62b6f39ce0abfaa0475f9635d2230f4a7f6bb551e66cf7f7fb0b
4
- data.tar.gz: 3fdf3c192b4e639bc0fdc0a98deef65f344e1be65853dbeebb876bde4592405c
3
+ metadata.gz: a528443c31169fe8bdf3631f0ba104c529f96d65e4b68fada26806ed7d1126b3
4
+ data.tar.gz: 0e0a5123832218f392d3b7bb6a7d52d0e06e0301c3861039ca6a6e48159141fe
5
5
  SHA512:
6
- metadata.gz: 20d726f2cb66074badb1779ad8b49613ad0f2e899fd3d8db9559a9590cec9224f98d7b2828072b4dd046cf053b5799a7cfcfeafb99723efa867cb9625ac33aa9
7
- data.tar.gz: 2a2e07c0374ce30e0ecf900262f41e33d16f0a5a494841e5a00eaf3c5c00cbec90df3cd6d785cc68c99916783245f640af3628b7d47cc365bbf8a659416643ba
6
+ metadata.gz: 208c6cbdfb4cc6f368c0efb9a37356f9779423e82d037ceaaf2d79d09d04f98b2171304ba28d462f6619e28f70d6d08d5168c26d6a4b155248ed8a9b94247904
7
+ data.tar.gz: e461eacbd51608bf69fc56fd113cae87bbb26d402311585de7738c1afaaf1f8fc9e254e62210f60e05799f3eacb0c4aa961ad4bce0c65eca5e3094c40cfb3d68
@@ -17,9 +17,9 @@ module Api
17
17
 
18
18
  api :POST, "/templates/import/", N_("Initiate Import")
19
19
  param :prefix, String, :required => false, :desc => N_("The string all imported templates should begin with.")
20
- param :associate, Setting::TemplateSync.associate_types.keys, :required => false, :desc => N_("Associate to OS's, Locations & Organizations. Options are: always, new or never.")
20
+ param :associate, ForemanTemplates.associate_types.keys, :required => false, :desc => N_("Associate to OS's, Locations & Organizations. Options are: always, new or never.")
21
21
  param :force, :bool, :required => false, :desc => N_("Update templates that are locked")
22
- param :lock, Setting::TemplateSync.lock_types.keys + ["true", "false", "0", "1"], :required => false, :desc => N_("Lock imported templates")
22
+ param :lock, ForemanTemplates.lock_types.keys + ["true", "false", "0", "1"], :required => false, :desc => N_("Lock imported templates")
23
23
  param :verbose, :bool, :required => false, :desc => N_("Show template diff in response")
24
24
  param_group :foreman_template_sync_params
25
25
  param_group :taxonomies, ::Api::V2::BaseController
@@ -32,7 +32,7 @@ module Api
32
32
  end
33
33
 
34
34
  api :POST, "/templates/export", N_("Initiate Export")
35
- param :metadata_export_mode, Setting::TemplateSync.metadata_export_mode_types.keys, :required => false, :desc => N_("Specify how to handle metadata")
35
+ param :metadata_export_mode, ForemanTemplates.metadata_export_mode_types.keys, :required => false, :desc => N_("Specify how to handle metadata")
36
36
  param :commit_msg, String, :desc => N_("Custom commit message for templates export")
37
37
  param_group :foreman_template_sync_params
38
38
  param_group :taxonomies, ::Api::V2::BaseController
@@ -8,8 +8,8 @@ class UiTemplateSyncsController < ApplicationController
8
8
  end
9
9
 
10
10
  def sync_settings
11
- import_settings = Setting.where :name => Setting::TemplateSync.import_setting_names(['verbose'])
12
- export_settings = Setting.where :name => Setting::TemplateSync.export_setting_names(['verbose'])
11
+ import_settings = setting_definitions(ForemanTemplates::IMPORT_SETTING_NAMES)
12
+ export_settings = setting_definitions(ForemanTemplates::EXPORT_SETTING_NAMES)
13
13
  @results = OpenStruct.new(:import => import_settings, :export => export_settings)
14
14
  end
15
15
 
@@ -45,4 +45,10 @@ class UiTemplateSyncsController < ApplicationController
45
45
  def render_errors(messages, severity = 'danger')
46
46
  render :json => { :error => { :errors => { :base => messages }, full_messages: messages, :severity => severity } }, :status => :unprocessable_entity
47
47
  end
48
+
49
+ private
50
+
51
+ def setting_definitions(short_names)
52
+ short_names.map { |name| Foreman.settings.find("template_sync_#{name}") }
53
+ end
48
54
  end
@@ -94,7 +94,7 @@ module ForemanTemplates
94
94
  def templates_to_dump
95
95
  find_templates.each do |template|
96
96
  if filter.present?
97
- exportable = template.name =~ /#{filter}/i ? !negate : negate
97
+ exportable = /#{filter}/i.match?(template.name) ? !negate : negate
98
98
  result = ExportResult.new(template, exportable)
99
99
  next @result_lines << result.matching_filter unless exportable
100
100
 
@@ -70,7 +70,7 @@ module ForemanTemplates
70
70
  @result_lines << parse_result.check_for_errors
71
71
  rescue NameError => e
72
72
  @result_lines << parse_result.name_error(e, metadata['model'])
73
- rescue => e
73
+ rescue StandardError => e
74
74
  @result_lines << parse_result.add_exception(e)
75
75
  end
76
76
  end
@@ -1,11 +1,11 @@
1
1
  object @setting
2
2
 
3
3
  node do |setting|
4
- { :name => setting.short_name }
4
+ { :name => setting.name.delete_prefix('template_sync_') }
5
5
  end
6
6
 
7
7
  attributes :id, :value, :description, :settings_type, :default, :full_name
8
8
 
9
9
  node do |setting|
10
- { :selection => setting.selection }
10
+ { :selection => (setting.select_values || {}).map { |key, label| { value: key, label: label } } }
11
11
  end
@@ -11,7 +11,7 @@ node(:class_name) do |template|
11
11
  end
12
12
 
13
13
  node(:humanized_class_name) do |template|
14
- template.class.name.underscore.split('_').map { |part| part.capitalize }.join(' ')
14
+ template.class.name.underscore.split('_').map(&:capitalize).join(' ')
15
15
  end
16
16
 
17
17
  node(:can_edit) do |template|
@@ -0,0 +1,5 @@
1
+ class TemplatesSettingsCategoryToDsl < ActiveRecord::Migration[6.0]
2
+ def up
3
+ Setting.where(category: 'Setting::TemplateSync').update_all(category: 'Setting')
4
+ end
5
+ end
@@ -10,10 +10,6 @@ module ForemanTemplates
10
10
  class Engine < ::Rails::Engine
11
11
  engine_name 'foreman_templates'
12
12
 
13
- initializer 'foreman_templates.load_default_settings', :before => :load_config_initializers do
14
- require_dependency File.expand_path('../../app/models/setting/template_sync.rb', __dir__) if (Setting.table_exists? rescue(false))
15
- end
16
-
17
13
  initializer "foreman_templates.add_rabl_view_path" do
18
14
  Rabl.configure do |config|
19
15
  config.view_paths << ForemanTemplates::Engine.root.join('app', 'views')
@@ -28,10 +24,78 @@ module ForemanTemplates
28
24
 
29
25
  initializer 'foreman_templates.register_plugin', :before => :finisher_hook do
30
26
  Foreman::Plugin.register :foreman_templates do
31
- requires_foreman '>= 1.24'
27
+ requires_foreman '>= 3.3'
32
28
 
33
29
  apipie_documented_controllers ["#{ForemanTemplates::Engine.root}/app/controllers/api/v2/*.rb"]
34
30
 
31
+ settings do
32
+ category(:template_sync, N_('Template Sync')) do
33
+ setting('template_sync_verbose',
34
+ type: :boolean,
35
+ description: N_('Choose verbosity for Rake task importing templates'),
36
+ default: false,
37
+ full_name: N_('Verbosity'))
38
+ setting('template_sync_associate',
39
+ type: :string,
40
+ description: N_('Associate templates to OS, organization and location'),
41
+ default: 'new',
42
+ full_name: N_('Associate'),
43
+ collection: -> { ForemanTemplates.associate_types })
44
+ setting('template_sync_prefix',
45
+ type: :string,
46
+ description: N_('The string that will be added as prefix to imported templates'),
47
+ default: "",
48
+ full_name: N_('Prefix'))
49
+ setting('template_sync_dirname',
50
+ type: :string,
51
+ description: N_('The directory within the Git repo containing the templates'),
52
+ default: '/',
53
+ full_name: N_('Dirname'))
54
+ setting('template_sync_filter',
55
+ type: :string,
56
+ description: N_('Import/export names matching this regex (case-insensitive; snippets are not filtered)'),
57
+ default: '',
58
+ full_name: N_('Filter'))
59
+ setting('template_sync_repo',
60
+ type: :string,
61
+ description: N_('Target path to import/export. Different protocols can be used, for example /tmp/dir, git://example.com, https://example.com, ssh://example.com. When exporting to /tmp, note that production deployments may be configured to use private tmp.'),
62
+ default: 'https://github.com/theforeman/community-templates.git',
63
+ full_name: N_('Repo'))
64
+ setting('template_sync_negate',
65
+ type: :boolean,
66
+ description: N_('Negate the filter for import/export'),
67
+ default: false,
68
+ full_name: N_('Negate'))
69
+ setting('template_sync_branch',
70
+ type: :string,
71
+ description: N_('Default branch in Git repo'),
72
+ default: '',
73
+ full_name: N_('Branch'))
74
+ setting('template_sync_metadata_export_mode',
75
+ type: :string,
76
+ description: N_('Default metadata export mode, refresh re-renders metadata, keep will keep existing metadata, remove exports template without metadata'),
77
+ default: 'refresh',
78
+ full_name: N_('Metadata export mode'),
79
+ collection: -> { ForemanTemplates.metadata_export_mode_types })
80
+ setting('template_sync_force',
81
+ type: :boolean,
82
+ description: N_('Should importing overwrite locked templates?'),
83
+ default: false,
84
+ full_name: N_('Force import'))
85
+ setting('template_sync_lock',
86
+ type: :string,
87
+ description: N_('How to handle lock for imported templates?'),
88
+ default: 'keep',
89
+ full_name: N_('Lock templates'),
90
+ collection: -> { ForemanTemplates.lock_types })
91
+ setting('template_sync_commit_msg',
92
+ type: :string,
93
+ description: N_('Custom commit message for templates export'),
94
+ default: 'Templates export made by a Foreman user',
95
+ full_name: N_('Commit message'))
96
+ end
97
+ end
98
+
35
99
  security_block :templates do
36
100
  permission :import_templates, {
37
101
  :"api/v2/template" => [:import],
@@ -49,15 +113,17 @@ module ForemanTemplates
49
113
  add_all_permissions_to_default_roles
50
114
 
51
115
  menu :top_menu, :template_sync,
52
- :url_hash => { :controller => :template_syncs, :action => :index },
53
- :caption => N_('Sync Templates'),
54
- :parent => :hosts_menu,
55
- :before => :ptables,
56
- :turbolinks => false
116
+ :url_hash => { :controller => :template_syncs, :action => :index },
117
+ :caption => N_('Sync Templates'),
118
+ :parent => :hosts_menu,
119
+ :before => :ptables,
120
+ :turbolinks => false
57
121
  end
58
122
  end
59
123
 
60
124
  config.to_prepare do
125
+ Setting::NOT_STRIPPED << 'template_sync_prefix'
126
+
61
127
  Template.include ForemanTemplates::TemplateExtensions
62
128
  end
63
129
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanTemplates
2
- VERSION = '9.0.2'.freeze
2
+ VERSION = '9.3.0'.freeze
3
3
  end
@@ -1,4 +1,19 @@
1
1
  require 'foreman_templates/engine'
2
2
 
3
3
  module ForemanTemplates
4
+ BASE_SETTING_NAMES = %w(repo branch dirname filter negate).freeze
5
+ IMPORT_SETTING_NAMES = (BASE_SETTING_NAMES | %w(prefix associate force lock)).freeze
6
+ EXPORT_SETTING_NAMES = (BASE_SETTING_NAMES | %w(metadata_export_mode commit_msg)).freeze
7
+
8
+ def self.associate_types
9
+ { 'always' => _('Always'), 'new' => _('New'), 'never' => _('Never') }
10
+ end
11
+
12
+ def self.lock_types
13
+ { 'lock' => _('Lock'), 'keep_lock_new' => _('Keep, lock new'), 'keep' => _('Keep, do not lock new'), 'unlock' => _('Unlock') }
14
+ end
15
+
16
+ def self.metadata_export_mode_types
17
+ { 'refresh' => _('Refresh'), 'keep' => _('Keep'), 'remove' => _('Remove') }
18
+ end
4
19
  end
@@ -20,14 +20,14 @@ namespace :templates do
20
20
  verbose = ENV['verbose']
21
21
 
22
22
  results = ForemanTemplates::TemplateImporter.new({
23
- verbose: verbose,
24
- repo: ENV['repo'],
25
- branch: ENV['branch'],
26
- prefix: ENV['prefix'],
27
- dirname: ENV['dirname'],
28
- filter: ENV['filter'],
23
+ verbose: verbose,
24
+ repo: ENV['repo'],
25
+ branch: ENV['branch'],
26
+ prefix: ENV['prefix'],
27
+ dirname: ENV['dirname'],
28
+ filter: ENV['filter'],
29
29
  associate: ENV['associate'],
30
- lock: ENV['lock'],
30
+ lock: ENV['lock'],
31
31
  }).import!
32
32
  pp(results[:results].map { |result| result.to_h(verbose) })
33
33
  end
@@ -58,8 +58,8 @@ namespace :templates do
58
58
  # * negate => negate query [false]
59
59
  # * prefix => The string all templates to purge should ( or not ) begin with [Community ]
60
60
  # * verbose => Print extra information during the run [false]
61
- negate: ENV['negate'],
62
- prefix: ENV['prefix'],
61
+ negate: ENV['negate'],
62
+ prefix: ENV['prefix'],
63
63
  verbose: ENV['verbose'],
64
64
  }).purge!
65
65
  end
@@ -89,6 +89,7 @@ namespace :foreman_templates do
89
89
  begin
90
90
  require 'rubocop/rake_task'
91
91
  RuboCop::RakeTask.new(:rubocop_foreman_templates) do |task|
92
+ task.options = ['--config', ForemanTemplates::Engine.root.join('.rubocop.yml').to_s]
92
93
  task.patterns = ["#{ForemanTemplates::Engine.root}/app/**/*.rb",
93
94
  "#{ForemanTemplates::Engine.root}/lib/**/*.rb",
94
95
  "#{ForemanTemplates::Engine.root}/test/**/*.rb"]
data/package.json CHANGED
@@ -7,8 +7,8 @@
7
7
  "test": "test"
8
8
  },
9
9
  "scripts": {
10
- "test": "node node_modules/.bin/jest webpack",
11
- "lint": "./node_modules/.bin/eslint -c .eslintrc webpack/"
10
+ "test": "tfm-test --plugin",
11
+ "lint": "tfm-lint --plugin -d /webpack"
12
12
  },
13
13
  "repository": {
14
14
  "type": "git",
@@ -21,45 +21,19 @@
21
21
  },
22
22
  "homepage": "https://github.com/theforeman/foreman_templates",
23
23
  "peerDependencies": {
24
- "@theforeman/vendor": ">= 3.3.2"
24
+ "@theforeman/vendor": "^10.1.0"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@babel/core": "^7.7.0",
28
- "@theforeman/env": "^3.3.2",
29
- "@theforeman/builder": "^4.0.2",
30
- "@theforeman/vendor-dev": "^3.3.2",
28
+ "@theforeman/builder": "^10.1.0",
29
+ "@theforeman/eslint-plugin-foreman": "^10.1.0",
30
+ "@theforeman/vendor-dev": "^10.1.0",
31
+ "@theforeman/test": "^10.1.0",
32
+ "@theforeman/stories": "^10.1.0",
31
33
  "babel-eslint": "^10.0.0",
32
- "babel-jest": "^24.9.0",
33
- "enzyme": "^3.7.0",
34
- "enzyme-adapter-react-16": "^1.7.0",
35
- "enzyme-to-json": "^3.3.5",
36
34
  "eslint": "^6.8.0",
37
- "eslint-plugin-patternfly-react": "^0.3.0",
35
+ "eslint-plugin-patternfly-react": "0.2.0",
38
36
  "identity-obj-proxy": "^3.0.0",
39
- "jest": "^24.9.0",
40
- "prettier": "^1.19.1",
41
- "react-redux-test-utils": "^0.1.1"
42
- },
43
- "jest": {
44
- "verbose": true,
45
- "moduleDirectories": [
46
- "node_modules/@theforeman/vendor-core/node_modules",
47
- "node_modules",
48
- "webpack"
49
- ],
50
- "transform": {
51
- "^.+\\.js$": "babel-jest"
52
- },
53
- "setupFiles": [
54
- "raf/polyfill",
55
- "./webpack/testSetup.js"
56
- ],
57
- "testPathIgnorePatterns": [
58
- "/node_modules/",
59
- "<rootDir>/foreman/"
60
- ],
61
- "moduleNameMapper": {
62
- "^.+\\.(css|scss)$": "identity-obj-proxy"
63
- }
37
+ "prettier": "^1.19.1"
64
38
  }
65
39
  }
@@ -0,0 +1,2 @@
1
+ export const useForemanOrganization = () => {};
2
+ export const useForemanLocation = () => {};
@@ -0,0 +1 @@
1
+ export const translate = s => s;
@@ -0,0 +1,2 @@
1
+ const Pagination = () => jest.fn();
2
+ export default Pagination;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { testSelectorsSnapshotWithFixtures } from 'react-redux-test-utils';
2
+ import { testSelectorsSnapshotWithFixtures } from '@theforeman/test';
3
3
  import withProtectedView from '../withProtectedView';
4
4
 
5
5
  const ProtectedComponent = () => <div>Protected component</div>;
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import { LoadingState } from 'patternfly-react';
3
- import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
4
3
  import PropTypes from 'prop-types';
4
+ import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
5
+ import { translate as __ } from 'foremanReact/common/I18n';
5
6
 
6
7
  import NewTemplateSyncForm from './components/NewTemplateSyncForm';
7
8
  import './NewTemplateSync.scss';
@@ -1,4 +1,4 @@
1
- import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import NewTemplateSync from '../NewTemplateSync';
4
4
 
@@ -1,4 +1,4 @@
1
- import { testReducerSnapshotWithFixtures } from 'react-redux-test-utils';
1
+ import { testReducerSnapshotWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import reducer, { initialState } from '../NewTemplateSyncReducer';
4
4
 
@@ -1,4 +1,4 @@
1
- import { testSelectorsSnapshotWithFixtures } from 'react-redux-test-utils';
1
+ import { testSelectorsSnapshotWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import {
4
4
  importSettings,
@@ -1,20 +1,14 @@
1
1
  import React from 'react';
2
- import { Tooltip, Icon, OverlayTrigger } from 'patternfly-react';
2
+ import { Tooltip } from '@patternfly/react-core';
3
+ import { RedoIcon } from '@patternfly/react-icons';
3
4
  import PropTypes from 'prop-types';
5
+ import { translate as __ } from 'foremanReact/common/I18n';
4
6
 
5
- const ButtonTooltip = props => {
6
- const tooltip = (
7
- <Tooltip id={`${props.tooltipId}-tooltip-id`}>
8
- <span>Use default value from settings</span>
9
- </Tooltip>
10
- );
11
-
12
- return (
13
- <OverlayTrigger overlay={tooltip} trigger={['hover', 'focus']}>
14
- <Icon type="fa" name="refresh" />
15
- </OverlayTrigger>
16
- );
17
- };
7
+ const ButtonTooltip = ({ tooltipId }) => (
8
+ <Tooltip id={tooltipId} content={__('Use default value from settings')}>
9
+ <RedoIcon />
10
+ </Tooltip>
11
+ );
18
12
 
19
13
  ButtonTooltip.propTypes = {
20
14
  tooltipId: PropTypes.string.isRequired,
@@ -1,159 +1,116 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { compose } from 'redux';
4
4
 
5
5
  import ForemanForm from 'foremanReact/components/common/forms/ForemanForm';
6
- import * as Yup from 'yup';
6
+ import {
7
+ useForemanLocation,
8
+ useForemanOrganization,
9
+ } from 'foremanReact/Root/Context/ForemanContext';
10
+
7
11
  import SyncSettingsFields from '../SyncSettingFields';
8
12
  import SyncTypeRadios from '../SyncTypeRadios';
9
-
10
- const redirectToResult = history => () =>
11
- history.push({ pathname: '/template_syncs/result' });
12
-
13
- const repoFormat = formatAry => value => {
14
- if (value === undefined) {
15
- return true;
16
- }
17
-
18
- const valid = formatAry
19
- .map(item => value.startsWith(item))
20
- .reduce((memo, item) => item || memo, false);
21
-
22
- return value && valid;
23
- };
24
-
25
- const syncFormSchema = (syncType, settingsObj, validationData) => {
26
- const schema = (settingsObj[syncType].asMutable() || []).reduce(
27
- (memo, setting) => {
28
- if (setting.name === 'repo') {
29
- return {
30
- ...memo,
31
- repo: Yup.string()
32
- .test(
33
- 'repo-format',
34
- `Invalid repo format, must start with one of: ${validationData.repo.join(
35
- ', '
36
- )}`,
37
- repoFormat(validationData.repo)
38
- )
39
- .required("can't be blank"),
40
- };
41
- }
42
- return memo;
43
- },
44
- {}
13
+ import { redirectToResult, syncFormSchema } from './NewTemplateSyncFormHelpers';
14
+
15
+ const NewTemplateSyncForm = ({
16
+ error,
17
+ submitForm,
18
+ importSettings,
19
+ exportSettings,
20
+ history,
21
+ validationData,
22
+ importUrl,
23
+ exportUrl,
24
+ initialValues,
25
+ userPermissions,
26
+ }) => {
27
+ const allowedSyncType = (currentUserPermissions, radioAttrs) =>
28
+ currentUserPermissions[radioAttrs.permission];
29
+
30
+ const radioButtons = [
31
+ { label: 'Import', value: 'import', permission: 'import' },
32
+ { label: 'Export', value: 'export', permission: 'export' },
33
+ ];
34
+
35
+ const [syncType, setSyncType] = useState(
36
+ radioButtons.find(radioAttrs =>
37
+ allowedSyncType(userPermissions, radioAttrs)
38
+ ).value
45
39
  );
46
40
 
47
- return Yup.object().shape({
48
- [syncType]: Yup.object().shape(schema),
49
- });
50
- };
51
-
52
- class NewTemplateSyncForm extends React.Component {
53
- allowedSyncType = (userPermissions, radioAttrs) =>
54
- this.props.userPermissions[radioAttrs.permission];
55
-
56
- constructor(props) {
57
- super(props);
58
-
59
- this.radioButtons = [
60
- { label: 'Import', value: 'import', permission: 'import' },
61
- { label: 'Export', value: 'export', permission: 'export' },
62
- ];
63
-
64
- this.state = {
65
- syncType: this.radioButtons.find(radioAttrs =>
66
- this.allowedSyncType(props.userPermissions, radioAttrs)
67
- ).value,
68
- };
69
- }
70
-
71
- updateSyncType = event => {
72
- this.setState({ syncType: event.target.value });
41
+ const updateSyncType = event => {
42
+ setSyncType(event.target.value);
73
43
  };
74
44
 
75
- permitRadioButtons = buttons =>
45
+ const permitRadioButtons = buttons =>
76
46
  buttons.filter(buttonAttrs =>
77
- this.allowedSyncType(this.props.userPermissions, buttonAttrs)
47
+ allowedSyncType(userPermissions, buttonAttrs)
78
48
  );
79
49
 
80
- initRadioButtons = syncType =>
81
- this.permitRadioButtons(this.radioButtons).map(buttonAttrs => ({
50
+ const initRadioButtons = templateSyncType =>
51
+ permitRadioButtons(radioButtons).map(buttonAttrs => ({
82
52
  get checked() {
83
- return this.value === syncType;
53
+ return buttonAttrs.value === templateSyncType;
84
54
  },
85
- onChange: this.updateSyncType,
55
+ onChange: updateSyncType,
86
56
  ...buttonAttrs,
87
57
  }));
88
58
 
89
- render() {
90
- const {
91
- error,
92
- submitForm,
93
- importSettings,
94
- exportSettings,
95
- history,
96
- validationData,
97
- importUrl,
98
- exportUrl,
99
- initialValues,
100
- currentLocation,
101
- currentOrganization,
102
- } = this.props;
103
-
104
- const addTaxParams = (key, currentTax) => params => {
105
- if (currentTax && currentTax.id) {
106
- return { ...params, [key]: [currentTax.id] };
107
- }
108
- return params;
109
- };
110
-
111
- const addOrgParams = addTaxParams('organization_ids', currentOrganization);
112
- const addLocParams = addTaxParams('location_ids', currentLocation);
113
-
114
- const resetToDefault = (fieldName, fieldValue) => resetFn =>
115
- resetFn(fieldName, fieldValue);
116
-
117
- return (
118
- <ForemanForm
119
- onSubmit={(values, actions) => {
120
- const url = this.state.syncType === 'import' ? importUrl : exportUrl;
121
- return submitForm({
122
- url,
123
- values: compose(
124
- addLocParams,
125
- addOrgParams
126
- )(values[this.state.syncType]),
127
- message: `Templates were ${this.state.syncType}ed.`,
128
- item: 'TemplateSync',
129
- }).then(args => {
130
- history.replace({ pathname: '/template_syncs/result' });
131
- });
132
- }}
133
- initialValues={initialValues}
134
- validationSchema={syncFormSchema(
135
- this.state.syncType,
136
- { import: importSettings, export: exportSettings },
137
- validationData
138
- )}
139
- onCancel={redirectToResult(history)}
140
- error={error}
141
- >
142
- <SyncTypeRadios
143
- name="syncType"
144
- controlLabel="Action type"
145
- radios={this.initRadioButtons(this.state.syncType)}
146
- />
147
- <SyncSettingsFields
148
- importSettings={importSettings}
149
- exportSettings={exportSettings}
150
- syncType={this.state.syncType}
151
- resetField={resetToDefault}
152
- />
153
- </ForemanForm>
154
- );
155
- }
156
- }
59
+ const addTaxParams = (key, currentTax) => params => {
60
+ if (currentTax && currentTax.id) {
61
+ return { ...params, [key]: [currentTax.id] };
62
+ }
63
+ return params;
64
+ };
65
+
66
+ const addOrgParams = addTaxParams(
67
+ 'organization_ids',
68
+ useForemanOrganization()
69
+ );
70
+ const addLocParams = addTaxParams('location_ids', useForemanLocation());
71
+
72
+ const resetToDefault = (fieldName, fieldValue) => resetFn =>
73
+ resetFn(fieldName, fieldValue);
74
+
75
+ const handleSubmit = (values, actions) => {
76
+ const url = syncType === 'import' ? importUrl : exportUrl;
77
+ return submitForm({
78
+ url,
79
+ values: compose(addLocParams, addOrgParams)(values[syncType]),
80
+ message: `Templates were ${syncType}ed.`,
81
+ item: 'TemplateSync',
82
+ actions,
83
+ successCallback: () =>
84
+ history.replace({ pathname: '/template_syncs/result' }),
85
+ });
86
+ };
87
+
88
+ return (
89
+ <ForemanForm
90
+ onSubmit={handleSubmit}
91
+ initialValues={initialValues}
92
+ validationSchema={syncFormSchema(
93
+ syncType,
94
+ { import: importSettings, export: exportSettings },
95
+ validationData
96
+ )}
97
+ onCancel={redirectToResult(history)}
98
+ error={error}
99
+ >
100
+ <SyncTypeRadios
101
+ name="syncType"
102
+ controlLabel="Action type"
103
+ radios={initRadioButtons(syncType)}
104
+ />
105
+ <SyncSettingsFields
106
+ importSettings={importSettings}
107
+ exportSettings={exportSettings}
108
+ syncType={syncType}
109
+ resetField={resetToDefault}
110
+ />
111
+ </ForemanForm>
112
+ );
113
+ };
157
114
 
158
115
  NewTemplateSyncForm.propTypes = {
159
116
  importSettings: PropTypes.array,
@@ -166,8 +123,6 @@ NewTemplateSyncForm.propTypes = {
166
123
  exportUrl: PropTypes.string.isRequired,
167
124
  importUrl: PropTypes.string.isRequired,
168
125
  submitForm: PropTypes.func.isRequired,
169
- currentLocation: PropTypes.object.isRequired,
170
- currentOrganization: PropTypes.object.isRequired,
171
126
  };
172
127
 
173
128
  NewTemplateSyncForm.defaultProps = {
@@ -0,0 +1,43 @@
1
+ import * as Yup from 'yup';
2
+
3
+ export const redirectToResult = history => () =>
4
+ history.push({ pathname: '/template_syncs/result' });
5
+
6
+ const repoFormat = formatAry => value => {
7
+ if (value === undefined) {
8
+ return true;
9
+ }
10
+
11
+ const valid = formatAry
12
+ .map(item => value.startsWith(item))
13
+ .reduce((memo, item) => item || memo, false);
14
+
15
+ return value && valid;
16
+ };
17
+
18
+ export const syncFormSchema = (syncType, settingsObj, validationData) => {
19
+ const schema = (settingsObj[syncType].asMutable() || []).reduce(
20
+ (memo, setting) => {
21
+ if (setting.name === 'repo') {
22
+ return {
23
+ ...memo,
24
+ repo: Yup.string()
25
+ .test(
26
+ 'repo-format',
27
+ `Invalid repo format, must start with one of: ${validationData.repo.join(
28
+ ', '
29
+ )}`,
30
+ repoFormat(validationData.repo)
31
+ )
32
+ .required("can't be blank"),
33
+ };
34
+ }
35
+ return memo;
36
+ },
37
+ {}
38
+ );
39
+
40
+ return Yup.object().shape({
41
+ [syncType]: Yup.object().shape(schema),
42
+ });
43
+ };
@@ -1,4 +1,4 @@
1
- import { testSelectorsSnapshotWithFixtures } from 'react-redux-test-utils';
1
+ import { testSelectorsSnapshotWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import {
4
4
  stateFactory,
@@ -2,8 +2,6 @@ import { connect } from 'react-redux';
2
2
 
3
3
  import * as FormActions from 'foremanReact/redux/actions/common/forms';
4
4
 
5
- import { selectLayout } from 'foremanReact/components/Layout/LayoutSelectors';
6
-
7
5
  import NewTemplateSyncForm from './NewTemplateSyncForm';
8
6
 
9
7
  import {
@@ -24,8 +22,6 @@ const mapStateToProps = (state, ownProps) => {
24
22
  initialValues: { ...initialFormValues },
25
23
  importSettings,
26
24
  exportSettings,
27
- currentOrganization: selectLayout(state).currentOrganization,
28
- currentLocation: selectLayout(state).currentLocation,
29
25
  };
30
26
  };
31
27
 
@@ -1,4 +1,4 @@
1
- import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import SyncSettingField from '../SyncSettingField';
4
4
 
@@ -1,4 +1,4 @@
1
- import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import SyncSettingFields from '../SyncSettingFields';
4
4
 
@@ -1,4 +1,4 @@
1
- import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import SyncTypeRadios from '../SyncTypeRadios';
4
4
 
@@ -1,4 +1,4 @@
1
- import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import TextButtonField from '../TextButtonField';
4
4
 
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { EmptyStatePattern as EmptyState } from 'foremanReact/components/common/EmptyState';
3
+ import { translate as __ } from 'foremanReact/common/I18n';
3
4
 
4
5
  const PageNotFound = props => (
5
6
  <EmptyState
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
 
4
+ import { translate as __ } from 'foremanReact/common/I18n';
4
5
  import { EmptyStatePattern as EmptyState } from 'foremanReact/components/common/EmptyState';
5
6
 
6
7
  const PermissionDenied = props => {
@@ -1,6 +1,6 @@
1
1
  // move to some sort of pagination helper in core
2
2
  export const templatesPage = (templates, pagination) => {
3
- const offset = (pagination.page - 1) * pagination.perPage;
3
+ const offset = (pagination.page - 1) * pagination.per_page;
4
4
 
5
- return templates.slice(offset, offset + pagination.perPage);
5
+ return templates.slice(offset, offset + pagination.per_page);
6
6
  };
@@ -12,7 +12,7 @@ export const initialState = Immutable({
12
12
 
13
13
  pagination: {
14
14
  page: 1,
15
- perPage: 20,
15
+ per_page: 20,
16
16
  },
17
17
  });
18
18
 
@@ -1,4 +1,4 @@
1
- import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import {
4
4
  importTemplates,
@@ -1,4 +1,4 @@
1
- import { testReducerSnapshotWithFixtures } from 'react-redux-test-utils';
1
+ import { testReducerSnapshotWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import reducer, { initialState } from '../TemplateSyncResultReducer';
4
4
  import { importTemplates } from '../__fixtures__/templateSyncResult.fixtures';
@@ -4,7 +4,7 @@ exports[`TemplateSyncResultReducer should return initial state 1`] = `
4
4
  Object {
5
5
  "pagination": Object {
6
6
  "page": 1,
7
- "perPage": 20,
7
+ "per_page": 20,
8
8
  },
9
9
  "resultAction": "",
10
10
  "templates": Array [],
@@ -27,7 +27,7 @@ Object {
27
27
  "branch": "master",
28
28
  "pagination": Object {
29
29
  "page": 1,
30
- "perPage": 20,
30
+ "per_page": 20,
31
31
  },
32
32
  "repo": "https://github.com/theforeman/community-templates.git",
33
33
  "resultAction": "import",
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { capitalize } from 'lodash';
4
+ import { LinkContainer } from 'react-router-bootstrap';
5
+ import { Button } from 'patternfly-react';
4
6
 
7
+ import { translate as __ } from 'foremanReact/common/I18n';
5
8
  import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
6
- import { LinkContainer } from 'react-router-bootstrap';
7
9
 
8
- import { Button } from 'patternfly-react';
9
10
  import SyncResultList from './SyncResultList';
10
11
 
11
12
  const titleString = (type, repo, branch, gitUser, fileRepoStartWith) => {
@@ -2,13 +2,19 @@ import React from 'react';
2
2
  import { ListView } from 'patternfly-react';
3
3
  import PropTypes from 'prop-types';
4
4
 
5
- import Pagination from 'foremanReact/components/Pagination/PaginationWrapper';
5
+ import Pagination from 'foremanReact/components/Pagination';
6
6
 
7
7
  import SyncedTemplate from './SyncedTemplate';
8
8
  import { templatesPage } from '../TemplateSyncResultHelpers';
9
9
  import ListViewHeader from './ListViewHeader';
10
10
 
11
- const SyncResultList = ({ pagination, pageChange, templates, editPaths }) => (
11
+ const SyncResultList = ({
12
+ pagination,
13
+ pagination: { page, per_page: perPage },
14
+ pageChange,
15
+ templates,
16
+ editPaths,
17
+ }) => (
12
18
  <ListView>
13
19
  <ListViewHeader />
14
20
  {templatesPage(templates, pagination).map((template, idx) => (
@@ -19,11 +25,10 @@ const SyncResultList = ({ pagination, pageChange, templates, editPaths }) => (
19
25
  />
20
26
  ))}
21
27
  <Pagination
22
- viewType="list"
23
28
  itemCount={templates.length}
24
- pagination={pagination}
25
29
  onChange={pageChange}
26
- dropdownButtonId="template-sync-result-dropdown"
30
+ page={page}
31
+ perPage={perPage}
27
32
  />
28
33
  </ListView>
29
34
  );
@@ -31,7 +36,7 @@ const SyncResultList = ({ pagination, pageChange, templates, editPaths }) => (
31
36
  SyncResultList.propTypes = {
32
37
  pagination: PropTypes.shape({
33
38
  page: PropTypes.number,
34
- perPage: PropTypes.number,
39
+ per_page: PropTypes.number,
35
40
  }).isRequired,
36
41
  pageChange: PropTypes.func.isRequired,
37
42
  templates: PropTypes.array.isRequired,
@@ -1,17 +1,13 @@
1
1
  import React from 'react';
2
- import { ListView, OverlayTrigger, Tooltip } from 'patternfly-react';
2
+ import { ListView } from 'patternfly-react';
3
+ import { Tooltip } from '@patternfly/react-core';
3
4
  import PropTypes from 'prop-types';
4
5
 
5
6
  const InfoItem = ({ itemId, children, tooltipText }) => {
6
7
  const overlay = (
7
- <OverlayTrigger
8
- overlay={tooltipText ? <Tooltip id={itemId}>{tooltipText}</Tooltip> : ''}
9
- placement="top"
10
- trigger={['hover', 'focus']}
11
- rootClose={false}
12
- >
8
+ <Tooltip content={tooltipText || ''} id={itemId}>
13
9
  {children}
14
- </OverlayTrigger>
10
+ </Tooltip>
15
11
  );
16
12
  return (
17
13
  <ListView.InfoItem key={itemId} className="additional-info-wide">
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import EllipsisWithTooltip from 'react-ellipsis-with-tooltip';
3
3
  import PropTypes from 'prop-types';
4
+ import { translate as __ } from 'foremanReact/common/I18n';
4
5
 
5
6
  import InfoItem from './InfoItem';
6
7
  import { itemIteratorId } from './helpers';
@@ -1,4 +1,4 @@
1
- import { testSelectorsSnapshotWithFixtures } from 'react-redux-test-utils';
1
+ import { testSelectorsSnapshotWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import { expandableContent } from './helpers';
4
4
 
@@ -1,4 +1,4 @@
1
- import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import SyncResultList from '../SyncResultList';
4
4
  import { importTemplates } from '../../__fixtures__/templateSyncResult.fixtures';
@@ -18,7 +18,7 @@ const fixtures = {
18
18
  editPaths,
19
19
  pagination: {
20
20
  page: 1,
21
- perPage: 20,
21
+ per_page: 20,
22
22
  },
23
23
  },
24
24
  };
@@ -1,4 +1,4 @@
1
- import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
  import SyncedTemplate from '../SyncedTemplate';
3
3
  import {
4
4
  noName,
@@ -88,17 +88,11 @@ exports[`SyncResultList should render 1`] = `
88
88
  }
89
89
  }
90
90
  />
91
- <PaginationWrapper
92
- dropdownButtonId="template-sync-result-dropdown"
91
+ <Pagination
93
92
  itemCount={5}
94
93
  onChange={[Function]}
95
- pagination={
96
- Object {
97
- "page": 1,
98
- "perPage": 20,
99
- }
100
- }
101
- viewType="list"
94
+ page={1}
95
+ perPage={20}
102
96
  />
103
97
  </ListView>
104
98
  `;
data/webpack/testSetup.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import 'core-js/shim';
2
2
  import 'regenerator-runtime/runtime';
3
3
 
4
- import { configure } from 'enzyme';
4
+ import { configure } from '@theforeman/test';
5
5
  import Adapter from 'enzyme-adapter-react-16';
6
6
 
7
7
  configure({ adapter: new Adapter() });
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_templates
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.0.2
4
+ version: 9.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Sutcliffe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-08 00:00:00.000000000 Z
11
+ date: 2022-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diffy
@@ -69,7 +69,6 @@ files:
69
69
  - app/controllers/ui_template_syncs_controller.rb
70
70
  - app/helpers/foreman_templates_helper.rb
71
71
  - app/models/concerns/foreman_templates/template_extensions.rb
72
- - app/models/setting/template_sync.rb
73
72
  - app/services/foreman_templates/action.rb
74
73
  - app/services/foreman_templates/cleaner.rb
75
74
  - app/services/foreman_templates/export_result.rb
@@ -89,6 +88,7 @@ files:
89
88
  - app/views/ui_template_syncs/template_import_results.json.rabl
90
89
  - config/routes.rb
91
90
  - db/migrate/20180627134929_change_lock_setting.rb
91
+ - db/migrate/20211122154929_templates_settings_category_to_dsl.rb
92
92
  - lib/foreman_templates.rb
93
93
  - lib/foreman_templates/engine.rb
94
94
  - lib/foreman_templates/version.rb
@@ -96,9 +96,11 @@ files:
96
96
  - package.json
97
97
  - webpack/ForemanTemplates.js
98
98
  - webpack/Routes.js
99
+ - webpack/__mocks__/foremanReact/Root/Context/ForemanContext.js
100
+ - webpack/__mocks__/foremanReact/common/I18n.js
99
101
  - webpack/__mocks__/foremanReact/common/helpers.js
100
102
  - webpack/__mocks__/foremanReact/components/Layout/LayoutSelectors.js
101
- - webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js
103
+ - webpack/__mocks__/foremanReact/components/Pagination/index.js
102
104
  - webpack/__mocks__/foremanReact/components/common/forms/CommonForm.js
103
105
  - webpack/__mocks__/foremanReact/components/common/forms/ForemanForm.js
104
106
  - webpack/__mocks__/foremanReact/components/common/forms/TextField.js
@@ -120,6 +122,7 @@ files:
120
122
  - webpack/components/NewTemplateSync/__tests__/__snapshots__/NewTemplateSyncSelectors.test.js.snap
121
123
  - webpack/components/NewTemplateSync/components/ButtonTooltip.js
122
124
  - webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncForm.js
125
+ - webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncFormHelpers.js
123
126
  - webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncFormSelectors.js
124
127
  - webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/NewTemplateSyncFormSelectors.test.js
125
128
  - webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/__snapshots__/NewTemplateSyncFormSelectors.test.js.snap
@@ -1,115 +0,0 @@
1
- class Setting
2
- class TemplateSync < ::Setting
3
- self.include_root_in_json = false
4
-
5
- def self.common_stripped_names
6
- %w(verbose repo branch dirname filter negate)
7
- end
8
-
9
- def self.import_stripped_names
10
- %w(prefix associate force lock)
11
- end
12
-
13
- def self.export_stripped_names
14
- %w(metadata_export_mode commit_msg)
15
- end
16
-
17
- def self.import_setting_names(except = [])
18
- map_prefix omit_settings(common_stripped_names + import_stripped_names, except)
19
- end
20
-
21
- def self.export_setting_names(except = [])
22
- map_prefix omit_settings(common_stripped_names + export_stripped_names, except)
23
- end
24
-
25
- def self.map_prefix(stripped_names)
26
- stripped_names.map { |item| "template_sync_#{item}" }
27
- end
28
-
29
- def self.omit_settings(setting_names, except_array)
30
- setting_names.reject { |name| except_array.include? name }
31
- end
32
-
33
- def self.associate_types
34
- {
35
- 'always' => _('Always'),
36
- 'new' => _('New'),
37
- 'never' => _('Never')
38
- }
39
- end
40
-
41
- def self.lock_types
42
- {
43
- 'lock' => _('Lock'),
44
- 'keep_lock_new' => _('Keep, lock new'),
45
- 'keep' => _('Keep, do not lock new'),
46
- 'unlock' => _('Unlock')
47
- }
48
- end
49
-
50
- def self.metadata_export_mode_types
51
- {
52
- 'refresh' => _('Refresh'),
53
- 'keep' => _('Keep'),
54
- 'remove' => _('Remove')
55
- }
56
- end
57
-
58
- def short_name
59
- name.split('template_sync_').last
60
- end
61
-
62
- def selection
63
- selection_method = name.split('template_sync_').last.concat('_types')
64
- return transformed_selection(selection_method) if self.class.respond_to?(selection_method)
65
-
66
- []
67
- end
68
-
69
- def self.load_defaults
70
- return unless super
71
-
72
- %w(template_sync_filter template_sync_branch template_sync_prefix).each { |s| Setting::BLANK_ATTRS << s }
73
- Setting::NOT_STRIPPED << 'template_sync_prefix'
74
-
75
- self.transaction do
76
- [
77
- self.set('template_sync_verbose', N_('Choose verbosity for Rake task importing templates'), false, N_('Verbosity')),
78
- self.set('template_sync_associate', N_('Associate templates to OS, organization and location'), 'new', N_('Associate'), nil, { :collection => Proc.new { self.associate_types } }),
79
- self.set('template_sync_prefix', N_('The string that will be added as prefix to imported templates'), "", N_('Prefix')),
80
- self.set('template_sync_dirname', N_('The directory within the Git repo containing the templates'), '/', N_('Dirname')),
81
- self.set('template_sync_filter', N_('Import/export names matching this regex (case-insensitive; snippets are not filtered)'), '', N_('Filter')),
82
- self.set('template_sync_repo', N_('Target path to import/export. Different protocols can be used, for example /tmp/dir, git://example.com, https://example.com, ssh://example.com. When exporting to /tmp, note that production deployments may be configured to use private tmp.'), 'https://github.com/theforeman/community-templates.git', N_('Repo')),
83
- self.set('template_sync_negate', N_('Negate the filter for import/export'), false, N_('Negate')),
84
- self.set('template_sync_branch', N_('Default branch in Git repo'), '', N_('Branch')),
85
- self.set('template_sync_metadata_export_mode', N_('Default metadata export mode, refresh re-renders metadata, keep will keep existing metadata, remove exports template without metadata'), 'refresh', N_('Metadata export mode'), nil, { :collection => Proc.new { self.metadata_export_mode_types } }),
86
- self.set('template_sync_force', N_('Should importing overwrite locked templates?'), false, N_('Force import')),
87
- self.set('template_sync_lock', N_('How to handle lock for imported templates?'), 'keep', N_('Lock templates'), nil, { :collection => Proc.new { self.lock_types } }),
88
- self.set('template_sync_commit_msg', N_('Custom commit message for templates export'), 'Templates export made by a Foreman user', N_('Commit message'))
89
- ].compact.each { |s| self.create! s.update(:category => "Setting::TemplateSync") }
90
- end
91
-
92
- true
93
- end
94
-
95
- def validate_template_sync_associate(record)
96
- values = record.class.associate_types.keys
97
- if record.value && !values.include?(record.value)
98
- record.errors[:base] << (_("template_sync_associate must be one of %s") % values.join(', '))
99
- end
100
- end
101
-
102
- def validate_template_sync_metadata_export_mode(record)
103
- values = record.class.metadata_export_mode_types.keys
104
- if record.value && !values.include?(record.value)
105
- record.errors[:base] << (_("template_sync_metadata_export_mode must be one of %s") % values.join(', '))
106
- end
107
- end
108
-
109
- private
110
-
111
- def transformed_selection(selection_method)
112
- self.class.public_send(selection_method).map { |key, translated| { :value => key, :label => translated } }
113
- end
114
- end
115
- end
@@ -1,2 +0,0 @@
1
- const PaginationWrapper = () => jest.fn();
2
- export default PaginationWrapper;