Skip to content
Snippets Groups Projects
Commit 21470fb9 authored by Sascha Eggenberger's avatar Sascha Eggenberger :speech_balloon:
Browse files

Merge branch 'project-overview-layout-reorganisation' into 'master'

Project overview page reoganisation: add sidebar

See merge request gitlab-org/gitlab!137025



Merged-by: default avatarSascha Eggenberger <seggenberger@gitlab.com>
Approved-by: default avatarJulia Miocene <jmiocene@gitlab.com>
Approved-by: default avatarElwyn Benson <ebenson@gitlab.com>
Reviewed-by: default avatarSascha Eggenberger <seggenberger@gitlab.com>
Reviewed-by: default avatarElwyn Benson <ebenson@gitlab.com>
Co-authored-by: default avatarAnnabel Dunstone Gray <annabel.dunstone@gmail.com>
parents adb8006d 14c76d7e
No related branches found
No related tags found
No related merge requests found
Showing
with 419 additions and 130 deletions
......@@ -36,7 +36,10 @@ export default {
<span>
<gl-button
v-gl-modal="$options.uploadBlobModalId"
variant="link"
icon="upload"
class="stat-link gl-px-0!"
button-text-classes="gl-ml-2"
data-testid="upload-file-button"
>{{ __('Upload File') }}</gl-button
>
......
......@@ -134,7 +134,7 @@
.stat-text,
.stat-link {
padding: $gl-btn-vert-padding 0;
padding: $gl-btn-vert-padding;
background-color: transparent;
font-size: $gl-font-size;
line-height: $gl-btn-line-height;
......@@ -149,7 +149,6 @@
&:hover,
&:focus {
text-decoration: underline;
border-bottom: 0;
}
.project-stat-value {
......@@ -159,13 +158,6 @@
.icon {
color: var(--gray-500, $gl-text-color-secondary);
}
.add-license-link {
&,
.icon {
color: var(--blue-600, $blue-600);
}
}
}
.btn {
......@@ -186,3 +178,60 @@
color: var(--gl-text-color, $gl-text-color);
}
}
// FF :project_overview_reorg enabled
.project-page-indicator:not(.hidden) + .project-page-layout {
--project-overview-sidebar-width: 290px;
@include media-breakpoint-up(lg) {
display: grid;
grid-template-columns: auto var(--project-overview-sidebar-width);
gap: 2rem;
.project-page-layout-content,
.project-page-layout-sidebar {
min-width: 1px;
}
.project-page-layout-sidebar {
order: 2;
overflow-x: clip;
margin-right: -$gl-padding-8;
}
.project-page-sidebar {
position: sticky;
top: calc(#{$calc-application-header-height} + #{$gl-spacing-scale-4});
width: calc(100% + 100px);
height: calc(
#{$calc-application-viewport-height} - #{$gl-spacing-scale-4}
);
padding-inline: $gl-padding-4;
overflow-y: scroll;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
.project-page-sidebar-block {
width: calc(var(--project-overview-sidebar-width) - 1px);
&:first-of-type {
padding-top: $gl-spacing-scale-1;
}
}
.nav {
> li {
width: 100%;
}
.btn {
justify-content: flex-start;
&:not(.btn-dashed) {
box-shadow: none;
}
}
}
}
}
}
......@@ -235,8 +235,7 @@
}
.repository-languages-bar {
height: 8px;
margin-bottom: $gl-padding;
height: 0.5rem;
background-color: var(--white, $white);
border-radius: $border-radius-default;
......
......@@ -11,12 +11,22 @@ def stat_anchor_attrs(anchor)
private
def new_button_attribute(anchor)
anchor.class_modifier || 'btn-link gl-text-blue-500!'
end
def button_attribute(anchor)
anchor.class_modifier || 'btn-dashed'
end
def extra_classes(anchor)
if anchor.is_link
if Feature.enabled?(:project_overview_reorg)
if anchor.is_link
'stat-link gl-px-0! gl-pb-2!'
else
"stat-link gl-px-0! gl-pb-2! #{new_button_attribute(anchor)}"
end
elsif anchor.is_link
'stat-link'
else
"gl-button btn #{button_attribute(anchor)}"
......
......@@ -21,8 +21,16 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
AnchorData = Struct.new(:is_link, :label, :link, :class_modifier, :icon, :itemprop, :data)
MAX_TOPICS_TO_SHOW = 3
def statistic_icon(icon_name = 'plus-square-o')
sprite_icon(icon_name, css_class: 'icon gl-mr-2 gl-text-gray-500')
def statistic_default_class_list
Feature.enabled?(:project_overview_reorg) ? 'icon gl-mr-3 gl-text-gray-500' : 'icon gl-mr-2 gl-text-gray-500'
end
def statistic_default_icon
Feature.enabled?(:project_overview_reorg) ? 'plus' : 'plus-square-o'
end
def statistic_icon(icon_name = statistic_default_icon, class_list = statistic_default_class_list)
sprite_icon(icon_name, css_class: class_list)
end
def statistics_anchors(show_auto_devops_callout:)
......@@ -288,13 +296,19 @@ def new_file_anchor_data
if can_current_user_push_to_default_branch?
new_file_path = empty_repo? ? ide_edit_path(project, default_branch_or_main) : project_new_blob_path(project, default_branch_or_main)
AnchorData.new(false, statistic_icon + _('New file'), new_file_path, 'btn-dashed')
if Feature.enabled?(:project_overview_reorg)
AnchorData.new(false, statistic_icon('plus', 'gl-text-blue-500! gl-mr-3') + _('New file'), new_file_path)
else
AnchorData.new(false, statistic_icon + _('New file'), new_file_path, 'btn-dashed')
end
end
end
def readme_anchor_data
if can_current_user_push_to_default_branch? && readme_path.nil?
AnchorData.new(false, statistic_icon + _('Add README'), empty_repo? ? add_readme_ide_path : add_readme_path)
icon = Feature.enabled?(:project_overview_reorg) ? statistic_icon('plus', 'gl-text-blue-500! gl-mr-3') : statistic_icon
label = icon + _('Add README')
AnchorData.new(false, label, empty_repo? ? add_readme_ide_path : add_readme_path)
elsif readme_path
AnchorData.new(
false,
......@@ -308,9 +322,11 @@ def readme_anchor_data
def changelog_anchor_data
if can_current_user_push_to_default_branch? && repository.changelog.blank?
icon = Feature.enabled?(:project_overview_reorg) ? statistic_icon('plus', 'gl-mr-3') : statistic_icon
label = icon + _('Add CHANGELOG')
AnchorData.new(
false,
statistic_icon + _('Add CHANGELOG'),
label,
empty_repo? ? add_changelog_ide_path : add_changelog_path
)
elsif repository.changelog.present?
......@@ -336,9 +352,11 @@ def license_anchor_data
'license'
)
elsif can_current_user_push_to_default_branch?
icon = Feature.enabled?(:project_overview_reorg) ? statistic_icon('plus', 'gl-text-blue-500! gl-mr-3') : statistic_icon
label = icon + _('Add LICENSE')
AnchorData.new(
false,
content_tag(:span, statistic_icon + _('Add LICENSE'), class: 'add-license-link d-flex'),
content_tag(:span, label, class: 'add-license-link d-flex'),
empty_repo? ? add_license_ide_path : add_license_path
)
end
......@@ -346,9 +364,11 @@ def license_anchor_data
def contribution_guide_anchor_data
if can_current_user_push_to_default_branch? && repository.contribution_guide.blank?
icon = Feature.enabled?(:project_overview_reorg) ? statistic_icon('plus', 'gl-text-blue-500! gl-mr-3') : statistic_icon
label = icon + _('Add CONTRIBUTING')
AnchorData.new(
false,
statistic_icon + _('Add CONTRIBUTING'),
label,
empty_repo? ? add_contribution_guide_ide_path : add_contribution_guide_path
)
elsif repository.contribution_guide.present?
......@@ -387,7 +407,11 @@ def autodevops_anchor_data(show_auto_devops_callout: false)
def kubernetes_cluster_anchor_data
if can_instantiate_cluster?
if clusters.empty?
AnchorData.new(false, statistic_icon + _('Add Kubernetes cluster'), project_clusters_path(project))
if Feature.enabled?(:project_overview_reorg)
AnchorData.new(false, content_tag(:span, statistic_icon('plus', 'gl-mr-3') + _('Add Kubernetes cluster'), class: 'btn-link'), project_clusters_path(project))
else
AnchorData.new(false, content_tag(:span, statistic_icon + _('Add Kubernetes cluster')), project_clusters_path(project))
end
else
cluster_link = clusters.count == 1 ? project_cluster_path(project, clusters.first) : project_clusters_path(project)
......@@ -402,7 +426,7 @@ def gitlab_ci_anchor_data
if cicd_missing?
AnchorData.new(false, statistic_icon + _('Set up CI/CD'), project_ci_pipeline_editor_path(project))
elsif repository.gitlab_ci_yml.present?
AnchorData.new(false, statistic_icon('doc-text') + _('CI/CD configuration'), project_ci_pipeline_editor_path(project), 'btn-default')
AnchorData.new(false, statistic_icon('rocket') + _('CI/CD configuration'), project_ci_pipeline_editor_path(project), 'btn-default')
end
end
......@@ -412,7 +436,9 @@ def wiki_anchor_data
if project.wiki.has_home_page?
AnchorData.new(false, statistic_icon('book') + _('Wiki'), project_wiki_path, 'btn-default', nil, nil)
elsif can_create_wiki?
AnchorData.new(false, statistic_icon + _('Add Wiki'), project_create_wiki_path, nil, nil, nil)
icon = Feature.enabled?(:project_overview_reorg) ? statistic_icon('plus', 'gl-mr-3') : statistic_icon
label = icon + _('Add Wiki')
AnchorData.new(false, label, project_create_wiki_path, nil, nil, nil)
end
end
......@@ -457,8 +483,11 @@ def all_clusters_empty?
def integrations_anchor_data
return unless can?(current_user, :admin_project, project)
label = statistic_icon('settings') + _('Configure Integrations')
AnchorData.new(false, label, project_settings_integrations_path(project), nil, nil, nil)
if Feature.enabled?(:project_overview_reorg)
AnchorData.new(false, content_tag(:span, statistic_icon('plus', 'gl-blue-500! gl-mr-3') + _('Configure Integrations'), class: 'btn-link'), project_settings_integrations_path(project), nil, nil, nil)
else
AnchorData.new(false, content_tag(:span, statistic_icon('settings') + _('Configure Integrations')), project_settings_integrations_path(project), nil, nil, nil)
end
end
def cicd_missing?
......
......@@ -8,23 +8,27 @@
- add_page_startup_api_call project_blob_path(@project, tree_join(@ref, readme_path), viewer: "rich", format: "json")
#tree-holder.tree-holder.clearfix.js-per-page{ data: { blame_per_page: Gitlab::Git::BlamePagination::PAGINATION_PER_PAGE } }
- if Feature.enabled?(:project_overview_reorg)
.nav-block.gl-display-flex.gl-flex-direction-column.gl-sm-flex-direction-row.gl-align-items-stretch
= render 'projects/tree/tree_header', tree: @tree
.info-well.gl-display-none.gl-sm-display-flex.project-last-commit.gl-flex-direction-column.gl-mt-5
#js-last-commit.gl-m-auto{ data: {ref_type: @ref_type.to_s} }
= gl_loading_icon(size: 'md')
- if project.licensed_feature_available?(:code_owners)
#js-code-owners{ data: { branch: @ref, can_view_branch_rules: can_view_branch_rules?, branch_rules_path: branch_rules_path } }
.nav-block.gl-display-flex.gl-flex-direction-column.gl-sm-flex-direction-row.gl-align-items-stretch
= render 'projects/tree/tree_header', tree: @tree
- if Feature.disabled?(:project_overview_reorg)
.nav-block.gl-display-flex.gl-flex-direction-column.gl-sm-flex-direction-row.gl-align-items-stretch
= render 'projects/tree/tree_header', tree: @tree
- if project.forked?
#js-fork-info{ data: vue_fork_divergence_data(project, ref) }
- if is_project_overview && has_project_shortcut_buttons
- if Feature.disabled?(:project_overview_reorg) && is_project_overview && has_project_shortcut_buttons
.project-buttons.gl-mb-5.js-show-on-project-root{ data: { testid: 'project-buttons' } }
= render 'stat_anchor_list', anchors: @project.statistics_buttons(show_auto_devops_callout: show_auto_devops_callout), project_buttons: true
#js-tree-list{ data: vue_file_list_data(project, ref) }
- if can_edit_tree?
= render 'projects/blob/new_dir'
- empty_repo = @project.empty_repo?
- show_auto_devops_callout = show_auto_devops_callout?(@project)
- emails_disabled = @project.emails_disabled?
- ff_reorg_disabled = Feature.disabled?(:project_overview_reorg)
.project-home-panel.js-show-on-project-root.gl-mt-4.gl-mb-5{ class: [("empty-project" if empty_repo)] }
.gl-display-flex.gl-justify-content-space-between.gl-flex-wrap.gl-flex-direction-column.gl-md-flex-direction-row.gl-mb-3.gl-gap-5
%header.project-home-panel.js-show-on-project-root.gl-mt-5{ class: [("empty-project" if empty_repo)] }
.gl-display-flex.gl-justify-content-space-between.gl-flex-wrap.gl-flex-direction-column.gl-md-flex-direction-row.gl-gap-5
.home-panel-title-row.gl-display-flex.gl-align-items-center
%div{ class: 'avatar-container rect-avatar s64 home-panel-avatar gl-flex-shrink-0 gl-w-11 gl-h-11 gl-mr-3! float-none' }
= project_icon(@project, alt: @project.name, class: 'avatar avatar-tile s64', width: 64, height: 64, itemprop: 'image')
......@@ -35,25 +35,29 @@
= render 'projects/buttons/star'
= render 'projects/buttons/fork'
- if can?(current_user, :read_code, @project)
%nav.project-stats
- if @project.empty_repo?
= render 'stat_anchor_list', anchors: @project.empty_repo_statistics_anchors
- else
= render 'stat_anchor_list', anchors: @project.statistics_anchors(show_auto_devops_callout: show_auto_devops_callout)
.gl-my-3
= render "shared/projects/topics", project: @project
.home-panel-home-desc.mt-1
- if @project.description.present?
.home-panel-description.text-break
.home-panel-description-markdown.read-more-container{ itemprop: 'description' }
= markdown_field(@project, :description)
%button.btn.gl-button.btn-blank.btn-link.js-read-more-trigger.d-lg-none{ type: "button" }
= _("Read more")
- if ff_reorg_disabled
- if can?(current_user, :read_code, @project)
- show_auto_devops_callout = show_auto_devops_callout?(@project)
%nav.project-stats.gl-mt-3
- if @project.empty_repo?
= render 'stat_anchor_list', anchors: @project.empty_repo_statistics_anchors
- else
= render 'stat_anchor_list', anchors: @project.statistics_anchors(show_auto_devops_callout: show_auto_devops_callout)
.gl-my-3
= render "shared/projects/topics", project: @project
.home-panel-home-desc.mt-1
- if @project.description.present?
.home-panel-description.text-break
.home-panel-description-markdown.read-more-container{ itemprop: 'description' }
= markdown_field(@project, :description)
%button.btn.gl-button.btn-blank.btn-link.js-read-more-trigger.d-lg-none{ type: "button" }
= _("Read more")
= render_if_exists "projects/home_mirror"
- if @project.badges.present?
- if ff_reorg_disabled && @project.badges.present?
.project-badges.mb-2{ data: { testid: 'project-badges-content' } }
- @project.badges.each do |badge|
- badge_link_url = badge.rendered_link_url(@project)
......
%h4.gl-mt-0.gl-mb-3{ data: { testid: 'invite-member-section',
track_label: 'invite_members_empty_project',
track_action: 'render' } }
= s_('InviteMember|Invite your team')
%p= s_('InviteMember|Add members to this project and start collaborating with your team.')
.js-invite-members-trigger{ data: { variant: 'confirm',
classes: 'gl-mb-8 gl-w-full gl-sm-w-auto',
display_text: s_('InviteMember|Invite members'),
trigger_source: 'project_empty_page' } }
- if Feature.enabled?(:project_overview_reorg)
%p.gl-font-weight-bold.gl-text-gray-900.gl-mt-0.gl-mt-n1.gl-mb-3{ data: { testid: 'invite-member-section',
track_label: 'invite_members_empty_project',
track_action: 'render' } }
= s_('InviteMember|Invite your team')
%p.gl-mb-3= s_('InviteMember|Add members to this project and start collaborating with your team.')
.js-invite-members-trigger{ data: { variant: 'confirm',
classes: 'gl-mb-3 gl-w-full gl-sm-w-auto',
display_text: s_('InviteMember|Invite members'),
trigger_source: 'project_empty_page' } }
- else
%h4.gl-mt-0.gl-mb-3{ data: { testid: 'invite-member-section',
track_label: 'invite_members_empty_project',
track_action: 'render' } }
= s_('InviteMember|Invite your team')
%p= s_('InviteMember|Add members to this project and start collaborating with your team.')
.js-invite-members-trigger{ data: { variant: 'confirm',
classes: 'gl-mb-8 gl-w-full gl-sm-w-auto',
display_text: s_('InviteMember|Invite members'),
trigger_source: 'project_empty_page' } }
- has_project_shortcut_buttons = !current_user || current_user.project_shortcut_buttons
- show_auto_devops_callout = show_auto_devops_callout?(@project)
%aside.project-page-sidebar
- if @project.description.present? || @project.badges.present?
.project-page-sidebar-block.home-panel-home-desc.gl-py-4.gl-border-b.gl-border-gray-50
-# Project description
- if @project.description.present?
.gl-display-flex.gl-justify-content-space-between.gl-mt-1.gl-pr-2
%p.gl-font-weight-bold.gl-text-gray-900.gl-m-0= s_('ProjectPage|Project information')
= render Pajamas::ButtonComponent.new(href: edit_project_path(@project),
category: :tertiary,
icon: 'settings',
size: :small,
button_options: { class: 'has-tooltip', title: s_('ProjectPage|Project settings'), 'aria-label' => s_('ProjectPage|Project settings') })
.home-panel-description.text-break
.home-panel-description-markdown{ itemprop: 'description' }
= markdown_field(@project, :description)
-# Topics
- if @project.topics.present?
.gl-mb-5
= render "shared/projects/topics", project: @project
-# Programming languages
- if can?(current_user, :read_code, @project) && @project.repository_languages.present?
.gl-mb-2{ class: ('gl-mb-4!' if @project.badges.present?) }
= repository_languages_bar(@project.repository_languages)
-# Badges
- if @project.badges.present?
.project-badges.gl-mb-2{ data: { testid: 'project-badges-content' } }
- @project.badges.each do |badge|
- badge_link_url = badge.rendered_link_url(@project)
%a.gl-mr-3{ href: badge_link_url,
target: '_blank',
rel: 'noopener noreferrer',
data: { testid: 'badge-image-link', qa_link_url: badge_link_url } }>
%img.project-badge{ src: badge.rendered_image_url(@project),
'aria-hidden': true,
alt: 'Project badge' }>
-# Invite members
- if @project.empty_repo?
.project-page-sidebar-block.gl-py-4.gl-border-b.gl-border-gray-50
= render "invite_members_empty_project" if can_admin_project_member?(@project)
-# Buttons
- if can?(current_user, :read_code, @project) && !@project.empty_repo?
.project-page-sidebar-block.gl-py-4.gl-border-b.gl-border-gray-50
%nav.project-stats
= render 'stat_anchor_list', anchors: @project.statistics_anchors(show_auto_devops_callout: show_auto_devops_callout)
-# Buttons
- if has_project_shortcut_buttons
.project-page-sidebar-block.gl-py-4
.project-buttons.gl-mb-2.js-show-on-project-root{ data: { testid: 'project-buttons' } }
- if @project.empty_repo?
= render 'stat_anchor_list', anchors: @project.empty_repo_statistics_buttons, project_buttons: true
- else
= render 'stat_anchor_list', anchors: @project.statistics_buttons(show_auto_devops_callout: show_auto_devops_callout), project_buttons: true
......@@ -2,8 +2,9 @@
- project_buttons = local_assigns.fetch(:project_buttons, false)
- return unless anchors.any?
%ul.nav{ class: (project_buttons ? 'gl-gap-3' : 'gl-gap-5') }
%ul.nav.gl-gap-2
- anchors.each do |anchor|
%li.nav-item
= link_to_if(anchor.link, anchor.label, anchor.link, stat_anchor_attrs(anchor)) do
.stat-text.d-flex.align-items-center{ class: ('btn gl-button btn-default disabled' if project_buttons) }= anchor.label
.stat-text.d-flex.align-items-center{ class: ('btn gl-button btn-default gl-px-0! disabled' if project_buttons) }= anchor.label
......@@ -4,7 +4,7 @@
- if can?(current_user, :download_code, @project)
.git-clone-holder.js-git-clone-holder
= render Pajamas::ButtonComponent.new(variant: :confirm, button_options: { id: 'clone-dropdown', class: 'clone-dropdown-btn', data: { toggle: 'dropdown', qa_selector: 'clone_dropdown' } }) do
%span.gl-mr-2.js-clone-dropdown-label
%span.js-clone-dropdown-label
= _('Clone')
= sprite_icon("chevron-down", css_class: "icon")
%ul.dropdown-menu.dropdown-menu-large.dropdown-menu-selectable.clone-options-dropdown{ class: dropdown_class, data: { qa_selector: 'clone_dropdown_content' } }
......
......@@ -9,68 +9,142 @@
= render "home_panel"
= render "archived_notice", project: @project
= render "invite_members_empty_project" if can_admin_project_member?(@project)
- if Feature.enabled?(:project_overview_reorg)
- add_page_specific_style 'page_bundles/project'
%h4.gl-mt-0.gl-mb-3
= _('The repository for this project is empty')
.project-page-indicator.js-show-on-project-root
- if @project.can_current_user_push_code?
%p
= _('You can get started by cloning the repository or start adding files to it with one of the following options.')
.project-page-layout
.project-page-layout-content.gl-mt-5
.project-buttons.gl-mb-5{ data: { testid: 'quick-actions-container' } }
.project-clone-holder.d-block.d-md-none
= render "shared/mobile_clone_panel"
.project-buttons{ data: { testid: 'quick-actions-container' } }
.project-clone-holder.d-block.d-md-none.gl-mt-3.gl-mr-3
= render "shared/mobile_clone_panel"
.project-clone-holder.gl-display-none.gl-md-display-flex.gl-justify-content-end.gl-w-full.gl-mt-2
= render "projects/buttons/clone"
.project-clone-holder.d-none.d-md-inline-block.gl-mb-3.gl-mr-3.float-left
= render "projects/buttons/clone"
= render 'stat_anchor_list', anchors: @project.empty_repo_statistics_buttons, project_buttons: true
= render Pajamas::CardComponent.new(card_options: { class: 'gl-mb-5' }, body_options: { class: 'gl-new-card-body gl-bg-gray-10 gl-p-5' }) do |c|
- c.with_body do
%h4.gl-font-lg.gl-mt-0.gl-mb-2= _('The repository for this project is empty')
- if @project.can_current_user_push_code?
%p.gl-m-0.gl-text-secondary= _('You can get started by cloning the repository or start adding files to it with one of the following options.')
- if can?(current_user, :push_code, @project)
.empty-wrapper.gl-mt-4
%h3#repo-command-line-instructions.page-title-empty
= _('Command line instructions')
- if can?(current_user, :push_code, @project)
= render Pajamas::CardComponent.new(header_options: { class: 'gl-py-4' }) do |c|
- c.with_header do
%h5.gl-font-lg.gl-m-0= _('Command line instructions')
- c.with_body do
%p
= _('You can also upload existing files from your computer using the instructions below.')
.git-empty.js-git-empty
%h5= _('Git global setup')
%pre.gl-bg-gray-10
:preserve
git config --global user.name "#{h git_user_name}"
git config --global user.email "#{h git_user_email}"
%h5= _('Create a new repository')
%pre.gl-bg-gray-10
:preserve
git clone #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
cd #{h @project.path}
git switch --create #{h escaped_default_branch_name}
touch README.md
git add README.md
git commit -m "add README"
- if @project.can_current_user_push_to_default_branch?
%span><
git push --set-upstream origin #{h escaped_default_branch_name }
%h5= _('Push an existing folder')
%pre.gl-bg-gray-10
:preserve
cd existing_folder
git init --initial-branch=#{h escaped_default_branch_name}
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
git add .
git commit -m "Initial commit"
- if @project.can_current_user_push_to_default_branch?
%span><
git push --set-upstream origin #{h escaped_default_branch_name }
%h5= _('Push an existing Git repository')
%pre.gl-bg-gray-10
:preserve
cd existing_repo
git remote rename origin old-origin
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
- if @project.can_current_user_push_to_default_branch?
%span><
git push --set-upstream origin --all
git push --set-upstream origin --tags
.project-page-layout-sidebar.js-show-on-project-root.gl-mt-5
= render "sidebar"
- else
= render "invite_members_empty_project" if can_admin_project_member?(@project)
%h4.gl-mt-0.gl-mb-3
= _('The repository for this project is empty')
- if @project.can_current_user_push_code?
%p
= _('You can also upload existing files from your computer using the instructions below.')
.git-empty.js-git-empty
%h5= _('Git global setup')
%pre.bg-light
:preserve
git config --global user.name "#{h git_user_name}"
git config --global user.email "#{h git_user_email}"
%h5= _('Create a new repository')
%pre.bg-light
:preserve
git clone #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
cd #{h @project.path}
git switch --create #{h escaped_default_branch_name}
touch README.md
git add README.md
git commit -m "add README"
- if @project.can_current_user_push_to_default_branch?
%span><
git push --set-upstream origin #{h escaped_default_branch_name }
%h5= _('Push an existing folder')
%pre.bg-light
:preserve
cd existing_folder
git init --initial-branch=#{h escaped_default_branch_name}
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
git add .
git commit -m "Initial commit"
- if @project.can_current_user_push_to_default_branch?
%span><
git push --set-upstream origin #{h escaped_default_branch_name }
%h5= _('Push an existing Git repository')
%pre.bg-light
:preserve
cd existing_repo
git remote rename origin old-origin
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
- if @project.can_current_user_push_to_default_branch?
%span><
git push --set-upstream origin --all
git push --set-upstream origin --tags
= _('You can get started by cloning the repository or start adding files to it with one of the following options.')
.project-buttons{ data: { testid: 'quick-actions-container' } }
.project-clone-holder.d-block.d-md-none.gl-mt-3.gl-mr-3
= render "shared/mobile_clone_panel"
.project-clone-holder.d-none.d-md-inline-block.gl-mb-3.gl-mr-3.float-left
= render "projects/buttons/clone"
= render 'stat_anchor_list', anchors: @project.empty_repo_statistics_buttons, project_buttons: true
- if can?(current_user, :push_code, @project)
.empty-wrapper.gl-mt-4
%h3#repo-command-line-instructions.page-title-empty
= _('Command line instructions')
%p
= _('You can also upload existing files from your computer using the instructions below.')
.git-empty.js-git-empty
%h5= _('Git global setup')
%pre.bg-light
:preserve
git config --global user.name "#{h git_user_name}"
git config --global user.email "#{h git_user_email}"
%h5= _('Create a new repository')
%pre.bg-light
:preserve
git clone #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
cd #{h @project.path}
git switch --create #{h escaped_default_branch_name}
touch README.md
git add README.md
git commit -m "add README"
- if @project.can_current_user_push_to_default_branch?
%span><
git push --set-upstream origin #{h escaped_default_branch_name }
%h5= _('Push an existing folder')
%pre.bg-light
:preserve
cd existing_folder
git init --initial-branch=#{h escaped_default_branch_name}
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
git add .
git commit -m "Initial commit"
- if @project.can_current_user_push_to_default_branch?
%span><
git push --set-upstream origin #{h escaped_default_branch_name }
%h5= _('Push an existing Git repository')
%pre.bg-light
:preserve
cd existing_repo
git remote rename origin old-origin
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
- if @project.can_current_user_push_to_default_branch?
%span><
git push --set-upstream origin --all
git push --set-upstream origin --tags
......@@ -15,15 +15,35 @@
= render "home_panel"
- if can?(current_user, :read_code, @project) && @project.repository_languages.present?
- add_page_startup_graphql_call('repository/path_last_commit', { projectPath: @project.full_path, ref: current_ref, path: current_route_path || "" })
= repository_languages_bar(@project.repository_languages)
- if Feature.enabled?(:project_overview_reorg)
.project-page-indicator.js-show-on-project-root
= render "archived_notice", project: @project
= render_if_exists "projects/marked_for_deletion_notice", project: @project
= render_if_exists "projects/ancestor_group_marked_for_deletion_notice", project: @project
.project-page-layout
.project-page-layout-sidebar.js-show-on-project-root.gl-mt-5
= render "sidebar"
- view_path = @project.default_view
.project-page-layout-content.gl-mt-5
- if can?(current_user, :read_code, @project) && @project.repository_languages.present?
- add_page_startup_graphql_call('repository/path_last_commit', { projectPath: @project.full_path, ref: current_ref, path: current_route_path || "" })
%div{ class: project_child_container_class(view_path) }
= render view_path, is_project_overview: true
= render "archived_notice", project: @project
= render_if_exists "projects/marked_for_deletion_notice", project: @project
= render_if_exists "projects/ancestor_group_marked_for_deletion_notice", project: @project
- view_path = @project.default_view
%div{ class: project_child_container_class(view_path) }
= render view_path, is_project_overview: true
- else
- if can?(current_user, :read_code, @project) && @project.repository_languages.present?
- add_page_startup_graphql_call('repository/path_last_commit', { projectPath: @project.full_path, ref: current_ref, path: current_route_path || "" })
= repository_languages_bar(@project.repository_languages)
= render "archived_notice", project: @project
= render_if_exists "projects/marked_for_deletion_notice", project: @project
= render_if_exists "projects/ancestor_group_marked_for_deletion_notice", project: @project
- view_path = @project.default_view
%div{ class: project_child_container_class(view_path) }
= render view_path, is_project_overview: true
......@@ -2,8 +2,9 @@
- if project.topics.present?
.gl-w-full.gl-display-inline-flex.gl-flex-wrap.gl-font-base.gl-font-weight-normal.gl-align-items-center.gl-mx-n2.gl-my-n2{ 'data-testid': 'project_topic_list' }
%span.gl-p-2.gl-text-gray-500
= _('Topics') + ':'
- if Feature.disabled?(:project_overview_reorg)
%span.gl-p-2.gl-text-gray-500
= _('Topics') + ':'
- project.topics_to_show.each do |topic|
- explore_project_topic_path = topic_explore_projects_cleaned_path(topic_name: topic[:name])
- if topic[:title].length > max_project_topic_length
......
---
name: project_overview_reorg
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/137025
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/432034
milestone: '16.7'
type: development
group: group::ux paper cuts
default_enabled: false
......@@ -36,6 +36,10 @@
create(:project, :repository, mirror: true, mirror_user: user, import_url: 'http://user:pass@test.com')
end
before do
stub_feature_flags(project_overview_reorg: false)
end
context 'for maintainer' do
before do
project.add_maintainer(user)
......
......@@ -37396,6 +37396,12 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
 
msgid "ProjectPage|Project information"
msgstr ""
msgid "ProjectPage|Project settings"
msgstr ""
msgid "ProjectQualitySummary|An error occurred while trying to fetch project quality statistics"
msgstr ""
 
......@@ -36,6 +36,9 @@ class Show < Page::Base
view 'app/views/projects/_home_panel.html.haml' do
element 'project-name-content'
element 'project-id-content'
end
view 'app/views/projects/_sidebar.html.haml' do
element 'project-badges-content'
element 'badge-image-link'
end
......
......@@ -10,6 +10,7 @@
# validation failure on NotificationSetting.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/299822#note_492817174
user.notification_settings.reset
stub_feature_flags(project_overview_reorg: false)
end
shared_examples_for 'redirects to the sign in page' do
......
......@@ -17,8 +17,8 @@
describe 'as a normal user' do
before do
stub_feature_flags(project_overview_reorg: false)
sign_in(user)
visit project_path(project)
end
......@@ -40,6 +40,7 @@
describe 'as a maintainer' do
before do
stub_feature_flags(project_overview_reorg: false)
project.add_maintainer(user)
sign_in(user)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment