Skip to content

Commit

Permalink
[#49932] Convert file storages index page to primer design (#13660)
Browse files Browse the repository at this point in the history
https://community.openproject.org/projects/openproject/work_packages/49932

---------

Co-authored-by: Oliver Günther <[email protected]>
Co-authored-by: Henriette Darge <[email protected]>
  • Loading branch information
3 people authored Oct 4, 2023
1 parent a457dd2 commit 2f4eb08
Show file tree
Hide file tree
Showing 12 changed files with 293 additions and 30 deletions.
1 change: 1 addition & 0 deletions frontend/src/global_styles/openproject.sass
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@

// Module specific Styles
@import "../../../modules/meeting/app/components/_index.sass"
@import "../../../modules/storages/app/components/_index.sass"
1 change: 1 addition & 0 deletions modules/storages/app/components/_index.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "storages/admin/storage_list_component"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<%=
render(Primer::Beta::Button.new(**button_options)) do |button|
button.with_leading_visual_icon(icon: :plus)
label
end
%>
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2023 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
#
module Storages::Admin
class NewStorageButtonComponent < ApplicationComponent
options scheme: :primary,
size: :medium,
tag: :a

def button_options
{ scheme:,
size:,
tag:,
role: :button,
href: Rails.application.routes.url_helpers.new_admin_settings_storage_path,
aria: { label: I18n.t("storages.label_add_new_storage") } }
end

def label
I18n.t("storages.label_storage")
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<%=
if storages.present?
render(Primer::Beta::BorderBox.new) do |component|
component.with_header(color: :subtle) do
grid_layout('op-storage-list--header', tag: :div, align_items: :center) do |grid|
grid.with_area(:name, tag: :div) do
render(Primer::Beta::Text.new(font_weight: :semibold)) { I18n.t('storages.label_name') }
end

grid.with_area(:user, tag: :div, color: :subtle, mr: 3, hide: :sm) do
render(Primer::Beta::Text.new(font_weight: :semibold)) { I18n.t('storages.label_creator') }
end

grid.with_area(:provider, tag: :div, color: :subtle, mr: 3, hide: :sm) do
render(Primer::Beta::Text.new(font_weight: :semibold)) { I18n.t('storages.label_provider') }
end

grid.with_area(:time, tag: :div, color: :subtle, hide: :sm) do
render(Primer::Beta::Text.new(font_weight: :semibold)) { I18n.t('storages.label_creation_time') }
end
end
end

storages.map do |storage|
component.with_row(scheme: :default, id: storage_row_css_id(storage)) do
grid_layout('op-storage-list--row', tag: :div, align_items: :center) do |grid|
grid.with_area(:name, tag: :div, mr: 3) do
concat(render(Primer::Beta::Link.new(href: edit_admin_settings_storage_path(storage), scheme: :primary, mr: 1, data: { 'test-selector': 'storage-name' })) { storage.name })

unless storage.configured?
concat(render(Primer::Beta::Label.new(scheme: :attention, data: { 'test-selector': 'label-incomplete' })) { I18n.t('storages.label_incomplete') })
end
end

grid.with_area(:host, tag: :div, color: :subtle, data: { 'test-selector': 'storage-host' }) do
render(Primer::Beta::Truncate.new(font_weight: :light)) { storage.host }
end

grid.with_area(:user, tag: :div, color: :subtle, mr: 3, font_weight: :light, data: { 'test-selector': 'storage-creator' }) do
render(Users::AvatarComponent.new(user: storage.creator, size: :mini, link: false, show_name: true))
end

grid.with_area(:provider, tag: :div, color: :subtle, mr: 3, hide: :sm, data: { 'test-selector': 'storage-provider' }) do
render(Primer::Beta::Truncate.new(font_weight: :light)) { storage.short_provider_type.capitalize }
end

grid.with_area(:time, tag: :div, color: :subtle, mr: 3) do
render(Primer::Beta::Text.new(font_weight: :light)) { I18n.t('activity.item.created_on', datetime: helpers.format_time(storage.created_at)).capitalize }
end
end
end
end
end
else
render Primer::Beta::Blankslate.new(border: true) do |component|
component.with_visual_icon(icon: :cloud)
component.with_heading(tag: :h2).with_content(I18n.t('storages.storage_list_blank_slate.heading'))
component.with_description { I18n.t('storages.storage_list_blank_slate.description') }

component.with_primary_action(**Storages::Admin::NewStorageButtonComponent.new.button_options) do |button|
button.with_leading_visual_icon(icon: :plus)
I18n.t("storages.label_storage")
end
end
end
%>
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2023 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
#
module Storages::Admin
class StorageListComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
alias_method :storages, :model

private

def storage_row_css_id(storage)
helpers.dom_id storage
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.op-storage-list--header,
.op-storage-list--row
display: grid
grid-template-columns: 1fr 180px 100px 240px
grid-template-areas: "name user provider time" "host user provider time"

@media screen and (max-width: $breakpoint-md)
.op-storage-list--row
grid-template-columns: 1fr
grid-template-areas: "name" "host" "user" "time"
grid-row-gap: 5px

.op-storage-list--header
grid-template-columns: 1fr
grid-template-areas: "name"
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def default_breadcrumb
# See: default_breadcrum above
# Defines whether to show breadcrumbs on the page or not.
def show_local_breadcrumb
true
!OpenProject::FeatureDecisions.storage_primer_design_active?
end

private
Expand Down
67 changes: 43 additions & 24 deletions modules/storages/app/views/storages/admin/storages/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,31 +1,50 @@
<!-- Standard Ruby view, please see the controller for comments -->
<% html_title t(:label_administration), t("project_module_storages") %>

<%= toolbar title: t("project_module_storages") do %>
<li class="toolbar-item">
<%= link_to new_admin_settings_storage_path,
{ class: 'button -alt-highlight',
aria: { label: t('storages.label_new_storage') },
title: t('storages.label_new_storage') } do %>
<%= op_icon('button--icon icon-add') %>
<span class="button--text"><%= ::Storages::Storage.model_name.human %></span>
<% if OpenProject::FeatureDecisions.storage_primer_design_active? %>
<%= render(Primer::OpenProject::PageHeader.new) do |header| %>
<% header.with_title do %>
<%= t("project_module_storages") %>
<% end %>
</li>
<% end %>

<div class="op-toast -info -with-bottom-spacing">
<div class="op-toast--content">
<p>
<%= t('repositories.storage.setup_documentation_details') %>
<a
href="<%= ::OpenProject::Static::Links[:storage_docs][:setup][:href] %>"
target="_blank"
class="spot-link"
>
<%= t('repositories.storage.setup_documentation_details_link_text') %>
</a>
</p>
<% header.with_description do %>
<%= t("storages.page_titles.file_storages.subtitle") %>
<% end %>

<% header.with_actions do %>
<%= render(Storages::Admin::NewStorageButtonComponent.new) %>
<% end %>
<% end %>

<%= render(::Storages::Admin::StorageListComponent.new(@storages)) %>

<% else %>
<%= toolbar title: t("project_module_storages") do %>
<li class="toolbar-item">
<%= link_to new_admin_settings_storage_path,
{ class: 'button -alt-highlight',
aria: { label: t('storages.label_new_storage') },
title: t('storages.label_new_storage') } do %>
<%= op_icon('button--icon icon-add') %>
<span class="button--text"><%= ::Storages::Storage.model_name.human %></span>
<% end %>
</li>
<% end %>

<div class="op-toast -info -with-bottom-spacing">
<div class="op-toast--content">
<p>
<%= t('repositories.storage.setup_documentation_details') %>
<a
href="<%= ::OpenProject::Static::Links[:storage_docs][:setup][:href] %>"
target="_blank"
class="spot-link"
>
<%= t('repositories.storage.setup_documentation_details_link_text') %>
</a>
</p>
</div>
</div>
</div>

<%= render(::Storages::Admin::TableComponent.new(rows: @storages)) %>
<%= render(::Storages::Admin::TableComponent.new(rows: @storages)) %>
<% end %>
9 changes: 9 additions & 0 deletions modules/storages/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ en:
select_folder: "Select folder"
configure: "Configure"
page_titles:
file_storages:
subtitle: "Add an external file storage in order to upload, link and manage files in work packages."
managed_project_folders:
title: "Automatically managed project folders"
subtitle: >
Expand Down Expand Up @@ -137,11 +139,18 @@ en:
project_storage_delete_result_2: "In case this storage has an automatically managed project folder, this and its files will be deleted forever."
input_delete_confirmation: "Enter the file storage name %{file_storage} to confirm deletion."
irreversible_notice: "Deleting a file storage is an irreversible action."
storage_list_blank_slate:
heading: "You don't have any storages yet."
description: "Add a storage to see them here."
label_active: "Active"
label_add_new_storage: "Add new storage"
label_inactive: "Inactive"
label_creator: "Creator"
label_provider: "Provider"
label_file_link: "File link"
label_file_links: "File links"
label_creation_time: "Creation time"
label_incomplete: "Incomplete"
label_name: "Name"
label_host: "Host URL"
label_managed_project_folders:
Expand Down
1 change: 1 addition & 0 deletions modules/storages/lib/open_project/storages/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def self.permissions
initializer 'openproject_storages.feature_decisions' do
OpenProject::FeatureDecisions.add :storage_file_picking_select_all
OpenProject::FeatureDecisions.add :storage_one_drive_integration
OpenProject::FeatureDecisions.add :storage_primer_design
end

initializer 'openproject_storages.event_subscriptions' do
Expand Down
Loading

0 comments on commit 2f4eb08

Please sign in to comment.