diff --git a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.sass b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.sass index 635af4bfd82a..76511b9c5b3e 100644 --- a/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.sass +++ b/app/components/settings/project_custom_fields/project_custom_field_mapping/new_project_mapping_component.sass @@ -6,8 +6,3 @@ &:before @include icon-font-common margin-right: 10px - -.FormControl-horizontalGroup - display: flex - align-items: center - justify-content: space-between diff --git a/docs/user-guide/work-packages/exporting/README.md b/docs/user-guide/work-packages/exporting/README.md index 7f665037c763..f98188319c95 100644 --- a/docs/user-guide/work-packages/exporting/README.md +++ b/docs/user-guide/work-packages/exporting/README.md @@ -48,9 +48,16 @@ PDF Table exports the work package table displaying work packages as single rows ### PDF Report -With PDF Reports you can export detailed up to date work plans for your project in a clean and practical format. It includes a title page, a table of contents (listing all of the work packages), followed by the description of single work packages in a block form. Table of contents is clickable and is linked to the respective pages within the report, making navigation much easier. For each work package a table of attributes is included (attributes correspond to the columns in the work package table). Work package ID attribute is clickable and linked directly to the respective work package in OpenProject. +With PDF Reports you can export detailed up to date work plans for your project in a clean and practical format. It includes a title page, a table of contents (listing all of the work packages), followed by the description of single work packages in a block form. Table of contents is clickable and is linked to the respective pages within the report, making navigation much easier. + +For each work package a table of attributes is included, where attributes correspond to the columns in the work package table. For a single work package export, attributes are displayed according to the work package form configuration. + +Table of attributes is followed by the work package description and if necessary custom long text fields, which support [embedded work package and project attributes](../../wysiwyg/#attributes). + +> **Note**: Embedding of rich text, e.g. descriptions of other work package, is currently not supported. ![OpenProject_pdf_report_export](openproject-pdf-export-work-plans.png) + > **Note**: If ["display sums" is activated](../work-package-table-configuration/) in the work package table, then the sum table is included between table of contents and work packages description in an Overview section. ![OpenProject_work_package_table_sum](openproject_wp_table_total_sum.png) diff --git a/lookbook/docs/patterns/10-page-headers.md.erb b/lookbook/docs/patterns/10-page-header.md.erb similarity index 74% rename from lookbook/docs/patterns/10-page-headers.md.erb rename to lookbook/docs/patterns/10-page-header.md.erb index 99eb7105ac6f..6b1db317b495 100644 --- a/lookbook/docs/patterns/10-page-headers.md.erb +++ b/lookbook/docs/patterns/10-page-header.md.erb @@ -1,5 +1,9 @@ This component is an adaptation for OpenProject requirements of the React component `PageHeader` of Primer. This document will only state the points that differ from what **[Primer specifies](https://primer.style/components/page-header)** about this component in their documentation. +## Overview + +<%= embed OpenProject::Common::PageHeaderPreview, :default %> + ## Anatomy There are minor adjustments on how the composition of this component is defined in Primer for OpenProject: @@ -10,39 +14,47 @@ There are minor adjustments on how the composition of this component is defined - **Tablet:** The content of the context bar will be a [breadcrumb](https://primer.style/components/breadcrumbs). - **Mobile:** - The content of the breadcrumb will collapse to a single element using the parent link style. - - All the page header actions will merge into an [ActionMenu](https://primer.style/components/action-menu) triggered by a single [Icon button](https://primer.style/components/icon-button) in the context bar. + - All the PageHeader actions will merge into an [ActionMenu](https://primer.style/components/action-menu) triggered by a single [Icon button](https://primer.style/components/icon-button) in the context bar. **[Title bar](https://primer.style/components/page-header#title-bar):** The default (medium) size will be always used keeping the capability as optionals of adding leading and trailing visuals and actions. **Actions:** If there are more than 5 actions, the last one will be an [Icon button](https://primer.style/components/icon-button) with a more (⋯) icon, which will display all the remaining actions in a dropdown. All actions require their own icon. -**Divider**: The divider bellow the Page Header will be always present with the exception of displaying a [Tav nav](https://primer.style/components/tab-nav) as navigation element bellow. +**Divider**: The divider bellow the PageHeader will be always present with the exception of displaying a [Tav nav](https://primer.style/components/tab-nav) as navigation element bellow. ## **Exceptional behaviours** -- A special behaviour occurs when the page can be saved (or saved as) as one of the Page Header actions will be used to display an informational text and a link to perform the action. +- A special behaviour occurs when the page can be saved (or saved as) as one of the PageHeader actions will be used to display an informational text and a link to perform the action. - Work packages details are the only exceptional case, where the breadcrumb will be used to display the parent work package instead of the navigational hierarchy. ## Best practices **Do** -- Limit the actions of the Page Header to the global actions of the page (e. for a work package list: favourite, share, full-screen, …). *Note: this can not be 100% fulfilled until the Primer page sub-headers are implemented.* -- Use the H1 tag always for the Page Header. +- Limit the actions of the PageHeader to the global actions of the page (e. for a work package list: favourite, share, full-screen, …). +- Use the H1 tag always for the PageHeader. - All actions require their own icon. - Use Icon buttons instead of buttons for actions only when the icon is clear enough to describe the action. **Don't** -- Don’t use the trailing action in the page header as navigation element “back”, the breadcrumb and the browser back are covering this case. -- Use Page Headers as section sub-header inside of the content of the page. +- Don’t use the trailing action in the PageHeader as navigation element “back”, the breadcrumb and the browser back are covering this case. +- Use PageHeaders as section sub-header inside of the content of the page. ## Used in -The Page Header is a navigational mandatory component in all pages that will always use as title the name of the page where is contained. +The PageHeader is a navigational mandatory component in all pages that will always use as title the name of the page where is contained. ## Examples +For detailed examples have a look at the other [preview examples](../../inspect/primer/open_project/page_header/playground) of the component. + +This is an exemplary playground of the `Primer::OpenProject::PageHeader`. + +<%= embed OpenProject::Common::PageHeaderPreview, :playground, panels: %i[params source] %> + +## Technical notes + The PageHeader actions offer a set of predefined slots, to use specific components inside the the PageHeader actions, such as: * **Primer::Alpha::Dialog** ([`with_action_dialog`](../../inspect/primer/open_project/page_header/dialog_actions)) @@ -59,9 +71,3 @@ The PageHeader actions offer a set of predefined slots, to use specific componen * The button will collapse on mobile into the mobile action menu. Therefore, an additional `mobile_label`, as well as a `mobile_label` have to passed. * **Primer::Beta::Text** ([`with_action_text`](../../inspect/primer/open_project/page_header/actions)): * The text will be hidden on mobile. - -For detailed examples have a look at the other [preview examples](../../inspect/primer/open_project/page_header/playground) of the component. - -This is an exemplary call of the `Primer::OpenProject::PageHeader`. - -<%= embed OpenProject::Common::PageHeaderPreview, :default, panels: %i[source] %> diff --git a/lookbook/docs/patterns/11-sub-header.md.erb b/lookbook/docs/patterns/11-sub-header.md.erb new file mode 100644 index 000000000000..9d688a4b2972 --- /dev/null +++ b/lookbook/docs/patterns/11-sub-header.md.erb @@ -0,0 +1,50 @@ +This component is an own implementation for OpenProject requirements of contextual elements that affect the content of the page below. Such a component does not exist in the Primer Design System. + +## Overview + +<%= embed OpenProject::Common::SubHeaderPreview, :default %> + +## Anatomy + +**Filter input:** (Optional) It will change depending on the viewport: + +- **Desktop:** A basic [text input](https://primer.style/components/text-input) with a [search icon](https://primer.style/components/text-input#with-leading-and-trailing-visuals) which is mostly used on index pages to filter the elements below. +- **Mobile:** + - There will be an IconButton shown instead of the input + - Clicking that, will show the input again and hide all other elements of the SubHeader + - An additional cancel button is shown to return to the previous state + +**Filter button:** (Optional)A button which is shown next to the filter input (or on the very left, if there is no filter input) + +**Text:** (Optional) A bold text shown in the middle of the SubHeader + +**Action buttons**: (Optional) A set of buttons that are shown on the right side + + +## Best practices + +**Do** + +- Restrict SubHeader actions to the page's content-specific actions (e.g. filtering or creating a new object). +- Use IconButtons instead of Buttons for actions only when the icon is clear enough to describe the action. + +**Don't** + +- Use the SubHeader to perform generic view actions (should be part of the PageHeader) + +## Used in + +* Project list +* Members +* Meetings +* Storages +* ... + +## Examples + + +For detailed examples have a look at the other [preview examples](../../inspect/primer/open_project/sub_header/playground) of the component. + +This is an exemplary playground of the `Primer::OpenProject::SubHeader`. + +<%= embed OpenProject::Common::SubHeaderPreview, :playground, panels: %i[params source] %> diff --git a/lookbook/previews/open_project/common/page_header_preview.rb b/lookbook/previews/open_project/common/page_header_preview.rb index 84b32f7a9194..23c4df508b69 100644 --- a/lookbook/previews/open_project/common/page_header_preview.rb +++ b/lookbook/previews/open_project/common/page_header_preview.rb @@ -5,7 +5,9 @@ class PageHeaderPreview < Lookbook::Preview def default render(Primer::OpenProject::PageHeader.new) do |header| header.with_title { "Some important page" } - header.with_description { "Some optional description" } + header.with_description do + "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore." + end header.with_breadcrumbs([{ href: "/foo", text: "Project A" }, { href: "/bar", text: "Module B" }, "Some important page"]) @@ -28,6 +30,59 @@ def default end end end + + # @label Playground + # @param variant [Symbol] select [medium, large] + # @param title [String] text + # @param description [String] text + # @param with_leading_action [Symbol] octicon + # @param with_actions [Boolean] + # @param with_tab_nav [Boolean] + # rubocop:disable Metrics/AbcSize + def playground( + variant: :medium, + title: "Hello", + description: "Last updated 5 minutes ago by XYZ.", + with_leading_action: :none, + with_actions: true, + with_tab_nav: false + ) + + breadcrumb_items = [{ href: "/foo", text: "Project A" }, + { href: "/bar", text: "Module B" }, + "Some important page"] + + render Primer::OpenProject::PageHeader.new do |header| + header.with_title(variant:) { title } + header.with_description { description } + if with_leading_action && with_leading_action != :none + header.with_leading_action(icon: with_leading_action, href: "#", + "aria-label": "A leading action") + end + header.with_breadcrumbs(breadcrumb_items) + if with_actions + header.with_action_icon_button(icon: "pencil", mobile_icon: "pencil", label: "Edit") + header.with_action_menu(menu_arguments: { anchor_align: :end }, + button_arguments: { icon: "op-kebab-vertical", + "aria-label": "Menu" }) do |menu, _button| + menu.with_item(label: "Subitem 1") do |item| + item.with_leading_visual_icon(icon: :unlock) + end + menu.with_item(label: "Subitem 2", scheme: :danger) do |item| + item.with_leading_visual_icon(icon: :trash) + end + end + end + if with_tab_nav + header.with_tab_nav(label: "label") do |nav| + nav.with_tab(selected: true, href: "#") { "Tab 1" } + nav.with_tab(href: "#") { "Tab 2" } + nav.with_tab(href: "#") { "Tab 3" } + end + end + end + end + # rubocop:enable Metrics/AbcSize end end end diff --git a/lookbook/previews/open_project/common/sub_header_preview.rb b/lookbook/previews/open_project/common/sub_header_preview.rb new file mode 100644 index 000000000000..129679bdb91f --- /dev/null +++ b/lookbook/previews/open_project/common/sub_header_preview.rb @@ -0,0 +1,46 @@ +module OpenProject + module Common + # @hidden + class SubHeaderPreview < Lookbook::Preview + def default + render(Primer::OpenProject::SubHeader.new) do |component| + component.with_filter_input(name: "filter", label: "Filter") + component.with_filter_button do |button| + button.with_trailing_visual_counter(count: "15") + "Filter" + end + component.with_action_button(scheme: :primary) do |button| + button.with_leading_visual_icon(icon: :plus) + "Create" + end + end + end + + # @label Playground + # @param show_filter_input toggle + # @param show_filter_button toggle + # @param show_action_button toggle + # @param text text + def playground(show_filter_input: true, show_filter_button: true, show_action_button: true, text: "Monday, 12th") + render(Primer::OpenProject::SubHeader.new) do |component| + component.with_filter_input(name: "filter", label: "Filter") if show_filter_input + if show_filter_button + component.with_filter_button do |button| + button.with_trailing_visual_counter(count: "15") + "Filter" + end + end + + component.with_text { text } unless text.nil? + + if show_action_button + component.with_action_button(scheme: :primary) do |button| + button.with_leading_visual_icon(icon: :plus) + "Create" + end + end + end + end + end + end +end