Compare commits
23 commits
Author | SHA1 | Date | |
---|---|---|---|
447bdb56a0 | |||
|
46885e7ca6 | ||
4a0ece5e6b | |||
542994205f | |||
ef0a93ee1f | |||
|
0e35431819 | ||
028344d02c | |||
30997419ac | |||
|
60cb0349ce | ||
145206224e | |||
3558a0f1b8 | |||
469d6bbf6d | |||
77037601a2 | |||
d98435b21e | |||
4e93120439 | |||
c300036c8a | |||
d0d63eaf87 | |||
f75b720d3f | |||
60789a01de | |||
0dba945ac2 | |||
8e1832416b | |||
ab5dbc047c | |||
b0744f94ad |
18 changed files with 172 additions and 38 deletions
43
.gitea/workflows/release-new.yml
Normal file
43
.gitea/workflows/release-new.yml
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
name: release-please
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release-please:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: release
|
||||||
|
uses: joaquinjsb/gitea-release-please-action@v4
|
||||||
|
with:
|
||||||
|
# this assumes that you have created a personal access token
|
||||||
|
# (PAT) and configured it as a GitHub action secret named
|
||||||
|
# `MY_RELEASE_PLEASE_TOKEN` (this secret name is not important).
|
||||||
|
token: ${{ secrets.MY_RELEASE_PLEASE_TOKEN }}
|
||||||
|
git-username: ${{ secrets.RL_USER }}
|
||||||
|
git-password: ${{ secrets.RL_PASSWD }}
|
||||||
|
# this is a built-in strategy in release-please, see "Action Inputs"
|
||||||
|
# for more options
|
||||||
|
release-type: simple
|
||||||
|
target-branch: main
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: tag major and minor versions
|
||||||
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
|
run: |
|
||||||
|
git config user.name github-actions[bot]
|
||||||
|
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
||||||
|
git remote add gh-token "https://${{ secrets.GITHUB_TOKEN }}@github.com/joaquinjsb/gitea-release-please-action.git"
|
||||||
|
git tag -d v${{ steps.release.outputs.major }} || true
|
||||||
|
git tag -d v${{ steps.release.outputs.major }}.${{ steps.release.outputs.minor }} || true
|
||||||
|
git push origin :v${{ steps.release.outputs.major }} || true
|
||||||
|
git push origin :v${{ steps.release.outputs.major }}.${{ steps.release.outputs.minor }} || true
|
||||||
|
git tag -a v${{ steps.release.outputs.major }} -m "Release v${{ steps.release.outputs.major }}"
|
||||||
|
git tag -a v${{ steps.release.outputs.major }}.${{ steps.release.outputs.minor }} -m "Release v${{ steps.release.outputs.major }}.${{ steps.release.outputs.minor }}"
|
||||||
|
git push origin v${{ steps.release.outputs.major }}
|
||||||
|
git push origin v${{ steps.release.outputs.major }}.${{ steps.release.outputs.minor }}
|
61
CHANGELOG.md
Normal file
61
CHANGELOG.md
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
## [1.2.0](https://git.kjan.de/jank/jklink/compare/v1.1.0...v1.2.0) (2025-01-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add custom slug support for links ([8e18324](https://git.kjan.de/jank/jklink/commit/8e1832416ba4f98543fcd1240ea0c0cc1425af21))
|
||||||
|
* **create-link:** Add snackbar notification for slug conflict ([0dba945](https://git.kjan.de/jank/jklink/commit/0dba945ac2c93dd4b1eeefaac060050999db88f9))
|
||||||
|
* **dashboard:** add link confirmation dialog before navigation ([4c77b4f](https://git.kjan.de/jank/jklink/commit/4c77b4f139fd6c88a1eedcbc450b3e489a46e20d))
|
||||||
|
* **dashboard:** add links to element IDs in dashboard table ([8302387](https://git.kjan.de/jank/jklink/commit/8302387aa73dfa0411f81c26dcc1fd0467209f87))
|
||||||
|
* **dashboard:** add options menu and improve layout ([ba520ee](https://git.kjan.de/jank/jklink/commit/ba520eea10ab32e8d76a09454033080843b87f47))
|
||||||
|
* **dashboard:** add snack bar notifications for link actions ([3e0b17e](https://git.kjan.de/jank/jklink/commit/3e0b17ebe61edf69f3f9f3d22189338e23170240))
|
||||||
|
* **dashboard:** add user greeting to dashboard component ([311fd89](https://git.kjan.de/jank/jklink/commit/311fd89c7b1ffcafb7491c4c884a12ac1f2ea490))
|
||||||
|
* **dashboard:** update getShortLink to use HTTPS ([8b08c66](https://git.kjan.de/jank/jklink/commit/8b08c6616c9e4856c3f0a305bbfbc8803842dd46))
|
||||||
|
* **login:** add Authentik login button and functionality ([cb658a7](https://git.kjan.de/jank/jklink/commit/cb658a77210499a2d731d4448f4030f01c5fc160))
|
||||||
|
* **login:** update login form with material design elements ([b218697](https://git.kjan.de/jank/jklink/commit/b2186978673e5223e5d10c7b1dfdc0326acf00a3))
|
||||||
|
* **options-menu:** add xPosition to mat-menu component ([fdfe92a](https://git.kjan.de/jank/jklink/commit/fdfe92a23242532d2e1a56494b1fa4a97a38937e))
|
||||||
|
* update deleteLink to use link object directly ([e0d9b82](https://git.kjan.de/jank/jklink/commit/e0d9b8295eb876a4b7629ae055b51cf98bd58a90))
|
||||||
|
|
||||||
|
## [1.1.0](https://git.kjan.de/jank/jklink/compare/v1.0.0...v1.1.0) (2025-01-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add custom slug support for links ([8e18324](https://git.kjan.de/jank/jklink/commit/8e1832416ba4f98543fcd1240ea0c0cc1425af21))
|
||||||
|
* **create-link:** Add snackbar notification for slug conflict ([0dba945](https://git.kjan.de/jank/jklink/commit/0dba945ac2c93dd4b1eeefaac060050999db88f9))
|
||||||
|
* **dashboard:** add copy link button to dashboard table ([50cb62e](https://git.kjan.de/jank/jklink/commit/50cb62e56d0f68320f2aea93cb0571398c314e05))
|
||||||
|
* **dashboard:** add link confirmation dialog before navigation ([4c77b4f](https://git.kjan.de/jank/jklink/commit/4c77b4f139fd6c88a1eedcbc450b3e489a46e20d))
|
||||||
|
* **dashboard:** add links to element IDs in dashboard table ([8302387](https://git.kjan.de/jank/jklink/commit/8302387aa73dfa0411f81c26dcc1fd0467209f87))
|
||||||
|
* **dashboard:** add options menu and improve layout ([ba520ee](https://git.kjan.de/jank/jklink/commit/ba520eea10ab32e8d76a09454033080843b87f47))
|
||||||
|
* **dashboard:** add snack bar notifications for link actions ([3e0b17e](https://git.kjan.de/jank/jklink/commit/3e0b17ebe61edf69f3f9f3d22189338e23170240))
|
||||||
|
* **dashboard:** add user greeting to dashboard component ([311fd89](https://git.kjan.de/jank/jklink/commit/311fd89c7b1ffcafb7491c4c884a12ac1f2ea490))
|
||||||
|
* **dashboard:** update getShortLink to use HTTPS ([8b08c66](https://git.kjan.de/jank/jklink/commit/8b08c6616c9e4856c3f0a305bbfbc8803842dd46))
|
||||||
|
* **login:** add Authentik login button and functionality ([cb658a7](https://git.kjan.de/jank/jklink/commit/cb658a77210499a2d731d4448f4030f01c5fc160))
|
||||||
|
* **login:** update login form with material design elements ([b218697](https://git.kjan.de/jank/jklink/commit/b2186978673e5223e5d10c7b1dfdc0326acf00a3))
|
||||||
|
* **options-menu:** add xPosition to mat-menu component ([fdfe92a](https://git.kjan.de/jank/jklink/commit/fdfe92a23242532d2e1a56494b1fa4a97a38937e))
|
||||||
|
* update deleteLink to use link object directly ([e0d9b82](https://git.kjan.de/jank/jklink/commit/e0d9b8295eb876a4b7629ae055b51cf98bd58a90))
|
||||||
|
* **view-link:** add ViewLink component and routing logic ([79fc66e](https://git.kjan.de/jank/jklink/commit/79fc66ef6b4bb0edf62531d46d325c33b05dbcdd))
|
||||||
|
|
||||||
|
## 1.0.0 (2025-01-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add Angular Material and refactor UI components ([6317c97](https://git.kjan.de/jank/jklink/commit/6317c97d96ae28bd8f3cb9e63abffd6e2747532e))
|
||||||
|
* Add custom slug support for links ([8e18324](https://git.kjan.de/jank/jklink/commit/8e1832416ba4f98543fcd1240ea0c0cc1425af21))
|
||||||
|
* **create-link:** add create link component and routing ([00a7688](https://git.kjan.de/jank/jklink/commit/00a7688ef9bc86f0cc707343123a62d8c7db1181))
|
||||||
|
* **create-link:** Add snackbar notification for slug conflict ([0dba945](https://git.kjan.de/jank/jklink/commit/0dba945ac2c93dd4b1eeefaac060050999db88f9))
|
||||||
|
* **dashboard:** add copy link button to dashboard table ([50cb62e](https://git.kjan.de/jank/jklink/commit/50cb62e56d0f68320f2aea93cb0571398c314e05))
|
||||||
|
* **dashboard:** add link confirmation dialog before navigation ([4c77b4f](https://git.kjan.de/jank/jklink/commit/4c77b4f139fd6c88a1eedcbc450b3e489a46e20d))
|
||||||
|
* **dashboard:** add links to element IDs in dashboard table ([8302387](https://git.kjan.de/jank/jklink/commit/8302387aa73dfa0411f81c26dcc1fd0467209f87))
|
||||||
|
* **dashboard:** add options menu and improve layout ([ba520ee](https://git.kjan.de/jank/jklink/commit/ba520eea10ab32e8d76a09454033080843b87f47))
|
||||||
|
* **dashboard:** add snack bar notifications for link actions ([3e0b17e](https://git.kjan.de/jank/jklink/commit/3e0b17ebe61edf69f3f9f3d22189338e23170240))
|
||||||
|
* **dashboard:** add user greeting to dashboard component ([311fd89](https://git.kjan.de/jank/jklink/commit/311fd89c7b1ffcafb7491c4c884a12ac1f2ea490))
|
||||||
|
* **dashboard:** update getShortLink to use HTTPS ([8b08c66](https://git.kjan.de/jank/jklink/commit/8b08c6616c9e4856c3f0a305bbfbc8803842dd46))
|
||||||
|
* **login:** add Authentik login button and functionality ([cb658a7](https://git.kjan.de/jank/jklink/commit/cb658a77210499a2d731d4448f4030f01c5fc160))
|
||||||
|
* **login:** update login form with material design elements ([b218697](https://git.kjan.de/jank/jklink/commit/b2186978673e5223e5d10c7b1dfdc0326acf00a3))
|
||||||
|
* **options-menu:** add xPosition to mat-menu component ([fdfe92a](https://git.kjan.de/jank/jklink/commit/fdfe92a23242532d2e1a56494b1fa4a97a38937e))
|
||||||
|
* update deleteLink to use link object directly ([e0d9b82](https://git.kjan.de/jank/jklink/commit/e0d9b8295eb876a4b7629ae055b51cf98bd58a90))
|
||||||
|
* **view-link:** add ViewLink component and routing logic ([79fc66e](https://git.kjan.de/jank/jklink/commit/79fc66ef6b4bb0edf62531d46d325c33b05dbcdd))
|
|
@ -25,7 +25,7 @@ describe('AppComponent', () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const compiled = fixture.nativeElement as HTMLElement;
|
const compiled = fixture.nativeElement as HTMLElement;
|
||||||
expect(compiled.querySelector('h1')?.textContent).toContain(
|
expect(compiled.querySelector('h1')?.textContent).toContain(
|
||||||
'Hello, jklink',
|
'Hello, jklink'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,7 +21,7 @@ export const routes: Routes = [
|
||||||
canActivate: [AuthGuard],
|
canActivate: [AuthGuard],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':link',
|
path: ':slug',
|
||||||
component: ViewLinkComponent,
|
component: ViewLinkComponent,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
<h2 mat-dialog-title>{{ data.title }}</h2>
|
<h2 mat-dialog-title>{{ data.title }}</h2>
|
||||||
<mat-dialog-content>{{ data.description }}</mat-dialog-content>
|
<mat-dialog-content>{{ data.description }}</mat-dialog-content>
|
||||||
<mat-dialog-actions>
|
<mat-dialog-actions>
|
||||||
<button [style.backgroundColor]="'#FFFFFF'" [style.color]="'#000000'" mat-stroked-button color="warn" (click)="accept()">Yes</button>
|
<button
|
||||||
|
[style.backgroundColor]="'#FFFFFF'"
|
||||||
|
[style.color]="'#000000'"
|
||||||
|
mat-stroked-button
|
||||||
|
color="warn"
|
||||||
|
(click)="accept()"
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</button>
|
||||||
<button mat-flat-button (click)="close()">No</button>
|
<button mat-flat-button (click)="close()">No</button>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
<div class="mx-auto container">
|
<div class="mx-auto container">
|
||||||
<app-navbar></app-navbar>
|
<app-navbar></app-navbar>
|
||||||
<button [style.backgroundColor]="'#FFFFFF'" [style.color]="'#000000'" mat-stroked-button class="mt-3" color="warn" (click)="back()">
|
<button
|
||||||
|
[style.backgroundColor]="'#FFFFFF'"
|
||||||
|
[style.color]="'#000000'"
|
||||||
|
mat-stroked-button
|
||||||
|
class="mt-3"
|
||||||
|
color="warn"
|
||||||
|
(click)="back()"
|
||||||
|
>
|
||||||
Back
|
Back
|
||||||
</button>
|
</button>
|
||||||
<mat-card class="mt-3 p-3" appearance="outlined">
|
<mat-card class="mt-3 p-3" appearance="outlined">
|
||||||
|
@ -20,6 +27,11 @@
|
||||||
placeholder="https://kjan.de"
|
placeholder="https://kjan.de"
|
||||||
/>
|
/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-error>{{ errorMessages["slug"] }}</mat-error>
|
||||||
|
<mat-label>Custom slug (optional)</mat-label>
|
||||||
|
<input formControlName="slug" matInput />
|
||||||
|
</mat-form-field>
|
||||||
<button mat-flat-button type="submit" (click)="submit()">Create</button>
|
<button mat-flat-button type="submit" (click)="submit()">Create</button>
|
||||||
</form>
|
</form>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
|
|
@ -13,6 +13,8 @@ import { MatInputModule, MatLabel } from '@angular/material/input';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { debounceTime } from 'rxjs';
|
import { debounceTime } from 'rxjs';
|
||||||
|
import { AsyncPipe } from '@angular/common';
|
||||||
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-create-link',
|
selector: 'app-create-link',
|
||||||
|
@ -35,6 +37,7 @@ export class CreateLinkComponent {
|
||||||
constructor(
|
constructor(
|
||||||
private linkService: LinkService,
|
private linkService: LinkService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
|
private snackBar: MatSnackBar,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
private validationErrorMessages: Record<string, string> = {
|
private validationErrorMessages: Record<string, string> = {
|
||||||
|
@ -73,6 +76,7 @@ export class CreateLinkComponent {
|
||||||
/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/,
|
/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/,
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
|
slug: new FormControl(''),
|
||||||
});
|
});
|
||||||
this.createLinkForm.valueChanges.subscribe(() => {
|
this.createLinkForm.valueChanges.subscribe(() => {
|
||||||
this.updateErrorMessages();
|
this.updateErrorMessages();
|
||||||
|
@ -89,8 +93,17 @@ export class CreateLinkComponent {
|
||||||
.createLink({
|
.createLink({
|
||||||
name: this.createLinkForm.get('name')?.value,
|
name: this.createLinkForm.get('name')?.value,
|
||||||
link: this.createLinkForm.get('link')?.value,
|
link: this.createLinkForm.get('link')?.value,
|
||||||
|
slug: this.createLinkForm.get('slug')?.value,
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.requestFailed = true;
|
||||||
|
const notification = this.snackBar.open(
|
||||||
|
'The slug is already used please use another slug.',
|
||||||
|
);
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.dismiss();
|
||||||
|
}, 5000);
|
||||||
})
|
})
|
||||||
.catch(() => (this.requestFailed = true))
|
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
if (!this.requestFailed) {
|
if (!this.requestFailed) {
|
||||||
this.router.navigate(['dashboard']);
|
this.router.navigate(['dashboard']);
|
||||||
|
|
|
@ -24,11 +24,11 @@
|
||||||
The actual rendered columns are set as a property on the row definition" -->
|
The actual rendered columns are set as a property on the row definition" -->
|
||||||
|
|
||||||
<!-- Position Column -->
|
<!-- Position Column -->
|
||||||
<ng-container matColumnDef="id">
|
<ng-container matColumnDef="slug">
|
||||||
<th mat-header-cell *matHeaderCellDef>ID</th>
|
<th mat-header-cell *matHeaderCellDef>Slug</th>
|
||||||
<td mat-cell *matCellDef="let element">
|
<td mat-cell *matCellDef="let element">
|
||||||
<a (click)="goToLink(element)" class="link">
|
<a (click)="goToLink(element)" class="link">
|
||||||
{{ element.id }}
|
{{ element.slug }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -49,11 +49,7 @@
|
||||||
<ng-container matColumnDef="shortLink">
|
<ng-container matColumnDef="shortLink">
|
||||||
<th mat-header-cell *matHeaderCellDef>Short link</th>
|
<th mat-header-cell *matHeaderCellDef>Short link</th>
|
||||||
<td mat-cell *matCellDef="let element">
|
<td mat-cell *matCellDef="let element">
|
||||||
<button
|
<button mat-flat-button class="my-3" (click)="copyLink(element)">
|
||||||
mat-flat-button
|
|
||||||
class="my-3"
|
|
||||||
(click)="copyLink(element.id)"
|
|
||||||
>
|
|
||||||
Copy short link
|
Copy short link
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -27,7 +27,7 @@ import { AuthRecord } from 'pocketbase';
|
||||||
})
|
})
|
||||||
export class DashboardComponent {
|
export class DashboardComponent {
|
||||||
public links: Link[] = [];
|
public links: Link[] = [];
|
||||||
displayedColumns: string[] = ['id', 'name', 'link', 'shortLink', 'actions'];
|
displayedColumns: string[] = ['slug', 'name', 'link', 'shortLink', 'actions'];
|
||||||
public user!: AuthRecord;
|
public user!: AuthRecord;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -35,15 +35,15 @@ export class DashboardComponent {
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
private snackBar: MatSnackBar,
|
private snackBar: MatSnackBar,
|
||||||
private userService: UserService,
|
private userService: UserService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
copyLink(id: string) {
|
copyLink(link: Link) {
|
||||||
navigator.clipboard.writeText(this.getShortLink(id));
|
navigator.clipboard.writeText(this.getShortLink(link));
|
||||||
}
|
}
|
||||||
|
|
||||||
getShortLink(id: string): string {
|
getShortLink(link: Link): string {
|
||||||
return 'https://' + window.location.hostname + '/' + id;
|
return 'https://' + window.location.hostname + '/' + link.slug;
|
||||||
}
|
}
|
||||||
|
|
||||||
goToLink(link: Link) {
|
goToLink(link: Link) {
|
||||||
|
@ -54,6 +54,7 @@ export class DashboardComponent {
|
||||||
description:
|
description:
|
||||||
'Are you sure that you want to open ' + link.link + ' now?',
|
'Are you sure that you want to open ' + link.link + ' now?',
|
||||||
},
|
},
|
||||||
|
autoFocus: false,
|
||||||
})
|
})
|
||||||
.afterClosed()
|
.afterClosed()
|
||||||
.subscribe((accepted: Boolean) => {
|
.subscribe((accepted: Boolean) => {
|
||||||
|
@ -83,13 +84,14 @@ export class DashboardComponent {
|
||||||
description:
|
description:
|
||||||
'Are you sure that you want to delete ' + link.name + '?',
|
'Are you sure that you want to delete ' + link.name + '?',
|
||||||
},
|
},
|
||||||
|
autoFocus: false,
|
||||||
})
|
})
|
||||||
.afterClosed()
|
.afterClosed()
|
||||||
.subscribe((accepted: boolean) => {
|
.subscribe((accepted: boolean) => {
|
||||||
if (accepted) {
|
if (accepted) {
|
||||||
this.linkService.deleteLink(link.id).catch(() => {
|
this.linkService.deleteLink(link.id).catch(() => {
|
||||||
const errorNotification = this.snackBar.open(
|
const errorNotification = this.snackBar.open(
|
||||||
'Something went wrong.',
|
'Something went wrong.'
|
||||||
);
|
);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
errorNotification.dismiss();
|
errorNotification.dismiss();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="mx-auto pt-3 container">
|
<div class="mx-auto place-content-center container max-w-md h-full">
|
||||||
<mat-card appearance="outlined">
|
<mat-card class="mx-3 sm:mx-0" appearance="outlined">
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<h1>Login</h1>
|
<h1>Login to jklink</h1>
|
||||||
|
|
||||||
<form class="flex flex-col" [formGroup]="loginForm">
|
<form class="flex flex-col" [formGroup]="loginForm">
|
||||||
<mat-form-field appearance="outline">
|
<mat-form-field appearance="outline">
|
||||||
|
|
|
@ -35,10 +35,7 @@ export class LoginComponent {
|
||||||
private pb = new PocketBase(environment.POCKETBASE);
|
private pb = new PocketBase(environment.POCKETBASE);
|
||||||
public errorMessages: Record<string, string> = {};
|
public errorMessages: Record<string, string> = {};
|
||||||
|
|
||||||
constructor(
|
constructor(private router: Router, private snackBar: MatSnackBar) {}
|
||||||
private router: Router,
|
|
||||||
private snackBar: MatSnackBar,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
private validationErrorMessages: Record<string, string> = {
|
private validationErrorMessages: Record<string, string> = {
|
||||||
required: 'This field is required',
|
required: 'This field is required',
|
||||||
|
@ -55,7 +52,7 @@ export class LoginComponent {
|
||||||
.map(
|
.map(
|
||||||
(errorKey) =>
|
(errorKey) =>
|
||||||
this.validationErrorMessages[errorKey] ||
|
this.validationErrorMessages[errorKey] ||
|
||||||
`Unknown error: ${errorKey}`,
|
`Unknown error: ${errorKey}`
|
||||||
)
|
)
|
||||||
.join(' ');
|
.join(' ');
|
||||||
}
|
}
|
||||||
|
@ -105,7 +102,7 @@ export class LoginComponent {
|
||||||
.collection('users')
|
.collection('users')
|
||||||
.authWithPassword(
|
.authWithPassword(
|
||||||
this.loginForm.get('email')?.value,
|
this.loginForm.get('email')?.value,
|
||||||
this.loginForm.get('password')?.value,
|
this.loginForm.get('password')?.value
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.router.navigate(['dashboard']);
|
this.router.navigate(['dashboard']);
|
||||||
|
|
|
@ -3,4 +3,5 @@ export interface Link {
|
||||||
link: string;
|
link: string;
|
||||||
name: string;
|
name: string;
|
||||||
owner: string;
|
owner: string;
|
||||||
|
slug: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ export class AuthGuard implements CanActivate {
|
||||||
|
|
||||||
async canActivate(
|
async canActivate(
|
||||||
route: ActivatedRouteSnapshot,
|
route: ActivatedRouteSnapshot,
|
||||||
state: RouterStateSnapshot,
|
state: RouterStateSnapshot
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const pb = new PocketBase(environment.POCKETBASE);
|
const pb = new PocketBase(environment.POCKETBASE);
|
||||||
await pb
|
await pb
|
||||||
|
|
|
@ -13,8 +13,8 @@ export class LinkService {
|
||||||
return this.pb.collection<Link>('links').getFullList<Link>();
|
return this.pb.collection<Link>('links').getFullList<Link>();
|
||||||
}
|
}
|
||||||
|
|
||||||
getLink(id: string): Promise<Link> {
|
getLink(slug: string): Promise<Link> {
|
||||||
return this.pb.collection('links').getOne<Link>(id);
|
return this.pb.collection('links').getFirstListItem(`slug="${slug}"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteLink(id: string): Promise<boolean> {
|
deleteLink(id: string): Promise<boolean> {
|
||||||
|
@ -26,6 +26,7 @@ export class LinkService {
|
||||||
name: link.name,
|
name: link.name,
|
||||||
link: link.link,
|
link: link.link,
|
||||||
owner: this.pb.authStore.record?.id,
|
owner: this.pb.authStore.record?.id,
|
||||||
|
slug: link.slug,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from '@angular/core';
|
||||||
import PocketBase, { AuthRecord } from 'pocketbase';
|
import PocketBase, { AuthRecord } from 'pocketbase';
|
||||||
import { environment } from "../../environments/environment";
|
import { environment } from '../../environments/environment';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
|
|
|
@ -12,12 +12,12 @@ export class ViewLinkComponent {
|
||||||
constructor(
|
constructor(
|
||||||
private linkService: LinkService,
|
private linkService: LinkService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.linkService
|
this.linkService
|
||||||
.getLink(this.route.snapshot.params['link'])
|
.getLink(this.route.snapshot.params['slug'])
|
||||||
.then((link) => {
|
.then((link) => {
|
||||||
window.location.href = link.link;
|
window.location.href = link.link;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<html class="h-full" lang="en" data-theme="light">
|
<html class="h-full" lang="en" data-theme="light">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
|
|
|
@ -3,5 +3,5 @@ import { appConfig } from './app/app.config';
|
||||||
import { AppComponent } from './app/app.component';
|
import { AppComponent } from './app/app.component';
|
||||||
|
|
||||||
bootstrapApplication(AppComponent, appConfig).catch((err) =>
|
bootstrapApplication(AppComponent, appConfig).catch((err) =>
|
||||||
console.error(err),
|
console.error(err)
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Reference in a new issue