Workflows index
This commit is contained in:
@@ -82,3 +82,34 @@ table {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
a[target=_blank]::after {
|
||||
content: url("mingcute/external_link_line.svg");
|
||||
display: inline-block;
|
||||
scale: 0.7;
|
||||
transform-origin: 0 50%;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: baseline;
|
||||
gap: 1em;
|
||||
|
||||
> * {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
> .right {
|
||||
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%;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
.tabs {
|
||||
padding-inline: 0;
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: flex-start;
|
||||
gap: 0.25em;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
padding: 0.25em 0.5em;
|
||||
border: 1px solid gray;
|
||||
border-radius: 0.5em;
|
||||
|
||||
transition: background-color 0.2s, color 0.2s;
|
||||
|
||||
&.active, &:hover, &:focus {
|
||||
background-color: var(--pico-primary);
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,25 @@
|
||||
.workflow {
|
||||
--bg-color: #D1D5DB; /* Pico zinc 150 */
|
||||
--text-color: oklch(from var(--bg-color) calc(0.55 * l) calc(0.55 * c) h);
|
||||
--color: #424751; /* Pico zinc 700 */
|
||||
|
||||
border-radius: 1em;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
outline: 2px solid var(--color);
|
||||
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
display: inline-flex;
|
||||
gap: 0.25em;
|
||||
min-width: 2em;
|
||||
padding: 0.1em 0.5em;
|
||||
gap: 0.5em;
|
||||
text-align: center;
|
||||
|
||||
> .mask-icon {
|
||||
--icon-color: var(--color);
|
||||
}
|
||||
|
||||
> img {
|
||||
max-width: unset;
|
||||
width: 1lh;
|
||||
opacity: 0.6;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
&.red {
|
||||
--bg-color: #F06048; /* Pico red 400 */
|
||||
--color: #BD3C13; /* Pico orange 550 */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module ProjectAdmin
|
||||
class ApplicationController < ::ApplicationController
|
||||
before_action :fetch_project
|
||||
|
||||
private
|
||||
|
||||
def fetch_project
|
||||
@project = Project.find_by!(code: params[:project_id])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module ProjectAdmin
|
||||
class WorkflowsController < ApplicationController
|
||||
def index
|
||||
@workflows = @project.workflows
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -6,4 +6,14 @@ module ApplicationHelper
|
||||
|
||||
url_for(controller: controller_name, action: :index, project:)
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
module ProjectAdmin::WorkflowsHelper
|
||||
end
|
||||
@@ -0,0 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module ProjectAdminHelper
|
||||
def project_admin_frame(project, &)
|
||||
tabs_id = 'project_admin_tabs'
|
||||
tabs = ProjectAdmin::TabsViewModel.new(project, frame: :project_admin, id: tabs_id)
|
||||
content = capture(&) if block_given?
|
||||
|
||||
render partial: 'project_admin/frame', locals: { id: :project_admin, tabs:, tabs_id:, content: }
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module ProjectAdmin
|
||||
class TabsViewModel
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
def initialize(project, id:, frame:)
|
||||
@project = project
|
||||
@id = id
|
||||
@frame = frame
|
||||
end
|
||||
|
||||
def render_in(view_context)
|
||||
view_context.render(
|
||||
partial: 'project_admin/tabs',
|
||||
locals: { project: @project, links:, id: @id, frame: @frame }
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def links
|
||||
{
|
||||
'Data' => edit_project_path(@project),
|
||||
'Workflows' => project_workflows_path(@project)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,11 @@
|
||||
h1
|
||||
span> Project
|
||||
span= @project.name
|
||||
|
||||
= link_to '← Back', project_path(@project)
|
||||
|
||||
= render tabs
|
||||
|
||||
= turbo_frame_tag(id) do
|
||||
= content
|
||||
= turbo_stream.replace(tabs_id, tabs)
|
||||
@@ -0,0 +1,3 @@
|
||||
nav.tabs id=id
|
||||
- links.each do |text, path|
|
||||
li= link_to text, path, class: {'active': request.path == path}, data: {'turbo-frame': frame, 'turbo-action': 'advance'}
|
||||
@@ -0,0 +1,9 @@
|
||||
= project_admin_frame(@project) do
|
||||
h2
|
||||
span Workflows
|
||||
|
||||
- @workflows.each do |workflow|
|
||||
article.row
|
||||
= workflow_display(workflow, full: true)
|
||||
ul.links.right
|
||||
li= link_to 'Edit', edit_project_workflow_path(@project, workflow), target: '_blank'
|
||||
@@ -1,5 +1,5 @@
|
||||
h1
|
||||
span Editing project
|
||||
span= @project.name
|
||||
= project_admin_frame(@project) do
|
||||
h2
|
||||
span Editing project
|
||||
|
||||
= render 'form'
|
||||
= render 'form'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
div.workflow class=color title=name
|
||||
= image_tag(icon)
|
||||
= mask_icon(icon)
|
||||
- if full
|
||||
span= name
|
||||
span<= name
|
||||
|
||||
Reference in New Issue
Block a user