Skip to content

OTWO-7618 Implement figma design for organizations show page#1883

Merged
Niharika1117 merged 4 commits intoOTWO-7546from
OTWO-7618
Apr 14, 2026
Merged

OTWO-7618 Implement figma design for organizations show page#1883
Niharika1117 merged 4 commits intoOTWO-7546from
OTWO-7618

Conversation

@bd-vaibhav
Copy link
Copy Markdown
Collaborator

No description provided.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Implements updated Explore Organizations page layout and styling (per Figma), including a new responsive “cards on mobile / table on desktop” org activity view and a standardized icon rendering approach via decorators.

Changes:

  • Reworked Explore Orgs page layout/partials and added mobile card rendering for 30-day commit volume.
  • Introduced global icon container/letter styling and updated project/org icon decorators to use it.
  • Updated orgs page styling (including dark theme adjustments) and added org type sort options.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
config/shared/sort_options.yml Adds org type filter option set.
app/views/projects/_project_index.html.haml Switches project icon rendering to decorator output.
app/views/explore/orgs_by_thirty_day_commit_volume.js.haml Adds mobile card HTML injection and updated show/hide behavior.
app/views/explore/orgs.html.haml Rebuilds Explore Orgs page layout and header.
app/views/explore/_stats_by_sector.html.haml Updates table wrapper/markup styling hooks.
app/views/explore/_orgs_by_30_day_commit_volume.html.haml Replaces chosen select with a custom dropdown; adds mobile card markup + desktop table class.
app/views/explore/_newest_orgs.html.haml Updates newest orgs layout to card design.
app/views/explore/_most_active_orgs.html.haml Updates most active orgs layout to card design.
app/decorators/project_decorator.rb Extends icon API to pass container class and dimensions behavior.
app/decorators/organization_decorator.rb Extends icon API to pass container class.
app/decorators/icon.rb Wraps icon output in a container div and uses a span letter fallback.
app/assets/stylesheets/projects.sass Removes old per-view project icon CSS; small layout tweaks.
app/assets/stylesheets/orgs.sass Adds extensive new Explore Orgs styling incl. responsive behavior and dark theme overrides.
app/assets/stylesheets/explore.sass Adjusts explore header spacing.
app/assets/stylesheets/dark_theme.sass Updates dark theme border colors for common components.
app/assets/stylesheets/base.sass Adds global icon container + icon-letter styling and a broad icon display override.
app/assets/javascripts/orgs.js Adds dark-theme gauge config and custom dropdown AJAX filtering hook.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +108 to +117
var filterOrgs = function(filterValue) {
$('.busy#commit_volume_loader').removeClass('hidden')
$.ajax({
url: '/explore/orgs_by_thirty_day_commit_volume?format=js&filter='+ $(this).val(),
url: '/explore/orgs_by_thirty_day_commit_volume?format=js&filter='+ filterValue,
type: "GET",
success: function(){
$('#orgs_by_30_days_volume table').toggleClass('hidden')
$('.busy#commit_volume_loader').toggleClass('hidden')
$('.busy#commit_volume_loader').addClass('hidden')
}
})
})
};
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The view code in this PR computes the current selection from params[:org_type] and emits a hidden input named org_type, but the AJAX request here sends filter=.... This mismatch will cause the selected filter to not round-trip correctly (e.g., refresh/back/initial render won’t reflect the active selection). Use a single parameter name consistently (either change the AJAX query param to org_type or update the view/controller to use filter).

Copilot uses AI. Check for mistakes.
Comment thread app/decorators/icon.rb
Comment on lines +12 to +22
def image(with_dimensions: true, container_class: 'icon-container')
container_classes = "#{container_class} #{logo ? 'has-logo' : ''}"
content = if logo
width_and_height = with_dimensions ? dimensions : ''
css_style = "#{width_and_height} border:0 none;"
image_tag(logo.attachment.url(size), style: css_style, itemprop: 'image', alt: 'img avatar')
else
content_tag :p, name.first.capitalize, style: default_style
content_tag :span, name.first.upcase, class: 'icon-letter'
end

content_tag :div, content, class: container_classes
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This removes the previous ‘broken image’ fallback behavior (the old view used an onerror handler to hide the image and show the letter). With the new implementation, if a logo URL 404s or fails to load, users will see a broken image and no letter fallback. Consider rendering both the <img> and the letter and toggling via CSS/JS, or reintroducing an onerror handler that swaps to the letter fallback and updates/removes the has-logo styling.

Copilot uses AI. Check for mistakes.
Comment thread app/decorators/icon.rb Outdated
content = if logo
width_and_height = with_dimensions ? dimensions : ''
css_style = "#{width_and_height} border:0 none;"
image_tag(logo.attachment.url(size), style: css_style, itemprop: 'image', alt: 'img avatar')
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alt text is hard-coded to 'img avatar', which is not descriptive and will be confusing for screen readers. Use an alt derived from the object name (e.g., organization/project name) or set alt: '' if the image is purely decorative and the adjacent link/text already conveys the name.

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +27
- mobile_cards_html = capture do
- @org_by_30_day_commits.each do |org_30_day_activity|
- org = org_30_day_activity.organization
.org-card
.org-card-header
= link_to org.decorate.icon(:small), organization_path(org), title: org.name, class: 'org-card-icon'
= link_to h(truncate(org.name, length: 24)), organization_path(org), title: org.name, class: 'org-card-name'
%span.org-card-size= org_30_day_activity.decorate.project_count_text
.org-card-body
.org-card-row
.org-card-label= t '.type'
.org-card-value= org.org_type_label
.org-card-row
.org-card-label= t '.projects'
.org-card-value= org_30_day_activity.project_count
.org-card-row
.org-card-label= t '.affiliates'
.org-card-value= org_30_day_activity.affiliate_count
.org-card-row
.org-card-label= t '30_day_commits'
.org-card-value= org_30_day_activity.thirty_day_commit_count
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mobile card markup is duplicated here (JS response) and in the initial render partial (_orgs_by_30_day_commit_volume.html.haml). This will be hard to keep consistent. Consider extracting the card into a partial (e.g., _org_30_day_activity_card) and rendering it both for the initial page and for the JS response (or have the JS response render the same partial into the mobile container).

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +17
.explore-page-wrapper
.explore-header-top
%h1= t('.title')
= render 'shared/search'

.explore-page-wrapper
.orgs-layout
.left-column
= render partial: 'most_active_orgs'
= render partial: 'newest_orgs'
.right-column
= render partial: 'orgs_by_30_day_commit_volume'
= render partial: 'stats_by_sector'
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two sibling .explore-page-wrapper containers. If the wrapper class applies spacing/constraints, this can lead to inconsistent layout and duplicated padding/margins. Prefer a single wrapper that contains both the header and the two-column layout, unless there’s a specific styling reason to split them.

Copilot uses AI. Check for mistakes.
%tr
%td.strong= Organization::ORG_TYPES.invert[orgs.org_type]
%td
#commit-gauge{ 'data-gauge' => orgs.average_commits.to_s, 'data-gauge-max' => gauge_scale.to_s, class: "gauge-#{orgs.org_type}" }
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This renders multiple elements with the same id commit-gauge (one per row), which is invalid HTML and can break CSS/JS that expects a unique id. Use a class instead (e.g., .commit-gauge) and update the stylesheet selectors accordingly.

Suggested change
#commit-gauge{ 'data-gauge' => orgs.average_commits.to_s, 'data-gauge-max' => gauge_scale.to_s, class: "gauge-#{orgs.org_type}" }
.commit-gauge{ 'data-gauge' => orgs.average_commits.to_s, 'data-gauge-max' => gauge_scale.to_s, class: "gauge-#{orgs.org_type}" }

Copilot uses AI. Check for mistakes.

// Icon Container - Global Baseline Styling
.icon-container
display: inline-flex !important
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are very broad, global overrides with !important (especially the a [class^=\"icon-\"] selector), which can unintentionally change layout for unrelated icons across the entire app. If this styling is intended primarily for Explore/Projects pages, consider scoping it under a page wrapper (e.g., #explore_orgs_page, .explore-page-wrapper, etc.) or reducing reliance on !important to minimize site-wide regressions.

Suggested change
display: inline-flex !important
display: inline-flex

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +18
%label!= t('.filter')
:ruby
current_filter = params[:org_type] || 'all_orgs'
selected_label = OrgThirtyDayActivity::SORT_TYPES.find { |opt| opt[1] == current_filter }&.first || OrgThirtyDayActivity::SORT_TYPES.first.first
.custom-sort-dropdown
%button.sort-dropdown-btn{ type: 'button' }
%span.selection{ data: { value: current_filter } }= selected_label
%i.fa.fa-chevron-down
.dropdown-menu.sort-dropdown-menu
- OrgThirtyDayActivity::SORT_TYPES.each do |label, value|
%button.sort-dropdown-item{ type: 'button', data: { value: value }, class: (value == current_filter ? 'active' : '') }= label
%input{ type: 'hidden', name: 'org_type', value: current_filter, class: 'sort-value-input', id: 'org_type' }
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replacing the native <select> with a custom button/menu needs additional accessibility support (ARIA roles/attributes like aria-expanded, aria-controls, proper focus management, keyboard navigation). If possible, keep a real <select> as the accessible baseline and enhance it visually, or fully implement ARIA + keyboard behavior for the custom component.

Suggested change
%label!= t('.filter')
:ruby
current_filter = params[:org_type] || 'all_orgs'
selected_label = OrgThirtyDayActivity::SORT_TYPES.find { |opt| opt[1] == current_filter }&.first || OrgThirtyDayActivity::SORT_TYPES.first.first
.custom-sort-dropdown
%button.sort-dropdown-btn{ type: 'button' }
%span.selection{ data: { value: current_filter } }= selected_label
%i.fa.fa-chevron-down
.dropdown-menu.sort-dropdown-menu
- OrgThirtyDayActivity::SORT_TYPES.each do |label, value|
%button.sort-dropdown-item{ type: 'button', data: { value: value }, class: (value == current_filter ? 'active' : '') }= label
%input{ type: 'hidden', name: 'org_type', value: current_filter, class: 'sort-value-input', id: 'org_type' }
%label{ for: 'org_type' }!= t('.filter')
:ruby
current_filter = params[:org_type] || 'all_orgs'
.custom-sort-dropdown
%select.sort-value-input{ name: 'org_type', id: 'org_type' }
- OrgThirtyDayActivity::SORT_TYPES.each do |label, value|
%option{ value: value, selected: (value == current_filter) }= label

Copilot uses AI. Check for mistakes.
@Niharika1117 Niharika1117 merged commit a6ff577 into OTWO-7546 Apr 14, 2026
1 check passed
@Niharika1117 Niharika1117 deleted the OTWO-7618 branch April 14, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants