mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-10 03:32:52 +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';
|
import {RouterModule, Routes} from '@angular/router';
|
||||||
|
|
||||||
const routes: Routes = [
|
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 {ConfigModule} from './modules/config/config.module';
|
||||||
import {DataModule} from './modules/data/data.module';
|
import {DataModule} from './modules/data/data.module';
|
||||||
import {MenuModule} from './modules/menu/menu.module';
|
import {MenuModule} from './modules/menu/menu.module';
|
||||||
|
import {NewsModule} from './modules/news/news.module';
|
||||||
import {SettingsModule} from './modules/settings/settings.module';
|
import {SettingsModule} from './modules/settings/settings.module';
|
||||||
import {StorageModule} from './modules/storage/storage.module';
|
import {StorageModule} from './modules/storage/storage.module';
|
||||||
import {fakeBackendProvider} from './_helpers/fake-backend.interceptor';
|
import {fakeBackendProvider} from './_helpers/fake-backend.interceptor';
|
||||||
@@ -72,6 +73,7 @@ const providers : Provider[] = [
|
|||||||
DataModule,
|
DataModule,
|
||||||
IonicModule.forRoot(),
|
IonicModule.forRoot(),
|
||||||
MenuModule,
|
MenuModule,
|
||||||
|
NewsModule,
|
||||||
SettingsModule,
|
SettingsModule,
|
||||||
StorageModule,
|
StorageModule,
|
||||||
TranslateModule.forRoot({
|
TranslateModule.forRoot({
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export class DataDetailComponent {
|
|||||||
language: SCLanguageCode;
|
language: SCLanguageCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param route TODO
|
* @param route TODO
|
||||||
* @param dataProvider TODO
|
* @param dataProvider TODO
|
||||||
* @param translateService TODO
|
* @param translateService TODO
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
import {Component} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* A placeholder to show when a list item is being loaded
|
||||||
*/
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'stapps-skeleton-list-item',
|
selector: 'stapps-skeleton-list-item',
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
import {Component} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* A placeholder to show when a simple card is being loaded
|
||||||
*/
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'stapps-skeleton-simple-card',
|
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": {
|
"menu": {
|
||||||
"context": {
|
"context": {
|
||||||
"title": "Kontext Menü",
|
"title": "Kontext Menü",
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"news": {
|
||||||
|
"title": "News"
|
||||||
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"context": {
|
"context": {
|
||||||
"title": "context menu",
|
"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