Add mobile-first kanban board view for Chorus triage #3
3 changed files with 50 additions and 9 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
import { updateItem } from '../api.js'
|
import { updateItem } from '../api.js'
|
||||||
|
import { DONATION_STAGES, OTHER_STAGES, OUTBOUND_STAGES, UNSORTED_STAGES, STAGE_LABELS } from '../stages.js'
|
||||||
|
|
||||||
const props = defineProps({ item: { type: Object, default: null } })
|
const props = defineProps({ item: { type: Object, default: null } })
|
||||||
const emit = defineEmits(['close', 'saved'])
|
const emit = defineEmits(['close', 'saved'])
|
||||||
|
|
@ -11,13 +12,6 @@ const stage = ref('')
|
||||||
const notes = ref('')
|
const notes = ref('')
|
||||||
const followUpDate = ref('')
|
const followUpDate = ref('')
|
||||||
|
|
||||||
const DONATION_STAGES = ['new', 'replied', 'pickup_scheduled', 'picked_up', 'logged_in_bookmark']
|
|
||||||
const OTHER_STAGES = ['new', 'done']
|
|
||||||
const OUTBOUND_STAGES = [
|
|
||||||
'new', 'reviewed', 'outreach_drafted', 'outreach_sent',
|
|
||||||
'replied', 'pickup_scheduled', 'picked_up', 'logged_in_bookmark',
|
|
||||||
]
|
|
||||||
|
|
||||||
watch(() => props.item, (item) => {
|
watch(() => props.item, (item) => {
|
||||||
if (!item) return
|
if (!item) return
|
||||||
senderId.value = item.sender_id || ''
|
senderId.value = item.sender_id || ''
|
||||||
|
|
@ -31,7 +25,7 @@ function stagesForType() {
|
||||||
if (props.item?.direction === 'outbound') return OUTBOUND_STAGES
|
if (props.item?.direction === 'outbound') return OUTBOUND_STAGES
|
||||||
if (type.value === 'donation') return DONATION_STAGES
|
if (type.value === 'donation') return DONATION_STAGES
|
||||||
if (type.value === 'other') return OTHER_STAGES
|
if (type.value === 'other') return OTHER_STAGES
|
||||||
return ['new']
|
return UNSORTED_STAGES
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(type, () => {
|
watch(type, () => {
|
||||||
|
|
@ -71,7 +65,7 @@ async function save() {
|
||||||
|
|
||||||
<label>Stage
|
<label>Stage
|
||||||
<select v-model="stage">
|
<select v-model="stage">
|
||||||
<option v-for="s in stagesForType()" :key="s" :value="s">{{ s }}</option>
|
<option v-for="s in stagesForType()" :key="s" :value="s">{{ STAGE_LABELS[s] || s }}</option>
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
|
|
||||||
19
frontend/src/stages.js
Normal file
19
frontend/src/stages.js
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
export const DONATION_STAGES = ['new', 'replied', 'pickup_scheduled', 'picked_up', 'logged_in_bookmark']
|
||||||
|
export const OTHER_STAGES = ['new', 'done']
|
||||||
|
export const OUTBOUND_STAGES = [
|
||||||
|
'new', 'reviewed', 'outreach_drafted', 'outreach_sent',
|
||||||
|
'replied', 'pickup_scheduled', 'picked_up', 'logged_in_bookmark',
|
||||||
|
]
|
||||||
|
export const UNSORTED_STAGES = ['new']
|
||||||
|
|
||||||
|
export const STAGE_LABELS = {
|
||||||
|
new: 'New',
|
||||||
|
replied: 'Replied',
|
||||||
|
pickup_scheduled: 'Pickup Scheduled',
|
||||||
|
picked_up: 'Picked Up',
|
||||||
|
logged_in_bookmark: 'Logged in Bookmark',
|
||||||
|
done: 'Done',
|
||||||
|
reviewed: 'Reviewed',
|
||||||
|
outreach_drafted: 'Outreach Drafted',
|
||||||
|
outreach_sent: 'Outreach Sent',
|
||||||
|
}
|
||||||
28
frontend/tests/stages.spec.js
Normal file
28
frontend/tests/stages.spec.js
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { describe, it, expect } from 'vitest'
|
||||||
|
import {
|
||||||
|
DONATION_STAGES, OTHER_STAGES, OUTBOUND_STAGES, UNSORTED_STAGES, STAGE_LABELS,
|
||||||
|
} from '../src/stages.js'
|
||||||
|
|
||||||
|
describe('stages.js', () => {
|
||||||
|
it('exports the expected stage lists', () => {
|
||||||
|
expect(DONATION_STAGES).toEqual([
|
||||||
|
'new', 'replied', 'pickup_scheduled', 'picked_up', 'logged_in_bookmark',
|
||||||
|
])
|
||||||
|
expect(OTHER_STAGES).toEqual(['new', 'done'])
|
||||||
|
expect(OUTBOUND_STAGES).toEqual([
|
||||||
|
'new', 'reviewed', 'outreach_drafted', 'outreach_sent',
|
||||||
|
'replied', 'pickup_scheduled', 'picked_up', 'logged_in_bookmark',
|
||||||
|
])
|
||||||
|
expect(UNSORTED_STAGES).toEqual(['new'])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('has a human-readable label for every stage across all lists', () => {
|
||||||
|
const allStages = new Set([
|
||||||
|
...DONATION_STAGES, ...OTHER_STAGES, ...OUTBOUND_STAGES, ...UNSORTED_STAGES,
|
||||||
|
])
|
||||||
|
for (const stage of allStages) {
|
||||||
|
expect(STAGE_LABELS[stage]).toBeTruthy()
|
||||||
|
expect(STAGE_LABELS[stage]).not.toBe(stage)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
Loading…
Reference in a new issue