From c9b142aaced9c3380271fd0762c1a31ffd7184f3 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Mon, 12 Sep 2022 19:01:01 +0600 Subject: [PATCH 001/275] adds tags controller --- app/controllers/tags_controller.rb | 43 ++++++++++++++++++++++++++++++ app/models/ability.rb | 1 + app/models/tag.rb | 4 +++ config/routes.rb | 2 ++ 4 files changed, 50 insertions(+) create mode 100644 app/controllers/tags_controller.rb diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb new file mode 100644 index 000000000..d52acbcea --- /dev/null +++ b/app/controllers/tags_controller.rb @@ -0,0 +1,43 @@ +class TagsController < AuthenticatedController + load_and_authorize_resource + include ProjectScoped + include ActivityTracking + + def index; end + + def new; end + + def create + if @tag.save + track_created(@tag, project: @project) + redirect_to project_tags_path(current_project), notice: 'Tag created' + else + render :new + end + end + + def edit; end + + def update + if @tag.update(tag_params) + track_updated(@tag, project: @project) + redirect_to project_tags_path(current_project), notice: 'Tag updated' + else + render :edit + end + end + + def destroy + @tag.destroy + track_destroyed(@tag, project: @project) + redirect_to project_tags_path(current_project), notice: 'Tag destroyed' + end + + private + + def tag_params + modified_params = params.require(:tag).permit(:display_name, :color) + modified_params[:name] = "#{modified_params[:color].gsub('#', '!')}_#{modified_params[:display_name]}" + modified_params.except(:color, :display_name) + end +end diff --git a/app/models/ability.rb b/app/models/ability.rb index 32d5c2868..fe32b9f51 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -7,5 +7,6 @@ def initialize(user) can [:read, :use, :update], Project, authors: { id: [user.id] } can [:create, :read], Comment can [:update, :destroy], Comment, user_id: user.id + can :manage, Tag end end diff --git a/app/models/tag.rb b/app/models/tag.rb index 961fa46e6..c42987734 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -36,6 +36,8 @@ class Tag < ApplicationRecord # * If the tag name contains color details, they are stripped # * The result is titleized def display_name() + return '' if self.name.nil? + if self.name =~ /\A!(\h{6})(_([[:word:]]+))?\z/ if $3 out = $3 @@ -51,6 +53,8 @@ def display_name() # Strips the tag's name and returns the color details if present # if no color information is found, returns a default value of #ccc def color() + return '' if self.name.nil? + name[/\A(!\h{6})_[[:word:]]+?\z/,1].try(:gsub, "!", "#") || "#555" end diff --git a/config/routes.rb b/config/routes.rb index e37b02b2b..c12c96d15 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -93,6 +93,8 @@ member { post :recover } end + resources :tags, except: [:show] + get 'search' => 'search#index' get 'trash' => 'revisions#trash' From ee0f65430ed3b54ea3bc8bd2f7c9b0d1e93e8241 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Mon, 12 Sep 2022 19:31:00 +0600 Subject: [PATCH 002/275] adds views --- app/views/tags/_form.html.erb | 13 ++++++ app/views/tags/activities/_tag.html.erb | 10 +++++ app/views/tags/edit.html.erb | 9 ++++ app/views/tags/index.html.erb | 57 +++++++++++++++++++++++++ app/views/tags/new.html.erb | 9 ++++ 5 files changed, 98 insertions(+) create mode 100644 app/views/tags/_form.html.erb create mode 100644 app/views/tags/activities/_tag.html.erb create mode 100644 app/views/tags/edit.html.erb create mode 100644 app/views/tags/index.html.erb create mode 100644 app/views/tags/new.html.erb diff --git a/app/views/tags/_form.html.erb b/app/views/tags/_form.html.erb new file mode 100644 index 000000000..c603aff74 --- /dev/null +++ b/app/views/tags/_form.html.erb @@ -0,0 +1,13 @@ +<%= simple_form_for @tag, url: url, method: method do |f| %> + <%= f.input :display_name %> + <%= f.label :color %> + <%= f.color_field :color %> +
+ <%= f.button :submit, class: 'btn btn-primary' %> or + <%= + link_to 'Cancel', + project_tags_path(current_project), + class: 'cancel-link' + %> +
+<% end %> diff --git a/app/views/tags/activities/_tag.html.erb b/app/views/tags/activities/_tag.html.erb new file mode 100644 index 000000000..c19fc14dd --- /dev/null +++ b/app/views/tags/activities/_tag.html.erb @@ -0,0 +1,10 @@ +<% if tag %> + <%= presenter.verb %> the + <%= link_to tag.name, edit_project_tag_path(current_project, tag) %> tag. +<% else %> + <% if activity.action == 'destroy' %> + deleted a tag. + <% else %> + <%= presenter.verb %> a tag which has since been deleted. + <% end %> +<% end %> diff --git a/app/views/tags/edit.html.erb b/app/views/tags/edit.html.erb new file mode 100644 index 000000000..549ac1729 --- /dev/null +++ b/app/views/tags/edit.html.erb @@ -0,0 +1,9 @@ +
+

+ Edit <%= @tag.display_name %> +

+ <%= render "form", + url: project_tag_path(current_project, @tag), + method: :patch + %> +
diff --git a/app/views/tags/index.html.erb b/app/views/tags/index.html.erb new file mode 100644 index 000000000..da34b815a --- /dev/null +++ b/app/views/tags/index.html.erb @@ -0,0 +1,57 @@ +
+

Tags Management + +
+ <%= link_to new_project_tag_path(current_project) do %> + New Tag + <% end %> +
+
+

+ <% if @tags.any? %> + + + + + + + <% @tags.each do |tag| %> + + + + + + <% end %> + +
Name Color
+ <%= h(tag.display_name) %> + + > + <%= h(tag.color) %> + + + <%= link_to edit_project_tag_path(current_project, tag), class: '' do %> + Edit + <% end %> + <%= link_to project_tag_path(current_project, tag), method: :delete, data: { confirm: "Are you sure?\n\nProceeding will delete this tag and any associated tagging." }, class: 'text-error-hover' do %> + Delete + <% end %> +
+ <% else %> +
+
+ <%= image_tag "icons/#{rand(9)}.svg" %> +
+
+
+

There are no tags created yet.

+

Create and use tags to manage your issues.

+ +
+
+
+ <% end %> +
diff --git a/app/views/tags/new.html.erb b/app/views/tags/new.html.erb new file mode 100644 index 000000000..ed6e29f4b --- /dev/null +++ b/app/views/tags/new.html.erb @@ -0,0 +1,9 @@ +
+

+ Add Tag +

+ <%= render "form", + url: project_tags_path(current_project), + method: :post + %> +
From a63653d3dda444d9a609f4525c5755dcc2d3bd8a Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Tue, 13 Sep 2022 20:22:40 +0600 Subject: [PATCH 003/275] used modal and added validation --- Gemfile.lock | 7 ++-- app/controllers/tags_controller.rb | 8 ++--- app/models/tag.rb | 35 ++++++------------- app/views/layouts/tylium.html.erb | 4 +++ app/views/tags/_form.html.erb | 28 +++++++++------ app/views/tags/edit.html.erb | 9 ----- app/views/tags/edit.js.erb | 2 ++ app/views/tags/index.html.erb | 10 +++--- app/views/tags/modals/_form.html.erb | 12 +++++++ app/views/tags/new.html.erb | 9 ----- app/views/tags/new.js.erb | 2 ++ db/migrate/20220913101427_add_color_to_tag.rb | 10 ++++++ db/schema.rb | 3 +- 13 files changed, 71 insertions(+), 68 deletions(-) delete mode 100644 app/views/tags/edit.html.erb create mode 100644 app/views/tags/edit.js.erb create mode 100644 app/views/tags/modals/_form.html.erb delete mode 100644 app/views/tags/new.html.erb create mode 100644 app/views/tags/new.js.erb create mode 100644 db/migrate/20220913101427_add_color_to_tag.rb diff --git a/Gemfile.lock b/Gemfile.lock index e6ec39320..bc66c097d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -244,8 +244,7 @@ GEM addressable (~> 2.3) letter_opener (1.7.0) launchy (~> 2.2) - libv8-node (16.10.0.0) - libv8-node (16.10.0.0-x86_64-darwin-19) + libv8-node (16.10.0.0-x86_64-darwin) libv8-node (16.10.0.0-x86_64-linux) liquid (5.0.1) listen (3.4.1) @@ -263,7 +262,7 @@ GEM method_source (0.9.2) mini_mime (1.1.2) mini_portile2 (2.8.0) - mini_racer (0.6.2) + mini_racer (0.6.3) libv8-node (~> 16.10.0.0) minitest (5.16.2) mono_logger (1.1.1) @@ -493,7 +492,7 @@ GEM PLATFORMS ruby - x86_64-darwin-19 + x86_64-darwin x86_64-linux DEPENDENCIES diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index d52acbcea..4740449da 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -12,7 +12,7 @@ def create track_created(@tag, project: @project) redirect_to project_tags_path(current_project), notice: 'Tag created' else - render :new + redirect_to project_tags_path(current_project), alert: @tag.errors.full_messages.join('; ') end end @@ -23,7 +23,7 @@ def update track_updated(@tag, project: @project) redirect_to project_tags_path(current_project), notice: 'Tag updated' else - render :edit + redirect_to project_tags_path(current_project), alert: @tag.errors.full_messages.join('; ') end end @@ -36,8 +36,6 @@ def destroy private def tag_params - modified_params = params.require(:tag).permit(:display_name, :color) - modified_params[:name] = "#{modified_params[:color].gsub('#', '!')}_#{modified_params[:display_name]}" - modified_params.except(:color, :display_name) + modified_params = params.require(:tag).permit(:name, :color) end end diff --git a/app/models/tag.rb b/app/models/tag.rb index c42987734..6528a620c 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -22,7 +22,14 @@ class Tag < ApplicationRecord before_save :normalize_name # -- Validations ------------------------------------------------------------ - validates :name, presence: true, uniqueness: { case_sensitive: false } + validates :name, + presence: true, + uniqueness: { case_sensitive: false }, + format: { with: /\A[a-zA-Z]+\z/ } + validates :color, + presence: true, + uniqueness: { case_sensitive: false }, + format: { with: /\A#\h{6}/ } # -- Scopes ----------------------------------------------------------------- @@ -33,29 +40,9 @@ class Tag < ApplicationRecord # -- Instance Methods ------------------------------------------------------- # Returns a version of the tag's name suitable to present to the user: - # * If the tag name contains color details, they are stripped - # * The result is titleized - def display_name() - return '' if self.name.nil? - - if self.name =~ /\A!(\h{6})(_([[:word:]]+))?\z/ - if $3 - out = $3 - else - out = $1 - end - else - out = self.name - end - return out.titleize - end - - # Strips the tag's name and returns the color details if present - # if no color information is found, returns a default value of #ccc - def color() - return '' if self.name.nil? - - name[/\A(!\h{6})_[[:word:]]+?\z/,1].try(:gsub, "!", "#") || "#555" + # * The name is titleized + def display_name + name.titleize end private diff --git a/app/views/layouts/tylium.html.erb b/app/views/layouts/tylium.html.erb index d70fbf58c..8be1e67f0 100644 --- a/app/views/layouts/tylium.html.erb +++ b/app/views/layouts/tylium.html.erb @@ -102,6 +102,10 @@ <%= render partial: 'styles_tylium/modal' %> <% end %> + <% if controller_name == 'tags' %> + <%= render partial: 'tags/modals/form' %> + <% end %> + <%= render 'console/console' %> diff --git a/app/views/tags/_form.html.erb b/app/views/tags/_form.html.erb index c603aff74..24d7f4cc9 100644 --- a/app/views/tags/_form.html.erb +++ b/app/views/tags/_form.html.erb @@ -1,13 +1,21 @@ + <%= simple_form_for @tag, url: url, method: method do |f| %> - <%= f.input :display_name %> - <%= f.label :color %> - <%= f.color_field :color %> -
- <%= f.button :submit, class: 'btn btn-primary' %> or - <%= - link_to 'Cancel', - project_tags_path(current_project), - class: 'cancel-link' - %> + + <% end %> diff --git a/app/views/tags/edit.html.erb b/app/views/tags/edit.html.erb deleted file mode 100644 index 549ac1729..000000000 --- a/app/views/tags/edit.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -
-

- Edit <%= @tag.display_name %> -

- <%= render "form", - url: project_tag_path(current_project, @tag), - method: :patch - %> -
diff --git a/app/views/tags/edit.js.erb b/app/views/tags/edit.js.erb new file mode 100644 index 000000000..e0d0658a6 --- /dev/null +++ b/app/views/tags/edit.js.erb @@ -0,0 +1,2 @@ +$('#modal-tag-form').modal('show'); +$('#modal-tag-content').html("<%= j (render partial: 'form', locals: { header: 'Edit tag', url: project_tag_path(current_project, @tag), method: :patch }) %>"); diff --git a/app/views/tags/index.html.erb b/app/views/tags/index.html.erb index da34b815a..0bfc390c7 100644 --- a/app/views/tags/index.html.erb +++ b/app/views/tags/index.html.erb @@ -1,11 +1,9 @@

Tags Management -
- <%= link_to new_project_tag_path(current_project) do %> - New Tag - <% end %> -
+ <%= link_to new_project_tag_path(current_project), remote: true, class: 'btn btn-primary' do %> + New Tag + <% end %>

<% if @tags.any? %> @@ -26,7 +24,7 @@ - <%= link_to edit_project_tag_path(current_project, tag), class: '' do %> + <%= link_to edit_project_tag_path(current_project, tag), remote: true do %> Edit <% end %> <%= link_to project_tag_path(current_project, tag), method: :delete, data: { confirm: "Are you sure?\n\nProceeding will delete this tag and any associated tagging." }, class: 'text-error-hover' do %> diff --git a/app/views/tags/modals/_form.html.erb b/app/views/tags/modals/_form.html.erb new file mode 100644 index 000000000..72a7e4ee8 --- /dev/null +++ b/app/views/tags/modals/_form.html.erb @@ -0,0 +1,12 @@ + diff --git a/app/views/tags/new.html.erb b/app/views/tags/new.html.erb deleted file mode 100644 index ed6e29f4b..000000000 --- a/app/views/tags/new.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -
-

- Add Tag -

- <%= render "form", - url: project_tags_path(current_project), - method: :post - %> -
diff --git a/app/views/tags/new.js.erb b/app/views/tags/new.js.erb new file mode 100644 index 000000000..76c954943 --- /dev/null +++ b/app/views/tags/new.js.erb @@ -0,0 +1,2 @@ +$('#modal-tag-form').modal('show'); +$('#modal-tag-content').html("<%= j (render partial: 'form', locals: { header: 'Add new tag', url: project_tags_path(current_project), method: :post }) %>"); diff --git a/db/migrate/20220913101427_add_color_to_tag.rb b/db/migrate/20220913101427_add_color_to_tag.rb new file mode 100644 index 000000000..1b915af52 --- /dev/null +++ b/db/migrate/20220913101427_add_color_to_tag.rb @@ -0,0 +1,10 @@ +class AddColorToTag < ActiveRecord::Migration[6.1] + def change + add_column :tags, :color, :string, default: '#555555', null: false + Tag.all.each do |tag| + color, name = tag.name.split('_') + color = color.try(:gsub, "!", "#") + tag.update(name: name, color: color) + end + end +end diff --git a/db/schema.rb b/db/schema.rb index ed8d97bc6..dad0856dd 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_03_16_202870) do +ActiveRecord::Schema.define(version: 2022_09_13_101427) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false @@ -197,6 +197,7 @@ t.integer "taggings_count", default: 0, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "color", default: "#555555", null: false t.index ["name"], name: "index_tags_on_name" t.index ["taggings_count"], name: "index_tags_on_taggings_count" end From 37facd01e916963fa1ddb17f466a28f8ee54982a Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Wed, 14 Sep 2022 18:02:58 +0600 Subject: [PATCH 004/275] index with datatable --- .../javascripts/shared/datatable/tag.js | 7 +++ app/controllers/issues_controller.rb | 2 +- app/controllers/tags_controller.rb | 13 ++++- app/views/issues/_table.html.erb | 1 + app/views/issues/_tag_input.html.erb | 1 + app/views/tags/_table.html.erb | 58 +++++++++++++++++++ app/views/tags/index.html.erb | 37 +++--------- config/routes.rb | 2 +- 8 files changed, 89 insertions(+), 32 deletions(-) create mode 100644 app/views/tags/_table.html.erb diff --git a/app/assets/javascripts/shared/datatable/tag.js b/app/assets/javascripts/shared/datatable/tag.js index 154fcd455..52b820bab 100644 --- a/app/assets/javascripts/shared/datatable/tag.js +++ b/app/assets/javascripts/shared/datatable/tag.js @@ -19,6 +19,13 @@ DradisDatatable.prototype.setupTagButtons = function() { }); }.bind(this)); + tagButtons.push({ + text: $('Manage Tags').css('color', '#000000'), + action: function(){ + window.location.href = this.$table.data('tags-path') + }.bind(this) + }); + return tagButtons; } diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index e02a0bf12..bdaea5081 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -177,7 +177,7 @@ def set_or_initialize_issue # Load all the colour tags in the project (those that start with !). If none # exist, initialize a set of tags. def set_or_initialize_tags - @tags = current_project.tags.where('name like ?', '!%') + @tags = current_project.tags.where('color like ?', '#%') end def issue_params diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 4740449da..d68dbbcd4 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -1,7 +1,10 @@ class TagsController < AuthenticatedController - load_and_authorize_resource include ProjectScoped include ActivityTracking + include MultipleDestroy + + before_action :set_columns, only: :index + load_and_authorize_resource def index; end @@ -38,4 +41,12 @@ def destroy def tag_params modified_params = params.require(:tag).permit(:name, :color) end + + def set_columns + default_field_names = ['Tag'].freeze + extra_field_names = ['Created', 'Updated'].freeze + + @default_columns = default_field_names + @all_columns = default_field_names | extra_field_names + end end diff --git a/app/views/issues/_table.html.erb b/app/views/issues/_table.html.erb index 9e3447cd8..f0331cded 100644 --- a/app/views/issues/_table.html.erb +++ b/app/views/issues/_table.html.erb @@ -5,6 +5,7 @@ data-item-name="issue" data-local-storage-key="project.ce.<%= dom_id(current_project) %>.issues_datatable" data-tags='<%= @tags.map { |t| [t.display_name, t.color, t.name] }.to_json %>' + data-tags-path="<%= project_tags_path(current_project) %>" > diff --git a/app/views/issues/_tag_input.html.erb b/app/views/issues/_tag_input.html.erb index dbfd49de0..45450a2cc 100644 --- a/app/views/issues/_tag_input.html.erb +++ b/app/views/issues/_tag_input.html.erb @@ -27,6 +27,7 @@ <%= h(tag.display_name) %> <% end %> <% end %> + <%= link_to 'Manage Tags', project_tags_path(current_project), style: "color: #000000", class: 'js-taglink dropdown-item' %>
diff --git a/app/views/tags/_table.html.erb b/app/views/tags/_table.html.erb new file mode 100644 index 000000000..672b9929c --- /dev/null +++ b/app/views/tags/_table.html.erb @@ -0,0 +1,58 @@ +<% cache ['tags-table', @all_columns] do %> + + + + + <% @all_columns.each do |column| %> + + <% end %> + + + + + <% @tags.each do |tag| %> + <% cache [tag, @all_columns, 'tags-table'] do %> + + + <% @all_columns.each do |column| %> + <% + sort, display = + case column + when 'Tag' + [ + tag.name, + content_tag(:span, class: 'tag', style: "color: #{tag.color}") do + content_tag(:i, nil, class: 'icon fa fa-tag') + tag.display_name + end + ] + when 'Created' + [tag.created_at.to_i, local_time_ago(tag.created_at)] + when 'Updated' + [tag.updated_at.to_i, local_time_ago(tag.updated_at)] + end + %> + <%= content_tag :td, + display, + data: { + sort: sort + } + %> + <% end %> + + + <% end %> + <% end %> + +
Select<%= column %>Actions
+ <%= link_to edit_project_tag_path(current_project, tag), remote: true do %> + Edit + <% end %> + <%= link_to project_tag_path(current_project, tag), method: :delete, data: { confirm: "Are you sure?\n\nProceeding will delete this tag and any associated tagging." }, class: 'text-error-hover' do %> + Delete + <% end %> +
+<% end %> diff --git a/app/views/tags/index.html.erb b/app/views/tags/index.html.erb index 0bfc390c7..6ac2d3cd8 100644 --- a/app/views/tags/index.html.erb +++ b/app/views/tags/index.html.erb @@ -1,40 +1,19 @@ +

Tags Management - <%= link_to new_project_tag_path(current_project), remote: true, class: 'btn btn-primary' do %> + <%= link_to new_project_tag_path(current_project), class: 'btn btn-primary', remote: true do %> New Tag <% end %>

<% if @tags.any? %> - - - - - - - <% @tags.each do |tag| %> - - - - - - <% end %> - -
Name Color
- <%= h(tag.display_name) %> - - > - <%= h(tag.color) %> - - - <%= link_to edit_project_tag_path(current_project, tag), remote: true do %> - Edit - <% end %> - <%= link_to project_tag_path(current_project, tag), method: :delete, data: { confirm: "Are you sure?\n\nProceeding will delete this tag and any associated tagging." }, class: 'text-error-hover' do %> - Delete - <% end %> -
+
+ <%= render 'table' %> +
<% else %>
diff --git a/config/routes.rb b/config/routes.rb index c12c96d15..ef5890d0e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -93,7 +93,7 @@ member { post :recover } end - resources :tags, except: [:show] + resources :tags, except: [:show], concerns: :multiple_destroy get 'search' => 'search#index' get 'trash' => 'revisions#trash' From 9d0b1e4e89964481c69bb4f054dd3c19e082bbc7 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Wed, 14 Sep 2022 18:06:21 +0600 Subject: [PATCH 005/275] Update Gemfile.lock --- Gemfile.lock | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index bc66c097d..e6ec39320 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -244,7 +244,8 @@ GEM addressable (~> 2.3) letter_opener (1.7.0) launchy (~> 2.2) - libv8-node (16.10.0.0-x86_64-darwin) + libv8-node (16.10.0.0) + libv8-node (16.10.0.0-x86_64-darwin-19) libv8-node (16.10.0.0-x86_64-linux) liquid (5.0.1) listen (3.4.1) @@ -262,7 +263,7 @@ GEM method_source (0.9.2) mini_mime (1.1.2) mini_portile2 (2.8.0) - mini_racer (0.6.3) + mini_racer (0.6.2) libv8-node (~> 16.10.0.0) minitest (5.16.2) mono_logger (1.1.1) @@ -492,7 +493,7 @@ GEM PLATFORMS ruby - x86_64-darwin + x86_64-darwin-19 x86_64-linux DEPENDENCIES From 403d8803de3680d5bc4920ba2b7ffcd9697eada9 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Wed, 14 Sep 2022 19:22:00 +0600 Subject: [PATCH 006/275] :wrench: --- app/controllers/issues_controller.rb | 2 +- app/controllers/tags_controller.rb | 4 ++- app/models/tag.rb | 36 +++++++++++++------ app/views/tags/_form.html.erb | 2 +- app/views/tags/_table.html.erb | 2 +- db/migrate/20220913101427_add_color_to_tag.rb | 10 ------ db/schema.rb | 1 - 7 files changed, 31 insertions(+), 26 deletions(-) delete mode 100644 db/migrate/20220913101427_add_color_to_tag.rb diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index bdaea5081..e02a0bf12 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -177,7 +177,7 @@ def set_or_initialize_issue # Load all the colour tags in the project (those that start with !). If none # exist, initialize a set of tags. def set_or_initialize_tags - @tags = current_project.tags.where('color like ?', '#%') + @tags = current_project.tags.where('name like ?', '!%') end def issue_params diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index d68dbbcd4..6519337cd 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -39,7 +39,9 @@ def destroy private def tag_params - modified_params = params.require(:tag).permit(:name, :color) + modified_params = params.require(:tag).permit(:display_name, :color) + modified_params[:name] = "#{modified_params[:color].gsub('#', '!')}_#{modified_params[:display_name]}" + modified_params.except(:color, :display_name) end def set_columns diff --git a/app/models/tag.rb b/app/models/tag.rb index 6528a620c..8821c4db3 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -14,6 +14,7 @@ class Tag < ApplicationRecord !6baed6_low !2ca02c_info ].freeze + NAME_REGEX = /\A(!\h{6})_[[:word:]]+?\z/ # -- Relationships ---------------------------------------------------------- has_many :taggings, dependent: :destroy @@ -22,14 +23,7 @@ class Tag < ApplicationRecord before_save :normalize_name # -- Validations ------------------------------------------------------------ - validates :name, - presence: true, - uniqueness: { case_sensitive: false }, - format: { with: /\A[a-zA-Z]+\z/ } - validates :color, - presence: true, - uniqueness: { case_sensitive: false }, - format: { with: /\A#\h{6}/ } + validates :name, presence: true, uniqueness: { case_sensitive: false } , format: { with: NAME_REGEX } # -- Scopes ----------------------------------------------------------------- @@ -40,9 +34,29 @@ class Tag < ApplicationRecord # -- Instance Methods ------------------------------------------------------- # Returns a version of the tag's name suitable to present to the user: - # * The name is titleized - def display_name - name.titleize + # * If the tag name contains color details, they are stripped + # * The result is titleized + def display_name() + return '' if self.name.nil? + + if self.name =~ /\A!(\h{6})(_([[:word:]]+))?\z/ + if $3 + out = $3 + else + out = $1 + end + else + out = self.name + end + return out.titleize + end + + # Strips the tag's name and returns the color details if present + # if no color information is found, returns a default value of #ccc + def color() + return '' if self.name.nil? + + name[NAME_REGEX, 1].try(:gsub, "!", "#") || "#555" end private diff --git a/app/views/tags/_form.html.erb b/app/views/tags/_form.html.erb index 24d7f4cc9..d260ca8b1 100644 --- a/app/views/tags/_form.html.erb +++ b/app/views/tags/_form.html.erb @@ -6,7 +6,7 @@
<%= simple_form_for @tag, url: url, method: method do |f| %>
diff --git a/app/views/layouts/tylium.html.erb b/app/views/layouts/tylium.html.erb index 8be1e67f0..c2ecfdc01 100644 --- a/app/views/layouts/tylium.html.erb +++ b/app/views/layouts/tylium.html.erb @@ -102,7 +102,7 @@ <%= render partial: 'styles_tylium/modal' %> <% end %> - <% if controller_name == 'tags' %> + <% if controller_name == 'tags' || controller_name == 'issues'%> <%= render partial: 'tags/modals/form' %> <% end %> diff --git a/app/views/tags/index.html.erb b/app/views/tags/index.html.erb index 6ac2d3cd8..488b0c996 100644 --- a/app/views/tags/index.html.erb +++ b/app/views/tags/index.html.erb @@ -2,9 +2,10 @@

Tags Management - <%= link_to new_project_tag_path(current_project), class: 'btn btn-primary', remote: true do %> - New Tag - <% end %> + <%= link_to new_project_tag_path(current_project), remote: true do %> + + Add new tag + <% end %>

<% if @tags.any? %> diff --git a/db/schema.rb b/db/schema.rb index 1b45143a4..12f2e0987 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,6 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. +ActiveRecord::Schema.define(version: 2021_03_16_202870) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false From da3d91f7b1dd1263aa9174babf86e0c7f713a77a Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Thu, 15 Sep 2022 17:18:01 +0600 Subject: [PATCH 009/275] :wrench: --- db/schema.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 12f2e0987..ed8d97bc6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -197,7 +197,6 @@ t.integer "taggings_count", default: 0, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.string "color", default: "#555555", null: false t.index ["name"], name: "index_tags_on_name" t.index ["taggings_count"], name: "index_tags_on_taggings_count" end From f235a14ec2ee3f4cb70535b16175e4b0d38e9004 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Mon, 19 Sep 2022 15:53:17 +0600 Subject: [PATCH 010/275] added specs --- app/controllers/tags_controller.rb | 14 +-- app/models/tag.rb | 4 +- app/views/tags/_table.html.erb | 2 - app/views/tags/index.html.erb | 17 +--- config/routes.rb | 2 +- spec/features/tags_spec.rb | 99 ++++++++++++++++++++++ spec/support/datatables_shared_examples.rb | 2 +- 7 files changed, 112 insertions(+), 28 deletions(-) create mode 100644 spec/features/tags_spec.rb diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 9abd26ff0..c8b5ea707 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -1,7 +1,6 @@ class TagsController < AuthenticatedController include ProjectScoped include ActivityTracking - include MultipleDestroy before_action :set_columns, only: :index load_and_authorize_resource @@ -13,7 +12,7 @@ def new; end def create if @tag.save track_created(@tag, project: @project) - redirect_to request.referer, notice: 'Tag created' + redirect_to request.referer, notice: 'Tag created.' else redirect_to request.referer, alert: @tag.errors.full_messages.join('; ') end @@ -24,16 +23,19 @@ def edit; end def update if @tag.update(tag_params) track_updated(@tag, project: @project) - redirect_to project_tags_path(current_project), notice: 'Tag updated' + redirect_to project_tags_path(current_project), notice: 'Tag updated.' else redirect_to project_tags_path(current_project), alert: @tag.errors.full_messages.join('; ') end end def destroy - @tag.destroy - track_destroyed(@tag, project: @project) - redirect_to project_tags_path(current_project), notice: 'Tag destroyed' + if @tag.destroy + track_destroyed(@tag) + redirect_to project_tags_path(current_project), alert: 'Tag deleted.' + else + redirect_to project_tags_path(current_project), alert: @tag.errors.full_messages.join('; ') + end end private diff --git a/app/models/tag.rb b/app/models/tag.rb index 2c5cec338..05a62a88f 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -26,10 +26,8 @@ class Tag < ApplicationRecord # -- Scopes ----------------------------------------------------------------- - # -- Class Methods ---------------------------------------------------------- - # -- Instance Methods ------------------------------------------------------- # Returns a version of the tag's name suitable to present to the user: @@ -55,7 +53,7 @@ def display_name() def color() return '' if self.name.nil? - name[/\A(!\h{6})_[[:word:]]+?\z/,1].try(:gsub, "!", "#") || "#555" + name[/\A(!\h{6})_[[:word:]]+?\z/, 1].try(:gsub, '!', '#') || '#555' end private diff --git a/app/views/tags/_table.html.erb b/app/views/tags/_table.html.erb index 4714d8f99..70c173ccc 100644 --- a/app/views/tags/_table.html.erb +++ b/app/views/tags/_table.html.erb @@ -6,7 +6,6 @@ data-local-storage-key="project.ce.<%= dom_id(current_project) %>.tags_datatable"> - Select <% @all_columns.each do |column| %> <%= column %> <% end %> @@ -17,7 +16,6 @@ <% @tags.each do |tag| %> <% cache [tag, @all_columns, 'tags-table'] do %> - <% @all_columns.each do |column| %> <% sort, display = diff --git a/app/views/tags/index.html.erb b/app/views/tags/index.html.erb index 488b0c996..e45336c4d 100644 --- a/app/views/tags/index.html.erb +++ b/app/views/tags/index.html.erb @@ -1,20 +1,7 @@ - +<% content_for :title, 'Tags' %>
-

Tags Management - - <%= link_to new_project_tag_path(current_project), remote: true do %> - - Add new tag - <% end %> - -

<% if @tags.any? %> -
- <%= render 'table' %> -
+ <%= render 'table' %> <% else %>
diff --git a/config/routes.rb b/config/routes.rb index ef5890d0e..c12c96d15 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -93,7 +93,7 @@ member { post :recover } end - resources :tags, except: [:show], concerns: :multiple_destroy + resources :tags, except: [:show] get 'search' => 'search#index' get 'trash' => 'revisions#trash' diff --git a/spec/features/tags_spec.rb b/spec/features/tags_spec.rb new file mode 100644 index 000000000..6717ff397 --- /dev/null +++ b/spec/features/tags_spec.rb @@ -0,0 +1,99 @@ +require 'rails_helper' + +describe 'Tag pages:' do + subject { page } + + before do + login_to_project_as_user + end + + describe 'tags#index', js: true do + let!(:tag) { create(:tag, name: '!9467bd_critical') } + before do + visit project_tags_path(current_project) + end + let(:default_columns) { ['Tag'] } + let(:hidden_columns) { ['Created', 'Updated'] } + let(:filter) { { keyword: tag.name, filter_count: 1 } } + + it_behaves_like 'a DataTable' + + describe 'can delete tag', js: true do + it 'deletes the Tag' do + page.find("tr#tag-#{tag.id}").hover + page.accept_confirm do + click_link('Delete') + end + expect(page).to have_text('Tag deleted.') + expect(Tag.exists?(tag.id)).to be false + end + end + + describe 'can edit tag', js: true do + it 'updates the Tag' do + page.find("tr#tag-#{tag.id}").hover + click_link('Edit') + fill_in :tag_display_name, with: 'test' + fill_in :tag_color, with: '#000000' + expect do + click_button 'Update Tag' + end.to change { tag.reload.name }.from('!9467bd_critical').to('!000000_test') + expect(page).to have_text('Tag updated.') + end + end + end + + describe 'create and manage tags' do + describe 'issue form', js: true do + before do + visit new_project_issue_path(current_project) + page.find('.dropdown-toggle span.tag').click + end + + it 'creates a tag' do + click_link 'Add new tag' + fill_in :tag_display_name, with: 'test' + fill_in :tag_color, with: '#000000' + expect do + click_button 'Create Tag' + end.to change { current_project.tags.count }.by(1) + expect(page).to have_text('Tag created.') + page.find('.dropdown-toggle span.tag').click + expect(page).to have_link('Test') + end + + it 'renders manage tag' do + click_link 'Manage Tags' + expect(current_path).to eq(project_tags_path(current_project)) + end + end + + describe 'issues index', js: true do + let!(:issue) { create(:issue) } + + before do + visit project_issues_path(current_project) + page.find('td.select-checkbox', match: :first).click + click_button('Tag') + end + + it 'creates a tag' do + click_link 'Add new tag' + fill_in :tag_display_name, with: 'ultra' + fill_in :tag_color, with: '#555555' + expect do + click_button 'Create Tag' + end.to change { current_project.tags.count }.by(1) + expect(page).to have_text('Tag created.') + page.find('td.select-checkbox', match: :first).click + click_button('Tag') + expect(page).to have_link('Ultra') + end + + it 'renders manage tag' do + click_link 'Manage Tags' + expect(current_path).to eq(project_tags_path(current_project)) + end + end + end +end diff --git a/spec/support/datatables_shared_examples.rb b/spec/support/datatables_shared_examples.rb index 70b4b89e1..84d6cd349 100644 --- a/spec/support/datatables_shared_examples.rb +++ b/spec/support/datatables_shared_examples.rb @@ -1,6 +1,6 @@ # let(:default_columns) { ['Title', 'Created', ...] } # let(:hidden_columns) { ['Description', 'Extra', ...] } -# let(:filter) { { keyword:'keyword', number_of_rows: 1 } } +# let(:filter) { { keyword:'keyword', filter_count: 1 } } shared_examples 'a DataTable' do describe 'column visibility', js: true do it 'displays default columns on load' do From 384776dc965948f3d2a1bd056893caafa3f01586 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Tue, 20 Sep 2022 12:29:04 +0200 Subject: [PATCH 011/275] use tags display name in the activity feed --- app/views/tags/activities/_tag.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/tags/activities/_tag.html.erb b/app/views/tags/activities/_tag.html.erb index c19fc14dd..1c7dc57f5 100644 --- a/app/views/tags/activities/_tag.html.erb +++ b/app/views/tags/activities/_tag.html.erb @@ -1,6 +1,6 @@ <% if tag %> <%= presenter.verb %> the - <%= link_to tag.name, edit_project_tag_path(current_project, tag) %> tag. + <%= link_to tag.display_name, edit_project_tag_path(current_project, tag) %> tag. <% else %> <% if activity.action == 'destroy' %> deleted a tag. From ad4132adda6b9e2052b5e35e1bd0215f6706b012 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Tue, 20 Sep 2022 13:12:44 +0200 Subject: [PATCH 012/275] Add styles for color picker --- app/assets/stylesheets/tylium/modules.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/assets/stylesheets/tylium/modules.scss b/app/assets/stylesheets/tylium/modules.scss index 035e8a23d..bc11f6d8b 100644 --- a/app/assets/stylesheets/tylium/modules.scss +++ b/app/assets/stylesheets/tylium/modules.scss @@ -86,6 +86,14 @@ white-space: nowrap; } +.color-picker { + padding: 0; + + &::-webkit-color-swatch-wrapper { + padding: 0; + } +} + .content { padding: 1em; From a65acdff4e313a2eac5fa3c9ec608ec7877a2839 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Tue, 20 Sep 2022 13:13:27 +0200 Subject: [PATCH 013/275] update form layout + consistency changes --- app/views/tags/_form.html.erb | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/app/views/tags/_form.html.erb b/app/views/tags/_form.html.erb index d260ca8b1..1e7fd0db9 100644 --- a/app/views/tags/_form.html.erb +++ b/app/views/tags/_form.html.erb @@ -4,18 +4,29 @@ Close modal
-<%= simple_form_for @tag, url: url, method: method do |f| %> +<%= form_for @tag, url: url, method: method do |f| %> <% end %> From a4035c8b5dbf77b9bffc5e5d06af9f0aab8b8002 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Tue, 20 Sep 2022 13:17:58 +0200 Subject: [PATCH 014/275] remove inline style attributes --- app/assets/javascripts/shared/datatable/tag.js | 2 +- app/views/issues/_tag_input.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/shared/datatable/tag.js b/app/assets/javascripts/shared/datatable/tag.js index 8f01bf4be..9ad23348b 100644 --- a/app/assets/javascripts/shared/datatable/tag.js +++ b/app/assets/javascripts/shared/datatable/tag.js @@ -27,7 +27,7 @@ DradisDatatable.prototype.setupTagButtons = function() { }.bind(this), }, { - text: $("Manage Tags").css("color", "#000000"), + text: $("Manage Tags"), action: function () { window.location.href = this.$table.data("tags-path"); }.bind(this), diff --git a/app/views/issues/_tag_input.html.erb b/app/views/issues/_tag_input.html.erb index b988faa6d..68d254031 100644 --- a/app/views/issues/_tag_input.html.erb +++ b/app/views/issues/_tag_input.html.erb @@ -31,7 +31,7 @@ Add new tag <% end %> - <%= link_to 'Manage Tags', project_tags_path(current_project), style: "color: #000000", class: 'dropdown-item' %> + <%= link_to 'Manage Tags', project_tags_path(current_project), class: 'dropdown-item' %>
From 8748fecba68f8aeed7e1bf87ad36fe4b1ca2c7d8 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Tue, 20 Sep 2022 13:21:23 +0200 Subject: [PATCH 015/275] remove extra `` --- app/assets/javascripts/shared/datatable/tag.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/shared/datatable/tag.js b/app/assets/javascripts/shared/datatable/tag.js index 9ad23348b..a68928819 100644 --- a/app/assets/javascripts/shared/datatable/tag.js +++ b/app/assets/javascripts/shared/datatable/tag.js @@ -11,7 +11,7 @@ DradisDatatable.prototype.setupTagButtons = function() { var tagColor = tag[1], tagFullName = tag[2], tagName = tag[0], - $tagElement = $(`${tagName}`).css('color', tagColor); + $tagElement = $(`${tagName}`).css('color', tagColor); tagButtons.push({ text: $tagElement, From 884a186ca8fcfe909569fc4591e08a4fa7483197 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Tue, 20 Sep 2022 14:28:36 +0200 Subject: [PATCH 016/275] fix icon spacing in issues#edit menu --- app/views/issues/_tag_input.html.erb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/issues/_tag_input.html.erb b/app/views/issues/_tag_input.html.erb index 68d254031..5780964df 100644 --- a/app/views/issues/_tag_input.html.erb +++ b/app/views/issues/_tag_input.html.erb @@ -10,7 +10,7 @@ <% else %> - + No tag <% end %> @@ -18,17 +18,17 @@ From da8aad165bf0556a38f5564505c7136933b37fda Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Tue, 20 Sep 2022 14:38:29 +0200 Subject: [PATCH 019/275] more spacing adjustments --- app/views/issues/_tag_input.html.erb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/issues/_tag_input.html.erb b/app/views/issues/_tag_input.html.erb index fb797adf9..2b28f5c80 100644 --- a/app/views/issues/_tag_input.html.erb +++ b/app/views/issues/_tag_input.html.erb @@ -5,12 +5,12 @@ From 1ff30dae893dde6bb609023664897428be8a5d16 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Tue, 20 Sep 2022 14:50:26 +0200 Subject: [PATCH 020/275] add header to tags#index with new tag link --- app/views/tags/index.html.erb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/views/tags/index.html.erb b/app/views/tags/index.html.erb index e45336c4d..2ed11ef93 100644 --- a/app/views/tags/index.html.erb +++ b/app/views/tags/index.html.erb @@ -1,5 +1,15 @@ <% content_for :title, 'Tags' %> -
+
+

Tags Management + +
+ <%= link_to new_project_tag_path(current_project), remote: :true do %> + New Tag + <% end %> +
+
+

+ <% if @tags.any? %> <%= render 'table' %> <% else %> From 5e1e151287446a457095eae01b488af9dcb1020f Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Tue, 20 Sep 2022 14:50:40 +0200 Subject: [PATCH 021/275] add icon spacing to table --- app/views/tags/_table.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/tags/_table.html.erb b/app/views/tags/_table.html.erb index 70c173ccc..332a1027a 100644 --- a/app/views/tags/_table.html.erb +++ b/app/views/tags/_table.html.erb @@ -24,7 +24,7 @@ [ tag.display_name, content_tag(:span, class: 'tag', style: "color: #{tag.color}") do - content_tag(:i, nil, class: 'icon fa fa-tag') + tag.display_name + content_tag(:i, nil, class: 'fa fa-tag fa-fw mr-1') + tag.display_name end ] when 'Created' From 4c40930d090a319d2885ff643683d84113c2d1af Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Tue, 20 Sep 2022 15:14:48 +0200 Subject: [PATCH 022/275] fix specs --- spec/features/tags_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/tags_spec.rb b/spec/features/tags_spec.rb index 6717ff397..ae0aa0cdf 100644 --- a/spec/features/tags_spec.rb +++ b/spec/features/tags_spec.rb @@ -63,7 +63,7 @@ end it 'renders manage tag' do - click_link 'Manage Tags' + click_link 'Manage tags' expect(current_path).to eq(project_tags_path(current_project)) end end From ccf70e52de4689c599b8c6dd0de02584019c12dd Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Wed, 21 Sep 2022 14:01:11 +0600 Subject: [PATCH 023/275] updated delete message and validation message --- app/models/tag.rb | 7 ++++++- app/views/tags/_table.html.erb | 2 +- app/views/tags/edit.js.erb | 4 ++-- app/views/tags/index.html.erb | 24 ++++++++++++------------ app/views/tags/modals/_form.html.erb | 4 ++-- app/views/tags/new.js.erb | 4 ++-- 6 files changed, 25 insertions(+), 20 deletions(-) diff --git a/app/models/tag.rb b/app/models/tag.rb index 05a62a88f..fbab8cd3c 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -22,7 +22,12 @@ class Tag < ApplicationRecord before_save :normalize_name # -- Validations ------------------------------------------------------------ - validates :name, presence: true, uniqueness: { case_sensitive: false } , format: { with: /\A(!\h{6})_[a-zA-Z]+?\z/ } + validates :name, + presence: true, + uniqueness: { case_sensitive: false } , + format: { + with: /\A(!\h{6})_[a-zA-Z]+?\z/, message: 'is invalid: Special character and number are not permitted' + } # -- Scopes ----------------------------------------------------------------- diff --git a/app/views/tags/_table.html.erb b/app/views/tags/_table.html.erb index 332a1027a..a93042c52 100644 --- a/app/views/tags/_table.html.erb +++ b/app/views/tags/_table.html.erb @@ -44,7 +44,7 @@ <%= link_to edit_project_tag_path(current_project, tag), remote: true do %> Edit <% end %> - <%= link_to project_tag_path(current_project, tag), method: :delete, data: { confirm: "Are you sure?\n\nProceeding will delete this tag and any associated tagging." }, class: 'text-error-hover' do %> + <%= link_to project_tag_path(current_project, tag), method: :delete, data: { confirm: "Are you sure?\n\nProceeding will untag any associated issues and delete this tag." }, class: 'text-error-hover' do %> Delete <% end %> diff --git a/app/views/tags/edit.js.erb b/app/views/tags/edit.js.erb index e0d0658a6..82a04421e 100644 --- a/app/views/tags/edit.js.erb +++ b/app/views/tags/edit.js.erb @@ -1,2 +1,2 @@ -$('#modal-tag-form').modal('show'); -$('#modal-tag-content').html("<%= j (render partial: 'form', locals: { header: 'Edit tag', url: project_tag_path(current_project, @tag), method: :patch }) %>"); +$('[data-behavior="modal-tag-form"]').modal('show'); +$('[data-behavior="modal-tag-content"]').html("<%= j (render partial: 'form', locals: { header: 'Edit tag', url: project_tag_path(current_project, @tag), method: :patch }) %>"); diff --git a/app/views/tags/index.html.erb b/app/views/tags/index.html.erb index 2ed11ef93..48d3ba37e 100644 --- a/app/views/tags/index.html.erb +++ b/app/views/tags/index.html.erb @@ -13,20 +13,20 @@ <% if @tags.any? %> <%= render 'table' %> <% else %> -
-
- <%= image_tag "icons/#{rand(9)}.svg" %> -
-
-
-

There are no tags created yet.

-

Create and use tags to manage your issues.

-
- More about tags +
+
+ <%= image_tag "icons/#{rand(9)}.svg" %> +
+
+
+

There are no tags created yet.

+

Use tags to flag and/or organize your issues.

+
-
<% end %>
diff --git a/app/views/tags/modals/_form.html.erb b/app/views/tags/modals/_form.html.erb index 72a7e4ee8..7cd82e750 100644 --- a/app/views/tags/modals/_form.html.erb +++ b/app/views/tags/modals/_form.html.erb @@ -1,5 +1,5 @@ diff --git a/app/views/tags/new.js.erb b/app/views/tags/new.js.erb index 76c954943..5ad72c093 100644 --- a/app/views/tags/new.js.erb +++ b/app/views/tags/new.js.erb @@ -1,2 +1,2 @@ -$('#modal-tag-form').modal('show'); -$('#modal-tag-content').html("<%= j (render partial: 'form', locals: { header: 'Add new tag', url: project_tags_path(current_project), method: :post }) %>"); +$('[data-behavior="modal-tag-form"]').modal('show'); +$('[data-behavior="modal-tag-content"]').html("<%= j (render partial: 'form', locals: { header: 'Add new tag', url: project_tags_path(current_project), method: :post }) %>"); From 65f6f6a987a620f56888c9f5bbc78bdf49ff25d9 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Wed, 21 Sep 2022 14:14:15 +0600 Subject: [PATCH 024/275] Update app/views/layouts/tylium.html.erb Co-authored-by: Matt Budz --- app/views/layouts/tylium.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/tylium.html.erb b/app/views/layouts/tylium.html.erb index c2ecfdc01..3106b726a 100644 --- a/app/views/layouts/tylium.html.erb +++ b/app/views/layouts/tylium.html.erb @@ -102,7 +102,7 @@ <%= render partial: 'styles_tylium/modal' %> <% end %> - <% if controller_name == 'tags' || controller_name == 'issues'%> + <% if controller_name == 'tags' || controller_name == 'issues' %> <%= render partial: 'tags/modals/form' %> <% end %> From b13c285ae98114b522433cf3ac75d028be7237a5 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Wed, 21 Sep 2022 16:08:25 +0600 Subject: [PATCH 025/275] added color code column --- app/controllers/tags_controller.rb | 2 +- app/views/tags/_table.html.erb | 2 ++ app/views/tags/activities/_tag.html.erb | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index c8b5ea707..e016c9f8b 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -48,7 +48,7 @@ def tag_params def set_columns default_field_names = ['Tag'].freeze - extra_field_names = ['Created', 'Updated'].freeze + extra_field_names = ['Color code', 'Created', 'Updated'].freeze @default_columns = default_field_names @all_columns = default_field_names | extra_field_names diff --git a/app/views/tags/_table.html.erb b/app/views/tags/_table.html.erb index a93042c52..2ce9d8b5a 100644 --- a/app/views/tags/_table.html.erb +++ b/app/views/tags/_table.html.erb @@ -27,6 +27,8 @@ content_tag(:i, nil, class: 'fa fa-tag fa-fw mr-1') + tag.display_name end ] + when 'Color code' + [tag.color, content_tag(:span, tag.color, style: "color: #{tag.color}")] when 'Created' [tag.created_at.to_i, local_time_ago(tag.created_at)] when 'Updated' diff --git a/app/views/tags/activities/_tag.html.erb b/app/views/tags/activities/_tag.html.erb index 1c7dc57f5..26f2ded0c 100644 --- a/app/views/tags/activities/_tag.html.erb +++ b/app/views/tags/activities/_tag.html.erb @@ -1,6 +1,6 @@ <% if tag %> <%= presenter.verb %> the - <%= link_to tag.display_name, edit_project_tag_path(current_project, tag) %> tag. + <%= link_to tag.display_name, project_tags_path(current_project) %> tag. <% else %> <% if activity.action == 'destroy' %> deleted a tag. From d93f3465950700d9c93b468d791efd657ef60bc4 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Wed, 21 Sep 2022 16:44:45 +0600 Subject: [PATCH 026/275] Update tags_spec.rb --- spec/features/tags_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/tags_spec.rb b/spec/features/tags_spec.rb index ae0aa0cdf..7695329f6 100644 --- a/spec/features/tags_spec.rb +++ b/spec/features/tags_spec.rb @@ -13,7 +13,7 @@ visit project_tags_path(current_project) end let(:default_columns) { ['Tag'] } - let(:hidden_columns) { ['Created', 'Updated'] } + let(:hidden_columns) { ['Color code', 'Created', 'Updated'] } let(:filter) { { keyword: tag.name, filter_count: 1 } } it_behaves_like 'a DataTable' From e2d34977e7f6fb9cfabeaa714086c95fd4af03f7 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Wed, 21 Sep 2022 18:46:15 +0600 Subject: [PATCH 027/275] updated delete and validation message --- app/models/tag.rb | 2 +- app/views/layouts/tylium.html.erb | 2 +- app/views/tags/_table.html.erb | 2 +- app/views/tags/edit.js.erb | 4 ++-- app/views/tags/new.js.erb | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/models/tag.rb b/app/models/tag.rb index fbab8cd3c..b34c07e2c 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -26,7 +26,7 @@ class Tag < ApplicationRecord presence: true, uniqueness: { case_sensitive: false } , format: { - with: /\A(!\h{6})_[a-zA-Z]+?\z/, message: 'is invalid: Special character and number are not permitted' + with: /\A(!\h{6})_[a-zA-Z]+?\z/, message: 'is invalid: Numbers and special characters are not permitted.' } # -- Scopes ----------------------------------------------------------------- diff --git a/app/views/layouts/tylium.html.erb b/app/views/layouts/tylium.html.erb index 3106b726a..6abcdceb5 100644 --- a/app/views/layouts/tylium.html.erb +++ b/app/views/layouts/tylium.html.erb @@ -102,7 +102,7 @@ <%= render partial: 'styles_tylium/modal' %> <% end %> - <% if controller_name == 'tags' || controller_name == 'issues' %> + <% if %w[tags issues].include?(controller_name) %> <%= render partial: 'tags/modals/form' %> <% end %> diff --git a/app/views/tags/_table.html.erb b/app/views/tags/_table.html.erb index 2ce9d8b5a..a735e557f 100644 --- a/app/views/tags/_table.html.erb +++ b/app/views/tags/_table.html.erb @@ -46,7 +46,7 @@ <%= link_to edit_project_tag_path(current_project, tag), remote: true do %> Edit <% end %> - <%= link_to project_tag_path(current_project, tag), method: :delete, data: { confirm: "Are you sure?\n\nProceeding will untag any associated issues and delete this tag." }, class: 'text-error-hover' do %> + <%= link_to project_tag_path(current_project, tag), method: :delete, data: { confirm: "Are you sure?\n\nProceeding will delete this tag. Any issues with this tag will be untagged." }, class: 'text-error-hover' do %> Delete <% end %> diff --git a/app/views/tags/edit.js.erb b/app/views/tags/edit.js.erb index 82a04421e..6e344e917 100644 --- a/app/views/tags/edit.js.erb +++ b/app/views/tags/edit.js.erb @@ -1,2 +1,2 @@ -$('[data-behavior="modal-tag-form"]').modal('show'); -$('[data-behavior="modal-tag-content"]').html("<%= j (render partial: 'form', locals: { header: 'Edit tag', url: project_tag_path(current_project, @tag), method: :patch }) %>"); +$('[data-behavior~=modal-tag-form]').modal('show'); +$('[data-behavior~=modal-tag-content]').html("<%= j (render partial: 'form', locals: { header: 'Edit tag', url: project_tag_path(current_project, @tag), method: :patch }) %>"); diff --git a/app/views/tags/new.js.erb b/app/views/tags/new.js.erb index 5ad72c093..65db351b5 100644 --- a/app/views/tags/new.js.erb +++ b/app/views/tags/new.js.erb @@ -1,2 +1,2 @@ -$('[data-behavior="modal-tag-form"]').modal('show'); -$('[data-behavior="modal-tag-content"]').html("<%= j (render partial: 'form', locals: { header: 'Add new tag', url: project_tags_path(current_project), method: :post }) %>"); +$('[data-behavior~=modal-tag-form]').modal('show'); +$('[data-behavior~=modal-tag-content]').html("<%= j (render partial: 'form', locals: { header: 'Add new tag', url: project_tags_path(current_project), method: :post }) %>"); From 7678f7c479d3196fd276df91d55e7c21eda6ef25 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Fri, 28 Oct 2022 16:13:48 +0600 Subject: [PATCH 028/275] added hint --- app/views/tags/_form.html.erb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/tags/_form.html.erb b/app/views/tags/_form.html.erb index 1e7fd0db9..81e9794a4 100644 --- a/app/views/tags/_form.html.erb +++ b/app/views/tags/_form.html.erb @@ -13,6 +13,7 @@ Name * <% end %> <%= f.text_field :display_name, required: true, class: 'form-control' %> + A-Z only. No special charaters or numbers.
From 2d43fb0b00c75859374bde8265202d0418182dc4 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Fri, 28 Oct 2022 16:17:49 +0600 Subject: [PATCH 029/275] Update _form.html.erb --- app/views/tags/_form.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/tags/_form.html.erb b/app/views/tags/_form.html.erb index 81e9794a4..54b47ed21 100644 --- a/app/views/tags/_form.html.erb +++ b/app/views/tags/_form.html.erb @@ -13,7 +13,7 @@ Name * <% end %> <%= f.text_field :display_name, required: true, class: 'form-control' %> - A-Z only. No special charaters or numbers. + A-Z only. No special characters or numbers.
From 6c195cc5f76b45aee0afb9cbbf47acf7d9e244f6 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Thu, 3 Nov 2022 18:01:44 +0600 Subject: [PATCH 030/275] Update CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index a92cd56d5..ea7fd09f5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ [v#.#.#] ([month] [YYYY]) - Notes: remove category selection from form UI. + - Tags: implemented CRUD to manage - [entity]: - [future tense verb] [feature] - Upgraded gems: From 8191773747d90e31adc47782eaf7a7e30c65a862 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Thu, 3 Nov 2022 18:28:39 +0600 Subject: [PATCH 031/275] Update tags_controller.rb --- app/controllers/tags_controller.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index e016c9f8b..8a970443e 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -10,8 +10,9 @@ def index; end def new; end def create + @tag.project = current_project if @tag.save - track_created(@tag, project: @project) + track_created(@tag) redirect_to request.referer, notice: 'Tag created.' else redirect_to request.referer, alert: @tag.errors.full_messages.join('; ') @@ -22,7 +23,7 @@ def edit; end def update if @tag.update(tag_params) - track_updated(@tag, project: @project) + track_updated(@tag) redirect_to project_tags_path(current_project), notice: 'Tag updated.' else redirect_to project_tags_path(current_project), alert: @tag.errors.full_messages.join('; ') From c55c7c49acaa753a63fd638fe5fe0be572c7cd27 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Thu, 3 Nov 2022 18:32:14 +0600 Subject: [PATCH 032/275] Update tags_controller.rb --- app/controllers/tags_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 8a970443e..2d8a4afbd 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -5,7 +5,9 @@ class TagsController < AuthenticatedController before_action :set_columns, only: :index load_and_authorize_resource - def index; end + def index + @tags = current_project.tags + end def new; end From 302cdd3b3d1f663cc5b72bd18c59c1cdbb10eeee Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Thu, 3 Nov 2022 19:53:04 +0600 Subject: [PATCH 033/275] updated changelog --- CHANGELOG | 2 +- app/controllers/tags_controller.rb | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ea7fd09f5..8bc681810 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,6 @@ [v#.#.#] ([month] [YYYY]) - Notes: remove category selection from form UI. - - Tags: implemented CRUD to manage + - Tags: Add tag management - [entity]: - [future tense verb] [feature] - Upgraded gems: diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 2d8a4afbd..99e22641e 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -12,7 +12,6 @@ def index def new; end def create - @tag.project = current_project if @tag.save track_created(@tag) redirect_to request.referer, notice: 'Tag created.' From 8a036c5ee6dc1984b439ab791516afbb6444fbe9 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Tue, 8 Nov 2022 12:09:09 +0600 Subject: [PATCH 034/275] fixes random spec fail --- spec/factories/tags.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/factories/tags.rb b/spec/factories/tags.rb index 0023eea09..11af3491f 100644 --- a/spec/factories/tags.rb +++ b/spec/factories/tags.rb @@ -1,5 +1,5 @@ FactoryBot.define do factory :tag do - sequence(:name){ |n| "!00000#{n}_tag" } + name { "!#{Random.bytes(3).unpack1('H*')}_tag" } end end From 61139cf33e0cfc6f6ac62d74f5f692245a4fa0a6 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Wed, 16 Nov 2022 14:57:21 +0600 Subject: [PATCH 035/275] consistent naming and fixed specs --- app/controllers/tags_controller.rb | 10 +++++----- app/models/tag.rb | 4 ---- app/views/tags/_form.html.erb | 6 +++--- app/views/tags/_table.html.erb | 4 ++-- spec/factories/tags.rb | 2 +- spec/features/tags_spec.rb | 10 +++++----- 6 files changed, 16 insertions(+), 20 deletions(-) diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 99e22641e..a352b6ae2 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -43,14 +43,14 @@ def destroy private def tag_params - modified_params = params.require(:tag).permit(:display_name, :color) - modified_params[:name] = "#{modified_params[:color].gsub('#', '!')}_#{modified_params[:display_name]}" - modified_params.except(:color, :display_name) + modified_params = params.require(:tag).permit(:name, :color) + modified_params[:name] = "#{modified_params[:color].gsub('#', '!')}_#{modified_params[:name]}" + modified_params.except(:color) end def set_columns - default_field_names = ['Tag'].freeze - extra_field_names = ['Color code', 'Created', 'Updated'].freeze + default_field_names = ['Name'].freeze + extra_field_names = ['Color', 'Created', 'Updated'].freeze @default_columns = default_field_names @all_columns = default_field_names | extra_field_names diff --git a/app/models/tag.rb b/app/models/tag.rb index b34c07e2c..026205719 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -39,8 +39,6 @@ class Tag < ApplicationRecord # * If the tag name contains color details, they are stripped # * The result is titleized def display_name() - return '' if self.name.nil? - if self.name =~ /\A!(\h{6})(_([[:word:]]+))?\z/ if $3 out = $3 @@ -56,8 +54,6 @@ def display_name() # Strips the tag's name and returns the color details if present # if no color information is found, returns a default value of #ccc def color() - return '' if self.name.nil? - name[/\A(!\h{6})_[[:word:]]+?\z/, 1].try(:gsub, '!', '#') || '#555' end diff --git a/app/views/tags/_form.html.erb b/app/views/tags/_form.html.erb index 54b47ed21..ce33cc657 100644 --- a/app/views/tags/_form.html.erb +++ b/app/views/tags/_form.html.erb @@ -9,10 +9,10 @@
- <%= f.label :display_name, class: 'col-form-label' do %> + <%= f.label :name, class: 'col-form-label' do %> Name * <% end %> - <%= f.text_field :display_name, required: true, class: 'form-control' %> + <%= f.text_field :name, value: @tag.new_record? ? '' : @tag.display_name, required: true, class: 'form-control' %> A-Z only. No special characters or numbers.
@@ -21,7 +21,7 @@ <%= f.label :color, class: 'col-form-label d-block' do %> Color * <% end %> - <%= f.color_field :color, required: true, class: 'form-control color-picker' %> + <%= f.color_field :color, value: @tag.new_record? ? '' : @tag.color, required: true, class: 'form-control color-picker' %>
diff --git a/app/views/tags/_table.html.erb b/app/views/tags/_table.html.erb index a735e557f..0ff913461 100644 --- a/app/views/tags/_table.html.erb +++ b/app/views/tags/_table.html.erb @@ -20,14 +20,14 @@ <% sort, display = case column - when 'Tag' + when 'Name' [ tag.display_name, content_tag(:span, class: 'tag', style: "color: #{tag.color}") do content_tag(:i, nil, class: 'fa fa-tag fa-fw mr-1') + tag.display_name end ] - when 'Color code' + when 'Color' [tag.color, content_tag(:span, tag.color, style: "color: #{tag.color}")] when 'Created' [tag.created_at.to_i, local_time_ago(tag.created_at)] diff --git a/spec/factories/tags.rb b/spec/factories/tags.rb index 11af3491f..79cb523f9 100644 --- a/spec/factories/tags.rb +++ b/spec/factories/tags.rb @@ -1,5 +1,5 @@ FactoryBot.define do factory :tag do - name { "!#{Random.bytes(3).unpack1('H*')}_tag" } + sequence(:name) { |n| "!#{"%06d" % n}_tag" } end end diff --git a/spec/features/tags_spec.rb b/spec/features/tags_spec.rb index 7695329f6..9584de9a2 100644 --- a/spec/features/tags_spec.rb +++ b/spec/features/tags_spec.rb @@ -12,8 +12,8 @@ before do visit project_tags_path(current_project) end - let(:default_columns) { ['Tag'] } - let(:hidden_columns) { ['Color code', 'Created', 'Updated'] } + let(:default_columns) { ['Name'] } + let(:hidden_columns) { ['Color', 'Created', 'Updated'] } let(:filter) { { keyword: tag.name, filter_count: 1 } } it_behaves_like 'a DataTable' @@ -33,7 +33,7 @@ it 'updates the Tag' do page.find("tr#tag-#{tag.id}").hover click_link('Edit') - fill_in :tag_display_name, with: 'test' + fill_in :tag_name, with: 'test' fill_in :tag_color, with: '#000000' expect do click_button 'Update Tag' @@ -52,7 +52,7 @@ it 'creates a tag' do click_link 'Add new tag' - fill_in :tag_display_name, with: 'test' + fill_in :tag_name, with: 'test' fill_in :tag_color, with: '#000000' expect do click_button 'Create Tag' @@ -79,7 +79,7 @@ it 'creates a tag' do click_link 'Add new tag' - fill_in :tag_display_name, with: 'ultra' + fill_in :tag_name, with: 'ultra' fill_in :tag_color, with: '#555555' expect do click_button 'Create Tag' From 5f2d03abff9560d1a868c3882bfe39916a7bc271 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Wed, 16 Nov 2022 15:32:43 +0600 Subject: [PATCH 036/275] Update CHANGELOG --- CHANGELOG | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 901f5bf93..805ab96cd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,6 @@ v4.6.0 (November 2022) - Kit Import: allow import of kit with no templates - Notes: remove category selection from form UI. - Tags: Add tag management - - [entity]: - - [future tense verb] [feature] - Upgraded gems: - nokogiri - New integrations: From 4b47f5e70623e2901a9e5eeb6c360224ad95c0f4 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Tue, 22 Nov 2022 13:42:07 +0600 Subject: [PATCH 037/275] mocked project in tag.rb --- app/controllers/tags_controller.rb | 1 + app/models/tag.rb | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index a352b6ae2..934bf079d 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -12,6 +12,7 @@ def index def new; end def create + @tag.project = current_project if @tag.save track_created(@tag) redirect_to request.referer, notice: 'Tag created.' diff --git a/app/models/tag.rb b/app/models/tag.rb index 026205719..1ec718dfe 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -18,6 +18,14 @@ class Tag < ApplicationRecord # -- Relationships ---------------------------------------------------------- has_many :taggings, dependent: :destroy + def project + # dummy project; this makes Tags's interface more similar to how it is + # in Pro and makes it easier to deal with tag in URL helpers + @project ||= Project.new + end + + def project=(new_project); end + # -- Callbacks -------------------------------------------------------------- before_save :normalize_name From 85bff3a3305333a7c29e99257bb83479b5872077 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Tue, 22 Nov 2022 14:08:58 +0600 Subject: [PATCH 038/275] Update tags_spec.rb --- spec/features/tags_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/tags_spec.rb b/spec/features/tags_spec.rb index 9584de9a2..1a4044165 100644 --- a/spec/features/tags_spec.rb +++ b/spec/features/tags_spec.rb @@ -8,7 +8,7 @@ end describe 'tags#index', js: true do - let!(:tag) { create(:tag, name: '!9467bd_critical') } + let!(:tag) { create(:tag, name: '!9467bd_critical' , project: current_project) } before do visit project_tags_path(current_project) end @@ -69,7 +69,7 @@ end describe 'issues index', js: true do - let!(:issue) { create(:issue) } + let!(:issue) { create(:issue, node: current_project.issue_library) } before do visit project_issues_path(current_project) From 1dbeeda6156479f421118b470625a68c1ae878f5 Mon Sep 17 00:00:00 2001 From: Alex Rupom Hasdak Date: Tue, 22 Nov 2022 18:06:45 +0600 Subject: [PATCH 039/275] fixes rubocop warning --- config/routes.rb | 2 +- spec/models/tag_spec.rb | 12 ++++++------ spec/models/tagging_spec.rb | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index c12c96d15..028724557 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -110,7 +110,7 @@ post '/upload/parse' => 'upload#parse' if Rails.env.development? - get '/styles' => 'styles_tylium#index' + get '/styles' => 'styles_tylium#index' end end diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb index a0d796a68..35ada91ae 100644 --- a/spec/models/tag_spec.rb +++ b/spec/models/tag_spec.rb @@ -2,19 +2,19 @@ describe Tag do describe '#display_name' do - it "capitalizes the first letter of the tag" do + it 'capitalizes the first letter of the tag' do tag = create(:tag, name: '!0000ff_blue') expect(tag.display_name).to eq('Blue') end - it "removes the color part of the tag name if present" do + it 'removes the color part of the tag name if present' do tag = create(:tag, name: '!0000ff_blue') expect(tag.display_name).to eq('Blue') end end describe '#save' do - it "normalizes the name before persisting" do + it 'normalizes the name before persisting' do tag = Tag.create!(name: '!0000ff_BlUe') tag.reload expect(tag.name).to eq('!0000ff_blue') @@ -22,18 +22,18 @@ end describe '#valid?' do - it "requires a name" do + it 'requires a name' do tag = Tag.new() expect(tag.valid?).to be false expect(tag.errors[:name].count).to eq(2) end - it "requires a unique name" do + it 'requires a unique name' do Tag.create!(name: '!0000ff_blue') expect(Tag.create(name: '!0000ff_blue').errors[:name].count).to eq(1) end - it "requires to match format" do + it 'requires to match format' do expect(Tag.create(name: '!ab_d').errors[:name].count).to eq(1) end end diff --git a/spec/models/tagging_spec.rb b/spec/models/tagging_spec.rb index 35eeae99f..45a2aa7c8 100644 --- a/spec/models/tagging_spec.rb +++ b/spec/models/tagging_spec.rb @@ -5,7 +5,7 @@ let(:tag) { Tag.create!(name: '!9467bd_critical') } let(:taggable) { create(:node) } - it "ensures tags are unique for any given taggable" do + it 'ensures tags are unique for any given taggable' do tagging = Tagging.new tagging.tag = tag tagging.taggable = taggable From 436cae9e19631134e057e25b4394c73138ff0b62 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Wed, 23 Nov 2022 16:10:19 +0800 Subject: [PATCH 040/275] Add author field for notes, issues, and evidence --- CHANGELOG | 3 +-- .../views/dradis/ce/api/v1/evidence/_evidence.json.jbuilder | 2 +- .../app/views/dradis/ce/api/v1/issues/_issue.json.jbuilder | 2 +- .../app/views/dradis/ce/api/v1/notes/_note.json.jbuilder | 2 +- .../spec/requests/dradis/ce/api/v1/evidence_spec.rb | 1 + .../dradis-api/spec/requests/dradis/ce/api/v1/issues_spec.rb | 4 ++++ .../dradis-api/spec/requests/dradis/ce/api/v1/notes_spec.rb | 1 + 7 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1df645685..2580cfe07 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,8 +19,7 @@ - [report type]: - [future tense verb] [reporting enhancement] - REST/JSON API enhancements: - - [API entity]: - - [future tense verb] [API enhancement] + - Author: Add author field for notes, issues, and evidence - Security Fixes: - High: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description] - Medium: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description] diff --git a/engines/dradis-api/app/views/dradis/ce/api/v1/evidence/_evidence.json.jbuilder b/engines/dradis-api/app/views/dradis/ce/api/v1/evidence/_evidence.json.jbuilder index b4a762481..52769068e 100644 --- a/engines/dradis-api/app/views/dradis/ce/api/v1/evidence/_evidence.json.jbuilder +++ b/engines/dradis-api/app/views/dradis/ce/api/v1/evidence/_evidence.json.jbuilder @@ -1,4 +1,4 @@ -json.(evidence, :id, :content, :fields) +json.(evidence, :id, :content, :fields, :author) json.issue do |json| json.id evidence.issue_id json.title evidence.issue.title diff --git a/engines/dradis-api/app/views/dradis/ce/api/v1/issues/_issue.json.jbuilder b/engines/dradis-api/app/views/dradis/ce/api/v1/issues/_issue.json.jbuilder index bfd503d1d..fcea86d9e 100644 --- a/engines/dradis-api/app/views/dradis/ce/api/v1/issues/_issue.json.jbuilder +++ b/engines/dradis-api/app/views/dradis/ce/api/v1/issues/_issue.json.jbuilder @@ -1,2 +1,2 @@ -json.(issue, :id, :title, :fields, :text, :created_at, :updated_at) +json.(issue, :id, :title, :fields, :text, :author, :created_at, :updated_at) json.tags issue.tags, :color, :display_name diff --git a/engines/dradis-api/app/views/dradis/ce/api/v1/notes/_note.json.jbuilder b/engines/dradis-api/app/views/dradis/ce/api/v1/notes/_note.json.jbuilder index 2634d52b0..a4b918084 100644 --- a/engines/dradis-api/app/views/dradis/ce/api/v1/notes/_note.json.jbuilder +++ b/engines/dradis-api/app/views/dradis/ce/api/v1/notes/_note.json.jbuilder @@ -1 +1 @@ -json.(note, :id, :category_id, :title, :fields, :text) +json.(note, :id, :category_id, :title, :fields, :text, :author) diff --git a/engines/dradis-api/spec/requests/dradis/ce/api/v1/evidence_spec.rb b/engines/dradis-api/spec/requests/dradis/ce/api/v1/evidence_spec.rb index ea710b23f..8ab22e9b4 100644 --- a/engines/dradis-api/spec/requests/dradis/ce/api/v1/evidence_spec.rb +++ b/engines/dradis-api/spec/requests/dradis/ce/api/v1/evidence_spec.rb @@ -110,6 +110,7 @@ it "returns JSON information about the evidence" do retrieved_evidence = JSON.parse(response.body) expect(retrieved_evidence["id"]).to eq @evidence.id + expect(retrieved_evidence['author']).to eq @evidence.author expect(retrieved_evidence["fields"].keys).to match_array( @evidence.local_fields.keys + %w(fizz foo) ) diff --git a/engines/dradis-api/spec/requests/dradis/ce/api/v1/issues_spec.rb b/engines/dradis-api/spec/requests/dradis/ce/api/v1/issues_spec.rb index a5f8ae9be..019820e34 100644 --- a/engines/dradis-api/spec/requests/dradis/ce/api/v1/issues_spec.rb +++ b/engines/dradis-api/spec/requests/dradis/ce/api/v1/issues_spec.rb @@ -92,6 +92,10 @@ tag = @issue.tags.first expect(@retrieved_issue['tags']).to eq [{'color' => tag.color, 'display_name' => tag.display_name}] end + + it 'includes the author' do + expect(@retrieved_issue['author']).to eq @issue.author + end end describe 'POST /api/issues' do diff --git a/engines/dradis-api/spec/requests/dradis/ce/api/v1/notes_spec.rb b/engines/dradis-api/spec/requests/dradis/ce/api/v1/notes_spec.rb index 09bfde05f..89a0ccd43 100644 --- a/engines/dradis-api/spec/requests/dradis/ce/api/v1/notes_spec.rb +++ b/engines/dradis-api/spec/requests/dradis/ce/api/v1/notes_spec.rb @@ -104,6 +104,7 @@ expect(retrieved_note['id']).to eq @note.id expect(retrieved_note['title']).to eq 'My note' expect(retrieved_note['category_id']).to eq category.id + expect(retrieved_note['author']).to eq @note.author expect(retrieved_note['fields'].keys).to match_array( %w[foo fizz Title] ) From 582bcc9364c552afbe1e9d383e78413bdd4df7e7 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Wed, 21 Dec 2022 16:50:02 +0100 Subject: [PATCH 041/275] :alpha constructor declarations + linting --- .../javascripts/tylium/modules/sidebar.js | 51 ++++++++++++------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/app/assets/javascripts/tylium/modules/sidebar.js b/app/assets/javascripts/tylium/modules/sidebar.js index 6f77009f7..1e5afb7e9 100644 --- a/app/assets/javascripts/tylium/modules/sidebar.js +++ b/app/assets/javascripts/tylium/modules/sidebar.js @@ -1,76 +1,91 @@ -(function($, window) { +(function ($, window) { function Sidebar($sidebar) { this.$sidebar = $sidebar; - this.$navbarBrand = $sidebar.siblings('[data-behavior~=navbar]').find('[data-behavior~=navbar-brand]'); - this.$viewContent = $sidebar.siblings('[data-behavior~=view-content]'); - this.storageKey = $sidebar.data('storage-key'); this.minBreakpoint = 992; + this.$navbarBrand = $sidebar + .siblings('[data-behavior~=navbar]') + .find('[data-behavior~=navbar-brand]'); + this.storageKey = $sidebar.data('storage-key'); + this.$viewContent = $sidebar.siblings('[data-behavior~=view-content]'); this.init(); } Sidebar.prototype = { - init: function() { + init: function () { this.toggle(this.isSidebarOpen()); var that = this; - $('[data-behavior~=sidebar-toggle]').on('click', function(e) { + $('[data-behavior~=sidebar-toggle]').on('click', function (e) { if ($(this).is('[data-behavior~=nodes-tree]')) { if (window.innerWidth < that.minBreakpoint) { $(this).attr('data-behavior', 'nodes-tree sidebar-toggle'); } else { - $(this).attr('data-behavior', 'nodes-tree sidebar-toggle open-only'); + $(this).attr( + 'data-behavior', + 'nodes-tree sidebar-toggle open-only' + ); } } - if (!(that.isSidebarOpen() && $(this).is('[data-behavior~=open-only]'))) { + if ( + !(that.isSidebarOpen() && $(this).is('[data-behavior~=open-only]')) + ) { that.toggle(!that.isSidebarOpen()); } }); if (window.innerWidth < that.minBreakpoint) { - $('[data-behavior~=sidebar-node-link]').on('click', function() { + $('[data-behavior~=sidebar-node-link]').on('click', function () { that.close(); }); } }, - changeState: function(state) { + changeState: function (state) { localStorage.setItem(this.storageKey, state); Turbolinks.clearCache(); }, - close: function() { + close: function () { this.$navbarBrand.css('padding-left', 0); this.$sidebar .removeClass('sidebar-expanded') .addClass('sidebar-collapsed'); - this.$viewContent.css({'left': this.$sidebar.css('width'), 'width': 'calc(100vw - ' + this.$sidebar.css('width') + ')'}); + this.$viewContent.css({ + left: this.$sidebar.css('width'), + width: 'calc(100vw - ' + this.$sidebar.css('width') + ')', + }); this.changeState(false); }, - isSidebarOpen: function() { + isSidebarOpen: function () { return JSON.parse(localStorage.getItem(this.storageKey)); }, - open: function() { + open: function () { this.$sidebar .removeClass('sidebar-collapsed') .addClass('sidebar-expanded'); - this.$viewContent.css({'left': this.$sidebar.css('width'), 'width': 'calc(100vw - ' + this.$sidebar.css('width') + ')'}); + this.$viewContent.css({ + left: this.$sidebar.css('width'), + width: 'calc(100vw - ' + this.$sidebar.css('width') + ')', + }); if (window.innerWidth > this.minBreakpoint) { - var navbarBrandOffset = parseFloat(this.$navbarBrand.css('padding-left').slice(0,-2)) + parseFloat(this.$sidebar.css('width').slice(0,-2) / 1.65); + var navbarBrandOffset = + parseFloat(this.$navbarBrand.css('padding-left').slice(0, -2)) + + parseFloat(this.$sidebar.css('width').slice(0, -2) / 1.65); this.$navbarBrand.css('padding-left', navbarBrandOffset); } this.changeState(true); }, - toggle: function(openSidebar) { + toggle: function (openSidebar) { if (openSidebar) { this.open(); } else { this.close(); } - } + }, }; window.Sidebar = Sidebar; From 1b9980b61d1659c8dd674e6131efa05b4018d0de Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Wed, 21 Dec 2022 16:50:49 +0100 Subject: [PATCH 042/275] scope client event listener --- app/assets/javascripts/tylium/modules/sidebar.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/tylium/modules/sidebar.js b/app/assets/javascripts/tylium/modules/sidebar.js index 1e5afb7e9..a56fd870b 100644 --- a/app/assets/javascripts/tylium/modules/sidebar.js +++ b/app/assets/javascripts/tylium/modules/sidebar.js @@ -6,6 +6,7 @@ .siblings('[data-behavior~=navbar]') .find('[data-behavior~=navbar-brand]'); this.storageKey = $sidebar.data('storage-key'); + this.$toggleLink = $sidebar.find($('[data-behavior~=sidebar-toggle]')); this.$viewContent = $sidebar.siblings('[data-behavior~=view-content]'); this.init(); @@ -17,7 +18,7 @@ var that = this; - $('[data-behavior~=sidebar-toggle]').on('click', function (e) { + this.$toggleLink.on('click', function (e) { if ($(this).is('[data-behavior~=nodes-tree]')) { if (window.innerWidth < that.minBreakpoint) { $(this).attr('data-behavior', 'nodes-tree sidebar-toggle'); From 40346f4b7838579fe4702fa55a8b1b277597820e Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Wed, 21 Dec 2022 17:05:57 +0100 Subject: [PATCH 043/275] guard main-sidebar js-triggered style changes --- .../javascripts/tylium/modules/sidebar.js | 34 +++++++++++-------- app/views/layouts/tylium.html.erb | 4 ++- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/app/assets/javascripts/tylium/modules/sidebar.js b/app/assets/javascripts/tylium/modules/sidebar.js index a56fd870b..6a86b7734 100644 --- a/app/assets/javascripts/tylium/modules/sidebar.js +++ b/app/assets/javascripts/tylium/modules/sidebar.js @@ -48,14 +48,17 @@ Turbolinks.clearCache(); }, close: function () { - this.$navbarBrand.css('padding-left', 0); this.$sidebar .removeClass('sidebar-expanded') .addClass('sidebar-collapsed'); - this.$viewContent.css({ - left: this.$sidebar.css('width'), - width: 'calc(100vw - ' + this.$sidebar.css('width') + ')', - }); + + if (this.$sidebar.is($('[data-behavior~=main-sidebar]'))) { + this.$navbarBrand.css('padding-left', 0); + this.$viewContent.css({ + left: this.$sidebar.css('width'), + width: 'calc(100vw - ' + this.$sidebar.css('width') + ')', + }); + } this.changeState(false); }, @@ -66,16 +69,19 @@ this.$sidebar .removeClass('sidebar-collapsed') .addClass('sidebar-expanded'); - this.$viewContent.css({ - left: this.$sidebar.css('width'), - width: 'calc(100vw - ' + this.$sidebar.css('width') + ')', - }); - if (window.innerWidth > this.minBreakpoint) { - var navbarBrandOffset = - parseFloat(this.$navbarBrand.css('padding-left').slice(0, -2)) + - parseFloat(this.$sidebar.css('width').slice(0, -2) / 1.65); - this.$navbarBrand.css('padding-left', navbarBrandOffset); + if (this.$sidebar.is($('[data-behavior~=main-sidebar]'))) { + this.$viewContent.css({ + left: this.$sidebar.css('width'), + width: 'calc(100vw - ' + this.$sidebar.css('width') + ')', + }); + + if (window.innerWidth > this.minBreakpoint) { + var navbarBrandOffset = + parseFloat(this.$navbarBrand.css('padding-left').slice(0, -2)) + + parseFloat(this.$sidebar.css('width').slice(0, -2) / 1.65); + this.$navbarBrand.css('padding-left', navbarBrandOffset); + } } this.changeState(true); diff --git a/app/views/layouts/tylium.html.erb b/app/views/layouts/tylium.html.erb index d70fbf58c..b3ea64dde 100644 --- a/app/views/layouts/tylium.html.erb +++ b/app/views/layouts/tylium.html.erb @@ -35,7 +35,9 @@
<% if content_for?(:sidebar) %> -
+
<%= yield :sidebar %>
From d7bb6f0524dfd6b1ef63ebfb7c41a7a51bc09957 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Wed, 21 Dec 2022 17:06:06 +0100 Subject: [PATCH 044/275] add secondary-sidebar collapsed styles --- .../tylium/modules/_secondary_sidebar.scss | 56 ++++++++++++++----- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss b/app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss index c2eeeb280..065de5fd0 100644 --- a/app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss +++ b/app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss @@ -37,7 +37,7 @@ cursor: default; margin-top: 0.5rem; padding-right: 2.5rem; - + a { color: $lightColor; } @@ -52,13 +52,12 @@ } .options { - a { color: $lightColor; - + &:hover { color: $white; - } + } } .dropdown { @@ -72,7 +71,7 @@ max-width: 180px; overflow: hidden; text-overflow: ellipsis; - + &:active, &:hover { color: $linkColorHover; @@ -83,7 +82,6 @@ } .note-list { - .active > a { color: $white !important; } @@ -93,7 +91,7 @@ padding: 0.5rem; border-radius: 3px; transition: all 0.2s ease-in-out; - + a { color: $lightColor; } @@ -101,13 +99,13 @@ &.active a { color: $white; } - + .list-item-actions { padding-top: 0.3rem; text-align: right; visibility: hidden; transition: visibility 0.1s ease-in-out; - + a { padding: 0 4px; } @@ -121,24 +119,24 @@ border-radius: 5px; transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out; } - + .list-item-action-delete:hover { color: $white; background-color: $red; } - + .list-item-action-edit:hover { color: $white; background-color: $green; } } - + &:hover { background-color: lighten($sidebarActiveColor, 3%); - + a { color: $lightColor; - + &:hover { color: $white; } @@ -149,7 +147,7 @@ } } } - + .summary-link { color: $lightColor; @@ -158,4 +156,32 @@ } } } + + @media (min-width: 992px) { + &.sidebar-collapsed { + $collapsed-width: 1.25rem; + + max-width: $collapsed-width; + padding: 1rem 0.25rem; + z-index: 1051; + + .inner-content, + .summary-link { + display: none; + } + + & + .secondary-sidebar-content { + max-width: calc(100% - #{$collapsed-width}); + flex: 0 0 100%; + } + + .sidebar-toggle-icon { + transform: rotate(180deg); + } + } + } + + .sidebar-toggle-link { + color: $lightColor; + } } From 35139cae8ec16c0b49735f588ffbb510e9394e17 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Wed, 21 Dec 2022 17:17:05 +0100 Subject: [PATCH 045/275] spacing --- app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss b/app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss index 065de5fd0..cb43e07e7 100644 --- a/app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss +++ b/app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss @@ -159,10 +159,10 @@ @media (min-width: 992px) { &.sidebar-collapsed { - $collapsed-width: 1.25rem; + $collapsed-width: 1.75rem; max-width: $collapsed-width; - padding: 1rem 0.25rem; + padding: 0.75rem 0.5rem; z-index: 1051; .inner-content, From 4c17df7b0e71919c63dfff45e08a8a68918c2ba4 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Wed, 21 Dec 2022 17:30:47 +0100 Subject: [PATCH 046/275] update issues secondary sidebar --- app/views/issues/_sidebar.html.erb | 37 +++++++++++++++++++----------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/app/views/issues/_sidebar.html.erb b/app/views/issues/_sidebar.html.erb index 2b50f091f..d9e06fd51 100644 --- a/app/views/issues/_sidebar.html.erb +++ b/app/views/issues/_sidebar.html.erb @@ -1,20 +1,29 @@
- <%= content_tag :div, id: 'issue_summary_link', class: current_page?(main_app.project_issues_path(current_project)) ? 'p-2 mb-2 active' : 'p-2 mb-2' do %> - <%= link_to main_app.project_issues_path(current_project), class: 'summary-link' do %> - - Issues Summary +
+ <%= content_tag :div, class: class_names(active: current_page?(main_app.project_issues_path(current_project))) do %> + <%= link_to main_app.project_issues_path(current_project), class: 'summary-link' do %> + + Issues Summary + <% end %> <% end %> - <% end %> + + + + Toggle secondary sidebar + +
-<%= render 'shared/sidebar_collection', - category_id: nil, - collection: @issues, - name: 'Issues', - new_path: main_app.new_project_issue_path(current_project) -%> +
+ <%= render 'shared/sidebar_collection', + category_id: nil, + collection: @issues, + name: 'Issues', + new_path: main_app.new_project_issue_path(current_project) + %> -<%= render 'issues/import_box' %> + <%= render 'issues/import_box' %> - -<%= render partial: 'attachments/attachment_box', locals: { attachments_node: current_project.plugin_uploads_node } %> + + <%= render partial: 'attachments/attachment_box', locals: { attachments_node: current_project.plugin_uploads_node } %> +
From b4b1284f7c0b6ab1d4b945e8a9f3307c1cd3d627 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Wed, 21 Dec 2022 17:30:54 +0100 Subject: [PATCH 047/275] update cards secondary sidebar --- app/views/cards/_sidebar.html.erb | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/app/views/cards/_sidebar.html.erb b/app/views/cards/_sidebar.html.erb index 74f4091e6..119fd6526 100644 --- a/app/views/cards/_sidebar.html.erb +++ b/app/views/cards/_sidebar.html.erb @@ -1,19 +1,26 @@
- <%= content_tag :div, id: 'issue_summary_link', class: current_page?(main_app.project_board_path(current_project, @board)) ? 'p-2 mb-2 active' : 'p-2 mb-2' do %> - <%= link_to project_board_path(current_project, @board), class: 'summary-link' do %> - Back to board view +
+ <%= content_tag :div, class: class_names(active: current_page?(main_app.project_board_path(current_project, @board))) do %> + <%= link_to project_board_path(current_project, @board), class: 'summary-link' do %> + Back to board view + <% end %> <% end %> - <% end %> + + + + Toggle secondary sidebar + +
- -<%= - render 'shared/sidebar_collection', +
+ <%= render 'shared/sidebar_collection', category_id: nil, collection: @sorted_cards, name: 'Tasks', new_path: new_project_board_list_card_path(current_project, @board, @list, @card) -%> + %> - -<%= render partial: 'attachments/attachment_box', locals: { attachments_node: current_project.plugin_uploads_node } %> + + <%= render partial: 'attachments/attachment_box', locals: { attachments_node: current_project.plugin_uploads_node } %> +
From d08aeb5d27e01df908e846318bd274bd34cedad4 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Wed, 21 Dec 2022 17:30:59 +0100 Subject: [PATCH 048/275] update nodes secondary sidebar --- app/views/nodes/_sidebar.html.erb | 35 +++++++++++++++++++------------ 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/app/views/nodes/_sidebar.html.erb b/app/views/nodes/_sidebar.html.erb index e92a52644..13db3d200 100644 --- a/app/views/nodes/_sidebar.html.erb +++ b/app/views/nodes/_sidebar.html.erb @@ -1,18 +1,26 @@ <% content_for :sidebar do %> - - <%= render 'shared/sidebar_collection', +
+ + <%= render 'shared/sidebar_collection', category_id: Category.default.id, collection: @sorted_notes, index_path: project_node_path(current_project, @node, tab: 'notes-tab'), @@ -20,8 +28,8 @@ new_path: new_project_node_note_path(@node.project, @node) %> - - <%= render 'shared/sidebar_collection', + + <%= render 'shared/sidebar_collection', category_id: Category.issue.id, collection: @sorted_evidence, index_path: project_node_path(current_project, @node, tab: 'evidence-tab'), @@ -29,6 +37,7 @@ new_path: new_project_node_evidence_path(@node.project, @node) %> - - <%= render partial: 'attachments/attachment_box', locals: { attachments_node: @node } %> + + <%= render partial: 'attachments/attachment_box', locals: { attachments_node: @node } %> +
<% end %> From 293eafdf355e10e1d230261d28aec1765501e83a Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Wed, 21 Dec 2022 17:31:55 +0100 Subject: [PATCH 049/275] Update CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 8c23a6099..7500d19f5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,7 @@ - Issues: Display the results from importers in a datatable - Tylium: - Add breadcrumbs to Revision History view + - Add secondary sidebar toggling functionality - Remove `Recent Activity` tabs and add `View History` link to the dots menu - Upgraded gems: - nokogiri, pg, rails-html-sanitizer, sinatra From 7b0ea3a6ad7c75166d0e3c7962bc87263a24e95c Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Wed, 21 Dec 2022 17:42:20 +0100 Subject: [PATCH 050/275] remove z-index --- app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss b/app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss index cb43e07e7..70feb5ca2 100644 --- a/app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss +++ b/app/assets/stylesheets/tylium/modules/_secondary_sidebar.scss @@ -163,7 +163,6 @@ max-width: $collapsed-width; padding: 0.75rem 0.5rem; - z-index: 1051; .inner-content, .summary-link { From 1cc1dc88fddd28ab62a2cb5f840eda61a4751e57 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Thu, 22 Dec 2022 15:35:23 +0100 Subject: [PATCH 051/275] consistency --- app/views/cards/_sidebar.html.erb | 2 +- app/views/issues/_sidebar.html.erb | 2 +- app/views/nodes/_sidebar.html.erb | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/cards/_sidebar.html.erb b/app/views/cards/_sidebar.html.erb index 119fd6526..3e2f76dfe 100644 --- a/app/views/cards/_sidebar.html.erb +++ b/app/views/cards/_sidebar.html.erb @@ -2,7 +2,7 @@
<%= content_tag :div, class: class_names(active: current_page?(main_app.project_board_path(current_project, @board))) do %> <%= link_to project_board_path(current_project, @board), class: 'summary-link' do %> - Back to board view + Board Summary <% end %> <% end %> diff --git a/app/views/issues/_sidebar.html.erb b/app/views/issues/_sidebar.html.erb index d9e06fd51..9f04d73b9 100644 --- a/app/views/issues/_sidebar.html.erb +++ b/app/views/issues/_sidebar.html.erb @@ -2,7 +2,7 @@
<%= content_tag :div, class: class_names(active: current_page?(main_app.project_issues_path(current_project))) do %> <%= link_to main_app.project_issues_path(current_project), class: 'summary-link' do %> - + Issues Summary <% end %> <% end %> diff --git a/app/views/nodes/_sidebar.html.erb b/app/views/nodes/_sidebar.html.erb index 13db3d200..6d637e708 100644 --- a/app/views/nodes/_sidebar.html.erb +++ b/app/views/nodes/_sidebar.html.erb @@ -4,9 +4,9 @@ <%= content_tag :div, class: class_names(active: current_page?(main_app.project_node_path(@node.project, @node))) do %> <%= link_to project_node_path(@node.project, @node), class: 'summary-link' do %> <% if @node.type_id == Node::Types::HOST %> - Host summary + Host Summary <% else%> - Node summary + Node Summary <% end %> <% end %> <% end %> From 5c757ba70dfe5a8fe19c8b0ea21f64e45c231ce5 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Thu, 22 Dec 2022 16:19:40 +0100 Subject: [PATCH 052/275] open sidebar by default on first run --- app/assets/javascripts/tylium/modules/sidebar.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/tylium/modules/sidebar.js b/app/assets/javascripts/tylium/modules/sidebar.js index 6a86b7734..546a6b795 100644 --- a/app/assets/javascripts/tylium/modules/sidebar.js +++ b/app/assets/javascripts/tylium/modules/sidebar.js @@ -63,7 +63,11 @@ this.changeState(false); }, isSidebarOpen: function () { - return JSON.parse(localStorage.getItem(this.storageKey)); + if (JSON.parse(localStorage.getItem(this.storageKey)) === null) { + return true; + } else { + return JSON.parse(localStorage.getItem(this.storageKey)); + } }, open: function () { this.$sidebar From 0cf82971a901de8579c3202cd602890aa7735555 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Thu, 22 Dec 2022 16:56:23 +0100 Subject: [PATCH 053/275] fix specs --- spec/features/node_pages_spec.rb | 171 +++++++++++++++---------------- 1 file changed, 83 insertions(+), 88 deletions(-) diff --git a/spec/features/node_pages_spec.rb b/spec/features/node_pages_spec.rb index d6652853a..c8eb3f680 100644 --- a/spec/features/node_pages_spec.rb +++ b/spec/features/node_pages_spec.rb @@ -1,18 +1,18 @@ require 'rails_helper' -describe "node pages" do +describe 'node pages' do subject { page } before do login_to_project_as_user end - describe "creating new nodes" do + describe 'creating new nodes' do context "when a project doesn't have any nodes yet" do - it "says so in the sidebar" do + it 'says so in the sidebar' do visit project_path(current_project) - within ".main-sidebar" do - should have_selector ".empty-state", text: "You don't have any nodes yet" + within '.main-sidebar' do + should have_selector '.empty-state', text: "You don't have any nodes yet" end end end @@ -20,30 +20,29 @@ describe "clicking the '+' button in the 'Nodes' sidebar", js: true do before do visit project_path(current_project) - find('[data-behavior~=sidebar-toggle]', match: :first).click find('.add-node > a').click end - let(:submit_form) { click_button "Add" } + let(:submit_form) { click_button 'Add' } - it "shows a modal for adding a top-level node" do + it 'shows a modal for adding a top-level node' do expect(page).to have_field :branch_node_label end describe "submitting the 'new top-level node' form" do - it "creates and shows the new node" do - fill_in :branch_node_label, with: "My awesome node" - expect{submit_form}.to change{Node.count}.by(1) - expect(page).to have_content "Successfully created node." + it 'creates and shows the new node' do + fill_in :branch_node_label, with: 'My awesome node' + expect { submit_form }.to change { Node.count }.by(1) + expect(page).to have_content 'Successfully created node.' new_node = Node.last expect(current_path).to eq project_node_path(new_node.project, new_node) end end - include_examples "creates an Activity", :create, Node + include_examples 'creates an Activity', :create, Node - example "adding multiple root nodes" do - choose "Add multiple" + example 'adding multiple root nodes' do + choose 'Add multiple' expect(page).to have_no_field :branch_node_label expect(page).to have_field :branch_nodes_list @@ -56,7 +55,7 @@ LIST expect do - click_button "Add" + click_button 'Add' end.to change { current_project.nodes.in_tree.count }.by(3) \ .and change { ActiveJob::Base.queue_adapter.enqueued_jobs.size }.by(3) @@ -77,24 +76,24 @@ ).to include *Array.new(3, 'Node') expect(current_project.nodes.last(3).map(&:label)).to match_array([ - "node 1", - "node_2", - "node with trailing whitespace", + 'node 1', + 'node_2', + 'node with trailing whitespace', ]) # redirects to project root: expect(page).to have_selector 'h3', text: /PROJECT SUMMARY/i end - example "adding multiple root host nodes" do - choose "Add multiple" + example 'adding multiple root host nodes' do + choose 'Add multiple' fill_in :branch_nodes_list, with: "foo\nbar" - select "Host", from: :branch_nodes_icon + select 'Host', from: :branch_nodes_icon expect do - click_button "Add" - end.to change{ current_project.nodes.in_tree.count }.by(2) + click_button 'Add' + end.to change { current_project.nodes.in_tree.count }.by(2) expect( current_project.nodes.in_tree.last(2).all? { |n| n.type_id == Node::Types::HOST } @@ -102,17 +101,17 @@ end end - describe "adding child nodes to an existing node", :js do + describe 'adding child nodes to an existing node', :js do before do visit project_node_path(node.project, node) find('[data-behavior~=nodes-more-dropdown]').click - click_link "Add subnode" + click_link 'Add subnode' end let(:node) { create(:node, project: current_project) } - example "adding a single node" do - fill_in "child_node_label", with: "My new node" + example 'adding a single node' do + fill_in 'child_node_label', with: 'My new node' expect do click_button 'Add' end.to change { node.children.count }.by(1) @@ -125,11 +124,11 @@ ) new_node = node.children.last - expect(new_node.label).to eq "My new node" + expect(new_node.label).to eq 'My new node' end - example "adding multiple nodes" do - choose "Add multiple" + example 'adding multiple nodes' do + choose 'Add multiple' expect(page).to have_no_field :child_node_label expect(page).to have_field :child_nodes_list @@ -163,49 +162,48 @@ ).to eq Array.new(3, 'Node') expect(node.children.pluck(:label)).to match_array([ - "node 1", - "node_2", - "node with trailing whitespace", + 'node 1', + 'node_2', + 'node with trailing whitespace', ]) # redirects to parent node's page expect(page).to have_selector 'ol.breadcrumb > li.active', text: node.label end - example "adding multiple nodes - submitting a blank textarea" do - choose "Add multiple" + example 'adding multiple nodes - submitting a blank textarea' do + choose 'Add multiple' fill_in :child_nodes_list, with: " \n \n \n \n " - click_button "Add" - expect(page).to have_content "Please add at least one node" + click_button 'Add' + expect(page).to have_content 'Please add at least one node' end end end - describe "clicking 'rename' on a node", js: true do before do - @node = create(:node, label: "My node", project: current_project) + @node = create(:node, label: 'My node', project: current_project) visit project_node_path(@node.project, @node) find('[data-behavior~=nodes-more-dropdown]').click - click_link "Rename" + click_link 'Rename' end - let(:submit_form) { click_button "Rename" } + let(:submit_form) { click_button 'Rename' } - it "shows a modal to rename the node" do + it 'shows a modal to rename the node' do should have_content /Rename My node node/i should have_field :node_new_label end - describe "submitting a new name" do - before { fill_in :node_new_label, with: "new node name" } + describe 'submitting a new name' do + before { fill_in :node_new_label, with: 'new node name' } it "updates the node's name" do submit_form - expect(@node.reload.label).to eq "new node name" + expect(@node.reload.label).to eq 'new node name' end - it "creates an Activity" do + it 'creates an Activity' do expect { submit_form }.to have_enqueued_job(ActivityTrackingJob).with( action: 'update', project_id: current_project.id, @@ -216,55 +214,53 @@ end end - describe "submitting an invalid name" do - before { fill_in :node_new_label, with: "" } + describe 'submitting an invalid name' do + before { fill_in :node_new_label, with: '' } it "doesn't update the node's name" do - expect{ submit_form }.not_to change{ @node.reload.label } + expect { submit_form }.not_to change { @node.reload.label } end include_examples "doesn't create an Activity" end end - describe "clicking 'Delete' on a node", js: true do before do - @node = create(:node, label: "My node", project: current_project) + @node = create(:node, label: 'My node', project: current_project) visit project_node_path(@node.project, @node) find('[data-behavior~=nodes-more-dropdown]').click - click_link "Delete" + click_link 'Delete' end - it "shows a modal to rename the node" do + it 'shows a modal to rename the node' do should have_content( 'Are you sure you want to delete the "My node" node from your project?' ) end - describe "confirming the deletion" do + describe 'confirming the deletion' do let(:submit_form) do - within "#modal_delete_node" do - click_link "Delete" + within '#modal_delete_node' do + click_link 'Delete' expect(current_path).to eq project_path(current_project) end end - it "deletes the node" do + it 'deletes the node' do node_id = @node.id submit_form expect(current_project.nodes.find_by_id(node_id)).to be_nil end let(:model) { @node } - include_examples "creates an Activity", :destroy + include_examples 'creates an Activity', :destroy end end - - describe "show page" do + describe 'show page' do before do - @properties = { foo: "bar", fizz: "buzz" } + @properties = { foo: 'bar', fizz: 'buzz' } @node = create(:node, project: current_project, properties: @properties) extra_setup visit project_node_path(@node.project, @node) @@ -272,7 +268,7 @@ let(:extra_setup) { nil } - context "when the node has activities" do + context 'when the node has activities' do include ActivityMacros let(:extra_setup) do @@ -292,7 +288,7 @@ @other_activity = create(:update_activity, trackable: @other_node) end - it "lists them in the activity feed" do + it 'lists them in the activity feed' do within activity_feed do @activities.each do |activity| should have_activity(activity) @@ -302,11 +298,11 @@ end end - context "when the node has no recent activity" do + context 'when the node has no recent activity' do it { should have_content "You don't have any activities yet" } end - context "when the node has nested notes or evidence" do + context 'when the node has nested notes or evidence' do let(:extra_setup) do @note = create(:note, node: @node, text: "#[Title]#\nMy note") @issue = create(:issue, node: current_project.issue_library) @@ -316,9 +312,9 @@ @other_evidence = create(:evidence, node: other_node) end - it "lists them in the sidebar" do - within ".secondary-sidebar" do - should have_selector "#note_#{@note.id}_link", text: "My note" + it 'lists them in the sidebar' do + within '.secondary-sidebar' do + should have_selector "#note_#{@note.id}_link", text: 'My note' should have_selector "#evidence_#{@evidence.id}_link" should_not have_selector "#note_#{@other_note.id}_link" should_not have_selector "#evidence_#{@other_evidence.id}_link" @@ -328,56 +324,55 @@ it "shows the node's properties" do @properties.each do |key, value| - should have_selector "h4", text: key.to_s.capitalize - should have_selector "p", text: value + should have_selector 'h4', text: key.to_s.capitalize + should have_selector 'p', text: value end end end - - describe "edit page" do + describe 'edit page' do before do - @properties = { foo: "bar", fizz: "buzz" } - @node = create(:node, label: "My node", project: current_project, properties: @properties) + @properties = { foo: 'bar', fizz: 'buzz' } + @node = create(:node, label: 'My node', project: current_project, properties: @properties) extra_setup visit edit_project_node_path(@node.project, @node) end let(:extra_setup) { nil } - let(:submit_form) { click_button "Update Node" } + let(:submit_form) { click_button 'Update Node' } it "has a form to edit the node's properties" do should have_field :node_raw_properties expect( - find("#node_raw_properties").text.squish + find('#node_raw_properties').text.squish ).to eq @node.raw_properties.squish end - describe "when this node is not a root node" do + describe 'when this node is not a root node' do let(:extra_setup) do - @node.parent = create(:node, label: "Parent", project: current_project) + @node.parent = create(:node, label: 'Parent', project: current_project) @node.save! end - it "shows the current node in the sidebar node tree", js: true do # bug fix + it 'shows the current node in the sidebar node tree', js: true do # bug fix find('.tree-header').click - within ".main-sidebar .nodes-nav" do + within '.main-sidebar .nodes-nav' do click_link class: 'toggle' should have_content 'My node' end end end - describe "submitting the form with valid information" do + describe 'submitting the form with valid information' do before do # fill_in :node_raw_properties doesn't work for some reason :( - find("#node_raw_properties").set('{ "hello" : "hola" }') + find('#node_raw_properties').set('{ "hello" : "hola" }') end it "updates the node's properties" do submit_form - expect(@node.reload.properties).to eq({ "hello" => "hola" }) + expect(@node.reload.properties).to eq({ 'hello' => 'hola' }) end it "redirects to the node's show page" do @@ -386,17 +381,17 @@ end let(:model) { @node } - include_examples "creates an Activity", :update + include_examples 'creates an Activity', :update end - describe "submitting the form with invalid information" do + describe 'submitting the form with invalid information' do before do # invalid JSON: - find("#node_raw_properties").set('{ "hello" "hola" }') + find('#node_raw_properties').set('{ "hello" "hola" }') end it "doesn't update the node's properties" do - expect{ submit_form }.not_to change{ @node.reload.properties } + expect { submit_form }.not_to change { @node.reload.properties } end # UPGRADE: fix specs From d71a644c85d2c6c0e7010db49bc2cc146ddfd049 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Mon, 2 Jan 2023 11:32:12 +0100 Subject: [PATCH 054/275] fix bug when toggling sidebar + resizing the view --- app/assets/javascripts/tylium/modules/sidebar.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/tylium/modules/sidebar.js b/app/assets/javascripts/tylium/modules/sidebar.js index 546a6b795..bcf3a67d4 100644 --- a/app/assets/javascripts/tylium/modules/sidebar.js +++ b/app/assets/javascripts/tylium/modules/sidebar.js @@ -42,6 +42,14 @@ that.close(); }); } + + $(window).on('resize', function () { + if (window.innerWidth < that.minBreakpoint) { + that.$navbarBrand.css('padding-left', 0); + } + + that.isSidebarOpen() ? that.open() : that.close(); + }); }, changeState: function (state) { localStorage.setItem(this.storageKey, state); @@ -81,9 +89,9 @@ }); if (window.innerWidth > this.minBreakpoint) { - var navbarBrandOffset = - parseFloat(this.$navbarBrand.css('padding-left').slice(0, -2)) + - parseFloat(this.$sidebar.css('width').slice(0, -2) / 1.65); + var navbarBrandOffset = parseFloat( + this.$sidebar.css('width').slice(0, -2) / 1.65 + ); this.$navbarBrand.css('padding-left', navbarBrandOffset); } } From 12e4623159faacd3998818e2491c95a14cf57e3b Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Mon, 2 Jan 2023 11:35:40 +0100 Subject: [PATCH 055/275] syntax tweaks --- app/assets/javascripts/tylium/modules/sidebar.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/tylium/modules/sidebar.js b/app/assets/javascripts/tylium/modules/sidebar.js index bcf3a67d4..c893a555e 100644 --- a/app/assets/javascripts/tylium/modules/sidebar.js +++ b/app/assets/javascripts/tylium/modules/sidebar.js @@ -18,7 +18,7 @@ var that = this; - this.$toggleLink.on('click', function (e) { + this.$toggleLink.on('click', function () { if ($(this).is('[data-behavior~=nodes-tree]')) { if (window.innerWidth < that.minBreakpoint) { $(this).attr('data-behavior', 'nodes-tree sidebar-toggle'); @@ -64,7 +64,7 @@ this.$navbarBrand.css('padding-left', 0); this.$viewContent.css({ left: this.$sidebar.css('width'), - width: 'calc(100vw - ' + this.$sidebar.css('width') + ')', + width: `calc(100vw - ${this.$sidebar.css('width')})`, }); } @@ -85,7 +85,7 @@ if (this.$sidebar.is($('[data-behavior~=main-sidebar]'))) { this.$viewContent.css({ left: this.$sidebar.css('width'), - width: 'calc(100vw - ' + this.$sidebar.css('width') + ')', + width: `calc(100vw - ${this.$sidebar.css('width')})`, }); if (window.innerWidth > this.minBreakpoint) { @@ -99,11 +99,7 @@ this.changeState(true); }, toggle: function (openSidebar) { - if (openSidebar) { - this.open(); - } else { - this.close(); - } + openSidebar ? this.open() : this.close(); }, }; From 2d310220ee4d3cdb23156d7e95b2823fe6fef81d Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Tue, 10 Jan 2023 11:32:53 +0100 Subject: [PATCH 056/275] Stop `@issues` collection from being overwritten --- app/controllers/issues_controller.rb | 4 ++-- app/views/issues/import.html.erb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 0c40e4848..00171cb3d 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -110,14 +110,14 @@ def destroy def import importer = IssueImporter.new(params) results = importer.query - @issues = issues_from_import_records(results) + @import_issues = issues_from_import_records(results) @plugin = importer.plugin @filter = importer.filter @query = params[:query] @default_columns = ['Title', 'Tags'] - @all_columns = @default_columns | (@issues.map(&:fields).map(&:keys).uniq.flatten - ['AddonTags']) + @all_columns = @default_columns | (@import_issues.map(&:fields).map(&:keys).uniq.flatten - ['AddonTags']) end private diff --git a/app/views/issues/import.html.erb b/app/views/issues/import.html.erb index 144b367a4..8aaab734f 100644 --- a/app/views/issues/import.html.erb +++ b/app/views/issues/import.html.erb @@ -16,7 +16,7 @@
- <% if @issues.any? %> + <% if @import_issues.any? %> - <% @issues.each do |issue| %> + <% @import_issues.each do |issue| %> <% @all_columns.each do |column| %> <% From 7268d30cae14bbd352bd333ee4b2c808241d50ff Mon Sep 17 00:00:00 2001 From: Caitlin Henry Date: Wed, 18 Jan 2023 13:56:08 -0500 Subject: [PATCH 057/275] omit schema from rubocop runs --- .rubocop.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.rubocop.yml b/.rubocop.yml index 9980e5b72..74f64e20d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -6,6 +6,7 @@ AllCops: Exclude: - '**/templates/**/*' - '**/vendor/**/*' + - 'db/schema.rb' # Prefer &&/|| over and/or. Style/AndOr: From f0dd53fc07abaa916933324a0366808ef8b40e4b Mon Sep 17 00:00:00 2001 From: Caitlin Henry Date: Thu, 19 Jan 2023 09:10:09 -0500 Subject: [PATCH 058/275] test changing schema --- db/schema.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index ed8d97bc6..9f22e0508 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_03_16_202870) do +ActiveRecord::Schema.define(version: 2023_01_19_140709) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false @@ -47,6 +47,7 @@ t.string "action", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.text "properties" t.index ["created_at"], name: "index_activities_on_created_at" t.index ["trackable_id", "trackable_type"], name: "index_activities_on_trackable_id_and_trackable_type" t.index ["user_id"], name: "index_activities_on_user_id" From 92eb8f99f09a1554de0ca8ec78729c6f14ae20a2 Mon Sep 17 00:00:00 2001 From: Caitlin Henry Date: Thu, 19 Jan 2023 09:12:33 -0500 Subject: [PATCH 059/275] revert schema changes used for testing --- db/schema.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 9f22e0508..8bb22a9b7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -47,7 +47,6 @@ t.string "action", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.text "properties" t.index ["created_at"], name: "index_activities_on_created_at" t.index ["trackable_id", "trackable_type"], name: "index_activities_on_trackable_id_and_trackable_type" t.index ["user_id"], name: "index_activities_on_user_id" From 50bf7da54cd896d2ee586eb457a659f815fab066 Mon Sep 17 00:00:00 2001 From: Caitlin Henry Date: Thu, 19 Jan 2023 09:45:13 -0500 Subject: [PATCH 060/275] revert schema version from testing --- db/schema.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 8bb22a9b7..ed8d97bc6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_01_19_140709) do +ActiveRecord::Schema.define(version: 2021_03_16_202870) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false From 72667d6724e24ee43a3b14c3dfe4b3cc0925eb07 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Wed, 25 Jan 2023 16:16:49 +0800 Subject: [PATCH 061/275] Bump rails to 6.1.7.1 --- Gemfile | 2 +- Gemfile.lock | 137 ++++++++++++++++++++++++++------------------------- 2 files changed, 71 insertions(+), 68 deletions(-) diff --git a/Gemfile b/Gemfile index 493d86032..2f41262b1 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '3.1.2' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 6.1.6.1' +gem 'rails', '~> 6.1.7.1' # Use SCSS for stylesheets gem 'sass-rails', '~> 6.0' diff --git a/Gemfile.lock b/Gemfile.lock index f2f660504..9735a7de0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,60 +8,60 @@ GEM remote: https://rubygems.org/ specs: RedCloth (4.3.2) - actioncable (6.1.6.1) - actionpack (= 6.1.6.1) - activesupport (= 6.1.6.1) + actioncable (6.1.7.2) + actionpack (= 6.1.7.2) + activesupport (= 6.1.7.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.6.1) - actionpack (= 6.1.6.1) - activejob (= 6.1.6.1) - activerecord (= 6.1.6.1) - activestorage (= 6.1.6.1) - activesupport (= 6.1.6.1) + actionmailbox (6.1.7.2) + actionpack (= 6.1.7.2) + activejob (= 6.1.7.2) + activerecord (= 6.1.7.2) + activestorage (= 6.1.7.2) + activesupport (= 6.1.7.2) mail (>= 2.7.1) - actionmailer (6.1.6.1) - actionpack (= 6.1.6.1) - actionview (= 6.1.6.1) - activejob (= 6.1.6.1) - activesupport (= 6.1.6.1) + actionmailer (6.1.7.2) + actionpack (= 6.1.7.2) + actionview (= 6.1.7.2) + activejob (= 6.1.7.2) + activesupport (= 6.1.7.2) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.1.6.1) - actionview (= 6.1.6.1) - activesupport (= 6.1.6.1) + actionpack (6.1.7.2) + actionview (= 6.1.7.2) + activesupport (= 6.1.7.2) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.6.1) - actionpack (= 6.1.6.1) - activerecord (= 6.1.6.1) - activestorage (= 6.1.6.1) - activesupport (= 6.1.6.1) + actiontext (6.1.7.2) + actionpack (= 6.1.7.2) + activerecord (= 6.1.7.2) + activestorage (= 6.1.7.2) + activesupport (= 6.1.7.2) nokogiri (>= 1.8.5) - actionview (6.1.6.1) - activesupport (= 6.1.6.1) + actionview (6.1.7.2) + activesupport (= 6.1.7.2) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.6.1) - activesupport (= 6.1.6.1) + activejob (6.1.7.2) + activesupport (= 6.1.7.2) globalid (>= 0.3.6) - activemodel (6.1.6.1) - activesupport (= 6.1.6.1) - activerecord (6.1.6.1) - activemodel (= 6.1.6.1) - activesupport (= 6.1.6.1) - activestorage (6.1.6.1) - actionpack (= 6.1.6.1) - activejob (= 6.1.6.1) - activerecord (= 6.1.6.1) - activesupport (= 6.1.6.1) + activemodel (6.1.7.2) + activesupport (= 6.1.7.2) + activerecord (6.1.7.2) + activemodel (= 6.1.7.2) + activesupport (= 6.1.7.2) + activestorage (6.1.7.2) + actionpack (= 6.1.7.2) + activejob (= 6.1.7.2) + activerecord (= 6.1.7.2) + activesupport (= 6.1.7.2) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.6.1) + activesupport (6.1.7.2) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -112,7 +112,7 @@ GEM activesupport (>= 3.0.0) railties (>= 3.0.0) thor (>= 0.14.6) - concurrent-ruby (1.1.10) + concurrent-ruby (1.2.0) crass (1.0.6) database_cleaner (1.8.2) diff-lcs (1.5.0) @@ -185,7 +185,7 @@ GEM dradis-zap (4.6.0) dradis-plugins (~> 4.0) nokogiri (~> 1.3) - erubi (1.10.0) + erubi (1.12.0) execjs (2.7.0) factory_bot (6.2.1) activesupport (>= 5.0.0) @@ -195,7 +195,7 @@ GEM ffi (1.14.2) foreman (0.87.0) formatador (0.2.5) - globalid (1.0.0) + globalid (1.0.1) activesupport (>= 5.0) guard (2.16.1) formatador (>= 0.2.4) @@ -214,7 +214,7 @@ GEM html-pipeline (2.12.3) activesupport (>= 2) nokogiri (>= 1.4) - i18n (1.11.0) + i18n (1.12.0) concurrent-ruby (~> 1.0) image_size (1.3.1) jbuilder (2.10.0) @@ -261,16 +261,19 @@ GEM crass (~> 1.0.2) nokogiri (>= 1.5.9) lumberjack (1.2.4) - mail (2.7.1) + mail (2.8.0.1) mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp marcel (1.0.2) matrix (0.4.2) method_source (0.9.2) mini_mime (1.1.2) - mini_portile2 (2.8.0) + mini_portile2 (2.8.1) mini_racer (0.6.2) libv8-node (~> 16.10.0.0) - minitest (5.16.2) + minitest (5.17.0) mono_logger (1.1.1) msgpack (1.5.2) multi_json (1.15.0) @@ -322,28 +325,28 @@ GEM public_suffix (4.0.6) puma (5.6.4) nio4r (~> 2.0) - racc (1.6.1) - rack (2.2.4) + racc (1.6.2) + rack (2.2.6.2) rack-mini-profiler (2.3.0) rack (>= 1.2.0) rack-protection (2.2.3) rack rack-test (2.0.2) rack (>= 1.3) - rails (6.1.6.1) - actioncable (= 6.1.6.1) - actionmailbox (= 6.1.6.1) - actionmailer (= 6.1.6.1) - actionpack (= 6.1.6.1) - actiontext (= 6.1.6.1) - actionview (= 6.1.6.1) - activejob (= 6.1.6.1) - activemodel (= 6.1.6.1) - activerecord (= 6.1.6.1) - activestorage (= 6.1.6.1) - activesupport (= 6.1.6.1) + rails (6.1.7.2) + actioncable (= 6.1.7.2) + actionmailbox (= 6.1.7.2) + actionmailer (= 6.1.7.2) + actionpack (= 6.1.7.2) + actiontext (= 6.1.7.2) + actionview (= 6.1.7.2) + activejob (= 6.1.7.2) + activemodel (= 6.1.7.2) + activerecord (= 6.1.7.2) + activestorage (= 6.1.7.2) + activesupport (= 6.1.7.2) bundler (>= 1.15.0) - railties (= 6.1.6.1) + railties (= 6.1.7.2) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) @@ -352,9 +355,9 @@ GEM loofah (~> 2.19, >= 2.19.1) rails_autolink (1.1.7) rails (> 3.1) - railties (6.1.6.1) - actionpack (= 6.1.6.1) - activesupport (= 6.1.6.1) + railties (6.1.7.2) + actionpack (= 6.1.7.2) + activesupport (= 6.1.7.2) method_source rake (>= 12.2) thor (~> 1.0) @@ -455,9 +458,9 @@ GEM rack-protection (= 2.2.3) tilt (~> 2.0) spring (2.1.0) - sprockets (4.1.1) + sprockets (4.2.0) concurrent-ruby (~> 1.0) - rack (> 1, < 3) + rack (>= 2.2.4, < 4) sprockets-rails (3.4.2) actionpack (>= 5.2) activesupport (>= 5.2) @@ -471,7 +474,7 @@ GEM turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) - tzinfo (2.0.4) + tzinfo (2.0.5) concurrent-ruby (~> 1.0) uglifier (4.2.0) execjs (>= 0.3.0, < 3) @@ -499,7 +502,7 @@ GEM chronic (>= 0.6.3) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.0) + zeitwerk (2.6.6) PLATFORMS arm64-darwin @@ -575,7 +578,7 @@ DEPENDENCIES pg puma (~> 5.0) rack-mini-profiler (~> 2.0) - rails (~> 6.1.6.1) + rails (~> 6.1.7.1) rails-html-sanitizer (~> 1.4.4) record_tag_helper rerun From 91102bbe8e3134cfa28919988a11cdd77fafdec3 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Wed, 25 Jan 2023 17:48:04 +0800 Subject: [PATCH 062/275] Move configuration to application.rb --- Gemfile.lock | 2 +- config/application.rb | 6 ++++++ config/initializers/new_framework_defaults_6_1.rb | 5 ----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9735a7de0..c20b5bba3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -457,7 +457,7 @@ GEM rack (~> 2.2) rack-protection (= 2.2.3) tilt (~> 2.0) - spring (2.1.0) + spring (2.1.1) sprockets (4.2.0) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) diff --git a/config/application.rb b/config/application.rb index 0c396acf3..b99a34120 100644 --- a/config/application.rb +++ b/config/application.rb @@ -35,6 +35,12 @@ class Application < Rails::Application config.assets.configure do |env| env.export_concurrent = false end + + config.active_record.yaml_column_permitted_classes = [ + 'ActiveModel::Errors', + 'Symbol', + 'UserPreferences' + ] end end diff --git a/config/initializers/new_framework_defaults_6_1.rb b/config/initializers/new_framework_defaults_6_1.rb index 3150d25cf..b67060efe 100644 --- a/config/initializers/new_framework_defaults_6_1.rb +++ b/config/initializers/new_framework_defaults_6_1.rb @@ -1,6 +1 @@ Rails.application.config.action_view.form_with_generates_remote_forms = true - -Rails.application.reloader.to_prepare do - Rails.application.config.active_record.yaml_column_permitted_classes = [ActiveModel::Errors, Symbol, UserPreferences] -end - From e005124a1d11c1c8a6d7e1648bbef9298241ad20 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Wed, 25 Jan 2023 17:54:27 +0800 Subject: [PATCH 063/275] Use Rails 6.1.7.2 --- Gemfile | 2 +- Gemfile.lock | 22 ++++++++-------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/Gemfile b/Gemfile index 2f41262b1..ec9af7e83 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '3.1.2' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 6.1.7.1' +gem 'rails', '~> 6.1.7.2' # Use SCSS for stylesheets gem 'sass-rails', '~> 6.0' diff --git a/Gemfile.lock b/Gemfile.lock index c20b5bba3..98cb6b881 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -115,9 +115,9 @@ GEM concurrent-ruby (1.2.0) crass (1.0.6) database_cleaner (1.8.2) + date (3.3.3) diff-lcs (1.5.0) differ (0.1.2) - digest (3.1.0) dradis-acunetix (4.6.0) dradis-plugins (~> 4.0) nokogiri (~> 1.3) @@ -280,20 +280,15 @@ GEM mustermann (2.0.2) ruby2_keywords (~> 0.0.1) nenv (0.3.0) - net-imap (0.2.3) - digest + net-imap (0.3.4) + date net-protocol - strscan - net-pop (0.1.1) - digest + net-pop (0.1.2) net-protocol + net-protocol (0.2.1) timeout - net-protocol (0.1.3) - timeout - net-smtp (0.3.1) - digest + net-smtp (0.3.3) net-protocol - timeout nio4r (2.5.8) nokogiri (1.13.10) mini_portile2 (~> 2.8.0) @@ -466,11 +461,10 @@ GEM activesupport (>= 5.2) sprockets (>= 3.0.0) sqlite3 (1.4.2) - strscan (3.0.3) thor (1.2.1) tilt (2.0.11) timecop (0.9.5) - timeout (0.2.0) + timeout (0.3.1) turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) @@ -578,7 +572,7 @@ DEPENDENCIES pg puma (~> 5.0) rack-mini-profiler (~> 2.0) - rails (~> 6.1.7.1) + rails (~> 6.1.7.2) rails-html-sanitizer (~> 1.4.4) record_tag_helper rerun From 0e34de280934407d1897bcf1884f3bb6ed7c8798 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Wed, 25 Jan 2023 18:05:55 +0800 Subject: [PATCH 064/275] Add changelog entry --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 365485347..8698f04a2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,7 +8,7 @@ - Add breadcrumbs to Revision History view - Remove `Recent Activity` tabs and add `View History` link to the dots menu - Upgraded gems: - - nokogiri, pg, rails-html-sanitizer, sinatra + - nokogiri, pg, rails, rails-html-sanitizer, sinatra - Bugs fixes: - [entity]: - [future tense verb] [bug fix] From dc529580d25569fbfd5575f8ebbe0159f3ee6a04 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Wed, 25 Jan 2023 18:12:25 +0800 Subject: [PATCH 065/275] Appease rubocop --- config/application.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/config/application.rb b/config/application.rb index b99a34120..3e06f9c6f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,17 +1,17 @@ require_relative 'boot' # Pick the frameworks you want: -require "active_model/railtie" -require "active_job/railtie" -require "active_record/railtie" -require "active_storage/engine" -require "action_controller/railtie" -require "action_mailer/railtie" +require 'active_model/railtie' +require 'active_job/railtie' +require 'active_record/railtie' +require 'active_storage/engine' +require 'action_controller/railtie' +require 'action_mailer/railtie' # require "action_mailbox/engine" # require "action_text/engine" -require "action_view/railtie" -require "action_cable/engine" -require "sprockets/railtie" +require 'action_view/railtie' +require 'action_cable/engine' +require 'sprockets/railtie' # require "rails/test_unit/railtie" require 'resque/server' From 33c3637af77bf510e799704f47e25b4bc21acd0a Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Wed, 25 Jan 2023 19:10:21 +0800 Subject: [PATCH 066/275] Remove framework defaults initializer --- config/application.rb | 2 +- config/initializers/new_framework_defaults_6_1.rb | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 config/initializers/new_framework_defaults_6_1.rb diff --git a/config/application.rb b/config/application.rb index 3e06f9c6f..0ba9dd854 100644 --- a/config/application.rb +++ b/config/application.rb @@ -35,7 +35,7 @@ class Application < Rails::Application config.assets.configure do |env| env.export_concurrent = false end - + config.action_view.form_with_generates_remote_forms = true config.active_record.yaml_column_permitted_classes = [ 'ActiveModel::Errors', 'Symbol', diff --git a/config/initializers/new_framework_defaults_6_1.rb b/config/initializers/new_framework_defaults_6_1.rb deleted file mode 100644 index b67060efe..000000000 --- a/config/initializers/new_framework_defaults_6_1.rb +++ /dev/null @@ -1 +0,0 @@ -Rails.application.config.action_view.form_with_generates_remote_forms = true From a9ff741329b5a42de0109006b2a5bc59431a7cd7 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Tue, 31 Jan 2023 15:26:35 +0800 Subject: [PATCH 067/275] Alpha author attribute --- .../app/views/dradis/ce/api/v1/evidence/_evidence.json.jbuilder | 2 +- .../app/views/dradis/ce/api/v1/issues/_issue.json.jbuilder | 2 +- .../app/views/dradis/ce/api/v1/notes/_note.json.jbuilder | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/engines/dradis-api/app/views/dradis/ce/api/v1/evidence/_evidence.json.jbuilder b/engines/dradis-api/app/views/dradis/ce/api/v1/evidence/_evidence.json.jbuilder index 52769068e..6d1c38732 100644 --- a/engines/dradis-api/app/views/dradis/ce/api/v1/evidence/_evidence.json.jbuilder +++ b/engines/dradis-api/app/views/dradis/ce/api/v1/evidence/_evidence.json.jbuilder @@ -1,4 +1,4 @@ -json.(evidence, :id, :content, :fields, :author) +json.(evidence, :id, :author, :content, :fields) json.issue do |json| json.id evidence.issue_id json.title evidence.issue.title diff --git a/engines/dradis-api/app/views/dradis/ce/api/v1/issues/_issue.json.jbuilder b/engines/dradis-api/app/views/dradis/ce/api/v1/issues/_issue.json.jbuilder index fcea86d9e..5eeb88a22 100644 --- a/engines/dradis-api/app/views/dradis/ce/api/v1/issues/_issue.json.jbuilder +++ b/engines/dradis-api/app/views/dradis/ce/api/v1/issues/_issue.json.jbuilder @@ -1,2 +1,2 @@ -json.(issue, :id, :title, :fields, :text, :author, :created_at, :updated_at) +json.(issue, :id, :author, :title, :fields, :text, :created_at, :updated_at) json.tags issue.tags, :color, :display_name diff --git a/engines/dradis-api/app/views/dradis/ce/api/v1/notes/_note.json.jbuilder b/engines/dradis-api/app/views/dradis/ce/api/v1/notes/_note.json.jbuilder index a4b918084..c28ebdc46 100644 --- a/engines/dradis-api/app/views/dradis/ce/api/v1/notes/_note.json.jbuilder +++ b/engines/dradis-api/app/views/dradis/ce/api/v1/notes/_note.json.jbuilder @@ -1 +1 @@ -json.(note, :id, :category_id, :title, :fields, :text, :author) +json.(note, :id, :author, :category_id, :title, :fields, :text) From be273c0420e54a676c865d4f68b107056dcfd5ef Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Tue, 31 Jan 2023 15:36:24 +0800 Subject: [PATCH 068/275] Appease rubocop --- .../dradis/ce/api/v1/evidence_spec.rb | 124 +++++++++--------- .../requests/dradis/ce/api/v1/issues_spec.rb | 12 +- .../requests/dradis/ce/api/v1/notes_spec.rb | 22 ++-- 3 files changed, 79 insertions(+), 79 deletions(-) diff --git a/engines/dradis-api/spec/requests/dradis/ce/api/v1/evidence_spec.rb b/engines/dradis-api/spec/requests/dradis/ce/api/v1/evidence_spec.rb index 8ab22e9b4..712fe81f3 100644 --- a/engines/dradis-api/spec/requests/dradis/ce/api/v1/evidence_spec.rb +++ b/engines/dradis-api/spec/requests/dradis/ce/api/v1/evidence_spec.rb @@ -54,7 +54,7 @@ it 'retrieves all the evidence for the given node' do expect(retrieved_evidence.count).to eq 33 - issue_titles = retrieved_evidence.map{ |json| json['issue']['title'] }.uniq + issue_titles = retrieved_evidence.map { |json| json['issue']['title'] }.uniq expect(issue_titles).to match_array @issues.map(&:title) end @@ -103,44 +103,44 @@ get "/api/nodes/#{node.id}/evidence/#{@evidence.id}", env: @env end - it "responds with HTTP code 200" do + it 'responds with HTTP code 200' do expect(response.status).to eq 200 end - it "returns JSON information about the evidence" do + it 'returns JSON information about the evidence' do retrieved_evidence = JSON.parse(response.body) - expect(retrieved_evidence["id"]).to eq @evidence.id + expect(retrieved_evidence['id']).to eq @evidence.id expect(retrieved_evidence['author']).to eq @evidence.author - expect(retrieved_evidence["fields"].keys).to match_array( + expect(retrieved_evidence['fields'].keys).to match_array( @evidence.local_fields.keys + %w(fizz foo) ) - expect(retrieved_evidence["fields"]["foo"]).to eq "bar" - expect(retrieved_evidence["fields"]["fizz"]).to eq "buzz" - expect(retrieved_evidence["issue"]["id"]).to eq @issue.id - expect(retrieved_evidence["issue"]["title"]).to eq @issue.title + expect(retrieved_evidence['fields']['foo']).to eq 'bar' + expect(retrieved_evidence['fields']['fizz']).to eq 'buzz' + expect(retrieved_evidence['issue']['id']).to eq @issue.id + expect(retrieved_evidence['issue']['title']).to eq @issue.title end end - describe "POST /api/nodes/:node_id/evidence" do + describe 'POST /api/nodes/:node_id/evidence' do let(:url) { "/api/nodes/#{node.id}/evidence" } let(:issue) { create(:issue, node: current_project.issue_library) } let(:post_evidence) { post url, params: params.to_json, env: @env } - context "when content_type header = application/json" do - include_context "content_type: application/json" + context 'when content_type header = application/json' do + include_context 'content_type: application/json' - context "with params for a valid evidence" do - let(:params) { { evidence: { content: "New evidence", issue_id: issue.id } } } + context 'with params for a valid evidence' do + let(:params) { { evidence: { content: 'New evidence', issue_id: issue.id } } } - it "responds with HTTP code 201" do + it 'responds with HTTP code 201' do post_evidence expect(response.status).to eq 201 end - it "creates an evidence" do - expect{post_evidence}.to change{node.evidence.count} + it 'creates an evidence' do + expect { post_evidence }.to change { node.evidence.count } new_evidence = node.evidence.last - expect(new_evidence.content).to eq "New evidence" + expect(new_evidence.content).to eq 'New evidence' expect(new_evidence.issue).to eq issue end @@ -149,34 +149,34 @@ include_examples 'sets the whodunnit', :create, Evidence end - context "with params for an invalid evidence" do - let(:params) { { evidence: { content: "New evidence" } } } # no issue + context 'with params for an invalid evidence' do + let(:params) { { evidence: { content: 'New evidence' } } } # no issue - it "responds with HTTP code 422" do + it 'responds with HTTP code 422' do post_evidence expect(response.status).to eq 422 end it "doesn't create an evidence" do - expect{post_evidence}.not_to change{Evidence.count} + expect { post_evidence }.not_to change { Evidence.count } end end - context "when no :evidence param is sent" do + context 'when no :evidence param is sent' do let(:params) { {} } it "doesn't create an evidence" do - expect{post_evidence}.not_to change{Evidence.count} + expect { post_evidence }.not_to change { Evidence.count } end - it "responds with HTTP code 422" do + it 'responds with HTTP code 422' do post_evidence expect(response.status).to eq(422) end end - context "when invalid JSON is sent" do - it "responds with HTTP code 400" do + context 'when invalid JSON is sent' do + it 'responds with HTTP code 400' do json_payload = '{"evidence":{"label":"A malformed label", , }}' post url, params: json_payload, env: @env expect(response.status).to eq(400) @@ -184,43 +184,43 @@ end end - context "when JSON is not sent" do - it "responds with HTTP code 415" do - params = { evidence: { } } + context 'when JSON is not sent' do + it 'responds with HTTP code 415' do + params = { evidence: {} } post url, params: params, env: @env expect(response.status).to eq(415) end end end - describe "PUT /api/nodes/:node_id/evidence/:id" do + describe 'PUT /api/nodes/:node_id/evidence/:id' do let(:evidence) do - create(:evidence, node: node, content: "My content", issue: issue) + create(:evidence, node: node, content: 'My content', issue: issue) end let(:url) { "/api/nodes/#{node.id}/evidence/#{evidence.id}" } let(:put_evidence) { put url, params: params.to_json, env: @env } - context "when content_type header = application/json" do - include_context "content_type: application/json" + context 'when content_type header = application/json' do + include_context 'content_type: application/json' - context "with params for a valid evidence" do - let(:params) { { evidence: { content: "New content" } } } + context 'with params for a valid evidence' do + let(:params) { { evidence: { content: 'New content' } } } - it "responds with HTTP code 200" do + it 'responds with HTTP code 200' do put_evidence expect(response.status).to eq 200 end - it "updates the evidence" do + it 'updates the evidence' do put_evidence - expect(evidence.reload.content).to eq "New content" + expect(evidence.reload.content).to eq 'New content' end - it "returns the attributes of the updated evidence as JSON" do + it 'returns the attributes of the updated evidence as JSON' do put_evidence retrieved_evidence = JSON.parse(response.body) - expect(retrieved_evidence["content"]).to eq "New content" + expect(retrieved_evidence['content']).to eq 'New content' end let(:submit_form) { put_evidence } @@ -229,34 +229,34 @@ include_examples 'sets the whodunnit', :update end - context "with params for an invalid evidence" do - let(:params) { { evidence: { content: "a"*65536 } } } # too long + context 'with params for an invalid evidence' do + let(:params) { { evidence: { content: 'a' * 65536 } } } # too long - it "responds with HTTP code 422" do + it 'responds with HTTP code 422' do put_evidence expect(response.status).to eq 422 end it "doesn't update the evidence" do - expect{put_evidence}.not_to change{evidence.reload.attributes} + expect { put_evidence }.not_to change { evidence.reload.attributes } end end - context "when no :evidence param is sent" do + context 'when no :evidence param is sent' do let(:params) { {} } it "doesn't update the evidence" do - expect{put_evidence}.not_to change{evidence.reload.attributes} + expect { put_evidence }.not_to change { evidence.reload.attributes } end - it "responds with HTTP code 422" do + it 'responds with HTTP code 422' do put_evidence expect(response.status).to eq 422 end end - context "when invalid JSON is sent" do - it "responds with HTTP code 400" do + context 'when invalid JSON is sent' do + it 'responds with HTTP code 400' do json_payload = '{"evidence":{"label":"A malformed label", , }}' put url, params: json_payload, env: @env expect(response.status).to eq(400) @@ -264,44 +264,44 @@ end end - context "when JSON is not sent" do - let(:params) { { evidence: { content: "New Evidence" } } } + context 'when JSON is not sent' do + let(:params) { { evidence: { content: 'New Evidence' } } } - it "responds with HTTP code 415" do - expect{put url, params: params, env: @env}.not_to change{evidence.reload.attributes} + it 'responds with HTTP code 415' do + expect { put url, params: params, env: @env }.not_to change { evidence.reload.attributes } expect(response.status).to eq 415 end end end - describe "DELETE /api/nodes/:node_id/evidence/:id" do - let(:evidence) { create(:evidence, node: node, content: "My Evidence", issue: issue) } + describe 'DELETE /api/nodes/:node_id/evidence/:id' do + let(:evidence) { create(:evidence, node: node, content: 'My Evidence', issue: issue) } let(:delete_evidence) do delete "/api/nodes/#{node.id}/evidence/#{evidence.id}", env: @env end - it "deletes the evidence" do + it 'deletes the evidence' do evidence_id = evidence.id delete_evidence expect(Evidence.find_by_id(evidence_id)).to be_nil end - it "responds with error code 200" do + it 'responds with error code 200' do delete_evidence expect(response.status).to eq(200) end - it "returns JSON with a success message" do + it 'returns JSON with a success message' do delete_evidence parsed_response = JSON.parse(response.body) - expect(parsed_response["message"]).to eq\ - "Resource deleted successfully" + expect(parsed_response['message']).to eq\ + 'Resource deleted successfully' end let(:submit_form) { delete_evidence } let(:model) { evidence } - include_examples "creates an Activity", :destroy + include_examples 'creates an Activity', :destroy end end end diff --git a/engines/dradis-api/spec/requests/dradis/ce/api/v1/issues_spec.rb b/engines/dradis-api/spec/requests/dradis/ce/api/v1/issues_spec.rb index 019820e34..7e9be67b6 100644 --- a/engines/dradis-api/spec/requests/dradis/ce/api/v1/issues_spec.rb +++ b/engines/dradis-api/spec/requests/dradis/ce/api/v1/issues_spec.rb @@ -41,7 +41,7 @@ it 'retrieves all the issues' do titles = @issues.map(&:title) - retrieved_titles = @retrieved_issues.map{ |json| json['title'] } + retrieved_titles = @retrieved_issues.map { |json| json['title'] } expect(@retrieved_issues.count).to eq(@issues.count) expect(retrieved_titles).to match_array(titles) @@ -90,7 +90,7 @@ it 'includes tags' do tag = @issue.tags.first - expect(@retrieved_issue['tags']).to eq [{'color' => tag.color, 'display_name' => tag.display_name}] + expect(@retrieved_issue['tags']).to eq [{ 'color' => tag.color, 'display_name' => tag.display_name }] end it 'includes the author' do @@ -105,7 +105,7 @@ end it 'creates a new issue' do - expect{valid_post}.to change{ current_project.issues.count }.by(1) + expect { valid_post }.to change { current_project.issues.count }.by(1) expect(response.status).to eq(201) retrieved_issue = JSON.parse(response.body) expect(retrieved_issue['text']).to eq valid_params[:issue][:text] @@ -115,7 +115,7 @@ tag_name = '!2ca02c_info' valid_params[:issue][:text] << "#[Tags]#\n\n#{tag_name}\n\n" - expect { valid_post }.to change{ current_project.issues.count }.by(1) + expect { valid_post }.to change { current_project.issues.count }.by(1) expect(response.status).to eq(201) retrieved_issue = JSON.parse(response.body) @@ -135,7 +135,7 @@ end it 'throws 422 if issue is invalid' do - params = { issue: { text: 'A'*(65535+1) } } + params = { issue: { text: 'A' * (65535 + 1) } } expect { post '/api/issues', params: params.to_json, env: @env.merge('CONTENT_TYPE' => 'application/json') }.not_to change { current_project.issues.count } @@ -172,7 +172,7 @@ end it 'throws 422 if issue is invalid' do - params = { issue: { text: 'B'*(65535+1) } } + params = { issue: { text: 'B' * (65535 + 1) } } put "/api/issues/#{ issue.id }", params: params.to_json, env: @env.merge('CONTENT_TYPE' => 'application/json') expect(response.status).to eq(422) end diff --git a/engines/dradis-api/spec/requests/dradis/ce/api/v1/notes_spec.rb b/engines/dradis-api/spec/requests/dradis/ce/api/v1/notes_spec.rb index 89a0ccd43..7333ca823 100644 --- a/engines/dradis-api/spec/requests/dradis/ce/api/v1/notes_spec.rb +++ b/engines/dradis-api/spec/requests/dradis/ce/api/v1/notes_spec.rb @@ -54,7 +54,7 @@ it 'retrieves all the notes for the given node' do expect(retrieved_notes.count).to eq 33 - retrieved_titles = retrieved_notes.map{ |json| json['title'] } + retrieved_titles = retrieved_notes.map { |json| json['title'] } expect(retrieved_titles).to match_array(@notes.map(&:title)) end @@ -136,7 +136,7 @@ before { params[:note][:category_id] = category.id } it 'creates a note with the given node & category' do - expect{post_note}.to change{node.notes.count}.by(1) + expect { post_note }.to change { node.notes.count }.by(1) note = node.notes.last expect(note.category).to eq category end @@ -155,14 +155,14 @@ context 'and category is not specified' do it 'creates a note with the given node & default category' do - expect{post_note}.to change{node.notes.count}.by(1) + expect { post_note }.to change { node.notes.count }.by(1) expect(node.notes.last.category).to eq Category.default end end end context 'with params for an invalid note' do - let(:params) { { note: { text: 'a'*65536 } } } # too long + let(:params) { { note: { text: 'a' * 65536 } } } # too long it 'responds with HTTP code 422' do post_note @@ -170,7 +170,7 @@ end it 'doesn\'t create a note' do - expect{post_note}.not_to change{Note.count} + expect { post_note }.not_to change { Note.count } end end @@ -178,7 +178,7 @@ let(:params) { {} } it 'doesn\'t create a note' do - expect{post_note}.not_to change{Note.count} + expect { post_note }.not_to change { Note.count } end it 'responds with HTTP code 422' do @@ -198,7 +198,7 @@ context 'when JSON is not sent' do it 'responds with HTTP code 415' do - params = { note: { } } + params = { note: {} } post url, params: params, env: @env expect(response.status).to eq(415) end @@ -242,7 +242,7 @@ end context 'with params for an invalid note' do - let(:params) { { note: { text: 'a'*65536 } } } # too long + let(:params) { { note: { text: 'a' * 65536 } } } # too long it 'responds with HTTP code 422' do put_note @@ -250,7 +250,7 @@ end it 'doesn\'t update the note' do - expect{put_note}.not_to change{note.reload.attributes} + expect { put_note }.not_to change { note.reload.attributes } end end @@ -258,7 +258,7 @@ let(:params) { {} } it 'doesn\'t update the note' do - expect{put_note}.not_to change{note.reload.attributes} + expect { put_note }.not_to change { note.reload.attributes } end it 'responds with HTTP code 422' do @@ -280,7 +280,7 @@ let(:params) { { note: { text: 'New Note' } } } it 'responds with HTTP code 415' do - expect{put url, params: params, env: @env}.not_to change{note.reload.attributes} + expect { put url, params: params, env: @env }.not_to change { note.reload.attributes } expect(response.status).to eq 415 end end From 7a9cc66c9cb563356653ba4ea6b63b94b16e1362 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Wed, 8 Feb 2023 19:01:31 +0800 Subject: [PATCH 069/275] Update sanitize gem 6.0.1 --- CHANGELOG | 2 +- Gemfile | 2 +- Gemfile.lock | 9 +++------ 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d3920395c..8dc23d5a1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -9,7 +9,7 @@ - Add secondary sidebar toggling functionality - Remove `Recent Activity` tabs and add `View History` link to the dots menu - Upgraded gems: - - nokogiri, pg, rails, rails-html-sanitizer, sinatra + - nokogiri, pg, rails, rails-html-sanitizer, sanitize, sinatra - Bugs fixes: - [entity]: - [future tense verb] [bug fix] diff --git a/Gemfile b/Gemfile index ec9af7e83..eaf94d0df 100644 --- a/Gemfile +++ b/Gemfile @@ -96,7 +96,7 @@ gem 'RedCloth', '~> 4.3.2', require: 'redcloth' gem 'rinku' # html-pipeline dependency for html sanitization -gem 'sanitize', '5.2.1' +gem 'sanitize', '6.0.1' # SQLite3 DB driver gem 'sqlite3' diff --git a/Gemfile.lock b/Gemfile.lock index 98cb6b881..678237689 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -299,8 +299,6 @@ GEM racc (~> 1.4) nokogiri (1.13.10-x86_64-linux) racc (~> 1.4) - nokogumbo (2.0.5) - nokogiri (~> 1.8, >= 1.8.4) notiffany (0.1.3) nenv (~> 0.1) shellany (~> 0.0) @@ -424,10 +422,9 @@ GEM ruby_audit (2.1.0) bundler-audit (~> 0.9.0) rubyzip (2.2.0) - sanitize (5.2.1) + sanitize (6.0.1) crass (~> 1.0.2) - nokogiri (>= 1.8.0) - nokogumbo (~> 2.0) + nokogiri (>= 1.12.0) sass-rails (6.0.0) sassc-rails (~> 2.1, >= 2.1.1) sassc (2.4.0) @@ -583,7 +580,7 @@ DEPENDENCIES rubocop ruby_audit rubyzip (>= 1.2.2) - sanitize (= 5.2.1) + sanitize (= 6.0.1) sass-rails (~> 6.0) selenium-webdriver shoulda-matchers (~> 3.1) From f1c2711787803024b85de2313e2f9e773084971b Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Tue, 14 Feb 2023 16:31:12 +0800 Subject: [PATCH 070/275] Bump version and update changelog --- CHANGELOG | 2 +- lib/dradis/ce/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index fce4967ec..b4a26b709 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -[v#.#.#] ([month] [YYYY]) +v4.7.0 (February 2023) - Rubocop CI: - disable EnforcedShorthandSyntax rule under Style/HashSyntax cop - Issues: Display the results from importers in a datatable diff --git a/lib/dradis/ce/version.rb b/lib/dradis/ce/version.rb index 7ad281c02..8ae7b69db 100644 --- a/lib/dradis/ce/version.rb +++ b/lib/dradis/ce/version.rb @@ -2,7 +2,7 @@ module Dradis module CE #:nodoc: module VERSION #:nodoc: MAJOR = 4 - MINOR = 6 + MINOR = 7 TINY = 0 PRE = nil From 5867385ea3e7d54ccc6bd1005163b3d54db5e6c9 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Tue, 14 Feb 2023 16:33:58 +0800 Subject: [PATCH 071/275] Update Gemfile.lock --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 678237689..bab47bd91 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: engines/dradis-api specs: - dradis-api (4.6.0) + dradis-api (4.7.0) jbuilder GEM From 6657d0907f440b3166b1c5fcbddcca7a0e26ad64 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Tue, 14 Feb 2023 16:40:53 +0800 Subject: [PATCH 072/275] Cleanup changelog --- CHANGELOG | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b4a26b709..30027efa8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,27 +10,9 @@ v4.7.0 (February 2023) - Upgraded gems: - nokogiri, pg, rails, rails-html-sanitizer, sanitize, sinatra - Bugs fixes: - - [entity]: - - [future tense verb] [bug fix] - Methodologies: Ensure params are validated when moving list/card - - Bug tracker items: - - [item] - - New integrations: - - [integration] - - Integration enhancements: - - [integration]: - - [future tense verb] [integration enhancement] - - [integration bug fixes]: - - [future tense verb] [integration bug fix] - - Reporting enhancements: - - [report type]: - - [future tense verb] [reporting enhancement] - REST/JSON API enhancements: - Author: Add author field for notes, issues, and evidence - - Security Fixes: - - High: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description] - - Medium: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description] - - Low: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description] v4.6.0 (November 2022) - Kit Import: allow import of kit with no templates From 18141a1e8a60bd63aadb973a8eedab5fa3bf6df2 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Tue, 14 Feb 2023 19:30:34 +0800 Subject: [PATCH 073/275] Move matrix gem to test group --- Gemfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index eaf94d0df..818ccfa0b 100644 --- a/Gemfile +++ b/Gemfile @@ -131,8 +131,6 @@ gem 'net-smtp' gem 'net-pop' gem 'net-imap' -gem 'matrix' - # ------------------------------------------------------------------ Deployment # Use Capistrano for deployment # gem 'capistrano-rails', group: :development @@ -193,6 +191,9 @@ group :test do gem 'shoulda-matchers', '~> 3.1' gem 'timecop' gem 'webdrivers' + + # Required by capybara + gem 'matrix' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem From 3b7da1c2ec7d029b1f803090d80632274cd92c11 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Wed, 15 Feb 2023 14:27:43 +0800 Subject: [PATCH 074/275] Add changelog entry for integrations --- CHANGELOG | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 30027efa8..6dcef0f29 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,10 @@ v4.7.0 (February 2023) - Add secondary sidebar toggling functionality - Remove `Recent Activity` tabs and add `View History` link to the dots menu - Tags: Add tag management + - Integration enhancements: + - Burp: Add support for large base64 response + - Nessus: Clean up code tags in description fields + - Netsparker: Add support for large base64 response - Upgraded gems: - nokogiri, pg, rails, rails-html-sanitizer, sanitize, sinatra - Bugs fixes: From b75e3a4edeae00b291a480dc59fe79747df6637b Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Wed, 15 Feb 2023 15:24:26 +0800 Subject: [PATCH 075/275] Update CHANGELOG --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 6dcef0f29..3184d630f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,7 +10,7 @@ v4.7.0 (February 2023) - Integration enhancements: - Burp: Add support for large base64 response - Nessus: Clean up code tags in description fields - - Netsparker: Add support for large base64 response + - Netsparker: Add issue.classification_owasp2021 as a new avaiable field - Upgraded gems: - nokogiri, pg, rails, rails-html-sanitizer, sanitize, sinatra - Bugs fixes: From de080c990f2246f66d7165243a6dce58911bdae0 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Fri, 17 Feb 2023 19:47:57 +0800 Subject: [PATCH 076/275] Add @tags to cache lists --- app/views/issues/_table.html.erb | 2 +- app/views/tags/_table.html.erb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/issues/_table.html.erb b/app/views/issues/_table.html.erb index 7ed2578e7..84182a413 100644 --- a/app/views/issues/_table.html.erb +++ b/app/views/issues/_table.html.erb @@ -1,4 +1,4 @@ -<% cache ['issues-table', @all_columns, issues.map(&:id), @issues.map(&:updated_at).map(&:to_i).sort.last] do %> +<% cache ['issues-table', @all_columns, issues.map(&:id), @issues.map(&:updated_at).map(&:to_i).sort.last, @tags] do %>
+<% cache ['tags-table', @all_columns, @tags] do %>
<%= content_tag :td, - display, + display, data: { sort: sort } From 0287d5eceef3f565bc7dfbbb617ac9b4e8a7107e Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Fri, 17 Feb 2023 20:26:53 +0800 Subject: [PATCH 077/275] Add Date class to diffed revision --- app/models/diffed_revision.rb | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/app/models/diffed_revision.rb b/app/models/diffed_revision.rb index 5a8694661..961771611 100644 --- a/app/models/diffed_revision.rb +++ b/app/models/diffed_revision.rb @@ -9,10 +9,11 @@ def initialize(revision, record) end def diff - @diff ||= Differ.diff_by_line( - after[content_attribute], - before[content_attribute] - ) + @diff ||= + Differ.diff_by_line( + after[content_attribute], + before[content_attribute] + ) end def last_updated_at @@ -39,7 +40,7 @@ def updated_at def before # Version#object is the state of the object *before* the change was made. - @before ||= YAML.load(@revision.object, permitted_classes: [ActiveSupport::TimeWithZone, Time, ActiveSupport::TimeZone], aliases: true) + @before ||= YAML.load(@revision.object, permitted_classes: [ActiveSupport::TimeWithZone, ActiveSupport::TimeZone, Date, Time], aliases: true) end def after @@ -47,11 +48,12 @@ def after # is `create` - but in theory, @revision.next below should always return # a version with event type 'update' or 'destroy'. If it doesn't, and # this method crashes, then bad data has snuck into your DB somehow. - @after ||= if next_revision = @revision.next - YAML.load(next_revision.object, permitted_classes: [ActiveSupport::TimeWithZone, Time, ActiveSupport::TimeZone], aliases: true) - else - @record.attributes - end + @after ||= + if next_revision = @revision.next + YAML.load(next_revision.object, permitted_classes: [ActiveSupport::TimeWithZone, ActiveSupport::TimeZone, Date, Time], aliases: true) + else + @record.attributes + end end # Issue/Note have the `text` attribute aliased as `content` but we can't use From 7b0fb88b5e816dba2da8444bdc7fa08347d1db34 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Mon, 20 Feb 2023 17:49:10 +0800 Subject: [PATCH 078/275] Bump the dradis gems --- Gemfile | 50 ++++++++++++------------ Gemfile.lock | 106 ++++++++++++++++++++++++++------------------------- 2 files changed, 79 insertions(+), 77 deletions(-) diff --git a/Gemfile b/Gemfile index 818ccfa0b..505ad1d48 100644 --- a/Gemfile +++ b/Gemfile @@ -211,12 +211,12 @@ end # # Base framework classes required by other plugins -gem 'dradis-plugins', '~> 4.6.1' +gem 'dradis-plugins', '~> 4.7.0' gem 'dradis-api', path: 'engines/dradis-api' # Import / export project data -gem 'dradis-projects', '~> 4.6.0' +gem 'dradis-projects', '~> 4.7.0' plugins_file = 'Gemfile.plugins' if File.exists?(plugins_file) @@ -227,32 +227,32 @@ end # effective. # ----------------------------------------------------------------- Calculators -gem 'dradis-calculator_cvss', '~> 4.6.0' -gem 'dradis-calculator_dread', '~> 4.6.0' +gem 'dradis-calculator_cvss', '~> 4.7.0' +gem 'dradis-calculator_dread', '~> 4.7.0' # ---------------------------------------------------------------------- Export -gem 'dradis-csv_export', '~> 4.6.0' -gem 'dradis-html_export', '~> 4.6.0' +gem 'dradis-csv_export', '~> 4.7.0' +gem 'dradis-html_export', '~> 4.7.0' # ---------------------------------------------------------------------- Import -gem 'dradis-csv', '~> 4.6.0' +gem 'dradis-csv', '~> 4.7.0' # ---------------------------------------------------------------------- Upload -gem 'dradis-acunetix', '~> 4.6.0' -gem 'dradis-brakeman', '~> 4.6.0' -gem 'dradis-burp', '~> 4.6.0' -gem 'dradis-coreimpact', '~> 4.6.0' -gem 'dradis-metasploit', '~> 4.6.0' -gem 'dradis-nessus', '~> 4.6.0' -gem 'dradis-netsparker', '~> 4.6.0' -gem 'dradis-nexpose', '~> 4.6.0' -gem 'dradis-nikto', '~> 4.6.0' -gem 'dradis-nipper', '~> 4.6.0' -gem 'dradis-nmap', '~> 4.6.0' -gem 'dradis-ntospider', '~> 4.6.0' -gem 'dradis-openvas', '~> 4.6.0' -gem 'dradis-qualys', '~> 4.6.0' -gem 'dradis-saint', '~> 4.6.0' -gem 'dradis-veracode', '~> 4.6.0' -gem 'dradis-wpscan', '~> 4.6.0' -gem 'dradis-zap', '~> 4.6.0' +gem 'dradis-acunetix', '~> 4.7.0' +gem 'dradis-brakeman', '~> 4.7.0' +gem 'dradis-burp', '~> 4.7.0' +gem 'dradis-coreimpact', '~> 4.7.0' +gem 'dradis-metasploit', '~> 4.7.0' +gem 'dradis-nessus', '~> 4.7.0' +gem 'dradis-netsparker', '~> 4.7.0' +gem 'dradis-nexpose', '~> 4.7.0' +gem 'dradis-nikto', '~> 4.7.0' +gem 'dradis-nipper', '~> 4.7.0' +gem 'dradis-nmap', '~> 4.7.0' +gem 'dradis-ntospider', '~> 4.7.0' +gem 'dradis-openvas', '~> 4.7.0' +gem 'dradis-qualys', '~> 4.7.0' +gem 'dradis-saint', '~> 4.7.0' +gem 'dradis-veracode', '~> 4.7.0' +gem 'dradis-wpscan', '~> 4.7.0' +gem 'dradis-zap', '~> 4.7.0' diff --git a/Gemfile.lock b/Gemfile.lock index bab47bd91..61e6a3b76 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -118,71 +118,71 @@ GEM date (3.3.3) diff-lcs (1.5.0) differ (0.1.2) - dradis-acunetix (4.6.0) + dradis-acunetix (4.7.1) dradis-plugins (~> 4.0) nokogiri (~> 1.3) - dradis-brakeman (4.6.0) + dradis-brakeman (4.7.1) dradis-plugins (~> 4.0) - dradis-burp (4.6.0) + dradis-burp (4.7.0) dradis-plugins (~> 4.0) nokogiri (~> 1.3) - dradis-calculator_cvss (4.6.0) + dradis-calculator_cvss (4.7.0) dradis-plugins (~> 4.0) - dradis-calculator_dread (4.6.0) + dradis-calculator_dread (4.7.0) dradis-plugins (~> 4.0) - dradis-coreimpact (4.6.0) + dradis-coreimpact (4.7.0) dradis-plugins (~> 4.0) - dradis-csv (4.6.0) + dradis-csv (4.7.0) dradis-plugins (~> 4.0) - dradis-csv_export (4.6.0) + dradis-csv_export (4.7.0) dradis-plugins (~> 4.0) - dradis-html_export (4.6.0) + dradis-html_export (4.7.0) RedCloth (~> 4.3.2) dradis-plugins (~> 4.0) rails_autolink (~> 1.1) - dradis-metasploit (4.6.0) + dradis-metasploit (4.7.0) dradis-plugins (~> 4.0) nokogiri (~> 1.3) - dradis-nessus (4.6.0) + dradis-nessus (4.7.0) dradis-plugins (~> 4.0) nokogiri - dradis-netsparker (4.6.0) + dradis-netsparker (4.7.0) dradis-plugins (~> 4.0) nokogiri (>= 1.12.5) - dradis-nexpose (4.6.0) + dradis-nexpose (4.7.0) dradis-plugins (~> 4.0) nokogiri (~> 1.3) - dradis-nikto (4.6.0) + dradis-nikto (4.7.0) dradis-plugins (~> 4.0) nokogiri (~> 1.3) - dradis-nipper (4.6.0) + dradis-nipper (4.7.0) dradis-plugins (~> 4.0) - dradis-nmap (4.6.0) + dradis-nmap (4.7.0) dradis-plugins (~> 4.0) ruby-nmap (~> 0.7) - dradis-ntospider (4.6.0) + dradis-ntospider (4.7.0) dradis-plugins (~> 4.0) - dradis-openvas (4.6.0) + dradis-openvas (4.7.0) dradis-plugins (~> 4.0) - dradis-plugins (4.6.1) - dradis-projects (4.6.0) + dradis-plugins (4.7.0) + dradis-projects (4.7.0) dradis-plugins (~> 4.0) rubyzip - dradis-qualys (4.6.0) + dradis-qualys (4.7.0) dradis-plugins (~> 4.0) nokogiri (~> 1.3) - dradis-saint (4.6.0) + dradis-saint (4.7.0) combustion (~> 0.6.0) dradis-plugins (~> 4.0) nokogiri rake (~> 13.0) rspec-rails - dradis-veracode (4.6.0) + dradis-veracode (4.7.0) dradis-plugins (~> 4.0) - dradis-wpscan (4.6.0) + dradis-wpscan (4.7.0) dradis-plugins (~> 4.0) multi_json - dradis-zap (4.6.0) + dradis-zap (4.7.0) dradis-plugins (~> 4.0) nokogiri (~> 1.3) erubi (1.12.0) @@ -346,8 +346,10 @@ GEM nokogiri (>= 1.6) rails-html-sanitizer (1.4.4) loofah (~> 2.19, >= 2.19.1) - rails_autolink (1.1.7) - rails (> 3.1) + rails_autolink (1.1.8) + actionview (> 3.1) + activesupport (> 3.1) + railties (> 3.1) railties (6.1.7.2) actionpack (= 6.1.7.2) activesupport (= 6.1.7.2) @@ -516,32 +518,32 @@ DEPENDENCIES coffee-rails (~> 5.0) database_cleaner differ (~> 0.1.2) - dradis-acunetix (~> 4.6.0) + dradis-acunetix (~> 4.7.0) dradis-api! - dradis-brakeman (~> 4.6.0) - dradis-burp (~> 4.6.0) - dradis-calculator_cvss (~> 4.6.0) - dradis-calculator_dread (~> 4.6.0) - dradis-coreimpact (~> 4.6.0) - dradis-csv (~> 4.6.0) - dradis-csv_export (~> 4.6.0) - dradis-html_export (~> 4.6.0) - dradis-metasploit (~> 4.6.0) - dradis-nessus (~> 4.6.0) - dradis-netsparker (~> 4.6.0) - dradis-nexpose (~> 4.6.0) - dradis-nikto (~> 4.6.0) - dradis-nipper (~> 4.6.0) - dradis-nmap (~> 4.6.0) - dradis-ntospider (~> 4.6.0) - dradis-openvas (~> 4.6.0) - dradis-plugins (~> 4.6.1) - dradis-projects (~> 4.6.0) - dradis-qualys (~> 4.6.0) - dradis-saint (~> 4.6.0) - dradis-veracode (~> 4.6.0) - dradis-wpscan (~> 4.6.0) - dradis-zap (~> 4.6.0) + dradis-brakeman (~> 4.7.0) + dradis-burp (~> 4.7.0) + dradis-calculator_cvss (~> 4.7.0) + dradis-calculator_dread (~> 4.7.0) + dradis-coreimpact (~> 4.7.0) + dradis-csv (~> 4.7.0) + dradis-csv_export (~> 4.7.0) + dradis-html_export (~> 4.7.0) + dradis-metasploit (~> 4.7.0) + dradis-nessus (~> 4.7.0) + dradis-netsparker (~> 4.7.0) + dradis-nexpose (~> 4.7.0) + dradis-nikto (~> 4.7.0) + dradis-nipper (~> 4.7.0) + dradis-nmap (~> 4.7.0) + dradis-ntospider (~> 4.7.0) + dradis-openvas (~> 4.7.0) + dradis-plugins (~> 4.7.0) + dradis-projects (~> 4.7.0) + dradis-qualys (~> 4.7.0) + dradis-saint (~> 4.7.0) + dradis-veracode (~> 4.7.0) + dradis-wpscan (~> 4.7.0) + dradis-zap (~> 4.7.0) factory_bot_rails foreman guard-rspec From ae4ab6c7bc8a181384f1f8ac90ab47283b91d5be Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Mon, 20 Feb 2023 17:54:20 +0800 Subject: [PATCH 079/275] Appease rubocop --- app/models/diffed_revision.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/models/diffed_revision.rb b/app/models/diffed_revision.rb index 961771611..c079d5e1d 100644 --- a/app/models/diffed_revision.rb +++ b/app/models/diffed_revision.rb @@ -1,7 +1,6 @@ # Wraps around an instance of `PaperTrail::Version` (where event==update) and # lets us show a diff class DiffedRevision - def initialize(revision, record) raise 'undiffable revision' unless revision.event == 'update' @revision = revision @@ -66,5 +65,4 @@ def content_attribute when Evidence; 'content' end end - end From 3d50e8641d8c1bdeee3b9e9080fa950121a5b422 Mon Sep 17 00:00:00 2001 From: Caitlin Date: Wed, 22 Feb 2023 11:55:55 -0500 Subject: [PATCH 080/275] appease rubocop again --- app/controllers/evidence_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/evidence_controller.rb b/app/controllers/evidence_controller.rb index 870bdb36e..c19f227a1 100644 --- a/app/controllers/evidence_controller.rb +++ b/app/controllers/evidence_controller.rb @@ -86,7 +86,7 @@ def destroy if request.headers['Referer'] == project_node_evidence_url(current_project, @node, @evidence) redirect_to project_node_path(current_project, @node), notice: notice else - redirect_back fallback_location: project_node_path(current_project, @node), notice: + redirect_back fallback_location: project_node_path(current_project, @node), notice: notice end } format.js From 76f0c571cc1b0592a20d80f763594ab12b29d6a7 Mon Sep 17 00:00:00 2001 From: Caitlin Date: Wed, 22 Feb 2023 13:43:09 -0500 Subject: [PATCH 081/275] add changelog template --- CHANGELOG | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 3184d630f..9e506af1c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,31 @@ +[v#.#.#] ([month] [YYYY]) + - [entity]: + - [future tense verb] [feature] + - Upgraded gems: + - [gem] + - Bugs fixes: + - [entity]: + - [future tense verb] [bug fix] + - Bug tracker items: + - [item] + - New integrations: + - [integration] + - Integration enhancements: + - [integration]: + - [future tense verb] [integration enhancement] + - [integration bug fixes]: + - [future tense verb] [integration bug fix] + - Reporting enhancements: + - [report type]: + - [future tense verb] [reporting enhancement] + - REST/JSON API enhancements: + - [API entity]: + - [future tense verb] [API enhancement] + - Security Fixes: + - High: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description] + - Medium: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description] + - Low: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description] + v4.7.0 (February 2023) - Rubocop CI: - disable EnforcedShorthandSyntax rule under Style/HashSyntax cop From f79f47a8faa26999fe5a6340bdd0849b96b8d555 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Fri, 3 Mar 2023 16:49:17 +0800 Subject: [PATCH 082/275] Add state to the notes table and state enum to issues --- app/models/issue.rb | 2 ++ db/migrate/20230303080209_add_state_to_issues.rb | 13 +++++++++++++ db/schema.rb | 3 ++- spec/factories/issues.rb | 1 + 4 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20230303080209_add_state_to_issues.rb diff --git a/app/models/issue.rb b/app/models/issue.rb index a2e323b3f..050d3f8bc 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -10,6 +10,8 @@ class Issue < Note include Taggable + enum state: [:draft, :ready_for_review, :published] + # -- Relationships -------------------------------------------------------- has_many :evidence, dependent: :destroy has_many :affected, through: :evidence, source: :node diff --git a/db/migrate/20230303080209_add_state_to_issues.rb b/db/migrate/20230303080209_add_state_to_issues.rb new file mode 100644 index 000000000..c126f92fc --- /dev/null +++ b/db/migrate/20230303080209_add_state_to_issues.rb @@ -0,0 +1,13 @@ +class AddStateToIssues < ActiveRecord::Migration[6.1] + def up + add_column :notes, :state, :integer, default: 0, null: false + + Issue.transaction do + Issue.update_all(state: :published) + end + end + + def down + remove_column :notes, :state + end +end diff --git a/db/schema.rb b/db/schema.rb index ed8d97bc6..b177f2124 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_03_16_202870) do +ActiveRecord::Schema.define(version: 2023_03_03_080209) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false @@ -152,6 +152,7 @@ t.integer "category_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "state", default: 0, null: false t.index ["category_id"], name: "index_notes_on_category_id" t.index ["node_id"], name: "index_notes_on_node_id" end diff --git a/spec/factories/issues.rb b/spec/factories/issues.rb index 6b0a80497..d2b42a7a6 100644 --- a/spec/factories/issues.rb +++ b/spec/factories/issues.rb @@ -4,6 +4,7 @@ author { "factory_bot" } category { Category.issue } node { Project.new.issue_library } + state { :published } trait :tagged_issue do after :create do |issue| From 6ab09ea4d3b4b451429232fd4410914475c7f36f Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Fri, 3 Mar 2023 17:40:27 +0800 Subject: [PATCH 083/275] Appease rubocop --- app/models/issue.rb | 10 ++++------ spec/factories/issues.rb | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/models/issue.rb b/app/models/issue.rb index 050d3f8bc..a39a78a9f 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -28,7 +28,7 @@ class Issue < Note # # FIXME - ISSUE/NOTE INHERITANCE def activities(*params) - Activity.where(trackable_type: "Issue", trackable_id: self.id) + Activity.where(trackable_type: 'Issue', trackable_id: self.id) end # `has_many :comments` doesn't work as normal here, because we're not @@ -68,10 +68,8 @@ def subscriptions(*params) # -- Validations ---------------------------------------------------------- - # -- Scopes --------------------------------------------------------------- - # -- Class Methods -------------------------------------------------------- # Create a hash with all issues where the keys correspond to the field passed @@ -108,14 +106,14 @@ def <=>(other) # This is useful in a number of views to present or hide information about # all the instances for a given issue and node/host. def evidence_by_node() - results = Hash.new{|h,k| h[k] = [] } + results = Hash.new { |h, k| h[k] = [] } self.evidence.includes(:node).each do |evidence| results[evidence.node] << evidence end # This sorts nodes by IP address. Non-IPs appear first - results.sort_by do |node,_| + results.sort_by do |node, _| node.label.split('.').map(&:to_i) end end @@ -129,7 +127,7 @@ def merge(issue_ids) issue_ids = [issue_ids] if issue_ids.is_a?(Integer) # check all specified ids are integers - return merged unless issue_ids.all?{|i| i.is_a? Integer} + return merged unless issue_ids.all? { |i| i.is_a? Integer } # assert current id is not there issue_ids -= [id] diff --git a/spec/factories/issues.rb b/spec/factories/issues.rb index d2b42a7a6..a7b7c3ba6 100644 --- a/spec/factories/issues.rb +++ b/spec/factories/issues.rb @@ -1,7 +1,7 @@ FactoryBot.define do factory :issue do - sequence(:text){ |n| "#[Title]#\nRspec multiple Apache bugs #{n}\n\n#[Description]#\nFoo" } - author { "factory_bot" } + sequence(:text) { |n| "#[Title]#\nRspec multiple Apache bugs #{n}\n\n#[Description]#\nFoo" } + author { 'factory_bot' } category { Category.issue } node { Project.new.issue_library } state { :published } From 45b6391468068e9d34f96b1481ca043beabc656f Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Fri, 3 Mar 2023 19:54:41 +0800 Subject: [PATCH 084/275] Add state to issue form and controller handling --- app/controllers/issues_controller.rb | 2 +- app/views/issues/_form.html.erb | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 0c40e4848..7dd4b64dc 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -183,7 +183,7 @@ def set_or_initialize_tags end def issue_params - params.require(:issue).permit(:tag_list, :text) + params.require(:issue).permit(:state, :tag_list, :text) end def set_auto_save_key diff --git a/app/views/issues/_form.html.erb b/app/views/issues/_form.html.erb index f687160d9..b02038f2e 100644 --- a/app/views/issues/_form.html.erb +++ b/app/views/issues/_form.html.erb @@ -31,6 +31,8 @@ <%= render 'tag_input', f: f %> + <%= f.select :state, Issue.states.map { |s, id| [s.humanize, s] } %> +
<%= f.button :submit, nil, class: 'btn btn-primary' %> or <%= From 951692ea0add7ab3e3e1c8c0e93eb648b5e5faac Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Fri, 3 Mar 2023 16:18:05 +0100 Subject: [PATCH 085/275] add a split button with state selection --- .../stylesheets/tylium/modules/_buttons.scss | 37 +++++++++++++++ app/views/issues/_form.html.erb | 46 ++++++++++++++----- 2 files changed, 72 insertions(+), 11 deletions(-) diff --git a/app/assets/stylesheets/tylium/modules/_buttons.scss b/app/assets/stylesheets/tylium/modules/_buttons.scss index d5cef2f4a..932d96355 100644 --- a/app/assets/stylesheets/tylium/modules/_buttons.scss +++ b/app/assets/stylesheets/tylium/modules/_buttons.scss @@ -48,3 +48,40 @@ } } } + +.btn-states { + span:not(:last-child) { + .state { + border-bottom: 1px solid $borderColor; + } + } + .state { + display: flex; + margin: 0; + padding: 0.5rem; + + &:hover { + background-color: $dropdownLinkBackgroundHover; + } + + i { + color: transparent; + margin: 0.25rem 0.25rem 0 0; + } + + input:checked + i { + color: $primaryColor; + } + + .state-label { + p { + color: $primaryColor; + margin: 0; + } + + span { + font-size: 0.8rem; + } + } + } +} diff --git a/app/views/issues/_form.html.erb b/app/views/issues/_form.html.erb index b02038f2e..797c29072 100644 --- a/app/views/issues/_form.html.erb +++ b/app/views/issues/_form.html.erb @@ -31,17 +31,41 @@ <%= render 'tag_input', f: f %> - <%= f.select :state, Issue.states.map { |s, id| [s.humanize, s] } %> -
- <%= f.button :submit, nil, class: 'btn btn-primary' %> or - <%= - link_to 'Cancel', - @issue.new_record? ? project_issues_path(current_project) : [current_project, @issue], - class: 'cancel-link', - data: { - behavior: 'clear-local-auto-save' - } - %> + <% verb = @issue.persisted? ? 'Update' : 'Create' %> +
+ <%= f.button :submit, "#{verb} Issue (draft)", class: 'btn btn-primary', data: { behavior: 'state-button' } %> + +
+ or + <%= + link_to 'Cancel', + @issue.new_record? ? project_issues_path(current_project) : [current_project, @issue], + class: 'cancel-link', + data: { + behavior: 'clear-local-auto-save' + } + %> +
<% end %> From ae4af7f915822e7efffce7a07e7909bd889b7dc2 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Fri, 3 Mar 2023 16:23:02 +0100 Subject: [PATCH 086/275] add js to update the button's text on state change --- app/assets/javascripts/tylium.js | 2 +- .../javascripts/tylium/modules/state_button.js | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/tylium/modules/state_button.js diff --git a/app/assets/javascripts/tylium.js b/app/assets/javascripts/tylium.js index c2d21a778..3ce0882cf 100644 --- a/app/assets/javascripts/tylium.js +++ b/app/assets/javascripts/tylium.js @@ -49,7 +49,6 @@ //= require tylium/engines //= require tylium/keyboard_shortcuts - //= require tylium/modules/configurations //= require tylium/modules/export //= require tylium/modules/fileupload @@ -57,6 +56,7 @@ //= require tylium/modules/nodes //= require tylium/modules/search //= require tylium/modules/sidebar +//= require tylium/modules/state_button //= require tylium/modules/activities/poller // require tylium/modules/tour //= require tylium/modules/uploads diff --git a/app/assets/javascripts/tylium/modules/state_button.js b/app/assets/javascripts/tylium/modules/state_button.js new file mode 100644 index 000000000..89dd572a0 --- /dev/null +++ b/app/assets/javascripts/tylium/modules/state_button.js @@ -0,0 +1,16 @@ +document.addEventListener('turbolinks:load', function () { + if ($('[data-behavior~=state-radio]').length) { + function updateBtnText($selectedRadio) { + selectedState = $selectedRadio + .parent() + .find('[data-behavior~=state-label]'); + $('[data-behavior~=state-button]').val(selectedState.text()); + } + + updateBtnText($('[data-behavior~=state-radio]:checked')); + + $('[data-behavior~=state-radio]').on('change', function () { + updateBtnText($(this)); + }); + } +}); From ab681ee23d92918d7f1dd1e4209bf515956ad9a4 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Fri, 3 Mar 2023 16:57:51 +0100 Subject: [PATCH 087/275] use string for radio button value --- app/views/issues/_form.html.erb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/issues/_form.html.erb b/app/views/issues/_form.html.erb index 797c29072..7473175f0 100644 --- a/app/views/issues/_form.html.erb +++ b/app/views/issues/_form.html.erb @@ -39,18 +39,18 @@ Toggle Dropdown
- - - - <% @all_columns.each do |column| %> - - <% end %> - - - - - <% issues.each do |issue| %> + + + + <% @all_columns.each do |column| %> + + <% end %> + + + + + <% issues.each do |issue| %> <% cache [issue, @all_columns, issue.affected_count, 'issues-table'] do %> - - - <% @all_columns.each do |column| %> - <% - sort, display = - case column - when 'Title' - [issue.title, link_to(issue.title, [current_project, issue])] - when 'Tags' - [ - issue.tags.any? ? issue.tags.first.display_name : '', - tag_and_name_for(issue) - ] - when 'Affected' - # this count is coming from the SQL finder in the controller - [ - issue.affected_count, - issue.affected.map { |node| link_to(node.label, [current_project, node]) }.join("\n").html_safe - ] - when 'Created' - [issue.created_at.to_i, local_time_ago(issue.created_at)] - when 'Created by' - [issue.author, issue.author] - when 'Updated' - [issue.updated_at.to_i, local_time_ago(issue.updated_at)] - else - [issue.fields.fetch(column, ''), markup(issue.fields.fetch(column, ''))] - end - %> - <%= content_tag :td, - display, - class: class_names('text-break-spaces': column == 'Affected'), - data: { - behavior: class_names(tag: column == 'Tags'), - sort: sort - } - %> - <% end %> - - + + + <% @all_columns.each do |column| %> + <% sort, display = + case column + when 'Title' + [issue.title, link_to(issue.title, [current_project, issue])] + when 'Tags' + [ + issue.tags.any? ? issue.tags.first.display_name : '', + tag_and_name_for(issue) + ] + when 'Affected' + # this count is coming from the SQL finder in the controller + [ + issue.affected_count, + issue.affected.map { |node| link_to(node.label, [current_project, node]) }.join("\n").html_safe + ] + when 'Created' + [issue.created_at.to_i, local_time_ago(issue.created_at)] + when 'Created by' + [issue.author, issue.author] + when 'State' + [issue.state, issue.state.humanize] + when 'Updated' + [issue.updated_at.to_i, local_time_ago(issue.updated_at)] + else + [issue.fields.fetch(column, ''), markup(issue.fields.fetch(column, ''))] + end + %> + <%= content_tag :td, + display, + class: class_names('text-break-spaces': column == 'Affected'), + data: { + behavior: class_names(tag: column == 'Tags'), + sort: sort + } + %> + <% end %> + + <% end %> <% end %> From 1c44f70b57feb804984bee11e4fdffe47ce21bf4 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Fri, 3 Mar 2023 18:13:41 +0100 Subject: [PATCH 091/275] select notes.state when setting issues --- app/controllers/issues_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index f91c0fe5e..1d426719c 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -147,7 +147,7 @@ def set_issues # index and a TOCTOR can appear between the Note read and the Issue.find Note.transaction do @unsorted_issues = Issue.where(node_id: @issuelib.id).select( - 'notes.id, notes.author, notes.text, '\ + 'notes.id, notes.author, notes.text, notes.state, '\ 'count(evidence.id) as affected_count, notes.created_at, notes.updated_at' ). joins('LEFT OUTER JOIN evidence on notes.id = evidence.issue_id'). From 1762a4961283fd6d7c9445cb6ad261cab2ea63c5 Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Mon, 6 Mar 2023 16:36:02 +0800 Subject: [PATCH 092/275] Add specs for states --- spec/features/issues_spec.rb | 65 ++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index 35f307228..959987899 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -74,6 +74,33 @@ include_examples 'creates an Activity', :create, Issue + context 'with states' do + it 'creates a new draft Issue' do + expect { submit_form }.to change { current_project.issues.count }.by(1) + issue = current_project.issues.last + expect(issue.state).to eq('draft') + end + + it 'creates a new ready for review Issue' do + within '.btn-states' do + click_button 'Toggle Dropdown' + find('p[data-behavior="state-label"]', text: 'Create Issue (Ready for review)').click + end + expect { submit_form }.to change { current_project.issues.count }.by(1) + issue = current_project.issues.last + expect(issue.state).to eq('ready_for_review') + end + + it 'creates a new published Issue' do + within '.btn-states' do + click_button 'Toggle Dropdown' + find('p[data-behavior="state-label"]', text: 'Create Issue (Published)').click + end + expect { submit_form }.to change { current_project.issues.count }.by(1) + issue = current_project.issues.last + expect(issue.state).to eq('published') + end + end end context 'submitting the form with invalid information' do @@ -193,6 +220,38 @@ end end + context 'with states' do + it 'updates the issue\'s state to draft' do + within '.btn-states' do + click_button 'Toggle Dropdown' + find('p[data-behavior="state-label"]', text: 'Update Issue (Draft)').click + end + submit_form + expect(@issue.reload.state).to eq('draft') + end + + it 'updates the issue\'s state to ready for review' do + within '.btn-states' do + click_button 'Toggle Dropdown' + find('p[data-behavior="state-label"]', text: 'Update Issue (Ready for review)').click + end + submit_form + expect(@issue.reload.state).to eq('ready_for_review') + end + + it 'updates the issue\'s state to published' do + @issue = create(:issue, node: issuelib, updated_at: 2.seconds.ago, state: 'draft') + visit edit_project_issue_path(current_project, @issue) + + within '.btn-states' do + click_button 'Toggle Dropdown' + find('p[data-behavior="state-label"]', text: 'Update Issue (Published)').click + end + submit_form + expect(@issue.reload.state).to eq('published') + end + end + let(:column) { :text } let(:record) { @issue } it_behaves_like 'a page which handles edit conflicts' @@ -317,6 +376,12 @@ include_examples 'deleted item is listed in Trash', :issue include_examples 'recover deleted item', :issue end + + context 'with states' do + it 'shows the issue states in the view' do + expect(page).to have_text "(#{@issue.state.humanize})" + end + end end end From 2b58ead533d5856100014ce836fe5f1b6f13e21c Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Mon, 6 Mar 2023 16:44:16 +0800 Subject: [PATCH 093/275] Appease rubocop --- spec/features/issues_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index 959987899..24c90307f 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -387,7 +387,7 @@ describe 'revision history' do let(:issue) do - issue = create(:issue, node:, text: 'issue text') + issue = create(:issue, node: node, text: 'issue text') issue.update(text: 'updated text') issue end From 682f328c5a2f4c8165abc642769395c3b34f1e41 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Mon, 6 Mar 2023 10:20:22 +0100 Subject: [PATCH 094/275] prevent textile-toolbar rendering over dropdown --- vendor/assets/stylesheets/jquery.textile.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/assets/stylesheets/jquery.textile.scss b/vendor/assets/stylesheets/jquery.textile.scss index e124c55b9..d684e632b 100644 --- a/vendor/assets/stylesheets/jquery.textile.scss +++ b/vendor/assets/stylesheets/jquery.textile.scss @@ -1,7 +1,7 @@ .textile-wrap { ul.textile-toolbar { position: relative; - z-index: 999; + z-index: 3; height: 33px; left: 0; top: 0; From b7f585f1d01fb3677139d7e70a040403a79258b4 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Mon, 6 Mar 2023 10:27:16 +0100 Subject: [PATCH 095/275] prevent cached state selection from causing confusion about the issue's current state when the form has cached content --- app/views/issues/edit.html.erb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/issues/edit.html.erb b/app/views/issues/edit.html.erb index a07f60143..b55c0d838 100644 --- a/app/views/issues/edit.html.erb +++ b/app/views/issues/edit.html.erb @@ -1,4 +1,4 @@ -<% content_for :title, 'Edit issue' %> +<% content_for :title, "Edit issue" %> <% content_for :sidebar do %> <%= render 'sidebar'%> @@ -13,8 +13,9 @@
-

Edit issue

-
+

Edit issue (<%= @issue.state.humanize %>)

+ +
<%= render 'form' %>
From 3e12f984beb53c16829153ae57930c28e1a8a1d7 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Mon, 6 Mar 2023 10:30:07 +0100 Subject: [PATCH 096/275] lint --- app/views/issues/edit.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/issues/edit.html.erb b/app/views/issues/edit.html.erb index b55c0d838..31cd8d24e 100644 --- a/app/views/issues/edit.html.erb +++ b/app/views/issues/edit.html.erb @@ -1,7 +1,7 @@ -<% content_for :title, "Edit issue" %> +<% content_for :title, 'Edit issue' %> <% content_for :sidebar do %> - <%= render 'sidebar'%> + <%= render 'sidebar' %> <% end %> <% content_for :breadcrumbs do %> From 86b47adc661e5e0679762240008de1fa5c60b3e5 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Mon, 6 Mar 2023 10:39:59 +0100 Subject: [PATCH 097/275] consistency --- app/views/issues/edit.html.erb | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/app/views/issues/edit.html.erb b/app/views/issues/edit.html.erb index 31cd8d24e..6c5c1fc99 100644 --- a/app/views/issues/edit.html.erb +++ b/app/views/issues/edit.html.erb @@ -10,13 +10,11 @@ <% end %> -
-
-
-

Edit issue (<%= @issue.state.humanize %>)

- -
- <%= render 'form' %> -
+
+
+

Edit issue (<%= @issue.state.humanize %>)

+ +
+ <%= render 'form' %>
From b8fe2e073a58f503283519a87efc9f55d83621ec Mon Sep 17 00:00:00 2001 From: Aaron Manaloto Date: Mon, 6 Mar 2023 20:27:26 +0800 Subject: [PATCH 098/275] Add initial QA index view --- app/controllers/qa/issues_controller.rb | 8 ++++++++ app/views/issues/_table.html.erb | 23 ++++++++++++----------- app/views/issues/index.html.erb | 2 +- app/views/qa/issues/index.html.erb | 17 +++++++++++++++++ config/initializers/inflections.rb | 1 + config/routes.rb | 4 ++++ 6 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 app/controllers/qa/issues_controller.rb create mode 100644 app/views/qa/issues/index.html.erb diff --git a/app/controllers/qa/issues_controller.rb b/app/controllers/qa/issues_controller.rb new file mode 100644 index 000000000..c6e2c369b --- /dev/null +++ b/app/controllers/qa/issues_controller.rb @@ -0,0 +1,8 @@ +class QA::IssuesController < AuthenticatedController + include ProjectScoped + + def index + @issues = Issue.ready_for_review + @all_columns = ['Title'] + end +end diff --git a/app/views/issues/_table.html.erb b/app/views/issues/_table.html.erb index 84182a413..abb0b7870 100644 --- a/app/views/issues/_table.html.erb +++ b/app/views/issues/_table.html.erb @@ -1,13 +1,14 @@ <% cache ['issues-table', @all_columns, issues.map(&:id), @issues.map(&:updated_at).map(&:to_i).sort.last, @tags] do %> -
Select<%= column %>Actions
Select<%= column %>Actions
- <%= link_to edit_project_issue_path(current_project, issue), class: '' do %> - Edit - <% end %> - <%= link_to [current_project, issue], method: :delete, data: { confirm: "Are you sure?\n\nProceeding will delete this issue and any associated evidence." }, class: 'text-error-hover' do %> - Delete - <% end %> -
+ <%= link_to edit_project_issue_path(current_project, issue), class: '' do %> + Edit + <% end %> + <%= link_to [current_project, issue], method: :delete, data: { confirm: "Are you sure?\n\nProceeding will delete this issue and any associated evidence." }, class: 'text-error-hover' do %> + Delete + <% end %> +
+ <% table_attributes = { + behavior: 'dradis-datatable', + 'default-columns': @default_columns.to_json, + 'item-name': 'issue', + 'local-storage-key': local_storage_key, + 'tags-path': project_tags_path(current_project), + 'new-tag-path': new_project_tag_path(current_project) + }%> + <% table_attributes.merge!(tags: @tags.map { |t| [t.display_name, t.color, t.name] }.to_json) if local_assigns[:tags] %> + <%= tag.table class: 'table table-striped mb-0', data: table_attributes do %> @@ -19,7 +20,7 @@ <% issues.each do |issue| %> - <% cache [issue, @all_columns, issue.affected_count, 'issues-table'] do %> + <% cache [issue, @all_columns, issue.try(:affected_count), 'issues-table'] do %> <% @all_columns.each do |column| %> @@ -70,5 +71,5 @@ <% end %> <% end %> -
Select
+ <% end %> <% end %> diff --git a/app/views/issues/index.html.erb b/app/views/issues/index.html.erb index 26c660c0e..5ef34f160 100644 --- a/app/views/issues/index.html.erb +++ b/app/views/issues/index.html.erb @@ -15,7 +15,7 @@ data-table-destroy-confirmation="Are you sure? Proceeding will delete the selected issue(s) and any associated evidence." data-table-close-console-url="<%= project_issues_path(current_project) %>" data-table-merge-url="<%= new_project_merge_path(current_project) %>" > - <%= render 'table', issues: @issues %> + <%= render partial: 'table', locals: { issues: @issues, local_storage_key: "project.ce.#{dom_id(current_project)}.issues_datatable", tags: @tags } %>
<% else %> <%= render 'shared/empty_state', diff --git a/app/views/qa/issues/index.html.erb b/app/views/qa/issues/index.html.erb new file mode 100644 index 000000000..016c76f7e --- /dev/null +++ b/app/views/qa/issues/index.html.erb @@ -0,0 +1,17 @@ +<% content_for :title, 'Quality Assurance' %> + + +
+
+ <% if @issues.any? %> + <%= render partial: 'issues/table', locals: { issues: @issues, local_storage_key: "project.ce.#{dom_id(current_project)}.qa_issues_datatable" } %> + <% else %> + <%= render 'shared/empty_state', + actions_partial: 'issues/empty_state_actions', + name: 'issue', + docs_link: 'https://dradisframework.com/support/guides/projects/issues.html', + text: 'Use issues to represent vulnerabilities or findings. Issues contain general information, such as: Title, Description, Recommendation, CVE\'s, etc. Issues are the findings you\'ll end up including in your report.' + %> + <% end %> +
+
diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index 68a321337..524ee60f9 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -15,4 +15,5 @@ inflect.acronym 'IPs' inflect.acronym 'OS' inflect.acronym 'OSs' + inflect.acronym 'QA' end diff --git a/config/routes.rb b/config/routes.rb index 028724557..6c03b854e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -95,6 +95,10 @@ resources :tags, except: [:show] + namespace :qa do + resources :issues, only: [:index, :show, :edit] + end + get 'search' => 'search#index' get 'trash' => 'revisions#trash' From d6c1e972f87aff196335f5508f80e2f3566529b4 Mon Sep 17 00:00:00 2001 From: Matt Budz Date: Mon, 6 Mar 2023 16:36:04 +0100 Subject: [PATCH 099/275] move change project to navbar brand --- .../stylesheets/tylium/modules/_navbar.scss | 29 ++++++++++++------- app/views/layouts/tylium/_navbar.html.erb | 10 ++++--- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/app/assets/stylesheets/tylium/modules/_navbar.scss b/app/assets/stylesheets/tylium/modules/_navbar.scss index 3bd2614e9..1bcf03ce1 100644 --- a/app/assets/stylesheets/tylium/modules/_navbar.scss +++ b/app/assets/stylesheets/tylium/modules/_navbar.scss @@ -6,21 +6,28 @@ z-index: 3; .navbar-brand { - color: $defaultText; + align-items: center; + display: flex; + gap: 0.5rem; margin-left: 6.4rem; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - &:hover { + .change-project-link { + font-size: 75%; + padding-top: 0.15rem; + } + + .project-title { color: $defaultText; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } @media screen and (min-width: 992px) { max-width: calc(100% - 780px); } - @include media-breakpoint-down(md) { + @include media-breakpoint-down(md) { margin-left: 0; } } @@ -43,7 +50,7 @@ .navbar-nav { flex-direction: column; align-items: flex-start; - padding: .25rem 0; + padding: 0.25rem 0; border: 1px solid $borderColor; .nav-item { @@ -58,14 +65,14 @@ position: initial; .dropdown-item { - padding-right: 1rem + padding-right: 1rem; } } .nav-link { color: $linkColor; font-size: 0.9rem; - padding: .25rem 1rem; + padding: 0.25rem 1rem; transition: color 0s; .fa { @@ -101,7 +108,7 @@ z-index: 2; .dropdown-menu { - border-radius: 0 0 .5rem .5rem; + border-radius: 0 0 0.5rem 0.5rem; margin-top: 0.6rem; } @@ -153,7 +160,7 @@ } .navbar-toggler-icon { - color: $linkColor + color: $linkColor; } } diff --git a/app/views/layouts/tylium/_navbar.html.erb b/app/views/layouts/tylium/_navbar.html.erb index 4601d22ad..feb755236 100644 --- a/app/views/layouts/tylium/_navbar.html.erb +++ b/app/views/layouts/tylium/_navbar.html.erb @@ -1,6 +1,11 @@