diff --git a/.gitea/workflows/release-new.yml b/.gitea/workflows/release-new.yml deleted file mode 100644 index 9ab967d..0000000 --- a/.gitea/workflows/release-new.yml +++ /dev/null @@ -1,43 +0,0 @@ -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 }} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..68a1939 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,46 @@ +# Changelog + +## 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)) + +## [1.6.0](https://git.kjan.de/jank/jklink/compare/v1.5.0...v1.6.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)) +* **auth:** use async in canActivate for auth refresh ([eadd831](https://git.kjan.de/jank/jklink/commit/eadd831e3f1e0c2082d0a7ee3acfedf7f40fea74)) +* **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)) diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 467203d..3fb9e53 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -25,7 +25,7 @@ describe('AppComponent', () => { fixture.detectChanges(); const compiled = fixture.nativeElement as HTMLElement; expect(compiled.querySelector('h1')?.textContent).toContain( - 'Hello, jklink' + 'Hello, jklink', ); }); }); diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 9168254..c9976fa 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -21,7 +21,7 @@ export const routes: Routes = [ canActivate: [AuthGuard], }, { - path: ':slug', + path: ':link', component: ViewLinkComponent, }, { diff --git a/src/app/confirmation-modal/confirmation-modal.component.html b/src/app/confirmation-modal/confirmation-modal.component.html index ed62bbc..13635d0 100644 --- a/src/app/confirmation-modal/confirmation-modal.component.html +++ b/src/app/confirmation-modal/confirmation-modal.component.html @@ -1,14 +1,6 @@

{{ data.title }}

{{ data.description }} - + diff --git a/src/app/create-link/create-link.component.html b/src/app/create-link/create-link.component.html index 5fc49cc..304eb92 100644 --- a/src/app/create-link/create-link.component.html +++ b/src/app/create-link/create-link.component.html @@ -1,13 +1,6 @@
- @@ -27,11 +20,6 @@ placeholder="https://kjan.de" /> - - {{ errorMessages["slug"] }} - Custom slug (optional) - - diff --git a/src/app/create-link/create-link.component.ts b/src/app/create-link/create-link.component.ts index 8d3eb08..ebf9788 100644 --- a/src/app/create-link/create-link.component.ts +++ b/src/app/create-link/create-link.component.ts @@ -13,8 +13,6 @@ import { MatInputModule, MatLabel } from '@angular/material/input'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatButtonModule } from '@angular/material/button'; import { debounceTime } from 'rxjs'; -import { AsyncPipe } from '@angular/common'; -import { MatSnackBar } from '@angular/material/snack-bar'; @Component({ selector: 'app-create-link', @@ -37,7 +35,6 @@ export class CreateLinkComponent { constructor( private linkService: LinkService, private router: Router, - private snackBar: MatSnackBar, ) {} private validationErrorMessages: Record = { @@ -76,7 +73,6 @@ export class CreateLinkComponent { /((([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.updateErrorMessages(); @@ -93,17 +89,8 @@ export class CreateLinkComponent { .createLink({ name: this.createLinkForm.get('name')?.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(() => { if (!this.requestFailed) { this.router.navigate(['dashboard']); diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index ca085e2..21581f1 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -24,11 +24,11 @@ The actual rendered columns are set as a property on the row definition" --> - - Slug + + ID - {{ element.slug }} + {{ element.id }} @@ -49,7 +49,11 @@ Short link - diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts index e37aa3c..ef72234 100644 --- a/src/app/dashboard/dashboard.component.ts +++ b/src/app/dashboard/dashboard.component.ts @@ -27,7 +27,7 @@ import { AuthRecord } from 'pocketbase'; }) export class DashboardComponent { public links: Link[] = []; - displayedColumns: string[] = ['slug', 'name', 'link', 'shortLink', 'actions']; + displayedColumns: string[] = ['id', 'name', 'link', 'shortLink', 'actions']; public user!: AuthRecord; constructor( @@ -35,15 +35,15 @@ export class DashboardComponent { private router: Router, private dialog: MatDialog, private snackBar: MatSnackBar, - private userService: UserService + private userService: UserService, ) {} - copyLink(link: Link) { - navigator.clipboard.writeText(this.getShortLink(link)); + copyLink(id: string) { + navigator.clipboard.writeText(this.getShortLink(id)); } - getShortLink(link: Link): string { - return 'https://' + window.location.hostname + '/' + link.slug; + getShortLink(id: string): string { + return 'https://' + window.location.hostname + '/' + id; } goToLink(link: Link) { @@ -54,12 +54,11 @@ export class DashboardComponent { description: 'Are you sure that you want to open ' + link.link + ' now?', }, - autoFocus: false, }) .afterClosed() .subscribe((accepted: Boolean) => { if (accepted) { - this.router.navigate([link.slug]); + this.router.navigate([link.id]); } }); } @@ -84,14 +83,13 @@ export class DashboardComponent { description: 'Are you sure that you want to delete ' + link.name + '?', }, - autoFocus: false, }) .afterClosed() .subscribe((accepted: boolean) => { if (accepted) { this.linkService.deleteLink(link.id).catch(() => { const errorNotification = this.snackBar.open( - 'Something went wrong.' + 'Something went wrong.', ); setTimeout(() => { errorNotification.dismiss(); diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html index d559138..701eebe 100644 --- a/src/app/login/login.component.html +++ b/src/app/login/login.component.html @@ -1,7 +1,7 @@ -
- +
+ -

Login to jklink

+

Login

diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts index d05fa7a..8d2b906 100644 --- a/src/app/login/login.component.ts +++ b/src/app/login/login.component.ts @@ -35,7 +35,10 @@ export class LoginComponent { private pb = new PocketBase(environment.POCKETBASE); public errorMessages: Record = {}; - constructor(private router: Router, private snackBar: MatSnackBar) {} + constructor( + private router: Router, + private snackBar: MatSnackBar, + ) {} private validationErrorMessages: Record = { required: 'This field is required', @@ -52,7 +55,7 @@ export class LoginComponent { .map( (errorKey) => this.validationErrorMessages[errorKey] || - `Unknown error: ${errorKey}` + `Unknown error: ${errorKey}`, ) .join(' '); } @@ -102,7 +105,7 @@ export class LoginComponent { .collection('users') .authWithPassword( this.loginForm.get('email')?.value, - this.loginForm.get('password')?.value + this.loginForm.get('password')?.value, ) .then(() => { this.router.navigate(['dashboard']); diff --git a/src/app/models/link.ts b/src/app/models/link.ts index 86ce99a..0f961c3 100644 --- a/src/app/models/link.ts +++ b/src/app/models/link.ts @@ -3,5 +3,4 @@ export interface Link { link: string; name: string; owner: string; - slug: string; } diff --git a/src/app/service/auth.service.ts b/src/app/service/auth.service.ts index 387a6c3..4290efa 100644 --- a/src/app/service/auth.service.ts +++ b/src/app/service/auth.service.ts @@ -18,7 +18,7 @@ export class AuthGuard implements CanActivate { async canActivate( route: ActivatedRouteSnapshot, - state: RouterStateSnapshot + state: RouterStateSnapshot, ): Promise { const pb = new PocketBase(environment.POCKETBASE); await pb diff --git a/src/app/service/link.service.ts b/src/app/service/link.service.ts index a4a3f91..77c01ee 100644 --- a/src/app/service/link.service.ts +++ b/src/app/service/link.service.ts @@ -13,8 +13,8 @@ export class LinkService { return this.pb.collection('links').getFullList(); } - getLink(slug: string): Promise { - return this.pb.collection('links').getFirstListItem(`slug="${slug}"`); + getLink(id: string): Promise { + return this.pb.collection('links').getOne(id); } deleteLink(id: string): Promise { @@ -26,7 +26,6 @@ export class LinkService { name: link.name, link: link.link, owner: this.pb.authStore.record?.id, - slug: link.slug, }); } } diff --git a/src/app/service/user.service.ts b/src/app/service/user.service.ts index 6893b96..ad6a555 100644 --- a/src/app/service/user.service.ts +++ b/src/app/service/user.service.ts @@ -1,6 +1,6 @@ -import { Injectable } from '@angular/core'; +import { Injectable } from "@angular/core"; import PocketBase, { AuthRecord } from 'pocketbase'; -import { environment } from '../../environments/environment'; +import { environment } from "../../environments/environment"; @Injectable({ providedIn: 'root', diff --git a/src/app/view-link/view-link.component.ts b/src/app/view-link/view-link.component.ts index c8fa572..635e560 100644 --- a/src/app/view-link/view-link.component.ts +++ b/src/app/view-link/view-link.component.ts @@ -12,12 +12,12 @@ export class ViewLinkComponent { constructor( private linkService: LinkService, private route: ActivatedRoute, - private router: Router + private router: Router, ) {} ngOnInit(): void { this.linkService - .getLink(this.route.snapshot.params['slug']) + .getLink(this.route.snapshot.params['link']) .then((link) => { window.location.href = link.link; }); diff --git a/src/index.html b/src/index.html index 44defb9..9d15f1b 100644 --- a/src/index.html +++ b/src/index.html @@ -1,4 +1,4 @@ - + @@ -17,14 +17,5 @@ - - diff --git a/src/main.ts b/src/main.ts index 514c89a..8882c45 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,5 +3,5 @@ import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), );