Commit 0f5eb7e4 authored by Phil Hughes's avatar Phil Hughes Committed by David O'Regan

Add user README to users profile

When a user has a project named the same as their username
and then this project has a README file inside of the repository
we will display the content of this README on the overview
tab of the users profile.

Changelog: added

Closes https://gitlab.com/gitlab-org/gitlab/-/issues/232157
parent 7b03b44b
......@@ -43,6 +43,8 @@ const onProjectPathChange = ($projectNameInput, $projectPathInput, hasExistingPr
};
const setProjectNamePathHandlers = ($projectNameInput, $projectPathInput) => {
const specialRepo = document.querySelector('.js-user-readme-repo');
// eslint-disable-next-line @gitlab/no-global-event-off
$projectNameInput.off('keyup change').on('keyup change', () => {
onProjectNameChange($projectNameInput, $projectPathInput);
......@@ -54,6 +56,11 @@ const setProjectNamePathHandlers = ($projectNameInput, $projectPathInput) => {
$projectPathInput.off('keyup change').on('keyup change', () => {
onProjectPathChange($projectNameInput, $projectPathInput, hasUserDefinedProjectName);
hasUserDefinedProjectPath = $projectPathInput.val().trim().length > 0;
specialRepo.classList.toggle(
'gl-display-none',
$projectPathInput.val() !== $projectPathInput.data('username'),
);
});
};
......
......@@ -1992,6 +1992,18 @@ class User < ApplicationRecord
saved
end
def user_project
strong_memoize(:user_project) do
personal_projects.find_by(path: username, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
end
end
def user_readme
strong_memoize(:user_readme) do
user_project&.repository&.readme
end
end
protected
# override, from Devise::Validatable
......
......@@ -40,12 +40,17 @@
.form-group.project-path.col-sm-6
= f.label :path, class: 'label-bold' do
%span= _("Project slug")
= f.text_field :path, placeholder: "my-awesome-project", class: "form-control gl-form-input", required: true, aria: { required: true }
= f.text_field :path, placeholder: "my-awesome-project", class: "form-control gl-form-input", required: true, aria: { required: true }, data: { username: current_user.username }
- if current_user.can_create_group?
.form-text.text-muted
- link_start_group_path = '<a href="%{path}">' % { path: new_group_path }
- project_tip = s_('ProjectsNew|Want to house several dependent projects under the same namespace? %{link_start}Create a group.%{link_end}') % { link_start: link_start_group_path, link_end: '</a>' }
= project_tip.html_safe
.gl-alert.gl-alert-success.gl-mb-4.gl-display-none.js-user-readme-repo
= sprite_icon('check-circle', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
.gl-alert-body
- help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/profile/index', anchor: 'user-profile-readme') }
= html_escape(_('%{project_path} is a project that you can use to add a README to your GitLab profile. Create a public project and initialize the repository with a README to get started. %{help_link_start}Learn more.%{help_link_end}')) % { project_path: "<strong>#{current_user.username} / #{current_user.username}</strong>".html_safe, help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
.form-group
= f.label :description, class: 'label-bold' do
......
......@@ -9,6 +9,22 @@
%a.js-retry-load{ href: '#' }
= s_('UserProfile|Retry')
.user-calendar-activities
- if @user.user_readme
.row
.col-12.gl-my-6
.gl-border-gray-100.gl-border-1.gl-border-solid.gl-rounded-small.gl-py-4.gl-px-6
.gl-display-flex
%ol.breadcrumb.gl-breadcrumb-list.gl-mb-4
%li.breadcrumb-item.gl-breadcrumb-item
= link_to @user.username, project_path(@user.user_project)
%span.gl-breadcrumb-separator
= sprite_icon("chevron-right", size: 16)
%li.breadcrumb-item.gl-breadcrumb-item
= link_to @user.user_readme.path, @user.user_project.readme_url
- if current_user == @user
.gl-ml-auto
= link_to _('Edit'), edit_blob_path(@user.user_project, @user.user_project.default_branch, @user.user_readme.path)
= render 'projects/blob/viewer', viewer: @user.user_readme.rich_viewer, load_async: false
.row
%div{ class: activity_pane_class }
- if can?(current_user, :read_cross_project)
......
......@@ -100,6 +100,18 @@ When visiting the public page of a user, you can only see the projects which you
If the [public level is restricted](../admin_area/settings/visibility_and_access_controls.md#restrict-visibility-levels),
user profiles are only visible to signed-in users.
## User profile README
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/232157) in GitLab 14.5.
You can add a README section to your profile that can include more information and formatting than
your profile's bio.
To add a README to your profile:
1. Create a new public project with the same name as your GitLab username.
1. Create a README file inside this project. The file can be any valid [README or index file](../project/repository/index.md#readme-and-index-files).
## Add external accounts to your user profile page
You can add links to certain other external accounts you might have, like Skype and Twitter.
......
......@@ -815,6 +815,9 @@ msgstr ""
msgid "%{primary} (%{secondary})"
msgstr ""
msgid "%{project_path} is a project that you can use to add a README to your GitLab profile. Create a public project and initialize the repository with a README to get started. %{help_link_start}Learn more.%{help_link_end}"
msgstr ""
msgid "%{ref} cannot be added: %{error}"
msgstr ""
......
......@@ -21,6 +21,14 @@ RSpec.describe 'User visits their profile' do
expect(page).to have_content "This information will appear on your profile"
end
it 'shows user readme' do
create(:project, :repository, :public, path: user.username, namespace: user.namespace)
visit(user_path(user))
expect(find('.file-content')).to have_content('testme')
end
context 'when user has groups' do
let(:group) do
create :group do |group|
......
......@@ -6225,4 +6225,31 @@ RSpec.describe User do
expect(described_class.get_ids_by_username([user_name])).to match_array([user_id])
end
end
describe 'user_project' do
it 'returns users project matched by username and public visibility' do
user = create(:user)
public_project = create(:project, :public, path: user.username, namespace: user.namespace)
create(:project, namespace: user.namespace)
expect(user.user_project).to eq(public_project)
end
end
describe 'user_readme' do
it 'returns readme from user project' do
user = create(:user)
create(:project, :repository, :public, path: user.username, namespace: user.namespace)
expect(user.user_readme.name).to eq('README.md')
expect(user.user_readme.data).to include('testme')
end
it 'returns nil if project is private' do
user = create(:user)
create(:project, :repository, :private, path: user.username, namespace: user.namespace)
expect(user.user_readme).to be(nil)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment