diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 305c4b0..a4cbd89 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -65,17 +65,6 @@ form { } } -.badge { - font-size: 0.875em; - padding: 0.25em 0.5em; - border: 1px solid var(--border-color, currentColor); - color: var(--color, currentColor); - background-color: var(--background-color, transparent); - border-radius: 1em / 0.5em; - font-weight: 500; - text-transform: uppercase; -} - table { /* TODO: maybe extract into a separate file */ details.dropdown { @@ -104,12 +93,3 @@ a[target=_blank]::after { margin-left: auto; } } - -.mask-icon { - display: inline-block; - height: 1lh; - width: 1lh; - background-color: var(--icon-color, black); - mask-image: var(--icon, url("mingcute/task_line.svg")); - mask-size: 100%; -} diff --git a/app/assets/stylesheets/badge.css b/app/assets/stylesheets/badge.css new file mode 100644 index 0000000..75c80dd --- /dev/null +++ b/app/assets/stylesheets/badge.css @@ -0,0 +1,13 @@ +.badge { + font-size: 0.875em; + border-radius: 1em; + + display: inline-flex; + gap: 0.25em; + min-width: 2em; + padding: 0.1em 0.5em; + + font-weight: 500; + text-transform: uppercase; + +} diff --git a/app/assets/stylesheets/mask-icon.css b/app/assets/stylesheets/mask-icon.css new file mode 100644 index 0000000..f82b5b6 --- /dev/null +++ b/app/assets/stylesheets/mask-icon.css @@ -0,0 +1,13 @@ +.mask-icon { + display: inline-block; + background-color: var(--icon-color, currentColor); + mask-image: var(--icon); + mask-size: 100%; + + height: 1lh; + width: 1lh; + transform: translateY(0.3em); /* Looks better when inline */ + .badge & { + transform: unset; + } +} diff --git a/app/assets/stylesheets/tasks.css b/app/assets/stylesheets/tasks.css index 392529b..c754dff 100644 --- a/app/assets/stylesheets/tasks.css +++ b/app/assets/stylesheets/tasks.css @@ -9,6 +9,12 @@ --color: var(--backlog-color); --background-color: var(--backlog-bg); + &.badge { + border: 2px solid var(--border-color, currentColor); + color: var(--color, currentColor); + background-color: var(--background-color); + } + &.analysis { --color: var(--analysis-color); --background-color: var(--analysis-bg); diff --git a/app/assets/stylesheets/workflows.css b/app/assets/stylesheets/workflows.css index 7018909..d5c9f4d 100644 --- a/app/assets/stylesheets/workflows.css +++ b/app/assets/stylesheets/workflows.css @@ -1,25 +1,29 @@ .workflow { --color: #424751; /* Pico zinc 700 */ + --icon: url("mingcute/task_line.svg"); - border-radius: 1em; - outline: 2px solid var(--color); - - display: inline-flex; - gap: 0.25em; - min-width: 2em; - padding: 0.1em 0.5em; + &.badge { + outline: 2px solid var(--color); + color: var(--color); + } > .mask-icon { --icon-color: var(--color); } - > img { - max-width: unset; - width: 1lh; - opacity: 0.75; - } - &.red { --color: #BD3C13; /* Pico orange 550 */ } + + &.blue { + --color: #1D59D0; /* Pico blue 600 */ + } + + &.lime { + --color: #628100; /* Pico lime 500 */ + } + + &.teal { + --color: #047878; /* Pico cyan 550 */ + } } diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index eef67dc..29e28f5 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -8,12 +8,11 @@ module ApplicationHelper end def mask_icon(icon, **options) - # Renders a span as a masked icon - case options[:class] - when String then options[:class] += ' mask-icon' - when nil then options[:class] = 'mask-icon' - else options[:class] = Array(options[:class]) + ['mask-icon'] - end - content_tag(:span, '', style: "--icon: url(#{image_path(icon)})", **options) + klass = options.delete(:class) + klass = Array(klass) + klass << 'mask-icon' + + icon_path = image_path("mingcute/#{icon}.svg") + content_tag(:span, '', class: klass, style: "--icon: url(#{icon_path})", **options) end end diff --git a/app/models/task_status.rb b/app/models/task_status.rb index 6aeae6f..7bc4582 100644 --- a/app/models/task_status.rb +++ b/app/models/task_status.rb @@ -8,15 +8,6 @@ class TaskStatus < ApplicationRecord validates :name, presence: true, uniqueness: { scope: :workflow } validates :category, presence: true - validate :associations_should_have_same_project scope :default_order, -> { order(:category, :name) } - - private - - def associations_should_have_same_project - return if workflow.project == project - - errors.add(:workflow, "Doesn't belong in the same project") - end end diff --git a/app/models/workflow.rb b/app/models/workflow.rb index 102856d..ec930ef 100644 --- a/app/models/workflow.rb +++ b/app/models/workflow.rb @@ -7,5 +7,5 @@ class Workflow < ApplicationRecord has_many :task_statuses, dependent: :restrict_with_error enum :icon, { task: 'task', warning: 'warning' }, default: 'task', scopes: false - enum :color, { blue: 'blue', gray: 'gray', yellow: 'yellow', red: 'red' }, default: 'gray', scopes: false + enum :color, { blue: 'blue', gray: 'gray', lime: 'lime', red: 'red', teal: 'teal' }, default: 'gray', scopes: false end diff --git a/app/view_models/workflows/display_view_model.rb b/app/view_models/workflows/display_view_model.rb index 9501dcb..d5d709b 100644 --- a/app/view_models/workflows/display_view_model.rb +++ b/app/view_models/workflows/display_view_model.rb @@ -7,21 +7,22 @@ module Workflows warning: 'warning_line' }.freeze - def initialize(workflow, full: false) + def initialize(workflow, badge: false, full: false) @workflow = workflow + @badge = badge @full = full end - def icon - icon = ICONS.fetch(@workflow.icon.to_sym, DEFAULT_ICON) + attr_reader :full, :badge - "mingcute/#{icon}.svg" + def icon + ICONS.fetch(@workflow.icon.to_sym, DEFAULT_ICON) end def render_in(view_context) view_context.render( partial: 'workflows/display', - locals: @workflow.attributes.symbolize_keys.merge(icon:, full: @full) + locals: @workflow.attributes.symbolize_keys.merge(full:, badge:, icon:) ) end end diff --git a/app/views/project_admin/_frame.html.slim b/app/views/project_admin/_frame.html.slim index 1087df0..81337f8 100644 --- a/app/views/project_admin/_frame.html.slim +++ b/app/views/project_admin/_frame.html.slim @@ -8,4 +8,5 @@ h1 = turbo_frame_tag(id) do = content - = turbo_stream.replace(tabs_id, tabs) + - if turbo_frame_request? + = turbo_stream.replace(tabs_id, tabs) diff --git a/app/views/tasks/_table_row.html.slim b/app/views/tasks/_table_row.html.slim index 76cfae5..13c81c6 100644 --- a/app/views/tasks/_table_row.html.slim +++ b/app/views/tasks/_table_row.html.slim @@ -1,6 +1,6 @@ - cache task do tr id="task_#{task.id}" - td= workflow_display task.workflow + td= workflow_display task.workflow, badge: true td= link_to task.full_number, task_path(task) td = task_status_selector task, with_form: true diff --git a/app/views/tasks/show.html.slim b/app/views/tasks/show.html.slim index 07292a6..fac8421 100644 --- a/app/views/tasks/show.html.slim +++ b/app/views/tasks/show.html.slim @@ -3,7 +3,7 @@ div h1= @task.title section.task-show-info - = workflow_display @task.workflow, full: true + = workflow_display @task.workflow, full: true, badge: true = task_status_selector @task, with_form: true = turbo_stream_from @task, :status, :with_form diff --git a/app/views/workflows/_display.html.slim b/app/views/workflows/_display.html.slim index 6e72610..915df42 100644 --- a/app/views/workflows/_display.html.slim +++ b/app/views/workflows/_display.html.slim @@ -1,4 +1,4 @@ -div.workflow class=color title=name +div.workflow class=[color, ('badge' if badge)] title=name = mask_icon(icon) - if full span<= name