diff --git a/app/assets/stylesheets/application.bootstrap.scss b/app/assets/stylesheets/application.bootstrap.scss index 65faf19..976c954 100644 --- a/app/assets/stylesheets/application.bootstrap.scss +++ b/app/assets/stylesheets/application.bootstrap.scss @@ -162,4 +162,5 @@ trix-toolbar .trix-dialog--link { overflow-y: auto; } */ -@import "./layout"; \ No newline at end of file +@import "./layout"; +@import "./dropdown"; diff --git a/app/assets/stylesheets/dropdown.scss b/app/assets/stylesheets/dropdown.scss new file mode 100644 index 0000000..f751bfc --- /dev/null +++ b/app/assets/stylesheets/dropdown.scss @@ -0,0 +1,67 @@ +.details-dropdown { + display: inline-block; + position: relative; +} + +/* Hide The disclosure widget: */ +.details-dropdown summary { + list-style: none; + cursor: pointer; +} +.details-dropdown[open] summary { + list-style: none; + cursor: pointer; + i { + + color: var(--bs-body-color) + } + /* border-left: solid 1px $secondary; */ + /* border-top: solid 1px $secondary; */ + /* border-right: solid 1px $secondary; */ +} +.details-dropdown[open] { + background-color: $secondary; +} + +/* Detache details content */ +.details-dropdown .details-dropdown-content { + border: solid 1px $secondary; + position: absolute; + min-inline-size: max-content; + z-index: 2000; + + /* In case the details-dropdown should open to the left: */ + right: 0; +} + +/* Closing the details-dropdown on clicking anywhere else */ +.details-dropdown[open] summary::before { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + content: ""; + cursor: default; +} + +/* Visual styles for your details-dropdown: */ +.details-dropdown .details-dropdown-trigger { + /* your look and feel here */ +} + +.details-dropdown .details-dropdown-content { + /* your look and feel here */ +} + +form.no-padding { + button { + padding: 0; + } +} + +li.list-group-item-danger:hover { + button { + color: var(--bs-body-color) ; + } +} diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 8700b9d..87fc2c1 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -91,7 +91,9 @@ $tertiary-dark-active-open: $gray-600; .page_nav nav ul { padding-left: 0; list-style-type: none; - line-height: 2rem; + li { + margin-bottom: 0.5rem; + } a { color: var(--bs-text); @@ -223,7 +225,14 @@ details.tree[open]>summary::before { padding-bottom: 0; } +details.success_criterion:last-child { + border-bottom: solid 1px $tertiary; +} + details.success_criterion { + border: solid 1px $tertiary; + border-bottom: solid 0px $tertiary; + summary:hover { background-color: $tertiary-hover; @@ -255,24 +264,31 @@ details.success_criterion { details.success_criterion[open] { border: solid 1px $tertiary; - summary { + >summary { background-color: $tertiary; } - summary:hover { + >summary:hover { background-color: $tertiary-active-hover; } } @include color-mode(dark) { + details.success_criterion { + border: solid 1px $tertiary-dark; + border-bottom: solid 0px $tertiary-dark; + } + details.success_criterion:last-child { + border-bottom: solid 1px $tertiary-dark; + } details.success_criterion[open] { border: solid 1px $tertiary-dark; - summary { + >summary { background-color: $tertiary-dark; } - summary:hover { + >summary:hover { background-color: $tertiary-dark-active-open; } } @@ -326,4 +342,4 @@ details[open] { .sortable-ghost { border: solid 3px $primary !important; -} \ No newline at end of file +} diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index c17a465..69e0cd5 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -32,4 +32,35 @@ module ApplicationHelper def turbo_stream_toast(content, alert) turbo_stream.append("toasts", partial: "layouts/toast", locals: { content:, alert: }) end + + + def dropdown_menu(items, klass: "") + tag.details(class: "details-dropdown #{klass}") do + tag.summary do + tag.div(class: "details-dropdown-trigger") do + tag.div(tag.i(class: "bi bi-three-dots-vertical"), class: "btn btn-outline-secondary") + end + end + + tag.div(class: "details-dropdown-content bg-secondary") do + tag.ul(class: "list-group") do + safe_join(items.map do |item| + tag.li(class: "list-group-item list-group-item-action#{ item[:color] ? " list-group-item-#{item[:color]}" : ""}") do + text = item[:icon] ? tag.i(class: "bi bi-#{item[:icon]} me-2") + " #{item[:text]}".html_safe : item[:text] + case item[:method] + when nil, :get + link_to(text, item[:href], class: "text-decoration-none text-body") + else + button_to(text, + item[:href], + method: item[:method], + form_class: "no-padding", + class: "btn btn-link text-decoration-none text-#{item[:color] ? "#{item[:color]}-emphasis" : "body"}", + data: { turbo_confirm: item[:confirm] }) + end + end + end) + end + end + end + end end diff --git a/app/helpers/success_criteria_helper.rb b/app/helpers/success_criteria_helper.rb index f15ebcc..5ecc7d0 100644 --- a/app/helpers/success_criteria_helper.rb +++ b/app/helpers/success_criteria_helper.rb @@ -25,8 +25,22 @@ module SuccessCriteriaHelper end end + def success_criterion_menu(success_criterion, show_mode = true) + dropdown_menu([ + { text: show_mode ? "Bearbeiten" : "Bearbeiten abbrechen", + icon: "pencil", + href: show_mode ? edit_success_criterion_path(success_criterion) : success_criterion_path(success_criterion)}, + { text: "Löschen", + icon: "trash", + href: success_criterion_path(success_criterion), + color: :danger, + method: :delete, + confirm: "Bist du sicher?"}], + klass: "mt-3 ms-auto") + end - def success_criterion_edit_button(success_criterion, edit_mode) + + def success_criterion_edit_button(success_criterion, edit_mode) path = if success_criterion.persisted? if edit_mode success_criterion @@ -37,9 +51,9 @@ module SuccessCriteriaHelper else success_criterion.element end - link_to tag.i(class: "bi bi-pencil"), + link_to tag.i(class: "bi bi-pencil") + " Bearbeiten".html_safe, path, - class: "btn btn-#{edit_mode ? 'link text-warning' : 'link text-body'}" + class: "text-decoration-none xbtn xbtn-#{edit_mode ? 'link text-warning' : 'link text-body'}" end def success_criterion_badge(content, extra_classes: "") diff --git a/app/views/exports/show.html.slim b/app/views/exports/show.html.slim index 269a527..b72b856 100644 --- a/app/views/exports/show.html.slim +++ b/app/views/exports/show.html.slim @@ -37,19 +37,26 @@ p Woher kommt dieser Text? h2 2 Protokoll - current_page_pos = 0 +- current_abs_element_pos = 0 - @report.pages.select { |p| p.elements.any? { |e| e.success_criteria.any? { _1.failed? } } }.each do |page| - current_page_pos += 1 - current_element_pos = 0 - h3 = "2.#{current_page_pos} #{page.path}" + - current_abs_element_pos = 0 + /h3 = "2.#{current_page_pos} #{page.path}" - page.elements { |e| e.success_criteria.any? { _1.failed? } }.each do |element| - current_element_pos += 1 + - current_abs_element_pos += 1 - current_sc_pos = 0 - h4 = "2.#{current_page_pos}.#{current_element_pos} #{element.title}" + /h4 = "2.#{current_page_pos}.#{current_element_pos} #{element.title}" + h3 = "2.#{current_abs_element_pos} #{element.title}" + p + strong Pfad: + span =< page.path = safe_display(element.screenshot) { image_tag(_1.representation(resize_to_fit: [250, 250]))} = element.description - element.success_criteria.select{ _1.failed? }.each do |sc| - current_sc_pos += 1 - h5 = "2.#{current_page_pos}.#{current_element_pos}.#{current_sc_pos} #{sc.title}" + h4 = "2.#{current_abs_element_pos}.#{current_sc_pos} #{sc.title}" - if sc.test_comment? p = sc.test_comment - safe_display(sc.quick_criterion) do diff --git a/app/views/success_criteria/_body.html.slim b/app/views/success_criteria/_body.html.slim index 59bf000..45a40d3 100644 --- a/app/views/success_criteria/_body.html.slim +++ b/app/views/success_criteria/_body.html.slim @@ -1,19 +1,18 @@ .content id="#{dom_id(success_criterion, :body)}" = turbo_frame_tag(dom_id(success_criterion, :frame)) do - .row - .col - .my-3.btn-group[role="group" aria-label="Resultat"] - = bootstrap_form_with(model: success_criterion, data: { controller: "autosubmit" }) do |form| - = form.radio_button_without_bootstrap :result, :passed, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_passed) - label.btn.btn-outline-success for=dom_id(success_criterion, :result_passed) Bestanden - = form.radio_button_without_bootstrap :result, :failed, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_failed) - label.btn.btn-outline-danger for=dom_id(success_criterion, :result_failed) Durchgefallen - = form.radio_button_without_bootstrap :result, :not_applicable, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_not_applicable) - label.btn.btn-outline-secondary for=dom_id(success_criterion, :result_not_applicable) Nicht anwendbar - /= form.radio_button_without_bootstrap :result, nil, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_not_applicable) - /label.btn.btn-outline-secondary for=dom_id(success_criterion, :nil) Reset - = button_to(tag.i(class: "bi bi-trash"), success_criterion, method: :delete, class: "btn btn-link text-danger", data: { turbo_confirm: "Bist du sicher?"}) - = success_criterion_edit_button(success_criterion, false) + .d-flex + .my-3.btn-group[role="group" aria-label="Resultat"] + = bootstrap_form_with(model: success_criterion, data: { controller: "autosubmit" }) do |form| + = form.radio_button_without_bootstrap :result, :passed, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_passed) + label.btn.btn-outline-success for=dom_id(success_criterion, :result_passed) Bestanden + = form.radio_button_without_bootstrap :result, :failed, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_failed) + label.btn.btn-outline-danger for=dom_id(success_criterion, :result_failed) Durchgefallen + = form.radio_button_without_bootstrap :result, :not_applicable, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_not_applicable) + label.btn.btn-outline-secondary for=dom_id(success_criterion, :result_not_applicable) Nicht anwendbar + /= form.radio_button_without_bootstrap :result, nil, class: "btn-check", autocomplete: "off", id: dom_id(success_criterion, :result_not_applicable) + /label.btn.btn-outline-secondary for=dom_id(success_criterion, :nil) Reset + / = dropdown_menu([{ text: "Bearbeiten", icon: "pencil", href: edit_success_criterion_path(success_criterion) }, { text: "Löschen", icon: "trash", href: success_criterion, color: :danger, method: :delete, confirm: "Bist du sicher?"}], klass: "mt-3 ms-auto") + = success_criterion_menu(success_criterion) .row .col - if success_criterion.test_comment? diff --git a/app/views/success_criteria/_form.html.erb b/app/views/success_criteria/_form.html.erb deleted file mode 100644 index 8f351a1..0000000 --- a/app/views/success_criteria/_form.html.erb +++ /dev/null @@ -1,11 +0,0 @@ - - <%= bootstrap_form_with(model: success_criterion.persisted? ? success_criterion : [:element, success_criterion], data: { controller: "unsaved-changes" }) do |form| %> - <%= form.text_field :title %> - <%= form.collection_select :result, SuccessCriterion.results.keys.map { [_1, t("activerecord.attributes.success_criterion.results/#{_1}")] }, :first, :second, include_blank: success_criterion.result ? "(Resultat zurücksetzen)" : "(unbeantwortet)" %> - <%= form.rich_text_area :quick_criterion %> - <%= form.rich_text_area :quick_fail %> - <%= form.rich_text_area :quick_fix %> - <%= form.rich_text_area :test_comment %> - <%= form.submit class: "btn btn-primary" %> - <%= link_to "Abbrechen", success_criterion.persisted? ? success_criterion : success_criterion.element, class: "btn btn-outline-secondary" %> - <% end %> diff --git a/app/views/success_criteria/_form.html.slim b/app/views/success_criteria/_form.html.slim new file mode 100644 index 0000000..fe12bf5 --- /dev/null +++ b/app/views/success_criteria/_form.html.slim @@ -0,0 +1,9 @@ += bootstrap_form_with(model: success_criterion.persisted? ? success_criterion : [:element, success_criterion], data: { controller: "unsaved-changes" }) do |form| + = form.text_field :title + = form.collection_select :result, SuccessCriterion.results.keys.map { [_1, t("activerecord.attributes.success_criterion.results/#{_1}")] }, :first, :second, include_blank: success_criterion.result ? "(Resultat zurücksetzen)" : "(unbeantwortet)" + = form.rich_text_area :quick_criterion + = form.rich_text_area :quick_fail + = form.rich_text_area :quick_fix + = form.rich_text_area :test_comment + = form.submit class: "btn btn-primary" + = link_to "Abbrechen", success_criterion.persisted? ? success_criterion : success_criterion.element, class: "btn btn-outline-secondary" diff --git a/app/views/success_criteria/_header.html.slim b/app/views/success_criteria/_header.html.slim index a27c7be..db31ae4 100644 --- a/app/views/success_criteria/_header.html.slim +++ b/app/views/success_criteria/_header.html.slim @@ -3,7 +3,7 @@ summary.d-flex.align-items-start id=dom_id(success_criterion, :header) .content.d-flex.align-items-center.w-100 .result-icon.flex-shrink-0 class=[success_criterion_result_color_classes(success_criterion)] span.h1.bi class=[success_criterion_result_icon_classes(success_criterion)] - .flex-fill + .flex-fill.py-1 span id=dom_id(success_criterion, :position) = success_criterion.page.position | . @@ -19,4 +19,4 @@ summary.d-flex.align-items-start id=dom_id(success_criterion, :header) = success_criterion_badge(success_criterion.check.external_number, extra_classes: "text-bg-info me-1") = success_criterion_badge(success_criterion.level, extra_classes: "sc-level-#{success_criterion.level.to_s.downcase} me-1") - i.bi.bi-grip-vertical.handle \ No newline at end of file + i.bi.bi-grip-vertical.handle diff --git a/app/views/success_criteria/_record_menu.html.slim b/app/views/success_criteria/_record_menu.html.slim new file mode 100644 index 0000000..5524b70 --- /dev/null +++ b/app/views/success_criteria/_record_menu.html.slim @@ -0,0 +1,3 @@ + = dropdown_menu(klass: "mt-3 ms-auto b-0") do + = success_criterion_edit_button(@success_criterion, true) + = button_to(tag.i(class: "bi bi-trash") + " Löschen".html_safe, @success_criterion, method: :delete, class: "text-danger", data: { turbo_confirm: "Bist du sicher?"}) diff --git a/app/views/success_criteria/edit.html.erb b/app/views/success_criteria/edit.html.erb deleted file mode 100644 index f0093e8..0000000 --- a/app/views/success_criteria/edit.html.erb +++ /dev/null @@ -1,10 +0,0 @@ -