From c8a825a2e6412d32c2cb01412a84ca0a238f38c8 Mon Sep 17 00:00:00 2001 From: Abhishek-Punhani Date: Wed, 27 May 2026 14:23:02 +0530 Subject: [PATCH 1/2] Update HintsEditor layout according to new figma specs and added collapse behavior Signed-off-by: Abhishek-Punhani --- .../HintsEditor/HintsEditor.spec.js | 25 +- .../components/HintsEditor/HintsEditor.vue | 295 ++++++++++++------ 2 files changed, 220 insertions(+), 100 deletions(-) diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.spec.js b/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.spec.js index ddf9838d19..4cc2035f3e 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.spec.js +++ b/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.spec.js @@ -20,6 +20,10 @@ const renderComponent = props => { }); }; +const openHintsSection = async user => { + await user.click(screen.getByText(HintsEditor.$trs.hintsLabel)); +}; + const getHintCards = () => { return screen.getAllByTestId('hint'); }; @@ -31,29 +35,35 @@ const clickToolbarAction = async ({ action, hintIdx, user }) => { }; describe('HintsEditor', () => { - it('smoke test', () => { + it('smoke test', async () => { + const user = userEvent.setup(); renderComponent(); + await openHintsSection(user); expect( screen.getByRole('button', { name: HintsEditor.$trs.newHintBtnLabel }), ).toBeInTheDocument(); }); - it('shows an empty-state message when a question has no hints', () => { + it('shows an empty-state message when a question has no hints', async () => { + const user = userEvent.setup(); renderComponent({ hints: [], }); + await openHintsSection(user); expect(screen.getByText(HintsEditor.$trs.noHintsPlaceholder)).toBeInTheDocument(); }); - it('shows hints in the same order as the question', () => { + it('shows hints in the same order as the question', async () => { + const user = userEvent.setup(); renderComponent({ hints: [ { hint: 'First hint', order: 1 }, { hint: 'Second hint', order: 2 }, ], }); + await openHintsSection(user); const hintCards = getHintCards(); expect(within(hintCards[0]).getByText('First hint')).toBeInTheDocument(); @@ -69,6 +79,7 @@ describe('HintsEditor', () => { ], openHintIdx: 1, }); + await openHintsSection(user); const hintCards = getHintCards(); const hintTextField = within(hintCards[1]).getByRole('textbox'); @@ -92,6 +103,7 @@ describe('HintsEditor', () => { { hint: 'Third hint', order: 3 }, ], }); + await openHintsSection(user); await user.click(screen.getByRole('button', { name: HintsEditor.$trs.newHintBtnLabel })); @@ -114,6 +126,7 @@ describe('HintsEditor', () => { ], openHintIdx: 0, }); + await openHintsSection(user); const hintCards = getHintCards(); await user.click(hintCards[1]); @@ -131,6 +144,7 @@ describe('HintsEditor', () => { ], openHintIdx: 1, }); + await openHintsSection(user); await clickToolbarAction({ action: AssessmentItemToolbarActions.MOVE_ITEM_UP, @@ -156,6 +170,7 @@ describe('HintsEditor', () => { ], openHintIdx: 0, }); + await openHintsSection(user); await clickToolbarAction({ action: AssessmentItemToolbarActions.MOVE_ITEM_UP, @@ -176,6 +191,7 @@ describe('HintsEditor', () => { ], openHintIdx: 0, }); + await openHintsSection(user); await clickToolbarAction({ action: AssessmentItemToolbarActions.MOVE_ITEM_DOWN, @@ -201,6 +217,7 @@ describe('HintsEditor', () => { ], openHintIdx: 1, }); + await openHintsSection(user); await clickToolbarAction({ action: AssessmentItemToolbarActions.MOVE_ITEM_DOWN, @@ -221,6 +238,7 @@ describe('HintsEditor', () => { ], openHintIdx: 0, }); + await openHintsSection(user); await clickToolbarAction({ action: AssessmentItemToolbarActions.DELETE_ITEM, @@ -242,6 +260,7 @@ describe('HintsEditor', () => { ], openHintIdx: 1, }); + await openHintsSection(user); await clickToolbarAction({ action: AssessmentItemToolbarActions.DELETE_ITEM, diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.vue b/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.vue index 05ad7ebf85..2b20f44d12 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.vue @@ -1,39 +1,127 @@ @@ -159,6 +195,7 @@ }, data() { return { + sectionOpen: false, toolbarIconActions: [ AssessmentItemToolbarActions.MOVE_ITEM_UP, AssessmentItemToolbarActions.MOVE_ITEM_DOWN, @@ -173,6 +210,23 @@ const { windowBreakpoint } = useKResponsiveWindow(); return windowBreakpoint.value ?? 0; }, + buttonAppearanceOverrides() { + return { + backgroundColor: this.$themePalette.grey.v_50, + color: `${this.$themePalette.grey.v_700} !important`, + fontSize: '14px', + fontWeight: '600', + textTransform: 'none', + ':hover': { + backgroundColor: this.$themePalette.grey.v_100, + }, + }; + }, + hintPlaceholderStyle() { + return { + color: this.$themePalette.grey.v_600, + }; + }, }, methods: { emitOpen(hintIdx) { @@ -187,6 +241,14 @@ isHintOpen(hintIdx) { return hintIdx === this.openHintIdx; }, + isHintEmpty(hint) { + return !hint.hint || !hint.hint.trim(); + }, + hintDisplayText(hint, hintIdx) { + return this.isHintEmpty(hint) + ? this.$tr('hintPlaceholder', { index: hintIdx + 1 }) + : hint.hint; + }, isHintFirst(hintIdx) { return hintIdx === 0; }, @@ -316,9 +378,10 @@ }, }, $trs: { - hintsLabel: 'Hints', + hintsLabel: 'Hints (optional)', noHintsPlaceholder: 'Question has no hints', - newHintBtnLabel: 'New hint', + newHintBtnLabel: 'Add hint', + hintPlaceholder: 'Enter hint {index}...', }, }; @@ -327,6 +390,33 @@ From 076780e6a211698a4442f56367f3f17189bc81d6 Mon Sep 17 00:00:00 2001 From: Abhishek-Punhani Date: Wed, 27 May 2026 18:13:18 +0530 Subject: [PATCH 2/2] refactor: update new hint button to use KIcon via slot with custom styling Signed-off-by: Abhishek-Punhani --- .../components/HintsEditor/HintsEditor.vue | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.vue b/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.vue index 2b20f44d12..5a7add10d5 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.vue +++ b/contentcuration/contentcuration/frontend/channelEdit/components/HintsEditor/HintsEditor.vue @@ -141,12 +141,19 @@ :text="$tr('newHintBtnLabel')" class="hint-editor-button" :style="{ border: `1px dashed ${$themePalette.grey.v_400}` }" - icon="plus" data-test="newHintBtn" appearance="flat-button" :appearanceOverrides="buttonAppearanceOverrides" @click="addNewHint" - /> + > + + @@ -443,8 +450,16 @@ } .hint-editor-button { + justify-content: center; width: 100%; margin-top: 10px; } + .add-hint-icon { + position: relative; + top: 0; + font-size: 14px; + font-weight: 600; + } +