mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-06 21:42:49 +00:00
feat: news module
This commit is contained in:
@@ -16,7 +16,7 @@ import {NgModule} from '@angular/core';
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
|
||||
const routes: Routes = [
|
||||
{path: '', redirectTo: '/search', pathMatch: 'full'},
|
||||
{path: '', redirectTo: '/news', pathMatch: 'full'},
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,7 @@ import {AppComponent} from './app.component';
|
||||
import {ConfigModule} from './modules/config/config.module';
|
||||
import {DataModule} from './modules/data/data.module';
|
||||
import {MenuModule} from './modules/menu/menu.module';
|
||||
import {NewsModule} from './modules/news/news.module';
|
||||
import {SettingsModule} from './modules/settings/settings.module';
|
||||
import {StorageModule} from './modules/storage/storage.module';
|
||||
import {fakeBackendProvider} from './_helpers/fake-backend.interceptor';
|
||||
@@ -72,6 +73,7 @@ const providers : Provider[] = [
|
||||
DataModule,
|
||||
IonicModule.forRoot(),
|
||||
MenuModule,
|
||||
NewsModule,
|
||||
SettingsModule,
|
||||
StorageModule,
|
||||
TranslateModule.forRoot({
|
||||
|
||||
@@ -42,7 +42,7 @@ export class DataDetailComponent {
|
||||
language: SCLanguageCode;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param route TODO
|
||||
* @param dataProvider TODO
|
||||
* @param translateService TODO
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* A placeholder to show when a list item is being loaded
|
||||
*/
|
||||
@Component({
|
||||
selector: 'stapps-skeleton-list-item',
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* A placeholder to show when a simple card is being loaded
|
||||
*/
|
||||
@Component({
|
||||
selector: 'stapps-skeleton-simple-card',
|
||||
|
||||
52
src/app/modules/news/news.module.ts
Normal file
52
src/app/modules/news/news.module.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2021 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 {CommonModule} from '@angular/common';
|
||||
import {NgModule} from '@angular/core';
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import {IonicModule} from '@ionic/angular';
|
||||
import {TranslateModule} from '@ngx-translate/core';
|
||||
import {MomentModule} from 'ngx-moment';
|
||||
import {DataModule} from '../data/data.module';
|
||||
import {SettingsProvider} from '../settings/settings.provider';
|
||||
import {NewsPageComponent} from './page/news-page.component';
|
||||
import {SkeletonNewsItem} from './page/skeleton-news-item.component';
|
||||
import {NewsItemComponent} from './page/news-item.component';
|
||||
|
||||
const newsRoutes: Routes = [
|
||||
{path: 'news', component: NewsPageComponent},
|
||||
];
|
||||
|
||||
/**
|
||||
* News Module
|
||||
*/
|
||||
@NgModule({
|
||||
declarations: [
|
||||
NewsPageComponent,
|
||||
SkeletonNewsItem,
|
||||
NewsItemComponent,
|
||||
],
|
||||
imports: [
|
||||
IonicModule.forRoot(),
|
||||
TranslateModule.forChild(),
|
||||
RouterModule.forChild(newsRoutes),
|
||||
CommonModule,
|
||||
MomentModule,
|
||||
DataModule,
|
||||
],
|
||||
providers: [
|
||||
SettingsProvider,
|
||||
],
|
||||
})
|
||||
export class NewsModule {}
|
||||
60
src/app/modules/news/news.provider.ts
Normal file
60
src/app/modules/news/news.provider.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2021 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 {Injectable} from '@angular/core';
|
||||
import {SCMessage} from '@openstapps/core';
|
||||
import {DataProvider} from '../data/data.provider';
|
||||
/**
|
||||
* Service for providing news messages
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class NewsProvider {
|
||||
constructor(private dataProvider: DataProvider) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get news messages
|
||||
* TODO: make dates sortable on the backend side and then adjust this method
|
||||
* @param size How many messages/news to fetch
|
||||
* @param sort If sort by date needs to be performed
|
||||
*/
|
||||
async getList(size: number, sort?: boolean): Promise<SCMessage[]> {
|
||||
const result = await this.dataProvider.search({
|
||||
filter: {
|
||||
type: 'value',
|
||||
arguments: {
|
||||
field: 'type',
|
||||
value: 'message',
|
||||
},
|
||||
},
|
||||
size: size,
|
||||
});
|
||||
|
||||
const news = result.data as SCMessage[];
|
||||
|
||||
if (sort) {
|
||||
news.sort((a, b) => {
|
||||
if (typeof a.datePublished !== 'undefined' && typeof b.datePublished !== 'undefined') {
|
||||
return (a.datePublished > b.datePublished) ? -1 : ((a.datePublished < b.datePublished) ? 1 : 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
return news;
|
||||
}
|
||||
}
|
||||
59
src/app/modules/news/page/news-item.component.ts
Normal file
59
src/app/modules/news/page/news-item.component.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 {LangChangeEvent, TranslateService} from '@ngx-translate/core';
|
||||
import {SCLanguageCode, SCMessage} from '@openstapps/core';
|
||||
import {Subscription} from 'rxjs';
|
||||
/**
|
||||
* News page component
|
||||
*/
|
||||
@Component({
|
||||
selector: 'stapps-news-item',
|
||||
templateUrl: 'news-item.html',
|
||||
styleUrls: ['news-item.scss'],
|
||||
})
|
||||
export class NewsItemComponent {
|
||||
/**
|
||||
* News (message) to show
|
||||
*/
|
||||
@Input() item: SCMessage;
|
||||
/**
|
||||
* Current language
|
||||
*/
|
||||
language: string;
|
||||
/**
|
||||
* Current language subscription
|
||||
*/
|
||||
languageSubscription: Subscription;
|
||||
|
||||
constructor(private translateService: TranslateService) {}
|
||||
|
||||
/**
|
||||
* Remove language subscription on component destruction
|
||||
*/
|
||||
ngOnDestroy() {
|
||||
this.languageSubscription?.unsubscribe();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the local variables on component initialization
|
||||
*/
|
||||
ngOnInit() {
|
||||
this.language = this.translateService.currentLang as SCLanguageCode;
|
||||
this.languageSubscription = this.translateService.onLangChange.subscribe((event: LangChangeEvent) => {
|
||||
this.language = event.lang as SCLanguageCode;
|
||||
});
|
||||
}
|
||||
}
|
||||
22
src/app/modules/news/page/news-item.html
Normal file
22
src/app/modules/news/page/news-item.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<ion-card>
|
||||
<span *ngIf="item.url; else imageNoUrl">
|
||||
<a href="{{item.url}}">
|
||||
<img src="{{item.image}}" onError="this.src='../../assets/imgs/modules/news/placeholder.jpg';" />
|
||||
</a>
|
||||
</span>
|
||||
<ng-template #imageNoUrl>
|
||||
<img src="{{item.image}}" onError="this.src='../../assets/imgs/modules/news/placeholder.jpg';" />
|
||||
</ng-template>
|
||||
<ion-card-header>
|
||||
<ion-card-subtitle *ngIf="item.datePublished">{{item.datePublished | amLocale: language | amDateFormat:'Do MMMM YYYY, HH:mm'}}
|
||||
<span *ngIf="language === 'de'">Uhr</span>
|
||||
</ion-card-subtitle>
|
||||
<ion-card-title>
|
||||
<span *ngIf="item.url; else titleNoUrl"><a href="{{item.url}}"><span class="text">{{item.name}}</span><span class="icon"><ion-icon name="open-outline"></ion-icon></span></a></span>
|
||||
<ng-template #titleNoUrl>{{item.name}}</ng-template>
|
||||
</ion-card-title>
|
||||
</ion-card-header>
|
||||
<ion-card-content>
|
||||
{{item.messageBody}}
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
12
src/app/modules/news/page/news-item.scss
Normal file
12
src/app/modules/news/page/news-item.scss
Normal file
@@ -0,0 +1,12 @@
|
||||
ion-card-header a {
|
||||
color: var(--ion-color-dark-tint);
|
||||
text-decoration: none;
|
||||
span.icon ion-icon {
|
||||
vertical-align: text-top;
|
||||
font-size: 60%;
|
||||
padding-left: 4px;
|
||||
}
|
||||
}
|
||||
ion-card img {
|
||||
width: 100%;
|
||||
}
|
||||
41
src/app/modules/news/page/news-page.component.ts
Normal file
41
src/app/modules/news/page/news-page.component.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2021 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';
|
||||
import {SCMessage} from '@openstapps/core';
|
||||
import {NewsProvider} from '../news.provider';
|
||||
/**
|
||||
* News page component
|
||||
*/
|
||||
@Component({
|
||||
selector: 'stapps-news-page',
|
||||
templateUrl: 'news-page.html',
|
||||
})
|
||||
export class NewsPageComponent {
|
||||
/**
|
||||
* News (messages) to show
|
||||
*/
|
||||
news: SCMessage[];
|
||||
|
||||
constructor(private newsProvider: NewsProvider) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the local variables on component initialization
|
||||
*/
|
||||
async ngOnInit() {
|
||||
/* tslint:disable:no-magic-numbers */
|
||||
this.news = await this.newsProvider.getList(30, true);
|
||||
}
|
||||
}
|
||||
25
src/app/modules/news/page/news-page.html
Normal file
25
src/app/modules/news/page/news-page.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button></ion-back-button>
|
||||
<ion-menu-button></ion-menu-button>
|
||||
</ion-buttons>
|
||||
<!--TODO: read this from the config (menu item title)-->
|
||||
<ion-title>{{'news.title' | translate}}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content fullscreen>
|
||||
<ion-grid>
|
||||
<ion-row *ngIf="!news">
|
||||
<ion-col size="12" size-md="6" *ngFor="let skeleton of [1, 2, 3, 4, 5]">
|
||||
<stapps-skeleton-news-item></stapps-skeleton-news-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row *ngIf="news">
|
||||
<ion-col size="12" size-md="6" *ngFor="let item of news">
|
||||
<stapps-news-item [item]="item"></stapps-news-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-content>
|
||||
25
src/app/modules/news/page/skeleton-news-item.component.ts
Normal file
25
src/app/modules/news/page/skeleton-news-item.component.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2021 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';
|
||||
|
||||
/**
|
||||
* A placeholder to show when a news item is being loaded
|
||||
*/
|
||||
@Component({
|
||||
selector: 'stapps-skeleton-news-item',
|
||||
templateUrl: 'skeleton-news-item.html',
|
||||
})
|
||||
export class SkeletonNewsItem {
|
||||
}
|
||||
12
src/app/modules/news/page/skeleton-news-item.html
Normal file
12
src/app/modules/news/page/skeleton-news-item.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<ion-card>
|
||||
<ion-card-header>
|
||||
<ion-card-subtitle><ion-skeleton-text animated style="width: 20%"></ion-skeleton-text></ion-card-subtitle>
|
||||
<ion-card-title><ion-skeleton-text animated style="width: 95%"></ion-skeleton-text></ion-card-title>
|
||||
<ion-card-title><ion-skeleton-text animated style="width: 65%"></ion-skeleton-text></ion-card-title>
|
||||
</ion-card-header>
|
||||
<ion-card-content>
|
||||
<p><ion-skeleton-text animated style="width: 95%;"></ion-skeleton-text></p>
|
||||
<p><ion-skeleton-text animated style="width: 95%;"></ion-skeleton-text></p>
|
||||
<p><ion-skeleton-text animated style="width: 55%;"></ion-skeleton-text></p>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
@@ -15,6 +15,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"news": {
|
||||
"title": "Aktuelles"
|
||||
},
|
||||
"menu": {
|
||||
"context": {
|
||||
"title": "Kontext Menü",
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"news": {
|
||||
"title": "News"
|
||||
},
|
||||
"menu": {
|
||||
"context": {
|
||||
"title": "context menu",
|
||||
|
||||
BIN
src/assets/imgs/modules/news/placeholder.jpg
Normal file
BIN
src/assets/imgs/modules/news/placeholder.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Reference in New Issue
Block a user