datatracker/client/components/ChatLog.vue
Robert Sparks 50668c97cd
feat: apis for attaching chatlogs and polls to session materials (#4488)
* feat: apis for attaching chatlogs and polls to session materials

* fix: anticipate becoming tzaware, and improve guard against attempts to provide docs for sessions that have no official timeslot assignment.

* fix: get chatlog upload to actually work

Modifications to several initial implementation decisions.
Updates to the fixtures.

* fix: test polls upload

Refactored test to reduce duplicate code

* fix: allow api keys to be created for the new endpoints

* feat: add ability to view chatlog and polls documents. Show links in session materials.

* fix: commit new template

* fix: typo in migration signatures

* feat: add main doc page handling for polls. Improve tests.

* feat: chat log vue component + embedded vue loader

* feat: render polls using Vue

* fix: address pug syntax review comments from Nick.

* fix: repair remaining mention of chat log from copymunging

* fix: use double-quotes in html attributes

* fix: provide missing choices update migration

* test: silence html validator empty attr warnings

* test: fix test_runner config

* fix: locate session when looking at a dochistory object for polls or chatlog

Co-authored-by: Nicolas Giard <github@ngpixel.com>
2022-10-13 09:20:36 -05:00

99 lines
1.9 KiB
Vue

<template lang="pug">
.chatlog
n-timeline(
v-if='state.items.length > 0'
:icon-size='18'
size='large'
)
n-timeline-item(
v-for='item of state.items'
:key='item.id'
type='default'
:color='item.color'
:title='item.author'
:time='item.time'
)
template(#default)
div(v-html='item.text')
span.text-muted(v-else)
em No chat log available.
</template>
<script setup>
import { onMounted, reactive } from 'vue'
import { DateTime } from 'luxon'
import {
NTimeline,
NTimelineItem
} from 'naive-ui'
// PROPS
const props = defineProps({
componentId: {
type: String,
required: true
}
})
// STATE
const state = reactive({
items: []
})
// bs5 colors
const colors = [
'#0d6efd',
'#dc3545',
'#20c997',
'#6f42c1',
'#fd7e14',
'#198754',
'#0dcaf0',
'#d63384',
'#ffc107',
'#6610f2',
'#adb5bd'
]
// MOUNTED
onMounted(() => {
const authorColors = {}
// Get chat log data from embedded json tag
const chatLog = JSON.parse(document.getElementById(`${props.componentId}-data`).textContent || '[]')
if (chatLog.length > 0) {
let idx = 1
let colorIdx = 0
for (const logItem of chatLog) {
// -> Get unique color per author
if (!authorColors[logItem.author]) {
authorColors[logItem.author] = colors[colorIdx]
colorIdx++
if (colorIdx >= colors.length) {
colorIdx = 0
}
}
// -> Generate log item
state.items.push({
id: `logitem-${idx}`,
color: authorColors[logItem.author],
author: logItem.author,
text: logItem.text,
time: DateTime.fromISO(logItem.time).toFormat('dd LLLL yyyy \'at\' HH:mm:ss a ZZZZ')
})
idx++
}
}
})
</script>
<style lang="scss">
.chatlog {
.n-timeline-item-content__content > div > p {
margin-bottom: 0;
}
}
</style>