Return communication database rows from communication API

This is a pretty big refactor of how communication works to start moving
us in the direction we want to go long-term. This adds the new
communication row and migrates existing reports to add rows for
communication.

There's also a bunch of automatic fixes from the new linter. I should
have added them separately, but whatever.
This commit is contained in:
Eli Ribble 2026-05-01 20:49:37 +00:00
parent a6ce0b7e67
commit a82732a49c
No known key found for this signature in database
41 changed files with 365 additions and 220 deletions

View file

@ -74,7 +74,7 @@
}"
@click="handleClick(comm.id)"
>
<ListCardPublicReport :comm="comm" />
<ListCardCommunication :comm="comm" />
</div>
</div>
</div>
@ -91,7 +91,7 @@
<script setup lang="ts">
import { computed, ref } from "vue";
import ListCardPublicReport from "@/components/ListCardPublicReport.vue";
import ListCardCommunication from "@/components/ListCardCommunication.vue";
import { Communication, LogEntry, PublicReport } from "@/type/api";
interface Props {

View file

@ -0,0 +1,92 @@
<template>
<!-- First row: icon, type badge, and time -->
<div class="justify-content-between align-items-center">
<div class="row">
<div class="d-flex align-items-center">
<div class="col">
<Tooltip placement="top" :title="tooltipTitleForCommunicationType()">
<i class="bi fs-4 me-2" :class="iconForReportType()"></i>
</Tooltip>
<Tooltip placement="top" :title="tooltipTitleForReportType()">
<i class="bi fs-4 me-2" :class="iconForCommunicationType()"></i>
</Tooltip>
</div>
<div class="col-6 text-end">
<small>
<Tooltip placement="top" :title="tooltipTitleForCreated()">
<TimeRelative :time="comm.created" />
</Tooltip>
</small>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import TimeRelative from "@/components/TimeRelative.vue";
import Tooltip from "@/components/Tooltip.vue";
import { formatAddress, formatDate } from "@/format";
import { Communication } from "@/type/api";
interface Props {
comm: Communication;
}
const props = defineProps<Props>();
function iconForCommunicationType(): string {
switch (props.comm.type) {
case "publicreport.compliance":
return "bi-card-checklist";
case "publicreport.nuisance":
return "bi-mosquito";
case "publicreport.water":
return "bi-droplet-fill";
default:
return "";
}
}
function iconForReportType(): string {
switch (props.comm.type) {
case "publicreport.compliance":
case "publicreport.nuisance":
case "publicreport.water":
return "bi-postcard";
case "email":
return "bi-envelope";
case "text":
return "bi-chat-dots";
default:
return "";
}
}
function tooltipTitleForCommunicationType(): string {
switch (props.comm.type) {
case "publicreport.compliance":
case "publicreport.nuisance":
case "publicreport.water":
return "A report made from a member of the public to report.mosquitoes.online";
case "email":
return "An email received from a member of the public";
case "text":
return "An SMS/MMS text message received from a member of the public";
default:
return "I'm actually not sure what this is. How are you even seeing this?";
}
}
function tooltipTitleForReportType(): string {
switch (props.comm.type) {
case "publicreport.compliance":
case "publicreport.nuisance":
case "publicreport.water":
return "A compliance report either made by scanning a door hanger or by receiving a personal letter through the mail";
case "publicreport.nuisance":
return "A report of a mosquito nuisance";
case "publicreport.water":
return "A report of standing water";
default:
return "I'm actually not sure what this is. This shouldn't be possible.";
}
}
function tooltipTitleForCreated(): string {
return `or at exactly ${formatDate(props.comm.created)}`;
}
</script>

View file

@ -1,65 +0,0 @@
<template>
<!-- First row: icon, type badge, and time -->
<div class="justify-content-between align-items-center">
<div class="row">
<div class="d-flex align-items-center">
<div class="col">
<i class="bi fs-4 me-2" :class="iconForType()"></i>
</div>
<div class="col-6 text-end">
<span class="badge" :class="colorForType()">
{{ titleForType() }}
</span>
</div>
</div>
</div>
<div class="row">
<small>
<TimeRelative :time="comm.created" />
</small>
</div>
</div>
</template>
<script setup lang="ts">
import TimeRelative from "@/components/TimeRelative.vue";
import { formatAddress } from "@/format";
import { Communication } from "@/type/api";
interface Props {
comm: Communication;
}
const props = defineProps<Props>();
function colorForType(): string {
if (props.comm.type == "publicreport.compliance") {
return "bg-secondary";
} else if (props.comm.type == "publicreport.nuisance") {
return "bg-danger";
} else if (props.comm.type == "publicreport.water") {
return "bg-info";
} else {
return "";
}
}
function iconForType(): string {
if (props.comm.type == "publicreport.compliance") {
return "bi-postcard";
} else if (props.comm.type == "publicreport.nuisance") {
return "bi-mosquito";
} else if (props.comm.type == "publicreport.water") {
return "bi-droplet-fill";
} else {
return "";
}
}
function titleForType(): string {
if (props.comm.type == "publicreport.compliance") {
return "Compliance";
} else if (props.comm.type == "publicreport.nuisance") {
return "Nuisance";
} else if (props.comm.type == "publicreport.water") {
return "Standing Water";
} else {
return "Unknown";
}
}
</script>