Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
97b345d
Merge pull request #4124 from learningequality/hotfixes
bjester Jun 9, 2023
e3754ba
Bump stylus-loader from 7.1.2 to 7.1.3
dependabot[bot] Jun 12, 2023
7b4608c
- add jszip yarn package;
Jun 12, 2023
ccf5f9e
Bump fonttools from 4.27.1 to 4.40.0
dependabot[bot] Jun 13, 2023
4af8e7d
Fixes error that appears in the console on drag nested resource to to…
akolson Jun 16, 2023
0ac48fd
Fixes error that appears in the console on drag nested resource to to…
akolson Jun 16, 2023
4f9fc43
Fixes css styling
akolson Jun 16, 2023
1c0af35
Finally, we handle copy failures with retry!
vkWeb Jun 23, 2023
77d8ed6
Merge branch 'hotfixes' into copy-fail-handle
vkWeb Jun 23, 2023
cfb48d9
Fix styles to match the design
vkWeb Jun 23, 2023
9b2aff0
Adds defensive check to prevent failing drops
akolson Jun 16, 2023
3a2b734
- [add] the extracted metadata from .h5p CP to contentNode
Jun 22, 2023
140490f
removed scroll on adding new question
Jaspreet-singh-1032 Jul 2, 2023
e5d1a25
added text truncate in import channel dropdown
Jaspreet-singh-1032 Jul 5, 2023
51b61bd
Prevent source edits for copied/imported resources
akolson Jul 5, 2023
aeb0c2e
Bump grpcio from 1.51.1 to 1.53.0
dependabot[bot] Jul 5, 2023
7d15ffe
Merge branch 'hotfixes' into copy-fail-handle
vkWeb Jul 6, 2023
80d33c6
Fix language ignorance for public API
vkWeb Jul 6, 2023
355eca9
[#4193][#4194] Apply defaults to details to avoid undefined errors
bjester Jul 6, 2023
7d81e1b
[#4195] Defensive check against deleted attr
bjester Jul 6, 2023
1f74be8
Merge pull request #4150 from akolson/fixes-drag-error-message
bjester Jul 6, 2023
7492935
Create computed prop for deleted
bjester Jul 7, 2023
95f09af
[#4200] Defensiveness against ZIM content kind, and .icon
bjester Jul 7, 2023
07a4e37
[#4206] Add missing image causing PDF generation to fail
bjester Jul 7, 2023
b2793ff
Fix Vue complaints about undefined 'name' used in template
bjester Jul 7, 2023
118894b
[#4200] Fix icon access in storage settings view
bjester Jul 7, 2023
5139611
Close drawer when opening language modal
bjester Jul 7, 2023
cef06b0
- [refactor] code
Jul 7, 2023
09dc992
uses instead of '!'=8084
akolson Jul 8, 2023
e0d69d7
Add argument docs & make deletion defensive
vkWeb Jul 10, 2023
1c1d9a7
Fix CTAs overflow
vkWeb Jul 10, 2023
a0bda29
Merge pull request #4189 from akolson/prevent-source-edits
bjester Jul 10, 2023
659b0eb
Remove public api export from deploy-migrate since it has run on prod
bjester Jul 10, 2023
de45841
Merge pull request #4210 from bjester/remove-public-api-export
rtibbles Jul 10, 2023
178d276
Merge pull request #4199 from bjester/bjester/v2023.07.05-patches/1
bjester Jul 10, 2023
8030319
Merge pull request #4207 from bjester/bjester/v2023.07.05-patches/2
bjester Jul 10, 2023
4442529
Bump semver from 5.7.1 to 5.7.2
dependabot[bot] Jul 10, 2023
4ccbf35
Merge pull request #4129 from learningequality/dependabot/npm_and_yar…
rtibbles Jul 12, 2023
aaea8e5
Merge pull request #4213 from learningequality/dependabot/npm_and_yar…
rtibbles Jul 12, 2023
975a571
Merge pull request #4192 from learningequality/dependabot/pip/grpcio-…
rtibbles Jul 12, 2023
9557200
Merge pull request #4132 from learningequality/dependabot/pip/fonttoo…
rtibbles Jul 12, 2023
64a1368
Bump google-cloud-kms from 1.4.0 to 2.10.0
dependabot[bot] Jul 12, 2023
daee90b
Bump workbox-precaching from 6.5.4 to 7.0.0
dependabot[bot] Jul 13, 2023
c9248aa
Merge pull request #4217 from learningequality/dependabot/npm_and_yar…
rtibbles Jul 13, 2023
c4fc395
Bump jest-serializer-vue from 2.0.2 to 3.1.0
dependabot[bot] Jul 14, 2023
5e557fc
Fix font-size and final cleanup
vkWeb Jul 14, 2023
a0687c4
Remove padding, replace with dynamic vertical alignment
bjester Jul 17, 2023
7b9fa05
apply ellipsis based on props
Jaspreet-singh-1032 Jul 18, 2023
3e7be2c
Merge pull request #4198 from vkWeb/ignore-lang
rtibbles Jul 18, 2023
abfa1d3
Merge pull request #4218 from learningequality/dependabot/npm_and_yar…
rtibbles Jul 18, 2023
a20e659
Merge pull request #3887 from learningequality/dependabot/pip/google-…
rtibbles Jul 18, 2023
7914232
Bump django-s3-storage from 0.13.11 to 0.14.0
dependabot[bot] Jul 19, 2023
98d377f
Bump locust from 2.8.6 to 2.15.1
dependabot[bot] Jul 19, 2023
ad2ea8c
Bump workbox-webpack-plugin from 6.5.4 to 7.0.0
dependabot[bot] Jul 19, 2023
f63fd2f
Merge pull request #4225 from learningequality/dependabot/npm_and_yar…
rtibbles Jul 19, 2023
6f28883
Bump word-wrap from 1.2.3 to 1.2.4
dependabot[bot] Jul 19, 2023
67c6966
Merge pull request #4224 from learningequality/dependabot/pip/locust-…
rtibbles Jul 19, 2023
36e3dfb
Merge pull request #4223 from learningequality/dependabot/pip/django-…
rtibbles Jul 19, 2023
f6669ad
Bump attrs from 19.3.0 to 23.1.0
dependabot[bot] Jul 19, 2023
d379eb1
Bump workbox-window from 6.5.4 to 7.0.0
dependabot[bot] Jul 19, 2023
a10be69
Handle errors in publishing better by cleaning up database connections.
rtibbles Jul 19, 2023
ab6f527
Add test case for publishing an empty channel.
rtibbles Jul 19, 2023
0b80f79
Add special handling of publishes that cannot go ahead.
rtibbles Jul 19, 2023
73cb9cf
Merge pull request #4227 from learningequality/dependabot/npm_and_yar…
rtibbles Jul 19, 2023
de70b3f
Merge pull request #4228 from learningequality/dependabot/npm_and_yar…
rtibbles Jul 19, 2023
a9049f2
Remove direct dependency on unused attrs
rtibbles Jul 19, 2023
14b89ea
Handle tear down better to avoid errors.
rtibbles Jul 19, 2023
5902425
Merge pull request #4230 from learningequality/dependabot/pip/attrs-2…
rtibbles Jul 19, 2023
77dd2cd
Prevent errors when creating already existing tag through model entries.
rtibbles Jul 19, 2023
1d78f3b
Fix bitmask filtering by multiple labels for AND rather than OR behav…
rtibbles Jul 19, 2023
1e3e05b
Merge pull request #4231 from rtibbles/empty_channels
bjester Jul 19, 2023
947e14c
Merge pull request #4233 from rtibbles/AND_NOT_OR
rtibbles Jul 19, 2023
1109117
Add regression test for duplicate tags edge case.
rtibbles Jul 19, 2023
ae16389
Merge pull request #4232 from rtibbles/tag_me_in
rtibbles Jul 19, 2023
59fdf45
Bump dexie from 3.2.2 to 3.2.4
dependabot[bot] Jul 20, 2023
bb3be23
Bump less-loader from 11.0.0 to 11.1.3
dependabot[bot] Jul 20, 2023
ba1c873
Merge pull request #4234 from learningequality/dependabot/npm_and_yar…
rtibbles Jul 20, 2023
e157980
Merge pull request #4235 from learningequality/dependabot/npm_and_yar…
rtibbles Jul 20, 2023
81283df
scrollintoview with block end
Jaspreet-singh-1032 Jul 20, 2023
5ab69cb
Merge pull request #4186 from Jaspreet-singh-1032/fixes-4166-overlapp…
LianaHarris360 Jul 20, 2023
9a48ae4
Fix undo of copying
vkWeb Jul 25, 2023
16881b7
Merge pull request #4244 from vkWeb/undo-copy-man
bjester Jul 25, 2023
a0d657a
Resolve merge conflicts in package.json
bjester Jul 25, 2023
212b46b
Merge pull request #4245 from bjester/merge-down-abc
bjester Jul 27, 2023
e047184
scroll to the question card
Jaspreet-singh-1032 Jul 27, 2023
68dbb7f
final cleanup
Jaspreet-singh-1032 Aug 1, 2023
d401e85
Merge pull request #4181 from Jaspreet-singh-1032/fixes-4079-add-new-…
vkWeb Aug 1, 2023
0669213
fix ordering issue
Jaspreet-singh-1032 Aug 4, 2023
04c749b
- [remove] unwanted logs
Aug 6, 2023
6729d52
Merge pull request #4250 from Jaspreet-singh-1032/fixes-4249-channel-…
vkWeb Aug 7, 2023
fcaa495
Enhance tests and add special handling for mptt fields.
rtibbles Aug 9, 2023
a71a320
Bump le-utils from 0.1.42 to 0.2.1
dependabot[bot] Aug 10, 2023
0816bb2
Merge pull request #4251 from rtibbles/import_metadata_lefty_righty
bjester Aug 10, 2023
3f68c51
- [add] test case for H5P content file extract metadata
Aug 6, 2023
63041b6
Merge pull request #4131 from manavagr1108/extract-metadata-for-h5p-cp
rtibbles Aug 14, 2023
089f088
Merge pull request #4252 from learningequality/dependabot/pip/le-util…
rtibbles Aug 14, 2023
36bbe24
Update JS constants for latest leutils.
rtibbles Aug 15, 2023
a82e78b
Final tweaks and tests for H5P upload.
rtibbles Aug 15, 2023
3625f6f
Add missing mappings for h5p kind.
rtibbles Aug 15, 2023
d76efcf
Merge pull request #4255 from rtibbles/h5p_finalization
rtibbles Aug 15, 2023
dc4608f
Fixes incorrect value for Practice quiz
akolson Aug 22, 2023
2a70ad2
Adds new automation django app for future AI features
akash5100 Aug 24, 2023
2f0ac11
Merge pull request #4262 from akash5100/automation-app
bjester Aug 24, 2023
dc357cc
Merge pull request #4260 from akolson/quiz-incorrect-completion-value
marcellamaki Aug 29, 2023
16787d9
Bump actions/checkout from 3 to 4
dependabot[bot] Sep 5, 2023
1a62ea9
Merge pull request #4271 from learningequality/dependabot/github_acti…
rtibbles Sep 5, 2023
7814874
Merge pull request #4176 from vkWeb/copy-fail-handle
bjester Sep 5, 2023
28c16e9
Fix missing attributes from change objects
vkWeb Sep 12, 2023
26b123d
Super Duper Fast Import Search :rocket:
vkWeb Sep 12, 2023
3fa10e3
Merge pull request #4278 from vkWeb/undefined_is_now_defined
rtibbles Sep 13, 2023
ba592bd
Merge pull request #4279 from vkWeb/super_fast_we_go
rtibbles Sep 13, 2023
b24c843
Merge pull request #4270 from learningequality/unstable
rtibbles Sep 14, 2023
1f932f7
Fixes incorrectly truncated channel titles in 'Channel/source' and 'L…
akolson Sep 21, 2023
32bd214
Merge pull request #4288 from akolson/fix-incorrectly-truncated-chann…
marcellamaki Sep 22, 2023
dbe7c04
Add instance ID to public API
bjester Sep 27, 2023
c2843ba
Merge pull request #4298 from bjester/add-instance-id
bjester Sep 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/deploytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
if: ${{ needs.pre_job.outputs.should_skip != 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v3
with:
Expand All @@ -51,7 +51,7 @@ jobs:
if: ${{ needs.pre_job.outputs.should_skip != 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/frontendlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
if: ${{ needs.pre_job.outputs.should_skip != 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v3
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/frontendtest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
if: ${{ needs.pre_job.outputs.should_skip != 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v3
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pythontest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
# Maps port 6379 on service container to the host
- 6379:6379
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up minio
run: |
docker run -d -p 9000:9000 --name minio \
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ migrate:
# 4) Remove the management command from this `deploy-migrate` recipe
# 5) Repeat!
deploy-migrate:
python contentcuration/manage.py export_channels_to_kolibri_public
echo "Nothing to do here!"

contentnodegc:
python contentcuration/manage.py garbage_collect
Expand Down
Empty file.
3 changes: 3 additions & 0 deletions contentcuration/automation/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# from django.contrib import admin

# Register your models here.
6 changes: 6 additions & 0 deletions contentcuration/automation/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class AutomationConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'automation'
Empty file.
3 changes: 3 additions & 0 deletions contentcuration/automation/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# from django.db import models

# Create your models here.
3 changes: 3 additions & 0 deletions contentcuration/automation/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# from django.test import TestCase

# Create your tests here.
3 changes: 3 additions & 0 deletions contentcuration/automation/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# from django.shortcuts import render

# Create your views here.
6 changes: 5 additions & 1 deletion contentcuration/contentcuration/db/models/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ def _copy_tags(self, source_copy_id_map):
tag_id_map[tag.id] = new_tag.id
tags_to_create.append(new_tag)

# TODO: Can cleanup the above and change the below to use ignore_conflicts=True
ContentTag.objects.bulk_create(tags_to_create)

mappings_to_create = [
Expand All @@ -499,7 +500,10 @@ def _copy_tags(self, source_copy_id_map):
for mapping in node_tags_mappings
]

self.model.tags.through.objects.bulk_create(mappings_to_create)
# In the case that we are copying a node that is in the weird state of having a tag
# that is duplicated (with a channel tag and a null channel tag) this can cause an error
# so we ignore conflicts here to ignore the duplicate tags.
self.model.tags.through.objects.bulk_create(mappings_to_create, ignore_conflicts=True)

def _copy_assessment_items(self, source_copy_id_map):
from contentcuration.models import File
Expand Down
2 changes: 1 addition & 1 deletion contentcuration/contentcuration/dev_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@

ROOT_URLCONF = "contentcuration.dev_urls"

INSTALLED_APPS += ("drf_yasg",)
INSTALLED_APPS += ("drf_yasg", "automation")
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export const tableMixin = {
...this.$route.query,
};
if (params.sortBy) {
params.ordering = (params.descending ? '-' : '') + params.sortBy;
params.ordering = (String(params.descending) === 'true' ? '-' : '') + params.sortBy;
delete params.sortBy;
delete params.descending;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@
channel() {
return this.getChannel(this.channelId);
},
name() {
return this.channel.name;
},
searchChannelEditorsLink() {
return {
name: RouteNames.USERS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
</template>
<LoadingText v-if="loading" absolute />
<VCardText v-else>
<Banner error :value="channel.deleted" class="mb-4">
<Banner error :value="isDeleted" class="mb-4">
This channel has been deleted
</Banner>
<VTabsItems v-model="tab">
Expand Down Expand Up @@ -102,6 +102,9 @@
channel() {
return this.getChannel(this.channelId);
},
isDeleted() {
return this.channel && Boolean(this.channel?.deleted);
},
channelWithDetails() {
if (!this.channel || !this.details) {
return {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<transition-group name="list-complete" tag="div">
<VCard
v-for="(item, idx) in sortedItems"
ref="questionCardRef"
:key="`question-${item.assessment_id}`"
pa-1
class="elevation-4 list-complete-item"
Expand Down Expand Up @@ -333,6 +334,17 @@
this.$analytics.trackAction('exercise_editor', 'Add', {
eventLabel: 'Question',
});
this.$nextTick(() => {
const questionCards = this.$refs['questionCardRef'];
if (questionCards?.length >= 1) {
const lastQuestionCard = questionCards[questionCards.length - 1].$el;
const editorDiv = document.getElementById('editViewId');
editorDiv.scrollTo({
top: lastQuestionCard.offsetTop,
behavior: 'smooth',
});
}
});
},
async deleteItem(itemToDelete) {
if (this.isItemActive(itemToDelete)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,6 @@
if (!this.question) {
this.openQuestion();
}
// Assessments are nested inside of a scrolling panel.
// Instead of propagating an event all the way back to
// the scrolling panel, just use scrollIntoView
// (supported by most major browsers)
if (this.$el.scrollIntoView) {
this.$el.scrollIntoView({ behaviour: 'smooth' });
}
},
methods: {
updateItem(payload) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
v-on="on"
@click="clickItem(action)"
>
<Icon :color="iconColor(action)">
<Icon v-if="config[action] && config[action].icon" :color="iconColor(action)">
{{ config[action].icon }}
</Icon>
</VBtn>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,22 @@
</VListTileAction>
</template>

<template #copy-fail-retry-action>
<span v-if="hasCopyingErrored">
<ActionLink class="copy-retry-btn" :text="$tr('retryCopy')" @click="retryFailedCopy" />
</span>
</template>

<template #copy-fail-remove-action>
<IconButton
v-if="hasCopyingErrored"
icon="close"
:text="$tr('removeNode')"
size="small"
@click="removeFailedCopyNode"
/>
</template>

<template #context-menu="{ showContextMenu, positionX, positionY }">
<ContentNodeContextMenu
:show="showContextMenu"
Expand All @@ -81,17 +97,19 @@

<script>

import { mapGetters } from 'vuex';
import { mapGetters, mapActions } from 'vuex';

import ContentNodeListItem from './ContentNodeListItem';
import ContentNodeOptions from './ContentNodeOptions';
import ContentNodeContextMenu from './ContentNodeContextMenu';
import Checkbox from 'shared/views/form/Checkbox';
import IconButton from 'shared/views/IconButton';
import DraggableItem from 'shared/views/draggable/DraggableItem';
import { COPYING_FLAG } from 'shared/data/constants';
import { ContentNode } from 'shared/data/resources';
import { DragEffect, DropEffect, EffectAllowed } from 'shared/mixins/draggable/constants';
import { DraggableRegions } from 'frontend/channelEdit/constants';
import { withChangeTracker } from 'shared/data/changes';
import { COPYING_STATUS, COPYING_STATUS_VALUES } from 'shared/data/constants';

export default {
name: 'ContentNodeEditListItem',
Expand Down Expand Up @@ -141,7 +159,11 @@
},
computed: {
...mapGetters('currentChannel', ['canEdit']),
...mapGetters('contentNode', ['getContentNode']),
...mapGetters('contentNode', [
'getContentNode',
'isNodeInCopyingState',
'hasNodeCopyingErrored',
]),
...mapGetters('draggable', ['activeDraggableRegionId']),
selected: {
get() {
Expand All @@ -163,7 +185,10 @@
return !this.copying;
},
copying() {
return this.contentNode[COPYING_FLAG];
return this.isNodeInCopyingState(this.nodeId);
},
hasCopyingErrored() {
return this.hasNodeCopyingErrored(this.nodeId);
},
dragEffect() {
return DragEffect.SORT;
Expand Down Expand Up @@ -206,18 +231,57 @@
this.selected = false;
}
},
methods: {
...mapActions(['showSnackbar', 'clearSnackbar']),
...mapActions('contentNode', [
'updateContentNode',
'waitForCopyingStatus',
'deleteContentNode',
]),
retryFailedCopy: withChangeTracker(function(changeTracker) {
this.updateContentNode({
id: this.nodeId,
[COPYING_STATUS]: COPYING_STATUS_VALUES.COPYING,
});

this.showSnackbar({
duration: null,
text: this.$tr('creatingCopies'),
// TODO: determine how to cancel copying while it's in progress,
// TODO: if that's something we want
// actionText: this.$tr('cancel'),
// actionCallback: () => changeTracker.revert(),
});

ContentNode.retryCopyChange(this.nodeId);

return this.waitForCopyingStatus({
contentNodeId: this.nodeId,
startingRev: changeTracker._startingRev,
})
.then(() => {
this.showSnackbar({
text: this.$tr('copiedSnackbar'),
actionText: this.$tr('undo'),
actionCallback: () => changeTracker.revert(),
}).then(() => changeTracker.cleanUp());
})
.catch(() => {
this.clearSnackbar();
changeTracker.cleanUp();
});
}),
removeFailedCopyNode() {
return this.deleteContentNode(this.nodeId);
},
},
$trs: {
optionsTooltip: 'Options',
/* eslint-disable kolibri/vue-no-unused-translations */
/**
* Strings for handling copy failures
*/
removeNode: 'Remove',
retryCopy: 'Retry',
creatingCopies: 'Copying...',
copiedSnackbar: 'Copy operation complete',
undo: 'Undo',
/* eslint-enable kolibri/vue-no-unused-translations */
},
};

Expand Down Expand Up @@ -298,4 +362,8 @@
justify-content: center;
}

.copy-retry-btn {
font-size: inherit;
}

</style>
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,16 @@ const TOPIC_NODE = {

function mountComponent(opts = {}) {
return mount(ContentNodeListItem, {
store: createStore(),
store: createStore({
modules: {
contentNode: {
namespaced: true,
getters: {
isNodeInCopyingState: () => jest.fn(),
},
},
},
}),
...opts,
});
}
Expand Down
Loading