Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-11-18 18:14:27 +00:00
parent bf0d6692fc
commit f6c037b73c
54 changed files with 880 additions and 548 deletions

View File

@ -53,7 +53,6 @@
/doc/user/application_security/cve_id_request.md @fneill
/doc/user/application_security/security_dashboard @fneill
/doc/user/application_security/vulnerabilities @fneill
/doc/user/application_security/vulnerability_management @fneill
/doc/user/application_security/vulnerability_report @fneill
/doc/user/clusters/ @marcia
/doc/user/compliance/ @rdickenson @eread
@ -86,7 +85,6 @@
[Docs Create]
/doc/administration/file_hooks.md @aqualls
/doc/administration/git_annex.md @aqualls
/doc/administration/git_protocol.md @aqualls
/doc/administration/invalidate_markdown_cache.md @aqualls
/doc/administration/issue_closing_pattern.md @aqualls
@ -179,7 +177,6 @@
/lib/gitlab/background_migration/ @gitlab-org/maintainers/database
/ee/lib/ee/gitlab/background_migration/ @gitlab-org/maintainers/database
/lib/gitlab/database/ @gitlab-org/maintainers/database
/ee/lib/gitlab/database/ @gitlab-org/maintainers/database
/lib/gitlab/sql/ @gitlab-org/maintainers/database
/lib/gitlab/github_import/ @gitlab-org/maintainers/database
/app/finders/ @gitlab-org/maintainers/database
@ -191,7 +188,6 @@
/.gitlab/ci/ @gl-quality/eng-prod
/.gitlab/ci/docs.gitlab-ci.yml @gl-quality/eng-prod @gl-docsteam
/.gitlab/ci/releases.gitlab-ci.yml @gl-quality/eng-prod @gitlab-org/delivery
/.gitlab/ci/dast.gitlab-ci.yml @dappelt @ngeorge1 @gl-quality/eng-prod
/.gitlab/ci/reports.gitlab-ci.yml @gitlab-com/gl-security/appsec @gl-quality/eng-prod
/.gitlab/CODEOWNERS @gl-quality/eng-prod
Dangerfile @gl-quality/eng-prod
@ -236,8 +232,6 @@ Dangerfile @gl-quality/eng-prod
/ee/app/policies/vulnerability*.rb @gitlab-org/secure/threat-insights-backend-team
/ee/app/presenters/projects/security/ @gitlab-org/secure/threat-insights-backend-team
/ee/lib/api/vulnerabilit*.rb @gitlab-org/secure/threat-insights-backend-team
/ee/lib/gitlab/ci/reports/security/vulnerability_reports_comparer.rb @gitlab-org/secure/threat-insights-backend-team
/ee/spec/lib/gitlab/ci/reports/security/vulnerability_reports_comparer_spec.rb @gitlab-org/secure/threat-insights-backend-team
/ee/spec/policies/vulnerabilities/ @gitlab-org/secure/threat-insights-backend-team
/ee/spec/policies/vulnerability*.rb @gitlab-org/secure/threat-insights-backend-team
/ee/spec/presenters/projects/security/ @gitlab-org/secure/threat-insights-backend-team
@ -273,8 +267,6 @@ Dangerfile @gl-quality/eng-prod
/spec/lib/gitlab/kubernetes/network_policy_spec.rb @gitlab-org/protect/container-security-backend
/ee/app/services/network_policies/** @gitlab-org/protect/container-security-backend
/ee/spec/services/network_policies/** @gitlab-org/protect/container-security-backend
/ee/app/controllers/projects/security/waf_anomalies_controller.rb @gitlab-org/protect/container-security-backend
/ee/spec/controllers/projects/security/waf_anomalies_controller_spec.rb @gitlab-org/protect/container-security-backend
/app/models/clusters/applications/cilium.rb @gitlab-org/protect/container-security-backend
/spec/models/clusters/applications/cilium_spec.rb @gitlab-org/protect/container-security-backend
/ee/app/controllers/projects/security/network_policies_controller.rb @gitlab-org/protect/container-security-backend
@ -304,7 +296,7 @@ Dangerfile @gl-quality/eng-prod
/lib/gitlab/discussions_diff/ @dskim_gitlab @garyh @patrickbajao @marc_shaw @kerrizor
/lib/gitlab/quick_actions/ @dskim_gitlab @garyh @patrickbajao @marc_shaw @kerrizor
/ee/app/models/merge_request.rb @dskim_gitlab @garyh @patrickbajao @marc_shaw @kerrizor
/ee/app/models/ee/merge_request.rb @dskim_gitlab @garyh @patrickbajao @marc_shaw @kerrizor
/ee/app/services/merge_requests/ @dskim_gitlab @garyh @patrickbajao @marc_shaw @kerrizor
/ee/app/workers/merge_requests/ @dskim_gitlab @garyh @patrickbajao @marc_shaw @kerrizor
/ee/app/workers/merge_request_reset_approvals_worker.rb @dskim_gitlab @garyh @patrickbajao @marc_shaw @kerrizor
@ -312,7 +304,6 @@ Dangerfile @gl-quality/eng-prod
/app/assets/javascripts/diffs @viktomas @jboyson @iamphill @thomasrandolph
/app/assets/javascripts/batch_comments/ @viktomas @jboyson @iamphill @thomasrandolph
/app/assets/javascripts/notes @viktomas @jboyson @iamphill @thomasrandolph
/app/assets/javascripts/merge_request @viktomas @jboyson @iamphill @thomasrandolph
/app/assets/javascripts/merge_conflicts @viktomas @jboyson @iamphill @thomasrandolph
/app/assets/javascripts/mr_notes @viktomas @jboyson @iamphill @thomasrandolph
/app/assets/javascripts/mr_popover @viktomas @jboyson @iamphill @thomasrandolph
@ -334,7 +325,6 @@ Dangerfile @gl-quality/eng-prod
/lib/gitlab/usage_data_counters/ @gitlab-org/growth/product-intelligence/engineers
[Growth Experiments]
/app/assets/javascripts/lib/utils/experimentation.js @gitlab-org/growth/experiment-devs
/app/experiments/ @gitlab-org/growth/experiment-devs
/app/models/experiment.rb @gitlab-org/growth/experiment-devs
/app/models/experiment_subject.rb @gitlab-org/growth/experiment-devs

View File

@ -2613,3 +2613,170 @@ Style/OpenStructUse:
- 'spec/support/shared_examples/requests/api/nuget_packages_shared_examples.rb'
- 'spec/tooling/rspec_flaky/flaky_example_spec.rb'
- 'tooling/rspec_flaky/flaky_example.rb'
GraphQL/ArgumentName:
Exclude:
- 'ee/app/graphql/mutations/audit_events/external_audit_event_destinations/update.rb'
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: group_definitions, define_resolver_after_definition
GraphQL/FieldDefinitions:
Exclude:
- 'app/graphql/types/commit_type.rb'
- 'app/graphql/types/group_type.rb'
- 'app/graphql/types/issue_type.rb'
- 'app/graphql/types/label_type.rb'
- 'app/graphql/types/merge_request_type.rb'
- 'app/graphql/types/namespace_type.rb'
- 'app/graphql/types/notes/note_type.rb'
- 'app/graphql/types/project_type.rb'
- 'app/graphql/types/projects/topic_type.rb'
- 'app/graphql/types/release_type.rb'
- 'ee/app/graphql/types/ci/code_quality_degradation_type.rb'
- 'ee/app/graphql/types/epic_type.rb'
- 'ee/app/graphql/types/group_release_stats_type.rb'
- 'ee/app/graphql/types/iteration_type.rb'
- 'ee/app/graphql/types/requirements_management/requirement_type.rb'
# Cop supports --auto-correct.
GraphQL/FieldHashKey:
Exclude:
- 'app/graphql/types/ci/config/job_type.rb'
- 'app/graphql/types/ci/status_action_type.rb'
- 'app/graphql/types/error_tracking/sentry_error_stack_trace_entry_type.rb'
- 'app/graphql/types/packages/helm/dependency_type.rb'
# Cop supports --auto-correct.
GraphQL/FieldMethod:
Exclude:
- 'app/graphql/types/ci/job_type.rb'
- 'app/graphql/types/merge_request_type.rb'
- 'app/graphql/types/metrics/dashboards/annotation_type.rb'
- 'app/graphql/types/packages/package_details_type.rb'
- 'app/graphql/types/project_type.rb'
- 'ee/app/graphql/types/dast/profile_type.rb'
- 'ee/app/graphql/types/dast_site_validation_type.rb'
- 'ee/app/graphql/types/group_release_stats_type.rb'
- 'ee/app/graphql/types/incident_management/oncall_rotation_type.rb'
# Cop supports --auto-correct.
GraphQL/OrderedArguments:
Exclude:
- 'app/graphql/mutations/jira_import/start.rb'
- 'app/graphql/mutations/merge_requests/accept.rb'
- 'app/graphql/resolvers/base_issues_resolver.rb'
- 'app/graphql/resolvers/design_management/designs_resolver.rb'
- 'app/graphql/resolvers/design_management/version/design_at_version_resolver.rb'
- 'app/graphql/resolvers/design_management/version/designs_at_version_resolver.rb'
- 'app/graphql/resolvers/design_management/version_in_collection_resolver.rb'
- 'app/graphql/resolvers/group_milestones_resolver.rb'
- 'app/graphql/resolvers/merge_requests_resolver.rb'
- 'app/graphql/resolvers/paginated_tree_resolver.rb'
- 'app/graphql/resolvers/tree_resolver.rb'
- 'app/graphql/resolvers/users/groups_resolver.rb'
- 'app/graphql/types/commit_action_type.rb'
- 'app/graphql/types/diff_paths_input_type.rb'
- 'app/graphql/types/issues/negated_issue_filter_input_type.rb'
- 'app/graphql/types/jira_users_mapping_input_type.rb'
- 'app/graphql/types/notes/diff_image_position_input_type.rb'
- 'app/graphql/types/notes/diff_position_base_input_type.rb'
- 'app/graphql/types/notes/diff_position_input_type.rb'
# Cop supports --auto-correct.
GraphQL/OrderedFields:
Exclude:
- 'app/graphql/types/board_list_type.rb'
- 'app/graphql/types/ci/analytics_type.rb'
- 'app/graphql/types/ci/ci_cd_setting_type.rb'
- 'app/graphql/types/ci/config/group_type.rb'
- 'app/graphql/types/ci/config/job_type.rb'
- 'app/graphql/types/ci/config/stage_type.rb'
- 'app/graphql/types/ci/detailed_status_type.rb'
- 'app/graphql/types/ci/group_type.rb'
- 'app/graphql/types/ci/job_type.rb'
- 'app/graphql/types/ci/runner_architecture_type.rb'
- 'app/graphql/types/ci/runner_platform_type.rb'
- 'app/graphql/types/ci/runner_type.rb'
- 'app/graphql/types/ci/stage_type.rb'
- 'app/graphql/types/ci/status_action_type.rb'
- 'app/graphql/types/ci/template_type.rb'
- 'app/graphql/types/commit_type.rb'
- 'app/graphql/types/container_expiration_policy_type.rb'
- 'app/graphql/types/container_repository_tag_type.rb'
- 'app/graphql/types/container_repository_type.rb'
- 'app/graphql/types/dependency_proxy/blob_type.rb'
- 'app/graphql/types/dependency_proxy/image_ttl_group_policy_type.rb'
- 'app/graphql/types/dependency_proxy/manifest_type.rb'
- 'app/graphql/types/design_management/design_collection_type.rb'
- 'app/graphql/types/diff_refs_type.rb'
- 'app/graphql/types/diff_stats_summary_type.rb'
- 'app/graphql/types/diff_stats_type.rb'
- 'app/graphql/types/error_tracking/sentry_detailed_error_type.rb'
- 'app/graphql/types/error_tracking/sentry_error_collection_type.rb'
- 'app/graphql/types/error_tracking/sentry_error_frequency_type.rb'
- 'app/graphql/types/error_tracking/sentry_error_stack_trace_context_type.rb'
- 'app/graphql/types/error_tracking/sentry_error_stack_trace_entry_type.rb'
- 'app/graphql/types/error_tracking/sentry_error_stack_trace_type.rb'
- 'app/graphql/types/error_tracking/sentry_error_type.rb'
- 'app/graphql/types/evidence_type.rb'
- 'app/graphql/types/grafana_integration_type.rb'
- 'app/graphql/types/issue_type.rb'
- 'app/graphql/types/jira_import_type.rb'
- 'app/graphql/types/jira_user_type.rb'
- 'app/graphql/types/label_type.rb'
- 'app/graphql/types/merge_request_type.rb'
- 'app/graphql/types/metadata/kas_type.rb'
- 'app/graphql/types/metadata_type.rb'
- 'app/graphql/types/namespace/package_settings_type.rb'
- 'app/graphql/types/namespace_type.rb'
- 'app/graphql/types/notes/diff_position_type.rb'
- 'app/graphql/types/notes/discussion_type.rb'
- 'app/graphql/types/notes/note_type.rb'
- 'app/graphql/types/packages/composer/json_type.rb'
- 'app/graphql/types/packages/composer/metadatum_type.rb'
- 'app/graphql/types/packages/conan/file_metadatum_type.rb'
- 'app/graphql/types/packages/conan/metadatum_type.rb'
- 'app/graphql/types/packages/helm/dependency_type.rb'
- 'app/graphql/types/packages/helm/maintainer_type.rb'
- 'app/graphql/types/packages/helm/metadata_type.rb'
- 'app/graphql/types/packages/maven/metadatum_type.rb'
- 'app/graphql/types/packages/nuget/metadatum_type.rb'
- 'app/graphql/types/packages/package_dependency_link_type.rb'
- 'app/graphql/types/packages/package_file_type.rb'
- 'app/graphql/types/packages/package_tag_type.rb'
- 'app/graphql/types/packages/package_type.rb'
- 'app/graphql/types/project_statistics_type.rb'
- 'app/graphql/types/project_type.rb'
- 'app/graphql/types/projects/services/jira_project_type.rb'
- 'app/graphql/types/release_asset_link_type.rb'
- 'app/graphql/types/release_links_type.rb'
- 'app/graphql/types/release_type.rb'
- 'app/graphql/types/repository_type.rb'
- 'app/graphql/types/root_storage_statistics_type.rb'
- 'app/graphql/types/task_completion_status.rb'
- 'app/graphql/types/tree/blob_type.rb'
- 'app/graphql/types/tree/submodule_type.rb'
- 'app/graphql/types/tree/tree_entry_type.rb'
- 'app/graphql/types/user_callout_type.rb'
- 'app/graphql/types/user_status_type.rb'
- 'ee/app/graphql/types/analytics/devops_adoption/snapshot_type.rb'
- 'ee/app/graphql/types/epic_descendant_count_type.rb'
- 'ee/app/graphql/types/epic_descendant_weight_sum_type.rb'
- 'ee/app/graphql/types/epic_health_status_type.rb'
- 'ee/app/graphql/types/epic_type.rb'
- 'ee/app/graphql/types/geo/geo_node_type.rb'
- 'ee/app/graphql/types/requirements_management/requirement_states_count_type.rb'
- 'ee/app/graphql/types/scan_execution_policy_type.rb'
- 'ee/app/graphql/types/scan_type.rb'
- 'ee/app/graphql/types/scanned_resource_type.rb'
- 'ee/app/graphql/types/security_report_summary_section_type.rb'
- 'ee/app/graphql/types/timebox_report_type.rb'
# Configuration parameters: Max, CountComments, ExcludedMethods.
GraphQL/ResolverMethodLength:
Exclude:
- 'app/graphql/types/ci/detailed_status_type.rb'
- 'app/graphql/types/ci/runner_type.rb'
- 'app/graphql/types/ci/stage_type.rb'
- 'app/graphql/types/packages/package_type.rb'

View File

@ -1 +1 @@
b6dda5d1f7a7e05c34ed0f72f161a46aee536d75
15bfbf4430778f416e42f931a5bf813e1a9c7fc5

View File

@ -197,7 +197,7 @@ gem 'state_machines-activerecord', '~> 0.8.0'
gem 'acts-as-taggable-on', '~> 7.0'
# Background jobs
gem 'sidekiq', '~> 6.2.2'
gem 'sidekiq', '~> 6.3'
gem 'sidekiq-cron', '~> 1.0'
gem 'redis-namespace', '~> 1.8.1'
gem 'gitlab-sidekiq-fetcher', '0.8.0', require: 'sidekiq-reliable-fetch'
@ -376,7 +376,7 @@ group :development, :test do
gem 'spring', '~> 2.1.0'
gem 'spring-commands-rspec', '~> 1.0.4'
gem 'gitlab-styles', '~> 6.4.0', require: false
gem 'gitlab-styles', '~> 6.5.0', require: false
gem 'haml_lint', '~> 0.36.0', require: false
gem 'bundler-audit', '~> 0.7.0.1', require: false

View File

@ -490,9 +490,10 @@ GEM
openid_connect (~> 1.2)
gitlab-sidekiq-fetcher (0.8.0)
sidekiq (~> 6.1)
gitlab-styles (6.4.0)
gitlab-styles (6.5.0)
rubocop (~> 0.91, >= 0.91.1)
rubocop-gitlab-security (~> 0.1.1)
rubocop-graphql (~> 0.10)
rubocop-performance (~> 1.9.2)
rubocop-rails (~> 2.9)
rubocop-rspec (~> 1.44)
@ -1107,6 +1108,8 @@ GEM
parser (>= 2.7.1.5)
rubocop-gitlab-security (0.1.1)
rubocop (>= 0.51)
rubocop-graphql (0.10.3)
rubocop (>= 0.87, < 2)
rubocop-performance (1.9.2)
rubocop (>= 0.90.0, < 2.0)
rubocop-ast (>= 0.4.0)
@ -1175,7 +1178,7 @@ GEM
shellany (0.0.1)
shoulda-matchers (4.0.1)
activesupport (>= 4.2.0)
sidekiq (6.2.2)
sidekiq (6.3.1)
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.2.0)
@ -1477,7 +1480,7 @@ DEPENDENCIES
gitlab-net-dns (~> 0.9.1)
gitlab-omniauth-openid-connect (~> 0.8.0)
gitlab-sidekiq-fetcher (= 0.8.0)
gitlab-styles (~> 6.4.0)
gitlab-styles (~> 6.5.0)
gitlab_chronic_duration (~> 0.10.6.2)
gitlab_omniauth-ldap (~> 2.1.1)
gon (~> 6.4.0)
@ -1620,7 +1623,7 @@ DEPENDENCIES
sentry-raven (~> 3.1)
settingslogic (~> 2.0.9)
shoulda-matchers (~> 4.0.1)
sidekiq (~> 6.2.2)
sidekiq (~> 6.3)
sidekiq-cron (~> 1.0)
simple_po_parser (~> 1.1.2)
simplecov (~> 0.18.5)

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -5,9 +5,11 @@ import { handleFileEvent } from '../services/upload_helpers';
export default Extension.create({
name: 'attachment',
defaultOptions: {
uploadsPath: null,
renderMarkdown: null,
addOptions() {
return {
uploadsPath: null,
renderMarkdown: null,
};
},
addCommands() {

View File

@ -2,8 +2,10 @@ import Playable from './playable';
export default Playable.extend({
name: 'audio',
defaultOptions: {
...Playable.options,
mediaType: 'audio',
addOptions() {
return {
...this.parent?.(),
mediaType: 'audio',
};
},
});

View File

@ -31,13 +31,12 @@ const attrs = {
export default marks.map((name) =>
Mark.create({
name,
inclusive: false,
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
};
},
addAttributes() {
return (attrs[name] || []).reduce(
(acc, attr) => ({

View File

@ -7,9 +7,11 @@ const resolveImageEl = (element) =>
element.nodeName === 'IMG' ? element : element.querySelector('img');
export default Image.extend({
defaultOptions: {
...Image.options,
inline: true,
addOptions() {
return {
...this.parent?.(),
inline: true,
};
},
addAttributes() {
return {

View File

@ -3,8 +3,10 @@ import { Mark, markInputRule, mergeAttributes } from '@tiptap/core';
export default Mark.create({
name: 'inlineDiff',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
};
},
addAttributes() {

View File

@ -18,10 +18,13 @@ export const extractHrefFromMarkdownLink = (match) => {
};
export default Link.extend({
defaultOptions: {
...Link.options,
openOnClick: false,
addOptions() {
return {
...this.parent?.(),
openOnClick: false,
};
},
addInputRules() {
const markdownLinkSyntaxInputRuleRegExp = /(?:^|\s)\[([\w|\s|-]+)\]\((?<href>.+?)\)$/gm;
const urlSyntaxRegExp = /(?:^|\s)(?<href>(?:https?:\/\/|www\.)[\S]+)(?:\s|\n)$/gim;

View File

@ -2,9 +2,11 @@ import { TaskItem } from '@tiptap/extension-task-item';
import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants';
export default TaskItem.extend({
defaultOptions: {
nested: true,
HTMLAttributes: {},
addOptions() {
return {
nested: true,
HTMLAttributes: {},
};
},
addAttributes() {

View File

@ -2,9 +2,11 @@ import Playable from './playable';
export default Playable.extend({
name: 'video',
defaultOptions: {
...Playable.options,
mediaType: 'video',
extraElementAttrs: { width: '400' },
addOptions() {
return {
...this.parent?.(),
mediaType: 'video',
extraElementAttrs: { width: '400' },
};
},
});

View File

@ -7,10 +7,12 @@ export default Node.create({
selectable: false,
atom: true,
defaultOptions: {
HTMLAttributes: {
class: 'gl-display-inline-flex gl-px-1 gl-bg-blue-100 gl-rounded-base gl-font-sm',
},
addOptions() {
return {
HTMLAttributes: {
class: 'gl-display-inline-flex gl-px-1 gl-bg-blue-100 gl-rounded-base gl-font-sm',
},
};
},
parseHTML() {

View File

@ -44,6 +44,7 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) {
let addFileToForm;
let updateAttachingMessage;
let uploadFile;
let hasPlainText;
formTextarea.wrap('<div class="div-dropzone"></div>');
formTextarea.on('paste', (event) => handlePaste(event));
@ -184,7 +185,7 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) {
event.preventDefault();
const text = converter.convertToTableMarkdown();
pasteText(text);
} else {
} else if (!hasPlainText(pasteEvent)) {
const fileList = [...clipboardData.files];
fileList.forEach((file) => {
if (file.type.indexOf('image') !== -1) {
@ -203,6 +204,11 @@ export default function dropzoneInput(form, config = { parallelUploads: 2 }) {
}
};
hasPlainText = (data) => {
const clipboardDataList = [...data.clipboardData.items];
return clipboardDataList.some((item) => item.type === 'text/plain');
};
pasteText = (text, shouldPad) => {
let formattedText = text;
if (shouldPad) {

View File

@ -185,6 +185,13 @@ export default {
:title="__('Confidential')"
:aria-label="__('Confidential')"
/>
<gl-icon
v-if="issuable.hidden"
v-gl-tooltip
name="spam"
:title="__('This issue is hidden because its author has been banned')"
:aria-label="__('Hidden')"
/>
<gl-link class="issue-title-text" dir="auto" :href="webUrl" v-bind="issuableTitleProps">
{{ issuable.title }}
<gl-icon v-if="isIssuableUrlExternal" name="external-link" class="gl-ml-2" />
@ -202,7 +209,7 @@ export default {
<span v-else data-testid="issuable-reference" class="issuable-reference">
{{ reference }}
</span>
<span class="gl-display-none gl-sm-display-inline-block">
<span class="gl-display-none gl-sm-display-inline">
<span aria-hidden="true">&middot;</span>
<span class="issuable-authored gl-mr-3">
<gl-sprintf :message="__('created %{timeAgo} by %{author}')">

View File

@ -11,7 +11,7 @@ import {
import fuzzaldrinPlus from 'fuzzaldrin-plus';
import getIssuesQuery from 'ee_else_ce/issues_list/queries/get_issues.query.graphql';
import getIssuesCountsQuery from 'ee_else_ce/issues_list/queries/get_issues_counts.query.graphql';
import createFlash from '~/flash';
import createFlash, { FLASH_TYPES } from '~/flash';
import { TYPE_USER } from '~/graphql_shared/constants';
import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
import { ITEM_TYPE } from '~/groups/constants';
@ -157,6 +157,9 @@ export default {
initialEmail: {
default: '',
},
isIssueRepositioningDisabled: {
default: false,
},
isProject: {
default: false,
},
@ -184,8 +187,13 @@ export default {
},
data() {
const state = getParameterByName(PARAM_STATE);
const sortKey = getSortKey(getParameterByName(PARAM_SORT));
const defaultSortKey = state === IssuableStates.Closed ? UPDATED_DESC : CREATED_DESC;
let sortKey = getSortKey(getParameterByName(PARAM_SORT)) || defaultSortKey;
if (this.isIssueRepositioningDisabled && sortKey === RELATIVE_POSITION_ASC) {
this.showIssueRepositioningMessage();
sortKey = defaultSortKey;
}
return {
dueDateFilter: getDueDateValue(getParameterByName(PARAM_DUE_DATE)),
@ -196,7 +204,7 @@ export default {
pageInfo: {},
pageParams: getInitialPageParams(sortKey),
showBulkEditSidebar: false,
sortKey: sortKey || defaultSortKey,
sortKey,
state: state || IssuableStates.Opened,
};
},
@ -611,11 +619,22 @@ export default {
});
},
handleSort(sortKey) {
if (this.isIssueRepositioningDisabled && sortKey === RELATIVE_POSITION_ASC) {
this.showIssueRepositioningMessage();
return;
}
if (this.sortKey !== sortKey) {
this.pageParams = getInitialPageParams(sortKey);
}
this.sortKey = sortKey;
},
showIssueRepositioningMessage() {
createFlash({
message: this.$options.i18n.issueRepositioningMessage,
type: FLASH_TYPES.NOTICE,
});
},
toggleBulkEditSidebar(showBulkEditSidebar) {
this.showBulkEditSidebar = showBulkEditSidebar;
},

View File

@ -75,6 +75,9 @@ export const i18n = {
editIssues: __('Edit issues'),
errorFetchingCounts: __('An error occurred while getting issue counts'),
errorFetchingIssues: __('An error occurred while loading issues'),
issueRepositioningMessage: __(
'Issues are being rebalanced at the moment, so manual reordering is disabled.',
),
jiraIntegrationMessage: s__(
'JiraService|%{jiraDocsLinkStart}Enable the Jira integration%{jiraDocsLinkEnd} to view your Jira issues in GitLab.',
),

View File

@ -129,6 +129,7 @@ export function mountIssuesListApp() {
hasMultipleIssueAssigneesFeature,
importCsvIssuesPath,
initialEmail,
isIssueRepositioningDisabled,
isProject,
isSignedIn,
jiraIntegrationPath,
@ -161,6 +162,7 @@ export function mountIssuesListApp() {
hasIssueWeightsFeature: parseBoolean(hasIssueWeightsFeature),
hasIterationsFeature: parseBoolean(hasIterationsFeature),
hasMultipleIssueAssigneesFeature: parseBoolean(hasMultipleIssueAssigneesFeature),
isIssueRepositioningDisabled: parseBoolean(isIssueRepositioningDisabled),
isProject: parseBoolean(isProject),
isSignedIn: parseBoolean(isSignedIn),
jiraIntegrationPath,

View File

@ -6,6 +6,7 @@ fragment IssueFragment on Issue {
createdAt
downvotes
dueDate
hidden
humanTimeEstimate
mergeRequestsCount
moved

View File

@ -54,7 +54,7 @@ export default {
class="gl-display-flex gl-flex-direction-column gl-border-b-solid gl-border-t-solid gl-border-t-1 gl-border-b-1"
:class="optionalClasses"
>
<div class="gl-display-flex gl-align-items-center gl-py-3 gl-px-5">
<div class="gl-display-flex gl-align-items-center gl-py-3">
<div
v-if="$slots['left-action']"
class="gl-w-7 gl-display-none gl-sm-display-flex gl-justify-content-start gl-pl-2"

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
module Projects
module Integrations
class ShimosController < Projects::ApplicationController
feature_category :integrations
before_action :ensure_renderable
def show; end
private
def ensure_renderable
render_404 unless Feature.enabled?(:shimo_integration, project) && project.has_shimo? && project.shimo_integration&.render?
end
end
end
end

View File

@ -212,6 +212,7 @@ module IssuesHelper
calendar_path: url_for(safe_params.merge(calendar_url_options)),
empty_state_svg_path: image_path('illustrations/issues.svg'),
full_path: namespace.full_path,
is_issue_repositioning_disabled: issue_repositioning_disabled?.to_s,
is_signed_in: current_user.present?.to_s,
jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'),
rss_path: url_for(safe_params.merge(rss_url_options)),

View File

@ -14,11 +14,13 @@ class Integration < ApplicationRecord
asana assembla bamboo bugzilla buildkite campfire confluence custom_issue_tracker datadog discord
drone_ci emails_on_push ewm external_wiki flowdock hangouts_chat irker jira
mattermost mattermost_slash_commands microsoft_teams packagist pipelines_email
pivotaltracker prometheus pushover redmine shimo slack slack_slash_commands teamcity unify_circuit webex_teams youtrack zentao
pivotaltracker prometheus pushover redmine slack slack_slash_commands teamcity unify_circuit webex_teams youtrack zentao
].freeze
# TODO Shimo is temporary disabled on group and instance-levels.
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/345677
PROJECT_SPECIFIC_INTEGRATION_NAMES = %w[
jenkins
jenkins shimo
].freeze
# Fake integrations to help with local development.

View File

@ -5,7 +5,11 @@ module Integrations
prop_accessor :external_wiki_url
validates :external_wiki_url, presence: true, public_url: true, if: :activated?
after_commit :cache_project_has_shimo
def render?
return false unless Feature.enabled?(:shimo_integration, project)
valid? && activated?
end
@ -43,5 +47,14 @@ module Integrations
}
]
end
private
def cache_project_has_shimo
return unless project && !project.destroyed?
project.project_setting.save! unless project.project_setting.persisted?
project.project_setting.update_column(:has_shimo, activated?)
end
end
end

View File

@ -448,7 +448,7 @@ class Project < ApplicationRecord
delegate :restrict_user_defined_variables, :restrict_user_defined_variables=, to: :ci_cd_settings, allow_nil: true
delegate :actual_limits, :actual_plan_name, to: :namespace, allow_nil: true
delegate :allow_merge_on_skipped_pipeline, :allow_merge_on_skipped_pipeline?,
:allow_merge_on_skipped_pipeline=, :has_confluence?,
:allow_merge_on_skipped_pipeline=, :has_confluence?, :has_shimo?,
to: :project_setting
delegate :active?, to: :prometheus_integration, allow_nil: true, prefix: true
delegate :merge_commit_template, :merge_commit_template=, to: :project_setting, allow_nil: true
@ -1468,7 +1468,9 @@ class Project < ApplicationRecord
end
def disabled_integrations
[:shimo]
disabled_integrations = []
disabled_integrations << 'shimo' unless Feature.enabled?(:shimo_integration, self)
disabled_integrations
end
def find_or_initialize_integration(name)

View File

@ -0,0 +1,10 @@
- breadcrumb_title s_('Shimo|Shimo Workspace')
- page_title s_('Shimo|Shimo Workspace')
- add_page_specific_style 'page_bundles/wiki'
= render layout: 'shared/empty_states/wikis_layout', locals: { image_path: 'illustrations/wiki_login_empty.svg' } do
%h4
= s_('Shimo|Shimo Workspace integration is enabled')
%p
= s_("Shimo|You've enabled the Shimo Workspace integration. You can view your wiki directly in Shimo.")
= link_to @project.shimo_integration.external_wiki_url, target: '_blank', rel: 'noopener noreferrer', class: 'gl-button btn btn-confirm', title: s_('Shimo|Go to Shimo Workspace') do
= s_('Shimo|Go to Shimo Workspace')

View File

@ -1,8 +0,0 @@
---
name: atomic_sidekiq_scheduler
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72380
rollout_issue_url:
milestone: '14.5'
type: development
group: group::project management
default_enabled: false

View File

@ -0,0 +1,8 @@
---
name: shimo_integration
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73129
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345356
milestone: '14.5'
type: development
group: group::integrations
default_enabled: false

View File

@ -29,7 +29,6 @@ use_sidekiq_legacy_memory_killer = !use_sidekiq_daemon_memory_killer
Sidekiq.configure_server do |config|
config.options[:strict] = false
config.options[:queues] = Gitlab::SidekiqConfig.expand_queues(config.options[:queues])
config.options[:scheduled_enq] = Gitlab::SidekiqEnq
Sidekiq.logger.info "Listening on queues #{config.options[:queues].uniq.sort}"
@ -115,5 +114,5 @@ Sidekiq.configure_client do |config|
config.client_middleware(&Gitlab::SidekiqMiddleware.client_configurator)
end
Sidekiq::Client.prepend Gitlab::Patch::SidekiqClient
Sidekiq::Cron::Poller.prepend Gitlab::Patch::SidekiqCronPoller
Sidekiq::Scheduled::Poller.prepend Gitlab::Patch::SidekiqPoller
Sidekiq::Cron::Poller.prepend Gitlab::Patch::SidekiqPoller

View File

@ -453,6 +453,10 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
end
namespace :integrations do
resource :shimo, only: [:show]
end
end
# End of the /-/ scope.

View File

@ -9,7 +9,12 @@ type: reference
## Default projects limit
You can change the default maximum number of projects that users can create in their personal namespace:
You can configure the default maximum number of projects new users can create in their
personal namespace. This limit affects only new user accounts created after you change
the setting. This setting is not retroactive for existing users, but you can separately edit
the [project limits for existing users](#projects-limit-for-a-user).
To configure the maximum number of projects in personal namespaces for new users:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General**, then expand **Account and limit**.
@ -18,6 +23,17 @@ You can change the default maximum number of projects that users can create in t
If you set **Default projects limit** to 0, users are not allowed to create projects
in their users personal namespace. However, projects can still be created in a group.
### Projects limit for a user
You can edit a specific user, and change the maximum number of projects this user
can create in their personal namespace:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview** > **Users**.
1. From the list of users, select a user.
1. Select **Edit**.
1. Increase or decrease the **Projects limit** value.
## Max attachment size
You can change the maximum file size for attachments in comments and replies in GitLab:

View File

@ -1,22 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Patch
module SidekiqClient
private
# This is a copy of https://github.com/mperham/sidekiq/blob/v6.2.2/lib/sidekiq/client.rb#L187-L194
# but using `conn.pipelined` instead of `conn.multi`. The multi call isn't needed here because in
# the case of scheduled jobs, only one Redis call is made. For other jobs, we don't really need
# the commands to be atomic.
def raw_push(payloads)
@redis_pool.with do |conn| # rubocop:disable Gitlab/ModuleWithInstanceVariables
conn.pipelined do
atomic_push(conn, payloads)
end
end
true
end
end
end
end

View File

@ -2,7 +2,7 @@
module Gitlab
module Patch
module SidekiqCronPoller
module SidekiqPoller
def enqueue
Rails.application.reloader.wrap do
::Gitlab::WithRequestStore.with_request_store do

View File

@ -1,111 +0,0 @@
# frozen_string_literal: true
module Gitlab
class SidekiqEnq
LUA_ZPOPBYSCORE = <<~EOS
local key, now = KEYS[1], ARGV[1]
local jobs = redis.call("zrangebyscore", key, "-inf", now, "limit", 0, 1)
if jobs[1] then
redis.call("zrem", key, jobs[1])
return jobs[1]
end
EOS
LUA_ZPOPBYSCORE_SHA = Digest::SHA1.hexdigest(LUA_ZPOPBYSCORE)
def enqueue_jobs(now = Time.now.to_f.to_s, sorted_sets = Sidekiq::Scheduled::SETS)
Rails.application.reloader.wrap do
::Gitlab::WithRequestStore.with_request_store do
if Feature.enabled?(:atomic_sidekiq_scheduler, default_enabled: :yaml)
atomic_find_jobs_and_enqueue(now, sorted_sets)
else
find_jobs_and_enqueue(now, sorted_sets)
end
ensure
::Gitlab::Database::LoadBalancing.release_hosts
end
end
end
private
# This is a copy of https://github.com/mperham/sidekiq/blob/32c55e31659a1e6bd42f98334cca5eef2863de8d/lib/sidekiq/scheduled.rb#L11-L34
#
# It effectively reverts
# https://github.com/mperham/sidekiq/commit/9b75467b33759888753191413eddbc15c37a219e
# because we observe that the extra ZREMs caused by this change can lead to high
# CPU usage on Redis at peak times:
# https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1179
#
def find_jobs_and_enqueue(now, sorted_sets)
# A job's "score" in Redis is the time at which it should be processed.
# Just check Redis for the set of jobs with a timestamp before now.
Sidekiq.redis do |conn|
sorted_sets.each do |sorted_set|
start_time = ::Gitlab::Metrics::System.monotonic_time
jobs = redundant_jobs = 0
Sidekiq.logger.info(message: 'Enqueuing scheduled jobs', status: 'start', sorted_set: sorted_set)
# Get the next item in the queue if it's score (time to execute) is <= now.
# We need to go through the list one at a time to reduce the risk of something
# going wrong between the time jobs are popped from the scheduled queue and when
# they are pushed onto a work queue and losing the jobs.
while job = conn.zrangebyscore(sorted_set, "-inf", now, limit: [0, 1]).first
# Pop item off the queue and add it to the work queue. If the job can't be popped from
# the queue, it's because another process already popped it so we can move on to the
# next one.
if conn.zrem(sorted_set, job)
jobs += 1
Sidekiq::Client.push(Sidekiq.load_json(job))
else
redundant_jobs += 1
end
end
end_time = ::Gitlab::Metrics::System.monotonic_time
Sidekiq.logger.info(message: 'Enqueuing scheduled jobs',
status: 'done',
sorted_set: sorted_set,
jobs_count: jobs,
redundant_jobs_count: redundant_jobs,
duration_s: end_time - start_time)
end
end
end
def atomic_find_jobs_and_enqueue(now, sorted_sets)
Sidekiq.redis do |conn|
sorted_sets.each do |sorted_set|
start_time = ::Gitlab::Metrics::System.monotonic_time
jobs = 0
Sidekiq.logger.info(message: 'Atomically enqueuing scheduled jobs', status: 'start', sorted_set: sorted_set)
while job = redis_eval_lua(conn, LUA_ZPOPBYSCORE, LUA_ZPOPBYSCORE_SHA, keys: [sorted_set], argv: [now])
jobs += 1
Sidekiq::Client.push(Sidekiq.load_json(job))
end
end_time = ::Gitlab::Metrics::System.monotonic_time
Sidekiq.logger.info(message: 'Atomically enqueuing scheduled jobs',
status: 'done',
sorted_set: sorted_set,
jobs_count: jobs,
duration_s: end_time - start_time)
end
end
end
def redis_eval_lua(conn, script, sha, keys: nil, argv: nil)
conn.evalsha(sha, keys: keys, argv: argv)
rescue ::Redis::CommandError => e
if e.message.start_with?('NOSCRIPT')
conn.eval(script, keys: keys, argv: argv)
else
raise
end
end
end
end

View File

@ -0,0 +1,41 @@
# frozen_string_literal: true
module Sidebars
module Projects
module Menus
class ShimoMenu < ::Sidebars::Menu
override :link
def link
project_integrations_shimo_path(context.project)
end
override :title
def title
s_('Shimo|Shimo')
end
override :image_path
def image_path
'logos/shimo.svg'
end
override :image_html_options
def image_html_options
{
size: 16
}
end
override :render?
def render?
context.project.has_shimo?
end
override :active_routes
def active_routes
{ controller: :shimo }
end
end
end
end
end

View File

@ -32,8 +32,7 @@ module Sidebars
add_menu(Sidebars::Projects::Menus::InfrastructureMenu.new(context))
add_menu(Sidebars::Projects::Menus::PackagesRegistriesMenu.new(context))
add_menu(Sidebars::Projects::Menus::AnalyticsMenu.new(context))
add_menu(confluence_or_wiki_menu)
add_menu(Sidebars::Projects::Menus::ExternalWikiMenu.new(context))
add_wiki_menus
add_menu(Sidebars::Projects::Menus::SnippetsMenu.new(context))
add_menu(Sidebars::Projects::Menus::SettingsMenu.new(context))
add_invite_members_menu
@ -46,10 +45,16 @@ module Sidebars
end
end
def confluence_or_wiki_menu
confluence_menu = ::Sidebars::Projects::Menus::ConfluenceMenu.new(context)
def add_wiki_menus
add_menu((third_party_wiki_menu || Sidebars::Projects::Menus::WikiMenu).new(context))
add_menu(Sidebars::Projects::Menus::ExternalWikiMenu.new(context))
end
confluence_menu.render? ? confluence_menu : Sidebars::Projects::Menus::WikiMenu.new(context)
def third_party_wiki_menu
wiki_menu_list = [::Sidebars::Projects::Menus::ConfluenceMenu]
wiki_menu_list << ::Sidebars::Projects::Menus::ShimoMenu if Feature.enabled?(:shimo_integration, context.project)
wiki_menu_list.find { |wiki_menu| wiki_menu.new(context).render? }
end
end
end

View File

@ -17092,6 +17092,9 @@ msgstr ""
msgid "Hi %{username}!"
msgstr ""
msgid "Hidden"
msgstr ""
msgid "Hide"
msgstr ""
@ -31883,15 +31886,27 @@ msgstr ""
msgid "Sherlock Transactions"
msgstr ""
msgid "Shimo|Go to Shimo Workspace"
msgstr ""
msgid "Shimo|Link to a Shimo Workspace from the sidebar."
msgstr ""
msgid "Shimo|Shimo"
msgstr ""
msgid "Shimo|Shimo Workspace"
msgstr ""
msgid "Shimo|Shimo Workspace URL"
msgstr ""
msgid "Shimo|Shimo Workspace integration is enabled"
msgstr ""
msgid "Shimo|You've enabled the Shimo Workspace integration. You can view your wiki directly in Shimo."
msgstr ""
msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{boldStart}will%{boldEnd} lose access to your account."
msgstr ""

View File

@ -63,36 +63,36 @@
"@rails/ujs": "6.1.4-1",
"@sentry/browser": "5.30.0",
"@sourcegraph/code-host-integration": "0.0.60",
"@tiptap/core": "^2.0.0-beta.125",
"@tiptap/extension-blockquote": "^2.0.0-beta.19",
"@tiptap/extension-bold": "^2.0.0-beta.19",
"@tiptap/extension-bullet-list": "^2.0.0-beta.18",
"@tiptap/extension-code": "^2.0.0-beta.20",
"@tiptap/extension-code-block-lowlight": "2.0.0-beta.47",
"@tiptap/extension-document": "^2.0.0-beta.13",
"@tiptap/extension-dropcursor": "^2.0.0-beta.19",
"@tiptap/extension-gapcursor": "^2.0.0-beta.27",
"@tiptap/extension-hard-break": "^2.0.0-beta.24",
"@tiptap/extension-heading": "^2.0.0-beta.18",
"@tiptap/extension-history": "^2.0.0-beta.16",
"@tiptap/extension-horizontal-rule": "^2.0.0-beta.24",
"@tiptap/extension-image": "^2.0.0-beta.19",
"@tiptap/extension-italic": "^2.0.0-beta.19",
"@tiptap/extension-link": "^2.0.0-beta.23",
"@tiptap/extension-list-item": "^2.0.0-beta.14",
"@tiptap/extension-ordered-list": "^2.0.0-beta.19",
"@tiptap/extension-paragraph": "^2.0.0-beta.17",
"@tiptap/extension-strike": "^2.0.0-beta.21",
"@tiptap/extension-subscript": "^2.0.0-beta.4",
"@tiptap/extension-superscript": "^2.0.0-beta.4",
"@tiptap/extension-table": "^2.0.0-beta.34",
"@tiptap/extension-table-cell": "^2.0.0-beta.15",
"@tiptap/extension-table-header": "^2.0.0-beta.17",
"@tiptap/extension-table-row": "^2.0.0-beta.14",
"@tiptap/extension-task-item": "^2.0.0-beta.21",
"@tiptap/extension-task-list": "^2.0.0-beta.18",
"@tiptap/extension-text": "^2.0.0-beta.13",
"@tiptap/vue-2": "^2.0.0-beta.60",
"@tiptap/core": "^2.0.0-beta.138",
"@tiptap/extension-blockquote": "^2.0.0-beta.24",
"@tiptap/extension-bold": "^2.0.0-beta.24",
"@tiptap/extension-bullet-list": "^2.0.0-beta.23",
"@tiptap/extension-code": "^2.0.0-beta.25",
"@tiptap/extension-code-block-lowlight": "2.0.0-beta.55",
"@tiptap/extension-document": "^2.0.0-beta.15",
"@tiptap/extension-dropcursor": "^2.0.0-beta.24",
"@tiptap/extension-gapcursor": "^2.0.0-beta.33",
"@tiptap/extension-hard-break": "^2.0.0-beta.30",
"@tiptap/extension-heading": "^2.0.0-beta.23",
"@tiptap/extension-history": "^2.0.0-beta.21",
"@tiptap/extension-horizontal-rule": "^2.0.0-beta.30",
"@tiptap/extension-image": "^2.0.0-beta.24",
"@tiptap/extension-italic": "^2.0.0-beta.24",
"@tiptap/extension-link": "^2.0.0-beta.28",
"@tiptap/extension-list-item": "^2.0.0-beta.19",
"@tiptap/extension-ordered-list": "^2.0.0-beta.24",
"@tiptap/extension-paragraph": "^2.0.0-beta.22",
"@tiptap/extension-strike": "^2.0.0-beta.26",
"@tiptap/extension-subscript": "^2.0.0-beta.9",
"@tiptap/extension-superscript": "^2.0.0-beta.9",
"@tiptap/extension-table": "^2.0.0-beta.42",
"@tiptap/extension-table-cell": "^2.0.0-beta.20",
"@tiptap/extension-table-header": "^2.0.0-beta.22",
"@tiptap/extension-table-row": "^2.0.0-beta.19",
"@tiptap/extension-task-item": "^2.0.0-beta.28",
"@tiptap/extension-task-list": "^2.0.0-beta.23",
"@tiptap/extension-text": "^2.0.0-beta.15",
"@tiptap/vue-2": "^2.0.0-beta.68",
"@toast-ui/editor": "^2.5.2",
"@toast-ui/vue-editor": "^2.5.2",
"apollo-cache-inmemory": "^1.6.6",
@ -162,10 +162,10 @@
"portal-vue": "^2.1.7",
"prismjs": "^1.21.0",
"prosemirror-markdown": "^1.6.0",
"prosemirror-model": "^1.14.3",
"prosemirror-model": "^1.15.0",
"prosemirror-state": "^1.3.4",
"prosemirror-tables": "^1.1.1",
"prosemirror-view": "^1.20.3",
"prosemirror-view": "^1.23.1",
"raphael": "^2.2.7",
"raw-loader": "^4.0.2",
"scrollparent": "^2.0.1",

View File

@ -28,7 +28,6 @@ import TableHeader from '~/content_editor/extensions/table_header';
import TableRow from '~/content_editor/extensions/table_row';
import TaskItem from '~/content_editor/extensions/task_item';
import TaskList from '~/content_editor/extensions/task_list';
import Text from '~/content_editor/extensions/text';
import markdownSerializer from '~/content_editor/services/markdown_serializer';
import { createTestEditor, createDocBuilder } from '../test_utils';
@ -58,7 +57,6 @@ const tiptapEditor = createTestEditor({
Link,
ListItem,
OrderedList,
Paragraph,
Strike,
Table,
TableCell,
@ -66,7 +64,6 @@ const tiptapEditor = createTestEditor({
TableRow,
TaskItem,
TaskList,
Text,
],
});

View File

@ -32,6 +32,8 @@ describe('dropzone_input', () => {
});
describe('handlePaste', () => {
let form;
const triggerPasteEvent = (clipboardData = {}) => {
const event = $.Event('paste');
const origEvent = new Event('paste');
@ -45,11 +47,15 @@ describe('dropzone_input', () => {
beforeEach(() => {
loadFixtures('issues/new-issue.html');
const form = $('#new_issue');
form = $('#new_issue');
form.data('uploads-path', TEST_UPLOAD_PATH);
dropzoneInput(form);
});
afterEach(() => {
form = null;
});
it('pastes Markdown tables', () => {
jest.spyOn(PasteMarkdownTable.prototype, 'isTable');
jest.spyOn(PasteMarkdownTable.prototype, 'convertToTableMarkdown');
@ -86,6 +92,27 @@ describe('dropzone_input', () => {
expect(axiosMock.history.post[0].data.get('file').name).toHaveLength(246);
});
it('disables generated image file when clipboardData have both image and text', () => {
const TEST_PLAIN_TEXT = 'This wording is a plain text.';
triggerPasteEvent({
types: ['text/plain', 'Files'],
getData: () => TEST_PLAIN_TEXT,
items: [
{
kind: 'text',
type: 'text/plain',
},
{
kind: 'file',
type: 'image/png',
getAsFile: () => new Blob(),
},
],
});
expect(form.find('.js-gfm-input')[0].value).toBe('');
});
it('display original file name in comment box', async () => {
const axiosMock = new MockAdapter(axios);
triggerPasteEvent({

View File

@ -1,19 +1,25 @@
import { GlLink, GlLabel, GlIcon, GlFormCheckbox, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { useFakeDate } from 'helpers/fake_date';
import { shallowMountExtended as shallowMount } from 'helpers/vue_test_utils_helper';
import IssuableItem from '~/issuable_list/components/issuable_item.vue';
import IssuableAssignees from '~/vue_shared/components/issue/issue_assignees.vue';
import { mockIssuable, mockRegularLabel, mockScopedLabel } from '../mock_data';
const createComponent = ({ issuableSymbol = '#', issuable = mockIssuable, slots = {} } = {}) =>
const createComponent = ({
issuableSymbol = '#',
issuable = mockIssuable,
enableLabelPermalinks = true,
showCheckbox = true,
slots = {},
} = {}) =>
shallowMount(IssuableItem, {
propsData: {
issuableSymbol,
issuable,
enableLabelPermalinks: true,
enableLabelPermalinks,
showDiscussions: true,
showCheckbox: false,
showCheckbox,
},
slots,
stubs: {
@ -34,7 +40,6 @@ describe('IssuableItem', () => {
beforeEach(() => {
gon.gitlab_url = MOCK_GITLAB_URL;
wrapper = createComponent();
});
afterEach(() => {
@ -45,6 +50,8 @@ describe('IssuableItem', () => {
describe('computed', () => {
describe('author', () => {
it('returns `issuable.author` reference', () => {
wrapper = createComponent();
expect(wrapper.vm.author).toEqual(mockIssuable.author);
});
});
@ -59,7 +66,7 @@ describe('IssuableItem', () => {
`(
'returns $returnValue when value of `issuable.author.id` is $authorId',
async ({ authorId, returnValue }) => {
wrapper.setProps({
wrapper = createComponent({
issuable: {
...mockIssuable,
author: {
@ -86,7 +93,7 @@ describe('IssuableItem', () => {
`(
'returns $returnValue when `issuable.webUrl` is $urlType',
async ({ issuableWebUrl, returnValue }) => {
wrapper.setProps({
wrapper = createComponent({
issuable: {
...mockIssuable,
webUrl: issuableWebUrl,
@ -102,11 +109,13 @@ describe('IssuableItem', () => {
describe('labels', () => {
it('returns `issuable.labels.nodes` reference when it is available', () => {
wrapper = createComponent();
expect(wrapper.vm.labels).toEqual(mockLabels);
});
it('returns `issuable.labels` reference when it is available', async () => {
wrapper.setProps({
wrapper = createComponent({
issuable: {
...mockIssuable,
labels: mockLabels,
@ -119,7 +128,7 @@ describe('IssuableItem', () => {
});
it('returns empty array when none of `issuable.labels.nodes` or `issuable.labels` are available', async () => {
wrapper.setProps({
wrapper = createComponent({
issuable: {
...mockIssuable,
labels: null,
@ -134,12 +143,16 @@ describe('IssuableItem', () => {
describe('assignees', () => {
it('returns `issuable.assignees` reference when it is available', () => {
wrapper = createComponent();
expect(wrapper.vm.assignees).toBe(mockIssuable.assignees);
});
});
describe('updatedAt', () => {
it('returns string containing timeago string based on `issuable.updatedAt`', () => {
wrapper = createComponent();
expect(wrapper.vm.updatedAt).toContain('updated');
expect(wrapper.vm.updatedAt).toContain('ago');
});
@ -155,7 +168,7 @@ describe('IssuableItem', () => {
`(
'returns $returnValue when issuable.userDiscussionsCount is $userDiscussionsCount',
({ userDiscussionsCount, returnValue }) => {
const wrapperWithDiscussions = createComponent({
wrapper = createComponent({
issuableSymbol: '#',
issuable: {
...mockIssuable,
@ -163,9 +176,7 @@ describe('IssuableItem', () => {
},
});
expect(wrapperWithDiscussions.vm.showDiscussions).toBe(returnValue);
wrapperWithDiscussions.destroy();
expect(wrapper.findByTestId('issuable-discussions').exists()).toBe(returnValue);
},
);
});
@ -180,6 +191,8 @@ describe('IssuableItem', () => {
`(
'return $returnValue when provided label param is a $labelType label',
({ label, returnValue }) => {
wrapper = createComponent();
expect(wrapper.vm.scopedLabel(label)).toBe(returnValue);
},
);
@ -191,19 +204,23 @@ describe('IssuableItem', () => {
${{ title: 'foo' }} | ${'title'} | ${'foo'}
${{ name: 'foo' }} | ${'name'} | ${'foo'}
`('returns string value of `label.$propWithTitle`', ({ label, returnValue }) => {
wrapper = createComponent();
expect(wrapper.vm.labelTitle(label)).toBe(returnValue);
});
});
describe('labelTarget', () => {
it('returns target string for a provided label param when `enableLabelPermalinks` is true', () => {
wrapper = createComponent();
expect(wrapper.vm.labelTarget(mockRegularLabel)).toBe(
'?label_name[]=Documentation%20Update',
);
});
it('returns string "#" for a provided label param when `enableLabelPermalinks` is false', async () => {
wrapper.setProps({
wrapper = createComponent({
enableLabelPermalinks: false,
});
@ -223,7 +240,7 @@ describe('IssuableItem', () => {
`(
'renders issuable title correctly when `gitlabWebUrl` is `$gitlabWebUrl` and webUrl is `$webUrl`',
async ({ webUrl, gitlabWebUrl, expectedHref, expectedTarget }) => {
wrapper.setProps({
wrapper = createComponent({
issuable: {
...mockIssuable,
webUrl,
@ -243,7 +260,7 @@ describe('IssuableItem', () => {
);
it('renders checkbox when `showCheckbox` prop is true', async () => {
wrapper.setProps({
wrapper = createComponent({
showCheckbox: true,
});
@ -262,7 +279,7 @@ describe('IssuableItem', () => {
});
it('renders issuable title with `target` set as "_blank" when issuable.webUrl is external', async () => {
wrapper.setProps({
wrapper = createComponent({
issuable: {
...mockIssuable,
webUrl: 'http://jira.atlassian.net/browse/IG-1',
@ -277,7 +294,7 @@ describe('IssuableItem', () => {
});
it('renders issuable confidential icon when issuable is confidential', async () => {
wrapper.setProps({
wrapper = createComponent({
issuable: {
...mockIssuable,
confidential: true,
@ -296,7 +313,21 @@ describe('IssuableItem', () => {
});
});
it('renders spam icon when issuable is hidden', async () => {
wrapper = createComponent({ issuable: { ...mockIssuable, hidden: true } });
const hiddenIcon = wrapper.findComponent(GlIcon);
expect(hiddenIcon.props('name')).toBe('spam');
expect(hiddenIcon.attributes()).toMatchObject({
title: 'This issue is hidden because its author has been banned',
arialabel: 'Hidden',
});
});
it('renders task status', () => {
wrapper = createComponent();
const taskStatus = wrapper.find('[data-testid="task-status"]');
const expected = `${mockIssuable.taskCompletionStatus.completedCount} of ${mockIssuable.taskCompletionStatus.count} tasks completed`;
@ -304,6 +335,8 @@ describe('IssuableItem', () => {
});
it('renders issuable reference', () => {
wrapper = createComponent();
const referenceEl = wrapper.find('[data-testid="issuable-reference"]');
expect(referenceEl.exists()).toBe(true);
@ -311,7 +344,7 @@ describe('IssuableItem', () => {
});
it('renders issuable reference via slot', () => {
const wrapperWithRefSlot = createComponent({
wrapper = createComponent({
issuableSymbol: '#',
issuable: mockIssuable,
slots: {
@ -320,15 +353,15 @@ describe('IssuableItem', () => {
`,
},
});
const referenceEl = wrapperWithRefSlot.find('.js-reference');
const referenceEl = wrapper.find('.js-reference');
expect(referenceEl.exists()).toBe(true);
expect(referenceEl.text()).toBe(`${mockIssuable.iid}`);
wrapperWithRefSlot.destroy();
});
it('renders issuable createdAt info', () => {
wrapper = createComponent();
const createdAtEl = wrapper.find('[data-testid="issuable-created-at"]');
expect(createdAtEl.exists()).toBe(true);
@ -337,6 +370,8 @@ describe('IssuableItem', () => {
});
it('renders issuable author info', () => {
wrapper = createComponent();
const authorEl = wrapper.find('[data-testid="issuable-author"]');
expect(authorEl.exists()).toBe(true);
@ -351,7 +386,7 @@ describe('IssuableItem', () => {
});
it('renders issuable author info via slot', () => {
const wrapperWithAuthorSlot = createComponent({
wrapper = createComponent({
issuableSymbol: '#',
issuable: mockIssuable,
slots: {
@ -360,16 +395,14 @@ describe('IssuableItem', () => {
`,
},
});
const authorEl = wrapperWithAuthorSlot.find('.js-author');
const authorEl = wrapper.find('.js-author');
expect(authorEl.exists()).toBe(true);
expect(authorEl.text()).toBe(mockAuthor.name);
wrapperWithAuthorSlot.destroy();
});
it('renders timeframe via slot', () => {
const wrapperWithTimeframeSlot = createComponent({
wrapper = createComponent({
issuableSymbol: '#',
issuable: mockIssuable,
slots: {
@ -378,15 +411,15 @@ describe('IssuableItem', () => {
`,
},
});
const timeframeEl = wrapperWithTimeframeSlot.find('.js-timeframe');
const timeframeEl = wrapper.find('.js-timeframe');
expect(timeframeEl.exists()).toBe(true);
expect(timeframeEl.text()).toBe('Jan 1, 2020 - Mar 31, 2020');
wrapperWithTimeframeSlot.destroy();
});
it('renders gl-label component for each label present within `issuable` prop', () => {
wrapper = createComponent();
const labelsEl = wrapper.findAll(GlLabel);
expect(labelsEl.exists()).toBe(true);
@ -402,7 +435,7 @@ describe('IssuableItem', () => {
});
it('renders issuable status via slot', () => {
const wrapperWithStatusSlot = createComponent({
wrapper = createComponent({
issuableSymbol: '#',
issuable: mockIssuable,
slots: {
@ -411,15 +444,15 @@ describe('IssuableItem', () => {
`,
},
});
const statusEl = wrapperWithStatusSlot.find('.js-status');
const statusEl = wrapper.find('.js-status');
expect(statusEl.exists()).toBe(true);
expect(statusEl.text()).toBe(`${mockIssuable.state}`);
wrapperWithStatusSlot.destroy();
});
it('renders discussions count', () => {
wrapper = createComponent();
const discussionsEl = wrapper.find('[data-testid="issuable-discussions"]');
expect(discussionsEl.exists()).toBe(true);
@ -432,6 +465,8 @@ describe('IssuableItem', () => {
});
it('renders issuable-assignees component', () => {
wrapper = createComponent();
const assigneesEl = wrapper.find(IssuableAssignees);
expect(assigneesEl.exists()).toBe(true);
@ -443,6 +478,8 @@ describe('IssuableItem', () => {
});
it('renders issuable updatedAt info', () => {
wrapper = createComponent();
const updatedAtEl = wrapper.find('[data-testid="issuable-updated-at"]');
expect(updatedAtEl.attributes('title')).toBe('Sep 10, 2020 11:41am UTC');

View File

@ -17,7 +17,7 @@ import {
locationSearch,
urlParams,
} from 'jest/issues_list/mock_data';
import createFlash from '~/flash';
import createFlash, { FLASH_TYPES } from '~/flash';
import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue';
import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
@ -29,6 +29,8 @@ import {
CREATED_DESC,
DUE_DATE_OVERDUE,
PARAM_DUE_DATE,
RELATIVE_POSITION,
RELATIVE_POSITION_ASC,
TOKEN_TYPE_ASSIGNEE,
TOKEN_TYPE_AUTHOR,
TOKEN_TYPE_CONFIDENTIAL,
@ -314,6 +316,29 @@ describe('IssuesListApp component', () => {
},
});
});
describe('when issue repositioning is disabled and the sort is manual', () => {
beforeEach(() => {
setWindowLocation(`?sort=${RELATIVE_POSITION}`);
wrapper = mountComponent({ provide: { isIssueRepositioningDisabled: true } });
});
it('changes the sort to the default of created descending', () => {
expect(findIssuableList().props()).toMatchObject({
initialSortBy: CREATED_DESC,
urlParams: {
sort: urlSortParams[CREATED_DESC],
},
});
});
it('shows an alert to tell the user that manual reordering is disabled', () => {
expect(createFlash).toHaveBeenCalledWith({
message: IssuesListApp.i18n.issueRepositioningMessage,
type: FLASH_TYPES.NOTICE,
});
});
});
});
describe('state', () => {
@ -762,6 +787,30 @@ describe('IssuesListApp component', () => {
});
},
);
describe('when issue repositioning is disabled', () => {
const initialSort = CREATED_DESC;
beforeEach(() => {
setWindowLocation(`?sort=${initialSort}`);
wrapper = mountComponent({ provide: { isIssueRepositioningDisabled: true } });
findIssuableList().vm.$emit('sort', RELATIVE_POSITION_ASC);
});
it('does not update the sort to manual', () => {
expect(findIssuableList().props('urlParams')).toMatchObject({
sort: urlSortParams[initialSort],
});
});
it('shows an alert to tell the user that manual reordering is disabled', () => {
expect(createFlash).toHaveBeenCalledWith({
message: IssuesListApp.i18n.issueRepositioningMessage,
type: FLASH_TYPES.NOTICE,
});
});
});
});
describe('when "update-legacy-bulk-edit" event is emitted by IssuableList', () => {

View File

@ -22,6 +22,7 @@ export const getIssuesQueryResponse = {
createdAt: '2021-05-22T04:08:01Z',
downvotes: 2,
dueDate: '2021-05-29',
hidden: false,
humanTimeEstimate: null,
mergeRequestsCount: false,
moved: false,

View File

@ -6,7 +6,7 @@ exports[`packages_list_row renders 1`] = `
data-qa-selector="package_row"
>
<div
class="gl-display-flex gl-align-items-center gl-py-3 gl-px-5"
class="gl-display-flex gl-align-items-center gl-py-3"
>
<!---->

View File

@ -5,7 +5,7 @@ exports[`VersionRow renders 1`] = `
class="gl-display-flex gl-flex-direction-column gl-border-b-solid gl-border-t-solid gl-border-t-1 gl-border-b-1 gl-border-t-transparent gl-border-b-gray-100"
>
<div
class="gl-display-flex gl-align-items-center gl-py-3 gl-px-5"
class="gl-display-flex gl-align-items-center gl-py-3"
>
<!---->

View File

@ -6,7 +6,7 @@ exports[`packages_list_row renders 1`] = `
data-qa-selector="package_row"
>
<div
class="gl-display-flex gl-align-items-center gl-py-3 gl-px-5"
class="gl-display-flex gl-align-items-center gl-py-3"
>
<!---->

View File

@ -302,6 +302,7 @@ RSpec.describe IssuesHelper do
allow(helper).to receive(:can?).and_return(true)
allow(helper).to receive(:image_path).and_return('#')
allow(helper).to receive(:import_csv_namespace_project_issues_path).and_return('#')
allow(helper).to receive(:issue_repositioning_disabled?).and_return(true)
allow(helper).to receive(:url_for).and_return('#')
expected = {
@ -318,6 +319,7 @@ RSpec.describe IssuesHelper do
has_any_issues: project_issues(project).exists?.to_s,
import_csv_issues_path: '#',
initial_email: project.new_issuable_address(current_user, 'issue'),
is_issue_repositioning_disabled: 'true',
is_project: 'true',
is_signed_in: current_user.present?.to_s,
jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'),

View File

@ -1,93 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::SidekiqEnq, :clean_gitlab_redis_queues do
let(:retry_set) { Sidekiq::Scheduled::SETS.first }
let(:schedule_set) { Sidekiq::Scheduled::SETS.last }
around do |example|
freeze_time { example.run }
end
shared_examples 'finds jobs that are due and enqueues them' do
before do
Sidekiq.redis do |redis|
redis.zadd(retry_set, (Time.current - 1.day).to_f.to_s, '{"jid": 1}')
redis.zadd(retry_set, Time.current.to_f.to_s, '{"jid": 2}')
redis.zadd(retry_set, (Time.current + 1.day).to_f.to_s, '{"jid": 3}')
redis.zadd(schedule_set, (Time.current - 1.day).to_f.to_s, '{"jid": 4}')
redis.zadd(schedule_set, Time.current.to_f.to_s, '{"jid": 5}')
redis.zadd(schedule_set, (Time.current + 1.day).to_f.to_s, '{"jid": 6}')
end
end
it 'enqueues jobs that are due' do
expect(Sidekiq::Client).to receive(:push).with({ 'jid' => 1 })
expect(Sidekiq::Client).to receive(:push).with({ 'jid' => 2 })
expect(Sidekiq::Client).to receive(:push).with({ 'jid' => 4 })
expect(Sidekiq::Client).to receive(:push).with({ 'jid' => 5 })
Gitlab::SidekiqEnq.new.enqueue_jobs
Sidekiq.redis do |redis|
expect(redis.zscan_each(retry_set).map(&:first)).to contain_exactly('{"jid": 3}')
expect(redis.zscan_each(schedule_set).map(&:first)).to contain_exactly('{"jid": 6}')
end
end
end
context 'when atomic_sidekiq_scheduler is disabled' do
before do
stub_feature_flags(atomic_sidekiq_scheduler: false)
end
it_behaves_like 'finds jobs that are due and enqueues them'
context 'when ZRANGEBYSCORE returns a job that is already removed by another process' do
before do
Sidekiq.redis do |redis|
redis.zadd(schedule_set, Time.current.to_f.to_s, '{"jid": 1}')
allow(redis).to receive(:zrangebyscore).and_wrap_original do |m, *args, **kwargs|
m.call(*args, **kwargs).tap do |jobs|
redis.zrem(schedule_set, jobs.first) if args[0] == schedule_set && jobs.first
end
end
end
end
it 'calls ZREM but does not enqueue the job' do
Sidekiq.redis do |redis|
expect(redis).to receive(:zrem).with(schedule_set, '{"jid": 1}').twice.and_call_original
end
expect(Sidekiq::Client).not_to receive(:push)
Gitlab::SidekiqEnq.new.enqueue_jobs
end
end
end
context 'when atomic_sidekiq_scheduler is enabled' do
before do
stub_feature_flags(atomic_sidekiq_scheduler: true)
end
context 'when Lua script is not yet loaded' do
before do
Gitlab::Redis::Queues.with { |redis| redis.script(:flush) }
end
it_behaves_like 'finds jobs that are due and enqueues them'
end
context 'when Lua script is already loaded' do
before do
Gitlab::SidekiqEnq.new.enqueue_jobs
end
it_behaves_like 'finds jobs that are due and enqueues them'
end
end
end

View File

@ -0,0 +1,44 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Sidebars::Projects::Menus::ShimoMenu do
let_it_be_with_reload(:project) { create(:project) }
let(:context) { Sidebars::Projects::Context.new(current_user: project.owner, container: project) }
subject(:shimo_menu) { described_class.new(context) }
describe '#render?' do
context 'without a valid Shimo integration' do
it "doesn't render the menu" do
expect(shimo_menu.render?).to be_falsey
end
end
context 'with a valid Shimo integration' do
let_it_be_with_reload(:shimo_integration) { create(:shimo_integration, project: project) }
context 'when integration is active' do
it 'renders the menu' do
expect(shimo_menu.render?).to eq true
end
it 'renders menu link' do
expected_url = Rails.application.routes.url_helpers.project_integrations_shimo_path(project)
expect(shimo_menu.link).to eq expected_url
end
end
context 'when integration is inactive' do
before do
shimo_integration.update!(active: false)
end
it "doesn't render the menu" do
expect(shimo_menu.render?).to eq false
end
end
end
end
end

View File

@ -38,4 +38,26 @@ RSpec.describe ::Integrations::Shimo do
end
end
end
describe 'Caching has_shimo on project_settings' do
let(:project) { create(:project) }
subject { project.project_setting.has_shimo? }
it 'sets the property to true when integration is active' do
create(:shimo_integration, project: project, active: true)
is_expected.to be(true)
end
it 'sets the property to false when integration is not active' do
create(:shimo_integration, project: project, active: false)
is_expected.to be(false)
end
it 'creates a project_setting record if one was not already created' do
expect { create(:shimo_integration) }.to change(ProjectSetting, :count).by(1)
end
end
end

View File

@ -0,0 +1,37 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ::Projects::Integrations::ShimosController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user, developer_projects: [project]) }
let_it_be(:shimo_integration) { create(:shimo_integration, project: project) }
before do
sign_in(user)
end
describe 'GET #show' do
context 'when Shimo integration is inactive' do
before do
shimo_integration.update!(active: false)
end
it 'returns 404 status' do
get project_integrations_shimo_path(project)
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'when Shimo integration is active' do
it 'renders the "show" template' do
get project_integrations_shimo_path(project)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:show)
expect(response.body).to include shimo_integration.external_wiki_url
end
end
end
end

344
yarn.lock
View File

@ -1491,223 +1491,223 @@
dom-accessibility-api "^0.5.1"
pretty-format "^26.4.2"
"@tiptap/core@^2.0.0-beta.125":
version "2.0.0-beta.125"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.125.tgz#672a86f21727614bfe8d5bf41544ce83ea4a7c87"
integrity sha512-I3lju5hcjK6nhC29jJCdGoRdP0C5nPBHGN8y/fbFmCX0oQ/THuzVdMgaGPpkHjralPPMS3DqHD/Rx8Kbo8zClg==
"@tiptap/core@^2.0.0-beta.138":
version "2.0.0-beta.138"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.138.tgz#3a73b32b10f07ba2842142552457b52abf8cfc41"
integrity sha512-Cg3ig6c+NCBILYaVNf5h8vJdsRynhKzy+zQzH/91kLoWzpNV5J6R2sW32Oufuwvr0Kra1+kKKh/WIGpB3Ia4RA==
dependencies:
"@types/prosemirror-commands" "^1.0.4"
"@types/prosemirror-keymap" "^1.0.4"
"@types/prosemirror-model" "^1.13.2"
"@types/prosemirror-schema-list" "^1.0.3"
"@types/prosemirror-state" "^1.2.7"
"@types/prosemirror-state" "^1.2.8"
"@types/prosemirror-transform" "^1.1.4"
"@types/prosemirror-view" "^1.19.1"
prosemirror-commands "^1.1.11"
prosemirror-keymap "^1.1.3"
prosemirror-model "^1.14.3"
prosemirror-commands "^1.1.12"
prosemirror-keymap "^1.1.5"
prosemirror-model "^1.15.0"
prosemirror-schema-list "^1.1.6"
prosemirror-state "^1.3.4"
prosemirror-transform "^1.3.3"
prosemirror-view "^1.20.3"
prosemirror-view "^1.22.0"
"@tiptap/extension-blockquote@^2.0.0-beta.19":
version "2.0.0-beta.19"
resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.19.tgz#4b1dfd0ec511f889ddb0f34cd09e57a0db877dc0"
integrity sha512-9y8keXSm4E5mdh/EocdbrJ/H71qyXv2jajRHIsXj1SaJqLaz4JbSQGrX3j2r0ia3KW3YNFFIHl/z33fU70YfGQ==
"@tiptap/extension-blockquote@^2.0.0-beta.24":
version "2.0.0-beta.24"
resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.24.tgz#4dcaf676ded8c3b551efd8f2d6b51cc882ba7d03"
integrity sha512-u9D/ZOziO4rMBKeLj7JA7fOc9h8wU6zrzVEsX9MbJwmuicoJZ1lIQ9cyrFWwmlfznzuXLaAxm3iZuHt7xxMppQ==
"@tiptap/extension-bold@^2.0.0-beta.19":
version "2.0.0-beta.19"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.19.tgz#9426b5fcb2bfb79082f9efefbafff955d26d023e"
integrity sha512-pbYMK3Lz78XFi+1OisdjuGQcjRnzHXeYivh9A4xP1fmSOS6t/lQsu2P2uDhFNXtz45dLcLTOkqnE0j5lj3TGMg==
"@tiptap/extension-bold@^2.0.0-beta.24":
version "2.0.0-beta.24"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.24.tgz#a8d1076922580db528cc6988fde08f731dcfe733"
integrity sha512-2VTCtY2JI0wpDwWT0a2fMFkjbgxDpwD3wvtY3/ndh5pyNX0JQCXtJarFzfZZurWvLNQ8QPRRel73182RBYUOHQ==
"@tiptap/extension-bubble-menu@^2.0.0-beta.42":
version "2.0.0-beta.42"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.42.tgz#40c2783860721e861b3eb11aa2a076d1944058c2"
integrity sha512-H+pGpSk0mK4BRm4RbevgT+ir1bEwlS1dEwi2YIPYVl+JSpuGS2P1jTWeZpCou9cewNuxxwrAarhp4aEvJrL8UQ==
"@tiptap/extension-bubble-menu@^2.0.0-beta.49":
version "2.0.0-beta.49"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.49.tgz#f9863b1abad5f87d298d4e6527005484137a6166"
integrity sha512-JbaSG3otBuMKRyTn0OqVscZnwqJ7c+qyKAnoZJit5EK1RS72cTfGWZvvAxaslAM4DeE9avJeudUi/tN5Iafv4A==
dependencies:
prosemirror-state "^1.3.4"
prosemirror-view "^1.20.3"
tippy.js "^6.3.2"
prosemirror-view "^1.22.0"
tippy.js "^6.3.6"
"@tiptap/extension-bullet-list@^2.0.0-beta.18":
version "2.0.0-beta.18"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.18.tgz#ab33426a3ea03cea11863e44aad9e48fc18d478c"
integrity sha512-dOf2Wx9bmgpBQIxhw7b+g1GhbIyIox7FIiIEkkSgqDtx8wPPYlnGwHRxopj4a57VbqRkRtspJZp52/vhP3is5w==
"@tiptap/extension-bullet-list@^2.0.0-beta.23":
version "2.0.0-beta.23"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.23.tgz#64698c98039ad301c94a9041bbd117e82957be21"
integrity sha512-ReoUiz9f1IX87RX+GRE+fCaLEzNNwmiP4kli3QH8/qrLK3qxvZYr9N31fUeOHecCctUofPSbQB79B39zSo9Ouw==
"@tiptap/extension-code-block-lowlight@2.0.0-beta.47":
version "2.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.0.0-beta.47.tgz#2a3253f778375e4a420dd77967931b4da7926913"
integrity sha512-+k0uACctl4PIrZQrZkiPapYL/Uq8Skc6gBhlvtJ3+U9+U798Rm7QZpGxEe9iXW4KC69E4LtD1JNj27Ofns35Cg==
"@tiptap/extension-code-block-lowlight@2.0.0-beta.55":
version "2.0.0-beta.55"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.0.0-beta.55.tgz#7ea0a9a64c1cf69514b359dcb0dbeb130afa2976"
integrity sha512-1Ckq4d3Q0EeEXlIX6QcHcHylvCEg2uj/BZ4jvclHc5rLYC1NndiwRoM5wkjj9xZ3WQHDHN405ocgFk+yUvID6g==
dependencies:
"@tiptap/extension-code-block" "^2.0.0-beta.24"
"@tiptap/extension-code-block" "^2.0.0-beta.29"
"@types/lowlight" "^0.0.3"
lowlight "^1.20.0"
prosemirror-model "^1.14.3"
prosemirror-model "^1.15.0"
prosemirror-state "^1.3.4"
prosemirror-view "^1.20.3"
prosemirror-view "^1.22.0"
"@tiptap/extension-code-block@^2.0.0-beta.24":
version "2.0.0-beta.24"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.24.tgz#f3d45d4ae0cdc2bf94ed5e61a5421c72b2bd3a53"
integrity sha512-Q6KxBe3FB+dMe/prlfeixXSVqGTmnOmIL2/10B1RzSj7Mj9SgzqQEHZFm3dKVqpYuMOYJ6S6edkW33E0Wq9ahQ==
"@tiptap/extension-code-block@^2.0.0-beta.29":
version "2.0.0-beta.29"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.29.tgz#ad7f537bc1f12decf027d66c7328f36a8b07795c"
integrity sha512-IoBJxqZ4F7dApRL3NisvMCBJmzpV0LmfJlFQacgm64Li15dP/QyDuvXpku03gT3y9e4f9Gv/KTKwJizXEVABhw==
dependencies:
prosemirror-state "^1.3.4"
"@tiptap/extension-code@^2.0.0-beta.20":
version "2.0.0-beta.20"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.0.0-beta.20.tgz#0f5ff7e827ae09c26d23ddc9e62f6375d2f1c0f8"
integrity sha512-25twg/rsg5CxTOfDgYzg1GbwrtdzNX2vCQyYsauXfPI1kbrWXdVBYWeL4iHdJk5WElfH9WUbQ4kMGh13/KCG/g==
"@tiptap/extension-code@^2.0.0-beta.25":
version "2.0.0-beta.25"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.0.0-beta.25.tgz#055dc8dc6d19d3f0439f57dd8ba6433e2f2fd733"
integrity sha512-kXBR4Zp79lpUEfqJtBGv9tO1mj9jFQLMj0iVhj8e8ZporNKei5JfDOY83kwFcKAE60i7tiRDtV3OizpAKMeqDg==
"@tiptap/extension-document@^2.0.0-beta.13":
version "2.0.0-beta.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.0.0-beta.13.tgz#8cfb29d4de64bf4a790817f730c05b4f9b7167b2"
integrity sha512-nrufdKziA/wovaY4DjGkc8OGuIZi8CH8CW3+yYfeWbruwFKkyZHlZy9nplFWSEqBHPAeqD+px9r91yGMW3ontA==
"@tiptap/extension-document@^2.0.0-beta.15":
version "2.0.0-beta.15"
resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.0.0-beta.15.tgz#5d17a0289244a913ab2ef08e8495a1e46950711e"
integrity sha512-ypENC+xUYD5m2t+KOKNYqyXnanXd5fxyIyhR1qeEEwwQwMXGNrO3kCH6O4mIDCpy+/WqHvVay2tV5dVsXnvY8w==
"@tiptap/extension-dropcursor@^2.0.0-beta.19":
version "2.0.0-beta.19"
resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.0-beta.19.tgz#8a37ffe27e484eb44dd18297830d1fd8ce0c50ce"
integrity sha512-rslIcVvD42NNh5sEbkCkG03DWMFBrS5KoK+lDOdIcC1DjmTtpVgcLvvE01btzaB3ljx+UVqI2Zaxa6VOiTeEMw==
"@tiptap/extension-dropcursor@^2.0.0-beta.24":
version "2.0.0-beta.24"
resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.0-beta.24.tgz#e0263c8d784304cb885aea299bfd5255d3435765"
integrity sha512-B4bzY84g82VY78kv6BFNSCgO9Sc3dtgkvzFDJ57X2QweYyLkXbYeZxI8SqO7Nva1QRZadBlFyRPm+aP1rLZsew==
dependencies:
"@types/prosemirror-dropcursor" "^1.0.3"
prosemirror-dropcursor "^1.3.5"
"@tiptap/extension-floating-menu@^2.0.0-beta.36":
version "2.0.0-beta.36"
resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.36.tgz#313082e2dd22b6b20c81aa4e98f7c9bcfd47ebe7"
integrity sha512-Pm9KK+Y7YUgMrlvqa/MgxV0WOTBiOp8d2kpt7OwGv/ahjc4amv0HFbei7glsiJ56VtOv8lsjiuBS+m2ctWHWVQ==
"@tiptap/extension-floating-menu@^2.0.0-beta.44":
version "2.0.0-beta.44"
resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.44.tgz#fca9eefd9bcc74fdf035b012b9eb9fbfda331cf1"
integrity sha512-R8EF6XXlwoiHvCuXV3qGsEKae5u0OYrKHJNeOgau5SANg/ab+pjFzr3Lrt43NFpOKf5rzD3p2OJxnikudceLSg==
dependencies:
prosemirror-state "^1.3.4"
prosemirror-view "^1.20.3"
tippy.js "^6.3.2"
prosemirror-view "^1.22.0"
tippy.js "^6.3.6"
"@tiptap/extension-gapcursor@^2.0.0-beta.27":
version "2.0.0-beta.27"
resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.27.tgz#ced6cb7d39a388e60f8ec22889a015beb81b417a"
integrity sha512-Sk041ygN+PhAGiCnDfEtFl8sFmm+clKTHJZJwb6ixcdfgY9xkTpkrgswsAY5fvLnLxZUJvZSDOrsvysbh6M2MQ==
"@tiptap/extension-gapcursor@^2.0.0-beta.33":
version "2.0.0-beta.33"
resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.33.tgz#99414204e61655d4df61efc27823732176719532"
integrity sha512-Yu6BJ1bseyXIgLlcw/2R/2wWe1mIQilMwW7hhfDJPLbFwLJrMINtA9hxd2qY7mtW19/CveT5HOihQS6QEk59iw==
dependencies:
"@types/prosemirror-gapcursor" "^1.0.4"
prosemirror-gapcursor "^1.2.0"
"@tiptap/extension-hard-break@^2.0.0-beta.24":
version "2.0.0-beta.24"
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.24.tgz#8518cf253c24a316824fdac41ffe195fe934bfb2"
integrity sha512-0oEHUlQKQZRQmrbKARFPBVVRBWdekR27ro+qg+T6nzEHYSRkJ7dWBswGSNul1v1XEp52JqniZ3el0w1xdYMR0w==
"@tiptap/extension-hard-break@^2.0.0-beta.30":
version "2.0.0-beta.30"
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.30.tgz#165494f1194a7bad08907e6d64d349dd15851b72"
integrity sha512-X9xj/S+CikrbIE7ccUFVwit5QHEbflnKVxod+4zPwr1cxogFbE9AyLZE2MpYdx3z9LcnTYYi9leBqFrP4T/Olw==
"@tiptap/extension-heading@^2.0.0-beta.18":
version "2.0.0-beta.18"
resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.18.tgz#ffaee32ab0286ac047a3f38a52f870538155e30c"
integrity sha512-JJtB1pNHkqC9z/z/6B+xQpDd1w5EaLp++yG8eoY9NCq3ZCRhwULda+Uq7reA9D0PdEDpASsTSS2qLu8ZAtgUeA==
"@tiptap/extension-heading@^2.0.0-beta.23":
version "2.0.0-beta.23"
resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.23.tgz#8aafadc58a8d536b7f7885e4ff0f64d30908a868"
integrity sha512-/WLymJjY+MMvee79rWHSKDBGVRw4dbBUMrFLqKLjQQBS1xS8+UW2TYzRrAH6HAH4Tc6WO39ZDbd9K9kc9wqPnA==
"@tiptap/extension-history@^2.0.0-beta.16":
version "2.0.0-beta.16"
resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.0.0-beta.16.tgz#f40317bab795e2daf981aa1a01d6025f306be72c"
integrity sha512-nrNwV8a7zUt1t2I/kPX5Y6N9vZ8mrugimJIQmPGIp/4mmw1SEUzkaPpIsv6+ELmqMHSDktQ0ofb3pXeWDXWZvw==
"@tiptap/extension-history@^2.0.0-beta.21":
version "2.0.0-beta.21"
resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.0.0-beta.21.tgz#5d96a17a83a7130744f0757a3275dd5b11eb1bf7"
integrity sha512-0v8Cl30V4dsabdpspLdk+f+lMoIvLFlJN5WRxtc7RRZ5gfJVxPHwooIKdvC51brfh/oJtWFCNMRjhoz0fRaF9A==
dependencies:
"@types/prosemirror-history" "^1.0.3"
prosemirror-history "^1.2.0"
"@tiptap/extension-horizontal-rule@^2.0.0-beta.24":
version "2.0.0-beta.24"
resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.0-beta.24.tgz#ffd6226a98a62c5314012b8c1cc60c90709d0b9c"
integrity sha512-kRHJySSJl6QgPvnD+MkN3rzwQgInbq5zE4oxPPbgqYkaAcVSL/q7JBQK1dXMMFaslQlYmEgM6Eh3oU5vo9gUdQ==
"@tiptap/extension-horizontal-rule@^2.0.0-beta.30":
version "2.0.0-beta.30"
resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.0-beta.30.tgz#56d497f1187384d131f3f3320f30748c1e4b766f"
integrity sha512-h/PlkvfcMuoBGRfD7Cbeh8mxZiEc2pKveLDwOfCES9TKV5i2lqcIgctpohWyISuFcTq4K+OFgr910+Rsp8qwEg==
dependencies:
prosemirror-state "^1.3.4"
"@tiptap/extension-image@^2.0.0-beta.19":
version "2.0.0-beta.19"
resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.0.0-beta.19.tgz#40bd95d6d4306d28640bf60a074f20c792f375c6"
integrity sha512-17ax4H6Y+xyePfLtL5Z2V2AuWKHziukixHigA+Go4yOdEHlSDvl+x8eNYAZkxy2nH1yFW+uu7Onv8Ln/jWzqLg==
"@tiptap/extension-image@^2.0.0-beta.24":
version "2.0.0-beta.24"
resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.0.0-beta.24.tgz#1010676f79925cbe11a44b6d8eee1251910fbc1d"
integrity sha512-7oiX/Ovj9WN4xTBqWbQWd4H3SUO2eNzOiKHebVo3eqWG8NxzOGfuU0iRCENtEa7vTiRrFgyeBotneMALDpDnTQ==
"@tiptap/extension-italic@^2.0.0-beta.19":
version "2.0.0-beta.19"
resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.19.tgz#8f140e778e8cbd2281df6463d895d3632280c26f"
integrity sha512-gEVDqEz25glLuOPW1IOPJy/AIrTgsm164XSi9lnwS1uZa1bmEAKpoALN0+9VzSVaBOmrg2tycMo+iuOhYxFb7w==
"@tiptap/extension-italic@^2.0.0-beta.24":
version "2.0.0-beta.24"
resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.24.tgz#0a08d06dbd8dbf10f18ed17f019aa42d7ac9dbe0"
integrity sha512-pMAWFaLFb0Z0SC5pjoTKzC6m4CQOdUYeVlHvTS/550Z9lf8cqMawQ8H6Yk6brIuANyh7iUi4/zpq4H4rAdUCuw==
"@tiptap/extension-link@^2.0.0-beta.23":
version "2.0.0-beta.23"
resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.0.0-beta.23.tgz#7591dfe6eb8f65548c2b6a562c2b6ec0568d23c2"
integrity sha512-XnNdu6OyB09M4Qsru5j/GsDwj/EFjLQNmGZSQIS3GoaEcxrOImohnEZBZO9WJ11A5IT2GilpRZn2wHscdKoBdA==
"@tiptap/extension-link@^2.0.0-beta.28":
version "2.0.0-beta.28"
resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.0.0-beta.28.tgz#4385f36b6bb31fab34a86fb7c686ca05a37ed572"
integrity sha512-dZNaEjoDhgjmts44KqgtOYObCdDYZq/yFhsZ8QfqEgNHJMvBNTDaPXwBDW9i3BTkkyLTmwR/qwWxqDrfDdKh2A==
dependencies:
linkifyjs "^3.0.3"
prosemirror-state "^1.3.4"
"@tiptap/extension-list-item@^2.0.0-beta.14":
version "2.0.0-beta.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.14.tgz#65a9ff9daa11bc9ca8bc2989a891abe68081cfbd"
integrity sha512-t6xwEqP+d5443Ul2Jvqz9kXb3ro7bA7yY9HA0vskm3120WxxHW9jxgxZN+82Ot5Tm7nXOAlsN6vuqnt4idnxZQ==
"@tiptap/extension-ordered-list@^2.0.0-beta.19":
"@tiptap/extension-list-item@^2.0.0-beta.19":
version "2.0.0-beta.19"
resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.19.tgz#eeab2e8488b84ba7deb93b299370dc187d37c98a"
integrity sha512-PHC5pA1gohxCJF2xMXOzruPt8XWyWLun3vhJL2AIUUzUoGJmSRhsc8Wreeozdlf8HkKrqnsIuk5tp6IEsau6Pw==
resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.19.tgz#657f2c5624a30f3effff723f4fadb0851a61dab8"
integrity sha512-z/5NrRKwwJc2ZkgoGxRQmA/VENxQugZoxKhUu2qoUdg5cJRcW+ERoKTiY1/AR+4M2k1izNWQMIz3nQNWMx1kQA==
"@tiptap/extension-paragraph@^2.0.0-beta.17":
version "2.0.0-beta.17"
resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.17.tgz#f8f0263359b95dec9c10078699697908568d9be9"
integrity sha512-qCQVCf9c2hgaeIdfy22PaoZyW5Vare/1aGkOEAaZma5RjrUbV9hrRKwoW9LsDjnh1EN1fIeKdg02yEhnHWtG8A==
"@tiptap/extension-ordered-list@^2.0.0-beta.24":
version "2.0.0-beta.24"
resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.24.tgz#69c56e2cfbf582b338d5dbc94c5eda4593775cb5"
integrity sha512-pXgwV+vuBAHMBGnUPa8fjxHapGCitfBJ1k8o3XvhotO7243Y7KOfYT7kg6XrY6dmTwCX2WLkIc912PP/E60y3A==
"@tiptap/extension-strike@^2.0.0-beta.21":
version "2.0.0-beta.21"
resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.21.tgz#d4b7f0d52a275bc6a4ddc60fe546495d9f77f041"
integrity sha512-uYU5k05MChVtZUwWMXAl+xp3IGx/N/+8VZaeJDlIZfg0hew+ZdEGVjwzgCQc1PAuEZriHhbpPg1yOdcHjWga8Q==
"@tiptap/extension-paragraph@^2.0.0-beta.22":
version "2.0.0-beta.22"
resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.22.tgz#7740fb6393296ec58e98332b2855ebdc3fd05226"
integrity sha512-BY6GWHlMvGiXLgPHcfZRUHKzMi1jKw3i1JrpMEQ8JLwYD3koI/6UOB/qphwUJkCkIPQXNkZw4/aSBxL9uChRDg==
"@tiptap/extension-subscript@^2.0.0-beta.4":
version "2.0.0-beta.4"
resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.0.0-beta.4.tgz#07907df58695eb02bf6904d2c3635111003b30fd"
integrity sha512-eEjUXkgfeIBIgzdg3/GQGdta9Ww0Wwfiovn7ZvalRofRT4dnoiS0/83t1pQL81JT+ENow5jtx8RZHlaw/fMP4g==
"@tiptap/extension-strike@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.26.tgz#19eda1a61706ac9690ecbc794c711deb4e1efc3e"
integrity sha512-BA+oqqYOZzRLiMYlHX6BJXlIGaNIR9LObgkHEXAj/JPK7do4wDOcuVaw+dlWS+tzvTebLbC9GYAALfNqVBlTwA==
"@tiptap/extension-superscript@^2.0.0-beta.4":
version "2.0.0-beta.4"
resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.0.0-beta.4.tgz#16906d71dd8f9892101cf792f42005f8cd404516"
integrity sha512-rTQCnSnloSf6UN1y3zhu6j41MxrcCVWm5JIPX8VEt60WsOXJLAc/YJHLYi2FWhh/Psq8k78sPrmZbjYUrj3Dkw==
"@tiptap/extension-subscript@^2.0.0-beta.9":
version "2.0.0-beta.9"
resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.0.0-beta.9.tgz#4d86e904ec081384696562a5f550e81a1ddf2c76"
integrity sha512-wrmcDbXeilBW9HjJi34KpUioBCYD5zyaRu1hnIymVRwmfLNrwGpNyo/8VZTfNDdvliyMYHiRVFI4Mott6OzmgA==
"@tiptap/extension-table-cell@^2.0.0-beta.15":
version "2.0.0-beta.15"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.0.0-beta.15.tgz#2059946b1657f0f22415bda84cee77fb1eb232b1"
integrity sha512-MyZHJlFOF2z4Y1DQ/uuFbDPYQxSrl/PW8TEpAh2UQI/PGVsKkjzHItTvLtWSgo7t+tuPHbEOvIBDfpQKSyfbWg==
"@tiptap/extension-superscript@^2.0.0-beta.9":
version "2.0.0-beta.9"
resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.0.0-beta.9.tgz#be43b0e85f6440ed200831309060c3f0691811f2"
integrity sha512-BxXvCDGtIiuPmY9JbgIEjNbrFzXN3SBj178CfmDcu/FrQimwcqmsfLP3JOu1ZbUwQJuNwubx026vHXPzHlLXDA==
"@tiptap/extension-table-header@^2.0.0-beta.17":
version "2.0.0-beta.17"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.0.0-beta.17.tgz#1bd008825146e6f5fc607a1d8682b5d47ba08f25"
integrity sha512-HctO608QQEPe29QBtxXcDfBKfv+m9u2jBJ5AYpo7HjYGfUYRxv5uQpGXX3RW/c50+AhyTF0skF6Td1jiZcEPPw==
"@tiptap/extension-table-cell@^2.0.0-beta.20":
version "2.0.0-beta.20"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.0.0-beta.20.tgz#859456fe8d7276a87161006a3f9b3642b306524c"
integrity sha512-IllQyxLQvgm1FAewz3U+DkgNHRthmuVrtUQnG6la45qdUOLCOrpFbRRaQ1LJ/BpbvZ2Xs1o2yAa97BqZOPwovQ==
"@tiptap/extension-table-row@^2.0.0-beta.14":
version "2.0.0-beta.14"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.0.0-beta.14.tgz#9ec98c73e309ee966b71ccd140019874d179e0c8"
integrity sha512-mewdlTqgBCyzeZIZ6F08gfuzwsiYjQ7BvABo2UhDfr0+EN2UvfJj0bT3tGgeZhMxT5Js2DXL+c+ZOVJxWJ9faQ==
"@tiptap/extension-table-header@^2.0.0-beta.22":
version "2.0.0-beta.22"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.0.0-beta.22.tgz#a1672970d8985c383411bb21c18e71fc7e53e262"
integrity sha512-nMrghrfl+ZS4EDixs3lgXnHw1Q+ECyTugpRvS36rP7b8GFp3GXm9DfbIAUzwGGfcq1D7DwRnJUDM6ARdWXyw0w==
"@tiptap/extension-table@^2.0.0-beta.34":
version "2.0.0-beta.34"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.0.0-beta.34.tgz#6669d7d937b981e39f7dfa04b9adbabc18f789bc"
integrity sha512-DyY+m0PcvdVwh0XynDbsHXu/omUoTzQRQPI4z035J+b2HnLQnYjviNqblY/x8/rGX4qGGjBUmKvQZgwPGg7Dfw==
"@tiptap/extension-table-row@^2.0.0-beta.19":
version "2.0.0-beta.19"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.0.0-beta.19.tgz#b45e82f29dfcc7405440ba237b069dbb93d1a94a"
integrity sha512-ldEVDpIUX7ZqbViTy4c/RfyNGRv++O/r3A/Ivuon1PykaDDTbPlp5JM89FunAD39cLAbo2HKtweqdmzCMlZsqA==
"@tiptap/extension-table@^2.0.0-beta.42":
version "2.0.0-beta.42"
resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.0.0-beta.42.tgz#bd7e2886f9f4e6d6c53fa1a5fdf24e05bd58a4af"
integrity sha512-M9vL4ZODthTSiSRn4yC/gPfPgn7fgpoIj0qm6LF0HMcZbsyDA7eH7E33Xed93OwdMaJuLeq2qqdo1Sg71AJwpQ==
dependencies:
prosemirror-tables "^1.1.1"
prosemirror-view "^1.20.3"
prosemirror-view "^1.22.0"
"@tiptap/extension-task-item@^2.0.0-beta.21":
version "2.0.0-beta.21"
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.0.0-beta.21.tgz#37a8d30949cefd79b80f107d426d14eb9aeaf567"
integrity sha512-7pCOc+jSlveTGIUUVQO5LOGZN20vb1fAIFMUKAxG756MMI69eVhpdqrXcmovYT8qs//DcvxC/sEjus+ZzFtKVg==
"@tiptap/extension-task-item@^2.0.0-beta.28":
version "2.0.0-beta.28"
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.0.0-beta.28.tgz#7c514ae94b4ab386f7406297e7fa0bbd5e9b5ddd"
integrity sha512-BucJLBiKUupdUF7k5Gqe73HKPgJddZTISOy+3hERt9XPGwa1iCzjwMB41X9+c8HniBDgSyI2aV0zKTT931xFfg==
"@tiptap/extension-task-list@^2.0.0-beta.18":
version "2.0.0-beta.18"
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.0.0-beta.18.tgz#8b13593e3818995e7b5058bc400ee04c68314d69"
integrity sha512-EkPM+We5TP6MWwk+dH3FX/aizNRgVzHDTnnGyMisEievaazi11oKmz72svVCfF+BJJaRdVroCbeRoLWYH7by7w==
"@tiptap/extension-task-list@^2.0.0-beta.23":
version "2.0.0-beta.23"
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.0.0-beta.23.tgz#ca29039de53f7315e5612bfd1fb4ca6d471b9a2f"
integrity sha512-NjAQhtWDtkDpeKtJPItNeLi1fLLVACBFMq2yRCtKBXDGYg2X5w9CYPqXzh8gAIM2qs11wIgS60UtvF2No7Crxg==
"@tiptap/extension-text@^2.0.0-beta.13":
version "2.0.0-beta.13"
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.0.0-beta.13.tgz#da0af8d9a3f149d20076e15d88c6af21fb6d940f"
integrity sha512-0EtAwuRldCAoFaL/iXgkRepEeOd55rPg5N4FQUN1xTwZT7PDofukP0DG/2jff/Uj17x4uTaJAa9qlFWuNnDvjw==
"@tiptap/extension-text@^2.0.0-beta.15":
version "2.0.0-beta.15"
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.0.0-beta.15.tgz#f08cff1b78f1c6996464dfba1fef8ec1e107617f"
integrity sha512-S3j2+HyV2gsXZP8Wg/HA+YVXQsZ3nrXgBM9HmGAxB0ESOO50l7LWfip0f3qcw1oRlh5H3iLPkA6/f7clD2/TFA==
"@tiptap/vue-2@^2.0.0-beta.60":
version "2.0.0-beta.60"
resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.0.0-beta.60.tgz#18b1c3e7f1a94e5a047c6e25f4e176a42b68e2d1"
integrity sha512-6V2BucVL440yPy4YqCVxnaq7ZkiR9RmOtLydcNIt9/Abc/iQTkp2Q8qyDUqbGTfGfMEEdpuHd4m9ZRk3cuZ14g==
"@tiptap/vue-2@^2.0.0-beta.68":
version "2.0.0-beta.68"
resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.0.0-beta.68.tgz#9f67bd57c9860d2263ae4f32b169f6307f7d273b"
integrity sha512-Denvq8TdO5mzOkFLbQHWpmz/90tFehN2eRBRH20lPBQyrHSW3kxLleNVf2UsmZhu9b9d83s2MrFNJp1wAkhCKg==
dependencies:
"@tiptap/extension-bubble-menu" "^2.0.0-beta.42"
"@tiptap/extension-floating-menu" "^2.0.0-beta.36"
prosemirror-view "^1.20.3"
"@tiptap/extension-bubble-menu" "^2.0.0-beta.49"
"@tiptap/extension-floating-menu" "^2.0.0-beta.44"
prosemirror-view "^1.22.0"
"@toast-ui/editor@^2.5.2":
version "2.5.2"
@ -1934,10 +1934,10 @@
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-state@*", "@types/prosemirror-state@^1.2.7":
version "1.2.7"
resolved "https://registry.yarnpkg.com/@types/prosemirror-state/-/prosemirror-state-1.2.7.tgz#cd55062e4043a31e3426f47668f1d7038b5d8dfb"
integrity sha512-clJf5uw3/XQnBJtl2RqYXoLMGBySnLYl43xtDvFfQZKkLnnYcM1SDU8dcz7lWjl2Dm+H98RpLOl44pp7DYT+wA==
"@types/prosemirror-state@*", "@types/prosemirror-state@^1.2.8":
version "1.2.8"
resolved "https://registry.yarnpkg.com/@types/prosemirror-state/-/prosemirror-state-1.2.8.tgz#65080eeec52f63c50bf7034377f07773b4f6b2ac"
integrity sha512-mq9uyQWcpu8jeamO6Callrdvf/e1H/aRLR2kZWSpZrPHctEsxWHBbluD/wqVjXBRIOoMHLf6ZvOkrkmGLoCHVA==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-transform" "*"
@ -9781,10 +9781,10 @@ prosemirror-collab@^1.2.2:
dependencies:
prosemirror-state "^1.0.0"
prosemirror-commands@^1.1.11, prosemirror-commands@^1.1.4:
version "1.1.11"
resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.1.11.tgz#369252fcca5397ee7b011b963cc4da45b0b7cb70"
integrity sha512-uXDVkOGJbFHocdacMJihrnQCT7tHswO48ewq6ByqLxTwOrI8Y4B4aHvwUbM4epwElv/YjgC+DuqXm/gEHPym4w==
prosemirror-commands@^1.1.12, prosemirror-commands@^1.1.4:
version "1.1.12"
resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.1.12.tgz#5cb0fef4e5a0039e2fa19b42a5626af03d7c2ec3"
integrity sha512-+CrMs3w/ZVPSkR+REg8KL/clyFLv/1+SgY/OMN+CB22Z24j9TZDje72vL36lOZ/E4NeRXuiCcmENcW/vAcG67A==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-state "^1.0.0"
@ -9826,10 +9826,10 @@ prosemirror-inputrules@^1.1.2, prosemirror-inputrules@^1.1.3:
prosemirror-state "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.1.3, prosemirror-keymap@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.1.4.tgz#8b481bf8389a5ac40d38dbd67ec3da2c7eac6a6d"
integrity sha512-Al8cVUOnDFL4gcI5IDlG6xbZ0aOD/i3B17VT+1JbHWDguCgt/lBHVTHUBcKvvbSg6+q/W4Nj1Fu6bwZSca3xjg==
prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.1.4, prosemirror-keymap@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.1.5.tgz#b5984c7d30f5c75956c853126c54e9e624c0327b"
integrity sha512-8SZgPH3K+GLsHL2wKuwBD9rxhsbnVBTwpHCO4VUO5GmqUQlxd/2GtBVWTsyLq4Dp3N9nGgPd3+lZFKUDuVp+Vw==
dependencies:
prosemirror-state "^1.0.0"
w3c-keyname "^2.2.0"
@ -9842,10 +9842,10 @@ prosemirror-markdown@^1.6.0:
markdown-it "^10.0.0"
prosemirror-model "^1.0.0"
prosemirror-model@^1.0.0, prosemirror-model@^1.13.1, prosemirror-model@^1.14.3, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1:
version "1.14.3"
resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.14.3.tgz#a9c250d3c4023ddf10ecb41a0a7a130e9741d37e"
integrity sha512-yzZlBaSxfUPIIP6U5Edh5zKxJPZ5f7bwZRhiCuH3UYkWhj+P3d8swHsbuAMOu/iDatDc5J/Qs5Mb3++mZf+CvQ==
prosemirror-model@^1.0.0, prosemirror-model@^1.13.1, prosemirror-model@^1.14.3, prosemirror-model@^1.15.0, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1:
version "1.15.0"
resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.15.0.tgz#23bc09098daa7c309dba90a76a1b989ce6f61405"
integrity sha512-hQJv7SnIhlAy9ga3lhPPgaufhvCbQB9tHwscJ9E1H1pPHmN8w5V/lURueoYv9Kc3/bpNWoyHa8r3g//m7N0ChQ==
dependencies:
orderedmap "^1.1.0"
@ -9899,10 +9899,10 @@ prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transfor
dependencies:
prosemirror-model "^1.0.0"
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.16.5, prosemirror-view@^1.20.3:
version "1.20.3"
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.20.3.tgz#9781fe59cf0728e749ff4116f8a69d30d8cea943"
integrity sha512-2ImL9K/tIEk+aC2GT8shzfmT2U0Y8UQZ13L5AY0A4Tcj09o/ICGE362gKUE3Ze/Xr/nMw61Zv5JMSQUszAj9dw==
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.16.5, prosemirror-view@^1.22.0, prosemirror-view@^1.23.1:
version "1.23.1"
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.23.1.tgz#ea84e685003fab655b835bf2fe834dba66d1798b"
integrity sha512-ZB0GqRqqkGvh7ggk7asFyKl3mqu3M5URBg0tf578kuP326RqL7nbIS0jEix95Vfb/U43J1T8PV6OCWQ5fZPVjg==
dependencies:
prosemirror-model "^1.14.3"
prosemirror-state "^1.0.0"
@ -11554,10 +11554,10 @@ tiny-emitter@^2.0.0:
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.2.tgz#82d27468aca5ade8e5fd1e6d22b57dd43ebdfb7c"
integrity sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow==
tippy.js@^6.3.2:
version "6.3.2"
resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.2.tgz#c03a0b88f170dffeba42f569771801dddc1f6340"
integrity sha512-35XVQI7Zl/jHZ51+8eHu/vVRXBjWYGobPm5G9FxOchj4r5dWhghKGS0nm0ARUKZTF96V7pPn7EbXS191NTwldw==
tippy.js@^6.3.6:
version "6.3.7"
resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c"
integrity sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==
dependencies:
"@popperjs/core" "^2.9.0"