Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-01-08 21:10:18 +00:00
parent fdeb53bebf
commit 5b5ff31460
29 changed files with 576 additions and 385 deletions

View File

@ -15,7 +15,7 @@ include:
gitlab_auth_token_variable_name: "PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE"
allure_job_name: "${QA_RUN_TYPE}"
- project: gitlab-org/quality/pipeline-common
ref: 8.3.2
ref: 8.4.0
file:
- /ci/base.gitlab-ci.yml
- /ci/knapsack-report.yml

View File

@ -393,8 +393,8 @@
{"name":"net-smtp","version":"0.3.3","platform":"ruby","checksum":"3d51dcaa981b74aff2d89cbe89de4503bc2d682365ea5176366e950a0d68d5b0"},
{"name":"net-ssh","version":"7.2.0","platform":"ruby","checksum":"2a28f177173d1f6bef77471fa927c73959cda36cd03772e117f2fec48f34d2cb"},
{"name":"netrc","version":"0.11.0","platform":"ruby","checksum":"de1ce33da8c99ab1d97871726cba75151113f117146becbe45aa85cb3dabee3f"},
{"name":"nio4r","version":"2.5.8","platform":"java","checksum":"b2b1800f6bf7ce4b797ca8b639ad278a99c9c904fb087a91d944f38e4bd71401"},
{"name":"nio4r","version":"2.5.8","platform":"ruby","checksum":"3becb4ad95ab8ac0a9bd2e1b16466869402be62848082bf6329ae9091f276676"},
{"name":"nio4r","version":"2.7.0","platform":"java","checksum":"3f2e515e928ceeef7668e1f64fc3bfef1417a5ec0908d8e69f2c6d486284e04d"},
{"name":"nio4r","version":"2.7.0","platform":"ruby","checksum":"9586a685eca8246d6406e712a525e705d15bb88f709d78fc3f141e864df97276"},
{"name":"no_proxy_fix","version":"0.1.2","platform":"ruby","checksum":"4e9b4c31bb146de7fcf347dc1087bb13ac2039b56d50aa019e61036256abcd00"},
{"name":"nokogiri","version":"1.16.0","platform":"aarch64-linux","checksum":"8cd981dfd4bea4f519ceebb885cf3b422b71c059d841c039d327e73b19247f53"},
{"name":"nokogiri","version":"1.16.0","platform":"arm-linux","checksum":"c68d861155c40777eee3eb4efbb375d665c8c889cebd5cd1ba32f30a8aac6c21"},

View File

@ -1106,7 +1106,7 @@ GEM
net-protocol
net-ssh (7.2.0)
netrc (0.11.0)
nio4r (2.5.8)
nio4r (2.7.0)
no_proxy_fix (0.1.2)
nokogiri (1.16.0)
mini_portile2 (~> 2.8.2)

View File

@ -0,0 +1,67 @@
<script>
import { GlBadge, GlTab, GlTabs, GlLoadingIcon } from '@gitlab/ui';
import { s__ } from '~/locale';
import { SCOPE } from '../../constants';
export default {
components: {
GlBadge,
GlTab,
GlTabs,
GlLoadingIcon,
},
props: {
isLoading: {
type: Boolean,
required: true,
},
resourceCounts: {
type: Object,
required: true,
},
},
computed: {
tabs() {
return [
{
text: s__('CiCatalog|All'),
scope: SCOPE.all,
testId: 'resources-all-tab',
count: this.resourceCounts.all,
},
{
text: s__('CiCatalog|Your resources'),
scope: SCOPE.namespaces,
testId: 'resources-your-tab',
count: this.resourceCounts.namespaces,
},
];
},
showLoadingIcon() {
return this.isLoading;
},
},
};
</script>
<template>
<div class="gl-display-flex align-items-lg-center">
<gl-tabs content-class="gl-py-0" class="gl-w-full">
<gl-tab
v-for="tab in tabs"
:key="tab.text"
:data-testid="tab.testId"
@click="$emit('setScope', tab.scope)"
>
<template #title>
<span>{{ tab.text }}</span>
<gl-loading-icon v-if="showLoadingIcon" class="gl-ml-3" />
<gl-badge v-else size="sm" class="gl-tab-counter-badge">
{{ tab.count }}
</gl-badge>
</template>
</gl-tab>
</gl-tabs>
</div>
</template>

View File

@ -3,6 +3,7 @@ import { createAlert } from '~/alert';
import { s__ } from '~/locale';
import { ciCatalogResourcesItemsCount } from '~/ci/catalog/graphql/settings';
import CatalogSearch from '../list/catalog_search.vue';
import CatalogTabs from '../list/catalog_tabs.vue';
import CiResourcesList from '../list/ci_resources_list.vue';
import CatalogListSkeletonLoader from '../list/catalog_list_skeleton_loader.vue';
import CatalogHeader from '../list/catalog_header.vue';
@ -10,29 +11,60 @@ import EmptyState from '../list/empty_state.vue';
import getCatalogResources from '../../graphql/queries/get_ci_catalog_resources.query.graphql';
import getCurrentPage from '../../graphql/queries/client/get_current_page.query.graphql';
import updateCurrentPageMutation from '../../graphql/mutations/client/update_current_page.mutation.graphql';
import getCatalogResourcesCount from '../../graphql/queries/get_ci_catalog_resources_count.query.graphql';
import { DEFAULT_SORT_VALUE, SCOPE } from '../../constants';
export default {
i18n: {
fetchError: s__('CiCatalog|There was an error fetching CI/CD Catalog resources.'),
countFetchError: s__('CiCatalog|There was an error fetching the CI/CD Catalog resource count.'),
},
components: {
CatalogHeader,
CatalogListSkeletonLoader,
CatalogSearch,
CatalogTabs,
CiResourcesList,
EmptyState,
},
data() {
return {
catalogResources: [],
catalogResourcesCount: { all: 0, namespaces: 0 },
currentPage: 1,
pageInfo: {},
searchTerm: '',
totalCount: 0,
scope: SCOPE.all,
searchTerm: null,
sortValue: DEFAULT_SORT_VALUE,
};
},
apollo: {
catalogResourcesCount: {
query: getCatalogResourcesCount,
variables() {
return {
searchTerm: this.searchTerm,
};
},
update({ namespaces, all }) {
return {
namespaces: namespaces.count,
all: all.count,
};
},
error(e) {
createAlert({
message: e.message || this.$options.i18n.countFetchError,
});
},
},
catalogResources: {
query: getCatalogResources,
variables() {
return {
scope: this.scope,
searchTerm: this.searchTerm,
sortValue: this.sortValue,
first: ciCatalogResourcesItemsCount,
};
},
@ -42,10 +74,9 @@ export default {
result({ data }) {
const { pageInfo } = data?.ciCatalogResources || {};
this.pageInfo = pageInfo;
this.totalCount = data?.ciCatalogResources?.count || 0;
},
error(e) {
createAlert({ message: e.message || this.$options.i18n.fetchError, variant: 'danger' });
createAlert({ message: e.message || this.$options.i18n.fetchError });
},
},
currentPage: {
@ -62,11 +93,14 @@ export default {
isLoading() {
return this.$apollo.queries.catalogResources.loading;
},
isSearching() {
return this.searchTerm?.length > 0;
isLoadingCounts() {
return this.$apollo.queries.catalogResourcesCount.loading;
},
showEmptyState() {
return !this.hasResources && !this.isSearching;
namespacesCount() {
return this.catalogResourcesCount.namespaces;
},
currentTabTotalCount() {
return this.catalogResourcesCount[this.scope.toLowerCase()];
},
},
methods: {
@ -103,6 +137,11 @@ export default {
createAlert({ message: e?.message || this.$options.i18n.fetchError, variant: 'danger' });
}
},
handleSetScope(scope) {
if (this.scope === scope) return;
this.scope = scope;
},
updatePageCount(pageNumber) {
this.$apollo.mutate({
mutation: updateCurrentPageMutation,
@ -120,30 +159,28 @@ export default {
onUpdateSearchTerm(searchTerm) {
this.searchTerm = !searchTerm.length ? null : searchTerm;
this.resetPageCount();
this.$apollo.queries.catalogResources.refetch({
searchTerm: this.searchTerm,
});
},
onUpdateSorting(sortValue) {
this.sortValue = sortValue;
this.resetPageCount();
this.$apollo.queries.catalogResources.refetch({
sortValue,
});
},
resetPageCount() {
this.updatePageCount(1);
},
},
i18n: {
fetchError: s__('CiCatalog|There was an error fetching CI/CD Catalog resources.'),
},
};
</script>
<template>
<div>
<catalog-header />
<catalog-tabs
:is-loading="isLoadingCounts"
:resource-counts="catalogResourcesCount"
class="gl-mb-3"
@setScope="handleSetScope"
/>
<catalog-search
class="gl-py-4 gl-border-b-1 gl-border-gray-100 gl-border-b-solid gl-border-t-1 gl-border-t-solid"
class="gl-py-2"
@update-search-term="onUpdateSearchTerm"
@update-sorting="onUpdateSorting"
/>
@ -156,7 +193,7 @@ export default {
:prev-text="__('Prev')"
:next-text="__('Next')"
:resources="catalogResources"
:total-count="totalCount"
:total-count="currentTabTotalCount"
@onPrevPage="handlePrevPage"
@onNextPage="handleNextPage"
/>

View File

@ -2,8 +2,14 @@ import { helpPagePath } from '~/helpers/help_page_helper';
export const CATALOG_FEEDBACK_DISMISSED_KEY = 'catalog_feedback_dismissed';
export const SCOPE = {
all: 'ALL',
namespaces: 'NAMESPACES',
};
export const SORT_OPTION_CREATED = 'CREATED';
export const SORT_ASC = 'ASC';
export const SORT_DESC = 'DESC';
export const DEFAULT_SORT_VALUE = `${SORT_OPTION_CREATED}_${SORT_DESC}`;
export const COMPONENTS_DOCS_URL = helpPagePath('ci/components/index');

View File

@ -1,6 +1,7 @@
#import "~/ci/catalog/graphql/fragments/catalog_resource.fragment.graphql"
query getCatalogResources(
$scope: CiCatalogResourceScope
$searchTerm: String
$sortValue: CiCatalogResourceSort
$after: String
@ -9,6 +10,7 @@ query getCatalogResources(
$last: Int
) {
ciCatalogResources(
scope: $scope
search: $searchTerm
sort: $sortValue
after: $after
@ -22,7 +24,6 @@ query getCatalogResources(
hasNextPage
hasPreviousPage
}
count
nodes {
...CatalogResourceFields
}

View File

@ -0,0 +1,8 @@
query getCatalogResourcesCount($searchTerm: String) {
all: ciCatalogResources(scope: ALL, search: $searchTerm) {
count
}
namespaces: ciCatalogResources(scope: NAMESPACES, search: $searchTerm) {
count
}
}

View File

@ -15,7 +15,7 @@ export const cacheConfig = {
});
},
ciCatalogResources: {
keyArgs: false,
keyArgs: ['scope', 'search', 'sort'],
},
},
},

View File

@ -1,42 +0,0 @@
<script>
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
import { n__ } from '~/locale';
export default {
directives: {
GlTooltip: GlTooltipDirective,
},
components: {
GlButton,
},
props: {
commentsCount: {
type: Number,
required: true,
},
},
computed: {
tooltipText() {
return n__('%d comment on this commit', '%d comments on this commit', this.commentsCount);
},
showCommentButton() {
return this.commentsCount > 0;
},
},
};
</script>
<template>
<span
v-if="showCommentButton"
v-gl-tooltip
class="gl-display-none gl-sm-display-inline-block"
tabindex="0"
:title="tooltipText"
data-testid="comment-button-wrapper"
>
<gl-button icon="comment" class="gl-mr-3" disabled>
{{ commentsCount }}
</gl-button>
</span>
</template>

View File

@ -1,11 +1,9 @@
import initCherryPickCommitModal from './init_cherry_pick_commit_modal';
import initCommitCommentsButton from './init_commit_comments_button';
import initCommitOptionsDropdown from './init_commit_options_dropdown';
import initRevertCommitModal from './init_revert_commit_modal';
export default () => {
initRevertCommitModal();
initCherryPickCommitModal();
initCommitCommentsButton();
initCommitOptionsDropdown();
};

View File

@ -1,18 +0,0 @@
import Vue from 'vue';
import CommitCommentsButton from './components/commit_comments_button.vue';
export default function initCommitCommentsButton() {
const el = document.querySelector('#js-commit-comments-button');
if (!el) {
return false;
}
const { commentsCount } = el.dataset;
return new Vue({
el,
render: (createElement) =>
createElement(CommitCommentsButton, { props: { commentsCount: Number(commentsCount) } }),
});
}

View File

@ -186,7 +186,6 @@ class Projects::CommitController < Projects::ApplicationController
opts[:use_extra_viewer_as_main] = false
@diffs = commit.diffs(opts)
@notes_count = commit.notes.count
@environment = ::Environments::EnvironmentsByDeploymentsFinder.new(@project, current_user, commit: @commit, find_latest: true).execute.last
end

View File

@ -18,7 +18,6 @@
= commit_committer_link(@commit, avatar: true, size: 24)
#{time_ago_with_tooltip(@commit.committed_date)}
#js-commit-comments-button{ data: { comments_count: @notes_count.to_i } }
= link_button_to _('Browse files'), project_tree_path(@project, @commit), class: 'gl-mr-3 gl-w-full gl-sm-w-auto gl-mb-3 gl-sm-mb-0'
#js-commit-options-dropdown{ data: commit_options_dropdown_data(@project, @commit) }

View File

@ -379,5 +379,12 @@
- elkjs
- :who: John T Skarbek
:why: https://gitlab.com/gitlab-com/legal-and-compliance/-/issues/1505
:versions: ["0.8.2"]
:when: 2023-04-07 09:15:33.00004000 Z
:versions:
- 0.8.2
:when: 2023-04-07 09:15:33.000040000 Z
- - :permit
- MIT AND (BSD-2-Clause OR GPL-2.0-or-later)
- :who: Stan Hu
:why: Used by nio4r gem. MIT license.
:versions: []
:when: 2024-01-08 09:05:34.528980000 Z

View File

@ -50,7 +50,8 @@ A release contains the following types of assets:
### Source code
GitLab automatically generates `zip`, `tar.gz`, `tar.bz2`, and `tar`
archived source code from the given Git tag. These are read-only assets.
archived source code from the given Git tag. These assets are read-only,
and [can be downloaded](../repository/index.md#download-the-code-in-a-repository).
### Links

View File

@ -126,11 +126,10 @@ To do this:
## Download the code in a repository
> Support for [including Git LFS blobs](../../../topics/git/lfs#lfs-objects-in-project-archives) was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15079) in GitLab 13.5.
You can download the source code that's stored in a repository.
1. Above the file list, select the download icon (**{download}**).
1. On the left sidebar, select **Search or go to** and find your project.
1. Above the file list, select **Code**.
1. From the options, select the files you want to download.
- **Source code:**

View File

@ -215,3 +215,13 @@ Project.where(mirror: true).each do |project|
project.save
end
```
## `The requested URL returned error: 301`
When mirroring using the `http://` or `https://` protocols, be sure to specify the exact URL to the repository: `https://gitlab.example.com/group/project.git`
HTTP redirects are not followed and omitting `.git` can result in a 301 error:
```plaintext
13:fetch remote: "fatal: unable to access 'https://gitlab.com/group/project': The requested URL returned error: 301\n": exit status 128.
```

View File

@ -48,7 +48,7 @@ module Sidebars
end
def container_registry_menu_item
if !::Gitlab.config.registry.enabled || !can?(context.current_user, :read_container_image, context.project)
if container_registry_unavailable?
return ::Sidebars::NilMenuItem.new(item_id: :container_registry)
end
@ -122,7 +122,14 @@ module Sidebars
!::Gitlab.config.packages.enabled ||
!can?(context.current_user, :read_package, context.project&.packages_policy_subject)
end
def container_registry_unavailable?
!::Gitlab.config.registry.enabled ||
!can?(context.current_user, :read_container_image, context.project)
end
end
end
end
end
Sidebars::Projects::Menus::PackagesRegistriesMenu.prepend_mod_with('Sidebars::Projects::Menus::PackagesRegistriesMenu')

View File

@ -197,11 +197,6 @@ msgid_plural "%d comments"
msgstr[0] ""
msgstr[1] ""
msgid "%d comment on this commit"
msgid_plural "%d comments on this commit"
msgstr[0] ""
msgstr[1] ""
msgid "%d commenter"
msgid_plural "%d commenters"
msgstr[0] ""
@ -10449,6 +10444,9 @@ msgstr ""
msgid "CiCatalogComponent|This tab displays auto-collected information about the components in the repository, but no information was found."
msgstr ""
msgid "CiCatalog|All"
msgstr ""
msgid "CiCatalog|Back to the CI/CD Catalog"
msgstr ""
@ -10530,6 +10528,9 @@ msgstr ""
msgid "CiCatalog|There was an error fetching CI/CD Catalog resources."
msgstr ""
msgid "CiCatalog|There was an error fetching the CI/CD Catalog resource count."
msgstr ""
msgid "CiCatalog|This project is no longer a CI/CD Catalog resource."
msgstr ""
@ -10548,6 +10549,9 @@ msgstr ""
msgid "CiCatalog|We want to help you create and manage pipeline component repositories, while also making it easier to reuse pipeline configurations. Let us know how we're doing!"
msgstr ""
msgid "CiCatalog|Your resources"
msgstr ""
msgid "CiCdAnalytics|Date range: %{range}"
msgstr ""
@ -22981,6 +22985,9 @@ msgstr ""
msgid "Go to your snippets"
msgstr ""
msgid "Google Artifact Registry"
msgstr ""
msgid "Google Cloud"
msgstr ""

View File

@ -74,41 +74,41 @@
"@snowplow/browser-plugin-timezone": "^3.9.0",
"@snowplow/browser-tracker": "^3.9.0",
"@sourcegraph/code-host-integration": "0.0.95",
"@tiptap/core": "^2.1.13",
"@tiptap/extension-blockquote": "^2.1.13",
"@tiptap/extension-bold": "^2.1.13",
"@tiptap/extension-bubble-menu": "^2.1.13",
"@tiptap/extension-bullet-list": "^2.1.13",
"@tiptap/extension-code": "^2.1.13",
"@tiptap/extension-code-block": "^2.1.13",
"@tiptap/extension-code-block-lowlight": "^2.1.13",
"@tiptap/extension-document": "^2.1.13",
"@tiptap/extension-dropcursor": "^2.1.13",
"@tiptap/extension-gapcursor": "^2.1.13",
"@tiptap/extension-hard-break": "^2.1.13",
"@tiptap/extension-heading": "^2.1.13",
"@tiptap/extension-highlight": "^2.1.13",
"@tiptap/extension-history": "^2.1.13",
"@tiptap/extension-horizontal-rule": "^2.1.13",
"@tiptap/extension-image": "^2.1.13",
"@tiptap/extension-italic": "^2.1.13",
"@tiptap/extension-link": "^2.1.13",
"@tiptap/extension-list-item": "^2.1.13",
"@tiptap/extension-ordered-list": "^2.1.13",
"@tiptap/extension-paragraph": "^2.1.13",
"@tiptap/extension-strike": "^2.1.13",
"@tiptap/extension-subscript": "^2.1.13",
"@tiptap/extension-superscript": "^2.1.13",
"@tiptap/extension-table": "^2.1.13",
"@tiptap/extension-table-cell": "^2.1.13",
"@tiptap/extension-table-header": "^2.1.13",
"@tiptap/extension-table-row": "^2.1.13",
"@tiptap/extension-task-item": "^2.1.13",
"@tiptap/extension-task-list": "^2.1.13",
"@tiptap/extension-text": "^2.1.13",
"@tiptap/pm": "^2.1.13",
"@tiptap/suggestion": "^2.1.13",
"@tiptap/vue-2": "^2.1.13",
"@tiptap/core": "^2.1.14",
"@tiptap/extension-blockquote": "^2.1.14",
"@tiptap/extension-bold": "^2.1.14",
"@tiptap/extension-bubble-menu": "^2.1.14",
"@tiptap/extension-bullet-list": "^2.1.14",
"@tiptap/extension-code": "^2.1.14",
"@tiptap/extension-code-block": "^2.1.14",
"@tiptap/extension-code-block-lowlight": "^2.1.14",
"@tiptap/extension-document": "^2.1.14",
"@tiptap/extension-dropcursor": "^2.1.14",
"@tiptap/extension-gapcursor": "^2.1.14",
"@tiptap/extension-hard-break": "^2.1.14",
"@tiptap/extension-heading": "^2.1.14",
"@tiptap/extension-highlight": "^2.1.14",
"@tiptap/extension-history": "^2.1.14",
"@tiptap/extension-horizontal-rule": "^2.1.14",
"@tiptap/extension-image": "^2.1.14",
"@tiptap/extension-italic": "^2.1.14",
"@tiptap/extension-link": "^2.1.14",
"@tiptap/extension-list-item": "^2.1.14",
"@tiptap/extension-ordered-list": "^2.1.14",
"@tiptap/extension-paragraph": "^2.1.14",
"@tiptap/extension-strike": "^2.1.14",
"@tiptap/extension-subscript": "^2.1.14",
"@tiptap/extension-superscript": "^2.1.14",
"@tiptap/extension-table": "^2.1.14",
"@tiptap/extension-table-cell": "^2.1.14",
"@tiptap/extension-table-header": "^2.1.14",
"@tiptap/extension-table-row": "^2.1.14",
"@tiptap/extension-task-item": "^2.1.14",
"@tiptap/extension-task-list": "^2.1.14",
"@tiptap/extension-text": "^2.1.14",
"@tiptap/pm": "^2.1.14",
"@tiptap/suggestion": "^2.1.14",
"@tiptap/vue-2": "^2.1.14",
"@vue/apollo-components": "^4.0.0-beta.4",
"@vue/apollo-option": "^4.0.0-beta.4",
"apollo-upload-client": "15.0.0",

View File

@ -0,0 +1,71 @@
import { GlTab, GlTabs, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { trimText } from 'helpers/text_helper';
import CatalogTabs from '~/ci/catalog/components/list/catalog_tabs.vue';
import { SCOPE } from '~/ci/catalog/constants';
describe('Catalog Tabs', () => {
let wrapper;
const defaultProps = {
isLoading: false,
resourceCounts: {
all: 11,
namespaces: 4,
},
};
const findAllTab = () => wrapper.findByTestId('resources-all-tab');
const findYourResourcesTab = () => wrapper.findByTestId('resources-your-tab');
const findLoadingIcons = () => wrapper.findAllComponents(GlLoadingIcon);
const triggerTabChange = (index) => wrapper.findAllComponents(GlTab).at(index).vm.$emit('click');
const createComponent = (props = defaultProps) => {
wrapper = extendedWrapper(
shallowMount(CatalogTabs, {
propsData: {
...props,
},
stubs: { GlTabs },
}),
);
};
describe('When count queries are loading', () => {
beforeEach(() => {
createComponent({ ...defaultProps, isLoading: true });
});
it('renders loading icons', () => {
expect(findLoadingIcons()).toHaveLength(2);
});
});
describe('When both tabs have resources', () => {
beforeEach(() => {
createComponent();
});
it('renders All tab with count', () => {
expect(trimText(findAllTab().text())).toBe(`All ${defaultProps.resourceCounts.all}`);
});
it('renders your resources tab with count', () => {
expect(trimText(findYourResourcesTab().text())).toBe(
`Your resources ${defaultProps.resourceCounts.namespaces}`,
);
});
it.each`
tabIndex | expectedScope
${0} | ${SCOPE.all}
${1} | ${SCOPE.namespaces}
`('emits setScope with $expectedScope on tab change', ({ tabIndex, expectedScope }) => {
triggerTabChange(tabIndex);
expect(wrapper.emitted()).toEqual({ setScope: [[expectedScope]] });
});
});
});

View File

@ -3,20 +3,19 @@ import { GlKeysetPagination } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import CiResourcesList from '~/ci/catalog/components/list/ci_resources_list.vue';
import CiResourcesListItem from '~/ci/catalog/components/list/ci_resources_list_item.vue';
import { ciCatalogResourcesItemsCount } from '~/ci/catalog/graphql/settings';
import { catalogResponseBody, catalogSinglePageResponse } from '../../mock';
describe('CiResourcesList', () => {
let wrapper;
const createComponent = ({ props = {} } = {}) => {
const { nodes, pageInfo, count } = catalogResponseBody.data.ciCatalogResources;
const { nodes, pageInfo } = catalogResponseBody.data.ciCatalogResources;
const defaultProps = {
currentPage: 1,
resources: nodes,
pageInfo,
totalCount: count,
totalCount: 20,
};
wrapper = shallowMountExtended(CiResourcesList, {
@ -36,11 +35,11 @@ describe('CiResourcesList', () => {
const findNextBtn = () => wrapper.findByTestId('nextButton');
describe('contains only one page', () => {
const { nodes, pageInfo, count } = catalogSinglePageResponse.data.ciCatalogResources;
const { nodes, pageInfo } = catalogSinglePageResponse.data.ciCatalogResources;
beforeEach(async () => {
await createComponent({
props: { currentPage: 1, resources: nodes, pageInfo, totalCount: count },
props: { currentPage: 1, resources: nodes, pageInfo, totalCount: nodes.length },
});
});
@ -62,58 +61,56 @@ describe('CiResourcesList', () => {
});
describe.each`
hasPreviousPage | hasNextPage | pageText | expectedTotal | currentPage
${false} | ${true} | ${'1 of 3'} | ${ciCatalogResourcesItemsCount} | ${1}
${true} | ${true} | ${'2 of 3'} | ${ciCatalogResourcesItemsCount} | ${2}
${true} | ${false} | ${'3 of 3'} | ${ciCatalogResourcesItemsCount} | ${3}
`(
'when on page $pageText',
({ currentPage, expectedTotal, pageText, hasPreviousPage, hasNextPage }) => {
const { nodes, pageInfo, count } = catalogResponseBody.data.ciCatalogResources;
hasPreviousPage | hasNextPage | pageText | currentPage
${false} | ${true} | ${'1 of 3'} | ${1}
${true} | ${true} | ${'2 of 3'} | ${2}
${true} | ${false} | ${'3 of 3'} | ${3}
`('when on page $pageText', ({ currentPage, pageText, hasPreviousPage, hasNextPage }) => {
const { nodes, pageInfo } = catalogResponseBody.data.ciCatalogResources;
const count = 50; // We want 3 pages of data to test. There are 20 items per page.
const previousPageState = hasPreviousPage ? 'enabled' : 'disabled';
const nextPageState = hasNextPage ? 'enabled' : 'disabled';
const previousPageState = hasPreviousPage ? 'enabled' : 'disabled';
const nextPageState = hasNextPage ? 'enabled' : 'disabled';
beforeEach(async () => {
await createComponent({
props: {
currentPage,
resources: nodes,
pageInfo: { ...pageInfo, hasPreviousPage, hasNextPage },
totalCount: count,
},
});
beforeEach(async () => {
await createComponent({
props: {
currentPage,
resources: nodes,
pageInfo: { ...pageInfo, hasPreviousPage, hasNextPage },
totalCount: count,
},
});
});
it('shows the right number of items', () => {
expect(findResourcesListItems()).toHaveLength(expectedTotal);
});
it('shows the right number of items', () => {
expect(findResourcesListItems()).toHaveLength(20);
});
it(`shows the keyset control for previous page as ${previousPageState}`, () => {
const disableAttr = findPrevBtn().attributes('disabled');
it(`shows the keyset control for previous page as ${previousPageState}`, () => {
const disableAttr = findPrevBtn().attributes('disabled');
if (previousPageState === 'disabled') {
expect(disableAttr).toBeDefined();
} else {
expect(disableAttr).toBeUndefined();
}
});
if (previousPageState === 'disabled') {
expect(disableAttr).toBeDefined();
} else {
expect(disableAttr).toBeUndefined();
}
});
it(`shows the keyset control for next page as ${nextPageState}`, () => {
const disableAttr = findNextBtn().attributes('disabled');
it(`shows the keyset control for next page as ${nextPageState}`, () => {
const disableAttr = findNextBtn().attributes('disabled');
if (nextPageState === 'disabled') {
expect(disableAttr).toBeDefined();
} else {
expect(disableAttr).toBeUndefined();
}
});
if (nextPageState === 'disabled') {
expect(disableAttr).toBeDefined();
} else {
expect(disableAttr).toBeUndefined();
}
});
it('shows the correct count of current page', () => {
expect(findPageCount().text()).toContain(pageText);
});
},
);
it('shows the correct count of current page', () => {
expect(findPageCount().text()).toContain(pageText);
});
});
describe('when there is an error getting the page count', () => {
beforeEach(() => {

View File

@ -7,17 +7,25 @@ import createMockApollo from 'helpers/mock_apollo_helper';
import { createAlert } from '~/alert';
import CatalogHeader from '~/ci/catalog/components/list/catalog_header.vue';
import CatalogSearch from '~/ci/catalog/components/list/catalog_search.vue';
import CiResourcesList from '~/ci/catalog/components/list/ci_resources_list.vue';
import CiResourcesPage from '~/ci/catalog/components/pages/ci_resources_page.vue';
import CatalogSearch from '~/ci/catalog/components/list/catalog_search.vue';
import CatalogTabs from '~/ci/catalog/components/list/catalog_tabs.vue';
import CatalogListSkeletonLoader from '~/ci/catalog/components/list/catalog_list_skeleton_loader.vue';
import EmptyState from '~/ci/catalog/components/list/empty_state.vue';
import { cacheConfig, resolvers } from '~/ci/catalog/graphql/settings';
import { DEFAULT_SORT_VALUE, SCOPE } from '~/ci/catalog/constants';
import typeDefs from '~/ci/catalog/graphql/typedefs.graphql';
import ciResourcesPage from '~/ci/catalog/components/pages/ci_resources_page.vue';
import getCatalogResources from '~/ci/catalog/graphql/queries/get_ci_catalog_resources.query.graphql';
import getCatalogResourcesCount from '~/ci/catalog/graphql/queries/get_ci_catalog_resources_count.query.graphql';
import { emptyCatalogResponseBody, catalogResponseBody } from '../../mock';
import {
emptyCatalogResponseBody,
catalogResponseBody,
catalogResourcesCountResponseBody,
} from '../../mock';
Vue.use(VueApollo);
jest.mock('~/alert');
@ -25,14 +33,23 @@ jest.mock('~/alert');
describe('CiResourcesPage', () => {
let wrapper;
let catalogResourcesResponse;
let catalogResourcesCountResponse;
const defaultQueryVariables = { first: 20 };
const defaultQueryVariables = {
first: 20,
scope: SCOPE.all,
searchTerm: null,
sortValue: DEFAULT_SORT_VALUE,
};
const createComponent = () => {
const handlers = [[getCatalogResources, catalogResourcesResponse]];
const handlers = [
[getCatalogResources, catalogResourcesResponse],
[getCatalogResourcesCount, catalogResourcesCountResponse],
];
const mockApollo = createMockApollo(handlers, resolvers, { cacheConfig, typeDefs });
wrapper = shallowMountExtended(ciResourcesPage, {
wrapper = shallowMountExtended(CiResourcesPage, {
apolloProvider: mockApollo,
});
@ -41,12 +58,15 @@ describe('CiResourcesPage', () => {
const findCatalogHeader = () => wrapper.findComponent(CatalogHeader);
const findCatalogSearch = () => wrapper.findComponent(CatalogSearch);
const findCatalogTabs = () => wrapper.findComponent(CatalogTabs);
const findCiResourcesList = () => wrapper.findComponent(CiResourcesList);
const findLoadingState = () => wrapper.findComponent(CatalogListSkeletonLoader);
const findEmptyState = () => wrapper.findComponent(EmptyState);
beforeEach(() => {
catalogResourcesResponse = jest.fn();
catalogResourcesCountResponse = jest.fn();
catalogResourcesCountResponse.mockResolvedValue(catalogResourcesCountResponseBody);
});
describe('when initial queries are loading', () => {
@ -83,31 +103,56 @@ describe('CiResourcesPage', () => {
expect(findCatalogSearch().exists()).toBe(true);
});
it('renders the tabs', () => {
expect(findCatalogTabs().exists()).toBe(true);
});
it('does not render the list', () => {
expect(findCiResourcesList().exists()).toBe(false);
});
});
describe('and there are resources', () => {
const { nodes, pageInfo, count } = catalogResponseBody.data.ciCatalogResources;
const { nodes, pageInfo } = catalogResponseBody.data.ciCatalogResources;
beforeEach(async () => {
catalogResourcesResponse.mockResolvedValue(catalogResponseBody);
await createComponent();
});
it('renders the resources list', () => {
expect(findLoadingState().exists()).toBe(false);
expect(findEmptyState().exists()).toBe(false);
expect(findCiResourcesList().exists()).toBe(true);
});
it('renders the catalog tabs', () => {
expect(findCatalogTabs().exists()).toBe(true);
});
it('updates the scope after switching tabs', async () => {
await findCatalogTabs().vm.$emit('setScope', SCOPE.namespaces);
expect(catalogResourcesResponse).toHaveBeenCalledWith({
...defaultQueryVariables,
scope: SCOPE.namespaces,
});
await findCatalogTabs().vm.$emit('setScope', SCOPE.all);
expect(catalogResourcesResponse).toHaveBeenCalledWith({
...defaultQueryVariables,
scope: SCOPE.all,
});
});
it('passes down props to the resources list', () => {
expect(findCiResourcesList().props()).toMatchObject({
currentPage: 1,
resources: nodes,
pageInfo,
totalCount: count,
totalCount: 0,
});
});
@ -145,6 +190,7 @@ describe('CiResourcesPage', () => {
before: pageInfo.startCursor,
last: 20,
first: null,
scope: SCOPE.all,
});
}
});
@ -190,10 +236,12 @@ describe('CiResourcesPage', () => {
beforeEach(async () => {
catalogResourcesResponse.mockResolvedValue(emptyCatalogResponseBody);
await createComponent();
await findCatalogSearch().vm.$emit('update-search-term', newSearch);
});
it('renders the empty state and passes down the search query', () => {
it('renders the empty state and passes down the search query', async () => {
await findCatalogSearch().vm.$emit('update-search-term', newSearch);
await waitForPromises();
expect(findEmptyState().exists()).toBe(true);
expect(findEmptyState().props().searchTerm).toBe(newSearch);
});

View File

@ -10,12 +10,26 @@ export const emptyCatalogResponseBody = {
hasPreviousPage: false,
__typename: 'PageInfo',
},
count: 0,
nodes: [],
},
},
};
export const catalogResourcesCountResponseBody = {
data: {
ciCatalogResources: {
all: {
count: 1,
__typename: 'CiCatalogResourceConnection',
},
namespaces: {
count: 7,
__typename: 'CiCatalogResourceConnection',
},
},
},
};
export const catalogResponseBody = {
data: {
ciCatalogResources: {
@ -28,7 +42,6 @@ export const catalogResponseBody = {
hasPreviousPage: false,
__typename: 'PageInfo',
},
count: 41,
nodes: [
{
id: 'gid://gitlab/Ci::Catalog::Resource/129',
@ -248,7 +261,6 @@ export const catalogSinglePageResponse = {
hasPreviousPage: false,
__typename: 'PageInfo',
},
count: 3,
nodes: [
{
id: 'gid://gitlab/Ci::Catalog::Resource/132',

View File

@ -1,42 +0,0 @@
import { shallowMount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import CommitCommentsButton from '~/projects/commit/components/commit_comments_button.vue';
describe('CommitCommentsButton', () => {
let wrapper;
const createComponent = (props = {}) => {
wrapper = extendedWrapper(
shallowMount(CommitCommentsButton, {
propsData: {
commentsCount: 1,
...props,
},
}),
);
};
const tooltip = () => wrapper.findByTestId('comment-button-wrapper');
describe('Comment Button', () => {
it('has proper tooltip and button attributes for 1 comment', () => {
createComponent();
expect(tooltip().attributes('title')).toBe('1 comment on this commit');
expect(tooltip().text()).toBe('1');
});
it('has proper tooltip and button attributes for multiple comments', () => {
createComponent({ commentsCount: 2 });
expect(tooltip().attributes('title')).toBe('2 comments on this commit');
expect(tooltip().text()).toBe('2');
});
it('does not show when there are no comments', () => {
createComponent({ commentsCount: 0 });
expect(tooltip().exists()).toBe(false);
});
});
});

View File

@ -1,12 +1,15 @@
# frozen_string_literal: true
module DnsHelpers
include ViteHelper
def block_dns!
stub_all_dns!
stub_invalid_dns!
permit_local_dns!
permit_postgresql!
permit_redis!
permit_vite!
end
def permit_dns!
@ -66,6 +69,14 @@ module DnsHelpers
end
end
def permit_vite!
# https://github.com/ElMassimo/vite_ruby/blob/7d2f558c9760802e5d763bfa40efe87607eb166a/vite_ruby/lib/vite_ruby.rb#L91
# uses Socket.tcp to connect to vite dev server - this won't necessarily be localhost
return unless vite_enabled?
allow(Addrinfo).to receive(:getaddrinfo).with(ViteRuby.instance.config.host, ViteRuby.instance.config.port, nil, :STREAM, anything, anything, any_args).and_call_original
end
def stub_resolver(stubbed_lookups = {})
resolver = instance_double('Resolv::DNS')
allow(resolver).to receive(:timeouts=)

View File

@ -76,6 +76,14 @@ module NavbarStructureHelper
)
end
def insert_google_artifact_registry_nav
insert_after_sub_nav_item(
_('Container Registry'),
within: _('Deploy'),
new_sub_nav_item_name: _('Google Artifact Registry')
)
end
def insert_dependency_proxy_nav
insert_before_sub_nav_item(
_('Kubernetes'),

292
yarn.lock
View File

@ -2208,181 +2208,181 @@
dom-accessibility-api "^0.5.1"
pretty-format "^26.4.2"
"@tiptap/core@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.1.13.tgz#e21f566e81688c826c6f26d2940886734189e193"
integrity sha512-cMC8bgTN63dj1Mv82iDeeLl6sa9kY0Pug8LSalxVEptRmyFVsVxGgu2/6Y3T+9aCYScxfS06EkA8SdzFMAwYTQ==
"@tiptap/core@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.1.14.tgz#c30d2227891554c0ad1038d84b0f0c44deebf77b"
integrity sha512-X8FWXWhxrOklNEdhDkSa4PekF3BwGjDfhq7Es95OrdJ3vZ1a5lkbCdx4jXErsX1C4TaIs7cI3tqdflTXhqjLmg==
"@tiptap/extension-blockquote@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.1.13.tgz#abf01e3a00d72434b08be7f3d7e318c7320db486"
integrity sha512-oe6wSQACmODugoP9XH3Ouffjy4BsOBWfTC+dETHNCG6ZED6ShHN3CB9Vr7EwwRgmm2WLaKAjMO1sVumwH+Z1rg==
"@tiptap/extension-blockquote@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.1.14.tgz#3c5decf6316ea1d299330f33e77d36047aa8ec54"
integrity sha512-hslTfGzlC52lq3EGaxl1V8tGFsnjGLIlYr5SGJzPYwQcr2WHU/WJZli66HB+8N2o+ox5Cp4gQRNDUd9XsfxChg==
"@tiptap/extension-bold@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.1.13.tgz#fb0c8916269be61269e4aef9d1da417daf52b7f1"
integrity sha512-6cHsQTh/rUiG4jkbJer3vk7g60I5tBwEBSGpdxmEHh83RsvevD8+n92PjA24hYYte5RNlATB011E1wu8PVhSvw==
"@tiptap/extension-bold@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.1.14.tgz#9a0d0274bd0569d5ed37720554264f2a7d3d8bac"
integrity sha512-LeIRHjc6LsZ4JVuvbrb2U18IHvaYwP4+O6lIG2riTmvuqhc1UL2dKeG8X13xfk7OttA89Vkkb/XdjzQvcT1I0Q==
"@tiptap/extension-bubble-menu@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.1.13.tgz#884cd2e4e0c9586998baac3d0a14621b177f1859"
integrity sha512-Hm7e1GX3AI6lfaUmr6WqsS9MMyXIzCkhh+VQi6K8jj4Q4s8kY4KPoAyD/c3v9pZ/dieUtm2TfqrOCkbHzsJQBg==
"@tiptap/extension-bubble-menu@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.1.14.tgz#6a23066934969fc89d2cd8b3b3932e1364712ee9"
integrity sha512-9+KsP2rCVymlSKXx7BhPF9xy7dj2/G7auu7qZ4AJzEbsLj1PMS8/pSjPUabCIN6z+9IeifOa2VKmXCnVfcpazw==
dependencies:
tippy.js "^6.3.7"
"@tiptap/extension-bullet-list@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.1.13.tgz#0a26731ebf98ddfd268884ff1712f7189be7b63c"
integrity sha512-NkWlQ5bLPUlcROj6G/d4oqAxMf3j3wfndGOPp0z8OoXJtVbVoXl/aMSlLbVgE6n8r6CS8MYxKhXNxrb7Ll2foA==
"@tiptap/extension-bullet-list@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.1.14.tgz#0e7f07c0f8f51de8378fdea49e7c9626ebb1ffcd"
integrity sha512-dbnYDGNkbtFaCQIqNsOD9cc2JewN4Ref3Qq0NrVoh+MbbX2oJN2vA8rrKmEv1GhxDjtvaj2RiH1ki5XW3P98UQ==
"@tiptap/extension-code-block-lowlight@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.1.13.tgz#91110f44d6cc8a12d95ac92aee0c848fdedefb0d"
integrity sha512-PlU0lzAEbUGqPykl7fYqlAiY7/zFRtQExsbrpi2kctSIzxC+jgMM4vEpWxLS4jZEXl7jVHvBRH6lRNINDHWmQA==
"@tiptap/extension-code-block-lowlight@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.1.14.tgz#f7b9bd0b6a2d6bbbfd2a10d2192831584e132d41"
integrity sha512-FSO8LRt2Ja8d/WQ340z1gW4AUKBECJHxw08ADV0mJpjY+6NnfOID1lqL02Gy15CjO/amccE1DqPHGlcC39WU+Q==
"@tiptap/extension-code-block@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.1.13.tgz#3e441d171d3ed821e67291dbf4cbad7e2ea29809"
integrity sha512-E3tweNExPOV+t1ODKX0MDVsS0aeHGWc1ECt+uyp6XwzsN0bdF2A5+pttQqM7sTcMnQkVACGFbn9wDeLRRcfyQg==
"@tiptap/extension-code-block@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.1.14.tgz#5220bd76d0e957e59898ef145142394dbfd58124"
integrity sha512-D+F+bGrmbXzIkZuKUaM5fhJHVoUmDyTdWCqOMOzG5t53GgMDdLQF7LTzOGC2iAVu0CtAxhUEsoIlzPBdV2FKrA==
"@tiptap/extension-code@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.1.13.tgz#27a5ca5705e59ca97390fad4d6631bf431690480"
integrity sha512-f5fLYlSgliVVa44vd7lQGvo49+peC+Z2H0Fn84TKNCH7tkNZzouoJsHYn0/enLaQ9Sq+24YPfqulfiwlxyiT8w==
"@tiptap/extension-code@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.1.14.tgz#1e62e5e138981b26675a1e2a7d6f446b99727a82"
integrity sha512-7fuDW0+nyzxTlGEdkkrGMkz5b90xAvZq7EPnta13Px7FsSy771dpbWer7xMbpWGh7VYxOG6qpWJouLLrx2FKyQ==
"@tiptap/extension-document@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.1.13.tgz#5b68fa08e8a79eebd41f1360982db2ddd28ad010"
integrity sha512-wLwiTWsVmZTGIE5duTcHRmW4ulVxNW4nmgfpk95+mPn1iKyNGtrVhGWleLhBlTj+DWXDtcfNWZgqZkZNzhkqYQ==
"@tiptap/extension-document@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.1.14.tgz#9b5234a7881f8ef222924a67ef771a2bfff8a75e"
integrity sha512-plOcTQBCysUyz8AXrkBhhAqa+ALyeGJPOku0L3lS6MCSAPM2/KRW/H4KXcrfW0G1lHKiJ4OkP8oHksxa6Id5zg==
"@tiptap/extension-dropcursor@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.1.13.tgz#2e8908f2dec9e8e997a2f216a11d3b915fe062df"
integrity sha512-NAyJi4BJxH7vl/2LNS1X0ndwFKjEtX+cRgshXCnMyh7qNpIRW6Plczapc/W1OiMncOEhZJfpZfkRSfwG01FWFg==
"@tiptap/extension-dropcursor@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.1.14.tgz#a6f2df2a36a5457a3afff3c933b5328147be8f80"
integrity sha512-ZupJ/3ukcuFK/HhWbD7vuEKt10RC1/Jbk8O+HHcAWftAghsXNAnCsKWhJhAs/MvvoBFQEkmVOdPXvQsDXbbCMw==
"@tiptap/extension-floating-menu@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.1.13.tgz#e12e6e73ee095319d4a723a9b46b8f7b1a9f4b1a"
integrity sha512-9Oz7pk1Nts2+EyY+rYfnREGbLzQ5UFazAvRhF6zAJdvyuDmAYm0Jp6s0GoTrpV0/dJEISoFaNpPdMJOb9EBNRw==
"@tiptap/extension-floating-menu@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.1.14.tgz#13f9e6cf62bfc3bec5e05e2bac0f6a1f66a909bf"
integrity sha512-o/yNaZ+ntMBCjFL95JyX6LoVb8fsrx0IsnlNtnGUVr8mpOg2JyeN2ZJpUhPo2aR7QuyfdR1XsGG4TRHJBp3fGg==
dependencies:
tippy.js "^6.3.7"
"@tiptap/extension-gapcursor@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.1.13.tgz#994a54e1d4106dfaede0acce184c48457ab34450"
integrity sha512-Cl5apsoTcyPPCgE3ThufxQxZ1wyqqh+9uxUN9VF9AbeTkid6oPZvKXwaILf6AFnkSy+SuKrb9kZD2iaezxpzXw==
"@tiptap/extension-gapcursor@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.1.14.tgz#fe36282b66f3652c5f7c2d5031b651b2db2a8898"
integrity sha512-wTT8k3msIUBIj3k28ZB8IUdI4zjnkiYGTqzNXud01hLsPuQWkPerW/LqqiyKfsGKSIJa/l8x4ZzUgJv3ciO9YQ==
"@tiptap/extension-hard-break@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.1.13.tgz#fc84d0ff7e2fe861bf421bc8000194ecc26979b0"
integrity sha512-TGkMzMQayuKg+vN4du0x1ahEItBLcCT1jdWeRsjdM8gHfzbPLdo4PQhVsvm1I0xaZmbJZelhnVsUwRZcIu1WNA==
"@tiptap/extension-hard-break@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.1.14.tgz#47eea3742a879bf7849377ffdb3549fddffa4474"
integrity sha512-Nv6JS1dmPiiWDJAcdb6nGns7vD65Gqbqxh/RQeT172G2yXu5TD8EJa0OiEhd1sMcEg7OXbHMLtkDzx57mEuZ7Q==
"@tiptap/extension-heading@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.1.13.tgz#94a6219448d97ffed0915fa1bf411074c39f4103"
integrity sha512-PEmc19QLmlVUTiHWoF0hpgNTNPNU0nlaFmMKskzO+cx5Df4xvHmv/UqoIwp7/UFbPMkfVJT1ozQU7oD1IWn9Hg==
"@tiptap/extension-heading@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.1.14.tgz#868dd4eff41480d31c0cbab04d6d14a682318259"
integrity sha512-x/AMzMANLvgbuwx4qe848WxF5W1Yq4bUjsduSu/5jonpH2sR5AFsH5VbWS8lfT34OdOI0Gs7p+k2NNuykWDPQA==
"@tiptap/extension-highlight@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-highlight/-/extension-highlight-2.1.13.tgz#d30221c178569264ab76327f87a0d81605493fcc"
integrity sha512-ZivjJma5WwPYcG0rpnynVDGis32OGdtpTwETEb+2OOjZBCBlyYQ4tcRk5gS3nzBAjLl/Qu84VVbawLhHXB6few==
"@tiptap/extension-highlight@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-highlight/-/extension-highlight-2.1.14.tgz#ce427a031561e8e89436db0dec969cc9ea1c02af"
integrity sha512-TU12/Hw5FBZuk1/j06UqNVx91Hms0XEEgtz3tOwyWrxbOe4hXILNedzrz3aNoTcLJoqOVefw+VBQLcsK0Ztw/Q==
"@tiptap/extension-history@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.1.13.tgz#50478c602143fa77bb3b45c9c9cae4ddb743e0ed"
integrity sha512-1ouitThGTBUObqw250aDwGLMNESBH5PRXIGybsCFO1bktdmWtEw7m72WY41EuX2BH8iKJpcYPerl3HfY1vmCNw==
"@tiptap/extension-history@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.1.14.tgz#06863c38511d39d309003f8cc187d38fa800dbe5"
integrity sha512-DN9QeiEv/Y3cCOHVH+/0M18btg7Gebhw7ooT0afanyHS/a5aV/IsgDnw6YRHaMfLUgDD7toOSSbjgGYWZX307w==
"@tiptap/extension-horizontal-rule@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.1.13.tgz#4884dbf912c8dabbbc69e041ff5529d6337e638e"
integrity sha512-7OgjgNqZXvBejgULNdMSma2M1nzv4bbZG+FT5XMFZmEOxR9IB1x/RzChjPdeicff2ZK2sfhMBc4Y9femF5XkUg==
"@tiptap/extension-horizontal-rule@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.1.14.tgz#23c4ffad88b8554e280344d70592bcd6702215fd"
integrity sha512-n5vNE4rTA3zfLhe0p3k38IJGtEWfvr2QIp5lQuw4/i5TcOrnpfryJwA9tLDTgAdcyvTTGJH5jAXWw9ENxBexQg==
"@tiptap/extension-image@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.1.13.tgz#835fc6759b2c1184fb54d3704c538029d523dbf6"
integrity sha512-7oVAos+BU4KR/zQsfltrd8hgIxKxyxZ19dhwb1BJI2Nt3Mnx+yFPRlRSehID6RT9dYqgW4UW5d6vh/3HQcYYYw==
"@tiptap/extension-image@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.1.14.tgz#5e5b662afd35d6a41ce9fb1fee72da8e3318e2d9"
integrity sha512-EDwbvBIpyJJDAtIlNNBDPtIIAi0GKEAOcqyB7G0tomyho6QUaO2yFtB37t7OAbM+CQiTBtO2AuJhOYr3354V4A==
"@tiptap/extension-italic@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.1.13.tgz#1e9521dea002c8d6de833d9fd928d4617623eab8"
integrity sha512-HyDJfuDn5hzwGKZiANcvgz6wcum6bEgb4wmJnfej8XanTMJatNVv63TVxCJ10dSc9KGpPVcIkg6W8/joNXIEbw==
"@tiptap/extension-italic@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.1.14.tgz#2542ee68202307ed01bd5e10b65650e99b6efa4f"
integrity sha512-K+n2ts26HNatX3FZ2pYJTFDuMypDyMP4jQ3T11cU908lUT8gHXHBcgh0OW83SX92asbWxUj8xEdDZczi7Qqbew==
"@tiptap/extension-link@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.1.13.tgz#ae4abd7c43292e3a1841488bfc7a687b2f014249"
integrity sha512-wuGMf3zRtMHhMrKm9l6Tft5M2N21Z0UP1dZ5t1IlOAvOeYV2QZ5UynwFryxGKLO0NslCBLF/4b/HAdNXbfXWUA==
"@tiptap/extension-link@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.1.14.tgz#aa850dddfaec14afe99bd3ba6695d515eecadc92"
integrity sha512-lfZIBaGGWJaX9tZIsAq5WuWk1cIQVM3takU4F5485eN8aM7Nnw/+Se8uSPZeh3rCbiNg5EeGi/eLEZv/L/TLGQ==
dependencies:
linkifyjs "^4.1.0"
"@tiptap/extension-list-item@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.1.13.tgz#3c62127df97974f3196866ec00ee397f4c9acdc4"
integrity sha512-6e8iiCWXOiJTl1XOwVW2tc0YG18h70HUtEHFCx2m5HspOGFKsFEaSS3qYxOheM9HxlmQeDt8mTtqftRjEFRxPQ==
"@tiptap/extension-list-item@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.1.14.tgz#f17c3b9cff2a710c3307c0298261c81f2a5d7cdd"
integrity sha512-MpOCf0QnbW0qxW4dB7JRMX7qGortjY8QRl1WBmUGBBN54Q712nfgmUmNJmzNYfRU91PN0afdBVibUSchB4LP3Q==
"@tiptap/extension-ordered-list@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.1.13.tgz#31f4b3a21fbcc2f605c48662e08b5253a304c8c7"
integrity sha512-UO4ZAL5Vrr1WwER5VjgmeNIWHpqy9cnIRo1En07gZ0OWTjs1eITPcu+4TCn1ZG6DhoFvAQzE5DTxxdhIotg+qw==
"@tiptap/extension-ordered-list@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.1.14.tgz#61d198f146d9c71b3809398263b4093616b2e545"
integrity sha512-XwARMGQbTbBOOvG62T4yH2g8OeoLYVaNTKRbiuhIzYekAN/elnydQahcjjE9/Y2Zq54g0nPdgh0LvsjWNWxr8Q==
"@tiptap/extension-paragraph@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.1.13.tgz#30f8ae3f8833c606b339f3554b9ffdbe1e604463"
integrity sha512-cEoZBJrsQn69FPpUMePXG/ltGXtqKISgypj70PEHXt5meKDjpmMVSY4/8cXvFYEYsI9GvIwyAK0OrfAHiSoROA==
"@tiptap/extension-paragraph@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.1.14.tgz#ec993235ac4ceca5026c0e821d2d72e9d5e3c4f9"
integrity sha512-iWD1nfMvADrx2pwxlQXu2PDnNghhU2EvAOmNOzGOEzkTaELkPR4CDyr/wEi1ewS9dNhhO8EpP8IYVXzd01r8JA==
"@tiptap/extension-strike@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.1.13.tgz#6605792fa98f0e36861be4c7ed4d4125de8c77aa"
integrity sha512-VN6zlaCNCbyJUCDyBFxavw19XmQ4LkCh8n20M8huNqW77lDGXA2A7UcWLHaNBpqAijBRu9mWI8l4Bftyf2fcAw==
"@tiptap/extension-strike@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.1.14.tgz#8a94de5ec6bf726ff0ef73f998bad9d863d3a65d"
integrity sha512-AcFiyUc2eiL3TM5flvExIi+LjukaGzSKGGuLH1Q9e7T4GkfZu7FaSzjP1+2kvgwGAMJxgm5Ybzvugcf9rrNosA==
"@tiptap/extension-subscript@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.1.13.tgz#4363473b760ba3805d6e5e4bd45e63dcc7099f56"
integrity sha512-+kqK0P669Dsl/7IPSQNM/bN35Er45MKtHn8eQmudcLpFmBTsL6DlxG/080/Lqr49a6OLcefQfLaENz+QQVfBag==
"@tiptap/extension-subscript@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.1.14.tgz#c6796abbb9d1654e8ab12c1b97354aac85754695"
integrity sha512-HYKqCkP4ncbHJFXxqafZUUHdL8raKqaw/DJ8Ogmk8luOqaFjgOGcgFRhtWyXCbv/BJCL42/0IGeoM5D4aRo/gg==
"@tiptap/extension-superscript@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.1.13.tgz#c508ef30340457f362b9d179a5aa65f619df134a"
integrity sha512-wZr9Ls7YYvzbVInBqqpQkn+/YwG3b78Rg3U1TldCcbg0IprwFyPsFHvu0NZnqYEG4MHhaF3F1sZRtPdZ0hDy8g==
"@tiptap/extension-superscript@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.1.14.tgz#1ce5646d5c5a2bbf009c563de14cdf879156811a"
integrity sha512-L44OToFzSULAM+8wfbDa2oW7fekNvsZXn081x2EcF8lTjJXDfK+3nViNfoSY7OAoZKEIF6HTYOPwFmiDM+ZZXg==
"@tiptap/extension-table-cell@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.1.13.tgz#28efbc99480d53346200dcbf50cfb32bade180d1"
integrity sha512-30pyVt2PxGAk8jmsXKxDheql8K/xIRA9FiDo++kS2Kr6Y7I42/kNPQttJ2W+Q1JdRJvedNfQtziQfKWDRLLCNA==
"@tiptap/extension-table-cell@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.1.14.tgz#fddcb425485e9b28ffa9873e79e27dde5ce0bf44"
integrity sha512-4cnT35wA/O33H/UTOJUiZJFe0QjHfz8vOVjvkbeYOxcuo5Ww0Ro1D6RWU70fdAdkFccFJZ5UtqG9RcZi+JkNWA==
"@tiptap/extension-table-header@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.1.13.tgz#8d64a0e5a6a5ea128708b866e56a0e04e34d7a5b"
integrity sha512-FwIV5iso5kmpu01QyvrPCjJqZfqxRTjtjMsDyut2uIgx9v5TXk0V5XvMWobx435ANIDJoGTYCMRlIqcgtyqwAQ==
"@tiptap/extension-table-header@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.1.14.tgz#540cc2a7312f5bd6b13076eea11be608555dfacc"
integrity sha512-hg57IePDTGcr9GEFY5g201DreuXv3MZYp6TjqDGF/O48Yy2v22X+Baaa/SyW9WKPLPInAXBp2f8/2YSBKTuwLg==
"@tiptap/extension-table-row@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.1.13.tgz#ef75d6de9c7695bbb90f745aabd72d327f161ac3"
integrity sha512-27Mb9/oYbiLd+/BUFMhQzRIqMd2Z5j1BZMYsktwtDG8vGdYVlaW257UVaoNR9TmiXyIzd3Dh1mOil8G35+HRHg==
"@tiptap/extension-table-row@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.1.14.tgz#42968b0eca9f45f646d5c922818590d1365271b2"
integrity sha512-TE1qLztFerqKbm+ZkR+4tN24ZI6EFB99bYQ7QUaw5v1ioyL4QfDny2vSePKmjNObmgmFNl8I4hBqpuzYq9CzhQ==
"@tiptap/extension-table@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.1.13.tgz#cfe3fc2665d12d2c946fc83b2cce9d1485ff29a0"
integrity sha512-yMWt2LqotOsWJhLwFNo8fyTwJNLPtnk+eCUxKLlMXP23mJ/lpF+jvTihhHVVic5GqV9vLYZFU2Tn+5k/Vd5P1w==
"@tiptap/extension-table@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.1.14.tgz#c50e403c43fa5623088cf5a2cdf11adf180c63d8"
integrity sha512-e/idEukzXSThGKyRHxIaK3zqwLCaZMvm0Xcv2D8X2rnQTRIWr4ZR1+zCgwysFAUT26aDYfMUfmx2kAmuNNdLsg==
"@tiptap/extension-task-item@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.1.13.tgz#f049b774f8151b9568d7afbbb5b8fbcb30f35755"
integrity sha512-0E1woY0BXpv0SBOGPl5Cmo2RuH+Zchn7dYcTILtOsqHu6onJ4eP0N76+jGFLGV3T0PnPf7JDuwsO/B6pC7yMSg==
"@tiptap/extension-task-item@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.1.14.tgz#6e30bf3e02885e3fa978a94d83c92c80d47d1dc2"
integrity sha512-P5/Z1cARREnvpFa3gGvFMUm++OJ4RBS/9NVfwKmfg4Y71/0ZbLpaYrq4TKSa8Zg/lR1Ybx7Y1T9agmDu5D5S1g==
"@tiptap/extension-task-list@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.1.13.tgz#1a1c40f5886111a1a74386637e7bd0c4ca4158d9"
integrity sha512-WfTo4KN0PqpmZxx23rak08M7flfBhv9IcPVpuJ4JthZOlexYdOZxaE/Yd4vlqZhq6cibG7CFljp8VzkfTUa1Ew==
"@tiptap/extension-task-list@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.1.14.tgz#4c6d12c9d45673bc0dd4e32031b4afa1fe041049"
integrity sha512-yI5vd6L0UC0aJvujjmzCnYfx9K8FExI/kVHd/+AlxGQwG90+XAfj6Tw93GyIu7DhGRq/Goek1Mt+RC09sw4AHQ==
"@tiptap/extension-text@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.1.13.tgz#ac17a0220aef1bae1bbd646a91491353e57bb5d1"
integrity sha512-zzsTTvu5U67a8WjImi6DrmpX2Q/onLSaj+LRWPh36A1Pz2WaxW5asZgaS+xWCnR+UrozlCALWa01r7uv69jq0w==
"@tiptap/extension-text@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.1.14.tgz#a781c68fe348bdd08730e727f2380295dc190260"
integrity sha512-Z5g+SlWqnK2loIwqkg2LzsVKVCiMyUfDD8IhNJsny0BRbWKFs4SKPCkAcyCxLK2h8Jm/BG6PyfGHsF/2wx7I3Q==
"@tiptap/pm@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-2.1.13.tgz#857753691580be760da13629fab2712c52750741"
integrity sha512-zNbA7muWsHuVg12GrTgN/j119rLePPq5M8dZgkKxUwdw8VmU3eUyBp1SihPEXJ2U0MGdZhNhFX7Y74g11u66sg==
"@tiptap/pm@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-2.1.14.tgz#b504120adfa428e4eb0526d5ea2b4ba5ed55400b"
integrity sha512-UuHqLDFPEPVLk4iopdHFpnn9KPNmbwQ8M0lnDRK1a9ZBheQpdTj6mQYFteYGKdqJpfcbhLHvmYl8nthfzlXGYw==
dependencies:
prosemirror-changeset "^2.2.0"
prosemirror-collab "^1.3.0"
@ -2403,18 +2403,18 @@
prosemirror-transform "^1.7.0"
prosemirror-view "^1.28.2"
"@tiptap/suggestion@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/suggestion/-/suggestion-2.1.13.tgz#0a8317260baed764a523a09099c0889a0e5b507e"
integrity sha512-Y05TsiXTFAJ5SrfoV+21MAxig5UNbY0AVa03lQlh/yicTRPpIc6hgZzblB0uxDSYoj6+kaHE4MIZvPvhUD8BJQ==
"@tiptap/suggestion@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/suggestion/-/suggestion-2.1.14.tgz#baae04da4cb1cb9431f85cc90456185851d5b167"
integrity sha512-8jx+RYY4cZ3ZFmHDm4fPhHN6N8fwIgFnB6iBTbEh5Ra+0Bvh1q+Ek21+Ni92ORjmYz9Vy1e5xxJMyGNywRS5dw==
"@tiptap/vue-2@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.1.13.tgz#e84c144fa36f79c36db3cf6913aef197002bd298"
integrity sha512-OsCINarPGyT3sDIXDrhVyaoH0I0VxeDDm+NgS5P0fPbBCnsHZ8csvxD9UB9/KZ/UoxYDfJ1zLplKQn1AIlnRzg==
"@tiptap/vue-2@^2.1.14":
version "2.1.14"
resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.1.14.tgz#59acb020a0ace9946d6f78572ae8a7629826b934"
integrity sha512-7kisS73LLnFlmRe0T7o/FBlZghaBsZDty1qfAuS+TrhgW1o5wvCtm8Ogoomai2ExWK6Lh8k7E3nc2lDS03s/aw==
dependencies:
"@tiptap/extension-bubble-menu" "^2.1.13"
"@tiptap/extension-floating-menu" "^2.1.13"
"@tiptap/extension-bubble-menu" "^2.1.14"
"@tiptap/extension-floating-menu" "^2.1.14"
vue-ts-types "^1.6.0"
"@tootallnate/once@2":