Project: codever - File: backup-bookmarks-dialog.component.ts

Use the DomSanitizer and its method bypassSecurityTrustUrl as shown in the example below. Thus, you don’t get the unsafe prefix in your generated html

export class BackupBookmarksDialogComponent implements OnInit {

  backupType: string; // 'bookmarks' | 'snippets';
  blobUrl: any;
  sanitizedBlobUrl: any;
  filename: string;

  constructor(
    private dialogRef: MatDialogRef<BackupBookmarksDialogComponent>,
    private router: Router,
    @Inject(MAT_DIALOG_DATA) data,
    private sanitizer: DomSanitizer
  ) {
    this.sanitizedBlobUrl = this.sanitizer.bypassSecurityTrustUrl(data.blobUrl);
    this.blobUrl = data.blobUrl;
    this.backupType = data.backupType;
    const currentDate = new Date();
    this.filename = `${this.backupType}_${currentDate.toISOString()}.json`;
  }

In the html component the sanitizedBlogUrl is injected in the href attribute of the a html element

  <a [href]="sanitizedBlobUrl" [download]="filename" type="button" class="btn btn-primary btn-sm mr-2" (click)="download()"><i class="fas fa-download"></i> Download
  </a>

Reference - https://angular.io/api/platform-browser/DomSanitizer


Shared with from Codever. 👉 Use the Copy to mine functionality to copy this snippet to your own personal collection and easy manage your code snippets.

Codever is open source on Github ⭐🙏

Project: codever

The following example shows the elements required to implement an angular material dialog to ask the user to log in on Codever, when this is needed (like following tags).

First thing add the MatDialogModule in the Angular module where you intend to use the dialog, and the component holding the dialog body (LoginRequiredDialogComponent) to the entryComponents

@NgModule({
  imports:      [
    //...
    MatDialogModule,
    RouterModule
  ],
  declarations: [
   //....
    LoginRequiredDialogComponent
  ],
  exports: [],
  entryComponents: [
    //....
    LoginRequiredDialogComponent,
  ]
})
export class SharedModule { }

Then in a component, where the dialog is launched, e.g TagComponent, inject a MatDialog service to open Material Design modal dialogs. Then configure the dialog with the help of MatDialogConfig and open it with the component holding the content of the dialog:

export class TagComponent implements OnInit {
  constructor(private tagService: TagService,
              //....
              private loginDialog: MatDialog) {
  }

  watchTag() {
    if (!this.userIsLoggedIn) {
      const dialogConfig = new MatDialogConfig();

      dialogConfig.disableClose = true;
      dialogConfig.autoFocus = true;
      dialogConfig.data = {
        message: 'You need to be logged in to follow tags'
      };

      this.loginDialog.open(LoginRequiredDialogComponent, dialogConfig);
    } else {
      this.userDataWatchedTagsStore.watchTag(this.tag);
    }
  }
}

Below is the component, LoginRequiredDialogComponent, holdingcontent (body) of the dialog. You can reference and access the provided the calling component using the MAT_DIALOG_DATA injectable:

import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { KeycloakService } from 'keycloak-angular';
import { Router } from '@angular/router';
import { KeycloakServiceWrapper } from '../../core/keycloak-service-wrapper.service';

@Component({
  selector: 'app-delete-bookmark-dialog',
  templateUrl: './login-required-dialog.component.html',
  styleUrls: ['./login-required-dialog.component.scss']
})
export class LoginRequiredDialogComponent implements OnInit {

  message: string;

  constructor(
    private keycloakService: KeycloakService,
    private keycloakServiceWrapper: KeycloakServiceWrapper,
    private dialogRef: MatDialogRef<LoginRequiredDialogComponent>,
    private router: Router,
    @Inject(MAT_DIALOG_DATA) data
  ) {
    this.message = data.message || 'You need to be logged in to be able execute this action';
  }

  ngOnInit() {
  }

  login() {
    this.dialogRef.close('LOGIN_CONFIRMED');
    this.keycloakServiceWrapper.login();
  }

  cancel() {
    this.dialogRef.close();
  }

}

The login() and cancel() methods seen in the component before, are triggered from the angular html template:

<h2 mat-dialog-title>Login required</h2>

<hr>

<mat-dialog-content>
  <p></p>
</mat-dialog-content>

<hr>

<mat-dialog-actions class="app-dialog-actions">
  <button type="button" class="btn btn-primary btn-sm mr-2" (click)="login()"><i class="fas fa-unlock"></i> Login / Register
  </button>
  <button type="button" class="btn btn-secondary btn-sm" (click)="cancel()">Cancel</button>
</mat-dialog-actions>

Reference - https://material.angular.io/components/dialog/overview


Shared with from Codever. 👉 Use the Copy to mine functionality to copy this snippet to your own personal collection and easy manage your code snippets.

Codever is open source on Github ⭐🙏

Project: codever - File: bookmark-list-element.component.html

Use a two-element array when specifying a route parameter:

<div *ngFor="let tag of bookmark.tags" class="btn-group tag-list  mr-2 mt-1">
  <a class="dropdown-item"
     [routerLink]="['/tagged', tag]"
     title='Public bookmarks tagged ""'>
    <i class="fas fa-tag"></i> Public
  </a>
</div>

This will generate a link similar to the following https://www.codever.dev/tagged/angular, where the value of the tag parameter in routerLink is the string angular

Reference - https://angular.io/guide/router


Shared with from Codever. 👉 Use the Copy to mine functionality to copy this snippet to your own personal collection and easy manage your code snippets.

Codever is open source on Github ⭐🙏

First list available certificates with the following command sudo certbot certificates. Should look something like the following:

$ sudo certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: codever.dev
    Domains: codever.dev www.codever.dev
    Expiry Date: 2022-03-02 11:13:46+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/codever.dev/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/codever.dev/privkey.pem
  Certificate Name: codever.dev
    Domains: codever.dev www.codever.dev
    Expiry Date: 2021-12-21 13:06:54+00:00 (VALID: 19 days)
    Certificate Path: /etc/letsencrypt/live/codever.dev/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/codever.dev/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Select the Certificate Name from the list and do a dry run before executing the actual command, with the help of --dry-run flag - e.g. sudo certbot renew --cert-name codever.dev --dry-run. The result should look something like the following:

sudo certbot renew --cert-name codever.dev --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/codever.dev.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator nginx, Installer nginx
Starting new HTTPS connection (1): acme-staging-v02.api.letsencrypt.org
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for codever.dev
http-01 challenge for www.codever.dev
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed with reload of nginx server; fullchain is
/etc/letsencrypt/live/codever.dev/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/codever.dev/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Execute the actual renewal by removing the --dry-run flag

$ sudo certbot renew --cert-name codever.dev

Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/codever.dev.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator nginx, Installer nginx
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for codever.dev
http-01 challenge for www.codever.dev
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed with reload of nginx server; fullchain is
/etc/letsencrypt/live/codever.dev/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/codever.dev/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Use the sudo cerbot certificates command to verify the validity and check the new expiration date:

$ sudo certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: codever.dev
    Domains: codever.dev www.codever.dev
    Expiry Date: 2022-03-02 11:13:46+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/codever.dev/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/codever.dev/privkey.pem
  Certificate Name: codever.dev
    Domains: codever.dev www.codever.dev
    Expiry Date: 2022-03-02 11:18:39+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/codever.dev/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/codever.dev/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Shared with from Codever. 👉 Use the Copy to mine functionality to copy this snippet to your own personal collection and easy manage your code snippets.

Codever is open source on Github ⭐🙏

We will base the logic around sysdate which returns the current datetime, from which we substract units. For example for the last day from now use sysdate - 1 (defaults to day) and compare with the timestamp column (in this case CREATED_AT) :

select count(*)
from PARTNER
WHERE CREATED_AT > (sysdate - 1)

-- last 2 days would be
select count(*)
from PARTNER
WHERE CREATED_AT > (sysdate - 2)

From the last hour, respectively last two hours use the following commands, where 1/24 is the unit for hour:

-- last hour
select count(*)
from PARTNER
WHERE CREATED_AT > (sysdate - 1)

-- last 2 hours
select count(*)
from PARTNER
WHERE CREATED_AT > (sysdate - 2/24)

Shared with from Codever. 👉 Use the Copy to mine functionality to copy this snippet to your own personal collection and easy manage your code snippets.

Codever is open source on Github ⭐🙏