From 47f92b48bf35401d66244472d89bad8c024ceb02 Mon Sep 17 00:00:00 2001 From: Macky Date: Wed, 26 Aug 2026 14:04:47 +0700 Subject: [PATCH] =?UTF-8?q?fix(chat):=20remove=20manual=20finish=20button?= =?UTF-8?q?=20=E2=80=94=20sale=20auto-closes=20when=20the=20customer=20dec?= =?UTF-8?q?ides?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The realistic sales simulation must not offer a "Finish practice / จบการฝึก" button, because the chat is meant to auto-close on buy/walk/try (as originally decided in ffb7cdd). The finish button and its chatFinish handler were reintroduced in 3c22d88 and are now removed; the composer holds only Send and the debrief renders automatically once the session finishes. Regression test asserts no finish/summary button is rendered. --- frontend/src/views/Chat.spec.js | 16 ++++++++++++++++ frontend/src/views/Chat.vue | 19 ------------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/frontend/src/views/Chat.spec.js b/frontend/src/views/Chat.spec.js index b4b2e88..87b1c73 100644 --- a/frontend/src/views/Chat.spec.js +++ b/frontend/src/views/Chat.spec.js @@ -55,6 +55,22 @@ describe('Chat resume state', () => { expect(wrapper.text()).not.toContain('เลือกสถานการณ์') }) + it('does not render a manual finish/summary button — chat closes only on auto-close', async () => { + const { default: Chat } = await import('./Chat.vue') + const wrapper = mount(Chat, { + global: { stubs: { 'router-link': RouterLinkStub } }, + }) + await flushPromises() + + // The sale simulation must auto-close (buy/walk/try); no "จบการฝึก"/"Finish practice" + // button should interrupt the realistic conversation. + expect(wrapper.find('.composer').exists()).toBe(true) + expect(wrapper.text()).not.toContain('Finish practice') + expect(wrapper.text()).not.toContain('จบการฝึก') + // Only the send control; no ghost finish button. + expect(wrapper.find('button.ghost').exists()).toBe(false) + }) + it('starts a hidden-group admin chat in preview mode', async () => { mocks.api.chatResume.mockRejectedValue(new Error('no active session')) mocks.api.mySessions.mockResolvedValue({ sessions: [] }) diff --git a/frontend/src/views/Chat.vue b/frontend/src/views/Chat.vue index 8956b0a..e2489a8 100644 --- a/frontend/src/views/Chat.vue +++ b/frontend/src/views/Chat.vue @@ -72,9 +72,6 @@
-
@@ -161,22 +158,6 @@ async function begin() { } } -async function finish() { - if (sending.value) return - sending.value = true - try { - const res = await api.chatFinish(gid, pid) - debrief.value = res.debrief || null - messages.value = res.session?.messages || messages.value - phase.value = 'done' - scrollDown() - } catch (e) { - alert(i18n.t('chatActionFailed')) - } finally { - sending.value = false - } -} - onMounted(async () => { persona.value = (await api.getPersona(gid, pid)).persona if (auth.isAdmin) {