From 8259c387e596dc81529a02b8fb2aad2d1ba91617 Mon Sep 17 00:00:00 2001 From: bytedream <bytedream@protonmail.com> Date: Tue, 29 Aug 2023 14:23:06 +0200 Subject: [PATCH] make admin users table resizable --- src/lib/components/utils.ts | 14 +++-- src/routes/admin/admin/+page.svelte | 14 +++-- src/routes/admin/users/+page.svelte | 83 +++++++++++++++++++++-------- 3 files changed, 79 insertions(+), 32 deletions(-) diff --git a/src/lib/components/utils.ts b/src/lib/components/utils.ts index 9bb5bc0..b417c64 100644 --- a/src/lib/components/utils.ts +++ b/src/lib/components/utils.ts @@ -21,17 +21,21 @@ export function resizeTableColumn(event: MouseEvent, dragOffset: number) { const table = element.parentElement!.parentElement!.parentElement as HTMLTableElement; let resizeRow: HTMLTableRowElement; - if (table.tBodies[0].rows[0].hidden) { - resizeRow = table.rows[0]; + if (table.tBodies[0].rows[0].hasAttribute('resize-row')) { + resizeRow = table.tBodies[0].rows[0]; } else { resizeRow = table.tBodies[0].insertRow(0); - resizeRow.hidden = true; + resizeRow.setAttribute('resize-row', ''); + resizeRow.style.height = '0'; + resizeRow.style.border = '0'; + resizeRow.style.overflow = 'hidden'; for (let i = 0; i < table.rows[0].cells.length; i++) { - resizeRow.insertCell(); + const cell = resizeRow.insertCell(); + cell.style.padding = '0'; } // insert an additional to keep the zebra in place pattern which might be applied - const zebraGhostRow = table.tBodies[0].insertRow(0); + const zebraGhostRow = table.tBodies[0].insertRow(1); zebraGhostRow.hidden = true; } diff --git a/src/routes/admin/admin/+page.svelte b/src/routes/admin/admin/+page.svelte index 61d7cdb..7ea23d1 100644 --- a/src/routes/admin/admin/+page.svelte +++ b/src/routes/admin/admin/+page.svelte @@ -196,17 +196,21 @@ </tr> {/each} <tr> - <td>{data.admins.length + 1}</td> - <td><Input type="text" bind:value={newAdminUsername} size="sm" /></td> - <td><Input type="password" bind:value={newAdminPassword} size="sm" /></td> - <td + <td on:mousedown={(e) => resizeTableColumn(e, 5)}>{data.admins.length + 1}</td> + <td on:mousedown={(e) => resizeTableColumn(e, 5)} + ><Input type="text" bind:value={newAdminUsername} size="sm" /></td + > + <td on:mousedown={(e) => resizeTableColumn(e, 5)} + ><Input type="password" bind:value={newAdminPassword} size="sm" /></td + > + <td on:mousedown={(e) => resizeTableColumn(e, 5)} ><Badges bind:value={newAdminPermissions} available={allPermissionBadges} disabled={!permissions.adminWrite()} /></td > - <td> + <td on:mousedown={(e) => resizeTableColumn(e, 5)}> <span class="w-min" class:cursor-not-allowed={!permissions.adminWrite() || diff --git a/src/routes/admin/users/+page.svelte b/src/routes/admin/users/+page.svelte index 3ee457d..ffe5be5 100644 --- a/src/routes/admin/users/+page.svelte +++ b/src/routes/admin/users/+page.svelte @@ -5,7 +5,7 @@ import Select from '$lib/components/Input/Select.svelte'; import { env } from '$env/dynamic/public'; import type { User } from '$lib/server/database'; - import { buttonTriggeredRequest } from '$lib/components/utils'; + import { buttonTriggeredRequest, resizeTableColumn } from '$lib/components/utils'; import { browser } from '$app/environment'; export let data: PageData; @@ -135,7 +135,7 @@ <tr class="[&>th]:bg-base-100 [&>th]:z-[1] [&>th]:sticky [&>th]:top-0"> <th /> {#each headers as header} - <th> + <th on:mousedown={(e) => resizeTableColumn(e, 5)}> <button class="flex items-center" on:click={() => { @@ -161,22 +161,36 @@ {#await currentPageUsersRequest} {#each Array(usersPerPage) as _, i} <tr class="animate-pulse text-transparent"> - <td>{i + 1}</td> - <td><Input type="text" disabled={true} size="sm" /></td> - <td><Input type="text" disabled={true} size="sm" /></td> - <td><Input type="date" disabled={true} size="sm" /></td> - <td><Input type="tel" disabled={true} size="sm" /></td> - <td><Input type="text" disabled={true} size="sm" /></td> - <td + <td on:mousedown={(e) => resizeTableColumn(e, 5)}>{i + 1}</td> + <td on:mousedown={(e) => resizeTableColumn(e, 5)} + ><Input type="text" disabled={true} size="sm" /></td + > + <td on:mousedown={(e) => resizeTableColumn(e, 5)} + ><Input type="text" disabled={true} size="sm" /></td + > + <td on:mousedown={(e) => resizeTableColumn(e, 5)} + ><Input type="date" disabled={true} size="sm" /></td + > + <td on:mousedown={(e) => resizeTableColumn(e, 5)} + ><Input type="tel" disabled={true} size="sm" /></td + > + <td on:mousedown={(e) => resizeTableColumn(e, 5)} + ><Input type="text" disabled={true} size="sm" /></td + > + <td on:mousedown={(e) => resizeTableColumn(e, 5)} ><Select id="edition" disabled={true} size="sm"> <option value="java">Java Edition</option> <option value="bedrock">Bedrock Edition</option> <option value="cracked">Java cracked</option> </Select></td > - <td><Input type="text" disabled={true} size="sm" /></td> - <td><Input type="text" disabled={true} size="sm" /></td> - <td + <td on:mousedown={(e) => resizeTableColumn(e, 5)} + ><Input type="text" disabled={true} size="sm" /></td + > + <td on:mousedown={(e) => resizeTableColumn(e, 5)} + ><Input type="text" disabled={true} size="sm" /></td + > + <td on:mousedown={(e) => resizeTableColumn(e, 5)} ><div class="flex gap-1"> <button class="btn btn-sm btn-square" disabled /> </div></td @@ -186,14 +200,14 @@ {:then _} {#each currentPageUsers as user, i} <tr> - <td>{i + 1}</td> - <td> + <td on:mousedown={(e) => resizeTableColumn(e, 5)}>{i + 1}</td> + <td on:mousedown={(e) => resizeTableColumn(e, 5)}> <Input type="text" bind:value={user.firstname} disabled={!user.edit} size="sm" /> </td> - <td> + <td on:mousedown={(e) => resizeTableColumn(e, 5)}> <Input type="text" bind:value={user.lastname} disabled={!user.edit} size="sm" /> </td> - <td> + <td on:mousedown={(e) => resizeTableColumn(e, 5)}> <Input type="date" value={new Date(user.birthday).toISOString().split('T')[0]} @@ -202,23 +216,23 @@ size="sm" /> </td> - <td> + <td on:mousedown={(e) => resizeTableColumn(e, 5)}> <Input type="tel" bind:value={user.telephone} disabled={!user.edit} size="sm" /> </td> - <td> + <td on:mousedown={(e) => resizeTableColumn(e, 5)}> <Input type="text" bind:value={user.username} disabled={!user.edit} size="sm" /> </td> - <td> + <td on:mousedown={(e) => resizeTableColumn(e, 5)}> <Select id="edition" bind:value={user.playertype} disabled={!user.edit} size="sm"> <option value="java">Java Edition</option> <option value="bedrock">Bedrock Edition</option> <option value="cracked">Java cracked</option> </Select> </td> - <td> + <td on:mousedown={(e) => resizeTableColumn(e, 5)}> <Input type="text" bind:value={user.password} disabled={!user.edit} size="sm" /> </td> - <td> + <td on:mousedown={(e) => resizeTableColumn(e, 5)}> <Input id="uuid" type="text" @@ -227,7 +241,7 @@ size="sm" /> </td> - <td> + <td on:mousedown={(e) => resizeTableColumn(e, 5)}> <div class="flex gap-1"> {#if user.edit} <button @@ -288,3 +302,28 @@ </div> </div> </div> + +<style lang="scss"> + thead tr th, + tbody tr td { + @apply relative; + + &:not(:first-child) { + @apply border-l-[1px] border-dashed; + + &::before { + @apply absolute left-0 bottom-0 h-full w-[5px] cursor-col-resize; + content: ''; + } + } + + &:not(:last-child) { + @apply border-r-[1px] border-dashed border-base-300; + + &::after { + @apply absolute right-0 bottom-0 h-full w-[5px] cursor-col-resize; + content: ''; + } + } + } +</style>