Email report on every report page; kiosk long-name fix
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<h1>Toner Report</h1>
|
||||
<div class="header-actions">
|
||||
<button v-if="!loading && !error" class="btn btn-secondary" @click="exportCSV">Export CSV</button>
|
||||
<EmailReportButton v-if="!loading && !error" subject="Toner / Supply Report"
|
||||
<EmailReportButton v-if="!loading && !error && canemail" subject="Toner / Supply Report"
|
||||
:columns="emailColumns" :rows="emailRows" />
|
||||
<router-link to="/reports" class="btn btn-secondary">Back to Reports</router-link>
|
||||
</div>
|
||||
@@ -133,9 +133,16 @@
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { printersApi } from '@/api'
|
||||
import EmailReportButton from '@/components/EmailReportButton.vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import LocationMapTooltip from '@/components/LocationMapTooltip.vue'
|
||||
import { getPrinterHostnameTemplate } from '@/utils/siteSettings'
|
||||
|
||||
// Emailing a report is the reports.export permission the endpoint enforces.
|
||||
// Offering the button to somebody who will only get a 403 is worse than not
|
||||
// offering it.
|
||||
const authStore = useAuthStore()
|
||||
const canemail = computed(() => authStore.hasPermission('reports.export'))
|
||||
|
||||
const emailColumns = [
|
||||
{ key: 'printer', label: 'Printer' },
|
||||
{ key: 'hostname', label: 'Hostname' },
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
@click="act(drive, 'checkin')">
|
||||
<span class="drive-name">
|
||||
{{ drive.device_id }}
|
||||
<small v-if="drive.device_desc">{{ drive.device_desc }}</small>
|
||||
<small v-if="drive.device_desc" class="drive-desc">{{ drive.device_desc }}</small>
|
||||
</span>
|
||||
<span class="drive-action return">Return</span>
|
||||
</button>
|
||||
@@ -83,7 +83,7 @@
|
||||
@click="act(drive, 'checkout')">
|
||||
<span class="drive-name">
|
||||
{{ drive.device_id }}
|
||||
<small v-if="drive.device_desc">{{ drive.device_desc }}</small>
|
||||
<small v-if="drive.device_desc" class="drive-desc">{{ drive.device_desc }}</small>
|
||||
<small v-if="drive.locker_location">Locker {{ drive.locker_location }}</small>
|
||||
</span>
|
||||
<span class="drive-action take">Take</span>
|
||||
@@ -112,7 +112,7 @@
|
||||
@click="act(drive, 'checkin', true)">
|
||||
<span class="drive-name">
|
||||
{{ drive.device_id }}
|
||||
<small>{{ drive.holdername || 'somebody else' }}</small>
|
||||
<small class="drive-desc">{{ drive.holdername || 'somebody else' }}</small>
|
||||
</span>
|
||||
<span class="drive-action return">Return</span>
|
||||
</button>
|
||||
@@ -436,8 +436,29 @@ function reset () {
|
||||
cursor: pointer;
|
||||
}
|
||||
.drive-row:disabled { opacity: 0.5; }
|
||||
.drive-name { display: flex; flex-direction: column; gap: 0.15rem; }
|
||||
/* The name has to YIELD. A flex item defaults to min-width:auto, so a long
|
||||
label kept its intrinsic width and shoved Take or Return out through the side
|
||||
of the card - a drive nobody could take. `anywhere` breaks the labels that
|
||||
carry no spaces at all, which a serial-style name often does not. */
|
||||
.drive-name {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.15rem;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.drive-name small { color: var(--text-light); font-size: 0.85rem; }
|
||||
/* Two lines of description is enough to tell two drives apart; more just makes
|
||||
one card tall and every card in its row tall with it. The locker line below
|
||||
is never clipped - it is how somebody finds the thing. */
|
||||
.drive-desc {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
.drive-action {
|
||||
flex: 0 0 auto;
|
||||
padding: 0.5rem 1.1rem;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<h1>Warranty Report</h1>
|
||||
<div class="header-actions">
|
||||
<button v-if="!loading" class="btn btn-secondary" @click="exportCSV">Export CSV</button>
|
||||
<EmailReportButton v-if="!loading" subject="Warranty Report"
|
||||
<EmailReportButton v-if="!loading && canemail" subject="Warranty Report"
|
||||
:columns="emailColumns" :rows="emailRows" />
|
||||
<router-link to="/reports" class="btn btn-secondary">Back to Reports</router-link>
|
||||
</div>
|
||||
@@ -65,8 +65,15 @@
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { warrantyApi } from '@/api'
|
||||
import EmailReportButton from '@/components/EmailReportButton.vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import MachineMapChip from '../components/MachineMapChip.vue'
|
||||
|
||||
// Emailing a report is the reports.export permission the endpoint enforces.
|
||||
// Offering the button to somebody who will only get a 403 is worse than not
|
||||
// offering it.
|
||||
const authStore = useAuthStore()
|
||||
const canemail = computed(() => authStore.hasPermission('reports.export'))
|
||||
|
||||
const loading = ref(true)
|
||||
const counts = ref({})
|
||||
const buckets = ref({})
|
||||
|
||||
Reference in New Issue
Block a user