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>[] { get(): TableColumn<ShortUrl>[] {
return [ return [
ID_COLUMN, ID_COLUMN,
{
name: 'short_url',
translationKey: 'short_url.short_url',
type: 'text',
filterable: true,
value: (row: ShortUrl) => row.shortUrl,
},
{ {
name: 'target_url', name: 'target_url',
translationKey: 'short_url.target_url', translationKey: 'short_url.target_url',
@ -33,6 +26,28 @@ export class ShortUrlsColumns extends PageColumns<ShortUrl> {
filterable: true, filterable: true,
value: (row: ShortUrl) => row.description, 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, ...DB_MODEL_COLUMNS,
]; ];
} }

View File

@ -8,7 +8,7 @@ import {
Update, Update,
} from 'src/app/core/base/page.data.service'; } from 'src/app/core/base/page.data.service';
import { Filter } from 'src/app/model/graphql/filter/filter.model'; 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 { Apollo, gql } from 'apollo-angular';
import { QueryResult } from 'src/app/model/entities/query-result'; import { QueryResult } from 'src/app/model/entities/query-result';
import { import {
@ -80,7 +80,7 @@ export class ShortUrlsDataService
`, `,
variables: { variables: {
filter: [{ group: { deleted: { equal: false } } }, ...(filter ?? [])], filter: [{ group: { deleted: { equal: false } } }, ...(filter ?? [])],
sort: sort, sort: [{ id: SortOrder.DESC }, ...(sort ?? [])],
skip: skip, skip: skip,
take: take, 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 bg rounded-lg p-3 w-full max-w-lg justify-between">
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<h3>{{ url.shortUrl }}</h3> <h3>{{ url.shortUrl }}</h3>
<div class="grid-container"> <ng-container *ngFor="let row of resolvedColumns.get(url.shortUrl) ">
<span class="grid-label font-bold">{{ 'short_url.target_url' | translate }}:</span> <div class="grid-container">
<a class="grid-value" [href]="url.targetUrl" target="_blank">{{ url.targetUrl }}</a> <span class="grid-label font-bold">{{ row.column.translationKey | translate }}:</span>
</div>
<div class="grid-container"> <ng-container *ngIf="row.column.type === 'boolean'; else text">
<span class="grid-label font-bold">{{ 'common.description' | translate }}:</span> <div class="pi pi-{{ row.value ? 'check-circle' : 'times-circle' }}"></div>
<span class="grid-value">{{ url.description }}</span> </ng-container>
</div> <ng-template #text>
<div class="grid-container"> <span [class]="'grid-value ' + row.column.class">{{ row.column.value(url) }}</span>
<span class="grid-label font-bold">{{ 'short_url.visits' | translate }}:</span> </ng-template>
<span class="grid-value highlight2">{{ url.visits }}</span> </div>
</div> </ng-container>
<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>
</div> </div>
<div class="flex justify-between"> <div class="flex justify-between">
<div class="flex"> <div class="flex">
@ -99,18 +90,15 @@
| translate | translate
}}" }}"
(click)="toggleShowDeleted()"></p-button> (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 <p-button
class="icon-btn btn" class="icon-btn btn"
icon="pi pi-filter-slash" icon="pi pi-filter-slash"
tooltipPosition="left" tooltipPosition="left"
pTooltip="{{ 'table.reset_filters' | translate }}" pTooltip="{{ 'table.reset_filters' | translate }}"
(click)="resetFilters()"></p-button> (click)="resetFilters()"></p-button>
<app-column-selector
[columns]="columns"
(selectChange)="resolveColumns()"></app-column-selector>
</div> </div>
</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 QrCodeWithLogo from 'qrcode-with-logos';
import { FileUpload, FileUploadHandlerEvent } from 'primeng/fileupload'; import { FileUpload, FileUploadHandlerEvent } from 'primeng/fileupload';
import { ConfigService } from 'src/app/service/config.service'; import { ConfigService } from 'src/app/service/config.service';
import {
ResolvedTableColumn,
TableColumn,
} from 'src/app/modules/shared/components/table/table.model';
@Component({ @Component({
selector: 'app-short-urls', selector: 'app-short-urls',
@ -40,6 +44,8 @@ export class ShortUrlsPage
logo: undefined, logo: undefined,
}; };
resolvedColumns: Map<string, ResolvedTableColumn<ShortUrl>[]> = new Map();
get groupsFromGroupedShortUrls() { get groupsFromGroupedShortUrls() {
return Object.keys(this.groupedShortUrls); 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 { load(silent?: boolean): void {
if (!silent) this.loading = true; if (!silent) this.loading = true;
this.dataService this.dataService
@ -103,6 +138,7 @@ export class ShortUrlsPage
this.result = result; this.result = result;
this.shortUrlsWithoutGroup = this.getShortUrlsWithoutGroup(); this.shortUrlsWithoutGroup = this.getShortUrlsWithoutGroup();
this.groupedShortUrls = this.getShortUrlsWithGroup(); this.groupedShortUrls = this.getShortUrlsWithGroup();
this.resolveColumns();
this.loading = false; this.loading = false;
}); });
} }