mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-21 17:12:43 +00:00
feat: dashboard search rework
This commit is contained in:
@@ -168,25 +168,13 @@ describe('dashboard', async function () {
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
describe('search section', function () {
|
describe('search section', function () {
|
||||||
it('should lead to the search when hitting enter', function () {
|
it('should go to search', function () {
|
||||||
cy.visit('/overview');
|
cy.visit('/overview');
|
||||||
|
|
||||||
cy.get('stapps-search-section')
|
cy.get('ion-searchbar').click({scrollBehavior: 'center'});
|
||||||
.find('.searchbar')
|
cy.url().should('eq', Cypress.config().baseUrl + '/search');
|
||||||
.type('test', {scrollBehavior: false})
|
|
||||||
.type('{enter}', {scrollBehavior: false});
|
|
||||||
cy.url().should('eq', Cypress.config().baseUrl + '/search?query=test');
|
|
||||||
cy.get('ion-searchbar').should('have.value', 'test');
|
|
||||||
|
|
||||||
cy.get('stapps-data-list-item').should('have.length.greaterThan', 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should go to search when clicking the icon', function () {
|
|
||||||
cy.visit('/overview');
|
|
||||||
|
|
||||||
cy.get('stapps-search-section').find('ion-icon[name=search]').click({force: true});
|
|
||||||
cy.url().should('eq', Cypress.config().baseUrl + '/search?query=');
|
|
||||||
cy.get('ion-searchbar').should('not.have.value');
|
cy.get('ion-searchbar').should('not.have.value');
|
||||||
|
cy.get('ion-searchbar input.searchbar-input').should('have.focus');
|
||||||
|
|
||||||
cy.get('stapps-data-list-item').should('have.length', 0);
|
cy.get('stapps-data-list-item').should('have.length', 0);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ion-content fullscreen="true" #ionContent>
|
<ion-content fullscreen="true" #ionContent>
|
||||||
<stapps-search-section #search (focusin)="onSearchBarFocus($event)"></stapps-search-section>
|
<stapps-search-section></stapps-search-section>
|
||||||
<stapps-news-section></stapps-news-section>
|
<stapps-news-section></stapps-news-section>
|
||||||
<stapps-mensa-section></stapps-mensa-section>
|
<stapps-mensa-section></stapps-mensa-section>
|
||||||
<stapps-favorites-section></stapps-favorites-section>
|
<stapps-favorites-section></stapps-favorites-section>
|
||||||
|
|||||||
@@ -43,8 +43,6 @@ export class DashboardComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
@ViewChild('schedule', {read: ElementRef}) scheduleRef: ElementRef;
|
@ViewChild('schedule', {read: ElementRef}) scheduleRef: ElementRef;
|
||||||
|
|
||||||
@ViewChild('search', {read: ElementRef}) searchRef: ElementRef;
|
|
||||||
|
|
||||||
@ViewChild('ionContent') ionContentRef: IonContent;
|
@ViewChild('ionContent') ionContentRef: IonContent;
|
||||||
|
|
||||||
collapseAnimation: DashboardCollapse;
|
collapseAnimation: DashboardCollapse;
|
||||||
@@ -145,8 +143,4 @@ export class DashboardComponent implements OnInit, OnDestroy {
|
|||||||
this._eventUuidSubscription.unsubscribe();
|
this._eventUuidSubscription.unsubscribe();
|
||||||
this.collapseAnimation.destroy();
|
this.collapseAnimation.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
async onSearchBarFocus(_event: Event) {
|
|
||||||
this.ionContentRef.scrollToTop(100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ import {DataModule} from '../data/data.module';
|
|||||||
import {SettingsProvider} from '../settings/settings.provider';
|
import {SettingsProvider} from '../settings/settings.provider';
|
||||||
import {DashboardComponent} from './dashboard.component';
|
import {DashboardComponent} from './dashboard.component';
|
||||||
import {EditModalComponent} from './edit-modal/edit-modal.component';
|
import {EditModalComponent} from './edit-modal/edit-modal.component';
|
||||||
import {SectionComponent} from './section/section.component';
|
|
||||||
import {NavigationSectionComponent} from './sections/navigation-section/navigation-section.component';
|
|
||||||
import {SearchSectionComponent} from './sections/search-section/search-section.component';
|
import {SearchSectionComponent} from './sections/search-section/search-section.component';
|
||||||
import {NewsSectionComponent} from './sections/news-section/news-section.component';
|
import {NewsSectionComponent} from './sections/news-section/news-section.component';
|
||||||
import {MensaSectionComponent} from './sections/mensa-section/mensa-section.component';
|
import {MensaSectionComponent} from './sections/mensa-section/mensa-section.component';
|
||||||
@@ -48,9 +46,7 @@ const catalogRoutes: Routes = [
|
|||||||
*/
|
*/
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
SectionComponent,
|
|
||||||
EditModalComponent,
|
EditModalComponent,
|
||||||
NavigationSectionComponent,
|
|
||||||
SearchSectionComponent,
|
SearchSectionComponent,
|
||||||
NewsSectionComponent,
|
NewsSectionComponent,
|
||||||
MensaSectionComponent,
|
MensaSectionComponent,
|
||||||
|
|||||||
@@ -13,11 +13,10 @@
|
|||||||
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<stapps-section
|
<stapps-section [title]="'dashboard.favorites.title' | translate">
|
||||||
[title]="'dashboard.favorites.title' | translate"
|
<ion-button slot="button-end" fill="clear" color="medium" [routerLink]="['/favorites']">
|
||||||
[isEditable]="true"
|
<ion-icon slot="icon-only" name="search" size="24"></ion-icon>
|
||||||
(onEdit)="onSectionEdit()"
|
</ion-button>
|
||||||
>
|
|
||||||
<simple-swiper *ngIf="(items | async)?.length; else noItems">
|
<simple-swiper *ngIf="(items | async)?.length; else noItems">
|
||||||
<stapps-data-list-item
|
<stapps-data-list-item
|
||||||
*ngFor="let item of items | async"
|
*ngFor="let item of items | async"
|
||||||
@@ -31,7 +30,7 @@
|
|||||||
<ion-item class="nothing-selected" lines="none">
|
<ion-item class="nothing-selected" lines="none">
|
||||||
<ion-label class="ion-text-wrap">
|
<ion-label class="ion-text-wrap">
|
||||||
{{ 'dashboard.favorites.no_favorite_prefix' | translate }}
|
{{ 'dashboard.favorites.no_favorite_prefix' | translate }}
|
||||||
<a (click)="onSectionEdit()">{{ 'dashboard.favorites.no_favorite_link' | translate }}</a>
|
<a [routerLink]="'/search'">{{ 'dashboard.favorites.no_favorite_link' | translate }}</a>
|
||||||
{{ 'dashboard.favorites.no_favorite_suffix' | translate }}
|
{{ 'dashboard.favorites.no_favorite_suffix' | translate }}
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|||||||
@@ -127,11 +127,4 @@ export class FavoritesSectionComponent extends SearchPageComponent implements On
|
|||||||
notifySelect(item: SCThings) {
|
notifySelect(item: SCThings) {
|
||||||
this.dataRoutingService.emitChildEvent(item);
|
this.dataRoutingService.emitChildEvent(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Action when user clicked edit to this section
|
|
||||||
*/
|
|
||||||
onSectionEdit() {
|
|
||||||
void this.router.navigate(['/search']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,24 +16,17 @@
|
|||||||
<ng-container *ngIf="items | async as items">
|
<ng-container *ngIf="items | async as items">
|
||||||
<ng-container *ngIf="items.length !== 0; else nothingSelected">
|
<ng-container *ngIf="items.length !== 0; else nothingSelected">
|
||||||
<ng-container *ngFor="let item of items">
|
<ng-container *ngFor="let item of items">
|
||||||
<stapps-section
|
<stapps-section @fade [item]="item" [title]="'name' | thingTranslate: item">
|
||||||
@fade
|
<ion-button slot="button-end" fill="clear" color="medium" (click)="favoritesService.delete(item)">
|
||||||
[item]="item"
|
<ion-icon slot="icon-only" name="delete" size="24"></ion-icon>
|
||||||
[title]="'name' | thingTranslate: item"
|
</ion-button>
|
||||||
[isEditable]="true"
|
|
||||||
(onEdit)="onSectionEdit()"
|
|
||||||
>
|
|
||||||
<stapps-opening-hours slot="subtitle" [openingHours]="item.openingHours"></stapps-opening-hours>
|
<stapps-opening-hours slot="subtitle" [openingHours]="item.openingHours"></stapps-opening-hours>
|
||||||
<stapps-mensa-section-content [item]="item"></stapps-mensa-section-content>
|
<stapps-mensa-section-content [item]="item"></stapps-mensa-section-content>
|
||||||
</stapps-section>
|
</stapps-section>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-template #nothingSelected>
|
<ng-template #nothingSelected>
|
||||||
<stapps-section
|
<stapps-section [title]="'dashboard.canteens.title' | translate">
|
||||||
[title]="'dashboard.canteens.title' | translate"
|
|
||||||
[isEditable]="true"
|
|
||||||
(onEdit)="onSectionEdit()"
|
|
||||||
>
|
|
||||||
<ion-item class="nothing-selected" lines="none">
|
<ion-item class="nothing-selected" lines="none">
|
||||||
<ion-label class="ion-text-wrap">
|
<ion-label class="ion-text-wrap">
|
||||||
{{ 'dashboard.canteens.no_favorite_prefix' | translate }}
|
{{ 'dashboard.canteens.no_favorite_prefix' | translate }}
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 StApps
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface MenuItemInterface {
|
|
||||||
icon: string;
|
|
||||||
label: string;
|
|
||||||
link: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum MenuItemKey {
|
|
||||||
CATALOG = 'catalog',
|
|
||||||
CANTEEN = 'canteen',
|
|
||||||
MAP = 'map',
|
|
||||||
SETTINGS = 'settings',
|
|
||||||
SEARCH = 'search',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type MenuItemConfig = Record<MenuItemKey, boolean>;
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 StApps
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {MenuItemInterface, MenuItemKey} from './menu-item.interface';
|
|
||||||
import {SCIcon} from '../../../../util/ion-icon/icon';
|
|
||||||
|
|
||||||
export const MENU_ITEMS: Record<MenuItemKey, MenuItemInterface> = {
|
|
||||||
catalog: {
|
|
||||||
icon: SCIcon`book`,
|
|
||||||
label: 'dashboard.navigation.item.catalog',
|
|
||||||
link: '/catalog',
|
|
||||||
},
|
|
||||||
canteen: {
|
|
||||||
icon: SCIcon`local_cafe`,
|
|
||||||
label: 'dashboard.navigation.item.canteen',
|
|
||||||
link: '/canteen',
|
|
||||||
},
|
|
||||||
map: {
|
|
||||||
icon: SCIcon`map`,
|
|
||||||
label: 'dashboard.navigation.item.map',
|
|
||||||
link: '/map',
|
|
||||||
},
|
|
||||||
settings: {
|
|
||||||
icon: SCIcon`settings`,
|
|
||||||
label: 'dashboard.navigation.item.settings',
|
|
||||||
link: '/settings',
|
|
||||||
},
|
|
||||||
search: {
|
|
||||||
icon: SCIcon`search`,
|
|
||||||
label: 'dashboard.navigation.item.search',
|
|
||||||
link: '/search',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DEFAULT_ACTIVE_MENU_ITEMS: MenuItemKey[] = [
|
|
||||||
MenuItemKey.CATALOG,
|
|
||||||
MenuItemKey.CANTEEN,
|
|
||||||
MenuItemKey.MAP,
|
|
||||||
MenuItemKey.SETTINGS,
|
|
||||||
MenuItemKey.SEARCH,
|
|
||||||
];
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<!--
|
|
||||||
~ Copyright (C) 2022 StApps
|
|
||||||
~ This program is free software: you can redistribute it and/or modify it
|
|
||||||
~ under the terms of the GNU General Public License as published by the Free
|
|
||||||
~ Software Foundation, version 3.
|
|
||||||
~
|
|
||||||
~ This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
~ more details.
|
|
||||||
~
|
|
||||||
~ You should have received a copy of the GNU General Public License along with
|
|
||||||
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<stapps-section
|
|
||||||
[title]="'dashboard.navigation.title' | translate"
|
|
||||||
[isEditable]="true"
|
|
||||||
[isSectionExtended]="true"
|
|
||||||
(onEdit)="onSectionEdit()"
|
|
||||||
>
|
|
||||||
<swiper [config]="sliderOptions" slidesPerView="auto" class="navigation-swiper card-swiper">
|
|
||||||
<ng-template swiperSlide *ngFor="let item of activeMenuItems">
|
|
||||||
<a [routerLink]="menuItems[item].link" class="card">
|
|
||||||
<ion-icon size="40" [name]="menuItems[item].icon"></ion-icon>
|
|
||||||
<ion-label>{{ menuItems[item].label | translate }}</ion-label>
|
|
||||||
</a>
|
|
||||||
</ng-template>
|
|
||||||
</swiper>
|
|
||||||
</stapps-section>
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Copyright (C) 2022 StApps
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.navigation-swiper.swiper {
|
|
||||||
.swiper-slide {
|
|
||||||
a {
|
|
||||||
font-family: var(--ion-font-family);
|
|
||||||
font-size: var(--font-size-xs);
|
|
||||||
font-weight: var(--font-weight-semi-bold);
|
|
||||||
text-align: center;
|
|
||||||
padding: var(--spacing-md) var(--spacing-lg);
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
ion-icon {
|
|
||||||
display: block;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 StApps
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import {Component, OnInit, ViewEncapsulation} from '@angular/core';
|
|
||||||
import {ModalController} from '@ionic/angular';
|
|
||||||
import {EditModalComponent} from '../../edit-modal/edit-modal.component';
|
|
||||||
import {DEFAULT_ACTIVE_MENU_ITEMS, MENU_ITEMS} from './menu-items.config';
|
|
||||||
import {MenuItemKey} from './menu-item.interface';
|
|
||||||
import {EditModalItem, EditModalTypeEnum} from '../../edit-modal/edit-modal-type.enum';
|
|
||||||
import {StorageProvider} from '../../../storage/storage.provider';
|
|
||||||
import {TranslatePipe} from '@ngx-translate/core';
|
|
||||||
|
|
||||||
const DASHBOARD_NAVIGATION = 'stapps.dashboard.navigation';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows a horizontal list of navigation items
|
|
||||||
*/
|
|
||||||
@Component({
|
|
||||||
selector: 'stapps-navigation-section',
|
|
||||||
templateUrl: 'navigation-section.component.html',
|
|
||||||
styleUrls: ['navigation-section.component.scss'],
|
|
||||||
encapsulation: ViewEncapsulation.None,
|
|
||||||
})
|
|
||||||
export class NavigationSectionComponent implements OnInit {
|
|
||||||
/**
|
|
||||||
* Slider options
|
|
||||||
*/
|
|
||||||
sliderOptions = {
|
|
||||||
spaceBetween: 12,
|
|
||||||
freeMode: {
|
|
||||||
enabled: true,
|
|
||||||
sticky: true,
|
|
||||||
},
|
|
||||||
width: 120,
|
|
||||||
};
|
|
||||||
|
|
||||||
menuItems = MENU_ITEMS;
|
|
||||||
|
|
||||||
activeMenuItems: MenuItemKey[] = DEFAULT_ACTIVE_MENU_ITEMS;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public modalController: ModalController,
|
|
||||||
private storageProvider: StorageProvider,
|
|
||||||
private translatePipe: TranslatePipe,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
void this.getItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get current order of items
|
|
||||||
*/
|
|
||||||
async getItems() {
|
|
||||||
if (await this.storageProvider.has(DASHBOARD_NAVIGATION)) {
|
|
||||||
const storedMenuItems: string = await this.storageProvider.get(DASHBOARD_NAVIGATION);
|
|
||||||
if (storedMenuItems) {
|
|
||||||
const parsedMenuItems = JSON.parse(storedMenuItems);
|
|
||||||
if (Array.isArray(parsedMenuItems) && parsedMenuItems.every(it => typeof it === 'string')) {
|
|
||||||
this.activeMenuItems = parsedMenuItems;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save updated order of items
|
|
||||||
*/
|
|
||||||
updateActiveItems(items: MenuItemKey[]) {
|
|
||||||
this.activeMenuItems = items;
|
|
||||||
void this.storageProvider.put<string>(DASHBOARD_NAVIGATION, JSON.stringify(this.activeMenuItems));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Action when user clicked edit to this section
|
|
||||||
*/
|
|
||||||
async onSectionEdit() {
|
|
||||||
const modal = await this.modalController.create({
|
|
||||||
component: EditModalComponent,
|
|
||||||
canDismiss: true,
|
|
||||||
componentProps: {
|
|
||||||
items: Object.entries(this.menuItems).map(([id, item]) => ({
|
|
||||||
id,
|
|
||||||
active: this.activeMenuItems.includes(id as MenuItemKey),
|
|
||||||
labelLocalized: this.translatePipe.transform(item.label),
|
|
||||||
})),
|
|
||||||
type: EditModalTypeEnum.CHECKBOXES,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await modal.present();
|
|
||||||
|
|
||||||
modal.onDidDismiss().then(result => {
|
|
||||||
if (result.data?.items) {
|
|
||||||
this.updateActiveItems(
|
|
||||||
result.data.items.filter((it: EditModalItem) => it.active).map((it: EditModalItem) => it.id),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,14 +13,11 @@
|
|||||||
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<stapps-section
|
<stapps-section [title]="'dashboard.news.title' | translate">
|
||||||
[title]="'dashboard.news.title' | translate"
|
<ion-button size="small" slot="button-end" fill="clear" color="medium" [routerLink]="['/news']">
|
||||||
[isEditable]="false"
|
<ion-icon slot="icon-only" name="read_more"></ion-icon>
|
||||||
[customIcon]="'read_more'"
|
</ion-button>
|
||||||
class="is-editable"
|
<simple-swiper class="news-swiper card-swiper" *ngIf="news | async as news" @fade>
|
||||||
(onEdit)="onMoreNewsClicked()"
|
|
||||||
>
|
|
||||||
<simple-swiper class="news-swiper card-swiper" *ngIf="news" @fade>
|
|
||||||
<stapps-news-item *ngFor="let newsItem of news" [item]="newsItem"> </stapps-news-item>
|
<stapps-news-item *ngFor="let newsItem of news" [item]="newsItem"> </stapps-news-item>
|
||||||
<ion-item [routerLink]="['/news']" class="more-news" lines="none">
|
<ion-item [routerLink]="['/news']" class="more-news" lines="none">
|
||||||
<ion-label>{{ 'dashboard.news.moreNews' | translate | titlecase }}</ion-label>
|
<ion-label>{{ 'dashboard.news.moreNews' | translate | titlecase }}</ion-label>
|
||||||
|
|||||||
@@ -12,15 +12,11 @@
|
|||||||
* 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, OnInit} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
import {Router} from '@angular/router';
|
|
||||||
import {NewsPageComponent} from '../../../news/page/news-page.component';
|
|
||||||
import {NewsProvider} from '../../../news/news.provider';
|
import {NewsProvider} from '../../../news/news.provider';
|
||||||
import {SettingsProvider} from '../../../settings/settings.provider';
|
import {SCMessage} from '@openstapps/core';
|
||||||
import {newsFilterSettingsFieldsMapping, NewsFilterSettingsNames} from '../../../news/news-filter-settings';
|
|
||||||
import {DataProvider} from '../../../data/data.provider';
|
|
||||||
import {SCSearchValueFilter} from '@openstapps/core';
|
|
||||||
import {animate, style, transition, trigger} from '@angular/animations';
|
import {animate, style, transition, trigger} from '@angular/animations';
|
||||||
|
import {Router} from '@angular/router';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a section with news
|
* Shows a section with news
|
||||||
@@ -38,40 +34,12 @@ import {animate, style, transition, trigger} from '@angular/animations';
|
|||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class NewsSectionComponent extends NewsPageComponent implements OnInit {
|
export class NewsSectionComponent {
|
||||||
pageSize = 5;
|
news: Promise<SCMessage[]>;
|
||||||
|
|
||||||
/**
|
constructor(readonly newsProvider: NewsProvider, readonly router: Router) {
|
||||||
* A map of the filters where the keys are settings names
|
this.news = this.newsProvider
|
||||||
*/
|
.getCurrentFilters()
|
||||||
filtersMap = new Map<NewsFilterSettingsNames, SCSearchValueFilter>();
|
.then(filters => this.newsProvider.getList(5, 0, filters));
|
||||||
|
|
||||||
constructor(newsProvider: NewsProvider, settingsProvider: SettingsProvider, private router: Router) {
|
|
||||||
super(newsProvider, settingsProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
async ngOnInit() {
|
|
||||||
await super.ngOnInit();
|
|
||||||
for (const setting of this.settings) {
|
|
||||||
this.filtersMap.set(
|
|
||||||
setting.name as NewsFilterSettingsNames,
|
|
||||||
DataProvider.createValueFilter(
|
|
||||||
newsFilterSettingsFieldsMapping[setting.name as NewsFilterSettingsNames],
|
|
||||||
setting.value as string,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.filters = [...this.filtersMap.values()];
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.fetchNews();
|
|
||||||
} catch {
|
|
||||||
this.news = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMoreNewsClicked() {
|
|
||||||
void this.router.navigate(['/news']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 StApps
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {AnimationController} from '@ionic/angular';
|
||||||
|
import {AnimationOptions} from '@ionic/angular/providers/nav-controller';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function homePageSearchTransition(animationController: AnimationController) {
|
||||||
|
let scheduleTransform: WebKitCSSMatrix;
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
return (_baseElement: HTMLElement, options: AnimationOptions | any) => {
|
||||||
|
const back = options.direction === 'back';
|
||||||
|
const searchPage = back ? options.leavingEl : options.enteringEl;
|
||||||
|
const homePage = back ? options.enteringEl : options.leavingEl;
|
||||||
|
const rootTransition = animationController
|
||||||
|
.create()
|
||||||
|
.duration(options.duration ?? 350)
|
||||||
|
.easing(
|
||||||
|
// quintic in / out
|
||||||
|
back ? 'cubic-bezier(0.64, 0, 0.78, 0)' : 'cubic-bezier(0.22, 1, 0.36, 1)',
|
||||||
|
);
|
||||||
|
|
||||||
|
const homePageContent = homePage.querySelector('ion-content').shadowRoot.querySelector('.inner-scroll');
|
||||||
|
const leavingSearchbar = homePage.querySelector('ion-searchbar');
|
||||||
|
const enteringSearchbar = searchPage.querySelector('ion-searchbar');
|
||||||
|
const searchPageHeader = searchPage.querySelector('ion-header');
|
||||||
|
const homePageSchedule = homePage.querySelector('.schedule');
|
||||||
|
|
||||||
|
if (!back) {
|
||||||
|
scheduleTransform = new WebKitCSSMatrix(window.getComputedStyle(homePageSchedule).transform);
|
||||||
|
}
|
||||||
|
const enteringSearchbarTop = enteringSearchbar.getBoundingClientRect().top;
|
||||||
|
const leavingSearchbarTop = leavingSearchbar.getBoundingClientRect().top;
|
||||||
|
const searchbarDelta = leavingSearchbarTop - enteringSearchbarTop;
|
||||||
|
const searchHeaderHeight = searchPageHeader.getBoundingClientRect().bottom;
|
||||||
|
const homeHeaderHeight = homePageSchedule.getBoundingClientRect().bottom;
|
||||||
|
const homePageSlideAmount = -50;
|
||||||
|
const headerDelta = homeHeaderHeight - searchHeaderHeight;
|
||||||
|
|
||||||
|
const enterTransition = animationController.create().fromTo('opacity', '0', '1').addElement(searchPage);
|
||||||
|
const exitTransition = animationController.create().fromTo('opacity', '1', '1').addElement(homePage);
|
||||||
|
|
||||||
|
const homePageSlide = animationController
|
||||||
|
.create()
|
||||||
|
.fromTo('transform', `translateY(0px)`, `translateY(${homePageSlideAmount}px)`)
|
||||||
|
.addElement(homePageContent);
|
||||||
|
|
||||||
|
const toolbarExit = animationController
|
||||||
|
.create()
|
||||||
|
.fromTo(
|
||||||
|
'transform',
|
||||||
|
scheduleTransform.toString(),
|
||||||
|
scheduleTransform.translate(undefined, -headerDelta).toString(),
|
||||||
|
)
|
||||||
|
.addElement(homePageSchedule);
|
||||||
|
const headerSlide = animationController
|
||||||
|
.create()
|
||||||
|
.fromTo('transform', `translateY(${headerDelta}px)`, 'translateY(0px)')
|
||||||
|
.addElement(searchPageHeader);
|
||||||
|
|
||||||
|
const searchbarSlideIn = animationController
|
||||||
|
.create()
|
||||||
|
.fromTo('transform', `translateY(${searchbarDelta - headerDelta}px)`, 'translateY(0px)')
|
||||||
|
.beforeStyles({
|
||||||
|
'z-index': 1000,
|
||||||
|
})
|
||||||
|
.afterClearStyles(['z-index'])
|
||||||
|
.addElement(searchPage.querySelector('.toolbar-searchbar'));
|
||||||
|
const searchbarSlideOut = animationController
|
||||||
|
.create()
|
||||||
|
.fromTo('transform', 'translateY(0px)', `translateY(-${searchbarDelta + homePageSlideAmount}px)`)
|
||||||
|
.addElement(homePage.querySelector('stapps-search-section > stapps-section'));
|
||||||
|
|
||||||
|
rootTransition
|
||||||
|
.addAnimation([
|
||||||
|
enterTransition,
|
||||||
|
exitTransition,
|
||||||
|
toolbarExit,
|
||||||
|
homePageSlide,
|
||||||
|
headerSlide,
|
||||||
|
searchbarSlideIn,
|
||||||
|
searchbarSlideOut,
|
||||||
|
])
|
||||||
|
.direction(back ? 'reverse' : 'normal');
|
||||||
|
return rootTransition;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
~ Copyright (C) 2022 StApps
|
~ Copyright (C) 2023 StApps
|
||||||
~ This program is free software: you can redistribute it and/or modify it
|
~ This program is free software: you can redistribute it and/or modify it
|
||||||
~ under the terms of the GNU General Public License as published by the Free
|
~ under the terms of the GNU General Public License as published by the Free
|
||||||
~ Software Foundation, version 3.
|
~ Software Foundation, version 3.
|
||||||
@@ -13,17 +13,12 @@
|
|||||||
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<stapps-section title="{{ 'dashboard.navigation.item.search' | translate }}" [isEditable]="false">
|
<stapps-section title="{{ 'dashboard.navigation.item.search' | translate }}">
|
||||||
<div class="searchbar">
|
<ion-searchbar
|
||||||
<ion-input
|
[routerLink]="'/search'"
|
||||||
type="search"
|
[routerAnimation]="routeTransition"
|
||||||
enterkeyhint="search"
|
class="stapps-searchbar ion-activatable ripple-parent"
|
||||||
placeholder="{{ 'search.search_bar.placeholder' | translate }}"
|
>
|
||||||
(submit)="onSubmitSearch()"
|
<ion-ripple-effect></ion-ripple-effect>
|
||||||
(keyup.enter)="onSubmitSearch()"
|
</ion-searchbar>
|
||||||
(search)="onSubmitSearch()"
|
|
||||||
[(ngModel)]="searchTerm"
|
|
||||||
></ion-input>
|
|
||||||
<ion-icon size="35" weight="300" name="search" (click)="onSubmitSearch()" class="clickable"></ion-icon>
|
|
||||||
</div>
|
|
||||||
</stapps-section>
|
</stapps-section>
|
||||||
|
|||||||
@@ -1,36 +1,43 @@
|
|||||||
/*!
|
/*!
|
||||||
* Copyright (C) 2022 StApps
|
* Copyright (C) 2023 StApps
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
* Software Foundation, version 3.
|
* Software Foundation, version 3.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
* more details.
|
* more details.
|
||||||
*
|
*
|
||||||
* 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/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.searchbar {
|
ion-ripple-effect {
|
||||||
position: relative;
|
z-index: 1000;
|
||||||
max-width: 700px;
|
border-radius: var(--spacing-sm);
|
||||||
|
}
|
||||||
|
|
||||||
ion-input {
|
ion-searchbar {
|
||||||
background: var(--ion-color-field-bg);
|
cursor: text;
|
||||||
border-radius: var(--border-radius-default);
|
}
|
||||||
--padding-start: var(--spacing-md);
|
|
||||||
--padding-end: var(--spacing-md);
|
ion-searchbar ::ng-deep .searchbar-input-container {
|
||||||
--padding-top: var(--spacing-md);
|
pointer-events: none;
|
||||||
--padding-bottom: var(--spacing-md);
|
}
|
||||||
box-shadow: var(--shadow-default);
|
|
||||||
|
ion-searchbar.ios {
|
||||||
|
ion-ripple-effect {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
ion-icon {
|
|
||||||
position: absolute;
|
transition: opacity 150ms ease;
|
||||||
top: 50%;
|
&:active {
|
||||||
right: var(--spacing-md);
|
opacity: 0.6;
|
||||||
transform: translateY(-50%);
|
}
|
||||||
z-index: 2;
|
@media (hover: hover) {
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 StApps
|
* Copyright (C) 2023 StApps
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
* Software Foundation, version 3.
|
* Software Foundation, version 3.
|
||||||
@@ -16,6 +16,8 @@ import {Component} from '@angular/core';
|
|||||||
import {Router} from '@angular/router';
|
import {Router} from '@angular/router';
|
||||||
import {Capacitor} from '@capacitor/core';
|
import {Capacitor} from '@capacitor/core';
|
||||||
import {Keyboard} from '@capacitor/keyboard';
|
import {Keyboard} from '@capacitor/keyboard';
|
||||||
|
import {AnimationBuilder, AnimationController} from '@ionic/angular';
|
||||||
|
import {homePageSearchTransition} from './search-route-transition';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a search input field
|
* Shows a search input field
|
||||||
@@ -28,7 +30,11 @@ import {Keyboard} from '@capacitor/keyboard';
|
|||||||
export class SearchSectionComponent {
|
export class SearchSectionComponent {
|
||||||
searchTerm = '';
|
searchTerm = '';
|
||||||
|
|
||||||
constructor(private router: Router) {}
|
routeTransition: AnimationBuilder;
|
||||||
|
|
||||||
|
constructor(private router: Router, private animationController: AnimationController) {
|
||||||
|
this.routeTransition = homePageSearchTransition(this.animationController);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User submits search
|
* User submits search
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
~ Copyright (C) 2022 StApps
|
~ Copyright (C) 2023 StApps
|
||||||
~ This program is free software: you can redistribute it and/or modify it
|
~ This program is free software: you can redistribute it and/or modify it
|
||||||
~ under the terms of the GNU General Public License as published by the Free
|
~ under the terms of the GNU General Public License as published by the Free
|
||||||
~ Software Foundation, version 3.
|
~ Software Foundation, version 3.
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
type="search"
|
type="search"
|
||||||
enterkeyhint="search"
|
enterkeyhint="search"
|
||||||
class="filterable"
|
class="filterable"
|
||||||
|
autofocus
|
||||||
>
|
>
|
||||||
<ion-menu-button menu="context" auto-hide="false">
|
<ion-menu-button menu="context" auto-hide="false">
|
||||||
<ion-icon name="tune"></ion-icon>
|
<ion-icon name="tune"></ion-icon>
|
||||||
|
|||||||
@@ -1,3 +1,18 @@
|
|||||||
|
/*!
|
||||||
|
* Copyright (C) 2023 StApps
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -35,3 +50,11 @@ ion-content {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ion-header {
|
||||||
|
background: var(--ion-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
ion-toolbar {
|
||||||
|
--ion-color-base: none !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ ion-card-title {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-size: var(--font-size-xl);
|
font-size: var(--font-size-xl);
|
||||||
--color: var(--ion-color-dark-contrast);
|
--color: var(--ion-color-dark-contrast);
|
||||||
|
max-lines: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
ion-card-subtitle {
|
ion-card-subtitle {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 StApps
|
* Copyright (C) 2023 StApps
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
* Software Foundation, version 3.
|
* Software Foundation, version 3.
|
||||||
@@ -19,8 +19,17 @@ import {
|
|||||||
SCSearchBooleanFilter,
|
SCSearchBooleanFilter,
|
||||||
SCSearchFilter,
|
SCSearchFilter,
|
||||||
SCSearchQuery,
|
SCSearchQuery,
|
||||||
|
SCSearchValueFilter,
|
||||||
|
SCSetting,
|
||||||
} from '@openstapps/core';
|
} from '@openstapps/core';
|
||||||
import {DataProvider} from '../data/data.provider';
|
import {DataProvider} from '../data/data.provider';
|
||||||
|
import {
|
||||||
|
newsFilterSettingsCategory,
|
||||||
|
newsFilterSettingsFieldsMapping,
|
||||||
|
NewsFilterSettingsNames,
|
||||||
|
} from './news-filter-settings';
|
||||||
|
import {SettingsProvider} from '../settings/settings.provider';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for providing news messages
|
* Service for providing news messages
|
||||||
*/
|
*/
|
||||||
@@ -28,7 +37,31 @@ import {DataProvider} from '../data/data.provider';
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class NewsProvider {
|
export class NewsProvider {
|
||||||
constructor(private dataProvider: DataProvider) {}
|
constructor(private dataProvider: DataProvider, private settingsProvider: SettingsProvider) {}
|
||||||
|
|
||||||
|
async getCurrentSettings(): Promise<SCSetting[]> {
|
||||||
|
const settings: SCSetting[] = [];
|
||||||
|
for (const settingName of Object.keys(newsFilterSettingsFieldsMapping) as NewsFilterSettingsNames[]) {
|
||||||
|
settings.push(await this.settingsProvider.getSetting(newsFilterSettingsCategory, settingName));
|
||||||
|
}
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCurrentFilters(): Promise<SCSearchFilter[]> {
|
||||||
|
const settings = await this.getCurrentSettings();
|
||||||
|
const filtersMap = new Map<NewsFilterSettingsNames, SCSearchValueFilter>();
|
||||||
|
for (const setting of settings) {
|
||||||
|
filtersMap.set(
|
||||||
|
setting.name as NewsFilterSettingsNames,
|
||||||
|
DataProvider.createValueFilter(
|
||||||
|
newsFilterSettingsFieldsMapping[setting.name as NewsFilterSettingsNames],
|
||||||
|
setting.value as string,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...filtersMap.values()];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get news messages
|
* Get news messages
|
||||||
|
|||||||
@@ -15,12 +15,6 @@
|
|||||||
import {Component, OnInit} from '@angular/core';
|
import {Component, OnInit} from '@angular/core';
|
||||||
import {IonRefresher} from '@ionic/angular';
|
import {IonRefresher} from '@ionic/angular';
|
||||||
import {SCMessage, SCSearchFilter, SCSearchValueFilter, SCSetting} from '@openstapps/core';
|
import {SCMessage, SCSearchFilter, SCSearchValueFilter, SCSetting} from '@openstapps/core';
|
||||||
import {SettingsProvider} from '../../settings/settings.provider';
|
|
||||||
import {
|
|
||||||
newsFilterSettingsCategory,
|
|
||||||
newsFilterSettingsFieldsMapping,
|
|
||||||
NewsFilterSettingsNames,
|
|
||||||
} from '../news-filter-settings';
|
|
||||||
import {NewsProvider} from '../news.provider';
|
import {NewsProvider} from '../news.provider';
|
||||||
import {SplashScreen} from '@capacitor/splash-screen';
|
import {SplashScreen} from '@capacitor/splash-screen';
|
||||||
|
|
||||||
@@ -68,7 +62,7 @@ export class NewsPageComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
filters: SCSearchFilter[];
|
filters: SCSearchFilter[];
|
||||||
|
|
||||||
constructor(private newsProvider: NewsProvider, private settingsProvider: SettingsProvider) {}
|
constructor(private newsProvider: NewsProvider) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch news from the backend
|
* Fetch news from the backend
|
||||||
@@ -109,18 +103,7 @@ export class NewsPageComponent implements OnInit {
|
|||||||
* Initialize the local variables on component initialization
|
* Initialize the local variables on component initialization
|
||||||
*/
|
*/
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
// Helper method to provide the relevant settings
|
this.settings = await this.newsProvider.getCurrentSettings();
|
||||||
const getNewsSettings = async (settingNames: NewsFilterSettingsNames[]) => {
|
|
||||||
const settings = [];
|
|
||||||
for (const settingName of settingNames) {
|
|
||||||
settings.push(await this.settingsProvider.getSetting(newsFilterSettingsCategory, settingName));
|
|
||||||
}
|
|
||||||
return settings;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.settings = await getNewsSettings(
|
|
||||||
Object.keys(newsFilterSettingsFieldsMapping) as NewsFilterSettingsNames[],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -13,58 +13,26 @@
|
|||||||
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<ion-label class="section-headline">
|
<stapps-section [title]="'name' | translateSimple: item">
|
||||||
<!-- TODO: move this to thing translate -->
|
<ion-button slot="button-end" *ngIf="item.authProvider" fill="clear" color="dark" (click)="toggleLogIn()">
|
||||||
{{ 'name' | translateSimple: item }}
|
<ion-icon *ngIf="isLoggedIn; else loginIcon" slot="end" name="logout"></ion-icon>
|
||||||
</ion-label>
|
<ng-template #loginIcon>
|
||||||
<ion-button
|
<ion-icon slot="end" name="login"></ion-icon>
|
||||||
*ngIf="item.authProvider"
|
</ng-template>
|
||||||
fill="clear"
|
<ion-label>{{ 'profile.buttons.default.log_' + (isLoggedIn ? 'out' : 'in') | translate }}</ion-label>
|
||||||
color="dark"
|
</ion-button>
|
||||||
(click)="toggleLogIn()"
|
|
||||||
style="grid-area: login"
|
<simple-swiper>
|
||||||
>
|
<ion-item
|
||||||
<ion-icon *ngIf="isLoggedIn; else loginIcon" slot="end" name="logout"></ion-icon>
|
lines="none"
|
||||||
<ng-template #loginIcon>
|
*ngFor="let link of item.links"
|
||||||
<ion-icon slot="end" name="login"></ion-icon>
|
[routerLink]="link.link"
|
||||||
</ng-template>
|
|
||||||
<ion-label>{{ 'profile.buttons.default.log_' + (isLoggedIn ? 'out' : 'in') | translate }}</ion-label>
|
|
||||||
</ion-button>
|
|
||||||
<ion-button
|
|
||||||
[disabled]="isBeginning"
|
|
||||||
(click)="swiper.swiperRef.slidePrev()"
|
|
||||||
fill="clear"
|
|
||||||
color="dark"
|
|
||||||
class="navigation"
|
|
||||||
[class.hidden]="slidesFillScreen"
|
|
||||||
style="grid-area: prev"
|
|
||||||
><ion-icon slot="icon-only" name="chevron_left"></ion-icon
|
|
||||||
></ion-button>
|
|
||||||
<ion-button
|
|
||||||
[disabled]="isEnd"
|
|
||||||
(click)="swiper.swiperRef.slideNext()"
|
|
||||||
fill="clear"
|
|
||||||
color="dark"
|
|
||||||
class="navigation"
|
|
||||||
[class.hidden]="slidesFillScreen"
|
|
||||||
style="grid-area: next"
|
|
||||||
><ion-icon slot="icon-only" name="chevron_right"></ion-icon
|
|
||||||
></ion-button>
|
|
||||||
<swiper
|
|
||||||
#swiper
|
|
||||||
(elementSizeChange)="resizeSwiper($event, swiper.swiperRef)"
|
|
||||||
[elementSizeChangeDebounce]="100"
|
|
||||||
(toEdge)="activeIndexChange($event[0])"
|
|
||||||
(fromEdge)="activeIndexChange($event[0])"
|
|
||||||
[cssMode]="true"
|
|
||||||
[spaceBetween]="0"
|
|
||||||
[slidesPerView]="slidesPerView"
|
|
||||||
class="card-swiper"
|
|
||||||
>
|
|
||||||
<ng-template swiperSlide *ngFor="let link of item.links">
|
|
||||||
<stapps-section-link-card
|
|
||||||
[disabled]="link.needsAuth && !isLoggedIn"
|
[disabled]="link.needsAuth && !isLoggedIn"
|
||||||
[item]="link"
|
>
|
||||||
></stapps-section-link-card>
|
<div>
|
||||||
</ng-template>
|
<ion-icon [name]="link.icon" size="36" color="dark"></ion-icon>
|
||||||
</swiper>
|
<ion-label>{{ 'name' | translateSimple: link }}</ion-label>
|
||||||
|
</div>
|
||||||
|
</ion-item>
|
||||||
|
</simple-swiper>
|
||||||
|
</stapps-section>
|
||||||
|
|||||||
@@ -12,9 +12,50 @@
|
|||||||
* 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/>.
|
||||||
*/
|
*/
|
||||||
|
$width: 108px;
|
||||||
|
|
||||||
.section-headline {
|
simple-swiper {
|
||||||
padding-inline-start: var(--spacing-md);
|
container-type: inline-size;
|
||||||
|
--swiper-slide-width: #{$width};
|
||||||
|
|
||||||
|
ion-item {
|
||||||
|
@each $i in 7, 6, 5, 4, 3, 2, 1 {
|
||||||
|
$max: #{($width + 8px) * $i};
|
||||||
|
@container (inline-size < #{$max}) {
|
||||||
|
--swiper-slide-width: #{100cqi / $i};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ion-item {
|
||||||
|
height: 96px;
|
||||||
|
--border-radius: var(--border-radius-default);
|
||||||
|
--inner-padding-start: unset;
|
||||||
|
--inner-padding-end: unset;
|
||||||
|
--padding-start: unset;
|
||||||
|
--padding-end: unset;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div,
|
||||||
|
ion-label {
|
||||||
|
white-space: normal;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::part(native) {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-in-hint {
|
.log-in-hint {
|
||||||
@@ -23,47 +64,3 @@
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
background: var(--ion-color-light-tint);
|
background: var(--ion-color-light-tint);
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation::part(native) {
|
|
||||||
padding-inline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
swiper {
|
|
||||||
//noinspection CssInvalidFunction
|
|
||||||
transform: translateY(calc(-1 * var(--spacing-sm)));
|
|
||||||
}
|
|
||||||
|
|
||||||
stapps-section-link-card {
|
|
||||||
// required spacing for box shadow
|
|
||||||
margin-block: var(--spacing-sm);
|
|
||||||
}
|
|
||||||
|
|
||||||
:host {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr auto auto auto;
|
|
||||||
grid-template-rows: 42px 1fr;
|
|
||||||
grid-template-areas:
|
|
||||||
'title prev next login'
|
|
||||||
'swiper swiper swiper swiper';
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
> ion-label {
|
|
||||||
margin-block-end: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
> swiper {
|
|
||||||
grid-area: swiper;
|
|
||||||
width: 100%;
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ion-button.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (hover: none) {
|
|
||||||
ion-button.navigation {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 StApps
|
* Copyright (C) 2023 StApps
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
* Software Foundation, version 3.
|
* Software Foundation, version 3.
|
||||||
@@ -25,7 +25,6 @@ import {UtilModule} from '../../util/util.module';
|
|||||||
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
|
import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
|
||||||
import {ProfilePageSectionComponent} from './page/profile-page-section.component';
|
import {ProfilePageSectionComponent} from './page/profile-page-section.component';
|
||||||
import {ThingTranslateModule} from '../../translation/thing-translate.module';
|
import {ThingTranslateModule} from '../../translation/thing-translate.module';
|
||||||
import {SectionModule} from '../../util/section/section.module';
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
@@ -46,7 +45,6 @@ const routes: Routes = [
|
|||||||
SwiperModule,
|
SwiperModule,
|
||||||
UtilModule,
|
UtilModule,
|
||||||
ThingTranslateModule,
|
ThingTranslateModule,
|
||||||
SectionModule,
|
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class ProfilePageModule {}
|
export class ProfilePageModule {}
|
||||||
|
|||||||
39
src/app/util/searchbar-autofocus.directive.ts
Normal file
39
src/app/util/searchbar-autofocus.directive.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 StApps
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {AfterViewInit, Directive, ElementRef} from '@angular/core';
|
||||||
|
import {IonSearchbar} from '@ionic/angular';
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: 'ion-searchbar[autofocus]',
|
||||||
|
})
|
||||||
|
export class SearchbarAutofocusDirective implements AfterViewInit {
|
||||||
|
constructor(private element: ElementRef) {}
|
||||||
|
|
||||||
|
ngAfterViewInit() {
|
||||||
|
const label = `focus`;
|
||||||
|
console.time(label);
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
const searchbar = this.element.nativeElement as IonSearchbar;
|
||||||
|
searchbar.setFocus();
|
||||||
|
});
|
||||||
|
const onFocus = () => {
|
||||||
|
console.timeEnd(label);
|
||||||
|
clearInterval(interval);
|
||||||
|
this.element.nativeElement.removeEventListener('ionFocus', onFocus);
|
||||||
|
};
|
||||||
|
this.element.nativeElement.addEventListener('ionFocus', onFocus);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,20 +37,14 @@
|
|||||||
</ion-button>
|
</ion-button>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
<ion-col size="auto">
|
||||||
<ion-col size="auto" *ngIf="isEditable">
|
<div>
|
||||||
<ion-button fill="clear" color="medium" (click)="onEditClick()">
|
<ng-content select="[slot=button-end]"></ng-content>
|
||||||
<ion-icon size="24" slot="icon-only" name="edit_square"></ion-icon>
|
</div>
|
||||||
</ion-button>
|
|
||||||
</ion-col>
|
|
||||||
<ion-col size="auto" *ngIf="customIcon">
|
|
||||||
<ion-button fill="clear" color="medium" (click)="onEditClick()">
|
|
||||||
<ion-icon slot="icon-only" size="24" [name]="customIcon"></ion-icon>
|
|
||||||
</ion-button>
|
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
<ion-row>
|
<ion-row>
|
||||||
<ion-col #content>
|
<ion-col>
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import '../../../../theme/util/mixins';
|
@import 'src/theme/util/mixins';
|
||||||
|
|
||||||
a {
|
a {
|
||||||
display: contents;
|
display: contents;
|
||||||
@@ -44,8 +44,8 @@ ion-col {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ion-button::part(native) {
|
:host ::ng-deep ion-button::part(native) {
|
||||||
padding-inline: var(--spacing-sm);
|
padding-inline: var(--spacing-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (hover: none) {
|
@media (hover: none) {
|
||||||
@@ -12,17 +12,7 @@
|
|||||||
* 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 {
|
import {AfterContentInit, Component, Input, OnDestroy, ViewContainerRef} from '@angular/core';
|
||||||
AfterContentInit,
|
|
||||||
Component,
|
|
||||||
EventEmitter,
|
|
||||||
HostBinding,
|
|
||||||
Input,
|
|
||||||
OnDestroy,
|
|
||||||
OnInit,
|
|
||||||
Output,
|
|
||||||
ViewContainerRef,
|
|
||||||
} from '@angular/core';
|
|
||||||
import {SCThings} from '@openstapps/core';
|
import {SCThings} from '@openstapps/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,35 +23,17 @@ import {SCThings} from '@openstapps/core';
|
|||||||
templateUrl: 'section.component.html',
|
templateUrl: 'section.component.html',
|
||||||
styleUrls: ['section.component.scss'],
|
styleUrls: ['section.component.scss'],
|
||||||
})
|
})
|
||||||
export class SectionComponent implements OnInit, AfterContentInit, OnDestroy {
|
export class SectionComponent implements AfterContentInit, OnDestroy {
|
||||||
@HostBinding('class.is-extended') isExtendedClass = false;
|
|
||||||
|
|
||||||
@HostBinding('class.is-editable') isEditableClass = false;
|
|
||||||
|
|
||||||
@Input() title = '';
|
@Input() title = '';
|
||||||
|
|
||||||
@Input() isSectionExtended = false;
|
|
||||||
|
|
||||||
@Input() isEditable = false;
|
|
||||||
|
|
||||||
@Input() customIcon?: string = undefined;
|
|
||||||
|
|
||||||
@Input() item?: SCThings;
|
@Input() item?: SCThings;
|
||||||
|
|
||||||
// eslint-disable-next-line @angular-eslint/no-output-on-prefix
|
|
||||||
@Output() onEdit = new EventEmitter<void>();
|
|
||||||
|
|
||||||
mutationObserver: MutationObserver;
|
mutationObserver: MutationObserver;
|
||||||
|
|
||||||
swiper?: HTMLElement;
|
swiper?: HTMLElement;
|
||||||
|
|
||||||
constructor(readonly viewContainerRef: ViewContainerRef) {}
|
constructor(readonly viewContainerRef: ViewContainerRef) {}
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.isExtendedClass = this.isSectionExtended;
|
|
||||||
this.isEditableClass = this.isEditable;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterContentInit() {
|
ngAfterContentInit() {
|
||||||
this.mutationObserver = new MutationObserver(() => {
|
this.mutationObserver = new MutationObserver(() => {
|
||||||
const simpleSwiper = this.viewContainerRef.element.nativeElement.querySelector('simple-swiper');
|
const simpleSwiper = this.viewContainerRef.element.nativeElement.querySelector('simple-swiper');
|
||||||
@@ -93,13 +65,6 @@ export class SectionComponent implements OnInit, AfterContentInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Action when edit is clicked
|
|
||||||
*/
|
|
||||||
onEditClick() {
|
|
||||||
this.onEdit.emit();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.mutationObserver.disconnect();
|
this.mutationObserver.disconnect();
|
||||||
}
|
}
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 StApps
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import {Component, Input} from '@angular/core';
|
|
||||||
import {SCSectionLink} from '../../modules/profile/page/sections';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'stapps-section-link-card',
|
|
||||||
templateUrl: 'section-link-card.html',
|
|
||||||
styleUrls: ['section-link-card.scss'],
|
|
||||||
})
|
|
||||||
export class SectionLinkCardComponent {
|
|
||||||
@Input() item: SCSectionLink;
|
|
||||||
|
|
||||||
@Input() disabled: boolean;
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<!--
|
|
||||||
~ Copyright (C) 2022 StApps
|
|
||||||
~ This program is free software: you can redistribute it and/or modify it
|
|
||||||
~ under the terms of the GNU General Public License as published by the Free
|
|
||||||
~ Software Foundation, version 3.
|
|
||||||
~
|
|
||||||
~ This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
~ more details.
|
|
||||||
~
|
|
||||||
~ You should have received a copy of the GNU General Public License along with
|
|
||||||
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
-->
|
|
||||||
<ion-card [routerLink]="item.link" class="card" [class.disabled]="disabled">
|
|
||||||
<ion-card-header mode="md">
|
|
||||||
<ion-card-title>
|
|
||||||
<ion-icon [name]="item.icon" size="40"></ion-icon>
|
|
||||||
<!-- TODO: move this to thing translate -->
|
|
||||||
{{ 'name' | translateSimple: item }}
|
|
||||||
</ion-card-title>
|
|
||||||
</ion-card-header>
|
|
||||||
</ion-card>
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Copyright (C) 2023 StApps
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
:host,
|
|
||||||
ion-card,
|
|
||||||
ion-card-header,
|
|
||||||
ion-card::part(native) {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
ion-card {
|
|
||||||
padding: 0;
|
|
||||||
margin-block: 0;
|
|
||||||
margin-inline: var(--spacing-sm);
|
|
||||||
}
|
|
||||||
|
|
||||||
ion-card-header {
|
|
||||||
padding: var(--spacing-md) var(--spacing-lg);
|
|
||||||
}
|
|
||||||
|
|
||||||
ion-card-title {
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
font-family: var(--ion-font-family);
|
|
||||||
font-size: var(--font-size-xs);
|
|
||||||
font-weight: var(--font-weight-semi-bold);
|
|
||||||
}
|
|
||||||
|
|
||||||
.disabled {
|
|
||||||
opacity: 0.3;
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 StApps
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {Component} from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'stapps-section-tail-prompt-card',
|
|
||||||
templateUrl: 'section-tail-prompt-card.html',
|
|
||||||
styleUrls: ['section-tail-prompt-card.scss', 'section-link-card.scss'],
|
|
||||||
})
|
|
||||||
export class SectionTailPromptCardComponent {}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<!--
|
|
||||||
~ Copyright (C) 2022 StApps
|
|
||||||
~ This program is free software: you can redistribute it and/or modify it
|
|
||||||
~ under the terms of the GNU General Public License as published by the Free
|
|
||||||
~ Software Foundation, version 3.
|
|
||||||
~
|
|
||||||
~ This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
~ more details.
|
|
||||||
~
|
|
||||||
~ You should have received a copy of the GNU General Public License along with
|
|
||||||
~ this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<ion-card [button]="true" class="card">
|
|
||||||
<ion-card-header>
|
|
||||||
<ion-card-title>
|
|
||||||
<ng-content></ng-content>
|
|
||||||
</ion-card-title>
|
|
||||||
</ion-card-header>
|
|
||||||
</ion-card>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Copyright (C) 2022 StApps
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.card {
|
|
||||||
box-shadow: none;
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2023 StApps
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, version 3.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
import {NgModule} from '@angular/core';
|
|
||||||
import {SectionLinkCardComponent} from './section-link-card.component';
|
|
||||||
import {IonicModule} from '@ionic/angular';
|
|
||||||
import {BrowserModule} from '@angular/platform-browser';
|
|
||||||
import {TranslateModule} from '@ngx-translate/core';
|
|
||||||
import {IonIconModule} from '../ion-icon/ion-icon.module';
|
|
||||||
import {ThingTranslateModule} from '../../translation/thing-translate.module';
|
|
||||||
import {RouterModule} from '@angular/router';
|
|
||||||
import {SectionTailPromptCardComponent} from './section-tail-prompt-card.component';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [BrowserModule, IonicModule, TranslateModule, IonIconModule, ThingTranslateModule, RouterModule],
|
|
||||||
declarations: [SectionLinkCardComponent, SectionTailPromptCardComponent],
|
|
||||||
exports: [SectionLinkCardComponent, SectionTailPromptCardComponent],
|
|
||||||
})
|
|
||||||
export class SectionModule {}
|
|
||||||
@@ -28,6 +28,8 @@ import {ElementSizeChangeDirective} from './element-size-change.directive';
|
|||||||
import {OpeningHoursComponent} from './opening-hours.component';
|
import {OpeningHoursComponent} from './opening-hours.component';
|
||||||
import {ThingTranslateModule} from '../translation/thing-translate.module';
|
import {ThingTranslateModule} from '../translation/thing-translate.module';
|
||||||
import {SimpleSwiperComponent} from './simple-swiper.component';
|
import {SimpleSwiperComponent} from './simple-swiper.component';
|
||||||
|
import {SearchbarAutofocusDirective} from './searchbar-autofocus.directive';
|
||||||
|
import {SectionComponent} from './section.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [BrowserModule, IonicModule, TranslateModule, ThingTranslateModule.forChild()],
|
imports: [BrowserModule, IonicModule, TranslateModule, ThingTranslateModule.forChild()],
|
||||||
@@ -37,12 +39,14 @@ import {SimpleSwiperComponent} from './simple-swiper.component';
|
|||||||
DateIsThisPipe,
|
DateIsThisPipe,
|
||||||
NullishCoalescingPipe,
|
NullishCoalescingPipe,
|
||||||
LazyPipe,
|
LazyPipe,
|
||||||
|
SectionComponent,
|
||||||
DateFromIndexPipe,
|
DateFromIndexPipe,
|
||||||
DaytimeKeyPipe,
|
DaytimeKeyPipe,
|
||||||
NextDateInListPipe,
|
NextDateInListPipe,
|
||||||
EditModalComponent,
|
EditModalComponent,
|
||||||
OpeningHoursComponent,
|
OpeningHoursComponent,
|
||||||
SimpleSwiperComponent,
|
SimpleSwiperComponent,
|
||||||
|
SearchbarAutofocusDirective,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
ElementSizeChangeDirective,
|
ElementSizeChangeDirective,
|
||||||
@@ -52,10 +56,12 @@ import {SimpleSwiperComponent} from './simple-swiper.component';
|
|||||||
LazyPipe,
|
LazyPipe,
|
||||||
DateFromIndexPipe,
|
DateFromIndexPipe,
|
||||||
DaytimeKeyPipe,
|
DaytimeKeyPipe,
|
||||||
|
SectionComponent,
|
||||||
NextDateInListPipe,
|
NextDateInListPipe,
|
||||||
EditModalComponent,
|
EditModalComponent,
|
||||||
OpeningHoursComponent,
|
OpeningHoursComponent,
|
||||||
SimpleSwiperComponent,
|
SimpleSwiperComponent,
|
||||||
|
SearchbarAutofocusDirective,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class UtilModule {}
|
export class UtilModule {}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*!
|
/*!
|
||||||
* Copyright (C) 2022 StApps
|
* Copyright (C) 2023 StApps
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
* Software Foundation, version 3.
|
* Software Foundation, version 3.
|
||||||
@@ -37,12 +37,6 @@ app-root ion-toolbar.in-toolbar {
|
|||||||
--padding-bottom: 0;
|
--padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ion-searchbar {
|
|
||||||
padding-left: 0;
|
|
||||||
padding-right: 0;
|
|
||||||
--box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
ion-segment {
|
ion-segment {
|
||||||
&:last-of-type {
|
&:last-of-type {
|
||||||
--padding-bottom: 0;
|
--padding-bottom: 0;
|
||||||
@@ -74,3 +68,10 @@ app-root ion-toolbar.in-toolbar {
|
|||||||
height: 42px; // this prevents the back button to become a .x px value
|
height: 42px; // this prevents the back button to become a .x px value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app-root ion-toolbar.in-toolbar ion-searchbar,
|
||||||
|
.stapps-searchbar {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
--box-shadow: none;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,10 +3,6 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "../out-tsc/app"
|
"outDir": "../out-tsc/app"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": ["src/main.ts", "src/polyfills.ts"],
|
||||||
"src/main.ts",
|
|
||||||
"src/polyfills.ts",
|
|
||||||
"src/app/modules/dashboard/sections/navigation-section/menu-item.interface.ts"
|
|
||||||
],
|
|
||||||
"include": ["src/**/*.d.ts"]
|
"include": ["src/**/*.d.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user