fix(ui): no raw JSON on Training list, pain no longer [object Object], add Chat button on GroupEdit, drop facebook/line from persona

- list_groups returns lightweight summaries (id/title/status/persona_count + product) —
  never the full personas array, so Training no longer shows a long JSON blob.
- PersonaForm toLines extracts .description/.text from pain/objection objects (fixes
  '[object Object]'); save re-wraps pains as {description}.
- GroupEdit persona cards get a 'แชท' (MessageSquare) button so you can start chatting
  right where you land after creating (chat was only on Personas page before).
- channel: default neutral 'social', removed facebook/line validation + removed from
  revealable_view (scenario now sets the tone, not fb/line).
All 9 backend suites pass. Rebuilt dist.
This commit is contained in:
Macky
2026-08-09 11:15:13 +07:00
parent f8719d77e3
commit cb2642a659
29 changed files with 69 additions and 42 deletions

View File

@@ -87,7 +87,13 @@ const objectionsText = ref('')
const negLeversText = ref('')
const busy = ref(false)
function toLines(a) { return Array.isArray(a) ? a.join('\n') : String(a || '') }
function toLines(a) {
if (!a) return ''
if (Array.isArray(a)) {
return a.map((x) => (typeof x === 'string' ? x : (x && x.description) || (x && x.text) || '')).filter(Boolean).join('\n')
}
return String(a)
}
function fromLines(s) { return s.split('\n').map(x => x.trim()).filter(Boolean) }
watch(() => props.persona, (p) => {
@@ -109,7 +115,7 @@ watch(() => props.persona, (p) => {
function save() {
emit('save', {
...d,
pains: fromLines(painsText.value),
pains: fromLines(painsText.value).map((t) => ({ description: t })),
objections: fromLines(objectionsText.value),
negotiation_levers: fromLines(negLeversText.value),
})

View File

@@ -43,7 +43,12 @@
</div>
<div class="muted">{{ p.profession }} · {{ p.age_group }} · {{ p.location }}</div>
<div class="muted">{{ p.personality }}</div>
<button class="edit-btn" @click="openEdit(p)"><Pencil :size="15" :stroke-width="1.8" /> {{ i18n.t('edit') }}</button>
<div class="row" style="gap:8px;margin-top:auto">
<router-link :to="`/groups/${gid}/chat/${p.id}`" style="flex:1;text-decoration:none">
<button class="primary" style="width:100%"><MessageSquare :size="16" :stroke-width="1.8" /> {{ i18n.t('chat') }}</button>
</router-link>
<button class="edit-btn" @click="openEdit(p)"><Pencil :size="15" :stroke-width="1.8" /> {{ i18n.t('edit') }}</button>
</div>
</div>
</div>
</div>
@@ -60,7 +65,7 @@
<script setup>
import { onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import { Sparkles, Users, Pencil } from 'lucide-vue-next'
import { Sparkles, Users, Pencil, MessageSquare } from 'lucide-vue-next'
import { api } from '../api'
import { i18n } from '../i18n'
import PersonaForm from '../components/PersonaForm.vue'