mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-23 10:02:51 +00:00
refactor: rework components
This commit is contained in:
@@ -12,19 +12,19 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {Component, Input} from '@angular/core';
|
import {ChangeDetectionStrategy, Component, Input} from '@angular/core';
|
||||||
import {SCPostalAddress} from '@openstapps/core';
|
import {SCPostalAddress} from '@openstapps/core';
|
||||||
|
import {IonCard, IonCardContent, IonCardHeader, IonCol, IonGrid, IonRow} from '@ionic/angular/standalone';
|
||||||
|
import {TranslateModule} from '@ngx-translate/core';
|
||||||
|
import {TitleCasePipe} from '@angular/common';
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO
|
|
||||||
*/
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'stapps-address-detail',
|
selector: 'stapps-address-detail',
|
||||||
templateUrl: 'address-detail.html',
|
templateUrl: 'address-detail.html',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
standalone: true,
|
||||||
|
imports: [IonCard, IonCardHeader, IonCardContent, IonGrid, IonRow, IonCol, TranslateModule, TitleCasePipe],
|
||||||
})
|
})
|
||||||
export class AddressDetailComponent {
|
export class AddressDetailComponent {
|
||||||
/**
|
|
||||||
* TODO
|
|
||||||
*/
|
|
||||||
@Input() address: SCPostalAddress;
|
@Input() address: SCPostalAddress;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,13 +12,41 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {Component, Input} from '@angular/core';
|
import {ChangeDetectionStrategy, Component, Input} from '@angular/core';
|
||||||
import {SCCertificationWithoutReferences} from '@openstapps/core';
|
import {SCCertificationWithoutReferences} from '@openstapps/core';
|
||||||
|
import {
|
||||||
|
IonCard,
|
||||||
|
IonCardContent,
|
||||||
|
IonCardHeader,
|
||||||
|
IonCardSubtitle,
|
||||||
|
IonCardTitle,
|
||||||
|
IonContent,
|
||||||
|
IonNote,
|
||||||
|
IonPopover,
|
||||||
|
} from '@ionic/angular/standalone';
|
||||||
|
import {TranslateModule} from '@ngx-translate/core';
|
||||||
|
import {ThingTranslateModule} from '../../../translation/thing-translate.module';
|
||||||
|
import {ExternalLinkComponent} from './external-link.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'stapps-certifications-in-detail',
|
selector: 'stapps-certifications-in-detail',
|
||||||
templateUrl: 'certifications-in-detail.html',
|
templateUrl: 'certifications-in-detail.html',
|
||||||
styleUrls: ['certifications-in-detail.scss'],
|
styleUrl: 'certifications-in-detail.scss',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
IonCard,
|
||||||
|
IonCardHeader,
|
||||||
|
TranslateModule,
|
||||||
|
IonCardContent,
|
||||||
|
ThingTranslateModule,
|
||||||
|
IonPopover,
|
||||||
|
IonContent,
|
||||||
|
IonCardTitle,
|
||||||
|
IonCardSubtitle,
|
||||||
|
IonNote,
|
||||||
|
ExternalLinkComponent,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class CertificationsInDetailComponent {
|
export class CertificationsInDetailComponent {
|
||||||
@Input() certifications: SCCertificationWithoutReferences[] = [];
|
@Input() certifications: SCCertificationWithoutReferences[] = [];
|
||||||
|
|||||||
@@ -16,22 +16,22 @@
|
|||||||
<ion-card-header>{{ 'data.types.certification.TITLE' | translate }}</ion-card-header>
|
<ion-card-header>{{ 'data.types.certification.TITLE' | translate }}</ion-card-header>
|
||||||
<ion-card-content>
|
<ion-card-content>
|
||||||
<div class="certification-list">
|
<div class="certification-list">
|
||||||
<ng-container *ngFor="let cert of certifications">
|
@for (certification of certifications; track $index) {
|
||||||
<img
|
<img
|
||||||
(click)="popover.present($event)"
|
(click)="popover.present($event)"
|
||||||
[width]="72"
|
[width]="72"
|
||||||
[src]="'image' | thingTranslate: cert"
|
[src]="'image' | thingTranslate: certification"
|
||||||
[alt]="'description' | thingTranslate: cert"
|
[alt]="'description' | thingTranslate: certification"
|
||||||
/>
|
/>
|
||||||
<ion-popover #popover>
|
<ion-popover #popover>
|
||||||
<ng-template>
|
<ng-template>
|
||||||
<ion-content class="ion-padding">
|
<ion-content class="ion-padding">
|
||||||
<ion-card-title>{{ 'name' | thingTranslate: cert }}</ion-card-title>
|
<ion-card-title>{{ 'name' | thingTranslate: certification }}</ion-card-title>
|
||||||
<ion-card-subtitle> {{ 'description' | thingTranslate: cert }} </ion-card-subtitle>
|
<ion-card-subtitle> {{ 'description' | thingTranslate: certification }} </ion-card-subtitle>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</ion-popover>
|
</ion-popover>
|
||||||
</ng-container>
|
}
|
||||||
</div>
|
</div>
|
||||||
<ion-note>
|
<ion-note>
|
||||||
<stapps-external-link
|
<stapps-external-link
|
||||||
|
|||||||
@@ -12,14 +12,17 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
import {ChangeDetectionStrategy, Component, Input} from '@angular/core';
|
||||||
import {Component, Input} from '@angular/core';
|
|
||||||
import {SimpleBrowser} from '../../../util/browser.factory';
|
import {SimpleBrowser} from '../../../util/browser.factory';
|
||||||
|
import {IonIcon} from '@ionic/angular/standalone';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'stapps-external-link',
|
selector: 'stapps-external-link',
|
||||||
templateUrl: './external-link.html',
|
templateUrl: 'external-link.html',
|
||||||
styleUrls: ['./external-link.scss'],
|
styleUrl: 'external-link.scss',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
standalone: true,
|
||||||
|
imports: [IonIcon],
|
||||||
})
|
})
|
||||||
export class ExternalLinkComponent {
|
export class ExternalLinkComponent {
|
||||||
@Input() link: string;
|
@Input() link: string;
|
||||||
@@ -29,7 +32,7 @@ export class ExternalLinkComponent {
|
|||||||
constructor(private browser: SimpleBrowser) {}
|
constructor(private browser: SimpleBrowser) {}
|
||||||
|
|
||||||
onLinkClick(url: string) {
|
onLinkClick(url: string) {
|
||||||
// make sure if the url is valid and then open it in the browser (prevent problem in iOS)
|
// make sure if the url is valid and then open it in the browser (prevent issues in iOS)
|
||||||
this.browser.open(new URL(url).href);
|
this.browser.open(new URL(url).href);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,4 +12,4 @@
|
|||||||
~ You should have received a copy of the GNU General Public License along with
|
~ You should have received a copy of the GNU General Public License along with
|
||||||
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<a (click)="onLinkClick(link)">{{ text }}<ion-icon name="open_in_browser"></ion-icon> </a>
|
<a (click)="onLinkClick(link)">{{ text }}<ion-icon name="open_in_browser"></ion-icon></a>
|
||||||
|
|||||||
@@ -12,19 +12,24 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {Component, Input} from '@angular/core';
|
import {ChangeDetectionStrategy, Component, Input} from '@angular/core';
|
||||||
import {SCIndexableThings} from '@openstapps/core';
|
import {SCIndexableThings} from '@openstapps/core';
|
||||||
import {FavoritesService} from '../../favorites/favorites.service';
|
import {FavoritesService} from '../../favorites/favorites.service';
|
||||||
import {Observable} from 'rxjs';
|
import {Observable} from 'rxjs';
|
||||||
import {map, take} from 'rxjs/operators';
|
import {map, take} from 'rxjs/operators';
|
||||||
|
import {IonButton, IonIcon} from '@ionic/angular/standalone';
|
||||||
|
import {AsyncPipe} from '@angular/common';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The button to add or remove a thing from favorites
|
* The button to add or remove a thing from favorites
|
||||||
*/
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'stapps-favorite-button',
|
selector: 'stapps-favorite-button',
|
||||||
templateUrl: './favorite-button.component.html',
|
templateUrl: 'favorite-button.html',
|
||||||
styleUrls: ['./favorite-button.component.scss'],
|
styleUrl: 'favorite-button.scss',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
standalone: true,
|
||||||
|
imports: [IonButton, IonIcon, AsyncPipe],
|
||||||
})
|
})
|
||||||
export class FavoriteButtonComponent {
|
export class FavoriteButtonComponent {
|
||||||
/**
|
/**
|
||||||
@@ -63,7 +68,7 @@ export class FavoriteButtonComponent {
|
|||||||
* @param event A click event
|
* @param event A click event
|
||||||
*/
|
*/
|
||||||
async toggle(event: Event) {
|
async toggle(event: Event) {
|
||||||
// prevent additional effects e.g. router to be activated
|
// prevent additional effects e.g., router to be activated
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.isFavorite$.pipe(take(1)).subscribe(enabled => {
|
this.isFavorite$.pipe(take(1)).subscribe(enabled => {
|
||||||
|
|||||||
@@ -12,23 +12,16 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {Component, Input} from '@angular/core';
|
import {ChangeDetectionStrategy, Component, Input} from '@angular/core';
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO
|
|
||||||
*/
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'stapps-long-inline-text',
|
selector: 'stapps-long-inline-text',
|
||||||
templateUrl: 'long-inline-text.html',
|
templateUrl: 'long-inline-text.html',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
standalone: true,
|
||||||
})
|
})
|
||||||
export class LongInlineTextComponent {
|
export class LongInlineTextComponent {
|
||||||
/**
|
|
||||||
* TODO
|
|
||||||
*/
|
|
||||||
@Input() size: number;
|
@Input() size: number;
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO
|
|
||||||
*/
|
|
||||||
@Input() text: string;
|
@Input() text: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,20 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<span class="ion-hide-sm-up">
|
<span class="ion-hide-sm-up">
|
||||||
{{ text | slice: 0 : size }}
|
{{ text.slice(0, size) }}
|
||||||
<span *ngIf="text.length > size" class="ion-hide-sm-up">…</span>
|
@if (text.length > size) {
|
||||||
|
…
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
<span class="ion-hide-sm-down ion-hide-md-up">
|
<span class="ion-hide-sm-down ion-hide-md-up">
|
||||||
{{ text | slice: 0 : size * 2 }}
|
{{ text.slice(0, size * 2) }}
|
||||||
<span *ngIf="text.length > size * 2" class="ion-hide-sm-down ion-hide-md-up"> … </span>
|
@if (text.length > size * 2) {
|
||||||
|
…
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
<span class="ion-hide-md-down">
|
<span class="ion-hide-md-down">
|
||||||
{{ text | slice: 0 : size * 3 }}
|
{{ text.slice(0, size * 3) }}
|
||||||
<span *ngIf="text.length > size * 3" class="ion-hide-md-down">…</span>
|
@if (text.length > size * 3) {
|
||||||
|
…
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -55,5 +55,5 @@ import {FormatPipeModule, ParseIsoPipeModule} from 'ngx-date-fns';
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class OffersDetailComponent {
|
export class OffersDetailComponent {
|
||||||
@Input() offers: Array<SCThingThatCanBeOfferedOffer<SCAcademicPriceGroup>>;
|
@Input() offers: SCThingThatCanBeOfferedOffer<SCAcademicPriceGroup>[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
</ion-grid>
|
</ion-grid>
|
||||||
} @else if (offer.prices) {
|
} @else if (offer.prices) {
|
||||||
<ion-grid>
|
<ion-grid>
|
||||||
@for (group of offer.prices | keyvalue) {
|
@for (group of offer.prices | keyvalue; track $index) {
|
||||||
<ion-row>
|
<ion-row>
|
||||||
@if (group[0] !== 'default') {
|
@if (group[0] !== 'default') {
|
||||||
<ion-col>{{ 'data.detail.offers.' + group[0] | translate }} </ion-col>
|
<ion-col>{{ 'data.detail.offers.' + group[0] | translate }} </ion-col>
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ import {RatingProvider} from '../rating.provider';
|
|||||||
import {ratingAnimation} from './rating.animation';
|
import {ratingAnimation} from './rating.animation';
|
||||||
import {BehaviorSubject, filter, merge, mergeMap, of, ReplaySubject, withLatestFrom} from 'rxjs';
|
import {BehaviorSubject, filter, merge, mergeMap, of, ReplaySubject, withLatestFrom} from 'rxjs';
|
||||||
import {catchError, map} from 'rxjs/operators';
|
import {catchError, map} from 'rxjs/operators';
|
||||||
|
import {IonButton, IonIcon} from '@ionic/angular/standalone';
|
||||||
|
import {AsyncPipe} from '@angular/common';
|
||||||
|
import {TranslateModule} from '@ngx-translate/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'stapps-rating',
|
selector: 'stapps-rating',
|
||||||
@@ -26,6 +29,8 @@ import {catchError, map} from 'rxjs/operators';
|
|||||||
styleUrls: ['rating.scss'],
|
styleUrls: ['rating.scss'],
|
||||||
animations: [ratingAnimation],
|
animations: [ratingAnimation],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
standalone: true,
|
||||||
|
imports: [IonButton, AsyncPipe, IonIcon, TranslateModule],
|
||||||
})
|
})
|
||||||
export class StappsRatingComponent {
|
export class StappsRatingComponent {
|
||||||
performRating = new BehaviorSubject(false);
|
performRating = new BehaviorSubject(false);
|
||||||
|
|||||||
@@ -13,28 +13,28 @@
|
|||||||
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<ion-button
|
@if (canBeRated | async) {
|
||||||
*ngIf="canBeRated | async"
|
<ion-button
|
||||||
fill="clear"
|
fill="clear"
|
||||||
(click)="$event.stopPropagation(); performRating.next(true)"
|
(click)="$event.stopPropagation(); performRating.next(true)"
|
||||||
[disabled]="wasAlreadyRated | async"
|
[disabled]="wasAlreadyRated | async"
|
||||||
>
|
>
|
||||||
<ion-icon slot="icon-only" color="medium" name="thumbs_up_down"></ion-icon>
|
<ion-icon slot="icon-only" color="medium" name="thumbs_up_down"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
|
}
|
||||||
|
|
||||||
<div
|
@if ((performRating | async) && (wasAlreadyRated | async) !== true) {
|
||||||
class="rating-stars"
|
<div class="rating-stars" [@rating]="(userRating | async) === undefined ? 'abandoned' : 'rated'">
|
||||||
*ngIf="(performRating | async) && (wasAlreadyRated | async) !== true"
|
@for (i of [5, 4, 3, 2, 1]; track i) {
|
||||||
[@rating]="(userRating | async) === undefined ? 'abandoned' : 'rated'"
|
<ion-icon
|
||||||
>
|
[class.rated-value]="(userRating | async) === i"
|
||||||
<ion-icon
|
(click)="$event.stopPropagation(); userRating.next(i)"
|
||||||
[class.rated-value]="(userRating | async) === i"
|
slot="icon-only"
|
||||||
*ngFor="let i of [5, 4, 3, 2, 1]"
|
size="32"
|
||||||
(click)="$event.stopPropagation(); userRating.next(i)"
|
color="medium"
|
||||||
slot="icon-only"
|
name="grade"
|
||||||
size="32"
|
></ion-icon>
|
||||||
color="medium"
|
}
|
||||||
name="grade"
|
<label class="thank-you">{{ 'ratings.thank_you' | translate }}</label>
|
||||||
></ion-icon>
|
</div>
|
||||||
<label class="thank-you">{{ 'ratings.thank_you' | translate }}</label>
|
}
|
||||||
</div>
|
|
||||||
|
|||||||
Reference in New Issue
Block a user