Skip to content
Open
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
2 changes: 1 addition & 1 deletion e2e/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export async function setCompanyData(page: Page, user: UserCredentials, company:
await expect(page.getByRole('heading', { name: 'Stammdaten Ihres Unternehmens' })).toBeVisible();

await page.getByLabel('Name').fill(company.name);
await page.getByLabel('Unternehmenssitz').pressSequentially(company.address, { delay: 10 });
await page.getByLabel('Unternehmenssitz').pressSequentially(company.address, { delay: 50 });
await page.getByText('Werner-Seelenbinder-Straße 70a').click();

await page.getByLabel('Pflichtfahrgebiet').selectOption({ label: company.zone });
Expand Down
30 changes: 30 additions & 0 deletions migrations/2025-03-21-favourites.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@


export async function up(db) {
await db.schema
.createTable('favourite_locations')
.addColumn('id', 'serial', (col) => col.primaryKey())
.addColumn('user', 'integer', (col) => col.references('user.id').notNull())
.addColumn('address', 'varchar', (col) => col.notNull())
.addColumn('lat', 'real', (col) => col.notNull())
.addColumn('lng', 'real', (col) => col.notNull())
.addColumn('level', 'integer', (col) => col.notNull())
.addColumn('last_timestamp', 'bigint', (col) => col.notNull())
.addColumn('count', 'integer', (col) => col.notNull().defaultTo(1))
.execute();

await db.schema
.createTable('favourite_routes')
.addColumn('id', 'serial', (col) => col.primaryKey())
.addColumn('user', 'integer', (col) => col.references('user.id').notNull())
.addColumn('from_id', 'integer', (col) => col.references('favourite_locations.id').notNull())
.addColumn('to_id', 'integer', (col) => col.references('favourite_locations.id').notNull())
.addColumn('last_timestamp', 'bigint', (col) => col.notNull())
.addColumn('count', 'integer', (col) => col.notNull().defaultTo(1))
.execute();
}

export async function down(db) {
await db.dropTable('favourite_routes').execute();
await db.dropTable('favourite_locations').execute();
}
6 changes: 5 additions & 1 deletion src/lib/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ const translations: Translations = {

// Feedback
feedbackThank: 'Vielen Dank für Ihr Feedback!',
feedbackMissing: 'Kein Feedback gegeben'
feedbackMissing: 'Kein Feedback gegeben',

invalidFrom: 'Invalide Start Addresse.',
invalidTo: 'Invalide Ziel Addresse.'
},
admin: {
completedToursSubtitle: 'Abgeschlossene Fahrten',
Expand Down Expand Up @@ -175,6 +178,7 @@ const translations: Translations = {
odm: 'ÖPNV-Taxi - Buchung erforderlich!',
from: 'Von',
to: 'Nach',
favourites: 'Favoriten',
arrival: 'Ankunft',
departure: 'Abfahrt',
duration: 'Dauer',
Expand Down
6 changes: 5 additions & 1 deletion src/lib/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ const translations: Translations = {

// Feedback
feedbackThank: 'Thank you very much for your feedback!',
feedbackMissing: 'No feedback given'
feedbackMissing: 'No feedback given',

invalidFrom: 'Invalid start address.',
invalidTo: 'Invalid destination address.'
},
admin: {
completedToursSubtitle: 'Completed Tours',
Expand Down Expand Up @@ -170,6 +173,7 @@ const translations: Translations = {
odm: 'Public Transport Taxi, booking required!',
from: 'From',
to: 'To',
favourites: 'Favourites',
arrival: 'Arrival',
departure: 'Departure',
duration: 'Duration',
Expand Down
4 changes: 4 additions & 0 deletions src/lib/i18n/translation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ export type Translations = {
// Feedback
feedbackThank: string;
feedbackMissing: string;

invalidFrom: string;
invalidTo: string;
};
admin: {
completedToursSubtitle: string;
Expand Down Expand Up @@ -160,6 +163,7 @@ export type Translations = {
odm: string;
from: string;
to: string;
favourites: string;
arrival: string;
departure: string;
duration: string;
Expand Down
4 changes: 2 additions & 2 deletions src/lib/map/Location.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export type Location = {
};
};

export function posToLocation(pos: maplibregl.LngLatLike, level: number): Location {
export function posToLocation(pos: maplibregl.LngLatLike, level: number, l?: string): Location {
const { lat, lng } = maplibregl.LngLat.convert(pos);
const label = `${lat},${lng},${level}`;
const label = l ? l : `${lat},${lng},${level}`;
return {
label,
value: {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/server/booking/getEventGroupInfo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Coordinates } from '$lib/util/Coordinates';
import { InsertHow } from './insertionTypes';
import { v4 as uuidv4 } from 'uuid';
import { isSamePlace } from './isSamePlace';
import { isSamePlace } from '$lib/util/booking/isSamePlace';
import { type Event } from '$lib/server/booking/getBookingAvailability';

export type EventGroupUpdate = {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/server/booking/routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { InsertionInfo } from './insertionTypes';
import { iterateAllInsertions } from './iterateAllInsertions';
import type { VehicleId } from './VehicleId';
import type { Range } from '$lib/util/booking/getPossibleInsertions';
import { isSamePlace } from './isSamePlace';
import { isSamePlace } from '$lib/util/booking/isSamePlace';
import { batchOneToManyCarRouting } from '$lib/server/util/batchOneToManyCarRouting';

export type InsertionRoutingResult = {
Expand Down
18 changes: 18 additions & 0 deletions src/lib/server/db/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,24 @@ export interface Database {
rating: number | null;
comment: string | null;
};
favouriteLocations: {
id: Generated<number>;
user: number;
address: string;
lat: number;
lng: number;
level: number;
lastTimestamp: number;
count: number;
};
favouriteRoutes: {
id: Generated<number>;
user: number;
fromId: number;
toId: number;
lastTimestamp: number;
count: number;
};
}

export const pool = new pg.Pool({ connectionString: env.DATABASE_URL });
Expand Down
3 changes: 0 additions & 3 deletions src/lib/ui/AccountingView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,6 @@
<SortableTable
bind:rows={currentRowsToursTable}
cols={isAdmin ? tourColsAdmin : tourColsCompany}
{isAdmin}
getRowStyle={(_) => 'cursor-pointer '}
bind:selectedRow={selectedToursTableRow}
bindSelectedRow={true}
Expand All @@ -318,15 +317,13 @@
<SortableTable
bind:rows={currentRowsSubtractionsTable}
cols={isAdmin ? subtractionColsAdmin : subtractionColsCompany}
{isAdmin}
/>
{/snippet}

{#snippet companyTable()}
<SortableTable
bind:rows={currentCompanyRows}
cols={isAdmin ? companyColsAdmin : companyColsCompany}
{isAdmin}
fixLastRow={isAdmin}
/>
{/snippet}
Expand Down
23 changes: 23 additions & 0 deletions src/lib/ui/DisplayAddresses.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script lang="ts">
import { Circle, MapPin } from 'lucide-svelte';

const { fromAddress, toAddress } = $props();

let fromHeight = $state(0);
let toHeight = $state(0);
let topMargin = $derived((fromHeight - 16) / 2);
let botMargin = $derived((toHeight - 20) / 2);
</script>

<div class="flex flex-row gap-1 text-sm">
<div class="flex flex-col items-center justify-between">
<Circle class="h-4 w-4" style="margin-top: {topMargin}px" />
<div class="min-h-4 w-px flex-1 border-l border-dashed border-foreground"></div>
<MapPin class="h-5 w-5" style="margin-bottom: {botMargin}px" />
</div>
<div class="flex flex-col justify-between break-all">
<div bind:offsetHeight={fromHeight}>{fromAddress}</div>
<div class="min-h-4"></div>
<div bind:offsetHeight={toHeight}>{toAddress}</div>
</div>
</div>
45 changes: 45 additions & 0 deletions src/lib/ui/FavouriteLocations.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script lang="ts">
import { t } from '$lib/i18n/translation';
import type { Column } from './tableData';
import SortableTable from './SortableTable.svelte';
import * as Card from '$lib/shadcn/card';

export type Favourite = {
address: string;
lat: number;
lng: number;
level: number;
};

let {
favourites,
selectedFavourite = $bindable()
}: {
favourites: Favourite[];
selectedFavourite?: Favourite[];
} = $props();

let favouriteRows = $derived(favourites);

const favouriteCols: Column<{ address: string; lat: number; lng: number }>[] = [
{
text: [t.favourites],
sort: undefined,
toTableEntry: (r: { address: string }) => r.address
}
];
</script>

{#if favouriteRows.length != 0}
<Card.Root class="mt-5">
<Card.Content>
<SortableTable
getRowStyle={(_) => 'cursor-pointer '}
rows={favouriteRows}
cols={favouriteCols}
bind:selectedRow={selectedFavourite}
bindSelectedRow={true}
/>
</Card.Content>
</Card.Root>
{/if}
51 changes: 51 additions & 0 deletions src/lib/ui/FavouriteRoutes.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<script lang="ts">
import { t } from '$lib/i18n/translation';
import * as Table from '$lib/shadcn/table/index';
import DisplayAddresses from './DisplayAddresses.svelte';

type FavouriteRoute = {
fromAddress: string;
fromLat: number;
fromLng: number;
fromLevel: number;
toAddress: string;
toLat: number;
toLng: number;
toLevel: number;
};
let {
favourites,
selectedFavourite = $bindable()
}: {
favourites: FavouriteRoute[];
selectedFavourite?: FavouriteRoute[];
} = $props();

let favouriteRows = $derived(favourites);
</script>

<div>
<Table.Root>
<Table.Header>
<Table.Row>
<Table.Head class="pb-4 pt-2">
{t.favourites}
</Table.Head>
</Table.Row>
</Table.Header>
<Table.Body>
{#each favouriteRows as row}
<Table.Row
class={'cursor-pointer'}
onclick={() => {
selectedFavourite = [row];
}}
>
<Table.Cell>
<DisplayAddresses fromAddress={row.fromAddress} toAddress={row.toAddress} />
</Table.Cell>
</Table.Row>
{/each}
</Table.Body>
</Table.Root>
</div>
1 change: 0 additions & 1 deletion src/lib/ui/SortableTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
toColumnStyle?: (r: T) => string;
hidden?: boolean;
}[];
isAdmin: boolean;
getRowStyle?: (row: T) => string;
selectedRow?: undefined | T[];
bindSelectedRow?: boolean;
Expand Down
Loading