foreman-tasks 3.0.1 → 3.0.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc7a0cd7f208321abcb3a5360623c6a639cbe6ae7e4f00c89987db5c18de95cb
4
- data.tar.gz: 7cc406baeb19a74bb7ac645349050d192ff1d3f62edb7895eada9744f1d39fd4
3
+ metadata.gz: 29e160b9773db8ef5b9f8cb9e26011b957578caccf2d56bc6a57852c5553df9d
4
+ data.tar.gz: 863c9436e788ede17b6e2a80aae49b259f96a1372c80a004ed66e70409957435
5
5
  SHA512:
6
- metadata.gz: 04ec2f1a2096462df40eea233da31072e713dfa2d75314a0a7c271a7b48cca32a46f9785b831f684dda45ad1c5efcf65da1c2941aad8c6f39deee25bf324f54f
7
- data.tar.gz: 5d8dbdeeff9b3bb1287707cc2abb13847fcece48f986e81240ec687b280811c2249200ea497901061ed789f9481a1ba8ec639918ab5010b0cf52ea341b5b34a5
6
+ metadata.gz: 4140dea3980dcbbc2d140b3e83dc23458a53ff6be35f5012feb8d3bd87c24ed45e98eb98a19aaf7228c1ca620f4e91e57236cc4c17e36754bd1cbe65dd1b3249
7
+ data.tar.gz: e2836f3e5061587913504a69509e21fab8e640f002cf026641d8948e64f830c8abf1aa4b7d72e9a9c64f49c47116ac94be299367b6fba9d44689d410f1805cb3
@@ -75,11 +75,16 @@ module ForemanTasks
75
75
  end
76
76
 
77
77
  api :POST, '/tasks/bulk_resume', N_('Resume all paused error tasks')
78
+ desc <<~DOC
79
+ Resumes all selected resumable tasks. If neither a search query nor an
80
+ explicit list of task IDs is provided, it tries to resume all tasks in
81
+ paused state with result error.
82
+ DOC
78
83
  param :search, String, :desc => N_('Resume tasks matching search string')
79
84
  param :task_ids, Array, :desc => N_('Resume specific tasks by ID')
80
85
  def bulk_resume
81
86
  if params[:search].nil? && params[:task_ids].nil?
82
- raise BadRequest, _('Please provide at least one of search or task_ids parameters in the request')
87
+ params[:search] = 'state = paused and result = error'
83
88
  end
84
89
  resumed = []
85
90
  failed = []
@@ -109,9 +114,14 @@ module ForemanTasks
109
114
  }
110
115
  end
111
116
 
112
- api :POST, '/tasks/bulk_cancel', N_('Cancel all cancellable tasks')
117
+ api :POST, '/tasks/bulk_cancel', N_('Cancel selected cancellable tasks')
118
+ desc <<~DOC
119
+ Cancels all selected cancellable tasks. Requires a search query or an
120
+ explicit list of task IDs to be provided.
121
+ DOC
113
122
  param :search, String, :desc => N_('Cancel tasks matching search string')
114
123
  param :task_ids, Array, :desc => N_('Cancel specific tasks by ID')
124
+ error :bad_request, 'Returned if neither search nor task_ids parameter is provided.'
115
125
  def bulk_cancel
116
126
  if params[:search].nil? && params[:task_ids].nil?
117
127
  raise BadRequest, _('Please provide at least one of search or task_ids parameters in the request')
@@ -130,9 +140,14 @@ module ForemanTasks
130
140
  }
131
141
  end
132
142
 
133
- api :POST, '/tasks/bulk_stop', N_('Stop all stoppable tasks')
143
+ api :POST, '/tasks/bulk_stop', N_('Stop selected stoppable tasks')
144
+ desc <<~DOC
145
+ Stops all selected tasks which are not already stopped. Requires a
146
+ search query or an explicit list of task IDs to be provided.
147
+ DOC
134
148
  param :search, String, :desc => N_('Stop tasks matching search string')
135
149
  param :task_ids, Array, :desc => N_('Stop specific tasks by ID')
150
+ error :bad_request, 'Returned if neither search nor task_ids parameter is provided.'
136
151
  def bulk_stop
137
152
  if params[:search].nil? && params[:task_ids].nil?
138
153
  raise BadRequest, _('Please provide at least one of search or task_ids parameters in the request')
@@ -31,12 +31,12 @@ module ForemanTasks
31
31
  if value
32
32
  task.update!(:start_at => next_occurrence_time) if task.start_at < Time.zone.now
33
33
  update(:state => 'active')
34
- else
35
- update(:state => 'disabled')
36
34
  end
37
- else
35
+ elsif value
38
36
  raise RecurringLogicCancelledException
39
37
  end
38
+
39
+ update(:state => 'disabled') unless value
40
40
  end
41
41
 
42
42
  def enabled?
@@ -140,12 +140,17 @@ module ForemanTasks
140
140
 
141
141
  def main_action
142
142
  return @main_action if defined?(@main_action)
143
+
144
+ @main_action = execution_plan && execution_plan.root_plan_step.try(:action, execution_plan)
143
145
  if active_job?
144
146
  job_data = active_job_data
145
- @main_action = active_job_action(job_data['job_class'], job_data['arguments'])
146
- else
147
- @main_action = execution_plan && execution_plan.root_plan_step.try(:action, execution_plan)
147
+ begin
148
+ @main_action = active_job_action(job_data['job_class'], job_data['arguments'])
149
+ rescue => e
150
+ Foreman::Logging.exception("Failed to load ActiveJob for task #{id}", e, :logger => 'foreman-tasks')
151
+ end
148
152
  end
153
+ @main_action
149
154
  end
150
155
 
151
156
  # The class for ActiveJob jobs in Dynflow, JobWrapper is not expected to
@@ -20,7 +20,8 @@ module ForemanTasks
20
20
  foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_type = '#{resource_type}')
21
21
  SQL
22
22
  # Select only those tasks which either have the correct taxonomy or are not related to any
23
- sql = "foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id #{operator} ? OR foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id IS NULL"
23
+ sql = "foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id #{operator} (?) OR foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id IS NULL"
24
+ value = value.split(',') if operator.index(/IN/i)
24
25
  { :conditions => sanitize_sql_for_conditions([sql, value]), :joins => joins }
25
26
  end
26
27
 
@@ -9,7 +9,6 @@
9
9
  <%= notifications %>
10
10
  <div id="organization-id" data-id="<%= Organization.current.id if Organization.current %>" ></div>
11
11
  <div id="user-id" data-id="<%= User.current.id if User.current %>" ></div>
12
- <div id="foremanTasksReactRoot"></div>
12
+ <%= react_component('ForemanTasks') %>
13
13
  <% end %>
14
14
  <%= render file: "layouts/base" %>
15
- <%= mount_react_component('ForemanTasks', '#foremanTasksReactRoot') %>
@@ -11,7 +11,7 @@
11
11
  <td class="ellipsis"><%= link_to task.humanized[:action], defined?(main_app) ? main_app.foreman_tasks_task_path(task.id) : foreman_tasks_task_path(task.id) %></td>
12
12
  <td><%= task.state %></td>
13
13
  <td><%= task.result %></td>
14
- <td><%= task.started_at ? (_(date_time_relative(task.started_at))) : _('N/A') %></td>
14
+ <td><%= task.started_at ? date_time_relative(task.started_at) : _('N/A') %></td>
15
15
  </tr>
16
16
  <% end %>
17
17
  </table>
@@ -11,7 +11,7 @@
11
11
  <td><%= result.state %></td>
12
12
  <td><%= result.result %></td>
13
13
  <td><%= link_to result.count, main_app.foreman_tasks_tasks_path(:search => "state=#{result.state}&result=#{result.result}") %></td>
14
- <td><%= result.started_at ? (_(date_time_relative(result.started_at))) : _('N/A') %></td>
14
+ <td><%= result.started_at ? date_time_relative(result.started_at) : _('N/A') %></td>
15
15
  </tr>
16
16
  <% end %>
17
17
  </table>
@@ -15,9 +15,4 @@
15
15
  switcher_item_url: foreman_tasks_task_path(:id => ':id')
16
16
  ) %>
17
17
 
18
-
19
- <div class="task-details" id="foremanTaskDetails">
20
- </div>
21
-
22
-
23
- <%= mount_react_component('TaskDetails', '#foremanTaskDetails') %>
18
+ <%= react_component('TaskDetails') %>
@@ -7,6 +7,7 @@ require "foreman_tasks/version"
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "foreman-tasks"
9
9
  s.version = ForemanTasks::VERSION
10
+ s.license = 'GPL-3.0'
10
11
  s.authors = ["Ivan Nečas"]
11
12
  s.email = ["inecas@redhat.com"]
12
13
  s.homepage = "https://github.com/theforeman/foreman-tasks"
@@ -1,3 +1,3 @@
1
1
  module ForemanTasks
2
- VERSION = '3.0.1'.freeze
2
+ VERSION = '3.0.6'.freeze
3
3
  end
@@ -148,6 +148,12 @@ class RecurringLogicsTest < ActiveSupport::TestCase
148
148
  assert ForemanTasks.dynflow.world.persistence.load_delayed_plan(task.execution_plan.id).frozen
149
149
  end
150
150
 
151
+ it 'handles if the task has been deleted' do
152
+ logic.tasks.find_by(:state => 'scheduled').destroy
153
+ logic.update!(:enabled => false)
154
+ assert_equal 'disabled', logic.state
155
+ end
156
+
151
157
  it 'properly re-enables on disable' do
152
158
  logic.update!(:enabled => false)
153
159
  logic.update!(:enabled => true)
@@ -129,6 +129,16 @@ class TasksTest < ActiveSupport::TestCase
129
129
  _ { proc { ForemanTasks::Task.search_for('duration = "25 potatoes"') } }.must_raise ScopedSearch::QueryNotSupported
130
130
  end
131
131
  end
132
+
133
+ context 'by taxonomies' do
134
+ test 'can search by taxonomies using IN' do
135
+ assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('location_id ^ (1)').first }
136
+ assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('organization_id ^ (1)').first }
137
+ assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('location_id ^ (1,2)').first }
138
+ assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('organization_id ^ (1,2)').first }
139
+ assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('organization_id = 1').first }
140
+ end
141
+ end
132
142
  end
133
143
 
134
144
  describe 'users' do
@@ -49,4 +49,14 @@
49
49
  .dynflow-button > span {
50
50
  pointer-events: auto;
51
51
  }
52
+
53
+ pre {
54
+ white-space: pre;
55
+ word-break: normal;
56
+ }
57
+
58
+ .param-name {
59
+ display: inline-block;
60
+ width: 10em;
61
+ }
52
62
  }
@@ -14,14 +14,6 @@ export const getApiPathname = url => {
14
14
  return uri.pathname().replace('foreman_tasks/', 'foreman_tasks/api/');
15
15
  };
16
16
 
17
- export const resolveSearchQuery = (search, history) => {
18
- const uriQuery = {
19
- search,
20
- page: 1,
21
- };
22
- updateURlQuery(uriQuery, history);
23
- };
24
-
25
17
  export const getCSVurl = (path, query) => {
26
18
  let url = new URI(path);
27
19
  url = url.pathname(`${url.pathname()}.csv`);
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
+ import URI from 'urijs';
3
4
  import { getURIsearch } from 'foremanReact/common/urlHelpers';
4
5
  import { Spinner, Button, Icon } from 'patternfly-react';
5
6
  import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
@@ -10,7 +11,7 @@ import { STATUS } from 'foremanReact/constants';
10
11
  import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
11
12
  import TasksDashboard from '../TasksDashboard';
12
13
  import TasksTable from './TasksTable';
13
- import { resolveSearchQuery, getCSVurl } from './TasksTableHelpers';
14
+ import { getCSVurl, updateURlQuery } from './TasksTableHelpers';
14
15
  import ConfirmModal from './Components/ConfirmModal/';
15
16
  import {
16
17
  TASKS_SEARCH_PROPS,
@@ -35,8 +36,17 @@ const TasksTablePage = ({
35
36
  }) => {
36
37
  const url = history.location.pathname + history.location.search;
37
38
  const uriQuery = getURIQuery(url);
38
- const onSearch = searchQuery => {
39
- resolveSearchQuery(searchQuery, history);
39
+ const onSearch = search => {
40
+ const uri = new URI(url);
41
+ if (uri.search(true).search === search && uri.search(true).page === '1') {
42
+ props.getTableItems(uri);
43
+ } else {
44
+ const newUriQuery = {
45
+ search,
46
+ page: 1,
47
+ };
48
+ updateURlQuery(newUriQuery, history);
49
+ }
40
50
  };
41
51
 
42
52
  const { setModalOpen, setModalClosed } = useForemanModal({
@@ -60,7 +70,6 @@ const TasksTablePage = ({
60
70
  onSearch={onSearch}
61
71
  header={createHeader(props.actionName)}
62
72
  breadcrumbOptions={getBreadcrumbs(props.actionName)}
63
- toastNotifications="foreman-tasks-cancel"
64
73
  toolbarButtons={
65
74
  <React.Fragment>
66
75
  <Button onClick={() => props.reloadPage(url, props.parentTaskID)}>
@@ -14,16 +14,6 @@
14
14
  }
15
15
  }
16
16
 
17
- .param-name {
18
- display: inline-block;
19
- width: 10em;
20
- }
21
-
22
- .task-details pre {
23
- white-space: pre;
24
- word-break: normal;
25
- }
26
-
27
17
  .tasks-time-row .time-label {
28
18
  float: left;
29
19
  }
@@ -66,7 +66,6 @@ exports[`TasksTablePage rendering render with Breadcrubs and edit permissions 1`
66
66
  }
67
67
  searchQuery="a=b"
68
68
  searchable={true}
69
- toastNotifications="foreman-tasks-cancel"
70
69
  toolbarButtons={
71
70
  <React.Fragment>
72
71
  <Button
@@ -202,7 +201,6 @@ exports[`TasksTablePage rendering render with minimal props 1`] = `
202
201
  }
203
202
  searchQuery="a=b"
204
203
  searchable={true}
205
- toastNotifications="foreman-tasks-cancel"
206
204
  toolbarButtons={
207
205
  <React.Fragment>
208
206
  <Button
@@ -4,6 +4,8 @@ exports[`actionNameCellFormatter render 1`] = `
4
4
  <a
5
5
  href="/some-url/some-id"
6
6
  >
7
- action-name
7
+ <EllipisWithTooltip>
8
+ action-name
9
+ </EllipisWithTooltip>
8
10
  </a>
9
11
  `;
@@ -1,5 +1,10 @@
1
1
  import React from 'react';
2
2
  import { cellFormatter } from 'foremanReact/components/common/table';
3
+ import EllipsisWithTooltip from 'react-ellipsis-with-tooltip';
3
4
 
4
5
  export const actionNameCellFormatter = url => (value, { rowData: { id } }) =>
5
- cellFormatter(<a href={`/${url}/${id}`}>{value}</a>);
6
+ cellFormatter(
7
+ <a href={`/${url}/${id}`}>
8
+ <EllipsisWithTooltip>{value}</EllipsisWithTooltip>
9
+ </a>
10
+ );
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman-tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Nečas
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-02 00:00:00.000000000 Z
11
+ date: 2021-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dynflow
@@ -137,7 +137,6 @@ files:
137
137
  - app/assets/javascripts/foreman_tasks/foreman_tasks.js
138
138
  - app/assets/javascripts/foreman_tasks/trigger_form.js
139
139
  - app/assets/stylesheets/foreman_tasks/foreman_tasks.css
140
- - app/assets/stylesheets/foreman_tasks/tasks.scss
141
140
  - app/assets/stylesheets/foreman_tasks/trigger_form.css
142
141
  - app/controllers/foreman_tasks/api/recurring_logics_controller.rb
143
142
  - app/controllers/foreman_tasks/api/tasks_controller.rb
@@ -586,9 +585,10 @@ files:
586
585
  - webpack/stories/decorators/index.js
587
586
  - webpack/stories/decorators/withCardsDecorator.js
588
587
  homepage: https://github.com/theforeman/foreman-tasks
589
- licenses: []
588
+ licenses:
589
+ - GPL-3.0
590
590
  metadata: {}
591
- post_install_message:
591
+ post_install_message:
592
592
  rdoc_options: []
593
593
  require_paths:
594
594
  - lib
@@ -603,8 +603,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
603
603
  - !ruby/object:Gem::Version
604
604
  version: '0'
605
605
  requirements: []
606
- rubygems_version: 3.0.3
607
- signing_key:
606
+ rubygems_version: 3.1.2
607
+ signing_key:
608
608
  specification_version: 4
609
609
  summary: Foreman plugin for showing tasks information for resources and users
610
610
  test_files:
@@ -1,9 +0,0 @@
1
- .param-name {
2
- display: inline-block;
3
- width: 10em;
4
- }
5
-
6
- .task-details pre {
7
- white-space: pre;
8
- word-break: normal;
9
- }