diff options
35 files changed, 203 insertions, 86 deletions
diff --git a/app/assets/javascripts/invite_members/components/invite_members_modal.vue b/app/assets/javascripts/invite_members/components/invite_members_modal.vue index cd9c3b0b5d3..2ab49b6c760 100644 --- a/app/assets/javascripts/invite_members/components/invite_members_modal.vue +++ b/app/assets/javascripts/invite_members/components/invite_members_modal.vue @@ -49,7 +49,7 @@ export default { required: true, }, defaultAccessLevel: { - type: String, + type: Number, required: true, }, helpLink: { @@ -280,6 +280,7 @@ export default { <gl-dropdown-item :key="key" active-class="is-active" + is-check-item :is-checked="key === selectedAccessLevel" @click="changeSelectedItem(key)" > diff --git a/app/assets/javascripts/invite_members/init_invite_members_modal.js b/app/assets/javascripts/invite_members/init_invite_members_modal.js index 3de99dcc546..fc77bd53ba4 100644 --- a/app/assets/javascripts/invite_members/init_invite_members_modal.js +++ b/app/assets/javascripts/invite_members/init_invite_members_modal.js @@ -20,6 +20,7 @@ export default function initInviteMembersModal() { ...el.dataset, isProject: parseBoolean(el.dataset.isProject), accessLevels: JSON.parse(el.dataset.accessLevels), + defaultAccessLevel: parseInt(el.dataset.defaultAccessLevel, 10), }, }), }); diff --git a/app/assets/javascripts/jobs/components/sidebar.vue b/app/assets/javascripts/jobs/components/sidebar.vue index f63fe72a71a..59b50d02dda 100644 --- a/app/assets/javascripts/jobs/components/sidebar.vue +++ b/app/assets/javascripts/jobs/components/sidebar.vue @@ -1,5 +1,5 @@ <script> -import { GlButton, GlIcon, GlLink } from '@gitlab/ui'; +import { GlButton, GlIcon } from '@gitlab/ui'; import { isEmpty } from 'lodash'; import { mapActions, mapGetters, mapState } from 'vuex'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; @@ -25,7 +25,6 @@ export default { ArtifactsBlock, CommitBlock, GlButton, - GlLink, GlIcon, JobsContainer, JobSidebarRetryButton, @@ -45,11 +44,8 @@ export default { computed: { ...mapGetters(['hasForwardDeploymentFailure']), ...mapState(['job', 'stages', 'jobs', 'selectedStage']), - retryButtonClass() { - let className = 'btn gl-button gl-text-decoration-none!'; - className += - this.job.status && this.job.recoverable ? ' btn-confirm' : ' btn-confirm-secondary'; - return className; + retryButtonCategory() { + return this.job.status && this.job.recoverable ? 'primary' : 'secondary'; }, hasArtifact() { return !isEmpty(this.job.artifact); @@ -76,59 +72,61 @@ export default { <aside class="right-sidebar build-sidebar" data-offset-top="101" data-spy="affix"> <div class="sidebar-container"> <div class="blocks-container"> - <div class="block d-flex flex-nowrap align-items-center"> + <div class="block gl-display-flex gl-flex-nowrap gl-align-items-center"> <tooltip-on-truncate :title="job.name" truncate-target="child" ><h4 class="my-0 mr-2 gl-text-truncate"> {{ job.name }} </h4> </tooltip-on-truncate> - <div class="flex-grow-1 flex-shrink-0 text-right"> + <div class="gl-flex-grow-1 gl-flex-shrink-0 gl-text-right"> <job-sidebar-retry-button v-if="job.retry_path" - :class="retryButtonClass" + :category="retryButtonCategory" :href="job.retry_path" :modal-id="$options.forwardDeploymentFailureModalId" + variant="confirm" data-qa-selector="retry_button" data-testid="retry-button" /> - <gl-link + <gl-button v-if="job.cancel_path" :href="job.cancel_path" - class="btn gl-button btn-default gl-text-decoration-none!" data-method="post" data-testid="cancel-button" rel="nofollow" >{{ $options.i18n.cancel }} - </gl-link> + </gl-button> </div> <gl-button :aria-label="$options.i18n.toggleSidebar" category="tertiary" - class="gl-md-display-none gl-ml-2 js-sidebar-build-toggle" + class="gl-md-display-none gl-ml-2" icon="chevron-double-lg-right" @click="toggleSidebar" /> </div> <div v-if="job.terminal_path || job.new_issue_path" class="block retry-link"> - <gl-link + <gl-button v-if="job.new_issue_path" + category="secondary" + variant="confirm" :href="job.new_issue_path" - class="btn gl-button btn-success-secondary float-left mr-2 gl-text-decoration-none!" + class="float-left gl-mr-2" data-testid="job-new-issue" >{{ $options.i18n.newIssue }} - </gl-link> - <gl-link + </gl-button> + <gl-button v-if="job.terminal_path" :href="job.terminal_path" - class="btn btn-primary btn-inverted visible-md-block visible-lg-block float-left" + class="gl-md-display-block gl-lg-display-block float-left" target="_blank" data-testid="terminal-link" > {{ $options.i18n.debug }} <gl-icon :size="14" name="external-link" /> - </gl-link> + </gl-button> </div> <job-sidebar-details-container /> <artifacts-block v-if="hasArtifact" :artifact="job.artifact" :help-url="artifactHelpUrl" /> diff --git a/app/views/import/shared/_new_project_form.html.haml b/app/views/import/shared/_new_project_form.html.haml index b053d14a851..bfc4e65e23d 100644 --- a/app/views/import/shared/_new_project_form.html.haml +++ b/app/views/import/shared/_new_project_form.html.haml @@ -1,7 +1,7 @@ .row .form-group.project-name.col-sm-12 = label_tag :name, _('Project name'), class: 'label-bold' - = text_field_tag :name, @name, placeholder: "My awesome project", class: "js-project-name form-control input-lg", autofocus: true + = text_field_tag :name, @name, placeholder: "My awesome project", class: "js-project-name form-control input-lg", autofocus: true, required: true, aria: { required: true } .form-group.col-12.col-sm-6 = label_tag :namespace_id, _('Project URL'), class: 'label-bold' .form-group @@ -18,4 +18,4 @@ = hidden_field_tag :namespace_id, current_user.namespace_id .form-group.col-12.col-sm-6.project-path = label_tag :path, _('Project slug'), class: 'label-bold' - = text_field_tag :path, @path, placeholder: "my-awesome-project", class: "js-path-name form-control", required: true + = text_field_tag :path, @path, placeholder: "my-awesome-project", class: "js-path-name form-control", required: true, aria: { required: true } diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml index 41992ee5ea9..f6b635173a5 100644 --- a/app/views/projects/_new_project_fields.html.haml +++ b/app/views/projects/_new_project_fields.html.haml @@ -8,7 +8,7 @@ .form-group.project-name.col-sm-12 = f.label :name, class: 'label-bold' do %span= _("Project name") - = f.text_field :name, placeholder: "My awesome project", class: "form-control input-lg", autofocus: true, data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_name", track_value: "" } + = f.text_field :name, placeholder: "My awesome project", class: "form-control input-lg", autofocus: true, data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_name", track_value: "" }, required: true, aria: { required: true } .form-group.project-path.col-sm-6 = f.label :namespace_id, class: 'label-bold' do %span= s_("Project URL") @@ -33,7 +33,7 @@ .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", required: true + = f.text_field :path, placeholder: "my-awesome-project", class: "form-control", required: true, aria: { required: true } - if current_user.can_create_group? .form-text.text-muted - link_start_group_path = '<a href="%{path}">' % { path: new_group_path } diff --git a/app/views/projects/merge_requests/_nav_btns.html.haml b/app/views/projects/merge_requests/_nav_btns.html.haml index 473490c6c35..ca0abd5910c 100644 --- a/app/views/projects/merge_requests/_nav_btns.html.haml +++ b/app/views/projects/merge_requests/_nav_btns.html.haml @@ -2,9 +2,9 @@ = render 'shared/issuable/csv_export/button', issuable_type: 'merge-requests' - if @can_bulk_update - = button_tag "Edit merge requests", class: "gl-button btn gl-mr-3 js-bulk-update-toggle" + = button_tag "Edit merge requests", class: "gl-button btn btn-default gl-mr-3 js-bulk-update-toggle" - if merge_project - = link_to new_merge_request_path, class: "gl-button btn btn-success", title: "New merge request" do + = link_to new_merge_request_path, class: "gl-button btn btn-confirm", title: "New merge request" do New merge request = render 'shared/issuable/csv_export/modal', issuable_type: 'merge_requests' diff --git a/app/views/shared/access_tokens/_form.html.haml b/app/views/shared/access_tokens/_form.html.haml index 4063674b2fc..9709ad8428e 100644 --- a/app/views/shared/access_tokens/_form.html.haml +++ b/app/views/shared/access_tokens/_form.html.haml @@ -34,4 +34,4 @@ %input{ type: 'hidden', name: 'temporary-name', id: 'temporary-id' } .gl-mt-3 - = f.submit _('Create %{type}') % { type: type }, class: 'gl-button btn btn-success', data: { qa_selector: 'create_token_button' } + = f.submit _('Create %{type}') % { type: type }, class: 'gl-button btn btn-confirm', data: { qa_selector: 'create_token_button' } diff --git a/app/views/shared/gitpod/_enable_gitpod_modal.html.haml b/app/views/shared/gitpod/_enable_gitpod_modal.html.haml index a6bd1d10e43..dacfbf63db8 100644 --- a/app/views/shared/gitpod/_enable_gitpod_modal.html.haml +++ b/app/views/shared/gitpod/_enable_gitpod_modal.html.haml @@ -8,5 +8,5 @@ .modal-body.p-3 %p= (_("To use Gitpod you must first enable the feature in the integrations section of your %{user_prefs}.") % { user_prefs: link_to(_('user preferences'), profile_preferences_path(anchor: 'gitpod')) }).html_safe .modal-footer - = link_to _('Cancel'), '#', class: "btn btn-cancel", "data-dismiss" => "modal" - = link_to _('Enable Gitpod'), profile_path(user: { gitpod_enabled: true}), class: 'btn btn-success', method: :put + = link_to _('Cancel'), '#', class: "gl-button btn btn-default btn-cancel", "data-dismiss" => "modal" + = link_to _('Enable Gitpod'), profile_path(user: { gitpod_enabled: true}), class: 'gl-button btn btn-confirm', method: :put diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index 3896946b91f..24005188d0b 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -72,9 +72,9 @@ %span.gl-mr-3 - if issuable.new_record? - = form.submit "Submit #{issuable.class.model_name.human.downcase}", class: 'gl-button btn btn-success qa-issuable-create-button' + = form.submit "Submit #{issuable.class.model_name.human.downcase}", class: 'gl-button btn btn-confirm qa-issuable-create-button' - else - = form.submit 'Save changes', class: 'gl-button btn btn-success' + = form.submit 'Save changes', class: 'gl-button btn btn-confirm' - if !issuable.persisted? && !issuable.project.empty_repo? && (guide_url = issuable.project.present.contribution_guide_path) .inline.gl-mt-3 diff --git a/app/views/shared/issuable/_label_page_create.html.haml b/app/views/shared/issuable/_label_page_create.html.haml index 005b76180fd..cf7e6cf8365 100644 --- a/app/views/shared/issuable/_label_page_create.html.haml +++ b/app/views/shared/issuable/_label_page_create.html.haml @@ -19,7 +19,7 @@ %input.js-add-list{ type: "checkbox", name: "add_list", checked: add_list } %span= _('Add list') .clearfix - %button.gl-button.btn.btn-success.float-left.js-new-label-btn{ type: "button" } + %button.gl-button.btn.btn-confirm.float-left.js-new-label-btn{ type: "button" } = _('Create') %button.gl-button.btn.btn-default.float-right.js-cancel-label-btn{ type: "button" } = _('Cancel') diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index f26f4adc19a..076ccd93360 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -163,7 +163,7 @@ = dropdown_content = dropdown_loading = dropdown_footer add_content_class: true do - %button.gl-button.btn.btn-success.sidebar-move-issue-confirmation-button.js-move-issue-confirmation-button{ type: 'button', disabled: true } + %button.gl-button.btn.btn-confirm.sidebar-move-issue-confirmation-button.js-move-issue-confirmation-button{ type: 'button', disabled: true } = _('Move') = loading_icon(css_class: 'gl-vertical-align-text-bottom sidebar-move-issue-confirmation-loading-icon') diff --git a/app/views/shared/issuable/csv_export/_modal.html.haml b/app/views/shared/issuable/csv_export/_modal.html.haml index 17990de8522..59d27ad7019 100644 --- a/app/views/shared/issuable/csv_export/_modal.html.haml +++ b/app/views/shared/issuable/csv_export/_modal.html.haml @@ -22,6 +22,6 @@ = html_escape(_('The CSV export will be created in the background. Once finished, it will be sent to %{strong_open}%{email}%{strong_close} in an attachment.')) % { email: @current_user.notification_email, strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe } .modal-footer - if issuable_type.eql?('merge_requests') - = link_to _("Export merge requests"), export_csv_project_merge_requests_path(@project, request.query_parameters), method: :post, class: 'btn gl-button btn-success', data: { track_label: "export_merge_requests_csv", track_event: "click_button", track_value: "" } + = link_to _("Export merge requests"), export_csv_project_merge_requests_path(@project, request.query_parameters), method: :post, class: 'btn gl-button btn-confirm', data: { track_label: "export_merge_requests_csv", track_event: "click_button", track_value: "" } - else - = link_to _('Export issues'), export_csv_project_issues_path(@project, request.query_parameters), method: :post, class: 'btn gl-button btn-success', data: { track_label: "export_issues_csv", track_event: "click_button", track_value: "", qa_selector: "export_issues_button" } + = link_to _('Export issues'), export_csv_project_issues_path(@project, request.query_parameters), method: :post, class: 'btn gl-button btn-confirm', data: { track_label: "export_issues_csv", track_event: "click_button", track_value: "", qa_selector: "export_issues_button" } diff --git a/changelogs/unreleased/294436-create-project-required-fields.yml b/changelogs/unreleased/294436-create-project-required-fields.yml new file mode 100644 index 00000000000..96f0ca574d9 --- /dev/null +++ b/changelogs/unreleased/294436-create-project-required-fields.yml @@ -0,0 +1,5 @@ +--- +title: Improve a11y of the new project form by marking required fields +merge_request: 55682 +author: +type: performance diff --git a/changelogs/unreleased/322082-fix-invite-member-modal-dropdown-styling.yml b/changelogs/unreleased/322082-fix-invite-member-modal-dropdown-styling.yml new file mode 100644 index 00000000000..9767730bd45 --- /dev/null +++ b/changelogs/unreleased/322082-fix-invite-member-modal-dropdown-styling.yml @@ -0,0 +1,5 @@ +--- +title: Fix invite member modal dropdown checkbox styling +merge_request: 55832 +author: Kev @KevSlashNull +type: fixed diff --git a/changelogs/unreleased/btn-confirm-shared-access-tokens.yml b/changelogs/unreleased/btn-confirm-shared-access-tokens.yml new file mode 100644 index 00000000000..e1e72fc884e --- /dev/null +++ b/changelogs/unreleased/btn-confirm-shared-access-tokens.yml @@ -0,0 +1,5 @@ +--- +title: Move from btn-success to btn-confirm in shared/access_token directory +merge_request: 55298 +author: Yogi (@yo) +type: changed diff --git a/changelogs/unreleased/btn-confirm-shared-gitpod.yml b/changelogs/unreleased/btn-confirm-shared-gitpod.yml new file mode 100644 index 00000000000..0cce62a474d --- /dev/null +++ b/changelogs/unreleased/btn-confirm-shared-gitpod.yml @@ -0,0 +1,5 @@ +--- +title: Move from btn-success to btn-confirm in shared/gitpod directory +merge_request: 55301 +author: Yogi (@yo) +type: changed diff --git a/changelogs/unreleased/update-mr-page-buttons.yml b/changelogs/unreleased/update-mr-page-buttons.yml new file mode 100644 index 00000000000..9cd872fc649 --- /dev/null +++ b/changelogs/unreleased/update-mr-page-buttons.yml @@ -0,0 +1,5 @@ +--- +title: Update button to btn-confirm on merge requests page +merge_request: 55218 +author: +type: changed diff --git a/changelogs/unreleased/yo-btn-confirm-shared-issuable.yml b/changelogs/unreleased/yo-btn-confirm-shared-issuable.yml new file mode 100644 index 00000000000..bcaacc9443c --- /dev/null +++ b/changelogs/unreleased/yo-btn-confirm-shared-issuable.yml @@ -0,0 +1,5 @@ +--- +title: Move from btn-success to btn-confirm in shared/issuable directory +merge_request: 55303 +author: Yogi (@yo) +type: changed diff --git a/config/initializers_before_autoloader/000_inflections.rb b/config/initializers_before_autoloader/000_inflections.rb index 9eb1ebe77bf..308b38c1ba2 100644 --- a/config/initializers_before_autoloader/000_inflections.rb +++ b/config/initializers_before_autoloader/000_inflections.rb @@ -20,6 +20,7 @@ ActiveSupport::Inflector.inflections do |inflect| event_log file_registry group_view + group_wiki_repository_registry job_artifact_registry lfs_object_registry package_file_registry diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md index 0051f2d238f..0f3bebcec87 100644 --- a/doc/administration/monitoring/prometheus/gitlab_metrics.md +++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md @@ -217,6 +217,12 @@ configuration option in `gitlab.yml`. These metrics are served from the | `geo_snippet_repositories_synced` | Gauge | 13.4 | Number of syncable snippets synced on secondary | `url` | | `geo_snippet_repositories_failed` | Gauge | 13.4 | Number of syncable snippets failed on secondary | `url` | | `geo_snippet_repositories_registry` | Gauge | 13.4 | Number of syncable snippets in the registry | `url` | +| `geo_group_wiki_repositories` | Gauge | 13.10 | Number of group wikis on primary | `url` | +| `geo_group_wiki_repositories_checksummed` | Gauge | 13.10 | Number of group wikis checksummed on primary | `url` | +| `geo_group_wiki_repositories_checksum_failed` | Gauge | 13.10 | Number of group wikis failed to calculate the checksum on primary | `url` | +| `geo_group_wiki_repositories_synced` | Gauge | 13.10 | Number of syncable group wikis synced on secondary | `url` | +| `geo_group_wiki_repositories_failed` | Gauge | 13.10 | Number of syncable group wikis failed on secondary | `url` | +| `geo_group_wiki_repositories_registry` | Gauge | 13.10 | Number of syncable group wikis in the registry | `url` | | `limited_capacity_worker_running_jobs` | Gauge | 13.5 | Number of running jobs | `worker` | | `limited_capacity_worker_max_running_jobs` | Gauge | 13.5 | Maximum number of running jobs | `worker` | | `limited_capacity_worker_remaining_work_count` | Gauge | 13.5 | Number of jobs waiting to be enqueued | `worker` | diff --git a/doc/api/geo_nodes.md b/doc/api/geo_nodes.md index a2417af5285..0401680b016 100644 --- a/doc/api/geo_nodes.md +++ b/doc/api/geo_nodes.md @@ -383,7 +383,12 @@ Example response: "snippet_repositories_checksum_failed_count": 0, "snippet_repositories_registry_count": 10, "snippet_repositories_synced_count": 6, - "snippet_repositories_failed_count": 3 + "snippet_repositories_failed_count": 3, + "group_wiki_repositories_checksummed_count": 10, + "group_wiki_repositories_checksum_failed_count": 0, + "group_wiki_repositories_registry_count": 10, + "group_wiki_repositories_synced_count": 6, + "group_wiki_repositories_failed_count": 3 }, { "geo_node_id": 2, @@ -477,7 +482,12 @@ Example response: "snippet_repositories_checksum_failed_count": 0, "snippet_repositories_registry_count": 10, "snippet_repositories_synced_count": 6, - "snippet_repositories_failed_count": 3 + "snippet_repositories_failed_count": 3, + "group_wiki_repositories_checksummed_count": 10, + "group_wiki_repositories_checksum_failed_count": 0, + "group_wiki_repositories_registry_count": 10, + "group_wiki_repositories_synced_count": 6, + "group_wiki_repositories_failed_count": 3 } ] ``` diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 5b3bc66eedc..eceff6d09c2 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -2139,6 +2139,7 @@ Represents an external issue. | `containerRepositoriesMaxCapacity` | Int | The maximum concurrency of container repository sync for this secondary node. | | `enabled` | Boolean | Indicates whether this Geo node is enabled. | | `filesMaxCapacity` | Int | The maximum concurrency of LFS/attachment backfill for this secondary node. | +| `groupWikiRepositoryRegistries` | GroupWikiRepositoryRegistryConnection | Find group wiki repository registries on this Geo node. Available only when feature flag `geo_group_wiki_repository_replication` is enabled. | | `id` | ID! | ID of this GeoNode. | | `internalUrl` | String | The URL defined on the primary node that secondary nodes should use to contact it. | | `mergeRequestDiffRegistries` | MergeRequestDiffRegistryConnection | Find merge request diff registries on this Geo node. | @@ -2282,6 +2283,21 @@ Contains statistics about a group. | ----- | ---- | ----------- | | `releaseStats` | GroupReleaseStats | Statistics related to releases within the group. | +### `GroupWikiRepositoryRegistry` + +Represents the Geo sync and verification state of a group wiki repository. + +| Field | Type | Description | +| ----- | ---- | ----------- | +| `createdAt` | Time | Timestamp when the GroupWikiRepositoryRegistry was created | +| `groupWikiRepositoryId` | ID! | ID of the Group Wiki Repository. | +| `id` | ID! | ID of the GroupWikiRepositoryRegistry | +| `lastSyncFailure` | String | Error message during sync of the GroupWikiRepositoryRegistry | +| `lastSyncedAt` | Time | Timestamp of the most recent successful sync of the GroupWikiRepositoryRegistry | +| `retryAt` | Time | Timestamp after which the GroupWikiRepositoryRegistry should be resynced | +| `retryCount` | Int | Number of consecutive failed sync attempts of the GroupWikiRepositoryRegistry | +| `state` | RegistryState | Sync state of the GroupWikiRepositoryRegistry | + ### `HttpIntegrationCreatePayload` Autogenerated return type of HttpIntegrationCreate. diff --git a/doc/api/issues.md b/doc/api/issues.md index c333967b36c..23028b44169 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -67,7 +67,7 @@ GET /issues?state=opened | `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. | | `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14016) in GitLab 10.0)_ | | `non_archived` | boolean | no | Return issues only from non-archived projects. If `false`, the response returns issues from both archived and non-archived projects. Default is `true`. _(Introduced in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/197170))_ | -| `not` | Hash | no | Return issues that do not match the parameters supplied. Accepts: `labels`, `milestone`, `author_id`, `author_username`, `assignee_id`, `assignee_username`, `my_reaction_emoji` | +| `not` | Hash | no | Return issues that do not match the parameters supplied. Accepts: `assignee_id`, `assignee_username`, `author_id`, `author_username`, `iids`, `iteration_id`, `iteration_title`, `labels`, `milestone`, and `weight`. | | `order_by` | string | no | Return issues ordered by `created_at`, `updated_at`, `priority`, `due_date`, `relative_position`, `label_priority`, `milestone_due`, `popularity`, `weight` fields. Default is `created_at` | | `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13004) in GitLab 9.5. [Changed to snake_case](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18935) in GitLab 11.0)_ | | `search` | string | no | Search issues against their `title` and `description` | diff --git a/doc/development/usage_ping/dictionary.md b/doc/development/usage_ping/dictionary.md index 852ddd8c3c4..43707e49ab4 100644 --- a/doc/development/usage_ping/dictionary.md +++ b/doc/development/usage_ping/dictionary.md @@ -6368,6 +6368,30 @@ Status: `data_available` Tiers: `free` +### `g_project_management_epic_created_monthly` + +Count of MAU creating epics + +[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_28d/20210305144719_g_product_planning_epic_created_monthly.yml) + +Group: `group::product planning` + +Status: `implemented` + +Tiers: `premium`, `ultimate` + +### `g_project_management_epic_created_weekly` + +Count of WAU creating epics + +[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_7d/20210305145820_g_product_planning_epic_created_weekly.yml) + +Group: `group::product planning` + +Status: `implemented` + +Tiers: `premium`, `ultimate` + ### `geo_enabled` Is Geo enabled? diff --git a/doc/integration/omniauth.md b/doc/integration/omniauth.md index 9fd2e7a69e9..e3b18c0b82b 100644 --- a/doc/integration/omniauth.md +++ b/doc/integration/omniauth.md @@ -239,7 +239,6 @@ from the OmniAuth provider's documentation. If you have successfully set up a provider that is not shipped with GitLab itself, please let us know. -Share your experience [in the public Wiki](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Custom-omniauth-provider-configurations). You can help others by reporting successful configurations and probably share a few insights or provide warnings for common errors or pitfalls. diff --git a/lib/api/helpers/issues_helpers.rb b/lib/api/helpers/issues_helpers.rb index b303f1f845d..2b1ed479692 100644 --- a/lib/api/helpers/issues_helpers.rb +++ b/lib/api/helpers/issues_helpers.rb @@ -11,10 +11,7 @@ module API params :optional_issue_params_ee do end - params :optional_issues_params_ee do - end - - params :optional_issue_not_params_ee do + params :issues_stats_params_ee do end def self.update_params_at_least_one_of diff --git a/lib/api/issues.rb b/lib/api/issues.rb index ea09174f03a..13dac1c174c 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -15,6 +15,24 @@ module API optional :labels, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'Comma-separated list of label names' optional :milestone, type: String, desc: 'Milestone title' optional :iids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The IID array of issues' + + optional :author_id, type: Integer, desc: 'Return issues which are not authored by the user with the given ID' + optional :author_username, type: String, desc: 'Return issues which are not authored by the user with the given username' + mutually_exclusive :author_id, :author_username + + optional :assignee_id, type: Integer, desc: 'Return issues which are not assigned to the user with the given ID' + optional :assignee_username, type: Array[String], check_assignees_count: true, + coerce_with: Validations::Validators::CheckAssigneesCount.coerce, + desc: 'Return issues which are not assigned to the user with the given username' + mutually_exclusive :assignee_id, :assignee_username + + use :negatable_issue_filter_params_ee + end + + params :issues_stats_params do + optional :labels, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'Comma-separated list of label names' + optional :milestone, type: String, desc: 'Milestone title' + optional :iids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The IID array of issues' optional :search, type: String, desc: 'Search issues for text present in the title, description, or any combination of these' optional :in, type: String, desc: '`title`, `description`, or a string joining them with comma' @@ -29,11 +47,6 @@ module API desc: 'Return issues which are assigned to the user with the given username' mutually_exclusive :assignee_id, :assignee_username - use :negatable_issue_filter_params_ee - end - - params :issues_stats_params do - use :negatable_issue_filter_params optional :created_after, type: DateTime, desc: 'Return issues created after the specified time' optional :created_before, type: DateTime, desc: 'Return issues created before the specified time' optional :updated_after, type: DateTime, desc: 'Return issues updated after the specified time' @@ -48,7 +61,7 @@ module API optional :my_reaction_emoji, type: String, desc: 'Return issues reacted by the authenticated user by the given emoji' optional :confidential, type: Boolean, desc: 'Filter confidential or public issues' - use :optional_issues_params_ee + use :issues_stats_params_ee end params :issues_params do diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml index 94941309ec4..7c8b7336d99 100644 --- a/lib/gitlab/usage_data_counters/known_events/common.yml +++ b/lib/gitlab/usage_data_counters/known_events/common.yml @@ -445,3 +445,13 @@ redis_slot: pipeline_authoring aggregation: weekly feature_flag: usage_data_o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile +# Epic events +# +# We are using the same slot of issue events 'project_management' for +# epic events to allow data aggregation. +# More information in: https://gitlab.com/gitlab-org/gitlab/-/issues/322405 +- name: g_project_management_epic_created + category: epics_usage + redis_slot: project_management + aggregation: daily + feature_flag: track_epics_activity diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb index aeb42cc2edb..0a2f81986be 100644 --- a/spec/features/labels_hierarchy_spec.rb +++ b/spec/features/labels_hierarchy_spec.rb @@ -160,7 +160,7 @@ RSpec.describe 'Labels Hierarchy', :js do find('a.label-item', text: parent_group_label.title).click find('a.label-item', text: project_label_1.title).click - find('.btn-success').click + find('.btn-confirm').click expect(page.find('.issue-details h2.title')).to have_content('new created issue') expect(page).to have_selector('span.gl-label-text', text: grandparent_group_label.title) diff --git a/spec/frontend/invite_members/components/invite_members_modal_spec.js b/spec/frontend/invite_members/components/invite_members_modal_spec.js index ca086549f3f..028133c54ea 100644 --- a/spec/frontend/invite_members/components/invite_members_modal_spec.js +++ b/spec/frontend/invite_members/components/invite_members_modal_spec.js @@ -10,7 +10,7 @@ const name = 'test name'; const isProject = false; const inviteeType = 'members'; const accessLevels = { Guest: 10, Reporter: 20, Developer: 30, Maintainer: 40, Owner: 50 }; -const defaultAccessLevel = '10'; +const defaultAccessLevel = 10; const helpLink = 'https://example.com'; const user1 = { id: 1, name: 'Name One', username: 'one_1', avatar_url: '' }; @@ -167,7 +167,7 @@ describe('InviteMembersModal', () => { describe('when inviting an existing user to group by user ID', () => { const postData = { user_id: '1', - access_level: '10', + access_level: defaultAccessLevel, expires_at: undefined, format: 'json', }; @@ -238,7 +238,7 @@ describe('InviteMembersModal', () => { describe('when inviting a new user by email address', () => { const postData = { - access_level: '10', + access_level: defaultAccessLevel, expires_at: undefined, email: 'email@example.com', format: 'json', @@ -287,7 +287,7 @@ describe('InviteMembersModal', () => { describe('when inviting members and non-members in same click', () => { const postData = { - access_level: '10', + access_level: defaultAccessLevel, expires_at: undefined, format: 'json', }; @@ -348,7 +348,7 @@ describe('InviteMembersModal', () => { describe('when sharing the group is successful', () => { const groupPostData = { group_id: sharedGroup.id, - group_access: '10', + group_access: defaultAccessLevel, expires_at: undefined, format: 'json', }; diff --git a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb index 8aaa7c055b6..d12dcdae955 100644 --- a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb @@ -42,7 +42,8 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s 'terraform', 'ci_templates', 'quickactions', - 'pipeline_authoring' + 'pipeline_authoring', + 'epics_usage' ) end end diff --git a/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb index bf43f7552e6..f8f6494b92e 100644 --- a/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/issue_activity_unique_counter_spec.rb @@ -9,7 +9,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git let(:time) { Time.zone.now } context 'for Issue title edit actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_TITLE_CHANGED } def track_action(params) @@ -19,7 +19,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue description edit actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_DESCRIPTION_CHANGED } def track_action(params) @@ -29,7 +29,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue assignee edit actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_ASSIGNEE_CHANGED } def track_action(params) @@ -39,7 +39,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue make confidential actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_MADE_CONFIDENTIAL } def track_action(params) @@ -49,7 +49,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue make visible actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_MADE_VISIBLE } def track_action(params) @@ -59,7 +59,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue created actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_CREATED } def track_action(params) @@ -69,7 +69,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue closed actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_CLOSED } def track_action(params) @@ -79,7 +79,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue reopened actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_REOPENED } def track_action(params) @@ -89,7 +89,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue label changed actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_LABEL_CHANGED } def track_action(params) @@ -99,7 +99,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue cross-referenced actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_CROSS_REFERENCED } def track_action(params) @@ -109,7 +109,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue moved actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_MOVED } def track_action(params) @@ -119,7 +119,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue cloned actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_CLONED } def track_action(params) @@ -129,7 +129,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue relate actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_RELATED } def track_action(params) @@ -139,7 +139,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue unrelate actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_UNRELATED } def track_action(params) @@ -149,7 +149,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue marked as duplicate actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_MARKED_AS_DUPLICATE } def track_action(params) @@ -159,7 +159,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue locked actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_LOCKED } def track_action(params) @@ -169,7 +169,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue unlocked actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_UNLOCKED } def track_action(params) @@ -179,7 +179,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue designs added actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_DESIGNS_ADDED } def track_action(params) @@ -189,7 +189,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue designs modified actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_DESIGNS_MODIFIED } def track_action(params) @@ -199,7 +199,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue designs removed actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_DESIGNS_REMOVED } def track_action(params) @@ -209,7 +209,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue due date changed actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_DUE_DATE_CHANGED } def track_action(params) @@ -219,7 +219,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue time estimate changed actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_TIME_ESTIMATE_CHANGED } def track_action(params) @@ -229,7 +229,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue time spent changed actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_TIME_SPENT_CHANGED } def track_action(params) @@ -239,7 +239,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue comment added actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_COMMENT_ADDED } def track_action(params) @@ -249,7 +249,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue comment edited actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_COMMENT_EDITED } def track_action(params) @@ -259,7 +259,7 @@ RSpec.describe Gitlab::UsageDataCounters::IssueActivityUniqueCounter, :clean_git end context 'for Issue comment removed actions' do - it_behaves_like 'a tracked issue edit event' do + it_behaves_like 'a daily tracked issuable event' do let(:action) { described_class::ISSUE_COMMENT_REMOVED } def track_action(params) diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index b0d7d011e43..97000856626 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -1353,7 +1353,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do let(:categories) { ::Gitlab::UsageDataCounters::HLLRedisCounter.categories } let(:ineligible_total_categories) do - %w[source_code ci_secrets_management incident_management_alerts snippets terraform] + %w[source_code ci_secrets_management incident_management_alerts snippets terraform epics_usage] end it 'has all known_events' do diff --git a/spec/support/gitlab_experiment.rb b/spec/support/gitlab_experiment.rb index 56fcb8330e8..4a5b1fe73c9 100644 --- a/spec/support/gitlab_experiment.rb +++ b/spec/support/gitlab_experiment.rb @@ -5,7 +5,7 @@ require 'gitlab/experiment/rspec' # This is a temporary fix until we have a larger discussion around the # challenges raised in https://gitlab.com/gitlab-org/gitlab/-/issues/300104 -class ApplicationExperiment < Gitlab::Experiment # rubocop:disable Gitlab/NamespacedClass +class ApplicationExperiment # rubocop:disable Gitlab/NamespacedClass def initialize(...) super(...) Feature.persist_used!(feature_flag_name) diff --git a/spec/support/shared_examples/lib/gitlab/usage_data_counters/issue_activity_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/usage_data_counters/issuable_activity_shared_examples.rb index edd9b6cdf37..aa6e64a3820 100644 --- a/spec/support/shared_examples/lib/gitlab/usage_data_counters/issue_activity_shared_examples.rb +++ b/spec/support/shared_examples/lib/gitlab/usage_data_counters/issuable_activity_shared_examples.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.shared_examples 'a tracked issue edit event' do |event| +RSpec.shared_examples 'a daily tracked issuable event' do before do stub_application_setting(usage_ping_enabled: true) end @@ -25,3 +25,13 @@ RSpec.shared_examples 'a tracked issue edit event' do |event| expect(track_action(author: nil)).to be_nil end end + +RSpec.shared_examples 'does not track when feature flag is disabled' do |feature_flag| + context "when feature flag #{feature_flag} is disabled" do + it 'does not track action' do + stub_feature_flags(feature_flag => false) + + expect(track_action(author: user1)).to be_nil + end + end +end |