diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 35ccb2c7d8..ed5c797138 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Set up Ruby uses: ruby/setup-ruby@v1 @@ -47,7 +47,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Set up Ruby uses: ruby/setup-ruby@v1 diff --git a/AGENTS.md b/AGENTS.md index 0443af703b..ab63e0cd64 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -51,7 +51,7 @@ This codebase (Rails 8.1) | `app/models/` | ActiveRecord models | ~78 files | | `app/services/` | Service objects and POROs (e.g. `MoneyFormatter` for currency display) | ~29 files | | `app/jobs/` | SolidQueue background jobs | 3 files | -| `app/models/concerns/` | Shared model modules | 15 concerns | +| `app/models/concerns/` | Shared model modules | 16 concerns | ### Presentation @@ -104,6 +104,8 @@ This codebase (Rails 8.1) | `Organization` | Groups with affiliations, addresses, logos via ActiveStorage | | `Grant` | Donated funds (polymorphic `donor`: Organization or Person) with eligibility criteria, tasks, deadlines; parent of `Scholarship`. Scholarship totals cannot exceed the grant amount | | `Scholarship` | Award to a `Person`; optionally drawn from a `Grant`, syncs to event registration `Allocation` | +| `ProfessionalLicense` | A license a `Person` holds (`number`, `kind`, `issuing_state`, `expires_on`); a null `number` is a placeholder. `find_or_create_for` keeps one license per (person, number) | +| `ContinuingEducationRegistration` | A registrant's CE for one event against one `ProfessionalLicense`; billable `allocatable` (`Registerable`) with stored `hours` + `cost_cents` (default from the event). Payment is computed (no stored status); the certificate is delivered via `certificate_sent_at` and gated by its own `certificate_available?` | | `Report` | STI base class for MonthlyReport | | `WorkshopLog` | Standalone model for workshop log submissions (attendance, form fields) | @@ -133,6 +135,7 @@ This codebase (Rails 8.1) | `NameFilterable` | Name-based filtering | | `Publishable` | `published`, `publicly_visible` scopes | | `PunctuationStrippable` | Strips punctuation from strings | +| `Registerable` | Shared payment (`allocations_sum`/`paid?`/`remaining_cost`/…) + certificate (`certificate_sent?`, `mark_certificate_sent!`) interface for `EventRegistration` and `ContinuingEducationRegistration`; includers supply `cost_cents` + their own `certificate_available?` | | `RemoteSearchable` | AJAX remote search by column | | `RichTextSearchable` | Full-text search on ActionText rich_text fields | | `SectorsTaggable` | Enforces a single primary sector for sector-tagged owners | diff --git a/app/models/resource.rb b/app/models/resource.rb index 751e83897e..a3d4bd134e 100644 --- a/app/models/resource.rb +++ b/app/models/resource.rb @@ -12,11 +12,6 @@ def self.mentionable_rich_text_fields PUBLISHED_KINDS = [ "Handout", "Template", "Toolkit", "Form" ] KINDS = PUBLISHED_KINDS + [ "Resource", "Story", "LeaderSpotlight", "SectorImpact", "Theme", "Scholarship" ] - # Titles whose downloadable PDF is a single page. Every other resource PDF is - # multi-page, so its first-page preview needs a "download for all pages" note. - # Hardcoded for now — replace with real PDF introspection later. - SINGLE_PAGE_PDF_TITLES = [ "Letter to Supervisors", "W-9" ].freeze - has_rich_text :rhino_body belongs_to :created_by, class_name: "User" @@ -124,12 +119,6 @@ def story? [ "Story", "LeaderSpotlight" ].include? self.kind end - # A multi-page PDF only previews its first page, so the viewer needs a prompt - # to download for the rest. See SINGLE_PAGE_PDF_TITLES. - def single_page_pdf? - SINGLE_PAGE_PDF_TITLES.include?(title) - end - def custom_label_list "#{self.title} (#{self.kind.upcase})" unless self.kind.nil? end diff --git a/app/views/assets/_resource_display.html.erb b/app/views/assets/_resource_display.html.erb new file mode 100644 index 0000000000..a3930a740d --- /dev/null +++ b/app/views/assets/_resource_display.html.erb @@ -0,0 +1,17 @@ +<%# Renders a resource's main display. A PDF opens in the browser's built-in + inline viewer (scrollable, all pages) — every major browser ships one — with + the first-page/image preview as the fallback child for the rare client that + can't. Anything else (images, etc.) renders through the shared asset + pipeline. `resource` is a decorated Resource. %> +<% display = resource.display_image %> +<% if display.respond_to?(:attached?) && display.attached? && display.content_type == "application/pdf" %> + +<% else %> + <%= render "assets/display_assets", + resource: resource, file: display, variant: :hero, link: true %> +<% end %> diff --git a/app/views/events/callouts/_resource_body.html.erb b/app/views/events/callouts/_resource_body.html.erb index 4b22d0e80e..5ad87a359d 100644 --- a/app/views/events/callouts/_resource_body.html.erb +++ b/app/views/events/callouts/_resource_body.html.erb @@ -1,13 +1,11 @@ <%# Renders a resource inside a callout page: a top-right download button (when a - downloadable file is attached) plus the resource display (PDF first-page preview - etc., via the same pipeline as resources/show). `resource` is a decorated - Resource. Shared by the registrant resource viewer and admin callouts that link - a resource. %> + downloadable file is attached) plus the resource display. PDFs show in the + browser's inline viewer; everything else renders via the shared asset + pipeline (see assets/resource_display). `resource` is a decorated Resource. + Shared by the registrant resource viewer and admin callouts that link a + resource. %> <% if resource.downloadable_asset&.file&.attached? %>
The preview below may take a moment to load.
-<%= render "assets/display_assets", - resource: resource, file: resource.display_image, - variant: :hero, link: true %> +<%= render "assets/resource_display", resource: resource %> diff --git a/app/views/resources/show.html.erb b/app/views/resources/show.html.erb index a0f45a6d2c..5d6077bb14 100644 --- a/app/views/resources/show.html.erb +++ b/app/views/resources/show.html.erb @@ -47,7 +47,7 @@