-
Notifications
You must be signed in to change notification settings - Fork 252
Show resubmit channel to community library CTA after channel publish #5541
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: unstable
Are you sure you want to change the base?
Show resubmit channel to community library CTA after channel publish #5541
Conversation
AlexVelezLl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @taoerman! Looking good, just a little concerned about the KModal styles overrides, and noted a couple of nitpicks. Thanks!
| <template #actions> | ||
| <div class="resubmit-modal-actions"> | ||
| <KButton | ||
| class="resubmit-modal-dismiss-btn" | ||
| :style="dismissButtonStyles" | ||
| data-test="dismiss-button" | ||
| @click="handleDismiss" | ||
| > | ||
| {{ dismissButtonText }} | ||
| </KButton> | ||
| <KButton | ||
| class="resubmit-modal-resubmit-btn" | ||
| primary | ||
| data-test="resubmit-button" | ||
| @click="handleResubmit" | ||
| > | ||
| {{ resubmitButtonText }} | ||
| </KButton> | ||
| </div> | ||
| </template> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason why we need these buttons to be in the #actions slot instead of using the KModal props? (It is not completely incorrect, it is more so because this slot is just for when we want specific styles handling on KModal actions)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Alex, just using KModal props could make code simpler! Fixed!
| [data-test='resubmit-modal'], | ||
| [data-test='resubmit-modal'] > *, | ||
| [data-test='resubmit-modal'] [role='dialog'], | ||
| [data-test='resubmit-modal'] .KModal, | ||
| [data-test='resubmit-modal'] .modal { | ||
| width: 500px !important; | ||
| max-width: 500px !important; | ||
| max-height: 284px !important; | ||
| } | ||
| [data-test='resubmit-modal'] h1, | ||
| [data-test='resubmit-modal'] h2, | ||
| [data-test='resubmit-modal'] h3, | ||
| [data-test='resubmit-modal'] h4, | ||
| [data-test='resubmit-modal'] .modal-title, | ||
| [data-test='resubmit-modal'] [class*='title'] { | ||
| width: 452px; | ||
| height: 52px; | ||
| font-family: 'Noto Sans', sans-serif; | ||
| font-size: 20px; | ||
| font-weight: 600; | ||
| line-height: 130%; | ||
| letter-spacing: 0%; | ||
| vertical-align: middle; | ||
| } | ||
| .resubmit-modal-content { | ||
| padding: 8px 0; | ||
| margin-top: 35px; | ||
| } | ||
| .resubmit-modal-description, | ||
| .resubmit-modal-question { | ||
| width: 100%; | ||
| min-height: 40px; | ||
| padding: 0; | ||
| margin: 0; | ||
| font-family: 'Noto Sans', sans-serif; | ||
| font-size: 14px; | ||
| font-weight: 400; | ||
| line-height: 140%; | ||
| letter-spacing: 0%; | ||
| vertical-align: middle; | ||
| } | ||
| .resubmit-modal-actions { | ||
| display: flex; | ||
| gap: 10px; | ||
| justify-content: flex-end; | ||
| width: 452px; | ||
| min-height: 40px; | ||
| padding-top: 16px; | ||
| } | ||
| .resubmit-modal-dismiss-btn:hover { | ||
| background-color: var(--hover-bg-color) !important; | ||
| } | ||
| .resubmit-modal-resubmit-btn { | ||
| height: 40px; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, are all of these styles added to match exactly the Figma specs? I don't think we need almost any of them; we can rely on KModal's inner styles to have a consistent view across modals in the application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I added these styles to match Figma. But I found only using KModal's inner styles could also match Figma. Thanks Alex!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the resubmit CL modal be checked and triggered by this component? If so, we can show a loader here, until that check finishes, and then we can emit a showResubmitCommunityLibraryModal or something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added! But when I tried to test it manually. The process of publishing was so fast. I could not even see the loader. LOL!
| this.resubmitModalChannel = { | ||
| ...this.currentChannel, | ||
| version: latestSubmission.channel_version, | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We won't need to update the channel version in this way after this is merged!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it!
| if (Array.isArray(response)) { | ||
| submissions = response; | ||
| } else if (response && response.results && Array.isArray(response.results)) { | ||
| submissions = response.results; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to check the response type. In this point of the application, it should always be the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, Thanks!
| computed: { | ||
| title() { | ||
| return communityChannelsStrings.resubmitModalTitle$(); | ||
| }, | ||
| description() { | ||
| return communityChannelsStrings.resubmitModalBodyFirst$({ | ||
| channelName: this.channel.name, | ||
| version: this.channel.version, | ||
| }); | ||
| }, | ||
| question() { | ||
| return communityChannelsStrings.resubmitModalBodySecond$(); | ||
| }, | ||
| dismissButtonText() { | ||
| return communityChannelsStrings.dismissButton$(); | ||
| }, | ||
| resubmitButtonText() { | ||
| return communityChannelsStrings.resubmitButton$(); | ||
| }, | ||
| dismissButtonStyles() { | ||
| return { | ||
| color: this.$themeTokens.primary, | ||
| backgroundColor: this.$themePalette.grey.v_100, | ||
| '--hover-bg-color': this.$themePalette.grey.v_200, | ||
| }; | ||
| }, | ||
| }, | ||
| methods: { | ||
| handleDismiss() { | ||
| this.$emit('dismiss'); | ||
| this.$emit('input', false); | ||
| }, | ||
| handleResubmit() { | ||
| this.$emit('resubmit'); | ||
| this.$emit('input', false); | ||
| }, | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, and just one last thing! 😅 Could we migrate this to use the Vue Composition API instead? Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I've migrated!
AlexVelezLl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found a couple of things that can be changed to have a better consistency with other modals 👐 .
| value: { | ||
| type: Boolean, | ||
| default: false, | ||
| }, | ||
| channel: { | ||
| type: Object, | ||
| required: true, | ||
| validator(value) { | ||
| return value && typeof value.name === 'string' && typeof value.version === 'number'; | ||
| }, | ||
| }, | ||
| latestSubmissionVersion: { | ||
| type: Number, | ||
| default: null, | ||
| }, | ||
| }); | ||
| const emit = defineEmits(['dismiss', 'resubmit', 'input']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oooh, similar to what we did for the DeleteModal here, could we also use the @close event for the parent component to close the Modal instead of using dismiss and v-model? So we can keep this consistent pattern for rendering modals!
| latestSubmissionVersion: { | ||
| type: Number, | ||
| default: null, | ||
| }, | ||
| }); | ||
| const emit = defineEmits(['dismiss', 'resubmit', 'input']); | ||
| const title = computed(() => communityChannelsStrings.resubmitModalTitle$()); | ||
| const publishedVersion = computed(() => { | ||
| return props.latestSubmissionVersion != null | ||
| ? props.latestSubmissionVersion | ||
| : props.channel.version; | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
latestSubmissionVersion should be required as well. If this prop is null, we should automatically close the side panel, since we need this information to be accurate when showing the modal; otherwise, it may confuse users.
| const mode = ref(PublishModes.LIVE); | ||
| const version_notes = ref(''); | ||
| const submitting = ref(false); | ||
| const checkingResubmit = ref(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can just use the current submitting loading ref instead of creating a new one, because at the end, this process of checking the latest submission could be part of the "submission" process.
| <span | ||
| v-if="checkingResubmit" | ||
| class="loader-wrapper" | ||
| > | ||
| <KCircularLoader :size="16" /> | ||
| </span> | ||
| <span v-else>{{ submitText }}</span> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't usually change the text button to a circular loader while something is loading, so we can just skip it!
| } catch (error) { | ||
| store.dispatch('shared/handleAxiosError', error); | ||
| } finally { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, let's do nothing if something fails, let's make this call just optional, and if it fails, it shouldn't block the normal user workflow.
| if (submissions.length > 0) { | ||
| const latestSubmission = submissions[0]; | ||
| emit('showResubmitCommunityLibraryModal', { | ||
| channel: currentChannel.value ? { ...currentChannel.value } : null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
currentChannel.value should always be defined at this point, so lets just skip the null check
| const latestSubmission = submissions[0]; | ||
| emit('showResubmitCommunityLibraryModal', { | ||
| channel: currentChannel.value ? { ...currentChannel.value } : null, | ||
| latestSubmissionVersion: latestSubmission?.channel_version ?? null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This latestSubmission ref should also always be defined at this point, the same with the channel_version, since this is a required field in the backend model, so that we can skip the null checks here too!
| } | ||
| function handleResubmit() { | ||
| emit('resubmit'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's also emit the 'close' event when resubmitting, so that the parent component can handle both events separately, without needing to close the modal when the resubmit event is emitted.
| handleResubmit() { | ||
| this.showResubmitModal = false; | ||
| this.showSubmitToCommunityLibrarySidePanel = true; | ||
| }, | ||
| handleDismissResubmit() { | ||
| this.showResubmitModal = false; | ||
| this.resubmitModalChannel = null; | ||
| this.resubmitModalSubmissionVersion = null; | ||
| }, | ||
| handleShowResubmitModal({ channel, latestSubmissionVersion }) { | ||
| this.resubmitModalChannel = channel; | ||
| this.resubmitModalSubmissionVersion = latestSubmissionVersion || null; | ||
| this.showResubmitModal = true; | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although less common, there is a more handy way to pass these multiple variables needed for showing the ResubmitChannelModal, and it is just storing the entire emitted object, and checking if this object is null to show the ResubmitChannelModal.
i.e., we could instead do something like this:
<PublishSidePanel
v-if="showPublishSidePanel"
@close="showPublishSidePanel = false"
@showResubmitCommunityLibraryModal="e => resubmitModalData = e" // we store the whole object without unwrapping it
/>And then in the ResubmitChannelModal rendering:
<ResubmitChannelModal
v-if="resubmitModalData" // We check if the `resubmitModalData` is defined
:channel="resubmitModalData.channel" // since at this point we know this ref is defined, we can access its properties
:latestSubmissionVersion="resubmitModalData.latestSubmissionVersion"
@resubmit="handleResubmit"
@close="resubmitModalData = null" // Set it to null instead of false since this variable is expected to be an object
/>With this, we prevent any potential regression because of data corruption (e.g., we set showResubmitModal but not resubmitModalChannel or resubmitModalSubmissionVersion), and save us some lines in the component.
| resubmitButton: { | ||
| message: 'RESUBMIT', | ||
| context: 'Button in the resubmit modal to open the submit to Community Library side panel', | ||
| }, | ||
| dismissButton: { | ||
| message: 'DISMISS', | ||
| context: 'Button in the resubmit modal to dismiss the modal', | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We usually use the Action suffix instead of Button, so for consistency, we can rename these strings to be resubmitAction and dismissAction.
And we can set the message to be just "Resubmit" and "Dismiss", and KButton will take care of using the upper case if needed.
Summary
Implemented ResubmitChannelModal to prompt users to resubmit a channel to the Community Library when publishing a channel that already has submissions. The modal appears immediately on publish click (not after completion, another issue has added a loader to make sure the side panel would load updated data from backend) and shows the channel name and the version already in the submission queue.
References
Fixed #5451
Reviewer guidance
test manually.