Handle visible columns for short urls
Some checks failed
Test before pr merge / test-lint (pull_request) Failing after 35s
Test before pr merge / test-translation-lint (pull_request) Failing after 1m8s
Test before pr merge / test-before-merge (pull_request) Failing after 1m31s

This commit is contained in:
Sven Heidemann 2025-04-18 11:59:36 +02:00
parent 7b62022a83
commit b872c33c02
4 changed files with 76 additions and 37 deletions

View File

@ -12,13 +12,6 @@ export class ShortUrlsColumns extends PageColumns<ShortUrl> {
get(): TableColumn<ShortUrl>[] {
return [
ID_COLUMN,
{
name: 'short_url',
translationKey: 'short_url.short_url',
type: 'text',
filterable: true,
value: (row: ShortUrl) => row.shortUrl,
},
{
name: 'target_url',
translationKey: 'short_url.target_url',
@ -33,6 +26,28 @@ export class ShortUrlsColumns extends PageColumns<ShortUrl> {
filterable: true,
value: (row: ShortUrl) => row.description,
},
{
name: 'visits',
translationKey: 'short_url.visits',
type: 'number',
filterable: true,
value: (row: ShortUrl) => row.visits,
class: 'highlight2',
},
{
name: 'loading_screen',
translationKey: 'short_url.loading_screen',
type: 'boolean',
filterable: true,
value: (row: ShortUrl) => row.loadingScreen,
},
{
name: 'domain',
translationKey: 'common.domain',
type: 'text',
filterable: true,
value: (row: ShortUrl) => row.domain?.name,
},
...DB_MODEL_COLUMNS,
];
}

View File

@ -8,7 +8,7 @@ import {
Update,
} from 'src/app/core/base/page.data.service';
import { Filter } from 'src/app/model/graphql/filter/filter.model';
import { Sort } from 'src/app/model/graphql/filter/sort.model';
import { Sort, SortOrder } from 'src/app/model/graphql/filter/sort.model';
import { Apollo, gql } from 'apollo-angular';
import { QueryResult } from 'src/app/model/entities/query-result';
import {
@ -80,7 +80,7 @@ export class ShortUrlsDataService
`,
variables: {
filter: [{ group: { deleted: { equal: false } } }, ...(filter ?? [])],
sort: sort,
sort: [{ id: SortOrder.DESC }, ...(sort ?? [])],
skip: skip,
take: take,
},

View File

@ -4,28 +4,19 @@
<div class="flex flex-col gap-2 bg rounded-lg p-3 w-full max-w-lg justify-between">
<div class="flex flex-col gap-2">
<h3>{{ url.shortUrl }}</h3>
<div class="grid-container">
<span class="grid-label font-bold">{{ 'short_url.target_url' | translate }}:</span>
<a class="grid-value" [href]="url.targetUrl" target="_blank">{{ url.targetUrl }}</a>
</div>
<div class="grid-container">
<span class="grid-label font-bold">{{ 'common.description' | translate }}:</span>
<span class="grid-value">{{ url.description }}</span>
</div>
<div class="grid-container">
<span class="grid-label font-bold">{{ 'short_url.visits' | translate }}:</span>
<span class="grid-value highlight2">{{ url.visits }}</span>
</div>
<div class="grid-container">
<span class="grid-label font-bold">{{ 'short_url.loading_screen' | translate }}:</span>
<span class="grid-value">
<div class="pi pi-{{ url.loadingScreen ? 'check-circle' : 'times-circle' }}"></div>
</span>
</div>
<div class="grid-container" *ngIf="url.domain">
<span class="grid-label font-bold">{{ 'common.domain' | translate }}:</span>
<span class="grid-value">{{ url.domain?.name }}</span>
</div>
<ng-container *ngFor="let row of resolvedColumns.get(url.shortUrl) ">
<div class="grid-container">
<span class="grid-label font-bold">{{ row.column.translationKey | translate }}:</span>
<ng-container *ngIf="row.column.type === 'boolean'; else text">
<div class="pi pi-{{ row.value ? 'check-circle' : 'times-circle' }}"></div>
</ng-container>
<ng-template #text>
<span [class]="'grid-value ' + row.column.class">{{ row.column.value(url) }}</span>
</ng-template>
</div>
</ng-container>
</div>
<div class="flex justify-between">
<div class="flex">
@ -99,18 +90,15 @@
| translate
}}"
(click)="toggleShowDeleted()"></p-button>
<p-button
class="icon-btn btn"
icon="pi pi-sort-alt-slash"
tooltipPosition="left"
pTooltip="{{ 'table.reset_sort' | translate }}"
(click)="resetSort()"></p-button>
<p-button
class="icon-btn btn"
icon="pi pi-filter-slash"
tooltipPosition="left"
pTooltip="{{ 'table.reset_filters' | translate }}"
(click)="resetFilters()"></p-button>
<app-column-selector
[columns]="columns"
(selectChange)="resolveColumns()"></app-column-selector>
</div>
</div>

View File

@ -11,6 +11,10 @@ import { Filter } from 'src/app/model/graphql/filter/filter.model';
import QrCodeWithLogo from 'qrcode-with-logos';
import { FileUpload, FileUploadHandlerEvent } from 'primeng/fileupload';
import { ConfigService } from 'src/app/service/config.service';
import {
ResolvedTableColumn,
TableColumn,
} from 'src/app/modules/shared/components/table/table.model';
@Component({
selector: 'app-short-urls',
@ -40,6 +44,8 @@ export class ShortUrlsPage
logo: undefined,
};
resolvedColumns: Map<string, ResolvedTableColumn<ShortUrl>[]> = new Map();
get groupsFromGroupedShortUrls() {
return Object.keys(this.groupedShortUrls);
}
@ -95,6 +101,35 @@ export class ShortUrlsPage
};
}
resolveColumns() {
const columns = this.columns
.map(x => {
if (x.visible === undefined || x.visible === null) {
x.visible = true;
}
return x;
})
.filter(x => !x.hidden && x.visible === true);
if (!this.result.nodes || this.result.nodes.length == 0) {
this.resolvedColumns = new Map();
return;
}
this.result.nodes.forEach(row => {
const resolvedRow: ResolvedTableColumn<ShortUrl>[] = [];
columns.forEach(column => {
resolvedRow.push({
value: column.value(row),
data: row,
column: column,
});
});
this.resolvedColumns.set(row.shortUrl, resolvedRow);
});
}
load(silent?: boolean): void {
if (!silent) this.loading = true;
this.dataService
@ -103,6 +138,7 @@ export class ShortUrlsPage
this.result = result;
this.shortUrlsWithoutGroup = this.getShortUrlsWithoutGroup();
this.groupedShortUrls = this.getShortUrlsWithGroup();
this.resolveColumns();
this.loading = false;
});
}