Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions frontend/src/components/Card.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@

<div class="card" class:fill>
<div class="card-header" class:dropdown on:click={() => dropdownActive = dropdown && !dropdownActive}>
<h4 class="card-title">
<slot name="title">
No Title :(
</slot>
</h4>
<div class="card-title-row">
<h4 class="card-title">
<slot name="title">
No Title :(
</slot>
</h4>
<slot name="title-items"></slot>
</div>
</div>
<div class="card-body" class:dropdown class:dropdownActive class:dropdownInactive={dropdown && !dropdownActive} {ref}>
<div class="inner" class:dropdown>
Expand Down Expand Up @@ -54,7 +57,13 @@
color: white;
font-size: 22px;
font-weight: bolder;
}

.card-title-row {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 20px;
margin: 0;
}
Expand Down
26 changes: 18 additions & 8 deletions frontend/src/components/ColumnSelector.svelte
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
<section>
<Button on:click={toggleDropdown} bind:clientWidth={buttonWidth}>{label}</Button>
<div class="dropdown" bind:this={dropdown} style="min-width: {buttonWidth}px">
<section class="column-selector">
<Button on:click={toggleDropdown}>{label}</Button>
<div class="dropdown" bind:this={dropdown}>
{#each options as option}
<div class="option">
<input type="checkbox" checked={selected.includes(option)} on:change={() => handleChange(option)} />
<span>{option}</span>
<label>
<input type="checkbox" checked={selected.includes(option)} on:change={() => handleChange(option)}>
<span>{option}</span>
</label>
</div>
{/each}
</div>
</section>

<style>
.column-selector {
position: relative;
display: inline-block;
font-size: 16px;
}

.dropdown {
display: none;
position: absolute;
margin-top: 6px;
z-index: 1;
top: 42px;
right: 0;
padding: 5px 10px;
background-color: var(--background);
border-radius: 4px;
Expand All @@ -26,8 +36,9 @@
display: flex;
flex-direction: row;
align-items: center;
text-wrap: nowrap;
gap: 4px;
font-size: 18px;
font-size: 16px;
}

input {
Expand Down Expand Up @@ -61,7 +72,6 @@
}

let dropdown;
let buttonWidth;

function toggleDropdown() {
if (dropdown.style.display === 'block') {
Expand Down
17 changes: 8 additions & 9 deletions frontend/src/views/Tickets.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,6 @@
Filters
</span>
<div slot="body" class="filter-wrapper">
<div>
<label class="form-label">Show Columns</label>
<ColumnSelector
options={["ID", "Panel", "User", "Opened Time", "Claimed By", "Last Message Time", "Awaiting Response"]}
bind:selected={selectedColumns}
/>
</div>

<Dropdown col2 label="Sort Tickets By..." bind:value={sortMethod}>
<option value="id_asc">Ticket ID (Ascending) / Oldest First</option>
<option value="id_desc">Ticket ID (Descending) / Newest First</option>
Expand All @@ -24,7 +16,14 @@
</Card>

<Card footer={false}>
<span slot="title">Open Tickets</span>
<span slot="title">
Open Tickets
</span>
<ColumnSelector
options={["ID", "Panel", "User", "Opened Time", "Claimed By", "Last Message Time", "Awaiting Response"]}
bind:selected={selectedColumns}
slot="title-items"
/>
<div slot="body" class="body-wrapper">
<table class="nice">
<thead>
Expand Down
66 changes: 45 additions & 21 deletions frontend/src/views/Transcripts.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -50,38 +50,45 @@
<span slot="title">
Transcripts
</span>
<ColumnSelector
options={["Ticket ID", "Username", "Rating", "Close Reason", "Transcript"]}
bind:selected={selectedColumns}
slot="title-items"
/>

<div slot="body" class="main-col">
<table class="nice">
<thead>
<tr>
<th>Ticket ID</th>
<th>Username</th>
<th>Rating</th>
<th class="reason">Close Reason</th>
<th>Transcript</th>
<th class:visible={selectedColumns.includes('Ticket ID')}>Ticket ID</th>
<th class:visible={selectedColumns.includes('Username')}>Username</th>
<th class:visible={selectedColumns.includes('Rating')}>Rating</th>
<th class:visible={selectedColumns.includes('Close Reason')}>Close Reason</th>
<th class:visible={selectedColumns.includes('Transcript')}>Transcript</th>
</tr>
</thead>
<tbody>
{#each transcripts as transcript}
<tr>
<td>{transcript.ticket_id}</td>
<td>{transcript.username}</td>
<td>
<td class:visible={selectedColumns.includes('Ticket ID')}>{transcript.ticket_id}</td>
<td class:visible={selectedColumns.includes('Username')}>{transcript.username}</td>
<td class:visible={selectedColumns.includes('Rating')}>
{#if transcript.rating}
{transcript.rating} ⭐
{:else}
No rating
{/if}
</td>
<td class="reason">{transcript.close_reason || 'No reason specified'}</td>
{#if transcript.has_transcript}
<td>
<td class:visible={selectedColumns.includes('Close Reason')}>
{transcript.close_reason || 'No reason specified'}
</td>
<td class:visible={selectedColumns.includes('Transcript')}>
{#if transcript.has_transcript}
<Navigate to="{`/manage/${guildId}/transcripts/view/${transcript.ticket_id}`}" styles="link">
<Button>View</Button>
</Navigate>
</td>
{/if}
{/if}
</td>
</tr>
{/each}
</tbody>
Expand All @@ -104,7 +111,6 @@
import Card from '../components/Card.svelte'
import Input from '../components/form/Input.svelte'
import Button from '../components/Button.svelte'

import {notifyError, withLoadingScreen} from '../js/util'
import {onMount} from "svelte";
import {dropdown} from "../js/stores";
Expand All @@ -114,6 +120,7 @@
import {Navigate} from 'svelte-router-spa'
import PanelDropdown from "../components/PanelDropdown.svelte";
import Dropdown from "../components/form/Dropdown.svelte";
import ColumnSelector from "../components/ColumnSelector.svelte";

setDefaultHeaders();

Expand All @@ -129,6 +136,23 @@
const pageLimit = 15;
let page = 1;

// Show Columns logic
let selectedColumns = ['Ticket ID', 'Username', 'Rating', 'Close Reason', 'Transcript'];
const columnStorageKey = 'transcript_list:selected_columns';

$: selectedColumns, updateColumnStorage();

function updateColumnStorage() {
window.localStorage.setItem(columnStorageKey, JSON.stringify(selectedColumns));
}

function loadColumnSettings() {
const columns = window.localStorage.getItem(columnStorageKey);
if (columns) {
selectedColumns = JSON.parse(columns);
}
}

let handleInputTicketId = () => {
filterSettings.username = undefined;
filterSettings.userId = undefined;
Expand Down Expand Up @@ -244,6 +268,7 @@
}

withLoadingScreen(async () => {
loadColumnSettings();
await Promise.all([
loadPanels(),
loadData({})
Expand Down Expand Up @@ -282,10 +307,6 @@
height: 100%;
}

.centre {
justify-content: center !important;
}

.form-wrapper {
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -361,9 +382,12 @@
.col {
width: 100%;
}
}

.reason {
display: none;
}
th, td {
display: none;
}
th.visible, td.visible {
display: table-cell;
}
</style>