Skip to content
Open
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that v-bind has some difficulties when the nodes their styles are applied to are removed from the DOM, and then reinserted again. (In this case the v-if=isModalVisible update made it appear). It seems that when the nodes are removed, the CSS variables are removed too, but if they are re-inserted, the CSS variables are not. So, just came back these colors to be declared in inline styles. And flagging that this is something that can happen with Vue 2.7's v-bind method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting - feels like that's some magic that's happening under the hood when Vue SFCs are compiled and have v-binds in them!

Seems like it may make this less useful overall, unfortunately!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, yes :/. Perhaps this is solved in Vue 3, let's see.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>

<SidePanelModal
v-if="isModalVisible"
alignment="right"
sidePanelWidth="700px"
@closePanel="$emit('close')"
Expand All @@ -20,7 +21,15 @@
class="submission-info-text"
>
<span class="author-name">{{ authorName }}</span>
<div class="editor-chip">Editor</div>
<div
class="editor-chip"
:style="{
color: chipTextColor,
backgroundColor: chipColor,
}"
>
Editor
</div>
<span>
submitted
<ActionLink
Expand All @@ -39,7 +48,10 @@
<div v-else>Error loading submission data.</div>

<div class="details">
<span class="detail-annotation">Country(s)</span>
<span
class="detail-annotation"
:style="{ color: annotationColor }"
>Country(s)</span>
<span
v-if="countriesString"
data-test="countries"
Expand All @@ -49,7 +61,10 @@
<template v-else>
<KEmptyPlaceholder />
</template>
<span class="detail-annotation">Language(s)</span>
<span
class="detail-annotation"
:style="{ color: annotationColor }"
>Language(s)</span>
<span
v-if="languagesString"
data-test="languages"
Expand All @@ -59,7 +74,10 @@
<template v-else>
<KEmptyPlaceholder />
</template>
<span class="detail-annotation">Categories</span>
<span
class="detail-annotation"
:style="{ color: annotationColor }"
>Categories</span>
<span
v-if="categoriesString"
data-test="categories"
Expand All @@ -69,7 +87,10 @@
<template v-else>
<KEmptyPlaceholder />
</template>
<span class="detail-annotation">License(s)</span>
<span
class="detail-annotation"
:style="{ color: annotationColor }"
>License(s)</span>
<span
v-if="licensesString"
data-test="licenses"
Expand All @@ -79,7 +100,10 @@
<template v-else>
<KEmptyPlaceholder />
</template>
<span class="detail-annotation">Status</span>
<span
class="detail-annotation"
:style="{ color: annotationColor }"
>Status</span>
<div
v-if="submissionIsFinished"
style="display: flex"
Expand All @@ -91,8 +115,16 @@
</template>
</div>

<div class="box">
<h3 class="box-title">Submission notes</h3>
<div
class="box"
:style="{ backgroundColor: boxBackgroundColor }"
>
<h3
class="box-title"
:style="{ color: boxTitleColor }"
>
Submission notes
</h3>
<span
v-if="submissionNotes"
data-test="submission-notes"
Expand Down Expand Up @@ -239,6 +271,7 @@
CommunityLibraryStatusChip,
},
setup(props, { emit }) {
const isModalVisible = ref(true);
const tokensTheme = themeTokens();
const paletteTheme = themePalette();

Expand Down Expand Up @@ -476,6 +509,8 @@

showSnackbar({ text: snackbarText });
updateStatusInStore(statusChoice.value);
emit('change');
emit('close');
} catch (error) {
showSnackbar({ text: 'Changing channel status failed' });
} finally {
Expand All @@ -489,13 +524,19 @@
actionText: 'Cancel',
actionCallback: () => {
clearTimeout(timer);
// Do not emit close just yet, so that the component isn't unmounted
// this will keep the component live until the submit function finishes, allowing
// to keep communicating with the parent component, and in particular allowing the
// "change" event to be emitted. It also allows us to keep the working information
// on the component, and show the side panel in the same state if the user cancels
isModalVisible.value = true;
Comment on lines +527 to +532
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the best way I found to manage this. It is similar to what we were doing initially for the BUM side panels, where the side panel component was still live until the user rejected the "undo" modal.

currentlySubmitting.value = false;
showSnackbar({
text: 'Action cancelled',
});
},
});

emit('close');
isModalVisible.value = false;
}

const chipColor = computed(() => paletteTheme.grey.v_200);
Expand All @@ -519,6 +560,7 @@

return {
isLoading,
isModalVisible,
chipColor,
chipTextColor,
annotationColor,
Expand Down Expand Up @@ -596,8 +638,6 @@
height: 20px;
padding: 2px 5px;
font-size: 10px;
color: v-bind('chipTextColor');
background-color: v-bind('chipColor');
border-radius: 16px;
}

Expand All @@ -612,15 +652,13 @@

.detail-annotation {
grid-column-start: 1;
color: v-bind('annotationColor');
}

.box {
display: flex;
flex-direction: column;
gap: 8px;
padding: 12px;
background-color: v-bind('boxBackgroundColor');
border-radius: 8px;
}

Expand All @@ -634,7 +672,6 @@
.box-title {
font-size: 12px;
font-weight: 600;
color: v-bind('boxTitleColor');
}

.details-box-title {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,15 +344,6 @@ describe('ReviewSubmissionSidePanel', () => {
jest.useRealTimers();
});

it('the panel closes', async () => {
jest.useFakeTimers();

const confirmButton = wrapper.findComponent({ ref: 'confirmButtonRef' });
await confirmButton.trigger('click');

expect(wrapper.emitted('close')).toBeTruthy();
});

it('a submission snackbar is shown', async () => {
jest.useFakeTimers();
const confirmButton = wrapper.findComponent({ ref: 'confirmButtonRef' });
Expand Down Expand Up @@ -403,6 +394,22 @@ describe('ReviewSubmissionSidePanel', () => {
store.replaceState(origStoreState);
});

it('the panel closes', async () => {
const origStoreState = store.state;
store.commit('channel/ADD_CHANNEL', channel);

jest.useFakeTimers();
const confirmButton = wrapper.findComponent({ ref: 'confirmButtonRef' });
await confirmButton.trigger('click');

jest.runAllTimers();
await wrapper.vm.$nextTick();

store.replaceState(origStoreState);

expect(wrapper.emitted('close')).toBeTruthy();
});

it('the channel latest submission status is updated in the store', async () => {
const origStoreState = store.state;
store.commit('channel/ADD_CHANNEL', channel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const RouteNames = {
CHANNEL: 'CHANNEL',
USERS: 'USERS',
USER: 'USER',
COMMUNITY_LIBRARY_SUBMISSION: 'COMMUNITY_LIBRARY_SUBMISSION',
};

export const rowsPerPageItems = [25, 50, 75, 100];
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,13 @@

<BaseMenu>
<template #activator="{ on }">
<VBtn
v-bind="$attrs"
<KButton
hasDropdown
:primary="primary"
v-on="on"
>
Actions
<Icon
icon="dropdown"
class="ml-1"
/>
</VBtn>
</KButton>
</template>
<VList>
<template v-if="channel.deleted">
Expand Down Expand Up @@ -115,6 +112,10 @@
type: String,
required: true,
},
primary: {
type: Boolean,
default: false,
},
},
data: () => ({
activeDialog: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@
<CommunityLibraryStatusButton
v-if="communityLibraryStatus"
:status="communityLibraryStatus"
@click="submissionToReview = channel.latest_community_library_submission_id"
@click="onCommunityLibraryButtonClick"
/>
<KEmptyPlaceholder v-else />
</td>
Expand All @@ -211,12 +211,6 @@
flat
/>
</td>
<ReviewSubmissionSidePanel
v-if="submissionToReview"
:channel="channel"
:submissionId="submissionToReview"
@close="submissionToReview = null"
/>
</tr>

</template>
Expand All @@ -226,7 +220,6 @@

import { mapGetters, mapActions } from 'vuex';
import ClipboardChip from '../../components/ClipboardChip';
import ReviewSubmissionSidePanel from '../../components/sidePanels/ReviewSubmissionSidePanel';
import CommunityLibraryStatusButton from '../../components/CommunityLibraryStatusButton.vue';
import { RouteNames } from '../../constants';
import ChannelActionsDropdown from './ChannelActionsDropdown';
Expand All @@ -241,7 +234,6 @@
ClipboardChip,
Checkbox,
CommunityLibraryStatusButton,
ReviewSubmissionSidePanel,
},
mixins: [fileSizeMixin],
props: {
Expand All @@ -254,11 +246,6 @@
required: true,
},
},
data() {
return {
submissionToReview: null,
};
},
computed: {
...mapGetters('channel', ['getChannel']),
selected: {
Expand Down Expand Up @@ -320,6 +307,15 @@
this.$store.dispatch('showSnackbarSimple', 'Source URL saved');
});
},
onCommunityLibraryButtonClick() {
this.$router.push({
name: RouteNames.COMMUNITY_LIBRARY_SUBMISSION,
params: {
channelId: this.channelId,
submissionId: this.channel.latest_community_library_submission_id.toString(),
},
});
},
},
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { mount } from '@vue/test-utils';
import CommunityLibraryStatusButton from '../../../components/CommunityLibraryStatusButton.vue';
import ReviewSubmissionSidePanel from '../../../components/sidePanels/ReviewSubmissionSidePanel';
import router from '../../../router';
import { factory } from '../../../store';
import { RouteNames } from '../../../constants';
Expand Down Expand Up @@ -185,10 +184,11 @@ describe('channelItem', () => {
const statusCell = wrapper.find('[data-test="community-library-status"]');
const statusButton = statusCell.findComponent(CommunityLibraryStatusButton);

expect(wrapper.findComponent(ReviewSubmissionSidePanel).exists()).toBe(false);

await statusButton.trigger('click');
await wrapper.vm.$nextTick();

expect(wrapper.findComponent(ReviewSubmissionSidePanel).exists()).toBe(true);
// assert that page is redirected to PageNames.COMMUNITY_LIBRARY_SUBMISSION
expect(wrapper.vm.$route.name).toEqual(RouteNames.COMMUNITY_LIBRARY_SUBMISSION);
expect(wrapper.vm.$route.params.submissionId).toEqual(submissionId);
});
});
11 changes: 11 additions & 0 deletions contentcuration/contentcuration/frontend/administration/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ChannelTable from './pages/Channels/ChannelTable';
import ChannelDetails from './pages/Channels/ChannelDetails';
import UserTable from './pages/Users/UserTable';
import UserDetails from './pages/Users/UserDetails';
import SubmissionDetailsModal from 'shared/views/communityLibrary/SubmissionDetailsModal/index.vue';

const router = new VueRouter({
routes: [
Expand All @@ -29,6 +30,16 @@ const router = new VueRouter({
props: true,
component: UserDetails,
},
{
name: RouteNames.COMMUNITY_LIBRARY_SUBMISSION,
path: '/community-library/:channelId/:submissionId',
component: SubmissionDetailsModal,
props: route => ({
channelId: route.params.channelId,
submissionId: route.params.submissionId,
adminReview: true,
}),
},
// Catch-all redirect to channels tab
{
path: '*',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const RouteNames = {
CATALOG_DETAILS: 'CATALOG_DETAILS',
CATALOG_FAQ: 'CATALOG_FAQ',
NEW_CHANNEL: 'NEW_CHANNEL',
COMMUNITY_LIBRARY_SUBMISSION: 'COMMUNITY_LIBRARY_SUBMISSION',
};

export const ListTypeToRouteMapping = {
Expand Down
Loading