diff --git a/app/assets/javascripts/persistent_user_callouts.js b/app/assets/javascripts/persistent_user_callouts.js index 31e80107fd8..100ffc0664b 100644 --- a/app/assets/javascripts/persistent_user_callouts.js +++ b/app/assets/javascripts/persistent_user_callouts.js @@ -10,7 +10,7 @@ const PERSISTENT_USER_CALLOUTS = [ '.js-new-user-signups-cap-reached', '.js-eoa-bronze-plan-banner', '.js-security-newsletter-callout', - '.js-approaching-seat-count-threshold', + '.js-approaching-seats-count-threshold', '.js-storage-enforcement-banner', '.js-user-over-limit-free-plan-alert', '.js-minute-limit-banner', diff --git a/app/controllers/registrations/welcome_controller.rb b/app/controllers/registrations/welcome_controller.rb index 77e734e15fa..ea50099120b 100644 --- a/app/controllers/registrations/welcome_controller.rb +++ b/app/controllers/registrations/welcome_controller.rb @@ -58,16 +58,7 @@ module Registrations def path_for_signed_in_user(user) return users_almost_there_path(email: user.email) if requires_confirmation?(user) - stored_url = stored_location_for(user) - if ::Feature.enabled?(:about_your_company_registration_flow) && - stored_url&.include?(new_users_sign_up_company_path) - company_params = update_params.slice(:role, :other_role, :registration_objective) - .merge(params.permit(:jobs_to_be_done_other)) - redirect_uri = Gitlab::Utils.add_url_parameters(stored_url, company_params) - store_location_for(:user, redirect_uri) - else - stored_url || members_activity_path(user.members) - end + stored_location_for(user) || members_activity_path(user.members) end def members_activity_path(members) diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb index c83200bd614..58729b34fc7 100644 --- a/app/graphql/types/issue_type.rb +++ b/app/graphql/types/issue_type.rb @@ -127,6 +127,9 @@ module Types field :moved_to, Types::IssueType, null: true, description: 'Updated Issue after it got moved to another project.' + field :closed_as_duplicate_of, Types::IssueType, null: true, + description: 'Issue this issue was closed as a duplicate of.' + field :create_note_email, GraphQL::Types::String, null: true, description: 'User specific email address for the issue.' @@ -161,6 +164,10 @@ module Types Gitlab::Graphql::Loaders::BatchModelLoader.new(Issue, object.moved_to_id).find end + def closed_as_duplicate_of + Gitlab::Graphql::Loaders::BatchModelLoader.new(Issue, object.duplicated_to_id).find + end + def discussion_locked !!object.discussion_locked end diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index b7cf7b7468f..185ed228d92 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -16,7 +16,7 @@ = yield :flash_message = dispensable_render "shared/service_ping_consent" = dispensable_render_if_exists "layouts/header/ee_subscribable_banner" - = dispensable_render_if_exists "layouts/header/seat_count_alert" + = dispensable_render_if_exists "layouts/header/seats_count_alert" = dispensable_render_if_exists "shared/namespace_storage_limit_alert" = dispensable_render_if_exists "shared/namespace_user_cap_reached_alert" = dispensable_render_if_exists "shared/new_user_signups_cap_reached_alert" diff --git a/config/feature_flags/development/seat_count_alerts.yml b/config/feature_flags/development/seat_count_alerts.yml deleted file mode 100644 index 3b05f391cbc..00000000000 --- a/config/feature_flags/development/seat_count_alerts.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: seat_count_alerts -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79563 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/362041 -milestone: '15.1' -type: development -group: group::purchase -default_enabled: false diff --git a/db/docs/ci_instance_variables.yml b/db/docs/ci_instance_variables.yml index aaac23556d6..94d7c08a0fa 100644 --- a/db/docs/ci_instance_variables.yml +++ b/db/docs/ci_instance_variables.yml @@ -4,6 +4,6 @@ classes: - Ci::InstanceVariable feature_categories: - pipeline_authoring -description: TODO +description: CI/CD variables available to all projects and groups in an instance. introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30156 milestone: '13.0' diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 1539fce8f56..9edd98a09e2 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -11016,6 +11016,7 @@ Relationship between an epic and an issue. | `blockedByCount` | [`Int`](#int) | Count of issues blocking this issue. | | `blockedByIssues` | [`IssueConnection`](#issueconnection) | Issues blocking this issue. (see [Connections](#connections)) | | `blockingCount` | [`Int!`](#int) | Count of issues this issue is blocking. | +| `closedAsDuplicateOf` | [`Issue`](#issue) | Issue this issue was closed as a duplicate of. | | `closedAt` | [`Time`](#time) | Timestamp of when the issue was closed. | | `confidential` | [`Boolean!`](#boolean) | Indicates the issue is confidential. | | `createNoteEmail` | [`String`](#string) | User specific email address for the issue. | @@ -12341,6 +12342,7 @@ Returns [`VulnerabilitySeveritiesCount`](#vulnerabilityseveritiescount). | `blockedByCount` | [`Int`](#int) | Count of issues blocking this issue. | | `blockedByIssues` | [`IssueConnection`](#issueconnection) | Issues blocking this issue. (see [Connections](#connections)) | | `blockingCount` | [`Int!`](#int) | Count of issues this issue is blocking. | +| `closedAsDuplicateOf` | [`Issue`](#issue) | Issue this issue was closed as a duplicate of. | | `closedAt` | [`Time`](#time) | Timestamp of when the issue was closed. | | `confidential` | [`Boolean!`](#boolean) | Indicates the issue is confidential. | | `createNoteEmail` | [`String`](#string) | User specific email address for the issue. | diff --git a/doc/development/documentation/structure.md b/doc/development/documentation/structure.md index 329fd279b99..a02046d4466 100644 --- a/doc/development/documentation/structure.md +++ b/doc/development/documentation/structure.md @@ -37,9 +37,6 @@ Don't tell them **how** to do this thing. Tell them **what it is**. If you start describing another concept, start a new concept and link to it. -Also, do not use **Overview** or **Introduction** for the title. Instead, -use a noun or phrase that someone would search for. - Concepts should be in this format: ```markdown @@ -53,6 +50,19 @@ Remember, if you start to describe about another concept, stop yourself. Each concept should be about one concept only. ``` +### Concept headings + +For the heading text, use a noun. For example, `Widgets` or `GDK dependency management`. + +If a noun is ambiguous, you can add a gerund. For example, `Documenting versions` instead of `Versions`. + +Avoid these heading titles: + +- `Overview` or `Introduction`. Instead, use a more specific + noun or phrase that someone would search for. +- `Use cases`. Instead, incorporate the information as part of the concept. +- `How it works`. Instead, use a noun followed by `workflow`. For example, `Merge request workflow`. + ## Task A task gives instructions for how to complete a procedure. @@ -101,8 +111,13 @@ To create an issue: The issue is created. You can view it by going to **Issues > List**. ``` +### Task headings + +For the heading text, use the structure `active verb` + `noun`. +For example, `Create an issue`. + If you have several tasks on a page that share prerequisites, you can use the title -**Prerequisites**, and link to it. +`Prerequisites` and link to it. ## Reference @@ -119,8 +134,17 @@ Introductory sentence. | **Name** | Descriptive sentence about the setting. | ``` -If a feature or concept has its own prerequisites, you can use reference -content to create a **Prerequisites** header for the information. +### Reference headings + +Reference headings are usually nouns. + +Avoid these heading titles: + +- `Important notes`. Instead, incorporate this information + closer to where it belongs. For example, this information might be a prerequisite + for a task, or information about a concept. +- `Limitations`. Instead, move the content near other similar information. + If you must, you can use the title `Known issues`. ## Troubleshooting @@ -142,6 +166,10 @@ This issue occurs when... The workaround is... ``` +If multiple causes or workarounds exist, consider putting them into a table format. + +### Troubleshooting headings + For the heading: - Consider including at least a partial error message. @@ -149,7 +177,17 @@ For the heading: If you do not put the full error in the title, include it in the body text. -If multiple causes or workarounds exist, consider putting them into a table format. +## General heading text guidelines + +In general, for heading text: + +- Be clear and direct. Make every word count. +- Use articles and prepositions. +- Follow [capitalization](styleguide/index.md#capitalization) guidelines. +- Do not repeat text from earlier headings. For example, if the page is about merge requests, + instead of `Troubleshooting merge requests`, use only `Troubleshooting`. + +See also [guidelines for headings in Markdown](styleguide/index.md#headings-in-markdown). ## Other types of content diff --git a/doc/development/documentation/styleguide/index.md b/doc/development/documentation/styleguide/index.md index 970a709027c..ddb83454d04 100644 --- a/doc/development/documentation/styleguide/index.md +++ b/doc/development/documentation/styleguide/index.md @@ -86,7 +86,7 @@ move in this direction, so we can address these issues: information into a format that is geared toward helping others, rather than documenting how a feature was implemented. -GitLab uses these [topic type templates](../structure.md). +GitLab uses these [topic types](../structure.md). ### Link instead of repeating text @@ -143,6 +143,25 @@ Hard-coded HTML is valid, although it's discouraged from being used. HTML is per - Special styling is required. - Reviewed and approved by a technical writer. +### Headings in Markdown + +Each documentation page begins with a level 1 heading (`#`). This becomes the `h1` element when +the page is rendered to HTML. There can be only **one** level 1 heading per page. + +- For each subsection, increment the heading level. In other words, increment the number of `#` characters + in front of the heading. +- Do not skip a level. For example: `##` > `####`. +- Leave one blank line before and after the heading. + +When you change heading text, the anchor link changes. To avoid broken links: + +- Do not use step numbers in headings. +- When possible, do not use words that might change in the future. + +Also, do not use links as part of heading text. + +See also [heading guidelines for specific topic types](../structure.md). + ### Markdown Rules GitLab ensures that the Markdown used across all documentation is consistent, as @@ -648,45 +667,6 @@ For other punctuation rules, refer to the [Pajamas Design System Punctuation section](https://design.gitlab.com/content/punctuation/). This is overridden by the [documentation-specific punctuation rules](#punctuation). -## Headings - -In the Markdown document: - -- Add one H1 (`#`) at the start of the page. The `h1` becomes the document ``. -- After the H1, follow the order `h2` > `h3` > `h4` > `h5` > `h6`. -- Do not skip a level. For example: `h2` > `h4`. -- Leave one blank line before and after the heading. - -For the heading text, **do**: - -- Be clear and direct. Make every word count. -- Use active, imperative verbs for [tasks](../structure.md#task). For example, `Create an issue`. -- Use `ing` (gerund) verbs only when you need a topic that introduces tasks. For example, `Configuring GDK`. -- Use nouns for [concepts](../structure.md#concept). For example, `GDK dependency management`. If a noun is - ambiguous, you can add a gerund. For example, `Documenting versions` instead of `Versions`. -- Talk about what the product does, realistically but from a positive perspective. Instead of - `Limitations`, move the content near other similar information. If you must, you can - use the title `Known issues`. -- Use articles and prepositions. -- Add the [product badge](#product-tier-badges) that corresponds to the license tier. -- Follow [capitalization](#capitalization) guidelines. - -For the heading text, **do not**: - -- Use generic words like `Overview` or `Use cases`. Instead, incorporate - the information under a concept heading. -- Use `How it works`. Incorporate this information under a concept, or use a - noun followed by `workflow`. For example, `Merge request workflow`. -- Use `Important Notes`. Incorporate this information closer to where it belongs. -- Use numbers to indicate steps. If the numbers change, the anchor links changes, - which eventually leads to dead links. If you think you must add numbers in headings, - at least discuss it with a writer in the merge request. -- Use words that might change in the future. Changing - a heading changes its anchor URL, which affects other linked pages. -- Repeat text from earlier headings. For example, instead of `Troubleshooting merge requests`, - use `Troubleshooting`. -- Use links. - ### Anchor links Headings generate anchor links when rendered. `## This is an example` generates diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 04122a57738..1b4368c7e8f 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -15008,9 +15008,6 @@ msgstr "" msgid "Estimated" msgstr "" -msgid "Even if you reach the number of seats in your subscription, you can continue to add users, and GitLab will bill you for the overage." -msgstr "" - msgid "EventFilterBy|Filter by all" msgstr "" @@ -44193,10 +44190,8 @@ msgstr "" msgid "Your subscription expired!" msgstr "" -msgid "Your subscription has %{remaining_seat_count} out of %{total_seat_count} seat remaining." -msgid_plural "Your subscription has %{remaining_seat_count} out of %{total_seat_count} seats remaining." -msgstr[0] "" -msgstr[1] "" +msgid "Your subscription has %{remaining_seats_count} out of %{total_seats_count} seats remaining. Even if you reach the number of seats in your subscription, you can continue to add users, and GitLab will bill you for the overage." +msgstr "" msgid "Your subscription is now expired. To renew, export your license usage file and email it to %{renewal_service_email}. A new license will be emailed to the email address registered in the %{customers_dot}. You can add this license to your instance. To use Free tier, remove your current license." msgstr "" diff --git a/qa/qa/page/issuable/new.rb b/qa/qa/page/issuable/new.rb index c549190c65b..ca1219cb7fc 100644 --- a/qa/qa/page/issuable/new.rb +++ b/qa/qa/page/issuable/new.rb @@ -58,6 +58,8 @@ module QA click_element :issuable_label click_link label.title + + click_element :issuable_label # So that the dropdown goes away(click away action) end def assign_to_me diff --git a/spec/controllers/registrations/welcome_controller_spec.rb b/spec/controllers/registrations/welcome_controller_spec.rb index 8a5a8490a23..c444875bf74 100644 --- a/spec/controllers/registrations/welcome_controller_spec.rb +++ b/spec/controllers/registrations/welcome_controller_spec.rb @@ -31,7 +31,6 @@ RSpec.describe Registrations::WelcomeController do context 'when role and setup_for_company is set' do before do - stub_feature_flags(about_your_company_registration_flow: false) user.update!(setup_for_company: false) sign_in(user) end @@ -61,10 +60,6 @@ RSpec.describe Registrations::WelcomeController do end describe '#update' do - before do - stub_feature_flags(about_your_company_registration_flow: false) - end - subject(:update) do patch :update, params: { user: { role: 'software_developer', setup_for_company: 'false' } } end diff --git a/spec/features/users/signup_spec.rb b/spec/features/users/signup_spec.rb index 30441dac7b6..3eae4955167 100644 --- a/spec/features/users/signup_spec.rb +++ b/spec/features/users/signup_spec.rb @@ -341,7 +341,6 @@ RSpec.describe 'Signup' do end it 'redirects to step 2 of the signup process, sets the role and redirects back' do - stub_feature_flags(about_your_company_registration_flow: false) visit new_user_registration_path fill_in_signup_form diff --git a/spec/graphql/types/issue_type_spec.rb b/spec/graphql/types/issue_type_spec.rb index 1d4590cbb4e..920aadd2faf 100644 --- a/spec/graphql/types/issue_type_spec.rb +++ b/spec/graphql/types/issue_type_spec.rb @@ -18,7 +18,7 @@ RSpec.describe GitlabSchema.types['Issue'] do confidential hidden discussion_locked upvotes downvotes merge_requests_count user_notes_count user_discussions_count web_path web_url relative_position emails_disabled subscribed time_estimate total_time_spent human_time_estimate human_total_time_spent closed_at created_at updated_at task_completion_status design_collection alert_management_alert severity current_user_todos moved moved_to - create_note_email timelogs project_id customer_relations_contacts escalation_status] + closed_as_duplicate_of create_note_email timelogs project_id customer_relations_contacts escalation_status] fields.each do |field_name| expect(described_class).to have_graphql_field(field_name) diff --git a/spec/requests/api/graphql/issue/issue_spec.rb b/spec/requests/api/graphql/issue/issue_spec.rb index 05fd6bf3022..6e2d736f244 100644 --- a/spec/requests/api/graphql/issue/issue_spec.rb +++ b/spec/requests/api/graphql/issue/issue_spec.rb @@ -129,6 +129,29 @@ RSpec.describe 'Query.issue(id)' do expect(graphql_errors.first['message']).to eq("\"#{gid}\" does not represent an instance of Issue") end end + + context 'when selecting `closed_as_duplicate_of`' do + let(:issue_fields) { ['closedAsDuplicateOf { id }'] } + let(:duplicate_issue) { create(:issue, project: project) } + + before do + issue.update!(duplicated_to_id: duplicate_issue.id) + + post_graphql(query, current_user: current_user) + end + + it 'returns the related issue' do + expect(issue_data['closedAsDuplicateOf']['id']).to eq(duplicate_issue.to_global_id.to_s) + end + + context 'no permission to related issue' do + let(:duplicate_issue) { create(:issue) } + + it 'does not return the related issue' do + expect(issue_data['closedAsDuplicateOf']).to eq(nil) + end + end + end end context 'when there is a confidential issue' do diff --git a/spec/requests/api/graphql/project/issues_spec.rb b/spec/requests/api/graphql/project/issues_spec.rb index f358ec3e53f..69e14eace66 100644 --- a/spec/requests/api/graphql/project/issues_spec.rb +++ b/spec/requests/api/graphql/project/issues_spec.rb @@ -633,6 +633,18 @@ RSpec.describe 'getting an issue list for a project' do create(:issue_timelog, issue: issue_b) end + include_examples 'N+1 query check' + end + context 'when requesting `closed_as_duplicate_of`' do + let(:requested_fields) { 'closedAsDuplicateOf { id }' } + let(:issue_a_dup) { create(:issue, project: project) } + let(:issue_b_dup) { create(:issue, project: project) } + + before do + issue_a.update!(duplicated_to_id: issue_a_dup) + issue_b.update!(duplicated_to_id: issue_a_dup) + end + include_examples 'N+1 query check' end end