Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1042 fixed filtering by status in classic mode #1046

Merged
merged 2 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ GEM
rack
ast (2.4.2)
aws-eventstream (1.3.0)
aws-partitions (1.1031.0)
aws-partitions (1.1032.0)
aws-sdk-core (3.214.1)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
Expand Down Expand Up @@ -524,7 +524,7 @@ CHECKSUMS
appsignal (4.3.2) sha256=b1f988815f2f972e9cba49eac6c459b1b2c376638d7c3c17c8c6e872d4d51043
ast (2.4.2) sha256=1e280232e6a33754cde542bc5ef85520b74db2aac73ec14acef453784447cc12
aws-eventstream (1.3.0) sha256=f1434cc03ab2248756eb02cfa45e900e59a061d7fbdc4a9fd82a5dd23d796d3f
aws-partitions (1.1031.0) sha256=b29f1e6e9ea047d3272031c1a1ad2ab874157e45a7e705fae8e12c5e2845fa55
aws-partitions (1.1032.0) sha256=8ae20dbd109e115f52989f2d09fe83bd05b25ea0d1e4c66c4ae0f7c80e95eeac
aws-sdk-core (3.214.1) sha256=419b317407d736a19f8b7c422ec134630dc283766a0f9171ceaa2704e82d49fd
aws-sdk-lambda (1.144.0) sha256=0299f2e961aa2e4bd6f34cde39ea9b66b2eb43057a8df36eb54d0f022d091d49
aws-sdk-rails (5.1.0) sha256=8cffd3b60142e12a6747c91a7a609f668276b1082fc0c10810d5da3d14b13189
Expand Down
12 changes: 4 additions & 8 deletions app/controllers/accounts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def index

def show
@account.readonly!
render 'show'
end

def new
Expand All @@ -37,15 +38,15 @@ def create
authorize(@account)

if @account.save
redirect_to(accounts_path, notice: 'Account was successfully created.')
redirect_to(edit_account_path(@account), notice: 'Account was successfully created.')
else
render(:new)
end
end

def update
if @account.update(account_params)
redirect_to(accounts_path, notice: 'Account was successfully updated.')
redirect_to(account_path(@account), notice: 'Account was successfully updated.')
else
render(:edit)
end
Expand Down Expand Up @@ -77,16 +78,11 @@ def account_params
params.fetch(:account, {}).permit(
:name,
:description,
:weblink,
:stakeholder_type_id,
:welcome_message,
:classic_grid_mode,
:deactivated,
:expires_on,
:max_users,
:max_scorecards,
:solution_ecosystem_maps,
:allow_transition_cards,
:allow_sustainable_development_goal_alignment_cards,
:transition_card_model_name,
:transition_card_focus_area_group_model_name,
:transition_card_focus_area_model_name,
Expand Down
51 changes: 40 additions & 11 deletions app/helpers/checklist_items_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ module ChecklistItemsHelper
other: 'bg-gray-200 dark:bg-gray-600'
}.freeze

CHECKLIST_LIST_ITEM_COLOR_OPACITY = {
actual: 'FF',
planned: '99',
more_information: '66',
suggestion: '40',
other: '00'
}.freeze

CHECKLIST_LIST_ITEM_RADIO_BUTTON_COLOR_CLASSES = {
actual: 'text-sky-600 focus:ring-sky-600',
planned: 'text-teal-500 focus:ring-teal-500',
Expand All @@ -56,16 +64,19 @@ def focus_area_grid_element(focus_area_data)
)
end

def checklist_list_item_grid_element(checklist_item_data)
background_color = checklist_list_item_grid_element_color(checklist_item_data[:status])
def checklist_list_item_grid_element(checklist_item_data:, grid_mode:)
options = checklist_list_item_grid_element_base_options(checklist_item_data)

content_tag(
:div,
'',
class: "p-1.5 h-2 rounded-sm #{background_color}",
title: checklist_item_data[:name],
data: { status: checklist_item_data[:status] }
)
case grid_mode
when :modern
background_color_class = checklist_list_item_status_color(checklist_item_data[:status])
options[:class] = "#{options[:class]} #{background_color_class}"
when :classic
background_color_hex = checklist_list_item_focus_area_status_color(checklist_item_data)
options[:style] = "background-color: #{background_color_hex}"
end

content_tag(:div, '', options)
end

def current_comment_status_style(checklist_item)
Expand All @@ -85,14 +96,32 @@ def checklist_item_badge(checklist_item) # rubocop:disable Metrics/MethodLength
comments_target: 'badge',
toggle: 'tooltip',
placement: 'top',
title: checklist_item.status.humanize
title: checklist_item.status.humanizeex
}
)
end

private

def checklist_list_item_grid_element_color(status)
def checklist_list_item_grid_element_base_options(checklist_item_data)
{
class: 'p-1.5 h-2 rounded-sm',
title: checklist_item_data[:name],
data: {
status: checklist_item_data[:status],
focus_area_color: checklist_item_data[:focus_area_color]
}
}
end

def checklist_list_item_focus_area_status_color(checklist_item_data)
opacity = CHECKLIST_LIST_ITEM_COLOR_OPACITY[checklist_item_data[:status].to_sym].presence ||
CHECKLIST_LIST_ITEM_COLOR_OPACITY[:other]

checklist_item_data[:focus_area_color] + opacity
end

def checklist_list_item_status_color(status)
CHECKLIST_LIST_ITEM_COLOR_CLASSES[status.to_sym].presence ||
CHECKLIST_LIST_ITEM_COLOR_CLASSES[:other]
end
Expand Down
4 changes: 4 additions & 0 deletions app/helpers/custom_form_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ def multi_select(method, choices = nil, options = {}, html_options = {}, &block)
end
end

def number_field(method, options = {})
wrap_field(method) { super(method, merge_options(method:, options:)) }
end

def password_field(method, options = {})
wrap_field(method) { super(method, merge_options(method:, options:)) }
end
Expand Down
21 changes: 18 additions & 3 deletions app/helpers/impact_cards_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,25 @@ def multi_select_options_for_labels(labels, selected_labels)
# Selected statuses are expected to be an array of strings, e.g. ["actual", "planned", ...]
#
# The color class is determined by the status name, itself expected to be a symbol, e.g. :actual, :planned, ...
def multi_select_options_for_statuses(statuses, selected_statuses)
def multi_select_options_for_statuses(statuses, selected_statuses, impact_card) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
focus_area_groups = impact_card.account.focus_area_groups.where(scorecard_type: impact_card.type)
focus_areas = FocusArea.where(focus_area_group: focus_area_groups).order(:scorecard_type, :position)
classic_mode_colors = focus_areas.map(&:actual_color).values_at(0, focus_areas.length / 2, -1).uniq

choices = statuses.map do |status|
color_class = ChecklistItemsHelper::CHECKLIST_LIST_ITEM_COLOR_CLASSES[status[1].to_sym]
icon = { icon: "<div class=\"w-3 h-3 mt-1 mr-2 bg-gray-500 rounded-full #{color_class}\">&nbsp;</div>".html_safe } # rubocop:disable Rails/OutputSafety
if impact_card.grid_mode.to_sym == :classic
icons = classic_mode_colors.map do |color|
opacity = ChecklistItemsHelper::CHECKLIST_LIST_ITEM_COLOR_OPACITY[status[1].to_sym]
status_color = "#{color}#{opacity}"

"<div class=\"w-3 h-3 mt-1 bg-gray-500 rounded-full\" style=\"background-color: #{status_color}\">&nbsp;</div>".html_safe # rubocop:disable Rails/OutputSafety,Layout/LineLength
end
icon = { icon: "<div class='flex mr-2'>#{icons.join('')}<div>".html_safe } # rubocop:disable Rails/OutputSafety
else
color_class = ChecklistItemsHelper::CHECKLIST_LIST_ITEM_COLOR_CLASSES[status[1].to_sym]
icon = { icon: "<div class=\"w-3 h-3 mt-1 mr-2 bg-gray-500 rounded-full #{color_class}\">&nbsp;</div>".html_safe } # rubocop:disable Rails/OutputSafety,Layout/LineLength
end

[*status, { data: { hs_select_option: icon.to_json(escape_html_entities: false) } }]
end

Expand Down
56 changes: 44 additions & 12 deletions app/javascript/controllers/grid_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,50 @@ export default class extends Controller {

const elements = this.gridTarget.querySelectorAll('[data-status]')

elements.forEach(element => {
const status = element.getAttribute('data-status')
const colorClasses = this.statusColorClasses(status)

if (statuses === undefined || statuses.length == 0 || statuses.includes(status)) {
element.classList.add(...colorClasses)
element.classList.remove('bg-gray-500')
} else {
element.classList.remove(...colorClasses)
element.classList.add('bg-gray-500')
}
})
if (this.data.get('mode') == 'classic') {
elements.forEach(element => {
const status = element.getAttribute('data-status')
const baseColor = element.getAttribute('data-focus-area-color')
const opacity = this.statusBackgroundColorOpacity(status)
const color = `${baseColor}${opacity}`

if (statuses === undefined || statuses.length == 0 || statuses.includes(status)) {
element.style.backgroundColor = color
} else {
element.style.backgroundColor = '#00000000'
}
})
} else {
elements.forEach(element => {
const status = element.getAttribute('data-status')
const colorClasses = this.statusColorClasses(status)

if (statuses === undefined || statuses.length == 0 || statuses.includes(status)) {
element.classList.add(...colorClasses)
element.classList.remove('bg-gray-500')
} else {
element.classList.remove(...colorClasses)
element.classList.add('bg-gray-500')
}
})
}
}


// NOTE: Duplicated in checklist_items_helper.rb
statusBackgroundColorOpacity(status) {
switch (status) {
case 'actual':
return 'FF'
case 'planned':
return '99'
case 'more_information':
return '66'
case 'suggestion':
return '40'
default:
return '00'
}
}

statusColorClasses(status) {
Expand Down
67 changes: 30 additions & 37 deletions app/models/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,31 @@
#
# Table name: accounts
#
# id :integer not null, primary key
# allow_sustainable_development_goal_alignment_cards :boolean default(FALSE)
# allow_transition_cards :boolean default(TRUE)
# deactivated :boolean
# deleted_at :datetime
# description :string
# expires_on :date
# expiry_warning_sent_on :date
# max_scorecards :integer default(1)
# max_users :integer default(1)
# name :string
# sdgs_alignment_card_characteristic_model_name :string default("Targets")
# sdgs_alignment_card_focus_area_group_model_name :string default("Focus Area Group")
# sdgs_alignment_card_focus_area_model_name :string default("Focus Area")
# sdgs_alignment_card_model_name :string default("SDGs Alignment Card")
# solution_ecosystem_maps :boolean
# transition_card_characteristic_model_name :string default("Characteristic")
# transition_card_focus_area_group_model_name :string default("Focus Area Group")
# transition_card_focus_area_model_name :string default("Focus Area")
# transition_card_model_name :string default("Transition Card")
# weblink :string
# welcome_message :text
# created_at :datetime not null
# updated_at :datetime not null
# stakeholder_type_id :integer
# id :integer not null, primary key
# classic_grid_mode :boolean default(FALSE)
# deactivated :boolean
# deleted_at :datetime
# deprecated_allow_sustainable_development_goal_alignment_cards :boolean default(FALSE)
# deprecated_allow_transition_cards :boolean default(TRUE)
# deprecated_solution_ecosystem_maps :boolean
# deprecated_weblink :string
# deprecated_welcome_message :text
# description :string
# expires_on :date
# expiry_warning_sent_on :date
# max_scorecards :integer default(1)
# max_users :integer default(1)
# name :string
# sdgs_alignment_card_characteristic_model_name :string default("Targets")
# sdgs_alignment_card_focus_area_group_model_name :string default("Focus Area Group")
# sdgs_alignment_card_focus_area_model_name :string default("Focus Area")
# sdgs_alignment_card_model_name :string default("SDGs Alignment Card")
# transition_card_characteristic_model_name :string default("Characteristic")
# transition_card_focus_area_group_model_name :string default("Focus Area Group")
# transition_card_focus_area_model_name :string default("Focus Area")
# transition_card_model_name :string default("Transition Card")
# created_at :datetime not null
# updated_at :datetime not null
#
class Account < ApplicationRecord
include Searchable
Expand All @@ -38,8 +38,6 @@ class Account < ApplicationRecord

EXPIRY_WARNING_PERIOD = 30.days

belongs_to :stakeholder_type, optional: true

# Direct associations
has_many :accounts_users, dependent: :destroy
has_many :communities, dependent: :destroy
Expand Down Expand Up @@ -83,22 +81,17 @@ def max_users_reached?
users.count >= max_users
end

def scorecard_types
@scorecard_types ||=
[].tap do |types|
types << TransitionCard if allow_transition_cards?
types << SustainableDevelopmentGoalAlignmentCard if allow_sustainable_development_goal_alignment_cards?
end
end
SCORECARD_TYPES = [
TransitionCard,
SustainableDevelopmentGoalAlignmentCard
].freeze

def default_scorecard_type
return scorecard_types.first if scorecard_types.size == 1

TransitionCard
end

def custom_stakeholder_types_in_use?
StakeholderType.system_stakeholder_types.order(:name).pluck(:name) != stakeholder_types.order(:name).pluck(:name)
StakeholderType.system_stakeholder_types.order(:name).pluck(:name) != SCORECARD_TYPES.order(:name).pluck(:name)
end

private
Expand Down
4 changes: 4 additions & 0 deletions app/models/scorecard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ def set_inverse_linked_scorecard
true
end

def grid_mode
@grid_mode ||= account.classic_grid_mode? ? :classic : :modern
end

def linked?
linked_scorecard_id.present?
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class User < ApplicationRecord
accepts_nested_attributes_for :accounts_users, allow_destroy: true

# Virtual attributes used when inviting or updating users
attr_accessor :initial_account_role, :initial_system_role
attr_accessor :initial_account_role, :initial_system_role, :account_role

def self.ransackable_attributes(_auth_object = nil)
%w[name email] + _ransackers.keys
Expand Down
8 changes: 1 addition & 7 deletions app/policies/scorecard_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@
class ScorecardPolicy < ApplicationPolicy # rubocop:disable Style/Documentation
class Scope < Scope # rubocop:disable Style/Documentation
def resolve
resolve_to_current_account.where(type: current_account_scorecard_types)
end

private

def current_account_scorecard_types
current_account&.scorecard_types&.map(&:name).presence || []
resolve_to_current_account
end
end

Expand Down
4 changes: 2 additions & 2 deletions app/views/accounts/_account.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<%= render partial: 'resource_summary', locals: { name: account.name, background_color: 'bg-green-700' } %>
<div class="space-y-1.5">
<div class="text-base/6 font-semibold dark:text-white">
<%= link_to highlight(account.name, params.dig(:q, :name_or_description_cont)), edit_account_path(account) %>
<%= link_to highlight(account.name, params.dig(:q, :name_or_description_cont)), account_path(account), data: { turbo: false } %>
</div>
<div class="text-xs/6 text-zinc-500">
<div class="text-xs/6 text-zinc-500 min-h-4">
<%= highlight(account.description, params.dig(:q, :name_or_description_cont)) %>
</div>
<div class="text-xs/6 text-zinc-600">
Expand Down
Loading
Loading