Browse Source

Task/resolve strict template errors in shell and dialogs (#8102)

Resolve strict template errors
pull/8070/head^2
Kenrick Tandrian 12 hours ago
committed by GitHub
parent
commit
ce042c1cd7
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      apps/client/src/app/app.component.html
  2. 8
      apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html
  3. 18
      apps/client/src/app/components/footer/footer.component.html
  4. 80
      apps/client/src/app/components/footer/footer.component.ts
  5. 10
      apps/client/src/app/components/header/header.component.html
  6. 4
      apps/client/src/app/components/user-account-membership/user-account-membership.html
  7. 8
      apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html
  8. 7
      apps/client/src/app/util/date.util.ts

2
apps/client/src/app/app.component.html

@ -48,6 +48,6 @@
@if (showFooter) { @if (showFooter) {
<footer class="justify-content-center overflow-hidden w-100"> <footer class="justify-content-center overflow-hidden w-100">
<gf-footer class="py-4" [info]="info" [user]="user" /> <gf-footer class="py-4" [info]="info" />
</footer> </footer>
} }

8
apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html

@ -28,12 +28,8 @@
matInput matInput
(keydown.enter)="$event.stopPropagation()" (keydown.enter)="$event.stopPropagation()"
/> />
@if (platformForm.get('url')?.value) { @if (platformForm.get('url')?.value; as url) {
<gf-entity-logo <gf-entity-logo class="mat-icon" matSuffix [url]="url" />
class="mat-icon"
matSuffix
[url]="platformForm.get('url').value"
/>
} }
</mat-form-field> </mat-form-field>
</div> </div>

18
apps/client/src/app/components/footer/footer.component.html

@ -6,7 +6,7 @@
<div class="col-sm"> <div class="col-sm">
<div class="h6 mt-2" i18n>Personal Finance</div> <div class="h6 mt-2" i18n>Personal Finance</div>
<ul class="list-unstyled"> <ul class="list-unstyled">
@if (hasPermissionToAccessFearAndGreedIndex) { @if (hasPermissionToAccessFearAndGreedIndex()) {
<li> <li>
<a i18n [routerLink]="routerLinkMarkets">Markets</a> <a i18n [routerLink]="routerLinkMarkets">Markets</a>
</li> </li>
@ -18,7 +18,7 @@
<div class="h6 mt-2">Ghostfolio</div> <div class="h6 mt-2">Ghostfolio</div>
<ul class="list-unstyled"> <ul class="list-unstyled">
<li><a i18n [routerLink]="routerLinkAbout">About</a></li> <li><a i18n [routerLink]="routerLinkAbout">About</a></li>
@if (hasPermissionForSubscription) { @if (hasPermissionForSubscription()) {
<li> <li>
<a i18n [routerLink]="routerLinkBlog">Blog</a> <a i18n [routerLink]="routerLinkBlog">Blog</a>
</li> </li>
@ -27,43 +27,43 @@
<a i18n [routerLink]="routerLinkAboutChangelog">Changelog</a> <a i18n [routerLink]="routerLinkAboutChangelog">Changelog</a>
</li> </li>
<li><a i18n [routerLink]="routerLinkFeatures">Features</a></li> <li><a i18n [routerLink]="routerLinkFeatures">Features</a></li>
@if (hasPermissionForSubscription) { @if (hasPermissionForSubscription()) {
<li> <li>
<a i18n [routerLink]="routerLinkFaq" <a i18n [routerLink]="routerLinkFaq"
>Frequently Asked Questions (FAQ)</a >Frequently Asked Questions (FAQ)</a
> >
</li> </li>
} }
@if (!hasPermissionForSubscription) { @if (!hasPermissionForSubscription()) {
<li> <li>
<a i18n [routerLink]="routerLinkAboutLicense">License</a> <a i18n [routerLink]="routerLinkAboutLicense">License</a>
</li> </li>
} }
@if (hasPermissionForStatistics) { @if (hasPermissionForStatistics()) {
<li> <li>
<a [routerLink]="routerLinkOpenStartup">Open Startup</a> <a [routerLink]="routerLinkOpenStartup">Open Startup</a>
</li> </li>
} }
@if (hasPermissionForSubscription) { @if (hasPermissionForSubscription()) {
<li> <li>
<a i18n [routerLink]="routerLinkPricing">Pricing</a> <a i18n [routerLink]="routerLinkPricing">Pricing</a>
</li> </li>
} }
@if (hasPermissionForSubscription) { @if (hasPermissionForSubscription()) {
<li> <li>
<a i18n [routerLink]="routerLinkAboutPrivacyPolicy" <a i18n [routerLink]="routerLinkAboutPrivacyPolicy"
>Privacy Policy</a >Privacy Policy</a
> >
</li> </li>
} }
@if (hasPermissionForSubscription) { @if (hasPermissionForSubscription()) {
<li> <li>
<a i18n [routerLink]="routerLinkAboutTermsOfService" <a i18n [routerLink]="routerLinkAboutTermsOfService"
>Terms of Service</a >Terms of Service</a
> >
</li> </li>
} }
@if (hasPermissionForSubscription) { @if (hasPermissionForSubscription()) {
<li> <li>
<a <a
class="align-items-baseline d-flex" class="align-items-baseline d-flex"

80
apps/client/src/app/components/footer/footer.component.ts

@ -1,4 +1,4 @@
import { InfoItem, User } from '@ghostfolio/common/interfaces'; import { InfoItem } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { GfLogoComponent } from '@ghostfolio/ui/logo'; import { GfLogoComponent } from '@ghostfolio/ui/logo';
@ -6,9 +6,9 @@ import { GfLogoComponent } from '@ghostfolio/ui/logo';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
Component, Component,
computed,
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
Input, input
OnChanges
} from '@angular/core'; } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone'; import { IonIcon } from '@ionic/angular/standalone';
@ -23,51 +23,53 @@ import { openOutline } from 'ionicons/icons';
styleUrls: ['./footer.component.scss'], styleUrls: ['./footer.component.scss'],
templateUrl: './footer.component.html' templateUrl: './footer.component.html'
}) })
export class GfFooterComponent implements OnChanges { export class GfFooterComponent {
@Input() public info: InfoItem; public readonly info = input.required<InfoItem | undefined>();
@Input() public user: User;
public currentYear = new Date().getFullYear(); protected readonly currentYear = new Date().getFullYear();
public hasPermissionForStatistics: boolean;
public hasPermissionForSubscription: boolean;
public hasPermissionToAccessFearAndGreedIndex: boolean;
public routerLinkAbout = publicRoutes.about.routerLink;
public routerLinkAboutChangelog =
publicRoutes.about.subRoutes.changelog.routerLink;
public routerLinkAboutLicense =
publicRoutes.about.subRoutes.license.routerLink;
public routerLinkAboutPrivacyPolicy =
publicRoutes.about.subRoutes.privacyPolicy.routerLink;
public routerLinkAboutTermsOfService =
publicRoutes.about.subRoutes.termsOfService.routerLink;
public routerLinkBlog = publicRoutes.blog.routerLink;
public routerLinkFaq = publicRoutes.faq.routerLink;
public routerLinkFeatures = publicRoutes.features.routerLink;
public routerLinkMarkets = publicRoutes.markets.routerLink;
public routerLinkOpenStartup = publicRoutes.openStartup.routerLink;
public routerLinkPricing = publicRoutes.pricing.routerLink;
public routerLinkResources = publicRoutes.resources.routerLink;
public constructor() {
addIcons({
openOutline
});
}
public ngOnChanges() { protected readonly hasPermissionForStatistics = computed(() => {
this.hasPermissionForStatistics = hasPermission( return hasPermission(
this.info?.globalPermissions, this.info()?.globalPermissions,
permissions.enableStatistics permissions.enableStatistics
); );
});
this.hasPermissionForSubscription = hasPermission( protected readonly hasPermissionForSubscription = computed(() => {
this.info?.globalPermissions, return hasPermission(
this.info()?.globalPermissions,
permissions.enableSubscription permissions.enableSubscription
); );
});
this.hasPermissionToAccessFearAndGreedIndex = hasPermission( protected readonly hasPermissionToAccessFearAndGreedIndex = computed(() => {
this.info?.globalPermissions, return hasPermission(
this.info()?.globalPermissions,
permissions.enableFearAndGreedIndex permissions.enableFearAndGreedIndex
); );
});
protected readonly routerLinkAbout = publicRoutes.about.routerLink;
protected readonly routerLinkAboutChangelog =
publicRoutes.about.subRoutes.changelog.routerLink;
protected readonly routerLinkAboutLicense =
publicRoutes.about.subRoutes.license.routerLink;
protected readonly routerLinkAboutPrivacyPolicy =
publicRoutes.about.subRoutes.privacyPolicy.routerLink;
protected readonly routerLinkAboutTermsOfService =
publicRoutes.about.subRoutes.termsOfService.routerLink;
protected readonly routerLinkBlog = publicRoutes.blog.routerLink;
protected readonly routerLinkFaq = publicRoutes.faq.routerLink;
protected readonly routerLinkFeatures = publicRoutes.features.routerLink;
protected readonly routerLinkMarkets = publicRoutes.markets.routerLink;
protected readonly routerLinkOpenStartup =
publicRoutes.openStartup.routerLink;
protected readonly routerLinkPricing = publicRoutes.pricing.routerLink;
protected readonly routerLinkResources = publicRoutes.resources.routerLink;
public constructor() {
addIcons({
openOutline
});
} }
} }

10
apps/client/src/app/components/header/header.component.html

@ -124,7 +124,7 @@
>About</a >About</a
> >
</li> </li>
@if (hasPermissionToAccessAssistant) { @if (hasPermissionToAccessAssistant && user(); as user) {
<li class="d-inline-flex list-inline-item"> <li class="d-inline-flex list-inline-item">
<button <button
#assistantTrigger="matMenuTrigger" #assistantTrigger="matMenuTrigger"
@ -144,7 +144,7 @@
class="no-max-width" class="no-max-width"
xPosition="before" xPosition="before"
[overlapTrigger]="true" [overlapTrigger]="true"
(closed)="assistantElement()?.setIsOpen(false)" (closed)="assistantElement().setIsOpen(false)"
> >
<gf-assistant <gf-assistant
#assistant #assistant
@ -156,7 +156,7 @@
hasPermissionToChangeDateRange() hasPermissionToChangeDateRange()
" "
[hasPermissionToChangeFilters]="hasPermissionToChangeFilters()" [hasPermissionToChangeFilters]="hasPermissionToChangeFilters()"
[user]="user()" [user]="user"
(closed)="closeAssistant()" (closed)="closeAssistant()"
(dateRangeChanged)="onDateRangeChange($event)" (dateRangeChanged)="onDateRangeChange($event)"
(filtersChanged)="onFiltersChanged($event)" (filtersChanged)="onFiltersChanged($event)"
@ -191,7 +191,7 @@
<a class="d-flex" mat-menu-item [routerLink]="routerLinkPricing" <a class="d-flex" mat-menu-item [routerLink]="routerLinkPricing"
><span class="align-items-center d-flex" ><span class="align-items-center d-flex"
><span> ><span>
@if (user().subscription.offer.isRenewal) { @if (user()?.subscription?.offer?.isRenewal) {
<ng-container i18n>Renew Plan</ng-container> <ng-container i18n>Renew Plan</ng-container>
} @else { } @else {
<ng-container i18n>Upgrade Plan</ng-container> <ng-container i18n>Upgrade Plan</ng-container>
@ -203,7 +203,7 @@
></a> ></a>
<hr class="m-0" /> <hr class="m-0" />
} }
@if (user()?.access?.length > 0) { @if ((user()?.access?.length ?? 0) > 0) {
<button mat-menu-item (click)="impersonateAccount(null)"> <button mat-menu-item (click)="impersonateAccount(null)">
<span class="align-items-center d-flex"> <span class="align-items-center d-flex">
<ion-icon <ion-icon

4
apps/client/src/app/components/user-account-membership/user-account-membership.html

@ -3,7 +3,9 @@
<div class="col"> <div class="col">
<div class="align-items-center d-flex flex-column"> <div class="align-items-center d-flex flex-column">
<gf-membership-card <gf-membership-card
[expiresAt]="user?.subscription?.expiresAt | date: defaultDateFormat" [expiresAt]="
(user?.subscription?.expiresAt | date: defaultDateFormat) ?? ''
"
[hasPermissionToCreateApiKey]="hasPermissionToCreateApiKey" [hasPermissionToCreateApiKey]="hasPermissionToCreateApiKey"
[hover3d]="true" [hover3d]="true"
[name]="user?.subscription?.type" [name]="user?.subscription?.type"

8
apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html

@ -43,7 +43,7 @@
}}</span> }}</span>
</mat-form-field> </mat-form-field>
</div> </div>
<div [class.d-none]="platforms?.length < 1"> <div [class.d-none]="platforms.length < 1">
<mat-form-field appearance="outline" class="w-100"> <mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Platform</mat-label> <mat-label i18n>Platform</mat-label>
@if (selectedPlatform) { @if (selectedPlatform) {
@ -51,8 +51,8 @@
class="ml-3" class="ml-3"
matPrefix matPrefix
[hasPlaceholder]="true" [hasPlaceholder]="true"
[tooltip]="selectedPlatform?.name" [tooltip]="selectedPlatform.name ?? ''"
[url]="selectedPlatform?.url" [url]="selectedPlatform.url"
/> />
} }
<input <input
@ -73,7 +73,7 @@
<gf-entity-logo <gf-entity-logo
class="mr-1" class="mr-1"
[hasPlaceholder]="true" [hasPlaceholder]="true"
[tooltip]="platformEntry.name" [tooltip]="platformEntry.name ?? ''"
[url]="platformEntry.url" [url]="platformEntry.url"
/> />
<span>{{ platformEntry.name }}</span> <span>{{ platformEntry.name }}</span>

7
apps/client/src/app/util/date.util.ts

@ -10,16 +10,17 @@ export function formatRelativeTime({
date, date,
language language
}: { }: {
date: string; date: Date | string | null | undefined;
language?: string; language?: string;
}) { }) {
if (date) { if (date) {
const distanceString = formatDistanceToNowStrict(parseISO(date), { const parsedDate = typeof date === 'string' ? parseISO(date) : date;
const distanceString = formatDistanceToNowStrict(parsedDate, {
addSuffix: true, addSuffix: true,
locale: getDateFnsLocale(language) locale: getDateFnsLocale(language)
}); });
return Math.abs(differenceInSeconds(parseISO(date), new Date())) < 60 return Math.abs(differenceInSeconds(parsedDate, new Date())) < 60
? $localize`just now` ? $localize`just now`
: distanceString; : distanceString;
} }

Loading…
Cancel
Save